Updated X11 and SDL versions to use the new Settings class. Currently

working on updating the DOS version.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@53 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2002-03-21 22:50:36 +00:00
parent fff4d40d77
commit 735a362381
2 changed files with 314 additions and 909 deletions

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: mainSDL.cxx,v 1.14 2002-03-20 00:03:24 stephena Exp $ // $Id: mainSDL.cxx,v 1.15 2002-03-21 22:50:36 stephena Exp $
//============================================================================ //============================================================================
#include <fstream> #include <fstream>
@ -36,6 +36,7 @@
#include "System.hxx" #include "System.hxx"
#include "SndUnix.hxx" #include "SndUnix.hxx"
#include "RectList.hxx" #include "RectList.hxx"
#include "Settings.hxx"
#ifdef HAVE_PNG #ifdef HAVE_PNG
#include "Snapshot.hxx" #include "Snapshot.hxx"
@ -49,38 +50,33 @@
#define SDL_DISABLE 0 #define SDL_DISABLE 0
#endif #endif
#define HAVE_GETTIMEOFDAY #define HAVE_GETTIMEOFDAY 1
SDL_Joystick* theLeftJoystick;
SDL_Joystick* theRightJoystick;
// function prototypes // function prototypes
bool setupDisplay(); static bool setupDisplay();
bool setupJoystick(); static bool setupJoystick();
bool createScreen(int width, int height); static bool createScreen(int width, int height);
void recalculate8BitPalette(); static void recalculate8BitPalette();
void setupPalette(); static void setupPalette();
void cleanup(); static void cleanup();
void updateDisplay(MediaSource& mediaSource); static void updateDisplay(MediaSource& mediaSource);
void handleEvents(); static void handleEvents();
void doQuit(); static void doQuit();
void resizeWindow(int mode); static void resizeWindow(int mode);
void centerWindow(); static void centerWindow();
void showCursor(bool show); static void showCursor(bool show);
void grabMouse(bool grab); static void grabMouse(bool grab);
void toggleFullscreen(); static void toggleFullscreen();
void takeSnapshot(); static void takeSnapshot();
void togglePause(); static void togglePause();
uInt32 maxWindowSizeForScreen(); static uInt32 maxWindowSizeForScreen();
uInt32 getTicks(); static uInt32 getTicks();
bool setupProperties(PropertiesSet& set); static bool setupProperties(PropertiesSet& set);
void handleCommandLineArguments(int ac, char* av[]); static void handleRCFile();
void handleRCFile(); static void usage();
void parseRCOptions(istream& in);
void usage();
// Globals for the SDL stuff // Globals for the SDL stuff
static SDL_Surface* screen; static SDL_Surface* screen;
@ -94,6 +90,8 @@ static bool x11Available = false;
static SDL_SysWMinfo info; static SDL_SysWMinfo info;
static int sdlflags; static int sdlflags;
static RectList* rectList; static RectList* rectList;
static SDL_Joystick* theLeftJoystick;
static SDL_Joystick* theRightJoystick;
#ifdef HAVE_PNG #ifdef HAVE_PNG
static Snapshot* snapshot; static Snapshot* snapshot;
@ -168,85 +166,30 @@ static Switches list[] = {
{ SDLK_F8, Event::ConsoleRightDifficultyB } { SDLK_F8, Event::ConsoleRightDifficultyB }
}; };
// Event objects to use
static Event theEvent;
static Event keyboardEvent; static Event keyboardEvent;
// Default window size of 0, meaning it must be set somewhere else
uInt32 theWindowSize = 0;
// Indicates the maximum window size for the current screen
uInt32 theMaxWindowSize;
// Indicates the width and height of the game display based on properties
uInt32 theHeight;
uInt32 theWidth;
// Pointer to the console object or the null pointer // Pointer to the console object or the null pointer
Console* theConsole; static Console* theConsole;
// Event object to use // Pointer to the settings object or the null pointer
Event theEvent; static Settings* settings;
// Indicates if the user wants to quit // Indicates if the user wants to quit
bool theQuitIndicator = false; static bool theQuitIndicator = false;
// Indicates if the emulator should be paused // Indicates if the emulator should be paused
bool thePauseIndicator = false; static bool thePauseIndicator = false;
// Indicates if the entire frame should be redrawn // Indicates if the entire frame should be redrawn
bool theRedrawEntireFrameFlag = true; static bool theRedrawEntireFrameIndicator = true;
// Indicates whether to use fullscreen
bool theUseFullScreenFlag = false;
// Indicates whether mouse can leave the game window
bool theGrabMouseFlag = false;
// Indicates whether to center the game window
bool theCenterWindowFlag = false;
// Indicates whether to show some game info on program exit
bool theShowInfoFlag = false;
// Indicates whether to show cursor in the game window
bool theHideCursorFlag = false;
// Indicates whether to allocate colors from a private color map
bool theUsePrivateColormapFlag = false;
// Indicates whether the game is currently in fullscreen // Indicates whether the game is currently in fullscreen
bool isFullscreen = false; static bool isFullscreen = false;
// Indicates whether the window is currently centered // Indicates whether the window is currently centered
bool isCentered = false; static bool isCentered = false;
// Indicates what the desired volume is
uInt32 theDesiredVolume = 75;
// Indicates what the desired frame rate is
uInt32 theDesiredFrameRate = 60;
// Indicate which paddle mode we're using:
// 0 - Mouse emulates paddle 0
// 1 - Mouse emulates paddle 1
// 2 - Mouse emulates paddle 2
// 3 - Mouse emulates paddle 3
// 4 - Use real Atari 2600 paddles
uInt32 thePaddleMode = 0;
// An alternate properties file to use
string theAlternateProFile = "";
#ifdef HAVE_PNG
// The path to save snapshot files
string theSnapShotDir = "";
// What the snapshot should be called (romname or md5sum)
string theSnapShotName = "";
// Indicates whether to generate multiple snapshots or keep
// overwriting the same file. Set to true by default.
bool theMultipleSnapShotFlag = true;
#endif
/** /**
@ -270,44 +213,44 @@ bool setupDisplay()
x11Available = true; x11Available = true;
sdlflags = SDL_HWSURFACE; sdlflags = SDL_HWSURFACE;
sdlflags |= theUseFullScreenFlag ? SDL_FULLSCREEN : 0; sdlflags |= settings->theUseFullScreenFlag ? SDL_FULLSCREEN : 0;
sdlflags |= theUsePrivateColormapFlag ? SDL_HWPALETTE : 0; sdlflags |= settings->theUsePrivateColormapFlag ? SDL_HWPALETTE : 0;
// Get the desired width and height of the display // Get the desired width and height of the display
theWidth = theConsole->mediaSource().width(); settings->theWidth = theConsole->mediaSource().width();
theHeight = theConsole->mediaSource().height(); settings->theHeight = theConsole->mediaSource().height();
// Get the maximum size of a window for THIS screen // Get the maximum size of a window for THIS screen
// Must be called after display and screen are known, as well as // Must be called after display and screen are known, as well as
// theWidth and theHeight // theWidth and theHeight
// Defaults to 3 on systems without X11, maximum of 4 on any system. // Defaults to 3 on systems without X11, maximum of 4 on any system.
theMaxWindowSize = maxWindowSizeForScreen(); settings->theMaxWindowSize = maxWindowSizeForScreen();
// If theWindowSize is not 0, then it must have been set on the commandline // If theWindowSize is not 0, then it must have been set on the commandline
// Now we check to see if it is within bounds // Now we check to see if it is within bounds
if(theWindowSize != 0) if(settings->theWindowSize != 0)
{ {
if(theWindowSize < 1) if(settings->theWindowSize < 1)
theWindowSize = 1; settings->theWindowSize = 1;
else if(theWindowSize > theMaxWindowSize) else if(settings->theWindowSize > settings->theMaxWindowSize)
theWindowSize = theMaxWindowSize; settings->theWindowSize = settings->theMaxWindowSize;
} }
else // theWindowSize hasn't been set so we do the default else // theWindowSize hasn't been set so we do the default
{ {
if(theMaxWindowSize < 2) if(settings->theMaxWindowSize < 2)
theWindowSize = 1; settings->theWindowSize = 1;
else else
theWindowSize = 2; settings->theWindowSize = 2;
} }
#ifdef HAVE_PNG #ifdef HAVE_PNG
// Take care of the snapshot stuff. // Take care of the snapshot stuff.
snapshot = new Snapshot(); snapshot = new Snapshot();
if(theSnapShotDir == "") if(settings->theSnapShotDir == "")
theSnapShotDir = getenv("HOME"); settings->theSnapShotDir = getenv("HOME");
if(theSnapShotName == "") if(settings->theSnapShotName == "")
theSnapShotName = "romname"; settings->theSnapShotName = "romname";
#endif #endif
// Set up the rectangle list to be used in updateDisplay // Set up the rectangle list to be used in updateDisplay
@ -325,8 +268,8 @@ bool setupDisplay()
SDL_WM_SetCaption(name, "stella"); SDL_WM_SetCaption(name, "stella");
// Figure out the desired size of the window // Figure out the desired size of the window
int width = theWidth * 2 * theWindowSize; int width = settings->theWidth * settings->theWindowSize * 2;
int height = theHeight * theWindowSize; int height = settings->theHeight * settings->theWindowSize;
// Create the screen // Create the screen
if(!createScreen(width, height)) if(!createScreen(width, height))
@ -334,7 +277,7 @@ bool setupDisplay()
setupPalette(); setupPalette();
// Make sure that theUseFullScreenFlag sets up fullscreen mode correctly // Make sure that theUseFullScreenFlag sets up fullscreen mode correctly
if(theUseFullScreenFlag) if(settings->theUseFullScreenFlag)
{ {
grabMouse(true); grabMouse(true);
showCursor(false); showCursor(false);
@ -343,14 +286,14 @@ bool setupDisplay()
else else
{ {
// Keep mouse in game window if grabmouse is selected // Keep mouse in game window if grabmouse is selected
grabMouse(theGrabMouseFlag); grabMouse(settings->theGrabMouseFlag);
// Show or hide the cursor depending on the 'hidecursor' argument // Show or hide the cursor depending on the 'hidecursor' argument
showCursor(!theHideCursorFlag); showCursor(!settings->theHideCursorFlag);
} }
// Center the window if centering is selected and not fullscreen // Center the window if centering is selected and not fullscreen
if(theCenterWindowFlag && !theUseFullScreenFlag) if(settings->theCenterWindowFlag && !settings->theUseFullScreenFlag)
centerWindow(); centerWindow();
return true; return true;
@ -507,32 +450,32 @@ void resizeWindow(int mode)
if(mode == 1) // increase size if(mode == 1) // increase size
{ {
if(theWindowSize == theMaxWindowSize) if(settings->theWindowSize == settings->theMaxWindowSize)
theWindowSize = 1; settings->theWindowSize = 1;
else else
theWindowSize++; settings->theWindowSize++;
} }
else // decrease size else // decrease size
{ {
if(theWindowSize == 1) if(settings->theWindowSize == 1)
theWindowSize = theMaxWindowSize; settings->theWindowSize = settings->theMaxWindowSize;
else else
theWindowSize--; settings->theWindowSize--;
} }
// Figure out the desired size of the window // Figure out the desired size of the window
int width = theWidth * 2 * theWindowSize; int width = settings->theWidth * settings->theWindowSize * 2;
int height = theHeight * theWindowSize; int height = settings->theHeight * settings->theWindowSize;
if(!createScreen(width, height)) if(!createScreen(width, height))
return; return;
theRedrawEntireFrameFlag = true; theRedrawEntireFrameIndicator = true;
// A resize may mean that the window is no longer centered // A resize may mean that the window is no longer centered
isCentered = false; isCentered = false;
if(theCenterWindowFlag) if(settings->theCenterWindowFlag)
centerWindow(); centerWindow();
} }
@ -575,8 +518,8 @@ void centerWindow()
*/ */
void toggleFullscreen() void toggleFullscreen()
{ {
int width = theWidth * 2 * theWindowSize; int width = settings->theWidth * settings->theWindowSize * 2;
int height = theHeight * theWindowSize; int height = settings->theHeight * settings->theWindowSize;
isFullscreen = !isFullscreen; isFullscreen = !isFullscreen;
if(isFullscreen) if(isFullscreen)
@ -594,14 +537,14 @@ void toggleFullscreen()
} }
else // now in windowed mode else // now in windowed mode
{ {
grabMouse(theGrabMouseFlag); grabMouse(settings->theGrabMouseFlag);
showCursor(!theHideCursorFlag); showCursor(!settings->theHideCursorFlag);
if(theCenterWindowFlag) if(settings->theCenterWindowFlag)
centerWindow(); centerWindow();
} }
theRedrawEntireFrameFlag = true; theRedrawEntireFrameIndicator = true;
} }
@ -654,7 +597,10 @@ void updateDisplay(MediaSource& mediaSource)
{ {
uInt8* currentFrame = mediaSource.currentFrameBuffer(); uInt8* currentFrame = mediaSource.currentFrameBuffer();
uInt8* previousFrame = mediaSource.previousFrameBuffer(); uInt8* previousFrame = mediaSource.previousFrameBuffer();
uInt16 screenMultiple = (uInt16)theWindowSize; uInt16 screenMultiple = (uInt16) settings->theWindowSize;
uInt32 width = settings->theWidth;
uInt32 height = settings->theHeight;
struct Rectangle struct Rectangle
{ {
@ -678,7 +624,7 @@ void updateDisplay(MediaSource& mediaSource)
// This update procedure requires theWidth to be a multiple of four. // This update procedure requires theWidth to be a multiple of four.
// This is validated when the properties are loaded. // This is validated when the properties are loaded.
for(uInt16 y = 0; y < theHeight; ++y) for(uInt16 y = 0; y < height; ++y)
{ {
// Indicates the number of current rectangles // Indicates the number of current rectangles
uInt16 currentCount = 0; uInt16 currentCount = 0;
@ -687,10 +633,10 @@ void updateDisplay(MediaSource& mediaSource)
uInt32* current = (uInt32*)(currentFrame); uInt32* current = (uInt32*)(currentFrame);
uInt32* previous = (uInt32*)(previousFrame); uInt32* previous = (uInt32*)(previousFrame);
for(uInt16 x = 0; x < theWidth; x += 4, ++current, ++previous) for(uInt16 x = 0; x < width; x += 4, ++current, ++previous)
{ {
// Has something changed in this set of four pixels? // Has something changed in this set of four pixels?
if((*current != *previous) || theRedrawEntireFrameFlag) if((*current != *previous) || theRedrawEntireFrameIndicator)
{ {
uInt8* c = (uInt8*)current; uInt8* c = (uInt8*)current;
uInt8* p = (uInt8*)previous; uInt8* p = (uInt8*)previous;
@ -699,7 +645,7 @@ void updateDisplay(MediaSource& mediaSource)
for(uInt16 i = 0; i < 4; ++i, ++c, ++p) for(uInt16 i = 0; i < 4; ++i, ++c, ++p)
{ {
// See if this pixel has changed // See if this pixel has changed
if((*c != *p) || theRedrawEntireFrameFlag) if((*c != *p) || theRedrawEntireFrameIndicator)
{ {
// Can we extend a rectangle or do we have to create a new one? // Can we extend a rectangle or do we have to create a new one?
if((currentCount != 0) && if((currentCount != 0) &&
@ -779,8 +725,8 @@ void updateDisplay(MediaSource& mediaSource)
activeRectangles = tmp; activeRectangles = tmp;
activeCount = currentCount; activeCount = currentCount;
currentFrame += theWidth; currentFrame += width;
previousFrame += theWidth; previousFrame += width;
} }
// Flush any rectangles that are still active // Flush any rectangles that are still active
@ -802,7 +748,7 @@ void updateDisplay(MediaSource& mediaSource)
SDL_UpdateRects(screen, rectList->numRects(), rectList->rects()); SDL_UpdateRects(screen, rectList->numRects(), rectList->rects());
// The frame doesn't need to be completely redrawn anymore // The frame doesn't need to be completely redrawn anymore
theRedrawEntireFrameFlag = false; theRedrawEntireFrameIndicator = false;
} }
@ -859,8 +805,8 @@ void handleEvents()
// don't change grabmouse in fullscreen mode // don't change grabmouse in fullscreen mode
if(!isFullscreen) if(!isFullscreen)
{ {
theGrabMouseFlag = !theGrabMouseFlag; settings->theGrabMouseFlag = !settings->theGrabMouseFlag;
grabMouse(theGrabMouseFlag); grabMouse(settings->theGrabMouseFlag);
} }
} }
else if(key == SDLK_h) else if(key == SDLK_h)
@ -868,8 +814,8 @@ void handleEvents()
// don't change hidecursor in fullscreen mode // don't change hidecursor in fullscreen mode
if(!isFullscreen) if(!isFullscreen)
{ {
theHideCursorFlag = !theHideCursorFlag; settings->theHideCursorFlag = !settings->theHideCursorFlag;
showCursor(!theHideCursorFlag); showCursor(!settings->theHideCursorFlag);
} }
} }
else // check all the other keys else // check all the other keys
@ -902,18 +848,18 @@ void handleEvents()
{ {
int resistance = 0, x = 0; int resistance = 0, x = 0;
float fudgeFactor = 1000000.0; float fudgeFactor = 1000000.0;
int width = theWidth * 2 * theWindowSize; Int32 width = settings->theWidth * settings->theWindowSize * 2;
// Grabmouse and hidecursor introduce some lag into the mouse movement, // Grabmouse and hidecursor introduce some lag into the mouse movement,
// so we need to fudge the numbers a bit // so we need to fudge the numbers a bit
if(theGrabMouseFlag && theHideCursorFlag) if(settings->theGrabMouseFlag && settings->theHideCursorFlag)
{ {
mouseX = (int)((float)mouseX + (float)event.motion.xrel mouseX = (int)((float)mouseX + (float)event.motion.xrel
* 1.5 * (float)theWindowSize); * 1.5 * (float) settings->theWindowSize);
} }
else else
{ {
mouseX = mouseX + event.motion.xrel * theWindowSize; mouseX = mouseX + event.motion.xrel * settings->theWindowSize;
} }
// Check to make sure mouseX is within the game window // Check to make sure mouseX is within the game window
@ -926,35 +872,35 @@ void handleEvents()
resistance = (Int32)((fudgeFactor * x) / width); resistance = (Int32)((fudgeFactor * x) / width);
// Now, set the event of the correct paddle to the calculated resistance // Now, set the event of the correct paddle to the calculated resistance
if(thePaddleMode == 0) if(settings->thePaddleMode == 0)
theEvent.set(Event::PaddleZeroResistance, resistance); theEvent.set(Event::PaddleZeroResistance, resistance);
else if(thePaddleMode == 1) else if(settings->thePaddleMode == 1)
theEvent.set(Event::PaddleOneResistance, resistance); theEvent.set(Event::PaddleOneResistance, resistance);
else if(thePaddleMode == 2) else if(settings->thePaddleMode == 2)
theEvent.set(Event::PaddleTwoResistance, resistance); theEvent.set(Event::PaddleTwoResistance, resistance);
else if(thePaddleMode == 3) else if(settings->thePaddleMode == 3)
theEvent.set(Event::PaddleThreeResistance, resistance); theEvent.set(Event::PaddleThreeResistance, resistance);
} }
else if(event.type == SDL_MOUSEBUTTONDOWN) else if(event.type == SDL_MOUSEBUTTONDOWN)
{ {
if(thePaddleMode == 0) if(settings->thePaddleMode == 0)
theEvent.set(Event::PaddleZeroFire, 1); theEvent.set(Event::PaddleZeroFire, 1);
else if(thePaddleMode == 1) else if(settings->thePaddleMode == 1)
theEvent.set(Event::PaddleOneFire, 1); theEvent.set(Event::PaddleOneFire, 1);
else if(thePaddleMode == 2) else if(settings->thePaddleMode == 2)
theEvent.set(Event::PaddleTwoFire, 1); theEvent.set(Event::PaddleTwoFire, 1);
else if(thePaddleMode == 3) else if(settings->thePaddleMode == 3)
theEvent.set(Event::PaddleThreeFire, 1); theEvent.set(Event::PaddleThreeFire, 1);
} }
else if(event.type == SDL_MOUSEBUTTONUP) else if(event.type == SDL_MOUSEBUTTONUP)
{ {
if(thePaddleMode == 0) if(settings->thePaddleMode == 0)
theEvent.set(Event::PaddleZeroFire, 0); theEvent.set(Event::PaddleZeroFire, 0);
else if(thePaddleMode == 1) else if(settings->thePaddleMode == 1)
theEvent.set(Event::PaddleOneFire, 0); theEvent.set(Event::PaddleOneFire, 0);
else if(thePaddleMode == 2) else if(settings->thePaddleMode == 2)
theEvent.set(Event::PaddleTwoFire, 0); theEvent.set(Event::PaddleTwoFire, 0);
else if(thePaddleMode == 3) else if(settings->thePaddleMode == 3)
theEvent.set(Event::PaddleThreeFire, 0); theEvent.set(Event::PaddleThreeFire, 0);
} }
else if(event.type == SDL_ACTIVEEVENT) else if(event.type == SDL_ACTIVEEVENT)
@ -988,7 +934,7 @@ void handleEvents()
1 : keyboardEvent.get(Event::JoystickZeroFire)); 1 : keyboardEvent.get(Event::JoystickZeroFire));
// If we're using real paddles then set paddle event as well // If we're using real paddles then set paddle event as well
if(thePaddleMode == 4) if(settings->thePaddleMode == 4)
theEvent.set(Event::PaddleZeroFire, state); theEvent.set(Event::PaddleZeroFire, state);
} }
else if(button == 1) // booster button else if(button == 1) // booster button
@ -997,7 +943,7 @@ void handleEvents()
1 : keyboardEvent.get(Event::BoosterGripZeroTrigger)); 1 : keyboardEvent.get(Event::BoosterGripZeroTrigger));
// If we're using real paddles then set paddle event as well // If we're using real paddles then set paddle event as well
if(thePaddleMode == 4) if(settings->thePaddleMode == 4)
theEvent.set(Event::PaddleOneFire, state); theEvent.set(Event::PaddleOneFire, state);
} }
} }
@ -1014,7 +960,7 @@ void handleEvents()
1 : keyboardEvent.get(Event::JoystickZeroRight)); 1 : keyboardEvent.get(Event::JoystickZeroRight));
// If we're using real paddles then set paddle events as well // If we're using real paddles then set paddle events as well
if(thePaddleMode == 4) if(settings->thePaddleMode == 4)
{ {
uInt32 r = (uInt32)((1.0E6L * (value + 32767L)) / 65536); uInt32 r = (uInt32)((1.0E6L * (value + 32767L)) / 65536);
theEvent.set(Event::PaddleZeroResistance, r); theEvent.set(Event::PaddleZeroResistance, r);
@ -1028,7 +974,7 @@ void handleEvents()
1 : keyboardEvent.get(Event::JoystickZeroDown)); 1 : keyboardEvent.get(Event::JoystickZeroDown));
// If we're using real paddles then set paddle events as well // If we're using real paddles then set paddle events as well
if(thePaddleMode == 4) if(settings->thePaddleMode == 4)
{ {
uInt32 r = (uInt32)((1.0E6L * (value + 32767L)) / 65536); uInt32 r = (uInt32)((1.0E6L * (value + 32767L)) / 65536);
theEvent.set(Event::PaddleOneResistance, r); theEvent.set(Event::PaddleOneResistance, r);
@ -1052,7 +998,7 @@ void handleEvents()
1 : keyboardEvent.get(Event::JoystickOneFire)); 1 : keyboardEvent.get(Event::JoystickOneFire));
// If we're using real paddles then set paddle event as well // If we're using real paddles then set paddle event as well
if(thePaddleMode == 4) if(settings->thePaddleMode == 4)
theEvent.set(Event::PaddleTwoFire, state); theEvent.set(Event::PaddleTwoFire, state);
} }
else if(button == 1) // booster button else if(button == 1) // booster button
@ -1061,7 +1007,7 @@ void handleEvents()
1 : keyboardEvent.get(Event::BoosterGripOneTrigger)); 1 : keyboardEvent.get(Event::BoosterGripOneTrigger));
// If we're using real paddles then set paddle event as well // If we're using real paddles then set paddle event as well
if(thePaddleMode == 4) if(settings->thePaddleMode == 4)
theEvent.set(Event::PaddleThreeFire, state); theEvent.set(Event::PaddleThreeFire, state);
} }
} }
@ -1078,7 +1024,7 @@ void handleEvents()
1 : keyboardEvent.get(Event::JoystickOneRight)); 1 : keyboardEvent.get(Event::JoystickOneRight));
// If we're using real paddles then set paddle events as well // If we're using real paddles then set paddle events as well
if(thePaddleMode == 4) if(settings->thePaddleMode == 4)
{ {
uInt32 r = (uInt32)((1.0E6L * (value + 32767L)) / 65536); uInt32 r = (uInt32)((1.0E6L * (value + 32767L)) / 65536);
theEvent.set(Event::PaddleTwoResistance, r); theEvent.set(Event::PaddleTwoResistance, r);
@ -1092,7 +1038,7 @@ void handleEvents()
1 : keyboardEvent.get(Event::JoystickOneDown)); 1 : keyboardEvent.get(Event::JoystickOneDown));
// If we're using real paddles then set paddle events as well // If we're using real paddles then set paddle events as well
if(thePaddleMode == 4) if(settings->thePaddleMode == 4)
{ {
uInt32 r = (uInt32)((1.0E6L * (value + 32767L)) / 65536); uInt32 r = (uInt32)((1.0E6L * (value + 32767L)) / 65536);
theEvent.set(Event::PaddleThreeResistance, r); theEvent.set(Event::PaddleThreeResistance, r);
@ -1124,14 +1070,14 @@ void takeSnapshot()
} }
// Now find the correct name for the snapshot // Now find the correct name for the snapshot
string filename = theSnapShotDir; string filename = settings->theSnapShotDir;
if(theSnapShotName == "romname") if(settings->theSnapShotName == "romname")
filename = filename + "/" + theConsole->properties().get("Cartridge.Name"); filename = filename + "/" + theConsole->properties().get("Cartridge.Name");
else if(theSnapShotName == "md5sum") else if(settings->theSnapShotName == "md5sum")
filename = filename + "/" + theConsole->properties().get("Cartridge.MD5"); filename = filename + "/" + theConsole->properties().get("Cartridge.MD5");
else else
{ {
cerr << "ERROR: unknown name " << theSnapShotName cerr << "ERROR: unknown name " << settings->theSnapShotName
<< " for snapshot type" << endl; << " for snapshot type" << endl;
return; return;
} }
@ -1140,7 +1086,7 @@ void takeSnapshot()
replace(filename.begin(), filename.end(), ' ', '_'); replace(filename.begin(), filename.end(), ' ', '_');
// Check whether we want multiple snapshots created // Check whether we want multiple snapshots created
if(theMultipleSnapShotFlag) if(settings->theMultipleSnapShotFlag)
{ {
// Determine if the file already exists, checking each successive filename // Determine if the file already exists, checking each successive filename
// until one doesn't exist // until one doesn't exist
@ -1165,7 +1111,7 @@ void takeSnapshot()
filename = filename + ".png"; filename = filename + ".png";
// Now save the snapshot file // Now save the snapshot file
snapshot->savePNG(filename, theConsole->mediaSource(), theWindowSize); snapshot->savePNG(filename, theConsole->mediaSource(), settings->theWindowSize);
if(access(filename.c_str(), F_OK) == 0) if(access(filename.c_str(), F_OK) == 0)
cerr << "Snapshot saved as " << filename << endl; cerr << "Snapshot saved as " << filename << endl;
@ -1198,14 +1144,14 @@ uInt32 maxWindowSizeForScreen()
int screenHeight = DisplayHeight(info.info.x11.display, int screenHeight = DisplayHeight(info.info.x11.display,
DefaultScreen(theX11Display)); DefaultScreen(theX11Display));
uInt32 multiplier = screenWidth / (theWidth * 2); uInt32 multiplier = screenWidth / (settings->theWidth * 2);
bool found = false; bool found = false;
while(!found && (multiplier > 0)) while(!found && (multiplier > 0))
{ {
// Figure out the desired size of the window // Figure out the desired size of the window
int width = theWidth * 2 * multiplier; int width = settings->theWidth * multiplier * 2;
int height = theHeight * multiplier; int height = settings->theHeight * multiplier;
if((width < screenWidth) && (height < screenHeight)) if((width < screenWidth) && (height < screenHeight))
found = true; found = true;
@ -1277,16 +1223,16 @@ bool setupProperties(PropertiesSet& set)
// Check to see if the user has specified an alternate .pro file. // Check to see if the user has specified an alternate .pro file.
// If it exists, use it. // If it exists, use it.
if(theAlternateProFile != "") if(settings->theAlternateProFile != "")
{ {
if(access(theAlternateProFile.c_str(), R_OK) == 0) if(access(settings->theAlternateProFile.c_str(), R_OK) == 0)
{ {
set.load(theAlternateProFile, &Console::defaultProperties(), false); set.load(settings->theAlternateProFile, &Console::defaultProperties(), false);
return true; return true;
} }
else else
{ {
cerr << "ERROR: Couldn't find \"" << theAlternateProFile << cerr << "ERROR: Couldn't find \"" << settings->theAlternateProFile <<
"\" properties file." << endl; "\" properties file." << endl;
return false; return false;
} }
@ -1310,115 +1256,6 @@ bool setupProperties(PropertiesSet& set)
} }
/**
Should be called to parse the command line arguments
@param argc The count of command line arguments
@param argv The command line arguments
*/
void handleCommandLineArguments(int argc, char* argv[])
{
// Make sure we have the correct number of command line arguments
if(argc == 1)
usage();
for(Int32 i = 1; i < (argc - 1); ++i)
{
// See which command line switch they're using
if(string(argv[i]) == "-fps")
{
// They're setting the desired frame rate
Int32 rate = atoi(argv[++i]);
if((rate < 1) || (rate > 300))
{
rate = 60;
}
theDesiredFrameRate = rate;
}
else if(string(argv[i]) == "-paddle")
{
// They're trying to set the paddle emulation mode
if(string(argv[i + 1]) == "real")
{
thePaddleMode = 4;
}
else
{
thePaddleMode = atoi(argv[i + 1]);
if((thePaddleMode < 0) || (thePaddleMode > 3))
{
usage();
}
}
++i;
}
else if(string(argv[i]) == "-owncmap")
{
theUsePrivateColormapFlag = true;
}
else if(string(argv[i]) == "-fullscreen")
{
theUseFullScreenFlag = true;
}
else if(string(argv[i]) == "-grabmouse")
{
theGrabMouseFlag = true;
}
else if(string(argv[i]) == "-hidecursor")
{
theHideCursorFlag = true;
}
else if(string(argv[i]) == "-center")
{
theCenterWindowFlag = true;
}
else if(string(argv[i]) == "-showinfo")
{
theShowInfoFlag = true;
}
else if(string(argv[i]) == "-zoom")
{
uInt32 size = atoi(argv[++i]);
theWindowSize = size;
}
else if(string(argv[i]) == "-volume")
{
// They're setting the desired volume
Int32 volume = atoi(argv[++i]);
if(volume < 0)
volume = 0;
if(volume > 100)
volume = 100;
theDesiredVolume = volume;
}
#ifdef HAVE_PNG
else if(string(argv[i]) == "-ssdir")
{
theSnapShotDir = argv[++i];
}
else if(string(argv[i]) == "-ssname")
{
theSnapShotName = argv[++i];
}
else if(string(argv[i]) == "-sssingle")
{
theMultipleSnapShotFlag = false;
}
#endif
else if(string(argv[i]) == "-pro")
{
theAlternateProFile = argv[++i];
}
else
{
cout << "Undefined option " << argv[i] << endl;
}
}
}
/** /**
Should be called to determine if an rc file exists. First checks if there Should be called to determine if an rc file exists. First checks if there
is a user specified file ".stellarc" and then if there is a system-wide is a user specified file ".stellarc" and then if there is a system-wide
@ -1432,161 +1269,12 @@ void handleRCFile()
if(access(homeRCFile.c_str(), R_OK) == 0 ) if(access(homeRCFile.c_str(), R_OK) == 0 )
{ {
ifstream homeStream(homeRCFile.c_str()); ifstream homeStream(homeRCFile.c_str());
parseRCOptions(homeStream); settings->handleRCFile(homeStream);
} }
else if(access("/etc/stellarc", R_OK) == 0 ) else if(access("/etc/stellarc", R_OK) == 0 )
{ {
ifstream systemStream("/etc/stellarc"); ifstream systemStream("/etc/stellarc");
parseRCOptions(systemStream); settings->handleRCFile(systemStream);
}
}
/**
Parses each line of the given rcfile and sets options accordingly.
@param in The file to parse for options
*/
void parseRCOptions(istream& in)
{
string line, key, value;
uInt32 equalPos;
while(getline(in, line))
{
// Strip all whitespace and tabs from the line
uInt32 garbage;
while((garbage = line.find(" ")) != string::npos)
line.erase(garbage, 1);
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;
key = line.substr(0, equalPos);
value = line.substr(equalPos + 1, line.length() - key.length() - 1);
// Check for absent key or value
if((key.length() == 0) || (value.length() == 0))
continue;
// Now set up the options by key
if(key == "fps")
{
// They're setting the desired frame rate
uInt32 rate = atoi(value.c_str());
if((rate < 1) || (rate > 300))
{
rate = 60;
}
theDesiredFrameRate = rate;
}
else if(key == "paddle")
{
// They're trying to set the paddle emulation mode
uInt32 pMode;
if(value == "real")
{
thePaddleMode = 4;
}
else
{
pMode = atoi(value.c_str());
if((pMode > 0) && (pMode < 4))
thePaddleMode = pMode;
}
}
else if(key == "owncmap")
{
uInt32 option = atoi(value.c_str());
if(option == 1)
theUsePrivateColormapFlag = true;
else if(option == 0)
theUsePrivateColormapFlag = false;
}
else if(key == "fullscreen")
{
uInt32 option = atoi(value.c_str());
if(option == 1)
theUseFullScreenFlag = true;
else if(option == 0)
theUseFullScreenFlag = false;
}
else if(key == "grabmouse")
{
uInt32 option = atoi(value.c_str());
if(option == 1)
theGrabMouseFlag = true;
else if(option == 0)
theGrabMouseFlag = false;
}
else if(key == "hidecursor")
{
uInt32 option = atoi(value.c_str());
if(option == 1)
theHideCursorFlag = true;
else if(option == 0)
theHideCursorFlag = false;
}
else if(key == "center")
{
uInt32 option = atoi(value.c_str());
if(option == 1)
theCenterWindowFlag = true;
else if(option == 0)
theCenterWindowFlag = false;
}
else if(key == "showinfo")
{
uInt32 option = atoi(value.c_str());
if(option == 1)
theShowInfoFlag = true;
else if(option == 0)
theShowInfoFlag = false;
}
else if(key == "zoom")
{
// They're setting the initial window size
// Don't do bounds checking here, it will be taken care of later
uInt32 size = atoi(value.c_str());
theWindowSize = size;
}
else if(key == "volume")
{
// They're setting the desired volume
uInt32 volume = atoi(value.c_str());
if(volume < 0)
volume = 0;
if(volume > 100)
volume = 100;
theDesiredVolume = volume;
}
#ifdef HAVE_PNG
else if(key == "ssdir")
{
theSnapShotDir = value;
}
else if(key == "ssname")
{
theSnapShotName = value;
}
else if(key == "sssingle")
{
uInt32 option = atoi(value.c_str());
if(option == 1)
theMultipleSnapShotFlag = false;
else if(option == 0)
theMultipleSnapShotFlag = true;
}
#endif
} }
} }
@ -1599,6 +1287,9 @@ void cleanup()
if(theConsole) if(theConsole)
delete theConsole; delete theConsole;
if(settings)
delete settings;
#ifdef HAVE_PNG #ifdef HAVE_PNG
if(snapshot) if(snapshot)
delete snapshot; delete snapshot;
@ -1619,11 +1310,23 @@ void cleanup()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
// First create some settings for the emulator
settings = new Settings();
if(!settings)
{
cerr << "ERROR: Couldn't create settings." << endl;
cleanup();
}
// Load in any user defined settings from an RC file // Load in any user defined settings from an RC file
handleRCFile(); handleRCFile();
// Handle the command line arguments // Handle the command line arguments
handleCommandLineArguments(argc, argv); if(!settings->handleCommandLineArgs(argc, argv))
{
usage();
cleanup();
}
// Get a pointer to the file which contains the cartridge ROM // Get a pointer to the file which contains the cartridge ROM
const char* file = argv[argc - 1]; const char* file = argv[argc - 1];
@ -1633,7 +1336,7 @@ int main(int argc, char* argv[])
if(!in) if(!in)
{ {
cerr << "ERROR: Couldn't open " << file << "..." << endl; cerr << "ERROR: Couldn't open " << file << "..." << endl;
exit(1); cleanup();
} }
uInt8* image = new uInt8[512 * 1024]; uInt8* image = new uInt8[512 * 1024];
@ -1646,11 +1349,11 @@ int main(int argc, char* argv[])
if(!setupProperties(propertiesSet)) if(!setupProperties(propertiesSet))
{ {
delete[] image; delete[] image;
exit(1); cleanup();
} }
// Create a sound object for use with the console // Create a sound object for use with the console
SoundUnix sound(theDesiredVolume); SoundUnix sound(settings->theDesiredVolume);
// Get just the filename of the file containing the ROM image // Get just the filename of the file containing the ROM image
const char* filename = (!strrchr(file, '/')) ? file : strrchr(file, '/') + 1; const char* filename = (!strrchr(file, '/')) ? file : strrchr(file, '/') + 1;
@ -1718,7 +1421,7 @@ int main(int argc, char* argv[])
// Set up timing stuff // Set up timing stuff
uInt32 startTime, frameTime, delta; uInt32 startTime, frameTime, delta;
uInt32 numberOfFrames = 0; uInt32 numberOfFrames = 0;
uInt32 timePerFrame = (uInt32) (1000000.0 / (double) theDesiredFrameRate); uInt32 timePerFrame = (uInt32) (1000000.0 / (double) settings->theDesiredFrameRate);
// Set the base for the timers // Set the base for the timers
frameTime = 0; frameTime = 0;
@ -1760,7 +1463,7 @@ int main(int argc, char* argv[])
} }
#endif #endif
if(theShowInfoFlag) if(settings->theShowInfoFlag)
{ {
double executionTime = (double) frameTime / 1000000.0; double executionTime = (double) frameTime / 1000000.0;
double framesPerSecond = (double) numberOfFrames / executionTime; double framesPerSecond = (double) numberOfFrames / executionTime;

File diff suppressed because it is too large Load Diff