From 1e6cf8b7500905cd49f201f3601959238584b505 Mon Sep 17 00:00:00 2001 From: Nadavbh Date: Sat, 18 Feb 2017 21:24:53 +0200 Subject: [PATCH] fixed multi rom load bug, moved to shared_ptr, cleaned settings --- CMakeLists.txt | 4 +- setup.py | 2 +- src/common/display_screen.cpp | 2 +- src/common/display_screen.h | 8 +- src/environment/RetroAgent.cpp | 13 +- src/environment/RetroAgent.h | 3 +- src/environment/RleSystem.cxx | 105 +--- src/environment/RleSystem.hxx | 120 +--- src/environment/Settings.cxx | 556 +++++-------------- src/environment/Settings.hxx | 76 +-- src/environment/retro_environment.cpp | 42 +- src/environment/retro_environment.hpp | 9 +- src/environment/rle_state.cpp | 12 +- src/environment/rle_state.hpp | 8 +- src/games/AtariSettings.cpp | 2 +- src/games/RomSettings.cpp | 4 +- src/games/RomSettings.hpp | 1 + src/games/supported/Aladdin.cpp | 4 +- src/games/supported/MortalKombat.cpp | 10 +- src/games/supported/MortalKombat2Players.cpp | 6 +- src/games/supported/SonicTheHedgehog.cpp | 2 +- src/games/supported/StreetFighterII.cpp | 2 +- src/os_dependent/OSystemWin32.cxx | 63 --- src/os_dependent/OSystemWin32.hxx | 52 -- src/os_dependent/RleSystemUNIX.cxx | 71 --- src/os_dependent/RleSystemUNIX.hxx | 58 -- src/os_dependent/SettingsUNIX.cxx | 41 -- src/os_dependent/SettingsUNIX.hxx | 48 -- src/os_dependent/SettingsWin32.cxx | 37 -- src/os_dependent/SettingsWin32.hxx | 41 -- src/rle_interface.cpp | 100 ++-- src/rle_interface.hpp | 16 +- test/RetroAgentTest.cpp | 11 + test/RleTest.cpp | 15 +- test/SettingsTest.cpp | 40 ++ test/python_interface_test.py | 7 +- test/rleCInterfaceTest.cpp | 9 +- 37 files changed, 360 insertions(+), 1240 deletions(-) delete mode 100644 src/os_dependent/OSystemWin32.cxx delete mode 100644 src/os_dependent/OSystemWin32.hxx delete mode 100644 src/os_dependent/RleSystemUNIX.cxx delete mode 100644 src/os_dependent/RleSystemUNIX.hxx delete mode 100644 src/os_dependent/SettingsUNIX.cxx delete mode 100644 src/os_dependent/SettingsUNIX.hxx delete mode 100644 src/os_dependent/SettingsWin32.cxx delete mode 100644 src/os_dependent/SettingsWin32.hxx create mode 100644 test/SettingsTest.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index e9efdf6..306307b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,9 +66,9 @@ if(APPLE) endif() if(WINDOWS OR MINGW) - list(APPEND SOURCES ${SOURCE_DIR}/os_dependent/SettingsWin32.cxx ${SOURCE_DIR}/os_dependent/OSystemWin32.cxx ${SOURCE_DIR}/os_dependent/FSNodeWin32.cxx) + list(APPEND SOURCES ${SOURCE_DIR}/os_dependent/FSNodeWin32.cxx) else() - list(APPEND SOURCES ${SOURCE_DIR}/os_dependent/SettingsUNIX.cxx ${SOURCE_DIR}/os_dependent/RleSystemUNIX.cxx ${SOURCE_DIR}/os_dependent/FSNodePOSIX.cxx) + list(APPEND SOURCES ${SOURCE_DIR}/os_dependent/FSNodePOSIX.cxx) endif() if(UNIX) diff --git a/setup.py b/setup.py index d9a368a..786c1f4 100644 --- a/setup.py +++ b/setup.py @@ -42,7 +42,7 @@ def run(self): ds.spawn(['./copy_cores.sh']) _build.build.run(self) -version = '1.1.0' +version = '1.1.1' setup(name = 'rle_python_interface', version=version, description = 'Retro Learning Environment Python Interface based on Ben Goodrich\'s work', diff --git a/src/common/display_screen.cpp b/src/common/display_screen.cpp index 1ee03c2..172033b 100644 --- a/src/common/display_screen.cpp +++ b/src/common/display_screen.cpp @@ -22,7 +22,7 @@ using namespace std; using namespace rle; #ifdef __USE_SDL -DisplayScreen::DisplayScreen(RetroAgent* rAgent ): manual_control_active(false), delay_msec(5), ragent(rAgent) { +DisplayScreen::DisplayScreen(pRetroAgent rAgent ): manual_control_active(false), delay_msec(5), ragent(rAgent) { bpp = ragent->getBpp(); screen_height = ragent->getHeight(); diff --git a/src/common/display_screen.h b/src/common/display_screen.h index 005e193..0297a28 100644 --- a/src/common/display_screen.h +++ b/src/common/display_screen.h @@ -31,8 +31,8 @@ namespace rle { class DisplayScreen { public: - // todo save RetroAgent as shared_ptr - DisplayScreen(RetroAgent* ragent ); + // todo save RetroAgent as unique_ptr + DisplayScreen(pRetroAgent ragent ); virtual ~DisplayScreen(); // Displays the current frame buffer from the mediasource. @@ -64,7 +64,7 @@ class DisplayScreen { Uint32 last_frame_time; Uint8 bpp; - RetroAgent* ragent; + pRetroAgent ragent; }; } // namespace rle @@ -74,7 +74,7 @@ namespace rle { /** A dummy class that simply ignores display events. */ class DisplayScreen { public: - DisplayScreen(RetroAgent* ragent) {} + DisplayScreen(pRetroAgent ragent) {} void display_screen() {} bool manual_control_engaged() { return false; } Action getUserAction() { return JOYPAD_UNDEFINED; } diff --git a/src/environment/RetroAgent.cpp b/src/environment/RetroAgent.cpp index b8f3f31..9e431ce 100644 --- a/src/environment/RetroAgent.cpp +++ b/src/environment/RetroAgent.cpp @@ -427,7 +427,7 @@ static void core_unload() { // dlclose(RetroAgent::g_retro.handle); } -RetroAgent::RetroAgent() : coreLoaded(false){ +RetroAgent::RetroAgent() : coreLoaded(false), romLoaded(false){ agentNum = numAgents++; RetroAgent::g_retro.initialized = false; } @@ -454,6 +454,9 @@ static void copyFile(string srcName, string dstName){ } void RetroAgent::loadCore(const string& coreName){ + if(coreLoaded){ + unloadCore(); + } string suffix = ".so"; size_t start_pos = coreName.find(suffix); if(start_pos == std::string::npos){ @@ -481,8 +484,12 @@ void RetroAgent::unloadCore(){ } void RetroAgent::loadRom(const string& romName){ + if(romLoaded){ + unloadRom(); + } core_load_game(romName.c_str()); RetroAgent::g_retro.serializeSize = RetroAgent::g_retro.retro_serialize_size(); + romLoaded = true; } void RetroAgent::unloadRom(){ @@ -490,6 +497,7 @@ void RetroAgent::unloadRom(){ RetroAgent::g_retro.retro_unload_game(); RetroAgent::g_retro.initialized = false; } + romLoaded = false; } void RetroAgent::run(){ @@ -543,9 +551,6 @@ void RetroAgent::SetActions(const Action& player_a_action, const Action& player_ g_retro.action_b = player_b_action; } -void RetroAgent::updateScreen(){ - -} void* RetroAgent::getCurrentBuffer() const{ return RetroAgent::g_video.currentBuffer; } diff --git a/src/environment/RetroAgent.h b/src/environment/RetroAgent.h index 97613cb..937e811 100644 --- a/src/environment/RetroAgent.h +++ b/src/environment/RetroAgent.h @@ -36,7 +36,6 @@ class RetroAgent{ uint8_t* getRamAddress(); uint32_t getRamSize(); void SetActions(const Action& player_a_action, const Action& player_b_action); - void updateScreen(); void* getCurrentBuffer() const; uint32_t getBufferSize() const; // in pixels uint8_t getBpp() const; //in bits @@ -106,11 +105,13 @@ class RetroAgent{ private: bool coreLoaded; + bool romLoaded; static std::atomic_uint numAgents; unsigned agentNum; void unloadCore(); void unloadRom(); }; +typedef shared_ptr pRetroAgent; } // namespace rle diff --git a/src/environment/RleSystem.cxx b/src/environment/RleSystem.cxx index f487be8..e57ddbc 100644 --- a/src/environment/RleSystem.cxx +++ b/src/environment/RleSystem.cxx @@ -12,48 +12,21 @@ using namespace std; #include "RleSystem.hxx" #include -#include "bspf.hxx" +//#include "bspf.hxx" using namespace rle; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -RleSystem::RleSystem(RetroAgent* retroagent) +RleSystem::RleSystem(pRetroAgent retroagent, pSettings settings) : - mySettings(NULL), + mySettings(settings), //RLE myRetroAgent(retroagent), //RLE myRomFile(""), - myCoreFile(""), - p_display_screen(NULL) + myCoreFile("") +// p_display_screen(NULL) {} // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -RleSystem::~RleSystem() -{ - - // RleSystem takes responsibility for framebuffer and sound, - // since it created them -// if (mySound != NULL) -// delete mySound; - - if (p_display_screen != NULL) { - delete p_display_screen; - } - -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool RleSystem::create() -{ - // Create the sound object; the sound subsystem isn't actually - // opened until needed, so this is non-blocking (on those systems - // that only have a single sound device (no hardware mixing) - // createSound(); - - // Seed RNG. This will likely get re-called, e.g. by the RLEInterface, but is needed - // by other interfaces. - resetRNGSeed(); - - return true; -} +RleSystem::~RleSystem(){} // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void RleSystem::resetRNGSeed() { @@ -78,70 +51,12 @@ bool RleSystem::saveState(Serializer& out) { bool RleSystem::loadState(Deserializer& in) { return myRandGen.loadState(in); } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -//void RleSystem::setConfigPaths() -//{ -// myGameListCacheFile = myBaseDir + BSPF_PATH_SEPARATOR + "stella.cache"; -// -// myCheatFile = mySettings->getString("cheatfile"); -// if(myCheatFile == "") -// myCheatFile = myBaseDir + BSPF_PATH_SEPARATOR + "stella.cht"; -// mySettings->setString("cheatfile", myCheatFile); -// -// myPrletteFile = mySettings->getString("prlettefile"); -// if(myPrletteFile == "") -// myPrletteFile = myBaseDir + BSPF_PATH_SEPARATOR + "stella.pal"; -// mySettings->setString("prlettefile", myPrletteFile); -// -// myPropertiesFile = mySettings->getString("propsfile"); -// if(myPropertiesFile == "") -// myPropertiesFile = myBaseDir + BSPF_PATH_SEPARATOR + "stella.pro"; -// mySettings->setString("propsfile", myPropertiesFile); -//} - -void RleSystem::setBaseDir(const string& basedir) -{ - myBaseDir = basedir; - if(!FilesystemNode::dirExists(myBaseDir)) - FilesystemNode::makeDir(myBaseDir); -} // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void RleSystem::step() { myRetroAgent->run(); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void RleSystem::setFramerate(uInt32 framerate) -{ - myDisplayFrameRate = framerate; - myTimePerFrame = (uInt32)(1000000.0 / (double)myDisplayFrameRate); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -//void RleSystem::createSound() -//{ -// if (mySound != NULL) { -// delete mySound; -// } -// mySound = NULL; -// -//#ifdef SOUND_SUPPORT -// // If requested (& supported), enable sound -// if (mySettings->getBool("sound") == true) { -// mySound = new SoundSDL(this); -// mySound->initialize(); -// } -// else { -// mySound = new SoundNull(this); -// } -//#else -// mySettings->setBool("sound", false); -// mySound = new SoundNull(this); -//#endif -//} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool RleSystem::loadCore(const string& corePath){ myCoreFile = corePath; @@ -154,11 +69,3 @@ bool RleSystem::loadRom(const string& rom){ myRetroAgent->loadRom(rom); return true; } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -//void RleSystem::resetLoopTiming() -//{ -// memset(&myTimingInfo, 0, sizeof(TimingInfo)); -// myTimingInfo.start = getTicks(); -// myTimingInfo.virt = getTicks(); -//} diff --git a/src/environment/RleSystem.hxx b/src/environment/RleSystem.hxx index 9db258a..e2ef174 100644 --- a/src/environment/RleSystem.hxx +++ b/src/environment/RleSystem.hxx @@ -52,13 +52,12 @@ struct Resolution { }; typedef Common::Array ResolutionList; -class RleSystem -{ - public: +class RleSystem{ +public: /** Create a new RleSystem abstract class */ - RleSystem(RetroAgent* retroagent); + RleSystem(pRetroAgent retroagent, pSettings settings); /** Destructor @@ -69,18 +68,6 @@ class RleSystem RleSystem& operator = (const RleSystem&) = delete; - /** - Create all child objects which belong to this RleSystem - */ - virtual bool create(); - - /** - Adds the specified settings object to the system. - - @param settings The settings object to add - */ - void attach(Settings* settings) { mySettings = settings; } - /** Get the frame buffer of the system @@ -92,52 +79,31 @@ class RleSystem Returns the size of the buffer in bytes; */ int getBufferSize() const { return myRetroAgent->getBufferSize();} - /** - Get the sound object of the system - - @return The sound object - */ -// inline Sound& sound() const { return *mySound; } /** Get the settings object of the system @return The settings object */ - inline Settings& settings() const { return *mySettings; } + pSettings settings() const { return mySettings; } /** Get the RetroAgent object of the system @return The RetorAgent object */ - inline RetroAgent& getRetroAgent() const { return *myRetroAgent; } + pRetroAgent getRetroAgent() const { return myRetroAgent; } /** Perform one step in the emulator */ void step(); - /** - Set the framerate for the video system. It's placed in this class since - the mainLoop() method is defined here. - - @param framerate The video framerate to use - */ - virtual void setFramerate(uInt32 framerate); - /** Set all config file paths for the RleSystem. */ void setConfigPaths(); - /** - Get the current framerate for the video system. - - @return The video framerate currently in use - */ - inline uInt32 frameRate() const { return myDisplayFrameRate; } - /** Get the maximum dimensions of a window for the video hardware. */ @@ -151,11 +117,6 @@ class RleSystem */ const ResolutionList& supportedResolutions() const { return myResolutions; } - /** - Return the default directory for storing data. - */ - const std::string& baseDir() const { return myBaseDir; } - /** This method should be called to get the full path of the config file. @@ -214,25 +175,8 @@ class RleSystem Deserializes the RleSystem state. */ bool loadState(Deserializer& in); - - public: - ////////////////////////////////////////////////////////////////////// - // The following methods are system-specific and must be implemented - // in derived classes. - ////////////////////////////////////////////////////////////////////// - /** - This method returns number of ticks in microseconds. - - @return Current time in microseconds. - */ - virtual uInt32 getTicks() = 0; - protected: - /** - Set the base directory for all Stella files (these files may be - located in other places through settings). - */ - void setBaseDir(const std::string& basedir); +protected: /** Set the locations of config file @@ -243,10 +187,10 @@ class RleSystem // Sound* mySound; // Pointer to the Settings object - Settings* mySettings; + pSettings mySettings; // Pointer to RetroAgent - RetroAgent* myRetroAgent; // RLE + pRetroAgent myRetroAgent; // RLE // Random number generator shared across the emulator's components Random myRandGen; @@ -264,56 +208,18 @@ class RleSystem // This is reset to false after one step bool mySkipEmulation; - private: - std::string myBaseDir; +private: std::string myRomFile; std::string myCoreFile; std::string myConfigFile; - public: //ALE - // Time per frame for a video update, based on the current framerate - uInt32 myTimePerFrame; - - // Indicates whether the main processing loop should proceed - struct TimingInfo { - uInt32 start; - uInt32 current; - uInt32 virt; - uInt32 totalTime; - uInt32 totalFrames; - }; - TimingInfo myTimingInfo; - - - // Table of RGB values for GUI elements - //ALE static uInt32 ourGUIColors[kNumUIPrlettes][kNumColors-256]; - public: - DisplayScreen* p_display_screen; //MHAUSKN - - private: - - /** - Creates the various sound devices available in this system - (for now, that means either 'SDL' or 'Null'). - */ -// void createSound(); - - /** - Query valid info for creating a valid console. - - @return Success or failure for a valid console - */ -// bool queryConsoleInfo(const uInt8* image, uInt32 size, const std::string& md5, -// Cartridge** cart, Properties& props); - - /** - Initializes the timing so that the mainloop is reset to its - initial values. - */ - void resetLoopTiming(); +public: //ALE + shared_ptr p_display_screen; //MHAUSKN }; +typedef shared_ptr pRleSystem; + } // namespace rle #endif diff --git a/src/environment/Settings.cxx b/src/environment/Settings.cxx index 200616d..077f2e7 100644 --- a/src/environment/Settings.cxx +++ b/src/environment/Settings.cxx @@ -31,168 +31,92 @@ using namespace std; using namespace rle; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Settings::Settings(RleSystem* rlesystem) : myRleSystem(rlesystem) { - // Add this settings object to the OSystem - myRleSystem->attach(this); - setInternal("sound", "false"); +Settings::Settings(){ setDefaultSettings(); - } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Settings::~Settings() { - myInternalSettings.clear(); - myExternalSettings.clear(); -} - -void Settings::loadConfig(const char* config_file) { - string line, key, value; - string::size_type equalPos, garbage; - - ifstream in(config_file); - if (!in || !in.is_open()) { - rle::Logger::Warning << "Warning: couldn't load settings file: " - << config_file << std::endl; - return; - } - - while (getline(in, line)) { - // Strip all whitespace and tabs from the line - while ((garbage = line.find("\t")) != string::npos) - line.erase(garbage, 1); - - // Ignore commented and empty lines - if ((line.length() == 0) || (line[0] == ';')) - continue; - - // Search for the equal sign and discard the line if its not found - if ((equalPos = line.find("=")) == string::npos) - continue; +Settings::~Settings() {} - // Split the line into key/value pairs and trim any whitespace - key = line.substr(0, equalPos); - value = line.substr(equalPos + 1, line.length() - key.length() - 1); - key = trim(key); - value = trim(value); - - // Check for absent key or value - if ((key.length() == 0) || (value.length() == 0)) - continue; - - // Only settings which have been previously set are valid - //ALE if(int idx = getInternalPos(key) != -1) - //ALE setInternal(key, value, idx, true); - setInternal(key, value); - } - - in.close(); -} -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Settings::loadConfig() { - loadConfig(myRleSystem->configFile().c_str()); -} +//void Settings::loadConfig(const char* config_file) { +// string line, key, value; +// string::size_type equalPos, garbage; +// +// ifstream in(config_file); +// if (!in || !in.is_open()) { +// rle::Logger::Warning << "Warning: couldn't load settings file: " +// << config_file << std::endl; +// return; +// } +// +// while (getline(in, line)) { +// // Strip all whitespace and tabs from the line +// while ((garbage = line.find("\t")) != string::npos) +// line.erase(garbage, 1); +// +// // Ignore commented and empty lines +// if ((line.length() == 0) || (line[0] == ';')) +// continue; +// +// // Search for the equal sign and discard the line if its not found +// if ((equalPos = line.find("=")) == string::npos) +// continue; +// +// // Split the line into key/value pairs and trim any whitespace +// key = line.substr(0, equalPos); +// value = line.substr(equalPos + 1, line.length() - key.length() - 1); +// key = trim(key); +// value = trim(value); +// +// // Check for absent key or value +// if ((key.length() == 0) || (value.length() == 0)) +// continue; +// } +// +// in.close(); +//} // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string Settings::loadCommandLine(int argc, char** argv) { - for (int i = 1; i < argc; ++i) { - // strip off the '-' character - string key = argv[i]; - if (key[0] == '-') { - key = key.substr(1, key.length()); - - // Take care of the arguments which are meant to be executed immediately - // (and then Stella should exit) - if (key == "help" || key == "listrominfo") { - usage(); - setExternal(key, "true"); - return ""; - } - - // Take care of arguments without an option - if (key == "rominfo" || key == "debug" || key == "holdreset" - || key == "holdselect" || key == "holdbutton0") { - setExternal(key, "true"); - continue; - } - - if (++i >= argc) { - rle::Logger::Error << "Missing argument for '" << key << "'" - << endl; - return ""; - } - string value = argv[i]; - - // Settings read from the commandline must not be saved to - // the rc-file, unless they were previously set - if (int idx = getInternalPos(key) != -1) - setInternal(key, value, idx); // don't set initialValue here - else - setExternal(key, value); - } else - return key; - } - - return ""; -} +//void Settings::loadConfig() { +// loadConfig(myRleSystem->configFile().c_str()); +//} // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Settings::validate() { - string s; - int i; - - s = getString("video"); - if (s != "soft" && s != "gl") - setInternal("video", "soft"); - -#ifdef DISPLAY_OPENGL - s = getString("gl_filter"); - if(s != "linear" && s != "nearest") - setInternal("gl_filter", "nearest"); - - i = getInt("gl_aspect"); - if(i < 50 || i > 100) - setInternal("gl_aspect", "100"); - - s = getString("gl_fsmax"); - if(s != "never" && s != "ui" && s != "tia" && s != "always") - setInternal("gl_fsmax", "never"); -#endif - -#ifdef SOUND_SUPPORT - i = getInt("volume"); - if(i < 0 || i > 100) - setInternal("volume", "100"); - i = getInt("freq"); - if(i < 0 || i > 48000) - setInternal("freq", "31400"); - i = getInt("tiafreq"); - if(i < 0 || i > 48000) - setInternal("tiafreq", "31400"); -#endif - - i = getInt("zoom_ui"); - if (i < 1 || i > 10) - setInternal("zoom_ui", "2"); - - i = getInt("zoom_tia"); - if (i < 1 || i > 10) - setInternal("zoom_tia", "2"); - - i = getInt("paddle"); - if (i < 0 || i > 3) - setInternal("paddle", "0"); - - i = getInt("pthresh"); - if (i < 400) - setInternal("pthresh", "400"); - else if (i > 800) - setInternal("pthresh", "800"); - - s = getString("prlette"); - if (s != "standard" && s != "z26" && s != "user") - setInternal("prlette", "standard"); -} - +//string Settings::loadCommandLine(int argc, char** argv) { +// for (int i = 1; i < argc; ++i) { +// // strip off the '-' character +// string key = argv[i]; +// if (key[0] == '-') { +// key = key.substr(1, key.length()); +// +// // Take care of the arguments which are meant to be executed immediately +// // (and then Stella should exit) +// if (key == "help" || key == "listrominfo") { +// usage(); +// setExternal(key, "true"); +// return ""; +// } +// +// // Take care of arguments without an option +// if (key == "rominfo" || key == "debug" || key == "holdreset" +// || key == "holdselect" || key == "holdbutton0") { +// setExternal(key, "true"); +// continue; +// } +// +// if (++i >= argc) { +// rle::Logger::Error << "Missing argument for '" << key << "'" +// << endl; +// return ""; +// } +// string value = argv[i]; +// setExternal(key, value); +// } else +// return key; +// } +// +// return ""; +//} // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Settings::usage() { @@ -263,172 +187,89 @@ void Settings::usage() { } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Settings::saveConfig() { - // Do a quick scan of the internal settings to see if any have - // changed. If not, we don't need to save them at all. - bool settingsChanged = false; - for (unsigned int i = 0; i < myInternalSettings.size(); ++i) { - if (myInternalSettings[i].value != myInternalSettings[i].initialValue) { - settingsChanged = true; - break; - } - } - - if (!settingsChanged) - return; - - ofstream out(myRleSystem->configFile().c_str()); - if (!out || !out.is_open()) { - rle::Logger::Error << "Error: Couldn't save settings file\n"; - return; - } - - out << "; Stella configuration file" << endl << ";" << endl - << "; Lines starting with ';' are comments and are ignored." - << endl << "; Spaces and tabs are ignored." << endl << ";" << endl - << "; Format MUST be as follows:" << endl << "; command = value" - << endl << ";" << endl - << "; Commmands are the same as those specified on the commandline," - << endl << "; without the '-' character." << endl << ";" << endl - << "; Values are the same as those allowed on the commandline." - << endl - << "; Boolean values are specified as 1 (or true) and 0 (or false)" - << endl << ";" << endl; - - // Write out each of the key and value pairs - for (unsigned int i = 0; i < myInternalSettings.size(); ++i) { - out << myInternalSettings[i].key << " = " << myInternalSettings[i].value - << endl; - } - - out.close(); -} +//void Settings::saveConfig(const char* outFile) { +// ofstream out(outFile); +// if (!out || !out.is_open()) { +// rle::Logger::Error << "Error: Couldn't save settings file\n"; +// return; +// } +// +// out << "; Stella configuration file" << endl << ";" << endl +// << "; Lines starting with ';' are comments and are ignored." +// << endl << "; Spaces and tabs are ignored." << endl << ";" << endl +// << "; Format MUST be as follows:" << endl << "; command = value" +// << endl << ";" << endl +// << "; Commmands are the same as those specified on the commandline," +// << endl << "; without the '-' character." << endl << ";" << endl +// << "; Values are the same as those allowed on the commandline." +// << endl +// << "; Boolean values are specified as 1 (or true) and 0 (or false)" +// << endl << ";" << endl; +// +// out.close(); +//} // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Settings::setInt(const string& key, const int value) { - std::ostringstream stream; - stream << value; - - if (int idx = getInternalPos(key) != -1) { - setInternal(key, stream.str(), idx); - } else { - verifyVariableExistence(intSettings, key); - setExternal(key, stream.str()); - } + verifyVariableExistence(intSettings, key); + intSettings.at(key) = value; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Settings::setFloat(const string& key, const float value) { - std::ostringstream stream; - stream << value; - - if (int idx = getInternalPos(key) != -1) { - setInternal(key, stream.str(), idx); - } else { - verifyVariableExistence(floatSettings, key); - setExternal(key, stream.str()); - } + verifyVariableExistence(floatSettings, key); + floatSettings.at(key) = value; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Settings::setBool(const string& key, const bool value) { - std::ostringstream stream; - stream << value; - - if (int idx = getInternalPos(key) != -1) { - setInternal(key, stream.str(), idx); - } else { - verifyVariableExistence(boolSettings, key); - setExternal(key, stream.str()); - } + verifyVariableExistence(boolSettings, key); + boolSettings.at(key) = value; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Settings::setString(const string& key, const string& value) { - if (int idx = getInternalPos(key) != -1) { - setInternal(key, value, idx); - } else { - verifyVariableExistence(stringSettings, key); - setExternal(key, value); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Settings::getSize(const string& key, int& x, int& y) const { - string size = getString(key); - replace(size.begin(), size.end(), 'x', ' '); - istringstream buf(size); - buf >> x; - buf >> y; + verifyVariableExistence(stringSettings, key); + stringSettings.at(key) = value; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - int Settings::getInt(const string& key, bool strict) const { - // Try to find the named setting and answer its value - int idx = -1; - if ((idx = getInternalPos(key)) != -1) { - return (int) atoi(myInternalSettings[idx].value.c_str()); - } else { - if ((idx = getExternalPos(key)) != -1) { - return (int) atoi(myExternalSettings[idx].value.c_str()); + try{ + return intSettings.at(key); + }catch(std::out_of_range&){ + if (strict) { + rle::Logger::Error << "No value found for key: " << key << ". "; + rle::Logger::Error << "Make sure all the settings files are loaded." + << endl; + exit(-1); } else { - if (strict) { - rle::Logger::Error << "No value found for key: " << key << ". "; - rle::Logger::Error - << "Make sure all the settings files are loaded." - << endl; - exit(-1); - } else { - return -1; - } + return -1; } } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - float Settings::getFloat(const string& key, bool strict) const { - // Try to find the named setting and answer its value - int idx = -1; - if ((idx = getInternalPos(key)) != -1) { - return (float) atof(myInternalSettings[idx].value.c_str()); - } else { - if ((idx = getExternalPos(key)) != -1) { - return (float) atof(myExternalSettings[idx].value.c_str()); + try{ + return floatSettings.at(key); + }catch(std::out_of_range&){ + if (strict) { + rle::Logger::Error << "No value found for key: " << key << ". "; + rle::Logger::Error << "Make sure all the settings files are loaded." + << endl; + exit(-1); } else { - if (strict) { - rle::Logger::Error << "No value found for key: " << key << ". "; - rle::Logger::Error - << "Make sure all the settings files are loaded." - << endl; - exit(-1); - } else { - return -1.0; - } + return -1.0; } } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool Settings::getBool(const string& key, bool strict) const { - // Try to find the named setting and answer its value - int idx = -1; - if ((idx = getInternalPos(key)) != -1) { - const string& value = myInternalSettings[idx].value; - if (value == "1" || value == "true" || value == "True") - return true; - else if (value == "0" || value == "false" || value == "False") - return false; - else - return false; - } else if ((idx = getExternalPos(key)) != -1) { - const string& value = myExternalSettings[idx].value; - if (value == "1" || value == "true") - return true; - else if (value == "0" || value == "false") - return false; - else - return false; - } else { + try{ + return boolSettings.at(key); + }catch(std::out_of_range&){ if (strict) { rle::Logger::Error << "No value found for key: " << key << ". "; rle::Logger::Error << "Make sure all the settings files are loaded." @@ -442,13 +283,9 @@ bool Settings::getBool(const string& key, bool strict) const { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - const string& Settings::getString(const string& key, bool strict) const { - // Try to find the named setting and answer its value - int idx = -1; - if ((idx = getInternalPos(key)) != -1) { - return myInternalSettings[idx].value; - } else if ((idx = getExternalPos(key)) != -1) { - return myExternalSettings[idx].value; - } else { + try{ + return stringSettings.at(key); + }catch(std::out_of_range&){ if (strict) { rle::Logger::Error << "No value found for key: " << key << ". "; rle::Logger::Error << "Make sure all the settings files are loaded." @@ -460,137 +297,6 @@ const string& Settings::getString(const string& key, bool strict) const { } } } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void Settings::setSize(const string& key, const int value1, const int value2) { - std::ostringstream buf; - buf << value1 << "x" << value2; - setString(key, buf.str()); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -int Settings::getInternalPos(const string& key) const { - for (unsigned int i = 0; i < myInternalSettings.size(); ++i) - if (myInternalSettings[i].key == key) - return i; - - return -1; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -int Settings::getExternalPos(const string& key) const { - for (unsigned int i = 0; i < myExternalSettings.size(); ++i) - if (myExternalSettings[i].key == key) - return i; - - return -1; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -int Settings::setInternal(const string& key, const string& value, int pos, - bool useAsInitial) { - int idx = -1; - - if (pos != -1 && pos >= 0 && pos < (int) myInternalSettings.size() - && myInternalSettings[pos].key == key) { - idx = pos; - } else { - for (unsigned int i = 0; i < myInternalSettings.size(); ++i) { - if (myInternalSettings[i].key == key) { - idx = i; - break; - } - } - } - - if (idx != -1) { - myInternalSettings[idx].key = key; - myInternalSettings[idx].value = value; - if (useAsInitial) - myInternalSettings[idx].initialValue = value; - - /*cerr << "modify internal: key = " << key - << ", value = " << value - << ", ivalue = " << myInternalSettings[idx].initialValue - << " @ index = " << idx - << endl;*/ - } else { - Setting setting; - setting.key = key; - setting.value = value; - if (useAsInitial) - setting.initialValue = value; - - myInternalSettings.push_back(setting); - idx = myInternalSettings.size() - 1; - - /*cerr << "insert internal: key = " << key - << ", value = " << value - << ", ivalue = " << setting.initialValue - << " @ index = " << idx - << endl;*/ - } - - return idx; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -int Settings::setExternal(const string& key, const string& value, int pos, - bool useAsInitial) { - int idx = -1; - - if (pos != -1 && pos >= 0 && pos < (int) myExternalSettings.size() - && myExternalSettings[pos].key == key) { - idx = pos; - } else { - for (unsigned int i = 0; i < myExternalSettings.size(); ++i) { - if (myExternalSettings[i].key == key) { - idx = i; - break; - } - } - } - - if (idx != -1) { - myExternalSettings[idx].key = key; - myExternalSettings[idx].value = value; - if (useAsInitial) - myExternalSettings[idx].initialValue = value; - - /*cerr << "modify external: key = " << key - << ", value = " << value - << " @ index = " << idx - << endl;*/ - } else { - Setting setting; - setting.key = key; - setting.value = value; - if (useAsInitial) - setting.initialValue = value; - - myExternalSettings.push_back(setting); - idx = myExternalSettings.size() - 1; - - /*cerr << "insert external: key = " << key - << ", value = " << value - << " @ index = " << idx - << endl;*/ - } - - return idx; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Settings::Settings(const Settings&) { -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Settings& Settings::operator =(const Settings&) { - assert(false); - - return *this; -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Settings::setDefaultSettings() { @@ -603,7 +309,7 @@ void Settings::setDefaultSettings() { // Environment customization settings boolSettings.emplace(std::make_pair("restricted_action_set", false)); - intSettings.emplace(std::make_pair("random_seed", 0)); + intSettings.emplace("random_seed", 0); boolSettings.emplace(std::make_pair("color_averaging", true)); boolSettings.emplace(std::make_pair("send_rgb", false)); intSettings.emplace(std::make_pair("frame_skip", 1)); diff --git a/src/environment/Settings.hxx b/src/environment/Settings.hxx index f7f7c4e..b07fff8 100644 --- a/src/environment/Settings.hxx +++ b/src/environment/Settings.hxx @@ -20,6 +20,8 @@ #define SETTINGS_HXX #include +#include +#include #include #include "../common/Array.hxx" @@ -42,41 +44,41 @@ class Settings /** Create a new settings abstract class */ - Settings(RleSystem* rlesystem); + Settings(); /** Destructor */ virtual ~Settings(); + // Copy constructor isn't supported by this class so make it private + Settings(const Settings&) = delete; + + // Assignment operator isn't supported by this class so make it private + Settings& operator = (const Settings&) = delete; + public: /** This method should be called to load the current settings from an rc file. */ - virtual void loadConfig(); +// virtual void loadConfig(); /** This method loads the given */ - void loadConfig(const char* config_file); +// void loadConfig(const char* config_file); /** This method should be called to save the current settings to an rc file. */ - virtual void saveConfig(); +// virtual void saveConfig(const char* outFile); /** This method should be called to load the arguments from the commandline. @return Name of the ROM to load, otherwise empty string */ - std::string loadCommandLine(int argc, char** argv); - - /** - This method should be called *after* settings have been read, - to validate (and change, if necessary) any improper settings. - */ - void validate(); +// std::string loadCommandLine(int argc, char** argv); /** This method should be called to display usage information. @@ -119,15 +121,6 @@ class Settings */ const std::string& getString(const std::string& key, bool strict = false) const; - /** - Get the x*y size assigned to the specified key. If the key does - not exist (or is invalid) then results are -1 for each item. - - @param key The key of the setting to lookup - @return The x and y values encoded in the key - */ - void getSize(const std::string& key, int& x, int& y) const; - /** Set the value associated with key to the given value. @@ -160,21 +153,8 @@ class Settings */ void setString(const std::string& key, const std::string& value); - /** - Set the value associated with key to the given value. - - @param key The key of the setting - @param value The value to assign to the setting - */ - void setSize(const std::string& key, const int value1, const int value2); - private: - // Copy constructor isn't supported by this class so make it private - Settings(const Settings&); - - // Assignment operator isn't supported by this class so make it private - Settings& operator = (const Settings&); // Trim leading and following whitespace from a string static std::string trim(std::string& str) @@ -188,9 +168,6 @@ class Settings void setDefaultSettings(); protected: - // The parent OSystem object - RleSystem* myRleSystem; - // Structure used for storing settings struct Setting { @@ -198,22 +175,7 @@ class Settings std::string value; std::string initialValue; }; - typedef Common::Array SettingsArray; - - const SettingsArray& getInternalSettings() const - { return myInternalSettings; } - const SettingsArray& getExternalSettings() const - { return myExternalSettings; } - - /** Get position in specified array of 'key' */ - int getInternalPos(const std::string& key) const; - int getExternalPos(const std::string& key) const; - - /** Add key,value pair to specified array at specified position */ - int setInternal(const std::string& key, const std::string& value, - int pos = -1, bool useAsInitial = false); - int setExternal(const std::string& key, const std::string& value, - int pos = -1, bool useAsInitial = false); + typedef std::vector SettingsArray; private: //Maps containing all external settings an user can @@ -224,16 +186,10 @@ class Settings std::map stringSettings; template void verifyVariableExistence(std::map dict, std::string key); - - // Holds key,value pairs that are necessary for Stella to - // function and must be saved on each program exit. - SettingsArray myInternalSettings; - - // Holds auxiliary key,value pairs that shouldn't be saved on - // program exit. - SettingsArray myExternalSettings; }; +typedef std::shared_ptr pSettings; + } // namespace rle #endif diff --git a/src/environment/retro_environment.cpp b/src/environment/retro_environment.cpp index 11c93b2..5dd7e20 100644 --- a/src/environment/retro_environment.cpp +++ b/src/environment/retro_environment.cpp @@ -23,14 +23,14 @@ using namespace rle; -RetroEnvironment::RetroEnvironment(RleSystem* rlesystem, RomSettings* settings) : +RetroEnvironment::RetroEnvironment(pRleSystem rlesystem, pRomSettings settings) : m_rlesystem(rlesystem), m_settings(settings), m_phosphor_blend( ), // TODO pass RleSystem - m_screen(m_rlesystem->getRetroAgent().getHeight(), - m_rlesystem->getRetroAgent().getWidth()), - m_ram(m_rlesystem->getRetroAgent().getRamSize(), - m_rlesystem->getRetroAgent().getRamAddress()), + m_screen(m_rlesystem->getRetroAgent()->getHeight(), + m_rlesystem->getRetroAgent()->getWidth()), + m_ram(m_rlesystem->getRetroAgent()->getRamSize(), + m_rlesystem->getRetroAgent()->getRamAddress()), m_player_a_action(PLAYER_A | JOYPAD_NOOP), m_player_b_action(PLAYER_B | JOYPAD_NOOP) { @@ -46,19 +46,19 @@ RetroEnvironment::RetroEnvironment(RleSystem* rlesystem, RomSettings* settings) m_num_reset_steps = 4; - m_max_num_frames_per_episode = m_rlesystem->settings().getInt("max_num_frames_per_episode"); - m_colour_averaging = m_rlesystem->settings().getBool("color_averaging"); + m_max_num_frames_per_episode = m_rlesystem->settings()->getInt("max_num_frames_per_episode"); + m_colour_averaging = m_rlesystem->settings()->getBool("color_averaging"); - m_repeat_action_probability = m_rlesystem->settings().getFloat("repeat_action_probability"); + m_repeat_action_probability = m_rlesystem->settings()->getFloat("repeat_action_probability"); - m_frame_skip = m_rlesystem->settings().getInt("frame_skip"); + m_frame_skip = m_rlesystem->settings()->getInt("frame_skip"); if (m_frame_skip < 1) { rle::Logger::Warning << "Warning: frame skip set to < 1. Setting to 1." << std::endl; m_frame_skip = 1; } // If so desired, we record all emulated frames to a given directory - std::string recordDir = m_rlesystem->settings().getString("record_screen_dir"); + std::string recordDir = m_rlesystem->settings()->getString("record_screen_dir"); getPixelFormat(*m_screen.m_pixelFormat); @@ -76,9 +76,9 @@ void RetroEnvironment::getPixelFormat(struct pixelFormat &pixel_format){ uint32_t rmask, gmask, bmask, amask; uint32_t rShift, gShift, bShift, aShift; - pixel_format.Bpp=m_rlesystem->getRetroAgent().getBpp()/8; //in bytes - m_rlesystem->getRetroAgent().getRgbMask(rmask, gmask, bmask, amask); - m_rlesystem->getRetroAgent().getRgbShift(rShift, gShift, bShift, aShift); + pixel_format.Bpp=m_rlesystem->getRetroAgent()->getBpp()/8; //in bytes + m_rlesystem->getRetroAgent()->getRgbMask(rmask, gmask, bmask, amask); + m_rlesystem->getRetroAgent()->getRgbShift(rShift, gShift, bShift, aShift); //mask pixel_format.rmask=rmask; pixel_format.gmask=gmask; @@ -101,12 +101,11 @@ void RetroEnvironment::reset() { m_state.resetEpisodeFrameNumber(); // Reset the emulator - m_rlesystem->getRetroAgent().reset(); + m_rlesystem->getRetroAgent()->reset(); // NOOP for 60 steps in the deterministic environment setting, or some random amount otherwise int noopSteps; noopSteps = 60; - emulateStart(PLAYER_A | JOYPAD_NOOP, PLAYER_B | JOYPAD_NOOP, noopSteps); // reset for n steps emulateStart(JOYPAD_RESET, PLAYER_B | JOYPAD_NOOP, m_num_reset_steps); @@ -255,7 +254,7 @@ void RetroEnvironment::emulate(const Action& player_a_action, const Action& play // else { // In joystick mode we only need to set the action events once // m_state.setActionJoysticks(player_a_action, player_b_action); - m_rlesystem->getRetroAgent().SetActions(player_a_action,player_b_action); + m_rlesystem->getRetroAgent()->SetActions(player_a_action,player_b_action); for (size_t t = 0; t < num_steps; ++t) { m_rlesystem->step(); @@ -269,8 +268,7 @@ void RetroEnvironment::emulate(const Action& player_a_action, const Action& play } void RetroEnvironment::emulateStart(Action player_a_action, Action player_b_action, size_t num_steps) { - - m_rlesystem->getRetroAgent().SetActions(player_a_action,player_b_action); + m_rlesystem->getRetroAgent()->SetActions(player_a_action,player_b_action); for (size_t t = 0; t < num_steps; ++t) { m_rlesystem->step(); } @@ -293,10 +291,10 @@ void RetroEnvironment::processScreen() { // else { // Copy screen over and we're done! // memcpy(m_screen.getArray(),(uint32_t*) m_rlesystem->getCurrentFrameBuffer(), 4*m_rlesystem->getRetroAgent().getBufferSize()); //shai: consider adding min/max of size // *4 to go to pixel - int height = m_rlesystem->getRetroAgent().getHeight(); - int width = m_rlesystem->getRetroAgent().getWidth(); - int Bpp = m_rlesystem->getRetroAgent().getBpp() / 8; - int pitch = m_rlesystem->getRetroAgent().getPitch(); + int height = m_rlesystem->getRetroAgent()->getHeight(); + int width = m_rlesystem->getRetroAgent()->getWidth(); + int Bpp = m_rlesystem->getRetroAgent()->getBpp() / 8; + int pitch = m_rlesystem->getRetroAgent()->getPitch(); uint8_t* buffer = m_rlesystem->getCurrentFrameBuffer(); for(int i = 0 ; i < height; ++i){ memcpy((uint8_t*)m_screen.getArray() + i*width *Bpp , buffer + i*pitch, width * Bpp); diff --git a/src/environment/retro_environment.hpp b/src/environment/retro_environment.hpp index ca685c0..dcd17c0 100644 --- a/src/environment/retro_environment.hpp +++ b/src/environment/retro_environment.hpp @@ -54,8 +54,8 @@ class RetroEnvironment { public: RetroEnvironment( - RleSystem * system, - RomSettings * settings); + pRleSystem system, + pRomSettings settings); /** Resets the system to its start state. */ void reset(); @@ -119,8 +119,8 @@ class RetroEnvironment { void getPixelFormat(struct pixelFormat &m_pixelFormat); private: - RleSystem *m_rlesystem; - RomSettings *m_settings; + pRleSystem m_rlesystem; + pRomSettings m_settings; PhosphorBlend m_phosphor_blend; // For performing phosphor colour averaging, if so desired // std::string m_cartridge_md5; // Necessary for saving and loading emulator state @@ -144,6 +144,7 @@ class RetroEnvironment { Action m_player_a_action, m_player_b_action; }; +typedef shared_ptr pRetroEnvironment; } // namespace rle diff --git a/src/environment/rle_state.cpp b/src/environment/rle_state.cpp index 8119ffa..0b420f2 100644 --- a/src/environment/rle_state.cpp +++ b/src/environment/rle_state.cpp @@ -40,8 +40,8 @@ RLEState::RLEState(const std::string &serialized) { /** Restores ALE to the given previously saved state. */ void RLEState::load( - RleSystem* rlesystem, - RomSettings* settings, const RLEState &rhs, + pRleSystem rlesystem, + pRomSettings settings, const RLEState &rhs, bool load_system) { assert(rhs.m_serialized_state.length() > 0); @@ -53,7 +53,7 @@ void RLEState::load( throw new std::runtime_error("Attempting to load an RLEState which does not contain " "system information."); - rlesystem->getRetroAgent().deserialize(deser); + rlesystem->getRetroAgent()->deserialize(deser); // If we have osystem data, load it as well if (load_system) rlesystem->loadState(deser); @@ -64,8 +64,8 @@ void RLEState::load( } RLEState RLEState::save( - RleSystem* rlesystem, - RomSettings* settings, + pRleSystem rlesystem, + pRomSettings settings, bool save_system) { // Use the emulator's built-in serialization to save the state Serializer ser; @@ -73,7 +73,7 @@ RLEState RLEState::save( // We use 'save_system' as a check at load time. ser.putBool(save_system); - rlesystem->getRetroAgent().serialize(ser); + rlesystem->getRetroAgent()->serialize(ser); if (save_system) rlesystem->saveState(ser); settings->saveState(ser); diff --git a/src/environment/rle_state.hpp b/src/environment/rle_state.hpp index 0f131e2..12e269d 100644 --- a/src/environment/rle_state.hpp +++ b/src/environment/rle_state.hpp @@ -62,15 +62,15 @@ class RLEState { /** Restores the environment to a previously saved state. If load_system == true, we also restore system-specific information (such as the RNG state). */ void load( - RleSystem* rlesystem, - RomSettings* settings, const RLEState &rhs, + pRleSystem rlesystem, + pRomSettings settings, const RLEState &rhs, bool load_system); /** Returns a "copy" of the current state, including the information necessary to restore * the emulator. If save_system == true, this includes the RNG state. */ RLEState save( - RleSystem* rlesystem, - RomSettings* settings, bool save_system); + pRleSystem rlesystem, + pRomSettings settings, bool save_system); private: diff --git a/src/games/AtariSettings.cpp b/src/games/AtariSettings.cpp index fa35afd..7439e83 100644 --- a/src/games/AtariSettings.cpp +++ b/src/games/AtariSettings.cpp @@ -43,5 +43,5 @@ AtariSettings::AtariSettings(){ } int AtariSettings::readRam(const RleSystem* system, int offset){ - RomSettings::readRam(system, offset & 0x7F ); + return RomSettings::readRam(system, offset & 0x7F ); } diff --git a/src/games/RomSettings.cpp b/src/games/RomSettings.cpp index 4e3e6d3..3462ee3 100644 --- a/src/games/RomSettings.cpp +++ b/src/games/RomSettings.cpp @@ -53,12 +53,12 @@ ActionVect RomSettings::getAllActions() { int RomSettings::readRam(const RleSystem* system, int offset) { - return system->getRetroAgent().readRam((offset)); + return system->getRetroAgent()->readRam((offset)); } void RomSettings::writeRam(const RleSystem* system, int offset, uint8_t data) { - return system->getRetroAgent().writeRam(offset, data ); + return system->getRetroAgent()->writeRam(offset, data ); } diff --git a/src/games/RomSettings.hpp b/src/games/RomSettings.hpp index 94c95ac..b033259 100644 --- a/src/games/RomSettings.hpp +++ b/src/games/RomSettings.hpp @@ -127,6 +127,7 @@ struct RomSettings { protected: ActionVect AllActionsVector; }; +typedef shared_ptr pRomSettings; } // namespace rle diff --git a/src/games/supported/Aladdin.cpp b/src/games/supported/Aladdin.cpp index 78408d7..573ff07 100644 --- a/src/games/supported/Aladdin.cpp +++ b/src/games/supported/Aladdin.cpp @@ -53,8 +53,8 @@ void AladdinSettings::step(const RleSystem& system) { // update the reward reward_t playerScore = 256*readRam(&system, 0xF411) + readRam(&system, 0xF410); //based solely on moving right reward_t healthBonus = m_health - readRam(&system, 0x366); // adding health bonus to discourage getting hit - int apples = readRam(&system, 0x368); - int dimonds = readRam(&system, 0x36a); +// int apples = readRam(&system, 0x368); +// int diamonds = readRam(&system, 0x36a); playerScore += healthBonus; int current_lives = readRam(&system, 0x363)-1; m_reward = playerScore - m_score; diff --git a/src/games/supported/MortalKombat.cpp b/src/games/supported/MortalKombat.cpp index b42ce98..bb370c6 100644 --- a/src/games/supported/MortalKombat.cpp +++ b/src/games/supported/MortalKombat.cpp @@ -91,7 +91,7 @@ void MortalKombatSettings::step(const RleSystem& system) { m_wins = getDecimalScore(0x196e, &system); o_wins = getDecimalScore(0x1aca, &system); - if(system.settings().getBool("MK_random_position")){ + if(system.settings()->getBool("MK_random_position")){ if((m_wins + o_wins) != totalWins){ match_ended = true; } @@ -162,7 +162,7 @@ ActionVect MortalKombatSettings::getStartingActions(const RleSystem& system){ INSERT_NOPS(num_of_nops) INSERT_ACTION_SINGLE_A(JOYPAD_DOWN) INSERT_NOPS(num_of_nops) - string difficulty = system.settings().getString("MK_difficulty"); + string difficulty = system.settings()->getString("MK_difficulty"); if("medium" == difficulty){ }else if("hard" == difficulty){ INSERT_ACTION_SINGLE_A(JOYPAD_X) @@ -197,7 +197,7 @@ ActionVect MortalKombatSettings::getStartingActions(const RleSystem& system){ INSERT_NOPS(3.5*num_of_nops) // choose character from list - string player1_character = system.settings().getString("MK_player1_character"); + string player1_character = system.settings()->getString("MK_player1_character"); if("rayden" == player1_character){ INSERT_ACTION_SINGLE(JOYPAD_DOWN, A) }else if("sonya" == player1_character){ @@ -223,7 +223,7 @@ ActionVect MortalKombatSettings::getStartingActions(const RleSystem& system){ INSERT_NOPS(num_of_nops) // Select opponent: random seed for opponent is set by num of NOOPs - int opponent_character_nops = system.settings().getInt("MK_opponent_character"); + int opponent_character_nops = system.settings()->getInt("MK_opponent_character"); INSERT_NOPS(opponent_character_nops); // select character @@ -243,7 +243,7 @@ ActionVect MortalKombatSettings::getStartingActions(const RleSystem& system){ } void MortalKombatSettings::startingOperations(RleSystem& system){ - if(system.settings().getBool("MK_random_position")){ + if(system.settings()->getBool("MK_random_position")){ Random& rng = system.rng(); writeRam(&system, 0x30d, (rng.next()%0x100)); // set player 1's random init position writeRam(&system, 0x30f, (rng.next()%0x100)); // set player 2's random init position diff --git a/src/games/supported/MortalKombat2Players.cpp b/src/games/supported/MortalKombat2Players.cpp index 0ef963b..b83b02d 100644 --- a/src/games/supported/MortalKombat2Players.cpp +++ b/src/games/supported/MortalKombat2Players.cpp @@ -74,7 +74,7 @@ ActionVect MortalKombat2PlayersSettings::getStartingActions(const RleSystem& sys INSERT_NOPS(num_of_nops) INSERT_ACTION_SINGLE_A(JOYPAD_DOWN) INSERT_NOPS(num_of_nops) - string difficulty = system.settings().getString("MK_difficulty"); + string difficulty = system.settings()->getString("MK_difficulty"); if("medium" == difficulty){ }else if("hard" == difficulty){ INSERT_ACTION_SINGLE_A(JOYPAD_X) @@ -112,7 +112,7 @@ ActionVect MortalKombat2PlayersSettings::getStartingActions(const RleSystem& sys INSERT_ACTION_SINGLE(JOYPAD_START, B) // choose character from list - string player1_character = system.settings().getString("MK_player1_character"); + string player1_character = system.settings()->getString("MK_player1_character"); if("rayden" == player1_character){ INSERT_ACTION_SINGLE(JOYPAD_DOWN, A) }else if("sonya" == player1_character){ @@ -138,7 +138,7 @@ ActionVect MortalKombat2PlayersSettings::getStartingActions(const RleSystem& sys INSERT_NOPS(num_of_nops) // choose for player b - Sonya // choose character from list - string player2_character = system.settings().getString("MK_player2_character"); + string player2_character = system.settings()->getString("MK_player2_character"); if("rayden" == player2_character){ INSERT_ACTION_SINGLE(JOYPAD_LEFT, B) INSERT_ACTION_SINGLE(JOYPAD_NOOP, B) diff --git a/src/games/supported/SonicTheHedgehog.cpp b/src/games/supported/SonicTheHedgehog.cpp index 235ac4a..07118f0 100644 --- a/src/games/supported/SonicTheHedgehog.cpp +++ b/src/games/supported/SonicTheHedgehog.cpp @@ -53,7 +53,7 @@ void SonicTheHedgehogSettings::step(const RleSystem& system) { // update the reward m_reward = score - m_score; - if(system.settings().getBool("sonic1_ring_reward")){ + if(system.settings()->getBool("sonic1_ring_reward")){ m_reward += rings - m_rings; } diff --git a/src/games/supported/StreetFighterII.cpp b/src/games/supported/StreetFighterII.cpp index 091ccda..89fbdac 100644 --- a/src/games/supported/StreetFighterII.cpp +++ b/src/games/supported/StreetFighterII.cpp @@ -91,7 +91,7 @@ void StreetFighterIISettings::step(const RleSystem& system) { } - int totalWins = m_wins + o_wins; +// int totalWins = m_wins + o_wins; m_wins = getDecimalScore(0xcd0, &system); o_wins = getDecimalScore(0xed0, &system); // cout << "player score: " << playerScore << " Time: " diff --git a/src/os_dependent/OSystemWin32.cxx b/src/os_dependent/OSystemWin32.cxx deleted file mode 100644 index 22112d0..0000000 --- a/src/os_dependent/OSystemWin32.cxx +++ /dev/null @@ -1,63 +0,0 @@ -////============================================================================ -//// -//// SSSS tt lll lll -//// SS SS tt ll ll -//// SS tttttt eeee ll ll aaaa -//// SSSS tt ee ee ll ll aa -//// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" -//// SS SS tt ee ll ll aa aa -//// SSSS ttt eeeee llll llll aaaaa -//// -//// Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team -//// -//// See the file "license" for information on usage and redistribution of -//// this file, and for a DISCLAIMER OF ALL WARRANTIES. -//// -//// $Id: OSystemWin32.cxx,v 1.20 2007/08/04 20:32:54 stephena Exp $ -////============================================================================ -// -//#include -//#include -//#include -// -//#include "bspf.hxx" -//#include "OSystem.hxx" -//#include "OSystemWin32.hxx" -// -//using namespace std; -// -///** -// Each derived class is responsible for calling the following methods -// in its constructor: -// -// setBaseDir() -// setConfigFile() -// -// See OSystem.hxx for a further explanation -//*/ -// -//// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -//OSystemWin32::OSystemWin32() -// : OSystem() -//{ -// // TODO - there really should be code here to determine which version -// // of Windows is being used. -// // If using a version which supports multiple users (NT and above), -// // the relevant directories should be created in per-user locations. -// // For now, we just put it in the same directory as the executable. -// const string& basedir = "."; -// setBaseDir(basedir); -// setConfigFile(basedir + "\\rle.cfg"); -//} -// -//// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -//OSystemWin32::~OSystemWin32() -//{ -//} -// -//// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -//uInt32 OSystemWin32::getTicks() -//{ -// //return (uInt32) SDL_GetTicks() * 1000; -// return static_cast(GetTickCount() * 1000); -//} diff --git a/src/os_dependent/OSystemWin32.hxx b/src/os_dependent/OSystemWin32.hxx deleted file mode 100644 index 0d9befd..0000000 --- a/src/os_dependent/OSystemWin32.hxx +++ /dev/null @@ -1,52 +0,0 @@ -////============================================================================ -//// -//// SSSS tt lll lll -//// SS SS tt ll ll -//// SS tttttt eeee ll ll aaaa -//// SSSS tt ee ee ll ll aa -//// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" -//// SS SS tt ee ll ll aa aa -//// SSSS ttt eeeee llll llll aaaaa -//// -//// Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team -//// -//// See the file "license" for information on usage and redistribution of -//// this file, and for a DISCLAIMER OF ALL WARRANTIES. -//// -//// $Id: OSystemWin32.hxx,v 1.11 2007/07/19 16:21:39 stephena Exp $ -////============================================================================ -// -//#ifndef OSYSTEM_WIN32_HXX -//#define OSYSTEM_WIN32_HXX -// -//#include "../emucore/m6502/src/bspf/src/bspf.hxx" -// -///** -// This class defines Windows system specific settings. -// -// @author Stephen Anthony -// @version $Id: OSystemWin32.hxx,v 1.11 2007/07/19 16:21:39 stephena Exp $ -//*/ -//class OSystemWin32 : public OSystem -//{ -// public: -// /** -// Create a new Win32 operating system object -// */ -// OSystemWin32(); -// -// /** -// Destructor -// */ -// virtual ~OSystemWin32(); -// -// public: -// /** -// This method returns number of ticks in microseconds. -// -// @return Current time in microseconds. -// */ -// virtual uInt32 getTicks(); -//}; -// -//#endif diff --git a/src/os_dependent/RleSystemUNIX.cxx b/src/os_dependent/RleSystemUNIX.cxx deleted file mode 100644 index 2486def..0000000 --- a/src/os_dependent/RleSystemUNIX.cxx +++ /dev/null @@ -1,71 +0,0 @@ -//============================================================================ -// -// SSSS tt lll lll -// SS SS tt ll ll -// SS tttttt eeee ll ll aaaa -// SSSS tt ee ee ll ll aa -// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" -// SS SS tt ee ll ll aa aa -// SSSS ttt eeeee llll llll aaaaa -// -// Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team -// -// See the file "license" for information on usage and redistribution of -// this file, and for a DISCLAIMER OF ALL WARRANTIES. -// -// $Id: RleSystemUNIX.cxx,v 1.27 2007/07/19 16:21:39 stephena Exp $ -//============================================================================ - -#include -#include -#include - -#include -#include -#include - -//#include "bspf.hxx" -#include "RleSystem.hxx" -#include "RleSystemUNIX.hxx" -using namespace std; -using namespace rle; - -//ALE #ifdef HAVE_GETTIMEOFDAY -#include -#include -//ALE #endif - -/** - Each derived class is responsible for calling the following methods - in its constructor: - - setBaseDir() - setConfigFile() - - See OSystem.hxx for a further explanation -*/ - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -RleSystemUNIX::RleSystemUNIX(RetroAgent* retroagent) - : RleSystem(retroagent) -{ - //ALE const string& basedir = string(getenv("HOME")) + "/.stella"; - string basedir = string("."); //ALE - setBaseDir(basedir); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -RleSystemUNIX::~RleSystemUNIX() -{ -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 RleSystemUNIX::getTicks() { -//ALE #ifdef HAVE_GETTIMEOFDAY - timeval now; - gettimeofday(&now, 0); - return (uInt32) (now.tv_sec * 1000000 + now.tv_usec); -//ALE #else -//ALE return (uInt32) SDL_GetTicks() * 1000; -//ALE #endif -} diff --git a/src/os_dependent/RleSystemUNIX.hxx b/src/os_dependent/RleSystemUNIX.hxx deleted file mode 100644 index 96a9bba..0000000 --- a/src/os_dependent/RleSystemUNIX.hxx +++ /dev/null @@ -1,58 +0,0 @@ -//============================================================================ -// -// SSSS tt lll lll -// SS SS tt ll ll -// SS tttttt eeee ll ll aaaa -// SSSS tt ee ee ll ll aa -// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" -// SS SS tt ee ll ll aa aa -// SSSS ttt eeeee llll llll aaaaa -// -// Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team -// -// See the file "license" for information on usage and redistribution of -// this file, and for a DISCLAIMER OF ALL WARRANTIES. -// -// $Id: RleSystemUNIX.hxx,v 1.16 2007/07/19 16:21:39 stephena Exp $ -//============================================================================ - -#ifndef OSYSTEM_UNIX_HXX -#define OSYSTEM_UNIX_HXX - -#include "../common/bspf.hxx" -#include "../environment/RleSystem.hxx" - -namespace rle { - -class RetroAgent; - -/** - This class defines UNIX-like OS's (Linux) system specific settings. - - @author Stephen Anthony - @version $Id: RleSystemUNIX.hxx,v 1.16 2007/07/19 16:21:39 stephena Exp $ -*/ -class RleSystemUNIX : public RleSystem -{ - public: - /** - Create a new UNIX-specific operating system object - */ - RleSystemUNIX(RetroAgent* retroagent); - - /** - Destructor - */ - virtual ~RleSystemUNIX(); - - /** - This method returns number of ticks in microseconds. - - @return Current time in microseconds. - */ - uInt32 getTicks(); -}; - -} // namespace rle - -#endif diff --git a/src/os_dependent/SettingsUNIX.cxx b/src/os_dependent/SettingsUNIX.cxx deleted file mode 100644 index bbfda26..0000000 --- a/src/os_dependent/SettingsUNIX.cxx +++ /dev/null @@ -1,41 +0,0 @@ -//============================================================================ -// -// SSSS tt lll lll -// SS SS tt ll ll -// SS tttttt eeee ll ll aaaa -// SSSS tt ee ee ll ll aa -// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" -// SS SS tt ee ll ll aa aa -// SSSS ttt eeeee llll llll aaaaa -// -// Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team -// -// See the file "license" for information on usage and redistribution of -// this file, and for a DISCLAIMER OF ALL WARRANTIES. -// -// $Id: SettingsUNIX.cxx,v 1.23 2007/07/27 13:49:16 stephena Exp $ -//============================================================================ - -#include "bspf.hxx" -#include "SettingsUNIX.hxx" - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#include "SettingsUNIX.hxx" - -namespace rle { - -SettingsUNIX::SettingsUNIX(RleSystem* rlesystem) - : Settings(rlesystem) -{ - setInternal("gl_lib", "libGL.so"); - // Most Linux GL implementations don't support this yet - setInternal("gl_vsync", "false"); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -SettingsUNIX::~SettingsUNIX() -{ -} - -} // namespace rle diff --git a/src/os_dependent/SettingsUNIX.hxx b/src/os_dependent/SettingsUNIX.hxx deleted file mode 100644 index e9677df..0000000 --- a/src/os_dependent/SettingsUNIX.hxx +++ /dev/null @@ -1,48 +0,0 @@ -//============================================================================ -// -// SSSS tt lll lll -// SS SS tt ll ll -// SS tttttt eeee ll ll aaaa -// SSSS tt ee ee ll ll aa -// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" -// SS SS tt ee ll ll aa aa -// SSSS ttt eeeee llll llll aaaaa -// -// Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team -// -// See the file "license" for information on usage and redistribution of -// this file, and for a DISCLAIMER OF ALL WARRANTIES. -// -// $Id: SettingsUNIX.hxx,v 1.8 2007/01/01 18:04:55 stephena Exp $ -//============================================================================ - -#ifndef SETTINGS_UNIX_HXX -#define SETTINGS_UNIX_HXX - -#include "../environment/Settings.hxx" -#include "../environment/RleSystem.hxx" - -namespace rle { -/** - This class defines UNIX-like OS's (Linux) system specific settings. - - @author Stephen Anthony - @version $Id: SettingsUNIX.hxx,v 1.8 2007/01/01 18:04:55 stephena Exp $ -*/ -class SettingsUNIX : public Settings -{ - public: - /** - Create a new UNIX settings object - */ - SettingsUNIX(RleSystem* rleSystem); - - /** - Destructor - */ - virtual ~SettingsUNIX(); -}; - -} // namespace rle - -#endif diff --git a/src/os_dependent/SettingsWin32.cxx b/src/os_dependent/SettingsWin32.cxx deleted file mode 100644 index a82adb7..0000000 --- a/src/os_dependent/SettingsWin32.cxx +++ /dev/null @@ -1,37 +0,0 @@ -////============================================================================ -//// -//// SSSS tt lll lll -//// SS SS tt ll ll -//// SS tttttt eeee ll ll aaaa -//// SSSS tt ee ee ll ll aa -//// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" -//// SS SS tt ee ll ll aa aa -//// SSSS ttt eeeee llll llll aaaaa -//// -//// Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team -//// -//// See the file "license" for information on usage and redistribution of -//// this file, and for a DISCLAIMER OF ALL WARRANTIES. -//// -//// $Id: SettingsWin32.cxx,v 1.26 2007/01/01 18:04:56 stephena Exp $ -////============================================================================ -// -//#include "bspf.hxx" -//#include "Settings.hxx" -//#include "SettingsWin32.hxx" -// -//// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -//SettingsWin32::SettingsWin32(OSystem* osystem) -// : Settings(osystem) -//{ -// // Anything less than this usually causes sound skipping -// setInternal("fragsize", "2048"); -// // Most Windows systems work better without this -// setInternal("dirtyrects", "false"); -// setInternal("romdir", "c:\\"); -//} -// -//// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -//SettingsWin32::~SettingsWin32() -//{ -//} diff --git a/src/os_dependent/SettingsWin32.hxx b/src/os_dependent/SettingsWin32.hxx deleted file mode 100644 index 8c32a1b..0000000 --- a/src/os_dependent/SettingsWin32.hxx +++ /dev/null @@ -1,41 +0,0 @@ -////============================================================================ -//// -//// SSSS tt lll lll -//// SS SS tt ll ll -//// SS tttttt eeee ll ll aaaa -//// SSSS tt ee ee ll ll aa -//// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" -//// SS SS tt ee ll ll aa aa -//// SSSS ttt eeeee llll llll aaaaa -//// -//// Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team -//// -//// See the file "license" for information on usage and redistribution of -//// this file, and for a DISCLAIMER OF ALL WARRANTIES. -//// -//// $Id: SettingsWin32.hxx,v 1.8 2007/01/01 18:04:56 stephena Exp $ -////============================================================================ -// -//#ifndef SETTINGS_WIN32_HXX -//#define SETTINGS_WIN32_HXX -// -//class OSystem; -// -//#include "../environment/Settings.hxx" -// -// -//class SettingsWin32 : public Settings -//{ -// public: -// /** -// Create a new UNIX settings object -// */ -// SettingsWin32(OSystem* osystem); -// -// /** -// Destructor -// */ -// virtual ~SettingsWin32(); -//}; -// -//#endif diff --git a/src/rle_interface.cpp b/src/rle_interface.cpp index f1c2cac..cc707df 100644 --- a/src/rle_interface.cpp +++ b/src/rle_interface.cpp @@ -29,14 +29,10 @@ **************************************************************************** */ #include "rle_interface.hpp" -#include "os_dependent/SettingsWin32.hxx" -#include "os_dependent/SettingsUNIX.hxx" -#include "os_dependent/RleSystemUNIX.hxx" +#include "RleSystem.hxx" #include "games/Roms.hpp" #include "common/display_screen.h" #include "environment/retro_environment.hpp" -#include "os_dependent/SettingsUNIX.hxx" -#include "os_dependent/SettingsWin32.hxx" #include "environment/FSNode.hxx" //#include "common/ScreenExporter.hpp" #include "common/Log.hpp" @@ -140,18 +136,18 @@ class RLEInterface::Impl{ ScreenExporter *createScreenExporter(const std::string &path) const; // static functions - void createRleSystem(std::unique_ptr &theRleSystem, - std::unique_ptr &theSettings, - std::unique_ptr &theRetroAgent); + void createRleSystem(pRleSystem &theRleSystem, + pSettings &theSettings, + pRetroAgent &theRetroAgent); void loadSettings(const std::string& romfile, const std::string& corefile, - std::unique_ptr &theSLESystem); + pRleSystem &theSLESystem); private: - std::unique_ptr theRleSystem; - std::unique_ptr theSettings; - std::unique_ptr theRetroAgent; - std::unique_ptr romSettings; - std::unique_ptr environment; + pRleSystem theRleSystem; + pSettings theSettings; + pRetroAgent theRetroAgent; + pRomSettings romSettings; + pRetroEnvironment environment; int max_num_frames; // Maximum number of frames for each episode bool gameLoaded; }; @@ -189,25 +185,21 @@ void RLEInterface::Impl::setString(const string& key, const string& value) { assert(theSettings); assert(theRleSystem); theSettings->setString(key, value); - theSettings->validate(); } void RLEInterface::Impl::setInt(const string& key, const int value) { assert(theSettings); assert(theRleSystem); theSettings->setInt(key, value); - theSettings->validate(); } void RLEInterface::Impl::setBool(const string& key, const bool value) { assert(theSettings); assert(theRleSystem); theSettings->setBool(key, value); - theSettings->validate(); } void RLEInterface::Impl::setFloat(const string& key, const float value) { assert(theSettings); assert(theRleSystem); theSettings->setFloat(key, value); - theSettings->validate(); if(key == "random_seed"){ theRleSystem->resetRNGSeed(); } @@ -312,55 +304,39 @@ void RLEInterface::disableBufferedIO() { cout.sync_with_stdio(); } -void RLEInterface::createRleSystem(std::unique_ptr &theRleSystem, - std::unique_ptr &theSettings, - std::unique_ptr &theRetroAgent) { -#if (defined(WIN32) || defined(__MINGW32__)) +void RLEInterface::createRleSystem(pRleSystem& theRleSystem, + pSettings& theSettings, + pRetroAgent& theRetroAgent) { theRetroAgent.reset(new RetroAgent()); - theRleSystem.reset(new OSystemWin32()); - theSettings.reset(new SettingsWin32(theRleSystem.get())); -#else - theRetroAgent.reset(new RetroAgent()); - theRleSystem.reset(new RleSystemUNIX(theRetroAgent.get())); - theSettings.reset(new SettingsUNIX(theRleSystem.get())); -#endif - - theRleSystem->settings().loadConfig(); + theSettings.reset(new Settings()); + theRleSystem.reset(new RleSystem(theRetroAgent, theSettings)); } void RLEInterface::loadSettings(const string& romfile, const std::string& corefile, - std::unique_ptr &theRleSystem) { - // Load the configuration from a config file (passed on the command - // line), if provided - string configFile = theRleSystem->settings().getString("config", false); - - if (!configFile.empty()) - theRleSystem->settings().loadConfig(configFile.c_str()); - - theRleSystem->settings().validate(); - theRleSystem->create(); - - if (romfile == "" || !FilesystemNode::fileExists(romfile)) { - Logger::Error << "No ROM File specified or the ROM file was not found." + pRleSystem &theRleSystem) { +// // Load the configuration from a config file (passed on the command +// // line), if provided +// string configFile = theRleSystem->settings().getString("config", false); +// +// if (!configFile.empty()) +// theRleSystem->settings().loadConfig(configFile.c_str()); + + if (romfile == "" || !FilesystemNode::fileExists(romfile)) { + Logger::Error << "No ROM File specified or the ROM file was not found." << std::endl; - exit(1); - } + exit(1); + } theRleSystem->loadCore(corefile); theRleSystem->loadRom(romfile); Logger::Info << "Running ROM file..." << std::endl; - theRleSystem->settings().setString("rom_file", romfile); + theRleSystem->settings()->setString("rom_file", romfile); #ifdef __USE_SDL - if(theRleSystem->settings().getBool("display_screen")){ - theRleSystem->p_display_screen = new DisplayScreen(&theRleSystem->getRetroAgent()); + if(theRleSystem->settings()->getBool("display_screen")){ + theRleSystem->p_display_screen = make_shared(&theRleSystem->getRetroAgent()); } #endif - //Shai : added format handling for RGB - - // Must force the resetting of the OSystem's random seed, which is set before we change - // choose our random seed. - Logger::Info << "Random seed is " << theRleSystem->settings().getInt("random_seed") << std::endl; - theRleSystem->resetRNGSeed(); - + Logger::Info << "Random seed is " << theRleSystem->settings()->getInt("random_seed") << std::endl; + theRleSystem->resetRNGSeed(); } void RLEInterface::loadROM(string rom_file, string core_file) { @@ -372,7 +348,7 @@ void RLEInterface::loadROM(string rom_file, string core_file) { // necessary after changing a setting. Optionally specify a new rom to // load. void RLEInterface::Impl::loadROM(string rom_file, string core_file) { - assert(theRleSystem.get()); + assert(theRleSystem); if (rom_file.empty()) { rom_file = theRleSystem->romFile(); } @@ -380,16 +356,18 @@ void RLEInterface::Impl::loadROM(string rom_file, string core_file) { core_file = theRleSystem->coreFile(); } RLEInterface::loadSettings(rom_file, core_file, theRleSystem); + bool twoPlayers = getBool("two_players"); romSettings.reset(buildRomRLWrapper(rom_file, twoPlayers)); - environment.reset(new RetroEnvironment(theRleSystem.get(), romSettings.get())); - max_num_frames = theRleSystem->settings().getInt("max_num_frames_per_episode"); + environment = make_shared(theRleSystem, romSettings); + max_num_frames = theRleSystem->settings()->getInt("max_num_frames_per_episode"); environment->reset(); + #ifndef __USE_SDL - if (theRleSystem->p_display_screen != NULL) { + if (theRleSystem->p_display_screen) { Logger::Error << "Screen display requires directive __USE_SDL to be defined." << endl; Logger::Error << "Please recompile this code with flag '-D__USE_SDL'." << endl; - Logger::Error << "Also ensure ALE has been compiled with USE_SDL active (see ALE makefile)." << endl; + Logger::Error << "Also ensure RLE has been compiled with USE_SDL active (see RLE makefile)." << endl; exit(1); } #endif diff --git a/src/rle_interface.hpp b/src/rle_interface.hpp index a4ebadc..eb665c1 100644 --- a/src/rle_interface.hpp +++ b/src/rle_interface.hpp @@ -21,7 +21,12 @@ * * Based on: Stella -- "An Atari 2600 VCS Emulator" * Copyright (c) 1995-2007 by Bradford W. Mott and the Stella team + * ***************************************************************************** + * R.L.E (Retro Learning Environment) + * Copyright (c) 2016-2017 by Shai Rozenberg, Nadav Bhonker and Itay Hubara. * + * Based on: A.L.E (see above) + * Released under the GNU General Public License; see License.txt for details. * ***************************************************************************** * rle_interface.hpp * @@ -40,7 +45,7 @@ namespace rle { -static const std::string Version = "1.0.0"; +static const std::string Version = "1.1.1"; class RleSystem; class Settings; @@ -283,11 +288,12 @@ class RLEInterface { // Display RLE welcome message static std::string welcomeMessage(); static void disableBufferedIO(); - static void createRleSystem(std::unique_ptr &theRleSystem, - std::unique_ptr &theSettings, - std::unique_ptr &theRetroAgent); + static void createRleSystem(std::shared_ptr& theRleSystem, + std::shared_ptr& theSettings, + std::shared_ptr& theRetroAgent); static void loadSettings(const std::string& romfile, const std::string& corefile, - std::unique_ptr &theSLESystem); + std::shared_ptr &theRleSystem); +// TODO: add loadConfigFile function private: class Impl; Impl* m_pimpl; diff --git a/test/RetroAgentTest.cpp b/test/RetroAgentTest.cpp index 21687bf..05a0d7f 100644 --- a/test/RetroAgentTest.cpp +++ b/test/RetroAgentTest.cpp @@ -73,5 +73,16 @@ TEST_F(RetroAgentTest, multiThreading) { } } +TEST_F(RetroAgentTest, multiLoadRom) { + RetroAgent agent; + initRetroAgent(&agent, corePath, romPath); + for(int i(0); i< 2; i++){ + agent.loadRom(romPath); + for(int j(0); j< 100; j++){ + agent.run(); + } +// agent.reset(); + } +} } diff --git a/test/RleTest.cpp b/test/RleTest.cpp index 8d7ebf4..b076ddd 100644 --- a/test/RleTest.cpp +++ b/test/RleTest.cpp @@ -97,11 +97,24 @@ TEST_F(RleTest, testRam) { run_example(&rle, romPath, corePath); RLERAM ram = rle.getRAM(); size_t size = ram.size(); - EXPECT_EQ(128 * 1024, size); + EXPECT_EQ((size_t)(128 * 1024), size); EXPECT_NO_THROW(ram.get(0)); EXPECT_NO_THROW(ram.get(size-1)); EXPECT_ANY_THROW(ram.get(size)); } +TEST_F(RleTest, multiLoadRom) { + rle::RLEInterface rle; + rle.loadROM(romPath, corePath); + rle.setInt("random_seed", 4); + EXPECT_EQ(4, rle.getInt("random_seed")); + rle.loadROM(romPath, corePath); + EXPECT_EQ(4, rle.getInt("random_seed")); +// for(int i=0; i<0; i++){ +// rle.loadROM(romPath, corePath); +// EXPECT_EQ(4, rle.getInt("random_seed")); +// } +} + } // namespace diff --git a/test/SettingsTest.cpp b/test/SettingsTest.cpp new file mode 100644 index 0000000..3659798 --- /dev/null +++ b/test/SettingsTest.cpp @@ -0,0 +1,40 @@ +/* + * RleTest.cpp + * + * Created on: Jul 22, 2016 + * Author: nadav + */ + +#include +#include +#include "rle_interface.hpp" +#include "gtest/gtest.h" +#include "common/RleException.h" +#include "gtest_arguments.h" +#include "../src/environment/Settings.hxx" + +namespace { + +using namespace rle; +using std::string; +// The fixture for testing class Foo. +class SettingsTest : public ::testing::Test { + protected: + + // Objects declared here can be used by all tests in the test case for Foo. + std::string corePath = gtest_arguments::coreName; + std::string romPath = gtest_arguments::romName; +}; + +TEST_F(SettingsTest, simpleCtor) { + rle::Settings settings; +} + +TEST_F(SettingsTest, getSet) { + rle::Settings settings; + EXPECT_EQ(0, settings.getInt("random_seed")); + EXPECT_EQ(0, settings.getBool("two_players")); +} + + +} // namespace diff --git a/test/python_interface_test.py b/test/python_interface_test.py index 8ef5111..fe5d524 100644 --- a/test/python_interface_test.py +++ b/test/python_interface_test.py @@ -1,19 +1,14 @@ import unittest import os - -from pexpect.screen import screen - from rle_python_interface import RLEInterface import numpy as np -import matplotlib.pyplot as plt class RleTest(unittest.TestCase): def setUp(self): cwd = os.getcwd() - # coreName = os.path.join(cwd, '..', 'snes9x2010', 'snes9x2010_libretro.so') core = 'snes' - romName = os.path.join(cwd, '..','..','Atari', 'roms', 'mortal_kombat.sfc') + romName = os.path.join(cwd, 'roms', 'classic_kong.smc') self.rle = RLEInterface() self.rle.loadROM(romName, core) diff --git a/test/rleCInterfaceTest.cpp b/test/rleCInterfaceTest.cpp index cbbaaaa..12ab5ce 100644 --- a/test/rleCInterfaceTest.cpp +++ b/test/rleCInterfaceTest.cpp @@ -66,12 +66,19 @@ TEST_F(RleCInterfaceTest, testRam) { EXPECT_ANY_THROW(getRAMSize(rle)); loadAndPlay(rle); size_t ramSize = getRAMSize(rle); - EXPECT_EQ(128 * 1024, ramSize); + EXPECT_EQ(size_t(128 * 1024), ramSize); unsigned char * ram = (unsigned char *)malloc(sizeof(unsigned char *)*ramSize); getRAM(rle, ram); EXPECT_NO_THROW(ram[0]); EXPECT_NO_THROW(ram[ramSize-1]); } +TEST_F(RleCInterfaceTest, testMultipleLoadRom) { + RLEInterface *rle = RLE_new(); + for(int i=0; i<2; i++){ + loadROM(rle, gtest_arguments::romName.c_str(), gtest_arguments::coreName.c_str()); + } + RLE_del(rle); +} } // namespace