LOL: some work on the music handling

svn-id: r35929
This commit is contained in:
Florian Kagerer 2009-01-19 23:35:27 +00:00
parent 98ba7247b1
commit 017b39eae0
4 changed files with 181 additions and 32 deletions

View File

@ -63,7 +63,9 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
_landsFile = 0; _landsFile = 0;
_levelLangFile = 0; _levelLangFile = 0;
_lastMusicTrack = -1;
_lastSfxTrack = -1; _lastSfxTrack = -1;
_curTlkFile = -1;
memset(_moneyColumnHeight, 0, 5); memset(_moneyColumnHeight, 0, 5);
_credits = 0; _credits = 0;
@ -122,6 +124,7 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
_lampOilStatus = _brightness = _lampStatusUnk = 0; _lampOilStatus = _brightness = _lampStatusUnk = 0;
_tempBuffer5120 = 0; _tempBuffer5120 = 0;
_tmpData136 = 0;
_lvlBuffer = 0; _lvlBuffer = 0;
_unkGameFlag = 0; _unkGameFlag = 0;
@ -149,6 +152,7 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
_musicTrackMap = 0; _musicTrackMap = 0;
_curMusicTheme = -1; _curMusicTheme = -1;
_curMusicFileExt = 0; _curMusicFileExt = 0;
_curMusicFileIndex = -1;
_sceneDrawVar1 = _sceneDrawVar2 = _sceneDrawVar3 = _wllProcessFlag = 0; _sceneDrawVar1 = _sceneDrawVar2 = _sceneDrawVar3 = _wllProcessFlag = 0;
_unkCmzU1 = _unkCmzU2 = 0; _unkCmzU1 = _unkCmzU2 = 0;
@ -229,6 +233,7 @@ LoLEngine::~LoLEngine() {
delete[] _lvlShapeBottom; delete[] _lvlShapeBottom;
delete[] _lvlShapeLeftRight; delete[] _lvlShapeLeftRight;
delete[] _tempBuffer5120; delete[] _tempBuffer5120;
delete[] _tmpData136;
delete[] _lvlBuffer; delete[] _lvlBuffer;
delete[] _levelBlockProperties; delete[] _levelBlockProperties;
delete[] _lvl415; delete[] _lvl415;
@ -332,7 +337,11 @@ Common::Error LoLEngine::init() {
_tempBuffer5120 = new uint8[5120]; _tempBuffer5120 = new uint8[5120];
memset(_tempBuffer5120, 0, 5120); memset(_tempBuffer5120, 0, 5120);
_tmpData136 = new uint8[136];
memset(_tmpData136, 0, 136);
memset(_gameFlags, 0, 15 * sizeof(uint16)); memset(_gameFlags, 0, 15 * sizeof(uint16));
memset(_unkEMC46, 0, 16 * sizeof(uint16));
_lvlShpHeader = 0; _lvlShpHeader = 0;
_levelFileData = 0; _levelFileData = 0;
@ -468,7 +477,7 @@ void LoLEngine::preInit() {
_eventList.clear(); _eventList.clear();
//loadTalkFile(0); loadTalkFile(0);
char filename[32]; char filename[32];
snprintf(filename, sizeof(filename), "LANDS.%s", _languageExt[_lang]); snprintf(filename, sizeof(filename), "LANDS.%s", _languageExt[_lang]);
@ -1402,6 +1411,27 @@ void LoLEngine::setupScreenDims() {
_screen->modifyScreenDim(5, 85, 123, 233, 18); _screen->modifyScreenDim(5, 85, 123, 233, 18);
} }
void LoLEngine::loadTalkFile(int index) {
char file[8];
if (index == _curTlkFile)
return;
if (_curTlkFile >= 0) {
snprintf(file, sizeof(file), "%02d.TLK", _curTlkFile);
_res->unloadPakFile(file);
}
snprintf(file, sizeof(file), "%02d.TLK", index);
_res->loadPakFile(file);
_curTlkFile = index;
}
void LoLEngine::snd_playVoiceFile(int) {
}
void LoLEngine::snd_playSoundEffect(int track, int volume) { void LoLEngine::snd_playSoundEffect(int track, int volume) {
debugC(9, kDebugLevelMain | kDebugLevelSound, "LoLEngine::snd_playSoundEffect(%d, %d)", track, volume); debugC(9, kDebugLevelMain | kDebugLevelSound, "LoLEngine::snd_playSoundEffect(%d, %d)", track, volume);
@ -1433,24 +1463,53 @@ void LoLEngine::snd_playSoundEffect(int track, int volume) {
} }
} }
void LoLEngine::snd_playTrack(int track) { void LoLEngine::snd_loadSoundFile(int track) {
if (_unkGameFlag & 2) { if (_unkGameFlag & 2) {
char filename[13]; char filename[13];
int t = (track - 250) * 3; int t = (track - 250) * 3;
if (_curMusicTheme != _musicTrackMap[t] || _curMusicFileExt != (char)_musicTrackMap[t + 1]) { if (_curMusicFileIndex != _musicTrackMap[t] || _curMusicFileExt != (char)_musicTrackMap[t + 1]) {
snd_stopMusic();
snprintf(filename, sizeof(filename), "LORE%02d%c", _musicTrackMap[t], (char)_musicTrackMap[t + 1]); snprintf(filename, sizeof(filename), "LORE%02d%c", _musicTrackMap[t], (char)_musicTrackMap[t + 1]);
_sound->loadSoundFile(filename); _sound->loadSoundFile(filename);
_curMusicTheme = _musicTrackMap[t]; _curMusicFileIndex = _musicTrackMap[t];
_curMusicFileExt = (char)_musicTrackMap[t + 1]; _curMusicFileExt = (char)_musicTrackMap[t + 1];
} else {
snd_stopMusic();
} }
_sound->playTrack(_musicTrackMap[t + 2]);
} else { } else {
//XXX
} }
} }
int LoLEngine::snd_playTrack(int track) {
if (track == -1)
return _lastMusicTrack;
int res = _lastMusicTrack;
_lastMusicTrack = track;
if (_unkGameFlag & 2) {
snd_loadSoundFile(track);
int t = (track - 250) * 3;
_sound->playTrack(_musicTrackMap[t + 2]);
}
return res;
}
int LoLEngine::snd_stopMusic() {
if (_unkGameFlag & 2) {
if (_sound->isPlaying()) {
_sound->beginFadeOut();
_system->delayMillis(3 * _tickLength);
}
_sound->haltTrack();
}
return snd_playTrack(-1);
}
#pragma mark - Opcodes #pragma mark - Opcodes
typedef Common::Functor1Mem<EMCState*, int, LoLEngine> OpcodeV2; typedef Common::Functor1Mem<EMCState*, int, LoLEngine> OpcodeV2;
@ -1512,7 +1571,7 @@ void LoLEngine::setupOpcodeTable() {
// 0x1C // 0x1C
OpcodeUnImpl(); OpcodeUnImpl();
OpcodeUnImpl(); OpcodeUnImpl();
OpcodeUnImpl(); Opcode(o2_setMusicTrack);
OpcodeUnImpl(); OpcodeUnImpl();
// 0x20 // 0x20
@ -1534,9 +1593,9 @@ void LoLEngine::setupOpcodeTable() {
OpcodeUnImpl(); OpcodeUnImpl();
// 0x2C // 0x2C
OpcodeUnImpl(); OpcodeUnImpl();
OpcodeUnImpl(); Opcode(o2_getUnkArrayVal);
OpcodeUnImpl(); Opcode(o2_setUnkArrayVal);
OpcodeUnImpl(); OpcodeUnImpl();
// 0x30 // 0x30
@ -1615,7 +1674,7 @@ void LoLEngine::setupOpcodeTable() {
OpcodeUnImpl(); OpcodeUnImpl();
OpcodeUnImpl(); OpcodeUnImpl();
OpcodeUnImpl(); OpcodeUnImpl();
Opcode(o2_playTrack); Opcode(o2_loadSoundFile);
// 0x64 // 0x64
OpcodeUnImpl(); OpcodeUnImpl();

View File

@ -108,15 +108,13 @@ struct LevelBlockProperty {
}; };
struct LVL { struct LVL {
uint8 field_0; uint16 itemIndexUnk;
uint8 field_1;
uint8 field_2; uint8 field_2;
uint8 field_3; uint16 field_3;
uint8 field_4;
uint16 blockPropertyIndex; uint16 blockPropertyIndex;
uint16 p_1a; uint16 p_1a;
uint16 p_1b; uint16 p_1b;
uint8 field_B; int8 level;
uint16 p_2a; uint16 p_2a;
uint16 p_2b; uint16 p_2b;
uint8 field_10; uint8 field_10;
@ -258,12 +256,18 @@ private:
void setupTimers() {} void setupTimers() {}
// sound // sound
void snd_playVoiceFile(int) { /* XXX */ } void loadTalkFile(int index);
void snd_playVoiceFile(int);
void snd_playSoundEffect(int track, int volume); void snd_playSoundEffect(int track, int volume);
void snd_playTrack(int track); void snd_loadSoundFile(int track);
int snd_playTrack(int track);
int snd_stopMusic();
int _lastSfxTrack; int _lastSfxTrack;
int _lastMusicTrack;
int _curMusicFileIndex;
char _curMusicFileExt; char _curMusicFileExt;
int _curTlkFile;
int _unkAudioSpecOffs; int _unkAudioSpecOffs;
bool _unkLangAudio; bool _unkLangAudio;
@ -316,8 +320,8 @@ private:
uint16 _currentBlock; uint16 _currentBlock;
bool _boolScriptFuncDone; bool _boolScriptFuncDone;
int16 _scriptExecutedFuncs[18]; int16 _scriptExecutedFuncs[18];
uint16 _gameFlags[15]; uint16 _gameFlags[15];
uint16 _unkEMC46[16];
// emc opcode // emc opcode
int o2_setGameFlag(EMCState *script); int o2_setGameFlag(EMCState *script);
@ -334,11 +338,14 @@ private:
int o2_loadLevelShapes(EMCState *script); int o2_loadLevelShapes(EMCState *script);
int o2_closeLevelShapeFile(EMCState *script); int o2_closeLevelShapeFile(EMCState *script);
int o2_loadDoorShapes(EMCState *script); int o2_loadDoorShapes(EMCState *script);
int o2_setMusicTrack(EMCState *script);
int o2_getUnkArrayVal(EMCState *script);
int o2_setUnkArrayVal(EMCState *script);
int o2_setGlobalVar(EMCState *script); int o2_setGlobalVar(EMCState *script);
int o2_mapShapeToBlock(EMCState *script); int o2_mapShapeToBlock(EMCState *script);
int o2_resetBlockShapeAssignment(EMCState *script); int o2_resetBlockShapeAssignment(EMCState *script);
int o2_loadLangFile(EMCState *script); int o2_loadLangFile(EMCState *script);
int o2_playTrack(EMCState *script); int o2_loadSoundFile(EMCState *script);
int o2_setPaletteBrightness(EMCState *script); int o2_setPaletteBrightness(EMCState *script);
int o2_assignCustomSfx(EMCState *script); int o2_assignCustomSfx(EMCState *script);
@ -451,6 +458,11 @@ private:
void loadLevelShpDat(const char *shpFile, const char *datFile, bool flag); void loadLevelShpDat(const char *shpFile, const char *datFile, bool flag);
void loadLevelGraphics(const char *file, int specialColor, int weight, int vcnLen, int vmpLen, const char *palFile); void loadLevelGraphics(const char *file, int specialColor, int weight, int vcnLen, int vmpLen, const char *palFile);
void resetItems(int flag);
void resetLvlBuffer();
void resetBlockProperties();
bool testWallInvisibility(int block, int direction);
void drawScene(int pageNum); void drawScene(int pageNum);
void generateBlockDrawingBuffer(int block, int direction); void generateBlockDrawingBuffer(int block, int direction);
@ -551,6 +563,7 @@ private:
uint8 _unkGameFlag; uint8 _unkGameFlag;
uint8 *_tempBuffer5120; uint8 *_tempBuffer5120;
uint8 *_tmpData136;
const char *const * _levelDatList; const char *const * _levelDatList;
int _levelDatListSize; int _levelDatListSize;

View File

@ -26,6 +26,7 @@
#include "kyra/lol.h" #include "kyra/lol.h"
#include "kyra/screen_lol.h" #include "kyra/screen_lol.h"
#include "kyra/resource.h" #include "kyra/resource.h"
#include "kyra/sound.h"
#include "common/endian.h" #include "common/endian.h"
@ -36,7 +37,7 @@ void LoLEngine::loadLevel(int index) {
setMouseCursorToIcon(0x85); setMouseCursorToIcon(0x85);
_scriptFuncIndex = 0; _scriptFuncIndex = 0;
// TODO snd_stopMusic();
updatePortraits(); updatePortraits();
@ -44,18 +45,24 @@ void LoLEngine::loadLevel(int index) {
delete[] _levelShapes[i]; delete[] _levelShapes[i];
_levelShapes[i] = 0; _levelShapes[i] = 0;
} }
_emc->unload(&_scriptData); _emc->unload(&_scriptData);
_currentLevel = index; resetItems(1);
_charFlagUnk = 0; resetLvlBuffer();
resetBlockProperties();
releaseMonsterShapes(0); releaseMonsterShapes(0);
releaseMonsterShapes(1); releaseMonsterShapes(1);
//TODO // TODO
_currentLevel = index;
_charFlagUnk = 0;
// TODO
loadTalkFile(index);
//loadTalkFile(index);
loadLevelWLL(index, true); loadLevelWLL(index, true);
_loadLevelFlag = 1; _loadLevelFlag = 1;
@ -85,7 +92,8 @@ void LoLEngine::loadLevel(int index) {
_screen->setPaletteBrightness(_screen->_currentPalette, _brightness, _lampOilStatus); _screen->setPaletteBrightness(_screen->_currentPalette, _brightness, _lampOilStatus);
setMouseCursorToItemInHand(); setMouseCursorToItemInHand();
//TODO
snd_playTrack(_curMusicTheme);
} }
void LoLEngine::addLevelItems() { void LoLEngine::addLevelItems() {
@ -106,7 +114,7 @@ int LoLEngine::initCmzWithScript(int block) {
while (i) { while (i) {
void *t = cmzGetItemOffset(i); void *t = cmzGetItemOffset(i);
i = (i & 0x8000) ? ((LVL*)t)->field_0 : ((ItemInPlay*)t)->itemIndexUnk; i = (i & 0x8000) ? ((LVL*)t)->itemIndexUnk : ((ItemInPlay*)t)->itemIndexUnk;
if (!(i & 0x8000)) if (!(i & 0x8000))
continue; continue;
@ -680,6 +688,59 @@ void LoLEngine::loadLevelGraphics(const char *file, int specialColor, int weight
_loadSuppFilesFlag = 1; _loadSuppFilesFlag = 1;
} }
void LoLEngine::resetItems(int flag) {
for (int i = 0; i < 1024; i++) {
_levelBlockProperties[i].field_8 = 5;
uint16 id = _levelBlockProperties[i].itemIndex;
LVL * r = 0;
while (id & 0x8000) {
LVL * r = (LVL*) cmzGetItemOffset(id);
id = r->itemIndexUnk;
}
if (!id)
continue;
ItemInPlay *it = &_itemsInPlay[id];
it->level = _currentLevel;
it->blockPropertyIndex = i;
r->itemIndexUnk = 0;
}
if (flag)
memset(_tmpData136, 0, 136);
}
void LoLEngine::resetLvlBuffer() {
memset(_lvlBuffer, 0, 30 * sizeof(LVL));
for (int i = 0; i < 30; i++)
_lvlBuffer[i].field_14 = 0x10;
}
void LoLEngine::resetBlockProperties() {
for (int i = 0; i < 1024; i++) {
LevelBlockProperty *l = &_levelBlockProperties[i];
if (l->flags & 0x10) {
l->flags &= 0xef;
if (testWallInvisibility(i, 0) && testWallInvisibility(i, 1))
l->flags |= 0x40;
} else {
if (l->flags & 0x40)
l->flags &= 0xbf;
else if (l->flags & 0x80)
l->flags &= 0x7f;
}
}
}
bool LoLEngine::testWallInvisibility(int block, int direction) {
uint8 w = _levelBlockProperties[block].walls[direction];
if (_wllVmpMap[w] || _wllShapeMap[w] || _levelBlockProperties[block].flags & 0x80)
return false;
return true;
}
void LoLEngine::turnOnLamp() { void LoLEngine::turnOnLamp() {
_screen->_drawGuiFlag |= 0x400; _screen->_drawGuiFlag |= 0x400;
_lampOilStatus = 255; _lampOilStatus = 255;
@ -1302,6 +1363,7 @@ void LoLEngine::drawIceShapes(int index, int iceShapeIndex) {
void LoLEngine::drawMonstersAndItems(int index) { void LoLEngine::drawMonstersAndItems(int index) {
} }
void LoLEngine::drawDoor(uint8 *shape, uint8 *table, int index, int unk2, int w, int h, int flags) { void LoLEngine::drawDoor(uint8 *shape, uint8 *table, int index, int unk2, int w, int h, int flags) {

View File

@ -354,6 +354,21 @@ int LoLEngine::o2_loadDoorShapes(EMCState *script) {
return 1; return 1;
} }
int LoLEngine::o2_setMusicTrack(EMCState *script) {
_curMusicTheme = stackPos(0);
return 1;
}
int LoLEngine::o2_getUnkArrayVal(EMCState *script) {
return _unkEMC46[stackPos(0)];
}
int LoLEngine::o2_setUnkArrayVal(EMCState *script) {
int a=stackPos(0);
_unkEMC46[stackPos(0)] = stackPos(1);
return 1;
}
int LoLEngine::o2_setGlobalVar(EMCState *script) { int LoLEngine::o2_setGlobalVar(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::o2_setGlobalVar(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); debugC(3, kDebugLevelScriptFuncs, "LoLEngine::o2_setGlobalVar(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
//uint16 a = stackPos(1); //uint16 a = stackPos(1);
@ -431,9 +446,9 @@ int LoLEngine::o2_loadLangFile(EMCState *script) {
return 1; return 1;
} }
int LoLEngine::o2_playTrack(EMCState *script) { int LoLEngine::o2_loadSoundFile(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::o2_playTrack(%p) (%d)", (const void *)script, stackPos(0)); debugC(3, kDebugLevelScriptFuncs, "LoLEngine::o2_loadSoundFile(%p) (%d)", (const void *)script, stackPos(0));
snd_playTrack(stackPos(0)); snd_loadSoundFile(stackPos(0));
return 1; return 1;
} }