Rando version warning on different builds (#2420)

* save build version to savefile

* adjust rando hash icons to use fade in/out

* add dialog message support on the file select screen and display rando version warning

* remove duplicated message functions and use stubbed play state instead for rando warning

* add major/minor/patch version saving to file and compare against

* use strncpy and memset for build version

* don't show rando warning one copy/erase screens

* review feedback

* Add german and french translations for rando warning

Co-authored-by: PurpleHato <linkvssangoku.jr@gmail.com>

---------

Co-authored-by: PurpleHato <linkvssangoku.jr@gmail.com>
This commit is contained in:
Adam Bird 2023-02-28 20:46:55 -05:00 committed by GitHub
commit 1fc6a2f08f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 139 additions and 12 deletions

View file

@ -1,4 +1,7 @@
const char gBuildVersion[] = "@PROJECT_BUILD_NAME@ (@CMAKE_PROJECT_VERSION_MAJOR@.@CMAKE_PROJECT_VERSION_MINOR@.@CMAKE_PROJECT_VERSION_PATCH@)";
const int gBuildVersionMajor = @CMAKE_PROJECT_VERSION_MAJOR@;
const int gBuildVersionMinor = @CMAKE_PROJECT_VERSION_MINOR@;
const int gBuildVersionPatch = @CMAKE_PROJECT_VERSION_PATCH@;
const char gBuildTeam[] = "@PROJECT_TEAM@";
const char gBuildDate[] = __DATE__ " " __TIME__;
const char gBuildMakeOption[] = "";

View file

@ -163,7 +163,7 @@ void Message_Init(PlayState* play) {
YREG(31) = 0;
}
void func_80111070(void) {
void Regs_InitDataImpl(void) {
YREG(8) = 10;
YREG(14) = 0;
YREG(15) = 0;
@ -572,6 +572,6 @@ void func_80111070(void) {
VREG(92) = -63;
}
void func_80112098(PlayState* play) {
func_80111070();
void Regs_InitData(PlayState* play) {
Regs_InitDataImpl();
}

View file

@ -463,7 +463,7 @@ void Play_Init(GameState* thisx) {
play->cameraPtrs[MAIN_CAM]->uid = 0;
play->activeCamera = MAIN_CAM;
func_8005AC48(&play->mainCamera, 0xFF);
func_80112098(play);
Regs_InitData(play);
Message_Init(play);
GameOver_Init(play);
SoundSource_InitAll(play);

View file

@ -11,6 +11,8 @@
#include "objects/gameplay_keep/gameplay_keep.h"
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/Enhancements/custom-message/CustomMessageTypes.h"
#define NORMAL_QUEST 0
#define MASTER_QUEST 1
#define RANDOMIZER_QUEST 2
@ -387,30 +389,42 @@ void DrawSeedHashSprites(FileChooseContext* this) {
gDPPipeSync(POLY_OPA_DISP++);
gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
if (this->windowRot == 0 || (this->configMode == CM_QUEST_MENU && this->questType[this->buttonIndex] == RANDOMIZER_QUEST)) {
if (this->selectMode == SM_CONFIRM_FILE) {
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0xFF, 0xFF, 0xFF, this->fileInfoAlpha[this->buttonIndex]);
// Draw icons on the main menu, when a rando file is selected, and when quest selection is set to rando
if ((this->configMode == CM_MAIN_MENU &&
(this->selectMode != SM_CONFIRM_FILE || Save_GetSaveMetaInfo(this->selectedFileIndex)->randoSave == 1)) ||
(this->configMode == CM_QUEST_MENU && this->questType[this->buttonIndex] == RANDOMIZER_QUEST)) {
if (this->fileInfoAlpha[this->selectedFileIndex] > 0) {
// Use file info alpha to match fading
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0xFF, 0xFF, 0xFF, this->fileInfoAlpha[this->selectedFileIndex]);
u16 xStart = 64;
// Draw Seed Icons
// Draw Seed Icons for specific file
for (unsigned int i = 0; i < 5; i++) {
if (Save_GetSaveMetaInfo(this->selectedFileIndex)->randoSave == 1) {
SpriteLoad(this, GetSeedTexture(Save_GetSaveMetaInfo(this->selectedFileIndex)->seedHash[i]));
SpriteDraw(this, GetSeedTexture(Save_GetSaveMetaInfo(this->selectedFileIndex)->seedHash[i]),
xStart + (18 * i), 136, 16, 16);
xStart + (18 * i), 136, 16, 16);
}
}
}
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0xFF, 0xFF, 0xFF, this->fileButtonAlpha[this->buttonIndex]);
// Fade top seed icons based on main menu fade and if save supports rando
u8 alpha = MAX(this->optionButtonAlpha, Save_GetSaveMetaInfo(this->selectedFileIndex)->randoSave == 1 ? 0xFF : 0);
if (alpha >= 200) {
alpha = 0xFF;
}
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0xFF, 0xFF, 0xFF, alpha);
// Draw Seed Icons for spoiler log
if (strnlen(CVarGetString("gSpoilerLog", ""), 1) != 0 && fileSelectSpoilerFileLoaded) {
u16 xStart = 64;
for (unsigned int i = 0; i < 5; i++) {
SpriteLoad(this, GetSeedTexture(gSaveContext.seedIcons[i]));
SpriteDraw(this, GetSeedTexture(gSaveContext.seedIcons[i]), xStart + (40 * i), 10, 24, 24);
}
}
}
}
gDPPipeSync(POLY_OPA_DISP++);
@ -1340,6 +1354,47 @@ void FileChoose_DrawFileInfo(GameState* thisx, s16 fileIndex, s16 isActive) {
}
}
}
// Use file info alpha to match fading
u8 textAlpha = this->fileInfoAlpha[fileIndex];
if (textAlpha >= 200) {
textAlpha = 255;
}
// Draw rando seed warning when build version doesn't match for Major or Minor number
if (Save_GetSaveMetaInfo(fileIndex)->randoSave == 1 &&
this->menuMode == FS_MENU_MODE_SELECT &&
(gBuildVersionMajor != Save_GetSaveMetaInfo(fileIndex)->buildVersionMajor ||
gBuildVersionMinor != Save_GetSaveMetaInfo(fileIndex)->buildVersionMinor)) {
// Stub out a dummy play state to be able to use the dialog system (MessageCtx)
PlayState dummyPlay;
PlayState* dummyPlayPtr = &dummyPlay;
// Set the MessageCtx and GameState onto the dummy play state
dummyPlayPtr->msgCtx = this->msgCtx;
dummyPlayPtr->state = this->state;
// Load the custom text ID without doing a textbox
Message_OpenText(dummyPlayPtr, TEXT_RANDO_SAVE_VERSION_WARNING);
// Force the context into message print mode
dummyPlayPtr->msgCtx.msgMode = MSGMODE_TEXT_NEXT_MSG;
Message_Decode(dummyPlayPtr);
// Set the draw pos to end of text to render it all at once
dummyPlayPtr->msgCtx.textDrawPos = dummyPlayPtr->msgCtx.decodedTextLen;
dummyPlayPtr->msgCtx.textColorAlpha = textAlpha;
// Set position and spacing values
R_TEXT_LINE_SPACING = 10;
R_TEXT_INIT_XPOS = 128;
R_TEXT_INIT_YPOS = 154;
Gfx* gfx = Graph_GfxPlusOne(POLY_OPA_DISP);
Message_DrawText(dummyPlayPtr, &gfx);
POLY_OPA_DISP = gfx;
}
}
CLOSE_DISPS(this->state.gfxCtx);
@ -2658,6 +2713,9 @@ void FileChoose_Init(GameState* thisx) {
DmaMgr_SendRequest1(this->parameterSegment, (u32)_parameter_staticSegmentRomStart, size, __FILE__,
__LINE__);
// Load some registers used by the dialog system
Regs_InitData(NULL); // Passing in NULL as we dont have a playstate, and it isn't used in the func
Matrix_Init(&this->state);
View_Init(&this->view, this->state.gfxCtx);
this->state.main = FileChoose_Main;