Commit 753697b6 authored by Steven Fuller's avatar Steven Fuller

Even more cleanups!

parent a95bbccf
......@@ -33,7 +33,7 @@ typedef struct
byte *tinf;
int mapon;
unsigned *mapsegs[MAPPLANES];
word *mapsegs[MAPPLANES];
maptype *mapheaderseg[NUMMAPS];
byte *audiosegs[NUMSNDCHUNKS];
void *grsegs[NUMCHUNKS];
......
......@@ -23,7 +23,7 @@ typedef struct
extern byte *tinf;
extern int mapon;
extern unsigned *mapsegs[MAPPLANES];
extern word *mapsegs[MAPPLANES];
extern maptype *mapheaderseg[NUMMAPS];
extern byte *audiosegs[NUMSNDCHUNKS];
extern void *grsegs[NUMCHUNKS];
......
......@@ -11,7 +11,6 @@ pictabletype *pictable;
int px,py;
byte fontcolor,backcolor;
int fontnumber;
int bufferwidth, bufferheight;
/* ======================================================================== */
......@@ -19,110 +18,42 @@ void VW_DrawPropString(char *string)
{
fontstruct *font;
int width, step, height, i;
byte *source, *dest, *origdest;
byte ch, mask;
byte *source, *dest, *ptrs, *ptrd;
byte ch;
font = (fontstruct *)grsegs[STARTFONT+fontnumber];
height = bufferheight = font->height;
dest = origdest = MK_FP(SCREENSEG,bufferofs+ylookup[py]+(px>>2));
mask = 1<<(px&3);
height = font->height;
dest = gfxbuf + py * 320 + px;
while ((ch = *string++)!=0)
{
while ((ch = *string++) != 0) {
width = step = font->width[ch];
source = ((byte *)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++;
while (width--) {
height = font->height;
ptrs = source;
ptrd = dest;
while (height--) {
if (*ptrs)
*ptrd = fontcolor;
ptrs += step;
ptrd += 320;
}
source++;
dest++;
}
}
bufferheight = height;
bufferwidth = ((dest+1)-origdest)*4;
}
/*
=================
=
= VL_MungePic
=
=================
*/
void VL_MungePic (byte *source, unsigned width, unsigned height)
{
unsigned x,y,plane,size,pwidth;
byte *temp, *dest, *srcline;
size = width*height;
if (width&3)
Quit ("VL_MungePic: Not divisable by 4!");
//
// copy the pic to a temp buffer
//
MM_GetPtr (&(memptr)temp,size);
memcpy (temp,source,size);
//
// munge it back into the original buffer
//
dest = source;
pwidth = width/4;
for (plane=0;plane<4;plane++)
{
srcline = temp;
for (y=0;y<height;y++)
{
for (x=0;x<pwidth;x++)
*dest++ = *(srcline+x*4+plane);
srcline+=width;
}
}
MM_FreePtr (&(memptr)temp);
}
void VWL_MeasureString (char *string, word *width, word *height,
void VWL_MeasureString(char *string, word *width, word *height,
fontstruct *font)
{
/* proportional width */
*height = font->height;
for (*width = 0;*string;string++)
*width += font->width[*((byte *)string)]; // proportional width
*width += font->width[*((byte *)string)];
}
void VW_MeasurePropString (char *string, word *width, word *height)
void VW_MeasurePropString (char *string, word *width, word *height)
{
VWL_MeasureString(string,width,height,(fontstruct *)grsegs[STARTFONT+fontnumber]);
}
......@@ -135,67 +66,9 @@ void VW_MeasurePropString (char *string, word *width, word *height)
=============================================================================
*/
/*
=======================
=
= VW_MarkUpdateBlock
=
= Takes a pixel bounded block and marks the tiles in bufferblocks
= Returns 0 if the entire block is off the buffer screen
=
=======================
*/
int VW_MarkUpdateBlock (int x1, int y1, int x2, int y2)
{
int x,y,xt1,yt1,xt2,yt2,nextline;
byte *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 (int x, int y, int tile)
{
if (VW_MarkUpdateBlock (x,y,x+7,y+7))
LatchDrawChar(x,y,tile);
LatchDrawChar(x,y,tile);
}
void VWB_DrawPic (int x, int y, int chunknum)
......@@ -208,44 +81,36 @@ void VWB_DrawPic (int x, int y, int chunknum)
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);
VL_MemToScreen (grsegs[chunknum],width,height,x,y);
}
void VWB_DrawPropString(char *string)
{
int x;
x=px;
VW_DrawPropString (string);
VW_MarkUpdateBlock(x,py,px-1,py+bufferheight-1);
}
void VWB_Bar(int x, int y, int width, int height, int color)
{
if (VW_MarkUpdateBlock (x,y,x+width,y+height-1) )
VW_Bar (x,y,width,height,color);
VW_Bar (x,y,width,height,color);
}
void VWB_Plot(int x, int y, int color)
{
if (VW_MarkUpdateBlock (x,y,x,y))
VW_Plot(x,y,color);
VW_Plot(x,y,color);
}
void VWB_Hlin(int x1, int x2, int y, int color)
{
if (VW_MarkUpdateBlock (x1,y,x2,y))
VW_Hlin(x1,x2,y,color);
VW_Hlin(x1,x2,y,color);
}
void VWB_Vlin(int y1, int y2, int x, int color)
{
if (VW_MarkUpdateBlock (x,y1,x,y2))
VW_Vlin(y1,y2,x,color);
VW_Vlin(y1,y2,x,color);
}
void VW_UpdateScreen (void)
void VW_UpdateScreen(void)
{
VH_UpdateScreen ();
}
......@@ -287,11 +152,11 @@ void LatchDrawPic (unsigned x, unsigned y, unsigned picnum)
===================
*/
void LoadLatchMem (void)
void LoadLatchMem(void)
{
int i,j,p,m,width,height,start,end;
byte *src;
unsigned destoff;
word destoff;
/*
tile 8s
......@@ -344,7 +209,6 @@ void LoadLatchMem (void)
UNCACHEGRCHUNK(i);
}
VGAMAPMASK(15);
}
/* ======================================================================== */
......@@ -376,15 +240,12 @@ boolean FizzleFade (unsigned source, unsigned dest,
IN_StartAck ();
TimeCount=frame=0;
do // while (1)
{
if (abortable && IN_CheckAck () )
do {
if (abortable && IN_CheckAck ())
return true;
asm mov es,[screenseg]
for (p=0;p<pixperframe;p++)
{
for (p=0;p<pixperframe;p++) {
#if 0
//
// seperate random value into x/y pair
//
......@@ -426,11 +287,13 @@ noxor:
asm add di,[pagedelta]
asm mov [es:di],al
if (rndval == 1) // entire sequence has been completed
#endif
if (rndval == 1) /* entire sequence has been completed */
return false;
}
frame++;
while (TimeCount<frame) // don't go too fast
while (TimeCount<frame)
;
} while (1);
}
......@@ -39,8 +39,6 @@ void VL_Hlin (unsigned x, unsigned y, unsigned width, unsigned color);
void VL_Vlin (int x, int y, int height, int color);
void VL_Bar (int x, int y, int width, int height, int color);
void VL_MungePic (byte *source, unsigned width, unsigned height);
void VL_DrawPicBare (int x, int y, byte *pic, int width, int height);
void VL_MemToLatch (byte *source, int width, int height, word dest);
void VL_ScreenToScreen (unsigned source, unsigned dest,int width, int height);
void VL_MemToScreen (byte *source, int width, int height, int x, int y);
......
// WL_ACT1.C
/* wl_act1.c */
#include "WL_DEF.H"
#pragma hdrstop
#include "wl_def.h"
/*
=============================================================================
......@@ -275,7 +274,7 @@ int doornum;
unsigned doorposition[MAXDOORS]; // leading edge of door 0=closed
// 0xffff = fully open
byte far areaconnect[NUMAREAS][NUMAREAS];
byte areaconnect[NUMAREAS][NUMAREAS];
boolean areabyplayer[NUMAREAS];
......@@ -350,7 +349,7 @@ void InitDoorList (void)
void SpawnDoor (int tilex, int tiley, boolean vertical, int lock)
{
int areanumber;
unsigned far *map;
word *map;
if (doornum==64)
Quit ("64+ doors on level!");
......@@ -369,7 +368,7 @@ void SpawnDoor (int tilex, int tiley, boolean vertical, int lock)
// for door sides
//
tilemap[tilex][tiley] = doornum | 0x80;
map = mapsegs[0] + farmapylookup[tiley]+tilex;
map = (word *)(mapsegs[0] + farmapylookup[tiley]+tilex);
if (vertical)
{
*map = *(map-1); // set area number
......@@ -554,7 +553,7 @@ void DoorOpen (int door)
void DoorOpening (int door)
{
int area1,area2;
unsigned far *map;
word *map;
long position;
position = doorposition[door];
......@@ -563,8 +562,8 @@ void DoorOpening (int door)
//
// door is just starting to open, so connect the areas
//
map = mapsegs[0] + farmapylookup[doorobjlist[door].tiley]
+doorobjlist[door].tilex;
map = (word *)(mapsegs[0] + farmapylookup[doorobjlist[door].tiley]
+doorobjlist[door].tilex);
if (doorobjlist[door].vertical)
{
......@@ -617,7 +616,7 @@ void DoorOpening (int door)
void DoorClosing (int door)
{
int area1,area2,move;
unsigned far *map;
word *map;
long position;
int tilex,tiley;
......@@ -646,8 +645,8 @@ void DoorClosing (int door)
doorobjlist[door].action = dr_closed;
map = mapsegs[0] + farmapylookup[doorobjlist[door].tiley]
+doorobjlist[door].tilex;
map = (word *)(mapsegs[0] + farmapylookup[doorobjlist[door].tiley]
+doorobjlist[door].tilex);
if (doorobjlist[door].vertical)
{
......
......@@ -653,7 +653,7 @@ typedef enum {
} weapontype;
typedef enum {
/* typedef */ enum {
gd_baby,
gd_easy,
gd_medium,
......@@ -1008,7 +1008,7 @@ typedef struct
{
unsigned codeofs[65];
unsigned width[65];
byte code[];
byte *code;
} t_compscale;
typedef struct
......
/* wl_draw.c */
// WL_DRAW.C
#include "wl_def.h"
/*
=============================================================================
LOCAL CONSTANTS
=============================================================================
*/
#include "wl_def.h"
// the door is the last picture before the sprites
#define DOORWALL (PMSpriteStart-8)
#define ACTORSIZE 0x4000
/*
=============================================================================
GLOBAL VARIABLES
=============================================================================
*/
unsigned screenloc[3]= {PAGE1START,PAGE2START,PAGE3START};
unsigned freelatch = FREESTART;
long lasttimecount;
long frameon;
......@@ -33,15 +14,17 @@ long frameon;
unsigned wallheight[MAXVIEWWIDTH];
fixed tileglobal = TILEGLOBAL;
fixed mindist = MINDIST;
#define mindist MINDIST
unsigned char tempy[4096]; /* TODO: testing code only... */
//
// math tables
//
int pixelangle[MAXVIEWWIDTH];
long far finetangent[FINEANGLES/4];
fixed far sintable[ANGLES+ANGLES/4],far *costable = sintable+(ANGLES/4);
long finetangent[FINEANGLES/4];
fixed sintable[ANGLES+ANGLES/4+1],*costable = sintable+(ANGLES/4);
//
// refresh variables
......@@ -50,37 +33,23 @@ fixed viewx,viewy; // the focal point
int viewangle;
fixed viewsin,viewcos;
fixed FixedByFrac (fixed a, fixed b);
void TransformActor (objtype *ob);
void BuildTables (void);
void ClearScreen (void);
int CalcRotate (objtype *ob);
void DrawScaleds (void);
void CalcTics (void);
void FixOfs (void);
void ThreeDRefresh (void);
//
// wall optimization variables
//
int lastside; // true for vertical
long lastintercept;
int lasttilehit;
unsigned char crapmap[4096]; /* TODO: remove this testing code */
//
// ray tracing variables
//
int focaltx,focalty,viewtx,viewty;
int focaltx,focalty;
int midangle,angle;
unsigned xpartial,ypartial;
unsigned xpartialup,xpartialdown,ypartialup,ypartialdown;
unsigned xinttile,yinttile;
unsigned tilehit;
unsigned pixx;
......@@ -92,29 +61,9 @@ long xstep,ystep;
int horizwall[MAXWALLTILES],vertwall[MAXWALLTILES];
extern unsigned xoffset, yoffset;
/*
=============================================================================
LOCAL VARIABLES
=============================================================================
*/
void AsmRefresh (void); // in WL_DR_A.ASM
/*
============================================================================
3 - D DEFINITIONS
============================================================================
*/
//==========================================================================
void AsmRefresh (void);
/*
========================
......@@ -126,52 +75,18 @@ void AsmRefresh (void); // in WL_DR_A.ASM
=
========================
*/
#pragma warn -rvl // I stick the return value in with ASMs
#if 0
fixed FixedByFrac (fixed a, fixed b)
{
//
// setup
//
asm mov si,[WORD PTR b+2] // sign of result = sign of fraction
asm mov ax,[WORD PTR a]
asm mov cx,[WORD PTR a+2]
asm or cx,cx
asm jns aok: // negative?
asm neg cx
asm neg ax
asm sbb cx,0
asm xor si,0x8000 // toggle sign of result
aok:
//
// multiply cx:ax by bx
//
asm mov bx,[WORD PTR b]
asm mul bx // fraction*fraction
asm mov di,dx // di is low word of result
asm mov ax,cx //
asm mul bx // units*fraction
asm add ax,di
asm adc dx,0
//
// put result dx:ax in 2's complement
//
asm test si,0x8000 // is the result negative?
asm jz ansok:
asm neg dx
asm neg ax
asm sbb dx,0
ansok:;
long long ra = a;
long long rb = b;
long long r;
r = ra * rb;
r >>= 16;
return (fixed)r;
}
#pragma warn +rvl
#endif
//==========================================================================
......@@ -200,9 +115,7 @@ ansok:;
//
void TransformActor (objtype *ob)
{
int ratio;
fixed gx,gy,gxt,gyt,nx,ny;
long temp;
//
// translate point to view centered coordinates
......@@ -216,8 +129,8 @@ void TransformActor (objtype *ob)
gxt = FixedByFrac(gx,viewcos);
gyt = FixedByFrac(gy,viewsin);
nx = gxt-gyt-ACTORSIZE; // fudge the shape forward a bit, because
// the midpoint could put parts of the shape
// into an adjacent wall
// the midpoint could put parts of the shape
// into an adjacent wall
//
// calculate newy
......@@ -232,24 +145,16 @@ void TransformActor (objtype *ob)
ob->transx = nx;
ob->transy = ny;
if (nx<mindist) // too close, don't overflow the divide
if (nx < mindist) /* too close, don't overflow the divide */
{
ob->viewheight = 0;
return;
}
ob->viewx = centerx + ny*scale/nx; // DEBUG: use assembly divide
ob->viewx = centerx + ny*scale/nx;
//
// calculate height (heightnumerator/(nx>>8))
//
asm mov ax,[WORD PTR heightnumerator]
asm mov dx,[WORD PTR heightnumerator+2]
asm idiv [WORD PTR nx+1] // nx>>8
asm mov [WORD PTR temp],ax
asm mov [WORD PTR temp+2],dx
ob->viewheight = heightnumerator/(nx>>8);
ob->viewheight = temp;
}
//==========================================================================
......@@ -277,9 +182,7 @@ void TransformActor (objtype *ob)
boolean TransformTile (int tx, int ty, int *dispx, int *dispheight)
{
int ratio;
fixed gx,gy,gxt,gyt,nx,ny;
long temp;
//
// translate point to view centered coordinates
......@@ -305,7 +208,7 @@ boolean TransformTile (int tx, int ty, int *dispx, int *dispheight)
//
// calculate perspective ratio
//
if (nx<mindist) // too close, don't overflow the divide
if (nx<mindist) /* too close, don't overflow the divide */
{
*dispheight = 0;
return false;
......@@ -313,16 +216,7 @@ boolean TransformTile (int tx, int ty, int *dispx, int *dispheight)
*dispx = centerx + ny*scale/nx; // DEBUG: use assembly divide
//
// calculate height (heightnumerator/(nx>>8))
//
asm mov ax,[WORD PTR heightnumerator]
asm mov dx,[WORD PTR heightnumerator+2]
asm idiv [WORD PTR nx+1] // nx>>8
asm mov [WORD PTR temp],ax
asm mov [WORD PTR temp+2],dx
*dispheight = temp;
*dispheight = heightnumerator/(nx>>8);
//
// see if it should be grabbed
......@@ -345,14 +239,10 @@ boolean TransformTile (int tx, int ty, int *dispx, int *dispheight)
====================
*/
#pragma warn -rvl // I stick the return value in with ASMs
int CalcHeight (void)
int CalcHeight (void)
{
int transheight;
int ratio;
fixed gxt,gyt,nx,ny;
long gx,gy;
fixed gxt,gyt,nx,gx,gy;
gx = xintercept-viewx;
gxt = FixedByFrac(gx,viewcos);
......@@ -366,11 +256,9 @@ int CalcHeight (void)
// calculate perspective ratio (heightnumerator/(nx>>8))
//
if (nx<mindist)
nx=mindist; // don't let divide overflow
nx=mindist; /* don't let divide overflow */
asm mov ax,[WORD PTR heightnumerator]
asm mov dx,[WORD PTR heightnumerator+2]
asm idiv [WORD PTR nx+1] // nx>>8
return heightnumerator/(nx>>8);
}
......@@ -388,218 +276,18 @@ long postsource;
unsigned postx;
unsigned postwidth;
void ScalePost(void)
{
asm mov ax,SCREENSEG
asm mov es,ax
asm mov bx,[postx]
asm shl bx,1
asm mov bp,WORD PTR [wallheight+bx] // fractional height (low 3 bits frac)
asm and bp,0xfff8 // bp = heightscaler*4
asm shr bp,1
asm cmp bp,[maxscaleshl2]
asm jle heightok
asm mov bp,[maxscaleshl2]
heightok:
asm add bp,OFFSET fullscalefarcall
//
// scale a byte wide strip of wall
//
asm mov bx,[postx]
asm mov di,bx
asm shr di,2 // X in bytes
asm add di,[bufferofs]
asm and bx,3
asm shl bx,3 // bx = pixel*8+pixwidth
asm add bx,[postwidth]
asm mov al,BYTE PTR [mapmasks1-1+bx] // -1 because no widths of 0
asm mov dx,SC_INDEX+1
asm out dx,al // set bit mask register
asm lds si,DWORD PTR [postsource]
asm call DWORD PTR [bp] // scale the line of pixels
asm mov al,BYTE PTR [ss:mapmasks2-1+bx] // -1 because no widths of 0
asm or al,al
asm jz nomore
//
// draw a second byte for vertical strips that cross two bytes
//
asm inc di
asm out dx,al // set bit mask register
asm call DWORD PTR [bp] // scale the line of pixels
asm mov al,BYTE PTR [ss:mapmasks3-1+bx] // -1 because no widths of 0
asm or al,al
asm jz nomore
//
// draw a third byte for vertical strips that cross three bytes
//
asm inc di
asm out dx,al // set bit mask register
asm call DWORD PTR [bp] // scale the line of pixels
nomore:
asm mov ax,ss
asm mov ds,ax
}
void FarScalePost (void) // just so other files can call
void ScalePost (byte *wall, int texture) // VGA version
{
ScalePost ();
int height;
byte *source;
height = (wallheight [postx] & 0xfff8) >> 1;
if (height > maxscaleshl2)
height = maxscaleshl2;
source = wall+texture;
xBuildCompScale (height/2, source, postx);
}
/*
====================
=
= HitVertWall
=
= tilehit bit 7 is 0, because it's not a door tile
= if bit 6 is 1 and the adjacent tile is a door tile, use door side pic
=
====================
*/
void HitVertWall (void)
{
int wallpic;
unsigned texture;
texture = (yintercept>>4)&0xfc0;
if (xtilestep == -1)
{
texture = 0xfc0-texture;
xintercept += TILEGLOBAL;
}
wallheight[pixx] = CalcHeight();
if (lastside==1 && lastintercept == xtile && lasttilehit == tilehit)
{
// in the same wall type as last time, so check for optimized draw
if (texture == (unsigned)postsource)
{
// wide scale
postwidth++;
wallheight[pixx] = wallheight[pixx-1];
return;
}
else
{
ScalePost ();
(unsigned)postsource = texture;
postwidth = 1;
postx = pixx;
}
}
else
{
// new wall
if (lastside != -1) // if not the first scaled post
ScalePost ();
lastside = true;
lastintercept = xtile;
lasttilehit = tilehit;
postx = pixx;
postwidth = 1;
if (tilehit & 0x40)
{ // check for adjacent doors
ytile = yintercept>>TILESHIFT;
if ( tilemap[xtile-xtilestep][ytile]&0x80 )
wallpic = DOORWALL+3;
else
wallpic = vertwall[tilehit & ~0x40];
}
else
wallpic = vertwall[tilehit];
*( ((unsigned *)&postsource)+1) = (unsigned)PM_GetPage(wallpic);
(unsigned)postsource = texture;
}
}
/*
====================
=
= HitHorizWall
=
= tilehit bit 7 is 0, because it's not a door tile
= if bit 6 is 1 and the adjacent tile is a door tile, use door side pic
=
====================
*/
void HitHorizWall (void)
{
int wallpic;
unsigned texture;
texture = (xintercept>>4)&0xfc0;
if (ytilestep == -1)
yintercept += TILEGLOBAL;
else
texture = 0xfc0-texture;
wallheight[pixx] = CalcHeight();
if (lastside==0 && lastintercept == ytile && lasttilehit == tilehit)
{
// in the same wall type as last time, so check for optimized draw
if (texture == (unsigned)postsource)
{
// wide scale
postwidth++;
wallheight[pixx] = wallheight[pixx-1];
return;
}
else
{
ScalePost ();
(unsigned)postsource = texture;
postwidth = 1;
postx = pixx;
}
}
else
{
// new wall
if (lastside != -1) // if not the first scaled post
ScalePost ();
lastside = 0;
lastintercept = ytile;
lasttilehit = tilehit;
postx = pixx;
postwidth = 1;
if (tilehit & 0x40)
{ // check for adjacent doors
xtile = xintercept>>TILESHIFT;
if ( tilemap[xtile][ytile-ytilestep]&0x80 )
wallpic = DOORWALL+2;
else
wallpic = horizwall[tilehit & ~0x40];
}
else
wallpic = horizwall[tilehit];
*( ((unsigned *)&postsource)+1) = (unsigned)PM_GetPage(wallpic);
(unsigned)postsource = texture;
}
}
//==========================================================================
/*
====================
=
......@@ -611,39 +299,14 @@ void HitHorizWall (void)
void HitHorizDoor (void)
{
unsigned texture,doorpage,doornum;
byte *wall;
doornum = tilehit&0x7f;
texture = ( (xintercept-doorposition[doornum]) >> 4) &0xfc0;
wallheight[pixx] = CalcHeight();
if (lasttilehit == tilehit)
{
// in the same door as last time, so check for optimized draw
if (texture == (unsigned)postsource)
{
// wide scale
postwidth++;
wallheight[pixx] = wallheight[pixx-1];
return;
}
else
{
ScalePost ();
(unsigned)postsource = texture;
postwidth = 1;
postx = pixx;
}
}
else
{
if (lastside != -1) // if not the first scaled post
ScalePost (); // draw last post
// first pixel in this door
lastside = 2;
lasttilehit = tilehit;
postx = pixx;
postwidth = 1;
switch (doorobjlist[doornum].lock)
{
......@@ -661,9 +324,9 @@ void HitHorizDoor (void)
break;
}
*( ((unsigned *)&postsource)+1) = (unsigned)PM_GetPage(doorpage);
(unsigned)postsource = texture;
}
wall = PM_GetPage (doorpage);
ScalePost (wall, texture);
}
//==========================================================================
......@@ -679,39 +342,14 @@ void HitHorizDoor (void)
void HitVertDoor (void)
{
unsigned texture,doorpage,doornum;
byte *wall;
doornum = tilehit&0x7f;
texture = ( (yintercept-doorposition[doornum]) >> 4) &0xfc0;
wallheight[pixx] = CalcHeight();
if (lasttilehit == tilehit)
{
// in the same door as last time, so check for optimized draw
if (texture == (unsigned)postsource)
{
// wide scale
postwidth++;
wallheight[pixx] = wallheight[pixx-1];
return;
}
else
{
ScalePost ();
(unsigned)postsource = texture;
postwidth = 1;
postx = pixx;
}
}
else
{
if (lastside != -1) // if not the first scaled post
ScalePost (); // draw last post
// first pixel in this door
lastside = 2;
lasttilehit = tilehit;
postx = pixx;
postwidth = 1;
switch (doorobjlist[doornum].lock)
{
......@@ -729,211 +367,12 @@ void HitVertDoor (void)
break;
}
*( ((unsigned *)&postsource)+1) = (unsigned)PM_GetPage(doorpage+1);
(unsigned)postsource = texture;
}
}
//==========================================================================
/*
====================
=
= HitHorizPWall
=
= A pushable wall in action has been hit
=
====================
*/
void HitHorizPWall (void)
{
int wallpic;
unsigned texture,offset;
texture = (xintercept>>4)&0xfc0;
offset = pwallpos<<10;
if (ytilestep == -1)
yintercept += TILEGLOBAL-offset;
else
{
texture = 0xfc0-texture;
yintercept += offset;
}
wallheight[pixx] = CalcHeight();
if (lasttilehit == tilehit)
{
// in the same wall type as last time, so check for optimized draw
if (texture == (unsigned)postsource)
{
// wide scale
postwidth++;
wallheight[pixx] = wallheight[pixx-1];
return;
}
else
{
ScalePost ();
(unsigned)postsource = texture;
postwidth = 1;
postx = pixx;
}
}
else
{
// new wall
if (lastside != -1) // if not the first scaled post
ScalePost ();
lasttilehit = tilehit;
postx = pixx;
postwidth = 1;
wallpic = horizwall[tilehit&63];
*( ((unsigned *)&postsource)+1) = (unsigned)PM_GetPage(wallpic);
(unsigned)postsource = texture;
}
}
/*
====================
=
= HitVertPWall
=
= A pushable wall in action has been hit
=
====================
*/
void HitVertPWall (void)
{
int wallpic;
unsigned texture,offset;
texture = (yintercept>>4)&0xfc0;
offset = pwallpos<<10;
if (xtilestep == -1)
{
xintercept += TILEGLOBAL-offset;
texture = 0xfc0-texture;
}
else
xintercept += offset;
wallheight[pixx] = CalcHeight();
if (lasttilehit == tilehit)
{
// in the same wall type as last time, so check for optimized draw
if (texture == (unsigned)postsource)
{
// wide scale
postwidth++;
wallheight[pixx] = wallheight[pixx-1];
return;
}
else
{
ScalePost ();
(unsigned)postsource = texture;
postwidth = 1;
postx = pixx;
}
}
else
{
// new wall
if (lastside != -1) // if not the first scaled post
ScalePost ();
lasttilehit = tilehit;
postx = pixx;
postwidth = 1;
wallpic = vertwall[tilehit&63];
*( ((unsigned *)&postsource)+1) = (unsigned)PM_GetPage(wallpic);
(unsigned)postsource = texture;
}
wall = PM_GetPage (doorpage);
ScalePost (wall, texture);
}
//==========================================================================
//==========================================================================
#if 0
/*
=====================
=
= ClearScreen
=
=====================
*/
void ClearScreen (void)
{
unsigned floor=egaFloor[gamestate.episode*10+mapon],
ceiling=egaCeiling[gamestate.episode*10+mapon];
//
// clear the screen
//
asm mov dx,GC_INDEX
asm mov ax,GC_MODE + 256*2 // read mode 0, write mode 2
asm out dx,ax
asm mov ax,GC_BITMASK + 255*256
asm out dx,ax
asm mov dx,40
asm mov ax,[viewwidth]
asm shr ax,3
asm sub dx,ax // dx = 40-viewwidth/8
asm mov bx,[viewwidth]
asm shr bx,4 // bl = viewwidth/16
asm mov bh,BYTE PTR [viewheight]
asm shr bh,1 // half height
asm mov ax,[ceiling]
asm mov es,[screenseg]
asm mov di,[bufferofs]
toploop:
asm mov cl,bl
asm rep stosw
asm add di,dx
asm dec bh
asm jnz toploop
asm mov bh,BYTE PTR [viewheight]
asm shr bh,1 // half height
asm mov ax,[floor]
bottomloop:
asm mov cl,bl
asm rep stosw
asm add di,dx
asm dec bh
asm jnz bottomloop
asm mov dx,GC_INDEX
asm mov ax,GC_MODE + 256*10 // read mode 1, write mode 2
asm out dx,ax
asm mov al,GC_BITMASK
asm out dx,al
}
#endif
//==========================================================================
unsigned vgaCeiling[]=
{
#ifndef SPEAR
......@@ -960,46 +399,11 @@ unsigned vgaCeiling[]=
void VGAClearScreen (void)
{
unsigned ceiling=vgaCeiling[gamestate.episode*10+mapon];
unsigned ceiling = vgaCeiling[gamestate.episode*10+mapon] & 0xFF;
unsigned floor = 0x19;
//
// clear the screen
//
asm mov dx,SC_INDEX
asm mov ax,SC_MAPMASK+15*256 // write through all planes
asm out dx,ax
asm mov dx,80
asm mov ax,[viewwidth]
asm shr ax,2
asm sub dx,ax // dx = 40-viewwidth/2
asm mov bx,[viewwidth]
asm shr bx,3 // bl = viewwidth/8
asm mov bh,BYTE PTR [viewheight]
asm shr bh,1 // half height
asm mov es,[screenseg]
asm mov di,[bufferofs]
asm mov ax,[ceiling]
toploop:
asm mov cl,bl
asm rep stosw
asm add di,dx
asm dec bh
asm jnz toploop
asm mov bh,BYTE PTR [viewheight]
asm shr bh,1 // half height
asm mov ax,0x1919
bottomloop:
asm mov cl,bl
asm rep stosw
asm add di,dx
asm dec bh
asm jnz bottomloop
VL_Bar(xoffset, yoffset, viewwidth, viewheight / 2, ceiling);
VL_Bar(xoffset, yoffset + viewheight / 2, viewwidth, viewheight / 2, floor);
}
//==========================================================================
......@@ -1016,8 +420,8 @@ int CalcRotate (objtype *ob)
{
int angle,viewangle;
// this isn't exactly correct, as it should vary by a trig value,
// but it is close enough with only eight rotations
/* this isn't exactly correct, as it should vary by a trig value, */
/* but it is close enough with only eight rotations */
viewangle = player->angle + (centerx - ob->viewx)/8;
......@@ -1062,10 +466,8 @@ visobj_t vislist[MAXVISABLE],*visptr,*visstep,*farthest;
void DrawScaleds (void)
{
int i,j,least,numvisable,height;
memptr shape;
int i,least,numvisable,height;
byte *tilespot,*visspot;
int shapenum;
unsigned spotloc;
statobj_t *statptr;
......@@ -1094,7 +496,7 @@ void DrawScaleds (void)
if (!visptr->viewheight)
continue; // to close to the object
if (visptr < &vislist[MAXVISABLE-1]) // don't let it overflow
if (visptr < &vislist[MAXVISABLE-1]) /* don't let it overflow */
visptr++;
}
......@@ -1136,7 +538,7 @@ void DrawScaleds (void)
if (obj->state->rotate)
visptr->shapenum += CalcRotate (obj);
if (visptr < &vislist[MAXVISABLE-1]) // don't let it overflow
if (visptr < &vislist[MAXVISABLE-1]) /* don't let it overflow */
visptr++;
obj->flags |= FL_VISABLE;
}
......@@ -1196,7 +598,7 @@ void DrawPlayerWeapon (void)
#ifndef SPEAR
if (gamestate.victoryflag)
{
if (player->state == &s_deathcam && (TimeCount&32) )
if (player->state == &s_deathcam && (get_TimeCount() & 32) )
SimpleScaleShape(viewwidth/2,SPR_DEATHCAM,viewheight+1);
return;
}
......@@ -1226,17 +628,17 @@ void DrawPlayerWeapon (void)
void CalcTics (void)
{
long newtime,oldtimecount;
long newtime;
//
// calculate tics since last refresh for adaptive timing
//
if (lasttimecount > TimeCount)
TimeCount = lasttimecount; // if the game was paused a LONG time
if (lasttimecount > get_TimeCount())
set_TimeCount(lasttimecount); // if the game was paused a LONG time
do
{
newtime = TimeCount;
newtime = get_TimeCount();
tics = newtime-lasttimecount;
} while (!tics); // make sure at least one tic passes
......@@ -1244,29 +646,11 @@ void CalcTics (void)
if (tics>MAXTICS)
{
TimeCount -= (tics-MAXTICS);
set_TimeCount(get_TimeCount() - (tics-MAXTICS));
tics = MAXTICS;
}
}
//==========================================================================
/*
========================
=
= FixOfs
=
========================
*/
void FixOfs (void)
{
VW_ScreenToScreen (displayofs,bufferofs,viewwidth/8,viewheight);
}
//==========================================================================
......@@ -1280,9 +664,9 @@ void FixOfs (void)
void WallRefresh (void)
{
//
// set up variables for this view
//
/*
set up variables for this view
*/
viewangle = player->angle;
midangle = viewangle*(FINEANGLES/ANGLES);
viewsin = sintable[viewangle];
......@@ -1293,17 +677,12 @@ void WallRefresh (void)
focaltx = viewx>>TILESHIFT;
focalty = viewy>>TILESHIFT;
viewtx = player->x >> TILESHIFT;
viewty = player->y >> TILESHIFT;
xpartialdown = viewx&(TILEGLOBAL-1);
xpartialup = TILEGLOBAL-xpartialdown;
ypartialdown = viewy&(TILEGLOBAL-1);
ypartialup = TILEGLOBAL-ypartialdown;
lastside = -1; // the first pixel is on a new wall
AsmRefresh ();
ScalePost (); // no more optimization on last post
AsmRefresh();
}
//==========================================================================
......@@ -1318,26 +697,16 @@ void WallRefresh (void)
void ThreeDRefresh (void)
{
int tracedir;
// this wouldn't need to be done except for my debugger/video wierdness
outportb (SC_INDEX,SC_MAPMASK);
//
// clear out the traced array
//
asm mov ax,ds
asm mov es,ax
asm mov di,OFFSET spotvis
asm xor ax,ax
asm mov cx,2048 // 64*64 / 2
asm rep stosw
bufferofs += screenofs;
memset (spotvis, 0, sizeof (spotvis));
//
// follow the walls from there to the right, drawwing as we go
//
DrawPlayBorder();
VGAClearScreen ();
WallRefresh ();
......@@ -1346,41 +715,390 @@ asm rep stosw
// draw all the scaled images
//
DrawScaleds(); // draw scaled stuff
DrawPlayerWeapon (); // draw player's hands
DrawPlayerWeapon (); /* draw player's hands */
//
// show screen and time last cycle
//
if (fizzlein)
{
FizzleFade(bufferofs,displayofs+screenofs,viewwidth,viewheight,20,false);
FizzleFade(xoffset, yoffset, viewwidth,viewheight,20,false);
fizzlein = false;
lasttimecount = TimeCount = 0; // don't make a big tic count
lasttimecount = 0; /* don't make a big tic count */
set_TimeCount(0);
}
bufferofs -= screenofs;
displayofs = bufferofs;
asm cli
asm mov cx,[displayofs]
asm mov dx,3d4h // CRTC address register
asm mov al,0ch // start address high register
asm out dx,al
asm inc dx
asm mov al,ch
asm out dx,al // set the high byte
asm sti
bufferofs += SCREENSIZE;
if (bufferofs > PAGE3START)
bufferofs = PAGE1START;
VL_UpdateScreen ();
frameon++;
PM_NextFrame();
}
//===========================================================================
/* xpartial = 16 bit fraction
ystep = 32 bit fixed 32,16
*/
#define xpartialbyystep() FixedByFrac (xpartial, ystep)
#define ypartialbyxstep() FixedByFrac (ypartial, xstep)
int samex (int intercept, int tile)
{
if (xtilestep > 0) {
if ((intercept>>16) >= tile)
return 0;
else
return 1;
}
else {
if ((intercept>>16) <= tile)
return 0;
else
return 1;
}
}
int samey (int intercept, int tile)
{
if (ytilestep > 0) {
if ((intercept>>16) >= tile)
return 0;
else
return 1;
}
else {
if ((intercept>>16) <= tile)
return 0;
else
return 1;
}
}
#define DEG90 900
#define DEG180 1800
#define DEG270 2700
#define DEG360 3600
void HitHorizWall (void);
void HitVertWall (void);
void HitHorizPWall (void);
void HitVertPWall (void);
int tempylock;
void AsmRefresh (void)
{
fixed doorxhit, dooryhit;
int angle; /* ray angle through pixx */
int i;
tempylock = 1;
for (i = 0; i < 4096; i++) { /* TODO: testing */
tempy[i] = tilemap[i % 64][i / 64] ? '1' : '0';
}
for (pixx = 0; pixx < viewwidth; pixx++) {
angle = midangle + pixelangle[pixx];
#ifdef DEBUGx
printf ("tracing angle = %d\n", angle);
#endif
if (angle < 0) {
/* -90 - -1 degree arc */
angle += FINEANGLES;
goto entry360;
} else if (angle < DEG90) {
/* 0-89 degree arc */
entry90:
xtilestep = 1;
ytilestep = -1;
xstep = finetangent[DEG90-1-angle];
ystep = -finetangent[angle];
xpartial = xpartialup;
ypartial = ypartialdown;
} else if (angle < DEG180) {
/* 90-179 degree arc */
xtilestep = -1;
ytilestep = -1;
xstep = -finetangent[angle-DEG90];
ystep = -finetangent[DEG180-1-angle];
xpartial = xpartialdown;
ypartial = ypartialdown;
} else if (angle < DEG270) {
/* 180-269 degree arc */
xtilestep = -1;
ytilestep = 1;
xstep = -finetangent[DEG270-1-angle];
ystep = finetangent[angle-DEG180];
xpartial = xpartialdown;
ypartial = ypartialup;
} else if (angle < DEG360) {
/* 270-359 degree arc */
entry360:
xtilestep = 1;
ytilestep = 1;
xstep = finetangent[angle-DEG270];
ystep = finetangent[DEG360-1-angle];
xpartial = xpartialup;
ypartial = ypartialup;
} else {
angle -= FINEANGLES;
goto entry90;
}
initvars:
yintercept = viewy + xpartialbyystep ();
xtile = focaltx + xtilestep;
xintercept = viewx + ypartialbyxstep ();
ytile = focalty + ytilestep;
#ifdef DEBUGx
printf ("xintercept = %d, ytile = %d\n", xintercept, ytile);
printf ("xtile = %d, yintercept = %d\n", xtile, yintercept);
#endif
/* CORE LOOP */
#define TILE(n) (n>>16)
/* check intersections with vertical walls */
vertcheck:
if (!samey (yintercept, ytile))
goto horizentry;
vertentry:
tilehit = tilemap [xtile][TILE(yintercept)];
#if DEBUGx
printf ("vert: %d %x %d, %d\n", pixx, tilehit, xtile, TILE(yintercept));
#endif
if (tilehit != 0) {
tempy[xtile + TILE(yintercept) * 64] = 'X';
if (tilehit & 0x80) {
if (tilehit & 0x40) {
/* vertpushwall */
long ytemp = yintercept + (pwallpos * ystep) / 64;
ytemp &= ~0x4000000; /* TODO: why? */
//fprintf(stderr, "VertPushWall@%d: 0x%X vs 0x%X\n", angle, yintercept, ytemp);
if (TILE(ytemp) != TILE(yintercept))
goto passvert;
yintercept = ytemp;
xintercept = xtile << 16;
HitVertPWall();
}
else {
dooryhit = yintercept + ystep / 2;
if (TILE (dooryhit) != TILE (yintercept))
goto passvert;
/* check door position */
if ((dooryhit&0xFFFF) < doorposition[tilehit&0x7f])
goto passvert;
yintercept = dooryhit;
xintercept = (xtile << 16) + 32768;
HitVertDoor ();
}
}
else {
xintercept = xtile << 16;
HitVertWall ();
}
goto nextpix;
}
passvert:
spotvis [xtile][TILE(yintercept)] = 1;
xtile += xtilestep;
yintercept += ystep;
goto vertcheck;
horizcheck:
/* check intersections with horizontal walls */
if (!samex (xintercept, xtile))
goto vertentry;
horizentry:
tilehit = tilemap [TILE(xintercept)][ytile];
#if DEBUGx
printf ("horiz: %d %x %d, %d\n", pixx, tilehit, TILE(xintercept), ytile);
#endif
if (tilehit != 0) {
tempy[TILE(xintercept) + ytile * 64] = 'Y';
if (tilehit & 0x80) {
/* horizdoor */
if (tilehit & 0x40) {
long xtemp = xintercept + (pwallpos * xstep) / 64;
xtemp &= ~0x4000000;
/* horizpushwall */
if (TILE(xtemp) != TILE(xintercept))
goto passhoriz;
xintercept = xtemp;
yintercept = ytile << 16;
HitHorizPWall();
}
else {
doorxhit = xintercept + xstep / 2;
if (TILE (doorxhit) != TILE (xintercept))
goto passhoriz;
/* check door position */
if ((doorxhit&0xFFFF) < doorposition[tilehit&0x7f])
goto passhoriz;
xintercept = doorxhit;
yintercept = (ytile << 16) + 32768;
HitHorizDoor ();
}
}
else {
yintercept = ytile << 16;
HitHorizWall ();
}
goto nextpix;
}
passhoriz:
spotvis [TILE(xintercept)][ytile] = 1;
ytile += ytilestep;
xintercept += xstep;
goto horizcheck;
nextpix:
}
tempylock = 0;
}
void HitVertWall (void)
{
int wallpic;
unsigned texture;
char *wall;
#ifdef DEBUGx
printf ("HitVertWall: xtile = %d, TILE(yintercept) = %d\n",
xtile, TILE(yintercept));
#endif
texture = (yintercept>>4)&0xfc0;
if (xtilestep == -1)
{
texture = 0xfc0-texture;
xintercept += TILEGLOBAL;
}
wallheight[pixx] = CalcHeight();
postx = pixx;
if (tilehit & 0x40)
{ // check for adjacent doors
ytile = yintercept>>TILESHIFT;
if ( tilemap[xtile-xtilestep][ytile]&0x80 )
wallpic = DOORWALL+3;
else
wallpic = vertwall[tilehit & ~0x40];
}
else
wallpic = vertwall[tilehit];
wall = PM_GetPage (wallpic);
ScalePost (wall, texture);
}
void
HitHorizWall (void)
{
int wallpic;
unsigned texture;
char *wall;
#ifdef DEBUGx
printf ("HitHorizWall: ytile = %d, TILE(xintercept) = %d\n",
ytile, TILE(xintercept));
#endif
texture = (xintercept>>4)&0xfc0;
if (ytilestep == -1)
yintercept += TILEGLOBAL;
else
texture = 0xfc0-texture;
wallheight[pixx] = CalcHeight();
postx = pixx;
if (tilehit & 0x40)
{ // check for adjacent doors
xtile = xintercept>>TILESHIFT;
if ( tilemap[xtile][ytile-ytilestep]&0x80 )
wallpic = DOORWALL+2;
else
wallpic = horizwall[tilehit & ~0x40];
}
else
wallpic = horizwall[tilehit];
wall = PM_GetPage (wallpic);
ScalePost (wall, texture);
}
/*
====================
=
= HitHorizPWall
=
= A pushable wall in action has been hit
=
====================
*/
void HitHorizPWall (void)
{
int wallpic;
unsigned texture,offset;
byte *wall;
texture = (xintercept>>4)&0xfc0;
offset = pwallpos<<10;
if (ytilestep == -1)
yintercept += TILEGLOBAL-offset;
else
{
texture = 0xfc0-texture;
yintercept += offset;
}
wallheight[pixx] = CalcHeight();
postx = pixx;
wallpic = horizwall[tilehit&63];
wall = PM_GetPage (wallpic);
ScalePost (wall, texture);
}
/*
====================
=
= HitVertPWall
=
= A pushable wall in action has been hit
=
====================
*/
void HitVertPWall (void)
{
int wallpic;
unsigned texture,offset;
byte *wall;
texture = (yintercept>>4)&0xfc0;
offset = pwallpos<<10;
if (xtilestep == -1)
{
xintercept += TILEGLOBAL-offset;
texture = 0xfc0-texture;
}
else
xintercept += offset;
wallheight[pixx] = CalcHeight();
postx = pixx;
wallpic = vertwall[tilehit&63];
wall = PM_GetPage (wallpic);
ScalePost (wall, texture);
}
......@@ -61,6 +61,7 @@ int mouseadjustment;
char configname[13]="config.";
unsigned xoffset, yoffset;
int _argc;
char **argv;
......@@ -690,7 +691,6 @@ void SignonScreen (void) // VGA version
if (!virtualreality)
{
VL_MungePic (&introscn,320,200);
VL_MemToScreen (&introscn,320,200,0,0);
}
}
......@@ -1211,7 +1211,10 @@ boolean SetViewSize (unsigned width, unsigned height)
centerx = viewwidth/2-1;
shootdelta = viewwidth/10;
screenofs = ((200-STATUSLINES-viewheight)/2*SCREENWIDTH+(320-viewwidth)/8);
yoffset = (200-STATUSLINES-viewheight)/2
xoffset = (320-viewwidth)/2;
//
// calculate trace angles and projection constants
//
......
// WL_SCALE.C
/* wl_scale.c */
#include "WL_DEF.H"
#pragma hdrstop
#include "wl_def.h"
#define OP_RETF 0xcb
extern unsigned xoffset, yoffset;
/*
=============================================================================
......@@ -13,42 +12,53 @@
=============================================================================
*/
t_compscale *scaledirectory[MAXSCALEHEIGHT+1];
long fullscalefarcall[MAXSCALEHEIGHT+1];
/* scaling data for a given height */
typedef struct {
/* number of destination pixels each source pixels maps to in x and y */
unsigned count [65];
/* the destination pixel for each source pixel row */
short desty [65];
} t_scaledata;
int maxscale,maxscaleshl2;
t_scaledata scaledata [MAXSCALEHEIGHT+1];
boolean insetupscaling;
int maxscale,maxscaleshl2;
/*
=============================================================================
unsigned BuildCompScale(int height)
{
LOCALS
int i;
long fix,step;
unsigned src,totalscaled,totalsize;
int startpix,endpix,toppix;
=============================================================================
*/
t_compscale *work;
unsigned BuildCompScale (int height, memptr *finalspot);
step = ((long)height<<16) / 64;
toppix = (viewheight-height)/2;
fix = 0;
int stepbytwo;
for (src=0;src<=64;src++)
{
startpix = fix>>16;
fix += step;
endpix = fix>>16;
if (endpix>startpix)
scaledata [height].count[src] = endpix-startpix;
else
scaledata [height].count[src] = 0;
//===========================================================================
startpix+=toppix;
endpix+=toppix;
/*
==============
=
= BadScale
=
==============
*/
if (startpix == endpix || endpix < 0 || startpix >= viewheight || src == 64)
/* source pixel goes off screen */
scaledata [height].desty [src] = -1;
else
scaledata [height].desty [src] = startpix;
}
void far BadScale (void)
{
Quit ("BadScale called!");
}
/*
==========================
=
......@@ -60,72 +70,19 @@ void far BadScale (void)
void SetupScaling (int maxscaleheight)
{
int i,x,y;
byte far *dest;
insetupscaling = true;
maxscaleheight/=2; // one scaler every two pixels
byte *dest;
maxscale = maxscaleheight-1;
maxscaleshl2 = maxscale<<2;
//
// free up old scalers
//
for (i=1;i<MAXSCALEHEIGHT;i++)
{
if (scaledirectory[i])
MM_FreePtr (&(memptr)scaledirectory[i]);
if (i>=stepbytwo)
i += 2;
}
memset (scaledirectory,0,sizeof(scaledirectory));
MM_SortMem ();
//
// build the compiled scalers
//
stepbytwo = viewheight/2; // save space by double stepping
MM_GetPtr (&(memptr)work,20000);
for (i=1;i<=maxscaleheight;i++)
{
BuildCompScale (i*2,&(memptr)scaledirectory[i]);
if (i>=stepbytwo)
i+= 2;
}
MM_FreePtr (&(memptr)work);
//
// compact memory and lock down scalers
//
MM_SortMem ();
for (i=1;i<=maxscaleheight;i++)
{
MM_SetLock (&(memptr)scaledirectory[i],true);
fullscalefarcall[i] = (unsigned)scaledirectory[i];
fullscalefarcall[i] <<=16;
fullscalefarcall[i] += scaledirectory[i]->codeofs[0];
if (i>=stepbytwo)
{
scaledirectory[i+1] = scaledirectory[i];
fullscalefarcall[i+1] = fullscalefarcall[i];
scaledirectory[i+2] = scaledirectory[i];
fullscalefarcall[i+2] = fullscalefarcall[i];
i+=2;
}
BuildCompScale (i);
}
scaledirectory[0] = scaledirectory[1];
fullscalefarcall[0] = fullscalefarcall[1];
//
// check for oversize wall drawing
//
for (i=maxscaleheight;i<MAXSCALEHEIGHT;i++)
fullscalefarcall[i] = (long)BadScale;
insetupscaling = false;
}
//===========================================================================
......@@ -150,81 +107,44 @@ void SetupScaling (int maxscaleheight)
========================
*/
unsigned BuildCompScale (int height, memptr *finalspot)
unsigned xBuildCompScale (int height, byte *source, int x)
{
byte far *code;
int i;
long fix,step;
unsigned src,totalscaled,totalsize;
int startpix,endpix,toppix;
step = ((long)height<<16) / 64;
code = &work->code[0];
toppix = (viewheight-height)/2;
int startpix,endpix,toppix;
unsigned char al;
step = height << 10;
toppix = (viewheight-height) >> 1;
fix = 0;
for (src=0;src<=64;src++)
for (i = 0; i < 64; i++)
{
startpix = fix>>16;
fix += step;
endpix = fix>>16;
if (endpix>startpix)
work->width[src] = endpix-startpix;
else
work->width[src] = 0;
//
// mark the start of the code
//
work->codeofs[src] = FP_OFF(code);
//
// compile some code if the source pixel generates any screen pixels
//
startpix+=toppix;
endpix+=toppix;
if (startpix == endpix || endpix < 0 || startpix >= viewheight || src == 64)
if (startpix == endpix || endpix < 0 || startpix >= viewheight)
continue;
//
// mov al,[si+src]
//
*code++ = 0x8a;
*code++ = 0x44;
*code++ = src;
al = source[i];
for (;startpix<endpix;startpix++)
{
if (startpix >= viewheight)
break; // off the bottom of the view area
if (startpix < 0)
continue; // not into the view area
//
// mov [es:di+heightofs],al
//
*code++ = 0x26;
*code++ = 0x88;
*code++ = 0x85;
*((unsigned far *)code)++ = startpix*SCREENBWIDE;
if (startpix >= viewheight)
break; /* off the bottom of the view area */
if (startpix < 0)
continue; /* not into the view area */
VL_Plot(x+xoffset, startpix+yoffset, al);
}
}
//
// retf
//
*code++ = 0xcb;
totalsize = FP_OFF(code);
MM_GetPtr (finalspot,totalsize);
_fmemcpy ((byte *)(*finalspot),(byte *)work,totalsize);
return totalsize;
}
......@@ -238,162 +158,54 @@ unsigned BuildCompScale (int height, memptr *finalspot)
=======================
*/
extern int slinex,slinewidth;
extern unsigned far *linecmds;
extern long linescale;
extern unsigned maskword;
byte mask1,mask2,mask3;
int slinex,slinewidth;
short *linecmds;
int linescale;
unsigned maskword;
t_compshape *shapeptr;
/* linecmds - points to line segment data
slinewidth - pixels across
slinex - screen coord of first column
*/
void ScaleLine (void)
{
asm mov cx,WORD PTR [linescale+2]
asm mov es,cx // segment of scaler
asm mov bp,WORD PTR [linecmds]
asm mov dx,SC_INDEX+1 // to set SC_MAPMASK
asm mov bx,[slinex]
asm mov di,bx
asm shr di,2 // X in bytes
asm add di,[bufferofs]
asm and bx,3
asm shl bx,3
asm add bx,[slinewidth] // bx = (pixel*8+pixwidth)
asm mov al,BYTE [mapmasks3-1+bx] // -1 because pixwidth of 1 is first
asm mov ds,WORD PTR [linecmds+2]
asm or al,al
asm jz notthreebyte // scale across three bytes
asm jmp threebyte
notthreebyte:
asm mov al,BYTE PTR ss:[mapmasks2-1+bx] // -1 because pixwidth of 1 is first
asm or al,al
asm jnz twobyte // scale across two bytes
//
// one byte scaling
//
asm mov al,BYTE PTR ss:[mapmasks1-1+bx] // -1 because pixwidth of 1 is first
asm out dx,al // set map mask register
scalesingle:
asm mov bx,[ds:bp] // table location of rtl to patch
asm or bx,bx
asm jz linedone // 0 signals end of segment list
asm mov bx,[es:bx]
asm mov dl,[es:bx] // save old value
asm mov BYTE PTR es:[bx],OP_RETF // patch a RETF in
asm mov si,[ds:bp+4] // table location of entry spot
asm mov ax,[es:si]
asm mov WORD PTR ss:[linescale],ax // call here to start scaling
asm mov si,[ds:bp+2] // corrected top of shape for this segment
asm add bp,6 // next segment list
asm mov ax,SCREENSEG
asm mov es,ax
asm call ss:[linescale] // scale the segment of pixels
asm mov es,cx // segment of scaler
asm mov BYTE PTR es:[bx],dl // unpatch the RETF
asm jmp scalesingle // do the next segment
//
// done
//
linedone:
asm mov ax,ss
asm mov ds,ax
return;
//
// two byte scaling
//
twobyte:
asm mov ss:[mask2],al
asm mov al,BYTE PTR ss:[mapmasks1-1+bx] // -1 because pixwidth of 1 is first
asm mov ss:[mask1],al
scaledouble:
asm mov bx,[ds:bp] // table location of rtl to patch
asm or bx,bx
asm jz linedone // 0 signals end of segment list
asm mov bx,[es:bx]
asm mov cl,[es:bx] // save old value
asm mov BYTE PTR es:[bx],OP_RETF // patch a RETF in
asm mov si,[ds:bp+4] // table location of entry spot
asm mov ax,[es:si]
asm mov WORD PTR ss:[linescale],ax // call here to start scaling
asm mov si,[ds:bp+2] // corrected top of shape for this segment
asm add bp,6 // next segment list
asm mov ax,SCREENSEG
asm mov es,ax
asm mov al,ss:[mask1]
asm out dx,al // set map mask register
asm call ss:[linescale] // scale the segment of pixels
asm inc di
asm mov al,ss:[mask2]
asm out dx,al // set map mask register
asm call ss:[linescale] // scale the segment of pixels
asm dec di
asm mov es,WORD PTR ss:[linescale+2] // segment of scaler
asm mov BYTE PTR es:[bx],cl // unpatch the RETF
asm jmp scaledouble // do the next segment
//
// three byte scaling
//
threebyte:
asm mov ss:[mask3],al
asm mov al,BYTE PTR ss:[mapmasks2-1+bx] // -1 because pixwidth of 1 is first
asm mov ss:[mask2],al
asm mov al,BYTE PTR ss:[mapmasks1-1+bx] // -1 because pixwidth of 1 is first
asm mov ss:[mask1],al
scaletriple:
asm mov bx,[ds:bp] // table location of rtl to patch
asm or bx,bx
asm jz linedone // 0 signals end of segment list
asm mov bx,[es:bx]
asm mov cl,[es:bx] // save old value
asm mov BYTE PTR es:[bx],OP_RETF // patch a RETF in
asm mov si,[ds:bp+4] // table location of entry spot
asm mov ax,[es:si]
asm mov WORD PTR ss:[linescale],ax // call here to start scaling
asm mov si,[ds:bp+2] // corrected top of shape for this segment
asm add bp,6 // next segment list
asm mov ax,SCREENSEG
asm mov es,ax
asm mov al,ss:[mask1]
asm out dx,al // set map mask register
asm call ss:[linescale] // scale the segment of pixels
asm inc di
asm mov al,ss:[mask2]
asm out dx,al // set map mask register
asm call ss:[linescale] // scale the segment of pixels
asm inc di
asm mov al,ss:[mask3]
asm out dx,al // set map mask register
asm call ss:[linescale] // scale the segment of pixels
asm dec di
asm dec di
asm mov es,WORD PTR ss:[linescale+2] // segment of scaler
asm mov BYTE PTR es:[bx],cl // unpatch the RETF
asm jmp scaletriple // do the next segment
int x, y, ys;
int n, ny;
int y0, y1;
unsigned char *pixels;
unsigned char color;
#ifdef DEBUGx
printf ("ScaleLine\n");
printf (" slinex = %d, slinewidth = %d\n", slinex, slinewidth);
#endif
while (linecmds[0]) {
y0 = linecmds[2]/2;
y1 = linecmds[0]/2 - 1;
pixels = (unsigned char *) shapeptr + y0 + linecmds[1];
#ifdef DEBUGx
printf (" y0,y1 = %d,%d pixels = 0x%8x\n", y0, y1, pixels);
#endif
for (y=y0; y<=y1; y++) {
ys = scaledata[linescale].desty[y];
color = *pixels++;
if (ys >= 0) {
//color = *pixels++;
for (ny=0; ny<scaledata[linescale].count[y]; ny++) {
for (n=0,x=slinex; n<slinewidth; n++, x++) {
// fprintf(stderr, " (%d,%d)\n", x, ys+ny);
//if (ys < 0) continue;
VL_Plot(x+xoffset, ys+ny+yoffset, color);
}
}
}
}
linecmds += 3;
}
}
/*
=======================
=
......@@ -420,36 +232,36 @@ static long longtemp;
void ScaleShape (int xcenter, int shapenum, unsigned height)
{
t_compshape *shape;
t_compscale *comptable;
t_compshape *shape;
unsigned scale,srcx,stopx,tempx;
int t;
unsigned far *cmdptr;
word *cmdptr;
boolean leftvis,rightvis;
//printf ("ScaleShape (xcenter=%d, shapenum=%d, height=%d)\n",
// xcenter, shapenum, height);
shape = PM_GetSpritePage (shapenum);
scale = height>>3; // low three bits are fractional
scale = height>>2; // low three bits are fractional
if (!scale || scale>maxscale)
return; // too close or far away
comptable = scaledirectory[scale];
*(((unsigned *)&linescale)+1)=(unsigned)comptable; // seg of far call
*(((unsigned *)&linecmds)+1)=(unsigned)shape; // seg of shape
linescale = scale;
shapeptr = shape;
//
// scale to the left (from pixel 31 to shape->leftpix)
//
srcx = 32;
slinex = xcenter;
stopx = shape->leftpix;
cmdptr = &shape->dataofs[31-stopx];
cmdptr = (word *)&(shape->dataofs[31-stopx]);
while ( --srcx >=stopx && slinex>0)
{
(unsigned)linecmds = *cmdptr--;
if ( !(slinewidth = comptable->width[srcx]) )
linecmds = (short *)((char *) shapeptr + *cmdptr--);
if ( !(slinewidth = scaledata[scale].count[srcx]) )
continue;
if (slinewidth == 1)
......@@ -520,19 +332,19 @@ void ScaleShape (int xcenter, int shapenum, unsigned height)
if (shape->leftpix<31)
{
srcx = 31;
cmdptr = &shape->dataofs[32-shape->leftpix];
cmdptr = (word *)&shape->dataofs[32-shape->leftpix];
}
else
{
srcx = shape->leftpix-1;
cmdptr = &shape->dataofs[0];
cmdptr = (word *)&shape->dataofs[0];
}
slinewidth = 0;
while ( ++srcx <= stopx && (slinex+=slinewidth)<viewwidth)
{
(unsigned)linecmds = *cmdptr++;
if ( !(slinewidth = comptable->width[srcx]) )
linecmds = (short *)((char *) shapeptr + *cmdptr++);
if ( !(slinewidth = scaledata[scale].count[srcx]) )
continue;
if (slinewidth == 1)
......@@ -624,36 +436,35 @@ void ScaleShape (int xcenter, int shapenum, unsigned height)
void SimpleScaleShape (int xcenter, int shapenum, unsigned height)
{
t_compshape *shape;
t_compscale *comptable;
t_compshape *shape;
unsigned scale,srcx,stopx,tempx;
int t;
unsigned far *cmdptr;
unsigned short *cmdptr;
boolean leftvis,rightvis;
//printf ("SimpleScaleShape (xcenter=%d, shapenum=%d, height=%d)\n",
// xcenter, shapenum, height);
shape = PM_GetSpritePage (shapenum);
scale = height>>1;
comptable = scaledirectory[scale];
*(((unsigned *)&linescale)+1)=(unsigned)comptable; // seg of far call
*(((unsigned *)&linecmds)+1)=(unsigned)shape; // seg of shape
scale = height;
/* *(((unsigned *)&linescale)+1)=(unsigned)comptable; // seg of far call */
linescale = scale;
shapeptr = shape;
//
// scale to the left (from pixel 31 to shape->leftpix)
//
srcx = 32;
slinex = xcenter;
stopx = shape->leftpix;
cmdptr = &shape->dataofs[31-stopx];
cmdptr = (word *)&shape->dataofs[31-stopx];
while ( --srcx >=stopx )
{
(unsigned)linecmds = *cmdptr--;
if ( !(slinewidth = comptable->width[srcx]) )
linecmds = (short *)((char *) shapeptr + *cmdptr--);
if ( !(slinewidth = scaledata[scale].count[srcx]) )
continue;
slinex -= slinewidth;
ScaleLine ();
}
......@@ -667,67 +478,22 @@ void SimpleScaleShape (int xcenter, int shapenum, unsigned height)
if (shape->leftpix<31)
{
srcx = 31;
cmdptr = &shape->dataofs[32-shape->leftpix];
cmdptr = (word *)&shape->dataofs[32-shape->leftpix];
}
else
{
srcx = shape->leftpix-1;
cmdptr = &shape->dataofs[0];
cmdptr = (word *)&shape->dataofs[0];
}
slinewidth = 0;
while ( ++srcx <= stopx )
{
(unsigned)linecmds = *cmdptr++;
if ( !(slinewidth = comptable->width[srcx]) )
linecmds = (short *)((char *) shapeptr + *cmdptr++);
if ( !(slinewidth = scaledata[scale].count[srcx]) )
continue;
ScaleLine ();
slinex+=slinewidth;
}
}
//
// bit mask tables for drawing scaled strips up to eight pixels wide
//
// down here so the STUPID inline assembler doesn't get confused!
//
byte mapmasks1[4][8] = {
{1 ,3 ,7 ,15,15,15,15,15},
{2 ,6 ,14,14,14,14,14,14},
{4 ,12,12,12,12,12,12,12},
{8 ,8 ,8 ,8 ,8 ,8 ,8 ,8} };
byte mapmasks2[4][8] = {
{0 ,0 ,0 ,0 ,1 ,3 ,7 ,15},
{0 ,0 ,0 ,1 ,3 ,7 ,15,15},
{0 ,0 ,1 ,3 ,7 ,15,15,15},
{0 ,1 ,3 ,7 ,15,15,15,15} };
byte mapmasks3[4][8] = {
{0 ,0 ,0 ,0 ,0 ,0 ,0 ,0},
{0 ,0 ,0 ,0 ,0 ,0 ,0 ,1},
{0 ,0 ,0 ,0 ,0 ,0 ,1 ,3},
{0 ,0 ,0 ,0 ,0 ,1 ,3 ,7} };
unsigned wordmasks[8][8] = {
{0x0080,0x00c0,0x00e0,0x00f0,0x00f8,0x00fc,0x00fe,0x00ff},
{0x0040,0x0060,0x0070,0x0078,0x007c,0x007e,0x007f,0x807f},
{0x0020,0x0030,0x0038,0x003c,0x003e,0x003f,0x803f,0xc03f},
{0x0010,0x0018,0x001c,0x001e,0x001f,0x801f,0xc01f,0xe01f},
{0x0008,0x000c,0x000e,0x000f,0x800f,0xc00f,0xe00f,0xf00f},
{0x0004,0x0006,0x0007,0x8007,0xc007,0xe007,0xf007,0xf807},
{0x0002,0x0003,0x8003,0xc003,0xe003,0xf003,0xf803,0xfc03},
{0x0001,0x8001,0xc001,0xe001,0xf001,0xf801,0xfc01,0xfe01} };
int slinex,slinewidth;
unsigned far *linecmds;
long linescale;
unsigned maskword;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment