Some changes across the board. Lets see if I can remember them all:

Fixed annoying timing bug that's bothered me since the 2.0 release.
Exiting a ROM and starting another one was causing the new ROM to not
start playing sound from the beginning.  This was made worse by the new
display format auto-detection logic.  Basically, the main event loop
wasn't being reset from one ROM to another.

Moved OSystem::mainLoop() back into the actual OSystem class, and
removed it from the UNIX/OSX/Win32/GP2X ports.  It's still virtual,
though, just in case a port wants to handle all timing itself.

Started a massive purge of all enhanced XStart/YStart values from
the internal properties.  I'll also be removing the 'tiadefaults'
argument, and leaning towards a more authentic emulation look
and feel.

Second pass at image centering in the GP2X port.  Now we only
do vertical centering, and only on images that won't be scaled
in hardware.

Reworked creating a new Console.  It now takes in the properties and
Cartridge required for operation.

Re-added changeWidth() and changeHeight() console functionality, since
it's proved to be very beneficial.

Cleaned up getting info about a cartridge.  It was sort of hacky before.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1246 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2006-12-28 18:31:27 +00:00
parent 485f9200a4
commit 705c97fd4f
20 changed files with 2196 additions and 6455 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: SoundSDL.cxx,v 1.34 2006-12-26 22:57:31 azaballa Exp $
// $Id: SoundSDL.cxx,v 1.35 2006-12-28 18:31:22 stephena Exp $
//============================================================================
#ifdef SOUND_SUPPORT
@ -218,6 +218,7 @@ void SoundSDL::reset()
SDL_PauseAudio(1);
myIsMuted = false;
myLastRegisterSetCycle = 0;
myTIASound.reset();
myRegWriteQueue.clear();
SDL_PauseAudio(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: Cart.cxx,v 1.25 2006-12-26 17:06:00 stephena Exp $
// $Id: Cart.cxx,v 1.26 2006-12-28 18:31:22 stephena Exp $
//============================================================================
#include <cassert>
@ -48,7 +48,7 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cartridge* Cartridge::create(const uInt8* image, uInt32 size,
const Properties& properties, const Settings& settings, string& about)
const Properties& properties, const Settings& settings)
{
Cartridge* cartridge = 0;
@ -71,7 +71,7 @@ Cartridge* Cartridge::create(const uInt8* image, uInt32 size,
type = detected;
}
about = buf.str();
myAboutString = buf.str();
// We should know the cart's type by now so let's create it
if(type == "2K")
@ -398,3 +398,6 @@ Cartridge& Cartridge::operator = (const Cartridge&)
assert(false);
return *this;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string Cartridge::myAboutString;

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: Cart.hxx,v 1.13 2006-12-26 00:39:43 stephena Exp $
// $Id: Cart.hxx,v 1.14 2006-12-28 18:31:22 stephena Exp $
//============================================================================
#ifndef CARTRIDGE_HXX
@ -33,7 +33,7 @@ class Settings;
game and handles any bankswitching performed by the cartridge.
@author Bradford W. Mott
@version $Id: Cart.hxx,v 1.13 2006-12-26 00:39:43 stephena Exp $
@version $Id: Cart.hxx,v 1.14 2006-12-28 18:31:22 stephena Exp $
*/
class Cartridge : public Device
{
@ -46,11 +46,10 @@ class Cartridge : public Device
@param size The size of the ROM image
@param props The properties associated with the game
@param settings The settings associated with the system
@param about Some info about this Cartridge
@return Pointer to the new cartridge object allocated on the heap
*/
static Cartridge* create(const uInt8* image, uInt32 size,
const Properties& props, const Settings& settings, string& about);
const Properties& props, const Settings& settings);
public:
/**
@ -63,6 +62,11 @@ class Cartridge : public Device
*/
virtual ~Cartridge();
/**
Query some information about this cartridge.
*/
static const string& about() { return myAboutString; }
virtual void bank(uInt16 b); // set bank
virtual int bank(); // get current bank (-1 if no bankswitching supported)
virtual int bankCount(); // count # of banks
@ -78,7 +82,6 @@ class Cartridge : public Device
bool bankLocked;
private:
/**
Try to auto-detect the bankswitching type of the cartridge
@ -119,6 +122,9 @@ class Cartridge : public Device
static bool isProbablyE7(const uInt8* image, uInt32 size);
private:
// Contains info about this cartridge in string format
static string myAboutString;
// Copy constructor isn't supported by cartridges so make it private
Cartridge(const Cartridge&);

View File

@ -13,10 +13,10 @@
// 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.113 2006-12-26 17:06:01 stephena Exp $
// $Id: Console.cxx,v 1.114 2006-12-28 18:31:22 stephena Exp $
//============================================================================
#include <assert.h>
#include <cassert>
#include <iostream>
#include <sstream>
#include <fstream>
@ -58,14 +58,11 @@
#endif
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Console::Console(const uInt8* image, uInt32 size, const string& md5,
OSystem* osystem)
Console::Console(OSystem* osystem, Cartridge* cart, const Properties& props)
: myOSystem(osystem),
myIsValidFlag(false),
myProperties(props),
myUserPaletteDefined(false)
{
Cartridge* cartridge = (Cartridge*) NULL;
ostringstream buf;
myControllers[0] = 0;
myControllers[1] = 0;
myMediaSource = 0;
@ -76,9 +73,6 @@ Console::Console(const uInt8* image, uInt32 size, const string& md5,
// Attach the event subsystem to the current console
myEvent = myOSystem->eventHandler().event();
// Search for the properties based on MD5
myOSystem->propSet().getMD5(md5, myProperties);
// A developer can override properties from the commandline
setDeveloperProperties();
@ -87,10 +81,6 @@ Console::Console(const uInt8* image, uInt32 size, const string& md5,
loadUserPalette();
setColorLossPalette(myOSystem->settings().getBool("colorloss"));
// Query some info about this console
buf << " Cart Name: " << myProperties.get(Cartridge_Name) << endl
<< " Cart MD5: " << md5 << endl;
// Setup the controllers based on properties
string left = myProperties.get(Controller_Left);
string right = myProperties.get(Controller_Right);
@ -188,25 +178,21 @@ Console::Console(const uInt8* image, uInt32 size, const string& md5,
M6532* m6532 = new M6532(*this);
TIA *tia = new TIA(*this, myOSystem->settings());
tia->setSound(myOSystem->sound());
cartridge = Cartridge::create(image, size, myProperties,
myOSystem->settings(), myAboutString);
buf << myAboutString;
if(!cartridge)
return;
mySystem->attach(m6502);
mySystem->attach(m6532);
mySystem->attach(tia);
mySystem->attach(cartridge);
mySystem->attach(cart);
// Remember what my media source is
myMediaSource = tia;
myCart = cartridge;
myCart = cart;
myRiot = m6532;
// Reset, the system to its power-on state
mySystem->reset();
// Query some info about this console
ostringstream buf;
buf << " Cart Name: " << myProperties.get(Cartridge_Name) << endl
<< " Cart MD5: " << myProperties.get(Cartridge_MD5) << endl;
// Auto-detect NTSC/PAL mode if it's requested
myDisplayFormat = myProperties.get(Display_Format);
@ -219,6 +205,7 @@ Console::Console(const uInt8* image, uInt32 size, const string& md5,
// the second 30 (useful to get past SuperCharger BIOS)
// Unfortunately, this means we have to always enable 'fastscbios',
// since otherwise the BIOS loading will take over 250 frames!
mySystem->reset();
int palCount = 0;
for(int i = 0; i < 60; ++i)
{
@ -231,6 +218,7 @@ Console::Console(const uInt8* image, uInt32 size, const string& md5,
if(myProperties.get(Display_Format) == "AUTO-DETECT")
buf << " Auto-detected display format: " << myDisplayFormat << endl;
}
buf << cart->about();
// Make sure height is set properly for PAL ROM
if(myDisplayFormat.compare(0, 3, "PAL") == 0)
@ -249,10 +237,10 @@ Console::Console(const uInt8* image, uInt32 size, const string& md5,
return;
}
mySystem->reset(); // Restart ROM again
// Reset, the system to its power-on state
mySystem->reset();
myAboutString = buf.str();
myIsValidFlag = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -268,12 +256,6 @@ Console::~Console()
delete myControllers[1];
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const Properties& Console::properties() const
{
return myProperties;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::toggleFormat()
{
@ -481,12 +463,6 @@ void Console::initializeVideo()
setPalette(myOSystem->settings().getString("palette"));
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::initializeAudio()
{
myMediaSource->setSound(myOSystem->sound());
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::setChannels(int channels)
{
@ -517,7 +493,7 @@ void Console::setChannels(int channels)
Until someone comes up with a more accurate way to emulate frying, I'm
leaving this as Fred posted it. -- B.
*/
void Console::fry()
void Console::fry() const
{
for (int ZPmem=0; ZPmem<0x100; ZPmem += rand() % 4)
mySystem->poke(ZPmem, mySystem->peek(ZPmem) & (uInt8)rand() % 256);
@ -606,7 +582,89 @@ void Console::changeYStart(int direction)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::toggleTIABit(TIA::TIABit bit, const string& bitname, bool show)
void Console::changeWidth(int direction)
{
uInt32 xstart = atoi(myProperties.get(Display_XStart).c_str());
Int32 width = atoi(myProperties.get(Display_Width).c_str());
ostringstream strval;
string message;
if(direction == +1) // increase Width
{
width += 4;
if((width > 160) || ((width % 4) != 0))
{
myOSystem->frameBuffer().showMessage("Width at maximum");
return;
}
else if((width + xstart) > 160)
{
myOSystem->frameBuffer().showMessage("Width no effect");
return;
}
}
else if(direction == -1) // decrease Width
{
width -= 4;
if(width < 80)
{
myOSystem->frameBuffer().showMessage("Width at minimum");
return;
}
}
else
return;
strval << width;
myProperties.set(Display_Width, strval.str());
mySystem->reset();
initializeVideo();
message = "Width ";
message += strval.str();
myOSystem->frameBuffer().showMessage(message);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::changeHeight(int direction)
{
Int32 height = atoi(myProperties.get(Display_Height).c_str());
ostringstream strval;
string message;
if(direction == +1) // increase Height
{
height++;
if(height > 256)
{
myOSystem->frameBuffer().showMessage("Height at maximum");
return;
}
}
else if(direction == -1) // decrease Height
{
height--;
if(height < 100)
{
myOSystem->frameBuffer().showMessage("Height at minimum");
return;
}
}
else
return;
strval << height;
myProperties.set(Display_Height, strval.str());
mySystem->reset();
initializeVideo();
message = "Height ";
message += strval.str();
myOSystem->frameBuffer().showMessage(message);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::toggleTIABit(TIA::TIABit bit, const string& bitname, bool show) const
{
bool result = ((TIA*)myMediaSource)->toggleBit(bit);
string message = bitname + (result ? " enabled" : " disabled");
@ -614,7 +672,7 @@ void Console::toggleTIABit(TIA::TIABit bit, const string& bitname, bool show)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::enableBits(bool enable)
void Console::enableBits(bool enable) const
{
((TIA*)myMediaSource)->enableBits(enable);
string message = string("TIA bits") + (enable ? " enabled" : " disabled");

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.54 2006-12-26 17:06:01 stephena Exp $
// $Id: Console.hxx,v 1.55 2006-12-28 18:31:22 stephena Exp $
//============================================================================
#ifndef CONSOLE_HXX
@ -38,7 +38,7 @@ class System;
This class represents the entire game console.
@author Bradford W. Mott
@version $Id: Console.hxx,v 1.54 2006-12-26 17:06:01 stephena Exp $
@version $Id: Console.hxx,v 1.55 2006-12-28 18:31:22 stephena Exp $
*/
class Console
{
@ -47,13 +47,11 @@ class Console
Create a new console for emulating the specified game using the
given game image and operating system.
@param image The ROM image of the game to emulate
@param size The size of the ROM image
@param md5 The md5 of the ROM image
@param osystem The OSystem object to use
@param cart The cartridge to use with this console
@param props The properties for the cartridge
*/
Console(const uInt8* image, uInt32 size, const string& md5,
OSystem* osystem);
Console(OSystem* osystem, Cartridge* cart, const Properties& props);
/**
Create a new console object by copying another one
@ -90,7 +88,7 @@ class Console
@return The properties being used by the game
*/
const Properties& properties() const;
const Properties& properties() const { return myProperties; }
/**
Get the console switches
@ -130,7 +128,7 @@ class Console
/**
Query some information about this console.
*/
string about() { return myAboutString; }
const string& about() const { return myAboutString; }
public:
/**
@ -182,22 +180,12 @@ class Console
*/
void initialize();
/**
Determine whether the console object is valid (no errors occurred
when it was created)
*/
bool isValid() const { return myIsValidFlag; }
/**
Initialize the video subsystem wrt this class.
This is required for changing window size, title, etc.
*/
void initializeVideo();
/**
Initialize the audio subsystem wrt this class.
*/
void initializeAudio();
/**
Sets the number of sound channels
@ -208,11 +196,11 @@ class Console
/**
"Fry" the Atari (mangle memory/TIA contents)
*/
void fry();
void fry() const;
/**
Change the "Display.XStart" variable. Currently, a system reset is issued
after the change. GUI's may need to resize their viewports.
after the change.
@param direction +1 indicates increase, -1 indicates decrease.
*/
@ -220,29 +208,45 @@ class Console
/**
Change the "Display.XStart" variable. Currently, a system reset is issued
after the change. GUI's may need to resize their viewports.
after the change.
@param direction +1 indicates increase, -1 indicates decrease.
*/
void changeYStart(int direction);
/**
Change the "Display.XStart" variable. Currently, a system reset is issued
after the change.
@param direction +1 indicates increase, -1 indicates decrease.
*/
void changeWidth(int direction);
/**
Change the "Display.XStart" variable. Currently, a system reset is issued
after the change.
@param direction +1 indicates increase, -1 indicates decrease.
*/
void changeHeight(int direction);
/**
Toggles the TIA bit specified in the method name.
*/
void toggleP0Bit() { toggleTIABit(TIA::P0, "P0"); }
void toggleP1Bit() { toggleTIABit(TIA::P1, "P1"); }
void toggleM0Bit() { toggleTIABit(TIA::M0, "M0"); }
void toggleM1Bit() { toggleTIABit(TIA::M1, "M1"); }
void toggleBLBit() { toggleTIABit(TIA::BL, "BL"); }
void togglePFBit() { toggleTIABit(TIA::PF, "PF"); }
void enableBits(bool enable);
void toggleP0Bit() const { toggleTIABit(TIA::P0, "P0"); }
void toggleP1Bit() const { toggleTIABit(TIA::P1, "P1"); }
void toggleM0Bit() const { toggleTIABit(TIA::M0, "M0"); }
void toggleM1Bit() const { toggleTIABit(TIA::M1, "M1"); }
void toggleBLBit() const { toggleTIABit(TIA::BL, "BL"); }
void togglePFBit() const { toggleTIABit(TIA::PF, "PF"); }
void enableBits(bool enable) const;
#ifdef ATARIVOX_SUPPORT
AtariVox *atariVox() { return vox; }
#endif
private:
void toggleTIABit(TIA::TIABit bit, const string& bitname, bool show = true);
void toggleTIABit(TIA::TIABit bit, const string& bitname, bool show = true) const;
void setDeveloperProperties();
/**
@ -296,8 +300,8 @@ class Console
AtariVox *vox;
#endif
// Indicates whether the console was successfully created
bool myIsValidFlag;
// The currently defined display format (NTSC/PAL/PAL60)
string myDisplayFormat;
// Indicates whether an external palette was found and
// successfully loaded
@ -306,9 +310,6 @@ class Console
// Contains info about this console in string format
string myAboutString;
// The currently defined display format (NTSC/PAL/PAL60)
string myDisplayFormat;
// Table of RGB values for NTSC and PAL
static uInt32 ourNTSCPalette[256];
static uInt32 ourPALPalette[256];

File diff suppressed because it is too large Load Diff

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.190 2006-12-26 17:06:01 stephena Exp $
// $Id: EventHandler.cxx,v 1.191 2006-12-28 18:31:26 stephena Exp $
//============================================================================
#include <sstream>
@ -63,7 +63,6 @@ EventHandler::EventHandler(OSystem* osystem)
myState(S_NONE),
myLSState(0),
myPauseFlag(false),
myQuitFlag(false),
myGrabMouseFlag(false),
myUseLauncherFlag(false),
myFryingFlag(false),
@ -163,7 +162,6 @@ void EventHandler::reset(State state)
myLSState = 0;
myPauseFlag = false;
myQuitFlag = false;
pause(false);
myEvent->clear();
@ -583,9 +581,26 @@ void EventHandler::poll(uInt32 time)
break;
case SDLK_r: // Ctrl-r reloads the currently loaded ROM
myOSystem->deleteConsole();
myOSystem->createConsole();
break;
case SDLK_END: // Ctrl-End increases Width
myOSystem->console().changeWidth(+1);
break;
case SDLK_HOME: // Ctrl-Home decreases Width
myOSystem->console().changeWidth(-1);
break;
case SDLK_PAGEUP: // Ctrl-PageUp increases Height
myOSystem->console().changeHeight(+1);
break;
case SDLK_PAGEDOWN: // Ctrl-PageDown decreases Height
myOSystem->console().changeHeight(-1);
break;
case SDLK_s: // Ctrl-s saves properties to a file
{
string filename = myOSystem->baseDir() + BSPF_PATH_SEPARATOR +
@ -1190,13 +1205,17 @@ void EventHandler::handleEvent(Event::Type event, int state)
if(myState == S_EMULATE && myUseLauncherFlag && state)
{
myOSystem->settings().saveConfig();
myOSystem->deleteConsole();
myOSystem->createLauncher();
}
return;
case Event::Quit:
if(state) myQuitFlag = true;
if(state)
{
myOSystem->settings().saveConfig();
myOSystem->quit();
}
return;
}

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.95 2006-12-12 01:02:12 stephena Exp $
// $Id: EventHandler.hxx,v 1.96 2006-12-28 18:31:26 stephena Exp $
//============================================================================
#ifndef EVENTHANDLER_HXX
@ -62,7 +62,7 @@ enum EventMode {
mapping can take place.
@author Stephen Anthony
@version $Id: EventHandler.hxx,v 1.95 2006-12-12 01:02:12 stephena Exp $
@version $Id: EventHandler.hxx,v 1.96 2006-12-28 18:31:26 stephena Exp $
*/
class EventHandler
{
@ -193,11 +193,6 @@ class EventHandler
*/
void quit() { handleEvent(Event::Quit, 1); }
/**
This method indicates whether a quit event has been received.
*/
inline bool doQuit() { return myQuitFlag; }
/**
Save state to explicit state number (debugger uses this)
*/
@ -555,9 +550,6 @@ class EventHandler
// Indicates the current pause status
bool myPauseFlag;
// Indicates whether to quit the emulator
bool myQuitFlag;
// Indicates whether the mouse cursor is grabbed
bool myGrabMouseFlag;

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.84 2006-12-26 00:39:44 stephena Exp $
// $Id: OSystem.cxx,v 1.85 2006-12-28 18:31:26 stephena Exp $
//============================================================================
#include <cassert>
@ -59,6 +59,7 @@ OSystem::OSystem()
myLauncher(NULL),
myDebugger(NULL),
myCheatManager(NULL),
myQuitLoop(false),
myRomFile(""),
myFeatures(""),
myFont(NULL),
@ -106,7 +107,7 @@ OSystem::~OSystem()
delete myConsoleFont;
// Remove any game console that is currently attached
delete myConsole;
deleteConsole();
// OSystem takes responsibility for framebuffer and sound,
// since it created them
@ -317,36 +318,16 @@ void OSystem::toggleFrameBuffer()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void OSystem::createSound()
{
// Delete the old sound device
delete mySound; mySound = NULL;
// And recreate a new sound device
mySound = MediaFactory::createAudio(this);
#ifndef SOUND_SUPPORT
mySettings->setBool("sound", false);
#endif
// Re-initialize the sound object to current settings
switch(myEventHandler->state())
{
case EventHandler::S_EMULATE:
case EventHandler::S_MENU:
case EventHandler::S_CMDMENU:
case EventHandler::S_DEBUGGER:
myConsole->initializeAudio();
break; // S_EMULATE, S_MENU, S_DEBUGGER
default:
break;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool OSystem::createConsole(const string& romfile)
{
// Delete any lingering console object
delete myConsole; myConsole = NULL;
bool retval = false, showmessage = false;
// If a blank ROM has been given, we reload the current one (assuming one exists)
@ -368,11 +349,13 @@ bool OSystem::createConsole(const string& romfile)
string md5;
if(openROM(myRomFile, md5, &image, &size))
{
// Create an instance of the 2600 game console
// The Console c'tor takes care of updating the eventhandler state
myConsole = new Console(image, size, md5, this);
if(myConsole && myConsole->isValid())
// Get all required info for creating a valid console
Cartridge* cart = (Cartridge*) NULL;
Properties props;
if(queryConsoleInfo(image, size, md5, &cart, props))
{
// Create an instance of the 2600 game console
myConsole = new Console(this, cart, props);
#ifdef CHEATCODE_SUPPORT
myCheatManager->loadCheats(md5);
#endif
@ -389,6 +372,9 @@ bool OSystem::createConsole(const string& romfile)
<< " ROM file: " << myRomFile << endl
<< myConsole->about() << endl;
// Update the timing info for a new console run
resetLoopTiming();
retval = true;
}
else
@ -411,9 +397,30 @@ bool OSystem::createConsole(const string& romfile)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void OSystem::createLauncher()
void OSystem::deleteConsole()
{
mySound->close();
if(myConsole)
{
if(mySettings->getBool("showinfo"))
{
double executionTime = (double) myTimingInfo.totalTime / 1000000.0;
double framesPerSecond = (double) myTimingInfo.totalFrames / executionTime;
cout << "Game console stats:" << endl
<< " Total frames drawn: " << myTimingInfo.totalFrames << endl
<< " Total time (sec): " << executionTime << endl
<< " Frames per second: " << framesPerSecond << endl
<< endl;
}
delete myConsole; myConsole = NULL;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void OSystem::createLauncher()
{
resetLoopTiming();
setFramerate(60);
myEventHandler->reset(EventHandler::S_LAUNCHER);
createFrameBuffer(false);
@ -423,7 +430,6 @@ void OSystem::createLauncher()
myLauncher->reStack();
myEventHandler->refreshDisplay();
myFrameBuffer->setCursorState();
}
@ -528,7 +534,6 @@ bool OSystem::openROM(const string& rom, string& md5, uInt8** image, int* size)
string OSystem::getROMInfo(const string& romfile)
{
ostringstream buf;
Console* console = (Console*) NULL;
// Open the cartridge image and read it in
uInt8* image;
@ -536,24 +541,50 @@ string OSystem::getROMInfo(const string& romfile)
string md5;
if(openROM(romfile, md5, &image, &size))
{
// Create a temporary instance of the 2600 game console
console = new Console(image, size, md5, this);
if(console && console->isValid())
// Get all required info for creating a temporary console
Cartridge* cart = (Cartridge*) NULL;
Properties props;
if(queryConsoleInfo(image, size, md5, &cart, props))
{
Console* console = new Console(this, cart, props);
if(console)
buf << console->about();
else
buf << "ERROR: Couldn't get ROM info for " << romfile << " ..." << endl;
delete console;
}
else
buf << "ERROR: Couldn't open " << romfile << " ..." << endl;
}
// Free the image and console since we don't need it any longer
delete console;
if(size != -1)
delete[] image;
return buf.str();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool OSystem::queryConsoleInfo(const uInt8* image, uInt32 size,
const string& md5,
Cartridge** cart, Properties& props)
{
myPropSet->getMD5(md5, props);
*cart = Cartridge::create(image, size, props, *mySettings);
if(!*cart)
return false;
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void OSystem::resetLoopTiming()
{
memset(&myTimingInfo, 0, sizeof(TimingInfo));
myTimingInfo.start = getTicks();
myTimingInfo.virt = getTicks();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void OSystem::setDefaultJoymap()
{
@ -621,6 +652,27 @@ void OSystem::pauseChanged(bool status)
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void OSystem::mainLoop()
{
for(;;)
{
myTimingInfo.start = getTicks();
myEventHandler->poll(myTimingInfo.start);
if(myQuitLoop) break; // Exit if the user wants to quit
myFrameBuffer->update();
myTimingInfo.current = getTicks();
myTimingInfo.virt += myTimePerFrame;
if(myTimingInfo.current < myTimingInfo.virt)
SDL_Delay((myTimingInfo.virt - myTimingInfo.current) / 1000);
myTimingInfo.totalTime += (getTicks() - myTimingInfo.start);
myTimingInfo.totalFrames++;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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.48 2006-12-26 00:39:44 stephena Exp $
// $Id: OSystem.hxx,v 1.49 2006-12-28 18:31:26 stephena Exp $
//============================================================================
#ifndef OSYSTEM_HXX
@ -45,7 +45,7 @@ class VideoDialog;
other objects belong.
@author Stephen Anthony
@version $Id: OSystem.hxx,v 1.48 2006-12-26 00:39:44 stephena Exp $
@version $Id: OSystem.hxx,v 1.49 2006-12-28 18:31:26 stephena Exp $
*/
class OSystem
{
@ -247,6 +247,12 @@ class OSystem
*/
bool createConsole(const string& romfile = "");
/**
Deletes the currently defined console, if it exists.
Also prints some statistics (fps, total frames, etc).
*/
void deleteConsole();
/**
Creates a new ROM launcher, to select a new ROM to emulate.
*/
@ -280,18 +286,16 @@ class OSystem
*/
bool openROM(const string& rom, string& md5, uInt8** image, int* size);
/**
Issue a quit event to the OSystem.
*/
void quit() { myQuitLoop = true; }
public:
//////////////////////////////////////////////////////////////////////
// The following methods are system-specific and must be implemented
// in derived classes.
//////////////////////////////////////////////////////////////////////
/**
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 mainLoop() = 0;
/**
This method returns number of ticks in microseconds.
@ -308,6 +312,14 @@ class OSystem
// The following methods are system-specific and can be overrided in
// derived classes. Otherwise, the base methods will be used.
//////////////////////////////////////////////////////////////////////
/**
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();
/**
This method determines the default mapping of joystick buttons to
Stella events for a specific system/platform.
@ -414,6 +426,9 @@ class OSystem
// Time per frame for a video update, based on the current framerate
uInt32 myTimePerFrame;
// Indicates whether to stop the main loop
bool myQuitLoop;
private:
string myBaseDir;
string myStateDir;
@ -435,6 +450,16 @@ class OSystem
// The font object to use for the console/debugger
GUI::Font* myConsoleFont;
// Indicates whether the main processing loop should proceed
struct TimingInfo {
uInt32 start;
uInt32 current;
uInt32 virt;
uInt32 totalTime;
uInt32 totalFrames;
};
TimingInfo myTimingInfo;
private:
/**
Creates the various framebuffers/renderers available in this system
@ -450,6 +475,20 @@ class OSystem
*/
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 string& md5,
Cartridge** cart, Properties& props);
/**
Initializes the timing so that the mainloop is reset to its
initial values.
*/
void resetLoopTiming();
// Copy constructor isn't supported by this class so make it private
OSystem(const OSystem&);

File diff suppressed because it is too large Load Diff

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: FrameBufferGP2X.cxx,v 1.14 2006-12-26 23:53:27 stephena Exp $
// $Id: FrameBufferGP2X.cxx,v 1.15 2006-12-28 18:31:26 stephena Exp $
//============================================================================
#include <SDL.h>
@ -77,23 +77,14 @@ bool FrameBufferGP2X::createScreen()
SDL_UpdateRect(myScreen, 0, 0, 0, 0);
}
// Determine the best screenmode to use; we only use 320x240 or 400x300
if(myBaseDim.w <= 320 && myBaseDim.h <= 240)
{
myScreenDim.w = 320;
myScreenDim.h = 240;
}
else
{
myScreenDim.w = 400;
myScreenDim.h = 300;
}
myScreenDim.x = myScreenDim.y = 0;
// If we got a screenmode that won't be scaled, center it vertically
// Otherwise, SDL hardware scaling kicks in, and we won't mess with it
myBaseDim.x = myBaseDim.y = 0;
if(myBaseDim.h <= 240)
myBaseDim.y = (240 - myBaseDim.h) / 2;
// In software mode, the image and base dimensions are always the same
myImageDim = myBaseDim;
myImageDim.x = (myScreenDim.w - myImageDim.w) / 2;
myImageDim.y = (myScreenDim.h - myImageDim.h) / 2;
// The GP2X always uses a 16-bit hardware buffer
myScreen = SDL_SetVideoMode(myScreenDim.w, myScreenDim.h, 16, mySDLFlags);
@ -102,8 +93,7 @@ bool FrameBufferGP2X::createScreen()
cerr << "ERROR: Unable to open SDL window: " << SDL_GetError() << endl;
return false;
}
myBasePtr = (uInt16*) myScreen->pixels +
myImageDim.y * myScreen->pitch + myImageDim.x;
myBasePtr = (uInt16*) myScreen->pixels + myImageDim.y * myScreen->pitch;
myPitch = myScreen->pitch/2;
myDirtyFlag = true;
@ -230,7 +220,7 @@ void FrameBufferGP2X::hLine(uInt32 x, uInt32 y, uInt32 x2, int color)
// Horizontal line
tmp.x = x;
tmp.y = y;
tmp.y = y + myImageDim.y;
tmp.w = (x2 - x + 1);
tmp.h = 1;
SDL_FillRect(myScreen, &tmp, myDefPalette[color]);
@ -242,7 +232,7 @@ void FrameBufferGP2X::vLine(uInt32 x, uInt32 y, uInt32 y2, int color)
SDL_Rect tmp;
// Vertical line
tmp.x = x + myImageDim.x;
tmp.x = x;
tmp.y = y + myImageDim.y;
tmp.w = 1;
tmp.h = (y2 - y + 1);
@ -256,7 +246,7 @@ void FrameBufferGP2X::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
SDL_Rect tmp;
// Fill the rectangle
tmp.x = x + myImageDim.x;
tmp.x = x;
tmp.y = y + myImageDim.y;
tmp.w = w;
tmp.h = h;
@ -282,7 +272,7 @@ void FrameBufferGP2X::drawChar(const GUI::Font* font, uInt8 chr,
chr -= desc.firstchar;
const uInt16* tmp = desc.bits + (desc.offset ? desc.offset[chr] : (chr * h));
uInt16* buffer = (uInt16*) myBasePtr + yorig * myScreen->w + xorig;
uInt16* buffer = (uInt16*) myBasePtr + yorig * myPitch + xorig;
for(int y = 0; y < h; ++y)
{
const uInt16 ptr = *tmp++;
@ -291,7 +281,7 @@ void FrameBufferGP2X::drawChar(const GUI::Font* font, uInt8 chr,
if(ptr & mask)
buffer[x] = (uInt16) myDefPalette[color];
buffer += myScreen->w;
buffer += myPitch;
}
}
@ -299,7 +289,7 @@ void FrameBufferGP2X::drawChar(const GUI::Font* font, uInt8 chr,
void FrameBufferGP2X::drawBitmap(uInt32* bitmap, Int32 xorig, Int32 yorig,
int color, Int32 h)
{
uInt16* buffer = (uInt16*) myBasePtr + yorig * myScreen->w + xorig;
uInt16* buffer = (uInt16*) myBasePtr + yorig * myPitch + xorig;
for(int y = 0; y < h; ++y)
{
uInt32 mask = 0xF0000000;
@ -307,7 +297,7 @@ void FrameBufferGP2X::drawBitmap(uInt32* bitmap, Int32 xorig, Int32 yorig,
if(bitmap[y] & mask)
buffer[x] = (uInt16) myDefPalette[color];
buffer += myScreen->w;
buffer += myPitch;
}
}

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: OSystemGP2X.cxx,v 1.22 2006-12-26 04:35:36 azaballa Exp $
// $Id: OSystemGP2X.cxx,v 1.23 2006-12-28 18:31:26 stephena Exp $
// Modified on 2006/01/06 by Alex Zaballa for use on GP2X
//============================================================================
@ -76,42 +76,6 @@ OSystemGP2X::~OSystemGP2X()
delete[] myCurrentEvents;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void OSystemGP2X::mainLoop()
{
// These variables are common to both timing options
// and are needed to calculate the overall frames per second.
uInt32 frameTime = 0, numberOfFrames = 0;
// Set up less accurate timing stuff
uInt32 startTime, virtualTime, currentTime;
// Set the base for the timers
virtualTime = getTicks();
frameTime = 0;
// Main game loop
for(;;)
{
// Exit if the user wants to quit
if(myEventHandler->doQuit())
break;
startTime = getTicks();
myEventHandler->poll(startTime);
myFrameBuffer->update();
currentTime = getTicks();
virtualTime += myTimePerFrame;
if(currentTime < virtualTime)
SDL_Delay((virtualTime - currentTime)/1000);
currentTime = getTicks() - startTime;
frameTime += currentTime;
++numberOfFrames;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 OSystemGP2X::getTicks()
{

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: OSystemGP2X.hxx,v 1.8 2006-12-08 16:49:31 stephena Exp $
// $Id: OSystemGP2X.hxx,v 1.9 2006-12-28 18:31:26 stephena Exp $
// Modified by Alex Zaballa on 2006/01/04 for use on GP2X
//============================================================================
@ -40,13 +40,6 @@ class OSystemGP2X : public OSystem
virtual ~OSystemGP2X();
public:
/**
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.
*/
void mainLoop();
/**
This method returns number of ticks in microseconds.

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: OSystemMACOSX.cxx,v 1.13 2006-12-08 16:49:37 stephena Exp $
// $Id: OSystemMACOSX.cxx,v 1.14 2006-12-28 18:31:26 stephena Exp $
//============================================================================
#include <cstdlib>
@ -112,77 +112,6 @@ OSystemMACOSX::~OSystemMACOSX()
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void OSystemMACOSX::mainLoop()
{
#if 0
double lasttime = Atari_time();
double lastcurtime = 0;
double curtime, delaytime;
double timePerFrame = 1.0 / 60.0;
// Main game loop
for(;;)
{
// Exit if the user wants to quit
if(myEventHandler->doQuit())
break;
myEventHandler->poll();
myFrameBuffer->update();
if (timePerFrame > 0.0)
{
curtime = Atari_time();
delaytime = lasttime + timePerFrame - curtime;
if (delaytime > 0)
usleep((int) (delaytime * 1e6));
curtime = Atari_time();
lastcurtime = curtime;
lasttime += timePerFrame;
if ((lasttime + timePerFrame) < curtime)
lasttime = curtime;
}
}
#else
// These variables are common to both timing options
// and are needed to calculate the overall frames per second.
uInt32 frameTime = 0, numberOfFrames = 0;
// Set up less accurate timing stuff
uInt32 startTime, virtualTime, currentTime;
// Set the base for the timers
virtualTime = getTicks();
frameTime = 0;
// Main game loop
for(;;)
{
// Exit if the user wants to quit
if(myEventHandler->doQuit())
break;
startTime = getTicks();
myEventHandler->poll(startTime);
myFrameBuffer->update();
currentTime = getTicks();
virtualTime = startTime + myTimePerFrame;
if(currentTime < virtualTime)
{
SDL_Delay((virtualTime - currentTime)/1000);
}
currentTime = getTicks() - startTime;
frameTime += currentTime;
++numberOfFrames;
}
#endif
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 OSystemMACOSX::getTicks()
{

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: OSystemMACOSX.hxx,v 1.6 2006-12-08 16:49:37 stephena Exp $
// $Id: OSystemMACOSX.hxx,v 1.7 2006-12-28 18:31:26 stephena Exp $
//============================================================================
#ifndef OSYSTEM_MACOSX_HXX
@ -26,7 +26,7 @@
This class defines UNIX-like OS's (Linux) system specific settings.
@author Mark Grebe
@version $Id: OSystemMACOSX.hxx,v 1.6 2006-12-08 16:49:37 stephena Exp $
@version $Id: OSystemMACOSX.hxx,v 1.7 2006-12-28 18:31:26 stephena Exp $
*/
class OSystemMACOSX : public OSystem
{
@ -42,13 +42,6 @@ class OSystemMACOSX : public OSystem
virtual ~OSystemMACOSX();
public:
/**
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 mainLoop();
/**
This method returns number of ticks in microseconds.

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.23 2006-12-26 00:39:44 stephena Exp $
// $Id: OSystemUNIX.cxx,v 1.24 2006-12-28 18:31:26 stephena Exp $
//============================================================================
#include <SDL.h>
@ -69,90 +69,6 @@ OSystemUNIX::~OSystemUNIX()
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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;
if(mySettings->getBool("accurate")) // normal, CPU-intensive timing
{
// Set up accurate timing stuff
uInt32 startTime, delta;
// Set the base for the timers
frameTime = 0;
// Main game loop
for(;;)
{
// Exit if the user wants to quit
if(myEventHandler->doQuit())
break;
startTime = getTicks();
myEventHandler->poll(startTime);
myFrameBuffer->update();
// Now, waste time if we need to so that we are at the desired frame rate
for(;;)
{
delta = getTicks() - startTime;
if(delta >= myTimePerFrame)
break;
}
frameTime += getTicks() - startTime;
++numberOfFrames;
}
}
else // less accurate, less CPU-intensive timing
{
// Set up less accurate timing stuff
uInt32 startTime, virtualTime, currentTime;
// Set the base for the timers
virtualTime = getTicks();
frameTime = 0;
// Main game loop
for(;;)
{
// Exit if the user wants to quit
if(myEventHandler->doQuit())
break;
startTime = getTicks();
myEventHandler->poll(startTime);
myFrameBuffer->update();
currentTime = getTicks();
virtualTime += myTimePerFrame;
if(currentTime < virtualTime)
{
SDL_Delay((virtualTime - currentTime)/1000);
}
currentTime = getTicks() - startTime;
frameTime += currentTime;
++numberOfFrames;
}
}
// Only print console information if a console was actually created
if(mySettings->getBool("showinfo"))
{
double executionTime = (double) frameTime / 1000000.0;
double framesPerSecond = (double) numberOfFrames / executionTime;
cout << endl;
cout << numberOfFrames << " total frames drawn\n";
cout << framesPerSecond << " frames/second\n";
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 OSystemUNIX::getTicks()
{

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.12 2006-12-08 16:49:41 stephena Exp $
// $Id: OSystemUNIX.hxx,v 1.13 2006-12-28 18:31:26 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.12 2006-12-08 16:49:41 stephena Exp $
@version $Id: OSystemUNIX.hxx,v 1.13 2006-12-28 18:31:26 stephena Exp $
*/
class OSystemUNIX : public OSystem
{
@ -42,13 +42,6 @@ class OSystemUNIX : public OSystem
virtual ~OSystemUNIX();
public:
/**
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.
*/
void mainLoop();
/**
This method returns number of ticks in microseconds.

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: OSystemWin32.cxx,v 1.15 2006-12-26 00:39:44 stephena Exp $
// $Id: OSystemWin32.cxx,v 1.16 2006-12-28 18:31:27 stephena Exp $
//============================================================================
#include <sstream>
@ -62,54 +62,6 @@ OSystemWin32::~OSystemWin32()
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void OSystemWin32::mainLoop()
{
// These variables are common to both timing options
// and are needed to calculate the overall frames per second.
uInt32 frameTime = 0, numberOfFrames = 0;
// Set up less accurate timing stuff
uInt32 startTime, virtualTime, currentTime;
// Set the base for the timers
virtualTime = getTicks();
frameTime = 0;
// Main game loop
for(;;)
{
// Exit if the user wants to quit
if(myEventHandler->doQuit())
break;
startTime = getTicks();
myEventHandler->poll(startTime);
myFrameBuffer->update();
currentTime = getTicks();
virtualTime += myTimePerFrame;
if(currentTime < virtualTime)
{
SDL_Delay((virtualTime - currentTime)/1000);
}
currentTime = getTicks() - startTime;
frameTime += currentTime;
++numberOfFrames;
}
if(mySettings->getBool("showinfo"))
{
double executionTime = (double) frameTime / 1000000.0;
double framesPerSecond = (double) numberOfFrames / executionTime;
cout << endl;
cout << numberOfFrames << " total frames drawn\n";
cout << framesPerSecond << " frames/second\n";
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 OSystemWin32::getTicks()
{

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: OSystemWin32.hxx,v 1.7 2006-12-08 16:49:41 stephena Exp $
// $Id: OSystemWin32.hxx,v 1.8 2006-12-28 18:31:27 stephena Exp $
//============================================================================
#ifndef OSYSTEM_WIN32_HXX
@ -25,7 +25,7 @@
This class defines Windows system specific settings.
@author Stephen Anthony
@version $Id: OSystemWin32.hxx,v 1.7 2006-12-08 16:49:41 stephena Exp $
@version $Id: OSystemWin32.hxx,v 1.8 2006-12-28 18:31:27 stephena Exp $
*/
class OSystemWin32 : public OSystem
{
@ -41,13 +41,6 @@ class OSystemWin32 : public OSystem
virtual ~OSystemWin32();
public:
/**
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 mainLoop();
/**
This method returns number of ticks in microseconds.