- Removed the screenshot parameter from D_Display(), since it was a relic of
a long-abandoned experiment to write directly to video memory instead of to a temporary buffer in system meroy. - Added Direct3D versions of the melt and burn screenwipes. - Fixed the strip sizes for the melt screenwipe to match what Doom would have produced on a 320x200 screen, rather than producing more, thinner strips for wider screens. SVN r659 (trunk)
This commit is contained in:
parent
db54c43175
commit
dc98279403
11 changed files with 1486 additions and 1022 deletions
329
src/f_wipe.cpp
329
src/f_wipe.cpp
|
|
@ -53,6 +53,10 @@ static int fade;
|
|||
|
||||
// Melt -------------------------------------------------------------
|
||||
|
||||
// Match the strip sizes that oldschool Doom used on a 320x200 screen.
|
||||
#define MELT_WIDTH 160
|
||||
#define MELT_HEIGHT 200
|
||||
|
||||
void wipe_shittyColMajorXform (short *array)
|
||||
{
|
||||
int x, y;
|
||||
|
|
@ -84,14 +88,12 @@ bool wipe_initMelt (int ticks)
|
|||
|
||||
// setup initial column positions
|
||||
// (y<0 => not ready to scroll yet)
|
||||
y = new int[SCREENWIDTH*sizeof(int)];
|
||||
y[0] = -(M_Random()&0xf);
|
||||
for (i = 1; i < SCREENWIDTH; i++)
|
||||
y = new int[MELT_WIDTH];
|
||||
y[0] = -(M_Random() & 15);
|
||||
for (i = 1; i < MELT_WIDTH; i++)
|
||||
{
|
||||
r = (M_Random()%3) - 1;
|
||||
y[i] = y[i-1] + r;
|
||||
if (y[i] > 0) y[i] = 0;
|
||||
else if (y[i] == -16) y[i] = -15;
|
||||
y[i] = clamp(y[i-1] + r, -15, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -99,50 +101,51 @@ bool wipe_initMelt (int ticks)
|
|||
|
||||
bool wipe_doMelt (int ticks)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
int dy;
|
||||
int idx;
|
||||
|
||||
short* s;
|
||||
short* d;
|
||||
bool done = true;
|
||||
|
||||
int width = SCREENWIDTH / 2;
|
||||
int i, j, dy, x;
|
||||
const short *s;
|
||||
short *d;
|
||||
bool done;
|
||||
|
||||
while (ticks--)
|
||||
{
|
||||
for (i = 0; i < width; i++)
|
||||
done = true;
|
||||
for (i = 0; i < MELT_WIDTH; i++)
|
||||
{
|
||||
if (y[i] < 0)
|
||||
{
|
||||
y[i]++; done = false;
|
||||
}
|
||||
else if (y[i] < SCREENHEIGHT)
|
||||
{
|
||||
int pitch = screen->GetPitch() / 2;
|
||||
dy = (y[i] < 16) ? y[i]+1 : 8;
|
||||
dy = (dy * SCREENHEIGHT) / 200;
|
||||
if (y[i]+dy >= SCREENHEIGHT)
|
||||
dy = SCREENHEIGHT - y[i];
|
||||
s = &wipe_scr_end[i*SCREENHEIGHT+y[i]];
|
||||
d = &((short *)screen->GetBuffer())[y[i]*pitch+i];
|
||||
idx = 0;
|
||||
for (j=dy;j;j--)
|
||||
{
|
||||
d[idx] = *(s++);
|
||||
idx += pitch;
|
||||
}
|
||||
y[i] += dy;
|
||||
s = &wipe_scr_start[i*SCREENHEIGHT];
|
||||
d = &((short *)screen->GetBuffer())[y[i]*pitch+i];
|
||||
idx = 0;
|
||||
for (j=SCREENHEIGHT-y[i];j;j--)
|
||||
{
|
||||
d[idx] = *(s++);
|
||||
idx += pitch;
|
||||
}
|
||||
y[i]++;
|
||||
done = false;
|
||||
}
|
||||
else if (y[i] < MELT_HEIGHT)
|
||||
{
|
||||
dy = (y[i] < 16) ? y[i]+1 : 8;
|
||||
y[i] = MIN(y[i] + dy, MELT_HEIGHT);
|
||||
done = false;
|
||||
}
|
||||
if (ticks == 0 && y[i] >= 0)
|
||||
{ // Only draw for the final tick.
|
||||
const int pitch = screen->GetPitch() / 2;
|
||||
int sy = y[i] * SCREENHEIGHT / MELT_HEIGHT;
|
||||
|
||||
for (x = i * (SCREENWIDTH/2) / MELT_WIDTH; x < (i + 1) * (SCREENWIDTH/2) / MELT_WIDTH; ++x)
|
||||
{
|
||||
s = &wipe_scr_end[x*SCREENHEIGHT];
|
||||
d = &((short *)screen->GetBuffer())[x];
|
||||
|
||||
for (j = sy; j != 0; --j)
|
||||
{
|
||||
*d = *(s++);
|
||||
d += pitch;
|
||||
}
|
||||
|
||||
s = &wipe_scr_start[x*SCREENHEIGHT];
|
||||
|
||||
for (j = SCREENHEIGHT - sy; j != 0; --j)
|
||||
{
|
||||
*d = *(s++);
|
||||
d += pitch;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -167,136 +170,147 @@ bool wipe_initBurn (int ticks)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int wipe_CalcBurn (BYTE *burnarray, int width, int height, int density)
|
||||
{
|
||||
// This is a modified version of the fire that was once used
|
||||
// on the player setup menu.
|
||||
static int voop;
|
||||
|
||||
int a, b;
|
||||
BYTE *from;
|
||||
|
||||
// generator
|
||||
from = &burnarray[width * height];
|
||||
b = voop;
|
||||
voop += density / 3;
|
||||
for (a = 0; a < density/8; a++)
|
||||
{
|
||||
unsigned int offs = (a+b) & (width - 1);
|
||||
unsigned int v = M_Random();
|
||||
v = MIN(from[offs] + 4 + (v & 15) + (v >> 3) + (M_Random() & 31), 255u);
|
||||
from[offs] = from[width*2 + ((offs + width*3/2) & (width - 1))] = v;
|
||||
}
|
||||
|
||||
density = MIN(density + 10, width * 7);
|
||||
|
||||
from = burnarray;
|
||||
for (b = 0; b <= height; b += 2)
|
||||
{
|
||||
BYTE *pixel = from;
|
||||
|
||||
// special case: first pixel on line
|
||||
BYTE *p = pixel + (width << 1);
|
||||
unsigned int top = *p + *(p + width - 1) + *(p + 1);
|
||||
unsigned int bottom = *(pixel + (width << 2));
|
||||
unsigned int c1 = (top + bottom) >> 2;
|
||||
if (c1 > 1) c1--;
|
||||
*pixel = c1;
|
||||
*(pixel + width) = (c1 + bottom) >> 1;
|
||||
pixel++;
|
||||
|
||||
// main line loop
|
||||
for (a = 1; a < width-1; a++)
|
||||
{
|
||||
// sum top pixels
|
||||
p = pixel + (width << 1);
|
||||
top = *p + *(p - 1) + *(p + 1);
|
||||
|
||||
// bottom pixel
|
||||
bottom = *(pixel + (width << 2));
|
||||
|
||||
// combine pixels
|
||||
c1 = (top + bottom) >> 2;
|
||||
if (c1 > 1) c1--;
|
||||
|
||||
// store pixels
|
||||
*pixel = c1;
|
||||
*(pixel + width) = (c1 + bottom) >> 1; // interpolate
|
||||
|
||||
// next pixel
|
||||
pixel++;
|
||||
}
|
||||
|
||||
// special case: last pixel on line
|
||||
p = pixel + (width << 1);
|
||||
top = *p + *(p - 1) + *(p - width + 1);
|
||||
bottom = *(pixel + (width << 2));
|
||||
c1 = (top + bottom) >> 2;
|
||||
if (c1 > 1) c1--;
|
||||
*pixel = c1;
|
||||
*(pixel + width) = (c1 + bottom) >> 1;
|
||||
|
||||
// next line
|
||||
from += width << 1;
|
||||
}
|
||||
|
||||
// Check for done-ness. (Every pixel with level 126 or higher counts as done.)
|
||||
for (a = width * height, from = burnarray; a != 0; --a, ++from)
|
||||
{
|
||||
if (*from < 126)
|
||||
{
|
||||
return density;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool wipe_doBurn (int ticks)
|
||||
{
|
||||
static int voop;
|
||||
bool done;
|
||||
|
||||
// This is a modified version of the fire from the player
|
||||
// setup menu.
|
||||
burntime += ticks;
|
||||
ticks *= 2;
|
||||
|
||||
// Make the fire burn
|
||||
while (ticks--)
|
||||
done = false;
|
||||
while (!done && ticks--)
|
||||
{
|
||||
int a, b;
|
||||
BYTE *from;
|
||||
|
||||
// generator
|
||||
from = burnarray + FIREHEIGHT * FIREWIDTH;
|
||||
b = voop;
|
||||
voop += density / 3;
|
||||
for (a = 0; a < density/8; a++)
|
||||
{
|
||||
unsigned int offs = (a+b) % FIREWIDTH;
|
||||
unsigned int v = M_Random();
|
||||
v = from[offs] + 4 + (v & 15) + (v >> 3) + (M_Random() & 31);
|
||||
if (v > 255)
|
||||
v = 255;
|
||||
from[offs] = from[FIREWIDTH*2 + (offs + FIREWIDTH*3/2)%FIREWIDTH] = v;
|
||||
}
|
||||
|
||||
density += 10;
|
||||
if (density > FIREWIDTH*7)
|
||||
density = FIREWIDTH*7;
|
||||
|
||||
from = burnarray;
|
||||
for (b = 0; b <= FIREHEIGHT; b += 2)
|
||||
{
|
||||
BYTE *pixel = from;
|
||||
|
||||
// special case: first pixel on line
|
||||
BYTE *p = pixel + (FIREWIDTH << 1);
|
||||
unsigned int top = *p + *(p + FIREWIDTH - 1) + *(p + 1);
|
||||
unsigned int bottom = *(pixel + (FIREWIDTH << 2));
|
||||
unsigned int c1 = (top + bottom) >> 2;
|
||||
if (c1 > 1) c1--;
|
||||
*pixel = c1;
|
||||
*(pixel + FIREWIDTH) = (c1 + bottom) >> 1;
|
||||
pixel++;
|
||||
|
||||
// main line loop
|
||||
for (a = 1; a < FIREWIDTH-1; a++)
|
||||
{
|
||||
// sum top pixels
|
||||
p = pixel + (FIREWIDTH << 1);
|
||||
top = *p + *(p - 1) + *(p + 1);
|
||||
|
||||
// bottom pixel
|
||||
bottom = *(pixel + (FIREWIDTH << 2));
|
||||
|
||||
// combine pixels
|
||||
c1 = (top + bottom) >> 2;
|
||||
if (c1 > 1) c1--;
|
||||
|
||||
// store pixels
|
||||
*pixel = c1;
|
||||
*(pixel + FIREWIDTH) = (c1 + bottom) >> 1; // interpolate
|
||||
|
||||
// next pixel
|
||||
pixel++;
|
||||
}
|
||||
|
||||
// special case: last pixel on line
|
||||
p = pixel + (FIREWIDTH << 1);
|
||||
top = *p + *(p - 1) + *(p - FIREWIDTH + 1);
|
||||
bottom = *(pixel + (FIREWIDTH << 2));
|
||||
c1 = (top + bottom) >> 2;
|
||||
if (c1 > 1) c1--;
|
||||
*pixel = c1;
|
||||
*(pixel + FIREWIDTH) = (c1 + bottom) >> 1;
|
||||
|
||||
// next line
|
||||
from += FIREWIDTH << 1;
|
||||
}
|
||||
density = wipe_CalcBurn(burnarray, FIREWIDTH, FIREHEIGHT, density);
|
||||
done = (density < 0);
|
||||
}
|
||||
|
||||
// Draw the screen
|
||||
fixed_t xstep, ystep, firex, firey;
|
||||
int x, y;
|
||||
BYTE *to, *fromold, *fromnew;
|
||||
|
||||
xstep = (FIREWIDTH * FRACUNIT) / SCREENWIDTH;
|
||||
ystep = (FIREHEIGHT * FRACUNIT) / SCREENHEIGHT;
|
||||
to = screen->GetBuffer();
|
||||
fromold = (BYTE *)wipe_scr_start;
|
||||
fromnew = (BYTE *)wipe_scr_end;
|
||||
|
||||
for (y = 0, firey = 0; y < SCREENHEIGHT; y++, firey += ystep)
|
||||
{
|
||||
fixed_t xstep, ystep, firex, firey;
|
||||
int x, y;
|
||||
BYTE *to, *fromold, *fromnew;
|
||||
|
||||
xstep = (FIREWIDTH * FRACUNIT) / SCREENWIDTH;
|
||||
ystep = (FIREHEIGHT * FRACUNIT) / SCREENHEIGHT;
|
||||
to = screen->GetBuffer();
|
||||
fromold = (BYTE *)wipe_scr_start;
|
||||
fromnew = (BYTE *)wipe_scr_end;
|
||||
done = true;
|
||||
|
||||
for (y = 0, firey = 0; y < SCREENHEIGHT; y++, firey += ystep)
|
||||
for (x = 0, firex = 0; x < SCREENWIDTH; x++, firex += xstep)
|
||||
{
|
||||
for (x = 0, firex = 0; x < SCREENWIDTH; x++, firex += xstep)
|
||||
{
|
||||
int fglevel;
|
||||
int fglevel;
|
||||
|
||||
fglevel = burnarray[(firex>>FRACBITS)+(firey>>FRACBITS)*FIREWIDTH] / 2;
|
||||
if (fglevel >= 63)
|
||||
{
|
||||
to[x] = fromnew[x];
|
||||
}
|
||||
else if (fglevel == 0)
|
||||
{
|
||||
to[x] = fromold[x];
|
||||
done = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
int bglevel = 64-fglevel;
|
||||
DWORD *fg2rgb = Col2RGB8[fglevel];
|
||||
DWORD *bg2rgb = Col2RGB8[bglevel];
|
||||
DWORD fg = fg2rgb[fromnew[x]];
|
||||
DWORD bg = bg2rgb[fromold[x]];
|
||||
fg = (fg+bg) | 0x1f07c1f;
|
||||
to[x] = RGB32k[0][0][fg & (fg>>15)];
|
||||
done = false;
|
||||
}
|
||||
fglevel = burnarray[(firex>>FRACBITS)+(firey>>FRACBITS)*FIREWIDTH] / 2;
|
||||
if (fglevel >= 63)
|
||||
{
|
||||
to[x] = fromnew[x];
|
||||
}
|
||||
else if (fglevel == 0)
|
||||
{
|
||||
to[x] = fromold[x];
|
||||
done = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
int bglevel = 64-fglevel;
|
||||
DWORD *fg2rgb = Col2RGB8[fglevel];
|
||||
DWORD *bg2rgb = Col2RGB8[bglevel];
|
||||
DWORD fg = fg2rgb[fromnew[x]];
|
||||
DWORD bg = bg2rgb[fromold[x]];
|
||||
fg = (fg+bg) | 0x1f07c1f;
|
||||
to[x] = RGB32k[0][0][fg & (fg>>15)];
|
||||
done = false;
|
||||
}
|
||||
fromold += SCREENWIDTH;
|
||||
fromnew += SCREENWIDTH;
|
||||
to += SCREENPITCH;
|
||||
}
|
||||
fromold += SCREENWIDTH;
|
||||
fromnew += SCREENWIDTH;
|
||||
to += SCREENPITCH;
|
||||
}
|
||||
|
||||
return done || (burntime > 40);
|
||||
|
|
@ -318,7 +332,7 @@ bool wipe_initFade (int ticks)
|
|||
|
||||
bool wipe_doFade (int ticks)
|
||||
{
|
||||
fade += ticks;
|
||||
fade += ticks * 2;
|
||||
if (fade > 64)
|
||||
{
|
||||
screen->DrawBlock (0, 0, SCREENWIDTH, SCREENHEIGHT, (BYTE *)wipe_scr_end);
|
||||
|
|
@ -348,7 +362,6 @@ bool wipe_doFade (int ticks)
|
|||
to += SCREENPITCH;
|
||||
}
|
||||
}
|
||||
fade++;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue