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
...@@ -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,96 +2,38 @@ ...@@ -2,96 +2,38 @@
#include "wl_def.h" #include "wl_def.h"
/* Originally from David Haslam -- dch@sirius.demon.co.uk */ typedef struct
{
/* word leftpix, rightpix;
============================================================================= word dataofs[64];
/* table data after dataofs[rightpix-leftpix+1] */
GLOBALS } PACKED t_compshape;
=============================================================================
*/
/* 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) /* TODO: this accesses gfxbuf directly! */
static void ScaledDraw(byte *gfx, int scale, byte *vid, unsigned long tfrac, unsigned long tint, unsigned long delta)
{ {
long fix, step; unsigned long OldDelta;
int src;
int startpix, endpix, toppix;
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];
}
}
}
/* while (scale--) {
========================== *vid = *gfx;
= vid += 320; /* TODO: compiled in constant! */
= SetupScaling OldDelta = delta;
= delta += tfrac;
========================== gfx += tint;
*/
void SetupScaling(int maxscaleheight) if (OldDelta > delta)
{ gfx += 1;
int i;
maxscale = maxscaleheight-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--) {
if (*gfx != 255)
*vid = *gfx; *vid = *gfx;
vid += 320; /* TODO: compiled in constant! */ vid += 320; /* TODO: compiled in constant! */
OldDelta = delta; OldDelta = delta;
...@@ -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;
while (linecmds[0]) {
y0 = linecmds[2] / 2;
y1 = linecmds[0] / 2;
pixels = (unsigned char *)shapeptr + y0 + linecmds[1];
for (y = y0; y < y1; y++) {
color = *pixels++;
ys = scaledata[linescale].desty[y];
if (ys >= 0) {
for (ny = 0; ny < scaledata[linescale].count[y]; ny++)
for (n = 0, x = slinex; n < slinewidth; n++, x++)
VL_Plot(x+xoffset, ys+ny+yoffset, color);
}
}
linecmds += 3;
}
}
/* if (height) {
======================= TheFrac = 0x40000000UL / height;
=
= ScaleShape
=
= Draws a compiled shape at [scale] pixels high
=
=======================
*/
void ScaleShape(int xcenter, int shapenum, unsigned height) if (height < viewheight) {
{ y = yoffset + (viewheight - height) / 2;
t_compshape *shape; TheInt = TheFrac >> 24;
unsigned scale,srcx,stopx; TheFrac <<= 8;
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) ScaledDrawTrans(source, height, gfxbuf + (y * 320) + x + xoffset,
{ TheFrac, TheInt, 0);
slinex--;
if (slinex<viewwidth)
{
if (wallheight[slinex] >= height)
continue; // obscured by closer wall
ScaleLine ();
}
continue;
}
// return;
// 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;
} }
y = (height - viewheight) / 2;
y *= TheFrac;
leftvis = (wallheight[slinex] < height); TheInt = TheFrac >> 24;
rightvis = (wallheight[slinex+slinewidth-1] < height); TheFrac <<= 8;
if (leftvis)
{
if (rightvis)
ScaleLine ();
else
{
while (wallheight[slinex+slinewidth-1] >= height)
slinewidth--;
ScaleLine ();
}
}
else
{
if (!rightvis)
continue; // totally obscured
while (wallheight[slinex] >= height) ScaledDrawTrans(&source[y >> 24], viewheight, gfxbuf + (yoffset * 320) + x + xoffset,
{ TheFrac, TheInt, y << 8);
slinex++;
slinewidth--;
}
ScaleLine();
break; // the rest of the shape is gone
}
} }
}
static unsigned char *spritegfx[SPR_TOTAL];
// /* TODO: merge FlipWall into function below */
// scale to the right static byte *FlipWall(byte *dat, int w, int h)
// {
slinex = xcenter; byte *buf;
stopx = shape->rightpix; int i, j;
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 && (slinex+=slinewidth)<viewwidth) buf = (byte *)malloc(w * h);
{
linecmds = (short *)((char *) shapeptr + *cmdptr++);
if ( !(slinewidth = scaledata[scale].count[srcx]) )
continue;
if (slinewidth == 1) for (j = 0; j < h; j++)
{ for (i = 0; i < w; i++)
if (slinex>=0 && wallheight[slinex] < height) buf[j*w+i] = dat[i*w+j];
{ return buf;
ScaleLine (); }
}
continue;
}
// static void DeCompileSprite(int shapenum)
// handle multi pixel lines {
// t_compshape *ptr;
if (slinex<0) unsigned char *buf;
{ int srcx = 32;
if (slinewidth <= -slinex) int slinex = 31;
continue; // still off the left edge int stopx;
unsigned short int *cmdptr;
slinewidth += slinex; MM_GetPtr((void *)&buf, 64 * 64);
slinex = 0;
}
else
{
if (slinex + slinewidth > viewwidth)
slinewidth = viewwidth-slinex;
}
ptr = PM_GetSpritePage(shapenum);
leftvis = (wallheight[slinex] < height); memset(buf, 255, 64 * 64);
rightvis = (wallheight[slinex+slinewidth-1] < height);
if (leftvis) stopx = ptr->leftpix;
{ cmdptr = &ptr->dataofs[31-stopx];
if (rightvis) while ( --srcx >=stopx ) {
{ short *linecmds = (short *)((unsigned char *)ptr + *cmdptr--);
ScaleLine (); 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;
} }
else linecmds += 3;
{
while (wallheight[slinex+slinewidth-1] >= height)
slinewidth--;
ScaleLine ();
break; // the rest of the shape is gone
} }
} }
else slinex = 31;
{ stopx = ptr->rightpix;
if (rightvis) if (ptr->leftpix < 31) {
{ srcx = 31;
while (wallheight[slinex] >= height) cmdptr = &ptr->dataofs[32 - ptr->leftpix];
{ } else {
slinex++; srcx = ptr->leftpix - 1;
slinewidth--; cmdptr = &ptr->dataofs[0];
} }
ScaleLine (); while (++srcx <= stopx) {
short *linecmds = (short *)((unsigned char *)ptr + *cmdptr++);
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;
} }
else linecmds += 3;
continue; // totally obscured
} }
slinex++;
} }
}
spritegfx[shapenum] = FlipWall(buf, 64, 64);
MM_FreePtr((void *)&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);
=
= SimpleScaleShape
=
= NO CLIPPING, height in pixels
=
= Draws a compiled shape at [scale] pixels high
=
=======================
*/
void SimpleScaleShape(int xcenter, int shapenum, unsigned height) for (p = xcenter - (height >> 3), x = 0; x < (64 << 16); x += scaler, p++) {
{ if ((p < 0) || (p >= viewwidth) || (wallheight[p] >= height))
t_compshape *shape;
unsigned scale,srcx,stopx;
unsigned short *cmdptr;
shape = PM_GetSpritePage (shapenum);
scale = height;
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 )
{
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 ();
} }
}
void SimpleScaleShape(int xcenter, int shapenum, unsigned height)
{
unsigned int scaler = (64 << 16) / height;
unsigned int x, p;
// if (spritegfx[shapenum] == NULL)
// scale to the right DeCompileSprite(shapenum);
//
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 ) for (p = xcenter - (height / 2), x = 0; x < (64 << 16); x += scaler, p++) {
{ if ((p < 0) || (p >= viewwidth))
linecmds = (short *)((char *) shapeptr + *cmdptr++);
if ( !(slinewidth = scaledata[scale].count[srcx]) )
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