summaryrefslogtreecommitdiff
path: root/src/amigax.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/amigax.c')
-rw-r--r--src/amigax.c382
1 files changed, 382 insertions, 0 deletions
diff --git a/src/amigax.c b/src/amigax.c
new file mode 100644
index 0000000..aa82d49
--- /dev/null
+++ b/src/amigax.c
@@ -0,0 +1,382 @@
+/*
+ * Copyright (C) 19896 Lorens Younes
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * Lorens Younes BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Lorens Younes shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Lorens Younes.
+ */
+
+/*****************************************************************************\
+* amigax.c: *
+* *
+* XPM library *
+* Emulates some Xlib functionality for Amiga. *
+* *
+* Developed by Lorens Younes (d93-hyo@nada.kth.se) 7/95 *
+* Revised 4/96 *
+\*****************************************************************************/
+
+#include "XpmI.h"
+#include "amigax.h"
+
+#include <graphics/gfxbase.h>
+#include <intuition/screens.h>
+
+#include <proto/exec.h>
+
+
+static struct RastPort *
+AllocRastPort (unsigned int, unsigned int, unsigned int);
+static void
+FreeRastPort (struct RastPort *, unsigned int,unsigned int);
+
+
+static struct RastPort *
+AllocRastPort (
+ unsigned int width,
+ unsigned int height,
+ unsigned int depth)
+{
+ struct RastPort *rp;
+
+ rp = XpmMalloc (sizeof (*rp));
+ if (rp != NULL)
+ {
+ InitRastPort (rp);
+ if (GfxBase->LibNode.lib_Version >= 39)
+ {
+ rp->BitMap = AllocBitMap (width, height, depth, BMF_CLEAR, NULL);
+ if (rp->BitMap == NULL)
+ {
+ FreeRastPort (rp, width, height);
+ return NULL;
+ }
+ }
+ else
+ {
+ unsigned int i;
+
+ rp->BitMap = XpmMalloc (sizeof (*rp->BitMap));
+ if (rp->BitMap == NULL)
+ {
+ FreeRastPort (rp, width, height);
+ return NULL;
+ }
+
+ InitBitMap (rp->BitMap, depth, width, height);
+ for (i = 0; i < depth; ++i)
+ rp->BitMap->Planes[i] = NULL;
+ for (i = 0; i < depth; ++i)
+ {
+ rp->BitMap->Planes[i] = (PLANEPTR)AllocRaster (width, height);
+ if (rp->BitMap->Planes[i] == NULL)
+ {
+ FreeRastPort (rp, width, height);
+ return NULL;
+ }
+ }
+ }
+ }
+
+ return rp;
+}
+
+
+static void
+FreeRastPort (
+ struct RastPort *rp,
+ unsigned int width,
+ unsigned int height)
+{
+ if (rp != NULL)
+ {
+ if (rp->BitMap != NULL)
+ {
+ WaitBlit ();
+ if (GfxBase->LibNode.lib_Version >= 39)
+ FreeBitMap (rp->BitMap);
+ else
+ {
+ unsigned int i;
+
+ for (i = 0; i < rp->BitMap->Depth; ++i)
+ {
+ if (rp->BitMap->Planes[i] != NULL)
+ FreeRaster (rp->BitMap->Planes[i], width, height);
+ }
+ XpmFree (rp->BitMap);
+ }
+ }
+ XpmFree (rp);
+ }
+}
+
+
+XImage *
+AllocXImage (
+ unsigned int width,
+ unsigned int height,
+ unsigned int depth)
+{
+ XImage *img;
+
+ img = XpmMalloc (sizeof (*img));
+ if (img != NULL)
+ {
+ img->width = width;
+ img->height = height;
+ img->rp = AllocRastPort (img->width, img->height, depth);
+ if (img->rp == NULL)
+ {
+ FreeXImage (img);
+ return NULL;
+ }
+ }
+
+ return img;
+}
+
+
+int
+FreeXImage (
+ XImage *ximage)
+{
+ if (ximage != NULL)
+ {
+ FreeRastPort (ximage->rp, ximage->width, ximage->height);
+ XpmFree (ximage);
+ }
+
+ return Success;
+}
+
+
+int
+XPutPixel (
+ XImage *ximage,
+ int x,
+ int y,
+ unsigned long pixel)
+{
+ SetAPen (ximage->rp, pixel);
+ WritePixel (ximage->rp, x, y);
+
+ return Success;
+}
+
+
+Status
+AllocBestPen (
+ Colormap colormap,
+ XColor *screen_in_out,
+ unsigned long precision,
+ Bool fail_if_bad)
+{
+ if (GfxBase->LibNode.lib_Version >= 39)
+ {
+ unsigned long r, g, b;
+
+ r = screen_in_out->red * 0x00010001;
+ g = screen_in_out->green * 0x00010001;
+ b = screen_in_out->blue * 0x00010001;
+ screen_in_out->pixel = ObtainBestPen (colormap, r, g, b,
+ OBP_Precision, precision,
+ OBP_FailIfBad, fail_if_bad,
+ TAG_DONE);
+ if (screen_in_out->pixel == -1)
+ return False;
+
+ QueryColor (colormap, screen_in_out);
+ }
+ else
+ {
+ XColor nearest, trial;
+ long nearest_delta, trial_delta;
+ int num_cells, i;
+
+ num_cells = colormap->Count;
+ nearest.pixel = 0;
+ QueryColor (colormap, &nearest);
+ nearest_delta = ((((screen_in_out->red >> 8) - (nearest.red >> 8))
+ * ((screen_in_out->red >> 8) - (nearest.red >> 8)))
+ +
+ (((screen_in_out->green >> 8) - (nearest.green >> 8))
+ * ((screen_in_out->green >> 8) - (nearest.green >> 8)))
+ +
+ (((screen_in_out->blue >> 8) - (nearest.blue >> 8))
+ * ((screen_in_out->blue >> 8) - (nearest.blue >> 8))));
+ for (i = 1; i < num_cells; i++)
+ {
+ /* precision and fail_if_bad is ignored under pre V39 */
+ trial.pixel = i;
+ QueryColor (colormap, &trial);
+ trial_delta = ((((screen_in_out->red >> 8) - (trial.red >> 8))
+ * ((screen_in_out->red >> 8) - (trial.red >> 8)))
+ +
+ (((screen_in_out->green >> 8) - (trial.green >> 8))
+ * ((screen_in_out->green >> 8) - (trial.green >> 8)))
+ +
+ (((screen_in_out->blue >> 8) - (trial.blue >> 8))
+ * ((screen_in_out->blue >> 8) - (trial.blue >> 8))));
+ if (trial_delta < nearest_delta)
+ {
+ nearest = trial;
+ nearest_delta = trial_delta;
+ }
+ }
+ screen_in_out->pixel = nearest.pixel;
+ screen_in_out->red = nearest.red;
+ screen_in_out->green = nearest.green;
+ screen_in_out->blue = nearest.blue;
+ }
+
+ return True;
+}
+
+
+int
+FreePens (
+ Colormap colormap,
+ unsigned long *pixels,
+ int npixels)
+{
+ if (GfxBase->LibNode.lib_Version >= 39)
+ {
+ int i;
+
+ for (i = 0; i < npixels; i++)
+ ReleasePen (colormap, pixels[i]);
+ }
+
+ return Success;
+}
+
+
+Status
+ParseColor (
+ char *spec,
+ XColor *exact_def_return)
+{
+ int spec_length;
+
+ if (spec == 0)
+ return False;
+
+ spec_length = strlen(spec);
+ if (spec[0] == '#')
+ {
+ int hexlen;
+ char hexstr[10];
+
+ hexlen = (spec_length - 1) / 3;
+ if (hexlen < 1 || hexlen > 4 || hexlen * 3 != spec_length - 1)
+ return False;
+
+ hexstr[hexlen] = '\0';
+ strncpy (hexstr, spec + 1, hexlen);
+ exact_def_return->red = strtoul (hexstr, NULL, 16) << (16 - 4*hexlen);
+ strncpy (hexstr, spec + 1 + hexlen, hexlen);
+ exact_def_return->green = strtoul (hexstr, NULL, 16) << (16 - 4*hexlen);
+ strncpy (hexstr, spec + 1 + 2 * hexlen, hexlen);
+ exact_def_return->blue = strtoul (hexstr, NULL, 16) << (16 - 4*hexlen);
+
+ return True;
+ }
+ else
+ {
+ FILE *rgbf;
+ int items, red, green, blue;
+ char line[512], name[512];
+ Bool success = False;
+
+ rgbf = fopen ("LIBS:rgb.txt", "r");
+ if (rgbf == NULL)
+ return False;
+
+ while (fgets(line, sizeof (line), rgbf) && !success)
+ {
+ items = sscanf (line, "%d %d %d %[^\n]\n",
+ &red, &green, &blue, name);
+ if (items != 4)
+ continue;
+
+ if (red < 0 || red > 0xFF
+ || green < 0 || green > 0xFF
+ || blue < 0 || blue > 0xFF)
+ {
+ continue;
+ }
+
+ if (0 == xpmstrcasecmp (spec, name))
+ {
+ exact_def_return->red = red * 0x0101;
+ exact_def_return->green = green * 0x0101;
+ exact_def_return->blue = blue * 0x0101;
+ success = True;
+ }
+ }
+ fclose (rgbf);
+
+ return success;
+ }
+}
+
+
+int
+QueryColor (
+ Colormap colormap,
+ XColor *def_in_out)
+{
+ if (GfxBase->LibNode.lib_Version >= 39)
+ {
+ unsigned long rgb[3];
+
+ GetRGB32 (colormap, def_in_out->pixel, 1, rgb);
+ def_in_out->red = rgb[0] >> 16;
+ def_in_out->green = rgb[1] >> 16;
+ def_in_out->blue = rgb[2] >> 16;
+ }
+ else
+ {
+ unsigned short rgb;
+
+ rgb = GetRGB4 (colormap, def_in_out->pixel);
+ def_in_out->red = ((rgb >> 8) & 0xF) * 0x1111;
+ def_in_out->green = ((rgb >> 4) & 0xF) * 0x1111;
+ def_in_out->blue = (rgb & 0xF) * 0x1111;
+ }
+
+ return Success;
+}
+
+
+int
+QueryColors (
+ Colormap colormap,
+ XColor *defs_in_out,
+ int ncolors)
+{
+ int i;
+
+ for (i = 0; i < ncolors; i++)
+ QueryColor (colormap, &defs_in_out[i]);
+
+ return Success;
+}