aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicola Mettifogo2007-08-12 19:11:37 +0000
committerNicola Mettifogo2007-08-12 19:11:37 +0000
commit3465571b121fdcaba1b97f0a52b1aa16a25390a5 (patch)
treece450e7d458ed4eda0de1e5bb68bac95a94d2430
parentd7b6f0ecc849ec4dbd6916f2ce466caae7343dc0 (diff)
downloadscummvm-rg350-3465571b121fdcaba1b97f0a52b1aa16a25390a5.tar.gz
scummvm-rg350-3465571b121fdcaba1b97f0a52b1aa16a25390a5.tar.bz2
scummvm-rg350-3465571b121fdcaba1b97f0a52b1aa16a25390a5.zip
Added preliminary support for loading locations in BRA:
- changed parseLocation to invoke subclasses for version-specific keywords. - implemented loading of background resources (backgrounds should be visible) svn-id: r28568
-rw-r--r--engines/parallaction/commands.cpp7
-rw-r--r--engines/parallaction/disk_br.cpp56
-rw-r--r--engines/parallaction/location.cpp188
-rw-r--r--engines/parallaction/parallaction.h3
-rw-r--r--engines/parallaction/parallaction_br.cpp78
-rw-r--r--engines/parallaction/parallaction_ns.cpp43
-rw-r--r--engines/parallaction/parser.cpp2
7 files changed, 263 insertions, 114 deletions
diff --git a/engines/parallaction/commands.cpp b/engines/parallaction/commands.cpp
index dc392fde2c..915d76d7cc 100644
--- a/engines/parallaction/commands.cpp
+++ b/engines/parallaction/commands.cpp
@@ -183,7 +183,12 @@ void Parallaction::parseCommands(Script &script, CommandList& list) {
}
- list.push_front(cmd); // NOTE: command lists are written backwards in scripts
+ // FIXME: implement a proper parseCommands for BRA
+ if (getGameType() == GType_BRA)
+ delete cmd;
+ else
+ list.push_front(cmd); // NOTE: command lists are written backwards in scripts
+
fillBuffers(script, true);
}
diff --git a/engines/parallaction/disk_br.cpp b/engines/parallaction/disk_br.cpp
index 65332a2a4a..b79af9c655 100644
--- a/engines/parallaction/disk_br.cpp
+++ b/engines/parallaction/disk_br.cpp
@@ -25,6 +25,7 @@
#include "common/stdafx.h"
#include "parallaction/parallaction.h"
+#include "parallaction/util.h"
namespace Parallaction {
@@ -87,17 +88,17 @@ Cnv* DosDisk_br::loadTalk(const char *name) {
Script* DosDisk_br::loadLocation(const char *name) {
debugC(5, kDebugDisk, "DosDisk_br::loadLocation");
- Common::File stream;
+ Common::File *stream = new Common::File;
char path[PATH_LEN];
sprintf(path, "%s/%s/%s.slf", _partPath, _languageDir, name);
- if (!stream.open(path)) {
+ if (!stream->open(path)) {
sprintf(path, "%s/%s/%s.loc", _partPath, _languageDir, name);
- if (!stream.open(path))
+ if (!stream->open(path))
errorFileNotFound(path);
}
- return new Script(&stream, false);
+ return new Script(stream, true);
}
Script* DosDisk_br::loadScript(const char* name) {
@@ -205,6 +206,53 @@ void DosDisk_br::loadSlide(BackgroundInfo& info, const char *name) {
void DosDisk_br::loadScenery(BackgroundInfo& info, const char *name, const char *mask, const char* path) {
debugC(5, kDebugDisk, "DosDisk_br::loadScenery");
+
+ char filename[PATH_LEN];
+ Common::File stream;
+
+ if (name) {
+ sprintf(filename, "%s/bkg/%s.bkg", _partPath, name);
+ if (!stream.open(filename))
+ errorFileNotFound(filename);
+
+ stream.skip(4);
+ info.width = stream.readUint32BE();
+ info.height = stream.readUint32BE();
+ stream.skip(20);
+
+ byte rgb[768];
+ stream.read(rgb, 768);
+
+ for (uint i = 0; i < 256; i++) {
+ info.palette.setEntry(i, rgb[i] >> 2, rgb[i+256] >> 2, rgb[i+512] >> 2);
+ }
+
+ info.bg.create(info.width, info.height, 1);
+ stream.read(info.bg.pixels, info.width * info.height);
+ }
+
+ if (mask) {
+ sprintf(filename, "%s/msk/%s.msk", _partPath, mask);
+ if (!stream.open(filename))
+ errorFileNotFound(filename);
+
+ // NOTE: info.width and info.height are only valid if the background graphics
+ // have already been loaded
+ info.mask.create(info.width, info.height);
+ stream.read(info.mask.data, info.width * info.height);
+ }
+
+ if (path) {
+ sprintf(filename, "%s/pth/%s.pth", _partPath, path);
+ if (!stream.open(filename))
+ errorFileNotFound(filename);
+
+ // NOTE: info.width and info.height are only valid if the background graphics
+ // have already been loaded
+ info.path.create(info.width, info.height);
+ stream.read(info.path.data, info.width * info.height);
+ }
+
return;
}
diff --git a/engines/parallaction/location.cpp b/engines/parallaction/location.cpp
index 6798e72afa..001c5a8d03 100644
--- a/engines/parallaction/location.cpp
+++ b/engines/parallaction/location.cpp
@@ -42,116 +42,91 @@ void Parallaction::parseLocation(const char *filename) {
Script *_locationScript = _disk->loadLocation(filename);
_hasLocationSound = false;
+ // WORKAROUND: the original code erroneously incremented
+ // _currentLocationIndex, thus producing inconsistent
+ // savegames. This workaround modified the following loop
+ // and if-statement, so the code exactly matches the one
+ // in Big Red Adventure.
+ _currentLocationIndex = -1;
+ uint16 _di = 0;
+ while (_locationNames[_di][0] != '\0') {
+ if (!scumm_stricmp(_locationNames[_di], filename)) {
+ _currentLocationIndex = _di;
+ }
+ _di++;
+ }
+
+ if (_currentLocationIndex == -1) {
+ strcpy(_locationNames[_numLocations], filename);
+ _currentLocationIndex = _numLocations;
+
+ _numLocations++;
+ _locationNames[_numLocations][0] = '\0';
+ _localFlags[_numLocations] = 0;
+ } else {
+ _localFlags[_currentLocationIndex] |= kFlagsVisited; // 'visited'
+ }
+
+
fillBuffers(*_locationScript, true);
+
+ printf("ciao (%s)\n", filename);
+
while (scumm_stricmp(_tokens[0], "ENDLOCATION")) {
- if (!scumm_stricmp(_tokens[0], "LOCATION")) {
- // The parameter for location is 'location.mask'.
- // If mask is not present, then it is assumed
- // that path & mask are encoded in the background
- // bitmap, otherwise a separate .msk file exists.
-
- char *mask = strchr(_tokens[1], '.');
- if (mask) {
- mask[0] = '\0';
- mask++;
- }
-
- // WORKAROUND: the original code erroneously incremented
- // _currentLocationIndex, thus producing inconsistent
- // savegames. This workaround modified the following loop
- // and if-statement, so the code exactly matches the one
- // in Big Red Adventure.
- _currentLocationIndex = -1;
- uint16 _di = 0;
- while (_locationNames[_di][0] != '\0') {
- if (!scumm_stricmp(_locationNames[_di], filename)) {
- _currentLocationIndex = _di;
- }
- _di++;
- }
-
- if (_currentLocationIndex == -1) {
- strcpy(_locationNames[_numLocations], filename);
- _currentLocationIndex = _numLocations;
-
- _numLocations++;
- _locationNames[_numLocations][0] = '\0';
- _localFlags[_numLocations] = 0;
- } else {
- _localFlags[_currentLocationIndex] |= kFlagsVisited; // 'visited'
- }
-
- strcpy(_location._name, _tokens[1]);
- switchBackground(_location._name, mask);
-
- if (_tokens[2][0] != '\0') {
- _char._ani._left = atoi(_tokens[2]);
- _char._ani._top = atoi(_tokens[3]);
- }
-
- if (_tokens[4][0] != '\0') {
- _char._ani._frame = atoi(_tokens[4]);
- }
- }
- if (!scumm_stricmp(_tokens[0], "DISK")) {
- _disk->selectArchive(_tokens[1]);
- }
- if (!scumm_stricmp(_tokens[0], "LOCALFLAGS")) {
- _si = 1; // _localFlagNames[0] = 'visited'
- while (_tokens[_si][0] != '\0') {
- _localFlagNames->addData(_tokens[_si]);
- _si++;
- }
- }
- if (!scumm_stricmp(_tokens[0], "COMMANDS")) {
- parseCommands(*_locationScript, _location._commands);
- }
- if (!scumm_stricmp(_tokens[0], "ACOMMANDS")) {
- parseCommands(*_locationScript, _location._aCommands);
- }
- if (!scumm_stricmp(_tokens[0], "FLAGS")) {
- if ((_localFlags[_currentLocationIndex] & kFlagsVisited) == 0) {
- // only for 1st visit
- _localFlags[_currentLocationIndex] = 0;
- _si = 1;
+ printf("inst = %s\n", _tokens[0]);
- do {
- byte _al = _localFlagNames->lookup(_tokens[_si]);
- _localFlags[_currentLocationIndex] |= 1 << (_al - 1);
+ bool parsed = parseLocationLine(filename, _locationScript);
+ if (!parsed) {
+ if (!scumm_stricmp(_tokens[0], "LOCALFLAGS")) {
+ _si = 1; // _localFlagNames[0] = 'visited'
+ while (_tokens[_si][0] != '\0') {
+ _localFlagNames->addData(_tokens[_si]);
_si++;
- if (scumm_stricmp(_tokens[_si], "|")) break;
- _si++;
- } while (true);
- }
- }
- if (!scumm_stricmp(_tokens[0], "COMMENT")) {
- _location._comment = parseComment(*_locationScript);
- debugC(3, kDebugLocation, "Location comment: '%s'", _location._comment);
- }
- if (!scumm_stricmp(_tokens[0], "ENDCOMMENT")) {
- _location._endComment = parseComment(*_locationScript);
- }
- if (!scumm_stricmp(_tokens[0], "ZONE")) {
- parseZone(*_locationScript, _zones, _tokens[1]);
- }
- if (!scumm_stricmp(_tokens[0], "NODES")) {
- parseWalkNodes(*_locationScript, _location._walkNodes);
- }
- if (!scumm_stricmp(_tokens[0], "ANIMATION")) {
- parseAnimation(*_locationScript, _animations, _tokens[1]);
- }
- if (!scumm_stricmp(_tokens[0], "SOUND")) {
- if (getPlatform() == Common::kPlatformAmiga) {
- strcpy(_locationSound, _tokens[1]);
- _hasLocationSound = true;
- }
- }
- if (!scumm_stricmp(_tokens[0], "MUSIC")) {
- if (getPlatform() == Common::kPlatformAmiga)
- _soundMan->setMusicFile(_tokens[1]);
+ }
+ } else
+ if (!scumm_stricmp(_tokens[0], "COMMANDS")) {
+ parseCommands(*_locationScript, _location._commands);
+ } else
+ if (!scumm_stricmp(_tokens[0], "ACOMMANDS")) {
+ parseCommands(*_locationScript, _location._aCommands);
+ } else
+ if (!scumm_stricmp(_tokens[0], "FLAGS")) {
+ if ((_localFlags[_currentLocationIndex] & kFlagsVisited) == 0) {
+ // only for 1st visit
+ _localFlags[_currentLocationIndex] = 0;
+ _si = 1;
+
+ do {
+ byte _al = _localFlagNames->lookup(_tokens[_si]);
+ _localFlags[_currentLocationIndex] |= 1 << (_al - 1);
+
+ _si++;
+ if (scumm_stricmp(_tokens[_si], "|")) break;
+ _si++;
+ } while (true);
+ }
+ } else
+ if (!scumm_stricmp(_tokens[0], "COMMENT")) {
+ _location._comment = parseComment(*_locationScript);
+ } else
+ if (!scumm_stricmp(_tokens[0], "ENDCOMMENT")) {
+ _location._endComment = parseComment(*_locationScript);
+ } else
+ if (!scumm_stricmp(_tokens[0], "SOUND")) {
+ if (getPlatform() == Common::kPlatformAmiga) {
+ strcpy(_locationSound, _tokens[1]);
+ _hasLocationSound = true;
+ }
+ } else
+ if (!scumm_stricmp(_tokens[0], "MUSIC")) {
+ if (getPlatform() == Common::kPlatformAmiga)
+ _soundMan->setMusicFile(_tokens[1]);
+ } else
+ error("unknown keyword '%s' in location '%s'", _tokens[0], filename);
}
+
fillBuffers(*_locationScript, true);
}
@@ -245,11 +220,9 @@ void Parallaction::freeBackground() {
}
-void Parallaction::setBackground(const char *background, const char *mask, const char *path) {
-
- freeBackground();
+void Parallaction::setBackground(const char* name, const char* mask, const char* path) {
- _disk->loadScenery(*_backgroundInfo, background, mask, path);
+ _disk->loadScenery(*_backgroundInfo, name, mask, path);
_gfx->setPalette(_backgroundInfo->palette);
_gfx->_palette.clone(_backgroundInfo->palette);
@@ -264,7 +237,6 @@ void Parallaction::setBackground(const char *background, const char *mask, const
return;
}
-
void Parallaction::showLocationComment(const char *text, bool end) {
_gfx->setFont(_dialogueFont);
diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h
index 6c040c9774..8549cba24f 100644
--- a/engines/parallaction/parallaction.h
+++ b/engines/parallaction/parallaction.h
@@ -310,6 +310,7 @@ public:
void waitTime(uint32 t);
void parseLocation(const char *filename);
+ virtual bool parseLocationLine(const char *filename, Script *script) = 0;
void changeCursor(int32 index);
void showCursor(bool visible);
void changeCharacter(const char *name);
@@ -512,6 +513,7 @@ public:
virtual void callFunction(uint index, void* parm);
void renderLabel(Graphics::Surface *cnv, char *text);
void setMousePointer(int16 index);
+ virtual bool parseLocationLine(const char *filename, Script *script);
public:
@@ -579,6 +581,7 @@ public:
public:
typedef void (Parallaction_br::*Callable)(void*);
virtual void callFunction(uint index, void* parm);
+ virtual bool parseLocationLine(const char *filename, Script *script);
public:
Table *_countersNames;
diff --git a/engines/parallaction/parallaction_br.cpp b/engines/parallaction/parallaction_br.cpp
index f6dd1aee45..82dfd96f54 100644
--- a/engines/parallaction/parallaction_br.cpp
+++ b/engines/parallaction/parallaction_br.cpp
@@ -343,5 +343,83 @@ void Parallaction_br::startPart() {
}
+void skip(Script* script, const char* endToken) {
+
+ while (scumm_stricmp(_tokens[0], endToken)) {
+ fillBuffers(*script, true);
+ }
+
+}
+
+bool Parallaction_br::parseLocationLine(const char *filename, Script *script) {
+
+ bool parsed = true;
+ bool flip = false;
+ int nextToken = 0;
+
+ if (!scumm_stricmp(_tokens[0], "LOCATION")) {
+
+ strcpy(_location._name, _tokens[1]);
+ _disk->loadScenery(*_backgroundInfo, _location._name, NULL, NULL);
+ _gfx->setBackground(&_backgroundInfo->bg);
+ _gfx->_palette.clone(_backgroundInfo->palette);
+ _gfx->setPalette(_backgroundInfo->palette);
+
+ if (!scumm_stricmp("flip", _tokens[2])) {
+ flip = true;
+ nextToken = 3;
+ } else {
+ nextToken = 2;
+ }
+
+ if (_tokens[nextToken][0] != '\0') {
+ _char._ani._left = atoi(_tokens[nextToken]);
+ nextToken++;
+ _char._ani._top = atoi(_tokens[nextToken]);
+ nextToken++;
+ }
+
+ if (_tokens[nextToken][0] != '\0') {
+ _char._ani._frame = atoi(_tokens[nextToken]);
+ }
+ } else
+ if (!scumm_stricmp(_tokens[0], "IFCHAR")) {
+ skip(script, "ENDIF");
+ } else
+ if (!scumm_stricmp(_tokens[0], "CHARACTER")) {
+
+ } else
+ if (!scumm_stricmp(_tokens[0], "MASK")) {
+ _disk->loadScenery(*_backgroundInfo, NULL, _tokens[1], NULL);
+ _gfx->setMask(&_backgroundInfo->mask);
+
+ _gfx->_bgLayers[0] = atoi(_tokens[2]);
+ _gfx->_bgLayers[1] = atoi(_tokens[3]);
+ _gfx->_bgLayers[2] = atoi(_tokens[4]);
+ } else
+ if (!scumm_stricmp(_tokens[0], "PATH")) {
+ _disk->loadScenery(*_backgroundInfo, NULL, NULL, _tokens[1]);
+ _pathBuffer = &_backgroundInfo->path;
+ } else
+ if (!scumm_stricmp(_tokens[0], "DISK")) {
+ //
+ } else
+ if (!scumm_stricmp(_tokens[0], "ESCAPE")) {
+ skip(script, "endcommands");
+ } else
+ if (!scumm_stricmp(_tokens[0], "ZETA")) {
+ //
+ } else
+ if (!scumm_stricmp(_tokens[0], "ZONE")) {
+ skip(script, "endzone");
+ } else
+ if (!scumm_stricmp(_tokens[0], "ANIMATION")) {
+ skip(script, "endanimation");
+ } else
+ parsed = false;
+
+ return parsed;
+}
+
} // namespace Parallaction
diff --git a/engines/parallaction/parallaction_ns.cpp b/engines/parallaction/parallaction_ns.cpp
index 6dcae1bdc8..38e2d999ff 100644
--- a/engines/parallaction/parallaction_ns.cpp
+++ b/engines/parallaction/parallaction_ns.cpp
@@ -199,6 +199,49 @@ int Parallaction_ns::go() {
return 0;
}
+bool Parallaction_ns::parseLocationLine(const char *filename, Script *script) {
+ bool parsed = true;
+
+ if (!scumm_stricmp(_tokens[0], "LOCATION")) {
+ // The parameter for location is 'location.mask'.
+ // If mask is not present, then it is assumed
+ // that path & mask are encoded in the background
+ // bitmap, otherwise a separate .msk file exists.
+
+ char *mask = strchr(_tokens[1], '.');
+ if (mask) {
+ mask[0] = '\0';
+ mask++;
+ }
+
+ strcpy(_location._name, _tokens[1]);
+ switchBackground(_location._name, mask);
+
+ if (_tokens[2][0] != '\0') {
+ _char._ani._left = atoi(_tokens[2]);
+ _char._ani._top = atoi(_tokens[3]);
+ }
+
+ if (_tokens[4][0] != '\0') {
+ _char._ani._frame = atoi(_tokens[4]);
+ }
+ } else
+ if (!scumm_stricmp(_tokens[0], "DISK")) {
+ _disk->selectArchive(_tokens[1]);
+ } else
+ if (!scumm_stricmp(_tokens[0], "NODES")) {
+ parseWalkNodes(*script, _location._walkNodes);
+ } else
+ if (!scumm_stricmp(_tokens[0], "ZONE")) {
+ parseZone(*script, _zones, _tokens[1]);
+ } else
+ if (!scumm_stricmp(_tokens[0], "ANIMATION")) {
+ parseAnimation(*script, _animations, _tokens[1]);
+ } else
+ parsed = false;
+
+ return parsed;
+}
} // namespace Parallaction
diff --git a/engines/parallaction/parser.cpp b/engines/parallaction/parser.cpp
index 44aae6c1cc..d786cc6487 100644
--- a/engines/parallaction/parser.cpp
+++ b/engines/parallaction/parser.cpp
@@ -48,7 +48,7 @@ char *Script::readLine(char *buf, size_t bufSize) {
v2 = _input->readSByte();
- if (v2 == 0xA || _input->eos()) break;
+ if (v2 == 0xA || v2 == 0xD || _input->eos()) break;
if (!_input->eos() && _si < bufSize) buf[_si] = v2;
}