home *** CD-ROM | disk | FTP | other *** search
- /*
- * PatchDT - Patch datatypes for faster blitting on systems with
- * enhanced video adapters.
- *
- * Improves performance roughly fourfold on 256-colour Workbench
- * screen in Zorro II mode, and even more when running in Zorro
- * III mode.
- *
- */
-
- /* === System Includes === */
-
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <proto/datatypes.h>
- #include <proto/utility.h>
- #include <proto/intuition.h>
- #include <proto/graphics.h>
- #include <datatypes/datatypes.h>
- #include <datatypes/pictureclass.h>
- #include <exec/memory.h>
- #include <exec/execbase.h>
-
- #include <string.h>
-
- /* === Function prototypes === */
-
- ULONG __asm __saveds GetDTAttrsA_patch(register __a0 Object *o, register __a2 struct TagItem *ti);
- VOID __asm __saveds DisposeDTObject_patch(register __a0 Object *o);
-
- extern __asm struct BitMap * ROMCall(register __d0 ULONG, register __d1 ULONG, register __d2 ULONG, register __d3 ULONG,
- register __a0 struct BitMap *, register __a5 void *, register __a6 void * );
-
- extern void __asm InitROMCall(void);
-
- /* === Various data items === */
-
- ULONG __asm (*getDTAttrsA)(register __a0 Object *, register __a2 struct TagItem *, register __a6 struct Library *dtBase);
- VOID __asm (*disposeDTObject)(register __a0 Object *, register __a6 struct Library *dtBase);
-
- void *allocBM;
-
- struct Library *DataTypesBase;
- struct Library *UtilityBase;
- struct ExecBase *SysBase;
- struct IntuitionBase *IntuitionBase;
- struct GfxBase *GfxBase;
- struct DosLibrary *DOSBase;
-
- #define MAX_KEYS 16 /* Maximum number of associations */
-
- ULONG key_list[MAX_KEYS]; /* List of keys */
- ULONG val_list[MAX_KEYS]; /* List of values associated with keys */
-
- /*
- * __main - Program entry
- *
- * Installs patch functions, waits for SIGBREAKF_CTRL_C, and uninstalls
- * patches.
- *
- */
-
- int __asm __saveds
- __main(void)
- {
- ULONG sig;
-
- /* === Open System Libraries - This only works with V39 and later === */
-
- SysBase = (*((struct ExecBase **)4));
-
- if (SysBase->LibNode.lib_Version < 39) {
- return RETURN_FAIL;
- }
-
- DataTypesBase = OpenLibrary("datatypes.library", 39);
- UtilityBase = OpenLibrary("utility.library", 39);
- IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39);
- GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 39);
- DOSBase = (struct DosLibrary *) OpenLibrary("dos.library", 39);
-
- InitROMCall();
-
- Forbid();
-
- /* === Patch vectors in datatypes.library === */
-
- disposeDTObject = SetFunction(DataTypesBase, -54, (APTR) DisposeDTObject_patch);
- getDTAttrsA = SetFunction(DataTypesBase, -66, (APTR) GetDTAttrsA_patch);
-
- /* === Find out address of AllocBitMap() function === */
-
- allocBM = SetFunction( (struct Library *) GfxBase, -918, NULL);
- SetFunction( (struct Library *) GfxBase, -918, allocBM);
-
- Permit();
-
- /* === Wait for signal to uninstall === */
-
- sig = 0;
-
- while (! (sig & SIGBREAKF_CTRL_C) ) {
- sig = Wait( SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D );
- }
-
- /* === Uninstall patch functions from datatypes.library === */
-
- Forbid();
-
- SetFunction(DataTypesBase, -54, (APTR) disposeDTObject);
- SetFunction(DataTypesBase, -66, (APTR) getDTAttrsA);
-
- Permit();
-
- /* === Close all open libraries === */
-
- CloseLibrary((struct Library *) DOSBase);
- CloseLibrary((struct Library *) GfxBase);
- CloseLibrary((struct Library *) IntuitionBase);
- CloseLibrary(UtilityBase);
- CloseLibrary(DataTypesBase);
-
- return 0;
- }
-
- /*
- * Association functions. Used to associate an arbitrary value (in this case
- * a pointer to a BitMap structure) with a key (in this case a datatypes
- * Object).
- *
- * associate(key) - returns the value associated with the given key.
- * disassociate(key) - forget an association
- * new_associate(key,value) - create a new association
- *
- */
-
- ULONG
- associate(ULONG key)
- {
- int i;
-
- for (i = 0; i < MAX_KEYS; i++) {
- if (key_list[i] == key) {
- return val_list[i];
- }
- }
-
- return 0;
- }
-
- void
- disassociate(ULONG key)
- {
- int i;
-
- for (i = 0; i < MAX_KEYS; i++) {
- if (key_list[i] == key) {
- val_list[i] = 0;
- key_list[i] = 0;
- }
- }
- }
-
- ULONG
- new_associate(ULONG key, ULONG value)
- {
- int i;
-
- for (i = 0; i < MAX_KEYS; i++) {
- if (key_list[i] == 0) {
- val_list[i] = value;
- key_list[i] = key;
-
- return key;
- }
- }
-
- return 0;
- }
-
- /*
- * Patch function for datatypes.library function GetDTAttrsA()
- *
- */
-
- ULONG __asm __saveds
- GetDTAttrsA_patch(register __a0 Object *o, register __a2 struct TagItem *ti)
- {
- ULONG retval;
- struct BitMap **bitmapPtr;
- struct BitMap *newBitMap;
- struct BitMapHeader *bmh;
- struct Screen *WBScreen;
-
- int width, height, depth;
- struct BitMap *friend;
-
- /* == First call original function == */
-
- retval = (*getDTAttrsA)(o, ti, DataTypesBase);
-
- /* === Optimization is only safe if "« IPrefs »" is the name of
- * the calling task. Programs such as MultiView may expect
- * the data to be in a specific format (even though it
- * really should not).
- */
-
- if (strcmp("« IPrefs »", (FindTask(NULL)->tc_Node.ln_Name)) == 0) {
-
- /* Get pointer to where the caller wants the BitMap pointer stored */
-
- bitmapPtr = (struct BitMap **) GetTagData (PDTA_BitMap, 0, ti);
-
- if (bitmapPtr) {
-
- /* If this Object already has an associated bitmap, return it */
-
- if (newBitMap = (struct BitMap *) associate((ULONG) o)) {
- *bitmapPtr = newBitMap;
- } else {
- ULONG tags[3];
-
- /* === Get sizing information from Object === */
-
- tags[0] = PDTA_BitMapHeader;
- tags[1] = (ULONG) &bmh;
- tags[2] = TAG_END;
-
- (*getDTAttrsA)(o, (struct TagItem *) tags, DataTypesBase);
-
- /* === Get pointer to Workbench screen, in order to obtain pointer
- * to the friend bitmap.
- */
-
- WBScreen = LockPubScreen( "Workbench" );
-
- /* Notice that I use the BitMap pointer stored in the Screen's
- * RastPort instead of the BitMap embedded in the Screen
- * structure. This is for future compatibility with V41 and
- * beyond, which has several different layouts (and sizes) for
- * BitMap structures. Everybody should do it like this.
- */
-
- friend = WBScreen->RastPort.BitMap;
- depth = friend->Depth;
-
- width = bmh->bmh_Width;
- height = bmh->bmh_Height;
-
- /* I have to call the AllocBitMap() function through an assembly
- * language stub in order to make it look as if the AllocBitMap()
- * call was done from ROM. Otherwise the EGS Workbench Emulation
- * software will not redirect the call, and this patch will have
- * no effect.
- */
-
- newBitMap = ROMCall(width, height, depth, 0, friend, allocBM, GfxBase);
-
- /* === Release Lock on Workbench screen === */
-
- UnlockPubScreen(NULL, WBScreen);
-
- /* === Now blit the image from the original bitmap into our newly
- * allocated bitmap, and set the caller's bitmap pointer to
- * point at our new bitmap.
- */
-
- if (newBitMap) {
- BltBitMap(*bitmapPtr, 0,0, newBitMap, 0,0, bmh->bmh_Width, bmh->bmh_Height, 0xC0, 0xff, 0);
-
- if (new_associate((ULONG) o, (ULONG) newBitMap)) {
- *bitmapPtr = newBitMap; /* Success! */
- } else {
- FreeBitMap(newBitMap);
- DisplayBeep(WBScreen); /* Error! Association table full */
- }
- } else {
- DisplayBeep(WBScreen); /* Error! Could not allocate BitMap */
- }
- }
- }
- }
-
- return retval;
- }
-
- /*
- * Patch function for datatypes.library DisposeDTObject() function.
- *
- * Simply calls FreeBitMap() if the Object has a special BitMap
- * allocated by us associated with it, and then falls through to the
- * original DisposeDTObject() function.
- *
- */
-
- VOID __asm __saveds
- DisposeDTObject_patch(register __a0 Object *o)
- {
- struct BitMap *bm;
-
- if (bm = (struct BitMap *) associate((ULONG) o)) {
- FreeBitMap(bm);
- disassociate((ULONG) o); /* Forget about this object */
- }
-
- (*disposeDTObject)(o, DataTypesBase);
- }
-