diff options
Diffstat (limited to 'src/amigax.c')
-rw-r--r-- | src/amigax.c | 382 |
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; +} |