aboutsummaryrefslogtreecommitdiff
path: root/engines/igor/igor.cpp
diff options
context:
space:
mode:
authorGregory Montoir2007-11-25 23:27:51 +0000
committerGregory Montoir2007-11-25 23:27:51 +0000
commit798ce43e19f1f4ee5b95f4de291217bf25a342f9 (patch)
treeb4641214f0b39923c249eaec3ce1a62982cebaf2 /engines/igor/igor.cpp
parent3d59f805202bd1d2161baa69902d377fa01ee7c6 (diff)
downloadscummvm-rg350-798ce43e19f1f4ee5b95f4de291217bf25a342f9.tar.gz
scummvm-rg350-798ce43e19f1f4ee5b95f4de291217bf25a342f9.tar.bz2
scummvm-rg350-798ce43e19f1f4ee5b95f4de291217bf25a342f9.zip
- enabled speech sounds
- added end of demo check for demo 1.10 - simplified parts loop - populated strings table in IGOR.TBL - updated and packed charset data svn-id: r29641
Diffstat (limited to 'engines/igor/igor.cpp')
-rw-r--r--engines/igor/igor.cpp180
1 files changed, 139 insertions, 41 deletions
diff --git a/engines/igor/igor.cpp b/engines/igor/igor.cpp
index 5e761a9e11..f4de78434a 100644
--- a/engines/igor/igor.cpp
+++ b/engines/igor/igor.cpp
@@ -36,10 +36,8 @@
namespace Igor {
-IgorEngine::IgorEngine(OSystem *system, int gameVersion)
- : Engine(system), _gameVersion(gameVersion) {
-
- _midiPlayer = new MidiPlayer(this);
+IgorEngine::IgorEngine(OSystem *system, int gameVersion, int gameFlags, Common::Language language)
+ : Engine(system), _gameVersion(gameVersion), _gameFlags(gameFlags), _gameLanguage(language) {
_screenVGA = (uint8 *)malloc(320 * 200);
for (int i = 0; i < 4; ++i) {
@@ -60,13 +58,17 @@ IgorEngine::IgorEngine(OSystem *system, int gameVersion)
Common::addSpecialDebugLevel(kDebugScreen, "Screen", "Screen debug level");
Common::addSpecialDebugLevel(kDebugWalk, "Walk", "Walk debug level");
Common::addSpecialDebugLevel(kDebugGame, "Game", "Game debug level");
+
+ if (gameFlags & kFlagFloppy) {
+ _midiPlayer = new MidiPlayer(this);
+ } else {
+ _midiPlayer = 0;
+ }
}
IgorEngine::~IgorEngine() {
- delete _midiPlayer;
free(_resourceEntries);
free(_soundOffsets);
- Common::clearAllSpecialDebugLevels();
free(_screenVGA);
for (int i = 0; i < 4; ++i) {
free(_facingIgorFrames[i]);
@@ -80,6 +82,10 @@ IgorEngine::~IgorEngine() {
free(_inventoryPanelBuffer);
free(_inventoryImagesBuffer);
free(_verbsPanelBuffer);
+
+ Common::clearAllSpecialDebugLevels();
+
+ delete _midiPlayer;
}
int IgorEngine::init() {
@@ -98,7 +104,7 @@ void IgorEngine::restart() {
memset(&_gameState, 0, sizeof(_gameState));
_nextTimer = 0;
_fastMode = false;
- _language = kLanguageEnglish;
+ _language = 0;
memset(_walkData, 0, sizeof(_walkData));
_walkCurrentPos = 0;
@@ -158,6 +164,8 @@ void IgorEngine::restart() {
_soundOffsetsCount = 0;
_soundOffsets = 0;
+ _demoActionsCounter = 0;
+
_gameTicks = 0;
}
@@ -170,7 +178,7 @@ int IgorEngine::go() {
}
const char *ovlFileName = "IGOR.DAT";
const char *fsdFileName = "IGOR.FSD";
- if (_gameVersion == kIdSpaCD) {
+ if (_gameFlags & kFlagTalkie) {
ovlFileName = "IGOR.EXE";
fsdFileName = "IGOR.DAT";
}
@@ -180,7 +188,7 @@ int IgorEngine::go() {
if (!_sndFile.open(fsdFileName)) {
error("Unable to open '%s'", fsdFileName);
}
- readResourceTableFile();
+ readTableFile();
loadMainTexts();
loadIgorFrames();
_gameState.talkMode = kTalkModeTextOnly;
@@ -193,11 +201,11 @@ int IgorEngine::go() {
return 0;
}
-void IgorEngine::readResourceTableFile() {
+void IgorEngine::readTableFile() {
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 stringsEntriesOffset = 0, resourcesEntriesOffset = 0, soundEntriesOffset = 0;
+ if (tblFile.open("IGOR.TBL") && tblFile.readUint32BE() == MKID_BE('ITBL') && tblFile.readUint32BE() == 3) {
+ stringsEntriesOffset = tblFile.readUint32BE();
uint32 borlandOverlaySize = _ovlFile.size();
int gameVersionsCount = tblFile.readByte();
for (int i = 0; i < gameVersionsCount; ++i) {
@@ -225,11 +233,38 @@ void IgorEngine::readResourceTableFile() {
for (int i = 0; i < _soundOffsetsCount; ++i) {
_soundOffsets[i] = tblFile.readUint32BE();
}
+ tblFile.seek(stringsEntriesOffset);
+ int stringsCount = tblFile.readUint16BE();
+ for (int i = 0; i < stringsCount; ++i) {
+ int id = tblFile.readUint16BE();
+ int lang = tblFile.readByte();
+ int len = tblFile.readByte();
+ bool skipString = (lang == 1 && _gameLanguage != Common::EN_ANY) || (lang == 2 && _gameLanguage != Common::ES_ESP);
+ if (skipString) {
+ tblFile.skip(len);
+ } else {
+ char buf[256];
+ tblFile.read(buf, len);
+ buf[len] = 0;
+ _stringEntries.push_back(StringEntry(id, buf));
+ }
+ }
return;
}
error("Unable to read 'IGOR.TBL'");
}
+const char *IgorEngine::getString(int id) {
+ const char *str = 0;
+ for (Common::Array<StringEntry>::const_iterator it = _stringEntries.begin(); it != _stringEntries.end(); ++it) {
+ if ((*it).id == id) {
+ str = (*it).str.c_str();
+ break;
+ }
+ }
+ return str;
+}
+
void IgorEngine::waitForTimer(int ticks) {
_system->copyRectToScreen(_screenVGA, 320, 0, _screenVGAVOffset, 320, 200 - _screenVGAVOffset);
_system->updateScreen();
@@ -283,12 +318,16 @@ void IgorEngine::waitForTimer(int ticks) {
return;
}
_gameTicks += kTimerTicksCount;
- if (_gameTicks == 64) { // TODO: original switches cursors more often
- _gameTicks = 0;
+ if ((_gameTicks & 31) == 0) {
setCursor(_currentCursor);
_currentCursor = (_currentCursor + 1) & 3;
}
- // TODO: updateMusic();
+ if (_gameFlags & kFlagFloppy) {
+ updateMusic();
+ }
+ if (_gameTicks == 64) {
+ _gameTicks = 0;
+ }
}
void IgorEngine::copyArea(uint8 *dst, int dstOffset, int dstPitch, const uint8 *src, int srcPitch, int w, int h, bool transparent) {
@@ -323,21 +362,21 @@ void IgorEngine::startMusic(int cmf) {
void IgorEngine::playMusic(int num) {
debugC(9, kDebugEngine, "playMusic() %d", num);
- 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;
- if (_gameVersion == kIdSpaCD) {
- // different file format
- return;
+ if (_gameFlags & kFlagFloppy) {
+ 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;
+ startMusic(cmf[num]);
+ } else {
+ // TODO: play CD track
}
- 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.jumpToNextMusic && 0) { // TODO: enable
switch (_gameState.musicNum) {
case 2:
_gameState.musicSequenceIndex = getRandomNumber(4) + 1;
@@ -367,21 +406,36 @@ void IgorEngine::updateMusic() {
}
}
-void IgorEngine::playSound(int num, int fl) {
+void IgorEngine::playSound(int num, int type) {
debugC(9, kDebugEngine, "playSound() %d", num);
- if (fl && _mixer->isSoundHandleActive(_sfxHandle)) {
- return;
- }
- if (!fl) {
-// num = 20; // "Speech not recorded"
+ --num;
+ int soundOffset = -1;
+ Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType;
+ Audio::SoundHandle *soundHandle = 0;
+ if (type == 1) {
+ if (_mixer->isSoundHandleActive(_sfxHandle)) {
+ return;
+ }
+ assert(num >= 0 && num < _soundOffsetsCount);
+ soundOffset = _soundOffsets[num];
+ soundType = Audio::Mixer::kSFXSoundType;
+ soundHandle = &_sfxHandle;
+ } else if (type == 0 && (_gameFlags & kFlagTalkie) != 0 && num != kNoSpeechSound) {
+ if (_mixer->isSoundHandleActive(_speechHandle)) {
+ _mixer->stopHandle(_speechHandle);
+ }
+ num += 100;
+ assert(num >= 0 && num < _soundOffsetsCount);
+ soundOffset = _soundOffsets[num];
+ soundType = Audio::Mixer::kSpeechSoundType;
+ soundHandle = &_speechHandle;
+ } else {
return;
}
- --num;
- assert(num >= 0 && num < _soundOffsetsCount);
- _sndFile.seek(_soundOffsets[num]);
+ _sndFile.seek(soundOffset);
Audio::AudioStream *stream = Audio::makeVOCStream(_sndFile);
if (stream) {
- _mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_sfxHandle, stream);
+ _mixer->playInputStream(soundType, soundHandle, stream);
}
}
@@ -398,6 +452,15 @@ void IgorEngine::loadIgorFrames() {
memcpy(_igorPalette, PAL_IGOR_1, 48);
}
+void IgorEngine::loadIgorFrames2() {
+ loadData(FRM_IgorDirBack2, _facingIgorFrames[0]);
+ loadData(FRM_IgorDirRight2, _facingIgorFrames[1]);
+ loadData(FRM_IgorDirFront2, _facingIgorFrames[2]);
+ loadData(FRM_IgorDirLeft2, _facingIgorFrames[3]);
+ loadData(FRM_IgorHead2, _igorHeadFrames);
+ memcpy(_igorPalette, PAL_IGOR_2, 48);
+}
+
void IgorEngine::fixDialogueTextPosition(int num, int count, int *x, int *y) {
int textLineWidth = 0;
for (int i = 0; i < count; ++i) {
@@ -527,9 +590,6 @@ void IgorEngine::fixIgorDialogueTextPosition(int num, int count, int *x, int *y)
void IgorEngine::startIgorDialogue() {
debugC(9, kDebugEngine, "startIgorDialogue()");
-// if (_dialogueCursorOn) {
-// clearCursor();
-// }
--_dialogueTextsCount;
int talkX, talkY;
const DialogueText *dt = &_dialogueTextsTable[_dialogueTextsStart];
@@ -997,8 +1057,10 @@ void IgorEngine::drawString(uint8 *dst, const char *s, int x, int y, int color1,
}
for (int j = 0; j < 11; ++j) {
uint8 *p = dst + (j + y) * 320 + x + dx;
- for (int i = 0; i < 9; ++i) {
- uint8 code = _fontData[(chr * 11 + j) * 9 + i];
+ uint32 chrMask = _fontData[chr * 11 + j];
+ for (int i = 0; i < 9; ++i, chrMask >>= 2) {
+// uint8 code = _fontData[(chr * 11 + j) * 9 + i];
+ uint8 code = chrMask & 3;
if (code == 1) {
p[i] = color1;
} else if (code == 2 && color2 != -1) {
@@ -1393,7 +1455,7 @@ void IgorEngine::handleRoomInput() {
}
if (_inputVars[kInputCursorYPos] >= 156 && _inputVars[kInputCursorYPos] <= 167) {
if (_inputVars[kInputClick]) {
- int verb = _verbAreasTable[_inputVars[kInputCursorXPos]];
+ int verb = getVerbUnderCursor(_inputVars[kInputCursorXPos]);
if (verb != _currentAction.verb) {
redrawVerb(_currentAction.verb, false);
_currentAction.verb = verb;
@@ -1702,6 +1764,42 @@ void IgorEngine::handleRoomLight() {
}
}
+void IgorEngine::enterPartLoop() {
+ if (!_gameState.dialogueTextRunning) {
+ showCursor();
+ }
+ _gameState.igorMoving = false;
+ if (_gameVersion == kIdEngDemo110) {
+ CHECK_FOR_END_OF_DEMO();
+ }
+}
+
+void IgorEngine::leavePartLoop() {
+ hideCursor();
+ SET_EXEC_ACTION_FUNC(1, 0);
+ _updateRoomBackground = 0;
+}
+
+void IgorEngine::runPartLoop() {
+ handleRoomInput();
+ if (compareGameTick(1, 16)) {
+ handleRoomIgorWalk();
+ }
+ if (compareGameTick(19, 32)) {
+ handleRoomDialogue();
+ }
+ if (compareGameTick(4, 8)) {
+ handleRoomInventoryScroll();
+ }
+ if (compareGameTick(1)) {
+ handleRoomLight();
+ }
+ if (_updateRoomBackground) {
+ (this->*_updateRoomBackground)();
+ }
+ waitForTimer();
+}
+
int IgorEngine::lookupScale(int xOffset, int yOffset, int h) const {
int index = READ_LE_UINT16(_walkScaleTable + 0x734 + _walkWidthScaleTable[h - 1] * 2);
int offset = _walkScaleTable[0x4FC + index + xOffset];