File:  [UNIX Amiga Emulator] / uae / gfxlib.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 16:38:19 2018 UTC (8 years, 3 months ago) by root
Branches: MAIN, BSchmidt
CVS tags: uae060, HEAD
uae-0.6.0

 /*
  * UAE - The Un*x Amiga Emulator
  *
  *   Graphics.library replacement
  *
  *   (c) 1996 by Christian Schmitt   <[email protected]>
  *
  *   (c) 1996 by Markus Gietzen
  *
  */

#include "sysconfig.h"
#include "sysdeps.h"

#include <assert.h>

#include "config.h"
#include "options.h"
#include "events.h"
#include "memory.h"
#include "custom.h"
#include "newcpu.h"
#include "xwin.h"
#include "autoconf.h"
#include "filesys.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);
}

unix.superglobalmegacorp.com

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