aboutsummaryrefslogtreecommitdiff
path: root/engines/sword2/anims.cpp
diff options
context:
space:
mode:
authorMax Horn2006-02-11 22:45:04 +0000
committerMax Horn2006-02-11 22:45:04 +0000
commit26ee630756ebdd7c96bccede0881a8c8b98e8f2b (patch)
tree26e378d5cf990a2b81c2c96e9e683a7f333b62e8 /engines/sword2/anims.cpp
parent2a9a0d4211b1ea5723f1409d91cb95de8984429e (diff)
downloadscummvm-rg350-26ee630756ebdd7c96bccede0881a8c8b98e8f2b.tar.gz
scummvm-rg350-26ee630756ebdd7c96bccede0881a8c8b98e8f2b.tar.bz2
scummvm-rg350-26ee630756ebdd7c96bccede0881a8c8b98e8f2b.zip
Moved engines to the new engines/ directory
svn-id: r20582
Diffstat (limited to 'engines/sword2/anims.cpp')
-rw-r--r--engines/sword2/anims.cpp308
1 files changed, 308 insertions, 0 deletions
diff --git a/engines/sword2/anims.cpp b/engines/sword2/anims.cpp
new file mode 100644
index 0000000000..e64903a61f
--- /dev/null
+++ b/engines/sword2/anims.cpp
@@ -0,0 +1,308 @@
+/* Copyright (C) 1994-1998 Revolution Software Ltd.
+ * Copyright (C) 2003-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ */
+
+// ---------------------------------------------------------------------------
+// A more intelligent version of the old ANIMS.C
+// All this stuff by James
+// DON'T TOUCH!
+// ---------------------------------------------------------------------------
+
+#include "common/stdafx.h"
+#include "common/file.h"
+
+#include "sword2/sword2.h"
+#include "sword2/defs.h"
+#include "sword2/build_display.h"
+#include "sword2/interpreter.h"
+#include "sword2/logic.h"
+#include "sword2/maketext.h"
+#include "sword2/resman.h"
+#include "sword2/router.h"
+#include "sword2/sound.h"
+#include "sword2/animation.h"
+
+namespace Sword2 {
+
+int Router::doAnimate(byte *ob_logic, byte *ob_graph, int32 animRes, bool reverse) {
+ AnimHeader anim_head;
+ byte *anim_file;
+
+ ObjectLogic obLogic(ob_logic);
+ ObjectGraphic obGraph(ob_graph);
+
+ if (obLogic.getLooping() == 0) {
+ byte *ptr;
+
+ // This is the start of the anim - set up the first frame
+
+ // For testing all anims!
+ // A script loop can send every resource number to the anim
+ // function & it will only run the valid ones. See
+ // 'testing_routines' object in George's Player Character
+ // section of linc
+
+ if (_vm->_logic->readVar(SYSTEM_TESTING_ANIMS)) {
+ if (!_vm->_resman->checkValid(animRes)) {
+ // Not a valid resource number. Switch off
+ // the sprite. Don't animate - just continue
+ // script next cycle.
+ setSpriteStatus(ob_graph, NO_SPRITE);
+ return IR_STOP;
+ }
+
+ ptr = _vm->_resman->openResource(animRes);
+
+ // if it's not an animation file
+ if (_vm->_resman->fetchType(animRes) != ANIMATION_FILE) {
+ _vm->_resman->closeResource(animRes);
+
+ // switch off the sprite
+ // don't animate - just continue
+ // script next cycle
+ setSpriteStatus(ob_graph, NO_SPRITE);
+ return IR_STOP;
+ }
+
+ _vm->_resman->closeResource(animRes);
+
+ // switch on the sprite
+ setSpriteStatus(ob_graph, SORT_SPRITE);
+ }
+
+ assert(animRes);
+
+ // open anim file
+ anim_file = _vm->_resman->openResource(animRes);
+
+ assert(_vm->_resman->fetchType(animRes) == ANIMATION_FILE);
+
+ // point to anim header
+ anim_head.read(_vm->fetchAnimHeader(anim_file));
+
+ // now running an anim, looping back to this call again
+ obLogic.setLooping(1);
+ obGraph.setAnimResource(animRes);
+
+ if (reverse)
+ obGraph.setAnimPc(anim_head.noAnimFrames - 1);
+ else
+ obGraph.setAnimPc(0);
+ } else if (_vm->_logic->getSync() != -1) {
+ // We've received a sync - return to script immediately
+ debug(5, "**sync stopped %d**", _vm->_logic->readVar(ID));
+
+ // If sync received, anim finishes right now (remaining on
+ // last frame). Quit animation, but continue script.
+ obLogic.setLooping(0);
+ return IR_CONT;
+ } else {
+ // Not first frame, and no sync received - set up the next
+ // frame of the anim.
+
+ // open anim file and point to anim header
+ anim_file = _vm->_resman->openResource(obGraph.getAnimResource());
+ anim_head.read(_vm->fetchAnimHeader(anim_file));
+
+ if (reverse)
+ obGraph.setAnimPc(obGraph.getAnimPc() - 1);
+ else
+ obGraph.setAnimPc(obGraph.getAnimPc() + 1);
+ }
+
+ // check for end of anim
+
+ if (reverse) {
+ if (obGraph.getAnimPc() == 0)
+ obLogic.setLooping(0);
+ } else {
+ if (obGraph.getAnimPc() == anim_head.noAnimFrames - 1)
+ obLogic.setLooping(0);
+ }
+
+ // close the anim file
+ _vm->_resman->closeResource(obGraph.getAnimResource());
+
+ // check if we want the script to loop back & call this function again
+ return obLogic.getLooping() ? IR_REPEAT : IR_STOP;
+}
+
+int Router::megaTableAnimate(byte *ob_logic, byte *ob_graph, byte *ob_mega, byte *animTable, bool reverse) {
+ int32 animRes = 0;
+
+ // If this is the start of the anim, read the anim table to get the
+ // appropriate anim resource
+
+ ObjectLogic obLogic(ob_logic);
+
+ if (obLogic.getLooping() == 0) {
+ ObjectMega obMega(ob_mega);
+
+ // Appropriate anim resource is in 'table[direction]'
+ animRes = READ_LE_UINT32(animTable + 4 * obMega.getCurDir());
+ }
+
+ return doAnimate(ob_logic, ob_graph, animRes, reverse);
+}
+
+void Router::setSpriteStatus(byte *ob_graph, uint32 type) {
+ ObjectGraphic obGraph(ob_graph);
+
+ // Remove the previous status, but don't affect the shading upper-word
+ obGraph.setType((obGraph.getType() & 0xffff0000) | type);
+}
+
+void Router::setSpriteShading(byte *ob_graph, uint32 type) {
+ ObjectGraphic obGraph(ob_graph);
+
+ // Remove the previous shading, but don't affect the status lower-word.
+ // Note that mega frames may still be shaded automatically, even when
+ // not sent 'RDSPR_SHADOW'.
+ obGraph.setType((obGraph.getType() & 0x0000ffff) | type);
+}
+
+void Logic::createSequenceSpeech(MovieTextObject *sequenceText[]) {
+ uint32 line;
+ uint32 local_text;
+ uint32 text_res;
+ byte *text;
+ uint32 wavId; // ie. offical text number (actor text number)
+ bool speechRunning;
+
+ // for each sequence text line that's been logged
+ for (line = 0; line < _sequenceTextLines; line++) {
+ // allocate this structure
+ sequenceText[line] = new MovieTextObject;
+
+ sequenceText[line]->startFrame = _sequenceTextList[line].startFrame;
+ sequenceText[line]->endFrame = _sequenceTextList[line].endFrame;
+
+ // pull out the text line to get the official text number
+ // (for wav id)
+
+ text_res = _sequenceTextList[line].textNumber / SIZE;
+ local_text = _sequenceTextList[line].textNumber & 0xffff;
+
+ // open text resource & get the line
+ text = _vm->fetchTextLine(_vm->_resman->openResource(text_res), local_text);
+ wavId = (int32)READ_LE_UINT16(text);
+
+ // now ok to close the text file
+ _vm->_resman->closeResource(text_res);
+
+ // 1st word of text line is the official line number
+ debug(5,"(%d) SEQUENCE TEXT: %s", READ_LE_UINT16(text), text + 2);
+
+ // is it to be speech or subtitles or both?
+ // assume speech is not running until know otherwise
+
+ speechRunning = false;
+ _sequenceTextList[line].speech_mem = NULL;
+ sequenceText[line]->speech = NULL;
+
+ if (!_vm->_sound->isSpeechMute()) {
+ _sequenceTextList[line].speechBufferSize = _vm->_sound->preFetchCompSpeech(wavId, &_sequenceTextList[line].speech_mem);
+ if (_sequenceTextList[line].speechBufferSize) {
+ // ok, we've got speech!
+ speechRunning = true;
+ }
+ }
+
+ // if we want subtitles, or speech failed to load
+
+ if (_vm->getSubtitles() || !speechRunning) {
+ // open text resource & get the line
+ text = _vm->fetchTextLine(_vm->_resman->openResource(text_res), local_text);
+ // make the sprite
+ // 'text+2' to skip the first 2 bytes which form the
+ // line reference number
+
+ // NB. The mem block containing the text sprite is
+ // currently FLOATING!
+
+ // When rendering text over a sequence we need a
+ // different colour for the border.
+
+ _sequenceTextList[line].text_mem = _vm->_fontRenderer->makeTextSprite(text + 2, 600, 255, _vm->_speechFontId, 1);
+
+ // ok to close the text resource now
+ _vm->_resman->closeResource(text_res);
+ } else {
+ _sequenceTextList[line].text_mem = NULL;
+ sequenceText[line]->textSprite = NULL;
+ }
+ }
+
+ // for drivers: NULL-terminate the array of pointers to
+ // MovieTextObject's
+ sequenceText[_sequenceTextLines] = NULL;
+
+ for (line = 0; line < _sequenceTextLines; line++) {
+ // if we've made a text sprite for this line...
+
+ if (_sequenceTextList[line].text_mem) {
+ // now fill out the SpriteInfo structure in the
+ // MovieTextObjectStructure
+ FrameHeader frame;
+
+ frame.read(_sequenceTextList[line].text_mem);
+
+ sequenceText[line]->textSprite = new SpriteInfo;
+
+ // center text at bottom of screen
+ sequenceText[line]->textSprite->x = 320 - frame.width / 2;
+ sequenceText[line]->textSprite->y = 440 - frame.height;
+ sequenceText[line]->textSprite->w = frame.width;
+ sequenceText[line]->textSprite->h = frame.height;
+ sequenceText[line]->textSprite->type = RDSPR_DISPLAYALIGN | RDSPR_NOCOMPRESSION;
+ sequenceText[line]->textSprite->data = _sequenceTextList[line].text_mem + FrameHeader::size();
+ }
+
+ // if we've loaded a speech sample for this line...
+
+ if (_sequenceTextList[line].speech_mem) {
+ // for drivers: set up pointer to decompressed wav in
+ // memory
+
+ sequenceText[line]->speechBufferSize = _sequenceTextList[line].speechBufferSize;
+ sequenceText[line]->speech = _sequenceTextList[line].speech_mem;
+ }
+ }
+}
+
+void Logic::clearSequenceSpeech(MovieTextObject *sequenceText[]) {
+ for (uint i = 0; i < _sequenceTextLines; i++) {
+ // free up the memory used by this MovieTextObject
+ delete sequenceText[i];
+
+ // free up the mem block containing this text sprite
+ if (_sequenceTextList[i].text_mem)
+ free(_sequenceTextList[i].text_mem);
+
+ // free up the mem block containing this speech sample
+ if (_sequenceTextList[i].speech_mem)
+ free(_sequenceTextList[i].speech_mem);
+ }
+
+ // IMPORTANT! Reset the line count ready for the next sequence!
+ _sequenceTextLines = 0;
+}
+
+} // End of namespace Sword2