ref: 0441e14568c0254ba99e516d1282fd196cb1e0a3
dir: /vh.c/
#define PIXTOBLOCK 4 // 16 pixels to an update block
u8int update[UPDATEHIGH][UPDATEWIDE];
//==========================================================================
pictabletype _seg *pictable;
s16int px,py;
u8int fontcolor,backcolor;
s16int fontnumber;
s16int bufferwidth,bufferheight;
//==========================================================================
void VWL_UpdateScreenBlocks (void);
//==========================================================================
void VW_DrawPropString (char far *string)
{
fontstruct far *font;
s16int width,step,height,i;
u8int far *source, far *dest, far *origdest;
u8int ch,mask;
font = (fontstruct far *)grsegs[STARTFONT+fontnumber];
height = bufferheight = font->height;
dest = origdest = MK_FP(SCREENSEG,bufferofs+ylookup[py]+(px>>2));
mask = 1<<(px&3);
while ((ch = *string++)!=0)
{
width = step = font->width[ch];
source = ((u8int far *)font)+font->location[ch];
while (width--)
{
VGAMAPMASK(mask);
asm mov ah,[BYTE PTR fontcolor]
asm mov bx,[step]
asm mov cx,[height]
asm mov dx,[linewidth]
asm lds si,[source]
asm les di,[dest]
vertloop:
asm mov al,[si]
asm or al,al
asm je next
asm mov [es:di],ah // draw color
next:
asm add si,bx
asm add di,dx
asm loop vertloop
asm mov ax,ss
asm mov ds,ax
source++;
px++;
mask <<= 1;
if (mask == 16)
{
mask = 1;
dest++;
}
}
}
bufferheight = height;
bufferwidth = ((dest+1)-origdest)*4;
}
void VW_DrawColorPropString (char far *string)
{
fontstruct far *font;
s16int width,step,height,i;
u8int far *source, far *dest, far *origdest;
u8int ch,mask;
font = (fontstruct far *)grsegs[STARTFONT+fontnumber];
height = bufferheight = font->height;
dest = origdest = MK_FP(SCREENSEG,bufferofs+ylookup[py]+(px>>2));
mask = 1<<(px&3);
while ((ch = *string++)!=0)
{
width = step = font->width[ch];
source = ((u8int far *)font)+font->location[ch];
while (width--)
{
VGAMAPMASK(mask);
asm mov ah,[BYTE PTR fontcolor]
asm mov bx,[step]
asm mov cx,[height]
asm mov dx,[linewidth]
asm lds si,[source]
asm les di,[dest]
vertloop:
asm mov al,[si]
asm or al,al
asm je next
asm mov [es:di],ah // draw color
next:
asm add si,bx
asm add di,dx
asm rcr cx,1 // inc font color
asm jc cont
asm inc ah
cont:
asm rcl cx,1
asm loop vertloop
asm mov ax,ss
asm mov ds,ax
source++;
px++;
mask <<= 1;
if (mask == 16)
{
mask = 1;
dest++;
}
}
}
bufferheight = height;
bufferwidth = ((dest+1)-origdest)*4;
}
void VWL_MeasureString (char far *string, u16int *width, u16int *height
, fontstruct _seg *font)
{
*height = font->height;
for (*width = 0;*string;string++)
*width += font->width[*((u8int far *)string)]; // proportional width
}
void VW_MeasurePropString (char far *string, u16int *width, u16int *height)
{
VWL_MeasureString(string,width,height,(fontstruct _seg *)grsegs[STARTFONT+fontnumber]);
}
/*
=============================================================================
Double buffer management routines
=============================================================================
*/
/*
=======================
=
= VW_MarkUpdateBlock
=
= Takes a pixel bounded block and marks the tiles in bufferblocks
= Returns 0 if the entire block is off the buffer screen
=
=======================
*/
s16int VW_MarkUpdateBlock (s16int x1, s16int y1, s16int x2, s16int y2)
{
s16int x,y,xt1,yt1,xt2,yt2,nextline;
u8int *mark;
xt1 = x1>>PIXTOBLOCK;
yt1 = y1>>PIXTOBLOCK;
xt2 = x2>>PIXTOBLOCK;
yt2 = y2>>PIXTOBLOCK;
if (xt1<0)
xt1=0;
else if (xt1>=UPDATEWIDE)
return 0;
if (yt1<0)
yt1=0;
else if (yt1>UPDATEHIGH)
return 0;
if (xt2<0)
return 0;
else if (xt2>=UPDATEWIDE)
xt2 = UPDATEWIDE-1;
if (yt2<0)
return 0;
else if (yt2>=UPDATEHIGH)
yt2 = UPDATEHIGH-1;
mark = updateptr + uwidthtable[yt1] + xt1;
nextline = UPDATEWIDE - (xt2-xt1) - 1;
for (y=yt1;y<=yt2;y++)
{
for (x=xt1;x<=xt2;x++)
*mark++ = 1; // this tile will need to be updated
mark += nextline;
}
return 1;
}
void VWB_DrawTile8 (s16int x, s16int y, s16int tile)
{
if (VW_MarkUpdateBlock (x,y,x+7,y+7))
LatchDrawChar(x,y,tile);
}
void VWB_DrawPic (s16int x, s16int y, s16int chunknum)
{
s16int picnum = chunknum - STARTPICS;
u16int width,height;
x &= ~7;
width = pictable[picnum].width;
height = pictable[picnum].height;
if (VW_MarkUpdateBlock (x,y,x+width-1,y+height-1))
VL_MemToScreen (grsegs[chunknum],width,height,x,y);
}
void VWB_DrawPropString (char far *string)
{
s16int x;
x=px;
VW_DrawPropString (string);
VW_MarkUpdateBlock(x,py,px-1,py+bufferheight-1);
}
void VWB_Bar (s16int x, s16int y, s16int width, s16int height, s16int color)
{
if (VW_MarkUpdateBlock (x,y,x+width,y+height-1) )
VW_Bar (x,y,width,height,color);
}
void VWB_Plot (s16int x, s16int y, s16int color)
{
if (VW_MarkUpdateBlock (x,y,x,y))
VW_Plot(x,y,color);
}
void VWB_Hlin (s16int x1, s16int x2, s16int y, s16int color)
{
if (VW_MarkUpdateBlock (x1,y,x2,y))
VW_Hlin(x1,x2,y,color);
}
void VWB_Vlin (s16int y1, s16int y2, s16int x, s16int color)
{
if (VW_MarkUpdateBlock (x,y1,x,y2))
VW_Vlin(y1,y2,x,color);
}
void VW_UpdateScreen (void)
{
VH_UpdateScreen ();
}
/*
=============================================================================
WOLFENSTEIN STUFF
=============================================================================
*/
/*
=====================
=
= LatchDrawPic
=
=====================
*/
void LatchDrawPic (u16int x, u16int y, u16int picnum)
{
u16int wide, height, source;
wide = pictable[picnum-STARTPICS].width;
height = pictable[picnum-STARTPICS].height;
source = latchpics[2+picnum-LATCHPICS_LUMP_START];
VL_LatchToScreen (source,wide/4,height,x*8,y);
}
//==========================================================================
/*
===================
=
= LoadLatchMem
=
===================
*/
void LoadLatchMem (void)
{
s16int i,j,p,m,width,height,start,end;
u8int far *src;
u16int destoff;
//
// tile 8s
//
FIXME: fuck this
latchpics[0] = freelatch;
src = (u8int _seg *)grsegs[STARTTILE8];
destoff = freelatch;
for (i=0;i<NUMTILE8;i++)
{
VL_MemToLatch (src,8,8,destoff);
src += 64;
destoff +=16;
}
//
// pics
//
start = LATCHPICS_LUMP_START;
end = LATCHPICS_LUMP_END;
for (i=start;i<=end;i++)
{
latchpics[2+i-start] = destoff;
width = pictable[i-STARTPICS].width;
height = pictable[i-STARTPICS].height;
VL_MemToLatch (grsegs[i],width,height,destoff);
destoff += width/4 *height;
}
EGAMAPMASK(15);
}
//==========================================================================
/*
===================
=
= FizzleFade
=
= returns true if aborted
=
===================
*/
extern ControlInfo c;
int FizzleFade (u16int source, u16int dest,
u16int width,u16int height, u16int frames, int abortable)
{
s16int pixperframe;
u16int drawofs,pagedelta;
u8int mask,maskb[8] = {1,2,4,8};
u16int x,y,p,frame;
s32int rndval;
pagedelta = dest-source;
rndval = 1;
y = 0;
pixperframe = 64000/frames;
IN_StartAck ();
TimeCount=frame=0;
do // while (1)
{
if (abortable && IN_CheckAck () )
return true;
asm mov es,[screenseg]
for (p=0;p<pixperframe;p++)
{
//
// seperate random value into x/y pair
//
asm mov ax,[WORD PTR rndval]
asm mov dx,[WORD PTR rndval+2]
asm mov bx,ax
asm dec bl
asm mov [BYTE PTR y],bl // low 8 bits - 1 = y xoordinate
asm mov bx,ax
asm mov cx,dx
asm mov [BYTE PTR x],ah // next 9 bits = x xoordinate
asm mov [BYTE PTR x+1],dl
//
// advance to next random element
//
asm shr dx,1
asm rcr ax,1
asm jnc noxor
asm xor dx,0x0001
asm xor ax,0x2000
noxor:
asm mov [WORD PTR rndval],ax
asm mov [WORD PTR rndval+2],dx
if (x>width || y>height)
continue;
drawofs = source+ylookup[y] + (x>>2);
//
// copy one pixel
//
mask = x&3;
VGAREADMAP(mask);
mask = maskb[mask];
VGAMAPMASK(mask);
asm mov di,[drawofs]
asm mov al,[es:di]
asm add di,[pagedelta]
asm mov [es:di],al
if (rndval == 1) // entire sequence has been completed
return false;
}
frame++;
while (TimeCount<frame) // don't go too fast
;
} while (1);
}