home *** CD-ROM | disk | FTP | other *** search
- /*
- * UAE - The Un*x Amiga Emulator
- *
- * Graphics.library replacement
- *
- * (c) 1996 by Christian Schmitt <schmittc@uni-freiburg.de>
- *
- * (c) 1996 by Markus Gietzen
- *
- */
-
- #include "sysconfig.h"
- #include "sysdeps.h"
-
- #include <assert.h>
-
- #include "config.h"
- #include "options.h"
- #include "memory.h"
- #include "custom.h"
- #include "newcpu.h"
- #include "xwin.h"
- #include "autoconf.h"
- #include "gfxlib.h"
-
-
- /* Global variables etc. */
- static ULONG gfxlibname;
-
- static CPTR Move,WritePixel,ReadPixel,SetRast,BltClear;
-
-
- static ULONG gfxl_WritePixel(void)
- {
- CPTR rastport=regs.a[1],layer=longget(rastport);
- CPTR bitmap=longget(rastport+4),adr=0L;
- UWORD x=regs.d[0],minx,miny,maxx,maxy;
- UWORD y=regs.d[1];
- UBYTE new=0,old=0,pen=byteget(rastport+25),
- depth=byteget(bitmap+5),pixel;
- UWORD bpr=wordget(bitmap);
- UWORD rows=wordget(bitmap+2);
- CPTR Planeptr=longget(bitmap+8),Plane=0;
- int i;
-
- if(layer!=0){
- rastport=longget(layer+12);
- pen=byteget(rastport+25);
- bitmap=longget(rastport+4);
- depth=byteget(bitmap+5);
- minx=wordget(layer+16);
- miny=wordget(layer+18);
- maxx=wordget(layer+20);
- maxy=wordget(layer+22);
- bpr=wordget(bitmap);
- rows=wordget(bitmap+2);
- } else {
- minx=miny=0;
- maxx=bpr*8;
- maxy=rows;
- }
- y=y+miny;
- x=x+minx;
- if((x>maxx)||(y>maxy)){
- regs.d[0]=-1;
- return 0;
- } else {
- for(i=0;i<depth;i++){
- Plane=longget(bitmap+8+4*i);
- old=byteget(Plane+y*bpr+x/8);
- if(!(pen&(1<<i))) new=old | (128>>(x%8));
- else new=old&(0xff-(128>>(x%8)));
- byteput(Plane+y*bpr+x/8,new);
- }
- }
- regs.d[0]=0;
- return 0;
- }
-
-
- static ULONG gfxl_ReadPixel(void)
- {
- CPTR rastport=regs.a[1];
- CPTR bitmap=longget(rastport+4);
- UWORD x=regs.d[0],y=regs.d[1],old;
- UBYTE pen=0,depth=byteget(bitmap+5);
- UWORD bpr=wordget(bitmap);
- UWORD rows=wordget(bitmap+2);
- CPTR PlanePtr=longget(bitmap+8),Plane=0;
- int i;
- for(i=0;i<depth;i++){
- Plane=longget(bitmap+8+4*i);
- old=byteget(Plane+y*bpr+x/8);
- if(((128>>(x%8))&old)) pen=pen+(1<<i);
- }
- regs.d[0]=pen;
- return 0;
- }
-
-
- static ULONG gfxl_SetRast(void) /* This function isn't working right now */
- {
- CPTR rastport=regs.a[1],bitmap,PlanePtr,Plane,layer;
- UBYTE pen=regs.d[0],depth,mode=byteget(rastport+28);
- UWORD bpr,rows,minx=0,miny=0,maxx,maxy,dx,x,y,dy;
- ULONG pattern,bits=0,new,old;
- int i,j;
-
- layer=longget(rastport);
- bitmap=longget(rastport+4);
- PlanePtr=longget(bitmap+8);
- bpr=wordget(bitmap);
- rows=wordget(bitmap+2);
- depth=byteget(bitmap+5);
- switch(mode) { /* What else do I have to do here ? */
- case 0 : break;
- case 1 : pen=byteget(rastport+26);break;
- default: break;
- }
- if(layer!=0) {
- rastport=longget(layer+12);
- minx=wordget(layer+16);
- miny=wordget(layer+18);
- maxx=wordget(layer+20);
- maxy=wordget(layer+22);
- } else {
- maxx=bpr*8;
- maxy=rows-1;
- }
- for(i=0;i<depth-1;i++){
- Plane=longget(bitmap+8+i*4);
- if((pen&(1<<i))) pattern=0xffffffff; else pattern=0;
- for(y=miny;y<=maxy;y++){
- x=0;dx=0,dy=0;
- new=old=longget(Plane+y*bpr+minx);
- while(((minx+x)%8!=0)&&(x<=maxx)){
- if(pattern==0xffffffff) new=new|(1<<(minx+x)%8);
- else new=new&(0xff-(1<<(minx+x)%8));
- x++;
- }
- if(x!=0) dx=1;
- byteput(Plane+y*bpr+minx,new);dy=x;
- while(8+dy<=maxx){
- byteput(Plane+y*bpr+minx+dx,pattern);
- dx++;
- dy+=8;
- }
- x=0;
- new=byteget(Plane+y*bpr+minx+dx);
- while(((minx+dy+x)%8!=0)&&(x+dy<=maxx)){
- if(pattern==0xffffffff) new=new|(1<<(minx+dy+x)%8);
- else new=new&(0xff-(1<<(minx+dy+x)%8));
- x++;
- }
- byteput(Plane+y*bpr+minx+dx,new);
- }
- }
- return 0;
- }
-
-
- static ULONG gfxl_BltClear(void)
- {
- CPTR mem=regs.a[1];
- ULONG count=regs.d[0];
- ULONG flags=regs.d[1];
- UWORD rows,bpr;
- UWORD pattern=((flags&0xffff0000)>>16);
- unsigned int i;
-
- if((flags&2)){
- bpr= (count&0x0000ffff);
- rows=(count>>16);
- count=bpr*rows;
- }
- if(flags&3){
- for(i=0;i<count;i+=2) wordput(mem+i,pattern);
- if(count%2) byteput(mem+(count/2)*2,pattern);
- }else {
- for(i=0;i<count;i+=4) longput(mem+i,0);
- mem=mem+(count/4)*4;
- switch(count%4) {
- case 0 : break;
- case 1 : byteput(mem,0);break;
- case 2 : wordput(mem,0);break;
- case 3 : wordput(mem,0);byteput(mem+2,0);break;
- default: break; /* Ooops */
- }
- }
- return 0;
- }
-
- static ULONG gfxl_Move(void)
- {
- CPTR rastport=regs.a[1];
- WORD x=regs.d[0];
- WORD y=regs.d[1];
- /* Set new coordinate */
- wordput(rastport+36,x);
- wordput(rastport+38,y);
- /* Set Linepatcnt */
- byteput(rastport+30,0x0f);
- return(0);
- }
-
-
- /*
- * Initialisation (called by AMIGA-OS !)
- */
- static ULONG gfxlib_init(void)
- {
- CPTR gfxbase;
- CPTR sysbase=regs.a[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;
- gfxbase=CallLib(sysbase, -408); /* OpenLibrary */
-
- regs.a[1]=gfxbase;
- regs.a[0]=-240;
- regs.d[0]=Move;
- CallLib(sysbase, -420); /* SetFunction */
-
- regs.a[1]=gfxbase;
- regs.a[0]=-324;
- regs.d[0]=WritePixel;
- CallLib(sysbase, -420);
-
- regs.a[1]=gfxbase;
- regs.a[0]=-300;
- regs.d[0]=BltClear;
- CallLib(sysbase, -420);
-
- regs.a[1]=gfxbase;
- regs.a[0]=-234;
- regs.d[0]=SetRast;
- CallLib(sysbase, -420);
-
- regs.a[0]=-318;
- regs.d[0]=ReadPixel;
- CallLib(sysbase,-420);
-
- return 0;
- }
-
- /*
- * Install the gfx-library-replacement
- */
- void gfxlib_install(void)
- {
- ULONG begin, end, resname, resid;
- int i;
-
- if(!use_gfxlib) return;
-
- fprintf(stderr, "Warning: you enabled the graphics.library replacement with -g\n"
- "This may be buggy right now, and will not speed things up much.\n");
-
- resname = ds("UAEgfxlib.resource");
- resid = ds("UAE gfxlib 0.1");
-
- gfxlibname = ds("graphics.library");
-
- begin = here();
- dw(0x4AFC); /* RTC_MATCHWORD */
- dl(begin); /* our start address */
- dl(0); /* Continue scan here */
- dw(0x0101); /* RTF_COLDSTART; Version 1 */
- dw(0x0805); /* NT_RESOURCE; pri 5 */
- dl(resname); /* name */
- dl(resid); /* ID */
- dl(here() + 4); /* Init area: directly after this */
-
- calltrap(deftrap(gfxlib_init)); dw(RTS);
-
- /* start of code */
-
- Move=here();
- calltrap(deftrap(gfxl_Move));
- dw(RTS);
-
- WritePixel=here();
- calltrap(deftrap(gfxl_WritePixel));
- dw(RTS);
-
- ReadPixel=here();
- calltrap(deftrap(gfxl_ReadPixel));
- dw(RTS);
-
- SetRast=here();
- calltrap(deftrap(gfxl_SetRast));
- dw(RTS);
-
- BltClear=here();
- calltrap(deftrap(gfxl_BltClear));
- dw(RTS);
-
- end = here();
- org(begin + 6);
- dl(end);
-
- org(end);
- }
-