--- uae/src/gfxlib.c 2018/04/24 16:39:08 1.1.1.2 +++ uae/src/gfxlib.c 2018/04/24 17:02:00 1.1.1.7 @@ -3,8 +3,8 @@ * * graphics.library emulation * - * Copyright 1996 Bernd Schmidt - * + * Copyright 1996, 1997 Bernd Schmidt + * * Ideas for this: * Rewrite layers completely. When there are lots of windows on the screen * it can take 3 minutes to update everything after resizing or moving one @@ -13,16 +13,15 @@ * conversion time. Programs really shouldn't do anything directly with the * Layer or ClipRect structures. * This means that a lot of graphics.library functions will have to be - * rewritten as well. Of course there's the problem that we can't Wait() in - * the emulator currently, so we can't lock layers reliably. Big problem. + * rewritten as well. * Once that's done, add support for non-planar bitmaps. Conveniently, the * struct Bitmap has an unused pad field which we could abuse as some sort of * type field. Need to add chunky<->planar conversion routines to get it * going, plus variants of all the drawing functions for speed reasons. - * + * * When it becomes necessary to convert a structure from Amiga memory, make * a function with a name ending in ..FA, which takes a pointer to the - * native structure and a CPTR and returns the native pointer. + * native structure and a uaecptr and returns the native pointer. */ #include "sysconfig.h" @@ -32,27 +31,107 @@ #include "config.h" #include "options.h" +#include "threaddep/thread.h" #include "memory.h" #include "custom.h" -#include "readcpu.h" #include "newcpu.h" #include "xwin.h" #include "autoconf.h" #include "osemu.h" +#include "osdep/exectasks.h" + +#ifdef USE_EXECLIB + +/* Uniq list management. Should be in a separate file. */ +struct uniq_head { + struct uniq_head *next; + uae_u32 uniq; +}; + +typedef struct { + struct uniq_head *head; + uae_u32 uniq; +} uniq_list; + +#define UNIQ_INIT { NULL, 1 } + +static void init_uniq(uniq_list *list) +{ + list->head = NULL; + list->uniq = 1; +} -static ULONG gfxlibname, layerslibname; +static struct uniq_head *find_uniq (uniq_list *a, uae_u32 uniq) +{ + struct uniq_head *b = a->head; + while (b && b->uniq != uniq) + b = b->next; + if (!b) + write_log("Couldn't find structure. Bad\n"); + return b; +} + +static struct uniq_head *find_and_rem_uniq (uniq_list *a, uae_u32 uniq) +{ + struct uniq_head **b = &a->head, *c; + while (*b && (*b)->uniq != uniq) + b = &(*b)->next; + c = *b; + if (!c) + write_log("Couldn't find structure. Bad\n"); + else + *b = c->next; + return c; +} + +static void add_uniq (uniq_list *a, struct uniq_head *item, uaecptr amem) +{ + item->uniq = a->uniq++; + put_long(amem, item->uniq); + if (a->uniq == 0) + a->uniq++; + item->next = a->head; + a->head = item; +} + +/* Graphics stuff begins here */ +#define CLIPRECT_SIZE 40 +#define LAYER_SIZE 160 +#define LINFO_SIZE 102 + +static uaecptr gfxbase, layersbase; + +static void do_LockLayer(uaecptr layer) +{ +#if 0 /* Later.. */ + uaecptr sigsem = layer + 72; + m68k_areg(regs, 0) = sigsem; + CallLib(get_long(4), -564); +#else + m68k_areg(regs, 1) = layer; + CallLib(layersbase, -96); +#endif +} + +static void do_UnlockLayer(uaecptr layer) +{ + m68k_areg(regs, 0) = layer; + CallLib(layersbase, -102); +} + +static uae_u32 gfxlibname, layerslibname; struct Rectangle { int MinX, MinY, MaxX, MaxY; }; -static int GFX_PointInRectangle(CPTR rect, int x, int y) +static int GFX_PointInRectangle(uaecptr rect, int x, int y) { - WORD minx = get_word(rect); - WORD miny = get_word(rect+2); - WORD maxx = get_word(rect+4); - WORD maxy = get_word(rect+6); - + uae_s16 minx = get_word(rect); + uae_s16 miny = get_word(rect+2); + uae_s16 maxx = get_word(rect+4); + uae_s16 maxy = get_word(rect+6); + if (x < minx || x > maxx || y < miny || y > maxy) return 0; return 1; @@ -64,45 +143,45 @@ static int GFX_RectContainsRect(struct R && r2->MinY >= r1->MinY && r2->MaxY <= r1->MaxY); } -static struct Rectangle *GFX_RectFA(struct Rectangle *rp, CPTR rect) +static struct Rectangle *GFX_RectFA(struct Rectangle *rp, uaecptr rect) { - rp->MinX = (WORD)get_word(rect); - rp->MinY = (WORD)get_word(rect+2); - rp->MaxX = (WORD)get_word(rect+4); - rp->MaxY = (WORD)get_word(rect+6); + rp->MinX = (uae_s16)get_word(rect); + rp->MinY = (uae_s16)get_word(rect+2); + rp->MaxX = (uae_s16)get_word(rect+4); + rp->MaxY = (uae_s16)get_word(rect+6); return rp; } -static int GFX_Bitmap_WritePixel(CPTR bitmap, int x, int y, CPTR rp) +static int GFX_Bitmap_WritePixel(uaecptr bitmap, int x, int y, uaecptr rp) { int i, offs; unsigned int bpr = get_word (bitmap); unsigned int rows = get_word (bitmap + 2); - UWORD mask; + uae_u16 mask; - UBYTE planemask = get_byte(rp + 24); - UBYTE fgpen = get_byte(rp + 25); - UBYTE bgpen = get_byte(rp + 26); - UBYTE drmd = get_byte(rp + 28); - UBYTE pen = drmd & 4 ? bgpen : fgpen; + uae_u8 planemask = get_byte(rp + 24); + uae_u8 fgpen = get_byte(rp + 25); + uae_u8 bgpen = get_byte(rp + 26); + uae_u8 drmd = get_byte(rp + 28); + uae_u8 pen = drmd & 4 ? bgpen : fgpen; if (x < 0 || y < 0 || x >= 8*bpr || y >= rows) return -1; - + offs = y*bpr + (x & ~15)/8; for (i = 0; i < get_byte (bitmap + 5); i++) { - CPTR planeptr; - UWORD data; + uaecptr planeptr; + uae_u16 data; if ((planemask & (1 << i)) == 0) continue; planeptr = get_long(bitmap + 8 + i*4); data = get_word(planeptr + offs); - + mask = 0x8000 >> (x & 15); - + if (drmd & 2) { if ((pen & (1 << i)) != 0) data ^=mask; @@ -110,17 +189,18 @@ static int GFX_Bitmap_WritePixel(CPTR bi data &= ~mask; if ((pen & (1 << i)) != 0) data |= mask; - } + } put_word(planeptr + offs, data); } return 0; } -int GFX_WritePixel(CPTR rp, int x, int y) +int GFX_WritePixel(uaecptr rp, int x, int y) { - CPTR layer = get_long(rp); - CPTR bitmap = get_long(rp + 4); - CPTR cliprect; + int v; + uaecptr layer = get_long(rp); + uaecptr bitmap = get_long(rp + 4); + uaecptr cliprect; int x2, y2; if (bitmap == 0) { @@ -132,19 +212,21 @@ int GFX_WritePixel(CPTR rp, int x, int y if (layer == 0) { return GFX_Bitmap_WritePixel(bitmap, x, y, rp); } - + do_LockLayer(layer); /* * Now, in theory we ought to obtain the semaphore. * Since we don't, the programs will happily write into the raster * even though we are currently moving the window around. * Not good. */ - - x2 = x + (WORD)get_word(layer + 16); - y2 = y + (WORD)get_word(layer + 18); - - if (!GFX_PointInRectangle (layer + 16, x2, y2)) + + x2 = x + (uae_s16)get_word(layer + 16); + y2 = y + (uae_s16)get_word(layer + 18); + + if (!GFX_PointInRectangle (layer + 16, x2, y2)) { + do_UnlockLayer(layer); return -1; + } /* Find the right ClipRect */ cliprect = get_long(layer + 8); while (cliprect != 0 && !GFX_PointInRectangle (cliprect + 16, x2, y2)) @@ -155,30 +237,32 @@ int GFX_WritePixel(CPTR rp, int x, int y * the dot. */ /*fprintf(stderr, "Weirdness in WritePixel\n");*/ - return -1; + v = -1; + } else if (get_long(cliprect + 8) == 0) { + v = GFX_Bitmap_WritePixel(bitmap, x2, y2, rp); + } else if (get_long(cliprect + 12) == 0) { + /* I don't really know what to do here... */ + v = 0; + } else { + /* This appears to be normal for smart refresh layers which are obscured */ + v = GFX_Bitmap_WritePixel (get_long(cliprect + 12), x2 - (uae_s16)get_word(cliprect + 16), + y2 - (uae_s16)get_word(cliprect + 18), rp); } - if (get_long(cliprect + 8) == 0) - return GFX_Bitmap_WritePixel(bitmap, x2, y2, rp); - - /* Now come the cases where I don't really know what to do... */ - if (get_long(cliprect + 12) == 0) - return 0; - - return GFX_Bitmap_WritePixel (get_long(cliprect + 12), x2 - (WORD)get_word(cliprect + 16), - y2 - (WORD)get_word(cliprect + 18), rp); + do_UnlockLayer(layer); + return v; } -static ULONG gfxl_WritePixel(void) { return GFX_WritePixel(m68k_areg(regs, 1), (WORD)m68k_dreg(regs, 0), (WORD)m68k_dreg(regs, 1)); } +static uae_u32 gfxl_WritePixel(void) { return GFX_WritePixel(m68k_areg(regs, 1), (uae_s16)m68k_dreg(regs, 0), (uae_s16)m68k_dreg(regs, 1)); } -static ULONG gfxl_BltClear(void) +static uae_u32 gfxl_BltClear(void) { - CPTR mem=m68k_areg(regs, 1); - UBYTE *mptr = chipmem_bank.xlateaddr(m68k_areg(regs, 1)); - ULONG count=m68k_dreg(regs, 0); - ULONG flags=m68k_dreg(regs, 1); + uaecptr mem=m68k_areg(regs, 1); + uae_u8 *mptr = chipmem_bank.xlateaddr(m68k_areg(regs, 1)); + uae_u32 count=m68k_dreg(regs, 0); + uae_u32 flags=m68k_dreg(regs, 1); unsigned int i; - ULONG pattern; + uae_u32 pattern; if ((flags & 2) == 2){ /* count is given in Rows / Bytes per row */ @@ -187,7 +271,7 @@ static ULONG gfxl_BltClear(void) if ((mem & 1) != 0 || (count & 1) != 0) fprintf(stderr, "gfx: BltClear called with odd parameters\n"); - + /* Bit 2 set means use pattern (V36+ only, but we might as well emulate * it always) */ if ((flags & 4) == 0) @@ -200,33 +284,33 @@ static ULONG gfxl_BltClear(void) return 0; } - for(i = 0; i < count; i += 4) + for(i = 0; i < count; i += 4) chipmem_bank.lput(mem+i, pattern); - + if ((count & 3) != 0) chipmem_bank.wput(mem + i - 4, pattern); return 0; -} +} -static ULONG gfxl_BltBitmap(void) +static uae_u32 gfxl_BltBitmap(void) { - CPTR srcbitmap = m68k_areg(regs, 0), dstbitmap = m68k_areg(regs, 1); - int srcx = (WORD)m68k_dreg(regs, 0), srcy = (WORD)m68k_dreg(regs, 1); - int dstx = (WORD)m68k_dreg(regs, 2), dsty = (WORD)m68k_dreg(regs, 3); - int sizex = (WORD)m68k_dreg(regs, 4), sizey = (WORD)m68k_dreg(regs, 5); - UBYTE minterm = (UBYTE)m68k_dreg(regs, 6), mask = m68k_dreg(regs, 7); - return 0; /* sam: a return was missing here ! */ + uaecptr srcbitmap = m68k_areg(regs, 0), dstbitmap = m68k_areg(regs, 1); + int srcx = (uae_s16)m68k_dreg(regs, 0), srcy = (uae_s16)m68k_dreg(regs, 1); + int dstx = (uae_s16)m68k_dreg(regs, 2), dsty = (uae_s16)m68k_dreg(regs, 3); + int sizex = (uae_s16)m68k_dreg(regs, 4), sizey = (uae_s16)m68k_dreg(regs, 5); + uae_u8 minterm = (uae_u8)m68k_dreg(regs, 6), mask = m68k_dreg(regs, 7); + return 0; /* sam: a return was missing here ! */ } -static CPTR amiga_malloc(int len) +static uaecptr amiga_malloc(int len) { m68k_dreg(regs, 0) = len; m68k_dreg(regs, 1) = 1; /* MEMF_PUBLIC */ return CallLib(get_long(4), -198); /* AllocMem */ } -static void amiga_free(CPTR addr, int len) +static void amiga_free(uaecptr addr, int len) { m68k_areg(regs, 1) = addr; m68k_dreg(regs, 0) = len; @@ -235,7 +319,7 @@ static void amiga_free(CPTR addr, int le /* * Region handling code - * + * * General ideas stolen from xc/verylongpath/miregion.c * * The Clear code is untested. And and Or seem to work, Xor is only used @@ -273,12 +357,22 @@ static void init_bandlist(struct BandLis bl->maxy = (int *)malloc(20*sizeof(int)); } -static __inline__ void add_band(struct BandList *bl, int miny, int maxy, int pos) +static void dup_bandlist(struct BandList *to, struct BandList *from) +{ + to->count = from->count; + to->space = to->count+4; + to->miny = (int *)malloc (to->space*sizeof(int)); + to->maxy = (int *)malloc (to->space*sizeof(int)); + memcpy(to->miny, from->miny, to->count*sizeof(int)); + memcpy(to->maxy, from->maxy, to->count*sizeof(int)); +} + +STATIC_INLINE void add_band(struct BandList *bl, int miny, int maxy, int pos) { if (bl->count == bl->space) { bl->space += 20; - bl->miny = (int *)realloc(bl->miny, bl->space*sizeof(int)); - bl->maxy = (int *)realloc(bl->maxy, bl->space*sizeof(int)); + bl->miny = (int *)realloc(bl->miny, bl->space*sizeof(int)); + bl->maxy = (int *)realloc(bl->maxy, bl->space*sizeof(int)); } memmove(bl->miny + pos + 1, bl->miny + pos, (bl->count - pos) * sizeof(int)); memmove(bl->maxy + pos + 1, bl->maxy + pos, (bl->count - pos) * sizeof(int)); @@ -295,7 +389,16 @@ static void init_rectlist(struct RectLis rl->rects = (struct Rectangle *)malloc(100*sizeof(struct Rectangle)); } -static __inline__ void add_rect(struct RectList *rl, struct Rectangle r) +static void dup_rectlist(struct RectList *to, struct RectList *from) +{ + to->count = from->count; + to->space = to->count+4; + to->bounds = from->bounds; + to->rects = (struct Rectangle *)malloc (to->space*sizeof(struct Rectangle)); + memcpy(to->rects, from->rects, to->count*sizeof(struct Rectangle)); +} + +STATIC_INLINE void add_rect(struct RectList *rl, struct Rectangle r) { if (rl->count == 0) rl->bounds = r; @@ -311,12 +414,12 @@ static __inline__ void add_rect(struct R } if (rl->count == rl->space) { rl->space += 100; - rl->rects = (struct Rectangle *)realloc(rl->rects, rl->space*sizeof(struct Rectangle)); + rl->rects = (struct Rectangle *)realloc(rl->rects, rl->space*sizeof(struct Rectangle)); } rl->rects[rl->count++] = r; } -static __inline__ void rem_rect(struct RectList *rl, int num) +STATIC_INLINE void rem_rect(struct RectList *rl, int num) { rl->count--; if (num == rl->count) @@ -339,7 +442,7 @@ static int regionrect_cmpfn(const void * { struct Rectangle *ra = (struct Rectangle *)a; struct Rectangle *rb = (struct Rectangle *)b; - + if (ra->MinY < rb->MinY) return -1; if (ra->MinY > rb->MinY) @@ -353,79 +456,96 @@ static int regionrect_cmpfn(const void * return 1; } -static __inline__ int min(int x, int y) +STATIC_INLINE int min(int x, int y) { return x < y ? x : y; } -static __inline__ int max(int x, int y) +STATIC_INLINE int max(int x, int y) { return x > y ? x : y; } -static void region_addbands(struct RectList *rl, struct BandList *bl) +static void add_rect_to_bands(struct BandList *bl, struct Rectangle *rect) { - int i,j; + int j; + struct Rectangle tmpr = *rect; - for (i = 0; i < rl->count; i++) { - struct Rectangle tmpr = rl->rects[i]; - - for (j = 0; j < bl->count; j++) { - /* Is the current band before the rectangle? */ - if (bl->maxy[j] < tmpr.MinY) - continue; - /* Band already present? */ - if (bl->miny[j] == tmpr.MinY && bl->maxy[j] == tmpr.MaxY) - break; - /* Completely new band? Add it */ - if (bl->miny[j] > tmpr.MaxY) { - add_band(bl, tmpr.MinY, tmpr.MaxY, j); - break; - } - /* Now we know that the bands are overlapping. - * See whether they match in one point */ - if (bl->miny[j] == tmpr.MinY) { - int t; - if (bl->maxy[j] < tmpr.MaxY) { - /* Rectangle exceeds band */ - tmpr.MinY = bl->maxy[j]+1; - continue; - } - /* Rectangle splits band */ - t = bl->maxy[j]; - bl->maxy[j] = tmpr.MaxY; - tmpr.MinY = bl->maxy[j] + 1; - tmpr.MaxY = t; - continue; - } else if (bl->maxy[j] == tmpr.MaxY) { - int t; - if (bl->miny[j] > tmpr.MinY) { - /* Rectangle exceeds band */ - t = bl->miny[j]; - bl->miny[j] = tmpr.MinY; - bl->maxy[j] = t-1; - tmpr.MinY = t; - continue; - } - /* Rectangle splits band */ - bl->maxy[j] = tmpr.MinY - 1; + for (j = 0; j < bl->count; j++) { + /* Is the current band before the rectangle? */ + if (bl->maxy[j] < tmpr.MinY) + continue; + /* Band already present? */ + if (bl->miny[j] == tmpr.MinY && bl->maxy[j] == tmpr.MaxY) + break; + /* Completely new band? Add it */ + if (bl->miny[j] > tmpr.MaxY) { + add_band(bl, tmpr.MinY, tmpr.MaxY, j); + break; + } + /* Now we know that the bands are overlapping. + * See whether they match in one point */ + if (bl->miny[j] == tmpr.MinY) { + int t; + if (bl->maxy[j] < tmpr.MaxY) { + /* Rectangle exceeds band */ + tmpr.MinY = bl->maxy[j]+1; continue; } - /* Bands overlap and match in no points. Get a new band and align */ + /* Rectangle splits band */ + t = bl->maxy[j]; + bl->maxy[j] = tmpr.MaxY; + tmpr.MinY = bl->maxy[j] + 1; + tmpr.MaxY = t; + continue; + } else if (bl->maxy[j] == tmpr.MaxY) { + int t; if (bl->miny[j] > tmpr.MinY) { - /* Rectangle begins before band, so make a new band before - * and adjust rectangle */ - add_band(bl, tmpr.MinY, bl->miny[j] - 1, j); - tmpr.MinY = bl->miny[j+1]; - } else { - /* Rectangle begins in band */ - add_band(bl, bl->miny[j], tmpr.MinY - 1, j); - bl->miny[j+1] = tmpr.MinY; + /* Rectangle exceeds band */ + t = bl->miny[j]; + bl->miny[j] = tmpr.MinY; + bl->maxy[j] = t-1; + tmpr.MinY = t; + continue; } + /* Rectangle splits band */ + bl->maxy[j] = tmpr.MinY - 1; continue; } - if (j == bl->count) - add_band(bl, tmpr.MinY, tmpr.MaxY, j); + /* Bands overlap and match in no points. Get a new band and align */ + if (bl->miny[j] > tmpr.MinY) { + /* Rectangle begins before band, so make a new band before + * and adjust rectangle */ + add_band(bl, tmpr.MinY, bl->miny[j] - 1, j); + tmpr.MinY = bl->miny[j+1]; + } else { + /* Rectangle begins in band */ + add_band(bl, bl->miny[j], tmpr.MinY - 1, j); + bl->miny[j+1] = tmpr.MinY; + } + continue; + } + if (j == bl->count) + add_band(bl, tmpr.MinY, tmpr.MaxY, j); +} + +static void region_addbands(struct RectList *rl, struct BandList *bl) +{ + int i,j; + + for (i = 0; i < rl->count; i++) { + add_rect_to_bands(bl, rl->rects + i); + } +} + +static void merge_bands(struct BandList *dest, struct BandList *src) +{ + int i; + for (i = 0; i < src->count; i++) { + struct Rectangle tmp; + tmp.MinY = src->miny[i]; + tmp.MaxY = src->maxy[i]; + add_rect_to_bands(dest, &tmp); } } @@ -473,10 +593,10 @@ static void region_coalesce_rects(struct i += offs; } rl->count = j; - + if (!do_2nd_pass) return; - + /* Second pass: Coalesce bands */ for (i = 0; i < rl->count;) { int match = 0; @@ -513,9 +633,9 @@ static void region_coalesce_rects(struct } } -static int copy_rects (CPTR region, struct RectList *rl) +static int copy_rects (uaecptr region, struct RectList *rl) { - CPTR regionrect; + uaecptr regionrect; int numrects = 0; struct Rectangle b; regionrect = get_long(region+8); @@ -523,14 +643,14 @@ static int copy_rects (CPTR region, stru b.MinY = get_word(region+2); b.MaxX = get_word(region+4); b.MaxY = get_word(region+6); - + while (regionrect != 0) { struct Rectangle tmpr; - - tmpr.MinX = (WORD)get_word(regionrect+8) + b.MinX; - tmpr.MinY = (WORD)get_word(regionrect+10) + b.MinY; - tmpr.MaxX = (WORD)get_word(regionrect+12) + b.MinX; - tmpr.MaxY = (WORD)get_word(regionrect+14) + b.MinY; + + tmpr.MinX = (uae_s16)get_word(regionrect+8) + b.MinX; + tmpr.MinY = (uae_s16)get_word(regionrect+10) + b.MinY; + tmpr.MaxX = (uae_s16)get_word(regionrect+12) + b.MinX; + tmpr.MaxY = (uae_s16)get_word(regionrect+14) + b.MinY; add_rect(rl, tmpr); regionrect = get_long(regionrect); numrects++; @@ -538,6 +658,42 @@ static int copy_rects (CPTR region, stru return numrects; } +static int rect_in_region(struct RectList *rl, struct Rectangle *r) +{ + int i; + int miny = r->MinY; + + for (i = 0; i < rl->count; i++) { + int j; + if (rl->rects[i].MaxY < miny) + continue; + if (rl->rects[i].MinY > miny) + break; + if (rl->rects[i].MaxX < r->MinX) + continue; + if (rl->rects[i].MinX > r->MaxX) + break; + /* Overlap! */ + j = i; + for (;;) { + if (rl->rects[j].MaxX > r->MaxX) { + miny = rl->rects[i].MaxY + 1; + break; + } + j++; + if (j == rl->count) + break; + if (rl->rects[j].MinX != rl->rects[j-1].MaxX+1) + break; + if (rl->rects[i].MinY != rl->rects[j].MinY) + break; + } + if (miny <= rl->rects[i].MaxY) + break; + } + return 0; +} + typedef void (*regionop)(struct RectList *,struct RectList *,struct RectList *); static void region_do_ClearRegionRegion(struct RectList *rl1,struct RectList *rl2, @@ -565,9 +721,9 @@ static void region_do_ClearRegionRegion( } if (i >= rl2->count) break; - + tmpr = rl2->rects[i]; - + while (i < rl2->count && j < rl1->count && rl1->rects[j].MinY == tmpr.MinY && rl2->rects[i].MinY == tmpr.MinY @@ -732,7 +888,7 @@ static void region_do_XorRegionRegion(st tmpr2 = rl2->rects[i]; tmpr1 = rl1->rects[j]; - + while (i < rl2->count && j < rl1->count && rl1->rects[j].MinY == tmpr1.MinY && rl2->rects[i].MinY == tmpr1.MinY @@ -745,7 +901,7 @@ static void region_do_XorRegionRegion(st int oldmax1 = tmpr1.MaxX; int need_1 = 0, need_2 = 0; - if (tmpr2.MinX > tmpr1.MinX && tmpr2.MaxX < tmpr1.MaxX) + if (tmpr2.MinX > tmpr1.MinX && tmpr2.MaxX < tmpr1.MaxX) { /* * ########### @@ -840,18 +996,18 @@ static void region_do_XorRegionRegion(st add_rect(rl3, rl1->rects[j]); } -static ULONG gfxl_perform_regionop(regionop op, int with_rect) +static uae_u32 gfxl_perform_regionop(regionop op, int with_rect) { int i,j,k; - CPTR reg1; - CPTR reg2; - CPTR tmp, rpp; + uaecptr reg1; + uaecptr reg2; + uaecptr tmp, rpp; struct RectList rl1, rl2, rl3; struct BandList bl; int retval = 0; int numrects2; - + init_rectlist(&rl1); init_rectlist(&rl2); init_rectlist(&rl3); if (with_rect) { @@ -893,7 +1049,7 @@ static ULONG gfxl_perform_regionop(regio put_long(get_long(rpp) + 4, rpp); } else if (rl3.count > numrects2) { while(numrects2++ != rl3.count) { - CPTR prev = get_long(rpp); + uaecptr prev = get_long(rpp); tmp = amiga_malloc(16); if (tmp == 0) goto done; @@ -901,14 +1057,14 @@ static ULONG gfxl_perform_regionop(regio put_long(tmp + 4, rpp); if (prev != 0) put_long(prev + 4, tmp); - put_long(rpp, tmp); + put_long(rpp, tmp); } } - + if (rl3.count > 0) { rpp = reg2 + 8; for (i = 0; i < rl3.count; i++) { - CPTR rr = get_long(rpp); + uaecptr rr = get_long(rpp); put_word(rr+8, rl3.rects[i].MinX - rl3.bounds.MinX); put_word(rr+10, rl3.rects[i].MinY - rl3.bounds.MinY); put_word(rr+12, rl3.rects[i].MaxX - rl3.bounds.MinX); @@ -917,7 +1073,7 @@ static ULONG gfxl_perform_regionop(regio } if (get_long(rpp) != 0) fprintf(stderr, "BUG\n"); - } + } put_word(reg2+0, rl3.bounds.MinX); put_word(reg2+2, rl3.bounds.MinY); put_word(reg2+4, rl3.bounds.MaxX); @@ -926,58 +1082,497 @@ static ULONG gfxl_perform_regionop(regio done: free_rectlist(&rl1); free_rectlist(&rl2); free_rectlist(&rl3); - free_bandlist(&bl); + free_bandlist(&bl); return retval; } -static ULONG gfxl_AndRegionRegion(void) +static uae_u32 gfxl_AndRegionRegion(void) { return gfxl_perform_regionop(region_do_AndRegionRegion, 0); } -static ULONG gfxl_XorRegionRegion(void) +static uae_u32 gfxl_XorRegionRegion(void) { return gfxl_perform_regionop(region_do_XorRegionRegion, 0); } -static ULONG gfxl_OrRegionRegion(void) +static uae_u32 gfxl_OrRegionRegion(void) { return gfxl_perform_regionop(region_do_OrRegionRegion, 0); } -static ULONG gfxl_ClearRectRegion(void) +static uae_u32 gfxl_ClearRectRegion(void) { return gfxl_perform_regionop(region_do_ClearRegionRegion, 1); } -static ULONG gfxl_OrRectRegion(void) +static uae_u32 gfxl_OrRectRegion(void) { return gfxl_perform_regionop(region_do_OrRegionRegion, 1); } -static ULONG gfxl_AndRectRegion(void) +static uae_u32 gfxl_AndRectRegion(void) { return gfxl_perform_regionop(region_do_AndRegionRegion, 1); } -static ULONG gfxl_XorRectRegion(void) +static uae_u32 gfxl_XorRectRegion(void) { return gfxl_perform_regionop(region_do_XorRegionRegion, 1); } +/* Layers code */ + +static uae_u32 LY_TryLockLayer(uaecptr layer) +{ + uaecptr sigsem = layer + 72; + + m68k_areg(regs, 0) = sigsem; + return CallLib(get_long(4), -576); +} + +static void LY_LockLayer(uaecptr layer) +{ + uaecptr sigsem = layer + 72; + + m68k_areg(regs, 0) = sigsem; + CallLib(get_long(4), -564); +} + +static void LY_UnlockLayer(uaecptr layer) +{ + uaecptr sigsem = layer + 72; + + m68k_areg(regs, 0) = sigsem; + CallLib(get_long(4), -570); +} + +static void LY_LockLayerInfo(uaecptr li) +{ + uaecptr sigsem = li + 24; + + m68k_areg(regs, 0) = sigsem; + CallLib(get_long(4), -564); + put_byte(li+91, get_byte(li+91)+1); +} + +static void LY_UnlockLayerInfo(uaecptr li) +{ + uaecptr sigsem = li + 24; + + put_byte(li+91, get_byte(li+91)-1); + m68k_areg(regs, 0) = sigsem; + CallLib(get_long(4), -570); +} + +static void LY_LockLayers(uaecptr li) +{ + uaecptr l = get_long (li); + LY_LockLayerInfo(li); + while (l != 0) { + LY_LockLayer(l); + l = get_long(l); + } + LY_UnlockLayerInfo(li); +} + +static void LY_UnlockLayers(uaecptr li) +{ + uaecptr l = get_long (li); + LY_LockLayerInfo(li); + while (l != 0) { + LY_UnlockLayer(l); + l = get_long(l); + } + LY_UnlockLayerInfo(li); +} + +#define LAYER_CLUELESS 0x8000 /* Indicates we know nothing about the layer's regions. */ +#define LAYER_CR_CHANGED 0x4000 /* Indicates that the cliprects in Amiga memory need to be re-done */ +#define LAYER_REDO 0x2000 /* Indicates that we have regions, but they are bogus. */ + +static uae_u32 layer_uniq = 1; + +struct MyLayerInfo { + struct uniq_head head; + uaecptr amigaos_linfo; + uniq_list layer_list; +}; + +struct MyLayer { + struct uniq_head head; + uaecptr amigaos_layer, rastport; + struct Rectangle bounds; + struct RectList clipregion; + struct RectList obscured; + struct RectList visible; + struct BandList big_bands; /* created by obscuring layers */ + struct BandList small_bands; /* big_bands + those from clipregion */ + struct RectList damage; + struct BandList damage_bands; + struct MyLayerInfo *mli; +}; + +static uniq_list MyLayerInfo_list = UNIQ_INIT; + +static void LY_InitLayers(uaecptr li) +{ + memset (get_real_address(li), 0, 92); + put_long(li + 0, 0); /* top layer */ + put_long(li+84, 0); /* uniq: */ + m68k_areg(regs, 0) = li + 24; CallLib(get_long(4), -558); /* InitSemaphore() */ + put_word(li+88, 0); /* flags (???) */ + put_byte(li+89, 0); /* fatten_count */ + /* @@@ How big can I assume the structure? What's all this 1.0/1.1 cruft? */ +} + +static void LY_FattenLayerInfo(uaecptr li) +{ + struct MyLayerInfo *mli; + int fatten_count = get_byte (li + 89); + if (fatten_count == 0) { + mli = (struct MyLayerInfo *)malloc(sizeof(struct MyLayerInfo)); + add_uniq(&MyLayerInfo_list, &mli->head, li + 84); + init_uniq(&mli->layer_list); + mli->amigaos_linfo = li; + } + put_byte (li + 89, fatten_count + 1); +} + +static void LY_ThinLayerInfo(uaecptr li) +{ + int fatten_count = get_byte (li + 89)-1; + put_byte (li + 89, fatten_count); + if (fatten_count == 0) { + struct MyLayerInfo *mli = (struct MyLayerInfo *)find_and_rem_uniq(&MyLayerInfo_list, get_long(li+84)); + if (mli) + free(mli); + } +} + +static void build_cliprect (struct MyLayer *l, struct Rectangle *bounds, + int obscured, uaecptr *crp, uaecptr *prev) +{ + uaecptr cr = get_long (*crp); + if (cr == 0) { + put_long (*crp, cr = amiga_malloc(CLIPRECT_SIZE)); + put_long (cr, 0); + } + *prev = cr; + *crp = cr; + put_word (cr + 16, bounds->MinX); + put_word (cr + 18, bounds->MinY); + put_word (cr + 20, bounds->MaxX); + put_word (cr + 22, bounds->MaxY); + put_long (cr + 8, obscured ? l->amigaos_layer : 0); /* cheat */ + put_long (cr + 12, 0); /* no smart refresh yet */ +} + +static void build_cliprects (struct MyLayer *l) +{ + uaecptr layer = l->amigaos_layer; + uaecptr cr = layer + 8; + uaecptr prev = 0; + uae_u16 flags = get_word(layer + 30); + int i; + + if ((flags & LAYER_CR_CHANGED) == 0) + return; + put_word (layer + 30, flags & ~LAYER_CR_CHANGED); + for (i = 0; i < l->obscured.count; i++) { + build_cliprect (l, l->obscured.rects + i, 1, &cr, &prev); + } + for (i = 0; i < l->visible.count; i++) { + build_cliprect (l, l->visible.rects + i, 1, &cr, &prev); + } + while ((prev = get_long (cr))) { + put_long (cr, get_long (prev)); + amiga_free (prev, CLIPRECT_SIZE); + } +} + +static void propagate_clueless_redo (struct MyLayerInfo *mli) +{ + /* For all CLUELESS layers, set the REDO bit for all layers below it that overlap it + * and delete the data associated with them. */ + uaecptr current_l = get_long(mli->amigaos_linfo); + while (current_l) { + struct MyLayer *l = (struct MyLayer *)find_uniq(&mli->layer_list, get_long(current_l + 24)); + if ((get_word(l->amigaos_layer + 32) & LAYER_CLUELESS) != 0) { + uaecptr next_l = get_long(current_l); + put_word(l->amigaos_layer + 32, get_word(l->amigaos_layer + 32) | LAYER_REDO); + while (next_l) { + struct MyLayer *l2 = (struct MyLayer *)find_uniq(&mli->layer_list, get_long(next_l + 24)); + uae_u16 flags = get_word(l2->amigaos_layer + 32); + if (l2->bounds.MinX <= l->bounds.MaxX && l->bounds.MinX <= l2->bounds.MaxX + && l2->bounds.MinY <= l->bounds.MaxY && l->bounds.MinY <= l2->bounds.MaxY) + put_word(l2->amigaos_layer + 32, flags | LAYER_REDO); + if ((flags & (LAYER_REDO|LAYER_CLUELESS)) == 0) { + free_rectlist(&l->obscured); + free_rectlist(&l->visible); + free_bandlist(&l->big_bands); + free_bandlist(&l->small_bands); + } + next_l = get_long(next_l); + } + } + current_l = get_long(current_l); + } +} + +static void redo_layers(struct MyLayerInfo *mli, uaecptr bm) +{ + uaecptr current_l; + struct RectList tmp_rl; + + propagate_clueless_redo(mli); + current_l = get_long(mli->amigaos_linfo); + + while (current_l) { + struct MyLayer *l = (struct MyLayer *)find_uniq(&mli->layer_list, get_long(current_l + 24)); + uae_u16 flags = get_word(l->amigaos_layer + 32); + if ((flags & LAYER_REDO) != 0) { + uaecptr next_l = get_long(current_l+4); + int have_rects = 0; + + init_rectlist(&l->obscured); + init_bandlist(&l->big_bands); + add_rect_to_bands(&l->big_bands, &l->bounds); + + while (next_l) { + struct MyLayer *l2 = (struct MyLayer *)find_uniq(&mli->layer_list, get_long(next_l + 24)); + if (l2->visible.bounds.MinX <= l->bounds.MaxX && l->bounds.MinX <= l2->visible.bounds.MaxX + && l2->visible.bounds.MinY <= l->bounds.MaxY && l->bounds.MinY <= l2->visible.bounds.MaxY + && !rect_in_region (&l->obscured, &l2->visible.bounds)) + { + add_rect_to_bands(&l->big_bands, &l2->visible.bounds); + add_rect(&l->obscured, l2->visible.bounds); + have_rects++; + } + next_l = get_long(next_l+4); + } + init_rectlist(&l->visible); + init_rectlist(&tmp_rl); + add_rect (&tmp_rl, l->bounds); + + region_splitrects_band(&l->obscured, &l->big_bands); + region_splitrects_band(&tmp_rl, &l->big_bands); + region_do_ClearRegionRegion(&l->obscured, &tmp_rl, &l->visible); + flags |= LAYER_CR_CHANGED; + } + put_word (l->amigaos_layer + 32, flags & ~(LAYER_CLUELESS|LAYER_REDO)); + current_l = get_long(current_l); + } +} + +static struct MyLayer *LY_NewLayer(struct MyLayerInfo *mli, int x0, int x1, int y0, int y1, + uae_u16 flags, uaecptr bm, uaecptr sbm) +{ + struct MyLayer *l = (struct MyLayer *)malloc(sizeof (struct MyLayer)); + uaecptr layer = amiga_malloc(LAYER_SIZE); + memset (get_real_address(layer), 0, LAYER_SIZE); + l->amigaos_layer = layer; + + put_word(layer + 16, x0); /* bounds */ + put_word(layer + 18, y0); + put_word(layer + 20, x1); + put_word(layer + 22, y1); + put_word(layer + 30, flags | LAYER_CLUELESS); + put_long(layer + 32, flags & 4 ? sbm : 0); /* ClipRect */ + put_long(layer + 68, mli->amigaos_linfo); + m68k_areg(regs, 0) = layer + 72; CallLib(get_long(4), -558); /* InitSemaphore() */ + add_uniq(&mli->layer_list, &l->head, layer + 24); + l->mli = mli; + + l->bounds.MinX = x0; + l->bounds.MaxX = x1; + l->bounds.MinY = y0; + l->bounds.MaxY = y1; + return l; +} + +static void LY_DeleteLayer(uaecptr layer) +{ + uaecptr cr; + struct MyLayer *l = (struct MyLayer *)find_and_rem_uniq(&l->mli->layer_list, get_long (layer + 24)); + /* Free ClipRects */ + while ((cr = get_long (l->amigaos_layer + 8))) { + put_long (l->amigaos_layer + 8, get_long(cr)); + amiga_free(cr, CLIPRECT_SIZE); + } + amiga_free (l->amigaos_layer, LAYER_SIZE); + free(l); +} + +static uaecptr find_behindlayer_position(uaecptr li, uae_u16 flags) +{ + uaecptr where = li; + for (;;) { + uaecptr other = get_long (where); + /* End of list? */ + if (other == 0) + break; + /* Backdrop? */ + if ((get_word(other + 30) & 0x40) > (flags & 0x40)) + break; + where = other; + } + return where; +} + +static uaecptr LY_CreateLayer(uaecptr li, int x0, int x1, int y0, int y1, + uae_u16 flags, uaecptr bm, uaecptr sbm, uaecptr where) +{ + struct MyLayerInfo *mli = (struct MyLayerInfo *)find_uniq(&MyLayerInfo_list, get_long (li + 84)); + struct MyLayer *l; + + LY_LockLayerInfo(li); + + l = LY_NewLayer(mli, x0, x1, y0, y1, flags, bm, sbm); + /* Chain into list */ + put_long(l->amigaos_layer, get_long (where)); + put_long(l->amigaos_layer + 4, where == li ? 0 : where); + if (get_long (where) != 0) + put_long(get_long (where) + 4, l->amigaos_layer); + put_long(where, l->amigaos_layer); + redo_layers(mli, bm); + build_cliprects(l); + LY_UnlockLayerInfo(li); + return l->amigaos_layer; +} + +static void LY_DisposeLayerInfo(uaecptr li) +{ + LY_ThinLayerInfo(li); + amiga_free(li, LINFO_SIZE); +} + +static uae_u32 layers_NewLayerInfo(void) +{ + uaecptr li = amiga_malloc(LINFO_SIZE); + LY_InitLayers(li); + LY_FattenLayerInfo(li); + return li; +} +static uae_u32 layers_InitLayers(void) { LY_InitLayers (m68k_areg (regs, 0)); return 0; } +static uae_u32 layers_DisposeLayerInfo(void) { LY_DisposeLayerInfo (m68k_areg (regs, 0)); return 0; } + +static uae_u32 layers_FattenLayerInfo(void) { LY_FattenLayerInfo(m68k_areg(regs, 0)); return 0; } +static uae_u32 layers_ThinLayerInfo(void) { LY_ThinLayerInfo(m68k_areg(regs, 0)); return 0; } + +static uae_u32 layers_CreateUpfrontLayer(void) +{ + return LY_CreateLayer(m68k_areg(regs, 0), (uae_s32)m68k_dreg(regs, 0), + (uae_s32)m68k_dreg(regs, 1), (uae_s32)m68k_dreg(regs, 2), + (uae_s32)m68k_dreg(regs, 3), + m68k_dreg(regs, 4), + m68k_areg(regs, 1), m68k_areg(regs, 2), m68k_areg(regs, 0)); +} +static uae_u32 layers_CreateBehindLayer(void) +{ + return LY_CreateLayer(m68k_areg(regs, 0), (uae_s32)m68k_dreg(regs, 0), + (uae_s32)m68k_dreg(regs, 1), (uae_s32)m68k_dreg(regs, 2), + (uae_s32)m68k_dreg(regs, 3), + m68k_dreg(regs, 4), + m68k_areg(regs, 1), m68k_areg(regs, 2), + find_behindlayer_position (m68k_areg(regs, 0), m68k_dreg(regs, 4))); +} +static uae_u32 layers_DeleteLayer(void) { LY_DeleteLayer (m68k_areg (regs, 1)); return 0; } + +static void LY_LockLayer1(uaecptr layer) +{ + uaecptr li = get_long (layer + 68); + struct MyLayerInfo *mli = (struct MyLayerInfo *)find_uniq (&MyLayerInfo_list, get_long (li + 84)); + struct MyLayer *l = (struct MyLayer *)find_uniq (&mli->layer_list, get_long (layer + 24)); + + LY_LockLayer(layer); + build_cliprects (l); +} +static uae_u32 LY_TryLockLayer1(uaecptr layer) +{ + uaecptr li = get_long (layer + 68); + struct MyLayerInfo *mli = (struct MyLayerInfo *)find_uniq (&MyLayerInfo_list, get_long (li + 84)); + struct MyLayer *l = (struct MyLayer *)find_uniq (&mli->layer_list, get_long (layer + 24)); + + if (!LY_TryLockLayer(layer)) + return 0; + build_cliprects (l); + return 1; +} +static uae_u32 gfx_TryLockLayer(void) { return LY_TryLockLayer1 (m68k_areg(regs, 5)); } +static uae_u32 gfx_LockLayer(void) { LY_LockLayer1 (m68k_areg(regs, 5)); return 0; } +static uae_u32 gfx_UnlockLayer(void) { LY_UnlockLayer(m68k_areg(regs, 5)); return 0; } +static uae_u32 layers_LockLayer(void) { LY_LockLayer1 (m68k_areg(regs, 1)); return 0; } +static uae_u32 layers_LockLayers(void) { LY_LockLayers(m68k_areg(regs, 0)); return 0; } +static uae_u32 layers_LockLayerInfo(void) { LY_LockLayerInfo(m68k_areg(regs, 0)); return 0; } +static uae_u32 layers_UnlockLayer(void) { LY_UnlockLayer(m68k_areg(regs, 0)); return 0; } +static uae_u32 layers_UnlockLayers(void) { LY_UnlockLayers(m68k_areg(regs, 0)); return 0; } +static uae_u32 layers_UnlockLayerInfo(void) { LY_UnlockLayerInfo(m68k_areg(regs, 0)); return 0; } + +static uae_u32 layers_ScrollLayer(void) +{ + abort(); +} + +static uae_u32 layers_SizeLayer(void) +{ + abort(); +} + +static uae_u32 layers_MoveLayer(void) +{ + abort(); +} + +static uae_u32 layers_UpfrontLayer(void) +{ + abort(); +} + +static uae_u32 layers_BehindLayer(void) +{ + abort(); +} + +static uae_u32 layers_MoveLayerInFrontOf(void) +{ + abort(); +} + +static uae_u32 layers_BeginUpdate(void) +{ + return 1; +} + +static uae_u32 layers_EndUpdate(void) +{ + return 0; +} + +static uae_u32 layers_WhichLayer(void) +{ + abort(); +} + +static uae_u32 layers_InstallClipRegion(void) +{ + return 0; +} + +static uae_u32 layers_SwapBitsRastPortClipRect(void) +{ + abort(); +} + /* * Initialization */ -static ULONG gfxlib_init(void) +static uae_u32 gfxlib_init(void) { - ULONG old_arr; - CPTR gfxbase, layersbase; - CPTR sysbase=m68k_areg(regs, 6); + uae_u32 old_arr; + uaecptr sysbase=m68k_areg(regs, 6); int i=0; /* Install new routines */ - /* We have to call SetFunction here instead of writing direktly into the GfxBase, - * because of the library checksum ! */ - m68k_dreg(regs, 0)=0; m68k_areg(regs, 1)=gfxlibname; gfxbase=CallLib(sysbase, -408); /* OpenLibrary */ @@ -985,49 +1580,83 @@ static ULONG gfxlib_init(void) m68k_areg(regs, 1)=layerslibname; layersbase=CallLib(sysbase, -408); /* OpenLibrary */ - libemu_InstallFunction(gfxl_WritePixel, gfxbase, -324, ""); - libemu_InstallFunction(gfxl_BltClear, gfxbase, -300, ""); - libemu_InstallFunction(gfxl_AndRegionRegion, gfxbase, -624, ""); - libemu_InstallFunction(gfxl_OrRegionRegion, gfxbase, -612, ""); - libemu_InstallFunction(gfxl_XorRegionRegion, gfxbase, -618, ""); - libemu_InstallFunction(gfxl_AndRectRegion, gfxbase, -504, ""); - libemu_InstallFunction(gfxl_OrRectRegion, gfxbase, -510, ""); - libemu_InstallFunction(gfxl_XorRectRegion, gfxbase, -558, ""); - libemu_InstallFunction(gfxl_ClearRectRegion, gfxbase, -522, ""); - - libemu_InstallFunction(NULL, layersbase, -60, "MoveLayer"); - libemu_InstallFunction(NULL, layersbase, -96, "LockLayer"); - libemu_InstallFunction(NULL, layersbase, -102, "UnlockLayer"); - libemu_InstallFunction(NULL, layersbase, -108, "LockLayers"); - libemu_InstallFunction(NULL, layersbase, -114, "UnlockLayers"); - libemu_InstallFunction(NULL, layersbase, -120, "LockLayerInfo"); - libemu_InstallFunction(NULL, layersbase, -138, "UnlockLayerInfo"); - libemu_InstallFunction(NULL, layersbase, -144, "NewLayerInfo"); - libemu_InstallFunction(NULL, layersbase, -156, "FattenLayerInfo"); + libemu_InstallFunctionFlags(gfxl_WritePixel, gfxbase, -324, TRAPFLAG_EXTRA_STACK, ""); + libemu_InstallFunctionFlags(gfxl_BltClear, gfxbase, -300, 0, ""); + libemu_InstallFunctionFlags(gfxl_AndRegionRegion, gfxbase, -624, TRAPFLAG_EXTRA_STACK, ""); + libemu_InstallFunctionFlags(gfxl_OrRegionRegion, gfxbase, -612, TRAPFLAG_EXTRA_STACK, ""); + libemu_InstallFunctionFlags(gfxl_XorRegionRegion, gfxbase, -618, TRAPFLAG_EXTRA_STACK, ""); + libemu_InstallFunctionFlags(gfxl_AndRectRegion, gfxbase, -504, TRAPFLAG_EXTRA_STACK, ""); + libemu_InstallFunctionFlags(gfxl_OrRectRegion, gfxbase, -510, TRAPFLAG_EXTRA_STACK, ""); + libemu_InstallFunctionFlags(gfxl_XorRectRegion, gfxbase, -558, TRAPFLAG_EXTRA_STACK, ""); + libemu_InstallFunctionFlags(gfxl_ClearRectRegion, gfxbase, -522, TRAPFLAG_EXTRA_STACK, ""); + +#if 0 +#define MAYBE_FUNCTION(a) NULL +#else +#define MAYBE_FUNCTION(a) (a) +#endif +#if 0 + libemu_InstallFunctionFlags(MAYBE_FUNCTION(gfx_TryLockLayer), gfxbase, -654, TRAPFLAG_EXTRA_STACK|TRAPFLAG_NO_RETVAL, "AttemptLockLayerRom"); + libemu_InstallFunctionFlags(MAYBE_FUNCTION(gfx_LockLayer), gfxbase, -432, TRAPFLAG_EXTRA_STACK|TRAPFLAG_NO_RETVAL, "LockLayerRom"); + libemu_InstallFunctionFlags(MAYBE_FUNCTION(gfx_UnlockLayer), gfxbase, -438, TRAPFLAG_EXTRA_STACK|TRAPFLAG_NO_RETVAL, "UnlockLayerRom"); + + libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_InitLayers), layersbase, -30, TRAPFLAG_EXTRA_STACK, "InitLayers"); + libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_CreateUpfrontLayer), layersbase, -36, TRAPFLAG_EXTRA_STACK, "CreateUpfrontLayer"); + libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_CreateBehindLayer), layersbase, -42, TRAPFLAG_EXTRA_STACK, "CreateBehindLayer"); + libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_UpfrontLayer), layersbase, -48, TRAPFLAG_EXTRA_STACK, "UpfrontLayer"); + libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_BehindLayer), layersbase, -54, TRAPFLAG_EXTRA_STACK, "BehindLayer"); + libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_MoveLayer), layersbase, -60, TRAPFLAG_EXTRA_STACK, "MoveLayer"); + libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_SizeLayer), layersbase, -66, TRAPFLAG_EXTRA_STACK, "SizeLayer"); + libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_ScrollLayer), layersbase, -72, TRAPFLAG_EXTRA_STACK, "ScrollLayer"); + libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_BeginUpdate), layersbase, -78, TRAPFLAG_EXTRA_STACK, "BeginUpdate"); + libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_EndUpdate), layersbase, -84, TRAPFLAG_EXTRA_STACK, "EndUpdate"); + libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_DeleteLayer), layersbase, -90, TRAPFLAG_EXTRA_STACK, "DeleteLayer"); + libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_LockLayer), layersbase, -96, TRAPFLAG_EXTRA_STACK, "LockLayer"); + libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_UnlockLayer), layersbase, -102, TRAPFLAG_EXTRA_STACK, "UnlockLayer"); + libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_LockLayers), layersbase, -108, TRAPFLAG_EXTRA_STACK, "LockLayers"); + libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_UnlockLayers), layersbase, -114, TRAPFLAG_EXTRA_STACK, "UnlockLayers"); + libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_LockLayerInfo), layersbase, -120, TRAPFLAG_EXTRA_STACK, "LockLayerInfo"); + libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_SwapBitsRastPortClipRect), layersbase, -126, TRAPFLAG_EXTRA_STACK, "SwapBitsRastPortClipRect"); + libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_WhichLayer), layersbase, -132, TRAPFLAG_EXTRA_STACK, "WhichLayer"); + libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_UnlockLayerInfo), layersbase, -138, TRAPFLAG_EXTRA_STACK, "UnlockLayerInfo"); + libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_NewLayerInfo), layersbase, -144, TRAPFLAG_EXTRA_STACK, "NewLayerInfo"); + libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_DisposeLayerInfo), layersbase, -150, TRAPFLAG_EXTRA_STACK, "DisposeLayerInfo"); + libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_FattenLayerInfo), layersbase, -156, TRAPFLAG_EXTRA_STACK, "FattenLayerInfo"); + libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_ThinLayerInfo), layersbase, -162, TRAPFLAG_EXTRA_STACK, "ThinLayerInfo"); + libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_MoveLayerInFrontOf), layersbase, -168, TRAPFLAG_EXTRA_STACK, "MoveLayerInFrontOf"); + libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_InstallClipRegion), layersbase, -174, TRAPFLAG_EXTRA_STACK, "InstallClipRegion"); +#if 0 + libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_), layersbase, -180, TRAPFLAG_EXTRA_STACK, "MoveSizeLayer"); + libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_), layersbase, -186, TRAPFLAG_EXTRA_STACK, "CreateUpfrontHookLayer"); + libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_), layersbase, -192, TRAPFLAG_EXTRA_STACK, "CreateBehindHookLayer"); + libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_), layersbase, -198, TRAPFLAG_EXTRA_STACK, "InstallLayerHook"); +#endif +#endif return 0; } -/* - * Install the gfx-library-replacement +/* + * Install the gfx-library-replacement */ void gfxlib_install(void) { - ULONG begin, end, resname, resid; + uae_u32 begin, end, resname, resid; int i; - - if(!use_gfxlib) return; - - fprintf(stderr, "Warning: you enabled the graphics.library replacement with -g\n" - "This may be buggy right now, and will not speed things up much.\n"); - resname = ds("UAEgfxlib.resource"); - resid = ds("UAE gfxlib 0.1"); + if (! currprefs.use_gfxlib) + return; + + fprintf (stderr, "Warning: you enabled the graphics.library replacement with -g\n" + "This may be buggy right now, and will not speed things up much.\n"); + + resname = ds ("UAEgfxlib.resource"); + resid = ds ("UAE gfxlib 0.1"); - gfxlibname = ds("graphics.library"); - layerslibname = ds("layers.library"); + gfxlibname = ds ("graphics.library"); + layerslibname = ds ("layers.library"); begin = here(); - dw(0x4AFC); /* RTC_MATCHWORD */ + dw(0x4AFC); /* RTC_MATCHuae_s16 */ dl(begin); /* our start address */ dl(0); /* Continue scan here */ dw(0x0101); /* RTF_COLDSTART; Version 1 */ @@ -1036,7 +1665,7 @@ void gfxlib_install(void) dl(resid); /* ID */ dl(here() + 4); /* Init area: directly after this */ - calltrap(deftrap(gfxlib_init)); dw(RTS); + calltrap(deftrap2(gfxlib_init, TRAPFLAG_EXTRA_STACK, "")); dw(RTS); end = here(); org(begin + 6); @@ -1044,3 +1673,10 @@ void gfxlib_install(void) org(end); } +#else + +void gfxlib_install (void) +{ +} + +#endif