--- uae/src/gfxlib.c 2018/04/24 16:38:39 1.1 +++ uae/src/gfxlib.c 2018/04/24 16:39:08 1.1.1.2 @@ -4,6 +4,25 @@ * graphics.library emulation * * Copyright 1996 Bernd Schmidt + * + * Ideas for this: + * Rewrite layers completely. When there are lots of windows on the screen + * it can take 3 minutes to update everything after resizing or moving one + * (at least with Kick 1.3). Hide the internal structure of the layers as far + * as possible, keep most of the data in emulator space so we save copying/ + * conversion time. Programs really shouldn't do anything directly with the + * Layer or ClipRect structures. + * This means that a lot of graphics.library functions will have to be + * rewritten as well. Of course there's the problem that we can't Wait() in + * the emulator currently, so we can't lock layers reliably. Big problem. + * Once that's done, add support for non-planar bitmaps. Conveniently, the + * struct Bitmap has an unused pad field which we could abuse as some sort of + * type field. Need to add chunky<->planar conversion routines to get it + * going, plus variants of all the drawing functions for speed reasons. + * + * When it becomes necessary to convert a structure from Amiga memory, make + * a function with a name ending in ..FA, which takes a pointer to the + * native structure and a CPTR and returns the native pointer. */ #include "sysconfig.h" @@ -15,13 +34,17 @@ #include "options.h" #include "memory.h" #include "custom.h" +#include "readcpu.h" #include "newcpu.h" #include "xwin.h" #include "autoconf.h" #include "osemu.h" -/* Global variables etc. */ -static ULONG gfxlibname; +static ULONG gfxlibname, layerslibname; + +struct Rectangle { + int MinX, MinY, MaxX, MaxY; +}; static int GFX_PointInRectangle(CPTR rect, int x, int y) { @@ -35,6 +58,21 @@ static int GFX_PointInRectangle(CPTR rec return 1; } +static int GFX_RectContainsRect(struct Rectangle *r1, struct Rectangle *r2) +{ + return (r2->MinX >= r1->MinX && r2->MaxX <= r1->MaxX + && r2->MinY >= r1->MinY && r2->MaxY <= r1->MaxY); +} + +static struct Rectangle *GFX_RectFA(struct Rectangle *rp, CPTR rect) +{ + rp->MinX = (WORD)get_word(rect); + rp->MinY = (WORD)get_word(rect+2); + rp->MaxX = (WORD)get_word(rect+4); + rp->MaxY = (WORD)get_word(rect+6); + return rp; +} + static int GFX_Bitmap_WritePixel(CPTR bitmap, int x, int y, CPTR rp) { int i, offs; @@ -131,14 +169,14 @@ int GFX_WritePixel(CPTR rp, int x, int y } -static ULONG gfxl_WritePixel(void) { return GFX_WritePixel(regs.a[1], (WORD)regs.d[0], (WORD)regs.d[1]); } +static ULONG gfxl_WritePixel(void) { return GFX_WritePixel(m68k_areg(regs, 1), (WORD)m68k_dreg(regs, 0), (WORD)m68k_dreg(regs, 1)); } static ULONG gfxl_BltClear(void) { - CPTR mem=regs.a[1]; - UBYTE *mptr = chipmem_bank.xlateaddr(regs.a[1]); - ULONG count=regs.d[0]; - ULONG flags=regs.d[1]; + CPTR mem=m68k_areg(regs, 1); + UBYTE *mptr = chipmem_bank.xlateaddr(m68k_areg(regs, 1)); + ULONG count=m68k_dreg(regs, 0); + ULONG flags=m68k_dreg(regs, 1); unsigned int i; ULONG pattern; @@ -155,7 +193,7 @@ static ULONG gfxl_BltClear(void) if ((flags & 4) == 0) pattern = 0; else - pattern= ((flags >> 16) & 0xFFFF) | (flags & 0xFFFF0000); + pattern= ((flags >> 16) & 0xFFFF) | (flags & 0xFFFF0000ul); if ((pattern & 0xFF) == ((pattern >> 8) & 0xFF)) { memset(mptr, pattern, count); @@ -173,39 +211,37 @@ static ULONG gfxl_BltClear(void) static ULONG gfxl_BltBitmap(void) { - CPTR srcbitmap = regs.a[0], dstbitmap = regs.a[1]; - int srcx = (WORD)regs.d[0], srcy = (WORD)regs.d[1]; - int dstx = (WORD)regs.d[2], dsty = (WORD)regs.d[3]; - int sizex = (WORD)regs.d[4], sizey = (WORD)regs.d[5]; - UBYTE minterm = (UBYTE)regs.d[6], mask = regs.d[7]; - + CPTR srcbitmap = m68k_areg(regs, 0), dstbitmap = m68k_areg(regs, 1); + int srcx = (WORD)m68k_dreg(regs, 0), srcy = (WORD)m68k_dreg(regs, 1); + int dstx = (WORD)m68k_dreg(regs, 2), dsty = (WORD)m68k_dreg(regs, 3); + int sizex = (WORD)m68k_dreg(regs, 4), sizey = (WORD)m68k_dreg(regs, 5); + UBYTE minterm = (UBYTE)m68k_dreg(regs, 6), mask = m68k_dreg(regs, 7); + return 0; /* sam: a return was missing here ! */ } static CPTR amiga_malloc(int len) { - regs.d[0] = len; - regs.d[1] = 1; /* MEMF_PUBLIC */ + m68k_dreg(regs, 0) = len; + m68k_dreg(regs, 1) = 1; /* MEMF_PUBLIC */ return CallLib(get_long(4), -198); /* AllocMem */ } static void amiga_free(CPTR addr, int len) { - regs.a[1] = addr; - regs.d[0] = len; + m68k_areg(regs, 1) = addr; + m68k_dreg(regs, 0) = len; CallLib(get_long(4), -210); /* FreeMem */ } /* * Region handling code + * + * General ideas stolen from xc/verylongpath/miregion.c * * The Clear code is untested. And and Or seem to work, Xor is only used * by the 1.3 Prefs program and seems to work, too. */ -struct Rectangle { - WORD MinX, MinY, MaxX, MaxY; -}; - struct RegionRectangle { struct RegionRectangle *Next,*Prev; struct Rectangle bounds; @@ -820,16 +856,16 @@ static ULONG gfxl_perform_regionop(regio if (with_rect) { struct Rectangle tmpr; - reg2 = regs.a[0]; + reg2 = m68k_areg(regs, 0); numrects2 = copy_rects(reg2, &rl2); - tmpr.MinX = get_word(regs.a[1]); - tmpr.MinY = get_word(regs.a[1] + 2); - tmpr.MaxX = get_word(regs.a[1] + 4); - tmpr.MaxY = get_word(regs.a[1] + 6); + tmpr.MinX = get_word(m68k_areg(regs, 1)); + tmpr.MinY = get_word(m68k_areg(regs, 1) + 2); + tmpr.MaxX = get_word(m68k_areg(regs, 1) + 4); + tmpr.MaxY = get_word(m68k_areg(regs, 1) + 6); add_rect(&rl1, tmpr); } else { - reg1 = regs.a[0]; - reg2 = regs.a[1]; + reg1 = m68k_areg(regs, 0); + reg2 = m68k_areg(regs, 1); copy_rects(reg1, &rl1); numrects2 = copy_rects(reg2, &rl2); @@ -897,40 +933,33 @@ static ULONG gfxl_perform_regionop(regio static ULONG gfxl_AndRegionRegion(void) { -/* printf("AndRegionRegion\n");*/ return gfxl_perform_regionop(region_do_AndRegionRegion, 0); } static ULONG gfxl_XorRegionRegion(void) { - printf("XorRegionRegion\n"); return gfxl_perform_regionop(region_do_XorRegionRegion, 0); } static ULONG gfxl_OrRegionRegion(void) { -/* printf("OrRegionRegion\n");*/ return gfxl_perform_regionop(region_do_OrRegionRegion, 0); } static ULONG gfxl_ClearRectRegion(void) { - printf("ClearRectRegion\n"); return gfxl_perform_regionop(region_do_ClearRegionRegion, 1); } static ULONG gfxl_OrRectRegion(void) { -/* printf("OrRectRegion\n");*/ return gfxl_perform_regionop(region_do_OrRegionRegion, 1); } static ULONG gfxl_AndRectRegion(void) { - printf("AndRectRegion\n"); return gfxl_perform_regionop(region_do_AndRegionRegion, 1); } static ULONG gfxl_XorRectRegion(void) { - printf("XorRectRegion\n"); return gfxl_perform_regionop(region_do_XorRegionRegion, 1); } @@ -941,28 +970,40 @@ static ULONG gfxl_XorRectRegion(void) static ULONG gfxlib_init(void) { ULONG old_arr; - CPTR gfxbase; - CPTR sysbase=regs.a[6]; + CPTR gfxbase, layersbase; + CPTR sysbase=m68k_areg(regs, 6); int i=0; /* Install new routines */ /* We have to call SetFunction here instead of writing direktly into the GfxBase, * because of the library checksum ! */ - regs.d[0]=0; - regs.a[1]=gfxlibname; + m68k_dreg(regs, 0)=0; + m68k_areg(regs, 1)=gfxlibname; gfxbase=CallLib(sysbase, -408); /* OpenLibrary */ - - libemu_InstallFunction(gfxl_WritePixel, gfxbase, -324); - libemu_InstallFunction(gfxl_BltClear, gfxbase, -300); - libemu_InstallFunction(gfxl_AndRegionRegion, gfxbase, -624); - libemu_InstallFunction(gfxl_OrRegionRegion, gfxbase, -612); - libemu_InstallFunction(gfxl_XorRegionRegion, gfxbase, -618); - libemu_InstallFunction(gfxl_AndRectRegion, gfxbase, -504); - libemu_InstallFunction(gfxl_OrRectRegion, gfxbase, -510); - libemu_InstallFunction(gfxl_XorRectRegion, gfxbase, -558); - libemu_InstallFunction(gfxl_ClearRectRegion, gfxbase, -522); - + m68k_dreg(regs, 0)=0; + m68k_areg(regs, 1)=layerslibname; + layersbase=CallLib(sysbase, -408); /* OpenLibrary */ + + libemu_InstallFunction(gfxl_WritePixel, gfxbase, -324, ""); + libemu_InstallFunction(gfxl_BltClear, gfxbase, -300, ""); + libemu_InstallFunction(gfxl_AndRegionRegion, gfxbase, -624, ""); + libemu_InstallFunction(gfxl_OrRegionRegion, gfxbase, -612, ""); + libemu_InstallFunction(gfxl_XorRegionRegion, gfxbase, -618, ""); + libemu_InstallFunction(gfxl_AndRectRegion, gfxbase, -504, ""); + libemu_InstallFunction(gfxl_OrRectRegion, gfxbase, -510, ""); + libemu_InstallFunction(gfxl_XorRectRegion, gfxbase, -558, ""); + libemu_InstallFunction(gfxl_ClearRectRegion, gfxbase, -522, ""); + + libemu_InstallFunction(NULL, layersbase, -60, "MoveLayer"); + libemu_InstallFunction(NULL, layersbase, -96, "LockLayer"); + libemu_InstallFunction(NULL, layersbase, -102, "UnlockLayer"); + libemu_InstallFunction(NULL, layersbase, -108, "LockLayers"); + libemu_InstallFunction(NULL, layersbase, -114, "UnlockLayers"); + libemu_InstallFunction(NULL, layersbase, -120, "LockLayerInfo"); + libemu_InstallFunction(NULL, layersbase, -138, "UnlockLayerInfo"); + libemu_InstallFunction(NULL, layersbase, -144, "NewLayerInfo"); + libemu_InstallFunction(NULL, layersbase, -156, "FattenLayerInfo"); return 0; } @@ -983,6 +1024,7 @@ void gfxlib_install(void) resid = ds("UAE gfxlib 0.1"); gfxlibname = ds("graphics.library"); + layerslibname = ds("layers.library"); begin = here(); dw(0x4AFC); /* RTC_MATCHWORD */