/* Copyright (C) 1998 BJ Eirich (aka vecna) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public Lic See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include "verge.h" // ================================= Data ==================================== byte *vesascreen, *vesascreenx; // virscr | realscr // ================================= Code ==================================== void VESASetMode(int mode) { REGISTERS r; SET_AX(r, mode); INTERRUPT(0x10, r); } int VESAShutdown(void) { VESASetMode(0x3); free(vesascreen); return 0; } void VESASetBank(int bank) { REGISTERS r; SET_AX(r, 0x4f05); SET_BX(r, 0); SET_DX(r, bank); INTERRUPT(0x10, r); } int VESAShowPage(void) { byte *s,*d; int y,bytes,bank; int span; RenderGUI(); cpubyte=PFLIP; s=vesascreen+(16*tsx)+16; d=vesascreenx; bank=0; bytes=65536; VESASetBank(bank++); for (y=sy; y; y--) { if (bytes >= sx) { memcpy(d,s,sx); bytes-=sx; s+=sx; d+=sx; } else { memcpy(d,s,bytes); s+=bytes; span=sx-bytes; VESASetBank(bank++); d=vesascreenx; bytes=65536; memcpy(d,s,span); bytes-=span; s+=span; d+=span; } s+=32; } cpubyte=ETC; return 0; } int VESACopySprite(int x, int y, int width, int height, byte *src) { cpubyte=RENDER; asm("movl %3, %%edx \n\t" "movl %4, %%esi \n\t" "csl0: \n\t" "movl %1, %%eax \n\t" "imul $672, %%eax \n\t" "addl %0, %%eax \n\t" "addl _vesascreen, %%eax \n\t" "movl %%eax, %%edi \n\t" "movl %2, %%ecx \n\t" "shrl $2, %%ecx \n\t" "repz \n\t" "movsl \n\t" "incl %1 \n\t" "decl %%edx \n\t" "jnz csl0 \n\t" : : "m" (x), "m" (y), "m" (width), "m" (height), "m" (src) : "eax","edx","esi","edi","ecx","cc" ); cpubyte=ETC; return 0; } int VESACCopySprite(int x,int y,int width,int height,byte *src) { byte *s,*d; int xl,yl,xs,ys; int cx1=0, cy1=0, cx2=tsx-1, cy2=tsy-1; cpubyte=RENDER; xl=width; yl=height; xs=ys=0; if (x>cx2 || y>cy2 || x+xl cx2) xl=cx2-x+1; if (y+yl > cy2) yl=cy2-y+1; if (xcx2 || y>cy2 || x+xl cx2) xl=cx2-x+1; if (y+yl > cy2) yl=cy2-y+1; if (x0 && th>0) dys=tsx-xm; else if (tw>0 && th<0) dys=(0-tsx)-xm; else if (tw<0 && th>0) dys=tsx+xm; else if (tw<0 && th<0) dys=(0-tsx)+xm; d = vesascreen+(y*tsx)+x; for (i=0;i>16)]; d+=xd; sx+=xs; } d+=dys; sy+=ys; s+=(sy>>16)*w; sy&=0xffff; } cpubyte=ETC; return 0; } int VESARenderMAPLine(int x, int y, int yofs, word *map) { cpubyte=RENDER; // ... cpubyte=ETC; return 0; } int VESATRenderMAPLine(int x, int y, int yofs, word *map) { cpubyte=RENDER; // ... cpubyte=ETC; return 0; } int VESAColorField(int x, int y, byte c) { cpubyte=RENDER; // ... cpubyte=ETC; return 0; } int VESAClearScreen() { cpubyte=RENDER; memset(vesascreen+(672*16)+16,0,(672*480)); cpubyte=ETC; return 0; } int VESAPutPixel(int x, int y, int color) { cpubyte=RENDER; if (xcx2 || y>cy2) { cpubyte=ETC; return 0; } x+=16; y+=16; vesascreen[(y*tsx)+x]=color; cpubyte=ETC; return 0; } int VESAGetPixel(int x, int y) { cpubyte=RENDER; if (xcx2 || y>cy2) { cpubyte=ETC; return 0; } x+=16; y+=16; cpubyte=ETC; return vesascreen[(y*tsx)+x]; return 0; } int VESAHLine(int x, int y, int x2, int color) { byte *d; int width; cpubyte=RENDER; // swap? if (x2cx2 || y>cy2 || x+width cx2) width=cx2-x+1; if (xcx2 || y>cy2 || x cy2) height=cy2-y+1; if (ycx2 && x2>cx2) || (y1cy2 && y2>cy2)) { cpubyte=ETC; return 0; } if (x1>x2) { i=x1; x1=x2; x2=i; i=y1; y1=y2; y2=i; } // clip the left side if (x1cx2) { int myy=(y2-y1); int mxx=(x2-x1),b; if (!mxx) { cpubyte=ETC; return 0; } if (myy) { b=y1-(y2-y1)*x1/mxx; y2=myy*cx2/mxx+b; x2=cx2; } else x2=cx2; } if (y1>y2) { i=x1; x1=x2; x2=i; i=y1; y1=y2; y2=i; } // clip the bottom if (y2>cy2) { int mxx=(x2-x1); int myy=(y2-y1),b; if (!myy) { cpubyte=ETC; return 0; } if (mxx) { b=y1-(y2-y1)*x1/mxx; x2=(cy2-b)*mxx/myy; y2=cy2; } else y2=cy2; } // clip the top if (y1cx2 || x2>cx2 || y1cy2 || y2>cy2) { cpubyte=ETC; return 0; } if (x1>x2) { xc=x2; xi=x1; } else { xi=x2; xc=x1; } x1+=16;y1+=16; // aen; adjust these here?? x2+=16;y2+=16; // assume y1<=y2 from above swap operation yi=y2; yc=y1; dcx=x1; dcy=y1; xc=(x2-x1); yc=(y2-y1); if (xc<0) xi=-1; else xi=1; if (yc<0) yi=-1; else yi=1; n=abs(xc); m=abs(yc); ycyi=abs(2*yc*xi); er=0; if (n>m) { xcxi=abs(2*xc*xi); for (i=0;i<=n;i++) { vesascreen[(dcy*tsx)+dcx]=color; if (er>0) { dcy+=yi; er-=xcxi; } er+=ycyi; dcx+=xi; } } else { xcyi=abs(2*xc*yi); for (i=0;i<=m;i++) { vesascreen[(dcy*tsx)+dcx]=color; if (er>0) { dcx+=xi; er-=ycyi; } er+=xcyi; dcy+=yi; } } cpubyte=ETC; return 0; } int VESACircle(int x, int y, int radius, int color) { int cx=0; int cy=radius; int df=1-radius; int d_e=3; int d_se=-2*radius+5; cpubyte=RENDER; do { VESAPutPixel(x+cx,y+cy,color); if (cx) VESAPutPixel(x-cx,y+cy,color); if (cy) VESAPutPixel(x+cx,y-cy,color); if ((cx) && (cy)) VESAPutPixel(x-cx,y-cy,color); if (cx != cy) { VESAPutPixel(x+cy,y+cx,color); if (cx) VESAPutPixel(x+cy,y-cx,color); if (cy) VESAPutPixel(x-cy,y+cx,color); if (cx && cy) VESAPutPixel(x-cy,y-cx,color); } if (df<0) { df+=d_e; d_e+=2; d_se+=2; } else { df+=d_se; d_e+=2; d_se+=4; cy--; } cx++; } while (cx <= cy); cpubyte=ETC; return 0; } int VESACircleFill(int x, int y, int radius, int color) { int cx=0; int cy=radius; int df=1-radius; int d_e=3; int d_se=-2*radius+5; cpubyte=RENDER; do { VESAHLine(x-cy,y-cx,x+cy,color); if (cx) VESAHLine(x-cy,y+cx,x+cy,color); if (df<0) { df+=d_e; d_e+=2; d_se+=2; } else { if (cx != cy) { VESAHLine(x-cx,y-cy,x+cx,color); if (cy) VESAHLine(x-cx,y+cy,x+cx,color); } df+=d_se; d_e+=2; d_se+=4; cy--; } cx++; } while (cx <= cy); cpubyte=ETC; return 0; } int VESARect(int x, int y, int x2, int y2, int color) { VESAHLine(x,y,x2,color); VESAHLine(x,y2,x2,color); VESAVLine(x,y+1,y2-1,color); VESAVLine(x2,y+1,y2-1,color); return 0; } int VESARectFill(int x, int y, int x2, int y2, int color) { cpubyte=RENDER; if (y2