aboutsummaryrefslogtreecommitdiff
path: root/engines/parallaction/parallaction_ns.cpp
diff options
context:
space:
mode:
authorNicola Mettifogo2007-08-25 20:34:10 +0000
committerNicola Mettifogo2007-08-25 20:34:10 +0000
commit39e4a9b180d37f2fef108391d5f04a3c7e3b2ea0 (patch)
treebd7bd96adb2d8df6677d1e25b9e4b98e2851bbad /engines/parallaction/parallaction_ns.cpp
parent9f8b0884fa2814b04567a86596cdae7953d8eb1e (diff)
downloadscummvm-rg350-39e4a9b180d37f2fef108391d5f04a3c7e3b2ea0.tar.gz
scummvm-rg350-39e4a9b180d37f2fef108391d5f04a3c7e3b2ea0.tar.bz2
scummvm-rg350-39e4a9b180d37f2fef108391d5f04a3c7e3b2ea0.zip
Added an abstract base class for representing multiple-frames for animations. Changed user code to rely on the new interface. Cnv has been turned into an implementation of the new interface, and it is now known as a concrete class only to Disk and Font code for Nippon Safes.
svn-id: r28734
Diffstat (limited to 'engines/parallaction/parallaction_ns.cpp')
-rw-r--r--engines/parallaction/parallaction_ns.cpp177
1 files changed, 176 insertions, 1 deletions
diff --git a/engines/parallaction/parallaction_ns.cpp b/engines/parallaction/parallaction_ns.cpp
index 2a82002f24..db0cdf84e7 100644
--- a/engines/parallaction/parallaction_ns.cpp
+++ b/engines/parallaction/parallaction_ns.cpp
@@ -151,7 +151,7 @@ void Parallaction_ns::setMousePointer(int16 index) {
byte *v8 = (byte*)_mouseComposedArrow->pixels;
// FIXME: destination offseting is not clear
- byte* s = _char._objs->getFramePtr(getInventoryItemIndex(index));
+ byte* s = _char._objs->getData(getInventoryItemIndex(index));
byte* d = v8 + 7 + MOUSECOMBO_WIDTH * 7;
for (uint i = 0; i < INVENTORYITEM_HEIGHT; i++) {
@@ -208,5 +208,180 @@ int Parallaction_ns::go() {
}
+/*
+ changeLocation handles transitions between locations, and is able to display slides
+ between one and the other. The input parameter 'location' exists in some flavours:
+
+ 1 - [S].slide.[L]{.[C]}
+ 2 - [L]{.[C]}
+
+ where:
+
+ [S] is the slide to be shown
+ [L] is the location to switch to (immediately in case 2, or right after slide [S] in case 1)
+ [C] is the character to be selected, and is optional
+
+ The routine tells one form from the other by searching for the '.slide.'
+
+ NOTE: there exists one script in which [L] is not used in the case 1, but its use
+ is commented out, and would definitely crash the current implementation.
+*/
+void Parallaction_ns::changeLocation(char *location) {
+ debugC(1, kDebugLocation, "changeLocation(%s)", location);
+
+ _soundMan->playLocationMusic(location);
+
+ // WORKAROUND: this if-statement has been added to avoid crashes caused by
+ // execution of label jobs after a location switch. The other workaround in
+ // Parallaction::runGame should have been rendered useless by this one.
+ if (_jDrawLabel != NULL) {
+ removeJob(_jDrawLabel);
+ removeJob(_jEraseLabel);
+ _jDrawLabel = NULL;
+ _jEraseLabel = NULL;
+ }
+
+
+ _hoverZone = NULL;
+ if (_engineFlags & kEngineBlockInput) {
+ changeCursor( kCursorArrow );
+ }
+
+ _animations.remove(&_char._ani);
+
+ freeLocation();
+ char buf[100];
+ strcpy(buf, location);
+
+ Common::StringList list;
+ char *tok = strtok(location, ".");
+ while (tok) {
+ list.push_back(tok);
+ tok = strtok(NULL, ".");
+ }
+
+ if (list.size() < 1 || list.size() > 4)
+ error("changeLocation: ill-formed location string '%s'", location);
+
+ if (list.size() > 1) {
+ if (list[1] == "slide") {
+ showSlide(list[0].c_str());
+ _gfx->setFont(_menuFont);
+ _gfx->displayCenteredString(14, _slideText[0]); // displays text on screen
+ _gfx->updateScreen();
+ waitUntilLeftClick();
+
+ list.remove_at(0); // removes slide name
+ list.remove_at(0); // removes 'slide'
+ }
+
+ // list is now only [L].{[C]} (see above comment)
+ if (list.size() == 2) {
+ changeCharacter(list[1].c_str());
+ strcpy(_characterName, list[1].c_str());
+ }
+ }
+
+ _animations.push_front(&_char._ani);
+
+ strcpy(_saveData1, list[0].c_str());
+ parseLocation(list[0].c_str());
+
+ _char._ani._oldPos.x = -1000;
+ _char._ani._oldPos.y = -1000;
+
+ _char._ani.field_50 = 0;
+ if (_location._startPosition.x != -1000) {
+ _char._ani._left = _location._startPosition.x;
+ _char._ani._top = _location._startPosition.y;
+ _char._ani._frame = _location._startFrame;
+ _location._startPosition.y = -1000;
+ _location._startPosition.x = -1000;
+ }
+
+
+ _gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
+ _gfx->copyScreen(Gfx::kBitBack, Gfx::kBit2);
+ _gfx->setBlackPalette();
+ _gfx->updateScreen();
+
+ if (_location._commands.size() > 0) {
+ runCommands(_location._commands);
+ runJobs();
+ _gfx->swapBuffers();
+ runJobs();
+ _gfx->swapBuffers();
+ }
+
+ if (_location._comment) {
+ doLocationEnterTransition();
+ }
+
+ runJobs();
+ _gfx->swapBuffers();
+
+ _gfx->setPalette(_gfx->_palette);
+ if (_location._aCommands.size() > 0) {
+ runCommands(_location._aCommands);
+ }
+
+ if (_hasLocationSound)
+ _soundMan->playSfx(_locationSound, 0, true);
+
+ debugC(1, kDebugLocation, "changeLocation() done");
+
+ return;
+
+}
+
+void Parallaction_ns::changeCharacter(const char *name) {
+ debugC(1, kDebugLocation, "changeCharacter(%s)", name);
+
+ char baseName[20];
+ if (IS_MINI_CHARACTER(name)) {
+ strcpy(baseName, name+4);
+ } else {
+ strcpy(baseName, name);
+ }
+
+ char fullName[20];
+ strcpy(fullName, name);
+ if (_engineFlags & kEngineTransformedDonna)
+ strcat(fullName, "tras");
+
+ if (scumm_stricmp(fullName, _characterName1)) {
+
+ // freeCharacter takes responsibility for checking
+ // character for sanity before memory is freed
+ freeCharacter();
+
+ Common::String oldArchive = _disk->selectArchive((getFeatures() & GF_LANG_MULT) ? "disk1" : "disk0");
+ _char._ani._cnv = _disk->loadFrames(fullName);
+
+ if (!IS_DUMMY_CHARACTER(name)) {
+ if (getPlatform() == Common::kPlatformAmiga && (getFeatures() & GF_LANG_MULT))
+ _disk->selectArchive("disk0");
+
+ _char._head = _disk->loadHead(baseName);
+ _char._talk = _disk->loadTalk(baseName);
+ _char._objs = _disk->loadObjects(baseName);
+ _objectsNames = _disk->loadTable(baseName);
+
+ _soundMan->playCharacterMusic(name);
+
+ if (!(getFeatures() & GF_DEMO))
+ parseLocation("common");
+ }
+
+ if (!oldArchive.empty())
+ _disk->selectArchive(oldArchive);
+ }
+
+ strcpy(_characterName1, fullName);
+
+ debugC(1, kDebugLocation, "changeCharacter() done");
+
+ return;
+}
} // namespace Parallaction