From cec0c10286d23d0f41f65ea1d0e779349a365864 Mon Sep 17 00:00:00 2001 From: Andrea Odetti Date: Sat, 12 Dec 2020 12:22:17 +0000 Subject: [PATCH] libretro: first "working" versions. draws video upside down accepts keys (O crashes, and others have overloaded meaning) Signed-off-by: Andrea Odetti --- source/frontends/retro/CMakeLists.txt | 3 + source/frontends/retro/environment.cpp | 9 ++ source/frontends/retro/environment.h | 10 ++ source/frontends/retro/game.cpp | 207 +++++++++++++++++++++++++ source/frontends/retro/game.h | 27 ++++ source/frontends/retro/interface.cpp | 22 +++ source/frontends/retro/libretro.cpp | 200 ++++-------------------- source/frontends/retro/run | 1 + 8 files changed, 306 insertions(+), 173 deletions(-) create mode 100644 source/frontends/retro/game.cpp create mode 100644 source/frontends/retro/game.h create mode 100644 source/frontends/retro/interface.cpp create mode 100644 source/frontends/retro/run diff --git a/source/frontends/retro/CMakeLists.txt b/source/frontends/retro/CMakeLists.txt index 963c7ce6..ce4af256 100644 --- a/source/frontends/retro/CMakeLists.txt +++ b/source/frontends/retro/CMakeLists.txt @@ -4,6 +4,9 @@ add_library(ra2 SHARED libretro.cpp bitmaps.cpp rdirectsound.cpp + interface.cpp + events.cpp + game.cpp ) target_include_directories(ra2 PRIVATE diff --git a/source/frontends/retro/environment.cpp b/source/frontends/retro/environment.cpp index c63678df..16466c5a 100644 --- a/source/frontends/retro/environment.cpp +++ b/source/frontends/retro/environment.cpp @@ -15,3 +15,12 @@ void fallback_log(enum retro_log_level level, const char *fmt, ...) retro_log_callback logging; retro_log_printf_t log_cb = fallback_log; +retro_input_poll_t input_poll_cb; +retro_input_state_t input_state_cb; + +retro_environment_t environ_cb; +retro_video_refresh_t video_cb; +retro_audio_sample_t audio_cb; +retro_audio_sample_batch_t audio_batch_cb; + +std::string retro_base_directory; diff --git a/source/frontends/retro/environment.h b/source/frontends/retro/environment.h index 079568c6..4810a98b 100644 --- a/source/frontends/retro/environment.h +++ b/source/frontends/retro/environment.h @@ -1,5 +1,15 @@ #include "libretro.h" +#include + void fallback_log(enum retro_log_level level, const char *fmt, ...); extern retro_log_callback logging; extern retro_log_printf_t log_cb; +extern retro_input_poll_t input_poll_cb; +extern retro_input_state_t input_state_cb; +extern retro_environment_t environ_cb; +extern retro_video_refresh_t video_cb; +extern retro_audio_sample_t audio_cb; +extern retro_audio_sample_batch_t audio_batch_cb; + +extern std::string retro_base_directory; diff --git a/source/frontends/retro/game.cpp b/source/frontends/retro/game.cpp new file mode 100644 index 00000000..bf91d860 --- /dev/null +++ b/source/frontends/retro/game.cpp @@ -0,0 +1,207 @@ +#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 "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); + } + } + + std::unordered_map getKeymap() + { + std::unordered_map km; + for (unsigned key = RETROK_a; key <= RETROK_z; ++key) + { + km[key] = 0x41 + (key - RETROK_a); + } + for (unsigned key = RETROK_0; key <= RETROK_9; ++key) + { + km[key] = 0x30 + (key - RETROK_0); + } + km[RETROK_SPACE] = 0x20; + km[RETROK_RETURN] = 0x0d; + km[RETROK_UP] = 0x0b; + km[RETROK_DOWN] = 0x0a; + km[RETROK_LEFT] = 0x08; + km[RETROK_UP] = 0x15; + km[RETROK_DELETE] = 0x7f; + km[RETROK_BACKSPACE] = 0x08; + km[RETROK_ESCAPE] = 0x1b; + + return km; + } + +} + +Game::Game() : myKeymap(getKeymap()), mySpeed(true) +{ + EmulatorOptions options; + options.memclear = g_nMemoryClearType; + options.log = true; + options.useQtIni = true; + + if (options.log) + { + LogInit(); + } + + InitializeRegistry(options); + initialiseEmulator(); +} + +Game::~Game() +{ + uninitialiseEmulator(); +} + +void Game::executeOneFrame() +{ + runOneFrame(mySpeed); +} + +void Game::processInputEvents() +{ + input_poll_cb(); + processKeyboardEvents(); +} + +void Game::processKeyboardEvents() +{ + std::vector newKeys; + + for (auto it : myKeymap) + { + const unsigned key = it.first; + const int16_t isDown = input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, key); + + // pressed now, not pressed before + if (isDown && !myKeystate[key]) + { + // add + newKeys.push_back(it.second); + } + + myKeystate[key] = isDown != 0; + } + + // pass to AppleWin. in which order? + for (unsigned key : newKeys) + { + addKeyToBuffer(key); + } + +} + +void Game::drawVideoBuffer() +{ + const size_t pitch = GetFrameBufferWidth() * 4; + video_cb(g_pFramebufferbits, GetFrameBufferWidth(), GetFrameBufferHeight(), pitch); +} + +bool Game::loadGame(const char * path) +{ + const bool ok = DoDiskInsert(SLOT6, DRIVE_1, path); + return ok; +} diff --git a/source/frontends/retro/game.h b/source/frontends/retro/game.h new file mode 100644 index 00000000..07d27db9 --- /dev/null +++ b/source/frontends/retro/game.h @@ -0,0 +1,27 @@ +#pragma once + +#include "frontends/common2/speed.h" + +#include + +class Game +{ +public: + Game(); + ~Game(); + + bool loadGame(const char * path); + + void executeOneFrame(); + void processInputEvents(); + + void drawVideoBuffer(); + + private: + const std::unordered_map myKeymap; + + Speed mySpeed; // fixed speed + std::unordered_map myKeystate; + + void processKeyboardEvents(); +}; diff --git a/source/frontends/retro/interface.cpp b/source/frontends/retro/interface.cpp new file mode 100644 index 00000000..923aafae --- /dev/null +++ b/source/frontends/retro/interface.cpp @@ -0,0 +1,22 @@ +#include "linux/interface.h" + +#include "frontends/retro/environment.h" +#include "linux/win.h" + +int MessageBox(HWND, const char * text, const char * caption, UINT type) +{ + log_cb(RETRO_LOG_INFO, "RA2: %s: %s - %s\n", __FUNCTION__, caption, text); + return IDOK; +} + +void FrameDrawDiskLEDS(HDC x) +{ +} + +void FrameDrawDiskStatus(HDC x) +{ +} + +void FrameRefreshStatus(int x, bool) +{ +} diff --git a/source/frontends/retro/libretro.cpp b/source/frontends/retro/libretro.cpp index 287626d1..4819ee22 100644 --- a/source/frontends/retro/libretro.cpp +++ b/source/frontends/retro/libretro.cpp @@ -1,154 +1,18 @@ #include "libretro.h" -#include +#include +#include #include "StdAfx.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/version.h" -#include -#include - -#include "frontends/common2/programoptions.h" -#include "frontends/common2/configuration.h" -#include "frontends/common2/speed.h" +#include "frontends/retro/game.h" #include "frontends/retro/environment.h" namespace { - std::string retro_base_directory; - - retro_video_refresh_t video_cb; - retro_audio_sample_t audio_cb; - retro_audio_sample_batch_t audio_batch_cb; - retro_input_poll_t input_poll_cb; - retro_input_state_t input_state_cb; - - retro_environment_t environ_cb; - - Speed speed(true); // fixed speed - - 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() - { - 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); - - g_dwCyclesThisFrame = (g_dwCyclesThisFrame + executedCycles) % dwClksPerFrame; - GetCardMgr().GetDisk2CardMgr().UpdateDriveState(executedCycles); - MB_PeriodicUpdate(executedCycles); - SpkrUpdate(executedCycles); - } - } - - void processInputEvents() - { - input_poll_cb(); - - const int16_t is_down = input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_a); - if (is_down) - { - log_cb(RETRO_LOG_INFO, "RA2: %s. A is down\n", __FUNCTION__); - } - } - -} - -int MessageBox(HWND, const char * text, const char * caption, UINT type) -{ - log_cb(RETRO_LOG_INFO, "RA2: %s: %s - %s\n", __FUNCTION__, caption, text); - return IDOK; -} - -void FrameDrawDiskLEDS(HDC x) -{ -} - -void FrameDrawDiskStatus(HDC x) -{ -} - -void FrameRefreshStatus(int x, bool) -{ + std::unique_ptr game; } void retro_init(void) @@ -159,25 +23,11 @@ void retro_init(void) { retro_base_directory = dir; } - - EmulatorOptions options; - options.memclear = g_nMemoryClearType; - options.log = true; - options.useQtIni = true; - - if (options.log) - { - LogInit(); - } - - InitializeRegistry(options); - initialiseEmulator(); } void retro_deinit(void) { log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__); - uninitialiseEmulator(); } unsigned retro_api_version(void) @@ -275,26 +125,14 @@ void retro_set_video_refresh(retro_video_refresh_t cb) void retro_run(void) { - input_poll_cb(); - processInputEvents(); - runOneFrame(); - const size_t pitch = GetFrameBufferWidth() * 4; - video_cb(g_pFramebufferbits, GetFrameBufferWidth(), GetFrameBufferHeight(), pitch); + game->processInputEvents(); + game->executeOneFrame(); + game->drawVideoBuffer(); } bool retro_load_game(const retro_game_info *info) { log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__); - retro_input_descriptor desc[] = - { - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "Left" }, - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "Up" }, - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "Down" }, - { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "Right" }, - { 0 }, - }; - - environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, desc); enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_XRGB8888; if (!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt)) @@ -303,14 +141,30 @@ bool retro_load_game(const retro_game_info *info) return false; } - const bool ok = DoDiskInsert(SLOT6, DRIVE_1, info->path); - log_cb(RETRO_LOG_INFO, "Game path: %s:%d\n", info->path, ok); + try + { + game.reset(new Game); + const bool ok = game->loadGame(info->path); - return true; + log_cb(RETRO_LOG_INFO, "Game path: %s:%d\n", info->path, ok); + + return ok; + } + catch (const std::exception & e) + { + log_cb(RETRO_LOG_INFO, "Exception: %s\n", e.what()); + } + catch (const std::string & s) + { + log_cb(RETRO_LOG_INFO, "Exception: %s\n", s.c_str()); + } + + return false; } void retro_unload_game(void) { + game.reset(); log_cb(RETRO_LOG_INFO, "RA2: %s\n", __FUNCTION__); } diff --git a/source/frontends/retro/run b/source/frontends/retro/run new file mode 100644 index 00000000..423882cf --- /dev/null +++ b/source/frontends/retro/run @@ -0,0 +1 @@ +retroarch -L source/frontends/retro/libra2.so ../Disks/NoSlotClockTest.dsk