Skip to content
Snippets Groups Projects
emulator.h 2.54 KiB
Newer Older
  • Learn to ignore specific revisions
  • Vicki Pfau's avatar
    Vicki Pfau committed
    #pragma once
    
    #include "libretro.h"
    #include "memory.h"
    
    #include <string>
    #include <vector>
    #include <cstring>
    #include <stdarg.h>
    
    #ifdef _WIN32
    #include <windows.h>
    #endif
    
    Vicki Pfau's avatar
    Vicki Pfau committed
    
    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
    
    Vicki Pfau's avatar
    Vicki Pfau committed
    	void* m_coreHandle = nullptr;
    
    #endif
    
    Vicki Pfau's avatar
    Vicki Pfau committed
    	bool m_romLoaded = false;
    	std::string m_core;
    	std::string m_romPath;
    };
    }