3 Commits
Author SHA1 Message Date
popux 6d63e12034 Gyro fix 2026-10-23 15:32:44 +02:00
popux 23ce248dce Look ahead 2026-10-23 10:36:39 +02:00
popux fa7ef3df64 Corpses 2026-10-22 13:09:06 +02:00
9 changed files with 132 additions and 16 deletions

No files matched your search

+2
View File
@@ -170,6 +170,8 @@ PD_CONSTRUCTOR static void gameConfigInit(void)
configRegisterInt("Game.DisableMpDeathMusic", &g_MusicDisableMpDeath, 0, 1);
configRegisterInt("Game.GEMuzzleFlashes", &g_BgunGeMuzzleFlashes, 0, 1);
configRegisterInt("Game.MaxExplosions", &g_MaxExplosions, 6, 96);
configRegisterInt("Game.DecalLimitMultiplier", &g_DecalLimitMultiplier, 1, MAX_DECAL_LIMIT_MULTIPLIER);
configRegisterInt("Game.MaxCorpses", &g_MaxCorpses, -1, MAX_CORPSES_LIMIT); // -1 = never fade
for (s32 j = 0; j < MAX_PLAYERS; ++j) {
const s32 i = j + 1;
configRegisterFloat(strFmt("Game.Player%d.FovY", i), &g_PlayerExtCfg[j].fovy, 5.f, 175.f);
+28
View File
@@ -1833,7 +1833,12 @@ void bmoveProcessInput(bool allowc1x, bool allowc1y, bool allowc1buttons, bool i
}
}
#ifdef PLATFORM_N64
if (controlmode == CONTROLMODE_12 || controlmode == CONTROLMODE_14 || controlmode == CONTROLMODE_PC) {
#else
// The PC controls walk with an analog stick like 1.1, so look ahead works there (see below)
if (controlmode == CONTROLMODE_12 || controlmode == CONTROLMODE_14) {
#endif
movedata.disablelookahead = true;
}
} // end 1.x
@@ -1992,6 +1997,22 @@ void bmoveProcessInput(bool allowc1x, bool allowc1y, bool allowc1buttons, bool i
lookahead = g_Vars.currentplayer->cachedlookahead;
}
#ifndef PLATFORM_N64
// PC controls pitch with the right stick or mouse (natural pitch), which the N64 code never
// treats as manual pitch. Do what C-up/C-down does: stop the centring until the next walk,
// or until the walk stops if already walking.
// A deliberate stick deflection only: a resting stick can drift past the small dead zone
if (controlmode == CONTROLMODE_PC
&& (movedata.analogpitch > 15 || movedata.analogpitch < -15 || movedata.freelookdy != 0.0f)) {
g_Vars.currentplayer->docentreupdown = false;
g_Vars.currentplayer->automovecentre = false;
if (movedata.canlookahead && (movedata.analogwalk > 60 || movedata.analogwalk < -60)) {
g_Vars.currentplayer->movecentrerelease = true;
}
}
#endif
if (g_Vars.currentplayer->movecentrerelease
&& movedata.analogwalk < 40 && movedata.analogwalk > -40) {
g_Vars.currentplayer->movecentrerelease = false;
@@ -2241,6 +2262,13 @@ void bmoveProcessInput(bool allowc1x, bool allowc1y, bool allowc1buttons, bool i
y = (y < -1.f) ? -1.f : ((y > 1.f) ? 1.f : y);
g_Vars.currentplayer->swivelpos[0] = x;
g_Vars.currentplayer->swivelpos[1] = y;
// The stick still offsets the crosshair, as in the stick-only path below, so gyro (sent as mouse)
// and stick aiming combine
x += (movedata.c1stickxraw * 0.65f) / 80.0f;
y += (movedata.c1stickyraw * 0.65f) / 80.0f;
x = (x < -1.f) ? -1.f : ((x > 1.f) ? 1.f : x);
y = (y < -1.f) ? -1.f : ((y > 1.f) ? 1.f : y);
bgunSwivelWithDamp(x, y, 0.01f);
return;
}
+13
View File
@@ -2633,6 +2633,19 @@ s32 chrTick(struct prop *prop)
}
#if VERSION >= VERSION_NTSC_1_0
#ifndef PLATFORM_N64
if (g_MaxCorpses != 0 && !g_Vars.normmplayerisrunning && needsupdate) {
// Kept corpses are drawn rather than deleted, and don't count towards the visible chr budget
if (chr->actiontype != ACT_DEAD
&& (chr->actiontype != ACT_DRUGGEDKO || (chr->chrflags & CHRCFLAG_KEEPCORPSEKO))) {
var8009cdb0++;
if (var8009cdb0 > 30) {
needsupdate = false;
}
}
} else
#endif
if (!g_Vars.normmplayerisrunning && needsupdate) {
if (chr->actiontype == ACT_DEAD
|| (chr->actiontype == ACT_DRUGGEDKO && (chr->chrflags & CHRCFLAG_KEEPCORPSEKO) == 0)) {
+35 -8
View File
@@ -7199,7 +7199,14 @@ bool chrTrySurrender(struct chrdata *chr)
bool chrFadeOut(struct chrdata *chr)
{
chrBeginDead(chr);
#ifndef PLATFORM_N64
// Scripted removals still fade when corpses are kept forever
if (chr->actiontype == ACT_DEAD || chr->actiontype == ACT_DRUGGEDKO) {
chr->act_dead.fadenow = true;
}
#else
chrFadeCorpse(chr);
#endif
return true;
}
@@ -8197,6 +8204,12 @@ void chrTickSurrender(struct chrdata *chr)
void chrFadeCorpse(struct chrdata *chr)
{
#ifndef PLATFORM_N64
if (g_MaxCorpses < 0 && chr->aibot == NULL) {
return;
}
#endif
if (chr->actiontype == ACT_DEAD || chr->actiontype == ACT_DRUGGEDKO) {
chr->act_dead.fadenow = true;
}
@@ -8204,6 +8217,12 @@ void chrFadeCorpse(struct chrdata *chr)
void chrFadeCorpseWhenOffScreen(struct chrdata *chr)
{
#ifndef PLATFORM_N64
if (g_MaxCorpses < 0 && chr->aibot == NULL) {
return;
}
#endif
if (chr->actiontype == ACT_DEAD) {
chr->act_dead.fadewheninvis = true;
}
@@ -13459,6 +13478,10 @@ void cutsceneStart(u32 ailistid)
* - Run BG scripts
* - Choose which corpses to fade
*/
// 0 keeps the original corpse limits, -1 never fades corpses, otherwise the number of corpses kept on screen,
// off screen and spawned
s32 g_MaxCorpses = 0;
void chraTickBg(void)
{
s32 i;
@@ -13470,10 +13493,10 @@ void chraTickBg(void)
#if VERSION >= VERSION_NTSC_1_0
s32 spawnslen;
#endif
struct chrdata *onscreen[5];
struct chrdata *offscreen[5];
struct chrdata *onscreen[MAX_CORPSES_LIMIT];
struct chrdata *offscreen[MAX_CORPSES_LIMIT];
#if VERSION >= VERSION_NTSC_1_0
struct chrdata *spawns[10];
struct chrdata *spawns[MAX_CORPSES_LIMIT];
#endif
s32 writeindex;
s32 maxdeadonscreen;
@@ -13599,7 +13622,7 @@ void chraTickBg(void)
spawns[spawnslen] = chr;
spawnslen++;
if (spawnslen >= 10) {
if (spawnslen >= (g_MaxCorpses > 0 ? g_MaxCorpses : 10)) {
writeindex = rngRandom() % spawnslen;
chrFadeCorpse(spawns[writeindex]);
spawns[writeindex] = spawns[spawnslen - 1];
@@ -13620,12 +13643,16 @@ void chraTickBg(void)
// 5 chrs (alive or dead) to keep the number of polygons low.
maxdeadonscreen = 5 - numaliveonscreen;
if (g_MaxCorpses > 0) {
maxdeadonscreen = g_MaxCorpses;
}
// If the game is lagging, take the number of 60ths over 6 since the
// previous frame and reduce the limit by that amount. So if it's been, say,
// 8 60ths since the last frame then the max corpses will be reduced by 2.
// This is why corpses are more likely to fade on screen when you change
// weapons - the lag spike from changing guns triggers a lower corpse limit.
if (g_Vars.lvupdate60 > 6) {
if (g_Vars.lvupdate60 > 6 && g_MaxCorpses == 0) {
maxdeadonscreen = maxdeadonscreen - g_Vars.lvupdate60 + 6;
}
@@ -13651,7 +13678,7 @@ void chraTickBg(void)
#else
// Decide which corpses to fade.
// NTSC Beta implements its engagement counter here.
if (numdeadonscreen) {
if (numdeadonscreen && g_MaxCorpses >= 0) {
numdeadonscreen = 0;
#if VERSION >= VERSION_NTSC_1_0
onscreenlen = 0;
@@ -13690,7 +13717,7 @@ void chraTickBg(void)
onscreen[onscreenlen] = chr;
onscreenlen++;
if (onscreenlen >= (VERSION >= VERSION_NTSC_1_0 ? 2 : 3)) {
if (onscreenlen >= (g_MaxCorpses > 0 ? g_MaxCorpses : (VERSION >= VERSION_NTSC_1_0 ? 2 : 3))) {
writeindex = rngRandom() % onscreenlen;
chrFadeCorpseWhenOffScreen(onscreen[writeindex]);
onscreen[writeindex] = onscreen[onscreenlen - 1];
@@ -13705,7 +13732,7 @@ void chraTickBg(void)
offscreenlen++;
// Allow up to 5 corpses off-screen
if (offscreenlen >= (VERSION >= VERSION_NTSC_1_0 ? 5 : 6)) {
if (offscreenlen >= (g_MaxCorpses > 0 ? g_MaxCorpses : (VERSION >= VERSION_NTSC_1_0 ? 5 : 6))) {
writeindex = rngRandom() % offscreenlen;
if (offscreen[writeindex]->actiontype != ACT_DEAD) {
+22 -8
View File
@@ -111,15 +111,29 @@ void gfxReset(void)
g_VtxSizesByPlayerCount[PLAYERCOUNT() - 1] = strtol(argFindByPrefix(1, "-mvtx"), NULL, 0) * 1024;
}
// %d Players : Allocating %d bytes for master dl's\n
g_GfxBuffers[0] = mempAlloc(g_GfxSizesByPlayerCount[PLAYERCOUNT() - 1] * NUM_GFXTASKS, MEMPOOL_STAGE);
g_GfxBuffers[1] = g_GfxBuffers[0] + g_GfxSizesByPlayerCount[PLAYERCOUNT() - 1];
g_GfxBuffers[2] = g_GfxBuffers[1] + g_GfxSizesByPlayerCount[PLAYERCOUNT() - 1];
{
u32 gfxsize = g_GfxSizesByPlayerCount[PLAYERCOUNT() - 1];
u32 vtxsize = g_VtxSizesByPlayerCount[PLAYERCOUNT() - 1];
// Allocating %d bytes for mtxvtx space\n
g_VtxBuffers[0] = mempAlloc(g_VtxSizesByPlayerCount[PLAYERCOUNT() - 1] * NUM_GFXTASKS, MEMPOOL_STAGE);
g_VtxBuffers[1] = g_VtxBuffers[0] + g_VtxSizesByPlayerCount[PLAYERCOUNT() - 1];
g_VtxBuffers[2] = g_VtxBuffers[1] + g_VtxSizesByPlayerCount[PLAYERCOUNT() - 1];
#ifndef PLATFORM_N64
// Each extra rendered decal needs display list commands and per-frame colours
if (g_DecalLimitMultiplier > 1) {
u32 extradecals = 360 * (g_DecalLimitMultiplier - 1);
gfxsize = ALIGN16(gfxsize + extradecals * 6 * sizeof(Gfx));
vtxsize = ALIGN16(vtxsize + extradecals * 32);
}
#endif
// %d Players : Allocating %d bytes for master dl's\n
g_GfxBuffers[0] = mempAlloc(gfxsize * NUM_GFXTASKS, MEMPOOL_STAGE);
g_GfxBuffers[1] = g_GfxBuffers[0] + gfxsize;
g_GfxBuffers[2] = g_GfxBuffers[1] + gfxsize;
// Allocating %d bytes for mtxvtx space\n
g_VtxBuffers[0] = mempAlloc(vtxsize * NUM_GFXTASKS, MEMPOOL_STAGE);
g_VtxBuffers[1] = g_VtxBuffers[0] + vtxsize;
g_VtxBuffers[2] = g_VtxBuffers[1] + vtxsize;
}
g_GfxActiveBufferIndex = 0;
g_GfxRequestedDisplayList = false;
+14
View File
@@ -1400,6 +1400,14 @@ void setupLoadFiles(s32 stagenum)
numobjs += g_Vars.numaibuddies; // the buddy's weapon
}
#ifndef PLATFORM_N64
// Kept corpses hold on to their slots, so reserve extra ones for spawned chrs and their weapons
if (!g_Vars.normmplayerisrunning) {
numchrs += g_MaxCorpses < 0 ? MAX_CORPSES_LIMIT : g_MaxCorpses;
numobjs += g_MaxCorpses < 0 ? MAX_CORPSES_LIMIT : g_MaxCorpses;
}
#endif
numobjs += setupCountCommandType(OBJTYPE_WEAPON);
numobjs += setupCountCommandType(OBJTYPE_KEY);
numobjs += setupCountCommandType(OBJTYPE_HAT);
@@ -1531,6 +1539,12 @@ void setupCreateProps(s32 stagenum)
numchrs += g_Vars.numaibuddies;
}
#ifndef PLATFORM_N64
if (!g_Vars.normmplayerisrunning) {
numchrs += g_MaxCorpses < 0 ? MAX_CORPSES_LIMIT : g_MaxCorpses;
}
#endif
chrmgrConfigure(numchrs);
} else {
chrmgrConfigure(0);
+14
View File
@@ -20,6 +20,7 @@ u32 var8009cc6c;
s32 g_WallhitsCriticalSpareLimit;
s32 g_WallhitsGoalSpareLimit;
f32 g_WallhitTargetBloodRatio;
s32 g_DecalLimitMultiplier = 1;
/**
* Initialises an array of room numbers and a linked list of structs.
@@ -81,6 +82,19 @@ void wallhitReset(void)
break;
}
#ifndef PLATFORM_N64
if (g_DecalLimitMultiplier > 1) {
g_WallhitsMax *= g_DecalLimitMultiplier;
g_MinPropWallhits *= g_DecalLimitMultiplier;
g_MaxPropWallhits *= g_DecalLimitMultiplier;
g_MinBgWallhitsPerRoom *= g_DecalLimitMultiplier;
g_MaxBgWallhitsPerRoom *= g_DecalLimitMultiplier;
var8009cc6c *= g_DecalLimitMultiplier;
g_WallhitsCriticalSpareLimit *= g_DecalLimitMultiplier;
g_WallhitsGoalSpareLimit *= g_DecalLimitMultiplier;
}
#endif
g_WallhitCountsPerRoom = NULL;
g_WallhitsNumSettled = 0;
g_WallhitsNumFree = 0;
+2
View File
@@ -201,6 +201,8 @@ extern u32 g_SkyStageNum;
extern bool g_SkyLightningActive;
extern struct explosion *g_Explosions;
extern s32 g_MaxExplosions;
extern s32 g_DecalLimitMultiplier;
extern s32 g_MaxCorpses;
extern struct smoke *g_Smokes;
extern s32 g_MaxSmokes;
extern Mtx var800a3448;
+2
View File
@@ -28,6 +28,8 @@
#define MAX_SQUADRONS 16
#define MAX_TEAMS 8
#define MAX_EXPLOSIONS_DEFAULT 6
#define MAX_DECAL_LIMIT_MULTIPLIER 10
#define MAX_CORPSES_LIMIT 64
#define NUM_BOTDIFFS 6
#define NUM_CYCLEABLE_WEAPONS 45