Merge pull request #596 from rafccq/port-enh-mpsetupfile

Enhanced multiplayer game setup save files
This commit is contained in:
fgsfds authored and GitHub committed 2025-04-27 14:26:39 +02:00
commit 9d2db1a346
27 files changed
+1245 -247

No files matched your search

+1 -5
View File
@@ -138,8 +138,6 @@ void bossfileLoad(void)
g_BossFile.usingmultipletunes = savebufferReadBits(&buffer, 1);
g_AltTitleUnlocked = savebufferReadBits(&buffer, 1);
g_AltTitleEnabled = savebufferReadBits(&buffer, 1);
func0f0d54c4(&buffer);
}
if (failed) {
@@ -168,7 +166,7 @@ void bossfileSave(void)
savebufferOr(&buffer, g_Vars.language, 4);
for (i = 0; i < ARRAYCOUNT(g_BossFile.teamnames); i++) {
func0f0d55a4(&buffer, g_BossFile.teamnames[i]);
savebufferWriteString(&buffer, g_BossFile.teamnames[i]);
}
if (g_BossFile.tracknum == -1) {
@@ -185,8 +183,6 @@ void bossfileSave(void)
savebufferOr(&buffer, g_AltTitleUnlocked, 1);
savebufferOr(&buffer, g_AltTitleEnabled, 1);
func0f0d54c4(&buffer);
fileid = bossfileFindFileId();
if (fileid == 0) {
+3
View File
@@ -400,6 +400,8 @@ struct mpconfigfull *challengeLoadConfig(s32 confignum, u8 *buffer, s32 len)
extern struct mpstrings EXT_SEG _mpstringsSSegmentRomEnd;
extern struct mpstrings EXT_SEG _mpstringsISegmentRomEnd;
extern struct mpconfig g_MpConfigs[];
BTYPE banks[][2] = {
{ (BTYPE)REF_SEG _mpstringsESegmentRomStart, (BTYPE)REF_SEG _mpstringsESegmentRomEnd },
{ (BTYPE)REF_SEG _mpstringsJSegmentRomStart, (BTYPE)REF_SEG _mpstringsJSegmentRomEnd },
@@ -421,6 +423,7 @@ struct mpconfigfull *challengeLoadConfig(s32 confignum, u8 *buffer, s32 len)
bank = banks[language_id][0];
loadedstrings = dmaExecWithAutoAlign(buffer2, bank + confignum * sizeof(struct mpstrings), sizeof(struct mpstrings));
mpconfig->config = g_MpConfigs[confignum];
mpconfig->strings = *loadedstrings;
return mpconfig;
+1 -33
View File
@@ -499,11 +499,6 @@ char *filemgrMenuTextFileType(struct menuitem *item)
case FILEOP_LOAD_GAME:
case FILEOP_READ_GAME:
return langGet(names[0]);
case FILEOP_SAVE_MPSETUP:
case FILEOP_WRITE_MPSETUP:
case FILEOP_LOAD_MPSETUP:
case FILEOP_READ_MPSETUP:
return langGet(names[1]);
case FILEOP_SAVE_MPPLAYER:
case FILEOP_WRITE_MPPLAYER:
case FILEOP_LOAD_MPPLAYER:
@@ -816,12 +811,6 @@ bool filemgrAttemptOperation(s32 device, bool closeonsuccess)
g_Menus[g_MpPlayerNum].fm.fileid,
g_Menus[g_MpPlayerNum].fm.deviceserial);
break;
case FILEOP_SAVE_MPSETUP:
errnum = mpsetupfileSave(device,
g_Menus[g_MpPlayerNum].fm.fileid,
g_Menus[g_MpPlayerNum].fm.deviceserial);
showfilesaved = true;
break;
case FILEOP_WRITE_GAME:
case FILEOP_WRITE_MPSETUP:
case FILEOP_WRITE_MPPLAYER:
@@ -845,11 +834,6 @@ bool filemgrAttemptOperation(s32 device, bool closeonsuccess)
g_Menus[g_MpPlayerNum].fm.fileid,
g_Menus[g_MpPlayerNum].fm.deviceserial);
break;
case FILEOP_LOAD_MPSETUP:
errnum = mpsetupfileLoad(device,
g_Menus[g_MpPlayerNum].fm.fileid,
g_Menus[g_MpPlayerNum].fm.deviceserial);
break;
case FILEOP_READ_GAME:
case FILEOP_READ_MPSETUP:
case FILEOP_READ_MPPLAYER:
@@ -2780,7 +2764,7 @@ MenuDialogHandlerResult filemgrMainMenuDialog(s32 operation, struct menudialogde
g_Menus[g_MpPlayerNum].fm.filetypeplusone = 0;
filelistCreate(0, FILETYPE_GAME);
mpInit();
mpInit(true);
// Set MP player names to "Player 1" through 4 if blank
for (i = 0; i < MAX_PLAYERS; i++) {
@@ -3307,14 +3291,6 @@ struct menuitem g_FilemgrOperationsMenuItems[] = {
0,
filemgrOpenCopyFileMenuHandler,
},
{
MENUITEMTYPE_SELECTABLE,
FILETYPE_MPSETUP,
0,
L_OPTIONS_104, // "Combat Simulator Settings File"
0,
filemgrOpenCopyFileMenuHandler,
},
{
MENUITEMTYPE_SELECTABLE,
FILETYPE_MPPLAYER,
@@ -3347,14 +3323,6 @@ struct menuitem g_FilemgrOperationsMenuItems[] = {
0,
filemgrOpenDeleteFileMenuHandler,
},
{
MENUITEMTYPE_SELECTABLE,
FILETYPE_MPSETUP,
0,
L_OPTIONS_104, // "Combat Simulator Settings File"
0,
filemgrOpenDeleteFileMenuHandler,
},
{
MENUITEMTYPE_SELECTABLE,
FILETYPE_MPPLAYER,
-16
View File
@@ -133,14 +133,6 @@ struct menuitem g_GameFiles4MbMenuItems[] = {
0,
filemgrOpenCopyFileMenuHandler,
},
{
MENUITEMTYPE_SELECTABLE,
1,
0,
L_OPTIONS_104, // "Combat Simulator Settings File"
0,
filemgrOpenCopyFileMenuHandler,
},
{
MENUITEMTYPE_SELECTABLE,
2,
@@ -173,14 +165,6 @@ struct menuitem g_GameFiles4MbMenuItems[] = {
0,
filemgrOpenDeleteFileMenuHandler,
},
{
MENUITEMTYPE_SELECTABLE,
1,
0,
L_OPTIONS_104, // "Combat Simulator Settings File"
0,
filemgrOpenDeleteFileMenuHandler,
},
{
MENUITEMTYPE_SELECTABLE,
2,
+1 -5
View File
@@ -395,8 +395,6 @@ s32 gamefileLoad(s32 device)
frSetWeaponFound(WEAPON_REMOTEMINE);
}
#endif
func0f0d54c4(&buffer);
gamefileApplyOptions(&g_GameFile);
return 0;
@@ -499,7 +497,7 @@ s32 gamefileSave(s32 device, s32 fileid, u16 deviceserial)
if (device >= 0) {
savebufferClear(&buffer);
func0f0d55a4(&buffer, g_GameFile.name);
savebufferWriteString(&buffer, g_GameFile.name);
savebufferOr(&buffer, g_GameFile.thumbnail, 5);
savebufferOr(&buffer, g_GameFile.totaltime, 32);
@@ -556,8 +554,6 @@ s32 gamefileSave(s32 device, s32 fileid, u16 deviceserial)
savebufferOr(&buffer, g_GameFile.weaponsfound[i], 8);
}
func0f0d54c4(&buffer);
ret = pakSaveAtGuid(device, fileid, PAKFILETYPE_GAME, buffer.bytes, &newfileid, 0);
g_FilemgrLastPakError = ret;
+13 -3
View File
@@ -614,6 +614,15 @@ Gfx *menuitemListRender(Gfx *gdl, struct menurendercontext *context)
height = 0;
}
// reuse the label color flag here
if (context->item->flags & MENUITEMFLAG_LABEL_CUSTOMCOLOUR) {
u32 savedunk04 = sp15c.list.unk04;
sp15c.list.unk04 = colour;
context->item->handler(MENUOP_GETCOLOUR, context->item, &sp15c);
colour = sp15c.list.unk04;
sp15c.list.unk04 = savedunk04;
}
gdl = textRenderProjected(gdl, &x, &y, text2, chars, font, colour, context->width - left + context->x, height, sp128, 0);
// Consider a checkbox
@@ -1520,6 +1529,7 @@ bool menuitemKeyboardTick(struct menuitem *item, struct menuinputs *inputs, u32
inputs->start = false;
}
u8 maxlen = item->param == 0 ? 10 : item->param;
#ifndef PLATFORM_N64
if (g_MenuKeyboardPlayer == g_MpPlayerNum) {
// match caps state to keyboard shift/caps if typing with keyboard
@@ -1531,7 +1541,7 @@ bool menuitemKeyboardTick(struct menuitem *item, struct menuinputs *inputs, u32
// handle text input
s32 prevpos = strlen(kb->string);
s32 pos = prevpos;
s32 result = inputTextHandler(kb->string, sizeof(kb->string), &pos, true);
s32 result = inputTextHandler(kb->string, maxlen-1, &pos, true);
if (result == -1) {
// cancel
kb->row = 5;
@@ -1608,7 +1618,7 @@ bool menuitemKeyboardTick(struct menuitem *item, struct menuinputs *inputs, u32
s32 textwidth;
s32 textheight;
if (kb->string[9] == '\0') {
if (kb->string[maxlen-1] == '\0') {
// String is not full
i = 0;
@@ -1644,7 +1654,7 @@ bool menuitemKeyboardTick(struct menuitem *item, struct menuinputs *inputs, u32
// Handle deleting
if (delete && kb->string[0] != '\0') {
s32 deleted = false;
s32 i = 10;
s32 i = maxlen;
menuPlaySound(MENUSOUND_FOCUS);
-1
View File
@@ -473,7 +473,6 @@ void menuTick(void)
(g_MenuData.root == MENUROOT_MPSETUP || g_MenuData.root == MENUROOT_4MBMAINMENU)) {
var80062948 = 1;
filelistCreate(0, FILETYPE_MPPLAYER);
filelistCreate(1, FILETYPE_MPSETUP);
}
if (var80062944) {
File renamed without changes.
+74 -79
View File
@@ -28,6 +28,9 @@
#include "lib/lib_317f0.h"
#include "data.h"
#include "types.h"
#include "fs.h"
#include "system.h"
#include "mpsetups.h"
// bss
struct chrdata *g_MpAllChrPtrs[MAX_MPCHRS];
@@ -515,12 +518,6 @@ void mpPlayerSetDefaults(s32 playernum, bool autonames)
for (i = 0; i < ARRAYCOUNT(g_PlayerConfigsArray); i++) {
g_PlayerConfigsArray[playernum].gunfuncs[i] = 0;
}
#ifndef PLATFORM_N64
for (i = 0; i < ARRAYCOUNT(g_MpWeapons); i++) {
g_MpWeaponSetRandomFilters[i] = 1;
}
#endif
}
void func0f1881d4(s32 index)
@@ -532,7 +529,7 @@ void func0f1881d4(s32 index)
g_BotConfigsArray[index].difficulty = BOTDIFF_DISABLED;
}
void mpInit(void)
void mpInit(bool resetplayers)
{
s32 i;
s32 j;
@@ -565,8 +562,10 @@ void mpInit(void)
strcpy(g_MpSetup.name, "");
for (i = 0; i < ARRAYCOUNT(g_PlayerConfigsArray); i++) {
mpPlayerSetDefaults(i, false);
if (resetplayers) {
for (i = 0; i < ARRAYCOUNT(g_PlayerConfigsArray); i++) {
mpPlayerSetDefaults(i, false);
}
}
for (i = 0; i < MAX_BOTS; i++) {
@@ -599,6 +598,16 @@ void mpInit(void)
}
g_MpSetup.chrslots = 0;
for (i = 0; i < ARRAYCOUNT(g_Menus); i++) {
g_Menus[i].mpsetup.showpresets = 1;
}
#ifndef PLATFORM_N64
for (i = 0; i < ARRAYCOUNT(g_MpWeapons); i++) {
g_MpWeaponSetRandomFilters[i] = 1;
}
#endif
}
#if VERSION >= VERSION_PAL_BETA
@@ -3532,7 +3541,7 @@ void mpplayerfileSaveWad(s32 playernum, struct savebuffer *buffer)
s32 j;
u32 stack;
func0f0d55a4(buffer, g_PlayerConfigsArray[playernum].base.name);
savebufferWriteString(buffer, g_PlayerConfigsArray[playernum].base.name);
if (g_PlayerConfigsArray[playernum].time > 0x0fffffff) { // over 3106 days
g_PlayerConfigsArray[playernum].time = 0x0fffffff;
@@ -3683,8 +3692,6 @@ s32 mpplayerfileSave(s32 playernum, s32 device, s32 fileid, u16 deviceserial)
if (device >= 0) {
savebufferClear(&buffer);
mpplayerfileSaveWad(playernum, &buffer);
func0f0d54c4(&buffer);
var80075bd0[2] = true;
ret = pakSaveAtGuid(device, fileid, PAKFILETYPE_MPPLAYER, buffer.bytes, &newfileid, 0);
@@ -3717,8 +3724,6 @@ s32 mpplayerfileLoad(s32 playernum, s32 device, s32 fileid, u16 deviceserial)
g_PlayerConfigsArray[playernum].fileguid.deviceserial = deviceserial;
mpplayerfileLoadWad(playernum, &buffer, 1);
func0f0d54c4(&buffer);
g_PlayerConfigsArray[playernum].handicap = 0x80;
return 0;
}
@@ -3912,21 +3917,54 @@ void mp0f18dec4(s32 slot)
#endif
}
void mpsetupfileLoadWad(struct savebuffer *buffer)
static u64 packWeaponSetRandomFilters()
{
u64 packed = 0;
for (int i = 0; i < NUM_MPWEAPONS; ++i) {
packed |= g_MpWeaponSetRandomFilters[i] != 0 ? (1LL << i) : 0;
}
return packed;
}
static void unpackWeaponSetRandomFilters(u64 packed)
{
for (int i = 0; i < NUM_MPWEAPONS; ++i) {
g_MpWeaponSetRandomFilters[i] = (packed & (1LL << i)) != 0;
}
}
void mpsetupfileLoadWad(struct savebuffer *buffer, u8 version)
{
s32 i;
s32 j;
savebufferReadString(buffer, g_MpSetup.name, false);
if (version > 0) {
savebufferReadString_ext(buffer, g_MpSetup.name, false, MPSETUP_MAXNAME + 1);
}
else {
savebufferReadString(buffer, g_MpSetup.name, false);
}
savebufferReadBits(buffer, 4);
g_MpSetup.stagenum = savebufferReadBits(buffer, 7);
g_MpSetup.scenario = savebufferReadBits(buffer, 3);
scenarioInit();
scenarioReadSave(buffer);
// version == 0 means we're only reading to convert, so no actions are needed
if (version > 0) {
scenarioInit();
}
scenarioReadSave(buffer, version);
if (version > 0) {
g_MpSetup.options = savebufferReadBits(buffer, 32);
}
else {
g_MpSetup.options = savebufferReadBits(buffer, 21);
}
g_MpSetup.options = savebufferReadBits(buffer, 21);
g_MpSetup.chrslots &= 0x000f;
for (i = 0; i < MAX_BOTS; i++) {
@@ -3947,13 +3985,20 @@ void mpsetupfileLoadWad(struct savebuffer *buffer)
g_BotConfigsArray[i].base.team = savebufferReadBits(buffer, 3);
}
mpGenerateBotNames();
if (version > 0) {
mpGenerateBotNames();
}
for (i = 0; i < ARRAYCOUNT(g_MpSetup.weapons); i++) {
g_MpSetup.weapons[i] = savebufferReadBits(buffer, 7);
}
func0f18913c();
if (version > 0) {
u64 wpnRndPacked = savebufferReadBits(buffer, 64);
unpackWeaponSetRandomFilters(wpnRndPacked);
}
g_MpWeaponSetNum = savebufferReadBits(buffer, 8);
g_MpSetup.timelimit = savebufferReadBits(buffer, 6);
g_MpSetup.scorelimit = savebufferReadBits(buffer, 7);
@@ -3972,7 +4017,7 @@ void mpsetupfileSaveWad(struct savebuffer *buffer)
s32 mpbodynum;
s32 i;
func0f0d55a4(buffer, g_MpSetup.name);
savebufferWriteString_ext(buffer, g_MpSetup.name, MPSETUP_MAXNAME + 1);
for (i = 0; i < MAX_BOTS; i++) {
if (g_MpSetup.chrslots & (1 << (i + 4))) {
@@ -3986,7 +4031,7 @@ void mpsetupfileSaveWad(struct savebuffer *buffer)
scenarioWriteSave(buffer);
savebufferOr(buffer, g_MpSetup.options, 21);
savebufferOr(buffer, g_MpSetup.options, 32);
for (i = 0; i < MAX_BOTS; i++) {
savebufferOr(buffer, g_BotConfigsArray[i].type, 5);
@@ -4019,6 +4064,10 @@ void mpsetupfileSaveWad(struct savebuffer *buffer)
savebufferOr(buffer, g_MpSetup.weapons[i], 7);
}
u64 wpnRndPacked = packWeaponSetRandomFilters();
savebufferOr(buffer, wpnRndPacked, 64);
savebufferOr(buffer, g_MpWeaponSetNum, 8);
savebufferOr(buffer, g_MpSetup.timelimit, 6);
savebufferOr(buffer, g_MpSetup.scorelimit, 7);
savebufferOr(buffer, g_MpSetup.teamscorelimit, 9);
@@ -4032,69 +4081,15 @@ void mpsetupfileGetOverview(char *arg0, char *filename, u16 *numsims, u16 *stage
{
struct savebuffer buffer;
savebufferWriteData(&buffer, arg0, 15);
savebufferWriteData(&buffer, arg0, 22);
savebufferReadString(&buffer, filename, 0);
savebufferReadString_ext(&buffer, filename, 0, MPSETUP_MAXNAME+1);
*numsims = savebufferReadBits(&buffer, 4);
*stagenum = savebufferReadBits(&buffer, 7);
*scenarionum = savebufferReadBits(&buffer, 3);
}
s32 mpsetupfileSave(s32 device, s32 fileid, u16 deviceserial)
{
s32 ret;
s32 newfileid;
struct savebuffer buffer;
if (device >= 0) {
savebufferClear(&buffer);
mpsetupfileSaveWad(&buffer);
func0f0d54c4(&buffer);
ret = pakSaveAtGuid(device, fileid, PAKFILETYPE_MPSETUP, buffer.bytes, &newfileid, 0);
var80075bd0[1] = true;
if (ret == 0) {
g_MpSetup.fileguid.fileid = newfileid;
g_MpSetup.fileguid.deviceserial = deviceserial;
return 0;
}
g_FilemgrLastPakError = ret;
return -1;
}
return -1;
}
s32 mpsetupfileLoad(s32 device, s32 fileid, u16 deviceserial)
{
s32 ret;
struct savebuffer buffer;
if (device >= 0) {
savebufferClear(&buffer);
ret = pakReadBodyAtGuid(device, fileid, buffer.bytes, 0);
if (ret == 0) {
g_MpSetup.fileguid.fileid = fileid;
g_MpSetup.fileguid.deviceserial = deviceserial;
mpsetupfileLoadWad(&buffer);
func0f0d54c4(&buffer);
return 0;
}
g_FilemgrLastPakError = ret;
return -1;
}
return -1;
}
void func0f18e558(void)
{
s32 i;
+6 -5
View File
@@ -70,7 +70,7 @@ struct mpscenario {
bool (*isroomhighlightedfunc)(RoomNum room);
void (*highlightroomfunc)(RoomNum room, s32 *arg1, s32 *arg2, s32 *arg3);
void *unk3c; // never hooked into nor fired
void (*readsavefunc)(struct savebuffer *buffer);
void (*readsavefunc)(struct savebuffer *buffer, u8 version);
void (*writesavefunc)(struct savebuffer *buffer);
};
@@ -416,12 +416,13 @@ MenuItemHandlerResult menuhandlerMpOpenOptions(s32 operation, struct menuitem *i
*
* Used by KOH to read the mphilltime.
*/
void scenarioReadSave(struct savebuffer *buffer)
void scenarioReadSave(struct savebuffer *buffer, u8 version)
{
if (g_MpScenarios[g_MpSetup.scenario].readsavefunc) {
g_MpScenarios[g_MpSetup.scenario].readsavefunc(buffer);
g_MpScenarios[g_MpSetup.scenario].readsavefunc(buffer, version);
} else {
savebufferReadBits(buffer, 8);
u8 sz = version > 0 ? 32 : 8;
savebufferReadBits(buffer, sz);
}
}
@@ -438,7 +439,7 @@ void scenarioWriteSave(struct savebuffer *buffer)
if (g_MpScenarios[g_MpSetup.scenario].writesavefunc) {
g_MpScenarios[g_MpSetup.scenario].writesavefunc(buffer);
} else {
savebufferOr(buffer, 0, 8);
savebufferOr(buffer, 0, 32);
}
}
+4 -3
View File
@@ -181,14 +181,15 @@ struct menudialogdef g_KohOptionsMenuDialog = {
NULL,
};
void kohReadSave(struct savebuffer *buffer)
void kohReadSave(struct savebuffer *buffer, u8 version)
{
g_Vars.mphilltime = savebufferReadBits(buffer, 8);
u8 sz = version > 0 ? 32 : 8;
g_Vars.mphilltime = savebufferReadBits(buffer, sz);
}
void kohWriteSave(struct savebuffer *buffer)
{
savebufferOr(buffer, g_Vars.mphilltime, 8);
savebufferOr(buffer, g_Vars.mphilltime, 32);
}
void kohInit(void)
+103 -60
View File
@@ -20,9 +20,13 @@
#include "lib/vi.h"
#include "lib/rng.h"
#include "lib/str.h"
#include "lib/joy.h"
#include "data.h"
#include "gbiex.h"
#include "types.h"
#include "system.h"
#include "input.h"
#include "mpsetups.h"
struct menuitem g_MpCharacterMenuItems[];
struct menudialogdef g_MpAddSimulantMenuDialog;
@@ -31,6 +35,10 @@ struct menudialogdef g_MpChangeTeamNameMenuDialog;
struct menudialogdef g_MpEditSimulantMenuDialog;
struct menudialogdef g_MpSaveSetupNameMenuDialog;
extern struct menudialogdef g_ManageSettingsDialog;
extern struct menudialogdef g_FilemgrFileSavedMenuDialog;
extern struct menudialogdef g_FilemgrErrorMenuDialog;
#ifndef PLATFORM_N64
extern s32 g_MpWeaponSetNum;
#endif
@@ -451,9 +459,11 @@ MenuItemHandlerResult menuhandlerMpConfirmSaveChr(s32 operation, struct menuitem
return 0;
}
extern struct menudialogdef g_StatusErrorDialog;
MenuItemHandlerResult menuhandlerMpSetupName(s32 operation, struct menuitem *item, union handlerdata *data)
{
char *name = data->keyboard.string;
s32 err;
switch (operation) {
case MENUOP_GETTEXT:
@@ -463,7 +473,14 @@ MenuItemHandlerResult menuhandlerMpSetupName(s32 operation, struct menuitem *ite
strcpy(g_MpSetup.name, name);
break;
case MENUOP_SET:
filemgrPushSelectLocationDialog(7, FILETYPE_MPSETUP);
err = mpsetupSaveSetup(g_MpSetupFile.numsetups, true);
if (!err) {
menuPushDialog(&g_FilemgrFileSavedMenuDialog);
g_MpCurrentSetup = g_MpSetupFile.numsetups - 1;
}
else {
menuPushDialog(&g_StatusErrorDialog);
}
break;
}
@@ -474,7 +491,8 @@ MenuItemHandlerResult menuhandlerMpSaveSetupOverwrite(s32 operation, struct menu
{
if (operation == MENUOP_SET) {
menuPopDialog();
filemgrSaveOrLoad(&g_MpSetup.fileguid, FILEOP_SAVE_MPSETUP, 0);
mpsetupSaveSetup(g_MpCurrentSetup, true);
menuPushDialog(&g_FilemgrFileSavedMenuDialog);
}
return 0;
@@ -1075,18 +1093,18 @@ struct menuitem g_MpSaveSetupNameMenuItems[] = {
{
MENUITEMTYPE_LABEL,
0,
MENUITEMFLAG_LESSLEFTPADDING,
L_MPMENU_189, // "Enter a name for your game setup file:"
MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_LESSLEFTPADDING,
(uintptr_t)"Enter the setup name:\n",
0,
NULL,
},
#endif
{
MENUITEMTYPE_KEYBOARD,
MPSETUP_MAXNAME,
0,
0,
0,
0,
1,
menuhandlerMpSetupName,
},
{ MENUITEMTYPE_END },
@@ -1112,10 +1130,10 @@ struct menuitem g_MpSaveSetupExistsMenuItems[] = {
NULL,
},
{
MENUITEMTYPE_LABEL,
MENUITEMTYPE_SEPARATOR,
0,
0,
0,
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_SELECTABLE_CENTRE | MENUITEMFLAG_SMALLFONT,
(uintptr_t)&filemgrMenuTextDeviceName,
0,
NULL,
},
@@ -1123,8 +1141,16 @@ struct menuitem g_MpSaveSetupExistsMenuItems[] = {
{
MENUITEMTYPE_LABEL,
0,
MENUITEMFLAG_LESSLEFTPADDING,
L_MPMENU_184, // "Do you want to save over your original game file?"
MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_LITERAL_TEXT,
(uintptr_t)"Save over your\noriginal setup?\n",
0,
NULL,
},
{
MENUITEMTYPE_SEPARATOR,
0,
0,
0,
0,
NULL,
},
@@ -2232,36 +2258,32 @@ MenuItemHandlerResult mpPlayerNameMenuHandler(s32 operation, struct menuitem *it
MenuItemHandlerResult mpLoadSettingsMenuHandler(s32 operation, struct menuitem *item, union handlerdata *data)
{
u8 presets = g_Menus[g_MpPlayerNum].mpsetup.showpresets;
s32 numpresets = mpGetNumUnlockedPresets()*presets;
switch (operation) {
case MENUOP_GETOPTIONCOUNT:
data->list.value = mpGetNumUnlockedPresets();
if (g_FileLists[1] != NULL) {
data->list.value += g_FileLists[1]->numfiles;
}
data->list.value = numpresets + g_MpSetupFile.numsetups;
break;
case MENUOP_GETOPTIONTEXT:
if (data->list.value < mpGetNumUnlockedPresets()) {
if (presets && data->list.value < mpGetNumUnlockedPresets()) {
return (uintptr_t)mpGetPresetNameBySlot(data->list.value);
}
if (g_FileLists[1] != NULL) {
func0f0d564c(g_FileLists[1]->files[data->list.value - mpGetNumUnlockedPresets()].name, g_StringPointer, false);
if (g_MpSetupFile.numsetups > 0) {
struct setupblock *block = &g_MpSetupFile.setups[data->list.value - numpresets];
func0f0d564c_ext(block->bytes, g_StringPointer, false, MPSETUP_MAXNAME+1);
return (uintptr_t)g_StringPointer;
}
break;
case MENUOP_SET:
mpCloseDialogsForNewSetup();
if (data->list.value < mpGetNumUnlockedPresets()) {
if (presets && data->list.value < mpGetNumUnlockedPresets()) {
mp0f18dec4(data->list.value);
} else if (g_FileLists[1] != NULL) {
struct filelistfile *file = &g_FileLists[1]->files[data->list.value - mpGetNumUnlockedPresets()];
struct fileguid guid;
guid.fileid = file->fileid;
guid.deviceserial = file->deviceserial;
filemgrSaveOrLoad(&guid, FILEOP_LOAD_MPSETUP, 0);
g_MpCurrentSetup = -1;
}
else {
mpsetupLoadSetup(data->list.value - numpresets);
}
if (item->param == 1) {
@@ -2276,36 +2298,22 @@ MenuItemHandlerResult mpLoadSettingsMenuHandler(s32 operation, struct menuitem *
data->list.value = 0xfffff;
break;
case MENUOP_GETOPTGROUPCOUNT:
data->list.value = 1;
if (g_FileLists[1] != NULL) {
data->list.value += g_FileLists[1]->numdevices;
}
data->list.value = presets ? 2 : 1;
break;
case MENUOP_GETOPTGROUPTEXT:
if (data->list.value == 0) {
if (presets && data->list.value == 0) {
return (uintptr_t)langGet(L_MPMENU_141); // "Presets"
}
if (g_FileLists[1] != NULL) {
return (uintptr_t)filemgrGetDeviceNameOrStartIndex(1, operation, data->list.value - 1);
}
break;
return (uintptr_t)"Custom";
case MENUOP_GETGROUPSTARTINDEX:
if (data->list.value == 0) {
data->list.groupstartindex = 0;
} else {
data->list.groupstartindex = mpGetNumUnlockedPresets();
if (g_FileLists[1] != NULL) {
data->list.groupstartindex += filemgrGetDeviceNameOrStartIndex(1, operation, data->list.value - 1);
}
}
data->list.groupstartindex = data->list.value == 0 ? 0 : numpresets;
break;
case MENUOP_LISTITEMFOCUS:
if (data->list.value < mpGetNumUnlockedPresets()) {
if (presets && data->list.value < mpGetNumUnlockedPresets()) {
g_Menus[g_MpPlayerNum].mpsetup.slotindex = 0xffff;
} else {
g_Menus[g_MpPlayerNum].mpsetup.slotindex = data->list.value - mpGetNumUnlockedPresets();
}
else {
g_Menus[g_MpPlayerNum].mpsetup.slotindex = data->list.value - numpresets;
}
break;
}
@@ -2315,21 +2323,21 @@ MenuItemHandlerResult mpLoadSettingsMenuHandler(s32 operation, struct menuitem *
char *mpMenuTextMpconfigMarquee(struct menuitem *item)
{
char filename[20];
char filename[MPSETUP_MAXNAME+1];
u16 numsims;
u16 stagenum;
u16 scenarionum;
s32 arenanum;
s32 i;
if (g_Menus[g_MpPlayerNum].mpsetup.slotindex < 0xffff && g_FileLists[1]) {
if (g_Menus[g_MpPlayerNum].mpsetup.slotindex < 0xffff && g_MpSetupFile.numsetups > 0) {
#if VERSION >= VERSION_NTSC_1_0
arenanum = -1;
#else
arenanum = 0;
#endif
mpsetupfileGetOverview(g_FileLists[1]->files[g_Menus[g_MpPlayerNum].mpsetup.slotindex].name,
mpsetupfileGetOverview(g_MpSetupFile.setups[g_Menus[g_MpPlayerNum].mpsetup.slotindex].bytes,
filename, &numsims, &stagenum, &scenarionum);
for (i = 0; i < ARRAYCOUNT(g_MpArenas); i++) {
@@ -2633,14 +2641,40 @@ struct menuitem g_MpLoadSettingsMenuItems[] = {
0,
NULL,
},
{
MENUITEMTYPE_SEPARATOR,
0,
0,
0,
0,
NULL,
},
{
MENUITEMTYPE_LABEL,
0,
MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_LESSLEFTPADDING | MENUITEMFLAG_SMALLFONT,
(uintptr_t)"Menu Alt: Toggle Presets\n",
0,
NULL,
},
{ MENUITEMTYPE_END },
};
MenuDialogHandlerResult loadSettingsDialogHandler(s32 operation, struct menudialogdef *dialogdef, union handlerdata *data)
{
if (operation == MENUOP_TICK) {
if (inputMenuAltMenuPressed(g_MpPlayerNum)) {
u8 presets = g_Menus[g_MpPlayerNum].mpsetup.showpresets;
g_Menus[g_MpPlayerNum].mpsetup.showpresets = 1 - presets;
}
}
}
struct menudialogdef g_MpLoadSettingsMenuDialog = {
MENUDIALOGTYPE_DEFAULT,
L_MPMENU_139, // "Load Game Settings"
g_MpLoadSettingsMenuItems,
NULL,
loadSettingsDialogHandler,
MENUDIALOGFLAG_CLOSEONSELECT,
NULL,
};
@@ -5016,13 +5050,10 @@ MenuItemHandlerResult menuhandler0017ef30(s32 operation, struct menuitem *item,
MenuItemHandlerResult menuhandlerMpSaveSettings(s32 operation, struct menuitem *item, union handlerdata *data)
{
if (operation == MENUOP_SET) {
if (g_MpSetup.fileguid.fileid == 0) {
if (g_MpCurrentSetup < 0) {
menuPushDialog(&g_MpSaveSetupNameMenuDialog);
} else {
#if VERSION >= VERSION_NTSC_1_0
filemgrSetDevice1BySerial(g_MpSetup.fileguid.deviceserial);
#endif
}
else {
menuPushDialog(&g_MpSaveSetupExistsMenuDialog);
}
}
@@ -5365,6 +5396,10 @@ MenuDialogHandlerResult menudialogCombatSimulator(s32 operation, struct menudial
g_Vars.waitingtojoin[1] = false;
g_Vars.waitingtojoin[2] = false;
g_Vars.waitingtojoin[3] = false;
// load the setup file when entering the Combat Simulator
mpsetupCopyAllFromPak();
mpsetupLoadCurrentFile();
}
if (g_Menus[g_MpPlayerNum].curdialog
@@ -5757,6 +5792,14 @@ struct menuitem g_MpAdvancedSetupMenuItems[] = {
0,
NULL,
},
{
MENUITEMTYPE_SELECTABLE,
0,
MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SELECTABLE_OPENSDIALOG | MENUITEMFLAG_LOCKABLEMINOR | MENUITEMFLAG_LOCKABLEMAJOR,
(uintptr_t)"Manage Settings\n",
0,
(void *)&g_ManageSettingsDialog,
},
{
MENUITEMTYPE_SELECTABLE,
0,
+32 -24
View File
@@ -374,13 +374,13 @@ Gfx *menugfxDrawPlane(Gfx *gdl, s32 x1, s32 y1, s32 x2, s32 y2, u32 colour1, u32
/**
* Write the specified amount of bits to the buffer, advancing the internal pointer.
*
* numbits is expected to be 32 or less.
* numbits is expected to be 64 or less.
*
* This function only sets bits to on and does not unset them.
*/
void savebufferOr(struct savebuffer *buffer, u32 value, s32 numbits)
void savebufferOr(struct savebuffer *buffer, u64 value, s32 numbits)
{
u32 bit = 1 << (numbits - 1);
u64 bit = 1LL << (numbits - 1LL);
for (; bit; bit >>= 1) {
if (bit & value) {
@@ -399,11 +399,11 @@ void savebufferOr(struct savebuffer *buffer, u32 value, s32 numbits)
/**
* Write the specified amount of bits to the buffer, advancing the internal pointer.
*
* numbits is expected to be 32 or less.
* numbits is expected to be 64 or less.
*/
void savebufferWriteBits(struct savebuffer *buffer, u32 value, s32 numbits, u8 *dst)
void savebufferWriteBits(struct savebuffer *buffer, u64 value, s32 numbits, u8 *dst)
{
u32 bit = 1 << (numbits - 1);
u64 bit = 1LL << (numbits - 1);
for (; bit; bit >>= 1) {
s32 bitindex = buffer->bitpos % 8;
@@ -425,12 +425,12 @@ void savebufferWriteBits(struct savebuffer *buffer, u32 value, s32 numbits, u8 *
* Read the specified amount of bits from the buffer and return it as an
* integer, advancing the internal pointer.
*
* numbits is expected to be 32 or less.
* numbits is expected to be 64 or less.
*/
u32 savebufferReadBits(struct savebuffer *buffer, s32 numbits)
u64 savebufferReadBits(struct savebuffer *buffer, s32 numbits)
{
u32 bit = 1 << (numbits - 1);
u32 value = 0;
u64 bit = 1LL << (numbits - 1);
u64 value = 0;
for (; bit; bit >>= 1) {
s32 bitindex = buffer->bitpos % 8;
@@ -470,24 +470,17 @@ void savebufferWriteData(struct savebuffer *buffer, u8 *data, u8 len)
}
}
void func0f0d54c4(struct savebuffer *buffer)
{
s32 tmp = buffer->bitpos;
if (tmp / 8 && buffer->bitpos);
}
/**
* Read a zero-terminated string from the buffer and move the buffer's internal
* pointer past the end of the string.
*/
void savebufferReadString(struct savebuffer *buffer, char *dst, bool addlinebreak)
void savebufferReadString_ext(struct savebuffer *buffer, char *dst, bool addlinebreak, u8 len)
{
bool foundnull = false;
s32 index = 0;
s32 i;
for (i = 0; i < 10; i++) {
for (i = 0; i < len; i++) {
s32 byte = savebufferReadBits(buffer, 8);
if (!foundnull) {
@@ -509,12 +502,17 @@ void savebufferReadString(struct savebuffer *buffer, char *dst, bool addlinebrea
dst[index] = '\0';
}
void func0f0d55a4(struct savebuffer *buffer, char *src)
void savebufferReadString(struct savebuffer *buffer, char *dst, bool addlinebreak)
{
savebufferReadString_ext(buffer, dst, addlinebreak, 10);
}
void savebufferWriteString_ext(struct savebuffer *buffer, char *src, u8 len)
{
bool done = false;
s32 i;
for (i = 0; i < 10; i++) {
for (i = 0; i < len; i++) {
if (!done) {
if (src[i] == '\0') {
done = true;
@@ -532,12 +530,22 @@ void func0f0d55a4(struct savebuffer *buffer, char *src)
}
}
void func0f0d564c(u8 *data, char *dst, bool addlinebreak)
void savebufferWriteString(struct savebuffer *buffer, char *src)
{
savebufferWriteString_ext(buffer, src, 10);
}
void func0f0d564c_ext(u8 *data, char *dst, bool addlinebreak, u8 len)
{
struct savebuffer buffer;
savebufferWriteData(&buffer, data, 10);
savebufferReadString(&buffer, dst, addlinebreak);
savebufferWriteData(&buffer, data, len);
savebufferReadString_ext(&buffer, dst, addlinebreak, len);
}
void func0f0d564c(u8 *data, char *dst, bool addlinebreak)
{
func0f0d564c_ext(data, dst, addlinebreak, 10);
}
#if VERSION >= VERSION_NTSC_1_0
+4
View File
@@ -4756,6 +4756,10 @@ enum weaponnum {
#define EXTRA_SLEEP_TIME 1000LL // 100us
#define MPSETUP_MAXSETUPS 128
#define MPSETUP_MAXNAME 17
#define MPSETUP_BLOCKSIZE 80
#endif
#endif
+3
View File
@@ -562,6 +562,9 @@ extern s32 g_FileAutoSelect;
extern u8 g_MpWeaponSetRandomFilters[NUM_MPWEAPONS];
extern s32 g_MpWeaponRandomFilterNum;
extern struct mpsetupfile g_MpSetupFile;
extern s16 g_MpCurrentSetup;
#define PLAYER_EXTCFG() g_PlayerExtCfg[g_Vars.currentplayerstats->mpindex & 3]
#define PLAYER_DEFAULT_FOV (PLAYER_EXTCFG().fovy)
+2 -3
View File
@@ -13,7 +13,7 @@ void func0f187fbc(s32 playernum);
void func0f187fec(void);
void mpPlayerSetDefaults(s32 playernum, bool autonames);
void func0f1881d4(s32 index);
void mpInit(void);
void mpInit(bool resetplayers);
void mpGetTeamsWithDefaultName(u8 *mask);
void mpSetTeamNamesToDefault(u8 mask);
void mpSetDefaultNamesIfEmpty(void);
@@ -118,11 +118,10 @@ s32 mpGetNumUnlockedPresets(void);
char *mpGetPresetNameBySlot(s32 slot);
void mpApplyConfig(struct mpconfigfull *mpconfig);
void mp0f18dec4(s32 arg0);
void mpsetupfileLoadWad(struct savebuffer *buffer);
void mpsetupfileLoadWad(struct savebuffer *buffer, u8 version);
void mpsetupfileSaveWad(struct savebuffer *buffer);
void mpsetupfileGetOverview(char *arg0, char *filename, u16 *numsims, u16 *stagenum, u16 *scenarionum);
s32 mpsetupfileSave(s32 device, s32 filenum, u16 deviceserial);
s32 mpsetupfileLoad(s32 device, s32 filenum, u16 deviceserial);
void func0f18e558(void);
struct modeldef *func0f18e57c(s32 index, s32 *headnum);
+1 -1
View File
@@ -17,7 +17,7 @@ struct mpscenariooverview {
extern struct mpscenariooverview g_MpScenarioOverviews[6];
MenuItemHandlerResult menuhandlerMpOpenOptions(s32 operation, struct menuitem *item, union handlerdata *data);
void scenarioReadSave(struct savebuffer *buffer);
void scenarioReadSave(struct savebuffer *buffer, u8 version);
void scenarioWriteSave(struct savebuffer *buffer);
void scenarioInit(void);
s32 scenarioNumProps(void);
+7 -5
View File
@@ -11,14 +11,16 @@ Gfx *func0f0d49c8(Gfx *gdl);
Gfx *func0f0d4a3c(Gfx *gdl, s32 arg1);
Gfx *func0f0d4c80(Gfx *gdl);
Gfx *menugfxDrawPlane(Gfx *gdl, s32 x1, s32 y1, s32 x2, s32 y2, u32 colour1, u32 colour2, s32 type);
void savebufferOr(struct savebuffer *buffer, u32 arg1, s32 arg2);
void savebufferWriteBits(struct savebuffer *buffer, u32 value, s32 numbits, u8 *dst);
u32 savebufferReadBits(struct savebuffer *buffer, s32 offset);
void savebufferOr(struct savebuffer *buffer, u64 arg1, s32 arg2);
void savebufferWriteBits(struct savebuffer *buffer, u64 value, s32 numbits, u8 *dst);
u64 savebufferReadBits(struct savebuffer *buffer, s32 offset);
void savebufferClear(struct savebuffer *buffer);
void savebufferWriteData(struct savebuffer *buffer, u8 *data, u8 len);
void func0f0d54c4(struct savebuffer *buffer);
void savebufferReadString_ext(struct savebuffer *buffer, char *dst, bool addlinebreak, u8 len);
void savebufferReadString(struct savebuffer *buffer, char *dst, bool addlinebreak);
void func0f0d55a4(struct savebuffer *buffer, char *src);
void savebufferWriteString_ext(struct savebuffer *buffer, char *src, u8 len);
void savebufferWriteString(struct savebuffer *buffer, char *src);
void func0f0d564c_ext(u8 *data, char *dst, bool addlinebreak, u8 len);
void func0f0d564c(u8 *data, char *dst, bool addlinebreak);
void func0f0d5690(u8 *dst, char *buffer);
void savebufferWriteGuid(struct savebuffer *buffer, struct fileguid *guid);
+16 -3
View File
@@ -3295,7 +3295,7 @@ struct menuitemdata_dropdown {
};
struct menuitemdata_keyboard {
char string[11];
char string[MPSETUP_MAXNAME+1];
s8 col;
s8 row;
u8 capslock : 1; // Pressed A on caps button
@@ -3774,6 +3774,7 @@ struct menudata_main {
struct menudata_mpsetup {
u32 slotindex;
u32 slotcount;
u8 showpresets;
u32 unke24;
};
@@ -3982,13 +3983,14 @@ struct menu {
union {
struct menudata_endscreen endscreen;
struct menudata_main main;
struct menudata_mpsetup mpsetup;
struct menudata_mppause mppause;
struct menudata_mpend mpend;
struct menudata_filemgr fm;
struct menudata_main4mb main4mb;
struct menudata_training training;
};
struct menudata_mpsetup mpsetup;
};
struct gamefile {
@@ -4080,7 +4082,7 @@ struct missionconfig {
};
struct mpsetup {
/*0x800acb88*/ char name[12];
/*0x800acb88*/ char name[MPSETUP_MAXNAME+1];
/*0x800acb94*/ u32 options;
/*0x800acb98*/ u8 scenario;
/*0x800acb99*/ u8 stagenum;
@@ -6156,6 +6158,17 @@ struct extplayerconfig {
s32 usereloads;
};
struct setupblock {
u8 bytes[MPSETUP_BLOCKSIZE];
};
struct mpsetupfile {
u8 version;
u8 defaultsetup;
u8 numsetups;
struct setupblock setups[MPSETUP_MAXSETUPS];
};
#endif
#endif