static void event_init_autosave(void) { unsigned i; settings_t *settings = config_get_ptr(); global_t *global = global_get_ptr(); if (settings->autosave_interval < 1 || !global->savefiles) return; if (!(global->autosave = (autosave_t**)calloc(global->savefiles->size, sizeof(*global->autosave)))) return; global->num_autosave = global->savefiles->size; for (i = 0; i < global->savefiles->size; i++) { const char *path = global->savefiles->elems[i].data; unsigned type = global->savefiles->elems[i].attr.i; if (pretro_get_memory_size(type) <= 0) continue; global->autosave[i] = autosave_new(path, pretro_get_memory_data(type), pretro_get_memory_size(type), settings->autosave_interval); if (!global->autosave[i]) RARCH_WARN(RETRO_LOG_INIT_AUTOSAVE_FAILED); } }
static bool get_info(netplay_t *handle) { uint32_t header[3]; if (!recv_all(handle->fd, header, sizeof(header))) { RARCH_ERR("Failed to receive header from client.\n"); return false; } if (g_extern.cart_crc != ntohl(header[0])) { RARCH_ERR("Cart CRC32s differ. Cannot use different games.\n"); return false; } if (implementation_magic_value() != ntohl(header[1])) { RARCH_ERR("Implementations differ, make sure you're using exact same libretro implementations and RetroArch version.\n"); return false; } if (pretro_get_memory_size(RETRO_MEMORY_SAVE_RAM) != ntohl(header[2])) { RARCH_ERR("Cartridge SRAM sizes do not correspond.\n"); return false; } if (!get_nickname(handle, handle->fd)) { RARCH_ERR("Failed to get nickname from client.\n"); return false; } // Send SRAM data to our Player 2. const void *sram = pretro_get_memory_data(RETRO_MEMORY_SAVE_RAM); unsigned sram_size = pretro_get_memory_size(RETRO_MEMORY_SAVE_RAM); if (!send_all(handle->fd, sram, sram_size)) { RARCH_ERR("Failed to send SRAM data to client.\n"); return false; } if (!send_nickname(handle, handle->fd)) { RARCH_ERR("Failed to send nickname to client.\n"); return false; } #ifndef HAVE_SOCKET_LEGACY log_connection(&handle->other_addr, 0, handle->other_nick); #endif return true; }
/** * load_ram_file: * @path : path of RAM state that will be loaded from. * @type : type of memory * * Load a RAM state from disk to memory. */ void load_ram_file(const char *path, int type) { ssize_t rc; bool ret = false; void *buf = NULL; size_t size = pretro_get_memory_size(type); void *data = pretro_get_memory_data(type); if (size == 0 || !data) return; ret = read_file(path, &buf, &rc); if (!ret) return; if (rc > 0) { if (rc > (ssize_t)size) { RARCH_WARN("SRAM is larger than implementation expects, doing partial load (truncating %u %s %s %u).\n", (unsigned)rc, msg_hash_to_str(MSG_BYTES), msg_hash_to_str(MSG_TO), (unsigned)size); rc = size; } memcpy(data, buf, rc); } if (buf) free(buf); }
static bool send_info(netplay_t *handle) { uint32_t header[3] = { htonl(g_extern.cart_crc), htonl(implementation_magic_value()), htonl(pretro_get_memory_size(RETRO_MEMORY_SAVE_RAM)) }; if (!send_all(handle->fd, header, sizeof(header))) return false; if (!send_nickname(handle, handle->fd)) { RARCH_ERR("Failed to send nick to host.\n"); return false; } // Get SRAM data from Player 1. void *sram = pretro_get_memory_data(RETRO_MEMORY_SAVE_RAM); unsigned sram_size = pretro_get_memory_size(RETRO_MEMORY_SAVE_RAM); if (!recv_all(handle->fd, sram, sram_size)) { RARCH_ERR("Failed to receive SRAM data from host.\n"); return false; } if (!get_nickname(handle, handle->fd)) { RARCH_ERR("Failed to receive nick from host.\n"); return false; } char msg[512]; snprintf(msg, sizeof(msg), "Connected to: \"%s\"", handle->other_nick); RARCH_LOG("%s\n", msg); msg_queue_push(g_extern.msg_queue, msg, 1, 180); return true; }
static bool gl_cg_load_imports(cg_shader_data_t *cg) { unsigned i; struct state_tracker_info tracker_info = {0}; if (!cg->cg_shader->variables) return true; for (i = 0; i < cg->cg_shader->variables; i++) { unsigned memtype; switch (cg->cg_shader->variable[i].ram_type) { case RARCH_STATE_WRAM: memtype = RETRO_MEMORY_SYSTEM_RAM; break; default: memtype = -1u; } if ((memtype != -1u) && (cg->cg_shader->variable[i].addr >= pretro_get_memory_size(memtype))) { RARCH_ERR("Address out of bounds.\n"); return false; } } tracker_info.wram = (uint8_t*) pretro_get_memory_data(RETRO_MEMORY_SYSTEM_RAM); tracker_info.info = cg->cg_shader->variable; tracker_info.info_elem = cg->cg_shader->variables; #ifdef HAVE_PYTHON if (*cg->cg_shader->script_path) { tracker_info.script = cg->cg_shader->script_path; tracker_info.script_is_file = true; } tracker_info.script_class = *cg->cg_shader->script_class ? cg->cg_shader->script_class : NULL; #endif cg->state_tracker = state_tracker_init(&tracker_info); if (!cg->state_tracker) RARCH_WARN("Failed to initialize state tracker.\n"); return true; }
void load_ram_file(const char *path, int type) { size_t size = pretro_get_memory_size(type); void *data = pretro_get_memory_data(type); if (size == 0 || !data) return; void *buf = NULL; ssize_t rc = read_file(path, &buf); if (rc > 0 && rc <= (ssize_t)size) memcpy(data, buf, rc); free(buf); }
void save_ram_file(const char *path, int type) { size_t size = pretro_get_memory_size(type); void *data = pretro_get_memory_data(type); if (data && size > 0) { if (!dump_to_file(path, data, size)) { RARCH_ERR("Failed to save SRAM.\n"); RARCH_WARN("Attempting to recover ...\n"); dump_to_file_desperate(data, size, type); } } }
void save_ram_file(const char *path, int type) { size_t size = pretro_get_memory_size(type); void *data = pretro_get_memory_data(type); if (data && size > 0) { if (!write_file(path, data, size)) { RARCH_ERR("Failed to save SRAM.\n"); RARCH_WARN("Attempting to recover ...\n"); dump_to_file_desperate(data, size, type); } else RARCH_LOG("Saved successfully to \"%s\".\n", path); } }
void load_ram_file(const char *path, int type) { size_t size = pretro_get_memory_size(type); void *data = pretro_get_memory_data(type); if (size == 0 || !data) return; void *buf = NULL; ssize_t rc = read_file(path, &buf); if (rc > 0) { if (rc > (ssize_t)size) { RARCH_WARN("SRAM is larger than implementation expects, doing partial load (truncating %u bytes to %u).\n", (unsigned)rc, (unsigned)size); rc = size; } memcpy(data, buf, rc); } free(buf); }
/** * save_ram_file: * @path : path of RAM state that shall be written to. * @type : type of memory * * Save a RAM state from memory to disk. * * In case the file could not be written to, a fallback function * 'dump_to_file_desperate' will be called. */ void save_ram_file(const char *path, int type) { size_t size = pretro_get_memory_size(type); void *data = pretro_get_memory_data(type); if (!data) return; if (size == 0) return; if (!retro_write_file(path, data, size)) { RARCH_ERR("%s.\n", msg_hash_to_str(MSG_FAILED_TO_SAVE_SRAM)); RARCH_WARN("Attempting to recover ...\n"); dump_to_file_desperate(data, size, type); return; } RARCH_LOG("%s \"%s\".\n", msg_hash_to_str(MSG_SAVED_SUCCESSFULLY_TO), path); }
static PyObject* py_read_vram(PyObject *self, PyObject *args) { (void)self; const uint8_t *data = (const uint8_t*)pretro_get_memory_data(RETRO_MEMORY_VIDEO_RAM); if (!data) { Py_INCREF(Py_None); return Py_None; } size_t max = pretro_get_memory_size(RETRO_MEMORY_VIDEO_RAM); unsigned addr; if (!PyArg_ParseTuple(args, "I", &addr)) return NULL; if (addr >= max) { Py_INCREF(Py_None); return Py_None; } return PyLong_FromLong(data[addr]); }
static bool get_import_value(xmlNodePtr ptr) { if (gl_tracker_info_cnt >= MAX_VARIABLES) { RARCH_ERR("Too many import variables ...\n"); return false; } char id[64], semantic[64], wram[64], input[64], bitmask[64], bitequal[64]; xml_get_prop(id, sizeof(id), ptr, "id"); xml_get_prop(semantic, sizeof(semantic), ptr, "semantic"); xml_get_prop(wram, sizeof(wram), ptr, "wram"); xml_get_prop(input, sizeof(input), ptr, "input_slot"); xml_get_prop(bitmask, sizeof(bitmask), ptr, "mask"); xml_get_prop(bitequal, sizeof(bitequal), ptr, "equal"); unsigned memtype; enum state_tracker_type tracker_type; enum state_ram_type ram_type = RARCH_STATE_NONE; uint32_t addr = 0; unsigned mask_value = 0; unsigned mask_equal = 0; if (!*semantic || !*id) { RARCH_ERR("No semantic or ID for import value.\n"); return false; } if (strcmp(semantic, "capture") == 0) tracker_type = RARCH_STATE_CAPTURE; else if (strcmp(semantic, "capture_previous") == 0) tracker_type = RARCH_STATE_CAPTURE_PREV; else if (strcmp(semantic, "transition") == 0) tracker_type = RARCH_STATE_TRANSITION; else if (strcmp(semantic, "transition_count") == 0) tracker_type = RARCH_STATE_TRANSITION_COUNT; else if (strcmp(semantic, "transition_previous") == 0) tracker_type = RARCH_STATE_TRANSITION_PREV; #ifdef HAVE_PYTHON else if (strcmp(semantic, "python") == 0) tracker_type = RARCH_STATE_PYTHON; #endif else { RARCH_ERR("Invalid semantic for import value.\n"); return false; } #ifdef HAVE_PYTHON if (tracker_type != RARCH_STATE_PYTHON) #endif { if (*input) { unsigned slot = strtoul(input, NULL, 0); switch (slot) { case 1: ram_type = RARCH_STATE_INPUT_SLOT1; break; case 2: ram_type = RARCH_STATE_INPUT_SLOT2; break; default: RARCH_ERR("Invalid input slot for import.\n"); return false; } } else if (*wram) { addr = strtoul(wram, NULL, 16); ram_type = RARCH_STATE_WRAM; } else { RARCH_ERR("No RAM address specificed for import value.\n"); return false; } } switch (ram_type) { case RARCH_STATE_WRAM: memtype = RETRO_MEMORY_SYSTEM_RAM; break; default: memtype = -1u; } if ((memtype != -1u) && (addr >= pretro_get_memory_size(memtype))) { RARCH_ERR("Address out of bounds.\n"); return false; } if (*bitmask) mask_value = strtoul(bitmask, NULL, 16); if (*bitequal) mask_equal = strtoul(bitequal, NULL, 16); strlcpy(gl_tracker_info[gl_tracker_info_cnt].id, id, sizeof(gl_tracker_info[0].id)); gl_tracker_info[gl_tracker_info_cnt].addr = addr; gl_tracker_info[gl_tracker_info_cnt].type = tracker_type; gl_tracker_info[gl_tracker_info_cnt].ram_type = ram_type; gl_tracker_info[gl_tracker_info_cnt].mask = mask_value; gl_tracker_info[gl_tracker_info_cnt].equal = mask_equal; gl_tracker_info_cnt++; return true; }
bool load_state(const char *path) { unsigned i; void *buf = NULL; ssize_t size = read_file(path, &buf); RARCH_LOG("Loading state: \"%s\".\n", path); if (size < 0) { RARCH_ERR("Failed to load state from \"%s\".\n", path); return false; } bool ret = true; RARCH_LOG("State size: %u bytes.\n", (unsigned)size); struct sram_block *blocks = NULL; unsigned num_blocks = 0; if (g_settings.block_sram_overwrite && g_extern.savefiles && g_extern.savefiles->size) { RARCH_LOG("Blocking SRAM overwrite.\n"); blocks = (struct sram_block*) calloc(g_extern.savefiles->size, sizeof(*blocks)); if (blocks) { num_blocks = g_extern.savefiles->size; for (i = 0; i < num_blocks; i++) blocks[i].type = g_extern.savefiles->elems[i].attr.i; } } for (i = 0; i < num_blocks; i++) blocks[i].size = pretro_get_memory_size(blocks[i].type); for (i = 0; i < num_blocks; i++) if (blocks[i].size) blocks[i].data = malloc(blocks[i].size); /* Backup current SRAM which is overwritten by unserialize. */ for (i = 0; i < num_blocks; i++) { if (blocks[i].data) { const void *ptr = pretro_get_memory_data(blocks[i].type); if (ptr) memcpy(blocks[i].data, ptr, blocks[i].size); } } ret = pretro_unserialize(buf, size); /* Flush back. */ for (i = 0; i < num_blocks; i++) { if (blocks[i].data) { void *ptr = pretro_get_memory_data(blocks[i].type); if (ptr) memcpy(ptr, blocks[i].data, blocks[i].size); } } for (i = 0; i < num_blocks; i++) free(blocks[i].data); free(blocks); return ret; }
bool load_state(const char *path) { unsigned i; void *buf = NULL; ssize_t size = read_file(path, &buf); RARCH_LOG("Loading state: \"%s\".\n", path); if (size < 0) { RARCH_ERR("Failed to load state from \"%s\".\n", path); return false; } bool ret = true; RARCH_LOG("State size: %u bytes.\n", (unsigned)size); void *block_buf[2] = {NULL, NULL}; int block_type[2] = {-1, -1}; size_t block_size[2] = {0}; if (g_settings.block_sram_overwrite) { RARCH_LOG("Blocking SRAM overwrite.\n"); switch (g_extern.game_type) { case RARCH_CART_NORMAL: block_type[0] = RETRO_MEMORY_SAVE_RAM; block_type[1] = RETRO_MEMORY_RTC; break; case RARCH_CART_BSX: case RARCH_CART_BSX_SLOTTED: block_type[0] = RETRO_MEMORY_SNES_BSX_RAM; block_type[1] = RETRO_MEMORY_SNES_BSX_PRAM; break; case RARCH_CART_SUFAMI: block_type[0] = RETRO_MEMORY_SNES_SUFAMI_TURBO_A_RAM; block_type[1] = RETRO_MEMORY_SNES_SUFAMI_TURBO_B_RAM; break; case RARCH_CART_SGB: block_type[0] = RETRO_MEMORY_SNES_GAME_BOY_RAM; block_type[1] = RETRO_MEMORY_SNES_GAME_BOY_RTC; break; } } for (i = 0; i < 2; i++) if (block_type[i] != -1) block_size[i] = pretro_get_memory_size(block_type[i]); for (i = 0; i < 2; i++) if (block_size[i]) block_buf[i] = malloc(block_size[i]); // Backup current SRAM which is overwritten by unserialize. for (i = 0; i < 2; i++) { if (block_buf[i]) { const void *ptr = pretro_get_memory_data(block_type[i]); if (ptr) memcpy(block_buf[i], ptr, block_size[i]); } } ret = pretro_unserialize(buf, size); // Flush back :D for (i = 0; i < 2 && ret; i++) { if (block_buf[i]) { void *ptr = pretro_get_memory_data(block_type[i]); if (ptr) memcpy(ptr, block_buf[i], block_size[i]); } } for (i = 0; i < 2; i++) if (block_buf[i]) free(block_buf[i]); free(buf); return ret; }
/** * load_state: * @path : path that state will be loaded from. * * Load a state from disk to memory. * * Returns: true if successful, false otherwise. **/ bool load_state(const char *path) { unsigned i; ssize_t size; unsigned num_blocks = 0; void *buf = NULL; struct sram_block *blocks = NULL; settings_t *settings = config_get_ptr(); global_t *global = global_get_ptr(); bool ret = read_file(path, &buf, &size); RARCH_LOG("%s: \"%s\".\n", msg_hash_to_str(MSG_LOADING_STATE), path); if (!ret || size < 0) { RARCH_ERR("%s \"%s\".\n", msg_hash_to_str(MSG_FAILED_TO_LOAD_STATE), path); return false; } RARCH_LOG("%s: %u %s.\n", msg_hash_to_str(MSG_STATE_SIZE), (unsigned)size, msg_hash_to_str(MSG_BYTES)); if (settings->block_sram_overwrite && global->savefiles && global->savefiles->size) { RARCH_LOG("%s.\n", msg_hash_to_str(MSG_BLOCKING_SRAM_OVERWRITE)); blocks = (struct sram_block*) calloc(global->savefiles->size, sizeof(*blocks)); if (blocks) { num_blocks = global->savefiles->size; for (i = 0; i < num_blocks; i++) blocks[i].type = global->savefiles->elems[i].attr.i; } } for (i = 0; i < num_blocks; i++) blocks[i].size = pretro_get_memory_size(blocks[i].type); for (i = 0; i < num_blocks; i++) if (blocks[i].size) blocks[i].data = malloc(blocks[i].size); /* Backup current SRAM which is overwritten by unserialize. */ for (i = 0; i < num_blocks; i++) { if (blocks[i].data) { const void *ptr = pretro_get_memory_data(blocks[i].type); if (ptr) memcpy(blocks[i].data, ptr, blocks[i].size); } } ret = pretro_unserialize(buf, size); /* Flush back. */ for (i = 0; i < num_blocks; i++) { if (blocks[i].data) { void *ptr = pretro_get_memory_data(blocks[i].type); if (ptr) memcpy(ptr, blocks[i].data, blocks[i].size); } } for (i = 0; i < num_blocks; i++) free(blocks[i].data); free(blocks); free(buf); return ret; }