2 Copyright (C) 1998 BJ Eirich (aka vecna)
\r
3 This program is free software; you can redistribute it and/or
\r
4 modify it under the terms of the GNU General Public License
\r
5 as published by the Free Software Foundation; either version 2
\r
6 of the License, or (at your option) any later version.
\r
7 This program is distributed in the hope that it will be useful,
\r
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
\r
10 See the GNU General Public Lic
\r
11 See the GNU General Public License for more details.
\r
12 You should have received a copy of the GNU General Public License
\r
13 along with this program; if not, write to the Free Software
\r
14 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
\r
22 #include <sys\nearptr.h>
\r
25 // ================================= Data ====================================
\r
27 byte *vesascreen, *vesascreenx; // virscr | realscr
\r
29 // ================================= Code ====================================
\r
31 void VESASetMode(int mode)
\r
38 int VESAShutdown(void)
\r
45 void VESASetBank(int bank)
\r
54 int VESAShowPage(void)
\r
62 s=vesascreen+(16*tsx)+16;
\r
67 VESASetBank(bank++);
\r
78 { memcpy(d,s,bytes);
\r
82 VESASetBank(bank++);
\r
98 int VESACopySprite(int x, int y, int width, int height, byte *src)
\r
102 asm("movl %3, %%edx \n\t"
\r
103 "movl %4, %%esi \n\t"
\r
105 "movl %1, %%eax \n\t"
\r
106 "imul $672, %%eax \n\t"
\r
107 "addl %0, %%eax \n\t"
\r
108 "addl _vesascreen, %%eax \n\t"
\r
109 "movl %%eax, %%edi \n\t"
\r
110 "movl %2, %%ecx \n\t"
\r
111 "shrl $2, %%ecx \n\t"
\r
118 : "m" (x), "m" (y), "m" (width), "m" (height), "m" (src)
\r
119 : "eax","edx","esi","edi","ecx","cc" );
\r
124 int VESACCopySprite(int x,int y,int width,int height,byte *src)
\r
128 int cx1=0, cy1=0, cx2=tsx-1, cy2=tsy-1;
\r
136 if (x>cx2 || y>cy2 || x+xl<cx1 || y+yl<cy1)
\r
139 if (x+xl > cx2) xl=cx2-x+1;
\r
140 if (y+yl > cy2) yl=cy2-y+1;
\r
142 if (x<cx1) { xs=cx1-x; xl-=xs; x=cx1; }
\r
143 if (y<cy1) { ys=cy1-y; yl-=ys; y=cy1; }
\r
146 if (xs+ys) s+=(ys*width)+xs;
\r
147 d=vesascreen+(y*tsx)+x;
\r
160 int VESATCCopySprite(int x,int y,int width,int height,byte *src)
\r
164 int cx1=0, cy1=0, cx2=tsx-1, cy2=tsy-1;
\r
172 if (x>cx2 || y>cy2 || x+xl<cx1 || y+yl<cy1)
\r
175 if (x+xl > cx2) xl=cx2-x+1;
\r
176 if (y+yl > cy2) yl=cy2-y+1;
\r
178 if (x<cx1) { xs=cx1-x; xl-=xs; x=cx1; }
\r
179 if (y<cy1) { ys=cy1-y; yl-=ys; y=cy1; }
\r
182 if (xs+ys) s+=(ys*width)+xs;
\r
183 d=vesascreen+(y*tsx)+x;
\r
187 for (x=0; x<xl; x++)
\r
201 int VESACopyTile(int x, int y, byte *spr)
\r
210 d=vesascreen+(y*tsx)+x;
\r
213 memcpy(d, spr, 16);
\r
222 int VESATCopySprite(int x, int y, int width, int height, byte *src)
\r
226 asm("movl %3, %%ecx \n\t"
\r
227 "movl %4, %%esi \n\t"
\r
229 "movl %1, %%eax \n\t"
\r
230 "imul $672, %%eax \n\t"
\r
231 "addl %0, %%eax \n\t"
\r
232 "addl _vesascreen, %%eax \n\t"
\r
233 "movl %%eax, %%edi \n\t"
\r
234 "movl %2, %%edx \n\t"
\r
237 "orb %%al, %%al \n\t"
\r
242 "jmp drawloop \n\t"
\r
246 "jnz drawloop \n\t"
\r
252 : "m" (x), "m" (y), "m" (width), "m" (height), "m" (src)
\r
253 : "eax","edx","esi","edi","ecx","cc" );
\r
259 int VESATCopyTile(int x, int y, byte *spr, byte *matte)
\r
262 asm("movl $16, %%ecx \n\t"
\r
263 "movl %2, %%esi \n\t"
\r
264 "movl %1, %%edi \n\t"
\r
265 "imul $672, %%edi \n\t"
\r
266 "addl %0, %%edi \n\t"
\r
267 "addl _vesascreen, %%edi \n\t"
\r
268 "movl %3, %%edx \n\t"
\r
270 "movl (%%edi), %%eax \n\t"
\r
271 "andl (%%edx), %%eax \n\t"
\r
272 "orl (%%esi), %%eax \n\t"
\r
273 "movl %%eax, (%%edi) \n\t"
\r
274 "movl 4(%%edi), %%eax \n\t"
\r
275 "andl 4(%%edx), %%eax \n\t"
\r
276 "orl 4(%%esi), %%eax \n\t"
\r
277 "movl %%eax, 4(%%edi) \n\t"
\r
278 "movl 8(%%edi), %%eax \n\t"
\r
279 "andl 8(%%edx), %%eax \n\t"
\r
280 "orl 8(%%esi), %%eax \n\t"
\r
281 "movl %%eax, 8(%%edi) \n\t"
\r
282 "movl 12(%%edi), %%eax \n\t"
\r
283 "andl 12(%%edx), %%eax \n\t"
\r
284 "orl 12(%%esi), %%eax \n\t"
\r
285 "movl %%eax, 12(%%edi) \n\t"
\r
286 "addl $16, %%esi \n\t"
\r
287 "addl $672, %%edi \n\t"
\r
288 "addl $16, %%edx \n\t"
\r
292 : "m" (x), "m" (y), "m" (spr), "m" (matte)
\r
293 : "eax","ecx","edx","esi","edi","cc" );
\r
299 int VESAScaleSprite(int x, int y, int w, int h, int tw, int th, byte *s)
\r
301 int i,j,xm,ym,xd,yd,sx,sy=0,xs,ys,dys=0;
\r
306 if (!tw || !th) return 0;
\r
307 tw += sgn(tw); th += sgn(th);
\r
308 xm = abs(tw); ym = abs(th);
\r
309 xs = (w<<16)/xm; ys = (h<<16)/ym;
\r
310 xd = sgn(tw); yd = sgn(th);
\r
312 if (tw>0 && th>0) dys=tsx-xm;
\r
313 else if (tw>0 && th<0) dys=(0-tsx)-xm;
\r
314 else if (tw<0 && th>0) dys=tsx+xm;
\r
315 else if (tw<0 && th<0) dys=(0-tsx)+xm;
\r
317 d = vesascreen+(y*tsx)+x;
\r
318 for (i=0;i<ym;++i) {
\r
320 for (j=0;j<xm;++j) {
\r
334 int VESARenderMAPLine(int x, int y, int yofs, word *map)
\r
342 int VESATRenderMAPLine(int x, int y, int yofs, word *map)
\r
350 int VESAColorField(int x, int y, byte c)
\r
358 int VESAClearScreen()
\r
361 memset(vesascreen+(672*16)+16,0,(672*480));
\r
366 int VESAPutPixel(int x, int y, int color)
\r
370 if (x<cx1 || y<cy1 || x>cx2 || y>cy2)
\r
379 vesascreen[(y*tsx)+x]=color;
\r
385 int VESAGetPixel(int x, int y)
\r
389 if (x<cx1 || y<cy1 || x>cx2 || y>cy2)
\r
399 return vesascreen[(y*tsx)+x];
\r
403 int VESAHLine(int x, int y, int x2, int color)
\r
411 if (x2<x) { int t=x2; x=x2; x2=t; }
\r
414 if (x>cx2 || y>cy2 || x+width<cx1 || y<cy1)
\r
417 if (x+width > cx2) width=cx2-x+1;
\r
418 if (x<cx1) { width-=(cx1-x); x=cx1; }
\r
424 d=vesascreen+(y*tsx)+x;
\r
425 memset(d,color,width);
\r
431 int VESAVLine(int x, int y, int y2, int color)
\r
439 if (y2<y) { int t=y2; x=y2; y2=t; }
\r
442 if (x>cx2 || y>cy2 || x<cx1 || y+height<cy1)
\r
448 if (y+height > cy2) height=cy2-y+1;
\r
449 if (y<cy1) { height-=(cy1-y); y=cy1; }
\r
455 d=vesascreen+(y*tsx)+x;
\r
456 for (; height; height--)
\r
466 int VESALine(int x1, int y1, int x2, int y2, int color)
\r
468 short i,xc,yc,er,n,m,xi,yi,xcxi,ycyi,xcyi;
\r
473 // check to see if the line is completly clipped off
\r
474 if ((x1<cx1 && x2<cx1) || (x1>cx2 && x2>cx2)
\r
475 || (y1<cy1 && y2<cy1) || (y1>cy2 && y2>cy2))
\r
487 // clip the left side
\r
498 b=y1-(y2-y1)*x1/mxx;
\r
505 // clip the right side
\r
516 b=y1-(y2-y1)*x1/mxx;
\r
540 b=y1-(y2-y1)*x1/mxx;
\r
541 x2=(cy2-b)*mxx/myy;
\r
558 b=y1-(y2-y1)*x1/mxx;
\r
559 x1=(cy1-b)*mxx/myy;
\r
566 // see if it got cliped into the box, out out
\r
567 if (x1<cx1 || x2<cx1 || x1>cx2 || x2>cx2 || y1<cy1 || y2 <cy1 || y1>cy2 || y2>cy2)
\r
575 else { xi=x2; xc=x1; }
\r
577 x1+=16;y1+=16; // aen; adjust these here??
\r
580 // assume y1<=y2 from above swap operation
\r
584 xc=(x2-x1); yc=(y2-y1);
\r
585 if (xc<0) xi=-1; else xi=1;
\r
586 if (yc<0) yi=-1; else yi=1;
\r
587 n=abs(xc); m=abs(yc);
\r
596 vesascreen[(dcy*tsx)+dcx]=color;
\r
610 vesascreen[(dcy*tsx)+dcx]=color;
\r
624 int VESACircle(int x, int y, int radius, int color)
\r
630 int d_se=-2*radius+5;
\r
635 VESAPutPixel(x+cx,y+cy,color);
\r
636 if (cx) VESAPutPixel(x-cx,y+cy,color);
\r
637 if (cy) VESAPutPixel(x+cx,y-cy,color);
\r
638 if ((cx) && (cy)) VESAPutPixel(x-cx,y-cy,color);
\r
642 VESAPutPixel(x+cy,y+cx,color);
\r
643 if (cx) VESAPutPixel(x+cy,y-cx,color);
\r
644 if (cy) VESAPutPixel(x-cy,y+cx,color);
\r
645 if (cx && cy) VESAPutPixel(x-cy,y-cx,color);
\r
664 } while (cx <= cy);
\r
670 int VESACircleFill(int x, int y, int radius, int color)
\r
676 int d_se=-2*radius+5;
\r
681 VESAHLine(x-cy,y-cx,x+cy,color);
\r
682 if (cx) VESAHLine(x-cy,y+cx,x+cy,color);
\r
694 VESAHLine(x-cx,y-cy,x+cx,color);
\r
695 if (cy) VESAHLine(x-cx,y+cy,x+cx,color);
\r
706 } while (cx <= cy);
\r
712 int VESARect(int x, int y, int x2, int y2, int color)
\r
714 VESAHLine(x,y,x2,color);
\r
715 VESAHLine(x,y2,x2,color);
\r
716 VESAVLine(x,y+1,y2-1,color);
\r
717 VESAVLine(x2,y+1,y2-1,color);
\r
721 int VESARectFill(int x, int y, int x2, int y2, int color)
\r
725 if (y2<y) { int t=y2; y=y2; y2=t; }
\r
728 VESAHLine(x,y,x2,color);
\r
734 void InitVESA(void)
\r
740 INTERRUPT(0x10, r);
\r
742 vesascreenx = (byte *) 0xA0000 + __djgpp_conventional_base;
\r
743 vesascreen = (byte *) valloc(344064, "vesascreen", 0);
\r
744 memset(vesascreen, 0, 344064);
\r
752 // Mode successfuly set, now lets set up the driver.
\r
753 ShutdownVideo = VESAShutdown;
\r
754 ShowPage = VESAShowPage;
\r
755 CopySprite = VESACopySprite;
\r
756 TCopySprite = VESATCopySprite;
\r
757 CCopySprite = VESACCopySprite;
\r
758 TCCopySprite = VESATCCopySprite;
\r
759 CopyTile = VESACopyTile;
\r
760 TCopyTile = VESATCopyTile;
\r
761 ScaleSprite = VESAScaleSprite;
\r
762 RenderMAPLine = VESARenderMAPLine;
\r
763 TRenderMAPLine = VESATRenderMAPLine;
\r
764 ColorField = VESAColorField;
\r
765 ClearScreen = VESAClearScreen;
\r
766 PutPixel = VESAPutPixel;
\r
767 GetPixel = VESAGetPixel;
\r
771 Circle = VESACircle;
\r
772 CircleFill = VESACircleFill;
\r
774 RectFill = VESARectFill;
\r
775 DriverDesc = "640x480 (VESA, Banked)";
\r