wolf3d

The original open source release of Wolfenstein 3D
Log | Files | Refs

ID_VL.C (16943B)


      1 // ID_VL.C
      2 
      3 #include <dos.h>
      4 #include <alloc.h>
      5 #include <mem.h>
      6 #include <string.h>
      7 #include "ID_HEAD.H"
      8 #include "ID_VL.H"
      9 #pragma hdrstop
     10 
     11 //
     12 // SC_INDEX is expected to stay at SC_MAPMASK for proper operation
     13 //
     14 
     15 unsigned	bufferofs;
     16 unsigned	displayofs,pelpan;
     17 
     18 unsigned	screenseg=SCREENSEG;		// set to 0xa000 for asm convenience
     19 
     20 unsigned	linewidth;
     21 unsigned	ylookup[MAXSCANLINES];
     22 
     23 boolean		screenfaded;
     24 unsigned	bordercolor;
     25 
     26 boolean		fastpalette;				// if true, use outsb to set
     27 
     28 byte		far	palette1[256][3],far palette2[256][3];
     29 
     30 //===========================================================================
     31 
     32 // asm
     33 
     34 int	 VL_VideoID (void);
     35 void VL_SetCRTC (int crtc);
     36 void VL_SetScreen (int crtc, int pelpan);
     37 void VL_WaitVBL (int vbls);
     38 
     39 //===========================================================================
     40 
     41 
     42 /*
     43 =======================
     44 =
     45 = VL_Startup
     46 =
     47 =======================
     48 */
     49 
     50 #if 0
     51 void	VL_Startup (void)
     52 {
     53 	if ( !MS_CheckParm ("HIDDENCARD") && VL_VideoID () != 5)
     54 		MS_Quit ("You need a VGA graphics card to run this!");
     55 
     56 	asm	cld;				// all string instructions assume forward
     57 }
     58 
     59 #endif
     60 
     61 /*
     62 =======================
     63 =
     64 = VL_Startup	// WOLFENSTEIN HACK
     65 =
     66 =======================
     67 */
     68 
     69 static	char *ParmStrings[] = {"HIDDENCARD",""};
     70 
     71 void	VL_Startup (void)
     72 {
     73 	int i,videocard;
     74 
     75 	asm	cld;
     76 
     77 	videocard = VL_VideoID ();
     78 	for (i = 1;i < _argc;i++)
     79 		if (US_CheckParm(_argv[i],ParmStrings) == 0)
     80 		{
     81 			videocard = 5;
     82 			break;
     83 		}
     84 
     85 	if (videocard != 5)
     86 Quit ("Improper video card!  If you really have a VGA card that I am not \n"
     87 	  "detecting, use the -HIDDENCARD command line parameter!");
     88 
     89 }
     90 
     91 
     92 
     93 /*
     94 =======================
     95 =
     96 = VL_Shutdown
     97 =
     98 =======================
     99 */
    100 
    101 void	VL_Shutdown (void)
    102 {
    103 	VL_SetTextMode ();
    104 }
    105 
    106 
    107 /*
    108 =======================
    109 =
    110 = VL_SetVGAPlaneMode
    111 =
    112 =======================
    113 */
    114 
    115 void	VL_SetVGAPlaneMode (void)
    116 {
    117 asm	mov	ax,0x13
    118 asm	int	0x10
    119 	VL_DePlaneVGA ();
    120 	VGAMAPMASK(15);
    121 	VL_SetLineWidth (40);
    122 }
    123 
    124 
    125 /*
    126 =======================
    127 =
    128 = VL_SetTextMode
    129 =
    130 =======================
    131 */
    132 
    133 void	VL_SetTextMode (void)
    134 {
    135 asm	mov	ax,3
    136 asm	int	0x10
    137 }
    138 
    139 //===========================================================================
    140 
    141 /*
    142 =================
    143 =
    144 = VL_ClearVideo
    145 =
    146 = Fill the entire video buffer with a given color
    147 =
    148 =================
    149 */
    150 
    151 void VL_ClearVideo (byte color)
    152 {
    153 asm	mov	dx,GC_INDEX
    154 asm	mov	al,GC_MODE
    155 asm	out	dx,al
    156 asm	inc	dx
    157 asm	in	al,dx
    158 asm	and	al,0xfc				// write mode 0 to store directly to video
    159 asm	out	dx,al
    160 
    161 asm	mov	dx,SC_INDEX
    162 asm	mov	ax,SC_MAPMASK+15*256
    163 asm	out	dx,ax				// write through all four planes
    164 
    165 asm	mov	ax,SCREENSEG
    166 asm	mov	es,ax
    167 asm	mov	al,[color]
    168 asm	mov	ah,al
    169 asm	mov	cx,0x8000			// 0x8000 words, clearing 8 video bytes/word
    170 asm	xor	di,di
    171 asm	rep	stosw
    172 }
    173 
    174 
    175 /*
    176 =============================================================================
    177 
    178 			VGA REGISTER MANAGEMENT ROUTINES
    179 
    180 =============================================================================
    181 */
    182 
    183 
    184 /*
    185 =================
    186 =
    187 = VL_DePlaneVGA
    188 =
    189 =================
    190 */
    191 
    192 void VL_DePlaneVGA (void)
    193 {
    194 
    195 //
    196 // change CPU addressing to non linear mode
    197 //
    198 
    199 //
    200 // turn off chain 4 and odd/even
    201 //
    202 	outportb (SC_INDEX,SC_MEMMODE);
    203 	outportb (SC_INDEX+1,(inportb(SC_INDEX+1)&~8)|4);
    204 
    205 	outportb (SC_INDEX,SC_MAPMASK);		// leave this set throughought
    206 
    207 //
    208 // turn off odd/even and set write mode 0
    209 //
    210 	outportb (GC_INDEX,GC_MODE);
    211 	outportb (GC_INDEX+1,inportb(GC_INDEX+1)&~0x13);
    212 
    213 //
    214 // turn off chain
    215 //
    216 	outportb (GC_INDEX,GC_MISCELLANEOUS);
    217 	outportb (GC_INDEX+1,inportb(GC_INDEX+1)&~2);
    218 
    219 //
    220 // clear the entire buffer space, because int 10h only did 16 k / plane
    221 //
    222 	VL_ClearVideo (0);
    223 
    224 //
    225 // change CRTC scanning from doubleword to byte mode, allowing >64k scans
    226 //
    227 	outportb (CRTC_INDEX,CRTC_UNDERLINE);
    228 	outportb (CRTC_INDEX+1,inportb(CRTC_INDEX+1)&~0x40);
    229 
    230 	outportb (CRTC_INDEX,CRTC_MODE);
    231 	outportb (CRTC_INDEX+1,inportb(CRTC_INDEX+1)|0x40);
    232 }
    233 
    234 //===========================================================================
    235 
    236 /*
    237 ====================
    238 =
    239 = VL_SetLineWidth
    240 =
    241 = Line witdh is in WORDS, 40 words is normal width for vgaplanegr
    242 =
    243 ====================
    244 */
    245 
    246 void VL_SetLineWidth (unsigned width)
    247 {
    248 	int i,offset;
    249 
    250 //
    251 // set wide virtual screen
    252 //
    253 	outport (CRTC_INDEX,CRTC_OFFSET+width*256);
    254 
    255 //
    256 // set up lookup tables
    257 //
    258 	linewidth = width*2;
    259 
    260 	offset = 0;
    261 
    262 	for (i=0;i<MAXSCANLINES;i++)
    263 	{
    264 		ylookup[i]=offset;
    265 		offset += linewidth;
    266 	}
    267 }
    268 
    269 /*
    270 ====================
    271 =
    272 = VL_SetSplitScreen
    273 =
    274 ====================
    275 */
    276 
    277 void VL_SetSplitScreen (int linenum)
    278 {
    279 	VL_WaitVBL (1);
    280 	linenum=linenum*2-1;
    281 	outportb (CRTC_INDEX,CRTC_LINECOMPARE);
    282 	outportb (CRTC_INDEX+1,linenum % 256);
    283 	outportb (CRTC_INDEX,CRTC_OVERFLOW);
    284 	outportb (CRTC_INDEX+1, 1+16*(linenum/256));
    285 	outportb (CRTC_INDEX,CRTC_MAXSCANLINE);
    286 	outportb (CRTC_INDEX+1,inportb(CRTC_INDEX+1) & (255-64));
    287 }
    288 
    289 
    290 /*
    291 =============================================================================
    292 
    293 						PALETTE OPS
    294 
    295 		To avoid snow, do a WaitVBL BEFORE calling these
    296 
    297 =============================================================================
    298 */
    299 
    300 
    301 /*
    302 =================
    303 =
    304 = VL_FillPalette
    305 =
    306 =================
    307 */
    308 
    309 void VL_FillPalette (int red, int green, int blue)
    310 {
    311 	int	i;
    312 
    313 	outportb (PEL_WRITE_ADR,0);
    314 	for (i=0;i<256;i++)
    315 	{
    316 		outportb (PEL_DATA,red);
    317 		outportb (PEL_DATA,green);
    318 		outportb (PEL_DATA,blue);
    319 	}
    320 }
    321 
    322 //===========================================================================
    323 
    324 /*
    325 =================
    326 =
    327 = VL_SetColor
    328 =
    329 =================
    330 */
    331 
    332 void VL_SetColor	(int color, int red, int green, int blue)
    333 {
    334 	outportb (PEL_WRITE_ADR,color);
    335 	outportb (PEL_DATA,red);
    336 	outportb (PEL_DATA,green);
    337 	outportb (PEL_DATA,blue);
    338 }
    339 
    340 //===========================================================================
    341 
    342 /*
    343 =================
    344 =
    345 = VL_GetColor
    346 =
    347 =================
    348 */
    349 
    350 void VL_GetColor	(int color, int *red, int *green, int *blue)
    351 {
    352 	outportb (PEL_READ_ADR,color);
    353 	*red = inportb (PEL_DATA);
    354 	*green = inportb (PEL_DATA);
    355 	*blue = inportb (PEL_DATA);
    356 }
    357 
    358 //===========================================================================
    359 
    360 /*
    361 =================
    362 =
    363 = VL_SetPalette
    364 =
    365 = If fast palette setting has been tested for, it is used
    366 = (some cards don't like outsb palette setting)
    367 =
    368 =================
    369 */
    370 
    371 void VL_SetPalette (byte far *palette)
    372 {
    373 	int	i;
    374 
    375 //	outportb (PEL_WRITE_ADR,0);
    376 //	for (i=0;i<768;i++)
    377 //		outportb(PEL_DATA,*palette++);
    378 
    379 	asm	mov	dx,PEL_WRITE_ADR
    380 	asm	mov	al,0
    381 	asm	out	dx,al
    382 	asm	mov	dx,PEL_DATA
    383 	asm	lds	si,[palette]
    384 
    385 	asm	test	[ss:fastpalette],1
    386 	asm	jz	slowset
    387 //
    388 // set palette fast for cards that can take it
    389 //
    390 	asm	mov	cx,768
    391 	asm	rep outsb
    392 	asm	jmp	done
    393 
    394 //
    395 // set palette slowly for some video cards
    396 //
    397 slowset:
    398 	asm	mov	cx,256
    399 setloop:
    400 	asm	lodsb
    401 	asm	out	dx,al
    402 	asm	lodsb
    403 	asm	out	dx,al
    404 	asm	lodsb
    405 	asm	out	dx,al
    406 	asm	loop	setloop
    407 
    408 done:
    409 	asm	mov	ax,ss
    410 	asm	mov	ds,ax
    411 
    412 }
    413 
    414 
    415 //===========================================================================
    416 
    417 /*
    418 =================
    419 =
    420 = VL_GetPalette
    421 =
    422 = This does not use the port string instructions,
    423 = due to some incompatabilities
    424 =
    425 =================
    426 */
    427 
    428 void VL_GetPalette (byte far *palette)
    429 {
    430 	int	i;
    431 
    432 	outportb (PEL_READ_ADR,0);
    433 	for (i=0;i<768;i++)
    434 		*palette++ = inportb(PEL_DATA);
    435 }
    436 
    437 
    438 //===========================================================================
    439 
    440 /*
    441 =================
    442 =
    443 = VL_FadeOut
    444 =
    445 = Fades the current palette to the given color in the given number of steps
    446 =
    447 =================
    448 */
    449 
    450 void VL_FadeOut (int start, int end, int red, int green, int blue, int steps)
    451 {
    452 	int		i,j,orig,delta;
    453 	byte	far *origptr, far *newptr;
    454 
    455 	VL_WaitVBL(1);
    456 	VL_GetPalette (&palette1[0][0]);
    457 	_fmemcpy (palette2,palette1,768);
    458 
    459 //
    460 // fade through intermediate frames
    461 //
    462 	for (i=0;i<steps;i++)
    463 	{
    464 		origptr = &palette1[start][0];
    465 		newptr = &palette2[start][0];
    466 		for (j=start;j<=end;j++)
    467 		{
    468 			orig = *origptr++;
    469 			delta = red-orig;
    470 			*newptr++ = orig + delta * i / steps;
    471 			orig = *origptr++;
    472 			delta = green-orig;
    473 			*newptr++ = orig + delta * i / steps;
    474 			orig = *origptr++;
    475 			delta = blue-orig;
    476 			*newptr++ = orig + delta * i / steps;
    477 		}
    478 
    479 		VL_WaitVBL(1);
    480 		VL_SetPalette (&palette2[0][0]);
    481 	}
    482 
    483 //
    484 // final color
    485 //
    486 	VL_FillPalette (red,green,blue);
    487 
    488 	screenfaded = true;
    489 }
    490 
    491 
    492 /*
    493 =================
    494 =
    495 = VL_FadeIn
    496 =
    497 =================
    498 */
    499 
    500 void VL_FadeIn (int start, int end, byte far *palette, int steps)
    501 {
    502 	int		i,j,delta;
    503 
    504 	VL_WaitVBL(1);
    505 	VL_GetPalette (&palette1[0][0]);
    506 	_fmemcpy (&palette2[0][0],&palette1[0][0],sizeof(palette1));
    507 
    508 	start *= 3;
    509 	end = end*3+2;
    510 
    511 //
    512 // fade through intermediate frames
    513 //
    514 	for (i=0;i<steps;i++)
    515 	{
    516 		for (j=start;j<=end;j++)
    517 		{
    518 			delta = palette[j]-palette1[0][j];
    519 			palette2[0][j] = palette1[0][j] + delta * i / steps;
    520 		}
    521 
    522 		VL_WaitVBL(1);
    523 		VL_SetPalette (&palette2[0][0]);
    524 	}
    525 
    526 //
    527 // final color
    528 //
    529 	VL_SetPalette (palette);
    530 	screenfaded = false;
    531 }
    532 
    533 
    534 
    535 /*
    536 =================
    537 =
    538 = VL_TestPaletteSet
    539 =
    540 = Sets the palette with outsb, then reads it in and compares
    541 = If it compares ok, fastpalette is set to true.
    542 =
    543 =================
    544 */
    545 
    546 void VL_TestPaletteSet (void)
    547 {
    548 	int	i;
    549 
    550 	for (i=0;i<768;i++)
    551 		palette1[0][i] = i;
    552 
    553 	fastpalette = true;
    554 	VL_SetPalette (&palette1[0][0]);
    555 	VL_GetPalette (&palette2[0][0]);
    556 	if (_fmemcmp (&palette1[0][0],&palette2[0][0],768))
    557 		fastpalette = false;
    558 }
    559 
    560 
    561 /*
    562 ==================
    563 =
    564 = VL_ColorBorder
    565 =
    566 ==================
    567 */
    568 
    569 void VL_ColorBorder (int color)
    570 {
    571 	_AH=0x10;
    572 	_AL=1;
    573 	_BH=color;
    574 	geninterrupt (0x10);
    575 	bordercolor = color;
    576 }
    577 
    578 
    579 
    580 /*
    581 =============================================================================
    582 
    583 							PIXEL OPS
    584 
    585 =============================================================================
    586 */
    587 
    588 byte	pixmasks[4] = {1,2,4,8};
    589 byte	leftmasks[4] = {15,14,12,8};
    590 byte	rightmasks[4] = {1,3,7,15};
    591 
    592 
    593 /*
    594 =================
    595 =
    596 = VL_Plot
    597 =
    598 =================
    599 */
    600 
    601 void VL_Plot (int x, int y, int color)
    602 {
    603 	byte mask;
    604 
    605 	mask = pixmasks[x&3];
    606 	VGAMAPMASK(mask);
    607 	*(byte far *)MK_FP(SCREENSEG,bufferofs+(ylookup[y]+(x>>2))) = color;
    608 	VGAMAPMASK(15);
    609 }
    610 
    611 
    612 /*
    613 =================
    614 =
    615 = VL_Hlin
    616 =
    617 =================
    618 */
    619 
    620 void VL_Hlin (unsigned x, unsigned y, unsigned width, unsigned color)
    621 {
    622 	unsigned		xbyte;
    623 	byte			far *dest;
    624 	byte			leftmask,rightmask;
    625 	int				midbytes;
    626 
    627 	xbyte = x>>2;
    628 	leftmask = leftmasks[x&3];
    629 	rightmask = rightmasks[(x+width-1)&3];
    630 	midbytes = ((x+width+3)>>2) - xbyte - 2;
    631 
    632 	dest = MK_FP(SCREENSEG,bufferofs+ylookup[y]+xbyte);
    633 
    634 	if (midbytes<0)
    635 	{
    636 	// all in one byte
    637 		VGAMAPMASK(leftmask&rightmask);
    638 		*dest = color;
    639 		VGAMAPMASK(15);
    640 		return;
    641 	}
    642 
    643 	VGAMAPMASK(leftmask);
    644 	*dest++ = color;
    645 
    646 	VGAMAPMASK(15);
    647 	_fmemset (dest,color,midbytes);
    648 	dest+=midbytes;
    649 
    650 	VGAMAPMASK(rightmask);
    651 	*dest = color;
    652 
    653 	VGAMAPMASK(15);
    654 }
    655 
    656 
    657 /*
    658 =================
    659 =
    660 = VL_Vlin
    661 =
    662 =================
    663 */
    664 
    665 void VL_Vlin (int x, int y, int height, int color)
    666 {
    667 	byte	far *dest,mask;
    668 
    669 	mask = pixmasks[x&3];
    670 	VGAMAPMASK(mask);
    671 
    672 	dest = MK_FP(SCREENSEG,bufferofs+ylookup[y]+(x>>2));
    673 
    674 	while (height--)
    675 	{
    676 		*dest = color;
    677 		dest += linewidth;
    678 	}
    679 
    680 	VGAMAPMASK(15);
    681 }
    682 
    683 
    684 /*
    685 =================
    686 =
    687 = VL_Bar
    688 =
    689 =================
    690 */
    691 
    692 void VL_Bar (int x, int y, int width, int height, int color)
    693 {
    694 	byte	far *dest;
    695 	byte	leftmask,rightmask;
    696 	int		midbytes,linedelta;
    697 
    698 	leftmask = leftmasks[x&3];
    699 	rightmask = rightmasks[(x+width-1)&3];
    700 	midbytes = ((x+width+3)>>2) - (x>>2) - 2;
    701 	linedelta = linewidth-(midbytes+1);
    702 
    703 	dest = MK_FP(SCREENSEG,bufferofs+ylookup[y]+(x>>2));
    704 
    705 	if (midbytes<0)
    706 	{
    707 	// all in one byte
    708 		VGAMAPMASK(leftmask&rightmask);
    709 		while (height--)
    710 		{
    711 			*dest = color;
    712 			dest += linewidth;
    713 		}
    714 		VGAMAPMASK(15);
    715 		return;
    716 	}
    717 
    718 	while (height--)
    719 	{
    720 		VGAMAPMASK(leftmask);
    721 		*dest++ = color;
    722 
    723 		VGAMAPMASK(15);
    724 		_fmemset (dest,color,midbytes);
    725 		dest+=midbytes;
    726 
    727 		VGAMAPMASK(rightmask);
    728 		*dest = color;
    729 
    730 		dest+=linedelta;
    731 	}
    732 
    733 	VGAMAPMASK(15);
    734 }
    735 
    736 /*
    737 ============================================================================
    738 
    739 							MEMORY OPS
    740 
    741 ============================================================================
    742 */
    743 
    744 /*
    745 =================
    746 =
    747 = VL_MemToLatch
    748 =
    749 =================
    750 */
    751 
    752 void VL_MemToLatch (byte far *source, int width, int height, unsigned dest)
    753 {
    754 	unsigned	count;
    755 	byte	plane,mask;
    756 
    757 	count = ((width+3)/4)*height;
    758 	mask = 1;
    759 	for (plane = 0; plane<4 ; plane++)
    760 	{
    761 		VGAMAPMASK(mask);
    762 		mask <<= 1;
    763 
    764 asm	mov	cx,count
    765 asm mov ax,SCREENSEG
    766 asm mov es,ax
    767 asm	mov	di,[dest]
    768 asm	lds	si,[source]
    769 asm	rep movsb
    770 asm mov	ax,ss
    771 asm	mov	ds,ax
    772 
    773 		source+= count;
    774 	}
    775 }
    776 
    777 
    778 //===========================================================================
    779 
    780 
    781 /*
    782 =================
    783 =
    784 = VL_MemToScreen
    785 =
    786 = Draws a block of data to the screen.
    787 =
    788 =================
    789 */
    790 
    791 void VL_MemToScreen (byte far *source, int width, int height, int x, int y)
    792 {
    793 	byte    far *screen,far *dest,mask;
    794 	int		plane;
    795 
    796 	width>>=2;
    797 	dest = MK_FP(SCREENSEG,bufferofs+ylookup[y]+(x>>2) );
    798 	mask = 1 << (x&3);
    799 
    800 	for (plane = 0; plane<4; plane++)
    801 	{
    802 		VGAMAPMASK(mask);
    803 		mask <<= 1;
    804 		if (mask == 16)
    805 			mask = 1;
    806 
    807 		screen = dest;
    808 		for (y=0;y<height;y++,screen+=linewidth,source+=width)
    809 			_fmemcpy (screen,source,width);
    810 	}
    811 }
    812 
    813 //==========================================================================
    814 
    815 
    816 /*
    817 =================
    818 =
    819 = VL_MaskedToScreen
    820 =
    821 = Masks a block of main memory to the screen.
    822 =
    823 =================
    824 */
    825 
    826 void VL_MaskedToScreen (byte far *source, int width, int height, int x, int y)
    827 {
    828 	byte    far *screen,far *dest,mask;
    829 	byte	far *maskptr;
    830 	int		plane;
    831 
    832 	width>>=2;
    833 	dest = MK_FP(SCREENSEG,bufferofs+ylookup[y]+(x>>2) );
    834 //	mask = 1 << (x&3);
    835 
    836 //	maskptr = source;
    837 
    838 	for (plane = 0; plane<4; plane++)
    839 	{
    840 		VGAMAPMASK(mask);
    841 		mask <<= 1;
    842 		if (mask == 16)
    843 			mask = 1;
    844 
    845 		screen = dest;
    846 		for (y=0;y<height;y++,screen+=linewidth,source+=width)
    847 			_fmemcpy (screen,source,width);
    848 	}
    849 }
    850 
    851 //==========================================================================
    852 
    853 /*
    854 =================
    855 =
    856 = VL_LatchToScreen
    857 =
    858 =================
    859 */
    860 
    861 void VL_LatchToScreen (unsigned source, int width, int height, int x, int y)
    862 {
    863 	VGAWRITEMODE(1);
    864 	VGAMAPMASK(15);
    865 
    866 asm	mov	di,[y]				// dest = bufferofs+ylookup[y]+(x>>2)
    867 asm	shl	di,1
    868 asm	mov	di,[WORD PTR ylookup+di]
    869 asm	add	di,[bufferofs]
    870 asm	mov	ax,[x]
    871 asm	shr	ax,2
    872 asm	add	di,ax
    873 
    874 asm	mov	si,[source]
    875 asm	mov	ax,[width]
    876 asm	mov	bx,[linewidth]
    877 asm	sub	bx,ax
    878 asm	mov	dx,[height]
    879 asm	mov	cx,SCREENSEG
    880 asm	mov	ds,cx
    881 asm	mov	es,cx
    882 
    883 drawline:
    884 asm	mov	cx,ax
    885 asm	rep movsb
    886 asm	add	di,bx
    887 asm	dec	dx
    888 asm	jnz	drawline
    889 
    890 asm	mov	ax,ss
    891 asm	mov	ds,ax
    892 
    893 	VGAWRITEMODE(0);
    894 }
    895 
    896 
    897 //===========================================================================
    898 
    899 #if 0
    900 
    901 /*
    902 =================
    903 =
    904 = VL_ScreenToScreen
    905 =
    906 =================
    907 */
    908 
    909 void VL_ScreenToScreen (unsigned source, unsigned dest,int width, int height)
    910 {
    911 	VGAWRITEMODE(1);
    912 	VGAMAPMASK(15);
    913 
    914 asm	mov	si,[source]
    915 asm	mov	di,[dest]
    916 asm	mov	ax,[width]
    917 asm	mov	bx,[linewidth]
    918 asm	sub	bx,ax
    919 asm	mov	dx,[height]
    920 asm	mov	cx,SCREENSEG
    921 asm	mov	ds,cx
    922 asm	mov	es,cx
    923 
    924 drawline:
    925 asm	mov	cx,ax
    926 asm	rep movsb
    927 asm	add	si,bx
    928 asm	add	di,bx
    929 asm	dec	dx
    930 asm	jnz	drawline
    931 
    932 asm	mov	ax,ss
    933 asm	mov	ds,ax
    934 
    935 	VGAWRITEMODE(0);
    936 }
    937 
    938 
    939 #endif
    940 
    941 /*
    942 =============================================================================
    943 
    944 						STRING OUTPUT ROUTINES
    945 
    946 =============================================================================
    947 */
    948 
    949 
    950 
    951 
    952 /*
    953 ===================
    954 =
    955 = VL_DrawTile8String
    956 =
    957 ===================
    958 */
    959 
    960 void VL_DrawTile8String (char *str, char far *tile8ptr, int printx, int printy)
    961 {
    962 	int		i;
    963 	unsigned	far *dest,far *screen,far *src;
    964 
    965 	dest = MK_FP(SCREENSEG,bufferofs+ylookup[printy]+(printx>>2));
    966 
    967 	while (*str)
    968 	{
    969 		src = (unsigned far *)(tile8ptr + (*str<<6));
    970 		// each character is 64 bytes
    971 
    972 		VGAMAPMASK(1);
    973 		screen = dest;
    974 		for (i=0;i<8;i++,screen+=linewidth)
    975 			*screen = *src++;
    976 		VGAMAPMASK(2);
    977 		screen = dest;
    978 		for (i=0;i<8;i++,screen+=linewidth)
    979 			*screen = *src++;
    980 		VGAMAPMASK(4);
    981 		screen = dest;
    982 		for (i=0;i<8;i++,screen+=linewidth)
    983 			*screen = *src++;
    984 		VGAMAPMASK(8);
    985 		screen = dest;
    986 		for (i=0;i<8;i++,screen+=linewidth)
    987 			*screen = *src++;
    988 
    989 		str++;
    990 		printx += 8;
    991 		dest+=2;
    992 	}
    993 }
    994 
    995 
    996 
    997 /*
    998 ===================
    999 =
   1000 = VL_DrawLatch8String
   1001 =
   1002 ===================
   1003 */
   1004 
   1005 void VL_DrawLatch8String (char *str, unsigned tile8ptr, int printx, int printy)
   1006 {
   1007 	int		i;
   1008 	unsigned	src,dest;
   1009 
   1010 	dest = bufferofs+ylookup[printy]+(printx>>2);
   1011 
   1012 	VGAWRITEMODE(1);
   1013 	VGAMAPMASK(15);
   1014 
   1015 	while (*str)
   1016 	{
   1017 		src = tile8ptr + (*str<<4);		// each character is 16 latch bytes
   1018 
   1019 asm	mov	si,[src]
   1020 asm	mov	di,[dest]
   1021 asm	mov	dx,[linewidth]
   1022 
   1023 asm	mov	ax,SCREENSEG
   1024 asm	mov	ds,ax
   1025 
   1026 asm	lodsw
   1027 asm	mov	[di],ax
   1028 asm	add	di,dx
   1029 asm	lodsw
   1030 asm	mov	[di],ax
   1031 asm	add	di,dx
   1032 asm	lodsw
   1033 asm	mov	[di],ax
   1034 asm	add	di,dx
   1035 asm	lodsw
   1036 asm	mov	[di],ax
   1037 asm	add	di,dx
   1038 asm	lodsw
   1039 asm	mov	[di],ax
   1040 asm	add	di,dx
   1041 asm	lodsw
   1042 asm	mov	[di],ax
   1043 asm	add	di,dx
   1044 asm	lodsw
   1045 asm	mov	[di],ax
   1046 asm	add	di,dx
   1047 asm	lodsw
   1048 asm	mov	[di],ax
   1049 asm	add	di,dx
   1050 
   1051 asm	mov	ax,ss
   1052 asm	mov	ds,ax
   1053 
   1054 		str++;
   1055 		printx += 8;
   1056 		dest+=2;
   1057 	}
   1058 
   1059 	VGAWRITEMODE(0);
   1060 }
   1061 
   1062 
   1063 /*
   1064 ===================
   1065 =
   1066 = VL_SizeTile8String
   1067 =
   1068 ===================
   1069 */
   1070 
   1071 void VL_SizeTile8String (char *str, int *width, int *height)
   1072 {
   1073 	*height = 8;
   1074 	*width = 8*strlen(str);
   1075 }
   1076 
   1077 
   1078 
   1079 
   1080 
   1081 
   1082 
   1083 
   1084