mirror of https://github.com/stella-emu/stella.git
The sound system is now opened once per program invocation, and paused
when it isn't needed. According to SDL this shouldn't be necessary, but some combinations of video modes and audio hardware cause sound to stop working if it's repeatedly opened and closed. So we have to keep it open. Always attempt to use 2 channels (aka stereo) when opening the SDL audio device. This is now required, since ROMs can request mono or stereo mode, and the sound system can no longer be closed and re-opened with the desired settings. So we need to always use 2 channels to accommodate when it might be needed. This actually more closely emulates the 2600, which does have two audio channels. The 'mono' vs 'stereo' ROM property basically controls whether these channels are exposed (ie, does the virtual console have two-channel audio hardware installed). In that sense, these settings control how the channels are mixed. Updated some settings to have more reasonable defaults. Added acknowledgement for people that have donated hardware to help with development. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2291 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
9d93318450
commit
56694b5934
28
Changes.txt
28
Changes.txt
|
@ -14,27 +14,30 @@
|
||||||
|
|
||||||
3.4.1 to 3.5: (December xx, 2011)
|
3.4.1 to 3.5: (December xx, 2011)
|
||||||
|
|
||||||
FIXME (will I have time for this?)
|
|
||||||
* Replaced NTSC TV filtering with Blargg NTSC filters. These filters
|
|
||||||
work in OpenGL mode only, but in contrast to the old filters, they
|
|
||||||
now work with OpenGL 1.x / OpenGL ES.
|
|
||||||
|
|
||||||
* Added several improvements to the joystick management code. Joystick
|
* Added several improvements to the joystick management code. Joystick
|
||||||
event mapping is now saved per device, meaning that if you map events
|
event mapping is now saved per device, meaning that if you map events
|
||||||
to a certain joystick device, remove the device and then later insert
|
to a certain joystick device, remove the device and then later insert
|
||||||
it again, Stella will remember the original mapping.
|
it again, Stella will remember the original mapping.
|
||||||
|
|
||||||
* The total number of joysticks present and their associated properties
|
* The total number of joysticks present and their associated properties
|
||||||
(number of axes, buttons, hats, etc) is now dynamic. That is, there's
|
(number of axes, buttons and hats) is now dynamic. That is, there's
|
||||||
no longer a hard-coded limit on number of joysticks that Stella can
|
no longer a hard-coded limit on the number of joysticks that Stella
|
||||||
use, or the number of buttons, etc that it contains. This fixes a
|
can use, or the number of buttons, etc that it contains. This fixes
|
||||||
serious bug with PS3 controllers with 27 buttons, whereby adding a
|
a serious bug with PS3 controllers with 27 buttons, whereby adding a
|
||||||
mapping for joystick 0 would inadvertantly change settings for
|
mapping for joystick 0 would inadvertantly change settings for
|
||||||
joystick 1, and could potentially lead to a segfault.
|
joystick 1, and could potentially lead to a program crash.
|
||||||
|
|
||||||
* Huge restructuring of the OpenGL code, making it compatible with
|
* Huge restructuring of the OpenGL code, making it compatible with
|
||||||
OpenGL 2.x+ features (such as vertex buffer objects), while at the
|
OpenGL 2.x+ features (such as vertex buffer objects), while at the
|
||||||
same time keeping compatibility with OpenGL 1.5 / OpenGL ES.
|
same time keeping compatibility with OpenGL 1.5 / OpenGL ES.
|
||||||
|
Because of the required changes, TV effects were removed (they will
|
||||||
|
be added again for the next release).
|
||||||
|
|
||||||
|
* Improvements to audio handling, particularly for certain cases of
|
||||||
|
Windows, ATI video cards, and OpenGL mode. The sound device is now
|
||||||
|
opened only once when Stella starts, and is paused between loading
|
||||||
|
different ROMs. This fixes a problem whereby sound could possibly
|
||||||
|
not be functional after loading the first ROM.
|
||||||
|
|
||||||
* Added logging facility, whereby the output of the application is
|
* Added logging facility, whereby the output of the application is
|
||||||
available within Stella itself. This can still be printed to the
|
available within Stella itself. This can still be printed to the
|
||||||
|
@ -56,7 +59,7 @@
|
||||||
can be disabled by developers for testing reasons.
|
can be disabled by developers for testing reasons.
|
||||||
|
|
||||||
* Updated default snapshot directory to be much saner and easier to
|
* Updated default snapshot directory to be much saner and easier to
|
||||||
find. For most systems, it now defaults to the users 'Desktop.
|
find. For most systems, it now defaults to the users 'Desktop'.
|
||||||
Note that the commandline argument has changed to 'snapdir'.
|
Note that the commandline argument has changed to 'snapdir'.
|
||||||
|
|
||||||
* The debugger 'print' command now indicates "special" addresses if
|
* The debugger 'print' command now indicates "special" addresses if
|
||||||
|
@ -72,6 +75,9 @@
|
||||||
|
|
||||||
* Updated include PNG library to latest stable version.
|
* Updated include PNG library to latest stable version.
|
||||||
|
|
||||||
|
* Updated the credits list in the documentation, listing people that
|
||||||
|
have donated hardware to the Stella team.
|
||||||
|
|
||||||
-Have fun!
|
-Have fun!
|
||||||
|
|
||||||
|
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.5 KiB |
|
@ -267,7 +267,7 @@
|
||||||
<li>Supports EEPROM emulation for <a href="http://www.richard.hutchinson.dsl.pipex.com/new_page_5.htm">
|
<li>Supports EEPROM emulation for <a href="http://www.richard.hutchinson.dsl.pipex.com/new_page_5.htm">
|
||||||
AtariVox</a> and <a href="http://www.vectrex.biz/MemCard.htm">SaveKey</a> controllers</li>
|
AtariVox</a> and <a href="http://www.vectrex.biz/MemCard.htm">SaveKey</a> controllers</li>
|
||||||
<li>Supports all known bankswitching schemes (let us know if there's one we missed)</li>
|
<li>Supports all known bankswitching schemes (let us know if there's one we missed)</li>
|
||||||
<li>Supports DPC+ bankswitching scheme from the Harmony cart, including emulation of the ARM processor</li>
|
<li>Supports DPC+ bankswitching scheme from the Harmony cart, including partial emulation of the ARM processor</li>
|
||||||
<li>Supports cartridge autodetection for almost all bankswitching schemes</li>
|
<li>Supports cartridge autodetection for almost all bankswitching schemes</li>
|
||||||
<li>Supports Supercharger single-load and multi-load games</li>
|
<li>Supports Supercharger single-load and multi-load games</li>
|
||||||
<li>Supports ROMs stored in ZIP and GZIP format, as well as the usual A26/BIN/ROM formats</li>
|
<li>Supports ROMs stored in ZIP and GZIP format, as well as the usual A26/BIN/ROM formats</li>
|
||||||
|
@ -2232,8 +2232,8 @@
|
||||||
<table border="1" cellpadding="4">
|
<table border="1" cellpadding="4">
|
||||||
<tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">CommandLine</a></th></tr>
|
<tr><th>Item</th><th>Brief description</th><th>For more information,<br>see <a href="#CommandLine">CommandLine</a></th></tr>
|
||||||
<tr><td>Volume</td><td>self-explanatory</td><td>-volume</td></tr>
|
<tr><td>Volume</td><td>self-explanatory</td><td>-volume</td></tr>
|
||||||
<tr><td>Fragment size</td><td>set size of audio buffers</td><td>-fragsize</td></tr>
|
<tr><td>Sample size (*)</td><td>set size of audio buffers</td><td>-fragsize</td></tr>
|
||||||
<tr><td>Output freq</td><td>change sound output frequency (advanced)</td><td>-freq</td></tr>
|
<tr><td>Output freq (*)</td><td>change sound output frequency (advanced)</td><td>-freq</td></tr>
|
||||||
<tr><td>TIA freq</td><td>change TIA output frequency (advanced)</td><td>-tiafreq</td></tr>
|
<tr><td>TIA freq</td><td>change TIA output frequency (advanced)</td><td>-tiafreq</td></tr>
|
||||||
<tr><td>Clip volume</td><td>Eliminate popping in sound generation (advanced)</td><td>-clipvol</td></tr>
|
<tr><td>Clip volume</td><td>Eliminate popping in sound generation (advanced)</td><td>-clipvol</td></tr>
|
||||||
<tr><td>Enable sound</td><td>self-explanatory</td><td>-sound</td></tr>
|
<tr><td>Enable sound</td><td>self-explanatory</td><td>-sound</td></tr>
|
||||||
|
@ -3263,6 +3263,12 @@ Ms Pac-Man (Stella extended codes):
|
||||||
<td>Provided technical information on the Supercharger</td>
|
<td>Provided technical information on the Supercharger</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td VALIGN="TOP">"Uncle" Carmine<br>
|
||||||
|
(<a href="http://www.carmine.com">http://www.carmine.com</a>)</td>
|
||||||
|
<td>Generously donated several 2600 games and manuals to help with development</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td VALIGN="TOP">Piero Cavina</td>
|
<td VALIGN="TOP">Piero Cavina</td>
|
||||||
<td>Allowed "Oystron" to be included in the Stella distribution</td>
|
<td>Allowed "Oystron" to be included in the Stella distribution</td>
|
||||||
|
@ -3344,6 +3350,12 @@ Ms Pac-Man (Stella extended codes):
|
||||||
in testing ROMs on a real system</td>
|
in testing ROMs on a real system</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td VALIGN="TOP">Nick Montfort and Ian Bogost<br>
|
||||||
|
(<a href="http://mitpress.mit.edu/catalog/item/default.asp?ttype=2&tid=11696">Racing the Beam</a>)</td>
|
||||||
|
<td>Specifically mentioned Stella in their book</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td VALIGN="TOP">Kostas Nakos</td>
|
<td VALIGN="TOP">Kostas Nakos</td>
|
||||||
<td>Author/maintainer of the WinCE version of Stella from releases 2.0
|
<td>Author/maintainer of the WinCE version of Stella from releases 2.0
|
||||||
|
@ -3413,6 +3425,12 @@ Ms Pac-Man (Stella extended codes):
|
||||||
<td>Author of the "Game Menu" emulator game shell</td>
|
<td>Author of the "Game Menu" emulator game shell</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td VALIGN="TOP">James Randall aka 'toymailman'</td>
|
||||||
|
<td>Generously donated a 7800 console and several games and manuals to help
|
||||||
|
with development</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td VALIGN="TOP">RomHunter<br>(<a href="http://www.atarimania.com/roms-MENU-2.html">RomHunter ROMs</a>)</td>
|
<td VALIGN="TOP">RomHunter<br>(<a href="http://www.atarimania.com/roms-MENU-2.html">RomHunter ROMs</a>)</td>
|
||||||
<td>Provides an updated database of ROM information on a regular basis</td>
|
<td>Provides an updated database of ROM information on a regular basis</td>
|
||||||
|
@ -3536,7 +3554,7 @@ Ms Pac-Man (Stella extended codes):
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td VALIGN="TOP">Albert Yarusso<br>
|
<td VALIGN="TOP">Albert Yarusso<br>
|
||||||
<a href="http://atariage.com">http://atariage.com</a></td>
|
(<a href="http://atariage.com">http://atariage.com</a>)</td>
|
||||||
<td>Provided helpful feedback for the MacOSX port, and generously
|
<td>Provided helpful feedback for the MacOSX port, and generously
|
||||||
donated an AtariVox device to help with development</td>
|
donated an AtariVox device to help with development</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -69,15 +69,15 @@ string FrameBufferSoft::about() const
|
||||||
{
|
{
|
||||||
ostringstream buf;
|
ostringstream buf;
|
||||||
|
|
||||||
buf << "Video rendering: Software mode" << endl
|
buf << "Video rendering: Software mode" << endl << setfill('0')
|
||||||
<< " Color: " << (int)myFormat->BitsPerPixel << " bit" << endl
|
<< " Color: " << (int)myFormat->BitsPerPixel << " bit" << endl
|
||||||
<< " Rmask = " << hex << setw(4) << (int)myFormat->Rmask
|
<< " Rmask = " << hex << setw(8) << (int)myFormat->Rmask
|
||||||
<< ", Rshift = "<< dec << setw(2) << (int)myFormat->Rshift
|
<< ", Rshift = "<< dec << setw(2) << (int)myFormat->Rshift
|
||||||
<< ", Rloss = " << dec << setw(2) << (int)myFormat->Rloss << endl
|
<< ", Rloss = " << dec << setw(2) << (int)myFormat->Rloss << endl
|
||||||
<< " Gmask = " << hex << setw(4) << (int)myFormat->Gmask
|
<< " Gmask = " << hex << setw(8) << (int)myFormat->Gmask
|
||||||
<< ", Gshift = "<< dec << setw(2) << (int)myFormat->Gshift
|
<< ", Gshift = "<< dec << setw(2) << (int)myFormat->Gshift
|
||||||
<< ", Gloss = " << dec << setw(2) << (int)myFormat->Gloss << endl
|
<< ", Gloss = " << dec << setw(2) << (int)myFormat->Gloss << endl
|
||||||
<< " Bmask = " << hex << setw(4) << (int)myFormat->Bmask
|
<< " Bmask = " << hex << setw(8) << (int)myFormat->Bmask
|
||||||
<< ", Bshift = "<< dec << setw(2) << (int)myFormat->Bshift
|
<< ", Bshift = "<< dec << setw(2) << (int)myFormat->Bshift
|
||||||
<< ", Bloss = " << dec << setw(2) << (int)myFormat->Bloss << endl;
|
<< ", Bloss = " << dec << setw(2) << (int)myFormat->Bloss << endl;
|
||||||
|
|
||||||
|
|
|
@ -90,13 +90,6 @@ class SoundNull : public Sound
|
||||||
*/
|
*/
|
||||||
void close() { }
|
void close() { }
|
||||||
|
|
||||||
/**
|
|
||||||
Return true iff the sound device was successfully initialized.
|
|
||||||
|
|
||||||
@return true iff the sound device was successfully initialized.
|
|
||||||
*/
|
|
||||||
bool isSuccessfullyInitialized() const { return false; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Set the mute state of the sound object. While muted no sound is played.
|
Set the mute state of the sound object. While muted no sound is played.
|
||||||
|
|
||||||
|
|
|
@ -35,39 +35,88 @@
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
SoundSDL::SoundSDL(OSystem* osystem)
|
SoundSDL::SoundSDL(OSystem* osystem)
|
||||||
: Sound(osystem),
|
: Sound(osystem),
|
||||||
myIsEnabled(osystem->settings().getBool("sound")),
|
myIsEnabled(false),
|
||||||
myIsInitializedFlag(false),
|
myIsInitializedFlag(false),
|
||||||
myLastRegisterSetCycle(0),
|
myLastRegisterSetCycle(0),
|
||||||
myDisplayFrameRate(60.0),
|
myDisplayFrameRate(60.0),
|
||||||
myNumChannels(1),
|
myNumChannels(0),
|
||||||
myFragmentSizeLogBase2(0),
|
myFragmentSizeLogBase2(0),
|
||||||
myIsMuted(false),
|
myIsMuted(true),
|
||||||
myVolume(100)
|
myVolume(100)
|
||||||
{
|
{
|
||||||
|
myOSystem->logMessage("SoundSDL::SoundSDL started ...\n", 2);
|
||||||
|
|
||||||
|
// The sound system is opened only once per program run, to eliminate
|
||||||
|
// issues with opening and closing it multiple times
|
||||||
|
// This fixes a bug most prevalent with ATI video cards in Windows,
|
||||||
|
// whereby sound stopped working after the first video change
|
||||||
|
SDL_AudioSpec desired;
|
||||||
|
desired.freq = myOSystem->settings().getInt("freq");
|
||||||
|
desired.format = AUDIO_U8;
|
||||||
|
desired.channels = 2;
|
||||||
|
desired.samples = myOSystem->settings().getInt("fragsize");
|
||||||
|
desired.callback = callback;
|
||||||
|
desired.userdata = (void*)this;
|
||||||
|
|
||||||
|
ostringstream buf;
|
||||||
|
if(SDL_OpenAudio(&desired, &myHardwareSpec) < 0)
|
||||||
|
{
|
||||||
|
buf << "WARNING: Couldn't open SDL audio system! " << endl
|
||||||
|
<< " " << SDL_GetError() << endl;
|
||||||
|
myOSystem->logMessage(buf.str(), 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the sample buffer isn't to big (if it is the sound code
|
||||||
|
// will not work so we'll need to disable the audio support)
|
||||||
|
if(((float)myHardwareSpec.samples / (float)myHardwareSpec.freq) >= 0.25)
|
||||||
|
{
|
||||||
|
buf << "WARNING: Sound device doesn't support realtime audio! Make "
|
||||||
|
<< "sure a sound" << endl
|
||||||
|
<< " server isn't running. Audio is disabled." << endl;
|
||||||
|
myOSystem->logMessage(buf.str(), 0);
|
||||||
|
|
||||||
|
SDL_CloseAudio();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
myIsInitializedFlag = true;
|
||||||
|
SDL_PauseAudio(1);
|
||||||
|
|
||||||
|
myOSystem->logMessage("SoundSDL::SoundSDL initialized\n", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
SoundSDL::~SoundSDL()
|
SoundSDL::~SoundSDL()
|
||||||
{
|
{
|
||||||
// Close the SDL audio system if it's initialized
|
// Close the SDL audio system if it's initialized
|
||||||
close();
|
if(myIsInitializedFlag)
|
||||||
|
{
|
||||||
|
SDL_CloseAudio();
|
||||||
|
myIsEnabled = myIsInitializedFlag = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
myOSystem->logMessage("SoundSDL destroyed\n", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void SoundSDL::setEnabled(bool state)
|
void SoundSDL::setEnabled(bool state)
|
||||||
{
|
{
|
||||||
myIsEnabled = state;
|
|
||||||
myOSystem->settings().setBool("sound", state);
|
myOSystem->settings().setBool("sound", state);
|
||||||
|
|
||||||
|
myOSystem->logMessage(state ? "SoundSDL::setEnabled(true)\n" :
|
||||||
|
"SoundSDL::setEnabled(false)\n", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void SoundSDL::open()
|
void SoundSDL::open()
|
||||||
{
|
{
|
||||||
// Check whether to start the sound subsystem
|
myOSystem->logMessage("SoundSDL::open started ...\n", 2);
|
||||||
if(!myIsEnabled)
|
myIsEnabled = false;
|
||||||
|
mute(true);
|
||||||
|
if(!myIsInitializedFlag || !myOSystem->settings().getBool("sound"))
|
||||||
{
|
{
|
||||||
close();
|
myOSystem->logMessage("Sound disabled\n\n", 1);
|
||||||
myOSystem->logMessage("Sound disabled.\n\n", 1);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,98 +124,48 @@ void SoundSDL::open()
|
||||||
myRegWriteQueue.clear();
|
myRegWriteQueue.clear();
|
||||||
myTIASound.reset();
|
myTIASound.reset();
|
||||||
|
|
||||||
if(SDL_WasInit(SDL_INIT_AUDIO) == 0)
|
myFragmentSizeLogBase2 = log((double)myHardwareSpec.samples) / log(2.0);
|
||||||
{
|
|
||||||
myIsInitializedFlag = false;
|
|
||||||
myIsMuted = false;
|
|
||||||
myLastRegisterSetCycle = 0;
|
|
||||||
|
|
||||||
uInt32 fragsize = myOSystem->settings().getInt("fragsize");
|
// Now initialize the TIASound object which will actually generate sound
|
||||||
Int32 frequency = myOSystem->settings().getInt("freq");
|
int tiafreq = myOSystem->settings().getInt("tiafreq");
|
||||||
Int32 tiafreq = myOSystem->settings().getInt("tiafreq");
|
myTIASound.outputFrequency(myHardwareSpec.freq);
|
||||||
|
myTIASound.tiaFrequency(tiafreq);
|
||||||
|
const string& chanResult =
|
||||||
|
myTIASound.channels(myHardwareSpec.channels, myNumChannels == 2);
|
||||||
|
|
||||||
SDL_AudioSpec desired;
|
bool clipvol = myOSystem->settings().getBool("clipvol");
|
||||||
desired.freq = frequency;
|
myTIASound.clipVolume(clipvol);
|
||||||
#ifndef GP2X
|
|
||||||
desired.format = AUDIO_U8;
|
|
||||||
#else
|
|
||||||
desired.format = AUDIO_U16;
|
|
||||||
#endif
|
|
||||||
desired.channels = myNumChannels;
|
|
||||||
desired.samples = fragsize;
|
|
||||||
desired.callback = callback;
|
|
||||||
desired.userdata = (void*)this;
|
|
||||||
|
|
||||||
ostringstream buf;
|
// Adjust volume to that defined in settings
|
||||||
if(SDL_OpenAudio(&desired, &myHardwareSpec) < 0)
|
myVolume = myOSystem->settings().getInt("volume");
|
||||||
{
|
setVolume(myVolume);
|
||||||
buf << "WARNING: Couldn't open SDL audio system! " << endl
|
|
||||||
<< " " << SDL_GetError() << endl;
|
|
||||||
myOSystem->logMessage(buf.str(), 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure the sample buffer isn't to big (if it is the sound code
|
// Show some info
|
||||||
// will not work so we'll need to disable the audio support)
|
ostringstream buf;
|
||||||
if(((float)myHardwareSpec.samples / (float)myHardwareSpec.freq) >= 0.25)
|
buf << "Sound enabled:" << endl
|
||||||
{
|
<< " Volume: " << (int)myVolume << endl
|
||||||
buf << "WARNING: Sound device doesn't support realtime audio! Make "
|
<< " Frag size: " << (int)myHardwareSpec.samples << endl
|
||||||
<< "sure a sound" << endl
|
<< " Frequency: " << (int)myHardwareSpec.freq << endl
|
||||||
<< " server isn't running. Audio is disabled." << endl;
|
<< " Format: " << (int)myHardwareSpec.format << endl
|
||||||
myOSystem->logMessage(buf.str(), 0);
|
<< " TIA Freq: " << (int)tiafreq << endl
|
||||||
|
<< " Channels: " << (int)myHardwareSpec.channels
|
||||||
SDL_CloseAudio();
|
<< " (" << chanResult << ")" << endl
|
||||||
return;
|
<< " Clip volume: " << (clipvol ? "on" : "off") << endl
|
||||||
}
|
<< endl;
|
||||||
|
myOSystem->logMessage(buf.str(), 1);
|
||||||
myIsInitializedFlag = true;
|
|
||||||
myIsMuted = false;
|
|
||||||
myFragmentSizeLogBase2 = log((double)myHardwareSpec.samples) / log(2.0);
|
|
||||||
|
|
||||||
// Now initialize the TIASound object which will actually generate sound
|
|
||||||
myTIASound.outputFrequency(myHardwareSpec.freq);
|
|
||||||
myTIASound.tiaFrequency(tiafreq);
|
|
||||||
myTIASound.channels(myHardwareSpec.channels);
|
|
||||||
|
|
||||||
bool clipvol = myOSystem->settings().getBool("clipvol");
|
|
||||||
myTIASound.clipVolume(clipvol);
|
|
||||||
|
|
||||||
// Adjust volume to that defined in settings
|
|
||||||
myVolume = myOSystem->settings().getInt("volume");
|
|
||||||
setVolume(myVolume);
|
|
||||||
|
|
||||||
// Show some info
|
|
||||||
buf << "Sound enabled:" << endl
|
|
||||||
<< " Volume: " << myVolume << endl
|
|
||||||
<< " Frag size: " << fragsize << endl
|
|
||||||
<< " Frequency: " << myHardwareSpec.freq << endl
|
|
||||||
<< " Format: " << myHardwareSpec.format << endl
|
|
||||||
<< " TIA Freq: " << tiafreq << endl
|
|
||||||
<< " Channels: " << myNumChannels << endl
|
|
||||||
<< " Clip volume: " << (int)clipvol << endl
|
|
||||||
<< endl;
|
|
||||||
myOSystem->logMessage(buf.str(), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// And start the SDL sound subsystem ...
|
// And start the SDL sound subsystem ...
|
||||||
if(myIsInitializedFlag)
|
myIsEnabled = true;
|
||||||
SDL_PauseAudio(0);
|
mute(false);
|
||||||
|
|
||||||
|
myOSystem->logMessage("SoundSDL::open finished\n", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void SoundSDL::close()
|
void SoundSDL::close()
|
||||||
{
|
{
|
||||||
if(myIsInitializedFlag)
|
mute(true);
|
||||||
{
|
myOSystem->logMessage("SoundSDL::close\n", 2);
|
||||||
SDL_CloseAudio();
|
|
||||||
myIsInitializedFlag = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
bool SoundSDL::isSuccessfullyInitialized() const
|
|
||||||
{
|
|
||||||
return myIsInitializedFlag;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -175,9 +174,7 @@ void SoundSDL::mute(bool state)
|
||||||
if(myIsInitializedFlag)
|
if(myIsInitializedFlag)
|
||||||
{
|
{
|
||||||
myIsMuted = state;
|
myIsMuted = state;
|
||||||
|
|
||||||
SDL_PauseAudio(myIsMuted ? 1 : 0);
|
SDL_PauseAudio(myIsMuted ? 1 : 0);
|
||||||
myRegWriteQueue.clear();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,7 +280,7 @@ void SoundSDL::set(uInt16 addr, uInt8 value, Int32 cycle)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void SoundSDL::processFragment(uInt8* stream, Int32 length)
|
void SoundSDL::processFragment(uInt8* stream, Int32 length)
|
||||||
{
|
{
|
||||||
if(!myIsInitializedFlag)
|
if(!myIsEnabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uInt32 channels = myHardwareSpec.channels;
|
uInt32 channels = myHardwareSpec.channels;
|
||||||
|
@ -425,13 +422,12 @@ bool SoundSDL::load(Serializer& in)
|
||||||
if(in.getString() != name())
|
if(in.getString() != name())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uInt8 reg1 = 0, reg2 = 0, reg3 = 0, reg4 = 0, reg5 = 0, reg6 = 0;
|
uInt8 reg1 = (uInt8) in.getByte(),
|
||||||
reg1 = (uInt8) in.getByte();
|
reg2 = (uInt8) in.getByte(),
|
||||||
reg2 = (uInt8) in.getByte();
|
reg3 = (uInt8) in.getByte(),
|
||||||
reg3 = (uInt8) in.getByte();
|
reg4 = (uInt8) in.getByte(),
|
||||||
reg4 = (uInt8) in.getByte();
|
reg5 = (uInt8) in.getByte(),
|
||||||
reg5 = (uInt8) in.getByte();
|
reg6 = (uInt8) in.getByte();
|
||||||
reg6 = (uInt8) in.getByte();
|
|
||||||
|
|
||||||
myLastRegisterSetCycle = (Int32) in.getInt();
|
myLastRegisterSetCycle = (Int32) in.getInt();
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ class SoundSDL : public Sound
|
||||||
/**
|
/**
|
||||||
Enables/disables the sound subsystem.
|
Enables/disables the sound subsystem.
|
||||||
|
|
||||||
@param state True or false, to enable or disable the sound system
|
@param state True or false, to enable or disable the sound system
|
||||||
*/
|
*/
|
||||||
void setEnabled(bool state);
|
void setEnabled(bool state);
|
||||||
|
|
||||||
|
@ -62,14 +62,18 @@ class SoundSDL : public Sound
|
||||||
The system cycle counter is being adjusting by the specified amount. Any
|
The system cycle counter is being adjusting by the specified amount. Any
|
||||||
members using the system cycle counter should be adjusted as needed.
|
members using the system cycle counter should be adjusted as needed.
|
||||||
|
|
||||||
@param amount The amount the cycle counter is being adjusted by
|
@param amount The amount the cycle counter is being adjusted by
|
||||||
*/
|
*/
|
||||||
void adjustCycleCounter(Int32 amount);
|
void adjustCycleCounter(Int32 amount);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Sets the number of channels (mono or stereo sound).
|
Sets the number of channels (mono or stereo sound). Note that this
|
||||||
|
determines how the emulation should 'mix' the channels of the TIA sound
|
||||||
|
system (of which there are always two). It does not specify the actual
|
||||||
|
number of hardware channels that SDL should use; it will always attempt
|
||||||
|
to use two channels in hardware.
|
||||||
|
|
||||||
@param channels The number of channels
|
@param channels The number of channels
|
||||||
*/
|
*/
|
||||||
void setChannels(uInt32 channels);
|
void setChannels(uInt32 channels);
|
||||||
|
|
||||||
|
@ -93,17 +97,10 @@ class SoundSDL : public Sound
|
||||||
*/
|
*/
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
/**
|
|
||||||
Return true iff the sound device was successfully initialized.
|
|
||||||
|
|
||||||
@return true iff the sound device was successfully initialized.
|
|
||||||
*/
|
|
||||||
bool isSuccessfullyInitialized() const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Set the mute state of the sound object. While muted no sound is played.
|
Set the mute state of the sound object. While muted no sound is played.
|
||||||
|
|
||||||
@param state Mutes sound if true, unmute if false
|
@param state Mutes sound if true, unmute if false
|
||||||
*/
|
*/
|
||||||
void mute(bool state);
|
void mute(bool state);
|
||||||
|
|
||||||
|
@ -115,9 +112,9 @@ class SoundSDL : public Sound
|
||||||
/**
|
/**
|
||||||
Sets the sound register to a given value.
|
Sets the sound register to a given value.
|
||||||
|
|
||||||
@param addr The register address
|
@param addr The register address
|
||||||
@param value The value to save into the register
|
@param value The value to save into the register
|
||||||
@param cycle The system cycle at which the register is being updated
|
@param cycle The system cycle at which the register is being updated
|
||||||
*/
|
*/
|
||||||
void set(uInt16 addr, uInt8 value, Int32 cycle);
|
void set(uInt16 addr, uInt8 value, Int32 cycle);
|
||||||
|
|
||||||
|
@ -126,15 +123,15 @@ class SoundSDL : public Sound
|
||||||
volume is given as a percentage from 0 to 100. Values outside
|
volume is given as a percentage from 0 to 100. Values outside
|
||||||
this range indicate that the volume shouldn't be changed at all.
|
this range indicate that the volume shouldn't be changed at all.
|
||||||
|
|
||||||
@param percent The new volume percentage level for the sound device
|
@param percent The new volume percentage level for the sound device
|
||||||
*/
|
*/
|
||||||
void setVolume(Int32 percent);
|
void setVolume(Int32 percent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Adjusts the volume of the sound device based on the given direction.
|
Adjusts the volume of the sound device based on the given direction.
|
||||||
|
|
||||||
@param direction Increase or decrease the current volume by a predefined
|
@param direction Increase or decrease the current volume by a predefined
|
||||||
amount based on the direction (1 = increase, -1 = decrease)
|
amount based on the direction (1 = increase, -1 = decrease)
|
||||||
*/
|
*/
|
||||||
void adjustVolume(Int8 direction);
|
void adjustVolume(Int8 direction);
|
||||||
|
|
||||||
|
@ -142,23 +139,23 @@ class SoundSDL : public Sound
|
||||||
/**
|
/**
|
||||||
Saves the current state of this device to the given Serializer.
|
Saves the current state of this device to the given Serializer.
|
||||||
|
|
||||||
@param out The serializer device to save to.
|
@param out The serializer device to save to.
|
||||||
@return The result of the save. True on success, false on failure.
|
@return The result of the save. True on success, false on failure.
|
||||||
*/
|
*/
|
||||||
bool save(Serializer& out) const;
|
bool save(Serializer& out) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Loads the current state of this device from the given Serializer.
|
Loads the current state of this device from the given Serializer.
|
||||||
|
|
||||||
@param in The Serializer device to load from.
|
@param in The Serializer device to load from.
|
||||||
@return The result of the load. True on success, false on failure.
|
@return The result of the load. True on success, false on failure.
|
||||||
*/
|
*/
|
||||||
bool load(Serializer& in);
|
bool load(Serializer& in);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get a descriptor for this console class (used in error checking).
|
Get a descriptor for this console class (used in error checking).
|
||||||
|
|
||||||
@return The name of the object
|
@return The name of the object
|
||||||
*/
|
*/
|
||||||
string name() const { return "TIASound"; }
|
string name() const { return "TIASound"; }
|
||||||
|
|
||||||
|
@ -166,8 +163,8 @@ class SoundSDL : public Sound
|
||||||
/**
|
/**
|
||||||
Invoked by the sound callback to process the next sound fragment.
|
Invoked by the sound callback to process the next sound fragment.
|
||||||
|
|
||||||
@param stream Pointer to the start of the fragment
|
@param stream Pointer to the start of the fragment
|
||||||
@param length Length of the fragment
|
@param length Length of the fragment
|
||||||
*/
|
*/
|
||||||
void processFragment(uInt8* stream, Int32 length);
|
void processFragment(uInt8* stream, Int32 length);
|
||||||
|
|
||||||
|
@ -223,14 +220,14 @@ class SoundSDL : public Sound
|
||||||
/**
|
/**
|
||||||
Return the item at the front on the queue.
|
Return the item at the front on the queue.
|
||||||
|
|
||||||
@return The item at the front of the queue.
|
@return The item at the front of the queue.
|
||||||
*/
|
*/
|
||||||
RegWrite& front();
|
RegWrite& front();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Answers the number of items currently in the queue.
|
Answers the number of items currently in the queue.
|
||||||
|
|
||||||
@return The number of items in the queue.
|
@return The number of items in the queue.
|
||||||
*/
|
*/
|
||||||
uInt32 size() const;
|
uInt32 size() const;
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
#define STELLA_VERSION "3.5_svn_test3"
|
#define STELLA_VERSION "3.5_svn_test4"
|
||||||
#define STELLA_BUILD atoi("$Rev$" + 6)
|
#define STELLA_BUILD atoi("$Rev$" + 6)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -487,10 +487,9 @@ void Console::initializeAudio()
|
||||||
int framerate = myOSystem->settings().getInt("framerate");
|
int framerate = myOSystem->settings().getInt("framerate");
|
||||||
if(framerate > 0) myFramerate = float(framerate);
|
if(framerate > 0) myFramerate = float(framerate);
|
||||||
const string& sound = myProperties.get(Cartridge_Sound);
|
const string& sound = myProperties.get(Cartridge_Sound);
|
||||||
uInt32 channels = (sound == "STEREO" ? 2 : 1);
|
|
||||||
|
|
||||||
myOSystem->sound().close();
|
myOSystem->sound().close();
|
||||||
myOSystem->sound().setChannels(channels);
|
myOSystem->sound().setChannels(sound == "STEREO" ? 2 : 1);
|
||||||
myOSystem->sound().setFrameRate(myFramerate);
|
myOSystem->sound().setFrameRate(myFramerate);
|
||||||
myOSystem->sound().open();
|
myOSystem->sound().open();
|
||||||
|
|
||||||
|
|
|
@ -2649,9 +2649,9 @@ string EventHandler::StellaJoystick::about() const
|
||||||
buf << name;
|
buf << name;
|
||||||
if(type == JT_REGULAR)
|
if(type == JT_REGULAR)
|
||||||
buf << " with:" << endl << " "
|
buf << " with:" << endl << " "
|
||||||
<< SDL_JoystickNumAxes(stick) << " axes, "
|
<< numAxes << " axes, "
|
||||||
<< SDL_JoystickNumButtons(stick) << " buttons, "
|
<< numButtons << " buttons, "
|
||||||
<< SDL_JoystickNumHats(stick) << " hats";
|
<< numHats << " hats";
|
||||||
|
|
||||||
return buf.str();
|
return buf.str();
|
||||||
}
|
}
|
||||||
|
|
|
@ -464,8 +464,8 @@ fallback:
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void OSystem::createSound()
|
void OSystem::createSound()
|
||||||
{
|
{
|
||||||
delete mySound; mySound = NULL;
|
if(!mySound)
|
||||||
mySound = MediaFactory::createAudio(this);
|
mySound = MediaFactory::createAudio(this);
|
||||||
#ifndef SOUND_SUPPORT
|
#ifndef SOUND_SUPPORT
|
||||||
mySettings->setBool("sound", false);
|
mySettings->setBool("sound", false);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -41,11 +41,11 @@ Settings::Settings(OSystem* osystem)
|
||||||
|
|
||||||
// OpenGL specific options
|
// OpenGL specific options
|
||||||
setInternal("gl_filter", "nearest");
|
setInternal("gl_filter", "nearest");
|
||||||
setInternal("gl_aspectn", "100");
|
setInternal("gl_aspectn", "90");
|
||||||
setInternal("gl_aspectp", "100");
|
setInternal("gl_aspectp", "100");
|
||||||
setInternal("gl_fsmax", "false");
|
setInternal("gl_fsmax", "true");
|
||||||
setInternal("gl_lib", "libGL.so");
|
setInternal("gl_lib", "libGL.so");
|
||||||
setInternal("gl_vsync", "false");
|
setInternal("gl_vsync", "true");
|
||||||
setInternal("gl_vbo", "true");
|
setInternal("gl_vbo", "true");
|
||||||
|
|
||||||
// Framebuffer-related options
|
// Framebuffer-related options
|
||||||
|
@ -99,7 +99,7 @@ Settings::Settings(OSystem* osystem)
|
||||||
setInternal("uselauncher", "true");
|
setInternal("uselauncher", "true");
|
||||||
setInternal("launcherres", "640x480");
|
setInternal("launcherres", "640x480");
|
||||||
setInternal("launcherfont", "medium");
|
setInternal("launcherfont", "medium");
|
||||||
setInternal("launcherexts", "allfiles");
|
setInternal("launcherexts", "allroms");
|
||||||
setInternal("romviewer", "0");
|
setInternal("romviewer", "0");
|
||||||
setInternal("lastrom", "");
|
setInternal("lastrom", "");
|
||||||
|
|
||||||
|
|
|
@ -89,13 +89,6 @@ class Sound : public Serializable
|
||||||
*/
|
*/
|
||||||
virtual void close() = 0;
|
virtual void close() = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
Return true iff the sound device was successfully initialized.
|
|
||||||
|
|
||||||
@return true iff the sound device was successfully initialized.
|
|
||||||
*/
|
|
||||||
virtual bool isSuccessfullyInitialized() const = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Set the mute state of the sound object. While muted no sound is played.
|
Set the mute state of the sound object. While muted no sound is played.
|
||||||
|
|
||||||
|
|
|
@ -21,10 +21,10 @@
|
||||||
#include "TIASnd.hxx"
|
#include "TIASnd.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
TIASound::TIASound(Int32 outputFrequency, Int32 tiaFrequency, uInt32 channels)
|
TIASound::TIASound(Int32 outputFrequency, Int32 tiaFrequency)
|
||||||
: myOutputFrequency(outputFrequency),
|
: myChannelMode(Hardware2Stereo),
|
||||||
|
myOutputFrequency(outputFrequency),
|
||||||
myTIAFrequency(tiaFrequency),
|
myTIAFrequency(tiaFrequency),
|
||||||
myChannels(channels),
|
|
||||||
myOutputCounter(0),
|
myOutputCounter(0),
|
||||||
myVolumePercentage(100),
|
myVolumePercentage(100),
|
||||||
myVolumeClip(128)
|
myVolumeClip(128)
|
||||||
|
@ -60,9 +60,20 @@ void TIASound::tiaFrequency(Int32 freq)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void TIASound::channels(uInt32 number)
|
string TIASound::channels(uInt32 hardware, bool stereo)
|
||||||
{
|
{
|
||||||
myChannels = number == 2 ? 2 : 1;
|
if(hardware == 1)
|
||||||
|
myChannelMode = Hardware1;
|
||||||
|
else
|
||||||
|
myChannelMode = stereo ? Hardware2Stereo : Hardware2Mono;
|
||||||
|
|
||||||
|
switch(myChannelMode)
|
||||||
|
{
|
||||||
|
case Hardware1: return "Hardware1";
|
||||||
|
case Hardware2Mono: return "Hardware2Mono";
|
||||||
|
case Hardware2Stereo: return "Hardware2Stereo";
|
||||||
|
default: return EmptyString;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -357,27 +368,39 @@ void TIASound::process(uInt8* buffer, uInt32 samples)
|
||||||
|
|
||||||
myOutputCounter += myOutputFrequency;
|
myOutputCounter += myOutputFrequency;
|
||||||
|
|
||||||
if(myChannels == 1)
|
switch(myChannelMode)
|
||||||
{
|
{
|
||||||
// Handle mono sample generation
|
case Hardware2Mono: // mono sampling with 2 hardware channels
|
||||||
while((samples > 0) && (myOutputCounter >= myTIAFrequency))
|
while((samples > 0) && (myOutputCounter >= myTIAFrequency))
|
||||||
{
|
{
|
||||||
*(buffer++) = (((myP4[0] & 8) ? v0 : 0) +
|
uInt8 byte = (((myP4[0] & 8) ? v0 : 0) +
|
||||||
((myP4[1] & 8) ? v1 : 0)) + myVolumeClip;
|
((myP4[1] & 8) ? v1 : 0)) + myVolumeClip;
|
||||||
myOutputCounter -= myTIAFrequency;
|
*(buffer++) = byte;
|
||||||
samples--;
|
*(buffer++) = byte;
|
||||||
}
|
myOutputCounter -= myTIAFrequency;
|
||||||
}
|
samples--;
|
||||||
else
|
}
|
||||||
{
|
break;
|
||||||
// Handle stereo sample generation
|
|
||||||
while((samples > 0) && (myOutputCounter >= myTIAFrequency))
|
case Hardware2Stereo: // stereo sampling with 2 hardware channels
|
||||||
{
|
while((samples > 0) && (myOutputCounter >= myTIAFrequency))
|
||||||
*(buffer++) = ((myP4[0] & 8) ? v0 : 0) + myVolumeClip;
|
{
|
||||||
*(buffer++) = ((myP4[1] & 8) ? v1 : 0) + myVolumeClip;
|
*(buffer++) = ((myP4[0] & 8) ? v0 : 0) + myVolumeClip;
|
||||||
myOutputCounter -= myTIAFrequency;
|
*(buffer++) = ((myP4[1] & 8) ? v1 : 0) + myVolumeClip;
|
||||||
samples--;
|
myOutputCounter -= myTIAFrequency;
|
||||||
}
|
samples--;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Hardware1: // mono/stereo sampling with only 1 hardware channel
|
||||||
|
while((samples > 0) && (myOutputCounter >= myTIAFrequency))
|
||||||
|
{
|
||||||
|
*(buffer++) = (((myP4[0] & 8) ? v0 : 0) +
|
||||||
|
((myP4[1] & 8) ? v1 : 0)) + myVolumeClip;
|
||||||
|
myOutputCounter -= myTIAFrequency;
|
||||||
|
samples--;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,8 +35,7 @@ class TIASound
|
||||||
/**
|
/**
|
||||||
Create a new TIA Sound object using the specified output frequency
|
Create a new TIA Sound object using the specified output frequency
|
||||||
*/
|
*/
|
||||||
TIASound(Int32 outputFrequency = 31400, Int32 tiaFrequency = 31400,
|
TIASound(Int32 outputFrequency = 31400, Int32 tiaFrequency = 31400);
|
||||||
uInt32 channels = 1);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Destructor
|
Destructor
|
||||||
|
@ -60,9 +59,16 @@ class TIASound
|
||||||
void tiaFrequency(Int32 freq);
|
void tiaFrequency(Int32 freq);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Selects the number of audio channels per sample (1 = mono, 2 = stereo)
|
Selects the number of audio channels per sample. There are two factors
|
||||||
|
to consider: hardware capability and desired mixing.
|
||||||
|
|
||||||
|
@param hardware The number of channels supported by the sound system
|
||||||
|
@param stereo Whether to output the internal sound signals into 1
|
||||||
|
or 2 channels
|
||||||
|
|
||||||
|
@return Status of the channel configuration used
|
||||||
*/
|
*/
|
||||||
void channels(uInt32 number);
|
string channels(uInt32 hardware, bool stereo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Set volume clipping (decrease volume range by half to eliminate popping)
|
Set volume clipping (decrease volume range by half to eliminate popping)
|
||||||
|
@ -133,6 +139,12 @@ class TIASound
|
||||||
uInt32 myCounter;
|
uInt32 myCounter;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ChannelMode {
|
||||||
|
Hardware1,
|
||||||
|
Hardware2Mono,
|
||||||
|
Hardware2Stereo
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uInt8 myAUDC[2];
|
uInt8 myAUDC[2];
|
||||||
uInt8 myAUDF[2];
|
uInt8 myAUDF[2];
|
||||||
|
@ -142,9 +154,9 @@ class TIASound
|
||||||
uInt8 myP4[2]; // 4-bit register LFSR (lower 4 bits used)
|
uInt8 myP4[2]; // 4-bit register LFSR (lower 4 bits used)
|
||||||
uInt8 myP5[2]; // 5-bit register LFSR (lower 5 bits used)
|
uInt8 myP5[2]; // 5-bit register LFSR (lower 5 bits used)
|
||||||
|
|
||||||
|
ChannelMode myChannelMode;
|
||||||
Int32 myOutputFrequency;
|
Int32 myOutputFrequency;
|
||||||
Int32 myTIAFrequency;
|
Int32 myTIAFrequency;
|
||||||
uInt32 myChannels;
|
|
||||||
Int32 myOutputCounter;
|
Int32 myOutputCounter;
|
||||||
uInt32 myVolumePercentage;
|
uInt32 myVolumePercentage;
|
||||||
uInt8 myVolumeClip;
|
uInt8 myVolumeClip;
|
||||||
|
|
|
@ -48,7 +48,7 @@ AudioDialog::AudioDialog(OSystem* osystem, DialogContainer* parent,
|
||||||
buttonWidth = font.getStringWidth("Defaults") + 20,
|
buttonWidth = font.getStringWidth("Defaults") + 20,
|
||||||
buttonHeight = font.getLineHeight() + 4;
|
buttonHeight = font.getLineHeight() + 4;
|
||||||
int xpos, ypos;
|
int xpos, ypos;
|
||||||
int lwidth = font.getStringWidth("Fragment Size: "),
|
int lwidth = font.getStringWidth("Sample Size (*): "),
|
||||||
pwidth = font.getStringWidth("512 bytes");
|
pwidth = font.getStringWidth("512 bytes");
|
||||||
WidgetArray wid;
|
WidgetArray wid;
|
||||||
StringMap items;
|
StringMap items;
|
||||||
|
@ -82,7 +82,7 @@ AudioDialog::AudioDialog(OSystem* osystem, DialogContainer* parent,
|
||||||
items.push_back("4 KB", "4096");
|
items.push_back("4 KB", "4096");
|
||||||
myFragsizePopup = new PopUpWidget(this, font, xpos, ypos,
|
myFragsizePopup = new PopUpWidget(this, font, xpos, ypos,
|
||||||
pwidth + myVolumeLabel->getWidth() - 4, lineHeight,
|
pwidth + myVolumeLabel->getWidth() - 4, lineHeight,
|
||||||
items, "Fragment size: ", lwidth);
|
items, "Sample size (*): ", lwidth);
|
||||||
wid.push_back(myFragsizePopup);
|
wid.push_back(myFragsizePopup);
|
||||||
ypos += lineHeight + 4;
|
ypos += lineHeight + 4;
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ AudioDialog::AudioDialog(OSystem* osystem, DialogContainer* parent,
|
||||||
items.push_back("48000 Hz", "48000");
|
items.push_back("48000 Hz", "48000");
|
||||||
myFreqPopup = new PopUpWidget(this, font, xpos, ypos,
|
myFreqPopup = new PopUpWidget(this, font, xpos, ypos,
|
||||||
pwidth + myVolumeLabel->getWidth() - 4, lineHeight,
|
pwidth + myVolumeLabel->getWidth() - 4, lineHeight,
|
||||||
items, "Output freq: ", lwidth);
|
items, "Output freq (*): ", lwidth);
|
||||||
wid.push_back(myFreqPopup);
|
wid.push_back(myFreqPopup);
|
||||||
ypos += lineHeight + 4;
|
ypos += lineHeight + 4;
|
||||||
|
|
||||||
|
@ -108,16 +108,22 @@ AudioDialog::AudioDialog(OSystem* osystem, DialogContainer* parent,
|
||||||
ypos += lineHeight + 4;
|
ypos += lineHeight + 4;
|
||||||
|
|
||||||
// Clip volume
|
// Clip volume
|
||||||
myClipVolumeCheckbox = new CheckboxWidget(this, font, xpos+50, ypos,
|
myClipVolumeCheckbox = new CheckboxWidget(this, font, xpos+10, ypos,
|
||||||
"Clip volume", 0);
|
"Clip volume", 0);
|
||||||
wid.push_back(myClipVolumeCheckbox);
|
wid.push_back(myClipVolumeCheckbox);
|
||||||
ypos += lineHeight + 4;
|
xpos += myClipVolumeCheckbox->getWidth() + 20;
|
||||||
|
|
||||||
// Enable sound
|
// Enable sound
|
||||||
mySoundEnableCheckbox = new CheckboxWidget(this, font, xpos+50, ypos,
|
mySoundEnableCheckbox = new CheckboxWidget(this, font, xpos, ypos,
|
||||||
"Enable sound", kSoundEnableChanged);
|
"Enable sound", kSoundEnableChanged);
|
||||||
wid.push_back(mySoundEnableCheckbox);
|
wid.push_back(mySoundEnableCheckbox);
|
||||||
|
|
||||||
|
// Add message concerning usage
|
||||||
ypos += lineHeight + 12;
|
ypos += lineHeight + 12;
|
||||||
|
const GUI::Font& infofont = instance().infoFont();
|
||||||
|
new StaticTextWidget(this, infofont, 10, ypos,
|
||||||
|
font.getStringWidth("(*) Requires application restart"), fontHeight,
|
||||||
|
"(*) Requires application restart", kTextAlignLeft);
|
||||||
|
|
||||||
// Add Defaults, OK and Cancel buttons
|
// Add Defaults, OK and Cancel buttons
|
||||||
ButtonWidget* b;
|
ButtonWidget* b;
|
||||||
|
|
|
@ -32,7 +32,8 @@ class StringListWidget;
|
||||||
class LoggerDialog : public Dialog
|
class LoggerDialog : public Dialog
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LoggerDialog(OSystem* osystem, DialogContainer* parent, const GUI::Font& font, int max_w, int max_h);
|
LoggerDialog(OSystem* osystem, DialogContainer* parent,
|
||||||
|
const GUI::Font& font, int max_w, int max_h);
|
||||||
virtual ~LoggerDialog();
|
virtual ~LoggerDialog();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -449,16 +449,16 @@ void VideoDialog::setDefaults()
|
||||||
myFSResPopup->setSelected("auto", "");
|
myFSResPopup->setSelected("auto", "");
|
||||||
myFrameTimingPopup->setSelected("sleep", "");
|
myFrameTimingPopup->setSelected("sleep", "");
|
||||||
myGLFilterPopup->setSelected("nearest", "");
|
myGLFilterPopup->setSelected("nearest", "");
|
||||||
myNAspectRatioSlider->setValue(100);
|
myNAspectRatioSlider->setValue(90);
|
||||||
myNAspectRatioLabel->setLabel("100");
|
myNAspectRatioLabel->setLabel("90");
|
||||||
myPAspectRatioSlider->setValue(100);
|
myPAspectRatioSlider->setValue(100);
|
||||||
myPAspectRatioLabel->setLabel("100");
|
myPAspectRatioLabel->setLabel("100");
|
||||||
myFrameRateSlider->setValue(0);
|
myFrameRateSlider->setValue(0);
|
||||||
myFrameRateLabel->setLabel("Auto");
|
myFrameRateLabel->setLabel("Auto");
|
||||||
|
|
||||||
myFullscreenPopup->setSelected("0", "");
|
myFullscreenPopup->setSelected("0", "");
|
||||||
myColorLossCheckbox->setState(false);
|
myColorLossCheckbox->setState(true);
|
||||||
myGLStretchCheckbox->setState(false);
|
myGLStretchCheckbox->setState(true);
|
||||||
myUseVBOCheckbox->setState(true);
|
myUseVBOCheckbox->setState(true);
|
||||||
myUseVSyncCheckbox->setState(true);
|
myUseVSyncCheckbox->setState(true);
|
||||||
myUIMessagesCheckbox->setState(true);
|
myUIMessagesCheckbox->setState(true);
|
||||||
|
|
Loading…
Reference in New Issue