1 /* Catacomb Armageddon Source Code
\r
2 * Copyright (C) 1993-2014 Flat Rock Software
\r
4 * This program is free software; you can redistribute it and/or modify
\r
5 * it under the terms of the GNU General Public License as published by
\r
6 * the Free Software Foundation; either version 2 of the License, or
\r
7 * (at your option) any later version.
\r
9 * This program is distributed in the hope that it will be useful,
\r
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
12 * GNU General Public License for more details.
\r
14 * You should have received a copy of the GNU General Public License along
\r
15 * with this program; if not, write to the Free Software Foundation, Inc.,
\r
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
\r
21 #include "ID_HEADS.H"
\r
24 =============================================================================
\r
28 =============================================================================
\r
31 #define VIEWWIDTH 40
\r
33 #define PIXTOBLOCK 4 // 16 pixels to an update block
\r
36 =============================================================================
\r
40 =============================================================================
\r
43 cardtype videocard; // set by VW_Startup
\r
44 grtype grmode; // CGAgr, EGAgr, VGAgr
\r
46 unsigned bufferofs; // hidden area to draw to before displaying
\r
47 unsigned displayofs; // origin of the visable screen
\r
48 unsigned panx,pany; // panning adjustments inside port in pixels
\r
49 unsigned pansx,pansy; // panning adjustments inside port in screen
\r
50 // block limited pixel values (ie 0/8 for ega x)
\r
51 unsigned panadjust; // panx/pany adjusted by screen resolution
\r
53 unsigned screenseg; // normally 0xa000 / 0xb800
\r
55 unsigned ylookup[VIRTUALHEIGHT];
\r
57 unsigned fontnumber; // 0 based font number for drawing
\r
59 boolean screenfaded;
\r
61 pictabletype _seg *pictable;
\r
62 pictabletype _seg *picmtable;
\r
63 spritetabletype _seg *spritetable;
\r
68 =============================================================================
\r
72 =============================================================================
\r
75 void VWL_MeasureString (char far *string, word *width, word *height,
\r
76 fontstruct _seg *font);
\r
77 void VWL_DrawCursor (void);
\r
78 void VWL_EraseCursor (void);
\r
79 void VWL_DBSetup (void);
\r
80 void VWL_UpdateScreenBlocks (void);
\r
85 int cursornumber,cursorwidth,cursorheight,cursorx,cursory;
\r
87 unsigned cursorspot;
\r
89 //===========================================================================
\r
93 =======================
\r
97 =======================
\r
100 static char *ParmStrings[] = {"HIDDENCARD",""};
\r
102 void VW_Startup (void)
\r
110 for (i = 1;i < _argc;i++)
\r
111 if (US_CheckParm(_argv[i],ParmStrings) == 0)
\r
113 videocard = EGAcard;
\r
118 videocard = VW_VideoID ();
\r
120 #if GRMODE == EGAGR
\r
122 if (videocard != EGAcard && videocard != VGAcard)
\r
123 Quit ("Improper video card! If you really have an EGA/VGA card that I am not \n"
\r
124 "detecting, use the -HIDDENCARD command line parameter!");
\r
128 #if GRMODE == CGAGR
\r
130 if (videocard < CGAcard || videocard > VGAcard)
\r
131 Quit ("Improper video card! If you really have a CGA card that I am not \n"
\r
132 "detecting, use the -HIDDENCARD command line parameter!");
\r
133 MM_GetPtr (&(memptr)screenseg,0x10000l); // grab 64k for floating screen
\r
139 //===========================================================================
\r
142 =======================
\r
146 =======================
\r
149 void VW_Shutdown (void)
\r
151 VW_SetScreenMode (TEXTGR);
\r
152 #if GRMODE == EGAGR
\r
153 VW_SetLineWidth (80);
\r
157 //===========================================================================
\r
160 ========================
\r
163 = Call BIOS to set TEXT / CGAgr / EGAgr / VGAgr
\r
165 ========================
\r
168 void VW_SetScreenMode (int grmode)
\r
172 case TEXTGR: _AX = 3;
\r
173 geninterrupt (0x10);
\r
176 case CGAGR: _AX = 4;
\r
177 geninterrupt (0x10); // screenseg is actually a main mem buffer
\r
180 case EGA320GR: // MDM start (GAMERS EDGE)
\r
184 geninterrupt (0x10);
\r
192 geninterrupt (0x10);
\r
194 break; // MDM end (GAMERS EDGE)
\r
196 case EGAGR: _AX = 0xd;
\r
199 geninterrupt (0x10);
\r
204 char extern VGAPAL; // deluxepaint vga pallet .OBJ file
\r
205 void far *vgapal = &VGAPAL;
\r
206 SetCool256 (); // custom 256 color mode
\r
208 _ES = FP_SEG(vgapal);
\r
209 _DX = FP_OFF(vgapal);
\r
213 geninterrupt(0x10); // set the deluxepaint pallet
\r
218 VW_SetLineWidth(SCREENWIDTH);
\r
222 =============================================================================
\r
226 =============================================================================
\r
229 char colors[7][17]=
\r
230 {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
\r
231 {0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,0},
\r
232 {0,0,0,0,0,0,0,0,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0},
\r
233 {0,1,2,3,4,5,6,7,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0},
\r
234 {0,1,2,3,4,5,6,7,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0},
\r
235 {0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f}};
\r
238 void VW_ColorBorder (int color)
\r
243 geninterrupt (0x10);
\r
244 bordercolor = color;
\r
247 void VW_SetPalette(byte *palette)
\r
252 for (i = 0;i < 15;i++)
\r
256 colors[1][i] = (p > 0x10)? (p & 0x0f) : 0;
\r
257 colors[2][i] = (p > 0x10)? p : 0;
\r
259 colors[4][i] = (p > 0x10)? 0x1f : p;
\r
260 colors[5][i] = 0x1f;
\r
264 void VW_SetDefaultColors(void)
\r
266 #if GRMODE == EGAGR
\r
267 colors[3][16] = bordercolor;
\r
268 _ES=FP_SEG(&colors[3]);
\r
269 _DX=FP_OFF(&colors[3]);
\r
271 geninterrupt(0x10);
\r
272 screenfaded = false;
\r
277 void VW_FadeOut(void)
\r
279 #if GRMODE == EGAGR
\r
284 colors[i][16] = bordercolor;
\r
285 _ES=FP_SEG(&colors[i]);
\r
286 _DX=FP_OFF(&colors[i]);
\r
288 geninterrupt(0x10);
\r
291 screenfaded = true;
\r
296 void VW_FadeIn(void)
\r
298 #if GRMODE == EGAGR
\r
303 colors[i][16] = bordercolor;
\r
304 _ES=FP_SEG(&colors[i]);
\r
305 _DX=FP_OFF(&colors[i]);
\r
307 geninterrupt(0x10);
\r
310 screenfaded = false;
\r
314 void VW_FadeUp(void)
\r
316 #if GRMODE == EGAGR
\r
321 colors[i][16] = bordercolor;
\r
322 _ES=FP_SEG(&colors[i]);
\r
323 _DX=FP_OFF(&colors[i]);
\r
325 geninterrupt(0x10);
\r
328 screenfaded = true;
\r
332 void VW_FadeDown(void)
\r
334 #if GRMODE == EGAGR
\r
339 colors[i][16] = bordercolor;
\r
340 _ES=FP_SEG(&colors[i]);
\r
341 _DX=FP_OFF(&colors[i]);
\r
343 geninterrupt(0x10);
\r
346 screenfaded = false;
\r
352 ========================
\r
356 = Sets an attribute (pallete / border) register
\r
359 ========================
\r
362 void VW_SetAtrReg (int reg, int value)
\r
365 asm mov dx,STATUS_REGISTER_1
\r
367 asm mov dx,ATR_INDEX
\r
369 asm mov al,BYTE PTR [reg]
\r
371 asm mov al,BYTE PTR [value]
\r
375 asm mov dx,ATR_INDEX
\r
383 //===========================================================================
\r
386 ====================
\r
390 = Must be an even number of bytes
\r
392 ====================
\r
395 void VW_SetLineWidth (int width)
\r
399 #if GRMODE == EGAGR
\r
401 // set wide virtual screen
\r
403 asm mov dx,CRTC_INDEX
\r
404 asm mov al,CRTC_OFFSET
\r
405 asm mov ah,[BYTE PTR width]
\r
411 // set up lookup tables
\r
417 for (i=0;i<VIRTUALHEIGHT;i++)
\r
425 //===========================================================================
\r
428 ====================
\r
430 = VW_SetSplitScreen
\r
432 ====================
\r
435 void VW_SetSplitScreen (int linenum)
\r
438 if (videocard==VGAcard)
\r
439 linenum=linenum*2-1;
\r
440 outportb (CRTC_INDEX,CRTC_LINECOMPARE);
\r
441 outportb (CRTC_INDEX+1,linenum % 256);
\r
442 outportb (CRTC_INDEX,CRTC_OVERFLOW);
\r
443 outportb (CRTC_INDEX+1, 1+16*(linenum/256));
\r
444 if (videocard==VGAcard)
\r
446 outportb (CRTC_INDEX,CRTC_MAXSCANLINE);
\r
447 outportb (CRTC_INDEX+1,inportb(CRTC_INDEX+1) & (255-64));
\r
451 //===========================================================================
\r
454 ====================
\r
458 ====================
\r
461 void VW_ClearVideo (int color)
\r
463 #if GRMODE == EGAGR
\r
468 asm mov es,[screenseg]
\r
471 asm mov al,[BYTE PTR color]
\r
475 #if GRMODE == EGAGR
\r
480 //===========================================================================
\r
485 ====================
\r
489 = X in bytes, y in pixels, chunknum is the #defined picnum
\r
491 ====================
\r
494 void VW_DrawPic(unsigned x, unsigned y, unsigned chunknum)
\r
496 int picnum = chunknum - STARTPICS;
\r
498 unsigned dest,width,height;
\r
500 source = grsegs[chunknum];
\r
501 dest = ylookup[y]+x+bufferofs;
\r
502 width = pictable[picnum].width;
\r
503 height = pictable[picnum].height;
\r
505 VW_MemToScreen(source,dest,width,height);
\r
509 // MDM (GAMERS EDGE) begin
\r
511 ====================
\r
513 = VW_DrawPic2x - Same as VW_DrawPic, but doubles pixels horizontally
\r
514 = (Great for drawing 320 graphics on 640 screen!)
\r
516 = X in bytes, y in pixels, chunknum is the #defined picnum
\r
518 ====================
\r
521 void VW_DrawPic2x(unsigned x, unsigned y, unsigned chunknum)
\r
523 int picnum = chunknum - STARTPICS;
\r
525 unsigned dest,width,height;
\r
527 source = grsegs[chunknum];
\r
528 dest = ylookup[y]+x+bufferofs;
\r
529 width = pictable[picnum].width;
\r
530 height = pictable[picnum].height;
\r
532 VW_MemToScreen2x(source,dest,width,height);
\r
534 // MDM (GAMERS EDGE) end
\r
541 ====================
\r
545 = X in bytes, y in pixels, chunknum is the #defined picnum
\r
547 ====================
\r
550 void VW_DrawMPic(unsigned x, unsigned y, unsigned chunknum)
\r
552 int picnum = chunknum - STARTPICM;
\r
554 unsigned dest,width,height;
\r
556 source = grsegs[chunknum];
\r
557 dest = ylookup[y]+x+bufferofs;
\r
558 width = picmtable[picnum].width;
\r
559 height = picmtable[picnum].height;
\r
561 VW_MaskBlock(source,0,dest,width,height,width*height);
\r
564 void VW_ClipDrawMPic(unsigned x, int y, unsigned chunknum)
\r
566 int picnum = chunknum - STARTPICM;
\r
568 unsigned dest,width,ofs,plane;
\r
571 source = grsegs[chunknum];
\r
572 width = picmtable[picnum].width;
\r
573 height = picmtable[picnum].height;
\r
574 plane = width*height;
\r
583 else if (y+height>216)
\r
587 dest = ylookup[y]+x+bufferofs;
\r
591 VW_MaskBlock(source,ofs,dest,width,height,plane);
\r
597 //===========================================================================
\r
602 ====================
\r
606 = X and Y in pixels, it will match the closest shift possible
\r
609 = Add vertical clipping!
\r
610 = Make the shifts act as center points, rather than break points
\r
612 ====================
\r
615 void VW_DrawSprite(int x, int y, unsigned chunknum)
\r
617 spritetabletype far *spr;
\r
618 spritetype _seg *block;
\r
619 unsigned dest,shift;
\r
621 spr = &spritetable[chunknum-STARTSPRITES];
\r
622 block = (spritetype _seg *)grsegs[chunknum];
\r
624 y+=spr->orgy>>G_P_SHIFT;
\r
625 x+=spr->orgx>>G_P_SHIFT;
\r
627 #if GRMODE == EGAGR
\r
630 #if GRMODE == CGAGR
\r
634 dest = bufferofs + ylookup[y];
\r
636 dest += x/SCREENXDIV;
\r
638 dest += (x+1)/SCREENXDIV;
\r
640 VW_MaskBlock (block,block->sourceoffset[shift],dest,
\r
641 block->width[shift],spr->height,block->planesize[shift]);
\r
656 #if GRMODE == EGAGR
\r
658 unsigned char leftmask[8] = {0xff,0x7f,0x3f,0x1f,0xf,7,3,1};
\r
659 unsigned char rightmask[8] = {0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff};
\r
661 void VW_Hlin(unsigned xl, unsigned xh, unsigned y, unsigned color)
\r
663 unsigned dest,xlb,xhb,maskleft,maskright,mid;
\r
671 maskleft = leftmask[xl&7];
\r
672 maskright = rightmask[xh&7];
\r
675 dest = bufferofs+ylookup[y]+xlb;
\r
680 // entire line is in one byte
\r
683 maskleft&=maskright;
\r
685 asm mov es,[screenseg]
\r
688 asm mov dx,GC_INDEX
\r
689 asm mov al,GC_BITMASK
\r
690 asm mov ah,[BYTE PTR maskleft]
\r
691 asm out dx,ax // mask off pixels
\r
693 asm mov al,[BYTE PTR color]
\r
694 asm xchg al,[es:di] // load latches and write pixels
\r
699 asm mov es,[screenseg]
\r
701 asm mov dx,GC_INDEX
\r
702 asm mov bh,[BYTE PTR color]
\r
707 asm mov al,GC_BITMASK
\r
708 asm mov ah,[BYTE PTR maskleft]
\r
709 asm out dx,ax // mask off pixels
\r
712 asm mov bl,[es:di] // load latches
\r
718 asm mov ax,GC_BITMASK + 255*256
\r
719 asm out dx,ax // no masking
\r
728 asm mov al,GC_BITMASK
\r
729 asm mov ah,[BYTE PTR maskright]
\r
730 asm out dx,ax // mask off pixels
\r
732 asm xchg bh,[es:di] // load latches and write pixels
\r
741 #if GRMODE == CGAGR
\r
743 unsigned char pixmask[4] = {0xc0,0x30,0x0c,0x03};
\r
744 unsigned char leftmask[4] = {0xff,0x3f,0x0f,0x03};
\r
745 unsigned char rightmask[4] = {0xc0,0xf0,0xfc,0xff};
\r
746 unsigned char colorbyte[4] = {0,0x55,0xaa,0xff};
\r
749 // could be optimized for rep stosw
\r
751 void VW_Hlin(unsigned xl, unsigned xh, unsigned y, unsigned color)
\r
753 unsigned dest,xlb,xhb,mid;
\r
754 byte maskleft,maskright;
\r
756 color = colorbyte[color]; // expand 2 color bits to 8
\r
761 maskleft = leftmask[xl&3];
\r
762 maskright = rightmask[xh&3];
\r
765 dest = bufferofs+ylookup[y]+xlb;
\r
766 asm mov es,[screenseg]
\r
771 // entire line is in one byte
\r
773 maskleft&=maskright;
\r
775 asm mov ah,[maskleft]
\r
776 asm mov bl,[BYTE PTR color]
\r
777 asm and bl,[maskleft]
\r
783 asm and al,ah // mask out pixels
\r
784 asm or al,bl // or in color
\r
790 asm mov bh,[BYTE PTR color]
\r
795 asm mov ah,[maskleft]
\r
797 asm and bl,[maskleft]
\r
800 asm and al,ah // mask out pixels
\r
801 asm or al,bl // or in color
\r
814 asm mov ah,[maskright]
\r
816 asm and bl,[maskright]
\r
819 asm and al,ah // mask out pixels
\r
820 asm or al,bl // or in color
\r
831 = Pixel addressable block fill routine
\r
836 #if GRMODE == CGAGR
\r
838 void VW_Bar (unsigned x, unsigned y, unsigned width, unsigned height,
\r
841 unsigned xh = x+width-1;
\r
844 VW_Hlin (x,xh,y++,color);
\r
850 #if GRMODE == EGAGR
\r
852 void VW_Bar (unsigned x, unsigned y, unsigned width, unsigned height,
\r
855 unsigned dest,xh,xlb,xhb,maskleft,maskright,mid;
\r
864 maskleft = leftmask[x&7];
\r
865 maskright = rightmask[xh&7];
\r
868 dest = bufferofs+ylookup[y]+xlb;
\r
873 // entire line is in one byte
\r
876 maskleft&=maskright;
\r
878 asm mov es,[screenseg]
\r
881 asm mov dx,GC_INDEX
\r
882 asm mov al,GC_BITMASK
\r
883 asm mov ah,[BYTE PTR maskleft]
\r
884 asm out dx,ax // mask off pixels
\r
886 asm mov ah,[BYTE PTR color]
\r
887 asm mov dx,[linewidth]
\r
890 asm xchg al,[es:di] // load latches and write pixels
\r
891 asm add di,dx // down to next line
\r
898 asm mov es,[screenseg]
\r
900 asm mov bh,[BYTE PTR color]
\r
901 asm mov dx,GC_INDEX
\r
902 asm mov si,[linewidth]
\r
903 asm sub si,[mid] // add to di at end of line to get to next scan
\r
910 asm mov al,GC_BITMASK
\r
911 asm mov ah,[BYTE PTR maskleft]
\r
912 asm out dx,ax // mask off pixels
\r
915 asm mov bl,[es:di] // load latches
\r
921 asm mov ax,GC_BITMASK + 255*256
\r
922 asm out dx,ax // no masking
\r
931 asm mov al,GC_BITMASK
\r
932 asm mov ah,[BYTE PTR maskright]
\r
933 asm out dx,ax // mask off pixels
\r
936 asm xchg al,[es:di] // load latches and write pixels
\r
938 asm add di,si // move to start of next line
\r
949 //==========================================================================
\r
959 #if NUMFONT+NUMFONTM>0
\r
961 VWL_MeasureString (char far *string, word *width, word *height, fontstruct _seg *font)
\r
963 *height = font->height-1; // MDM (GAMERS EDGE) - squeeze font vertically...
\r
964 for (*width = 0;*string;string++)
\r
965 *width += font->width[*((byte far *)string)]; // proportional width
\r
968 void VW_MeasurePropString (char far *string, word *width, word *height)
\r
970 VWL_MeasureString(string,width,height,(fontstruct _seg *)grsegs[STARTFONT+fontnumber]);
\r
973 void VW_MeasureMPropString (char far *string, word *width, word *height)
\r
975 VWL_MeasureString(string,width,height,(fontstruct _seg *)grsegs[STARTFONTM+fontnumber]);
\r
983 =============================================================================
\r
987 =============================================================================
\r
990 #if GRMODE == CGAGR
\r
992 #define CGACRTCWIDTH 40
\r
995 ==========================
\r
999 ==========================
\r
1002 void VW_CGAFullUpdate (void)
\r
1006 unsigned x,y,middlerows,middlecollumns;
\r
1008 displayofs = bufferofs+panadjust;
\r
1013 asm mov si,[displayofs]
\r
1016 asm mov bx,100 // pairs of scan lines to copy
\r
1017 asm mov dx,[linewidth]
\r
1020 asm mov ds,[screenseg]
\r
1027 asm mov ax,39 // words accross screen
\r
1034 asm add di,0x2000-80 // go to the interlaced bank
\r
1040 asm sub di,0x2000 // go to the non interlaced bank
\r
1043 asm jnz copytwolineso
\r
1050 asm mov ax,40 // words accross screen
\r
1055 asm add di,0x2000-80 // go to the interlaced bank
\r
1059 asm sub di,0x2000 // go to the non interlaced bank
\r
1062 asm jnz copytwolines
\r
1069 asm xor ax,ax // clear out the update matrix
\r
1070 asm mov cx,UPDATEWIDE*UPDATEHIGH/2
\r
1072 asm mov di,[baseupdateptr]
\r
1075 updateptr = baseupdateptr;
\r
1076 *(unsigned *)(updateptr + UPDATEWIDE*PORTTILESHIGH) = UPDATETERMINATE;
\r
1083 =============================================================================
\r
1087 These only work in the context of the double buffered update routines
\r
1089 =============================================================================
\r
1093 ====================
\r
1097 = Background saves, then draws the cursor at cursorspot
\r
1099 ====================
\r
1102 void VWL_DrawCursor (void)
\r
1104 cursorspot = bufferofs + ylookup[cursory+pansy]+(cursorx+pansx)/SCREENXDIV;
\r
1105 VW_ScreenToMem(cursorspot,cursorsave,cursorwidth,cursorheight);
\r
1106 VWB_DrawSprite(cursorx,cursory,cursornumber);
\r
1110 //==========================================================================
\r
1114 ====================
\r
1118 ====================
\r
1121 void VWL_EraseCursor (void)
\r
1123 VW_MemToScreen(cursorsave,cursorspot,cursorwidth,cursorheight);
\r
1124 VW_MarkUpdateBlock ((cursorx+pansx)&SCREENXMASK,cursory+pansy,
\r
1125 ( (cursorx+pansx)&SCREENXMASK)+cursorwidth*SCREENXDIV-1,
\r
1126 cursory+pansy+cursorheight-1);
\r
1130 //==========================================================================
\r
1134 ====================
\r
1138 ====================
\r
1141 void VW_ShowCursor (void)
\r
1147 //==========================================================================
\r
1150 ====================
\r
1154 ====================
\r
1157 void VW_HideCursor (void)
\r
1162 //==========================================================================
\r
1165 ====================
\r
1169 ====================
\r
1171 #define MAXCURSORX (319-24)
\r
1172 #define MAXCURSORY (199-24)
\r
1174 void VW_MoveCursor (int x, int y)
\r
1179 y=MAXCURSORY; // catacombs hack to keep cursor on screen
\r
1185 //==========================================================================
\r
1188 ====================
\r
1192 = Load in a sprite to be used as a cursor, and allocate background save space
\r
1194 ====================
\r
1197 void VW_SetCursor (int spritenum)
\r
1201 cursornumber = spritenum;
\r
1203 CA_CacheGrChunk (spritenum);
\r
1204 MM_SetLock (&grsegs[spritenum],true);
\r
1206 cursorwidth = spritetable[spritenum-STARTSPRITES].width+1;
\r
1207 cursorheight = spritetable[spritenum-STARTSPRITES].height;
\r
1209 MM_GetPtr (&cursorsave,cursorwidth*cursorheight*5);
\r
1210 MM_SetLock (&cursorsave,true);
\r
1215 ====================
\r
1219 = Frees the memory used by the cursor and its background save
\r
1221 ====================
\r
1224 void VW_FreeCursor (void)
\r
1228 MM_SetLock (&grsegs[cursornumber],false);
\r
1229 MM_SetPurge (&grsegs[cursornumber],3);
\r
1230 MM_SetLock (&cursorsave,false);
\r
1231 MM_FreePtr (&cursorsave);
\r
1238 =============================================================================
\r
1240 Double buffer management routines
\r
1242 =============================================================================
\r
1246 ======================
\r
1248 = VW_InitDoubleBuffer
\r
1250 ======================
\r
1253 void VW_InitDoubleBuffer (void)
\r
1255 #if GRMODE == EGAGR
\r
1256 VW_SetScreen (displayofs+panadjust,0); // no pel pan
\r
1262 ======================
\r
1264 = VW_FixRefreshBuffer
\r
1266 = Copies the view page to the buffer page on page flipped refreshes to
\r
1267 = avoid a one frame shear around pop up windows
\r
1269 ======================
\r
1272 void VW_FixRefreshBuffer (void)
\r
1274 #if GRMODE == EGAGR
\r
1275 VW_ScreenToScreen (displayofs,bufferofs,PORTTILESWIDE*4*CHARWIDTH,
\r
1276 (PORTTILESHIGH-1)*16);
\r
1282 ======================
\r
1284 = VW_QuitDoubleBuffer
\r
1286 ======================
\r
1289 void VW_QuitDoubleBuffer (void)
\r
1295 =======================
\r
1297 = VW_MarkUpdateBlock
\r
1299 = Takes a pixel bounded block and marks the tiles in bufferblocks
\r
1300 = Returns 0 if the entire block is off the buffer screen
\r
1302 =======================
\r
1305 int VW_MarkUpdateBlock (int x1, int y1, int x2, int y2)
\r
1307 // MDM (GAMERS EDGE) begin - NOT NEEDED FOR 3D ENGINE
\r
1309 int x,y,xt1,yt1,xt2,yt2,nextline;
\r
1312 xt1 = x1>>PIXTOBLOCK;
\r
1313 yt1 = y1>>PIXTOBLOCK;
\r
1315 xt2 = x2>>PIXTOBLOCK;
\r
1316 yt2 = y2>>PIXTOBLOCK;
\r
1320 else if (xt1>=UPDATEWIDE-1)
\r
1325 else if (yt1>UPDATEHIGH)
\r
1330 else if (xt2>=UPDATEWIDE-1)
\r
1331 xt2 = UPDATEWIDE-2;
\r
1335 else if (yt2>=UPDATEHIGH)
\r
1336 yt2 = UPDATEHIGH-1;
\r
1338 mark = updateptr + uwidthtable[yt1] + xt1;
\r
1339 nextline = UPDATEWIDE - (xt2-xt1) - 1;
\r
1341 for (y=yt1;y<=yt2;y++)
\r
1343 for (x=xt1;x<=xt2;x++)
\r
1344 *mark++ = 1; // this tile will need to be updated
\r
1349 // MDM (GAMERS EDGE) end
\r
1356 ===========================
\r
1360 = Updates any changed areas of the double buffer and displays the cursor
\r
1362 ===========================
\r
1365 void VW_UpdateScreen (void)
\r
1367 if (cursorvisible>0)
\r
1370 #if GRMODE == EGAGR
\r
1371 VWL_UpdateScreenBlocks();
\r
1375 asm mov di,[updateptr] // cat3d patch
\r
1376 asm xor ax,ax // clear out the update matrix
\r
1377 asm mov cx,UPDATEWIDE*UPDATEHIGH/2
\r
1379 *(unsigned *)(updateptr + UPDATEWIDE*PORTTILESHIGH) = UPDATETERMINATE;
\r
1382 asm mov cx,[displayofs]
\r
1383 asm add cx,[panadjust]
\r
1384 asm mov dx,CRTC_INDEX
\r
1385 asm mov al,0ch // start address high register
\r
1391 asm mov al,0dh // start address low register
\r
1399 #if GRMODE == CGAGR
\r
1400 VW_CGAFullUpdate();
\r
1403 if (cursorvisible>0)
\r
1404 VWL_EraseCursor();
\r
1409 void VWB_DrawTile8 (int x, int y, int tile)
\r
1413 if (VW_MarkUpdateBlock (x&SCREENXMASK,y,(x&SCREENXMASK)+7,y+7))
\r
1414 VW_DrawTile8 (x/SCREENXDIV,y,tile);
\r
1417 void VWB_DrawTile8M (int x, int y, int tile)
\r
1423 xb = x/SCREENXDIV; // use intermediate because VW_DT8M is macro
\r
1424 // if (VW_MarkUpdateBlock (x&SCREENXMASK,y,(x&SCREENXMASK)+7,y+7)) // MDM (GAMER EDGE)
\r
1425 VW_DrawTile8M (xb,y,tile); // statement prevents drawing chars past 42
\r
1428 void VWB_DrawTile16 (int x, int y, int tile)
\r
1432 if (VW_MarkUpdateBlock (x&SCREENXMASK,y,(x&SCREENXMASK)+15,y+15))
\r
1433 VW_DrawTile16 (x/SCREENXDIV,y,tile);
\r
1436 void VWB_DrawTile16M (int x, int y, int tile)
\r
1442 xb = x/SCREENXDIV; // use intermediate because VW_DT16M is macro
\r
1443 if (VW_MarkUpdateBlock (x&SCREENXMASK,y,(x&SCREENXMASK)+15,y+15))
\r
1444 VW_DrawTile16M (xb,y,tile);
\r
1448 void VWB_DrawPic (int x, int y, int chunknum)
\r
1450 // mostly copied from drawpic
\r
1451 int picnum = chunknum - STARTPICS;
\r
1453 unsigned dest,width,height;
\r
1459 source = grsegs[chunknum];
\r
1460 dest = ylookup[y]+x+bufferofs;
\r
1461 width = pictable[picnum].width;
\r
1462 height = pictable[picnum].height;
\r
1464 if (VW_MarkUpdateBlock (x*SCREENXDIV,y,(x+width)*SCREENXDIV-1,y+height-1))
\r
1465 VW_MemToScreen(source,dest,width,height);
\r
1470 void VWB_DrawMPic(int x, int y, int chunknum)
\r
1472 // mostly copied from drawmpic
\r
1473 int picnum = chunknum - STARTPICM;
\r
1475 unsigned dest,width,height;
\r
1481 source = grsegs[chunknum];
\r
1482 dest = ylookup[y]+x+bufferofs;
\r
1483 width = picmtable[picnum].width;
\r
1484 height = picmtable[picnum].height;
\r
1486 if (VW_MarkUpdateBlock (x*SCREENXDIV,y,(x+width)*SCREENXDIV-1,y+height-1))
\r
1487 VW_MaskBlock(source,0,dest,width,height,width*height);
\r
1492 void VWB_Bar (int x, int y, int width, int height, int color)
\r
1496 if (VW_MarkUpdateBlock (x,y,x+width,y+height-1) )
\r
1497 VW_Bar (x,y,width,height,color);
\r
1502 void VWB_DrawPropString (char far *string)
\r
1507 VW_DrawPropString (string);
\r
1508 VW_MarkUpdateBlock(x,y,x+bufferwidth*8-1,y+bufferheight-1);
\r
1514 void VWB_DrawMPropString (char far *string)
\r
1519 VW_DrawMPropString (string);
\r
1520 VW_MarkUpdateBlock(x,y,x+bufferwidth*8-1,y+bufferheight-1);
\r
1525 void VWB_DrawSprite(int x, int y, int chunknum)
\r
1527 spritetabletype far *spr;
\r
1528 spritetype _seg *block;
\r
1529 unsigned dest,shift,width,height;
\r
1534 spr = &spritetable[chunknum-STARTSPRITES];
\r
1535 block = (spritetype _seg *)grsegs[chunknum];
\r
1537 y+=spr->orgy>>G_P_SHIFT;
\r
1538 x+=spr->orgx>>G_P_SHIFT;
\r
1541 #if GRMODE == EGAGR
\r
1544 #if GRMODE == CGAGR
\r
1548 dest = bufferofs + ylookup[y];
\r
1550 dest += x/SCREENXDIV;
\r
1552 dest += (x+1)/SCREENXDIV;
\r
1554 width = block->width[shift];
\r
1555 height = spr->height;
\r
1557 if (VW_MarkUpdateBlock (x&SCREENXMASK,y,(x&SCREENXMASK)+width*SCREENXDIV-1
\r
1559 VW_MaskBlock (block,block->sourceoffset[shift],dest,
\r
1560 width,height,block->planesize[shift]);
\r
1564 void VWB_Plot (int x, int y, int color)
\r
1568 if (VW_MarkUpdateBlock (x,y,x,y))
\r
1569 VW_Plot(x,y,color);
\r
1572 void VWB_Hlin (int x1, int x2, int y, int color)
\r
1577 if (VW_MarkUpdateBlock (x1,y,x2,y))
\r
1578 VW_Hlin(x1,x2,y,color);
\r
1581 void VWB_Vlin (int y1, int y2, int x, int color)
\r
1586 if (VW_MarkUpdateBlock (x,y1,x,y2))
\r
1587 VW_Vlin(y1,y2,x,color);
\r
1591 //===========================================================================
\r