Example #1
0
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);
   }
}
Example #2
0
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;
}
Example #3
0
/**
 * 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);
}
Example #4
0
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;
}
Example #5
0
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;
}
Example #6
0
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);
}
Example #7
0
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);
      }
   }
}
Example #8
0
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);
   }
}
Example #9
0
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);
}
Example #10
0
/**
 * 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);
}
Example #11
0
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]);
}
Example #12
0
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;
}
Example #13
0
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;
}
Example #14
0
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;
}
Example #15
0
/**
 * 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;
}