Annotation of uae/src/gfxlib.c, revision 1.1.1.4

1.1       root        1:  /*
                      2:   * UAE - The Un*x Amiga Emulator
                      3:   *
                      4:   * graphics.library emulation
                      5:   *
1.1.1.3   root        6:   * Copyright 1996, 1997 Bernd Schmidt
                      7:   *
1.1.1.2   root        8:   * Ideas for this:
                      9:   * Rewrite layers completely. When there are lots of windows on the screen
                     10:   * it can take 3 minutes to update everything after resizing or moving one
                     11:   * (at least with Kick 1.3). Hide the internal structure of the layers as far
                     12:   * as possible, keep most of the data in emulator space so we save copying/
                     13:   * conversion time. Programs really shouldn't do anything directly with the
                     14:   * Layer or ClipRect structures.
                     15:   * This means that a lot of graphics.library functions will have to be
1.1.1.3   root       16:   * rewritten as well.
1.1.1.2   root       17:   * Once that's done, add support for non-planar bitmaps. Conveniently, the
                     18:   * struct Bitmap has an unused pad field which we could abuse as some sort of
                     19:   * type field. Need to add chunky<->planar conversion routines to get it
                     20:   * going, plus variants of all the drawing functions for speed reasons.
1.1.1.3   root       21:   *
1.1.1.2   root       22:   * When it becomes necessary to convert a structure from Amiga memory, make
                     23:   * a function with a name ending in ..FA, which takes a pointer to the
1.1.1.3   root       24:   * native structure and a uaecptr and returns the native pointer.
1.1       root       25:   */
                     26: 
                     27: #include "sysconfig.h"
                     28: #include "sysdeps.h"
                     29: 
                     30: #include <assert.h>
                     31: 
                     32: #include "config.h"
                     33: #include "options.h"
1.1.1.3   root       34: #include "threaddep/penguin.h"
1.1       root       35: #include "memory.h"
                     36: #include "custom.h"
1.1.1.2   root       37: #include "readcpu.h"
1.1       root       38: #include "newcpu.h"
                     39: #include "xwin.h"
                     40: #include "autoconf.h"
                     41: #include "osemu.h"
1.1.1.3   root       42: #include "osdep/exectasks.h"
1.1       root       43: 
1.1.1.3   root       44: #ifdef USE_EXECLIB
                     45: 
                     46: /* Uniq list management. Should be in a separate file. */
                     47: struct uniq_head {
                     48:     struct uniq_head *next;
                     49:     uae_u32 uniq;
                     50: };
                     51: 
                     52: typedef struct {
                     53:     struct uniq_head *head;
                     54:     uae_u32 uniq;
                     55: } uniq_list;
                     56: 
                     57: #define UNIQ_INIT { NULL, 1 }
                     58: 
                     59: static void init_uniq(uniq_list *list)
                     60: {
                     61:     list->head = NULL;
                     62:     list->uniq = 1;
                     63: }
                     64: 
                     65: static struct uniq_head *find_uniq (uniq_list *a, uae_u32 uniq)
                     66: {
                     67:     struct uniq_head *b = a->head;
                     68:     while (b && b->uniq != uniq)
                     69:        b = b->next;
                     70:     if (!b)
                     71:        write_log("Couldn't find structure. Bad\n");
                     72:     return b;
                     73: }
                     74: 
                     75: static struct uniq_head *find_and_rem_uniq (uniq_list *a, uae_u32 uniq)
                     76: {
                     77:     struct uniq_head **b = &a->head, *c;
                     78:     while (*b && (*b)->uniq != uniq)
                     79:        b = &(*b)->next;
                     80:     c = *b;
                     81:     if (!c)
                     82:        write_log("Couldn't find structure. Bad\n");
                     83:     else
                     84:        *b = c->next;
                     85:     return c;
                     86: }
                     87: 
                     88: static void add_uniq (uniq_list *a, struct uniq_head *item, uaecptr amem)
                     89: {
                     90:     item->uniq = a->uniq++;
                     91:     put_long(amem, item->uniq);
                     92:     if (a->uniq == 0)
                     93:        a->uniq++;
                     94:     item->next = a->head;
                     95:     a->head = item;
                     96: }
                     97: 
                     98: /* Graphics stuff begins here */
                     99: #define CLIPRECT_SIZE 40
                    100: #define LAYER_SIZE 160
                    101: #define LINFO_SIZE 102
                    102: 
                    103: static uaecptr gfxbase, layersbase;
                    104: 
                    105: static void do_LockLayer(uaecptr layer)
                    106: {
                    107: #if 0 /* Later.. */
                    108:     uaecptr sigsem = layer + 72;
                    109:     m68k_areg(regs, 0) = sigsem;
                    110:     CallLib(get_long(4), -564);
                    111: #else
                    112:     m68k_areg(regs, 1) = layer;
                    113:     CallLib(layersbase, -96);
                    114: #endif
                    115: }
                    116: 
                    117: static void do_UnlockLayer(uaecptr layer)
                    118: {
                    119:     m68k_areg(regs, 0) = layer;
                    120:     CallLib(layersbase, -102);
                    121: }
                    122: 
                    123: static uae_u32 gfxlibname, layerslibname;
1.1.1.2   root      124: 
                    125: struct Rectangle {
                    126:     int MinX, MinY, MaxX, MaxY;
                    127: };
1.1       root      128: 
1.1.1.3   root      129: static int GFX_PointInRectangle(uaecptr rect, int x, int y)
1.1       root      130: {
1.1.1.3   root      131:     uae_s16 minx = get_word(rect);
                    132:     uae_s16 miny = get_word(rect+2);
                    133:     uae_s16 maxx = get_word(rect+4);
                    134:     uae_s16 maxy = get_word(rect+6);
                    135: 
1.1       root      136:     if (x < minx || x > maxx || y < miny || y > maxy)
                    137:        return 0;
                    138:     return 1;
                    139: }
                    140: 
1.1.1.2   root      141: static int GFX_RectContainsRect(struct Rectangle *r1, struct Rectangle *r2)
                    142: {
                    143:     return (r2->MinX >= r1->MinX && r2->MaxX <= r1->MaxX
                    144:            && r2->MinY >= r1->MinY && r2->MaxY <= r1->MaxY);
                    145: }
                    146: 
1.1.1.3   root      147: static struct Rectangle *GFX_RectFA(struct Rectangle *rp, uaecptr rect)
1.1.1.2   root      148: {
1.1.1.3   root      149:     rp->MinX = (uae_s16)get_word(rect);
                    150:     rp->MinY = (uae_s16)get_word(rect+2);
                    151:     rp->MaxX = (uae_s16)get_word(rect+4);
                    152:     rp->MaxY = (uae_s16)get_word(rect+6);
1.1.1.2   root      153:     return rp;
                    154: }
                    155: 
1.1.1.3   root      156: static int GFX_Bitmap_WritePixel(uaecptr bitmap, int x, int y, uaecptr rp)
1.1       root      157: {
                    158:     int i, offs;
                    159:     unsigned int bpr = get_word (bitmap);
                    160:     unsigned int rows = get_word (bitmap + 2);
1.1.1.3   root      161:     uae_u16 mask;
1.1       root      162: 
1.1.1.3   root      163:     uae_u8 planemask = get_byte(rp + 24);
                    164:     uae_u8 fgpen = get_byte(rp + 25);
                    165:     uae_u8 bgpen = get_byte(rp + 26);
                    166:     uae_u8 drmd = get_byte(rp + 28);
                    167:     uae_u8 pen = drmd & 4 ? bgpen : fgpen;
1.1       root      168: 
                    169:     if (x < 0 || y < 0 || x >= 8*bpr || y >= rows)
                    170:        return -1;
1.1.1.3   root      171: 
1.1       root      172:     offs = y*bpr + (x & ~15)/8;
                    173: 
                    174:     for (i = 0; i < get_byte (bitmap + 5); i++) {
1.1.1.3   root      175:        uaecptr planeptr;
                    176:        uae_u16 data;
1.1       root      177: 
                    178:        if ((planemask & (1 << i)) == 0)
                    179:            continue;
                    180: 
                    181:        planeptr = get_long(bitmap + 8 + i*4);
                    182:        data = get_word(planeptr + offs);
1.1.1.3   root      183: 
1.1       root      184:        mask = 0x8000 >> (x & 15);
1.1.1.3   root      185: 
1.1       root      186:        if (drmd & 2) {
                    187:            if ((pen & (1 << i)) != 0)
                    188:                data ^=mask;
                    189:        } else {
                    190:            data &= ~mask;
                    191:            if ((pen & (1 << i)) != 0)
                    192:                data |= mask;
1.1.1.3   root      193:        }
1.1       root      194:        put_word(planeptr + offs, data);
                    195:     }
                    196:     return 0;
                    197: }
                    198: 
1.1.1.3   root      199: int GFX_WritePixel(uaecptr rp, int x, int y)
1.1       root      200: {
1.1.1.3   root      201:     int v;
                    202:     uaecptr layer = get_long(rp);
                    203:     uaecptr bitmap = get_long(rp + 4);
                    204:     uaecptr cliprect;
1.1       root      205:     int x2, y2;
                    206: 
                    207:     if (bitmap == 0) {
                    208:        fprintf(stderr, "bogus RastPort in WritePixel\n");
                    209:        return -1;
                    210:     }
                    211: 
                    212:     /* Easy case first */
                    213:     if (layer == 0) {
                    214:        return GFX_Bitmap_WritePixel(bitmap, x, y, rp);
                    215:     }
1.1.1.3   root      216:     do_LockLayer(layer);
1.1       root      217:     /*
                    218:      * Now, in theory we ought to obtain the semaphore.
                    219:      * Since we don't, the programs will happily write into the raster
                    220:      * even though we are currently moving the window around.
                    221:      * Not good.
                    222:      */
1.1.1.3   root      223: 
                    224:     x2 = x + (uae_s16)get_word(layer + 16);
                    225:     y2 = y + (uae_s16)get_word(layer + 18);
                    226: 
                    227:     if (!GFX_PointInRectangle (layer + 16, x2, y2)) {
                    228:        do_UnlockLayer(layer);
1.1       root      229:        return -1;
1.1.1.3   root      230:     }
1.1       root      231:     /* Find the right ClipRect */
                    232:     cliprect = get_long(layer + 8);
                    233:     while (cliprect != 0 && !GFX_PointInRectangle (cliprect + 16, x2, y2))
                    234:        cliprect = get_long(cliprect);
                    235:     if (cliprect == 0) {
                    236:        /* Don't complain: The "Dots" demo does this all the time. I
                    237:         * suppose if we can't find a ClipRect, we aren't supposed to draw
                    238:         * the dot.
                    239:         */
                    240:        /*fprintf(stderr, "Weirdness in WritePixel\n");*/
1.1.1.3   root      241:        v = -1;
                    242:     } else if (get_long(cliprect + 8) == 0) {
                    243:        v = GFX_Bitmap_WritePixel(bitmap, x2, y2, rp);
                    244:     } else if (get_long(cliprect + 12) == 0) {
                    245:        /* I don't really know what to do here... */
                    246:        v = 0;
                    247:     } else {
                    248:        /* This appears to be normal for smart refresh layers which are obscured */
                    249:        v = GFX_Bitmap_WritePixel (get_long(cliprect + 12), x2 - (uae_s16)get_word(cliprect + 16),
                    250:                                   y2 - (uae_s16)get_word(cliprect + 18), rp);
1.1       root      251:     }
1.1.1.3   root      252:     do_UnlockLayer(layer);
                    253:     return v;
1.1       root      254: }
                    255: 
                    256: 
1.1.1.3   root      257: 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)); }
1.1       root      258: 
1.1.1.3   root      259: static uae_u32 gfxl_BltClear(void)
1.1       root      260: {
1.1.1.3   root      261:     uaecptr mem=m68k_areg(regs, 1);
                    262:     uae_u8 *mptr = chipmem_bank.xlateaddr(m68k_areg(regs, 1));
                    263:     uae_u32 count=m68k_dreg(regs, 0);
                    264:     uae_u32 flags=m68k_dreg(regs, 1);
1.1       root      265:     unsigned int i;
1.1.1.3   root      266:     uae_u32 pattern;
1.1       root      267: 
                    268:     if ((flags & 2) == 2){
                    269:        /* count is given in Rows / Bytes per row */
                    270:        count=(count & 0xFFFF) * (count >> 16);
                    271:     }
                    272: 
                    273:     if ((mem & 1) != 0 || (count & 1) != 0)
                    274:        fprintf(stderr, "gfx: BltClear called with odd parameters\n");
1.1.1.3   root      275: 
1.1       root      276:     /* Bit 2 set means use pattern (V36+ only, but we might as well emulate
                    277:      * it always) */
                    278:     if ((flags & 4) == 0)
                    279:        pattern = 0;
                    280:     else
1.1.1.2   root      281:        pattern= ((flags >> 16) & 0xFFFF) | (flags & 0xFFFF0000ul);
1.1       root      282: 
                    283:     if ((pattern & 0xFF) == ((pattern >> 8) & 0xFF)) {
                    284:        memset(mptr, pattern, count);
                    285:        return 0;
                    286:     }
                    287: 
1.1.1.3   root      288:     for(i = 0; i < count; i += 4)
1.1       root      289:        chipmem_bank.lput(mem+i, pattern);
1.1.1.3   root      290: 
1.1       root      291:     if ((count & 3) != 0)
                    292:        chipmem_bank.wput(mem + i - 4, pattern);
                    293: 
                    294:     return 0;
1.1.1.3   root      295: }
1.1       root      296: 
1.1.1.3   root      297: static uae_u32 gfxl_BltBitmap(void)
1.1       root      298: {
1.1.1.3   root      299:     uaecptr srcbitmap = m68k_areg(regs, 0), dstbitmap = m68k_areg(regs, 1);
                    300:     int srcx = (uae_s16)m68k_dreg(regs, 0), srcy = (uae_s16)m68k_dreg(regs, 1);
                    301:     int dstx = (uae_s16)m68k_dreg(regs, 2), dsty = (uae_s16)m68k_dreg(regs, 3);
                    302:     int sizex = (uae_s16)m68k_dreg(regs, 4), sizey = (uae_s16)m68k_dreg(regs, 5);
                    303:     uae_u8 minterm = (uae_u8)m68k_dreg(regs, 6), mask = m68k_dreg(regs, 7);
                    304:     return 0; /* sam: a return was missing here ! */
1.1       root      305: }
                    306: 
1.1.1.3   root      307: static uaecptr amiga_malloc(int len)
1.1       root      308: {
1.1.1.2   root      309:     m68k_dreg(regs, 0) = len;
                    310:     m68k_dreg(regs, 1) = 1; /* MEMF_PUBLIC */
1.1       root      311:     return CallLib(get_long(4), -198); /* AllocMem */
                    312: }
                    313: 
1.1.1.3   root      314: static void amiga_free(uaecptr addr, int len)
1.1       root      315: {
1.1.1.2   root      316:     m68k_areg(regs, 1) = addr;
                    317:     m68k_dreg(regs, 0) = len;
1.1       root      318:     CallLib(get_long(4), -210); /* FreeMem */
                    319: }
                    320: 
                    321: /*
                    322:  * Region handling code
1.1.1.3   root      323:  *
1.1.1.2   root      324:  * General ideas stolen from xc/verylongpath/miregion.c
1.1       root      325:  *
                    326:  * The Clear code is untested. And and Or seem to work, Xor is only used
                    327:  * by the 1.3 Prefs program and seems to work, too.
                    328:  */
                    329: 
                    330: struct RegionRectangle {
                    331:     struct RegionRectangle *Next,*Prev;
                    332:     struct Rectangle bounds;
                    333: };
                    334: 
                    335: struct Region {
                    336:     struct Rectangle bounds;
                    337:     struct RegionRectangle *RegionRectangle;
                    338: };
                    339: 
                    340: struct RectList {
                    341:     int count;
                    342:     int space;
                    343:     struct Rectangle bounds;
                    344:     struct Rectangle *rects;
                    345: };
                    346: 
                    347: struct BandList {
                    348:     int count;
                    349:     int space;
                    350:     int *miny, *maxy;
                    351: };
                    352: 
                    353: static void init_bandlist(struct BandList *bl)
                    354: {
                    355:     bl->count = 0;
                    356:     bl->space = 20;
                    357:     bl->miny = (int *)malloc(20*sizeof(int));
                    358:     bl->maxy = (int *)malloc(20*sizeof(int));
                    359: }
                    360: 
1.1.1.3   root      361: static void dup_bandlist(struct BandList *to, struct BandList *from)
                    362: {
                    363:     to->count = from->count;
                    364:     to->space = to->count+4;
                    365:     to->miny = (int *)malloc (to->space*sizeof(int));
                    366:     to->maxy = (int *)malloc (to->space*sizeof(int));
                    367:     memcpy(to->miny, from->miny, to->count*sizeof(int));
                    368:     memcpy(to->maxy, from->maxy, to->count*sizeof(int));
                    369: }
                    370: 
1.1       root      371: static __inline__ void add_band(struct BandList *bl, int miny, int maxy, int pos)
                    372: {
                    373:     if (bl->count == bl->space) {
                    374:        bl->space += 20;
1.1.1.3   root      375:        bl->miny = (int *)realloc(bl->miny, bl->space*sizeof(int));
                    376:        bl->maxy = (int *)realloc(bl->maxy, bl->space*sizeof(int));
1.1       root      377:     }
                    378:     memmove(bl->miny + pos + 1, bl->miny + pos, (bl->count - pos) * sizeof(int));
                    379:     memmove(bl->maxy + pos + 1, bl->maxy + pos, (bl->count - pos) * sizeof(int));
                    380:     bl->count++;
                    381:     bl->miny[pos] = miny;
                    382:     bl->maxy[pos] = maxy;
                    383: }
                    384: 
                    385: static void init_rectlist(struct RectList *rl)
                    386: {
                    387:     rl->count = 0;
                    388:     rl->space = 100;
                    389:     rl->bounds.MinX = rl->bounds.MinY = rl->bounds.MaxX = rl->bounds.MaxY = 0;
                    390:     rl->rects = (struct Rectangle *)malloc(100*sizeof(struct Rectangle));
                    391: }
                    392: 
1.1.1.3   root      393: static void dup_rectlist(struct RectList *to, struct RectList *from)
                    394: {
                    395:     to->count = from->count;
                    396:     to->space = to->count+4;
                    397:     to->bounds = from->bounds;
                    398:     to->rects = (struct Rectangle *)malloc (to->space*sizeof(struct Rectangle));
                    399:     memcpy(to->rects, from->rects, to->count*sizeof(struct Rectangle));
                    400: }
                    401: 
1.1       root      402: static __inline__ void add_rect(struct RectList *rl, struct Rectangle r)
                    403: {
                    404:     if (rl->count == 0)
                    405:        rl->bounds = r;
                    406:     else {
                    407:        if (r.MinX < rl->bounds.MinX)
                    408:            rl->bounds.MinX = r.MinX;
                    409:        if (r.MinY < rl->bounds.MinY)
                    410:            rl->bounds.MinY = r.MinY;
                    411:        if (r.MaxX > rl->bounds.MaxX)
                    412:            rl->bounds.MaxX = r.MaxX;
                    413:        if (r.MaxY > rl->bounds.MaxY)
                    414:            rl->bounds.MaxY = r.MaxY;
                    415:     }
                    416:     if (rl->count == rl->space) {
                    417:        rl->space += 100;
1.1.1.3   root      418:        rl->rects = (struct Rectangle *)realloc(rl->rects, rl->space*sizeof(struct Rectangle));
1.1       root      419:     }
                    420:     rl->rects[rl->count++] = r;
                    421: }
                    422: 
                    423: static __inline__ void rem_rect(struct RectList *rl, int num)
                    424: {
                    425:     rl->count--;
                    426:     if (num == rl->count)
                    427:        return;
                    428:     rl->rects[num] = rl->rects[rl->count];
                    429: }
                    430: 
                    431: static void free_rectlist(struct RectList *rl)
                    432: {
                    433:     free(rl->rects);
                    434: }
                    435: 
                    436: static void free_bandlist(struct BandList *bl)
                    437: {
                    438:     free(bl->miny);
                    439:     free(bl->maxy);
                    440: }
                    441: 
                    442: static int regionrect_cmpfn(const void *a, const void *b)
                    443: {
                    444:     struct Rectangle *ra = (struct Rectangle *)a;
                    445:     struct Rectangle *rb = (struct Rectangle *)b;
1.1.1.3   root      446: 
1.1       root      447:     if (ra->MinY < rb->MinY)
                    448:        return -1;
                    449:     if (ra->MinY > rb->MinY)
                    450:        return 1;
                    451:     if (ra->MinX < rb->MinX)
                    452:        return -1;
                    453:     if (ra->MinX > rb->MinX)
                    454:        return 1;
                    455:     if (ra->MaxX < rb->MaxX)
                    456:        return -1;
                    457:     return 1;
                    458: }
                    459: 
                    460: static __inline__ int min(int x, int y)
                    461: {
                    462:     return x < y ? x : y;
                    463: }
                    464: 
                    465: static __inline__ int max(int x, int y)
                    466: {
                    467:     return x > y ? x : y;
                    468: }
                    469: 
1.1.1.3   root      470: static void add_rect_to_bands(struct BandList *bl, struct Rectangle *rect)
1.1       root      471: {
1.1.1.3   root      472:     int j;
                    473:     struct Rectangle tmpr = *rect;
1.1       root      474: 
1.1.1.3   root      475:     for (j = 0; j < bl->count; j++) {
                    476:        /* Is the current band before the rectangle? */
                    477:        if (bl->maxy[j] < tmpr.MinY)
                    478:            continue;
                    479:        /* Band already present? */
                    480:        if (bl->miny[j] == tmpr.MinY && bl->maxy[j] == tmpr.MaxY)
                    481:            break;
                    482:        /* Completely new band? Add it */
                    483:        if (bl->miny[j] > tmpr.MaxY) {
                    484:            add_band(bl, tmpr.MinY, tmpr.MaxY, j);
                    485:            break;
                    486:        }
                    487:        /* Now we know that the bands are overlapping.
                    488:         * See whether they match in one point */
                    489:        if (bl->miny[j] == tmpr.MinY) {
                    490:            int t;
                    491:            if (bl->maxy[j] < tmpr.MaxY) {
                    492:                /* Rectangle exceeds band */
                    493:                tmpr.MinY = bl->maxy[j]+1;
1.1       root      494:                continue;
                    495:            }
1.1.1.3   root      496:            /* Rectangle splits band */
                    497:            t = bl->maxy[j];
                    498:            bl->maxy[j] = tmpr.MaxY;
                    499:            tmpr.MinY = bl->maxy[j] + 1;
                    500:            tmpr.MaxY = t;
                    501:            continue;
                    502:        } else if (bl->maxy[j] == tmpr.MaxY) {
                    503:            int t;
1.1       root      504:            if (bl->miny[j] > tmpr.MinY) {
1.1.1.3   root      505:                /* Rectangle exceeds band */
                    506:                t = bl->miny[j];
                    507:                bl->miny[j] = tmpr.MinY;
                    508:                bl->maxy[j] = t-1;
                    509:                tmpr.MinY = t;
                    510:                continue;
1.1       root      511:            }
1.1.1.3   root      512:            /* Rectangle splits band */
                    513:            bl->maxy[j] = tmpr.MinY - 1;
1.1       root      514:            continue;
                    515:        }
1.1.1.3   root      516:        /* Bands overlap and match in no points. Get a new band and align */
                    517:        if (bl->miny[j] > tmpr.MinY) {
                    518:            /* Rectangle begins before band, so make a new band before
                    519:             * and adjust rectangle */
                    520:            add_band(bl, tmpr.MinY, bl->miny[j] - 1, j);
                    521:            tmpr.MinY = bl->miny[j+1];
                    522:        } else {
                    523:            /* Rectangle begins in band */
                    524:            add_band(bl, bl->miny[j], tmpr.MinY - 1, j);
                    525:            bl->miny[j+1] = tmpr.MinY;
                    526:        }
                    527:        continue;
                    528:     }
                    529:     if (j == bl->count)
                    530:        add_band(bl, tmpr.MinY, tmpr.MaxY, j);
                    531: }
                    532: 
                    533: static void region_addbands(struct RectList *rl, struct BandList *bl)
                    534: {
                    535:     int i,j;
                    536: 
                    537:     for (i = 0; i < rl->count; i++) {
                    538:        add_rect_to_bands(bl, rl->rects + i);
                    539:     }
                    540: }
                    541: 
                    542: static void merge_bands(struct BandList *dest, struct BandList *src)
                    543: {
                    544:     int i;
                    545:     for (i = 0; i < src->count; i++) {
                    546:        struct Rectangle tmp;
                    547:        tmp.MinY = src->miny[i];
                    548:        tmp.MaxY = src->maxy[i];
                    549:        add_rect_to_bands(dest, &tmp);
1.1       root      550:     }
                    551: }
                    552: 
                    553: static void region_splitrects_band(struct RectList *rl, struct BandList *bl)
                    554: {
                    555:     int i,j;
                    556:     for (i = 0; i < rl->count; i++) {
                    557:        for (j = 0; j < bl->count; j++) {
                    558:            if (bl->miny[j] == rl->rects[i].MinY && bl->maxy[j] == rl->rects[i].MaxY)
                    559:                break;
                    560:            if (rl->rects[i].MinY > bl->maxy[j])
                    561:                continue;
                    562:            if (bl->miny[j] == rl->rects[i].MinY) {
                    563:                struct Rectangle tmpr;
                    564:                tmpr.MinX = rl->rects[i].MinX;
                    565:                tmpr.MaxX = rl->rects[i].MaxX;
                    566:                tmpr.MinY = bl->maxy[j] + 1;
                    567:                tmpr.MaxY = rl->rects[i].MaxY;
                    568:                add_rect(rl, tmpr); /* will be processed later */
                    569:                rl->rects[i].MaxY = bl->maxy[j];
                    570:                break;
                    571:            }
                    572:            fprintf(stderr, "Foo..\n");
                    573:        }
                    574:     }
                    575:     qsort(rl->rects, rl->count, sizeof (struct Rectangle), regionrect_cmpfn);
                    576: }
                    577: 
                    578: static void region_coalesce_rects(struct RectList *rl, int do_2nd_pass)
                    579: {
                    580:     int i,j;
                    581: 
                    582:     /* First pass: Coalesce horizontally */
                    583:     for (i = j = 0; i < rl->count;) {
                    584:        int offs = 1;
                    585:        while (i + offs < rl->count) {
                    586:            if (rl->rects[i].MinY != rl->rects[i+offs].MinY
                    587:                || rl->rects[i].MaxY != rl->rects[i+offs].MaxY
                    588:                || rl->rects[i].MaxX+1 < rl->rects[i+offs].MinX)
                    589:                break;
                    590:            rl->rects[i].MaxX = rl->rects[i+offs].MaxX;
                    591:            offs++;
                    592:        }
                    593:        rl->rects[j++] = rl->rects[i];
                    594:        i += offs;
                    595:     }
                    596:     rl->count = j;
1.1.1.3   root      597: 
1.1       root      598:     if (!do_2nd_pass)
                    599:        return;
1.1.1.3   root      600: 
1.1       root      601:     /* Second pass: Coalesce bands */
                    602:     for (i = 0; i < rl->count;) {
                    603:        int match = 0;
                    604:        for (j = i + 1; j < rl->count; j++)
                    605:            if (rl->rects[i].MinY != rl->rects[j].MinY)
                    606:                break;
                    607:        if (j < rl->count && rl->rects[i].MaxY + 1 == rl->rects[j].MinY) {
                    608:            int k;
                    609:            match = 1;
                    610:            for (k = 0; i+k < j; k++) {
                    611:                if (j+k >= rl->count
                    612:                    || rl->rects[j+k].MinY != rl->rects[j].MinY)
                    613:                {
                    614:                    match = 0; break;
                    615:                }
                    616:                if (rl->rects[i+k].MinX != rl->rects[j+k].MinX
                    617:                    || rl->rects[i+k].MaxX != rl->rects[j+k].MaxX)
                    618:                {
                    619:                    match = 0;
                    620:                    break;
                    621:                }
                    622:            }
                    623:            if (j+k < rl->count && rl->rects[j+k].MinY == rl->rects[j].MinY)
                    624:                match = 0;
                    625:            if (match) {
                    626:                for (k = 0; i+k < j; k++)
                    627:                    rl->rects[i+k].MaxY = rl->rects[j].MaxY;
                    628:                memmove(rl->rects + j, rl->rects + j + k, (rl->count - j - k)*sizeof(struct Rectangle));
                    629:                rl->count -= k;
                    630:            }
                    631:        }
                    632:        if (!match)
                    633:            i = j;
                    634:     }
                    635: }
                    636: 
1.1.1.3   root      637: static int copy_rects (uaecptr region, struct RectList *rl)
1.1       root      638: {
1.1.1.3   root      639:     uaecptr regionrect;
1.1       root      640:     int numrects = 0;
                    641:     struct Rectangle b;
                    642:     regionrect = get_long(region+8);
                    643:     b.MinX = get_word(region);
                    644:     b.MinY = get_word(region+2);
                    645:     b.MaxX = get_word(region+4);
                    646:     b.MaxY = get_word(region+6);
1.1.1.3   root      647: 
1.1       root      648:     while (regionrect != 0) {
                    649:        struct Rectangle tmpr;
1.1.1.3   root      650: 
                    651:        tmpr.MinX = (uae_s16)get_word(regionrect+8)  + b.MinX;
                    652:        tmpr.MinY = (uae_s16)get_word(regionrect+10) + b.MinY;
                    653:        tmpr.MaxX = (uae_s16)get_word(regionrect+12) + b.MinX;
                    654:        tmpr.MaxY = (uae_s16)get_word(regionrect+14) + b.MinY;
1.1       root      655:        add_rect(rl, tmpr);
                    656:        regionrect = get_long(regionrect);
                    657:        numrects++;
                    658:     }
                    659:     return numrects;
                    660: }
                    661: 
1.1.1.3   root      662: static int rect_in_region(struct RectList *rl, struct Rectangle *r)
                    663: {
                    664:     int i;
                    665:     int miny = r->MinY;
                    666: 
                    667:     for (i = 0; i < rl->count; i++) {
                    668:        int j;
                    669:        if (rl->rects[i].MaxY < miny)
                    670:            continue;
                    671:        if (rl->rects[i].MinY > miny)
                    672:            break;
                    673:        if (rl->rects[i].MaxX < r->MinX)
                    674:            continue;
                    675:        if (rl->rects[i].MinX > r->MaxX)
                    676:            break;
                    677:        /* Overlap! */
                    678:        j = i;
                    679:        for (;;) {
                    680:            if (rl->rects[j].MaxX > r->MaxX) {
                    681:                miny = rl->rects[i].MaxY + 1;
                    682:                break;
                    683:            }
                    684:            j++;
                    685:            if (j == rl->count)
                    686:                break;
                    687:            if (rl->rects[j].MinX != rl->rects[j-1].MaxX+1)
                    688:                break;
                    689:            if (rl->rects[i].MinY != rl->rects[j].MinY)
                    690:                break;
                    691:        }
                    692:        if (miny <= rl->rects[i].MaxY)
                    693:            break;
                    694:     }
                    695:     return 0;
                    696: }
                    697: 
1.1       root      698: typedef void (*regionop)(struct RectList *,struct RectList *,struct RectList *);
                    699: 
                    700: static void region_do_ClearRegionRegion(struct RectList *rl1,struct RectList *rl2,
                    701:                                        struct RectList *rl3)
                    702: {
                    703:     int i,j;
                    704: 
                    705:     for (i = j = 0; i < rl2->count && j < rl1->count;) {
                    706:        struct Rectangle tmpr;
                    707: 
                    708:        while ((rl1->rects[j].MinY < rl2->rects[i].MinY
                    709:                || (rl1->rects[j].MinY == rl2->rects[i].MinY
                    710:                    && rl1->rects[j].MaxX < rl2->rects[i].MinX))
                    711:               && j < rl1->count)
                    712:            j++;
                    713:        if (j >= rl1->count)
                    714:            break;
                    715:        while ((rl1->rects[j].MinY > rl2->rects[i].MinY
                    716:                || (rl1->rects[j].MinY == rl2->rects[i].MinY
                    717:                    && rl1->rects[j].MinX > rl2->rects[i].MaxX))
                    718:               && i < rl2->count)
                    719:        {
                    720:            add_rect(rl3, rl2->rects[i]);
                    721:            i++;
                    722:        }
                    723:        if (i >= rl2->count)
                    724:            break;
1.1.1.3   root      725: 
1.1       root      726:        tmpr = rl2->rects[i];
1.1.1.3   root      727: 
1.1       root      728:        while (i < rl2->count && j < rl1->count
                    729:               && rl1->rects[j].MinY == tmpr.MinY
                    730:               && rl2->rects[i].MinY == tmpr.MinY
                    731:               && rl1->rects[j].MinX <= rl2->rects[i].MaxX
                    732:               && rl1->rects[j].MaxX >= rl2->rects[i].MinX)
                    733:        {
                    734:            int oldmin = tmpr.MinX;
                    735:            int oldmax = tmpr.MaxX;
                    736:            if (tmpr.MinX < rl1->rects[j].MinX) {
                    737:                tmpr.MaxX = rl1->rects[j].MinX - 1;
                    738:                add_rect(rl3, tmpr);
                    739:            }
                    740:            if (oldmax <= rl1->rects[j].MaxX) {
                    741:                i++;
                    742:                if (i < rl2->count && rl2->rects[i].MinY == tmpr.MinY)
                    743:                    tmpr = rl2->rects[i];
                    744:            } else {
                    745:                tmpr.MinX = rl1->rects[j].MaxX + 1;
                    746:                tmpr.MaxX = oldmax;
                    747:                j++;
                    748:            }
                    749:        }
                    750:     }
                    751:     for(; i < rl2->count; i++)
                    752:        add_rect(rl3, rl2->rects[i]);
                    753: }
                    754: 
                    755: static void region_do_AndRegionRegion(struct RectList *rl1,struct RectList *rl2,
                    756:                                      struct RectList *rl3)
                    757: {
                    758:     int i,j;
                    759: 
                    760:     for (i = j = 0; i < rl2->count && j < rl1->count;) {
                    761:        while ((rl1->rects[j].MinY < rl2->rects[i].MinY
                    762:                || (rl1->rects[j].MinY == rl2->rects[i].MinY
                    763:                    && rl1->rects[j].MaxX < rl2->rects[i].MinX))
                    764:               && j < rl1->count)
                    765:            j++;
                    766:        if (j >= rl1->count)
                    767:            break;
                    768:        while ((rl1->rects[j].MinY > rl2->rects[i].MinY
                    769:                || (rl1->rects[j].MinY == rl2->rects[i].MinY
                    770:                    && rl1->rects[j].MinX > rl2->rects[i].MaxX))
                    771:               && i < rl2->count)
                    772:            i++;
                    773:        if (i >= rl2->count)
                    774:            break;
                    775:        if (rl1->rects[j].MinY == rl2->rects[i].MinY
                    776:            && rl1->rects[j].MinX <= rl2->rects[i].MaxX
                    777:            && rl1->rects[j].MaxX >= rl2->rects[i].MinX)
                    778:        {
                    779:            /* We have an intersection! */
                    780:            struct Rectangle tmpr;
                    781:            tmpr = rl2->rects[i];
                    782:            if (tmpr.MinX < rl1->rects[j].MinX)
                    783:                tmpr.MinX = rl1->rects[j].MinX;
                    784:            if (tmpr.MaxX > rl1->rects[j].MaxX)
                    785:                tmpr.MaxX = rl1->rects[j].MaxX;
                    786:            add_rect(rl3, tmpr);
                    787:            if (rl1->rects[j].MaxX == rl2->rects[i].MaxX)
                    788:                i++, j++;
                    789:            else if (rl1->rects[j].MaxX > rl2->rects[i].MaxX)
                    790:                i++;
                    791:            else
                    792:                j++;
                    793:        }
                    794:     }
                    795: }
                    796: 
                    797: static void region_do_OrRegionRegion(struct RectList *rl1,struct RectList *rl2,
                    798:                                     struct RectList *rl3)
                    799: {
                    800:     int i,j;
                    801: 
                    802:     for (i = j = 0; i < rl2->count && j < rl1->count;) {
                    803:        while ((rl1->rects[j].MinY < rl2->rects[i].MinY
                    804:                || (rl1->rects[j].MinY == rl2->rects[i].MinY
                    805:                    && rl1->rects[j].MaxX < rl2->rects[i].MinX))
                    806:               && j < rl1->count)
                    807:        {
                    808:            add_rect(rl3, rl1->rects[j]);
                    809:            j++;
                    810:        }
                    811:        if (j >= rl1->count)
                    812:            break;
                    813:        while ((rl1->rects[j].MinY > rl2->rects[i].MinY
                    814:                || (rl1->rects[j].MinY == rl2->rects[i].MinY
                    815:                    && rl1->rects[j].MinX > rl2->rects[i].MaxX))
                    816:               && i < rl2->count)
                    817:        {
                    818:            add_rect(rl3, rl2->rects[i]);
                    819:            i++;
                    820:        }
                    821:        if (i >= rl2->count)
                    822:            break;
                    823:        if (rl1->rects[j].MinY == rl2->rects[i].MinY
                    824:            && rl1->rects[j].MinX <= rl2->rects[i].MaxX
                    825:            && rl1->rects[j].MaxX >= rl2->rects[i].MinX)
                    826:        {
                    827:            /* We have an intersection! */
                    828:            struct Rectangle tmpr;
                    829:            tmpr = rl2->rects[i];
                    830:            if (tmpr.MinX > rl1->rects[j].MinX)
                    831:                tmpr.MinX = rl1->rects[j].MinX;
                    832:            if (tmpr.MaxX < rl1->rects[j].MaxX)
                    833:                tmpr.MaxX = rl1->rects[j].MaxX;
                    834:            i++; j++;
                    835:            for (;;) {
                    836:                int cont = 0;
                    837:                if (j < rl1->count && rl1->rects[j].MinY == tmpr.MinY
                    838:                    && tmpr.MaxX+1 >= rl1->rects[j].MinX) {
                    839:                    if (tmpr.MaxX < rl1->rects[j].MaxX)
                    840:                        tmpr.MaxX = rl1->rects[j].MaxX;
                    841:                    j++; cont = 1;
                    842:                }
                    843:                if (i < rl2->count && rl2->rects[i].MinY == tmpr.MinY
                    844:                    && tmpr.MaxX+1 >= rl2->rects[i].MinX) {
                    845:                    if (tmpr.MaxX < rl2->rects[i].MaxX)
                    846:                        tmpr.MaxX = rl2->rects[i].MaxX;
                    847:                    i++; cont = 1;
                    848:                }
                    849:                if (!cont)
                    850:                    break;
                    851:            }
                    852:            add_rect(rl3, tmpr);
                    853:        }
                    854:     }
                    855:     for(; i < rl2->count; i++)
                    856:        add_rect(rl3, rl2->rects[i]);
                    857:     for(; j < rl1->count; j++)
                    858:        add_rect(rl3, rl1->rects[j]);
                    859: }
                    860: 
                    861: static void region_do_XorRegionRegion(struct RectList *rl1,struct RectList *rl2,
                    862:                                      struct RectList *rl3)
                    863: {
                    864:     int i,j;
                    865: 
                    866:     for (i = j = 0; i < rl2->count && j < rl1->count;) {
                    867:        struct Rectangle tmpr1, tmpr2;
                    868: 
                    869:        while ((rl1->rects[j].MinY < rl2->rects[i].MinY
                    870:                || (rl1->rects[j].MinY == rl2->rects[i].MinY
                    871:                    && rl1->rects[j].MaxX < rl2->rects[i].MinX))
                    872:               && j < rl1->count)
                    873:        {
                    874:            add_rect(rl3, rl1->rects[j]);
                    875:            j++;
                    876:        }
                    877:        if (j >= rl1->count)
                    878:            break;
                    879:        while ((rl1->rects[j].MinY > rl2->rects[i].MinY
                    880:                || (rl1->rects[j].MinY == rl2->rects[i].MinY
                    881:                    && rl1->rects[j].MinX > rl2->rects[i].MaxX))
                    882:               && i < rl2->count)
                    883:        {
                    884:            add_rect(rl3, rl2->rects[i]);
                    885:            i++;
                    886:        }
                    887:        if (i >= rl2->count)
                    888:            break;
                    889: 
                    890:        tmpr2 = rl2->rects[i];
                    891:        tmpr1 = rl1->rects[j];
1.1.1.3   root      892: 
1.1       root      893:        while (i < rl2->count && j < rl1->count
                    894:               && rl1->rects[j].MinY == tmpr1.MinY
                    895:               && rl2->rects[i].MinY == tmpr1.MinY
                    896:               && rl1->rects[j].MinX <= rl2->rects[i].MaxX
                    897:               && rl1->rects[j].MaxX >= rl2->rects[i].MinX)
                    898:        {
                    899:            int oldmin2 = tmpr2.MinX;
                    900:            int oldmax2 = tmpr2.MaxX;
                    901:            int oldmin1 = tmpr1.MinX;
                    902:            int oldmax1 = tmpr1.MaxX;
                    903:            int need_1 = 0, need_2 = 0;
                    904: 
1.1.1.3   root      905:            if (tmpr2.MinX > tmpr1.MinX && tmpr2.MaxX < tmpr1.MaxX)
1.1       root      906:            {
                    907:                /*
                    908:                 *    ###########
                    909:                 *       ****
                    910:                 */
                    911:                tmpr1.MaxX = tmpr2.MinX - 1;
                    912:                add_rect(rl3, tmpr1);
                    913:                tmpr1.MaxX = oldmax1;
                    914:                tmpr1.MinX = tmpr2.MaxX + 1;
                    915:                add_rect(rl3, tmpr1);
                    916:                need_2 = 1;
                    917:            } else if (tmpr2.MinX > tmpr1.MinX && tmpr2.MaxX > tmpr1.MaxX) {
                    918:                /*
                    919:                 *    ##########
                    920:                 *       *********
                    921:                 */
                    922:                tmpr1.MaxX = tmpr2.MinX - 1;
                    923:                add_rect(rl3, tmpr1);
                    924:                tmpr2.MinX = oldmax1 + 1;
                    925:                add_rect(rl3, tmpr2);
                    926:                need_1 = 1;
                    927:            } else if (tmpr2.MinX < tmpr1.MinX && tmpr2.MaxX < tmpr1.MaxX) {
                    928:                /*
                    929:                 *       ##########
                    930:                 *    *********
                    931:                 */
                    932:                tmpr2.MaxX = tmpr1.MinX - 1;
                    933:                add_rect(rl3, tmpr2);
                    934:                tmpr1.MinX = oldmax2 + 1;
                    935:                add_rect(rl3, tmpr1);
                    936:                need_2 = 1;
                    937:            } else if (tmpr2.MinX < tmpr1.MinX && tmpr2.MaxX > tmpr1.MaxX) {
                    938:                /*
                    939:                 *       ###
                    940:                 *    *********
                    941:                 */
                    942:                tmpr2.MaxX = tmpr1.MinX - 1;
                    943:                add_rect(rl3, tmpr2);
                    944:                tmpr2.MaxX = oldmax2;
                    945:                tmpr2.MinX = tmpr1.MaxX + 1;
                    946:                add_rect(rl3, tmpr2);
                    947:                need_1 = 1;
                    948:            } else if (tmpr1.MinX == tmpr2.MinX && tmpr2.MaxX < tmpr1.MaxX) {
                    949:                /*
                    950:                 *    #############
                    951:                 *    *********
                    952:                 */
                    953:                tmpr1.MinX = tmpr2.MaxX + 1;
                    954:                need_2 = 1;
                    955:            } else if (tmpr1.MinX == tmpr2.MinX && tmpr2.MaxX > tmpr1.MaxX) {
                    956:                /*
                    957:                 *    #########
                    958:                 *    *************
                    959:                 */
                    960:                tmpr2.MinX = tmpr1.MaxX + 1;
                    961:                need_1 = 1;
                    962:            } else if (tmpr1.MinX < tmpr2.MinX && tmpr2.MaxX == tmpr1.MaxX) {
                    963:                /*
                    964:                 *    #############
                    965:                 *        *********
                    966:                 */
                    967:                tmpr1.MaxX = tmpr2.MinX - 1;
                    968:                add_rect(rl3, tmpr1);
                    969:                need_2 = need_1 = 1;
                    970:            } else if (tmpr1.MinX > tmpr2.MinX && tmpr2.MaxX == tmpr1.MaxX) {
                    971:                /*
                    972:                 *        #########
                    973:                 *    *************
                    974:                 */
                    975:                tmpr2.MaxX = tmpr1.MinX - 1;
                    976:                add_rect(rl3, tmpr2);
                    977:                need_2 = need_1 = 1;
                    978:            } else {
                    979:                assert(tmpr1.MinX == tmpr2.MinX && tmpr2.MaxX == tmpr1.MaxX);
                    980:                need_1 = need_2 = 1;
                    981:            }
                    982:            if (need_1) {
                    983:                j++;
                    984:                if (j < rl1->count && rl1->rects[j].MinY == tmpr1.MinY)
                    985:                    tmpr1 = rl1->rects[j];
                    986:            }
                    987:            if (need_2) {
                    988:                i++;
                    989:                if (i < rl2->count && rl2->rects[i].MinY == tmpr2.MinY)
                    990:                    tmpr2 = rl2->rects[i];
                    991:            }
                    992:        }
                    993:     }
                    994:     for(; i < rl2->count; i++)
                    995:        add_rect(rl3, rl2->rects[i]);
                    996:     for(; j < rl1->count; j++)
                    997:        add_rect(rl3, rl1->rects[j]);
                    998: }
                    999: 
1.1.1.3   root     1000: static uae_u32 gfxl_perform_regionop(regionop op, int with_rect)
1.1       root     1001: {
                   1002:     int i,j,k;
1.1.1.3   root     1003:     uaecptr reg1;
                   1004:     uaecptr reg2;
                   1005:     uaecptr tmp, rpp;
1.1       root     1006:     struct RectList rl1, rl2, rl3;
                   1007:     struct BandList bl;
                   1008: 
                   1009:     int retval = 0;
                   1010:     int numrects2;
1.1.1.3   root     1011: 
1.1       root     1012:     init_rectlist(&rl1); init_rectlist(&rl2); init_rectlist(&rl3);
                   1013: 
                   1014:     if (with_rect) {
                   1015:        struct Rectangle tmpr;
1.1.1.2   root     1016:        reg2 = m68k_areg(regs, 0);
1.1       root     1017:        numrects2 = copy_rects(reg2, &rl2);
1.1.1.2   root     1018:        tmpr.MinX = get_word(m68k_areg(regs, 1));
                   1019:        tmpr.MinY = get_word(m68k_areg(regs, 1) + 2);
                   1020:        tmpr.MaxX = get_word(m68k_areg(regs, 1) + 4);
                   1021:        tmpr.MaxY = get_word(m68k_areg(regs, 1) + 6);
1.1       root     1022:        add_rect(&rl1, tmpr);
                   1023:     } else {
1.1.1.2   root     1024:        reg1 = m68k_areg(regs, 0);
                   1025:        reg2 = m68k_areg(regs, 1);
1.1       root     1026: 
                   1027:        copy_rects(reg1, &rl1);
                   1028:        numrects2 = copy_rects(reg2, &rl2);
                   1029:     }
                   1030: 
                   1031:     init_bandlist(&bl);
                   1032:     region_addbands(&rl1, &bl);
                   1033:     region_addbands(&rl2, &bl);
                   1034:     region_splitrects_band(&rl1, &bl);
                   1035:     region_splitrects_band(&rl2, &bl);
                   1036:     region_coalesce_rects(&rl1, 0);
                   1037:     region_coalesce_rects(&rl2, 0);
                   1038: 
                   1039:     (*op)(&rl1, &rl2, &rl3);
                   1040:     region_coalesce_rects(&rl3, 1);
                   1041: 
                   1042:     rpp = reg2 + 8;
                   1043:     if (rl3.count < numrects2) {
                   1044:        while (numrects2-- != rl3.count) {
                   1045:            tmp = get_long(rpp);
                   1046:            put_long(rpp, get_long(tmp));
                   1047:            amiga_free(tmp, 16);
                   1048:        }
                   1049:        if (rl3.count > 0)
                   1050:            put_long(get_long(rpp) + 4, rpp);
                   1051:     } else if (rl3.count > numrects2) {
                   1052:        while(numrects2++ != rl3.count) {
1.1.1.3   root     1053:            uaecptr prev = get_long(rpp);
1.1       root     1054:            tmp = amiga_malloc(16);
                   1055:            if (tmp == 0)
                   1056:                goto done;
                   1057:            put_long(tmp, prev);
                   1058:            put_long(tmp + 4, rpp);
                   1059:            if (prev != 0)
                   1060:                put_long(prev + 4, tmp);
1.1.1.3   root     1061:            put_long(rpp, tmp);
1.1       root     1062:        }
                   1063:     }
1.1.1.3   root     1064: 
1.1       root     1065:     if (rl3.count > 0) {
                   1066:        rpp = reg2 + 8;
                   1067:        for (i = 0; i < rl3.count; i++) {
1.1.1.3   root     1068:            uaecptr rr = get_long(rpp);
1.1       root     1069:            put_word(rr+8, rl3.rects[i].MinX - rl3.bounds.MinX);
                   1070:            put_word(rr+10, rl3.rects[i].MinY - rl3.bounds.MinY);
                   1071:            put_word(rr+12, rl3.rects[i].MaxX - rl3.bounds.MinX);
                   1072:            put_word(rr+14, rl3.rects[i].MaxY - rl3.bounds.MinY);
                   1073:            rpp = rr;
                   1074:        }
                   1075:        if (get_long(rpp) != 0)
                   1076:            fprintf(stderr, "BUG\n");
1.1.1.3   root     1077:     }
1.1       root     1078:     put_word(reg2+0, rl3.bounds.MinX);
                   1079:     put_word(reg2+2, rl3.bounds.MinY);
                   1080:     put_word(reg2+4, rl3.bounds.MaxX);
                   1081:     put_word(reg2+6, rl3.bounds.MaxY);
                   1082:     retval = 1;
                   1083: 
                   1084:     done:
                   1085:     free_rectlist(&rl1); free_rectlist(&rl2); free_rectlist(&rl3);
1.1.1.3   root     1086:     free_bandlist(&bl);
1.1       root     1087: 
                   1088:     return retval;
                   1089: }
                   1090: 
1.1.1.3   root     1091: static uae_u32 gfxl_AndRegionRegion(void)
1.1       root     1092: {
                   1093:     return gfxl_perform_regionop(region_do_AndRegionRegion, 0);
                   1094: }
1.1.1.3   root     1095: static uae_u32 gfxl_XorRegionRegion(void)
1.1       root     1096: {
                   1097:     return gfxl_perform_regionop(region_do_XorRegionRegion, 0);
                   1098: }
1.1.1.3   root     1099: static uae_u32 gfxl_OrRegionRegion(void)
1.1       root     1100: {
                   1101:     return gfxl_perform_regionop(region_do_OrRegionRegion, 0);
                   1102: }
                   1103: 
1.1.1.3   root     1104: static uae_u32 gfxl_ClearRectRegion(void)
1.1       root     1105: {
                   1106:     return gfxl_perform_regionop(region_do_ClearRegionRegion, 1);
                   1107: }
1.1.1.3   root     1108: static uae_u32 gfxl_OrRectRegion(void)
1.1       root     1109: {
                   1110:     return gfxl_perform_regionop(region_do_OrRegionRegion, 1);
                   1111: }
                   1112: 
1.1.1.3   root     1113: static uae_u32 gfxl_AndRectRegion(void)
1.1       root     1114: {
                   1115:     return gfxl_perform_regionop(region_do_AndRegionRegion, 1);
                   1116: }
                   1117: 
1.1.1.3   root     1118: static uae_u32 gfxl_XorRectRegion(void)
1.1       root     1119: {
                   1120:     return gfxl_perform_regionop(region_do_XorRegionRegion, 1);
                   1121: }
                   1122: 
                   1123: 
1.1.1.3   root     1124: /* Layers code */
                   1125: 
                   1126: static uae_u32 LY_TryLockLayer(uaecptr layer)
                   1127: {
                   1128:     uaecptr sigsem = layer + 72;
                   1129: 
                   1130:     m68k_areg(regs, 0) = sigsem;
                   1131:     return CallLib(get_long(4), -576);
                   1132: }
                   1133: 
                   1134: static void LY_LockLayer(uaecptr layer)
                   1135: {
                   1136:     uaecptr sigsem = layer + 72;
                   1137: 
                   1138:     m68k_areg(regs, 0) = sigsem;
                   1139:     CallLib(get_long(4), -564);
                   1140: }
                   1141: 
                   1142: static void LY_UnlockLayer(uaecptr layer)
                   1143: {
                   1144:     uaecptr sigsem = layer + 72;
                   1145: 
                   1146:     m68k_areg(regs, 0) = sigsem;
                   1147:     CallLib(get_long(4), -570);
                   1148: }
                   1149: 
                   1150: static void LY_LockLayerInfo(uaecptr li)
                   1151: {
                   1152:     uaecptr sigsem = li + 24;
                   1153: 
                   1154:     m68k_areg(regs, 0) = sigsem;
                   1155:     CallLib(get_long(4), -564);
                   1156:     put_byte(li+91, get_byte(li+91)+1);
                   1157: }
                   1158: 
                   1159: static void LY_UnlockLayerInfo(uaecptr li)
                   1160: {
                   1161:     uaecptr sigsem = li + 24;
                   1162: 
                   1163:     put_byte(li+91, get_byte(li+91)-1);
                   1164:     m68k_areg(regs, 0) = sigsem;
                   1165:     CallLib(get_long(4), -570);
                   1166: }
                   1167: 
                   1168: static void LY_LockLayers(uaecptr li)
                   1169: {
                   1170:     uaecptr l = get_long (li);
                   1171:     LY_LockLayerInfo(li);
                   1172:     while (l != 0) {
                   1173:        LY_LockLayer(l);
                   1174:        l = get_long(l);
                   1175:     }
                   1176:     LY_UnlockLayerInfo(li);
                   1177: }
                   1178: 
                   1179: static void LY_UnlockLayers(uaecptr li)
                   1180: {
                   1181:     uaecptr l = get_long (li);
                   1182:     LY_LockLayerInfo(li);
                   1183:     while (l != 0) {
                   1184:        LY_UnlockLayer(l);
                   1185:        l = get_long(l);
                   1186:     }
                   1187:     LY_UnlockLayerInfo(li);
                   1188: }
                   1189: 
                   1190: #define LAYER_CLUELESS   0x8000 /* Indicates we know nothing about the layer's regions. */
                   1191: #define LAYER_CR_CHANGED 0x4000 /* Indicates that the cliprects in Amiga memory need to be re-done */
                   1192: #define LAYER_REDO       0x2000 /* Indicates that we have regions, but they are bogus. */
                   1193: 
                   1194: static uae_u32 layer_uniq = 1;
                   1195: 
                   1196: struct MyLayerInfo {
                   1197:     struct uniq_head head;
                   1198:     uaecptr amigaos_linfo;
                   1199:     uniq_list layer_list;
                   1200: };
                   1201: 
                   1202: struct MyLayer {
                   1203:     struct uniq_head head;
                   1204:     uaecptr amigaos_layer, rastport;
                   1205:     struct Rectangle bounds;
                   1206:     struct RectList clipregion;
                   1207:     struct RectList obscured;
                   1208:     struct RectList visible;
                   1209:     struct BandList big_bands; /* created by obscuring layers */
                   1210:     struct BandList small_bands; /* big_bands + those from clipregion */
                   1211:     struct RectList damage;
                   1212:     struct BandList damage_bands;
                   1213:     struct MyLayerInfo *mli;
                   1214: };
                   1215: 
                   1216: static uniq_list MyLayerInfo_list = UNIQ_INIT;
                   1217: 
                   1218: static void LY_InitLayers(uaecptr li)
                   1219: {
                   1220:     memset (get_real_address(li), 0, 92);
                   1221:     put_long(li + 0, 0); /* top layer */
                   1222:     put_long(li+84, 0); /* uniq: */
                   1223:     m68k_areg(regs, 0) = li + 24; CallLib(get_long(4), -558); /* InitSemaphore() */
                   1224:     put_word(li+88, 0); /* flags (???) */
                   1225:     put_byte(li+89, 0); /* fatten_count */
                   1226:     /* @@@ How big can I assume the structure? What's all this 1.0/1.1 cruft? */
                   1227: }
                   1228: 
                   1229: static void LY_FattenLayerInfo(uaecptr li)
                   1230: {
                   1231:     struct MyLayerInfo *mli;
                   1232:     int fatten_count = get_byte (li + 89);
                   1233:     if (fatten_count == 0) {
                   1234:        mli = (struct MyLayerInfo *)malloc(sizeof(struct MyLayerInfo));
                   1235:        add_uniq(&MyLayerInfo_list, &mli->head, li + 84);
                   1236:        init_uniq(&mli->layer_list);
                   1237:        mli->amigaos_linfo = li;
                   1238:     }
                   1239:     put_byte (li + 89, fatten_count + 1);
                   1240: }
                   1241: 
                   1242: static void LY_ThinLayerInfo(uaecptr li)
                   1243: {
                   1244:     int fatten_count = get_byte (li + 89)-1;
                   1245:     put_byte (li + 89, fatten_count);
                   1246:     if (fatten_count == 0) {
                   1247:        struct MyLayerInfo *mli = (struct MyLayerInfo *)find_and_rem_uniq(&MyLayerInfo_list, get_long(li+84));
                   1248:        if (mli)
                   1249:            free(mli);
                   1250:     }
                   1251: }
                   1252: 
                   1253: static void build_cliprect (struct MyLayer *l, struct Rectangle *bounds,
                   1254:                            int obscured, uaecptr *crp, uaecptr *prev)
                   1255: {
                   1256:     uaecptr cr = get_long (*crp);
                   1257:     if (cr == 0) {
                   1258:        put_long (*crp, cr = amiga_malloc(CLIPRECT_SIZE));
                   1259:        put_long (cr, 0);
                   1260:     }
                   1261:     *prev = cr;
                   1262:     *crp = cr;
                   1263:     put_word (cr + 16, bounds->MinX);
                   1264:     put_word (cr + 18, bounds->MinY);
                   1265:     put_word (cr + 20, bounds->MaxX);
                   1266:     put_word (cr + 22, bounds->MaxY);
                   1267:     put_long (cr + 8, obscured ? l->amigaos_layer : 0); /* cheat */
                   1268:     put_long (cr + 12, 0); /* no smart refresh yet */
                   1269: }
                   1270: 
                   1271: static void build_cliprects (struct MyLayer *l)
                   1272: {
                   1273:     uaecptr layer = l->amigaos_layer;
                   1274:     uaecptr cr = layer + 8;
                   1275:     uaecptr prev = 0;
                   1276:     uae_u16 flags = get_word(layer + 30);
                   1277:     int i;
                   1278: 
                   1279:     if ((flags & LAYER_CR_CHANGED) == 0)
                   1280:        return;
                   1281:     put_word (layer + 30, flags & ~LAYER_CR_CHANGED);
                   1282:     for (i = 0; i < l->obscured.count; i++) {
                   1283:        build_cliprect (l, l->obscured.rects + i, 1, &cr, &prev);
                   1284:     }
                   1285:     for (i = 0; i < l->visible.count; i++) {
                   1286:        build_cliprect (l, l->visible.rects + i, 1, &cr, &prev);
                   1287:     }
                   1288:     while ((prev = get_long (cr))) {
                   1289:        put_long (cr, get_long (prev));
                   1290:        amiga_free (prev, CLIPRECT_SIZE);
                   1291:     }
                   1292: }
                   1293: 
                   1294: static void propagate_clueless_redo (struct MyLayerInfo *mli)
                   1295: {
                   1296:     /* For all CLUELESS layers, set the REDO bit for all layers below it that overlap it
                   1297:      * and delete the data associated with them. */
                   1298:     uaecptr current_l = get_long(mli->amigaos_linfo);
                   1299:     while (current_l) {
                   1300:        struct MyLayer *l = (struct MyLayer *)find_uniq(&mli->layer_list, get_long(current_l + 24));
                   1301:        if ((get_word(l->amigaos_layer + 32) & LAYER_CLUELESS) != 0) {
                   1302:            uaecptr next_l = get_long(current_l);
                   1303:            put_word(l->amigaos_layer + 32, get_word(l->amigaos_layer + 32) | LAYER_REDO);
                   1304:            while (next_l) {
                   1305:                struct MyLayer *l2 = (struct MyLayer *)find_uniq(&mli->layer_list, get_long(next_l + 24));
                   1306:                uae_u16 flags = get_word(l2->amigaos_layer + 32);
                   1307:                if (l2->bounds.MinX <= l->bounds.MaxX && l->bounds.MinX <= l2->bounds.MaxX
                   1308:                    && l2->bounds.MinY <= l->bounds.MaxY && l->bounds.MinY <= l2->bounds.MaxY)
                   1309:                    put_word(l2->amigaos_layer + 32, flags | LAYER_REDO);
                   1310:                if ((flags & (LAYER_REDO|LAYER_CLUELESS)) == 0) {
                   1311:                    free_rectlist(&l->obscured);
                   1312:                    free_rectlist(&l->visible);
                   1313:                    free_bandlist(&l->big_bands);
                   1314:                    free_bandlist(&l->small_bands);
                   1315:                }
                   1316:                next_l = get_long(next_l);
                   1317:            }
                   1318:        }
                   1319:        current_l = get_long(current_l);
                   1320:     }
                   1321: }
                   1322: 
                   1323: static void redo_layers(struct MyLayerInfo *mli, uaecptr bm)
                   1324: {
                   1325:     uaecptr current_l;
                   1326:     struct RectList tmp_rl;
                   1327: 
                   1328:     propagate_clueless_redo(mli);
                   1329:     current_l = get_long(mli->amigaos_linfo);
                   1330: 
                   1331:     while (current_l) {
                   1332:        struct MyLayer *l = (struct MyLayer *)find_uniq(&mli->layer_list, get_long(current_l + 24));
                   1333:        uae_u16 flags = get_word(l->amigaos_layer + 32);
                   1334:        if ((flags & LAYER_REDO) != 0) {
                   1335:            uaecptr next_l = get_long(current_l+4);
                   1336:            int have_rects = 0;
                   1337: 
                   1338:            init_rectlist(&l->obscured);
                   1339:            init_bandlist(&l->big_bands);
                   1340:            add_rect_to_bands(&l->big_bands, &l->bounds);
                   1341: 
                   1342:            while (next_l) {
                   1343:                struct MyLayer *l2 = (struct MyLayer *)find_uniq(&mli->layer_list, get_long(next_l + 24));
                   1344:                if (l2->visible.bounds.MinX <= l->bounds.MaxX && l->bounds.MinX <= l2->visible.bounds.MaxX
                   1345:                    && l2->visible.bounds.MinY <= l->bounds.MaxY && l->bounds.MinY <= l2->visible.bounds.MaxY
                   1346:                    && !rect_in_region (&l->obscured, &l2->visible.bounds))
                   1347:                {
                   1348:                    add_rect_to_bands(&l->big_bands, &l2->visible.bounds);
                   1349:                    add_rect(&l->obscured, l2->visible.bounds);
                   1350:                    have_rects++;
                   1351:                }
                   1352:                next_l = get_long(next_l+4);
                   1353:            }
                   1354:            init_rectlist(&l->visible);
                   1355:            init_rectlist(&tmp_rl);
                   1356:            add_rect (&tmp_rl, l->bounds);
                   1357: 
                   1358:            region_splitrects_band(&l->obscured, &l->big_bands);
                   1359:            region_splitrects_band(&tmp_rl, &l->big_bands);
                   1360:            region_do_ClearRegionRegion(&l->obscured, &tmp_rl, &l->visible);
                   1361:            flags |= LAYER_CR_CHANGED;
                   1362:        }
                   1363:        put_word (l->amigaos_layer + 32, flags & ~(LAYER_CLUELESS|LAYER_REDO));
                   1364:        current_l = get_long(current_l);
                   1365:     }
                   1366: }
                   1367: 
                   1368: static struct MyLayer *LY_NewLayer(struct MyLayerInfo *mli, int x0, int x1, int y0, int y1,
                   1369:                                   uae_u16 flags, uaecptr bm, uaecptr sbm)
                   1370: {
                   1371:     struct MyLayer *l = (struct MyLayer *)malloc(sizeof (struct MyLayer));
                   1372:     uaecptr layer = amiga_malloc(LAYER_SIZE);
                   1373:     memset (get_real_address(layer), 0, LAYER_SIZE);
                   1374:     l->amigaos_layer = layer;
                   1375: 
                   1376:     put_word(layer + 16, x0); /* bounds */
                   1377:     put_word(layer + 18, y0);
                   1378:     put_word(layer + 20, x1);
                   1379:     put_word(layer + 22, y1);
                   1380:     put_word(layer + 30, flags | LAYER_CLUELESS);
                   1381:     put_long(layer + 32, flags & 4 ? sbm : 0); /* ClipRect */
                   1382:     put_long(layer + 68, mli->amigaos_linfo);
                   1383:     m68k_areg(regs, 0) = layer + 72; CallLib(get_long(4), -558); /* InitSemaphore() */
                   1384:     add_uniq(&mli->layer_list, &l->head, layer + 24);
                   1385:     l->mli = mli;
                   1386: 
                   1387:     l->bounds.MinX = x0;
                   1388:     l->bounds.MaxX = x1;
                   1389:     l->bounds.MinY = y0;
                   1390:     l->bounds.MaxY = y1;
                   1391:     return l;
                   1392: }
                   1393: 
                   1394: static void LY_DeleteLayer(uaecptr layer)
                   1395: {
                   1396:     uaecptr cr;
                   1397:     struct MyLayer *l = (struct MyLayer *)find_and_rem_uniq(&l->mli->layer_list, get_long (layer + 24));
                   1398:     /* Free ClipRects */
                   1399:     while ((cr = get_long (l->amigaos_layer + 8))) {
                   1400:        put_long (l->amigaos_layer + 8, get_long(cr));
                   1401:        amiga_free(cr, CLIPRECT_SIZE);
                   1402:     }
                   1403:     amiga_free (l->amigaos_layer, LAYER_SIZE);
                   1404:     free(l);
                   1405: }
                   1406: 
                   1407: static uaecptr find_behindlayer_position(uaecptr li, uae_u16 flags)
                   1408: {
                   1409:     uaecptr where = li;
                   1410:     for (;;) {
                   1411:        uaecptr other = get_long (where);
                   1412:        /* End of list? */
                   1413:        if (other == 0)
                   1414:            break;
                   1415:        /* Backdrop? */
                   1416:        if ((get_word(other + 30) & 0x40) > (flags & 0x40))
                   1417:            break;
                   1418:        where = other;
                   1419:     }
                   1420:     return where;
                   1421: }
                   1422: 
                   1423: static uaecptr LY_CreateLayer(uaecptr li, int x0, int x1, int y0, int y1,
                   1424:                              uae_u16 flags, uaecptr bm, uaecptr sbm, uaecptr where)
                   1425: {
                   1426:     struct MyLayerInfo *mli = (struct MyLayerInfo *)find_uniq(&MyLayerInfo_list, get_long (li + 84));
                   1427:     struct MyLayer *l;
                   1428: 
                   1429:     LY_LockLayerInfo(li);
                   1430: 
                   1431:     l = LY_NewLayer(mli, x0, x1, y0, y1, flags, bm, sbm);
                   1432:     /* Chain into list */
                   1433:     put_long(l->amigaos_layer, get_long (where));
                   1434:     put_long(l->amigaos_layer + 4, where == li ? 0 : where);
                   1435:     if (get_long (where) != 0)
                   1436:        put_long(get_long (where) + 4, l->amigaos_layer);
                   1437:     put_long(where, l->amigaos_layer);
                   1438:     redo_layers(mli, bm);
                   1439:     build_cliprects(l);
                   1440:     LY_UnlockLayerInfo(li);
                   1441:     return l->amigaos_layer;
                   1442: }
                   1443: 
                   1444: static void LY_DisposeLayerInfo(uaecptr li)
                   1445: {
                   1446:     LY_ThinLayerInfo(li);
                   1447:     amiga_free(li, LINFO_SIZE);
                   1448: }
                   1449: 
                   1450: static uae_u32 layers_NewLayerInfo(void)
                   1451: {
                   1452:     uaecptr li = amiga_malloc(LINFO_SIZE);
                   1453:     LY_InitLayers(li);
                   1454:     LY_FattenLayerInfo(li);
                   1455:     return li;
                   1456: }
                   1457: static uae_u32 layers_InitLayers(void) { LY_InitLayers (m68k_areg (regs, 0)); return 0; }
                   1458: static uae_u32 layers_DisposeLayerInfo(void) { LY_DisposeLayerInfo (m68k_areg (regs, 0)); return 0; }
                   1459: 
                   1460: static uae_u32 layers_FattenLayerInfo(void) { LY_FattenLayerInfo(m68k_areg(regs, 0)); return 0; }
                   1461: static uae_u32 layers_ThinLayerInfo(void) { LY_ThinLayerInfo(m68k_areg(regs, 0)); return 0; }
                   1462: 
                   1463: static uae_u32 layers_CreateUpfrontLayer(void)
                   1464: {
                   1465:     return LY_CreateLayer(m68k_areg(regs, 0), (uae_s32)m68k_dreg(regs, 0),
                   1466:                          (uae_s32)m68k_dreg(regs, 1), (uae_s32)m68k_dreg(regs, 2),
                   1467:                          (uae_s32)m68k_dreg(regs, 3),
                   1468:                          m68k_dreg(regs, 4),
                   1469:                          m68k_areg(regs, 1), m68k_areg(regs, 2), m68k_areg(regs, 0));
                   1470: }
                   1471: static uae_u32 layers_CreateBehindLayer(void)
                   1472: {
                   1473:     return LY_CreateLayer(m68k_areg(regs, 0), (uae_s32)m68k_dreg(regs, 0),
                   1474:                          (uae_s32)m68k_dreg(regs, 1), (uae_s32)m68k_dreg(regs, 2),
                   1475:                          (uae_s32)m68k_dreg(regs, 3),
                   1476:                          m68k_dreg(regs, 4),
                   1477:                          m68k_areg(regs, 1), m68k_areg(regs, 2),
                   1478:                          find_behindlayer_position (m68k_areg(regs, 0), m68k_dreg(regs, 4)));
                   1479: }
                   1480: static uae_u32 layers_DeleteLayer(void) { LY_DeleteLayer (m68k_areg (regs, 1)); return 0; }
                   1481: 
                   1482: static void LY_LockLayer1(uaecptr layer)
                   1483: {
                   1484:     uaecptr li = get_long (layer + 68);
                   1485:     struct MyLayerInfo *mli = (struct MyLayerInfo *)find_uniq (&MyLayerInfo_list, get_long (li + 84));
                   1486:     struct MyLayer *l = (struct MyLayer *)find_uniq (&mli->layer_list, get_long (layer + 24));
                   1487: 
                   1488:     LY_LockLayer(layer);
                   1489:     build_cliprects (l);
                   1490: }
                   1491: static uae_u32 LY_TryLockLayer1(uaecptr layer)
                   1492: {
                   1493:     uaecptr li = get_long (layer + 68);
                   1494:     struct MyLayerInfo *mli = (struct MyLayerInfo *)find_uniq (&MyLayerInfo_list, get_long (li + 84));
                   1495:     struct MyLayer *l = (struct MyLayer *)find_uniq (&mli->layer_list, get_long (layer + 24));
                   1496: 
                   1497:     if (!LY_TryLockLayer(layer))
                   1498:        return 0;
                   1499:     build_cliprects (l);
                   1500:     return 1;
                   1501: }
                   1502: static uae_u32 gfx_TryLockLayer(void) { return LY_TryLockLayer1 (m68k_areg(regs, 5));  }
                   1503: static uae_u32 gfx_LockLayer(void) { LY_LockLayer1 (m68k_areg(regs, 5)); return 0; }
                   1504: static uae_u32 gfx_UnlockLayer(void) { LY_UnlockLayer(m68k_areg(regs, 5)); return 0; }
                   1505: static uae_u32 layers_LockLayer(void) { LY_LockLayer1 (m68k_areg(regs, 1)); return 0; }
                   1506: static uae_u32 layers_LockLayers(void) { LY_LockLayers(m68k_areg(regs, 0)); return 0; }
                   1507: static uae_u32 layers_LockLayerInfo(void) { LY_LockLayerInfo(m68k_areg(regs, 0)); return 0; }
                   1508: static uae_u32 layers_UnlockLayer(void) { LY_UnlockLayer(m68k_areg(regs, 0)); return 0; }
                   1509: static uae_u32 layers_UnlockLayers(void) { LY_UnlockLayers(m68k_areg(regs, 0)); return 0; }
                   1510: static uae_u32 layers_UnlockLayerInfo(void) { LY_UnlockLayerInfo(m68k_areg(regs, 0)); return 0; }
                   1511: 
                   1512: static uae_u32 layers_ScrollLayer(void)
                   1513: {
                   1514:     abort();
                   1515: }
                   1516: 
                   1517: static uae_u32 layers_SizeLayer(void)
                   1518: {
                   1519:     abort();
                   1520: }
                   1521: 
                   1522: static uae_u32 layers_MoveLayer(void)
                   1523: {
                   1524:     abort();
                   1525: }
                   1526: 
                   1527: static uae_u32 layers_UpfrontLayer(void)
                   1528: {
                   1529:     abort();
                   1530: }
                   1531: 
                   1532: static uae_u32 layers_BehindLayer(void)
                   1533: {
                   1534:     abort();
                   1535: }
                   1536: 
                   1537: static uae_u32 layers_MoveLayerInFrontOf(void)
                   1538: {
                   1539:     abort();
                   1540: }
                   1541: 
                   1542: static uae_u32 layers_BeginUpdate(void)
                   1543: {
                   1544:     return 1;
                   1545: }
                   1546: 
                   1547: static uae_u32 layers_EndUpdate(void)
                   1548: {
                   1549:     return 0;
                   1550: }
                   1551: 
                   1552: static uae_u32 layers_WhichLayer(void)
                   1553: {
                   1554:     abort();
                   1555: }
                   1556: 
                   1557: static uae_u32 layers_InstallClipRegion(void)
                   1558: {
                   1559:     return 0;
                   1560: }
                   1561: 
                   1562: static uae_u32 layers_SwapBitsRastPortClipRect(void)
                   1563: {
                   1564:     abort();
                   1565: }
                   1566: 
1.1       root     1567: /*
                   1568:  *  Initialization
                   1569:  */
1.1.1.3   root     1570: static uae_u32 gfxlib_init(void)
1.1       root     1571: {
1.1.1.3   root     1572:     uae_u32 old_arr;
                   1573:     uaecptr sysbase=m68k_areg(regs, 6);
1.1       root     1574:     int i=0;
                   1575: 
                   1576:     /* Install new routines */
1.1.1.2   root     1577:     m68k_dreg(regs, 0)=0;
                   1578:     m68k_areg(regs, 1)=gfxlibname;
1.1       root     1579:     gfxbase=CallLib(sysbase, -408);  /* OpenLibrary */
1.1.1.2   root     1580:     m68k_dreg(regs, 0)=0;
                   1581:     m68k_areg(regs, 1)=layerslibname;
                   1582:     layersbase=CallLib(sysbase, -408);  /* OpenLibrary */
                   1583: 
1.1.1.3   root     1584:     libemu_InstallFunctionFlags(gfxl_WritePixel, gfxbase, -324, TRAPFLAG_EXTRA_STACK, "");
                   1585:     libemu_InstallFunctionFlags(gfxl_BltClear, gfxbase, -300, 0, "");
                   1586:     libemu_InstallFunctionFlags(gfxl_AndRegionRegion, gfxbase, -624, TRAPFLAG_EXTRA_STACK, "");
                   1587:     libemu_InstallFunctionFlags(gfxl_OrRegionRegion, gfxbase, -612, TRAPFLAG_EXTRA_STACK, "");
                   1588:     libemu_InstallFunctionFlags(gfxl_XorRegionRegion, gfxbase, -618, TRAPFLAG_EXTRA_STACK, "");
                   1589:     libemu_InstallFunctionFlags(gfxl_AndRectRegion, gfxbase, -504, TRAPFLAG_EXTRA_STACK, "");
                   1590:     libemu_InstallFunctionFlags(gfxl_OrRectRegion, gfxbase, -510, TRAPFLAG_EXTRA_STACK, "");
                   1591:     libemu_InstallFunctionFlags(gfxl_XorRectRegion, gfxbase, -558, TRAPFLAG_EXTRA_STACK, "");
                   1592:     libemu_InstallFunctionFlags(gfxl_ClearRectRegion, gfxbase, -522, TRAPFLAG_EXTRA_STACK, "");
                   1593: 
                   1594: #if 0
                   1595: #define MAYBE_FUNCTION(a) NULL
                   1596: #else
                   1597: #define MAYBE_FUNCTION(a) (a)
                   1598: #endif
                   1599: #if 0
                   1600:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(gfx_TryLockLayer), gfxbase, -654, TRAPFLAG_EXTRA_STACK|TRAPFLAG_NO_RETVAL, "AttemptLockLayerRom");
                   1601:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(gfx_LockLayer), gfxbase, -432, TRAPFLAG_EXTRA_STACK|TRAPFLAG_NO_RETVAL, "LockLayerRom");
                   1602:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(gfx_UnlockLayer), gfxbase, -438, TRAPFLAG_EXTRA_STACK|TRAPFLAG_NO_RETVAL, "UnlockLayerRom");
                   1603: 
                   1604:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_InitLayers), layersbase, -30, TRAPFLAG_EXTRA_STACK, "InitLayers");
                   1605:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_CreateUpfrontLayer), layersbase, -36, TRAPFLAG_EXTRA_STACK, "CreateUpfrontLayer");
                   1606:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_CreateBehindLayer), layersbase, -42, TRAPFLAG_EXTRA_STACK, "CreateBehindLayer");
                   1607:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_UpfrontLayer), layersbase, -48, TRAPFLAG_EXTRA_STACK, "UpfrontLayer");
                   1608:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_BehindLayer), layersbase, -54, TRAPFLAG_EXTRA_STACK, "BehindLayer");
                   1609:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_MoveLayer), layersbase, -60, TRAPFLAG_EXTRA_STACK, "MoveLayer");
                   1610:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_SizeLayer), layersbase, -66, TRAPFLAG_EXTRA_STACK, "SizeLayer");
                   1611:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_ScrollLayer), layersbase, -72, TRAPFLAG_EXTRA_STACK, "ScrollLayer");
                   1612:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_BeginUpdate), layersbase, -78, TRAPFLAG_EXTRA_STACK, "BeginUpdate");
                   1613:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_EndUpdate), layersbase, -84, TRAPFLAG_EXTRA_STACK, "EndUpdate");
                   1614:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_DeleteLayer), layersbase, -90, TRAPFLAG_EXTRA_STACK, "DeleteLayer");
                   1615:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_LockLayer), layersbase, -96, TRAPFLAG_EXTRA_STACK, "LockLayer");
                   1616:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_UnlockLayer), layersbase, -102, TRAPFLAG_EXTRA_STACK, "UnlockLayer");
                   1617:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_LockLayers), layersbase, -108, TRAPFLAG_EXTRA_STACK, "LockLayers");
                   1618:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_UnlockLayers), layersbase, -114, TRAPFLAG_EXTRA_STACK, "UnlockLayers");
                   1619:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_LockLayerInfo), layersbase, -120, TRAPFLAG_EXTRA_STACK, "LockLayerInfo");
                   1620:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_SwapBitsRastPortClipRect), layersbase, -126, TRAPFLAG_EXTRA_STACK, "SwapBitsRastPortClipRect");
                   1621:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_WhichLayer), layersbase, -132, TRAPFLAG_EXTRA_STACK, "WhichLayer");
                   1622:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_UnlockLayerInfo), layersbase, -138, TRAPFLAG_EXTRA_STACK, "UnlockLayerInfo");
                   1623:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_NewLayerInfo), layersbase, -144, TRAPFLAG_EXTRA_STACK, "NewLayerInfo");
                   1624:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_DisposeLayerInfo), layersbase, -150, TRAPFLAG_EXTRA_STACK, "DisposeLayerInfo");
                   1625:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_FattenLayerInfo), layersbase, -156, TRAPFLAG_EXTRA_STACK, "FattenLayerInfo");
                   1626:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_ThinLayerInfo), layersbase, -162, TRAPFLAG_EXTRA_STACK, "ThinLayerInfo");
                   1627:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_MoveLayerInFrontOf), layersbase, -168, TRAPFLAG_EXTRA_STACK, "MoveLayerInFrontOf");
                   1628:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_InstallClipRegion), layersbase, -174, TRAPFLAG_EXTRA_STACK, "InstallClipRegion");
                   1629: #if 0
                   1630:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_), layersbase, -180, TRAPFLAG_EXTRA_STACK, "MoveSizeLayer");
                   1631:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_), layersbase, -186, TRAPFLAG_EXTRA_STACK, "CreateUpfrontHookLayer");
                   1632:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_), layersbase, -192, TRAPFLAG_EXTRA_STACK, "CreateBehindHookLayer");
                   1633:     libemu_InstallFunctionFlags(MAYBE_FUNCTION(layers_), layersbase, -198, TRAPFLAG_EXTRA_STACK, "InstallLayerHook");
                   1634: #endif
                   1635: #endif
1.1       root     1636:     return 0;
                   1637: }
                   1638: 
1.1.1.3   root     1639: /*
                   1640:  *  Install the gfx-library-replacement
1.1       root     1641:  */
                   1642: void gfxlib_install(void)
                   1643: {
1.1.1.3   root     1644:     uae_u32 begin, end, resname, resid;
1.1       root     1645:     int i;
1.1.1.3   root     1646: 
1.1.1.4 ! root     1647:     if (! currprefs.use_gfxlib)
        !          1648:        return;
1.1.1.3   root     1649: 
1.1.1.4 ! root     1650:     fprintf (stderr, "Warning: you enabled the graphics.library replacement with -g\n"
        !          1651:             "This may be buggy right now, and will not speed things up much.\n");
1.1       root     1652: 
1.1.1.4 ! root     1653:     resname = ds ("UAEgfxlib.resource");
        !          1654:     resid = ds ("UAE gfxlib 0.1");
1.1       root     1655: 
1.1.1.4 ! root     1656:     gfxlibname = ds ("graphics.library");
        !          1657:     layerslibname = ds ("layers.library");
1.1       root     1658: 
                   1659:     begin = here();
1.1.1.3   root     1660:     dw(0x4AFC);             /* RTC_MATCHuae_s16 */
1.1       root     1661:     dl(begin);              /* our start address */
                   1662:     dl(0);                  /* Continue scan here */
                   1663:     dw(0x0101);             /* RTF_COLDSTART; Version 1 */
                   1664:     dw(0x0805);             /* NT_RESOURCE; pri 5 */
                   1665:     dl(resname);            /* name */
                   1666:     dl(resid);              /* ID */
                   1667:     dl(here() + 4);         /* Init area: directly after this */
                   1668: 
1.1.1.3   root     1669:     calltrap(deftrap2(gfxlib_init, TRAPFLAG_EXTRA_STACK, "")); dw(RTS);
1.1       root     1670: 
                   1671:     end = here();
                   1672:     org(begin + 6);
                   1673:     dl(end);
                   1674: 
                   1675:     org(end);
                   1676: }
1.1.1.3   root     1677: #else
                   1678: 
                   1679: void gfxlib_install (void)
                   1680: {
                   1681: }
                   1682: 
                   1683: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.