#pragma once #include "libretro.h" #include "memory.h" #include <string> #include <vector> #include <cstring> #include <stdarg.h> #ifdef _WIN32 #include <windows.h> #endif namespace Retro { const int N_BUTTONS = 16; const int MAX_PLAYERS = 2; class GameData; class Emulator { public: Emulator(); ~Emulator(); Emulator(const Emulator&) = delete; static bool isLoaded(); bool loadRom(const std::string& romPath); void run(); void reset(); AddressSpace* getAddressSpace(); const void* getImageData() { return m_imgData; } int getImageHeight() { return m_avInfo.geometry.base_height; } int getImageWidth() { return m_avInfo.geometry.base_width; } int getImagePitch() { return m_imgPitch; } int getImageDepth() { return m_imgDepth; } double getFrameRate() { return m_avInfo.timing.fps; } int getAudioSamples() { return m_audioData.size() / 2; } double getAudioRate() { return m_avInfo.timing.sample_rate; } const int16_t* getAudioData() { return m_audioData.data(); } void unloadCore(); void unloadRom(); bool serialize(void* data, size_t size); bool unserialize(const void* data, size_t size); size_t serializeSize(); void setKey(int port, int key, bool active) { m_buttonMask[port][key] = active; } bool getKey(int port, int key) { return m_buttonMask[port][key]; } void clearCheats(); void setCheat(unsigned index, bool enabled, const char* code); std::string core() const { return m_core; } void configureData(GameData*); std::vector<std::string> buttons() const; std::vector<std::string> keybinds() const; private: bool loadCore(const std::string& corePath); void fixScreenSize(const std::string& romName); void reconfigureAddressSpace(); static bool cbEnvironment(unsigned cmd, void* data); static void cbVideoRefresh(const void* data, unsigned width, unsigned height, size_t pitch); static void cbAudioSample(int16_t left, int16_t right); static size_t cbAudioSampleBatch(const int16_t* data, size_t frames); static void cbInputPoll(); static int16_t cbInputState(unsigned port, unsigned device, unsigned index, unsigned id); bool m_buttonMask[MAX_PLAYERS][N_BUTTONS]{}; // Video frame info const void* m_imgData = nullptr; size_t m_imgPitch = 0; int m_imgDepth = 0; // Audio buffer; accumulated during run() std::vector<int16_t> m_audioData; AddressSpace* m_addressSpace = nullptr; retro_system_av_info m_avInfo = {}; std::vector<retro_memory_descriptor> m_map; #ifdef _WIN32 HMODULE m_coreHandle = nullptr; #else void* m_coreHandle = nullptr; #endif bool m_romLoaded = false; std::string m_core; std::string m_romPath; }; }