GROOVIE: TLC Music / Small Bugfixes / Better Comments

This commit is contained in:
Christian Lindemann 2018-10-05 23:28:22 +02:00 committed by Filippos Karapetis
parent e0ed66fe58
commit 6525123663
7 changed files with 514 additions and 341 deletions

View File

@ -180,28 +180,42 @@ Common::Error GroovieEngine::run() {
error("GROOVIE: Unknown Game version. groovie.cpp:run()");
}
// Detect ScummVM Music Enhancement Project presence (T7G only)
if (Common::File::exists("gu16.ogg") && _gameDescription->version == kGroovieT7G) {
// Load player for external files
_musicPlayer = new MusicPlayerIOS(this);
} else {
// Create the music player
switch (getPlatform()) {
case Common::kPlatformMacintosh:
if (_gameDescription->version == kGroovieT7G)
_musicPlayer = new MusicPlayerMac_t7g(this);
else
_musicPlayer = new MusicPlayerMac_v2(this);
break;
case Common::kPlatformIOS:
switch (_gameDescription->version) {
case kGroovieT7G:
case kGroovieT11H:
case kGroovieCDY:
case kGroovieUHP:
// Detect ScummVM Music Enhancement Project presence (T7G only)
if (Common::File::exists("gu16.ogg") && _gameDescription->version == kGroovieT7G) {
// Load player for external files
_musicPlayer = new MusicPlayerIOS(this);
break;
default:
_musicPlayer = new MusicPlayerXMI(this, _gameDescription->version == kGroovieT7G ? "fat" : "sample");
break;
}
else {
// Create the music player
switch (getPlatform()) {
case Common::kPlatformMacintosh:
if (_gameDescription->version == kGroovieT7G)
_musicPlayer = new MusicPlayerMac_t7g(this);
else
_musicPlayer = new MusicPlayerMac_v2(this);
break;
case Common::kPlatformIOS:
_musicPlayer = new MusicPlayerIOS(this);
break;
default:
_musicPlayer = new MusicPlayerXMI(this, _gameDescription->version == kGroovieT7G ? "fat" : "sample");
break;
}
}
break;
case kGroovieTLC:
_musicPlayer = new MusicPlayerTlc(this);
break;
}
// Load volume levels
syncSoundSettings();
@ -268,7 +282,7 @@ Common::Error GroovieEngine::run() {
// Check that the game files and the audio tracks aren't together run from
// the same cd
if (getPlatform() != Common::kPlatformIOS) {
if (getPlatform() != Common::kPlatformIOS && _gameDescription->version != kGroovieTLC) {
if (!existExtractedCDAudioFiles()
&& !isDataAndCDAudioReadFromSameCD()) {
warnMissingExtractedCDAudio();

View File

@ -26,6 +26,7 @@
#include "groovie/music.h"
#include "groovie/groovie.h"
#include "groovie/resource.h"
#include "groovie/tlcgame.h"
#include "backends/audiocd/audiocd.h"
#include "common/config-manager.h"
@ -37,6 +38,7 @@
#include "audio/audiostream.h"
#include "audio/midiparser.h"
#include "audio/miles.h"
#include "audio/decoders/mp3.h"
namespace Groovie {
@ -746,4 +748,59 @@ bool MusicPlayerIOS::load(uint32 fileref, bool loop) {
return true;
}
MusicPlayerTlc::MusicPlayerTlc(GroovieEngine *vm) : MusicPlayer(vm) {
vm->getTimerManager()->installTimerProc(&onTimer, 50 * 1000, this, "groovieMusic");
}
MusicPlayerTlc::~MusicPlayerTlc() {
_vm->getTimerManager()->removeTimerProc(&onTimer);
}
void MusicPlayerTlc::updateVolume() {
// Just set the mixer volume for the music sound type
_vm->_system->getMixer()->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, _userVolume * _gameVolume / 100);
}
void MusicPlayerTlc::unload() {
MusicPlayer::unload();
_vm->_system->getMixer()->stopHandle(_handle);
}
bool MusicPlayerTlc::load(uint32 fileref, bool loop) {
// Find correct filename
Common::String filename;
Common::File *fileHandle = new Common::File();
Audio::SeekableAudioStream *seekStream = NULL;
// Create the audio stream from fileref
filename = TlcGame::getTlcMusicFilename(fileref);
fileHandle->open(filename);
if (fileHandle->isOpen()) {
seekStream = Audio::makeMP3Stream(fileHandle, DisposeAfterUse::YES);
} else {
delete fileHandle;
}
if (!seekStream) {
warning("Could not play audio file '%s'", filename.c_str());
return false;
}
Audio::AudioStream *audStream = seekStream;
// Loop if requested
if (loop || 1)
audStream = Audio::makeLoopingAudioStream(seekStream, 0);
// MIDI player handles volume reset on load, IOS player doesn't - force update here
updateVolume();
// Play!
_vm->_system->getMixer()->playStream(Audio::Mixer::kMusicSoundType, &_handle, audStream);
return true;
}
} // End of Groovie namespace

View File

@ -35,6 +35,7 @@ class MidiParser;
namespace Groovie {
class GroovieEngine;
class TlcGame;
class MusicPlayer {
public:
@ -204,6 +205,20 @@ private:
Audio::SoundHandle _handle;
};
class MusicPlayerTlc : public MusicPlayer {
public:
MusicPlayerTlc(GroovieEngine *vm);
~MusicPlayerTlc();
protected:
void updateVolume();
bool load(uint32 fileref, bool loop);
void unload();
private:
Audio::SoundHandle _handle;
};
} // End of Groovie namespace
#endif // GROOVIE_MUSIC_H

File diff suppressed because it is too large Load Diff

View File

@ -146,8 +146,9 @@ private:
uint32 readScript32bits();
uint16 readScript8or16bits();
uint8 readScriptChar(bool allow7C, bool limitVal, bool limitVar);
void readScriptString(Common::String &str);
uint8 readScriptVar();
uint32 getVideoRefString();
uint32 getVideoRefString(Common::String &resName);
bool hotspot(Common::Rect rect, uint16 addr, uint8 cursor);
@ -243,6 +244,7 @@ private:
void o2_printstring();
void o2_playsong();
void o2_midicontrol();
void o2_setbackgroundsong();
void o2_videofromref();
void o2_vdxtransition();

View File

@ -34,7 +34,7 @@
namespace Groovie {
// This a list of files for background music. These list is hard-coded in the TLC player.
const Common::String kTlcMidiFiles[] = {"ep01epm.mpg", "ep01tatm.mpg", "amb_hs.mpg", "amb_mr.mpg", "amb_kr.mpg", "amb_mo.mpg", "music_rc.mpg", "amb_ds.mpg", "amb_ds3.mpg", "amb_jr.mpg", "amb_mr4.mpg", "amb_jr4.mpg", "amb_jr2.mpg", "amb_kr2.mpg", "amb_mr2.mpg", "amb_br.mpg", "amb_ds2.mpg", "amb_jr3.mpg", "amb_ds4.mpg", "amb_kr3.mpg", "amb_to1.mpg", "amb_to2.mpg", "ep02epm.mpg", "ep02tatm.mpg", "ep03epm.mpg", "ep03tatm.mpg", "ep04epm.mpg", "ep04tatm.mpg", "ep05epm.mpg", "ep05tatm.mpg", "ep06epm.mpg", "ep06tatm.mpg", "ep07epm.mpg", "ep07tatm.mpg", "ep08epm.mpg", "ep08tatm.mpg", "ep09epm.mpg", "ep09tatm.mpg", "ep10epm.mpg", "ep10tatm.mpg", "ep11epm.mpg", "ep11tatm.mpg", "ep12epm.mpg", "ep12tatm.mpg", "ep13epm.mpg", "ep13tatm.mpg", "ep14epm.mpg", "ep14tatm.mpg", "ep15epm.mpg", "ep15tatm.mpg" };
const Common::String kTlcMusicFiles[] = {"ep01epm.mpg", "ep01tatm.mpg", "amb_hs.mpg", "amb_mr.mpg", "amb_kr.mpg", "amb_mo.mpg", "music_rc.mpg", "amb_ds.mpg", "amb_ds3.mpg", "amb_jr.mpg", "amb_mr4.mpg", "amb_jr4.mpg", "amb_jr2.mpg", "amb_kr2.mpg", "amb_mr2.mpg", "amb_br.mpg", "amb_ds2.mpg", "amb_jr3.mpg", "amb_ds4.mpg", "amb_kr3.mpg", "amb_to1.mpg", "amb_to2.mpg", "ep02epm.mpg", "ep02tatm.mpg", "ep03epm.mpg", "ep03tatm.mpg", "ep04epm.mpg", "ep04tatm.mpg", "ep05epm.mpg", "ep05tatm.mpg", "ep06epm.mpg", "ep06tatm.mpg", "ep07epm.mpg", "ep07tatm.mpg", "ep08epm.mpg", "ep08tatm.mpg", "ep09epm.mpg", "ep09tatm.mpg", "ep10epm.mpg", "ep10tatm.mpg", "ep11epm.mpg", "ep11tatm.mpg", "ep12epm.mpg", "ep12tatm.mpg", "ep13epm.mpg", "ep13tatm.mpg", "ep14epm.mpg", "ep14tatm.mpg", "ep15epm.mpg", "ep15tatm.mpg" };
const uint8 kTlcEpQuestToPlay[] = { 0x0E, 0x0F, 0x0B, 0x10, 0x11, 0x12, 0x0C, 0x0C, 0x09, 0x06, 0x0F, 0x0C, 0x0B, 0x0D, 0x0D };
@ -78,6 +78,10 @@ uint16 inline TlcGame::getScriptVar16(uint16 var) {
return value;
}
// Gets the filename of the background music file.
Common::String TlcGame::getTlcMusicFilename(int musicId) {
return kTlcMusicFiles[musicId];
}
void TlcGame::opRegions() {
if (_scriptVariables[0x1A] == 1) {

View File

@ -1,94 +1,96 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef GROOVIE_TLCGAME_H
#define GROOVIE_TLCGAME_H
#include "common/textconsole.h"
#include "common/random.h"
#define GROOVIE_TLC_MAX_EPSIODES (15)
#define GROOVIE_TLC_MAX_QUEST_EP (50)
namespace Groovie {
class GroovieEngine;
// The regions.rle contains 898 entries. Round about 18 kByte in memory.
struct TlcRegionsHeader {
char name[12];
int numAnswers;
uint32 offset;
};
struct TlcRegion {
uint16 left;
uint16 top;
uint16 right;
uint16 bottom;
};
struct TlcEpQuestionData {
bool questionUsed;
uint32 questionScore;
};
struct TlcTatHeader {
uint32 questionsNum;
uint32 questionsOffset;
uint8 binDividends[16];
};
struct TlcTatAnswer {
uint8 binScore[8];
};
struct TlcTatQuestions {
char name[6];
int answerCount;
TlcTatAnswer answerData[8];
};
class TlcGame
{
public:
TlcGame();
~TlcGame();
/**
* Sets a pointer to the script variables. This makes it easier if we want
* to debug write accesses to the script variables
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef GROOVIE_TLCGAME_H
#define GROOVIE_TLCGAME_H
#include "common/textconsole.h"
#include "common/random.h"
#define GROOVIE_TLC_MAX_EPSIODES (15)
#define GROOVIE_TLC_MAX_QUEST_EP (50)
namespace Groovie {
class GroovieEngine;
// The regions.rle contains 898 entries. Round about 18 kByte in memory.
struct TlcRegionsHeader {
char name[12];
int numAnswers;
uint32 offset;
};
struct TlcRegion {
uint16 left;
uint16 top;
uint16 right;
uint16 bottom;
};
struct TlcEpQuestionData {
bool questionUsed;
uint32 questionScore;
};
struct TlcTatHeader {
uint32 questionsNum;
uint32 questionsOffset;
uint8 binDividends[16];
};
struct TlcTatAnswer {
uint8 binScore[8];
};
struct TlcTatQuestions {
char name[6];
int answerCount;
TlcTatAnswer answerData[8];
};
class TlcGame
{
public:
TlcGame();
~TlcGame();
static Common::String getTlcMusicFilename(int musicId);
/**
* Sets a pointer to the script variables. This makes it easier if we want
* to debug write accesses to the script variables
* @param scriptVariables The current variables from the script.
*/
void setVariables(byte *scriptVariables);
*/
void setVariables(byte *scriptVariables);
/**
* Handle region commands. A region describes the coordinates of
* a rectangle as clickable area in the question dialogs. These regions
* are provided by a the extra file.
* screen coordinates.
*/
void opRegions();
*/
void opRegions();
/**
* Get the coordiantes of the region for the next answer. There are
* up to 8 answers possible for each question. In the script the
@ -99,95 +101,95 @@ public:
* @param bottom Bottom value of the rectangle
* @return 0 if anwer was found. -1 in case no more answer
* available for this question
*/
int getRegionNext(uint16 &left, uint16 &top, uint16 &right, uint16 &bottom);
*/
int getRegionNext(uint16 &left, uint16 &top, uint16 &right, uint16 &bottom);
/**
* Rewinds the internal answer counter for the function
* getRegionNext()
*/
void getRegionRewind();
/**
* Handles some flags which are used during a TAT. The game seems to
* use this flags to skip some questions during a TAT.
* OpCode_0x42(2)
*/
void opFlags();
/**
* Handles all Exit Poll commands. The exit poll (EP) questions are
* described in detail in the file EPAIDB.RLE.
* OpCode_0x42(1)
*/
void opExitPoll();
/**
* Handles all TAT commands. The TAT questions are described in detail
* in the file TATAIDB.RLE
*/
void opTat();
private:
Common::RandomSource _random;
void inline setScriptVar(uint16 var, byte value);
void inline setScriptVar16(uint16 var, uint16 value);
uint16 inline getScriptVar16(uint16 var);
byte *_scriptVariables;
*/
void getRegionRewind();
/**
* Handles some flags which are used during a TAT. The game seems to
* use this flags to skip some questions during a TAT.
* OpCode_0x42(2)
*/
void opFlags();
/**
* Handles all Exit Poll commands. The exit poll (EP) questions are
* described in detail in the file EPAIDB.RLE.
* OpCode_0x42(1)
*/
void opExitPoll();
/**
* Handles all TAT commands. The TAT questions are described in detail
* in the file TATAIDB.RLE
*/
void opTat();
private:
Common::RandomSource _random;
void inline setScriptVar(uint16 var, byte value);
void inline setScriptVar16(uint16 var, uint16 value);
uint16 inline getScriptVar16(uint16 var);
byte *_scriptVariables;
/**
* Loads the description part of the regions.rle file into memory
* This makes it faster to search for the correct quesion.
*/
void regionsInit();
void regionsLoad();
// Variables for region handling
int _numRegionHeaders;
int _curAnswerIndex;
int _curQuestNumAnswers;
TlcRegion _curQuestRegions[8];
TlcRegionsHeader *_regionHeader;
/**
* Functions for Exit Poll Commands
*/
void epInit();
void epSelectNextQuestion();
void epResultQuestion();
void epResultEpisode();
// Variables for Exit Poll handling
int16 _epScoreBin[6];
int _epEpisodeIdx; // 15 Episodes: 0..14
int _epQuestionIdx; // 1..X (questions in current episode. counted up for every question)
int _epQuestionNumOfPool; // 1..X (question number in the data base. The questions are played in random order)
int _epQuestionsInEpisode;
TlcEpQuestionData *_epQuestionsData;
// Variables for flag handling
byte _tatFlags[0x0E][0x09];
/**
* Functions for TAT Commands
*/
void tatInitRegs();
void tatLoadDB();
void tatResultQuest();
void tatResultEpisode();
void tatGetProfile();
// Variables for TAT handling
int _tatCount;
int _tatQuestCount;
TlcTatHeader *_tatHeaders;
TlcTatQuestions *_tatQuestions;
uint8 _tatCoeffs[15][16];
};
} // End of Groovie namespace
#endif // GROOVIE_TLCGAME_H
*/
void regionsInit();
void regionsLoad();
// Variables for region handling
int _numRegionHeaders;
int _curAnswerIndex;
int _curQuestNumAnswers;
TlcRegion _curQuestRegions[8];
TlcRegionsHeader *_regionHeader;
/**
* Functions for Exit Poll Commands
*/
void epInit();
void epSelectNextQuestion();
void epResultQuestion();
void epResultEpisode();
// Variables for Exit Poll handling
int16 _epScoreBin[6];
int _epEpisodeIdx; // 15 Episodes: 0..14
int _epQuestionIdx; // 1..X (questions in current episode. counted up for every question)
int _epQuestionNumOfPool; // 1..X (question number in the data base. The questions are played in random order)
int _epQuestionsInEpisode;
TlcEpQuestionData *_epQuestionsData;
// Variables for flag handling
byte _tatFlags[0x0E][0x09];
/**
* Functions for TAT Commands
*/
void tatInitRegs();
void tatLoadDB();
void tatResultQuest();
void tatResultEpisode();
void tatGetProfile();
// Variables for TAT handling
int _tatCount;
int _tatQuestCount;
TlcTatHeader *_tatHeaders;
TlcTatQuestions *_tatQuestions;
uint8 _tatCoeffs[15][16];
};
} // End of Groovie namespace
#endif // GROOVIE_TLCGAME_H