Skip to content

Commit 8eb1ff5

Browse files
committed
Add custom error display for platforms
Implemented currently for 3DS and SDL2. Switch and Vita are possible, however an Error report might be generated on Switch (bad, could get send to big N) and for Vita one would need to match framebuffer format and such when dealing with GXM for dialog display. This is not worth currently, since we likely migrate away from vita2d library in the future. Go through platform teardown code. While this may not work for every case (e.g. out of memory on Wii), this should be cleaner.
1 parent 4bdfb75 commit 8eb1ff5

File tree

16 files changed

+140
-24
lines changed

16 files changed

+140
-24
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ add_library(${PROJECT_NAME} OBJECT
231231
src/instrumentation.cpp
232232
src/instrumentation.h
233233
src/keys.h
234+
src/main.h
234235
src/main_data.cpp
235236
src/main_data.h
236237
src/maniac_patch.cpp

Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ libeasyrpg_player_a_SOURCES = \
212212
src/instrumentation.cpp \
213213
src/instrumentation.h \
214214
src/keys.h \
215+
src/main.h \
215216
src/main_data.cpp \
216217
src/main_data.h \
217218
src/maniac_patch.cpp \

src/baseui.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,14 @@ class BaseUi {
103103
*/
104104
virtual bool ShowCursor(bool /* flag */) { return true; };
105105

106+
/**
107+
* Outputs the error message in a custom way depending on platform
108+
*
109+
* @param message message string.
110+
* @return wether error has been handled
111+
*/
112+
virtual bool HandleErrorOutput(const std::string & /* message */) { return false; }
113+
106114
/**
107115
* Gets if fullscreen mode is active.
108116
*

src/main.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* This file is part of EasyRPG Player.
3+
*
4+
* EasyRPG Player is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* EasyRPG Player is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with EasyRPG Player. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
#ifndef EP_MAIN_H
19+
#define EP_MAIN_H
20+
21+
namespace Platform {
22+
23+
/**
24+
* Run Platform teardown code and set return status code when
25+
* program terminates.
26+
*
27+
* @param without_error Whether to set an error exit code
28+
*/
29+
int Exit(bool without_error = true);
30+
31+
}
32+
33+
#endif

src/output.cpp

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@
2828
#include <fmt/ostream.h>
2929
#ifdef EMSCRIPTEN
3030
# include "platform/emscripten/interface.h"
31-
#elif defined(__vita__)
32-
# include <psp2/kernel/processmgr.h>
3331
#endif
3432

3533
#include "output.h"
@@ -42,6 +40,7 @@
4240
#include "message_overlay.h"
4341
#include "font.h"
4442
#include "baseui.h"
43+
#include "main.h"
4544

4645
// fmt 7 has renamed the namespace
4746
#if FMT_VERSION < 70000
@@ -203,10 +202,7 @@ static void HandleErrorOutput(const std::string& err) {
203202
BitmapRef surface = DisplayUi->GetDisplaySurface();
204203
surface->FillRect(surface->GetRect(), Color(255, 0, 0, 128));
205204

206-
std::string error = "Error:\n";
207-
error += err;
208-
209-
error += "\n\nEasyRPG Player will close now.\nPress [ENTER] key to exit...";
205+
std::string error = err + "\nPress [ENTER] key to exit...";
210206

211207
Text::Draw(*surface, 11, 11, *Font::DefaultBitmapFont(), Color(0, 0, 0, 255), error);
212208
Text::Draw(*surface, 10, 10, *Font::DefaultBitmapFont(), Color(255, 255, 255, 255), error);
@@ -294,16 +290,18 @@ void Output::ToggleLog() {
294290

295291
void Output::ErrorStr(std::string const& err) {
296292
WriteLog(LogLevel::Error, err);
293+
std::string error = "Error:\n" + err + "\n\nEasyRPG Player will close now.";
294+
297295
static bool recursive_call = false;
298296
if (!recursive_call && DisplayUi) {
299297
recursive_call = true;
300-
HandleErrorOutput(err);
298+
// Try platform handler first
299+
if (!DisplayUi->HandleErrorOutput(error))
300+
HandleErrorOutput(error);
301301
DisplayUi.reset();
302302
} else {
303303
// Fallback to Console if the display is not ready yet
304-
std::cout << err << std::endl;
305-
std::cout << std::endl;
306-
std::cout << "EasyRPG Player will close now.";
304+
std::cout << error << std::endl;
307305
#if defined (PLAYER_NINTENDO) || defined(__vita__)
308306
// stdin is non-blocking
309307
Game_Clock::SleepFor(5s);
@@ -316,11 +314,12 @@ void Output::ErrorStr(std::string const& err) {
316314
#endif
317315
}
318316

319-
// FIXME: This does not go through platform teardown code
320-
#ifdef __vita__
321-
sceKernelExitProcess(EXIT_FAILURE);
322-
#endif
317+
#ifdef USE_LIBRETRO
318+
// FIXME
323319
exit(EXIT_FAILURE);
320+
#else
321+
exit(Platform::Exit(false));
322+
#endif
324323
}
325324

326325
void Output::WarningStr(std::string const& warn) {

src/platform/3ds/main.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <cstdio>
2020

2121
#include "player.h"
22+
#include "main.h"
2223
#include <string>
2324
#include <sys/stat.h>
2425
#include <unistd.h>
@@ -178,6 +179,11 @@ int main(int argc, char* argv[]) {
178179
Player::Init(std::move(args));
179180
Player::Run();
180181

182+
// Close
183+
return Platform::Exit();
184+
}
185+
186+
int Platform::Exit(bool without_error) {
181187
romfsExit();
182188
stop3DSLink();
183189
gfxExit();
@@ -186,5 +192,6 @@ int main(int argc, char* argv[]) {
186192
APT_SetAppCpuTimeLimit(old_time_limit);
187193
}
188194

189-
return EXIT_SUCCESS;
195+
if(without_error) return EXIT_SUCCESS;
196+
return EXIT_FAILURE;
190197
}

src/platform/3ds/ui.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,3 +428,15 @@ void CtrUi::vGetConfig(Game_ConfigVideo& cfg) const {
428428
cfg.touch_ui.SetDescription("Toggle the backlight of the bottom screen");
429429
cfg.touch_ui.Set(bottom_state != screen_state::off);
430430
}
431+
432+
bool CtrUi::HandleErrorOutput(const std::string &message) {
433+
errorConf errCnf;
434+
std::string error = Player::GetFullVersionString();
435+
error += "\n\n" + message;
436+
437+
errorInit(&errCnf, ERROR_TEXT_WORD_WRAP, CFG_LANGUAGE_EN);
438+
errorText(&errCnf, error.c_str());
439+
errorDisp(&errCnf);
440+
441+
return true;
442+
}

src/platform/3ds/ui.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class CtrUi final : public BaseUi {
5454
void ToggleStretch() override;
5555
void ToggleTouchUi() override;
5656
void vGetConfig(Game_ConfigVideo& cfg) const override;
57+
bool HandleErrorOutput(const std::string &message) override;
5758

5859
#ifdef SUPPORT_AUDIO
5960
AudioInterface& GetAudio();

src/platform/psvita/main.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <psp2/appmgr.h>
2525
#include "player.h"
2626
#include "output.h"
27+
#include "main.h"
2728

2829
int _newlib_heap_size_user = 330 * 1024 * 1024;
2930

@@ -107,6 +108,13 @@ int main(int argc, char* argv[]) {
107108
Player::Run();
108109

109110
// Close
110-
sceKernelExitProcess(EXIT_SUCCESS);
111-
return EXIT_SUCCESS;
111+
return Platform::Exit();
112+
}
113+
114+
int Platform::Exit(bool without_error) {
115+
if(without_error) return sceKernelExitProcess(EXIT_SUCCESS);
116+
sceKernelExitProcess(EXIT_FAILURE);
117+
118+
// Does not matter
119+
return 0;
112120
}

src/platform/sdl/main.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "player.h"
2222
#include "utils.h"
2323
#include "output.h"
24+
#include "main.h"
2425

2526
#ifdef USE_SDL // This is needed on Windows, SDL wraps main()
2627
# include <SDL.h>
@@ -86,5 +87,11 @@ extern "C" int main(int argc, char* argv[]) {
8687
Player::Init(std::move(args));
8788
Player::Run();
8889

89-
return EXIT_SUCCESS;
90+
// Close
91+
return Platform::Exit();
92+
}
93+
94+
int Platform::Exit(bool without_error) {
95+
if(without_error) return EXIT_SUCCESS;
96+
return EXIT_FAILURE;
9097
}

src/platform/sdl/sdl2_ui.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,24 @@ bool Sdl2Ui::ShowCursor(bool flag) {
656656
#endif
657657
}
658658

659+
bool Sdl2Ui::HandleErrorOutput(const std::string &message) {
660+
std::string title = Player::GetFullVersionString();
661+
662+
// Manually Restore window from fullscreen, since message would not be visible otherwise
663+
if ((current_display_mode.flags & SDL_WINDOW_FULLSCREEN_DESKTOP)
664+
== SDL_WINDOW_FULLSCREEN_DESKTOP) {
665+
SDL_SetWindowFullscreen(sdl_window, 0);
666+
SDL_SetWindowSize(sdl_window, 0, 0);
667+
}
668+
669+
if(SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, title.c_str(),
670+
message.c_str(), sdl_window) != 0) {
671+
return false;
672+
}
673+
674+
return true;
675+
}
676+
659677
void Sdl2Ui::ProcessEvent(SDL_Event &evnt) {
660678
switch (evnt.type) {
661679
case SDL_WINDOWEVENT:

src/platform/sdl/sdl2_ui.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class Sdl2Ui final : public BaseUi {
7171
void ToggleVsync() override;
7272
void vGetConfig(Game_ConfigVideo& cfg) const override;
7373
Rect GetWindowMetrics() const override;
74+
bool HandleErrorOutput(const std::string &message) override;
7475

7576
#ifdef SUPPORT_AUDIO
7677
AudioInterface& GetAudio() override;

src/platform/switch/main.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <vector>
2222
#include "player.h"
2323
#include "output.h"
24+
#include "main.h"
2425

2526
namespace {
2627
int nxlinkSocket = -1;
@@ -48,7 +49,7 @@ int main(int argc, char* argv[]) {
4849

4950
appletLockExit();
5051

51-
// yuzu/nso
52+
// suyu/nso
5253
is_nro = envHasArgv();
5354
Output::SetLogCallback(LogCallback);
5455

@@ -89,6 +90,11 @@ int main(int argc, char* argv[]) {
8990
Player::Init(std::move(args));
9091
Player::Run();
9192

93+
// Close
94+
return Platform::Exit();
95+
}
96+
97+
int Platform::Exit(bool without_error) {
9298
romfsExit();
9399

94100
// Close debug log
@@ -101,5 +107,7 @@ int main(int argc, char* argv[]) {
101107
// HOS will close us immediately afterwards, if requested by home menu.
102108
// So no further cleanup possible.
103109
appletUnlockExit();
104-
return EXIT_SUCCESS;
110+
111+
if(without_error) return EXIT_SUCCESS;
112+
return EXIT_FAILURE;
105113
}

src/platform/wii/main.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,5 +114,11 @@ extern "C" int main(int argc, char* argv[]) {
114114
Player::Init(std::move(args));
115115
Player::Run();
116116

117-
return EXIT_SUCCESS;
117+
// Close
118+
return Platform::Exit();
119+
}
120+
121+
int Platform::Exit(bool without_error) {
122+
if(without_error) return EXIT_SUCCESS;
123+
return EXIT_FAILURE;
118124
}

src/player.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,8 @@ namespace Player {
106106
int menu_offset_y = (screen_height - MENU_HEIGHT) / 2;
107107
int message_box_offset_x = (screen_width - MENU_WIDTH) / 2;
108108
bool has_custom_resolution = false;
109-
110-
bool exit_flag;
111-
bool reset_flag;
109+
bool exit_flag = false;
110+
bool reset_flag = false;
112111
bool debug_flag;
113112
bool hide_title_flag;
114113
int load_game_id;

tests/test_main.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include <emscripten.h>
88
#endif
99

10+
#include "main.h"
11+
1012
int main(int argc, char** argv) {
1113
#ifdef EMSCRIPTEN
1214
EM_ASM({
@@ -21,3 +23,8 @@ int main(int argc, char** argv) {
2123

2224
return doctest::Context(argc, argv).run();
2325
}
26+
27+
int Platform::Exit(bool) {
28+
// Empty on purpose
29+
return 0;
30+
}

0 commit comments

Comments
 (0)