This commit is contained in:
popux committed 2026-10-22 13:08:39 +02:00
1 parent f3b74e9c7c
commit 342e825c73
7 files changed
+140 -1

No files matched your search

+4
View File
@@ -112,6 +112,8 @@ s32 portSkipIntro = 0;
* hook in src/game/bondview2.c currentPlayerSetFadeColour). 0 (default) =
* original damage flash. */
s32 portNoHitFlash = 0;
s32 portDecalLimit = 100; /* Game.DecalLimit: bullet holes / blood splats kept per stage (N64: 100) */
s32 portMaxCorpses = 0; /* Game.MaxCorpses: 0 = bodies fade after dying (N64), -1 = never */
/* v0.4.0 M2 (D373/D379): in-game crosshair on/off + tint
* (gunfire.c gunDrawSight, #ifdef PORT). Default keeps the original
@@ -561,6 +563,8 @@ PD_CONSTRUCTOR static void videoConfigInit(void)
configRegisterFloat("Game.ScreenShakeIntensity", &portScreenShakeScale, 0.0f, 10.0f);
configRegisterInt("Game.SkipIntro", &portSkipIntro, 0, 1);
configRegisterInt("Game.NoHitFlash", &portNoHitFlash, 0, 1);
configRegisterInt("Game.DecalLimit", &portDecalLimit, 100, 2000);
configRegisterInt("Game.MaxCorpses", &portMaxCorpses, -1, 64); /* -1 = never fade */
configRegisterInt("Game.AIWideView", &cfgAIWideView, 0, 1); /* D468 */
configRegisterInt("Video.CrosshairHide", &portCrosshairHide, 0, 1); /* v0.4.0 M2 (D373) */
configRegisterInt("Video.CrosshairPersistent", &cfgCrosshairPersistent, 0, 1); /* D436 */
+107
View File
@@ -887,6 +887,92 @@ void chrlvActorFadeAway(ChrRecord *self)
}
#ifdef PORT
/* Game.MaxCorpses: 0 = original (every body fades once its death animation
* ends), -1 = bodies never fade unless guard slots run low (spawning needs 3
* free). Otherwise bodies stay, and the oldest starts its normal fade once
* there are more than this many. A kept body is marked by allowfade ==
* CORPSE_KEEP, and reaptimer holds its death order. */
#define CORPSE_MIN_FREE_SLOTS 4
#define CORPSE_KEEP (-2)
extern s32 portMaxCorpses;
s32 chrGetNumFree(void);
static s32 s_CorpseSeq = 0;
static void chrlvActorKeepCorpse(ChrRecord *self)
{
if (self->actiontype != ACT_DEAD)
{
chrStopFiring(self);
self->actiontype = ACT_DEAD;
self->act_dead.allowfade = CORPSE_KEEP;
self->act_dead.reaptimer = ++s_CorpseSeq;
self->sleep = 0;
}
}
static void chrlvFadeExcessCorpses(void)
{
for (;;)
{
s32 i;
s32 count = 0;
s32 fading = 0;
bool excess;
ChrRecord *oldest = NULL;
ChrRecord *oldestoffscreen = NULL;
for (i = 0; i < g_NumChrSlots; i++)
{
ChrRecord *chr = &g_ChrSlots[i];
if (chr->model == NULL || chr->prop == NULL || chr->actiontype != ACT_DEAD)
{
continue;
}
if (chr->act_dead.allowfade != CORPSE_KEEP)
{
/* already fading: its slot frees up within 1.5 s */
fading++;
continue;
}
count++;
if (oldest == NULL || chr->act_dead.reaptimer < oldest->act_dead.reaptimer)
{
oldest = chr;
}
if ((chr->prop->flags & PROPFLAG_ONSCREEN) == 0
&& (oldestoffscreen == NULL || chr->act_dead.reaptimer < oldestoffscreen->act_dead.reaptimer))
{
oldestoffscreen = chr;
}
}
if (portMaxCorpses > 0)
{
excess = count > portMaxCorpses;
}
else
{
excess = chrGetNumFree() + fading < CORPSE_MIN_FREE_SLOTS;
}
if (!excess || oldest == NULL)
{
return;
}
/* Prefer one the player can't see; chrlvTickDead starts the fade */
(oldestoffscreen ? oldestoffscreen : oldest)->act_dead.allowfade = -1;
}
}
#endif
/**
* chrStepToSide
@@ -5331,6 +5417,13 @@ void chrlvTickSurrender(ChrRecord *self)
*/
void chrlvTickDead(ChrRecord *self)
{
#ifdef PORT
if (self->act_dead.allowfade == CORPSE_KEEP)
{
return;
}
#endif
if (self->act_init.padding[0] >= 0)
{
self->act_init.padding[0] += g_ClockTimer;
@@ -5502,6 +5595,13 @@ void chrlvTickDie(ChrRecord *self)
return;
}
#ifdef PORT
if (portMaxCorpses != 0)
{
chrlvActorKeepCorpse(self);
}
else
#endif
chrlvActorFadeAway(self);
}
@@ -9618,6 +9718,13 @@ void chrlvAllChrTick(void)
chrlvActionTick(&g_ActiveChrs[i]);
}
#ifdef PORT
if (portMaxCorpses != 0)
{
chrlvFadeExcessCorpses();
}
#endif
g_SeenBondRecentlyGuardCount = 0;
for (i=0; i<max; i++)
+5
View File
@@ -76,6 +76,11 @@ void dynInitMemory(void) {
* targets, so g_VtxBuffers is left alone. */
{
s32 gfxHalf = g_GfxSizesByPlayerCount[getPlayerCount() - 1] * ((s32)sizeof(Gfx) / 8);
extern s32 portDecalLimit;
/* Game.DecalLimit: each impact above the default 100 needs a few more commands */
if (portDecalLimit > 100) {
gfxHalf += (portDecalLimit - 100) * 4 * (s32)sizeof(Gfx);
}
g_GfxBuffers[0] = mempAllocBytesInBank(gfxHalf * 2, MEMPOOL_STAGE);
g_GfxBuffers[1] = (g_GfxBuffers[0] + gfxHalf);
g_GfxBuffers[2] = (g_GfxBuffers[1] + gfxHalf);
+3
View File
@@ -74,6 +74,9 @@ struct Scorch *g_ScorchBuffer;
* cannonically wallhitlist
*/
struct BulletImpact *g_BulletImpactBuffer;
#ifdef PORT
s32 g_BulletImpactBufferLen = BULLET_IMPACT_BUFFER_LEN_DEFAULT;
#endif
// data
//D:80040170
+8 -1
View File
@@ -13,7 +13,14 @@
#define SMOKE_PARTS_LEN 10
#define SCORCH_BUFFER_LEN 20
#define IMPACT_TYPE_LEN 20
#define BULLET_IMPACT_BUFFER_LEN 100
#define BULLET_IMPACT_BUFFER_LEN_DEFAULT 100
#ifdef PORT
/* Game.DecalLimit, latched when the stage's impact buffer is allocated */
extern s32 g_BulletImpactBufferLen;
#define BULLET_IMPACT_BUFFER_LEN g_BulletImpactBufferLen
#else
#define BULLET_IMPACT_BUFFER_LEN BULLET_IMPACT_BUFFER_LEN_DEFAULT
#endif
#define MAX_FLYING_PARTICLES 200
typedef struct s_smoketype {
+6
View File
@@ -57,6 +57,12 @@ void alloc_explosion_smoke_casing_scorch_impact_buffers(void)
}
}
#ifdef PORT
{
extern s32 portDecalLimit;
g_BulletImpactBufferLen = portDecalLimit;
}
#endif
osSyncPrintf("Allocating %d bytes for wallhit data\n", BULLET_IMPACT_BUFFER_LEN * sizeof(struct BulletImpact));
g_BulletImpactBuffer = (struct BulletImpact *)mempAllocBytesInBank(BULLET_IMPACT_BUFFER_LEN * sizeof(struct BulletImpact), MEMPOOL_STAGE);
+7
View File
@@ -28,6 +28,13 @@ void alloc_init_GUARDdata_entries(s32 count)
s32 i;
g_NumChrSlots = count + 10; //special guards?
#ifdef PORT
{
/* Game.MaxCorpses: kept bodies hold their slots; keep room for spawns */
extern s32 portMaxCorpses;
g_NumChrSlots += portMaxCorpses < 0 ? 64 : portMaxCorpses;
}
#endif
g_ChrSlots = mempAllocBytesInBank(align_addr_zero(g_NumChrSlots * sizeof(ChrRecord)), MEMPOOL_STAGE);
for(i = 0; g_NumChrSlots > i; i++)