mirror of https://github.com/stella-emu/stella.git
Updated X11 and SDL ports to make use of the new DEVELOPER_SUPPORT
stuff. These are availble only if DEVELOPER_SUPPORT as been defined. The keys are as follows: Alt+s: Save the current properties to your home directory named as "Cartridge.Name".pro, with all spaces in the filename converted to underscore. Alt+f: Toggle between NTSC and PAL modes, and update the palette accordingly. PageUp / PageDown: Increase / decrease the "Display.YStart" variable. Alt+PageUp / Alt+PageDown: Increase / decrease the "Display.Height" variable. Home / End: Increase / decrease the "Display.XStart" variable. Alt+Home / Alt+End: Increase / decrease the "Display.Width" variable. Also, cleaned up the code a bit wrt C functions. Got rid of all sprintf C-style functions, and used C++ style sstream instead. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@125 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
a12078de97
commit
4d149d7885
|
@ -13,14 +13,15 @@
|
||||||
// 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.31 2002-10-12 15:24:49 stephena Exp $
|
// $Id: mainSDL.cxx,v 1.32 2002-11-10 19:18:35 stephena Exp $
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
@ -57,7 +58,7 @@
|
||||||
// function prototypes
|
// function prototypes
|
||||||
static bool setupDisplay();
|
static bool setupDisplay();
|
||||||
static bool setupJoystick();
|
static bool setupJoystick();
|
||||||
static bool createScreen(int width, int height);
|
static bool createScreen();
|
||||||
static void recalculate8BitPalette();
|
static void recalculate8BitPalette();
|
||||||
static void setupPalette();
|
static void setupPalette();
|
||||||
static void cleanup();
|
static void cleanup();
|
||||||
|
@ -229,7 +230,7 @@ bool setupDisplay()
|
||||||
sdlflags |= settings->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
|
||||||
settings->theWidth = theConsole->mediaSource().width();
|
settings->theWidth = theConsole->mediaSource().width();
|
||||||
settings->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
|
||||||
|
@ -274,17 +275,12 @@ bool setupDisplay()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the window title and icon
|
// Set the window title and icon
|
||||||
char name[512];
|
ostringstream name;
|
||||||
sprintf(name, "Stella: \"%s\"",
|
name << "Stella: \"" << theConsole->properties().get("Cartridge.Name") << "\"";
|
||||||
theConsole->properties().get("Cartridge.Name").c_str());
|
SDL_WM_SetCaption(name.str().c_str(), "stella");
|
||||||
SDL_WM_SetCaption(name, "stella");
|
|
||||||
|
|
||||||
// Figure out the desired size of the window
|
|
||||||
int width = settings->theWidth * settings->theWindowSize * 2;
|
|
||||||
int height = settings->theHeight * settings->theWindowSize;
|
|
||||||
|
|
||||||
// Create the screen
|
// Create the screen
|
||||||
if(!createScreen(width, height))
|
if(!createScreen())
|
||||||
return false;
|
return false;
|
||||||
setupPalette();
|
setupPalette();
|
||||||
|
|
||||||
|
@ -350,8 +346,11 @@ bool setupJoystick()
|
||||||
It updates the global screen variable. When this happens, the
|
It updates the global screen variable. When this happens, the
|
||||||
8-bit palette needs to be recalculated.
|
8-bit palette needs to be recalculated.
|
||||||
*/
|
*/
|
||||||
bool createScreen(int w, int h)
|
bool createScreen()
|
||||||
{
|
{
|
||||||
|
int w = settings->theWidth * settings->theWindowSize * 2;
|
||||||
|
int h = settings->theHeight * settings->theWindowSize;
|
||||||
|
|
||||||
screen = SDL_SetVideoMode(w, h, 0, sdlflags);
|
screen = SDL_SetVideoMode(w, h, 0, sdlflags);
|
||||||
if(screen == NULL)
|
if(screen == NULL)
|
||||||
{
|
{
|
||||||
|
@ -363,6 +362,8 @@ bool createScreen(int w, int h)
|
||||||
if(bpp == 8)
|
if(bpp == 8)
|
||||||
recalculate8BitPalette();
|
recalculate8BitPalette();
|
||||||
|
|
||||||
|
theRedrawEntireFrameIndicator = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -404,6 +405,8 @@ void recalculate8BitPalette()
|
||||||
|
|
||||||
palette[i] = SDL_MapRGB(format, r, g, b);
|
palette[i] = SDL_MapRGB(format, r, g, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
theRedrawEntireFrameIndicator = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -449,6 +452,8 @@ void setupPalette()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
theRedrawEntireFrameIndicator = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -464,39 +469,45 @@ void doQuit()
|
||||||
/**
|
/**
|
||||||
This routine is called when the user wants to resize the window.
|
This routine is called when the user wants to resize the window.
|
||||||
A '1' argument indicates that the window should increase in size, while '0'
|
A '1' argument indicates that the window should increase in size, while '0'
|
||||||
indicates that the windows should decrease in size.
|
indicates that the windows should decrease in size. A '-1' indicates that
|
||||||
|
the window should be sized according to the current properties.
|
||||||
Can't resize in fullscreen mode. Will only resize up to the maximum size
|
Can't resize in fullscreen mode. Will only resize up to the maximum size
|
||||||
of the screen.
|
of the screen.
|
||||||
*/
|
*/
|
||||||
void resizeWindow(int mode)
|
void resizeWindow(int mode)
|
||||||
{
|
{
|
||||||
if(isFullscreen)
|
// reset size to that given in properties
|
||||||
return;
|
// this is a special case of allowing a resize while in fullscreen mode
|
||||||
|
if(mode == -1)
|
||||||
if(mode == 1) // increase size
|
|
||||||
{
|
{
|
||||||
|
settings->theWidth = theConsole->mediaSource().width();
|
||||||
|
settings->theHeight = theConsole->mediaSource().height();
|
||||||
|
settings->theMaxWindowSize = maxWindowSizeForScreen();
|
||||||
|
}
|
||||||
|
else if(mode == 1) // increase size
|
||||||
|
{
|
||||||
|
if(isFullscreen)
|
||||||
|
return;
|
||||||
|
|
||||||
if(settings->theWindowSize == settings->theMaxWindowSize)
|
if(settings->theWindowSize == settings->theMaxWindowSize)
|
||||||
settings->theWindowSize = 1;
|
settings->theWindowSize = 1;
|
||||||
else
|
else
|
||||||
settings->theWindowSize++;
|
settings->theWindowSize++;
|
||||||
}
|
}
|
||||||
else // decrease size
|
else if(mode == 0) // decrease size
|
||||||
{
|
{
|
||||||
|
if(isFullscreen)
|
||||||
|
return;
|
||||||
|
|
||||||
if(settings->theWindowSize == 1)
|
if(settings->theWindowSize == 1)
|
||||||
settings->theWindowSize = settings->theMaxWindowSize;
|
settings->theWindowSize = settings->theMaxWindowSize;
|
||||||
else
|
else
|
||||||
settings->theWindowSize--;
|
settings->theWindowSize--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Figure out the desired size of the window
|
if(!createScreen())
|
||||||
int width = settings->theWidth * settings->theWindowSize * 2;
|
|
||||||
int height = settings->theHeight * settings->theWindowSize;
|
|
||||||
|
|
||||||
if(!createScreen(width, height))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
@ -534,6 +545,7 @@ void centerWindow()
|
||||||
info.info.x11.unlock_func();
|
info.info.x11.unlock_func();
|
||||||
|
|
||||||
isCentered = true;
|
isCentered = true;
|
||||||
|
theRedrawEntireFrameIndicator = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -552,7 +564,7 @@ void toggleFullscreen()
|
||||||
else
|
else
|
||||||
sdlflags &= ~SDL_FULLSCREEN;
|
sdlflags &= ~SDL_FULLSCREEN;
|
||||||
|
|
||||||
if(!createScreen(width, height))
|
if(!createScreen())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(isFullscreen) // now in fullscreen mode
|
if(isFullscreen) // now in fullscreen mode
|
||||||
|
@ -568,8 +580,6 @@ void toggleFullscreen()
|
||||||
if(settings->theCenterWindowFlag)
|
if(settings->theCenterWindowFlag)
|
||||||
centerWindow();
|
centerWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
theRedrawEntireFrameIndicator = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -592,7 +602,6 @@ void togglePause()
|
||||||
|
|
||||||
// Show a different palette depending on pause state
|
// Show a different palette depending on pause state
|
||||||
setupPalette();
|
setupPalette();
|
||||||
theRedrawEntireFrameIndicator = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -625,27 +634,24 @@ void grabMouse(bool grab)
|
||||||
*/
|
*/
|
||||||
void saveState()
|
void saveState()
|
||||||
{
|
{
|
||||||
char buf[1024];
|
ostringstream buf;
|
||||||
string path = getenv("HOME");
|
|
||||||
path += "/.stella/state";
|
|
||||||
|
|
||||||
// First get the name for the current state file
|
|
||||||
string md5 = theConsole->properties().get("Cartridge.MD5");
|
string md5 = theConsole->properties().get("Cartridge.MD5");
|
||||||
snprintf(buf, 1023, "%s/%s.st%d", path.c_str(), md5.c_str(), currentState);
|
buf << getenv("HOME") << "/.stella/state/" << md5 << ".st" << currentState;
|
||||||
string fileName = buf;
|
string filename = buf.str();
|
||||||
|
|
||||||
// Do a state save using the System
|
// Do a state save using the System
|
||||||
int result = theConsole->system().saveState(fileName, md5);
|
int result = theConsole->system().saveState(filename, md5);
|
||||||
|
|
||||||
// Print appropriate message
|
// Print appropriate message
|
||||||
|
buf.str("");
|
||||||
if(result == 1)
|
if(result == 1)
|
||||||
snprintf(buf, 1023, "State %d saved", currentState);
|
buf << "State " << currentState << " saved";
|
||||||
else if(result == 2)
|
else if(result == 2)
|
||||||
snprintf(buf, 1023, "Error saving state %d", currentState);
|
buf << "Error saving state " << currentState;
|
||||||
else if(result == 3)
|
else if(result == 3)
|
||||||
snprintf(buf, 1023, "Invalid state %d file", currentState);
|
buf << "Invalid state " << currentState << " file";
|
||||||
|
|
||||||
string message = buf;
|
string message = buf.str();
|
||||||
theConsole->mediaSource().showMessage(message, MESSAGE_INTERVAL *
|
theConsole->mediaSource().showMessage(message, MESSAGE_INTERVAL *
|
||||||
settings->theDesiredFrameRate);
|
settings->theDesiredFrameRate);
|
||||||
}
|
}
|
||||||
|
@ -672,9 +678,9 @@ void changeState(int direction)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print appropriate message
|
// Print appropriate message
|
||||||
char buf[40];
|
ostringstream buf;
|
||||||
snprintf(buf, 39, "Changed to slot %d", currentState);
|
buf << "Changed to slot " << currentState;
|
||||||
string message = buf;
|
string message = buf.str();
|
||||||
theConsole->mediaSource().showMessage(message, MESSAGE_INTERVAL *
|
theConsole->mediaSource().showMessage(message, MESSAGE_INTERVAL *
|
||||||
settings->theDesiredFrameRate);
|
settings->theDesiredFrameRate);
|
||||||
}
|
}
|
||||||
|
@ -685,27 +691,24 @@ void changeState(int direction)
|
||||||
*/
|
*/
|
||||||
void loadState()
|
void loadState()
|
||||||
{
|
{
|
||||||
char buf[1024];
|
ostringstream buf;
|
||||||
string path = getenv("HOME");
|
|
||||||
path += "/.stella/state";
|
|
||||||
|
|
||||||
// First get the name for the current state file
|
|
||||||
string md5 = theConsole->properties().get("Cartridge.MD5");
|
string md5 = theConsole->properties().get("Cartridge.MD5");
|
||||||
snprintf(buf, 1023, "%s/%s.st%d", path.c_str(), md5.c_str(), currentState);
|
buf << getenv("HOME") << "/.stella/state/" << md5 << ".st" << currentState;
|
||||||
string fileName = buf;
|
string filename = buf.str();
|
||||||
|
|
||||||
// Do a state load using the System
|
// Do a state load using the System
|
||||||
int result = theConsole->system().loadState(fileName, md5);
|
int result = theConsole->system().loadState(filename, md5);
|
||||||
|
|
||||||
// Print appropriate message
|
// Print appropriate message
|
||||||
|
buf.str("");
|
||||||
if(result == 1)
|
if(result == 1)
|
||||||
snprintf(buf, 1023, "State %d loaded", currentState);
|
buf << "State " << currentState << " loaded";
|
||||||
else if(result == 2)
|
else if(result == 2)
|
||||||
snprintf(buf, 1023, "Error loading state %d", currentState);
|
buf << "Error loading state " << currentState;
|
||||||
else if(result == 3)
|
else if(result == 3)
|
||||||
snprintf(buf, 1023, "Invalid state %d file", currentState);
|
buf << "Invalid state " << currentState << " file";
|
||||||
|
|
||||||
string message = buf;
|
string message = buf.str();
|
||||||
theConsole->mediaSource().showMessage(message, MESSAGE_INTERVAL *
|
theConsole->mediaSource().showMessage(message, MESSAGE_INTERVAL *
|
||||||
settings->theDesiredFrameRate);
|
settings->theDesiredFrameRate);
|
||||||
}
|
}
|
||||||
|
@ -954,6 +957,69 @@ void handleEvents()
|
||||||
showCursor(!settings->theHideCursorFlag);
|
showCursor(!settings->theHideCursorFlag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef DEVELOPER_SUPPORT
|
||||||
|
if(key == SDLK_f) // Alt-f switches between NTSC and PAL
|
||||||
|
{
|
||||||
|
if(mod & KMOD_ALT)
|
||||||
|
{
|
||||||
|
theConsole->toggleFormat();
|
||||||
|
|
||||||
|
// update the palette
|
||||||
|
setupPalette();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(key == SDLK_END) // End decreases XStart
|
||||||
|
{ // Alt-End decreases Width
|
||||||
|
if(mod & KMOD_ALT)
|
||||||
|
theConsole->changeWidth(0);
|
||||||
|
else
|
||||||
|
theConsole->changeXStart(0);
|
||||||
|
|
||||||
|
// Make sure changes to the properties are reflected onscreen
|
||||||
|
resizeWindow(-1);
|
||||||
|
}
|
||||||
|
else if(key == SDLK_HOME) // Home increases XStart
|
||||||
|
{ // Alt-Home increases Width
|
||||||
|
if(mod & KMOD_ALT)
|
||||||
|
theConsole->changeWidth(1);
|
||||||
|
else
|
||||||
|
theConsole->changeXStart(1);
|
||||||
|
|
||||||
|
// Make sure changes to the properties are reflected onscreen
|
||||||
|
resizeWindow(-1);
|
||||||
|
}
|
||||||
|
else if(key == SDLK_PAGEDOWN) // PageDown decreases YStart
|
||||||
|
{ // Alt-PageDown decreases Height
|
||||||
|
if(mod & KMOD_ALT)
|
||||||
|
theConsole->changeHeight(0);
|
||||||
|
else
|
||||||
|
theConsole->changeYStart(0);
|
||||||
|
|
||||||
|
// Make sure changes to the properties are reflected onscreen
|
||||||
|
resizeWindow(-1);
|
||||||
|
}
|
||||||
|
else if(key == SDLK_PAGEUP) // PageUp increases YStart
|
||||||
|
{ // Alt-PageUp increases Height
|
||||||
|
if(mod & KMOD_ALT)
|
||||||
|
theConsole->changeHeight(1);
|
||||||
|
else
|
||||||
|
theConsole->changeYStart(1);
|
||||||
|
|
||||||
|
// Make sure changes to the properties are reflected onscreen
|
||||||
|
resizeWindow(-1);
|
||||||
|
}
|
||||||
|
else if(key == SDLK_s) // Alt-s saves properties to a file
|
||||||
|
{
|
||||||
|
if(mod & KMOD_ALT)
|
||||||
|
{
|
||||||
|
string newPropertiesFile = getenv("HOME");
|
||||||
|
newPropertiesFile = newPropertiesFile + "/" + \
|
||||||
|
theConsole->properties().get("Cartridge.Name") + ".pro";
|
||||||
|
theConsole->saveProperties(newPropertiesFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else // check all the other keys
|
else // check all the other keys
|
||||||
{
|
{
|
||||||
for(unsigned int i = 0; i < sizeof(list) / sizeof(Switches); ++i)
|
for(unsigned int i = 0; i < sizeof(list) / sizeof(Switches); ++i)
|
||||||
|
@ -1211,11 +1277,13 @@ void takeSnapshot()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now find the correct name for the snapshot
|
// Now find the correct name for the snapshot
|
||||||
string filename = settings->theSnapShotDir;
|
string path = settings->theSnapShotDir;
|
||||||
|
string filename;
|
||||||
|
|
||||||
if(settings->theSnapShotName == "romname")
|
if(settings->theSnapShotName == "romname")
|
||||||
filename = filename + "/" + theConsole->properties().get("Cartridge.Name");
|
path = path + "/" + theConsole->properties().get("Cartridge.Name");
|
||||||
else if(settings->theSnapShotName == "md5sum")
|
else if(settings->theSnapShotName == "md5sum")
|
||||||
filename = filename + "/" + theConsole->properties().get("Cartridge.MD5");
|
path = path + "/" + theConsole->properties().get("Cartridge.MD5");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cerr << "ERROR: unknown name " << settings->theSnapShotName
|
cerr << "ERROR: unknown name " << settings->theSnapShotName
|
||||||
|
@ -1224,32 +1292,29 @@ void takeSnapshot()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace all spaces in name with underscores
|
// Replace all spaces in name with underscores
|
||||||
replace(filename.begin(), filename.end(), ' ', '_');
|
replace(path.begin(), path.end(), ' ', '_');
|
||||||
|
|
||||||
// Check whether we want multiple snapshots created
|
// Check whether we want multiple snapshots created
|
||||||
if(settings->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
|
||||||
string extFilename = filename + ".png";
|
filename = path + ".png";
|
||||||
if(access(extFilename.c_str(), F_OK) == 0 )
|
if(access(filename.c_str(), F_OK) == 0 )
|
||||||
{
|
{
|
||||||
uInt32 i;
|
ostringstream buf;
|
||||||
char buffer[1024];
|
for(uInt32 i = 1; ;++i)
|
||||||
|
|
||||||
for(i = 1; ;++i)
|
|
||||||
{
|
{
|
||||||
snprintf(buffer, 1023, "%s_%d.png", filename.c_str(), i);
|
buf.str("");
|
||||||
if(access(buffer, F_OK) == -1 )
|
buf << path << "_" << i << ".png";
|
||||||
|
if(access(buf.str().c_str(), F_OK) == -1 )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
filename = buffer;
|
filename = buf.str();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
filename = extFilename;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
filename = filename + ".png";
|
filename = path + ".png";
|
||||||
|
|
||||||
// Now save the snapshot file
|
// Now save the snapshot file
|
||||||
snapshot->savePNG(filename, theConsole->mediaSource(), settings->theWindowSize);
|
snapshot->savePNG(filename, theConsole->mediaSource(), settings->theWindowSize);
|
||||||
|
@ -1343,6 +1408,16 @@ void usage()
|
||||||
" -pro <props file> Use the given properties file instead of stella.pro",
|
" -pro <props file> Use the given properties file instead of stella.pro",
|
||||||
" -accurate <0|1> Accurate game timing (uses more CPU)",
|
" -accurate <0|1> Accurate game timing (uses more CPU)",
|
||||||
"",
|
"",
|
||||||
|
#ifdef DEVELOPER_SUPPORT
|
||||||
|
" DEVELOPER options (see Stella manual for details)",
|
||||||
|
" -Dformat Sets \"Display.Format\"",
|
||||||
|
" -Dxstart Sets \"Display.XStart\"",
|
||||||
|
" -Dwidth Sets \"Display.Width\"",
|
||||||
|
" -Dystart Sets \"Display.YStart\"",
|
||||||
|
" -Dheight Sets \"Display.Height\"",
|
||||||
|
" -Dcpu Sets \"Emulation.CPU\"",
|
||||||
|
" -Dhmoveblanks Sets \"Emulation.HmoveBlanks\"",
|
||||||
|
#endif
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1569,9 +1644,15 @@ int main(int argc, char* argv[])
|
||||||
// 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;
|
||||||
|
|
||||||
// Create the 2600 game console
|
// Create the 2600 game console for users or developers
|
||||||
|
#ifdef DEVELOPER_SUPPORT
|
||||||
|
theConsole = new Console(image, size, filename,
|
||||||
|
theEvent, propertiesSet, sound.getSampleRate(),
|
||||||
|
&settings->userDefinedProperties);
|
||||||
|
#else
|
||||||
theConsole = new Console(image, size, filename,
|
theConsole = new Console(image, size, filename,
|
||||||
theEvent, propertiesSet, sound.getSampleRate());
|
theEvent, propertiesSet, sound.getSampleRate());
|
||||||
|
#endif
|
||||||
|
|
||||||
// Let the sound object know about the MediaSource.
|
// Let the sound object know about the MediaSource.
|
||||||
// The sound object takes care of getting samples from the MediaSource.
|
// The sound object takes care of getting samples from the MediaSource.
|
||||||
|
|
|
@ -13,14 +13,15 @@
|
||||||
// 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: mainX11.cxx,v 1.28 2002-10-09 04:38:12 bwmott Exp $
|
// $Id: mainX11.cxx,v 1.29 2002-11-10 19:18:35 stephena Exp $
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <stdio.h>
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
@ -283,11 +284,10 @@ bool setupDisplay()
|
||||||
hints.min_height = hints.max_height = hints.height = height;
|
hints.min_height = hints.max_height = hints.height = height;
|
||||||
|
|
||||||
// Set window and icon name, size hints and other properties
|
// Set window and icon name, size hints and other properties
|
||||||
char name[512];
|
ostringstream name;
|
||||||
sprintf(name, "Stella: \"%s\"",
|
name << "Stella: \"" << theConsole->properties().get("Cartridge.Name") << "\"";
|
||||||
theConsole->properties().get("Cartridge.Name").c_str());
|
XmbSetWMProperties(theDisplay, theWindow, name.str().c_str(), "stella", 0, 0,
|
||||||
XmbSetWMProperties(theDisplay, theWindow, name, "stella", 0, 0, &hints,
|
&hints, None, None);
|
||||||
None, None);
|
|
||||||
|
|
||||||
// Set up the palette for the screen
|
// Set up the palette for the screen
|
||||||
setupPalette();
|
setupPalette();
|
||||||
|
@ -406,6 +406,8 @@ void setupPalette()
|
||||||
|
|
||||||
theGCTable[t] = XCreateGC(theDisplay, theWindow, GCForeground, &values);
|
theGCTable[t] = XCreateGC(theDisplay, theWindow, GCForeground, &values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
theRedrawEntireFrameIndicator = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -626,6 +628,68 @@ void handleEvents()
|
||||||
showCursor(!settings->theHideCursorFlag);
|
showCursor(!settings->theHideCursorFlag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef DEVELOPER_SUPPORT
|
||||||
|
else if((key == XK_f) && (event.type == KeyPress)) // Alt-f switches between NTSC and PAL
|
||||||
|
{
|
||||||
|
if(event.xkey.state & Mod1Mask)
|
||||||
|
{
|
||||||
|
theConsole->toggleFormat();
|
||||||
|
|
||||||
|
// update the palette
|
||||||
|
setupPalette();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if((key == XK_End) && (event.type == KeyPress)) // End decreases XStart
|
||||||
|
{ // Alt-End decreases Width
|
||||||
|
if(event.xkey.state & Mod1Mask)
|
||||||
|
theConsole->changeWidth(0);
|
||||||
|
else
|
||||||
|
theConsole->changeXStart(0);
|
||||||
|
|
||||||
|
// Make sure changes to the properties are reflected onscreen
|
||||||
|
resizeWindow(-1);
|
||||||
|
}
|
||||||
|
else if((key == XK_Home) && (event.type == KeyPress)) // Home increases XStart
|
||||||
|
{ // Alt-Home increases Width
|
||||||
|
if(event.xkey.state & Mod1Mask)
|
||||||
|
theConsole->changeWidth(1);
|
||||||
|
else
|
||||||
|
theConsole->changeXStart(1);
|
||||||
|
|
||||||
|
// Make sure changes to the properties are reflected onscreen
|
||||||
|
resizeWindow(-1);
|
||||||
|
}
|
||||||
|
else if((key == XK_Next) && (event.type == KeyPress)) // PageDown decreases YStart
|
||||||
|
{ // Alt-PageDown decreases Height
|
||||||
|
if(event.xkey.state & Mod1Mask)
|
||||||
|
theConsole->changeHeight(0);
|
||||||
|
else
|
||||||
|
theConsole->changeYStart(0);
|
||||||
|
|
||||||
|
// Make sure changes to the properties are reflected onscreen
|
||||||
|
resizeWindow(-1);
|
||||||
|
}
|
||||||
|
else if((key == XK_Prior) && (event.type == KeyPress)) // PageUp increases YStart
|
||||||
|
{ // Alt-PageUp increases Height
|
||||||
|
if(event.xkey.state & Mod1Mask)
|
||||||
|
theConsole->changeHeight(1);
|
||||||
|
else
|
||||||
|
theConsole->changeYStart(1);
|
||||||
|
|
||||||
|
// Make sure changes to the properties are reflected onscreen
|
||||||
|
resizeWindow(-1);
|
||||||
|
}
|
||||||
|
else if((key == XK_s) && (event.type == KeyPress)) // Alt-s saves properties to a file
|
||||||
|
{
|
||||||
|
if(event.xkey.state & Mod1Mask)
|
||||||
|
{
|
||||||
|
string newPropertiesFile = getenv("HOME");
|
||||||
|
newPropertiesFile = newPropertiesFile + "/" + \
|
||||||
|
theConsole->properties().get("Cartridge.Name") + ".pro";
|
||||||
|
theConsole->saveProperties(newPropertiesFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for(unsigned int i = 0; i < sizeof(list) / sizeof(Switches); ++i)
|
for(unsigned int i = 0; i < sizeof(list) / sizeof(Switches); ++i)
|
||||||
|
@ -836,24 +900,36 @@ void doQuit()
|
||||||
/**
|
/**
|
||||||
This routine is called when the user wants to resize the window.
|
This routine is called when the user wants to resize the window.
|
||||||
A '1' argument indicates that the window should increase in size, while '0'
|
A '1' argument indicates that the window should increase in size, while '0'
|
||||||
indicates that the windows should decrease in size.
|
indicates that the windows should decrease in size. A '-1' indicates that
|
||||||
|
the window should be sized according to the current properties.
|
||||||
Can't resize in fullscreen mode. Will only resize up to the maximum size
|
Can't resize in fullscreen mode. Will only resize up to the maximum size
|
||||||
for the '-zoom' argument.
|
of the screen.
|
||||||
*/
|
*/
|
||||||
void resizeWindow(int mode)
|
void resizeWindow(int mode)
|
||||||
{
|
{
|
||||||
if(isFullscreen)
|
// reset size to that given in properties
|
||||||
return;
|
// this is a special case of allowing a resize while in fullscreen mode
|
||||||
|
if(mode == -1)
|
||||||
if(mode == 1) // increase size
|
|
||||||
{
|
{
|
||||||
|
settings->theWidth = theConsole->mediaSource().width();
|
||||||
|
settings->theHeight = theConsole->mediaSource().height();
|
||||||
|
settings->theMaxWindowSize = maxWindowSizeForScreen();
|
||||||
|
}
|
||||||
|
else if(mode == 1) // increase size
|
||||||
|
{
|
||||||
|
if(isFullscreen)
|
||||||
|
return;
|
||||||
|
|
||||||
if(settings->theWindowSize == settings->theMaxWindowSize)
|
if(settings->theWindowSize == settings->theMaxWindowSize)
|
||||||
settings->theWindowSize = 1;
|
settings->theWindowSize = 1;
|
||||||
else
|
else
|
||||||
settings->theWindowSize++;
|
settings->theWindowSize++;
|
||||||
}
|
}
|
||||||
else // decrease size
|
else if(mode == 0) // decrease size
|
||||||
{
|
{
|
||||||
|
if(isFullscreen)
|
||||||
|
return;
|
||||||
|
|
||||||
if(settings->theWindowSize == 1)
|
if(settings->theWindowSize == 1)
|
||||||
settings->theWindowSize = settings->theMaxWindowSize;
|
settings->theWindowSize = settings->theMaxWindowSize;
|
||||||
else
|
else
|
||||||
|
@ -911,6 +987,7 @@ void centerWindow()
|
||||||
XSetWMNormalHints(theDisplay, theWindow, &hints);
|
XSetWMNormalHints(theDisplay, theWindow, &hints);
|
||||||
|
|
||||||
isCentered = true;
|
isCentered = true;
|
||||||
|
theRedrawEntireFrameIndicator = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -941,7 +1018,6 @@ void togglePause()
|
||||||
|
|
||||||
// Show a different palette depending on pause state
|
// Show a different palette depending on pause state
|
||||||
setupPalette();
|
setupPalette();
|
||||||
theRedrawEntireFrameIndicator = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -949,27 +1025,24 @@ void togglePause()
|
||||||
*/
|
*/
|
||||||
void saveState()
|
void saveState()
|
||||||
{
|
{
|
||||||
char buf[1024];
|
ostringstream buf;
|
||||||
string path = getenv("HOME");
|
|
||||||
path += "/.stella/state";
|
|
||||||
|
|
||||||
// First get the name for the current state file
|
|
||||||
string md5 = theConsole->properties().get("Cartridge.MD5");
|
string md5 = theConsole->properties().get("Cartridge.MD5");
|
||||||
snprintf(buf, 1023, "%s/%s.st%d", path.c_str(), md5.c_str(), currentState);
|
buf << getenv("HOME") << "/.stella/state/" << md5 << ".st" << currentState;
|
||||||
string fileName = buf;
|
string filename = buf.str();
|
||||||
|
|
||||||
// Do a state save using the System
|
// Do a state save using the System
|
||||||
int result = theConsole->system().saveState(fileName, md5);
|
int result = theConsole->system().saveState(filename, md5);
|
||||||
|
|
||||||
// Print appropriate message
|
// Print appropriate message
|
||||||
|
buf.str("");
|
||||||
if(result == 1)
|
if(result == 1)
|
||||||
snprintf(buf, 1023, "State %d saved", currentState);
|
buf << "State " << currentState << " saved";
|
||||||
else if(result == 2)
|
else if(result == 2)
|
||||||
snprintf(buf, 1023, "Error saving state %d", currentState);
|
buf << "Error saving state " << currentState;
|
||||||
else if(result == 3)
|
else if(result == 3)
|
||||||
snprintf(buf, 1023, "Invalid state %d file", currentState);
|
buf << "Invalid state " << currentState << " file";
|
||||||
|
|
||||||
string message = buf;
|
string message = buf.str();
|
||||||
theConsole->mediaSource().showMessage(message, MESSAGE_INTERVAL *
|
theConsole->mediaSource().showMessage(message, MESSAGE_INTERVAL *
|
||||||
settings->theDesiredFrameRate);
|
settings->theDesiredFrameRate);
|
||||||
}
|
}
|
||||||
|
@ -995,9 +1068,9 @@ void changeState(int direction)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print appropriate message
|
// Print appropriate message
|
||||||
char buf[40];
|
ostringstream buf;
|
||||||
snprintf(buf, 39, "Changed to slot %d", currentState);
|
buf << "Changed to slot " << currentState;
|
||||||
string message = buf;
|
string message = buf.str();
|
||||||
theConsole->mediaSource().showMessage(message, MESSAGE_INTERVAL *
|
theConsole->mediaSource().showMessage(message, MESSAGE_INTERVAL *
|
||||||
settings->theDesiredFrameRate);
|
settings->theDesiredFrameRate);
|
||||||
}
|
}
|
||||||
|
@ -1007,27 +1080,24 @@ void changeState(int direction)
|
||||||
*/
|
*/
|
||||||
void loadState()
|
void loadState()
|
||||||
{
|
{
|
||||||
char buf[1024];
|
ostringstream buf;
|
||||||
string path = getenv("HOME");
|
|
||||||
path += "/.stella/state";
|
|
||||||
|
|
||||||
// First get the name for the current state file
|
|
||||||
string md5 = theConsole->properties().get("Cartridge.MD5");
|
string md5 = theConsole->properties().get("Cartridge.MD5");
|
||||||
snprintf(buf, 1023, "%s/%s.st%d", path.c_str(), md5.c_str(), currentState);
|
buf << getenv("HOME") << "/.stella/state/" << md5 << ".st" << currentState;
|
||||||
string fileName = buf;
|
string filename = buf.str();
|
||||||
|
|
||||||
// Do a state load using the System
|
// Do a state load using the System
|
||||||
int result = theConsole->system().loadState(fileName, md5);
|
int result = theConsole->system().loadState(filename, md5);
|
||||||
|
|
||||||
// Print appropriate message
|
// Print appropriate message
|
||||||
|
buf.str("");
|
||||||
if(result == 1)
|
if(result == 1)
|
||||||
snprintf(buf, 1023, "State %d loaded", currentState);
|
buf << "State " << currentState << " loaded";
|
||||||
else if(result == 2)
|
else if(result == 2)
|
||||||
snprintf(buf, 1023, "Error loading state %d", currentState);
|
buf << "Error loading state " << currentState;
|
||||||
else if(result == 3)
|
else if(result == 3)
|
||||||
snprintf(buf, 1023, "Invalid state %d file", currentState);
|
buf << "Invalid state " << currentState << " file";
|
||||||
|
|
||||||
string message = buf;
|
string message = buf.str();
|
||||||
theConsole->mediaSource().showMessage(message, MESSAGE_INTERVAL *
|
theConsole->mediaSource().showMessage(message, MESSAGE_INTERVAL *
|
||||||
settings->theDesiredFrameRate);
|
settings->theDesiredFrameRate);
|
||||||
}
|
}
|
||||||
|
@ -1121,11 +1191,13 @@ void takeSnapshot()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now find the correct name for the snapshot
|
// Now find the correct name for the snapshot
|
||||||
string filename = settings->theSnapShotDir;
|
string path = settings->theSnapShotDir;
|
||||||
|
string filename;
|
||||||
|
|
||||||
if(settings->theSnapShotName == "romname")
|
if(settings->theSnapShotName == "romname")
|
||||||
filename = filename + "/" + theConsole->properties().get("Cartridge.Name");
|
path = path + "/" + theConsole->properties().get("Cartridge.Name");
|
||||||
else if(settings->theSnapShotName == "md5sum")
|
else if(settings->theSnapShotName == "md5sum")
|
||||||
filename = filename + "/" + theConsole->properties().get("Cartridge.MD5");
|
path = path + "/" + theConsole->properties().get("Cartridge.MD5");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cerr << "ERROR: unknown name " << settings->theSnapShotName
|
cerr << "ERROR: unknown name " << settings->theSnapShotName
|
||||||
|
@ -1134,36 +1206,32 @@ void takeSnapshot()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace all spaces in name with underscores
|
// Replace all spaces in name with underscores
|
||||||
replace(filename.begin(), filename.end(), ' ', '_');
|
replace(path.begin(), path.end(), ' ', '_');
|
||||||
|
|
||||||
// Check whether we want multiple snapshots created
|
// Check whether we want multiple snapshots created
|
||||||
if(settings->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
|
||||||
string extFilename = filename + ".png";
|
filename = path + ".png";
|
||||||
if(access(extFilename.c_str(), F_OK) == 0 )
|
if(access(filename.c_str(), F_OK) == 0 )
|
||||||
{
|
{
|
||||||
uInt32 i;
|
ostringstream buf;
|
||||||
char buffer[1024];
|
for(uInt32 i = 1; ;++i)
|
||||||
|
|
||||||
for(i = 1; ;++i)
|
|
||||||
{
|
{
|
||||||
snprintf(buffer, 1023, "%s_%d.png", filename.c_str(), i);
|
buf.str("");
|
||||||
if(access(buffer, F_OK) == -1 )
|
buf << path << "_" << i << ".png";
|
||||||
|
if(access(buf.str().c_str(), F_OK) == -1 )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
filename = buffer;
|
filename = buf.str();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
filename = extFilename;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
filename = filename + ".png";
|
filename = path + ".png";
|
||||||
|
|
||||||
// Now save the snapshot file
|
// Now save the snapshot file
|
||||||
snapshot->savePNG(filename, theConsole->mediaSource(),
|
snapshot->savePNG(filename, theConsole->mediaSource(), settings->theWindowSize);
|
||||||
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;
|
||||||
|
@ -1239,6 +1307,16 @@ void usage()
|
||||||
" -pro <props file> Use the given properties file instead of stella.pro",
|
" -pro <props file> Use the given properties file instead of stella.pro",
|
||||||
" -accurate <0|1> Accurate game timing (uses more CPU)",
|
" -accurate <0|1> Accurate game timing (uses more CPU)",
|
||||||
"",
|
"",
|
||||||
|
#ifdef DEVELOPER_SUPPORT
|
||||||
|
" DEVELOPER options (see Stella manual for details)",
|
||||||
|
" -Dformat Sets \"Display.Format\"",
|
||||||
|
" -Dxstart Sets \"Display.XStart\"",
|
||||||
|
" -Dwidth Sets \"Display.Width\"",
|
||||||
|
" -Dystart Sets \"Display.YStart\"",
|
||||||
|
" -Dheight Sets \"Display.Height\"",
|
||||||
|
" -Dcpu Sets \"Emulation.CPU\"",
|
||||||
|
" -Dhmoveblanks Sets \"Emulation.HmoveBlanks\"",
|
||||||
|
#endif
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1446,9 +1524,15 @@ int main(int argc, char* argv[])
|
||||||
// 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;
|
||||||
|
|
||||||
// Create the 2600 game console
|
// Create the 2600 game console for users or developers
|
||||||
|
#ifdef DEVELOPER_SUPPORT
|
||||||
|
theConsole = new Console(image, size, filename,
|
||||||
|
theEvent, propertiesSet, sound.getSampleRate(),
|
||||||
|
&settings->userDefinedProperties);
|
||||||
|
#else
|
||||||
theConsole = new Console(image, size, filename,
|
theConsole = new Console(image, size, filename,
|
||||||
theEvent, propertiesSet, sound.getSampleRate());
|
theEvent, propertiesSet, sound.getSampleRate());
|
||||||
|
#endif
|
||||||
|
|
||||||
// Free the image since we don't need it any longer
|
// Free the image since we don't need it any longer
|
||||||
delete[] image;
|
delete[] image;
|
||||||
|
|
Loading…
Reference in New Issue