#include "StdAfx.h" #include "frontends/retro/game.h" #include "Frame.h" #include "Video.h" #include "Common.h" #include "CardManager.h" #include "Core.h" #include "Disk.h" #include "Mockingboard.h" #include "SoundCore.h" #include "Harddisk.h" #include "Speaker.h" #include "Log.h" #include "CPU.h" #include "Memory.h" #include "LanguageCard.h" #include "MouseInterface.h" #include "ParallelPrinter.h" #include "NTSC.h" #include "SaveState.h" #include "RGBMonitor.h" #include "Riff.h" #include "Utilities.h" #include "linux/videobuffer.h" #include "linux/keyboard.h" #include "linux/paddle.h" #include "frontends/common2/programoptions.h" #include "frontends/common2/configuration.h" #include "frontends/retro/environment.h" #include "libretro.h" namespace { void initialiseEmulator() { #ifdef RIFF_SPKR RiffInitWriteFile("/tmp/Spkr.wav", SPKR_SAMPLE_RATE, 1); #endif #ifdef RIFF_MB RiffInitWriteFile("/tmp/Mockingboard.wav", 44100, 2); #endif g_nAppMode = MODE_RUNNING; LogFileOutput("Initialisation\n"); g_bFullSpeed = false; LoadConfiguration(); SetCurrentCLK6502(); GetAppleWindowTitle(); DSInit(); MB_Initialize(); SpkrInitialize(); MemInitialize(); VideoBufferInitialize(); VideoSwitchVideocardPalette(RGB_GetVideocard(), GetVideoType()); GetCardMgr().GetDisk2CardMgr().Reset(); HD_Reset(); Snapshot_Startup(); } void uninitialiseEmulator() { Snapshot_Shutdown(); CMouseInterface* pMouseCard = GetCardMgr().GetMouseCard(); if (pMouseCard) { pMouseCard->Reset(); } VideoBufferDestroy(); MemDestroy(); SpkrDestroy(); MB_Destroy(); DSUninit(); HD_Destroy(); PrintDestroy(); CpuDestroy(); GetCardMgr().GetDisk2CardMgr().Destroy(); LogDone(); RiffFinishWriteFile(); } void runOneFrame(Speed & speed) { if (g_nAppMode == MODE_RUNNING) { const size_t cyclesToExecute = speed.getCyclesTillNext(16); const bool bVideoUpdate = true; const UINT dwClksPerFrame = NTSC_GetCyclesPerFrame(); const DWORD executedCycles = CpuExecute(cyclesToExecute, bVideoUpdate); // log_cb(RETRO_LOG_INFO, "RA2: %s %d\n", __FUNCTION__, executedCycles); g_dwCyclesThisFrame = (g_dwCyclesThisFrame + executedCycles) % dwClksPerFrame; GetCardMgr().GetDisk2CardMgr().UpdateDriveState(executedCycles); MB_PeriodicUpdate(executedCycles); SpkrUpdate(executedCycles); } } } Game::Game() : mySpeed(true) , myWidth(GetFrameBufferWidth()) , myHeight(GetFrameBufferHeight()) { EmulatorOptions options; options.memclear = g_nMemoryClearType; options.log = true; if (options.log) { LogInit(); } InitializeRegistry(options); initialiseEmulator(); const size_t size = myWidth * myHeight * sizeof(bgra_t); myVideoBuffer.resize(size); } Game::~Game() { uninitialiseEmulator(); } void Game::executeOneFrame() { runOneFrame(mySpeed); } void Game::processInputEvents() { input_poll_cb(); } void Game::keyboardCallback(bool down, unsigned keycode, uint32_t character, uint16_t key_modifiers) { if (down) { processKeyDown(keycode, character, key_modifiers); } else { processKeyUp(keycode, character, key_modifiers); } } void Game::processKeyDown(unsigned keycode, uint32_t character, uint16_t key_modifiers) { BYTE ch = 0; switch (keycode) { case RETROK_RETURN: { ch = 0x0d; break; } case RETROK_BACKSPACE: // same as AppleWin case RETROK_LEFT: { ch = 0x08; break; } case RETROK_RIGHT: { ch = 0x15; break; } case RETROK_UP: { ch = 0x0b; break; } case RETROK_DOWN: { ch = 0x0a; break; } case RETROK_DELETE: { ch = 0x7f; break; } case RETROK_ESCAPE: { ch = 0x1b; break; } case RETROK_TAB: { ch = 0x09; break; } case RETROK_LALT: { Paddle::setButtonPressed(Paddle::ourOpenApple); break; } case RETROK_RALT: { Paddle::setButtonPressed(Paddle::ourSolidApple); break; } case RETROK_a ... RETROK_z: { ch = (keycode - RETROK_a) + 0x01; if (key_modifiers & RETROKMOD_CTRL) { // ok } else if (key_modifiers & RETROKMOD_SHIFT) { ch += 0x60; } else { ch += 0x40; } break; } } if (!ch) { switch (character) { case 0x20 ... 0x40: case 0x5b ... 0x60: case 0x7b ... 0x7e: { // not the letters // this is very simple, but one cannot handle CRTL-key combination. ch = character; break; } } } if (ch) { addKeyToBuffer(ch); log_cb(RETRO_LOG_INFO, "RA2: %s - %02x\n", __FUNCTION__, ch); } } void Game::processKeyUp(unsigned keycode, uint32_t character, uint16_t key_modifiers) { switch (keycode) { case RETROK_LALT: { Paddle::setButtonReleased(Paddle::ourOpenApple); break; } case RETROK_RALT: { Paddle::setButtonReleased(Paddle::ourSolidApple); break; } } } void Game::drawVideoBuffer() { const size_t pitch = myWidth * sizeof(bgra_t); // this should not be necessary // either libretro handles it // or we should change AW // but for now, there is no alternative for (size_t row = 0; row < myHeight; ++row) { const uint8_t * src = g_pFramebufferbits + row * pitch; uint8_t * dst = myVideoBuffer.data() + (myHeight - row - 1) * pitch; memcpy(dst, src, pitch); } video_cb(myVideoBuffer.data(), myWidth, myHeight, pitch); } bool Game::loadGame(const char * path) { const bool ok = DoDiskInsert(SLOT6, DRIVE_1, path); return ok; }