Пример #1
0
// Fast raw chunk reader
static void DOReadChunk(StateMem *st, SFORMAT *sf)
{
   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_t) ~0) // Link to another SFORMAT struct
      {
         DOReadChunk(st, (SFORMAT *)sf->v);
         sf++;
         continue;
      }

      int32_t bytesize = sf->size;

      // Loading raw data, bool types are stored as they appear in memory, not as single bytes in the full state format.
      // In the SFORMAT structure, the size member for bool entries is the number of bool elements, not the total in-memory size,
      // so we adjust it here.
      if(sf->flags & MDFNSTATE_BOOL)
         bytesize *= sizeof(bool);

      smem_read(st, (uint8_t *)sf->v, bytesize);
      sf++;
   }
}
Пример #2
0
static int ReadStateChunk(StateMem *st, SFORMAT *sf, int size, int data_only)
{
	SFORMAT *tmp;
	int temp;

	if(data_only)
	{
		DOReadChunk(st, sf);
	}
	else
	{
		temp = smem_tell(st);
		while(smem_tell(st) < temp + size)
		{
			uint32 tsize;
			char toa[32];

			if(smem_read(st, toa, 32) <= 0)
			{
				puts("Unexpected EOF?");
				return 0;
			}

			smem_read32le(st, &tsize);
			if((tmp=CheckS(sf,tsize,toa)))
			{
				int32 bytesize = tmp->s&(~(MDFNSTATE_RLSB32 | MDFNSTATE_RLSB16 | RLSB));

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

				if(tmp->s & MDFNSTATE_RLSB32)
					Endian_A32_LE_to_NE(tmp->v, bytesize / sizeof(uint32));
				else if(tmp->s & MDFNSTATE_RLSB16)
					Endian_A16_LE_to_NE(tmp->v, bytesize / sizeof(uint16));
				else if(tmp->s&RLSB)
					Endian_V_LE_to_NE(tmp->v, bytesize);
			}
			else
				if(smem_seek(st,tsize,SEEK_CUR) < 0)
				{
					puts("Seek error");
					return(0);
				}
		} // while(...)
	}
	return 1;
}
Пример #3
0
// Fast raw chunk reader
static void DOReadChunk(StateMem *st, SFORMAT *sf)
{
	while(sf->s || sf->desc)// Size can sometimes be zero, so also check for the text description.
		// These two should both be zero only at the end of a struct.
	{
		if(!sf->s || !sf->v)
		{
			sf++;
			continue;
		}

		if(sf->s == (uint32) ~0) // Link to another SFORMAT struct
		{
			DOReadChunk(st, (SFORMAT *)sf->v);
			sf++;
			continue;
		}

		int32 bytesize = sf->s&(~(MDFNSTATE_RLSB32 | MDFNSTATE_RLSB16 | RLSB));

		smem_read(st, (uint8 *)sf->v, bytesize);
		sf++;
	}
}
Пример #4
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;
}
Пример #5
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 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)
   {
	   MDFN_printf("Unexpected EOF");
    return(0);
   }

   if(smem_read(st, toa + 1, toa[0]) != toa[0])
   {
	   MDFN_printf("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)
    {
     MDFN_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)
      {
    	  MDFN_PrintError("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
   {
	   MDFN_printf("Unknown variable in save state: %s\n", toa + 1);
	  if(smem_seek(st, recorded_size, SEEK_CUR) < 0)
    {
    	MDFN_printf("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())
   {
	   MDFN_printf("Variable missing from save state: %s\n", it->second->name);
   }
  }

  assert(smem_tell(st) == (temp + size));
 }
 return 1;
}