Example #1
0
static bool bsv_parse_header(const uint32_t *header, uint32_t magic)
{
   uint32_t in_bsv = swap_if_little32(header[MAGIC_INDEX]);
   if (in_bsv != BSV_MAGIC)
   {
      RARCH_ERR("BSV magic mismatch, got 0x%x, expected 0x%x.\n",
            in_bsv, BSV_MAGIC);
      return false;
   }

   uint32_t in_magic = swap_if_big32(header[SERIALIZER_INDEX]);
   if (in_magic != magic)
   {
      RARCH_ERR("Magic mismatch, got 0x%x, expected 0x%x.\n", in_magic, magic);
      return false;
   }

   uint32_t in_crc = swap_if_big32(header[CRC_INDEX]);
   if (in_crc != g_extern.cart_crc)
   {
      RARCH_ERR("CRC32 mismatch, got 0x%x, expected 0x%x.\n", in_crc, g_extern.cart_crc);
      return false;
   }

   uint32_t in_state_size = swap_if_big32(header[STATE_SIZE_INDEX]);
   if (in_state_size != pretro_serialize_size())
   {
      RARCH_ERR("Serialization size mismatch, got 0x%x, expected 0x%x.\n",
            (unsigned)in_state_size, (unsigned)pretro_serialize_size());
      return false;
   }

   return true;
}
Example #2
0
uint32_t *np_bsv_header_generate(size_t *size, uint32_t magic)
{
   uint32_t *header, bsv_header[4] = {0};
   size_t serialize_size = core.retro_serialize_size();
   size_t header_size = sizeof(bsv_header) + serialize_size;
   global_t *global = global_get_ptr();

   *size = header_size;

   header = (uint32_t*)malloc(header_size);
   if (!header)
      return NULL;

   bsv_header[MAGIC_INDEX]      = swap_if_little32(BSV_MAGIC);
   bsv_header[SERIALIZER_INDEX] = swap_if_big32(magic);
   bsv_header[CRC_INDEX]        = swap_if_big32(global->content_crc);
   bsv_header[STATE_SIZE_INDEX] = swap_if_big32(serialize_size);

   if (serialize_size && !core.retro_serialize(header + 4, serialize_size))
   {
      free(header);
      return NULL;
   }

   memcpy(header, bsv_header, sizeof(bsv_header));
   return header;
}
Example #3
0
static uint32_t *bsv_header_generate(size_t *size, uint32_t magic)
{
   uint32_t bsv_header[4] = {0};
   size_t serialize_size = pretro_serialize_size();
   size_t header_size = sizeof(bsv_header) + serialize_size;
   *size = header_size;

   uint32_t *header = (uint32_t*)malloc(header_size);
   if (!header)
      return NULL;

   bsv_header[MAGIC_INDEX] = swap_if_little32(BSV_MAGIC);
   bsv_header[SERIALIZER_INDEX] = swap_if_big32(magic);
   bsv_header[CRC_INDEX] = swap_if_big32(g_extern.cart_crc);
   bsv_header[STATE_SIZE_INDEX] = swap_if_big32(serialize_size);

   if (serialize_size && !pretro_serialize(header + 4, serialize_size))
   {
      free(header);
      return NULL;
   }

   memcpy(header, bsv_header, sizeof(bsv_header));
   return header;
}
Example #4
0
static bool init_playback(bsv_movie_t *handle, const char *path)
{
   uint32_t state_size;
   uint32_t header[4] = {0};
   global_t *global   = global_get_ptr();

   handle->playback   = true;
   handle->file       = fopen(path, "rb");

   if (!handle->file)
   {
      RARCH_ERR("Couldn't open BSV file \"%s\" for playback.\n", path);
      return false;
   }

   if (fread(header, sizeof(uint32_t), 4, handle->file) != 4)
   {
      RARCH_ERR("Couldn't read movie header.\n");
      return false;
   }

   /* Compatibility with old implementation that
    * used incorrect documentation. */
   if (swap_if_little32(header[MAGIC_INDEX]) != BSV_MAGIC
         && swap_if_big32(header[MAGIC_INDEX]) != BSV_MAGIC)
   {
      RARCH_ERR("Movie file is not a valid BSV1 file.\n");
      return false;
   }

   if (swap_if_big32(header[CRC_INDEX]) != global->content_crc)
      RARCH_WARN("CRC32 checksum mismatch between content file and saved content checksum in replay file header; replay highly likely to desync on playback.\n");

   state_size = swap_if_big32(header[STATE_SIZE_INDEX]);

   if (state_size)
   {
      handle->state      = (uint8_t*)malloc(state_size);
      handle->state_size = state_size;
      if (!handle->state)
         return false;

      if (fread(handle->state, 1, state_size, handle->file) != state_size)
      {
         RARCH_ERR("Couldn't read state from movie.\n");
         return false;
      }

      if (core.retro_serialize_size() == state_size)
         core.retro_unserialize(handle->state, state_size);
      else
         RARCH_WARN("Movie format seems to have a different serializer version. Will most likely fail.\n");
   }

   handle->min_file_pos = sizeof(header) + state_size;

   return true;
}
Example #5
0
static int task_database_iterate_crc_lookup(
      database_state_handle_t *db_state,
      database_info_handle_t *db,
      const char *zip_entry)
{

   if (!db_state->list || 
         (unsigned)db_state->list_index == (unsigned)db_state->list->size)
      return database_info_list_iterate_end_no_match(db_state);

   if (db_state->entry_index == 0)
   {
      char query[50] = {0};
      snprintf(query, sizeof(query),
            "{crc:or(b\"%08X\",b\"%08X\")}",
            swap_if_big32(db_state->crc), swap_if_big32(db_state->zip_crc));

      database_info_list_iterate_new(db_state, query);
   }

   if (db_state->info)
   {
      database_info_t *db_info_entry = 
         &db_state->info->list[db_state->entry_index];

      if (db_info_entry && db_info_entry->crc32)
      {
#if 0
         RARCH_LOG("CRC32: 0x%08X , entry CRC32: 0x%08X (%s).\n",
               db_state->crc, db_info_entry->crc32, db_info_entry->name);
#endif
         if (db_state->zip_crc == db_info_entry->crc32)
            return database_info_list_iterate_found_match(
                  db_state, db, NULL);
         if (db_state->crc == db_info_entry->crc32)
            return database_info_list_iterate_found_match(
                  db_state, db, zip_entry);
      }
   }

   db_state->entry_index++;

   if (db_state->info)
   {
      if (db_state->entry_index >= db_state->info->count)
         return database_info_list_iterate_next(db_state);
   }

   /* If we haven't reached the end of the database list yet,
    * continue iterating. */
   if (db_state->list_index < db_state->list->size)
      return 1;

   database_info_list_free(db_state->info);
   return 0;
}
Example #6
0
static bool init_record(bsv_movie_t *handle, const char *path)
{
   retro_ctx_size_info_t info;
   uint32_t state_size;
   uint32_t header[4]        = {0};
   uint32_t *content_crc_ptr = NULL;

   handle->file       = fopen(path, "wb");
   if (!handle->file)
   {
      RARCH_ERR("Couldn't open BSV \"%s\" for recording.\n", path);
      return false;
   }

   content_ctl(CONTENT_CTL_GET_CRC, &content_crc_ptr);

   /* This value is supposed to show up as
    * BSV1 in a HEX editor, big-endian. */
   header[MAGIC_INDEX]      = swap_if_little32(BSV_MAGIC);
   header[CRC_INDEX]        = swap_if_big32(*content_crc_ptr);

   core_ctl(CORE_CTL_RETRO_SERIALIZE_SIZE, &info);

   state_size               = info.size;

   header[STATE_SIZE_INDEX] = swap_if_big32(state_size);

   fwrite(header, 4, sizeof(uint32_t), handle->file);

   handle->min_file_pos     = sizeof(header) + state_size;
   handle->state_size       = state_size;

   if (state_size)
   {
      retro_ctx_serialize_info_t serial_info;

      handle->state = (uint8_t*)malloc(state_size);
      if (!handle->state)
         return false;

      serial_info.data = handle->state;
      serial_info.size = state_size;

      core_ctl(CORE_CTL_RETRO_SERIALIZE, &serial_info);

      fwrite(handle->state, 1, state_size, handle->file);
   }

   return true;
}
Example #7
0
bool np_bsv_parse_header(const uint32_t *header, uint32_t magic)
{
   retro_ctx_size_info_t info;
   uint32_t *content_crc_ptr;
   uint32_t in_crc, in_magic, in_state_size;
   uint32_t in_bsv = swap_if_little32(header[MAGIC_INDEX]);

   if (in_bsv != BSV_MAGIC)
   {
      RARCH_ERR("BSV magic mismatch, got 0x%x, expected 0x%x.\n",
            in_bsv, BSV_MAGIC);
      return false;
   }

   in_magic = swap_if_big32(header[SERIALIZER_INDEX]);
   if (in_magic != magic)
   {
      RARCH_ERR("Magic mismatch, got 0x%x, expected 0x%x.\n", in_magic, magic);
      return false;
   }

   in_crc = swap_if_big32(header[CRC_INDEX]);

   content_ctl(CONTENT_CTL_GET_CRC, &content_crc_ptr);

   if (in_crc != *content_crc_ptr)
   {
      RARCH_ERR("CRC32 mismatch, got 0x%x, expected 0x%x.\n", in_crc,
            *content_crc_ptr);
      return false;
   }

   core_ctl(CORE_CTL_RETRO_SERIALIZE_SIZE, &info);

   in_state_size = swap_if_big32(header[STATE_SIZE_INDEX]);
   if (in_state_size != info.size)
   {
      RARCH_ERR("Serialization size mismatch, got 0x%x, expected 0x%x.\n",
            (unsigned)in_state_size, (unsigned)info.size);
      return false;
   }

   return true;
}
Example #8
0
bool np_bsv_parse_header(const uint32_t *header, uint32_t magic)
{
   uint32_t in_crc, in_magic, in_state_size;
   uint32_t in_bsv = swap_if_little32(header[MAGIC_INDEX]);
   global_t *global = global_get_ptr();

   if (in_bsv != BSV_MAGIC)
   {
      RARCH_ERR("BSV magic mismatch, got 0x%x, expected 0x%x.\n",
            in_bsv, BSV_MAGIC);
      return false;
   }

   in_magic = swap_if_big32(header[SERIALIZER_INDEX]);
   if (in_magic != magic)
   {
      RARCH_ERR("Magic mismatch, got 0x%x, expected 0x%x.\n", in_magic, magic);
      return false;
   }

   in_crc = swap_if_big32(header[CRC_INDEX]);
   if (in_crc != global->content_crc)
   {
      RARCH_ERR("CRC32 mismatch, got 0x%x, expected 0x%x.\n", in_crc,
            global->content_crc);
      return false;
   }

   in_state_size = swap_if_big32(header[STATE_SIZE_INDEX]);
   if (in_state_size != core.retro_serialize_size())
   {
      RARCH_ERR("Serialization size mismatch, got 0x%x, expected 0x%x.\n",
            (unsigned)in_state_size, (unsigned)core.retro_serialize_size());
      return false;
   }

   return true;
}
Example #9
0
uint32_t *np_bsv_header_generate(size_t *size, uint32_t magic)
{
   retro_ctx_serialize_info_t serial_info;
   retro_ctx_size_info_t info;
   uint32_t *content_crc_ptr;
   size_t serialize_size, header_size;
   uint32_t *header, bsv_header[4] = {0};

   core_ctl(CORE_CTL_RETRO_SERIALIZE_SIZE, &info);
   
   serialize_size = info.size;
   header_size    = sizeof(bsv_header) + serialize_size;
   *size          = header_size;
   header         = (uint32_t*)malloc(header_size);
   if (!header)
      goto error;

   content_ctl(CONTENT_CTL_GET_CRC, &content_crc_ptr);

   bsv_header[MAGIC_INDEX]      = swap_if_little32(BSV_MAGIC);
   bsv_header[SERIALIZER_INDEX] = swap_if_big32(magic);
   bsv_header[CRC_INDEX]        = swap_if_big32(*content_crc_ptr);
   bsv_header[STATE_SIZE_INDEX] = swap_if_big32(serialize_size);

   serial_info.data             = header + 4;
   serial_info.size             = serialize_size;

   if (serialize_size && !core_ctl(CORE_CTL_RETRO_SERIALIZE, &serial_info))
      goto error;

   memcpy(header, bsv_header, sizeof(bsv_header));
   return header;

error:
   if (header)
      free(header);
   return NULL;
}
Example #10
0
static bool init_record(bsv_movie_t *handle, const char *path)
{
   uint32_t state_size;
   uint32_t header[4] = {0};
   global_t *global   = global_get_ptr();

   handle->file       = fopen(path, "wb");
   if (!handle->file)
   {
      RARCH_ERR("Couldn't open BSV \"%s\" for recording.\n", path);
      return false;
   }

   /* This value is supposed to show up as
    * BSV1 in a HEX editor, big-endian. */
   header[MAGIC_INDEX]      = swap_if_little32(BSV_MAGIC);
   header[CRC_INDEX]        = swap_if_big32(global->content_crc);
   state_size               = core.retro_serialize_size();
   header[STATE_SIZE_INDEX] = swap_if_big32(state_size);

   fwrite(header, 4, sizeof(uint32_t), handle->file);

   handle->min_file_pos     = sizeof(header) + state_size;
   handle->state_size       = state_size;

   if (state_size)
   {
      handle->state = (uint8_t*)malloc(state_size);
      if (!handle->state)
         return false;

      core.retro_serialize(handle->state, state_size);
      fwrite(handle->state, 1, state_size, handle->file);
   }

   return true;
}
Example #11
0
static int task_database_iterate_crc_lookup(
    database_state_handle_t *db_state,
    database_info_handle_t *db,
    const char *name,
    const char *archive_entry)
{

    if (!db_state->list ||
            (unsigned)db_state->list_index == (unsigned)db_state->list->size)
        return database_info_list_iterate_end_no_match(db_state);

    if (db_state->entry_index == 0)
    {
        bool db_supports_content;
        bool unsupported_content;
        char query[50];

        query[0] = '\0';

        db_supports_content = core_info_database_supports_content_path(db_state->list->elems[db_state->list_index].data, name);
        unsupported_content = core_info_unsupported_content_path(name);

        /* don't scan files that can't be in this database */
        if(!db_supports_content && !unsupported_content)
            return database_info_list_iterate_next(db_state);

        snprintf(query, sizeof(query),
                 "{crc:or(b\"%08X\",b\"%08X\")}",
                 swap_if_big32(db_state->crc), swap_if_big32(db_state->archive_crc));

        database_info_list_iterate_new(db_state, query);
    }

    if (db_state->info)
    {
        database_info_t *db_info_entry =
            &db_state->info->list[db_state->entry_index];

        if (db_info_entry && db_info_entry->crc32)
        {
#if 0
            RARCH_LOG("CRC32: 0x%08X , entry CRC32: 0x%08X (%s).\n",
                      db_state->crc, db_info_entry->crc32, db_info_entry->name);
#endif
            if (db_state->archive_crc == db_info_entry->crc32)
                return database_info_list_iterate_found_match(
                           db_state, db, NULL);
            if (db_state->crc == db_info_entry->crc32)
                return database_info_list_iterate_found_match(
                           db_state, db, archive_entry);
        }
    }

    db_state->entry_index++;

    if (db_state->info)
    {
        if (db_state->entry_index >= db_state->info->count)
            return database_info_list_iterate_next(db_state);
    }

    /* If we haven't reached the end of the database list yet,
     * continue iterating. */
    if (db_state->list_index < db_state->list->size)
        return 1;

    database_info_list_free(db_state->info);

    if (db_state->info)
        free(db_state->info);

    return 0;
}
Example #12
0
static bool init_playback(bsv_movie_t *handle, const char *path)
{
   uint32_t state_size;
   uint32_t *content_crc_ptr = NULL;
   uint32_t header[4]        = {0};

   handle->playback          = true;
   handle->file              = fopen(path, "rb");

   if (!handle->file)
   {
      RARCH_ERR("Couldn't open BSV file \"%s\" for playback.\n", path);
      return false;
   }

   if (fread(header, sizeof(uint32_t), 4, handle->file) != 4)
   {
      RARCH_ERR("Couldn't read movie header.\n");
      return false;
   }

   /* Compatibility with old implementation that
    * used incorrect documentation. */
   if (swap_if_little32(header[MAGIC_INDEX]) != BSV_MAGIC
         && swap_if_big32(header[MAGIC_INDEX]) != BSV_MAGIC)
   {
      RARCH_ERR("Movie file is not a valid BSV1 file.\n");
      return false;
   }

   content_ctl(CONTENT_CTL_GET_CRC, &content_crc_ptr);

   if (swap_if_big32(header[CRC_INDEX]) != *content_crc_ptr)
      RARCH_WARN("CRC32 checksum mismatch between content file and saved content checksum in replay file header; replay highly likely to desync on playback.\n");

   state_size = swap_if_big32(header[STATE_SIZE_INDEX]);

   if (state_size)
   {
      retro_ctx_serialize_info_t serial_info;
      retro_ctx_size_info_t info;

      handle->state      = (uint8_t*)malloc(state_size);
      handle->state_size = state_size;
      if (!handle->state)
         return false;

      if (fread(handle->state, 1, state_size, handle->file) != state_size)
      {
         RARCH_ERR("Couldn't read state from movie.\n");
         return false;
      }

      core_ctl(CORE_CTL_RETRO_SERIALIZE_SIZE, &info);

      if (info.size == state_size)
      {
         serial_info.data_const = handle->state;
         serial_info.size       = state_size;
         core_ctl(CORE_CTL_RETRO_UNSERIALIZE, &serial_info);
      }
      else
         RARCH_WARN("Movie format seems to have a different serializer version. Will most likely fail.\n");
   }

   handle->min_file_pos = sizeof(header) + state_size;

   return true;
}