From 04f95ed1d183acf64ea91d425b31e372acf03d1f Mon Sep 17 00:00:00 2001 From: fgsfds Date: Tue, 26 Dec 2023 22:48:28 +0100 Subject: [PATCH] port: net: experimental 8 player support --- port/src/main.c | 4 +-- port/src/pdmain.c | 15 +++----- port/src/preprocess.c | 4 +++ src/game/activemenu.c | 2 +- src/game/activemenutick.c | 2 +- src/game/challenge.c | 10 ++++-- src/game/chraction.c | 4 +-- src/game/filelist.c | 2 +- src/game/filemgr.c | 16 ++++----- src/game/gamefile.c | 8 ++--- src/game/gfxmemory.c | 22 ++++++++++++ src/game/lv.c | 6 ++-- src/game/menu.c | 11 +++--- src/game/menutick.c | 24 +++++++------ src/game/mplayer/mplayer.c | 74 +++++++++++++++++++++----------------- src/game/mplayer/setup.c | 18 +++++----- src/game/pak.c | 14 ++++---- src/game/player.c | 13 +++++++ src/game/playermgr.c | 14 +++++++- src/game/roomreset.c | 10 ++++++ src/game/setup.c | 2 +- src/include/bss.h | 8 ++--- src/include/constants.h | 7 ++-- src/include/data.h | 6 ++-- src/include/game/player.h | 1 + src/include/types.h | 10 +++--- 26 files changed, 191 insertions(+), 116 deletions(-) diff --git a/port/src/main.c b/port/src/main.c index 7f4ec11ee..c6ace0187 100644 --- a/port/src/main.c +++ b/port/src/main.c @@ -66,7 +66,7 @@ static void gameInit(void) { osMemSize = g_OsMemSizeMb * 1024 * 1024; - for (s32 i = 0; i < MAX_PLAYERS; ++i) { + for (s32 i = 0; i < MAX_LOCAL_PLAYERS; ++i) { struct extplayerconfig *cfg = g_PlayerExtCfg + i; cfg->fovzoommult = cfg->fovzoom ? cfg->fovy / 60.0f : 1.0f; } @@ -159,7 +159,7 @@ PD_CONSTRUCTOR static void gameConfigInit(void) configRegisterInt("Game.SkipIntro", &g_SkipIntro, 0, 1); configRegisterInt("Game.DisableMpDeathMusic", &g_MusicDisableMpDeath, 0, 1); configRegisterInt("Game.GEMuzzleFlashes", &g_BgunGeMuzzleFlashes, 0, 1); - for (s32 j = 0; j < MAX_PLAYERS; ++j) { + for (s32 j = 0; j < MAX_LOCAL_PLAYERS; ++j) { const s32 i = j + 1; configRegisterFloat(strFmt("Game.Player%d.FovY", i), &g_PlayerExtCfg[j].fovy, 5.f, 175.f); configRegisterInt(strFmt("Game.Player%d.FovAffectsZoom", i), &g_PlayerExtCfg[j].fovzoom, 0, 1); diff --git a/port/src/pdmain.c b/port/src/pdmain.c index 9d2812748..b0c5e27c4 100644 --- a/port/src/pdmain.c +++ b/port/src/pdmain.c @@ -421,6 +421,9 @@ void mainLoop(void) if (argFindByPrefix(1, "-ma")) { g_MainMemaHeapSize = strtol(argFindByPrefix(1, "-ma"), NULL, 0) * 1024; + if (g_NetMode && g_NetMaxClients > MAX_LOCAL_PLAYERS) { + g_MainMemaHeapSize *= MAX_PLAYERS / MAX_LOCAL_PLAYERS; + } } memaReset(mempAlloc(g_MainMemaHeapSize, MEMPOOL_STAGE), g_MainMemaHeapSize); @@ -470,16 +473,8 @@ void mainLoop(void) && (numplayers >= 2 || g_Vars.lvmpbotlevel || argFindByPrefix(1, "-play"))) { g_MpSetup.chrslots = 1; - if (numplayers >= 2) { - g_MpSetup.chrslots |= 1 << 1; - } - - if (numplayers >= 3) { - g_MpSetup.chrslots |= 1 << 2; - } - - if (numplayers >= 4) { - g_MpSetup.chrslots |= 1 << 3; + for (s32 i = 1; i < numplayers; ++i) { + g_MpSetup.chrslots |= 1 << i; } g_MpSetup.stagenum = g_StageNum; diff --git a/port/src/preprocess.c b/port/src/preprocess.c index 15f54f470..347219980 100644 --- a/port/src/preprocess.c +++ b/port/src/preprocess.c @@ -1042,6 +1042,10 @@ void preprocessMpConfigs(u8 *data, u32 size) PD_SWAP_VAL(cfg->setup.options); PD_SWAP_VAL(cfg->setup.teamscorelimit); PD_SWAP_VAL(cfg->setup.chrslots); +#if MAX_PLAYERS > 4 + // make space for the extra players + cfg->setup.chrslots = (cfg->setup.chrslots & 0x000f) | ((cfg->setup.chrslots & 0x0ff0) << 4); +#endif // TODO: are these required or are they always 0? PD_SWAP_VAL(cfg->setup.fileguid.deviceserial); PD_SWAP_VAL(cfg->setup.fileguid.fileid); diff --git a/src/game/activemenu.c b/src/game/activemenu.c index 52924ab00..e282980f8 100644 --- a/src/game/activemenu.c +++ b/src/game/activemenu.c @@ -26,7 +26,7 @@ #include "data.h" #include "types.h" -struct activemenu g_AmMenus[MAX_PLAYERS]; +struct activemenu g_AmMenus[MAX_LOCAL_PLAYERS]; struct fontchar *g_AmFont1; struct font *g_AmFont2; s32 g_AmIndex; diff --git a/src/game/activemenutick.c b/src/game/activemenutick.c index 570508ea4..d4caf5135 100644 --- a/src/game/activemenutick.c +++ b/src/game/activemenutick.c @@ -22,7 +22,7 @@ void amTick(void) s32 prevplayernum = g_Vars.currentplayernum; s32 i; - for (i = 0; i < PLAYERCOUNT(); i++) { + for (i = 0; i < LOCALPLAYERCOUNT(); i++) { setCurrentPlayerNum(i); g_AmIndex = g_Vars.currentplayernum; diff --git a/src/game/challenge.c b/src/game/challenge.c index ca809ca99..167eae8aa 100644 --- a/src/game/challenge.c +++ b/src/game/challenge.c @@ -136,7 +136,7 @@ void challengeDetermineUnlockedFeatures(void) } // Now same as above, but per player - for (j = 0; j < MAX_PLAYERS; j++) { + for (j = 0; j < MAX_LOCAL_PLAYERS; j++) { numgifted = 0; for (challengeindex = 0; challengeindex < ARRAYCOUNT(g_MpChallenges); challengeindex++) { @@ -197,7 +197,7 @@ void challengeDetermineUnlockedFeatures(void) } for (challengeindex = 0; challengeindex < ARRAYCOUNT(g_MpChallenges); challengeindex++) { - for (prev = 0; prev < MAX_PLAYERS; prev++) { + for (prev = 0; prev < MAX_LOCAL_PLAYERS; prev++) { if (challengeIsAvailableToPlayer(prev, challengeindex)) { for (i = 0; i < ARRAYCOUNT(g_MpChallenges[challengeindex].unlockfeatures); i++) { if (g_MpChallenges[challengeindex].unlockfeatures[i] == j) { @@ -249,7 +249,7 @@ void challengePerformSanityChecks(void) } } - // Turn off all simulants and turn them on if enabled + // Turn off all simulants (and players 5-8 if supported) and turn them on if enabled // for this number of players g_MpSetup.chrslots &= 0x000f; @@ -266,7 +266,11 @@ void challengePerformSanityChecks(void) } } else if (!challengeIsFeatureUnlocked(MPFEATURE_8BOTS)) { // Limit to 4 players and 4 simulants +#if MAX_PLAYERS > 4 + g_MpSetup.chrslots &= 0x0f0f; +#else g_MpSetup.chrslots &= 0x00ff; +#endif } } diff --git a/src/game/chraction.c b/src/game/chraction.c index 926531424..9867ef28b 100644 --- a/src/game/chraction.c +++ b/src/game/chraction.c @@ -15411,7 +15411,7 @@ bool chrMoveToPos(struct chrdata *chr, struct coord *pos, RoomNum *rooms, f32 an bool result = false; u32 nodetype; union modelrwdata *rwdata; - struct player *player; + struct player *player = NULL; f32 ground; pos2.x = pos->x; @@ -15462,7 +15462,7 @@ bool chrMoveToPos(struct chrdata *chr, struct coord *pos, RoomNum *rooms, f32 an } #ifndef PLATFORM_N64 - if (g_NetMode == NETMODE_SERVER && player->isremote) { + if (g_NetMode == NETMODE_SERVER && player && player->isremote) { player->ucmd |= UCMD_FL_FORCEPOS | UCMD_FL_FORCEANGLE | UCMD_FL_FORCEGROUND; } #endif diff --git a/src/game/filelist.c b/src/game/filelist.c index 1cfe79936..cdd85e62e 100644 --- a/src/game/filelist.c +++ b/src/game/filelist.c @@ -24,7 +24,7 @@ s32 g_FilelistKnownPlugCounts[5]; -struct filelist *g_FileLists[MAX_PLAYERS] = { NULL }; +struct filelist *g_FileLists[MAX_LOCAL_PLAYERS] = { NULL }; bool var80075bd0[] = { true, true, true, true }; bool var80075be0[] = { false, false, false, false }; u32 var80075bf0 = false; diff --git a/src/game/filemgr.c b/src/game/filemgr.c index 6d7184cf1..a5f904bfe 100644 --- a/src/game/filemgr.c +++ b/src/game/filemgr.c @@ -25,7 +25,7 @@ struct fileguid g_FilemgrFileToCopy; struct fileguid var800a21e8; #if VERSION >= VERSION_JPN_FINAL -struct fileguid g_FilemgrFileToDelete[MAX_PLAYERS]; +struct fileguid g_FilemgrFileToDelete[MAX_LOCAL_PLAYERS]; #else struct fileguid g_FilemgrFileToDelete; #endif @@ -986,7 +986,7 @@ void filemgrDeleteCurrentFile(void) filemgrPushErrorDialog(FILEERROR_DELETEFAILED); } else { // If deleting a loaded MP player, reset them to default - for (i = 0; i < MAX_PLAYERS; i++) { + for (i = 0; i < MAX_LOCAL_PLAYERS; i++) { if (g_FilemgrFileToDelete[g_MpPlayerNum].fileid == g_PlayerConfigsArray[i].fileguid.fileid && g_FilemgrFileToDelete[g_MpPlayerNum].deviceserial == g_PlayerConfigsArray[i].fileguid.deviceserial) { mpPlayerSetDefaults(i, true); @@ -1013,7 +1013,7 @@ void filemgrDeleteCurrentFile(void) filemgrPushErrorDialog(FILEERROR_DELETEFAILED); } else { // If deleting a loaded MP player, reset them to default - for (i = 0; i < MAX_PLAYERS; i++) { + for (i = 0; i < MAX_LOCAL_PLAYERS; i++) { if (g_FilemgrFileToDelete.fileid == g_PlayerConfigsArray[i].fileguid.fileid && g_FilemgrFileToDelete.deviceserial == g_PlayerConfigsArray[i].fileguid.deviceserial) { mpPlayerSetDefaults(i, true); @@ -1860,7 +1860,7 @@ bool filemgrIsFileInUse(struct filelistfile *file) } } - for (i = 0; i < MAX_PLAYERS; i++) { + for (i = 0; i < MAX_LOCAL_PLAYERS; i++) { if ((g_MpSetup.chrslots & (1 << i)) && g_PlayerConfigsArray[i].fileguid.fileid == file->fileid && g_PlayerConfigsArray[i].fileguid.deviceserial == file->deviceserial) { @@ -1998,7 +1998,7 @@ bool filemgrIsFileInUse(struct filelistfile *file) return true; } - for (i = 0; i < MAX_PLAYERS; i++) { + for (i = 0; i < MAX_LOCAL_PLAYERS; i++) { if ((g_MpSetup.chrslots & (1 << i)) && g_PlayerConfigsArray[i].fileguid.fileid == file->fileid && g_PlayerConfigsArray[i].fileguid.deviceserial == file->deviceserial) { @@ -2436,7 +2436,7 @@ MenuDialogHandlerResult pakChoosePakMenuDialog(s32 operation, struct menudialogd if (g_Vars.stagenum != STAGE_BOOTPAKMENU) { s32 i; - for (i = 0; i < MAX_PLAYERS; i++) { + for (i = 0; i < MAX_LOCAL_PLAYERS; i++) { if (g_Menus[g_MpPlayerNum].fm.unke24 & (1 << i)) { g_Vars.pakstocheck &= 0xfff0; g_Vars.pakstocheck |= 0x0008; @@ -2461,7 +2461,7 @@ MenuDialogHandlerResult pakChoosePakMenuDialog(s32 operation, struct menudialogd { s32 i; - for (i = 0; i < MAX_PLAYERS; i++) { + for (i = 0; i < MAX_LOCAL_PLAYERS; i++) { if (g_Menus[g_MpPlayerNum].fm.unke24 & (1 << i)) { pak0f1169c8(i, STAGE_BOOTPAKMENU == g_Vars.stagenum); } @@ -2773,7 +2773,7 @@ MenuDialogHandlerResult filemgrMainMenuDialog(s32 operation, struct menudialogde mpInit(); // Set MP player names to "Player 1" through 4 if blank - for (i = 0; i < MAX_PLAYERS; i++) { + for (i = 0; i < MAX_LOCAL_PLAYERS; i++) { if (g_PlayerConfigsArray[i].base.name[0] == '\0') { sprintf(g_PlayerConfigsArray[i].base.name, "%s %d\n", langGet(L_MISC_437), i + 1); } diff --git a/src/game/gamefile.c b/src/game/gamefile.c index 3f334ace9..a8a3f8dd6 100644 --- a/src/game/gamefile.c +++ b/src/game/gamefile.c @@ -258,7 +258,7 @@ void gamefileLoadDefaults(struct gamefile *file) } for (i = 0; i < ARRAYCOUNT(g_MpChallenges); i++) { - for (j = 1; j < MAX_PLAYERS + 1; j++) { + for (j = 1; j < MAX_LOCAL_PLAYERS + 1; j++) { challengeSetCompletedByAnyPlayerWithNumPlayers(i, j, false); } } @@ -362,7 +362,7 @@ s32 gamefileLoad(s32 device) } for (i = 0; i < ARRAYCOUNT(g_MpChallenges); i++) { - for (j = 1; j < MAX_PLAYERS + 1; j++) { + for (j = 1; j < MAX_LOCAL_PLAYERS + 1; j++) { challengeSetCompletedByAnyPlayerWithNumPlayers(i, j, savebufferReadBits(&buffer, 1)); } } @@ -539,7 +539,7 @@ s32 gamefileSave(s32 device, s32 fileid, u16 deviceserial) } for (i = 0; i < ARRAYCOUNT(g_MpChallenges); i++) { - for (j = 1; j < MAX_PLAYERS + 1; j++) { + for (j = 1; j < MAX_LOCAL_PLAYERS + 1; j++) { savebufferOr(&buffer, challengeIsCompletedByAnyPlayerWithNumPlayers(i, j), 1); } } @@ -602,7 +602,7 @@ void gamefileUnlockEverything(void) // unlock all challenges for (i = 0; i < ARRAYCOUNT(g_MpChallenges); ++i) { - for (j = 0; j < MAX_PLAYERS; ++j) { + for (j = 0; j < MAX_LOCAL_PLAYERS; ++j) { g_MpChallenges[i].completions[j] = 0xff; } } diff --git a/src/game/gfxmemory.c b/src/game/gfxmemory.c index a7d6bb9d6..7bce8d1ac 100644 --- a/src/game/gfxmemory.c +++ b/src/game/gfxmemory.c @@ -47,6 +47,12 @@ u32 g_GfxSizesByPlayerCount[] = { 0x00018000, 0x00020000, 0x00028000, +#ifndef PLATFORM_N64 + 0x00030000, + 0x00038000, + 0x00040000, + 0x00048000, +#endif }; u32 g_VtxSizesByPlayerCount[] = { @@ -54,6 +60,12 @@ u32 g_VtxSizesByPlayerCount[] = { 0x00018000, 0x00020000, 0x00028000, +#ifndef PLATFORM_N64 + 0x00030000, + 0x00038000, + 0x00040000, + 0x00048000, +#endif }; s32 g_GfxNumSwapsPerBuffer[NUM_GFXTASKS] = {0, 1}; @@ -94,11 +106,21 @@ void gfxReset(void) // ******** Extra Amount required = %dK ber buffer\n // ******** Total of %dK (Double Buffered)\n g_GfxSizesByPlayerCount[PLAYERCOUNT() - 1] = gfx + gfxtra; +#ifndef PLATFORM_N64 + if (PLAYERCOUNT() > MAX_LOCAL_PLAYERS) { + g_GfxSizesByPlayerCount[PLAYERCOUNT() - 1] *= MAX_PLAYERS / MAX_LOCAL_PLAYERS; + } +#endif } if (argFindByPrefix(1, "-mvtx")) { // Argument specified mtxvtx_size\n g_VtxSizesByPlayerCount[PLAYERCOUNT() - 1] = strtol(argFindByPrefix(1, "-mvtx"), NULL, 0) * 1024; +#ifndef PLATFORM_N64 + if (PLAYERCOUNT() > MAX_LOCAL_PLAYERS) { + g_VtxSizesByPlayerCount[PLAYERCOUNT() - 1] *= MAX_PLAYERS / MAX_LOCAL_PLAYERS; + } +#endif } // %d Players : Allocating %d bytes for master dl's\n diff --git a/src/game/lv.c b/src/game/lv.c index 192223358..5d8025a51 100644 --- a/src/game/lv.c +++ b/src/game/lv.c @@ -345,8 +345,8 @@ void lvReset(s32 stagenum) if (g_Vars.mplayerisrunning == false) { g_Vars.playerstats[0].mpindex = 4; - g_PlayerConfigsArray[4].contpad1 = 0; - g_PlayerConfigsArray[4].contpad2 = 1; + g_PlayerConfigsArray[MAX_PLAYERS].contpad1 = 0; + g_PlayerConfigsArray[MAX_PLAYERS].contpad2 = 1; } for (i = 0; i != ARRAYCOUNT(g_Vars.playerstats); i++) { @@ -1695,7 +1695,7 @@ Gfx *lvRender(Gfx *gdl) artifactsTick(); #ifndef PLATFORM_N64 - if (g_NetMode && i) { + if ((g_NetMode && i) || i > MAX_LOCAL_PLAYERS) { gdl = savedgdl; } #endif diff --git a/src/game/menu.c b/src/game/menu.c index a824b849a..9851b4bdf 100644 --- a/src/game/menu.c +++ b/src/game/menu.c @@ -71,7 +71,7 @@ u32 var8009dfc4; struct briefing g_Briefing; u32 var8009dfe4; struct missionconfig g_MissionConfig; -struct menu g_Menus[MAX_PLAYERS]; +struct menu g_Menus[MAX_LOCAL_PLAYERS]; struct menudata g_MenuData; s32 g_MenuScissorX1; s32 g_MenuScissorX2; @@ -3437,7 +3437,7 @@ void menuClose(void) void func0f0f8120(void) { #ifdef AVOID_UB - u32 mpindex = g_MpPlayerNum % MAX_PLAYERS; + u32 mpindex = g_MpPlayerNum % MAX_LOCAL_PLAYERS; struct menudialog *prev = g_Menus[mpindex].curdialog; s32 i; #else @@ -3452,9 +3452,6 @@ void func0f0f8120(void) } #ifdef AVOID_UB - mpindex = g_MpPlayerNum; - if (mpindex >= MAX_PLAYERS) - mpindex -= MAX_PLAYERS; if (g_Menus[mpindex].curdialog == prev) { while (g_Menus[mpindex].depth > 0) { menuPopDialog(); @@ -5346,7 +5343,7 @@ Gfx *menuRender(Gfx *gdl) } else { s32 i; - for (i = 0; i < MAX_PLAYERS; i++) { + for (i = 0; i < MAX_LOCAL_PLAYERS; i++) { g_MpPlayerNum = i; gdl = menuRenderDialogs(gdl); } @@ -5392,7 +5389,7 @@ Gfx *menuRender(Gfx *gdl) gdl = textRenderProjected(gdl, &x, &y, text, g_CharsHandelGothicSm, g_FontHandelGothicSm, colour, viGetWidth(), viGetHeight(), 0, 0); } else #endif - for (i = 0; i < MAX_PLAYERS; i++) { + for (i = 0; i < MAX_LOCAL_PLAYERS; i++) { // Figure out what text will be displayed. The text calculated // here is for measuring purposes only and isn't rendered. // Amusingly, there's a %d placeholder in the text which isn't diff --git a/src/game/menutick.c b/src/game/menutick.c index 74c2e1de9..73e19ee13 100644 --- a/src/game/menutick.c +++ b/src/game/menutick.c @@ -233,7 +233,7 @@ void menuTick(void) g_Vars.mpsetupmenu = MPSETUPMENU_GENERAL; } - for (i = 0; i < MAX_PLAYERS; i++) { + for (i = 0; i < MAX_LOCAL_PLAYERS; i++) { g_Vars.waitingtojoin[i] = false; if (g_MpSetup.chrslots & (1 << i)) { @@ -302,7 +302,11 @@ void menuTick(void) if (g_MenuData.root == MENUROOT_MPSETUP || g_MenuData.root == MENUROOT_4MBMAINMENU) { if (g_MenuData.unk008 == -1) { +#if MAX_PLAYERS > 4 + g_MpSetup.chrslots &= 0xff00; +#else g_MpSetup.chrslots &= 0xfff0; +#endif } g_MpNumJoined = 0; @@ -321,7 +325,7 @@ void menuTick(void) challengePerformSanityChecks(); } - for (i = 0; i < MAX_PLAYERS; i++) { + for (i = 0; i < MAX_LOCAL_PLAYERS; i++) { g_MpPlayerNum = i; if (g_Menus[g_MpPlayerNum].curdialog) { @@ -333,7 +337,7 @@ void menuTick(void) } } - for (i = 0; i < MAX_PLAYERS; i++) { + for (i = 0; i < MAX_LOCAL_PLAYERS; i++) { g_MpPlayerNum = i; if (g_Menus[g_MpPlayerNum].curdialog) { @@ -357,7 +361,7 @@ void menuTick(void) // Limit to 2 players? But in a roundabout kind of way canjoin = true; - for (j = 0; j < MAX_PLAYERS; j++) { + for (j = 0; j < MAX_LOCAL_PLAYERS; j++) { if (g_Vars.waitingtojoin[j]) { canjoin = false; } @@ -550,9 +554,9 @@ void menuTick(void) } #ifdef PLATFORM_N64 - for (i = 0; i < MAX_PLAYERS; i++) { + for (i = 0; i < MAX_LOCAL_PLAYERS; i++) { #else - const s32 maxplayers = g_NetMode ? 1 : MAX_PLAYERS; + const s32 maxplayers = g_NetMode ? 1 : MAX_LOCAL_PLAYERS; for (i = 0; i < maxplayers; i++) { #endif if (g_MpSetup.chrslots & (1 << i)) { @@ -644,12 +648,12 @@ void menuTick(void) } else if (g_Vars.coopplayernum >= 0 || g_Vars.antiplayernum >= 0) { struct mpplayerconfig tmp; - tmp = g_PlayerConfigsArray[4]; - g_PlayerConfigsArray[4] = g_PlayerConfigsArray[0]; + tmp = g_PlayerConfigsArray[MAX_PLAYERS]; + g_PlayerConfigsArray[MAX_PLAYERS] = g_PlayerConfigsArray[0]; g_PlayerConfigsArray[0] = tmp; - tmp = g_PlayerConfigsArray[5]; - g_PlayerConfigsArray[5] = g_PlayerConfigsArray[1]; + tmp = g_PlayerConfigsArray[MAX_PLAYERS + 1]; + g_PlayerConfigsArray[MAX_PLAYERS + 1] = g_PlayerConfigsArray[1]; g_PlayerConfigsArray[1] = tmp; } diff --git a/src/game/mplayer/mplayer.c b/src/game/mplayer/mplayer.c index 4af5823a4..373f35312 100644 --- a/src/game/mplayer/mplayer.c +++ b/src/game/mplayer/mplayer.c @@ -38,7 +38,7 @@ struct mpchrconfig *g_MpAllChrConfigPtrs[MAX_MPCHRS]; s32 g_MpNumChrs; u32 var800ac534; struct mpbotconfig g_BotConfigsArray[MAX_BOTS]; -u8 g_MpSimulantDifficultiesPerNumPlayers[MAX_BOTS][MAX_PLAYERS]; +u8 g_MpSimulantDifficultiesPerNumPlayers[MAX_BOTS][MAX_LOCAL_PLAYERS]; struct mpplayerconfig g_PlayerConfigsArray[MAX_MPPLAYERCONFIGS]; u8 g_AmBotCommands[9]; struct mpsetup g_MpSetup; @@ -128,7 +128,7 @@ struct mpweapon g_MpWeapons[NUM_MPWEAPONS] = { .crosshaircolour = 0x00ff0028, \ } -struct extplayerconfig g_PlayerExtCfg[MAX_PLAYERS] = { +struct extplayerconfig g_PlayerExtCfg[MAX_LOCAL_PLAYERS] = { PLAYER_EXT_CFG_DEFAULT, PLAYER_EXT_CFG_DEFAULT, PLAYER_EXT_CFG_DEFAULT, @@ -182,7 +182,7 @@ void mpStartMatch(void) #ifndef PLATFORM_N64 if (g_NetMode == NETMODE_SERVER) { - g_MpSetup.chrslots &= ~0x000f; + g_MpSetup.chrslots &= 0xff00; g_MpSetup.chrslots |= 1; for (s32 i = 1; i < g_NetMaxClients; ++i) { if (g_NetClients[i].state >= CLSTATE_LOBBY) { @@ -428,7 +428,7 @@ void mpPlayerSetDefaults(s32 playernum, bool autonames) g_PlayerConfigsArray[playernum].controlmode = CONTROLMODE_11; #ifndef PLATFORM_N64 - if (g_PlayerExtCfg[playernum % MAX_PLAYERS].extcontrols) { + if (g_PlayerExtCfg[playernum % MAX_LOCAL_PLAYERS].extcontrols) { g_PlayerConfigsArray[playernum].controlmode = CONTROLMODE_PC; } #endif @@ -496,9 +496,9 @@ void mpPlayerSetDefaults(s32 playernum, bool autonames) g_PlayerConfigsArray[playernum].survivormedals = 0; g_PlayerConfigsArray[playernum].title = MPPLAYERTITLE_BEGINNER; - if (playernum < MAX_PLAYERS) { + if (playernum < MAX_LOCAL_PLAYERS) { for (i = 0; i < ARRAYCOUNT(g_MpChallenges); i++) { - for (j = 1; j <= MAX_PLAYERS; j++) { + for (j = 1; j <= MAX_LOCAL_PLAYERS; j++) { challengeSetCompletedByPlayerWithNumPlayers(playernum, i, j, false); } } @@ -2626,10 +2626,10 @@ void mpFindUnusedHeadAndBody(u8 *mpheadnum, u8 *mpbodynum) s32 mpChooseRandomLockPlayer(void) { - s32 start = random() % 4; + s32 start = random() % MAX_PLAYERS; s32 i; - for (i = (start + 1) % 4;; i = (i + 1) % 4) { + for (i = (start + 1) % MAX_PLAYERS;; i = (i + 1) % MAX_PLAYERS) { if ((g_MpSetup.chrslots & (1 << i)) || i == start) { break; } @@ -3069,11 +3069,11 @@ void mpCreateBotFromProfile(s32 botnum, u8 profilenum) g_BotConfigsArray[botnum].type = g_BotProfiles[profilenum].type; g_BotConfigsArray[botnum].difficulty = g_BotProfiles[profilenum].difficulty; - for (i = 0; i < MAX_PLAYERS; i++) { + for (i = 0; i < MAX_LOCAL_PLAYERS; i++) { g_MpSimulantDifficultiesPerNumPlayers[botnum][i] = g_BotConfigsArray[botnum].difficulty; } - g_MpSetup.chrslots |= 1 << (botnum + 4); + g_MpSetup.chrslots |= 1 << (botnum + MAX_PLAYERS); strcpy(g_BotConfigsArray[botnum].base.name, "Sim\n"); g_BotConfigsArray[botnum].base.team = team; @@ -3102,7 +3102,7 @@ void mpSetBotDifficulty(s32 botnum, s32 difficulty) g_BotConfigsArray[botnum].difficulty = difficulty; - for (i = 0; i < MAX_PLAYERS; i++) { + for (i = 0; i < MAX_LOCAL_PLAYERS; i++) { g_MpSimulantDifficultiesPerNumPlayers[botnum][i] = g_BotConfigsArray[botnum].difficulty; } } @@ -3116,7 +3116,7 @@ s32 mpGetSlotForNewBot(void) { s32 i = 0; - while (i < MAX_BOTS - 1 && g_MpSetup.chrslots & (1 << (i + 4))) { + while (i < MAX_BOTS - 1 && g_MpSetup.chrslots & (1 << (i + MAX_PLAYERS))) { i++; } @@ -3125,7 +3125,7 @@ s32 mpGetSlotForNewBot(void) void mpRemoveSimulant(s32 index) { - g_MpSetup.chrslots &= ~(1 << (index + 4)); + g_MpSetup.chrslots &= ~(1 << (index + MAX_PLAYERS)); g_BotConfigsArray[index].base.name[0] = '\0'; func0f1881d4(index); mpGenerateBotNames(); @@ -3133,7 +3133,11 @@ void mpRemoveSimulant(s32 index) bool mpHasSimulants(void) { +#if MAX_PLAYERS > 4 + if ((g_MpSetup.chrslots & 0xff00) != 0) { +#else if ((g_MpSetup.chrslots & 0xfff0) != 0) { +#endif return true; } @@ -3145,7 +3149,7 @@ bool mpHasUnusedBotSlots(void) s32 numvacant = challengeIsFeatureUnlocked(MPFEATURE_8BOTS) ? MAX_BOTS : 4; s32 i; - for (i = 4; i < MAX_MPCHRS; i++) { + for (i = MAX_PLAYERS; i < MAX_MPCHRS; i++) { if (g_MpSetup.chrslots & (1 << i)) { numvacant--; } @@ -3163,9 +3167,9 @@ bool mpIsSimSlotEnabled(s32 slot) s32 numfree = MAX_BOTS; s32 i; - if ((g_MpSetup.chrslots & (1 << (slot + 4))) == 0) { + if ((g_MpSetup.chrslots & (1 << (slot + MAX_PLAYERS))) == 0) { for (i = 0; i < MAX_BOTS; i++) { - if (g_MpSetup.chrslots & (1 << (i + 4))) { + if (g_MpSetup.chrslots & (1 << (i + MAX_PLAYERS))) { numfree--; } } @@ -3217,9 +3221,9 @@ void mpGenerateBotNames(void) } // Count the number of bots using each profile (MeatSim, TurtleSim etc) - for (i = 4; i < MAX_MPCHRS; i++) { + for (i = MAX_PLAYERS; i < MAX_MPCHRS; i++) { if (g_MpSetup.chrslots & (1 << i)) { - profilenum = mpFindBotProfile(g_BotConfigsArray[i - 4].type, g_BotConfigsArray[i - 4].difficulty); + profilenum = mpFindBotProfile(g_BotConfigsArray[i - MAX_PLAYERS].type, g_BotConfigsArray[i - MAX_PLAYERS].difficulty); if (profilenum >= 0 && profilenum < ARRAYCOUNT(g_BotProfiles)) { counts[profilenum]++; @@ -3238,20 +3242,20 @@ void mpGenerateBotNames(void) } } - for (i = 4; i < MAX_MPCHRS; i++) { + for (i = MAX_PLAYERS; i < MAX_MPCHRS; i++) { if (g_MpSetup.chrslots & (1 << i)) { - profilenum = mpFindBotProfile(g_BotConfigsArray[i - 4].type, g_BotConfigsArray[i - 4].difficulty); + profilenum = mpFindBotProfile(g_BotConfigsArray[i - MAX_PLAYERS].type, g_BotConfigsArray[i - MAX_PLAYERS].difficulty); if (profilenum >= 0 && profilenum < ARRAYCOUNT(g_BotProfiles)) { if (counts[profilenum] >= 0) { // Multiple bots using this profile - append the number counts[profilenum]++; sprintf(name, "%s:%d\n", langGet(g_BotProfiles[profilenum].name), counts[profilenum]); - strcpy(g_BotConfigsArray[i - 4].base.name, name); + strcpy(g_BotConfigsArray[i - MAX_PLAYERS].base.name, name); } else { // One bots using this profile - just use the profile name sprintf(name, "%s\n", langGet(g_BotProfiles[profilenum].name)); - strcpy(g_BotConfigsArray[i - 4].base.name, name); + strcpy(g_BotConfigsArray[i - MAX_PLAYERS].base.name, name); } } } @@ -3422,13 +3426,13 @@ void mpplayerfileLoadWad(s32 playernum, struct savebuffer *buffer, s32 arg2) #ifndef PLATFORM_N64 // override with PC controls if enabled in the config - if (g_PlayerExtCfg[playernum % MAX_PLAYERS].extcontrols) { + if (g_PlayerExtCfg[playernum % MAX_LOCAL_PLAYERS].extcontrols) { g_PlayerConfigsArray[playernum].controlmode = CONTROLMODE_PC; } #endif for (i = 0; i < ARRAYCOUNT(g_MpChallenges); i++) { - for (j = 1; j < MAX_PLAYERS + 1; j++) { + for (j = 1; j < MAX_LOCAL_PLAYERS + 1; j++) { challengeSetCompletedByPlayerWithNumPlayers(playernum, i, j, savebufferReadBits(buffer, 1)); } } @@ -3568,7 +3572,7 @@ void mpplayerfileSaveWad(s32 playernum, struct savebuffer *buffer) savebufferOr(buffer, g_PlayerConfigsArray[playernum].options, 12); for (i = 0; i < ARRAYCOUNT(g_MpChallenges); i++) { - for (j = 1; j < MAX_PLAYERS + 1; j++) { + for (j = 1; j < MAX_LOCAL_PLAYERS + 1; j++) { savebufferOr(buffer, challengeIsCompletedByPlayerWithNumPlayers(playernum, i, j), 1); } } @@ -3757,7 +3761,7 @@ void mpApplyConfig(struct mpconfigfull *config) for (i = 0; i < MAX_BOTS; i++) { g_BotConfigsArray[i].type = config->config.simulants[i].type; - for (j = 0; j < MAX_PLAYERS; j++) { + for (j = 0; j < MAX_LOCAL_PLAYERS; j++) { g_MpSimulantDifficultiesPerNumPlayers[i][j] = config->config.simulants[i].difficulties[j]; } @@ -3814,11 +3818,15 @@ void mp0f18dec4(s32 slot) mpApplyConfig(config); #if VERSION >= VERSION_JPN_FINAL +#if MAX_PLAYERS > 4 + g_MpSetup.chrslots &= 0xff; +#else g_MpSetup.chrslots &= 0x0f; +#endif for (i = 0; i < MAX_BOTS; i++) { if (g_BotConfigsArray[i].difficulty != BOTDIFF_DISABLED) { - g_MpSetup.chrslots |= 1 << (i + 4); + g_MpSetup.chrslots |= 1 << (i + MAX_PLAYERS); } } #endif @@ -3846,12 +3854,12 @@ void mpsetupfileLoadWad(struct savebuffer *buffer) g_BotConfigsArray[i].type = savebufferReadBits(buffer, 5); g_BotConfigsArray[i].difficulty = savebufferReadBits(buffer, 3); - for (j = 0; j < MAX_PLAYERS; j++) { + for (j = 0; j < MAX_LOCAL_PLAYERS; j++) { g_MpSimulantDifficultiesPerNumPlayers[i][j] = g_BotConfigsArray[i].difficulty; } if (g_BotConfigsArray[i].difficulty != BOTDIFF_DISABLED) { - g_MpSetup.chrslots |= 1 << (i + 4); + g_MpSetup.chrslots |= 1 << (i + MAX_PLAYERS); } g_BotConfigsArray[i].base.mpheadnum = savebufferReadBits(buffer, 7); @@ -3871,7 +3879,7 @@ void mpsetupfileLoadWad(struct savebuffer *buffer) g_MpSetup.scorelimit = savebufferReadBits(buffer, 7); g_MpSetup.teamscorelimit = savebufferReadBits(buffer, 9); - for (i = 0; i < MAX_PLAYERS; i++) { + for (i = 0; i < MAX_LOCAL_PLAYERS; i++) { g_PlayerConfigsArray[i].base.team = savebufferReadBits(buffer, 3); } @@ -3887,7 +3895,7 @@ void mpsetupfileSaveWad(struct savebuffer *buffer) func0f0d55a4(buffer, g_MpSetup.name); for (i = 0; i < MAX_BOTS; i++) { - if (g_MpSetup.chrslots & (1 << (i + 4))) { + if (g_MpSetup.chrslots & (1 << (i + MAX_PLAYERS))) { numsims++; } } @@ -3903,7 +3911,7 @@ void mpsetupfileSaveWad(struct savebuffer *buffer) for (i = 0; i < MAX_BOTS; i++) { savebufferOr(buffer, g_BotConfigsArray[i].type, 5); - if (g_MpSetup.chrslots & (1 << (i + 4))) { + if (g_MpSetup.chrslots & (1 << (i + MAX_PLAYERS))) { savebufferOr(buffer, g_BotConfigsArray[i].difficulty, 3); } else { savebufferOr(buffer, BOTDIFF_DISABLED, 3); @@ -3935,7 +3943,7 @@ void mpsetupfileSaveWad(struct savebuffer *buffer) savebufferOr(buffer, g_MpSetup.scorelimit, 7); savebufferOr(buffer, g_MpSetup.teamscorelimit, 9); - for (i = 0; i < MAX_PLAYERS; i++) { + for (i = 0; i < MAX_LOCAL_PLAYERS; i++) { savebufferOr(buffer, g_PlayerConfigsArray[i].base.team, 3); } } diff --git a/src/game/mplayer/setup.c b/src/game/mplayer/setup.c index 87b99860d..f9aed5955 100644 --- a/src/game/mplayer/setup.c +++ b/src/game/mplayer/setup.c @@ -2166,7 +2166,7 @@ MenuItemHandlerResult mpLoadPlayerMenuHandler(s32 operation, struct menuitem *it file = &g_FileLists[0]->files[data->list.value]; available = true; - for (i = 0; i < MAX_PLAYERS; i++) { + for (i = 0; i < MAX_LOCAL_PLAYERS; i++) { if (file->fileid == g_PlayerConfigsArray[i].fileguid.fileid && file->deviceserial == g_PlayerConfigsArray[i].fileguid.deviceserial) { if ((g_MpSetup.chrslots & (1 << i)) == 0) { @@ -2696,7 +2696,7 @@ MenuItemHandlerResult mpAddChangeSimulantMenuHandler(s32 operation, struct menui if (botnum < 0) { botnum = mpGetSlotForNewBot(); creating = 1; - } else if ((g_MpSetup.chrslots & (1 << (botnum + 4))) == 0) { + } else if ((g_MpSetup.chrslots & (1 << (botnum + MAX_PLAYERS))) == 0) { creating = 1; } @@ -2936,7 +2936,7 @@ MenuItemHandlerResult menuhandlerMpSimulantSlot(s32 operation, struct menuitem * case MENUOP_SET: g_Menus[g_MpPlayerNum].mpsetup.slotindex = item->param; - if ((g_MpSetup.chrslots & (1 << (item->param + 4))) == 0) { + if ((g_MpSetup.chrslots & (1 << (item->param + MAX_PLAYERS))) == 0) { menuPushDialog(&g_MpAddSimulantMenuDialog); } else if (IS4MB()) { menuPushDialog(&g_MpEditSimulant4MbMenuDialog); @@ -2962,7 +2962,7 @@ char *mpMenuTextSimulantName(struct menuitem *item) { s32 index = item->param; - if (g_BotConfigsArray[index].base.name[0] == '\0' || (g_MpSetup.chrslots & 1 << (index + 4)) == 0) { + if (g_BotConfigsArray[index].base.name[0] == '\0' || (g_MpSetup.chrslots & 1 << (index + MAX_PLAYERS)) == 0) { return ""; } @@ -2974,7 +2974,7 @@ char *func0f17d3dc(struct menuitem *item) s32 index = item->param; if (g_BotConfigsArray[index].base.name[0] == '\0' - || ((g_MpSetup.chrslots & 1 << (index + 4)) == 0)) { + || ((g_MpSetup.chrslots & 1 << (index + MAX_PLAYERS)) == 0)) { return ""; } @@ -3362,7 +3362,7 @@ MenuItemHandlerResult menuhandlerMpHumansVsSimulants(s32 operation, struct menui if (g_MpSetup.chrslots & (1 << i)) { struct mpchrconfig *mpchr = MPCHR(i); - mpchr->team = i < 4 ? 0 : 1; + mpchr->team = i < MAX_PLAYERS ? 0 : 1; } } @@ -3375,7 +3375,7 @@ MenuItemHandlerResult menuhandlerMpHumansVsSimulants(s32 operation, struct menui MenuItemHandlerResult menuhandlerMpHumanSimulantPairs(s32 operation, struct menuitem *item, union handlerdata *data) { if (operation == MENUOP_SET) { - u8 team_ids[4] = {0, 1, 2, 3}; + u8 team_ids[MAX_PLAYERS] = {0, 1, 2, 3, 4, 5, 6, 7}; s32 i; s32 playerindex = 0; s32 simindex = 0; @@ -3384,7 +3384,7 @@ MenuItemHandlerResult menuhandlerMpHumanSimulantPairs(s32 operation, struct menu if (g_MpSetup.chrslots & (1 << i)) { struct mpchrconfig *mpchr = MPCHR(i); - if (i < 4) { + if (i < MAX_PLAYERS) { mpchr->team = team_ids[playerindex++]; } else { mpchr->team = team_ids[simindex++]; @@ -5153,7 +5153,7 @@ void mpCloseDialogsForNewSetup(void) s32 k; // Loop through each player - for (i = 0; i < MAX_PLAYERS; i++) { + for (i = 0; i < MAX_LOCAL_PLAYERS; i++) { g_MpPlayerNum = i; // If they have a menu open diff --git a/src/game/pak.c b/src/game/pak.c index c58b59de3..640108177 100644 --- a/src/game/pak.c +++ b/src/game/pak.c @@ -234,7 +234,7 @@ struct pak g_Paks[5]; // controller paks + EEPROM u32 var800a317c; #endif -OSPfs g_Pfses[MAX_PLAYERS]; +OSPfs g_Pfses[MAX_LOCAL_PLAYERS]; u32 var800a3320; u32 var800a3324; u32 var800a3328; @@ -4421,7 +4421,7 @@ void pak0f11c6d0(void) { s32 i; - for (i = 0; i < MAX_PLAYERS; i++) { + for (i = 0; i < MAX_LOCAL_PLAYERS; i++) { switch (g_Paks[i].state) { case PAKSTATE_PROBE: case PAKSTATE_MEM_DISPATCH: @@ -5437,14 +5437,14 @@ void pakDisableRumbleForAllPlayers(void) s32 i; #if VERSION >= VERSION_NTSC_1_0 - for (i = 0; i < MAX_PLAYERS; i++) { + for (i = 0; i < MAX_LOCAL_PLAYERS; i++) { if (g_Paks[i].type == PAKTYPE_RUMBLE) { g_Paks[i].rumblestate = RUMBLESTATE_DISABLED_STOPPING; joyStopRumble(i, true); } } #else - for (i = 0; i < MAX_PLAYERS; i++) { + for (i = 0; i < MAX_LOCAL_PLAYERS; i++) { pakDisableRumbleForPlayer(i); } #endif @@ -5455,13 +5455,13 @@ void pakEnableRumbleForAllPlayers(void) s32 i; #if VERSION >= VERSION_NTSC_FINAL - for (i = 0; i < MAX_PLAYERS; i++) { + for (i = 0; i < MAX_LOCAL_PLAYERS; i++) { if (g_Paks[i].type == PAKTYPE_RUMBLE && g_Paks[i].rumblestate == RUMBLESTATE_DISABLED_STOPPED) { g_Paks[i].rumblestate = RUMBLESTATE_ENABLING; } } #else - for (i = 0; i < MAX_PLAYERS; i++) { + for (i = 0; i < MAX_LOCAL_PLAYERS; i++) { pakEnableRumbleForPlayer(i); } #endif @@ -5984,7 +5984,7 @@ bool gbpakIsAnyPerfectDark(void) { s8 i; - for (i = 0; i < MAX_PLAYERS; i++) { + for (i = 0; i < MAX_LOCAL_PLAYERS; i++) { if (gbpakIdentifyGame(i) == GBGAME_PD) { return true; } diff --git a/src/game/player.c b/src/game/player.c index ecfcab38e..a5e104a64 100644 --- a/src/game/player.c +++ b/src/game/player.c @@ -5841,3 +5841,16 @@ void player0f0c3320(Mtxf *matrices, s32 count) mtxF2L(&sp40, matrices + i); } } + +#if MAX_PLAYERS > 4 + +s32 playerGetCount(void) +{ + s32 count = 0; + for (s32 i = 0; i < MAX_PLAYERS; ++i) { + count += (g_Vars.players[i] != NULL); + } + return count; +} + +#endif diff --git a/src/game/playermgr.c b/src/game/playermgr.c index 609ecaadb..520b722ab 100644 --- a/src/game/playermgr.c +++ b/src/game/playermgr.c @@ -29,10 +29,16 @@ void playermgrInit(void) void playermgrReset(void) { +#if MAX_PLAYERS > 4 + for (s32 i = 0; i < MAX_PLAYERS; ++i) { + g_Vars.players[i] = NULL; + } +#else g_Vars.players[0] = NULL; g_Vars.players[1] = NULL; g_Vars.players[2] = NULL; g_Vars.players[3] = NULL; +#endif g_Vars.currentplayer = NULL; g_Vars.currentplayerindex = 0; @@ -51,10 +57,16 @@ void playermgrReset(void) void playermgrAllocatePlayers(s32 count) { +#if MAX_PLAYERS > 4 + for (s32 i = 0; i < MAX_PLAYERS; ++i) { + g_Vars.players[i] = NULL; + } +#else g_Vars.players[0] = NULL; g_Vars.players[1] = NULL; g_Vars.players[2] = NULL; g_Vars.players[3] = NULL; +#endif if (count > 0) { s32 i; @@ -600,7 +612,7 @@ void playermgrAllocatePlayer(s32 index) g_Vars.players[index]->introanimnum = 0; g_Vars.players[index]->lastsighton = 0; - for (i = 0; i < MAX_PLAYERS; i++) { + for (i = 0; i < ARRAYCOUNT(g_Vars.players[index]->targetset); i++) { g_Vars.players[index]->targetset[i] = 0; } diff --git a/src/game/roomreset.c b/src/game/roomreset.c index d02e12820..6e343d67c 100644 --- a/src/game/roomreset.c +++ b/src/game/roomreset.c @@ -12,7 +12,17 @@ void roomsReset(void) { s32 i; +#if MAX_PLAYERS > 4 + if (PLAYERCOUNT() > 4) { + g_RoomMtxNumSlots = 400; + } else if (PLAYERCOUNT() > 2) { + g_RoomMtxNumSlots = 200; + } else { + g_RoomMtxNumSlots = 120; + } +#else g_RoomMtxNumSlots = PLAYERCOUNT() >= 2 ? 200 : 120; +#endif g_RoomMtxAges = mempAlloc(ALIGN16(g_RoomMtxNumSlots), MEMPOOL_STAGE); g_RoomMtxLinkedRooms = mempAlloc(ALIGN16(g_RoomMtxNumSlots * sizeof(*g_RoomMtxLinkedRooms)), MEMPOOL_STAGE); diff --git a/src/game/setup.c b/src/game/setup.c index 912284624..d1a773202 100644 --- a/src/game/setup.c +++ b/src/game/setup.c @@ -2073,7 +2073,7 @@ void setupCreateProps(s32 stagenum) slotnum = (slotnum + 1) % maxsimulants; } - if ((g_MpSetup.chrslots & (1 << (slotnum + 4))) + if ((g_MpSetup.chrslots & (1 << (slotnum + MAX_PLAYERS))) && mpIsSimSlotEnabled(slotnum)) { botmgrAllocateBot(chrnum, slotnum); chrnum++; diff --git a/src/include/bss.h b/src/include/bss.h index e07a9d931..6c481f3b8 100644 --- a/src/include/bss.h +++ b/src/include/bss.h @@ -175,9 +175,9 @@ extern u8 *g_BlurBuffer; extern s32 var8009dfc0; extern struct briefing g_Briefing; extern struct missionconfig g_MissionConfig; -extern struct menu g_Menus[MAX_PLAYERS]; +extern struct menu g_Menus[MAX_LOCAL_PLAYERS]; extern struct menudata g_MenuData; -extern struct activemenu g_AmMenus[MAX_PLAYERS]; +extern struct activemenu g_AmMenus[MAX_LOCAL_PLAYERS]; extern s32 g_AmIndex; extern u32 g_CheatsActiveBank0; extern u32 g_CheatsActiveBank1; @@ -196,7 +196,7 @@ extern struct covercandidate *g_CoverCandidates; extern u16 g_NumSpecialCovers; extern u16 *g_SpecialCoverNums; extern struct pak g_Paks[5]; -extern OSPfs g_Pfses[MAX_PLAYERS]; +extern OSPfs g_Pfses[MAX_LOCAL_PLAYERS]; extern u32 g_SkyStageNum; extern bool g_SkyLightningActive; extern struct explosion *g_Explosions; @@ -285,7 +285,7 @@ extern struct chrdata *g_MpAllChrPtrs[MAX_MPCHRS]; extern struct mpchrconfig *g_MpAllChrConfigPtrs[MAX_MPCHRS]; extern s32 g_MpNumChrs; extern struct mpbotconfig g_BotConfigsArray[MAX_BOTS]; -extern u8 g_MpSimulantDifficultiesPerNumPlayers[MAX_BOTS][MAX_PLAYERS]; +extern u8 g_MpSimulantDifficultiesPerNumPlayers[MAX_BOTS][MAX_LOCAL_PLAYERS]; extern struct mpplayerconfig g_PlayerConfigsArray[MAX_MPPLAYERCONFIGS]; extern u8 g_AmBotCommands[9]; extern struct mpsetup g_MpSetup; diff --git a/src/include/constants.h b/src/include/constants.h index 337af44d3..5a514a207 100644 --- a/src/include/constants.h +++ b/src/include/constants.h @@ -23,7 +23,8 @@ #define MAX_MPCHRS (MAX_PLAYERS + MAX_BOTS) #define MAX_MPPLAYERCONFIGS (MAX_PLAYERS + 2) #define MAX_OBJECTIVES 10 -#define MAX_PLAYERS 4 +#define MAX_LOCAL_PLAYERS 4 +#define MAX_PLAYERS 8 #define MAX_PROPSPERROOMCHUNK 7 #define MAX_ROOMPROPLISTCHUNKS 256 #define MAX_SQUADRONS 16 @@ -68,7 +69,9 @@ #define SECSTOTIME60(secs) (secs * 60) #define PFS(device) (device == SAVEDEVICE_GAMEPAK ? NULL : &g_Pfses[device]) -#if MAX_PLAYERS >= 4 +#if MAX_PLAYERS > 4 +#define PLAYERCOUNT() playerGetCount() +#elif MAX_PLAYERS == 4 #define PLAYERCOUNT() ((g_Vars.players[0] ? 1 : 0) + (g_Vars.players[1] ? 1 : 0) + (g_Vars.players[2] ? 1 : 0) + (g_Vars.players[3] ? 1 : 0)) #elif MAX_PLAYERS >= 3 #define PLAYERCOUNT() ((g_Vars.players[0] ? 1 : 0) + (g_Vars.players[1] ? 1 : 0) + (g_Vars.players[2] ? 1 : 0)) diff --git a/src/include/data.h b/src/include/data.h index 7797182ca..47107df9f 100644 --- a/src/include/data.h +++ b/src/include/data.h @@ -304,7 +304,7 @@ extern struct menudialogdef g_MpConfirmChallenge4MbMenuDialog; extern struct menudialogdef g_MainMenu4MbMenuDialog; extern struct menudialogdef g_MpEditSimulant4MbMenuDialog; extern struct menudialogdef g_AdvancedSetup4MbMenuDialog; -extern struct filelist *g_FileLists[MAX_PLAYERS]; +extern struct filelist *g_FileLists[MAX_LOCAL_PLAYERS]; extern bool var80075bd0[]; extern struct headanim g_HeadAnims[2]; extern s32 var80075d60; @@ -532,7 +532,7 @@ extern struct menudialogdef g_HangarListMenuDialog; #ifndef PLATFORM_N64 -extern struct extplayerconfig g_PlayerExtCfg[MAX_PLAYERS]; +extern struct extplayerconfig g_PlayerExtCfg[MAX_LOCAL_PLAYERS]; extern struct weathercfg g_WeatherConfig[WEATHERCFG_MAX_STAGES]; extern const struct weathercfg g_DefaultWeatherConfig; @@ -559,6 +559,8 @@ extern s32 g_NetMode; #define TEX_FILTER_2D g_TexFilter2D #define ADJUST_ZOOM_FOV(x) ((x) * PLAYER_EXTCFG().fovzoommult) +s32 playerGetCount(void); + #else // PLATFORM_N64 #define TEX_FILTER_2D G_TF_BILERP diff --git a/src/include/game/player.h b/src/include/game/player.h index 81840b813..4b2233cc1 100644 --- a/src/include/game/player.h +++ b/src/include/game/player.h @@ -106,5 +106,6 @@ void playerSetCamPropertiesWithRoom(struct coord *pos, struct coord *up, struct void playerSetCamPropertiesWithoutRoom(struct coord *pos, struct coord *up, struct coord *look, s32 room); void playerSetCamProperties(struct coord *pos, struct coord *up, struct coord *look, s32 room); void playerClearMemCamRoom(void); +s32 playerGetCount(void); #endif diff --git a/src/include/types.h b/src/include/types.h index 5484bb145..0e431051e 100644 --- a/src/include/types.h +++ b/src/include/types.h @@ -230,7 +230,7 @@ struct g_vars { /*0x488*/ s32 totalkills; /*0x48c*/ bool useperimshoot; /*0x490*/ s32 mpsetupmenu; - /*0x494*/ s8 waitingtojoin[MAX_PLAYERS]; + /*0x494*/ s8 waitingtojoin[MAX_LOCAL_PLAYERS]; /*0x498*/ s32 unk000498; /*0x49c*/ bool usingadvsetup; /*0x4a0*/ s32 unk0004a0; @@ -251,7 +251,7 @@ struct g_vars { /*0x4d6*/ s8 autocutfinished; // true if cutscene reached natural end /*0x4d7*/ s8 autocutgroupskip; // true if pressed start during auto cutscene /*0x4d8*/ s32 joydisableframestogo; - /*0x4dc*/ u8 playertojoymap[MAX_PLAYERS]; + /*0x4dc*/ u8 playertojoymap[MAX_LOCAL_PLAYERS]; /*0x4e0*/ u8 fourmeg2player; /*0x4e1*/ u8 remakewallhitvtx; /*0x4e2*/ u8 cutsceneskip60ths; @@ -4162,7 +4162,7 @@ struct challenge { // Same structure as availability, however each byte determines how many // players it was completed with. So completions[0] is for completions with // a single player and completions[3] is for completions with 4 players. - /*0x05*/ u8 completions[MAX_PLAYERS]; + /*0x05*/ u8 completions[MAX_LOCAL_PLAYERS]; // Array of features which will become unlocked once the challenge is // available. The array is automatically populated at runtime based on what @@ -4794,7 +4794,7 @@ struct menudata { /*0x014*/ u8 bg; /*0x015*/ u8 nextbg; /*0x016*/ u8 screenshottimer; - /*0x017*/ u8 playerjoinalpha[MAX_PLAYERS]; + /*0x017*/ u8 playerjoinalpha[MAX_LOCAL_PLAYERS]; /*0x01b*/ s8 bannernum; /*0x01c*/ struct menumodel hudpiece; /*0x5d4*/ u8 unk5d4; @@ -5007,7 +5007,7 @@ struct mpconfigsim { u8 mpheadnum; u8 mpbodynum; u8 team; - u8 difficulties[MAX_PLAYERS]; + u8 difficulties[MAX_LOCAL_PLAYERS]; }; struct mpconfig {