mirror of
https://github.com/libretro/RetroArch
synced 2025-03-17 10:21:26 +00:00
update to rcheevos 11.3 (#16512)
This commit is contained in:
parent
76b5d40954
commit
2013370aa9
@ -339,8 +339,7 @@ static rcheevos_racheevo_t* rcheevos_find_cheevo(unsigned id)
|
||||
static bool rcheevos_is_game_loaded(void)
|
||||
{
|
||||
#ifdef HAVE_RC_CLIENT
|
||||
const rc_client_game_t* game = rc_client_get_game_info(rcheevos_locals.client);
|
||||
return (game && game->id);
|
||||
return rc_client_is_game_loaded(rcheevos_locals.client);
|
||||
#else
|
||||
return rcheevos_locals.loaded;
|
||||
#endif
|
||||
@ -1189,7 +1188,13 @@ void rcheevos_refresh_memory(void)
|
||||
bool rcheevos_hardcore_active(void)
|
||||
{
|
||||
#ifdef HAVE_RC_CLIENT
|
||||
return rcheevos_locals.client && rc_client_get_hardcore_enabled(rcheevos_locals.client);
|
||||
/* normal hardcore check */
|
||||
if (rcheevos_locals.client && rc_client_get_hardcore_enabled(rcheevos_locals.client))
|
||||
return true;
|
||||
|
||||
/* if we're trying to enable hardcore, pretend it's on so the caller can decide to disable
|
||||
* it (by calling rcheevos_pause_hardcore) before we actually turn it on. */
|
||||
return rcheevos_locals.hardcore_allowed;
|
||||
#else
|
||||
return rcheevos_locals.hardcore_active;
|
||||
#endif
|
||||
|
6
deps/rcheevos/include/rc_client.h
vendored
6
deps/rcheevos/include/rc_client.h
vendored
@ -251,6 +251,11 @@ enum {
|
||||
RC_CLIENT_LOAD_GAME_STATE_ABORTED
|
||||
};
|
||||
|
||||
/**
|
||||
* Determines if a game was successfully identified and loaded.
|
||||
*/
|
||||
RC_EXPORT int RC_CCONV rc_client_is_game_loaded(const rc_client_t* client);
|
||||
|
||||
/**
|
||||
* Unloads the current game.
|
||||
*/
|
||||
@ -266,6 +271,7 @@ typedef struct rc_client_game_t {
|
||||
|
||||
/**
|
||||
* Get information about the current game. Returns NULL if no game is loaded.
|
||||
* NOTE: returns a dummy game record if an unidentified game is loaded.
|
||||
*/
|
||||
RC_EXPORT const rc_client_game_t* RC_CCONV rc_client_get_game_info(const rc_client_t* client);
|
||||
|
||||
|
11
deps/rcheevos/include/rc_client_raintegration.h
vendored
11
deps/rcheevos/include/rc_client_raintegration.h
vendored
@ -27,6 +27,14 @@ typedef struct rc_client_raintegration_menu_t {
|
||||
uint32_t num_items;
|
||||
} rc_client_raintegration_menu_t;
|
||||
|
||||
enum {
|
||||
RC_CLIENT_RAINTEGRATION_ACHIEVEMENT_STATE_NONE = 0,
|
||||
RC_CLIENT_RAINTEGRATION_ACHIEVEMENT_STATE_PUBLISHED = 1,
|
||||
RC_CLIENT_RAINTEGRATION_ACHIEVEMENT_STATE_LOCAL = 2,
|
||||
RC_CLIENT_RAINTEGRATION_ACHIEVEMENT_STATE_MODIFIED = 3,
|
||||
RC_CLIENT_RAINTEGRATION_ACHIEVEMENT_STATE_INSECURE = 4,
|
||||
};
|
||||
|
||||
enum {
|
||||
RC_CLIENT_RAINTEGRATION_EVENT_TYPE_NONE = 0,
|
||||
RC_CLIENT_RAINTEGRATION_EVENT_MENUITEM_CHECKED_CHANGED = 1, /* [menu_item] checked changed */
|
||||
@ -77,11 +85,14 @@ RC_EXPORT int RC_CCONV rc_client_raintegration_activate_menu_item(const rc_clien
|
||||
|
||||
RC_EXPORT void RC_CCONV rc_client_raintegration_set_write_memory_function(rc_client_t* client, rc_client_raintegration_write_memory_func_t handler);
|
||||
RC_EXPORT void RC_CCONV rc_client_raintegration_set_get_game_name_function(rc_client_t* client, rc_client_raintegration_get_game_name_func_t handler);
|
||||
RC_EXPORT void RC_CCONV rc_client_raintegration_set_console_id(rc_client_t* client, uint32_t console_id);
|
||||
RC_EXPORT int RC_CCONV rc_client_raintegration_has_modifications(const rc_client_t* client);
|
||||
|
||||
RC_EXPORT void RC_CCONV rc_client_raintegration_set_event_handler(rc_client_t* client,
|
||||
rc_client_raintegration_event_handler_t handler);
|
||||
|
||||
RC_EXPORT int RC_CCONV rc_client_raintegration_get_achievement_state(const rc_client_t* client, uint32_t achievement_id);
|
||||
|
||||
#endif /* RC_CLIENT_SUPPORTS_RAINTEGRATION */
|
||||
|
||||
RC_END_C_DECLS
|
||||
|
3
deps/rcheevos/include/rc_runtime_types.h
vendored
3
deps/rcheevos/include/rc_runtime_types.h
vendored
@ -175,7 +175,8 @@ enum {
|
||||
RC_OPERATOR_MULT,
|
||||
RC_OPERATOR_DIV,
|
||||
RC_OPERATOR_AND,
|
||||
RC_OPERATOR_XOR
|
||||
RC_OPERATOR_XOR,
|
||||
RC_OPERATOR_MOD
|
||||
};
|
||||
|
||||
typedef struct rc_condition_t rc_condition_t;
|
||||
|
38
deps/rcheevos/src/rc_client.c
vendored
38
deps/rcheevos/src/rc_client.c
vendored
@ -1947,13 +1947,13 @@ static void rc_client_fetch_game_data_callback(const rc_api_server_response_t* s
|
||||
if (!subset->public_.title) {
|
||||
const char* core_subset_title = rc_client_subset_extract_title(load_state->game, load_state->game->public_.title);
|
||||
if (core_subset_title) {
|
||||
rc_client_subset_info_t* scan = load_state->game->subsets;
|
||||
for (; scan; scan = scan->next) {
|
||||
if (scan->public_.title == load_state->game->public_.title) {
|
||||
scan->public_.title = core_subset_title;
|
||||
break;
|
||||
}
|
||||
}
|
||||
scan = load_state->game->subsets;
|
||||
for (; scan; scan = scan->next) {
|
||||
if (scan->public_.title == load_state->game->public_.title) {
|
||||
scan->public_.title = core_subset_title;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
subset->public_.title = rc_buffer_strcpy(&load_state->game->buffer, fetch_game_data_response.title);
|
||||
@ -2058,8 +2058,15 @@ static void rc_client_begin_fetch_game_data(rc_client_load_state_t* load_state)
|
||||
#endif /* RC_CLIENT_SUPPORTS_HASH */
|
||||
|
||||
if (load_state->hash->game_id == 0) {
|
||||
rc_client_subset_info_t* subset;
|
||||
|
||||
subset = (rc_client_subset_info_t*)rc_buffer_alloc(&load_state->game->buffer, sizeof(rc_client_subset_info_t));
|
||||
memset(subset, 0, sizeof(*subset));
|
||||
subset->public_.title = "";
|
||||
|
||||
load_state->game->public_.title = "Unknown Game";
|
||||
load_state->game->public_.badge_name = "";
|
||||
load_state->game->subsets = subset;
|
||||
client->game = load_state->game;
|
||||
load_state->game = NULL;
|
||||
|
||||
@ -2405,6 +2412,23 @@ int rc_client_get_load_game_state(const rc_client_t* client)
|
||||
return state;
|
||||
}
|
||||
|
||||
int rc_client_is_game_loaded(const rc_client_t* client)
|
||||
{
|
||||
const rc_client_game_t* game;
|
||||
|
||||
if (!client)
|
||||
return 0;
|
||||
|
||||
#ifdef RC_CLIENT_SUPPORTS_EXTERNAL
|
||||
if (client->state.external_client && client->state.external_client->get_game_info)
|
||||
game = client->state.external_client->get_game_info();
|
||||
else
|
||||
#endif
|
||||
game = client->game ? &client->game->public_ : NULL;
|
||||
|
||||
return (game && game->id != 0);
|
||||
}
|
||||
|
||||
static void rc_client_game_mark_ui_to_be_hidden(rc_client_t* client, rc_client_game_info_t* game)
|
||||
{
|
||||
rc_client_achievement_info_t* achievement;
|
||||
|
43
deps/rcheevos/src/rc_client_raintegration.c
vendored
43
deps/rcheevos/src/rc_client_raintegration.c
vendored
@ -69,6 +69,7 @@ static void rc_client_raintegration_load_dll(rc_client_t* client,
|
||||
raintegration->get_host_url = (rc_client_raintegration_get_string_func_t)GetProcAddress(hDLL, "_RA_HostUrl");
|
||||
raintegration->init_client = (rc_client_raintegration_init_client_func_t)GetProcAddress(hDLL, "_RA_InitClient");
|
||||
raintegration->init_client_offline = (rc_client_raintegration_init_client_func_t)GetProcAddress(hDLL, "_RA_InitOffline");
|
||||
raintegration->set_console_id = (rc_client_raintegration_set_int_func_t)GetProcAddress(hDLL, "_RA_SetConsoleID");
|
||||
raintegration->shutdown = (rc_client_raintegration_action_func_t)GetProcAddress(hDLL, "_RA_Shutdown");
|
||||
|
||||
raintegration->update_main_window_handle = (rc_client_raintegration_hwnd_action_func_t)GetProcAddress(hDLL, "_RA_UpdateHWnd");
|
||||
@ -80,6 +81,7 @@ static void rc_client_raintegration_load_dll(rc_client_t* client,
|
||||
raintegration->set_get_game_name_function = (rc_client_raintegration_set_get_game_name_func_t)GetProcAddress(hDLL, "_Rcheevos_SetRAIntegrationGetGameNameFunction");
|
||||
raintegration->set_event_handler = (rc_client_raintegration_set_event_handler_func_t)GetProcAddress(hDLL, "_Rcheevos_SetRAIntegrationEventHandler");
|
||||
raintegration->has_modifications = (rc_client_raintegration_get_int_func_t)GetProcAddress(hDLL, "_Rcheevos_HasModifications");
|
||||
raintegration->get_achievement_state = (rc_client_raintegration_get_achievement_state_func_t)GetProcAddress(hDLL, "_Rcheevos_GetAchievementState");
|
||||
|
||||
if (!raintegration->get_version ||
|
||||
!raintegration->init_client ||
|
||||
@ -204,6 +206,7 @@ static void rc_client_init_raintegration(rc_client_t* client,
|
||||
/* attach the external client and call the callback */
|
||||
client->state.external_client = external_client;
|
||||
|
||||
client->state.raintegration->hMainWindow = version_validation_callback_data->main_window_handle;
|
||||
client->state.raintegration->bIsInited = 1;
|
||||
|
||||
version_validation_callback_data->callback(RC_OK, NULL,
|
||||
@ -352,12 +355,14 @@ rc_client_async_handle_t* rc_client_begin_load_raintegration(rc_client_t* client
|
||||
|
||||
void rc_client_raintegration_update_main_window_handle(rc_client_t* client, HWND main_window_handle)
|
||||
{
|
||||
if (client && client->state.raintegration &&
|
||||
client->state.raintegration->bIsInited &&
|
||||
client->state.raintegration->update_main_window_handle)
|
||||
{
|
||||
if (client && client->state.raintegration) {
|
||||
client->state.raintegration->hMainWindow = main_window_handle;
|
||||
|
||||
if (client->state.raintegration->bIsInited &&
|
||||
client->state.raintegration->update_main_window_handle) {
|
||||
client->state.raintegration->update_main_window_handle(main_window_handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rc_client_raintegration_set_write_memory_function(rc_client_t* client, rc_client_raintegration_write_memory_func_t handler)
|
||||
@ -383,26 +388,41 @@ const rc_client_raintegration_menu_t* rc_client_raintegration_get_menu(const rc_
|
||||
{
|
||||
if (!client || !client->state.raintegration ||
|
||||
!client->state.raintegration->bIsInited ||
|
||||
!client->state.raintegration->get_menu)
|
||||
{
|
||||
!client->state.raintegration->get_menu) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return client->state.raintegration->get_menu();
|
||||
}
|
||||
|
||||
void rc_client_raintegration_set_console_id(rc_client_t* client, uint32_t console_id)
|
||||
{
|
||||
if (client && client->state.raintegration && client->state.raintegration->set_console_id)
|
||||
client->state.raintegration->set_console_id(console_id);
|
||||
}
|
||||
|
||||
int rc_client_raintegration_has_modifications(const rc_client_t* client)
|
||||
{
|
||||
if (!client || !client->state.raintegration ||
|
||||
!client->state.raintegration->bIsInited ||
|
||||
!client->state.raintegration->has_modifications)
|
||||
{
|
||||
!client->state.raintegration->bIsInited ||
|
||||
!client->state.raintegration->has_modifications) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return client->state.raintegration->has_modifications();
|
||||
}
|
||||
|
||||
int rc_client_raintegration_get_achievement_state(const rc_client_t* client, uint32_t achievement_id)
|
||||
{
|
||||
if (!client || !client->state.raintegration ||
|
||||
!client->state.raintegration->bIsInited ||
|
||||
!client->state.raintegration->get_achievement_state) {
|
||||
return RC_CLIENT_RAINTEGRATION_ACHIEVEMENT_STATE_NONE;
|
||||
}
|
||||
|
||||
return client->state.raintegration->get_achievement_state(achievement_id);
|
||||
}
|
||||
|
||||
void rc_client_raintegration_rebuild_submenu(rc_client_t* client, HMENU hMenu)
|
||||
{
|
||||
HMENU hPopupMenu = NULL;
|
||||
@ -464,6 +484,9 @@ void rc_client_raintegration_rebuild_submenu(rc_client_t* client, HMENU hMenu)
|
||||
AppendMenuA(hMenu, flags, (UINT_PTR)hPopupMenu, menuText);
|
||||
else
|
||||
ModifyMenuA(hMenu, nIndex, flags | MF_BYPOSITION, (UINT_PTR)hPopupMenu, menuText);
|
||||
|
||||
if (client->state.raintegration->hMainWindow && GetMenu(client->state.raintegration->hMainWindow) == hMenu)
|
||||
DrawMenuBar(client->state.raintegration->hMainWindow);
|
||||
}
|
||||
|
||||
client->state.raintegration->hPopupMenu = hPopupMenu;
|
||||
|
@ -17,16 +17,19 @@ typedef const char* (RC_CCONV* rc_client_raintegration_get_string_func_t)(void);
|
||||
typedef int (RC_CCONV* rc_client_raintegration_init_client_func_t)(HWND hMainWnd, const char* sClientName, const char* sClientVersion);
|
||||
typedef int (RC_CCONV* rc_client_raintegration_get_external_client_func_t)(rc_client_external_t* pClient, int nVersion);
|
||||
typedef void (RC_CCONV* rc_client_raintegration_hwnd_action_func_t)(HWND hWnd);
|
||||
typedef int (RC_CCONV* rc_client_raintegration_get_achievement_state_func_t)(uint32_t nMenuItemId);
|
||||
typedef const rc_client_raintegration_menu_t* (RC_CCONV* rc_client_raintegration_get_menu_func_t)(void);
|
||||
typedef int (RC_CCONV* rc_client_raintegration_activate_menuitem_func_t)(uint32_t nMenuItemId);
|
||||
typedef void (RC_CCONV* rc_client_raintegration_set_write_memory_func_t)(rc_client_t* pClient, rc_client_raintegration_write_memory_func_t handler);
|
||||
typedef void (RC_CCONV* rc_client_raintegration_set_get_game_name_func_t)(rc_client_t* pClient, rc_client_raintegration_get_game_name_func_t handler);
|
||||
typedef void (RC_CCONV* rc_client_raintegration_set_event_handler_func_t)(rc_client_t* pClient, rc_client_raintegration_event_handler_t handler);
|
||||
typedef void (RC_CCONV* rc_client_raintegration_set_int_func_t)(int);
|
||||
typedef int (RC_CCONV* rc_client_raintegration_get_int_func_t)(void);
|
||||
|
||||
typedef struct rc_client_raintegration_t
|
||||
{
|
||||
HINSTANCE hDLL;
|
||||
HWND hMainWindow;
|
||||
HMENU hPopupMenu;
|
||||
uint8_t bIsInited;
|
||||
|
||||
@ -34,6 +37,7 @@ typedef struct rc_client_raintegration_t
|
||||
rc_client_raintegration_get_string_func_t get_host_url;
|
||||
rc_client_raintegration_init_client_func_t init_client;
|
||||
rc_client_raintegration_init_client_func_t init_client_offline;
|
||||
rc_client_raintegration_set_int_func_t set_console_id;
|
||||
rc_client_raintegration_action_func_t shutdown;
|
||||
|
||||
rc_client_raintegration_hwnd_action_func_t update_main_window_handle;
|
||||
@ -44,6 +48,7 @@ typedef struct rc_client_raintegration_t
|
||||
rc_client_raintegration_get_menu_func_t get_menu;
|
||||
rc_client_raintegration_activate_menuitem_func_t activate_menu_item;
|
||||
rc_client_raintegration_get_int_func_t has_modifications;
|
||||
rc_client_raintegration_get_achievement_state_func_t get_achievement_state;
|
||||
|
||||
rc_client_raintegration_get_external_client_func_t get_external_client;
|
||||
|
||||
|
9
deps/rcheevos/src/rcheevos/condition.c
vendored
9
deps/rcheevos/src/rcheevos/condition.c
vendored
@ -139,6 +139,10 @@ static int rc_parse_operator(const char** memaddr) {
|
||||
++(*memaddr);
|
||||
return RC_OPERATOR_XOR;
|
||||
|
||||
case '%':
|
||||
++(*memaddr);
|
||||
return RC_OPERATOR_MOD;
|
||||
|
||||
case '\0':/* end of string */
|
||||
case '_': /* next condition */
|
||||
case 'S': /* next condset */
|
||||
@ -226,6 +230,7 @@ rc_condition_t* rc_parse_condition(const char** memaddr, rc_parse_state_t* parse
|
||||
case RC_OPERATOR_DIV:
|
||||
case RC_OPERATOR_AND:
|
||||
case RC_OPERATOR_XOR:
|
||||
case RC_OPERATOR_MOD:
|
||||
/* modifying operators are only valid on modifying statements */
|
||||
if (can_modify)
|
||||
break;
|
||||
@ -551,5 +556,9 @@ void rc_evaluate_condition_value(rc_typed_value_t* value, rc_condition_t* self,
|
||||
rc_typed_value_convert(&amount, RC_VALUE_TYPE_UNSIGNED);
|
||||
value->value.u32 ^= amount.value.u32;
|
||||
break;
|
||||
|
||||
case RC_OPERATOR_MOD:
|
||||
rc_typed_value_modulus(value, &amount);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
1
deps/rcheevos/src/rcheevos/condset.c
vendored
1
deps/rcheevos/src/rcheevos/condset.c
vendored
@ -87,6 +87,7 @@ rc_condset_t* rc_parse_condset(const char** memaddr, rc_parse_state_t* parse, in
|
||||
case RC_OPERATOR_XOR:
|
||||
case RC_OPERATOR_DIV:
|
||||
case RC_OPERATOR_MULT:
|
||||
case RC_OPERATOR_MOD:
|
||||
case RC_OPERATOR_NONE:
|
||||
/* measuring value. leave required_hits at 0 */
|
||||
break;
|
||||
|
85
deps/rcheevos/src/rcheevos/consoleinfo.c
vendored
85
deps/rcheevos/src/rcheevos/consoleinfo.c
vendored
@ -418,7 +418,7 @@ static const rc_memory_region_t _rc_memory_regions_fairchild_channel_f[] = {
|
||||
};
|
||||
static const rc_memory_regions_t rc_memory_regions_fairchild_channel_f = { _rc_memory_regions_fairchild_channel_f, 4 };
|
||||
|
||||
/* ===== GameBoy / GameBoy Color ===== */
|
||||
/* ===== GameBoy / MegaDuck ===== */
|
||||
static const rc_memory_region_t _rc_memory_regions_gameboy[] = {
|
||||
{ 0x000000U, 0x0000FFU, 0x000000U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Interrupt vector" },
|
||||
{ 0x000100U, 0x00014FU, 0x000100U, RC_MEMORY_TYPE_READONLY, "Cartridge header" },
|
||||
@ -427,8 +427,37 @@ static const rc_memory_region_t _rc_memory_regions_gameboy[] = {
|
||||
{ 0x008000U, 0x0097FFU, 0x008000U, RC_MEMORY_TYPE_VIDEO_RAM, "Tile RAM" },
|
||||
{ 0x009800U, 0x009BFFU, 0x009800U, RC_MEMORY_TYPE_VIDEO_RAM, "BG1 map data" },
|
||||
{ 0x009C00U, 0x009FFFU, 0x009C00U, RC_MEMORY_TYPE_VIDEO_RAM, "BG2 map data" },
|
||||
{ 0x00A000U, 0x00BFFFU, 0x00A000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM"},
|
||||
{ 0x00A000U, 0x00BFFFU, 0x00A000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM (bank 0)"},
|
||||
{ 0x00C000U, 0x00CFFFU, 0x00C000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM (fixed)" },
|
||||
{ 0x00D000U, 0x00DFFFU, 0x00D000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM (fixed)" },
|
||||
{ 0x00E000U, 0x00FDFFU, 0x00C000U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Echo RAM" },
|
||||
{ 0x00FE00U, 0x00FE9FU, 0x00FE00U, RC_MEMORY_TYPE_VIDEO_RAM, "Sprite RAM"},
|
||||
{ 0x00FEA0U, 0x00FEFFU, 0x00FEA0U, RC_MEMORY_TYPE_UNUSED, ""},
|
||||
{ 0x00FF00U, 0x00FF7FU, 0x00FF00U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Hardware I/O"},
|
||||
{ 0x00FF80U, 0x00FFFEU, 0x00FF80U, RC_MEMORY_TYPE_SYSTEM_RAM, "Quick RAM"},
|
||||
{ 0x00FFFFU, 0x00FFFFU, 0x00FFFFU, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Interrupt enable"},
|
||||
|
||||
/* GameBoy's cartridge RAM may have a total of up to 16 banks that can be paged through $A000-$BFFF.
|
||||
* It is desirable to always have access to these extra banks. We do this by expecting the extra banks
|
||||
* to be addressable at addresses not supported by the native system. 0x10000-0x16000 is reserved
|
||||
* for the extra banks of system memory that are exclusive to the GameBoy Color. */
|
||||
{ 0x010000U, 0x015FFFU, 0x010000U, RC_MEMORY_TYPE_UNUSED, "Unused (GameBoy Color exclusive)" },
|
||||
{ 0x016000U, 0x033FFFU, 0x016000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM (banks 1-15)" },
|
||||
};
|
||||
static const rc_memory_regions_t rc_memory_regions_megaduck = { _rc_memory_regions_gameboy, 16 };
|
||||
static const rc_memory_regions_t rc_memory_regions_gameboy = { _rc_memory_regions_gameboy, 18 };
|
||||
|
||||
/* ===== GameBoy Color ===== */
|
||||
static const rc_memory_region_t _rc_memory_regions_gameboy_color[] = {
|
||||
{ 0x000000U, 0x0000FFU, 0x000000U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Interrupt vector" },
|
||||
{ 0x000100U, 0x00014FU, 0x000100U, RC_MEMORY_TYPE_READONLY, "Cartridge header" },
|
||||
{ 0x000150U, 0x003FFFU, 0x000150U, RC_MEMORY_TYPE_READONLY, "Cartridge ROM (fixed)" }, /* bank 0 */
|
||||
{ 0x004000U, 0x007FFFU, 0x004000U, RC_MEMORY_TYPE_READONLY, "Cartridge ROM (paged)" }, /* bank 1-XX (switchable) */
|
||||
{ 0x008000U, 0x0097FFU, 0x008000U, RC_MEMORY_TYPE_VIDEO_RAM, "Tile RAM" },
|
||||
{ 0x009800U, 0x009BFFU, 0x009800U, RC_MEMORY_TYPE_VIDEO_RAM, "BG1 map data" },
|
||||
{ 0x009C00U, 0x009FFFU, 0x009C00U, RC_MEMORY_TYPE_VIDEO_RAM, "BG2 map data" },
|
||||
{ 0x00A000U, 0x00BFFFU, 0x00A000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM (bank 0)"},
|
||||
{ 0x00C000U, 0x00CFFFU, 0x00C000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM (bank 0)" },
|
||||
{ 0x00D000U, 0x00DFFFU, 0x00D000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM (bank 1)" },
|
||||
{ 0x00E000U, 0x00FDFFU, 0x00C000U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Echo RAM" },
|
||||
{ 0x00FE00U, 0x00FE9FU, 0x00FE00U, RC_MEMORY_TYPE_VIDEO_RAM, "Sprite RAM"},
|
||||
@ -437,14 +466,14 @@ static const rc_memory_region_t _rc_memory_regions_gameboy[] = {
|
||||
{ 0x00FF80U, 0x00FFFEU, 0x00FF80U, RC_MEMORY_TYPE_SYSTEM_RAM, "Quick RAM"},
|
||||
{ 0x00FFFFU, 0x00FFFFU, 0x00FFFFU, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Interrupt enable"},
|
||||
|
||||
/* GameBoy Color provides six extra banks of memory that can be paged out through the $DXXX
|
||||
* memory space, but the timing of that does not correspond with blanks, which is when achievements
|
||||
* are processed. As such, it is desirable to always have access to these extra banks. We do this
|
||||
* by expecting the extra banks to be addressable at addresses not supported by the native system. */
|
||||
{ 0x010000U, 0x015FFFU, 0x010000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM (banks 2-7, GBC only)" }
|
||||
/* GameBoy Color provides 6 extra banks of system memory that can be paged out through the $D000-$DFFF,
|
||||
* and the cartridge RAM may have a total of up to 16 banks page through $A000-$BFFF.
|
||||
* It is desirable to always have access to these extra banks. We do this by expecting the extra banks
|
||||
* to be addressable at addresses not supported by the native system. */
|
||||
{ 0x010000U, 0x015FFFU, 0x010000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM (banks 2-7)" },
|
||||
{ 0x016000U, 0x033FFFU, 0x016000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM (banks 1-15)" },
|
||||
};
|
||||
static const rc_memory_regions_t rc_memory_regions_gameboy = { _rc_memory_regions_gameboy, 16 };
|
||||
static const rc_memory_regions_t rc_memory_regions_gameboy_color = { _rc_memory_regions_gameboy, 17 };
|
||||
static const rc_memory_regions_t rc_memory_regions_gameboy_color = { _rc_memory_regions_gameboy_color, 18 };
|
||||
|
||||
/* ===== GameBoy Advance ===== */
|
||||
/* http://problemkaputt.de/gbatek-gba-memory-map.htm */
|
||||
@ -463,11 +492,19 @@ static const rc_memory_region_t _rc_memory_regions_gamecube[] = {
|
||||
static const rc_memory_regions_t rc_memory_regions_gamecube = { _rc_memory_regions_gamecube, 1 };
|
||||
|
||||
/* ===== Game Gear ===== */
|
||||
/* http://www.smspower.org/Development/MemoryMap */
|
||||
/* https://www.smspower.org/Development/MemoryMap */
|
||||
/* https://www.smspower.org/Development/Mappers */
|
||||
static const rc_memory_region_t _rc_memory_regions_game_gear[] = {
|
||||
{ 0x000000U, 0x001FFFU, 0x00C000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
|
||||
{ 0x000000U, 0x001FFFU, 0x00C000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
|
||||
/* GG/SMS have various possible mappings for cartridge memory depending on the mapper used.
|
||||
* However, these ultimately do not map all of their memory at once, typically requiring banking.
|
||||
* Thus, the "real address" used is just a virtual address mapping all cartridge memory in one contiguous block.
|
||||
* Note that this may possibly refer to non-battery backed "extended RAM" so this isn't strictly RC_MEMORY_TYPE_SAVE_RAM.
|
||||
* libretro cores expose "extended RAM" as RETRO_MEMORY_SAVE_RAM regardless however.
|
||||
*/
|
||||
{ 0x002000U, 0x009FFFU, 0x010000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM" }
|
||||
};
|
||||
static const rc_memory_regions_t rc_memory_regions_game_gear = { _rc_memory_regions_game_gear, 1 };
|
||||
static const rc_memory_regions_t rc_memory_regions_game_gear = { _rc_memory_regions_game_gear, 2 };
|
||||
|
||||
/* ===== Intellivision ===== */
|
||||
/* http://wiki.intellivision.us/index.php/Memory_Map */
|
||||
@ -531,14 +568,22 @@ static const rc_memory_region_t _rc_memory_regions_magnavox_odyssey_2[] = {
|
||||
static const rc_memory_regions_t rc_memory_regions_magnavox_odyssey_2 = { _rc_memory_regions_magnavox_odyssey_2, 2 };
|
||||
|
||||
/* ===== Master System ===== */
|
||||
/* http://www.smspower.org/Development/MemoryMap */
|
||||
/* https://www.smspower.org/Development/MemoryMap */
|
||||
/* https://www.smspower.org/Development/Mappers */
|
||||
static const rc_memory_region_t _rc_memory_regions_master_system[] = {
|
||||
{ 0x000000U, 0x001FFFU, 0x00C000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
|
||||
{ 0x000000U, 0x001FFFU, 0x00C000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
|
||||
/* GG/SMS have various possible mappings for cartridge memory depending on the mapper used.
|
||||
* However, these ultimately do not map all of their memory at once, typically requiring banking.
|
||||
* Thus, the "real address" used is just a virtual address mapping all cartridge memory in one contiguous block.
|
||||
* Note that this may possibly refer to non-battery backed "extended RAM" so this isn't strictly RC_MEMORY_TYPE_SAVE_RAM.
|
||||
* libretro cores expose "extended RAM" as RETRO_MEMORY_SAVE_RAM regardless however.
|
||||
*/
|
||||
{ 0x002000U, 0x009FFFU, 0x010000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM" }
|
||||
};
|
||||
static const rc_memory_regions_t rc_memory_regions_master_system = { _rc_memory_regions_master_system, 1 };
|
||||
static const rc_memory_regions_t rc_memory_regions_master_system = { _rc_memory_regions_master_system, 2 };
|
||||
|
||||
/* ===== MegaDrive (Genesis) ===== */
|
||||
/* http://www.smspower.org/Development/MemoryMap */
|
||||
/* https://www.smspower.org/Development/MemoryMap */
|
||||
static const rc_memory_region_t _rc_memory_regions_megadrive[] = {
|
||||
{ 0x000000U, 0x00FFFFU, 0xFF0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
|
||||
{ 0x010000U, 0x01FFFFU, 0x000000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM" }
|
||||
@ -772,7 +817,7 @@ static const rc_memory_region_t _rc_memory_regions_saturn[] = {
|
||||
static const rc_memory_regions_t rc_memory_regions_saturn = { _rc_memory_regions_saturn, 2 };
|
||||
|
||||
/* ===== SG-1000 ===== */
|
||||
/* http://www.smspower.org/Development/MemoryMap */
|
||||
/* https://www.smspower.org/Development/MemoryMap */
|
||||
static const rc_memory_region_t _rc_memory_regions_sg1000[] = {
|
||||
{ 0x000000U, 0x0003FFU, 0xC000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
|
||||
/* https://github.com/libretro/FBNeo/blob/697801c6262be6ca91615cf905444d3e039bc06f/src/burn/drv/sg1000/d_sg1000.cpp#L210-L237 */
|
||||
@ -957,8 +1002,7 @@ const rc_memory_regions_t* rc_console_memory_regions(uint32_t console_id)
|
||||
|
||||
case RC_CONSOLE_FAIRCHILD_CHANNEL_F:
|
||||
return &rc_memory_regions_fairchild_channel_f;
|
||||
|
||||
case RC_CONSOLE_MEGADUCK:
|
||||
|
||||
case RC_CONSOLE_GAMEBOY:
|
||||
return &rc_memory_regions_gameboy;
|
||||
|
||||
@ -989,6 +1033,9 @@ const rc_memory_regions_t* rc_console_memory_regions(uint32_t console_id)
|
||||
case RC_CONSOLE_MEGA_DRIVE:
|
||||
return &rc_memory_regions_megadrive;
|
||||
|
||||
case RC_CONSOLE_MEGADUCK:
|
||||
return &rc_memory_regions_megaduck;
|
||||
|
||||
case RC_CONSOLE_SEGA_32X:
|
||||
return &rc_memory_regions_megadrive_32x;
|
||||
|
||||
|
1
deps/rcheevos/src/rcheevos/rc_internal.h
vendored
1
deps/rcheevos/src/rcheevos/rc_internal.h
vendored
@ -181,6 +181,7 @@ void rc_typed_value_convert(rc_typed_value_t* value, char new_type);
|
||||
void rc_typed_value_add(rc_typed_value_t* value, const rc_typed_value_t* amount);
|
||||
void rc_typed_value_multiply(rc_typed_value_t* value, const rc_typed_value_t* amount);
|
||||
void rc_typed_value_divide(rc_typed_value_t* value, const rc_typed_value_t* amount);
|
||||
void rc_typed_value_modulus(rc_typed_value_t* value, const rc_typed_value_t* amount);
|
||||
void rc_typed_value_negate(rc_typed_value_t* value);
|
||||
int rc_typed_value_compare(const rc_typed_value_t* value1, const rc_typed_value_t* value2, char oper);
|
||||
void rc_typed_value_from_memref_value(rc_typed_value_t* value, const rc_memref_value_t* memref);
|
||||
|
68
deps/rcheevos/src/rcheevos/value.c
vendored
68
deps/rcheevos/src/rcheevos/value.c
vendored
@ -3,6 +3,7 @@
|
||||
#include <string.h> /* memset */
|
||||
#include <ctype.h> /* isdigit */
|
||||
#include <float.h> /* FLT_EPSILON */
|
||||
#include <math.h> /* fmod */
|
||||
|
||||
static void rc_parse_cond_value(rc_value_t* self, const char** memaddr, rc_parse_state_t* parse) {
|
||||
rc_condset_t** next_clause;
|
||||
@ -112,6 +113,7 @@ void rc_parse_legacy_value(rc_value_t* self, const char** memaddr, rc_parse_stat
|
||||
case RC_OPERATOR_DIV:
|
||||
case RC_OPERATOR_AND:
|
||||
case RC_OPERATOR_XOR:
|
||||
case RC_OPERATOR_MOD:
|
||||
case RC_OPERATOR_NONE:
|
||||
break;
|
||||
|
||||
@ -628,6 +630,72 @@ void rc_typed_value_divide(rc_typed_value_t* value, const rc_typed_value_t* amou
|
||||
value->value.f32 /= amount->value.f32;
|
||||
}
|
||||
|
||||
void rc_typed_value_modulus(rc_typed_value_t* value, const rc_typed_value_t* amount) {
|
||||
rc_typed_value_t converted;
|
||||
|
||||
switch (amount->type)
|
||||
{
|
||||
case RC_VALUE_TYPE_UNSIGNED:
|
||||
if (amount->value.u32 == 0) { /* divide by zero */
|
||||
value->type = RC_VALUE_TYPE_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (value->type) {
|
||||
case RC_VALUE_TYPE_UNSIGNED: /* integer math */
|
||||
value->value.u32 %= amount->value.u32;
|
||||
return;
|
||||
case RC_VALUE_TYPE_SIGNED: /* integer math */
|
||||
value->value.i32 %= (int)amount->value.u32;
|
||||
return;
|
||||
case RC_VALUE_TYPE_FLOAT:
|
||||
amount = rc_typed_value_convert_into(&converted, amount, RC_VALUE_TYPE_FLOAT);
|
||||
break;
|
||||
default:
|
||||
value->type = RC_VALUE_TYPE_NONE;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case RC_VALUE_TYPE_SIGNED:
|
||||
if (amount->value.i32 == 0) { /* divide by zero */
|
||||
value->type = RC_VALUE_TYPE_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (value->type) {
|
||||
case RC_VALUE_TYPE_SIGNED: /* integer math */
|
||||
value->value.i32 %= amount->value.i32;
|
||||
return;
|
||||
case RC_VALUE_TYPE_UNSIGNED: /* integer math */
|
||||
value->value.u32 %= (unsigned)amount->value.i32;
|
||||
return;
|
||||
case RC_VALUE_TYPE_FLOAT:
|
||||
amount = rc_typed_value_convert_into(&converted, amount, RC_VALUE_TYPE_FLOAT);
|
||||
break;
|
||||
default:
|
||||
value->type = RC_VALUE_TYPE_NONE;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case RC_VALUE_TYPE_FLOAT:
|
||||
break;
|
||||
|
||||
default:
|
||||
value->type = RC_VALUE_TYPE_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (amount->value.f32 == 0.0) { /* divide by zero */
|
||||
value->type = RC_VALUE_TYPE_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
rc_typed_value_convert(value, RC_VALUE_TYPE_FLOAT);
|
||||
value->value.f32 = (float)fmod(value->value.f32, amount->value.f32);
|
||||
}
|
||||
|
||||
static int rc_typed_value_compare_floats(float f1, float f2, char oper) {
|
||||
if (f1 == f2) {
|
||||
/* exactly equal */
|
||||
|
50
deps/rcheevos/src/rhash/hash.c
vendored
50
deps/rcheevos/src/rhash/hash.c
vendored
@ -11,6 +11,7 @@
|
||||
#if defined(_WIN32)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <share.h>
|
||||
#endif
|
||||
|
||||
/* arbitrary limit to prevent allocating and hashing large files */
|
||||
@ -53,9 +54,9 @@ static void rc_hash_verbose(const char* message)
|
||||
static struct rc_hash_filereader filereader_funcs;
|
||||
static struct rc_hash_filereader* filereader = NULL;
|
||||
|
||||
#if defined(WINVER) && WINVER >= 0x0500
|
||||
static void* filereader_open(const char* path)
|
||||
{
|
||||
#if defined(WINVER) && WINVER >= 0x0500
|
||||
/* Windows requires using wchar APIs for Unicode paths */
|
||||
/* Note that MultiByteToWideChar will only be defined for >= Windows 2000 */
|
||||
wchar_t* wpath;
|
||||
@ -76,21 +77,34 @@ static void* filereader_open(const char* path)
|
||||
free(wpath);
|
||||
return NULL;
|
||||
}
|
||||
#if defined(__STDC_WANT_SECURE_LIB__)
|
||||
_wfopen_s(&fp, wpath, L"rb");
|
||||
#else
|
||||
|
||||
#if defined(__STDC_WANT_SECURE_LIB__)
|
||||
/* have to use _SH_DENYNO because some cores lock the file while its loaded */
|
||||
fp = _wfsopen(wpath, L"rb", _SH_DENYNO);
|
||||
#else
|
||||
fp = _wfopen(wpath, L"rb");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
free(wpath);
|
||||
return fp;
|
||||
#elif defined(__STDC_WANT_SECURE_LIB__)
|
||||
FILE* fp;
|
||||
fopen_s(&fp, path, "rb");
|
||||
return fp;
|
||||
#else
|
||||
return fopen(path, "rb");
|
||||
#endif
|
||||
}
|
||||
#else /* !WINVER >= 0x0500 */
|
||||
static void* filereader_open(const char* path)
|
||||
{
|
||||
#if defined(__STDC_WANT_SECURE_LIB__)
|
||||
#if defined(WINVER)
|
||||
/* have to use _SH_DENYNO because some cores lock the file while its loaded */
|
||||
return _fsopen(path, "rb", _SH_DENYNO);
|
||||
#else /* !WINVER */
|
||||
FILE *fp;
|
||||
fopen_s(&fp, path, "rb");
|
||||
return fp;
|
||||
#endif
|
||||
#else /* !__STDC_WANT_SECURE_LIB__ */
|
||||
return fopen(path, "rb");
|
||||
#endif
|
||||
}
|
||||
#endif /* WINVER >= 0x0500 */
|
||||
|
||||
static void filereader_seek(void* file_handle, int64_t offset, int origin)
|
||||
{
|
||||
@ -2756,6 +2770,14 @@ static int rc_hash_psp(char hash[33], const char* path)
|
||||
uint32_t size;
|
||||
md5_state_t md5;
|
||||
|
||||
/* https://www.psdevwiki.com/psp/PBP
|
||||
* A PBP file is an archive containing the PARAM.SFO, primary executable, and a bunch of metadata.
|
||||
* While we could extract the PARAM.SFO and primary executable to mimic the normal PSP hashing logic,
|
||||
* it's easier to just hash the entire file. This also helps alleviate issues where the primary
|
||||
* executable is just a game engine and the only differentiating data would be the metadata. */
|
||||
if (rc_path_compare_extension(path, "pbp"))
|
||||
return rc_hash_whole_file(hash, path);
|
||||
|
||||
track_handle = rc_cd_open_track(path, 1);
|
||||
if (!track_handle)
|
||||
return rc_hash_error("Could not open track");
|
||||
@ -3772,6 +3794,10 @@ void rc_hash_initialize_iterator(struct rc_hash_iterator* iterator, const char*
|
||||
{
|
||||
iterator->consoles[0] = RC_CONSOLE_PC_ENGINE;
|
||||
}
|
||||
else if (rc_path_compare_extension(ext, "pbp"))
|
||||
{
|
||||
iterator->consoles[0] = RC_CONSOLE_PSP;
|
||||
}
|
||||
else if (rc_path_compare_extension(ext, "pgm"))
|
||||
{
|
||||
iterator->consoles[0] = RC_CONSOLE_ELEKTOR_TV_GAMES_COMPUTER;
|
||||
|
Loading…
x
Reference in New Issue
Block a user