TONY: Implement more of the music related code from the original

This commit is contained in:
Paul Gilbert 2012-06-19 20:50:48 +10:00
parent 0aa3d39cf7
commit 61d460a854
6 changed files with 673 additions and 286 deletions

View file

@ -2198,14 +2198,14 @@ DECLARE_CUSTOM_FUNCTION(DemuteJingle)(CORO_PARAM, uint32, uint32, uint32, uint32
void CustPlayMusic(uint32 nChannel, const char *mFN, uint32 nFX, bool bLoop, int nSync = 0) { void CustPlayMusic(uint32 nChannel, const char *mFN, uint32 nFX, bool bLoop, int nSync = 0) {
if (nSync == 0) if (nSync == 0)
nSync = 2000; nSync = 2000;
debug("Start CustPlayMusic"); debugC(DEBUG_INTERMEDIATE, kTonyDebugMusic, "Start CustPlayMusic");
GLOBALS.PlayMusic(nChannel, mFN, nFX, bLoop, nSync); GLOBALS.PlayMusic(nChannel, mFN, nFX, bLoop, nSync);
debug("End CustPlayMusic"); debugC(DEBUG_INTERMEDIATE, kTonyDebugMusic, "End CustPlayMusic");
} }
DECLARE_CUSTOM_FUNCTION(PlaySoundEffect)(CORO_PARAM, uint32 nMusic, uint32 nFX, uint32 bNoLoop, uint32) { DECLARE_CUSTOM_FUNCTION(PlaySoundEffect)(CORO_PARAM, uint32 nMusic, uint32 nFX, uint32 bNoLoop, uint32) {
if (nFX == 0 || nFX == 1 || nFX == 2) { if (nFX == 0 || nFX == 1 || nFX == 2) {
debug("PlaySoundEffect stop fadeout"); debugC(DEBUG_INTERMEDIATE, kTonyDebugSound, "PlaySoundEffect stop fadeout");
GLOBALS._bFadeOutStop = true; GLOBALS._bFadeOutStop = true;
} }

View file

@ -473,8 +473,6 @@ void RMGfxEngine::init() {
delete load; delete load;
// Display 'Loading' screen // Display 'Loading' screen
// TODO: The loading screen isn't currently optimal, since the game doesn't respond to events
// whilst the mpalInit code is being executed.
_vm->_window.getNewFrame(*this, NULL); _vm->_window.getNewFrame(*this, NULL);
_vm->_window.repaint(); _vm->_window.repaint();

File diff suppressed because it is too large Load diff

View file

@ -245,6 +245,24 @@ public:
bool endOfBuffer() const; bool endOfBuffer() const;
}; };
/**
* Codec base class
*/
class CODEC {
protected:
bool _bEndReached;
public:
bool _bLoop;
CODEC(bool _bLoop = true);
virtual ~CODEC();
virtual uint32 decompress(Common::SeekableReadStream *stream, void *lpBuf, uint32 dwSize) = 0;
virtual void loopReset() = 0;
bool endOfStream();
};
class FPStream { class FPStream {
private: private:
// HWND hwnd; // HWND hwnd;
@ -258,12 +276,12 @@ private:
uint32 _dwSize; // Stream size (bytes) uint32 _dwSize; // Stream size (bytes)
uint32 _dwCodec; // CODEC used uint32 _dwCodec; // CODEC used
HANDLE _hThreadEnd; // Event used to close thread uint32 _hThreadEnd; // Event used to close thread
Common::File _file; // File handle used for the stream Common::File _file; // File handle used for the stream
HANDLE _hPlayThread; // Handle of the Play thread uint32 _hPlayThread; // Handle of the Play thread
HANDLE _hHot1, _hHot2, _hHot3; // Events set by DirectSoundNotify uint32 _hHot1, _hHot2, _hHot3; // Events set by DirectSoundNotify
HANDLE _hPlayThreadPlayFast; uint32 _hPlayThreadPlayFast;
HANDLE _hPlayThreadPlayNormal; uint32 _hPlayThreadPlayNormal;
bool _bSoundSupported; // True if the sound is active bool _bSoundSupported; // True if the sound is active
bool _bFileLoaded; // True if the file is open bool _bFileLoaded; // True if the file is open
@ -273,6 +291,7 @@ private:
bool _bPaused; bool _bPaused;
int _lastVolume; int _lastVolume;
FPStream *_syncToPlay; FPStream *_syncToPlay;
CODEC *_codec;
// DSBPOSITIONNOTIFY dspnHot[3]; // DSBPOSITIONNOTIFY dspnHot[3];
@ -286,7 +305,7 @@ private:
* Thread playing the stream * Thread playing the stream
* *
*/ */
static void playThread(FPStream *This); static void playThread(CORO_PARAM, const void *param);
public: public:
@ -321,13 +340,13 @@ public:
/** /**
* Opens a file stream * Opens a file stream
* *
* @param lpszFile Filename to be opened * @param fileName Filename to be opened
* @param dwCodec CODEC to be used to uncompress samples * @param dwCodec CODEC to be used to uncompress samples
* *
* @returns True is everything is OK, False otherwise * @returns True is everything is OK, False otherwise
*/ */
bool loadFile(const char *lpszFileName, uint32 dwCodec = FPCODEC_RAW, int nSync = 2000); bool loadFile(const Common::String &fileName, uint32 dwCodec = FPCODEC_RAW, int nSync = 2000);
/** /**
* Closes a file stream (opened or not). * Closes a file stream (opened or not).

View file

@ -187,10 +187,7 @@ void TonyEngine::GUIError(const Common::String &msg) {
GUIErrorMessage(msg); GUIErrorMessage(msg);
} }
void TonyEngine::playMusic(int nChannel, const char *fn, int nFX, bool bLoop, int nSync) { void TonyEngine::playMusic(int nChannel, const Common::String &fname, int nFX, bool bLoop, int nSync) {
warning("TODO: TonyEngine::playMusic");
// g_system->lockMutex(csMusic);
if (nChannel < 4) if (nChannel < 4)
if (GLOBALS._flipflop) if (GLOBALS._flipflop)
nChannel = nChannel + 1; nChannel = nChannel + 1;
@ -207,64 +204,78 @@ void TonyEngine::playMusic(int nChannel, const char *fn, int nFX, bool bLoop, in
break; break;
} }
#ifdef REFACTOR_ME
// Mette il path giusto
if (nChannel < 4)
GetDataDirectory(DD_MUSIC, path_buffer);
else
GetDataDirectory(DD_LAYER, path_buffer);
_splitpath(path_buffer, drive, dir, NULL, NULL);
_splitpath(fn, NULL, NULL, fname, ext);
_makepath(path_buffer, drive, dir, fname, ext);
_makepath(path_buffer, drive, dir, fname, ext);
if (nFX == 22) { // Sync a tempo if (nFX == 22) { // Sync a tempo
curChannel = nChannel; GLOBALS._curChannel = nChannel;
strcpy(nextMusic, path_buffer); GLOBALS._nextLoop = bLoop;
nextLoop = bLoop; GLOBALS._nextSync = nSync;
nextSync = nSync; if (GLOBALS._flipflop)
if (flipflop) GLOBALS._nextChannel = nChannel - 1;
nextChannel = nChannel - 1;
else else
nextChannel = nChannel + 1; GLOBALS._nextChannel = nChannel + 1;
DWORD id;
HANDLE hThread = CreateThread(NULL, 10240, (LPTHREAD_START_ROUTINE)DoNextMusic, _stream, 0, &id);
SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST);
} else if (nFX == 44) { // Cambia canale e lascia finire il primo
if (flipflop)
nextChannel = nChannel - 1;
else
nextChannel = nChannel + 1;
_stream[nextChannel]->Stop(); uint32 hThread = CoroScheduler.createProcess(doNextMusic, &_stream, sizeof(FPStream ***));
_stream[nextChannel]->UnloadFile(); assert(hThread != CORO_INVALID_PID_VALUE);
} else if (nFX == 44) { // Cambia canale e lascia finire il primo
if (GLOBALS._flipflop)
GLOBALS._nextChannel = nChannel - 1;
else
GLOBALS._nextChannel = nChannel + 1;
_stream[GLOBALS._nextChannel]->stop();
_stream[GLOBALS._nextChannel]->unloadFile();
if (!getIsDemo()) { if (!getIsDemo()) {
if (!_stream[nextChannel]->LoadFile(path_buffer, FPCODEC_ADPCM, nSync)) if (!_stream[GLOBALS._nextChannel]->loadFile(fname, FPCODEC_ADPCM, nSync))
theGame.Abort(); _vm->abortGame();
} else { } else {
_stream[nextChannel]->LoadFile(path_buffer, FPCODEC_ADPCM, nSync); _stream[GLOBALS._nextChannel]->loadFile(fname, FPCODEC_ADPCM, nSync);
} }
_stream[nextChannel]->SetLoop(bLoop); _stream[GLOBALS._nextChannel]->setLoop(bLoop);
_stream[nextChannel]->Play(); _stream[GLOBALS._nextChannel]->play();
flipflop = 1 - flipflop; GLOBALS._flipflop = 1 - GLOBALS._flipflop;
} else { } else {
if (!getIsDemo()) { if (!getIsDemo()) {
if (!_stream[nChannel]->LoadFile(path_buffer, FPCODEC_ADPCM, nSync)) if (!_stream[nChannel]->loadFile(fname, FPCODEC_ADPCM, nSync))
theGame.Abort(); _vm->abortGame();
} else { } else {
_stream[nChannel]->LoadFile(path_buffer, FPCODEC_ADPCM, nSync); _stream[nChannel]->loadFile(fname, FPCODEC_ADPCM, nSync);
} }
_stream[nChannel]->SetLoop(bLoop); _stream[nChannel]->setLoop(bLoop);
_stream[nChannel]->Play(); _stream[nChannel]->play();
} }
#endif }
// g_system->unlockMutex(csMusic); void TonyEngine::doNextMusic(CORO_PARAM, const void *param) {
CORO_BEGIN_CONTEXT;
Common::String fn;
CORO_END_CONTEXT(_ctx);
FPStream **streams = *(FPStream ***)param;
CORO_BEGIN_CODE(_ctx);
if (!_vm->getIsDemo()) {
if (!streams[GLOBALS._nextChannel]->loadFile(GLOBALS._nextMusic, FPCODEC_ADPCM, GLOBALS._nextSync))
_vm->abortGame();
} else {
streams[GLOBALS._nextChannel]->loadFile(GLOBALS._nextMusic, FPCODEC_ADPCM, GLOBALS._nextSync);
}
streams[GLOBALS._nextChannel]->setLoop(GLOBALS._nextLoop);
streams[GLOBALS._nextChannel]->prefetch();
streams[GLOBALS._curChannel]->stop(true);
streams[GLOBALS._curChannel]->waitForSync(streams[GLOBALS._nextChannel]);
streams[GLOBALS._curChannel]->unloadFile();
GLOBALS._flipflop = 1 - GLOBALS._flipflop;
CORO_END_CODE;
} }
void TonyEngine::playSFX(int nChannel, int nFX) { void TonyEngine::playSFX(int nChannel, int nFX) {

View file

@ -87,6 +87,8 @@ private:
void closeVoiceDatabase(); void closeVoiceDatabase();
void initCustomFunctionMap(); void initCustomFunctionMap();
static void playProcess(CORO_PARAM, const void *param); static void playProcess(CORO_PARAM, const void *param);
static void doNextMusic(CORO_PARAM, const void *param);
protected: protected:
// Engine APIs // Engine APIs
virtual Common::Error run(); virtual Common::Error run();
@ -183,7 +185,7 @@ public:
// Music // Music
// ****** // ******
void playMusic(int nChannel, const char *fn, int nFX, bool bLoop, int nSync); void playMusic(int nChannel, const Common::String &fn, int nFX, bool bLoop, int nSync);
void stopMusic(int nChannel); void stopMusic(int nChannel);
void playSFX(int nSfx, int nFX = 0); void playSFX(int nSfx, int nFX = 0);