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

Even more cleanups!

parent a95bbccf
...@@ -33,7 +33,7 @@ typedef struct ...@@ -33,7 +33,7 @@ typedef struct
byte *tinf; byte *tinf;
int mapon; int mapon;
unsigned *mapsegs[MAPPLANES]; word *mapsegs[MAPPLANES];
maptype *mapheaderseg[NUMMAPS]; maptype *mapheaderseg[NUMMAPS];
byte *audiosegs[NUMSNDCHUNKS]; byte *audiosegs[NUMSNDCHUNKS];
void *grsegs[NUMCHUNKS]; void *grsegs[NUMCHUNKS];
......
...@@ -23,7 +23,7 @@ typedef struct ...@@ -23,7 +23,7 @@ typedef struct
extern byte *tinf; extern byte *tinf;
extern int mapon; extern int mapon;
extern unsigned *mapsegs[MAPPLANES]; extern word *mapsegs[MAPPLANES];
extern maptype *mapheaderseg[NUMMAPS]; extern maptype *mapheaderseg[NUMMAPS];
extern byte *audiosegs[NUMSNDCHUNKS]; extern byte *audiosegs[NUMSNDCHUNKS];
extern void *grsegs[NUMCHUNKS]; extern void *grsegs[NUMCHUNKS];
......
...@@ -11,7 +11,6 @@ pictabletype *pictable; ...@@ -11,7 +11,6 @@ pictabletype *pictable;
int px,py; int px,py;
byte fontcolor,backcolor; byte fontcolor,backcolor;
int fontnumber; int fontnumber;
int bufferwidth, bufferheight;
/* ======================================================================== */ /* ======================================================================== */
...@@ -19,107 +18,39 @@ void VW_DrawPropString(char *string) ...@@ -19,107 +18,39 @@ void VW_DrawPropString(char *string)
{ {
fontstruct *font; fontstruct *font;
int width, step, height, i; int width, step, height, i;
byte *source, *dest, *origdest; byte *source, *dest, *ptrs, *ptrd;
byte ch, mask; byte ch;
font = (fontstruct *)grsegs[STARTFONT+fontnumber]; font = (fontstruct *)grsegs[STARTFONT+fontnumber];
height = bufferheight = font->height; height = font->height;
dest = origdest = MK_FP(SCREENSEG,bufferofs+ylookup[py]+(px>>2)); dest = gfxbuf + py * 320 + px;
mask = 1<<(px&3);
while ((ch = *string++) != 0) {
while ((ch = *string++)!=0)
{
width = step = font->width[ch]; width = step = font->width[ch];
source = ((byte *)font)+font->location[ch]; source = ((byte *)font)+font->location[ch];
while (width--) while (width--) {
{ height = font->height;
VGAMAPMASK(mask); ptrs = source;
ptrd = dest;
asm mov ah,[BYTE PTR fontcolor] while (height--) {
asm mov bx,[step] if (*ptrs)
asm mov cx,[height] *ptrd = fontcolor;
asm mov dx,[linewidth] ptrs += step;
asm lds si,[source] ptrd += 320;
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++; source++;
px++;
mask <<= 1;
if (mask == 16)
{
mask = 1;
dest++; 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) fontstruct *font)
{ {
/* proportional width */
*height = font->height; *height = font->height;
for (*width = 0;*string;string++) 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)
...@@ -135,66 +66,8 @@ void VW_MeasurePropString (char *string, word *width, word *height) ...@@ -135,66 +66,8 @@ 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) 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);
} }
...@@ -208,44 +81,36 @@ 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; width = pictable[picnum].width;
height = pictable[picnum].height; 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) void VWB_DrawPropString(char *string)
{ {
int x;
x=px;
VW_DrawPropString (string); 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) 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) 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) 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) 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 (); VH_UpdateScreen ();
} }
...@@ -287,11 +152,11 @@ void LatchDrawPic (unsigned x, unsigned y, unsigned picnum) ...@@ -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; int i,j,p,m,width,height,start,end;
byte *src; byte *src;
unsigned destoff; word destoff;
/* /*
tile 8s tile 8s
...@@ -344,7 +209,6 @@ void LoadLatchMem (void) ...@@ -344,7 +209,6 @@ void LoadLatchMem (void)
UNCACHEGRCHUNK(i); UNCACHEGRCHUNK(i);
} }
VGAMAPMASK(15);
} }
/* ======================================================================== */ /* ======================================================================== */
...@@ -376,15 +240,12 @@ boolean FizzleFade (unsigned source, unsigned dest, ...@@ -376,15 +240,12 @@ boolean FizzleFade (unsigned source, unsigned dest,
IN_StartAck (); IN_StartAck ();
TimeCount=frame=0; TimeCount=frame=0;
do // while (1) do {
{ if (abortable && IN_CheckAck ())
if (abortable && IN_CheckAck () )
return true; return true;
asm mov es,[screenseg] for (p=0;p<pixperframe;p++) {
#if 0
for (p=0;p<pixperframe;p++)
{
// //
// seperate random value into x/y pair // seperate random value into x/y pair
// //
...@@ -426,11 +287,13 @@ noxor: ...@@ -426,11 +287,13 @@ noxor:
asm add di,[pagedelta] asm add di,[pagedelta]
asm mov [es:di],al asm mov [es:di],al
if (rndval == 1) // entire sequence has been completed #endif
if (rndval == 1) /* entire sequence has been completed */
return false; return false;
} }
frame++; frame++;
while (TimeCount<frame) // don't go too fast while (TimeCount<frame)
; ;
} while (1); } while (1);
} }
...@@ -39,8 +39,6 @@ void VL_Hlin (unsigned x, unsigned y, unsigned width, unsigned color); ...@@ -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_Vlin (int x, int y, int height, int color);
void VL_Bar (int x, int y, int width, 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_MemToLatch (byte *source, int width, int height, word dest);
void VL_ScreenToScreen (unsigned source, unsigned dest,int width, int height); void VL_ScreenToScreen (unsigned source, unsigned dest,int width, int height);
void VL_MemToScreen (byte *source, int width, int height, int x, int y); void VL_MemToScreen (byte *source, int width, int height, int x, int y);
......
// WL_ACT1.C /* wl_act1.c */
#include "WL_DEF.H" #include "wl_def.h"
#pragma hdrstop
/* /*
============================================================================= =============================================================================
...@@ -275,7 +274,7 @@ int doornum; ...@@ -275,7 +274,7 @@ int doornum;
unsigned doorposition[MAXDOORS]; // leading edge of door 0=closed unsigned doorposition[MAXDOORS]; // leading edge of door 0=closed
// 0xffff = fully open // 0xffff = fully open
byte far areaconnect[NUMAREAS][NUMAREAS]; byte areaconnect[NUMAREAS][NUMAREAS];
boolean areabyplayer[NUMAREAS]; boolean areabyplayer[NUMAREAS];
...@@ -350,7 +349,7 @@ void InitDoorList (void) ...@@ -350,7 +349,7 @@ void InitDoorList (void)
void SpawnDoor (int tilex, int tiley, boolean vertical, int lock) void SpawnDoor (int tilex, int tiley, boolean vertical, int lock)
{ {
int areanumber; int areanumber;
unsigned far *map; word *map;
if (doornum==64) if (doornum==64)
Quit ("64+ doors on level!"); Quit ("64+ doors on level!");
...@@ -369,7 +368,7 @@ void SpawnDoor (int tilex, int tiley, boolean vertical, int lock) ...@@ -369,7 +368,7 @@ void SpawnDoor (int tilex, int tiley, boolean vertical, int lock)
// for door sides // for door sides
// //
tilemap[tilex][tiley] = doornum | 0x80; tilemap[tilex][tiley] = doornum | 0x80;
map = mapsegs[0] + farmapylookup[tiley]+tilex; map = (word *)(mapsegs[0] + farmapylookup[tiley]+tilex);
if (vertical) if (vertical)
{ {
*map = *(map-1); // set area number *map = *(map-1); // set area number
...@@ -554,7 +553,7 @@ void DoorOpen (int door) ...@@ -554,7 +553,7 @@ void DoorOpen (int door)
void DoorOpening (int door) void DoorOpening (int door)
{ {
int area1,area2; int area1,area2;
unsigned far *map; word *map;
long position; long position;
position = doorposition[door]; position = doorposition[door];
...@@ -563,8 +562,8 @@ void DoorOpening (int door) ...@@ -563,8 +562,8 @@ void DoorOpening (int door)
// //
// door is just starting to open, so connect the areas // door is just starting to open, so connect the areas
// //
map = mapsegs[0] + farmapylookup[doorobjlist[door].tiley] map = (word *)(mapsegs[0] + farmapylookup[doorobjlist[door].tiley]
+doorobjlist[door].tilex; +doorobjlist[door].tilex);
if (doorobjlist[door].vertical) if (doorobjlist[door].vertical)
{ {
...@@ -617,7 +616,7 @@ void DoorOpening (int door) ...@@ -617,7 +616,7 @@ void DoorOpening (int door)
void DoorClosing (int door) void DoorClosing (int door)
{ {
int area1,area2,move; int area1,area2,move;
unsigned far *map; word *map;
long position; long position;
int tilex,tiley; int tilex,tiley;
...@@ -646,8 +645,8 @@ void DoorClosing (int door) ...@@ -646,8 +645,8 @@ void DoorClosing (int door)
doorobjlist[door].action = dr_closed; doorobjlist[door].action = dr_closed;
map = mapsegs[0] + farmapylookup[doorobjlist[door].tiley] map = (word *)(mapsegs[0] + farmapylookup[doorobjlist[door].tiley]
+doorobjlist[door].tilex; +doorobjlist[door].tilex);
if (doorobjlist[door].vertical) if (doorobjlist[door].vertical)
{ {
......
...@@ -653,7 +653,7 @@ typedef enum { ...@@ -653,7 +653,7 @@ typedef enum {
} weapontype; } weapontype;
typedef enum { /* typedef */ enum {
gd_baby, gd_baby,
gd_easy, gd_easy,
gd_medium, gd_medium,
...@@ -1008,7 +1008,7 @@ typedef struct ...@@ -1008,7 +1008,7 @@ typedef struct
{ {
unsigned codeofs[65]; unsigned codeofs[65];
unsigned width[65]; unsigned width[65];
byte code[]; byte *code;
} t_compscale; } t_compscale;
typedef struct typedef struct
......
/* wl_draw.c */ // WL_DRAW.C
#include "wl_def.h" #include "wl_def.h"
/*
=============================================================================
LOCAL CONSTANTS
=============================================================================
*/
// the door is the last picture before the sprites // the door is the last picture before the sprites
#define DOORWALL (PMSpriteStart-8) #define DOORWALL (PMSpriteStart-8)
#define ACTORSIZE 0x4000 #define ACTORSIZE 0x4000
/*
=============================================================================
GLOBAL VARIABLES
=============================================================================
*/
unsigned screenloc[3]= {PAGE1START,PAGE2START,PAGE3START};
unsigned freelatch = FREESTART;
long lasttimecount; long lasttimecount;
long frameon; long frameon;
...@@ -33,15 +14,17 @@ long frameon; ...@@ -33,15 +14,17 @@ long frameon;
unsigned wallheight[MAXVIEWWIDTH]; unsigned wallheight[MAXVIEWWIDTH];
fixed tileglobal = TILEGLOBAL; fixed tileglobal = TILEGLOBAL;
fixed mindist = MINDIST;
#define mindist MINDIST
unsigned char tempy[4096]; /* TODO: testing code only... */
// //
// math tables // math tables
// //
int pixelangle[MAXVIEWWIDTH]; int pixelangle[MAXVIEWWIDTH];
long far finetangent[FINEANGLES/4]; long finetangent[FINEANGLES/4];
fixed far sintable[ANGLES+ANGLES/4],far *costable = sintable+(ANGLES/4); fixed sintable[ANGLES+ANGLES/4+1],*costable = sintable+(ANGLES/4);
// //
// refresh variables // refresh variables
...@@ -50,37 +33,23 @@ fixed viewx,viewy; // the focal point ...@@ -50,37 +33,23 @@ fixed viewx,viewy; // the focal point
int viewangle; int viewangle;
fixed viewsin,viewcos; fixed viewsin,viewcos;
fixed FixedByFrac (fixed a, fixed b);
void TransformActor (objtype *ob); void TransformActor (objtype *ob);
void BuildTables (void); void BuildTables (void);
void ClearScreen (void); void ClearScreen (void);
int CalcRotate (objtype *ob); int CalcRotate (objtype *ob);
void DrawScaleds (void); void DrawScaleds (void);
void CalcTics (void); void CalcTics (void);
void FixOfs (void);
void ThreeDRefresh (void); void ThreeDRefresh (void);
unsigned char crapmap[4096]; /* TODO: remove this testing code */
//
// wall optimization variables
//
int lastside; // true for vertical
long lastintercept;
int lasttilehit;
// //
// ray tracing variables // ray tracing variables
// //
int focaltx,focalty,viewtx,viewty; int focaltx,focalty;
int midangle,angle; int midangle,angle;
unsigned xpartial,ypartial; unsigned xpartial,ypartial;
unsigned xpartialup,xpartialdown,ypartialup,ypartialdown; unsigned xpartialup,xpartialdown,ypartialup,ypartialdown;
unsigned xinttile,yinttile;
unsigned tilehit; unsigned tilehit;
unsigned pixx; unsigned pixx;
...@@ -92,29 +61,9 @@ long xstep,ystep; ...@@ -92,29 +61,9 @@ long xstep,ystep;
int horizwall[MAXWALLTILES],vertwall[MAXWALLTILES]; int horizwall[MAXWALLTILES],vertwall[MAXWALLTILES];
extern unsigned xoffset, yoffset;
/* void AsmRefresh (void);
=============================================================================
LOCAL VARIABLES
=============================================================================
*/
void AsmRefresh (void); // in WL_DR_A.ASM
/*
============================================================================
3 - D DEFINITIONS
============================================================================
*/
//==========================================================================
/* /*
======================== ========================
...@@ -126,52 +75,18 @@ void AsmRefresh (void); // in WL_DR_A.ASM ...@@ -126,52 +75,18 @@ void AsmRefresh (void); // in WL_DR_A.ASM
= =
======================== ========================
*/ */
#if 0
#pragma warn -rvl // I stick the return value in with ASMs
fixed FixedByFrac (fixed a, fixed b) fixed FixedByFrac (fixed a, fixed b)
{ {
// long long ra = a;
// setup long long rb = b;
// long long r;
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:;
r = ra * rb;
r >>= 16;
return (fixed)r;
} }
#endif
#pragma warn +rvl
//========================================================================== //==========================================================================
...@@ -200,9 +115,7 @@ ansok:; ...@@ -200,9 +115,7 @@ ansok:;
// //
void TransformActor (objtype *ob) void TransformActor (objtype *ob)
{ {
int ratio;
fixed gx,gy,gxt,gyt,nx,ny; fixed gx,gy,gxt,gyt,nx,ny;
long temp;
// //
// translate point to view centered coordinates // translate point to view centered coordinates
...@@ -232,24 +145,16 @@ void TransformActor (objtype *ob) ...@@ -232,24 +145,16 @@ void TransformActor (objtype *ob)
ob->transx = nx; ob->transx = nx;
ob->transy = ny; 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; ob->viewheight = 0;
return; return;
} }
ob->viewx = centerx + ny*scale/nx; // DEBUG: use assembly divide ob->viewx = centerx + ny*scale/nx;
// ob->viewheight = heightnumerator/(nx>>8);
// 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 = temp;
} }
//========================================================================== //==========================================================================
...@@ -277,9 +182,7 @@ void TransformActor (objtype *ob) ...@@ -277,9 +182,7 @@ void TransformActor (objtype *ob)
boolean TransformTile (int tx, int ty, int *dispx, int *dispheight) boolean TransformTile (int tx, int ty, int *dispx, int *dispheight)
{ {
int ratio;
fixed gx,gy,gxt,gyt,nx,ny; fixed gx,gy,gxt,gyt,nx,ny;
long temp;
// //
// translate point to view centered coordinates // translate point to view centered coordinates
...@@ -305,7 +208,7 @@ boolean TransformTile (int tx, int ty, int *dispx, int *dispheight) ...@@ -305,7 +208,7 @@ boolean TransformTile (int tx, int ty, int *dispx, int *dispheight)
// //
// calculate perspective ratio // 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; *dispheight = 0;
return false; return false;
...@@ -313,16 +216,7 @@ boolean TransformTile (int tx, int ty, int *dispx, int *dispheight) ...@@ -313,16 +216,7 @@ boolean TransformTile (int tx, int ty, int *dispx, int *dispheight)
*dispx = centerx + ny*scale/nx; // DEBUG: use assembly divide *dispx = centerx + ny*scale/nx; // DEBUG: use assembly divide
// *dispheight = heightnumerator/(nx>>8);
// 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;
// //
// see if it should be grabbed // see if it should be grabbed
...@@ -345,14 +239,10 @@ boolean TransformTile (int tx, int ty, int *dispx, int *dispheight) ...@@ -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; fixed gxt,gyt,nx,gx,gy;
int ratio;
fixed gxt,gyt,nx,ny;
long gx,gy;
gx = xintercept-viewx; gx = xintercept-viewx;
gxt = FixedByFrac(gx,viewcos); gxt = FixedByFrac(gx,viewcos);
...@@ -366,11 +256,9 @@ int CalcHeight (void) ...@@ -366,11 +256,9 @@ int CalcHeight (void)
// calculate perspective ratio (heightnumerator/(nx>>8)) // calculate perspective ratio (heightnumerator/(nx>>8))
// //
if (nx<mindist) if (nx<mindist)
nx=mindist; // don't let divide overflow nx=mindist; /* don't let divide overflow */
asm mov ax,[WORD PTR heightnumerator] return heightnumerator/(nx>>8);
asm mov dx,[WORD PTR heightnumerator+2]
asm idiv [WORD PTR nx+1] // nx>>8
} }
...@@ -388,218 +276,18 @@ long postsource; ...@@ -388,218 +276,18 @@ long postsource;
unsigned postx; unsigned postx;
unsigned postwidth; unsigned postwidth;
void ScalePost(void) void ScalePost (byte *wall, int texture) // VGA version
{
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
{
ScalePost ();
}
/*
====================
=
= 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; int height;
unsigned texture; byte *source;
height = (wallheight [postx] & 0xfff8) >> 1;
texture = (yintercept>>4)&0xfc0; if (height > maxscaleshl2)
if (xtilestep == -1) height = maxscaleshl2;
{ source = wall+texture;
texture = 0xfc0-texture; xBuildCompScale (height/2, source, postx);
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) ...@@ -611,39 +299,14 @@ void HitHorizWall (void)
void HitHorizDoor (void) void HitHorizDoor (void)
{ {
unsigned texture,doorpage,doornum; unsigned texture,doorpage,doornum;
byte *wall;
doornum = tilehit&0x7f; doornum = tilehit&0x7f;
texture = ( (xintercept-doorposition[doornum]) >> 4) &0xfc0; texture = ( (xintercept-doorposition[doornum]) >> 4) &0xfc0;
wallheight[pixx] = CalcHeight(); 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; postx = pixx;
postwidth = 1;
switch (doorobjlist[doornum].lock) switch (doorobjlist[doornum].lock)
{ {
...@@ -661,9 +324,9 @@ void HitHorizDoor (void) ...@@ -661,9 +324,9 @@ void HitHorizDoor (void)
break; break;
} }
*( ((unsigned *)&postsource)+1) = (unsigned)PM_GetPage(doorpage); wall = PM_GetPage (doorpage);
(unsigned)postsource = texture; ScalePost (wall, texture);
}
} }
//========================================================================== //==========================================================================
...@@ -679,39 +342,14 @@ void HitHorizDoor (void) ...@@ -679,39 +342,14 @@ void HitHorizDoor (void)
void HitVertDoor (void) void HitVertDoor (void)
{ {
unsigned texture,doorpage,doornum; unsigned texture,doorpage,doornum;
byte *wall;
doornum = tilehit&0x7f; doornum = tilehit&0x7f;
texture = ( (yintercept-doorposition[doornum]) >> 4) &0xfc0; texture = ( (yintercept-doorposition[doornum]) >> 4) &0xfc0;
wallheight[pixx] = CalcHeight(); 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; postx = pixx;
postwidth = 1;
switch (doorobjlist[doornum].lock) switch (doorobjlist[doornum].lock)
{ {
...@@ -729,211 +367,12 @@ void HitVertDoor (void) ...@@ -729,211 +367,12 @@ void HitVertDoor (void)
break; break;
} }
*( ((unsigned *)&postsource)+1) = (unsigned)PM_GetPage(doorpage+1); wall = PM_GetPage (doorpage);
(unsigned)postsource = texture; ScalePost (wall, 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;
}
} }
//========================================================================== //==========================================================================
//==========================================================================
#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[]= unsigned vgaCeiling[]=
{ {
#ifndef SPEAR #ifndef SPEAR
...@@ -960,46 +399,11 @@ unsigned vgaCeiling[]= ...@@ -960,46 +399,11 @@ unsigned vgaCeiling[]=
void VGAClearScreen (void) void VGAClearScreen (void)
{ {
unsigned ceiling=vgaCeiling[gamestate.episode*10+mapon]; unsigned ceiling = vgaCeiling[gamestate.episode*10+mapon] & 0xFF;
unsigned floor = 0x19;
// VL_Bar(xoffset, yoffset, viewwidth, viewheight / 2, ceiling);
// clear the screen VL_Bar(xoffset, yoffset + viewheight / 2, viewwidth, viewheight / 2, floor);
//
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
} }
//========================================================================== //==========================================================================
...@@ -1016,8 +420,8 @@ int CalcRotate (objtype *ob) ...@@ -1016,8 +420,8 @@ int CalcRotate (objtype *ob)
{ {
int angle,viewangle; int angle,viewangle;
// this isn't exactly correct, as it should vary by a trig value, /* this isn't exactly correct, as it should vary by a trig value, */
// but it is close enough with only eight rotations /* but it is close enough with only eight rotations */
viewangle = player->angle + (centerx - ob->viewx)/8; viewangle = player->angle + (centerx - ob->viewx)/8;
...@@ -1062,10 +466,8 @@ visobj_t vislist[MAXVISABLE],*visptr,*visstep,*farthest; ...@@ -1062,10 +466,8 @@ visobj_t vislist[MAXVISABLE],*visptr,*visstep,*farthest;
void DrawScaleds (void) void DrawScaleds (void)
{ {
int i,j,least,numvisable,height; int i,least,numvisable,height;
memptr shape;
byte *tilespot,*visspot; byte *tilespot,*visspot;
int shapenum;
unsigned spotloc; unsigned spotloc;
statobj_t *statptr; statobj_t *statptr;
...@@ -1094,7 +496,7 @@ void DrawScaleds (void) ...@@ -1094,7 +496,7 @@ void DrawScaleds (void)
if (!visptr->viewheight) if (!visptr->viewheight)
continue; // to close to the object 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++; visptr++;
} }
...@@ -1136,7 +538,7 @@ void DrawScaleds (void) ...@@ -1136,7 +538,7 @@ void DrawScaleds (void)
if (obj->state->rotate) if (obj->state->rotate)
visptr->shapenum += CalcRotate (obj); 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++; visptr++;
obj->flags |= FL_VISABLE; obj->flags |= FL_VISABLE;
} }
...@@ -1196,7 +598,7 @@ void DrawPlayerWeapon (void) ...@@ -1196,7 +598,7 @@ void DrawPlayerWeapon (void)
#ifndef SPEAR #ifndef SPEAR
if (gamestate.victoryflag) 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); SimpleScaleShape(viewwidth/2,SPR_DEATHCAM,viewheight+1);
return; return;
} }
...@@ -1226,17 +628,17 @@ void DrawPlayerWeapon (void) ...@@ -1226,17 +628,17 @@ void DrawPlayerWeapon (void)
void CalcTics (void) void CalcTics (void)
{ {
long newtime,oldtimecount; long newtime;
// //
// calculate tics since last refresh for adaptive timing // calculate tics since last refresh for adaptive timing
// //
if (lasttimecount > TimeCount) if (lasttimecount > get_TimeCount())
TimeCount = lasttimecount; // if the game was paused a LONG time set_TimeCount(lasttimecount); // if the game was paused a LONG time
do do
{ {
newtime = TimeCount; newtime = get_TimeCount();
tics = newtime-lasttimecount; tics = newtime-lasttimecount;
} while (!tics); // make sure at least one tic passes } while (!tics); // make sure at least one tic passes
...@@ -1244,29 +646,11 @@ void CalcTics (void) ...@@ -1244,29 +646,11 @@ void CalcTics (void)
if (tics>MAXTICS) if (tics>MAXTICS)
{ {
TimeCount -= (tics-MAXTICS); set_TimeCount(get_TimeCount() - (tics-MAXTICS));
tics = MAXTICS; tics = MAXTICS;
} }
} }
//==========================================================================
/*
========================
=
= FixOfs
=
========================
*/
void FixOfs (void)
{
VW_ScreenToScreen (displayofs,bufferofs,viewwidth/8,viewheight);
}
//========================================================================== //==========================================================================
...@@ -1280,9 +664,9 @@ void FixOfs (void) ...@@ -1280,9 +664,9 @@ void FixOfs (void)
void WallRefresh (void) void WallRefresh (void)
{ {
// /*
// set up variables for this view set up variables for this view
// */
viewangle = player->angle; viewangle = player->angle;
midangle = viewangle*(FINEANGLES/ANGLES); midangle = viewangle*(FINEANGLES/ANGLES);
viewsin = sintable[viewangle]; viewsin = sintable[viewangle];
...@@ -1293,17 +677,12 @@ void WallRefresh (void) ...@@ -1293,17 +677,12 @@ void WallRefresh (void)
focaltx = viewx>>TILESHIFT; focaltx = viewx>>TILESHIFT;
focalty = viewy>>TILESHIFT; focalty = viewy>>TILESHIFT;
viewtx = player->x >> TILESHIFT;
viewty = player->y >> TILESHIFT;
xpartialdown = viewx&(TILEGLOBAL-1); xpartialdown = viewx&(TILEGLOBAL-1);
xpartialup = TILEGLOBAL-xpartialdown; xpartialup = TILEGLOBAL-xpartialdown;
ypartialdown = viewy&(TILEGLOBAL-1); ypartialdown = viewy&(TILEGLOBAL-1);
ypartialup = TILEGLOBAL-ypartialdown; ypartialup = TILEGLOBAL-ypartialdown;
lastside = -1; // the first pixel is on a new wall AsmRefresh();
AsmRefresh ();
ScalePost (); // no more optimization on last post
} }
//========================================================================== //==========================================================================
...@@ -1318,26 +697,16 @@ void WallRefresh (void) ...@@ -1318,26 +697,16 @@ void WallRefresh (void)
void ThreeDRefresh (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 // clear out the traced array
// //
asm mov ax,ds memset (spotvis, 0, sizeof (spotvis));
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;
// //
// follow the walls from there to the right, drawwing as we go // follow the walls from there to the right, drawwing as we go
// //
DrawPlayBorder();
VGAClearScreen (); VGAClearScreen ();
WallRefresh (); WallRefresh ();
...@@ -1346,41 +715,390 @@ asm rep stosw ...@@ -1346,41 +715,390 @@ asm rep stosw
// draw all the scaled images // draw all the scaled images
// //
DrawScaleds(); // draw scaled stuff DrawScaleds(); // draw scaled stuff
DrawPlayerWeapon (); // draw player's hands DrawPlayerWeapon (); /* draw player's hands */
// //
// show screen and time last cycle // show screen and time last cycle
// //
if (fizzlein) if (fizzlein)
{ {
FizzleFade(bufferofs,displayofs+screenofs,viewwidth,viewheight,20,false); FizzleFade(xoffset, yoffset, viewwidth,viewheight,20,false);
fizzlein = 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; VL_UpdateScreen ();
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;
frameon++; 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; ...@@ -61,6 +61,7 @@ int mouseadjustment;
char configname[13]="config."; char configname[13]="config.";
unsigned xoffset, yoffset;
int _argc; int _argc;
char **argv; char **argv;
...@@ -690,7 +691,6 @@ void SignonScreen (void) // VGA version ...@@ -690,7 +691,6 @@ void SignonScreen (void) // VGA version
if (!virtualreality) if (!virtualreality)
{ {
VL_MungePic (&introscn,320,200);
VL_MemToScreen (&introscn,320,200,0,0); VL_MemToScreen (&introscn,320,200,0,0);
} }
} }
...@@ -1212,6 +1212,9 @@ boolean SetViewSize (unsigned width, unsigned height) ...@@ -1212,6 +1212,9 @@ boolean SetViewSize (unsigned width, unsigned height)
shootdelta = viewwidth/10; shootdelta = viewwidth/10;
screenofs = ((200-STATUSLINES-viewheight)/2*SCREENWIDTH+(320-viewwidth)/8); screenofs = ((200-STATUSLINES-viewheight)/2*SCREENWIDTH+(320-viewwidth)/8);
yoffset = (200-STATUSLINES-viewheight)/2
xoffset = (320-viewwidth)/2;
// //
// calculate trace angles and projection constants // calculate trace angles and projection constants
// //
......
// WL_SCALE.C /* wl_scale.c */
#include "WL_DEF.H" #include "wl_def.h"
#pragma hdrstop
#define OP_RETF 0xcb extern unsigned xoffset, yoffset;
/* /*
============================================================================= =============================================================================
...@@ -13,42 +12,53 @@ ...@@ -13,42 +12,53 @@
============================================================================= =============================================================================
*/ */
t_compscale *scaledirectory[MAXSCALEHEIGHT+1]; /* scaling data for a given height */
long fullscalefarcall[MAXSCALEHEIGHT+1]; 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; step = ((long)height<<16) / 64;
unsigned BuildCompScale (int height, memptr *finalspot); 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;
/* if (startpix == endpix || endpix < 0 || startpix >= viewheight || src == 64)
============== /* source pixel goes off screen */
= scaledata [height].desty [src] = -1;
= BadScale else
= scaledata [height].desty [src] = startpix;
============== }
*/
void far BadScale (void)
{
Quit ("BadScale called!");
} }
/* /*
========================== ==========================
= =
...@@ -60,72 +70,19 @@ void far BadScale (void) ...@@ -60,72 +70,19 @@ void far BadScale (void)
void SetupScaling (int maxscaleheight) void SetupScaling (int maxscaleheight)
{ {
int i,x,y; int i,x,y;
byte far *dest; byte *dest;
insetupscaling = true;
maxscaleheight/=2; // one scaler every two pixels
maxscale = maxscaleheight-1; maxscale = maxscaleheight-1;
maxscaleshl2 = maxscale<<2; 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 // 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++) for (i=1;i<=maxscaleheight;i++)
{ {
MM_SetLock (&(memptr)scaledirectory[i],true); BuildCompScale (i);
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;
}
} }
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) ...@@ -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; int i;
long fix,step; long fix,step;
unsigned src,totalscaled,totalsize;
int startpix,endpix,toppix; int startpix,endpix,toppix;
unsigned char al;
step = height << 10;
toppix = (viewheight-height) >> 1;
step = ((long)height<<16) / 64;
code = &work->code[0];
toppix = (viewheight-height)/2;
fix = 0; fix = 0;
for (src=0;src<=64;src++) for (i = 0; i < 64; i++)
{ {
startpix = fix>>16; startpix = fix>>16;
fix += step; fix += step;
endpix = fix>>16; 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; startpix+=toppix;
endpix+=toppix; endpix+=toppix;
if (startpix == endpix || endpix < 0 || startpix >= viewheight || src == 64) if (startpix == endpix || endpix < 0 || startpix >= viewheight)
continue; continue;
// al = source[i];
// mov al,[si+src]
//
*code++ = 0x8a;
*code++ = 0x44;
*code++ = src;
for (;startpix<endpix;startpix++) for (;startpix<endpix;startpix++)
{ {
if (startpix >= viewheight) if (startpix >= viewheight)
break; // off the bottom of the view area break; /* off the bottom of the view area */
if (startpix < 0) if (startpix < 0)
continue; // not into the view area continue; /* not into the view area */
VL_Plot(x+xoffset, startpix+yoffset, al);
//
// mov [es:di+heightofs],al
//
*code++ = 0x26;
*code++ = 0x88;
*code++ = 0x85;
*((unsigned far *)code)++ = startpix*SCREENBWIDE;
} }
} }
//
// 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) ...@@ -238,162 +158,54 @@ unsigned BuildCompScale (int height, memptr *finalspot)
======================= =======================
*/ */
extern int slinex,slinewidth; int slinex,slinewidth;
extern unsigned far *linecmds; short *linecmds;
extern long linescale; int linescale;
extern unsigned maskword; unsigned maskword;
t_compshape *shapeptr;
byte mask1,mask2,mask3;
/* linecmds - points to line segment data
slinewidth - pixels across
slinex - screen coord of first column
*/
void ScaleLine (void) void ScaleLine (void)
{ {
asm mov cx,WORD PTR [linescale+2] int x, y, ys;
asm mov es,cx // segment of scaler int n, ny;
int y0, y1;
asm mov bp,WORD PTR [linecmds] unsigned char *pixels;
asm mov dx,SC_INDEX+1 // to set SC_MAPMASK unsigned char color;
#ifdef DEBUGx
asm mov bx,[slinex] printf ("ScaleLine\n");
asm mov di,bx printf (" slinex = %d, slinewidth = %d\n", slinex, slinewidth);
asm shr di,2 // X in bytes #endif
asm add di,[bufferofs]
asm and bx,3 while (linecmds[0]) {
asm shl bx,3 y0 = linecmds[2]/2;
asm add bx,[slinewidth] // bx = (pixel*8+pixwidth) y1 = linecmds[0]/2 - 1;
asm mov al,BYTE [mapmasks3-1+bx] // -1 because pixwidth of 1 is first pixels = (unsigned char *) shapeptr + y0 + linecmds[1];
asm mov ds,WORD PTR [linecmds+2] #ifdef DEBUGx
asm or al,al printf (" y0,y1 = %d,%d pixels = 0x%8x\n", y0, y1, pixels);
asm jz notthreebyte // scale across three bytes #endif
asm jmp threebyte for (y=y0; y<=y1; y++) {
notthreebyte: ys = scaledata[linescale].desty[y];
asm mov al,BYTE PTR ss:[mapmasks2-1+bx] // -1 because pixwidth of 1 is first color = *pixels++;
asm or al,al if (ys >= 0) {
asm jnz twobyte // scale across two bytes //color = *pixels++;
for (ny=0; ny<scaledata[linescale].count[y]; ny++) {
// for (n=0,x=slinex; n<slinewidth; n++, x++) {
// one byte scaling // fprintf(stderr, " (%d,%d)\n", x, ys+ny);
// //if (ys < 0) continue;
asm mov al,BYTE PTR ss:[mapmasks1-1+bx] // -1 because pixwidth of 1 is first VL_Plot(x+xoffset, ys+ny+yoffset, color);
asm out dx,al // set map mask register }
}
scalesingle: }
}
asm mov bx,[ds:bp] // table location of rtl to patch linecmds += 3;
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
} }
/* /*
======================= =======================
= =
...@@ -421,35 +233,35 @@ static long longtemp; ...@@ -421,35 +233,35 @@ static long longtemp;
void ScaleShape (int xcenter, int shapenum, unsigned height) void ScaleShape (int xcenter, int shapenum, unsigned height)
{ {
t_compshape *shape; t_compshape *shape;
t_compscale *comptable;
unsigned scale,srcx,stopx,tempx; unsigned scale,srcx,stopx,tempx;
int t; int t;
unsigned far *cmdptr; word *cmdptr;
boolean leftvis,rightvis; boolean leftvis,rightvis;
//printf ("ScaleShape (xcenter=%d, shapenum=%d, height=%d)\n",
// xcenter, shapenum, height);
shape = PM_GetSpritePage (shapenum); shape = PM_GetSpritePage (shapenum);
scale = height>>3; // low three bits are fractional scale = height>>2; // low three bits are fractional
if (!scale || scale>maxscale) if (!scale || scale>maxscale)
return; // too close or far away 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) // scale to the left (from pixel 31 to shape->leftpix)
// //
srcx = 32; srcx = 32;
slinex = xcenter; slinex = xcenter;
stopx = shape->leftpix; stopx = shape->leftpix;
cmdptr = &shape->dataofs[31-stopx]; cmdptr = (word *)&(shape->dataofs[31-stopx]);
while ( --srcx >=stopx && slinex>0) while ( --srcx >=stopx && slinex>0)
{ {
(unsigned)linecmds = *cmdptr--; linecmds = (short *)((char *) shapeptr + *cmdptr--);
if ( !(slinewidth = comptable->width[srcx]) ) if ( !(slinewidth = scaledata[scale].count[srcx]) )
continue; continue;
if (slinewidth == 1) if (slinewidth == 1)
...@@ -520,19 +332,19 @@ void ScaleShape (int xcenter, int shapenum, unsigned height) ...@@ -520,19 +332,19 @@ void ScaleShape (int xcenter, int shapenum, unsigned height)
if (shape->leftpix<31) if (shape->leftpix<31)
{ {
srcx = 31; srcx = 31;
cmdptr = &shape->dataofs[32-shape->leftpix]; cmdptr = (word *)&shape->dataofs[32-shape->leftpix];
} }
else else
{ {
srcx = shape->leftpix-1; srcx = shape->leftpix-1;
cmdptr = &shape->dataofs[0]; cmdptr = (word *)&shape->dataofs[0];
} }
slinewidth = 0; slinewidth = 0;
while ( ++srcx <= stopx && (slinex+=slinewidth)<viewwidth) while ( ++srcx <= stopx && (slinex+=slinewidth)<viewwidth)
{ {
(unsigned)linecmds = *cmdptr++; linecmds = (short *)((char *) shapeptr + *cmdptr++);
if ( !(slinewidth = comptable->width[srcx]) ) if ( !(slinewidth = scaledata[scale].count[srcx]) )
continue; continue;
if (slinewidth == 1) if (slinewidth == 1)
...@@ -625,35 +437,34 @@ void ScaleShape (int xcenter, int shapenum, unsigned height) ...@@ -625,35 +437,34 @@ void ScaleShape (int xcenter, int shapenum, unsigned height)
void SimpleScaleShape (int xcenter, int shapenum, unsigned height) void SimpleScaleShape (int xcenter, int shapenum, unsigned height)
{ {
t_compshape *shape; t_compshape *shape;
t_compscale *comptable;
unsigned scale,srcx,stopx,tempx; unsigned scale,srcx,stopx,tempx;
int t; int t;
unsigned far *cmdptr; unsigned short *cmdptr;
boolean leftvis,rightvis; boolean leftvis,rightvis;
//printf ("SimpleScaleShape (xcenter=%d, shapenum=%d, height=%d)\n",
// xcenter, shapenum, height);
shape = PM_GetSpritePage (shapenum); shape = PM_GetSpritePage (shapenum);
scale = height>>1; scale = height;
comptable = scaledirectory[scale];
*(((unsigned *)&linescale)+1)=(unsigned)comptable; // seg of far call
*(((unsigned *)&linecmds)+1)=(unsigned)shape; // seg of shape
/* *(((unsigned *)&linescale)+1)=(unsigned)comptable; // seg of far call */
linescale = scale;
shapeptr = shape;
// //
// scale to the left (from pixel 31 to shape->leftpix) // scale to the left (from pixel 31 to shape->leftpix)
// //
srcx = 32; srcx = 32;
slinex = xcenter; slinex = xcenter;
stopx = shape->leftpix; stopx = shape->leftpix;
cmdptr = &shape->dataofs[31-stopx]; cmdptr = (word *)&shape->dataofs[31-stopx];
while ( --srcx >=stopx ) while ( --srcx >=stopx )
{ {
(unsigned)linecmds = *cmdptr--; linecmds = (short *)((char *) shapeptr + *cmdptr--);
if ( !(slinewidth = comptable->width[srcx]) ) if ( !(slinewidth = scaledata[scale].count[srcx]) )
continue; continue;
slinex -= slinewidth; slinex -= slinewidth;
ScaleLine (); ScaleLine ();
} }
...@@ -667,67 +478,22 @@ void SimpleScaleShape (int xcenter, int shapenum, unsigned height) ...@@ -667,67 +478,22 @@ void SimpleScaleShape (int xcenter, int shapenum, unsigned height)
if (shape->leftpix<31) if (shape->leftpix<31)
{ {
srcx = 31; srcx = 31;
cmdptr = &shape->dataofs[32-shape->leftpix]; cmdptr = (word *)&shape->dataofs[32-shape->leftpix];
} }
else else
{ {
srcx = shape->leftpix-1; srcx = shape->leftpix-1;
cmdptr = &shape->dataofs[0]; cmdptr = (word *)&shape->dataofs[0];
} }
slinewidth = 0; slinewidth = 0;
while ( ++srcx <= stopx ) while ( ++srcx <= stopx )
{ {
(unsigned)linecmds = *cmdptr++; linecmds = (short *)((char *) shapeptr + *cmdptr++);
if ( !(slinewidth = comptable->width[srcx]) ) if ( !(slinewidth = scaledata[scale].count[srcx]) )
continue; continue;
ScaleLine (); ScaleLine ();
slinex+=slinewidth; 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