mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-01-23 17:51:31 +00:00
Add a hitbox renderer to Software mode
renderhitbox - Tangible - collision activating objects, minus rings - All - every object - Intangible - the opposite of Tangible, also no rings - Rings - rings
This commit is contained in:
parent
e6780f2bee
commit
356bdb25a1
7 changed files with 305 additions and 2 deletions
|
@ -64,6 +64,7 @@ r_skins.c
|
|||
r_sky.c
|
||||
r_splats.c
|
||||
r_things.c
|
||||
r_bbox.c
|
||||
r_textures.c
|
||||
r_patch.c
|
||||
r_patchrotation.c
|
||||
|
|
|
@ -868,6 +868,7 @@ void D_RegisterClientCommands(void)
|
|||
// screen.c
|
||||
CV_RegisterVar(&cv_fullscreen);
|
||||
CV_RegisterVar(&cv_renderview);
|
||||
CV_RegisterVar(&cv_renderhitbox);
|
||||
CV_RegisterVar(&cv_renderer);
|
||||
CV_RegisterVar(&cv_scr_depth);
|
||||
CV_RegisterVar(&cv_scr_width);
|
||||
|
|
|
@ -122,7 +122,7 @@ typedef enum
|
|||
MF_AMBIENT = 1<<10,
|
||||
// Slide this object when it hits a wall.
|
||||
MF_SLIDEME = 1<<11,
|
||||
// Player cheat.
|
||||
// Don't collide with walls or solid objects. Two MF_NOCLIP objects can't touch each other at all!
|
||||
MF_NOCLIP = 1<<12,
|
||||
// Allow moves to any height, no gravity. For active floaters.
|
||||
MF_FLOAT = 1<<13,
|
||||
|
|
290
src/r_bbox.c
Normal file
290
src/r_bbox.c
Normal file
|
@ -0,0 +1,290 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2021 by Sonic Team Junior.
|
||||
// Copyright (C) 2022 by Kart Krew.
|
||||
//
|
||||
// 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_bbox.c
|
||||
/// \brief Boundary box (cube) renderer
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "command.h"
|
||||
#include "r_local.h"
|
||||
#include "screen.h" // cv_renderhitbox
|
||||
#include "v_video.h" // V_DrawFill
|
||||
|
||||
enum {
|
||||
RENDERHITBOX_OFF,
|
||||
RENDERHITBOX_TANGIBLE,
|
||||
RENDERHITBOX_ALL,
|
||||
RENDERHITBOX_INTANGIBLE,
|
||||
RENDERHITBOX_RINGS,
|
||||
};
|
||||
|
||||
static CV_PossibleValue_t renderhitbox_cons_t[] = {
|
||||
{RENDERHITBOX_OFF, "Off"},
|
||||
{RENDERHITBOX_TANGIBLE, "Tangible"},
|
||||
{RENDERHITBOX_ALL, "All"},
|
||||
{RENDERHITBOX_INTANGIBLE, "Intangible"},
|
||||
{RENDERHITBOX_RINGS, "Rings"},
|
||||
{0}};
|
||||
|
||||
consvar_t cv_renderhitbox = CVAR_INIT ("renderhitbox", "Off", 0, renderhitbox_cons_t, NULL);
|
||||
|
||||
struct bbox_col {
|
||||
INT32 x;
|
||||
INT32 y;
|
||||
INT32 h;
|
||||
};
|
||||
|
||||
struct bbox_config {
|
||||
fixed_t height;
|
||||
fixed_t tz;
|
||||
struct bbox_col col[4];
|
||||
UINT8 color;
|
||||
};
|
||||
|
||||
static inline void
|
||||
raster_bbox_seg
|
||||
( INT32 x,
|
||||
fixed_t y,
|
||||
fixed_t h,
|
||||
UINT8 pixel)
|
||||
{
|
||||
y /= FRACUNIT;
|
||||
|
||||
if (y < 0)
|
||||
y = 0;
|
||||
|
||||
h = y + (FixedCeil(abs(h)) / FRACUNIT);
|
||||
|
||||
if (h >= viewheight)
|
||||
h = viewheight;
|
||||
|
||||
while (y < h)
|
||||
{
|
||||
topleft[x + y * vid.width] = pixel;
|
||||
y++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
draw_bbox_col
|
||||
( struct bbox_config * bb,
|
||||
int p,
|
||||
fixed_t tx,
|
||||
fixed_t ty)
|
||||
{
|
||||
struct bbox_col *col = &bb->col[p];
|
||||
|
||||
fixed_t xscale = FixedDiv(projection, ty);
|
||||
fixed_t yscale = FixedDiv(projectiony, ty);
|
||||
|
||||
col->x = (centerxfrac + FixedMul(tx, xscale)) / FRACUNIT;
|
||||
col->y = (centeryfrac - FixedMul(bb->tz, yscale));
|
||||
col->h = FixedMul(bb->height, yscale);
|
||||
|
||||
// Using this function is TOO EASY!
|
||||
V_DrawFill(
|
||||
viewwindowx + col->x,
|
||||
viewwindowy + col->y / FRACUNIT, 1,
|
||||
col->h / FRACUNIT, V_NOSCALESTART | bb->color);
|
||||
}
|
||||
|
||||
static void
|
||||
draw_bbox_row
|
||||
( struct bbox_config * bb,
|
||||
int p1,
|
||||
int p2)
|
||||
{
|
||||
struct bbox_col
|
||||
*a = &bb->col[p1],
|
||||
*b = &bb->col[p2];
|
||||
|
||||
INT32 x1, x2; // left, right
|
||||
INT32 dx; // width
|
||||
|
||||
fixed_t y1, y2; // top, bottom
|
||||
fixed_t s1, s2; // top and bottom increment
|
||||
|
||||
if (a->x > b->x)
|
||||
{
|
||||
struct bbox_col *c = a;
|
||||
a = b;
|
||||
b = c;
|
||||
}
|
||||
|
||||
x1 = a->x;
|
||||
x2 = b->x;
|
||||
|
||||
if (x2 >= viewwidth)
|
||||
x2 = viewwidth - 1;
|
||||
|
||||
if (x1 == x2 || x1 >= viewwidth || x2 < 0)
|
||||
return;
|
||||
|
||||
dx = x2 - x1;
|
||||
|
||||
y1 = a->y;
|
||||
y2 = b->y;
|
||||
s1 = (y2 - y1) / dx;
|
||||
|
||||
y2 = y1 + a->h;
|
||||
s2 = ((b->y + b->h) - y2) / dx;
|
||||
|
||||
// FixedCeil needs a minimum!!! :D :D
|
||||
|
||||
if (s1 == 0)
|
||||
s1 = 1;
|
||||
|
||||
if (s2 == 0)
|
||||
s2 = 1;
|
||||
|
||||
if (x1 < 0)
|
||||
{
|
||||
y1 -= x1 * s1;
|
||||
y2 -= x1 * s2;
|
||||
x1 = 0;
|
||||
}
|
||||
|
||||
while (x1 < x2)
|
||||
{
|
||||
raster_bbox_seg(x1, y1, s1, bb->color);
|
||||
raster_bbox_seg(x1, y2, s2, bb->color);
|
||||
|
||||
y1 += s1;
|
||||
y2 += s2;
|
||||
|
||||
x1++;
|
||||
}
|
||||
}
|
||||
|
||||
static UINT8
|
||||
get_bbox_color (mobj_t *thing)
|
||||
{
|
||||
UINT32 flags = thing->flags;
|
||||
|
||||
if (thing->player)
|
||||
return 255; // 0FF
|
||||
|
||||
if (flags & (MF_NOCLIPTHING))
|
||||
return 7; // BFBFBF
|
||||
|
||||
if (flags & (MF_BOSS|MF_MISSILE|MF_ENEMY|MF_PAIN))
|
||||
return 35; // F00
|
||||
|
||||
if (flags & (MF_SPECIAL|MF_MONITOR))
|
||||
return 73; // FF0
|
||||
|
||||
if (flags & (MF_NOCLIP))
|
||||
return 152; // 00F
|
||||
|
||||
return 0; // FFF
|
||||
}
|
||||
|
||||
void R_DrawThingBoundingBox(mobj_t *thing)
|
||||
{
|
||||
fixed_t rs, rc; // radius offsets
|
||||
fixed_t gx, gy; // origin
|
||||
fixed_t tx, ty; // translated coordinates
|
||||
|
||||
struct bbox_config bb = {0};
|
||||
|
||||
rs = FixedMul(thing->radius, viewsin);
|
||||
rc = FixedMul(thing->radius, viewcos);
|
||||
|
||||
gx = thing->x - viewx;
|
||||
gy = thing->y - viewy;
|
||||
|
||||
tx = FixedMul(gx, viewsin) - FixedMul(gy, viewcos);
|
||||
ty = FixedMul(gx, viewcos) + FixedMul(gy, viewsin);
|
||||
|
||||
bb.height = thing->height;
|
||||
bb.tz = (thing->z + bb.height) - viewz;
|
||||
bb.color = get_bbox_color(thing);
|
||||
|
||||
// 1--3
|
||||
// | |
|
||||
// 0--2
|
||||
|
||||
// left
|
||||
|
||||
tx -= rs;
|
||||
ty -= rc;
|
||||
|
||||
draw_bbox_col(&bb, 0, tx + rc, ty - rs); // bottom
|
||||
draw_bbox_col(&bb, 1, tx - rc, ty + rs); // top
|
||||
|
||||
// right
|
||||
|
||||
tx += rs + rs;
|
||||
ty += rc + rc;
|
||||
|
||||
draw_bbox_col(&bb, 2, tx + rc, ty - rs); // bottom
|
||||
draw_bbox_col(&bb, 3, tx - rc, ty + rs); // top
|
||||
|
||||
// connect all four columns
|
||||
|
||||
draw_bbox_row(&bb, 0, 1);
|
||||
draw_bbox_row(&bb, 1, 3);
|
||||
draw_bbox_row(&bb, 3, 2);
|
||||
draw_bbox_row(&bb, 2, 0);
|
||||
}
|
||||
|
||||
static boolean is_tangible (mobj_t *thing)
|
||||
{
|
||||
// These objects can never touch another
|
||||
if (thing->flags & (MF_NOCLIPTHING))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// These objects probably do nothing! :D
|
||||
if ((thing->flags & (MF_SPECIAL|MF_SOLID|MF_SHOOTABLE
|
||||
|MF_PUSHABLE|MF_BOSS|MF_MISSILE|MF_SPRING
|
||||
|MF_BOUNCE|MF_MONITOR|MF_FIRE|MF_ENEMY
|
||||
|MF_PAIN|MF_STICKY
|
||||
|MF_GRENADEBOUNCE)) == 0U)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean R_ThingBoundingBoxVisible(mobj_t *thing)
|
||||
{
|
||||
INT32 cvmode = cv_renderhitbox.value;
|
||||
|
||||
switch (cvmode)
|
||||
{
|
||||
case RENDERHITBOX_OFF:
|
||||
return false;
|
||||
|
||||
case RENDERHITBOX_ALL:
|
||||
return true;
|
||||
|
||||
case RENDERHITBOX_INTANGIBLE:
|
||||
return !is_tangible(thing);
|
||||
|
||||
case RENDERHITBOX_TANGIBLE:
|
||||
// Exclude rings from here, lots of them!
|
||||
if (thing->type == MT_RING)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return is_tangible(thing);
|
||||
|
||||
case RENDERHITBOX_RINGS:
|
||||
return (thing->type == MT_RING);
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -2939,6 +2939,14 @@ static void R_DrawSprite(vissprite_t *spr)
|
|||
R_DrawFloorSplat(spr);
|
||||
else
|
||||
R_DrawVisSprite(spr);
|
||||
|
||||
if (R_ThingBoundingBoxVisible(spr->mobj))
|
||||
{
|
||||
// fuck you fuck you fuck you FUCK YOU
|
||||
// (shadows are linked to their mobj)
|
||||
if (!(spr->cut & SC_SHADOW))
|
||||
R_DrawThingBoundingBox(spr->mobj);
|
||||
}
|
||||
}
|
||||
|
||||
// Special drawer for precipitation sprites Tails 08-18-2002
|
||||
|
|
|
@ -66,6 +66,9 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel);
|
|||
void R_InitSprites(void);
|
||||
void R_ClearSprites(void);
|
||||
|
||||
boolean R_ThingBoundingBoxVisible(mobj_t *thing);
|
||||
void R_DrawThingBoundingBox(mobj_t *thing);
|
||||
|
||||
boolean R_ThingVisible (mobj_t *thing);
|
||||
|
||||
boolean R_ThingVisibleWithinDist (mobj_t *thing,
|
||||
|
|
|
@ -199,7 +199,7 @@ extern CV_PossibleValue_t cv_renderer_t[];
|
|||
extern INT32 scr_bpp;
|
||||
extern UINT8 *scr_borderpatch; // patch used to fill the view borders
|
||||
|
||||
extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_renderer, cv_fullscreen;
|
||||
extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_renderer, cv_renderhitbox, cv_fullscreen;
|
||||
// wait for page flipping to end or not
|
||||
extern consvar_t cv_vidwait;
|
||||
extern consvar_t cv_timescale;
|
||||
|
|
Loading…
Reference in a new issue