mirror of
https://github.com/fabiangreffrath/woof.git
synced 2025-09-22 11:22:18 -04:00
interpolation of wipe melt animation, adapted from R&R (#1903)
* no need to skip DRS
This commit is contained in:
parent
4e6ed4a1a0
commit
e87ac53bb0
23
src/d_main.c
23
src/d_main.c
@ -292,7 +292,7 @@ void D_Display (void)
|
|||||||
if (gamestate != wipegamestate && (strictmode || screen_melt))
|
if (gamestate != wipegamestate && (strictmode || screen_melt))
|
||||||
{
|
{
|
||||||
wipe = true;
|
wipe = true;
|
||||||
wipe_StartScreen(0, 0, video.unscaledw, SCREENHEIGHT);
|
wipe_StartScreen(0, 0, video.width, video.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!wipe)
|
if (!wipe)
|
||||||
@ -432,29 +432,24 @@ void D_Display (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// wipe update
|
// wipe update
|
||||||
wipe_EndScreen(0, 0, video.unscaledw, SCREENHEIGHT);
|
wipe_EndScreen(0, 0, video.width, video.height);
|
||||||
|
|
||||||
wipestart = I_GetTime () - 1;
|
wipestart = I_GetTime () - 1;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
int nowtime, tics;
|
int nowtime = I_GetTime();
|
||||||
do
|
int tics = nowtime - wipestart;
|
||||||
{
|
|
||||||
I_Sleep(1);
|
fractionaltic = I_GetFracTime();
|
||||||
nowtime = I_GetTime();
|
|
||||||
tics = nowtime - wipestart;
|
|
||||||
}
|
|
||||||
while (!tics);
|
|
||||||
wipestart = nowtime;
|
|
||||||
done = wipe_ScreenWipe(strictmode ? wipe_Melt : screen_melt,
|
done = wipe_ScreenWipe(strictmode ? wipe_Melt : screen_melt,
|
||||||
0, 0, video.unscaledw, SCREENHEIGHT, tics);
|
0, 0, video.width, video.height, tics);
|
||||||
|
wipestart = nowtime;
|
||||||
M_Drawer(); // menu is drawn even on top of wipes
|
M_Drawer(); // menu is drawn even on top of wipes
|
||||||
I_FinishUpdate(); // page flip or blit buffer
|
I_FinishUpdate(); // page flip or blit buffer
|
||||||
}
|
}
|
||||||
while (!done);
|
while (!done);
|
||||||
|
|
||||||
drs_skip_frame = true; // skip DRS after wipe
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
237
src/f_wipe.c
237
src/f_wipe.c
@ -23,6 +23,7 @@
|
|||||||
#include "f_wipe.h"
|
#include "f_wipe.h"
|
||||||
#include "i_video.h"
|
#include "i_video.h"
|
||||||
#include "m_random.h"
|
#include "m_random.h"
|
||||||
|
#include "r_main.h"
|
||||||
#include "v_flextran.h"
|
#include "v_flextran.h"
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
@ -33,10 +34,10 @@
|
|||||||
// when they try to scale up the original logic to higher resolutions.
|
// when they try to scale up the original logic to higher resolutions.
|
||||||
|
|
||||||
// Number of "falling columns" on the screen.
|
// Number of "falling columns" on the screen.
|
||||||
static int num_columns;
|
static int wipe_columns;
|
||||||
|
|
||||||
// Distance a column falls before it reaches the bottom of the screen.
|
// Distance a column falls before it reaches the bottom of the screen.
|
||||||
#define COLUMN_MAX_Y 200
|
#define WIPE_ROWS 200
|
||||||
|
|
||||||
//
|
//
|
||||||
// SCREEN WIPE PACKAGE
|
// SCREEN WIPE PACKAGE
|
||||||
@ -46,18 +47,6 @@ static byte *wipe_scr_start;
|
|||||||
static byte *wipe_scr_end;
|
static byte *wipe_scr_end;
|
||||||
static byte *wipe_scr;
|
static byte *wipe_scr;
|
||||||
|
|
||||||
static void wipe_shittyColMajorXform(byte *array, int width, int height)
|
|
||||||
{
|
|
||||||
byte *dest = Z_Malloc(width*height, PU_STATIC, 0);
|
|
||||||
int x, y;
|
|
||||||
|
|
||||||
for(y=0;y<height;y++)
|
|
||||||
for(x=0;x<width;x++)
|
|
||||||
dest[x*height+y] = array[y*width+x];
|
|
||||||
memcpy(array, dest, width*height);
|
|
||||||
Z_Free(dest);
|
|
||||||
}
|
|
||||||
|
|
||||||
// [FG] cross-fading screen wipe implementation
|
// [FG] cross-fading screen wipe implementation
|
||||||
|
|
||||||
static int fade_tick;
|
static int fade_tick;
|
||||||
@ -102,99 +91,170 @@ static int wipe_exit(int width, int height, int ticks)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int *col_y;
|
static int *ybuff1, *ybuff2;
|
||||||
|
static int *curry, *prevy;
|
||||||
|
|
||||||
static int wipe_initMelt(int width, int height, int ticks)
|
static int wipe_initMelt(int width, int height, int ticks)
|
||||||
{
|
{
|
||||||
int i;
|
wipe_columns = video.unscaledw / 2;
|
||||||
|
|
||||||
num_columns = video.unscaledw / 2;
|
ybuff1 = Z_Malloc(wipe_columns * sizeof(*ybuff1), PU_STATIC, NULL);
|
||||||
|
ybuff2 = Z_Malloc(wipe_columns * sizeof(*ybuff2), PU_STATIC, NULL);
|
||||||
|
|
||||||
col_y = Z_Malloc(num_columns * sizeof(*col_y), PU_STATIC, NULL);
|
curry = ybuff1;
|
||||||
|
prevy = ybuff2;
|
||||||
|
|
||||||
// copy start screen to main screen
|
// copy start screen to main screen
|
||||||
V_PutBlock(0, 0, width, height, wipe_scr_start);
|
V_PutBlock(0, 0, width, height, wipe_scr_start);
|
||||||
|
|
||||||
// makes this wipe faster (in theory)
|
// setup initial column positions (y<0 => not ready to scroll yet)
|
||||||
// to have stuff in column-major format
|
curry[0] = -(M_Random() % 16);
|
||||||
wipe_shittyColMajorXform(wipe_scr_start, width, height);
|
for (int i = 1; i < wipe_columns; i++)
|
||||||
wipe_shittyColMajorXform(wipe_scr_end, width, height);
|
|
||||||
|
|
||||||
// setup initial column positions (y<0 => not ready to scroll yet)
|
|
||||||
col_y[0] = -(M_Random()%16);
|
|
||||||
for (i=1;i<num_columns;i++)
|
|
||||||
{
|
{
|
||||||
int r = (M_Random()%3) - 1;
|
int r = (M_Random() % 3) - 1;
|
||||||
col_y[i] = col_y[i-1] + r;
|
curry[i] = curry[i - 1] + r;
|
||||||
if (col_y[i] > 0)
|
if (curry[i] > 0)
|
||||||
col_y[i] = 0;
|
{
|
||||||
else
|
curry[i] = 0;
|
||||||
if (col_y[i] == -16)
|
}
|
||||||
col_y[i] = -15;
|
else if (curry[i] == -16)
|
||||||
|
{
|
||||||
|
curry[i] = -15;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
memcpy(prevy, curry, sizeof(int) * wipe_columns);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wipe_doMelt(int width, int height, int ticks)
|
static int wipe_doMelt(int width, int height, int ticks)
|
||||||
{
|
{
|
||||||
boolean done = true;
|
boolean done = true;
|
||||||
int x, y, xfactor, yfactor;
|
|
||||||
|
|
||||||
while (ticks--)
|
if (ticks > 0)
|
||||||
for (x=0;x<num_columns;x++)
|
{
|
||||||
if (col_y[x]<0)
|
while (ticks--)
|
||||||
{
|
{
|
||||||
col_y[x]++;
|
int *temp = prevy;
|
||||||
done = false;
|
prevy = curry;
|
||||||
|
curry = temp;
|
||||||
|
|
||||||
|
for (int col = 0; col < wipe_columns; ++col)
|
||||||
|
{
|
||||||
|
if (prevy[col] < 0)
|
||||||
|
{
|
||||||
|
curry[col] = prevy[col] + 1;
|
||||||
|
done = false;
|
||||||
|
}
|
||||||
|
else if (prevy[col] < WIPE_ROWS)
|
||||||
|
{
|
||||||
|
int dy = (prevy[col] < 16) ? prevy[col] + 1 : 8;
|
||||||
|
curry[col] = MIN(prevy[col] + dy, WIPE_ROWS);
|
||||||
|
|
||||||
|
done = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
curry[col] = WIPE_ROWS;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (col_y[x] < COLUMN_MAX_Y)
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int col = 0; col < wipe_columns; ++col)
|
||||||
{
|
{
|
||||||
int dy = (col_y[x] < 16) ? col_y[x]+1 : 8;
|
done &= curry[col] >= WIPE_ROWS;
|
||||||
if (col_y[x]+dy >= COLUMN_MAX_Y)
|
}
|
||||||
dy = COLUMN_MAX_Y - col_y[x];
|
}
|
||||||
col_y[x] += dy;
|
|
||||||
done = false;
|
return done;
|
||||||
|
}
|
||||||
|
|
||||||
|
int wipe_renderMelt(int width, int height, int ticks)
|
||||||
|
{
|
||||||
|
boolean done = true;
|
||||||
|
|
||||||
|
// Scale up and then down to handle arbitrary dimensions with integer math
|
||||||
|
int vertblocksize = height * 100 / WIPE_ROWS;
|
||||||
|
int horizblocksize = width * 100 / wipe_columns;
|
||||||
|
int currcol;
|
||||||
|
int currcolend;
|
||||||
|
int currrow;
|
||||||
|
|
||||||
|
V_UseBuffer(wipe_scr);
|
||||||
|
V_PutBlock(0, 0, width, height, wipe_scr_end);
|
||||||
|
V_RestoreBuffer();
|
||||||
|
|
||||||
|
for (int col = 0; col < wipe_columns; ++col)
|
||||||
|
{
|
||||||
|
int current;
|
||||||
|
if (uncapped)
|
||||||
|
{
|
||||||
|
current = FixedToInt(
|
||||||
|
LerpFixed(IntToFixed(prevy[col]), IntToFixed(curry[col])));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
current = curry[col];
|
||||||
}
|
}
|
||||||
|
|
||||||
xfactor = (width + num_columns - 1) / num_columns;
|
if (current < 0)
|
||||||
yfactor = (height + COLUMN_MAX_Y - 1) / COLUMN_MAX_Y;
|
{
|
||||||
|
currcol = col * horizblocksize / 100;
|
||||||
|
currcolend = (col + 1) * horizblocksize / 100;
|
||||||
|
for (; currcol < currcolend; ++currcol)
|
||||||
|
{
|
||||||
|
pixel_t *source = wipe_scr_start + currcol;
|
||||||
|
pixel_t *dest = wipe_scr + currcol;
|
||||||
|
|
||||||
for (x = 0; x < width; x++)
|
for (int i = 0; i < height; ++i)
|
||||||
{
|
{
|
||||||
byte *s, *d;
|
*dest = *source;
|
||||||
int scroff = col_y[x / xfactor] * yfactor;
|
dest += video.pitch;
|
||||||
if (scroff > height)
|
source += width;
|
||||||
scroff = height;
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (current < WIPE_ROWS)
|
||||||
|
{
|
||||||
|
currcol = col * horizblocksize / 100;
|
||||||
|
currcolend = (col + 1) * horizblocksize / 100;
|
||||||
|
|
||||||
d = wipe_scr + x;
|
currrow = current * vertblocksize / 100;
|
||||||
s = wipe_scr_end + x * height;
|
|
||||||
for (y = 0; y < scroff; ++y)
|
for (; currcol < currcolend; ++currcol)
|
||||||
{
|
{
|
||||||
*d = *s;
|
pixel_t *source = wipe_scr_start + currcol;
|
||||||
d += video.pitch;
|
pixel_t *dest = wipe_scr + currcol + (currrow * video.pitch);
|
||||||
s++;
|
|
||||||
|
for (int i = 0; i < height - currrow; ++i)
|
||||||
|
{
|
||||||
|
*dest = *source;
|
||||||
|
dest += video.pitch;
|
||||||
|
source += width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
done = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
s = wipe_scr_start + x * height;
|
|
||||||
for (; y < height; ++y)
|
return done;
|
||||||
{
|
|
||||||
*d = *s;
|
|
||||||
d += video.pitch;
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return done;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wipe_exitMelt(int width, int height, int ticks)
|
static int wipe_exitMelt(int width, int height, int ticks)
|
||||||
{
|
{
|
||||||
Z_Free(col_y);
|
Z_Free(ybuff1);
|
||||||
|
Z_Free(ybuff2);
|
||||||
wipe_exit(width, height, ticks);
|
wipe_exit(width, height, ticks);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wipe_StartScreen(int x, int y, int width, int height)
|
int wipe_StartScreen(int x, int y, int width, int height)
|
||||||
{
|
{
|
||||||
int size = video.width * video.height;
|
int size = width * height;
|
||||||
wipe_scr_start = Z_Malloc(size * sizeof(*wipe_scr_start), PU_STATIC, NULL);
|
wipe_scr_start = Z_Malloc(size * sizeof(*wipe_scr_start), PU_STATIC, NULL);
|
||||||
I_ReadScreen(wipe_scr_start);
|
I_ReadScreen(wipe_scr_start);
|
||||||
return 0;
|
return 0;
|
||||||
@ -202,14 +262,14 @@ int wipe_StartScreen(int x, int y, int width, int height)
|
|||||||
|
|
||||||
int wipe_EndScreen(int x, int y, int width, int height)
|
int wipe_EndScreen(int x, int y, int width, int height)
|
||||||
{
|
{
|
||||||
int size = video.width * video.height;
|
int size = width * height;
|
||||||
wipe_scr_end = Z_Malloc(size * sizeof(*wipe_scr_end), PU_STATIC, NULL);
|
wipe_scr_end = Z_Malloc(size * sizeof(*wipe_scr_end), PU_STATIC, NULL);
|
||||||
I_ReadScreen(wipe_scr_end);
|
I_ReadScreen(wipe_scr_end);
|
||||||
V_DrawBlock(x, y, width, height, wipe_scr_start); // restore start scr.
|
V_DrawBlock(x, y, width, height, wipe_scr_start); // restore start scr.
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wipe_NOP(int x, int y, int t)
|
static int wipe_NOP(int width, int height, int tics)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -266,7 +326,7 @@ static unsigned int lastrndval;
|
|||||||
static int wipe_initFizzle(int width, int height, int ticks)
|
static int wipe_initFizzle(int width, int height, int ticks)
|
||||||
{
|
{
|
||||||
int rndbits_x = log2_ceil(video.unscaledw);
|
int rndbits_x = log2_ceil(video.unscaledw);
|
||||||
rndbits_y = log2_ceil(COLUMN_MAX_Y);
|
rndbits_y = log2_ceil(WIPE_ROWS);
|
||||||
|
|
||||||
int rndbits = rndbits_x + rndbits_y;
|
int rndbits = rndbits_x + rndbits_y;
|
||||||
if (rndbits < 17)
|
if (rndbits < 17)
|
||||||
@ -285,7 +345,7 @@ static int wipe_initFizzle(int width, int height, int ticks)
|
|||||||
|
|
||||||
static int wipe_doFizzle(int width, int height, int ticks)
|
static int wipe_doFizzle(int width, int height, int ticks)
|
||||||
{
|
{
|
||||||
const int pixperframe = (video.unscaledw * COLUMN_MAX_Y) >> 5;
|
const int pixperframe = (video.unscaledw * WIPE_ROWS) >> 5;
|
||||||
unsigned int rndval = lastrndval;
|
unsigned int rndval = lastrndval;
|
||||||
|
|
||||||
for (unsigned p = 0; p < pixperframe; p++)
|
for (unsigned p = 0; p < pixperframe; p++)
|
||||||
@ -299,7 +359,7 @@ static int wipe_doFizzle(int width, int height, int ticks)
|
|||||||
|
|
||||||
rndval = (rndval >> 1) ^ (rndval & 1 ? 0 : rndmask);
|
rndval = (rndval >> 1) ^ (rndval & 1 ? 0 : rndmask);
|
||||||
|
|
||||||
if (x >= video.unscaledw || y >= COLUMN_MAX_Y)
|
if (x >= video.unscaledw || y >= WIPE_ROWS)
|
||||||
{
|
{
|
||||||
if (rndval == 0) // entire sequence has been completed
|
if (rndval == 0) // entire sequence has been completed
|
||||||
{
|
{
|
||||||
@ -336,17 +396,21 @@ static int wipe_doFizzle(int width, int height, int ticks)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int (*const wipes[])(int, int, int) = {
|
static int (*const wipes[])(int, int, int) = {
|
||||||
|
wipe_NOP,
|
||||||
wipe_NOP,
|
wipe_NOP,
|
||||||
wipe_NOP,
|
wipe_NOP,
|
||||||
wipe_exit,
|
wipe_exit,
|
||||||
wipe_initMelt,
|
wipe_initMelt,
|
||||||
wipe_doMelt,
|
wipe_doMelt,
|
||||||
|
wipe_renderMelt,
|
||||||
wipe_exitMelt,
|
wipe_exitMelt,
|
||||||
wipe_initColorXForm,
|
wipe_initColorXForm,
|
||||||
wipe_doColorXForm,
|
wipe_doColorXForm,
|
||||||
|
wipe_NOP,
|
||||||
wipe_exit,
|
wipe_exit,
|
||||||
wipe_initFizzle,
|
wipe_initFizzle,
|
||||||
wipe_doFizzle,
|
wipe_doFizzle,
|
||||||
|
wipe_NOP,
|
||||||
wipe_exit,
|
wipe_exit,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -355,18 +419,19 @@ int wipe_ScreenWipe(int wipeno, int x, int y, int width, int height, int ticks)
|
|||||||
{
|
{
|
||||||
static boolean go; // when zero, stop the wipe
|
static boolean go; // when zero, stop the wipe
|
||||||
|
|
||||||
width = video.width;
|
|
||||||
height = video.height;
|
|
||||||
|
|
||||||
if (!go) // initial stuff
|
if (!go) // initial stuff
|
||||||
{
|
{
|
||||||
go = 1;
|
go = 1;
|
||||||
wipe_scr = I_VideoBuffer;
|
wipe_scr = I_VideoBuffer;
|
||||||
wipes[wipeno*3](width, height, ticks);
|
wipes[wipeno*4](width, height, ticks);
|
||||||
}
|
}
|
||||||
if (wipes[wipeno*3+1](width, height, ticks)) // final stuff
|
|
||||||
|
int rc = wipes[wipeno*4+1](width, height, ticks);
|
||||||
|
wipes[wipeno*4+2](width, height, ticks);
|
||||||
|
|
||||||
|
if (rc) // final stuff
|
||||||
{
|
{
|
||||||
wipes[wipeno*3+2](width, height, ticks);
|
wipes[wipeno*4+3](width, height, ticks);
|
||||||
go = 0;
|
go = 0;
|
||||||
}
|
}
|
||||||
return !go;
|
return !go;
|
||||||
|
@ -44,6 +44,10 @@
|
|||||||
#define FRACUNIT (1<<FRACBITS)
|
#define FRACUNIT (1<<FRACBITS)
|
||||||
#define FIXED2DOUBLE(x) ((x)/(double)FRACUNIT)
|
#define FIXED2DOUBLE(x) ((x)/(double)FRACUNIT)
|
||||||
#define FRACMASK (FRACUNIT - 1)
|
#define FRACMASK (FRACUNIT - 1)
|
||||||
|
#define FRACFILL(x, o) ((x) | ((o) < 0 ? (FRACMASK << (32 - FRACBITS)) : 0))
|
||||||
|
|
||||||
|
#define IntToFixed(x) ((x) << FRACBITS)
|
||||||
|
#define FixedToInt(x) FRACFILL((x) >> FRACBITS, (x))
|
||||||
|
|
||||||
typedef int fixed_t;
|
typedef int fixed_t;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user