Moved the main processing loop out of mainSDL and into OSystem::mainLoop().

Also, moved creation of new console into OSystem::createConsole.

Added hooks for browser mode (coming soon).

Added Ctrl-r to reload the currently loaded ROM.  It has the nice side
effect of testing whether another ROM can be reloaded while the emulation
is running.  Since this was successful, adding the ROM browser mode will
be very easy.

Added ability to actually change the framerate from the VideoDialog.

Reworked FrameBuffer::setPalette to be called only when a new console
is created (and we know that MediaSource::palette() is defined).

When toggling between NTSC/PAL mode, the video framerate is now toggled
between 50 and 60 (still TODO is change the audio framerate).


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@410 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2005-05-05 00:10:49 +00:00
parent 79f738b93e
commit e5df395075
15 changed files with 158 additions and 146 deletions

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FrameBufferGL.cxx,v 1.20 2005-04-29 19:05:04 stephena Exp $
// $Id: FrameBufferGL.cxx,v 1.21 2005-05-05 00:10:43 stephena Exp $
//============================================================================
#include <SDL.h>
@ -127,9 +127,6 @@ bool FrameBufferGL::initSubsystem()
createTextures();
#endif
// Set up the palette *after* we know the color components and the textures
setupPalette();
// Show some OpenGL info
if(myOSystem->settings().getBool("showinfo"))
{

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FrameBufferSoft.cxx,v 1.19 2005-04-29 19:05:04 stephena Exp $
// $Id: FrameBufferSoft.cxx,v 1.20 2005-05-05 00:10:43 stephena Exp $
//============================================================================
#include <SDL.h>
@ -58,7 +58,6 @@ bool FrameBufferSoft::initSubsystem()
// Create the screen
if(!createScreen())
return false;
setupPalette();
// Show some info
if(myOSystem->settings().getBool("showinfo"))

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: mainSDL.cxx,v 1.34 2005-05-02 19:35:57 stephena Exp $
// $Id: mainSDL.cxx,v 1.35 2005-05-05 00:10:43 stephena Exp $
//============================================================================
#include <fstream>
@ -45,7 +45,6 @@
#error Unsupported platform!
#endif
static Console* CreateConsole(const string& romfile);
static void SetupProperties(PropertiesSet& set);
static void Cleanup();
@ -59,15 +58,18 @@ static OSystem* theOSystem = (OSystem*) NULL;
*/
void SetupProperties(PropertiesSet& set)
{
bool useMemList = false;
bool useMemList = true; // It seems we always need the list in memory
string theAltPropertiesFile = theOSystem->settings().getString("altpro");
string thePropertiesFile = theOSystem->propertiesInputFilename();
/*
// When 'listrominfo' or 'mergeprops' is specified, we need to have the
// full list in memory
// FIXME - we need the whole list in memory
// if(theSettings->getBool("listrominfo") || theSettings->getBool("mergeprops"))
if(theOSystem->settings().getBool("listrominfo") ||
theOSystem->settings().getBool("mergeprops") ||
theOSystem->settings().getBool("browser"))
useMemList = true;
*/
stringstream buf;
if(theAltPropertiesFile != "")
@ -88,39 +90,6 @@ void SetupProperties(PropertiesSet& set)
}
/**
Creates a new game console for the specified game.
*/
Console* CreateConsole(const string& romfile)
{
Console* console = (Console*) NULL;
// Open the cartridge image and read it in
ifstream in(romfile.c_str(), ios_base::binary);
if(!in)
cerr << "ERROR: Couldn't open " << romfile << "..." << endl;
else
{
uInt8* image = new uInt8[512 * 1024];
in.read((char*)image, 512 * 1024);
uInt32 size = in.gcount();
in.close();
// Remove old console from the OSystem
theOSystem->detachConsole();
// Create an instance of the 2600 game console
console = new Console(image, size, theOSystem);
// Free the image since we don't need it any longer
delete[] image;
}
return console;
}
/**
Does general Cleanup in case any operation failed (or at end of program).
*/
@ -172,12 +141,13 @@ int main(int argc, char* argv[])
// We do it once here, so the rest of the program can assume valid settings
theOSystem->settings().validate();
// Make sure the OSystem has a valid framerate set, since it's used for
// more then just emulation mode
theOSystem->setFramerate(theOSystem->settings().getInt("framerate"));
// Create the event handler for the system
EventHandler handler(theOSystem);
// Cache some settings so they don't have to be repeatedly searched for
bool theRomLauncherFlag = false;//true;//FIXMEtheSettings->getBool("romlauncher");
// Create a properties set for us to use and set it up
PropertiesSet propertiesSet;
SetupProperties(propertiesSet);
@ -222,48 +192,23 @@ int main(int argc, char* argv[])
cout << framerate << endl;
//// Main loop ////
// Load a ROM and start the main game loop
// If the game is given from the commandline, exiting game means exit emulator
// If the game is loaded from the ROM launcher, exiting game means show launcher
string romfile = "";
Console* theConsole = (Console*) NULL;
////
ostringstream rom;
rom << argv[argc - 1];
romfile = rom.str();
////
if(theRomLauncherFlag)
// If the ROM browser is being used, we enter 'browser' mode and let the
// main event loop take care of opening a new console/ROM.
// Otherwise, we use the ROM specified on the commandline.
if(theOSystem->settings().getBool("browser"))
{
for(;;)
{
// theOSystem->gui().showRomLauncher();
if(theOSystem->eventHandler().doQuit())
break;
else // FIXME - add code here to delay a little
{
cerr << "GUI not yet written, run game again (y or n): ";
char runagain;
cin >> runagain;
if(runagain == 'n')
break;
else
{
if((theConsole = CreateConsole(romfile)) != NULL)
theOSystem->mainGameLoop();
else
break;
}
}
}
theOSystem->eventHandler().reset(EventHandler::S_BROWSER);
}
else
{
ostringstream romfile;
romfile << argv[argc - 1];
theConsole = CreateConsole(romfile.str());
theOSystem->mainGameLoop();
string romfile = argv[argc - 1];
theOSystem->setRom(romfile);
theOSystem->createConsole();
}
// Start the main loop, and don't exit until the user issues a QUIT command
theOSystem->mainLoop();
// Cleanup time ...
Cleanup();
return 0;

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: Console.cxx,v 1.49 2005-05-04 00:43:22 stephena Exp $
// $Id: Console.cxx,v 1.50 2005-05-05 00:10:46 stephena Exp $
//============================================================================
#include <assert.h>
@ -62,9 +62,6 @@ Console::Console(const uInt8* image, uInt32 size, OSystem* osystem)
mySystem = 0;
myEvent = 0;
// Add the current console to the system
myOSystem->attach(this);
// Indicate that emulation should start now
myOSystem->eventHandler().reset(EventHandler::S_EMULATE);
@ -223,19 +220,25 @@ Console& Console::operator = (const Console&)
void Console::toggleFormat()
{
string format = myProperties.get("Display.Format");
uInt32 framerate = 60;
if(format == "NTSC")
{
myProperties.set("Display.Format", "PAL");
mySystem->reset();
myOSystem->frameBuffer().showMessage("PAL Mode");
framerate = 50;
}
else if(format == "PAL")
{
myProperties.set("Display.Format", "NTSC");
mySystem->reset();
myOSystem->frameBuffer().showMessage("NTSC Mode");
framerate = 60;
}
setPalette();
myOSystem->setFramerate(framerate);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -282,8 +285,9 @@ void Console::togglePalette(const string& palette)
}
myOSystem->settings().setString("palette", type);
myOSystem->frameBuffer().setupPalette();
myOSystem->frameBuffer().showMessage(message);
setPalette();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -321,6 +325,7 @@ void Console::initializeVideo()
myOSystem->frameBuffer().initialize(title,
myMediaSource->width() << 1,
myMediaSource->height());
setPalette();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -329,6 +334,12 @@ void Console::initializeAudio()
myMediaSource->setSound(myOSystem->sound());
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::setPalette()
{
myOSystem->frameBuffer().setPalette(myMediaSource->palette());
}
#ifdef DEVELOPER_SUPPORT
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::changeXStart(const uInt32 direction)

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: Console.hxx,v 1.29 2005-05-04 00:43:22 stephena Exp $
// $Id: Console.hxx,v 1.30 2005-05-05 00:10:47 stephena Exp $
//============================================================================
#ifndef CONSOLE_HXX
@ -35,7 +35,7 @@ class System;
This class represents the entire game console.
@author Bradford W. Mott
@version $Id: Console.hxx,v 1.29 2005-05-04 00:43:22 stephena Exp $
@version $Id: Console.hxx,v 1.30 2005-05-05 00:10:47 stephena Exp $
*/
class Console
{
@ -151,6 +151,11 @@ class Console
*/
void initializeAudio();
/**
Sets the palette to that specified in the mediasource
*/
void setPalette();
#ifdef DEVELOPER_SUPPORT
public:
/**

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: Event.hxx,v 1.6 2005-02-25 02:29:38 stephena Exp $
// $Id: Event.hxx,v 1.7 2005-05-05 00:10:47 stephena Exp $
//============================================================================
#ifndef EVENT_HXX
@ -25,7 +25,7 @@ class Event;
/**
@author Bradford W. Mott
@version $Id: Event.hxx,v 1.6 2005-02-25 02:29:38 stephena Exp $
@version $Id: Event.hxx,v 1.7 2005-05-05 00:10:47 stephena Exp $
*/
class Event
{
@ -72,6 +72,7 @@ class Event
DrivingOneFire,
ChangeState, LoadState, SaveState, TakeSnapshot, Pause, Quit, ExitGame,
ReloadRom,
LastType
};

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: EventHandler.cxx,v 1.49 2005-05-04 19:04:45 stephena Exp $
// $Id: EventHandler.cxx,v 1.50 2005-05-05 00:10:47 stephena Exp $
//============================================================================
#include <algorithm>
@ -332,12 +332,14 @@ void EventHandler::handleKeyEvent(SDLKey key, SDLMod mod, uInt8 state)
case SDLK_f: // Ctrl-f toggles NTSC/PAL mode
myOSystem->console().toggleFormat();
myOSystem->frameBuffer().setupPalette();
break;
case SDLK_p: // Ctrl-p toggles different palettes
myOSystem->console().togglePalette();
myOSystem->frameBuffer().setupPalette();
break;
case SDLK_r: // Ctrl-r reloads the currently loaded ROM
myOSystem->createConsole(true);
break;
#ifdef DEVELOPER_SUPPORT

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: EventHandler.hxx,v 1.24 2005-05-01 18:57:20 stephena Exp $
// $Id: EventHandler.hxx,v 1.25 2005-05-05 00:10:48 stephena Exp $
//============================================================================
#ifndef EVENTHANDLER_HXX
@ -57,7 +57,7 @@ struct ActionList {
mapping can take place.
@author Stephen Anthony
@version $Id: EventHandler.hxx,v 1.24 2005-05-01 18:57:20 stephena Exp $
@version $Id: EventHandler.hxx,v 1.25 2005-05-05 00:10:48 stephena Exp $
*/
class EventHandler
{
@ -137,6 +137,11 @@ class EventHandler
*/
inline bool doQuit() { return myQuitFlag; }
/**
This method indicates that the system should terminate.
*/
inline void quit() { handleEvent(Event::Quit, 1); }
// Holds static strings for the remap menu
static ActionList ourActionList[58];

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FrameBuffer.cxx,v 1.30 2005-05-01 20:11:07 stephena Exp $
// $Id: FrameBuffer.cxx,v 1.31 2005-05-05 00:10:48 stephena Exp $
//============================================================================
#include <sstream>
@ -241,28 +241,18 @@ void FrameBuffer::showMessage(const string& message)
void FrameBuffer::pause(bool status)
{
myPauseStatus = status;
// Now notify the child object, in case it wants to do something
// special when pause is received
//FIXME pauseEvent(myPauseStatus);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::setupPalette()
void FrameBuffer::setPalette(const uInt32* palette)
{
// Shade the palette to 75% normal value in pause mode
float shade = 1.0;
if(myPauseStatus)
shade = 0.75;
const uInt32* gamePalette = myOSystem->console().mediaSource().palette();
for(uInt32 i = 0; i < 256; ++i)
{
Uint8 r, g, b;
r = (Uint8) (((gamePalette[i] & 0x00ff0000) >> 16) * shade);
g = (Uint8) (((gamePalette[i] & 0x0000ff00) >> 8) * shade);
b = (Uint8) ((gamePalette[i] & 0x000000ff) * shade);
r = (Uint8) ((palette[i] & 0x00ff0000) >> 16);
g = (Uint8) ((palette[i] & 0x0000ff00) >> 8);
b = (Uint8) (palette[i] & 0x000000ff);
myPalette[i] = mapRGB(r, g, b);
}

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FrameBuffer.hxx,v 1.27 2005-05-01 20:11:07 stephena Exp $
// $Id: FrameBuffer.hxx,v 1.28 2005-05-05 00:10:48 stephena Exp $
//============================================================================
#ifndef FRAMEBUFFER_HXX
@ -41,7 +41,7 @@ class OSystem;
All GUI elements (ala ScummVM) are drawn here as well.
@author Stephen Anthony
@version $Id: FrameBuffer.hxx,v 1.27 2005-05-01 20:11:07 stephena Exp $
@version $Id: FrameBuffer.hxx,v 1.28 2005-05-05 00:10:48 stephena Exp $
*/
class FrameBuffer
{
@ -208,8 +208,10 @@ class FrameBuffer
/**
Set up the palette for a screen of any depth > 8.
@param palette The array of colors
*/
void setupPalette();
void setPalette(const uInt32* palette);
/**
This routine should be called to draw a rectangular box with sides

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: OSystem.cxx,v 1.8 2005-05-01 18:57:20 stephena Exp $
// $Id: OSystem.cxx,v 1.9 2005-05-05 00:10:49 stephena Exp $
//============================================================================
#include <cassert>
@ -48,8 +48,9 @@ OSystem::OSystem()
mySettings(NULL),
myPropSet(NULL),
myConsole(NULL),
myMenu(NULL)
// myBrowser(NULL)
myMenu(NULL),
// myBrowser(NULL),
myRomFile("")
{
// Create gui-related classes
myMenu = new Menu(this);
@ -63,7 +64,7 @@ OSystem::~OSystem()
// delete myBrowser;
// Remove any game console that is currently attached
detachConsole();
delete myConsole;
// OSystem takes responsibility for framebuffer and sound,
// since it created them
@ -221,6 +222,45 @@ void OSystem::createSound()
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void OSystem::createConsole(bool showmessage)
{
if(myRomFile == "")
{
cerr << "ERROR: Rom file not specified ..." << endl;
myEventHandler->quit();
return;
}
// Open the cartridge image and read it in
ifstream in(myRomFile.c_str(), ios_base::binary);
if(!in)
{
cerr << "ERROR: Couldn't open " << myRomFile << "..." << endl;
myEventHandler->quit();
return;
}
else
{
uInt8* image = new uInt8[512 * 1024];
in.read((char*)image, 512 * 1024);
uInt32 size = in.gcount();
in.close();
delete myConsole;
// Create an instance of the 2600 game console
// The Console c'tor takes care of updating the eventhandler state
myConsole = new Console(image, size, this);
// Free the image since we don't need it any longer
delete[] image;
if(showmessage)
myFrameBuffer->showMessage("New console created");
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OSystem::OSystem(const OSystem& osystem)
{

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: OSystem.hxx,v 1.8 2005-05-04 19:04:46 stephena Exp $
// $Id: OSystem.hxx,v 1.9 2005-05-05 00:10:49 stephena Exp $
//============================================================================
#ifndef OSYSTEM_HXX
@ -38,7 +38,7 @@ class Browser;
other objects belong.
@author Stephen Anthony
@version $Id: OSystem.hxx,v 1.8 2005-05-04 19:04:46 stephena Exp $
@version $Id: OSystem.hxx,v 1.9 2005-05-05 00:10:49 stephena Exp $
*/
class OSystem
{
@ -75,18 +75,6 @@ class OSystem
*/
void attach(PropertiesSet* propset) { myPropSet = propset; }
/**
Adds the specified console to the system.
@param console The console (game emulation object) to add
*/
void attach(Console* console) { myConsole = console; }
/**
Removes the currently attached console from the system.
*/
void detachConsole(void) { delete myConsole; myConsole = NULL; }
/**
Get the event handler of the system
@ -143,6 +131,20 @@ class OSystem
*/
Browser& browser(void) const { return *myBrowser; }
/**
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
*/
void setFramerate(uInt32 framerate)
{ myTimePerFrame = (uInt32)(1000000.0 / (double) framerate); }
/**
Set the ROM file (filename of current ROM to load)
*/
void setRom(const string& romfile) { myRomFile = romfile; }
/**
Set the base directory for all configuration files
*/
@ -224,17 +226,26 @@ class OSystem
*/
void createSound();
/**
Creates a new game console. It is assumed that setRom() has
been called before this method, to set actual ROM file name.
@param showmessage Whether to show an onscreen message that
the console has been (re)created
*/
void createConsole(bool showmessage = false);
public:
//////////////////////////////////////////////////////////////////////
// The following methods are system-specific and must be implemented
// in derived classes.
//////////////////////////////////////////////////////////////////////
/**
This method runs the main gaming loop. Since different platforms
This method runs the main loop. Since different platforms
may use different timing methods and/or algorithms, this method has
been abstracted to each platform.
*/
virtual void mainGameLoop() = 0;
virtual void mainLoop() = 0;
/**
This method returns number of ticks in microseconds.
@ -297,6 +308,9 @@ class OSystem
// Pointer to the Browser object
Browser* myBrowser;
// Time per frame for a video update, based on the current framerate
uInt32 myTimePerFrame;
private:
string myBaseDir;
string myStateDir;
@ -306,6 +320,8 @@ class OSystem
string myConfigInputFile;
string myConfigOutputFile;
string myRomFile;
private:
// Copy constructor isn't supported by this class so make it private
OSystem(const OSystem&);

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: VideoDialog.cxx,v 1.8 2005-05-01 20:11:07 stephena Exp $
// $Id: VideoDialog.cxx,v 1.9 2005-05-05 00:10:49 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -276,7 +276,7 @@ void VideoDialog::saveConfig()
// Framerate
i = myFrameRateSlider->getValue();
instance()->settings().setInt("framerate", i);
// FIXME - immediately change the framerate
instance()->setFramerate(i);
// Zoom
i = (myZoomSlider->getValue() / 10) + 1;

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: OSystemUNIX.cxx,v 1.4 2005-05-02 19:36:05 stephena Exp $
// $Id: OSystemUNIX.cxx,v 1.5 2005-05-05 00:10:49 stephena Exp $
//============================================================================
#include <cstdlib>
@ -44,12 +44,11 @@ OSystemUNIX::~OSystemUNIX()
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void OSystemUNIX::mainGameLoop()
void OSystemUNIX::mainLoop()
{
// These variables are common to both timing options
// and are needed to calculate the overall frames per second.
uInt32 frameTime = 0, numberOfFrames = 0;
uInt32 timePerFrame = (uInt32)(1000000.0 / (double) mySettings->getInt("framerate"));
if(mySettings->getBool("accurate")) // normal, CPU-intensive timing
{
@ -75,7 +74,7 @@ void OSystemUNIX::mainGameLoop()
{
delta = getTicks() - startTime;
if(delta >= timePerFrame)
if(delta >= myTimePerFrame)
break;
}
@ -104,7 +103,7 @@ void OSystemUNIX::mainGameLoop()
myFrameBuffer->update();
currentTime = getTicks();
virtualTime += timePerFrame;
virtualTime += myTimePerFrame;
if(currentTime < virtualTime)
{
SDL_Delay((virtualTime - currentTime)/1000);

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: OSystemUNIX.hxx,v 1.4 2005-05-02 19:36:05 stephena Exp $
// $Id: OSystemUNIX.hxx,v 1.5 2005-05-05 00:10:49 stephena Exp $
//============================================================================
#ifndef OSYSTEM_UNIX_HXX
@ -26,7 +26,7 @@
This class defines UNIX-like OS's (Linux) system specific settings.
@author Stephen Anthony
@version $Id: OSystemUNIX.hxx,v 1.4 2005-05-02 19:36:05 stephena Exp $
@version $Id: OSystemUNIX.hxx,v 1.5 2005-05-05 00:10:49 stephena Exp $
*/
class OSystemUNIX : public OSystem
{
@ -43,11 +43,11 @@ class OSystemUNIX : public OSystem
public:
/**
This method runs the main gaming loop. Since different platforms
This method runs the main loop. Since different platforms
may use different timing methods and/or algorithms, this method has
been abstracted to each platform.
*/
virtual void mainGameLoop();
virtual void mainLoop();
/**
This method returns number of ticks in microseconds.