mirror of https://github.com/stella-emu/stella.git
Huge changes across the map. Lets see if I can remember it all ...
There is now an SDL OpenGL port with filtering and alpha-blending. It's a work in progress right now, but is already quite stable. It's not as optimized as the software version yet, but this will change as well. For now, you have to compile the SDL version in either normal software mode or OpenGL mode. This will change before the 1.4 release. When entering menu mode, the emulation is now suspended. And when pause is pressed, you can't enter menu mode. Because of these changes, CPU use has dropped dramatically when viewing menus. This will benefit all ports, since menus are now redrawn only when necessary, instead of at the current framerate. For a reference, on a Pentium-IV 2.4GHz, the software SDL version maxes CPU usage at 9%, and the SDL OpenGL version at 13.5%. This is at 60 fps and a zoomlevel of 4. While some small improvements can (possibly) be made to the OpenGL version, I think we'll soon be hitting the glass ceiling. Work on the Porting.txt document is progressing, and I estimate it to be 45% complete. The Windows version still doesn't compile, and I still haven't looked at it. Rest assured that it will be done before 1.4. There will be a simultaneous release, even if the Linux versions are finished. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@200 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
d098cb1207
commit
8239748980
|
@ -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.43 2003-10-26 19:40:39 stephena Exp $
|
||||
## $Id: makefile,v 1.44 2003-11-06 22:22:32 stephena Exp $
|
||||
##============================================================================
|
||||
|
||||
##============================================================================
|
||||
|
@ -34,10 +34,10 @@ SOUND_OSS = 1
|
|||
#SOUND_SDL = 1
|
||||
|
||||
### to include OpenGL video support (SDL)
|
||||
#DISPLAY_OPENGL = 1
|
||||
DISPLAY_OPENGL = 0
|
||||
|
||||
### to include joystick support (SDL)
|
||||
JOYSTICK_SUPPORT = 1
|
||||
# JOYSTICK_SUPPORT = 1
|
||||
|
||||
### to include support for saving snapshots in png format
|
||||
### (requires PNG library) FIXME
|
||||
|
@ -142,10 +142,14 @@ endif
|
|||
|
||||
ifeq ($(DISPLAY_OPENGL), 1)
|
||||
OPTS.SDL += -DDISPLAY_OPENGL=1
|
||||
OBJS.SDL += DispGLSDL.o
|
||||
OBJS.SDL += FrameBufferGL.o
|
||||
LIBS.SDL += -lGL -lGLU
|
||||
endif
|
||||
|
||||
ifeq ($(DISPLAY_OPENGL), 0)
|
||||
OBJS.SDL += FrameBufferSDL.o
|
||||
endif
|
||||
|
||||
|
||||
default:
|
||||
@echo ""
|
||||
|
@ -181,7 +185,7 @@ linux-sdl:
|
|||
LDFLAGS+="$(CFLAGS.SDL)" \
|
||||
LDLIBS="-lX11 -lXext" \
|
||||
LDLIBS+="$(LIBS.SDL)" \
|
||||
OBJS="mainSDL.o FrameBufferSDL.o RectList.o SettingsUNIX.o" \
|
||||
OBJS="mainSDL.o SettingsUNIX.o" \
|
||||
OBJS+="$(OBJS.SDL)"
|
||||
|
||||
###############################################################################
|
||||
|
|
|
@ -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.19 2003-10-26 19:40:39 stephena Exp $
|
||||
// $Id: Console.cxx,v 1.20 2003-11-06 22:22:32 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -39,6 +39,7 @@
|
|||
#include "Props.hxx"
|
||||
#include "PropsSet.hxx"
|
||||
#include "Settings.hxx"
|
||||
#include "Sound.hxx"
|
||||
#include "Switches.hxx"
|
||||
#include "System.hxx"
|
||||
#include "TIA.hxx"
|
||||
|
@ -50,11 +51,12 @@
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Console::Console(const uInt8* image, uInt32 size, const char* filename,
|
||||
Settings& rcsettings, PropertiesSet& propertiesSet,
|
||||
FrameBuffer& framebuffer, uInt32 sampleRate)
|
||||
: mySettings(rcsettings),
|
||||
Settings& settings, PropertiesSet& propertiesSet,
|
||||
FrameBuffer& framebuffer, Sound& sound)
|
||||
: mySettings(settings),
|
||||
myPropSet(propertiesSet),
|
||||
myFrameBuffer(framebuffer)
|
||||
myFrameBuffer(framebuffer),
|
||||
mySound(sound)
|
||||
{
|
||||
myControllers[0] = 0;
|
||||
myControllers[1] = 0;
|
||||
|
@ -158,7 +160,7 @@ Console::Console(const uInt8* image, uInt32 size, const char* filename,
|
|||
}
|
||||
|
||||
M6532* m6532 = new M6532(*this);
|
||||
TIA* tia = new TIA(*this, sampleRate);
|
||||
TIA* tia = new TIA(*this, mySound.getSampleRate());
|
||||
Cartridge* cartridge = Cartridge::create(image, size, myProperties);
|
||||
|
||||
mySystem->attach(m6502);
|
||||
|
@ -181,7 +183,8 @@ Console::Console(const uInt8* image, uInt32 size, const char* filename,
|
|||
Console::Console(const Console& console)
|
||||
: mySettings(console.mySettings),
|
||||
myPropSet(console.myPropSet),
|
||||
myFrameBuffer(console.myFrameBuffer)
|
||||
myFrameBuffer(console.myFrameBuffer),
|
||||
mySound(console.mySound)
|
||||
{
|
||||
// TODO: Write this method
|
||||
assert(false);
|
||||
|
@ -215,6 +218,12 @@ FrameBuffer& Console::frameBuffer() const
|
|||
return myFrameBuffer;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Sound& Console::sound() const
|
||||
{
|
||||
return mySound;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Console& Console::operator = (const Console&)
|
||||
{
|
||||
|
|
|
@ -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.14 2003-10-26 19:40:39 stephena Exp $
|
||||
// $Id: Console.hxx,v 1.15 2003-11-06 22:22:32 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.14 2003-10-26 19:40:39 stephena Exp $
|
||||
@version $Id: Console.hxx,v 1.15 2003-11-06 22:22:32 stephena Exp $
|
||||
*/
|
||||
class Console
|
||||
{
|
||||
|
@ -53,14 +53,14 @@ class Console
|
|||
@param image The ROM image of the game to emulate
|
||||
@param size The size of the ROM image
|
||||
@param filename The name of the file that contained the ROM image
|
||||
@param rcsettings The settings object to use
|
||||
@param settings 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
|
||||
@param sound The sound object to use
|
||||
*/
|
||||
Console(const uInt8* image, uInt32 size, const char* filename,
|
||||
Settings& rcsettings, PropertiesSet& propertiesSet,
|
||||
FrameBuffer& framebuffer, uInt32 sampleRate);
|
||||
Settings& settings, PropertiesSet& propertiesSet,
|
||||
FrameBuffer& framebuffer, Sound& sound);
|
||||
|
||||
/**
|
||||
Create a new console object by copying another one
|
||||
|
@ -106,6 +106,13 @@ class Console
|
|||
*/
|
||||
FrameBuffer& frameBuffer() const;
|
||||
|
||||
/**
|
||||
Get the sound object of the console
|
||||
|
||||
@return The sound object for this console
|
||||
*/
|
||||
Sound& sound() const;
|
||||
|
||||
/**
|
||||
Get the console switches
|
||||
|
||||
|
@ -246,6 +253,9 @@ class Console
|
|||
// Reference to the FrameBuffer object
|
||||
FrameBuffer& myFrameBuffer;
|
||||
|
||||
// Reference to the Sound object
|
||||
Sound& mySound;
|
||||
|
||||
// Pointer to the EventHandler object
|
||||
EventHandler* myEventHandler;
|
||||
|
||||
|
|
|
@ -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.17 2003-10-26 19:40:39 stephena Exp $
|
||||
// $Id: EventHandler.cxx,v 1.18 2003-11-06 22:22:32 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -27,6 +27,7 @@
|
|||
#include "StellaEvent.hxx"
|
||||
#include "System.hxx"
|
||||
#include "FrameBuffer.hxx"
|
||||
#include "Sound.hxx"
|
||||
#include "bspf.hxx"
|
||||
|
||||
#ifdef SNAPSHOT_SUPPORT
|
||||
|
@ -38,6 +39,7 @@ EventHandler::EventHandler(Console* console)
|
|||
: myConsole(console),
|
||||
myCurrentState(0),
|
||||
myPauseStatus(false),
|
||||
myQuitStatus(false),
|
||||
myMenuStatus(false),
|
||||
myRemapEnabledFlag(true)
|
||||
{
|
||||
|
@ -84,11 +86,13 @@ Event* EventHandler::event()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EventHandler::sendKeyEvent(StellaEvent::KeyCode key, Int32 state)
|
||||
{
|
||||
// First check if we are entering menu mode
|
||||
if(myRemapEnabledFlag && key == StellaEvent::KCODE_TAB && state == 1)
|
||||
// First check if we are changing menu mode, and only change when not paused
|
||||
// Sound is paused when entering menu mode, but the framebuffer is kept active
|
||||
if(myRemapEnabledFlag && key == StellaEvent::KCODE_TAB && state == 1 && !myPauseStatus)
|
||||
{
|
||||
myMenuStatus = !myMenuStatus;
|
||||
myConsole->frameBuffer().showMainMenu(myMenuStatus);
|
||||
myConsole->frameBuffer().showMenu(myMenuStatus);
|
||||
myConsole->sound().pause(myMenuStatus);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -145,13 +149,13 @@ void EventHandler::sendEvent(Event::Type event, Int32 state)
|
|||
{
|
||||
myPauseStatus = !myPauseStatus;
|
||||
myConsole->frameBuffer().pause(myPauseStatus);
|
||||
//FIXME myConsole->sound().pause(myPauseStatus);
|
||||
myConsole->sound().pause(myPauseStatus);
|
||||
return;
|
||||
}
|
||||
else if(event == Event::Quit)
|
||||
{
|
||||
myQuitStatus = !myQuitStatus;
|
||||
myConsole->settings().saveConfig();
|
||||
myConsole->settings().setQuitEvent();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.11 2003-10-26 19:40:39 stephena Exp $
|
||||
// $Id: EventHandler.hxx,v 1.12 2003-11-06 22:22:32 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef EVENTHANDLER_HXX
|
||||
|
@ -41,7 +41,7 @@ class MediaSource;
|
|||
mapping can take place.
|
||||
|
||||
@author Stephen Anthony
|
||||
@version $Id: EventHandler.hxx,v 1.11 2003-10-26 19:40:39 stephena Exp $
|
||||
@version $Id: EventHandler.hxx,v 1.12 2003-11-06 22:22:32 stephena Exp $
|
||||
*/
|
||||
class EventHandler
|
||||
{
|
||||
|
@ -118,6 +118,16 @@ class EventHandler
|
|||
*/
|
||||
void enableRemapping(bool status) { myRemapEnabledFlag = status; }
|
||||
|
||||
/**
|
||||
This method indicated whether a pause event has been received.
|
||||
*/
|
||||
bool doPause() { return myPauseStatus; }
|
||||
|
||||
/**
|
||||
This method indicated whether a quit event has been received.
|
||||
*/
|
||||
bool doQuit() { return myQuitStatus; }
|
||||
|
||||
void getKeymapArray(Event::Type** array, uInt32* size);
|
||||
void getJoymapArray(Event::Type** array, uInt32* size);
|
||||
|
||||
|
@ -159,6 +169,9 @@ class EventHandler
|
|||
// Indicates the current pause status
|
||||
bool myPauseStatus;
|
||||
|
||||
// Indicates the current quit status
|
||||
bool myQuitStatus;
|
||||
|
||||
// The current keymap in string form
|
||||
string myKeymapString;
|
||||
|
||||
|
|
|
@ -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.2 2003-10-26 19:40:39 stephena Exp $
|
||||
// $Id: FrameBuffer.cxx,v 1.3 2003-11-06 22:22:32 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <sstream>
|
||||
|
@ -57,6 +57,8 @@ FrameBuffer::FrameBuffer()
|
|||
myCurrentWidget(W_NONE),
|
||||
myRemapEventSelectedFlag(false),
|
||||
mySelectedEvent(Event::NoType),
|
||||
myMenuMode(false),
|
||||
theMenuChangedIndicator(false),
|
||||
myMaxLines(0),
|
||||
myMainMenuIndex(0),
|
||||
myMainMenuItems(sizeof(ourMainMenu)/sizeof(MainMenuItem)),
|
||||
|
@ -84,23 +86,19 @@ void FrameBuffer::initDisplay(Console* console, MediaSource* mediasrc)
|
|||
|
||||
// Fill the properties info array with game information
|
||||
ourPropertiesInfo[0] = myConsole->properties().get("Cartridge.Name");
|
||||
if(ourPropertiesInfo[0].length() > myInfoMenuWidth)
|
||||
myInfoMenuWidth = ourPropertiesInfo[0].length();
|
||||
ourPropertiesInfo[1] = myConsole->properties().get("Cartridge.Manufacturer");
|
||||
if(ourPropertiesInfo[1].length() > myInfoMenuWidth)
|
||||
myInfoMenuWidth = ourPropertiesInfo[1].length();
|
||||
ourPropertiesInfo[2] = myConsole->properties().get("Cartridge.Rarity");
|
||||
if(ourPropertiesInfo[2].length() > myInfoMenuWidth)
|
||||
myInfoMenuWidth = ourPropertiesInfo[2].length();
|
||||
ourPropertiesInfo[3] = myConsole->properties().get("Cartridge.MD5");
|
||||
if(ourPropertiesInfo[3].length() > myInfoMenuWidth)
|
||||
myInfoMenuWidth = ourPropertiesInfo[3].length();
|
||||
ourPropertiesInfo[4] = myConsole->properties().get("Cartridge.Type");
|
||||
if(ourPropertiesInfo[4].length() > myInfoMenuWidth)
|
||||
myInfoMenuWidth = ourPropertiesInfo[4].length();
|
||||
ourPropertiesInfo[5] = myConsole->properties().get("Cartridge.ModelNo");
|
||||
if(ourPropertiesInfo[5].length() > myInfoMenuWidth)
|
||||
myInfoMenuWidth = ourPropertiesInfo[5].length();
|
||||
ourPropertiesInfo[1] = "";
|
||||
ourPropertiesInfo[2] = "Manufacturer: " + myConsole->properties().get("Cartridge.Manufacturer");
|
||||
ourPropertiesInfo[3] = "Model: " + myConsole->properties().get("Cartridge.ModelNo");
|
||||
ourPropertiesInfo[4] = "Rarity: " + myConsole->properties().get("Cartridge.Rarity");
|
||||
ourPropertiesInfo[5] = "Type: " + myConsole->properties().get("Cartridge.Type");
|
||||
ourPropertiesInfo[6] = "";
|
||||
ourPropertiesInfo[7] = "MD5SUM:";
|
||||
ourPropertiesInfo[8] = myConsole->properties().get("Cartridge.MD5");
|
||||
|
||||
// Figure out the longest string
|
||||
for(uInt8 i = 0; i < 9; i++)
|
||||
if(ourPropertiesInfo[i].length() > myInfoMenuWidth)
|
||||
myInfoMenuWidth = ourPropertiesInfo[i].length();
|
||||
|
||||
// Get the arrays containing key and joystick mappings
|
||||
myConsole->eventHandler().getKeymapArray(&myKeyTable, &myKeyTableSize);
|
||||
|
@ -128,10 +126,48 @@ void FrameBuffer::update()
|
|||
// Do any pre-frame stuff
|
||||
preFrameUpdate();
|
||||
|
||||
// Determine which mode we are in (normal or menu mode)
|
||||
// In normal mode, only the mediasource or messages are shown,
|
||||
// and they are shown per-frame
|
||||
// In menu mode, any of the menus are shown, but the mediasource
|
||||
// is not updated, and all updates depend on whether the screen is dirty
|
||||
if(!myMenuMode)
|
||||
{
|
||||
// Draw changes to the mediasource
|
||||
if(!myPauseStatus) // FIXME - sound class
|
||||
if(!myPauseStatus)
|
||||
myMediaSource->update();
|
||||
|
||||
// We always draw the screen, even if the core is paused
|
||||
drawMediaSource();
|
||||
|
||||
if(!myPauseStatus)
|
||||
{
|
||||
// Draw any pending messages
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // we are in MENU_MODE
|
||||
{
|
||||
// Only update the screen if it's been invalidated
|
||||
// or the menus have changed
|
||||
if(theMenuChangedIndicator || theRedrawEntireFrameIndicator)
|
||||
{
|
||||
cerr << "redrawing screen and menus\n";
|
||||
drawMediaSource();
|
||||
|
||||
// Then overlay any menu items
|
||||
|
@ -156,23 +192,9 @@ void FrameBuffer::update()
|
|||
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;
|
||||
// Now the screen is up to date
|
||||
theMenuChangedIndicator = theRedrawEntireFrameIndicator = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Do any post-frame stuff
|
||||
|
@ -180,8 +202,10 @@ void FrameBuffer::update()
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBuffer::showMainMenu(bool show)
|
||||
void FrameBuffer::showMenu(bool show)
|
||||
{
|
||||
myMenuMode = show;
|
||||
|
||||
myCurrentWidget = show ? MAIN_MENU : W_NONE;
|
||||
myRemapEventSelectedFlag = false;
|
||||
mySelectedEvent = Event::NoType;
|
||||
|
@ -192,7 +216,7 @@ void FrameBuffer::showMainMenu(bool show)
|
|||
void FrameBuffer::showMessage(const string& message)
|
||||
{
|
||||
myMessageText = message;
|
||||
myMessageTime = myFrameRate << 1;
|
||||
myMessageTime = myFrameRate << 1; // Show message for 2 seconds
|
||||
theRedrawEntireFrameIndicator = true;
|
||||
}
|
||||
|
||||
|
@ -202,7 +226,7 @@ inline void FrameBuffer::drawMainMenu()
|
|||
uInt32 x, y, width, height, i, xpos, ypos;
|
||||
|
||||
width = 16*FONTWIDTH + (FONTWIDTH << 1);
|
||||
height = myMainMenuItems*LINEOFFSET + 2*FONTHEIGHT;
|
||||
height = myMainMenuItems*LINEOFFSET + (FONTHEIGHT << 1);
|
||||
x = (myWidth >> 1) - (width >> 1);
|
||||
y = (myHeight >> 1) - (height >> 1);
|
||||
|
||||
|
@ -224,7 +248,7 @@ inline void FrameBuffer::drawRemapMenu()
|
|||
uInt32 x, y, width, height, i, xpos, ypos;
|
||||
|
||||
width = (myWidth >> 3) * FONTWIDTH - (FONTWIDTH << 1);
|
||||
height = myMaxLines*LINEOFFSET + 2*FONTHEIGHT;
|
||||
height = myMaxLines*LINEOFFSET + (FONTHEIGHT << 1);
|
||||
x = (myWidth >> 1) - (width >> 1);
|
||||
y = (myHeight >> 1) - (height >> 1);
|
||||
|
||||
|
@ -260,12 +284,12 @@ inline void FrameBuffer::drawRemapMenu()
|
|||
}
|
||||
|
||||
// Finally, indicate that there are more items to the top or bottom
|
||||
xpos = (width >> 1) - FONTWIDTH/2;
|
||||
xpos = (width >> 1) - (FONTWIDTH >> 1);
|
||||
if(myRemapMenuHighIndex - myMaxLines > 0)
|
||||
drawChar(xpos, y, UPARROW, FGCOLOR);
|
||||
|
||||
if(myRemapMenuLowIndex + myMaxLines < myRemapMenuItems)
|
||||
drawChar(xpos, height - FONTWIDTH/2, DOWNARROW, FGCOLOR);
|
||||
drawChar(xpos, height - (FONTWIDTH >> 1), DOWNARROW, FGCOLOR);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -273,15 +297,15 @@ inline void FrameBuffer::drawInfoMenu()
|
|||
{
|
||||
uInt32 x, y, width, height, i, xpos;
|
||||
|
||||
width = myInfoMenuWidth*FONTWIDTH + 2*FONTWIDTH;
|
||||
height = 6*LINEOFFSET + 2*FONTHEIGHT;
|
||||
width = myInfoMenuWidth*FONTWIDTH + (FONTWIDTH << 1);
|
||||
height = 9*LINEOFFSET + (FONTHEIGHT << 1);
|
||||
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++)
|
||||
for(i = 0; i < 9; i++)
|
||||
drawText(xpos, LINEOFFSET*i + y + YBOXOFFSET, ourPropertiesInfo[i], FGCOLOR);
|
||||
}
|
||||
|
||||
|
@ -291,6 +315,9 @@ void FrameBuffer::sendKeyEvent(StellaEvent::KeyCode key, Int32 state)
|
|||
if(myCurrentWidget == W_NONE || state != 1)
|
||||
return;
|
||||
|
||||
// Redraw the menus whenever a key event is received
|
||||
theMenuChangedIndicator = true;
|
||||
|
||||
// Check which type of widget is pending
|
||||
switch(myCurrentWidget)
|
||||
{
|
||||
|
@ -357,6 +384,8 @@ void FrameBuffer::sendJoyEvent(StellaEvent::JoyStick stick,
|
|||
return;
|
||||
|
||||
cerr << "stick = " << stick << ", button = " << code << endl;
|
||||
// Redraw the menus whenever a joy event is received
|
||||
theMenuChangedIndicator = true;
|
||||
|
||||
// Check which type of widget is pending
|
||||
switch(myCurrentWidget)
|
||||
|
@ -663,7 +692,7 @@ const uInt8 FrameBuffer::ourFontData[2048] = {
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FrameBuffer::MainMenuItem FrameBuffer::ourMainMenu[2] = {
|
||||
{ REMAP_MENU, "Key Remapping" },
|
||||
{ REMAP_MENU, "Event Remapping" },
|
||||
{ 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.2 2003-10-26 19:40:39 stephena Exp $
|
||||
// $Id: FrameBuffer.hxx,v 1.3 2003-11-06 22:22:32 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef FRAMEBUFFER_HXX
|
||||
|
@ -35,7 +35,7 @@ class Console;
|
|||
can be changed.
|
||||
|
||||
@author Stephen Anthony
|
||||
@version $Id: FrameBuffer.hxx,v 1.2 2003-10-26 19:40:39 stephena Exp $
|
||||
@version $Id: FrameBuffer.hxx,v 1.3 2003-11-06 22:22:32 stephena Exp $
|
||||
*/
|
||||
class FrameBuffer
|
||||
{
|
||||
|
@ -70,7 +70,7 @@ class FrameBuffer
|
|||
|
||||
@param show Show/hide the menu based on the boolean value
|
||||
*/
|
||||
void showMainMenu(bool show);
|
||||
void showMenu(bool show);
|
||||
|
||||
/**
|
||||
Shows a message onscreen.
|
||||
|
@ -280,6 +280,12 @@ class FrameBuffer
|
|||
// Indicates the current selected event being remapped
|
||||
Event::Type mySelectedEvent;
|
||||
|
||||
// Indicates if we are in menu mode
|
||||
bool myMenuMode;
|
||||
|
||||
// Indicates if the menus should be redrawn
|
||||
bool theMenuChangedIndicator;
|
||||
|
||||
// The maximum number of vertical lines of text that can be onscreen
|
||||
uInt32 myMaxLines;
|
||||
|
||||
|
@ -300,7 +306,7 @@ class FrameBuffer
|
|||
uInt32 myInfoMenuWidth;
|
||||
|
||||
// Holds information about the current selected ROM image
|
||||
string ourPropertiesInfo[6];
|
||||
string ourPropertiesInfo[9];
|
||||
|
||||
// Holds static strings for the main menu
|
||||
static MainMenuItem ourMainMenu[2];
|
||||
|
|
|
@ -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.cxx,v 1.10 2003-09-28 21:59:24 stephena Exp $
|
||||
// $Id: Settings.cxx,v 1.11 2003-11-06 22:22:32 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <cassert>
|
||||
|
@ -32,9 +32,7 @@
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Settings::Settings()
|
||||
: myPauseIndicator(false),
|
||||
myQuitIndicator(false),
|
||||
myConsole(0)
|
||||
: myConsole(0)
|
||||
{
|
||||
// First create the settings array
|
||||
myCapacity = 30;
|
||||
|
|
|
@ -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.8 2003-10-26 19:40:39 stephena Exp $
|
||||
// $Id: Settings.hxx,v 1.9 2003-11-06 22:22:32 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.8 2003-10-26 19:40:39 stephena Exp $
|
||||
@version $Id: Settings.hxx,v 1.9 2003-11-06 22:22:32 stephena Exp $
|
||||
*/
|
||||
class Settings
|
||||
{
|
||||
|
@ -134,32 +134,6 @@ class Settings
|
|||
*/
|
||||
void setConsole(Console* console) { myConsole = console; }
|
||||
|
||||
/**
|
||||
This method should be called when the emulation core receives
|
||||
a QUIT event.
|
||||
*/
|
||||
void setQuitEvent() { myQuitIndicator = true; }
|
||||
|
||||
/**
|
||||
This method determines whether the QUIT event has been received.
|
||||
|
||||
@return Boolean representing whether a QUIT event has been received
|
||||
*/
|
||||
bool quit() { return myQuitIndicator; }
|
||||
|
||||
/**
|
||||
This method should be called at when the emulation core receives
|
||||
a PAUSE event.
|
||||
*/
|
||||
void setPauseEvent(bool status) { myPauseIndicator = status; }
|
||||
|
||||
/**
|
||||
This method determines whether the PAUSE event has been received.
|
||||
|
||||
@return Boolean representing whether a PAUSE event has been received
|
||||
*/
|
||||
bool pause() { return myPauseIndicator; }
|
||||
|
||||
/**
|
||||
This method should be called to get the filename of the users'
|
||||
properties (stella.pro) file.
|
||||
|
@ -204,9 +178,6 @@ class Settings
|
|||
#endif
|
||||
|
||||
protected:
|
||||
bool myPauseIndicator;
|
||||
bool myQuitIndicator;
|
||||
|
||||
string myBaseDir;
|
||||
string myStateDir;
|
||||
string myStateFile;
|
||||
|
|
|
@ -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: Sound.cxx,v 1.5 2003-02-25 03:12:54 stephena Exp $
|
||||
// $Id: Sound.cxx,v 1.6 2003-11-06 22:22:32 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include "Sound.hxx"
|
||||
|
@ -50,6 +50,11 @@ void Sound::setSoundVolume(Int32 volume)
|
|||
{
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Sound::pause(bool status)
|
||||
{
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Sound::updateSound(MediaSource& mediaSource)
|
||||
{
|
||||
|
|
|
@ -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: Sound.hxx,v 1.5 2003-02-25 03:12:55 stephena Exp $
|
||||
// $Id: Sound.hxx,v 1.6 2003-11-06 22:22:32 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef SOUND_HXX
|
||||
|
@ -28,7 +28,7 @@
|
|||
to compile Stella with no sound support whatsoever.
|
||||
|
||||
@author Stephen Anthony
|
||||
@version $Id: Sound.hxx,v 1.5 2003-02-25 03:12:55 stephena Exp $
|
||||
@version $Id: Sound.hxx,v 1.6 2003-11-06 22:22:32 stephena Exp $
|
||||
*/
|
||||
class Sound
|
||||
{
|
||||
|
@ -72,6 +72,14 @@ class Sound
|
|||
*/
|
||||
virtual void setSoundVolume(Int32 percent);
|
||||
|
||||
/**
|
||||
Sets the pause status. While pause is selected, updateSound()
|
||||
should not play any sound.
|
||||
|
||||
@param status Toggle pause based on status
|
||||
*/
|
||||
virtual void pause(bool status);
|
||||
|
||||
/**
|
||||
Update the sound device using the audio sample from the specified
|
||||
media source.
|
||||
|
|
|
@ -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: Snapshot.cxx,v 1.6 2003-10-17 18:02:16 stephena Exp $
|
||||
// $Id: Snapshot.cxx,v 1.7 2003-11-06 22:22:32 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <png.h>
|
||||
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "bspf.hxx"
|
||||
#include "FrameBuffer.hxx"
|
||||
#include "MediaSrc.hxx"
|
||||
#include "Snapshot.hxx"
|
||||
|
||||
|
||||
|
@ -62,20 +63,19 @@ void Snapshot::png_user_error(png_structp ctx, png_const_charp str)
|
|||
This routine saves the current frame buffer to a 256 color PNG file,
|
||||
appropriately scaled by the amount specified in 'multiplier'.
|
||||
*/
|
||||
int Snapshot::savePNG(string filename, FrameBuffer& frameBuffer, uInt32 multiplier)
|
||||
int Snapshot::savePNG(string filename, FrameBuffer& framebuffer, uInt32 multiplier)
|
||||
{
|
||||
#if 0
|
||||
// FIXME
|
||||
png_structp png_ptr = 0;
|
||||
png_infop info_ptr = 0;
|
||||
MediaSource* source = framebuffer.mediaSource();
|
||||
|
||||
uInt8* pixels = frameBuffer.current();
|
||||
uInt8* pixels = source->currentFrameBuffer();
|
||||
|
||||
// PNG and window dimensions will be different because of scaling
|
||||
int picWidth = frameBuffer.width() * 2 * multiplier;
|
||||
int picHeight = frameBuffer.height() * multiplier;
|
||||
int width = frameBuffer.width();
|
||||
int height = frameBuffer.height();
|
||||
int picWidth = framebuffer.width() * multiplier;
|
||||
int picHeight = framebuffer.height() * multiplier;
|
||||
int width = source->width();
|
||||
int height = source->height();
|
||||
|
||||
ofstream* out = new ofstream(filename.c_str());
|
||||
if(!out)
|
||||
|
@ -93,7 +93,7 @@ int Snapshot::savePNG(string filename, FrameBuffer& frameBuffer, uInt32 multipli
|
|||
return 0;
|
||||
}
|
||||
|
||||
const uInt32* gamePalette = frameBuffer.palette();
|
||||
const uInt32* gamePalette = source->palette();
|
||||
for(uInt32 i = 0; i < 256; ++i)
|
||||
{
|
||||
palette[i].red = (uInt8) ((gamePalette[i] & 0x00ff0000) >> 16);
|
||||
|
@ -138,7 +138,7 @@ int Snapshot::savePNG(string filename, FrameBuffer& frameBuffer, uInt32 multipli
|
|||
|
||||
// The width has to be scaled by 2 * multiplier. Each pixel must be
|
||||
// present scaleX times. Each scanline must be present scaleY times.
|
||||
int scaleX = 2 * multiplier;
|
||||
int scaleX = multiplier << 1;
|
||||
int scaleY = multiplier;
|
||||
|
||||
// Create a buffer to hold the new scanline.
|
||||
|
@ -172,6 +172,6 @@ int Snapshot::savePNG(string filename, FrameBuffer& frameBuffer, uInt32 multipli
|
|||
|
||||
out->close();
|
||||
delete out;
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -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: Snapshot.hxx,v 1.3 2003-10-17 18:02:16 stephena Exp $
|
||||
// $Id: Snapshot.hxx,v 1.4 2003-11-06 22:22:32 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef SNAPSHOT_HXX
|
||||
|
@ -31,7 +31,7 @@ class Snapshot
|
|||
Snapshot();
|
||||
~Snapshot();
|
||||
|
||||
int savePNG(string filename, FrameBuffer& mediaSource, uInt32 multiplier = 1);
|
||||
int savePNG(string filename, FrameBuffer& framebuffer, uInt32 multiplier = 1);
|
||||
|
||||
private:
|
||||
static void png_write_data(png_structp ctx, png_bytep area, png_size_t size);
|
||||
|
|
|
@ -0,0 +1,586 @@
|
|||
//============================================================================
|
||||
//
|
||||
// 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: FrameBufferGL.cxx,v 1.1 2003-11-06 22:22:32 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL_syswm.h>
|
||||
#include <sstream>
|
||||
|
||||
#include "Console.hxx"
|
||||
#include "FrameBuffer.hxx"
|
||||
#include "FrameBufferGL.hxx"
|
||||
#include "MediaSrc.hxx"
|
||||
#include "Settings.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FrameBufferGL::FrameBufferGL()
|
||||
: myScreen(0),
|
||||
myTexture(0),
|
||||
x11Available(false),
|
||||
theZoomLevel(1),
|
||||
theMaxZoomLevel(1),
|
||||
theGrabMouseIndicator(false),
|
||||
theHideCursorIndicator(false),
|
||||
isFullscreen(false)
|
||||
{
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FrameBufferGL::~FrameBufferGL()
|
||||
{
|
||||
if(myTexture)
|
||||
SDL_FreeSurface(myTexture);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FrameBufferGL::init()
|
||||
{
|
||||
// Get the desired width and height of the display
|
||||
myWidth = myMediaSource->width() << 1;
|
||||
myHeight = myMediaSource->height();
|
||||
|
||||
// Now create the OpenGL 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_OPENGL;
|
||||
mySDLFlags |= myConsole->settings().getBool("fullscreen") ? SDL_FULLSCREEN : 0;
|
||||
|
||||
// Set the window title and icon
|
||||
ostringstream name;
|
||||
name << "Stella: \"" << myConsole->properties().get("Cartridge.Name") << "\"";
|
||||
SDL_WM_SetCaption(name.str().c_str(), "stella");
|
||||
|
||||
// Set up the OpenGL attributes
|
||||
int rgb_size[3];
|
||||
int bpp = SDL_GetVideoInfo()->vfmt->BitsPerPixel;
|
||||
switch(bpp)
|
||||
{
|
||||
case 8:
|
||||
rgb_size[0] = 3;
|
||||
rgb_size[1] = 3;
|
||||
rgb_size[2] = 2;
|
||||
break;
|
||||
|
||||
case 15:
|
||||
case 16:
|
||||
rgb_size[0] = 5;
|
||||
rgb_size[1] = 5;
|
||||
rgb_size[2] = 5;
|
||||
break;
|
||||
|
||||
default:
|
||||
rgb_size[0] = 8;
|
||||
rgb_size[1] = 8;
|
||||
rgb_size[2] = 8;
|
||||
break;
|
||||
}
|
||||
SDL_GL_SetAttribute( SDL_GL_RED_SIZE, rgb_size[0] );
|
||||
SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, rgb_size[1] );
|
||||
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, rgb_size[2] );
|
||||
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, bpp );
|
||||
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
|
||||
|
||||
// Create the screen
|
||||
if(!createScreen())
|
||||
return false;
|
||||
setupPalette(1.0);
|
||||
|
||||
// Show some OpenGL info
|
||||
if(myConsole->settings().getBool("showinfo"))
|
||||
{
|
||||
cout << endl
|
||||
<< "Vendor : " << glGetString(GL_VENDOR) << endl
|
||||
<< "Renderer: " << glGetString(GL_RENDERER) << endl
|
||||
<< "Version : " << glGetString(GL_VERSION) << endl;
|
||||
}
|
||||
|
||||
// Create the texture surface and texture fonts
|
||||
createTextures();
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
// Set up global GL stuff
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGL::drawMediaSource() // FIXME - maybe less copying can be done?
|
||||
{
|
||||
// Copy the mediasource framebuffer to the RGB texture
|
||||
uInt8* currentFrame = myMediaSource->currentFrameBuffer();
|
||||
uInt8* previousFrame = myMediaSource->previousFrameBuffer();
|
||||
uInt32 width = myMediaSource->width();
|
||||
uInt32 height = myMediaSource->height();
|
||||
uInt32* buffer = (uInt32*) myTexture->pixels;
|
||||
|
||||
register uInt32 y;
|
||||
for(y = 0; y < height; ++y )
|
||||
{
|
||||
const uInt32 bufofsY = y * width;
|
||||
const uInt32 screenofsY = y * myTexture->w;
|
||||
|
||||
register uInt32 x;
|
||||
for(x = 0; x < width; ++x )
|
||||
{
|
||||
const uInt32 bufofs = bufofsY + x;
|
||||
uInt8 v = currentFrame[bufofs];
|
||||
if(v == previousFrame[bufofs] && !theRedrawEntireFrameIndicator)
|
||||
continue;
|
||||
|
||||
// x << 1 is times 2 ( doubling width ) WIDTH_FACTOR
|
||||
const uInt32 pos = screenofsY + (x << 1);
|
||||
buffer[pos] = buffer[pos+1] = myPalette[v];
|
||||
}
|
||||
}
|
||||
|
||||
// Texturemap complete texture to surface so we have free scaling
|
||||
// and antialiasing
|
||||
glBindTexture(GL_TEXTURE_2D, myTextureID);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, myTexture->w, myTexture->h,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, myTexture->pixels);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(myTexCoord[0], myTexCoord[1]); glVertex2i(0, 0);
|
||||
glTexCoord2f(myTexCoord[2], myTexCoord[1]); glVertex2i(myWidth, 0);
|
||||
glTexCoord2f(myTexCoord[2], myTexCoord[3]); glVertex2i(myWidth, myHeight);
|
||||
glTexCoord2f(myTexCoord[0], myTexCoord[3]); glVertex2i(0, myHeight);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGL::preFrameUpdate()
|
||||
{
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGL::postFrameUpdate()
|
||||
{
|
||||
// Now show all changes made to the textures
|
||||
SDL_GL_SwapBuffers();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FrameBufferGL::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;
|
||||
}
|
||||
|
||||
glPushAttrib(GL_ENABLE_BIT);
|
||||
glViewport(0, 0, myScreen->w, myScreen->h);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
glOrtho(0.0, (GLdouble) myScreen->w/theZoomLevel,
|
||||
(GLdouble) myScreen->h/theZoomLevel, 0.0, 0.0, 1.0);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
theRedrawEntireFrameIndicator = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGL::setupPalette(float shade)
|
||||
{
|
||||
// FIXME - OpenGL should be able to shade the texture itself
|
||||
const uInt32* gamePalette = myMediaSource->palette();
|
||||
for(uInt32 i = 0; i < 256; ++i)
|
||||
{
|
||||
Uint8 r, g, b, a;
|
||||
|
||||
r = (Uint8) (((gamePalette[i] & 0x00ff0000) >> 16) * shade);
|
||||
g = (Uint8) (((gamePalette[i] & 0x0000ff00) >> 8) * shade);
|
||||
b = (Uint8) ((gamePalette[i] & 0x000000ff) * shade);
|
||||
a = 0xff;
|
||||
|
||||
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
|
||||
myPalette[i] = (a << 24) | (b << 16) | (g << 8) | r;
|
||||
#else
|
||||
myPalette[i] = (r << 24) | (g << 16) | (b << 8) | a;
|
||||
#endif
|
||||
}
|
||||
|
||||
theRedrawEntireFrameIndicator = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGL::pause(bool status)
|
||||
{
|
||||
myPauseStatus = status;
|
||||
|
||||
// Shade the palette to 75% normal value in pause mode
|
||||
// FIXME - this seems like cheating, we should be using OpenGL instead
|
||||
if(myPauseStatus)
|
||||
setupPalette(0.75);
|
||||
else
|
||||
setupPalette(1.0);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGL::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);
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGL::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;
|
||||
|
||||
// Now update the settings
|
||||
ostringstream tmp;
|
||||
tmp << theZoomLevel;
|
||||
myConsole->settings().set("zoom", tmp.str());
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGL::showCursor(bool show)
|
||||
{
|
||||
if(isFullscreen)
|
||||
return;
|
||||
|
||||
if(show)
|
||||
SDL_ShowCursor(SDL_ENABLE);
|
||||
else
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGL::grabMouse(bool grab)
|
||||
{
|
||||
if(isFullscreen)
|
||||
return;
|
||||
|
||||
if(grab)
|
||||
SDL_WM_GrabInput(SDL_GRAB_ON);
|
||||
else
|
||||
SDL_WM_GrabInput(SDL_GRAB_OFF);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 FrameBufferGL::maxWindowSizeForScreen()
|
||||
{
|
||||
if(!x11Available)
|
||||
return 1;
|
||||
|
||||
#ifdef UNIX
|
||||
// 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;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGL::drawBoundedBox(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
|
||||
uInt8 fg, uInt8 bg)
|
||||
{
|
||||
// First draw the box in the background, alpha-blended
|
||||
// We don't care about the specified bg color, since
|
||||
// we always want black with alpha
|
||||
glEnable(GL_BLEND);
|
||||
glColor4f(0.0, 0.0, 0.0, 0.7);
|
||||
glRecti(x, y, x+w, y+h);
|
||||
|
||||
// Now draw the outer edges
|
||||
// Again, we don't care about the provided fg color, since
|
||||
// we always want a light grey with no alpha
|
||||
glDisable(GL_BLEND);
|
||||
glColor3f(0.8, 0.8, 0.8);
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2i(x, y ); // Top Left
|
||||
glVertex2i(x+w, y ); // Top Right
|
||||
glVertex2i(x+w, y+h); // Bottom Right
|
||||
glVertex2i(x, y+h); // Bottom Left
|
||||
glEnd();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGL::drawText(uInt32 xorig, uInt32 yorig,
|
||||
const string& message, uInt8 fg)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, myFontTextureID);
|
||||
glEnable(GL_BLEND);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
|
||||
|
||||
// We place the loop here to avoid multiple calls to glBegin/glEnd
|
||||
glBegin(GL_QUADS);
|
||||
for(uInt32 i = 0; i < message.length(); i++)
|
||||
{
|
||||
uInt32 x = xorig + i*8;
|
||||
uInt32 y = yorig;
|
||||
uInt8 c = message[i];
|
||||
|
||||
glTexCoord2f(myFontCoord[c].minX, myFontCoord[c].minY); glVertex2i(x, y );
|
||||
glTexCoord2f(myFontCoord[c].maxX, myFontCoord[c].minY); glVertex2i(x+8, y );
|
||||
glTexCoord2f(myFontCoord[c].maxX, myFontCoord[c].maxY); glVertex2i(x+8, y+8);
|
||||
glTexCoord2f(myFontCoord[c].minX, myFontCoord[c].maxY); glVertex2i(x, y+8);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGL::drawChar(uInt32 x, uInt32 y, uInt32 c, uInt8 fg)
|
||||
{
|
||||
if(c >= 256 )
|
||||
return;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, myFontTextureID);
|
||||
glEnable(GL_BLEND);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(myFontCoord[c].minX, myFontCoord[c].minY); glVertex2i(x, y );
|
||||
glTexCoord2f(myFontCoord[c].maxX, myFontCoord[c].minY); glVertex2i(x+8, y );
|
||||
glTexCoord2f(myFontCoord[c].maxX, myFontCoord[c].maxY); glVertex2i(x+8, y+8);
|
||||
glTexCoord2f(myFontCoord[c].minX, myFontCoord[c].maxY); glVertex2i(x, y+8);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FrameBufferGL::createTextures()
|
||||
{
|
||||
uInt32 w = power_of_two(myWidth);
|
||||
uInt32 h = power_of_two(myHeight);
|
||||
|
||||
myTexCoord[0] = 0.0f;
|
||||
myTexCoord[1] = 0.0f;
|
||||
myTexCoord[2] = (GLfloat) myWidth / w;
|
||||
myTexCoord[3] = (GLfloat) myHeight / h;
|
||||
|
||||
myTexture = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32,
|
||||
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
|
||||
0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000);
|
||||
#else
|
||||
0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
|
||||
#endif
|
||||
|
||||
if(myTexture == NULL)
|
||||
return false;
|
||||
|
||||
// Create an OpenGL texture from the SDL texture
|
||||
bool showinfo = myConsole->settings().getBool("showinfo");
|
||||
string filter = myConsole->settings().getString("gl_filter");
|
||||
GLint param = GL_NEAREST;
|
||||
if(filter == "linear")
|
||||
{
|
||||
param = GL_LINEAR;
|
||||
if(showinfo)
|
||||
cout << "Using GL_LINEAR filtering.\n\n";
|
||||
}
|
||||
else if(filter == "nearest")
|
||||
{
|
||||
param = GL_NEAREST;
|
||||
if(showinfo)
|
||||
cout << "Using GL_NEAREST filtering.\n\n";
|
||||
}
|
||||
|
||||
glGenTextures(1, &myTextureID);
|
||||
glBindTexture(GL_TEXTURE_2D, myTextureID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, param);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, param);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
myTexture->pixels);
|
||||
|
||||
// Now create the font texture. There are 256 fonts of 8x8 pixels.
|
||||
// These will be stored in a texture of size 256x64, which is 32 characters
|
||||
// per line, and 8 lines.
|
||||
SDL_Surface* fontTexture = SDL_CreateRGBSurface(SDL_SWSURFACE, 256, 64, 32,
|
||||
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
|
||||
0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000);
|
||||
#else
|
||||
0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
|
||||
#endif
|
||||
|
||||
if(fontTexture == NULL)
|
||||
return false;
|
||||
|
||||
// First clear the texture
|
||||
SDL_Rect tmp;
|
||||
tmp.x = 0; tmp.y = 0; tmp.w = 256; tmp.h = 64;
|
||||
SDL_FillRect(fontTexture, &tmp,
|
||||
SDL_MapRGBA(fontTexture->format, 0xff, 0xff, 0xff, 0x0));
|
||||
|
||||
// Now fill the texture with font data
|
||||
for(uInt32 lines = 0; lines < 8; lines++)
|
||||
{
|
||||
for(uInt32 x = lines*32; x < (lines+1)*32; x++)
|
||||
{
|
||||
for(uInt32 y = 0; y < 8; y++)
|
||||
{
|
||||
for(uInt32 z = 0; z < 8; z++)
|
||||
{
|
||||
if((ourFontData[(x << 3) + y] >> z) & 1)
|
||||
{
|
||||
tmp.x = ((x-lines*32)<<3) + z;
|
||||
tmp.y = y + lines*8;
|
||||
tmp.w = tmp.h = 1;
|
||||
SDL_FillRect(fontTexture, &tmp,
|
||||
SDL_MapRGBA(fontTexture->format, 0x10, 0x10, 0x10, 0xff));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generate the character coordinates
|
||||
for(uInt32 i = 0; i < 256; i++)
|
||||
{
|
||||
uInt32 row = i / 32;
|
||||
uInt32 col = i - (row*32);
|
||||
|
||||
myFontCoord[i].minX = (GLfloat) (col*8) / 256;
|
||||
myFontCoord[i].maxX = (GLfloat) (col*8+8) / 256;
|
||||
myFontCoord[i].minY = (GLfloat) (row*8) / 64;
|
||||
myFontCoord[i].maxY = (GLfloat) (row*8+8) / 64;
|
||||
}
|
||||
|
||||
glGenTextures(1, &myFontTextureID);
|
||||
glBindTexture(GL_TEXTURE_2D, myFontTextureID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, param);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, param);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
fontTexture->pixels);
|
||||
|
||||
SDL_FreeSurface(fontTexture);
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,232 @@
|
|||
//============================================================================
|
||||
//
|
||||
// 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: FrameBufferGL.hxx,v 1.1 2003-11-06 22:22:32 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef FRAMEBUFFER_GL_HXX
|
||||
#define FRAMEBUFFER_GL_HXX
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL_opengl.h>
|
||||
#include <SDL_syswm.h>
|
||||
|
||||
#include "FrameBuffer.hxx"
|
||||
#include "bspf.hxx"
|
||||
|
||||
class Console;
|
||||
class MediaSource;
|
||||
|
||||
class FrameBufferGL : public FrameBuffer
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Creates a new SDL OpenGL framebuffer
|
||||
*/
|
||||
FrameBufferGL();
|
||||
|
||||
/**
|
||||
Destructor
|
||||
*/
|
||||
virtual ~FrameBufferGL();
|
||||
|
||||
/**
|
||||
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);
|
||||
|
||||
/**
|
||||
Set up the palette for a screen of any depth > 8.
|
||||
Scales the palette by 'shade'.
|
||||
*/
|
||||
void setupPalette(float shade);
|
||||
|
||||
/**
|
||||
Answers if the display is currently in fullscreen mode.
|
||||
*/
|
||||
bool fullScreen() { return isFullscreen; }
|
||||
|
||||
/**
|
||||
Answers the current zoom level of the SDL window
|
||||
*/
|
||||
uInt32 zoomLevel() { return theZoomLevel; }
|
||||
|
||||
private:
|
||||
/**
|
||||
This routine is called whenever the screen needs to be recreated.
|
||||
It updates the global screen variable.
|
||||
*/
|
||||
bool createScreen();
|
||||
|
||||
/**
|
||||
Calculate the maximum window size that the current screen can hold.
|
||||
Only works in X11 for now. If not running under X11, always return 1.
|
||||
*/
|
||||
uInt32 maxWindowSizeForScreen();
|
||||
|
||||
bool createTextures();
|
||||
|
||||
uInt32 power_of_two(uInt32 input)
|
||||
{
|
||||
uInt32 value = 1;
|
||||
while( value < input )
|
||||
value <<= 1;
|
||||
return value;
|
||||
}
|
||||
|
||||
private:
|
||||
// The SDL video buffer
|
||||
SDL_Surface* myScreen;
|
||||
|
||||
// The main texture buffer
|
||||
SDL_Surface* myTexture;
|
||||
|
||||
// The OpenGL main texture handle
|
||||
GLuint myTextureID;
|
||||
|
||||
// OpenGL texture coordinates for the main surface
|
||||
GLfloat myTexCoord[4];
|
||||
|
||||
// The OpenGL font texture handle
|
||||
GLuint myFontTextureID;
|
||||
|
||||
// Structure to hold a characters coordinates
|
||||
struct Coordinates
|
||||
{
|
||||
GLfloat minX;
|
||||
GLfloat maxX;
|
||||
GLfloat minY;
|
||||
GLfloat maxY;
|
||||
};
|
||||
|
||||
// OpenGL texture coordinates for the font surface
|
||||
Coordinates myFontCoord[256];
|
||||
|
||||
// SDL initialization flags
|
||||
uInt32 mySDLFlags;
|
||||
|
||||
// SDL palette
|
||||
uInt32 myPalette[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
|
|
@ -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: FrameBufferSDL.cxx,v 1.1 2003-10-26 19:40:39 stephena Exp $
|
||||
// $Id: FrameBufferSDL.cxx,v 1.2 2003-11-06 22:22:32 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <SDL.h>
|
||||
|
@ -24,7 +24,6 @@
|
|||
#include "FrameBuffer.hxx"
|
||||
#include "FrameBufferSDL.hxx"
|
||||
#include "MediaSrc.hxx"
|
||||
#include "RectList.hxx"
|
||||
#include "Settings.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -609,3 +608,59 @@ void FrameBufferSDL::drawChar(uInt32 xorig, uInt32 yorig, uInt32 c, uInt8 fg)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
RectList::RectList(Uint32 size)
|
||||
{
|
||||
currentSize = size;
|
||||
currentRect = 0;
|
||||
|
||||
rectArray = new SDL_Rect[currentSize];
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
RectList::~RectList()
|
||||
{
|
||||
delete[] rectArray;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void RectList::add(SDL_Rect* newRect)
|
||||
{
|
||||
if(currentRect >= currentSize)
|
||||
{
|
||||
currentSize = currentSize * 2;
|
||||
SDL_Rect *temp = new SDL_Rect[currentSize];
|
||||
|
||||
for(Uint32 i = 0; i < currentRect; ++i)
|
||||
temp[i] = rectArray[i];
|
||||
|
||||
delete[] rectArray;
|
||||
rectArray = temp;
|
||||
}
|
||||
|
||||
rectArray[currentRect].x = newRect->x;
|
||||
rectArray[currentRect].y = newRect->y;
|
||||
rectArray[currentRect].w = newRect->w;
|
||||
rectArray[currentRect].h = newRect->h;
|
||||
|
||||
++currentRect;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
SDL_Rect* RectList::rects()
|
||||
{
|
||||
return rectArray;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Uint32 RectList::numRects()
|
||||
{
|
||||
return currentRect;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void RectList::start()
|
||||
{
|
||||
currentRect = 0;
|
||||
}
|
||||
|
|
|
@ -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: FrameBufferSDL.hxx,v 1.1 2003-10-26 19:40:39 stephena Exp $
|
||||
// $Id: FrameBufferSDL.hxx,v 1.2 2003-11-06 22:22:32 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef FRAMEBUFFER_SDL_HXX
|
||||
|
@ -202,4 +202,25 @@ class FrameBufferSDL : public FrameBuffer
|
|||
bool isFullscreen;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
*/
|
||||
class RectList
|
||||
{
|
||||
public:
|
||||
RectList(Uint32 size = 512);
|
||||
~RectList();
|
||||
|
||||
void add(SDL_Rect* rect);
|
||||
|
||||
SDL_Rect* rects();
|
||||
Uint32 numRects();
|
||||
void start();
|
||||
|
||||
private:
|
||||
Uint32 currentSize, currentRect;
|
||||
|
||||
SDL_Rect* rectArray;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,72 +0,0 @@
|
|||
//============================================================================
|
||||
//
|
||||
// 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: RectList.cxx,v 1.1 2002-03-05 22:39:47 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include "RectList.hxx"
|
||||
|
||||
|
||||
RectList::RectList(Uint32 size)
|
||||
{
|
||||
currentSize = size;
|
||||
currentRect = 0;
|
||||
|
||||
rectArray = new SDL_Rect[currentSize];
|
||||
}
|
||||
|
||||
RectList::~RectList()
|
||||
{
|
||||
delete[] rectArray;
|
||||
}
|
||||
|
||||
void RectList::add(SDL_Rect* newRect)
|
||||
{
|
||||
if(currentRect >= currentSize)
|
||||
{
|
||||
currentSize = currentSize * 2;
|
||||
SDL_Rect *temp = new SDL_Rect[currentSize];
|
||||
|
||||
for(Uint32 i = 0; i < currentRect; ++i)
|
||||
temp[i] = rectArray[i];
|
||||
|
||||
delete[] rectArray;
|
||||
rectArray = temp;
|
||||
}
|
||||
|
||||
rectArray[currentRect].x = newRect->x;
|
||||
rectArray[currentRect].y = newRect->y;
|
||||
rectArray[currentRect].w = newRect->w;
|
||||
rectArray[currentRect].h = newRect->h;
|
||||
|
||||
++currentRect;
|
||||
}
|
||||
|
||||
SDL_Rect* RectList::rects()
|
||||
{
|
||||
return rectArray;
|
||||
}
|
||||
|
||||
Uint32 RectList::numRects()
|
||||
{
|
||||
return currentRect;
|
||||
}
|
||||
|
||||
void RectList::start()
|
||||
{
|
||||
currentRect = 0;
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
//============================================================================
|
||||
//
|
||||
// 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: RectList.hxx,v 1.1 2002-03-05 22:39:47 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef RECT_LIST_HXX
|
||||
#define RECT_LIST_HXX
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
class RectList
|
||||
{
|
||||
public:
|
||||
RectList(Uint32 size = 512);
|
||||
~RectList();
|
||||
|
||||
void add(SDL_Rect* rect);
|
||||
|
||||
SDL_Rect* rects();
|
||||
Uint32 numRects();
|
||||
void start();
|
||||
|
||||
private:
|
||||
Uint32 currentSize, currentRect;
|
||||
|
||||
SDL_Rect* rectArray;
|
||||
};
|
||||
|
||||
#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: SettingsUNIX.cxx,v 1.1 2003-10-26 19:40:39 stephena Exp $
|
||||
// $Id: SettingsUNIX.cxx,v 1.2 2003-11-06 22:22:32 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <cstdlib>
|
||||
|
@ -63,11 +63,15 @@ SettingsUNIX::SettingsUNIX()
|
|||
|
||||
// Now create UNIX specific settings
|
||||
#ifdef DISPLAY_OPENGL
|
||||
set("opengl", "false");
|
||||
set("gl_filter", "nearest");
|
||||
#endif
|
||||
#ifdef SNAPSHOT_SUPPORT
|
||||
set("ssname", "romname");
|
||||
set("ssdir", "./");
|
||||
set("ssingle", "false");
|
||||
#endif
|
||||
set("fullscreen", "false");
|
||||
set("grabmouse", "false");
|
||||
set("center", "false");
|
||||
set("hidecursor", "false");
|
||||
set("accurate", "true");
|
||||
set("volume", "-1");
|
||||
|
@ -89,6 +93,24 @@ void SettingsUNIX::usage(string& message)
|
|||
<< endl
|
||||
<< "Valid options are:" << endl
|
||||
<< endl
|
||||
#ifdef DISPLAY_OPENGL
|
||||
<< " -gl_filter <type> Type is one of the following:\n"
|
||||
<< " nearest Normal scaling (GL_NEAREST)\n"
|
||||
<< " linear Blurred scaling (GL_LINEAR)\n"
|
||||
<< endl
|
||||
#endif
|
||||
<< " -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
|
||||
#ifdef SOUND_SDL
|
||||
<< " SDL Native SDL driver\n"
|
||||
#endif
|
||||
<< 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"
|
||||
|
@ -96,9 +118,6 @@ void SettingsUNIX::usage(string& message)
|
|||
<< " -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"
|
||||
|
@ -114,15 +133,6 @@ void SettingsUNIX::usage(string& message)
|
|||
<< " -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
|
||||
|
|
|
@ -13,13 +13,14 @@
|
|||
// 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.56 2003-10-26 19:40:39 stephena Exp $
|
||||
// $Id: mainSDL.cxx,v 1.57 2003-11-06 22:22:32 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
#include <time.h>
|
||||
|
@ -34,13 +35,18 @@
|
|||
#include "StellaEvent.hxx"
|
||||
#include "EventHandler.hxx"
|
||||
#include "FrameBuffer.hxx"
|
||||
#include "FrameBufferSDL.hxx"
|
||||
#include "PropsSet.hxx"
|
||||
#include "Sound.hxx"
|
||||
#include "Settings.hxx"
|
||||
|
||||
#ifdef DISPLAY_OPENGL
|
||||
#include "FrameBufferGL.hxx"
|
||||
// Pointer to the OpenGL display object or the null pointer
|
||||
static FrameBufferGL* theDisplay = (FrameBufferGL*) NULL;
|
||||
#else
|
||||
#include "FrameBufferSDL.hxx"
|
||||
// Pointer to the software display object or the null pointer
|
||||
static FrameBufferSDL* theDisplay = (FrameBufferSDL*) NULL;
|
||||
#endif
|
||||
|
||||
#ifdef SOUND_ALSA
|
||||
|
@ -83,9 +89,6 @@ static Sound* theSound = (Sound*) NULL;
|
|||
// Pointer to the settings object or the null pointer
|
||||
static Settings* theSettings = (Settings*) NULL;
|
||||
|
||||
// Pointer to the display object or the null pointer
|
||||
static FrameBufferSDL* theDisplay = (FrameBufferSDL*) NULL;
|
||||
|
||||
// Indicates if the mouse should be grabbed
|
||||
static bool theGrabMouseIndicator = false;
|
||||
|
||||
|
@ -201,7 +204,6 @@ static Switches keyList[] = {
|
|||
{ SDLK_CLEAR, StellaEvent::KCODE_CLEAR },
|
||||
{ SDLK_RETURN, StellaEvent::KCODE_RETURN },
|
||||
{ SDLK_ESCAPE, StellaEvent::KCODE_ESCAPE },
|
||||
{ SDLK_SPACE, StellaEvent::KCODE_SPACE },
|
||||
{ SDLK_COMMA, StellaEvent::KCODE_COMMA },
|
||||
{ SDLK_MINUS, StellaEvent::KCODE_MINUS },
|
||||
{ SDLK_PERIOD, StellaEvent::KCODE_PERIOD },
|
||||
|
@ -506,7 +508,7 @@ void handleEvents()
|
|||
{
|
||||
if((event.active.state & SDL_APPACTIVE) && (event.active.gain == 0))
|
||||
{
|
||||
if(!theSettings->pause())
|
||||
if(!theConsole->eventHandler().doPause())
|
||||
{
|
||||
theConsole->eventHandler().sendEvent(Event::Pause, 1);
|
||||
}
|
||||
|
@ -671,6 +673,10 @@ int main(int argc, char* argv[])
|
|||
thePaddleMode = theSettings->getInt("paddle");
|
||||
theShowInfoFlag = theSettings->getBool("showinfo");
|
||||
|
||||
// Request that the SDL window be centered, if possible
|
||||
// This will probably only work under Linux
|
||||
setenv("SDL_VIDEO_CENTERED", "1", 1);
|
||||
|
||||
// Get a pointer to the file which contains the cartridge ROM
|
||||
const char* file = argv[argc - 1];
|
||||
|
||||
|
@ -697,6 +703,24 @@ int main(int argc, char* argv[])
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Create an SDL window
|
||||
#ifdef DISPLAY_OPENGL
|
||||
theDisplay = new FrameBufferGL();
|
||||
if(theShowInfoFlag)
|
||||
cout << "Using OpenGL SDL for video.\n";
|
||||
#else
|
||||
theDisplay = new FrameBufferSDL();
|
||||
if(theShowInfoFlag)
|
||||
cout << "Using software SDL for video.\n";
|
||||
#endif
|
||||
|
||||
if(!theDisplay)
|
||||
{
|
||||
cerr << "ERROR: Couldn't set up display.\n";
|
||||
cleanup();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Create a sound object for playing audio
|
||||
string driver = theSettings->getString("sound");
|
||||
if(driver == "0")
|
||||
|
@ -741,25 +765,9 @@ 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
|
||||
#ifdef DISPLAY_OPENGL
|
||||
bool useGL = theSettings->getBool("opengl");
|
||||
if(useGL)
|
||||
theDisplay = new FrameBufferGL();
|
||||
else
|
||||
#endif
|
||||
theDisplay = new FrameBufferSDL();
|
||||
|
||||
if(!theDisplay)
|
||||
{
|
||||
cerr << "ERROR: Couldn't set up display.\n";
|
||||
cleanup();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Create the 2600 game console
|
||||
theConsole = new Console(image, size, filename, *theSettings, propertiesSet,
|
||||
*theDisplay, theSound->getSampleRate());
|
||||
*theDisplay, *theSound);
|
||||
|
||||
// Free the image since we don't need it any longer
|
||||
delete[] image;
|
||||
|
@ -790,21 +798,13 @@ int main(int argc, char* argv[])
|
|||
for(;;)
|
||||
{
|
||||
// Exit if the user wants to quit
|
||||
if(theSettings->quit())
|
||||
if(theConsole->eventHandler().doQuit())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Call handleEvents here to see if user pressed pause
|
||||
startTime = getTicks();
|
||||
handleEvents();
|
||||
if(theSettings->pause())
|
||||
{
|
||||
theDisplay->update();
|
||||
SDL_Delay(10);
|
||||
continue;
|
||||
}
|
||||
|
||||
theDisplay->update();
|
||||
theSound->updateSound(*theDisplay->mediaSource());
|
||||
|
||||
|
@ -835,24 +835,16 @@ int main(int argc, char* argv[])
|
|||
for(;;)
|
||||
{
|
||||
// Exit if the user wants to quit
|
||||
if(theSettings->quit())
|
||||
if(theConsole->eventHandler().doQuit())
|
||||
{
|
||||
break;
|
||||
}
|
||||
/*
|
||||
startTime = getTicks();
|
||||
handleEvents();
|
||||
if(!theSettings->pause())
|
||||
{
|
||||
theSound->updateSound(*theDisplay->mediaSource());
|
||||
}
|
||||
theDisplay->update();
|
||||
*/
|
||||
|
||||
startTime = getTicks();
|
||||
handleEvents();
|
||||
theDisplay->update();
|
||||
theSound->updateSound(*theDisplay->mediaSource());
|
||||
///
|
||||
|
||||
currentTime = getTicks();
|
||||
virtualTime += timePerFrame;
|
||||
if(currentTime < virtualTime)
|
||||
|
|
|
@ -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: SoundALSA.cxx,v 1.3 2003-02-25 03:12:55 stephena Exp $
|
||||
// $Id: SoundALSA.cxx,v 1.4 2003-11-06 22:22:32 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <alsa/asoundlib.h>
|
||||
|
@ -30,7 +30,8 @@ SoundALSA::SoundALSA()
|
|||
myOriginalVolumeLeft(-1),
|
||||
myOriginalVolumeRight(-1),
|
||||
myBufferSize(0),
|
||||
mySampleRate(0)
|
||||
mySampleRate(0),
|
||||
myPauseStatus(false)
|
||||
{
|
||||
Int32 err;
|
||||
char pcmName[] = "plughw:0,0";
|
||||
|
@ -242,6 +243,9 @@ void SoundALSA::updateSound(MediaSource& mediaSource)
|
|||
{
|
||||
if(myIsInitializedFlag)
|
||||
{
|
||||
if(myPauseStatus)
|
||||
return;
|
||||
|
||||
snd_pcm_sframes_t frames;
|
||||
uInt8 periodCount = 0;
|
||||
|
||||
|
|
|
@ -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: SoundALSA.hxx,v 1.3 2003-02-25 03:12:55 stephena Exp $
|
||||
// $Id: SoundALSA.hxx,v 1.4 2003-11-06 22:22:32 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef SOUNDALSA_HXX
|
||||
|
@ -30,7 +30,7 @@
|
|||
Advanced Linux Sound Architecture (ALSA) version 0.9.x API.
|
||||
|
||||
@author Stephen Anthony
|
||||
@version $Id: SoundALSA.hxx,v 1.3 2003-02-25 03:12:55 stephena Exp $
|
||||
@version $Id: SoundALSA.hxx,v 1.4 2003-11-06 22:22:32 stephena Exp $
|
||||
*/
|
||||
class SoundALSA : public Sound
|
||||
{
|
||||
|
@ -74,6 +74,14 @@ class SoundALSA : public Sound
|
|||
*/
|
||||
void setSoundVolume(Int32 percent);
|
||||
|
||||
/**
|
||||
Sets the pause status. While pause is selected, updateSound()
|
||||
should not play any sound.
|
||||
|
||||
@param status Toggle pause based on status
|
||||
*/
|
||||
void pause(bool status) { myPauseStatus = status; }
|
||||
|
||||
/**
|
||||
Update the sound device using the audio sample from the specified
|
||||
media source.
|
||||
|
@ -110,5 +118,8 @@ class SoundALSA : public Sound
|
|||
|
||||
// PCM sample rate
|
||||
uInt32 mySampleRate;
|
||||
|
||||
// The pause status
|
||||
bool myPauseStatus;
|
||||
};
|
||||
#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: SoundOSS.cxx,v 1.2 2003-02-25 03:12:55 stephena Exp $
|
||||
// $Id: SoundOSS.cxx,v 1.3 2003-11-06 22:22:32 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <fcntl.h>
|
||||
|
@ -39,7 +39,8 @@ SoundOSS::SoundOSS()
|
|||
myDspFd(-1),
|
||||
myMixerFd(-1),
|
||||
myOriginalVolume(-1),
|
||||
mySampleRate(0)
|
||||
mySampleRate(0),
|
||||
myPauseStatus(false)
|
||||
{
|
||||
// Open the sound device for writing
|
||||
if((myDspFd = open(DSP_DEVICE, O_WRONLY, 0)) == -1)
|
||||
|
@ -197,6 +198,9 @@ void SoundOSS::updateSound(MediaSource& mediaSource)
|
|||
{
|
||||
if(myIsInitializedFlag)
|
||||
{
|
||||
if(myPauseStatus)
|
||||
return;
|
||||
|
||||
// Get audio buffer information
|
||||
audio_buf_info info;
|
||||
if(ioctl(myDspFd, SNDCTL_DSP_GETOSPACE, &info) == -1)
|
||||
|
|
|
@ -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: SoundOSS.hxx,v 1.2 2003-02-25 03:12:55 stephena Exp $
|
||||
// $Id: SoundOSS.hxx,v 1.3 2003-11-06 22:22:32 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef SOUNDOSS_HXX
|
||||
|
@ -28,7 +28,7 @@
|
|||
Open Sound System (OSS) API.
|
||||
|
||||
@author Bradford W. Mott
|
||||
@version $Id: SoundOSS.hxx,v 1.2 2003-02-25 03:12:55 stephena Exp $
|
||||
@version $Id: SoundOSS.hxx,v 1.3 2003-11-06 22:22:32 stephena Exp $
|
||||
*/
|
||||
class SoundOSS : public Sound
|
||||
{
|
||||
|
@ -72,6 +72,14 @@ class SoundOSS : public Sound
|
|||
*/
|
||||
void setSoundVolume(Int32 percent);
|
||||
|
||||
/**
|
||||
Sets the pause status. While pause is selected, updateSound()
|
||||
should not play any sound.
|
||||
|
||||
@param status Toggle pause based on status
|
||||
*/
|
||||
void pause(bool status) { myPauseStatus = status; }
|
||||
|
||||
/**
|
||||
Update the sound device using the audio sample from the specified
|
||||
media source.
|
||||
|
@ -95,5 +103,8 @@ class SoundOSS : public Sound
|
|||
|
||||
// DSP sample rate
|
||||
uInt32 mySampleRate;
|
||||
|
||||
// The pause status
|
||||
bool myPauseStatus;
|
||||
};
|
||||
#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: SoundSDL.cxx,v 1.2 2003-02-25 03:12:55 stephena Exp $
|
||||
// $Id: SoundSDL.cxx,v 1.3 2003-11-06 22:22:33 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <SDL.h>
|
||||
|
@ -27,7 +27,8 @@ SoundSDL::SoundSDL(bool activate)
|
|||
myIsInitializedFlag(false),
|
||||
myIsMuted(false),
|
||||
mySampleRate(31400),
|
||||
mySampleQueue(mySampleRate)
|
||||
mySampleQueue(mySampleRate),
|
||||
myPauseStatus(false)
|
||||
{
|
||||
if(activate)
|
||||
{
|
||||
|
@ -165,6 +166,9 @@ void SoundSDL::updateSound(MediaSource& mediaSource)
|
|||
{
|
||||
if(myIsInitializedFlag)
|
||||
{
|
||||
if(myPauseStatus)
|
||||
return;
|
||||
|
||||
// Make sure we have exclusive access to the sample queue
|
||||
SDL_LockAudio();
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: SoundSDL.hxx,v 1.2 2003-02-25 03:12:55 stephena Exp $
|
||||
// $Id: SoundSDL.hxx,v 1.3 2003-11-06 22:22:33 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef SOUNDSDL_HXX
|
||||
|
@ -29,7 +29,7 @@
|
|||
This class implements the sound API for SDL.
|
||||
|
||||
@author Stephen Anthony and Bradford W. Mott
|
||||
@version $Id: SoundSDL.hxx,v 1.2 2003-02-25 03:12:55 stephena Exp $
|
||||
@version $Id: SoundSDL.hxx,v 1.3 2003-11-06 22:22:33 stephena Exp $
|
||||
*/
|
||||
class SoundSDL : public Sound
|
||||
{
|
||||
|
@ -80,6 +80,14 @@ class SoundSDL : public Sound
|
|||
*/
|
||||
void setSoundVolume(Int32 percent);
|
||||
|
||||
/**
|
||||
Sets the pause status. While pause is selected, updateSound()
|
||||
should not play any sound.
|
||||
|
||||
@param status Toggle pause based on status
|
||||
*/
|
||||
void pause(bool status) { myPauseStatus = status; }
|
||||
|
||||
/**
|
||||
Update the sound device using the audio sample from the specified
|
||||
media source.
|
||||
|
@ -165,6 +173,9 @@ class SoundSDL : public Sound
|
|||
// Queue which holds samples from the media source before they are played
|
||||
SampleQueue mySampleQueue;
|
||||
|
||||
// The pause status
|
||||
bool myPauseStatus;
|
||||
|
||||
private:
|
||||
// Callback function invoked by the SDL Audio library when it needs data
|
||||
static void callback(void* udata, uInt8* stream, int len);
|
||||
|
|
|
@ -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: mainX11.cxx,v 1.42 2003-09-19 15:45:01 stephena Exp $
|
||||
// $Id: mainX11.cxx,v 1.43 2003-11-06 22:22:33 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <fstream>
|
||||
|
@ -64,7 +64,7 @@
|
|||
#endif
|
||||
|
||||
// function prototypes
|
||||
// FIXME the following will be placed in a Display class eventually ...
|
||||
// the following will be placed in a Display class eventually ...
|
||||
// A graphic context for each of the 2600's colors
|
||||
static GC theGCTable[256];
|
||||
static bool setupDisplay();
|
||||
|
@ -647,7 +647,7 @@ void handleEvents()
|
|||
{
|
||||
resizeWindow(0);
|
||||
}
|
||||
// FIXME - change x to Ctrl-x
|
||||
// change x to Ctrl-x
|
||||
else if((key == XK_g) && (event.type == KeyPress))
|
||||
{
|
||||
// don't change grabmouse in fullscreen mode
|
||||
|
|
Loading…
Reference in New Issue