Handle 'read from write port' functionality for CV carts. Still TODO are

the ones that bankswitch in RAM, since I don't know what should happen there.

Added 'exitlauncher' commandline argument, which specifies the functionality
of the 'Exit to launcher' action; should exiting a game actually go back to
the launcher, or exit the program entirely.  Also added a UI item in UIDialog
for this.

Reworked the fullscreen/windowed handling in FrameBuffer, simplifying the
logic for determining whether the SDL surface is actually in fullscreen
or not.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1752 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2009-06-05 14:05:23 +00:00
parent f76af14b25
commit 2bc2ff639c
11 changed files with 87 additions and 44 deletions

View File

@ -337,6 +337,8 @@ bool FrameBufferGL::setVidMode(VideoMode& mode)
cerr << "ERROR: Unable to open SDL window: " << SDL_GetError() << endl;
return false;
}
// Make sure the flags represent the current screen state
mySDLFlags = myScreen->flags;
// Reload OpenGL function pointers. This only seems to be needed for Windows
// Vista, but it shouldn't hurt on other systems.

View File

@ -102,6 +102,9 @@ bool FrameBufferSoft::setVidMode(VideoMode& mode)
myFormat = myScreen->format;
myBytesPerPixel = myFormat->BytesPerPixel;
// Make sure the flags represent the current screen state
mySDLFlags = myScreen->flags;
// Make sure drawTIA() knows which renderer to use
switch(myBytesPerPixel)
{

View File

@ -97,6 +97,7 @@ void Cartridge3E::install(System& system)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 Cartridge3E::peek(uInt16 address)
{
// TODO - determine what really happens when you read from the write port
address &= 0x0FFF;
if(address < 0x0800)

View File

@ -80,13 +80,13 @@ void CartridgeCV::install(System& system)
assert((0x1800 & mask) == 0);
System::PageAccess access;
access.directPokeBase = 0;
access.device = this;
// Map ROM image into the system
for(uInt32 address = 0x1800; address < 0x2000; address += (1 << shift))
{
access.device = this;
access.directPeekBase = &myImage[address & 0x07FF];
access.directPokeBase = 0;
mySystem->setPageAccess(address >> mySystem->pageShift(), access);
}
@ -112,7 +112,18 @@ void CartridgeCV::install(System& system)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 CartridgeCV::peek(uInt16 address)
{
// Reading from the write port triggers an unwanted write
// The value written to RAM is somewhat undefined, so we use 0
// Thanks to Kroko of AtariAge for this advice and code idea
if(address & 0x0FFF < 0x0800) // Write port is at 0xF400 - 0xF800 (1024 bytes)
{ // Read port is handled in ::install()
if(myBankLocked) return 0;
else return myRAM[address & 0x03FF] = 0;
}
else
{
return myImage[address & 0x07FF];
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -109,6 +109,7 @@ uInt8 CartridgeE7::peek(uInt16 address)
// NOTE: The following does not handle reading from RAM, however,
// this function should never be called for RAM because of the
// way page accessing has been setup
// TODO - determine what really happens when you read from the write port
return myImage[(myCurrentSlice[address >> 11] << 11) + (address & 0x07FF)];
}
@ -142,23 +143,23 @@ void CartridgeE7::bankRAM(uInt16 bank)
// Setup the page access methods for the current bank
System::PageAccess access;
access.device = this;
// Set the page accessing method for the 256 bytes of RAM writing pages
access.directPeekBase = 0;
access.directPokeBase = 0;
for(uInt32 j = 0x1800; j < 0x1900; j += (1 << shift))
{
access.device = this;
access.directPeekBase = 0;
access.directPokeBase = &myRAM[1024 + offset + (j & 0x00FF)];
mySystem->setPageAccess(j >> shift, access);
}
// Set the page accessing method for the 256 bytes of RAM reading pages
access.directPeekBase = 0;
access.directPokeBase = 0;
for(uInt32 k = 0x1900; k < 0x1A00; k += (1 << shift))
{
access.device = this;
access.directPeekBase = &myRAM[1024 + offset + (k & 0x00FF)];
access.directPokeBase = 0;
mySystem->setPageAccess(k >> shift, access);
}
}
@ -173,40 +174,37 @@ void CartridgeE7::bank(uInt16 slice)
uInt16 offset = slice << 11;
uInt16 shift = mySystem->pageShift();
System::PageAccess access;
// Setup the page access methods for the current bank
if(slice != 7)
{
System::PageAccess access;
access.device = this;
access.directPokeBase = 0;
// Map ROM image into first segment
for(uInt32 address = 0x1000; address < 0x1800; address += (1 << shift))
{
access.device = this;
access.directPeekBase = &myImage[offset + (address & 0x07FF)];
access.directPokeBase = 0;
mySystem->setPageAccess(address >> shift, access);
}
}
else
{
System::PageAccess access;
access.device = this;
// Set the page accessing method for the 1K slice of RAM writing pages
access.directPeekBase = 0;
access.directPokeBase = 0;
for(uInt32 j = 0x1000; j < 0x1400; j += (1 << shift))
{
access.device = this;
access.directPeekBase = 0;
access.directPokeBase = &myRAM[j & 0x03FF];
mySystem->setPageAccess(j >> shift, access);
}
// Set the page accessing method for the 1K slice of RAM reading pages
access.directPeekBase = 0;
access.directPokeBase = 0;
for(uInt32 k = 0x1400; k < 0x1800; k += (1 << shift))
{
access.device = this;
access.directPeekBase = &myRAM[k & 0x03FF];
access.directPokeBase = 0;
mySystem->setPageAccess(k >> shift, access);
}
}

View File

@ -972,9 +972,16 @@ void EventHandler::handleEvent(Event::Type event, int state)
if((myState == S_EMULATE || myState == S_CMDMENU) && state)
{
myOSystem->settings().saveConfig();
// Go back to the launcher, or immediately quit
if(!myOSystem->settings().getBool("exitlauncher"))
{
myOSystem->deleteConsole();
myOSystem->createLauncher();
}
else
myOSystem->quit();
}
return;
case Event::Quit:

View File

@ -88,6 +88,13 @@ bool FrameBuffer::initialize(const string& title, uInt32 width, uInt32 height)
return false;
#endif
// Initialize SDL flags and set fullscreen flag
// This must be done before any modes are initialized
mySDLFlags = 0;
#ifdef WINDOWED_SUPPORT
if(myOSystem->settings().getBool("fullscreen")) mySDLFlags = SDL_FULLSCREEN;
#endif
// Set the available video modes for this framebuffer
setAvailableVidModes(width, height);
@ -99,13 +106,6 @@ bool FrameBuffer::initialize(const string& title, uInt32 width, uInt32 height)
setWindowTitle(title);
if(myInitializedCount == 1) setWindowIcon();
// Set fullscreen flag
#ifdef WINDOWED_SUPPORT
mySDLFlags = myOSystem->settings().getBool("fullscreen") ? SDL_FULLSCREEN : 0;
#else
mySDLFlags = 0;
#endif
if(!initSubsystem(mode))
{
cerr << "ERROR: Couldn't initialize video subsystem" << endl;
@ -119,6 +119,9 @@ bool FrameBuffer::initialize(const string& title, uInt32 width, uInt32 height)
myScreenRect.setWidth(mode.screen_w);
myScreenRect.setHeight(mode.screen_h);
// Did we get the requested fullscreen state?
myOSystem->settings().setBool("fullscreen", fullScreen());
}
}
else
@ -599,15 +602,13 @@ void FrameBuffer::stateChanged(EventHandler::State state)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::toggleFullscreen()
{
setFullscreen(!myOSystem->settings().getBool("fullscreen"));
setFullscreen(!fullScreen());
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::setFullscreen(bool enable)
{
#ifdef WINDOWED_SUPPORT
// Update the settings
myOSystem->settings().setBool("fullscreen", enable);
if(enable)
mySDLFlags |= SDL_FULLSCREEN;
else
@ -642,7 +643,7 @@ bool FrameBuffer::changeVidMode(int direction)
else if(direction == -1)
myCurrentModeList->previous();
VideoMode vidmode = myCurrentModeList->current(myOSystem->settings());
VideoMode vidmode = myCurrentModeList->current(myOSystem->settings(), fullScreen());
if(setVidMode(vidmode))
{
myImageRect.setWidth(vidmode.image_w);
@ -652,6 +653,9 @@ bool FrameBuffer::changeVidMode(int direction)
myScreenRect.setWidth(vidmode.screen_w);
myScreenRect.setHeight(vidmode.screen_h);
// Did we get the requested fullscreen state?
myOSystem->settings().setBool("fullscreen", fullScreen());
if(!inUIMode)
{
setCursorState();
@ -684,9 +688,7 @@ cerr << "New mode:" << endl
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::setCursorState()
{
bool isFullscreen = myOSystem->settings().getBool("fullscreen");
if(isFullscreen)
if(fullScreen())
grabMouse(true);
else
grabMouse(myOSystem->settings().getBool("grabmouse"));
@ -718,7 +720,7 @@ void FrameBuffer::grabMouse(bool grab)
bool FrameBuffer::fullScreen() const
{
#ifdef WINDOWED_SUPPORT
return myOSystem->settings().getBool("fullscreen");
return mySDLFlags & SDL_FULLSCREEN;
#else
return true;
#endif
@ -930,7 +932,7 @@ FrameBuffer::VideoMode FrameBuffer::getSavedVidMode()
{
EventHandler::State state = myOSystem->eventHandler().state();
if(myOSystem->settings().getBool("fullscreen"))
if(fullScreen())
myCurrentModeList = &myFullscreenModeList;
else
myCurrentModeList = &myWindowedModeList;
@ -948,13 +950,13 @@ FrameBuffer::VideoMode FrameBuffer::getSavedVidMode()
myCurrentModeList->setByGfxMode(name);
}
return myCurrentModeList->current(myOSystem->settings());
return myCurrentModeList->current(myOSystem->settings(), fullScreen());
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FrameBuffer::VideoModeList::VideoModeList()
: myIdx(-1)
{
myIdx = -1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -996,14 +998,13 @@ void FrameBuffer::VideoModeList::previous()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const FrameBuffer::VideoMode FrameBuffer::
VideoModeList::current(const Settings& settings) const
VideoModeList::current(const Settings& settings, bool isFullscreen) const
{
// Fullscreen modes are related to the 'fullres' setting
// If it's 'auto', we just use the mode as already previously defined
// If it's not 'auto', attempt to fit the mode into the resolution
// specified by 'fullres' (if possible)
if(settings.getBool("fullscreen") &&
BSPF_tolower(settings.getString("fullres")) != "auto")
if(isFullscreen && BSPF_tolower(settings.getString("fullres")) != "auto")
{
// Only use 'fullres' if it's *bigger* than the requested mode
int w, h;

View File

@ -417,6 +417,9 @@ class FrameBuffer
SDL_Surface* myScreen;
// SDL initialization flags
// This is set by the base FrameBuffer class, and read by the derived classes
// If a FrameBuffer is successfully created, the derived classes must modify
// it to point to the actual flags used by the SDL_Surface
uInt32 mySDLFlags;
// Indicates if the entire frame need to redrawn
@ -509,7 +512,8 @@ class FrameBuffer
uInt32 size() const;
void previous();
const FrameBuffer::VideoMode current(const Settings& settings) const;
const FrameBuffer::VideoMode current(const Settings& settings,
bool isFullscreen) const;
void next();
void setByGfxMode(GfxID id);

View File

@ -100,6 +100,7 @@ Settings::Settings(OSystem* osystem)
setInternal("launcherres", "640x480");
setInternal("launcherfont", "medium");
setInternal("launcherexts", "allfiles");
setInternal("exitlauncher", "false");
setInternal("romviewer", "0");
setInternal("lastrom", "");
@ -365,6 +366,7 @@ void Settings::usage()
<< " -launcherexts <allfiles| Show files with the given extensions in ROM launcher\n"
<< " allroms| (exts is a ':' separated list of extensions)\n"
<< " exts\n"
<< " -exitlauncher <1|0> Don't go back to ROM launcher after playing a game\n"
<< " -romviewer <0|1|2> Show ROM info viewer at given zoom level in ROM launcher (0 for off)\n"
<< " -uipalette <1|2> Used the specified palette for UI elements\n"
<< " -listdelay <delay> Time to wait between keypresses in list widgets (300-1000)\n"

View File

@ -53,7 +53,7 @@ UIDialog::UIDialog(OSystem* osystem, DialogContainer* parent,
// Set real dimensions
_w = 42 * fontWidth + 10;
_h = 9 * (lineHeight + 4) + 10;
_h = 10 * (lineHeight + 4) + 10;
// The tab widget
xpos = ypos = vBorder;
@ -117,6 +117,12 @@ UIDialog::UIDialog(OSystem* osystem, DialogContainer* parent,
new PopUpWidget(myTab, font, xpos, ypos+1, pwidth, lineHeight, items,
"ROM Info viewer: ", lwidth);
wid.push_back(myRomViewerPopup);
ypos += lineHeight + 4;
// Should exiting a game go back to launcher
myExitLauncherBox = new CheckboxWidget(myTab, font, xpos+20, ypos+10,
"Enter launcher after exiting ROM");
wid.push_back(myExitLauncherBox);
// Add message concerning usage
xpos = vBorder; ypos += 2*(lineHeight + 4);
@ -278,6 +284,9 @@ void UIDialog::loadConfig()
const string& viewer = instance().settings().getString("romviewer");
myRomViewerPopup->setSelected(viewer, "0");
// Exit launcher after a game
myExitLauncherBox->setState(!instance().settings().getBool("exitlauncher"));
// Debugger size
instance().settings().getSize("debuggerres", w, h);
w = BSPF_max(w, 1050);
@ -324,6 +333,9 @@ void UIDialog::saveConfig()
instance().settings().setString("romviewer",
myRomViewerPopup->getSelectedTag());
// Exit launcher after a game
instance().settings().setBool("exitlauncher", !myExitLauncherBox->getState());
// Debugger size
instance().settings().setSize("debuggerres",
myDebuggerWidthSlider->getValue(), myDebuggerHeightSlider->getValue());
@ -358,6 +370,7 @@ void UIDialog::setDefaults()
myLauncherHeightLabel->setValue(h);
myLauncherFontPopup->setSelected("medium", "");
myRomViewerPopup->setSelected("0", "");
myExitLauncherBox->setState(true);
break;
}

View File

@ -50,6 +50,7 @@ class UIDialog : public Dialog
StaticTextWidget* myLauncherHeightLabel;
PopUpWidget* myLauncherFontPopup;
PopUpWidget* myRomViewerPopup;
CheckboxWidget* myExitLauncherBox;
// Debugger options
SliderWidget* myDebuggerWidthSlider;