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

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

unix.superglobalmegacorp.com

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