JaffarPlus
High-performance best-first search optimizer for tool-assisted speedruns
Loading...
Searching...
No Matches
emulator.hpp
Go to the documentation of this file.
1#pragma once
2
9#include <SDL2/SDL.h>
10#include <inputParser.hpp>
11#include <inputSet.hpp>
12#include <jaffarCommon/deserializers/contiguous.hpp>
13#include <jaffarCommon/file.hpp>
14#include <jaffarCommon/json.hpp>
15#include <jaffarCommon/serializers/contiguous.hpp>
16#include <string>
17
18namespace jaffarPlus
19{
20
25{
26 uint8_t* pointer;
27 size_t size;
28};
29
40{
41public:
46 {
48 std::string inputString;
49
51 jaffar::input_t inputData;
52 };
53
64 Emulator(const nlohmann::json& config) : _emulatorConfigRemaining(config)
65 {
66 // Getting emulator name (for runtime use)
67 _emulatorName = jaffarCommon::json::popString(_emulatorConfigRemaining, "Emulator Name");
68 };
69
70 virtual ~Emulator() = default;
71
77 __INLINE__ void initialize()
78 {
79 if (_isInitialized == true) JAFFAR_THROW_LOGIC("This emulator instance was already initialized");
80
81 // Calling emulator-specific initializer
83
84 // Set this as initialized
85 _isInitialized = true;
86 }
87
95 __INLINE__ InputSet::inputIndex_t registerInput(const std::string inputString)
96 {
97 // Registration is done only at the beginning with linear complexity O(n) to optimize for read access O(1)
98 for (size_t i = 0; i < _inputMap.size(); i++)
99 if (inputString == _inputMap[i].inputString) return i;
100
101 // Otherwise, getting decoded input data from the emulator
102 auto inputData = getInputParser()->parseInputString(inputString);
103
104 // Otherwise, register it as a new entry
105 _inputMap.push_back({inputString, inputData});
106
107 // Returning current index
108 return _inputMap.size() - 1;
109 }
110
116 __INLINE__ const inputEntry_t& getRegisteredInput(const InputSet::inputIndex_t inputIdx) const { return _inputMap[(size_t)inputIdx]; }
117
122 void advanceState(const InputSet::inputIndex_t input) { advanceStateImpl(_inputMap[input].inputData); };
123
128 size_t getStateSize() const
129 {
130 jaffarCommon::serializer::Contiguous s;
132 return s.getOutputSize();
133 }
134
136 __INLINE__ bool isInitialized() const { return _isInitialized; }
137
139 __INLINE__ std::string getName() const { return _emulatorName; }
140
142 virtual void initializeImpl() = 0;
143
148 virtual void serializeState(jaffarCommon::serializer::Base& serializer) const = 0;
153 virtual void deserializeState(jaffarCommon::deserializer::Base& deserializer) = 0;
154
159 virtual jaffar::InputParser* getInputParser() const = 0;
160
162 virtual void printInfo() const = 0;
163
169 virtual property_t getProperty(const std::string& propertyName) const = 0;
170
176 static std::unique_ptr<Emulator> getEmulator(const nlohmann::json& emulatorConfig);
177
179
181 virtual void initializeVideoOutput() = 0;
182
184 virtual void finalizeVideoOutput() = 0;
185
187 virtual void enableRendering() = 0;
188
190 virtual void disableRendering() = 0;
191
197 virtual void updateRendererState(const size_t stepIdx, const std::string input) = 0;
198
203 virtual void serializeRendererState(jaffarCommon::serializer::Base& serializer) const = 0;
204
209 virtual void deserializeRendererState(jaffarCommon::deserializer::Base& deserializer) = 0;
210
215 virtual size_t getRendererStateSize() const = 0;
216
218 virtual void showRender() = 0;
219
226 virtual void saveScreenshot(const std::string& /*path*/) {}
227
228protected:
233 virtual void advanceStateImpl(const jaffar::input_t& input) = 0;
234
244 void finalizeEmulatorConfig() { jaffarCommon::json::checkEmpty(_emulatorConfigRemaining, "Emulator Configuration"); }
245
247 std::string _emulatorName;
248
251
253 bool _isInitialized = false;
254
255private:
257 std::vector<inputEntry_t> _inputMap;
258};
259
260} // namespace jaffarPlus
Abstract base for an emulation core.
Definition emulator.hpp:40
InputSet::inputIndex_t registerInput(const std::string inputString)
Registers an input string, avoiding repeated decoding of the same input.
Definition emulator.hpp:95
const inputEntry_t & getRegisteredInput(const InputSet::inputIndex_t inputIdx) const
Returns the information about a previously registered input.
Definition emulator.hpp:116
virtual void serializeState(jaffarCommon::serializer::Base &serializer) const =0
Serializes the emulator state into the given serializer.
Emulator(const nlohmann::json &config)
Constructs the emulator, performing only configuration parsing (for dry runs).
Definition emulator.hpp:64
void finalizeEmulatorConfig()
Asserts that every key in the emulator configuration has been recognized.
Definition emulator.hpp:244
virtual size_t getRendererStateSize() const =0
Returns the size of the renderer state.
virtual void saveScreenshot(const std::string &)
Saves the currently-rendered frame to an image file at the given destination path.
Definition emulator.hpp:226
bool isInitialized() const
Returns whether the emulator instance has been initialized.
Definition emulator.hpp:136
virtual void printInfo() const =0
Prints core-specific debug information.
void initialize()
Initializes the emulator instance.
Definition emulator.hpp:77
std::string getName() const
Returns the emulator's configured name.
Definition emulator.hpp:139
static std::unique_ptr< Emulator > getEmulator(const nlohmann::json &emulatorConfig)
Constructs the emulator core selected by the configuration.
void advanceState(const InputSet::inputIndex_t input)
Advances the emulator state by applying a registered input.
Definition emulator.hpp:122
virtual void deserializeRendererState(jaffarCommon::deserializer::Base &deserializer)=0
Loads the renderer state for a given state/frame from the deserializer.
virtual void disableRendering()=0
Disables rendering within the emulation core (typically enables faster emulation).
nlohmann::json _emulatorConfigRemaining
Mutable working copy of the emulator config; recognized keys are popped, leftovers are unrecognized....
Definition emulator.hpp:250
virtual void enableRendering()=0
Enables rendering within the emulation core (does not output it to screen).
std::string _emulatorName
Emulator name (for runtime use).
Definition emulator.hpp:247
virtual void showRender()=0
Shows the contents of the emulator's renderer in the window.
virtual void serializeRendererState(jaffarCommon::serializer::Base &serializer) const =0
Gathers the data needed to render a given state/frame into the serializer.
bool _isInitialized
Whether the emulator has been initialized.
Definition emulator.hpp:253
virtual void deserializeState(jaffarCommon::deserializer::Base &deserializer)=0
Deserializes the emulator state from the given deserializer.
virtual void finalizeVideoOutput()=0
Closes the video output (e.g., window).
size_t getStateSize() const
Computes the serialized size of the emulator state.
Definition emulator.hpp:128
virtual property_t getProperty(const std::string &propertyName) const =0
Returns a memory property by name.
virtual void initializeImpl()=0
Core-specific initialization, invoked by initialize.
virtual void advanceStateImpl(const jaffar::input_t &input)=0
Core-specific state advancement, invoked by advanceState.
virtual void initializeVideoOutput()=0
Opens the video output (e.g., window).
virtual void updateRendererState(const size_t stepIdx, const std::string input)=0
Updates the internal state of the renderer with the current game state.
std::vector< inputEntry_t > _inputMap
Maps an input id to its input data.
Definition emulator.hpp:257
virtual jaffar::InputParser * getInputParser() const =0
Returns a reference to the emulator's input parser.
size_t inputIndex_t
Type used to index an input.
Definition inputSet.hpp:29
A set of input indexes gated by conditions: the inputs become available only when all of the set's co...
Pairs an input's string form with its decoded, emulator-specific input data.
Definition emulator.hpp:46
std::string inputString
Input string.
Definition emulator.hpp:48
jaffar::input_t inputData
Emulator-specific input data.
Definition emulator.hpp:51
A property: a contiguous segment of memory with a size, identifiable by name.
Definition emulator.hpp:25
uint8_t * pointer
Pointer to the start of the property's memory segment.
Definition emulator.hpp:26
size_t size
Size of the property's memory segment, in bytes.
Definition emulator.hpp:27