Skip to content

Commit 7c229ac

Browse files
committed
Added World.Loaded field to indicate whether the world level is loaded, error messages now include more info about where the error happened
1 parent 3ff2da3 commit 7c229ac

File tree

13 files changed

+142
-37
lines changed

13 files changed

+142
-37
lines changed

Includes/Game/GameState.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#pragma once
2+
3+
#include <atomic>
4+
5+
typedef struct {
6+
std::atomic<bool> MainMenuLoaded = false;
7+
std::atomic<bool> WorldLoaded = false;
8+
} GameState_s;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#pragma once
2+
3+
void SetLoadingWorldScreenMessageCallback();
4+
5+
void SetLeaveLevelPromptCallback();

Includes/Game/MenuLayout.hpp renamed to Includes/Game/MainMenuLayoutLoad.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@ void PatchGameMenuLayoutFunction();
66

77
bool LoadGameMenuLayout(const std::string &filepath);
88

9-
void PatchMenuLayoutCustomDefault(int plg_maj, int plg_min, int plg_patch);
9+
void PatchMenuCustomLayoutDefault(int plg_maj, int plg_min, int plg_patch);
10+
11+
void SetMainMenuLayoutLoadCallback();

Sources/Async.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ void Core::AsyncHandlerCallback()
2929
{
3030
if (lua_pcall(L, 0, 0, 0))
3131
{
32-
Core::Debug::LogError("Core error: " + std::string(lua_tostring(L, -1)));
32+
Core::Debug::LogError("Core::Async::handler error: " + std::string(lua_tostring(L, -1)));
3333
lua_pop(L, 1);
3434
}
3535
}
@@ -95,7 +95,7 @@ static int l_Async_tick(lua_State *L)
9595
lua_pushvalue(L, scriptsTableIdx);
9696
lua_pushinteger(L, i);
9797
if (lua_pcall(L, 2, 1, 0))
98-
Core::Debug::LogError(CTRPF::Utils::Format("Core error: %s", lua_tostring(L, -1)));
98+
Core::Debug::LogError(CTRPF::Utils::Format("Core::Async::tick error: %s", lua_tostring(L, -1)));
9999
lua_pop(L, 1); // Remove either error string or returned value
100100
lua_gc(L, LUA_GCCOLLECT, 0);
101101
continue;
@@ -114,12 +114,12 @@ static int l_Async_tick(lua_State *L)
114114
lua_pushstring(L, errMsg);
115115

116116
if (lua_pcall(L, 2, 1, 0)) {
117-
Core::Debug::LogError("Core error: "+std::string(lua_tostring(L, -1)));
117+
Core::Debug::LogError("Core::Async::tick error: "+std::string(lua_tostring(L, -1)));
118118
lua_pop(L, 1);
119119
} else {
120120
std::string traceback(lua_tostring(L, -1));
121121
Core::Utils::Replace(traceback, "\t", " ");
122-
Core::Debug::LogError(traceback);
122+
Core::Debug::LogError("Async task error: "+traceback);
123123
lua_pop(L, 1);
124124
}
125125
lua_pop(L, 1); // Remove co
@@ -131,7 +131,7 @@ static int l_Async_tick(lua_State *L)
131131
lua_pushvalue(L, scriptsTableIdx);
132132
lua_pushinteger(L, i);
133133
if (lua_pcall(L, 2, 1, 0))
134-
Core::Debug::LogError(CTRPF::Utils::Format("Core error: %s", lua_tostring(L, -1)));
134+
Core::Debug::LogError(CTRPF::Utils::Format("Core::Async::tick error: %s", lua_tostring(L, -1)));
135135
lua_pop(L, 1); // Remove either error string or returned value
136136
lua_gc(L, LUA_GCCOLLECT, 0);
137137
continue;
@@ -179,7 +179,7 @@ bool Core::RegisterAsyncModule(lua_State *L)
179179
)";
180180
if (luaL_dostring(L, luaCode))
181181
{
182-
Core::Debug::LogError("Core Async module failed load: " + std::string(lua_tostring(L, -1)));
182+
Core::Debug::LogError("Core::Async::load error: " + std::string(lua_tostring(L, -1)));
183183
lua_pop(L, 1);
184184
return false;
185185
}

Sources/Event.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@ void Core::EventHandlerCallback()
3838
lua_pushvalue(L, -2);
3939
if (lua_pcall(L, 1, 0, 0))
4040
{
41-
Core::Debug::LogError("Core error. Event module error in OnKeyPressed: " + std::string(lua_tostring(L, -1)));
41+
Core::Debug::LogError("Core::Event::OnKeyPressed error: " + std::string(lua_tostring(L, -1)));
4242
lua_pop(L, 1);
4343
}
4444
}
4545
else {
46-
Core::Debug::LogError("Core error. Unexpected type for Event.OnKeyPressed:Trigger");
46+
Core::Debug::LogError("Core::Event::OnKeyPressed::Trigger error. Unexpected type");
4747
lua_pop(L, 1);
4848
}
4949
lua_pop(L, 3);
@@ -62,12 +62,12 @@ void Core::EventHandlerCallback()
6262
lua_pushvalue(L, -2);
6363
if (lua_pcall(L, 1, 0, 0))
6464
{
65-
Core::Debug::LogError("Core error. Event module error in OnKeyDown: " + std::string(lua_tostring(L, -1)));
65+
Core::Debug::LogError("Core::Event::OnKeyDown error: " + std::string(lua_tostring(L, -1)));
6666
lua_pop(L, 1);
6767
}
6868
}
6969
else {
70-
Core::Debug::LogError("Core error. Unexpected type for Event.OnKeyDown:Trigger");
70+
Core::Debug::LogError("Core::Event::OnKeyDown::Trigger error. Unexpected type");
7171
lua_pop(L, 1);
7272
}
7373
lua_pop(L, 3);
@@ -86,12 +86,12 @@ void Core::EventHandlerCallback()
8686
lua_pushvalue(L, -2);
8787
if (lua_pcall(L, 1, 0, 0))
8888
{
89-
Core::Debug::LogError("Core error. Event module error in OnKeyReleased: " + std::string(lua_tostring(L, -1)));
89+
Core::Debug::LogError("Core::Event::OnKeyReleased error: " + std::string(lua_tostring(L, -1)));
9090
lua_pop(L, 1);
9191
}
9292
}
9393
else {
94-
Core::Debug::LogError("Core error. Unexpected type for Event.OnKeyReleased:Trigger");
94+
Core::Debug::LogError("Core::Event::OnKeyReleased::Trigger error. Unexpected type");
9595
lua_pop(L, 1);
9696
}
9797
lua_pop(L, 3);
@@ -109,7 +109,7 @@ void Core::EventHandlerCallback()
109109
graphicsIsTop.store(true);
110110
if (lua_pcall(L, 2, 0, 0))
111111
{
112-
Core::Debug::LogError("Core error. Event module error in OnNewFrame(top): " + std::string(lua_tostring(L, -1)));
112+
Core::Debug::LogError("Core::Event::OnNewFrame(top) error: " + std::string(lua_tostring(L, -1)));
113113
lua_pop(L, 1);
114114
}
115115
lua_getfield(L, -1, "Trigger");
@@ -118,12 +118,12 @@ void Core::EventHandlerCallback()
118118
graphicsIsTop.store(false);
119119
if (lua_pcall(L, 2, 0, 0))
120120
{
121-
Core::Debug::LogError("Core error. Event module error in OnNewFrame(bottom): " + std::string(lua_tostring(L, -1)));
121+
Core::Debug::LogError("Core::Event::OnNewFrame(bottom) error: " + std::string(lua_tostring(L, -1)));
122122
lua_pop(L, 1);
123123
}
124124
}
125125
else {
126-
Core::Debug::LogError("Core error. Unexpected type for Event.OnNewFrame:Trigger");
126+
Core::Debug::LogError("Core::Event::OnNewFrame::Trigger error. Unexpected type");
127127
lua_pop(L, 1);
128128
}
129129
lua_pop(L, 3);
@@ -204,7 +204,7 @@ static int l_Event_BaseEvent_Trigger(lua_State *L)
204204
if (lua_pcall(L, argc, 0, errfunc - (argc + 1))) {
205205
std::string errMsg(lua_tostring(L, -1));
206206
Core::Utils::Replace(errMsg, "\t", " ");
207-
Core::Debug::LogError(errMsg);
207+
Core::Debug::LogError("Event error: "+errMsg);
208208
lua_pop(L, 1);
209209
lua_remove(L, errfunc - (argc + 1));
210210

@@ -215,7 +215,7 @@ static int l_Event_BaseEvent_Trigger(lua_State *L)
215215
lua_pushvalue(L, listenersIdx);
216216
lua_pushinteger(L, i);
217217
if (lua_pcall(L, 2, 1, 0))
218-
Core::Debug::LogError(CTRPF::Utils::Format("Core error: %s", lua_tostring(L, -1)));
218+
Core::Debug::LogError(CTRPF::Utils::Format("Core::Event::BaseEvent::Trigger error: %s", lua_tostring(L, -1)));
219219
lua_pop(L, 1); // Remove either error string or returned value
220220
lua_gc(L, LUA_GCCOLLECT, 0);
221221
} else {
@@ -296,7 +296,7 @@ bool Core::Game::RegisterEventModule(lua_State *L)
296296
)";
297297
if (luaL_dostring(L, lua_Code))
298298
{
299-
Core::Debug::LogError("Core error. Unable to set 'Game.Event.BaseEvent' read-only: "+std::string(lua_tostring(L, -1)));
299+
Core::Debug::LogError("Core::Event::Load error: "+std::string(lua_tostring(L, -1)));
300300
lua_pop(L, 1);
301301
return false;
302302
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
2+
#include <CTRPluginFramework.hpp>
3+
4+
#include "Game/GameState.hpp"
5+
6+
namespace CTRPF = CTRPluginFramework;
7+
8+
#define BASE_OFF 0x100000
9+
10+
extern GameState_s GameState;
11+
12+
typedef int (*MBdetectStateFunc)(int *);
13+
14+
void LoadingWorldScreenMessageCallback(int *ptr1, int *ptr2) {
15+
GameState.MainMenuLoaded.store(false);
16+
17+
void (*LoadingWorldScreenMessageOriginal)(int*, int*) = (void(*)(int*,int*))(0x612ef0+BASE_OFF);
18+
MBdetectStateFunc *detectState = (MBdetectStateFunc*)(*ptr2 + 0x18);
19+
int state = detectState[0](ptr2);
20+
if (state == 0x10) {
21+
GameState.WorldLoaded.store(true);
22+
}
23+
24+
LoadingWorldScreenMessageOriginal(ptr1, ptr2);
25+
return;
26+
}
27+
28+
void SetLoadingWorldScreenMessageCallback() {
29+
CTRPF::Process::Write32(0x8c5df4+BASE_OFF, (u32)LoadingWorldScreenMessageCallback);
30+
}
31+
32+
void LeaveLevelPromptCallback(int *ptr1, int param2, int param3, u32 param4) {
33+
void (*LeaveLevelPromptOriginal)(int*,int,int,u32) = (void(*)(int*,int,int,u32))(0x221d78+BASE_OFF);
34+
35+
GameState.WorldLoaded.store(false);
36+
37+
LeaveLevelPromptOriginal(ptr1, param2, param3, param4);
38+
return;
39+
}
40+
41+
void SetLeaveLevelPromptCallback() {
42+
CTRPF::Process::Write32(0x8b3a70+BASE_OFF, (u32)LeaveLevelPromptCallback);
43+
}

Sources/Game/MenuLayout.cpp renamed to Sources/Game/MainMenuLayoutLoad.cpp

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include "Game/MenuLayout.hpp"
1+
#include "Game/MainMenuLayoutLoad.hpp"
22

33
#include <vector>
44

@@ -11,13 +11,16 @@
1111
using json = nlohmann::json;
1212

1313
#include "Game/Utils/game_functions.hpp"
14+
#include "Game/GameState.hpp"
1415
#include "Debug.hpp"
1516
#include "Utils/Utils.hpp"
1617

1718
#define BASE_OFF 0x100000
1819

1920
namespace CTRPF = CTRPluginFramework;
2021

22+
extern GameState_s GameState;
23+
2124
namespace MenuButtonID {
2225
typedef enum {
2326
Play = 0,
@@ -57,8 +60,6 @@ typedef struct uv_vals_struct {
5760

5861
typedef void (*code2Func)(int *);
5962

60-
#define NOP_INS 0xe320f000
61-
6263
typedef struct {
6364
int x = 0, y = 0, width = 0, height = 0;
6465
int iconU = 0, iconV = 0, iconW = 0, iconH = 0;
@@ -119,7 +120,7 @@ void CreateMenuButtons(int *ptr, std::vector<btn_ctx> &btn_ctxs) {
119120
}
120121
}
121122

122-
extern "C" void CreateMenuButtonsCallback(int *ptr) {
123+
void CreateMainMenuCustomLayout(int *ptr) {
123124
void (*MaybeRegisterData)(int*, void*) = (void(*)(int*, void*))(0x7f9788+BASE_OFF);
124125
btn_ctx *(*MaybeUpdateData)(btn_ctx*) = (btn_ctx*(*)(btn_ctx*))(0x7b1c18+BASE_OFF);
125126
u64 (*InitMenuCharacter)(GameCharacterView* chrPtr,int*,float,float,int,int,int,int) = (u64(*)(GameCharacterView*,int*,float,float,int,int,int,int))(0xec930+BASE_OFF);
@@ -162,11 +163,27 @@ extern "C" void CreateMenuButtonsCallback(int *ptr) {
162163

163164
for (auto &i : btnsOrder)
164165
MaybeUpdateData(&btn_ctxs[i]);
166+
167+
GameState.MainMenuLoaded.store(true);
165168
return;
166169
}
167170

171+
// Note: If a layout is loaded this will overwrite callback
172+
// So always do the same as the callback in CreateMainMenuCustomLayout
168173
void PatchGameMenuLayoutFunction() {
169-
CTRPF::Process::Write32(0x8ab4a4 + BASE_OFF, (u32)CreateMenuButtonsCallback); // Patch only reference to CreateMenuButtons
174+
CTRPF::Process::Write32(0x8ab4a4 + BASE_OFF, (u32)CreateMainMenuCustomLayout); // Patch only reference to CreateMenuButtons
175+
}
176+
177+
void MainMenuLayoutLoadCallback(int *ptr) {
178+
void (*MainMenuLoadOriginal)(int*) = (void(*)(int*))(0x16eda4+BASE_OFF);
179+
MainMenuLoadOriginal(ptr);
180+
181+
GameState.MainMenuLoaded.store(true);
182+
return;
183+
}
184+
185+
void SetMainMenuLayoutLoadCallback() {
186+
CTRPF::Process::Write32(0x8ab4a4 + BASE_OFF, (u32)MainMenuLayoutLoadCallback); // Patch only reference to CreateMenuButtons
170187
}
171188

172189
void LoadButtonData(json &btnJData, MenuBtnData &btnData, const std::string &btnName) {
@@ -252,7 +269,7 @@ static bool ReplaceConstString(u32 offset, u32 insAddr, u32 strAddr, u8 reg, con
252269
return ReplaceStringWithPointer(offset, insAddr, strAddr, (u32)textPtr, reg);
253270
}
254271

255-
void PatchMenuLayoutCustomDefault(int plg_maj, int plg_min, int plg_patch) {
272+
void PatchMenuCustomLayoutDefault(int plg_maj, int plg_min, int plg_patch) {
256273
ReplaceConstString(BASE_OFF, 0x16edd8, 0x16f170, 9, " Play"); // menu.play
257274
ReplaceConstString(BASE_OFF, 0x16ef24, 0x16f1a0, 0, " "); // menu.multiplayer
258275
ReplaceConstString(BASE_OFF, 0x16f078, 0x16f1b8, 0, " "); // menu.options

Sources/Modules.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ namespace Core {
5656
)";
5757
if (luaL_dostring(L, lua_Code))
5858
{
59-
Core::Debug::LogError("Core error. Unable to set 'Game' global read-only: "+std::string(lua_tostring(L, -1)));
59+
Core::Debug::LogError("Core::Load error: "+std::string(lua_tostring(L, -1)));
6060
lua_pop(L, 1);
6161
return false;
6262
}

Sources/Utils/Utils.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ bool Core::RegisterUtilsModule(lua_State *L)
6464
)";
6565
if (luaL_dostring(L, lua_Code))
6666
{
67-
Core::Debug::LogError("Core Utils module failed load: " + std::string(lua_tostring(L, -1)));
67+
Core::Debug::LogError("Core::Utils::Load error: " + std::string(lua_tostring(L, -1)));
6868
lua_pop(L, 1);
6969
return false;
7070
}

Sources/World.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@
22

33
#include <CTRPluginFramework.hpp>
44

5+
#include "Game/GameState.hpp"
6+
57
#include "string_hash.hpp"
68

79
#include "Minecraft.hpp"
810

911
namespace CTRPF = CTRPluginFramework;
1012

13+
extern GameState_s GameState;
14+
1115
enum world_offsets : u32
1216
{
1317
cloudsHeight = 0x100000 + 0x2C5398
@@ -20,6 +24,7 @@ enum world_offsets : u32
2024
// ----------------------------------------------------------------------------
2125

2226
/*
27+
=Game.World.Loaded = false
2328
=Game.World.Raining = false
2429
=Game.World.Thunderstorm = false
2530
=Game.World.CloudsHeight = 0.0
@@ -33,6 +38,9 @@ static int l_World_index(lua_State *L)
3338
bool valid_key = true;
3439

3540
switch (key) {
41+
case hash("Loaded"): // Read-only
42+
lua_pushboolean(L, GameState.WorldLoaded.load());
43+
break;
3644
case hash("Raining"):
3745
lua_pushboolean(L, Minecraft::IsRaining());
3846
break;

0 commit comments

Comments
 (0)