Пример #1
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;
}
Пример #2
0
static int ReadStateChunk(StateMem *st, SFORMAT *sf, int size)
{
   int temp = st->loc;

   while (st->loc < (temp + size))
   {
      uint32_t recorded_size;	// In bytes
      uint8_t 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);

      SFORMAT *tmp = FindSF((char*)toa + 1, sf);

      if(tmp)
      {
         uint32_t 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
         {
            smem_read(st, (uint8_t *)tmp->v, expected_size);

            if(tmp->flags & MDFNSTATE_BOOL)
            {
               // Converting downwards is necessary for the case of sizeof(bool) > 1
               for(int32_t bool_monster = expected_size - 1; bool_monster >= 0; bool_monster--)
               {
                  ((bool *)tmp->v)[bool_monster] = ((uint8_t *)tmp->v)[bool_monster];
               }
            }
#ifdef MSB_FIRST
            if(tmp->flags & MDFNSTATE_RLSB64)
               Endian_A64_LE_to_NE(tmp->v, expected_size / sizeof(uint64_t));
            else if(tmp->flags & MDFNSTATE_RLSB32)
               Endian_A32_LE_to_NE(tmp->v, expected_size / sizeof(uint32_t));
            else if(tmp->flags & MDFNSTATE_RLSB16)
               Endian_A16_LE_to_NE(tmp->v, expected_size / sizeof(uint16_t));
            else if(tmp->flags & RLSB)
               Endian_V_LE_to_NE(tmp->v, expected_size);
#endif
         }
      }
      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(...)

   assert(st->loc == (temp + size));
   return 1;
}
Пример #3
0
static bool SubWrite(StateMem *st, SFORMAT *sf, const char *name_prefix = NULL)
{
   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 struct.	*/
      {
         if(!SubWrite(st, (SFORMAT *)sf->v, name_prefix))
            return(0);

         sf++;
         continue;
      }

      int32_t bytesize = sf->size;

      char nameo[1 + 256];
      int slen;

      slen = snprintf(nameo + 1, 256, "%s%s", name_prefix ? name_prefix : "", sf->name);
      nameo[0] = slen;

      if(slen >= 255)
      {
         printf("Warning:  state variable name possibly too long: %s %s %s %d\n", sf->name, name_prefix, nameo, slen);
         slen = 255;
      }

      smem_write(st, nameo, 1 + nameo[0]);
      smem_write32le(st, bytesize);

#ifdef MSB_FIRST
      /* Flip the byte order... */
      if(sf->flags & MDFNSTATE_BOOL)
      {

      }
      else if(sf->flags & MDFNSTATE_RLSB64)
         Endian_A64_NE_to_LE(sf->v, bytesize / sizeof(uint64_t));
      else if(sf->flags & MDFNSTATE_RLSB32)
         Endian_A32_NE_to_LE(sf->v, bytesize / sizeof(uint32_t));
      else if(sf->flags & MDFNSTATE_RLSB16)
         Endian_A16_NE_to_LE(sf->v, bytesize / sizeof(uint16_t));
      else if(sf->flags & RLSB)
         Endian_V_NE_to_LE(sf->v, bytesize);
#endif

      // Special case for the evil bool type, to convert bool to 1-byte elements.
      // Don't do it if we're only saving the raw data.
      if(sf->flags & MDFNSTATE_BOOL)
      {
         for(int32_t bool_monster = 0; bool_monster < bytesize; bool_monster++)
         {
            uint8_t tmp_bool = ((bool *)sf->v)[bool_monster];
            //printf("Bool write: %.31s\n", sf->name);
            smem_write(st, &tmp_bool, 1);
         }
      }
      else
         smem_write(st, (uint8_t *)sf->v, bytesize);

#ifdef MSB_FIRST
      /* Now restore the original byte order. */
      if(sf->flags & MDFNSTATE_BOOL)
      {

      }
      else if(sf->flags & MDFNSTATE_RLSB64)
         Endian_A64_LE_to_NE(sf->v, bytesize / sizeof(uint64_t));
      else if(sf->flags & MDFNSTATE_RLSB32)
         Endian_A32_LE_to_NE(sf->v, bytesize / sizeof(uint32_t));
      else if(sf->flags & MDFNSTATE_RLSB16)
         Endian_A16_LE_to_NE(sf->v, bytesize / sizeof(uint16_t));
      else if(sf->flags & RLSB)
         Endian_V_LE_to_NE(sf->v, bytesize);
#endif
      sf++; 
   }

   return true;
}
Пример #4
0
static int SubWrite(StateMem *st, SFORMAT *sf, int data_only, gzFile fp)
{
	uint32 acc=0;

	// FIXME? It's kind of slow, and we definitely don't want it on with state rewinding...
	//ValidateSFStructure(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 struct. */
		{
			uint32 tmp;

			if(!(tmp=SubWrite(st,(SFORMAT *)sf->v, data_only, fp)))
				return(0);
			acc+=tmp;
			sf++;
			continue;
		}

		if(!data_only)
			acc+=32 + 4; /* Description + size */

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

		acc += bytesize;
		//printf("%d %d %d\n", bytesize, data_only, fp);
		if(st || fp) /* Are we writing or calculating the size of this block? */
		{
			if(!data_only)
			{
				char desco[32];
				int slen = strlen(sf->desc);

				memset(desco, 0, 32);

				if(slen > 32)
				{
					printf("Warning: state variable name too long: %s %d\n", sf->desc, slen);
					slen = 32;
				}

				memcpy(desco, sf->desc, slen);
				smem_write(st, desco, 32);
				smem_write32le(st, bytesize);

				/* Flip the byte order... */
				if(sf->s & MDFNSTATE_RLSB32)
					Endian_A32_NE_to_LE(sf->v, bytesize / sizeof(uint32));
				else if(sf->s & MDFNSTATE_RLSB16)
					Endian_A16_NE_to_LE(sf->v, bytesize / sizeof(uint16));
				else if(sf->s&RLSB)
					Endian_V_NE_to_LE(sf->v, bytesize);
			}

			if(fp)
			{
				//printf("Wrote: %d\n", bytesize);
				gzwrite(fp, sf->v, bytesize);
			}
			else
			{
				smem_write(st, (uint8 *)sf->v, bytesize);
			}

			if(!data_only)
			{
				/* Now restore the original byte order. */
				if(sf->s & MDFNSTATE_RLSB32)
					Endian_A32_LE_to_NE(sf->v, bytesize / sizeof(uint32));
				else if(sf->s & MDFNSTATE_RLSB16)
					Endian_A16_LE_to_NE(sf->v, bytesize / sizeof(uint16));
				else if(sf->s&RLSB)
					Endian_V_LE_to_NE(sf->v, bytesize);
			}
		}
		sf++;
	}

	return(acc);
}
Пример #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 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;
}
Пример #6
0
static bool SubWrite(StateMem *st, SFORMAT *sf, int data_only, const char *name_prefix = NULL)
{
 // FIXME?  It's kind of slow, and we definitely don't want it on with state rewinding...
 //if(!data_only) 
 // ValidateSFStructure(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)~0)		/* Link to another struct.	*/
  {
   if(!SubWrite(st, (SFORMAT *)sf->v, data_only, name_prefix))
    return(0);

   sf++;
   continue;
  }

  int32 bytesize = sf->size;

  // If we're only saving the raw data, and we come across a bool type, we save it as it is in memory, rather than converting it to
  // 1-byte.  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(data_only && (sf->flags & MDFNSTATE_BOOL))
  {
   bytesize *= sizeof(bool);
  }
  
  if(!data_only)
  {
   char nameo[1 + 256];
   int slen;

   slen = snprintf(nameo + 1, 256, "%s%s", name_prefix ? name_prefix : "", sf->name);
   nameo[0] = slen;

   if(slen >= 255)
   {
    printf("Warning:  state variable name possibly too long: %s %s %s %d\n", sf->name, name_prefix, nameo, slen);
    slen = 255;
   }

   smem_write(st, nameo, 1 + nameo[0]);
   smem_write32le(st, bytesize);

   /* Flip the byte order... */
   if(sf->flags & MDFNSTATE_BOOL)
   {

   }
   else if(sf->flags & MDFNSTATE_RLSB64)
    Endian_A64_NE_to_LE(sf->v, bytesize / sizeof(uint64));
   else if(sf->flags & MDFNSTATE_RLSB32)
    Endian_A32_NE_to_LE(sf->v, bytesize / sizeof(uint32));
   else if(sf->flags & MDFNSTATE_RLSB16)
    Endian_A16_NE_to_LE(sf->v, bytesize / sizeof(uint16));
   else if(sf->flags & RLSB)
    Endian_V_NE_to_LE(sf->v, bytesize);
  }
    
  // Special case for the evil bool type, to convert bool to 1-byte elements.
  // Don't do it if we're only saving the raw data.
  if((sf->flags & MDFNSTATE_BOOL) && !data_only)
  {
   for(int32 bool_monster = 0; bool_monster < bytesize; bool_monster++)
   {
    uint8 tmp_bool = ((bool *)sf->v)[bool_monster];
    //printf("Bool write: %.31s\n", sf->name);
    smem_write(st, &tmp_bool, 1);
   }
  }
  else
   smem_write(st, (uint8 *)sf->v, bytesize);

  if(!data_only)
  {
   /* Now restore the original byte order. */
   if(sf->flags & MDFNSTATE_BOOL)
   {

   }
   else if(sf->flags & MDFNSTATE_RLSB64)
    Endian_A64_LE_to_NE(sf->v, bytesize / sizeof(uint64));
   else if(sf->flags & MDFNSTATE_RLSB32)
    Endian_A32_LE_to_NE(sf->v, bytesize / sizeof(uint32));
   else if(sf->flags & MDFNSTATE_RLSB16)
    Endian_A16_LE_to_NE(sf->v, bytesize / sizeof(uint16));
   else if(sf->flags & RLSB)
    Endian_V_LE_to_NE(sf->v, bytesize);
  }
  sf++; 
 }

 return(TRUE);
}
Пример #7
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;
}