diff --git a/src/common/SoundSDL.cxx b/src/common/SoundSDL.cxx index 70ba2e288..4bc8e7360 100644 --- a/src/common/SoundSDL.cxx +++ b/src/common/SoundSDL.cxx @@ -31,9 +31,6 @@ #include "Console.hxx" #include "AtariVox.hxx" -#ifdef SPEAKJET_EMULATION - #include "SpeakJet.hxx" -#endif #include "SoundSDL.hxx" @@ -293,8 +290,6 @@ void SoundSDL::set(uInt16 addr, uInt8 value, Int32 cycle) // the sound to "scale" correctly, we have to know the games real frame // rate (e.g., 50 or 60) and the currently emulated frame rate. We use these // values to "scale" the time before the register change occurs. -// FIXME - this always results in 1.0, so we don't really need it -// delta = delta * (myDisplayFrameRate / myOSystem->frameRate()); RegWrite info; info.addr = addr; info.value = value; @@ -403,27 +398,6 @@ void SoundSDL::callback(void* udata, uInt8* stream, int len) { SoundSDL* sound = (SoundSDL*)udata; sound->processFragment(stream, (Int32)len); - -#ifdef SPEAKJET_EMULATION -// cerr << "SoundSDL::callback(): len==" << len << endl; - - // See if we need sound from the AtariVox - AtariVox *vox = sound->myOSystem->console().atariVox(); - if(vox) - { - // If so, mix 'em together (this is a crappy way to mix audio streams...) - uInt8 *s = stream; - for(int i=0; igetSpeakJet()->getSamples(&count); - if(!count) - break; - SDL_MixAudio(s, voxSamples, OUTPUT_BUFFER_SIZE, SDL_MIX_MAXVOLUME); - s += OUTPUT_BUFFER_SIZE; - } - } -#endif } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/CartDebug.cxx b/src/debugger/CartDebug.cxx index f82d1b5de..0f7604e69 100644 --- a/src/debugger/CartDebug.cxx +++ b/src/debugger/CartDebug.cxx @@ -282,9 +282,6 @@ int CartDebug::addressToLine(uInt16 address) const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - string CartDebug::disassemble(uInt16 start, uInt16 lines) const { -// if(!(start & 0x1000)) -// return DebuggerParser::red("Disassembly below 0x1000 not yet supported"); -// FIXME DisassemblyList list; DiStella distella(list, start, false); diff --git a/src/debugger/Debugger.cxx b/src/debugger/Debugger.cxx index 4fe7323a3..ad46c0848 100644 --- a/src/debugger/Debugger.cxx +++ b/src/debugger/Debugger.cxx @@ -206,9 +206,6 @@ void Debugger::setConsole(Console* console) // Initialize breakpoints to known state clearAllBreakPoints(); clearAllTraps(); - -// FIXME - these will probably be removed -// loadListFile(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/gui/AudioWidget.cxx b/src/debugger/gui/AudioWidget.cxx index 23c17c0ce..cd4f8302b 100644 --- a/src/debugger/gui/AudioWidget.cxx +++ b/src/debugger/gui/AudioWidget.cxx @@ -101,29 +101,7 @@ AudioWidget::~AudioWidget() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void AudioWidget::handleCommand(CommandSender* sender, int cmd, int data, int id) { -/* FIXME - implement this - // We simply change the values in the DataGridWidget - // It will then send the 'kDGItemDataChangedCmd' signal to change the actual - // memory location - int addr, value; - string buf; - - Debugger& dbg = instance().debugger(); - TIADebug& tia = dbg.tiaDebug(); - - switch(cmd) - { - case kDGItemDataChangedCmd: - switch(id) - { - case kNusizP0ID: - tia.nusizP0(myNusizP0->getSelectedValue()); - myNusizP0Text->setEditString(tia.nusizP0String()); - break; - } - break; - } -*/ + // TODO - implement this } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/gui/ColorWidget.cxx b/src/debugger/gui/ColorWidget.cxx index 17dd608b5..6ee77cbb9 100644 --- a/src/debugger/gui/ColorWidget.cxx +++ b/src/debugger/gui/ColorWidget.cxx @@ -52,15 +52,6 @@ void ColorWidget::setColor(int color) setDirty(); draw(); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void ColorWidget::handleMouseDown(int x, int y, int button, int clickCount) -{ -// TODO - add ColorDialog, which will show all 256 colors in the -// TIA palette -// if(isEnabled()) -// parent()->addDialog(myColorDialog); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void ColorWidget::drawWidget(bool hilite) { diff --git a/src/debugger/gui/ColorWidget.hxx b/src/debugger/gui/ColorWidget.hxx index bbdcedd03..677134b44 100644 --- a/src/debugger/gui/ColorWidget.hxx +++ b/src/debugger/gui/ColorWidget.hxx @@ -51,7 +51,6 @@ class ColorWidget : public Widget, public CommandSender protected: void drawWidget(bool hilite); - void handleMouseDown(int x, int y, int button, int clickCount); protected: int _color; diff --git a/src/debugger/gui/PromptWidget.cxx b/src/debugger/gui/PromptWidget.cxx index 00d5e9e73..ea81d71db 100644 --- a/src/debugger/gui/PromptWidget.cxx +++ b/src/debugger/gui/PromptWidget.cxx @@ -21,6 +21,7 @@ #include #include +#include #include "ScrollBarWidget.hxx" #include "FrameBuffer.hxx" @@ -36,14 +37,6 @@ #define PROMPT "> " -/* TODO: - * - it is very inefficient to redraw the full thingy when just one char is added/removed. - * Instead, we could just copy the GFX of the blank console (i.e. after the transparent - * background is drawn, before any text is drawn). Then using that, it becomes trivial - * to erase a single character, do scrolling etc. - * - a *lot* of others things, this code is in no way complete and heavily under progress - */ - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PromptWidget::PromptWidget(GuiObject* boss, const GUI::Font& font, int x, int y, int w, int h) @@ -246,7 +239,7 @@ bool PromptWidget::handleKeyDown(int ascii, int keycode, int modifiers) if(list.size() < 1) break; - // TODO: sort completions (add sort method to StringList) + sort(list.begin(), list.end()); completionList = list[0]; for(uInt32 i = 1; i < list.size(); ++i) completionList += " " + list[i]; @@ -263,7 +256,7 @@ bool PromptWidget::handleKeyDown(int ascii, int keycode, int modifiers) if(list.size() < 1) break; - // TODO: sort completions (add sort method to StringList) + sort(list.begin(), list.end()); completionList = list[0]; for(uInt32 i = 1; i < list.size(); ++i) completionList += " " + list[i]; @@ -852,7 +845,7 @@ void PromptWidget::scrollToCurrent() if (line + _linesPerPage <= _scrollLine) { - // TODO - this should only occur for loong edit lines, though + // TODO - this should only occur for long edit lines, though } else if (line > _scrollLine) { diff --git a/src/emucore/CartMC.cxx b/src/emucore/CartMC.cxx index 06ba84e86..4943bf723 100644 --- a/src/emucore/CartMC.cxx +++ b/src/emucore/CartMC.cxx @@ -233,7 +233,7 @@ bool CartridgeMC::patch(uInt16 address, uInt8 value) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - const uInt8* CartridgeMC::getImage(int& size) const { - size = 128 * 1024; // FIXME: keep track of original size + size = 128 * 1024; return myImage; } diff --git a/src/emucore/CartUA.cxx b/src/emucore/CartUA.cxx index 223986e9a..a31b812e8 100644 --- a/src/emucore/CartUA.cxx +++ b/src/emucore/CartUA.cxx @@ -73,7 +73,7 @@ void CartridgeUA::install(System& system) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt8 CartridgeUA::peek(uInt16 address) { -// address &= 0x1FFF; TODO - is this needed here? + address &= 0x1FFF; // Switch banks if necessary switch(address) diff --git a/src/emucore/SpeakJet.cxx b/src/emucore/SpeakJet.cxx deleted file mode 100644 index fe14fb43b..000000000 --- a/src/emucore/SpeakJet.cxx +++ /dev/null @@ -1,346 +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-2010 by Bradford W. Mott and the Stella Team -// -// See the file "License.txt" for information on usage and redistribution of -// this file, and for a DISCLAIMER OF ALL WARRANTIES. -// -// $Id$ -//============================================================================ - -#ifdef SPEAKJET_EMULATION - -#include "SpeakJet.hxx" - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -SpeakJet::SpeakJet() -{ - // Initialize output buffers. Each one points to the next element, - // except the last, which points back to the first. - SpeechBuffer *first = &outputBuffers[0]; - SpeechBuffer *last = 0; - for(int i=0; iitems = 0; - sb->lock = SDL_CreateSemaphore(1); - if(last) { - last->next = sb; - } - last = sb; - } - last->next = first; - - myCurrentOutputBuffer = ourCurrentWriteBuffer = first; - ourCurrentWritePosition = 0; - - // Init rsynth library - darray_init(&rsynthSamples, sizeof(short), 2048); - -/* - rsynth = rsynth_init(samp_rate, mSec_per_frame, - rsynth_speaker(F0Hz, gain, Elements), - save_sample, flush_samples, &samples); -*/ - rsynth = rsynth_init(31400, 10.0, - rsynth_speaker(133.0, 57, Elements), - save_sample, flush_samples, &rsynthSamples); - spawnThread(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -SpeakJet::~SpeakJet() -{ -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void SpeakJet::spawnThread() -{ - ourInputSemaphore = SDL_CreateSemaphore(1); // 1==unlocked - uInt32 sem = SDL_SemValue(ourInputSemaphore); - cerr << "before SDL_CreateThread(), sem==" << sem << endl; - ourThread = SDL_CreateThread(thread, 0); - sem = SDL_SemValue(ourInputSemaphore); - cerr << "after SDL_CreateThread(), sem==" << sem << endl; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -int SpeakJet::thread(void *data) { - cerr << "rsynth thread spawned" << endl; - while(1) { - speak(); - usleep(10); - } - return 0; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void SpeakJet::write(uInt8 code) -{ - cerr << "SpeakJet: output byte " << ((int)(code)) << endl; - - // TODO: clean up this mess. - const char *rsynthPhones = xlatePhoneme(code); -// cerr << "rsynth: \"" << rsynthPhones << "\"" << endl; - int len = strlen(rsynthPhones); - - if(ourInputCount + len + 1 >= INPUT_BUFFER_SIZE) { - cerr << "phonemeBuffer is full, dropping" << endl; - return; - } - - uInt32 sem = SDL_SemValue(ourInputSemaphore); -// cerr << "write() waiting on semaphore (value " << sem << ")" << endl; - SDL_SemWait(ourInputSemaphore); -// cerr << "write() got semaphore" << endl; - for(int i=0; i= INPUT_BUFFER_SIZE - 5) - foundSpace = true; - - if(foundSpace) - ourInputCount = 0; - - // end locked section -// cerr << "speak() releasing semaphore" << endl; - SDL_SemPost(ourInputSemaphore); - - if(foundSpace) - { - // Lock current buffer. save_sample will unlock it when it gets full. - SDL_SemWait(ourCurrentWriteBuffer->lock); - rsynth_phones(rsynth, myInput, strlen(myInput)); - } -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const char *SpeakJet::xlatePhoneme(uInt8 code) -{ - if(code <= 6) - return " "; - - if(code >= 128 && code <= 199) - return ourPhonemeTable[ code - 128 ]; - - return ""; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt8 *SpeakJet::getSamples(int *count) { - static uInt8 contents[OUTPUT_BUFFER_SIZE]; - SDL_sem *lock = myCurrentOutputBuffer->lock; - SDL_SemWait(lock); - *count = myCurrentOutputBuffer->items; - for(int i=0; i<*count; i++) - contents[i] = myCurrentOutputBuffer->contents[i]; - myCurrentOutputBuffer->items = 0; - myCurrentOutputBuffer = myCurrentOutputBuffer->next; - SDL_SemPost(lock); - return contents; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool SpeakJet::chipReady() -{ - return true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void *SpeakJet::save_sample(void *user_data, - float sample, - unsigned nsamp, - rsynth_t *rsynth) -{ - static long clip_max; - static float peak; - short shortSamp; - uInt8 output; - - darray_t *buf = (darray_t *) user_data; - shortSamp = clip(&clip_max, sample, &peak); - darray_short(buf, shortSamp); - - // Convert to 8-bit - // output = (uInt8)( (((float)shortSamp) + 32768.0) / 256.0 ); - double d = shortSamp + 32768.0; - output = (uInt8)(d/256.0); -// cerr << "Output sample: " << ((int)(output)) << endl; - - // Put in buffer - ourCurrentWriteBuffer->contents[ourCurrentWritePosition++] = output; - ourCurrentWriteBuffer->items = ourCurrentWritePosition; - - // If buffer is full, unlock it and use the next one. - if(ourCurrentWritePosition == OUTPUT_BUFFER_SIZE) - { - SDL_SemWait(ourCurrentWriteBuffer->next->lock); - SDL_SemPost(ourCurrentWriteBuffer->lock); - ourCurrentWriteBuffer = ourCurrentWriteBuffer->next; - ourCurrentWriteBuffer->items = ourCurrentWritePosition = 0; - } - return (void *) buf; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void *SpeakJet::flush_samples(void *user_data, - unsigned nsamp, - rsynth_t *rsynth) -{ - darray_t *buf = (darray_t *) user_data; - buf->items = 0; - for (;ourCurrentWritePosition < OUTPUT_BUFFER_SIZE; ourCurrentWritePosition++) - ourCurrentWriteBuffer->contents[ourCurrentWritePosition] = 0; - ourCurrentWritePosition = 0; - SDL_SemPost(ourCurrentWriteBuffer->lock); - ourCurrentWriteBuffer = ourCurrentWriteBuffer->next; // NOT locked - return (void *) buf; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -short SpeakJet::clip(long *clip_max, float input, float *peak) -{ - long temp = (long) input; - float isq = input * input; -#ifdef PEAK - if (isq > *peak) - *peak = isq; -#else - *peak += isq; -#endif - if (-temp > *clip_max) - *clip_max = -temp; - if (temp > *clip_max) - *clip_max = temp; - if (temp < -32767) { - temp = -32767; - } - else if (temp > 32767) { - temp = 32767; - } - return (temp); -} - - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -/* -Table of rsynth phonemes, indexed by SpeakJet phoneme code number. -Table is offset by 128 bytes (ourPhonemeTable[0] is code #128) -see rsynth/phones.def for definitions of rsynth phonemes. -We prefix a "'" to the rsynth phoneme for stress or a "," -for relax. -FIXME: This will need a lot of tweaking, once I get a real -SpeakJet to test with. -*/ - -const char *SpeakJet::ourPhonemeTable[] = { -//"rsynth phoneme(s) (phones.def)", // SJ phonemes (p. 16 in SJ manual) - "i:", // 128 IY See, Even, Feed - "I", // 129 IH Sit, Fix, Pin - "eI", // 130 EY Hair, Gate, Beige - "E", // 131 EH Met, Check, Red - "{", // 132 AY Hat, Fast, Fan - "A:", // 133 AX Cotten // maybe "@" instead? - "V", // 134 UX Luck, Up, Uncle - "Q", // 135 OH Hot, Clock, Fox - "A:", // 136 AW Father, Fall - "oU", // 137 OW Comb, Over, Hold - "U", // 138 UH Book, Could, Should - "u:", // 139 UW Food, June - "m", // 140 MM Milk, Famous, - "n", // 141 NE Nip, Danger, Thin - "n", // 142 NO No, Snow, On - "N", // 143 NGE Think, Ping - "N", // 144 NGO Hung, Song - "l", // 145 LE Lake, Alarm, Lapel - "l", // 146 LO Clock, Plus, Hello - "w", // 147 WW Wool, Sweat - "r", // 148 RR Ray, Brain, Over - "I@", // 149 IYRR Clear, Hear, Year - "e@", // 150 EYRR Hair, Stair, Repair - "3:", // 151 AXRR Fir, Bird, Burn - "A:", // 152 AWRR Part, Farm, Yarn - "Qr", // 153 OWRR Corn, Four, Your [*] - "eI", // 154 EYIY Gate, Ate, Ray - "aI", // 155 OHIY Mice, Fight, White - "OI", // 156 OWIY Boy, Toy, Voice - "aI", // 157 OHIH Sky, Five, I - "j", // 158 IYEH Yes, Yarn, Million - "el", // 159 EHLL Saddle, Angle, Spell [*] - "U@", // 160 IYUW Cute, Few // maybe u - "aU", // 161 AXUW Brown, Clown, Thousan - "U@", // 162 IHWW Two, New, Zoo - "aU", // 163 AYWW Our, Ouch, Owl - "@U", // 164 OWWW Go, Hello, Snow // maybe "oU"? - "dZ", // 165 JH Dodge, Jet, Savage - "v", // 166 VV Vest, Even, - "z", // 167 ZZ Zoo, Zap - "Z", // 168 ZH Azure, Treasure - "D", // 169 DH There, That, This - "b", // 170 BE Bear, Bird, Beed ??? - "b", // 171 BO Bone, Book Brown ??? - "b", // 172 EB Cab, Crib, Web ??? - "b", // 173 OB Bob, Sub, Tub ??? - "d", // 174 DE Deep, Date, Divide ??? - "d", // 175 DO Do, Dust, Dog ??? - "d", // 176 ED Could, Bird ??? - "d", // 177 OD Bud, Food ??? - "g", // 178 GE Get, Gate, Guest, ??? - "g", // 179 GO Got, Glue, Goo ??? - "g", // 180 EG Peg, Wig ??? - "g", // 181 OG Dog, Peg ??? - "tS", // 182 CH Church, Feature, March - "h", // 183 HE Help, Hand, Hair - "h", // 184 HO Hoe, Hot, Hug - "hw", // 185 WH Who, Whale, White [*] - "f", // 186 FF Food, Effort, Off - "s", // 187 SE See, Vest, Plus - "s", // 188 SO So, Sweat ??? - "S", // 189 SH Ship, Fiction, Leash - "T", // 190 TH Thin, month - "t", // 191 TT Part, Little, Sit - "t", // 192 TU To, Talk, Ten - "ts", // 193 TS Parts, Costs, Robots - "k", // 194 KE Can't, Clown, Key - "k", // 195 KO Comb, Quick, Fox ??? - "k", // 196 EK Speak, Task ??? - "k", // 197 OK Book, Took, October ??? - "p", // 198 PE People, Computer - "p" // 199 PO Paw, Copy ??? -}; - -#endif diff --git a/src/emucore/SpeakJet.hxx b/src/emucore/SpeakJet.hxx deleted file mode 100644 index 531c0a4c5..000000000 --- a/src/emucore/SpeakJet.hxx +++ /dev/null @@ -1,239 +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-2010 by Bradford W. Mott and the Stella Team -// -// See the file "License.txt" for information on usage and redistribution of -// this file, and for a DISCLAIMER OF ALL WARRANTIES. -// -// $Id$ -//============================================================================ - -#ifdef SPEAKJET_EMULATION - -#ifndef SPEAKJET_HXX -#define SPEAKJET_HXX - -/** - Emulation of the Magnevation SpeakJet. - This is the speech synthesizer chip used in the AtariVox. - See AtariVox.hxx and .cxx for AtariVox specifics. - - This class doesn't attempt 100% accurate emulation of the SpeakJet, - as the chip contains a proprietary algorithm that does some complex - modelling (in other words, it doesn't just string samples together). - For this emulation, I use a library called rsynth, which does something - similar (models the human vocal/nasal tract), but is implemented - in a totally different way. You might say I'm emulating the spirit - of the SpeakJet, not the letter :) - - Implementation details: - - Both rsynth and the SpeakJet take a stream of phoneme codes and produce - audio output. - - My SpeakJet class accepts the SpeakJet phonemes, one at a time, and - translates them to rsynth phonemes (which are not quite one-to-one - equivalent). As each phoneme is translated, it's added to a phoneme - buffer. - - Because of the way rsynth is implemented, it needs a full word's worth - of phonemes in its buffer before its speech function is called. This - means I'll only call rsynth_phones() when I receive a SpeakJet code that - indicates a pause, or end-of-word, or a control code (set parameters - or such). This will result in a slight delay (typically, games will - send one SJ code per frame). - - Also due to rsynth's implementation, I have to run it in a thread. This - is because rsynth_phones() is a monolithic function that needs a string - of phonemes, and takes a while to run (for the word "testing", it takes - 1/4 second on an Athlon 64 @ 1800MHz). We can't have the emulator pause - for a quarter second while this happens, so I'll call rsynth_phones() - in a separate thread, and have it fill a buffer from which our main - thread will pull as much data as it needs. A typical word will be - 30-40 thousand samples, and we only need fragsize/2 samples at a time. - - As always when using threads, there will be locking in play... - - rsynth's output is always 16-bit samples. This class will have to - convert them to 8-bit samples before feeding them to the SDL audio - buffer. - - When using the AtariVox, we'll use SDL stereo sound. The regular TIA - sound will come out the left channel, and the speech will come out - the right. This isn't ideal, but it's the easiest way to mix the two - (I don't want to add an SDL_mixer dependency). The real SpeakJet uses a - separate speaker from the 2600 (the 2600 TIA sound comes from the TV, - the SJ sound comes from a set of PC speakers), so splitting them to - the left and right channels isn't unreasonable... However, it means - no game can simultaneously use stereo sound and the AtariVox (for now, - anyway). - - @author B. Watson - @version $Id$ -*/ - -#include "bspf.hxx" - -#include -#include -#include "rsynth/rsynth.h" - -struct SpeechBuffer; - - -enum { INPUT_BUFFER_SIZE = 128 }; -enum { OUTPUT_BUFFER_SIZE = 128 }; -enum { SPEECH_BUFFERS = 1024 }; -static SDL_sem *ourInputSemaphore; -static rsynth_t *rsynth; -static darray_t rsynthSamples; -// phonemeBuffer holds *translated* phonemes (e.g. rsynth phonemes, -// not SpeakJet phonemes). -static char phonemeBuffer[INPUT_BUFFER_SIZE]; -// How many bytes are in the input buffer? -static uInt16 ourInputCount; - - -class SpeakJet -{ - public: - /** - Create a new SpeakJet with given buffer size. We use a circular linked - list of fixed size, each node being a buffer of bufferSize 8-bit - samples. - - @param bufferSize The size of each output buffer, presumably equal - to fragsize/2. - */ - SpeakJet(); - - virtual ~SpeakJet(); - - public: - /** - Writes a SpeakJet phoneme (or other code). - These are the codes from page 16 of the Speaket User Manual. - Not all codes are emulated. In particular, the non-speech noises - (200 thru 254) will be treated as silence. Also, not all the - control codes will actually work (will document later). - - @param code The SpeakJet code being written to the emulated chip - */ - void write(uInt8 code); - - /** - Returns a buffer full of 8-bit samples. This should be called every - frame or so, or else the older buffers will get overwritten by new - data. - - @param count This will be set to the number of samples that are - returned. Value ranges from 0 to bufferSize. - */ - uInt8 *getSamples(int *count); - - /** - Returns false if the phonemeBuffer is full, true otherwise. - */ - bool chipReady(); - - private: - // function that spawns the rsynth thread - void spawnThread(); - - // function that the rsynth thread runs... - // ...and it has to be a *function*, not a method, because SDL's - // written in C. Dammit. - static int thread(void *data); - - private: - // These functions are called from the rsynth thread context only - - // speak() is our locking wrapper for rsynth_phones() - static void speak(); - - static void *save_sample(void *user_data, - float sample, - unsigned nsamp, - rsynth_t *rsynth); - - static void *flush_samples(void *user_data, - unsigned nsamp, - rsynth_t *rsynth); - - static short clip(long *clip_max, float input, float *peak); - - private: - - // True if last code was 20 thru 29 - bool needParameter; - - static const char *ourPhonemeTable[]; - - SDL_Thread *ourThread; - - SpeechBuffer *myCurrentOutputBuffer; - - // We use this semaphore like so: - // Main thread locks it initially - // Main thread gathers up phonemes, storing in the input buffer, - // until it hits a pause/space, - // then unlocks the semaphore. - // The rsynth thread blocks on the semaphore until the main thread - // is done feeding data into the buffer. - // When the rsynth thread unblocks, it quickly copies the buffer to - // a private buffer, then unlocks the semaphore so the main thread - // can re-use the buffer. - - // Note to self: locking decrements the semaphore; unlocking increments - // To lock (blocking): SDL_SemWait() - // To unlock: SDL_SemPost() - - // Each output buffer also needs its own locking semaphore: - // rsynth thread locks each buffer as it fills it, then unlocks it - // when it's done, and moves on to the next buffer in the circular - // list (blocking if it's locked). - - // When the main thread is ready to play audio, it grabs its idea - // of what the next buffer is (blocking if it's locked), locks it, mixes - // its contents with the TIA audio data (if it's not an empty buffer), - // clears the buffer, then unlocks it. - // Note that, if the rsynth thread has been sleeping a while, all - // the buffers might be empty. - - // When the rsynth thread runs out of input, it should probably - // listen on a condition, so it can be woken up when there's something - // to do. - - private: - // Convert a SpeakJet phoneme into one or more rsynth phonemes. - // Input range is 0 to 255, but not all codes are supported yet. - static const char *xlatePhoneme(uInt8 code); - -}; - -// Where our output samples go. -struct SpeechBuffer -{ - SDL_sem *lock; - SpeechBuffer *next; - int items; - uInt8 contents[OUTPUT_BUFFER_SIZE]; -}; - -// For now, just a static array of them -static SpeechBuffer outputBuffers[SPEECH_BUFFERS]; - -static SpeechBuffer *ourCurrentWriteBuffer; -static uInt8 ourCurrentWritePosition; - -#endif - -#endif diff --git a/src/emucore/module.mk b/src/emucore/module.mk index 4cf482e1c..89c5d9b65 100644 --- a/src/emucore/module.mk +++ b/src/emucore/module.mk @@ -56,7 +56,6 @@ MODULE_OBJS := \ src/emucore/SaveKey.o \ src/emucore/Serializer.o \ src/emucore/Settings.o \ - src/emucore/SpeakJet.o \ src/emucore/Switches.o \ src/emucore/StateManager.o \ src/emucore/System.o \ diff --git a/src/gui/TabWidget.cxx b/src/gui/TabWidget.cxx index 4a5dbefa5..be0e95815 100644 --- a/src/gui/TabWidget.cxx +++ b/src/gui/TabWidget.cxx @@ -120,7 +120,7 @@ void TabWidget::disableTab(int tabID) assert(0 <= tabID && tabID < (int)_tabs.size()); _tabs[tabID].enabled = false; - // TODO - alsa disable all widgets belonging to this tab + // TODO - also disable all widgets belonging to this tab } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/yacc/YaccParser.cxx b/src/yacc/YaccParser.cxx index dfe334937..153fb5fbc 100644 --- a/src/yacc/YaccParser.cxx +++ b/src/yacc/YaccParser.cxx @@ -167,7 +167,6 @@ int const_to_int(char *c) { } } -// TODO: store in a map or something // special methods that get e.g. CPU registers CPUDEBUG_INT_METHOD getCpuSpecial(char *c) {