Example #1
0
static void Emulate(EmulateSpecStruct *espec)
{
 espec->DisplayRect.x = 0;
 espec->DisplayRect.y = 0;
 espec->DisplayRect.w = 160;
 espec->DisplayRect.h = 102;

 if(espec->VideoFormatChanged)
  lynxie->DisplaySetAttributes(espec->surface->format, espec->surface->pitch32); // FIXME, pitch

 if(espec->SoundFormatChanged)
 {
  lynxie->mMikie->mikbuf.set_sample_rate(espec->SoundRate ? espec->SoundRate : 44100, 60);
  lynxie->mMikie->mikbuf.clock_rate((long int)(16000000 / 4));
  lynxie->mMikie->mikbuf.bass_freq(60);
  lynxie->mMikie->miksynth.volume(0.50);
 }

 uint16 butt_data = chee[0] | (chee[1] << 8);

 lynxie->SetButtonData(butt_data);

 MDFNMP_ApplyPeriodicCheats();

 memset(LynxLineDrawn, 0, sizeof(LynxLineDrawn[0]) * 102);

 lynxie->mMikie->mpSkipFrame = espec->skip;
 lynxie->mMikie->mpDisplayCurrent = espec->surface->pixels;
 lynxie->mMikie->mpDisplayCurrentLine = 0;
 lynxie->mMikie->startTS = gSystemCycleCount;

 while(lynxie->mMikie->mpDisplayCurrent && (gSystemCycleCount - lynxie->mMikie->startTS) < 700000)
 {
  lynxie->Update();
//  printf("%d ", gSystemCycleCount - lynxie->mMikie->startTS);
 }

 {
  // FIXME, we should integrate this into mikie.*
  uint32 color_black = espec->surface->MakeColor(30, 30, 30);

  for(int y = 0; y < 102; y++)
  {
   uint32 *row = espec->surface->pixels + y * espec->surface->pitch32;

   if(!LynxLineDrawn[y])
   {
    for(int x = 0; x < 160; x++)
     row[x] = color_black;
   }
  }
 }

 espec->MasterCycles = gSystemCycleCount - lynxie->mMikie->startTS;

 if(espec->SoundBuf)
 {
  lynxie->mMikie->mikbuf.end_frame((gSystemCycleCount - lynxie->mMikie->startTS) >> 2);
  espec->SoundBufSize = lynxie->mMikie->mikbuf.read_samples(espec->SoundBuf, espec->SoundBufMaxSize);
 }
Example #2
0
static void Emulate(EmulateSpecStruct *espec)
{
 INPUT_Frame();

 MDFNMP_ApplyPeriodicCheats();

 /*if(unlikely(espec->VideoFormatChanged))
  VDC_SetPixelFormat(espec->surface->format); //.Rshift, espec->surface->format.Gshift, espec->surface->format.Bshift);

 if(unlikely(espec->SoundFormatChanged))
 {
  for(int y = 0; y < 2; y++)
  {
   sbuf[y].set_sample_rate(espec->SoundRate ? espec->SoundRate : 44100, 50);
   sbuf[y].clock_rate((long)(PCE_MASTER_CLOCK / 3));
   sbuf[y].bass_freq(20);
  }
 }*/
 int usedSubSurfaces = 0;
 vdcRunFunc(espec->surface, &espec->DisplayRect, espec->subSurface, IsHES ? 1 : espec->skip, usedSubSurfaces);
 if(!espec->skip && espec->commitVideo)
	 MDFND_commitVideoFrame({espec->DisplayRect, espec->subSurface, usedSubSurfaces});

 if(PCE_IsCD)
 {
  int32 dummy_ne;

  dummy_ne = PCECD_Run(HuCPU.timestamp * 3);
 }

 psg->EndFrame(HuCPU.timestamp / pce_overclocked);

 if(espec->SoundBuf)
 {
  for(int y = 0; y < 2; y++)
  {
   sbuf[y].end_frame(HuCPU.timestamp / pce_overclocked);
   espec->SoundBufSize = sbuf[y].read_samples(espec->SoundBuf + y, espec->SoundBufMaxSize, 1);
  }
 }

 espec->MasterCycles = HuCPU.timestamp * 3;

 INPUT_FixTS();

 HuC6280_ResetTS();

 if(PCE_IsCD)
  PCECD_ResetTS();

 if(IsHES && !espec->skip)
  HES_Draw(espec->surface, &espec->DisplayRect, espec->SoundBuf, espec->SoundBufSize);
}
Example #3
0
static void Emulate(EmulateSpecStruct *espec)
{
 MDFNMP_ApplyPeriodicCheats();

 MDIO_BeginTimePeriod(md_timestamp);

 MDINPUT_Frame();

 if(espec->VideoFormatChanged)
  MainVDP.SetPixelFormat(espec->surface->format); //.Rshift, espec->surface->format.Gshift, espec->surface->format.Bshift);

 if(espec->SoundFormatChanged)
  MDSound_SetSoundRate(espec->SoundRate);

 MainVDP.SetSurface(espec);	//espec->surface, &espec->DisplayRect);

 system_frame(0);

 espec->MasterCycles = md_timestamp;

 espec->SoundBufSize = MDSound_Flush(espec->SoundBuf, espec->SoundBufMaxSize);

#if 0
 {
  static double avg = 0;
  static double s_avg = 0;

  avg += (espec->MasterCycles - avg) * 0.05;
  s_avg += (espec->SoundBufSize - s_avg) * 0.05;
  printf("%f, %f\n", avg / 262 / 10, 48000 / s_avg);
 }
#endif

 MDIO_EndTimePeriod(md_timestamp);

 md_timestamp = 0;
 z80_last_ts = 0;
 Main68K.timestamp = 0;
 MainVDP.ResetTS();

 //MainVDP.SetSurface(NULL);
}
Example #4
0
static void Emulate(EmulateSpecStruct *espec)
{
 int ssize;

#if 0
 static bool firstcat = true;

 MDFN_PixelFormat tmp_pf;

 tmp_pf.Rshift = 0;
 tmp_pf.Gshift = 0;
 tmp_pf.Bshift = 0;
 tmp_pf.Ashift = 8;

 tmp_pf.Rprec = 6;
 tmp_pf.Gprec = 6;
 tmp_pf.Bprec = 6;
 tmp_pf.Aprec = 0;

 tmp_pf.bpp = 8;
 tmp_pf.colorspace = MDFN_COLORSPACE_RGB;

 espec->surface->SetFormat(tmp_pf, false);
 espec->VideoFormatChanged = firstcat;
 firstcat = false;
#endif


 if(espec->VideoFormatChanged)
 {
  MDFN_InitPalette(NESIsVSUni ? MDFN_VSUniGetPaletteNum() : (bool)PAL, espec->CustomPalette, espec->CustomPaletteNumEntries);
  MDFNNES_SetPixelFormat(espec->surface->format);
 }

 if(espec->SoundFormatChanged)
  MDFNNES_SetSoundRate(espec->SoundRate);

 NESPPU_GetDisplayRect(&espec->DisplayRect);

 MDFN_UpdateInput();

 if(!Genie_BIOSInstalled())
  MDFNMP_ApplyPeriodicCheats();

 MDFNPPU_Loop(espec);

 ssize = FlushEmulateSound(espec->NeedSoundReverse, espec->SoundBuf, espec->SoundBufMaxSize);
 espec->NeedSoundReverse = 0;

 timestampbase += timestamp;
 espec->MasterCycles = timestamp;

 timestamp = 0;

 if(MDFNGameInfo->GameType == GMT_PLAYER)
  MDFNNES_DrawNSF(espec->surface, &espec->DisplayRect, espec->SoundBuf, ssize);

 espec->SoundBufSize = ssize;


 if(MDFNGameInfo->GameType != GMT_PLAYER)
 {
  if(NESIsVSUni)
   MDFN_VSUniDraw(espec->surface);
 }
}
Example #5
0
	static void								ModuleEmulate			(EmulateSpecStruct *espec)
	{
		//AUDIO PREP
		Resampler::Init(espec, 44100.0);

		//INPUT
		g.PadState[0].JoyKeyStatus = ~Input::GetPort<0, 2>();
		g.PadState[0].KeyStatus = ~Input::GetPort<0, 2>();
		g.PadState[1].JoyKeyStatus = ~Input::GetPort<1, 2>();
		g.PadState[1].KeyStatus = ~Input::GetPort<1, 2>();

		//CHEATS
		MDFNMP_ApplyPeriodicCheats();

		//EMULATE
		psxCpu->Execute();

		//VIDEO
		#define RED(x) (x & 0xff)
		#define BLUE(x) ((x>>16) & 0xff)
		#define GREEN(x) ((x>>8) & 0xff)
		#define COLOR(x) (x & 0xffffff)

		Video::SetDisplayRect(espec, 0, 0, 320, 240);

		if((g_gpu.dsp.mode.x && g_gpu.dsp.mode.y) && (!(g_gpu.status_reg & STATUS_DISPLAYDISABLED)) && !espec->skip)
		{
			Video::SetDisplayRect(espec, 0, 0, (g_gpu.dsp.range.x1 - g_gpu.dsp.range.x0) / g_gpu.dsp.mode.x, (g_gpu.dsp.range.y1 - g_gpu.dsp.range.y0) * g_gpu.dsp.mode.y);

			uint32_t* pixels = espec->surface->pixels;

			if(g_gpu.status_reg & STATUS_RGB24)
			{
				for(int i = 0; i != espec->DisplayRect.h; i++)
				{
					int startxy = ((1024) * (i + g_gpu.dsp.position.y)) + g_gpu.dsp.position.x;
					unsigned char* pD = (unsigned char *)&g_gpu.psx_vram.u16[startxy];
					uint32_t* destpix = (uint32_t *)(pixels + (i * espec->surface->pitchinpix));
					for(int j = 0; j != espec->DisplayRect.w; j++)
					{
						uint32_t lu = SWAP32(*((uint32_t *)pD));
						destpix[j] = 0xff000000 | (RED(lu) << 16) | (GREEN(lu) << 8) | (BLUE(lu));
						pD += 3;
					}
				}
			}
			else
			{
				Video::BlitRGB15<0, 1, 2, 2, 1, 0, -1>(espec, &g_gpu.psx_vram.u16[1024 * g_gpu.dsp.position.y + g_gpu.dsp.position.x], espec->DisplayRect.w, espec->DisplayRect.h, 1024);
			}
		}
		else if(g_gpu.status_reg & STATUS_DISPLAYDISABLED)
		{
			Video::Clear<uint32_t>(espec, 320, 240);
		}

		//AUDIO
		Resampler::Fetch(espec);

		//Update timing
		espec->MasterCycles = 1LL * 100;
	}
Example #6
0
static void Emulate(EmulateSpecStruct *espec)
{
 INPUT_Frame();

 MDFNMP_ApplyPeriodicCheats();

 #if 0
 {
  static bool firstcat = true;
  MDFN_PixelFormat nf;

  nf.bpp = 16;
  nf.colorspace = MDFN_COLORSPACE_RGB;
  nf.Rshift = 11;
  nf.Gshift = 5;
  nf.Bshift = 0;
  nf.Ashift = 16;

  nf.Rprec = 5;
  nf.Gprec = 6;
  nf.Bprec = 5;
  nf.Aprec = 8;

  espec->surface->SetFormat(nf, false);
  espec->VideoFormatChanged = firstcat;
  firstcat = false;
 }
 #endif

#if 0
 static bool firstcat = true;

 MDFN_PixelFormat tmp_pf;

 tmp_pf.Rshift = 0;
 tmp_pf.Gshift = 0;
 tmp_pf.Bshift = 0;
 tmp_pf.Ashift = 8;

 tmp_pf.Rprec = 6;
 tmp_pf.Gprec = 6;
 tmp_pf.Bprec = 6;
 tmp_pf.Aprec = 0;

 tmp_pf.bpp = 8;
 tmp_pf.colorspace = MDFN_COLORSPACE_RGB;

 espec->surface->SetFormat(tmp_pf, false);
 espec->VideoFormatChanged = firstcat;
 firstcat = false;
#endif

 /*if(unlikely(espec->VideoFormatChanged))
  VDC_SetPixelFormat(espec->surface->format); //.Rshift, espec->surface->format.Gshift, espec->surface->format.Bshift);

 if(unlikely(espec->SoundFormatChanged))
 {
  for(int y = 0; y < 2; y++)
  {
   sbuf[y].set_sample_rate(espec->SoundRate ? espec->SoundRate : 44100, 50);
   sbuf[y].clock_rate((long)(PCE_MASTER_CLOCK / 3));
   sbuf[y].bass_freq(10);
  }
 }*/
 VDC_RunFrame(espec, IsHES);
 if(!espec->skip)
	 MDFND_commitVideoFrame(espec);

 if(PCE_IsCD)
 {
  PCECD_Run(HuCPU.timestamp * 3);
 }

 psg->EndFrame(HuCPU.timestamp / pce_overclocked);

 if(espec->SoundBuf)
 {
  for(int y = 0; y < 2; y++)
  {
   sbuf[y].end_frame(HuCPU.timestamp / pce_overclocked);
   espec->SoundBufSize = sbuf[y].read_samples(espec->SoundBuf + y, espec->SoundBufMaxSize, 1);
  }
 }

 espec->MasterCycles = HuCPU.timestamp * 3;

 INPUT_FixTS();

 HuC6280_ResetTS();

 if(PCE_IsCD)
  PCECD_ResetTS();

 if(IsHES && !espec->skip)
  HES_Draw(espec->surface, &espec->DisplayRect, espec->SoundBuf, espec->SoundBufSize);
}
Example #7
0
static void	Emulate (EmulateSpecStruct *espec)
{
    Fir_Resampler<8>* Resampler;
    //AUDIO PREP
    //Resampler::Init(espec, 34100.0);
    
    
    //INPUT
    //Update stella's event structure
    for(int i = 0; i != 2; i ++)
    {
        //Get the base event id for this port
        Event::Type baseEvent = (i == 0) ? Event::JoystickZeroUp : Event::JoystickOneUp;
        
        //Get the input data for this port and stuff it in the event structure
        //uint32_t inputState = Input::GetPort<3>(i);
        uint32_t inputState;
        for(int j = 0; j != 19; j ++, inputState >>= 1)
        {
            mdfnStella->GameConsole->event().set((Event::Type)(baseEvent + j), inputState & 1);
        }
    }
    
    uint16 butt_data = chee[0] | (chee[1] << 8);
    
    //mdfnStella->SetButtonData(butt_data);
    
    //Update the reset and select events
    //uint32_t inputState = Input::GetPort<0, 3>() >> 19;
    uint32_t inputState;
    mdfnStella->GameConsole->event().set(Event::ConsoleSelect, inputState & 1);
    mdfnStella->GameConsole->event().set(Event::ConsoleReset, inputState & 2);
    
    //Tell all input devices to read their state from the event structure
    mdfnStella->GameConsole->switches().update();
    mdfnStella->GameConsole->controller(Controller::Left).update();
    mdfnStella->GameConsole->controller(Controller::Right).update();
    
    //CHEATS
    MDFNMP_ApplyPeriodicCheats();
    
    //EMULATE
    mdfnStella->GameConsole->tia().update();
    
    //	if(myOSystem->eventHandler().frying())
    //		myOSystem->GameConsole().fry();
    
    //VIDEO: TODO: Support other color formats
    //Get the frame info from stella
    Int32 frameWidth = mdfnStella->GameConsole->tia().width();
    Int32 frameHeight = mdfnStella->GameConsole->tia().height();
    
    //printf("frameWidth %d\n", frameWidth);
    //printf("frameHeight %d\n", frameHeight);
    
    
    //Setup the output area for mednafen, never allow stella's size to excede mednafen's
    //Video::SetDisplayRect(espec, 0, 0, frameWidth, frameHeight);
    espec->DisplayRect.x = 0;
    espec->DisplayRect.y = 0;
    espec->DisplayRect.w = frameWidth;
    espec->DisplayRect.h = frameHeight;
    
    //Copy the frame from stella to mednafen
    //Video::BlitPalette<0xFF>(espec, mdfnStella->Palette, mdfnStella->GameConsole->tia().currentFrameBuffer(), frameWidth, frameHeight, frameWidth);
    //inline void __attribute((always_inline))                BlitPalette                                     (EmulateSpecStruct* espec, const pType* aPalette, const sType* aSource, uint32_t aWidth, uint32_t aHeight, uint32_t aPixelPitch)

        for(int i = 0; i != frameHeight; i ++)
        {
            for(int j = 0; j != frameWidth; j ++)
            {
                espec->surface->pixels[i * espec->surface->pitchinpix + j] = mdfnStella->Palette[mdfnStella->GameConsole->tia().currentFrameBuffer()[i * frameWidth + j] & 0xFF];
            }
        }
    
    //Player_Draw(espec->surface, &espec->DisplayRect, 0, espec->SoundBuf, espec->SoundBufSize);
    
    //AUDIO
    //Get the number of samples in a frame
    uint32_t soundFrameSize = 34100.0f / mdfnStella->GameConsole->getFramerate();
    
    //Process one frame of audio from stella
    uint8_t samplebuffer[2048];
    mdfnStella->Sound.processFragment(samplebuffer, soundFrameSize);
    
    //Convert and stash it in the resampler...
    for(int i = 0; i != soundFrameSize; i ++)
    {
        int16_t sample = (samplebuffer[i] << 8) - 32768;
        int16_t frame[2] = {sample, sample};
        //Resampler::Fill(frame, 2);
    }
    
    //Get the output
    //Resampler::Fetch(espec);
    assert(espec);
    if(Resampler && espec->SoundBuf && espec->SoundBufMaxSize)
    {
        uint32_t readsize = std::min(Resampler->avail() / 2, espec->SoundBufMaxSize);
        espec->SoundBufSize = Resampler->read(espec->SoundBuf, readsize) >> 1;
    }
Example #8
0
static void Emulate(EmulateSpecStruct *espec)
{
 //printf("%d\n", PCFX_V810.v810_timestamp);

 FXINPUT_Frame();

 MDFNMP_ApplyPeriodicCheats();

 if(espec->VideoFormatChanged)
  KING_SetPixelFormat(espec->surface->format); //.Rshift, espec->surface->format.Gshift, espec->surface->format.Bshift);

 if(espec->SoundFormatChanged)
  SoundBox_SetSoundRate(espec->SoundRate);


 KING_StartFrame(fx_vdc_chips, espec);	//espec->surface, &espec->DisplayRect, espec->LineWidths, espec->skip);

 v810_timestamp_t v810_timestamp;
 v810_timestamp = PCFX_V810.Run(pcfx_event_handler);


 PCFX_FixNonEvents();

 // Call before resetting v810_timestamp
 ForceEventUpdates(v810_timestamp);

 //
 // Call KING_EndFrame() before SoundBox_Flush(), otherwise CD-DA audio distortion will occur due to sound data being updated
 // after it was needed instead of before.
 //
 KING_EndFrame(v810_timestamp);

 //
 // new_base_ts is guaranteed to be <= v810_timestamp
 //
 v810_timestamp_t new_base_ts;
 espec->SoundBufSize = SoundBox_Flush(v810_timestamp, &new_base_ts, espec->SoundBuf, espec->SoundBufMaxSize);

 KING_ResetTS(new_base_ts);
 FXTIMER_ResetTS(new_base_ts);
 FXINPUT_ResetTS(new_base_ts);
 SoundBox_ResetTS(new_base_ts);

 // Call this AFTER all the EndFrame/Flush/ResetTS stuff
 RebaseTS(v810_timestamp, new_base_ts);

 espec->MasterCycles = v810_timestamp - new_base_ts;

 PCFX_V810.ResetTS(new_base_ts);

 //
 //
 //
 if(BackupSignalDirty)
 {
  BackupSaveDelay = 120;
  BackupSignalDirty = false;
 }
 else if(BackupSaveDelay)
 {
  BackupSaveDelay--;

  if(!BackupSaveDelay)
  {
   //puts("SAVE");
   try
   {
    SaveBackupMemory();
   }
   catch(std::exception &e)
   {
    MDFN_PrintError(_("Error saving save-game memory: %s"), e.what());
    MDFN_DispMessage(_("Error saving save-game memory: %s"), e.what());
    BackupSaveDelay = 60 * 60;	// Try it again in about 60 seconds emulated time(unless more writes occur to the backup memory before then, then the regular delay
				// will be used from that time).
   }
  }
 }
}
Example #9
0
static void Emulate(EmulateSpecStruct *espec)
{
	bool MeowMeow = 0;

	espec->DisplayRect.x = 0;
	espec->DisplayRect.y = 0;
	espec->DisplayRect.w = 160;
	espec->DisplayRect.h = 152;

	if(espec->VideoFormatChanged)
	 NGPGfx->set_pixel_format(espec->surface->format);

	if(espec->SoundFormatChanged)
	 MDFNNGPC_SetSoundRate(espec->SoundRate);


	NGPJoyLatch = *chee;
	storeB(0x6F82, *chee);

	MDFNMP_ApplyPeriodicCheats();

	ngpc_soundTS = 0;
	NGPFrameSkip = espec->skip;

	do
	{
#if 0
         int32 timetime;

	 if(main_timeaccum == 0)
	 {
	  main_timeaccum = TLCS900h_interpret();
          if(main_timeaccum > 255)
	  {
	   main_timeaccum = 255;
           printf("%d\n", main_timeaccum);
	  }
	 }

	 timetime = std::min<int32>(main_timeaccum, 24);
	 main_timeaccum -= timetime;
#else
#if 0
	 uint32 old_pc = pc;
	 {
	  uint32 xix = gpr[0];
	  uint32 xiz = gpr[2];
	  printf("%08x %08x --- %s\n", xix, xiz, TLCS900h_disassemble());
	 }
	 pc = old_pc;
#endif

	 int32 timetime = (uint8)TLCS900h_interpret();	// This is sooo not right, but it's replicating the old behavior(which is necessary
							// now since I've fixed the TLCS900h core and other places not to truncate cycle counts
							// internally to 8-bits).  Switch to the #if 0'd block of code once we fix cycle counts in the
							// TLCS900h core(they're all sorts of messed up), and investigate if certain long
							// instructions are interruptable(by interrupts) and later resumable, RE Rockman Battle
							// & Fighters voice sample playback.
#endif
	 //if(timetime > 255)
	 // printf("%d\n", timetime);

	 // Note: Don't call updateTimers with a time/tick/cycle/whatever count greater than 255.
	 MeowMeow |= updateTimers(espec->surface, timetime);

	 z80_runtime += timetime;

         while(z80_runtime > 0)
	 {
	  int z80rantime = Z80_RunOP();

	  if(z80rantime < 0) // Z80 inactive, so take up all run time!
	  {
	   z80_runtime = 0;
	   break;
	  }

	  z80_runtime -= z80rantime << 1;

	 }
	} while(!MeowMeow);


	espec->MasterCycles = ngpc_soundTS;
	espec->SoundBufSize = MDFNNGPCSOUND_Flush(espec->SoundBuf, espec->SoundBufMaxSize);
}
Example #10
0
static void Emulate(EmulateSpecStruct *espec)
{
 if(espec->VideoFormatChanged)
  SMS_VDPSetPixelFormat(espec->surface->format, espec->CustomPalette);

 if(espec->SoundFormatChanged)
  SMS_SetSoundRate(espec->SoundRate);


 sms.timestamp = 0;

 input.pad[0] = *InputPtrs[0] & 0x3F;

 if(IS_SMS)
 {
  input.pad[1] = *InputPtrs[1] & 0x3F;

  if((*InputPtrs[0] | *InputPtrs[1]) & 0x40)
   input.system |= INPUT_PAUSE;
  else
   input.system &= ~INPUT_PAUSE;
 }
 else // GG:
 {
  if(*InputPtrs[0] & 0x40)
  {
   input.system |= INPUT_START;
  }
  else
   input.system &= ~INPUT_START;
 }

 //NGPJoyLatch = *chee;

 MDFNMP_ApplyPeriodicCheats();

 if(sms.console == CONSOLE_GG)
 {
  espec->DisplayRect.x = 48;
  espec->DisplayRect.y = 48;
  espec->DisplayRect.w = 160;
  espec->DisplayRect.h = 144;
 }
 else
 {
  espec->DisplayRect.x = 0;
  espec->DisplayRect.y = 0;
  espec->DisplayRect.w = 256;
  espec->DisplayRect.h = 240;
 }

 bitmap.data = (uint8*)espec->surface->pixels;
 bitmap.width = 256;
 bitmap.height = 240;
 bitmap.pitch = 256 * sizeof(uint32);

 system_frame(espec->skip);

 espec->MasterCycles = sms.timestamp;
 espec->SoundBufSize = SMS_SoundFlush(espec->SoundBuf, espec->SoundBufMaxSize);
}
Example #11
0
static void Emulate(EmulateSpecStruct *espec)
{
 espec->DisplayRect.x = 0;
 espec->DisplayRect.y = 0;
 espec->DisplayRect.w = 224;
 espec->DisplayRect.h = 144;

 if(espec->VideoFormatChanged)
  WSwan_SetPixelFormat(espec->surface->format);

 if(espec->SoundFormatChanged)
  WSwan_SetSoundRate(espec->SoundRate);

 uint16 butt_data = chee[0] | (chee[1] << 8);

 WSButtonStatus = butt_data;
 

 MDFNMP_ApplyPeriodicCheats();

 while(!wsExecuteLine(espec->surface, espec->skip))
 {

 }


 espec->SoundBufSize = WSwan_SoundFlush(espec->SoundBuf, espec->SoundBufMaxSize);

 espec->MasterCycles = v30mz_timestamp;
 v30mz_timestamp = 0;

 if(IsWSR)
 {
  bool needreload = FALSE;
  static uint16 last;

  Player_Draw(espec->surface, &espec->DisplayRect, WSRCurrentSong, espec->SoundBuf, espec->SoundBufSize);

  if((WSButtonStatus & 0x02) && !(last & 0x02))
  {
   WSRCurrentSong++;
   needreload = 1;
  }

  if((WSButtonStatus & 0x08) && !(last & 0x08))
  {
   WSRCurrentSong--;
   needreload = 1;
  }

  if((WSButtonStatus & 0x100) && !(last & 0x100))
   needreload = 1;

  if((WSButtonStatus & 0x01) && !(last & 0x01))
  {
   WSRCurrentSong += 10;
   needreload = 1;
  }

  if((WSButtonStatus & 0x04) && !(last & 0x04))
  {
   WSRCurrentSong -= 10;
   needreload = 1;
  }


  last = WSButtonStatus;

  if(needreload)
   Reset();
 }
}