Skip to content

Commit a1ceb63

Browse files
committed
Error code framework
As one of the feedbacks from the RetroArch UI Improvements series put together by Nic Watt, the ways RetroArch (or any other frontend) could indicate errors about the cores, is quite limited. The Libretro API functions provide little feedback opportunity for the cores to indicate problems. By introducing a new environment call, the possibility will be available for the cores to indicate errors at any point, using a code that contains a defined part and a core specific part, as well as a short textual message. RetroArch will display such errors as on-screen messages (widgets), with the appropriate message class. Localized explanation of the error codes can be maintained. Example for the core side added to Remote Retropad, can be seen by trying to change input device type.
1 parent e661dde commit a1ceb63

8 files changed

Lines changed: 593 additions & 9 deletions

File tree

cores/libretro-net-retropad/net_retropad_core.c

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,8 @@ static bool input_test_file_read(const char* file_path)
396396
(int)rjson_get_source_line(parser),
397397
(int)rjson_get_source_column(parser),
398398
(*rjson_get_error(parser) ? rjson_get_error(parser) : "format error"));
399+
if (last_test_step > MAX_TEST_STEPS)
400+
last_test_step = 0;
399401
}
400402

401403
/* Free parser */
@@ -414,6 +416,12 @@ static bool input_test_file_read(const char* file_path)
414416
{
415417
NETRETROPAD_CORE_PREFIX(log_cb)(RETRO_LOG_WARN,"[Remote RetroPad] Too long test input json, maximum size: %d\n",MAX_TEST_STEPS);
416418
}
419+
if (last_test_step == 0)
420+
{
421+
NETRETROPAD_CORE_PREFIX(log_cb)(RETRO_LOG_WARN,"[Remote RetroPad]: no steps in input json\n");
422+
success = false;
423+
}
424+
417425
for (current_test_step = 0; current_test_step < last_test_step; current_test_step++)
418426
{
419427
NETRETROPAD_CORE_PREFIX(log_cb)(RETRO_LOG_DEBUG,
@@ -569,7 +577,14 @@ unsigned NETRETROPAD_CORE_PREFIX(retro_api_version)(void)
569577
}
570578

571579
void NETRETROPAD_CORE_PREFIX(retro_set_controller_port_device)(
572-
unsigned port, unsigned device) { }
580+
unsigned port, unsigned device)
581+
{
582+
const char msg[] = "Input device type change is not supported!";
583+
struct retro_error_message e;
584+
e.code = RETROE_UNSUPPORTED_ACTION | ((port & 0xFF) << 8) | (device & 0xFF);
585+
e.message = msg;
586+
NETRETROPAD_CORE_PREFIX(environ_cb)(RETRO_ENVIRONMENT_SET_ERROR_CODE, &e);
587+
}
573588

574589
void NETRETROPAD_CORE_PREFIX(retro_get_system_info)(
575590
struct retro_system_info *info)
@@ -1409,13 +1424,16 @@ void NETRETROPAD_CORE_PREFIX(retro_run)(void)
14091424

14101425
bool NETRETROPAD_CORE_PREFIX(retro_load_game)(const struct retro_game_info *info)
14111426
{
1427+
bool load_result = true;
1428+
14121429
netretropad_check_variables();
14131430
open_UDP_socket();
14141431

14151432
/* If a .ratst file is given (only possible via command line),
14161433
* initialize test sequence. */
14171434
if (info)
1418-
input_test_file_read(info->path);
1435+
load_result = input_test_file_read(info->path);
1436+
14191437
if (last_test_step > MAX_TEST_STEPS)
14201438
current_test_step = last_test_step;
14211439
else
@@ -1426,7 +1444,25 @@ bool NETRETROPAD_CORE_PREFIX(retro_load_game)(const struct retro_game_info *info
14261444
NETRETROPAD_CORE_PREFIX(environ_cb)(RETRO_ENVIRONMENT_SET_MESSAGE, &message);
14271445
}
14281446

1429-
return true;
1447+
if (!load_result)
1448+
{
1449+
const char msg[] = "Invalid test input file!";
1450+
struct retro_error_message e;
1451+
e.code = RETROE_UNSUPPORTED_CONTENT_FORMAT;
1452+
e.message = msg;
1453+
NETRETROPAD_CORE_PREFIX(environ_cb)(RETRO_ENVIRONMENT_SET_ERROR_CODE, &e);
1454+
}
1455+
1456+
if (false)
1457+
{
1458+
const char msg[] = "Simulated load error - BIOS!";
1459+
struct retro_error_message e;
1460+
e.code = RETROE_MISSING_BIOS | 0x4321;
1461+
e.message = msg;
1462+
NETRETROPAD_CORE_PREFIX(environ_cb)(RETRO_ENVIRONMENT_SET_ERROR_CODE, &e);
1463+
load_result = false;
1464+
}
1465+
return load_result;
14301466
}
14311467

14321468
void NETRETROPAD_CORE_PREFIX(retro_unload_game)(void) { }
@@ -1435,9 +1471,23 @@ bool NETRETROPAD_CORE_PREFIX(retro_load_game_special)(unsigned type,
14351471
const struct retro_game_info *info, size_t num) { return false; }
14361472
size_t NETRETROPAD_CORE_PREFIX(retro_serialize_size)(void) { return 0; }
14371473
bool NETRETROPAD_CORE_PREFIX(retro_serialize)(void *data,
1438-
size_t len) { return false; }
1474+
size_t len)
1475+
{
1476+
struct retro_error_message e;
1477+
e.code = RETROE_UNSUPPORTED_ACTION_SERIALIZE;
1478+
e.message = NULL;
1479+
NETRETROPAD_CORE_PREFIX(environ_cb)(RETRO_ENVIRONMENT_SET_ERROR_CODE, &e);
1480+
return false;
1481+
}
14391482
bool NETRETROPAD_CORE_PREFIX(retro_unserialize)(const void *data,
1440-
size_t len) { return false; }
1483+
size_t len)
1484+
{
1485+
struct retro_error_message e;
1486+
e.code = RETROE_UNSUPPORTED_ACTION_UNSERIALIZE;
1487+
e.message = NULL;
1488+
NETRETROPAD_CORE_PREFIX(environ_cb)(RETRO_ENVIRONMENT_SET_ERROR_CODE, &e);
1489+
return false;
1490+
}
14411491
size_t NETRETROPAD_CORE_PREFIX(retro_get_memory_size)(
14421492
unsigned id) { return 0; }
14431493
void NETRETROPAD_CORE_PREFIX(retro_cheat_reset)(void) { }

intl/msg_hash_us.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,69 @@ int msg_hash_get_help_us_enum(enum msg_hash_enums msg, char *s, size_t len)
517517
}
518518
#endif
519519

520+
#define ERROR_CODE_CASE(CODE) \
521+
case CODE :\
522+
return strlcpy(s, msg_hash_to_str(MSG_##CODE), len);\
523+
break;
524+
525+
int msg_hash_get_error_msg_us_enum(enum retro_error err, char *s, size_t len)
526+
{
527+
settings_t *settings = config_get_ptr();
528+
529+
switch (err & RETROE_MASK_FRONTEND)
530+
{
531+
ERROR_CODE_CASE(RETROE_UNSUPPORTED_CONTENT)
532+
ERROR_CODE_CASE(RETROE_UNSUPPORTED_CONTENT_ISO_FORMAT_ERROR)
533+
ERROR_CODE_CASE(RETROE_UNSUPPORTED_CONTENT_CHD_FORMAT_ERROR)
534+
ERROR_CODE_CASE(RETROE_UNSUPPORTED_CONTENT_CUE_FORMAT_ERROR)
535+
ERROR_CODE_CASE(RETROE_UNSUPPORTED_CONTENT_BIN_FORMAT_ERROR)
536+
ERROR_CODE_CASE(RETROE_UNSUPPORTED_CONTENT_ZIP_FORMAT_ERROR)
537+
ERROR_CODE_CASE(RETROE_UNSUPPORTED_CONTENT_7Z_FORMAT_ERROR)
538+
ERROR_CODE_CASE(RETROE_UNSUPPORTED_CONTENT_FORMAT)
539+
ERROR_CODE_CASE(RETROE_MISSING_BIOS)
540+
ERROR_CODE_CASE(RETROE_MISSING_BIOS_REGION_PAL)
541+
ERROR_CODE_CASE(RETROE_MISSING_BIOS_REGION_NTSC)
542+
ERROR_CODE_CASE(RETROE_MISSING_BIOS_REGION_WORLD)
543+
ERROR_CODE_CASE(RETROE_MISSING_BIOS_REGION_USA)
544+
ERROR_CODE_CASE(RETROE_MISSING_BIOS_REGION_JAPAN)
545+
ERROR_CODE_CASE(RETROE_MISSING_BIOS_REGION_EUROPE)
546+
ERROR_CODE_CASE(RETROE_MISSING_BIOS_REGION_BRAZIL)
547+
ERROR_CODE_CASE(RETROE_MISSING_BIOS_REGION_COUNTRY)
548+
ERROR_CODE_CASE(RETROE_MISSING_SYSTEM_FILES)
549+
ERROR_CODE_CASE(RETROE_HARDWARE_RENDERING)
550+
ERROR_CODE_CASE(RETROE_HARDWARE_RENDERING_VULKAN_NOT_AVAILABLE)
551+
ERROR_CODE_CASE(RETROE_HARDWARE_RENDERING_VULKAN_VERSION_ERROR)
552+
ERROR_CODE_CASE(RETROE_HARDWARE_RENDERING_OPENGL_NOT_AVAILABLE)
553+
ERROR_CODE_CASE(RETROE_HARDWARE_RENDERING_OPENGL_VERSION_ERROR)
554+
ERROR_CODE_CASE(RETROE_HARDWARE_RENDERING_DX11_NOT_AVAILABLE)
555+
ERROR_CODE_CASE(RETROE_HARDWARE_RENDERING_DX12_NOT_AVAILABLE)
556+
ERROR_CODE_CASE(RETROE_HARDWARE_RENDERING_PXFMT_XRGB8888_UNSUPP)
557+
ERROR_CODE_CASE(RETROE_HARDWARE_RENDERING_PXFMT_RGB565_UNSUPP)
558+
ERROR_CODE_CASE(RETROE_UNSUPPORTED_ACTION)
559+
ERROR_CODE_CASE(RETROE_UNSUPPORTED_ACTION_SERIALIZE)
560+
ERROR_CODE_CASE(RETROE_UNSUPPORTED_ACTION_UNSERIALIZE)
561+
ERROR_CODE_CASE(RETROE_UNSUPPORTED_ACTION_UNSERIALIZE_FORMAT)
562+
ERROR_CODE_CASE(RETROE_UNSUPPORTED_ACTION_CORE_OPTION_COMBI)
563+
564+
default:
565+
if ( err > RETROE_UNSUPPORTED_CONTENT &&
566+
err < RETROE_UNSUPPORTED_CONTENT_RANGE_END)
567+
return strlcpy(s, msg_hash_to_str(MSG_RETROE_UNSUPPORTED_CONTENT), len);
568+
else if ( err > RETROE_MISSING_BIOS &&
569+
err < RETROE_MISSING_BIOS_RANGE_END)
570+
return strlcpy(s, msg_hash_to_str(MSG_RETROE_MISSING_BIOS), len);
571+
else if ( err > RETROE_HARDWARE_RENDERING &&
572+
err < RETROE_HARDWARE_RENDERING_RANGE_END)
573+
return strlcpy(s, msg_hash_to_str(MSG_RETROE_HARDWARE_RENDERING), len);
574+
else if ( err > RETROE_UNSUPPORTED_ACTION &&
575+
err < RETROE_UNSUPPORTED_ACTION_RANGE_END)
576+
return strlcpy(s, msg_hash_to_str(MSG_RETROE_UNSUPPORTED_ACTION), len);
577+
else
578+
return strlcpy(s, msg_hash_to_str(MSG_RETROE_UNKNOWN), len);
579+
}
580+
return 0;
581+
}
582+
520583
#ifdef HAVE_MENU
521584
static const char *menu_hash_to_str_us_label_enum(enum msg_hash_enums msg)
522585
{

intl/msg_hash_us.h

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17194,6 +17194,138 @@ MSG_HASH(
1719417194
MSG_AI_SERVICE_STOPPED,
1719517195
"stopped."
1719617196
)
17197+
MSG_HASH(
17198+
MSG_RETROE_UNKNOWN,
17199+
"Unknown error code received from core."
17200+
)
17201+
MSG_HASH(
17202+
MSG_RETROE_UNSUPPORTED_CONTENT,
17203+
"This core does not support this kind of content."
17204+
)
17205+
MSG_HASH(
17206+
MSG_RETROE_UNSUPPORTED_CONTENT_ISO_FORMAT_ERROR,
17207+
"This core does not support the specific ISO format of this content."
17208+
)
17209+
MSG_HASH(
17210+
MSG_RETROE_UNSUPPORTED_CONTENT_CHD_FORMAT_ERROR,
17211+
"This core does not support the specific CHD format of this content."
17212+
)
17213+
MSG_HASH(
17214+
MSG_RETROE_UNSUPPORTED_CONTENT_CUE_FORMAT_ERROR,
17215+
"This core does not support the specific CUE format of this content."
17216+
)
17217+
MSG_HASH(
17218+
MSG_RETROE_UNSUPPORTED_CONTENT_BIN_FORMAT_ERROR,
17219+
"This core does not support the specific BIN format of this content."
17220+
)
17221+
MSG_HASH(
17222+
MSG_RETROE_UNSUPPORTED_CONTENT_ZIP_FORMAT_ERROR,
17223+
"This core does not support the specific ZIP format of this content."
17224+
)
17225+
MSG_HASH(
17226+
MSG_RETROE_UNSUPPORTED_CONTENT_7Z_FORMAT_ERROR,
17227+
"This core does not support the specific 7Z format of this content."
17228+
)
17229+
MSG_HASH(
17230+
MSG_RETROE_UNSUPPORTED_CONTENT_FORMAT,
17231+
"This core does not support the specific format of this content."
17232+
)
17233+
MSG_HASH(
17234+
MSG_RETROE_MISSING_BIOS,
17235+
"Necessary BIOS file(s) to run this content are not present."
17236+
)
17237+
MSG_HASH(
17238+
MSG_RETROE_MISSING_BIOS_REGION_PAL,
17239+
"Necessary PAL region BIOS file(s) to run this content are not present."
17240+
)
17241+
MSG_HASH(
17242+
MSG_RETROE_MISSING_BIOS_REGION_NTSC,
17243+
"Necessary NTSC region BIOS file(s) to run this content are not present."
17244+
)
17245+
MSG_HASH(
17246+
MSG_RETROE_MISSING_BIOS_REGION_WORLD,
17247+
"Necessary world region BIOS file(s) to run this content are not present."
17248+
)
17249+
MSG_HASH(
17250+
MSG_RETROE_MISSING_BIOS_REGION_USA,
17251+
"Necessary USA region BIOS file(s) to run this content are not present."
17252+
)
17253+
MSG_HASH(
17254+
MSG_RETROE_MISSING_BIOS_REGION_JAPAN,
17255+
"Necessary Japan region BIOS file(s) to run this content are not present."
17256+
)
17257+
MSG_HASH(
17258+
MSG_RETROE_MISSING_BIOS_REGION_EUROPE,
17259+
"Necessary Europe region BIOS file(s) to run this content are not present."
17260+
)
17261+
MSG_HASH(
17262+
MSG_RETROE_MISSING_BIOS_REGION_BRAZIL,
17263+
"Necessary Brazil region BIOS file(s) to run this content are not present."
17264+
)
17265+
MSG_HASH(
17266+
MSG_RETROE_MISSING_BIOS_REGION_COUNTRY,
17267+
"Necessary country specific BIOS file(s) to run this content are not present."
17268+
)
17269+
MSG_HASH(
17270+
MSG_RETROE_MISSING_SYSTEM_FILES,
17271+
"Necessary system file(s) to run this content are not present, they may be retrieved with the online updater."
17272+
)
17273+
MSG_HASH(
17274+
MSG_RETROE_HARDWARE_RENDERING,
17275+
"This core would require a hardware rendering feature that is not available."
17276+
)
17277+
MSG_HASH(
17278+
MSG_RETROE_HARDWARE_RENDERING_VULKAN_NOT_AVAILABLE,
17279+
"This core would require Vulkan rendering that is not available."
17280+
)
17281+
MSG_HASH(
17282+
MSG_RETROE_HARDWARE_RENDERING_VULKAN_VERSION_ERROR,
17283+
"This core would require a Vulkan rendering version that is not available."
17284+
)
17285+
MSG_HASH(
17286+
MSG_RETROE_HARDWARE_RENDERING_OPENGL_NOT_AVAILABLE,
17287+
"This core would require OpenGL rendering that is not available."
17288+
)
17289+
MSG_HASH(
17290+
MSG_RETROE_HARDWARE_RENDERING_OPENGL_VERSION_ERROR,
17291+
"This core would require an OpenGL rendering version that is not available."
17292+
)
17293+
MSG_HASH(
17294+
MSG_RETROE_HARDWARE_RENDERING_DX11_NOT_AVAILABLE,
17295+
"This core would require DirectX 11 rendering that is not available."
17296+
)
17297+
MSG_HASH(
17298+
MSG_RETROE_HARDWARE_RENDERING_DX12_NOT_AVAILABLE,
17299+
"This core would require DirectX 12 rendering that is not available."
17300+
)
17301+
MSG_HASH(
17302+
MSG_RETROE_HARDWARE_RENDERING_PXFMT_XRGB8888_UNSUPP,
17303+
"This core would require pixel format XRGB8888 that is not available."
17304+
)
17305+
MSG_HASH(
17306+
MSG_RETROE_HARDWARE_RENDERING_PXFMT_RGB565_UNSUPP,
17307+
"This core would require pixel format RGB565 that is not available."
17308+
)
17309+
MSG_HASH(
17310+
MSG_RETROE_UNSUPPORTED_ACTION,
17311+
"This core does not support this action."
17312+
)
17313+
MSG_HASH(
17314+
MSG_RETROE_UNSUPPORTED_ACTION_SERIALIZE,
17315+
"This core does not support serialization (save states)."
17316+
)
17317+
MSG_HASH(
17318+
MSG_RETROE_UNSUPPORTED_ACTION_UNSERIALIZE,
17319+
"This core does not support unserialization (save state loading)."
17320+
)
17321+
MSG_HASH(
17322+
MSG_RETROE_UNSUPPORTED_ACTION_UNSERIALIZE_FORMAT,
17323+
"Error encountered with save state format."
17324+
)
17325+
MSG_HASH(
17326+
MSG_RETROE_UNSUPPORTED_ACTION_CORE_OPTION_COMBI,
17327+
"This combination of core options is invalid."
17328+
)
1719717329
#ifdef HAVE_GAME_AI
1719817330
MSG_HASH(
1719917331
MENU_ENUM_LABEL_VALUE_GAME_AI_MENU_OPTION,

0 commit comments

Comments
 (0)