]> 4ch.mooo.com Git - 16.git/blobdiff - 16/keen456/KEEN4-6/ID_VW.C
added keen 4-6 rebuild code for reference.... i need to stop doing this... xD
[16.git] / 16 / keen456 / KEEN4-6 / ID_VW.C
diff --git a/16/keen456/KEEN4-6/ID_VW.C b/16/keen456/KEEN4-6/ID_VW.C
deleted file mode 100755 (executable)
index 69b54c5..0000000
+++ /dev/null
@@ -1,1548 +0,0 @@
-/* Reconstructed Commander Keen 4-6 Source Code\r
- * Copyright (C) 2021 K1n9_Duk3\r
- *\r
- * This file is primarily based on:\r
- * Catacomb 3-D Source Code\r
- * Copyright (C) 1993-2014 Flat Rock Software\r
- *\r
- * This program is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 2 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License along\r
- * with this program; if not, write to the Free Software Foundation, Inc.,\r
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
- */\r
-\r
-// ID_VW.C\r
-\r
-#include "ID_HEADS.H"\r
-\r
-/*\r
-=============================================================================\r
-\r
-                                                LOCAL CONSTANTS\r
-\r
-=============================================================================\r
-*/\r
-\r
-#define VIEWWIDTH              40\r
-\r
-#define PIXTOBLOCK             4               // 16 pixels to an update block\r
-\r
-/*\r
-=============================================================================\r
-\r
-                                                GLOBAL VARIABLES\r
-\r
-=============================================================================\r
-*/\r
-\r
-cardtype       videocard;              // set by VW_Startup\r
-grtype         grmode;                 // CGAgr, EGAgr, VGAgr\r
-\r
-unsigned       bufferofs;              // hidden area to draw to before displaying\r
-unsigned       displayofs;             // origin of the visable screen\r
-unsigned       panx,pany;              // panning adjustments inside port in pixels\r
-unsigned       pansx,pansy;    // panning adjustments inside port in screen\r
-                                                       // block limited pixel values (ie 0/8 for ega x)\r
-unsigned       panadjust;              // panx/pany adjusted by screen resolution\r
-\r
-unsigned       screenseg;              // normally 0xa000 / 0xb800\r
-unsigned       linewidth;\r
-unsigned       ylookup[VIRTUALHEIGHT];\r
-\r
-unsigned       fontnumber;             // 0 based font number for drawing\r
-\r
-boolean                screenfaded;\r
-\r
-pictabletype   _seg *pictable;\r
-pictabletype   _seg *picmtable;\r
-spritetabletype _seg *spritetable;\r
-\r
-int                    bordercolor;\r
-boolean                        nopan;\r
-\r
-/*\r
-=============================================================================\r
-\r
-                                                LOCAL VARIABLES\r
-\r
-=============================================================================\r
-*/\r
-\r
-void   VWL_MeasureString (char far *string, word *width, word *height,\r
-               fontstruct _seg *font);\r
-void   VWL_DrawCursor (void);\r
-void   VWL_EraseCursor (void);\r
-void   VWL_DBSetup (void);\r
-void   VWL_UpdateScreenBlocks (void);\r
-\r
-\r
-int                    bordercolor;\r
-int                    cursorvisible;\r
-int                    cursornumber,cursorwidth,cursorheight,cursorx,cursory;\r
-memptr         cursorsave;\r
-unsigned       cursorspot;\r
-\r
-//===========================================================================\r
-\r
-\r
-/*\r
-=======================\r
-=\r
-= VW_Startup\r
-=\r
-=======================\r
-*/\r
-\r
-static char *ParmStrings[] = {"HIDDENCARD","NOPAN",""};\r
-\r
-void   VW_Startup (void)\r
-{\r
-       int i,n;\r
-\r
-       asm     cld;\r
-\r
-       videocard = 0;\r
-\r
-       for (i = 1;i < _argc;i++)\r
-       {\r
-               n = US_CheckParm(_argv[i],ParmStrings);\r
-               if (n == 0)\r
-               {\r
-                       videocard = EGAcard;\r
-               }\r
-               else if (n == 1)\r
-               {\r
-                       nopan = true;\r
-               }\r
-       }\r
-\r
-       if (!videocard)\r
-               videocard = VW_VideoID ();\r
-\r
-#if GRMODE == EGAGR\r
-       grmode = EGAGR;\r
-       if (videocard != EGAcard && videocard != VGAcard)\r
-#ifdef KEEN\r
-Quit ("Improper video card!  If you really have an EGA/VGA card that I am not\n"\r
-         "detecting, use the -HIDDENCARD command line parameter!");\r
-#else\r
-Quit ("Improper video card!  If you really have an EGA/VGA card that I am not \n"\r
-         "detecting, use the -HIDDENCARD command line parameter!");\r
-#endif\r
-       EGAWRITEMODE(0);\r
-#endif\r
-\r
-#if GRMODE == CGAGR\r
-       grmode = CGAGR;\r
-       if (videocard < CGAcard || videocard > VGAcard)\r
-#ifdef KEEN\r
-Quit ("Improper video card!  If you really have a CGA card that I am not\n"\r
-         "detecting, use the -HIDDENCARD command line parameter!");\r
-#else\r
-Quit ("Improper video card!  If you really have a CGA card that I am not \n"\r
-         "detecting, use the -HIDDENCARD command line parameter!");\r
-#endif\r
-       MM_GetPtr (&(memptr)screenseg,0x10000l);        // grab 64k for floating screen\r
-#endif\r
-\r
-       cursorvisible = 0;\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-=======================\r
-=\r
-= VW_Shutdown\r
-=\r
-=======================\r
-*/\r
-\r
-void   VW_Shutdown (void)\r
-{\r
-       VW_SetScreenMode (TEXTGR);\r
-#if GRMODE == EGAGR\r
-       VW_SetLineWidth (80);\r
-#endif\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-========================\r
-=\r
-= VW_SetScreenMode\r
-= Call BIOS to set TEXT / CGAgr / EGAgr / VGAgr\r
-=\r
-========================\r
-*/\r
-\r
-void VW_SetScreenMode (int grmode)\r
-{\r
-       switch (grmode)\r
-       {\r
-         case TEXTGR:  _AX = 3;\r
-                 geninterrupt (0x10);\r
-#ifdef CAT3D\r
-                 screenseg=0xb000;\r
-#endif\r
-                 break;\r
-         case CGAGR: _AX = 4;\r
-                 geninterrupt (0x10);          // screenseg is actually a main mem buffer\r
-                 break;\r
-         case EGAGR: _AX = 0xd;\r
-                 geninterrupt (0x10);\r
-                 screenseg=0xa000;\r
-                 break;\r
-#ifdef VGAGAME\r
-         case VGAGR:{\r
-                 char extern VGAPAL;   // deluxepaint vga pallet .OBJ file\r
-                 void far *vgapal = &VGAPAL;\r
-                 SetCool256 ();                // custom 256 color mode\r
-                 screenseg=0xa000;\r
-                 _ES = FP_SEG(vgapal);\r
-                 _DX = FP_OFF(vgapal);\r
-                 _BX = 0;\r
-                 _CX = 0x100;\r
-                 _AX = 0x1012;\r
-                 geninterrupt(0x10);                   // set the deluxepaint pallet\r
-\r
-                 break;\r
-#endif\r
-       }\r
-       VW_SetLineWidth(SCREENWIDTH);\r
-}\r
-\r
-/*\r
-=============================================================================\r
-\r
-                                                       SCREEN FADES\r
-\r
-=============================================================================\r
-*/\r
-\r
-char colors[7][17]=\r
-{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\r
- {0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,0},\r
- {0,0,0,0,0,0,0,0,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0},\r
- {0,1,2,3,4,5,6,7,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0},\r
- {0,1,2,3,4,5,6,7,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0},\r
- {0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f}};\r
-\r
-\r
-void VW_ColorBorder (int color)\r
-{\r
-       _AH=0x10;\r
-       _AL=1;\r
-       _BH=color;\r
-       geninterrupt (0x10);\r
-       bordercolor = color;\r
-}\r
-\r
-void VW_SetPalette(byte *palette)\r
-{\r
-       byte    p;\r
-       word    i;\r
-\r
-       for (i = 0;i < 15;i++)\r
-       {\r
-               p = palette[i];\r
-               colors[0][i] = 0;\r
-               colors[1][i] = (p > 0x10)? (p & 0x0f) : 0;\r
-               colors[2][i] = (p > 0x10)? p : 0;\r
-               colors[3][i] = p;\r
-               colors[4][i] = (p > 0x10)? 0x1f : p;\r
-               colors[5][i] = 0x1f;\r
-       }\r
-}\r
-\r
-void VW_SetDefaultColors(void)\r
-{\r
-#if GRMODE == EGAGR\r
-       colors[3][16] = bordercolor;\r
-       _ES=FP_SEG(&colors[3]);\r
-       _DX=FP_OFF(&colors[3]);\r
-       _AX=0x1002;\r
-       geninterrupt(0x10);\r
-       screenfaded = false;\r
-#endif\r
-}\r
-\r
-\r
-void VW_FadeOut(void)\r
-{\r
-#if GRMODE == EGAGR\r
-       int i;\r
-\r
-       for (i=3;i>=0;i--)\r
-       {\r
-         colors[i][16] = bordercolor;\r
-         _ES=FP_SEG(&colors[i]);\r
-         _DX=FP_OFF(&colors[i]);\r
-         _AX=0x1002;\r
-         geninterrupt(0x10);\r
-         VW_WaitVBL(6);\r
-       }\r
-       screenfaded = true;\r
-#endif\r
-}\r
-\r
-\r
-void VW_FadeIn(void)\r
-{\r
-#if GRMODE == EGAGR\r
-       int i;\r
-\r
-       for (i=0;i<4;i++)\r
-       {\r
-         colors[i][16] = bordercolor;\r
-         _ES=FP_SEG(&colors[i]);\r
-         _DX=FP_OFF(&colors[i]);\r
-         _AX=0x1002;\r
-         geninterrupt(0x10);\r
-         VW_WaitVBL(6);\r
-       }\r
-       screenfaded = false;\r
-#endif\r
-}\r
-\r
-void VW_FadeUp(void)\r
-{\r
-#if GRMODE == EGAGR\r
-       int i;\r
-\r
-       for (i=3;i<6;i++)\r
-       {\r
-         colors[i][16] = bordercolor;\r
-         _ES=FP_SEG(&colors[i]);\r
-         _DX=FP_OFF(&colors[i]);\r
-         _AX=0x1002;\r
-         geninterrupt(0x10);\r
-         VW_WaitVBL(6);\r
-       }\r
-       screenfaded = true;\r
-#endif\r
-}\r
-\r
-void VW_FadeDown(void)\r
-{\r
-#if GRMODE == EGAGR\r
-       int i;\r
-\r
-       for (i=5;i>2;i--)\r
-       {\r
-         colors[i][16] = bordercolor;\r
-         _ES=FP_SEG(&colors[i]);\r
-         _DX=FP_OFF(&colors[i]);\r
-         _AX=0x1002;\r
-         geninterrupt(0x10);\r
-         VW_WaitVBL(6);\r
-       }\r
-       screenfaded = false;\r
-#endif\r
-}\r
-\r
-\r
-/*\r
-========================\r
-=\r
-= VW_SetAtrReg\r
-=\r
-= Sets an attribute (pallete / border) register\r
-= Does NOT vsync!\r
-=\r
-========================\r
-*/\r
-\r
-void VW_SetAtrReg (int reg, int value)\r
-{\r
-  asm  cli\r
-  asm  mov     dx,STATUS_REGISTER_1\r
-  asm  in      al,dx\r
-  asm  mov     dx,ATR_INDEX\r
-\r
-  asm  mov     al,BYTE PTR [reg]\r
-  asm  out     dx,al\r
-  asm  mov     al,BYTE PTR [value]\r
-  asm  out     dx,al\r
-  asm  mov     dx,0x3da\r
-  asm  in      al,dx\r
-  asm  mov     dx,ATR_INDEX\r
-  asm  mov     al,0x20\r
-  asm  out     dx,al\r
-  asm  sti\r
-}\r
-\r
-\r
-\r
-//===========================================================================\r
-\r
-/*\r
-====================\r
-=\r
-= VW_SetLineWidth\r
-=\r
-= Must be an even number of bytes\r
-=\r
-====================\r
-*/\r
-\r
-void VW_SetLineWidth (int width)\r
-{\r
-  int i,offset;\r
-\r
-#if GRMODE == EGAGR\r
-//\r
-// set wide virtual screen\r
-//\r
-asm    mov     dx,CRTC_INDEX\r
-asm    mov     al,CRTC_OFFSET\r
-asm mov        ah,[BYTE PTR width]\r
-asm    shr     ah,1\r
-asm    out     dx,ax\r
-#endif\r
-\r
-//\r
-// set up lookup tables\r
-//\r
-  linewidth = width;\r
-\r
-  offset = 0;\r
-\r
-  for (i=0;i<VIRTUALHEIGHT;i++)\r
-  {\r
-       ylookup[i]=offset;\r
-       offset += width;\r
-  }\r
-}\r
-\r
-\r
-//===========================================================================\r
-\r
-/*\r
-====================\r
-=\r
-= VW_SetSplitScreen\r
-=\r
-====================\r
-*/\r
-#ifdef CAT3D\r
-void VW_SetSplitScreen (int linenum)\r
-{\r
-       VW_WaitVBL (1);\r
-       if (videocard==VGAcard)\r
-               linenum=linenum*2-1;\r
-       outportb (CRTC_INDEX,CRTC_LINECOMPARE);\r
-       outportb (CRTC_INDEX+1,linenum % 256);\r
-       outportb (CRTC_INDEX,CRTC_OVERFLOW);\r
-       outportb (CRTC_INDEX+1, 1+16*(linenum/256));\r
-       if (videocard==VGAcard)\r
-       {\r
-               outportb (CRTC_INDEX,CRTC_MAXSCANLINE);\r
-               outportb (CRTC_INDEX+1,inportb(CRTC_INDEX+1) & (255-64));\r
-       }\r
-}\r
-#endif\r
-//===========================================================================\r
-\r
-/*\r
-====================\r
-=\r
-= VW_ClearVideo\r
-=\r
-====================\r
-*/\r
-\r
-void   VW_ClearVideo (int color)\r
-{\r
-#if GRMODE == EGAGR\r
-       EGAWRITEMODE(2);\r
-       EGAMAPMASK(15);\r
-\r
-       color = (color << 8) & color;   //BUG: color is always 0 after this\r
-#endif\r
-\r
-#if GRMODE == CGAGR\r
-       color = (color << 12) & (color << 8) & (color << 4) & color;    //BUG: color is always 0 after this\r
-#endif\r
-\r
-       VW_WaitVBL(1);\r
-\r
-asm    mov     es, screenseg;\r
-asm    mov     di, displayofs;\r
-asm    and     di, not 1;\r
-asm    mov     cx, 8000h;\r
-asm    mov     ax, color;\r
-asm    rep stosw;\r
-\r
-#if GRMODE == EGAGR\r
-       EGAWRITEMODE(0);\r
-#endif\r
-}\r
-\r
-//===========================================================================\r
-\r
-#if NUMPICS>0\r
-\r
-/*\r
-====================\r
-=\r
-= VW_DrawPic\r
-=\r
-= X in bytes, y in pixels, chunknum is the #defined picnum\r
-=\r
-====================\r
-*/\r
-\r
-void VW_DrawPic(unsigned x, unsigned y, unsigned chunknum)\r
-{\r
-       int     picnum = chunknum - STARTPICS;\r
-       memptr source;\r
-       unsigned dest,width,height;\r
-\r
-       source = grsegs[chunknum];\r
-       dest = ylookup[y]+x+bufferofs;\r
-       width = pictable[picnum].width;\r
-       height = pictable[picnum].height;\r
-\r
-       VW_MemToScreen(source,dest,width,height);\r
-}\r
-\r
-\r
-#endif\r
-\r
-#if NUMPICM>0\r
-\r
-/*\r
-====================\r
-=\r
-= VW_DrawMPic\r
-=\r
-= X in bytes, y in pixels, chunknum is the #defined picnum\r
-=\r
-====================\r
-*/\r
-\r
-void VW_DrawMPic(unsigned x, unsigned y, unsigned chunknum)\r
-{\r
-       int     picnum = chunknum - STARTPICM;\r
-       memptr source;\r
-       unsigned dest,width,height;\r
-\r
-       source = grsegs[chunknum];\r
-       dest = ylookup[y]+x+bufferofs;\r
-       width = picmtable[picnum].width;\r
-       height = picmtable[picnum].height;\r
-\r
-       VW_MaskBlock(source,0,dest,width,height,width*height);\r
-}\r
-\r
-void VW_ClipDrawMPic(unsigned x, int y, unsigned chunknum)\r
-{\r
-       int     picnum = chunknum - STARTPICM;\r
-       memptr source;\r
-       unsigned dest,width,ofs,plane;\r
-       int             height;\r
-\r
-       source = grsegs[chunknum];\r
-       width = picmtable[picnum].width;\r
-       height = picmtable[picnum].height;\r
-       plane = width*height;\r
-\r
-       ofs = 0;\r
-       if (y<0)\r
-       {\r
-               ofs= -y*width;\r
-               height+=y;\r
-               y=0;\r
-       }\r
-       else if (y+height>216)\r
-       {\r
-               height-=(y-216);\r
-       }\r
-       dest = ylookup[y]+x+bufferofs;\r
-       if (height<1)\r
-               return;\r
-\r
-       VW_MaskBlock(source,ofs,dest,width,height,plane);\r
-}\r
-\r
-\r
-#endif\r
-\r
-//===========================================================================\r
-\r
-#if NUMSPRITES>0\r
-\r
-/*\r
-====================\r
-=\r
-= VW_DrawSprite\r
-=\r
-= X and Y in pixels, it will match the closest shift possible\r
-=\r
-= To do:\r
-= Add vertical clipping!\r
-= Make the shifts act as center points, rather than break points\r
-=\r
-====================\r
-*/\r
-\r
-void VW_DrawSprite(int x, int y, unsigned chunknum)\r
-{\r
-       spritetabletype far *spr;\r
-       spritetype _seg *block;\r
-       unsigned        dest,shift;\r
-\r
-       spr = &spritetable[chunknum-STARTSPRITES];\r
-       block = (spritetype _seg *)grsegs[chunknum];\r
-\r
-       y+=spr->orgy>>G_P_SHIFT;\r
-       x+=spr->orgx>>G_P_SHIFT;\r
-\r
-#if GRMODE == EGAGR\r
-       shift = (x&7)/2;\r
-#endif\r
-#if GRMODE == CGAGR\r
-       shift = 0;\r
-#endif\r
-\r
-       dest = bufferofs + ylookup[y];\r
-       if (x>=0)\r
-               dest += x/SCREENXDIV;\r
-       else\r
-               dest += (x+1)/SCREENXDIV;\r
-\r
-       VW_MaskBlock (block,block->sourceoffset[shift],dest,\r
-               block->width[shift],spr->height,block->planesize[shift]);\r
-}\r
-\r
-#endif\r
-\r
-\r
-/*\r
-==================\r
-=\r
-= VW_Hlin\r
-=\r
-==================\r
-*/\r
-\r
-\r
-#if GRMODE == EGAGR\r
-\r
-unsigned char leftmask[8] = {0xff,0x7f,0x3f,0x1f,0xf,7,3,1};\r
-unsigned char rightmask[8] = {0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff};\r
-\r
-void VW_Hlin(unsigned xl, unsigned xh, unsigned y, unsigned color)\r
-{\r
-  unsigned dest,xlb,xhb,maskleft,maskright,mid;\r
-\r
-       xlb=xl/8;\r
-       xhb=xh/8;\r
-\r
-       EGAWRITEMODE(2);\r
-       EGAMAPMASK(15);\r
-\r
-       maskleft = leftmask[xl&7];\r
-       maskright = rightmask[xh&7];\r
-\r
-       mid = xhb-xlb-1;\r
-       dest = bufferofs+ylookup[y]+xlb;\r
-\r
-  if (xlb==xhb)\r
-  {\r
-  //\r
-  // entire line is in one byte\r
-  //\r
-\r
-       maskleft&=maskright;\r
-\r
-       asm     mov     es,[screenseg]\r
-       asm     mov     di,[dest]\r
-\r
-       asm     mov     dx,GC_INDEX\r
-       asm     mov     al,GC_BITMASK\r
-       asm     mov     ah,[BYTE PTR maskleft]\r
-       asm     out     dx,ax           // mask off pixels\r
-\r
-       asm     mov     al,[BYTE PTR color]\r
-       asm     xchg    al,[es:di]      // load latches and write pixels\r
-\r
-       goto    done;\r
-  }\r
-\r
-asm    mov     es,[screenseg]\r
-asm    mov     di,[dest]\r
-asm    mov     dx,GC_INDEX\r
-asm    mov     bh,[BYTE PTR color]\r
-\r
-//\r
-// draw left side\r
-//\r
-asm    mov     al,GC_BITMASK\r
-asm    mov     ah,[BYTE PTR maskleft]\r
-asm    out     dx,ax           // mask off pixels\r
-\r
-asm    mov     al,bh\r
-asm    mov     bl,[es:di]      // load latches\r
-asm    stosb\r
-\r
-//\r
-// draw middle\r
-//\r
-asm    mov     ax,GC_BITMASK + 255*256\r
-asm    out     dx,ax           // no masking\r
-\r
-asm    mov     al,bh\r
-asm    mov     cx,[mid]\r
-asm    rep     stosb\r
-\r
-//\r
-// draw right side\r
-//\r
-asm    mov     al,GC_BITMASK\r
-asm    mov     ah,[BYTE PTR maskright]\r
-asm    out     dx,ax           // mask off pixels\r
-\r
-asm    xchg    bh,[es:di]      // load latches and write pixels\r
-\r
-done:\r
-       EGABITMASK(255);\r
-       EGAWRITEMODE(0);\r
-}\r
-#endif\r
-\r
-\r
-#if GRMODE == CGAGR\r
-\r
-unsigned char pixmask[4] = {0xc0,0x30,0x0c,0x03};\r
-unsigned char leftmask[4] = {0xff,0x3f,0x0f,0x03};\r
-unsigned char rightmask[4] = {0xc0,0xf0,0xfc,0xff};\r
-unsigned char colorbyte[4] = {0,0x55,0xaa,0xff};\r
-\r
-//\r
-// could be optimized for rep stosw\r
-//\r
-void VW_Hlin(unsigned xl, unsigned xh, unsigned y, unsigned color)\r
-{\r
-       unsigned dest,xlb,xhb,mid;\r
-       byte maskleft,maskright;\r
-\r
-       color = colorbyte[color];       // expand 2 color bits to 8\r
-\r
-       xlb=xl/4;\r
-       xhb=xh/4;\r
-\r
-       maskleft = leftmask[xl&3];\r
-       maskright = rightmask[xh&3];\r
-\r
-       mid = xhb-xlb-1;\r
-       dest = bufferofs+ylookup[y]+xlb;\r
-asm    mov     es,[screenseg]\r
-\r
-       if (xlb==xhb)\r
-       {\r
-       //\r
-       // entire line is in one byte\r
-       //\r
-               maskleft&=maskright;\r
-\r
-               asm     mov     ah,[maskleft]\r
-               asm     mov     bl,[BYTE PTR color]\r
-               asm     and     bl,[maskleft]\r
-               asm     not     ah\r
-\r
-               asm     mov     di,[dest]\r
-\r
-               asm     mov     al,[es:di]\r
-               asm     and     al,ah                   // mask out pixels\r
-               asm     or      al,bl                   // or in color\r
-               asm     mov     [es:di],al\r
-               return;\r
-       }\r
-\r
-asm    mov     di,[dest]\r
-asm    mov     bh,[BYTE PTR color]\r
-\r
-//\r
-// draw left side\r
-//\r
-asm    mov     ah,[maskleft]\r
-asm    mov     bl,bh\r
-asm    and     bl,[maskleft]\r
-asm    not     ah\r
-asm    mov     al,[es:di]\r
-asm    and     al,ah                   // mask out pixels\r
-asm    or      al,bl                   // or in color\r
-asm    stosb\r
-\r
-//\r
-// draw middle\r
-//\r
-asm    mov     al,bh\r
-asm    mov     cx,[mid]\r
-asm    rep     stosb\r
-\r
-//\r
-// draw right side\r
-//\r
-asm    mov     ah,[maskright]\r
-asm    mov     bl,bh\r
-asm    and     bl,[maskright]\r
-asm    not     ah\r
-asm    mov     al,[es:di]\r
-asm    and     al,ah                   // mask out pixels\r
-asm    or      al,bl                   // or in color\r
-asm    stosb\r
-}\r
-#endif\r
-\r
-\r
-/*\r
-==================\r
-=\r
-= VW_Bar\r
-=\r
-= Pixel addressable block fill routine\r
-=\r
-==================\r
-*/\r
-\r
-#if GRMODE == CGAGR\r
-\r
-void VW_Bar (unsigned x, unsigned y, unsigned width, unsigned height,\r
-       unsigned color)\r
-{\r
-       unsigned xh = x+width-1;\r
-\r
-       while (height--)\r
-               VW_Hlin (x,xh,y++,color);\r
-}\r
-\r
-#endif\r
-\r
-\r
-#if    GRMODE == EGAGR\r
-\r
-void VW_Bar (unsigned x, unsigned y, unsigned width, unsigned height,\r
-       unsigned color)\r
-{\r
-       unsigned dest,xh,xlb,xhb,maskleft,maskright,mid;\r
-\r
-       xh = x+width-1;\r
-       xlb=x/8;\r
-       xhb=xh/8;\r
-\r
-       EGAWRITEMODE(2);\r
-       EGAMAPMASK(15);\r
-\r
-       maskleft = leftmask[x&7];\r
-       maskright = rightmask[xh&7];\r
-\r
-       mid = xhb-xlb-1;\r
-       dest = bufferofs+ylookup[y]+xlb;\r
-\r
-       if (xlb==xhb)\r
-       {\r
-       //\r
-       // entire line is in one byte\r
-       //\r
-\r
-               maskleft&=maskright;\r
-\r
-       asm     mov     es,[screenseg]\r
-       asm     mov     di,[dest]\r
-\r
-       asm     mov     dx,GC_INDEX\r
-       asm     mov     al,GC_BITMASK\r
-       asm     mov     ah,[BYTE PTR maskleft]\r
-       asm     out     dx,ax           // mask off pixels\r
-\r
-       asm     mov     ah,[BYTE PTR color]\r
-       asm     mov     dx,[linewidth]\r
-yloop1:\r
-       asm     mov     al,ah\r
-       asm     xchg    al,[es:di]      // load latches and write pixels\r
-       asm     add     di,dx                   // down to next line\r
-       asm     dec     [height]\r
-       asm     jnz     yloop1\r
-\r
-               goto    done;\r
-       }\r
-\r
-asm    mov     es,[screenseg]\r
-asm    mov     di,[dest]\r
-asm    mov     bh,[BYTE PTR color]\r
-asm    mov     dx,GC_INDEX\r
-asm    mov     si,[linewidth]\r
-asm    sub     si,[mid]                        // add to di at end of line to get to next scan\r
-asm    dec     si\r
-\r
-//\r
-// draw left side\r
-//\r
-yloop2:\r
-asm    mov     al,GC_BITMASK\r
-asm    mov     ah,[BYTE PTR maskleft]\r
-asm    out     dx,ax           // mask off pixels\r
-\r
-asm    mov     al,bh\r
-asm    mov     bl,[es:di]      // load latches\r
-asm    stosb\r
-\r
-//\r
-// draw middle\r
-//\r
-asm    mov     ax,GC_BITMASK + 255*256\r
-asm    out     dx,ax           // no masking\r
-\r
-asm    mov     al,bh\r
-asm    mov     cx,[mid]\r
-asm    rep     stosb\r
-\r
-//\r
-// draw right side\r
-//\r
-asm    mov     al,GC_BITMASK\r
-asm    mov     ah,[BYTE PTR maskright]\r
-asm    out     dx,ax           // mask off pixels\r
-\r
-asm    mov     al,bh\r
-asm    xchg    al,[es:di]      // load latches and write pixels\r
-\r
-asm    add     di,si           // move to start of next line\r
-asm    dec     [height]\r
-asm    jnz     yloop2\r
-\r
-done:\r
-       EGABITMASK(255);\r
-       EGAWRITEMODE(0);\r
-}\r
-\r
-#endif\r
-\r
-//==========================================================================\r
-\r
-/*\r
-==================\r
-=\r
-= VW_MeasureString\r
-=\r
-==================\r
-*/\r
-\r
-#if NUMFONT+NUMFONTM>0\r
-void\r
-VWL_MeasureString (char far *string, word *width, word *height, fontstruct _seg *font)\r
-{\r
-       *height = font->height;\r
-       for (*width = 0;*string;string++)\r
-               *width += font->width[*((byte far *)string)];   // proportional width\r
-}\r
-\r
-void   VW_MeasurePropString (char far *string, word *width, word *height)\r
-{\r
-       VWL_MeasureString(string,width,height,(fontstruct _seg *)grsegs[STARTFONT+fontnumber]);\r
-}\r
-\r
-void   VW_MeasureMPropString  (char far *string, word *width, word *height)\r
-{\r
-       VWL_MeasureString(string,width,height,(fontstruct _seg *)grsegs[STARTFONTM+fontnumber]);\r
-}\r
-\r
-\r
-#endif\r
-\r
-\r
-/*\r
-=============================================================================\r
-\r
-                                                       CGA stuff\r
-\r
-=============================================================================\r
-*/\r
-\r
-#if GRMODE == CGAGR\r
-\r
-#define CGACRTCWIDTH   40\r
-\r
-/*\r
-==========================\r
-=\r
-= VW_CGAFullUpdate\r
-=\r
-==========================\r
-*/\r
-\r
-void VW_CGAFullUpdate (void)\r
-{\r
-       byte    *update;\r
-       boolean halftile;\r
-       unsigned        x,y,middlerows,middlecollumns;\r
-\r
-       displayofs = bufferofs+panadjust;\r
-\r
-asm    mov     ax,0xb800\r
-asm    mov     es,ax\r
-\r
-asm    mov     si,[displayofs]\r
-asm    xor     di,di\r
-\r
-asm    mov     bx,100                          // pairs of scan lines to copy\r
-asm    mov     dx,[linewidth]\r
-asm    sub     dx,80\r
-\r
-asm    mov     ds,[screenseg]\r
-asm    test    si,1\r
-asm    jz      evenblock\r
-\r
-//\r
-// odd source\r
-//\r
-asm    mov     ax,39                           // words accross screen\r
-copytwolineso:\r
-asm    movsb\r
-asm    mov     cx,ax\r
-asm    rep     movsw\r
-asm    movsb\r
-asm    add     si,dx\r
-asm    add     di,0x2000-80            // go to the interlaced bank\r
-asm    movsb\r
-asm    mov     cx,ax\r
-asm    rep     movsw\r
-asm    movsb\r
-asm    add     si,dx\r
-asm    sub     di,0x2000                       // go to the non interlaced bank\r
-\r
-asm    dec     bx\r
-asm    jnz     copytwolineso\r
-asm    jmp     blitdone\r
-\r
-//\r
-// even source\r
-//\r
-evenblock:\r
-asm    mov     ax,40                           // words accross screen\r
-copytwolines:\r
-asm    mov     cx,ax\r
-asm    rep     movsw\r
-asm    add     si,dx\r
-asm    add     di,0x2000-80            // go to the interlaced bank\r
-asm    mov     cx,ax\r
-asm    rep     movsw\r
-asm    add     si,dx\r
-asm    sub     di,0x2000                       // go to the non interlaced bank\r
-\r
-asm    dec     bx\r
-asm    jnz     copytwolines\r
-\r
-blitdone:\r
-asm    mov     ax,ss\r
-asm    mov     ds,ax\r
-asm    mov     es,ax\r
-\r
-asm    xor     ax,ax                           // clear out the update matrix\r
-asm    mov     cx,UPDATEWIDE*UPDATEHIGH/2\r
-\r
-asm    mov     di,[baseupdateptr]\r
-asm    rep     stosw\r
-\r
-       updateptr = baseupdateptr;\r
-       *(unsigned *)(updateptr + UPDATEWIDE*PORTTILESHIGH) = UPDATETERMINATE;\r
-}\r
-\r
-\r
-#endif\r
-\r
-/*\r
-=============================================================================\r
-\r
-                                          CURSOR ROUTINES\r
-\r
-These only work in the context of the double buffered update routines\r
-\r
-=============================================================================\r
-*/\r
-\r
-/*\r
-====================\r
-=\r
-= VWL_DrawCursor\r
-=\r
-= Background saves, then draws the cursor at cursorspot\r
-=\r
-====================\r
-*/\r
-\r
-void VWL_DrawCursor (void)\r
-{\r
-       cursorspot = bufferofs + ylookup[cursory+pansy]+(cursorx+pansx)/SCREENXDIV;\r
-       VW_ScreenToMem(cursorspot,cursorsave,cursorwidth,cursorheight);\r
-       VWB_DrawSprite(cursorx,cursory,cursornumber);\r
-}\r
-\r
-\r
-//==========================================================================\r
-\r
-\r
-/*\r
-====================\r
-=\r
-= VWL_EraseCursor\r
-=\r
-====================\r
-*/\r
-\r
-void VWL_EraseCursor (void)\r
-{\r
-       VW_MemToScreen(cursorsave,cursorspot,cursorwidth,cursorheight);\r
-       VW_MarkUpdateBlock ((cursorx+pansx)&SCREENXMASK,cursory+pansy,\r
-               ( (cursorx+pansx)&SCREENXMASK)+cursorwidth*SCREENXDIV-1,\r
-               cursory+pansy+cursorheight-1);\r
-}\r
-\r
-\r
-//==========================================================================\r
-\r
-\r
-/*\r
-====================\r
-=\r
-= VW_ShowCursor\r
-=\r
-====================\r
-*/\r
-\r
-void VW_ShowCursor (void)\r
-{\r
-       cursorvisible++;\r
-}\r
-\r
-\r
-//==========================================================================\r
-\r
-/*\r
-====================\r
-=\r
-= VW_HideCursor\r
-=\r
-====================\r
-*/\r
-\r
-void VW_HideCursor (void)\r
-{\r
-       cursorvisible--;\r
-}\r
-\r
-//==========================================================================\r
-\r
-/*\r
-====================\r
-=\r
-= VW_MoveCursor\r
-=\r
-====================\r
-*/\r
-#define MAXCURSORX     (319-24)\r
-#define MAXCURSORY     (199-24)\r
-\r
-void VW_MoveCursor (int x, int y)\r
-{\r
-#ifdef CAT3D\r
-       if (x>MAXCURSORX)\r
-               x=MAXCURSORX;\r
-       if (y>MAXCURSORY)\r
-               y=MAXCURSORY;                   // catacombs hack to keep cursor on screen\r
-#endif\r
-\r
-       cursorx = x;\r
-       cursory = y;\r
-}\r
-\r
-//==========================================================================\r
-\r
-/*\r
-====================\r
-=\r
-= VW_SetCursor\r
-=\r
-= Load in a sprite to be used as a cursor, and allocate background save space\r
-=\r
-====================\r
-*/\r
-\r
-void VW_SetCursor (int spritenum)\r
-{\r
-       VW_FreeCursor ();\r
-\r
-       cursornumber = spritenum;\r
-\r
-       CA_CacheGrChunk (spritenum);\r
-       MM_SetLock (&grsegs[spritenum],true);\r
-\r
-       cursorwidth = spritetable[spritenum-STARTSPRITES].width+1;\r
-       cursorheight = spritetable[spritenum-STARTSPRITES].height;\r
-\r
-       MM_GetPtr (&cursorsave,cursorwidth*cursorheight*5);\r
-       MM_SetLock (&cursorsave,true);\r
-}\r
-\r
-\r
-/*\r
-====================\r
-=\r
-= VW_FreeCursor\r
-=\r
-= Frees the memory used by the cursor and its background save\r
-=\r
-====================\r
-*/\r
-\r
-void VW_FreeCursor (void)\r
-{\r
-       if (cursornumber)\r
-       {\r
-               MM_SetLock (&grsegs[cursornumber],false);\r
-               MM_SetPurge (&grsegs[cursornumber],3);\r
-               MM_SetLock (&cursorsave,false);\r
-               MM_FreePtr (&cursorsave);\r
-               cursornumber = 0;\r
-       }\r
-}\r
-\r
-\r
-/*\r
-=============================================================================\r
-\r
-                               Double buffer management routines\r
-\r
-=============================================================================\r
-*/\r
-\r
-/*\r
-======================\r
-=\r
-= VW_InitDoubleBuffer\r
-=\r
-======================\r
-*/\r
-\r
-void VW_InitDoubleBuffer (void)\r
-{\r
-#if GRMODE == EGAGR\r
-       VW_SetScreen (displayofs+panadjust,0);                  // no pel pan\r
-#endif\r
-}\r
-\r
-\r
-/*\r
-======================\r
-=\r
-= VW_FixRefreshBuffer\r
-=\r
-= Copies the view page to the buffer page on page flipped refreshes to\r
-= avoid a one frame shear around pop up windows\r
-=\r
-======================\r
-*/\r
-\r
-void VW_FixRefreshBuffer (void)\r
-{\r
-#if GRMODE == EGAGR\r
-       VW_ScreenToScreen (displayofs,bufferofs,PORTTILESWIDE*4*CHARWIDTH,\r
-               (PORTTILESHIGH-1)*16);\r
-#endif\r
-}\r
-\r
-\r
-/*\r
-======================\r
-=\r
-= VW_QuitDoubleBuffer\r
-=\r
-======================\r
-*/\r
-\r
-void VW_QuitDoubleBuffer (void)\r
-{\r
-}\r
-\r
-\r
-/*\r
-=======================\r
-=\r
-= VW_MarkUpdateBlock\r
-=\r
-= Takes a pixel bounded block and marks the tiles in bufferblocks\r
-= Returns 0 if the entire block is off the buffer screen\r
-=\r
-=======================\r
-*/\r
-\r
-int VW_MarkUpdateBlock (int x1, int y1, int x2, int y2)\r
-{\r
-       int     x,y,xt1,yt1,xt2,yt2,nextline;\r
-       byte *mark;\r
-\r
-       xt1 = x1>>PIXTOBLOCK;\r
-       yt1 = y1>>PIXTOBLOCK;\r
-\r
-       xt2 = x2>>PIXTOBLOCK;\r
-       yt2 = y2>>PIXTOBLOCK;\r
-\r
-       if (xt1<0)\r
-               xt1=0;\r
-       else if (xt1>=UPDATEWIDE-1)\r
-               return 0;\r
-\r
-       if (yt1<0)\r
-               yt1=0;\r
-       else if (yt1>UPDATEHIGH)\r
-               return 0;\r
-\r
-       if (xt2<0)\r
-               return 0;\r
-       else if (xt2>=UPDATEWIDE-1)\r
-               xt2 = UPDATEWIDE-2;\r
-\r
-       if (yt2<0)\r
-               return 0;\r
-       else if (yt2>=UPDATEHIGH)\r
-               yt2 = UPDATEHIGH-1;\r
-\r
-       mark = updateptr + uwidthtable[yt1] + xt1;\r
-       nextline = UPDATEWIDE - (xt2-xt1) - 1;\r
-\r
-       for (y=yt1;y<=yt2;y++)\r
-       {\r
-               for (x=xt1;x<=xt2;x++)\r
-                       *mark++ = 1;                    // this tile will need to be updated\r
-\r
-               mark += nextline;\r
-       }\r
-\r
-       return 1;\r
-}\r
-\r
-\r
-/*\r
-===========================\r
-=\r
-= VW_UpdateScreen\r
-=\r
-= Updates any changed areas of the double buffer and displays the cursor\r
-=\r
-===========================\r
-*/\r
-\r
-void VW_UpdateScreen (void)\r
-{\r
-       if (cursorvisible>0)\r
-               VWL_DrawCursor();\r
-\r
-#if GRMODE == EGAGR\r
-       VWL_UpdateScreenBlocks();\r
-#endif\r
-#if GRMODE == CGAGR\r
-       VW_CGAFullUpdate();\r
-#endif\r
-\r
-       if (cursorvisible>0)\r
-               VWL_EraseCursor();\r
-}\r
-\r
-\r
-\r
-void VWB_DrawTile8 (int x, int y, int tile)\r
-{\r
-       x+=pansx;\r
-       y+=pansy;\r
-       if (VW_MarkUpdateBlock (x&SCREENXMASK,y,(x&SCREENXMASK)+7,y+7))\r
-               VW_DrawTile8 (x/SCREENXDIV,y,tile);\r
-}\r
-\r
-void VWB_DrawTile8M (int x, int y, int tile)\r
-{\r
-       int xb;\r
-\r
-       x+=pansx;\r
-       y+=pansy;\r
-       xb = x/SCREENXDIV;                      // use intermediate because VW_DT8M is macro\r
-       if (VW_MarkUpdateBlock (x&SCREENXMASK,y,(x&SCREENXMASK)+7,y+7))\r
-               VW_DrawTile8M (xb,y,tile);\r
-}\r
-\r
-void VWB_DrawTile16 (int x, int y, int tile)\r
-{\r
-       x+=pansx;\r
-       y+=pansy;\r
-       if (VW_MarkUpdateBlock (x&SCREENXMASK,y,(x&SCREENXMASK)+15,y+15))\r
-               VW_DrawTile16 (x/SCREENXDIV,y,tile);\r
-}\r
-\r
-void VWB_DrawTile16M (int x, int y, int tile)\r
-{\r
-       int xb;\r
-\r
-       x+=pansx;\r
-       y+=pansy;\r
-       xb = x/SCREENXDIV;              // use intermediate because VW_DT16M is macro\r
-       if (VW_MarkUpdateBlock (x&SCREENXMASK,y,(x&SCREENXMASK)+15,y+15))\r
-               VW_DrawTile16M (xb,y,tile);\r
-}\r
-\r
-#if NUMPICS\r
-void VWB_DrawPic (int x, int y, int chunknum)\r
-{\r
-// mostly copied from drawpic\r
-       int     picnum = chunknum - STARTPICS;\r
-       memptr source;\r
-       unsigned dest,width,height;\r
-\r
-       x+=pansx;\r
-       y+=pansy;\r
-       x/= SCREENXDIV;\r
-\r
-       source = grsegs[chunknum];\r
-       dest = ylookup[y]+x+bufferofs;\r
-       width = pictable[picnum].width;\r
-       height = pictable[picnum].height;\r
-\r
-       if (VW_MarkUpdateBlock (x*SCREENXDIV,y,(x+width)*SCREENXDIV-1,y+height-1))\r
-               VW_MemToScreen(source,dest,width,height);\r
-}\r
-#endif\r
-\r
-#if NUMPICM>0\r
-void VWB_DrawMPic(int x, int y, int chunknum)\r
-{\r
-// mostly copied from drawmpic\r
-       int     picnum = chunknum - STARTPICM;\r
-       memptr source;\r
-       unsigned dest,width,height;\r
-\r
-       x+=pansx;\r
-       y+=pansy;\r
-       x/=SCREENXDIV;\r
-\r
-       source = grsegs[chunknum];\r
-       dest = ylookup[y]+x+bufferofs;\r
-       width = picmtable[picnum].width;\r
-       height = picmtable[picnum].height;\r
-\r
-       if (VW_MarkUpdateBlock (x*SCREENXDIV,y,(x+width)*SCREENXDIV-1,y+height-1))\r
-               VW_MaskBlock(source,0,dest,width,height,width*height);\r
-}\r
-#endif\r
-\r
-\r
-void VWB_Bar (int x, int y, int width, int height, int color)\r
-{\r
-       x+=pansx;\r
-       y+=pansy;\r
-       if (VW_MarkUpdateBlock (x,y,x+width,y+height-1) )\r
-               VW_Bar (x,y,width,height,color);\r
-}\r
-\r
-\r
-#if NUMFONT\r
-void VWB_DrawPropString         (char far *string)\r
-{\r
-       int x,y;\r
-       x = px+pansx;\r
-       y = py+pansy;\r
-       VW_DrawPropString (string);\r
-       VW_MarkUpdateBlock(x,y,x+bufferwidth*8-1,y+bufferheight-1);\r
-}\r
-#endif\r
-\r
-\r
-#if NUMFONTM\r
-void VWB_DrawMPropString (char far *string)\r
-{\r
-       int x,y;\r
-       x = px+pansx;\r
-       y = py+pansy;\r
-       VW_DrawMPropString (string);\r
-       VW_MarkUpdateBlock(x,y,x+bufferwidth*8-1,y+bufferheight-1);\r
-}\r
-#endif\r
-\r
-#if NUMSPRITES\r
-void VWB_DrawSprite(int x, int y, int chunknum)\r
-{\r
-       spritetabletype far *spr;\r
-       spritetype _seg *block;\r
-       unsigned        dest,shift,width,height;\r
-\r
-       x+=pansx;\r
-       y+=pansy;\r
-\r
-       spr = &spritetable[chunknum-STARTSPRITES];\r
-       block = (spritetype _seg *)grsegs[chunknum];\r
-\r
-       y+=spr->orgy>>G_P_SHIFT;\r
-       x+=spr->orgx>>G_P_SHIFT;\r
-\r
-\r
-#if GRMODE == EGAGR\r
-       shift = (x&7)/2;\r
-#endif\r
-#if GRMODE == CGAGR\r
-       shift = 0;\r
-#endif\r
-\r
-       dest = bufferofs + ylookup[y];\r
-       if (x>=0)\r
-               dest += x/SCREENXDIV;\r
-       else\r
-               dest += (x+1)/SCREENXDIV;\r
-\r
-       width = block->width[shift];\r
-       height = spr->height;\r
-\r
-       if (VW_MarkUpdateBlock (x&SCREENXMASK,y,(x&SCREENXMASK)+width*SCREENXDIV-1\r
-               ,y+height-1))\r
-               VW_MaskBlock (block,block->sourceoffset[shift],dest,\r
-                       width,height,block->planesize[shift]);\r
-}\r
-#endif\r
-\r
-void VWB_Plot (int x, int y, int color)\r
-{\r
-       x+=pansx;\r
-       y+=pansy;\r
-       if (VW_MarkUpdateBlock (x,y,x,y))\r
-               VW_Plot(x,y,color);\r
-}\r
-\r
-void VWB_Hlin (int x1, int x2, int y, int color)\r
-{\r
-       x1+=pansx;\r
-       x2+=pansx;\r
-       y+=pansy;\r
-       if (VW_MarkUpdateBlock (x1,y,x2,y))\r
-               VW_Hlin(x1,x2,y,color);\r
-}\r
-\r
-void VWB_Vlin (int y1, int y2, int x, int color)\r
-{\r
-       x+=pansx;\r
-       y1+=pansy;\r
-       y2+=pansy;\r
-       if (VW_MarkUpdateBlock (x,y1,x,y2))\r
-               VW_Vlin(y1,y2,x,color);\r
-}\r
-\r
-\r
-//===========================================================================\r