mirror of https://github.com/stella-emu/stella.git
Too many changes to list here specifically.
The major changes are a stabilization of the core code. There should be much fewer major core changes from now on. Updated the SDL port to the latest core changes. Next I'll start on the Windows port. There are still many optimizations left to do. Specifically, when using the SDL port on a Pentium4 2.4GHz, normal mode results in 4% CPU usage, while menu mode makes it jump to 46%. This must be improved. The porters guide is a work-in-progress, and not yet available. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@199 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
c7233b35b0
commit
d098cb1207
|
@ -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: makefile,v 1.42 2003-10-17 18:02:15 stephena Exp $
|
||||
## $Id: makefile,v 1.43 2003-10-26 19:40:39 stephena Exp $
|
||||
##============================================================================
|
||||
|
||||
##============================================================================
|
||||
|
@ -30,14 +30,14 @@ OPTIMIZATIONS = $(CXXFLAGS) -Wall -Wunused
|
|||
### comment out all lines to completely disable sound
|
||||
###
|
||||
#SOUND_ALSA = 1
|
||||
#SOUND_OSS = 1
|
||||
SOUND_OSS = 1
|
||||
#SOUND_SDL = 1
|
||||
|
||||
### to include OpenGL video support (SDL)
|
||||
#DISPLAY_OPENGL = 1
|
||||
|
||||
### to include joystick support (SDL)
|
||||
# JOYSTICK_SUPPORT = 1
|
||||
JOYSTICK_SUPPORT = 1
|
||||
|
||||
### to include support for saving snapshots in png format
|
||||
### (requires PNG library) FIXME
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: Console.cxx,v 1.18 2003-10-17 18:02:16 stephena Exp $
|
||||
// $Id: Console.cxx,v 1.19 2003-10-26 19:40:39 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -174,7 +174,7 @@ Console::Console(const uInt8* image, uInt32 size, const char* filename,
|
|||
|
||||
// Initialize the framebuffer interface.
|
||||
// This must be done *after* a reset, since it needs updated values.
|
||||
myFrameBuffer.init(this, myMediaSource);
|
||||
myFrameBuffer.initDisplay(this, myMediaSource);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -268,12 +268,12 @@ void Console::toggleFormat()
|
|||
|
||||
if(format == "NTSC")
|
||||
{
|
||||
myFrameBuffer->showMessage("PAL Mode");
|
||||
myFrameBuffer.showMessage("PAL Mode");
|
||||
myProperties.set("Display.Format", "PAL");
|
||||
}
|
||||
else if(format == "PAL")
|
||||
{
|
||||
myFrameBuffer->showMessage("NTSC Mode");
|
||||
myFrameBuffer.showMessage("NTSC Mode");
|
||||
myProperties.set("Display.Format", "NTSC");
|
||||
}
|
||||
}
|
||||
|
@ -291,12 +291,12 @@ void Console::changeXStart(const uInt32 direction)
|
|||
xstart += 4;
|
||||
if(xstart > 80)
|
||||
{
|
||||
myFrameBuffer->showMessage("XStart at maximum");
|
||||
myFrameBuffer.showMessage("XStart at maximum");
|
||||
return;
|
||||
}
|
||||
else if((width + xstart) > 160)
|
||||
{
|
||||
myFrameBuffer->showMessage("XStart no effect");
|
||||
myFrameBuffer.showMessage("XStart no effect");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -305,7 +305,7 @@ void Console::changeXStart(const uInt32 direction)
|
|||
xstart -= 4;
|
||||
if(xstart < 0)
|
||||
{
|
||||
myFrameBuffer->showMessage("XStart at minimum");
|
||||
myFrameBuffer.showMessage("XStart at minimum");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -316,7 +316,7 @@ void Console::changeXStart(const uInt32 direction)
|
|||
|
||||
message = "XStart ";
|
||||
message += strval.str();
|
||||
myFrameBuffer->showMessage(message);
|
||||
myFrameBuffer.showMessage(message);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -331,7 +331,7 @@ void Console::changeYStart(const uInt32 direction)
|
|||
ystart++;
|
||||
if(ystart > 64)
|
||||
{
|
||||
myFrameBuffer->showMessage("YStart at maximum");
|
||||
myFrameBuffer.showMessage("YStart at maximum");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -340,7 +340,7 @@ void Console::changeYStart(const uInt32 direction)
|
|||
ystart--;
|
||||
if(ystart < 0)
|
||||
{
|
||||
myFrameBuffer->showMessage("YStart at minimum");
|
||||
myFrameBuffer.showMessage("YStart at minimum");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -351,7 +351,7 @@ void Console::changeYStart(const uInt32 direction)
|
|||
|
||||
message = "YStart ";
|
||||
message += strval.str();
|
||||
myFrameBuffer->showMessage(message);
|
||||
myFrameBuffer.showMessage(message);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -367,12 +367,12 @@ void Console::changeWidth(const uInt32 direction)
|
|||
width += 4;
|
||||
if((width > 160) || ((width % 4) != 0))
|
||||
{
|
||||
myFrameBuffer->showMessage("Width at maximum");
|
||||
myFrameBuffer.showMessage("Width at maximum");
|
||||
return;
|
||||
}
|
||||
else if((width + xstart) > 160)
|
||||
{
|
||||
myFrameBuffer->showMessage("Width no effect");
|
||||
myFrameBuffer.showMessage("Width no effect");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -381,7 +381,7 @@ void Console::changeWidth(const uInt32 direction)
|
|||
width -= 4;
|
||||
if(width < 80)
|
||||
{
|
||||
myFrameBuffer->showMessage("Width at minimum");
|
||||
myFrameBuffer.showMessage("Width at minimum");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -392,7 +392,7 @@ void Console::changeWidth(const uInt32 direction)
|
|||
|
||||
message = "Width ";
|
||||
message += strval.str();
|
||||
myFrameBuffer->showMessage(message);
|
||||
myFrameBuffer.showMessage(message);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -407,7 +407,7 @@ void Console::changeHeight(const uInt32 direction)
|
|||
height++;
|
||||
if(height > 256)
|
||||
{
|
||||
myFrameBuffer->showMessage("Height at maximum");
|
||||
myFrameBuffer.showMessage("Height at maximum");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -416,7 +416,7 @@ void Console::changeHeight(const uInt32 direction)
|
|||
height--;
|
||||
if(height < 100)
|
||||
{
|
||||
myFrameBuffer->showMessage("Height at minimum");
|
||||
myFrameBuffer.showMessage("Height at minimum");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -427,7 +427,7 @@ void Console::changeHeight(const uInt32 direction)
|
|||
|
||||
message = "Height ";
|
||||
message += strval.str();
|
||||
myFrameBuffer->showMessage(message);
|
||||
myFrameBuffer.showMessage(message);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -437,9 +437,9 @@ void Console::saveProperties(string filename, bool merge)
|
|||
if(merge)
|
||||
{
|
||||
if(myPropSet.merge(myProperties, filename))
|
||||
myFrameBuffer->showMessage("Properties merged");
|
||||
myFrameBuffer.showMessage("Properties merged");
|
||||
else
|
||||
myFrameBuffer->showMessage("Properties not merged");
|
||||
myFrameBuffer.showMessage("Properties not merged");
|
||||
}
|
||||
else // Save to the specified file directly
|
||||
{
|
||||
|
@ -449,11 +449,11 @@ void Console::saveProperties(string filename, bool merge)
|
|||
{
|
||||
myProperties.save(out);
|
||||
out.close();
|
||||
myFrameBuffer->showMessage("Properties saved");
|
||||
myFrameBuffer.showMessage("Properties saved");
|
||||
}
|
||||
else
|
||||
{
|
||||
myFrameBuffer->showMessage("Properties not saved");
|
||||
myFrameBuffer.showMessage("Properties not saved");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.13 2003-10-17 18:02:16 stephena Exp $
|
||||
// $Id: Console.hxx,v 1.14 2003-10-26 19:40:39 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef CONSOLE_HXX
|
||||
|
@ -41,7 +41,7 @@ class FrameBuffer;
|
|||
This class represents the entire game console.
|
||||
|
||||
@author Bradford W. Mott
|
||||
@version $Id: Console.hxx,v 1.13 2003-10-17 18:02:16 stephena Exp $
|
||||
@version $Id: Console.hxx,v 1.14 2003-10-26 19:40:39 stephena Exp $
|
||||
*/
|
||||
class Console
|
||||
{
|
||||
|
@ -55,6 +55,7 @@ class Console
|
|||
@param filename The name of the file that contained the ROM image
|
||||
@param rcsettings The settings object to use
|
||||
@param profiles The game profiles object to use
|
||||
@param framebuffer The framebuffer object to use
|
||||
@param sampleRate The rate to create audio samples at
|
||||
*/
|
||||
Console(const uInt8* image, uInt32 size, const char* filename,
|
||||
|
|
|
@ -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.16 2003-10-17 18:02:16 stephena Exp $
|
||||
// $Id: EventHandler.cxx,v 1.17 2003-10-26 19:40:39 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -37,23 +37,23 @@
|
|||
EventHandler::EventHandler(Console* console)
|
||||
: myConsole(console),
|
||||
myCurrentState(0),
|
||||
myMenuStatus(false)
|
||||
myPauseStatus(false),
|
||||
myMenuStatus(false),
|
||||
myRemapEnabledFlag(true)
|
||||
{
|
||||
Int32 i;
|
||||
|
||||
// Create the event object which will be used for this handler
|
||||
myEvent = new Event();
|
||||
|
||||
// Erase the KeyEvent array
|
||||
for(i = 0; i < StellaEvent::LastKCODE; ++i)
|
||||
for(Int32 i = 0; i < StellaEvent::LastKCODE; ++i)
|
||||
myKeyTable[i] = Event::NoType;
|
||||
|
||||
// Erase the JoyEvent array
|
||||
for(i = 0; i < StellaEvent::LastJSTICK*StellaEvent::LastJCODE; ++i)
|
||||
for(Int32 i = 0; i < StellaEvent::LastJSTICK*StellaEvent::LastJCODE; ++i)
|
||||
myJoyTable[i] = Event::NoType;
|
||||
|
||||
// Erase the Message array
|
||||
for(i = 0; i < Event::LastType; ++i)
|
||||
for(Int32 i = 0; i < Event::LastType; ++i)
|
||||
ourMessageTable[i] = "";
|
||||
|
||||
// Set unchanging messages
|
||||
|
@ -85,7 +85,7 @@ Event* EventHandler::event()
|
|||
void EventHandler::sendKeyEvent(StellaEvent::KeyCode key, Int32 state)
|
||||
{
|
||||
// First check if we are entering menu mode
|
||||
if(key == StellaEvent::KCODE_TAB && state == 1)
|
||||
if(myRemapEnabledFlag && key == StellaEvent::KCODE_TAB && state == 1)
|
||||
{
|
||||
myMenuStatus = !myMenuStatus;
|
||||
myConsole->frameBuffer().showMainMenu(myMenuStatus);
|
||||
|
@ -143,7 +143,9 @@ void EventHandler::sendEvent(Event::Type event, Int32 state)
|
|||
}
|
||||
else if(event == Event::Pause)
|
||||
{
|
||||
myConsole->settings().setPauseEvent();
|
||||
myPauseStatus = !myPauseStatus;
|
||||
myConsole->frameBuffer().pause(myPauseStatus);
|
||||
//FIXME myConsole->sound().pause(myPauseStatus);
|
||||
return;
|
||||
}
|
||||
else if(event == Event::Quit)
|
||||
|
@ -417,7 +419,7 @@ void EventHandler::takeSnapshot()
|
|||
// Now save the snapshot file
|
||||
string filename = myConsole->settings().snapshotFilename();
|
||||
myConsole->snapshot().savePNG(filename, myConsole->frameBuffer(),
|
||||
myConsole->settings().getInt("zoom")); // FIXME - update zoom in resizewindow
|
||||
myConsole->settings().getInt("zoom"));
|
||||
|
||||
myConsole->frameBuffer().showMessage("Snapshot saved");
|
||||
#else
|
||||
|
|
|
@ -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.10 2003-09-30 01:22:45 stephena Exp $
|
||||
// $Id: EventHandler.hxx,v 1.11 2003-10-26 19:40:39 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef EVENTHANDLER_HXX
|
||||
|
@ -41,7 +41,7 @@ class MediaSource;
|
|||
mapping can take place.
|
||||
|
||||
@author Stephen Anthony
|
||||
@version $Id: EventHandler.hxx,v 1.10 2003-09-30 01:22:45 stephena Exp $
|
||||
@version $Id: EventHandler.hxx,v 1.11 2003-10-26 19:40:39 stephena Exp $
|
||||
*/
|
||||
class EventHandler
|
||||
{
|
||||
|
@ -111,6 +111,13 @@ class EventHandler
|
|||
*/
|
||||
string getJoymap();
|
||||
|
||||
/**
|
||||
Enable/disable remapping mode.
|
||||
|
||||
@param status The toggle for enable/disable
|
||||
*/
|
||||
void enableRemapping(bool status) { myRemapEnabledFlag = status; }
|
||||
|
||||
void getKeymapArray(Event::Type** array, uInt32* size);
|
||||
void getJoymapArray(Event::Type** array, uInt32* size);
|
||||
|
||||
|
@ -160,6 +167,9 @@ class EventHandler
|
|||
|
||||
// Indicates that the main menu is being entered
|
||||
bool myMenuStatus;
|
||||
|
||||
// Indicates that remapping mode is enabled
|
||||
bool myRemapEnabledFlag;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: FrameBuffer.cxx,v 1.1 2003-10-17 18:02:16 stephena Exp $
|
||||
// $Id: FrameBuffer.cxx,v 1.2 2003-10-26 19:40:39 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <sstream>
|
||||
|
@ -28,26 +28,32 @@
|
|||
#include "FrameBuffer.hxx"
|
||||
|
||||
// Eventually, these may become variables
|
||||
#define FGCOLOR 10 // A white color in NTSC and PAL mode
|
||||
#define BGCOLOR 0 // A black color in NTSC and PAL mode
|
||||
#define FONTWIDTH 8 // FIXME - TIA framebuffers must be updated for this
|
||||
#define FGCOLOR 10 // A white color in NTSC and PAL mode
|
||||
#define BGCOLOR 0 // A black color in NTSC and PAL mode
|
||||
#define FONTWIDTH 8
|
||||
#define FONTHEIGHT 8
|
||||
|
||||
#define LINEOFFSET 10 // FONTHEIGHT + 1 pixel on top and bottom
|
||||
#define XBOXOFFSET 8 // 4 pixels to the left and right of text
|
||||
#define YBOXOFFSET 8 // 4 pixels to the top and bottom of text
|
||||
#define LINEOFFSET 10 // FONTHEIGHT + 1 pixel on top and bottom
|
||||
#define XBOXOFFSET 8 // 4 pixels to the left and right of text
|
||||
#define YBOXOFFSET 8 // 4 pixels to the top and bottom of text
|
||||
|
||||
#define UPARROW 24 // Indicates more lines above
|
||||
#define DOWNARROW 25 // Indicates more lines below
|
||||
#define LEFTARROW 26 // Left arrow for indicating current line
|
||||
#define RIGHTARROW 27 // Left arrow for indicating current line
|
||||
#define UPARROW 24 // Indicates more lines above
|
||||
#define DOWNARROW 25 // Indicates more lines below
|
||||
#define LEFTARROW 26 // Left arrow for indicating current line
|
||||
#define RIGHTARROW 27 // Left arrow for indicating current line
|
||||
|
||||
#define LEFTMARKER 17 // Indicates item being remapped
|
||||
#define RIGHTMARKER 16 // Indicates item being remapped
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FrameBuffer::FrameBuffer()
|
||||
: myFrameRate(0),
|
||||
: myConsole(0),
|
||||
myMediaSource(0),
|
||||
myWidth(160),
|
||||
myHeight(300),
|
||||
theRedrawEntireFrameIndicator(true),
|
||||
myPauseStatus(false),
|
||||
myFrameRate(0),
|
||||
myCurrentWidget(W_NONE),
|
||||
myRemapEventSelectedFlag(false),
|
||||
mySelectedEvent(Event::NoType),
|
||||
|
@ -61,20 +67,17 @@ FrameBuffer::FrameBuffer()
|
|||
myRemapMenuMaxLines(0),
|
||||
myMessageTime(0),
|
||||
myMessageText(""),
|
||||
myInfoMenuWidth(0),
|
||||
isFullscreen(false) // FIXME
|
||||
myInfoMenuWidth(0)
|
||||
{
|
||||
cerr << "FrameBuffer::FrameBuffer()\n";
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FrameBuffer::~FrameBuffer(void)
|
||||
{
|
||||
cerr << "FrameBuffer::~FrameBuffer()\n";
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBuffer::initBase(Console* console, MediaSource* mediasrc)
|
||||
void FrameBuffer::initDisplay(Console* console, MediaSource* mediasrc)
|
||||
{
|
||||
myConsole = console;
|
||||
myMediaSource = mediasrc;
|
||||
|
@ -99,14 +102,6 @@ void FrameBuffer::initBase(Console* console, MediaSource* mediasrc)
|
|||
if(ourPropertiesInfo[5].length() > myInfoMenuWidth)
|
||||
myInfoMenuWidth = ourPropertiesInfo[5].length();
|
||||
|
||||
// Determine the maximum number of items that can be onscreen vertically
|
||||
myMaxLines = myHeight / LINEOFFSET - 2;
|
||||
|
||||
// Set up the correct bounds for the remap menu
|
||||
myRemapMenuMaxLines = myRemapMenuItems > myMaxLines ? myMaxLines : myRemapMenuItems;
|
||||
myRemapMenuLowIndex = 0;
|
||||
myRemapMenuHighIndex = myRemapMenuMaxLines;
|
||||
|
||||
// Get the arrays containing key and joystick mappings
|
||||
myConsole->eventHandler().getKeymapArray(&myKeyTable, &myKeyTableSize);
|
||||
myConsole->eventHandler().getJoymapArray(&myJoyTable, &myJoyTableSize);
|
||||
|
@ -114,6 +109,74 @@ void FrameBuffer::initBase(Console* console, MediaSource* mediasrc)
|
|||
myFrameRate = myConsole->settings().getInt("framerate");
|
||||
|
||||
loadRemapMenu();
|
||||
|
||||
// Now initialize the derived class
|
||||
init();
|
||||
|
||||
// The following has to be done after the initialization of the derived class
|
||||
// Determine the maximum number of items that can be onscreen vertically
|
||||
myMaxLines = myHeight / LINEOFFSET - 2;
|
||||
// Set up the correct bounds for the remap menu
|
||||
myRemapMenuMaxLines = myRemapMenuItems > myMaxLines ? myMaxLines : myRemapMenuItems;
|
||||
myRemapMenuLowIndex = 0;
|
||||
myRemapMenuHighIndex = myRemapMenuMaxLines;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBuffer::update()
|
||||
{
|
||||
// Do any pre-frame stuff
|
||||
preFrameUpdate();
|
||||
|
||||
// Draw changes to the mediasource
|
||||
if(!myPauseStatus) // FIXME - sound class
|
||||
myMediaSource->update();
|
||||
|
||||
drawMediaSource();
|
||||
|
||||
// Then overlay any menu items
|
||||
switch(myCurrentWidget)
|
||||
{
|
||||
case W_NONE:
|
||||
break;
|
||||
|
||||
case MAIN_MENU:
|
||||
drawMainMenu();
|
||||
break;
|
||||
|
||||
case REMAP_MENU:
|
||||
drawRemapMenu();
|
||||
break;
|
||||
|
||||
case INFO_MENU:
|
||||
drawInfoMenu();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// A message is a special case of interface element
|
||||
// It can overwrite even a menu
|
||||
if(myMessageTime > 0)
|
||||
{
|
||||
uInt32 width = myMessageText.length()*FONTWIDTH + FONTWIDTH;
|
||||
uInt32 height = LINEOFFSET + FONTHEIGHT;
|
||||
uInt32 x = (myWidth >> 1) - (width >> 1);
|
||||
uInt32 y = myHeight - height - LINEOFFSET/2;
|
||||
|
||||
// Draw the bounded box and text
|
||||
drawBoundedBox(x, y, width, height, FGCOLOR, BGCOLOR);
|
||||
drawText(x + XBOXOFFSET/2, LINEOFFSET/2 + y, myMessageText, FGCOLOR);
|
||||
myMessageTime--;
|
||||
|
||||
// Erase this message on next update
|
||||
if(myMessageTime == 0)
|
||||
theRedrawEntireFrameIndicator = true;
|
||||
}
|
||||
|
||||
// Do any post-frame stuff
|
||||
postFrameUpdate();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -122,6 +185,7 @@ void FrameBuffer::showMainMenu(bool show)
|
|||
myCurrentWidget = show ? MAIN_MENU : W_NONE;
|
||||
myRemapEventSelectedFlag = false;
|
||||
mySelectedEvent = Event::NoType;
|
||||
theRedrawEntireFrameIndicator = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -129,6 +193,96 @@ void FrameBuffer::showMessage(const string& message)
|
|||
{
|
||||
myMessageText = message;
|
||||
myMessageTime = myFrameRate << 1;
|
||||
theRedrawEntireFrameIndicator = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
inline void FrameBuffer::drawMainMenu()
|
||||
{
|
||||
uInt32 x, y, width, height, i, xpos, ypos;
|
||||
|
||||
width = 16*FONTWIDTH + (FONTWIDTH << 1);
|
||||
height = myMainMenuItems*LINEOFFSET + 2*FONTHEIGHT;
|
||||
x = (myWidth >> 1) - (width >> 1);
|
||||
y = (myHeight >> 1) - (height >> 1);
|
||||
|
||||
// Draw the bounded box and text, leaving a little room for arrows
|
||||
xpos = x + XBOXOFFSET;
|
||||
drawBoundedBox(x-2, y-2, width+3, height+3, FGCOLOR, BGCOLOR);
|
||||
for(i = 0; i < myMainMenuItems; i++)
|
||||
drawText(xpos, LINEOFFSET*i + y + YBOXOFFSET, ourMainMenu[i].action, FGCOLOR);
|
||||
|
||||
// Now draw the selection arrow around the currently selected item
|
||||
ypos = LINEOFFSET*myMainMenuIndex + y + YBOXOFFSET;
|
||||
drawChar(x, ypos, LEFTARROW, FGCOLOR);
|
||||
drawChar(x + width - FONTWIDTH, ypos, RIGHTARROW, FGCOLOR);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
inline void FrameBuffer::drawRemapMenu()
|
||||
{
|
||||
uInt32 x, y, width, height, i, xpos, ypos;
|
||||
|
||||
width = (myWidth >> 3) * FONTWIDTH - (FONTWIDTH << 1);
|
||||
height = myMaxLines*LINEOFFSET + 2*FONTHEIGHT;
|
||||
x = (myWidth >> 1) - (width >> 1);
|
||||
y = (myHeight >> 1) - (height >> 1);
|
||||
|
||||
// Draw the bounded box and text, leaving a little room for arrows
|
||||
drawBoundedBox(x-2, y-2, width+3, height+3, FGCOLOR, BGCOLOR);
|
||||
for(i = myRemapMenuLowIndex; i < myRemapMenuHighIndex; i++)
|
||||
{
|
||||
ypos = LINEOFFSET*(i-myRemapMenuLowIndex) + y + YBOXOFFSET;
|
||||
drawText(x + XBOXOFFSET, ypos, ourRemapMenu[i].action, FGCOLOR);
|
||||
|
||||
xpos = width - ourRemapMenu[i].key.length() * FONTWIDTH;
|
||||
drawText(xpos, ypos, ourRemapMenu[i].key, FGCOLOR);
|
||||
}
|
||||
|
||||
// Normally draw an arrow indicating the current line,
|
||||
// otherwise highlight the currently selected item for remapping
|
||||
if(!myRemapEventSelectedFlag)
|
||||
{
|
||||
ypos = LINEOFFSET*(myRemapMenuIndex-myRemapMenuLowIndex) + y + YBOXOFFSET;
|
||||
drawChar(x, ypos, LEFTARROW, FGCOLOR);
|
||||
drawChar(x + width - FONTWIDTH, ypos, RIGHTARROW, FGCOLOR);
|
||||
}
|
||||
else
|
||||
{
|
||||
ypos = LINEOFFSET*(myRemapMenuIndex-myRemapMenuLowIndex) + y + YBOXOFFSET;
|
||||
|
||||
// Left marker is at the beginning of event name text
|
||||
xpos = width - ourRemapMenu[myRemapMenuIndex].key.length() * FONTWIDTH - FONTWIDTH;
|
||||
drawChar(xpos, ypos, LEFTMARKER, FGCOLOR);
|
||||
|
||||
// Right marker is at the end of the line
|
||||
drawChar(x + width - FONTWIDTH, ypos, RIGHTMARKER, FGCOLOR);
|
||||
}
|
||||
|
||||
// Finally, indicate that there are more items to the top or bottom
|
||||
xpos = (width >> 1) - FONTWIDTH/2;
|
||||
if(myRemapMenuHighIndex - myMaxLines > 0)
|
||||
drawChar(xpos, y, UPARROW, FGCOLOR);
|
||||
|
||||
if(myRemapMenuLowIndex + myMaxLines < myRemapMenuItems)
|
||||
drawChar(xpos, height - FONTWIDTH/2, DOWNARROW, FGCOLOR);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
inline void FrameBuffer::drawInfoMenu()
|
||||
{
|
||||
uInt32 x, y, width, height, i, xpos;
|
||||
|
||||
width = myInfoMenuWidth*FONTWIDTH + 2*FONTWIDTH;
|
||||
height = 6*LINEOFFSET + 2*FONTHEIGHT;
|
||||
x = (myWidth >> 1) - (width >> 1);
|
||||
y = (myHeight >> 1) - (height >> 1);
|
||||
|
||||
// Draw the bounded box and text
|
||||
xpos = x + XBOXOFFSET;
|
||||
drawBoundedBox(x, y, width, height, FGCOLOR, BGCOLOR);
|
||||
for(i = 0; i < 6; i++)
|
||||
drawText(xpos, LINEOFFSET*i + y + YBOXOFFSET, ourPropertiesInfo[i], FGCOLOR);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -164,7 +318,6 @@ void FrameBuffer::sendKeyEvent(StellaEvent::KeyCode key, Int32 state)
|
|||
{
|
||||
mySelectedEvent = currentSelectedEvent();
|
||||
myRemapEventSelectedFlag = true;
|
||||
cerr << "'" << ourRemapMenu[myRemapMenuIndex].action << "' selected for remapping\n";
|
||||
}
|
||||
else if(key == StellaEvent::KCODE_UP)
|
||||
moveCursorUp();
|
||||
|
@ -175,17 +328,19 @@ cerr << "'" << ourRemapMenu[myRemapMenuIndex].action << "' selected for remappin
|
|||
else if(key == StellaEvent::KCODE_PAGEDOWN)
|
||||
movePageDown();
|
||||
else if(key == StellaEvent::KCODE_ESCAPE)
|
||||
{
|
||||
myCurrentWidget = MAIN_MENU;
|
||||
theRedrawEntireFrameIndicator = true;
|
||||
}
|
||||
|
||||
break; // REMAP_MENU
|
||||
|
||||
case INFO_MENU:
|
||||
if(key == StellaEvent::KCODE_ESCAPE)
|
||||
{
|
||||
myCurrentWidget = MAIN_MENU;
|
||||
|
||||
case FONTS_MENU:
|
||||
if(key == StellaEvent::KCODE_ESCAPE)
|
||||
myCurrentWidget = MAIN_MENU;
|
||||
theRedrawEntireFrameIndicator = true;
|
||||
}
|
||||
|
||||
break; // INFO_MENU
|
||||
|
||||
|
@ -240,6 +395,15 @@ cerr << "stick = " << stick << ", button = " << code << endl;
|
|||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
MediaSource* FrameBuffer::mediaSource() const
|
||||
{
|
||||
if(myMediaSource)
|
||||
return myMediaSource;
|
||||
else
|
||||
return (MediaSource*) NULL;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FrameBuffer::Widget FrameBuffer::currentSelectedWidget()
|
||||
{
|
||||
|
@ -413,7 +577,7 @@ void FrameBuffer::loadRemapMenu()
|
|||
}
|
||||
for(uInt32 j = 0; j < myJoyTableSize; ++j)
|
||||
{
|
||||
if(myJoyTable[j] == event) // FIXME - don't label axis as button
|
||||
if(myJoyTable[j] == event)
|
||||
{
|
||||
ostringstream joyevent;
|
||||
uInt32 stick = j / StellaEvent::LastJCODE;
|
||||
|
@ -498,10 +662,9 @@ const uInt8 FrameBuffer::ourFontData[2048] = {
|
|||
};
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FrameBuffer::MainMenuItem FrameBuffer::ourMainMenu[3] = {
|
||||
FrameBuffer::MainMenuItem FrameBuffer::ourMainMenu[2] = {
|
||||
{ REMAP_MENU, "Key Remapping" },
|
||||
{ INFO_MENU, "Game Information" },
|
||||
{ FONTS_MENU, "Character Set" }
|
||||
{ INFO_MENU, "Game Information" }
|
||||
};
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: FrameBuffer.hxx,v 1.1 2003-10-17 18:02:16 stephena Exp $
|
||||
// $Id: FrameBuffer.hxx,v 1.2 2003-10-26 19:40:39 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef FRAMEBUFFER_HXX
|
||||
|
@ -27,11 +27,15 @@
|
|||
class Console;
|
||||
|
||||
/**
|
||||
This class implements a MAME-like user interface where Stella settings
|
||||
can be changed. It also encapsulates the MediaSource.
|
||||
This class encapsulates the MediaSource and is the basis for the video
|
||||
display in Stella. All ports should derive from this class for
|
||||
platform-specific video stuff.
|
||||
|
||||
This class also implements a MAME-like user interface where Stella settings
|
||||
can be changed.
|
||||
|
||||
@author Stephen Anthony
|
||||
@version $Id: FrameBuffer.hxx,v 1.1 2003-10-17 18:02:16 stephena Exp $
|
||||
@version $Id: FrameBuffer.hxx,v 1.2 2003-10-26 19:40:39 stephena Exp $
|
||||
*/
|
||||
class FrameBuffer
|
||||
{
|
||||
|
@ -44,13 +48,58 @@ class FrameBuffer
|
|||
/**
|
||||
Destructor
|
||||
*/
|
||||
virtual ~FrameBuffer(void);
|
||||
virtual ~FrameBuffer();
|
||||
|
||||
/**
|
||||
Initializes the framebuffer display. This must be called before any
|
||||
calls are made to derived methods.
|
||||
|
||||
@param console The console
|
||||
@param mediasrc The console
|
||||
*/
|
||||
void initDisplay(Console* console, MediaSource* mediasrc);
|
||||
|
||||
/**
|
||||
Updates the display. Also draws any pending menus, etc.
|
||||
*/
|
||||
void update();
|
||||
|
||||
/**
|
||||
Shows the main menu onscreen. This will only be called if event
|
||||
remapping has been enabled in the event handler.
|
||||
|
||||
@param show Show/hide the menu based on the boolean value
|
||||
*/
|
||||
void showMainMenu(bool show);
|
||||
|
||||
/**
|
||||
Shows a message onscreen.
|
||||
|
||||
@param message The message to be shown
|
||||
*/
|
||||
void showMessage(const string& message);
|
||||
|
||||
/**
|
||||
Returns the current width of the framebuffer.
|
||||
Note that this will take into account the current scaling (if any).
|
||||
|
||||
@return The current width
|
||||
*/
|
||||
uInt32 width() { return myWidth; }
|
||||
|
||||
/**
|
||||
Returns the current height of the framebuffer.
|
||||
Note that this will take into account the current scaling (if any).
|
||||
|
||||
@return The current height
|
||||
*/
|
||||
uInt32 height() { return myHeight; }
|
||||
|
||||
/**
|
||||
Send a keyboard event to the user interface.
|
||||
|
||||
@param code The StellaEvent code
|
||||
@param state The StellaEvent state
|
||||
@param code The StellaEvent code
|
||||
@param state The StellaEvent state
|
||||
*/
|
||||
void sendKeyEvent(StellaEvent::KeyCode code, Int32 state);
|
||||
|
||||
|
@ -64,40 +113,104 @@ class FrameBuffer
|
|||
void sendJoyEvent(StellaEvent::JoyStick stick, StellaEvent::JoyCode code,
|
||||
Int32 state);
|
||||
|
||||
void showMainMenu(bool show);
|
||||
void showMessage(const string& message);
|
||||
|
||||
uInt32 width() { return myWidth; }
|
||||
uInt32 height() { return myHeight; }
|
||||
|
||||
uInt16* pixels() const;
|
||||
|
||||
/**
|
||||
Answers if the display is currently in fullscreen mode.
|
||||
Returns the mediasource used in the framebuffer.
|
||||
|
||||
@result The mediasource for this framebuffer
|
||||
*/
|
||||
bool fullScreen() { return isFullscreen; }
|
||||
MediaSource* mediaSource() const;
|
||||
|
||||
public:
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// The following methods are system-specific and must be implemented
|
||||
// in derived classes.
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
This routine should be called once the console is created to setup
|
||||
the video system for us to use. Return false if any operation fails,
|
||||
otherwise return true.
|
||||
*/
|
||||
virtual bool init(Console* console, MediaSource* mediasrc) = 0;
|
||||
virtual bool init() = 0;
|
||||
|
||||
/**
|
||||
This routine should be called anytime the display needs to be updated
|
||||
This routine should be called anytime the MediaSource needs to be redrawn
|
||||
to the screen.
|
||||
*/
|
||||
virtual void update() = 0;
|
||||
virtual void drawMediaSource() = 0;
|
||||
|
||||
/**
|
||||
Toggles between fullscreen and windowed mode.
|
||||
This routine should be called to draw a rectangular box with sides
|
||||
at the specified coordinates.
|
||||
|
||||
@param x The x coordinate
|
||||
@param y The y coordinate
|
||||
@param w The width of the box
|
||||
@param h The height of the box
|
||||
@param fg The color of the bounding sides
|
||||
@param bg The color of the background
|
||||
*/
|
||||
virtual void toggleFullscreen() = 0;
|
||||
virtual void drawBoundedBox(uInt32 x, uInt32 y, uInt32 w, uInt32 h, uInt8 fg, uInt8 bg) = 0;
|
||||
|
||||
/**
|
||||
This routine should be called to draw text at the specified coordinates.
|
||||
|
||||
@param x The x coordinate
|
||||
@param y The y coordinate
|
||||
@param message The message text
|
||||
@param fg The color of the text
|
||||
*/
|
||||
virtual void drawText(uInt32 x, uInt32 y, const string& message, uInt8 fg) = 0;
|
||||
|
||||
/**
|
||||
This routine should be called to draw character 'c' at the specified coordinates.
|
||||
|
||||
@param x The x coordinate
|
||||
@param y The y coordinate
|
||||
@param c The character to draw
|
||||
@param fg The color of the character
|
||||
*/
|
||||
virtual void drawChar(uInt32 x, uInt32 y, uInt32 c, uInt8 fg) = 0;
|
||||
|
||||
/**
|
||||
This routine is called before any drawing is done (per-frame).
|
||||
*/
|
||||
virtual void preFrameUpdate() = 0;
|
||||
|
||||
/**
|
||||
This routine is called after any drawing is done (per-frame).
|
||||
*/
|
||||
virtual void postFrameUpdate() = 0;
|
||||
|
||||
/**
|
||||
This routine is called when the emulation has been paused.
|
||||
|
||||
@param status Toggle pause based on status
|
||||
*/
|
||||
virtual void pause(bool status) = 0;
|
||||
|
||||
protected:
|
||||
// The Console for the system
|
||||
Console* myConsole;
|
||||
|
||||
// The Mediasource for the system
|
||||
MediaSource* myMediaSource;
|
||||
|
||||
// Bounds for the window frame
|
||||
uInt32 myWidth, myHeight;
|
||||
|
||||
// Indicates if the entire frame should be redrawn
|
||||
bool theRedrawEntireFrameIndicator;
|
||||
|
||||
// Indicates the current pause status
|
||||
bool myPauseStatus;
|
||||
|
||||
// Table of bitmapped fonts.
|
||||
static const uInt8 ourFontData[2048];
|
||||
|
||||
private:
|
||||
// Enumeration representing the different types of user interface widgets
|
||||
enum Widget { W_NONE, MAIN_MENU, REMAP_MENU, INFO_MENU, FONTS_MENU };
|
||||
enum Widget { W_NONE, MAIN_MENU, REMAP_MENU, INFO_MENU };
|
||||
|
||||
Widget currentSelectedWidget();
|
||||
Event::Type currentSelectedEvent();
|
||||
|
@ -112,6 +225,15 @@ class FrameBuffer
|
|||
// Remove all bindings for this core event
|
||||
void deleteBinding(Event::Type event);
|
||||
|
||||
// Draw the main menu
|
||||
void drawMainMenu();
|
||||
|
||||
// Draw the remap menu
|
||||
void drawRemapMenu();
|
||||
|
||||
// Draw the info menu
|
||||
void drawInfoMenu();
|
||||
|
||||
// Move the cursor up 1 line, possibly scrolling the list of items
|
||||
void moveCursorUp();
|
||||
|
||||
|
@ -127,15 +249,7 @@ class FrameBuffer
|
|||
// scan the mapping arrays and update the remap menu
|
||||
void loadRemapMenu();
|
||||
|
||||
void initBase(Console* console, MediaSource* mediasrc);
|
||||
|
||||
protected:
|
||||
// The Console for the system
|
||||
Console* myConsole;
|
||||
|
||||
// The Mediasource for the system
|
||||
MediaSource* myMediaSource;
|
||||
|
||||
private:
|
||||
// Indicates the current framerate of the system
|
||||
uInt32 myFrameRate;
|
||||
|
||||
|
@ -154,12 +268,6 @@ class FrameBuffer
|
|||
string key;
|
||||
};
|
||||
|
||||
// Bounds for the window frame
|
||||
uInt32 myXStart, myYStart, myWidth, myHeight;
|
||||
|
||||
// Table of bitmapped fonts.
|
||||
static const uInt8 ourFontData[2048];
|
||||
|
||||
// Table of strings representing the various StellaEvent codes
|
||||
static const char* ourEventName[StellaEvent::LastKCODE];
|
||||
|
||||
|
@ -195,7 +303,7 @@ class FrameBuffer
|
|||
string ourPropertiesInfo[6];
|
||||
|
||||
// Holds static strings for the main menu
|
||||
static MainMenuItem ourMainMenu[3];
|
||||
static MainMenuItem ourMainMenu[2];
|
||||
|
||||
// Holds static strings for the remap menu
|
||||
static RemapMenuItem ourRemapMenu[57];
|
||||
|
@ -211,9 +319,6 @@ class FrameBuffer
|
|||
|
||||
// Holds the number of items in the joytable array
|
||||
uInt32 myJoyTableSize;
|
||||
|
||||
// Indicates whether the emulator is currently in fullscreen mode
|
||||
bool isFullscreen; // FIXME - remove from here, its specific
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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: MediaSrc.hxx,v 1.5 2003-09-26 22:39:36 stephena Exp $
|
||||
// $Id: MediaSrc.hxx,v 1.6 2003-10-26 19:40:39 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef MEDIASOURCE_HXX
|
||||
|
@ -29,7 +29,7 @@ class MediaSource;
|
|||
This class provides an interface for accessing graphics and audio data.
|
||||
|
||||
@author Bradford W. Mott
|
||||
@version $Id: MediaSrc.hxx,v 1.5 2003-09-26 22:39:36 stephena Exp $
|
||||
@version $Id: MediaSrc.hxx,v 1.6 2003-10-26 19:40:39 stephena Exp $
|
||||
*/
|
||||
class MediaSource
|
||||
{
|
||||
|
@ -53,16 +53,6 @@ class MediaSource
|
|||
*/
|
||||
virtual void update() = 0;
|
||||
|
||||
/**
|
||||
This method should be called to change the pause state of the
|
||||
media source. Once the media source is paused further calls to
|
||||
the update method will be ignored until the media source is
|
||||
unpaused.
|
||||
|
||||
@return Status of the pause, success (true) or failure (false)
|
||||
*/
|
||||
virtual bool pause(bool state) = 0;
|
||||
|
||||
/**
|
||||
Answers the current frame buffer
|
||||
|
||||
|
|
|
@ -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: Settings.hxx,v 1.7 2003-09-23 17:27:11 stephena Exp $
|
||||
// $Id: Settings.hxx,v 1.8 2003-10-26 19:40:39 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef SETTINGS_HXX
|
||||
|
@ -32,7 +32,7 @@ class Console;
|
|||
This class provides an interface for accessing frontend specific settings.
|
||||
|
||||
@author Stephen Anthony
|
||||
@version $Id: Settings.hxx,v 1.7 2003-09-23 17:27:11 stephena Exp $
|
||||
@version $Id: Settings.hxx,v 1.8 2003-10-26 19:40:39 stephena Exp $
|
||||
*/
|
||||
class Settings
|
||||
{
|
||||
|
@ -151,7 +151,7 @@ class Settings
|
|||
This method should be called at when the emulation core receives
|
||||
a PAUSE event.
|
||||
*/
|
||||
void setPauseEvent() { myPauseIndicator = !myPauseIndicator; }
|
||||
void setPauseEvent(bool status) { myPauseIndicator = status; }
|
||||
|
||||
/**
|
||||
This method determines whether the PAUSE event has been received.
|
||||
|
|
|
@ -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: TIA.cxx,v 1.24 2003-10-17 18:02:16 stephena Exp $
|
||||
// $Id: TIA.cxx,v 1.25 2003-10-26 19:40:39 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <cassert>
|
||||
|
@ -35,7 +35,6 @@
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
TIA::TIA(const Console& console, uInt32 sampleRate)
|
||||
: myConsole(console),
|
||||
myPauseState(false),
|
||||
myLastSoundUpdateCycle(0),
|
||||
myColorLossEnabled(false),
|
||||
myCOLUBK(myColor[0]),
|
||||
|
@ -510,12 +509,6 @@ bool TIA::load(Deserializer& in)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void TIA::update()
|
||||
{
|
||||
// Don't do an update if the emulator is paused
|
||||
if(myPauseState)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uInt8* tmp = myCurrentFrameBuffer;
|
||||
myCurrentFrameBuffer = myPreviousFrameBuffer;
|
||||
myPreviousFrameBuffer = tmp;
|
||||
|
@ -572,21 +565,6 @@ void TIA::update()
|
|||
myScanlineCountForLastFrame = totalClocks / 228;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool TIA::pause(bool state)
|
||||
{
|
||||
if(myPauseState == state)
|
||||
{
|
||||
// Ignore multiple calls to do the same thing
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
myPauseState = state;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const uInt32* TIA::palette() const
|
||||
{
|
||||
|
@ -3217,4 +3195,3 @@ uInt32 TIA::SampleQueue::size() const
|
|||
{
|
||||
return mySize;
|
||||
}
|
||||
|
||||
|
|
|
@ -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: TIA.hxx,v 1.9 2003-09-28 21:59:24 stephena Exp $
|
||||
// $Id: TIA.hxx,v 1.10 2003-10-26 19:40:39 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef TIA_HXX
|
||||
|
@ -43,7 +43,7 @@ class Deserializer;
|
|||
in a bounded queue.
|
||||
|
||||
@author Bradford W. Mott
|
||||
@version $Id: TIA.hxx,v 1.9 2003-09-28 21:59:24 stephena Exp $
|
||||
@version $Id: TIA.hxx,v 1.10 2003-10-26 19:40:39 stephena Exp $
|
||||
*/
|
||||
class TIA : public Device , public MediaSource
|
||||
{
|
||||
|
@ -128,15 +128,6 @@ class TIA : public Device , public MediaSource
|
|||
*/
|
||||
virtual void update();
|
||||
|
||||
/**
|
||||
This method should be called to cause further calls to 'update'
|
||||
to be ignored until an unpause is given. Will also send a mute to
|
||||
the Sound device.
|
||||
|
||||
@return Status of the pause, success (true) or failure (false)
|
||||
*/
|
||||
virtual bool pause(bool state);
|
||||
|
||||
/**
|
||||
Answers the current frame buffer
|
||||
|
||||
|
@ -307,9 +298,6 @@ class TIA : public Device , public MediaSource
|
|||
// Console the TIA is associated with
|
||||
const Console& myConsole;
|
||||
|
||||
// Indicates whether the emulation is paused or not
|
||||
bool myPauseState;
|
||||
|
||||
private:
|
||||
// Indicates the CPU cycle when a TIA sound register was last updated
|
||||
Int32 myLastSoundUpdateCycle;
|
||||
|
|
|
@ -0,0 +1,611 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-1999 by Bradford W. Mott
|
||||
//
|
||||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: FrameBufferSDL.cxx,v 1.1 2003-10-26 19:40:39 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL_syswm.h>
|
||||
#include <sstream>
|
||||
|
||||
#include "Console.hxx"
|
||||
#include "FrameBuffer.hxx"
|
||||
#include "FrameBufferSDL.hxx"
|
||||
#include "MediaSrc.hxx"
|
||||
#include "RectList.hxx"
|
||||
#include "Settings.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FrameBufferSDL::FrameBufferSDL()
|
||||
: x11Available(false),
|
||||
theZoomLevel(1),
|
||||
theMaxZoomLevel(1),
|
||||
isCentered(false),
|
||||
theGrabMouseIndicator(false),
|
||||
theHideCursorIndicator(false),
|
||||
isFullscreen(false)
|
||||
{
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FrameBufferSDL::~FrameBufferSDL()
|
||||
{
|
||||
if(myRectList)
|
||||
delete myRectList;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FrameBufferSDL::init()
|
||||
{
|
||||
// Get the desired width and height of the display
|
||||
myWidth = myMediaSource->width() << 1;
|
||||
myHeight = myMediaSource->height();
|
||||
|
||||
// Now create the software SDL screen
|
||||
Uint32 initflags = SDL_INIT_VIDEO | SDL_INIT_TIMER;
|
||||
if(SDL_Init(initflags) < 0)
|
||||
return false;
|
||||
|
||||
// Check which system we are running under
|
||||
x11Available = false;
|
||||
SDL_VERSION(&myWMInfo.version);
|
||||
if(SDL_GetWMInfo(&myWMInfo) > 0)
|
||||
if(myWMInfo.subsystem == SDL_SYSWM_X11)
|
||||
x11Available = true;
|
||||
|
||||
// Get the maximum size of a window for THIS screen
|
||||
theMaxZoomLevel = maxWindowSizeForScreen();
|
||||
|
||||
// Check to see if window size will fit in the screen
|
||||
if((uInt32)myConsole->settings().getInt("zoom") > theMaxZoomLevel)
|
||||
theZoomLevel = theMaxZoomLevel;
|
||||
else
|
||||
theZoomLevel = myConsole->settings().getInt("zoom");
|
||||
|
||||
mySDLFlags = SDL_SWSURFACE;
|
||||
mySDLFlags |= myConsole->settings().getBool("fullscreen") ? SDL_FULLSCREEN : 0;
|
||||
|
||||
// Set up the rectangle list to be used in the dirty update
|
||||
myRectList = new RectList();
|
||||
if(!myRectList)
|
||||
{
|
||||
cerr << "ERROR: Unable to get memory for SDL rects" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set the window title and icon
|
||||
ostringstream name;
|
||||
name << "Stella: \"" << myConsole->properties().get("Cartridge.Name") << "\"";
|
||||
SDL_WM_SetCaption(name.str().c_str(), "stella");
|
||||
|
||||
// Create the screen
|
||||
if(!createScreen())
|
||||
return false;
|
||||
setupPalette(1.0);
|
||||
|
||||
// Make sure that theUseFullScreenFlag sets up fullscreen mode correctly
|
||||
theGrabMouseIndicator = myConsole->settings().getBool("grabmouse");
|
||||
theHideCursorIndicator = myConsole->settings().getBool("hidecursor");
|
||||
if(myConsole->settings().getBool("fullscreen"))
|
||||
{
|
||||
grabMouse(true);
|
||||
showCursor(false);
|
||||
isFullscreen = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Keep mouse in game window if grabmouse is selected
|
||||
grabMouse(theGrabMouseIndicator);
|
||||
|
||||
// Show or hide the cursor depending on the 'hidecursor' argument
|
||||
showCursor(!theHideCursorIndicator);
|
||||
}
|
||||
|
||||
// Center the window if centering is selected and not fullscreen
|
||||
if(myConsole->settings().getBool("center") &&
|
||||
!myConsole->settings().getBool("fullscreen"))
|
||||
centerScreen();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSDL::drawMediaSource()
|
||||
{
|
||||
uInt8* currentFrame = myMediaSource->currentFrameBuffer();
|
||||
uInt8* previousFrame = myMediaSource->previousFrameBuffer();
|
||||
uInt16 screenMultiple = (uInt16) theZoomLevel;
|
||||
|
||||
uInt32 width = myMediaSource->width();
|
||||
uInt32 height = myMediaSource->height();
|
||||
|
||||
struct Rectangle
|
||||
{
|
||||
uInt8 color;
|
||||
uInt16 x, y, width, height;
|
||||
} rectangles[2][160];
|
||||
|
||||
// This array represents the rectangles that need displaying
|
||||
// on the current scanline we're processing
|
||||
Rectangle* currentRectangles = rectangles[0];
|
||||
|
||||
// This array represents the rectangles that are still active
|
||||
// from the previous scanlines we have processed
|
||||
Rectangle* activeRectangles = rectangles[1];
|
||||
|
||||
// Indicates the number of active rectangles
|
||||
uInt16 activeCount = 0;
|
||||
|
||||
// This update procedure requires theWidth to be a multiple of four.
|
||||
// This is validated when the properties are loaded.
|
||||
for(uInt16 y = 0; y < height; ++y)
|
||||
{
|
||||
// Indicates the number of current rectangles
|
||||
uInt16 currentCount = 0;
|
||||
|
||||
// Look at four pixels at a time to see if anything has changed
|
||||
uInt32* current = (uInt32*)(currentFrame);
|
||||
uInt32* previous = (uInt32*)(previousFrame);
|
||||
|
||||
for(uInt16 x = 0; x < width; x += 4, ++current, ++previous)
|
||||
{
|
||||
// Has something changed in this set of four pixels?
|
||||
if((*current != *previous) || theRedrawEntireFrameIndicator)
|
||||
{
|
||||
uInt8* c = (uInt8*)current;
|
||||
uInt8* p = (uInt8*)previous;
|
||||
|
||||
// Look at each of the bytes that make up the uInt32
|
||||
for(uInt16 i = 0; i < 4; ++i, ++c, ++p)
|
||||
{
|
||||
// See if this pixel has changed
|
||||
if((*c != *p) || theRedrawEntireFrameIndicator)
|
||||
{
|
||||
// Can we extend a rectangle or do we have to create a new one?
|
||||
if((currentCount != 0) &&
|
||||
(currentRectangles[currentCount - 1].color == *c) &&
|
||||
((currentRectangles[currentCount - 1].x +
|
||||
currentRectangles[currentCount - 1].width) == (x + i)))
|
||||
{
|
||||
currentRectangles[currentCount - 1].width += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentRectangles[currentCount].x = x + i;
|
||||
currentRectangles[currentCount].y = y;
|
||||
currentRectangles[currentCount].width = 1;
|
||||
currentRectangles[currentCount].height = 1;
|
||||
currentRectangles[currentCount].color = *c;
|
||||
currentCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Merge the active and current rectangles flushing any that are of no use
|
||||
uInt16 activeIndex = 0;
|
||||
|
||||
for(uInt16 t = 0; (t < currentCount) && (activeIndex < activeCount); ++t)
|
||||
{
|
||||
Rectangle& current = currentRectangles[t];
|
||||
Rectangle& active = activeRectangles[activeIndex];
|
||||
|
||||
// Can we merge the current rectangle with an active one?
|
||||
if((current.x == active.x) && (current.width == active.width) &&
|
||||
(current.color == active.color))
|
||||
{
|
||||
current.y = active.y;
|
||||
current.height = active.height + 1;
|
||||
|
||||
++activeIndex;
|
||||
}
|
||||
// Is it impossible for this active rectangle to be merged?
|
||||
else if(current.x >= active.x)
|
||||
{
|
||||
// Flush the active rectangle
|
||||
SDL_Rect temp;
|
||||
|
||||
temp.x = active.x * screenMultiple << 1;
|
||||
temp.y = active.y * screenMultiple;
|
||||
temp.w = active.width * screenMultiple << 1;
|
||||
temp.h = active.height * screenMultiple;
|
||||
|
||||
myRectList->add(&temp);
|
||||
SDL_FillRect(myScreen, &temp, palette[active.color]);
|
||||
|
||||
++activeIndex;
|
||||
}
|
||||
}
|
||||
|
||||
// Flush any remaining active rectangles
|
||||
for(uInt16 s = activeIndex; s < activeCount; ++s)
|
||||
{
|
||||
Rectangle& active = activeRectangles[s];
|
||||
|
||||
SDL_Rect temp;
|
||||
temp.x = active.x * screenMultiple << 1;
|
||||
temp.y = active.y * screenMultiple;
|
||||
temp.w = active.width * screenMultiple << 1;
|
||||
temp.h = active.height * screenMultiple;
|
||||
|
||||
myRectList->add(&temp);
|
||||
SDL_FillRect(myScreen, &temp, palette[active.color]);
|
||||
}
|
||||
|
||||
// We can now make the current rectangles into the active rectangles
|
||||
Rectangle* tmp = currentRectangles;
|
||||
currentRectangles = activeRectangles;
|
||||
activeRectangles = tmp;
|
||||
activeCount = currentCount;
|
||||
|
||||
currentFrame += width;
|
||||
previousFrame += width;
|
||||
}
|
||||
|
||||
// Flush any rectangles that are still active
|
||||
for(uInt16 t = 0; t < activeCount; ++t)
|
||||
{
|
||||
Rectangle& active = activeRectangles[t];
|
||||
|
||||
SDL_Rect temp;
|
||||
temp.x = active.x * screenMultiple << 1;
|
||||
temp.y = active.y * screenMultiple;
|
||||
temp.w = active.width * screenMultiple << 1;
|
||||
temp.h = active.height * screenMultiple;
|
||||
|
||||
myRectList->add(&temp);
|
||||
SDL_FillRect(myScreen, &temp, palette[active.color]);
|
||||
}
|
||||
|
||||
// The frame doesn't need to be completely redrawn anymore
|
||||
theRedrawEntireFrameIndicator = false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSDL::preFrameUpdate()
|
||||
{
|
||||
// Start a new rectlist on each display update
|
||||
myRectList->start();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSDL::postFrameUpdate()
|
||||
{
|
||||
// Now update all the rectangles at once
|
||||
SDL_UpdateRects(myScreen, myRectList->numRects(), myRectList->rects());
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FrameBufferSDL::createScreen()
|
||||
{
|
||||
int w = myWidth * theZoomLevel;
|
||||
int h = myHeight * theZoomLevel;
|
||||
|
||||
myScreen = SDL_SetVideoMode(w, h, 0, mySDLFlags);
|
||||
if(myScreen == NULL)
|
||||
{
|
||||
cerr << "ERROR: Unable to open SDL window: " << SDL_GetError() << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
theRedrawEntireFrameIndicator = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSDL::setupPalette(float shade)
|
||||
{
|
||||
const uInt32* gamePalette = myMediaSource->palette();
|
||||
for(uInt32 i = 0; i < 256; ++i)
|
||||
{
|
||||
Uint8 r, g, b;
|
||||
|
||||
r = (Uint8) (((gamePalette[i] & 0x00ff0000) >> 16) * shade);
|
||||
g = (Uint8) (((gamePalette[i] & 0x0000ff00) >> 8) * shade);
|
||||
b = (Uint8) ((gamePalette[i] & 0x000000ff) * shade);
|
||||
|
||||
switch(myScreen->format->BitsPerPixel)
|
||||
{
|
||||
case 15:
|
||||
palette[i] = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);
|
||||
break;
|
||||
|
||||
case 16:
|
||||
palette[i] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
|
||||
break;
|
||||
|
||||
case 24:
|
||||
case 32:
|
||||
palette[i] = (r << 16) | (g << 8) | b;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
theRedrawEntireFrameIndicator = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSDL::pause(bool status)
|
||||
{
|
||||
myPauseStatus = status;
|
||||
|
||||
// Shade the palette to 75% normal value in pause mode
|
||||
if(myPauseStatus)
|
||||
setupPalette(0.75);
|
||||
else
|
||||
setupPalette(1.0);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSDL::toggleFullscreen()
|
||||
{
|
||||
isFullscreen = !isFullscreen;
|
||||
if(isFullscreen)
|
||||
mySDLFlags |= SDL_FULLSCREEN;
|
||||
else
|
||||
mySDLFlags &= ~SDL_FULLSCREEN;
|
||||
|
||||
if(!createScreen())
|
||||
return;
|
||||
|
||||
if(isFullscreen) // now in fullscreen mode
|
||||
{
|
||||
grabMouse(true);
|
||||
showCursor(false);
|
||||
}
|
||||
else // now in windowed mode
|
||||
{
|
||||
grabMouse(theGrabMouseIndicator);
|
||||
showCursor(!theHideCursorIndicator);
|
||||
|
||||
if(myConsole->settings().getBool("center"))
|
||||
centerScreen();
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSDL::resize(int mode)
|
||||
{
|
||||
// reset size to that given in properties
|
||||
// this is a special case of allowing a resize while in fullscreen mode
|
||||
if(mode == 0)
|
||||
{
|
||||
myWidth = myMediaSource->width() << 1;
|
||||
myHeight = myMediaSource->height();
|
||||
}
|
||||
else if(mode == 1) // increase size
|
||||
{
|
||||
if(isFullscreen)
|
||||
return;
|
||||
|
||||
if(theZoomLevel == theMaxZoomLevel)
|
||||
theZoomLevel = 1;
|
||||
else
|
||||
theZoomLevel++;
|
||||
}
|
||||
else if(mode == -1) // decrease size
|
||||
{
|
||||
if(isFullscreen)
|
||||
return;
|
||||
|
||||
if(theZoomLevel == 1)
|
||||
theZoomLevel = theMaxZoomLevel;
|
||||
else
|
||||
theZoomLevel--;
|
||||
}
|
||||
|
||||
if(!createScreen())
|
||||
return;
|
||||
|
||||
// A resize may mean that the window is no longer centered
|
||||
isCentered = false;
|
||||
|
||||
if(myConsole->settings().getBool("center"))
|
||||
centerScreen();
|
||||
|
||||
// Now update the settings
|
||||
ostringstream tmp;
|
||||
tmp << theZoomLevel;
|
||||
myConsole->settings().set("zoom", tmp.str());
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSDL::showCursor(bool show)
|
||||
{
|
||||
if(isFullscreen)
|
||||
return;
|
||||
|
||||
if(show)
|
||||
SDL_ShowCursor(SDL_ENABLE);
|
||||
else
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSDL::grabMouse(bool grab)
|
||||
{
|
||||
if(isFullscreen)
|
||||
return;
|
||||
|
||||
if(grab)
|
||||
SDL_WM_GrabInput(SDL_GRAB_ON);
|
||||
else
|
||||
SDL_WM_GrabInput(SDL_GRAB_OFF);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSDL::centerScreen()
|
||||
{
|
||||
if(!x11Available)
|
||||
{
|
||||
cerr << "Window centering only available under X11.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
if(isFullscreen || isCentered)
|
||||
return;
|
||||
|
||||
uInt32 x, y, w, h;
|
||||
myWMInfo.info.x11.lock_func();
|
||||
Display* theX11Display = myWMInfo.info.x11.display;
|
||||
Window theX11Window = myWMInfo.info.x11.wmwindow;
|
||||
|
||||
w = DisplayWidth(theX11Display, DefaultScreen(theX11Display));
|
||||
h = DisplayHeight(theX11Display, DefaultScreen(theX11Display));
|
||||
x = (w - myScreen->w)/2;
|
||||
y = (h - myScreen->h)/2;
|
||||
|
||||
XMoveWindow(theX11Display, theX11Window, x, y);
|
||||
myWMInfo.info.x11.unlock_func();
|
||||
|
||||
isCentered = true;
|
||||
theRedrawEntireFrameIndicator = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 FrameBufferSDL::maxWindowSizeForScreen()
|
||||
{
|
||||
if(!x11Available)
|
||||
return 1;
|
||||
|
||||
// Otherwise, lock the screen and get the width and height
|
||||
myWMInfo.info.x11.lock_func();
|
||||
Display* theX11Display = myWMInfo.info.x11.display;
|
||||
myWMInfo.info.x11.unlock_func();
|
||||
|
||||
int screenWidth = DisplayWidth(theX11Display, DefaultScreen(theX11Display));
|
||||
int screenHeight = DisplayHeight(theX11Display, DefaultScreen(theX11Display));
|
||||
|
||||
uInt32 multiplier = screenWidth / myWidth;
|
||||
bool found = false;
|
||||
|
||||
while(!found && (multiplier > 0))
|
||||
{
|
||||
// Figure out the desired size of the window
|
||||
int width = myWidth * multiplier;
|
||||
int height = myHeight * multiplier;
|
||||
|
||||
if((width < screenWidth) && (height < screenHeight))
|
||||
found = true;
|
||||
else
|
||||
multiplier--;
|
||||
}
|
||||
|
||||
if(found)
|
||||
return multiplier;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSDL::drawBoundedBox(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
|
||||
uInt8 fg, uInt8 bg)
|
||||
{
|
||||
SDL_Rect tmp;
|
||||
|
||||
// Scale all values to the current window size
|
||||
x *= theZoomLevel;
|
||||
y *= theZoomLevel;
|
||||
w *= theZoomLevel;
|
||||
h *= theZoomLevel;
|
||||
|
||||
// First draw the underlying box
|
||||
tmp.x = x;
|
||||
tmp.y = y;
|
||||
tmp.w = w;
|
||||
tmp.h = h;
|
||||
myRectList->add(&tmp);
|
||||
SDL_FillRect(myScreen, &tmp, palette[bg]);
|
||||
|
||||
// Now draw the bounding sides
|
||||
tmp.x = x;
|
||||
tmp.y = y;
|
||||
tmp.w = w;
|
||||
tmp.h = theZoomLevel;
|
||||
SDL_FillRect(myScreen, &tmp, palette[fg]); // top
|
||||
|
||||
tmp.x = x;
|
||||
tmp.y = y + h - theZoomLevel;
|
||||
tmp.w = w;
|
||||
tmp.h = theZoomLevel;
|
||||
SDL_FillRect(myScreen, &tmp, palette[fg]); // bottom
|
||||
|
||||
tmp.x = x;
|
||||
tmp.y = y;
|
||||
tmp.w = theZoomLevel;
|
||||
tmp.h = h;
|
||||
SDL_FillRect(myScreen, &tmp, palette[fg]); // left
|
||||
|
||||
tmp.x = x + w - theZoomLevel;
|
||||
tmp.y = y;
|
||||
tmp.w = theZoomLevel;
|
||||
tmp.h = h;
|
||||
SDL_FillRect(myScreen, &tmp, palette[fg]); // right
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSDL::drawText(uInt32 xorig, uInt32 yorig,
|
||||
const string& message, uInt8 fg)
|
||||
{
|
||||
SDL_Rect tmp;
|
||||
|
||||
uInt8 length = message.length();
|
||||
for(uInt32 x = 0; x < length; x++)
|
||||
{
|
||||
for(uInt32 y = 0; y < 8; y++)
|
||||
{
|
||||
for(uInt32 z = 0; z < 8; z++)
|
||||
{
|
||||
char letter = message[x];
|
||||
if((ourFontData[(letter << 3) + y] >> z) & 1)
|
||||
{
|
||||
// myFrameBuffer[(y + yorig)*myWidth + (x<<3) + z + xorig] = 0xF0F0F0;
|
||||
tmp.x = ((x<<3) + z + xorig) * theZoomLevel;
|
||||
tmp.y = (y + yorig) * theZoomLevel;
|
||||
tmp.w = tmp.h = theZoomLevel;
|
||||
SDL_FillRect(myScreen, &tmp, palette[fg]);
|
||||
// FIXME - this can be a lot more efficient
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSDL::drawChar(uInt32 xorig, uInt32 yorig, uInt32 c, uInt8 fg)
|
||||
{
|
||||
if(c >= 256 )
|
||||
return;
|
||||
|
||||
SDL_Rect tmp;
|
||||
|
||||
for(uInt32 y = 0; y < 8; y++)
|
||||
{
|
||||
for(uInt32 z = 0; z < 8; z++)
|
||||
{
|
||||
if((ourFontData[(c << 3) + y] >> z) & 1)
|
||||
{
|
||||
// myFrameBuffer[(y + yorig)*myWidth + z + xorig] = 0xF0F0F0;
|
||||
tmp.x = (z + xorig) * theZoomLevel;
|
||||
tmp.y = (y + yorig) * theZoomLevel;
|
||||
tmp.w = tmp.h = theZoomLevel;
|
||||
myRectList->add(&tmp);
|
||||
SDL_FillRect(myScreen, &tmp, palette[fg]);
|
||||
// FIXME - this can be a lot more efficient
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,205 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-1999 by Bradford W. Mott
|
||||
//
|
||||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: FrameBufferSDL.hxx,v 1.1 2003-10-26 19:40:39 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef FRAMEBUFFER_SDL_HXX
|
||||
#define FRAMEBUFFER_SDL_HXX
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL_syswm.h>
|
||||
|
||||
#include "FrameBuffer.hxx"
|
||||
#include "bspf.hxx"
|
||||
|
||||
class Console;
|
||||
class MediaSource;
|
||||
class RectList;
|
||||
|
||||
class FrameBufferSDL : public FrameBuffer
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Creates a new SDL software framebuffer
|
||||
*/
|
||||
FrameBufferSDL();
|
||||
|
||||
/**
|
||||
Destructor
|
||||
*/
|
||||
virtual ~FrameBufferSDL();
|
||||
|
||||
/**
|
||||
This routine should be called once the console is created to setup
|
||||
the video system for us to use. Return false if any operation fails,
|
||||
otherwise return true.
|
||||
*/
|
||||
virtual bool init();
|
||||
|
||||
/**
|
||||
This routine should be called anytime the MediaSource needs to be redrawn
|
||||
to the screen.
|
||||
*/
|
||||
virtual void drawMediaSource();
|
||||
|
||||
/**
|
||||
This routine should be called to draw a rectangular box with sides
|
||||
at the specified coordinates.
|
||||
|
||||
@param x The x coordinate
|
||||
@param y The y coordinate
|
||||
@param w The width of the box
|
||||
@param h The height of the box
|
||||
@param fg The color of the bounding sides
|
||||
@param bg The color of the background
|
||||
*/
|
||||
virtual void drawBoundedBox(uInt32 x, uInt32 y, uInt32 w, uInt32 h, uInt8 fg, uInt8 bg);
|
||||
|
||||
/**
|
||||
This routine should be called to draw text at the specified coordinates.
|
||||
|
||||
@param x The x coordinate
|
||||
@param y The y coordinate
|
||||
@param message The message text
|
||||
@param fg The color of the text
|
||||
*/
|
||||
virtual void drawText(uInt32 x, uInt32 y, const string& message, uInt8 fg);
|
||||
|
||||
/**
|
||||
This routine should be called to draw character 'c' at the specified coordinates.
|
||||
|
||||
@param x The x coordinate
|
||||
@param y The y coordinate
|
||||
@param c The character to draw
|
||||
@param fg The color of the character
|
||||
*/
|
||||
virtual void drawChar(uInt32 x, uInt32 y, uInt32 c, uInt8 fg);
|
||||
|
||||
/**
|
||||
This routine is called before any drawing is done (per-frame).
|
||||
*/
|
||||
virtual void preFrameUpdate();
|
||||
|
||||
/**
|
||||
This routine is called after any drawing is done (per-frame).
|
||||
*/
|
||||
virtual void postFrameUpdate();
|
||||
|
||||
/**
|
||||
This routine is called when the emulation has been paused.
|
||||
|
||||
@param status Toggle pause based on status
|
||||
*/
|
||||
virtual void pause(bool status);
|
||||
|
||||
/**
|
||||
Toggles between fullscreen and window mode. Grabmouse and hidecursor
|
||||
activated when in fullscreen mode.
|
||||
*/
|
||||
void toggleFullscreen();
|
||||
|
||||
/**
|
||||
This routine is called when the user wants to resize the window.
|
||||
A '1' argument indicates that the window should increase in size, while '-1'
|
||||
indicates that the windows should decrease in size. A '0' 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
|
||||
of the screen.
|
||||
*/
|
||||
void resize(int mode);
|
||||
|
||||
/**
|
||||
Shows or hides the cursor based on the given boolean value.
|
||||
*/
|
||||
void showCursor(bool show);
|
||||
|
||||
/**
|
||||
Grabs or ungrabs the mouse based on the given boolean value.
|
||||
*/
|
||||
void grabMouse(bool grab);
|
||||
|
||||
/**
|
||||
Answers if the display is currently in fullscreen mode.
|
||||
*/
|
||||
bool fullScreen() { return isFullscreen; }
|
||||
|
||||
/**
|
||||
Answers the current zoom level of the SDL
|
||||
*/
|
||||
uInt32 zoomLevel() { return theZoomLevel; }
|
||||
|
||||
/**
|
||||
This routine is called whenever the screen needs to be recreated.
|
||||
It updates the global screen variable.
|
||||
*/
|
||||
bool createScreen();
|
||||
|
||||
/**
|
||||
Centers the game window onscreen. Only works in X11 for now.
|
||||
*/
|
||||
void centerScreen();
|
||||
|
||||
/**
|
||||
Calculate the maximum window size that the current screen can hold.
|
||||
Only works in X11 for now. If not running under X11, always return 4.
|
||||
*/
|
||||
uInt32 maxWindowSizeForScreen();
|
||||
|
||||
/**
|
||||
Set up the palette for a screen of any depth > 8.
|
||||
Scales the palette by 'shade'.
|
||||
*/
|
||||
void setupPalette(float shade);
|
||||
|
||||
private:
|
||||
// The SDL video buffer
|
||||
SDL_Surface* myScreen;
|
||||
|
||||
// Used in the dirty update of the SDL surface
|
||||
RectList* myRectList;
|
||||
|
||||
// SDL initialization flags
|
||||
uInt32 mySDLFlags;
|
||||
|
||||
// SDL palette
|
||||
Uint32 palette[256];
|
||||
|
||||
// Used to get window-manager specifics
|
||||
SDL_SysWMinfo myWMInfo;
|
||||
|
||||
// Indicates if we are running under X11
|
||||
bool x11Available;
|
||||
|
||||
// Indicates the current zoom level of the SDL screen
|
||||
uInt32 theZoomLevel;
|
||||
|
||||
// Indicates the maximum zoom of the SDL screen
|
||||
uInt32 theMaxZoomLevel;
|
||||
|
||||
// Indicates whether the window is currently centered
|
||||
bool isCentered;
|
||||
|
||||
// Indicates if the mouse should be grabbed
|
||||
bool theGrabMouseIndicator;
|
||||
|
||||
// Indicates if the mouse cursor should be hidden
|
||||
bool theHideCursorIndicator;
|
||||
|
||||
// Indicates whether the game is currently in fullscreen
|
||||
bool isFullscreen;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,197 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-1999 by Bradford W. Mott
|
||||
//
|
||||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: SettingsUNIX.cxx,v 1.1 2003-10-26 19:40:39 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "bspf.hxx"
|
||||
#include "Console.hxx"
|
||||
#include "EventHandler.hxx"
|
||||
#include "StellaEvent.hxx"
|
||||
|
||||
#include "Settings.hxx"
|
||||
#include "SettingsUNIX.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
SettingsUNIX::SettingsUNIX()
|
||||
{
|
||||
// First set variables that the parent class needs
|
||||
myBaseDir = getenv("HOME");
|
||||
string stelladir = myBaseDir + "/.stella";
|
||||
|
||||
if(access(stelladir.c_str(), R_OK|W_OK|X_OK) != 0 )
|
||||
mkdir(stelladir.c_str(), 0777);
|
||||
|
||||
myStateDir = stelladir + "/state/";
|
||||
if(access(myStateDir.c_str(), R_OK|W_OK|X_OK) != 0 )
|
||||
mkdir(myStateDir.c_str(), 0777);
|
||||
|
||||
myUserPropertiesFile = stelladir + "/stella.pro";
|
||||
mySystemPropertiesFile = "/etc/stella.pro";
|
||||
myUserConfigFile = stelladir + "/stellarc";
|
||||
mySystemConfigFile = "/etc/stellarc";
|
||||
|
||||
// Set up the names of the input and output config files
|
||||
mySettingsOutputFilename = myUserConfigFile;
|
||||
if(access(myUserConfigFile.c_str(), R_OK) == 0)
|
||||
mySettingsInputFilename = myUserConfigFile;
|
||||
else
|
||||
mySettingsInputFilename = mySystemConfigFile;
|
||||
|
||||
mySnapshotFile = "";
|
||||
myStateFile = "";
|
||||
|
||||
// Now create UNIX specific settings
|
||||
#ifdef DISPLAY_OPENGL
|
||||
set("opengl", "false");
|
||||
#endif
|
||||
set("fullscreen", "false");
|
||||
set("grabmouse", "false");
|
||||
set("center", "false");
|
||||
set("hidecursor", "false");
|
||||
set("accurate", "true");
|
||||
set("volume", "-1");
|
||||
set("sound", "oss");
|
||||
set("joyleft", "0");
|
||||
set("joyright", "1");
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
SettingsUNIX::~SettingsUNIX()
|
||||
{
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void SettingsUNIX::usage(string& message)
|
||||
{
|
||||
cout << endl
|
||||
<< message << endl
|
||||
<< endl
|
||||
<< "Valid options are:" << endl
|
||||
<< endl
|
||||
<< " -framerate <number> Display the given number of frames per second\n"
|
||||
<< " -zoom <size> Makes window be 'size' times normal\n"
|
||||
<< " -fullscreen <0|1> Play the game in fullscreen mode\n"
|
||||
<< " -grabmouse <0|1> Keeps the mouse in the game window\n"
|
||||
<< " -hidecursor <0|1> Hides the mouse cursor in the game window\n"
|
||||
<< " -center <0|1> Centers the game window onscreen\n"
|
||||
<< " -volume <number> Set the volume (0 - 100)\n"
|
||||
#ifdef DISPLAY_OPENGL
|
||||
<< " -opengl <0|1> Use OpenGL mode.\n"
|
||||
#endif
|
||||
#ifdef HAVE_JOYSTICK
|
||||
<< " -paddle <0|1|2|3|real> Indicates which paddle the mouse should emulate\n"
|
||||
<< " or that real Atari 2600 paddles are being used\n"
|
||||
<< " -joyleft <number> The joystick number representing the left controller\n"
|
||||
<< " -joyright <number> The joystick number representing the right controller\n"
|
||||
#else
|
||||
<< " -paddle <0|1|2|3> Indicates which paddle the mouse should emulate\n"
|
||||
#endif
|
||||
<< " -altpro <props file> Use the given properties file instead of stella.pro\n"
|
||||
<< " -showinfo <0|1> Shows some game info\n"
|
||||
<< " -accurate <0|1> Accurate game timing (uses more CPU)\n"
|
||||
#ifdef SNAPSHOT_SUPPORT
|
||||
<< " -ssdir <path> The directory to save snapshot files to\n"
|
||||
<< " -ssname <name> How to name the snapshot (romname or md5sum)\n"
|
||||
<< " -sssingle <0|1> Generate single snapshot instead of many\n"
|
||||
#endif
|
||||
<< endl
|
||||
<< " -sound <type> Type is one of the following:\n"
|
||||
<< " 0 Disables all sound generation\n"
|
||||
#ifdef SOUND_ALSA
|
||||
<< " alsa ALSA version 0.9 driver\n"
|
||||
#endif
|
||||
#ifdef SOUND_OSS
|
||||
<< " oss Open Sound System driver\n"
|
||||
#endif
|
||||
<< endl
|
||||
#ifdef DEVELOPER_SUPPORT
|
||||
<< " DEVELOPER options (see Stella manual for details)\n"
|
||||
<< " -Dformat Sets \"Display.Format\"\n"
|
||||
<< " -Dxstart Sets \"Display.XStart\"\n"
|
||||
<< " -Dwidth Sets \"Display.Width\"\n"
|
||||
<< " -Dystart Sets \"Display.YStart\"\n"
|
||||
<< " -Dheight Sets \"Display.Height\"\n"
|
||||
<< " -mergeprops <0|1> Merge changed properties into properties file,\n"
|
||||
<< " or save into a separate file\n"
|
||||
#endif
|
||||
<< endl;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string SettingsUNIX::stateFilename(uInt32 state)
|
||||
{
|
||||
if(!myConsole)
|
||||
return "";
|
||||
|
||||
ostringstream buf;
|
||||
buf << myStateDir << myConsole->properties().get("Cartridge.MD5")
|
||||
<< ".st" << state;
|
||||
|
||||
myStateFile = buf.str();
|
||||
return myStateFile;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string SettingsUNIX::snapshotFilename()
|
||||
{
|
||||
if(!myConsole)
|
||||
return "";
|
||||
|
||||
string filename;
|
||||
string path = getString("ssdir");
|
||||
string theSnapshotName = getString("ssname");
|
||||
|
||||
if(theSnapshotName == "romname")
|
||||
path = path + "/" + myConsole->properties().get("Cartridge.Name");
|
||||
else if(theSnapshotName == "md5sum")
|
||||
path = path + "/" + myConsole->properties().get("Cartridge.MD5");
|
||||
|
||||
// Replace all spaces in name with underscores
|
||||
replace(path.begin(), path.end(), ' ', '_');
|
||||
|
||||
// Check whether we want multiple snapshots created
|
||||
if(!getBool("sssingle"))
|
||||
{
|
||||
// Determine if the file already exists, checking each successive filename
|
||||
// until one doesn't exist
|
||||
filename = path + ".png";
|
||||
if(access(filename.c_str(), F_OK) == 0 )
|
||||
{
|
||||
ostringstream buf;
|
||||
for(uInt32 i = 1; ;++i)
|
||||
{
|
||||
buf.str("");
|
||||
buf << path << "_" << i << ".png";
|
||||
if(access(buf.str().c_str(), F_OK) == -1 )
|
||||
break;
|
||||
}
|
||||
filename = buf.str();
|
||||
}
|
||||
}
|
||||
else
|
||||
filename = path + ".png";
|
||||
|
||||
mySnapshotFile = filename;
|
||||
return mySnapshotFile;
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-1999 by Bradford W. Mott
|
||||
//
|
||||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: SettingsUNIX.hxx,v 1.1 2003-10-26 19:40:39 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef SETTINGS_UNIX_HXX
|
||||
#define SETTINGS_UNIX_HXX
|
||||
|
||||
#include "bspf.hxx"
|
||||
|
||||
class Console;
|
||||
|
||||
|
||||
/**
|
||||
This class defines UNIX-like OS's (Linux) system specific settings.
|
||||
|
||||
@author Stephen Anthony
|
||||
@version $Id: SettingsUNIX.hxx,v 1.1 2003-10-26 19:40:39 stephena Exp $
|
||||
*/
|
||||
class SettingsUNIX : public Settings
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Create a new UNIX settings object
|
||||
*/
|
||||
SettingsUNIX();
|
||||
|
||||
/**
|
||||
Destructor
|
||||
*/
|
||||
virtual ~SettingsUNIX();
|
||||
|
||||
public:
|
||||
/**
|
||||
This method should be called to get the filename of a state file
|
||||
given the state number.
|
||||
|
||||
@return String representing the full path of the state filename.
|
||||
*/
|
||||
virtual string stateFilename(uInt32 state);
|
||||
|
||||
/**
|
||||
This method should be called to get the filename of a snapshot.
|
||||
|
||||
@return String representing the full path of the snapshot filename.
|
||||
*/
|
||||
virtual string snapshotFilename();
|
||||
|
||||
/**
|
||||
Display the commandline settings for this UNIX version of Stella.
|
||||
|
||||
@param message A short message about this version of Stella
|
||||
*/
|
||||
virtual void usage(string& message);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -13,7 +13,7 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: mainSDL.cxx,v 1.55 2003-10-17 18:02:16 stephena Exp $
|
||||
// $Id: mainSDL.cxx,v 1.56 2003-10-26 19:40:39 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <fstream>
|
||||
|
@ -95,6 +95,9 @@ static bool theHideCursorIndicator = false;
|
|||
// Indicates the current paddle mode
|
||||
static Int32 thePaddleMode;
|
||||
|
||||
// Indicates relative mouse position horizontally
|
||||
static Int32 mouseX = 0;
|
||||
|
||||
// Indicates whether to show information during program execution
|
||||
static bool theShowInfoFlag;
|
||||
|
||||
|
@ -331,29 +334,29 @@ void handleEvents()
|
|||
if(key == SDLK_EQUALS)
|
||||
theDisplay->resize(1);
|
||||
else if(key == SDLK_MINUS)
|
||||
theDisplay->resize(0);
|
||||
theDisplay->resize(-1);
|
||||
else if(key == SDLK_RETURN)
|
||||
theDisplay->toggleFullscreen();
|
||||
#ifdef DEVELOPER_SUPPORT
|
||||
else if(key == SDLK_END) // Alt-End increases XStart
|
||||
{
|
||||
theConsole->changeXStart(1);
|
||||
theDisplay->resize(-1);
|
||||
theDisplay->resize(0);
|
||||
}
|
||||
else if(key == SDLK_HOME) // Alt-Home decreases XStart
|
||||
{
|
||||
theConsole->changeXStart(0);
|
||||
theDisplay->resize(-1);
|
||||
theDisplay->resize(0);
|
||||
}
|
||||
else if(key == SDLK_PAGEUP) // Alt-PageUp increases YStart
|
||||
{
|
||||
theConsole->changeYStart(1);
|
||||
theDisplay->resize(-1);
|
||||
theDisplay->resize(0);
|
||||
}
|
||||
else if(key == SDLK_PAGEDOWN) // Alt-PageDown decreases YStart
|
||||
{
|
||||
theConsole->changeYStart(0);
|
||||
theDisplay->resize(-1);
|
||||
theDisplay->resize(0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -381,27 +384,27 @@ void handleEvents()
|
|||
else if(key == SDLK_f) // Ctrl-f toggles NTSC/PAL mode
|
||||
{
|
||||
theConsole->toggleFormat();
|
||||
theDisplay->setupPalette();
|
||||
theDisplay->setupPalette(1.0);
|
||||
}
|
||||
else if(key == SDLK_END) // Ctrl-End increases Width
|
||||
{
|
||||
theConsole->changeWidth(1);
|
||||
theDisplay->resize(-1);
|
||||
theDisplay->resize(0);
|
||||
}
|
||||
else if(key == SDLK_HOME) // Ctrl-Home decreases Width
|
||||
{
|
||||
theConsole->changeWidth(0);
|
||||
theDisplay->resize(-1);
|
||||
theDisplay->resize(0);
|
||||
}
|
||||
else if(key == SDLK_PAGEUP) // Ctrl-PageUp increases Height
|
||||
{
|
||||
theConsole->changeHeight(1);
|
||||
theDisplay->resize(-1);
|
||||
theDisplay->resize(0);
|
||||
}
|
||||
else if(key == SDLK_PAGEDOWN) // Ctrl-PageDown decreases Height
|
||||
{
|
||||
theConsole->changeHeight(0);
|
||||
theDisplay->resize(-1);
|
||||
theDisplay->resize(0);
|
||||
}
|
||||
else if(key == SDLK_s) // Ctrl-s saves properties to a file
|
||||
{
|
||||
|
@ -441,21 +444,21 @@ void handleEvents()
|
|||
}
|
||||
else if(event.type == SDL_MOUSEMOTION)
|
||||
{
|
||||
float fudgeFactor = 1000000.0;
|
||||
Int32 resistance = 0, x = 0, mouseX;
|
||||
Int32 width = 640;//theWidth * theWindowSize * 2; FIXME
|
||||
Event::Type type = Event::LastType;
|
||||
Int32 resistance;
|
||||
uInt32 zoom = theDisplay->zoomLevel();
|
||||
Int32 width = theDisplay->width() * zoom;
|
||||
Event::Type type = Event::NoType;
|
||||
|
||||
// Grabmouse and hidecursor introduce some lag into the mouse movement,
|
||||
// so we need to fudge the numbers a bit
|
||||
if(theGrabMouseIndicator && theHideCursorIndicator)
|
||||
{
|
||||
// mouseX = (int)((float)mouseX + (float)event.motion.xrel
|
||||
// * 1.5 * (float) theWindowSize); FIXME
|
||||
mouseX = (int)((float)mouseX + (float)event.motion.xrel
|
||||
* 1.5 * (float) zoom);
|
||||
}
|
||||
else
|
||||
{
|
||||
// mouseX = mouseX + event.motion.xrel * theWindowSize; FIXME
|
||||
mouseX = mouseX + event.motion.xrel * zoom;
|
||||
}
|
||||
|
||||
// Check to make sure mouseX is within the game window
|
||||
|
@ -464,8 +467,7 @@ void handleEvents()
|
|||
else if(mouseX > width)
|
||||
mouseX = width;
|
||||
|
||||
x = width - mouseX;
|
||||
resistance = (Int32)((fudgeFactor * x) / width);
|
||||
resistance = (Int32)(1000000.0 * (width - mouseX) / width);
|
||||
|
||||
// Now, set the event of the correct paddle to the calculated resistance
|
||||
if(thePaddleMode == 0)
|
||||
|
@ -739,7 +741,7 @@ int main(int argc, char* argv[])
|
|||
// Get just the filename of the file containing the ROM image
|
||||
const char* filename = (!strrchr(file, '/')) ? file : strrchr(file, '/') + 1;
|
||||
|
||||
// Setup the SDL window and joystick
|
||||
// Setup the SDL window
|
||||
#ifdef DISPLAY_OPENGL
|
||||
bool useGL = theSettings->getBool("opengl");
|
||||
if(useGL)
|
||||
|
@ -755,13 +757,6 @@ int main(int argc, char* argv[])
|
|||
return 0;
|
||||
}
|
||||
|
||||
if(!setupJoystick())
|
||||
{
|
||||
cerr << "ERROR: Couldn't set up joysticks.\n";
|
||||
cleanup();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Create the 2600 game console
|
||||
theConsole = new Console(image, size, filename, *theSettings, propertiesSet,
|
||||
*theDisplay, theSound->getSampleRate());
|
||||
|
@ -769,6 +764,15 @@ int main(int argc, char* argv[])
|
|||
// Free the image since we don't need it any longer
|
||||
delete[] image;
|
||||
|
||||
// Setup the SDL joysticks
|
||||
// This must be done after the console is created
|
||||
if(!setupJoystick())
|
||||
{
|
||||
cerr << "ERROR: Couldn't set up joysticks.\n";
|
||||
cleanup();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// These variables are common to both timing options
|
||||
// and are needed to calculate the overall frames per second.
|
||||
uInt32 frameTime = 0, numberOfFrames = 0;
|
||||
|
@ -802,7 +806,7 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
|
||||
theDisplay->update();
|
||||
//FIXME theSound->updateSound(theConsole->mediaSource());
|
||||
theSound->updateSound(*theDisplay->mediaSource());
|
||||
|
||||
// Now, waste time if we need to so that we are at the desired frame rate
|
||||
for(;;)
|
||||
|
@ -835,15 +839,20 @@ int main(int argc, char* argv[])
|
|||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
startTime = getTicks();
|
||||
handleEvents();
|
||||
if(!theSettings->pause())
|
||||
{
|
||||
//FIXME theSound->updateSound(theConsole->mediaSource());
|
||||
theSound->updateSound(*theDisplay->mediaSource());
|
||||
}
|
||||
theDisplay->update();
|
||||
|
||||
*/
|
||||
startTime = getTicks();
|
||||
handleEvents();
|
||||
theDisplay->update();
|
||||
theSound->updateSound(*theDisplay->mediaSource());
|
||||
///
|
||||
currentTime = getTicks();
|
||||
virtualTime += timePerFrame;
|
||||
if(currentTime < virtualTime)
|
||||
|
|
Loading…
Reference in New Issue