Fix TROR & skyboxes to work with mirrors in Software & Polymost

git-svn-id: https://svn.eduke32.com/eduke32@7733 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
pogokeen 2019-06-25 18:35:05 +00:00 committed by Christoph Oelckers
parent 2c85a0a53c
commit cdd83905ca
6 changed files with 80 additions and 49 deletions

View file

@ -1368,6 +1368,8 @@ static int32_t *swplc, *lplc, *swall, *lwall;
static float *swallf; static float *swallf;
#endif #endif
uint8_t* mirrorBuffer;
static int32_t smostcnt; static int32_t smostcnt;
static int32_t smoststart[MAXWALLSB]; static int32_t smoststart[MAXWALLSB];
static char smostwalltype[MAXWALLSB]; static char smostwalltype[MAXWALLSB];
@ -1467,7 +1469,7 @@ int16_t searchsector, searchwall, searchstat; //search output
// When aiming at a 2-sided wall, 1 if aiming at the bottom part, 0 else // When aiming at a 2-sided wall, 1 if aiming at the bottom part, 0 else
int16_t searchbottomwall, searchisbottom; int16_t searchbottomwall, searchisbottom;
char inpreparemirror = 0, mirrorrender = 0; char inpreparemirror = 0;
static int32_t mirrorsx1, mirrorsy1, mirrorsx2, mirrorsy2; static int32_t mirrorsx1, mirrorsy1, mirrorsx2, mirrorsy2;
#define MAXSETVIEW 4 #define MAXSETVIEW 4
@ -8025,8 +8027,6 @@ int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz,
int32_t i, j, /*cz, fz,*/ closest; int32_t i, j, /*cz, fz,*/ closest;
int16_t *shortptr1, *shortptr2; int16_t *shortptr1, *shortptr2;
int32_t didmirror = 0;
beforedrawrooms = 0; beforedrawrooms = 0;
set_globalpos(daposx, daposy, daposz); set_globalpos(daposx, daposy, daposz);
@ -8183,7 +8183,7 @@ int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz,
polymost_drawrooms(); polymost_drawrooms();
if (videoGetRenderMode() != REND_CLASSIC) if (videoGetRenderMode() != REND_CLASSIC)
return 0; return inpreparemirror;
//============================================================================= //POLYMOST ENDS //============================================================================= //POLYMOST ENDS
#endif #endif
@ -8236,16 +8236,14 @@ int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz,
// INPREPAREMIRROR_NO_BUNCHES // INPREPAREMIRROR_NO_BUNCHES
// numbunches==0 can happen if the mirror is far away... the game code decides // numbunches==0 can happen if the mirror is far away... the game code decides
// to draw it, but scansector gets zero bunches. Result: big screwup! // to draw it, but scansector gets zero bunches. Result: big screwup!
// Leave inpreparemirror as is, it's restored by completemirror. // Set inpreparemirror to 0 to indicate that we were unable to render the mirror
if (numbunches==0) if (numbunches==0)
{ {
inpreparemirror = 0;
videoEndDrawing(); //!!! videoEndDrawing(); //!!!
return 0; return 0;
} }
inpreparemirror = 0;
didmirror = 1;
mirrorsx1 = xdimen-1; mirrorsx2 = 0; mirrorsx1 = xdimen-1; mirrorsx2 = 0;
for (i=numscans-1; i>=0; i--) for (i=numscans-1; i>=0; i--)
{ {
@ -8301,7 +8299,7 @@ int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz,
videoEndDrawing(); //}}} videoEndDrawing(); //}}}
return didmirror; return inpreparemirror;
} }
// UTILITY TYPES AND FUNCTIONS FOR DRAWMASKS OCCLUSION TREE // UTILITY TYPES AND FUNCTIONS FOR DRAWMASKS OCCLUSION TREE
@ -9962,6 +9960,7 @@ static void videoAllocateBuffers(void)
{ (void **)&dotp1, clamped_ydim * sizeof(intptr_t) }, { (void **)&dotp1, clamped_ydim * sizeof(intptr_t) },
{ (void **)&dotp2, clamped_ydim * sizeof(intptr_t) }, { (void **)&dotp2, clamped_ydim * sizeof(intptr_t) },
{ (void **)&lastx, clamped_ydim * sizeof(int32_t) }, { (void **)&lastx, clamped_ydim * sizeof(int32_t) },
{ (void **)&mirrorBuffer, (size_t) (xdim * ydim)},
}; };
for (i = 0; i < (signed)ARRAY_SIZE(dynarray); i++) for (i = 0; i < (signed)ARRAY_SIZE(dynarray); i++)
@ -11701,7 +11700,6 @@ void squarerotatetile(int16_t tilenume)
void renderPrepareMirror(int32_t dax, int32_t day, fix16_t daang, int16_t dawall, void renderPrepareMirror(int32_t dax, int32_t day, fix16_t daang, int16_t dawall,
int32_t *tposx, int32_t *tposy, fix16_t *tang) int32_t *tposx, int32_t *tposy, fix16_t *tang)
{ {
mirrorrender = 1;
const int32_t x = wall[dawall].x, dx = wall[wall[dawall].point2].x-x; const int32_t x = wall[dawall].x, dx = wall[wall[dawall].point2].x-x;
const int32_t y = wall[dawall].y, dy = wall[wall[dawall].point2].y-y; const int32_t y = wall[dawall].y, dy = wall[wall[dawall].point2].y-y;
@ -11764,15 +11762,15 @@ void renderPrepareMirrorOld(int32_t dax, int32_t day, int32_t daz, fix16_t daang
// //
void renderCompleteMirror(void) void renderCompleteMirror(void)
{ {
mirrorrender = 0; // Don't try to complete a mirror if we haven't drawn the reflection for one
if (!inpreparemirror) { return; }
inpreparemirror = 0;
#ifdef USE_OPENGL #ifdef USE_OPENGL
if (videoGetRenderMode() != REND_CLASSIC) if (videoGetRenderMode() != REND_CLASSIC)
return; return;
#endif #endif
// Can't reverse when the world has not yet been drawn from the other side.
if (inpreparemirror) { inpreparemirror = 0; return; }
// The mirroring code maps the rightmost pixel to the right neighbor of the // The mirroring code maps the rightmost pixel to the right neighbor of the
// leftmost one (see copybufreverse() call below). Thus, the leftmost would // leftmost one (see copybufreverse() call below). Thus, the leftmost would
// be mapped to the right neighbor of the rightmost one, which would be out // be mapped to the right neighbor of the rightmost one, which would be out
@ -11795,22 +11793,21 @@ void renderCompleteMirror(void)
int const height = mirrorsy2-mirrorsy1; int const height = mirrorsy2-mirrorsy1;
// Address of the mirror wall's top left corner in the source scene: // Address of the mirror wall's top left corner in the source scene:
intptr_t p = frameplace + ylookup[windowxy1.y+mirrorsy1] + windowxy1.x+mirrorsx1; intptr_t s = (intptr_t) mirrorBuffer + ylookup[windowxy1.y+mirrorsy1] + windowxy1.x+mirrorsx1;
// Offset (wrt p) of a mirror line's left corner in the destination: // Pointer to the mirror line's left corner in the destination:
// p+destof == frameplace + ylookup[...] + windowxy2.x-mirrorsx2 intptr_t d = (intptr_t) frameplace + ylookup[windowxy1.y+mirrorsy1] + windowxy2.x-mirrorsx2;
int const destofs = windowxy2.x-mirrorsx2-windowxy1.x-mirrorsx1;
for (bssize_t y=0; y<height; y++) for (bssize_t y=0; y<height; y++)
{ {
#if 0 #if 0
if ((p-frameplace) + width-1 >= bytesperline*ydim) if ((p-mirrorBuffer) + width-1 >= bytesperline*ydim)
printf("oob read: mirrorsx1=%d, mirrorsx2=%d\n", mirrorsx1, mirrorsx2); printf("oob read: mirrorsx1=%d, mirrorsx2=%d\n", mirrorsx1, mirrorsx2);
#endif #endif
copybufbyte((void *)p, tempbuf, width); copybufreverse((void *)(s+width-1), (void *)(d+1), width);
copybufreverse(&tempbuf[width-1], (void *)(p+destofs+1), width);
p += ylookup[1]; s += ylookup[1];
d += ylookup[1];
faketimerhandler(); faketimerhandler();
} }

View file

@ -209,6 +209,7 @@ extern int16_t thesector[MAXWALLSB], thewall[MAXWALLSB];
extern int16_t bunchfirst[MAXWALLSB], bunchlast[MAXWALLSB]; extern int16_t bunchfirst[MAXWALLSB], bunchlast[MAXWALLSB];
extern int16_t maskwall[MAXWALLSB], maskwallcnt; extern int16_t maskwall[MAXWALLSB], maskwallcnt;
extern tspriteptr_t tspriteptr[MAXSPRITESONSCREEN + 1]; extern tspriteptr_t tspriteptr[MAXSPRITESONSCREEN + 1];
extern uint8_t* mirrorBuffer;
extern int32_t xdimen, xdimenrecip, halfxdimen, xdimenscale, xdimscale, ydimen; extern int32_t xdimen, xdimenrecip, halfxdimen, xdimenscale, xdimscale, ydimen;
extern float fxdimen; extern float fxdimen;
extern intptr_t frameoffset; extern intptr_t frameoffset;
@ -236,7 +237,7 @@ extern int32_t searchx, searchy;
extern int16_t searchsector, searchwall, searchstat; extern int16_t searchsector, searchwall, searchstat;
extern int16_t searchbottomwall, searchisbottom; extern int16_t searchbottomwall, searchisbottom;
extern char inpreparemirror, mirrorrender; extern char inpreparemirror;
extern char picsiz[MAXTILES]; extern char picsiz[MAXTILES];
extern int16_t sectorborder[256]; extern int16_t sectorborder[256];

View file

@ -5505,7 +5505,7 @@ void polymost_drawrooms()
gctang = (gctang > 0.f) ? 1.f : -1.f; gctang = (gctang > 0.f) ? 1.f : -1.f;
} }
if (mirrorrender) if (inpreparemirror)
gstang = -gstang; gstang = -gstang;
//Generate viewport trapezoid (for handling screen up/down) //Generate viewport trapezoid (for handling screen up/down)
@ -5525,7 +5525,7 @@ void polymost_drawrooms()
} }
#if !SOFTROTMAT #if !SOFTROTMAT
if (mirrorrender) if (inpreparemirror)
gstang = -gstang; gstang = -gstang;
#endif #endif
@ -5603,20 +5603,19 @@ void polymost_drawrooms()
grhalfxdown10x = grhalfxdown10; grhalfxdown10x = grhalfxdown10;
if (mirrorrender)
grhalfxdown10x = -grhalfxdown10;
if (inpreparemirror) if (inpreparemirror)
{ {
inpreparemirror = 0;
// see engine.c: INPREPAREMIRROR_NO_BUNCHES // see engine.c: INPREPAREMIRROR_NO_BUNCHES
if (numbunches > 0) if (numbunches > 0)
{ {
grhalfxdown10x = -grhalfxdown10;
polymost_drawalls(0); polymost_drawalls(0);
numbunches--; numbunches--;
bunchfirst[0] = bunchfirst[numbunches]; bunchfirst[0] = bunchfirst[numbunches];
bunchlast[0] = bunchlast[numbunches]; bunchlast[0] = bunchlast[numbunches];
} else
{
inpreparemirror = 0;
} }
} }

View file

@ -1650,21 +1650,22 @@ void videoBeginDrawing(void)
if (offscreenrendering) return; if (offscreenrendering) return;
if (inpreparemirror)
{
frameplace = (intptr_t)mirrorBuffer;
}
else
#ifdef USE_OPENGL #ifdef USE_OPENGL
if (!nogl) if (!nogl)
{ {
frameplace = (intptr_t)glsurface_getBuffer(); frameplace = (intptr_t)glsurface_getBuffer();
if (modechange)
{
bytesperline = xdim;
calc_ylookup(bytesperline, ydim);
modechange=0;
}
return;
} }
else
#endif #endif
{
frameplace = (intptr_t)softsurface_getBuffer();
}
frameplace = (intptr_t)softsurface_getBuffer();
if (modechange) if (modechange)
{ {
bytesperline = xdim; bytesperline = xdim;

View file

@ -623,17 +623,44 @@ void G_HandleMirror(int32_t x, int32_t y, int32_t z, fix16_t a, fix16_t q16horiz
int32_t tposx, tposy; int32_t tposx, tposy;
fix16_t tang; fix16_t tang;
//prepare to render any scripted EVENT_DISPLAYROOMS extras as mirrored
renderPrepareMirror(x, y, a, g_mirrorWall[i], &tposx, &tposy, &tang); renderPrepareMirror(x, y, a, g_mirrorWall[i], &tposx, &tposy, &tang);
int32_t j = g_visibility; int32_t j = g_visibility;
g_visibility = (j>>1) + (j>>2); g_visibility = (j>>1) + (j>>2);
//backup original camera position
int32_t origCamX = CAMERA(pos.x);
int32_t origCamY = CAMERA(pos.y);
int32_t origCamZ = CAMERA(pos.z);
fix16_t origCamq16ang = CAMERA(q16ang);
fix16_t origCamq16horiz = CAMERA(q16horiz);
//set the camera inside the mirror facing out
CAMERA(pos.x) = tposx;
CAMERA(pos.y) = tposy;
CAMERA(pos.z) = z;
CAMERA(q16ang) = tang;
CAMERA(q16horiz) = q16horiz;
display_mirror = 1;
VM_OnEventWithReturn(EVENT_DISPLAYROOMS, g_player[0].ps->i, 0, 0);
display_mirror = 0;
//reset the camera position
CAMERA(pos.x) = origCamX;
CAMERA(pos.y) = origCamY;
CAMERA(pos.z) = origCamZ;
CAMERA(q16ang) = origCamq16ang;
CAMERA(q16horiz) = origCamq16horiz;
//prepare to render the mirror
renderPrepareMirror(x, y, a, g_mirrorWall[i], &tposx, &tposy, &tang);
if (videoGetRenderMode() != REND_POLYMER) if (videoGetRenderMode() != REND_POLYMER)
{ {
int32_t didmirror; int32_t didmirror;
yax_preparedrawrooms(); yax_preparedrawrooms();
didmirror = renderDrawRoomsQ16(tposx,tposy,z,tang,q16horiz,g_mirrorSector[i]+MAXSECTORS); didmirror = renderDrawRoomsQ16(tposx,tposy,z,tang,q16horiz,g_mirrorSector[i]+MAXSECTORS);
//POGO: if didmirror == 0, we may simply wish to abort instead of rendering with yax_drawrooms (which may require cleaning yax state)
yax_drawrooms(G_DoSpriteAnimations, g_mirrorSector[i], didmirror, smoothratio); yax_drawrooms(G_DoSpriteAnimations, g_mirrorSector[i], didmirror, smoothratio);
} }
#ifdef USE_OPENGL #ifdef USE_OPENGL
@ -649,19 +676,22 @@ void G_HandleMirror(int32_t x, int32_t y, int32_t z, fix16_t a, fix16_t q16horiz
renderCompleteMirror(); //Reverse screen x-wise in this function renderCompleteMirror(); //Reverse screen x-wise in this function
g_visibility = j; g_visibility = j;
} }
}
}
static void G_ClearGotMirror()
{
#ifdef SPLITSCREEN_MOD_HACKS #ifdef SPLITSCREEN_MOD_HACKS
if (!g_fakeMultiMode) if (!g_fakeMultiMode)
#endif #endif
{ {
// HACK for splitscreen mod: this is so that mirrors will be drawn // HACK for splitscreen mod: this is so that mirrors will be drawn
// from showview commands. Ugly, because we'll attempt do draw mirrors // from showview commands. Ugly, because we'll attempt do draw mirrors
// each frame then. But it's better than not drawing them, I guess. // each frame then. But it's better than not drawing them, I guess.
// XXX: fix the sequence of setting/clearing this bit. Right now, // XXX: fix the sequence of setting/clearing this bit. Right now,
// we always draw one frame without drawing the mirror, after which // we always draw one frame without drawing the mirror, after which
// the bit gets set and drawn subsequently. // the bit gets set and drawn subsequently.
gotpic[MIRROR>>3] &= ~(1<<(MIRROR&7)); gotpic[MIRROR>>3] &= ~(1<<(MIRROR&7));
}
} }
} }
@ -1029,6 +1059,7 @@ void G_DrawRooms(int32_t playerNum, int32_t smoothRatio)
#endif #endif
G_HandleMirror(CAMERA(pos.x), CAMERA(pos.y), CAMERA(pos.z), CAMERA(q16ang), CAMERA(q16horiz), smoothRatio); G_HandleMirror(CAMERA(pos.x), CAMERA(pos.y), CAMERA(pos.z), CAMERA(q16ang), CAMERA(q16horiz), smoothRatio);
G_ClearGotMirror();
#ifdef LEGACY_ROR #ifdef LEGACY_ROR
G_SE40(smoothRatio); G_SE40(smoothRatio);
#endif #endif

View file

@ -1175,6 +1175,7 @@ LUNATIC_EXTERN void G_ShowView(vec3_t vec, fix16_t a, fix16_t horiz, int sect, i
if (g_screenCapture) if (g_screenCapture)
return; return;
//POGOTODO: check if this has anything to do with cameras not rendering the skybox properly
if (offscreenrendering) if (offscreenrendering)
{ {
videoClearViewableArea(0); videoClearViewableArea(0);
@ -1215,7 +1216,8 @@ LUNATIC_EXTERN void G_ShowView(vec3_t vec, fix16_t a, fix16_t horiz, int sect, i
renderSetAspect(viewingRange, yxAspect); renderSetAspect(viewingRange, yxAspect);
int const smoothratio = calc_smoothratio(totalclock, ototalclock); int const smoothratio = calc_smoothratio(totalclock, ototalclock);
G_DoInterpolations(smoothratio); G_DoInterpolations(smoothratio);
G_HandleMirror(vec.x, vec.y, vec.z, a, horiz, smoothratio); if (!display_mirror)
G_HandleMirror(vec.x, vec.y, vec.z, a, horiz, smoothratio);
#ifdef POLYMER #ifdef POLYMER
if (videoGetRenderMode() == REND_POLYMER) if (videoGetRenderMode() == REND_POLYMER)
polymer_setanimatesprites(G_DoSpriteAnimations, vec.x, vec.y, fix16_to_int(a), smoothratio); polymer_setanimatesprites(G_DoSpriteAnimations, vec.x, vec.y, fix16_to_int(a), smoothratio);