Enable wipe effect with no additional heap

This commit is contained in:
Lephenixnoir 2021-09-07 21:55:12 +02:00
parent de8d48e714
commit f4c33a2b6a
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
6 changed files with 64 additions and 30 deletions

View File

@ -48,8 +48,8 @@ typedef enum
indetermined // Well, no IWAD found.
} GameMode_t;
//CGGOOM
//#define ENABLE_F_WIPE
#define ENABLE_F_WIPE
// Mission packs - might be useful for TC stuff?

View File

@ -46,24 +46,6 @@ static byte* wipe_scr_end;
static byte* wipe_scr;
void wipe_shittyColMajorXform( short* array, int width, int height )
{
int x;
int y;
short* dest;
dest = (short*) Z_Malloc(width*height*2, PU_STATIC, 0);
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*2);
Z_Free(dest);
}
int wipe_initColorXForm( int width, int height, int ticks )
{
ticks= 0; //Shuts up GCC
@ -134,10 +116,14 @@ int wipe_initMelt( int width, int height, int ticks )
// copy start screen to main screen
memcpy(wipe_scr, wipe_scr_start, width*height);
/* CGDoom: Normally the wipe effect transposes the buffers in color-major
order to better use the cache, but uses a screen-sized temporary buffer in
the process. We don't need the added speed, but we sure need every bit of
memory we can scrape. So we keep the row-major order. */
// makes this wipe faster (in theory)
// to have stuff in column-major format
wipe_shittyColMajorXform((short*)wipe_scr_start, width/2, height);
wipe_shittyColMajorXform((short*)wipe_scr_end, width/2, height);
// wipe_shittyColMajorXform((short*)wipe_scr_start, width/2, height);
// wipe_shittyColMajorXform((short*)wipe_scr_end, width/2, height);
// setup initial column positions
// (y<0 => not ready to scroll yet)
@ -154,8 +140,29 @@ int wipe_initMelt( int width, int height, int ticks )
return 0;
}
/* See wipe_doMelt(). */
short SPU2_read16(short *x)
{
if ((int)x & 2) {
volatile int *z = (int *)(x - 1);
return *z & 0xffff;
}
else {
volatile int *z = (int *)x;
return *z >> 16;
}
}
int wipe_doMelt( int width, int height, int ticks )
{
/* CGDoom: To spare memory, we have left both wipe_scr_start and wipe_scr_end
in row-major order. This affects the computation of (short *s) as well as
its stride (now a full row instead of 2 pixels).
In addition, the screen wipe buffers are allocated in PRAM to reduce
pressure on the heap. Therefore, only 4-byte accesses are possible, so we
read with SPU2_read16() to keep everything working. */
int i;
int j;
int dy;
@ -179,21 +186,23 @@ int wipe_doMelt( int width, int height, int ticks )
{
dy = (y[i] < 16) ? y[i]+1 : 8;
if (y[i]+dy >= height) dy = height - y[i];
s = &((short *)wipe_scr_end)[i*height+y[i]];
s = &((short *)wipe_scr_end)[y[i]*width+i]; /* Row-major order */
d = &((short *)wipe_scr)[y[i]*width+i];
idx = 0;
for (j=dy;j;j--)
{
d[idx] = *(s++);
d[idx] = SPU2_read16(s);
s += width; /* Row-major order */
idx += width;
}
y[i] += dy;
s = &((short *)wipe_scr_start)[i*height];
s = &((short *)wipe_scr_start)[i]; /* Row-major order */
d = &((short *)wipe_scr)[y[i]*width+i];
idx = 0;
for (j=height-y[i];j;j--)
{
d[idx] = *(s++);
d[idx] = SPU2_read16(s);
s += width; /* Row-major order */
idx += width;
}
done = false;
@ -226,7 +235,12 @@ int wipe_EndScreen( int x, int y, int width, int height )
{
wipe_scr_end = screens[3];
I_ReadScreen(wipe_scr_end);
/* CGDoom: The wipe buffer is in PRAM, so the V_DrawBlock() below may not
at every position on screen. But we always wipe the whole screen, so
that's not going to be a problem. */
V_DrawBlock(x, y, 0, width, height, wipe_scr_start); // restore start scr.
return 0;
}

View File

@ -24,6 +24,7 @@
#include "platform.h"
#include "cgdoom.h"
#include "cgdoom-alloc.h"
#include <stdlib.h>
#include "doomdef.h"
@ -131,6 +132,13 @@ byte *I_ScreenBase(int screen)
if (screen == 4)
return CGDOOM_SCREENS_BASE + 320*200*2;
/* For the wipe buffers, use PRAM. This can be done with rather little
changes because the wipe buffers are used only in f_wipe.c. */
if (screen == 2)
return CGD_PRAM_Malloc(320*200);
if (screen == 3)
return CGD_PRAM_Malloc(320*200);
return NULL;
}

View File

@ -248,3 +248,12 @@ void I_SetWindowAfterError(void)
}
#endif
//
// I_ReadScreen
//
void I_ReadScreen (byte* scr)
{
memcpy(scr, screens[0], SCREENWIDTH*SCREENHEIGHT);
}

View File

@ -374,8 +374,8 @@ const byte* R_GetColumn ( int tex, int col )
lump = texturecolumnlump[tex][col];
ofs = texturecolumnofs[tex][col];
/* CGDOOM: To save RAM in WADs bound by limited memory, composite textures
can be allowed only up to a certain size. Original CGDOOM limits to 8192
/* CGDoom: To save RAM in WADs bound by limited memory, composite textures
can be allowed only up to a certain size. Original CGDoom limits to 8192
bytes so that switches can appear, but some other textures fail. */
#if 0
if(lump <= 0 && texturecompositesize[tex] > 8192)

View File

@ -355,11 +355,14 @@ void V_Init (void)
screens[0] = I_ScreenBase(0);
/* screens[1] is used for the level end sequence (intermission) */
screens[1] = I_ScreenBase(1);
/* screens[2] and screens[3] are used for wipe effects (disabled here) */
/* screens[2] and screens[3] are used for wipe effects */
screens[2] = I_ScreenBase(2);
screens[3] = I_ScreenBase(3);
/* screens[4] is used for the status bar (allocated by st_stuff.c) */
screens[4] = NULL;
}
/* CGDOOM-specific function to clear screen when changing window size */
/* CGDoom-specific function to clear screen when changing window size */
void V_Clear (void)
{
memset(screens[0], 0, 320*(200-32));