Beispiel #1
0
static void MakeSFMap(SFORMAT *sf, SFMap_t &sfmap)
{
 while(sf->size || sf->name) // Size can sometimes be zero, so also check for the text name.  These two should both be zero only at the end of a struct.
 {
  if(!sf->size || !sf->v)
  {
   sf++;
   continue;
  }

  if(sf->size == (uint32)~0)            /* Link to another SFORMAT structure. */
   MakeSFMap((SFORMAT *)sf->v, sfmap);
  else
  {
   assert(sf->name);

   if(sfmap.find(sf->name) != sfmap.end())
    printf("Duplicate save state variable in internal emulator structures(CLUB THE PROGRAMMERS WITH BREADSTICKS): %s\n", sf->name);

   sfmap[sf->name] = sf;
  }

  sf++;
 }
}
Beispiel #2
0
static int ReadStateChunk(StateMem *st, SFORMAT *sf, int size, int data_only)
{
 int temp;

 if(data_only)
 {
  DOReadChunk(st, sf);
 }
 else
 {
  SFMap_t sfmap;
  SFMap_t sfmap_found;	// Used for identify variables that are missing in the save state.

  MakeSFMap(sf, sfmap);

  temp = smem_tell(st);
  while(smem_tell(st) < (temp + size))
  {
   uint32 tsize;
   char toa[1 + 256];

   if(smem_read(st, toa, 1) != 1)
   {
    puts("Unexpected EOF");
    return(0);
   }

   if(smem_read(st, toa + 1, toa[0]) != toa[0])
   {
    puts("Unexpected EOF?");
    return 0;
   }

   toa[1 + toa[0]] = 0;

   smem_read32le(st, &tsize);

   SFMap_t::iterator sfmit;

   sfmit = sfmap.find(toa + 1);

   if(sfmit != sfmap.end())
   {
    SFORMAT *tmp = sfmit->second;
    int32 bytesize = tmp->size;

    sfmap_found[tmp->name] = tmp;

    smem_read(st, (uint8 *)tmp->v, bytesize);

    if(tmp->flags & MDFNSTATE_BOOL)
    {
     // Converting downwards is necessary for the case of sizeof(bool) > 1
     for(int32 bool_monster = bytesize - 1; bool_monster >= 0; bool_monster--)
     {
      ((bool *)tmp->v)[bool_monster] = (bool)((uint8 *)tmp->v)[bool_monster];
     }
    }
    if(tmp->flags & MDFNSTATE_RLSB64)
     Endian_A64_LE_to_NE(tmp->v, bytesize / sizeof(uint64));
    else if(tmp->flags & MDFNSTATE_RLSB32)
     Endian_A32_LE_to_NE(tmp->v, bytesize / sizeof(uint32));
    else if(tmp->flags & MDFNSTATE_RLSB16)
     Endian_A16_LE_to_NE(tmp->v, bytesize / sizeof(uint16));
    else if(tmp->flags & RLSB)
     Endian_V_LE_to_NE(tmp->v, bytesize);
   }
   else
   {
    printf("Unknown variable in save state: %s\n", toa + 1);
    if(smem_seek(st, tsize, SEEK_CUR) < 0)
    {
     puts("Seek error");
     return(0);
    }
   }
  } // while(...)

  for(SFMap_t::const_iterator it = sfmap.begin(); it != sfmap.end(); it++)
  {
   if(sfmap_found.find(it->second->name) == sfmap_found.end())
   {
    printf("Variable missing from save state: %s\n", it->second->name);
   }
  }

  assert(smem_tell(st) == (temp + size));
 }
 return 1;
}
Beispiel #3
0
static int ReadStateChunk(StateMem *st, SFORMAT *sf, int size)
{
    int temp;

    {
        SFMap_t sfmap;
        SFMap_t sfmap_found;	// Used for identifying variables that are missing in the save state.

        MakeSFMap(sf, sfmap);

        temp = smem_tell(st);
        while(smem_tell(st) < (temp + size))
        {
            uint32 recorded_size;	// In bytes
            uint8 toa[1 + 256];	// Don't change to char unless cast toa[0] to unsigned to smem_read() and other places.

            if(smem_read(st, toa, 1) != 1)
            {
                puts("Unexpected EOF");
                return(0);
            }

            if(smem_read(st, toa + 1, toa[0]) != toa[0])
            {
                puts("Unexpected EOF?");
                return 0;
            }

            toa[1 + toa[0]] = 0;

            smem_read32le(st, &recorded_size);

            SFMap_t::iterator sfmit;

            sfmit = sfmap.find((char *)toa + 1);

            if(sfmit != sfmap.end())
            {
                SFORMAT *tmp = sfmit->second;
                uint32 expected_size = tmp->size;	// In bytes

                if(recorded_size != expected_size)
                {
                    printf("Variable in save state wrong size: %s.  Need: %d, got: %d\n", toa + 1, expected_size, recorded_size);
                    if(smem_seek(st, recorded_size, SEEK_CUR) < 0)
                    {
                        puts("Seek error");
                        return(0);
                    }
                }
                else
                {
                    sfmap_found[tmp->name] = tmp;

                    smem_read(st, (uint8 *)tmp->v, expected_size);

                    if(tmp->flags & MDFNSTATE_BOOL)
                    {
                        // Converting downwards is necessary for the case of sizeof(bool) > 1
                        for(int32 bool_monster = expected_size - 1; bool_monster >= 0; bool_monster--)
                        {
                            ((bool *)tmp->v)[bool_monster] = ((uint8 *)tmp->v)[bool_monster];
                        }
                    }
                    if(tmp->flags & MDFNSTATE_RLSB64)
                        Endian_A64_LE_to_NE(tmp->v, expected_size / sizeof(uint64));
                    else if(tmp->flags & MDFNSTATE_RLSB32)
                        Endian_A32_LE_to_NE(tmp->v, expected_size / sizeof(uint32));
                    else if(tmp->flags & MDFNSTATE_RLSB16)
                        Endian_A16_LE_to_NE(tmp->v, expected_size / sizeof(uint16));
                    else if(tmp->flags & RLSB)
                        Endian_V_LE_to_NE(tmp->v, expected_size);
                }
            }
            else
            {
                printf("Unknown variable in save state: %s\n", toa + 1);
                if(smem_seek(st, recorded_size, SEEK_CUR) < 0)
                {
                    puts("Seek error");
                    return(0);
                }
            }
        } // while(...)

        for(SFMap_t::const_iterator it = sfmap.begin(); it != sfmap.end(); it++)
        {
            if(sfmap_found.find(it->second->name) == sfmap_found.end())
            {
                printf("Variable missing from save state: %s\n", it->second->name);
            }
        }

        assert(smem_tell(st) == (temp + size));
    }
    return 1;
}
Beispiel #4
0
static void ReadStateChunk(Stream *st, SFORMAT *sf, uint32 size, const bool svbe)
{
 SFMap_t sfmap;
 SFMap_t sfmap_found;	// Used for identifying variables that are missing in the save state.

 MakeSFMap(sf, sfmap);

 uint64 temp = st->tell();
 while(st->tell() < (temp + size))
 {
  uint32 recorded_size;	// In bytes
  uint8 toa[1 + 256];	// Don't change to char unless cast toa[0] to unsigned to smem_read() and other places.

  st->read(toa, 1);
  st->read(toa + 1, toa[0]);

  toa[1 + toa[0]] = 0;

  recorded_size = st->get_LE<uint32>();

  SFMap_t::iterator sfmit;

  sfmit = sfmap.find((char *)toa + 1);

  if(sfmit != sfmap.end())
  {
   SFORMAT *tmp = sfmit->second;
   uint32 expected_size = tmp->size;	// In bytes

   if(recorded_size != expected_size)
   {
    // Don't error out(throw), but still printf-log it.
    printf("Variable in save state wrong size: %s.  Need: %u, got: %u\n", toa + 1, expected_size, recorded_size);
    st->seek(recorded_size, SEEK_CUR);
   }
   else
   {
    sfmap_found[tmp->name] = tmp;

    st->read((uint8 *)tmp->v, expected_size);

    if(tmp->flags & MDFNSTATE_BOOL)
    {
     // Converting downwards is necessary for the case of sizeof(bool) > 1
     for(int32 bool_monster = expected_size - 1; bool_monster >= 0; bool_monster--)
     {
      ((bool *)tmp->v)[bool_monster] = ((uint8 *)tmp->v)[bool_monster];
     }
    }
    else
    {
     if(svbe)
     {
      if(tmp->flags & MDFNSTATE_RLSB64)
       Endian_A64_NE_BE(tmp->v, expected_size / sizeof(uint64));
      else if(tmp->flags & MDFNSTATE_RLSB32)
       Endian_A32_NE_BE(tmp->v, expected_size / sizeof(uint32));
      else if(tmp->flags & MDFNSTATE_RLSB16)
       Endian_A16_NE_BE(tmp->v, expected_size / sizeof(uint16));
      else if(tmp->flags & MDFNSTATE_RLSB)
       Endian_V_NE_BE(tmp->v, expected_size);
     }
     else
     {
      if(tmp->flags & MDFNSTATE_RLSB64)
       Endian_A64_NE_LE(tmp->v, expected_size / sizeof(uint64));
      else if(tmp->flags & MDFNSTATE_RLSB32)
       Endian_A32_NE_LE(tmp->v, expected_size / sizeof(uint32));
      else if(tmp->flags & MDFNSTATE_RLSB16)
       Endian_A16_NE_LE(tmp->v, expected_size / sizeof(uint16));
      else if(tmp->flags & MDFNSTATE_RLSB)
       Endian_V_NE_LE(tmp->v, expected_size);
     }
    }
   }
  }
  else
  {
   printf("Unknown variable in save state: %s\n", toa + 1);
   st->seek(recorded_size, SEEK_CUR);
  }
 } // while(...)

 for(SFMap_t::const_iterator it = sfmap.begin(); it != sfmap.end(); it++)
 {
  if(sfmap_found.find(it->second->name) == sfmap_found.end())
  {
   printf("Variable of bytesize %u missing from save state: %s\n", it->second->size, it->second->name);
  }
 }
}