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,6 +413,13 @@ void VL_Startup() ...@@ -413,6 +413,13 @@ void VL_Startup()
void VL_Shutdown() void VL_Shutdown()
{ {
if (fullscreen) {
XF86VidModeLockModeSwitch(dpy, screen, False);
//printf("%d, %d\n", vidmode.hdisplay, vidmode.vdisplay);
//XF86VidModeSwitchToMode(dpy, screen, &vidmode);
XF86VidModeSwitchToMode(dpy, screen, vmmi[0]);
}
if (dga) { if (dga) {
XF86DGADirectVideo(dpy, screen, 0); XF86DGADirectVideo(dpy, screen, 0);
XUngrabKeyboard(dpy, CurrentTime); XUngrabKeyboard(dpy, CurrentTime);
...@@ -421,13 +428,6 @@ void VL_Shutdown() ...@@ -421,13 +428,6 @@ void VL_Shutdown()
gfxbuf = disbuf = NULL; gfxbuf = disbuf = NULL;
} }
if (fullscreen) {
XF86VidModeLockModeSwitch(dpy, screen, False);
//printf("%d, %d\n", vidmode.hdisplay, vidmode.vdisplay);
//XF86VidModeSwitchToMode(dpy, screen, &vidmode);
XF86VidModeSwitchToMode(dpy, screen, vmmi[0]);
}
if ( !shmmode && (gfxbuf != NULL) ) { if ( !shmmode && (gfxbuf != NULL) ) {
free(gfxbuf); free(gfxbuf);
gfxbuf = NULL; gfxbuf = NULL;
......
...@@ -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();
} }
...@@ -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;
......
/* 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) \
...@@ -48,10 +45,7 @@ void ScaleLine(int height, byte *source, int x); ...@@ -48,10 +45,7 @@ void ScaleLine(int height, byte *source, int x);
}) })
#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;
...@@ -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;
xpartial = 16 bit fraction word dataofs[64];
ystep = 32 bit fixed 16,16 /* table data after dataofs[rightpix-leftpix+1] */
*/ } PACKED t_compshape;
static int samex(int intercept, int tile) /* TODO: this accesses gfxbuf directly! */
static void ScaledDraw(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 *vid = *gfx;
return 1; vid += 320; /* TODO: compiled in constant! */
} else { OldDelta = delta;
if ((intercept>>16) <= tile) delta += tfrac;
return 0; gfx += tint;
else
return 1; if (OldDelta > delta)
gfx += 1;
} }
} }
static int samey(int intercept, int tile) static void ScaledDrawTrans(byte *gfx, int scale, byte *vid, unsigned long tfrac, unsigned long tint, unsigned long delta)
{ {
if (ytilestep > 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;
} }
} }
#define DEG90 900 void ScaleLine(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;
static void HitHorizWall(); if (height) {
static void HitVertWall(); TheFrac = 0x40000000UL / height;
static void HitHorizPWall();
static void HitVertPWall();
static void AsmRefresh() 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)
{ {
fixed doorxhit, dooryhit; unsigned long TheFrac;
unsigned long TheInt;
unsigned long y;
int angle; /* ray angle through postx */ if (height) {
TheFrac = 0x40000000UL / height;
for (postx = 0; postx < viewwidth; postx++) { if (height < viewheight) {
angle = midangle + pixelangle[postx]; y = yoffset + (viewheight - height) / 2;
TheInt = TheFrac >> 24;
TheFrac <<= 8;
if (angle < 0) { ScaledDrawTrans(source, height, gfxbuf + (y * 320) + x + xoffset,
/* -90 - -1 degree arc */ TheFrac, TheInt, 0);
angle += FINEANGLES;
goto entry360; return;
} 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 (); y = (height - viewheight) / 2;
xtile = focaltx + xtilestep; y *= TheFrac;
xintercept = viewx + ypartialbyxstep (); TheInt = TheFrac >> 24;
ytile = focalty + ytilestep; TheFrac <<= 8;
/* CORE LOOP */ ScaledDrawTrans(&source[y >> 24], viewheight, gfxbuf + (yoffset * 320) + x + xoffset,
TheFrac, TheInt, y << 8);
}
}
#define TILE(n) (n>>16) static unsigned char *spritegfx[SPR_TOTAL];
/* check intersections with vertical walls */ static void DeCompileSprite(int shapenum)
vertcheck: {
if (!samey (yintercept, ytile)) t_compshape *ptr;
goto horizentry; unsigned char *buf;
vertentry: int srcx;
tilehit = tilemap[xtile][TILE(yintercept)]; unsigned short int *cmdptr;
short int *linecmds;
unsigned char *pixels;
int y, y0, y1;
if (tilehit != 0) { MM_GetPtr((void *)&buf, 64 * 64);
if (tilehit & 0x80) {
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); memset(buf, 255, 64 * 64);
ytemp &= ~0x4000000; /* TODO: why? */
if (TILE(ytemp) != TILE(yintercept)) ptr = PM_GetSpritePage(shapenum);
goto passvert;
yintercept = ytemp; cmdptr = &ptr->dataofs[31 - ptr->leftpix];
xintercept = xtile << 16;
HitVertPWall(); 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;
} }
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();
} }
if (ptr->leftpix < 31) {
srcx = 32;
cmdptr = &ptr->dataofs[32 - ptr->leftpix];
} else { } else {
xintercept = xtile << 16; srcx = ptr->leftpix;
HitVertWall(); 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;
} }
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) { spritegfx[shapenum] = buf;
if (tilehit & 0x80) { }
/* horizdoor */
if (tilehit & 0x40) {
long xtemp = xintercept + (pwallpos * xstep) / 64;
fprintf(stderr, "HorizPushWall@%d: %d = %d + (%d * %d) / 64\n", angle, xtemp, xintercept, pwallpos, xstep); void ScaleShape(int xcenter, int shapenum, unsigned height)
xtemp &= ~0x4000000; {
/* horizpushwall */ unsigned int scaler = (64 << 16) / (height >> 2);
if (TILE(xtemp) != TILE(xintercept)) unsigned int x, p;
goto passhoriz;
xintercept = xtemp; if (spritegfx[shapenum] == NULL)
yintercept = ytile << 16; DeCompileSprite(shapenum);
HitHorizPWall();
} else { for (p = xcenter - (height >> 3), x = 0; x < (64 << 16); x += scaler, p++) {
doorxhit = xintercept + xstep / 2; if ((p < 0) || (p >= viewwidth) || (wallheight[p] >= height))
if (TILE (doorxhit) != TILE (xintercept)) continue;
goto passhoriz; ScaleLineTrans(height >> 2, spritegfx[shapenum] + ((x >> 16) << 6), p);
/* check door position */
if ((doorxhit&0xFFFF) < doorposition[tilehit&0x7f])
goto passhoriz;
xintercept = doorxhit;
yintercept = (ytile << 16) + 32768;
HitHorizDoor();
} }
} else { }
yintercept = ytile << 16;
HitHorizWall(); 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);
} }
goto nextpix; }
/* ======================================================================== */
/*
====================
=
= 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;
source = wall+texture;
ScaleLine(height, source, postx);
}
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;
} }
passhoriz:
spotvis [TILE(xintercept)][ytile] = 1; wall = PM_GetPage(doorpage);
ytile += ytilestep; ScalePost(wall, texture);
xintercept += xstep; }
goto horizcheck;
nextpix: ; 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);
} }
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;
...@@ -1143,3 +1080,201 @@ static void HitVertPWall() ...@@ -1143,3 +1080,201 @@ static void HitVertPWall()
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