mirror of https://github.com/stella-emu/stella.git
588 lines
16 KiB
C++
588 lines
16 KiB
C++
//============================================================================
|
|
//
|
|
// 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-2018 by Bradford W. Mott, Stephen Anthony
|
|
// and the Stella Team
|
|
//
|
|
// See the file "License.txt" for information on usage and redistribution of
|
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
|
//============================================================================
|
|
|
|
#ifndef OSYSTEM_HXX
|
|
#define OSYSTEM_HXX
|
|
|
|
#ifdef CHEATCODE_SUPPORT
|
|
class CheatManager;
|
|
#endif
|
|
class CommandMenu;
|
|
class Console;
|
|
class Debugger;
|
|
class Launcher;
|
|
class Menu;
|
|
class TimeMachine;
|
|
class FrameBuffer;
|
|
class EventHandler;
|
|
class PNGLibrary;
|
|
class Properties;
|
|
class PropertiesSet;
|
|
class Random;
|
|
class SerialPort;
|
|
class Settings;
|
|
class Sound;
|
|
class StateManager;
|
|
class TimerManager;
|
|
class VideoDialog;
|
|
class EmulationWorker;
|
|
class AudioSettings;
|
|
|
|
#include <chrono>
|
|
|
|
#include "FSNode.hxx"
|
|
#include "FrameBufferConstants.hxx"
|
|
#include "EventHandlerConstants.hxx"
|
|
#include "FpsMeter.hxx"
|
|
#include "bspf.hxx"
|
|
|
|
/**
|
|
This class provides an interface for accessing operating system specific
|
|
functions. It also comprises an overall parent object, to which all the
|
|
other objects belong.
|
|
|
|
@author Stephen Anthony
|
|
*/
|
|
class OSystem
|
|
{
|
|
friend class EventHandler;
|
|
friend class VideoDialog;
|
|
friend class DeveloperDialog;
|
|
|
|
public:
|
|
OSystem();
|
|
virtual ~OSystem();
|
|
|
|
/**
|
|
Create all child objects which belong to this OSystem
|
|
*/
|
|
virtual bool create();
|
|
|
|
public:
|
|
/**
|
|
Get the event handler of the system.
|
|
|
|
@return The event handler
|
|
*/
|
|
EventHandler& eventHandler() const { return *myEventHandler; }
|
|
|
|
/**
|
|
Get the frame buffer of the system.
|
|
|
|
@return The frame buffer
|
|
*/
|
|
FrameBuffer& frameBuffer() const { return *myFrameBuffer; }
|
|
|
|
/**
|
|
Get the sound object of the system.
|
|
|
|
@return The sound object
|
|
*/
|
|
Sound& sound() const { return *mySound; }
|
|
|
|
/**
|
|
Get the settings object of the system.
|
|
|
|
@return The settings object
|
|
*/
|
|
Settings& settings() const { return *mySettings; }
|
|
|
|
/**
|
|
Get the random object of the system.
|
|
|
|
@return The random object
|
|
*/
|
|
Random& random() const { return *myRandom; }
|
|
|
|
/**
|
|
Get the set of game properties for the system.
|
|
|
|
@return The properties set object
|
|
*/
|
|
PropertiesSet& propSet() const { return *myPropSet; }
|
|
|
|
/**
|
|
Get the console of the system. The console won't always exist,
|
|
so we should test if it's available.
|
|
|
|
@return The console object
|
|
*/
|
|
Console& console() const { return *myConsole; }
|
|
bool hasConsole() const;
|
|
|
|
/**
|
|
Get the audio settings object of the system.
|
|
|
|
@return The audio settings object
|
|
*/
|
|
AudioSettings& audioSettings() { return *myAudioSettings; }
|
|
|
|
/**
|
|
Get the serial port of the system.
|
|
|
|
@return The serial port object
|
|
*/
|
|
SerialPort& serialPort() const { return *mySerialPort; }
|
|
|
|
/**
|
|
Get the settings menu of the system.
|
|
|
|
@return The settings menu object
|
|
*/
|
|
Menu& menu() const { return *myMenu; }
|
|
|
|
/**
|
|
Get the command menu of the system.
|
|
|
|
@return The command menu object
|
|
*/
|
|
CommandMenu& commandMenu() const { return *myCommandMenu; }
|
|
|
|
/**
|
|
Get the ROM launcher of the system.
|
|
|
|
@return The launcher object
|
|
*/
|
|
Launcher& launcher() const { return *myLauncher; }
|
|
|
|
/**
|
|
Get the time machine of the system (manages state files).
|
|
|
|
@return The time machine object
|
|
*/
|
|
TimeMachine& timeMachine() const { return *myTimeMachine; }
|
|
|
|
/**
|
|
Get the state manager of the system.
|
|
|
|
@return The statemanager object
|
|
*/
|
|
StateManager& state() const { return *myStateManager; }
|
|
|
|
/**
|
|
Get the timer/callback manager of the system.
|
|
|
|
@return The timermanager object
|
|
*/
|
|
TimerManager& timer() const { return *myTimerManager; }
|
|
|
|
/**
|
|
Get the PNG handler of the system.
|
|
|
|
@return The PNGlib object
|
|
*/
|
|
PNGLibrary& png() const { return *myPNGLib; }
|
|
|
|
/**
|
|
This method should be called to load the current settings from an rc file.
|
|
It first loads the settings from the config file, then informs subsystems
|
|
about the new settings.
|
|
*/
|
|
void loadConfig();
|
|
|
|
/**
|
|
This method should be called to save the current settings to an rc file.
|
|
It first asks each subsystem to update its settings, then it saves all
|
|
settings to the config file.
|
|
*/
|
|
void saveConfig();
|
|
|
|
#ifdef DEBUGGER_SUPPORT
|
|
/**
|
|
Get the ROM debugger of the system.
|
|
|
|
@return The debugger object
|
|
*/
|
|
Debugger& debugger() const { return *myDebugger; }
|
|
#endif
|
|
|
|
#ifdef CHEATCODE_SUPPORT
|
|
/**
|
|
Get the cheat manager of the system.
|
|
|
|
@return The cheatmanager object
|
|
*/
|
|
CheatManager& cheat() const { return *myCheatManager; }
|
|
#endif
|
|
|
|
/**
|
|
Set all config file paths for the OSystem.
|
|
*/
|
|
void setConfigPaths();
|
|
|
|
/**
|
|
Return the default full/complete directory name for storing data.
|
|
*/
|
|
const string& baseDir() const { return myBaseDir; }
|
|
|
|
/**
|
|
Return the full/complete directory name for storing state files.
|
|
*/
|
|
const string& stateDir() const { return myStateDir; }
|
|
|
|
/**
|
|
Return the full/complete directory name for saving and loading
|
|
PNG snapshots.
|
|
*/
|
|
const string& snapshotSaveDir() const { return mySnapshotSaveDir; }
|
|
const string& snapshotLoadDir() const { return mySnapshotLoadDir; }
|
|
|
|
/**
|
|
Return the full/complete directory name for storing nvram
|
|
(flash/EEPROM) files.
|
|
*/
|
|
const string& nvramDir() const { return myNVRamDir; }
|
|
|
|
/**
|
|
Return the full/complete directory name for storing Distella cfg files.
|
|
*/
|
|
const string& cfgDir() const { return myCfgDir; }
|
|
|
|
/**
|
|
This method should be called to get the full path of the cheat file.
|
|
|
|
@return String representing the full path of the cheat filename.
|
|
*/
|
|
const string& cheatFile() const { return myCheatFile; }
|
|
|
|
/**
|
|
This method should be called to get the full path of the config file.
|
|
|
|
@return String representing the full path of the config filename.
|
|
*/
|
|
const string& configFile() const { return myConfigFile; }
|
|
|
|
/**
|
|
This method should be called to get the full path of the
|
|
(optional) palette file.
|
|
|
|
@return String representing the full path of the properties filename.
|
|
*/
|
|
const string& paletteFile() const { return myPaletteFile; }
|
|
|
|
/**
|
|
This method should be called to get the full path of the currently
|
|
loaded ROM.
|
|
|
|
@return FSNode object representing the ROM file.
|
|
*/
|
|
const FilesystemNode& romFile() const { return myRomFile; }
|
|
|
|
/**
|
|
Creates a new game console from the specified romfile, and correctly
|
|
initializes the system state to start emulation of the Console.
|
|
|
|
@param rom The FSNode of the ROM to use (contains path, etc)
|
|
@param md5 The MD5sum of the ROM
|
|
@param newrom Whether this is a new ROM, or a reload of current one
|
|
|
|
@return String indicating any error message (EmptyString for no errors)
|
|
*/
|
|
string createConsole(const FilesystemNode& rom, const string& md5 = "",
|
|
bool newrom = true);
|
|
|
|
/**
|
|
Reloads the current console (essentially deletes and re-creates it).
|
|
This can be thought of as a real console off/on toggle.
|
|
|
|
@return True on successful creation, otherwise false
|
|
*/
|
|
bool reloadConsole();
|
|
|
|
/**
|
|
Creates a new ROM launcher, to select a new ROM to emulate.
|
|
|
|
@param startdir The directory to use when opening the launcher;
|
|
if blank, use 'romdir' setting.
|
|
|
|
@return True on successful creation, otherwise false
|
|
*/
|
|
bool createLauncher(const string& startdir = "");
|
|
|
|
/**
|
|
Answers whether the ROM launcher was actually successfully used
|
|
at some point since the app started.
|
|
|
|
@return True if launcher was ever used, otherwise false
|
|
*/
|
|
bool launcherUsed() const { return myLauncherUsed; }
|
|
|
|
/**
|
|
Gets all possible info about the ROM by creating a temporary
|
|
Console object and querying it.
|
|
|
|
@param romfile The file node of the ROM to use
|
|
@return Some information about this ROM
|
|
*/
|
|
string getROMInfo(const FilesystemNode& romfile);
|
|
|
|
/**
|
|
The features which are conditionally compiled into Stella.
|
|
|
|
@return The supported features
|
|
*/
|
|
const string& features() const { return myFeatures; }
|
|
|
|
/**
|
|
The build information for Stella (toolkit version, architecture, etc).
|
|
|
|
@return The build info
|
|
*/
|
|
const string& buildInfo() const { return myBuildInfo; }
|
|
|
|
/**
|
|
Issue a quit event to the OSystem.
|
|
*/
|
|
void quit() { myQuitLoop = true; }
|
|
|
|
/**
|
|
Append a message to the internal log
|
|
(a newline is automatically added).
|
|
|
|
@param message The message to be appended
|
|
@param level If 0, always output the message, only append when
|
|
level is less than or equal to that in 'loglevel'
|
|
*/
|
|
void logMessage(const string& message, uInt8 level);
|
|
|
|
/**
|
|
Get the system messages logged up to this point.
|
|
|
|
@return The list of log messages
|
|
*/
|
|
const string& logMessages() const { return myLogMessages; }
|
|
|
|
/**
|
|
Reset FPS measurement.
|
|
*/
|
|
void resetFps();
|
|
|
|
public:
|
|
//////////////////////////////////////////////////////////////////////
|
|
// The following methods are system-specific and can be overrided in
|
|
// derived classes. Otherwise, the base methods will be used.
|
|
//////////////////////////////////////////////////////////////////////
|
|
/**
|
|
This method returns number of ticks in microseconds since some
|
|
pre-defined time in the past. *NOTE*: it is necessary that this
|
|
pre-defined time exists between runs of the application, and must
|
|
be (relatively) unique. For example, the time since the system
|
|
started running is not a good choice, since it can be duplicated.
|
|
The current implementation uses time since the UNIX epoch.
|
|
|
|
@return Current time in microseconds.
|
|
*/
|
|
virtual uInt64 getTicks() const;
|
|
|
|
float frameRate() const;
|
|
|
|
/**
|
|
This method runs the main loop. Since different platforms
|
|
may use different timing methods and/or algorithms, this method can
|
|
be overrided. However, the port then takes all responsibility for
|
|
running the emulation and taking care of timing.
|
|
*/
|
|
virtual void mainLoop();
|
|
|
|
/**
|
|
Informs the OSystem of a change in EventHandler state.
|
|
*/
|
|
virtual void stateChanged(EventHandlerState state) { }
|
|
|
|
/**
|
|
Returns the default save and load paths for various files
|
|
(snapshots, disassembly, roms, etc). Since this varies greatly
|
|
among different systems and is the one directory that most end-users
|
|
care about (vs. config file stuff that usually isn't user-modifiable),
|
|
we create a special method for it.
|
|
*/
|
|
virtual string defaultSaveDir() const { return string("~") + BSPF::PATH_SEPARATOR; }
|
|
virtual string defaultLoadDir() const { return string("~") + BSPF::PATH_SEPARATOR; }
|
|
|
|
protected:
|
|
/**
|
|
Set the base directory for all Stella files (these files may be
|
|
located in other places through settings).
|
|
*/
|
|
void setBaseDir(const string& basedir);
|
|
|
|
/**
|
|
Set the locations of config file
|
|
*/
|
|
void setConfigFile(const string& file);
|
|
|
|
protected:
|
|
// Pointer to the EventHandler object
|
|
unique_ptr<EventHandler> myEventHandler;
|
|
|
|
// Pointer to the FrameBuffer object
|
|
unique_ptr<FrameBuffer> myFrameBuffer;
|
|
|
|
// Pointer to the Sound object
|
|
unique_ptr<Sound> mySound;
|
|
|
|
// Pointer to the Settings object
|
|
unique_ptr<Settings> mySettings;
|
|
|
|
// Pointer to the Random object
|
|
unique_ptr<Random> myRandom;
|
|
|
|
// Pointer to the PropertiesSet object
|
|
unique_ptr<PropertiesSet> myPropSet;
|
|
|
|
// Pointer to the (currently defined) Console object
|
|
unique_ptr<Console> myConsole;
|
|
|
|
// Pointer to audio settings object
|
|
unique_ptr<AudioSettings> myAudioSettings;
|
|
|
|
// Pointer to the serial port object
|
|
unique_ptr<SerialPort> mySerialPort;
|
|
|
|
// Pointer to the Menu object
|
|
unique_ptr<Menu> myMenu;
|
|
|
|
// Pointer to the CommandMenu object
|
|
unique_ptr<CommandMenu> myCommandMenu;
|
|
|
|
// Pointer to the Launcher object
|
|
unique_ptr<Launcher> myLauncher;
|
|
bool myLauncherUsed;
|
|
|
|
// Pointer to the TimeMachine object
|
|
unique_ptr<TimeMachine> myTimeMachine;
|
|
|
|
#ifdef DEBUGGER_SUPPORT
|
|
// Pointer to the Debugger object
|
|
unique_ptr<Debugger> myDebugger;
|
|
#endif
|
|
|
|
#ifdef CHEATCODE_SUPPORT
|
|
// Pointer to the CheatManager object
|
|
unique_ptr<CheatManager> myCheatManager;
|
|
#endif
|
|
|
|
// Pointer to the StateManager object
|
|
unique_ptr<StateManager> myStateManager;
|
|
|
|
// Pointer to the TimerManager object
|
|
unique_ptr<TimerManager> myTimerManager;
|
|
|
|
// PNG object responsible for loading/saving PNG images
|
|
unique_ptr<PNGLibrary> myPNGLib;
|
|
|
|
// The list of log messages
|
|
string myLogMessages;
|
|
|
|
// Indicates whether to stop the main loop
|
|
bool myQuitLoop;
|
|
|
|
private:
|
|
string myBaseDir;
|
|
string myStateDir;
|
|
string mySnapshotSaveDir;
|
|
string mySnapshotLoadDir;
|
|
string myNVRamDir;
|
|
string myCfgDir;
|
|
|
|
string myCheatFile;
|
|
string myConfigFile;
|
|
string myPaletteFile;
|
|
string myPropertiesFile;
|
|
|
|
FilesystemNode myRomFile;
|
|
string myRomMD5;
|
|
|
|
string myFeatures;
|
|
string myBuildInfo;
|
|
|
|
FpsMeter myFpsMeter;
|
|
|
|
private:
|
|
/**
|
|
Creates the various framebuffers/renderers available in this system.
|
|
Note that it will only create one type per run of Stella.
|
|
|
|
@return Success or failure of the framebuffer creation
|
|
*/
|
|
FBInitStatus createFrameBuffer();
|
|
|
|
/**
|
|
Creates the various sound devices available in this system
|
|
*/
|
|
void createSound();
|
|
|
|
/**
|
|
Creates an actual Console object based on the given info.
|
|
|
|
@param romfile The file node of the ROM to use (contains path)
|
|
@param md5 The MD5sum of the ROM
|
|
|
|
@return The actual Console object, otherwise nullptr.
|
|
*/
|
|
unique_ptr<Console> openConsole(const FilesystemNode& romfile, string& md5);
|
|
|
|
/**
|
|
Close and finalize any currently open console.
|
|
*/
|
|
void closeConsole();
|
|
|
|
/**
|
|
Open the given ROM and return an array containing its contents.
|
|
Also, the properties database is updated with a valid ROM name
|
|
for this ROM (if necessary).
|
|
|
|
@param rom The file node of the ROM to open (contains path)
|
|
@param md5 The md5 calculated from the ROM file
|
|
(will be recalculated if necessary)
|
|
@param size The amount of data read into the image array
|
|
|
|
@return Unique pointer to the array
|
|
*/
|
|
BytePtr openROM(const FilesystemNode& rom, string& md5, uInt32& size);
|
|
|
|
/**
|
|
Gets all possible info about the given console.
|
|
|
|
@param console The console to use
|
|
@return Some information about this console
|
|
*/
|
|
string getROMInfo(const Console& console);
|
|
|
|
/**
|
|
Validate the directory name, and create it if necessary.
|
|
Also, update the settings with the new name. For now, validation
|
|
means that the path must always end with the appropriate separator.
|
|
|
|
@param path The actual path being accessed and created
|
|
@param setting The setting corresponding to the path being considered
|
|
@param defaultpath The default path to use if the settings don't exist
|
|
*/
|
|
void validatePath(string& path, const string& setting,
|
|
const string& defaultpath);
|
|
|
|
double dispatchEmulation(EmulationWorker& emulationWorker);
|
|
|
|
// Following constructors and assignment operators not supported
|
|
OSystem(const OSystem&) = delete;
|
|
OSystem(OSystem&&) = delete;
|
|
OSystem& operator=(const OSystem&) = delete;
|
|
OSystem& operator=(OSystem&&) = delete;
|
|
};
|
|
|
|
#endif
|