mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-15 06:08:35 +00:00
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
This commit is contained in:
parent
d7b6f0ecc8
commit
3465571b12
@ -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);
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
printf("inst = %s\n", _tokens[0]);
|
||||
|
||||
char *mask = strchr(_tokens[1], '.');
|
||||
if (mask) {
|
||||
mask[0] = '\0';
|
||||
mask++;
|
||||
}
|
||||
bool parsed = parseLocationLine(filename, _locationScript);
|
||||
if (!parsed) {
|
||||
|
||||
// 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;
|
||||
if (!scumm_stricmp(_tokens[0], "LOCALFLAGS")) {
|
||||
_si = 1; // _localFlagNames[0] = 'visited'
|
||||
while (_tokens[_si][0] != '\0') {
|
||||
_localFlagNames->addData(_tokens[_si]);
|
||||
_si++;
|
||||
}
|
||||
_di++;
|
||||
}
|
||||
} 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;
|
||||
|
||||
if (_currentLocationIndex == -1) {
|
||||
strcpy(_locationNames[_numLocations], filename);
|
||||
_currentLocationIndex = _numLocations;
|
||||
do {
|
||||
byte _al = _localFlagNames->lookup(_tokens[_si]);
|
||||
_localFlags[_currentLocationIndex] |= 1 << (_al - 1);
|
||||
|
||||
_numLocations++;
|
||||
_locationNames[_numLocations][0] = '\0';
|
||||
_localFlags[_numLocations] = 0;
|
||||
} else {
|
||||
_localFlags[_currentLocationIndex] |= kFlagsVisited; // 'visited'
|
||||
}
|
||||
_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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
do {
|
||||
byte _al = _localFlagNames->lookup(_tokens[_si]);
|
||||
_localFlags[_currentLocationIndex] |= 1 << (_al - 1);
|
||||
|
||||
_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]);
|
||||
}
|
||||
fillBuffers(*_locationScript, true);
|
||||
}
|
||||
|
||||
@ -245,11 +220,9 @@ void Parallaction::freeBackground() {
|
||||
|
||||
}
|
||||
|
||||
void Parallaction::setBackground(const char *background, const char *mask, const char *path) {
|
||||
void Parallaction::setBackground(const char* name, const char* mask, const char* path) {
|
||||
|
||||
freeBackground();
|
||||
|
||||
_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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user