예제 #1
0
static int ReadStateChunk(MEMFILE *st, SFORMAT *sf, int size)
{
 //if(scan_chunks)
 //  return mem_fseek(st,size,SEEK_CUR) == 0;

 SFORMAT *tmp;
 int temp;
 temp=mem_ftell(st);

 while(mem_ftell(st)<temp+size)
 {
  uint32 tsize;
  char toa[4];
  if(mem_fread(toa,1,4,st)<=0)
   return 0;

  mem_read32le(&tsize,st);

  if((tmp=CheckS(sf,tsize,toa)))
  {
   mem_fread((uint8 *)tmp->v,1,tmp->s&(~RLSB),st);

   #ifndef LSB_FIRST
   if(tmp->s&RLSB)
    FlipByteOrder(tmp->v,tmp->s&(~RLSB));
   #endif
  }
  else
  {
   mem_fseek(st,tsize,SEEK_CUR);
   printf("ReadStateChunk: sect \"%c%c%c%c\" not handled\n", toa[0], toa[1], toa[2], toa[3]);
  }
 } // while(...)
 return 1;
}
예제 #2
0
파일: i_midi.cpp 프로젝트: WChrisK/OdaStats
//
// I_ReadVariableSizeInt()
//
// Will read an int from a MEMFILE of unknown length.  For each byte we read,
// the highest bit will idicate if the next byte is to be read.  Returns the
// value or -1 if there was a read error.
//
static int I_ReadVariableSizeInt(MEMFILE *mf)
{
	if (!mf)
		return -1;
		
	// In midi files the variable can use between 1 and 5 bytes
	// if the high bit is set, the next byte is used
	int var = 0;
	for (size_t i = 0; i < 5; i++)
	{
		byte curbyte = 0;
		size_t res = mem_fread(&curbyte, sizeof(curbyte), 1, mf);
		if (!res)
			return -1;
			
		// Insert the bottom seven bits from this byte.			
        var = (var << 7) | (curbyte & 0x7f);
        
		// If the top bit is not set, this is the end.
        if ((curbyte & 0x80) == 0)
			break;
	}
	
	return var;
}
예제 #3
0
파일: i_midi.cpp 프로젝트: WChrisK/OdaStats
//
// I_ReadMidiTrack()
//
// Reads an entire midi track from memory and creates a list of MidiEvents
// pointers where the event's start time is the time since the beginning of the
// track.  It is the caller's responsibility to delete the list returned
// by this function.
//
static std::list<MidiEvent*> *I_ReadMidiTrack(MEMFILE *mf)
{
	if (!mf)
		return NULL;
		
	midi_chunk_header_t chunkheader;
	unsigned int track_time = 0;
	
    size_t res = mem_fread(&chunkheader, cTrackHeaderSize, 1, mf); 
	if (!res)
		return NULL;
		
	chunkheader.chunk_id = ntohl(chunkheader.chunk_id);
	chunkheader.chunk_size = ntohl(chunkheader.chunk_size);
		
	if (chunkheader.chunk_id != cTrackChunkId)
	{
		Printf(PRINT_HIGH, "I_ReadMidiTrack: Unexpected chunk header ID\n");
		return NULL;
	}
	
	std::list<MidiEvent*> *eventlist = new std::list<MidiEvent*>;
	
	size_t trackend = mem_ftell(mf) + chunkheader.chunk_size;
	while (mem_ftell(mf) < int(trackend))
	{
		MidiEvent *newevent = I_ReadMidiEvent(mf, track_time);
		
		if (!newevent)
		{
			Printf(PRINT_HIGH, "I_ReadMidiTrack: Unable to read MIDI event\n");
			
			I_ClearMidiEventList(eventlist);
			delete eventlist;
			
			return NULL;
		}
		
		eventlist->push_back(newevent);
		track_time = newevent->getMidiClockTime();
	}
	
	return eventlist;
}
예제 #4
0
int FCEUSS_LoadFP(MEMFILE *st, int make_backup)
{
	int x;
	if(st!=NULL)
	{
	 uint8 header[16];

         mem_fread(&header,1,16,st);
         if(memcmp(header,"FCS",3))
         {
          mem_fseek(st,0,SEEK_SET);
          if(!LoadStateOld(st))
           goto lerror;
          goto okload;
         }
         stateversion=header[3];
	 if(stateversion<53)
	 FixOldSaveStateSFreq();
	 x=ReadStateChunks(st);
	 if(GameStateRestore) GameStateRestore(header[3]);
	 if(x)
	 {
	  okload:
          TempAddr=TempAddrT;
          RefreshAddr=RefreshAddrT;

	  SaveStateStatus[CurrentState]=1;
	 }
	 else
	 {
	  SaveStateStatus[CurrentState]=1;
	  FCEU_DispMessage("Error(s) reading state %d!",CurrentState);
	 }
	}
	else
	{
	 lerror:
	 FCEU_DispMessage("State %d load error.",CurrentState);
	 SaveStateStatus[CurrentState]=0;
	 return 0;
	}
	return 1;
}
예제 #5
0
static int LoadStateOld(MEMFILE *st)
{
	int x;
	int32 nada;
        uint8 version;
	nada=0;

	printf("LoadStateOld\n");

	StateBuffer=FCEU_malloc(59999);
	if(StateBuffer==NULL)
         return 0;
        if(!mem_fread(StateBuffer,59999,1,st))
        {
            mem_fclose(st);
            free(StateBuffer);
            return 0;
        }

	intostate=0;

	{
	 uint8 a[2];
 	 afread(&a[0],1,1);
	 afread(&a[1],1,1);
	 X.PC=a[0]|(a[1]<<8);
	}
	afread(&X.A,1,1);
	afread(&X.P,1,1);
	afread(&X.X,1,1);
	afread(&X.Y,1,1);
	afread(&X.S,1,1);
	afread(&version,1,1);
	afread(&nada,1,1);
	afread(&nada,1,1);
	afread(&nada,1,1);
	afread(&nada,1,1);
	aread32((int8 *)&X.count);
	afread(&nada,1,1);
	afread(&nada,1,1);
	afread(&nada,1,1);
	afread(&nada,1,1);
	aread32((int8 *)&nada);
	afread(&nada,1,1);
	afread(&nada,1,1);
	afread(&nada,1,1);
	afread(&nada,1,1);

	for(x=0;x<8;x++)
		areadupper8of16((int8 *)&CHRBankList[x]);
	afread(PRGBankList,4,1);
	for(x=0;x<8;x++)
		areadlower8of16((int8 *)&CHRBankList[x]);
        afread(CHRRAM,1,0x2000);
        afread(NTARAM,1,0x400);
        afread(ExtraNTARAM,1,0x400);
        afread(NTARAM+0x400,1,0x400);
        afread(ExtraNTARAM+0x400,1,0x400);

        for(x=0;x<0xF00;x++)
         afread(&nada,1,1);
        afread(PALRAM,1,0x20);
        for(x=0;x<256-32;x++)
         afread(&nada,1,1);
        for(x=0x00;x<0x20;x++)
         PALRAM[x]&=0x3f;
	afread(PPU,1,4);
	afread(SPRAM,1,0x100);
	afread(WRAM,1,8192);
	afread(RAM,1,0x800);
	aread16((int8 *)&scanline);
	aread16((int8 *)&RefreshAddr);
	afread(&VRAMBuffer,1,1);

	afread(&IRQa,1,1);
	aread32((int8 *)&IRQCount);
	aread32((int8 *)&IRQLatch);
	afread(&Mirroring,1,1);
	afread(PSG,1,0x17);
	PSG[0x11]&=0x7F;
        afread(MapperExRAM,1,193);
        if(version>=31)
         PSG[0x17]=MapperExRAM[115];
        else
         PSG[0x17]|=0x40;
        PSG[0x15]&=0xF;
        sqnon=PSG[0x15];

        X.IRQlow=0;
        afread(&nada,1,1);
        afread(&nada,1,1);
        afread(&nada,1,1);
        afread(&nada,1,1);
        afread(&nada,1,1);
        afread(&nada,1,1);
	afread(&XOffset,1,1);
        PPUCHRRAM=0;
        for(x=0;x<8;x++)
        {
         nada=0;
         afread(&nada,1,1);
         PPUCHRRAM|=(nada?1:0)<<x;
        }

         afread(mapbyte1,1,8);
         afread(mapbyte2,1,8);
         afread(mapbyte3,1,8);
         afread(mapbyte4,1,8);
         for(x=0;x<4;x++)
          aread16((int8 *)&nada);

         PPUNTARAM=0;
         for(x=0;x<4;x++)
         {
          nada=0;
          aread16((int8 *)&nada);
          PPUNTARAM|=((nada&0x800)?0:1)<<x;
         }
         afread(MapperExRAM,1,32768);
         afread(&vtoggle,1,1);
         aread16((int8 *)&TempAddrT);
         aread16((int8 *)&RefreshAddrT);

         if(GameStateRestore) GameStateRestore(version);
         free(StateBuffer);
	 FixOldSaveStateSFreq();
	 X.mooPI=X.P;
         return 1;
}
예제 #6
0
파일: i_midi.cpp 프로젝트: WChrisK/OdaStats
//
// MidiSong::_ParseSong()
//
// Loads a midi song stored in the MEMFILE, parses the header, and reads
// all of the midi events from the song.  If the midi song has multiple
// tracks, they are merged into a single stream of events.
//
// Based partially on an implementation from Chocolate Doom by Simon Howard.
//
void MidiSong::_ParseSong(MEMFILE *mf)
{
	if (!mf)
		return;
		
	I_ClearMidiEventList(&mEvents);
	
	mem_fseek(mf, 0, MEM_SEEK_SET);
		
	midi_chunk_header_t chunkheader;
    if (!mem_fread(&chunkheader, cTrackHeaderSize, 1, mf))
		return;
		
	chunkheader.chunk_id = ntohl(chunkheader.chunk_id);
	chunkheader.chunk_size = ntohl(chunkheader.chunk_size);
		
	if (chunkheader.chunk_id != cHeaderChunkId)
	{
		Printf(PRINT_HIGH, "MidiSong::_ParseSong: Unexpected file header ID\n");
		return;
	}

	midi_header_t fileheader;
	if (!mem_fread(&fileheader, cHeaderSize, 1, mf))
		return;
	
	fileheader.format_type = ntohs(fileheader.format_type);
	fileheader.num_tracks = ntohs(fileheader.num_tracks);
	fileheader.time_division = ntohs(fileheader.time_division);
	mTimeDivision = fileheader.time_division;

	if (fileheader.format_type != 0 && fileheader.format_type != 1)
	{
		Printf(PRINT_HIGH, "MidiSong::_ParseSong: Only type 0 or type 1 MIDI files are supported.\n");
		return;
	}
	
	// Read all the tracks and merge them into one stream of events
	for (size_t i = 0; i < fileheader.num_tracks; i++)
	{
		std::list<MidiEvent*> *eventlist = I_ReadMidiTrack(mf);
		if (!eventlist)
		{
			Printf(PRINT_HIGH, "MidiSong::_ParseSong: Error reading track %d.\n", i + 1);
			return;
		}
		
		// add this track's list of events to the song's list
		while (!eventlist->empty())
		{
			mEvents.push_back(eventlist->front());
			eventlist->pop_front();
		}
		
		delete eventlist;
	}

	// sort the stream of events by start time 
	// (only needed if we're merging multiple tracks)
	if (fileheader.num_tracks > 1)
		mEvents.sort(I_CompareMidiEventTimes);
}
예제 #7
0
파일: i_midi.cpp 프로젝트: WChrisK/OdaStats
//
// I_ReadMidiEvent()
//
// Parses a MEMFILE and will create and return a MidiEvent object of the
// next midi event stored in the MEMFILE.  It will return NULL if there is
// an error.
//
static MidiEvent* I_ReadMidiEvent(MEMFILE *mf, unsigned int start_time)
{
	if (!mf)
		return NULL;
	
	int delta_time = I_ReadVariableSizeInt(mf);
	if (delta_time == -1)
		return NULL;
		
	unsigned int event_time = start_time + delta_time;
	
	// Read event type
	byte val;
	if (!mem_fread(&val, sizeof(val), 1, mf))
		return NULL;
		
	midi_event_type_t eventtype = static_cast<midi_event_type_t>(val);
	static midi_event_type_t prev_eventtype = eventtype;
	
	// All event types have their top bit set.  Therefore, if
	// the top bit is not set, it is because we are using the "same
	// as previous event type" shortcut to save a byte.  Skip back
	// a byte so that we read this byte again.
	if ((eventtype & 0x80) == 0)
	{
		eventtype = prev_eventtype;
		mem_fseek(mf, -1, MEM_SEEK_CUR);	// put the byte back in the memfile
	}
	else
		prev_eventtype = eventtype;
	
	if (I_IsMidiSysexEvent(eventtype))
	{
		int length = I_ReadVariableSizeInt(mf);
		if (length == -1)
			return NULL;
		
		byte* data = I_ReadDataBlock(mf, length);
		if (!data)
			return NULL;

		return new MidiSysexEvent(event_time, data, length);
	}
	
	if (I_IsMidiMetaEvent(eventtype))
	{
		byte val;
		if (!mem_fread(&val, sizeof(val), 1, mf))
			return NULL;
		
		midi_meta_event_type_t metatype = static_cast<midi_meta_event_type_t>(val);
		
		int length = I_ReadVariableSizeInt(mf);
		if (length == -1)
			return NULL;

		byte* data = I_ReadDataBlock(mf, length);
		if (!data)
			return NULL;
			
		return new MidiMetaEvent(event_time, metatype, data, length);
	}

	// Channel Events only use the highest 4 bits to denote the type
	// Lower four bits denote the channel
	int channel = eventtype & 0x0F;
	eventtype = static_cast<midi_event_type_t>(int(eventtype) & 0xF0);
	
	if (I_IsMidiControllerEvent(eventtype))
	{
		byte val, param1 = 0;
		
		if (!mem_fread(&val, sizeof(val), 1, mf))
			return NULL;

		midi_controller_t controllertype = static_cast<midi_controller_t>(val);
		
		if (!mem_fread(&param1, sizeof(param1), 1, mf))
			return NULL;
		
		return new MidiControllerEvent(event_time, controllertype, channel, param1);
	}
	
	if (I_IsMidiChannelEvent(eventtype))
	{
		byte param1 = 0, param2 = 0;
		
		if (!mem_fread(&param1, sizeof(param1), 1, mf))
			return NULL;
			
		if (eventtype != MIDI_EVENT_PROGRAM_CHANGE && 
			eventtype != MIDI_EVENT_CHAN_AFTERTOUCH)
		{
			// this is an event that uses two parameters
			if (!mem_fread(&param2, sizeof(param2), 1, mf))
				return NULL;
		}
		
		return new MidiChannelEvent(event_time, eventtype, channel, param1, param2);
	}
		
	// none of the above?
	return NULL;
}