makefile : cleaned up options, changed method of selecting options, added sdl frontend

Console.cxx :  changed lookup of current rom to be always based on md5sum
Console.hxx :  changed lookup of current rom to be always based on md5sum
Props.cxx :  added method to get rom info based on md5sum
Props.hxx :  added method to get rom info based on md5sum
PropsSet.cxx :  changed storage of properties to a BST based on md5sum
PropsSet.hxx :  changed storage of properties to a BST based on md5sum
OSS.c : added volume command-line argument and mixer functions
SndUnix.cxx :  added code to pass volume to stella-sound process
mainX11.cxx :  major enhancements, see Changelog


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@17 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2002-01-08 17:11:32 +00:00
parent 7d7d406f94
commit 875baa25c2
11 changed files with 1172 additions and 511 deletions

View File

@ -13,51 +13,118 @@
## See the file "license" for information on usage and redistribution of ## See the file "license" for information on usage and redistribution of
## this file, and for a DISCLAIMER OF ALL WARRANTIES. ## this file, and for a DISCLAIMER OF ALL WARRANTIES.
## ##
## $Id: makefile,v 1.2 2001-12-30 18:43:30 bwmott Exp $ ## $Id: makefile,v 1.3 2002-01-08 17:11:32 stephena Exp $
##============================================================================ ##============================================================================
##============================================================================ ##============================================================================
## Development environment options
## ##
## The following options are used during compiling. You may need to ## The following options are used during compiling.
## define some of these on the CXXFLAGS line if you're running on an ## Comment a line out to disable that option, remove comment to enable it.
## "unsupported" system
##
## -DBSPF_BOOL if your C++ compiler doesn't support the bool type
##
## -DSHOW_TIMING if your want some timing information displayed when
## you exit the program
##
## -DDEBUG if you want a 6507 trace written to stdout
##
## -DLINUX_JOYSTICK to include linux joystick driver support
## (requires you to install the joystick kernel module)
##
##============================================================================ ##============================================================================
CXX = g++ ### for normal optimization, full warnings
LD = g++ OPTIMIZATIONS = -O -Wall
### for common optimizations, full warnings except unused vars
# OPTIMIZATIONS = -O2 -Wall -Wno-unused
### this should work with all compilers
# OPTIMIZATIONS =
### to get full optimization under gcc/x Intel based OS's..
# OPTIMIZATIONS = -O3 -mcpu=pentiumpro -march=pentiumpro -Wall -Wno-unused \
# -funroll-loops -fstrength-reduce -fomit-frame-pointer -ffast-math \
# -malign-functions=2 -malign-jumps=2 -malign-loops=2
LDFLAGS =
LDLIBS =
SRC = .. ### if your C++ compiler doesn't support the bool type
CORE = $(SRC)/emucore # BSPF_BOOL = 1
UI = $(SRC)/ui
### if your want some timing information displayed when you exit the program
# SHOW_TIMING = 1
### you want a 6507 trace written to stdout
# DEBUG = 1
### to include linux joystick driver support in the X11 version
### (requires you to install the joystick kernel module)
# LINUX_JOYSTICK = 1
### to include support for saving snapshots in png format
### (X and SDL versions only)
### (requires you to install Imlib2)
# IMLIB2_SNAPSHOT = 1
##============================================================================
## All done, type make to get a list of frontends
## No configurable options below this line ...
##============================================================================
CXX = g++
LD = g++
LDFLAGS =
LDLIBS =
OPTS.X11 =
LIBS.X11 =
CFLAGS.X11 =
OPTS.SDL =
LIBS.SDL =
CFLAGS.SDL =
OPTS.DOS =
SRC = ..
CORE = $(SRC)/emucore
UI = $(SRC)/ui
INCLUDES = -I. -I$(CORE) -I$(CORE)/m6502/src -I$(CORE)/m6502/src/bspf/src INCLUDES = -I. -I$(CORE) -I$(CORE)/m6502/src -I$(CORE)/m6502/src/bspf/src
CXXFLAGS = -O -Wall $(INCLUDES) $(SYS_INCLUDES) CXXFLAGS = $(OPTIMIZATIONS) $(INCLUDES) $(SYS_INCLUDES)
## set the user-defined options
ifdef BSPF_BOOL
OPTS.X11 += -DBSPF_BOOL
OPTS.DOS += -DBSPF_BOOL
endif
ifdef SHOW_TIMING
OPTS.X11 += -DSHOW_TIMING
OPTS.SDL += -DSHOW_TIMING
OPTS.DOS += -DSHOW_TIMING
endif
ifdef DEBUG
OPTS.X11 += -DDEBUG
OPTS.SDL += -DDEBUG
OPTS.DOS += -DDEBUG
endif
ifdef LINUX_JOYSTICK
OPTS.X11 += -DLINUX_JOYSTICK
endif
ifdef IMLIB2_SNAPSHOT
OPTS.X11 += -DIMLIB2_SNAPSHOT
LIBS.X11 += `imlib2-config --libs`
CFLAGS.X11 += `imlib2-config --cflags`
OPTS.SDL += -DIMLIB2_SNAPSHOT
LIBS.SDL += `imlib2-config --libs`
CFLAGS.SDL += `imlib2-config --cflags`
endif
default: default:
@echo "" @echo ""
@echo "To build Stella type: 'make <version>'" @echo "To build Stella type: 'make <version>'"
@echo "You should edit the makefile for extra options"
@echo "" @echo ""
@echo "where <version> is one of:" @echo "<version> is one of:"
@echo "" @echo ""
@echo " dos DOS version using DJGPP" @echo " dos DOS version using DJGPP"
@echo " unix-x Generic Unix X windows version" @echo " unix-x Generic Unix X windows version"
@echo " linux-x Linux X windows version" @echo " linux-x Linux X windows version"
@echo " linux-x-joy Linux X windows version with joystick" @echo " linux-sdl Linux SDL version"
@echo " bsdi-x BSD/OS 4.0 X Windows version" @echo " bsdi-x BSD/OS 4.0 X Windows version"
@echo " solaris-x Solaris X windows version" @echo " solaris-x Solaris X windows version"
@echo "" @echo ""
@ -70,53 +137,69 @@ dos:
CXX="gcc" \ CXX="gcc" \
INCLUDES="$(INCLUDES) -I$(UI)/dos -I$(UI)/sound" \ INCLUDES="$(INCLUDES) -I$(UI)/dos -I$(UI)/sound" \
OPTIONS="-DBSPF_DOS" \ OPTIONS="-DBSPF_DOS" \
OPTIONS+="$(OPTS.DOS)" \
LDFLAGS="" \ LDFLAGS="" \
LDLIBS="" \ LDLIBS="" \
OBJS="mainDOS.o PCJoys.o SndDOS.o sbdrv.o TIASound.o" OBJS="mainDOS.o PCJoys.o SndDOS.o sbdrv.o TIASound.o"
unix-x: unix-x:
make xstella \ make stella.x11 \
INCLUDES="$(INCLUDES) -I$(UI)/x11 -I$(UI)/sound" \ INCLUDES="$(INCLUDES) -I$(UI)/x11 -I$(UI)/sound" \
SYS_INCLUDES="" \ SYS_INCLUDES="" \
OPTIONS="-DBSPF_UNIX" \ OPTIONS="-DBSPF_UNIX" \
OPTIONS+="$(OPTS.X11)" \
LDFLAGS="-L/usr/X11R6/lib" \ LDFLAGS="-L/usr/X11R6/lib" \
LDFLAGS+="$(CFLAGS.X11)" \
LDLIBS="-lX11 -lXext" \ LDLIBS="-lX11 -lXext" \
LDLIBS+="$(LIBS.X11)" \
OBJS="mainX11.o SndUnix.o" OBJS="mainX11.o SndUnix.o"
linux-x: linux-x:
make xstella \ make stella.x11 \
INCLUDES="$(INCLUDES) -I$(UI)/x11 -I$(UI)/sound" \ INCLUDES="$(INCLUDES) -I$(UI)/x11 -I$(UI)/sound" \
SYS_INCLUDES="" \ SYS_INCLUDES="" \
OPTIONS="-DBSPF_UNIX" \ OPTIONS="-DBSPF_UNIX" \
OPTIONS+="$(OPTS.X11)" \
LDFLAGS="-L/usr/X11R6/lib" \ LDFLAGS="-L/usr/X11R6/lib" \
LDFLAGS+="$(CFLAGS.X11)" \
LDLIBS="-lX11 -lXext" \ LDLIBS="-lX11 -lXext" \
LDLIBS+="$(LIBS.X11)" \
OBJS="mainX11.o SndUnix.o" OBJS="mainX11.o SndUnix.o"
linux-x-joy: linux-sdl:
make xstella \ make stella.sdl \
INCLUDES="$(INCLUDES) -I$(UI)/x11 -I$(UI)/sound" \ INCLUDES="$(INCLUDES) -I$(UI)/sdl -I$(UI)/sound" \
SYS_INCLUDES="" \ SYS_INCLUDES="" \
OPTIONS="-DBSPF_UNIX -DLINUX_JOYSTICK" \ OPTIONS="-DBSPF_UNIX" \
OPTIONS+="$(OPTS.SDL)" \
LDFLAGS="-L/usr/X11R6/lib" \ LDFLAGS="-L/usr/X11R6/lib" \
LDFLAGS+="$(CFLAGS.SDL)" \
LDLIBS="-lX11 -lXext" \ LDLIBS="-lX11 -lXext" \
OBJS="mainX11.o SndUnix.o" LDLIBS+="$(LIBS.SDL)" \
OBJS="mainSDL.o SndUnix.o"
bsdi-x: bsdi-x:
make xstella \ make stella.x11 \
INCLUDES="$(INCLUDES) -I$(UI)/x11 -I$(UI)/sound" \ INCLUDES="$(INCLUDES) -I$(UI)/x11 -I$(UI)/sound" \
SYS_INCLUDES="-I/usr/X11R6/include" \ SYS_INCLUDES="-I/usr/X11R6/include" \
OPTIONS="-DBSPF_UNIX" \ OPTIONS="-DBSPF_UNIX" \
OPTIONS+="$(OPTS.X11)" \
LDFLAGS="-L/usr/X11R6/lib" \ LDFLAGS="-L/usr/X11R6/lib" \
LDFLAGS+="$(CFLAGS.X11)" \
LDLIBS="-lX11 -lXext" \ LDLIBS="-lX11 -lXext" \
LDLIBS+="$(LIBS.X11)" \
OBJS="mainX11.o SndUnix.o" OBJS="mainX11.o SndUnix.o"
solaris-x: solaris-x:
make xstella \ make stella.x11 \
INCLUDES="$(INCLUDES) -I$(UI)/x11 -I$(UI)/sound" \ INCLUDES="$(INCLUDES) -I$(UI)/x11 -I$(UI)/sound" \
SYS_INCLUDES="-I/usr/openwin/include" \ SYS_INCLUDES="-I/usr/openwin/include" \
OPTIONS="-DBSPF_UNIX" \ OPTIONS="-DBSPF_UNIX" \
OPTIONS+="$(OPTS.X11)" \
LDFLAGS="-L/usr/openwin/lib" \ LDFLAGS="-L/usr/openwin/lib" \
LDFLAGS+="$(CFLAGS.X11)" \
LDLIBS="-lX11 -lXext" \ LDLIBS="-lX11 -lXext" \
LDLIBS+="$(LIBS.X11)" \
OBJS="mainX11.o SndUnix.o" OBJS="mainX11.o SndUnix.o"
############################################################################### ###############################################################################
@ -140,8 +223,11 @@ stella.exe: $(CORE_OBJS) $(OBJS)
del a del a
del a.exe del a.exe
xstella: $(CORE_OBJS) $(OBJS) stella.x11: $(CORE_OBJS) $(OBJS)
$(LD) -o xstella $(CORE_OBJS) $(OBJS) $(LDFLAGS) $(LDLIBS) $(LD) -o stella.x11 $(CORE_OBJS) $(OBJS) $(LDFLAGS) $(LDLIBS)
stella.sdl: $(CORE_OBJS) $(OBJS)
$(LD) -o stella.sdl $(CORE_OBJS) $(OBJS) $(LDFLAGS) $(LDLIBS)
M6502Low.ins: $(CORE)/m6502/src/M6502Low.m4 $(CORE)/m6502/src/M6502.m4 M6502Low.ins: $(CORE)/m6502/src/M6502Low.m4 $(CORE)/m6502/src/M6502.m4
m4 $(CORE)/m6502/src/M6502Low.m4 $(CORE)/m6502/src/M6502.m4 > M6502Low.ins m4 $(CORE)/m6502/src/M6502Low.m4 $(CORE)/m6502/src/M6502.m4 > M6502Low.ins
@ -164,7 +250,7 @@ cleandos:
del M6502Hi.ins del M6502Hi.ins
clean: clean:
rm -f *.o stella xstella stella.exe core rm -f *.o stella stella.x11 stella.sdl stella.exe core
cleanall: clean cleanall: clean
rm -f DefProps.def M6502Low.ins M6502Hi.ins rm -f DefProps.def M6502Low.ins M6502Hi.ins
@ -294,7 +380,10 @@ TermX11.o: $(UI)/x11/TermX11.cxx
$(CXX) -c $(CXXFLAGS) $(OPTIONS) $(UI)/x11/TermX11.cxx $(CXX) -c $(CXXFLAGS) $(OPTIONS) $(UI)/x11/TermX11.cxx
mainX11.o: $(UI)/x11/mainX11.cxx mainX11.o: $(UI)/x11/mainX11.cxx
$(CXX) -c $(CXXFLAGS) $(OPTIONS) $(UI)/x11/mainX11.cxx $(CXX) -c $(CXXFLAGS) $(OPTIONS) $(LDFLAGS) $(UI)/x11/mainX11.cxx
mainSDL.o: $(UI)/sdl/mainSDL.cxx
$(CXX) -c $(CXXFLAGS) $(OPTIONS) $(LDFLAGS) $(UI)/sdl/mainSDL.cxx
SndUnix.o: $(UI)/sound/SndUnix.cxx SndUnix.o: $(UI)/sound/SndUnix.cxx
$(CXX) -c $(CXXFLAGS) $(OPTIONS) $(UI)/sound/SndUnix.cxx $(CXX) -c $(CXXFLAGS) $(OPTIONS) $(UI)/sound/SndUnix.cxx

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: Console.cxx,v 1.1.1.1 2001-12-27 19:54:21 bwmott Exp $ // $Id: Console.cxx,v 1.2 2002-01-08 17:11:32 stephena Exp $
//============================================================================ //============================================================================
#include <assert.h> #include <assert.h>
@ -37,31 +37,7 @@
#include "System.hxx" #include "System.hxx"
#include "TIA.hxx" #include "TIA.hxx"
/** #include <iostream>
Compare the two strings s1 and s2 ignoring the case of the
characters. Answers true iff they are equal.
@param s1 The first string to compare
@param s2 The second string to compare
@return true iff the two strings are equal
*/
static bool compare(const string& s1, const string& s2)
{
if(s1.length() != s2.length())
{
return false;
}
for(uInt32 i = 0; i < s1.length(); ++i)
{
if(tolower(s1[i]) != tolower(s2[i]))
{
return false;
}
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Console::Console(const uInt8* image, uInt32 size, const char* filename, Console::Console(const uInt8* image, uInt32 size, const char* filename,
@ -78,34 +54,10 @@ Console::Console(const uInt8* image, uInt32 size, const char* filename,
// Get the MD5 message-digest for the ROM image // Get the MD5 message-digest for the ROM image
string md5 = MD5(image, size); string md5 = MD5(image, size);
// Search through the properties set to see if some exist for this game // Search for the properties based on MD5
for(uInt32 i = 0; i < propertiesSet.size(); ++i) const Properties* properties = propertiesSet.getMD5(md5);
{ if(properties)
const Properties& properties = propertiesSet.get(i); myProperties = properties;
if(properties.get("Cartridge.MD5") == md5)
{
// We have a match so let's use those properties
myProperties = properties;
break;
}
}
// If there was no MD5 match then let's search based on filename
if(md5 != myProperties.get("Cartridge.MD5"))
{
for(uInt32 i = 0; i < propertiesSet.size(); ++i)
{
const Properties& properties = propertiesSet.get(i);
if(compare(properties.get("Cartridge.Filename"), filename))
{
// We have a match so let's use those properties
myProperties = properties;
break;
}
}
}
// TODO: At some point I belive we'll need to set the properties' // TODO: At some point I belive we'll need to set the properties'
// MD5 value so the user will be able to edit it. // MD5 value so the user will be able to edit it.
@ -258,4 +210,3 @@ const Properties& Console::defaultProperties()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Properties Console::ourDefaultProperties; Properties Console::ourDefaultProperties;

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: Console.hxx,v 1.1.1.1 2001-12-27 19:54:21 bwmott Exp $ // $Id: Console.hxx,v 1.2 2002-01-08 17:11:32 stephena Exp $
//============================================================================ //============================================================================
#ifndef CONSOLE_HXX #ifndef CONSOLE_HXX
@ -36,7 +36,7 @@ class System;
This class represents the entire game console. This class represents the entire game console.
@author Bradford W. Mott @author Bradford W. Mott
@version $Id: Console.hxx,v 1.1.1.1 2001-12-27 19:54:21 bwmott Exp $ @version $Id: Console.hxx,v 1.2 2002-01-08 17:11:32 stephena Exp $
*/ */
class Console class Console
{ {
@ -156,4 +156,3 @@ class Console
static Properties ourDefaultProperties; static Properties ourDefaultProperties;
}; };
#endif #endif

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: Props.cxx,v 1.1.1.1 2001-12-27 19:54:23 bwmott Exp $ // $Id: Props.cxx,v 1.2 2002-01-08 17:11:32 stephena Exp $
//============================================================================ //============================================================================
#include "Props.hxx" #include "Props.hxx"
@ -108,32 +108,37 @@ void Properties::load(istream& in)
// Empty my property array // Empty my property array
mySize = 0; mySize = 0;
string line, key, value;
uInt32 one, two, three, four, garbage;
// Loop reading properties // Loop reading properties
for(;;) while(getline(in, line))
{ {
// Get the key associated with this property // Strip all tabs from the line
string key = readQuotedString(in); while((garbage = line.find("\t")) != string::npos)
line.erase(garbage, 1);
// Make sure the stream is still okay // Ignore commented and empty lines
if(!in) if((line.length() == 0) || (line[0] == ';'))
{ continue;
return;
}
// A null key signifies the end of the property list // End of this record
if(key == "") if(line == "\"\"")
{
break; break;
}
// Get the value associated with this property one = line.find("\"", 0);
string value = readQuotedString(in); two = line.find("\"", one + 1);
three = line.find("\"", two + 1);
four = line.find("\"", three + 1);
// Make sure the stream is still okay // Invalid line if it doesn't contain 4 quotes
if(!in) if((one == string::npos) || (two == string::npos) ||
{ (three == string::npos) || (four == string::npos))
return; break;
}
// Otherwise get the key and value
key = line.substr(one + 1, two - one - 1);
value = line.substr(three + 1, four - three - 1);
// Set the property // Set the property
set(key, value); set(key, value);
@ -255,4 +260,3 @@ void Properties::copy(const Properties& properties)
myProperties[i] = properties.myProperties[i]; myProperties[i] = properties.myProperties[i];
} }
} }

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: Props.hxx,v 1.1.1.1 2001-12-27 19:54:23 bwmott Exp $ // $Id: Props.hxx,v 1.2 2002-01-08 17:11:32 stephena Exp $
//============================================================================ //============================================================================
#ifndef PROPERTIES_HXX #ifndef PROPERTIES_HXX
@ -30,7 +30,7 @@
if the property key is not found in the original property list. if the property key is not found in the original property list.
@author Bradford W. Mott @author Bradford W. Mott
@version $Id: Props.hxx,v 1.1.1.1 2001-12-27 19:54:23 bwmott Exp $ @version $Id: Props.hxx,v 1.2 2002-01-08 17:11:32 stephena Exp $
*/ */
class Properties class Properties
{ {
@ -147,4 +147,3 @@ class Properties
unsigned int mySize; unsigned int mySize;
}; };
#endif #endif

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: PropsSet.cxx,v 1.1.1.1 2001-12-27 19:54:23 bwmott Exp $ // $Id: PropsSet.cxx,v 1.2 2002-01-08 17:11:32 stephena Exp $
//============================================================================ //============================================================================
#include <assert.h> #include <assert.h>
@ -21,139 +21,103 @@
#include "PropsSet.hxx" #include "PropsSet.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertiesSet::PropertiesSet(const string& key) PropertiesSet::PropertiesSet()
: myKey(key)
{ {
myCapacity = 16; root = 0;
myProperties = new Properties[myCapacity];
mySize = 0; mySize = 0;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertiesSet::PropertiesSet(const PropertiesSet& p)
: myKey(p.myKey)
{
myCapacity = p.myCapacity;
myProperties = new Properties[myCapacity];
mySize = p.mySize;
// Copy the properties from the other set
for(uInt32 i = 0; i < mySize; ++i)
{
myProperties[i] = p.myProperties[i];
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertiesSet::~PropertiesSet() PropertiesSet::~PropertiesSet()
{ {
delete[] myProperties; deleteNode(root);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const Properties& PropertiesSet::get(uInt32 i) Properties* PropertiesSet::getMD5(string md5)
{ {
// Make sure index is within range // Make sure tree isn't empty
assert(i < mySize); if(root == 0)
return 0;
return myProperties[i]; // Else, do a BST search for the node with the given md5
TreeNode *current = root;
bool found = false;
while(current)
{
string currentMd5 = current->props->get("Cartridge.MD5");
if(currentMd5 == md5)
{
found = true;
break;
}
else
{
if(md5 < currentMd5)
current = current->left;
else
current = current->right;
}
}
if(found)
return current->props;
else
return 0;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PropertiesSet::insert(const Properties& properties) void PropertiesSet::insert(const Properties& properties)
{ {
uInt32 i; insertNode(root, properties);
uInt32 j;
// Get the key of the properties
string name = properties.get(myKey);
// See if the key already exists (we could use a binary search here...)
for(i = 0; i < mySize; ++i)
{
if(name == myProperties[i].get(myKey))
{
// Copy the properties which are being inserted
myProperties[i] = properties;
return;
}
}
// See if the properties array needs to be resized
if(mySize == myCapacity)
{
Properties* newProperties = new Properties[myCapacity *= 2];
for(i = 0; i < mySize; ++i)
{
newProperties[i] = myProperties[i];
}
delete[] myProperties;
myProperties = newProperties;
}
// Find the correct place to insert the properties at
for(i = 0; (i < mySize) && (myProperties[i].get(myKey) < name); ++i);
// Okay, make room for the properties
for(j = mySize; j > i; --j)
{
myProperties[j] = myProperties[j - 1];
}
// Now, put the properties in the array
myProperties[i] = properties;
++mySize;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 PropertiesSet::size() const void PropertiesSet::insertNode(TreeNode* &t, const Properties& properties)
{ {
return mySize; if(t)
{
string md5 = properties.get("Cartridge.MD5");
string currentMd5 = t->props->get("Cartridge.MD5");
if(md5 < currentMd5)
insertNode(t->left, properties);
else if(md5 > currentMd5)
insertNode(t->right, properties);
else
{
delete t->props;
t->props = new Properties(properties);
}
}
else
{
t = new TreeNode;
t->props = new Properties(properties);
t->left = 0;
t->right = 0;
}
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PropertiesSet::erase(uInt32 i) void PropertiesSet::deleteNode(TreeNode *node)
{ {
// Make sure index is within range if(node)
assert(i < mySize);
for(uInt32 j = i + 1; j < mySize; ++j)
{ {
myProperties[j - 1] = myProperties[j]; deleteNode(node->left);
deleteNode(node->right);
delete node->props;
} }
--mySize;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PropertiesSet::load(istream& in, const Properties* defaults) void PropertiesSet::load(istream& in, const Properties* defaults)
{ {
// Empty my properties array
mySize = 0;
// Loop reading properties // Loop reading properties
for(;;) for(;;)
{ {
// Read char's until we see a quote as the next char or EOF is reached
while(in && (in.peek() != '"'))
{
char c;
in.get(c);
// If we see the comment character then ignore the line
if(c == ';')
{
while(in && (c != '\n'))
{
in.get(c);
}
}
}
// Make sure the stream is still good or we're done // Make sure the stream is still good or we're done
if(!in) if(!in)
{ {
@ -175,32 +139,23 @@ void PropertiesSet::load(istream& in, const Properties* defaults)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PropertiesSet::save(ostream& out) void PropertiesSet::save(ostream& out)
{ {
// Write each of the properties out saveNode(out, root);
for(uInt32 i = 0; i < mySize; ++i) }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PropertiesSet::saveNode(ostream& out, TreeNode *node)
{
if(node)
{ {
myProperties[i].save(out); saveNode(out, node->left);
saveNode(out, node->right);
node->props->save(out);
} }
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertiesSet& PropertiesSet::operator = (const PropertiesSet& p) uInt32 PropertiesSet::size() const
{ {
if(this != &p) return mySize;
{
delete[] myProperties;
myKey = p.myKey;
myCapacity = p.myCapacity;
myProperties = new Properties[myCapacity];
mySize = p.mySize;
// Copy the properties from the other set
for(uInt32 i = 0; i < mySize; ++i)
{
myProperties[i] = p.myProperties[i];
}
}
return *this;
} }

View File

@ -13,79 +13,51 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: PropsSet.hxx,v 1.1.1.1 2001-12-27 19:54:23 bwmott Exp $ // $Id: PropsSet.hxx,v 1.2 2002-01-08 17:11:32 stephena Exp $
//============================================================================ //============================================================================
#ifndef PROPERTIESSET_HXX #ifndef PROPERTIESSET_HXX
#define PROPERTIESSET_HXX #define PROPERTIESSET_HXX
class Properties; #include <string>
#include "bspf.hxx" #include "bspf.hxx"
#include "Props.hxx" #include "Props.hxx"
/** class Properties;
This class maintains a sorted collection of properties. Upon
construction one property is distinguished as the key for sorting.
@author Bradford W. Mott /**
@version $Id: PropsSet.hxx,v 1.1.1.1 2001-12-27 19:54:23 bwmott Exp $ This class maintains a sorted collection of properties. The objects
are maintained in a binary search tree sorted by md5, since this is
the attribute most likely to be present in each entry in stella.pro
and least likely to change. A change in MD5 would mean a change in
the game rom image (essentially a different game) and this would
necessitate a new entry in the stella.pro file anyway.
@author Stephen Anthony
*/ */
class PropertiesSet class PropertiesSet
{ {
public: public:
/** /**
Create an empty properties set object using the specified Create an empty properties set object using the md5 as the
property as the key for sorting. key to the BST.
@param key The property to use as the key
*/ */
PropertiesSet(const string& key); PropertiesSet();
/**
Create a properties set object by copying another one
@param set The properties set to copy
*/
PropertiesSet(const PropertiesSet& set);
/** /**
Destructor Destructor
*/ */
virtual ~PropertiesSet(); virtual ~PropertiesSet();
public:
/** /**
Get the i'th properties from the set Get the property from the set with the given MD5.
@param i The index of the properties to get @param md5 The md5 of the property to get
@return The properties stored at the i'th location @return The property with the given MD5, or 0 if not found
*/ */
const Properties& get(uInt32 i); Properties* getMD5(string md5);
/**
Insert the properties into the set. If a duplicate is inserted
the old properties are overwritten with the new ones.
@param properties The collection of properties
*/
void insert(const Properties& properties);
/**
Get the number of properties in the collection.
@return The number of properties in the collection
*/
uInt32 size() const;
/**
Erase the i'th properties from the collection.
@param i The profile index
*/
void erase(uInt32 i);
public:
/** /**
Load properties from the specified input stream. Use the given Load properties from the specified input stream. Use the given
defaults properties as the defaults for any properties loaded. defaults properties as the defaults for any properties loaded.
@ -102,27 +74,61 @@ class PropertiesSet
*/ */
void save(ostream& out); void save(ostream& out);
public:
/** /**
Overloaded assignment operator Get the number of properties in the collection.
@param propertiesSet The properties set to set myself equal to @return The number of properties in the collection
@return Myself after assignment has taken place
*/ */
PropertiesSet& operator = (const PropertiesSet& propertiesSet); uInt32 size() const;
private: private:
struct TreeNode
{
Properties *props;
TreeNode *left;
TreeNode *right;
};
/**
Insert the properties into the set. If a duplicate is inserted
the old properties are overwritten with the new ones.
@param properties The collection of properties
*/
void insert(const Properties& properties);
/**
Insert a node in the bst, keeping the tree sorted.
@param node The current subroot of the tree
@param properties The collection of properties
*/
void insertNode(TreeNode* &node, const Properties& properties);
/**
Deletes a node from the bst. Does not preserve bst sorting.
@param node The current subroot of the tree
*/
void deleteNode(TreeNode *node);
/**
Save current node properties to the specified output stream
@param out The output stream to use
@param node The current subroot of the tree
*/
void saveNode(ostream& out, TreeNode *node);
// The root of the BST
TreeNode* root;
// Property to use as the key // Property to use as the key
string myKey; string myKey;
// Pointer to a dynamically allocated array of properties // The size of the properties bst (i.e. the number of properties in it)
Properties* myProperties; uInt32 mySize;
// Current capacity of the properties array
unsigned int myCapacity;
// The size of the properties array (i.e. the number of properties in it)
unsigned int mySize;
}; };
#endif #endif

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: OSS.c,v 1.1.1.1 2001-12-27 19:54:35 bwmott Exp $ // $Id: OSS.c,v 1.2 2002-01-08 17:11:32 stephena Exp $
//==========================================================================*/ //==========================================================================*/
/** /**
@ -21,7 +21,7 @@
Open Sound System (OSS) API. Open Sound System (OSS) API.
@author Bradford W. Mott @author Bradford W. Mott
@version $Id: OSS.c,v 1.1.1.1 2001-12-27 19:54:35 bwmott Exp $ @version $Id: OSS.c,v 1.2 2002-01-08 17:11:32 stephena Exp $
*/ */
#include <fcntl.h> #include <fcntl.h>
@ -31,6 +31,7 @@
#include <sys/time.h> #include <sys/time.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include <string.h>
#ifdef __FreeBSD__ #ifdef __FreeBSD__
#include <machine/soundcard.h> #include <machine/soundcard.h>
@ -47,11 +48,17 @@
*/ */
unsigned long computeFragmentSize(int sampleRate); unsigned long computeFragmentSize(int sampleRate);
/* Mixer function prototypes */
void openMixer(int changeVolume);
void closeMixer();
/* dsp and mixer file descriptors */
int fd, mixer_fd;
int originalVolume;
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
int fd;
int numberAndSizeOfFragments; int numberAndSizeOfFragments;
int fragmentSize; int fragmentSize;
unsigned char* fragmentBuffer; unsigned char* fragmentBuffer;
@ -59,6 +66,16 @@ int main(int argc, char* argv[])
int format; int format;
int stereo; int stereo;
int mute = 0; int mute = 0;
int newVolume = 75;
if(argc == 3) /* check to see if volume has been given */
{
if(!strncmp(argv[1], "-volume", 7))
{
if((atoi(argv[2]) >= 0) && (atoi(argv[2]) <= 100))
newVolume = atoi(argv[2]);
}
}
/* Open the sound device for writing */ /* Open the sound device for writing */
if((fd = open("/dev/dsp", O_WRONLY, 0)) == -1) if((fd = open("/dev/dsp", O_WRONLY, 0)) == -1)
@ -117,6 +134,8 @@ int main(int argc, char* argv[])
/* Allocate fragment buffer */ /* Allocate fragment buffer */
fragmentBuffer = (unsigned char*)malloc(fragmentSize); fragmentBuffer = (unsigned char*)malloc(fragmentSize);
/* Now open the mixer for changing the volume */
openMixer(newVolume);
/* Initialize the TIA Sound Library */ /* Initialize the TIA Sound Library */
Tia_sound_init(31400, sampleRate); Tia_sound_init(31400, sampleRate);
@ -176,6 +195,8 @@ int main(int argc, char* argv[])
case 6: /* Quit */ case 6: /* Quit */
close(fd); close(fd);
free(fragmentBuffer);
closeMixer();
return 1; return 1;
break; break;
@ -225,3 +246,45 @@ unsigned long computeFragmentSize(int sampleRate)
return 8; return 8;
} }
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
void openMixer(int changeVolume)
{
int volume;
if((mixer_fd = open("/dev/mixer", O_RDWR, 0)) == -1)
{
printf("stella-sound: Unable to open /dev/mixer device!\n");
mixer_fd = 0;
return;
}
volume = 0;
if(ioctl(mixer_fd, MIXER_READ(SOUND_MIXER_PCM), &originalVolume) == -1)
{
printf("stella-sound: Unable to read mixer settings!\n");
close(mixer_fd);
mixer_fd = 0;
return;
}
volume = changeVolume | (changeVolume << 8);
if(ioctl(mixer_fd, MIXER_WRITE(SOUND_MIXER_PCM), &volume) == -1)
{
printf("stella-sound: Unable to set new volume!\n");
close(mixer_fd);
mixer_fd = 0;
return;
}
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
void closeMixer()
{
if(mixer_fd)
{
if(ioctl(mixer_fd, MIXER_WRITE(SOUND_MIXER_PCM), &originalVolume) == -1)
printf("stella-sound: Unable to set original volume!\n");
close(mixer_fd);
}
}

View File

@ -13,18 +13,19 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: SndUnix.cxx,v 1.1.1.1 2001-12-27 19:54:35 bwmott Exp $ // $Id: SndUnix.cxx,v 1.2 2002-01-08 17:11:32 stephena Exp $
//============================================================================ //============================================================================
#include <sys/types.h> #include <sys/types.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <signal.h> #include <signal.h>
#include <unistd.h> #include <unistd.h>
#include <stdio.h>
#include "SndUnix.hxx" #include "SndUnix.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SoundUnix::SoundUnix() SoundUnix::SoundUnix(int volume)
: myDisabled(false), : myDisabled(false),
myMute(false) myMute(false)
{ {
@ -55,7 +56,9 @@ SoundUnix::SoundUnix()
close(pfd[1]); close(pfd[1]);
// Execute the stella-sound server // Execute the stella-sound server
if(execlp("stella-sound", "stella-sound", (char*)0)) char vol[3];
sprintf(vol, "%d", volume);
if(execlp("stella-sound", "stella-sound", "-volume", vol, (char*)0))
{ {
exit(1); exit(1);
} }
@ -87,9 +90,6 @@ SoundUnix::~SoundUnix()
unsigned char command = 0xC0; unsigned char command = 0xC0;
write(myFd, &command, 1); write(myFd, &command, 1);
// Kill the sound server
kill(myProcessId, SIGHUP);
// Close descriptors // Close descriptors
close(myFd); close(myFd);
} }
@ -231,4 +231,3 @@ void SoundUnix::mute(bool state)
// Send sound command to the stella-sound process // Send sound command to the stella-sound process
write(myFd, &command, 1); write(myFd, &command, 1);
} }

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: SndUnix.hxx,v 1.1.1.1 2001-12-27 19:54:35 bwmott Exp $ // $Id: SndUnix.hxx,v 1.2 2002-01-08 17:11:32 stephena Exp $
//============================================================================ //============================================================================
#ifndef SOUNDUNIX_HXX #ifndef SOUNDUNIX_HXX
@ -30,7 +30,7 @@
"stella-sound" process is done through a pipe. "stella-sound" process is done through a pipe.
@author Bradford W. Mott @author Bradford W. Mott
@version $Id: SndUnix.hxx,v 1.1.1.1 2001-12-27 19:54:35 bwmott Exp $ @version $Id: SndUnix.hxx,v 1.2 2002-01-08 17:11:32 stephena Exp $
*/ */
class SoundUnix : public Sound class SoundUnix : public Sound
{ {
@ -38,7 +38,7 @@ class SoundUnix : public Sound
/** /**
Create a new sound object Create a new sound object
*/ */
SoundUnix(); SoundUnix(int volume);
/** /**
Destructor Destructor
@ -84,4 +84,3 @@ class SoundUnix : public Sound
uInt8 myAUDV1; uInt8 myAUDV1;
}; };
#endif #endif

File diff suppressed because it is too large Load Diff