mirror of
https://github.com/CraftyBoss/SuperMarioOdysseyOnline.git
synced 2024-11-21 18:55:16 +00:00
fix: crashes related to Keyboard in FreezeTagConfigMenu
In some kingdoms (e.g. in Sand, but not in Cascade) it always/sometimes crashed the game when closing the keyboard. I assume that's because the Keyboard was on the SceneHeap which it shouldn't. At least moving it to the game mode heap fixed it. But then there was a memory leak that the game mode heap growed everytime the scene was reloaded. That was because of some never freed memory in the Keyboard class. I tried to implement destructors for `StageSceneStateServerConfig` and `FreezeTagConfigMenu` but that also crashed. So I added new `clean()` methods instead.
This commit is contained in:
parent
7fa8c659e1
commit
be50d034f8
8 changed files with 42 additions and 17 deletions
|
@ -9,6 +9,7 @@ typedef void (*KeyboardSetup)(nn::swkbd::KeyboardConfig&);
|
|||
class Keyboard {
|
||||
public:
|
||||
Keyboard(ulong strSize);
|
||||
~Keyboard();
|
||||
void keyboardThread();
|
||||
|
||||
void openKeyboard(const char* initialText, KeyboardSetup setup);
|
||||
|
|
|
@ -41,6 +41,7 @@ class StageSceneStateServerConfig : public al::HostStateBase<al::Scene>, public
|
|||
virtual void appear(void) override;
|
||||
virtual void kill(void) override;
|
||||
|
||||
void clean();
|
||||
void exeMainMenu();
|
||||
void exeOpenKeyboardIP();
|
||||
void exeOpenKeyboardPort();
|
||||
|
|
|
@ -9,6 +9,8 @@ class FreezeTagConfigMenu : public GameModeConfigMenu {
|
|||
public:
|
||||
FreezeTagConfigMenu();
|
||||
|
||||
void clean() override;
|
||||
|
||||
const sead::WFixedSafeString<0x200>* getStringData() override;
|
||||
GameModeConfigMenu::UpdateAction updateMenu(int selectIndex) override;
|
||||
|
||||
|
@ -17,6 +19,5 @@ class FreezeTagConfigMenu : public GameModeConfigMenu {
|
|||
private:
|
||||
static constexpr int mItemCount = 8;
|
||||
sead::SafeArray<sead::WFixedSafeString<0x200>, mItemCount>* mItems = nullptr;
|
||||
Keyboard* mScoreKeyboard;
|
||||
Keyboard* mRoundKeyboard;
|
||||
Keyboard* mKeyboard;
|
||||
};
|
||||
|
|
|
@ -12,6 +12,8 @@ public:
|
|||
|
||||
GameModeConfigMenu() = default;
|
||||
|
||||
virtual void clean() {}
|
||||
|
||||
virtual UpdateAction updateMenu(int selectIndex) { return UpdateAction::NOOP; }
|
||||
|
||||
virtual const sead::WFixedSafeString<0x200>* getStringData() { return nullptr; }
|
||||
|
|
|
@ -20,7 +20,13 @@ Keyboard::Keyboard(ulong strSize) : mResultString(strSize) {
|
|||
|
||||
mCustomizeDicSize = 0x400;
|
||||
mCustomizeDicBuf = (char*)malloc(mCustomizeDicSize);
|
||||
}
|
||||
|
||||
Keyboard::~Keyboard() {
|
||||
delete mThread;
|
||||
free(mWorkBuf);
|
||||
free(mTextCheckBuf);
|
||||
free(mCustomizeDicBuf);
|
||||
}
|
||||
|
||||
void Keyboard::keyboardThread() {
|
||||
|
@ -48,7 +54,6 @@ void Keyboard::keyboardThread() {
|
|||
}
|
||||
|
||||
void Keyboard::openKeyboard(const char* initialText, KeyboardSetup setupFunc) {
|
||||
|
||||
mInitialText = initialText;
|
||||
mSetupFunc = setupFunc;
|
||||
|
||||
|
|
|
@ -119,6 +119,7 @@ void initStateHook(
|
|||
) {
|
||||
thisPtr->mStateOption = new StageSceneStateOption(stateName, host, initInfo, footer, data, unkBool);
|
||||
|
||||
if (sceneStateServerConfig) { sceneStateServerConfig->clean(); }
|
||||
sceneStateServerConfig = new StageSceneStateServerConfig("ServerConfig", host, initInfo, footer, data, unkBool);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#include "server/freeze-tag/FreezeTagConfigMenu.hpp"
|
||||
|
||||
#include <cmath>
|
||||
#include <stdint.h>
|
||||
#include "sead/basis/seadNew.h"
|
||||
#include "sead/heap/seadHeap.h"
|
||||
#include "server/gamemode/GameModeManager.hpp"
|
||||
#include "nn/util.h"
|
||||
|
||||
FreezeTagConfigMenu::FreezeTagConfigMenu() : GameModeConfigMenu() {
|
||||
|
@ -14,13 +18,12 @@ FreezeTagConfigMenu::FreezeTagConfigMenu() : GameModeConfigMenu() {
|
|||
mItems->mBuffer[6].copy(u"Cappy Collision (ON) ");
|
||||
mItems->mBuffer[7].copy(u"Cappy Bounce (OFF) ");
|
||||
|
||||
mScoreKeyboard = new Keyboard(6);
|
||||
mScoreKeyboard->setHeaderText(u"Set your Freeze Tag score");
|
||||
mScoreKeyboard->setSubText(u"");
|
||||
sead::Heap* heap = GameModeManager::instance()->getHeap();
|
||||
mKeyboard = new (heap) Keyboard(6);
|
||||
}
|
||||
|
||||
mRoundKeyboard = new Keyboard(3);
|
||||
mRoundKeyboard->setHeaderText(u"Set length of rounds you start in minutes");
|
||||
mRoundKeyboard->setSubText(u"This will be automatically sent to other players (2-60 minutes)");
|
||||
void FreezeTagConfigMenu::clean() {
|
||||
delete mKeyboard;
|
||||
}
|
||||
|
||||
const sead::WFixedSafeString<0x200>* FreezeTagConfigMenu::getStringData() {
|
||||
|
@ -92,7 +95,9 @@ GameModeConfigMenu::UpdateAction FreezeTagConfigMenu::updateMenu(int selectIndex
|
|||
char buf[5];
|
||||
nn::util::SNPrintf(buf, 5, "%u", oldScore);
|
||||
|
||||
mScoreKeyboard->openKeyboard(
|
||||
mKeyboard->setHeaderText(u"Set your Freeze Tag score");
|
||||
mKeyboard->setSubText(u"");
|
||||
mKeyboard->openKeyboard(
|
||||
buf,
|
||||
[](nn::swkbd::KeyboardConfig& config) {
|
||||
config.keyboardMode = nn::swkbd::KeyboardMode::ModeNumeric;
|
||||
|
@ -103,12 +108,12 @@ GameModeConfigMenu::UpdateAction FreezeTagConfigMenu::updateMenu(int selectIndex
|
|||
}
|
||||
);
|
||||
|
||||
while (!mScoreKeyboard->isThreadDone()) {
|
||||
while (!mKeyboard->isThreadDone()) {
|
||||
nn::os::YieldThread(); // allow other threads to run
|
||||
}
|
||||
|
||||
if (!mScoreKeyboard->isKeyboardCancelled()) {
|
||||
newScore = ::atoi(mScoreKeyboard->getResult());
|
||||
if (!mKeyboard->isKeyboardCancelled()) {
|
||||
newScore = std::atoi(mKeyboard->getResult());
|
||||
}
|
||||
|
||||
if (newScore != uint16_t(-1)) {
|
||||
|
@ -128,7 +133,9 @@ GameModeConfigMenu::UpdateAction FreezeTagConfigMenu::updateMenu(int selectIndex
|
|||
char buf[3];
|
||||
nn::util::SNPrintf(buf, 3, "%u", oldTime);
|
||||
|
||||
mRoundKeyboard->openKeyboard(
|
||||
mKeyboard->setHeaderText(u"Set length of rounds you start in minutes");
|
||||
mKeyboard->setSubText(u"This will be automatically sent to other players (2-60 minutes)");
|
||||
mKeyboard->openKeyboard(
|
||||
buf,
|
||||
[](nn::swkbd::KeyboardConfig& config) {
|
||||
config.keyboardMode = nn::swkbd::KeyboardMode::ModeNumeric;
|
||||
|
@ -139,17 +146,18 @@ GameModeConfigMenu::UpdateAction FreezeTagConfigMenu::updateMenu(int selectIndex
|
|||
}
|
||||
);
|
||||
|
||||
while (!mRoundKeyboard->isThreadDone()) {
|
||||
while (!mKeyboard->isThreadDone()) {
|
||||
nn::os::YieldThread(); // allow other threads to run
|
||||
}
|
||||
|
||||
if (!mRoundKeyboard->isKeyboardCancelled()) {
|
||||
newTime = ::atoi(mRoundKeyboard->getResult());
|
||||
if (!mKeyboard->isKeyboardCancelled()) {
|
||||
newTime = std::atoi(mKeyboard->getResult());
|
||||
}
|
||||
|
||||
if (newTime != uint8_t(-1)) {
|
||||
FreezeTagInfo::mRoundLength = al::clamp(newTime, u8(2), u8(60));
|
||||
}
|
||||
|
||||
return UpdateAction::NOOP;
|
||||
}
|
||||
case 4: {
|
||||
|
|
|
@ -139,6 +139,12 @@ al::MessageSystem* StageSceneStateServerConfig::getMessageSystem(void) const {
|
|||
return mMsgSystem;
|
||||
}
|
||||
|
||||
void StageSceneStateServerConfig::clean() {
|
||||
for (int mode = 0; mode < GameModeFactory::getModeCount() - 1; mode++) {
|
||||
mGamemodeConfigMenus[mode].mMenu->clean();
|
||||
}
|
||||
}
|
||||
|
||||
void StageSceneStateServerConfig::exeMainMenu() {
|
||||
if (al::isFirstStep(this)) {
|
||||
activateInput();
|
||||
|
|
Loading…
Reference in a new issue