Code refactoring to turn portal struct into a more generalized shape.
Split portal-related code to its own source files. Most of the 2-line-specific setup has been moved to the function which adds a 2-line case. The portals should render as they used to so far, anyway.
This commit is contained in:
parent
ec0719f74f
commit
df0a40b3c2
|
@ -123,6 +123,7 @@ set(SRB2_CORE_RENDER_SOURCES
|
||||||
r_sky.c
|
r_sky.c
|
||||||
r_splats.c
|
r_splats.c
|
||||||
r_things.c
|
r_things.c
|
||||||
|
r_portal.c
|
||||||
|
|
||||||
r_bsp.h
|
r_bsp.h
|
||||||
r_data.h
|
r_data.h
|
||||||
|
@ -136,6 +137,7 @@ set(SRB2_CORE_RENDER_SOURCES
|
||||||
r_splats.h
|
r_splats.h
|
||||||
r_state.h
|
r_state.h
|
||||||
r_things.h
|
r_things.h
|
||||||
|
r_portal.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(SRB2_CORE_GAME_SOURCES
|
set(SRB2_CORE_GAME_SOURCES
|
||||||
|
|
|
@ -455,6 +455,7 @@ OBJS:=$(i_main_o) \
|
||||||
$(OBJDIR)/r_sky.o \
|
$(OBJDIR)/r_sky.o \
|
||||||
$(OBJDIR)/r_splats.o \
|
$(OBJDIR)/r_splats.o \
|
||||||
$(OBJDIR)/r_things.o \
|
$(OBJDIR)/r_things.o \
|
||||||
|
$(OBJDIR)/r_portal.o \
|
||||||
$(OBJDIR)/screen.o \
|
$(OBJDIR)/screen.o \
|
||||||
$(OBJDIR)/v_video.o \
|
$(OBJDIR)/v_video.o \
|
||||||
$(OBJDIR)/s_sound.o \
|
$(OBJDIR)/s_sound.o \
|
||||||
|
|
|
@ -26,7 +26,6 @@ side_t *sidedef;
|
||||||
line_t *linedef;
|
line_t *linedef;
|
||||||
sector_t *frontsector;
|
sector_t *frontsector;
|
||||||
sector_t *backsector;
|
sector_t *backsector;
|
||||||
boolean portalline; // is curline a portal seg?
|
|
||||||
|
|
||||||
// very ugly realloc() of drawsegs at run-time, I upped it to 512
|
// very ugly realloc() of drawsegs at run-time, I upped it to 512
|
||||||
// instead of 256.. and someone managed to send me a level with
|
// instead of 256.. and someone managed to send me a level with
|
||||||
|
@ -459,7 +458,7 @@ static void R_AddLine(seg_t *line)
|
||||||
line2 = P_FindSpecialLineFromTag(40, line->linedef->tag, line2);
|
line2 = P_FindSpecialLineFromTag(40, line->linedef->tag, line2);
|
||||||
if (line2 >= 0) // found it!
|
if (line2 >= 0) // found it!
|
||||||
{
|
{
|
||||||
R_AddPortal(line->linedef-lines, line2, x1, x2); // Remember the lines for later rendering
|
Portal_Add2Lines(line->linedef-lines, line2, x1, x2); // Remember the lines for later rendering
|
||||||
//return; // Don't fill in that space now!
|
//return; // Don't fill in that space now!
|
||||||
goto clipsolid;
|
goto clipsolid;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,6 @@ void R_ClearClipSegs(void);
|
||||||
void R_PortalClearClipSegs(INT32 start, INT32 end);
|
void R_PortalClearClipSegs(INT32 start, INT32 end);
|
||||||
void R_ClearDrawSegs(void);
|
void R_ClearDrawSegs(void);
|
||||||
void R_RenderBSPNode(INT32 bspnum);
|
void R_RenderBSPNode(INT32 bspnum);
|
||||||
void R_AddPortal(INT32 line1, INT32 line2, INT32 x1, INT32 x2);
|
|
||||||
|
|
||||||
#ifdef POLYOBJECTS
|
#ifdef POLYOBJECTS
|
||||||
void R_SortPolyObjects(subsector_t *sub);
|
void R_SortPolyObjects(subsector_t *sub);
|
||||||
|
|
170
src/r_main.c
170
src/r_main.c
|
@ -30,6 +30,7 @@
|
||||||
#include "p_spec.h" // skyboxmo
|
#include "p_spec.h" // skyboxmo
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
#include "m_random.h" // quake camera shake
|
#include "m_random.h" // quake camera shake
|
||||||
|
#include "r_portal.h"
|
||||||
|
|
||||||
#ifdef HWRENDER
|
#ifdef HWRENDER
|
||||||
#include "hardware/hw_main.h"
|
#include "hardware/hw_main.h"
|
||||||
|
@ -70,32 +71,6 @@ boolean skyVisible1, skyVisible2; // saved values of skyVisible for P1 and P2, f
|
||||||
sector_t *viewsector;
|
sector_t *viewsector;
|
||||||
player_t *viewplayer;
|
player_t *viewplayer;
|
||||||
|
|
||||||
// PORTALS!
|
|
||||||
// You can thank and/or curse JTE for these.
|
|
||||||
UINT8 portalrender;
|
|
||||||
sector_t *portalcullsector;
|
|
||||||
typedef struct portal_pair
|
|
||||||
{
|
|
||||||
INT32 line1;
|
|
||||||
INT32 line2;
|
|
||||||
UINT8 pass;
|
|
||||||
struct portal_pair *next;
|
|
||||||
|
|
||||||
fixed_t viewx;
|
|
||||||
fixed_t viewy;
|
|
||||||
fixed_t viewz;
|
|
||||||
angle_t viewangle;
|
|
||||||
|
|
||||||
INT32 start;
|
|
||||||
INT32 end;
|
|
||||||
INT16 *ceilingclip;
|
|
||||||
INT16 *floorclip;
|
|
||||||
fixed_t *frontscale;
|
|
||||||
} portal_pair;
|
|
||||||
portal_pair *portal_base, *portal_cap;
|
|
||||||
line_t *portalclipline;
|
|
||||||
INT32 portalclipstart, portalclipend;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// precalculated math tables
|
// precalculated math tables
|
||||||
//
|
//
|
||||||
|
@ -1010,17 +985,8 @@ void R_SkyboxFrame(player_t *player)
|
||||||
R_SetupFreelook();
|
R_SetupFreelook();
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ANGLED_PORTALS
|
static void R_PortalFrame(portal_t *portal)
|
||||||
|
|
||||||
static void R_PortalFrame(line_t *start, line_t *dest, portal_pair *portal)
|
|
||||||
{
|
{
|
||||||
vertex_t dest_c, start_c;
|
|
||||||
#ifdef ANGLED_PORTALS
|
|
||||||
// delta angle
|
|
||||||
angle_t dangle = R_PointToAngle2(0,0,dest->dx,dest->dy) - R_PointToAngle2(start->dx,start->dy,0,0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//R_SetupFrame(player, false);
|
|
||||||
viewx = portal->viewx;
|
viewx = portal->viewx;
|
||||||
viewy = portal->viewy;
|
viewy = portal->viewy;
|
||||||
viewz = portal->viewz;
|
viewz = portal->viewz;
|
||||||
|
@ -1029,93 +995,18 @@ static void R_PortalFrame(line_t *start, line_t *dest, portal_pair *portal)
|
||||||
viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT);
|
viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT);
|
||||||
viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
|
viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
|
||||||
|
|
||||||
portalcullsector = dest->frontsector;
|
|
||||||
viewsector = dest->frontsector;
|
|
||||||
portalclipline = dest;
|
|
||||||
portalclipstart = portal->start;
|
portalclipstart = portal->start;
|
||||||
portalclipend = portal->end;
|
portalclipend = portal->end;
|
||||||
|
|
||||||
// Offset the portal view by the linedef centers
|
if (portal->clipline != -1)
|
||||||
|
|
||||||
// looking glass center
|
|
||||||
start_c.x = (start->v1->x + start->v2->x) / 2;
|
|
||||||
start_c.y = (start->v1->y + start->v2->y) / 2;
|
|
||||||
|
|
||||||
// other side center
|
|
||||||
dest_c.x = (dest->v1->x + dest->v2->x) / 2;
|
|
||||||
dest_c.y = (dest->v1->y + dest->v2->y) / 2;
|
|
||||||
|
|
||||||
// Heights!
|
|
||||||
viewz += dest->frontsector->floorheight - start->frontsector->floorheight;
|
|
||||||
|
|
||||||
// calculate the difference in position and rotation!
|
|
||||||
#ifdef ANGLED_PORTALS
|
|
||||||
if (dangle == 0)
|
|
||||||
#endif
|
|
||||||
{ // the entrance goes straight opposite the exit, so we just need to mess with the offset.
|
|
||||||
viewx += dest_c.x - start_c.x;
|
|
||||||
viewy += dest_c.y - start_c.y;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ANGLED_PORTALS
|
|
||||||
viewangle += dangle;
|
|
||||||
viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT);
|
|
||||||
viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
|
|
||||||
//CONS_Printf("dangle == %u\n", AngleFixed(dangle)>>FRACBITS);
|
|
||||||
|
|
||||||
// ????
|
|
||||||
{
|
{
|
||||||
fixed_t disttopoint;
|
portalclipline = &lines[portal->clipline];
|
||||||
angle_t angtopoint;
|
viewsector = portalcullsector = portalclipline->frontsector;
|
||||||
|
|
||||||
disttopoint = R_PointToDist2(start_c.x, start_c.y, viewx, viewy);
|
|
||||||
angtopoint = R_PointToAngle2(start_c.x, start_c.y, viewx, viewy);
|
|
||||||
angtopoint += dangle;
|
|
||||||
|
|
||||||
viewx = dest_c.x+FixedMul(FINECOSINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
|
|
||||||
viewy = dest_c.y+FixedMul(FINESINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void R_AddPortal(INT32 line1, INT32 line2, INT32 x1, INT32 x2)
|
|
||||||
{
|
|
||||||
portal_pair *portal = Z_Malloc(sizeof(portal_pair), PU_LEVEL, NULL);
|
|
||||||
INT16 *ceilingclipsave = Z_Malloc(sizeof(INT16)*(x2-x1), PU_LEVEL, NULL);
|
|
||||||
INT16 *floorclipsave = Z_Malloc(sizeof(INT16)*(x2-x1), PU_LEVEL, NULL);
|
|
||||||
fixed_t *frontscalesave = Z_Malloc(sizeof(fixed_t)*(x2-x1), PU_LEVEL, NULL);
|
|
||||||
|
|
||||||
portal->line1 = line1;
|
|
||||||
portal->line2 = line2;
|
|
||||||
portal->pass = portalrender+1;
|
|
||||||
portal->next = NULL;
|
|
||||||
|
|
||||||
R_PortalStoreClipValues(x1, x2, ceilingclipsave, floorclipsave, frontscalesave);
|
|
||||||
|
|
||||||
portal->ceilingclip = ceilingclipsave;
|
|
||||||
portal->floorclip = floorclipsave;
|
|
||||||
portal->frontscale = frontscalesave;
|
|
||||||
|
|
||||||
portal->start = x1;
|
|
||||||
portal->end = x2;
|
|
||||||
|
|
||||||
portalline = true; // this tells R_StoreWallRange that curline is a portal seg
|
|
||||||
|
|
||||||
portal->viewx = viewx;
|
|
||||||
portal->viewy = viewy;
|
|
||||||
portal->viewz = viewz;
|
|
||||||
portal->viewangle = viewangle;
|
|
||||||
|
|
||||||
if (!portal_base)
|
|
||||||
{
|
|
||||||
portal_base = portal;
|
|
||||||
portal_cap = portal;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
portal_cap->next = portal;
|
portalclipline = NULL;
|
||||||
portal_cap = portal;
|
viewsector = portalcullsector = R_PointInSubsector(viewx, viewy)->sector;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1131,7 +1022,7 @@ void R_AddPortal(INT32 line1, INT32 line2, INT32 x1, INT32 x2)
|
||||||
|
|
||||||
void R_RenderPlayerView(player_t *player)
|
void R_RenderPlayerView(player_t *player)
|
||||||
{
|
{
|
||||||
portal_pair *portal;
|
portal_t *portal;
|
||||||
const boolean skybox = (skyboxmo[0] && cv_skybox.value);
|
const boolean skybox = (skyboxmo[0] && cv_skybox.value);
|
||||||
|
|
||||||
if (cv_homremoval.value && player == &players[displayplayer]) // if this is display player 1
|
if (cv_homremoval.value && player == &players[displayplayer]) // if this is display player 1
|
||||||
|
@ -1148,8 +1039,7 @@ void R_RenderPlayerView(player_t *player)
|
||||||
else
|
else
|
||||||
skyVisible = skyVisible1;
|
skyVisible = skyVisible1;
|
||||||
|
|
||||||
portalrender = 0;
|
Portal_InitList();
|
||||||
portal_base = portal_cap = NULL;
|
|
||||||
|
|
||||||
if (skybox && skyVisible)
|
if (skybox && skyVisible)
|
||||||
{
|
{
|
||||||
|
@ -1206,35 +1096,37 @@ void R_RenderPlayerView(player_t *player)
|
||||||
#endif
|
#endif
|
||||||
//profile stuff ---------------------------------------------------------
|
//profile stuff ---------------------------------------------------------
|
||||||
|
|
||||||
// PORTAL RENDERING
|
// Portal rendering. Hijacks the BSP traversal.
|
||||||
for(portal = portal_base; portal; portal = portal_base)
|
if (portal_base)
|
||||||
{
|
{
|
||||||
// render the portal
|
for(portal = portal_base; portal; portal = portal_base)
|
||||||
CONS_Debug(DBG_RENDER, "Rendering portal from line %d to %d\n", portal->line1, portal->line2);
|
{
|
||||||
portalrender = portal->pass;
|
portalrender = portal->pass; // Recursiveness depth.
|
||||||
|
|
||||||
R_PortalFrame(&lines[portal->line1], &lines[portal->line2], portal);
|
// Apply the viewpoint stored for the portal.
|
||||||
|
R_PortalFrame(portal);
|
||||||
|
|
||||||
R_PortalClearClipSegs(portal->start, portal->end);
|
// Hack in the clipsegs to delimit the starting
|
||||||
|
// clipping for sprites and possibly other similar
|
||||||
|
// future items.
|
||||||
|
R_PortalClearClipSegs(portal->start, portal->end);
|
||||||
|
|
||||||
R_PortalRestoreClipValues(portal->start, portal->end, portal->ceilingclip, portal->floorclip, portal->frontscale);
|
// Hack in the top/bottom clip values for the window
|
||||||
|
// that were previously stored.
|
||||||
|
Portal_ClipApply(portal);
|
||||||
|
|
||||||
validcount++;
|
// Render the BSP from the new viewpoint, and clip
|
||||||
|
// any sprites with the new clipsegs and window.
|
||||||
|
R_RenderBSPNode((INT32)numnodes - 1);
|
||||||
|
R_ClipSprites();
|
||||||
|
|
||||||
R_RenderBSPNode((INT32)numnodes - 1);
|
Portal_Remove(portal);
|
||||||
R_ClipSprites();
|
|
||||||
//R_DrawPlanes();
|
validcount++;
|
||||||
//R_DrawMasked();
|
}
|
||||||
|
|
||||||
// okay done. free it.
|
|
||||||
portalcullsector = NULL; // Just in case...
|
portalcullsector = NULL; // Just in case...
|
||||||
portal_base = portal->next;
|
|
||||||
Z_Free(portal->ceilingclip);
|
|
||||||
Z_Free(portal->floorclip);
|
|
||||||
Z_Free(portal->frontscale);
|
|
||||||
Z_Free(portal);
|
|
||||||
}
|
}
|
||||||
// END PORTAL RENDERING
|
|
||||||
|
|
||||||
R_DrawPlanes();
|
R_DrawPlanes();
|
||||||
#ifdef FLOORSPLATS
|
#ifdef FLOORSPLATS
|
||||||
|
|
|
@ -112,50 +112,6 @@ void R_InitPlanes(void)
|
||||||
// FIXME: unused
|
// FIXME: unused
|
||||||
}
|
}
|
||||||
|
|
||||||
// R_PortalStoreClipValues
|
|
||||||
// Saves clipping values for later. -Red
|
|
||||||
void R_PortalStoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale)
|
|
||||||
{
|
|
||||||
INT32 i;
|
|
||||||
for (i = 0; i < end-start; i++)
|
|
||||||
{
|
|
||||||
*ceil = ceilingclip[start+i];
|
|
||||||
ceil++;
|
|
||||||
*floor = floorclip[start+i];
|
|
||||||
floor++;
|
|
||||||
*scale = frontscale[start+i];
|
|
||||||
scale++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// R_PortalRestoreClipValues
|
|
||||||
// Inverse of the above. Restores the old value!
|
|
||||||
void R_PortalRestoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale)
|
|
||||||
{
|
|
||||||
INT32 i;
|
|
||||||
for (i = 0; i < end-start; i++)
|
|
||||||
{
|
|
||||||
ceilingclip[start+i] = *ceil;
|
|
||||||
ceil++;
|
|
||||||
floorclip[start+i] = *floor;
|
|
||||||
floor++;
|
|
||||||
frontscale[start+i] = *scale;
|
|
||||||
scale++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// HACKS FOLLOW
|
|
||||||
for (i = 0; i < start; i++)
|
|
||||||
{
|
|
||||||
floorclip[i] = -1;
|
|
||||||
ceilingclip[i] = (INT16)viewheight;
|
|
||||||
}
|
|
||||||
for (i = end; i < vid.width; i++)
|
|
||||||
{
|
|
||||||
floorclip[i] = -1;
|
|
||||||
ceilingclip[i] = (INT16)viewheight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// R_MapPlane
|
// R_MapPlane
|
||||||
//
|
//
|
||||||
|
|
|
@ -72,8 +72,6 @@ extern fixed_t *yslope;
|
||||||
extern lighttable_t **planezlight;
|
extern lighttable_t **planezlight;
|
||||||
|
|
||||||
void R_InitPlanes(void);
|
void R_InitPlanes(void);
|
||||||
void R_PortalStoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale);
|
|
||||||
void R_PortalRestoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale);
|
|
||||||
void R_ClearPlanes(void);
|
void R_ClearPlanes(void);
|
||||||
|
|
||||||
void R_MapPlane(INT32 y, INT32 x1, INT32 x2);
|
void R_MapPlane(INT32 y, INT32 x1, INT32 x2);
|
||||||
|
|
|
@ -0,0 +1,187 @@
|
||||||
|
// SONIC ROBO BLAST 2
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||||
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
|
// Copyright (C) 1999-2018 by Sonic Team Junior.
|
||||||
|
//
|
||||||
|
// This program is free software distributed under the
|
||||||
|
// terms of the GNU General Public License, version 2.
|
||||||
|
// See the 'LICENSE' file for more details.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// \file r_portal.c
|
||||||
|
/// \brief Software renderer portals.
|
||||||
|
|
||||||
|
#include "r_portal.h"
|
||||||
|
#include "r_plane.h"
|
||||||
|
#include "r_main.h" // viewheight, viewwidth
|
||||||
|
#include "z_zone.h"
|
||||||
|
|
||||||
|
UINT8 portalrender; /**< When rendering a portal, it establishes the depth of the current BSP traversal. */
|
||||||
|
sector_t *portalcullsector;
|
||||||
|
|
||||||
|
// Linked list for portals.
|
||||||
|
portal_t *portal_base, *portal_cap;
|
||||||
|
|
||||||
|
line_t *portalclipline;
|
||||||
|
INT32 portalclipstart, portalclipend;
|
||||||
|
|
||||||
|
boolean portalline; // is curline a portal seg?
|
||||||
|
|
||||||
|
void Portal_InitList (void)
|
||||||
|
{
|
||||||
|
portalrender = 0;
|
||||||
|
portal_base = portal_cap = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Store the clipping window for a portal in its given range.
|
||||||
|
*
|
||||||
|
* The window is copied from the current window at the time
|
||||||
|
* the function is called, so it is useful for converting one-sided
|
||||||
|
* lines into portals.
|
||||||
|
*/
|
||||||
|
void Portal_ClipStoreFromRange (portal_t* portal)
|
||||||
|
{
|
||||||
|
INT32 start = portal->start;
|
||||||
|
INT32 end = portal->end;
|
||||||
|
INT16 *ceil = portal->ceilingclip;
|
||||||
|
INT16 *floor = portal->floorclip;
|
||||||
|
fixed_t *scale = portal->frontscale;
|
||||||
|
|
||||||
|
INT32 i;
|
||||||
|
for (i = 0; i < end-start; i++)
|
||||||
|
{
|
||||||
|
*ceil = ceilingclip[start+i];
|
||||||
|
ceil++;
|
||||||
|
*floor = floorclip[start+i];
|
||||||
|
floor++;
|
||||||
|
*scale = frontscale[start+i];
|
||||||
|
scale++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Apply the clipping window from a portal.
|
||||||
|
*/
|
||||||
|
void Portal_ClipApply (const portal_t* portal)
|
||||||
|
{
|
||||||
|
INT32 i;
|
||||||
|
INT32 start = portal->start;
|
||||||
|
INT32 end = portal->end;
|
||||||
|
INT16 *ceil = portal->ceilingclip;
|
||||||
|
INT16 *floor = portal->floorclip;
|
||||||
|
fixed_t *scale = portal->frontscale;
|
||||||
|
|
||||||
|
for (i = 0; i < end-start; i++)
|
||||||
|
{
|
||||||
|
ceilingclip[start+i] = *ceil;
|
||||||
|
ceil++;
|
||||||
|
floorclip[start+i] = *floor;
|
||||||
|
floor++;
|
||||||
|
frontscale[start+i] = *scale;
|
||||||
|
scale++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// HACKS FOLLOW
|
||||||
|
for (i = 0; i < start; i++)
|
||||||
|
{
|
||||||
|
floorclip[i] = -1;
|
||||||
|
ceilingclip[i] = (INT16)viewheight;
|
||||||
|
}
|
||||||
|
for (i = end; i < vid.width; i++)
|
||||||
|
{
|
||||||
|
floorclip[i] = -1;
|
||||||
|
ceilingclip[i] = (INT16)viewheight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
portal_t* Portal_Add (const INT16 x1, const INT16 x2)
|
||||||
|
{
|
||||||
|
portal_t *portal = Z_Malloc(sizeof(portal_t), PU_LEVEL, NULL);
|
||||||
|
INT16 *ceilingclipsave = Z_Malloc(sizeof(INT16)*(x2-x1), PU_LEVEL, NULL);
|
||||||
|
INT16 *floorclipsave = Z_Malloc(sizeof(INT16)*(x2-x1), PU_LEVEL, NULL);
|
||||||
|
fixed_t *frontscalesave = Z_Malloc(sizeof(fixed_t)*(x2-x1), PU_LEVEL, NULL);
|
||||||
|
|
||||||
|
// Linked list.
|
||||||
|
if (!portal_base)
|
||||||
|
{
|
||||||
|
portal_base = portal;
|
||||||
|
portal_cap = portal;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
portal_cap->next = portal;
|
||||||
|
portal_cap = portal;
|
||||||
|
}
|
||||||
|
portal->next = NULL;
|
||||||
|
|
||||||
|
// Store clipping values so they can be restored once the portal is rendered.
|
||||||
|
portal->ceilingclip = ceilingclipsave;
|
||||||
|
portal->floorclip = floorclipsave;
|
||||||
|
portal->frontscale = frontscalesave;
|
||||||
|
portal->start = x1;
|
||||||
|
portal->end = x2;
|
||||||
|
|
||||||
|
// Increase recursion level.
|
||||||
|
portal->pass = portalrender+1;
|
||||||
|
|
||||||
|
return portal;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Portal_Remove (portal_t* portal)
|
||||||
|
{
|
||||||
|
portal_base = portal->next;
|
||||||
|
Z_Free(portal->ceilingclip);
|
||||||
|
Z_Free(portal->floorclip);
|
||||||
|
Z_Free(portal->frontscale);
|
||||||
|
Z_Free(portal);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Creates a portal out of two lines and a determined screen range.
|
||||||
|
*
|
||||||
|
* line1 determines the entrance, and line2 the exit.
|
||||||
|
* x1 and x2 determine the screen's column bounds.
|
||||||
|
|
||||||
|
* The view's offset from the entry line center is obtained,
|
||||||
|
* and then rotated&translated to the exit line's center.
|
||||||
|
* When the portal renders, it will create the illusion of
|
||||||
|
* the two lines being seamed together.
|
||||||
|
*/
|
||||||
|
void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2)
|
||||||
|
{
|
||||||
|
portal_t* portal = Portal_Add(x1, x2);
|
||||||
|
|
||||||
|
// Offset the portal view by the linedef centers
|
||||||
|
line_t* start = &lines[line1];
|
||||||
|
line_t* dest = &lines[line2];
|
||||||
|
|
||||||
|
angle_t dangle = R_PointToAngle2(0,0,dest->dx,dest->dy) - R_PointToAngle2(start->dx,start->dy,0,0);
|
||||||
|
|
||||||
|
fixed_t disttopoint;
|
||||||
|
angle_t angtopoint;
|
||||||
|
|
||||||
|
vertex_t dest_c, start_c;
|
||||||
|
|
||||||
|
// looking glass center
|
||||||
|
start_c.x = (start->v1->x + start->v2->x) / 2;
|
||||||
|
start_c.y = (start->v1->y + start->v2->y) / 2;
|
||||||
|
|
||||||
|
// other side center
|
||||||
|
dest_c.x = (dest->v1->x + dest->v2->x) / 2;
|
||||||
|
dest_c.y = (dest->v1->y + dest->v2->y) / 2;
|
||||||
|
|
||||||
|
disttopoint = R_PointToDist2(start_c.x, start_c.y, viewx, viewy);
|
||||||
|
angtopoint = R_PointToAngle2(start_c.x, start_c.y, viewx, viewy);
|
||||||
|
angtopoint += dangle;
|
||||||
|
|
||||||
|
portal->viewx = dest_c.x + FixedMul(FINECOSINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
|
||||||
|
portal->viewy = dest_c.y + FixedMul(FINESINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
|
||||||
|
portal->viewz = viewz + dest->frontsector->floorheight - start->frontsector->floorheight;
|
||||||
|
portal->viewangle = viewangle + dangle;
|
||||||
|
|
||||||
|
portal->clipline = line2;
|
||||||
|
|
||||||
|
Portal_ClipStoreFromRange(portal);
|
||||||
|
|
||||||
|
portalline = true; // this tells R_StoreWallRange that curline is a portal seg
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
// SONIC ROBO BLAST 2
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||||
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
|
// Copyright (C) 1999-2018 by Sonic Team Junior.
|
||||||
|
//
|
||||||
|
// This program is free software distributed under the
|
||||||
|
// terms of the GNU General Public License, version 2.
|
||||||
|
// See the 'LICENSE' file for more details.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// \file r_portal.h
|
||||||
|
/// \brief Software renderer portal struct, functions, linked list extern.
|
||||||
|
|
||||||
|
#include "r_data.h"
|
||||||
|
|
||||||
|
|
||||||
|
/** Portal structure.
|
||||||
|
*/
|
||||||
|
typedef struct portal_s
|
||||||
|
{
|
||||||
|
struct portal_s *next;
|
||||||
|
|
||||||
|
// Viewport.
|
||||||
|
fixed_t viewx;
|
||||||
|
fixed_t viewy;
|
||||||
|
fixed_t viewz;
|
||||||
|
angle_t viewangle;
|
||||||
|
|
||||||
|
UINT8 pass; /**< Keeps track of the portal's recursion depth. */
|
||||||
|
INT32 clipline; /**< Optional clipline for line-based portals. */
|
||||||
|
|
||||||
|
// Clipping information.
|
||||||
|
INT32 start; /**< First horizontal pixel coordinate to draw at. */
|
||||||
|
INT32 end; /**< Last horizontal pixel coordinate to draw at. */
|
||||||
|
INT16 *ceilingclip; /**< Temporary screen top clipping array. */
|
||||||
|
INT16 *floorclip; /**< Temporary screen bottom clipping array. */
|
||||||
|
fixed_t *frontscale;/**< Temporary screen bottom clipping array. */
|
||||||
|
} portal_t;
|
||||||
|
|
||||||
|
extern portal_t* portal_base;
|
||||||
|
extern portal_t* portal_cap;
|
||||||
|
extern UINT8 portalrender;
|
||||||
|
|
||||||
|
void Portal_InitList (void);
|
||||||
|
void Portal_Remove (portal_t* portal);
|
||||||
|
void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2);
|
||||||
|
|
||||||
|
void Portal_ClipStoreFromRange (portal_t* portal);
|
||||||
|
void Portal_ClipApply (const portal_t* portal);
|
|
@ -1249,7 +1249,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PORTAL SPRITE CLIPPING
|
// PORTAL SPRITE CLIPPING
|
||||||
if (portalrender)
|
if (portalrender && portalclipline)
|
||||||
{
|
{
|
||||||
if (x2 < portalclipstart || x1 > portalclipend)
|
if (x2 < portalclipstart || x1 > portalclipend)
|
||||||
return;
|
return;
|
||||||
|
@ -1517,7 +1517,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// PORTAL SPRITE CLIPPING
|
// PORTAL SPRITE CLIPPING
|
||||||
if (portalrender)
|
if (portalrender && portalclipline)
|
||||||
{
|
{
|
||||||
if (x2 < portalclipstart || x1 > portalclipend)
|
if (x2 < portalclipstart || x1 > portalclipend)
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in New Issue