diff --git a/cheevos.c b/cheevos.c index 2c903e2d40..44e9386777 100644 --- a/cheevos.c +++ b/cheevos.c @@ -156,15 +156,6 @@ enum CHEEVOS_DIRTY_ALL = (1 << 9) - 1 }; -typedef struct -{ - unsigned size; - unsigned type; - int bank_id; - unsigned value; - unsigned previous; -} cheevos_var_t; - typedef struct { unsigned type; @@ -605,6 +596,68 @@ static unsigned cheevos_parse_operator(const char **memaddr) return op; } +void cheevos_parse_guest_addr(cheevos_var_t *var, unsigned value) +{ + rarch_system_info_t *system; + runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &system); + + var->bank_id = -1; + var->value = value; + + if (system->mmaps.num_descriptors != 0) + { + const struct retro_memory_descriptor *desc; + const struct retro_memory_descriptor *end; + + if (cheevos_locals.console_id == CHEEVOS_CONSOLE_GAMEBOY_ADVANCE) + { + /* Patch the address to correctly map it to the mmaps */ + if (var->value < 0x8000) + { + /* Internal RAM */ + var->value += 0x3000000; + } + else + { + /* Work RAM */ + var->value += 0x2000000 - 0x8000; + } + } + else if (cheevos_locals.console_id == CHEEVOS_CONSOLE_PC_ENGINE) + { + var->value += 0x1f0000; + } + + desc = system->mmaps.descriptors; + end = desc + system->mmaps.num_descriptors; + + for (; desc < end; desc++) + { + if ((var->value & desc->select) == desc->start) + { + var->bank_id = desc - system->mmaps.descriptors; + var->value = var->value - desc->start + desc->offset; + break; + } + } + } + else + { + unsigned i; + + for (i = 0; i < sizeof(cheevos_locals.meminfo) / sizeof(cheevos_locals.meminfo[0]); i++) + { + if (var->value < cheevos_locals.meminfo[i].size) + { + var->bank_id = i; + break; + } + + var->value -= cheevos_locals.meminfo[i].size; + } + } +} + static void cheevos_parse_var(cheevos_var_t *var, const char **memaddr) { char *end = NULL; @@ -647,63 +700,7 @@ static void cheevos_parse_var(cheevos_var_t *var, const char **memaddr) if ( var->type == CHEEVOS_VAR_TYPE_ADDRESS || var->type == CHEEVOS_VAR_TYPE_DELTA_MEM) { - rarch_system_info_t *system; - runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &system); - - var->bank_id = -1; - - if (system->mmaps.num_descriptors != 0) - { - const struct retro_memory_descriptor *desc; - const struct retro_memory_descriptor *end; - - if (cheevos_locals.console_id == CHEEVOS_CONSOLE_GAMEBOY_ADVANCE) - { - /* Patch the address to correctly map it to the mmaps */ - if (var->value < 0x8000) - { - /* Internal RAM */ - var->value += 0x3000000; - } - else - { - /* Work RAM */ - var->value += 0x2000000 - 0x8000; - } - } - else if (cheevos_locals.console_id == CHEEVOS_CONSOLE_PC_ENGINE) - { - var->value += 0x1f0000; - } - - desc = system->mmaps.descriptors; - end = desc + system->mmaps.num_descriptors; - - for (; desc < end; desc++) - { - if ((var->value & desc->select) == desc->start) - { - var->bank_id = desc - system->mmaps.descriptors; - var->value = var->value - desc->start + desc->offset; - break; - } - } - } - else - { - unsigned i; - - for (i = 0; i < sizeof(cheevos_locals.meminfo) / sizeof(cheevos_locals.meminfo[0]); i++) - { - if (var->value < cheevos_locals.meminfo[i].size) - { - var->bank_id = i; - break; - } - - var->value -= cheevos_locals.meminfo[i].size; - } - } + cheevos_parse_guest_addr(var, var->value); #ifdef CHEEVOS_DUMP_ADDRS RARCH_LOG("CHEEVOS var %03d:%08X\n", var->bank_id + 1, var->value); #endif @@ -1072,7 +1069,7 @@ static int cheevos_parse(const char *json) Test all the achievements (call once per frame). *****************************************************************************/ -static const uint8_t *cheevos_get_memory(const cheevos_var_t *var) +uint8_t *cheevos_get_memory(const cheevos_var_t *var) { if (var->bank_id >= 0) { diff --git a/cheevos.h b/cheevos.h index 8642f7cc57..c5d3f529d3 100644 --- a/cheevos.h +++ b/cheevos.h @@ -48,6 +48,19 @@ bool cheevos_set_cheats(void); void cheevos_set_support_cheevos(bool state); + +typedef struct +{ + unsigned size; + unsigned type; + int bank_id; + unsigned value; + unsigned previous; +} cheevos_var_t; + +void cheevos_parse_guest_addr(cheevos_var_t *var, unsigned value); +uint8_t *cheevos_get_memory(const cheevos_var_t *var); + RETRO_END_DECLS #endif /* __RARCH_CHEEVOS_H */ diff --git a/command.c b/command.c index 4a63b47616..9a731ab021 100644 --- a/command.c +++ b/command.c @@ -102,6 +102,33 @@ struct command bool state[RARCH_BIND_LIST_END]; }; +enum cmd_source_t { cmd_none, cmd_stdin, cmd_network }; +static enum cmd_source_t lastcmd_source; +#if defined(HAVE_NETWORK_CMD) && defined(HAVE_NETPLAY) +static int lastcmd_net_fd; +static struct sockaddr_storage lastcmd_net_source; +static socklen_t lastcmd_net_source_len; +#endif + +static bool command_reply(const char * data, size_t len) +{ +#ifdef HAVE_STDIN_CMD + if (lastcmd_source == cmd_stdin) + { + fwrite(data, 1,len, stdout); + return true; + } +#endif +#if defined(HAVE_NETWORK_CMD) && defined(HAVE_NETPLAY) + if (lastcmd_source == cmd_network) + { + sendto(lastcmd_net_fd, data, len, 0, (struct sockaddr*)&lastcmd_net_source, lastcmd_net_source_len); + return true; + } +#endif + return false; +} + struct cmd_map { const char *str; @@ -157,8 +184,77 @@ static bool command_set_shader(const char *arg) return video_driver_set_shader(type, arg); } +static bool command_read_ram(const char *arg) +{ +#ifdef HAVE_CHEEVOS + cheevos_var_t var; + const uint8_t * data; + unsigned nbytes; + int i; + char reply[256]; + strcpy(reply, "READ_CORE_RAM "); + char * reply_at = reply + strlen("READ_CORE_RAM "); + strcpy(reply_at, arg); + + cheevos_parse_guest_addr(&var, strtoul(reply_at, (char**)&reply_at, 16)); + data = cheevos_get_memory(&var); + + if (data) + { + unsigned nbytes = strtol(reply_at, NULL, 10); + + for (i=0;i" }, +#ifdef HAVE_CHEEVOS + { "READ_CORE_RAM", command_read_ram, "
" }, + { "WRITE_CORE_RAM", command_write_ram, "
..." }, +#endif }; static const struct cmd_map map[] = { @@ -182,7 +278,7 @@ static const struct cmd_map map[] = { { "CHEAT_TOGGLE", RARCH_CHEAT_TOGGLE }, { "SCREENSHOT", RARCH_SCREENSHOT }, { "MUTE", RARCH_MUTE }, - { "OSK", RARCH_OSK }, + { "OSK", RARCH_OSK }, { "NETPLAY_FLIP", RARCH_NETPLAY_FLIP }, { "SLOWMOTION", RARCH_SLOWMOTION }, { "VOLUME_UP", RARCH_VOLUME_UP }, @@ -199,6 +295,7 @@ static const struct cmd_map map[] = { { "MENU_RIGHT", RETRO_DEVICE_ID_JOYPAD_RIGHT }, { "MENU_A", RETRO_DEVICE_ID_JOYPAD_A }, { "MENU_B", RETRO_DEVICE_ID_JOYPAD_B }, + { "MENU_B", RETRO_DEVICE_ID_JOYPAD_B }, }; static bool command_get_arg(const char *tok, @@ -264,16 +361,19 @@ static void command_parse_sub_msg(command_t *handle, const char *tok) msg_hash_to_str(MSG_RECEIVED)); } -static void command_parse_msg(command_t *handle, char *buf) +static void command_parse_msg(command_t *handle, char *buf, enum cmd_source_t source) { char *save = NULL; const char *tok = strtok_r(buf, "\n", &save); + lastcmd_source = source; + while (tok) { command_parse_sub_msg(handle, tok); tok = strtok_r(NULL, "\n", &save); } + lastcmd_source = cmd_none; } #if defined(HAVE_NETWORK_CMD) && defined(HAVE_NETPLAY) @@ -449,14 +549,18 @@ static void command_network_poll(command_t *handle) for (;;) { char buf[1024]; + + lastcmd_net_fd = handle->net_fd; + lastcmd_net_source_len = sizeof(lastcmd_net_source); ssize_t ret = recvfrom(handle->net_fd, buf, - sizeof(buf) - 1, 0, NULL, NULL); + sizeof(buf) - 1, 0, (struct sockaddr*)&lastcmd_net_source, &lastcmd_net_source_len); if (ret <= 0) break; buf[ret] = '\0'; - command_parse_msg(handle, buf); + + command_parse_msg(handle, buf, cmd_network); } } #endif @@ -659,7 +763,7 @@ static void command_stdin_poll(command_t *handle) *last_newline++ = '\0'; msg_len = last_newline - handle->stdin_buf; - command_parse_msg(handle, handle->stdin_buf); + command_parse_msg(handle, handle->stdin_buf, cmd_stdin); memmove(handle->stdin_buf, last_newline, handle->stdin_buf_ptr - msg_len);