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); }
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); }
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); }
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); } }
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; }
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); }
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; }
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). } } } }
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); }
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); }
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(); } }