static int WriteStateChunk(StateMem *st, const char *sname, SFORMAT *sf)
{
   int32_t data_start_pos;
   int32_t end_pos;

   uint8_t sname_tmp[32];

   memset(sname_tmp, 0, sizeof(sname_tmp));
   strncpy((char *)sname_tmp, sname, 32);

   if(strlen(sname) > 32)
      printf("Warning: section name is too long: %s\n", sname);

   smem_write(st, sname_tmp, 32);

   smem_write32le(st, 0);                // We'll come back and write this later.

   data_start_pos = st->loc;

   if(!SubWrite(st, sf))
      return(0);

   end_pos = st->loc;

   smem_seek(st, data_start_pos - 4, SEEK_SET);
   smem_write32le(st, end_pos - data_start_pos);
   smem_seek(st, end_pos, SEEK_SET);

   return(end_pos - data_start_pos);
}
int MDFNSS_StateAction(void* st_p, int load, SFORMAT* sf, const char* name)
{
   StateMem* st = (StateMem*)st_p;
   if (load)
   {
      char sname[32];

      int found = 0;
      uint32 tmp_size;
      uint32 total = 0;

      while (smem_read(st, (uint8*)sname, 32) == 32)
      {
         if (smem_read32le(st, &tmp_size) != 4)
            return (0);

         total += tmp_size + 32 + 4;

         // Yay, we found the section
         if (!strncmp(sname, name, 32))
         {
            if (!ReadStateChunk(st, sf, tmp_size))
            {
               printf("Error reading chunk: %s\n", name);
               return (0);
            }
            found = 1;
            break;
         }
         else
         {
            if (smem_seek(st, tmp_size, SEEK_CUR) < 0)
            {
               puts("Chunk seek failure");
               return (0);
            }
         }
      }
      if (smem_seek(st, -total, SEEK_CUR) < 0)
      {
         puts("Reverse seek error");
         return (0);
      }
      if (!found) // Not found.  We are sad!
      {
         printf("Section missing:  %.32s\n", name);
         return (0);
      }


   }
   else
   {
      if (!WriteStateChunk(st, name, sf))
         return (0);
   }

   return (1);
}
/* This function is called by the game driver(NES, GB, GBA) to save a state. */
static int MDFNSS_StateAction_internal(void *st_p, int load, int data_only, SSDescriptor *section)
{
   StateMem *st = (StateMem*)st_p;

   if(load)
   {
      char sname[32];

      int found = 0;
      uint32_t tmp_size;
      uint32_t total = 0;

      while(smem_read(st, (uint8_t *)sname, 32) == 32)
      {
         if(smem_read32le(st, &tmp_size) != 4)
            return(0);

         total += tmp_size + 32 + 4;

         // Yay, we found the section
         if(!strncmp(sname, section->name, 32))
         {
            if(!ReadStateChunk(st, section->sf, tmp_size))
            {
               printf("Error reading chunk: %s\n", section->name);
               return(0);
            }
            found = 1;
            break;
         } 
         else
         {
            if(smem_seek(st, tmp_size, SEEK_CUR) < 0)
            {
               puts("Chunk seek failure");
               return(0);
            }
         }
      }
      if(smem_seek(st, -total, SEEK_CUR) < 0)
      {
         puts("Reverse seek error");
         return(0);
      }
      if(!found && !section->optional) // Not found.  We are sad!
      {
         printf("Section missing:  %.32s\n", section->name);
         return(0);
      }
   }
   else
   {
      if(!WriteStateChunk(st, section->name, section->sf))
         return(0);
   }

   return(1);
}
static int WriteStateChunk(StateMem *st, const char *sname, SFORMAT *sf, int data_only)
{
 int32 data_start_pos;
 int32 end_pos;

 if(!data_only)
 {
  uint8 sname_tmp[32];

  memset(sname_tmp, 0, sizeof(sname_tmp));
  strncpy((char *)sname_tmp, sname, 32);

  if(strlen(sname) > 32)
	  MDFN_printf("Warning: section name is too long: %s\n", sname);

  smem_write(st, sname_tmp, 32);

  smem_write32le(st, 0);                // We'll come back and write this later.
 }

 data_start_pos = smem_tell(st);

 if(!SubWrite(st, sf, data_only))
  return(0);

 end_pos = smem_tell(st);

 if(!data_only)
 {
  smem_seek(st, data_start_pos - 4, SEEK_SET);
  smem_write32le(st, end_pos - data_start_pos);
  smem_seek(st, end_pos, SEEK_SET);
 }

 return(end_pos - data_start_pos);
}
Exemple #5
0
int MDFNSS_SaveSM(StateMem *st, int wantpreview, int data_only, uint32 *fb, MDFN_Rect *LineWidths)
{
	static uint8 header[32]="MEDNAFENSVESTATE";
	int neowidth, neoheight;

	neowidth = MDFNGameInfo->ss_preview_width;
	neoheight = MDFNGameInfo->DisplayRect.h;

	if(!data_only)
	{
		memset(header+16,0,16);
		MDFN_en32lsb(header + 12, currFrameCounter);
		MDFN_en32lsb(header + 16, pcejin.lagFrameCounter);
//		MDFN_en32lsb(header + 16, MEDNAFEN_VERSION_NUMERIC);
		MDFN_en32lsb(header + 24, neowidth);
		MDFN_en32lsb(header + 28, neoheight);
		smem_write(st, header, 32);
	}

	if(wantpreview)
	{
		uint8 *previewbuffer = (uint8 *)malloc(17 * neowidth * neoheight);

//		MakeStatePreview(previewbuffer, fb, LineWidths);
		smem_write(st, fb, 17 * neowidth * neoheight);

		free(previewbuffer);
	}

	// State rewinding code path hack, FIXME
	//if(data_only)
	//{
	// if(!MDFN_RawInputStateAction(st, 0, data_only))
	// return(0);
	//}

	if(!MDFNGameInfo->StateAction(st, 0, data_only))
		return(0);

	if(!data_only)
	{
		uint32 sizy = smem_tell(st);
		smem_seek(st, 16 + 4, SEEK_SET);
		smem_write32le(st, sizy);
	}
	return(1);
}
Exemple #6
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;
}
Exemple #7
0
int MDFNSS_LoadSM(StateMem *st, int haspreview, int data_only)
{
	uint8 header[32];
	uint32 stateversion;

	if(data_only)
	{
		stateversion = MEDNAFEN_VERSION_NUMERIC;
	}
	else
	{
		smem_read(st, header, 32);
		// if(memcmp(header,"MEDNAFENSVESTATE",16))
		// return(0);

		stateversion = MDFN_de32lsb(header + 16);

		if(stateversion < 0x0600)
		{
			// printf("State too old: %08x\n", stateversion);
			// return(0);
		}
	}

	currFrameCounter = MDFN_de32lsb(header + 12);
	pcejin.lagFrameCounter = MDFN_de32lsb(header + 16);

	if(haspreview)
	{
		uint32 width = MDFN_de32lsb(header + 24);
		uint32 height = MDFN_de32lsb(header + 28);
		uint32 psize;

		//PREVIEWIMAGE
		psize = width * height * 4;
		smem_seek(st, psize, SEEK_CUR); // Skip preview
	}

	// State rewinding code path hack, FIXME
	if(data_only)
	{
		// if(!MDFN_RawInputStateAction(st, stateversion, data_only))
		return(0);
	}

	return(MDFNGameInfo->StateAction(st, stateversion, data_only));
}
Exemple #8
0
int MDFNSS_LoadSM(StateMem *st, int haspreview, int data_only)
{
        uint8 header[32];
	uint32 stateversion;

	if(data_only)
	{
	 stateversion = MEDNAFEN_VERSION_NUMERIC;
	}
	else
	{
         smem_read(st, header, 32);

         if(memcmp(header, "MEDNAFENSVESTATE", 16) && memcmp(header, "MDFNSVST", 8))
          return(0);

	 stateversion = MDFN_de32lsb(header + 16);
	}

	if(haspreview)
        {
         uint32 width = MDFN_de32lsb(header + 24);
         uint32 height = MDFN_de32lsb(header + 28);
	 uint32 psize;

	 psize = width * height * 3;
	 smem_seek(st, psize, SEEK_CUR);	// Skip preview
 	}

	// State rewinding code path hack, FIXME
	if(data_only)
	{
	 if(!MDFN_RawInputStateAction(st, stateversion, data_only))
	  return(0);
	}

	return(MDFNGameInfo->StateAction(st, stateversion, data_only));
}
int MDFNSS_SaveSM(void *st_p, int, int, const void*, const void*, const void*)
{
   uint8_t header[32];
   StateMem *st = (StateMem*)st_p;
   static const char *header_magic = "MDFNSVST";
   int neowidth = 0, neoheight = 0;

   memset(header, 0, sizeof(header));
   memcpy(header, header_magic, 8);

   MDFN_en32lsb(header + 16, MEDNAFEN_VERSION_NUMERIC);
   MDFN_en32lsb(header + 24, neowidth);
   MDFN_en32lsb(header + 28, neoheight);
   smem_write(st, header, 32);

   if(!StateAction(st, 0, 0))
      return(0);

   uint32_t sizy = st->loc;
   smem_seek(st, 16 + 4, SEEK_SET);
   smem_write32le(st, sizy);

   return(1);
}
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;
}
Exemple #11
0
/* This function is called by the game driver(NES, GB, GBA) to save a state. */
int MDFNSS_StateAction(StateMem *st, int load, int data_only, std::vector <SSDescriptor> &sections)
{
	std::vector<SSDescriptor>::iterator section;

	if(load)
	{
		char sname[4];

		for(section = sections.begin(); section != sections.end(); section++)
		{
			if(data_only)
			{
				ReadStateChunk(st, section->sf, ~0, 1);
			}
			else
			{
				int found = 0;
				uint32 tmp_size;
				uint32 total = 0;
				while(smem_read(st, (uint8 *)sname, 4) == 4)
				{
					if(!smem_read32le(st, &tmp_size)) return(0);
					total += tmp_size + 8;
					// Yay, we found the section
					if(!memcmp(sname, section->name, 4))
					{
						if(!ReadStateChunk(st, section->sf, tmp_size, 0))
						{
							printf("Error reading chunk: %.4s\n", section->name);
							return(0);
						}
						found = 1;
						break;
					}
					else
					{
						//puts("SEEK");
						if(smem_seek(st, tmp_size, SEEK_CUR) < 0)
						{
							puts("Chunk seek failure");
							return(0);
						}
					}
				}
				if(smem_seek(st, -(int)total, SEEK_CUR) < 0)
				{
					puts("Reverse seek error");
					return(0);
				}
				if(!found && !section->optional) // Not found. We are sad!
				{
					printf("Chunk missing: %.4s\n", section->name);
					return(0);
				}
			}
		}
	}
	else
		for(section = sections.begin(); section != sections.end(); section++)
		{
			if(!WriteStateChunk(st, section->name, section->sf, data_only))
				return(0);
		}
		return(1);
}
Exemple #12
0
int MDFNSS_SaveSM(StateMem *st, int wantpreview, int data_only, const MDFN_Surface *surface, const MDFN_Rect *DisplayRect, const MDFN_Rect *LineWidths)
{
	static uint8 header[32]="MEDNAFENSVESTATE";
	int neowidth = 0, neoheight = 0;

	if(wantpreview)
	{
		bool is_multires = FALSE;

		// We'll want to use the nominal width if the source rectangle is > 25% off on either axis, or the source image has
		// multiple horizontal resolutions.
		neowidth = MDFNGameInfo->nominal_width;
		neoheight = MDFNGameInfo->nominal_height;

		if(LineWidths[0].w != ~0)
		{
			uint32 first_w = LineWidths[DisplayRect->y].w;

			for(int y = 0; y < DisplayRect->h; y++)
				if(LineWidths[DisplayRect->y + y].w != first_w)
				{
					puts("Multires!");
					is_multires = TRUE;
				}
		}

		if(!is_multires)
		{
			if(((double)DisplayRect->w / MDFNGameInfo->nominal_width) > 0.75 && ((double)DisplayRect->w / MDFNGameInfo->nominal_width) < 1.25)
				neowidth = DisplayRect->w;

			if(((double)DisplayRect->h / MDFNGameInfo->nominal_height) > 0.75 && ((double)DisplayRect->h / MDFNGameInfo->nominal_height) < 1.25)
				neoheight = DisplayRect->h;
		}
	}

	if(!data_only)
	{
		memset(header+16,0,16);
		MDFN_en32lsb(header + 12, currFrameCounter);
		MDFN_en32lsb(header + 16, pcejin.lagFrameCounter);
		// MDFN_en32lsb(header + 16, MEDNAFEN_VERSION_NUMERIC);
		MDFN_en32lsb(header + 24, neowidth);
		MDFN_en32lsb(header + 28, neoheight);
		smem_write(st, header, 32);
	}

	if(wantpreview)
	{
		/*
		uint8 *previewbuffer = (uint8 *)malloc(4 * neowidth * neoheight);
		MDFN_Surface *dest_surface = new MDFN_Surface((uint32 *)previewbuffer, neowidth, neoheight, neowidth, surface->format.colorspace,
			surface->format.Rshift, surface->format.Gshift, surface->format.Bshift,
			surface->format.Ashift);
		MDFN_Rect dest_rect;

		dest_rect.x = 0;
		dest_rect.y = 0;
		dest_rect.w = neowidth;
		dest_rect.h = neoheight;

		// MDFN_ResizeSurface(surface, DisplayRect, (LineWidths[0].w != ~0) ? LineWidths : NULL, dest_surface, &dest_rect);

		{
			uint32 a, b = 0;
			for(a = 0; a < neowidth * neoheight * 4; a+=4)
			{
				uint32 c = *(uint32 *)&previewbuffer[a];
				int nr, ng, nb;

				surface->DecodeColor(c, nr, ng, nb);

				previewbuffer[b + 0] = nr;
				previewbuffer[b + 1] = ng;
				previewbuffer[b + 2] = nb;
				b += 3;
			}
		}*/
		//PREVIEWIMAGE
		smem_write(st, surface->pixels, 4 * neowidth * neoheight);

//		free(previewbuffer);
//		delete dest_surface;
	}

	// State rewinding code path hack, FIXME
	if(data_only)
	{
		// if(!MDFN_RawInputStateAction(st, 0, data_only))
		return(0);
	}

	if(!MDFNGameInfo->StateAction(st, 0, data_only))
		return(0);

	if(!data_only)
	{
		uint32 sizy = smem_tell(st);
		smem_seek(st, 16 + 4, SEEK_SET);
		smem_write32le(st, sizy);
	}
	return(1);
}
Exemple #13
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;
}
Exemple #14
0
/* This function is called by the game driver(NES, GB, GBA) to save a state. */
int MDFNSS_StateAction(void *st_p, int load, int data_only, std::vector <SSDescriptor> &sections)
{
    StateMem *st = (StateMem*)st_p;
    std::vector<SSDescriptor>::iterator section;

    if(load)
    {
        {
            char sname[32];

            for(section = sections.begin(); section != sections.end(); section++)
            {
                int found = 0;
                uint32 tmp_size;
                uint32 total = 0;

                while(smem_read(st, (uint8 *)sname, 32) == 32)
                {
                    if(smem_read32le(st, &tmp_size) != 4)
                        return(0);

                    total += tmp_size + 32 + 4;

                    // Yay, we found the section
                    if(!strncmp(sname, section->name, 32))
                    {
                        if(!ReadStateChunk(st, section->sf, tmp_size))
                        {
                            printf("Error reading chunk: %s\n", section->name);
                            return(0);
                        }
                        found = 1;
                        break;
                    }
                    else
                    {
                        if(smem_seek(st, tmp_size, SEEK_CUR) < 0)
                        {
                            puts("Chunk seek failure");
                            return(0);
                        }
                    }
                }
                if(smem_seek(st, -total, SEEK_CUR) < 0)
                {
                    puts("Reverse seek error");
                    return(0);
                }
                if(!found && !section->optional) // Not found.  We are sad!
                {
                    printf("Section missing:  %.32s\n", section->name);
                    return(0);
                }
            }
        }
    }
    else
    {
        for(section = sections.begin(); section != sections.end(); section++)
        {
            if(!WriteStateChunk(st, section->name, section->sf))
                return(0);
        }
    }

    return(1);
}
Exemple #15
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;
}
Exemple #16
0
int MDFNSS_SaveSM(StateMem *st, int wantpreview_and_ts, int data_only, const MDFN_Surface *surface, const MDFN_Rect *DisplayRect, const MDFN_Rect *LineWidths)
{
	static const char *header_magic = "MDFNSVST";
  uint8 header[32];
	int neowidth = 0, neoheight = 0;

	memset(header, 0, sizeof(header));

	if(wantpreview_and_ts)
	{
	 bool is_multires = FALSE;

	 // We'll want to use the nominal width if the source rectangle is > 25% off on either axis, or the source image has
	 // multiple horizontal resolutions.
	 neowidth = MDFNGameInfo->nominal_width;
	 neoheight = MDFNGameInfo->nominal_height;

	 if(LineWidths[0].w != ~0)
 	 {
	  uint32 first_w = LineWidths[DisplayRect->y].w;

	  for(int y = 0; y < DisplayRect->h; y++)
	   if(LineWidths[DisplayRect->y + y].w != first_w)
	   {
		   MDFN_printf("Multires!");
	    is_multires = TRUE;
	   }
	 }

	 if(!is_multires)
	 {
	  if(((SysDDec)DisplayRect->w / MDFNGameInfo->nominal_width) > 0.75  && ((SysDDec)DisplayRect->w / MDFNGameInfo->nominal_width) < 1.25)
	   neowidth = DisplayRect->w;

          if(((SysDDec)DisplayRect->h / MDFNGameInfo->nominal_height) > 0.75  && ((SysDDec)DisplayRect->h / MDFNGameInfo->nominal_height) < 1.25)
	   neoheight = DisplayRect->h;
	 }
	}

	if(!data_only)
	{
		memcpy(header, header_magic, 8);

		if(wantpreview_and_ts)
			  MDFN_en64lsb(header + 8, time(NULL));

	 MDFN_en32lsb(header + 16, MEDNAFEN_VERSION_NUMERIC);
	 MDFN_en32lsb(header + 24, neowidth);
	 MDFN_en32lsb(header + 28, neoheight);
	 smem_write(st, header, 32);
	}

	if(wantpreview_and_ts)
	{
         uint8 *previewbuffer = (uint8 *)malloc(4 * neowidth * neoheight);
	 MDFN_Surface *dest_surface = new MDFN_Surface((uint32 *)previewbuffer, neowidth, neoheight, neowidth, surface->format);
	 MDFN_Rect dest_rect;

	 dest_rect.x = 0;
	 dest_rect.y = 0;
	 dest_rect.w = neowidth;
	 dest_rect.h = neoheight;

	 MDFN_ResizeSurface(surface, DisplayRect, (LineWidths[0].w != ~0) ? LineWidths : NULL, dest_surface, &dest_rect);

	 {
	  uint32 a, b = 0;
	  for(a = 0; a < neowidth * neoheight * 4; a+=4)
	  {
	   uint32 c = *(uint32 *)&previewbuffer[a];
	   int nr, ng, nb;

	   surface->DecodeColor(c, nr, ng, nb);

	   previewbuffer[b + 0] = nr;
	   previewbuffer[b + 1] = ng;
           previewbuffer[b + 2] = nb;
	   b += 3;
	  }
	 }

         smem_write(st, previewbuffer, 3 * neowidth * neoheight);

	 free(previewbuffer);
	 delete dest_surface;
	}

        // State rewinding code path hack, FIXME
        if(data_only)
        {
         if(!MDFN_RawInputStateAction(st, 0, data_only))
          return(0);
        }

	if(!MDFNGameInfo->StateAction(st, 0, data_only))
	 return(0);

	if(!data_only)
	{
	 uint32 sizy = smem_tell(st);
	 smem_seek(st, 16 + 4, SEEK_SET);
	 smem_write32le(st, sizy);
	}
	return(1);
}