--- /dev/null
+// ID_VL.C\r
+\r
+#include <dos.h>\r
+#include <alloc.h>\r
+#include <mem.h>\r
+#include <string.h>\r
+#include "ID_HEAD.H"\r
+#include "ID_VL.H"\r
+#pragma hdrstop\r
+\r
+//\r
+// SC_INDEX is expected to stay at SC_MAPMASK for proper operation\r
+//\r
+\r
+unsigned bufferofs;\r
+unsigned displayofs,pelpan;\r
+\r
+unsigned screenseg=SCREENSEG; // set to 0xa000 for asm convenience\r
+\r
+unsigned linewidth;\r
+unsigned ylookup[MAXSCANLINES];\r
+\r
+boolean screenfaded;\r
+unsigned bordercolor;\r
+\r
+boolean fastpalette; // if true, use outsb to set\r
+\r
+byte far palette1[256][3],far palette2[256][3];\r
+\r
+//===========================================================================\r
+\r
+// asm\r
+\r
+int VL_VideoID (void);\r
+void VL_SetCRTC (int crtc);\r
+void VL_SetScreen (int crtc, int pelpan);\r
+void VL_WaitVBL (int vbls);\r
+\r
+//===========================================================================\r
+\r
+\r
+/*\r
+=======================\r
+=\r
+= VL_Startup\r
+=\r
+=======================\r
+*/\r
+\r
+#if 0\r
+void VL_Startup (void)\r
+{\r
+ if ( !MS_CheckParm ("HIDDENCARD") && VL_VideoID () != 5)\r
+ MS_Quit ("You need a VGA graphics card to run this!");\r
+\r
+ asm cld; // all string instructions assume forward\r
+}\r
+\r
+#endif\r
+\r
+/*\r
+=======================\r
+=\r
+= VL_Startup // WOLFENSTEIN HACK\r
+=\r
+=======================\r
+*/\r
+\r
+static char *ParmStrings[] = {"HIDDENCARD",""};\r
+\r
+void VL_Startup (void)\r
+{\r
+ int i,videocard;\r
+\r
+ asm cld;\r
+\r
+ videocard = VL_VideoID ();\r
+ for (i = 1;i < _argc;i++)\r
+ if (US_CheckParm(_argv[i],ParmStrings) == 0)\r
+ {\r
+ videocard = 5;\r
+ break;\r
+ }\r
+\r
+ if (videocard != 5)\r
+Quit ("Improper video card! If you really have a VGA card that I am not \n"\r
+ "detecting, use the -HIDDENCARD command line parameter!");\r
+\r
+}\r
+\r
+\r
+\r
+/*\r
+=======================\r
+=\r
+= VL_Shutdown\r
+=\r
+=======================\r
+*/\r
+\r
+void VL_Shutdown (void)\r
+{\r
+ VL_SetTextMode ();\r
+}\r
+\r
+\r
+/*\r
+=======================\r
+=\r
+= VL_SetVGAPlaneMode\r
+=\r
+=======================\r
+*/\r
+\r
+void VL_SetVGAPlaneMode (void)\r
+{\r
+asm mov ax,0x13\r
+asm int 0x10\r
+ VL_DePlaneVGA ();\r
+ VGAMAPMASK(15);\r
+ VL_SetLineWidth (40);\r
+}\r
+\r
+\r
+/*\r
+=======================\r
+=\r
+= VL_SetTextMode\r
+=\r
+=======================\r
+*/\r
+\r
+void VL_SetTextMode (void)\r
+{\r
+asm mov ax,3\r
+asm int 0x10\r
+}\r
+\r
+//===========================================================================\r
+\r
+/*\r
+=================\r
+=\r
+= VL_ClearVideo\r
+=\r
+= Fill the entire video buffer with a given color\r
+=\r
+=================\r
+*/\r
+\r
+void VL_ClearVideo (byte color)\r
+{\r
+asm mov dx,GC_INDEX\r
+asm mov al,GC_MODE\r
+asm out dx,al\r
+asm inc dx\r
+asm in al,dx\r
+asm and al,0xfc // write mode 0 to store directly to video\r
+asm out dx,al\r
+\r
+asm mov dx,SC_INDEX\r
+asm mov ax,SC_MAPMASK+15*256\r
+asm out dx,ax // write through all four planes\r
+\r
+asm mov ax,SCREENSEG\r
+asm mov es,ax\r
+asm mov al,[color]\r
+asm mov ah,al\r
+asm mov cx,0x8000 // 0x8000 words, clearing 8 video bytes/word\r
+asm xor di,di\r
+asm rep stosw\r
+}\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+ VGA REGISTER MANAGEMENT ROUTINES\r
+\r
+=============================================================================\r
+*/\r
+\r
+\r
+/*\r
+=================\r
+=\r
+= VL_DePlaneVGA\r
+=\r
+=================\r
+*/\r
+\r
+void VL_DePlaneVGA (void)\r
+{\r
+\r
+//\r
+// change CPU addressing to non linear mode\r
+//\r
+\r
+//\r
+// turn off chain 4 and odd/even\r
+//\r
+ outportb (SC_INDEX,SC_MEMMODE);\r
+ outportb (SC_INDEX+1,(inportb(SC_INDEX+1)&~8)|4);\r
+\r
+ outportb (SC_INDEX,SC_MAPMASK); // leave this set throughought\r
+\r
+//\r
+// turn off odd/even and set write mode 0\r
+//\r
+ outportb (GC_INDEX,GC_MODE);\r
+ outportb (GC_INDEX+1,inportb(GC_INDEX+1)&~0x13);\r
+\r
+//\r
+// turn off chain\r
+//\r
+ outportb (GC_INDEX,GC_MISCELLANEOUS);\r
+ outportb (GC_INDEX+1,inportb(GC_INDEX+1)&~2);\r
+\r
+//\r
+// clear the entire buffer space, because int 10h only did 16 k / plane\r
+//\r
+ VL_ClearVideo (0);\r
+\r
+//\r
+// change CRTC scanning from doubleword to byte mode, allowing >64k scans\r
+//\r
+ outportb (CRTC_INDEX,CRTC_UNDERLINE);\r
+ outportb (CRTC_INDEX+1,inportb(CRTC_INDEX+1)&~0x40);\r
+\r
+ outportb (CRTC_INDEX,CRTC_MODE);\r
+ outportb (CRTC_INDEX+1,inportb(CRTC_INDEX+1)|0x40);\r
+}\r
+\r
+//===========================================================================\r
+\r
+/*\r
+====================\r
+=\r
+= VL_SetLineWidth\r
+=\r
+= Line witdh is in WORDS, 40 words is normal width for vgaplanegr\r
+=\r
+====================\r
+*/\r
+\r
+void VL_SetLineWidth (unsigned width)\r
+{\r
+ int i,offset;\r
+\r
+//\r
+// set wide virtual screen\r
+//\r
+ outport (CRTC_INDEX,CRTC_OFFSET+width*256);\r
+\r
+//\r
+// set up lookup tables\r
+//\r
+ linewidth = width*2;\r
+\r
+ offset = 0;\r
+\r
+ for (i=0;i<MAXSCANLINES;i++)\r
+ {\r
+ ylookup[i]=offset;\r
+ offset += linewidth;\r
+ }\r
+}\r
+\r
+/*\r
+====================\r
+=\r
+= VL_SetSplitScreen\r
+=\r
+====================\r
+*/\r
+\r
+void VL_SetSplitScreen (int linenum)\r
+{\r
+ VL_WaitVBL (1);\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
+ outportb (CRTC_INDEX,CRTC_MAXSCANLINE);\r
+ outportb (CRTC_INDEX+1,inportb(CRTC_INDEX+1) & (255-64));\r
+}\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+ PALETTE OPS\r
+\r
+ To avoid snow, do a WaitVBL BEFORE calling these\r
+\r
+=============================================================================\r
+*/\r
+\r
+\r
+/*\r
+=================\r
+=\r
+= VL_FillPalette\r
+=\r
+=================\r
+*/\r
+\r
+void VL_FillPalette (int red, int green, int blue)\r
+{\r
+ int i;\r
+\r
+ outportb (PEL_WRITE_ADR,0);\r
+ for (i=0;i<256;i++)\r
+ {\r
+ outportb (PEL_DATA,red);\r
+ outportb (PEL_DATA,green);\r
+ outportb (PEL_DATA,blue);\r
+ }\r
+}\r
+\r
+//===========================================================================\r
+\r
+/*\r
+=================\r
+=\r
+= VL_SetColor\r
+=\r
+=================\r
+*/\r
+\r
+void VL_SetColor (int color, int red, int green, int blue)\r
+{\r
+ outportb (PEL_WRITE_ADR,color);\r
+ outportb (PEL_DATA,red);\r
+ outportb (PEL_DATA,green);\r
+ outportb (PEL_DATA,blue);\r
+}\r
+\r
+//===========================================================================\r
+\r
+/*\r
+=================\r
+=\r
+= VL_GetColor\r
+=\r
+=================\r
+*/\r
+\r
+void VL_GetColor (int color, int *red, int *green, int *blue)\r
+{\r
+ outportb (PEL_READ_ADR,color);\r
+ *red = inportb (PEL_DATA);\r
+ *green = inportb (PEL_DATA);\r
+ *blue = inportb (PEL_DATA);\r
+}\r
+\r
+//===========================================================================\r
+\r
+/*\r
+=================\r
+=\r
+= VL_SetPalette\r
+=\r
+= If fast palette setting has been tested for, it is used\r
+= (some cards don't like outsb palette setting)\r
+=\r
+=================\r
+*/\r
+\r
+void VL_SetPalette (byte far *palette)\r
+{\r
+ int i;\r
+\r
+// outportb (PEL_WRITE_ADR,0);\r
+// for (i=0;i<768;i++)\r
+// outportb(PEL_DATA,*palette++);\r
+\r
+ asm mov dx,PEL_WRITE_ADR\r
+ asm mov al,0\r
+ asm out dx,al\r
+ asm mov dx,PEL_DATA\r
+ asm lds si,[palette]\r
+\r
+ asm test [ss:fastpalette],1\r
+ asm jz slowset\r
+//\r
+// set palette fast for cards that can take it\r
+//\r
+ asm mov cx,768\r
+ asm rep outsb\r
+ asm jmp done\r
+\r
+//\r
+// set palette slowly for some video cards\r
+//\r
+slowset:\r
+ asm mov cx,256\r
+setloop:\r
+ asm lodsb\r
+ asm out dx,al\r
+ asm lodsb\r
+ asm out dx,al\r
+ asm lodsb\r
+ asm out dx,al\r
+ asm loop setloop\r
+\r
+done:\r
+ asm mov ax,ss\r
+ asm mov ds,ax\r
+\r
+}\r
+\r
+\r
+//===========================================================================\r
+\r
+/*\r
+=================\r
+=\r
+= VL_GetPalette\r
+=\r
+= This does not use the port string instructions,\r
+= due to some incompatabilities\r
+=\r
+=================\r
+*/\r
+\r
+void VL_GetPalette (byte far *palette)\r
+{\r
+ int i;\r
+\r
+ outportb (PEL_READ_ADR,0);\r
+ for (i=0;i<768;i++)\r
+ *palette++ = inportb(PEL_DATA);\r
+}\r
+\r
+\r
+//===========================================================================\r
+\r
+/*\r
+=================\r
+=\r
+= VL_FadeOut\r
+=\r
+= Fades the current palette to the given color in the given number of steps\r
+=\r
+=================\r
+*/\r
+\r
+void VL_FadeOut (int start, int end, int red, int green, int blue, int steps)\r
+{\r
+ int i,j,orig,delta;\r
+ byte far *origptr, far *newptr;\r
+\r
+ VL_WaitVBL(1);\r
+ VL_GetPalette (&palette1[0][0]);\r
+ _fmemcpy (palette2,palette1,768);\r
+\r
+//\r
+// fade through intermediate frames\r
+//\r
+ for (i=0;i<steps;i++)\r
+ {\r
+ origptr = &palette1[start][0];\r
+ newptr = &palette2[start][0];\r
+ for (j=start;j<=end;j++)\r
+ {\r
+ orig = *origptr++;\r
+ delta = red-orig;\r
+ *newptr++ = orig + delta * i / steps;\r
+ orig = *origptr++;\r
+ delta = green-orig;\r
+ *newptr++ = orig + delta * i / steps;\r
+ orig = *origptr++;\r
+ delta = blue-orig;\r
+ *newptr++ = orig + delta * i / steps;\r
+ }\r
+\r
+ VL_WaitVBL(1);\r
+ VL_SetPalette (&palette2[0][0]);\r
+ }\r
+\r
+//\r
+// final color\r
+//\r
+ VL_FillPalette (red,green,blue);\r
+\r
+ screenfaded = true;\r
+}\r
+\r
+\r
+/*\r
+=================\r
+=\r
+= VL_FadeIn\r
+=\r
+=================\r
+*/\r
+\r
+void VL_FadeIn (int start, int end, byte far *palette, int steps)\r
+{\r
+ int i,j,delta;\r
+\r
+ VL_WaitVBL(1);\r
+ VL_GetPalette (&palette1[0][0]);\r
+ _fmemcpy (&palette2[0][0],&palette1[0][0],sizeof(palette1));\r
+\r
+ start *= 3;\r
+ end = end*3+2;\r
+\r
+//\r
+// fade through intermediate frames\r
+//\r
+ for (i=0;i<steps;i++)\r
+ {\r
+ for (j=start;j<=end;j++)\r
+ {\r
+ delta = palette[j]-palette1[0][j];\r
+ palette2[0][j] = palette1[0][j] + delta * i / steps;\r
+ }\r
+\r
+ VL_WaitVBL(1);\r
+ VL_SetPalette (&palette2[0][0]);\r
+ }\r
+\r
+//\r
+// final color\r
+//\r
+ VL_SetPalette (palette);\r
+ screenfaded = false;\r
+}\r
+\r
+\r
+\r
+/*\r
+=================\r
+=\r
+= VL_TestPaletteSet\r
+=\r
+= Sets the palette with outsb, then reads it in and compares\r
+= If it compares ok, fastpalette is set to true.\r
+=\r
+=================\r
+*/\r
+\r
+void VL_TestPaletteSet (void)\r
+{\r
+ int i;\r
+\r
+ for (i=0;i<768;i++)\r
+ palette1[0][i] = i;\r
+\r
+ fastpalette = true;\r
+ VL_SetPalette (&palette1[0][0]);\r
+ VL_GetPalette (&palette2[0][0]);\r
+ if (_fmemcmp (&palette1[0][0],&palette2[0][0],768))\r
+ fastpalette = false;\r
+}\r
+\r
+\r
+/*\r
+==================\r
+=\r
+= VL_ColorBorder\r
+=\r
+==================\r
+*/\r
+\r
+void VL_ColorBorder (int color)\r
+{\r
+ _AH=0x10;\r
+ _AL=1;\r
+ _BH=color;\r
+ geninterrupt (0x10);\r
+ bordercolor = color;\r
+}\r
+\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+ PIXEL OPS\r
+\r
+=============================================================================\r
+*/\r
+\r
+byte pixmasks[4] = {1,2,4,8};\r
+byte leftmasks[4] = {15,14,12,8};\r
+byte rightmasks[4] = {1,3,7,15};\r
+\r
+\r
+/*\r
+=================\r
+=\r
+= VL_Plot\r
+=\r
+=================\r
+*/\r
+\r
+void VL_Plot (int x, int y, int color)\r
+{\r
+ byte mask;\r
+\r
+ mask = pixmasks[x&3];\r
+ VGAMAPMASK(mask);\r
+ *(byte far *)MK_FP(SCREENSEG,bufferofs+(ylookup[y]+(x>>2))) = color;\r
+ VGAMAPMASK(15);\r
+}\r
+\r
+\r
+/*\r
+=================\r
+=\r
+= VL_Hlin\r
+=\r
+=================\r
+*/\r
+\r
+void VL_Hlin (unsigned x, unsigned y, unsigned width, unsigned color)\r
+{\r
+ unsigned xbyte;\r
+ byte far *dest;\r
+ byte leftmask,rightmask;\r
+ int midbytes;\r
+\r
+ xbyte = x>>2;\r
+ leftmask = leftmasks[x&3];\r
+ rightmask = rightmasks[(x+width-1)&3];\r
+ midbytes = ((x+width+3)>>2) - xbyte - 2;\r
+\r
+ dest = MK_FP(SCREENSEG,bufferofs+ylookup[y]+xbyte);\r
+\r
+ if (midbytes<0)\r
+ {\r
+ // all in one byte\r
+ VGAMAPMASK(leftmask&rightmask);\r
+ *dest = color;\r
+ VGAMAPMASK(15);\r
+ return;\r
+ }\r
+\r
+ VGAMAPMASK(leftmask);\r
+ *dest++ = color;\r
+\r
+ VGAMAPMASK(15);\r
+ _fmemset (dest,color,midbytes);\r
+ dest+=midbytes;\r
+\r
+ VGAMAPMASK(rightmask);\r
+ *dest = color;\r
+\r
+ VGAMAPMASK(15);\r
+}\r
+\r
+\r
+/*\r
+=================\r
+=\r
+= VL_Vlin\r
+=\r
+=================\r
+*/\r
+\r
+void VL_Vlin (int x, int y, int height, int color)\r
+{\r
+ byte far *dest,mask;\r
+\r
+ mask = pixmasks[x&3];\r
+ VGAMAPMASK(mask);\r
+\r
+ dest = MK_FP(SCREENSEG,bufferofs+ylookup[y]+(x>>2));\r
+\r
+ while (height--)\r
+ {\r
+ *dest = color;\r
+ dest += linewidth;\r
+ }\r
+\r
+ VGAMAPMASK(15);\r
+}\r
+\r
+\r
+/*\r
+=================\r
+=\r
+= VL_Bar\r
+=\r
+=================\r
+*/\r
+\r
+void VL_Bar (int x, int y, int width, int height, int color)\r
+{\r
+ byte far *dest;\r
+ byte leftmask,rightmask;\r
+ int midbytes,linedelta;\r
+\r
+ leftmask = leftmasks[x&3];\r
+ rightmask = rightmasks[(x+width-1)&3];\r
+ midbytes = ((x+width+3)>>2) - (x>>2) - 2;\r
+ linedelta = linewidth-(midbytes+1);\r
+\r
+ dest = MK_FP(SCREENSEG,bufferofs+ylookup[y]+(x>>2));\r
+\r
+ if (midbytes<0)\r
+ {\r
+ // all in one byte\r
+ VGAMAPMASK(leftmask&rightmask);\r
+ while (height--)\r
+ {\r
+ *dest = color;\r
+ dest += linewidth;\r
+ }\r
+ VGAMAPMASK(15);\r
+ return;\r
+ }\r
+\r
+ while (height--)\r
+ {\r
+ VGAMAPMASK(leftmask);\r
+ *dest++ = color;\r
+\r
+ VGAMAPMASK(15);\r
+ _fmemset (dest,color,midbytes);\r
+ dest+=midbytes;\r
+\r
+ VGAMAPMASK(rightmask);\r
+ *dest = color;\r
+\r
+ dest+=linedelta;\r
+ }\r
+\r
+ VGAMAPMASK(15);\r
+}\r
+\r
+/*\r
+============================================================================\r
+\r
+ MEMORY OPS\r
+\r
+============================================================================\r
+*/\r
+\r
+/*\r
+=================\r
+=\r
+= VL_MemToLatch\r
+=\r
+=================\r
+*/\r
+\r
+void VL_MemToLatch (byte far *source, int width, int height, unsigned dest)\r
+{\r
+ unsigned count;\r
+ byte plane,mask;\r
+\r
+ count = ((width+3)/4)*height;\r
+ mask = 1;\r
+ for (plane = 0; plane<4 ; plane++)\r
+ {\r
+ VGAMAPMASK(mask);\r
+ mask <<= 1;\r
+\r
+asm mov cx,count\r
+asm mov ax,SCREENSEG\r
+asm mov es,ax\r
+asm mov di,[dest]\r
+asm lds si,[source]\r
+asm rep movsb\r
+asm mov ax,ss\r
+asm mov ds,ax\r
+\r
+ source+= count;\r
+ }\r
+}\r
+\r
+\r
+//===========================================================================\r
+\r
+\r
+/*\r
+=================\r
+=\r
+= VL_MemToScreen\r
+=\r
+= Draws a block of data to the screen.\r
+=\r
+=================\r
+*/\r
+\r
+void VL_MemToScreen (byte far *source, int width, int height, int x, int y)\r
+{\r
+ byte far *screen,far *dest,mask;\r
+ int plane;\r
+\r
+ width>>=2;\r
+ dest = MK_FP(SCREENSEG,bufferofs+ylookup[y]+(x>>2) );\r
+ mask = 1 << (x&3);\r
+\r
+ for (plane = 0; plane<4; plane++)\r
+ {\r
+ VGAMAPMASK(mask);\r
+ mask <<= 1;\r
+ if (mask == 16)\r
+ mask = 1;\r
+\r
+ screen = dest;\r
+ for (y=0;y<height;y++,screen+=linewidth,source+=width)\r
+ _fmemcpy (screen,source,width);\r
+ }\r
+}\r
+\r
+//==========================================================================\r
+\r
+\r
+/*\r
+=================\r
+=\r
+= VL_MaskedToScreen\r
+=\r
+= Masks a block of main memory to the screen.\r
+=\r
+=================\r
+*/\r
+\r
+void VL_MaskedToScreen (byte far *source, int width, int height, int x, int y)\r
+{\r
+ byte far *screen,far *dest,mask;\r
+ byte far *maskptr;\r
+ int plane;\r
+\r
+ width>>=2;\r
+ dest = MK_FP(SCREENSEG,bufferofs+ylookup[y]+(x>>2) );\r
+// mask = 1 << (x&3);\r
+\r
+// maskptr = source;\r
+\r
+ for (plane = 0; plane<4; plane++)\r
+ {\r
+ VGAMAPMASK(mask);\r
+ mask <<= 1;\r
+ if (mask == 16)\r
+ mask = 1;\r
+\r
+ screen = dest;\r
+ for (y=0;y<height;y++,screen+=linewidth,source+=width)\r
+ _fmemcpy (screen,source,width);\r
+ }\r
+}\r
+\r
+//==========================================================================\r
+\r
+/*\r
+=================\r
+=\r
+= VL_LatchToScreen\r
+=\r
+=================\r
+*/\r
+\r
+void VL_LatchToScreen (unsigned source, int width, int height, int x, int y)\r
+{\r
+ VGAWRITEMODE(1);\r
+ VGAMAPMASK(15);\r
+\r
+asm mov di,[y] // dest = bufferofs+ylookup[y]+(x>>2)\r
+asm shl di,1\r
+asm mov di,[WORD PTR ylookup+di]\r
+asm add di,[bufferofs]\r
+asm mov ax,[x]\r
+asm shr ax,1\r
+asm shr ax,1\r
+asm add di,ax\r
+\r
+asm mov si,[source]\r
+asm mov ax,[width]\r
+asm mov bx,[linewidth]\r
+asm sub bx,ax\r
+asm mov dx,[height]\r
+asm mov cx,SCREENSEG\r
+asm mov ds,cx\r
+asm mov es,cx\r
+\r
+drawline:\r
+asm mov cx,ax\r
+asm rep movsb\r
+asm add di,bx\r
+asm dec dx\r
+asm jnz drawline\r
+\r
+asm mov ax,ss\r
+asm mov ds,ax\r
+\r
+ VGAWRITEMODE(0);\r
+}\r
+\r
+\r
+//===========================================================================\r
+\r
+#if 0\r
+\r
+/*\r
+=================\r
+=\r
+= VL_ScreenToScreen\r
+=\r
+=================\r
+*/\r
+\r
+void VL_ScreenToScreen (unsigned source, unsigned dest,int width, int height)\r
+{\r
+ VGAWRITEMODE(1);\r
+ VGAMAPMASK(15);\r
+\r
+asm mov si,[source]\r
+asm mov di,[dest]\r
+asm mov ax,[width]\r
+asm mov bx,[linewidth]\r
+asm sub bx,ax\r
+asm mov dx,[height]\r
+asm mov cx,SCREENSEG\r
+asm mov ds,cx\r
+asm mov es,cx\r
+\r
+drawline:\r
+asm mov cx,ax\r
+asm rep movsb\r
+asm add si,bx\r
+asm add di,bx\r
+asm dec dx\r
+asm jnz drawline\r
+\r
+asm mov ax,ss\r
+asm mov ds,ax\r
+\r
+ VGAWRITEMODE(0);\r
+}\r
+\r
+\r
+#endif\r
+\r
+/*\r
+=============================================================================\r
+\r
+ STRING OUTPUT ROUTINES\r
+\r
+=============================================================================\r
+*/\r
+\r
+\r
+\r
+\r
+/*\r
+===================\r
+=\r
+= VL_DrawTile8String\r
+=\r
+===================\r
+*/\r
+\r
+void VL_DrawTile8String (char *str, char far *tile8ptr, int printx, int printy)\r
+{\r
+ int i;\r
+ unsigned far *dest,far *screen,far *src;\r
+\r
+ dest = MK_FP(SCREENSEG,bufferofs+ylookup[printy]+(printx>>2));\r
+\r
+ while (*str)\r
+ {\r
+ src = (unsigned far *)(tile8ptr + (*str<<6));\r
+ // each character is 64 bytes\r
+\r
+ VGAMAPMASK(1);\r
+ screen = dest;\r
+ for (i=0;i<8;i++,screen+=linewidth)\r
+ *screen = *src++;\r
+ VGAMAPMASK(2);\r
+ screen = dest;\r
+ for (i=0;i<8;i++,screen+=linewidth)\r
+ *screen = *src++;\r
+ VGAMAPMASK(4);\r
+ screen = dest;\r
+ for (i=0;i<8;i++,screen+=linewidth)\r
+ *screen = *src++;\r
+ VGAMAPMASK(8);\r
+ screen = dest;\r
+ for (i=0;i<8;i++,screen+=linewidth)\r
+ *screen = *src++;\r
+\r
+ str++;\r
+ printx += 8;\r
+ dest+=2;\r
+ }\r
+}\r
+\r
+\r
+\r
+/*\r
+===================\r
+=\r
+= VL_DrawLatch8String\r
+=\r
+===================\r
+*/\r
+\r
+void VL_DrawLatch8String (char *str, unsigned tile8ptr, int printx, int printy)\r
+{\r
+ int i;\r
+ unsigned src,dest;\r
+\r
+ dest = bufferofs+ylookup[printy]+(printx>>2);\r
+\r
+ VGAWRITEMODE(1);\r
+ VGAMAPMASK(15);\r
+\r
+ while (*str)\r
+ {\r
+ src = tile8ptr + (*str<<4); // each character is 16 latch bytes\r
+\r
+asm mov si,[src]\r
+asm mov di,[dest]\r
+asm mov dx,[linewidth]\r
+\r
+asm mov ax,SCREENSEG\r
+asm mov ds,ax\r
+\r
+asm lodsw\r
+asm mov [di],ax\r
+asm add di,dx\r
+asm lodsw\r
+asm mov [di],ax\r
+asm add di,dx\r
+asm lodsw\r
+asm mov [di],ax\r
+asm add di,dx\r
+asm lodsw\r
+asm mov [di],ax\r
+asm add di,dx\r
+asm lodsw\r
+asm mov [di],ax\r
+asm add di,dx\r
+asm lodsw\r
+asm mov [di],ax\r
+asm add di,dx\r
+asm lodsw\r
+asm mov [di],ax\r
+asm add di,dx\r
+asm lodsw\r
+asm mov [di],ax\r
+asm add di,dx\r
+\r
+asm mov ax,ss\r
+asm mov ds,ax\r
+\r
+ str++;\r
+ printx += 8;\r
+ dest+=2;\r
+ }\r
+\r
+ VGAWRITEMODE(0);\r
+}\r
+\r
+\r
+/*\r
+===================\r
+=\r
+= VL_SizeTile8String\r
+=\r
+===================\r
+*/\r
+\r
+void VL_SizeTile8String (char *str, int *width, int *height)\r
+{\r
+ *height = 8;\r
+ *width = 8*strlen(str);\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r