home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD1.iso / Emulatoren / UAE061.LZH / uae-0.6.1 / gfxlib.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-28  |  8.6 KB  |  309 lines

  1.  /*
  2.   * UAE - The Un*x Amiga Emulator
  3.   *
  4.   *   Graphics.library replacement
  5.   *
  6.   *   (c) 1996 by Christian Schmitt   <schmittc@uni-freiburg.de>
  7.   *
  8.   *   (c) 1996 by Markus Gietzen
  9.   *
  10.   */
  11.  
  12. #include "sysconfig.h"
  13. #include "sysdeps.h"
  14.  
  15. #include <assert.h>
  16.  
  17. #include "config.h"
  18. #include "options.h"
  19. #include "memory.h"
  20. #include "custom.h"
  21. #include "newcpu.h"
  22. #include "xwin.h"
  23. #include "autoconf.h"
  24. #include "gfxlib.h"
  25.  
  26.  
  27. /* Global variables etc. */
  28. static ULONG gfxlibname;
  29.  
  30. static CPTR Move,WritePixel,ReadPixel,SetRast,BltClear;
  31.  
  32.  
  33. static ULONG gfxl_WritePixel(void)
  34. {
  35.         CPTR rastport=regs.a[1],layer=longget(rastport);
  36.         CPTR bitmap=longget(rastport+4),adr=0L;
  37.         UWORD x=regs.d[0],minx,miny,maxx,maxy;
  38.         UWORD y=regs.d[1];
  39.         UBYTE new=0,old=0,pen=byteget(rastport+25),
  40.               depth=byteget(bitmap+5),pixel;
  41.         UWORD bpr=wordget(bitmap);
  42.         UWORD rows=wordget(bitmap+2);
  43.         CPTR Planeptr=longget(bitmap+8),Plane=0;
  44.         int i;
  45.  
  46.         if(layer!=0){
  47.                 rastport=longget(layer+12);
  48.                 pen=byteget(rastport+25);
  49.                 bitmap=longget(rastport+4);
  50.                 depth=byteget(bitmap+5);
  51.                 minx=wordget(layer+16);
  52.                 miny=wordget(layer+18);
  53.                 maxx=wordget(layer+20);
  54.                 maxy=wordget(layer+22);
  55.                 bpr=wordget(bitmap);
  56.                 rows=wordget(bitmap+2);
  57.         } else {
  58.                 minx=miny=0;
  59.                 maxx=bpr*8;
  60.                 maxy=rows;
  61.         }
  62.         y=y+miny;
  63.         x=x+minx;
  64.         if((x>maxx)||(y>maxy)){
  65.                 regs.d[0]=-1;
  66.                 return 0;
  67.         } else {
  68.                 for(i=0;i<depth;i++){
  69.                         Plane=longget(bitmap+8+4*i);
  70.                         old=byteget(Plane+y*bpr+x/8);
  71.                         if(!(pen&(1<<i))) new=old | (128>>(x%8));
  72.                         else new=old&(0xff-(128>>(x%8)));
  73.                         byteput(Plane+y*bpr+x/8,new);
  74.                 }
  75.     }
  76.         regs.d[0]=0;
  77.         return 0;
  78. }                    
  79.  
  80.  
  81. static ULONG gfxl_ReadPixel(void)
  82. {
  83.         CPTR rastport=regs.a[1];
  84.         CPTR bitmap=longget(rastport+4);
  85.         UWORD x=regs.d[0],y=regs.d[1],old;
  86.         UBYTE pen=0,depth=byteget(bitmap+5);
  87.         UWORD bpr=wordget(bitmap);
  88.         UWORD rows=wordget(bitmap+2);
  89.         CPTR PlanePtr=longget(bitmap+8),Plane=0;
  90.         int i;
  91.         for(i=0;i<depth;i++){
  92.                 Plane=longget(bitmap+8+4*i);
  93.                 old=byteget(Plane+y*bpr+x/8);
  94.                 if(((128>>(x%8))&old)) pen=pen+(1<<i);
  95.         }
  96.         regs.d[0]=pen;
  97.         return 0;
  98. }
  99.  
  100.  
  101. static ULONG gfxl_SetRast(void)       /* This function isn't working right now */
  102. {
  103.         CPTR rastport=regs.a[1],bitmap,PlanePtr,Plane,layer;
  104.         UBYTE pen=regs.d[0],depth,mode=byteget(rastport+28);
  105.         UWORD bpr,rows,minx=0,miny=0,maxx,maxy,dx,x,y,dy;
  106.         ULONG pattern,bits=0,new,old;
  107.         int i,j;
  108.  
  109.         layer=longget(rastport);
  110.         bitmap=longget(rastport+4);
  111.         PlanePtr=longget(bitmap+8);
  112.         bpr=wordget(bitmap);
  113.         rows=wordget(bitmap+2);
  114.         depth=byteget(bitmap+5);
  115.     switch(mode) {                /* What else do I have to do here ? */   
  116.             case 0 : break;
  117.         case 1 : pen=byteget(rastport+26);break;
  118.         default: break;
  119.         }
  120.         if(layer!=0) {
  121.                 rastport=longget(layer+12);
  122.                 minx=wordget(layer+16);
  123.                 miny=wordget(layer+18);
  124.                 maxx=wordget(layer+20);
  125.                 maxy=wordget(layer+22); 
  126.         } else {
  127.             maxx=bpr*8;
  128.         maxy=rows-1;
  129.     }
  130.         for(i=0;i<depth-1;i++){   
  131.                 Plane=longget(bitmap+8+i*4);
  132.                 if((pen&(1<<i))) pattern=0xffffffff; else pattern=0;
  133.                 for(y=miny;y<=maxy;y++){
  134.                         x=0;dx=0,dy=0;
  135.                         new=old=longget(Plane+y*bpr+minx);
  136.                         while(((minx+x)%8!=0)&&(x<=maxx)){
  137.                                 if(pattern==0xffffffff) new=new|(1<<(minx+x)%8);
  138.                                 else new=new&(0xff-(1<<(minx+x)%8));
  139.                                 x++;
  140.                         }
  141.                         if(x!=0) dx=1;
  142.                         byteput(Plane+y*bpr+minx,new);dy=x;
  143.                         while(8+dy<=maxx){
  144.                                 byteput(Plane+y*bpr+minx+dx,pattern);
  145.                                 dx++;
  146.                                 dy+=8;
  147.                         }
  148.                         x=0;
  149.                         new=byteget(Plane+y*bpr+minx+dx);
  150.                         while(((minx+dy+x)%8!=0)&&(x+dy<=maxx)){
  151.                                 if(pattern==0xffffffff) new=new|(1<<(minx+dy+x)%8);
  152.                                 else new=new&(0xff-(1<<(minx+dy+x)%8));
  153.                                 x++;
  154.                         } 
  155.                         byteput(Plane+y*bpr+minx+dx,new);
  156.                 }
  157.         }
  158.         return 0;
  159. }       
  160.    
  161.  
  162. static ULONG gfxl_BltClear(void)
  163. {
  164.         CPTR mem=regs.a[1];
  165.         ULONG count=regs.d[0];
  166.         ULONG flags=regs.d[1];
  167.         UWORD rows,bpr;
  168.         UWORD pattern=((flags&0xffff0000)>>16);
  169.         unsigned int i;
  170.  
  171.         if((flags&2)){
  172.                 bpr= (count&0x0000ffff);
  173.                 rows=(count>>16);
  174.                 count=bpr*rows;
  175.         }
  176.         if(flags&3){
  177.                 for(i=0;i<count;i+=2) wordput(mem+i,pattern);
  178.                 if(count%2) byteput(mem+(count/2)*2,pattern);
  179.         }else {
  180.                 for(i=0;i<count;i+=4) longput(mem+i,0);
  181.                 mem=mem+(count/4)*4;
  182.                 switch(count%4) {
  183.                         case 0 : break;
  184.                         case 1 : byteput(mem,0);break;
  185.                         case 2 : wordput(mem,0);break;
  186.                         case 3 : wordput(mem,0);byteput(mem+2,0);break;
  187.                         default: break; /* Ooops */
  188.                 }
  189.         }
  190.         return 0;
  191. }  
  192.  
  193. static ULONG gfxl_Move(void)
  194. {
  195.         CPTR rastport=regs.a[1];
  196.         WORD x=regs.d[0];
  197.         WORD y=regs.d[1];
  198.         /* Set new coordinate */
  199.         wordput(rastport+36,x);
  200.         wordput(rastport+38,y);
  201.         /* Set Linepatcnt */
  202.         byteput(rastport+30,0x0f);
  203.         return(0);
  204. }  
  205.  
  206.  
  207. /*
  208.  *  Initialisation  (called by AMIGA-OS !)
  209.  */
  210. static ULONG gfxlib_init(void)
  211. {
  212.         CPTR gfxbase;
  213.         CPTR sysbase=regs.a[6]; 
  214.         int i=0;
  215.  
  216.          /* Install new routines */
  217.      /* We have to call SetFunction here instead of writing direktly into the GfxBase,
  218.         because of the library checksum ! */
  219.  
  220.         regs.d[0]=0;
  221.         regs.a[1]=gfxlibname;
  222.         gfxbase=CallLib(sysbase, -408);  /* OpenLibrary */
  223.  
  224.         regs.a[1]=gfxbase;
  225.         regs.a[0]=-240;
  226.         regs.d[0]=Move;
  227.         CallLib(sysbase, -420);  /* SetFunction */
  228.  
  229.         regs.a[1]=gfxbase;
  230.         regs.a[0]=-324;
  231.         regs.d[0]=WritePixel;
  232.         CallLib(sysbase, -420);
  233.  
  234.         regs.a[1]=gfxbase;
  235.         regs.a[0]=-300;
  236.         regs.d[0]=BltClear;
  237.         CallLib(sysbase, -420);
  238.  
  239.         regs.a[1]=gfxbase;
  240.         regs.a[0]=-234;
  241.         regs.d[0]=SetRast;
  242.         CallLib(sysbase, -420);
  243.  
  244.         regs.a[0]=-318;
  245.         regs.d[0]=ReadPixel;
  246.         CallLib(sysbase,-420);
  247.  
  248.         return 0;
  249. }
  250.  
  251. /* 
  252.  *  Install the gfx-library-replacement 
  253.  */
  254. void gfxlib_install(void)
  255. {
  256.         ULONG begin, end, resname, resid;
  257.         int i;
  258.  
  259.         if(!use_gfxlib) return;
  260.     
  261.         fprintf(stderr, "Warning: you enabled the graphics.library replacement with -g\n"
  262.         "This may be buggy right now, and will not speed things up much.\n");
  263.  
  264.         resname = ds("UAEgfxlib.resource");
  265.         resid = ds("UAE gfxlib 0.1");
  266.  
  267.         gfxlibname = ds("graphics.library");
  268.  
  269.         begin = here();
  270.         dw(0x4AFC);             /* RTC_MATCHWORD */
  271.         dl(begin);              /* our start address */
  272.         dl(0);                  /* Continue scan here */
  273.         dw(0x0101);             /* RTF_COLDSTART; Version 1 */
  274.         dw(0x0805);             /* NT_RESOURCE; pri 5 */
  275.         dl(resname);            /* name */
  276.         dl(resid);              /* ID */
  277.         dl(here() + 4);         /* Init area: directly after this */
  278.  
  279.         calltrap(deftrap(gfxlib_init)); dw(RTS);
  280.  
  281.         /* start of code */
  282.  
  283.         Move=here();
  284.         calltrap(deftrap(gfxl_Move));
  285.         dw(RTS);
  286.  
  287.         WritePixel=here();
  288.         calltrap(deftrap(gfxl_WritePixel));
  289.         dw(RTS);
  290.  
  291.         ReadPixel=here();
  292.         calltrap(deftrap(gfxl_ReadPixel));
  293.         dw(RTS); 
  294.  
  295.         SetRast=here();
  296.         calltrap(deftrap(gfxl_SetRast));
  297.         dw(RTS); 
  298.  
  299.         BltClear=here();
  300.         calltrap(deftrap(gfxl_BltClear));
  301.         dw(RTS);
  302.  
  303.         end = here();
  304.         org(begin + 6);
  305.         dl(end);
  306.  
  307.         org(end);
  308. }
  309.