// ID_VL.C #include #include #include #include #include "ID_HEAD.H" #include "ID_VL.H" #pragma hdrstop // // SC_INDEX is expected to stay at SC_MAPMASK for proper operation // unsigned bufferofs; unsigned displayofs,pelpan; unsigned screenseg=SCREENSEG; // set to 0xa000 for asm convenience unsigned linewidth; unsigned ylookup[MAXSCANLINES]; boolean screenfaded; unsigned bordercolor; boolean fastpalette; // if true, use outsb to set byte far palette1[256][3],far palette2[256][3]; //=========================================================================== // asm int VL_VideoID (void); void VL_SetCRTC (int crtc); void VL_SetScreen (int crtc, int pelpan); void VL_WaitVBL (int vbls); //=========================================================================== /* ======================= = = VL_Startup = ======================= */ #if 0 void VL_Startup (void) { if ( !MS_CheckParm ("HIDDENCARD") && VL_VideoID () != 5) MS_Quit ("You need a VGA graphics card to run this!"); asm cld; // all string instructions assume forward } #endif /* ======================= = = VL_Startup // WOLFENSTEIN HACK = ======================= */ static char *ParmStrings[] = {"HIDDENCARD",""}; void VL_Startup (void) { int i,videocard; asm cld; videocard = VL_VideoID (); for (i = 1;i < _argc;i++) if (US_CheckParm(_argv[i],ParmStrings) == 0) { videocard = 5; break; } if (videocard != 5) Quit ("Improper video card! If you really have a VGA card that I am not \n" "detecting, use the -HIDDENCARD command line parameter!"); } /* ======================= = = VL_Shutdown = ======================= */ void VL_Shutdown (void) { VL_SetTextMode (); } /* ======================= = = VL_SetVGAPlaneMode = ======================= */ void VL_SetVGAPlaneMode (void) { asm mov ax,0x13 asm int 0x10 VL_DePlaneVGA (); VGAMAPMASK(15); VL_SetLineWidth (40); } /* ======================= = = VL_SetTextMode = ======================= */ void VL_SetTextMode (void) { asm mov ax,3 asm int 0x10 } //=========================================================================== /* ================= = = VL_ClearVideo = = Fill the entire video buffer with a given color = ================= */ void VL_ClearVideo (byte color) { asm mov dx,GC_INDEX asm mov al,GC_MODE asm out dx,al asm inc dx asm in al,dx asm and al,0xfc // write mode 0 to store directly to video asm out dx,al asm mov dx,SC_INDEX asm mov ax,SC_MAPMASK+15*256 asm out dx,ax // write through all four planes asm mov ax,SCREENSEG asm mov es,ax asm mov al,[color] asm mov ah,al asm mov cx,0x8000 // 0x8000 words, clearing 8 video bytes/word asm xor di,di asm rep stosw } /* ============================================================================= VGA REGISTER MANAGEMENT ROUTINES ============================================================================= */ /* ================= = = VL_DePlaneVGA = ================= */ void VL_DePlaneVGA (void) { // // change CPU addressing to non linear mode // // // turn off chain 4 and odd/even // outportb (SC_INDEX,SC_MEMMODE); outportb (SC_INDEX+1,(inportb(SC_INDEX+1)&~8)|4); outportb (SC_INDEX,SC_MAPMASK); // leave this set throughought // // turn off odd/even and set write mode 0 // outportb (GC_INDEX,GC_MODE); outportb (GC_INDEX+1,inportb(GC_INDEX+1)&~0x13); // // turn off chain // outportb (GC_INDEX,GC_MISCELLANEOUS); outportb (GC_INDEX+1,inportb(GC_INDEX+1)&~2); // // clear the entire buffer space, because int 10h only did 16 k / plane // VL_ClearVideo (0); // // change CRTC scanning from doubleword to byte mode, allowing >64k scans // outportb (CRTC_INDEX,CRTC_UNDERLINE); outportb (CRTC_INDEX+1,inportb(CRTC_INDEX+1)&~0x40); outportb (CRTC_INDEX,CRTC_MODE); outportb (CRTC_INDEX+1,inportb(CRTC_INDEX+1)|0x40); } //=========================================================================== /* ==================== = = VL_SetLineWidth = = Line witdh is in WORDS, 40 words is normal width for vgaplanegr = ==================== */ void VL_SetLineWidth (unsigned width) { int i,offset; // // set wide virtual screen // outport (CRTC_INDEX,CRTC_OFFSET+width*256); // // set up lookup tables // linewidth = width*2; offset = 0; for (i=0;i>2))) = color; VGAMAPMASK(15); } /* ================= = = VL_Hlin = ================= */ void VL_Hlin (unsigned x, unsigned y, unsigned width, unsigned color) { unsigned xbyte; byte far *dest; byte leftmask,rightmask; int midbytes; xbyte = x>>2; leftmask = leftmasks[x&3]; rightmask = rightmasks[(x+width-1)&3]; midbytes = ((x+width+3)>>2) - xbyte - 2; dest = MK_FP(SCREENSEG,bufferofs+ylookup[y]+xbyte); if (midbytes<0) { // all in one byte VGAMAPMASK(leftmask&rightmask); *dest = color; VGAMAPMASK(15); return; } VGAMAPMASK(leftmask); *dest++ = color; VGAMAPMASK(15); _fmemset (dest,color,midbytes); dest+=midbytes; VGAMAPMASK(rightmask); *dest = color; VGAMAPMASK(15); } /* ================= = = VL_Vlin = ================= */ void VL_Vlin (int x, int y, int height, int color) { byte far *dest,mask; mask = pixmasks[x&3]; VGAMAPMASK(mask); dest = MK_FP(SCREENSEG,bufferofs+ylookup[y]+(x>>2)); while (height--) { *dest = color; dest += linewidth; } VGAMAPMASK(15); } /* ================= = = VL_Bar = ================= */ void VL_Bar (int x, int y, int width, int height, int color) { byte far *dest; byte leftmask,rightmask; int midbytes,linedelta; leftmask = leftmasks[x&3]; rightmask = rightmasks[(x+width-1)&3]; midbytes = ((x+width+3)>>2) - (x>>2) - 2; linedelta = linewidth-(midbytes+1); dest = MK_FP(SCREENSEG,bufferofs+ylookup[y]+(x>>2)); if (midbytes<0) { // all in one byte VGAMAPMASK(leftmask&rightmask); while (height--) { *dest = color; dest += linewidth; } VGAMAPMASK(15); return; } while (height--) { VGAMAPMASK(leftmask); *dest++ = color; VGAMAPMASK(15); _fmemset (dest,color,midbytes); dest+=midbytes; VGAMAPMASK(rightmask); *dest = color; dest+=linedelta; } VGAMAPMASK(15); } /* ============================================================================ MEMORY OPS ============================================================================ */ /* ================= = = VL_MemToLatch = ================= */ void VL_MemToLatch (byte far *source, int width, int height, unsigned dest) { unsigned count; byte plane,mask; count = ((width+3)/4)*height; mask = 1; for (plane = 0; plane<4 ; plane++) { VGAMAPMASK(mask); mask <<= 1; asm mov cx,count asm mov ax,SCREENSEG asm mov es,ax asm mov di,[dest] asm lds si,[source] asm rep movsb asm mov ax,ss asm mov ds,ax source+= count; } } //=========================================================================== /* ================= = = VL_MemToScreen = = Draws a block of data to the screen. = ================= */ void VL_MemToScreen (byte far *source, int width, int height, int x, int y) { byte far *screen,far *dest,mask; int plane; width>>=2; dest = MK_FP(SCREENSEG,bufferofs+ylookup[y]+(x>>2) ); mask = 1 << (x&3); for (plane = 0; plane<4; plane++) { VGAMAPMASK(mask); mask <<= 1; if (mask == 16) mask = 1; screen = dest; for (y=0;y>=2; dest = MK_FP(SCREENSEG,bufferofs+ylookup[y]+(x>>2) ); // mask = 1 << (x&3); // maskptr = source; for (plane = 0; plane<4; plane++) { VGAMAPMASK(mask); mask <<= 1; if (mask == 16) mask = 1; screen = dest; for (y=0;y>2) asm shl di,1 asm mov di,[WORD PTR ylookup+di] asm add di,[bufferofs] asm mov ax,[x] asm shr ax,1 asm shr ax,1 asm add di,ax asm mov si,[source] asm mov ax,[width] asm mov bx,[linewidth] asm sub bx,ax asm mov dx,[height] asm mov cx,SCREENSEG asm mov ds,cx asm mov es,cx drawline: asm mov cx,ax asm rep movsb asm add di,bx asm dec dx asm jnz drawline asm mov ax,ss asm mov ds,ax VGAWRITEMODE(0); } //=========================================================================== #if 0 /* ================= = = VL_ScreenToScreen = ================= */ void VL_ScreenToScreen (unsigned source, unsigned dest,int width, int height) { VGAWRITEMODE(1); VGAMAPMASK(15); asm mov si,[source] asm mov di,[dest] asm mov ax,[width] asm mov bx,[linewidth] asm sub bx,ax asm mov dx,[height] asm mov cx,SCREENSEG asm mov ds,cx asm mov es,cx drawline: asm mov cx,ax asm rep movsb asm add si,bx asm add di,bx asm dec dx asm jnz drawline asm mov ax,ss asm mov ds,ax VGAWRITEMODE(0); } #endif /* ============================================================================= STRING OUTPUT ROUTINES ============================================================================= */ /* =================== = = VL_DrawTile8String = =================== */ void VL_DrawTile8String (char *str, char far *tile8ptr, int printx, int printy) { int i; unsigned far *dest,far *screen,far *src; dest = MK_FP(SCREENSEG,bufferofs+ylookup[printy]+(printx>>2)); while (*str) { src = (unsigned far *)(tile8ptr + (*str<<6)); // each character is 64 bytes VGAMAPMASK(1); screen = dest; for (i=0;i<8;i++,screen+=linewidth) *screen = *src++; VGAMAPMASK(2); screen = dest; for (i=0;i<8;i++,screen+=linewidth) *screen = *src++; VGAMAPMASK(4); screen = dest; for (i=0;i<8;i++,screen+=linewidth) *screen = *src++; VGAMAPMASK(8); screen = dest; for (i=0;i<8;i++,screen+=linewidth) *screen = *src++; str++; printx += 8; dest+=2; } } /* =================== = = VL_DrawLatch8String = =================== */ void VL_DrawLatch8String (char *str, unsigned tile8ptr, int printx, int printy) { int i; unsigned src,dest; dest = bufferofs+ylookup[printy]+(printx>>2); VGAWRITEMODE(1); VGAMAPMASK(15); while (*str) { src = tile8ptr + (*str<<4); // each character is 16 latch bytes asm mov si,[src] asm mov di,[dest] asm mov dx,[linewidth] asm mov ax,SCREENSEG asm mov ds,ax asm lodsw asm mov [di],ax asm add di,dx asm lodsw asm mov [di],ax asm add di,dx asm lodsw asm mov [di],ax asm add di,dx asm lodsw asm mov [di],ax asm add di,dx asm lodsw asm mov [di],ax asm add di,dx asm lodsw asm mov [di],ax asm add di,dx asm lodsw asm mov [di],ax asm add di,dx asm lodsw asm mov [di],ax asm add di,dx asm mov ax,ss asm mov ds,ax str++; printx += 8; dest+=2; } VGAWRITEMODE(0); } /* =================== = = VL_SizeTile8String = =================== */ void VL_SizeTile8String (char *str, int *width, int *height) { *height = 8; *width = 8*strlen(str); }