sync with latest IGOR.TBL

svn-id: r29598
This commit is contained in:
Gregory Montoir 2007-11-21 21:50:11 +00:00
parent e28fd1edb7
commit a9f42051dd
6 changed files with 146 additions and 133 deletions

View File

@ -40,7 +40,11 @@ static const IgorGameDescription igorGameDescriptions[] = {
{
"igor",
"Demo 1.00s",
AD_ENTRY1s("IGOR.DAT", 0, 4086790),
{
{ "IGOR.DAT", 0, 0, 4086790 },
{ "IGOR.FSD", 0, 0, 462564 },
{ 0, 0, 0, 0 }
},
Common::EN_ANY,
Common::kPlatformPC,
Common::ADGF_DEMO
@ -51,13 +55,32 @@ static const IgorGameDescription igorGameDescriptions[] = {
{
"igor",
"Demo 1.10s",
AD_ENTRY1s("IGOR.DAT", 0, 4094103),
{
{ "IGOR.DAT", 0, 0, 4094103 },
{ "IGOR.FSD", 0, 0, 462564 },
{ 0, 0, 0, 0 }
},
Common::EN_ANY,
Common::kPlatformPC,
Common::ADGF_DEMO
},
Igor::kIdEngDemo110
},
{
{
"igor",
"Talkie",
{
{ "IGOR.EXE", 0, 0, 9115648 },
{ "IGOR.DAT", 0, 0, 61682719 },
{ 0, 0, 0, 0 }
},
Common::ES_ESP,
Common::kPlatformPC,
Common::ADGF_NO_FLAGS
},
Igor::kIdSpaCD
},
{ AD_TABLE_END_MARKER, 0 }
};
@ -69,7 +92,7 @@ static const PlainGameDescriptor igorGameDescriptors[] = {
static const Common::ADParams igorDetectionParams = {
(const byte *)igorGameDescriptions,
sizeof(IgorGameDescription),
0, // no md5
1024, // number of md5 bytes
igorGameDescriptors,
0,
"igor",

View File

@ -64,6 +64,8 @@ IgorEngine::IgorEngine(OSystem *system, int gameVersion)
IgorEngine::~IgorEngine() {
delete _midiPlayer;
free(_resourceEntries);
free(_soundOffsets);
Common::clearAllSpecialDebugLevels();
free(_screenVGA);
for (int i = 0; i < 4; ++i) {
@ -110,7 +112,7 @@ void IgorEngine::restart() {
_actionCode = 0;
_actionWalkPoint = 0;
memset(_inputVars, 0, sizeof(_inputVars));
memset(_musicSequenceTable, 0, sizeof(_musicSequenceTable));
_musicData = 0;
_talkDelay = _talkSpeechCounter = _talkDelayCounter = 0;
memset(_dialogueTextsTable, 0, sizeof(_dialogueTextsTable));
@ -140,7 +142,7 @@ void IgorEngine::restart() {
_executeMainAction = 0;
_executeRoomAction = 0;
_previousMusic = 0;
memset(_musicSequenceTable, 0, sizeof(_musicSequenceTable));
_musicData = 0;
_actionCode = 0;
_actionWalkPoint = 0;
memset(_inputVars, 0, sizeof(_inputVars));
@ -151,6 +153,11 @@ void IgorEngine::restart() {
_updateDialogue = 0;
_updateRoomBackground = 0;
_resourceEntriesCount = 0;
_resourceEntries = 0;
_soundOffsetsCount = 0;
_soundOffsets = 0;
_gameTicks = 0;
}
@ -161,14 +168,17 @@ int IgorEngine::go() {
if (_currentPart == 0) {
_currentPart = kStartupPart;
}
if (!_ovlFile.open("IGOR.DAT")) {
error("Unable to open 'IGOR.DAT'");
const char *ovlFileName = "IGOR.DAT";
const char *fsdFileName = "IGOR.FSD";
if (_gameVersion == kIdSpaCD) {
ovlFileName = "IGOR.EXE";
fsdFileName = "IGOR.DAT";
}
if (!_sndFile.open("IGOR.FSD")) {
error("Unable to open 'IGOR.FSD'");
if (!_ovlFile.open(ovlFileName)) {
error("Unable to open '%s'", ovlFileName);
}
if (!_tblFile.open("IGOR.TBL")) {
error("Unable to open 'IGOR.TBL'");
if (!_sndFile.open(fsdFileName)) {
error("Unable to open '%s'", fsdFileName);
}
readResourceTableFile();
loadMainTexts();
@ -180,25 +190,43 @@ int IgorEngine::go() {
PART_MAIN();
_ovlFile.close();
_sndFile.close();
_tblFile.close();
return 0;
}
void IgorEngine::readResourceTableFile() {
if (_tblFile.readUint32BE() == MKID_BE('ITBL') && _tblFile.readUint32BE() == 1) {
Common::File tblFile;
uint32 resourcesEntriesOffset = 0, soundEntriesOffset = 0;
if (tblFile.open("IGOR.TBL") && tblFile.readUint32BE() == MKID_BE('ITBL') && tblFile.readUint32BE() == 2) {
tblFile.skip(4);
uint32 borlandOverlaySize = _ovlFile.size();
int gameVersionsCount = _tblFile.readByte();
int gameVersionsCount = tblFile.readByte();
for (int i = 0; i < gameVersionsCount; ++i) {
uint32 size = _tblFile.readUint32BE();
uint32 offs = _tblFile.readUint32BE();
uint32 size = tblFile.readUint32BE();
if (size == borlandOverlaySize) {
_tblFile.seek(offs);
_resourceEntriesCount = _tblFile.readUint16BE();
_resourceEntriesOffset = offs + 2;
return;
resourcesEntriesOffset = tblFile.readUint32BE();
soundEntriesOffset = tblFile.readUint32BE();
break;
}
tblFile.skip(8);
}
}
if (resourcesEntriesOffset != 0 && soundEntriesOffset != 0) {
tblFile.seek(resourcesEntriesOffset);
_resourceEntriesCount = tblFile.readUint16BE();
_resourceEntries = (ResourceEntry *)malloc(sizeof(ResourceEntry) * _resourceEntriesCount);
for (int i = 0; i < _resourceEntriesCount; ++i) {
_resourceEntries[i].id = tblFile.readUint16BE();
_resourceEntries[i].offs = tblFile.readUint32BE();
_resourceEntries[i].size = tblFile.readUint32BE();
}
tblFile.seek(soundEntriesOffset);
_soundOffsetsCount = tblFile.readUint16BE();
_soundOffsets = (uint32 *)malloc(sizeof(uint32) * _soundOffsetsCount);
for (int i = 0; i < _soundOffsetsCount; ++i) {
_soundOffsets[i] = tblFile.readUint32BE();
}
return;
}
error("Unable to read 'IGOR.TBL'");
}
@ -255,11 +283,12 @@ void IgorEngine::waitForTimer(int ticks) {
return;
}
_gameTicks += kTimerTicksCount;
if (_gameTicks == 64) {
if (_gameTicks == 64) { // TODO: original switches cursors more often
_gameTicks = 0;
setCursor(_currentCursor);
_currentCursor = (_currentCursor + 1) & 3;
}
// TODO: updateMusic();
}
void IgorEngine::copyArea(uint8 *dst, int dstOffset, int dstPitch, const uint8 *src, int srcPitch, int w, int h, bool transparent) {
@ -280,89 +309,60 @@ void IgorEngine::copyArea(uint8 *dst, int dstOffset, int dstPitch, const uint8 *
}
int IgorEngine::getRandomNumber(int m) {
assert(m != 0);
return rand() % m;
assert(m > 0);
return _rnd.getRandomNumber(m - 1);
}
void IgorEngine::startMusic(int cmf) {
_midiPlayer->stopMusic();
free(_musicData);
int musicDataSize;
_musicData = loadData(cmf, 0, &musicDataSize);
_midiPlayer->playMusic(_musicData, musicDataSize);
}
void IgorEngine::playMusic(int num) {
debugC(9, kDebugEngine, "playMusic() %d", num);
const int *seq = 0;
switch (num) {
case 2: {
static const int cmf[] = { CMF_2_1, CMF_2_2, CMF_2_3, CMF_2_4, 0 };
seq = cmf;
}
break;
case 3: {
static const int cmf[] = { CMF_3, 0 };
seq = cmf;
}
break;
case 4: {
static const int cmf[] = { CMF_4, 0 };
seq = cmf;
}
break;
case 7: {
static const int cmf[] = { CMF_7_1, CMF_7_2, CMF_7_3, CMF_7_4, 0 };
seq = cmf;
}
break;
case 8: {
static const int cmf[] = { CMF_8, 0 };
seq = cmf;
}
break;
case 9: {
static const int cmf[] = { CMF_9, 0 };
seq = cmf;
}
break;
case 10: {
static const int cmf[] = { CMF_10, 0 };
seq = cmf;
}
break;
case 11: {
static const int cmf[] = { CMF_11, 0 };
seq = cmf;
}
break;
case 12: {
static const int cmf[] = { CMF_12, 0 };
seq = cmf;
}
break;
}
if (seq) {
for (int i = 0; i < 5; ++i) {
free(_musicSequenceTable[i].data);
}
for (int i = 0; seq[i]; ++i) {
_musicSequenceTable[i].data = loadData(seq[i], 0, &_musicSequenceTable[i].dataSize);
}
}
static const int cmf[] = { 0, 0, CMF_2_1, CMF_3, CMF_4, 0, 0, CMF_7_1, CMF_8, CMF_9, CMF_10, CMF_11, CMF_12 };
assert(num < ARRAYSIZE(cmf) && cmf[num] != 0);
_gameState.musicNum = num;
_gameState.musicSequenceIndex = 1;
_midiPlayer->playMusic(_musicSequenceTable[0].data, _musicSequenceTable[0].dataSize);
if (_gameVersion == kIdSpaCD) {
// different file format
return;
}
startMusic(cmf[num]);
}
void IgorEngine::updateMusic() {
static const int cmf2Seq[] = { CMF_2_1, CMF_2_2, CMF_2_3, CMF_2_4 };
static const int cmf7Seq[] = { CMF_7_1, CMF_7_2, CMF_7_3, CMF_7_4 };
if (_gameState.jumpToNextMusic) {
if (_gameState.musicNum == 2) {
switch (_gameState.musicNum) {
case 2:
_gameState.musicSequenceIndex = getRandomNumber(4) + 1;
startMusic(cmf2Seq[_gameState.musicSequenceIndex - 1]);
// _timerHandler0x1CCounter = 5;
} else if (_gameState.musicNum == 3 || _gameState.musicNum == 4 || _gameState.musicNum == 8 || _gameState.musicNum == 9 || _gameState.musicNum == 10) {
// _timerHandler0x1CCounter = 50;
} else if (_gameState.musicNum == 7) {
break;
case 7:
if (_gameState.musicSequenceIndex == 4) {
_gameState.musicSequenceIndex = 1;
} else {
++_gameState.musicSequenceIndex;
}
startMusic(cmf7Seq[_gameState.musicSequenceIndex - 1]);
// _timerHandler0x1CCounter = 5;
} else if (_gameState.musicNum == 11) {
break;
case 3:
case 4:
case 8:
case 9:
case 10:
// _timerHandler0x1CCounter = 50;
break;
case 11:
// _timerHandler0x1CCounter = 5;
break;
}
}
}
@ -377,7 +377,8 @@ void IgorEngine::playSound(int num, int fl) {
return;
}
--num;
_sndFile.seek(_fdsOffsetsTable[num]);
assert(num >= 0 && num < _soundOffsetsCount);
_sndFile.seek(_soundOffsets[num]);
Audio::AudioStream *stream = Audio::makeVOCStream(_sndFile);
if (stream) {
_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_sfxHandle, stream);
@ -633,30 +634,31 @@ int IgorEngine::getObjectFromInventory(int x) const {
return 0;
}
ResourceEntry IgorEngine::findData(int id) {
assert(id >= 1 && id <= _resourceEntriesCount);
_tblFile.seek(_resourceEntriesOffset + (id - 1) * 10);
ResourceEntry re;
re.id = _tblFile.readUint16BE();
re.offs = _tblFile.readUint32BE();
re.size = _tblFile.readUint32BE();
assert(re.id == id);
static int compareResourceEntry(const void *a, const void *b) {
int id = *(const int *)a;
const ResourceEntry *entry = (const ResourceEntry *)b;
return id - entry->id;
}
ResourceEntry *IgorEngine::findData(int id) {
ResourceEntry *re = (ResourceEntry *)bsearch(&id, _resourceEntries, _resourceEntriesCount, sizeof(ResourceEntry), compareResourceEntry);
assert(re);
return re;
}
uint8 *IgorEngine::loadData(int id, uint8 *dst, int *size) {
ResourceEntry re = findData(id);
debugC(9, kDebugResource, "loadData() id %d offset %d size %d", id, re.offs, re.size);
debugC(9, kDebugResource, "loadData() id %d", id);
ResourceEntry *re = findData(id);
if (!dst) {
dst = (uint8 *)malloc(re.size);
dst = (uint8 *)malloc(re->size);
if (!dst) {
error("Unable to allocate %d bytes", re.size);
error("Unable to allocate %d bytes", re->size);
}
}
_ovlFile.seek(re.offs);
_ovlFile.read(dst, re.size);
_ovlFile.seek(re->offs);
_ovlFile.read(dst, re->size);
if (size) {
*size = re.size;
*size = re->size;
}
return dst;
}
@ -811,7 +813,7 @@ void IgorEngine::loadAnimData(const int *anm, int loadOffset) {
void IgorEngine::loadActionData(int act) {
if (act != 0) {
assert(findData(act).size <= 0x2000);
assert(findData(act)->size <= 0x2000);
loadData(act, _roomActionsTable);
}
}

View File

@ -311,6 +311,7 @@ protected:
int getRandomNumber(int m);
void handleOptionsMenu();
void handlePause();
void startMusic(int cmf);
void playMusic(int num);
void updateMusic();
void playSound(int num, int fl);
@ -323,7 +324,7 @@ protected:
void startIgorDialogue();
void waitForEndOfIgorDialogue();
int getObjectFromInventory(int x) const;
ResourceEntry findData(int num);
ResourceEntry *findData(int num);
uint8 *loadData(int num, uint8 *dst = 0, int *size = 0);
void decodeMainText(const uint8 *p);
void decodeRoomStrings(const uint8 *p, bool skipObjectNames = false);
@ -400,9 +401,10 @@ protected:
MidiPlayer *_midiPlayer;
Common::RandomSource _rnd;
Common::File _ovlFile;
Common::File _sndFile;
Common::File _tblFile;
Audio::SoundHandle _sfxHandle;
@ -468,10 +470,7 @@ protected:
ExecuteActionProc _executeMainAction;
ExecuteActionProc _executeRoomAction;
uint8 _previousMusic;
struct {
uint8 *data;
int dataSize;
} _musicSequenceTable[5];
uint8 *_musicData;
Action _currentAction;
uint8 _actionCode;
uint8 _actionWalkPoint;
@ -487,7 +486,9 @@ protected:
UpdateRoomBackgroundProc _updateRoomBackground;
int _gameTicks;
int _resourceEntriesCount;
int _resourceEntriesOffset;
ResourceEntry *_resourceEntries;
int _soundOffsetsCount;
uint32 *_soundOffsets;
char _saveStateDescriptions[kMaxSaveStates][100];
static const uint8 _dialogueColor[];
@ -504,7 +505,6 @@ protected:
static const uint8 _walkScaleTable[];
static const uint8 _mouseCursorMask[];
static const uint8 _mouseCursorData[];
static const uint32 _fdsOffsetsTable[];
//

View File

@ -69,10 +69,9 @@ void IgorEngine::PART_90() {
_inputVars[kInputEscape] = 0;
fadeOutPalette(768);
if (_currentPart != kInvalidPart) {
if (_currentPart == 904) {
++_currentPart;
if ((_gameVersion == kIdSpaCD && _currentPart == 904) || _currentPart == 905) {
_currentPart = 850;
} else {
++_currentPart;
}
}
}

View File

@ -585,13 +585,13 @@ void IgorEngine::UPDATE_OBJECT_STATE(int num) {
if (num == 1 || num == 255) {
switch (_objectsState[0]) {
case 0:
memcpy(_globalObjectNames + 0x592 / 62, " bottle of whisky", 30);
strcpy(_globalObjectNames[23], " bottle of whisky");
break;
case 1:
memcpy(_globalObjectNames + 0x592 / 62, " empty bottle", 30);
strcpy(_globalObjectNames[23], " empty bottle");
break;
case 2:
memcpy(_globalObjectNames + 0x592 / 62, " bottle of water", 30);
strcpy(_globalObjectNames[23], " bottle of water");
break;
}
}
@ -599,21 +599,21 @@ void IgorEngine::UPDATE_OBJECT_STATE(int num) {
switch (_objectsState[1]) {
case 0:
_inventoryImages[23] = 27;
memcpy(_globalObjectNames + 0x5D0 / 62, " lizard", 30);
strcpy(_globalObjectNames[24], " lizard");
break;
default:
_inventoryImages[23] = 35;
memcpy(_globalObjectNames + 0x5D0 / 62, " fat lizard", 30);
strcpy(_globalObjectNames[24], " fat lizard");
break;
}
}
if (num == 4 || num == 255) {
switch (_objectsState[3]) {
case 0:
memcpy(_globalObjectNames + 0x554 / 62, " Caroline%s folder", 30);
strcpy(_globalObjectNames[22], " Caroline%s folder");
break;
case 1:
memcpy(_globalObjectNames + 0x554 / 62, " Philip%s folder", 30);
strcpy(_globalObjectNames[22], " Philip%s folder");
break;
}
}
@ -632,10 +632,10 @@ void IgorEngine::UPDATE_OBJECT_STATE(int num) {
}
if (num == 8 || num == 255) {
if (_objectsState[7] == 0) {
memcpy(_globalObjectNames + 0x60E / 62, " statuette", 30);
strcpy(_globalObjectNames[25], " statuette");
_inventoryImages[24] = 29;
} else {
memcpy(_globalObjectNames + 0x60E / 62, " reward", 30);
strcpy(_globalObjectNames[25], " reward");
_inventoryImages[24] = 39;
}
}

View File

@ -904,17 +904,6 @@ const uint8 IgorEngine::_mouseCursorData[] = {
0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05
};
const uint32 IgorEngine::_fdsOffsetsTable[] = {
0x000000, 0x000001, 0x000002, 0x0018E4, 0x003301, 0x003302, 0x003303, 0x003304,
0x003305, 0x003306, 0x003307, 0x003308, 0x003309, 0x003EEB, 0x005908, 0x005909,
0x00590A, 0x01542C, 0x016418, 0x016419, 0x01D37F, 0x01E4A1, 0x01F42C, 0x01F95F,
0x026B80, 0x026B81, 0x026B82, 0x026B83, 0x026B84, 0x026B85, 0x026B86, 0x026B87,
0x026B88, 0x02CA59, 0x02DD76, 0x02ED6A, 0x02ED6B, 0x02ED6C, 0x02ED6D, 0x02ED6E,
0x02ED6F, 0x02ED70, 0x02ED71, 0x02ED72, 0x02ED73, 0x047F4F, 0x047F50, 0x04AC64,
0x04EFC5, 0x052755, 0x052756, 0x052988, 0x058119, 0x05811A, 0x06202A, 0x06202B,
0x06202C, 0x06202D, 0x06202E, 0x06202F, 0x062030, 0x062031, 0x070CB2
};
const uint8 IgorEngine::PAL_48_1[] = {
0x2D, 0x16, 0x00, 0x3D, 0x26, 0x01, 0x32, 0x32, 0x24, 0x16, 0x1D, 0x16, 0x12, 0x19, 0x12, 0x0B,
0x12, 0x0B, 0x32, 0x32, 0x24, 0x16, 0x1D, 0x16, 0x12, 0x19, 0x12, 0x0B, 0x12, 0x0B, 0x3D, 0x3D,