/* RetroArch - A frontend for libretro. * Copyright (C) 2011-2016 - Daniel De Matteis * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. * * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with RetroArch. * If not, see . */ #include #include #include #include #include #include #include #include #include #include "../core.h" #include "../msg_hash.h" #include "../verbosity.h" #include "tasks_internal.h" /* TODO/FIXME - turn this into actual task */ struct ram_type { const char *path; int type; }; /** * content_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. */ bool content_load_ram_file(unsigned slot) { ssize_t rc; ram_type_t ram; retro_ctx_memory_info_t mem_info; global_t *global = global_get_ptr(); void *buf = NULL; ram.path = global->savefiles->elems[slot].data; ram.type = global->savefiles->elems[slot].attr.i; mem_info.id = ram.type; core_get_memory(&mem_info); if (mem_info.size == 0 || !mem_info.data) return false; if (!filestream_read_file(ram.path, &buf, &rc)) return false; if (rc > 0) { if (rc > (ssize_t)mem_info.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)mem_info.size); rc = mem_info.size; } memcpy(mem_info.data, buf, rc); } if (buf) free(buf); return true; } /** * content_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. * */ bool content_save_ram_file(unsigned slot) { retro_ctx_memory_info_t mem_info; ram_type_t ram; global_t *global = global_get_ptr(); if (!global) return false; ram.type = global->savefiles->elems[slot].attr.i; ram.path = global->savefiles->elems[slot].data; mem_info.id = ram.type; core_get_memory(&mem_info); if (!mem_info.data || mem_info.size == 0) return false; RARCH_LOG("%s #%u %s \"%s\".\n", msg_hash_to_str(MSG_SAVING_RAM_TYPE), ram.type, msg_hash_to_str(MSG_TO), ram.path); if (!filestream_write_file(ram.path, mem_info.data, mem_info.size)) { RARCH_ERR("%s.\n", msg_hash_to_str(MSG_FAILED_TO_SAVE_SRAM)); RARCH_WARN("Attempting to recover ...\n"); /* In case the file could not be written to, * the fallback function 'dump_to_file_desperate' * will be called. */ if (!dump_to_file_desperate(mem_info.data, mem_info.size, ram.type)) { RARCH_WARN("Failed ... Cannot recover save file.\n"); } return false; } RARCH_LOG("%s \"%s\".\n", msg_hash_to_str(MSG_SAVED_SUCCESSFULLY_TO), ram.path); return true; }