Commit 219c11c0 authored by Steven Fuller's avatar Steven Fuller

wl_scale.c: Rewrote the sprite drawing code (now works similar to wall

drawing).
parent 3d16d302
...@@ -96,7 +96,7 @@ ...@@ -96,7 +96,7 @@
// sprite constants // sprite constants
// //
enum { enum {
SPR_DEMO, SPR_DEMO,
SPR_DEATHCAM, SPR_DEATHCAM,
// //
...@@ -404,9 +404,8 @@ enum { ...@@ -404,9 +404,8 @@ enum {
SPR_MACHINEGUNATK4, SPR_MACHINEGUNATK4,
SPR_CHAINREADY,SPR_CHAINATK1,SPR_CHAINATK2,SPR_CHAINATK3, SPR_CHAINREADY,SPR_CHAINATK1,SPR_CHAINATK2,SPR_CHAINATK3,
SPR_CHAINATK4, SPR_NULLSPRITE SPR_CHAINATK4, SPR_NULLSPRITE, SPR_TOTAL
};
};
/* /*
...@@ -437,7 +436,6 @@ typedef enum { ...@@ -437,7 +436,6 @@ typedef enum {
ac_badobject = -1, ac_badobject = -1,
ac_no, ac_no,
ac_yes, ac_yes,
ac_allways
} activetype; } activetype;
typedef enum { typedef enum {
...@@ -931,16 +929,8 @@ boolean CheckSight (objtype *ob); ...@@ -931,16 +929,8 @@ boolean CheckSight (objtype *ob);
============================================================================= =============================================================================
*/ */
typedef struct void ScaleShape(int xcenter, int shapenum, unsigned height);
{ void SimpleScaleShape(int xcenter, int shapenum, unsigned height);
word leftpix,rightpix;
word dataofs[64];
/* table data after dataofs[rightpix-leftpix+1] */
} PACKED t_compshape;
void SetupScaling (int maxscaleheight);
void ScaleShape (int xcenter, int shapenum, unsigned height);
void SimpleScaleShape (int xcenter, int shapenum, unsigned height);
/* /*
============================================================================= =============================================================================
......
...@@ -36,7 +36,7 @@ static long xstep, ystep; ...@@ -36,7 +36,7 @@ static long xstep, ystep;
static unsigned postx; static unsigned postx;
static void AsmRefresh(); static void AsmRefresh();
void xBuildCompScale(int height, byte *source, int x); void ScaleLine(int height, byte *source, int x);
#define NOASM #define NOASM
...@@ -241,7 +241,7 @@ static void ScalePost(byte *wall, int texture) ...@@ -241,7 +241,7 @@ static void ScalePost(byte *wall, int texture)
height = (wallheight[postx] & 0xfff8) >> 1; height = (wallheight[postx] & 0xfff8) >> 1;
source = wall+texture; source = wall+texture;
xBuildCompScale(height/2, source, postx); ScaleLine(height/2, source, postx);
} }
/* /*
......
...@@ -1119,12 +1119,8 @@ boolean SetViewSize(unsigned width, unsigned height) ...@@ -1119,12 +1119,8 @@ boolean SetViewSize(unsigned width, unsigned height)
// //
// calculate trace angles and projection constants // calculate trace angles and projection constants
// //
CalcProjection (FOCALLENGTH); CalcProjection(FOCALLENGTH);
//
// build all needed compiled scalers
//
SetupScaling(viewwidth*1.5);
return true; return true;
} }
......
...@@ -2,97 +2,39 @@ ...@@ -2,97 +2,39 @@
#include "wl_def.h" #include "wl_def.h"
/* Originally from David Haslam -- dch@sirius.demon.co.uk */ typedef struct
/*
=============================================================================
GLOBALS
=============================================================================
*/
/* scaling data for a given height */
typedef struct {
/* number of destination pixels each source pixels maps to in x and y */
int count[64];
/* the destination pixel for each source pixel row */
int desty[64];
} t_scaledata;
static t_scaledata scaledata[MAXSCALEHEIGHT+1];
static int maxscale;
static void BuildCompScale(int height)
{ {
long fix, step; word leftpix, rightpix;
int src; word dataofs[64];
int startpix, endpix, toppix; /* table data after dataofs[rightpix-leftpix+1] */
} PACKED t_compshape;
step = ((long)height << 16) / 64;
toppix = (viewheight - height) / 2;
fix = 0;
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;
} else if (startpix < 0) {
scaledata[height].desty[src] = 0;
} else {
scaledata[height].desty[src] = startpix;
/* Clip if needed */
if ((scaledata[height].count[src] + scaledata[height].desty[src]) > viewheight)
scaledata[height].count[src] = viewheight - scaledata [height].desty[src];
}
}
}
/* /* ======================================================================== */
==========================
=
= SetupScaling
=
==========================
*/
void SetupScaling(int maxscaleheight) /* TODO: this accesses gfxbuf directly! */
static void ScaledDraw(byte *gfx, int scale, byte *vid, unsigned long tfrac, unsigned long tint, unsigned long delta)
{ {
int i; unsigned long OldDelta;
while (scale--) {
*vid = *gfx;
vid += 320; /* TODO: compiled in constant! */
OldDelta = delta;
delta += tfrac;
gfx += tint;
maxscale = maxscaleheight-1; if (OldDelta > delta)
// gfx += 1;
// build the compiled scalers
//
for (i = 1; i <= maxscaleheight; i++) {
BuildCompScale(i);
} }
} }
/* ======================================================================== */ static void ScaledDrawTrans(byte *gfx, int scale, byte *vid, unsigned long tfrac, unsigned long tint, unsigned long delta)
/* 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; unsigned long OldDelta;
while (scale--) { while (scale--) {
*vid = *gfx; if (*gfx != 255)
*vid = *gfx;
vid += 320; /* TODO: compiled in constant! */ vid += 320; /* TODO: compiled in constant! */
OldDelta = delta; OldDelta = delta;
delta += tfrac; delta += tfrac;
...@@ -103,7 +45,7 @@ static void ScaledDraw(byte *gfx, int scale, byte *vid, unsigned long tfrac, uns ...@@ -103,7 +45,7 @@ static void ScaledDraw(byte *gfx, int scale, byte *vid, unsigned long tfrac, uns
} }
} }
void xBuildCompScale(unsigned int height, byte *source, int x) void ScaleLine(unsigned int height, byte *source, int x)
{ {
unsigned long TheFrac; unsigned long TheFrac;
unsigned long TheInt; unsigned long TheInt;
...@@ -134,306 +76,140 @@ void xBuildCompScale(unsigned int height, byte *source, int x) ...@@ -134,306 +76,140 @@ void xBuildCompScale(unsigned int height, byte *source, int x)
} }
} }
/* static void ScaleLineTrans(unsigned int height, byte *source, int x)
=======================
=
= ScaleLine
=
=======================
*/
static int slinex, slinewidth;
static short *linecmds;
static int linescale;
static t_compshape *shapeptr;
/*
linecmds - points to line segment data
slinewidth - pixels across
slinex - screen coord of first column
*/
static void ScaleLine()
{ {
int x, y, ys; unsigned long TheFrac;
int n, ny; unsigned long TheInt;
int y0, y1; unsigned long y;
unsigned char *pixels;
unsigned char color; if (height) {
TheFrac = 0x40000000UL / height;
while (linecmds[0]) {
y0 = linecmds[2] / 2; if (height < viewheight) {
y1 = linecmds[0] / 2; y = yoffset + (viewheight - height) / 2;
pixels = (unsigned char *)shapeptr + y0 + linecmds[1]; TheInt = TheFrac >> 24;
TheFrac <<= 8;
for (y = y0; y < y1; y++) {
color = *pixels++;
ys = scaledata[linescale].desty[y];
if (ys >= 0) { ScaledDrawTrans(source, height, gfxbuf + (y * 320) + x + xoffset,
for (ny = 0; ny < scaledata[linescale].count[y]; ny++) TheFrac, TheInt, 0);
for (n = 0, x = slinex; n < slinewidth; n++, x++)
VL_Plot(x+xoffset, ys+ny+yoffset, color); return;
} }
}
linecmds += 3; 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];
=======================
=
= ScaleShape
=
= Draws a compiled shape at [scale] pixels high
=
=======================
*/
void ScaleShape(int xcenter, int shapenum, unsigned height) /* TODO: merge FlipWall into function below */
static byte *FlipWall(byte *dat, int w, int h)
{ {
t_compshape *shape; byte *buf;
unsigned scale,srcx,stopx; int i, j;
word *cmdptr;
boolean leftvis,rightvis;
shape = PM_GetSpritePage(shapenum);
scale = height>>2; // low three bits are fractional
scale += 4; /* sprites look a bit better pulled up some */
if (!scale || scale>maxscale)
return; // too close or far away
linescale = scale;
shapeptr = shape;
//
// scale to the left (from pixel 31 to shape->leftpix)
//
srcx = 32;
slinex = xcenter;
stopx = shape->leftpix;
cmdptr = (word *)&(shape->dataofs[31-stopx]);
while ( --srcx >= stopx && slinex>0)
{
linecmds = (short *)((char *) shapeptr + *cmdptr--);
if ( !(slinewidth = scaledata[scale].count[srcx]) )
continue;
if (slinewidth == 1)
{
slinex--;
if (slinex<viewwidth)
{
if (wallheight[slinex] >= height)
continue; // obscured by closer wall
ScaleLine ();
}
continue;
}
//
// handle multi pixel lines
//
if (slinex>viewwidth)
{
slinex -= slinewidth;
slinewidth = viewwidth-slinex;
if (slinewidth<1)
continue; // still off the right side
}
else
{
if (slinewidth>slinex)
slinewidth = slinex;
slinex -= slinewidth;
}
leftvis = (wallheight[slinex] < height); buf = (byte *)malloc(w * h);
rightvis = (wallheight[slinex+slinewidth-1] < height);
if (leftvis) for (j = 0; j < h; j++)
{ for (i = 0; i < w; i++)
if (rightvis) buf[j*w+i] = dat[i*w+j];
ScaleLine (); return buf;
else }
{
while (wallheight[slinex+slinewidth-1] >= height)
slinewidth--;
ScaleLine ();
}
}
else
{
if (!rightvis)
continue; // totally obscured
while (wallheight[slinex] >= height) static void DeCompileSprite(int shapenum)
{ {
slinex++; t_compshape *ptr;
slinewidth--; unsigned char *buf;
int srcx = 32;
int slinex = 31;
int stopx;
unsigned short int *cmdptr;
MM_GetPtr((void *)&buf, 64 * 64);
ptr = PM_GetSpritePage(shapenum);
memset(buf, 255, 64 * 64);
stopx = ptr->leftpix;
cmdptr = &ptr->dataofs[31-stopx];
while ( --srcx >=stopx ) {
short *linecmds = (short *)((unsigned char *)ptr + *cmdptr--);
slinex--;
while (linecmds[0]) {
int y;
int y0 = linecmds[2] / 2;
int y1 = linecmds[0] / 2 - 1;
unsigned char *pixels = (unsigned char *)ptr + y0 + linecmds[1];
for (y=y0; y<=y1; y++) {
unsigned char color = *pixels++;
*(buf + slinex + (y*64)) = color;
} }
ScaleLine(); linecmds += 3;
break; // the rest of the shape is gone
} }
} }
slinex = 31;
stopx = ptr->rightpix;
// if (ptr->leftpix < 31) {
// scale to the right
//
slinex = xcenter;
stopx = shape->rightpix;
if (shape->leftpix<31)
{
srcx = 31; srcx = 31;
cmdptr = (word *)&shape->dataofs[32-shape->leftpix]; cmdptr = &ptr->dataofs[32 - ptr->leftpix];
} else {
srcx = ptr->leftpix - 1;
cmdptr = &ptr->dataofs[0];
} }
else while (++srcx <= stopx) {
{ short *linecmds = (short *)((unsigned char *)ptr + *cmdptr++);
srcx = shape->leftpix-1; while (linecmds[0]) {
cmdptr = (word *)&shape->dataofs[0]; int y;
} int y0 = linecmds[2] / 2;
slinewidth = 0; int y1 = linecmds[0] / 2 - 1;
unsigned char *pixels = (unsigned char *)ptr + y0 + linecmds[1];
while ( ++srcx <= stopx && (slinex+=slinewidth)<viewwidth) for (y=y0; y<=y1; y++) {
{ unsigned char color = *pixels++;
linecmds = (short *)((char *) shapeptr + *cmdptr++); *(buf + slinex + (y*64)) = color;
if ( !(slinewidth = scaledata[scale].count[srcx]) )
continue;
if (slinewidth == 1)
{
if (slinex>=0 && wallheight[slinex] < height)
{
ScaleLine ();
} }
continue; linecmds += 3;
}
//
// handle multi pixel lines
//
if (slinex<0)
{
if (slinewidth <= -slinex)
continue; // still off the left edge
slinewidth += slinex;
slinex = 0;
}
else
{
if (slinex + slinewidth > viewwidth)
slinewidth = viewwidth-slinex;
}
leftvis = (wallheight[slinex] < height);
rightvis = (wallheight[slinex+slinewidth-1] < height);
if (leftvis)
{
if (rightvis)
{
ScaleLine ();
}
else
{
while (wallheight[slinex+slinewidth-1] >= height)
slinewidth--;
ScaleLine ();
break; // the rest of the shape is gone
}
}
else
{
if (rightvis)
{
while (wallheight[slinex] >= height)
{
slinex++;
slinewidth--;
}
ScaleLine ();
}
else
continue; // totally obscured
} }
slinex++;
} }
spritegfx[shapenum] = FlipWall(buf, 64, 64);
MM_FreePtr((void *)&buf);
} }
void ScaleShape(int xcenter, int shapenum, unsigned height)
/*
=======================
=
= SimpleScaleShape
=
= NO CLIPPING, height in pixels
=
= Draws a compiled shape at [scale] pixels high
=
=======================
*/
void SimpleScaleShape(int xcenter, int shapenum, unsigned height)
{ {
t_compshape *shape; unsigned int scaler = (64 << 16) / (height >> 2);
unsigned scale,srcx,stopx; unsigned int x, p;
unsigned short *cmdptr;
shape = PM_GetSpritePage (shapenum);
scale = height; if (spritegfx[shapenum] == NULL)
DeCompileSprite(shapenum);
linescale = scale;
shapeptr = shape; for (p = xcenter - (height >> 3), x = 0; x < (64 << 16); x += scaler, p++) {
// if ((p < 0) || (p >= viewwidth) || (wallheight[p] >= height))
// scale to the left (from pixel 31 to shape->leftpix)
//
srcx = 32;
slinex = xcenter;
stopx = shape->leftpix;
cmdptr = (word *)&shape->dataofs[31-stopx];
while ( --srcx >=stopx )
{
linecmds = (short *)((char *) shapeptr + *cmdptr--);
if ( !(slinewidth = scaledata[scale].count[srcx]) )
continue; continue;
slinex -= slinewidth; ScaleLineTrans((height >> 2) + 0, spritegfx[shapenum] + ((x >> 16) << 6), p);
ScaleLine (); }
} }
//
// scale to the right
//
slinex = xcenter;
stopx = shape->rightpix;
if (shape->leftpix<31)
{
srcx = 31;
cmdptr = (word *)&shape->dataofs[32-shape->leftpix];
}
else
{
srcx = shape->leftpix-1;
cmdptr = (word *)&shape->dataofs[0];
}
slinewidth = 0;
while ( ++srcx <= stopx ) void SimpleScaleShape(int xcenter, int shapenum, unsigned height)
{ {
linecmds = (short *)((char *) shapeptr + *cmdptr++); unsigned int scaler = (64 << 16) / height;
if ( !(slinewidth = scaledata[scale].count[srcx]) ) 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; continue;
ScaleLineTrans(height, spritegfx[shapenum] + ((x >> 16) << 6), p);
ScaleLine();
slinex += slinewidth;
} }
} }
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