Commit d9136e3d authored by Steven Fuller's avatar Steven Fuller

wl_draw.c: Moved functions around, merged wl_scale.c

vi_xlib.c: now fullscreen resets to the previous mode with dga
parent 3d7829b5
...@@ -10,7 +10,7 @@ OBJS = objs.o misc.o id_ca.o id_vh.o id_us.o \ ...@@ -10,7 +10,7 @@ OBJS = objs.o misc.o id_ca.o id_vh.o id_us.o \
wl_act1.o wl_act2.o wl_agent.o wl_game.o \ wl_act1.o wl_act2.o wl_agent.o wl_game.o \
wl_inter.o wl_menu.o wl_play.o wl_state.o wl_text.o wl_main.o \ wl_inter.o wl_menu.o wl_play.o wl_state.o wl_text.o wl_main.o \
wl_debug.o gfxsave.o wl_debug.o gfxsave.o
ROBJS = wl_draw.o wl_scale.o ROBJS = wl_draw.o
SOBJS = $(OBJS) $(ROBJS) vi_svga.o SOBJS = $(OBJS) $(ROBJS) vi_svga.o
XOBJS = $(OBJS) $(ROBJS) vi_xlib.o XOBJS = $(OBJS) $(ROBJS) vi_xlib.o
......
...@@ -22,8 +22,11 @@ SD_StartMusic((MusicGroup *)audiosegs[STARTMUSIC + chunk]); ...@@ -22,8 +22,11 @@ SD_StartMusic((MusicGroup *)audiosegs[STARTMUSIC + chunk]);
=> =>
SD_StartMusic(chunk); SD_StartMusic(chunk);
* clean up vi_xlib.c: fix vid mode changing, fix dga for non8bit modes and
the nonpalette setting stuff... lots of if statements
also, it should be able to compile without extensions
also, update xlib code with new knowledge of how things work
* getenv so that you can point an env. var to the proper dir * getenv so that you can point an env. var to the proper dir
* merge wl_scale with wl_draw?
* refresh rate under svgalib is horrible. the screen keeps getting updated * refresh rate under svgalib is horrible. the screen keeps getting updated
midframe. it's due to the way CalcTics works midframe. it's due to the way CalcTics works
* rewrite hw (sound, input) code, remove stuff like SD_SetSoundMode * rewrite hw (sound, input) code, remove stuff like SD_SetSoundMode
...@@ -86,9 +89,6 @@ screen update ...@@ -86,9 +89,6 @@ screen update
* make sure none of the non-loader code tries to handle gfx/sound data * make sure none of the non-loader code tries to handle gfx/sound data
directly directly
* when window loses focus, it should clear the keys * when window loses focus, it should clear the keys
* clean up vi_xlib.c: fix vid mode changing, fix dga for non8bit modes and
the nonpalette setting stuff... lots of if statements
also, it should be able to compile without extensions
* rename visable to visible * rename visable to visible
* create 'sound channels' with priority.. ie a door can only make one sound * create 'sound channels' with priority.. ie a door can only make one sound
at a time at a time
......
...@@ -193,6 +193,6 @@ void DisplayTextSplash(byte *text) ...@@ -193,6 +193,6 @@ void DisplayTextSplash(byte *text)
else else
printf(" "); printf(" ");
} }
/* TODO: reset color */ printf("%c[m", 27);
printf("\n"); printf("\n");
} }
...@@ -413,14 +413,6 @@ void VL_Startup() ...@@ -413,14 +413,6 @@ void VL_Startup()
void VL_Shutdown() void VL_Shutdown()
{ {
if (dga) {
XF86DGADirectVideo(dpy, screen, 0);
XUngrabKeyboard(dpy, CurrentTime);
free(gfxbuf);
free(disbuf);
gfxbuf = disbuf = NULL;
}
if (fullscreen) { if (fullscreen) {
XF86VidModeLockModeSwitch(dpy, screen, False); XF86VidModeLockModeSwitch(dpy, screen, False);
//printf("%d, %d\n", vidmode.hdisplay, vidmode.vdisplay); //printf("%d, %d\n", vidmode.hdisplay, vidmode.vdisplay);
...@@ -428,6 +420,14 @@ void VL_Shutdown() ...@@ -428,6 +420,14 @@ void VL_Shutdown()
XF86VidModeSwitchToMode(dpy, screen, vmmi[0]); XF86VidModeSwitchToMode(dpy, screen, vmmi[0]);
} }
if (dga) {
XF86DGADirectVideo(dpy, screen, 0);
XUngrabKeyboard(dpy, CurrentTime);
free(gfxbuf);
free(disbuf);
gfxbuf = disbuf = NULL;
}
if ( !shmmode && (gfxbuf != NULL) ) { if ( !shmmode && (gfxbuf != NULL) ) {
free(gfxbuf); free(gfxbuf);
gfxbuf = NULL; gfxbuf = NULL;
...@@ -597,7 +597,7 @@ void VL_FillPalette(int red, int green, int blue) ...@@ -597,7 +597,7 @@ void VL_FillPalette(int red, int green, int blue)
void VL_SetPalette(const byte *palette) void VL_SetPalette(const byte *palette)
{ {
int i; int i;
if (indexmode) { if (indexmode) {
for (i = 0; i < 256; i++) { for (i = 0; i < 256; i++) {
clr[i].red = palette[i*3+0] << 10; clr[i].red = palette[i*3+0] << 10;
......
...@@ -1058,7 +1058,7 @@ void SpawnPlayer (int tilex, int tiley, int dir) ...@@ -1058,7 +1058,7 @@ void SpawnPlayer (int tilex, int tiley, int dir)
player->flags = FL_NEVERMARK; player->flags = FL_NEVERMARK;
Thrust (0,0); // set some variables Thrust (0,0); // set some variables
InitAreas (); InitAreas();
} }
...@@ -1074,7 +1074,7 @@ void SpawnPlayer (int tilex, int tiley, int dir) ...@@ -1074,7 +1074,7 @@ void SpawnPlayer (int tilex, int tiley, int dir)
=============== ===============
*/ */
void KnifeAttack (objtype *ob) void KnifeAttack (objtype *ob)
{ {
objtype *check,*closest; objtype *check,*closest;
long dist; long dist;
...@@ -1104,14 +1104,14 @@ void KnifeAttack (objtype *ob) ...@@ -1104,14 +1104,14 @@ void KnifeAttack (objtype *ob)
} }
// hit something // hit something
DamageActor (closest,US_RndT() >> 4); DamageActor(closest, US_RndT() >> 4);
} }
void GunAttack (objtype *ob) void GunAttack(objtype *ob)
{ {
objtype *check,*closest,*oldclosest; objtype *check, *closest, *oldclosest;
int damage; int damage;
int dx,dy,dist; int dx,dy,dist;
long viewdist; long viewdist;
...@@ -1157,7 +1157,7 @@ void GunAttack (objtype *ob) ...@@ -1157,7 +1157,7 @@ void GunAttack (objtype *ob)
} }
if (closest == oldclosest) if (closest == oldclosest)
return; // no more targets, all missed return; // no more targets, all missed
// //
// trace a line from player to enemey // trace a line from player to enemey
......
/* wl_draw.c */
#include "wl_def.h" #include "wl_def.h"
/* Originally from David Haslam -- dch@sirius.demon.co.uk */ /* C AsmRefresh() originally from David Haslam -- dch@sirius.demon.co.uk */
// 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)
...@@ -36,9 +34,8 @@ static long xstep, ystep; ...@@ -36,9 +34,8 @@ static long xstep, ystep;
static unsigned postx; static unsigned postx;
static void AsmRefresh(); static void AsmRefresh();
void ScaleLine(int height, byte *source, int x);
#define NOASM //#define NOASM
#ifndef NOASM #ifndef NOASM
#define FixedByFrac(x, y) \ #define FixedByFrac(x, y) \
...@@ -47,11 +44,8 @@ void ScaleLine(int height, byte *source, int x); ...@@ -47,11 +44,8 @@ void ScaleLine(int height, byte *source, int x);
z; \ z; \
}) })
#endif #endif
#define xpartialbyystep() FixedByFrac(xpartial, ystep)
#define ypartialbyxstep() FixedByFrac(ypartial, xstep)
//========================================================================== /* ======================================================================== */
/* /*
======================== ========================
...@@ -72,9 +66,6 @@ void ScaleLine(int height, byte *source, int x); ...@@ -72,9 +66,6 @@ void ScaleLine(int height, byte *source, int x);
======================== ========================
*/ */
//
// transform actor
//
static void TransformActor(objtype *ob) static void TransformActor(objtype *ob)
{ {
fixed gx,gy,gxt,gyt,nx,ny; fixed gx,gy,gxt,gyt,nx,ny;
...@@ -109,8 +100,8 @@ static void TransformActor(objtype *ob) ...@@ -109,8 +100,8 @@ static void TransformActor(objtype *ob)
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; ob->viewx = centerx + ny*scale/nx;
...@@ -119,8 +110,6 @@ static void TransformActor(objtype *ob) ...@@ -119,8 +110,6 @@ static void TransformActor(objtype *ob)
} }
//==========================================================================
/* /*
======================== ========================
= =
...@@ -189,136 +178,6 @@ static boolean TransformTile(int tx, int ty, int *dispx, int *dispheight) ...@@ -189,136 +178,6 @@ static boolean TransformTile(int tx, int ty, int *dispx, int *dispheight)
return false; return false;
} }
//==========================================================================
/*
====================
=
= CalcHeight
=
= Calculates the height of xintercept,yintercept from viewx,viewy
=
====================
*/
static int CalcHeight()
{
fixed gxt,gyt,nx,gx,gy;
gx = xintercept-viewx;
gxt = FixedByFrac(gx,viewcos);
gy = yintercept-viewy;
gyt = FixedByFrac(gy,viewsin);
nx = gxt-gyt;
//
// calculate perspective ratio (heightnumerator/(nx>>8))
//
if (nx<MINDIST)
nx=MINDIST; /* don't let divide overflow */
return heightnumerator/(nx>>8);
}
//==========================================================================
/*
===================
=
= ScalePost
=
===================
*/
static void ScalePost(byte *wall, int texture)
{
int height;
byte *source;
height = (wallheight[postx] & 0xfff8) >> 1;
source = wall+texture;
ScaleLine(height/2, source, postx);
}
/*
====================
=
= HitHorizDoor
=
====================
*/
static void HitHorizDoor()
{
unsigned texture, doorpage = 0, doornum;
byte *wall;
doornum = tilehit&0x7f;
texture = ((xintercept-doorposition[doornum]) >> 4) & 0xfc0;
wallheight[postx] = CalcHeight();
switch(doorobjlist[doornum].lock) {
case dr_normal:
doorpage = DOORWALL;
break;
case dr_lock1:
case dr_lock2:
case dr_lock3:
case dr_lock4:
doorpage = DOORWALL+6;
break;
case dr_elevator:
doorpage = DOORWALL+4;
break;
}
wall = PM_GetPage(doorpage);
ScalePost(wall, texture);
}
//==========================================================================
/*
====================
=
= HitVertDoor
=
====================
*/
static void HitVertDoor()
{
unsigned texture, doorpage = 0, doornum;
byte *wall;
doornum = tilehit&0x7f;
texture = ((yintercept-doorposition[doornum]) >> 4) & 0xfc0;
wallheight[postx] = CalcHeight();
switch(doorobjlist[doornum].lock) {
case dr_normal:
doorpage = DOORWALL;
break;
case dr_lock1:
case dr_lock2:
case dr_lock3:
case dr_lock4:
doorpage = DOORWALL+6;
break;
case dr_elevator:
doorpage = DOORWALL+4;
break;
}
wall = PM_GetPage(doorpage);
ScalePost(wall, texture);
}
/* ======================================================================== */ /* ======================================================================== */
...@@ -563,9 +422,6 @@ static void DrawPlayerWeapon() ...@@ -563,9 +422,6 @@ static void DrawPlayerWeapon()
SimpleScaleShape(viewwidth/2,SPR_DEMO,viewheight+1); SimpleScaleShape(viewwidth/2,SPR_DEMO,viewheight+1);
} }
//==========================================================================
/* /*
==================== ====================
= =
...@@ -748,8 +604,7 @@ void DrawPlanes() ...@@ -748,8 +604,7 @@ void DrawPlanes()
{ {
height = wallheight[x]>>3; height = wallheight[x]>>3;
if (height < lastheight) { // more starts if (height < lastheight) { // more starts
do do {
{
spanstart[--lastheight] = x; spanstart[--lastheight] = x;
} while (lastheight > height); } while (lastheight > height);
} else if (height > lastheight) { // draw spans } else if (height > lastheight) { // draw spans
...@@ -821,204 +676,306 @@ void ThreeDRefresh() ...@@ -821,204 +676,306 @@ void ThreeDRefresh()
frameon++; frameon++;
} }
/* ======================================================================== */
//=========================================================================== typedef struct
{
word leftpix, rightpix;
word dataofs[64];
/* table data after dataofs[rightpix-leftpix+1] */
} PACKED t_compshape;
/* /* TODO: this accesses gfxbuf directly! */
xpartial = 16 bit fraction static void ScaledDraw(byte *gfx, int scale, byte *vid, unsigned long tfrac, unsigned long tint, unsigned long delta)
ystep = 32 bit fixed 16,16 {
*/ unsigned long OldDelta;
while (scale--) {
*vid = *gfx;
vid += 320; /* TODO: compiled in constant! */
OldDelta = delta;
delta += tfrac;
gfx += tint;
if (OldDelta > delta)
gfx += 1;
}
}
static int samex(int intercept, int tile) static void ScaledDrawTrans(byte *gfx, int scale, byte *vid, unsigned long tfrac, unsigned long tint, unsigned long delta)
{ {
if (xtilestep > 0) { unsigned long OldDelta;
if ((intercept>>16) >= tile)
return 0; while (scale--) {
else if (*gfx != 255)
return 1; *vid = *gfx;
} else { vid += 320; /* TODO: compiled in constant! */
if ((intercept>>16) <= tile) OldDelta = delta;
return 0; delta += tfrac;
else gfx += tint;
return 1;
if (OldDelta > delta)
gfx += 1;
} }
} }
static int samey(int intercept, int tile) void ScaleLine(unsigned int height, byte *source, int x)
{ {
if (ytilestep > 0) { unsigned long TheFrac;
if ((intercept>>16) >= tile) unsigned long TheInt;
return 0; unsigned long y;
else
return 1; if (height) {
} else { TheFrac = 0x40000000UL / height;
if ((intercept>>16) <= tile)
return 0; if (height < viewheight) {
else y = yoffset + (viewheight - height) / 2;
return 1; TheInt = TheFrac >> 24;
} TheFrac <<= 8;
ScaledDraw(source, height, gfxbuf + (y * 320) + x + xoffset,
TheFrac, TheInt, 0);
return;
}
y = (height - viewheight) / 2;
y *= TheFrac;
TheInt = TheFrac >> 24;
TheFrac <<= 8;
ScaledDraw(&source[y >> 24], viewheight, gfxbuf + (yoffset * 320) + x + xoffset,
TheFrac, TheInt, y << 8);
}
} }
#define DEG90 900 static void ScaleLineTrans(unsigned int height, byte *source, int x)
#define DEG180 1800 {
#define DEG270 2700 unsigned long TheFrac;
#define DEG360 3600 unsigned long TheInt;
unsigned long y;
if (height) {
TheFrac = 0x40000000UL / height;
if (height < viewheight) {
y = yoffset + (viewheight - height) / 2;
TheInt = TheFrac >> 24;
TheFrac <<= 8;
ScaledDrawTrans(source, height, gfxbuf + (y * 320) + x + xoffset,
TheFrac, TheInt, 0);
return;
}
y = (height - viewheight) / 2;
y *= TheFrac;
TheInt = TheFrac >> 24;
TheFrac <<= 8;
ScaledDrawTrans(&source[y >> 24], viewheight, gfxbuf + (yoffset * 320) + x + xoffset,
TheFrac, TheInt, y << 8);
}
}
static void HitHorizWall(); static unsigned char *spritegfx[SPR_TOTAL];
static void HitVertWall();
static void HitHorizPWall();
static void HitVertPWall();
static void AsmRefresh() static void DeCompileSprite(int shapenum)
{ {
fixed doorxhit, dooryhit; t_compshape *ptr;
unsigned char *buf;
int srcx;
unsigned short int *cmdptr;
short int *linecmds;
unsigned char *pixels;
int y, y0, y1;
MM_GetPtr((void *)&buf, 64 * 64);
memset(buf, 255, 64 * 64);
ptr = PM_GetSpritePage(shapenum);
int angle; /* ray angle through postx */ cmdptr = &ptr->dataofs[31 - ptr->leftpix];
for (srcx = 31; srcx >= ptr->leftpix; srcx--) {
linecmds = (short *)((unsigned char *)ptr + *cmdptr--);
while (linecmds[0]) {
y0 = linecmds[2] / 2;
y1 = linecmds[0] / 2;
pixels = (unsigned char *)ptr + y0 + linecmds[1];
for (y = y0; y < y1; y++) {
//*(buf + slinex + (y*64)) = *pixels;
*(buf + (srcx*64) + y) = *pixels;
pixels++;
}
linecmds += 3;
}
}
if (ptr->leftpix < 31) {
srcx = 32;
cmdptr = &ptr->dataofs[32 - ptr->leftpix];
} else {
srcx = ptr->leftpix;
cmdptr = &ptr->dataofs[0];
}
for (; srcx <= ptr->rightpix; srcx++) {
linecmds = (short *)((unsigned char *)ptr + *cmdptr++);
while (linecmds[0]) {
y0 = linecmds[2] / 2;
y1 = linecmds[0] / 2;
pixels = (unsigned char *)ptr + y0 + linecmds[1];
for (y = y0; y < y1; y++) {
//*(buf + slinex + (y*64)) = *pixels;
*(buf + (srcx*64) + y) = *pixels;
pixels++;
}
linecmds += 3;
}
}
spritegfx[shapenum] = buf;
}
for (postx = 0; postx < viewwidth; postx++) { void ScaleShape(int xcenter, int shapenum, unsigned height)
angle = midangle + pixelangle[postx]; {
unsigned int scaler = (64 << 16) / (height >> 2);
unsigned int x, p;
if (angle < 0) { if (spritegfx[shapenum] == NULL)
/* -90 - -1 degree arc */ DeCompileSprite(shapenum);
angle += FINEANGLES;
goto entry360; for (p = xcenter - (height >> 3), x = 0; x < (64 << 16); x += scaler, p++) {
} else if (angle < DEG90) { if ((p < 0) || (p >= viewwidth) || (wallheight[p] >= height))
/* 0-89 degree arc */ continue;
entry90: ScaleLineTrans(height >> 2, spritegfx[shapenum] + ((x >> 16) << 6), p);
xtilestep = 1; }
ytilestep = -1; }
xstep = finetangent[DEG90-1-angle];
ystep = -finetangent[angle]; void SimpleScaleShape(int xcenter, int shapenum, unsigned height)
xpartial = xpartialup; {
ypartial = ypartialdown; unsigned int scaler = (64 << 16) / height;
} else if (angle < DEG180) { unsigned int x, p;
/* 90-179 degree arc */
xtilestep = -1; if (spritegfx[shapenum] == NULL)
ytilestep = -1; DeCompileSprite(shapenum);
xstep = -finetangent[angle-DEG90];
ystep = -finetangent[DEG180-1-angle]; for (p = xcenter - (height / 2), x = 0; x < (64 << 16); x += scaler, p++) {
xpartial = xpartialdown; if ((p < 0) || (p >= viewwidth))
ypartial = ypartialdown; continue;
} else if (angle < DEG270) { ScaleLineTrans(height, spritegfx[shapenum] + ((x >> 16) << 6), p);
/* 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;
} }
}
/* ======================================================================== */
/*
====================
=
= CalcHeight
=
= Calculates the height of xintercept,yintercept from viewx,viewy
=
====================
*/
static int CalcHeight()
{
fixed gxt,gyt,nx,gx,gy;
gx = xintercept-viewx;
gxt = FixedByFrac(gx,viewcos);
gy = yintercept-viewy;
gyt = FixedByFrac(gy,viewsin);
nx = gxt-gyt;
//
// calculate perspective ratio (heightnumerator/(nx>>8))
//
if (nx<MINDIST)
nx=MINDIST; /* don't let divide overflow */
return heightnumerator/(nx>>8);
}
static void ScalePost(byte *wall, int texture)
{
int height;
byte *source;
height = (wallheight[postx] & 0xFFF8) >> 2;
yintercept = viewy + xpartialbyystep (); source = wall+texture;
xtile = focaltx + xtilestep; ScaleLine(height, source, postx);
}
xintercept = viewx + ypartialbyxstep (); static void HitHorizDoor()
ytile = focalty + ytilestep; {
unsigned texture, doorpage = 0, doornum;
byte *wall;
/* CORE LOOP */ doornum = tilehit&0x7f;
texture = ((xintercept-doorposition[doornum]) >> 4) & 0xfc0;
#define TILE(n) (n>>16) wallheight[postx] = CalcHeight();
/* check intersections with vertical walls */ switch(doorobjlist[doornum].lock) {
vertcheck: case dr_normal:
if (!samey (yintercept, ytile)) doorpage = DOORWALL;
goto horizentry; break;
vertentry: case dr_lock1:
tilehit = tilemap[xtile][TILE(yintercept)]; case dr_lock2:
case dr_lock3:
case dr_lock4:
doorpage = DOORWALL+6;
break;
case dr_elevator:
doorpage = DOORWALL+4;
break;
}
if (tilehit != 0) { wall = PM_GetPage(doorpage);
if (tilehit & 0x80) { ScalePost(wall, texture);
if (tilehit & 0x40) { }
/* vertpushwall */
long ytemp = yintercept + (pwallpos * ystep) / 64;
fprintf(stderr, "VertPushWall@%d: %d = %d + (%d * %d) / 64\n", angle, ytemp, yintercept, pwallpos, ystep);
ytemp &= ~0x4000000; /* TODO: why? */
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 (tilehit != 0) { static void HitVertDoor()
if (tilehit & 0x80) { {
/* horizdoor */ unsigned texture, doorpage = 0, doornum;
if (tilehit & 0x40) { byte *wall;
long xtemp = xintercept + (pwallpos * xstep) / 64;
doornum = tilehit&0x7f;
fprintf(stderr, "HorizPushWall@%d: %d = %d + (%d * %d) / 64\n", angle, xtemp, xintercept, pwallpos, xstep); texture = ((yintercept-doorposition[doornum]) >> 4) & 0xfc0;
xtemp &= ~0x4000000;
/* horizpushwall */ wallheight[postx] = CalcHeight();
if (TILE(xtemp) != TILE(xintercept))
goto passhoriz; switch(doorobjlist[doornum].lock) {
xintercept = xtemp; case dr_normal:
yintercept = ytile << 16; doorpage = DOORWALL;
HitHorizPWall(); break;
} else { case dr_lock1:
doorxhit = xintercept + xstep / 2; case dr_lock2:
if (TILE (doorxhit) != TILE (xintercept)) case dr_lock3:
goto passhoriz; case dr_lock4:
/* check door position */ doorpage = DOORWALL+6;
if ((doorxhit&0xFFFF) < doorposition[tilehit&0x7f]) break;
goto passhoriz; case dr_elevator:
xintercept = doorxhit; doorpage = DOORWALL+4;
yintercept = (ytile << 16) + 32768; break;
HitHorizDoor(); }
}
} else { wall = PM_GetPage(doorpage);
yintercept = ytile << 16; ScalePost(wall, texture);
HitHorizWall();
}
goto nextpix;
}
passhoriz:
spotvis [TILE(xintercept)][ytile] = 1;
ytile += ytilestep;
xintercept += xstep;
goto horizcheck;
nextpix: ;
}
} }
static void HitVertWall() static void HitVertWall()
...@@ -1077,16 +1034,6 @@ static void HitHorizWall() ...@@ -1077,16 +1034,6 @@ static void HitHorizWall()
ScalePost(wall, texture); ScalePost(wall, texture);
} }
/*
====================
=
= HitHorizPWall
=
= A pushable wall in action has been hit
=
====================
*/
static void HitHorizPWall() static void HitHorizPWall()
{ {
int wallpic; int wallpic;
...@@ -1111,16 +1058,6 @@ static void HitHorizPWall() ...@@ -1111,16 +1058,6 @@ static void HitHorizPWall()
ScalePost(wall, texture); ScalePost(wall, texture);
} }
/*
====================
=
= HitVertPWall
=
= A pushable wall in action has been hit
=
====================
*/
static void HitVertPWall() static void HitVertPWall()
{ {
int wallpic; int wallpic;
...@@ -1141,5 +1078,203 @@ static void HitVertPWall() ...@@ -1141,5 +1078,203 @@ static void HitVertPWall()
wallpic = vertwall[tilehit&63]; wallpic = vertwall[tilehit&63];
wall = PM_GetPage(wallpic); wall = PM_GetPage(wallpic);
ScalePost(wall, texture); ScalePost(wall, texture);
}
#define DEG90 900
#define DEG180 1800
#define DEG270 2700
#define DEG360 3600
#define xpartialbyystep() FixedByFrac(xpartial, ystep)
#define ypartialbyxstep() FixedByFrac(ypartial, xstep)
static 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;
}
}
static 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;
}
}
static void AsmRefresh()
{
fixed doorxhit, dooryhit;
long xtemp, ytemp;
int angle; /* ray angle through postx */
for (postx = 0; postx < viewwidth; postx++) {
angle = midangle + pixelangle[postx];
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;
}
yintercept = viewy + xpartialbyystep();
xtile = focaltx + xtilestep;
xintercept = viewx + ypartialbyxstep();
ytile = focalty + ytilestep;
/* 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 (tilehit != 0) {
if (tilehit & 0x80) {
if (tilehit & 0x40) {
/* vertpushwall */
ytemp = yintercept + (signed)((signed)pwallpos * ystep) / 64;
if (TILE(ytemp) != TILE(yintercept))
goto passvert;
yintercept = ytemp;
xintercept = xtile << 16;
HitVertPWall();
} else {
/* vertdoor */
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();
}
continue;
}
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 (tilehit != 0) {
if (tilehit & 0x80) {
if (tilehit & 0x40) {
xtemp = xintercept + (signed)((signed)pwallpos * xstep) / 64;
/* 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();
}
continue;
}
passhoriz:
spotvis[TILE(xintercept)][ytile] = 1;
ytile += ytilestep;
xintercept += xstep;
goto horizcheck;
}
} }
/* wl_scale.c */
#include "wl_def.h"
typedef struct
{
word leftpix, rightpix;
word dataofs[64];
/* table data after dataofs[rightpix-leftpix+1] */
} PACKED t_compshape;
/* ======================================================================== */
/* TODO: this accesses gfxbuf directly! */
static void ScaledDraw(byte *gfx, int scale, byte *vid, unsigned long tfrac, unsigned long tint, unsigned long delta)
{
unsigned long OldDelta;
while (scale--) {
*vid = *gfx;
vid += 320; /* TODO: compiled in constant! */
OldDelta = delta;
delta += tfrac;
gfx += tint;
if (OldDelta > delta)
gfx += 1;
}
}
static void ScaledDrawTrans(byte *gfx, int scale, byte *vid, unsigned long tfrac, unsigned long tint, unsigned long delta)
{
unsigned long OldDelta;
while (scale--) {
if (*gfx != 255)
*vid = *gfx;
vid += 320; /* TODO: compiled in constant! */
OldDelta = delta;
delta += tfrac;
gfx += tint;
if (OldDelta > delta)
gfx += 1;
}
}
void ScaleLine(unsigned int height, byte *source, int x)
{
unsigned long TheFrac;
unsigned long TheInt;
unsigned long y;
if (height) {
TheFrac = 0x40000000UL / height;
if (height < viewheight) {
y = yoffset + (viewheight - height) / 2;
TheInt = TheFrac >> 24;
TheFrac <<= 8;
ScaledDraw(source, height, gfxbuf + (y * 320) + x + xoffset,
TheFrac, TheInt, 0);
return;
}
y = (height - viewheight) / 2;
y *= TheFrac;
TheInt = TheFrac >> 24;
TheFrac <<= 8;
ScaledDraw(&source[y >> 24], viewheight, gfxbuf + (yoffset * 320) + x + xoffset,
TheFrac, TheInt, y << 8);
}
}
static void ScaleLineTrans(unsigned int height, byte *source, int x)
{
unsigned long TheFrac;
unsigned long TheInt;
unsigned long y;
if (height) {
TheFrac = 0x40000000UL / height;
if (height < viewheight) {
y = yoffset + (viewheight - height) / 2;
TheInt = TheFrac >> 24;
TheFrac <<= 8;
ScaledDrawTrans(source, height, gfxbuf + (y * 320) + x + xoffset,
TheFrac, TheInt, 0);
return;
}
y = (height - viewheight) / 2;
y *= TheFrac;
TheInt = TheFrac >> 24;
TheFrac <<= 8;
ScaledDrawTrans(&source[y >> 24], viewheight, gfxbuf + (yoffset * 320) + x + xoffset,
TheFrac, TheInt, y << 8);
}
}
static unsigned char *spritegfx[SPR_TOTAL];
static void DeCompileSprite(int shapenum)
{
t_compshape *ptr;
unsigned char *buf;
int srcx;
unsigned short int *cmdptr;
short int *linecmds;
unsigned char *pixels;
int y, y0, y1;
MM_GetPtr((void *)&buf, 64 * 64);
memset(buf, 255, 64 * 64);
ptr = PM_GetSpritePage(shapenum);
cmdptr = &ptr->dataofs[31 - ptr->leftpix];
for (srcx = 31; srcx >= ptr->leftpix; srcx--) {
linecmds = (short *)((unsigned char *)ptr + *cmdptr--);
while (linecmds[0]) {
y0 = linecmds[2] / 2;
y1 = linecmds[0] / 2;
pixels = (unsigned char *)ptr + y0 + linecmds[1];
for (y = y0; y < y1; y++) {
//*(buf + slinex + (y*64)) = *pixels;
*(buf + (srcx*64) + y) = *pixels;
pixels++;
}
linecmds += 3;
}
}
if (ptr->leftpix < 31) {
srcx = 32;
cmdptr = &ptr->dataofs[32 - ptr->leftpix];
} else {
srcx = ptr->leftpix;
cmdptr = &ptr->dataofs[0];
}
for (; srcx <= ptr->rightpix; srcx++) {
linecmds = (short *)((unsigned char *)ptr + *cmdptr++);
while (linecmds[0]) {
y0 = linecmds[2] / 2;
y1 = linecmds[0] / 2;
pixels = (unsigned char *)ptr + y0 + linecmds[1];
for (y = y0; y < y1; y++) {
//*(buf + slinex + (y*64)) = *pixels;
*(buf + (srcx*64) + y) = *pixels;
pixels++;
}
linecmds += 3;
}
}
spritegfx[shapenum] = buf;
}
void ScaleShape(int xcenter, int shapenum, unsigned height)
{
unsigned int scaler = (64 << 16) / (height >> 2);
unsigned int x, p;
if (spritegfx[shapenum] == NULL)
DeCompileSprite(shapenum);
for (p = xcenter - (height >> 3), x = 0; x < (64 << 16); x += scaler, p++) {
if ((p < 0) || (p >= viewwidth) || (wallheight[p] >= height))
continue;
ScaleLineTrans(height >> 2, spritegfx[shapenum] + ((x >> 16) << 6), p);
}
}
void SimpleScaleShape(int xcenter, int shapenum, unsigned height)
{
unsigned int scaler = (64 << 16) / height;
unsigned int x, p;
if (spritegfx[shapenum] == NULL)
DeCompileSprite(shapenum);
for (p = xcenter - (height / 2), x = 0; x < (64 << 16); x += scaler, p++) {
if ((p < 0) || (p >= viewwidth))
continue;
ScaleLineTrans(height, spritegfx[shapenum] + ((x >> 16) << 6), p);
}
}
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