Skip to content

Commit ee4cc43

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 cb69d25 commit ee4cc43

File tree

8 files changed

+593
-9
lines changed

8 files changed

+593
-9
lines changed

cores/libretro-net-retropad/net_retropad_core.c

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,8 @@ static bool input_test_file_read(const char* file_path)
394394
(int)rjson_get_source_line(parser),
395395
(int)rjson_get_source_column(parser),
396396
(*rjson_get_error(parser) ? rjson_get_error(parser) : "format error"));
397+
if (last_test_step > MAX_TEST_STEPS)
398+
last_test_step = 0;
397399
}
398400

399401
/* Free parser */
@@ -412,6 +414,12 @@ static bool input_test_file_read(const char* file_path)
412414
{
413415
NETRETROPAD_CORE_PREFIX(log_cb)(RETRO_LOG_WARN,"[Remote RetroPad]: too long test input json, maximum size: %d\n",MAX_TEST_STEPS);
414416
}
417+
if (last_test_step == 0)
418+
{
419+
NETRETROPAD_CORE_PREFIX(log_cb)(RETRO_LOG_WARN,"[Remote RetroPad]: no steps in input json\n");
420+
success = false;
421+
}
422+
415423
for (current_test_step = 0; current_test_step < last_test_step; current_test_step++)
416424
{
417425
NETRETROPAD_CORE_PREFIX(log_cb)(RETRO_LOG_DEBUG,
@@ -562,7 +570,14 @@ unsigned NETRETROPAD_CORE_PREFIX(retro_api_version)(void)
562570
}
563571

564572
void NETRETROPAD_CORE_PREFIX(retro_set_controller_port_device)(
565-
unsigned port, unsigned device) { }
573+
unsigned port, unsigned device)
574+
{
575+
const char msg[] = "Input device type change is not supported!";
576+
struct retro_error_message e;
577+
e.code = RETROE_UNSUPPORTED_ACTION | ((port & 0xFF) << 8) | (device & 0xFF);
578+
e.message = msg;
579+
NETRETROPAD_CORE_PREFIX(environ_cb)(RETRO_ENVIRONMENT_SET_ERROR_CODE, &e);
580+
}
566581

567582
void NETRETROPAD_CORE_PREFIX(retro_get_system_info)(
568583
struct retro_system_info *info)
@@ -1385,13 +1400,16 @@ void NETRETROPAD_CORE_PREFIX(retro_run)(void)
13851400

13861401
bool NETRETROPAD_CORE_PREFIX(retro_load_game)(const struct retro_game_info *info)
13871402
{
1403+
bool load_result = true;
1404+
13881405
netretropad_check_variables();
13891406
open_UDP_socket();
13901407

13911408
/* If a .ratst file is given (only possible via command line),
13921409
* initialize test sequence. */
13931410
if (info)
1394-
input_test_file_read(info->path);
1411+
load_result = input_test_file_read(info->path);
1412+
13951413
if (last_test_step > MAX_TEST_STEPS)
13961414
current_test_step = last_test_step;
13971415
else
@@ -1402,7 +1420,25 @@ bool NETRETROPAD_CORE_PREFIX(retro_load_game)(const struct retro_game_info *info
14021420
NETRETROPAD_CORE_PREFIX(environ_cb)(RETRO_ENVIRONMENT_SET_MESSAGE, &message);
14031421
}
14041422

1405-
return true;
1423+
if (!load_result)
1424+
{
1425+
const char msg[] = "Invalid test input file!";
1426+
struct retro_error_message e;
1427+
e.code = RETROE_UNSUPPORTED_CONTENT_FORMAT;
1428+
e.message = msg;
1429+
NETRETROPAD_CORE_PREFIX(environ_cb)(RETRO_ENVIRONMENT_SET_ERROR_CODE, &e);
1430+
}
1431+
1432+
if (false)
1433+
{
1434+
const char msg[] = "Simulated load error - BIOS!";
1435+
struct retro_error_message e;
1436+
e.code = RETROE_MISSING_BIOS | 0x4321;
1437+
e.message = msg;
1438+
NETRETROPAD_CORE_PREFIX(environ_cb)(RETRO_ENVIRONMENT_SET_ERROR_CODE, &e);
1439+
load_result = false;
1440+
}
1441+
return load_result;
14061442
}
14071443

14081444
void NETRETROPAD_CORE_PREFIX(retro_unload_game)(void) { }
@@ -1411,9 +1447,23 @@ bool NETRETROPAD_CORE_PREFIX(retro_load_game_special)(unsigned type,
14111447
const struct retro_game_info *info, size_t num) { return false; }
14121448
size_t NETRETROPAD_CORE_PREFIX(retro_serialize_size)(void) { return 0; }
14131449
bool NETRETROPAD_CORE_PREFIX(retro_serialize)(void *data,
1414-
size_t len) { return false; }
1450+
size_t len)
1451+
{
1452+
struct retro_error_message e;
1453+
e.code = RETROE_UNSUPPORTED_ACTION_SERIALIZE;
1454+
e.message = NULL;
1455+
NETRETROPAD_CORE_PREFIX(environ_cb)(RETRO_ENVIRONMENT_SET_ERROR_CODE, &e);
1456+
return false;
1457+
}
14151458
bool NETRETROPAD_CORE_PREFIX(retro_unserialize)(const void *data,
1416-
size_t len) { return false; }
1459+
size_t len)
1460+
{
1461+
struct retro_error_message e;
1462+
e.code = RETROE_UNSUPPORTED_ACTION_UNSERIALIZE;
1463+
e.message = NULL;
1464+
NETRETROPAD_CORE_PREFIX(environ_cb)(RETRO_ENVIRONMENT_SET_ERROR_CODE, &e);
1465+
return false;
1466+
}
14171467
size_t NETRETROPAD_CORE_PREFIX(retro_get_memory_size)(
14181468
unsigned id) { return 0; }
14191469
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
@@ -511,6 +511,69 @@ int msg_hash_get_help_us_enum(enum msg_hash_enums msg, char *s, size_t len)
511511
}
512512
#endif
513513

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

intl/msg_hash_us.h

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16707,6 +16707,138 @@ MSG_HASH(
1670716707
MSG_AI_SERVICE_STOPPED,
1670816708
"stopped."
1670916709
)
16710+
MSG_HASH(
16711+
MSG_RETROE_UNKNOWN,
16712+
"Unknown error code received from core."
16713+
)
16714+
MSG_HASH(
16715+
MSG_RETROE_UNSUPPORTED_CONTENT,
16716+
"This core does not support this kind of content."
16717+
)
16718+
MSG_HASH(
16719+
MSG_RETROE_UNSUPPORTED_CONTENT_ISO_FORMAT_ERROR,
16720+
"This core does not support the specific ISO format of this content."
16721+
)
16722+
MSG_HASH(
16723+
MSG_RETROE_UNSUPPORTED_CONTENT_CHD_FORMAT_ERROR,
16724+
"This core does not support the specific CHD format of this content."
16725+
)
16726+
MSG_HASH(
16727+
MSG_RETROE_UNSUPPORTED_CONTENT_CUE_FORMAT_ERROR,
16728+
"This core does not support the specific CUE format of this content."
16729+
)
16730+
MSG_HASH(
16731+
MSG_RETROE_UNSUPPORTED_CONTENT_BIN_FORMAT_ERROR,
16732+
"This core does not support the specific BIN format of this content."
16733+
)
16734+
MSG_HASH(
16735+
MSG_RETROE_UNSUPPORTED_CONTENT_ZIP_FORMAT_ERROR,
16736+
"This core does not support the specific ZIP format of this content."
16737+
)
16738+
MSG_HASH(
16739+
MSG_RETROE_UNSUPPORTED_CONTENT_7Z_FORMAT_ERROR,
16740+
"This core does not support the specific 7Z format of this content."
16741+
)
16742+
MSG_HASH(
16743+
MSG_RETROE_UNSUPPORTED_CONTENT_FORMAT,
16744+
"This core does not support the specific format of this content."
16745+
)
16746+
MSG_HASH(
16747+
MSG_RETROE_MISSING_BIOS,
16748+
"Necessary BIOS file(s) to run this content are not present."
16749+
)
16750+
MSG_HASH(
16751+
MSG_RETROE_MISSING_BIOS_REGION_PAL,
16752+
"Necessary PAL region BIOS file(s) to run this content are not present."
16753+
)
16754+
MSG_HASH(
16755+
MSG_RETROE_MISSING_BIOS_REGION_NTSC,
16756+
"Necessary NTSC region BIOS file(s) to run this content are not present."
16757+
)
16758+
MSG_HASH(
16759+
MSG_RETROE_MISSING_BIOS_REGION_WORLD,
16760+
"Necessary world region BIOS file(s) to run this content are not present."
16761+
)
16762+
MSG_HASH(
16763+
MSG_RETROE_MISSING_BIOS_REGION_USA,
16764+
"Necessary USA region BIOS file(s) to run this content are not present."
16765+
)
16766+
MSG_HASH(
16767+
MSG_RETROE_MISSING_BIOS_REGION_JAPAN,
16768+
"Necessary Japan region BIOS file(s) to run this content are not present."
16769+
)
16770+
MSG_HASH(
16771+
MSG_RETROE_MISSING_BIOS_REGION_EUROPE,
16772+
"Necessary Europe region BIOS file(s) to run this content are not present."
16773+
)
16774+
MSG_HASH(
16775+
MSG_RETROE_MISSING_BIOS_REGION_BRAZIL,
16776+
"Necessary Brazil region BIOS file(s) to run this content are not present."
16777+
)
16778+
MSG_HASH(
16779+
MSG_RETROE_MISSING_BIOS_REGION_COUNTRY,
16780+
"Necessary country specific BIOS file(s) to run this content are not present."
16781+
)
16782+
MSG_HASH(
16783+
MSG_RETROE_MISSING_SYSTEM_FILES,
16784+
"Necessary system file(s) to run this content are not present, they may be retrieved with the online updater."
16785+
)
16786+
MSG_HASH(
16787+
MSG_RETROE_HARDWARE_RENDERING,
16788+
"This core would require a hardware rendering feature that is not available."
16789+
)
16790+
MSG_HASH(
16791+
MSG_RETROE_HARDWARE_RENDERING_VULKAN_NOT_AVAILABLE,
16792+
"This core would require Vulkan rendering that is not available."
16793+
)
16794+
MSG_HASH(
16795+
MSG_RETROE_HARDWARE_RENDERING_VULKAN_VERSION_ERROR,
16796+
"This core would require a Vulkan rendering version that is not available."
16797+
)
16798+
MSG_HASH(
16799+
MSG_RETROE_HARDWARE_RENDERING_OPENGL_NOT_AVAILABLE,
16800+
"This core would require OpenGL rendering that is not available."
16801+
)
16802+
MSG_HASH(
16803+
MSG_RETROE_HARDWARE_RENDERING_OPENGL_VERSION_ERROR,
16804+
"This core would require an OpenGL rendering version that is not available."
16805+
)
16806+
MSG_HASH(
16807+
MSG_RETROE_HARDWARE_RENDERING_DX11_NOT_AVAILABLE,
16808+
"This core would require DirectX 11 rendering that is not available."
16809+
)
16810+
MSG_HASH(
16811+
MSG_RETROE_HARDWARE_RENDERING_DX12_NOT_AVAILABLE,
16812+
"This core would require DirectX 12 rendering that is not available."
16813+
)
16814+
MSG_HASH(
16815+
MSG_RETROE_HARDWARE_RENDERING_PXFMT_XRGB8888_UNSUPP,
16816+
"This core would require pixel format XRGB8888 that is not available."
16817+
)
16818+
MSG_HASH(
16819+
MSG_RETROE_HARDWARE_RENDERING_PXFMT_RGB565_UNSUPP,
16820+
"This core would require pixel format RGB565 that is not available."
16821+
)
16822+
MSG_HASH(
16823+
MSG_RETROE_UNSUPPORTED_ACTION,
16824+
"This core does not support this action."
16825+
)
16826+
MSG_HASH(
16827+
MSG_RETROE_UNSUPPORTED_ACTION_SERIALIZE,
16828+
"This core does not support serialization (save states)."
16829+
)
16830+
MSG_HASH(
16831+
MSG_RETROE_UNSUPPORTED_ACTION_UNSERIALIZE,
16832+
"This core does not support unserialization (save state loading)."
16833+
)
16834+
MSG_HASH(
16835+
MSG_RETROE_UNSUPPORTED_ACTION_UNSERIALIZE_FORMAT,
16836+
"Error encountered with save state format."
16837+
)
16838+
MSG_HASH(
16839+
MSG_RETROE_UNSUPPORTED_ACTION_CORE_OPTION_COMBI,
16840+
"This combination of core options is invalid."
16841+
)
1671016842
#ifdef HAVE_GAME_AI
1671116843
MSG_HASH(
1671216844
MENU_ENUM_LABEL_VALUE_GAME_AI_MENU_OPTION,

0 commit comments

Comments
 (0)