diff options
author | Max Horn | 2006-02-11 22:45:04 +0000 |
---|---|---|
committer | Max Horn | 2006-02-11 22:45:04 +0000 |
commit | 26ee630756ebdd7c96bccede0881a8c8b98e8f2b (patch) | |
tree | 26e378d5cf990a2b81c2c96e9e683a7f333b62e8 /saga | |
parent | 2a9a0d4211b1ea5723f1409d91cb95de8984429e (diff) | |
download | scummvm-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 'saga')
56 files changed, 0 insertions, 29180 deletions
diff --git a/saga/actor.cpp b/saga/actor.cpp deleted file mode 100644 index cc89f0ef2a..0000000000 --- a/saga/actor.cpp +++ /dev/null @@ -1,3092 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -#include "saga/saga.h" - -#include "saga/actor.h" -#include "saga/animation.h" -#include "saga/console.h" -#include "saga/events.h" -#include "saga/gfx.h" -#include "saga/interface.h" -#include "saga/isomap.h" -#include "saga/itedata.h" -#include "saga/objectmap.h" -#include "saga/resnames.h" -#include "saga/rscfile.h" -#include "saga/script.h" -#include "saga/sndres.h" -#include "saga/sprite.h" -#include "saga/stream.h" -#include "saga/font.h" -#include "saga/sound.h" -#include "saga/scene.h" - -#include "common/config-manager.h" - -namespace Saga { - -enum ActorFrameIds { -//ITE - kFrameITEStand = 0, - kFrameITEWalk = 1, - kFrameITESpeak = 2, - kFrameITEGive = 3, - kFrameITEGesture = 4, - kFrameITEWait = 5, - kFrameITEPickUp = 6, - kFrameITELook = 7, -//IHNM - kFrameIHNMStand = 0, - kFrameIHNMSpeak = 1, - kFrameIHNMWait = 2, - kFrameIHNMGesture = 3, - kFrameIHNMWalk = 4 -}; - -static int commonObjectCompare(const CommonObjectDataPointer& obj1, const CommonObjectDataPointer& obj2) { - int p1 = obj1->_location.y - obj1->_location.z; - int p2 = obj2->_location.y - obj2->_location.z; - if (p1 == p2) - return 0; - if (p1 < p2) - return -1; - return 1; -} - -static int tileCommonObjectCompare(const CommonObjectDataPointer& obj1, const CommonObjectDataPointer& obj2) { - int p1 = -obj1->_location.u() - obj1->_location.v() - obj1->_location.z; - int p2 = -obj2->_location.u() - obj2->_location.v() - obj2->_location.z; - //TODO: for kObjNotFlat obj Height*3 of sprite should be added to p1 and p2 - //if (validObjId(obj1->id)) { - - if (p1 == p2) - return 0; - if (p1 < p2) - return -1; - return 1; -} - -// Lookup table to convert 8 cardinal directions to 4 -static const int actorDirectectionsLUT[8] = { - ACTOR_DIRECTION_BACK, // kDirUp - ACTOR_DIRECTION_RIGHT, // kDirUpRight - ACTOR_DIRECTION_RIGHT, // kDirRight - ACTOR_DIRECTION_RIGHT, // kDirDownRight - ACTOR_DIRECTION_FORWARD,// kDirDown - ACTOR_DIRECTION_LEFT, // kDirDownLeft - ACTOR_DIRECTION_LEFT, // kDirLeft - ACTOR_DIRECTION_LEFT, // kDirUpLeft -}; - -static const PathDirectionData pathDirectionLUT[8][3] = { - { { 0, 0, -1 }, { 7, -1, -1 }, { 4, 1, -1 } }, - { { 1, 1, 0 }, { 4, 1, -1 }, { 5, 1, 1 } }, - { { 2, 0, 1 }, { 5, 1, 1 }, { 6, -1, 1 } }, - { { 3, -1, 0 }, { 6, -1, 1 }, { 7, -1, -1 } }, - { { 0, 0, -1 }, { 1, 1, 0 }, { 4, 1, -1 } }, - { { 1, 1, 0 }, { 2, 0, 1 }, { 5, 1, 1 } }, - { { 2, 0, 1 }, { 3, -1, 0 }, { 6, -1, 1 } }, - { { 3, -1, 0 }, { 0, 0, -1 }, { 7, -1, -1 } } -}; - -static const int pathDirectionLUT2[8][2] = { - { 0, -1 }, - { 1, 0 }, - { 0, 1 }, - { -1, 0 }, - { 1, -1 }, - { 1, 1 }, - { -1, 1 }, - { -1, -1 } -}; - -static const int angleLUT[16][2] = { - { 0, -256 }, - { 98, -237 }, - { 181, -181 }, - { 237, -98 }, - { 256, 0 }, - { 237, 98 }, - { 181, 181 }, - { 98, 237 }, - { 0, 256 }, - { -98, 237 }, - { -181, 181 }, - { -237, 98 }, - { -256, 0 }, - { -237, -98 }, - { -181, -181 }, - { -98, -237 } -}; - -static const int directionLUT[8][2] = { - { 0 * 2, -2 * 2 }, - { 2 * 2, -1 * 2 }, - { 3 * 2, 0 * 2 }, - { 2 * 2, 1 * 2 }, - { 0 * 2, 2 * 2 }, - { -2 * 2, 1 * 2 }, - { -4 * 2, 0 * 2 }, - { -2 * 2, -1 * 2 } -}; - -static const int tileDirectionLUT[8][2] = { - { 1, 1 }, - { 2, 0 }, - { 1, -1 }, - { 0, -2 }, - { -1, -1 }, - { -2, 0 }, - { -1, 1 }, - { 0, 2 } -}; - -struct DragonMove { - uint16 baseFrame; - int16 offset[4][2]; -}; - -static const DragonMove dragonMoveTable[12] = { - { 0, { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } }, - { 0, { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } }, - { 0, { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } }, - { 0, { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } }, - { 28, { { -0, 0 }, { -1, 6 }, { -5, 11 }, { -10, 15 } } }, - { 56, { { 0, 0 }, { 1, 6 }, { 5, 11 }, { 10, 15 } } }, - { 40, { { 0, 0 }, { 6, 1 }, { 11, 5 }, { 15, 10 } } }, - { 44, { { 0, 0 }, { 6, -1 }, { 11, -5 }, { 15, -10 } } }, - { 32, { { -0, -0 }, { -6, -1 }, { -11, -5 }, { -15, -10 } } }, - { 52, { { -0, 0 }, { -6, 1 }, { -11, 5 }, { -15, 10 } } }, - { 36, { { 0, -0 }, { 1, -6 }, { 5, -11 }, { 10, -15 } } }, - { 48, { { -0, -0 }, { -1, -6 }, { -5, -11 }, { -10, -15 } } } -}; - -Actor::Actor(SagaEngine *vm) : _vm(vm) { - int i; - byte *stringsPointer; - size_t stringsLength; - ActorData *actor; - ObjectData *obj; - debug(9, "Actor::Actor()"); - _handleActionDiv = 15; - - _actors = NULL; - _actorsCount = 0; - - _objs = NULL; - _objsCount = 0; - -#ifdef ACTOR_DEBUG - _debugPoints = NULL; - _debugPointsAlloced = _debugPointsCount = 0; -#endif - - _protagStates = 0; - _protagStatesCount = 0; - - _pathNodeList = _newPathNodeList = NULL; - _pathList = NULL; - _pathDirectionList = NULL; - _pathListAlloced = _pathNodeListAlloced = _newPathNodeListAlloced = 0; - _pathListIndex = _pathNodeListIndex = _newPathNodeListIndex = -1; - _pathDirectionListCount = 0; - _pathDirectionListAlloced = 0; - - _centerActor = _protagonist = NULL; - _protagState = 0; - _lastTickMsec = 0; - - _yCellCount = _vm->_scene->getHeight(); - _xCellCount = _vm->getDisplayWidth(); - - _pathCell = (int8 *)malloc(_yCellCount * _xCellCount * sizeof(*_pathCell)); - - _pathRect.left = 0; - _pathRect.right = _vm->getDisplayWidth(); - _pathRect.top = _vm->getDisplayInfo().pathStartY; - _pathRect.bottom = _vm->_scene->getHeight(); - - // Get actor resource file context - _actorContext = _vm->_resource->getContext(GAME_RESOURCEFILE); - if (_actorContext == NULL) { - error("Actor::Actor() resource context not found"); - } - - // Load ITE actor strings. (IHNM actor strings are loaded by - // loadGlobalResources() instead.) - - if (_vm->getGameType() == GType_ITE) { - - _vm->_resource->loadResource(_actorContext, _vm->getResourceDescription()->actorsStringsResourceId, stringsPointer, stringsLength); - - _vm->loadStrings(_actorsStrings, stringsPointer, stringsLength); - free(stringsPointer); - } - - if (_vm->getGameType() == GType_ITE) { - _actorsCount = ITE_ACTORCOUNT; - _actors = (ActorData **)malloc(_actorsCount * sizeof(*_actors)); - for (i = 0; i < _actorsCount; i++) { - actor = _actors[i] = new ActorData(); - actor->_id = actorIndexToId(i); - actor->_index = i; - debug(9, "init actor id=%d index=%d", actor->_id, actor->_index); - actor->_nameIndex = ITE_ActorTable[i].nameIndex; - actor->_scriptEntrypointNumber = ITE_ActorTable[i].scriptEntrypointNumber; - actor->_spriteListResourceId = ITE_ActorTable[i].spriteListResourceId; - actor->_frameListResourceId = ITE_ActorTable[i].frameListResourceId; - actor->_speechColor = ITE_ActorTable[i].speechColor; - actor->_sceneNumber = ITE_ActorTable[i].sceneIndex; - actor->_flags = ITE_ActorTable[i].flags; - actor->_currentAction = ITE_ActorTable[i].currentAction; - actor->_facingDirection = ITE_ActorTable[i].facingDirection; - actor->_actionDirection = ITE_ActorTable[i].actionDirection; - - actor->_location.x = ITE_ActorTable[i].x; - actor->_location.y = ITE_ActorTable[i].y; - actor->_location.z = ITE_ActorTable[i].z; - - actor->_disabled = !loadActorResources(actor); - if (actor->_disabled) { - warning("Disabling actor Id=%d index=%d", actor->_id, actor->_index); - } - } - _objsCount = ITE_OBJECTCOUNT; - _objs = (ObjectData **)malloc(_objsCount * sizeof(*_objs)); - for (i = 0; i < _objsCount; i++) { - obj = _objs[i] = new ObjectData(); - obj->_id = objIndexToId(i); - obj->_index = i; - debug(9, "init obj id=%d index=%d", obj->_id, obj->_index); - obj->_nameIndex = ITE_ObjectTable[i].nameIndex; - obj->_scriptEntrypointNumber = ITE_ObjectTable[i].scriptEntrypointNumber; - obj->_spriteListResourceId = ITE_ObjectTable[i].spriteListResourceId; - obj->_sceneNumber = ITE_ObjectTable[i].sceneIndex; - obj->_interactBits = ITE_ObjectTable[i].interactBits; - - obj->_location.x = ITE_ObjectTable[i].x; - obj->_location.y = ITE_ObjectTable[i].y; - obj->_location.z = ITE_ObjectTable[i].z; - } - } else { - // TODO. This is causing problems for SYMBIAN os as it doesn't like a static class here - ActorData dummyActor; - - dummyActor._frames = NULL; - dummyActor._walkStepsPoints = NULL; - - _protagonist = &dummyActor; - } - - _dragonHunt = true; -} - -Actor::~Actor() { - debug(9, "Actor::~Actor()"); - -#ifdef ACTOR_DEBUG - free(_debugPoints); -#endif - free(_pathDirectionList); - free(_pathNodeList); - free(_newPathNodeList); - free(_pathList); - free(_pathCell); - _actorsStrings.freeMem(); - //release resources - freeActorList(); - freeObjList(); -} - -bool Actor::loadActorResources(ActorData *actor) { - byte *resourcePointer; - size_t resourceLength; - int framesCount; - ActorFrameSequence *framesPointer; - bool gotSomething = false; - - if (actor->_frameListResourceId) { - debug(9, "Loading frame resource id %d", actor->_frameListResourceId); - _vm->_resource->loadResource(_actorContext, actor->_frameListResourceId, resourcePointer, resourceLength); - - framesCount = resourceLength / 16; - debug(9, "Frame resource contains %d frames (res length is %d)", framesCount, resourceLength); - - framesPointer = (ActorFrameSequence *)malloc(sizeof(ActorFrameSequence) * framesCount); - if (framesPointer == NULL && framesCount != 0) { - memoryError("Actor::loadActorResources"); - } - - MemoryReadStreamEndian readS(resourcePointer, resourceLength, _actorContext->isBigEndian); - - for (int i = 0; i < framesCount; i++) { - debug(9, "frameType %d", i); - for (int orient = 0; orient < ACTOR_DIRECTIONS_COUNT; orient++) { - // Load all four orientations - framesPointer[i].directions[orient].frameIndex = readS.readUint16(); - if (_vm->getGameType() == GType_ITE) { - framesPointer[i].directions[orient].frameCount = readS.readSint16(); - } else { - framesPointer[i].directions[orient].frameCount = readS.readByte(); - readS.readByte(); - } - if (framesPointer[i].directions[orient].frameCount < 0) - warning("frameCount < 0 (%d)", framesPointer[i].directions[orient].frameCount); - debug(9, "frameIndex %d frameCount %d", framesPointer[i].directions[orient].frameIndex, framesPointer[i].directions[orient].frameCount); - } - } - - free(resourcePointer); - - actor->_frames = framesPointer; - actor->_framesCount = framesCount; - - gotSomething = true; - } else { - warning("Frame List ID = 0 for actor index %d", actor->_index); - - //if (_vm->getGameType() == GType_ITE) - return true; - } - - if (actor->_spriteListResourceId) { - gotSomething = true; - } else { - warning("Sprite List ID = 0 for actor index %d", actor->_index); - } - - return gotSomething; -} - -void Actor::freeActorList() { - int i; - ActorData *actor; - for (i = 0; i < _actorsCount; i++) { - actor = _actors[i]; - delete actor; - } - free(_actors); - _actors = NULL; - _actorsCount = 0; -} - -void Actor::loadActorSpriteList(ActorData *actor) { - int lastFrame = 0; - int resourceId = actor->_spriteListResourceId; - - for (int i = 0; i < actor->_framesCount; i++) { - for (int orient = 0; orient < ACTOR_DIRECTIONS_COUNT; orient++) { - if (actor->_frames[i].directions[orient].frameIndex > lastFrame) { - lastFrame = actor->_frames[i].directions[orient].frameIndex; - } - } - } - - debug(9, "Loading actor sprite resource id %d", resourceId); - - _vm->_sprite->loadList(resourceId, actor->_spriteList); - - if (_vm->getGameType() == GType_ITE) { - if (actor->_flags & kExtended) { - while ((lastFrame >= actor->_spriteList.spriteCount)) { - resourceId++; - debug(9, "Appending to actor sprite list %d", resourceId); - _vm->_sprite->loadList(resourceId, actor->_spriteList); - } - } - } -} - -void Actor::loadActorList(int protagonistIdx, int actorCount, int actorsResourceID, int protagStatesCount, int protagStatesResourceID) { - int i, j; - ActorData *actor; - byte* actorListData; - size_t actorListLength; - byte walk[128]; - byte acv[6]; - int movementSpeed; - int walkStepIndex; - int walkStepCount; - - freeActorList(); - - _vm->_resource->loadResource(_actorContext, actorsResourceID, actorListData, actorListLength); - - _actorsCount = actorCount; - - if (actorListLength != (uint)_actorsCount * ACTOR_INHM_SIZE) { - error("Actor::loadActorList wrong actorlist length"); - } - - MemoryReadStream actorS(actorListData, actorListLength); - - _actors = (ActorData **)malloc(_actorsCount * sizeof(*_actors)); - for (i = 0; i < _actorsCount; i++) { - actor = _actors[i] = new ActorData(); - actor->_id = objectIndexToId(kGameObjectActor, i); //actorIndexToId(i); - actor->_index = i; - debug(4, "init actor id=0x%x index=%d", actor->_id, actor->_index); - actorS.readUint32LE(); //next displayed - actorS.readByte(); //type - actor->_flags = actorS.readByte(); - actor->_nameIndex = actorS.readUint16LE(); - actor->_sceneNumber = actorS.readUint32LE(); - actor->_location.fromStream(actorS); - actor->_screenPosition.x = actorS.readUint16LE(); - actor->_screenPosition.y = actorS.readUint16LE(); - actor->_screenScale = actorS.readUint16LE(); - actor->_screenDepth = actorS.readUint16LE(); - actor->_spriteListResourceId = actorS.readUint32LE(); - actor->_frameListResourceId = actorS.readUint32LE(); - debug(4, "%d: %d, %d [%d]", i, actor->_spriteListResourceId, actor->_frameListResourceId, actor->_nameIndex); - actor->_scriptEntrypointNumber = actorS.readUint32LE(); - actorS.readUint32LE(); // xSprite *dSpr; - actorS.readUint16LE(); //LEFT - actorS.readUint16LE(); //RIGHT - actorS.readUint16LE(); //TOP - actorS.readUint16LE(); //BOTTOM - actor->_speechColor = actorS.readByte(); - actor->_currentAction = actorS.readByte(); - actor->_facingDirection = actorS.readByte(); - actor->_actionDirection = actorS.readByte(); - actor->_actionCycle = actorS.readUint16LE(); - actor->_frameNumber = actorS.readUint16LE(); - actor->_finalTarget.fromStream(actorS); - actor->_partialTarget.fromStream(actorS); - movementSpeed = actorS.readUint16LE(); //movement speed - if (movementSpeed) { - error("Actor::loadActorList movementSpeed != 0"); - } - actorS.read(walk, 128); - for (j = 0; j < 128; j++) { - if (walk[j]) { - error("Actor::loadActorList walk[128] != 0"); - } - } - //actorS.seek(128, SEEK_CUR); - walkStepCount = actorS.readByte();//walkStepCount - if (walkStepCount) { - error("Actor::loadActorList walkStepCount != 0"); - } - walkStepIndex = actorS.readByte();//walkStepIndex - if (walkStepIndex) { - error("Actor::loadActorList walkStepIndex != 0"); - } - //no need to check pointers - actorS.readUint32LE(); //sprites - actorS.readUint32LE(); //frames - actorS.readUint32LE(); //last zone - actor->_targetObject = actorS.readUint16LE(); - actor->_actorFlags = actorS.readUint16LE(); - //no need to check pointers - actorS.readUint32LE(); //next in scene - actorS.read(acv, 6); - for (j = 0; j < 6; j++) { - if (acv[j]) { - error("Actor::loadActorList acv[%d] != 0", j); - } - } -// actorS.seek(6, SEEK_CUR); //action vars - } - free(actorListData); - - _actors[protagonistIdx]->_flags |= kProtagonist | kExtended; - - for (i = 0; i < _actorsCount; i++) { - actor = _actors[i]; - //if (actor->_flags & kProtagonist) { - loadActorResources(actor); - //break; - //} - } - - _centerActor = _protagonist = _actors[protagonistIdx]; - _protagState = 0; - - if (protagStatesResourceID) { - free(_protagStates); - - _protagStates = (ActorFrameSequence *)malloc(sizeof(ActorFrameSequence) * protagStatesCount); - - byte *resourcePointer; - size_t resourceLength; - - _vm->_resource->loadResource(_actorContext, protagStatesResourceID, - resourcePointer, resourceLength); - - - MemoryReadStream statesS(resourcePointer, resourceLength); - - for (i = 0; i < protagStatesCount; i++) { - for (j = 0; j < ACTOR_DIRECTIONS_COUNT; j++) { - _protagStates[i].directions[j].frameIndex = statesS.readUint16LE(); - _protagStates[i].directions[j].frameCount = statesS.readUint16LE(); - } - } - free(resourcePointer); - - _protagonist->_frames = &_protagStates[_protagState]; - } - - _protagStatesCount = protagStatesCount; -} - -void Actor::freeObjList() { - int i; - ObjectData *object; - for (i = 0; i < _objsCount; i++) { - object = _objs[i]; - delete object; - } - free(_objs); - _objs = NULL; - _objsCount = 0; -} - -void Actor::loadObjList(int objectCount, int objectsResourceID) { - int i; - int frameListResourceId; - ObjectData *object; - byte* objectListData; - size_t objectListLength; - freeObjList(); - - _vm->_resource->loadResource(_actorContext, objectsResourceID, objectListData, objectListLength); - - _objsCount = objectCount; - - MemoryReadStream objectS(objectListData, objectListLength); - - _objs = (ObjectData **)malloc(_objsCount * sizeof(*_objs)); - for (i = 0; i < _objsCount; i++) { - object = _objs[i] = new ObjectData(); - object->_id = objectIndexToId(kGameObjectObject, i); - object->_index = i; - debug(9, "init object id=%d index=%d", object->_id, object->_index); - objectS.readUint32LE(); //next displayed - objectS.readByte(); //type - object->_flags = objectS.readByte(); - object->_nameIndex = objectS.readUint16LE(); - object->_sceneNumber = objectS.readUint32LE(); - object->_location.fromStream(objectS); - object->_screenPosition.x = objectS.readUint16LE(); - object->_screenPosition.y = objectS.readUint16LE(); - object->_screenScale = objectS.readUint16LE(); - object->_screenDepth = objectS.readUint16LE(); - object->_spriteListResourceId = objectS.readUint32LE(); - frameListResourceId = objectS.readUint32LE(); // object->_frameListResourceId - if (frameListResourceId) { - error("Actor::loadObjList frameListResourceId != 0"); - } - object->_scriptEntrypointNumber = objectS.readUint32LE(); - objectS.readUint32LE(); // xSprite *dSpr; - objectS.readUint16LE(); //LEFT - objectS.readUint16LE(); //RIGHT - objectS.readUint16LE(); //TOP - objectS.readUint16LE(); //BOTTOM - object->_interactBits = objectS.readUint16LE(); - } - free(objectListData); -} - -void Actor::takeExit(uint16 actorId, const HitZone *hitZone) { - ActorData *actor; - actor = getActor(actorId); - actor->_lastZone = NULL; - - _vm->_scene->changeScene(hitZone->getSceneNumber(), hitZone->getActorsEntrance(), kTransitionNoFade); - if (_vm->_interface->getMode() != kPanelSceneSubstitute) { - _vm->_script->setNoPendingVerb(); - } -} - -void Actor::stepZoneAction(ActorData *actor, const HitZone *hitZone, bool exit, bool stopped) { - Event event; - - if (actor != _protagonist) { - return; - } - if (((hitZone->getFlags() & kHitZoneTerminus) && !stopped) || (!(hitZone->getFlags() & kHitZoneTerminus) && stopped)) { - return; - } - - if (!exit) { - if (hitZone->getFlags() & kHitZoneAutoWalk) { - actor->_currentAction = kActionWalkDir; - actor->_actionDirection = actor->_facingDirection = hitZone->getDirection(); - actor->_walkFrameSequence = getFrameType(kFrameWalk); - return; - } - } else if (!(hitZone->getFlags() & kHitZoneAutoWalk)) { - return; - } - if (hitZone->getFlags() & kHitZoneExit) { - takeExit(actor->_id, hitZone); - } else if (hitZone->getScriptNumber() > 0) { - event.type = kEvTOneshot; - event.code = kScriptEvent; - event.op = kEventExecNonBlocking; - event.time = 0; - event.param = _vm->_scene->getScriptModuleNumber(); // module number - event.param2 = hitZone->getScriptNumber(); // script entry point number - event.param3 = _vm->_script->getVerbType(kVerbEnter); // Action - event.param4 = ID_NOTHING; // Object - event.param5 = ID_NOTHING; // With Object - event.param6 = ID_PROTAG; // Actor - - _vm->_events->queue(&event); - } -} - -void Actor::realLocation(Location &location, uint16 objectId, uint16 walkFlags) { - int angle; - int distance; - ActorData *actor; - ObjectData *obj; - debug (8, "Actor::realLocation objectId=%i", objectId); - if (walkFlags & kWalkUseAngle) { - if (_vm->_scene->getFlags() & kSceneFlagISO) { - angle = (location.x + 2) & 15; - distance = location.y; - - location.u() = (angleLUT[angle][0] * distance) >> 8; - location.v() = -(angleLUT[angle][1] * distance) >> 8; - } else { - angle = location.x & 15; - distance = location.y; - - location.x = (angleLUT[angle][0] * distance) >> 6; - location.y = (angleLUT[angle][1] * distance) >> 6; - } - } - - if (objectId != ID_NOTHING) { - if (validActorId(objectId)) { - actor = getActor(objectId); - location.addXY(actor->_location); - } else if (validObjId(objectId)) { - obj = getObj(objectId); - location.addXY(obj->_location); - } - } -} - -void Actor::actorFaceTowardsPoint(uint16 actorId, const Location &toLocation) { - ActorData *actor; - Location delta; - //debug (8, "Actor::actorFaceTowardsPoint actorId=%i", actorId); - actor = getActor(actorId); - - toLocation.delta(actor->_location, delta); - - if (_vm->_scene->getFlags() & kSceneFlagISO) { - if (delta.u() > 0) { - actor->_facingDirection = (delta.v() > 0) ? kDirUp : kDirRight; - } else { - actor->_facingDirection = (delta.v() > 0) ? kDirLeft : kDirDown; - } - } else { - if (ABS(delta.y) > ABS(delta.x * 2)) { - actor->_facingDirection = (delta.y > 0) ? kDirDown : kDirUp; - } else { - actor->_facingDirection = (delta.x > 0) ? kDirRight : kDirLeft; - } - } -} - -void Actor::actorFaceTowardsObject(uint16 actorId, uint16 objectId) { - ActorData *actor; - ObjectData *obj; - - if (validActorId(objectId)) { - actor = getActor(objectId); - actorFaceTowardsPoint(actorId, actor->_location); - } else if (validObjId(objectId)) { - obj = getObj(objectId); - actorFaceTowardsPoint(actorId, obj->_location); - } -} - - -ObjectData *Actor::getObj(uint16 objId) { - ObjectData *obj; - - if (!validObjId(objId)) - error("Actor::getObj Wrong objId 0x%X", objId); - - obj = _objs[objIdToIndex(objId)]; - - if (obj->_disabled) - error("Actor::getObj disabled objId 0x%X", objId); - - return obj; -} - -ActorData *Actor::getActor(uint16 actorId) { - ActorData *actor; - - if (!validActorId(actorId)) { - warning("Actor::getActor Wrong actorId 0x%X", actorId); - assert(0); - } - - if (actorId == ID_PROTAG) { - if (_protagonist == NULL) { - error("_protagonist == NULL"); - } - return _protagonist; - } - - actor = _actors[actorIdToIndex(actorId)]; - - if (actor->_disabled) - error("Actor::getActor disabled actorId 0x%X", actorId); - - return actor; -} - -bool Actor::validFollowerLocation(const Location &location) { - Point point; - location.toScreenPointXY(point); - - if ((point.x < 5) || (point.x >= _vm->getDisplayWidth() - 5) || - (point.y < 0) || (point.y > _vm->_scene->getHeight())) { - return false; - } - - return (_vm->_scene->canWalk(point)); -} - -void Actor::setProtagState(int state) { - _protagState = state; - - if (_vm->getGameType() == GType_IHNM) - _protagonist->_frames = &_protagStates[state]; -} - -void Actor::updateActorsScene(int actorsEntrance) { - int i, j; - int followerDirection; - ActorData *actor; - Location tempLocation; - Location possibleLocation; - Point delta; - const SceneEntry *sceneEntry; - - if (_vm->_scene->currentSceneNumber() == 0) { - error("Actor::updateActorsScene _vm->_scene->currentSceneNumber() == 0"); - } - - _vm->_sound->stopVoice(); - _activeSpeech.stringsCount = 0; - _activeSpeech.playing = false; - _protagonist = NULL; - - for (i = 0; i < _actorsCount; i++) { - actor = _actors[i]; - actor->_inScene = false; - actor->_spriteList.freeMem(); - if (actor->_disabled) { - continue; - } - if ((actor->_flags & (kProtagonist | kFollower)) || (i == 0)) { - if (actor->_flags & kProtagonist) { - actor->_finalTarget = actor->_location; - _centerActor = _protagonist = actor; - } else if (_vm->getGameType() == GType_ITE && - _vm->_scene->currentSceneResourceId() == RID_ITE_OVERMAP_SCENE) { - continue; - } - - actor->_sceneNumber = _vm->_scene->currentSceneNumber(); - } - if (actor->_sceneNumber == _vm->_scene->currentSceneNumber()) { - actor->_inScene = true; - actor->_actionCycle = (_vm->_rnd.getRandomNumber(7) & 0x7) * 4; // 1/8th chance - } - } - - assert(_protagonist); - - if ((actorsEntrance >= 0) && (_vm->_scene->_entryList.entryListCount > 0)) { - if (_vm->_scene->_entryList.entryListCount <= actorsEntrance) { - actorsEntrance = 0; //OCEAN bug - } - - sceneEntry = _vm->_scene->_entryList.getEntry(actorsEntrance); - if (_vm->_scene->getFlags() & kSceneFlagISO) { - _protagonist->_location = sceneEntry->location; - } else { - _protagonist->_location.x = sceneEntry->location.x * ACTOR_LMULT; - _protagonist->_location.y = sceneEntry->location.y * ACTOR_LMULT; - _protagonist->_location.z = sceneEntry->location.z * ACTOR_LMULT; - } - // Workaround for bug #1328045: - // "When entering any of the houses at the start of the - // game if you click on anything inside the building you - // start walking through the door, turn around and leave." - // - // After steping of action zone - Rif trying to exit. - // This piece of code shift Rif's entry position to non action zone area. - if (_vm->getGameType() == GType_ITE) { - if ((_vm->_scene->currentSceneNumber() >= 53) && (_vm->_scene->currentSceneNumber() <= 66)) - _protagonist->_location.y += 10; - } - - _protagonist->_facingDirection = _protagonist->_actionDirection = sceneEntry->facing; - } - - _protagonist->_currentAction = kActionWait; - - if (_vm->_scene->getFlags() & kSceneFlagISO) { - //nothing? - } else { - _vm->_scene->initDoorsState(); //TODO: move to _scene - } - - followerDirection = _protagonist->_facingDirection + 3; - calcScreenPosition(_protagonist); - - for (i = 0; i < _actorsCount; i++) { - actor = _actors[i]; - if (actor->_flags & (kFollower)) { - actor->_facingDirection = actor->_actionDirection = _protagonist->_facingDirection; - actor->_currentAction = kActionWait; - actor->_walkStepsCount = actor->_walkStepIndex = 0; - actor->_location.z = _protagonist->_location.z; - - - if (_vm->_scene->getFlags() & kSceneFlagISO) { - _vm->_isoMap->placeOnTileMap(_protagonist->_location, actor->_location, 3, followerDirection & 0x07); - } else { - followerDirection &= 0x07; - - possibleLocation = _protagonist->_location; - - - delta.x = directionLUT[followerDirection][0]; - delta.y = directionLUT[followerDirection][1]; - - - for (j = 0; j < 30; j++) { - tempLocation = possibleLocation; - tempLocation.x += delta.x; - tempLocation.y += delta.y; - - if (validFollowerLocation(tempLocation)) { - possibleLocation = tempLocation; - } else { - tempLocation = possibleLocation; - tempLocation.x += delta.x; - if (validFollowerLocation(tempLocation)) { - possibleLocation = tempLocation; - } else { - tempLocation = possibleLocation; - tempLocation.y += delta.y; - if (validFollowerLocation(tempLocation)) { - possibleLocation = tempLocation; - } else { - break; - } - } - } - } - - actor->_location = possibleLocation; - } - followerDirection += 2; - } - - } - - handleActions(0, true); - if (_vm->_scene->getFlags() & kSceneFlagISO) { - _vm->_isoMap->adjustScroll(true); - } -} - -int Actor::getFrameType(ActorFrameTypes frameType) { - - if (_vm->getGameType() == GType_ITE) { - switch (frameType) { - case kFrameStand: - return kFrameITEStand; - case kFrameWalk: - return kFrameITEWalk; - case kFrameSpeak: - return kFrameITESpeak; - case kFrameGive: - return kFrameITEGive; - case kFrameGesture: - return kFrameITEGesture; - case kFrameWait: - return kFrameITEWait; - case kFramePickUp: - return kFrameITEPickUp; - case kFrameLook: - return kFrameITELook; - } - } - else { - switch (frameType) { - case kFrameStand: - return kFrameIHNMStand; - case kFrameWalk: - return kFrameIHNMWalk; - case kFrameSpeak: - return kFrameIHNMSpeak; - case kFrameGesture: - return kFrameIHNMGesture; - case kFrameWait: - return kFrameIHNMWait; - case kFrameGive: - case kFramePickUp: - case kFrameLook: - error("Actor::getFrameType() unknown frame type %d", frameType); - return kFrameIHNMStand; - } - } - error("Actor::getFrameType() unknown frame type %d", frameType); -} - -ActorFrameRange *Actor::getActorFrameRange(uint16 actorId, int frameType) { - ActorData *actor; - int fourDirection; - static ActorFrameRange def = {0, 0}; - - actor = getActor(actorId); - if (actor->_disabled) - error("Actor::getActorFrameRange Wrong actorId 0x%X", actorId); - - if ((actor->_facingDirection < kDirUp) || (actor->_facingDirection > kDirUpLeft)) - error("Actor::getActorFrameRange Wrong direction 0x%X actorId 0x%X", actor->_facingDirection, actorId); - - //if (_vm->getGameType() == GType_ITE) { - if (frameType >= actor->_framesCount) { - warning("Actor::getActorFrameRange Wrong frameType 0x%X (%d) actorId 0x%X", frameType, actor->_framesCount, actorId); - return &def; - } - - - fourDirection = actorDirectectionsLUT[actor->_facingDirection]; - return &actor->_frames[frameType].directions[fourDirection]; -/* - } else { - if (0 == actor->_framesCount) { - return &def; - } - - //TEST - if (actor->_id == 0x2000) { - if (actor->_framesCount <= _currentFrameIndex) { - _currentFrameIndex = 0; - } - fr = actor->_frames[_currentFrameIndex].directions; - return fr; - } - //TEST - if (frameType >= actor->_framesCount) { - frameType = actor->_framesCount - 1; - } - if (frameType < 0) { - frameType = 0; - } - - if (frameType == kFrameIHNMWalk ) { - switch (actor->_facingDirection) { - case kDirUpRight: - if (frameType > 0) - fr = &actor->_frames[frameType - 1].directions[ACTOR_DIRECTION_RIGHT]; - else - fr = &def; - if (!fr->frameCount) - fr = &actor->_frames[frameType].directions[ACTOR_DIRECTION_RIGHT]; - break; - case kDirDownRight: - if (frameType > 0) - fr = &actor->_frames[frameType - 1].directions[ACTOR_DIRECTION_FORWARD]; - else - fr = &def; - if (!fr->frameCount) - fr = &actor->_frames[frameType].directions[ACTOR_DIRECTION_RIGHT]; - break; - case kDirUpLeft: - if (frameType > 0) - fr = &actor->_frames[frameType - 1].directions[ACTOR_DIRECTION_LEFT]; - else - fr = &def; - if (!fr->frameCount) - fr = &actor->_frames[frameType].directions[ACTOR_DIRECTION_LEFT]; - break; - case kDirDownLeft: - if (frameType > 0) - fr = &actor->_frames[frameType - 1].directions[ACTOR_DIRECTION_BACK]; - else - fr = &def; - if (!fr->frameCount) - fr = &actor->_frames[frameType].directions[ACTOR_DIRECTION_LEFT]; - break; - case kDirRight: - fr = &actor->_frames[frameType].directions[ACTOR_DIRECTION_RIGHT]; - break; - case kDirLeft: - fr = &actor->_frames[frameType].directions[ACTOR_DIRECTION_LEFT]; - break; - case kDirUp: - fr = &actor->_frames[frameType].directions[ACTOR_DIRECTION_BACK]; - break; - case kDirDown: - fr = &actor->_frames[frameType].directions[ACTOR_DIRECTION_FORWARD]; - break; - } - return fr; - } - else { - if (frameType >= actor->_framesCount) { - error("Actor::getActorFrameRange Wrong frameType 0x%X (%d) actorId 0x%X", frameType, actor->_framesCount, actorId); - } - fourDirection = actorDirectectionsLUT[actor->_facingDirection]; - return &actor->_frames[frameType].directions[fourDirection]; - } - }*/ -} - -void Actor::handleSpeech(int msec) { - int stringLength; - int sampleLength; - bool removeFirst; - int i; - ActorData *actor; - int width, height, height2; - Point posPoint; - - if (_activeSpeech.playing) { - _activeSpeech.playingTime -= msec; - stringLength = strlen(_activeSpeech.strings[0]); - - removeFirst = false; - if (_activeSpeech.playingTime <= 0) { - if (_activeSpeech.speechFlags & kSpeakSlow) { - _activeSpeech.slowModeCharIndex++; - if (_activeSpeech.slowModeCharIndex >= stringLength) - removeFirst = true; - } else { - removeFirst = true; - } - _activeSpeech.playing = false; - if (_activeSpeech.actorIds[0] != 0) { - actor = getActor(_activeSpeech.actorIds[0]); - if (!(_activeSpeech.speechFlags & kSpeakNoAnimate)) { - actor->_currentAction = kActionWait; - } - } - } - - if (removeFirst) { - for (i = 1; i < _activeSpeech.stringsCount; i++) { - _activeSpeech.strings[i - 1] = _activeSpeech.strings[i]; - } - _activeSpeech.stringsCount--; - } - - if (_vm->_script->_skipSpeeches) { - _activeSpeech.stringsCount = 0; - _vm->_script->wakeUpThreads(kWaitTypeSpeech); - return; - } - - if (_activeSpeech.stringsCount == 0) { - _vm->_script->wakeUpThreadsDelayed(kWaitTypeSpeech, ticksToMSec(kScriptTimeTicksPerSecond / 3)); - } - - return; - } - - if (_vm->_script->_skipSpeeches) { - _activeSpeech.stringsCount = 0; - _vm->_script->wakeUpThreads(kWaitTypeSpeech); - } - - if (_activeSpeech.stringsCount == 0) { - return; - } - - stringLength = strlen(_activeSpeech.strings[0]); - - if (_activeSpeech.speechFlags & kSpeakSlow) { - if (_activeSpeech.slowModeCharIndex >= stringLength) - error("Wrong string index"); - - warning("Slow string encountered!"); - _activeSpeech.playingTime = stringLength * 1000 / 4; - - } else { - sampleLength = _vm->_sndRes->getVoiceLength(_activeSpeech.sampleResourceId); - - if (sampleLength < 0) { - _activeSpeech.playingTime = stringLength * 1000 / 22; - switch (_vm->_readingSpeed) { - case 1: - _activeSpeech.playingTime *= 2; - break; - case 2: - _activeSpeech.playingTime *= 4; - break; - case 3: - _activeSpeech.playingTime = 0x7fffff; - break; - } - } else { - _activeSpeech.playingTime = sampleLength; - } - } - - if (_activeSpeech.sampleResourceId != -1) { - _vm->_sndRes->playVoice(_activeSpeech.sampleResourceId); - _activeSpeech.sampleResourceId++; - } - - if (_activeSpeech.actorIds[0] != 0) { - actor = getActor(_activeSpeech.actorIds[0]); - if (!(_activeSpeech.speechFlags & kSpeakNoAnimate)) { - actor->_currentAction = kActionSpeak; - actor->_actionCycle = _vm->_rnd.getRandomNumber(63); - } - } - - if (_activeSpeech.actorsCount == 1) { - if (_speechBoxScript.width() > 0) { - _activeSpeech.drawRect.left = _speechBoxScript.left; - _activeSpeech.drawRect.right = _speechBoxScript.right; - _activeSpeech.drawRect.top = _speechBoxScript.top; - _activeSpeech.drawRect.bottom = _speechBoxScript.bottom; - } else { - width = _activeSpeech.speechBox.width(); - height = _vm->_font->getHeight(kKnownFontScript, _activeSpeech.strings[0], width - 2, _activeSpeech.getFontFlags(0)) + 1; - - if (height > 40 && width < _vm->getDisplayWidth() - 100) { - width = _vm->getDisplayWidth() - 100; - height = _vm->_font->getHeight(kKnownFontScript, _activeSpeech.strings[0], width - 2, _activeSpeech.getFontFlags(0)) + 1; - } - - _activeSpeech.speechBox.setWidth(width); - - if (_activeSpeech.actorIds[0] != 0) { - actor = getActor(_activeSpeech.actorIds[0]); - _activeSpeech.speechBox.setHeight(height); - - if (_activeSpeech.speechBox.right > _vm->getDisplayWidth() - 10) { - _activeSpeech.drawRect.left = _vm->getDisplayWidth() - 10 - width; - } else { - _activeSpeech.drawRect.left = _activeSpeech.speechBox.left; - } - - height2 = actor->_screenPosition.y - 50; - _activeSpeech.speechBox.top = _activeSpeech.drawRect.top = MAX(10, (height2 - height) / 2); - } else { - _activeSpeech.drawRect.left = _activeSpeech.speechBox.left; - _activeSpeech.drawRect.top = _activeSpeech.speechBox.top + (_activeSpeech.speechBox.height() - height) / 2; - } - _activeSpeech.drawRect.setWidth(width); - _activeSpeech.drawRect.setHeight(height); - } - } - - _activeSpeech.playing = true; -} - -void Actor::handleActions(int msec, bool setup) { - int i; - ActorData *actor; - ActorFrameRange *frameRange; - int state; - int speed; - int32 framesLeft; - Location delta; - Location addDelta; - int hitZoneIndex; - const HitZone *hitZone; - Point hitPoint; - Location pickLocation; - - for (i = 0; i < _actorsCount; i++) { - actor = _actors[i]; - if (!actor->_inScene) - continue; - - if ((_vm->getGameType() == GType_ITE) && (i == ACTOR_DRAGON_INDEX)) { - moveDragon(actor); - continue; - } - - switch (actor->_currentAction) { - case kActionWait: - if (!setup && (actor->_flags & kFollower)) { - followProtagonist(actor); - if (actor->_currentAction != kActionWait) - break; - } - - if (actor->_targetObject != ID_NOTHING) { - actorFaceTowardsObject(actor->_id, actor->_targetObject); - } - - if (actor->_flags & kCycle) { - frameRange = getActorFrameRange(actor->_id, getFrameType(kFrameStand)); - if (frameRange->frameCount > 0) { - actor->_actionCycle++; - actor->_actionCycle = (actor->_actionCycle) % frameRange->frameCount; - } else { - actor->_actionCycle = 0; - } - actor->_frameNumber = frameRange->frameIndex + actor->_actionCycle; - break; - } - - if ((actor->_actionCycle & 3) == 0) { - actor->cycleWrap(100); - - frameRange = getActorFrameRange(actor->_id, getFrameType(kFrameWait)); - if ((frameRange->frameCount < 1 || actor->_actionCycle > 33)) - frameRange = getActorFrameRange(actor->_id, getFrameType(kFrameStand)); - - if (frameRange->frameCount) { - actor->_frameNumber = frameRange->frameIndex + (uint16)_vm->_rnd.getRandomNumber(frameRange->frameCount - 1); - } else { - actor->_frameNumber = frameRange->frameIndex; - } - } - actor->_actionCycle++; - break; - - case kActionWalkToPoint: - case kActionWalkToLink: - if (_vm->_scene->getFlags() & kSceneFlagISO) { - actor->_partialTarget.delta(actor->_location, delta); - - while ((delta.u() == 0) && (delta.v() == 0)) { - - if ((actor == _protagonist) && (_vm->mouseButtonPressed())) { - _vm->_isoMap->screenPointToTileCoords(_vm->mousePos(), pickLocation); - - if (!actorWalkTo(_protagonist->_id, pickLocation)) { - break; - } - } else if (!_vm->_isoMap->nextTileTarget(actor) && !actorEndWalk(actor->_id, true)) { - break; - } - - actor->_partialTarget.delta(actor->_location, delta); - actor->_partialTarget.z = 0; - } - - if (actor->_flags & kFastest) { - speed = 8; - } else if (actor->_flags & kFaster) { - speed = 6; - } else { - speed = 4; - } - - if (_vm->_scene->currentSceneResourceId() == RID_ITE_OVERMAP_SCENE) { - speed = 2; - } - - if ((actor->_actionDirection == 2) || (actor->_actionDirection == 6)) { - speed = speed / 2; - } - - if (ABS(delta.v()) > ABS(delta.u())) { - addDelta.v() = clamp(-speed, delta.v(), speed); - if (addDelta.v() == delta.v()) { - addDelta.u() = delta.u(); - } else { - addDelta.u() = delta.u() * addDelta.v(); - addDelta.u() += (addDelta.u() > 0) ? (delta.v() / 2) : (-delta.v() / 2); - addDelta.u() /= delta.v(); - } - } else { - addDelta.u() = clamp(-speed, delta.u(), speed); - if (addDelta.u() == delta.u()) { - addDelta.v() = delta.v(); - } else { - addDelta.v() = delta.v() * addDelta.u(); - addDelta.v() += (addDelta.v() > 0) ? (delta.u() / 2) : (-delta.u() / 2); - addDelta.v() /= delta.u(); - } - } - - actor->_location.add(addDelta); - } else { - actor->_partialTarget.delta(actor->_location, delta); - - while ((delta.x == 0) && (delta.y == 0)) { - - if (actor->_walkStepIndex >= actor->_walkStepsCount) { - actorEndWalk(actor->_id, true); - break; - } - - actor->_partialTarget.fromScreenPoint(actor->_walkStepsPoints[actor->_walkStepIndex++]); - if (_vm->getGameType() == GType_ITE) { - if (actor->_partialTarget.x > 224 * 2 * ACTOR_LMULT) { - actor->_partialTarget.x -= 256 * 2 * ACTOR_LMULT; - } - } else { - if (actor->_partialTarget.x > 224 * 4 * ACTOR_LMULT) { - actor->_partialTarget.x -= 256 * 4 * ACTOR_LMULT; - } - } - - actor->_partialTarget.delta(actor->_location, delta); - - if (ABS(delta.y) > ABS(delta.x)) { - actor->_actionDirection = delta.y > 0 ? kDirDown : kDirUp; - } else { - actor->_actionDirection = delta.x > 0 ? kDirRight : kDirLeft; - } - } - - speed = (ACTOR_LMULT * 2 * actor->_screenScale + 63) / 256; - if (speed < 1) { - speed = 1; - } - - if ((actor->_actionDirection == kDirUp) || (actor->_actionDirection == kDirDown)) { - addDelta.y = clamp(-speed, delta.y, speed); - if (addDelta.y == delta.y) { - addDelta.x = delta.x; - } else { - addDelta.x = delta.x * addDelta.y; - addDelta.x += (addDelta.x > 0) ? (delta.y / 2) : (-delta.y / 2); - addDelta.x /= delta.y; - actor->_facingDirection = actor->_actionDirection; - } - } else { - addDelta.x = clamp(-2 * speed, delta.x, 2 * speed); - if (addDelta.x == delta.x) { - addDelta.y = delta.y; - } else { - addDelta.y = delta.y * addDelta.x; - addDelta.y += (addDelta.y > 0) ? (delta.x / 2) : (-delta.x / 2); - addDelta.y /= delta.x; - actor->_facingDirection = actor->_actionDirection; - } - } - - actor->_location.add(addDelta); - } - - if (actor->_actorFlags & kActorBackwards) { - actor->_facingDirection = (actor->_actionDirection + 4) & 7; - actor->_actionCycle--; - } else { - actor->_actionCycle++; - } - - frameRange = getActorFrameRange(actor->_id, actor->_walkFrameSequence); - - if (actor->_actionCycle < 0) { - actor->_actionCycle = frameRange->frameCount - 1; - } else if (actor->_actionCycle >= frameRange->frameCount) { - actor->_actionCycle = 0; - } - - actor->_frameNumber = frameRange->frameIndex + actor->_actionCycle; - break; - - case kActionWalkDir: - if (_vm->_scene->getFlags() & kSceneFlagISO) { - actor->_location.u() += tileDirectionLUT[actor->_actionDirection][0]; - actor->_location.v() += tileDirectionLUT[actor->_actionDirection][1]; - - frameRange = getActorFrameRange(actor->_id, actor->_walkFrameSequence); - - actor->_actionCycle++; - actor->cycleWrap(frameRange->frameCount); - actor->_frameNumber = frameRange->frameIndex + actor->_actionCycle; - } else { - actor->_location.x += directionLUT[actor->_actionDirection][0] * 2; - actor->_location.y += directionLUT[actor->_actionDirection][1] * 2; - - frameRange = getActorFrameRange(actor->_id, actor->_walkFrameSequence); - actor->_actionCycle++; - actor->cycleWrap(frameRange->frameCount); - actor->_frameNumber = frameRange->frameIndex + actor->_actionCycle; - } - break; - - case kActionSpeak: - actor->_actionCycle++; - actor->cycleWrap(64); - - frameRange = getActorFrameRange(actor->_id, getFrameType(kFrameGesture)); - if (actor->_actionCycle >= frameRange->frameCount) { - if (actor->_actionCycle & 1) - break; - frameRange = getActorFrameRange(actor->_id, getFrameType(kFrameSpeak)); - - state = (uint16)_vm->_rnd.getRandomNumber(frameRange->frameCount); - - if (state == 0) { - frameRange = getActorFrameRange(actor->_id, getFrameType(kFrameStand)); - } else { - state--; - } - } else { - state = actor->_actionCycle; - } - - actor->_frameNumber = frameRange->frameIndex + state; - break; - - case kActionAccept: - case kActionStoop: - break; - - case kActionCycleFrames: - case kActionPongFrames: - if (actor->_cycleTimeCount > 0) { - actor->_cycleTimeCount--; - break; - } - - actor->_cycleTimeCount = actor->_cycleDelay; - actor->_actionCycle++; - - frameRange = getActorFrameRange(actor->_id, actor->_cycleFrameSequence); - - if (actor->_currentAction == kActionPongFrames) { - if (actor->_actionCycle >= frameRange->frameCount * 2 - 2) { - if (actor->_actorFlags & kActorContinuous) { - actor->_actionCycle = 0; - } else { - actor->_currentAction = kActionFreeze; - break; - } - } - - state = actor->_actionCycle; - if (state >= frameRange->frameCount) { - state = frameRange->frameCount * 2 - 2 - state; - } - } else { - if (actor->_actionCycle >= frameRange->frameCount) { - if (actor->_actorFlags & kActorContinuous) { - actor->_actionCycle = 0; - } else { - actor->_currentAction = kActionFreeze; - break; - } - } - state = actor->_actionCycle; - } - - if (frameRange->frameCount && (actor->_actorFlags & kActorRandom)) { - state = _vm->_rnd.getRandomNumber(frameRange->frameCount - 1); - } - - if (actor->_actorFlags & kActorBackwards) { - actor->_frameNumber = frameRange->frameIndex + frameRange->frameCount - 1 - state; - } else { - actor->_frameNumber = frameRange->frameIndex + state; - } - break; - - case kActionFall: - if (actor->_actionCycle > 0) { - framesLeft = actor->_actionCycle--; - actor->_finalTarget.delta(actor->_location, delta); - delta.x /= framesLeft; - delta.y /= framesLeft; - actor->_location.addXY(delta); - actor->_fallVelocity += actor->_fallAcceleration; - actor->_fallPosition += actor->_fallVelocity; - actor->_location.z = actor->_fallPosition >> 4; - } else { - actor->_location = actor->_finalTarget; - actor->_currentAction = kActionFreeze; - _vm->_script->wakeUpActorThread(kWaitTypeWalk, actor); - } - break; - - case kActionClimb: - actor->_cycleDelay++; - if (actor->_cycleDelay & 3) { - break; - } - - if (actor->_location.z >= actor->_finalTarget.z + ACTOR_CLIMB_SPEED) { - actor->_location.z -= ACTOR_CLIMB_SPEED; - actor->_actionCycle--; - } else if (actor->_location.z <= actor->_finalTarget.z - ACTOR_CLIMB_SPEED) { - actor->_location.z += ACTOR_CLIMB_SPEED; - actor->_actionCycle++; - } else { - actor->_location.z = actor->_finalTarget.z; - actor->_currentAction = kActionFreeze; - _vm->_script->wakeUpActorThread(kWaitTypeWalk, actor); - } - - frameRange = getActorFrameRange(actor->_id, actor->_cycleFrameSequence); - - if (actor->_actionCycle < 0) { - actor->_actionCycle = frameRange->frameCount - 1; - } - actor->cycleWrap(frameRange->frameCount); - actor->_frameNumber = frameRange->frameIndex + actor->_actionCycle; - break; - } - - if ((actor->_currentAction >= kActionWalkToPoint) && (actor->_currentAction <= kActionWalkDir)) { - hitZone = NULL; - - if (_vm->_scene->getFlags() & kSceneFlagISO) { - actor->_location.toScreenPointUV(hitPoint); - } else { - actor->_location.toScreenPointXY(hitPoint); - } - hitZoneIndex = _vm->_scene->_actionMap->hitTest(hitPoint); - if (hitZoneIndex != -1) { - hitZone = _vm->_scene->_actionMap->getHitZone(hitZoneIndex); - } - - if (hitZone != actor->_lastZone) { - if (actor->_lastZone) - stepZoneAction(actor, actor->_lastZone, true, false); - actor->_lastZone = hitZone; - if (hitZone) - stepZoneAction(actor, hitZone, false, false); - } - } - } -} - -void Actor::direct(int msec) { - - if (_vm->_scene->_entryList.entryListCount == 0) { - return; - } - - if (_vm->_interface->_statusTextInput) { - return; - } - - // FIXME: HACK. This should be turned into cycle event. - _lastTickMsec += msec; - - if (_lastTickMsec > 1000 / _handleActionDiv) { - _lastTickMsec = 0; - //process actions - handleActions(msec, false); - } - -//process speech - handleSpeech(msec); -} - - -bool Actor::calcScreenPosition(CommonObjectData *commonObjectData) { - int beginSlope, endSlope, middle; - bool result; - if (_vm->_scene->getFlags() & kSceneFlagISO) { - _vm->_isoMap->tileCoordsToScreenPoint(commonObjectData->_location, commonObjectData->_screenPosition); - commonObjectData->_screenScale = 256; - } else { - middle = _vm->_scene->getHeight() - commonObjectData->_location.y / ACTOR_LMULT; - - _vm->_scene->getSlopes(beginSlope, endSlope); - - commonObjectData->_screenDepth = (14 * middle) / endSlope + 1; - - if (middle <= beginSlope) { - commonObjectData->_screenScale = 256; - } else if (middle >= endSlope) { - commonObjectData->_screenScale = 1; - } else { - middle -= beginSlope; - endSlope -= beginSlope; - commonObjectData->_screenScale = 256 - (middle * 256) / endSlope; - } - - commonObjectData->_location.toScreenPointXYZ(commonObjectData->_screenPosition); - } - - result = commonObjectData->_screenPosition.x > -64 && - commonObjectData->_screenPosition.x < _vm->getDisplayWidth() + 64 && - commonObjectData->_screenPosition.y > -64 && - commonObjectData->_screenPosition.y < _vm->_scene->getHeight() + 64; - - return result; -} - -uint16 Actor::hitTest(const Point &testPoint, bool skipProtagonist) { - // We can only interact with objects or actors that are inside the - // scene area. While this is usually the entire upper part of the - // screen, it could also be an inset. Note that other kinds of hit - // areas may be outside the inset, and that those are still perfectly - // fine to interact with. For example, the door entrance at the glass - // makers's house in ITE's ferret village. - - if (!_vm->_scene->getSceneClip().contains(testPoint)) - return ID_NOTHING; - - CommonObjectOrderList::iterator drawOrderIterator; - CommonObjectDataPointer drawObject; - int frameNumber; - SpriteList *spriteList; - - createDrawOrderList(); - - for (drawOrderIterator = _drawOrderList.begin(); drawOrderIterator != _drawOrderList.end(); ++drawOrderIterator) { - drawObject = drawOrderIterator.operator*(); - if (skipProtagonist && (drawObject == _protagonist)) { - continue; - } - if (!getSpriteParams(drawObject, frameNumber, spriteList)) { - continue; - } - if (_vm->_sprite->hitTest(*spriteList, frameNumber, drawObject->_screenPosition, drawObject->_screenScale, testPoint)) { - return drawObject->_id; - } - } - return ID_NOTHING; -} - -void Actor::createDrawOrderList() { - int i; - ActorData *actor; - ObjectData *obj; - CommonObjectOrderList::CompareFunction compareFunction; - - if (_vm->_scene->getFlags() & kSceneFlagISO) { - compareFunction = &tileCommonObjectCompare; - } else { - compareFunction = &commonObjectCompare; - } - - _drawOrderList.clear(); - for (i = 0; i < _actorsCount; i++) { - actor = _actors[i]; - - if (!actor->_inScene) - continue; - - if (calcScreenPosition(actor)) { - _drawOrderList.pushBack(actor, compareFunction); - } - } - - for (i = 0; i < _objsCount; i++) { - obj = _objs[i]; - if (obj->_disabled) - continue; - - if (obj->_sceneNumber != _vm->_scene->currentSceneNumber()) - continue; - - if (calcScreenPosition(obj)) { - _drawOrderList.pushBack(obj, compareFunction); - } - } -} - -bool Actor::getSpriteParams(CommonObjectData *commonObjectData, int &frameNumber, SpriteList *&spriteList) { - if (_vm->_scene->currentSceneResourceId() == RID_ITE_OVERMAP_SCENE) { - if (!(commonObjectData->_flags & kProtagonist)){ -// warning("not protagonist"); - return false; - } - frameNumber = 8; - spriteList = &_vm->_sprite->_mainSprites; - } else if (validActorId(commonObjectData->_id)) { - ActorData *actor = (ActorData *)commonObjectData; - spriteList = &(actor->_spriteList); - frameNumber = actor->_frameNumber; - if (spriteList->infoList == NULL) - loadActorSpriteList(actor); - - } else if (validObjId(commonObjectData->_id)) { - spriteList = &_vm->_sprite->_mainSprites; - frameNumber = commonObjectData->_spriteListResourceId; - } - - if ((frameNumber < 0) || (spriteList->spriteCount <= frameNumber)) { - debug(1, "Actor::getSpriteParams frameNumber invalid for %s id 0x%X (%d)", - validObjId(commonObjectData->_id) ? "object" : "actor", - commonObjectData->_id, frameNumber); - return false; - } - return true; -} - -void Actor::drawActors() { - if (_vm->_anim->hasCutaway()) { - drawSpeech(); - return; - } - - if (_vm->_scene->currentSceneNumber() <= 0) { - return; - } - - if (_vm->_scene->_entryList.entryListCount == 0) { - return; - } - - CommonObjectOrderList::iterator drawOrderIterator; - CommonObjectDataPointer drawObject; - int frameNumber; - SpriteList *spriteList; - - Surface *backBuffer; - - backBuffer = _vm->_gfx->getBackBuffer(); - - createDrawOrderList(); - - for (drawOrderIterator = _drawOrderList.begin(); drawOrderIterator != _drawOrderList.end(); ++drawOrderIterator) { - drawObject = drawOrderIterator.operator*(); - - if (!getSpriteParams(drawObject, frameNumber, spriteList)) { - continue; - } - - if (_vm->_scene->getFlags() & kSceneFlagISO) { - _vm->_isoMap->drawSprite(backBuffer, *spriteList, frameNumber, drawObject->_location, drawObject->_screenPosition, drawObject->_screenScale); - } else { - _vm->_sprite->drawOccluded(backBuffer, _vm->_scene->getSceneClip(),*spriteList, frameNumber, drawObject->_screenPosition, drawObject->_screenScale, drawObject->_screenDepth); - } - } - - drawSpeech(); -} - -void Actor::drawSpeech(void) { - if (!isSpeaking() || !_activeSpeech.playing || _vm->_script->_skipSpeeches - || (!_vm->_subtitlesEnabled && (_vm->getFeatures() & GF_CD_FX))) - return; - - int i; - Point textPoint; - ActorData *actor; - int width, height; - char oneChar[2]; - oneChar[1] = 0; - const char *outputString; - Surface *backBuffer; - - backBuffer = _vm->_gfx->getBackBuffer(); - - if (_activeSpeech.speechFlags & kSpeakSlow) { - outputString = oneChar; - oneChar[0] = _activeSpeech.strings[0][_activeSpeech.slowModeCharIndex]; - } else { - outputString = _activeSpeech.strings[0]; - } - - if (_activeSpeech.actorsCount > 1) { - height = _vm->_font->getHeight(kKnownFontScript); - width = _vm->_font->getStringWidth(kKnownFontScript, _activeSpeech.strings[0], 0, kFontNormal); - - for (i = 0; i < _activeSpeech.actorsCount; i++) { - actor = getActor(_activeSpeech.actorIds[i]); - calcScreenPosition(actor); - - textPoint.x = clamp(10, actor->_screenPosition.x - width / 2, _vm->getDisplayWidth() - 10 - width); - textPoint.y = clamp(10, actor->_screenPosition.y - 58, _vm->_scene->getHeight() - 10 - height); - - _vm->_font->textDraw(kKnownFontScript, backBuffer, _activeSpeech.strings[0], textPoint, - _activeSpeech.speechColor[i], _activeSpeech.outlineColor[i], _activeSpeech.getFontFlags(i)); - } - } else { - _vm->_font->textDrawRect(kKnownFontScript, backBuffer, _activeSpeech.strings[0], _activeSpeech.drawRect, _activeSpeech.speechColor[0], - _activeSpeech.outlineColor[0], _activeSpeech.getFontFlags(0)); - } -} - -bool Actor::followProtagonist(ActorData *actor) { - Location protagonistLocation; - Location newLocation; - Location delta; - int protagonistBGMaskType; - Point prefer1; - Point prefer2; - Point prefer3; - int16 prefU; - int16 prefV; - int16 newU; - int16 newV; - - assert(_protagonist); - - actor->_flags &= ~(kFaster | kFastest); - protagonistLocation = _protagonist->_location; - calcScreenPosition(_protagonist); - - if (_vm->_scene->getFlags() & kSceneFlagISO) { - prefU = 60; - prefV = 60; - - - actor->_location.delta(protagonistLocation, delta); - - if (actor->_id == actorIndexToId(2)) { - prefU = prefV = 48; - } - - if ((delta.u() > prefU) || (delta.u() < -prefU) || (delta.v() > prefV) || (delta.v() < -prefV)) { - - if ((delta.u() > prefU * 2) || (delta.u() < -prefU * 2) || (delta.v() > prefV * 2) || (delta.v() < -prefV * 2)) { - actor->_flags |= kFaster; - - if ((delta.u() > prefU * 3) || (delta.u() < -prefU*3) || (delta.v() > prefV * 3) || (delta.v() < -prefV * 3)) { - actor->_flags |= kFastest; - } - } - - prefU /= 2; - prefV /= 2; - - newU = clamp(-prefU, delta.u(), prefU) + protagonistLocation.u(); - newV = clamp(-prefV, delta.v(), prefV) + protagonistLocation.v(); - - newLocation.u() = newU + _vm->_rnd.getRandomNumber(prefU - 1) - prefU / 2; - newLocation.v() = newV + _vm->_rnd.getRandomNumber(prefV - 1) - prefV / 2; - newLocation.z = 0; - - return actorWalkTo(actor->_id, newLocation); - } - - } else { - prefer1.x = (100 * _protagonist->_screenScale) >> 8; - prefer1.y = (50 * _protagonist->_screenScale) >> 8; - - if (_protagonist->_currentAction == kActionWalkDir) { - prefer1.x /= 2; - } - - if (prefer1.x < 8) { - prefer1.x = 8; - } - - if (prefer1.y < 8) { - prefer1.y = 8; - } - - prefer2.x = prefer1.x * 2; - prefer2.y = prefer1.y * 2; - prefer3.x = prefer1.x + prefer1.x / 2; - prefer3.y = prefer1.y + prefer1.y / 2; - - actor->_location.delta(protagonistLocation, delta); - - protagonistBGMaskType = 0; - if (_vm->_scene->isBGMaskPresent() && _vm->_scene->validBGMaskPoint(_protagonist->_screenPosition)) { - protagonistBGMaskType = _vm->_scene->getBGMaskType(_protagonist->_screenPosition); - } - - if ((_vm->_rnd.getRandomNumber(7) & 0x7) == 0) // 1/8th chance - actor->_actorFlags &= ~kActorNoFollow; - - if (actor->_actorFlags & kActorNoFollow) { - return false; - } - - if ((delta.x > prefer2.x) || (delta.x < -prefer2.x) || - (delta.y > prefer2.y) || (delta.y < -prefer2.y) || - ((_protagonist->_currentAction == kActionWait) && - (delta.x * 2 < prefer1.x) && (delta.x * 2 > -prefer1.x) && - (delta.y < prefer1.y) && (delta.y > -prefer1.y))) { - - if (ABS(delta.x) > ABS(delta.y)) { - - delta.x = (delta.x > 0) ? prefer3.x : -prefer3.x; - - newLocation.x = delta.x + protagonistLocation.x; - newLocation.y = clamp(-prefer2.y, delta.y, prefer2.y) + protagonistLocation.y; - } else { - delta.y = (delta.y > 0) ? prefer3.y : -prefer3.y; - - newLocation.x = clamp(-prefer2.x, delta.x, prefer2.x) + protagonistLocation.x; - newLocation.y = delta.y + protagonistLocation.y; - } - newLocation.z = 0; - - if (protagonistBGMaskType != 3) { - newLocation.x += _vm->_rnd.getRandomNumber(prefer1.x - 1) - prefer1.x / 2; - newLocation.y += _vm->_rnd.getRandomNumber(prefer1.y - 1) - prefer1.y / 2; - } - - newLocation.x = clamp(-31*4, newLocation.x, (_vm->getDisplayWidth() + 31) * 4); //fixme - - return actorWalkTo(actor->_id, newLocation); - } - } - return false; -} - -bool Actor::actorEndWalk(uint16 actorId, bool recurse) { - bool walkMore = false; - ActorData *actor; - const HitZone *hitZone; - int hitZoneIndex; - Point testPoint; - - actor = getActor(actorId); - actor->_actorFlags &= ~kActorBackwards; - - if (actor->_location.distance(actor->_finalTarget) > 8 && (actor->_flags & kProtagonist) && recurse && !(actor->_actorFlags & kActorNoCollide)) { - actor->_actorFlags |= kActorNoCollide; - return actorWalkTo(actorId, actor->_finalTarget); - } - - actor->_currentAction = kActionWait; - if (actor->_actorFlags & kActorFinalFace) { - actor->_facingDirection = actor->_actionDirection = (actor->_actorFlags >> 6) & 0x07; //? - } - - actor->_actorFlags &= ~(kActorNoCollide | kActorCollided | kActorFinalFace | kActorFacingMask); - actor->_flags &= ~(kFaster | kFastest); - - if (actor == _protagonist) { - _vm->_script->wakeUpActorThread(kWaitTypeWalk, actor); - if (_vm->_script->_pendingVerb == _vm->_script->getVerbType(kVerbWalkTo)) { - if (_vm->getGameType() == GType_ITE) - actor->_location.toScreenPointUV(testPoint); // it's wrong calculation, but it is used in ITE - else - actor->_location.toScreenPointXY(testPoint); - - hitZoneIndex = _vm->_scene->_actionMap->hitTest(testPoint); - if (hitZoneIndex != -1) { - hitZone = _vm->_scene->_actionMap->getHitZone(hitZoneIndex); - stepZoneAction(actor, hitZone, false, true); - } else { - _vm->_script->setNoPendingVerb(); - } - } else if (_vm->_script->_pendingVerb != _vm->_script->getVerbType(kVerbNone)) { - _vm->_script->doVerb(); - } - } else { - if (recurse && (actor->_flags & kFollower)) - walkMore = followProtagonist(actor); - - _vm->_script->wakeUpActorThread(kWaitTypeWalk, actor); - } - return walkMore; -} - -bool Actor::actorWalkTo(uint16 actorId, const Location &toLocation) { - ActorData *actor; - ActorData *anotherActor; - int i; - - Rect testBox; - Rect testBox2; - Point anotherActorScreenPosition; - Point collision; - Point pointFrom, pointTo, pointBest, pointAdd; - Point delta, bestDelta; - Point tempPoint; - bool extraStartNode; - bool extraEndNode; - - actor = getActor(actorId); - - if (actor == _protagonist) { - _vm->_scene->setDoorState(2, 0xff); - _vm->_scene->setDoorState(3, 0); - } else { - _vm->_scene->setDoorState(2, 0); - _vm->_scene->setDoorState(3, 0xff); - } - - if (_vm->_scene->getFlags() & kSceneFlagISO) { - - if ((_vm->getGameType() == GType_ITE) && (actor->_index == ACTOR_DRAGON_INDEX)) { - return false; - } - - actor->_finalTarget = toLocation; - actor->_walkStepsCount = 0; - _vm->_isoMap->findTilePath(actor, actor->_location, toLocation); - - - if ((actor->_walkStepsCount == 0) && (actor->_flags & kProtagonist)) { - actor->_actorFlags |= kActorNoCollide; - _vm->_isoMap->findTilePath(actor, actor->_location, toLocation); - } - - actor->_walkStepIndex = 0; - if (_vm->_isoMap->nextTileTarget(actor)) { - actor->_currentAction = kActionWalkToPoint; - actor->_walkFrameSequence = getFrameType(kFrameWalk); - } else { - actorEndWalk(actorId, false); - return false; - } - } else { - - actor->_location.toScreenPointXY(pointFrom); - pointFrom.x &= ~1; - - extraStartNode = _vm->_scene->offscreenPath(pointFrom); - - toLocation.toScreenPointXY(pointTo); - pointTo.x &= ~1; - - extraEndNode = _vm->_scene->offscreenPath(pointTo); - - if (_vm->_scene->isBGMaskPresent()) { - - if ((((actor->_currentAction >= kActionWalkToPoint) && - (actor->_currentAction <= kActionWalkDir)) || (actor == _protagonist)) && - !_vm->_scene->canWalk(pointFrom)) { - for (i = 1; i < 8; i++) { - pointAdd = pointFrom; - pointAdd.y += i; - if (_vm->_scene->canWalk(pointAdd)) { - pointFrom = pointAdd; - break; - } - pointAdd = pointFrom; - pointAdd.y -= i; - if (_vm->_scene->canWalk(pointAdd)) { - pointFrom = pointAdd; - break; - } - pointAdd = pointFrom; - pointAdd.x += i; - if (_vm->_scene->canWalk(pointAdd)) { - pointFrom = pointAdd; - break; - } - pointAdd = pointFrom; - pointAdd.x -= i; - if (_vm->_scene->canWalk(pointAdd)) { - pointFrom = pointAdd; - break; - } - } - } - - _barrierCount = 0; - if (!(actor->_actorFlags & kActorNoCollide)) { - collision.x = ACTOR_COLLISION_WIDTH * actor->_screenScale / (256 * 2); - collision.y = ACTOR_COLLISION_HEIGHT * actor->_screenScale / (256 * 2); - - - for (i = 0; (i < _actorsCount) && (_barrierCount < ACTOR_BARRIERS_MAX); i++) { - anotherActor = _actors[i]; - if (!anotherActor->_inScene) - continue; - if (anotherActor == actor) - continue; - - anotherActorScreenPosition = anotherActor->_screenPosition; - testBox.left = (anotherActorScreenPosition.x - collision.x) & ~1; - testBox.right = (anotherActorScreenPosition.x + collision.x) & ~1 + 1; - testBox.top = anotherActorScreenPosition.y - collision.y; - testBox.bottom = anotherActorScreenPosition.y + collision.y + 1; - testBox2 = testBox; - testBox2.right += 2; - testBox2.left -= 2; - testBox2.top -= 1; - testBox2.bottom += 1; - - if (testBox2.contains(pointFrom)) { - if (pointFrom.x > anotherActorScreenPosition.x + 4) { - testBox.right = pointFrom.x - 1; - } else if (pointFrom.x < anotherActorScreenPosition.x - 4) { - testBox.left = pointFrom.x + 2; - } else if (pointFrom.y > anotherActorScreenPosition.y) { - testBox.bottom = pointFrom.y; - } else { - testBox.top = pointFrom.y + 1 ; - } - } - - if ((testBox.width() > 0) && (testBox.height() > 0)) { - _barrierList[_barrierCount++] = testBox; - } - } - } - - - pointBest = pointTo; - actor->_walkStepsCount = 0; - findActorPath(actor, pointFrom, pointTo); - - if (actor->_walkStepsCount == 0) { - error("actor->_walkStepsCount == 0"); - } - - if (extraStartNode) { - actor->_walkStepIndex = 0; - } else { - actor->_walkStepIndex = 1; - } - - if (extraEndNode) { - toLocation.toScreenPointXY(tempPoint); - actor->_walkStepsCount--; - actor->addWalkStepPoint(tempPoint); - } - - - pointBest = actor->_walkStepsPoints[actor->_walkStepsCount - 1]; - - pointBest.x &= ~1; - delta.x = ABS(pointFrom.x - pointTo.x); - delta.y = ABS(pointFrom.y - pointTo.y); - - bestDelta.x = ABS(pointBest.x - pointTo.x); - bestDelta.y = ABS(pointBest.y - pointTo.y); - - if ((delta.x + delta.y <= bestDelta.x + bestDelta.y) && (actor->_flags & kFollower)) { - actor->_actorFlags |= kActorNoFollow; - } - - if (pointBest == pointFrom) { - actor->_walkStepsCount = 0; - } - } else { - actor->_walkStepsCount = 0; - actor->addWalkStepPoint(pointTo); - actor->_walkStepIndex = 0; - } - - actor->_partialTarget = actor->_location; - actor->_finalTarget = toLocation; - if (actor->_walkStepsCount == 0) { - actorEndWalk(actorId, false); - return false; - } else { - if (actor->_flags & kProtagonist) { - _actors[1]->_actorFlags &= ~kActorNoFollow; // TODO: mark all actors with kFollower flag, not only 1 and 2 - _actors[2]->_actorFlags &= ~kActorNoFollow; - } - actor->_currentAction = (actor->_walkStepsCount >= ACTOR_MAX_STEPS_COUNT) ? kActionWalkToLink : kActionWalkToPoint; - actor->_walkFrameSequence = getFrameType(kFrameWalk); - } - } - return true; -} - -void Actor::actorSpeech(uint16 actorId, const char **strings, int stringsCount, int sampleResourceId, int speechFlags) { - ActorData *actor; - int i; - int16 dist; - - actor = getActor(actorId); - calcScreenPosition(actor); - for (i = 0; i < stringsCount; i++) { - _activeSpeech.strings[i] = strings[i]; - } - - _activeSpeech.stringsCount = stringsCount; - _activeSpeech.speechFlags = speechFlags; - _activeSpeech.actorsCount = 1; - _activeSpeech.actorIds[0] = actorId; - _activeSpeech.speechColor[0] = actor->_speechColor; - _activeSpeech.outlineColor[0] = (_vm->getGameType() == GType_ITE ? kITEColorBlack : kIHNMColorBlack); - _activeSpeech.sampleResourceId = sampleResourceId; - _activeSpeech.playing = false; - _activeSpeech.slowModeCharIndex = 0; - - dist = MIN(actor->_screenPosition.x - 10, _vm->getDisplayWidth() - 10 - actor->_screenPosition.x); - dist = clamp(60, dist, 150); - - _activeSpeech.speechBox.left = actor->_screenPosition.x - dist; - _activeSpeech.speechBox.right = actor->_screenPosition.x + dist; - - if (_activeSpeech.speechBox.left < 10) { - _activeSpeech.speechBox.right += 10 - _activeSpeech.speechBox.left; - _activeSpeech.speechBox.left = 10; - } - if (_activeSpeech.speechBox.right > _vm->getDisplayWidth() - 10) { - _activeSpeech.speechBox.left -= _activeSpeech.speechBox.right - _vm->getDisplayWidth() - 10; - _activeSpeech.speechBox.right = _vm->getDisplayWidth() - 10; - } -} - -void Actor::nonActorSpeech(const Common::Rect &box, const char **strings, int stringsCount, int sampleResourceId, int speechFlags) { - int i; - - _vm->_script->wakeUpThreads(kWaitTypeSpeech); - - for (i = 0; i < stringsCount; i++) { - _activeSpeech.strings[i] = strings[i]; - } - _activeSpeech.stringsCount = stringsCount; - _activeSpeech.speechFlags = speechFlags; - _activeSpeech.actorsCount = 1; - _activeSpeech.actorIds[0] = 0; - if (!(_vm->getFeatures() & GF_CD_FX)) - _activeSpeech.sampleResourceId = -1; - else - _activeSpeech.sampleResourceId = sampleResourceId; - _activeSpeech.playing = false; - _activeSpeech.slowModeCharIndex = 0; - _activeSpeech.speechBox = box; -} - -void Actor::simulSpeech(const char *string, uint16 *actorIds, int actorIdsCount, int speechFlags, int sampleResourceId) { - int i; - - for (i = 0; i < actorIdsCount; i++) { - ActorData *actor; - - actor = getActor(actorIds[i]); - _activeSpeech.actorIds[i] = actorIds[i]; - _activeSpeech.speechColor[i] = actor->_speechColor; - _activeSpeech.outlineColor[i] = 0; // disable outline - } - _activeSpeech.actorsCount = actorIdsCount; - _activeSpeech.strings[0] = string; - _activeSpeech.stringsCount = 1; - _activeSpeech.speechFlags = speechFlags; - _activeSpeech.sampleResourceId = sampleResourceId; - _activeSpeech.playing = false; - _activeSpeech.slowModeCharIndex = 0; - - // caller should call thread->wait(kWaitTypeSpeech) by itself -} - -void Actor::abortAllSpeeches() { - abortSpeech(); - - if (_vm->_script->_abortEnabled) - _vm->_script->_skipSpeeches = true; - - for (int i = 0; i < 10; i++) - _vm->_script->executeThreads(0); -} - -void Actor::abortSpeech() { - _vm->_sound->stopVoice(); - _activeSpeech.playingTime = 0; -} - -void Actor::moveDragon(ActorData *actor) { - int16 dir0, dir1, dir2, dir3; - int16 moveType; - Event event; - const DragonMove *dragonMove; - - if ((actor->_actionCycle < 0) || - ((actor->_actionCycle == 0) && (actor->_dragonMoveType >= ACTOR_DRAGON_TURN_MOVES))) { - - moveType = kDragonMoveInvalid; - if (actor->_location.distance(_protagonist->_location) < 24) { - if (_dragonHunt && (_protagonist->_currentAction != kActionFall)) { - event.type = kEvTOneshot; - event.code = kScriptEvent; - event.op = kEventExecNonBlocking; - event.time = 0; - event.param = _vm->_scene->getScriptModuleNumber(); // module number - event.param2 = ACTOR_EXP_KNOCK_RIF; // script entry point number - event.param3 = -1; // Action - event.param4 = -1; // Object - event.param5 = -1; // With Object - event.param6 = -1; // Actor - - _vm->_events->queue(&event); - _dragonHunt = false; - } - } else { - _dragonHunt = true; - } - - if (actor->_walkStepIndex + 2 > actor->_walkStepsCount) { - - _vm->_isoMap->findDragonTilePath(actor, actor->_location, _protagonist->_location, actor->_actionDirection); - - if (actor->_walkStepsCount == 0) { - _vm->_isoMap->findDragonTilePath(actor, actor->_location, _protagonist->_location, 0); - } - - if (actor->_walkStepsCount < 2) { - return; - } - - actor->_partialTarget = actor->_location; - actor->_finalTarget = _protagonist->_location; - actor->_walkStepIndex = 0; - } - - dir0 = actor->_actionDirection; - dir1 = actor->_tileDirections[actor->_walkStepIndex++]; - dir2 = actor->_tileDirections[actor->_walkStepIndex]; - dir3 = actor->_tileDirections[actor->_walkStepIndex + 1]; - - if (dir0 != dir1){ - actor->_actionDirection = dir0 = dir1; - } - - actor->_location = actor->_partialTarget; - - if ((dir1 != dir2) && (dir1 == dir3)) { - switch (dir1) { - case kDirUpLeft: - actor->_partialTarget.v() += 16; - moveType = kDragonMoveUpLeft; - break; - case kDirDownLeft: - actor->_partialTarget.u() -= 16; - moveType = kDragonMoveDownLeft; - break; - case kDirDownRight: - actor->_partialTarget.v() -= 16; - moveType = kDragonMoveDownRight; - break; - case kDirUpRight: - actor->_partialTarget.u() += 16; - moveType = kDragonMoveUpRight; - break; - } - - switch (dir2) { - case kDirUpLeft: - actor->_partialTarget.v() += 16; - break; - case kDirDownLeft: - actor->_partialTarget.u() -= 16; - break; - case kDirDownRight: - actor->_partialTarget.v() -= 16; - break; - case kDirUpRight: - actor->_partialTarget.u() += 16; - break; - } - - actor->_walkStepIndex++; - } else { - switch (dir1) { - case kDirUpLeft: - actor->_partialTarget.v() += 16; - switch (dir2) { - case kDirDownLeft: - moveType = kDragonMoveUpLeft_Left; - actor->_partialTarget.u() -= 16; - break; - case kDirUpLeft: - moveType = kDragonMoveUpLeft; - break; - case kDirUpRight: - actor->_partialTarget.u() += 16; - moveType = kDragonMoveUpLeft_Right; - break; - default: - actor->_actionDirection = dir1; - actor->_walkStepsCount = 0; - break; - } - break; - case kDirDownLeft: - actor->_partialTarget.u() -= 16; - switch (dir2) { - case kDirDownRight: - moveType = kDragonMoveDownLeft_Left; - actor->_partialTarget.v() -= 16; - break; - case kDirDownLeft: - moveType = kDragonMoveDownLeft; - break; - case kDirUpLeft: - moveType = kDragonMoveDownLeft_Right; - actor->_partialTarget.v() += 16; - break; - default: - actor->_actionDirection = dir1; - actor->_walkStepsCount = 0; - break; - } - break; - case kDirDownRight: - actor->_partialTarget.v() -= 16; - switch (dir2) { - case kDirUpRight: - moveType = kDragonMoveDownRight_Left; - actor->_partialTarget.u() += 16; - break; - case kDirDownRight: - moveType = kDragonMoveDownRight; - break; - case kDirDownLeft: - moveType = kDragonMoveDownRight_Right; - actor->_partialTarget.u() -= 16; - break; - default: - actor->_actionDirection = dir1; - actor->_walkStepsCount = 0; - break; - } - break; - case kDirUpRight: - actor->_partialTarget.u() += 16; - switch (dir2) { - case kDirUpLeft: - moveType = kDragonMoveUpRight_Left; - actor->_partialTarget.v() += 16; - break; - case kDirUpRight: - moveType = kDragonMoveUpRight; - break; - case kDirDownRight: - moveType = kDragonMoveUpRight_Right; - actor->_partialTarget.v() -= 16; - break; - default: - actor->_actionDirection = dir1; - actor->_walkStepsCount = 0; - break; - } - break; - - default: - actor->_actionDirection = dir1; - actor->_walkStepsCount = 0; - break; - } - } - - actor->_dragonMoveType = moveType; - - if (moveType >= ACTOR_DRAGON_TURN_MOVES) { - actor->_dragonStepCycle = 0; - actor->_actionCycle = 4; - actor->_walkStepIndex++; - } else { - actor->_actionCycle = 4; - } - } - - actor->_actionCycle--; - - if ((actor->_walkStepsCount < 1) || (actor->_actionCycle < 0)) { - return; - } - - if (actor->_dragonMoveType < ACTOR_DRAGON_TURN_MOVES) { - - actor->_dragonStepCycle++; - if (actor->_dragonStepCycle >= 7) { - actor->_dragonStepCycle = 0; - } - - actor->_dragonBaseFrame = actor->_dragonMoveType * 7; - - if (actor->_location.u() > actor->_partialTarget.u() + 3) { - actor->_location.u() -= 4; - } else if (actor->_location.u() < actor->_partialTarget.u() - 3) { - actor->_location.u() += 4; - } else { - actor->_location.u() = actor->_partialTarget.u(); - } - - if (actor->_location.v() > actor->_partialTarget.v() + 3) { - actor->_location.v() -= 4; - } else if (actor->_location.v() < actor->_partialTarget.v() - 3) { - actor->_location.v() += 4; - } else { - actor->_location.v() = actor->_partialTarget.v(); - } - } else { - dragonMove = &dragonMoveTable[actor->_dragonMoveType]; - actor->_dragonBaseFrame = dragonMove->baseFrame; - - - actor->_location.u() = actor->_partialTarget.u() - dragonMove->offset[actor->_actionCycle][0]; - actor->_location.v() = actor->_partialTarget.v() - dragonMove->offset[actor->_actionCycle][1]; - - actor->_dragonStepCycle++; - if (actor->_dragonStepCycle >= 3) { - actor->_dragonStepCycle = 3; - } - } - - actor->_frameNumber = actor->_dragonBaseFrame + actor->_dragonStepCycle; -} - -void Actor::findActorPath(ActorData *actor, const Point &fromPoint, const Point &toPoint) { - Point iteratorPoint; - Point bestPoint; - int maskType; - int i; - Rect intersect; - -#ifdef ACTOR_DEBUG - _debugPointsCount = 0; -#endif - - actor->_walkStepsCount = 0; - if (fromPoint == toPoint) { - actor->addWalkStepPoint(toPoint); - return; - } - - for (iteratorPoint.y = 0; iteratorPoint.y < _yCellCount; iteratorPoint.y++) { - for (iteratorPoint.x = 0; iteratorPoint.x < _xCellCount; iteratorPoint.x++) { - if (_vm->_scene->validBGMaskPoint(iteratorPoint)) { - maskType = _vm->_scene->getBGMaskType(iteratorPoint); - setPathCell(iteratorPoint, _vm->_scene->getDoorState(maskType) ? kPathCellBarrier : kPathCellEmpty); - } else { - setPathCell(iteratorPoint, kPathCellBarrier); - } - } - } - - for (i = 0; i < _barrierCount; i++) { - intersect.left = MAX(_pathRect.left, _barrierList[i].left); - intersect.top = MAX(_pathRect.top, _barrierList[i].top); - intersect.right = MIN(_pathRect.right, _barrierList[i].right); - intersect.bottom = MIN(_pathRect.bottom, _barrierList[i].bottom); - - for (iteratorPoint.y = intersect.top; iteratorPoint.y < intersect.bottom; iteratorPoint.y++) { - for (iteratorPoint.x = intersect.left; iteratorPoint.x < intersect.right; iteratorPoint.x++) { - setPathCell(iteratorPoint, kPathCellBarrier); - } - } - } - -#ifdef ACTOR_DEBUG - for (iteratorPoint.y = 0; iteratorPoint.y < _yCellCount; iteratorPoint.y++) { - for (iteratorPoint.x = 0; iteratorPoint.x < _xCellCount; iteratorPoint.x++) { - if (getPathCell(iteratorPoint) == kPathCellBarrier) { - addDebugPoint(iteratorPoint, 24); - } - } - } -#endif - - if (scanPathLine(fromPoint, toPoint)) { - actor->addWalkStepPoint(fromPoint); - actor->addWalkStepPoint(toPoint); - return; - } - - i = fillPathArray(fromPoint, toPoint, bestPoint); - - if (fromPoint == bestPoint) { - actor->addWalkStepPoint(bestPoint); - return; - } - - if (i == 0) { - error("fillPathArray returns zero"); - } - - setActorPath(actor, fromPoint, bestPoint); -} - -bool Actor::scanPathLine(const Point &point1, const Point &point2) { - Point point; - Point delta; - bool interchange = false; - Point fDelta; - int errterm; - int s1; - int s2; - int i; - - point = point1; - delta.x = ABS(point1.x - point2.x); - delta.y = ABS(point1.y - point2.y); - s1 = integerCompare(point2.x, point1.x); - s2 = integerCompare(point2.y, point1.y); - - if (delta.y > delta.x) { - SWAP(delta.y, delta.x); - interchange = true; - } - - fDelta.x = delta.x * 2; - fDelta.y = delta.y * 2; - - errterm = fDelta.y - delta.x; - - for (i = 0; i < delta.x; i++) { - while (errterm >= 0) { - if (interchange) { - point.x += s1; - } else { - point.y += s2; - } - errterm -= fDelta.x; - } - - if (interchange) - point.y += s2; - else - point.x += s1; - - errterm += fDelta.y; - - if (!validPathCellPoint(point)) { - return false; - } - if (getPathCell(point) == kPathCellBarrier) { - return false; - } - } - return true; -} - -int Actor::fillPathArray(const Point &fromPoint, const Point &toPoint, Point &bestPoint) { - int bestRating; - int currentRating; - int i; - Point bestPath; - int pointCounter; - int startDirection; - PathDirectionData *pathDirection; - PathDirectionData *newPathDirection; - const PathDirectionData *samplePathDirection; - Point nextPoint; - int directionCount; - - _pathDirectionListCount = 0; - pointCounter = 0; - bestRating = quickDistance(fromPoint, toPoint); - bestPath = fromPoint; - - for (startDirection = 0; startDirection < 4; startDirection++) { - newPathDirection = addPathDirectionListData(); - newPathDirection->x = fromPoint.x; - newPathDirection->y = fromPoint.y; - newPathDirection->direction = startDirection; - } - - if (validPathCellPoint(fromPoint)) { - setPathCell(fromPoint, kDirUp); - -#ifdef ACTOR_DEBUG - addDebugPoint(fromPoint, 24+36); -#endif - } - - i = 0; - - do { - pathDirection = &_pathDirectionList[i]; - for (directionCount = 0; directionCount < 3; directionCount++) { - samplePathDirection = &pathDirectionLUT[pathDirection->direction][directionCount]; - nextPoint.x = samplePathDirection->x + pathDirection->x; - nextPoint.y = samplePathDirection->y + pathDirection->y; - - if (!validPathCellPoint(nextPoint)) { - continue; - } - - if (getPathCell(nextPoint) != kPathCellEmpty) { - continue; - } - - setPathCell(nextPoint, samplePathDirection->direction); - -#ifdef ACTOR_DEBUG - addDebugPoint(nextPoint, samplePathDirection->direction + 96); -#endif - newPathDirection = addPathDirectionListData(); - newPathDirection->x = nextPoint.x; - newPathDirection->y = nextPoint.y; - newPathDirection->direction = samplePathDirection->direction; - ++pointCounter; - if (nextPoint == toPoint) { - bestPoint = toPoint; - return pointCounter; - } - currentRating = quickDistance(nextPoint, toPoint); - if (currentRating < bestRating) { - bestRating = currentRating; - bestPath = nextPoint; - } - pathDirection = &_pathDirectionList[i]; - } - ++i; - } while (i < _pathDirectionListCount); - - bestPoint = bestPath; - return pointCounter; -} - -void Actor::setActorPath(ActorData *actor, const Point &fromPoint, const Point &toPoint) { - Point nextPoint; - int8 direction; - int i; - - _pathListIndex = -1; - addPathListPoint(toPoint); - nextPoint = toPoint; - - while (!(nextPoint == fromPoint)) { - direction = getPathCell(nextPoint); - if ((direction < 0) || (direction >= 8)) { - error("Actor::setActorPath error direction 0x%X", direction); - } - nextPoint.x -= pathDirectionLUT2[direction][0]; - nextPoint.y -= pathDirectionLUT2[direction][1]; - addPathListPoint(nextPoint); - -#ifdef ACTOR_DEBUG - addDebugPoint(nextPoint, 0x8a); -#endif - } - - pathToNode(); - removeNodes(); - nodeToPath(); - removePathPoints(); - - for (i = 0; i <= _pathNodeListIndex; i++) { - actor->addWalkStepPoint(_pathNodeList[i].point); - } -} - -void Actor::pathToNode() { - Point point1, point2, delta; - int direction; - int i; - Point *point; - - point= &_pathList[_pathListIndex]; - direction = 0; - - _pathNodeListIndex = -1; - addPathNodeListPoint(*point); - - for (i = _pathListIndex; i > 0; i--) { - point1 = *point; - --point; - point2 = *point; - if (direction == 0) { - delta.x = integerCompare(point2.x, point1.x); - delta.y = integerCompare(point2.y, point1.y); - direction++; - } - if ((point1.x + delta.x != point2.x) || (point1.y + delta.y != point2.y)) { - addPathNodeListPoint(point1); - direction--; - i++; - point++; - } - } - addPathNodeListPoint(*_pathList); -} - -int pathLine(Point *pointList, const Point &point1, const Point &point2) { - Point point; - Point delta; - Point tempPoint; - int s1; - int s2; - bool interchange = false; - int errterm; - int i; - - delta.x = abs(point2.x - point1.x); - delta.y = abs(point2.y - point1.y); - point = point1; - s1 = integerCompare(point2.x, point1.x); - s2 = integerCompare(point2.y, point1.y); - - if (delta.y > delta.x) { - SWAP(delta.y, delta.x); - interchange = true; - } - - tempPoint.x = delta.x * 2; - tempPoint.y = delta.y * 2; - - errterm = tempPoint.y - delta.x; - - for (i = 0; i < delta.x; i++) { - while (errterm >= 0) { - if (interchange) { - point.x += s1; - } else { - point.y += s2; - } - errterm -= tempPoint.x; - } - if (interchange) { - point.y += s2; - } else { - point.x += s1; - } - errterm += tempPoint.y; - - pointList[i] = point; - } - return delta.x; -} - -void Actor::nodeToPath() { - int i; - Point point1, point2; - PathNode *node; - Point *point; - - for (i = 0, point = _pathList; i < _pathListAlloced; i++, point++) { - point->x = point->y = PATH_NODE_EMPTY; - } - - _pathListIndex = 1; - _pathList[0] = _pathNodeList[0].point; - _pathNodeList[0].link = 0; - for (i = 0, node = _pathNodeList; i < _pathNodeListIndex; i++) { - point1 = node->point; - node++; - point2 = node->point; - _pathListIndex += pathLine(&_pathList[_pathListIndex], point1, point2); - node->link = _pathListIndex - 1; - } - _pathListIndex--; - _pathNodeList[_pathNodeListIndex].link = _pathListIndex; - -} - -void Actor::removeNodes() { - int i, j, k; - PathNode *iNode, *jNode, *kNode, *fNode; - fNode = &_pathNodeList[_pathNodeListIndex]; - - if (scanPathLine(_pathNodeList[0].point, fNode->point)) { - _pathNodeList[1] = *fNode; - _pathNodeListIndex = 1; - } - - if (_pathNodeListIndex < 4) { - return; - } - - for (i = _pathNodeListIndex - 1, iNode = fNode-1; i > 1 ; i--, iNode--) { - if (iNode->point.x == PATH_NODE_EMPTY) { - continue; - } - - if (scanPathLine(_pathNodeList[0].point, iNode->point)) { - for (j = 1, jNode = _pathNodeList + 1; j < i; j++, jNode++) { - jNode->point.x = PATH_NODE_EMPTY; - } - } - } - - for (i = 1, iNode = _pathNodeList + 1; i < _pathNodeListIndex - 1; i++, iNode++) { - if (iNode->point.x == PATH_NODE_EMPTY) { - continue; - } - - if (scanPathLine(fNode->point, iNode->point)) { - for (j = i + 1, jNode = iNode + 1; j < _pathNodeListIndex; j++, jNode++) { - jNode->point.x = PATH_NODE_EMPTY; - } - } - } - condenseNodeList(); - - for (i = 1, iNode = _pathNodeList + 1; i < _pathNodeListIndex - 1; i++, iNode++) { - if (iNode->point.x == PATH_NODE_EMPTY) { - continue; - } - for (j = i + 2, jNode = iNode + 2; j < _pathNodeListIndex; j++, jNode++) { - if (jNode->point.x == PATH_NODE_EMPTY) { - continue; - } - - if (scanPathLine(iNode->point, jNode->point)) { - for (k = i + 1,kNode = iNode + 1; k < j; k++, kNode++) { - kNode->point.x = PATH_NODE_EMPTY; - } - } - } - } - condenseNodeList(); -} - -void Actor::condenseNodeList() { - int i, j, count; - PathNode *iNode, *jNode; - - count = _pathNodeListIndex; - - for (i = 1, iNode = _pathNodeList + 1; i < _pathNodeListIndex; i++, iNode++) { - if (iNode->point.x == PATH_NODE_EMPTY) { - j = i + 1; - jNode = iNode + 1; - while (jNode->point.x == PATH_NODE_EMPTY) { - j++; - jNode++; - } - *iNode = *jNode; - count = i; - jNode->point.x = PATH_NODE_EMPTY; - if (j == _pathNodeListIndex) { - break; - } - } - } - _pathNodeListIndex = count; -} - -void Actor::removePathPoints() { - int i, j, k, l; - PathNode *node; - int start; - int end; - Point point1, point2; - - if (_pathNodeListIndex < 2) - return; - - _newPathNodeListIndex = -1; - addNewPathNodeListPoint(_pathNodeList[0]); - - for (i = 1, node = _pathNodeList + 1; i < _pathNodeListIndex; i++, node++) { - addNewPathNodeListPoint(*node); - - for (j = 5; j > 0; j--) { - start = node->link - j; - end = node->link + j; - - if (start < 0 || end > _pathListIndex) { - continue; - } - - point1 = _pathList[start]; - point2 = _pathList[end]; - if ((point1.x == PATH_NODE_EMPTY) || (point2.x == PATH_NODE_EMPTY)) { - continue; - } - - if (scanPathLine(point1, point2)) { - for (l = 1; l <= _newPathNodeListIndex; l++) { - if (start <= _newPathNodeList[l].link) { - _newPathNodeListIndex = l; - _newPathNodeList[_newPathNodeListIndex].point = point1; - _newPathNodeList[_newPathNodeListIndex].link = start; - incrementNewPathNodeListIndex(); - break; - } - } - _newPathNodeList[_newPathNodeListIndex].point = point2; - _newPathNodeList[_newPathNodeListIndex].link = end; - - for (k = start + 1; k < end; k++) { - _pathList[k].x = PATH_NODE_EMPTY; - } - break; - } - } - } - - addNewPathNodeListPoint(_pathNodeList[_pathNodeListIndex]); - - for (i = 0, j = 0; i <= _newPathNodeListIndex; i++) { - if (_newPathNodeListIndex == i || (_newPathNodeList[i].point != _newPathNodeList[i+1].point)) { - _pathNodeList[j++] = _newPathNodeList[i]; - } - } - _pathNodeListIndex = j - 1; -} - -void Actor::drawPathTest() { -#ifdef ACTOR_DEBUG - int i; - Surface *surface; - surface = _vm->_gfx->getBackBuffer(); - if (_debugPoints == NULL) { - return; - } - - for (i = 0; i < _debugPointsCount; i++) { - *((byte *)surface->pixels + (_debugPoints[i].point.y * surface->pitch) + _debugPoints[i].point.x) = _debugPoints[i].color; - } -#endif -} - -void Actor::saveState(Common::OutSaveFile *out) { - uint16 i; - - out->writeSint16LE(getProtagState()); - - for (i = 0; i < _actorsCount; i++) { - ActorData *a = _actors[i]; - a->saveState(out); - } - - for (i = 0; i < _objsCount; i++) { - ObjectData *o = _objs[i]; - o->saveState(out); - } -} - -void Actor::loadState(Common::InSaveFile *in) { - int32 i; - - setProtagState(in->readSint16LE()); - - for (i = 0; i < _actorsCount; i++) { - ActorData *a = _actors[i]; - a->loadState(_vm->getCurrentLoadVersion(), in); - - // Fix bug #1258633 "ITE: Second Rif appears in wall of dog castle prison" - // For some reason in some cases actor position is all wrong, so Rif - // crawls to his original poition - if (i == 122 && _vm->getGameType() == GType_ITE) { - a->_location.x = 130; - a->_location.y = 55; - } - } - - for (i = 0; i < _objsCount; i++) { - ObjectData *o = _objs[i]; - o->loadState(in); - } -} - -// Console wrappers - must be safe to run - -void Actor::cmdActorWalkTo(int argc, const char **argv) { - uint16 actorId = (uint16) atoi(argv[1]); - Location location; - Point movePoint; - - movePoint.x = atoi(argv[2]); - movePoint.y = atoi(argv[3]); - - location.fromScreenPoint(movePoint); - - if (!validActorId(actorId)) { - _vm->_console->DebugPrintf("Actor::cmActorWalkTo Invalid actorId 0x%X.\n", actorId); - return; - } - - actorWalkTo(actorId, location); -} - -} // End of namespace Saga diff --git a/saga/actor.h b/saga/actor.h deleted file mode 100644 index 74f1abd689..0000000000 --- a/saga/actor.h +++ /dev/null @@ -1,778 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Actor management module header file - -#ifndef SAGA_ACTOR_H__ -#define SAGA_ACTOR_H__ - -#include "common/savefile.h" - -#include "saga/sprite.h" -#include "saga/itedata.h" -#include "saga/list.h" -#include "saga/saga.h" -#include "saga/font.h" - -namespace Saga { - -class HitZone; - - -//#define ACTOR_DEBUG //only for actor pathfinding debug! - -#define ACTOR_BARRIERS_MAX 16 - -#define ACTOR_MAX_STEPS_COUNT 32 - -#define ACTOR_DIALOGUE_HEIGHT 100 - -#define ACTOR_LMULT 4 - -#define ACTOR_CLIMB_SPEED 8 - -#define ACTOR_COLLISION_WIDTH 32 -#define ACTOR_COLLISION_HEIGHT 8 - -#define ACTOR_DIRECTIONS_COUNT 4 // for ActorFrameSequence -#define ACTOR_DIRECTION_RIGHT 0 -#define ACTOR_DIRECTION_LEFT 1 -#define ACTOR_DIRECTION_BACK 2 -#define ACTOR_DIRECTION_FORWARD 3 - -#define ACTOR_SPEECH_STRING_MAX 16 // speech const -#define ACTOR_SPEECH_ACTORS_MAX 8 - -#define ACTOR_DRAGON_TURN_MOVES 4 -#define ACTOR_DRAGON_INDEX 133 - -#define ACTOR_NO_ENTRANCE -1 - -#define ACTOR_EXP_KNOCK_RIF 24 - -#define PATH_NODE_EMPTY -1 - -#define ACTOR_INHM_SIZE 228 - -enum ActorActions { - kActionWait = 0, - kActionWalkToPoint = 1, - kActionWalkToLink = 2, - kActionWalkDir = 3, - kActionSpeak = 4, - kActionAccept = 5, - kActionStoop = 6, - kActionLook = 7, - kActionCycleFrames = 8, - kActionPongFrames = 9, - kActionFreeze = 10, - kActionFall = 11, - kActionClimb = 12 -}; - -enum SpeechFlags { - kSpeakNoAnimate = 1, - kSpeakAsync = 2, - kSpeakSlow = 4 -}; - -enum ActorFrameTypes { - kFrameStand, - kFrameWalk, - kFrameSpeak, - kFrameGive, - kFrameGesture, - kFrameWait, - kFramePickUp, - kFrameLook -}; - -enum ActorFlagsEx { - kActorNoCollide = (1 << 0), - kActorNoFollow = (1 << 1), - kActorCollided = (1 << 2), - kActorBackwards = (1 << 3), - kActorContinuous = (1 << 4), - kActorFinalFace = (1 << 5), - kActorFinishLeft = ((1 << 5) | (kDirLeft << 6)), - kActorFinishRight = ((1 << 5) | (kDirRight << 6)), - kActorFinishUp = ((1 << 5) | (kDirUp << 6)), - kActorFinishDown = ((1 << 5) | (kDirDown << 6)), - kActorFacingMask = (0xf << 5), - kActorRandom = (1 << 10) -}; - -enum PathCellType { - kPathCellEmpty = -1, - //kDirUp = 0 .... kDirUpLeft = 7 - kPathCellBarrier = 0x57 -}; - -enum DragonMoveTypes { - kDragonMoveUpLeft = 0, - kDragonMoveUpRight = 1, - kDragonMoveDownLeft = 2, - kDragonMoveDownRight = 3, - kDragonMoveUpLeft_Left = 4, - kDragonMoveUpLeft_Right = 5, - kDragonMoveUpRight_Left = 6, - kDragonMoveUpRight_Right = 7, - kDragonMoveDownLeft_Left = 8, - kDragonMoveDownLeft_Right = 9, - kDragonMoveDownRight_Left = 10, - kDragonMoveDownRight_Right = 11, - kDragonMoveInvalid = 12 -}; - -struct PathDirectionData { - int8 direction; - int16 x; - int16 y; -}; - -struct ActorFrameRange { - int frameIndex; - int frameCount; -}; - -struct ActorFrameSequence { - ActorFrameRange directions[ACTOR_DIRECTIONS_COUNT]; -}; - -int pathLine(Point *pointList, const Point &point1, const Point &point2); - -struct Location { - int32 x; // logical coordinates - int32 y; // - int32 z; // - Location() { - x = y = z = 0; - } - void saveState(Common::OutSaveFile *out) { - out->writeSint32LE(x); - out->writeSint32LE(y); - out->writeSint32LE(z); - } - void loadState(Common::InSaveFile *in) { - x = in->readSint32LE(); - y = in->readSint32LE(); - z = in->readSint32LE(); - } - - int distance(const Location &location) const { - return MAX(ABS(x - location.x), ABS(y - location.y)); - } - int32 &u() { - return x; - } - int32 &v() { - return y; - } - int32 u() const { - return x; - } - int32 v() const { - return y; - } - int32 uv() const { - return u() + v(); - } - void delta(const Location &location, Location &result) const { - result.x = x - location.x; - result.y = y - location.y; - result.z = z - location.z; - } - void addXY(const Location &location) { - x += location.x; - y += location.y; - } - void add(const Location &location) { - x += location.x; - y += location.y; - z += location.z; - } - void fromScreenPoint(const Point &screenPoint) { - x = (screenPoint.x * ACTOR_LMULT); - y = (screenPoint.y * ACTOR_LMULT); - z = 0; - } - void toScreenPointXY(Point &screenPoint) const { - screenPoint.x = x / ACTOR_LMULT; - screenPoint.y = y / ACTOR_LMULT; - } - void toScreenPointUV(Point &screenPoint) const { - screenPoint.x = u(); - screenPoint.y = v(); - } - void toScreenPointXYZ(Point &screenPoint) const { - screenPoint.x = x / ACTOR_LMULT; - screenPoint.y = y / ACTOR_LMULT - z; - } - void fromStream(Common::MemoryReadStream &stream) { - x = stream.readUint16LE(); - y = stream.readUint16LE(); - z = stream.readUint16LE(); - } - - void debugPrint(int debuglevel = 0, const char *loc = "Loc:") const { - debug(debuglevel, "%s %d, %d, %d", loc, x, y, z); - } -}; - -class CommonObjectData { -public: -//constant - bool _disabled; // disabled in init section - int32 _index; // index in local array - uint16 _id; // object id - int32 _scriptEntrypointNumber; // script entrypoint number - -//variables - uint16 _flags; // initial flags - int32 _nameIndex; // index in name string list - int32 _sceneNumber; // scene - int32 _spriteListResourceId; // sprite list resource id - - Location _location; // logical coordinates - Point _screenPosition; // screen coordinates - int32 _screenDepth; // - int32 _screenScale; // - - void saveState(Common::OutSaveFile *out) { - out->writeUint16LE(_flags); - out->writeSint32LE(_nameIndex); - out->writeSint32LE(_sceneNumber); - out->writeSint32LE(_spriteListResourceId); - _location.saveState(out); - out->writeSint16LE(_screenPosition.x); - out->writeSint16LE(_screenPosition.y); - out->writeSint32LE(_screenDepth); - out->writeSint32LE(_screenScale); - } - void loadState(Common::InSaveFile *in) { - _flags = in->readUint16LE(); - _nameIndex = in->readSint32LE(); - _sceneNumber = in->readSint32LE(); - _spriteListResourceId = in->readSint32LE(); - _location.loadState(in); - _screenPosition.x = in->readSint16LE(); - _screenPosition.y = in->readSint16LE(); - _screenDepth = in->readSint32LE(); - _screenScale = in->readSint32LE(); - } -}; - -typedef CommonObjectData *CommonObjectDataPointer; - -typedef SortedList<CommonObjectDataPointer> CommonObjectOrderList; - -class ObjectData: public CommonObjectData { -public: - //constant - uint16 _interactBits; - ObjectData() { - memset(this, 0, sizeof(*this)); - } -}; - -class ActorData: public CommonObjectData { -public: - //constant - SpriteList _spriteList; // sprite list data - - ActorFrameSequence *_frames; // Actor's frames - int _framesCount; // Actor's frames count - int _frameListResourceId; // Actor's frame list resource id - - byte _speechColor; // Actor dialogue color - // - bool _inScene; - - //variables - uint16 _actorFlags; // dynamic flags - int32 _currentAction; // ActorActions type - int32 _facingDirection; // orientation - int32 _actionDirection; - int32 _actionCycle; - uint16 _targetObject; - const HitZone *_lastZone; - - int32 _cycleFrameSequence; - uint8 _cycleDelay; - uint8 _cycleTimeCount; - uint8 _cycleFlags; - - int16 _fallVelocity; - int16 _fallAcceleration; - int16 _fallPosition; - - uint8 _dragonBaseFrame; - uint8 _dragonStepCycle; - uint8 _dragonMoveType; - - int32 _frameNumber; // current frame number - - int32 _tileDirectionsAlloced; - byte *_tileDirections; - - int32 _walkStepsAlloced; - Point *_walkStepsPoints; - - int32 _walkStepsCount; - int32 _walkStepIndex; - - Location _finalTarget; - Location _partialTarget; - int32 _walkFrameSequence; - -public: - void saveState(Common::OutSaveFile *out) { - int i = 0; - CommonObjectData::saveState(out); - out->writeUint16LE(_actorFlags); - out->writeSint32LE(_currentAction); - out->writeSint32LE(_facingDirection); - out->writeSint32LE(_actionDirection); - out->writeSint32LE(_actionCycle); - out->writeUint16LE(_targetObject); - - out->writeSint32LE(_cycleFrameSequence); - out->writeByte(_cycleDelay); - out->writeByte(_cycleTimeCount); - out->writeByte(_cycleFlags); - out->writeSint16LE(_fallVelocity); - out->writeSint16LE(_fallAcceleration); - out->writeSint16LE(_fallPosition); - out->writeByte(_dragonBaseFrame); - out->writeByte(_dragonStepCycle); - out->writeByte(_dragonMoveType); - out->writeSint32LE(_frameNumber); - - out->writeSint32LE(_tileDirectionsAlloced); - for (i = 0; i < _tileDirectionsAlloced; i++) { - out->writeByte(_tileDirections[i]); - } - - out->writeSint32LE(_walkStepsAlloced); - for (i = 0; i < _walkStepsAlloced; i++) { - out->writeSint16LE(_walkStepsPoints[i].x); - out->writeSint16LE(_walkStepsPoints[i].y); - } - - out->writeSint32LE(_walkStepsCount); - out->writeSint32LE(_walkStepIndex); - _finalTarget.saveState(out); - _partialTarget.saveState(out); - out->writeSint32LE(_walkFrameSequence); - } - - void loadState(uint32 version, Common::InSaveFile *in) { - int i = 0; - CommonObjectData::loadState(in); - _actorFlags = in->readUint16LE(); - _currentAction = in->readSint32LE(); - _facingDirection = in->readSint32LE(); - _actionDirection = in->readSint32LE(); - _actionCycle = in->readSint32LE(); - _targetObject = in->readUint16LE(); - - _lastZone = NULL; - _cycleFrameSequence = in->readSint32LE(); - _cycleDelay = in->readByte(); - _cycleTimeCount = in->readByte(); - _cycleFlags = in->readByte(); - if (version > 1) { - _fallVelocity = in->readSint16LE(); - _fallAcceleration = in->readSint16LE(); - _fallPosition = in->readSint16LE(); - } else { - _fallVelocity = _fallAcceleration = _fallPosition = 0; - } - if (version > 2) { - _dragonBaseFrame = in->readByte(); - _dragonStepCycle = in->readByte(); - _dragonMoveType = in->readByte(); - } else { - _dragonBaseFrame = _dragonStepCycle = _dragonMoveType = 0; - } - - _frameNumber = in->readSint32LE(); - - - setTileDirectionsSize(in->readSint32LE(), true); - for (i = 0; i < _tileDirectionsAlloced; i++) { - _tileDirections[i] = in->readByte(); - } - - setWalkStepsPointsSize(in->readSint32LE(), true); - for (i = 0; i < _walkStepsAlloced; i++) { - _walkStepsPoints[i].x = in->readSint16LE(); - _walkStepsPoints[i].y = in->readSint16LE(); - } - - _walkStepsCount = in->readSint32LE(); - _walkStepIndex = in->readSint32LE(); - _finalTarget.loadState(in); - _partialTarget.loadState(in); - _walkFrameSequence = in->readSint32LE(); - } - - void setTileDirectionsSize(int size, bool forceRealloc) { - if ((size <= _tileDirectionsAlloced) && !forceRealloc) { - return; - } - _tileDirectionsAlloced = size; - _tileDirections = (byte*)realloc(_tileDirections, _tileDirectionsAlloced * sizeof(*_tileDirections)); - } - - void cycleWrap(int cycleLimit) { - if (_actionCycle >= cycleLimit) - _actionCycle = 0; - } - - void setWalkStepsPointsSize(int size, bool forceRealloc) { - if ((size <= _walkStepsAlloced) && !forceRealloc) { - return; - } - _walkStepsAlloced = size; - _walkStepsPoints = (Point*)realloc(_walkStepsPoints, _walkStepsAlloced * sizeof(*_walkStepsPoints)); - } - - void addWalkStepPoint(const Point &point) { - setWalkStepsPointsSize(_walkStepsCount + 1, false); - _walkStepsPoints[_walkStepsCount++] = point; - } - - void freeSpriteList() { - _spriteList.freeMem(); - } - - ActorData() { - memset(this, 0, sizeof(*this)); - } - ~ActorData() { - free(_frames); - free(_tileDirections); - free(_walkStepsPoints); - freeSpriteList(); - } -}; - - - -struct SpeechData { - int speechColor[ACTOR_SPEECH_ACTORS_MAX]; - int outlineColor[ACTOR_SPEECH_ACTORS_MAX]; - int speechFlags; - const char *strings[ACTOR_SPEECH_STRING_MAX]; - Rect speechBox; - Rect drawRect; - int stringsCount; - int slowModeCharIndex; - uint16 actorIds[ACTOR_SPEECH_ACTORS_MAX]; - int actorsCount; - int sampleResourceId; - bool playing; - int playingTime; - - SpeechData() { - memset(this, 0, sizeof(*this)); - } - - FontEffectFlags getFontFlags(int i) { - if (outlineColor[i] != 0) { - return kFontOutline; - } else { - return kFontNormal; - } - } -}; - - - -class Actor { - friend class IsoMap; - friend class SagaEngine; - friend class Puzzle; -public: - - Actor(SagaEngine *vm); - ~Actor(); - - void cmdActorWalkTo(int argc, const char **argv); - - bool validActorId(uint16 id) { return (id == ID_PROTAG) || ((id >= objectIndexToId(kGameObjectActor, 0)) && (id < objectIndexToId(kGameObjectActor, _actorsCount))); } - int actorIdToIndex(uint16 id) { return (id == ID_PROTAG ) ? 0 : objectIdToIndex(id); } - uint16 actorIndexToId(int index) { return (index == 0 ) ? ID_PROTAG : objectIndexToId(kGameObjectActor, index); } - ActorData *getActor(uint16 actorId); - -// clarification: Obj - means game object, such Hat, Spoon etc, Object - means Actor,Obj,HitZone,StepZone - - bool validObjId(uint16 id) { return (id >= objectIndexToId(kGameObjectObject, 0)) && (id < objectIndexToId(kGameObjectObject, _objsCount)); } - int objIdToIndex(uint16 id) { return objectIdToIndex(id); } - uint16 objIndexToId(int index) { return objectIndexToId(kGameObjectObject, index); } - ObjectData *getObj(uint16 objId); - - int getObjectScriptEntrypointNumber(uint16 id) { - int objectType; - objectType = objectTypeId(id); - if (!(objectType & (kGameObjectObject | kGameObjectActor))) { - error("Actor::getObjectScriptEntrypointNumber wrong id 0x%X", id); - } - return (objectType == kGameObjectObject) ? getObj(id)->_scriptEntrypointNumber : getActor(id)->_scriptEntrypointNumber; - } - int getObjectFlags(uint16 id) { - int objectType; - objectType = objectTypeId(id); - if (!(objectType & (kGameObjectObject | kGameObjectActor))) { - error("Actor::getObjectFlags wrong id 0x%X", id); - } - return (objectType == kGameObjectObject) ? getObj(id)->_flags : getActor(id)->_flags; - } - - void direct(int msec); - void drawActors(); - void updateActorsScene(int actorsEntrance); // calls from scene loading to update Actors info - - void drawSpeech(); - - void drawPathTest(); - - uint16 hitTest(const Point &testPoint, bool skipProtagonist); - void takeExit(uint16 actorId, const HitZone *hitZone); - bool actorEndWalk(uint16 actorId, bool recurse); - bool actorWalkTo(uint16 actorId, const Location &toLocation); - int getFrameType(ActorFrameTypes frameType); - ActorFrameRange *getActorFrameRange(uint16 actorId, int frameType); - void actorFaceTowardsPoint(uint16 actorId, const Location &toLocation); - void actorFaceTowardsObject(uint16 actorId, uint16 objectId); - - void realLocation(Location &location, uint16 objectId, uint16 walkFlags); - -// speech - void actorSpeech(uint16 actorId, const char **strings, int stringsCount, int sampleResourceId, int speechFlags); - void nonActorSpeech(const Common::Rect &box, const char **strings, int stringsCount, int sampleResourceId, int speechFlags); - void simulSpeech(const char *string, uint16 *actorIds, int actorIdsCount, int speechFlags, int sampleResourceId); - void setSpeechColor(int speechColor, int outlineColor) { - _activeSpeech.speechColor[0] = speechColor; - _activeSpeech.outlineColor[0] = outlineColor; - } - void abortAllSpeeches(); - void abortSpeech(); - bool isSpeaking() { - return _activeSpeech.stringsCount > 0; - } - - void saveState(Common::OutSaveFile *out); - void loadState(Common::InSaveFile *in); - - void setProtagState(int state); - int getProtagState() { return _protagState; } - - void freeActorList(); - void loadActorList(int protagonistIdx, int actorCount, int actorsResourceID, - int protagStatesCount, int protagStatesResourceID); - void freeObjList(); - void loadObjList(int objectCount, int objectsResourceID); - - /* - uint16 _currentFrameIndex; - void frameTest() { - _currentFrameIndex++; - }*/ -protected: - friend class Script; - bool loadActorResources(ActorData *actor); - -private: - void stepZoneAction(ActorData *actor, const HitZone *hitZone, bool exit, bool stopped); - void loadActorSpriteList(ActorData *actor); - - void createDrawOrderList(); - bool calcScreenPosition(CommonObjectData *commonObjectData); - bool getSpriteParams(CommonObjectData *commonObjectData, int &frameNumber, SpriteList *&spriteList); - - bool followProtagonist(ActorData *actor); - void findActorPath(ActorData *actor, const Point &fromPoint, const Point &toPoint); - void handleSpeech(int msec); - void handleActions(int msec, bool setup); - bool validPathCellPoint(const Point &testPoint) { - return !((testPoint.x < 0) || (testPoint.x >= _xCellCount) || - (testPoint.y < 0) || (testPoint.y >= _yCellCount)); - } - void setPathCell(const Point &testPoint, int8 value) { - if (!validPathCellPoint(testPoint)) { - error("Actor::setPathCell wrong point"); - } - _pathCell[testPoint.x + testPoint.y * _xCellCount] = value; - } - int8 getPathCell(const Point &testPoint) { - if (!validPathCellPoint(testPoint)) { - error("Actor::getPathCell wrong point"); - } - return _pathCell[testPoint.x + testPoint.y * _xCellCount]; - } - bool scanPathLine(const Point &point1, const Point &point2); - int fillPathArray(const Point &fromPoint, const Point &toPoint, Point &bestPoint); - void setActorPath(ActorData *actor, const Point &fromPoint, const Point &toPoint); - void pathToNode(); - void condenseNodeList(); - void removeNodes(); - void nodeToPath(); - void removePathPoints(); - bool validFollowerLocation(const Location &location); - void moveDragon(ActorData *actor); - - -protected: -//constants - int _actorsCount; - ActorData **_actors; - - int _objsCount; - ObjectData **_objs; - - SagaEngine *_vm; - ResourceContext *_actorContext; - - int _lastTickMsec; - CommonObjectOrderList _drawOrderList; - -//variables -public: - ActorData *_centerActor; - ActorData *_protagonist; - int _handleActionDiv; - - Rect _speechBoxScript; - - StringsTable _objectsStrings; - StringsTable _actorsStrings; - -protected: - SpeechData _activeSpeech; - int _protagState; - bool _dragonHunt; - -private: - ActorFrameSequence *_protagStates; - int _protagStatesCount; - -//path stuff - struct PathNode { - Point point; - int link; - }; - - Rect _barrierList[ACTOR_BARRIERS_MAX]; - int _barrierCount; - int8 *_pathCell; - - int _xCellCount; - int _yCellCount; - Rect _pathRect; - - PathDirectionData *_pathDirectionList; - int _pathDirectionListCount; - int _pathDirectionListAlloced; - PathDirectionData * addPathDirectionListData() { - if (_pathDirectionListCount + 1 >= _pathDirectionListAlloced) { - _pathDirectionListAlloced += 100; - _pathDirectionList = (PathDirectionData*) realloc(_pathDirectionList, _pathDirectionListAlloced * sizeof(*_pathDirectionList)); - } - return &_pathDirectionList[_pathDirectionListCount++]; - } - - Point *_pathList; - int _pathListIndex; - int _pathListAlloced; - void addPathListPoint(const Point &point) { - ++_pathListIndex; - if (_pathListIndex >= _pathListAlloced) { - _pathListAlloced += 100; - _pathList = (Point*) realloc(_pathList, _pathListAlloced * sizeof(*_pathList)); - - } - _pathList[_pathListIndex] = point; - } - - int _pathNodeListIndex; - int _pathNodeListAlloced; - PathNode *_pathNodeList; - void addPathNodeListPoint(const Point &point) { - ++_pathNodeListIndex; - if (_pathNodeListIndex >= _pathNodeListAlloced) { - _pathNodeListAlloced += 100; - _pathNodeList = (PathNode*) realloc(_pathNodeList, _pathNodeListAlloced * sizeof(*_pathNodeList)); - - } - _pathNodeList[_pathNodeListIndex].point = point; - } - - int _newPathNodeListIndex; - int _newPathNodeListAlloced; - PathNode *_newPathNodeList; - void incrementNewPathNodeListIndex() { - ++_newPathNodeListIndex; - if (_newPathNodeListIndex >= _newPathNodeListAlloced) { - _newPathNodeListAlloced += 100; - _newPathNodeList = (PathNode*) realloc(_newPathNodeList, _newPathNodeListAlloced * sizeof(*_newPathNodeList)); - - } - } - void addNewPathNodeListPoint(const PathNode &pathNode) { - incrementNewPathNodeListIndex(); - _newPathNodeList[_newPathNodeListIndex] = pathNode; - } - -public: -#ifdef ACTOR_DEBUG -//path debug - use with care - struct DebugPoint { - Point point; - byte color; - }; - DebugPoint *_debugPoints; - int _debugPointsCount; - int _debugPointsAlloced; - void addDebugPoint(const Point &point, byte color) { - if (_debugPointsCount + 1 > _debugPointsAlloced) { - _debugPointsAlloced += 1000; - _debugPoints = (DebugPoint*) realloc(_debugPoints, _debugPointsAlloced * sizeof(*_debugPoints)); - } - _debugPoints[_debugPointsCount].color = color; - _debugPoints[_debugPointsCount++].point = point; - } -#endif -}; - -inline int16 quickDistance(const Point &point1, const Point &point2) { - Point delta; - delta.x = ABS(point1.x - point2.x) / 2; - delta.y = ABS(point1.y - point2.y); - return ((delta.x < delta.y) ? (delta.y + delta.x / 2) : (delta.x + delta.y / 2)); -} -} // End of namespace Saga - -#endif diff --git a/saga/animation.cpp b/saga/animation.cpp deleted file mode 100644 index 016070dc50..0000000000 --- a/saga/animation.cpp +++ /dev/null @@ -1,720 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Background animation management module -#include "saga/saga.h" -#include "saga/gfx.h" - -#include "saga/console.h" -#include "saga/events.h" -#include "saga/interface.h" -#include "saga/render.h" -#include "saga/rscfile.h" -#include "saga/scene.h" - -#include "saga/animation.h" - -namespace Saga { - -Anim::Anim(SagaEngine *vm) : _vm(vm) { - uint16 i; - - _cutawayList = NULL; - _cutawayListLength = 0; - _cutawayActive = false; - - for (i = 0; i < MAX_ANIMATIONS; i++) - _animations[i] = NULL; - - for (i = 0; i < ARRAYSIZE(_cutawayAnimations); i++) - _cutawayAnimations[i] = NULL; -} - -Anim::~Anim(void) { - reset(); -} - -void Anim::loadCutawayList(const byte *resourcePointer, size_t resourceLength) { - free(_cutawayList); - _cutawayListLength = resourceLength / 8; - _cutawayList = (Cutaway *)malloc(_cutawayListLength * sizeof(Cutaway)); - - MemoryReadStream cutawayS(resourcePointer, resourceLength); - - for (int i = 0; i < _cutawayListLength; i++) { - _cutawayList[i].backgroundResourceId = cutawayS.readUint16LE(); - _cutawayList[i].animResourceId = cutawayS.readUint16LE(); - _cutawayList[i].cycles = cutawayS.readSint16LE(); - _cutawayList[i].frameRate = cutawayS.readSint16LE(); - } -} - -void Anim::freeCutawayList(void) { - free(_cutawayList); - _cutawayList = NULL; - _cutawayListLength = 0; -} - -void Anim::playCutaway(int cut, bool fade) { - debug(0, "playCutaway(%d, %d)", cut, fade); - - if (fade) { - // TODO: Fade down. Is this blocking or non-blocking? - } - - if (!_cutawayActive) { - _vm->_gfx->showCursor(false); - _vm->_interface->setStatusText(""); - _vm->_interface->setSaveReminderState(0); - _vm->_interface->rememberMode(); - _vm->_interface->setMode(kPanelCutaway); - _cutawayActive = true; - } - - // Set the initial background and palette for the cutaway - - ResourceContext *context = _vm->_resource->getContext(GAME_RESOURCEFILE); - - byte *resourceData; - size_t resourceDataLength; - - _vm->_resource->loadResource(context, _cutawayList[cut].backgroundResourceId, resourceData, resourceDataLength); - - byte *buf; - size_t buflen; - int width; - int height; - - _vm->decodeBGImage(resourceData, resourceDataLength, &buf, &buflen, &width, &height); - - const PalEntry *palette = (const PalEntry *)_vm->getImagePal(resourceData, resourceDataLength); - - Surface *bgSurface = _vm->_render->getBackGroundSurface(); - const Rect rect(width, height); - - bgSurface->blit(rect, buf); - _vm->_gfx->setPalette(palette); - - free(buf); - free(resourceData); - - // Play the animation - - int cutawaySlot = -1; - - for (int i = 0; i < ARRAYSIZE(_cutawayAnimations); i++) { - if (!_cutawayAnimations[i]) { - cutawaySlot = i; - } else if (_cutawayAnimations[i]->state == ANIM_PAUSE) { - delete _cutawayAnimations[i]; - _cutawayAnimations[i] = NULL; - cutawaySlot = i; - } else if (_cutawayAnimations[i]->state == ANIM_PLAYING) { - _cutawayAnimations[i]->state = ANIM_PAUSE; - } - } - - if (cutawaySlot == -1) { - warning("Could not allocate cutaway animation slot"); - return; - } - - _vm->_resource->loadResource(context, _cutawayList[cut].animResourceId, resourceData, resourceDataLength); - - load(MAX_ANIMATIONS + cutawaySlot, resourceData, resourceDataLength); - - free(resourceData); - - setCycles(MAX_ANIMATIONS + cutawaySlot, _cutawayList[cut].cycles); - setFrameTime(MAX_ANIMATIONS + cutawaySlot, 1000 / _cutawayList[cut].frameRate); - play(MAX_ANIMATIONS + cutawaySlot, 0); -} - -void Anim::endCutaway(void) { - // I believe this is called by scripts after running one cutaway. At - // this time, nothing needs to be done here. - - debug(0, "endCutaway()"); -} - -void Anim::returnFromCutaway(void) { - // I believe this is called by scripts after running a cutaway to - // ensure that we return to the scene as if nothing had happened. It's - // not called by the IHNM intro, presumably because there is no old - // scene to return to. - - debug(0, "returnFromCutaway()"); - - if (_cutawayActive) { - // Note that clearCutaway() sets _cutawayActive to false. - clearCutaway(); - - // TODO: Handle fade up, if we previously faded down - - // TODO: Restore the scene - - // TODO: Restore the animations - - for (int i = 0; i < MAX_ANIMATIONS; i++) { - if (_animations[i] && _animations[i]->state == ANIM_PLAYING) { - resume(i, 0); - } - } - } -} - -void Anim::clearCutaway(void) { - debug(0, "clearCutaway()"); - - if (_cutawayActive) { - _cutawayActive = false; - - for (int i = 0; i < ARRAYSIZE(_cutawayAnimations); i++) { - delete _cutawayAnimations[i]; - _cutawayAnimations[i] = NULL; - } - - _vm->_interface->restoreMode(); - _vm->_gfx->showCursor(true); - } -} - -void Anim::load(uint16 animId, const byte *animResourceData, size_t animResourceLength) { - AnimationData *anim; - uint16 temp; - - if (animId >= MAX_ANIMATIONS) { - if (animId >= MAX_ANIMATIONS + ARRAYSIZE(_cutawayAnimations)) - error("Anim::load could not find unused animation slot"); - anim = _cutawayAnimations[animId - MAX_ANIMATIONS] = new AnimationData(animResourceData, animResourceLength); - } else - anim = _animations[animId] = new AnimationData(animResourceData, animResourceLength); - - MemoryReadStreamEndian headerReadS(anim->resourceData, anim->resourceLength, _vm->isBigEndian()); - anim->magic = headerReadS.readUint16LE(); // cause ALWAYS LE - anim->screenWidth = headerReadS.readUint16(); - anim->screenHeight = headerReadS.readUint16(); - - anim->unknown06 = headerReadS.readByte(); - anim->unknown07 = headerReadS.readByte(); - anim->maxFrame = headerReadS.readByte() - 1; - anim->loopFrame = headerReadS.readByte() - 1; - temp = headerReadS.readUint16BE(); - anim->start = headerReadS.pos(); - if (temp == (uint16)(-1)) { - temp = 0; - } - anim->start += temp; - - // Cache frame offsets - anim->frameOffsets = (size_t *)malloc((anim->maxFrame + 1) * sizeof(*anim->frameOffsets)); - if (anim->frameOffsets == NULL) { - memoryError("Anim::load"); - } - - fillFrameOffsets(anim); - - /* char s[200]; - sprintf(s, "d:\\anim%i",animId); - long flen=anim->resourceLength; - char *buf=(char*)anim->resourceData; - FILE*f; - f=fopen(s,"wb"); - for(long i=0;i<flen;i++) - fputc(buf[i],f); - fclose(f);*/ - - // Set animation data - anim->currentFrame = 0; - anim->completed = 0; - anim->cycles = anim->maxFrame; - - anim->frameTime = DEFAULT_FRAME_TIME; - anim->flags = ANIM_FLAG_NONE; - anim->linkId = -1; - anim->state = ANIM_PAUSE; -} - -void Anim::link(int16 animId1, int16 animId2) { - AnimationData *anim1; - AnimationData *anim2; - - anim1 = getAnimation(animId1); - - anim1->linkId = animId2; - - if (animId2 == -1) { - return; - } - - anim2 = getAnimation(animId2); - anim2->frameTime = anim1->frameTime; -} - -void Anim::setCycles(uint16 animId, int cycles) { - AnimationData *anim; - - anim = getAnimation(animId); - - anim->cycles = cycles; -} - -void Anim::play(uint16 animId, int vectorTime, bool playing) { - Event event; - Surface *backGroundSurface; - - byte *displayBuffer; - - uint16 frame; - int frameTime; - - AnimationData *anim; - AnimationData *linkAnim; - - if (animId > MAX_ANIMATIONS && !_cutawayActive) - return; - - if (animId < MAX_ANIMATIONS && _cutawayActive) - return; - - anim = getAnimation(animId); - - backGroundSurface = _vm->_render->getBackGroundSurface(); - displayBuffer = (byte*)backGroundSurface->pixels; - - if (playing) { - anim->state = ANIM_PLAYING; - } - - if (anim->state == ANIM_PAUSE) { - return; - } - - if (anim->completed < anim->cycles) { - frame = anim->currentFrame; - // FIXME: if start > 0, then this works incorrectly - decodeFrame(anim, anim->frameOffsets[frame], displayBuffer, _vm->getDisplayWidth() * _vm->getDisplayHeight()); - - anim->currentFrame++; - if (anim->completed != 65535) { - anim->completed++; - } - - if (anim->currentFrame > anim->maxFrame) { - anim->currentFrame = anim->loopFrame; - - if (anim->state == ANIM_STOPPING || anim->currentFrame == -1) { - anim->state = ANIM_PAUSE; - } - } - } else { - // Animation done playing - anim->state = ANIM_PAUSE; - if (anim->linkId == -1) { - if (anim->flags & ANIM_FLAG_ENDSCENE) { - // This animation ends the scene - event.type = kEvTOneshot; - event.code = kSceneEvent; - event.op = kEventEnd; - event.time = anim->frameTime + vectorTime; - _vm->_events->queue(&event); - } - return; - } else { - anim->currentFrame = 0; - anim->completed = 0; - } - } - - if (anim->state == ANIM_PAUSE && anim->linkId != -1) { - // If this animation has a link, follow it - linkAnim = getAnimation(anim->linkId); - - debug(5, "Animation ended going to %d", anim->linkId); - linkAnim->state = ANIM_PLAYING; - animId = anim->linkId; - frameTime = 0; - } else { - frameTime = anim->frameTime + vectorTime; - } - - event.type = kEvTOneshot; - event.code = kAnimEvent; - event.op = kEventFrame; - event.param = animId; - event.time = frameTime; - - _vm->_events->queue(&event); -} - -void Anim::stop(uint16 animId) { - AnimationData *anim; - - anim = getAnimation(animId); - - anim->state = ANIM_PAUSE; -} - -void Anim::finish(uint16 animId) { - AnimationData *anim; - - anim = getAnimation(animId); - - anim->state = ANIM_STOPPING; -} - -void Anim::resume(uint16 animId, int cycles) { - AnimationData *anim; - - anim = getAnimation(animId); - - anim->cycles += cycles; - play(animId, 0, true); -} - -void Anim::reset() { - uint16 i; - - for (i = 0; i < MAX_ANIMATIONS; i++) { - if (_animations[i] != NULL) { - delete _animations[i]; - _animations[i] = NULL; - } - } - - for (i = 0; i < ARRAYSIZE(_cutawayAnimations); i++) { - if (_cutawayAnimations[i] != NULL) { - delete _cutawayAnimations[i]; - _cutawayAnimations[i] = NULL; - } - } -} - -void Anim::setFlag(uint16 animId, uint16 flag) { - AnimationData *anim; - - anim = getAnimation(animId); - - anim->flags |= flag; -} - -void Anim::clearFlag(uint16 animId, uint16 flag) { - AnimationData *anim; - - anim = getAnimation(animId); - - anim->flags &= ~flag; -} - -void Anim::setFrameTime(uint16 animId, int time) { - AnimationData *anim; - - anim = getAnimation(animId); - - anim->frameTime = time; -} - -int16 Anim::getCurrentFrame(uint16 animId) { - AnimationData *anim; - - anim = getAnimation(animId); - - return anim->currentFrame; -} - -void Anim::decodeFrame(AnimationData *anim, size_t frameOffset, byte *buf, size_t bufLength) { - byte *writePointer = NULL; - - uint16 xStart = 0; - uint16 yStart = 0; - uint32 screenWidth; - uint32 screenHeight; - - int markByte; - byte dataByte; - int newRow; - - uint16 controlChar; - uint16 paramChar; - - uint16 runcount; - int xVector; - - uint16 i; - bool longData = isLongData(); - - screenWidth = anim->screenWidth; - screenHeight = anim->screenHeight; - - if ((screenWidth * screenHeight) > bufLength) { - // Buffer argument is too small to hold decoded frame, abort. - error("decodeFrame() Buffer size inadequate"); - } - - MemoryReadStream readS(anim->resourceData + frameOffset, anim->resourceLength - frameOffset); - - -#if 1 -#define VALIDATE_WRITE_POINTER \ - if ((writePointer < buf) || (writePointer >= (buf + screenWidth * screenHeight))) { \ - error("VALIDATE_WRITE_POINTER: writePointer=%x buf=%x", writePointer, buf); \ - } -#else -#define VALIDATE_WRITE_POINTER -#endif - - - // Begin RLE decompression to output buffer - do { - markByte = readS.readByte(); - switch (markByte) { - case SAGA_FRAME_START: - xStart = readS.readUint16BE(); - if (longData) - yStart = readS.readUint16BE(); - else - yStart = readS.readByte(); - readS.readByte(); /* Skip pad byte */ - /*xPos = */readS.readUint16BE(); - /*yPos = */readS.readUint16BE(); - /*width = */readS.readUint16BE(); - /*height = */readS.readUint16BE(); - - // Setup write pointer to the draw origin - writePointer = (buf + (yStart * screenWidth) + xStart); - VALIDATE_WRITE_POINTER; - continue; - break; - case SAGA_FRAME_NOOP: // Does nothing - readS.readByte(); - readS.readByte(); - readS.readByte(); - continue; - break; - case SAGA_FRAME_LONG_UNCOMPRESSED_RUN: // Long Unencoded Run - runcount = readS.readSint16BE(); - for (i = 0; i < runcount; i++) { - dataByte = readS.readByte(); - if (dataByte != 0) { - *writePointer = dataByte; - } - writePointer++; - VALIDATE_WRITE_POINTER; - } - continue; - break; - case SAGA_FRAME_LONG_COMPRESSED_RUN: // Long encoded run - runcount = readS.readSint16BE(); - dataByte = readS.readByte(); - for (i = 0; i < runcount; i++) { - *writePointer++ = dataByte; - VALIDATE_WRITE_POINTER; - } - continue; - break; - case SAGA_FRAME_ROW_END: // End of row - xVector = readS.readSint16BE(); - - if (longData) - newRow = readS.readSint16BE(); - else - newRow = readS.readByte(); - - // Set write pointer to the new draw origin - writePointer = buf + ((yStart + newRow) * screenWidth) + xStart + xVector; - VALIDATE_WRITE_POINTER; - continue; - break; - case SAGA_FRAME_REPOSITION: // Reposition command - xVector = readS.readSint16BE(); - writePointer += xVector; - VALIDATE_WRITE_POINTER; - continue; - break; - case SAGA_FRAME_END: // End of frame marker - return; - break; - default: - break; - } - - // Mask all but two high order control bits - controlChar = markByte & 0xC0U; - paramChar = markByte & 0x3FU; - switch (controlChar) { - case SAGA_FRAME_EMPTY_RUN: // 1100 0000 - // Run of empty pixels - runcount = paramChar + 1; - writePointer += runcount; - VALIDATE_WRITE_POINTER; - continue; - break; - case SAGA_FRAME_COMPRESSED_RUN: // 1000 0000 - // Run of compressed data - runcount = paramChar + 1; - dataByte = readS.readByte(); - for (i = 0; i < runcount; i++) { - *writePointer++ = dataByte; - VALIDATE_WRITE_POINTER; - } - continue; - break; - case SAGA_FRAME_UNCOMPRESSED_RUN: // 0100 0000 - // Uncompressed run - runcount = paramChar + 1; - for (i = 0; i < runcount; i++) { - dataByte = readS.readByte(); - if (dataByte != 0) { - *writePointer = dataByte; - } - writePointer++; - VALIDATE_WRITE_POINTER; - } - continue; - break; - default: - // Unknown marker found - abort - error("decodeFrame() Invalid RLE marker encountered"); - break; - } - } while (1); -} - -void Anim::fillFrameOffsets(AnimationData *anim) { - uint16 currentFrame; - byte markByte; - uint16 control; - uint16 runcount; - int i; - bool longData = isLongData(); - - MemoryReadStreamEndian readS(anim->resourceData, anim->resourceLength, _vm->isBigEndian()); - - readS.seek(12); - - readS._bigEndian = !_vm->isBigEndian(); // RLE has inversion BE<>LE - - for (currentFrame = 0; currentFrame <= anim->maxFrame; currentFrame++) { - anim->frameOffsets[currentFrame] = readS.pos(); - - // For some strange reason, the animation header is in little - // endian format, but the actual RLE encoded frame data, - // including the frame header, is in big endian format. */ - do { - markByte = readS.readByte(); -// debug(7, "_pos=%x currentFrame=%i markByte=%x", readS.pos(), currentFrame, markByte); - - switch (markByte) { - case SAGA_FRAME_START: // Start of frame - // skip header - if (longData) { - readS.seek(13, SEEK_CUR); - } else { - readS.seek(12, SEEK_CUR); - } - continue; - break; - - case SAGA_FRAME_END: // End of frame marker - continue; - break; - case SAGA_FRAME_REPOSITION: // Reposition command - readS.readSint16BE(); - continue; - break; - case SAGA_FRAME_ROW_END: // End of row marker - readS.readSint16BE(); - if (longData) - readS.readSint16BE(); - else - readS.readByte(); - continue; - break; - case SAGA_FRAME_LONG_COMPRESSED_RUN: // Long compressed run marker - readS.readSint16BE(); - readS.readByte(); - continue; - break; - case SAGA_FRAME_LONG_UNCOMPRESSED_RUN: // (16) 0001 0000 - // Long Uncompressed Run - runcount = readS.readSint16BE(); - for (i = 0; i < runcount; i++) - readS.readByte(); - continue; - break; - case SAGA_FRAME_NOOP: // Does nothing - readS.readByte(); - readS.readByte(); - readS.readByte(); - continue; - break; - default: - break; - } - - // Mask all but two high order (control) bits - control = markByte & 0xC0; - switch (control) { - case SAGA_FRAME_EMPTY_RUN: - // Run of empty pixels - continue; - break; - case SAGA_FRAME_COMPRESSED_RUN: - // Run of compressed data - readS.readByte(); // Skip data byte - continue; - break; - case SAGA_FRAME_UNCOMPRESSED_RUN: - // Uncompressed run - runcount = (markByte & 0x3f) + 1; - for (i = 0; i < runcount; i++) - readS.readByte(); - continue; - break; - default: - error("Encountered unknown RLE marker %i", markByte); - break; - } - } while (markByte != SAGA_FRAME_END); - } -} - -void Anim::animInfo() { - uint16 animCount; - uint16 i; - - animCount = getAnimationCount(); - - _vm->_console->DebugPrintf("There are %d animations loaded:\n", animCount); - - for (i = 0; i < MAX_ANIMATIONS; i++) { - if (_animations[i] == NULL) { - continue; - } - - _vm->_console->DebugPrintf("%02d: Frames: %u Flags: %u\n", i, _animations[i]->maxFrame, _animations[i]->flags); - } -} - -} // End of namespace Saga diff --git a/saga/animation.h b/saga/animation.h deleted file mode 100644 index 191166732a..0000000000 --- a/saga/animation.h +++ /dev/null @@ -1,198 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Background animation management module private header - -#ifndef SAGA_ANIMATION_H_ -#define SAGA_ANIMATION_H_ - -#include "saga/stream.h" - -namespace Saga { - -#define MAX_ANIMATIONS 10 -#define DEFAULT_FRAME_TIME 140 - -#define SAGA_FRAME_START 0xF -#define SAGA_FRAME_END 0x3F -#define SAGA_FRAME_NOOP 0x1F -#define SAGA_FRAME_REPOSITION 0x30 -#define SAGA_FRAME_ROW_END 0x2F -#define SAGA_FRAME_LONG_COMPRESSED_RUN 0x20 -#define SAGA_FRAME_LONG_UNCOMPRESSED_RUN 0x10 -#define SAGA_FRAME_COMPRESSED_RUN 0x80 -#define SAGA_FRAME_UNCOMPRESSED_RUN 0x40 -#define SAGA_FRAME_EMPTY_RUN 0xC0 - -enum AnimationState { - ANIM_PLAYING = 0x01, - ANIM_PAUSE = 0x02, - ANIM_STOPPING = 0x03 -}; - -enum AnimationFlags { - ANIM_FLAG_NONE = 0x00, - ANIM_FLAG_ENDSCENE = 0x01 // When animation ends, dispatch scene end event -}; - -// Cutaway info array member. Cutaways are basically animations with a really -// bad attitude. -struct Cutaway { - uint16 backgroundResourceId; - uint16 animResourceId; - int16 cycles; - int16 frameRate; -}; - -// Animation info array member -struct AnimationData { - byte *resourceData; - size_t resourceLength; - - uint16 magic; - - uint16 screenWidth; - uint16 screenHeight; - - byte unknown06; - byte unknown07; - - int16 maxFrame; - int16 loopFrame; - - int16 start; - - int16 currentFrame; - size_t *frameOffsets; - - uint16 completed; - uint16 cycles; - - int frameTime; - - AnimationState state; - int16 linkId; - uint16 flags; - - AnimationData(const byte *animResourceData, size_t animResourceLength) { - memset(this, 0, sizeof(*this)); - resourceLength = animResourceLength; - resourceData = (byte*)malloc(animResourceLength); - memcpy(resourceData, animResourceData, animResourceLength); - } - ~AnimationData() { - free(frameOffsets); - free(resourceData); - } -}; - -class Anim { -public: - Anim(SagaEngine *vm); - ~Anim(void); - - void loadCutawayList(const byte *resourcePointer, size_t resourceLength); - void freeCutawayList(void); - void playCutaway(int cut, bool fade); - void endCutaway(void); - void returnFromCutaway(void); - void clearCutaway(void); - - void load(uint16 animId, const byte *animResourceData, size_t animResourceLength); - void freeId(uint16 animId); - void play(uint16 animId, int vectorTime, bool playing = true); - void link(int16 animId1, int16 animId2); - void setFlag(uint16 animId, uint16 flag); - void clearFlag(uint16 animId, uint16 flag); - void setFrameTime(uint16 animId, int time); - void reset(void); - void animInfo(void); - void setCycles(uint16 animId, int cycles); - void stop(uint16 animId); - void finish(uint16 animId); - void resume(uint16 animId, int cycles); - int16 getCurrentFrame(uint16 animId); - bool hasCutaway(void) { - return _cutawayActive; - } - bool hasAnimation(uint16 animId) { - if (animId >= MAX_ANIMATIONS) { - if (animId < MAX_ANIMATIONS + ARRAYSIZE(_cutawayAnimations)) - return (_cutawayAnimations[animId - MAX_ANIMATIONS] != NULL); - return false; - } - return (_animations[animId] != NULL); - } -private: - void decodeFrame(AnimationData *anim, size_t frameOffset, byte *buf, size_t bufLength); - void fillFrameOffsets(AnimationData *anim); - - void validateAnimationId(uint16 animId) { - if (animId >= MAX_ANIMATIONS) { - if (animId >= MAX_ANIMATIONS + ARRAYSIZE(_cutawayAnimations)) - error("validateAnimationId: animId out of range"); - if (_cutawayAnimations[animId - MAX_ANIMATIONS] == NULL) { - error("validateAnimationId: animId=%i unassigned", animId); - } - } - if (_animations[animId] == NULL) { - error("validateAnimationId: animId=%i unassigned", animId); - } - } - - bool isLongData() const { - if ((_vm->getGameType() == GType_ITE) && (_vm->getPlatform() != Common::kPlatformMacintosh)) { - return false; - } - return true; - } - - AnimationData* getAnimation(uint16 animId) { - validateAnimationId(animId); - if (animId > MAX_ANIMATIONS) - return _cutawayAnimations[animId - MAX_ANIMATIONS]; - return _animations[animId]; - } - - uint16 getAnimationCount() const { - uint16 i = 0; - for (; i < MAX_ANIMATIONS; i++) { - if (_animations[i] == NULL) { - break; - } - } - return i; - } - - SagaEngine *_vm; - AnimationData *_animations[MAX_ANIMATIONS]; - AnimationData *_cutawayAnimations[2]; - Cutaway *_cutawayList; - int _cutawayListLength; - bool _cutawayActive; -}; - -} // End of namespace Saga - -#endif /* ANIMATION_H_ */ diff --git a/saga/console.cpp b/saga/console.cpp deleted file mode 100644 index 3455c8c1c3..0000000000 --- a/saga/console.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Console module - -#include "saga/saga.h" -#include "saga/actor.h" -#include "saga/animation.h" -#include "saga/scene.h" -#include "saga/script.h" - -#include "saga/console.h" - -#include "common/debugger.cpp" - -namespace Saga { - -Console::Console(SagaEngine *vm) : Common::Debugger<Console>() { - _vm = vm; - - DCmd_Register("continue", &Console::Cmd_Exit); - DCmd_Register("exit", &Console::Cmd_Exit); - DCmd_Register("quit", &Console::Cmd_Exit); - DCmd_Register("help", &Console::Cmd_Help); - - // CVAR_Register_I(&_soundEnabled, "sound", NULL, CVAR_CFG, 0, 1); - // CVAR_Register_I(&_musicEnabled, "music", NULL, CVAR_CFG, 0, 1); - - // Actor commands - DCmd_Register("actor_walk_to", &Console::cmdActorWalkTo); - - // Animation commands - DCmd_Register("anim_info", &Console::Cmd_AnimInfo); - - // Game stuff - -#if 0 - // Register "g_language" cfg cvar - strncpy(GameModule.game_language, "us", MAXPATH); - - CVAR_Register_S(GameModule.game_language, "g_language", NULL, CVAR_CFG, GAME_LANGSTR_LIMIT); - - // Register "g_skipintro" cfg cvar - CVAR_Register_I(&GameModule.g_skipintro, "g_skipintro", NULL, CVAR_CFG, 0, 1); -#endif - - // Scene commands - DCmd_Register("scene_change", &Console::cmdSceneChange); - DCmd_Register("action_map_info", &Console::cmdActionMapInfo); - DCmd_Register("object_map_info", &Console::cmdObjectMapInfo); -} - -Console::~Console() { -} - -void Console::preEnter() { -} - -void Console::postEnter() { -} - -bool Console::Cmd_Exit(int argc, const char **argv) { - _detach_now = true; - return false; -} - -bool Console::Cmd_Help(int argc, const char **argv) { - // console normally has 39 line width - // wrap around nicely - int width = 0, size, i; - - DebugPrintf("Commands are:\n"); - for (i = 0 ; i < _dcmd_count ; i++) { - size = strlen(_dcmds[i].name) + 1; - - if ((width + size) >= 39) { - DebugPrintf("\n"); - width = size; - } else - width += size; - - DebugPrintf("%s ", _dcmds[i].name); - } - - width = 0; - - DebugPrintf("\n\nVariables are:\n"); - for (i = 0 ; i < _dvar_count ; i++) { - size = strlen(_dvars[i].name) + 1; - - if ((width + size) >= 39) { - DebugPrintf("\n"); - width = size; - } else - width += size; - - DebugPrintf("%s ", _dvars[i].name); - } - - DebugPrintf("\n"); - - return true; -} - -bool Console::cmdActorWalkTo(int argc, const char **argv) { - if (argc != 4) - DebugPrintf("Usage: %s <Actor id> <lx> <ly>\n", argv[0]); - else - _vm->_actor->cmdActorWalkTo(argc, argv); - return true; -} - - -bool Console::Cmd_AnimInfo(int argc, const char **argv) { - _vm->_anim->animInfo(); - return true; -} - -bool Console::cmdSceneChange(int argc, const char **argv) { - if (argc != 2) - DebugPrintf("Usage: %s <Scene number>\n", argv[0]); - else - _vm->_scene->cmdSceneChange(argc, argv); - return true; -} - -bool Console::cmdActionMapInfo(int argc, const char **argv) { - _vm->_scene->cmdActionMapInfo(); - return true; -} - -bool Console::cmdObjectMapInfo(int argc, const char **argv) { - _vm->_scene->cmdObjectMapInfo(); - return true; -} - -} // End of namespace Saga diff --git a/saga/console.h b/saga/console.h deleted file mode 100644 index c93373960f..0000000000 --- a/saga/console.h +++ /dev/null @@ -1,62 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - - // Console module header file - -#ifndef SAGA_CONSOLE_H_ -#define SAGA_CONSOLE_H_ - -#include "common/debugger.h" - -namespace Saga { - -class Console : public Common::Debugger<Console> { -public: - Console(SagaEngine *vm); - virtual ~Console(void); - -protected: - virtual void preEnter(); - virtual void postEnter(); - -private: - bool Cmd_Exit(int argc, const char **argv); - bool Cmd_Help(int argc, const char **argv); - - bool cmdActorWalkTo(int argc, const char **argv); - - bool Cmd_AnimInfo(int argc, const char **argv); - - bool cmdSceneChange(int argc, const char **argv); - bool cmdActionMapInfo(int argc, const char **argv); - bool cmdObjectMapInfo(int argc, const char **argv); - - -private: - SagaEngine *_vm; -}; - -} // End of namespace Saga - -#endif diff --git a/saga/events.cpp b/saga/events.cpp deleted file mode 100644 index 0d1da65efb..0000000000 --- a/saga/events.cpp +++ /dev/null @@ -1,590 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Event management module - -#include "saga/saga.h" -#include "saga/gfx.h" - -#include "saga/animation.h" -#include "saga/console.h" -#include "saga/scene.h" -#include "saga/interface.h" -#include "saga/palanim.h" -#include "saga/render.h" -#include "saga/sndres.h" -#include "saga/music.h" -#include "saga/actor.h" - -#include "saga/events.h" - -namespace Saga { - -Events::Events(SagaEngine *vm) : _vm(vm), _initialized(false) { - debug(8, "Initializing event subsystem..."); - _initialized = true; -} - -Events::~Events(void) { - debug(8, "Shutting down event subsystem..."); - freeList(); -} - -// Function to process event list once per frame. -// First advances event times, then processes each event with the appropriate -// handler depending on the type of event. -int Events::handleEvents(long msec) { - Event *event_p; - - long delta_time; - int result; - - // Advance event times - processEventTime(msec); - - // Process each event in list - for (EventList::iterator eventi = _eventList.begin(); eventi != _eventList.end(); ++eventi) { - event_p = (Event *)eventi.operator->(); - - // Call the appropriate event handler for the specific event type - switch (event_p->type) { - - case kEvTOneshot: - result = handleOneShot(event_p); - break; - - case kEvTContinuous: - result = handleContinuous(event_p); - break; - - case kEvTInterval: - result = handleInterval(event_p); - break; - - case kEvTImmediate: - result = handleImmediate(event_p); - break; - - default: - result = kEvStInvalidCode; - warning("Invalid event code encountered"); - break; - } - - // Process the event appropriately based on result code from - // handler - if ((result == kEvStDelete) || (result == kEvStInvalidCode)) { - // If there is no event chain, delete the base event. - if (event_p->chain == NULL) { - eventi = _eventList.eraseAndPrev(eventi); - } else { - // If there is an event chain present, move the next event - // in the chain up, adjust it by the previous delta time, - // and reprocess the event - delta_time = event_p->time; - Event *from_chain = event_p->chain; - memcpy(event_p, from_chain, sizeof(*event_p)); - free(from_chain); - - event_p->time += delta_time; - --eventi; - } - } else if (result == kEvStBreak) { - break; - } - } - - return SUCCESS; -} - -int Events::handleContinuous(Event *event) { - double event_pc = 0.0; // Event completion percentage - int event_done = 0; - - Surface *backGroundSurface; - BGInfo bgInfo; - Rect rect; - if(event->duration != 0) { - event_pc = ((double)event->duration - event->time) / event->duration; - } else { - event_pc = 1.0; - } - - if (event_pc >= 1.0) { - // Cap percentage to 100 - event_pc = 1.0; - event_done = 1; - } - - if (event_pc < 0.0) { - // Event not signaled, skip it - return kEvStContinue; - } else if (!(event->code & kEvFSignaled)) { - // Signal event - event->code |= kEvFSignaled; - event_pc = 0.0; - } - - switch (event->code & EVENT_MASK) { - case kPalEvent: - switch (event->op) { - case kEventBlackToPal: - _vm->_gfx->blackToPal((PalEntry *)event->data, event_pc); - break; - - case kEventPalToBlack: - _vm->_gfx->palToBlack((PalEntry *)event->data, event_pc); - break; - default: - break; - } - break; - case kTransitionEvent: - switch (event->op) { - case kEventDissolve: - backGroundSurface = _vm->_render->getBackGroundSurface(); - _vm->_scene->getBGInfo(bgInfo); - rect.left = rect.top = 0; - rect.right = bgInfo.bounds.width(); - rect.bottom = bgInfo.bounds.height(); - backGroundSurface->transitionDissolve(bgInfo.buffer, rect, 0, event_pc); - break; - case kEventDissolveBGMask: - // we dissolve it centered. - // set flag of Dissolve to 1. It is a hack to simulate zero masking. - int w, h; - byte *maskBuffer; - size_t len; - - backGroundSurface = _vm->_render->getBackGroundSurface(); - _vm->_scene->getBGMaskInfo(w, h, maskBuffer, len); - rect.left = (_vm->getDisplayWidth() - w) / 2; - rect.top = (_vm->getDisplayHeight() - h) / 2; - rect.setWidth(w); - rect.setHeight(h); - - backGroundSurface->transitionDissolve( maskBuffer, rect, 1, event_pc); - break; - default: - break; - } - break; - default: - break; - - } - - if (event_done) { - return kEvStDelete; - } - - return kEvStContinue; -} - -int Events::handleImmediate(Event *event) { - double event_pc = 0.0; // Event completion percentage - bool event_done = false; - - // Duration might be 0 so dont do division then - if(event->duration != 0) { - event_pc = ((double)event->duration - event->time) / event->duration; - } else { - // Just make sure that event_pc is 1.0 so event_done is true - event_pc = 1.0; - } - - if (event_pc >= 1.0) { - // Cap percentage to 100 - event_pc = 1.0; - event_done = true; - } - - if (event_pc < 0.0) { - // Event not signaled, skip it - return kEvStBreak; - } else if (!(event->code & kEvFSignaled)) { - // Signal event - event->code |= kEvFSignaled; - event_pc = 0.0; - } - - switch (event->code & EVENT_MASK) { - case kPalEvent: - switch (event->op) { - case kEventBlackToPal: - _vm->_gfx->blackToPal((PalEntry *)event->data, event_pc); - break; - - case kEventPalToBlack: - _vm->_gfx->palToBlack((PalEntry *)event->data, event_pc); - break; - default: - break; - } - break; - case kScriptEvent: - case kBgEvent: - case kInterfaceEvent: - handleOneShot(event); - event_done = true; - break; - default: - break; - - } - - if (event_done) { - return kEvStDelete; - } - - return kEvStBreak; -} - -int Events::handleOneShot(Event *event) { - Surface *backBuffer; - ScriptThread *sthread; - Rect rect; - - - if (event->time > 0) { - return kEvStContinue; - } - - // Event has been signaled - - switch (event->code & EVENT_MASK) { - case kTextEvent: - switch (event->op) { - case kEventDisplay: - ((TextListEntry *)event->data)->display = true; - break; - case kEventRemove: - _vm->_scene->_textList.remove((TextListEntry *)event->data); - break; - default: - break; - } - - break; - case kSoundEvent: - _vm->_sound->stopSound(); - if (event->op == kEventPlay) - _vm->_sndRes->playSound(event->param, event->param2, event->param3 != 0); - break; - case kVoiceEvent: - _vm->_sndRes->playVoice(event->param); - break; - case kMusicEvent: - _vm->_music->stop(); - if (event->op == kEventPlay) - _vm->_music->play(event->param, (MusicFlags)event->param2); - break; - case kBgEvent: - { - Surface *backGroundSurface; - BGInfo bgInfo; - - if (!(_vm->_scene->getFlags() & kSceneFlagISO)) { - - backBuffer = _vm->_gfx->getBackBuffer(); - backGroundSurface = _vm->_render->getBackGroundSurface(); - _vm->_scene->getBGInfo(bgInfo); - - backGroundSurface->blit(bgInfo.bounds, bgInfo.buffer); - - // If it is inset scene then draw black border - if (bgInfo.bounds.width() < _vm->getDisplayWidth() || bgInfo.bounds.height() < _vm->_scene->getHeight()) { - Common::Rect rect1(2, bgInfo.bounds.height() + 4); - Common::Rect rect2(bgInfo.bounds.width() + 4, 2); - Common::Rect rect3(2, bgInfo.bounds.height() + 4); - Common::Rect rect4(bgInfo.bounds.width() + 4, 2); - rect1.moveTo(bgInfo.bounds.left - 2, bgInfo.bounds.top - 2); - rect2.moveTo(bgInfo.bounds.left - 2, bgInfo.bounds.top - 2); - rect3.moveTo(bgInfo.bounds.right, bgInfo.bounds.top - 2); - rect4.moveTo(bgInfo.bounds.left - 2, bgInfo.bounds.bottom); - - backGroundSurface->drawRect(rect1, kITEColorBlack); - backGroundSurface->drawRect(rect2, kITEColorBlack); - backGroundSurface->drawRect(rect3, kITEColorBlack); - backGroundSurface->drawRect(rect4, kITEColorBlack); - } - - if (event->param == kEvPSetPalette) { - PalEntry *palPointer; - _vm->_scene->getBGPal(palPointer); - _vm->_gfx->setPalette(palPointer); - } - } - } - break; - case kAnimEvent: - switch (event->op) { - case kEventPlay: - _vm->_anim->play(event->param, event->time, true); - break; - case kEventStop: - _vm->_anim->stop(event->param); - break; - case kEventFrame: - _vm->_anim->play(event->param, event->time, false); - break; - case kEventSetFlag: - _vm->_anim->setFlag(event->param, event->param2); - break; - case kEventClearFlag: - _vm->_anim->clearFlag(event->param, event->param2); - break; - default: - break; - } - break; - case kSceneEvent: - switch (event->op) { - case kEventEnd: - _vm->_scene->nextScene(); - return kEvStBreak; - break; - default: - break; - } - break; - case kPalAnimEvent: - switch (event->op) { - case kEventCycleStart: - _vm->_palanim->cycleStart(); - break; - case kEventCycleStep: - _vm->_palanim->cycleStep(event->time); - break; - default: - break; - } - break; - case kInterfaceEvent: - switch (event->op) { - case kEventActivate: - _vm->_interface->activate(); - break; - case kEventDeactivate: - _vm->_interface->deactivate(); - break; - case kEventSetStatus: - _vm->_interface->setStatusText((const char*)event->data); - _vm->_interface->drawStatusBar(); - break; - case kEventClearStatus: - _vm->_interface->setStatusText(""); - _vm->_interface->drawStatusBar(); - break; - case kEventSetFadeMode: - _vm->_interface->setFadeMode(event->param); - break; - default: - break; - } - break; - case kScriptEvent: - switch (event->op) { - case kEventExecBlocking: - case kEventExecNonBlocking: - debug(6, "Exec module number %d script entry number %d", event->param, event->param2); - - sthread = _vm->_script->createThread(event->param, event->param2); - if (sthread == NULL) { - _vm->_console->DebugPrintf("Thread creation failed.\n"); - break; - } - - sthread->_threadVars[kThreadVarAction] = event->param3; - sthread->_threadVars[kThreadVarObject] = event->param4; - sthread->_threadVars[kThreadVarWithObject] = event->param5; - sthread->_threadVars[kThreadVarActor] = event->param6; - - if (event->op == kEventExecBlocking) - _vm->_script->completeThread(); - - break; - case kEventThreadWake: - _vm->_script->wakeUpThreads(event->param); - break; - } - break; - case kCursorEvent: - switch (event->op) { - case kEventShow: - _vm->_gfx->showCursor(true); - break; - case kEventHide: - _vm->_gfx->showCursor(false); - break; - default: - break; - } - break; - case kGraphicsEvent: - switch (event->op) { - case kEventFillRect: - rect.top = event->param2; - rect.bottom = event->param3; - rect.left = event->param4; - rect.right = event->param5; - ((Surface *)event->data)->drawRect(rect, event->param); - break; - case kEventSetFlag: - _vm->_render->setFlag(event->param); - break; - case kEventClearFlag: - _vm->_render->clearFlag(event->param); - break; - default: - break; - } - default: - break; - } - - return kEvStDelete; -} - -int Events::handleInterval(Event *event) { - return kEvStDelete; -} - -// Schedules an event in the event list; returns a pointer to the scheduled -// event suitable for chaining if desired. -Event *Events::queue(Event *event) { - Event *queuedEvent; - - queuedEvent = _eventList.pushBack(*event).operator->(); - initializeEvent(queuedEvent); - - return queuedEvent; -} - -// Places a 'add_event' on the end of an event chain given by 'head_event' -// (head_event may be in any position in the event chain) -Event *Events::chain(Event *headEvent, Event *addEvent) { - if (headEvent == NULL) { - return queue(addEvent); - } - - Event *walkEvent; - for (walkEvent = headEvent; walkEvent->chain != NULL; walkEvent = walkEvent->chain) { - continue; - } - - walkEvent->chain = (Event *)malloc(sizeof(*walkEvent->chain)); - *walkEvent->chain = *addEvent; - initializeEvent(walkEvent->chain); - - return walkEvent->chain; -} - -int Events::initializeEvent(Event *event) { - event->chain = NULL; - switch (event->type) { - case kEvTOneshot: - break; - case kEvTContinuous: - case kEvTImmediate: - event->time += event->duration; - break; - case kEvTInterval: - break; - default: - return FAILURE; - break; - } - - return SUCCESS; -} - -int Events::clearList() { - Event *chain_walk; - Event *next_chain; - Event *event_p; - - // Walk down event list - for (EventList::iterator eventi = _eventList.begin(); eventi != _eventList.end(); ++eventi) { - event_p = (Event *)eventi.operator->(); - - // Only remove events not marked kEvFNoDestory (engine events) - if (!(event_p->code & kEvFNoDestory)) { - // Remove any events chained off this one */ - for (chain_walk = event_p->chain; chain_walk != NULL; chain_walk = next_chain) { - next_chain = chain_walk->chain; - free(chain_walk); - } - eventi = _eventList.eraseAndPrev(eventi); - } - } - - return SUCCESS; -} - -// Removes all events from the list (even kEvFNoDestory) -int Events::freeList() { - Event *chain_walk; - Event *next_chain; - Event *event_p; - - // Walk down event list - EventList::iterator eventi = _eventList.begin(); - while (eventi != _eventList.end()) { - event_p = (Event *)eventi.operator->(); - - // Remove any events chained off this one */ - for (chain_walk = event_p->chain; chain_walk != NULL; chain_walk = next_chain) { - next_chain = chain_walk->chain; - free(chain_walk); - } - eventi=_eventList.erase(eventi); - } - - return SUCCESS; -} - -// Walks down the event list, updating event times by 'msec'. -int Events::processEventTime(long msec) { - Event *event_p; - uint16 event_count = 0; - - for (EventList::iterator eventi = _eventList.begin(); eventi != _eventList.end(); ++eventi) { - event_p = (Event *)eventi.operator->(); - - event_p->time -= msec; - event_count++; - - if (event_p->type == kEvTImmediate) - break; - - if (event_count > EVENT_WARNINGCOUNT) { - warning("Event list exceeds %u", EVENT_WARNINGCOUNT); - } - } - - return SUCCESS; -} - -} // End of namespace Saga diff --git a/saga/events.h b/saga/events.h deleted file mode 100644 index d89b3d89f5..0000000000 --- a/saga/events.h +++ /dev/null @@ -1,179 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Event management module header file - -#ifndef SAGA_EVENT_H -#define SAGA_EVENT_H - -#include "saga/list.h" - -namespace Saga { - -enum EventTypes { - kEvTOneshot, // Event takes no time - kEvTContinuous, // Event takes time; next event starts immediately - kEvTInterval, // Not yet implemented - kEvTImmediate // Event takes time; next event starts when event is done -}; - -enum EventFlags { - kEvFSignaled = 0x8000, - kEvFNoDestory = 0x4000 -}; - -enum EventCodes { - kBgEvent = 1, - kAnimEvent, - kMusicEvent, - kVoiceEvent, - kSoundEvent, - kSceneEvent, - kTextEvent, - kPalEvent, - kPalAnimEvent, - kTransitionEvent, - kInterfaceEvent, - kActorEvent, - kScriptEvent, - kCursorEvent, - kGraphicsEvent -}; - -enum EventOps { - // INSTANTANEOUS events - // BG events - kEventDisplay = 1, - // ANIM events - // kEventPlay = 1, // reused - // kEventStop = 2, // reused - kEventFrame = 3, - kEventSetFlag = 4, - kEventClearFlag = 5, - // MUISC & SOUND events - kEventPlay = 1, - kEventStop = 2, - // SCENE events - kEventEnd = 2, - // TEXT events - kEventHide = 2, - kEventRemove = 3, - // PALANIM events - kEventCycleStart = 1, - kEventCycleStep = 2, - // INTERFACE events - kEventActivate = 1, - kEventDeactivate = 2, - kEventSetStatus = 3, - kEventClearStatus = 4, - kEventSetFadeMode = 5, - // ACTOR events - kEventMove = 1, - // SCRIPT events - kEventExecBlocking = 1, - kEventExecNonBlocking = 2, - kEventThreadWake = 3, - // CURSOR events - kEventShow = 1, - // kEventHide = 2, // reused - // GRAPHICS events - kEventFillRect = 1, - // kEventSetFlag = 4, // reused - // kEventClearFlag = 5, // reused - - // CONTINUOUS events - // PALETTE events - kEventPalToBlack = 1, - kEventBlackToPal = 2, - // TRANSITION events - kEventDissolve = 1, - kEventDissolveBGMask = 2 -}; - -enum EventParams { - kEvPNoSetPalette, - kEvPSetPalette -}; - -struct Event { - unsigned int type; - unsigned int code; // Event operation category & flags - int op; // Event operation - long param; // Optional event parameter - long param2; - long param3; - long param4; - long param5; - long param6; - void *data; // Optional event data - long time; // Elapsed time until event - long duration; // Duration of event - long d_reserved; - - Event *chain; // Event chain (For consecutive events) - Event() { - memset(this, 0, sizeof(*this)); - } -}; - -typedef SortedList<Event> EventList; - -#define EVENT_WARNINGCOUNT 1000 -#define EVENT_MASK 0x00FF - -enum EventStatusCode { - kEvStInvalidCode = 0, - kEvStDelete, - kEvStContinue, - kEvStBreak -}; - -class Events { - public: - Events(SagaEngine *vm); - ~Events(void); - int handleEvents(long msec); - int clearList(); - int freeList(); - Event *queue(Event *event); - Event *chain(Event *headEvent, Event *addEvent); - - private: - int handleContinuous(Event *event); - int handleOneShot(Event *event); - int handleInterval(Event *event); - int handleImmediate(Event *event); - int processEventTime(long msec); - int initializeEvent(Event *event); - - private: - SagaEngine *_vm; - bool _initialized; - - EventList _eventList; -}; - -} // End of namespace Saga - -#endif diff --git a/saga/font.cpp b/saga/font.cpp deleted file mode 100644 index 9a91bf4872..0000000000 --- a/saga/font.cpp +++ /dev/null @@ -1,681 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Font management and font drawing module -#include "saga/saga.h" -#include "saga/gfx.h" -#include "saga/rscfile.h" - -#include "saga/font.h" -#include "saga/stream.h" - -namespace Saga { - -Font::Font(SagaEngine *vm) : _vm(vm), _initialized(false) { - int i; - - // Load font module resource context - - assert(_vm->getFontsCount() > 0); - - _fonts = (FontData **)calloc(_vm->getFontsCount(), sizeof(*_fonts)); - _loadedFonts = 0; - - for (i = 0; i < _vm->getFontsCount(); i++) { - loadFont(_vm->getFontDescription(i)->fontResourceId); - } - - _initialized = true; -} - -Font::~Font(void) { - debug(8, "Font::~Font(): Freeing fonts."); - int i; - - for (i = 0 ; i < _loadedFonts ; i++) { - if (_fonts[i] != NULL) { - free(_fonts[i]->normal.font); - free(_fonts[i]->outline.font); - } - - free(_fonts[i]); - } -} - - -void Font::loadFont(uint32 fontResourceId) { - FontData *font; - byte *fontResourcePointer; - size_t fontResourceLength; - int numBits; - int c; - ResourceContext *fontContext; - - debug(1, "Font::loadFont(): Reading fontResourceId %d...", fontResourceId); - - fontContext = _vm->_resource->getContext(GAME_RESOURCEFILE); - if (fontContext == NULL) { - error("Font::Font() resource context not found"); - } - - // Load font resource - _vm->_resource->loadResource(fontContext, fontResourceId, fontResourcePointer, fontResourceLength); - - if (fontResourceLength < FONT_DESCSIZE) { - error("Font::loadFont() Invalid font length (%i < %i)", fontResourceLength, FONT_DESCSIZE); - } - - MemoryReadStreamEndian readS(fontResourcePointer, fontResourceLength, fontContext->isBigEndian); - - // Create new font structure - font = (FontData *)malloc(sizeof(*font)); - - // Read font header - font->normal.header.charHeight = readS.readUint16(); - font->normal.header.charWidth = readS.readUint16(); - font->normal.header.rowLength = readS.readUint16(); - - - debug(2, "Character width: %d", font->normal.header.charWidth); - debug(2, "Character height: %d", font->normal.header.charHeight); - debug(2, "Row padding: %d", font->normal.header.rowLength); - - for (c = 0; c < FONT_CHARCOUNT; c++) { - font->normal.fontCharEntry[c].index = readS.readUint16(); - } - - for (c = 0; c < FONT_CHARCOUNT; c++) { - numBits = font->normal.fontCharEntry[c].width = readS.readByte(); - font->normal.fontCharEntry[c].byteWidth = getByteLen(numBits); - } - - for (c = 0; c < FONT_CHARCOUNT; c++) { - font->normal.fontCharEntry[c].flag = readS.readByte(); - } - - for (c = 0; c < FONT_CHARCOUNT; c++) { - font->normal.fontCharEntry[c].tracking = readS.readByte(); - } - - if (readS.pos() != FONT_DESCSIZE) { - error("Invalid font resource size."); - } - - font->normal.font = (byte*)malloc(fontResourceLength - FONT_DESCSIZE); - memcpy(font->normal.font, fontResourcePointer + FONT_DESCSIZE, fontResourceLength - FONT_DESCSIZE); - - free(fontResourcePointer); - - - // Create outline font style - createOutline(font); - - // Set font data - _fonts[_loadedFonts++] = font; -} - -void Font::createOutline(FontData *font) { - int i; - int row; - int newByteWidth; - int oldByteWidth; - int newRowLength = 0; - size_t indexOffset = 0; - int index; - int currentByte; - unsigned char *basePointer; - unsigned char *srcPointer; - unsigned char *destPointer1; - unsigned char *destPointer2; - unsigned char *destPointer3; - unsigned char charRep; - - - // Populate new font style character data - for (i = 0; i < FONT_CHARCOUNT; i++) { - newByteWidth = 0; - oldByteWidth = 0; - index = font->normal.fontCharEntry[i].index; - if ((index > 0) || (i == FONT_FIRSTCHAR)) { - index += indexOffset; - } - - font->outline.fontCharEntry[i].index = index; - font->outline.fontCharEntry[i].tracking = font->normal.fontCharEntry[i].tracking; - font->outline.fontCharEntry[i].flag = font->normal.fontCharEntry[i].flag; - - if (font->normal.fontCharEntry[i].width != 0) { - newByteWidth = getByteLen(font->normal.fontCharEntry[i].width + 2); - oldByteWidth = getByteLen(font->normal.fontCharEntry[i].width); - - if (newByteWidth > oldByteWidth) { - indexOffset++; - } - } - - font->outline.fontCharEntry[i].width = font->normal.fontCharEntry[i].width + 2; - font->outline.fontCharEntry[i].byteWidth = newByteWidth; - newRowLength += newByteWidth; - } - - debug(2, "New row length: %d", newRowLength); - - font->outline.header = font->normal.header; - font->outline.header.charWidth += 2; - font->outline.header.charHeight += 2; - font->outline.header.rowLength = newRowLength; - - // Allocate new font representation storage - font->outline.font = (unsigned char *)calloc(newRowLength, font->outline.header.charHeight); - - - // Generate outline font representation - for (i = 0; i < FONT_CHARCOUNT; i++) { - for (row = 0; row < font->normal.header.charHeight; row++) { - for (currentByte = 0; currentByte < font->outline.fontCharEntry[i].byteWidth; currentByte++) { - basePointer = font->outline.font + font->outline.fontCharEntry[i].index + currentByte; - destPointer1 = basePointer + newRowLength * row; - destPointer2 = basePointer + newRowLength * (row + 1); - destPointer3 = basePointer + newRowLength * (row + 2); - if (currentByte > 0) { - // Get last two columns from previous byte - srcPointer = font->normal.font + font->normal.header.rowLength * row + font->normal.fontCharEntry[i].index + (currentByte - 1); - charRep = *srcPointer; - *destPointer1 |= ((charRep << 6) | (charRep << 7)); - *destPointer2 |= ((charRep << 6) | (charRep << 7)); - *destPointer3 |= ((charRep << 6) | (charRep << 7)); - } - - if (currentByte < font->normal.fontCharEntry[i].byteWidth) { - srcPointer = font->normal.font + font->normal.header.rowLength * row + font->normal.fontCharEntry[i].index + currentByte; - charRep = *srcPointer; - *destPointer1 |= charRep | (charRep >> 1) | (charRep >> 2); - *destPointer2 |= charRep | (charRep >> 1) | (charRep >> 2); - *destPointer3 |= charRep | (charRep >> 1) | (charRep >> 2); - } - } - } - - // "Hollow out" character to prevent overdraw - for (row = 0; row < font->normal.header.charHeight; row++) { - for (currentByte = 0; currentByte < font->outline.fontCharEntry[i].byteWidth; currentByte++) { - destPointer2 = font->outline.font + font->outline.header.rowLength * (row + 1) + font->outline.fontCharEntry[i].index + currentByte; - if (currentByte > 0) { - // Get last two columns from previous byte - srcPointer = font->normal.font + font->normal.header.rowLength * row + font->normal.fontCharEntry[i].index + (currentByte - 1); - *destPointer2 &= ((*srcPointer << 7) ^ 0xFFU); - } - - if (currentByte < font->normal.fontCharEntry[i].byteWidth) { - srcPointer = font->normal.font + font->normal.header.rowLength * row + font->normal.fontCharEntry[i].index + currentByte; - *destPointer2 &= ((*srcPointer >> 1) ^ 0xFFU); - } - } - } - } -} - -// Returns the horizontal length in pixels of the graphical representation -// of at most 'count' characters of the string 'text', taking -// into account any formatting options specified by 'flags'. -// If 'count' is 0, all characters of 'test' are counted. -int Font::getStringWidth(FontId fontId, const char *text, size_t count, FontEffectFlags flags) { - FontData *font; - size_t ct; - int width = 0; - int ch; - const byte *txt; - - - font = getFont(fontId); - - txt = (const byte *) text; - - for (ct = count; *txt && (!count || ct > 0); txt++, ct--) { - ch = *txt & 0xFFU; - // Translate character - ch = _charMap[ch]; - assert(ch < FONT_CHARCOUNT); - width += font->normal.fontCharEntry[ch].tracking; - } - - if ((flags & kFontBold) || (flags & kFontOutline)) { - width += 1; - } - - return width; -} - - -void Font::draw(FontId fontId, Surface *ds, const char *text, size_t count, const Common::Point &point, - int color, int effectColor, FontEffectFlags flags) { - FontData *font; - Point offsetPoint(point); - - font = getFont(fontId); - - if (flags & kFontOutline) { - offsetPoint.x--; - offsetPoint.y--; - outFont(font->outline, ds, text, count, offsetPoint, effectColor, flags); - outFont(font->normal, ds, text, count, point, color, flags); - } else if (flags & kFontShadow) { - offsetPoint.x--; - offsetPoint.y++; - outFont(font->normal, ds, text, count, offsetPoint, effectColor, flags); - outFont(font->normal, ds, text, count, point, color, flags); - } else { // FONT_NORMAL - outFont(font->normal, ds, text, count, point, color, flags); - } -} - -void Font::outFont(const FontStyle &drawFont, Surface *ds, const char *text, size_t count, const Common::Point &point, int color, FontEffectFlags flags) { - const byte *textPointer; - byte *c_dataPointer; - int c_code; - int charRow; - Point textPoint(point); - - byte *outputPointer; - byte *outputPointer_min; - byte *outputPointer_max; - - int row; - int rowLimit; - - int c_byte_len; - int c_byte; - int c_bit; - int ct; - - if ((point.x > ds->w) || (point.y > ds->h)) { - // Output string can't be visible - return; - } - - textPointer = (const byte *)text; - ct = count; - - // Draw string one character at a time, maximum of 'draw_str'_ct - // characters, or no limit if 'draw_str_ct' is 0 - for (; *textPointer && (!count || ct); textPointer++, ct--) { - c_code = *textPointer & 0xFFU; - - // Translate character - if (!(flags & kFontDontmap)) - c_code = _charMap[c_code]; - assert(c_code < FONT_CHARCOUNT); - - // Check if character is defined - if ((drawFont.fontCharEntry[c_code].index == 0) && (c_code != FONT_FIRSTCHAR)) { -#if FONT_SHOWUNDEFINED - if (c_code == FONT_CH_SPACE) { - textPoint.x += drawFont.fontCharEntry[c_code].tracking; - continue; - } - c_code = FONT_CH_QMARK; -#else - // Character code is not defined, but advance tracking - // ( Not defined if offset is 0, except for 33 ('!') which - // is defined ) - textPoint.x += drawFont.fontCharEntry[c_code].tracking; - continue; -#endif - } - - // Get length of character in bytes - c_byte_len = ((drawFont.fontCharEntry[c_code].width - 1) / 8) + 1; - rowLimit = (ds->h < (textPoint.y + drawFont.header.charHeight)) ? ds->h : textPoint.y + drawFont.header.charHeight; - charRow = 0; - - for (row = textPoint.y; row < rowLimit; row++, charRow++) { - // Clip negative rows */ - if (row < 0) { - continue; - } - - outputPointer = (byte *)ds->pixels + (ds->pitch * row) + textPoint.x; - outputPointer_min = (byte *)ds->pixels + (ds->pitch * row) + (textPoint.x > 0 ? textPoint.x : 0); - outputPointer_max = outputPointer + (ds->pitch - textPoint.x); - - // If character starts off the screen, jump to next character - if (outputPointer < outputPointer_min) { - break; - } - - c_dataPointer = drawFont.font + charRow * drawFont.header.rowLength + drawFont.fontCharEntry[c_code].index; - - for (c_byte = 0; c_byte < c_byte_len; c_byte++, c_dataPointer++) { - // Check each bit, draw pixel if bit is set - for (c_bit = 7; c_bit >= 0 && (outputPointer < outputPointer_max); c_bit--) { - if ((*c_dataPointer >> c_bit) & 0x01) { - *outputPointer = (byte)color; - } - outputPointer++; - } // end per-bit processing - } // end per-byte processing - } // end per-row processing - - // Advance tracking position - textPoint.x += drawFont.fontCharEntry[c_code].tracking; - } // end per-character processing -} - - -void Font::textDraw(FontId fontId, Surface *ds, const char *text, const Common::Point &point, int color, int effectColor, FontEffectFlags flags) { - int textWidth; - int textLength; - int fitWidth; - Common::Point textPoint(point); - - textLength = strlen(text); - - if (!(flags & kFontCentered)) { - // Text is not centered; No formatting required - draw(fontId, ds, text, textLength, point, color, effectColor, flags); - return; - } - - // Text is centered... format output - // Enforce minimum and maximum center points for centered text - if (textPoint.x < TEXT_CENTERLIMIT) { - textPoint.x = TEXT_CENTERLIMIT; - } - - if (textPoint.x > ds->w - TEXT_CENTERLIMIT) { - textPoint.x = ds->w - TEXT_CENTERLIMIT; - } - - if (textPoint.x < (TEXT_MARGIN * 2)) { - // Text can't be centered if it's too close to the margin - return; - } - - textWidth = getStringWidth(fontId, text, textLength, flags); - - if (textPoint.x < (ds->w / 2)) { - // Fit to right side - fitWidth = (textPoint.x - TEXT_MARGIN) * 2; - } else { - // Fit to left side - fitWidth = ((ds->w - TEXT_MARGIN) - textPoint.x) * 2; - } - - if (fitWidth < textWidth) { - warning("text too long to be displayed in one line"); - textWidth = fitWidth; - } - // Entire string fits, draw it - textPoint.x = textPoint.x - (textWidth / 2); - draw(fontId, ds, text, textLength, textPoint, color, effectColor, flags); -} - -int Font::getHeight(FontId fontId, const char *text, int width, FontEffectFlags flags) { - int textWidth; - int textLength; - int fitWidth; - const char *startPointer; - const char *searchPointer; - const char *measurePointer; - const char *foundPointer; - int len; - int w; - const char *endPointer; - int h; - int wc; - int w_total; - int len_total; - Common::Point textPoint; - Common::Point textPoint2; - - textLength = strlen(text); - - textWidth = getStringWidth(fontId, text, textLength, flags); - h = getHeight(fontId); - fitWidth = width; - - textPoint.x = (fitWidth / 2); - textPoint.y = 0; - - if (fitWidth >= textWidth) { - return h; - } - - // String won't fit on one line - w_total = 0; - len_total = 0; - wc = 0; - - startPointer = text; - measurePointer = text; - searchPointer = text; - endPointer = text + textLength; - - for (;;) { - foundPointer = strchr(searchPointer, ' '); - if (foundPointer == NULL) { - // Ran to the end of the buffer - len = endPointer - measurePointer; - } else { - len = foundPointer - measurePointer; - } - - w = getStringWidth(fontId, measurePointer, len, flags); - measurePointer = foundPointer; - - if ((w_total + w) > fitWidth) { - // This word won't fit - if (wc == 0) { - // The first word in the line didn't fit. Still print it - searchPointer = measurePointer + 1; - } - // Wrap what we've got and restart - textPoint.y += h + TEXT_LINESPACING; - if (foundPointer == NULL) { - // Since word hit NULL but fit, we are done - return textPoint.y + h; - } - w_total = 0; - len_total = 0; - wc = 0; - measurePointer = searchPointer; - startPointer = searchPointer; - } else { - // Word will fit ok - w_total += w; - len_total += len; - wc++; - if (foundPointer == NULL) { - // Since word hit NULL but fit, we are done - return textPoint.y + h; - } - searchPointer = measurePointer + 1; - } - } -} - -void Font::textDrawRect(FontId fontId, Surface *ds, const char *text, const Common::Rect &rect, int color, int effectColor, FontEffectFlags flags) { - int textWidth; - int textLength; - int fitWidth; - const char *startPointer; - const char *searchPointer; - const char *measurePointer; - const char *foundPointer; - int len; - int w; - const char *endPointer; - int h; - int wc; - int w_total; - int len_total; - Common::Point textPoint; - Common::Point textPoint2; - - textLength = strlen(text); - - textWidth = getStringWidth(fontId, text, textLength, flags); - fitWidth = rect.width(); - - textPoint.x = rect.left + (fitWidth / 2); - textPoint.y = rect.top; - - if (fitWidth >= textWidth) { - // Entire string fits, draw it - textPoint.x -= (textWidth / 2); - draw(fontId, ds, text, textLength, textPoint, color, effectColor, flags); - return; - } - - // String won't fit on one line - h = getHeight(fontId); - w_total = 0; - len_total = 0; - wc = 0; - - startPointer = text; - measurePointer = text; - searchPointer = text; - endPointer = text + textLength; - - for (;;) { - foundPointer = strchr(searchPointer, ' '); - if (foundPointer == NULL) { - // Ran to the end of the buffer - len = endPointer - measurePointer; - } else { - len = foundPointer - measurePointer; - } - - w = getStringWidth(fontId, measurePointer, len, flags); - measurePointer = foundPointer; - - if ((w_total + w) > fitWidth) { - // This word won't fit - if (wc == 0) { - w_total = fitWidth; - len_total = len; - } - - // Wrap what we've got and restart - textPoint2.x = textPoint.x - (w_total / 2); - textPoint2.y = textPoint.y; - draw(fontId, ds, startPointer, len_total, textPoint2, color, effectColor, flags); - textPoint.y += h + TEXT_LINESPACING; - if (textPoint.y >= rect.bottom) { - return; - } - w_total = 0; - len_total = 0; - if (wc == 0) { - searchPointer = measurePointer + 1; - } - wc = 0; - - // Advance the search pointer to the next non-space. - // Otherwise, the first "word" to be measured will be - // an empty string. Measuring or drawing a string of - // length 0 is interpreted as measure/draw the entire - // buffer, which certainly is not what we want here. - // - // This happes because a string may contain several - // spaces in a row, e.g. after a period. - - while (*searchPointer == ' ') - searchPointer++; - - measurePointer = searchPointer; - startPointer = searchPointer; - } else { - // Word will fit ok - w_total += w; - len_total += len; - wc++; - if (foundPointer == NULL) { - // Since word hit NULL but fit, we are done - textPoint2.x = textPoint.x - (w_total / 2); - textPoint2.y = textPoint.y; - draw(fontId, ds, startPointer, len_total, textPoint2, color, - effectColor, flags); - return; - } - searchPointer = measurePointer + 1; - } - } -} - -Font::FontId Font::knownFont2FontIdx(KnownFont font) { - FontId fontId = kSmallFont; - - if (_vm->getGameType() == GType_ITE) { - switch (font) - { - case (kKnownFontSmall): - fontId = kSmallFont; - break; - case (kKnownFontMedium): - fontId = kMediumFont; - break; - case (kKnownFontBig): - fontId = kBigFont; - break; - - case (kKnownFontVerb): - fontId = kSmallFont; - break; - case (kKnownFontScript): - fontId = kMediumFont; - break; - case (kKnownFontPause): - fontId = _vm->_font->valid(kBigFont) ? kBigFont : kMediumFont; - break; - } - } else if (_vm->getGameType() == GType_IHNM) { - switch (font) - { - case (kKnownFontSmall): - fontId = kSmallFont; - break; - case (kKnownFontMedium): - fontId = kMediumFont; - break; - case (kKnownFontBig): - fontId = kBigFont; - break; - - case (kKnownFontVerb): - fontId = kIHNMFont8; - break; - case (kKnownFontScript): - fontId = kIHNMMainFont; - break; - case (kKnownFontPause): - fontId = kMediumFont; // unchecked - break; - } - } - return fontId; -} - -} // End of namespace Saga diff --git a/saga/font.h b/saga/font.h deleted file mode 100644 index f7f2113808..0000000000 --- a/saga/font.h +++ /dev/null @@ -1,205 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Font management and font drawing header file - -#ifndef SAGA_FONT_H__ -#define SAGA_FONT_H__ - -#include "saga/list.h" -#include "saga/gfx.h" - -namespace Saga { - -#define FONT_SHOWUNDEFINED 1 // Define to draw undefined characters * as ?'s - -// The first defined character (!) is the only one that may -// have a valid offset of '0' -#define FONT_FIRSTCHAR 33 - -#define FONT_CH_SPACE 32 -#define FONT_CH_QMARK 63 - -// Minimum font header size without font data -// (6 + 512 + 256 + 256 + 256 ) -#define FONT_DESCSIZE 1286 - -#define FONT_CHARCOUNT 256 -#define FONT_CHARMASK 0xFFU - -#define SAGA_FONT_HEADER_LEN 6 - -#define TEXT_CENTERLIMIT 50 -#define TEXT_MARGIN 10 -#define TEXT_LINESPACING 2 - -enum FontEffectFlags { - kFontNormal = 0, - kFontOutline = 1 << 0, - kFontShadow = 1 << 1, - kFontBold = 1 << 2, - kFontCentered = 1 << 3, - kFontDontmap = 1 << 4 -}; - -enum KnownFont { - kKnownFontSmall, - kKnownFontMedium, - kKnownFontBig, - - kKnownFontPause, - kKnownFontScript, - kKnownFontVerb -}; - -struct TextListEntry { - bool display; - bool useRect; - Common::Point point; - Common::Rect rect; - KnownColor knownColor; - KnownColor effectKnownColor; - FontEffectFlags flags; - KnownFont font; - const char *text; - TextListEntry() { - memset(this, 0, sizeof(*this)); - } -}; - -class TextList: public SortedList<TextListEntry> { -public: - - TextListEntry *addEntry(const TextListEntry &entry) { - return pushBack(entry).operator->(); - } -}; - -struct FontHeader { - int charHeight; - int charWidth; - int rowLength; -}; - -struct FontCharEntry { - int index; - int byteWidth; - int width; - int flag; - int tracking; -}; - -struct FontStyle { - FontHeader header; - FontCharEntry fontCharEntry[256]; - byte *font; -}; - -struct FontData { - FontStyle normal; - FontStyle outline; -}; - -class Font { - public: - Font(SagaEngine *vm); - ~Font(void); - int getStringWidth(KnownFont font, const char *text, size_t count, FontEffectFlags flags) { - return getStringWidth(knownFont2FontIdx(font), text, count, flags); - } - int getHeight(KnownFont font) { - return getHeight(knownFont2FontIdx(font)); - } - int getHeight(KnownFont font, const char *text, int width, FontEffectFlags flags) { - return getHeight(knownFont2FontIdx(font), text, width, flags); - } - void textDraw(KnownFont font, Surface *ds, const char *string, const Common::Point &point, int color, int effectColor, FontEffectFlags flags) { - textDraw(knownFont2FontIdx(font), ds, string, point, color, effectColor, flags); - } - void textDrawRect(KnownFont font, Surface *ds, const char *text, const Common::Rect &rect, int color, int effectColor, FontEffectFlags flags) { - textDrawRect(knownFont2FontIdx(font), ds, text, rect, color, effectColor, flags); - } - - private: - enum FontId { - kSmallFont, - kMediumFont, - kBigFont, - kIHNMUnknown, - kIHNMFont8, - kIHNMUnknown2, - kIHNMMainFont - }; - - Font::FontId knownFont2FontIdx(KnownFont font); - - int getStringWidth(FontId fontId, const char *text, size_t count, FontEffectFlags flags); - int getHeight(FontId fontId, const char *text, int width, FontEffectFlags flags); - void textDrawRect(FontId fontId, Surface *ds, const char *text, const Common::Rect &rect, int color, int effectColor, FontEffectFlags flags); - void textDraw(FontId fontId, Surface *ds, const char *string, const Common::Point &point, int color, int effectColor, FontEffectFlags flags); - - void loadFont(uint32 fontResourceId); - void createOutline(FontData *font); - void draw(FontId fontId, Surface *ds, const char *text, size_t count, const Common::Point &point, int color, int effectColor, FontEffectFlags flags); - void outFont(const FontStyle &drawFont, Surface *ds, const char *text, size_t count, const Common::Point &point, int color, FontEffectFlags flags); - - FontData *getFont(FontId fontId) { - validate(fontId); - return _fonts[fontId]; - } - - int getHeight(FontId fontId) { - return getFont(fontId)->normal.header.charHeight; - } - - void validate(FontId fontId) { - if (!valid(fontId)) { - error("Font::validate: Invalid font id."); - } - } - bool valid(FontId fontId) { - return ((fontId >= 0) && (fontId < _loadedFonts)); - } - int getByteLen(int numBits) const { - int byteLength = numBits / 8; - - if (numBits % 8) { - byteLength++; - } - - return byteLength; - } - - static const int _charMap[256]; - SagaEngine *_vm; - - bool _initialized; - - int _loadedFonts; - FontData **_fonts; -}; - -} // End of namespace Saga - -#endif diff --git a/saga/font_map.cpp b/saga/font_map.cpp deleted file mode 100644 index 04e3400b2e..0000000000 --- a/saga/font_map.cpp +++ /dev/null @@ -1,293 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Font module character mapping table ( MS CP-850 to ISO 8859-1 ) - -// Translation table derived from http://www.kostis.net/charsets/ - -#include "saga/saga.h" -#include "saga/font.h" - -namespace Saga { - -const int Font::_charMap[256] = { - 0, // 0 - 1, // 1 - 2, // 2 - 3, // 3 - 4, // 4 - 5, // 5 - 6, // 6 - 7, // 7 - 8, // 8 - 9, // 9 - 10, // 10 - 11, // 11 - 12, // 12 - 13, // 13 - 14, // 14 - 15, // 15 - 16, // 16 - 17, // 17 - 18, // 18 - 19, // 19 - 20, // 20 - 21, // 21 - 22, // 22 - 23, // 23 - 24, // 24 - 25, // 25 - 26, // 26 - 27, // 27 - 28, // 28 - 29, // 29 - 30, // 30 - 31, // 31 - 32, // 32 - 33, // 33 - 34, // 34 - 35, // 35 - 36, // 36 - 37, // 37 - 38, // 38 - 39, // 39 - 40, // 40 - 41, // 41 - 42, // 42 - 43, // 43 - 44, // 44 - 45, // 45 - 46, // 46 - 47, // 47 - 48, // 48 - 49, // 49 - 50, // 50 - 51, // 51 - 52, // 52 - 53, // 53 - 54, // 54 - 55, // 55 - 56, // 56 - 57, // 57 - 58, // 58 - 59, // 59 - 60, // 60 - 61, // 61 - 62, // 62 - 63, // 63 - 64, // 64 - 65, // 65 - 66, // 66 - 67, // 67 - 68, // 68 - 69, // 69 - 70, // 70 - 71, // 71 - 72, // 72 - 73, // 73 - 74, // 74 - 75, // 75 - 76, // 76 - 77, // 77 - 78, // 78 - 79, // 79 - 80, // 80 - 81, // 81 - 82, // 82 - 83, // 83 - 84, // 84 - 85, // 85 - 86, // 86 - 87, // 87 - 88, // 88 - 89, // 89 - 90, // 90 - 91, // 91 - 92, // 92 - 93, // 93 - 94, // 94 - 95, // 95 - 96, // 96 - 97, // 97 - 98, // 98 - 99, // 99 - 100, // 100 - 101, // 101 - 102, // 102 - 103, // 103 - 104, // 104 - 105, // 105 - 106, // 106 - 107, // 107 - 108, // 108 - 109, // 109 - 110, // 110 - 111, // 111 - 112, // 112 - 113, // 113 - 114, // 114 - 115, // 115 - 116, // 116 - 117, // 117 - 118, // 118 - 119, // 119 - 120, // 120 - 121, // 121 - 122, // 122 - 123, // 123 - 124, // 124 - 125, // 125 - 126, // 126 - 127, // 127 - 199, // 128 LATIN CAPITAL LETTER C WITH CEDILLA - 252, // 129 LATIN SMALL LETTER U WITH DIAERESIS - 233, // 130 LATIN SMALL LETTER E WITH ACUTE - 226, // 131 LATIN SMALL LETTER A WITH CIRCUMFLEX - 228, // 132 LATIN SMALL LETTER A WITH DIAERESIS - 224, // 133 LATIN SMALL LETTER A WITH GRAVE - 229, // 134 LATIN SMALL LETTER A WITH RING ABOVE - 231, // 135 LATIN SMALL LETTER C WITH CEDILLA - 234, // 136 LATIN SMALL LETTER E WITH CIRCUMFLEX - 235, // 137 LATIN SMALL LETTER E WITH DIAERESIS - 232, // 138 LATIN SMALL LETTER E WITH GRAVE - 239, // 139 LATIN SMALL LETTER I WITH DIAERESIS - 238, // 140 LATIN SMALL LETTER I WITH CIRCUMFLEX - 236, // 141 LATIN SMALL LETTER I WITH GRAVE - 196, // 142 LATIN CAPITAL LETTER A WITH DIAERESIS - 197, // 143 LATIN CAPITAL LETTER A WITH RING ABOVE - 201, // 144 LATIN CAPITAL LETTER E WITH ACUTE - 230, // 145 LATIN SMALL LETTER AE - 198, // 146 LATIN CAPITAL LETTER AE - 244, // 147 LATIN SMALL LETTER O WITH CIRCUMFLEX - 246, // 148 LATIN SMALL LETTER O WITH DIAERESIS - 242, // 149 LATIN SMALL LETTER O WITH GRAVE - 251, // 150 LATIN SMALL LETTER U WITH CIRCUMFLEX - 249, // 151 LATIN SMALL LETTER U WITH GRAVE - 255, // 152 LATIN SMALL LETTER Y WITH DIAERESIS - 214, // 153 LATIN CAPITAL LETTER O WITH DIAERESIS - 220, // 154 LATIN CAPITAL LETTER U WITH DIAERESIS - 248, // 155 LATIN SMALL LETTER O WITH STROKE - 163, // 156 POUND SIGN - 216, // 157 LATIN CAPITAL LETTER O WITH STROKE - 215, // 158 MULTIPLICATION SIGN - 0, // 159 LATIN SMALL LETTER F WITH HOOK - 225, // 160 LATIN SMALL LETTER A WITH ACUTE - 237, // 161 LATIN SMALL LETTER I WITH ACUTE - 243, // 162 LATIN SMALL LETTER O WITH ACUTE - 250, // 163 LATIN SMALL LETTER U WITH ACUTE - 241, // 164 LATIN SMALL LETTER N WITH TILDE - 209, // 165 LATIN CAPITAL LETTER N WITH TILDE - 170, // 166 FEMININE ORDINAL INDICATOR - 186, // 167 MASCULINE ORDINAL INDICATOR - 191, // 168 INVERTED QUESTION MARK - 174, // 169 REGISTERED SIGN - 172, // 170 NOT SIGN - 189, // 171 VULGAR FRACTION ONE HALF - 188, // 172 VULGAR FRACTION ONE QUARTER - 161, // 173 INVERTED EXCLAMATION MARK - 171, // 174 LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - 187, // 175 RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - 0, // 176 LIGHT SHADE - 0, // 177 MEDIUM SHADE - 0, // 178 DARK SHADE - 0, // 179 BOX DRAWINGS LIGHT VERTICAL - 0, // 180 BOX DRAWINGS LIGHT VERTICAL AND LEFT - 193, // 181 LATIN CAPITAL LETTER A WITH ACUTE - 194, // 182 LATIN CAPITAL LETTER A WITH CIRCUMFLEX - 192, // 183 LATIN CAPITAL LETTER A WITH GRAVE - 169, // 184 COPYRIGHT SIGN - 0, // 185 BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0, // 186 BOX DRAWINGS DOUBLE VERTICAL - 0, // 187 BOX DRAWINGS DOUBLE DOWN AND LEFT - 0, // 188 BOX DRAWINGS DOUBLE UP AND LEFT - 162, // 189 CENT SIGN - 165, // 190 YEN SIGN - 0, // 191 BOX DRAWINGS LIGHT DOWN AND LEFT - 0, // 192 BOX DRAWINGS LIGHT UP AND RIGHT - 0, // 193 BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0, // 194 BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0, // 195 BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0, // 196 BOX DRAWINGS LIGHT HORIZONTAL - 0, // 197 BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 227, // 198 LATIN SMALL LETTER A WITH TILDE - 195, // 199 LATIN CAPITAL LETTER A WITH TILDE - 0, // 200 BOX DRAWINGS DOUBLE UP AND RIGHT - 0, // 201 BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0, // 202 BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0, // 203 BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0, // 204 BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0, // 205 BOX DRAWINGS DOUBLE HORIZONTAL - 0, // 206 BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 164, // 207 CURRENCY SIGN - 240, // 208 LATIN SMALL LETTER ETH - 208, // 209 LATIN CAPITAL LETTER ETH - 202, // 210 LATIN CAPITAL LETTER E WITH CIRCUMFLEX - 203, // 211 LATIN CAPITAL LETTER E WITH DIAERESIS - 200, // 212 LATIN CAPITAL LETTER E WITH GRAVE - 305, // 213 LATIN SMALL LETTER DOTLESS I - 205, // 214 LATIN CAPITAL LETTER I WITH ACUTE - 206, // 215 LATIN CAPITAL LETTER I WITH CIRCUMFLEX - 207, // 216 LATIN CAPITAL LETTER I WITH DIAERESIS - 0, // 217 BOX DRAWINGS LIGHT UP AND LEFT - 0, // 218 BOX DRAWINGS LIGHT DOWN AND RIGHT - 0, // 219 FULL BLOCK - 0, // 220 LOWER HALF BLOCK - 166, // 221 BROKEN BAR - 204, // 222 LATIN CAPITAL LETTER I WITH GRAVE - 0, // 223 UPPER HALF BLOCK - 211, // 224 LATIN CAPITAL LETTER O WITH ACUTE - 223, // 225 LATIN SMALL LETTER SHARP S - 212, // 226 LATIN CAPITAL LETTER O WITH CIRCUMFLEX - 210, // 227 LATIN CAPITAL LETTER O WITH GRAVE - 245, // 228 LATIN SMALL LETTER O WITH TILDE - 213, // 229 LATIN CAPITAL LETTER O WITH TILDE - 181, // 230 MICRO SIGN - 254, // 231 LATIN SMALL LETTER THORN - 222, // 232 LATIN CAPITAL LETTER THORN - 218, // 233 LATIN CAPITAL LETTER U WITH ACUTE - 219, // 234 LATIN CAPITAL LETTER U WITH CIRCUMFLEX - 217, // 235 LATIN CAPITAL LETTER U WITH GRAVE - 253, // 236 LATIN SMALL LETTER Y WITH ACUTE - 221, // 237 LATIN CAPITAL LETTER Y WITH ACUTE - 175, // 238 MACRON - 180, // 239 ACUTE ACCENT - 173, // 240 SOFT HYPHEN - 177, // 241 PLUS-MINUS SIGN - 0, // 242 DOUBLE LOW LINE - 190, // 243 VULGAR FRACTION THREE QUARTERS - 182, // 244 PILCROW SIGN - 167, // 245 SECTION SIGN - 247, // 246 DIVISION SIGN - 184, // 247 CEDILLA - 176, // 248 DEGREE SIGN - 168, // 249 DIAERESIS - 183, // 250 MIDDLE DOT - 185, // 251 SUPERSCRIPT ONE - 179, // 252 SUPERSCRIPT THREE - 178, // 253 SUPERSCRIPT TWO - 0, // 254 BLACK SQUARE - 160 // 255 NO-BREAK SPACE -}; - -} // End of namespace Saga diff --git a/saga/game.cpp b/saga/game.cpp deleted file mode 100644 index 86526fe267..0000000000 --- a/saga/game.cpp +++ /dev/null @@ -1,1790 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Game detection, general game parameters - -#include "saga/saga.h" - -#include "common/file.h" -#include "common/md5.h" -#include "common/map.h" -#include "common/config-manager.h" -#include "base/plugins.h" -#include "base/gameDetector.h" -#include "backends/fs/fs.h" - -#include "saga/rscfile.h" -#include "saga/interface.h" -#include "saga/scene.h" -#include "saga/resnames.h" - -#define ITE_CONVERSE_MAX_TEXT_WIDTH (256 - 60) -#define ITE_CONVERSE_TEXT_HEIGHT 10 -#define ITE_CONVERSE_TEXT_LINES 4 - -//TODO: ihnm -#define IHNM_CONVERSE_MAX_TEXT_WIDTH (256 - 60) -#define IHNM_CONVERSE_TEXT_HEIGHT 10 -#define IHNM_CONVERSE_TEXT_LINES 10 - -namespace Saga { - -static int detectGame(const FSList &fslist, bool mode = false, int start = -1); - -// ITE section -static PanelButton ITE_MainPanelButtons[] = { - {kPanelButtonVerb, 52,4, 57,10, kVerbITEWalkTo,'w',0, 0,1,0}, - {kPanelButtonVerb, 52,15, 57,10, kVerbITELookAt,'l',0, 2,3,0}, - {kPanelButtonVerb, 52,26, 57,10, kVerbITEPickUp,'p',0, 4,5,0}, - {kPanelButtonVerb, 52,37, 57,10, kVerbITETalkTo,'t',0, 0,1,0}, - {kPanelButtonVerb, 110,4, 56,10, kVerbITEOpen,'o',0, 6,7,0}, - {kPanelButtonVerb, 110,15, 56,10, kVerbITEClose,'c',0, 8,9,0}, - {kPanelButtonVerb, 110,26, 56,10, kVerbITEUse,'u',0, 10,11,0}, - {kPanelButtonVerb, 110,37, 56,10, kVerbITEGive,'g',0, 12,13,0}, - {kPanelButtonArrow, 306,6, 8,5, -1,'U',0, 0,4,2}, - {kPanelButtonArrow, 306,41, 8,5, 1,'D',0, 1,5,3}, - - {kPanelButtonInventory, 181 + 32*0,6, 27,18, 0,'-',0, 0,0,0}, - {kPanelButtonInventory, 181 + 32*1,6, 27,18, 1,'-',0, 0,0,0}, - {kPanelButtonInventory, 181 + 32*2,6, 27,18, 2,'-',0, 0,0,0}, - {kPanelButtonInventory, 181 + 32*3,6, 27,18, 3,'-',0, 0,0,0}, - - {kPanelButtonInventory, 181 + 32*0,27, 27,18, 4,'-',0, 0,0,0}, - {kPanelButtonInventory, 181 + 32*1,27, 27,18, 5,'-',0, 0,0,0}, - {kPanelButtonInventory, 181 + 32*2,27, 27,18, 6,'-',0, 0,0,0}, - {kPanelButtonInventory, 181 + 32*3,27, 27,18, 7,'-',0, 0,0,0} -}; - -static PanelButton ITE_ConversePanelButtons[] = { - {kPanelButtonConverseText, 52,6 + ITE_CONVERSE_TEXT_HEIGHT * 0, ITE_CONVERSE_MAX_TEXT_WIDTH,ITE_CONVERSE_TEXT_HEIGHT, 0,'1',0, 0,0,0}, - {kPanelButtonConverseText, 52,6 + ITE_CONVERSE_TEXT_HEIGHT * 1, ITE_CONVERSE_MAX_TEXT_WIDTH,ITE_CONVERSE_TEXT_HEIGHT, 1,'2',0, 0,0,0}, - {kPanelButtonConverseText, 52,6 + ITE_CONVERSE_TEXT_HEIGHT * 2, ITE_CONVERSE_MAX_TEXT_WIDTH,ITE_CONVERSE_TEXT_HEIGHT, 2,'3',0, 0,0,0}, - {kPanelButtonConverseText, 52,6 + ITE_CONVERSE_TEXT_HEIGHT * 3, ITE_CONVERSE_MAX_TEXT_WIDTH,ITE_CONVERSE_TEXT_HEIGHT, 3,'4',0, 0,0,0}, - {kPanelButtonArrow, 257,6, 9,6, -1,'u',0, 0,4,2}, - {kPanelButtonArrow, 257,41, 9,6, 1,'d',0, 1,5,3}, -}; - -static PanelButton ITE_OptionPanelButtons[] = { - {kPanelButtonOptionSlider, 284,19, 13,75, 0,'-',0, 0,0,0}, //slider-scroller - {kPanelButtonOption, 113,18, 45,17, kTextReadingSpeed,'r',0, 0,0,0}, //read speed - {kPanelButtonOption, 113,37, 45,17, kTextMusic,'m',0, 0,0,0}, //music - {kPanelButtonOption, 113,56, 45,17, kTextSound,'n',0, 0,0,0}, //sound-noise - {kPanelButtonOption, 13,79, 135,17, kTextQuitGame,'q',0, 0,0,0}, //quit - {kPanelButtonOption, 13,98, 135,17, kTextContinuePlaying,'c',0, 0,0,0}, //continue - {kPanelButtonOption, 164,98, 57,17, kTextLoad,'l',0, 0,0,0}, //load - {kPanelButtonOption, 241,98, 57,17, kTextSave,'s',0, 0,0,0}, //save - {kPanelButtonOptionSaveFiles, 166,20, 112,74, 0,'-',0, 0,0,0}, //savefiles - - {kPanelButtonOptionText,106,4, 0,0, kTextGameOptions,'-',0, 0,0,0}, // text: game options - {kPanelButtonOptionText,11,22, 0,0, kTextReadingSpeed,'-',0, 0,0,0}, // text: read speed - {kPanelButtonOptionText,28,22, 0,0, kTextShowDialog,'-',0, 0,0,0}, // text: read speed - {kPanelButtonOptionText,73,41, 0,0, kTextMusic,'-',0, 0,0,0}, // text: music - {kPanelButtonOptionText,69,60, 0,0, kTextSound,'-',0, 0,0,0}, // text: noise -}; - -static PanelButton ITE_QuitPanelButtons[] = { - {kPanelButtonQuit, 11,17, 60,16, kTextQuit,'q',0, 0,0,0}, - {kPanelButtonQuit, 121,17, 60,16, kTextCancel,'c',0, 0,0,0}, - {kPanelButtonQuitText, -1,5, 0,0, kTextQuitTheGameQuestion,'-',0, 0,0,0}, -}; - -static PanelButton ITE_LoadPanelButtons[] = { - {kPanelButtonLoad, 101,19, 60,16, kTextOK,'o',0, 0,0,0}, - {kPanelButtonLoadText, -1,5, 0,0, kTextLoadSuccessful,'-',0, 0,0,0}, -}; - -static PanelButton ITE_SavePanelButtons[] = { - {kPanelButtonSave, 11,37, 60,16, kTextSave,'s',0, 0,0,0}, - {kPanelButtonSave, 101,37, 60,16, kTextCancel,'c',0, 0,0,0}, - {kPanelButtonSaveEdit, 26,17, 119,17, 0,'-',0, 0,0,0}, - {kPanelButtonSaveText, -1,5, 0,0, kTextEnterSaveGameName,'-',0, 0,0,0}, -}; - -static PanelButton ITE_ProtectPanelButtons[] = { - {kPanelButtonProtectEdit, 26,17, 119,17, 0,'-',0, 0,0,0}, - {kPanelButtonProtectText, -1,5, 0,0, kTextEnterProtectAnswer,'-',0, 0,0,0}, -}; - -/* -static PanelButton ITE_ProtectionPanelButtons[] = { - {kPanelButtonArrow, 0,0, 0,0, 0,'-',0, 0,0,0}, //TODO -};*/ - -static GameDisplayInfo ITE_DisplayInfo = { - 320, 200, // logical width&height - - 35, // scene path y offset - 137, // scene height - - 0, // status x offset - 137, // status y offset - 320, // status width - 11, // status height - 2, // status text y offset - 186, // status text color - 15, // status BG color - 308,137, // save reminder pos - 12,12, // save reminder w & h - 6,7, // save reminder sprite numbers - - 5, 4, // left portrait x, y offset - 274, 4, // right portrait x, y offset - - 8, 9, // inventory Up & Down button indexies - 2, 4, // inventory rows, columns - - 0, 148, // main panel offsets - ARRAYSIZE(ITE_MainPanelButtons), - ITE_MainPanelButtons, - - ITE_CONVERSE_MAX_TEXT_WIDTH, - ITE_CONVERSE_TEXT_HEIGHT, - ITE_CONVERSE_TEXT_LINES, - 4, 5, // converse Up & Down button indexies - 0, 148, // converse panel offsets - ARRAYSIZE(ITE_ConversePanelButtons), - ITE_ConversePanelButtons, - - 8, 0, // save file index - 8, // optionSaveFileVisible - 8, 8, // option panel offsets - ARRAYSIZE(ITE_OptionPanelButtons), - ITE_OptionPanelButtons, - - 64,54, // quit panel offsets - 192,38, // quit panel width & height - ARRAYSIZE(ITE_QuitPanelButtons), - ITE_QuitPanelButtons, - - 74, 53, // load panel offsets - 172, 40, // load panel width & height - ARRAYSIZE(ITE_LoadPanelButtons), - ITE_LoadPanelButtons, - - 2, // save edit index - 74, 44, // save panel offsets - 172, 58, // save panel width & height - ARRAYSIZE(ITE_SavePanelButtons), - ITE_SavePanelButtons, - - 0, // protect edit index - 74, 44, // protect panel offsets - 172, 58, // protect panel width & height - ARRAYSIZE(ITE_ProtectPanelButtons), - ITE_ProtectPanelButtons -}; - -static GameResourceDescription ITE_Resources = { - RID_ITE_SCENE_LUT, // Scene lookup table RN - RID_ITE_SCRIPT_LUT, // Script lookup table RN - RID_ITE_MAIN_PANEL, - RID_ITE_CONVERSE_PANEL, - RID_ITE_OPTION_PANEL, - RID_ITE_MAIN_SPRITES, - RID_ITE_MAIN_PANEL_SPRITES, - RID_ITE_DEFAULT_PORTRAITS, - RID_ITE_MAIN_STRINGS, - RID_ITE_ACTOR_NAMES -}; - -static GameResourceDescription ITEDemo_Resources = { - RID_ITEDEMO_SCENE_LUT, // Scene lookup table RN - RID_ITEDEMO_SCRIPT_LUT, // Script lookup table RN - RID_ITEDEMO_MAIN_PANEL, - RID_ITEDEMO_CONVERSE_PANEL, - RID_ITEDEMO_OPTION_PANEL, - RID_ITEDEMO_MAIN_SPRITES, - RID_ITEDEMO_MAIN_PANEL_SPRITES, - RID_ITEDEMO_DEFAULT_PORTRAITS, - RID_ITEDEMO_MAIN_STRINGS, - RID_ITEDEMO_ACTOR_NAMES -}; - -// Inherit the Earth - DOS Demo version -static GameFileDescription ITEDEMO_GameFiles[] = { - {"ite.rsc", GAME_RESOURCEFILE}, - //{"ite.dmo", GAME_DEMOFILE}, - {"scripts.rsc", GAME_SCRIPTFILE}, - {"voices.rsc", GAME_SOUNDFILE | GAME_VOICEFILE} -}; - -static GameFontDescription ITEDEMO_GameFonts[] = { - {0}, - {1} -}; - -static GameSoundInfo ITEDEMO_GameSound = { - kSoundVOC, - -1, - -1, - false, - false, - true -}; - -// Inherit the Earth - Wyrmkeep Win32 Demo version -static GameFileDescription ITEWINDEMO_GameFiles[] = { - {"ited.rsc", GAME_RESOURCEFILE}, - {"scriptsd.rsc", GAME_SCRIPTFILE}, - {"soundsd.rsc", GAME_SOUNDFILE}, - {"voicesd.rsc", GAME_VOICEFILE} -}; - -static GameFontDescription ITEWINDEMO_GameFonts[] = { - {2}, - {0} -}; - -static GameSoundInfo ITEWINDEMO1_GameSound = { - kSoundPCM, - 22050, - 8, - false, - false, - false -}; - -static GameSoundInfo ITEWINDEMO2_GameVoice = { - kSoundVOX, - 22050, - 16, - false, - false, - true -}; - -static GameSoundInfo ITEWINDEMO2_GameSound = { - kSoundPCM, - 22050, - 16, - false, - false, - true -}; - -// Inherit the Earth - Wyrmkeep Mac Demo version -static GameFileDescription ITEMACDEMO_GameFiles[] = { - {"ited.rsc", GAME_RESOURCEFILE}, - {"scriptsd.rsc", GAME_SCRIPTFILE}, - {"soundsd.rsc", GAME_SOUNDFILE}, - {"voicesd.rsc", GAME_VOICEFILE}, - {"musicd.rsc", GAME_MUSICFILE} -}; - -static GameSoundInfo ITEMACDEMO_GameVoice = { - kSoundVOX, - 22050, - 16, - false, - false, - true -}; - -static GameSoundInfo ITEMACDEMO_GameSound = { - kSoundPCM, - 22050, - 16, - false, - true, - true -}; - -static GameSoundInfo ITEMACDEMO_GameMusic = { - kSoundPCM, - 11025, - 16, - false, - false, - true -}; - -// Inherit the Earth - Wyrmkeep Linux Demo version -static GameFileDescription ITELINDEMO_GameFiles[] = { - {"ited.rsc", GAME_RESOURCEFILE}, - {"scriptsd.rsc", GAME_SCRIPTFILE}, - {"soundsd.rsc", GAME_SOUNDFILE}, - {"voicesd.rsc", GAME_VOICEFILE}, - {"musicd.rsc", GAME_MUSICFILE} -}; - -static GameSoundInfo ITELINDEMO_GameMusic = { - kSoundPCM, - 11025, - 16, - true, - false, - true -}; - -// Inherit the Earth - Wyrmkeep Linux version -static GameFileDescription ITELINCD_GameFiles[] = { - {"ite.rsc", GAME_RESOURCEFILE}, - {"scripts.rsc", GAME_SCRIPTFILE}, - {"sounds.rsc", GAME_SOUNDFILE}, - {"voices.rsc", GAME_VOICEFILE}, - {"music.rsc", GAME_MUSICFILE} -}; - -// Inherit the Earth - Wyrmkeep combined Windows/Mac/Linux version. This -// version is different from the other Wyrmkeep re-releases in that it does -// not have any substitute files. Presumably the ite.rsc file has been -// modified to include the Wyrmkeep changes. The resource files are little- -// endian, except for the voice file which is big-endian. - -static GameFileDescription ITEMULTICD_GameFiles[] = { - {"ite.rsc", GAME_RESOURCEFILE}, - {"scripts.rsc", GAME_SCRIPTFILE}, - {"sounds.rsc", GAME_SOUNDFILE}, - {"Inherit the Earth Voices", GAME_VOICEFILE | GAME_SWAPENDIAN}, - {"music.rsc", GAME_MUSICFILE} -}; - -static GameFileDescription ITEMACCD_G_GameFiles[] = { - {"ITE Resources.bin", GAME_RESOURCEFILE | GAME_MACBINARY}, - {"ITE Scripts.bin", GAME_SCRIPTFILE | GAME_MACBINARY}, - {"ITE Sounds.bin", GAME_SOUNDFILE | GAME_MACBINARY}, - {"ITE Music.bin", GAME_MUSICFILE_GM | GAME_MACBINARY}, - {"ITE Voices.bin", GAME_VOICEFILE | GAME_MACBINARY} -}; - -static GameSoundInfo ITEMACCD_G_GameSound = { - kSoundMacPCM, - 22050, - 8, - false, - false, - false -}; - -// Inherit the Earth - Mac Wyrmkeep version -static GameFileDescription ITEMACCD_GameFiles[] = { - {"ite.rsc", GAME_RESOURCEFILE}, - {"scripts.rsc", GAME_SCRIPTFILE}, - {"sounds.rsc", GAME_SOUNDFILE}, - {"Inherit the Earth Voices", GAME_VOICEFILE}, - {"music.rsc", GAME_MUSICFILE} -}; - -static GameSoundInfo ITEMACCD_GameSound = { - kSoundPCM, - 22050, - 16, - false, - true, - true -}; - -static GameSoundInfo ITEMACCD_GameMusic = { - kSoundPCM, - 11025, - 16, - true, - false, - true -}; - -// Inherit the Earth - Diskette version -static GameFileDescription ITEDISK_GameFiles[] = { - {"ite.rsc", GAME_RESOURCEFILE}, - {"scripts.rsc", GAME_SCRIPTFILE}, - {"voices.rsc", GAME_SOUNDFILE | GAME_VOICEFILE} -}; - -static GameFileDescription ITEDISK2_GameFiles[] = { - {"ite.rsc", GAME_RESOURCEFILE}, - {"scripts.rsc", GAME_SCRIPTFILE}, - {"voices.rsc", GAME_SOUNDFILE | GAME_VOICEFILE}, - {"music.rsc", GAME_MUSICFILE} -}; - -static GameFontDescription ITEDISK_GameFonts[] = { - {2}, - {0}, - {1} -}; - -static GameSoundInfo ITEDISK_GameSound = { - kSoundVOC, - -1, - -1, - false, - false, - true -}; - -// Inherit the Earth - CD Enhanced version -static GameFileDescription ITECD_GameFiles[] = { - {"ite.rsc", GAME_RESOURCEFILE}, - {"scripts.rsc", GAME_SCRIPTFILE}, - {"sounds.rsc", GAME_SOUNDFILE}, - {"voices.rsc", GAME_VOICEFILE} -}; - -static GameFileDescription ITECD2_GameFiles[] = { - {"ite.rsc", GAME_RESOURCEFILE}, - {"scripts.rsc", GAME_SCRIPTFILE}, - {"sounds.rsc", GAME_SOUNDFILE}, - {"voices.rsc", GAME_VOICEFILE}, - {"music.rsc", GAME_MUSICFILE} -}; - -static GameFontDescription ITECD_GameFonts[] = { - {2}, - {0}, - {1} -}; - -static GameSoundInfo ITECD_GameSound = { - kSoundPCM, - 22050, - 16, - false, - false, - true -}; - -static GamePatchDescription ITEWinPatch1_Files[] = { - { "cave.mid", GAME_RESOURCEFILE, 9, NULL}, - { "intro.mid", GAME_RESOURCEFILE, 10, NULL}, - { "fvillage.mid", GAME_RESOURCEFILE, 11, NULL}, - { "elkhall.mid", GAME_RESOURCEFILE, 12, NULL}, - { "mouse.mid", GAME_RESOURCEFILE, 13, NULL}, - { "darkclaw.mid", GAME_RESOURCEFILE, 14, NULL}, - { "birdchrp.mid", GAME_RESOURCEFILE, 15, NULL}, - { "orbtempl.mid", GAME_RESOURCEFILE, 16, NULL}, - { "spooky.mid", GAME_RESOURCEFILE, 17, NULL}, - { "catfest.mid", GAME_RESOURCEFILE, 18, NULL}, - { "elkfanfare.mid", GAME_RESOURCEFILE, 19, NULL}, - { "bcexpl.mid", GAME_RESOURCEFILE, 20, NULL}, - { "boargtnt.mid", GAME_RESOURCEFILE, 21, NULL}, - { "boarking.mid", GAME_RESOURCEFILE, 22, NULL}, - { "explorea.mid", GAME_RESOURCEFILE, 23, NULL}, - { "exploreb.mid", GAME_RESOURCEFILE, 24, NULL}, - { "explorec.mid", GAME_RESOURCEFILE, 25, NULL}, - { "sunstatm.mid", GAME_RESOURCEFILE, 26, NULL}, - { "nitstrlm.mid", GAME_RESOURCEFILE, 27, NULL}, - { "humruinm.mid", GAME_RESOURCEFILE, 28, NULL}, - { "damexplm.mid", GAME_RESOURCEFILE, 29, NULL}, - { "tychom.mid", GAME_RESOURCEFILE, 30, NULL}, - { "kitten.mid", GAME_RESOURCEFILE, 31, NULL}, - { "sweet.mid", GAME_RESOURCEFILE, 32, NULL}, - { "brutalmt.mid", GAME_RESOURCEFILE, 33, NULL}, - { "shiala.mid", GAME_RESOURCEFILE, 34, NULL}, - - { "wyrm.pak", GAME_RESOURCEFILE, 1529, NULL}, - { "wyrm1.dlt", GAME_RESOURCEFILE, 1530, NULL}, - { "wyrm2.dlt", GAME_RESOURCEFILE, 1531, NULL}, - { "wyrm3.dlt", GAME_RESOURCEFILE, 1532, NULL}, - { "wyrm4.dlt", GAME_RESOURCEFILE, 1533, NULL}, - { "credit3n.dlt", GAME_RESOURCEFILE, 1796, NULL}, - { "credit4n.dlt", GAME_RESOURCEFILE, 1797, NULL}, - { "p2_a.voc", GAME_VOICEFILE, 4, NULL} -}; - -static GamePatchDescription ITEWinPatch2_Files[] = { - { "cave.mid", GAME_RESOURCEFILE, 9, NULL}, - { "intro.mid", GAME_RESOURCEFILE, 10, NULL}, - { "fvillage.mid", GAME_RESOURCEFILE, 11, NULL}, - { "elkfanfare.mid", GAME_RESOURCEFILE, 19, NULL}, - { "bcexpl.mid", GAME_RESOURCEFILE, 20, NULL}, - { "boargtnt.mid", GAME_RESOURCEFILE, 21, NULL}, - { "explorea.mid", GAME_RESOURCEFILE, 23, NULL}, - { "sweet.mid", GAME_RESOURCEFILE, 32, NULL}, - - { "wyrm.pak", GAME_RESOURCEFILE, 1529, NULL}, - { "wyrm1.dlt", GAME_RESOURCEFILE, 1530, NULL}, - { "wyrm2.dlt", GAME_RESOURCEFILE, 1531, NULL}, - { "wyrm3.dlt", GAME_RESOURCEFILE, 1532, NULL}, - { "p2_a.iaf", GAME_VOICEFILE, 4, &ITECD_GameSound} -/* boarhall.bbm - elkenter.bbm - ferrets.bbm - ratdoor.bbm - sanctuar.bbm - tycho.bbm*/ -}; - -static GamePatchDescription ITEMacPatch_Files[] = { - { "wyrm.pak", GAME_RESOURCEFILE, 1529, NULL}, - { "wyrm1.dlt", GAME_RESOURCEFILE, 1530, NULL}, - { "wyrm2.dlt", GAME_RESOURCEFILE, 1531, NULL}, - { "wyrm3.dlt", GAME_RESOURCEFILE, 1532, NULL}, - { "wyrm4.dlt", GAME_RESOURCEFILE, 1533, NULL}, - { "credit3m.dlt", GAME_RESOURCEFILE, 1796, NULL}, - { "credit4m.dlt", GAME_RESOURCEFILE, 1797, NULL}, - { "p2_a.iaf", GAME_VOICEFILE, 4, &ITEMACCD_GameSound} -}; - -static GamePatchDescription ITELinPatch_Files[] = { - { "wyrm.pak", GAME_RESOURCEFILE, 1529, NULL}, - { "wyrm1.dlt", GAME_RESOURCEFILE, 1530, NULL}, - { "wyrm2.dlt", GAME_RESOURCEFILE, 1531, NULL}, - { "wyrm3.dlt", GAME_RESOURCEFILE, 1532, NULL}, - { "credit3n.dlt", GAME_RESOURCEFILE, 1796, NULL}, - { "credit4n.dlt", GAME_RESOURCEFILE, 1797, NULL}, - { "P2_A.iaf", GAME_VOICEFILE, 4, &ITECD_GameSound} -}; - -// IHNM section - -static PanelButton IHNM_MainPanelButtons[] = { - {kPanelButtonVerb, 106,12, 114,30, kVerbIHNMWalk,'w',0, 0,1,0}, - {kPanelButtonVerb, 106,44, 114,30, kVerbIHNMLookAt,'l',0, 2,3,0}, - {kPanelButtonVerb, 106,76, 114,30, kVerbIHNMTake,'k',0, 4,5,0}, - {kPanelButtonVerb, 106,108, 114,30, kVerbIHNMUse,'u',0, 6,7,0}, - {kPanelButtonVerb, 223,12, 114,30, kVerbIHNMTalkTo,'t',0, 8,9,0}, - {kPanelButtonVerb, 223,44, 114,30, kVerbIHNMSwallow,'s',0, 10,11,0}, - {kPanelButtonVerb, 223,76, 114,30, kVerbIHNMGive,'g',0, 12,13,0}, - {kPanelButtonVerb, 223,108, 114,30, kVerbIHNMPush,'p',0, 14,15,0}, - {kPanelButtonArrow, 606,22, 20,25, -1,'[',0, 0,0,0}, //TODO: arrow Sprite Numbers - {kPanelButtonArrow, 606,108, 20,25, 1,']',0, 0,0,0}, - - {kPanelButtonInventory, 357 + 64*0,18, 54,54, 0,'-',0, 0,0,0}, - {kPanelButtonInventory, 357 + 64*1,18, 54,54, 1,'-',0, 0,0,0}, - {kPanelButtonInventory, 357 + 64*2,18, 54,54, 2,'-',0, 0,0,0}, - {kPanelButtonInventory, 357 + 64*3,18, 54,54, 3,'-',0, 0,0,0}, - - {kPanelButtonInventory, 357 + 64*0,80, 54,54, 4,'-',0, 0,0,0}, - {kPanelButtonInventory, 357 + 64*1,80, 54,54, 5,'-',0, 0,0,0}, - {kPanelButtonInventory, 357 + 64*2,80, 54,54, 6,'-',0, 0,0,0}, - {kPanelButtonInventory, 357 + 64*3,80, 54,54, 7,'-',0, 0,0,0} -}; - -static PanelButton IHNM_ConversePanelButtons[] = { - {kPanelButtonConverseText, 117,18 + IHNM_CONVERSE_TEXT_HEIGHT * 0, IHNM_CONVERSE_MAX_TEXT_WIDTH,IHNM_CONVERSE_TEXT_HEIGHT, 0,'1',0, 0,0,0}, - {kPanelButtonConverseText, 52,18 + IHNM_CONVERSE_TEXT_HEIGHT * 1, IHNM_CONVERSE_MAX_TEXT_WIDTH,IHNM_CONVERSE_TEXT_HEIGHT, 1,'2',0, 0,0,0}, - {kPanelButtonConverseText, 52,18 + IHNM_CONVERSE_TEXT_HEIGHT * 2, IHNM_CONVERSE_MAX_TEXT_WIDTH,IHNM_CONVERSE_TEXT_HEIGHT, 2,'3',0, 0,0,0}, - {kPanelButtonConverseText, 52,18 + IHNM_CONVERSE_TEXT_HEIGHT * 3, IHNM_CONVERSE_MAX_TEXT_WIDTH,IHNM_CONVERSE_TEXT_HEIGHT, 3,'4',0, 0,0,0}, - //..... - {kPanelButtonArrow, 606,22, 20,25, -1,'[',0, 0,0,0}, //TODO: arrow Sprite Numbers - {kPanelButtonArrow, 606,108, 20,25, 1,']',0, 0,0,0} -}; - -static PanelButton IHNM_OptionPanelButtons[] = { - {kPanelButtonArrow, 0,0, 0,0, 0,'-',0, 0,0,0}, //TODO -}; - -static PanelButton IHNM_QuitPanelButtons[] = { - {kPanelButtonArrow, 0,0, 0,0, 0,'-',0, 0,0,0}, //TODO -}; - -static PanelButton IHNM_LoadPanelButtons[] = { - {kPanelButtonArrow, 0,0, 0,0, 0,'-',0, 0,0,0}, //TODO -}; - -static PanelButton IHNM_SavePanelButtons[] = { - {kPanelButtonArrow, 0,0, 0,0, 0,'-',0, 0,0,0}, //TODO -}; - - -static GameDisplayInfo IHNM_DisplayInfo = { //TODO: fill it all - 640, 480, // logical width&height - - 0, // scene path y offset - 304, // scene height - - 0, // status x offset - 304, // status y offset - 616, // status width - 24, // status height - 8, // status text y offset - 253, // status text color - 250, // status BG color - 616, 303, // save reminder pos - 24, 24, // save reminder w&h - 0,1, // save reminder sprite numbers - - 11, 12, // left portrait x, y offset - -1, -1, // right portrait x, y offset - - -1, -1, // inventory Up & Down button indexies - 2, 4, // inventory rows, columns - - 0, 328, // main panel offsets - ARRAYSIZE(IHNM_MainPanelButtons), - IHNM_MainPanelButtons, - - -1, -1, // converse Up & Down button indexies - - IHNM_CONVERSE_MAX_TEXT_WIDTH, - IHNM_CONVERSE_TEXT_HEIGHT, - IHNM_CONVERSE_TEXT_LINES, - 0, 328, // converse panel offsets - ARRAYSIZE(IHNM_ConversePanelButtons), - IHNM_ConversePanelButtons, - - -1, -1, // save file index - 0, // optionSaveFileVisible - 0, 0, // option panel offsets - ARRAYSIZE(IHNM_OptionPanelButtons), - IHNM_OptionPanelButtons, - - 0,0, // quit panel offsets - 0,0, // quit panel width & height - ARRAYSIZE(IHNM_QuitPanelButtons), - IHNM_QuitPanelButtons, - - 0, 0, // load panel offsets - 0, 0, // load panel width & height - ARRAYSIZE(IHNM_LoadPanelButtons), - IHNM_LoadPanelButtons, - - -1, // save edit index - 0, 0, // save panel offsets - 0, 0, // save panel width & height - ARRAYSIZE(IHNM_SavePanelButtons), - IHNM_SavePanelButtons, - - // No protection panel in IHNM - -1, // protect edit index - 0, 0, // protect panel offsets - 0, 0, // protect panel width & height - ARRAYSIZE(IHNM_SavePanelButtons), - IHNM_SavePanelButtons -}; - -static GameResourceDescription IHNM_Resources = { - RID_IHNM_SCENE_LUT, // Scene lookup table RN - RID_IHNM_SCRIPT_LUT, // Script lookup table RN - RID_IHNM_MAIN_PANEL, - RID_IHNM_CONVERSE_PANEL, - RID_IHNM_OPTION_PANEL, - RID_IHNM_MAIN_SPRITES, - RID_IHNM_MAIN_PANEL_SPRITES, - 0, - RID_IHNM_MAIN_STRINGS, - 0 -}; - -// I Have No Mouth and I Must Scream - Demo version -static GameFileDescription IHNMDEMO_GameFiles[] = { - {"scream.res", GAME_RESOURCEFILE}, - {"scripts.res", GAME_SCRIPTFILE}, - {"sfx.res", GAME_SOUNDFILE}, - {"voicesd.res", GAME_VOICEFILE} -}; - -// I Have No Mouth and I Must Scream - Retail CD version -static GameFileDescription IHNMCD_GameFiles[] = { - {"musicfm.res", GAME_MUSICFILE_FM}, - {"musicgm.res", GAME_MUSICFILE_GM}, - {"scream.res", GAME_RESOURCEFILE}, - {"patch.re_", GAME_PATCHFILE | GAME_RESOURCEFILE}, - {"scripts.res", GAME_SCRIPTFILE}, - {"sfx.res", GAME_SOUNDFILE}, - {"voicess.res", GAME_VOICEFILE}, //order of voice bank file is important - {"voices1.res", GAME_VOICEFILE}, - {"voices2.res", GAME_VOICEFILE}, - {"voices3.res", GAME_VOICEFILE}, - {"voices4.res", GAME_VOICEFILE}, - {"voices5.res", GAME_VOICEFILE}, - {"voices6.res", GAME_VOICEFILE} -}; - -// I Have No Mouth and I Must Scream - Censored CD version (without Nimdok) -static GameFileDescription IHNMCD_Censored_GameFiles[] = { - {"musicfm.res", GAME_MUSICFILE_FM}, - {"musicgm.res", GAME_MUSICFILE_GM}, - {"scream.res", GAME_RESOURCEFILE}, - {"scripts.res", GAME_SCRIPTFILE}, - {"patch.re_", GAME_PATCHFILE | GAME_RESOURCEFILE}, - {"sfx.res", GAME_SOUNDFILE}, - {"voicess.res", GAME_VOICEFILE}, //order of voice bank file is important - {"voices1.res", GAME_VOICEFILE}, - {"voices2.res", GAME_VOICEFILE}, - {"voices3.res", GAME_VOICEFILE}, - {"voices5.res", GAME_VOICEFILE}, - {"voices6.res", GAME_VOICEFILE} -}; - -static GameFontDescription IHNMDEMO_GameFonts[] = { - {2}, - {3}, - {4} -}; - -static GameFontDescription IHNMCD_GameFonts[] = { - {2}, - {3}, - {4}, - {5}, - {6}, // kIHNMFont8 - {7}, - {8} // kIHNMMainFont -}; - -static GameSoundInfo IHNM_GameSound = { - kSoundWAV, - -1, - -1, - false, - false, - true -}; - -struct GameMD5 { - GameIds id; - const char *md5; - const char *filename; - bool caseSensitive; -}; - -#define FILE_MD5_BYTES 5000 - -static GameMD5 gameMD5[] = { - { GID_ITE_DISK_G, "8f4315a9bb10ec839253108a032c8b54", "ite.rsc", false }, - { GID_ITE_DISK_G, "516f7330f8410057b834424ea719d1ef", "scripts.rsc", false }, - { GID_ITE_DISK_G, "c46e4392fcd2e89bc91e5567db33b62d", "voices.rsc", false }, - - { GID_ITE_DISK_G2, "8f4315a9bb10ec839253108a032c8b54", "ite.rsc", false }, - { GID_ITE_DISK_G2, "516f7330f8410057b834424ea719d1ef", "scripts.rsc", false }, - { GID_ITE_DISK_G2, "c46e4392fcd2e89bc91e5567db33b62d", "voices.rsc", false }, - { GID_ITE_DISK_G2, "d6454756517f042f01210458abe8edd4", "music.rsc", false }, - - { GID_ITE_CD_G, "8f4315a9bb10ec839253108a032c8b54", "ite.rsc", false }, - { GID_ITE_CD_G, "50a0d2d7003c926a3832d503c8534e90", "scripts.rsc", false }, - { GID_ITE_CD_G, "e2ccb61c325d6d1ead3be0e731fe29fe", "sounds.rsc", false }, - { GID_ITE_CD_G, "41bb6b95d792dde5196bdb78740895a6", "voices.rsc", false }, - - { GID_ITE_CD_G2, "8f4315a9bb10ec839253108a032c8b54", "ite.rsc", false }, - { GID_ITE_CD_G2, "50a0d2d7003c926a3832d503c8534e90", "scripts.rsc", false }, - { GID_ITE_CD_G2, "e2ccb61c325d6d1ead3be0e731fe29fe", "sounds.rsc", false }, - { GID_ITE_CD_G2, "41bb6b95d792dde5196bdb78740895a6", "voices.rsc", false }, - { GID_ITE_CD_G2, "d6454756517f042f01210458abe8edd4", "music.rsc", false }, - - { GID_ITE_CD, "8f4315a9bb10ec839253108a032c8b54", "ite.rsc", false }, - { GID_ITE_CD, "a891405405edefc69c9d6c420c868b84", "scripts.rsc", false }, - { GID_ITE_CD, "e2ccb61c325d6d1ead3be0e731fe29fe", "sounds.rsc", false }, - { GID_ITE_CD, "41bb6b95d792dde5196bdb78740895a6", "voices.rsc", false }, - - // reported by mld. Bestsellergamers cover disk - { GID_ITE_CD_DE, "869fc23c8f38f575979ec67152914fee", "ite.rsc", false }, - { GID_ITE_CD_DE, "a891405405edefc69c9d6c420c868b84", "scripts.rsc", false }, - { GID_ITE_CD_DE, "e2ccb61c325d6d1ead3be0e731fe29fe", "sounds.rsc", false }, - { GID_ITE_CD_DE, "2fbad5d10b9b60a3415dc4aebbb11718", "voices.rsc", false }, - - { GID_ITE_CD_DE2, "869fc23c8f38f575979ec67152914fee", "ite.rsc", false }, - { GID_ITE_CD_DE2, "a891405405edefc69c9d6c420c868b84", "scripts.rsc", false }, - { GID_ITE_CD_DE2, "e2ccb61c325d6d1ead3be0e731fe29fe", "sounds.rsc", false }, - { GID_ITE_CD_DE2, "2fbad5d10b9b60a3415dc4aebbb11718", "voices.rsc", false }, - { GID_ITE_CD_DE2, "d6454756517f042f01210458abe8edd4", "music.rsc", false }, - - { GID_ITE_DEMO_G, "986c79c4d2939dbe555576529fd37932", "ite.rsc", false }, - { GID_ITE_DEMO_G, "d5697dd3240a3ceaddaa986c47e1a2d7", "scripts.rsc", false }, - { GID_ITE_DEMO_G, "c58e67c506af4ffa03fd0aac2079deb0", "voices.rsc", false }, - { GID_ITE_DEMO_G, "0b9a70eb4e120b6f00579b46c8cae29e", "ite.dmo", false }, - - { GID_ITE_WINCD, "8f4315a9bb10ec839253108a032c8b54", "ite.rsc", false }, - { GID_ITE_WINCD, "a891405405edefc69c9d6c420c868b84", "scripts.rsc", false }, - { GID_ITE_WINCD, "e2ccb61c325d6d1ead3be0e731fe29fe", "sounds.rsc", false }, - { GID_ITE_WINCD, "41bb6b95d792dde5196bdb78740895a6", "voices.rsc", false }, - - { GID_ITE_MACCD, "4f7fa11c5175980ed593392838523060", "ite.rsc", false }, - { GID_ITE_MACCD, "adf1f46c1d0589083996a7060c798ad0", "scripts.rsc", false }, - { GID_ITE_MACCD, "1a91cd60169f367ecb6c6e058d899b2f", "music.rsc", false }, - { GID_ITE_MACCD, "95863b89a0916941f6c5e1789843ba14", "sounds.rsc", false }, - { GID_ITE_MACCD, "c14c4c995e7a0d3828e3812a494301b7", "Inherit the Earth Voices", true }, - - { GID_ITE_MACCD_G, "0bd506aa887bfc7965f695c6bd28237d", "ITE Resources.bin", true }, - { GID_ITE_MACCD_G, "af0d7a2588e09ad3ecbc5b474ea238bf", "ITE Scripts.bin", true }, - { GID_ITE_MACCD_G, "c1d20324b7cdf1650e67061b8a93251c", "ITE Music.bin", true }, - { GID_ITE_MACCD_G, "441426c6bb2a517f65c7e49b57f7a345", "ITE Sounds.bin", true }, - { GID_ITE_MACCD_G, "dba92ae7d57e942250fe135609708369", "ITE Voices.bin", true }, - - { GID_ITE_LINCD, "8f4315a9bb10ec839253108a032c8b54", "ite.rsc", false }, - { GID_ITE_LINCD, "a891405405edefc69c9d6c420c868b84", "scripts.rsc", false }, - { GID_ITE_LINCD, "e2ccb61c325d6d1ead3be0e731fe29fe", "sounds.rsc", false }, - { GID_ITE_LINCD, "41bb6b95d792dde5196bdb78740895a6", "voices.rsc", false }, - { GID_ITE_LINCD, "d6454756517f042f01210458abe8edd4", "music.rsc", false }, - - { GID_ITE_MULTICD, "a6433e34b97b15e64fe8214651012db9", "ite.rsc", false }, - { GID_ITE_MULTICD, "a891405405edefc69c9d6c420c868b84", "scripts.rsc", false }, - { GID_ITE_MULTICD, "e2ccb61c325d6d1ead3be0e731fe29fe", "sounds.rsc", false }, - { GID_ITE_MULTICD, "c14c4c995e7a0d3828e3812a494301b7", "Inherit the Earth Voices", true }, - { GID_ITE_MULTICD, "d6454756517f042f01210458abe8edd4", "music.rsc", false }, - - { GID_ITE_DISK_DE, "869fc23c8f38f575979ec67152914fee", "ite.rsc", false }, - { GID_ITE_DISK_DE, "516f7330f8410057b834424ea719d1ef", "scripts.rsc", false }, - { GID_ITE_DISK_DE, "0c9113e630f97ef0996b8c3114badb08", "voices.rsc", false }, - - { GID_ITE_DISK_DE2, "869fc23c8f38f575979ec67152914fee", "ite.rsc", false }, - { GID_ITE_DISK_DE2, "516f7330f8410057b834424ea719d1ef", "scripts.rsc", false }, - { GID_ITE_DISK_DE2, "0c9113e630f97ef0996b8c3114badb08", "voices.rsc", false }, - { GID_ITE_DISK_DE2, "d6454756517f042f01210458abe8edd4", "music.rsc", false }, - - { GID_ITE_WINDEMO2, "3a450852cbf3c80773984d565647e6ac", "ited.rsc", false }, - { GID_ITE_WINDEMO2, "3f12b67fa93e56e1a6be39d2921d80bb", "scriptsd.rsc", false }, - { GID_ITE_WINDEMO2, "95a6c148e22e99a8c243f2978223583c", "soundsd.rsc", false }, - { GID_ITE_WINDEMO2, "e139d86bab2ee8ba3157337f894a92d4", "voicesd.rsc", false }, - - { GID_ITE_LINDEMO, "3a450852cbf3c80773984d565647e6ac", "ited.rsc", false }, - { GID_ITE_LINDEMO, "3f12b67fa93e56e1a6be39d2921d80bb", "scriptsd.rsc", false }, - { GID_ITE_LINDEMO, "d6454756517f042f01210458abe8edd4", "musicd.rsc", false }, - { GID_ITE_LINDEMO, "95a6c148e22e99a8c243f2978223583c", "soundsd.rsc", false }, - { GID_ITE_LINDEMO, "e139d86bab2ee8ba3157337f894a92d4", "voicesd.rsc", false }, - - { GID_ITE_MACDEMO2, "addfc9d82bc2fa1f4cab23743c652c08", "ited.rsc", false }, - { GID_ITE_MACDEMO2, "fded5c59b8b7c5976229f960d21e6b0b", "scriptsd.rsc", false }, - { GID_ITE_MACDEMO2, "495bdde51fd9f4bea2b9c911091b1ab2", "musicd.rsc", false }, - { GID_ITE_MACDEMO2, "b3a831fbed337d1f1300fee1dd474f6c", "soundsd.rsc", false }, - { GID_ITE_MACDEMO2, "e139d86bab2ee8ba3157337f894a92d4", "voicesd.rsc", false }, - - { GID_ITE_WINDEMO1, "3a450852cbf3c80773984d565647e6ac", "ited.rsc", false }, - { GID_ITE_WINDEMO1, "3f12b67fa93e56e1a6be39d2921d80bb", "scriptsd.rsc", false }, - { GID_ITE_WINDEMO1, "a741139dd7365a13f463cd896ff9969a", "soundsd.rsc", false }, - { GID_ITE_WINDEMO1, "0759eaf5b64ae19fd429920a70151ad3", "voicesd.rsc", false }, - - { GID_ITE_MACDEMO1, "addfc9d82bc2fa1f4cab23743c652c08", "ited.rsc", false }, - { GID_ITE_MACDEMO1, "fded5c59b8b7c5976229f960d21e6b0b", "scriptsd.rsc", false }, - { GID_ITE_MACDEMO1, "1a91cd60169f367ecb6c6e058d899b2f", "musicd.rsc", false }, - { GID_ITE_MACDEMO1, "b3a831fbed337d1f1300fee1dd474f6c", "soundsd.rsc", false }, - { GID_ITE_MACDEMO1, "e139d86bab2ee8ba3157337f894a92d4", "voicesd.rsc", false }, - - { GID_IHNM_CD, "0439083e3dfdc51b486071d45872ae52", "musicfm.res", false }, - { GID_IHNM_CD, "80f875a1fb384160d1f4b27166eef583", "musicgm.res", false }, - { GID_IHNM_CD, "46bbdc65d164ba7e89836a0935eec8e6", "scream.res", false }, - { GID_IHNM_CD, "be38bbc5a26be809dbf39f13befebd01", "scripts.res", false }, - { GID_IHNM_CD, "58b79e61594779513c7f2d35509fa89e", "patch.re_", false }, - { GID_IHNM_CD, "1c610d543f32ec8b525e3f652536f269", "sfx.res", false }, - { GID_IHNM_CD, "fc6440b38025f4b2cc3ff55c3da5c3eb", "voices1.res", false }, - { GID_IHNM_CD, "b37f10fd1696ade7d58704ccaaebceeb", "voices2.res", false }, - { GID_IHNM_CD, "3bbc16a8f741dbb511da506c660a0b54", "voices3.res", false }, - { GID_IHNM_CD, "ebfa160122d2247a676ca39920e5d481", "voices4.res", false }, - { GID_IHNM_CD, "1f501ce4b72392bdd1d9ec38f6eec6da", "voices5.res", false }, - { GID_IHNM_CD, "f580ed7568c7d6ef34e934ba20adf834", "voices6.res", false }, - { GID_IHNM_CD, "54b1f2013a075338ceb0e258d97808bd", "voicess.res", false }, - - // Reported by mld. German Retail - { GID_IHNM_CD_DE, "0439083e3dfdc51b486071d45872ae52", "musicfm.res", false }, - { GID_IHNM_CD_DE, "80f875a1fb384160d1f4b27166eef583", "musicgm.res", false }, - { GID_IHNM_CD_DE, "c92370d400e6f2a3fc411c3729d09224", "scream.res", false }, - { GID_IHNM_CD_DE, "32aa01a89937520fe0ea513950117292", "scripts.res", false }, - { GID_IHNM_CD_DE, "58b79e61594779513c7f2d35509fa89e", "patch.re_", false }, - { GID_IHNM_CD_DE, "1c610d543f32ec8b525e3f652536f269", "sfx.res", false }, - { GID_IHNM_CD_DE, "424971e1e2373187c3f5734fe36071a2", "voices1.res", false }, - { GID_IHNM_CD_DE, "c270e0980782af43641a86e4a14e2a32", "voices2.res", false }, - { GID_IHNM_CD_DE, "49e42befea883fd101ec3d0f5d0647b9", "voices3.res", false }, - { GID_IHNM_CD_DE, "c477443c52a0aa56e686ebd8d051e4ab", "voices5.res", false }, - { GID_IHNM_CD_DE, "2b9aea838f74b4eecfb29a8f205a2bd4", "voices6.res", false }, - { GID_IHNM_CD_DE, "8b09a196a52627cacb4eab13bfe0b2c3", "voicess.res", false }, - - { GID_IHNM_CD_ES, "0439083e3dfdc51b486071d45872ae52", "musicfm.res", false }, - { GID_IHNM_CD_ES, "80f875a1fb384160d1f4b27166eef583", "musicgm.res", false }, - { GID_IHNM_CD_ES, "58b79e61594779513c7f2d35509fa89e", "patch.re_", false }, - { GID_IHNM_CD_ES, "c92370d400e6f2a3fc411c3729d09224", "scream.res", false }, - { GID_IHNM_CD_ES, "be38bbc5a26be809dbf39f13befebd01", "scripts.res", false }, - { GID_IHNM_CD_ES, "1c610d543f32ec8b525e3f652536f269", "sfx.res", false }, - { GID_IHNM_CD_ES, "dc6a34e3d1668730ea46815a92c7847f", "voices1.res", false }, - { GID_IHNM_CD_ES, "dc6a5fa7a4cdc2ca5a6fd924e969986c", "voices2.res", false }, - { GID_IHNM_CD_ES, "dc6a5fa7a4cdc2ca5a6fd924e969986c", "voices3.res", false }, - { GID_IHNM_CD_ES, "0f87400b804232a58dd22e404420cc45", "voices4.res", false }, - { GID_IHNM_CD_ES, "172668cfc5d8c305cb5b1a9b4d995fc0", "voices5.res", false }, - { GID_IHNM_CD_ES, "96c9bda9a5f41d6bc232ed7bf6d371d9", "voices6.res", false }, - { GID_IHNM_CD_ES, "d869de9883c8faea7f687217a9ec7057", "voicess.res", false }, - - { GID_IHNM_CD_RU, "0439083e3dfdc51b486071d45872ae52", "musicfm.res", false }, - { GID_IHNM_CD_RU, "80f875a1fb384160d1f4b27166eef583", "musicgm.res", false }, - { GID_IHNM_CD_RU, "46bbdc65d164ba7e89836a0935eec8e6", "scream.res", false }, - { GID_IHNM_CD_RU, "be38bbc5a26be809dbf39f13befebd01", "scripts.res", false }, - { GID_IHNM_CD_RU, "58b79e61594779513c7f2d35509fa89e", "patch.re_", false }, - { GID_IHNM_CD_RU, "1c610d543f32ec8b525e3f652536f269", "sfx.res", false }, - { GID_IHNM_CD_RU, "d6100d2dc3b2b9f2e1ad247f613dce9b", "voices1.res", false }, - { GID_IHNM_CD_RU, "84f6f48ecc2832841ea6417a9a379430", "voices2.res", false }, - { GID_IHNM_CD_RU, "ebb9501283047f27a0f54e27b3c8ba1e", "voices3.res", false }, - { GID_IHNM_CD_RU, "4c145da5fa6d1306162a7ca8ce5a4f2e", "voices4.res", false }, - { GID_IHNM_CD_RU, "871a559644281917677eca4af1b05620", "voices5.res", false }, - { GID_IHNM_CD_RU, "211be5c24f066d69a2f6cfa953acfba6", "voices6.res", false }, - { GID_IHNM_CD_RU, "9df7cd3b18ddaa16b5291b3432567036", "voicess.res", false }, - - { GID_IHNM_CD_FR, "0439083e3dfdc51b486071d45872ae52", "musicfm.res", false }, - { GID_IHNM_CD_FR, "80f875a1fb384160d1f4b27166eef583", "musicgm.res", false }, - { GID_IHNM_CD_FR, "58b79e61594779513c7f2d35509fa89e", "patch.re_", false }, - { GID_IHNM_CD_FR, "c92370d400e6f2a3fc411c3729d09224", "scream.res", false }, - { GID_IHNM_CD_FR, "32aa01a89937520fe0ea513950117292", "scripts.res", false }, - { GID_IHNM_CD_FR, "1c610d543f32ec8b525e3f652536f269", "sfx.res", false }, - { GID_IHNM_CD_FR, "424971e1e2373187c3f5734fe36071a2", "voices1.res", false }, - { GID_IHNM_CD_FR, "c2d93a35d2c2def9c3d6d242576c794b", "voices2.res", false }, - { GID_IHNM_CD_FR, "49e42befea883fd101ec3d0f5d0647b9", "voices3.res", false }, - { GID_IHNM_CD_FR, "f4c415de7c03de86b73f9a12b8bd632f", "voices5.res", false }, - { GID_IHNM_CD_FR, "3fc5358a5d8eee43bdfab2740276572e", "voices6.res", false }, - { GID_IHNM_CD_FR, "b8642e943bbebf89cef2f48b31cb4305", "voicess.res", false }, - - { GID_IHNM_DEMO, "46bbdc65d164ba7e89836a0935eec8e6", "scream.res", false }, - { GID_IHNM_DEMO, "9626bda8978094ff9b29198bc1ed5f9a", "scripts.res", false }, - { GID_IHNM_DEMO, "1c610d543f32ec8b525e3f652536f269", "sfx.res", false }, - { GID_IHNM_DEMO, "3bbc16a8f741dbb511da506c660a0b54", "voicesd.res", false }, -}; - -static GameDescription gameDescriptions[] = { - // Inherit the earth - DOS Demo version - // sound unchecked - { - "ite", - GType_ITE, - GID_ITE_DEMO_G, // Game id - "Inherit the Earth: Quest for the Orb (DOS Demo)", // Game title - &ITE_DisplayInfo, - ITE_DEFAULT_SCENE, // Starting scene number - &ITEDemo_Resources, - ARRAYSIZE(ITEDEMO_GameFiles), // Game datafiles - ITEDEMO_GameFiles, - ARRAYSIZE(ITEDEMO_GameFonts), - ITEDEMO_GameFonts, - &ITEDEMO_GameSound, - &ITEDEMO_GameSound, - NULL, - 0, - NULL, - 0, // features - Common::EN_USA, - Common::kPlatformPC, - }, - - // Inherit the earth - MAC Demo version - { - "ite", - GType_ITE, - GID_ITE_MACDEMO2, - "Inherit the Earth: Quest for the Orb (MAC Demo)", - &ITE_DisplayInfo, - ITE_DEFAULT_SCENE, - &ITE_Resources, - ARRAYSIZE(ITEMACDEMO_GameFiles), - ITEMACDEMO_GameFiles, - ARRAYSIZE(ITEWINDEMO_GameFonts), - ITEWINDEMO_GameFonts, - &ITEMACDEMO_GameVoice, - &ITEMACDEMO_GameSound, - &ITEMACDEMO_GameMusic, - ARRAYSIZE(ITEMacPatch_Files), - ITEMacPatch_Files, - GF_BIG_ENDIAN_DATA | GF_WYRMKEEP | GF_CD_FX | GF_SCENE_SUBSTITUTES, - Common::EN_USA, - Common::kPlatformMacintosh, - }, - - // Inherit the earth - early MAC Demo version - { - "ite", - GType_ITE, - GID_ITE_MACDEMO1, - "Inherit the Earth: Quest for the Orb (early MAC Demo)", - &ITE_DisplayInfo, - ITE_DEFAULT_SCENE, - &ITE_Resources, - ARRAYSIZE(ITEMACDEMO_GameFiles), - ITEMACDEMO_GameFiles, - ARRAYSIZE(ITEWINDEMO_GameFonts), - ITEWINDEMO_GameFonts, - &ITEMACDEMO_GameVoice, - &ITEMACDEMO_GameSound, - &ITEMACCD_GameMusic, - ARRAYSIZE(ITEMacPatch_Files), - ITEMacPatch_Files, - GF_BIG_ENDIAN_DATA | GF_WYRMKEEP | GF_CD_FX, - Common::EN_USA, - Common::kPlatformMacintosh, - }, - - // Inherit the earth - MAC CD Guild version - { - "ite", - GType_ITE, - GID_ITE_MACCD_G, - "Inherit the Earth: Quest for the Orb (MAC CD)", - &ITE_DisplayInfo, - ITE_DEFAULT_SCENE, - &ITE_Resources, - ARRAYSIZE(ITEMACCD_G_GameFiles), - ITEMACCD_G_GameFiles, - ARRAYSIZE(ITEWINDEMO_GameFonts), - ITEWINDEMO_GameFonts, - &ITEMACCD_G_GameSound, - &ITEMACCD_G_GameSound, - NULL, - 0, - NULL, - GF_BIG_ENDIAN_DATA | GF_CD_FX, - Common::EN_USA, - Common::kPlatformMacintosh, - }, - - // Inherit the earth - MAC CD Wyrmkeep version - { - "ite", - GType_ITE, - GID_ITE_MACCD, - "Inherit the Earth: Quest for the Orb (Wyrmkeep MAC CD)", - &ITE_DisplayInfo, - ITE_DEFAULT_SCENE, - &ITE_Resources, - ARRAYSIZE(ITEMACCD_GameFiles), - ITEMACCD_GameFiles, - ARRAYSIZE(ITEWINDEMO_GameFonts), - ITEWINDEMO_GameFonts, - &ITEMACCD_GameSound, - &ITEMACCD_GameSound, - &ITEMACCD_GameMusic, - ARRAYSIZE(ITEMacPatch_Files), - ITEMacPatch_Files, - GF_BIG_ENDIAN_DATA | GF_WYRMKEEP | GF_CD_FX, - Common::EN_USA, - Common::kPlatformMacintosh, - }, - - // Inherit the earth - Linux Demo version - // Note: it should be before GID_ITE_WINDEMO2 version - { - "ite", - GType_ITE, - GID_ITE_LINDEMO, - "Inherit the Earth: Quest for the Orb (Linux Demo)", - &ITE_DisplayInfo, - ITE_DEFAULT_SCENE, - &ITE_Resources, - ARRAYSIZE(ITELINDEMO_GameFiles), - ITELINDEMO_GameFiles, - ARRAYSIZE(ITEWINDEMO_GameFonts), - ITEWINDEMO_GameFonts, - &ITEWINDEMO2_GameVoice, - &ITEWINDEMO2_GameSound, - &ITELINDEMO_GameMusic, - ARRAYSIZE(ITELinPatch_Files), - ITELinPatch_Files, - GF_WYRMKEEP | GF_CD_FX | GF_SCENE_SUBSTITUTES, - Common::EN_USA, - Common::kPlatformLinux, - }, - - // Inherit the earth - Win32 Demo version - { - "ite", - GType_ITE, - GID_ITE_WINDEMO2, - "Inherit the Earth: Quest for the Orb (Win32 Demo)", - &ITE_DisplayInfo, - ITE_DEFAULT_SCENE, - &ITE_Resources, - ARRAYSIZE(ITEWINDEMO_GameFiles), - ITEWINDEMO_GameFiles, - ARRAYSIZE(ITEWINDEMO_GameFonts), - ITEWINDEMO_GameFonts, - &ITEWINDEMO2_GameVoice, - &ITEWINDEMO2_GameSound, - NULL, - ARRAYSIZE(ITEWinPatch2_Files), - ITEWinPatch2_Files, - GF_WYRMKEEP | GF_CD_FX | GF_SCENE_SUBSTITUTES, - Common::EN_USA, - Common::kPlatformWindows, - }, - - // Inherit the earth - early Win32 Demo version - { - "ite", - GType_ITE, - GID_ITE_WINDEMO1, - "Inherit the Earth: Quest for the Orb (early Win32 Demo)", - &ITE_DisplayInfo, - ITE_DEFAULT_SCENE, - &ITE_Resources, - ARRAYSIZE(ITEWINDEMO_GameFiles), - ITEWINDEMO_GameFiles, - ARRAYSIZE(ITEWINDEMO_GameFonts), - ITEWINDEMO_GameFonts, - &ITEWINDEMO1_GameSound, - &ITEWINDEMO1_GameSound, - NULL, - ARRAYSIZE(ITEWinPatch1_Files), - ITEWinPatch1_Files, - GF_WYRMKEEP | GF_CD_FX, - Common::EN_USA, - Common::kPlatformWindows, - }, - - // Inherit the earth - Wyrmkeep combined Windows/Mac/Linux CD - { - "ite", - GType_ITE, - GID_ITE_MULTICD, - "Inherit the Earth: Quest for the Orb (Multi-OS CD Version)", - &ITE_DisplayInfo, - ITE_DEFAULT_SCENE, - &ITE_Resources, - ARRAYSIZE(ITEMULTICD_GameFiles), - ITEMULTICD_GameFiles, - ARRAYSIZE(ITECD_GameFonts), - ITECD_GameFonts, - &ITEMACCD_GameSound, - &ITECD_GameSound, - &ITEMACCD_GameMusic, - 0, - NULL, - GF_WYRMKEEP | GF_CD_FX, - Common::EN_USA, - Common::kPlatformUnknown, - }, - - // Inherit the earth - Wyrmkeep Linux CD version - { - "ite", - GType_ITE, - GID_ITE_LINCD, - "Inherit the Earth: Quest for the Orb (Linux CD Version)", - &ITE_DisplayInfo, - ITE_DEFAULT_SCENE, - &ITE_Resources, - ARRAYSIZE(ITELINCD_GameFiles), - ITELINCD_GameFiles, - ARRAYSIZE(ITECD_GameFonts), - ITECD_GameFonts, - &ITECD_GameSound, - &ITECD_GameSound, - &ITEMACCD_GameMusic, - ARRAYSIZE(ITELinPatch_Files), - ITELinPatch_Files, - GF_WYRMKEEP | GF_CD_FX, - Common::EN_USA, - Common::kPlatformLinux, - }, - - // Inherit the earth - Wyrmkeep Windows CD version - { - "ite", - GType_ITE, - GID_ITE_WINCD, - "Inherit the Earth: Quest for the Orb (Win32 CD Version)", - &ITE_DisplayInfo, - ITE_DEFAULT_SCENE, - &ITE_Resources, - ARRAYSIZE(ITECD_GameFiles), - ITECD_GameFiles, - ARRAYSIZE(ITECD_GameFonts), - ITECD_GameFonts, - &ITECD_GameSound, - &ITECD_GameSound, - NULL, - ARRAYSIZE(ITEWinPatch1_Files), - ITEWinPatch1_Files, - GF_WYRMKEEP | GF_CD_FX, - Common::EN_USA, - Common::kPlatformWindows, - }, - - // Inherit the earth - DOS CD version - { - "ite", - GType_ITE, - GID_ITE_CD_G, - "Inherit the Earth: Quest for the Orb (DOS CD Version)", - &ITE_DisplayInfo, - ITE_DEFAULT_SCENE, - &ITE_Resources, - ARRAYSIZE(ITECD_GameFiles), - ITECD_GameFiles, - ARRAYSIZE(ITECD_GameFonts), - ITECD_GameFonts, - &ITECD_GameSound, - &ITECD_GameSound, - NULL, - 0, - NULL, - GF_CD_FX, - Common::EN_USA, - Common::kPlatformPC, - }, - - // Inherit the earth - DOS CD version with digital music - { - "ite", - GType_ITE, - GID_ITE_CD_G2, - "Inherit the Earth: Quest for the Orb (DOS CD Version)", - &ITE_DisplayInfo, - ITE_DEFAULT_SCENE, - &ITE_Resources, - ARRAYSIZE(ITECD2_GameFiles), - ITECD2_GameFiles, - ARRAYSIZE(ITECD_GameFonts), - ITECD_GameFonts, - &ITECD_GameSound, - &ITECD_GameSound, - &ITEMACCD_GameMusic, - 0, - NULL, - GF_CD_FX, - Common::EN_USA, - Common::kPlatformPC, - }, - - // Inherit the earth - DOS CD German version - { - "ite", - GType_ITE, - GID_ITE_CD_DE, - "Inherit the Earth: Quest for the Orb (De DOS CD Version)", - &ITE_DisplayInfo, - ITE_DEFAULT_SCENE, - &ITE_Resources, - ARRAYSIZE(ITECD_GameFiles), - ITECD_GameFiles, - ARRAYSIZE(ITECD_GameFonts), - ITECD_GameFonts, - &ITECD_GameSound, - &ITECD_GameSound, - NULL, - 0, - NULL, - GF_CD_FX, - Common::DE_DEU, - Common::kPlatformPC, - }, - - // Inherit the earth - DOS CD German version with digital music - { - "ite", - GType_ITE, - GID_ITE_CD_DE2, - "Inherit the Earth: Quest for the Orb (De DOS CD Version)", - &ITE_DisplayInfo, - ITE_DEFAULT_SCENE, - &ITE_Resources, - ARRAYSIZE(ITECD2_GameFiles), - ITECD2_GameFiles, - ARRAYSIZE(ITECD_GameFonts), - ITECD_GameFonts, - &ITECD_GameSound, - &ITECD_GameSound, - &ITEMACCD_GameMusic, - 0, - NULL, - GF_CD_FX, - Common::DE_DEU, - Common::kPlatformPC, - }, - - // Inherit the earth - CD version - { - "ite", - GType_ITE, - GID_ITE_CD, - "Inherit the Earth: Quest for the Orb (DOS CD Version)", - &ITE_DisplayInfo, - ITE_DEFAULT_SCENE, - &ITE_Resources, - ARRAYSIZE(ITECD_GameFiles), - ITECD_GameFiles, - ARRAYSIZE(ITECD_GameFonts), - ITECD_GameFonts, - &ITECD_GameSound, - &ITECD_GameSound, - NULL, - 0, - NULL, - GF_CD_FX, - Common::EN_USA, - Common::kPlatformPC, - }, - - // Inherit the earth - German Floppy version - { - "ite", - GType_ITE, - GID_ITE_DISK_DE, - "Inherit the Earth: Quest for the Orb (De DOS Floppy)", - &ITE_DisplayInfo, - ITE_DEFAULT_SCENE, - &ITE_Resources, - ARRAYSIZE(ITEDISK_GameFiles), - ITEDISK_GameFiles, - ARRAYSIZE(ITEDISK_GameFonts), - ITEDISK_GameFonts, - &ITEDISK_GameSound, - &ITEDISK_GameSound, - NULL, - 0, - NULL, - 0, - Common::DE_DEU, - Common::kPlatformPC, - }, - - // Inherit the earth - German Floppy version with digital music - { - "ite", - GType_ITE, - GID_ITE_DISK_DE2, - "Inherit the Earth: Quest for the Orb (De DOS Floppy)", - &ITE_DisplayInfo, - ITE_DEFAULT_SCENE, - &ITE_Resources, - ARRAYSIZE(ITEDISK2_GameFiles), - ITEDISK2_GameFiles, - ARRAYSIZE(ITEDISK_GameFonts), - ITEDISK_GameFonts, - &ITEDISK_GameSound, - &ITEDISK_GameSound, - &ITEMACCD_GameMusic, - 0, - NULL, - 0, - Common::DE_DEU, - Common::kPlatformPC, - }, - - // Inherit the earth - Disk version - { - "ite", - GType_ITE, - GID_ITE_DISK_G, - "Inherit the Earth: Quest for the Orb (DOS Floppy)", - &ITE_DisplayInfo, - ITE_DEFAULT_SCENE, - &ITE_Resources, - ARRAYSIZE(ITEDISK_GameFiles), - ITEDISK_GameFiles, - ARRAYSIZE(ITEDISK_GameFonts), - ITEDISK_GameFonts, - &ITEDISK_GameSound, - &ITEDISK_GameSound, - NULL, - 0, - NULL, - 0, - Common::EN_USA, - Common::kPlatformPC, - }, - - // Inherit the earth - Disk version with digital music - { - "ite", - GType_ITE, - GID_ITE_DISK_G2, - "Inherit the Earth: Quest for the Orb (DOS Floppy)", - &ITE_DisplayInfo, - ITE_DEFAULT_SCENE, - &ITE_Resources, - ARRAYSIZE(ITEDISK2_GameFiles), - ITEDISK2_GameFiles, - ARRAYSIZE(ITEDISK_GameFonts), - ITEDISK_GameFonts, - &ITEDISK_GameSound, - &ITEDISK_GameSound, - &ITEMACCD_GameMusic, - 0, - NULL, - 0, - Common::EN_USA, - Common::kPlatformPC, - }, - - // I Have No Mouth And I Must Scream - Demo version - { - "ihnm", - GType_IHNM, - GID_IHNM_DEMO, - "I Have No Mouth and I Must Scream (DOS Demo)", - &IHNM_DisplayInfo, - 0, - &IHNM_Resources, - ARRAYSIZE(IHNMDEMO_GameFiles), - IHNMDEMO_GameFiles, - ARRAYSIZE(IHNMDEMO_GameFonts), - IHNMDEMO_GameFonts, - &IHNM_GameSound, - &IHNM_GameSound, - NULL, - 0, - NULL, - GF_DEFAULT_TO_1X_SCALER, - Common::EN_USA, - Common::kPlatformPC, - }, - - // I Have No Mouth And I Must Scream - CD version - { - "ihnm", - GType_IHNM, - GID_IHNM_CD, - "I Have No Mouth and I Must Scream (DOS)", - &IHNM_DisplayInfo, - IHNM_DEFAULT_SCENE, - &IHNM_Resources, - ARRAYSIZE(IHNMCD_GameFiles), - IHNMCD_GameFiles, - ARRAYSIZE(IHNMCD_GameFonts), - IHNMCD_GameFonts, - &IHNM_GameSound, - &IHNM_GameSound, - NULL, - 0, - NULL, - GF_DEFAULT_TO_1X_SCALER, - Common::EN_USA, - Common::kPlatformPC, - }, - - // I Have No Mouth And I Must Scream - De CD version - { - "ihnm", - GType_IHNM, - GID_IHNM_CD_DE, - "I Have No Mouth and I Must Scream (DE DOS)", - &IHNM_DisplayInfo, - IHNM_DEFAULT_SCENE, - &IHNM_Resources, - ARRAYSIZE(IHNMCD_Censored_GameFiles), - IHNMCD_Censored_GameFiles, - ARRAYSIZE(IHNMCD_GameFonts), - IHNMCD_GameFonts, - &IHNM_GameSound, - &IHNM_GameSound, - NULL, - 0, - NULL, - GF_DEFAULT_TO_1X_SCALER, - Common::DE_DEU, - Common::kPlatformPC, - }, - // I Have No Mouth And I Must Scream - Sp CD version - { - "ihnm", - GType_IHNM, - GID_IHNM_CD_ES, - "I Have No Mouth and I Must Scream (Sp DOS)", - &IHNM_DisplayInfo, - IHNM_DEFAULT_SCENE, - &IHNM_Resources, - ARRAYSIZE(IHNMCD_GameFiles), - IHNMCD_GameFiles, - ARRAYSIZE(IHNMCD_GameFonts), - IHNMCD_GameFonts, - &IHNM_GameSound, - &IHNM_GameSound, - NULL, - 0, - NULL, - GF_DEFAULT_TO_1X_SCALER, - Common::ES_ESP, - Common::kPlatformPC, - }, - // I Have No Mouth And I Must Scream - Ru CD version - { - "ihnm", - GType_IHNM, - GID_IHNM_CD_RU, - "I Have No Mouth and I Must Scream (Ru DOS)", - &IHNM_DisplayInfo, - IHNM_DEFAULT_SCENE, - &IHNM_Resources, - ARRAYSIZE(IHNMCD_GameFiles), - IHNMCD_GameFiles, - ARRAYSIZE(IHNMCD_GameFonts), - IHNMCD_GameFonts, - &IHNM_GameSound, - &IHNM_GameSound, - NULL, - 0, - NULL, - GF_DEFAULT_TO_1X_SCALER, - Common::RU_RUS, - Common::kPlatformPC, - }, - // I Have No Mouth And I Must Scream - Fr CD version - { - "ihnm", - GType_IHNM, - GID_IHNM_CD_FR, - "I Have No Mouth and I Must Scream (Fr DOS)", - &IHNM_DisplayInfo, - IHNM_DEFAULT_SCENE, - &IHNM_Resources, - ARRAYSIZE(IHNMCD_Censored_GameFiles), - IHNMCD_Censored_GameFiles, - ARRAYSIZE(IHNMCD_GameFonts), - IHNMCD_GameFonts, - &IHNM_GameSound, - &IHNM_GameSound, - NULL, - 0, - NULL, - GF_DEFAULT_TO_1X_SCALER, - Common::FR_FRA, - Common::kPlatformPC, - }, -}; - -bool SagaEngine::initGame() { - uint16 gameCount = ARRAYSIZE(gameDescriptions); - int gameNumber = -1; - FSList dummy; - DetectedGameList detectedGames; - int *matches; - Common::Language language = Common::UNK_LANG; - Common::Platform platform = Common::kPlatformUnknown; - - if (ConfMan.hasKey("language")) - language = Common::parseLanguage(ConfMan.get("language")); - if (ConfMan.hasKey("platform")) - platform = Common::parsePlatform(ConfMan.get("platform")); - - - detectedGames = GAME_ProbeGame(dummy, &matches); - - if (detectedGames.size() == 0) { - warning("No valid games were found in the specified directory."); - return false; - } - - // If we have more than one match then try to match by platform and - // language - int count = 0; - if (detectedGames.size() > 1) { - for (int i = 0; i < ARRAYSIZE(gameDescriptions); i++) - if (matches[i] != -1) { - if ((gameDescriptions[matches[i]].language != language && - language != Common::UNK_LANG) || - (gameDescriptions[matches[i]].platform != platform && - platform != Common::kPlatformUnknown)) { - debug(2, "Purged (pass 2) %s", gameDescriptions[matches[i]].title); - matches[i] = -1; - } - else - count++; - } - } else - count = 1; - - if (count != 1) - warning("Conflicting targets detected (%d)", count); - - for (int i = 0; i < ARRAYSIZE(gameDescriptions); i++) - if (matches[i] != -1) { - gameNumber = matches[i]; - break; - } - - free(matches); - - if (gameNumber >= gameCount || gameNumber == -1) { - error("SagaEngine::loadGame wrong gameNumber"); - } - - debug(2, "Running %s", gameDescriptions[gameNumber].title); - - _gameNumber = gameNumber; - _gameDescription = &gameDescriptions[gameNumber]; - _gameDisplayInfo = *_gameDescription->gameDisplayInfo; - _displayClip.right = _gameDisplayInfo.logicalWidth; - _displayClip.bottom = _gameDisplayInfo.logicalHeight; - - if (!_resource->createContexts()) { - return false; - } - return true; -} - -DetectedGameList GAME_ProbeGame(const FSList &fslist, int **retmatches) { - DetectedGameList detectedGames; - int game_n; - int index = 0, i, j; - int matches[ARRAYSIZE(gameDescriptions)]; - bool mode = retmatches ? false : true; - - game_n = -1; - for (i = 0; i < ARRAYSIZE(gameDescriptions); i++) - matches[i] = -1; - - while (1) { - game_n = detectGame(fslist, mode, game_n); - if (game_n == -1) - break; - matches[index++] = game_n; - } - - // We have some resource sets which are superpositions of other - // Particularly it is ite-demo-linux vs ite-demo-win - // Now remove lesser set if bigger matches too - - if (index > 1) { - // Search max number - int maxcount = 0; - for (i = 0; i < index; i++) { - int count = 0; - for (j = 0; j < ARRAYSIZE(gameMD5); j++) - if (gameMD5[j].id == gameDescriptions[matches[i]].gameId) - count++; - maxcount = MAX(maxcount, count); - } - - // Now purge targets with number of files lesser than max - for (i = 0; i < index; i++) { - int count = 0; - for (j = 0; j < ARRAYSIZE(gameMD5); j++) - if (gameMD5[j].id == gameDescriptions[matches[i]].gameId) - count++; - if (count < maxcount) { - debug(2, "Purged: %s", gameDescriptions[matches[i]].title); - matches[i] = -1; - } - } - - } - - // and now push them into list of detected games - for (i = 0; i < index; i++) - if (matches[i] != -1) - detectedGames.push_back(DetectedGame(gameDescriptions[matches[i]].toGameSettings(), - gameDescriptions[matches[i]].language, - gameDescriptions[matches[i]].platform)); - - if (retmatches) { - *retmatches = (int *)calloc(ARRAYSIZE(gameDescriptions), sizeof(int)); - for (i = 0; i < ARRAYSIZE(gameDescriptions); i++) - (*retmatches)[i] = matches[i]; - } - - return detectedGames; -} - -int detectGame(const FSList &fslist, bool mode, int start) { - int game_count = ARRAYSIZE(gameDescriptions); - int game_n = -1; - typedef Common::Map<Common::String, Common::String> StringMap; - StringMap filesMD5; - - typedef Common::Map<Common::String, bool> StringSet; - StringSet filesList; - - uint16 file_count; - uint16 file_n; - Common::File test_file; - bool file_missing; - - Common::String tstr, tstr1; - char md5str[32+1]; - uint8 md5sum[16]; - - // First we compose list of files which we need MD5s for - for (int i = 0; i < ARRAYSIZE(gameMD5); i++) { - tstr = Common::String(gameMD5[i].filename); - tstr.toLowercase(); - - if (gameMD5[i].caseSensitive && !mode) - filesList[Common::String(gameMD5[i].filename)] = true; - else - filesList[tstr] = true; - } - - if (mode) { - // Now count MD5s for required files - for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) { - if (!file->isDirectory()) { - tstr = file->displayName(); - // FIXME: there is a bug in String class. tstr1 = tstr; tstr.toLowercase() - // makes tstr1 lowercase as well - tstr1 = Common::String(file->displayName().c_str()); - tstr.toLowercase(); - - if (filesList.contains(tstr) || filesList.contains(tstr1)) { - if (Common::md5_file(file->path().c_str(), md5sum, NULL, FILE_MD5_BYTES)) { - for (int j = 0; j < 16; j++) { - sprintf(md5str + j*2, "%02x", (int)md5sum[j]); - } - filesMD5[tstr] = Common::String(md5str); - filesMD5[tstr1] = Common::String(md5str); - } - } - } - } - } else { - Common::File testFile; - - for (StringSet::const_iterator file = filesList.begin(); file != filesList.end(); ++file) { - if (testFile.open(file->_key.c_str())) { - testFile.close(); - if (Common::md5_file(file->_key.c_str(), md5sum, NULL, FILE_MD5_BYTES)) { - for (int j = 0; j < 16; j++) { - sprintf(md5str + j*2, "%02x", (int)md5sum[j]); - } - filesMD5[file->_key] = Common::String(md5str); - } - } - } - } - - for (game_n = start + 1; game_n < game_count; game_n++) { - file_count = gameDescriptions[game_n].filesCount; - file_missing = false; - - // Try to open all files for this game - for (file_n = 0; file_n < file_count; file_n++) { - tstr = gameDescriptions[game_n].filesDescriptions[file_n].fileName; - - if (!filesMD5.contains(tstr)) { - file_missing = true; - break; - } - } - - // Try the next game, couldn't find all files for the current - // game - if (file_missing) { - continue; - } else { - bool match = true; - - debug(2, "Probing game: %s", gameDescriptions[game_n].title); - - for (int i = 0; i < ARRAYSIZE(gameMD5); i++) { - if (gameMD5[i].id == gameDescriptions[game_n].gameId) { - tstr = gameMD5[i].filename; - - if (strcmp(gameMD5[i].md5, filesMD5[tstr].c_str())) { - match = false; - break; - } - } - } - if (!match) - continue; - - debug(2, "Found game: %s", gameDescriptions[game_n].title); - - return game_n; - } - } - - if (!filesMD5.isEmpty() && start == -1) { - printf("MD5s of your game version are unknown. Please, report following data to\n"); - printf("ScummVM team along with your game name and version:\n"); - - for (StringMap::const_iterator file = filesMD5.begin(); file != filesMD5.end(); ++file) - printf("%s: %s\n", file->_key.c_str(), file->_value.c_str()); - } - - return -1; -} - -} // End of namespace Saga diff --git a/saga/gfx.cpp b/saga/gfx.cpp deleted file mode 100644 index 4de8c52de2..0000000000 --- a/saga/gfx.cpp +++ /dev/null @@ -1,485 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Misc. graphics routines - -#include "saga/saga.h" -#include "saga/gfx.h" -#include "saga/interface.h" -#include "saga/resnames.h" -#include "saga/rscfile.h" -#include "saga/scene.h" -#include "saga/stream.h" - -#include "common/system.h" - -namespace Saga { - -Gfx::Gfx(SagaEngine *vm, OSystem *system, int width, int height, GameDetector &detector) : _vm(vm), _system(system) { - _system->beginGFXTransaction(); - _vm->initCommonGFX(detector); - _system->initSize(width, height); - _system->endGFXTransaction(); - - debug(5, "Init screen %dx%d", width, height); - // Convert surface data to R surface data - _backBuffer.create(width, height, 1); - - // Set module data - _init = 1; - - // Start with the cursor shown. It will be hidden before the intro, if - // there is an intro. (With boot params, there may not be.) - setCursor(kCursorNormal); - showCursor(true); -} - -Gfx::~Gfx() { - _backBuffer.free(); -} - -void Surface::drawPalette() { - int x; - int y; - int color = 0; - Rect palRect; - - for (y = 0; y < 16; y++) { - palRect.top = (y * 8) + 4; - palRect.bottom = palRect.top + 8; - - for (x = 0; x < 16; x++) { - palRect.left = (x * 8) + 4; - palRect.right = palRect.left + 8; - - drawRect(palRect, color); - color++; - } - } -} - -// * Copies a rectangle from a raw 8 bit pixel buffer to the specified surface. -// - The surface must match the logical dimensions of the buffer exactly. -void Surface::blit(const Common::Rect &destRect, const byte *sourceBuffer) { - const byte *readPointer; - byte *writePointer; - int row; - ClipData clipData; - - clipData.sourceRect.left = 0; - clipData.sourceRect.top = 0; - clipData.sourceRect.right = destRect.width(); - clipData.sourceRect.bottom = destRect.height(); - - clipData.destPoint.x = destRect.left; - clipData.destPoint.y = destRect.top; - clipData.destRect.left = 0; - clipData.destRect.right = w; - clipData.destRect.top = 0; - clipData.destRect.bottom = h; - - if (!clipData.calcClip()) { - return; - } - - // Transfer buffer data to surface - readPointer = (sourceBuffer + clipData.drawSource.x) + - (clipData.sourceRect.right * clipData.drawSource.y); - - writePointer = ((byte *)pixels + clipData.drawDest.x) + (pitch * clipData.drawDest.y); - - for (row = 0; row < clipData.drawHeight; row++) { - memcpy(writePointer, readPointer, clipData.drawWidth); - - writePointer += pitch; - readPointer += clipData.sourceRect.right; - } -} - -void Surface::drawPolyLine(const Point *points, int count, int color) { - int i; - if (count >= 3) { - for (i = 1; i < count; i++) { - drawLine(points[i].x, points[i].y, points[i - 1].x, points[i - 1].y, color); - } - - drawLine(points[count - 1].x, points[count - 1].y, points->x, points->y, color); - } -} - -/** -* Dissolve one image with another. -* If flags if set to 1, do zero masking. -*/ -void Surface::transitionDissolve(const byte *sourceBuffer, const Common::Rect &sourceRect, int flags, double percent) { -#define XOR_MASK 0xB400; - int pixelcount = w * h; - int seqlimit = (int)(65535 * percent); - int seq = 1; - int i, x1, y1; - byte color; - - for (i = 0; i < seqlimit; i++) { - if (seq & 1) { - seq = (seq >> 1) ^ XOR_MASK; - } else { - seq = seq >> 1; - } - - if (seq == 1) { - return; - } - - if (seq >= pixelcount) { - continue; - } else { - x1 = seq % w; - y1 = seq / w; - - if (sourceRect.contains(x1, y1)) { - color = sourceBuffer[(x1-sourceRect.left) + sourceRect.width()*(y1-sourceRect.top)]; - if (flags == 0 || color) - ((byte*)pixels)[seq] = color; - } - } - } -} - -void Gfx::initPalette() { - if(_vm->getGameType() != GType_IHNM) - return; - - ResourceContext *resourceContext = _vm->_resource->getContext(GAME_RESOURCEFILE); - if (resourceContext == NULL) { - error("Resource::loadGlobalResources() resource context not found"); - } - - byte *resourcePointer; - size_t resourceLength; - - _vm->_resource->loadResource(resourceContext, RID_IHNM_DEFAULT_PALETTE, - resourcePointer, resourceLength); - - MemoryReadStream metaS(resourcePointer, resourceLength); - - for(int i = 0; i < 256; i++) { - _globalPalette[i].red = metaS.readByte(); - _globalPalette[i].green = metaS.readByte(); - _globalPalette[i].blue = metaS.readByte(); - } - - free(resourcePointer); - - setPalette(_globalPalette, true); -} - -void Gfx::setPalette(const PalEntry *pal, bool full) { - int i; - byte *ppal; - int from, numcolors; - - if (_vm->getGameType() != GType_IHNM || full) { - from = 0; - numcolors = PAL_ENTRIES; - } else { - from = 0; - numcolors = 248; - } - - for (i = 0, ppal = &_currentPal[from * 4]; i < numcolors; i++, ppal += 4) { - ppal[0] = _globalPalette[i].red = pal[i].red; - ppal[1] = _globalPalette[i].green = pal[i].green; - ppal[2] = _globalPalette[i].blue = pal[i].blue; - ppal[3] = 0; - } - - // Make 256th color black. See bug #1256368 - if ((_vm->getPlatform() == Common::kPlatformMacintosh) && !_vm->_scene->isInIntro()) - memset(&_currentPal[255 * 4], 0, 4); - - _system->setPalette(_currentPal, 0, PAL_ENTRIES); -} - -void Gfx::setPaletteColor(int n, int r, int g, int b) { - bool update = false; - - // This function may get called a lot. To avoid forcing full-screen - // updates, only update the palette if the color actually changes. - - if (_currentPal[4 * n + 0] != r) { - _currentPal[4 * n + 0] = _globalPalette[n].red = r; - update = true; - } - if (_currentPal[4 * n + 1] != g) { - _currentPal[4 * n + 1] = _globalPalette[n].green = g; - update = true; - } - if (_currentPal[4 * n + 2] != b) { - _currentPal[4 * n + 2] = _globalPalette[n].blue = b; - update = true; - } - if (_currentPal[4 * n + 3] != 0) { - _currentPal[4 * n + 3] = 0; - update = true; - } - - if (update) - _system->setPalette(_currentPal, n, 1); -} - -void Gfx::getCurrentPal(PalEntry *src_pal) { - int i; - byte *ppal; - - for (i = 0, ppal = _currentPal; i < PAL_ENTRIES; i++, ppal += 4) { - src_pal[i].red = ppal[0]; - src_pal[i].green = ppal[1]; - src_pal[i].blue = ppal[2]; - } -} - -void Gfx::palToBlack(PalEntry *srcPal, double percent) { - int i; - //int fade_max = 255; - int new_entry; - byte *ppal; - PalEntry *palE; - int from, numcolors; - - double fpercent; - - if (_vm->getGameType() != GType_IHNM) { - from = 0; - numcolors = PAL_ENTRIES; - } else { - from = 0; - numcolors = 248; - } - - if (percent > 1.0) { - percent = 1.0; - } - - // Exponential fade - fpercent = percent * percent; - - fpercent = 1.0 - fpercent; - - // Use the correct percentage change per frame for each palette entry - for (i = 0, ppal = _currentPal; i < PAL_ENTRIES; i++, ppal += 4) { - if (i < from || i >= from + numcolors) - palE = &_globalPalette[i]; - else - palE = &srcPal[i]; - - new_entry = (int)(palE->red * fpercent); - - if (new_entry < 0) { - ppal[0] = 0; - } else { - ppal[0] = (byte) new_entry; - } - - new_entry = (int)(palE->green * fpercent); - - if (new_entry < 0) { - ppal[1] = 0; - } else { - ppal[1] = (byte) new_entry; - } - - new_entry = (int)(palE->blue * fpercent); - - if (new_entry < 0) { - ppal[2] = 0; - } else { - ppal[2] = (byte) new_entry; - } - ppal[3] = 0; - } - - // Make 256th color black. See bug #1256368 - if ((_vm->getPlatform() == Common::kPlatformMacintosh) && !_vm->_scene->isInIntro()) - memset(&_currentPal[255 * 4], 0, 4); - - _system->setPalette(_currentPal, 0, PAL_ENTRIES); -} - -void Gfx::blackToPal(PalEntry *srcPal, double percent) { - int new_entry; - double fpercent; - byte *ppal; - int i; - PalEntry *palE; - int from, numcolors; - - if (_vm->getGameType() != GType_IHNM) { - from = 0; - numcolors = PAL_ENTRIES; - } else { - from = 0; - numcolors = 248; - } - - if (percent > 1.0) { - percent = 1.0; - } - - // Exponential fade - fpercent = percent * percent; - - fpercent = 1.0 - fpercent; - - // Use the correct percentage change per frame for each palette entry - for (i = 0, ppal = _currentPal; i < PAL_ENTRIES; i++, ppal += 4) { - if (i < from || i >= from + numcolors) - palE = &_globalPalette[i]; - else - palE = &srcPal[i]; - - new_entry = (int)(palE->red - palE->red * fpercent); - - if (new_entry < 0) { - ppal[0] = 0; - } else { - ppal[0] = (byte)new_entry; - } - - new_entry = (int)(palE->green - palE->green * fpercent); - - if (new_entry < 0) { - ppal[1] = 0; - } else { - ppal[1] = (byte) new_entry; - } - - new_entry = (int)(palE->blue - palE->blue * fpercent); - - if (new_entry < 0) { - ppal[2] = 0; - } else { - ppal[2] = (byte) new_entry; - } - ppal[3] = 0; - } - - // Make 256th color black. See bug #1256368 - if ((_vm->getPlatform() == Common::kPlatformMacintosh) && !_vm->_scene->isInIntro()) - memset(&_currentPal[255 * 4], 0, 4); - - _system->setPalette(_currentPal, 0, PAL_ENTRIES); -} - -void Gfx::showCursor(bool state) { - g_system->showMouse(state); -} - -void Gfx::setCursor(CursorType cursorType) { - if (_vm->getGameType() == GType_ITE) { - // Set up the mouse cursor - const byte A = kITEColorLightGrey; - const byte B = kITEColorWhite; - - const byte cursor_img[CURSOR_W * CURSOR_H] = { - 0, 0, 0, A, 0, 0, 0, - 0, 0, 0, A, 0, 0, 0, - 0, 0, 0, A, 0, 0, 0, - A, A, A, B, A, A, A, - 0, 0, 0, A, 0, 0, 0, - 0, 0, 0, A, 0, 0, 0, - 0, 0, 0, A, 0, 0, 0, - }; - - _system->setMouseCursor(cursor_img, CURSOR_W, CURSOR_H, 3, 3, 0); - } else { - uint32 resourceId; - - switch (cursorType) { - case kCursorBusy: - resourceId = RID_IHNM_HOURGLASS_CURSOR; - break; - default: - resourceId = (uint32)-1; - break; - } - - byte *resource; - size_t resourceLength; - byte *image; - size_t imageLength; - int width, height; - - if (resourceId != (uint32)-1) { - ResourceContext *context = _vm->_resource->getContext(GAME_RESOURCEFILE); - - _vm->_resource->loadResource(context, resourceId, resource, resourceLength); - - _vm->decodeBGImage(resource, resourceLength, &image, &imageLength, &width, &height); - } else { - resource = NULL; - width = height = 31; - image = (byte *)calloc(width, height); - - for (int i = 0; i < 14; i++) { - image[15 * 31 + i] = 1; - image[15 * 31 + 30 - i] = 1; - image[i * 31 + 15] = 1; - image[(30 - i) * 31 + 15] = 1; - } - } - - // Note: Hard-coded hotspot - _system->setMouseCursor(image, width, height, 15, 15, 0); - - free(image); - free(resource); - } -} - -bool hitTestPoly(const Point *points, unsigned int npoints, const Point& test_point) { - int yflag0; - int yflag1; - bool inside_flag = false; - unsigned int pt; - - const Point *vtx0 = &points[npoints - 1]; - const Point *vtx1 = &points[0]; - - yflag0 = (vtx0->y >= test_point.y); - for (pt = 0; pt < npoints; pt++, vtx1++) { - yflag1 = (vtx1->y >= test_point.y); - if (yflag0 != yflag1) { - if (((vtx1->y - test_point.y) * (vtx0->x - vtx1->x) >= - (vtx1->x - test_point.x) * (vtx0->y - vtx1->y)) == yflag1) { - inside_flag = !inside_flag; - } - } - yflag0 = yflag1; - vtx0 = vtx1; - } - - return inside_flag; -} - -} // End of namespace Saga diff --git a/saga/gfx.h b/saga/gfx.h deleted file mode 100644 index ff96cbf081..0000000000 --- a/saga/gfx.h +++ /dev/null @@ -1,164 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Graphics maniuplation routines - private header file - -#ifndef SAGA_GFX_H_ -#define SAGA_GFX_H_ - -#include "graphics/surface.h" - -namespace Saga { - -using Common::Point; -using Common::Rect; - -enum CursorType { - kCursorNormal, - kCursorBusy -}; - -struct ClipData { - // input members - Rect sourceRect; - Rect destRect; - Point destPoint; - - // output members - Point drawSource; - Point drawDest; - int drawWidth; - int drawHeight; - - bool calcClip() { - Common::Rect s; - - // Adjust the rect to draw to its screen coordinates - s = sourceRect; - s.left += destPoint.x; - s.right += destPoint.x; - s.top += destPoint.y; - s.bottom += destPoint.y; - - s.clip(destRect); - - if ((s.width() <= 0) || (s.height() <= 0)) { - return false; - } - - drawSource.x = s.left - sourceRect.left - destPoint.x; - drawSource.y = s.top - sourceRect.top - destPoint.y; - drawDest.x = s.left; - drawDest.y = s.top; - drawWidth = s.width(); - drawHeight = s.height(); - - return true; - } -}; - -#pragma START_PACK_STRUCTS -struct PalEntry { - byte red; - byte green; - byte blue; -} GCC_PACK; - -#pragma END_PACK_STRUCTS - -struct Color { - int red; - int green; - int blue; - int alpha; -}; - -struct Surface : Graphics::Surface { - - void transitionDissolve(const byte *sourceBuffer, const Common::Rect &sourceRect, int flags, double percent); - void drawPalette(); - void drawPolyLine(const Point *points, int count, int color); - void blit(const Common::Rect &destRect, const byte *sourceBuffer); - - void getRect(Common::Rect &rect) { - rect.left = rect.top = 0; - rect.right = w; - rect.bottom = h; - } - void drawFrame(const Common::Point &p1, const Common::Point &p2, int color) { - Common::Rect rect(MIN(p1.x, p2.x), MIN(p1.y, p2.y), MAX(p1.x, p2.x) + 1, MAX(p1.y, p2.y) + 1); - frameRect(rect, color); - } - void drawRect(const Common::Rect &destRect, int color) { - Common::Rect rect(w , h); - rect.clip(destRect); - - if (rect.isValidRect()) { - fillRect(rect, color); - } - } -}; - -#define PAL_ENTRIES 256 - -#define CURSOR_W 7 -#define CURSOR_H 7 - -#define CURSOR_ORIGIN_X 4 -#define CURSOR_ORIGIN_Y 4 - -bool hitTestPoly(const Point *points, unsigned int npoints, const Point& test_point); -class SagaEngine; - -class Gfx { -public: - - Gfx(SagaEngine *vm, OSystem *system, int width, int height, GameDetector &detector); - ~Gfx(); - Surface *getBackBuffer() { - return &_backBuffer; - } - - void initPalette(); - void setPalette(const PalEntry *pal, bool full = false); - void setPaletteColor(int n, int r, int g, int b); - void getCurrentPal(PalEntry *src_pal); - void palToBlack(PalEntry *src_pal, double percent); - void blackToPal(PalEntry *src_pal, double percent); - void showCursor(bool state); - -private: - void setCursor(CursorType cursorType = kCursorNormal); - int _init; - Surface _backBuffer; - byte _currentPal[PAL_ENTRIES * 4]; - OSystem *_system; - SagaEngine *_vm; - - PalEntry _globalPalette[PAL_ENTRIES]; -}; - -} // End of namespace Saga - -#endif diff --git a/saga/ihnm_introproc.cpp b/saga/ihnm_introproc.cpp deleted file mode 100644 index 881625c170..0000000000 --- a/saga/ihnm_introproc.cpp +++ /dev/null @@ -1,331 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// "I Have No Mouth" Intro sequence scene procedures - -#include "saga/saga.h" -#include "saga/gfx.h" - -#include "saga/animation.h" -#include "saga/events.h" -#include "saga/interface.h" -#include "saga/sndres.h" -#include "saga/music.h" - -#include "saga/scene.h" - -namespace Saga { - -SceneResourceData IHNM_IntroMovie1RL[] = { - {30, 2, 0, 0, false} , - {31, 14, 0, 0, false} -}; - -SceneDescription IHNM_IntroMovie1Desc = { - 0, 0, 0, 0, 0, 0, 0, 0, - IHNM_IntroMovie1RL, - ARRAYSIZE(IHNM_IntroMovie1RL) -}; - -SceneResourceData IHNM_IntroMovie2RL[] = { - {32, 2, 0, 0, false} , - {33, 14, 0, 0, false} -}; - -SceneDescription IHNM_IntroMovie2Desc = { - 0, 0, 0, 0, 0, 0, 0, 0, - IHNM_IntroMovie2RL, - ARRAYSIZE(IHNM_IntroMovie2RL) -}; - -SceneResourceData IHNM_IntroMovie3RL[] = { - {34, 2, 0, 0, false}, - {35, 14, 0, 0, false} -}; - -SceneDescription IHNM_IntroMovie3Desc = { - 0, 0, 0, 0, 0, 0, 0, 0, - IHNM_IntroMovie3RL, - ARRAYSIZE(IHNM_IntroMovie3RL) -}; - -SceneResourceData IHNM_IntroMovie4RL[] = { - {1227, 2, 0, 0, false}, - {1226, 14, 0, 0, false} -}; - -SceneDescription IHNM_IntroMovie4Desc = { - 0, 0, 0, 0, 0, 0, 0, 0, - IHNM_IntroMovie4RL, - ARRAYSIZE(IHNM_IntroMovie4RL) -}; - -LoadSceneParams IHNM_IntroList[] = { - {0, kLoadByDescription, &IHNM_IntroMovie1Desc, Scene::SC_IHNMIntroMovieProc1, false, kTransitionNoFade, 0, NO_CHAPTER_CHANGE}, - {0, kLoadByDescription, &IHNM_IntroMovie2Desc, Scene::SC_IHNMIntroMovieProc2, false, kTransitionNoFade, 0, NO_CHAPTER_CHANGE}, - {0, kLoadByDescription, &IHNM_IntroMovie3Desc, Scene::SC_IHNMIntroMovieProc3, false, kTransitionNoFade, 0, NO_CHAPTER_CHANGE}, -}; - -int Scene::IHNMStartProc() { - size_t n_introscenes; - size_t i; - - LoadSceneParams firstScene; - - // The original used the "play video" mechanism for the first part of - // the intro. We just use that panel mode. - - _vm->_interface->setMode(kPanelVideo); - - n_introscenes = ARRAYSIZE(IHNM_IntroList); - - for (i = 0; i < n_introscenes; i++) { - _vm->_scene->queueScene(&IHNM_IntroList[i]); - } - - firstScene.loadFlag = kLoadBySceneNumber; - firstScene.sceneDescriptor = -1; - firstScene.sceneDescription = NULL; - firstScene.sceneSkipTarget = true; - firstScene.sceneProc = NULL; - firstScene.transitionType = kTransitionFade; - firstScene.actorsEntrance = 0; - firstScene.chapter = -1; - - _vm->_scene->queueScene(&firstScene); - - return SUCCESS; -} - -int Scene::SC_IHNMIntroMovieProc1(int param, void *refCon) { - return ((Scene *)refCon)->IHNMIntroMovieProc1(param); -} - -int Scene::IHNMIntroMovieProc1(int param) { - Event event; - Event *q_event; - - switch (param) { - case SCENE_BEGIN: - // Background for intro scene is the first frame of the - // intro animation; display it and set the palette - event.type = kEvTOneshot; - event.code = kBgEvent; - event.op = kEventDisplay; - event.param = kEvPSetPalette; - event.time = 0; - - q_event = _vm->_events->queue(&event); - - _vm->_anim->setFrameTime(0, IHNM_INTRO_FRAMETIME); - _vm->_anim->setFlag(0, ANIM_FLAG_ENDSCENE); - - event.type = kEvTOneshot; - event.code = kAnimEvent; - event.op = kEventPlay; - event.param = 0; - event.time = 0; - - q_event = _vm->_events->chain(q_event, &event); - break; - default: - break; - } - - return 0; -} - -int Scene::SC_IHNMIntroMovieProc2(int param, void *refCon) { - return ((Scene *)refCon)->IHNMIntroMovieProc2(param); -} - -int Scene::IHNMIntroMovieProc2(int param) { - Event event; - Event *q_event; - PalEntry *pal; - - static PalEntry current_pal[PAL_ENTRIES]; - - switch (param) { - case SCENE_BEGIN: - // Fade to black out of the intro CyberDreams logo anim - _vm->_gfx->getCurrentPal(current_pal); - - event.type = kEvTContinuous; - event.code = kPalEvent; - event.op = kEventPalToBlack; - event.time = 0; - event.duration = IHNM_PALFADE_TIME; - event.data = current_pal; - - q_event = _vm->_events->queue(&event); - - // Background for intro scene is the first frame of the - // intro animation; display it but don't set palette - event.type = kEvTOneshot; - event.code = kBgEvent; - event.op = kEventDisplay; - event.param = kEvPNoSetPalette; - event.time = 0; - - q_event = _vm->_events->chain(q_event, &event); - - _vm->_anim->setCycles(0, -1); - - // Unlike the original, we keep the logo spinning during the - // palette fades. We don't have to, but I think it looks better - // that way. - - event.type = kEvTOneshot; - event.code = kAnimEvent; - event.op = kEventPlay; - event.param = 0; - event.time = 0; - - q_event = _vm->_events->chain(q_event, &event); - - // Fade in from black to the scene background palette - _vm->_scene->getBGPal(pal); - - event.type = kEvTContinuous; - event.code = kPalEvent; - event.op = kEventBlackToPal; - event.time = 0; - event.duration = IHNM_PALFADE_TIME; - event.data = pal; - - q_event = _vm->_events->chain(q_event, &event); - - // Fade to black after looping animation for a while - event.type = kEvTContinuous; - event.code = kPalEvent; - event.op = kEventPalToBlack; - event.time = IHNM_DGLOGO_TIME; - event.duration = IHNM_PALFADE_TIME; - event.data = pal; - - q_event = _vm->_events->chain(q_event, &event); - - // Queue end of scene - event.type = kEvTOneshot; - event.code = kSceneEvent; - event.op = kEventEnd; - event.time = 0; - - q_event = _vm->_events->chain(q_event, &event); - break; - default: - break; - } - - return 0; -} - -int Scene::SC_IHNMIntroMovieProc3(int param, void *refCon) { - return ((Scene *)refCon)->IHNMIntroMovieProc3(param); -} - -int Scene::IHNMIntroMovieProc3(int param) { - Event event; - Event *q_event; - PalEntry *pal; - static PalEntry current_pal[PAL_ENTRIES]; - - switch (param) { - case SCENE_BEGIN: - // Fade to black out of the intro DG logo anim - _vm->_gfx->getCurrentPal(current_pal); - - event.type = kEvTContinuous; - event.code = kPalEvent; - event.op = kEventPalToBlack; - event.time = 0; - event.duration = IHNM_PALFADE_TIME; - event.data = current_pal; - - q_event = _vm->_events->queue(&event); - - // Music, maestro - - // In the GM file, this music also appears as tracks 7, 13, 19, - // 25 and 31, but only track 1 sounds right with the FM music. - - event.type = kEvTOneshot; - event.code = kMusicEvent; - event.param = 1; - event.param2 = MUSIC_NORMAL; - event.op = kEventPlay; - event.time = 0; - - q_event = _vm->_events->chain(q_event, &event); - - // Background for intro scene is the first frame of the intro - // animation; display it but don't set palette - event.type = kEvTOneshot; - event.code = kBgEvent; - event.op = kEventDisplay; - event.param = kEvPNoSetPalette; - event.time = 0; - - q_event = _vm->_events->chain(q_event, &event); - - // Fade in from black to the scene background palette - _vm->_scene->getBGPal(pal); - - event.type = kEvTContinuous; - event.code = kPalEvent; - event.op = kEventBlackToPal; - event.time = 0; - event.duration = IHNM_PALFADE_TIME; - event.data = pal; - - q_event = _vm->_events->chain(q_event, &event); - - event.type = kEvTOneshot; - event.code = kAnimEvent; - event.op = kEventPlay; - event.param = 0; - event.time = 0; - - q_event = _vm->_events->chain(q_event, &event); - - // Queue end of scene after a while - // TODO: I've increased the delay so the speech won't start - // until the music has ended. Could someone verify if that's - // the correct behaviour? - event.type = kEvTOneshot; - event.code = kSceneEvent; - event.op = kEventEnd; - event.time = _vm->_music->hasAdlib() ? IHNM_TITLE_TIME_FM : IHNM_TITLE_TIME_GM; - - q_event = _vm->_events->chain(q_event, &event); - break; - default: - break; - } - - return 0; -} - -} // End of namespace Saga diff --git a/saga/image.cpp b/saga/image.cpp deleted file mode 100644 index b7ac53f179..0000000000 --- a/saga/image.cpp +++ /dev/null @@ -1,439 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// SAGA Image resource management routines -#include "saga/saga.h" - -#include "saga/stream.h" - -namespace Saga { - -static int granulate(int value, int granularity) { - int remainder; - - if (value == 0) - return 0; - - if (granularity == 0) - return 0; - - remainder = value % granularity; - - if (remainder == 0) { - return value; - } else { - return (granularity - remainder + value); - } -} - -int SagaEngine::decodeBGImage(const byte *image_data, size_t image_size, - byte **output_buf, size_t *output_buf_len, int *w, int *h, bool flip) { - ImageHeader hdr; - int modex_height; - const byte *RLE_data_ptr; - size_t RLE_data_len; - byte *decode_buf; - size_t decode_buf_len; - byte *out_buf; - size_t out_buf_len; - - if (image_size <= SAGA_IMAGE_DATA_OFFSET) { - error("decodeBGImage() Image size is way too small (%d)", image_size); - } - - MemoryReadStreamEndian readS(image_data, image_size, isBigEndian()); - - hdr.width = readS.readUint16(); - hdr.height = readS.readUint16(); - // The next four bytes of the image header aren't used. - readS.readUint16(); - readS.readUint16(); - - RLE_data_ptr = image_data + SAGA_IMAGE_DATA_OFFSET; - RLE_data_len = image_size - SAGA_IMAGE_DATA_OFFSET; - - modex_height = granulate(hdr.height, 4); - - decode_buf_len = hdr.width * modex_height; - decode_buf = (byte *)malloc(decode_buf_len); - - out_buf_len = hdr.width * hdr.height; - out_buf = (byte *)malloc(out_buf_len); - - if (decodeBGImageRLE(RLE_data_ptr, - RLE_data_len, decode_buf, decode_buf_len) != SUCCESS) { - free(decode_buf); - free(out_buf); - return FAILURE; - } - - unbankBGImage(out_buf, decode_buf, hdr.width, hdr.height); - - // For some reason bg images in IHNM are upside down - if (getGameType() == GType_IHNM && !flip) { - flipImage(out_buf, hdr.width, hdr.height); - } - - free(decode_buf); - - *output_buf_len = out_buf_len; - *output_buf = out_buf; - - *w = hdr.width; - *h = hdr.height; - - return SUCCESS; -} - -int SagaEngine::decodeBGImageRLE(const byte *inbuf, size_t inbuf_len, byte *outbuf, size_t outbuf_len) { - const byte *inbuf_ptr; - byte *outbuf_ptr; - uint32 inbuf_remain; - - const byte *inbuf_end; - byte *outbuf_end; - uint32 outbuf_remain; - - byte mark_byte; - int test_byte; - - uint32 runcount; - - byte bitfield; - byte bitfield_byte1; - byte bitfield_byte2; - - byte *backtrack_ptr; - int backtrack_amount; - - uint16 c, b; - - int decode_err = 0; - - inbuf_ptr = inbuf; - inbuf_remain = inbuf_len; - - outbuf_ptr = outbuf; - outbuf_remain = outbuf_len; - - inbuf_end = (inbuf + inbuf_len) - 1; - outbuf_end = (outbuf + outbuf_len) - 1; - - memset(outbuf, 0, outbuf_len); - - while ((inbuf_remain > 1) && (outbuf_remain > 0) && !decode_err) { - - if ((inbuf_ptr > inbuf_end) || (outbuf_ptr > outbuf_end)) { - return FAILURE; - } - - mark_byte = *inbuf_ptr++; - inbuf_remain--; - - test_byte = mark_byte & 0xC0; // Mask all but two high order bits - - switch (test_byte) { - case 0xC0: // 1100 0000 - // Uncompressed run follows: Max runlength 63 - runcount = mark_byte & 0x3f; - if ((inbuf_remain < runcount) || (outbuf_remain < runcount)) { - return FAILURE; - } - - for (c = 0; c < runcount; c++) { - *outbuf_ptr++ = *inbuf_ptr++; - } - - inbuf_remain -= runcount; - outbuf_remain -= runcount; - continue; - break; - case 0x80: // 1000 0000 - // Compressed run follows: Max runlength 63 - runcount = (mark_byte & 0x3f) + 3; - if (!inbuf_remain || (outbuf_remain < runcount)) { - return FAILURE; - } - - for (c = 0; c < runcount; c++) { - *outbuf_ptr++ = *inbuf_ptr; - } - - inbuf_ptr++; - inbuf_remain--; - outbuf_remain -= runcount; - continue; - - break; - - case 0x40: // 0100 0000 - // Repeat decoded sequence from output stream: - // Max runlength 10 - - runcount = ((mark_byte >> 3) & 0x07U) + 3; - backtrack_amount = *inbuf_ptr; - - if (!inbuf_remain || (backtrack_amount > (outbuf_ptr - outbuf)) || (runcount > outbuf_remain)) { - return FAILURE; - } - - inbuf_ptr++; - inbuf_remain--; - - backtrack_ptr = outbuf_ptr - backtrack_amount; - - for (c = 0; c < runcount; c++) { - *outbuf_ptr++ = *backtrack_ptr++; - } - - outbuf_remain -= runcount; - continue; - break; - default: // 0000 0000 - break; - } - - // Mask all but the third and fourth highest order bits - test_byte = mark_byte & 0x30; - - switch (test_byte) { - - case 0x30: // 0011 0000 - // Bitfield compression - runcount = (mark_byte & 0x0F) + 1; - - if ((inbuf_remain < (runcount + 2)) || (outbuf_remain < (runcount * 8))) { - return FAILURE; - } - - bitfield_byte1 = *inbuf_ptr++; - bitfield_byte2 = *inbuf_ptr++; - - for (c = 0; c < runcount; c++) { - bitfield = *inbuf_ptr; - for (b = 0; b < 8; b++) { - if (bitfield & 0x80) { - *outbuf_ptr = bitfield_byte2; - } else { - *outbuf_ptr = bitfield_byte1; - } - bitfield <<= 1; - outbuf_ptr++; - } - inbuf_ptr++; - } - - inbuf_remain -= (runcount + 2); - outbuf_remain -= (runcount * 8); - continue; - break; - case 0x20: // 0010 0000 - // Uncompressed run follows - runcount = ((mark_byte & 0x0F) << 8) + *inbuf_ptr; - if ((inbuf_remain < (runcount + 1)) || (outbuf_remain < runcount)) { - return FAILURE; - } - - inbuf_ptr++; - - for (c = 0; c < runcount; c++) { - *outbuf_ptr++ = *inbuf_ptr++; - } - - inbuf_remain -= (runcount + 1); - outbuf_remain -= runcount; - continue; - - break; - - case 0x10: // 0001 0000 - // Repeat decoded sequence from output stream - backtrack_amount = ((mark_byte & 0x0F) << 8) + *inbuf_ptr; - if (inbuf_remain < 2) { - return FAILURE; - } - - inbuf_ptr++; - runcount = *inbuf_ptr++; - - if ((backtrack_amount > (outbuf_ptr - outbuf)) || (outbuf_remain < runcount)) { - return FAILURE; - } - - backtrack_ptr = outbuf_ptr - backtrack_amount; - - for (c = 0; c < runcount; c++) { - *outbuf_ptr++ = *backtrack_ptr++; - } - - inbuf_remain -= 2; - outbuf_remain -= runcount; - continue; - break; - default: - return FAILURE; - break; - } - } - - return SUCCESS; -} - -int SagaEngine::flipImage(byte *img_buf, int columns, int scanlines) { - int line; - byte *tmp_scan; - - byte *flip_p1; - byte *flip_p2; - - int flipcount = scanlines / 2; - - tmp_scan = (byte *)malloc(columns); - if (tmp_scan == NULL) { - return FAILURE; - } - - flip_p1 = img_buf; - flip_p2 = img_buf + (columns * (scanlines - 1)); - - for (line = 0; line < flipcount; line++) { - memcpy(tmp_scan, flip_p1, columns); - memcpy(flip_p1, flip_p2, columns); - memcpy(flip_p2, tmp_scan, columns); - flip_p1 += columns; - flip_p2 -= columns; - } - - free(tmp_scan); - - return SUCCESS; -} - -int SagaEngine::unbankBGImage(byte *dst_buf, const byte *src_buf, int columns, int scanlines) { - int x, y; - int temp; - int quadruple_rows; - int remain_rows; - int rowjump_src; - int rowjump_dest; - const byte *src_p; - byte *dst_p; - const byte *srcptr1, *srcptr2, *srcptr3, *srcptr4; - byte *dstptr1, *dstptr2, *dstptr3, *dstptr4; - - quadruple_rows = scanlines - (scanlines % 4); - remain_rows = scanlines - quadruple_rows; - - assert(scanlines > 0); - - src_p = src_buf; - dst_p = dst_buf + columns; - - srcptr1 = src_p; - srcptr2 = src_p + 1; - srcptr3 = src_p + 2; - srcptr4 = src_p + 3; - - dstptr1 = dst_buf; - dstptr2 = dst_buf + columns; - dstptr3 = dst_buf + columns * 2; - dstptr4 = dst_buf + columns * 3; - - rowjump_src = columns * 4; - rowjump_dest = columns * 4; - - // Unbank groups of 4 first - for (y = 0; y < quadruple_rows; y += 4) { - for (x = 0; x < columns; x++) { - temp = x * 4; - dstptr1[x] = srcptr1[temp]; - dstptr2[x] = srcptr2[temp]; - dstptr3[x] = srcptr3[temp]; - dstptr4[x] = srcptr4[temp]; - } - - // This is to avoid generating invalid pointers - - // usually innocuous, but undefined - if (y < quadruple_rows - 4) { - dstptr1 += rowjump_dest; - dstptr2 += rowjump_dest; - dstptr3 += rowjump_dest; - dstptr4 += rowjump_dest; - srcptr1 += rowjump_src; - srcptr2 += rowjump_src; - srcptr3 += rowjump_src; - srcptr4 += rowjump_src; - } - } - - // Unbank rows remaining - switch (remain_rows) { - case 1: - dstptr1 += rowjump_dest; - srcptr1 += rowjump_src; - for (x = 0; x < columns; x++) { - temp = x * 4; - dstptr1[x] = srcptr1[temp]; - } - break; - case 2: - dstptr1 += rowjump_dest; - dstptr2 += rowjump_dest; - srcptr1 += rowjump_src; - srcptr2 += rowjump_src; - for (x = 0; x < columns; x++) { - temp = x * 4; - dstptr1[x] = srcptr1[temp]; - dstptr2[x] = srcptr2[temp]; - } - break; - case 3: - dstptr1 += rowjump_dest; - dstptr2 += rowjump_dest; - dstptr3 += rowjump_dest; - srcptr1 += rowjump_src; - srcptr2 += rowjump_src; - srcptr3 += rowjump_src; - for (x = 0; x < columns; x++) { - temp = x * 4; - dstptr1[x] = srcptr1[temp]; - dstptr2[x] = srcptr2[temp]; - dstptr3[x] = srcptr3[temp]; - } - break; - default: - break; - } - return SUCCESS; -} - -const byte *SagaEngine::getImagePal(const byte *image_data, size_t image_size) { - if (image_size <= SAGA_IMAGE_HEADER_LEN) { - return NULL; - } - - return image_data + SAGA_IMAGE_HEADER_LEN; -} - -} // End of namespace Saga diff --git a/saga/input.cpp b/saga/input.cpp deleted file mode 100644 index 0abce03a31..0000000000 --- a/saga/input.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ -#include "saga/saga.h" - -#include "saga/gfx.h" -#include "saga/actor.h" -#include "saga/console.h" -#include "saga/interface.h" -#include "saga/render.h" -#include "saga/scene.h" -#include "saga/script.h" -#include "saga/isomap.h" - -#include "common/system.h" - -namespace Saga { - -int SagaEngine::processInput() { - OSystem::Event event; - -// Point imousePt; - - while (g_system->pollEvent(event)) { - switch (event.type) { - case OSystem::EVENT_KEYDOWN: - if (event.kbd.flags == OSystem::KBD_CTRL) { - if (event.kbd.keycode == 'd') - _console->attach(); - } - if (_interface->_textInput || _interface->_statusTextInput) { - _interface->processAscii(event.kbd.ascii); - return SUCCESS; - } - - switch (event.kbd.keycode) { - case '#': - case '`': - case '~': - _console->attach(); - break; - case 'r': - _interface->draw(); - break; - -#if 0 - case 269: - case 270: - case 273: - case 274: - case 275: - case 276: - if (_vm->_scene->getFlags() & kSceneFlagISO) { - _vm->_isoMap->_viewDiff += (event.kbd.keycode == 270) - (event.kbd.keycode == 269); - _vm->_isoMap->_viewScroll.y += (_vm->_isoMap->_viewDiff * (event.kbd.keycode == 274) - _vm->_isoMap->_viewDiff * (event.kbd.keycode == 273)); - _vm->_isoMap->_viewScroll.x += (_vm->_isoMap->_viewDiff * (event.kbd.keycode == 275) - _vm->_isoMap->_viewDiff * (event.kbd.keycode == 276)); - } - break; -#endif - case 282: // F1 - _render->toggleFlag(RF_SHOW_FPS); - _actor->_handleActionDiv = (_actor->_handleActionDiv == 15) ? 50 : 15; - break; - case 283: // F2 - _render->toggleFlag(RF_PALETTE_TEST); - break; - case 284: // F3 - _render->toggleFlag(RF_TEXT_TEST); - break; - case 285: // F4 - _render->toggleFlag(RF_OBJECTMAP_TEST); - break; - case 286: // F5 - if (_interface->getSaveReminderState() > 0) - _interface->setMode(kPanelOption); - break; - case 287: // F6 - _render->toggleFlag(RF_ACTOR_PATH_TEST); - break; - case 288: // F7 - //_actor->frameTest(); - break; - case 289: // F8 - break; - case 290: // F9 - _interface->keyBoss(); - break; - - // Actual game keys - case 32: // space - _actor->abortSpeech(); - break; - case 19: // pause - case 'z': - _render->toggleFlag(RF_RENDERPAUSE); - break; - default: - _interface->processAscii(event.kbd.ascii); - break; - } - break; - case OSystem::EVENT_KEYUP: - _interface->processKeyUp(event.kbd.ascii); - break; - case OSystem::EVENT_LBUTTONUP: - _leftMouseButtonPressed = false; - break; - case OSystem::EVENT_RBUTTONUP: - _rightMouseButtonPressed = false; - break; - case OSystem::EVENT_LBUTTONDOWN: - _leftMouseButtonPressed = true; - _mousePos = event.mouse; - _interface->update(_mousePos, UPDATE_LEFTBUTTONCLICK); - break; - case OSystem::EVENT_RBUTTONDOWN: - _rightMouseButtonPressed = true; - _mousePos = event.mouse; - _interface->update(_mousePos, UPDATE_RIGHTBUTTONCLICK); - break; - case OSystem::EVENT_WHEELUP: - _interface->update(_mousePos, UPDATE_WHEELUP); - break; - case OSystem::EVENT_WHEELDOWN: - _interface->update(_mousePos, UPDATE_WHEELDOWN); - break; - case OSystem::EVENT_MOUSEMOVE: - _mousePos = event.mouse; - break; - case OSystem::EVENT_QUIT: - shutDown(); - break; - default: - break; - } - } - - return SUCCESS; -} - - -} // End of namespace Saga - diff --git a/saga/interface.cpp b/saga/interface.cpp deleted file mode 100644 index 1d3b110068..0000000000 --- a/saga/interface.cpp +++ /dev/null @@ -1,2453 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Game interface module -#include "saga/saga.h" - -#include "saga/gfx.h" -#include "saga/actor.h" -#include "saga/console.h" -#include "saga/events.h" -#include "saga/font.h" -#include "saga/objectmap.h" -#include "saga/isomap.h" -#include "saga/itedata.h" -#include "saga/music.h" -#include "saga/puzzle.h" -#include "saga/render.h" -#include "saga/scene.h" -#include "saga/script.h" -#include "saga/sound.h" -#include "saga/sprite.h" -#include "saga/rscfile.h" -#include "saga/resnames.h" - -#include "saga/interface.h" - -#include "common/config-manager.h" -#include "common/system.h" -#include "common/timer.h" - -namespace Saga { - -static int verbTypeToTextStringsIdLUT[2][kVerbTypeIdsMax] = { - {-1, - kTextPickUp, - kTextLookAt, - kTextWalkTo, - kTextTalkTo, - kTextOpen, - kTextClose, - kTextGive, - kTextUse, - -1, - -1, - -1, - -1, - -1, - -1}, - {-1, - 3, //TODO:check - 2, - 1, - 5, - 6, //TODO:check - 8, //TODO:check - 7, - 4} -}; - -Interface::Interface(SagaEngine *vm) : _vm(vm) { - byte *resource; - size_t resourceLength; - int i; - - // Load interface module resource file context - _interfaceContext = _vm->_resource->getContext(GAME_RESOURCEFILE); - if (_interfaceContext == NULL) { - error("Interface::Interface() resource context not found"); - } - - _mainPanel.buttons = _vm->getDisplayInfo().mainPanelButtons; - _mainPanel.buttonsCount = _vm->getDisplayInfo().mainPanelButtonsCount; - - for (i = 0; i < kVerbTypeIdsMax; i++) { - _verbTypeToPanelButton[i] = NULL; - } - - for (i = 0; i < _mainPanel.buttonsCount; i++) { - if (_mainPanel.buttons[i].type == kPanelButtonVerb) { - _verbTypeToPanelButton[_mainPanel.buttons[i].id] = &_mainPanel.buttons[i]; - } - } - - _vm->_resource->loadResource(_interfaceContext, _vm->getResourceDescription()->mainPanelResourceId, resource, resourceLength); - _vm->decodeBGImage(resource, resourceLength, &_mainPanel.image, - &_mainPanel.imageLength, &_mainPanel.imageWidth, &_mainPanel.imageHeight); - - free(resource); - - _conversePanel.buttons = _vm->getDisplayInfo().conversePanelButtons; - _conversePanel.buttonsCount = _vm->getDisplayInfo().conversePanelButtonsCount; - - _vm->_resource->loadResource(_interfaceContext, _vm->getResourceDescription()->conversePanelResourceId, resource, resourceLength); - _vm->decodeBGImage(resource, resourceLength, &_conversePanel.image, - &_conversePanel.imageLength, &_conversePanel.imageWidth, &_conversePanel.imageHeight); - free(resource); - - _optionPanel.buttons = _vm->getDisplayInfo().optionPanelButtons; - _optionPanel.buttonsCount = _vm->getDisplayInfo().optionPanelButtonsCount; - - _vm->_resource->loadResource(_interfaceContext, _vm->getResourceDescription()->optionPanelResourceId, resource, resourceLength); - _vm->decodeBGImage(resource, resourceLength, &_optionPanel.image, - &_optionPanel.imageLength, &_optionPanel.imageWidth, &_optionPanel.imageHeight); - free(resource); - - _vm->_sprite->loadList(_vm->getResourceDescription()->mainPanelSpritesResourceId, _mainPanel.sprites); - - if (_vm->getGameType() == GType_ITE) { - _vm->_sprite->loadList(_vm->getResourceDescription()->defaultPortraitsResourceId, _defPortraits); - } - - setPortraitBgColor(0, 0, 0); - - _mainPanel.x = _vm->getDisplayInfo().mainPanelXOffset; - _mainPanel.y = _vm->getDisplayInfo().mainPanelYOffset; - _mainPanel.currentButton = NULL; - _inventoryUpButton = _mainPanel.getButton(_vm->getDisplayInfo().inventoryUpButtonIndex); - _inventoryDownButton = _mainPanel.getButton(_vm->getDisplayInfo().inventoryDownButtonIndex); - - _conversePanel.x = _vm->getDisplayInfo().conversePanelXOffset; - _conversePanel.y = _vm->getDisplayInfo().conversePanelYOffset; - _conversePanel.currentButton = NULL; - _converseUpButton = _conversePanel.getButton(_vm->getDisplayInfo().converseUpButtonIndex); - _converseDownButton = _conversePanel.getButton(_vm->getDisplayInfo().converseDownButtonIndex); - - _leftPortrait = 0; - _rightPortrait = 0; - - _optionPanel.x = _vm->getDisplayInfo().optionPanelXOffset; - _optionPanel.y = _vm->getDisplayInfo().optionPanelYOffset; - _optionPanel.currentButton = NULL; - _optionSaveFileSlider = _optionPanel.getButton(_vm->getDisplayInfo().optionSaveFileSliderIndex); - _optionSaveFilePanel = _optionPanel.getButton(_vm->getDisplayInfo().optionSaveFilePanelIndex); - - _quitPanel.x = _vm->getDisplayInfo().quitPanelXOffset; - _quitPanel.y = _vm->getDisplayInfo().quitPanelYOffset; - _quitPanel.imageWidth = _vm->getDisplayInfo().quitPanelWidth; - _quitPanel.imageHeight = _vm->getDisplayInfo().quitPanelHeight; - _quitPanel.buttons = _vm->getDisplayInfo().quitPanelButtons; - _quitPanel.buttonsCount = _vm->getDisplayInfo().quitPanelButtonsCount; - _quitPanel.currentButton = NULL; - - _loadPanel.x = _vm->getDisplayInfo().loadPanelXOffset; - _loadPanel.y = _vm->getDisplayInfo().loadPanelYOffset; - _loadPanel.imageWidth = _vm->getDisplayInfo().loadPanelWidth; - _loadPanel.imageHeight = _vm->getDisplayInfo().loadPanelHeight; - _loadPanel.buttons = _vm->getDisplayInfo().loadPanelButtons; - _loadPanel.buttonsCount = _vm->getDisplayInfo().loadPanelButtonsCount; - _loadPanel.currentButton = NULL; - - _savePanel.x = _vm->getDisplayInfo().savePanelXOffset; - _savePanel.y = _vm->getDisplayInfo().savePanelYOffset; - _savePanel.imageWidth = _vm->getDisplayInfo().savePanelWidth; - _savePanel.imageHeight = _vm->getDisplayInfo().savePanelHeight; - _savePanel.buttons = _vm->getDisplayInfo().savePanelButtons; - _savePanel.buttonsCount = _vm->getDisplayInfo().savePanelButtonsCount; - _saveEdit = _savePanel.getButton(_vm->getDisplayInfo().saveEditIndex); - _savePanel.currentButton = NULL; - - _protectPanel.x = _vm->getDisplayInfo().protectPanelXOffset; - _protectPanel.y = _vm->getDisplayInfo().protectPanelYOffset; - _protectPanel.imageWidth = _vm->getDisplayInfo().protectPanelWidth; - _protectPanel.imageHeight = _vm->getDisplayInfo().protectPanelHeight; - _protectPanel.buttons = _vm->getDisplayInfo().protectPanelButtons; - _protectPanel.buttonsCount = _vm->getDisplayInfo().protectPanelButtonsCount; - _protectEdit = _protectPanel.getButton(_vm->getDisplayInfo().protectEditIndex); - _protectPanel.currentButton = NULL; - - _active = true; - _panelMode = _lockedMode = kPanelNull; - _savedMode = -1; - _bossMode = -1; - _fadeMode = kNoFade; - _inMainMode = false; - *_statusText = 0; - _statusOnceColor = -1; - - _inventoryCount = 0; - _inventoryPos = 0; - _inventoryStart = 0; - _inventoryEnd = 0; - _inventoryBox = 0; - _inventorySize = ITE_INVENTORY_SIZE; - _saveReminderState = 0; - - _optionSaveFileTop = 0; - _optionSaveFileTitleNumber = 0; - - _inventory = (uint16 *)calloc(_inventorySize, sizeof(uint16)); - if (_inventory == NULL) { - error("Interface::Interface(): not enough memory"); - } - - _textInputRepeatPhase = 0; - _textInput = false; - _statusTextInput = false; - _statusTextInputState = kStatusTextInputFirstRun; - - _disableAbortSpeeches = false; -} - -Interface::~Interface(void) { - free(_inventory); - - _mainPanel.sprites.freeMem(); - _defPortraits.freeMem(); - _scenePortraits.freeMem(); -} - -int Interface::activate() { - if (!_active) { - _active = true; - _vm->_script->_skipSpeeches = false; - _vm->_actor->_protagonist->_targetObject = ID_NOTHING; - unlockMode(); - if (_panelMode == kPanelMain){ - _saveReminderState = 1; - } - draw(); - } - _vm->_gfx->showCursor(true); - - return SUCCESS; -} - -int Interface::deactivate() { - if (_active) { - _active = false; - lockMode(); - setMode(kPanelNull); - } - _vm->_gfx->showCursor(false); - - return SUCCESS; -} - -void Interface::rememberMode() { - assert (_savedMode == -1); - - _savedMode = _panelMode; -} - -void Interface::restoreMode() { - assert (_savedMode != -1); - - _panelMode = _savedMode; - _savedMode = -1; - - draw(); -} - -void Interface::setMode(int mode) { - debug(1, "Interface::setMode %i", mode); - - if (mode == kPanelMain) { - _inMainMode = true; - _saveReminderState = 1; //TODO: blinking timeout - } else { - if (mode == kPanelConverse) { - _inMainMode = false; - } - _saveReminderState = 0; - } - - _panelMode = mode; - - switch (_panelMode) { - case kPanelMain: - if (_vm->getGameType() == GType_IHNM) - warning("FIXME: Implement IHNM differences from ExecuteInventoryPanel"); - - _mainPanel.currentButton = NULL; - break; - case kPanelConverse: - _conversePanel.currentButton = NULL; - converseDisplayText(); - break; - case kPanelOption: - _optionPanel.currentButton = NULL; - _vm->fillSaveList(); - calcOptionSaveSlider(); - if (_optionSaveFileTitleNumber >= _vm->getDisplayInfo().optionSaveFileVisible) { - _optionSaveFileTitleNumber = _vm->getDisplayInfo().optionSaveFileVisible - 1; - } - break; - case kPanelLoad: - _loadPanel.currentButton = NULL; - break; - case kPanelQuit: - _quitPanel.currentButton = NULL; - break; - case kPanelSave: - _savePanel.currentButton = NULL; - _textInputMaxWidth = _saveEdit->width - 10; - _textInput = true; - _textInputStringLength = strlen(_textInputString); - _textInputPos = _textInputStringLength + 1; - _textInputRepeatPhase = 0; - break; - case kPanelMap: - mapPanelShow(); - break; - case kPanelSceneSubstitute: - _vm->_render->setFlag(RF_DEMO_SUBST); - _vm->_gfx->getCurrentPal(_mapSavedPal); - break; - case kPanelChapterSelection: - break; - case kPanelBoss: - _vm->_render->setFlag(RF_DEMO_SUBST); - break; - case kPanelProtect: - _protectPanel.currentButton = NULL; - _textInputMaxWidth = _protectEdit->width - 10; - _textInput = true; - _textInputString[0] = 0; - _textInputStringLength = 0; - _textInputPos = _textInputStringLength + 1; - _textInputRepeatPhase = 0; - break; - } - - draw(); -} - -bool Interface::processAscii(uint16 ascii, bool synthetic) { - // TODO: Checking for Esc and Enter below is a bit hackish, and - // and probably only works with the English version. Maybe we should - // add a flag to the button so it can indicate if it's the default or - // cancel button? - - int i; - PanelButton *panelButton; - if (!synthetic) - _textInputRepeatPhase = 0; - if (_statusTextInput) { - processStatusTextInput(ascii); - return true; - } - - switch (_panelMode) { - case kPanelNull: - if (ascii == 27) { // Esc - if (_vm->_scene->isInIntro()) { - _vm->_scene->skipScene(); - } else { - if (!_disableAbortSpeeches) - _vm->_actor->abortAllSpeeches(); - } - return true; - } - break; - case kPanelCutaway: - if (ascii == 27) { // Esc - if (!_disableAbortSpeeches) - _vm->_actor->abortAllSpeeches(); - _vm->_scene->cutawaySkip(); - return true; - } - break; - case kPanelVideo: - if (ascii == 27) { // Esc - if (_vm->_scene->isInIntro()) { - _vm->_scene->skipScene(); - } else { - if (!_disableAbortSpeeches) - _vm->_actor->abortAllSpeeches(); - } - _vm->_scene->cutawaySkip(); - } - break; - case kPanelOption: - // TODO: check input dialog keys - if (ascii == 27 || ascii == 13) { // Esc or Enter - ascii = 'c'; //continue - } - - for (i = 0; i < _optionPanel.buttonsCount; i++) { - panelButton = &_optionPanel.buttons[i]; - if (panelButton->type == kPanelButtonOption) { - if (panelButton->ascii == ascii) { - setOption(panelButton); - return true; - } - } - } - break; - case kPanelSave: - if (_textInput && processTextInput(ascii)) { - return true; - } - - if (ascii == 27) { // Esc - ascii = 'c'; // cancel - } else if (ascii == 13) { // Enter - ascii = 's'; // save - } - - for (i = 0; i < _savePanel.buttonsCount; i++) { - panelButton = &_savePanel.buttons[i]; - if (panelButton->type == kPanelButtonSave) { - if (panelButton->ascii == ascii) { - setSave(panelButton); - return true; - } - } - } - break; - case kPanelQuit: - if (ascii == 27) { // Esc - ascii = 'c'; // cancel - } else if (ascii == 13) { // Enter - ascii = 'q'; // quit - } - - for (i = 0; i < _quitPanel.buttonsCount; i++) { - panelButton = &_quitPanel.buttons[i]; - if (panelButton->type == kPanelButtonQuit) { - if (panelButton->ascii == ascii) { - setQuit(panelButton); - return true; - } - } - } - break; - case kPanelLoad: - for (i = 0; i < _loadPanel.buttonsCount; i++) { - panelButton = &_loadPanel.buttons[i]; - if (panelButton->type == kPanelButtonLoad) { - if (panelButton->ascii == ascii) { - setLoad(panelButton); - return true; - } - } - } - break; - case kPanelMain: - for (i = 0; i < _mainPanel.buttonsCount; i++) { - panelButton = &_mainPanel.buttons[i]; - if (panelButton->ascii == ascii) { - if (panelButton->type == kPanelButtonVerb) { - _vm->_script->setVerb(panelButton->id); - } - if (panelButton->type == kPanelButtonArrow) { - inventoryChangePos(panelButton->id); - } - return true; - } - } - if (ascii == 15) // ctrl-o - { - if (_saveReminderState > 0) { - setMode(kPanelOption); - return true; - } - } - break; - case kPanelConverse: - switch (ascii) { - case 'x': - setMode(kPanelMain); - if (_vm->_puzzle->isActive()) - _vm->_puzzle->exitPuzzle(); - break; - - case 'u': - converseChangePos(-1); - break; - - case 'd': - converseChangePos(1); - break; - - case '1': - case '2': - case '3': - case '4': - converseSetPos(ascii); - break; - } - break; - case kPanelMap: - mapPanelClean(); - break; - case kPanelSceneSubstitute: - if (ascii == 13) { - _vm->_render->clearFlag(RF_DEMO_SUBST); - _vm->_gfx->setPalette(_mapSavedPal); - setMode(kPanelMain); - _vm->_script->setNoPendingVerb(); - } else if (ascii == 'q' || ascii == 'Q') { - _vm->shutDown(); - } - break; - case kPanelBoss: - _vm->_render->clearFlag(RF_DEMO_SUBST); - keyBossExit(); - break; - case kPanelProtect: - if (_textInput && processTextInput(ascii)) { - return true; - } - - if (ascii == 27 || ascii == 13) { // Esc or Enter - _vm->_script->wakeUpThreads(kWaitTypeRequest); - _vm->_interface->setMode(kPanelMain); - - _protectHash = 0; - - for (char *p = _textInputString; *p; p++) - _protectHash = (_protectHash << 1) + toupper(*p); - } - break; - } - return false; -} - -#define KEYBOARD_REPEAT_DELAY1 300000L -#define KEYBOARD_REPEAT_DELAY2 50000L - -void Interface::textInputRepeatCallback(void *refCon) { - ((Interface *)refCon)->textInputRepeat(); -} - -void Interface::textInputStartRepeat(uint16 ascii) { - if (!_textInputRepeatPhase) { - _textInputRepeatPhase = 1; - Common::g_timer->removeTimerProc(&textInputRepeatCallback); - Common::g_timer->installTimerProc(&textInputRepeatCallback, KEYBOARD_REPEAT_DELAY1, this); - } - - _textInputRepeatChar = ascii; -} - -void Interface::textInputRepeat() { - if (_textInputRepeatPhase == 1) { - _textInputRepeatPhase = 2; - Common::g_timer->removeTimerProc(&textInputRepeatCallback); - Common::g_timer->installTimerProc(&textInputRepeatCallback, KEYBOARD_REPEAT_DELAY2, this); - } else if (_textInputRepeatPhase == 2) { - processAscii(_textInputRepeatChar, true); - } -} - -void Interface::processKeyUp(uint16 ascii) { - if (_textInputRepeatPhase) { - Common::g_timer->removeTimerProc(&textInputRepeatCallback); - _textInputRepeatPhase = 0; - } -} - -void Interface::setStatusText(const char *text, int statusColor) { - assert(text != NULL); - assert(strlen(text) < STATUS_TEXT_LEN); - - if (_vm->_render->getFlags() & (RF_PLACARD | RF_MAP)) - return; - - strncpy(_statusText, text, STATUS_TEXT_LEN); - _statusOnceColor = statusColor; - drawStatusBar(); -} - -void Interface::loadScenePortraits(int resourceId) { - _scenePortraits.freeMem(); - - _vm->_sprite->loadList(resourceId, _scenePortraits); -} - -void Interface::drawVerbPanel(Surface *backBuffer, PanelButton* panelButton) { - PanelButton * rightButtonVerbPanelButton; - PanelButton * currentVerbPanelButton; - KnownColor textColor; - int spriteNumber; - Point point; - - rightButtonVerbPanelButton = getPanelButtonByVerbType(_vm->_script->getRightButtonVerb()); - currentVerbPanelButton = getPanelButtonByVerbType(_vm->_script->getCurrentVerb()); - - if (panelButton->state) { - textColor = kKnownColorVerbTextActive; - } else if (panelButton == rightButtonVerbPanelButton) { - textColor = kKnownColorVerbTextActive; - } else { - textColor = kKnownColorVerbText; - } - - if (panelButton == currentVerbPanelButton) { - spriteNumber = panelButton->downSpriteNumber; - } else { - spriteNumber = panelButton->upSpriteNumber; - } - point.x = _mainPanel.x + panelButton->xOffset; - point.y = _mainPanel.y + panelButton->yOffset; - - _vm->_sprite->draw(backBuffer, _vm->getDisplayClip(), _mainPanel.sprites, spriteNumber, point, 256); - - drawVerbPanelText(backBuffer, panelButton, textColor, kKnownColorVerbTextShadow); -} - -void Interface::draw() { - Surface *backBuffer; - int i; - - Point leftPortraitPoint; - Point rightPortraitPoint; - Rect rect; - - backBuffer = _vm->_gfx->getBackBuffer(); - - if (_vm->_scene->isInIntro() || _fadeMode == kFadeOut) - return; - - drawStatusBar(); - - if (_panelMode == kPanelMain || _panelMode == kPanelMap) { - _mainPanel.getRect(rect); - backBuffer->blit(rect, _mainPanel.image); - - for (i = 0; i < kVerbTypeIdsMax; i++) { - if (_verbTypeToPanelButton[i] != NULL) { - drawVerbPanel(backBuffer, _verbTypeToPanelButton[i]); - } - } - } else if (_panelMode == kPanelConverse) { - _conversePanel.getRect(rect); - backBuffer->blit(rect, _conversePanel.image); - converseDisplayTextLines(backBuffer); - } - - if (_vm->getGameType() == GType_IHNM) { - if (_vm->_spiritualBarometer > 255) - _vm->_gfx->setPaletteColor(kIHNMColorPortrait, 0xff, 0xff, 0xff); - else - _vm->_gfx->setPaletteColor(kIHNMColorPortrait, - _vm->_spiritualBarometer * _portraitBgColor.red / 256, - _vm->_spiritualBarometer * _portraitBgColor.green / 256, - _vm->_spiritualBarometer * _portraitBgColor.blue / 256); - } - - if (_panelMode == kPanelMain || _panelMode == kPanelConverse || - _lockedMode == kPanelMain || _lockedMode == kPanelConverse) { - leftPortraitPoint.x = _mainPanel.x + _vm->getDisplayInfo().leftPortraitXOffset; - leftPortraitPoint.y = _mainPanel.y + _vm->getDisplayInfo().leftPortraitYOffset; - _vm->_sprite->draw(backBuffer, _vm->getDisplayClip(), _defPortraits, _leftPortrait, leftPortraitPoint, 256); - } - - if (!_inMainMode && _vm->getDisplayInfo().rightPortraitXOffset >= 0) { //FIXME: should we change !_inMainMode to _panelMode == kPanelConverse ? - rightPortraitPoint.x = _mainPanel.x + _vm->getDisplayInfo().rightPortraitXOffset; - rightPortraitPoint.y = _mainPanel.y + _vm->getDisplayInfo().rightPortraitYOffset; - - // This looks like hack - particularly since it's only done for - // the right-side portrait - and perhaps it is! But as far as I - // can tell this is what the original engine does. And it keeps - // ITE from crashing when entering the Elk King's court. - - if (_rightPortrait >= _scenePortraits.spriteCount) - _rightPortrait = 0; - - _vm->_sprite->draw(backBuffer, _vm->getDisplayClip(), _scenePortraits, _rightPortrait, rightPortraitPoint, 256); - } - - drawInventory(backBuffer); -} - -void Interface::calcOptionSaveSlider() { - int totalFiles = _vm->getSaveFilesCount(); - int visibleFiles = _vm->getDisplayInfo().optionSaveFileVisible; - if (_optionSaveFileSlider == NULL) return; //TODO:REMOVE - int height = _optionSaveFileSlider->height; - int sliderHeight; - int pos; - - if (totalFiles < visibleFiles) { - totalFiles = visibleFiles; - } - - sliderHeight = visibleFiles * height / totalFiles; - if (sliderHeight < 7) { - sliderHeight = 7; - } - - if (totalFiles - visibleFiles <= 0) { - pos = 0; - } else { - pos = _optionSaveFileTop * (height - sliderHeight) / (totalFiles - visibleFiles); - } - _optionPanel.calcPanelButtonRect(_optionSaveFileSlider, _optionSaveRectTop); - _optionSaveRectBottom = _optionSaveRectSlider = _optionSaveRectTop; - - _optionSaveRectTop.bottom = _optionSaveRectTop.top + pos; - _optionSaveRectTop.top++; - _optionSaveRectTop.right--; - - _optionSaveRectSlider.top = _optionSaveRectTop.bottom; - _optionSaveRectSlider.bottom = _optionSaveRectSlider.top + sliderHeight; - - _optionSaveRectBottom.top = _optionSaveRectSlider.bottom; - _optionSaveRectBottom.right--; -} - -void Interface::drawPanelText(Surface *ds, InterfacePanel *panel, PanelButton *panelButton) { - const char *text; - int textWidth; - Rect rect; - Point textPoint; - - // Button differs for CD version - if (panelButton->id == kTextReadingSpeed && _vm->getFeatures() & GF_CD_FX) - return; - if (panelButton->id == kTextShowDialog && !(_vm->getFeatures() & GF_CD_FX)) - return; - - text = _vm->getTextString(panelButton->id); - panel->calcPanelButtonRect(panelButton, rect); - if (panelButton->xOffset < 0) { - textWidth = _vm->_font->getStringWidth(kKnownFontMedium, text, 0, kFontNormal); - rect.left += 2 + (panel->imageWidth - 1 - textWidth) / 2; - } - - textPoint.x = rect.left; - textPoint.y = rect.top + 1; - - _vm->_font->textDraw(kKnownFontMedium, ds, text, textPoint, _vm->KnownColor2ColorId(kKnownColorVerbText), _vm->KnownColor2ColorId(kKnownColorVerbTextShadow), kFontShadow); -} - -void Interface::drawOption() { - const char *text; - Surface *backBuffer; - int i; - int fontHeight; - uint j, idx; - int fgColor; - int bgColor; - Rect rect; - Rect rect2; - PanelButton *panelButton; - Point textPoint; - if (_optionSaveFileSlider == NULL) return;//TODO:REMOVE - - backBuffer = _vm->_gfx->getBackBuffer(); - - _optionPanel.getRect(rect); - backBuffer->blit(rect, _optionPanel.image); - - for (i = 0; i < _optionPanel.buttonsCount; i++) { - panelButton = &_optionPanel.buttons[i]; - if (panelButton->type == kPanelButtonOption) { - drawPanelButtonText(backBuffer, &_optionPanel, panelButton); - } - if (panelButton->type == kPanelButtonOptionText) { - drawPanelText(backBuffer, &_optionPanel, panelButton); - } - } - - if (_optionSaveRectTop.height() > 0) { - backBuffer->drawRect(_optionSaveRectTop, kITEColorDarkGrey); - } - - drawButtonBox(backBuffer, _optionSaveRectSlider, kSlider, _optionSaveFileSlider->state > 0); - - if (_optionSaveRectBottom.height() > 0) { - backBuffer->drawRect(_optionSaveRectBottom, kITEColorDarkGrey); - } - - _optionPanel.calcPanelButtonRect(_optionSaveFilePanel, rect); - rect.top++; - rect2 = rect; - fontHeight = _vm->_font->getHeight(kKnownFontSmall); - for (j = 0; j < _vm->getDisplayInfo().optionSaveFileVisible; j++) { - bgColor = kITEColorDarkGrey0C; - fgColor = kITEColorBrightWhite; - - idx = j + _optionSaveFileTop; - if (idx == _optionSaveFileTitleNumber) { - SWAP(bgColor, fgColor); - } - if (idx < _vm->getSaveFilesCount()) { - rect2.top = rect.top + j * (fontHeight + 1); - rect2.bottom = rect2.top + fontHeight; - backBuffer->fillRect(rect2, bgColor); - text = _vm->getSaveFile(idx)->name; - textPoint.x = rect.left + 1; - textPoint.y = rect2.top; - _vm->_font->textDraw(kKnownFontSmall, backBuffer, text, textPoint, fgColor, 0, kFontNormal); - } - } - -} - -void Interface::drawQuit() { - Surface *backBuffer; - Rect rect; - int i; - PanelButton *panelButton; - - backBuffer = _vm->_gfx->getBackBuffer(); - - _quitPanel.getRect(rect); - drawButtonBox(backBuffer, rect, kButton, false); - for (i = 0; i < _quitPanel.buttonsCount; i++) { - panelButton = &_quitPanel.buttons[i]; - if (panelButton->type == kPanelButtonQuit) { - drawPanelButtonText(backBuffer, &_quitPanel, panelButton); - } - if (panelButton->type == kPanelButtonQuitText) { - drawPanelText(backBuffer, &_quitPanel, panelButton); - } - } -} - -void Interface::handleQuitUpdate(const Point& mousePoint) { - bool releasedButton; - - _quitPanel.currentButton = quitHitTest(mousePoint); - releasedButton = (_quitPanel.currentButton != NULL) && (_quitPanel.currentButton->state > 0) && (!_vm->mouseButtonPressed()); - - if (!_vm->mouseButtonPressed()) { - _quitPanel.zeroAllButtonState(); - } - - if (releasedButton) { - setQuit(_quitPanel.currentButton); - } -} - -void Interface::handleQuitClick(const Point& mousePoint) { - _quitPanel.currentButton = quitHitTest(mousePoint); - - _quitPanel.zeroAllButtonState(); - - if (_quitPanel.currentButton == NULL) { - return; - } - - _quitPanel.currentButton->state = 1; -} - -void Interface::setQuit(PanelButton *panelButton) { - _quitPanel.currentButton = NULL; - switch (panelButton->id) { - case kTextCancel: - setMode(kPanelOption); - break; - case kTextQuit: - _vm->shutDown(); - break; - } -} - -void Interface::drawLoad() { - Surface *backBuffer; - Rect rect; - int i; - PanelButton *panelButton; - - backBuffer = _vm->_gfx->getBackBuffer(); - - _loadPanel.getRect(rect); - drawButtonBox(backBuffer, rect, kButton, false); - for (i = 0; i < _loadPanel.buttonsCount; i++) { - panelButton = &_loadPanel.buttons[i]; - if (panelButton->type == kPanelButtonLoad) { - drawPanelButtonText(backBuffer, &_loadPanel, panelButton); - } - if (panelButton->type == kPanelButtonLoadText) { - drawPanelText(backBuffer, &_loadPanel, panelButton); - } - } -} - -void Interface::handleLoadUpdate(const Point& mousePoint) { - bool releasedButton; - - _loadPanel.currentButton = loadHitTest(mousePoint); - releasedButton = (_loadPanel.currentButton != NULL) && (_loadPanel.currentButton->state > 0) && (!_vm->mouseButtonPressed()); - - if (!_vm->mouseButtonPressed()) { - _loadPanel.zeroAllButtonState(); - } - - if (releasedButton) { - setLoad(_loadPanel.currentButton); - } -} - -void Interface::handleLoadClick(const Point& mousePoint) { - _loadPanel.currentButton = loadHitTest(mousePoint); - - _loadPanel.zeroAllButtonState(); - - if (_loadPanel.currentButton == NULL) { - return; - } - - _loadPanel.currentButton->state = 1; -} - -void Interface::setLoad(PanelButton *panelButton) { - _loadPanel.currentButton = NULL; - switch (panelButton->id) { - case kTextOK: - setMode(kPanelMain); - break; - } -} - -void Interface::processStatusTextInput(uint16 ascii) { - - textInputStartRepeat(ascii); - switch (ascii) { - case 27: // esc - _statusTextInputState = kStatusTextInputAborted; - _statusTextInput = false; - _vm->_script->wakeUpThreads(kWaitTypeStatusTextInput); - break; - case 13: // return - _statusTextInputState = kStatusTextInputEntered; - _statusTextInput = false; - _vm->_script->wakeUpThreads(kWaitTypeStatusTextInput); - break; - case 8: // backspace - if (_statusTextInputPos == 0) { - break; - } - _statusTextInputPos--; - _statusTextInputString[_statusTextInputPos] = 0; - default: - if (_statusTextInputPos >= STATUS_TEXT_INPUT_MAX) { - break; - } - if (((ascii >= 'a') && (ascii <='z')) || - ((ascii >= '0') && (ascii <='9')) || - ((ascii >= 'A') && (ascii <='Z')) || - (ascii == ' ')) { - _statusTextInputString[_statusTextInputPos++] = ascii; - _statusTextInputString[_statusTextInputPos] = 0; - } - } - setStatusText(_statusTextInputString); -} - -bool Interface::processTextInput(uint16 ascii) { - char ch[2]; - char tempString[SAVE_TITLE_SIZE]; - uint tempWidth; - memset(tempString, 0, SAVE_TITLE_SIZE); - ch[1] = 0; - - textInputStartRepeat(ascii); - - switch (ascii) { - case 13: - return false; - case 27: // esc - _textInput = false; - break; - case 8: // backspace - if (_textInputPos <= 1) { - break; - } - _textInputPos--; - case 127: // del - if (_textInputPos <= _textInputStringLength) { - if (_textInputPos != 1) { - strncpy(tempString, _textInputString, _textInputPos - 1); - } - if (_textInputPos != _textInputStringLength) { - strncat(tempString, &_textInputString[_textInputPos], _textInputStringLength - _textInputPos); - } - strcpy(_textInputString, tempString); - _textInputStringLength = strlen(_textInputString); - } - break; - case 276: // left - if (_textInputPos > 1) { - _textInputPos--; - } - break; - case 275: // right - if (_textInputPos <= _textInputStringLength) { - _textInputPos++; - } - break; - default: - if (((ascii >= 'a') && (ascii <='z')) || - ((ascii >= '0') && (ascii <='9')) || - ((ascii >= 'A') && (ascii <='Z')) || - (ascii == ' ')) { - if (_textInputStringLength < SAVE_TITLE_SIZE - 1) { - ch[0] = ascii; - tempWidth = _vm->_font->getStringWidth(kKnownFontSmall, ch, 0, kFontNormal); - tempWidth += _vm->_font->getStringWidth(kKnownFontSmall, _textInputString, 0, kFontNormal); - if (tempWidth > _textInputMaxWidth) { - break; - } - if (_textInputPos != 1) { - strncpy(tempString, _textInputString, _textInputPos - 1); - strcat(tempString, ch); - } - if ((_textInputStringLength == 0) || (_textInputPos == 1)) { - strcpy(tempString, ch); - } - if ((_textInputStringLength != 0) && (_textInputPos != _textInputStringLength)) { - strncat(tempString, &_textInputString[_textInputPos - 1], _textInputStringLength - _textInputPos + 1); - } - - strcpy(_textInputString, tempString); - _textInputStringLength = strlen(_textInputString); - _textInputPos++; - } - } - break; - } - return true; -} - -void Interface::drawTextInput(Surface *ds, InterfacePanel *panel, PanelButton *panelButton) { - Point textPoint; - Rect rect; - char ch[2]; - int fgColor; - uint i; - - ch[1] = 0; - panel->calcPanelButtonRect(panelButton, rect); - drawButtonBox(ds, rect, kEdit, _textInput); - rect.left += 4; - rect.top += 4; - rect.setHeight(_vm->_font->getHeight(kKnownFontSmall)); - - i = 0; - while ((ch[0] = _textInputString[i++]) != 0) { - rect.setWidth(_vm->_font->getStringWidth(kKnownFontSmall, ch, 0, kFontNormal)); - if ((i == _textInputPos) && _textInput) { - fgColor = kITEColorBlack; - ds->fillRect(rect, kITEColorWhite); - } else { - fgColor = kITEColorWhite; - } - textPoint.x = rect.left; - textPoint.y = rect.top + 1; - - _vm->_font->textDraw(kKnownFontSmall, ds, ch, textPoint, fgColor, 0, kFontNormal); - rect.left += rect.width(); - } - if (_textInput && (_textInputPos >= i)) { - ch[0] = ' '; - rect.setWidth(_vm->_font->getStringWidth(kKnownFontSmall, ch, 0, kFontNormal)); - ds->fillRect(rect, kITEColorWhite); - } -} - -void Interface::drawSave() { - Surface *backBuffer; - Rect rect; - int i; - PanelButton *panelButton; - - backBuffer = _vm->_gfx->getBackBuffer(); - - _savePanel.getRect(rect); - drawButtonBox(backBuffer, rect, kButton, false); - for (i = 0; i < _savePanel.buttonsCount; i++) { - panelButton = &_savePanel.buttons[i]; - if (panelButton->type == kPanelButtonSave) { - drawPanelButtonText(backBuffer, &_savePanel, panelButton); - } - if (panelButton->type == kPanelButtonSaveText) { - drawPanelText(backBuffer, &_savePanel, panelButton); - } - } - - drawTextInput(backBuffer, &_savePanel, _saveEdit); -} - -void Interface::drawProtect() { - Surface *backBuffer; - Rect rect; - int i; - PanelButton *panelButton; - - backBuffer = _vm->_gfx->getBackBuffer(); - - _protectPanel.getRect(rect); - drawButtonBox(backBuffer, rect, kButton, false); - - for (i = 0; i < _protectPanel.buttonsCount; i++) { - panelButton = &_protectPanel.buttons[i]; - if (panelButton->type == kPanelButtonProtectText) { - drawPanelText(backBuffer, &_protectPanel, panelButton); - } - } - drawTextInput(backBuffer, &_protectPanel, _protectEdit); -} - -void Interface::handleSaveUpdate(const Point& mousePoint) { - bool releasedButton; - - _savePanel.currentButton = saveHitTest(mousePoint); - - validateSaveButtons(); - - releasedButton = (_savePanel.currentButton != NULL) && - (_savePanel.currentButton->state > 0) && (!_vm->mouseButtonPressed()); - - if (!_vm->mouseButtonPressed()) { - _savePanel.zeroAllButtonState(); - } - - if (releasedButton) { - setSave(_savePanel.currentButton); - } -} - -void Interface::handleSaveClick(const Point& mousePoint) { - _savePanel.currentButton = saveHitTest(mousePoint); - - validateSaveButtons(); - - _savePanel.zeroAllButtonState(); - - if (_savePanel.currentButton == NULL) { - _textInput = false; - return; - } - - _savePanel.currentButton->state = 1; - if (_savePanel.currentButton == _saveEdit) { - _textInput = true; - } -} - -void Interface::setSave(PanelButton *panelButton) { - _savePanel.currentButton = NULL; - uint titleNumber; - char *fileName; - switch (panelButton->id) { - case kTextSave: - if (_textInputStringLength == 0 ) { - break; - } - if (!_vm->isSaveListFull() && (_optionSaveFileTitleNumber == 0)) { - if (_vm->locateSaveFile(_textInputString, titleNumber)) { - fileName = _vm->calcSaveFileName(_vm->getSaveFile(titleNumber)->slotNumber); - _vm->save(fileName, _textInputString); - _optionSaveFileTitleNumber = titleNumber; - } else { - fileName = _vm->calcSaveFileName(_vm->getNewSaveSlotNumber()); - _vm->save(fileName, _textInputString); - _vm->fillSaveList(); - calcOptionSaveSlider(); - } - } else { - fileName = _vm->calcSaveFileName(_vm->getSaveFile(_optionSaveFileTitleNumber)->slotNumber); - _vm->save(fileName, _textInputString); - } - _textInput = false; - setMode(kPanelOption); - break; - case kTextCancel: - _textInput = false; - setMode(kPanelOption); - break; - } -} - -void Interface::handleOptionUpdate(const Point& mousePoint) { - int16 mouseY; - Rect rect; - int totalFiles = _vm->getSaveFilesCount(); - int visibleFiles = _vm->getDisplayInfo().optionSaveFileVisible; - bool releasedButton; - - if (_vm->mouseButtonPressed()) { - if (_optionSaveFileSlider != NULL) //TODO:REMOVE - if (_optionSaveFileSlider->state > 0) { - _optionPanel.calcPanelButtonRect(_optionSaveFileSlider, rect); - - mouseY = mousePoint.y - rect.top -_optionSaveFileMouseOff; - - if (totalFiles - visibleFiles <= 0) { - _optionSaveFileTop = 0; - } else { - _optionSaveFileTop = mouseY * (totalFiles - visibleFiles) / - (_optionSaveFileSlider->height - _optionSaveRectSlider.height()); - } - - _optionSaveFileTop = clamp(0, _optionSaveFileTop, _vm->getSaveFilesCount() - _vm->getDisplayInfo().optionSaveFileVisible); - calcOptionSaveSlider(); - } - } - - _optionPanel.currentButton = optionHitTest(mousePoint); - - validateOptionButtons(); - - releasedButton = (_optionPanel.currentButton != NULL) && (_optionPanel.currentButton->state > 0) && (!_vm->mouseButtonPressed()); - - if (!_vm->mouseButtonPressed()) { - _optionPanel.zeroAllButtonState(); - } - - if (releasedButton) { - setOption(_optionPanel.currentButton); - } -} - - -void Interface::handleOptionClick(const Point& mousePoint) { - Rect rect; - _optionPanel.currentButton = optionHitTest(mousePoint); - - validateOptionButtons(); - - _optionPanel.zeroAllButtonState(); - - if (_optionPanel.currentButton == NULL) { - return; - } - - if (_optionPanel.currentButton == _optionSaveFileSlider) { - if ((_optionSaveRectTop.height() > 0) && (mousePoint.y < _optionSaveRectTop.bottom)) { - _optionSaveFileTop -= _vm->getDisplayInfo().optionSaveFileVisible; - } else { - if ((_optionSaveRectBottom.height() > 0) && (mousePoint.y >= _optionSaveRectBottom.top)) { - _optionSaveFileTop += _vm->getDisplayInfo().optionSaveFileVisible; - } else { - if (_vm->getDisplayInfo().optionSaveFileVisible < _vm->getSaveFilesCount()) { - _optionSaveFileMouseOff = mousePoint.y - _optionSaveRectSlider.top; - _optionPanel.currentButton->state = 1; - } - } - } - - _optionSaveFileTop = clamp(0, _optionSaveFileTop, _vm->getSaveFilesCount() - _vm->getDisplayInfo().optionSaveFileVisible); - calcOptionSaveSlider(); - } else { - if (_optionPanel.currentButton == _optionSaveFilePanel) { - _optionPanel.calcPanelButtonRect(_optionSaveFilePanel, rect); - _optionSaveFileTitleNumber = (mousePoint.y - rect.top) / (_vm->_font->getHeight(kKnownFontSmall) + 1); - - if (_optionSaveFileTitleNumber >= _vm->getDisplayInfo().optionSaveFileVisible) { - _optionSaveFileTitleNumber = _vm->getDisplayInfo().optionSaveFileVisible - 1; - } - _optionSaveFileTitleNumber += _optionSaveFileTop; - if (_optionSaveFileTitleNumber >= _vm->getSaveFilesCount()) { - _optionSaveFileTitleNumber = _vm->getSaveFilesCount() - 1; - } - } else { - _optionPanel.currentButton->state = 1; - } - } -} - -void Interface::handleChapterSelectionUpdate(const Point& mousePoint) { - uint16 objectId; - - // FIXME: Original handled more object types here. - - objectId = _vm->_actor->hitTest(mousePoint, true); - - if (objectId != _vm->_script->_pointerObject) { - _vm->_script->_pointerObject = objectId; - } -} - -void Interface::handleChapterSelectionClick(const Point& mousePoint) { - int obj = _vm->_script->_pointerObject; - - _vm->_actor->abortSpeech(); - - if (obj) { - int script = 0; - HitZone *hitZone; - ActorData *a; - ObjectData *o; - Event event; - - switch (objectTypeId(obj)) { - case kGameObjectHitZone: - hitZone = _vm->_scene->_actionMap->getHitZone(objectIdToIndex(obj)); - if (hitZone->getFlags() & kHitZoneExit) - script = hitZone->getScriptNumber(); - break; - - case kGameObjectActor: - a = _vm->_actor->getActor(obj); - script = a->_scriptEntrypointNumber; - break; - - case kGameObjectObject: - o = _vm->_actor->getObj(obj); - script = o->_scriptEntrypointNumber; - break; - } - - if (script > 0) { - event.type = kEvTOneshot; - event.code = kScriptEvent; - event.op = kEventExecNonBlocking; - event.time = 0; - event.param = _vm->_scene->getScriptModuleNumber(); - event.param2 = script; - event.param3 = _vm->_script->getVerbType(kVerbUse); // Action - event.param4 = obj; // Object - event.param5 = 0; // With Object - event.param6 = obj; // Actor - - _vm->_events->queue(&event); - } - } -} - -void Interface::setOption(PanelButton *panelButton) { - char * fileName; - _optionPanel.currentButton = NULL; - switch (panelButton->id) { - case kTextContinuePlaying: - ConfMan.flushToDisk(); - setMode(kPanelMain); - break; - case kTextQuitGame: - setMode(kPanelQuit); - break; - case kTextLoad: - if (_vm->getSaveFilesCount() > 0) { - if (_vm->isSaveListFull() || (_optionSaveFileTitleNumber > 0)) { - fileName = _vm->calcSaveFileName(_vm->getSaveFile(_optionSaveFileTitleNumber)->slotNumber); - setMode(kPanelMain); - _vm->load(fileName); - } - } - break; - case kTextSave: - if (!_vm->isSaveListFull() && (_optionSaveFileTitleNumber == 0)) { - _textInputString[0] = 0; - } else { - strcpy(_textInputString, _vm->getSaveFile(_optionSaveFileTitleNumber)->name); - } - setMode(kPanelSave); - break; - case kTextReadingSpeed: - if (_vm->getFeatures() & GF_CD_FX) { - _vm->_subtitlesEnabled = !_vm->_subtitlesEnabled; - ConfMan.set("subtitles", _vm->_subtitlesEnabled); - } else { - _vm->_readingSpeed = (_vm->_readingSpeed + 1) % 4; - ConfMan.set("talkspeed", _vm->_readingSpeed); - } - break; - case kTextMusic: - _vm->_musicVolume = (_vm->_musicVolume + 1) % 11; - _vm->_music->setVolume(_vm->_musicVolume == 10 ? -1 : _vm->_musicVolume * 25, 1); - ConfMan.set("music_volume", _vm->_musicVolume * 25); - break; - case kTextSound: - _vm->_soundVolume = (_vm->_soundVolume + 1) % 11; - _vm->_sound->setVolume(_vm->_soundVolume == 10 ? 255 : _vm->_soundVolume * 25); - ConfMan.set("sfx_volume", _vm->_soundVolume * 25); - break; - } -} - -void Interface::update(const Point& mousePoint, int updateFlag) { - - if (!_active && _panelMode == kPanelNull && (updateFlag & UPDATE_MOUSECLICK)) - _vm->_actor->abortSpeech(); - - if (_vm->_scene->isInIntro() || _fadeMode == kFadeOut || !_active) { - return; - } - - if (_statusTextInput) { - return; - } - - switch (_panelMode) { - case kPanelMain: - if (updateFlag & UPDATE_MOUSEMOVE) { - bool lastWasPlayfield = _lastMousePoint.y < _vm->_scene->getHeight(); - if (mousePoint.y < _vm->_scene->getHeight()) { - if (!lastWasPlayfield) { - handleMainUpdate(mousePoint); - } - _vm->_script->whichObject(mousePoint); - } else { - if (lastWasPlayfield) { - _vm->_script->setNonPlayfieldVerb(); - } - handleMainUpdate(mousePoint); - } - - } else { - - if (updateFlag & UPDATE_MOUSECLICK) { - if (mousePoint.y < _vm->_scene->getHeight()) { - _vm->_script->playfieldClick(mousePoint, (updateFlag & UPDATE_LEFTBUTTONCLICK) != 0); - } else { - handleMainClick(mousePoint); - } - } - } - break; - - case kPanelConverse: - if (updateFlag & UPDATE_MOUSEMOVE) { - handleConverseUpdate(mousePoint); - } else { - if (updateFlag & UPDATE_MOUSECLICK) { - handleConverseClick(mousePoint); - } - if (updateFlag & UPDATE_WHEELUP) { - converseChangePos(-1); - } - if (updateFlag & UPDATE_WHEELDOWN) { - converseChangePos(1); - } - - if (_vm->_puzzle->isActive()) { - _vm->_puzzle->handleClick(mousePoint); - } - } - break; - - case kPanelOption: - if (updateFlag & UPDATE_MOUSEMOVE) { - handleOptionUpdate(mousePoint); - } else { - if (updateFlag & UPDATE_MOUSECLICK) { - handleOptionClick(mousePoint); - } - if (updateFlag & UPDATE_WHEELUP) { - if (_optionSaveFileTop) - _optionSaveFileTop--; - calcOptionSaveSlider(); - } - if (updateFlag & UPDATE_WHEELDOWN) { - if (_optionSaveFileTop < _vm->getSaveFilesCount() - _vm->getDisplayInfo().optionSaveFileVisible) - _optionSaveFileTop++; - calcOptionSaveSlider(); - } - } - break; - - case kPanelQuit: - if (updateFlag & UPDATE_MOUSEMOVE) { - handleQuitUpdate(mousePoint); - } else { - if (updateFlag & UPDATE_MOUSECLICK) { - handleQuitClick(mousePoint); - } - } - break; - - case kPanelLoad: - if (updateFlag & UPDATE_MOUSEMOVE) { - - handleLoadUpdate(mousePoint); - - } else { - if (updateFlag & UPDATE_MOUSECLICK) { - handleLoadClick(mousePoint); - } - } - break; - - case kPanelSave: - if (updateFlag & UPDATE_MOUSEMOVE) { - - handleSaveUpdate(mousePoint); - - } else { - if (updateFlag & UPDATE_MOUSECLICK) { - handleSaveClick(mousePoint); - } - } - break; - - case kPanelMap: - if (updateFlag & UPDATE_MOUSECLICK) - mapPanelClean(); - break; - - case kPanelSceneSubstitute: - if (updateFlag & UPDATE_MOUSECLICK) { - _vm->_render->clearFlag(RF_DEMO_SUBST); - _vm->_gfx->setPalette(_mapSavedPal); - setMode(kPanelMain); - _vm->_script->setNoPendingVerb(); - } - break; - - case kPanelChapterSelection: - // TODO: panel has silent button - if (updateFlag & UPDATE_MOUSEMOVE) { - handleChapterSelectionUpdate(mousePoint); - } else { - if (updateFlag & UPDATE_MOUSECLICK) - handleChapterSelectionClick(mousePoint); - } - break; - - case kPanelProtect: - // No mouse interaction - break; - - } - - _lastMousePoint = mousePoint; -} - -void Interface::drawStatusBar() { - Surface *backBuffer; - Rect rect; - Point textPoint; - int stringWidth; - int color; - - if (_panelMode == kPanelChapterSelection) - return; - - backBuffer = _vm->_gfx->getBackBuffer(); - - // Disable this for IHNM for now, since that game uses the full screen - // in some cases. - - // Erase background of status bar - rect.left = _vm->getDisplayInfo().statusXOffset; - rect.top = _vm->getDisplayInfo().statusYOffset; - rect.right = rect.left + _vm->getDisplayWidth(); - rect.bottom = rect.top + _vm->getDisplayInfo().statusHeight; - - backBuffer->drawRect(rect, _vm->getDisplayInfo().statusBGColor); - - stringWidth = _vm->_font->getStringWidth(kKnownFontSmall, _statusText, 0, kFontNormal); - - if (_statusOnceColor == -1) - color = _vm->getDisplayInfo().statusTextColor; - else - color = _statusOnceColor; - - textPoint.x = _vm->getDisplayInfo().statusXOffset + (_vm->getDisplayInfo().statusWidth - stringWidth) / 2; - textPoint.y = _vm->getDisplayInfo().statusYOffset + _vm->getDisplayInfo().statusTextY; - _vm->_font->textDraw(kKnownFontSmall, backBuffer, _statusText, textPoint, color, 0, kFontNormal); - - if (_saveReminderState > 0) { - rect.left = _vm->getDisplayInfo().saveReminderXOffset; - rect.top = _vm->getDisplayInfo().saveReminderYOffset; - - rect.right = rect.left + _vm->getDisplayInfo().saveReminderWidth; - rect.bottom = rect.top + _vm->getDisplayInfo().saveReminderHeight; - _vm->_sprite->draw(backBuffer, _vm->getDisplayClip(), _vm->_sprite->_saveReminderSprites, - _saveReminderState == 1 ? _vm->getDisplayInfo().saveReminderFirstSpriteNumber : _vm->getDisplayInfo().saveReminderSecondSpriteNumber, - rect, 256); - - } -} - -void Interface::handleMainClick(const Point& mousePoint) { - - PanelButton *panelButton; - - panelButton = verbHitTest(mousePoint); - if (panelButton) { - _vm->_script->setVerb(panelButton->id); - return; - } - - panelButton = _mainPanel.hitTest(mousePoint, kPanelAllButtons); - - if (panelButton != NULL) { - if (panelButton->type == kPanelButtonArrow) { - panelButton->state = 1; - converseChangePos(panelButton->id); - } - - if (panelButton->type == kPanelButtonInventory) { - if (_vm->_script->_pointerObject != ID_NOTHING) { - _vm->_script->hitObject(_vm->leftMouseButtonPressed()); - } - if (_vm->_script->_pendingVerb) { - _vm->_actor->_protagonist->_currentAction = kActionWait; - _vm->_script->doVerb(); - } - } - } else { - if (_saveReminderState > 0) { - Rect rect; - rect.left = _vm->getDisplayInfo().saveReminderXOffset; - rect.top = _vm->getDisplayInfo().saveReminderYOffset; - - rect.right = rect.left + _vm->getDisplayInfo().saveReminderWidth; - rect.bottom = rect.top + _vm->getDisplayInfo().saveReminderHeight; - if (rect.contains(mousePoint)) { - setMode(kPanelOption); - } - } - } -} - -void Interface::handleMainUpdate(const Point& mousePoint) { - PanelButton *panelButton; - - panelButton = verbHitTest(mousePoint); - if (_mainPanel.currentButton != panelButton) { - if (_mainPanel.currentButton) { - if (_mainPanel.currentButton->type == kPanelButtonVerb) { - setVerbState(_mainPanel.currentButton->id, 0); - } - } - if (panelButton) { - setVerbState(panelButton->id, 1); - } - } - - if (panelButton) { - _mainPanel.currentButton = panelButton; - return; - } - - - if (!_vm->mouseButtonPressed()) { // remove pressed flag - if (_inventoryUpButton) { - _inventoryUpButton->state = 0; - _inventoryDownButton->state = 0; - } - } - - panelButton = _mainPanel.hitTest(mousePoint, kPanelAllButtons); - - bool changed = false; - - if ((panelButton != NULL) && (panelButton->type == kPanelButtonArrow)) { - if (panelButton->state == 1) { - //TODO: insert timeout catchup - inventoryChangePos(panelButton->id); - } - changed = true; - } else { - _vm->_script->whichObject(mousePoint); - } - - changed = changed || (panelButton != _mainPanel.currentButton); - _mainPanel.currentButton = panelButton; - if (changed) { - draw(); - } -} - -//inventory stuff -void Interface::inventoryChangePos(int chg) { - if ((chg < 0 && _inventoryStart + chg >= 0) || - (chg > 0 && _inventoryStart < _inventoryEnd)) { - _inventoryStart += chg; - draw(); - } -} - -void Interface::inventorySetPos(int key) { - _inventoryBox = key - '1'; - _inventoryPos = _inventoryStart + _inventoryBox; - if (_inventoryPos >= _inventoryCount) - _inventoryPos = -1; -} - -void Interface::updateInventory(int pos) { - int cols = _vm->getDisplayInfo().inventoryColumns; - if (pos >= _inventoryCount) { - pos = _inventoryCount - 1; - } - if (pos < 0) { - pos = 0; - } - _inventoryStart = (pos - cols) / cols * cols; - if (_inventoryStart < 0) { - _inventoryStart = 0; - } - - _inventoryEnd = (_inventoryCount - 1 - cols) / cols * cols; - if (_inventoryEnd < 0) { - _inventoryEnd = 0; - } -} - -void Interface::addToInventory(int objectId) { - if (_inventoryCount >= _inventorySize) { - return; - } - - for (int i = _inventoryCount; i > 0; i--) { - _inventory[i] = _inventory[i - 1]; - } - - _inventory[0] = objectId; - _inventoryCount++; - - _inventoryPos = 0; - updateInventory(0); - draw(); -} - -void Interface::removeFromInventory(int objectId) { - int j = inventoryItemPosition(objectId); - if (j == -1) { - return; - } - - int i; - - for (i = j; i < _inventoryCount - 1; i++) { - _inventory[i] = _inventory[i + 1]; - } - - --_inventoryCount; - _inventory[_inventoryCount] = 0; - updateInventory(j); - draw(); -} - -void Interface::clearInventory() { - for (int i = 0; i < _inventoryCount; i++) - _inventory[i] = 0; - - _inventoryCount = 0; - updateInventory(0); -} - -int Interface::inventoryItemPosition(int objectId) { - for (int i = 0; i < _inventoryCount; i++) - if (_inventory[i] == objectId) - return i; - - return -1; -} - -void Interface::drawInventory(Surface *backBuffer) { - if (!isInMainMode()) - return; - - int i; - Rect rect; - int ci; - ObjectData *obj; - ci = _inventoryStart; - if (_inventoryStart != 0) { - drawPanelButtonArrow(backBuffer, &_mainPanel, _inventoryUpButton); - } - if (_inventoryStart != _inventoryEnd) { - drawPanelButtonArrow(backBuffer, &_mainPanel, _inventoryDownButton); - } - - for (i = 0; i < _mainPanel.buttonsCount; i++) { - if (_mainPanel.buttons[i].type != kPanelButtonInventory) { - continue; - } - _mainPanel.calcPanelButtonRect(&_mainPanel.buttons[i], rect); - - // TODO: Different colour for IHNM, probably. - backBuffer->drawRect(rect, kITEColorDarkGrey); - - if (ci < _inventoryCount) { - obj = _vm->_actor->getObj(_inventory[ci]); - _vm->_sprite->draw(backBuffer, _vm->getDisplayClip(), _vm->_sprite->_inventorySprites, obj->_spriteListResourceId, rect, 256); - } - - ci++; - } -} - -void Interface::setVerbState(int verb, int state) { - PanelButton * panelButton = getPanelButtonByVerbType(verb); - if (panelButton == NULL) return; - if (state == 2) { - state = (_mainPanel.currentButton == panelButton) ? 1 : 0; - } - panelButton->state = state; - draw(); -} - -void Interface::drawButtonBox(Surface *ds, const Rect& rect, ButtonKind kind, bool down) { - byte cornerColor; - byte frameColor; - byte fillColor; - byte solidColor; - byte odl, our, idl, iur; - - switch (kind ) { - case kSlider: - cornerColor = 0x8b; - frameColor = kITEColorBlack; - fillColor = kITEColorLightBlue96; - odl = kITEColorDarkBlue8a; - our = kITEColorLightBlue92; - idl = 0x89; - iur = 0x94; - solidColor = down ? kITEColorLightBlue94 : kITEColorLightBlue96; - break; - case kEdit: - cornerColor = kITEColorLightBlue96; - frameColor = kITEColorLightBlue96; - fillColor = kITEColorLightBlue96; - our = kITEColorDarkBlue8a; - odl = kITEColorLightBlue94; - iur = 0x97; - idl = 0x95; - if (down) { - solidColor = kITEColorBlue; - } else { - solidColor = kITEColorDarkGrey0C; - } - break; - default: - cornerColor = 0x8b; - frameColor = kITEColorBlack; - solidColor = fillColor = kITEColorLightBlue96; - odl = kITEColorDarkBlue8a; - our = kITEColorLightBlue94; - idl = 0x97; - iur = 0x95; - if (down) { - SWAP(odl, our); - SWAP(idl, iur); - } - break; - } - - int x = rect.left; - int y = rect.top; - int w = rect.width(); - int h = rect.height(); - int xe = rect.right - 1; - int ye = rect.bottom - 1; - - ((byte *)ds->getBasePtr(x, y))[0] = cornerColor; - ((byte *)ds->getBasePtr(x, ye))[0] = cornerColor; - ((byte *)ds->getBasePtr(xe, y))[0] = cornerColor; - ((byte *)ds->getBasePtr(xe, ye))[0] = cornerColor; - ds->hLine(x + 1, y, x + 1 + w - 2, frameColor); - ds->hLine(x + 1, ye, x + 1 + w - 2, frameColor); - ds->vLine(x, y + 1, y + 1 + h - 2, frameColor); - ds->vLine(xe, y + 1, y + 1 + h - 2, frameColor); - - x++; - y++; - xe--; - ye--; - w -= 2; - h -= 2; - ds->vLine(x, y, y + h - 1, odl); - ds->hLine(x, ye, x + w - 1, odl); - ds->vLine(xe, y, y + h - 1, our); - ds->hLine(x + 1, y, x + 1 + w - 2, our); - - x++; - y++; - xe--; - ye--; - w -= 2; - h -= 2; - ((byte *)ds->getBasePtr(x, y))[0] = fillColor; - ((byte *)ds->getBasePtr(xe, ye))[0] = fillColor; - ds->vLine(x, y + 1, y + 1 + h - 2, idl); - ds->hLine(x + 1, ye, x + 1 + w - 2, idl); - ds->vLine(xe, y, y + h - 1, iur); - ds->hLine(x + 1, y, x + 1 + w - 2, iur); - - x++; y++; - w -= 2; h -= 2; - - Common::Rect fill(x, y, x + w, y + h); - ds->fillRect(fill, solidColor); -} - -static const int readingSpeeds[] = { kTextFast, kTextMid, kTextSlow, kTextClick }; - -void Interface::drawPanelButtonText(Surface *ds, InterfacePanel *panel, PanelButton *panelButton) { - const char *text; - int textId; - int textWidth; - int textHeight; - Point point; - KnownColor textColor; - Rect rect; - - textId = panelButton->id; - switch(panelButton->id) { - case kTextReadingSpeed: - if (_vm->getFeatures() & GF_CD_FX) { - if (_vm->_subtitlesEnabled) - textId = kTextOn; - else - textId = kTextOff; - } else { - textId = readingSpeeds[_vm->_readingSpeed]; - } - break; - case kTextMusic: - if (_vm->_musicVolume) - textId = kText10Percent + _vm->_musicVolume - 1; - else - textId = kTextOff; - break; - case kTextSound: - if (_vm->_soundVolume) - textId = kText10Percent + _vm->_soundVolume - 1; - else - textId = kTextOff; - break; - } - text = _vm->getTextString(textId); - - textWidth = _vm->_font->getStringWidth(kKnownFontMedium, text, 0, kFontNormal); - textHeight = _vm->_font->getHeight(kKnownFontMedium); - - point.x = panel->x + panelButton->xOffset + (panelButton->width / 2) - (textWidth / 2); - point.y = panel->y + panelButton->yOffset + (panelButton->height / 2) - (textHeight / 2); - - if (panelButton == panel->currentButton) { - textColor = kKnownColorVerbTextActive; - } else { - textColor = kKnownColorVerbText; - } - - panel->calcPanelButtonRect(panelButton, rect); - drawButtonBox(ds, rect, kButton, panelButton->state > 0); - - _vm->_font->textDraw(kKnownFontMedium, ds, text, point, - _vm->KnownColor2ColorId(textColor), _vm->KnownColor2ColorId(kKnownColorVerbTextShadow), kFontShadow); -} - -void Interface::drawPanelButtonArrow(Surface *ds, InterfacePanel *panel, PanelButton *panelButton) { - Point point; - int spriteNumber; - - if (panel->currentButton == panelButton) { - if (panelButton->state != 0) { - spriteNumber = panelButton->downSpriteNumber; - } else { - spriteNumber = panelButton->overSpriteNumber; - } - } else { - spriteNumber = panelButton->upSpriteNumber; - } - - point.x = panel->x + panelButton->xOffset; - point.y = panel->y + panelButton->yOffset; - - _vm->_sprite->draw(ds, _vm->getDisplayClip(), _vm->_sprite->_mainSprites, spriteNumber, point, 256); -} - -void Interface::drawVerbPanelText(Surface *ds, PanelButton *panelButton, KnownColor textKnownColor, KnownColor textShadowKnownColor) { - const char *text; - int textWidth; - Point point; - int textId; - - if (_vm->getGameType() == GType_ITE) { - textId = verbTypeToTextStringsIdLUT[0][panelButton->id]; - text = _vm->getTextString(textId); - } else { - textId = verbTypeToTextStringsIdLUT[1][panelButton->id]; - text = _vm->_script->_mainStrings.getString(textId + 1); - textShadowKnownColor = kKnownColorTransparent; - } - - textWidth = _vm->_font->getStringWidth(kKnownFontVerb, text, 0, kFontNormal); - - if (_vm->getGameType() == GType_ITE) { - point.x = _mainPanel.x + panelButton->xOffset + 1 + (panelButton->width - 1 - textWidth) / 2; - point.y = _mainPanel.y + panelButton->yOffset + 1; - } else { - point.x = _mainPanel.x + panelButton->xOffset + 1 + (panelButton->width - textWidth) / 2; - point.y = _mainPanel.y + panelButton->yOffset + 12; - } - - _vm->_font->textDraw(kKnownFontVerb, ds, text, point, _vm->KnownColor2ColorId(textKnownColor),_vm->KnownColor2ColorId(textShadowKnownColor), (textShadowKnownColor != kKnownColorTransparent) ? kFontShadow : kFontNormal); -} - - -// Converse stuff -void Interface::converseInit(void) { - for (int i = 0; i < CONVERSE_MAX_TEXTS; i++) - _converseText[i].text = NULL; - converseClear(); -} - -void Interface::converseClear(void) { - for (int i = 0; i < CONVERSE_MAX_TEXTS; i++) { - if (_converseText[i].text != NULL) { - free(_converseText[i].text); - _converseText[i].text = NULL; - } - _converseText[i].stringNum = -1; - _converseText[i].replyId = 0; - _converseText[i].replyFlags = 0; - _converseText[i].replyBit = 0; - } - - _converseTextCount = 0; - _converseStrCount = 0; - _converseStartPos = 0; - _converseEndPos = 0; - _conversePos = -1; -} - -bool Interface::converseAddText(const char *text, int replyId, byte replyFlags, int replyBit) { - int count = 0; // count how many pieces of text per string - int i; - int len; - byte c; - - assert(strlen(text) < CONVERSE_MAX_WORK_STRING); - - strncpy(_converseWorkString, text, CONVERSE_MAX_WORK_STRING); - - while (1) { - len = strlen(_converseWorkString); - - for (i = len; i >= 0; i--) { - c = _converseWorkString[i]; - - if ((c == ' ' || c == '\0') && (_vm->_font->getStringWidth(kKnownFontSmall, _converseWorkString, i, kFontNormal) <= _vm->getDisplayInfo().converseMaxTextWidth)) { - break; - } - } - if (i < 0) { - return true; - } - - if (_converseTextCount == CONVERSE_MAX_TEXTS) { - return true; - } - - _converseText[_converseTextCount].text = (char *)malloc(i + 1); - strncpy(_converseText[_converseTextCount].text, _converseWorkString, i); - - _converseText[_converseTextCount].text[i] = 0; - _converseText[_converseTextCount].textNum = count; - _converseText[_converseTextCount].stringNum = _converseStrCount; - _converseText[_converseTextCount].replyId = replyId; - _converseText[_converseTextCount].replyFlags = replyFlags; - _converseText[_converseTextCount].replyBit = replyBit; - - _converseTextCount++; - count++; - - if (len == i) - break; - - strncpy(_converseWorkString, &_converseWorkString[i + 1], len - i); - } - - _converseStrCount++; - - return false; -} - -void Interface::converseDisplayText() { - int end; - - _converseStartPos = 0; - - end = _converseTextCount - _vm->getDisplayInfo().converseTextLines; - - if (end < 0) - end = 0; - - _converseEndPos = end; - draw(); -} - - -void Interface::converseSetTextLines(int row) { - int pos = row + _converseStartPos; - if (pos >= _converseTextCount) - pos = -1; - if (pos != _conversePos) { - _conversePos = pos; - draw(); - } -} - -void Interface::converseDisplayTextLines(Surface *ds) { - int relPos; - byte foregnd; - byte backgnd; - byte bulletForegnd; - byte bulletBackgnd; - const char *str; - char bullet[2] = { - (char)0xb7, 0 - }; - Rect rect(8, _vm->getDisplayInfo().converseTextLines * _vm->getDisplayInfo().converseTextHeight); - Point textPoint; - - assert(_conversePanel.buttonsCount >= 6); - - bulletForegnd = kITEColorGreen; - bulletBackgnd = kITEColorBlack; - - rect.moveTo(_conversePanel.x + _conversePanel.buttons[0].xOffset, - _conversePanel.y + _conversePanel.buttons[0].yOffset); - - ds->drawRect(rect, kITEColorDarkGrey); //fill bullet place - - for (int i = 0; i < _vm->getDisplayInfo().converseTextLines; i++) { - relPos = _converseStartPos + i; - - if (_converseTextCount <= relPos) { - break; - } - - if (_conversePos >= 0 && _converseText[_conversePos].stringNum == _converseText[relPos].stringNum) { - foregnd = kITEColorBrightWhite; - backgnd = (!_vm->leftMouseButtonPressed()) ? kITEColorDarkGrey : kITEColorGrey; - } else { - foregnd = kITEColorBlue; - backgnd = kITEColorDarkGrey; - } - - _conversePanel.calcPanelButtonRect(&_conversePanel.buttons[i], rect); - rect.left += 8; - ds->drawRect(rect, backgnd); - - str = _converseText[relPos].text; - - if (_converseText[relPos].textNum == 0) { // first entry - textPoint.x = rect.left - 6; - textPoint.y = rect.top; - - _vm->_font->textDraw(kKnownFontSmall, ds, bullet, textPoint, bulletForegnd, bulletBackgnd, (FontEffectFlags)(kFontShadow | kFontDontmap)); - } - textPoint.x = rect.left + 1; - textPoint.y = rect.top; - _vm->_font->textDraw(kKnownFontSmall, ds, str, textPoint, foregnd, kITEColorBlack, kFontShadow); - } - - if (_converseStartPos != 0) { - drawPanelButtonArrow(ds, &_conversePanel, _converseUpButton); - } - - if (_converseStartPos != _converseEndPos) { - drawPanelButtonArrow(ds, &_conversePanel, _converseDownButton); - } -} - -void Interface::converseChangePos(int chg) { - if ((chg < 0 && _converseStartPos + chg >= 0) || - (chg > 0 && _converseStartPos < _converseEndPos)) { - _converseStartPos += chg; - draw(); - } -} - -void Interface::converseSetPos(int key) { - Converse *ct; - int selection = key - '1'; - - if (selection >= _converseTextCount) - return; - - converseSetTextLines(selection); - - ct = &_converseText[_conversePos]; - - _vm->_script->finishDialog(ct->replyId, ct->replyFlags, ct->replyBit); - - if (_vm->_puzzle->isActive()) - _vm->_puzzle->handleReply(ct->replyId); - - _conversePos = -1; -} - - -void Interface::handleConverseUpdate(const Point& mousePoint) { - bool changed; - - PanelButton *last = _conversePanel.currentButton; - - if (!_vm->mouseButtonPressed()) { // remove pressed flag - if (_converseUpButton) { - _converseUpButton->state = 0; - _converseDownButton->state = 0; - } - } - - _conversePanel.currentButton = converseHitTest(mousePoint); - changed = last != _conversePanel.currentButton; - - - if (_conversePanel.currentButton == NULL) { - _conversePos = -1; - if (changed) { - draw(); - } - return; - } - - if (_conversePanel.currentButton->type == kPanelButtonConverseText) { - converseSetTextLines(_conversePanel.currentButton->id); - } - - if (_conversePanel.currentButton->type == kPanelButtonArrow) { - if (_conversePanel.currentButton->state == 1) { - //TODO: insert timeout catchup - converseChangePos(_conversePanel.currentButton->id); - } - draw(); - } -} - - -void Interface::handleConverseClick(const Point& mousePoint) { - _conversePanel.currentButton = converseHitTest(mousePoint); - - if (_conversePanel.currentButton == NULL) { - return; - } - - if (_conversePanel.currentButton->type == kPanelButtonConverseText) { - converseSetPos(_conversePanel.currentButton->ascii); - } - - if (_conversePanel.currentButton->type == kPanelButtonArrow) { - _conversePanel.currentButton->state = 1; - converseChangePos(_conversePanel.currentButton->id); - } - -} - -void Interface::saveState(Common::OutSaveFile *out) { - out->writeUint16LE(_inventoryCount); - - for (int i = 0; i < _inventoryCount; i++) { - out->writeUint16LE(_inventory[i]); - } -} - -void Interface::loadState(Common::InSaveFile *in) { - _inventoryCount = in->readUint16LE(); - - for (int i = 0; i < _inventoryCount; i++) { - _inventory[i] = in->readUint16LE(); - } - - updateInventory(0); -} - -void Interface::mapPanelShow() { - int i; - byte *resource; - size_t resourceLength, imageLength; - Surface *backBuffer; - Rect rect; - byte *image; - int imageWidth, imageHeight; - const byte *pal; - PalEntry cPal[PAL_ENTRIES]; - - _vm->_gfx->showCursor(false); - - backBuffer = _vm->_gfx->getBackBuffer(); - - rect.left = rect.top = 0; - - _vm->_resource->loadResource(_interfaceContext, - _vm->_resource->convertResourceId(RID_ITE_TYCHO_MAP), resource, resourceLength); - if (resourceLength == 0) { - error("Interface::mapPanelShow() unable to load Tycho map resource"); - } - - _vm->_gfx->getCurrentPal(_mapSavedPal); - - for (i = 0; i < 6 ; i++) { - _vm->_gfx->palToBlack(_mapSavedPal, 0.2 * i); - _vm->_render->drawScene(); - _vm->_system->delayMillis(5); - } - - _vm->_render->setFlag(RF_MAP); - - _vm->decodeBGImage(resource, resourceLength, &image, &imageLength, &imageWidth, &imageHeight); - pal = _vm->getImagePal(resource, resourceLength); - - for (i = 0; i < PAL_ENTRIES; i++) { - cPal[i].red = *pal++; - cPal[i].green = *pal++; - cPal[i].blue = *pal++; - } - - rect.setWidth(imageWidth); - rect.setHeight(imageHeight); - - backBuffer->blit(rect, image); - - // Evil Evil - for (i = 0; i < 6 ; i++) { - _vm->_gfx->blackToPal(cPal, 0.2 * i); - _vm->_render->drawScene(); - _vm->_system->delayMillis(5); - } - - free(resource); - free(image); - - setSaveReminderState(false); - - _mapPanelCrossHairState = true; -} - -void Interface::mapPanelClean() { - PalEntry pal[PAL_ENTRIES]; - int i; - - _vm->_gfx->getCurrentPal(pal); - - for (i = 0; i < 6 ; i++) { - _vm->_gfx->palToBlack(pal, 0.2 * i); - _vm->_render->drawScene(); - _vm->_system->delayMillis(5); - } - - _vm->_render->clearFlag(RF_MAP); - setMode(kPanelMain); - - _vm->_gfx->showCursor(true); - _vm->_render->drawScene(); - - for (i = 0; i < 6 ; i++) { - _vm->_gfx->blackToPal(_mapSavedPal, 0.2 * i); - _vm->_render->drawScene(); - _vm->_system->delayMillis(5); - } -} - -void Interface::mapPanelDrawCrossHair() { - Surface *backBuffer; - - backBuffer = _vm->_gfx->getBackBuffer(); - _mapPanelCrossHairState = !_mapPanelCrossHairState; - - Point mapPosition = _vm->_isoMap->getMapPosition(); - Rect screen(_vm->getDisplayWidth(), _vm->_scene->getHeight()); - - if (screen.contains(mapPosition)) { - _vm->_sprite->draw(backBuffer, _vm->getDisplayClip(), _vm->_sprite->_mainSprites, - _mapPanelCrossHairState? RID_ITE_SPR_XHAIR1 : RID_ITE_SPR_XHAIR2, - mapPosition, 256); - } -} - -void Interface::keyBoss() { - if (_vm->getGameType() != GType_IHNM) - return; - - if (_bossMode != -1 || _fadeMode != kNoFade) - return; - - _vm->_sound->pauseVoice(); - _vm->_sound->pauseSound(); - _vm->_music->pause(); - - int i; - byte *resource; - size_t resourceLength, imageLength; - Surface *backBuffer; - Rect rect; - byte *image; - int imageWidth, imageHeight; - const byte *pal; - PalEntry cPal[PAL_ENTRIES]; - - _vm->_gfx->showCursor(false); - - backBuffer = _vm->_gfx->getBackBuffer(); - - rect.left = rect.top = 0; - - _vm->_resource->loadResource(_interfaceContext, RID_IHNM_BOSS_SCREEN, resource, resourceLength); - if (resourceLength == 0) { - error("Interface::bossKey() unable to load Boss image resource"); - } - - _bossMode = _panelMode; - setMode(kPanelBoss); - - _vm->decodeBGImage(resource, resourceLength, &image, &imageLength, &imageWidth, &imageHeight); - rect.setWidth(imageWidth); - rect.setHeight(imageHeight); - - _vm->_gfx->getCurrentPal(_mapSavedPal); - pal = _vm->getImagePal(resource, resourceLength); - - for (i = 0; i < PAL_ENTRIES; i++) { - cPal[i].red = *pal++; - cPal[i].green = *pal++; - cPal[i].blue = *pal++; - } - - backBuffer->blit(rect, image); - - _vm->_gfx->setPalette(cPal); - - free(resource); - free(image); -} - - -void Interface::keyBossExit() { - PalEntry pal[PAL_ENTRIES]; - - _vm->_sound->resumeVoice(); - _vm->_sound->resumeSound(); - _vm->_music->resume(); - - _vm->_gfx->getCurrentPal(pal); - - _vm->_gfx->palToBlack(pal, 1); - setMode(_bossMode); - - _vm->_render->drawScene(); - - _vm->_gfx->blackToPal(_mapSavedPal, 1); - - _vm->_gfx->showCursor(true); - - _bossMode = -1; -} - - -} // End of namespace Saga diff --git a/saga/interface.h b/saga/interface.h deleted file mode 100644 index bee3fd4a2a..0000000000 --- a/saga/interface.h +++ /dev/null @@ -1,466 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Game interface module private header file - -#ifndef SAGA_INTERFACE_H__ -#define SAGA_INTERFACE_H__ - -#include "common/savefile.h" - -#include "saga/sprite.h" -#include "saga/script.h" - -namespace Saga { - -enum InterfaceUpdateFlags { - UPDATE_MOUSEMOVE = 1, - UPDATE_LEFTBUTTONCLICK = 2, - UPDATE_RIGHTBUTTONCLICK = 4, - UPDATE_MOUSECLICK = UPDATE_LEFTBUTTONCLICK | UPDATE_RIGHTBUTTONCLICK, - UPDATE_WHEELUP = 8, - UPDATE_WHEELDOWN = 16 -}; - -#define CONVERSE_MAX_TEXTS 64 -#define CONVERSE_MAX_WORK_STRING 128 - -#define ITE_INVENTORY_SIZE 24 - -#define VERB_STRLIMIT 32 - -#define STATUS_TEXT_LEN 128 -#define STATUS_TEXT_INPUT_MAX 256 - -// Converse-specific stuff - -enum PanelModes { - kPanelNull, - kPanelMain, - kPanelOption, - kPanelSave, //ex- kPanelTextBox, - kPanelQuit, - kPanelError, - kPanelLoad, - kPanelConverse, - kPanelProtect, - kPanelPlacard, - kPanelMap, - kPanelSceneSubstitute, - kPanelChapterSelection, - kPanelCutaway, - kPanelVideo, - kPanelBoss -// kPanelInventory -}; - -enum FadeModes { - kNoFade = 0, - kFadeIn, - kFadeOut -}; - -struct InterfacePanel { - int x; - int y; - byte *image; - size_t imageLength; - int imageWidth; - int imageHeight; - - PanelButton *currentButton; - int buttonsCount; - PanelButton *buttons; - SpriteList sprites; - - InterfacePanel() { - x = y = 0; - image = NULL; - imageLength = 0; - imageWidth = imageHeight = 0; - currentButton = NULL; - buttonsCount = 0; - buttons = NULL; - } - - PanelButton *getButton(int index) { - if ((index >= 0) && (index < buttonsCount)) { - return &buttons[index]; - } - return NULL; - } - - void getRect(Rect &rect) { - rect.left = x; - rect.top = y; - rect.setWidth(imageWidth); - rect.setHeight(imageHeight); - } - - void calcPanelButtonRect(const PanelButton* panelButton, Rect &rect) { - rect.left = x + panelButton->xOffset; - rect.right = rect.left + panelButton->width; - rect.top = y + panelButton->yOffset; - rect.bottom = rect.top + panelButton->height; - } - - PanelButton *hitTest(const Point& mousePoint, int buttonType) { - PanelButton *panelButton; - Rect rect; - int i; - for (i = 0; i < buttonsCount; i++) { - panelButton = &buttons[i]; - if (panelButton != NULL) { - if ((panelButton->type & buttonType) > 0) { - calcPanelButtonRect(panelButton, rect); - if (rect.contains(mousePoint)) { - return panelButton; - } - } - } - } - return NULL; - } - - void zeroAllButtonState() { - int i; - for (i = 0; i < buttonsCount; i++) { - buttons[i].state = 0; - } - } - - -}; - -struct Converse { - char *text; - int stringNum; - int textNum; - int replyId; - int replyFlags; - int replyBit; -}; - - -enum StatusTextInputState { - kStatusTextInputFirstRun, - kStatusTextInputEntered, - kStatusTextInputAborted -}; - -class Interface { -public: - Interface(SagaEngine *vm); - ~Interface(void); - - int activate(); - int deactivate(); - void setSaveReminderState(int state) { - _saveReminderState = state; - draw(); - } - int getSaveReminderState() { - return _saveReminderState; - } - bool isActive() { return _active; } - void setMode(int mode); - int getMode(void) const { return _panelMode; } - void setFadeMode(int fadeMode) { - _fadeMode = fadeMode; - draw(); - } - int getFadeMode() const { - return _fadeMode; - } - void rememberMode(); - void restoreMode(); - bool isInMainMode() { return _inMainMode; } - void setStatusText(const char *text, int statusColor = -1); - void loadScenePortraits(int resourceId); - void setLeftPortrait(int portrait) { - _leftPortrait = portrait; - draw(); - } - void setRightPortrait(int portrait) { - _rightPortrait = portrait; - draw(); - } - void setPortraitBgColor(int red, int green, int blue) { - _portraitBgColor.red = red; - _portraitBgColor.green = green; - _portraitBgColor.blue = blue; - } - - void draw(); - void drawOption(); - void drawQuit(); - void drawLoad(); - void drawSave(); - void drawProtect(); - void update(const Point& mousePoint, int updateFlag); - void drawStatusBar(); - void setVerbState(int verb, int state); - - bool processAscii(uint16 ascii, bool synthetic = false); - void processKeyUp(uint16 ascii); - - void keyBoss(); - void keyBossExit(); - - void disableAbortSpeeches(bool d) { _disableAbortSpeeches = d; } - - bool _textInput; - - bool _statusTextInput; - StatusTextInputState _statusTextInputState; - char _statusTextInputString[STATUS_TEXT_INPUT_MAX]; - void enterStatusString() { - _statusTextInput = true; - _statusTextInputPos = 0; - _statusTextInputString[0] = 0; - setStatusText(_statusTextInputString); - } - -private: - static void textInputRepeatCallback(void *refCon); - - void drawInventory(Surface *backBuffer); - void updateInventory(int pos); - void inventoryChangePos(int chg); - void inventorySetPos(int key); - -public: - void refreshInventory() { - updateInventory(_inventoryCount); - draw(); - } - void addToInventory(int objectId); - void removeFromInventory(int objectId); - void clearInventory(); - int inventoryItemPosition(int objectId); - int getInventoryContentByPanelButton(PanelButton * panelButton) { - int cell = _inventoryStart + panelButton->id; - if (cell >= _inventoryCount) { - return 0; - } - return _inventory[cell]; - } - - PanelButton *inventoryHitTest(const Point& mousePoint) { - return _mainPanel.hitTest(mousePoint, kPanelButtonInventory); - } - PanelButton *verbHitTest(const Point& mousePoint){ - return _mainPanel.hitTest(mousePoint, kPanelButtonVerb); - } - void saveState(Common::OutSaveFile *out); - void loadState(Common::InSaveFile *in); - - void mapPanelDrawCrossHair(); - - int32 getProtectHash() { return _protectHash; } - -private: - void handleMainUpdate(const Point& mousePoint); // main panel update - void handleMainClick(const Point& mousePoint); // main panel click - - PanelButton *converseHitTest(const Point& mousePoint) { - return _conversePanel.hitTest(mousePoint, kPanelAllButtons); - } - void handleConverseUpdate(const Point& mousePoint); // converse panel update - void handleConverseClick(const Point& mousePoint); // converse panel click - - PanelButton *optionHitTest(const Point& mousePoint) { - return _optionPanel.hitTest(mousePoint, kPanelButtonOptionSaveFiles | kPanelButtonOption | kPanelButtonOptionSlider); - } - void handleOptionUpdate(const Point& mousePoint); // option panel update - void handleOptionClick(const Point& mousePoint); // option panel click - - PanelButton *quitHitTest(const Point& mousePoint) { - return _quitPanel.hitTest(mousePoint, kPanelAllButtons); - } - void handleQuitUpdate(const Point& mousePoint); // quit panel update - void handleQuitClick(const Point& mousePoint); // quit panel click - - PanelButton *loadHitTest(const Point& mousePoint) { - return _loadPanel.hitTest(mousePoint, kPanelAllButtons); - } - void handleLoadUpdate(const Point& mousePoint); // load panel update - void handleLoadClick(const Point& mousePoint); // load panel click - - PanelButton *saveHitTest(const Point& mousePoint) { - return _savePanel.hitTest(mousePoint, kPanelAllButtons); - } - void handleSaveUpdate(const Point& mousePoint); // save panel update - void handleSaveClick(const Point& mousePoint); // save panel click - - void handleChapterSelectionUpdate(const Point& mousePoint); - void handleChapterSelectionClick(const Point& mousePoint); - - void mapPanelShow(); - void mapPanelClean(); - - void lockMode() { _lockedMode = _panelMode; } - void unlockMode() { _panelMode = _lockedMode; } - - void setOption(PanelButton *panelButton); - void setQuit(PanelButton *panelButton); - void setLoad(PanelButton *panelButton); - void setSave(PanelButton *panelButton); - - void drawTextInput(Surface *ds, InterfacePanel *panel, PanelButton *panelButton); - void drawPanelText(Surface *ds, InterfacePanel *panel, PanelButton *panelButton); - void drawPanelButtonText(Surface *ds, InterfacePanel *panel, PanelButton *panelButton); - enum ButtonKind { - kButton, - kSlider, - kEdit - }; - void drawButtonBox(Surface *ds, const Rect &rect, ButtonKind kind, bool down); - void drawPanelButtonArrow(Surface *ds, InterfacePanel *panel, PanelButton *panelButton); - void drawVerbPanelText(Surface *ds, PanelButton *panelButton, KnownColor textKnownColor, KnownColor textShadowKnownColor); - void drawVerbPanel(Surface *backBuffer, PanelButton* panelButton); - void calcOptionSaveSlider(); - bool processTextInput(uint16 ascii); - void processStatusTextInput(uint16 ascii); - void textInputStartRepeat(uint16 ascii); - void textInputRepeat(void); - -public: - void converseInit(void); - void converseClear(void); - bool converseAddText(const char *text, int replyId, byte replyFlags, int replyBit); - void converseDisplayText(); - void converseSetTextLines(int row); - void converseChangePos(int chg); - void converseSetPos(int key); - -private: - void converseDisplayTextLines(Surface *ds); - PanelButton *getPanelButtonByVerbType(int verb) { - if ((verb < 0) || (verb >= kVerbTypeIdsMax)) { - error("Interface::getPanelButtonByVerbType wrong verb"); - } - return _verbTypeToPanelButton[verb]; - } - - void validateOptionButtons() { - if (!_vm->isSaveListFull() && (_optionSaveFileTitleNumber == 0) && (_optionPanel.currentButton != NULL)) { - if (_optionPanel.currentButton->id == kTextLoad) { - _optionPanel.currentButton = NULL; - } - } - } - void validateSaveButtons() { - if ((_textInputStringLength == 0) && (_savePanel.currentButton != NULL)) { - if (_savePanel.currentButton->id == kTextSave) { - _savePanel.currentButton = NULL; - } - } - } - -public: - SpriteList _defPortraits; - -private: - SagaEngine *_vm; - - ResourceContext *_interfaceContext; - InterfacePanel _mainPanel; - PanelButton *_inventoryUpButton; - PanelButton *_inventoryDownButton; - InterfacePanel _conversePanel; - PanelButton *_converseUpButton; - PanelButton *_converseDownButton; - SpriteList _scenePortraits; - PanelButton *_verbTypeToPanelButton[kVerbTypeIdsMax]; - InterfacePanel _optionPanel; - PanelButton * _optionSaveFileSlider; - PanelButton * _optionSaveFilePanel; - InterfacePanel _quitPanel; - InterfacePanel _loadPanel; - InterfacePanel _savePanel; - PanelButton * _saveEdit; - InterfacePanel _protectPanel; - PanelButton * _protectEdit; - - bool _disableAbortSpeeches; - - int _saveReminderState; - bool _active; - int _fadeMode; - int _panelMode; - int _savedMode; - int _lockedMode; - int _bossMode; - bool _inMainMode; - char _statusText[STATUS_TEXT_LEN]; - int _statusOnceColor; - int _leftPortrait; - int _rightPortrait; - PalEntry _portraitBgColor; - - Point _lastMousePoint; - - uint16 *_inventory; - int _inventorySize; - int _inventoryStart; - int _inventoryEnd; - int _inventoryPos; - int _inventoryBox; - int _inventoryCount; - - char _converseWorkString[CONVERSE_MAX_WORK_STRING]; - Converse _converseText[CONVERSE_MAX_TEXTS]; - int _converseTextCount; - int _converseStrCount; - int _converseStartPos; - int _converseEndPos; - int _conversePos; - - uint _optionSaveFileTop; - uint _optionSaveFileTitleNumber; - int16 _optionSaveFileMouseOff; - Rect _optionSaveRectTop; - Rect _optionSaveRectSlider; - Rect _optionSaveRectBottom; - - char _textInputString[SAVE_TITLE_SIZE]; - uint _textInputStringLength; - uint _textInputPos; - uint _textInputMaxWidth; - - uint _statusTextInputPos; - - int _textInputRepeatPhase; - uint16 _textInputRepeatChar; - - PalEntry _mapSavedPal[PAL_ENTRIES]; - bool _mapPanelCrossHairState; - - int32 _protectHash; -}; - -} // End of namespace Saga - -#endif /* INTERFACE_H__ */ diff --git a/saga/isomap.cpp b/saga/isomap.cpp deleted file mode 100644 index 6acbf8ba70..0000000000 --- a/saga/isomap.cpp +++ /dev/null @@ -1,1694 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Isometric level module -#include "saga/saga.h" - -#include "saga/gfx.h" - -#include "saga/resnames.h" -#include "saga/scene.h" -#include "saga/isomap.h" -#include "saga/stream.h" - -namespace Saga { - -enum MaskRules { - kMaskRuleNever = 0, - kMaskRuleAlways, - kMaskRuleUMIN, - kMaskRuleUMID, - kMaskRuleUMAX, - kMaskRuleVMIN, - kMaskRuleVMID, - kMaskRuleVMAX, - kMaskRuleYMIN, - kMaskRuleYMID, - kMaskRuleYMAX, - kMaskRuleUVMAX, - kMaskRuleUVMIN, - kMaskRuleUorV, - kMaskRuleUandV -}; - - -static const IsoMap::TilePoint normalDirTable[8] = { - { 1, 1, 0, SAGA_DIAG_NORMAL_COST}, - { 1, 0, 0, SAGA_STRAIGHT_NORMAL_COST}, - { 1,-1, 0, SAGA_DIAG_NORMAL_COST}, - { 0,-1, 0, SAGA_STRAIGHT_NORMAL_COST}, - {-1,-1, 0, SAGA_DIAG_NORMAL_COST}, - {-1, 0, 0, SAGA_STRAIGHT_NORMAL_COST}, - {-1, 1, 0, SAGA_DIAG_NORMAL_COST}, - { 0, 1, 0, SAGA_STRAIGHT_NORMAL_COST}, -}; - -static const IsoMap::TilePoint easyDirTable[8] = { - { 1, 1, 0, SAGA_DIAG_EASY_COST}, - { 1, 0, 0, SAGA_STRAIGHT_EASY_COST}, - { 1,-1, 0, SAGA_DIAG_EASY_COST}, - { 0,-1, 0, SAGA_STRAIGHT_EASY_COST}, - {-1,-1, 0, SAGA_DIAG_EASY_COST}, - {-1, 0, 0, SAGA_STRAIGHT_EASY_COST}, - {-1, 1, 0, SAGA_DIAG_EASY_COST}, - { 0, 1, 0, SAGA_STRAIGHT_EASY_COST}, -}; - -static const IsoMap::TilePoint hardDirTable[8] = { - { 1, 1, 0, SAGA_DIAG_HARD_COST}, - { 1, 0, 0, SAGA_STRAIGHT_HARD_COST}, - { 1,-1, 0, SAGA_DIAG_HARD_COST}, - { 0,-1, 0, SAGA_STRAIGHT_HARD_COST}, - {-1,-1, 0, SAGA_DIAG_HARD_COST}, - {-1, 0, 0, SAGA_STRAIGHT_HARD_COST}, - {-1, 1, 0, SAGA_DIAG_HARD_COST}, - { 0, 1, 0, SAGA_STRAIGHT_HARD_COST}, -}; - -IsoMap::IsoMap(SagaEngine *vm) : _vm(vm) { - _tileData = NULL; - _tilesCount = 0; - _tilePlatformList = NULL; - _tilePlatformsCount = 0; - _metaTileList = NULL; - _metaTilesCount = 0; - _multiTable = NULL; - _multiCount = 0; - _multiTableData = NULL; - _multiDataCount = 0; - _viewScroll.x = (128 - 8) * 16; - _viewScroll.x = (128 - 8) * 16 - 64; - _viewDiff = 1; - -} - -void IsoMap::loadImages(const byte *resourcePointer, size_t resourceLength) { - IsoTileData *tileData; - uint16 i; - - if (resourceLength == 0) { - error("IsoMap::loadImages wrong resourceLength"); - } - - _tileData = (byte*)malloc(resourceLength); - _tileDataLength = resourceLength; - memcpy(_tileData, resourcePointer, resourceLength); - - MemoryReadStreamEndian readS(_tileData, _tileDataLength, _vm->isBigEndian()); - readS.readUint16(); // skip - _tilesCount = readS.readUint16(); - _tilesCount = _tilesCount / SAGA_ISOTILEDATA_LEN; - - readS.seek(0); - - _tilesTable = (IsoTileData *)malloc(_tilesCount * sizeof(*_tilesTable)); - if (_tilesTable == NULL) { - memoryError("IsoMap::loadImages"); - } - - for (i = 0; i < _tilesCount; i++) { - tileData = &_tilesTable[i]; - tileData->height = readS.readByte(); - tileData->attributes = readS.readSByte(); - tileData->offset = readS.readUint16(); - tileData->terrainMask = readS.readUint16(); - tileData->FGDBGDAttr = readS.readByte(); - readS.readByte(); //skip - } - -} - -void IsoMap::loadPlatforms(const byte * resourcePointer, size_t resourceLength) { - TilePlatformData *tilePlatformData; - uint16 i, x, y; - - if (resourceLength == 0) { - error("IsoMap::loadPlatforms wrong resourceLength"); - } - - MemoryReadStreamEndian readS(resourcePointer, resourceLength, _vm->isBigEndian()); - - _tilePlatformsCount = resourceLength / SAGA_TILEPLATFORMDATA_LEN; - _tilePlatformList = (TilePlatformData *)malloc(_tilePlatformsCount * sizeof(*_tilePlatformList)); - if (_tilePlatformList == NULL) { - memoryError("IsoMap::loadPlatforms"); - } - - for (i = 0; i < _tilePlatformsCount; i++) { - tilePlatformData = &_tilePlatformList[i]; - tilePlatformData->metaTile = readS.readSint16(); - tilePlatformData->height = readS.readSint16(); - tilePlatformData->highestPixel = readS.readSint16(); - tilePlatformData->vBits = readS.readByte(); - tilePlatformData->uBits = readS.readByte(); - for (x = 0; x < SAGA_PLATFORM_W; x++) { - for (y = 0; y < SAGA_PLATFORM_W; y++) { - tilePlatformData->tiles[x][y] = readS.readSint16(); - } - } - } - -} - -void IsoMap::loadMap(const byte * resourcePointer, size_t resourceLength) { - uint16 x, y; - - if (resourceLength != SAGA_TILEMAP_LEN) { - error("IsoMap::loadMap wrong resourceLength"); - } - - MemoryReadStreamEndian readS(resourcePointer, resourceLength, _vm->isBigEndian()); - _tileMap.edgeType = readS.readByte(); - readS.readByte(); //skip - - for (x = 0; x < SAGA_TILEMAP_W; x++) { - for (y = 0; y < SAGA_TILEMAP_H; y++) { - _tileMap.tilePlatforms[x][y] = readS.readSint16(); - } - } - -} - -void IsoMap::loadMetaTiles(const byte * resourcePointer, size_t resourceLength) { - MetaTileData *metaTileData; - uint16 i, j; - - if (resourceLength == 0) { - error("IsoMap::loadMetaTiles wrong resourceLength"); - } - - MemoryReadStreamEndian readS(resourcePointer, resourceLength, _vm->isBigEndian()); - _metaTilesCount = resourceLength / SAGA_METATILEDATA_LEN; - - _metaTileList = (MetaTileData *)malloc(_metaTilesCount * sizeof(*_metaTileList)); - if (_metaTileList == NULL) { - memoryError("IsoMap::loadMetaTiles"); - } - - for (i = 0; i < _metaTilesCount; i++) { - metaTileData = &_metaTileList[i]; - metaTileData->highestPlatform = readS.readUint16(); - metaTileData->highestPixel = readS.readUint16(); - for (j = 0; j < SAGA_MAX_PLATFORM_H; j++) { - metaTileData->stack[j] = readS.readSint16(); - } - } -} - -void IsoMap::loadMulti(const byte * resourcePointer, size_t resourceLength) { - MultiTileEntryData *multiTileEntryData; - uint16 i; - int16 offsetDiff; - - if (resourceLength < 2) { - error("IsoMap::loadMetaTiles wrong resourceLength"); - } - - MemoryReadStreamEndian readS(resourcePointer, resourceLength, _vm->isBigEndian()); - _multiCount = readS.readUint16(); - _multiTable = (MultiTileEntryData *)malloc(_multiCount * sizeof(*_multiTable)); - if (_multiTable == NULL) { - memoryError("IsoMap::loadMulti"); - } - - for (i = 0; i < _multiCount; i++) { - multiTileEntryData = &_multiTable[i]; - readS.readUint32();//skip - multiTileEntryData->offset = readS.readSint16(); - multiTileEntryData->u = readS.readByte(); - multiTileEntryData->v = readS.readByte(); - multiTileEntryData->h = readS.readByte(); - multiTileEntryData->uSize = readS.readByte(); - multiTileEntryData->vSize = readS.readByte(); - multiTileEntryData->numStates = readS.readByte(); - multiTileEntryData->currentState = readS.readByte(); - readS.readByte();//skip - } - - offsetDiff = (readS.pos() - 2); - - for (i = 0; i < _multiCount; i++) { - _multiTable[i].offset -= offsetDiff; - } - - _multiDataCount = (readS.size() - readS.pos()) / 2; - - _multiTableData = (int16 *)malloc(_multiDataCount * sizeof(*_multiTableData)); - for (i = 0; i < _multiDataCount; i++) { - _multiTableData[i] = readS.readSint16(); - } -} - -void IsoMap::freeMem() { - free(_tileData); - _tileData = NULL; - _tilesCount = 0; - free(_tilePlatformList); - _tilePlatformList = NULL; - _tilePlatformsCount = 0; - free(_metaTileList); - _metaTileList = NULL; - _metaTilesCount = 0; - free(_multiTable); - _multiTable = NULL; - _multiCount = 0; - free(_multiTableData); - _multiTableData = NULL; - _multiDataCount = 0; -} - -void IsoMap::adjustScroll(bool jump) { - Point playerPoint; - Point minScrollPos; - Point maxScrollPos; - - - tileCoordsToScreenPoint(_vm->_actor->_centerActor->_location, playerPoint); - - if (_vm->_scene->currentSceneResourceId() == RID_ITE_OVERMAP_SCENE) { - _mapPosition.x = (playerPoint.x + _viewScroll.x) * 30 / 100 - (381); - _mapPosition.y = (playerPoint.y + _viewScroll.y) * 30 / 100 - (342); - } - - if (_vm->_actor->_centerActor != _vm->_actor->_protagonist) { - playerPoint.y -= 24; - } - playerPoint.y -= 28; - - playerPoint.x += _viewScroll.x - _vm->getDisplayWidth()/2; - playerPoint.y += _viewScroll.y - _vm->_scene->getHeight()/2; - - minScrollPos.x = playerPoint.x - SAGA_SCROLL_LIMIT_X1; - minScrollPos.y = playerPoint.y - SAGA_SCROLL_LIMIT_Y1; - - maxScrollPos.x = playerPoint.x + SAGA_SCROLL_LIMIT_X1; - maxScrollPos.y = playerPoint.y + SAGA_SCROLL_LIMIT_Y2; - - if (jump) { - if (_viewScroll.y < minScrollPos.y) { - _viewScroll.y = minScrollPos.y; - } - if (_viewScroll.y > maxScrollPos.y) { - _viewScroll.y = maxScrollPos.y; - } - if (_viewScroll.x < minScrollPos.x) { - _viewScroll.x = minScrollPos.x; - } - if (_viewScroll.x > maxScrollPos.x) { - _viewScroll.x = maxScrollPos.x; - } - } else { - _viewScroll.y = smoothSlide( _viewScroll.y, minScrollPos.y, maxScrollPos.y ); - _viewScroll.x = smoothSlide( _viewScroll.x, minScrollPos.x, maxScrollPos.x ); - } - - if (_vm->_scene->currentSceneResourceId() == RID_ITE_OVERMAP_SCENE) { - ObjectData *obj; - uint16 objectId; - objectId = _vm->_actor->objIndexToId(ITE_OBJ_MAP); - obj = _vm->_actor->getObj(objectId); - if (obj->_sceneNumber != ITE_SCENE_INV) { - _viewScroll.x = 1552 + 8; - _viewScroll.y = 1456 + 8; - } - } -} - -int16 IsoMap::findMulti(int16 tileIndex, int16 absU, int16 absV, int16 absH) { - MultiTileEntryData *multiTileEntryData; - int16 ru; - int16 rv; - int16 mu; - int16 mv; - int16 state; - uint16 i, offset; - int16 *tiles; - - ru = (tileIndex >> 13) & 0x03; - rv = (tileIndex >> 11) & 0x03; - mu = absU - ru; - mv = absV - rv; - - tileIndex = 0; - for (i = 0; i < _multiCount; i++) { - multiTileEntryData = &_multiTable[i]; - - if ((multiTileEntryData->u == mu) && - (multiTileEntryData->v == mv) && - (multiTileEntryData->h == absH)) { - state = multiTileEntryData->currentState; - - offset = (ru + state * multiTileEntryData->uSize) * multiTileEntryData->vSize + rv; - offset *= sizeof(*_multiTableData); - offset += multiTileEntryData->offset; - if (offset + sizeof(*_multiTableData) - 1 >= _multiDataCount * sizeof(*_multiTableData)) { - error("wrong multiTileEntryData->offset"); - } - tiles = (int16*)((byte*)_multiTableData + offset); - tileIndex = *tiles; - if (tileIndex >= 256) { - warning("something terrible happened"); - return 1; - } - return tileIndex; - } - } - - return 1; -} - -void IsoMap::draw(Surface *ds) { - - _tileClip = _vm->_scene->getSceneClip(); - ds->drawRect(_tileClip, 0); - drawTiles(ds, NULL); -} - -void IsoMap::setMapPosition(int x, int y) { - _mapPosition.x = x; - _mapPosition.y = y; -} - -void IsoMap::drawSprite(Surface *ds, SpriteList &spriteList, int spriteNumber, const Location &location, const Point &screenPosition, int scale) { - int width; - int height; - int xAlign; - int yAlign; - const byte *spriteBuffer; - Point spritePointer; - Rect clip(_vm->_scene->getSceneClip()); - - _vm->_sprite->getScaledSpriteBuffer(spriteList, spriteNumber, scale, width, height, xAlign, yAlign, spriteBuffer); - - spritePointer.x = screenPosition.x + xAlign; - spritePointer.y = screenPosition.y + yAlign; - - _tileClip.left = spritePointer.x; - _tileClip.top = spritePointer.y; - _tileClip.right = spritePointer.x + width; - _tileClip.bottom = spritePointer.y + height; - - if (_tileClip.left < 0) { - _tileClip.left = 0; - } - if (_tileClip.right > _vm->getDisplayWidth()) { - _tileClip.right = _vm->getDisplayWidth(); - } - if (_tileClip.top < 0) { - _tileClip.top = 0; - } - if (_tileClip.bottom > _vm->_scene->getHeight()) { - _tileClip.bottom = _vm->_scene->getHeight(); - } - - _vm->_sprite->drawClip(ds, clip, spritePointer, width, height, spriteBuffer); - drawTiles(ds, &location); -} - - -void IsoMap::drawTiles(Surface *ds, const Location *location) { - Point view1; - Point fineScroll; - Point tileScroll; - Point metaTileY; - Point metaTileX; - int16 u0, v0, - u1, v1, - u2, v2, - uc, vc; - uint16 metaTileIndex; - Location rLocation; - int16 workAreaWidth; - int16 workAreaHeight; - - tileScroll.x = _viewScroll.x >> 4; - tileScroll.y = _viewScroll.y >> 4; - - fineScroll.x = _viewScroll.x & 0xf; - fineScroll.y = _viewScroll.y & 0xf; - - view1.x = tileScroll.x - (8 * SAGA_TILEMAP_W); - view1.y = (8 * SAGA_TILEMAP_W) - tileScroll.y; - - u0 = ((view1.y + 64) * 2 + view1.x) >> 4; - v0 = ((view1.y + 64) * 2 - view1.x) >> 4; - - metaTileY.x = (u0 - v0) * 128 - (view1.x * 16 + fineScroll.x); - metaTileY.y = (view1.y * 16 - fineScroll.y) - (u0 + v0) * 64; - - workAreaWidth = _vm->getDisplayWidth() + 128; - workAreaHeight = _vm->_scene->getHeight() + 128 + 80; - - for (u1 = u0, v1 = v0; metaTileY.y < workAreaHeight; u1--, v1-- ) { - metaTileX = metaTileY; - - for (u2 = u1, v2 = v1; metaTileX.x < workAreaWidth; u2++, v2--, metaTileX.x += 256) { - - uc = u2 & (SAGA_TILEMAP_W - 1); - vc = v2 & (SAGA_TILEMAP_W - 1); - - if (uc != u2 || vc != v2) { - metaTileIndex = 0; - switch ( _tileMap.edgeType) { - case kEdgeTypeBlack: - continue; - case kEdgeTypeFill0: - break; - case kEdgeTypeFill1: - metaTileIndex = 1; - break; - case kEdgeTypeRpt: - uc = clamp( 0, u2, SAGA_TILEMAP_W - 1); - vc = clamp( 0, v2, SAGA_TILEMAP_W - 1); - metaTileIndex = _tileMap.tilePlatforms[uc][vc]; - break; - case kEdgeTypeWrap: - metaTileIndex = _tileMap.tilePlatforms[uc][vc]; - break; - } - } else { - metaTileIndex = _tileMap.tilePlatforms[uc][vc]; - } - - if (location != NULL) { - rLocation.u() = location->u() - (u2 << 7); - rLocation.v() = location->v() - (v2 << 7); - rLocation.z = location->z; - drawSpriteMetaTile(ds, metaTileIndex, metaTileX, rLocation, u2 << 3, v2 << 3); - } else { - drawMetaTile(ds, metaTileIndex, metaTileX, u2 << 3, v2 << 3); - } - } - - metaTileY.y += 64; - - metaTileX = metaTileY; - - metaTileX.x -= 128; - - for (u2 = u1 - 1, v2 = v1; metaTileX.x < workAreaWidth; u2++, v2--, metaTileX.x += 256) { - - uc = u2 & (SAGA_TILEMAP_W - 1); - vc = v2 & (SAGA_TILEMAP_W - 1); - - if (uc != u2 || vc != v2) { - metaTileIndex = 0; - switch ( _tileMap.edgeType) { - case kEdgeTypeBlack: - continue; - case kEdgeTypeFill0: - break; - case kEdgeTypeFill1: - metaTileIndex = 1; - break; - case kEdgeTypeRpt: - uc = clamp( 0, u2, SAGA_TILEMAP_W - 1); - vc = clamp( 0, v2, SAGA_TILEMAP_W - 1); - metaTileIndex = _tileMap.tilePlatforms[uc][vc]; - break; - case kEdgeTypeWrap: - metaTileIndex = _tileMap.tilePlatforms[uc][vc]; - break; - } - } else { - metaTileIndex = _tileMap.tilePlatforms[uc][vc]; - } - - if (location != NULL) { - rLocation.u() = location->u() - (u2 << 7); - rLocation.v() = location->v() - (v2 << 7); - rLocation.z = location->z; - drawSpriteMetaTile(ds, metaTileIndex, metaTileX, rLocation, u2 << 3, v2 << 3); - } else { - drawMetaTile(ds, metaTileIndex, metaTileX, u2 << 3, v2 << 3); - } - } - metaTileY.y += 64; - } - -} - -void IsoMap::drawSpriteMetaTile(Surface *ds, uint16 metaTileIndex, const Point &point, Location &location, int16 absU, int16 absV) { - MetaTileData * metaTile; - uint16 high; - int16 platformIndex; - Point platformPoint; - platformPoint = point; - - if (_metaTilesCount <= metaTileIndex) { - error("IsoMap::drawMetaTile wrong metaTileIndex"); - } - - metaTile = &_metaTileList[metaTileIndex]; - - if (metaTile->highestPlatform > 18) { - metaTile->highestPlatform = 0; - } - - for (high = 0; high <= metaTile->highestPlatform; high++, platformPoint.y -= 8, location.z -= 8) { - assert(SAGA_MAX_PLATFORM_H > high); - platformIndex = metaTile->stack[high]; - - if (platformIndex >= 0) { - drawSpritePlatform( ds, platformIndex, platformPoint, location, absU, absV, high ); - } - } -} - -void IsoMap::drawMetaTile(Surface *ds, uint16 metaTileIndex, const Point &point, int16 absU, int16 absV) { - MetaTileData * metaTile; - uint16 high; - int16 platformIndex; - Point platformPoint; - platformPoint = point; - - if (_metaTilesCount <= metaTileIndex) { - error("IsoMap::drawMetaTile wrong metaTileIndex"); - } - - metaTile = &_metaTileList[metaTileIndex]; - - if (metaTile->highestPlatform > 18) { - metaTile->highestPlatform = 0; - } - - for (high = 0; high <= metaTile->highestPlatform; high++, platformPoint.y -= 8) { - assert(SAGA_MAX_PLATFORM_H > high); - platformIndex = metaTile->stack[high]; - - if (platformIndex >= 0) { - drawPlatform( ds, platformIndex, platformPoint, absU, absV, high ); - } - } -} - -void IsoMap::drawSpritePlatform(Surface *ds, uint16 platformIndex, const Point &point, const Location &location, int16 absU, int16 absV, int16 absH) { - TilePlatformData *tilePlatform; - int16 u, v; - Point s; - Point s0; - uint16 tileIndex; - Location copyLocation(location); - - if (_tilePlatformsCount <= platformIndex) { - error("IsoMap::drawPlatform wrong platformIndex"); - } - - tilePlatform = &_tilePlatformList[platformIndex]; - - if ((point.y <= _tileClip.top) || (point.y - SAGA_MAX_TILE_H - SAGA_PLATFORM_W * SAGA_TILE_NOMINAL_H >= _tileClip.bottom)) { - return; - } - - s0 = point; - s0.y -= (((SAGA_PLATFORM_W - 1) + (SAGA_PLATFORM_W - 1)) * 8); - - for (v = SAGA_PLATFORM_W - 1, - copyLocation.v() = location.v() - ((SAGA_PLATFORM_W - 1) << 4); - v >= 0 && s0.y - SAGA_MAX_TILE_H < _tileClip.bottom && s0.x - 128 < _tileClip.right; - v--, copyLocation.v() += 16, s0.x += 16, s0.y += 8) { - - if ((tilePlatform->vBits & (1 << v)) == 0) { - continue; - } - - if (s0.x + 128 + 32 < _tileClip.left) { - continue; - } - - s = s0; - - for (u = SAGA_PLATFORM_W - 1, - copyLocation.u() = location.u() - ((SAGA_PLATFORM_W - 1) << 4); - u >= 0 && s.x + 32 > _tileClip.left && s.y - SAGA_MAX_TILE_H < _tileClip.bottom; - u--, copyLocation.u() += 16, s.x -= 16, s.y += 8 ) { - if (s.x < _tileClip.right && s.y > _tileClip.top) { - - tileIndex = tilePlatform->tiles[u][v]; - if (tileIndex != 0) { - if (tileIndex & SAGA_MULTI_TILE) { - tileIndex = findMulti(tileIndex, absU + u, absV + v, absH); - } - - drawTile(ds, tileIndex, s, ©Location); - } - } - } - } -} - -void IsoMap::drawPlatform(Surface *ds, uint16 platformIndex, const Point &point, int16 absU, int16 absV, int16 absH) { - TilePlatformData *tilePlatform; - int16 u, v; - Point s; - Point s0; - uint16 tileIndex; - - if (_tilePlatformsCount <= platformIndex) { - error("IsoMap::drawPlatform wrong platformIndex"); - } - - tilePlatform = &_tilePlatformList[platformIndex]; - - if ((point.y <= _tileClip.top) || (point.y - SAGA_MAX_TILE_H - SAGA_PLATFORM_W * SAGA_TILE_NOMINAL_H >= _tileClip.bottom)) { - return; - } - - s0 = point; - s0.y -= (((SAGA_PLATFORM_W - 1) + (SAGA_PLATFORM_W - 1)) * 8); - - for (v = SAGA_PLATFORM_W - 1; - v >= 0 && s0.y - SAGA_MAX_TILE_H < _tileClip.bottom && s0.x - 128 < _tileClip.right; - v--, s0.x += 16, s0.y += 8) { - - if ((tilePlatform->vBits & (1 << v)) == 0) { - continue; - } - - if (s0.x + 128 + 32 < _tileClip.left) { - continue; - } - - s = s0; - - for (u = SAGA_PLATFORM_W - 1; - u >= 0 && s.x + 32 > _tileClip.left && s.y - SAGA_MAX_TILE_H < _tileClip.bottom; - u--, s.x -= 16, s.y += 8 ) { - if (s.x < _tileClip.right && s.y > _tileClip.top) { - - tileIndex = tilePlatform->tiles[u][v]; - if (tileIndex > 1) { - if (tileIndex & SAGA_MULTI_TILE) { - tileIndex = findMulti(tileIndex, absU + u, absV + v, absH); - } - - drawTile(ds, tileIndex, s, NULL); - } - } - } - } -} - -#define THRESH0 0 -#define THRESH8 8 -#define THRESH16 16 - -void IsoMap::drawTile(Surface *ds, uint16 tileIndex, const Point &point, const Location *location) { - const byte *tilePointer; - const byte *readPointer; - byte *drawPointer; - Point drawPoint; - int height; - int widthCount = 0; - int row, col, count, lowBound; - int bgRunCount; - int fgRunCount; - - - if (tileIndex >= _tilesCount) { - error("IsoMap::drawTile wrong tileIndex"); - } - - - if (point.x + SAGA_ISOTILE_WIDTH < _tileClip.left) { - return; - } - - if (point.x - SAGA_ISOTILE_WIDTH >= _tileClip.right) { - return; - } - - tilePointer = _tileData + _tilesTable[tileIndex].offset; - height = _tilesTable[tileIndex].height; - - if ((height <= 8) || (height > 64)) { - return; - } - - drawPoint = point; - drawPoint.y -= height; - - if (drawPoint.y >= _tileClip.bottom) { - return; - } - - if (location != NULL) { - if (location->z <= -16) { - if (location->z <= -48) { - if (location->u() < -THRESH8 || location->v() < -THRESH8) { - return; - } - } else { - if (location->u() < THRESH0 || location->v() < THRESH0) { - return; - } - } - } else { - if (location->z >= 16) { - return; - } else { - switch (_tilesTable[tileIndex].GetMaskRule()) { - case kMaskRuleNever: - return; - case kMaskRuleAlways: - break; - case kMaskRuleUMIN: - if (location->u() < THRESH0) { - return; - } - break; - case kMaskRuleUMID: - if (location->u() < THRESH8) { - return; - } - break; - case kMaskRuleUMAX: - if (location->u() < THRESH16) { - return; - } - break; - case kMaskRuleVMIN: - if (location->v() < THRESH0) { - return; - } - break; - case kMaskRuleVMID: - if (location->v() < THRESH8) { - return; - } - break; - case kMaskRuleVMAX: - if (location->v() < THRESH16) { - return; - } - break; - case kMaskRuleYMIN: - if (location->uv() < THRESH0 * 2) { - return; - } - break; - case kMaskRuleYMID: - if (location->uv() < THRESH8 * 2) { - return; - } - break; - case kMaskRuleYMAX: - if (location->uv() < THRESH16 * 2) { - return; - } - break; - case kMaskRuleUVMAX: - if (location->u() < THRESH16 && location->v() < THRESH16) { - return; - } - break; - case kMaskRuleUVMIN: - if (location->u() < THRESH0 || location->v() < THRESH0) { - return; - } - break; - case kMaskRuleUorV: - if (location->u() < THRESH8 && location->v() < THRESH8) { - return; - } - break; - case kMaskRuleUandV: - if (location->u() < THRESH8 || location->v() < THRESH8) { - return; - } - break; - } - } - } - } - - readPointer = tilePointer; - lowBound = MIN((int)(drawPoint.y + height), (int)_tileClip.bottom); - for (row = drawPoint.y; row < lowBound; row++) { - widthCount = 0; - if (row >= _tileClip.top) { - drawPointer = (byte *)ds->pixels + drawPoint.x + (row * ds->pitch); - col = drawPoint.x; - for (;;) { - bgRunCount = *readPointer++; - widthCount += bgRunCount; - if (widthCount >= SAGA_ISOTILE_WIDTH) { - break; - } - - drawPointer += bgRunCount; - col += bgRunCount; - fgRunCount = *readPointer++; - widthCount += fgRunCount; - - count = 0; - while ((col < _tileClip.left) && (count < fgRunCount)) { - count++; - col++; - } - while ((col < _tileClip.right) && (count < fgRunCount)) { - assert((byte *)ds->pixels <= (byte *)(drawPointer + count)); - assert((byte *)((byte *)ds->pixels + (_vm->getDisplayWidth() * - _vm->getDisplayHeight())) > (byte *)(drawPointer + count)); - drawPointer[count] = readPointer[count]; - count++; - col++; - } - readPointer += fgRunCount; - drawPointer += fgRunCount; - } - } else { - for (;;) { - bgRunCount = *readPointer++; - widthCount += bgRunCount; - if (widthCount >= SAGA_ISOTILE_WIDTH) { - break; - } - - fgRunCount = *readPointer++; - widthCount += fgRunCount; - - readPointer += fgRunCount; - } - } - } - -} - -bool IsoMap::checkDragonPoint(int16 u, int16 v, uint16 direction) { - DragonPathCell *pathCell; - - if ((u < 1) || (u >= SAGA_DRAGON_SEARCH_DIAMETER - 1) || (v < 1) || (v >= SAGA_DRAGON_SEARCH_DIAMETER - 1)) { - return false; - } - - pathCell = _dragonSearchArray.getPathCell(u, v); - - if (pathCell->visited) { - return false; - } - - pathCell->visited = 1; - pathCell->direction = direction; - return true; -} - -void IsoMap::pushDragonPoint(int16 u, int16 v, uint16 direction) { - DragonTilePoint *tilePoint; - DragonPathCell *pathCell; - - if ((u < 1) || (u >= SAGA_DRAGON_SEARCH_DIAMETER - 1) || (v < 1) || (v >= SAGA_DRAGON_SEARCH_DIAMETER - 1)) { - return; - } - - pathCell = _dragonSearchArray.getPathCell(u, v); - - if (pathCell->visited) { - return; - } - - tilePoint = _dragonSearchArray.getQueue(_queueCount); - _queueCount++; - if (_queueCount >= SAGA_SEARCH_QUEUE_SIZE) { - _queueCount = 0; - } - - tilePoint->u = u; - tilePoint->v = v; - tilePoint->direction = direction; - - pathCell->visited = 1; - pathCell->direction = direction; -} - -void IsoMap::pushPoint(int16 u, int16 v, uint16 cost, uint16 direction) { - int16 upper; - int16 lower; - int16 mid; - TilePoint *tilePoint; - PathCell *pathCell; - - upper = _queueCount; - lower = 0; - - if ((u < 1) || (u >= SAGA_SEARCH_DIAMETER - 1) || (v < 1) || (v >= SAGA_SEARCH_DIAMETER - 1)) { - return; - } - - pathCell = _searchArray.getPathCell(u, v); - - if ((pathCell->visited) && (pathCell->cost <= cost)) { - return; - } - - if (_queueCount >= SAGA_SEARCH_QUEUE_SIZE) { - return; - } - - while (1) { - mid = (upper + lower) / 2; - tilePoint = _searchArray.getQueue(mid); - - if (upper <= lower) { - break; - } - - if (cost < tilePoint->cost) { - lower = mid + 1; - } else { - upper = mid; - } - } - - if (mid < _queueCount ) { - memmove(tilePoint + 1, tilePoint, (_queueCount - mid) * sizeof (*tilePoint)); - } - _queueCount++; - - tilePoint->u = u; - tilePoint->v = v; - tilePoint->cost = cost; - tilePoint->direction = direction; - - pathCell->visited = 1; - pathCell->direction = direction; - pathCell->cost = cost; -} - -int16 IsoMap::getTileIndex(int16 u, int16 v, int16 z) { - int16 mtileU; - int16 mtileV; - int16 uc; - int16 vc; - int16 u0; - int16 v0; - int16 platformIndex; - int16 metaTileIndex; - - mtileU = u >> 3; - mtileV = v >> 3; - uc = mtileU & (SAGA_TILEMAP_W - 1); - vc = mtileV & (SAGA_TILEMAP_W - 1); - u0 = u & (SAGA_PLATFORM_W - 1); - v0 = v & (SAGA_PLATFORM_W - 1); - - if ((uc != mtileU) || (vc != mtileV)) { - metaTileIndex = 0; - switch ( _tileMap.edgeType) { - case kEdgeTypeBlack: - return 0; - case kEdgeTypeFill0: - break; - case kEdgeTypeFill1: - metaTileIndex = 1; - break; - case kEdgeTypeRpt: - uc = clamp( 0, mtileU, SAGA_TILEMAP_W - 1); - vc = clamp( 0, mtileV, SAGA_TILEMAP_W - 1); - metaTileIndex = _tileMap.tilePlatforms[uc][vc]; - break; - case kEdgeTypeWrap: - metaTileIndex = _tileMap.tilePlatforms[uc][vc]; - break; - } - } else { - metaTileIndex = _tileMap.tilePlatforms[uc][vc]; - } - - if (_metaTilesCount <= metaTileIndex) { - error("IsoMap::getTile wrong metaTileIndex"); - } - - platformIndex = _metaTileList[metaTileIndex].stack[z]; - if (platformIndex < 0) { - return 0; - } - - if (_tilePlatformsCount <= platformIndex) { - error("IsoMap::getTile wrong platformIndex"); - } - - return _tilePlatformList[platformIndex].tiles[u0][v0]; -} - -IsoTileData *IsoMap::getTile(int16 u, int16 v, int16 z) { - int16 tileIndex; - - tileIndex = getTileIndex(u, v, z); - - if (tileIndex == 0) { - return NULL; - } - - if (tileIndex & SAGA_MULTI_TILE) { - tileIndex = findMulti(tileIndex, u, v, z); - } - - return &_tilesTable[tileIndex]; -} - -void IsoMap::testPossibleDirections(int16 u, int16 v, uint16 terraComp[8], int skipCenter) { - IsoTileData *tile; - uint16 fgdMask; - uint16 bgdMask; - uint16 mask; - - - memset(terraComp, 0, 8 * sizeof(uint16)); - -#define FILL_MASK(index, testMask) \ - if ( mask & testMask) { \ - terraComp[index] |= fgdMask; \ - } \ - if (~mask & testMask) { \ - terraComp[index] |= bgdMask; \ - } - -#define TEST_TILE_PROLOG(offsetU, offsetV) \ - tile = getTile(u + offsetU, v + offsetV , _platformHeight); \ - if (tile != NULL) { \ - fgdMask = tile->GetFGDMask(); \ - bgdMask = tile->GetBGDMask(); \ - mask = tile->terrainMask; - -#define TEST_TILE_EPILOG(index) \ - } else { \ - if (_vm->_actor->_protagonist->_location.z > 0) { \ - terraComp[index] = SAGA_IMPASSABLE; \ - } \ - } - -#define TEST_TILE_END } - - TEST_TILE_PROLOG(0, 0) - if (skipCenter) { - if ((mask & 0x0660) && (fgdMask & SAGA_IMPASSABLE)) { - fgdMask = 0; - } - if ((~mask & 0x0660) && (bgdMask & SAGA_IMPASSABLE)) { - bgdMask = 0; - } - } - - FILL_MASK(0, 0xcc00) - FILL_MASK(1, 0x6600) - FILL_MASK(2, 0x3300) - FILL_MASK(3, 0x0330) - FILL_MASK(4, 0x0033) - FILL_MASK(5, 0x0066) - FILL_MASK(6, 0x00cc) - FILL_MASK(7, 0x0cc0) - TEST_TILE_END - - TEST_TILE_PROLOG(1, 1) - FILL_MASK(0, 0x0673) - TEST_TILE_EPILOG(0) - - - TEST_TILE_PROLOG(1, 0) - FILL_MASK(0, 0x0008) - FILL_MASK(1, 0x0666) - FILL_MASK(2, 0x0001) - TEST_TILE_EPILOG(1) - - - TEST_TILE_PROLOG(1, -1) - FILL_MASK(2, 0x06ec) - TEST_TILE_EPILOG(2) - - TEST_TILE_PROLOG(0, 1) - FILL_MASK(0, 0x1000) - FILL_MASK(7, 0x0770) - FILL_MASK(6, 0x0001) - TEST_TILE_EPILOG(7) - - - TEST_TILE_PROLOG(0, -1) - FILL_MASK(2, 0x8000) - FILL_MASK(3, 0x0ee0) - FILL_MASK(4, 0x0008) - TEST_TILE_EPILOG(3) - - - TEST_TILE_PROLOG(-1, 1) - FILL_MASK(6, 0x3670) - TEST_TILE_EPILOG(6) - - - TEST_TILE_PROLOG(-1, 0) - FILL_MASK(6, 0x8000) - FILL_MASK(5, 0x6660) - FILL_MASK(4, 0x1000) - TEST_TILE_EPILOG(5) - - TEST_TILE_PROLOG(-1, -1) - FILL_MASK(4, 0xce60) - TEST_TILE_EPILOG(4) -} - -void IsoMap::placeOnTileMap(const Location &start, Location &result, int16 distance, uint16 direction) { - int16 bestDistance; - int16 bestU; - int16 bestV; - int16 uBase; - int16 vBase; - int16 u; - int16 v; - int i; - ActorData *actor; - TilePoint tilePoint; - uint16 dir; - int16 dist; - uint16 terraComp[8]; - const TilePoint *tdir; - uint16 terrainMask; - - bestDistance = 0; - - - uBase = (start.u() >> 4) - SAGA_SEARCH_CENTER; - vBase = (start.v() >> 4) - SAGA_SEARCH_CENTER; - - bestU = SAGA_SEARCH_CENTER; - bestV = SAGA_SEARCH_CENTER; - - _platformHeight = _vm->_actor->_protagonist->_location.z / 8; - - memset( &_searchArray, 0, sizeof(_searchArray)); - - for (i = 0; i < _vm->_actor->_actorsCount; i++) { - actor = _vm->_actor->_actors[i]; - if (!actor->_inScene) continue; - - u = (actor->_location.u() >> 4) - uBase; - v = (actor->_location.v() >> 4) - vBase; - if ((u >= 0) && (u < SAGA_SEARCH_DIAMETER) && - (v >= 0) && (v < SAGA_SEARCH_DIAMETER) && - ((u != SAGA_SEARCH_CENTER) || (v != SAGA_SEARCH_CENTER))) { - _searchArray.getPathCell(u, v)->visited = 1; - } - } - - _queueCount = 0; - pushPoint(SAGA_SEARCH_CENTER, SAGA_SEARCH_CENTER, 0, 0); - - while (_queueCount > 0) { - - _queueCount--; - tilePoint = *_searchArray.getQueue(_queueCount); - - - dist = ABS(tilePoint.u - SAGA_SEARCH_CENTER) + ABS(tilePoint.v - SAGA_SEARCH_CENTER); - - if (dist > bestDistance) { - bestU = tilePoint.u; - bestV = tilePoint.v; - bestDistance = dist; - - if (dist >= distance) { - break; - } - } - - testPossibleDirections(uBase + tilePoint.u, vBase + tilePoint.v, terraComp, 0); - - - for (dir = 0; dir < 8; dir++) { - terrainMask = terraComp[dir]; - - if (terrainMask & SAGA_IMPASSABLE ) { - continue; - } - - if (dir == direction) { - tdir = &easyDirTable[ dir ]; - } else { - if (dir + 1 == direction || dir - 1 == direction) { - tdir = &normalDirTable[ dir ]; - } else { - tdir = &hardDirTable[ dir ]; - } - } - - pushPoint(tilePoint.u + tdir->u,tilePoint.v + tdir->v, tilePoint.cost + tdir->cost, dir); - } - } - - result.u() = ((uBase + bestU) << 4) + 8; - result.v() = ((vBase + bestV) << 4) + 8; -} - -bool IsoMap::findNearestChasm(int16 &u0, int16 &v0, uint16 &direction) { - int16 u, v; - uint16 i; - u = u0; - v = v0; - - for (i = 1; i < 5; i++) { - if (getTile( u - i, v, 6) == NULL) { - u0 = u - i - 1; - v0 = v; - direction = kDirDownLeft; - return true; - } - - if (getTile( u, v - i, 6) == NULL) { - u0 = u; - v0 = v - i - 1; - direction = kDirDownRight; - return true; - } - - if (getTile( u - i, v - i, 6) == NULL) { - u0 = u - i - 1; - v0 = v - i - 1; - direction = kDirDown; - return true; - } - - if (getTile( u + i, v - i, 6) == NULL) { - u0 = u + i + 1; - v0 = v - i - 1; - direction = kDirDownRight; - return true; - } - - if (getTile( u - i, v + i, 6) == NULL) { - u0 = u + i + 1; - v0 = v - i - 1; - direction = kDirLeft; - return true; - } - } - - for (i = 1; i < 5; i++) { - if (getTile( u + i, v, 6) == NULL) { - u0 = u + i + 1; - v0 = v; - direction = kDirUpRight; - return true; - } - - if (getTile( u, v + i, 6) == NULL) { - u0 = u; - v0 = v + i + 1; - direction = kDirUpLeft; - return true; - } - - if (getTile( u + i, v + i, 6) == NULL) { - u0 = u + i + 1; - v0 = v + i + 1; - direction = kDirUp; - return true; - } - } - return false; -} - -void IsoMap::findDragonTilePath(ActorData* actor,const Location &start, const Location &end, uint16 initialDirection) { - byte *res; - int i; - int16 u; - int16 v; - int16 u1; - int16 v1; - uint16 dir; - - int16 bestDistance; - int16 bestU; - int16 bestV; - - int16 uBase; - int16 vBase; - int16 uFinish; - int16 vFinish; - DragonPathCell *pcell; - IsoTileData *tile; - uint16 mask; - DragonTilePoint *tilePoint; - - int16 dist; - bool first; - - bestDistance = SAGA_DRAGON_SEARCH_DIAMETER; - bestU = SAGA_DRAGON_SEARCH_CENTER, - bestV = SAGA_DRAGON_SEARCH_CENTER; - - uBase = (start.u() >> 4) - SAGA_DRAGON_SEARCH_CENTER; - vBase = (start.v() >> 4) - SAGA_DRAGON_SEARCH_CENTER; - uFinish = (end.u() >> 4) - uBase; - vFinish = (end.v() >> 4) - vBase; - - _platformHeight = _vm->_actor->_protagonist->_location.z / 8; - - memset( &_dragonSearchArray, 0, sizeof(_dragonSearchArray)); - - for (u = 0; u < SAGA_DRAGON_SEARCH_DIAMETER; u++) { - for (v = 0; v < SAGA_DRAGON_SEARCH_DIAMETER; v++) { - - pcell = _dragonSearchArray.getPathCell(u, v); - - u1 = uBase + u; - v1 = vBase + v; - - if ((u1 > 127) || (u1 < 48) || (v1 > 127) || (v1 < 0)) { - pcell->visited = 1; - continue; - } - - tile = getTile(u1, v1, _platformHeight ); - if (tile != NULL) { - mask = tile->terrainMask; - if ( ((mask != 0) && (tile->GetFGDAttr() >= kTerrBlock)) || - ((mask != 0xFFFF) && (tile->GetBGDAttr() >= kTerrBlock)) ) { - pcell->visited = 1; - } - } else { - pcell->visited = 1; - } - } - } - - first = true; - _queueCount = _readCount = 0; - pushDragonPoint( SAGA_DRAGON_SEARCH_CENTER, SAGA_DRAGON_SEARCH_CENTER, initialDirection); - - while (_queueCount != _readCount) { - - tilePoint = _dragonSearchArray.getQueue(_readCount++); - if (_readCount >= SAGA_SEARCH_QUEUE_SIZE) { - _readCount = 0; - } - - - dist = ABS(tilePoint->u - uFinish) + ABS(tilePoint->v - vFinish); - - if (dist < bestDistance) { - - bestU = tilePoint->u; - bestV = tilePoint->v; - bestDistance = dist; - if (dist == 0) { - break; - } - } - - switch (tilePoint->direction) { - case kDirUpRight: - if (checkDragonPoint( tilePoint->u + 1, tilePoint->v + 0, kDirUpRight)) { - pushDragonPoint( tilePoint->u + 2, tilePoint->v + 0, kDirUpRight); - pushDragonPoint( tilePoint->u + 1, tilePoint->v + 1, kDirUpLeft); - pushDragonPoint( tilePoint->u + 1, tilePoint->v - 1, kDirDownRight); - } - break; - case kDirDownRight: - if (checkDragonPoint( tilePoint->u + 0, tilePoint->v - 1, kDirDownRight)) { - pushDragonPoint( tilePoint->u + 0, tilePoint->v - 2, kDirDownRight); - pushDragonPoint( tilePoint->u + 1, tilePoint->v - 1, kDirUpRight); - pushDragonPoint( tilePoint->u - 1, tilePoint->v - 1, kDirDownLeft); - } - break; - case kDirDownLeft: - if (checkDragonPoint( tilePoint->u - 1, tilePoint->v + 0, kDirDownLeft)) { - pushDragonPoint( tilePoint->u - 2, tilePoint->v + 0, kDirDownLeft); - pushDragonPoint( tilePoint->u - 1, tilePoint->v - 1, kDirDownRight); - pushDragonPoint( tilePoint->u - 1, tilePoint->v + 1, kDirUpLeft); - } - break; - case kDirUpLeft: - if (checkDragonPoint( tilePoint->u + 0, tilePoint->v + 1, kDirUpLeft)) { - pushDragonPoint( tilePoint->u + 0, tilePoint->v + 2, kDirUpLeft); - pushDragonPoint( tilePoint->u - 1, tilePoint->v + 1, kDirDownLeft); - pushDragonPoint( tilePoint->u + 1, tilePoint->v + 1, kDirUpRight); - } - break; - } - - if (first && (_queueCount == _readCount)) { - pushDragonPoint( tilePoint->u + 1, tilePoint->v + 0, kDirUpRight); - pushDragonPoint( tilePoint->u + 0, tilePoint->v - 1, kDirDownRight); - pushDragonPoint( tilePoint->u - 1, tilePoint->v + 0, kDirDownLeft); - pushDragonPoint( tilePoint->u + 0, tilePoint->v + 1, kDirUpLeft); - } - first = false; - } - - res = &_pathDirections[SAGA_MAX_PATH_DIRECTIONS]; - i = 0; - while ((bestU != SAGA_DRAGON_SEARCH_CENTER) || (bestV != SAGA_DRAGON_SEARCH_CENTER)) { - pcell = _dragonSearchArray.getPathCell(bestU, bestV); - - *--res = pcell->direction; - i++; - if (i >= SAGA_MAX_PATH_DIRECTIONS) { - break; - } - - dir = (pcell->direction + 4) & 0x07; - - bestU += normalDirTable[dir].u; - bestV += normalDirTable[dir].v; - } - -/* if (i > 64) { - i = 64; - }*/ - - actor->_walkStepsCount = i; - if (i) { - actor->setTileDirectionsSize(i, false); - memcpy(actor->_tileDirections, res, i ); - } - -} - -void IsoMap::findTilePath(ActorData* actor, const Location &start, const Location &end) { - ActorData *other; - int i; - int16 u; - int16 v; - int16 bestDistance; - int16 bestU; - int16 bestV; - - int16 uBase; - int16 vBase; - int16 uFinish; - int16 vFinish; - - TilePoint tilePoint; - uint16 dir; - int16 dist; - uint16 terraComp[8]; - const TilePoint *tdir; - uint16 terrainMask; - const PathCell *pcell; - byte *res; - - - bestDistance = SAGA_SEARCH_DIAMETER; - bestU = SAGA_SEARCH_CENTER, - bestV = SAGA_SEARCH_CENTER; - - uBase = (start.u() >> 4) - SAGA_SEARCH_CENTER; - vBase = (start.v() >> 4) - SAGA_SEARCH_CENTER; - uFinish = (end.u() >> 4) - uBase; - vFinish = (end.v() >> 4) - vBase; - - _platformHeight = _vm->_actor->_protagonist->_location.z / 8; - - - - memset( &_searchArray, 0, sizeof(_searchArray)); - - if (!(actor->_actorFlags & kActorNoCollide) && - (_vm->_scene->currentSceneResourceId() != RID_ITE_OVERMAP_SCENE)) { - for (i = 0; i < _vm->_actor->_actorsCount; i++) { - other = _vm->_actor->_actors[i]; - if (!other->_inScene) continue; - if (other == actor) continue; - - u = (other->_location.u() >> 4) - uBase; - v = (other->_location.v() >> 4) - vBase; - if ((u >= 1) && (u < SAGA_SEARCH_DIAMETER) && - (v >= 1) && (v < SAGA_SEARCH_DIAMETER) && - ((u != SAGA_SEARCH_CENTER) || (v != SAGA_SEARCH_CENTER))) { - _searchArray.getPathCell(u, v)->visited = 1; - } - } - } - - _queueCount = 0; - pushPoint(SAGA_SEARCH_CENTER, SAGA_SEARCH_CENTER, 0, 0); - - - while (_queueCount > 0) { - - _queueCount--; - tilePoint = *_searchArray.getQueue(_queueCount); - - if (tilePoint.cost > 100 && actor == _vm->_actor->_protagonist) continue; - - dist = ABS(tilePoint.u - uFinish) + ABS(tilePoint.v - vFinish); - - if (dist < bestDistance) { - bestU = tilePoint.u; - bestV = tilePoint.v; - bestDistance = dist; - - if (dist == 0) { - break; - } - } - - testPossibleDirections(uBase + tilePoint.u, vBase + tilePoint.v, terraComp, - (tilePoint.u == SAGA_SEARCH_CENTER && tilePoint.v == SAGA_SEARCH_CENTER)); - - for (dir = 0; dir < 8; dir++) { - terrainMask = terraComp[dir]; - - if (terrainMask & SAGA_IMPASSABLE) { - continue; - } else { - if (terrainMask & (1 << kTerrRough)) { - tdir = &hardDirTable[ dir ]; - } else { - if (terrainMask & (1 << kTerrNone)) { - tdir = &normalDirTable[ dir ]; - } else { - tdir = &easyDirTable[ dir ]; - } - } - } - - - pushPoint(tilePoint.u + tdir->u, tilePoint.v + tdir->v, tilePoint.cost + tdir->cost, dir); - } - } - - res = &_pathDirections[SAGA_MAX_PATH_DIRECTIONS]; - i = 0; - while ((bestU != SAGA_SEARCH_CENTER) || (bestV != SAGA_SEARCH_CENTER)) { - pcell = _searchArray.getPathCell(bestU, bestV); - - *--res = pcell->direction; - i++; - if (i >= SAGA_MAX_PATH_DIRECTIONS) { - break; - } - - dir = (pcell->direction + 4) & 0x07; - - bestU += normalDirTable[dir].u; - bestV += normalDirTable[dir].v; - } - -/* if (i > 64) { - i = 64; - }*/ - actor->_walkStepsCount = i; - if (i) { - actor->setTileDirectionsSize(i, false); - memcpy(actor->_tileDirections, res, i ); - } -} - -void IsoMap::setTileDoorState(int doorNumber, int doorState) { - MultiTileEntryData *multiTileEntryData; - - if ((doorNumber < 0) || (doorNumber >= _multiCount)) { - error("setTileDoorState: doorNumber >= _multiCount"); - } - - multiTileEntryData = &_multiTable[doorNumber]; - multiTileEntryData->currentState = doorState; -} - -static const int16 directions[8][2] = { - { 16, 16}, - { 16, 0}, - { 16, -16}, - { 0, -16}, - { -16, -16}, - { -16, 0}, - { -16, 16}, - { 0, 16} -}; - - - -bool IsoMap::nextTileTarget(ActorData* actor) { - uint16 dir; - - if (actor->_walkStepIndex >= actor->_walkStepsCount) { - return false; - } - - - actor->_actionDirection = dir = actor->_tileDirections[actor->_walkStepIndex++]; - - actor->_partialTarget.u() = - (actor->_location.u() & ~0x0f) + 8 + directions[dir][0]; - - actor->_partialTarget.v() = - (actor->_location.v() & ~0x0f) + 8 + directions[dir][1]; - - - if (dir == 0) { - actor->_facingDirection = kDirUp; - } else { - if (dir == 4) { - actor->_facingDirection = kDirDown; - } else { - if (dir < 4) { - actor->_facingDirection = kDirRight; - } else { - actor->_facingDirection = kDirLeft; - } - } - } - - return true; -} - -void IsoMap::screenPointToTileCoords(const Point &position, Location &location) { - Point mPos(position); - int x,y; - - if (_vm->_scene->currentSceneResourceId() == RID_ITE_OVERMAP_SCENE){ - if (mPos.y < 16) { - mPos.y = 16; - } - } - - x = mPos.x + _viewScroll.x - (128 * SAGA_TILEMAP_W) - 16; - y = mPos.y + _viewScroll.y - (128 * SAGA_TILEMAP_W) + _vm->_actor->_protagonist->_location.z; - - location.u() = (x - y * 2) >> 1; - location.v() = - (x + y * 2) >> 1; - location.z = _vm->_actor->_protagonist->_location.z; -} - -} // End of namespace Saga diff --git a/saga/isomap.h b/saga/isomap.h deleted file mode 100644 index 9264c20fbe..0000000000 --- a/saga/isomap.h +++ /dev/null @@ -1,294 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Isometric level module - private header - -#ifndef SAGA_ISOMAP_H_ -#define SAGA_ISOMAP_H_ - -#include "saga/actor.h" - -namespace Saga { - -#define SAGA_ISOTILEDATA_LEN 8 -#define SAGA_ISOTILE_WIDTH 32 -#define SAGA_ISOTILE_BASEHEIGHT 15 -#define SAGA_TILE_NOMINAL_H 16 -#define SAGA_MAX_TILE_H 64 - -#define SAGA_TILEPLATFORMDATA_LEN 136 -#define SAGA_PLATFORM_W 8 -#define SAGA_MAX_PLATFORM_H 16 - -#define SAGA_TILEMAP_LEN 514 -#define SAGA_TILEMAP_W 16 -#define SAGA_TILEMAP_H 16 - -#define SAGA_METATILEDATA_LEN 36 - -#define SAGA_MULTI_TILE (1 << 15) - -#define SAGA_SCROLL_LIMIT_X1 32 -#define SAGA_SCROLL_LIMIT_X2 64 -#define SAGA_SCROLL_LIMIT_Y1 8 -#define SAGA_SCROLL_LIMIT_Y2 32 - -#define SAGA_DRAGON_SEARCH_CENTER 24 -#define SAGA_DRAGON_SEARCH_DIAMETER (SAGA_DRAGON_SEARCH_CENTER * 2) - -#define SAGA_SEARCH_CENTER 15 -#define SAGA_SEARCH_DIAMETER (SAGA_SEARCH_CENTER * 2) -#define SAGA_SEARCH_QUEUE_SIZE 128 -#define SAGA_IMPASSABLE ((1 << kTerrBlock) | (1 << kTerrWater)) - -#define SAGA_STRAIGHT_NORMAL_COST 4 -#define SAGA_DIAG_NORMAL_COST 6 - -#define SAGA_STRAIGHT_EASY_COST 2 -#define SAGA_DIAG_EASY_COST 3 - -#define SAGA_STRAIGHT_HARD_COST 9 -#define SAGA_DIAG_HARD_COST 10 -#define SAGA_MAX_PATH_DIRECTIONS 256 - -enum TerrainTypes { - kTerrNone = 0, - kTerrPath = 1, - kTerrRough = 2, - kTerrBlock = 3, - kTerrWater = 4, - kTerrLast = 5 -}; - -enum TileMapEdgeType { - kEdgeTypeBlack = 0, - kEdgeTypeFill0 = 1, - kEdgeTypeFill1 = 2, - kEdgeTypeRpt = 3, - kEdgeTypeWrap = 4 -}; - -struct IsoTileData { - byte height; - int8 attributes; - size_t offset; - uint16 terrainMask; - byte FGDBGDAttr; - int8 GetMaskRule() const { - return attributes & 0x0F; - } - byte GetFGDAttr() const { - return FGDBGDAttr >> 4; - } - byte GetBGDAttr() const { - return FGDBGDAttr & 0x0F; - } - uint16 GetFGDMask() const { - return 1 << GetFGDAttr(); - } - uint16 GetBGDMask() const { - return 1 << GetBGDAttr(); - } -}; - -struct TilePlatformData { - int16 metaTile; - int16 height; - int16 highestPixel; - byte vBits; - byte uBits; - int16 tiles[SAGA_PLATFORM_W][SAGA_PLATFORM_W]; -}; - -struct TileMapData { - byte edgeType; - int16 tilePlatforms[SAGA_TILEMAP_W][SAGA_TILEMAP_H]; -}; - -struct MetaTileData { - uint16 highestPlatform; - uint16 highestPixel; - int16 stack[SAGA_MAX_PLATFORM_H]; -}; - -struct MultiTileEntryData { - int16 offset; - byte u; - byte v; - byte h; - byte uSize; - byte vSize; - byte numStates; - byte currentState; -}; - - - - - -class IsoMap { -public: - IsoMap(SagaEngine *vm); - ~IsoMap() { - freeMem(); - } - void loadImages(const byte * resourcePointer, size_t resourceLength); - void loadMap(const byte * resourcePointer, size_t resourceLength); - void loadPlatforms(const byte * resourcePointer, size_t resourceLength); - void loadMetaTiles(const byte * resourcePointer, size_t resourceLength); - void loadMulti(const byte * resourcePointer, size_t resourceLength); - void freeMem(); - void draw(Surface *ds); - void drawSprite(Surface *ds, SpriteList &spriteList, int spriteNumber, const Location &location, const Point &screenPosition, int scale); - void adjustScroll(bool jump); - void tileCoordsToScreenPoint(const Location &location, Point &position) { - position.x = location.u() - location.v() + (128 * SAGA_TILEMAP_W) - _viewScroll.x + 16; - position.y = -(location.uv() >> 1) + (128 * SAGA_TILEMAP_W) - _viewScroll.y - location.z; - } - void screenPointToTileCoords(const Point &position, Location &location); - void placeOnTileMap(const Location &start, Location &result, int16 distance, uint16 direction); - void findDragonTilePath(ActorData* actor, const Location &start, const Location &end, uint16 initialDirection); - bool findNearestChasm(int16 &u0, int16 &v0, uint16 &direction); - void findTilePath(ActorData* actor, const Location &start, const Location &end); - bool nextTileTarget(ActorData* actor); - void setTileDoorState(int doorNumber, int doorState); - Point getMapPosition() { return _mapPosition; } - void setMapPosition(int x, int y); - int16 getTileIndex(int16 u, int16 v, int16 z); - -private: - void drawTiles(Surface *ds, const Location *location); - void drawMetaTile(Surface *ds, uint16 metaTileIndex, const Point &point, int16 absU, int16 absV); - void drawSpriteMetaTile(Surface *ds, uint16 metaTileIndex, const Point &point, Location &location, int16 absU, int16 absV); - void drawPlatform(Surface *ds, uint16 platformIndex, const Point &point, int16 absU, int16 absV, int16 absH); - void drawSpritePlatform(Surface *ds, uint16 platformIndex, const Point &point, const Location &location, int16 absU, int16 absV, int16 absH); - void drawTile(Surface *ds, uint16 tileIndex, const Point &point, const Location *location); - int16 smoothSlide(int16 value, int16 min, int16 max) { - if (value < min) { - if (value < min - 100 || value > min - 4) { - value = min; - } else { - value += 4; - } - } else { - if (value > max) { - if (value > max + 100 || value < max + 4) { - value = max; - } else { - value -= 4; - } - } - } - return value; - } - int16 findMulti(int16 tileIndex, int16 absU, int16 absV, int16 absH); - void pushPoint(int16 u, int16 v, uint16 cost, uint16 direction); - void pushDragonPoint(int16 u, int16 v, uint16 direction); - bool checkDragonPoint(int16 u, int16 v, uint16 direction); - void testPossibleDirections(int16 u, int16 v, uint16 terraComp[8], int skipCenter); - IsoTileData *getTile(int16 u, int16 v, int16 z); - - - byte *_tileData; - size_t _tileDataLength; - uint16 _tilesCount; - IsoTileData *_tilesTable; - - uint16 _tilePlatformsCount; - TilePlatformData *_tilePlatformList; - uint16 _metaTilesCount; - MetaTileData *_metaTileList; - - uint16 _multiCount; - MultiTileEntryData *_multiTable; - uint16 _multiDataCount; - int16 *_multiTableData; - - TileMapData _tileMap; - - Point _mapPosition; - -// path finding stuff - uint16 _platformHeight; - - struct DragonPathCell { - uint8 visited:1,direction:3; - }; - struct DragonTilePoint { - int8 u, v; - uint8 direction:4; - }; - struct PathCell { - uint16 visited:1,direction:3,cost:12; - }; - -public: - struct TilePoint { - int8 u, v; - uint16 direction:4,cost:12; - }; - -private: - struct DragonSearchArray { - DragonPathCell cell[SAGA_DRAGON_SEARCH_DIAMETER][SAGA_DRAGON_SEARCH_DIAMETER]; - DragonTilePoint queue[SAGA_SEARCH_QUEUE_SIZE]; - DragonTilePoint *getQueue(uint16 i) { - assert(i < SAGA_SEARCH_QUEUE_SIZE); - return &queue[i]; - } - DragonPathCell *getPathCell(uint16 u, uint16 v) { - assert((u < SAGA_DRAGON_SEARCH_DIAMETER) && (v < SAGA_DRAGON_SEARCH_DIAMETER)); - return &cell[u][v]; - } - }; - struct SearchArray { - PathCell cell[SAGA_SEARCH_DIAMETER][SAGA_SEARCH_DIAMETER]; - TilePoint queue[SAGA_SEARCH_QUEUE_SIZE]; - TilePoint *getQueue(uint16 i) { - assert(i < SAGA_SEARCH_QUEUE_SIZE); - return &queue[i]; - } - PathCell *getPathCell(uint16 u, uint16 v) { - assert((u < SAGA_SEARCH_DIAMETER) && (v < SAGA_SEARCH_DIAMETER)); - return &cell[u][v]; - } - }; - - int16 _queueCount; - int16 _readCount; - SearchArray _searchArray; - DragonSearchArray _dragonSearchArray; - byte _pathDirections[SAGA_MAX_PATH_DIRECTIONS]; - - - int _viewDiff; - Point _viewScroll; - Rect _tileClip; - - SagaEngine *_vm; -}; - -} // End of namespace Saga - -#endif diff --git a/saga/ite_introproc.cpp b/saga/ite_introproc.cpp deleted file mode 100644 index abe2deb4a5..0000000000 --- a/saga/ite_introproc.cpp +++ /dev/null @@ -1,1028 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - - -// Intro sequence scene procedures - -#include "saga/saga.h" -#include "saga/gfx.h" - -#include "saga/animation.h" -#include "saga/events.h" -#include "saga/font.h" -#include "saga/sndres.h" -#include "saga/palanim.h" -#include "saga/music.h" - -#include "saga/scene.h" -#include "saga/resnames.h" -#include "saga/rscfile.h" - -namespace Saga { - -using Common::UNK_LANG; -using Common::EN_USA; -using Common::DE_DEU; - -LoadSceneParams ITE_IntroList[] = { - {RID_ITE_INTRO_ANIM_SCENE, kLoadByResourceId, NULL, Scene::SC_ITEIntroAnimProc, false, kTransitionNoFade, 0, NO_CHAPTER_CHANGE}, - {RID_ITE_CAVE_SCENE_1, kLoadByResourceId, NULL, Scene::SC_ITEIntroCave1Proc, false, kTransitionFade, 0, NO_CHAPTER_CHANGE}, - {RID_ITE_CAVE_SCENE_2, kLoadByResourceId, NULL, Scene::SC_ITEIntroCave2Proc, false, kTransitionNoFade, 0, NO_CHAPTER_CHANGE}, - {RID_ITE_CAVE_SCENE_3, kLoadByResourceId, NULL, Scene::SC_ITEIntroCave3Proc, false, kTransitionNoFade, 0, NO_CHAPTER_CHANGE}, - {RID_ITE_CAVE_SCENE_4, kLoadByResourceId, NULL, Scene::SC_ITEIntroCave4Proc, false, kTransitionNoFade, 0, NO_CHAPTER_CHANGE}, - {RID_ITE_VALLEY_SCENE, kLoadByResourceId, NULL, Scene::SC_ITEIntroValleyProc, false, kTransitionFade, 0, NO_CHAPTER_CHANGE}, - {RID_ITE_TREEHOUSE_SCENE, kLoadByResourceId, NULL, Scene::SC_ITEIntroTreeHouseProc, false, kTransitionNoFade, 0, NO_CHAPTER_CHANGE}, - {RID_ITE_FAIREPATH_SCENE, kLoadByResourceId, NULL, Scene::SC_ITEIntroFairePathProc, false, kTransitionNoFade, 0, NO_CHAPTER_CHANGE}, - {RID_ITE_FAIRETENT_SCENE, kLoadByResourceId, NULL, Scene::SC_ITEIntroFaireTentProc, false, kTransitionNoFade, 0, NO_CHAPTER_CHANGE} -}; - -int Scene::ITEStartProc() { - size_t scenesCount; - size_t i; - - LoadSceneParams firstScene; - LoadSceneParams tempScene; - - scenesCount = ARRAYSIZE(ITE_IntroList); - - for (i = 0; i < scenesCount; i++) { - tempScene = ITE_IntroList[i]; - tempScene.sceneDescriptor = _vm->_resource->convertResourceId(tempScene.sceneDescriptor); - _vm->_scene->queueScene(&tempScene); - } - - - firstScene.loadFlag = kLoadBySceneNumber; - firstScene.sceneDescriptor = _vm->getStartSceneNumber(); - firstScene.sceneDescription = NULL; - firstScene.sceneSkipTarget = true; - firstScene.sceneProc = NULL; - firstScene.transitionType = kTransitionFade; - firstScene.actorsEntrance = 0; - firstScene.chapter = -1; - - _vm->_scene->queueScene(&firstScene); - - return SUCCESS; -} - -Event *Scene::ITEQueueDialogue(Event *q_event, int n_dialogues, const IntroDialogue dialogue[]) { - TextListEntry textEntry; - TextListEntry *entry; - Event event; - int voice_len; - int i; - - // Queue narrator dialogue list - textEntry.knownColor = kKnownColorSubtitleTextColor; - textEntry.effectKnownColor = kKnownColorTransparent; - textEntry.useRect = true; - textEntry.rect.left = 0; - textEntry.rect.right = _vm->getDisplayWidth(); - textEntry.rect.top = (_vm->getLanguage() == Common::DE_DEU) ? INTRO_DE_CAPTION_Y : INTRO_CAPTION_Y; - textEntry.rect.bottom = _vm->getDisplayHeight(); - textEntry.font = kKnownFontMedium; - textEntry.flags = (FontEffectFlags)(kFontOutline | kFontCentered); - - for (i = 0; i < n_dialogues; i++) { - textEntry.text = dialogue[i].i_str; - entry = _vm->_scene->_textList.addEntry(textEntry); - - // Display text - event.type = kEvTOneshot; - event.code = kTextEvent; - event.op = kEventDisplay; - event.data = entry; - event.time = (i == 0) ? 0 : VOICE_PAD; - - q_event = _vm->_events->chain(q_event, &event); - - // Play voice - event.type = kEvTOneshot; - event.code = kVoiceEvent; - event.op = kEventPlay; - event.param = dialogue[i].i_voice_rn; - event.time = 0; - - q_event = _vm->_events->chain(q_event, &event); - - voice_len = _vm->_sndRes->getVoiceLength(dialogue[i].i_voice_rn); - if (voice_len < 0) { - voice_len = strlen(dialogue[i].i_str) * VOICE_LETTERLEN; - } - - // Remove text - event.type = kEvTOneshot; - event.code = kTextEvent; - event.op = kEventRemove; - event.data = entry; - event.time = voice_len; - - q_event = _vm->_events->chain(q_event, &event); - } - - return q_event; -} - -enum { - kCHeader, - kCText -}; - -enum { - kITEPC = (1 << 0), - kITEPCCD = (1 << 1), - kITEMac = (1 << 2), - kITEWyrmKeep = (1 << 3), - kITEAny = 0xffff, - kITENotWyrmKeep = kITEAny & ~kITEWyrmKeep -}; - -// Queue a page of credits text. The original interpreter did word-wrapping -// automatically. We currently don't. - -Event *Scene::ITEQueueCredits(int delta_time, int duration, int n_credits, const IntroCredit credits[]) { - int game; - Common::Language lang; - - // The assumption here is that all WyrmKeep versions have the same - // credits, regardless of which operating system they're for. - - lang = _vm->getLanguage(); - - if (_vm->getFeatures() & GF_WYRMKEEP) { - game = kITEWyrmKeep; - } else if (_vm->getPlatform() == Common::kPlatformMacintosh) { - game = kITEMac; - } else if (_vm->getGameId() == GID_ITE_CD_G) { - game = kITEPCCD; - } else { - game = kITEPC; - } - - int line_spacing = 0; - int paragraph_spacing; - KnownFont font = kKnownFontSmall; - int i; - - int n_paragraphs = 0; - int credits_height = 0; - - for (i = 0; i < n_credits; i++) { - if (credits[i].lang != lang && credits[i].lang != UNK_LANG) { - continue; - } - - if (!(credits[i].game & game)) { - continue; - } - - switch (credits[i].type) { - case kCHeader: - font = kKnownFontSmall; - line_spacing = 4; - n_paragraphs++; - break; - case kCText: - font = kKnownFontMedium; - line_spacing = 2; - break; - default: - error("Unknown credit type"); - } - - credits_height += (_vm->_font->getHeight(font) + line_spacing); - } - - paragraph_spacing = (200 - credits_height) / (n_paragraphs + 3); - credits_height += (n_paragraphs * paragraph_spacing); - - int y = paragraph_spacing; - - TextListEntry textEntry; - TextListEntry *entry; - Event event; - Event *q_event = NULL; - - textEntry.knownColor = kKnownColorSubtitleTextColor; - textEntry.effectKnownColor = kKnownColorTransparent; - textEntry.flags = (FontEffectFlags)(kFontOutline | kFontCentered); - textEntry.point.x = 160; - - for (i = 0; i < n_credits; i++) { - if (credits[i].lang != lang && credits[i].lang != UNK_LANG) { - continue; - } - - if (!(credits[i].game & game)) { - continue; - } - - switch (credits[i].type) { - case kCHeader: - font = kKnownFontSmall; - line_spacing = 4; - y += paragraph_spacing; - break; - case kCText: - font = kKnownFontMedium; - line_spacing = 2; - break; - default: - break; - } - - textEntry.text = credits[i].string; - textEntry.font = font; - textEntry.point.y = y; - - entry = _vm->_scene->_textList.addEntry(textEntry); - - // Display text - event.type = kEvTOneshot; - event.code = kTextEvent; - event.op = kEventDisplay; - event.data = entry; - event.time = delta_time; - - q_event = _vm->_events->queue(&event); - - // Remove text - event.type = kEvTOneshot; - event.code = kTextEvent; - event.op = kEventRemove; - event.data = entry; - event.time = duration; - - q_event = _vm->_events->chain(q_event, &event); - - y += (_vm->_font->getHeight(font) + line_spacing); - } - - return q_event; -} - -int Scene::SC_ITEIntroAnimProc(int param, void *refCon) { - return ((Scene *)refCon)->ITEIntroAnimProc(param); -} - -// Handles the introductory Dreamer's Guild / NWC logo animation scene. -int Scene::ITEIntroAnimProc(int param) { - Event event; - Event *q_event; - - switch (param) { - case SCENE_BEGIN:{ - // Background for intro scene is the first frame of the - // intro animation; display it and set the palette - event.type = kEvTOneshot; - event.code = kBgEvent; - event.op = kEventDisplay; - event.param = kEvPSetPalette; - event.time = 0; - - q_event = _vm->_events->queue(&event); - - debug(3, "Intro animation procedure started."); - debug(3, "Linking animation resources..."); - - _vm->_anim->setFrameTime(0, ITE_INTRO_FRAMETIME); - - // Link this scene's animation resources for continuous - // playback - int lastAnim; - - if (_vm->getFeatures() & GF_WYRMKEEP) { - if (_vm->getPlatform() == Common::kPlatformMacintosh) { - lastAnim = 3; - } else { - lastAnim = 2; - } - } else { - if (_vm->getPlatform() == Common::kPlatformMacintosh) { - lastAnim = 4; - } else { - lastAnim = 5; - } - } - - for (int i = 0; i < lastAnim; i++) - _vm->_anim->link(i, i+1); - - _vm->_anim->setFlag(lastAnim, ANIM_FLAG_ENDSCENE); - - debug(3, "Beginning animation playback."); - - // Begin the animation - event.type = kEvTOneshot; - event.code = kAnimEvent; - event.op = kEventPlay; - event.param = 0; - event.time = 0; - - q_event = _vm->_events->chain(q_event, &event); - - // Queue intro music playback - event.type = kEvTOneshot; - event.code = kMusicEvent; - event.param = MUSIC_1; - event.param2 = MUSIC_LOOP; - event.op = kEventPlay; - event.time = 0; - - q_event = _vm->_events->chain(q_event, &event); - } - break; - case SCENE_END: - break; - default: - warning("Illegal scene procedure parameter"); - break; - } - - return 0; -} - -int Scene::SC_ITEIntroCave1Proc(int param, void *refCon) { - return ((Scene *)refCon)->ITEIntroCave1Proc(param); -} - -// Handles first introductory cave painting scene -int Scene::ITEIntroCave1Proc(int param) { - Event event; - Event *q_event; - int lang = (_vm->getLanguage() == Common::DE_DEU) ? 1 : 0; - - static const IntroDialogue dialogue[][4] = { - { { // English - RID_CAVE_VOICE_0, - "We see the sky, we see the land, we see the water, " - "and we wonder: Are we the only ones?" - }, - { - RID_CAVE_VOICE_1, - "Long before we came to exist, the humans ruled the " - "Earth." - }, - { - RID_CAVE_VOICE_2, - "They made marvelous things, and moved whole " - "mountains." - }, - { - RID_CAVE_VOICE_3, - "They knew the Secret of Flight, the Secret of " - "Happiness, and other secrets beyond our imagining." - } }, - { { // German - RID_CAVE_VOICE_0, - "Um uns sind der Himmel, das Land und die Seen; und " - "wir fragen uns - sind wir die einzigen?" - }, - { - RID_CAVE_VOICE_1, - "Lange vor unserer Zeit herrschten die Menschen " - "\201ber die Erde." - }, - { - RID_CAVE_VOICE_2, - "Sie taten wundersame Dinge und versetzten ganze " - "Berge." - }, - { - RID_CAVE_VOICE_3, - "Sie kannten das Geheimnis des Fluges, das Geheimnis " - "der Fr\224hlichkeit und andere Geheimnisse, die " - "unsere Vorstellungskraft \201bersteigen." - } } - }; - - int n_dialogues = ARRAYSIZE(dialogue[lang]); - - switch (param) { - case SCENE_BEGIN: - // Begin palette cycling animation for candles - event.type = kEvTOneshot; - event.code = kPalAnimEvent; - event.op = kEventCycleStart; - event.time = 0; - - q_event = _vm->_events->queue(&event); - - // Queue narrator dialogue list - q_event = ITEQueueDialogue(q_event, n_dialogues, dialogue[lang]); - - // End scene after last dialogue over - event.type = kEvTOneshot; - event.code = kSceneEvent; - event.op = kEventEnd; - event.time = VOICE_PAD; - - q_event = _vm->_events->chain(q_event, &event); - break; - case SCENE_END: - break; - - default: - warning("Illegal scene procedure paramater"); - break; - } - - return 0; -} - -int Scene::SC_ITEIntroCave2Proc(int param, void *refCon) { - return ((Scene *)refCon)->ITEIntroCave2Proc(param); -} - -// Handles second introductory cave painting scene -int Scene::ITEIntroCave2Proc(int param) { - Event event; - Event *q_event; - int lang = (_vm->getLanguage() == Common::DE_DEU) ? 1 : 0; - - static const IntroDialogue dialogue[][3] = { - { { // English - RID_CAVE_VOICE_4, - "The humans also knew the Secret of Life, and they " - "used it to give us the Four Great Gifts:" - }, - { - RID_CAVE_VOICE_5, - "Thinking minds, feeling hearts, speaking mouths, and " - "reaching hands." - }, - { - RID_CAVE_VOICE_6, - "We are their children." - } }, - { { // German - RID_CAVE_VOICE_4, - "Au$erdem kannten die Menschen das Geheimnis des " - "Lebens. Und sie nutzten es, um uns die vier gro$en " - "Geschenke zu geben -" - }, - { - RID_CAVE_VOICE_5, - "den denkenden Geist, das f\201hlende Herz, den " - "sprechenden Mund und die greifende Hand." - }, - { - RID_CAVE_VOICE_6, - "Wir sind ihre Kinder." - } } - }; - - int n_dialogues = ARRAYSIZE(dialogue[lang]); - - switch (param) { - case SCENE_BEGIN: - // Start 'dissolve' transition to new scene background - event.type = kEvTContinuous; - event.code = kTransitionEvent; - event.op = kEventDissolve; - event.time = 0; - event.duration = DISSOLVE_DURATION; - - q_event = _vm->_events->queue(&event); - - // Begin palette cycling animation for candles - event.type = kEvTOneshot; - event.code = kPalAnimEvent; - event.op = kEventCycleStart; - event.time = 0; - - q_event = _vm->_events->chain(q_event, &event); - - // Queue narrator dialogue list - q_event = ITEQueueDialogue(q_event, n_dialogues, dialogue[lang]); - - // End scene after last dialogue over - event.type = kEvTOneshot; - event.code = kSceneEvent; - event.op = kEventEnd; - event.time = VOICE_PAD; - - q_event = _vm->_events->chain(q_event, &event); - break; - case SCENE_END: - break; - default: - warning("Illegal scene procedure paramater"); - break; - } - - return 0; -} - -int Scene::SC_ITEIntroCave3Proc(int param, void *refCon) { - return ((Scene *)refCon)->ITEIntroCave3Proc(param); -} - -// Handles third introductory cave painting scene -int Scene::ITEIntroCave3Proc(int param) { - Event event; - Event *q_event; - int lang = (_vm->getLanguage() == Common::DE_DEU) ? 1 : 0; - - static const IntroDialogue dialogue[][3] = { - { { // English - RID_CAVE_VOICE_7, - "They taught us how to use our hands, and how to " - "speak." - }, - { - RID_CAVE_VOICE_8, - "They showed us the joy of using our minds." - }, - { - RID_CAVE_VOICE_9, - "They loved us, and when we were ready, they surely " - "would have given us the Secret of Happiness." - } }, - { { // German - RID_CAVE_VOICE_7, - "Sie lehrten uns zu sprechen und unsere H\204nde zu " - "benutzen." - }, - { - RID_CAVE_VOICE_8, - "Sie zeigten uns die Freude am Denken." - }, - { - RID_CAVE_VOICE_9, - "Sie liebten uns, und w\204ren wir bereit gewesen, " - "h\204tten sie uns sicherlich das Geheimnis der " - "Fr\224hlichkeit offenbart." - } } - }; - - int n_dialogues = ARRAYSIZE(dialogue[lang]); - - switch (param) { - case SCENE_BEGIN: - // Start 'dissolve' transition to new scene background - event.type = kEvTContinuous; - event.code = kTransitionEvent; - event.op = kEventDissolve; - event.time = 0; - event.duration = DISSOLVE_DURATION; - - q_event = _vm->_events->queue(&event); - - // Begin palette cycling animation for candles - event.type = kEvTOneshot; - event.code = kPalAnimEvent; - event.op = kEventCycleStart; - event.time = 0; - - q_event = _vm->_events->chain(q_event, &event); - - // Queue narrator dialogue list - q_event = ITEQueueDialogue(q_event, n_dialogues, dialogue[lang]); - - // End scene after last dialogue over - event.type = kEvTOneshot; - event.code = kSceneEvent; - event.op = kEventEnd; - event.time = VOICE_PAD; - - q_event = _vm->_events->chain(q_event, &event); - break; - case SCENE_END: - break; - default: - warning("Illegal scene procedure paramater"); - break; - } - - return 0; -} - -int Scene::SC_ITEIntroCave4Proc(int param, void *refCon) { - return ((Scene *)refCon)->ITEIntroCave4Proc(param); -} - -// Handles fourth introductory cave painting scene -int Scene::ITEIntroCave4Proc(int param) { - Event event; - Event *q_event; - int lang = (_vm->getLanguage() == Common::DE_DEU) ? 1 : 0; - - static const IntroDialogue dialogue[][4] = { - { { // English - RID_CAVE_VOICE_10, - "And now we see the sky, the land, and the water that " - "we are heirs to, and we wonder: why did they leave?" - }, - { - RID_CAVE_VOICE_11, - "Do they live still, in the stars? In the oceans " - "depths? In the wind?" - }, - { - RID_CAVE_VOICE_12, - "We wonder, was their fate good or evil?" - }, - { - RID_CAVE_VOICE_13, - "And will we also share the same fate one day?" - } }, - { { // German - RID_CAVE_VOICE_10, - "Und nun sehen wir den Himmel, das Land und die " - "Seen - unser Erbe. Und wir fragen uns - warum " - "verschwanden sie?" - }, - { - RID_CAVE_VOICE_11, - "Leben sie noch in den Sternen? In den Tiefen des " - "Ozeans? Im Wind?" - }, - { - RID_CAVE_VOICE_12, - "Wir fragen uns - war ihr Schicksal gut oder b\224se?" - }, - { - RID_CAVE_VOICE_13, - "Und wird uns eines Tages das gleiche Schicksal " - "ereilen?" - } } - }; - - int n_dialogues = ARRAYSIZE(dialogue[lang]); - - switch (param) { - case SCENE_BEGIN: - // Start 'dissolve' transition to new scene background - event.type = kEvTContinuous; - event.code = kTransitionEvent; - event.op = kEventDissolve; - event.time = 0; - event.duration = DISSOLVE_DURATION; - - q_event = _vm->_events->queue(&event); - - // Begin palette cycling animation for candles - event.type = kEvTOneshot; - event.code = kPalAnimEvent; - event.op = kEventCycleStart; - event.time = 0; - - q_event = _vm->_events->chain(q_event, &event); - - // Queue narrator dialogue list - q_event = ITEQueueDialogue(q_event, n_dialogues, dialogue[lang]); - - // End scene after last dialogue over - event.type = kEvTOneshot; - event.code = kSceneEvent; - event.op = kEventEnd; - event.time = VOICE_PAD; - - q_event = _vm->_events->chain(q_event, &event); - break; - case SCENE_END: - break; - default: - warning("Illegal scene procedure paramater"); - break; - } - - return 0; -} - -int Scene::SC_ITEIntroValleyProc(int param, void *refCon) { - return ((Scene *)refCon)->ITEIntroValleyProc(param); -} - -// Handles intro title scene (valley overlook) -int Scene::ITEIntroValleyProc(int param) { - Event event; - Event *q_event; - - static const IntroCredit credits[] = { - {EN_USA, kITEAny, kCHeader, "Producer"}, - {DE_DEU, kITEAny, kCHeader, "Produzent"}, - {UNK_LANG, kITEAny, kCText, "Walter Hochbrueckner"}, - {EN_USA, kITEAny, kCHeader, "Executive Producer"}, - {DE_DEU, kITEAny, kCHeader, "Ausf\201hrender Produzent"}, - {UNK_LANG, kITEAny, kCText, "Robert McNally"}, - {UNK_LANG, kITEWyrmKeep, kCHeader, "2nd Executive Producer"}, - {EN_USA, kITENotWyrmKeep, kCHeader, "Publisher"}, - {DE_DEU, kITENotWyrmKeep, kCHeader, "Herausgeber"}, - {UNK_LANG, kITEAny, kCText, "Jon Van Caneghem"} - }; - - int n_credits = ARRAYSIZE(credits); - - switch (param) { - case SCENE_BEGIN: - // Begin title screen background animation - _vm->_anim->setCycles(0, -1); - - event.type = kEvTOneshot; - event.code = kAnimEvent; - event.op = kEventPlay; - event.param = 0; - event.time = 0; - - q_event = _vm->_events->queue(&event); - - // Begin ITE title theme music - _vm->_music->stop(); - - event.type = kEvTOneshot; - event.code = kMusicEvent; - event.param = MUSIC_2; - event.param2 = MUSIC_NORMAL; - event.op = kEventPlay; - event.time = 0; - - q_event = _vm->_events->chain(q_event, &event); - - // Pause animation before logo - event.type = kEvTOneshot; - event.code = kAnimEvent; - event.op = kEventStop; - event.param = 0; - event.time = 3000; - - q_event = _vm->_events->chain(q_event, &event); - - // Display logo - event.type = kEvTContinuous; - event.code = kTransitionEvent; - event.op = kEventDissolveBGMask; - event.time = 0; - event.duration = LOGO_DISSOLVE_DURATION; - - q_event = _vm->_events->chain(q_event, &event); - - // Remove logo - event.type = kEvTContinuous; - event.code = kTransitionEvent; - event.op = kEventDissolve; - event.time = 3000; - event.duration = LOGO_DISSOLVE_DURATION; - - q_event = _vm->_events->chain(q_event, &event); - - // Unpause animation before logo - event.type = kEvTOneshot; - event.code = kAnimEvent; - event.op = kEventPlay; - event.time = 0; - event.param = 0; - - q_event = _vm->_events->chain(q_event, &event); - - // Queue game credits list - q_event = ITEQueueCredits(9000, CREDIT_DURATION1, n_credits, credits); - - // End scene after credit display - event.type = kEvTOneshot; - event.code = kSceneEvent; - event.op = kEventEnd; - event.time = 1000; - - q_event = _vm->_events->chain(q_event, &event); - break; - case SCENE_END: - break; - default: - warning("Illegal scene procedure parameter"); - break; - } - - return 0; -} - -int Scene::SC_ITEIntroTreeHouseProc(int param, void *refCon) { - return ((Scene *)refCon)->ITEIntroTreeHouseProc(param); -} - -// Handles second intro credit screen (treehouse view) -int Scene::ITEIntroTreeHouseProc(int param) { - Event event; - Event *q_event; - - static const IntroCredit credits1[] = { - {EN_USA, kITEAny, kCHeader, "Game Design"}, - {DE_DEU, kITEAny, kCHeader, "Spielentwurf"}, - {UNK_LANG, kITEAny, kCText, "Talin, Joe Pearce, Robert McNally"}, - {EN_USA, kITEAny, kCText, "and Carolly Hauksdottir"}, - {DE_DEU, kITEAny, kCText, "und Carolly Hauksdottir"}, - {EN_USA, kITEAny, kCHeader, "Screenplay and Dialog"}, - {EN_USA, kITEAny, kCText, "Robert Leh, Len Wein, and Bill Rotsler"}, - {DE_DEU, kITEAny, kCHeader, "Geschichte und Dialoge"}, - {DE_DEU, kITEAny, kCText, "Robert Leh, Len Wein und Bill Rotsler"} - }; - - int n_credits1 = ARRAYSIZE(credits1); - - static const IntroCredit credits2[] = { - {UNK_LANG, kITEWyrmKeep, kCHeader, "Art Direction"}, - {UNK_LANG, kITEWyrmKeep, kCText, "Allison Hershey"}, - {EN_USA, kITEAny, kCHeader, "Art"}, - {DE_DEU, kITEAny, kCHeader, "Grafiken"}, - {UNK_LANG, kITEWyrmKeep, kCText, "Ed Lacabanne, Glenn Price, April Lee,"}, - {UNK_LANG, kITENotWyrmKeep, kCText, "Edward Lacabanne, Glenn Price, April Lee,"}, - {UNK_LANG, kITEWyrmKeep, kCText, "Lisa Sample, Brian Dowrick, Reed Waller,"}, - {EN_USA, kITEWyrmKeep, kCText, "Allison Hershey and Talin"}, - {DE_DEU, kITEWyrmKeep, kCText, "Allison Hershey und Talin"}, - {EN_USA, kITENotWyrmKeep, kCText, "Lisa Iennaco, Brian Dowrick, Reed"}, - {EN_USA, kITENotWyrmKeep, kCText, "Waller, Allison Hershey and Talin"}, - {DE_DEU, kITEAny, kCText, "Waller, Allison Hershey und Talin"}, - {EN_USA, kITENotWyrmKeep, kCHeader, "Art Direction"}, - {DE_DEU, kITENotWyrmKeep, kCHeader, "Grafische Leitung"}, - {UNK_LANG, kITENotWyrmKeep, kCText, "Allison Hershey"} - }; - - int n_credits2 = ARRAYSIZE(credits2); - - switch (param) { - case SCENE_BEGIN: - // Start 'dissolve' transition to new scene background - event.type = kEvTContinuous; - event.code = kTransitionEvent; - event.op = kEventDissolve; - event.time = 0; - event.duration = DISSOLVE_DURATION; - - q_event = _vm->_events->queue(&event); - - if (_vm->_anim->hasAnimation(0)) { - // Begin title screen background animation - _vm->_anim->setFrameTime(0, 100); - - event.type = kEvTOneshot; - event.code = kAnimEvent; - event.op = kEventPlay; - event.param = 0; - event.time = 0; - - q_event = _vm->_events->chain(q_event, &event); - } - - // Queue game credits list - q_event = ITEQueueCredits(DISSOLVE_DURATION + 2000, CREDIT_DURATION1, n_credits1, credits1); - q_event = ITEQueueCredits(DISSOLVE_DURATION + 7000, CREDIT_DURATION1, n_credits2, credits2); - - // End scene after credit display - event.type = kEvTOneshot; - event.code = kSceneEvent; - event.op = kEventEnd; - event.time = 1000; - - q_event = _vm->_events->chain(q_event, &event); - break; - case SCENE_END: - break; - default: - warning("Illegal scene procedure parameter"); - break; - } - - return 0; -} - -int Scene::SC_ITEIntroFairePathProc(int param, void *refCon) { - return ((Scene *)refCon)->ITEIntroFairePathProc(param); -} - -// Handles third intro credit screen (path to puzzle tent) -int Scene::ITEIntroFairePathProc(int param) { - Event event; - Event *q_event; - - static const IntroCredit credits1[] = { - {EN_USA, kITEAny, kCHeader, "Programming"}, - {DE_DEU, kITEAny, kCHeader, "Programmiert von"}, - {UNK_LANG, kITEAny, kCText, "Talin, Walter Hochbrueckner,"}, - {EN_USA, kITEAny, kCText, "Joe Burks and Robert Wiggins"}, - {DE_DEU, kITEAny, kCText, "Joe Burks und Robert Wiggins"}, - {EN_USA, kITEPCCD | kITEWyrmKeep, kCHeader, "Additional Programming"}, - {EN_USA, kITEPCCD | kITEWyrmKeep, kCText, "John Bolton"}, - {UNK_LANG, kITEMac, kCHeader, "Macintosh Version"}, - {UNK_LANG, kITEMac, kCText, "Michael McNally and Robert McNally"}, - {EN_USA, kITEAny, kCHeader, "Music and Sound"}, - {DE_DEU, kITEAny, kCHeader, "Musik und Sound"}, - {UNK_LANG, kITEAny, kCText, "Matt Nathan"} - }; - - int n_credits1 = ARRAYSIZE(credits1); - - static const IntroCredit credits2[] = { - {EN_USA, kITEAny, kCHeader, "Directed by"}, - {DE_DEU, kITEAny, kCHeader, "Regie"}, - {UNK_LANG, kITEAny, kCText, "Talin"} - }; - - int n_credits2 = ARRAYSIZE(credits2); - - switch (param) { - case SCENE_BEGIN: - // Start 'dissolve' transition to new scene background - event.type = kEvTContinuous; - event.code = kTransitionEvent; - event.op = kEventDissolve; - event.time = 0; - event.duration = DISSOLVE_DURATION; - - q_event = _vm->_events->queue(&event); - - // Begin title screen background animation - _vm->_anim->setCycles(0, -1); - - event.type = kEvTOneshot; - event.code = kAnimEvent; - event.op = kEventPlay; - event.param = 0; - event.time = 0; - - q_event = _vm->_events->chain(q_event, &event); - - // Queue game credits list - q_event = ITEQueueCredits(DISSOLVE_DURATION + 2000, CREDIT_DURATION1, n_credits1, credits1); - q_event = ITEQueueCredits(DISSOLVE_DURATION + 7000, CREDIT_DURATION1, n_credits2, credits2); - - // End scene after credit display - event.type = kEvTOneshot; - event.code = kSceneEvent; - event.op = kEventEnd; - event.time = 1000; - - q_event = _vm->_events->chain(q_event, &event); - break; - case SCENE_END: - break; - default: - warning("Illegal scene procedure parameter"); - break; - } - - return 0; -} - -int Scene::SC_ITEIntroFaireTentProc(int param, void *refCon) { - return ((Scene *)refCon)->ITEIntroFaireTentProc(param); -} - -// Handles fourth intro credit screen (treehouse view) -int Scene::ITEIntroFaireTentProc(int param) { - Event event; - Event *q_event; - Event *q_event_start; - - switch (param) { - case SCENE_BEGIN: - - // Start 'dissolve' transition to new scene background - event.type = kEvTContinuous; - event.code = kTransitionEvent; - event.op = kEventDissolve; - event.time = 0; - event.duration = DISSOLVE_DURATION; - - q_event_start = _vm->_events->queue(&event); - - // End scene after momentary pause - event.type = kEvTOneshot; - event.code = kSceneEvent; - event.op = kEventEnd; - event.time = 5000; - q_event = _vm->_events->chain(q_event_start, &event); - break; - case SCENE_END: - break; - default: - warning("Illegal scene procedure parameter"); - break; - } - - return 0; -} - -} // End of namespace Saga diff --git a/saga/itedata.cpp b/saga/itedata.cpp deleted file mode 100644 index 3329ab1bbd..0000000000 --- a/saga/itedata.cpp +++ /dev/null @@ -1,484 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Actor and Object data tables -#include "saga/saga.h" -#include "saga/itedata.h" -#include "saga/resnames.h" -#include "saga/sndres.h" - -namespace Saga { - -ActorTableData ITE_ActorTable[ITE_ACTORCOUNT] = { - // Original used so called permanent actors for first three and that was designed by - // EXTENDED object flag. They contained frames in more than one resource. We use - // different technique here see "Appending to sprite list" in loadActorResources() - -// flags name scene x y z spr frm scp col -// ------------ ---- ---- ---- ----- ---- ---- ---- --- ---- -- -- -- - { kProtagonist | kExtended, - 0, 1, 0, 0, 0, 37, 135, 0, 1, 0, 0, 0}, // map party - // spr and frm numbers taken from permanent actors list - { kFollower | kExtended, - 1, 0, 0, 0, 0, 45, 177, 1, 132, 0, 0, 0}, // Okk - { kFollower | kExtended, - 2, 0, 0, 0, 0, 48, 143, 2, 161, 0, 0, 0}, // Eeah - { 0, 3, 0, 240, 480, 0, 115, 206, 0, 25, 0, 0, 0}, // albino ferret - { 0, 4, 17, 368, 400, 0, 115, 206, 4, 49, 0, 0, 0}, // moneychanger - { 0, 5, 11, 552, 412, 0, 54, 152, 1, 171, 0, 0, 0}, // Sist - { 0, 17, 2, 1192, 888, 0, 57, 153, 17, 49, 0, 0, 0}, // worker ferret 1 - { 0, 17, 2, 816, 1052, 0, 57, 153, 18, 49, 0, 0, 0}, // worker ferret 2 - { 0, 17, 2, 928, 932, 0, 58, 153, 19, 49, 0, 0, 0}, // worker ferret 3 - { 0, 17, 2, 1416, 1160, 0, 58, 153, 20, 49, 0, 0, 0}, // worker ferret 4 - { 0, 19, 49, 1592, 1336, 0, 92, 175, 15, 162, 0, 0, 0}, // faire merchant 1 (bear) - { 0, 20, 49, 744, 824, 0, 63, 156, 19, 112, 0, 4, 4}, // faire merchant 2 (ferret) - { 0, 19, 0, 1592, 1336, 0, 92, 175, 0, 171, 0, 0, 0}, // faire merchant 3 - { 0, 19, 0, 1592, 1336, 0, 92, 175, 0, 171, 0, 0, 0}, // faire merchant 4 - { 0, 9, 49, 1560, 1624, 0, 94, 147, 18, 132, 0, 4, 4}, // faire goer 1a (rat) - { 0, 56, 49, 1384, 792, 0, 95, 193, 20, 72, 0, 0, 0}, // faire goer 1b (otter) - { 0, 19, 0, 1592, 1336, 0, 92, 175, 0, 171, 0, 0, 0}, // faire goer 2a - { 0, 19, 0, 1592, 1336, 0, 92, 175, 0, 171, 0, 0, 0}, // faire goer 2b - { 0, 19, 0, 1592, 1336, 0, 92, 175, 0, 171, 0, 0, 0}, // faire goer 3a - { 0, 19, 0, 1592, 1336, 0, 92, 175, 0, 171, 0, 0, 0}, // faire goer 3b - { 0, 19, 0, 1592, 1336, 0, 92, 175, 0, 171, 0, 0, 0}, // faire goer 4a - { 0, 19, 0, 1592, 1336, 0, 92, 175, 0, 171, 0, 0, 0}, // faire goer 4b - { 0, 18, 32, 764, 448, 0, 55, 150, 0, 48, 10, 4, 4}, // Scorry - { 0, 35, 32, 0, 0, 0, 56, 151, 0, 112, 0, 0, 0}, // grand puzzler - { 0, 36, 32, 0, 0, 0, 105, 142, 0, 155, 0, 0, 0}, // Rhene - { 0, 32, 32, 0, 0, 0, 91, 190, 0, 98, 0, 0, 0}, // elk captain - { 0, 31, 32, 0, 0, 0, 90, 189, 0, 171, 0, 0, 0}, // elk guard 1 - { 0, 31, 32, 0, 0, 0, 90, 189, 0, 171, 0, 0, 0}, // elk guard 2 - { 0, 31, 32, 0, 0, 0, 90, 189, 0, 171, 0, 0, 0}, // elk guard 3 - { 0, 31, 32, 0, 0, 0, 79, 172, 0, 18, 0, 0, 0}, // boar sergeant - { 0, 21, 50, 664, 400, 0, 76, 171, 2, 74, 0, 4, 4}, // boar sentry 1 - { 0, 21, 50, 892, 428, 0, 76, 171, 2, 74, 0, 4, 4}, // boar sentry 2 - { 0, 9, 51, 904, 936, 0, 51, 145, 35, 5, 0, 0, 0}, // hall rat 1 - { 0, 9, 51, 872, 840, 0, 51, 145, 36, 5, 0, 0, 0}, // hall rat 2 - { 0, 9, 51, 1432, 344, 0, 51, 145, 37, 5, 0, 0, 0}, // hall rat 3 - { 0, 9, 51, 664, 472, 0, 51, 145, 38, 5, 0, 0, 0}, // hall rat 4 - { 0, 10, 51, 1368, 1464, 0, 80, 146, 39, 147, 0, 0, 0}, // book rat 1 - { 0, 10, 51, 1416, 1624, 0, 80, 146, 40, 147, 0, 0, 0}, // book rat 2 - { 0, 10, 51, 1752, 120, 0, 80, 146, 41, 147, 0, 0, 0}, // book rat 3 - { 0, 10, 51, 984, 408, 0, 80, 146, 42, 147, 0, 0, 0}, // book rat 4 - { 0, 14, 52, 856, 376, 0, 82, 174, 8, 73, 0, 0, 0}, // grounds servant 1 - { 0, 14, 52, 808, 664, 0, 82, 174, 9, 73, 0, 0, 0}, // grounds servant 2 - { 0, 14, 52, 440, 568, 0, 82, 174, 10, 73, 0, 0, 0}, // grounds servant 3 - { 0, 14, 52, 392, 776, 0, 82, 174, 11, 73, 0, 0, 0}, // grounds servant 4 - { 0, 21, 4, 240, 384, 0, 79, 172, 0, 18, 0, 2, 2}, // boar sentry 3 (by doorway) - { 0, 23, 4, 636, 268, 0, 77, 173, 0, 74, 0, 4, 4}, // boar courtier - { 0, 22, 4, 900, 320, 0, 78, 179, 0, 60, 0, 4, 4}, // boar king - { 0, 14, 4, 788, 264, 0, 75, 170, 0, 171, 0, 2, 2}, // boar servant 1 - { 0, 14, 4, 1088, 264, 0, 75, 170, 0, 171, 0, 6, 6}, // boar servant 2 - { 0, 24, 19, 728, 396, 0, 65, 181, 47, 146, 0, 6, 6}, // glass master - { 0, 24, 21, -20, -20, 0, 66, 182, 0, 146, 0, 4, 4}, // glass master (with orb) - { kCycle, 25, 19, 372, 464, 0, 67, 183, 73, 146, 0, 2, 2}, // glass worker - { 0, 26, 5, 564, 476, 27, 53, 149, 1, 5, 0, 4, 4}, // door rat - { kCycle, 27, 31, 868, 344, 0, 81, 180, 0, 171, 0, 4, 4}, // bees - { 0, 28, 73, 568, 380, 0, 83, 176, 30, 120, 0, 4, 4}, // fortune teller - { 0, 14, 7, 808, 480, 0, 82, 174, 9, 73, 0, 0, 0}, // orb messenger - { 0, 29, 10, 508, 432, 0, 84, 186, 6, 112, 0, 4, 4}, // elk king - { 0, 33, 10, 676, 420, 0, 86, 184, 6, 171, 0, 4, 4}, // elk chancellor - { 0, 30, 10, 388, 452, 0, 88, 185, 6, 171, 0, 4, 4}, // elk courtier 1 - { 0, 30, 10, 608, 444, 0, 89, 185, 6, 171, 0, 4, 4}, // elk courtier 2 - { 0, 31, 10, 192, 468, 0, 90, 189, 6, 171, 0, 4, 4}, // elk throne guard 1 - { 0, 31, 10, 772, 432, 0, 90, 189, 6, 171, 0, 4, 4}, // elk throne guard 2 - { 0, 14, 10, 1340, 444, 0, 87, 188, 6, 171, 0, 4, 4}, // elk servant - { 0, 20, 18, 808, 360, 7, 60, 154, 64, 88, 0, 4, 4}, // hardware ferret - { 0, 34, 49, 1128, 1256, 0, 96, 191, 16, 35, 0, 4, 4}, // porcupine - { 0, 34, 49, 1384, 792, 0, 93, 192, 17, 66, 0, 4, 4}, // faire ram - { 0, 24, 21, 0, -40, 0, 65, 181, 50, 146, 0, 6, 6}, // glass master 2 - { 0, 3, 21, 0, -40, 0, 64, 158, 49, 112, 0, 0, 0}, // Sakka - { 0, 17, 21, 0, -40, 0, 62, 157, 74, 48, 0, 0, 0}, // lodge ferret 1 - { 0, 17, 21, 0, -40, 0, 62, 157, 74, 49, 0, 0, 0}, // lodge ferret 2 - { 0, 17, 21, 0, -40, 0, 62, 157, 74, 50, 0, 0, 0}, // lodge ferret 3 - { 0, 12, 244, 1056, 504, 0, 107, 167, 21, 124, 0, 6, 6}, // Elara - { 0, 8, 33, 248, 440, 0, 68, 169, 14, 112, 0, 0, 0}, // Tycho - { 0, 11, 23, 308, 424, 0, 106, 166, 6, 48, 0, 2, 2}, // Alamma - { 0, 17, 2, 1864, 1336, 0, 58, 153, 21, 49, 0, 0, 0}, // worker ferret 5 - { 0, 17, 2, 760, 216, 0, 58, 153, 22, 49, 0, 0, 0}, // worker ferret 6 - { 0, 44, 29, 0, 0, 0, 72, 159, 0, 112, 0, 0, 0}, // Prince - { 0, 45, 29, 0, 0, 0, 71, 163, 0, 146, 0, 6, 6}, // harem girl 1 - { 0, 45, 29, 0, 0, 0, 71, 163, 0, 124, 0, 2, 2}, // harem girl 2 - { 0, 45, 29, 0, 0, 0, 71, 163, 0, 169, 0, 0, 0}, // harem girl 3 - { 0, 7, 29, 0, 0, 0, 69, 164, 0, 4, 0, 0, 0}, // dog sergeant - { 0, 7, 29, 0, 0, 0, 70, 165, 0, 4, 0, 0, 0}, // throne dog guard 1 - { 0, 7, 257, 552, 408, 0, 70, 165, 0, 4, 0, 2, 2}, // throne dog guard 2 - { 0, 7, 29, 0, 0, 0, 70, 165, 0, 4, 0, 0, 0}, // throne dog guard 3 - { 0, 7, 29, 0, 0, 0, 70, 165, 0, 4, 0, 0, 0}, // throne dog guard 4 - { 0, 7, 257, 712, 380, 0, 69, 164, 0, 4, 0, 4, 4}, // throne dog guard 5 - { 0, 7, 29, 0, 0, 0, 69, 164, 0, 4, 0, 0, 0}, // throne dog guard 6 - { 0, 7, 29, 0, 0, 0, 69, 164, 0, 4, 0, 0, 0}, // throne dog guard 7 - { 0, 7, 29, 0, 0, 0, 69, 164, 0, 4, 0, 0, 0}, // throne dog guard 8 - { 0, 7, 29, 0, 0, 0, 69, 164, 0, 4, 0, 0, 0}, // throne dog guard 9 - { 0, 7, 0, 0, 0, 0, 69, 164, 0, 4, 0, 0, 0}, // throne dog guard 10 - { 0, 7, 29, 0, 0, 0, 70, 165, 0, 4, 0, 0, 0}, // throne dog guard 11 - { 0, 47, 30, 0, 0, 0, 102, 199, 1, 186, 0, 0, 0}, // old wolf ferryman - { 0, 48, 69, 0, 0, 0, 109, 202, 35, 26, 0, 0, 0}, // cat village wildcat - { 0, 49, 69, 0, 0, 0, 109, 202, 35, 26, 0, 0, 0}, // cat village attendant - { 0, 50, 69, 0, 0, 0, 111, 203, 16, 67, 0, 0, 0}, // cat village Prowwa - { 0, 51, 20, 0, 0, 0, 112, 204, 15, 26, 0, 0, 0}, // Prowwa hut Mirrhp - { 0, 50, 20, 0, 0, 0, 111, 203, 14, 67, 0, 0, 0}, // Prowwa hut Prowwa - { 0, 49, 20, 0, 0, 0, 109, 202, 35, 26, 0, 0, 0}, // Prowwa hut attendant - { 0, 48, 256, 0, 0, 0, 109, 202, 35, 26, 0, 0, 0}, // wildcat sentry - { 0, 21, 32, 0, 0, 0, 76, 171, 0, 171, 0, 0, 0}, // boar warrior 1 - { 0, 21, 32, 0, 0, 0, 76, 171, 0, 171, 0, 0, 0}, // boar warrior 2 - { 0, 21, 32, 0, 0, 0, 76, 171, 0, 171, 0, 0, 0}, // boar warrior 3 - { 0, 52, 15, 152, 400, 0, 108, 168, 19, 48, 10, 2, 2}, // Alamma's voice - { 0, 47, 251, 640, 360, 0, 113, 205, 5, 186, 10, 2, 2}, // ferry on ocean - { 0, 41, 75, 152, 400, 0, 100, 197, 5, 81, 0, 0, 0}, // Shiala - { 0, 44, 9, 0, 0, 0, 73, 160, 54, 112, 0, 0, 0}, // Prince (asleep) - { 0, 0, 22, -20, -20, 0, 118, 209, 0, 171, 0, 0, 0}, // Rif and Eeah (at rockslide) - { 0, 1, 22, 0, 0, 0, 119, 210, 0, 171, 0, 0, 0}, // Okk (at rockslide) - { 0, 0, 22, -20, -20, 0, 118, 209, 0, 171, 0, 0, 0}, // Rif and Eeah (at rockslide w. rope) - { 0, 1, 22, 0, 0, 0, 119, 210, 0, 171, 0, 0, 0}, // Okk (at rockslide w. rope) - { 0, 53, 42, 640, 400, 0, 104, 201, 8, 141, 0, 0, 0}, // Kylas Honeyfoot - { 0, 54, 21, -20, -20, 0, 120, 211, 48, 238, 0, 0, 0}, // Orb of Hands - { 0, 0, 4, -20, -20, 0, 42, 140, 0, 1, 0, 0, 0}, // Rif (muddy) - { 0, 26, 5, -20, -20, 27, 52, 148, 1, 5, 0, 4, 4}, // door rat (standing) - { 0, 36, 4, -20, -20, 0, 116, 207, 0, 155, 0, 0, 0}, // boar with Rhene 1 - { 0, 36, 0, -20, -20, 0, 117, 208, 0, 155, 0, 0, 0}, // boar with Rhene 2 - { 0, 46, 252, -20, -20, 0, 74, 162, 29, 34, 0, 0, 0}, // dog jailer - { 0, 0, 32, -20, -20, 0, 41, 137, 0, 1, 0, 0, 0}, // Rif (tourney) - { 0, 0, 259, -20, -20, 0, 44, 138, 0, 1, 0, 0, 0}, // cliff rat - { 0, 0, 5, -20, -20, 0, 43, 139, 0, 1, 0, 0, 0}, // Rif (cloaked) - { 0, 0, 31, -20, -20, 0, 39, 136, 0, 1, 0, 0, 0}, // Rif (oak tree scene) - { 0, 0, 252, -20, -20, 0, 39, 136, 0, 1, 0, 0, 0}, // Rif (jail cell scene) - { 0, 0, 15, -20, -20, 0, 39, 136, 0, 1, 0, 0, 0}, // Rif (outside Alamma's) - { 0, 0, 20, -20, -20, 0, 39, 136, 0, 1, 0, 0, 0}, // Rif (sick tent) - { 0, 0, 25, -20, -20, 0, 39, 136, 0, 1, 0, 0, 0}, // Rif (gem room) - { 0, 0, 272, -20, -20, 0, 40, 141, 0, 1, 0, 0, 0}, // Rif (dragon maze) - { 0, 0, 50, -20, -20, 0, 39, 136, 0, 1, 0, 0, 0}, // Rif (boar entry gate) - { 0, 50, 71, -20, -20, 0, 111, 203, 0, 67, 0, 0, 0}, // Prowwa (dog castle back) - { 0, 50, 274, -20, -20, 0, 111, 203, 0, 67, 0, 0, 0}, // Prowwa (cat festival) - { 0, 50, 274, -20, -20, 0, 110, 212, 0, 171, 0, 0, 0}, // cat festival dancer 1 - { 0, 50, 274, -20, -20, 0, 110, 212, 0, 171, 0, 0, 0}, // cat festival dancer 2 - { 0, 50, 274, -20, -20, 0, 110, 212, 0, 171, 0, 0, 0}, // cat festival dancer 3 - { 0, 57, 272, 909, 909, 48, 121, 213, 0, 171, 0, 0, 0}, // komodo dragon - { 0, 58, 15, -20, -20, 0, 122, 214, 0, 171, 0, 0, 0}, // letter from Elara - { 0, 37, 246, -20, -20, 0, 97, 194, 0, 141, 0, 0, 0}, // Gar (wolves' cage) - { 0, 38, 246, -20, -20, 0, 98, 195, 0, 27, 0, 0, 0}, // Wrah (wolves' cage) - { 0, 59, 246, -20, -20, 0, 103, 200, 0, 26, 0, 0, 0}, // Chota (wolves' cage) - { 0, 41, 245, -20, -20, 0, 100, 197, 0, 81, 0, 0, 0}, // Shiala (wolves' cage) - { 0, 47, 250, 640, 360, 0, 114, 205, 0, 186, 10, 2, 2}, // ferry on ocean - { 0, 0, 278, -20, -20, 0, 40, 141, 0, 1, 0, 0, 0}, // Rif (falling in tunnel trap door) - { 0, 0, 272, -20, -20, 0, 40, 141, 0, 1, 0, 0, 0}, // Rif (falling in dragon maze) - { 0, 41, 77, -20, -20, 0, 100, 197, 24, 81, 0, 0, 0}, // Shiala (grotto) - { 0, 37, 261, -20, -20, 0, 97, 194, 0, 141, 0, 0, 0}, // Gar (ambush) - { 0, 38, 261, -20, -20, 0, 98, 195, 0, 27, 0, 0, 0}, // Wrah (ambush) - { 0, 39, 261, -20, -20, 0, 99, 196, 0, 5, 0, 0, 0}, // dark claw wolf (ambush) - { 0, 39, 261, -20, -20, 0, 99, 196, 0, 5, 0, 0, 0}, // dark claw wolf (ambush) - { 0, 39, 261, -20, -20, 0, 99, 196, 0, 5, 0, 0, 0}, // dark claw wolf (ambush) - { 0, 39, 261, -20, -20, 0, 99, 196, 0, 5, 0, 0, 0}, // dark claw wolf (ambush) - { 0, 59, 279, -20, -20, 0, 103, 200, 0, 26, 0, 0, 0}, // Chota (top of dam) - { 0, 38, 279, -20, -20, 0, 98, 195, 0, 27, 0, 0, 0}, // Wrah (top of dam) - { 0, 42, 77, -20, -20, 0, 101, 198, 25, 171, 0, 0, 0}, // Shiala's spear - { 0, 59, 281, -20, -20, 0, 103, 200, 26, 26, 0, 0, 0}, // Chota (lab) - { 0, 59, 279, -20, -20, 0, 123, 215, 0, 1, 0, 0, 0}, // Rif (finale) - { 0, 59, 279, -20, -20, 0, 123, 215, 0, 132, 0, 0, 0}, // Okk (finale) - { 0, 59, 279, -20, -20, 0, 123, 215, 0, 161, 0, 0, 0}, // Eeah (finale) - { 0, 54, 279, -20, -20, 0, 120, 211, 0, 133, 0, 6, 6}, // Orb of Storms (top of dam) - { 0, 44, 9, -20, -20, 0, 124, 161, 0, 171, 0, 6, 6}, // Prince's snores - { 0, 7, 255, 588, 252, 0, 70, 165, 0, 3, 0, 2, 2}, // hall dog guard 1 - { 0, 7, 255, 696, 252, 0, 70, 165, 0, 5, 0, 6, 6}, // hall dog guard 2 - { 0, 36, 4, 0, 0, 0, 105, 142, 0, 155, 0, 0, 0}, // Rhene - { 0, 44, 272, 1124, 1124, 120, 72, 159, 0, 112, 0, 0, 0}, // Prince (dragon maze) - { 0, 7, 272, 1124, 1108, 120, 70, 165, 0, 4, 0, 0, 0}, // dog heckler 1 (dragon maze) - { 0, 7, 272, 1108, 1124, 120, 70, 165, 0, 4, 0, 0, 0}, // dog heckler 2 (dragon maze) - { 0, 29, 288, 508, 432, 0, 85, 187, 0, 112, 0, 4, 4}, // elk king (finale) - { 0, 29, 0, 508, 432, 0, 84, 186, 0, 99, 0, 4, 4}, // crowd voice 1 (finale) - { 0, 29, 0, 508, 432, 0, 84, 186, 0, 98, 0, 4, 4}, // crowd voice 2 (finale) - { 0, 29, 0, 508, 432, 0, 84, 186, 0, 104, 0, 4, 4}, // crowd voice 3 (finale) - { 0, 29, 0, 508, 432, 0, 84, 186, 0, 99, 0, 4, 4}, // crowd voice 4 (finale) - { 0, 36, 288, 0, 0, 0, 105, 142, 0, 155, 0, 0, 0}, // Rhene (finale) - { 0, 1, 27, -20, -20, 0, 47, 178, 0, 132, 0, 0, 0}, // Okk (temple gate) - { 0, 1, 252, -20, -20, 0, 47, 178, 0, 132, 0, 0, 0}, // Okk (jail cell) - { 0, 1, 25, -20, -20, 0, 47, 178, 0, 132, 0, 0, 0}, // Okk (gem room) - { 0, 1, 259, -20, -20, 0, 47, 178, 0, 132, 0, 0, 0}, // Okk (cliff) - { 0, 1, 279, -20, -20, 0, 47, 178, 0, 132, 0, 0, 0}, // Okk (dam top) - { 0, 1, 273, -20, -20, 0, 47, 178, 0, 132, 0, 0, 0}, // Okk (human ruins) - { 0, 1, 26, -20, -20, 0, 8, 178, 0, 171, 0, 0, 0}, // puzzle pieces - { 0, 1, 0, -20, -20, 0, 0, 0, 0, 50, 0, 0, 0}, // poker dog 1 - { 0, 1, 0, -20, -20, 0, 0, 0, 0, 82, 0, 0, 0}, // poker dog 2 - { 0, 1, 0, -20, -20, 0, 0, 0, 0, 35, 0, 0, 0}, // poker dog 3 - { 0, 9, 74, -20, -20, 0, 51, 145, 0, 5, 0, 0, 0} // sundial rat -}; - - -ObjectTableData ITE_ObjectTable[ITE_OBJECTCOUNT] = { - { 8, 49, 1256, 760, 0, 9, 5, kObjNotFlat }, // Magic Hat - { 9, 52, 1080, 1864, 0, 68, 4, kObjUseWith }, // Berries - { 10, 259, 744, 524, 0, 79, 42, kObjUseWith }, // Card Key - { 11, 0, 480, 480, 0, 69, 6, 0 }, // Foot Print - { 12, 0, 480, 480, 0, 13, 38, kObjUseWith }, // Power Cell - { 13, 28, 640, 412, 40, 14, 15, kObjUseWith }, // Digital Clock - { 14, 0, 480, 480, 0, 15, 41, kObjUseWith }, // Oil Lamp - { 15, 24, 868, 456, 35, 46, 13, kObjUseWith }, // Magnetic Key - { 16, 0, 480, 480, 0, 17, 7, kObjUseWith }, // Plaster - { 17, 249, 320, 476, 45, 18, 44, 0 }, // Trophy - { 18, 0, 480, 480, 0, 19, 20, 0 }, // Coins - { 19, 19, 600, 480, 0, 20, 8, 0 }, // Lens Fragments - { 20, 0, 1012, 568, 80, 44, 10, kObjUseWith }, // Key to jail cell - { 21, 0, 480, 480, 0, 22, 9, 0 }, // Remade lens - { 22, 0, 480, 480, 0, 23, 21, 0 }, // Tycho's Map - { 23, 0, 480, 480, 0, 24, 23, 0 }, // Silver Medallion - { 24, 0, 480, 480, 0, 25, 24, 0 }, // Mud in Fur - { 25, 0, 480, 480, 0, 26, 25, 0 }, // Gold Ring - { 27, 13, 1036, 572, 40, 47, 14, kObjUseWith }, // Screwdriver - { 28, 0, 480, 480, 0, 29, 26, 0 }, // Apple Token - { 29, 0, 480, 480, 0, 30, 22, kObjUseWith }, // Letter from Elara - { 30, 0, 164, 440, 0, 31, 16, kObjUseWith }, // Spoon - { 32, 0, 480, 480, 0, 33, 43, 0 }, // Catnip - { 33, 31, 580, 392, 0, 45, 11, 0 }, // Twigs - { 35, 0, 468, 480, 0, 36, 12, kObjUseWith }, // Empty Bowl (also bowl of honey) - { 37, 0, 480, 480, 0, 38, 45, kObjUseWith }, // Needle and Thread - { 38, 25, 332, 328, 0, 48, 19, 0 }, // Rock Crystal - { 39, 0, 480, 480, 0, 40, 0, kObjUseWith }, // Salve - { 40, 269, 644, 416, 0, 41, 39, kObjNotFlat }, // Electrical Cable - { 41, 12, 280, 516, 0, 43, 17, kObjUseWith }, // Piece of flint - { 42, 5, 876, 332, 32, 65, 18, 0 }, // Rat Cloak - { 43, 52, 556, 1612, 0, 49, 28, kObjUseWith | kObjNotFlat }, // Bucket - { 48, 52, 732, 948, 0, 50, 27, kObjUseWith }, // Cup - { 49, 52, 520, 1872, 0, 53, 29, 0 }, // Fertilizer - { 50, 52, 1012, 1268, 0, 52, 30, 0 }, // Feeder - { 51, 252, -20, -20, 0, 71, 32, kObjUseWith | kObjNotFlat }, // Bowl in jail cell - { 53, 252, 1148, 388, 0, 70, 33, 0 }, // Loose stone block in jail cell - { 26, 12, 496, 368, 0, 76, 31, 0 }, // Coil of Rope from Quarry - { 54, 281, 620, 352, 0, 80, 46, 0 } // Orb of Storms in Dam Lab -}; - -FxTable ITE_SfxTable[ITE_SFXCOUNT] = { - { FX_DOOR_OPEN, 127 }, - { FX_DOOR_CLOSE, 127 }, - { FX_RUSH_WATER, 63 }, // Floppy volume: 127 - { FX_RUSH_WATER, 26 }, // Floppy volume: 40 - { FX_CRICKET, 64 }, - { FX_PORTICULLIS, 84 }, // Floppy volume: 127 - { FX_CLOCK_1, 64 }, - { FX_CLOCK_2, 64 }, - { FX_DAM_MACHINE, 64 }, - { FX_DAM_MACHINE, 40 }, - { FX_HUM1, 64 }, - { FX_HUM2, 64 }, - { FX_HUM3, 64 }, - { FX_HUM4, 64 }, - { FX_WATER_LOOP_S, 32 }, // Floppy volume: 64 - { FX_SURF, 42 }, // Floppy volume: 127 - { FX_SURF, 32 }, // Floppy volume: 64 - { FX_FIRELOOP, 64 }, // Floppy volume: 96 - { FX_SCRAPING, 84 }, // Floppy volume: 127 - { FX_BEE_SWARM, 64 }, // Floppy volume: 96 - { FX_BEE_SWARM, 26 }, // Floppy volume: 40 - { FX_SQUEAKBOARD, 64 }, - { FX_KNOCK, 127 }, - { FX_COINS, 32 }, // Floppy volume: 48 - { FX_STORM, 84 }, // Floppy volume: 127 - { FX_DOOR_CLOSE_2, 84 }, // Floppy volume: 127 - { FX_ARCWELD, 84 }, // Floppy volume: 127 - { FX_RETRACT_ORB, 127 }, - { FX_DRAGON, 127 }, - { FX_SNORES, 127 }, - { FX_SPLASH, 127 }, - { FX_LOBBY_DOOR, 127 }, - { FX_CHIRP_LOOP, 26 }, // Floppy volume: 40 - { FX_DOOR_CREAK, 96 }, - { FX_SPOON_DIG, 64 }, - { FX_CROW, 96 }, - { FX_COLDWIND, 42 }, // Floppy volume: 64 - { FX_TOOL_SND_1, 96 }, - { FX_TOOL_SND_2, 127 }, - { FX_TOOL_SND_3, 64 }, - { FX_DOOR_METAL, 96 }, - { FX_WATER_LOOP_S, 32 }, - { FX_WATER_LOOP_L, 32 }, // Floppy volume: 64 - { FX_DOOR_OPEN_2, 127 }, - { FX_JAIL_DOOR, 64 }, - { FX_KILN_FIRE, 53 }, // Floppy volume: 80 - - // Only in the CD version - { FX_CROWD_01, 64 }, - { FX_CROWD_02, 64 }, - { FX_CROWD_03, 64 }, - { FX_CROWD_04, 64 }, - { FX_CROWD_05, 64 }, - { FX_CROWD_06, 64 }, - { FX_CROWD_07, 64 }, - { FX_CROWD_08, 64 }, - { FX_CROWD_09, 64 }, - { FX_CROWD_10, 64 }, - { FX_CROWD_11, 64 }, - { FX_CROWD_12, 64 }, - { FX_CROWD_13, 64 }, - { FX_CROWD_14, 64 }, - { FX_CROWD_15, 64 }, - { FX_CROWD_16, 64 }, - { FX_CROWD_17, 64 } -}; - -const char *ITEinterfaceTextStrings[][52] = { - { - "Walk to", "Look At", "Pick Up", "Talk to", "Open", - "Close", "Use", "Give", "Options", "Test", - "Demo", "Help", "Quit Game", "Fast", "Slow", - "On", "Off", "Continue Playing", "Load", "Save", - "Game Options", "Reading Speed", "Music", "Sound", "Cancel", - "Quit", "OK", "Mid", "Click", "10%", - "20%", "30%", "40%", "50%", "60%", - "70%", "80%", "90%", "Max", "Quit the Game?", - "Load Successful!", "Enter Save Game Name", "Give %s to %s", "Use %s with %s", - "[New Save Game]", - "I can't pick that up.", - "I see nothing special about it.", - "There's no place to open it.", - "There's no opening to close.", - "I don't know how to do that.", - "Show Dialog", - "What is Rif's reply?" - }, - // German - { - "Gehe zu", "Schau an", "Nimm", "Rede mit", "\231ffne", - "Schlie$e", "Benutze", "Gib", "Optionen", "Test", - "Demo", "Hilfe", "Spiel beenden", "S", "L", - "An", "Aus", "Weiterspielen", "Laden", "Sichern", - "Spieleoptionen", "Lesegeschw.", "Musik", "Sound", "Abbr.", - "Beenden", NULL, "M", "Klick", "10%", - "20%", "30%", "40%", "50%", "60%", - "70%", "80%", "90%", "Max", "Spiel beenden?", - "Spielstand geladen!", "Bitte Namen eingeben", "Gib %s zu %s", "Benutze %s mit %s", - "[Neuer Spielstand]", - "Das kann ich nicht aufnehmen.", - "Ich sehe nichts besonderes.", - "Das kann man nicht \224ffnen.", - "Hier ist keine \231ffnung zum Schlie$en.", - "Ich wei$ nicht, wie ich das machen soll.", - "Text zeigen", - "Wie lautet die Antwort?" - } -}; - -Point pieceOrigins[PUZZLE_PIECES] = { - Point(268, 18), - Point(270, 51), - Point( 19, 51), - Point( 73, 0), - Point( 0, 34), - Point(215, 0), - Point(159, 0), - Point( 9, 69), - Point(288, 18), - Point(112, 0), - Point( 27, 88), - Point( 43, 0), - Point( 0, 0), - Point(262, 0), - Point(271, 103) -}; - -const char *pieceNames[][PUZZLE_PIECES] = { - { "screwdriver", "pliers", "c-clamp", "wood clamp", "level", - "twine", "wood plane", "claw hammer", "tape measure", "hatchet", - "shears", "ruler", "saw", "mallet", "paint brush" - }, - { "Schraubendreher", "Zange", "Schraubzwinge", "Holzzwinge", "Wasserwaage", - "Bindfaden", "Hobel", "Schusterhammer", "Bandma$", "Beil", - "Schere", "Winkel", "S\204ge", "Hammer", "Pinsel" - } -}; - -const char *hintStr[][4] = { - { "Check which pieces could fit in each corner first.", - "Check which corner has the least number of pieces that can fit and start from there.", - "Check each new corner and any new side for pieces that fit.", - "I don't see anything out of place." - }, - { "\232berpr\201fe zun\204chst, welche die Eckteile sein k\224nnten.", - "Schau, in welche Ecke die wenigsten Teile passen, und fang dort an.", - "Untersuche jede Ecke und jede Seite auf Teile, die dort passen k\224nnen.", - "Ich sehe nichts an der falschen Stelle." - } -}; - -const char *solicitStr[][NUM_SOLICIT_REPLIES] = { - { "Hey, Fox! Would you like a hint?", - "Would you like some help?", - "Umm...Umm...", - "Psst! want a hint?", - "I would have done this differently, you know." - }, - { "Hey, Fuchs! Brauchst Du \047nen Tip?", - "M\224chtest Du etwas Hilfe?" - "\231hm...\216hm..." - "Psst! \047n Tip vielleicht?" - "Ja, wei$t Du... ich h\204tte das anders gemacht." - } -}; - -const char portraitList[] = { - RID_ITE_JFERRET_SERIOUS, - RID_ITE_JFERRET_GOOFY, - RID_ITE_JFERRET_SERIOUS, - RID_ITE_JFERRET_GOOFY, - RID_ITE_JFERRET_ALOOF -}; - -const char *sakkaStr[][NUM_SAKKA] = { - { "Hey, you're not supposed to help the applicants!", - "Guys! This is supposed to be a test!", - "C'mon fellows, that's not in the rules!" - }, - { "Hey, Du darfst dem Pr\201fling nicht helfen!", - "Hallo?! Dies soll eine Pr\201fung sein!", - "Also, Jungs. Schummeln steht nicht in den Regeln!" - } -}; - -const char *whineStr[][NUM_WHINES] = { - { "Aww, c'mon Sakka!", - "One hint won't hurt, will it?", - "Sigh...", - "I think that clipboard has gone to your head, Sakka!", - "Well, I don't recall any specific rule against hinting." - }, - { "Och, sei nicht so, Sakka!" - "EIN Tip wird schon nicht schaden, oder?", - "Seufz..." - "Ich glaube, Du hast ein Brett vor dem Kopf, Sakka!", - "Hm, ich kann mich an keine Regel erinnern, die Tips verbietet." - } -}; - -const char *optionsStr[][4] = { - { "\"I'll do this puzzle later.\"", - "\"Yes, I'd like a hint please.\"", - "\"No, thank you, I'd like to try and solve it myself.\"", - "I think the %s is in the wrong place." - }, - { "\"Ich l\224se das Puzzle sp\204ter.\"", - "\"Ja, ich m\224chte einen Tip, bitte.\"", - "\"Nein danke, ich m\224chte das alleine l\224sen.\"", - "Pssst... %s... falsche Stelle..." - } -}; - -} // End of namespace Saga diff --git a/saga/itedata.h b/saga/itedata.h deleted file mode 100644 index 45d045356d..0000000000 --- a/saga/itedata.h +++ /dev/null @@ -1,113 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Actor data table header file - -#ifndef SAGA_ITEDATA_H -#define SAGA_ITEDATA_H - -namespace Saga { - -enum ActorFlags { - kProtagonist = 0x01, // Actor is protagonist - kFollower = 0x02, // Actor is follower - kCycle = 0x04, // Actor stand has a cycle - kFaster = 0x08, // Actor is fast - kFastest = 0x10, // Actor is faster - kExtended = 0x20 // Actor uses extended sprites -}; - -// TODO: This doesn't quite correspond to the original Actor struct, so I'm not -// sure if I got it right. - -struct ActorTableData { - byte flags; - byte nameIndex; - int32 sceneIndex; - int16 x; - int16 y; - int16 z; - int32 spriteListResourceId; - int32 frameListResourceId; - byte scriptEntrypointNumber; - byte speechColor; - byte currentAction; - byte facingDirection; - byte actionDirection; -}; - -#define ITE_ACTORCOUNT 181 - -extern ActorTableData ITE_ActorTable[ITE_ACTORCOUNT]; - -enum { - kObjUseWith = 0x01, - kObjNotFlat = 0x02 -}; - -struct ObjectTableData { - byte nameIndex; - int32 sceneIndex; - int16 x; - int16 y; - int16 z; - int32 spriteListResourceId; - byte scriptEntrypointNumber; - uint16 interactBits; -}; - -struct FxTable { - int res; - int vol; -}; - -#define ITE_OBJECTCOUNT 39 -#define ITE_SFXCOUNT 63 - -extern ObjectTableData ITE_ObjectTable[ITE_OBJECTCOUNT]; -extern FxTable ITE_SfxTable[ITE_SFXCOUNT]; - -extern const char *ITEinterfaceTextStrings[][52]; - -#define PUZZLE_PIECES 15 - -extern Point pieceOrigins[PUZZLE_PIECES]; -extern const char *pieceNames[][PUZZLE_PIECES]; - -#define NUM_SOLICIT_REPLIES 5 -extern const char *solicitStr[][NUM_SOLICIT_REPLIES]; - -#define NUM_SAKKA 3 -extern const char *sakkaStr[][NUM_SAKKA]; - -#define NUM_WHINES 5 -extern const char *whineStr[][NUM_WHINES]; - -extern const char *hintStr[][4]; -extern const char portraitList[]; -extern const char *optionsStr[][4]; - -} // End of namespace Saga - -#endif diff --git a/saga/list.h b/saga/list.h deleted file mode 100644 index d002f405de..0000000000 --- a/saga/list.h +++ /dev/null @@ -1,156 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-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$ - * - */ - -#ifndef SAGA_LIST_H__ -#define SAGA_LIST_H__ - -#include "common/list.h" - -namespace Saga { - -template <class T> -class SortedList : public Common::List<T> { -public: - typedef int (*CompareFunction) (const T& a, const T& b); - - typedef typename Common::List<T>::iterator iterator; - typedef typename Common::List<T>::const_iterator const_iterator; - typedef typename Common::List<T> Common_List; - -public: - - iterator pushFront(const T& element) { - return insert(Common::List<T>::begin(), element); - } - - iterator pushBack(const T& element) { - return insert(Common_List::end(), element); - } - - iterator insert(iterator pos, const T& element) { - Common_List::insert(pos, element); - return --pos; - } - - iterator pushFront() { - return insert(Common_List::begin()); - } - - iterator pushBack() { - return insert(Common_List::end()); - } - - iterator insert(iterator pos) { - T init; - return insert(pos, init); - } - - iterator pushFront(const T& element, CompareFunction compareFunction) { - return insert(Common::List<T>::begin(), element, compareFunction); - } - - iterator pushBack(const T& element, CompareFunction compareFunction) { - return insert(Common_List::end(), element, compareFunction); - } - - iterator insert(iterator pos, const T& element, CompareFunction compareFunction) { - int res; - - for (iterator i = Common_List::begin(); i != Common_List::end(); ++i) { - res = compareFunction(element, i.operator*()); - if (res < 0) { - return insert(i, element); - } - } - return pushBack(element); - } - - iterator reorderUp(iterator pos, CompareFunction compareFunction) { - iterator i(pos); - int res; - - --i; - while (i != Common::List<T>::end()) { - res = compareFunction(i.operator*(), pos.operator*()); - if (res <= 0) { - - T temp(*pos); - erase(pos); - ++i; - return insert(i, temp); - } - --i; - } - return pos; - } - - iterator reorderDown(iterator pos, CompareFunction compareFunction) { - iterator i(pos); - int res; - - ++i; - while (i != Common::List<T>::end()) { - res = compareFunction(i.operator*(), pos.operator*()); - if (res >= 0) { - - T temp(*pos); - erase(pos); - return insert(i, temp); - } - ++i; - } - return pos; - } - - iterator eraseAndPrev(iterator pos) { - assert(pos != Common_List::end()); - iterator res(pos); - - --res; - erase(pos); - return res; - } - - void remove(const T* val) { - for (iterator i = Common_List::begin(); i != Common_List::end(); ++i) - if (val == i.operator->()) { - erase(i); - return; - } - } - - bool locate(const T* val, iterator& foundedIterator) { - - for (iterator i = Common::List<T>::begin(); i != Common::List<T>::end(); ++i) - if (val == i.operator->()) - { - foundedIterator = i; - return true; - } - - return false; - } -}; - -} // End of namespace Saga - -#endif diff --git a/saga/module.mk b/saga/module.mk deleted file mode 100644 index 0f648fea48..0000000000 --- a/saga/module.mk +++ /dev/null @@ -1,44 +0,0 @@ -MODULE := saga - -MODULE_OBJS := \ - saga/actor.o \ - saga/animation.o \ - saga/console.o \ - saga/events.o \ - saga/font.o \ - saga/font_map.o \ - saga/game.o \ - saga/gfx.o \ - saga/ihnm_introproc.o \ - saga/image.o \ - saga/interface.o \ - saga/isomap.o \ - saga/ite_introproc.o \ - saga/itedata.o \ - saga/objectmap.o \ - saga/puzzle.o \ - saga/palanim.o \ - saga/render.o \ - saga/rscfile.o \ - saga/saga.o \ - saga/saveload.o \ - saga/scene.o \ - saga/script.o \ - saga/sfuncs.o \ - saga/sndres.o \ - saga/sprite.o \ - saga/sthread.o \ - saga/input.o \ - saga/music.o \ - saga/sound.o - -MODULE_DIRS += \ - saga - -# This module can be built as a plugin -ifdef BUILD_PLUGINS -PLUGIN := 1 -endif - -# Include common rules -include $(srcdir)/common.rules diff --git a/saga/music.cpp b/saga/music.cpp deleted file mode 100644 index e352818ee6..0000000000 --- a/saga/music.cpp +++ /dev/null @@ -1,524 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ -#include "saga/saga.h" - -#include "saga/rscfile.h" -#include "saga/music.h" -#include "saga/stream.h" -#include "sound/audiostream.h" -#include "sound/mididrv.h" -#include "sound/midiparser.h" -#include "sound/mp3.h" -#include "sound/vorbis.h" -#include "sound/flac.h" -#include "common/config-manager.h" -#include "common/file.h" - -namespace Saga { - -#define BUFFER_SIZE 4096 - -struct TrackFormat { - DigitalTrackInfo* (*openTrackFunction)(int); -}; - -static const TrackFormat TRACK_FORMATS[] = { -#ifdef USE_FLAC - { getFlacTrack }, -#endif -#ifdef USE_VORBIS - { getVorbisTrack }, -#endif -#ifdef USE_MAD - { getMP3Track }, -#endif - - { NULL } // Terminator -}; - -// I haven't decided yet if it's a good idea to make looping part of the audio -// stream class, or if I should use a "wrapper" class, like I did for Broken -// Sword 2, to make it easier to add support for compressed music... but I'll -// worry about that later. - -class RAWInputStream : public AudioStream { -private: - ResourceContext *_context; - Common::File *_file; - uint32 _filePos; - uint32 _startPos; - uint32 _endPos; - bool _finished; - bool _looping; - int16 _buf[BUFFER_SIZE]; - const int16 *_bufferEnd; - const int16 *_pos; - const GameSoundInfo *_musicInfo; - - void refill(); - bool eosIntern() const { - return _pos >= _bufferEnd; - } - -public: - RAWInputStream(SagaEngine *vm, ResourceContext *context, uint32 resourceId, bool looping); - - int readBuffer(int16 *buffer, const int numSamples); - - bool endOfData() const { return eosIntern(); } - bool isStereo() const { return _musicInfo->stereo; } - int getRate() const { return _musicInfo->frequency; } -}; - -RAWInputStream::RAWInputStream(SagaEngine *vm, ResourceContext *context, uint32 resourceId, bool looping) - : _context(context), _finished(false), _looping(looping), _bufferEnd(_buf + BUFFER_SIZE) { - - ResourceData * resourceData; - - resourceData = vm->_resource->getResourceData(context, resourceId); - _file = context->getFile(resourceData); - _musicInfo = vm->getMusicInfo(); - - if (_musicInfo == NULL) { - error("RAWInputStream() wrong musicInfo"); - } - - // Determine the end position - _startPos = resourceData->offset; - _endPos = _startPos + resourceData->size; - _filePos = _startPos; - - // Read in initial data - refill(); -} - -int RAWInputStream::readBuffer(int16 *buffer, const int numSamples) { - int samples = 0; - while (samples < numSamples && !eosIntern()) { - const int len = MIN(numSamples - samples, (int) (_bufferEnd - _pos)); - memcpy(buffer, _pos, len * 2); - buffer += len; - _pos += len; - samples += len; - if (_pos >= _bufferEnd) { - refill(); - } - } - return samples; -} - -void RAWInputStream::refill() { - if (_finished) - return; - - uint32 lengthLeft; - byte *ptr = (byte *) _buf; - - - _file->seek(_filePos, SEEK_SET); - - if (_looping) - lengthLeft = 2 * BUFFER_SIZE; - else - lengthLeft = MIN((uint32) (2 * BUFFER_SIZE), _endPos - _filePos); - - while (lengthLeft > 0) { - uint32 len = _file->read(ptr, MIN(lengthLeft, _endPos - _file->pos())); - - if (len & 1) - len--; - -#ifdef SCUMM_BIG_ENDIAN - if (!_context->isBigEndian) { -#else - if (_context->isBigEndian) { -#endif - uint16 *ptr16 = (uint16 *)ptr; - for (uint32 i = 0; i < (len / 2); i++) - ptr16[i] = SWAP_BYTES_16(ptr16[i]); - } - - lengthLeft -= len; - ptr += len; - - if (lengthLeft > 0) - _file->seek(_startPos); - } - - _filePos = _file->pos(); - _pos = _buf; - _bufferEnd = (int16 *)ptr; - - if (!_looping && _filePos >= _endPos) { - _finished = true; - } -} - - -MusicPlayer::MusicPlayer(MidiDriver *driver) : _parser(0), _driver(driver), _looping(false), _isPlaying(false), _passThrough(false), _isGM(false) { - memset(_channel, 0, sizeof(_channel)); - _masterVolume = 0; - this->open(); -} - -MusicPlayer::~MusicPlayer() { - _driver->setTimerCallback(NULL, NULL); - stopMusic(); - this->close(); -} - -void MusicPlayer::setVolume(int volume) { - if (volume < 0) - volume = 0; - else if (volume > 255) - volume = 255; - - if (_masterVolume == volume) - return; - - _masterVolume = volume; - - for (int i = 0; i < 16; ++i) { - if (_channel[i]) { - _channel[i]->volume(_channelVolume[i] * _masterVolume / 255); - } - } -} - -int MusicPlayer::open() { - // Don't ever call open without first setting the output driver! - if (!_driver) - return 255; - - int ret = _driver->open(); - if (ret) - return ret; - - _driver->setTimerCallback(this, &onTimer); - return 0; -} - -void MusicPlayer::close() { - stopMusic(); - if (_driver) - _driver->close(); - _driver = 0; -} - -void MusicPlayer::send(uint32 b) { - if (_passThrough) { - _driver->send(b); - return; - } - - byte channel = (byte)(b & 0x0F); - if ((b & 0xFFF0) == 0x07B0) { - // Adjust volume changes by master volume - byte volume = (byte)((b >> 16) & 0x7F); - _channelVolume[channel] = volume; - volume = volume * _masterVolume / 255; - b = (b & 0xFF00FFFF) | (volume << 16); - } else if ((b & 0xF0) == 0xC0 && !_isGM && !_nativeMT32) { - b = (b & 0xFFFF00FF) | MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8; - } - else if ((b & 0xFFF0) == 0x007BB0) { - //Only respond to All Notes Off if this channel - //has currently been allocated - if (_channel[b & 0x0F]) - return; - } - - if (!_channel[channel]) - _channel[channel] = (channel == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel(); - - if (_channel[channel]) - _channel[channel]->send(b); -} - -void MusicPlayer::metaEvent(byte type, byte *data, uint16 length) { - // FIXME: The "elkfanfare" is played much too quickly. There are some - // meta events that we don't handle. Perhaps there is a - // connection...? - - switch (type) { - case 0x2F: // End of Track - if (_looping) - _parser->jumpToTick(0); - else - stopMusic(); - break; - default: - //warning("Unhandled meta event: %02x", type); - break; - } -} - -void MusicPlayer::onTimer(void *refCon) { - MusicPlayer *music = (MusicPlayer *)refCon; - if (music->_isPlaying) - music->_parser->onTimer(); -} - -void MusicPlayer::playMusic() { - _isPlaying = true; -} - -void MusicPlayer::stopMusic() { - _isPlaying = false; - if (_parser) { - _parser->unloadMusic(); - _parser = NULL; - } -} - -Music::Music(SagaEngine *vm, Audio::Mixer *mixer, MidiDriver *driver, int enabled) : _vm(vm), _mixer(mixer), _enabled(enabled), _adlib(false) { - _player = new MusicPlayer(driver); - _currentVolume = 0; - - xmidiParser = MidiParser::createParser_XMIDI(); - smfParser = MidiParser::createParser_SMF(); - - _musicContext = _vm->_resource->getContext(GAME_MUSICFILE); - - _songTableLen = 0; - _songTable = 0; - - _track = NULL; -} - -Music::~Music() { - _mixer->stopHandle(_musicHandle); - delete _player; - xmidiParser->setMidiDriver(NULL); - smfParser->setMidiDriver(NULL); - delete xmidiParser; - delete smfParser; - - free(_songTable); -} - -void Music::musicVolumeGaugeCallback(void *refCon) { - ((Music *)refCon)->musicVolumeGauge(); -} - -void Music::musicVolumeGauge() { - int volume; - - _currentVolumePercent += 10; - - if (_currentVolume - _targetVolume > 0) { // Volume decrease - volume = _targetVolume + (_currentVolume - _targetVolume) * (100 - _currentVolumePercent) / 100; - } else { - volume = _currentVolume + (_targetVolume - _currentVolume) * _currentVolumePercent / 100; - } - - if (volume < 0) - volume = 1; - - _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, volume); - _player->setVolume(volume); - - if (_currentVolumePercent == 100) { - Common::g_timer->removeTimerProc(&musicVolumeGaugeCallback); - _currentVolume = _targetVolume; - } -} - -void Music::setVolume(int volume, int time) { - _targetVolume = volume * 2; // ScummVM has different volume scale - _currentVolumePercent = 0; - - if (volume == -1) // Set Full volume - volume = 255; - - if (time == 1) { - _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, volume); - _player->setVolume(volume); - Common::g_timer->removeTimerProc(&musicVolumeGaugeCallback); - _currentVolume = volume; - return; - } - - Common::g_timer->installTimerProc(&musicVolumeGaugeCallback, time * 100L, this); -} - -bool Music::isPlaying() { - return _mixer->isSoundHandleActive(_musicHandle) || _player->isPlaying(); -} - -void Music::play(uint32 resourceId, MusicFlags flags) { - AudioStream *audioStream = NULL; - MidiParser *parser; - ResourceContext *context; - byte *resourceData; - size_t resourceSize; - - debug(2, "Music::play %d, %d", resourceId, flags); - - if (!_enabled) { - return; - } - - if (isPlaying() && _trackNumber == resourceId) { - return; - } - - _trackNumber = resourceId; - _player->stopMusic(); - _mixer->stopHandle(_musicHandle); - - int realTrackNumber; - - if (_vm->getGameType() == GType_ITE) { - if (flags == MUSIC_DEFAULT) { - if (resourceId == 13 || resourceId == 19) { - flags = MUSIC_NORMAL; - } else { - flags = MUSIC_LOOP; - } - } - realTrackNumber = resourceId - 8; - } else { - realTrackNumber = resourceId + 1; - } - - // Try to open standalone digital track - for (int i = 0; i < ARRAYSIZE(TRACK_FORMATS) - 1; ++i) - if ((_track = TRACK_FORMATS[i].openTrackFunction(realTrackNumber))) { - break; - } - if (_track) { - _track->play(_mixer, &_musicHandle, (flags == MUSIC_LOOP) ? -1 : 1, 10000); - return; - } - - if (_vm->getGameType() == GType_ITE) { - if (resourceId >= 9 && resourceId <= 34) { - if (_musicContext != NULL) { - //TODO: check resource size - audioStream = new RAWInputStream(_vm, _musicContext, resourceId - 9, flags == MUSIC_LOOP); - } - } - } - - if (audioStream) { - debug(2, "Playing digitized music"); - _mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_musicHandle, audioStream); - return; - } - - if (flags == MUSIC_DEFAULT) { - flags = MUSIC_NORMAL; - } - - // FIXME: Is resource_data ever freed? - // Load MIDI/XMI resource data - - if (_vm->getGameType() == GType_ITE) { - context = _vm->_resource->getContext(GAME_MUSICFILE_GM); - if (context == NULL) { - context = _vm->_resource->getContext(GAME_RESOURCEFILE); - } - } else { - // I've listened to music from both the FM and the GM - // file, and I've tentatively reached the conclusion - // that they are both General MIDI. My guess is that - // the FM file has been reorchestrated to sound better - // on Adlib and other FM synths. - // - // Sev says the Adlib music does not sound like in the - // original, but I still think assuming General MIDI is - // the right thing to do. Some music, like the End - // Title (song 0) sound absolutely atrocious when piped - // through our MT-32 to GM mapping. - // - // It is, however, quite possible that the original - // used a different GM to FM mapping. If the original - // sounded markedly better, perhaps we should add some - // way of replacing our stock mapping in adlib.cpp? - // - // For the composer's own recording of the End Title, - // see http://www.johnottman.com/ - - // Oddly enough, the intro music (song 1) is very - // different in the two files. I have no idea why. - - if (hasAdlib()) { - context = _vm->_resource->getContext(GAME_MUSICFILE_FM); - } else { - context = _vm->_resource->getContext(GAME_MUSICFILE_GM); - } - } - - _player->setGM(true); - - _vm->_resource->loadResource(context, resourceId, resourceData, resourceSize); - - if (resourceSize < 4) { - error("Music::play() wrong music resource size"); - } - - if (xmidiParser->loadMusic(resourceData, resourceSize)) { - if (_vm->getGameType() == GType_ITE) - _player->setGM(false); - - parser = xmidiParser; - } else { - if (smfParser->loadMusic(resourceData, resourceSize)) { - parser = smfParser; - } else { - error("Music::play() wrong music resource"); - } - } - - parser->setTrack(0); - parser->setMidiDriver(_player); - parser->setTimerRate(_player->getBaseTempo()); - parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1); - - _player->_parser = parser; - _player->setVolume(_vm->_musicVolume == 10 ? 255 : _vm->_musicVolume * 25); - - if (flags & MUSIC_LOOP) - _player->setLoop(true); - else - _player->setLoop(false); - - _player->playMusic(); -} - -void Music::pause(void) { - //TODO: do it -} - -void Music::resume(void) { - //TODO: do it} -} - -void Music::stop(void) { - //TODO: do it -} - -} // End of namespace Saga - diff --git a/saga/music.h b/saga/music.h deleted file mode 100644 index 377a5bf1d8..0000000000 --- a/saga/music.h +++ /dev/null @@ -1,148 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Music class - -#ifndef SAGA_MUSIC_H_ -#define SAGA_MUSIC_H_ - -#include "sound/audiocd.h" -#include "sound/mididrv.h" -#include "sound/midiparser.h" - -namespace Saga { - -enum MusicFlags { - MUSIC_NORMAL = 0, - MUSIC_LOOP = 0x0001, - MUSIC_DEFAULT = 0xffff -}; - -class MusicPlayer : public MidiDriver { -public: - MusicPlayer(MidiDriver *driver); - ~MusicPlayer(); - - bool isPlaying() { return _isPlaying; } - - void setVolume(int volume); - int getVolume() { return _masterVolume; } - - void setNativeMT32(bool b) { _nativeMT32 = b; } - bool hasNativeMT32() { return _nativeMT32; } - void playMusic(); - void stopMusic(); - void setLoop(bool loop) { _looping = loop; } - void setPassThrough(bool b) { _passThrough = b; } - - void setGM(bool isGM) { _isGM = isGM; } - - //MidiDriver interface implementation - int open(); - void close(); - void send(uint32 b); - - void metaEvent(byte type, byte *data, uint16 length); - - void setTimerCallback(void *timerParam, void (*timerProc)(void *)) { } - uint32 getBaseTempo(void) { return _driver ? _driver->getBaseTempo() : 0; } - - //Channel allocation functions - MidiChannel *allocateChannel() { return 0; } - MidiChannel *getPercussionChannel() { return 0; } - - MidiParser *_parser; - -protected: - - static void onTimer(void *data); - - MidiChannel *_channel[16]; - MidiDriver *_driver; - byte _channelVolume[16]; - bool _nativeMT32; - bool _isGM; - bool _passThrough; - - bool _isPlaying; - bool _looping; - bool _randomLoop; - byte _masterVolume; - - byte *_musicData; - uint16 *_buf; - uint32 _musicDataSize; -}; - -class Music { -public: - - Music(SagaEngine *vm, Audio::Mixer *mixer, MidiDriver *driver, int enabled); - ~Music(void); - void setNativeMT32(bool b) { _player->setNativeMT32(b); } - bool hasNativeMT32() { return _player->hasNativeMT32(); } - void setAdlib(bool b) { _adlib = b; } - bool hasAdlib() { return _adlib; } - void setPassThrough(bool b) { _player->setPassThrough(b); } - bool isPlaying(void); - - void play(uint32 resourceId, MusicFlags flags = MUSIC_DEFAULT); - void pause(void); - void resume(void); - void stop(void); - - void setVolume(int volume, int time = 1); - int getVolume() { return _currentVolume; } - - int32 *_songTable; - int _songTableLen; - -private: - SagaEngine *_vm; - Audio::Mixer *_mixer; - - MusicPlayer *_player; - Audio::SoundHandle _musicHandle; - uint32 _trackNumber; - - int _enabled; - bool _adlib; - - int _targetVolume; - int _currentVolume; - int _currentVolumePercent; - - ResourceContext *_musicContext; - MidiParser *xmidiParser; - MidiParser *smfParser; - - DigitalTrackInfo *_track; - - static void musicVolumeGaugeCallback(void *refCon); - void musicVolumeGauge(void); -}; - -} // End of namespace Saga - -#endif diff --git a/saga/objectmap.cpp b/saga/objectmap.cpp deleted file mode 100644 index d0a302b0d7..0000000000 --- a/saga/objectmap.cpp +++ /dev/null @@ -1,267 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Object map / Object click-area module - -// Polygon Hit Test code ( HitTestPoly() ) adapted from code (C) Eric Haines -// appearing in Graphics Gems IV, "Point in Polygon Strategies." -// p. 24-46, code: p. 34-45 -#include "saga/saga.h" - -#include "saga/gfx.h" -#include "saga/console.h" -#include "saga/font.h" -#include "saga/interface.h" -#include "saga/objectmap.h" -#include "saga/stream.h" -#include "saga/actor.h" -#include "saga/scene.h" -#include "saga/isomap.h" - -namespace Saga { - -HitZone::HitZone(MemoryReadStreamEndian *readStream, int index): _index(index) { - int i, j; - HitZone::ClickArea *clickArea; - Point *point; - - _flags = readStream->readByte(); - _clickAreasCount = readStream->readByte(); - _rightButtonVerb = readStream->readByte(); - readStream->readByte(); // pad - _nameIndex = readStream->readUint16(); - _scriptNumber = readStream->readUint16(); - - _clickAreas = (HitZone::ClickArea *)malloc(_clickAreasCount * sizeof(*_clickAreas)); - - if (_clickAreas == NULL) { - memoryError("HitZone::HitZone"); - } - - for (i = 0; i < _clickAreasCount; i++) { - clickArea = &_clickAreas[i]; - clickArea->pointsCount = readStream->readUint16LE(); - - assert(clickArea->pointsCount); - - clickArea->points = (Point *)malloc(clickArea->pointsCount * sizeof(*(clickArea->points))); - if (clickArea->points == NULL) { - memoryError("HitZone::HitZone"); - } - - for (j = 0; j < clickArea->pointsCount; j++) { - point = &clickArea->points[j]; - point->x = readStream->readSint16(); - point->y = readStream->readSint16(); - } - } -} - -HitZone::~HitZone() { - for (int i = 0; i < _clickAreasCount; i++) { - free(_clickAreas[i].points); - } - free(_clickAreas); -} - -bool HitZone::getSpecialPoint(Point &specialPoint) const { - int i, pointsCount; - HitZone::ClickArea *clickArea; - Point *points; - - for (i = 0; i < _clickAreasCount; i++) { - clickArea = &_clickAreas[i]; - pointsCount = clickArea->pointsCount; - points = clickArea->points; - if (pointsCount == 1) { - specialPoint = points[0]; - return true; - } - } - return false; -} -bool HitZone::hitTest(const Point &testPoint) { - int i, pointsCount; - HitZone::ClickArea *clickArea; - Point *points; - - if (_flags & kHitZoneEnabled) { - for (i = 0; i < _clickAreasCount; i++) { - clickArea = &_clickAreas[i]; - pointsCount = clickArea->pointsCount; - points = clickArea->points; - - if (pointsCount == 2) { - // Hit-test a box region - if ((testPoint.x >= points[0].x) && - (testPoint.x <= points[1].x) && - (testPoint.y >= points[0].y) && - (testPoint.y <= points[1].y)) { - return true; - } - } else { - if (pointsCount > 2) { - // Hit-test a polygon - if (hitTestPoly(points, pointsCount, testPoint)) { - return true; - } - } - } - } - } - return false; -} - -void HitZone::draw(SagaEngine *vm, Surface *ds, int color) { - int i, pointsCount, j; - Location location; - HitZone::ClickArea *clickArea; - Point *points; - for (i = 0; i < _clickAreasCount; i++) { - clickArea = &_clickAreas[i]; - pointsCount = clickArea->pointsCount; - if (vm->_scene->getFlags() & kSceneFlagISO) { - points = (Point*)malloc(sizeof(Point) * pointsCount); - for (j = 0; j < pointsCount; j++) { - location.u() = clickArea->points[j].x; - location.v() = clickArea->points[j].y; - location.z = 0; - vm->_isoMap->tileCoordsToScreenPoint(location, points[j]); - } - } else { - points = clickArea->points; - } - - if (pointsCount == 2) { - // 2 points represent a box - ds->drawFrame(points[0], points[1], color); - } else { - if (pointsCount > 2) { - // Otherwise draw a polyline - ds->drawPolyLine(points, pointsCount, color); - } - } - if (vm->_scene->getFlags() & kSceneFlagISO) { - free(points); - } - - } -} - - -// Loads an object map resource ( objects ( clickareas ( points ) ) ) -void ObjectMap::load(const byte *resourcePointer, size_t resourceLength) { - int i; - - if (resourceLength == 0) { - return; - } - - if (resourceLength < 4) { - error("ObjectMap::load wrong resourceLength"); - } - - MemoryReadStreamEndian readS(resourcePointer, resourceLength, _vm->isBigEndian()); - - _hitZoneListCount = readS.readSint16(); - if (_hitZoneListCount < 0) { - error("ObjectMap::load _hitZoneListCount < 0"); - } - - if (_hitZoneList) - error("ObjectMap::load _hitZoneList != NULL"); - - _hitZoneList = (HitZone **) malloc(_hitZoneListCount * sizeof(HitZone *)); - if (_hitZoneList == NULL) { - memoryError("ObjectMap::load"); - } - - for (i = 0; i < _hitZoneListCount; i++) { - _hitZoneList[i] = new HitZone(&readS, i); - } -} - -void ObjectMap::freeMem() { - int i; - - if (_hitZoneList) { - for (i = 0; i < _hitZoneListCount; i++) { - delete _hitZoneList[i]; - } - - free(_hitZoneList); - _hitZoneList = NULL; - } - _hitZoneListCount = 0; -} - - - -void ObjectMap::draw(Surface *ds, const Point& testPoint, int color, int color2) { - int i; - int hitZoneIndex; - char txtBuf[32]; - Point pickPoint; - Point textPoint; - Location pickLocation; - pickPoint = testPoint; - if (_vm->_scene->getFlags() & kSceneFlagISO) { - assert(_vm->_actor->_protagonist); - pickPoint.y -= _vm->_actor->_protagonist->_location.z; - _vm->_isoMap->screenPointToTileCoords(pickPoint, pickLocation); - pickLocation.toScreenPointUV(pickPoint); - } - - hitZoneIndex = hitTest(pickPoint); - - for (i = 0; i < _hitZoneListCount; i++) { - _hitZoneList[i]->draw(_vm, ds, (hitZoneIndex == i) ? color2 : color); - } - - if (hitZoneIndex != -1) { - snprintf(txtBuf, sizeof(txtBuf), "hitZone %d", hitZoneIndex); - textPoint.x = 2; - textPoint.y = 2; - _vm->_font->textDraw(kKnownFontSmall, ds, txtBuf, textPoint, kITEColorBrightWhite, kITEColorBlack, kFontOutline); - } -} - -int ObjectMap::hitTest(const Point& testPoint) { - int i; - - // Loop through all scene objects - for (i = 0; i < _hitZoneListCount; i++) { - if (_hitZoneList[i]->hitTest(testPoint)) { - return i; - } - } - - return -1; -} - -void ObjectMap::cmdInfo(void) { - _vm->_console->DebugPrintf("%d zone(s) loaded.\n\n", _hitZoneListCount); -} - -} // End of namespace Saga diff --git a/saga/objectmap.h b/saga/objectmap.h deleted file mode 100644 index 43356d3579..0000000000 --- a/saga/objectmap.h +++ /dev/null @@ -1,128 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Object map / Object click-area module header file - -#ifndef SAGA_OBJECTMAP_H_ -#define SAGA_OBJECTMAP_H_ - -#include "saga/stream.h" - -namespace Saga { - - -class HitZone { -private: - struct ClickArea { - int pointsCount; - Point *points; - }; - -public: - HitZone(MemoryReadStreamEndian *readStream, int index); - ~HitZone(); - - int getNameIndex() const { - return _nameIndex; - } - int getSceneNumber() const { - return _nameIndex; - } - int getActorsEntrance() const { - return _scriptNumber; - } - int getScriptNumber() const { - return _scriptNumber; - } - int getRightButtonVerb() const { - return _rightButtonVerb; - } - int getFlags() const { - return _flags; - } - void setFlag(HitZoneFlags flag) { - _flags |= flag; - } - void clearFlag(HitZoneFlags flag) { - _flags &= ~flag; - } - int getDirection() const { - return ((_flags >> 4) & 0xF); - } - uint16 getHitZoneId() const { - return objectIndexToId(kGameObjectHitZone, _index); - } - uint16 getStepZoneId() const { - return objectIndexToId(kGameObjectStepZone, _index); - } - bool getSpecialPoint(Point &specialPoint) const; - void draw(SagaEngine *vm, Surface *ds, int color); - bool hitTest(const Point &testPoint); - -private: - int _flags; // Saga::HitZoneFlags - int _clickAreasCount; - int _rightButtonVerb; - int _nameIndex; - int _scriptNumber; - int _index; - - ClickArea *_clickAreas; -}; - - -class ObjectMap { -public: - ObjectMap(SagaEngine *vm) : _vm(vm) { - _hitZoneList = NULL; - _hitZoneListCount = 0; - - } - ~ObjectMap(void) { - freeMem(); - } - void load(const byte *resourcePointer, size_t resourceLength); - void freeMem(void); - - void draw(Surface *drawSurface, const Point& testPoint, int color, int color2); - int hitTest(const Point& testPoint); - HitZone *getHitZone(int16 index) { - if ((index < 0) || (index >= _hitZoneListCount)) { - error("ObjectMap::getHitZone wrong index 0x%X", index); - } - return _hitZoneList[index]; - } - - void cmdInfo(void); - -private: - SagaEngine *_vm; - - int _hitZoneListCount; - HitZone **_hitZoneList; -}; - -} // End of namespace Saga - -#endif diff --git a/saga/palanim.cpp b/saga/palanim.cpp deleted file mode 100644 index 4cfaf5e0fd..0000000000 --- a/saga/palanim.cpp +++ /dev/null @@ -1,209 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Palette animation module -#include "saga/saga.h" -#include "saga/gfx.h" - -#include "saga/events.h" - -#include "saga/palanim.h" -#include "saga/stream.h" - -namespace Saga { - -PalAnim::PalAnim(SagaEngine *vm) : _vm(vm) { - _loaded = false; - _entryCount = 0; - _entries = NULL; -} - -PalAnim::~PalAnim(void) { -} - -int PalAnim::loadPalAnim(const byte *resdata, size_t resdata_len) { - void *test_p; - - uint16 i; - - if (_loaded) { - freePalAnim(); - } - - if (resdata == NULL) { - return FAILURE; - } - - MemoryReadStreamEndian readS(resdata, resdata_len, _vm->isBigEndian()); - - if (_vm->getGameType() == GType_IHNM) { - return SUCCESS; - } - - _entryCount = readS.readUint16(); - - debug(3, "PalAnim::loadPalAnim(): Loading %d PALANIM entries.", _entryCount); - - test_p = calloc(_entryCount, sizeof(PalanimEntry)); - if (test_p == NULL) { - warning("PalAnim::loadPalAnim(): Allocation failure"); - return MEM; - } - - _entries = (PalanimEntry *)test_p; - - for (i = 0; i < _entryCount; i++) { - int color_count; - int pal_count; - int p, c; - - color_count = readS.readUint16(); - pal_count = readS.readUint16(); - - _entries[i].pal_count = pal_count; - _entries[i].color_count = color_count; - - debug(2, "PalAnim::loadPalAnim(): Entry %d: Loading %d palette indices.\n", i, pal_count); - - test_p = calloc(1, sizeof(char) * pal_count); - if (test_p == NULL) { - warning("PalAnim::loadPalAnim(): Allocation failure"); - return MEM; - } - - _entries[i].pal_index = (byte *)test_p; - - debug(2, "PalAnim::loadPalAnim(): Entry %d: Loading %d SAGA_COLOR structures.", i, color_count); - - test_p = calloc(1, sizeof(Color) * color_count); - if (test_p == NULL) { - warning("PalAnim::loadPalAnim(): Allocation failure"); - return MEM; - } - - _entries[i].colors = (Color *)test_p; - - for (p = 0; p < pal_count; p++) { - _entries[i].pal_index[p] = readS.readByte(); - } - - for (c = 0; c < color_count; c++) { - _entries[i].colors[c].red = readS.readByte(); - _entries[i].colors[c].green = readS.readByte(); - _entries[i].colors[c].blue = readS.readByte(); - } - } - - _loaded = true; - return SUCCESS; -} - -int PalAnim::cycleStart() { - Event event; - - if (!_loaded) { - return FAILURE; - } - - event.type = kEvTOneshot; - event.code = kPalAnimEvent; - event.op = kEventCycleStep; - event.time = PALANIM_CYCLETIME; - - _vm->_events->queue(&event); - - return SUCCESS; -} - -int PalAnim::cycleStep(int vectortime) { - static PalEntry pal[256]; - uint16 pal_index; - uint16 col_index; - - uint16 i, j; - uint16 cycle; - uint16 cycle_limit; - - Event event; - - if (!_loaded) { - return FAILURE; - } - - _vm->_gfx->getCurrentPal(pal); - - for (i = 0; i < _entryCount; i++) { - cycle = _entries[i].cycle; - cycle_limit = _entries[i].color_count; - for (j = 0; j < _entries[i].pal_count; j++) { - pal_index = (unsigned char)_entries[i].pal_index[j]; - col_index = (cycle + j) % cycle_limit; - pal[pal_index].red = (byte) _entries[i].colors[col_index].red; - pal[pal_index].green = (byte) _entries[i].colors[col_index].green; - pal[pal_index].blue = (byte) _entries[i].colors[col_index].blue; - } - - _entries[i].cycle++; - - if (_entries[i].cycle == cycle_limit) { - _entries[i].cycle = 0; - } - } - - _vm->_gfx->setPalette(pal); - - event.type = kEvTOneshot; - event.code = kPalAnimEvent; - event.op = kEventCycleStep; - event.time = vectortime + PALANIM_CYCLETIME; - - _vm->_events->queue(&event); - - return SUCCESS; -} - -int PalAnim::freePalAnim() { - uint16 i; - - if (!_loaded) { - return FAILURE; - } - - for (i = 0; i < _entryCount; i++) { - debug(2, "PalAnim::freePalAnim(): Entry %d: Freeing colors.", i); - free(_entries[i].colors); - debug(2, "PalAnim::freePalAnim(): Entry %d: Freeing indices.", i); - free(_entries[i].pal_index); - } - - debug(3, "PalAnim::freePalAnim(): Freeing entries."); - - free(_entries); - - _loaded = false; - - return SUCCESS; -} - -} // End of namespace Saga diff --git a/saga/palanim.h b/saga/palanim.h deleted file mode 100644 index e2ca695eb6..0000000000 --- a/saga/palanim.h +++ /dev/null @@ -1,63 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Palette animation module header file - -#ifndef SAGA_PALANIM_H -#define SAGA_PALANIM_H - -namespace Saga { - -#define PALANIM_CYCLETIME 100 - -struct PalanimEntry { - uint16 pal_count; - uint16 color_count; - uint16 cycle; - byte *pal_index; - Color *colors; -}; - -class PalAnim { - public: - PalAnim(SagaEngine *vm); - ~PalAnim(void); - - int loadPalAnim(const byte *, size_t); - int cycleStart(); - int cycleStep(int vectortime); - int freePalAnim(); - - private: - SagaEngine *_vm; - - bool _loaded; - uint16 _entryCount; - PalanimEntry *_entries; -}; - -} // End of namespace Saga - -#endif - diff --git a/saga/puzzle.cpp b/saga/puzzle.cpp deleted file mode 100644 index c09a9c0462..0000000000 --- a/saga/puzzle.cpp +++ /dev/null @@ -1,560 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2005-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$ - * - */ - -#include "saga/saga.h" - -#include "saga/actor.h" -#include "saga/interface.h" -#include "saga/scene.h" -#include "saga/sprite.h" -#include "saga/puzzle.h" -#include "saga/render.h" -#include "saga/resnames.h" - -#include "common/system.h" -#include "common/timer.h" - -namespace Saga { - -#define PUZZLE_X_OFFSET 72 -#define PUZZLE_Y_OFFSET 46 - -#define PUZZLE_FIT 0x01 // 1 when in correct position -#define PUZZLE_MOVED 0x04 // 1 when somewhere in the box -#define PUZZLE_ALL_SET PUZZLE_FIT | PUZZLE_MOVED - - -enum rifOptions { - kROLater = 0, - kROAccept = 1, - kRODecline = 2, - kROHint = 3 -}; - -Puzzle::Puzzle(SagaEngine *vm) : _vm(vm), _solved(false), _active(false) { - _lang = (_vm->getLanguage() == Common::DE_DEU) ? 1 : 0; - - _hintRqState = kRQNoHint; - _hintOffer = 0; - _hintCount = 0; - _helpCount = 0; - _puzzlePiece = -1; - _newPuzzle = true; - _sliding = false; - _hintBox.left = 70; - _hintBox.top = 105; - _hintBox.setWidth(240); - _hintBox.setHeight(30); - - initPieceInfo( 0, 268, 18, 0, 0, 0 + PUZZLE_X_OFFSET, 0 + PUZZLE_Y_OFFSET, 0, 3, - Point(0, 1), Point(0, 62), Point(15, 31), Point(0, 0), Point(0, 0), Point(0,0)); - initPieceInfo( 1, 270, 52, 0, 0, 0 + PUZZLE_X_OFFSET, 32 + PUZZLE_Y_OFFSET, 0, 4, - Point(0, 31), Point(0, 47), Point(39, 47), Point(15, 1), Point(0, 0), Point(0, 0)); - initPieceInfo( 2, 19, 51, 0, 0, 0 + PUZZLE_X_OFFSET, 0 + PUZZLE_Y_OFFSET, 0, 4, - Point(0, 0), Point(23, 46), Point(39, 15), Point(31, 0), Point(0, 0), Point(0, 0)); - initPieceInfo( 3, 73, 0, 0, 0, 32 + PUZZLE_X_OFFSET, 0 + PUZZLE_Y_OFFSET, 0, 6, - Point(0, 0), Point(8, 16), Point(0, 31), Point(31, 31), Point(39, 15), Point(31, 0)); - initPieceInfo( 4, 0, 35, 0, 0, 64 + PUZZLE_X_OFFSET, 16 + PUZZLE_Y_OFFSET, 0, 4, - Point(0, 15), Point(15, 46), Point(23, 32), Point(7, 1), Point(0, 0), Point(0, 0)); - initPieceInfo( 5, 215, 0, 0, 0, 24 + PUZZLE_X_OFFSET, 32 + PUZZLE_Y_OFFSET, 0, 6, - Point(0, 15), Point(8, 31), Point(39, 31), Point(47, 16), Point(39, 0), Point(8, 0)); - initPieceInfo( 6, 159, 0, 0, 0, 32 + PUZZLE_X_OFFSET, 48 + PUZZLE_Y_OFFSET, 0, 5, - Point(0, 16), Point(8, 31), Point(55, 31), Point(39, 1), Point(32, 15), Point(0, 0)); - initPieceInfo( 7, 9, 70, 0, 0, 80 + PUZZLE_X_OFFSET, 32 + PUZZLE_Y_OFFSET, 0, 5, - Point(0, 31), Point(8, 47), Point(23, 47), Point(31, 31), Point(15, 1), Point(0, 0)); - initPieceInfo( 8, 288, 18, 0, 0, 96 + PUZZLE_X_OFFSET, 0 + PUZZLE_Y_OFFSET, 0, 4, - Point(0, 31), Point(15, 62), Point(31, 32), Point(15, 1), Point(0, 0), Point(0, 0)); - initPieceInfo( 9, 112, 0, 0, 0, 112 + PUZZLE_X_OFFSET, 0 + PUZZLE_Y_OFFSET, 0, 4, - Point(0, 0), Point(16, 31), Point(47, 31), Point(31, 0), Point(0, 0), Point(0, 0)); - initPieceInfo(10, 27, 89, 0, 0, 104 + PUZZLE_X_OFFSET, 32 + PUZZLE_Y_OFFSET, 0, 4, - Point(0, 47), Point(31, 47), Point(31, 0), Point(24, 0), Point(0, 0), Point(0, 0)); - initPieceInfo(11, 43, 0, 0, 0, 136 + PUZZLE_X_OFFSET, 32 + PUZZLE_Y_OFFSET, 0, 6, - Point(0, 0), Point(0, 47), Point(15, 47), Point(15, 15), Point(31, 15), Point(23, 0)); - initPieceInfo(12, 0, 0, 0, 0, 144 + PUZZLE_X_OFFSET, 0 + PUZZLE_Y_OFFSET, 0, 4, - Point(0, 0), Point(24, 47), Point(39, 47), Point(39, 0), Point(0, 0), Point(0, 0)); - initPieceInfo(13, 262, 0, 0, 0, 64 + PUZZLE_X_OFFSET, 0 + PUZZLE_Y_OFFSET, 0, 3, - Point(0, 0), Point(23, 46), Point(47, 0), Point(0, 0), Point(0, 0), Point(0, 0)); - initPieceInfo(14, 271, 103, 0, 0, 152 + PUZZLE_X_OFFSET, 48 + PUZZLE_Y_OFFSET, 0, 4, - Point(0, 0), Point(0, 31), Point(31, 31), Point(31, 0), Point(0, 0), Point(0, 0)); -} - -void Puzzle::initPieceInfo(int i, int16 curX, int16 curY, byte offX, byte offY, int16 trgX, - int16 trgY, uint8 flag, uint8 count, Point point0, Point point1, - Point point2, Point point3, Point point4, Point point5) { - _pieceInfo[i].curX = curX; - _pieceInfo[i].curY = curY; - _pieceInfo[i].offX = offX; - _pieceInfo[i].offY = offY; - _pieceInfo[i].trgX = trgX; - _pieceInfo[i].trgY = trgY; - _pieceInfo[i].flag = flag; - _pieceInfo[i].count = count; - _pieceInfo[i].point[0] = point0; - _pieceInfo[i].point[1] = point1; - _pieceInfo[i].point[2] = point2; - _pieceInfo[i].point[3] = point3; - _pieceInfo[i].point[4] = point4; - _pieceInfo[i].point[5] = point5; -} - - -void Puzzle::execute(void) { - _active = true; - Common::g_timer->installTimerProc(&hintTimerCallback, kPuzzleHintTime, this); - - initPieces(); - - showPieces(); - - _vm->_interface->setMode(kPanelConverse); - clearHint(); - //_solved = true; // Cheat - //exitPuzzle(); -} - -void Puzzle::exitPuzzle(void) { - _active = false; - - Common::g_timer->removeTimerProc(&hintTimerCallback); - - _vm->_scene->changeScene(ITE_SCENE_LODGE, 0, kTransitionNoFade); - _vm->_interface->setMode(kPanelMain); -} - -void Puzzle::initPieces(void) { - SpriteInfo *spI; - ActorData *puzzle = _vm->_actor->getActor(_vm->_actor->actorIndexToId(ITE_ACTOR_PUZZLE)); - int frameNumber; - SpriteList *spriteList; - _vm->_actor->getSpriteParams(puzzle, frameNumber, spriteList); - - for (int i = 0; i < PUZZLE_PIECES; i++) { - spI = &(spriteList->infoList[i]); - _pieceInfo[i].offX = (byte)(spI->width >> 1); - _pieceInfo[i].offY = (byte)(spI->height >> 1); - - if (_newPuzzle) { - _pieceInfo[i].curX = pieceOrigins[i].x; - _pieceInfo[i].curY = pieceOrigins[i].y; - } - _piecePriority[i] = i; - } - _newPuzzle = false; -} - -void Puzzle::showPieces(void) { - ActorData *puzzle = _vm->_actor->getActor(_vm->_actor->actorIndexToId(ITE_ACTOR_PUZZLE)); - int frameNumber; - SpriteList *spriteList; - Surface *backBuffer = _vm->_gfx->getBackBuffer(); - _vm->_actor->getSpriteParams(puzzle, frameNumber, spriteList); - - for (int j = PUZZLE_PIECES - 1 ; j >= 0; j--) { - int num = _piecePriority[j]; - - if (_puzzlePiece != num) { - _vm->_sprite->draw(backBuffer, _vm->getDisplayClip(), *spriteList, num, Point(_pieceInfo[num].curX, _pieceInfo[num].curY), 256); - } - } -} - -void Puzzle::drawCurrentPiece() { - ActorData *puzzle = _vm->_actor->getActor(_vm->_actor->actorIndexToId(ITE_ACTOR_PUZZLE)); - Surface *backBuffer = _vm->_gfx->getBackBuffer(); - int frameNumber; - SpriteList *spriteList; - _vm->_actor->getSpriteParams(puzzle, frameNumber, spriteList); - - _vm->_sprite->draw(backBuffer, _vm->_scene->getSceneClip(), *spriteList, _puzzlePiece, - Point(_pieceInfo[_puzzlePiece].curX, _pieceInfo[_puzzlePiece].curY), 256); -} - -void Puzzle::movePiece(Point mousePt) { - int newx, newy; - - showPieces(); - - if (_puzzlePiece == -1) - return; - - if (_sliding) { - newx = _slidePointX; - newy = _slidePointY; - } else { - if (mousePt.y >= 137) - return; - - newx = mousePt.x; - newy = mousePt.y; - } - - newx -= _pieceInfo[_puzzlePiece].offX; - newy -= _pieceInfo[_puzzlePiece].offY; - - _pieceInfo[_puzzlePiece].curX = newx; - _pieceInfo[_puzzlePiece].curY = newy; - - drawCurrentPiece(); -} - -void Puzzle::handleClick(Point mousePt) { - if (_puzzlePiece != -1) { - dropPiece(mousePt); - - if (!_active) - return; // we won - - drawCurrentPiece(); - _puzzlePiece = -1; - - return; - } - - for (int j = 0; j < PUZZLE_PIECES; j++) { - int i = _piecePriority[j]; - int adjX = mousePt.x - _pieceInfo[i].curX; - int adjY = mousePt.y - _pieceInfo[i].curY; - - if (hitTestPoly(&_pieceInfo[i].point[0], _pieceInfo[i].count, Point(adjX, adjY))) { - _puzzlePiece = i; - break; - } - } - - if (_puzzlePiece == -1) - return; - - alterPiecePriority(); - - // Display scene background - _vm->_scene->draw(); - showPieces(); - - int newx = mousePt.x - _pieceInfo[_puzzlePiece].offX; - int newy = mousePt.y - _pieceInfo[_puzzlePiece].offY; - - if (newx != _pieceInfo[_puzzlePiece].curX - || newy != _pieceInfo[_puzzlePiece].curY) { - _pieceInfo[_puzzlePiece].curX = newx; - _pieceInfo[_puzzlePiece].curY = newy; - } - _vm->_interface->setStatusText(pieceNames[_lang][_puzzlePiece]); -} - -void Puzzle::alterPiecePriority(void) { - for (int i = 1; i < PUZZLE_PIECES; i++) { - if (_puzzlePiece == _piecePriority[i]) { - for (int j = i - 1; j >= 0; j--) - _piecePriority[j+1] = _piecePriority[j]; - _piecePriority[0] = _puzzlePiece; - break; - } - } -} - -void Puzzle::slidePiece(int x1, int y1, int x2, int y2) { - int count; - Point slidePoints[320]; - - x1 += _pieceInfo[_puzzlePiece].offX; - y1 += _pieceInfo[_puzzlePiece].offY; - - count = pathLine(&slidePoints[0], Point(x1, y1), - Point(x2 + _pieceInfo[_puzzlePiece].offX, y2 + _pieceInfo[_puzzlePiece].offY)); - - if (count > 1) { - int factor = count / 4; - _sliding = true; - - if (!factor) - factor++; - - for (int i = 1; i < count; i += factor) { - _slidePointX = slidePoints[i].x; - _slidePointY = slidePoints[i].y; - _vm->_render->drawScene(); - _vm->_system->delayMillis(10); - } - _sliding = false; - } - - _pieceInfo[_puzzlePiece].curX = x2; - _pieceInfo[_puzzlePiece].curY = y2; -} - -void Puzzle::dropPiece(Point mousePt) { - int boxx = PUZZLE_X_OFFSET; - int boxy = PUZZLE_Y_OFFSET; - int boxw = boxx + 184; - int boxh = boxy + 80; - - // if the center is within the box quantize within - // else move it back to its original start point - if (mousePt.x >= boxx && mousePt.x < boxw && mousePt.y >= boxy && mousePt.y <= boxh) { - ActorData *puzzle = _vm->_actor->getActor(_vm->_actor->actorIndexToId(ITE_ACTOR_PUZZLE)); - SpriteInfo *spI; - int frameNumber; - SpriteList *spriteList; - _vm->_actor->getSpriteParams(puzzle, frameNumber, spriteList); - - int newx = mousePt.x - _pieceInfo[_puzzlePiece].offX; - int newy = mousePt.y - _pieceInfo[_puzzlePiece].offY; - - if (newx < boxx) - newx = PUZZLE_X_OFFSET; - if (newy < boxy) - newy = PUZZLE_Y_OFFSET; - - spI = &(spriteList->infoList[_puzzlePiece]); - - if (newx + spI->width > boxw) - newx = boxw - spI->width ; - if (newy + spI->height > boxh) - newy = boxh - spI->height ; - - int x1 = ((newx - PUZZLE_X_OFFSET) & ~7) + PUZZLE_X_OFFSET; - int y1 = ((newy - PUZZLE_Y_OFFSET) & ~7) + PUZZLE_Y_OFFSET; - int x2 = x1 + 8; - int y2 = y1 + 8; - newx = (x2 - newx < newx - x1) ? x2 : x1; - newy = (y2 - newy < newy - y1) ? y2 : y1; - - // if any part of the puzzle piece falls outside the box - // force it back in - - // is the piece at the target location - if (newx == _pieceInfo[_puzzlePiece].trgX - && newy == _pieceInfo[_puzzlePiece].trgY) { - _pieceInfo[_puzzlePiece].flag |= (PUZZLE_MOVED | PUZZLE_FIT); - } else { - _pieceInfo[_puzzlePiece].flag &= ~PUZZLE_FIT; - _pieceInfo[_puzzlePiece].flag |= PUZZLE_MOVED; - } - _pieceInfo[_puzzlePiece].curX = newx; - _pieceInfo[_puzzlePiece].curY = newy; - } else { - int newx = pieceOrigins[_puzzlePiece].x; - int newy = pieceOrigins[_puzzlePiece].y; - _pieceInfo[_puzzlePiece].flag &= ~(PUZZLE_FIT | PUZZLE_MOVED); - - // slide piece from current position to new position - slidePiece(_pieceInfo[_puzzlePiece].curX, _pieceInfo[_puzzlePiece].curY, - newx, newy); - } - - // is the puzzle completed? - - _solved = true; - for (int i = 0; i < PUZZLE_PIECES; i++) - if ((_pieceInfo[i].flag & PUZZLE_FIT) == 0) { - _solved = false; - break; - } - - if (_solved) - exitPuzzle(); -} - -void Puzzle::hintTimerCallback(void *refCon) { - ((Puzzle *)refCon)->solicitHint(); -} - -void Puzzle::solicitHint(void) { - int i; - - _vm->_actor->setSpeechColor(1, kITEColorBlack); - - Common::g_timer->removeTimerProc(&hintTimerCallback); - - switch (_hintRqState) { - case kRQSpeaking: - if (_vm->_actor->isSpeaking()) { - Common::g_timer->installTimerProc(&hintTimerCallback, 50000, this); - break; - } - - _hintRqState = _hintNextRqState; - Common::g_timer->installTimerProc(&hintTimerCallback, 333333, this); - break; - - case kRQNoHint: - // Pick a random hint request. - i = _hintOffer++; - if (_hintOffer >= NUM_SOLICIT_REPLIES) - _hintOffer = 0; - - // Determine which of the journeymen will offer then - // hint, and then show that character's portrait. - _hintGiver = portraitList[i]; - _hintSpeaker = _hintGiver - RID_ITE_JFERRET_SERIOUS; - _vm->_interface->setRightPortrait(_hintGiver); - - _vm->_actor->nonActorSpeech(_hintBox, &solicitStr[_lang][i], 1, PUZZLE_SOLICIT_SOUNDS + i * 3 + _hintSpeaker, 0); - - // Add Rif's reply to the list. - clearHint(); - - // Roll to see if Sakka scolds - if (_vm->_rnd.getRandomNumber(1)) { - _hintRqState = kRQSakkaDenies; - Common::g_timer->installTimerProc(&hintTimerCallback, 200000, this); - } else { - _hintRqState = kRQSpeaking; - _hintNextRqState = kRQHintRequested; - Common::g_timer->installTimerProc(&hintTimerCallback, 50000, this); - } - - break; - - case kRQHintRequested: - i = _vm->_rnd.getRandomNumber(NUM_SAKKA - 1); - _vm->_actor->nonActorSpeech(_hintBox, &sakkaStr[_lang][i], 1, PUZZLE_SAKKA_SOUNDS + i, 0); - - _vm->_interface->setRightPortrait(RID_ITE_SAKKA_APPRAISING); - - _hintRqState = kRQSpeaking; - _hintNextRqState = kRQHintRequestedStage2; - Common::g_timer->installTimerProc(&hintTimerCallback, 50000, this); - - _vm->_interface->converseClear(); - _vm->_interface->converseAddText(optionsStr[_lang][kROAccept], 1, 0, 0 ); - _vm->_interface->converseAddText(optionsStr[_lang][kRODecline], 2, 0, 0 ); - _vm->_interface->converseAddText(optionsStr[_lang][kROLater], 0, 0, 0 ); - _vm->_interface->converseDisplayText(); - break; - - case kRQHintRequestedStage2: - if (_vm->_rnd.getRandomNumber(1)) { // Skip Reply part - i = _vm->_rnd.getRandomNumber(NUM_WHINES - 1); - _vm->_actor->nonActorSpeech(_hintBox, &whineStr[_lang][i], 1, PUZZLE_WHINE_SOUNDS + i * 3 + _hintSpeaker, 0); - } - - _vm->_interface->setRightPortrait(_hintGiver); - - _hintRqState = kRQSakkaDenies; - break; - - case kRQSakkaDenies: - _vm->_interface->converseClear(); - _vm->_interface->converseAddText(optionsStr[_lang][kROAccept], 1, 0, 0); - _vm->_interface->converseAddText(optionsStr[_lang][kRODecline], 2, 0, 0); - _vm->_interface->converseAddText(optionsStr[_lang][kROLater], 0, 0, 0); - _vm->_interface->converseDisplayText(); - - Common::g_timer->installTimerProc(&hintTimerCallback, kPuzzleHintTime, this); - - _hintRqState = kRQSkipEverything; - break; - - default: - break; - } -} - -void Puzzle::handleReply(int reply) { - switch(reply) { - case 0: // Quit the puzzle - exitPuzzle(); - break; - - case 1: // Accept the hint - giveHint(); - break; - - case 2: // Decline the hint - _vm->_actor->abortSpeech(); - _hintRqState = kRQNoHint; - Common::g_timer->removeTimerProc(&hintTimerCallback); - Common::g_timer->installTimerProc(&hintTimerCallback, kPuzzleHintTime * 2, this); - clearHint(); - break; - } -} - -void Puzzle::giveHint(void) { - int i, total = 0; - - _vm->_interface->converseClear(); - - _vm->_actor->abortSpeech(); - _vm->_interface->setRightPortrait(_hintGiver); - - for (i = 0; i < PUZZLE_PIECES; i++) - total += _pieceInfo[i].flag & PUZZLE_FIT; - - if (_hintCount == 0 && (_pieceInfo[1].flag & PUZZLE_FIT - || _pieceInfo[12].flag & PUZZLE_FIT)) - _hintCount++; - if (_hintCount == 1 && _pieceInfo[14].flag & PUZZLE_FIT) - _hintCount++; - - if (_hintCount == 2 && total > 3) - _hintCount++; - - _vm->_actor->setSpeechColor(1, kITEColorBlack); - - if (_hintCount < 3) { - _vm->_actor->nonActorSpeech(_hintBox, &hintStr[_lang][_hintCount], 1, PUZZLE_HINT_SOUNDS + _hintCount * 3 + _hintSpeaker, 0); - } else { - int piece = 0; - - for (i = PUZZLE_PIECES - 1; i >= 0; i--) { - piece = _piecePriority[i]; - if (_pieceInfo[piece].flag & PUZZLE_MOVED - && !(_pieceInfo[piece].flag & PUZZLE_FIT)) { - if (_helpCount < 12) - _helpCount++; - break; - } - } - - if (i >= 0) { - static char hintBuf[64]; - static const char *hintPtr = hintBuf; - sprintf(hintBuf, optionsStr[_lang][kROHint], pieceNames[_lang][piece]); - - _vm->_actor->nonActorSpeech(_hintBox, &hintPtr, 1, PUZZLE_TOOL_SOUNDS + _hintSpeaker + piece * 3, 0); - } - else { - // If no pieces are in the wrong place - _vm->_actor->nonActorSpeech(_hintBox, &hintStr[_lang][3], 1, PUZZLE_HINT_SOUNDS + 3 * 3 + _hintSpeaker, 0); - } - } - _hintCount++; - - _hintRqState = kRQNoHint; - - _vm->_interface->converseAddText(optionsStr[_lang][kROLater], 0, 0, 0); - _vm->_interface->converseDisplayText(); - - Common::g_timer->removeTimerProc(&hintTimerCallback); - Common::g_timer->installTimerProc(&hintTimerCallback, kPuzzleHintTime, this); -} - -void Puzzle::clearHint(void) { - _vm->_interface->converseClear(); - _vm->_interface->converseAddText(optionsStr[_lang][kROLater], 0, 0, 0); - _vm->_interface->converseDisplayText(); - _vm->_interface->setStatusText(" "); -} - -} // End of namespace Saga diff --git a/saga/puzzle.h b/saga/puzzle.h deleted file mode 100644 index b5c9b7c15c..0000000000 --- a/saga/puzzle.h +++ /dev/null @@ -1,120 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2005-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$ - * - */ - -#ifndef SAGA_PUZZLE_H_ -#define SAGA_PUZZLE_H_ - -namespace Saga { - - -#define PUZZLE_SOUNDS 3622 -#define PUZZLE_TOOL_SOUNDS (PUZZLE_SOUNDS + 0) -#define PUZZLE_HINT_SOUNDS (PUZZLE_SOUNDS + 45) -#define PUZZLE_SOLICIT_SOUNDS (PUZZLE_SOUNDS + 57) -#define PUZZLE_WHINE_SOUNDS (PUZZLE_SOUNDS + 72) -#define PUZZLE_SAKKA_SOUNDS (PUZZLE_SOUNDS + 87) - -class Puzzle { -private: - enum kRQStates { - kRQNoHint = 0, - kRQHintRequested = 1, - kRQHintRequestedStage2 = 2, - kRQSakkaDenies = 3, - kRQSkipEverything = 4, - kRQSpeaking = 5 - }; - - SagaEngine *_vm; - - bool _solved; - bool _active; - bool _newPuzzle; - bool _sliding; - - kRQStates _hintRqState; - kRQStates _hintNextRqState; - int _hintGiver; - int _hintSpeaker; - int _hintOffer; - int _hintCount; - int _helpCount; - - int _puzzlePiece; - int _piecePriority[PUZZLE_PIECES]; - - int _lang; - -public: - Puzzle(SagaEngine *vm); - - void execute(void); - void exitPuzzle(void); - - bool isSolved(void) { return _solved; } - bool isActive(void) { return _active; } - - void handleReply(int reply); - void handleClick(Point mousePt); - - void movePiece(Point mousePt); - -private: - void initPieceInfo(int i, int16 curX, int16 curY, byte offX, byte offY, int16 trgX, - int16 trgY, uint8 flag, uint8 count, Point point0, Point point1, - Point point2, Point point3, Point point4, Point point5); - - static void hintTimerCallback(void *refCon); - - void solicitHint(void); - - void initPieces(void); - void showPieces(void); - void slidePiece(int x1, int y1, int x2, int y2); - void dropPiece(Point mousePt); - void alterPiecePriority(void); - void drawCurrentPiece(void); - - void giveHint(void); - void clearHint(void); - -private: - struct PieceInfo { - int16 curX; - int16 curY; - byte offX; - byte offY; - int16 trgX; - int16 trgY; - uint8 flag; - uint8 count; - Point point[6]; - }; - - PieceInfo _pieceInfo[PUZZLE_PIECES]; - int _slidePointX, _slidePointY; - Rect _hintBox; -}; - -} // End of namespace Saga - -#endif diff --git a/saga/render.cpp b/saga/render.cpp deleted file mode 100644 index 7d312fb920..0000000000 --- a/saga/render.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Main rendering loop -#include "saga/saga.h" - -#include "saga/actor.h" -#include "saga/font.h" -#include "saga/gfx.h" -#include "saga/interface.h" -#include "saga/objectmap.h" -#include "saga/puzzle.h" -#include "saga/render.h" -#include "saga/scene.h" - -#include "common/timer.h" -#include "common/system.h" - -namespace Saga { - -const char *test_txt = "The quick brown fox jumped over the lazy dog. She sells sea shells down by the sea shore."; -const char *pauseString = "PAWS GAME"; - -Render::Render(SagaEngine *vm, OSystem *system) { - _vm = vm; - _system = system; - _initialized = false; - - // Initialize FPS timer callback - Common::g_timer->installTimerProc(&fpsTimerCallback, 1000000, this); - - _backGroundSurface.create(_vm->getDisplayWidth(), _vm->getDisplayHeight(), 1); - - _flags = 0; - - _initialized = true; -} - -Render::~Render(void) { - Common::g_timer->removeTimerProc(&fpsTimerCallback); - _backGroundSurface.free(); - - _initialized = false; -} - -bool Render::initialized() { - return _initialized; -} - -void Render::drawScene() { - Surface *backBufferSurface; - char txtBuffer[20]; - Point mousePoint; - Point textPoint; - - assert(_initialized); - - _frameCount++; - - backBufferSurface = _vm->_gfx->getBackBuffer(); - - // Get mouse coordinates - mousePoint = _vm->mousePos(); - - if (!(_flags & (RF_DEMO_SUBST | RF_PLACARD | RF_MAP))) { - // Display scene background - _vm->_scene->draw(); - - if (_vm->_interface->getFadeMode() != kFadeOut) { - if (_vm->_puzzle->isActive()) { - _vm->_puzzle->movePiece(mousePoint); - _vm->_actor->drawSpeech(); - } else { - // Draw queued actors - if (!(_flags & RF_DISABLE_ACTORS)) - _vm->_actor->drawActors(); - } - - if (getFlags() & RF_OBJECTMAP_TEST) { - if (_vm->_scene->_objectMap) - _vm->_scene->_objectMap->draw(backBufferSurface, mousePoint, kITEColorBrightWhite, kITEColorBlack); - if (_vm->_scene->_actionMap) - _vm->_scene->_actionMap->draw(backBufferSurface, mousePoint, kITEColorRed, kITEColorBlack); - } - if (getFlags() & RF_ACTOR_PATH_TEST) { - _vm->_actor->drawPathTest(); - } - } - } - - if (_flags & RF_MAP) - _vm->_interface->mapPanelDrawCrossHair(); - - if ((_vm->_interface->getMode() == kPanelOption) || - (_vm->_interface->getMode() == kPanelQuit) || - (_vm->_interface->getMode() == kPanelLoad) || - (_vm->_interface->getMode() == kPanelSave)) { - _vm->_interface->drawOption(); - - if (_vm->_interface->getMode() == kPanelQuit) { - _vm->_interface->drawQuit(); - } - if (_vm->_interface->getMode() == kPanelLoad) { - _vm->_interface->drawLoad(); - } - if (_vm->_interface->getMode() == kPanelSave) { - _vm->_interface->drawSave(); - } - } - - if (_vm->_interface->getMode() == kPanelProtect) { - _vm->_interface->drawProtect(); - } - - // Draw queued text strings - _vm->_scene->drawTextList(backBufferSurface); - - // Handle user input - _vm->processInput(); - - // Display rendering information - if (_flags & RF_SHOW_FPS) { - sprintf(txtBuffer, "%d", _fps); - textPoint.x = backBufferSurface->w - _vm->_font->getStringWidth(kKnownFontSmall, txtBuffer, 0, kFontOutline); - textPoint.y = 2; - - _vm->_font->textDraw(kKnownFontSmall, backBufferSurface, txtBuffer, textPoint, kITEColorBrightWhite, kITEColorBlack, kFontOutline); - } - - // Display "paused game" message, if applicable - if (_flags & RF_RENDERPAUSE) { - textPoint.x = (backBufferSurface->w - _vm->_font->getStringWidth(kKnownFontPause, pauseString, 0, kFontOutline)) / 2; - textPoint.y = 90; - - _vm->_font->textDraw(kKnownFontPause, backBufferSurface, pauseString, textPoint, kITEColorBrightWhite, kITEColorBlack, kFontOutline); - } - - // Update user interface - _vm->_interface->update(mousePoint, UPDATE_MOUSEMOVE); - - // Display text formatting test, if applicable - if (_flags & RF_TEXT_TEST) { - Rect rect(mousePoint.x, mousePoint.y, mousePoint.x + 100, mousePoint.y + 50); - _vm->_font->textDrawRect(kKnownFontMedium, backBufferSurface, test_txt, rect, - kITEColorBrightWhite, kITEColorBlack, (FontEffectFlags)(kFontOutline | kFontCentered)); - } - - // Display palette test, if applicable - if (_flags & RF_PALETTE_TEST) { - backBufferSurface->drawPalette(); - } - - _system->copyRectToScreen((byte *)backBufferSurface->pixels, backBufferSurface->w, 0, 0, - backBufferSurface->w, backBufferSurface->h); - - _system->updateScreen(); -} - -void Render::fpsTimerCallback(void *refCon) { - ((Render *)refCon)->fpsTimer(); -} - -void Render::fpsTimer(void) { - _fps = _frameCount; - _frameCount = 0; -} - -} // End of namespace Saga diff --git a/saga/render.h b/saga/render.h deleted file mode 100644 index f6187393d2..0000000000 --- a/saga/render.h +++ /dev/null @@ -1,93 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Main rendering loop - private header - -#ifndef SAGA_RENDER_H_ -#define SAGA_RENDER_H_ - -#include "saga/sprite.h" - -namespace Saga { - -enum RENDER_FLAGS { - RF_SHOW_FPS = (1 << 0), - RF_PALETTE_TEST = (1 << 1), - RF_TEXT_TEST = (1 << 2), - RF_OBJECTMAP_TEST = (1 << 3), - RF_RENDERPAUSE = (1 << 4), - RF_GAMEPAUSE = (1 << 5), - RF_PLACARD = (1 << 6), - RF_ACTOR_PATH_TEST = (1 << 7), - RF_MAP = (1 << 8), - RF_DISABLE_ACTORS = (1 << 9), - RF_DEMO_SUBST = (1 << 10) -}; - -class Render { -public: - Render(SagaEngine *vm, OSystem *system); - ~Render(void); - bool initialized(); - void drawScene(void); - - unsigned int getFlags() const { - return _flags; - } - - void setFlag(unsigned int flag) { - _flags |= flag; - } - - void clearFlag(unsigned int flag) { - _flags &= ~flag; - } - - void toggleFlag(unsigned int flag) { - _flags ^= flag; - } - - Surface *getBackGroundSurface() { - return &_backGroundSurface; - } - -private: - static void fpsTimerCallback(void *refCon); - void fpsTimer(void); - - SagaEngine *_vm; - OSystem *_system; - bool _initialized; - - // Module data - Surface _backGroundSurface; - - unsigned int _fps; - unsigned int _frameCount; - uint32 _flags; -}; - -} // End of namespace Saga - -#endif diff --git a/saga/resnames.h b/saga/resnames.h deleted file mode 100644 index 01522a9ca7..0000000000 --- a/saga/resnames.h +++ /dev/null @@ -1,253 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Descriptive names for game resource numbers - -#ifndef SAGA_RESOURCENAMES_H_ -#define SAGA_RESOURCENAMES_H_ - -namespace Saga { - -// Prefix RID_ means Resource Id - -// Lookup tables -#define RID_ITE_SCENE_LUT 1806 -#define RID_ITE_SCRIPT_LUT 216 - -#define RID_ITEDEMO_SCENE_LUT 318 -#define RID_ITEDEMO_SCRIPT_LUT 146 - -#define RID_IHNM_SCENE_LUT 1272 -#define RID_IHNM_SCRIPT_LUT 29 -#define RID_IHNM_SFX_LUT 265 - -#define RID_IHNMDEMO_SCENE_LUT 286 -#define RID_IHNMDEMO_SCRIPT_LUT 18 - -//obj names -#define ITE_OBJ_MAP 14 -#define ITE_OBJ_MAGIC_HAT 0 - -#define IHNM_OBJ_PROFILE 0x4000 - -#define RID_IHNM_DEFAULT_PALETTE 1 - -//actor names -#define ITE_ACTOR_PUZZLE 176 - -// SCENES -#define ITE_SCENE_INV -1 -#define ITE_SCENE_PUZZLE 26 -#define ITE_SCENE_LODGE 21 -#define ITE_SCENE_ENDCREDIT1 295 - -#define ITE_DEFAULT_SCENE 32 -#define IHNM_DEFAULT_SCENE 151 - -#define ITEDEMO_DEFAULT_SCENE 68 - -// FONTS -#define RID_MEDIUM_FONT 0 -#define RID_BIG_FONT 1 -#define RID_SMALL_FONT 2 - -// INTERFACE IMAGES -#define RID_ITE_MAIN_PANEL 3 -#define RID_ITE_CONVERSE_PANEL 4 -#define RID_ITE_OPTION_PANEL 5 -#define RID_ITE_MAIN_SPRITES 6 -#define RID_ITE_MAIN_PANEL_SPRITES 7 -#define RID_ITE_MAIN_STRINGS 35 //main strings -#define RID_ITE_ACTOR_NAMES 36 //actors names -#define RID_ITE_DEFAULT_PORTRAITS 125 - -#define RID_ITEDEMO_MAIN_PANEL 2 -#define RID_ITEDEMO_CONVERSE_PANEL 3 -#define RID_ITEDEMO_OPTION_PANEL 3 // FIXME: should be 4 but it is an empty resource. -#define RID_ITEDEMO_MAIN_SPRITES 5 // Proper fix would be not load options panel when demo is running -#define RID_ITEDEMO_MAIN_PANEL_SPRITES 6 -#define RID_ITEDEMO_MAIN_STRINGS 8 //main strings -#define RID_ITEDEMO_ACTOR_NAMES 9 //actors names -#define RID_ITEDEMO_DEFAULT_PORTRAITS 80 - -#define RID_ITE_TYCHO_MAP 1686 -#define RID_ITE_SPR_XHAIR1 (73 + 9) -#define RID_ITE_SPR_XHAIR2 (74 + 9) - -#define RID_IHNM_MAIN_PANEL 9 -#define RID_IHNM_CONVERSE_PANEL 10 -#define RID_IHNM_HOURGLASS_CURSOR 11 -#define RID_IHNM_MAIN_SPRITES 12 // TODO: verify this -#define RID_IHNM_MAIN_PANEL_SPRITES 12 -#define RID_IHNM_ARROW_SPRITES 13 -#define RID_IHNM_SAVEREMINDER_SPRITES 14 -#define RID_IHNM_OPTION_PANEL 15 -#define RID_IHNM_WARNING_PANEL 17 -#define RID_IHNM_BOSS_SCREEN 19 -#define RID_IHNM_PROFILE_BG 20 -#define RID_IHNM_MAIN_STRINGS 21 - -// Puzzle portraits -#define RID_ITE_SAKKA_APPRAISING 6 -#define RID_ITE_SAKKA_DENIAL 7 -#define RID_ITE_SAKKA_EXCITED 8 -#define RID_ITE_JFERRET_SERIOUS 9 -#define RID_ITE_JFERRET_GOOFY 10 -#define RID_ITE_JFERRET_ALOOF 11 - -// ITE Scene resource numbers -#define RID_ITE_OVERMAP_SCENE 226 -#define RID_ITE_INTRO_ANIM_SCENE 1538 -#define RID_ITE_CAVE_SCENE_1 1542 -#define RID_ITE_CAVE_SCENE_2 1545 -#define RID_ITE_CAVE_SCENE_3 1548 -#define RID_ITE_CAVE_SCENE_4 1551 - -#define RID_ITE_VALLEY_SCENE 1556 -#define RID_ITE_TREEHOUSE_SCENE 1560 -#define RID_ITE_FAIREPATH_SCENE 1564 -#define RID_ITE_FAIRETENT_SCENE 1567 - -#define RID_ITE_INTRO_ANIM_STARTFRAME 1529 - -#define RID_ITE_INTRO_ANIM_1 1530 -#define RID_ITE_INTRO_ANIM_2 1531 -#define RID_ITE_INTRO_ANIM_3 1532 -#define RID_ITE_INTRO_ANIM_4 1533 -#define RID_ITE_INTRO_ANIM_5 1534 -#define RID_ITE_INTRO_ANIM_6 1535 -#define RID_ITE_INTRO_ANIM_7 1536 - -#define RID_ITE_CAVE_IMG_1 1540 -#define RID_ITE_CAVE_IMG_2 1543 -#define RID_ITE_CAVE_IMG_3 1546 -#define RID_ITE_CAVE_IMG_4 1549 - -#define RID_ITE_INTRO_IMG_1 1552 -#define RID_ITE_INTRO_IMG_2 1557 -#define RID_ITE_INTRO_IMG_3 1561 -#define RID_ITE_INTRO_IMG_4 1565 - -// ITE_VOICES -#define RID_CAVE_VOICE_0 0 -#define RID_CAVE_VOICE_1 1 -#define RID_CAVE_VOICE_2 2 -#define RID_CAVE_VOICE_3 3 -#define RID_CAVE_VOICE_4 4 -#define RID_CAVE_VOICE_5 5 -#define RID_CAVE_VOICE_6 6 -#define RID_CAVE_VOICE_7 7 -#define RID_CAVE_VOICE_8 8 -#define RID_CAVE_VOICE_9 9 -#define RID_CAVE_VOICE_10 10 -#define RID_CAVE_VOICE_11 11 -#define RID_CAVE_VOICE_12 12 -#define RID_CAVE_VOICE_13 13 - -#define RID_SCENE1_VOICE_009 57 -//TODO: fill it -#define RID_SCENE1_VOICE_138 186 - -#define RID_BOAR_VOICE_000 239 -#define RID_BOAR_VOICE_002 241 -#define RID_BOAR_VOICE_005 244 -#define RID_BOAR_VOICE_006 245 -#define RID_BOAR_VOICE_007 246 - -// MUSIC -#define MUSIC_1 9 -#define MUSIC_2 10 - -// TODO: If the sound effects are numbered sequentially, we don't really need -// these constants. But for now they might be useful for debugging. - -// SOUND EFFECTS - -#define FX_DOOR_OPEN 14 -#define FX_DOOR_CLOSE 15 -#define FX_RUSH_WATER 16 -#define FX_CRICKET 17 -#define FX_PORTICULLIS 18 -#define FX_CLOCK_1 19 -#define FX_CLOCK_2 20 -#define FX_DAM_MACHINE 21 -#define FX_HUM1 22 -#define FX_HUM2 23 -#define FX_HUM3 24 -#define FX_HUM4 25 -#define FX_STREAM 26 -#define FX_SURF 27 -#define FX_FIRELOOP 28 -#define FX_SCRAPING 29 -#define FX_BEE_SWARM 30 -#define FX_SQUEAKBOARD 31 -#define FX_KNOCK 32 -#define FX_COINS 33 -#define FX_STORM 34 -#define FX_DOOR_CLOSE_2 35 -#define FX_ARCWELD 36 -#define FX_RETRACT_ORB 37 -#define FX_DRAGON 38 -#define FX_SNORES 39 -#define FX_SPLASH 40 -#define FX_LOBBY_DOOR 41 -#define FX_CHIRP_LOOP 42 -#define FX_DOOR_CREAK 43 -#define FX_SPOON_DIG 44 -#define FX_CROW 45 -#define FX_COLDWIND 46 -#define FX_TOOL_SND_1 47 -#define FX_TOOL_SND_2 48 -#define FX_TOOL_SND_3 49 -#define FX_DOOR_METAL 50 -#define FX_WATER_LOOP_S 51 -#define FX_WATER_LOOP_L 52 -#define FX_DOOR_OPEN_2 53 -#define FX_JAIL_DOOR 54 -#define FX_KILN_FIRE 55 -#define FX_DUMMY 56 - -// These are only in the CD version - -#define FX_CROWD_01 57 -#define FX_CROWD_02 58 -#define FX_CROWD_03 59 -#define FX_CROWD_04 60 -#define FX_CROWD_05 61 -#define FX_CROWD_06 62 -#define FX_CROWD_07 63 -#define FX_CROWD_08 64 -#define FX_CROWD_09 65 -#define FX_CROWD_10 66 -#define FX_CROWD_11 67 -#define FX_CROWD_12 68 -#define FX_CROWD_13 69 -#define FX_CROWD_14 70 -#define FX_CROWD_15 71 -#define FX_CROWD_16 72 -#define FX_CROWD_17 73 - -} // End of namespace Saga - -#endif diff --git a/saga/rscfile.cpp b/saga/rscfile.cpp deleted file mode 100644 index 24d1262d56..0000000000 --- a/saga/rscfile.cpp +++ /dev/null @@ -1,615 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// RSC Resource file management module -#include "saga/saga.h" - -#include "saga/actor.h" -#include "saga/animation.h" -#include "saga/interface.h" -#include "saga/music.h" -#include "saga/rscfile.h" -#include "saga/scene.h" -#include "saga/sndres.h" -#include "saga/stream.h" - -namespace Saga { - -struct MacResMap { - int16 resAttr; - int16 typeOffset; - int16 nameOffset; - int16 numTypes; -}; - -struct MacResource { - int16 id; - int16 nameOffset; - byte attr; - int32 dataOffset; - byte name[255]; -}; - -struct MacResType { - uint32 id; - int16 items; - int16 maxItemId; - int16 offset; - MacResource *resources; -}; - - -#define ID_MIDI MKID_BE('Midi') - -Resource::Resource(SagaEngine *vm): _vm(vm) { - _contexts = NULL; - _contextsCount = 0; -} - -Resource::~Resource() { - clearContexts(); -} - -bool Resource::loadSagaContext(ResourceContext *context, uint32 contextOffset, uint32 contextSize) { - size_t i; - bool result; - byte tableInfo[RSC_TABLEINFO_SIZE]; - byte *tableBuffer; - size_t tableSize; - uint32 resourceTableOffset; - ResourceData *resourceData; - - if (contextSize < RSC_MIN_FILESIZE) { - return false; - } - - context->file->seek(contextOffset + contextSize - RSC_TABLEINFO_SIZE); - - if (context->file->read(tableInfo, RSC_TABLEINFO_SIZE) != RSC_TABLEINFO_SIZE) { - return false; - } - - MemoryReadStreamEndian readS(tableInfo, RSC_TABLEINFO_SIZE, context->isBigEndian); - - resourceTableOffset = readS.readUint32(); - context->count = readS.readUint32(); - - // Check for sane table offset - if (resourceTableOffset != contextSize - RSC_TABLEINFO_SIZE - RSC_TABLEENTRY_SIZE * context->count) { - return false; - } - - // Load resource table - tableSize = RSC_TABLEENTRY_SIZE * context->count; - - tableBuffer = (byte *)malloc(tableSize); - - context->file->seek(resourceTableOffset + contextOffset, SEEK_SET); - - result = (context->file->read(tableBuffer, tableSize) == tableSize); - if (result) { - context->table = (ResourceData *)calloc(context->count, sizeof(*context->table)); - - MemoryReadStreamEndian readS1(tableBuffer, tableSize, context->isBigEndian); - - for (i = 0; i < context->count; i++) { - resourceData = &context->table[i]; - resourceData->offset = contextOffset + readS1.readUint32(); - resourceData->size = readS1.readUint32(); - //sanity check - if ((resourceData->offset > context->file->size()) || (resourceData->size > contextSize)) { - result = false; - break; - } - } - } - - free(tableBuffer); - return result; -} - -bool Resource::loadMacContext(ResourceContext *context) { - int32 macDataSize, macDataSizePad; - int32 macResSize, macResSizePad; - int32 macResOffset; - - uint32 macMapLength; - uint32 macDataLength; - uint32 macMapOffset; - uint32 macDataOffset; - - MacResMap macResMap; - MacResType *macResTypes; - - MacResType *macResType; - MacResource *macResource; - int i, j; - byte macNameLen; - bool notSagaContext = false; - - if (context->file->size() < RSC_MIN_FILESIZE + MAC_BINARY_HEADER_SIZE) { - return false; - } - - if (context->file->readByte() != 0) { - return false; - } - context->file->readByte(); //MAX Name Len - context->file->seek(74); - if (context->file->readByte() != 0) { - return false; - } - context->file->seek(82); - if (context->file->readByte() != 0) { - return false; - } - - macDataSize = context->file->readSint32BE(); - macResSize = context->file->readSint32BE(); - macDataSizePad = (((macDataSize + 127) >> 7) << 7); - macResSizePad = (((macResSize + 127) >> 7) << 7); - - macResOffset = MAC_BINARY_HEADER_SIZE + macDataSizePad; - context->file->seek(macResOffset); - - macDataOffset = context->file->readUint32BE() + macResOffset; - macMapOffset = context->file->readUint32BE() + macResOffset; - macDataLength = context->file->readUint32BE(); - macMapLength = context->file->readUint32BE(); - - if (macDataOffset >= context->file->size() || macMapOffset >= context->file->size() || - macDataLength + macMapLength > context->file->size()) { - return false; - } - - context->file->seek(macMapOffset + 22); - - macResMap.resAttr = context->file->readUint16BE(); - macResMap.typeOffset = context->file->readUint16BE(); - macResMap.nameOffset = context->file->readUint16BE(); - macResMap.numTypes = context->file->readUint16BE(); - macResMap.numTypes++; - - context->file->seek(macMapOffset + macResMap.typeOffset + 2); - - macResTypes = (MacResType *)calloc(macResMap.numTypes, sizeof(*macResTypes)); - - for (i = macResMap.numTypes, macResType = macResTypes; i > 0; i--, macResType++) { - macResType->id = context->file->readUint32BE(); - macResType->items = context->file->readUint16BE(); - macResType->offset = context->file->readUint16BE(); - macResType->items++; - macResType->resources = (MacResource*)calloc(macResType->items, sizeof(*macResType->resources)); - } - - for (i = macResMap.numTypes, macResType = macResTypes; i > 0; i--, macResType++) { - context->file->seek(macResType->offset + macMapOffset + macResMap.typeOffset); - - for (j = macResType->items, macResource = macResType->resources; j > 0; j--, macResource++) { - macResource->id = context->file->readUint16BE(); - macResource->nameOffset = context->file->readUint16BE(); - macResource->dataOffset = context->file->readUint32BE(); - macResSize = context->file->readUint32BE(); - - macResource->attr = macResource->dataOffset >> 24; - macResource->dataOffset &= 0xFFFFFF; - if (macResource->id > macResType->maxItemId) { - macResType->maxItemId = macResource->id; - } - } - - for (j = macResType->items, macResource = macResType->resources; j > 0; j--, macResource++) { - if (macResource->nameOffset != -1) { - context->file->seek(macResource->nameOffset + macMapOffset + macResMap.nameOffset); - macNameLen = context->file->readByte(); - context->file->read(macResource->name, macNameLen); - } - } - } - -// - for (i = macResMap.numTypes, macResType = macResTypes; i > 0; i--, macResType++) { - //getting offsets & sizes of midi - if (((context->fileType & GAME_MUSICFILE_GM) > 0) && (macResType->id == ID_MIDI)) { - - context->count = macResType->maxItemId + 1; - context->table = (ResourceData *)calloc(context->count, sizeof(*context->table)); - for (j = macResType->items, macResource = macResType->resources; j > 0; j--, macResource++) { - context->file->seek(macDataOffset + macResource->dataOffset); - context->table[macResource->id].size = context->file->readUint32BE(); - context->table[macResource->id].offset = context->file->pos(); - } - notSagaContext = true; - break; - } - } - -//free - for (i = 0; i < macResMap.numTypes; i++) { - free(macResTypes[i].resources); - } - free(macResTypes); - - if ((!notSagaContext) && (!loadSagaContext(context, MAC_BINARY_HEADER_SIZE, macDataSize))) { - return false; - } - - return true; -} - -bool Resource::loadContext(ResourceContext *context) { - size_t i; - int j; - GamePatchDescription *patchDescription; - ResourceData *resourceData; - uint16 subjectResourceType; - ResourceContext *subjectContext; - uint32 subjectResourceId; - uint32 patchResourceId; - ResourceData *subjectResourceData; - byte *tableBuffer; - size_t tableSize; - bool isMacBinary; - - if (!context->file->open(context->fileName)) { - return false; - } - - context->isBigEndian = _vm->isBigEndian(); - - if (context->fileType & GAME_SWAPENDIAN) - context->isBigEndian = !context->isBigEndian; - - isMacBinary = (context->fileType & GAME_MACBINARY) > 0; - context->fileType &= ~GAME_MACBINARY; - - if (isMacBinary) { - if (!loadMacContext(context)) { - return false; - } - } else { - if (!loadSagaContext(context, 0, context->file->size())) { - return false; - } - } - - //process internal patch files - if (GAME_PATCHFILE & context->fileType) { - subjectResourceType = ~GAME_PATCHFILE & context->fileType; - subjectContext = getContext((GameFileTypes)subjectResourceType); - if (subjectContext == NULL) { - error("Resource::loadContext() Subject context not found"); - } - loadResource(context, context->count - 1, tableBuffer, tableSize); - - MemoryReadStreamEndian readS2(tableBuffer, tableSize, context->isBigEndian); - for (i = 0; i < tableSize / 8; i++) { - subjectResourceId = readS2.readUint32(); - patchResourceId = readS2.readUint32(); - subjectResourceData = getResourceData(subjectContext, subjectResourceId); - resourceData = getResourceData(context, patchResourceId); - subjectResourceData->patchData = new PatchData(context->file); - subjectResourceData->offset = resourceData->offset; - subjectResourceData->size = resourceData->size; - } - - } - - //process external patch files - for (j = 0; j < _vm->getGameDescription()->patchesCount; j++) { - patchDescription = &_vm->getGameDescription()->patchDescriptions[j]; - if ((patchDescription->fileType & context->fileType) != 0) { - if (patchDescription->resourceId < context->count) { - resourceData = &context->table[patchDescription->resourceId]; - resourceData->patchData = new PatchData(patchDescription); - if (resourceData->patchData->_patchFile->open(patchDescription->fileName)) { - resourceData->offset = 0; - resourceData->size = resourceData->patchData->_patchFile->size(); - } else { - delete resourceData->patchData; - resourceData->patchData = NULL; - } - } - } - } - - return true; -} - -bool Resource::createContexts() { - int i; - ResourceContext *context; - _contextsCount = _vm->getGameDescription()->filesCount; - _contexts = (ResourceContext*)calloc(_contextsCount, sizeof(*_contexts)); - - for (i = 0; i < _contextsCount; i++) { - context = &_contexts[i]; - context->file = new Common::File(); - context->fileName = _vm->getGameDescription()->filesDescriptions[i].fileName; - context->fileType = _vm->getGameDescription()->filesDescriptions[i].fileType; - context->serial = 0; - - // IHNM has serveral different voice files, so we need to allow - // multiple resource contexts of the same type. We tell them - // apart by assigning each of the duplicates an unique serial - // number. The default behaviour when requesting a context will - // be to look for serial number 0. - - for (int j = i - 1; j >= 0; j--) { - if (_contexts[j].fileType & context->fileType) { - context->serial = _contexts[j].serial + 1; - break; - } - } - - if (!loadContext(context)) { - return false; - } - } - return true; -} - -void Resource::clearContexts() { - int i; - size_t j; - ResourceContext *context; - if (_contexts == NULL) { - return; - } - for(i = 0; i < _contextsCount; i++) { - context = &_contexts[i]; - delete context->file; - if (context->table != NULL) { - for(j = 0; j < context->count; j++) { - delete context->table[j].patchData; - } - } - free(context->table); - } - free(_contexts); - _contexts = NULL; -} - -uint32 Resource::convertResourceId(uint32 resourceId) { - - if (_vm->getGameType() == GType_ITE && _vm->isMacResources()) { - if (resourceId > 1537) { - return resourceId - 2; - } else { - if (resourceId == 1535 || resourceId == 1536) { - error ("Wrong resource number %d for Mac ITE", resourceId); - } - } - } - - return resourceId; -} - -void Resource::loadResource(ResourceContext *context, uint32 resourceId, byte*&resourceBuffer, size_t &resourceSize) { - Common::File *file; - uint32 resourceOffset; - ResourceData *resourceData; - - debug(8, "loadResource %d", resourceId); - - resourceData = getResourceData(context, resourceId); - - file = context->getFile(resourceData); - - resourceOffset = resourceData->offset; - resourceSize = resourceData->size; - - resourceBuffer = (byte*)malloc(resourceSize); - - file->seek((long)resourceOffset, SEEK_SET); - - if (file->read(resourceBuffer, resourceSize) != resourceSize) { - error("Resource::loadResource() failed to read"); - } -} - -static int metaResourceTable[] = { 0, 326, 517, 677, 805, 968, 1165, 0, 1271 }; - -void Resource::loadGlobalResources(int chapter, int actorsEntrance) { - if (chapter < 0) - chapter = 8; - - // TODO - //if (module.voiceLUT) - // free module.voiceLUT; - - // TODO: close chapter context, or rather reassign it in our case - - ResourceContext *resourceContext; - ResourceContext *soundContext; - int i; - - resourceContext = _vm->_resource->getContext(GAME_RESOURCEFILE); - if (resourceContext == NULL) { - error("Resource::loadGlobalResources() resource context not found"); - } - - soundContext = _vm->_resource->getContext(GAME_SOUNDFILE); - if (soundContext == NULL) { - error("Resource::loadGlobalResources() sound context not found"); - } - - byte *resourcePointer; - size_t resourceLength; - - _vm->_resource->loadResource(resourceContext, metaResourceTable[chapter], - resourcePointer, resourceLength); - - if (resourceLength == 0) { - error("Resource::loadGlobalResources wrong metaResource"); - } - - MemoryReadStream metaS(resourcePointer, resourceLength); - - _metaResource.sceneIndex = metaS.readSint16LE(); - _metaResource.objectCount = metaS.readSint16LE(); - _metaResource.objectsStringsResourceID = metaS.readSint32LE(); - _metaResource.inventorySpritesID = metaS.readSint32LE(); - _metaResource.mainSpritesID = metaS.readSint32LE(); - _metaResource.objectsResourceID = metaS.readSint32LE(); - _metaResource.actorCount = metaS.readSint16LE(); - _metaResource.actorsStringsResourceID = metaS.readSint32LE(); - _metaResource.actorsResourceID = metaS.readSint32LE(); - _metaResource.protagFaceSpritesID = metaS.readSint32LE(); - _metaResource.field_22 = metaS.readSint32LE(); - _metaResource.field_26 = metaS.readSint16LE(); - _metaResource.protagStatesCount = metaS.readSint16LE(); - _metaResource.protagStatesResourceID = metaS.readSint32LE(); - _metaResource.cutawayListResourceID = metaS.readSint32LE(); - _metaResource.songTableID = metaS.readSint32LE(); - - free(resourcePointer); - - _vm->_actor->loadActorList(actorsEntrance, _metaResource.actorCount, - _metaResource.actorsResourceID, _metaResource.protagStatesCount, - _metaResource.protagStatesResourceID); - - _vm->_actor->_protagonist->_sceneNumber = _metaResource.sceneIndex; - - _vm->_actor->_objectsStrings.freeMem(); - - _vm->_resource->loadResource(resourceContext, _metaResource.objectsStringsResourceID, resourcePointer, resourceLength); - _vm->loadStrings(_vm->_actor->_objectsStrings, resourcePointer, resourceLength); - free(resourcePointer); - - if (chapter >= _vm->_sndRes->_fxTableIDsLen) { - error("Chapter ID exceeds fxTableIDs length"); - } - - debug(0, "Going to read %d of %d", chapter, _vm->_sndRes->_fxTableIDs[chapter]); - _vm->_resource->loadResource(soundContext, _vm->_sndRes->_fxTableIDs[chapter], - resourcePointer, resourceLength); - - if (resourceLength == 0) { - error("Resource::loadGlobalResources Can't load sound effects for current track"); - } - - free(_vm->_sndRes->_fxTable); - - _vm->_sndRes->_fxTableLen = resourceLength / 4; - _vm->_sndRes->_fxTable = (FxTable *)malloc(sizeof(FxTable) * _vm->_sndRes->_fxTableLen); - - MemoryReadStream fxS(resourcePointer, resourceLength); - - for (i = 0; i < _vm->_sndRes->_fxTableLen; i++) { - _vm->_sndRes->_fxTable[i].res = fxS.readSint16LE(); - _vm->_sndRes->_fxTable[i].vol = fxS.readSint16LE(); - } - free(resourcePointer); - - _vm->_interface->_defPortraits.freeMem(); - _vm->_sprite->loadList(_metaResource.protagFaceSpritesID, _vm->_interface->_defPortraits); - - _vm->_actor->_actorsStrings.freeMem(); - - _vm->_resource->loadResource(resourceContext, _metaResource.actorsStringsResourceID, resourcePointer, resourceLength); - _vm->loadStrings(_vm->_actor->_actorsStrings, resourcePointer, resourceLength); - free(resourcePointer); - - _vm->_sprite->_inventorySprites.freeMem(); - _vm->_sprite->loadList(_metaResource.inventorySpritesID, _vm->_sprite->_inventorySprites); - - _vm->_sprite->_mainSprites.freeMem(); - _vm->_sprite->loadList(_metaResource.mainSpritesID, _vm->_sprite->_mainSprites); - - _vm->_actor->loadObjList(_metaResource.objectCount, _metaResource.objectsResourceID); - - _vm->_resource->loadResource(resourceContext, _metaResource.cutawayListResourceID, resourcePointer, resourceLength); - - if (resourceLength == 0) { - error("Resource::loadGlobalResources Can't load cutaway list"); - } - - _vm->_anim->loadCutawayList(resourcePointer, resourceLength); - - _vm->_resource->loadResource(resourceContext, _metaResource.songTableID, resourcePointer, resourceLength); - - if (resourceLength == 0) { - error("Resource::loadGlobalResources Can't load songs list for current track"); - } - - free(_vm->_music->_songTable); - - _vm->_music->_songTableLen = resourceLength / 4; - _vm->_music->_songTable = (int32 *)malloc(sizeof(int32) * _vm->_music->_songTableLen); - - MemoryReadStream songS(resourcePointer, resourceLength); - - for (i = 0; i < _vm->_music->_songTableLen; i++) - _vm->_music->_songTable[i] = songS.readSint32LE(); - free(resourcePointer); - - int voiceLUTResourceID = 0; - - _vm->_script->_globalVoiceLUT.freeMem(); - - switch (chapter) { - case 1: - _vm->_sndRes->setVoiceBank(1); - voiceLUTResourceID = 23; - break; - case 2: - _vm->_sndRes->setVoiceBank(2); - voiceLUTResourceID = 24; - break; - case 3: - _vm->_sndRes->setVoiceBank(3); - voiceLUTResourceID = 25; - break; - case 4: - _vm->_sndRes->setVoiceBank(4); - voiceLUTResourceID = 26; - break; - case 5: - _vm->_sndRes->setVoiceBank(5); - voiceLUTResourceID = 27; - break; - case 6: - _vm->_sndRes->setVoiceBank(6); - voiceLUTResourceID = 28; - break; - case 7: - break; - case 8: - _vm->_sndRes->setVoiceBank(0); - voiceLUTResourceID = 22; - break; - } - - if (voiceLUTResourceID) { - _vm->_resource->loadResource(resourceContext, voiceLUTResourceID, resourcePointer, resourceLength); - _vm->_script->loadVoiceLUT(_vm->_script->_globalVoiceLUT, resourcePointer, resourceLength); - free(resourcePointer); - } - - _vm->_spiritualBarometer = 0; - _vm->_scene->setChapterNumber(chapter); -} - -} // End of namespace Saga diff --git a/saga/rscfile.h b/saga/rscfile.h deleted file mode 100644 index 434a6d9a96..0000000000 --- a/saga/rscfile.h +++ /dev/null @@ -1,173 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// RSC Resource file management header file - -#ifndef SAGA_RSCFILE_H__ -#define SAGA_RSCFILE_H__ - -#include "common/file.h" - -namespace Saga { - -#define MAC_BINARY_HEADER_SIZE 128 -#define RSC_TABLEINFO_SIZE 8 -#define RSC_TABLEENTRY_SIZE 8 - -#define RSC_MIN_FILESIZE (RSC_TABLEINFO_SIZE + RSC_TABLEENTRY_SIZE + 1) - -struct PatchData { - bool _deletePatchFile; - Common::File *_patchFile; - GamePatchDescription *_patchDescription; - - PatchData(GamePatchDescription *patchDescription): _patchDescription(patchDescription), _deletePatchFile(true) { - _patchFile = new Common::File(); - } - PatchData(Common::File *patchFile): _patchDescription(NULL), _patchFile(patchFile), _deletePatchFile(false) { - } - - ~PatchData() { - if (_deletePatchFile) { - delete _patchFile; - } - } -}; - -struct ResourceData { - size_t offset; - size_t size; - PatchData *patchData; - void fillSoundPatch(const GameSoundInfo *&soundInfo) { - if (patchData != NULL) { - if (patchData->_patchDescription != NULL) { - if (patchData->_patchDescription->soundInfo != NULL) { - soundInfo = patchData->_patchDescription->soundInfo; - } - } - } - } -}; - -struct ResourceContext { - const char *fileName; - uint16 fileType; - Common::File *file; - int serial; - - bool isBigEndian; - ResourceData *table; - size_t count; - - Common::File *getFile(ResourceData *resourceData) const { - if (resourceData->patchData != NULL) { - return resourceData->patchData->_patchFile; - } else { - return file; - } - } -}; - -struct MetaResource { - int16 sceneIndex; - int16 objectCount; - int32 objectsStringsResourceID; - int32 inventorySpritesID; - int32 mainSpritesID; - int32 objectsResourceID; - int16 actorCount; - int32 actorsStringsResourceID; - int32 actorsResourceID; - int32 protagFaceSpritesID; - int32 field_22; - int16 field_26; - int16 protagStatesCount; - int32 protagStatesResourceID; - int32 cutawayListResourceID; - int32 songTableID; - - MetaResource() { - memset(this, 0, sizeof(*this)); - } -}; - -class Resource { -public: - Resource(SagaEngine *vm); - ~Resource(); - bool createContexts(); - void clearContexts(); - void loadResource(ResourceContext *context, uint32 resourceId, byte*&resourceBuffer, size_t &resourceSize); - size_t getResourceSize(ResourceContext *context, uint32 resourceId); - uint32 convertResourceId(uint32 resourceId); - - void loadGlobalResources(int chapter, int actorsEntrance); - - ResourceContext *getContext(uint16 fileType, int serial = 0) { - int i; - for (i = 0; i < _contextsCount; i++) { - if ((_contexts[i].fileType & fileType) && _contexts[i].serial == serial) { - return &_contexts[i]; - } - } - return NULL; - } - - bool validResourceId(ResourceContext *context, uint32 resourceId) const { - return (resourceId < context->count); - } - - size_t getResourceSize(ResourceContext *context, uint32 resourceId) const { - return getResourceData(context, resourceId)->size; - } - - size_t getResourceOffset(ResourceContext *context, uint32 resourceId) const { - return getResourceData(context, resourceId)->offset; - } - - ResourceData *getResourceData(ResourceContext *context, uint32 resourceId) const { - if (!validResourceId(context, resourceId)) { - warning("Resource::getResourceData() wrong resourceId %d", resourceId); - assert(0); - } - return &context->table[resourceId]; - } - -private: - SagaEngine *_vm; - ResourceContext *_contexts; - int _contextsCount; - - bool loadContext(ResourceContext *context); - bool loadMacContext(ResourceContext *context); - bool loadSagaContext(ResourceContext *context, uint32 contextOffset, uint32 contextSize); - - -public: - MetaResource _metaResource; -}; - -} // End of namespace Saga - -#endif diff --git a/saga/saga.cpp b/saga/saga.cpp deleted file mode 100644 index 4adda480c6..0000000000 --- a/saga/saga.cpp +++ /dev/null @@ -1,505 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ -#include "common/stdafx.h" - -#include "base/gameDetector.h" -#include "base/plugins.h" -#include "backends/fs/fs.h" - -#include "common/file.h" -#include "common/config-manager.h" -#include "common/system.h" - -#include "sound/mixer.h" - -#include "saga/saga.h" - -#include "saga/rscfile.h" -#include "saga/gfx.h" -#include "saga/render.h" -#include "saga/actor.h" -#include "saga/animation.h" -#include "saga/console.h" -#include "saga/events.h" -#include "saga/font.h" -#include "saga/interface.h" -#include "saga/isomap.h" -#include "saga/puzzle.h" -#include "saga/script.h" -#include "saga/scene.h" -#include "saga/sndres.h" -#include "saga/sprite.h" -#include "saga/sound.h" -#include "saga/music.h" -#include "saga/palanim.h" -#include "saga/objectmap.h" -#include "saga/resnames.h" - -static const GameSettings saga_games[] = { - {"ite", "Inherit the Earth", 0}, - {"ihnm", "I Have No Mouth and I Must Scream", GF_DEFAULT_TO_1X_SCALER }, - {0, 0, 0} -}; - -GameList Engine_SAGA_gameList() { - GameList games; - const GameSettings *g = saga_games; - - while (g->gameid) { - games.push_back(*g); - g++; - } - - return games; -} - -DetectedGameList Engine_SAGA_detectGames(const FSList &fslist) { - return Saga::GAME_ProbeGame(fslist); -} - -Engine *Engine_SAGA_create(GameDetector *detector, OSystem *syst) { - return new Saga::SagaEngine(detector, syst); -} - -REGISTER_PLUGIN(SAGA, "SAGA Engine") - -namespace Saga { - -#define MAX_TIME_DELTA 100 - -SagaEngine::SagaEngine(GameDetector *detector, OSystem *syst) - : Engine(syst), - _targetName(detector->_targetName) { - - _leftMouseButtonPressed = _rightMouseButtonPressed = false; - - _console = NULL; - _quit = false; - - _resource = NULL; - _sndRes = NULL; - _events = NULL; - _font = NULL; - _sprite = NULL; - _anim = NULL; - _script = NULL; - _interface = NULL; - _actor = NULL; - _palanim = NULL; - _scene = NULL; - _isoMap = NULL; - _gfx = NULL; - _console = NULL; - _render = NULL; - _music = NULL; - _sound = NULL; - _puzzle = NULL; - - _frameCount = 0; - _globalFlags = 0; - memset(_ethicsPoints, 0, sizeof(_ethicsPoints)); - - // The Linux version of Inherit the Earth puts all data files in an - // 'itedata' sub-directory, except for voices.rsc - Common::File::addDefaultDirectory(_gameDataPath + "itedata/"); - - // The Windows version of Inherit the Earth puts various data files in - // other subdirectories. - Common::File::addDefaultDirectory(_gameDataPath + "graphics/"); - Common::File::addDefaultDirectory(_gameDataPath + "music/"); - Common::File::addDefaultDirectory(_gameDataPath + "sound/"); - - // The Multi-OS version puts the voices file in the root directory of - // the CD. The rest of the data files are in game/itedata - Common::File::addDefaultDirectory(_gameDataPath + "game/itedata/"); - - // Mac CD Wyrmkeep - Common::File::addDefaultDirectory(_gameDataPath + "patch/"); - - // Setup mixer - if (!_mixer->isReady()) { - warning("Sound initialization failed."); - } - - _displayClip.left = _displayClip.top = 0; -} - -SagaEngine::~SagaEngine() { - if (_scene != NULL) { - if (_scene->isSceneLoaded()) { - _scene->endScene(); - } - } - - delete _puzzle; - delete _sndRes; - delete _events; - delete _font; - delete _sprite; - delete _anim; - delete _script; - delete _interface; - delete _actor; - delete _palanim; - delete _scene; - delete _isoMap; - delete _render; - delete _music; - delete _sound; - delete _gfx; - delete _console; - - delete _resource; -} - -void SagaEngine::errorString(const char *buf1, char *buf2) { - strcpy(buf2, buf1); -} - -int SagaEngine::init(GameDetector &detector) { - _soundVolume = ConfMan.getInt("sfx_volume") / 25; - _musicVolume = ConfMan.getInt("music_volume") / 25; - _subtitlesEnabled = ConfMan.getBool("subtitles"); - _readingSpeed = ConfMan.getInt("talkspeed"); - _copyProtection = ConfMan.getBool("copy_protection"); - - if (_readingSpeed > 3) - _readingSpeed = 0; - - _resource = new Resource(this); - - // Add some default directories - // Win32 demo & full game - Common::File::addDefaultDirectory("graphics"); - Common::File::addDefaultDirectory("music"); - Common::File::addDefaultDirectory("sound"); - - // Linux demo - Common::File::addDefaultDirectory("itedata"); - - // Mac demos & full game - Common::File::addDefaultDirectory("patch"); - - // Process command line - - // Detect game and open resource files - if (!initGame()) { - return FAILURE; - } - - // Initialize engine modules - _sndRes = new SndRes(this); - _events = new Events(this); - _font = new Font(this); - _sprite = new Sprite(this); - _anim = new Anim(this); - _script = new Script(this); - _interface = new Interface(this); // requires script module - _scene = new Scene(this); - _actor = new Actor(this); - _palanim = new PalAnim(this); - _isoMap = new IsoMap(this); - _puzzle = new Puzzle(this); - - // System initialization - - _previousTicks = _system->getMillis(); - - // Initialize graphics - _gfx = new Gfx(this, _system, getDisplayWidth(), getDisplayHeight(), detector); - - // Graphics driver should be initialized before console - _console = new Console(this); - - // Graphics should be initialized before music - int midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); - bool native_mt32 = ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32")); - bool adlib = (midiDriver == MD_ADLIB); - - MidiDriver *driver = MidiDriver::createMidi(midiDriver); - if (native_mt32) - driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE); - - _music = new Music(this, _mixer, driver, _musicVolume); - _music->setNativeMT32(native_mt32); - _music->setAdlib(adlib); - - if (!_musicVolume) { - debug(1, "Music disabled."); - } - - _render = new Render(this, _system); - if (!_render->initialized()) { - return FAILURE; - } - - // Initialize system specific sound - _sound = new Sound(this, _mixer, _soundVolume); - if (!_soundVolume) { - debug(1, "Sound disabled."); - } - - _interface->converseInit(); - _script->setVerb(_script->getVerbType(kVerbWalkTo)); - - _music->setVolume(-1, 1); - - _gfx->initPalette(); - - // FIXME: This is the ugly way of reducing redraw overhead. It works - // well for 320x200 but it's unclear how well it will work for - // 640x480. - - if (getGameType() == GType_ITE) - _system->setFeatureState(OSystem::kFeatureAutoComputeDirtyRects, true); - - return SUCCESS; -} - -int SagaEngine::go() { - int msec = 0; - - _previousTicks = _system->getMillis(); - - if (ConfMan.hasKey("start_scene")) { - _scene->changeScene(ConfMan.getInt("start_scene"), 0, kTransitionNoFade); - } else if (ConfMan.hasKey("boot_param")) { - if (getGameType() == GType_ITE) - _interface->addToInventory(_actor->objIndexToId(ITE_OBJ_MAGIC_HAT)); - _scene->changeScene(ConfMan.getInt("boot_param"), 0, kTransitionNoFade); - } else if (ConfMan.hasKey("save_slot")) { - // First scene sets up palette - _scene->changeScene(getStartSceneNumber(), 0, kTransitionNoFade); - _events->handleEvents(0); // Process immediate events - - char *fileName; - fileName = calcSaveFileName(ConfMan.getInt("save_slot")); - load(fileName); - _interface->setMode(kPanelMain); - } else { - _framesEsc = 0; - _scene->startScene(); - } - - uint32 currentTicks; - - while (!_quit) { - if (_console->isAttached()) - _console->onFrame(); - - if (_render->getFlags() & RF_RENDERPAUSE) { - // Freeze time while paused - _previousTicks = _system->getMillis(); - } else { - currentTicks = _system->getMillis(); - // Timer has rolled over after 49 days - if (currentTicks < _previousTicks) - msec = 0; - else { - msec = currentTicks - _previousTicks; - _previousTicks = currentTicks; - } - if (msec > MAX_TIME_DELTA) { - msec = MAX_TIME_DELTA; - } - - // Since Puzzle is actorless, we do it here - if (_puzzle->isActive()) { - _actor->handleSpeech(msec); - } else if (!_scene->isInIntro()) { - if (_interface->getMode() == kPanelMain || - _interface->getMode() == kPanelConverse || - _interface->getMode() == kPanelCutaway || - _interface->getMode() == kPanelNull || - _interface->getMode() == kPanelChapterSelection) - _actor->direct(msec); - } - - _events->handleEvents(msec); - _script->executeThreads(msec); - } - // Per frame processing - _render->drawScene(); - _system->delayMillis(10); - } - - return 0; -} - -void SagaEngine::loadStrings(StringsTable &stringsTable, const byte *stringsPointer, size_t stringsLength) { - uint16 stringsCount; - size_t offset; - int i; - - if (stringsLength == 0) { - error("SagaEngine::loadStrings() Error loading strings list resource"); - } - - stringsTable.stringsPointer = (byte*)malloc(stringsLength); - memcpy(stringsTable.stringsPointer, stringsPointer, stringsLength); - - - MemoryReadStreamEndian scriptS(stringsTable.stringsPointer, stringsLength, isBigEndian()); //TODO: get endianess from context - - offset = scriptS.readUint16(); - stringsCount = offset / 2; - stringsTable.strings = (const char **)malloc(stringsCount * sizeof(*stringsTable.strings)); - i = 0; - scriptS.seek(0); - while (i < stringsCount) { - offset = scriptS.readUint16(); - if (offset == stringsLength) { - stringsCount = i; - stringsTable.strings = (const char **)realloc(stringsTable.strings, stringsCount * sizeof(*stringsTable.strings)); - break; - } - if (offset > stringsLength) { - error("SagaEngine::loadStrings wrong strings table"); - } - stringsTable.strings[i] = (const char *)stringsTable.stringsPointer + offset; - debug(9, "string[%i]=%s", i, stringsTable.strings[i]); - i++; - } - stringsTable.stringsCount = stringsCount; -} - -const char *SagaEngine::getObjectName(uint16 objectId) { - ActorData *actor; - ObjectData *obj; - const HitZone *hitZone; - switch (objectTypeId(objectId)) { - case kGameObjectObject: - obj = _actor->getObj(objectId); - if (getGameType() == GType_ITE) - return _script->_mainStrings.getString(obj->_nameIndex); - return _actor->_objectsStrings.getString(obj->_nameIndex); - case kGameObjectActor: - actor = _actor->getActor(objectId); - return _actor->_actorsStrings.getString(actor->_nameIndex); - case kGameObjectHitZone: - hitZone = _scene->_objectMap->getHitZone(objectIdToIndex(objectId)); - return _scene->_sceneStrings.getString(hitZone->getNameIndex()); - } - warning("SagaEngine::getObjectName name not found for 0x%X", objectId); - return NULL; -} - -const char *SagaEngine::getTextString(int textStringId) { - const char *string; - int lang = (getLanguage() == Common::DE_DEU) ? 1 : 0; - - string = ITEinterfaceTextStrings[lang][textStringId]; - if (!string) - string = ITEinterfaceTextStrings[0][textStringId]; - - return string; -} - -void SagaEngine::getExcuseInfo(int verb, const char *&textString, int &soundResourceId) { - textString = NULL; - - if (verb == _script->getVerbType(kVerbPickUp)) { - textString = getTextString(kTextICantPickup); - soundResourceId = RID_BOAR_VOICE_007; - } else - if (verb == _script->getVerbType(kVerbLookAt)) { - textString = getTextString(kTextNothingSpecial); - soundResourceId = RID_BOAR_VOICE_006; - } - if (verb == _script->getVerbType(kVerbOpen)) { - textString = getTextString(kTextNoPlaceToOpen); - soundResourceId = RID_BOAR_VOICE_000; - } - if (verb == _script->getVerbType(kVerbClose)) { - textString = getTextString(kTextNoOpening); - soundResourceId = RID_BOAR_VOICE_002; - } - if (verb == _script->getVerbType(kVerbUse)) { - textString = getTextString(kTextDontKnow); - soundResourceId = RID_BOAR_VOICE_005; - } -} - -ColorId SagaEngine::KnownColor2ColorId(KnownColor knownColor) { - ColorId colorId = kITEColorTransBlack; - - if (getGameType() == GType_ITE) { - switch (knownColor) { - case(kKnownColorTransparent): - colorId = kITEColorTransBlack; - break; - - case (kKnownColorBrightWhite): - colorId = kITEColorBrightWhite; - break; - case (kKnownColorBlack): - colorId = kITEColorBlack; - break; - - case (kKnownColorSubtitleTextColor): - colorId = (ColorId)255; - break; - case (kKnownColorVerbText): - colorId = kITEColorBlue; - break; - case (kKnownColorVerbTextShadow): - colorId = kITEColorBlack; - break; - case (kKnownColorVerbTextActive): - colorId = (ColorId)96; - break; - - default: - error("SagaEngine::KnownColor2ColorId unknown color %i", knownColor); - } - } else if (getGameType() == GType_IHNM) { - switch (knownColor) - { - case(kKnownColorTransparent): - colorId = kITEColorTransBlack; - break; - - case (kKnownColorBlack): - colorId = kIHNMColorBlack; - break; - - case (kKnownColorVerbText): - colorId = (ColorId)253; - break; - case (kKnownColorVerbTextShadow): - colorId = (ColorId)15; - break; - case (kKnownColorVerbTextActive): - colorId = (ColorId)252; - break; - - default: - error("SagaEngine::KnownColor2ColorId unknown color %i", knownColor); - } - } - return colorId; -} - - -} // End of namespace Saga diff --git a/saga/saga.h b/saga/saga.h deleted file mode 100644 index f2111265bd..0000000000 --- a/saga/saga.h +++ /dev/null @@ -1,741 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -#ifndef SAGA_H -#define SAGA_H - -#include "base/engine.h" -#include "base/plugins.h" - -#include "common/stream.h" - -#include "saga/gfx.h" -#include "saga/list.h" - -namespace Saga { - -class SndRes; -class Sound; -class Music; -class Anim; -class Render; -class IsoMap; -class Gfx; -class Script; -class Actor; -class Font; -class Sprite; -class Scene; -class Interface; -class Console; -class Events; -class PalAnim; -class Puzzle; -class Resource; - -struct ResourceContext; -struct StringList; - -//#define MIN_IMG_RLECODE 3 -//#define MODEX_SCANLINE_LIMIT 200 //TODO: remove - -#define SAGA_IMAGE_DATA_OFFSET 776 -#define SAGA_IMAGE_HEADER_LEN 8 - -#define MAXPATH 512 //TODO: remove - -#define SAVE_TITLE_SIZE 28 -#define MAX_SAVES 96 -#define MAX_FILE_NAME 256 - -#define ID_NOTHING 0 -#define ID_PROTAG 1 -#define OBJECT_TYPE_SHIFT 13 -#define OBJECT_TYPE_MASK ((1 << OBJECT_TYPE_SHIFT) - 1) - -#define OBJ_SPRITE_BASE 9 - -#define memoryError(Place) error("%s Memory allocation error.", Place) - -enum ERRORCODE { - MEM = -2,//todo: remove - FAILURE = -1, - SUCCESS = 0 -}; - -enum SAGAGameType { - GType_ITE, - GType_IHNM -}; - -enum GameObjectTypes { - kGameObjectNone = 0, - kGameObjectActor = 1, - kGameObjectObject = 2, - kGameObjectHitZone = 3, - kGameObjectStepZone = 4 -}; - -enum ScriptTimings { - kScriptTimeTicksPerSecond = (728L/10L), - kRepeatSpeedTicks = (728L/10L)/3, - kNormalFadeDuration = 320, // 64 steps, 5 msec each - kQuickFadeDuration = 64, // 64 steps, 1 msec each - kPuzzleHintTime = 30000000L // 30 secs. used in timer -}; - -enum Directions { - kDirUp = 0, - kDirUpRight = 1, - kDirRight = 2, - kDirDownRight = 3, - kDirDown = 4, - kDirDownLeft = 5, - kDirLeft = 6, - kDirUpLeft = 7 -}; - -enum HitZoneFlags { - kHitZoneEnabled = (1 << 0), // Zone is enabled - kHitZoneExit = (1 << 1), // Causes char to exit - - // The following flag causes the zone to act differently. - // When the actor hits the zone, it will immediately begin walking - // in the specified direction, and the actual specified effect of - // the zone will be delayed until the actor leaves the zone. - kHitZoneAutoWalk = (1 << 2), - - // When set on a hit zone, this causes the character not to walk - // to the object (but they will look at it). - kHitZoneNoWalk = (1 << 2), - - // zone activates only when character stops walking - kHitZoneTerminus = (1 << 3), - - // Hit zones only - when the zone is clicked on it projects the - // click point downwards from the middle of the zone until it - // reaches the lowest point in the zone. - kHitZoneProject = (1 << 3) -}; - - -enum PanelButtonType { - kPanelButtonVerb = 1 << 0, - kPanelButtonArrow = 1 << 1, - kPanelButtonConverseText = 1 << 2, - kPanelButtonInventory = 1 << 3, - - kPanelButtonOption = 1 << 4, - kPanelButtonOptionSlider = 1 << 5, - kPanelButtonOptionSaveFiles = 1 << 6, - kPanelButtonOptionText = 1 << 7, - - kPanelButtonQuit = 1 << 8, - kPanelButtonQuitText = 1 << 9, - - kPanelButtonLoad = 1 << 10, - kPanelButtonLoadText = 1 << 11, - - kPanelButtonSave = 1 << 12, - kPanelButtonSaveText = 1 << 13, - kPanelButtonSaveEdit = 1 << 14, - - kPanelButtonProtectText = 1 << 15, - kPanelButtonProtectEdit = 1 << 16, - - kPanelAllButtons = 0xFFFFF -}; - -enum TextStringIds { - kTextWalkTo, - kTextLookAt, - kTextPickUp, - kTextTalkTo, - kTextOpen, - kTextClose, - kTextUse, - kTextGive, - kTextOptions, - kTextTest, - kTextDemo, - kTextHelp, - kTextQuitGame, - kTextFast, - kTextSlow, - kTextOn, - kTextOff, - kTextContinuePlaying, - kTextLoad, - kTextSave, - kTextGameOptions, - kTextReadingSpeed, - kTextMusic, - kTextSound, - kTextCancel, - kTextQuit, - kTextOK, - kTextMid, - kTextClick, - kText10Percent, - kText20Percent, - kText30Percent, - kText40Percent, - kText50Percent, - kText60Percent, - kText70Percent, - kText80Percent, - kText90Percent, - kTextMax, - kTextQuitTheGameQuestion, - kTextLoadSuccessful, - kTextEnterSaveGameName, - kTextGiveTo, - kTextUseWidth, - kTextNewSave, - kTextICantPickup, - kTextNothingSpecial, - kTextNoPlaceToOpen, - kTextNoOpening, - kTextDontKnow, - kTextShowDialog, - kTextEnterProtectAnswer -}; - -struct ImageHeader { - int width; - int height; -}; - -struct StringsTable { - byte *stringsPointer; - int stringsCount; - const char **strings; - - const char *getString(int index) const { - if ((stringsCount <= index) || (index < 0)) { - error("StringList::getString wrong index 0x%X (%d)", index, stringsCount); - } - return strings[index]; - } - - void freeMem() { - free(strings); - free(stringsPointer); - memset(this, 0, sizeof(*this)); - } - - StringsTable() { - memset(this, 0, sizeof(*this)); - } - ~StringsTable() { - freeMem(); - } -}; - -enum GameIds { - // Dreamers Guild - GID_ITE_DEMO_G = 0, - GID_ITE_DISK_G, - GID_ITE_DISK_G2, - GID_ITE_CD_G, - GID_ITE_CD_G2, - GID_ITE_MACCD_G, - - // Wyrmkeep - GID_ITE_CD, // data for Win rerelease is same as in old DOS - GID_ITE_WINCD, // but it has a bunch of patch files - GID_ITE_MACCD, - GID_ITE_LINCD, - GID_ITE_MULTICD, // Wyrmkeep combined Windows/Mac/Linux version - GID_ITE_WINDEMO1, // older Wyrmkeep windows demo - GID_ITE_MACDEMO1, // older Wyrmkeep mac demo - GID_ITE_LINDEMO, - GID_ITE_WINDEMO2, - GID_ITE_MACDEMO2, - - // German - GID_ITE_DISK_DE, - GID_ITE_DISK_DE2, - GID_ITE_AMIGACD_DE, // TODO - GID_ITE_OLDMAC_DE, // TODO - GID_ITE_AMIGA_FL_DE,// TODO - GID_ITE_CD_DE, // reported by mld. Bestsellergamers cover disk - GID_ITE_CD_DE2, - GID_ITE_AMIGA_AGA_DEMO, // TODO - GID_ITE_AMIGA_ECS_DEMO, // TODO - - GID_IHNM_DEMO, - GID_IHNM_CD, - GID_IHNM_CD_DE, // reported by mld. German retail - GID_IHNM_CD_ES, - GID_IHNM_CD_RU, - GID_IHNM_CD_FR -}; - -enum GameFileTypes { - GAME_RESOURCEFILE = 1 << 0, - GAME_SCRIPTFILE = 1 << 1, - GAME_SOUNDFILE = 1 << 2, - GAME_VOICEFILE = 1 << 3, - GAME_DEMOFILE = 1 << 4, - GAME_MUSICFILE = 1 << 5, - GAME_MUSICFILE_GM = 1 << 6, - GAME_MUSICFILE_FM = 1 << 7, - GAME_PATCHFILE = 1 << 8, - GAME_MACBINARY = 1 << 9, - GAME_SWAPENDIAN = 1 << 10 -}; - -enum GameSoundTypes { - kSoundPCM = 0, - kSoundVOX = 1, - kSoundVOC = 2, - kSoundWAV = 3, - kSoundMacPCM = 4 -}; - -enum GameFeatures { - GF_BIG_ENDIAN_DATA = 1 << 0, - GF_WYRMKEEP = 1 << 1, - GF_CD_FX = 1 << 2, - GF_SCENE_SUBSTITUTES = 1 << 3 -}; - -enum ColorId { - kITEColorTransBlack = 0x00, - kITEColorBrightWhite = 0x01, - kITEColorWhite = 0x02, - kITEColorLightGrey = 0x04, - kITEColorGrey = 0x0a, - kITEColorDarkGrey = 0x0b, - kITEColorDarkGrey0C = 0x0C, - kITEColorBlack = 0x0f, - kITEColorRed = 0x65, - kITEColorDarkBlue8a = 0x8a, - kITEColorBlue89 = 0x89, - kITEColorLightBlue92 = 0x92, - kITEColorBlue = 0x93, - kITEColorLightBlue94 = 0x94, - kITEColorLightBlue96 = 0x96, - kITEColorGreen = 0xba, - - kIHNMColorBlack = 0xfa, - kIHNMColorPortrait = 0xfe -}; - -enum KnownColor { - kKnownColorTransparent, - kKnownColorBrightWhite, - kKnownColorBlack, - - kKnownColorSubtitleTextColor, - kKnownColorVerbText, - kKnownColorVerbTextShadow, - kKnownColorVerbTextActive -}; - -struct GameSoundInfo { - GameSoundTypes resourceType; - long frequency; - int sampleBits; - bool stereo; - bool isBigEndian; - bool isSigned; -}; - -struct GameFontDescription { - uint32 fontResourceId; -}; - -struct GameResourceDescription { - uint32 sceneLUTResourceId; - uint32 moduleLUTResourceId; - uint32 mainPanelResourceId; - uint32 conversePanelResourceId; - uint32 optionPanelResourceId; - uint32 mainSpritesResourceId; - uint32 mainPanelSpritesResourceId; - uint32 defaultPortraitsResourceId; - uint32 mainStringsResourceId; - uint32 actorsStringsResourceId; -}; - -struct GameFileDescription { - const char *fileName; - uint16 fileType; -}; - -struct GamePatchDescription { - const char *fileName; - uint16 fileType; - uint32 resourceId; - GameSoundInfo *soundInfo; -}; - -struct PanelButton { - PanelButtonType type; - int xOffset; - int yOffset; - int width; - int height; - int id; - uint16 ascii; - int state; - int upSpriteNumber; - int downSpriteNumber; - int overSpriteNumber; -}; - -struct GameDisplayInfo { - int logicalWidth; - int logicalHeight; - - int pathStartY; - int sceneHeight; - - int statusXOffset; - int statusYOffset; - int statusWidth; - int statusHeight; - int statusTextY; - int statusTextColor; - int statusBGColor; - - int saveReminderXOffset; - int saveReminderYOffset; - int saveReminderWidth; - int saveReminderHeight; - int saveReminderFirstSpriteNumber; - int saveReminderSecondSpriteNumber; - - int leftPortraitXOffset; - int leftPortraitYOffset; - int rightPortraitXOffset; - int rightPortraitYOffset; - - int inventoryUpButtonIndex; - int inventoryDownButtonIndex; - int inventoryRows; - int inventoryColumns; - - int mainPanelXOffset; - int mainPanelYOffset; - int mainPanelButtonsCount; - PanelButton *mainPanelButtons; - - int converseMaxTextWidth; - int converseTextHeight; - int converseTextLines; - int converseUpButtonIndex; - int converseDownButtonIndex; - - int conversePanelXOffset; - int conversePanelYOffset; - int conversePanelButtonsCount; - PanelButton *conversePanelButtons; - - int optionSaveFilePanelIndex; - int optionSaveFileSliderIndex; - uint optionSaveFileVisible; - - int optionPanelXOffset; - int optionPanelYOffset; - int optionPanelButtonsCount; - PanelButton *optionPanelButtons; - - int quitPanelXOffset; - int quitPanelYOffset; - int quitPanelWidth; - int quitPanelHeight; - int quitPanelButtonsCount; - PanelButton *quitPanelButtons; - - int loadPanelXOffset; - int loadPanelYOffset; - int loadPanelWidth; - int loadPanelHeight; - int loadPanelButtonsCount; - PanelButton *loadPanelButtons; - - int saveEditIndex; - int savePanelXOffset; - int savePanelYOffset; - int savePanelWidth; - int savePanelHeight; - int savePanelButtonsCount; - PanelButton *savePanelButtons; - - int protectEditIndex; - int protectPanelXOffset; - int protectPanelYOffset; - int protectPanelWidth; - int protectPanelHeight; - int protectPanelButtonsCount; - PanelButton *protectPanelButtons; -}; - - -struct GameDescription { - const char *name; - SAGAGameType gameType; - GameIds gameId; - const char *title; - GameDisplayInfo *gameDisplayInfo; - int startSceneNumber; - GameResourceDescription *resourceDescription; - int filesCount; - GameFileDescription *filesDescriptions; - int fontsCount; - GameFontDescription *fontDescriptions; - GameSoundInfo *voiceInfo; - GameSoundInfo *sfxInfo; - GameSoundInfo *musicInfo; - int patchesCount; - GamePatchDescription *patchDescriptions; - uint32 features; - Common::Language language; - Common::Platform platform; - - GameSettings toGameSettings() const { - GameSettings dummy = { name, title, features }; - return dummy; - } -}; - -struct SaveFileData { - char name[SAVE_TITLE_SIZE]; - uint slotNumber; -}; - -struct SaveGameHeader { - uint32 type; - uint32 size; - uint32 version; - char name[SAVE_TITLE_SIZE]; -}; - -inline int ticksToMSec(int tick) { - return tick * 1000 / kScriptTimeTicksPerSecond; -} - -inline int clamp(int minValue, int value, int maxValue) { - if (value <= minValue) { - return minValue; - } else { - if (value >= maxValue) { - return maxValue; - } else { - return value; - } - } -} - -inline int integerCompare(int i1, int i2) { - return ((i1) > (i2) ? 1 : ((i1) < (i2) ? -1 : 0)); -} - -inline int objectTypeId(uint16 objectId) { - return objectId >> OBJECT_TYPE_SHIFT; -} - -inline int objectIdToIndex(uint16 objectId) { - return OBJECT_TYPE_MASK & objectId; -} - -inline uint16 objectIndexToId(int type, int index) { - return (type << OBJECT_TYPE_SHIFT) | (OBJECT_TYPE_MASK & index); -} - - -DetectedGameList GAME_ProbeGame(const FSList &fslist, int **matches = NULL); - -class SagaEngine : public Engine { - friend class Scene; - - void errorString(const char *buf_input, char *buf_output); - -protected: - int go(); - int init(GameDetector &detector); -public: - SagaEngine(GameDetector * detector, OSystem * syst); - virtual ~SagaEngine(); - void shutDown() { _quit = true; } - - void save(const char *fileName, const char *saveName); - void load(const char *fileName); - uint32 getCurrentLoadVersion() { - return _saveHeader.version; - } - void fillSaveList(); - char *calcSaveFileName(uint slotNumber); - - SaveFileData *getSaveFile(uint idx); - uint getSaveSlotNumber(uint idx); - uint getNewSaveSlotNumber(); - bool locateSaveFile(char *saveName, uint &titleNumber); - bool isSaveListFull() const { - return _saveFilesMaxCount == _saveFilesCount; - } - uint getSaveFilesCount() const { - return isSaveListFull() ? _saveFilesCount : _saveFilesCount + 1; - } - - int16 _framesEsc; - - uint32 _globalFlags; - int16 _ethicsPoints[8]; - int _spiritualBarometer; - - int _soundVolume; - int _musicVolume; - bool _subtitlesEnabled; - int _readingSpeed; - - bool _copyProtection; - - SndRes *_sndRes; - Sound *_sound; - Music *_music; - Anim *_anim; - Render *_render; - IsoMap *_isoMap; - Gfx *_gfx; - Script *_script; - Actor *_actor; - Font *_font; - Sprite *_sprite; - Scene *_scene; - Interface *_interface; - Console *_console; - Events *_events; - PalAnim *_palanim; - Puzzle *_puzzle; - Resource *_resource; - - - /** Random number generator */ - Common::RandomSource _rnd; - -private: - int decodeBGImageRLE(const byte *inbuf, size_t inbuf_len, byte *outbuf, size_t outbuf_len); - int flipImage(byte *img_buf, int columns, int scanlines); - int unbankBGImage(byte *dest_buf, const byte *src_buf, int columns, int scanlines); - uint32 _previousTicks; - -public: - int decodeBGImage(const byte *image_data, size_t image_size, - byte **output_buf, size_t *output_buf_len, int *w, int *h, bool flip = false); - const byte *getImagePal(const byte *image_data, size_t image_size); - void loadStrings(StringsTable &stringsTable, const byte *stringsPointer, size_t stringsLength); - - const char *getObjectName(uint16 objectId); -public: - int processInput(void); - const Point &mousePos() const { - return _mousePos; - } - - const bool leftMouseButtonPressed() const { - return _leftMouseButtonPressed; - } - - const bool rightMouseButtonPressed() const { - return _rightMouseButtonPressed; - } - - const bool mouseButtonPressed() const { - return _leftMouseButtonPressed || _rightMouseButtonPressed; - } - - private: - Common::String _targetName; - - uint _saveFilesMaxCount; - uint _saveFilesCount; - SaveFileData _saveFiles[MAX_SAVES]; - bool _saveMarks[MAX_SAVES]; - SaveGameHeader _saveHeader; - - Point _mousePos; - bool _leftMouseButtonPressed; - bool _rightMouseButtonPressed; - - bool _quit; - -//current game description - int _gameNumber; - GameDescription *_gameDescription; - Common::Rect _displayClip; - -protected: - GameDisplayInfo _gameDisplayInfo; - -public: - int32 _frameCount; - -public: - bool initGame(void); -public: - const GameDescription *getGameDescription() const { return _gameDescription; } - const bool isBigEndian() const { return (_gameDescription->features & GF_BIG_ENDIAN_DATA) != 0; } - const bool isMacResources() const { return (getPlatform() == Common::kPlatformMacintosh); } - const GameResourceDescription *getResourceDescription() { return _gameDescription->resourceDescription; } - const GameSoundInfo *getVoiceInfo() const { return _gameDescription->voiceInfo; } - const GameSoundInfo *getSfxInfo() const { return _gameDescription->sfxInfo; } - const GameSoundInfo *getMusicInfo() const { return _gameDescription->musicInfo; } - - const GameFontDescription *getFontDescription(int index) { - assert(index < _gameDescription->fontsCount); - return &_gameDescription->fontDescriptions[index]; - } - int getFontsCount() const { return _gameDescription->fontsCount; } - - int getGameId() const { return _gameDescription->gameId; } - int getGameType() const { return _gameDescription->gameType; } - uint32 getFeatures() const { return _gameDescription->features; } - Common::Language getLanguage() const { return _gameDescription->language; } - Common::Platform getPlatform() const { return _gameDescription->platform; } - int getGameNumber() const { return _gameNumber; } - int getStartSceneNumber() const { return _gameDescription->startSceneNumber; } - - - const Common::Rect &getDisplayClip() const { return _displayClip;} - int getDisplayWidth() const { return _gameDisplayInfo.logicalWidth; } - int getDisplayHeight() const { return _gameDisplayInfo.logicalHeight;} - const GameDisplayInfo & getDisplayInfo() { return _gameDisplayInfo; } - - const char *getTextString(int textStringId); - void getExcuseInfo(int verb, const char *&textString, int &soundResourceId); - -private: - -public: - ColorId KnownColor2ColorId(KnownColor knownColor); -}; - - -} // End of namespace Saga - -#endif diff --git a/saga/saveload.cpp b/saga/saveload.cpp deleted file mode 100644 index 761ae49521..0000000000 --- a/saga/saveload.cpp +++ /dev/null @@ -1,299 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -#include "common/stdafx.h" - -#include "common/config-manager.h" -#include "common/savefile.h" -#include "common/system.h" -#include "common/file.h" - -#include "saga/saga.h" -#include "saga/actor.h" -#include "saga/events.h" -#include "saga/interface.h" -#include "saga/isomap.h" -#include "saga/music.h" -#include "saga/render.h" -#include "saga/resnames.h" -#include "saga/scene.h" -#include "saga/script.h" - -#define CURRENT_SAGA_VER 5 - -namespace Saga { - -static SaveFileData emptySlot = { - "", 0 -}; - -//TODO: -// - delete savegame - -char* SagaEngine::calcSaveFileName(uint slotNumber) { - static char name[MAX_FILE_NAME]; - sprintf(name, "%s.s%02d", _targetName.c_str(), slotNumber); - return name; -} - -SaveFileData *SagaEngine::getSaveFile(uint idx) { - if (idx >= _saveFilesMaxCount) { - error("getSaveFileName wrong idx"); - } - if (isSaveListFull()) { - return &_saveFiles[_saveFilesCount - idx - 1]; - } else { - if (!emptySlot.name[0]) - strcpy(emptySlot.name, getTextString(kTextNewSave)); - - return (idx == 0) ? &emptySlot : &_saveFiles[_saveFilesCount - idx]; - } -} - -bool SagaEngine::locateSaveFile(char *saveName, uint &titleNumber) { - uint i; - for (i = 0; i < _saveFilesCount; i++) { - if (strcmp(saveName, _saveFiles[i].name) == 0) { - if (isSaveListFull()) { - titleNumber = _saveFilesCount - i - 1; - } else { - titleNumber = _saveFilesCount - i; - } - return true; - } - } - return false; -} - -uint SagaEngine::getNewSaveSlotNumber() { - uint i, j; - bool found; - if (isSaveListFull()) { - error("getNewSaveSlotNumber save list is full"); - } - for (i = 0; i < MAX_SAVES; i++) { - if (_saveMarks[i]) { - found = false; - for (j = 0; j < _saveFilesCount; j++) { - if (_saveFiles[j].slotNumber == i) { - found = true; - break; - } - } - if (!found) { - return i; - } - } - } - - error("getNewSaveSlotNumber save list is full"); -} - -void SagaEngine::fillSaveList() { - int i; - Common::InSaveFile *in; - char *name; - - name = calcSaveFileName(MAX_SAVES); - name[strlen(name) - 2] = 0; - _saveFileMan->listSavefiles(name, _saveMarks, MAX_SAVES); - - _saveFilesMaxCount = 0; - for (i = 0; i < MAX_SAVES; i++) { - if (_saveMarks[i]) { - _saveFilesMaxCount++; - } - _saveFiles[i].name[0] = 0; - _saveFiles[i].slotNumber = (uint)-1; - } - - _saveFilesCount = 0; - - i = 0; - while (i < MAX_SAVES) { - if (_saveMarks[i]) { - name = calcSaveFileName(i); - if ((in = _saveFileMan->openForLoading(name)) != NULL) { - in->read(&_saveHeader, sizeof(_saveHeader)); - - if (_saveHeader.type != MKID('SAGA')) { - error("SagaEngine::load wrong format"); - } - strcpy(_saveFiles[_saveFilesCount].name, _saveHeader.name); - _saveFiles[_saveFilesCount].slotNumber = i; - delete in; - _saveFilesCount++; - } - } - i++; - } -/* 4debug - for (i = 0; i < 14; i++) { - sprintf(_saveFiles[i].name,"test%i", i); - _saveFiles[i].slotNumber = i; - } - _saveFilesCount = 14; - _saveFilesMaxCount = 14; - */ -} - - -#define TITLESIZE 80 -void SagaEngine::save(const char *fileName, const char *saveName) { - Common::OutSaveFile *out; - char title[TITLESIZE]; - - if (!(out = _saveFileMan->openForSaving(fileName))) { - return; - } - - _saveHeader.type = MKID('SAGA'); - _saveHeader.size = 0; - _saveHeader.version = TO_LE_32(CURRENT_SAGA_VER); - strncpy(_saveHeader.name, saveName, SAVE_TITLE_SIZE); - - out->write(&_saveHeader, sizeof(_saveHeader)); - - // Original game title - memset(title, 0, TITLESIZE); - strncpy(title, getGameDescription()->title, TITLESIZE); - out->write(title, TITLESIZE); - - // Surrounding scene - out->writeSint32LE(_scene->getOutsetSceneNumber()); - - // Inset scene - out->writeSint32LE(_scene->currentSceneNumber()); - - if (getGameType() != GType_ITE) { - out->writeUint32LE(_globalFlags); - for (int i = 0; i < ARRAYSIZE(_ethicsPoints); i++) - out->writeSint16LE(_ethicsPoints[i]); - } - - _interface->saveState(out); - - _actor->saveState(out); - - out->writeSint16LE(_script->_commonBufferSize); - - out->write(_script->_commonBuffer, _script->_commonBufferSize); - - out->writeSint16LE(_isoMap->getMapPosition().x); - out->writeSint16LE(_isoMap->getMapPosition().y); - - out->flush(); - - // TODO: Check out->ioFailed() - - delete out; -} - -void SagaEngine::load(const char *fileName) { - Common::InSaveFile *in; - int commonBufferSize; - int sceneNumber, insetSceneNumber; - int mapx, mapy; - char title[TITLESIZE]; - - if (!(in = _saveFileMan->openForLoading(fileName))) { - return; - } - - in->read(&_saveHeader, sizeof(_saveHeader)); - - _saveHeader.size = FROM_LE_32(_saveHeader.size); - _saveHeader.version = FROM_LE_32(_saveHeader.version); - - // This save was written in native endianness (fix that, so warning will show up) - if (_saveHeader.version > CURRENT_SAGA_VER) { -#ifdef SCUMM_LITTLE_ENDIAN - _saveHeader.version = TO_BE_32(_saveHeader.version); -#else - _saveHeader.version = TO_LE_32(_saveHeader.version); -#endif - } - - debug(2, "Save version: %x", _saveHeader.version); - - if (_saveHeader.version < 4) - warning("This savegame is not endian-safe. There may be problems"); - - if (_saveHeader.type != MKID('SAGA')) { - error("SagaEngine::load wrong format"); - } - - if (_saveHeader.version > 4) { - in->read(title, TITLESIZE); - debug(0, "Save is for: %s", title); - } - - // Surrounding scene - sceneNumber = in->readSint32LE(); - - // Inset scene - insetSceneNumber = in->readSint32LE(); - - if (getGameType() != GType_ITE) { - _globalFlags = in->readUint32LE(); - for (int i = 0; i < ARRAYSIZE(_ethicsPoints); i++) - _ethicsPoints[i] = in->readSint16LE(); - } - - _interface->loadState(in); - - _actor->loadState(in); - - commonBufferSize = in->readSint16LE(); - in->read(_script->_commonBuffer, commonBufferSize); - - mapx = in->readSint16LE(); - mapy = in->readSint16LE(); - - delete in; - - // Mute volume to prevent outScene music play - int volume = _music->getVolume(); - _music->setVolume(0); - - _isoMap->setMapPosition(mapx, mapy); - - _scene->clearSceneQueue(); - _scene->changeScene(sceneNumber, ACTOR_NO_ENTRANCE, kTransitionNoFade); - - _events->handleEvents(0); //dissolve backgrounds - - if (insetSceneNumber != sceneNumber) { - _render->setFlag(RF_DISABLE_ACTORS); - _render->drawScene(); - _render->clearFlag(RF_DISABLE_ACTORS); - _scene->changeScene(insetSceneNumber, ACTOR_NO_ENTRANCE, kTransitionNoFade); - } - - _music->setVolume(volume); - - _interface->draw(); -} - -} // End of namespace Saga diff --git a/saga/scene.cpp b/saga/scene.cpp deleted file mode 100644 index 708800dc41..0000000000 --- a/saga/scene.cpp +++ /dev/null @@ -1,1283 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Scene management module -#include "saga/saga.h" - -#include "saga/gfx.h" -#include "saga/animation.h" -#include "saga/console.h" -#include "saga/interface.h" -#include "saga/events.h" -#include "saga/isomap.h" -#include "saga/objectmap.h" -#include "saga/palanim.h" -#include "saga/puzzle.h" -#include "saga/render.h" -#include "saga/script.h" -#include "saga/sound.h" -#include "saga/music.h" - -#include "saga/scene.h" -#include "saga/stream.h" -#include "saga/actor.h" -#include "saga/rscfile.h" -#include "saga/resnames.h" - -#include "graphics/ilbm.h" -#include "common/util.h" - -namespace Saga { - -static int initSceneDoors[SCENE_DOORS_MAX] = { - 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff -}; - -static SAGAResourceTypes ITESceneResourceTypes[26] = { - SAGA_ACTOR, - SAGA_OBJECT, - SAGA_BG_IMAGE, - SAGA_BG_MASK, -SAGA_UNKNOWN, - SAGA_STRINGS, - SAGA_OBJECT_MAP, - SAGA_ACTION_MAP, - SAGA_ISO_IMAGES, - SAGA_ISO_MAP, - SAGA_ISO_PLATFORMS, - SAGA_ISO_METATILES, - SAGA_ENTRY, -SAGA_UNKNOWN, - SAGA_ANIM, - SAGA_ANIM, - SAGA_ANIM, - SAGA_ANIM, - SAGA_ANIM, - SAGA_ANIM, - SAGA_ANIM, - SAGA_ANIM, - SAGA_ISO_MULTI, - SAGA_PAL_ANIM, - SAGA_FACES, - SAGA_PALETTE -}; - -static SAGAResourceTypes IHNMSceneResourceTypes[28] = { - SAGA_ACTOR, -SAGA_UNKNOWN, - SAGA_BG_IMAGE, - SAGA_BG_MASK, -SAGA_UNKNOWN, - SAGA_STRINGS, - SAGA_OBJECT_MAP, - SAGA_ACTION_MAP, - SAGA_ISO_IMAGES, - SAGA_ISO_MAP, - SAGA_ISO_PLATFORMS, - SAGA_ISO_METATILES, - SAGA_ENTRY, -SAGA_UNKNOWN, - SAGA_ANIM, - SAGA_ANIM, - SAGA_ANIM, - SAGA_ANIM, - SAGA_ANIM, - SAGA_ANIM, - SAGA_ANIM, - SAGA_ANIM, - SAGA_ANIM, - SAGA_ANIM, - SAGA_ISO_MULTI, - SAGA_PAL_ANIM, - SAGA_FACES, - SAGA_PALETTE -}; - -const char *SAGAResourceTypesString[] = { - "SAGA_UNKNOWN", - "SAGA_ACTOR", - "SAGA_OBJECT", - "SAGA_BG_IMAGE", - "SAGA_BG_MASK", - "SAGA_STRINGS", - "SAGA_OBJECT_MAP", - "SAGA_ACTION_MAP", - "SAGA_ISO_IMAGES", - "SAGA_ISO_MAP", - "SAGA_ISO_PLATFORMS", - "SAGA_ISO_METATILES", - "SAGA_ENTRY", - "SAGA_ANIM", - "SAGA_ISO_MULTI", - "SAGA_PAL_ANIM", - "SAGA_FACES", - "SAGA_PALETTE" -}; - -Scene::Scene(SagaEngine *vm) : _vm(vm) { - byte *sceneLUTPointer; - size_t sceneLUTLength; - uint32 resourceId; - int i; - - // Load scene module resource context - _sceneContext = _vm->_resource->getContext(GAME_RESOURCEFILE); - if (_sceneContext == NULL) { - error("Scene::Scene() scene context not found"); - } - - // Load scene lookup table - resourceId = _vm->_resource->convertResourceId(_vm->getResourceDescription()->sceneLUTResourceId); - debug(3, "Loading scene LUT from resource %i", resourceId); - _vm->_resource->loadResource(_sceneContext, resourceId, sceneLUTPointer, sceneLUTLength); - if (sceneLUTLength == 0) { - error("Scene::Scene() sceneLUTLength == 0"); - } - _sceneCount = sceneLUTLength / 2; - _sceneLUT = (int *)malloc(_sceneCount * sizeof(*_sceneLUT)); - if (_sceneLUT == NULL) { - memoryError("Scene::Scene()"); - } - - MemoryReadStreamEndian readS(sceneLUTPointer, sceneLUTLength, _sceneContext->isBigEndian); - - for (i = 0; i < _sceneCount; i++) { - _sceneLUT[i] = readS.readUint16(); - debug(8, "sceneNumber %i has resourceId %i", i, _sceneLUT[i]); - } - - free(sceneLUTPointer); - -#define DUMP_SCENES_LEVEL 10 - - if (DUMP_SCENES_LEVEL <= gDebugLevel) { - uint j; - int backUpDebugLevel = gDebugLevel; - SAGAResourceTypes *types; - int typesCount; - SAGAResourceTypes resType; - - getResourceTypes(types, typesCount); - - for (i = 0; i < _sceneCount; i++) { - gDebugLevel = -1; - loadSceneDescriptor(_sceneLUT[i]); - loadSceneResourceList(_sceneDescription.resourceListResourceId); - gDebugLevel = backUpDebugLevel; - debug(DUMP_SCENES_LEVEL, "Dump Scene: number %i, descriptor resourceId %i, resourceList resourceId %i", i, _sceneLUT[i], _sceneDescription.resourceListResourceId); - debug(DUMP_SCENES_LEVEL, "\tresourceListCount %i", _resourceListCount); - for (j = 0; j < _resourceListCount; j++) { - if (_resourceList[j].resourceType >= typesCount) { - error("wrong resource type %i", _resourceList[j].resourceType); - } - resType = types[_resourceList[j].resourceType]; - - debug(DUMP_SCENES_LEVEL, "\t%s resourceId %i", SAGAResourceTypesString[resType], _resourceList[j].resourceId); - } - free(_resourceList); - } - } - - - debug(3, "LUT has %d entries.", _sceneCount); - - _sceneLoaded = false; - _sceneNumber = 0; - _sceneResourceId = 0; - _inGame = false; - _loadDescription = false; - memset(&_sceneDescription, 0, sizeof(_sceneDescription)); - _resourceListCount = 0; - _resourceList = NULL; - _sceneProc = NULL; - _objectMap = new ObjectMap(_vm); - _actionMap = new ObjectMap(_vm); - memset(&_bg, 0, sizeof(_bg)); - memset(&_bgMask, 0, sizeof(_bgMask)); -} - -Scene::~Scene() { - delete _actionMap; - delete _objectMap; - free(_sceneLUT); -} - -void Scene::getResourceTypes(SAGAResourceTypes *&types, int &typesCount) { - if (_vm->getGameType() == GType_IHNM) { - typesCount = ARRAYSIZE(IHNMSceneResourceTypes); - types = IHNMSceneResourceTypes; - } else { - typesCount = ARRAYSIZE(ITESceneResourceTypes); - types = ITESceneResourceTypes; - } -} - -void Scene::drawTextList(Surface *ds) { - TextListEntry *entry; - - for (TextList::iterator textIterator = _textList.begin(); textIterator != _textList.end(); ++textIterator) { - entry = (TextListEntry *)textIterator.operator->(); - if (entry->display) { - - if (entry->useRect) { - _vm->_font->textDrawRect(entry->font, ds, entry->text, entry->rect, _vm->KnownColor2ColorId(entry->knownColor), _vm->KnownColor2ColorId(entry->effectKnownColor), entry->flags); - } else { - _vm->_font->textDraw(entry->font, ds, entry->text, entry->point, _vm->KnownColor2ColorId(entry->knownColor), _vm->KnownColor2ColorId(entry->effectKnownColor), entry->flags); - } - } - } -} - -void Scene::startScene() { - SceneQueueList::iterator queueIterator; - LoadSceneParams *sceneQueue; - Event event; - - if (_sceneLoaded) { - error("Scene::start(): Error: Can't start game...scene already loaded"); - } - - if (_inGame) { - error("Scene::start(): Error: Can't start game...game already started"); - } - - // Hide cursor during intro - event.type = kEvTOneshot; - event.code = kCursorEvent; - event.op = kEventHide; - _vm->_events->queue(&event); - - switch (_vm->getGameType()) { - case GType_ITE: - ITEStartProc(); - break; - case GType_IHNM: - IHNMStartProc(); - break; - default: - error("Scene::start(): Error: Can't start game... gametype not supported"); - break; - } - - // Load the head in scene queue - queueIterator = _sceneQueue.begin(); - if (queueIterator == _sceneQueue.end()) { - return; - } - - sceneQueue = queueIterator.operator->(); - - loadScene(sceneQueue); -} - -void Scene::nextScene() { - SceneQueueList::iterator queueIterator; - LoadSceneParams *sceneQueue; - - if (!_sceneLoaded) { - error("Scene::next(): Error: Can't advance scene...no scene loaded"); - } - - if (_inGame) { - error("Scene::next(): Error: Can't advance scene...game already started"); - } - - endScene(); - - // Delete the current head in scene queue - queueIterator = _sceneQueue.begin(); - if (queueIterator == _sceneQueue.end()) { - return; - } - - queueIterator = _sceneQueue.erase(queueIterator); - - if (queueIterator == _sceneQueue.end()) { - return; - } - - // Load the head in scene queue - sceneQueue = queueIterator.operator->(); - - loadScene(sceneQueue); -} - -void Scene::skipScene() { - SceneQueueList::iterator queueIterator; - - LoadSceneParams *sceneQueue = NULL; - LoadSceneParams *skipQueue = NULL; - - if (!_sceneLoaded) { - error("Scene::skip(): Error: Can't skip scene...no scene loaded"); - } - - if (_inGame) { - error("Scene::skip(): Error: Can't skip scene...game already started"); - } - - // Walk down scene queue and try to find a skip target - queueIterator = _sceneQueue.begin(); - if (queueIterator == _sceneQueue.end()) { - error("Scene::skip(): Error: Can't skip scene...no scenes in queue"); - } - - ++queueIterator; - while (queueIterator != _sceneQueue.end()) { - sceneQueue = queueIterator.operator->(); - assert(sceneQueue != NULL); - - if (sceneQueue->sceneSkipTarget) { - skipQueue = sceneQueue; - break; - } - ++queueIterator; - } - - // If skip target found, remove preceding scenes and load - if (skipQueue != NULL) { - _sceneQueue.erase(_sceneQueue.begin(), queueIterator); - - endScene(); - loadScene(skipQueue); - } -} - -static struct SceneSubstitutes { - int sceneId; - const char *message; - const char *title; - const char *image; -} sceneSubstitutes[] = { - { - 7, - "Tycho says he knows much about the northern lands. Can Rif convince " - "the Dog to share this knowledge?", - "The Home of Tycho Northpaw", - "tycho.bbm" - }, - - { - 27, - "The scene of the crime may hold many clues, but will the servants of " - "the Sanctuary trust Rif?", - "The Sanctuary of the Orb", - "sanctuar.bbm" - }, - - { - 5, - "The Rats hold many secrets that could guide Rif on his quest -- assuming " - "he can get past the doorkeeper.", - "The Rat Complex", - "ratdoor.bbm" - }, - - { - 2, - "The Ferrets enjoy making things and have the materials to do so. How can " - "that help Rif?", - "The Ferret Village", - "ferrets.bbm" - }, - - { - 67, - "What aid can the noble King of the Elks provide to Rif and his companions?", - "The Realm of the Forest King", - "elkenter.bbm" - }, - - { - 3, - "The King holds Rif's sweetheart hostage. Will the Boar provide any " - "assistance to Rif?", - "The Great Hall of the Boar King", - "boarhall.bbm" - } -}; - -void Scene::changeScene(int16 sceneNumber, int actorsEntrance, SceneTransitionType transitionType, int chapter) { - - debug(5, "Scene::changeScene(%d, %d, %d, %d)", sceneNumber, actorsEntrance, transitionType, chapter); - - // This is used for latter ITE demos where all places on world map except - // Tent Faire are substituted with LBM picture and short description - if (_vm->getFeatures() & GF_SCENE_SUBSTITUTES) { - for (int i = 0; i < ARRAYSIZE(sceneSubstitutes); i++) { - if (sceneSubstitutes[i].sceneId == sceneNumber) { - Surface *backBuffer = _vm->_gfx->getBackBuffer(); - Surface bbmBuffer; - byte *pal, *colors; - Common::File file; - Rect rect; - PalEntry cPal[PAL_ENTRIES]; - - _vm->_interface->setMode(kPanelSceneSubstitute); - - if (file.open(sceneSubstitutes[i].image)) { - Graphics::decodeILBM(file, bbmBuffer, pal); - colors = pal; - rect.setWidth(bbmBuffer.w); - rect.setHeight(bbmBuffer.h); - backBuffer->blit(rect, (const byte*)bbmBuffer.pixels); - for (int j = 0; j < PAL_ENTRIES; j++) { - cPal[j].red = *pal++; - cPal[j].green = *pal++; - cPal[j].blue = *pal++; - } - free(colors); - _vm->_gfx->setPalette(cPal); - - } - - _vm->_interface->setStatusText("Click or Press Return to continue. Press Q to quit.", 96); - _vm->_font->textDrawRect(kKnownFontMedium, backBuffer, sceneSubstitutes[i].title, - Common::Rect(0, 7, _vm->getDisplayWidth(), 27), _vm->KnownColor2ColorId(kKnownColorBrightWhite), _vm->KnownColor2ColorId(kKnownColorBlack), kFontOutline); - _vm->_font->textDrawRect(kKnownFontMedium, backBuffer, sceneSubstitutes[i].message, - Common::Rect(24, getHeight() - 33, _vm->getDisplayWidth() - 11, - getHeight()), _vm->KnownColor2ColorId(kKnownColorBrightWhite), _vm->KnownColor2ColorId(kKnownColorBlack), kFontOutline); - return; - } - } - } - - LoadSceneParams sceneParams; - - sceneParams.actorsEntrance = actorsEntrance; - sceneParams.loadFlag = kLoadBySceneNumber; - sceneParams.sceneDescriptor = sceneNumber; - sceneParams.transitionType = transitionType; - sceneParams.sceneProc = NULL; - sceneParams.sceneSkipTarget = false; - sceneParams.chapter = chapter; - - if (sceneNumber != -2) { - endScene(); - } - loadScene(&sceneParams); -} - -void Scene::getSlopes(int &beginSlope, int &endSlope) { - beginSlope = getHeight() - _sceneDescription.beginSlope; - endSlope = getHeight() - _sceneDescription.endSlope; -} - -void Scene::getBGInfo(BGInfo &bgInfo) { - bgInfo.buffer = _bg.buf; - bgInfo.bufferLength = _bg.buf_len; - bgInfo.bounds.left = 0; - bgInfo.bounds.top = 0; - - if (_bg.w < _vm->getDisplayWidth()) { - bgInfo.bounds.left = (_vm->getDisplayWidth() - _bg.w) / 2; - } - - if (_bg.h < getHeight()) { - bgInfo.bounds.top = (getHeight() - _bg.h) / 2; - } - - bgInfo.bounds.setWidth(_bg.w); - bgInfo.bounds.setHeight(_bg.h); -} - -int Scene::getBGMaskType(const Point &testPoint) { - uint offset; - if (!_bgMask.loaded) { - return 0; - } - offset = testPoint.x + testPoint.y * _bgMask.w; - if (offset >= _bgMask.buf_len) { - error("Scene::getBGMaskType offset 0x%X exceed bufferLength 0x%X", offset, _bgMask.buf_len); - } - - return (_bgMask.buf[offset] >> 4) & 0x0f; -} - -bool Scene::validBGMaskPoint(const Point &testPoint) { - if (!_bgMask.loaded) { - error("Scene::validBGMaskPoint _bgMask not loaded"); - } - - return !((testPoint.x < 0) || (testPoint.x >= _bgMask.w) || - (testPoint.y < 0) || (testPoint.y >= _bgMask.h)); -} - -bool Scene::canWalk(const Point &testPoint) { - int maskType; - - if (!_bgMask.loaded) { - return true; - } - if (!validBGMaskPoint(testPoint)) { - return true; - } - - maskType = getBGMaskType(testPoint); - return getDoorState(maskType) == 0; -} - -bool Scene::offscreenPath(Point &testPoint) { - Point point; - - if (!_bgMask.loaded) { - return false; - } - - point.x = clamp( 0, testPoint.x, _bgMask.w - 1 ); - point.y = clamp( 0, testPoint.y, _bgMask.h - 1 ); - if (point == testPoint) { - return false; - } - - if (point.y >= _bgMask.h - 1) { - point.y = _bgMask.h - 2; - } - testPoint = point; - - return true; -} - - -void Scene::getBGMaskInfo(int &width, int &height, byte *&buffer, size_t &bufferLength) { - if (!_bgMask.loaded) { - error("Scene::getBGMaskInfo _bgMask not loaded"); - } - - width = _bgMask.w; - height = _bgMask.h; - buffer = _bgMask.buf; - bufferLength = _bgMask.buf_len; -} - -void Scene::setDoorState(int doorNumber, int doorState) { - if ((doorNumber < 0) || (doorNumber >= SCENE_DOORS_MAX)) - error("Scene::setDoorState wrong doorNumber"); - - _sceneDoors[doorNumber] = doorState; -} - -int Scene::getDoorState(int doorNumber) { - if ((doorNumber < 0) || (doorNumber >= SCENE_DOORS_MAX)) - error("Scene::getDoorState wrong doorNumber"); - - return _sceneDoors[doorNumber]; -} - -void Scene::initDoorsState() { - memcpy(_sceneDoors, initSceneDoors, sizeof (_sceneDoors) ); -} - -void Scene::loadScene(LoadSceneParams *loadSceneParams) { - size_t i; - Event event; - Event *q_event; - static PalEntry current_pal[PAL_ENTRIES]; - - if ((_vm->getGameType() == GType_IHNM) && (loadSceneParams->chapter != NO_CHAPTER_CHANGE)) { - if (loadSceneParams->loadFlag != kLoadBySceneNumber) { - error("loadScene wrong usage"); - } - - if (loadSceneParams->chapter == 6) - _vm->_interface->setLeftPortrait(0); - - _vm->_anim->freeCutawayList(); - _vm->_script->freeModules(); - // deleteAllScenes(); - - // installSomeAlarm() - - _vm->_interface->clearInventory(); - _vm->_resource->loadGlobalResources(loadSceneParams->chapter, loadSceneParams->actorsEntrance); - _vm->_interface->addToInventory(IHNM_OBJ_PROFILE); - _vm->_interface->activate(); - - if (loadSceneParams->chapter == 8 || loadSceneParams->chapter == -1) - _vm->_interface->setMode(kPanelChapterSelection); - else - _vm->_interface->setMode(kPanelMain); - - _inGame = true; - - _vm->_script->setVerb(_vm->_script->getVerbType(kVerbWalkTo)); - - if (loadSceneParams->sceneDescriptor == -2) { - return; - } - } - - if (_sceneLoaded) { - error("Scene::loadScene(): Error, a scene is already loaded"); - } - - _loadDescription = true; - - if (_vm->getGameType() == GType_IHNM) { - if (loadSceneParams->loadFlag == kLoadBySceneNumber) // When will we get rid of it? - if (loadSceneParams->sceneDescriptor <= 0) - loadSceneParams->sceneDescriptor = _vm->_resource->_metaResource.sceneIndex; - } - - switch (loadSceneParams->loadFlag) { - case kLoadByResourceId: - _sceneNumber = 0; // original assign zero for loaded by resource id - _sceneResourceId = loadSceneParams->sceneDescriptor; - break; - case kLoadBySceneNumber: - _sceneNumber = loadSceneParams->sceneDescriptor; - _sceneResourceId = getSceneResourceId(_sceneNumber); - break; - case kLoadByDescription: - _sceneNumber = -1; - _sceneResourceId = -1; - assert(loadSceneParams->sceneDescription != NULL); - assert(loadSceneParams->sceneDescription->resourceList != NULL); - _loadDescription = false; - _sceneDescription = *loadSceneParams->sceneDescription; - _resourceList = loadSceneParams->sceneDescription->resourceList; - _resourceListCount = loadSceneParams->sceneDescription->resourceListCount; - break; - } - - debug(3, "Loading scene number %d:", _sceneNumber); - - // Load scene descriptor and resource list resources - if (_loadDescription) { - debug(3, "Loading scene resource %i", _sceneResourceId); - - loadSceneDescriptor(_sceneResourceId); - - loadSceneResourceList(_sceneDescription.resourceListResourceId); - } else { - debug(3, "Loading memory scene resource"); - } - - // Load resources from scene resource list - for (i = 0; i < _resourceListCount; i++) { - if (!_resourceList[i].invalid) { - _vm->_resource->loadResource(_sceneContext, _resourceList[i].resourceId, - _resourceList[i].buffer, _resourceList[i].size); - - - if (_resourceList[i].size >= 6) { - if (!memcmp(_resourceList[i].buffer, "DUMMY!", 6)) { - _resourceList[i].invalid = true; - warning("DUMMY resource %i", _resourceList[i].resourceId); - } - } - } - } - - // Process resources from scene resource list - processSceneResources(); - - if (_sceneDescription.flags & kSceneFlagISO) { - _outsetSceneNumber = _sceneNumber; - - _sceneClip.left = 0; - _sceneClip.top = 0; - _sceneClip.right = _vm->getDisplayWidth(); - _sceneClip.bottom = getHeight(); - } else { - BGInfo backGroundInfo; - getBGInfo(backGroundInfo); - _sceneClip = backGroundInfo.bounds; - if (!(_bg.w < _vm->getDisplayWidth() || _bg.h < getHeight())) - _outsetSceneNumber = _sceneNumber; - } - - _sceneLoaded = true; - - q_event = NULL; - - //fix placard bug - //i guess we should remove RF_PLACARD flag - and use _interface->getMode() - event.type = kEvTOneshot; - event.code = kGraphicsEvent; - event.op = kEventClearFlag; - event.param = RF_PLACARD; - - q_event = _vm->_events->chain(q_event, &event); - - if (loadSceneParams->transitionType == kTransitionFade) { - - _vm->_interface->setFadeMode(kFadeOut); - - // Fade to black out - _vm->_gfx->getCurrentPal(current_pal); - event.type = kEvTImmediate; - event.code = kPalEvent; - event.op = kEventPalToBlack; - event.time = 0; - event.duration = kNormalFadeDuration; - event.data = current_pal; - q_event = _vm->_events->queue(&event); - - // set fade mode - event.type = kEvTImmediate; - event.code = kInterfaceEvent; - event.op = kEventSetFadeMode; - event.param = kNoFade; - event.time = 0; - event.duration = 0; - q_event = _vm->_events->chain(q_event, &event); - - // Display scene background, but stay with black palette - event.type = kEvTImmediate; - event.code = kBgEvent; - event.op = kEventDisplay; - event.param = kEvPNoSetPalette; - event.time = 0; - event.duration = 0; - q_event = _vm->_events->chain(q_event, &event); - - } - - // Start the scene pre script, but stay with black palette - if (_sceneDescription.startScriptEntrypointNumber > 0) { - event.type = kEvTOneshot; - event.code = kScriptEvent; - event.op = kEventExecBlocking; - event.time = 0; - event.param = _sceneDescription.scriptModuleNumber; - event.param2 = _sceneDescription.startScriptEntrypointNumber; - event.param3 = 0; // Action - event.param4 = _sceneNumber; // Object - event.param5 = loadSceneParams->actorsEntrance; // With Object - event.param6 = 0; // Actor - - q_event = _vm->_events->chain(q_event, &event); - } - - if (loadSceneParams->transitionType == kTransitionFade) { - - // set fade mode - event.type = kEvTImmediate; - event.code = kInterfaceEvent; - event.op = kEventSetFadeMode; - event.param = kFadeIn; - event.time = 0; - event.duration = 0; - q_event = _vm->_events->chain(q_event, &event); - - // Fade in from black to the scene background palette - event.type = kEvTImmediate; - event.code = kPalEvent; - event.op = kEventBlackToPal; - event.time = 0; - event.duration = kNormalFadeDuration; - event.data = _bg.pal; - - q_event = _vm->_events->chain(q_event, &event); - - // set fade mode - event.type = kEvTImmediate; - event.code = kInterfaceEvent; - event.op = kEventSetFadeMode; - event.param = kNoFade; - event.time = 0; - event.duration = 0; - q_event = _vm->_events->chain(q_event, &event); - } - - if (loadSceneParams->sceneProc == NULL) { - if (!_inGame && _vm->getGameType() == GType_ITE) { - _inGame = true; - _vm->_interface->setMode(kPanelMain); - } - - _vm->_sound->stopAll(); - - // FIXME: Does IHNM use scene background music, or is all the - // music scripted? At the very least, it shouldn't try - // to start song 0 at the beginning of the game, since - // it's the end credits music. - - if (_vm->getGameType() == GType_ITE) { - if (_sceneDescription.musicResourceId >= 0) { - event.type = kEvTOneshot; - event.code = kMusicEvent; - event.param = _sceneDescription.musicResourceId; - event.param2 = MUSIC_DEFAULT; - event.op = kEventPlay; - event.time = 0; - - _vm->_events->queue(&event); - } else { - event.type = kEvTOneshot; - event.code = kMusicEvent; - event.op = kEventStop; - event.time = 0; - - _vm->_events->queue(&event); - } - } - - // Set scene background - event.type = kEvTOneshot; - event.code = kBgEvent; - event.op = kEventDisplay; - event.param = kEvPSetPalette; - event.time = 0; - - _vm->_events->queue(&event); - - // Begin palette cycle animation if present - event.type = kEvTOneshot; - event.code = kPalAnimEvent; - event.op = kEventCycleStart; - event.time = 0; - - q_event = _vm->_events->queue(&event); - - // Start the scene main script - if (_sceneDescription.sceneScriptEntrypointNumber > 0) { - event.type = kEvTOneshot; - event.code = kScriptEvent; - event.op = kEventExecNonBlocking; - event.time = 0; - event.param = _sceneDescription.scriptModuleNumber; - event.param2 = _sceneDescription.sceneScriptEntrypointNumber; - event.param3 = _vm->_script->getVerbType(kVerbEnter); // Action - event.param4 = _sceneNumber; // Object - event.param5 = loadSceneParams->actorsEntrance; // With Object - event.param6 = 0; // Actor - - _vm->_events->queue(&event); - } - - debug(3, "Scene started"); - - } else { - loadSceneParams->sceneProc(SCENE_BEGIN, this); - } - - - - // We probably don't want "followers" to go into scene -1 , 0. At the very - // least we don't want garbage to be drawn that early in the ITE intro. - if (_sceneNumber > 0 && _sceneNumber != ITE_SCENE_PUZZLE) - _vm->_actor->updateActorsScene(loadSceneParams->actorsEntrance); - - if (_sceneNumber == ITE_SCENE_PUZZLE) - _vm->_puzzle->execute(); - - if (getFlags() & kSceneFlagShowCursor) { - // Activate user interface - event.type = kEvTOneshot; - event.code = kInterfaceEvent; - event.op = kEventActivate; - event.time = 0; - _vm->_events->queue(&event); - } -} - -void Scene::loadSceneDescriptor(uint32 resourceId) { - byte *sceneDescriptorData; - size_t sceneDescriptorDataLength; - - memset(&_sceneDescription, 0, sizeof(_sceneDescription)); - - if (resourceId == 0) { - return; - } - - _vm->_resource->loadResource(_sceneContext, resourceId, sceneDescriptorData, sceneDescriptorDataLength); - - if (sceneDescriptorDataLength == 16) { - MemoryReadStreamEndian readS(sceneDescriptorData, sceneDescriptorDataLength, _sceneContext->isBigEndian); - - _sceneDescription.flags = readS.readSint16(); - _sceneDescription.resourceListResourceId = readS.readSint16(); - _sceneDescription.endSlope = readS.readSint16(); - _sceneDescription.beginSlope = readS.readSint16(); - _sceneDescription.scriptModuleNumber = readS.readUint16(); - _sceneDescription.sceneScriptEntrypointNumber = readS.readUint16(); - _sceneDescription.startScriptEntrypointNumber = readS.readUint16(); - _sceneDescription.musicResourceId = readS.readSint16(); - } - - free(sceneDescriptorData); -} - -void Scene::loadSceneResourceList(uint32 resourceId) { - byte *resourceListData; - size_t resourceListDataLength; - size_t i; - - _resourceListCount = 0; - _resourceList = NULL; - - if (resourceId == 0) { - return; - } - - // Load the scene resource table - _vm->_resource->loadResource(_sceneContext, resourceId, resourceListData, resourceListDataLength); - - if ((resourceListDataLength % SAGA_RESLIST_ENTRY_LEN) == 0) { - MemoryReadStreamEndian readS(resourceListData, resourceListDataLength, _sceneContext->isBigEndian); - - // Allocate memory for scene resource list - _resourceListCount = resourceListDataLength / SAGA_RESLIST_ENTRY_LEN; - debug(3, "Scene resource list contains %i entries", _resourceListCount); - _resourceList = (SceneResourceData *)calloc(_resourceListCount, sizeof(*_resourceList)); - - // Load scene resource list from raw scene - // resource table - debug(3, "Loading scene resource list"); - - for (i = 0; i < _resourceListCount; i++) { - _resourceList[i].resourceId = readS.readUint16(); - _resourceList[i].resourceType = readS.readUint16(); - // demo version may contain invalid resourceId - _resourceList[i].invalid = !_vm->_resource->validResourceId(_sceneContext, _resourceList[i].resourceId); - } - - } - free(resourceListData); -} - -void Scene::processSceneResources() { - byte *resourceData; - size_t resourceDataLength; - const byte *palPointer; - size_t i; - SAGAResourceTypes *types; - int typesCount; - SAGAResourceTypes resType; - - getResourceTypes(types, typesCount); - - // Process the scene resource list - for (i = 0; i < _resourceListCount; i++) { - if (_resourceList[i].invalid) { - continue; - } - resourceData = _resourceList[i].buffer; - resourceDataLength = _resourceList[i].size; - - if (_resourceList[i].resourceType >= typesCount) { - error("Scene::processSceneResources() wrong resource type %i", _resourceList[i].resourceType); - } - - resType = types[_resourceList[i].resourceType]; - - switch (resType) { - case SAGA_UNKNOWN: - warning("UNKNOWN resourceType %i", _resourceList[i].resourceType); - break; - case SAGA_ACTOR: - //for (a = actorsInScene; a; a = a->nextInScene) - // if (a->obj.figID == glist->file_id) - // if (_vm->getGameType() == GType_ITE || - // ((a->obj.flags & ACTORF_FINAL_FACE) & 0xff)) - // a->sprites = (xSpriteSet *)glist->offset; - warning("STUB: unimplemeted handler of SAGA_ACTOR resource"); - break; - case SAGA_OBJECT: - break; - case SAGA_BG_IMAGE: // Scene background resource - if (_bg.loaded) { - error("Scene::processSceneResources() Multiple background resources encountered"); - } - - debug(3, "Loading background resource."); - _bg.res_buf = resourceData; - _bg.res_len = resourceDataLength; - _bg.loaded = 1; - - if (_vm->decodeBGImage(_bg.res_buf, - _bg.res_len, - &_bg.buf, - &_bg.buf_len, - &_bg.w, - &_bg.h) != SUCCESS) { - error("Scene::processSceneResources() Error loading background resource %i", _resourceList[i].resourceId); - } - - palPointer = _vm->getImagePal(_bg.res_buf, _bg.res_len); - memcpy(_bg.pal, palPointer, sizeof(_bg.pal)); - break; - case SAGA_BG_MASK: // Scene background mask resource - if (_bgMask.loaded) { - error("Scene::ProcessSceneResources(): Duplicate background mask resource encountered"); - } - debug(3, "Loading BACKGROUND MASK resource."); - _bgMask.res_buf = resourceData; - _bgMask.res_len = resourceDataLength; - _bgMask.loaded = 1; - _vm->decodeBGImage(_bgMask.res_buf, _bgMask.res_len, &_bgMask.buf, - &_bgMask.buf_len, &_bgMask.w, &_bgMask.h, true); - - // At least in ITE the mask needs to be clipped. - - _bgMask.w = MIN(_bgMask.w, _vm->getDisplayWidth()); - _bgMask.h = MIN(_bgMask.h, getHeight()); - - debug(4, "BACKGROUND MASK width=%d height=%d length=%d", _bgMask.w, _bgMask.h, _bgMask.buf_len); - break; - case SAGA_STRINGS: - debug(3, "Loading scene strings resource..."); - _vm->loadStrings(_sceneStrings, resourceData, resourceDataLength); - break; - case SAGA_OBJECT_MAP: - debug(3, "Loading object map resource..."); - _objectMap->load(resourceData, resourceDataLength); - break; - case SAGA_ACTION_MAP: - debug(3, "Loading action map resource..."); - _actionMap->load(resourceData, resourceDataLength); - break; - case SAGA_ISO_IMAGES: - if (!(_sceneDescription.flags & kSceneFlagISO)) { - error("Scene::ProcessSceneResources(): not Iso mode"); - } - - debug(3, "Loading isometric images resource."); - - _vm->_isoMap->loadImages(resourceData, resourceDataLength); - break; - case SAGA_ISO_MAP: - if (!(_sceneDescription.flags & kSceneFlagISO)) { - error("Scene::ProcessSceneResources(): not Iso mode"); - } - - debug(3, "Loading isometric map resource."); - - _vm->_isoMap->loadMap(resourceData, resourceDataLength); - break; - case SAGA_ISO_PLATFORMS: - if (!(_sceneDescription.flags & kSceneFlagISO)) { - error("Scene::ProcessSceneResources(): not Iso mode"); - } - - debug(3, "Loading isometric platforms resource."); - - _vm->_isoMap->loadPlatforms(resourceData, resourceDataLength); - break; - case SAGA_ISO_METATILES: - if (!(_sceneDescription.flags & kSceneFlagISO)) { - error("Scene::ProcessSceneResources(): not Iso mode"); - } - - debug(3, "Loading isometric metatiles resource."); - - _vm->_isoMap->loadMetaTiles(resourceData, resourceDataLength); - break; - case SAGA_ANIM: - { - uint16 animId = _resourceList[i].resourceType - 14; - - debug(3, "Loading animation resource animId=%i", animId); - - _vm->_anim->load(animId, resourceData, resourceDataLength); - } - break; - case SAGA_ENTRY: - debug(3, "Loading entry list resource..."); - loadSceneEntryList(resourceData, resourceDataLength); - break; - case SAGA_ISO_MULTI: - if (!(_sceneDescription.flags & kSceneFlagISO)) { - error("Scene::ProcessSceneResources(): not Iso mode"); - } - - debug(3, "Loading isometric multi resource."); - - _vm->_isoMap->loadMulti(resourceData, resourceDataLength); - break; - case SAGA_PAL_ANIM: - debug(3, "Loading palette animation resource."); - _vm->_palanim->loadPalAnim(resourceData, resourceDataLength); - break; - case SAGA_FACES: - if (_vm->getGameType() == GType_ITE) - _vm->_interface->loadScenePortraits(_resourceList[i].resourceId); - break; - case SAGA_PALETTE: - { - PalEntry pal[PAL_ENTRIES]; - byte *palPtr = resourceData; - - if (resourceDataLength < 3 * PAL_ENTRIES) - error("Too small scene palette %i", resourceDataLength); - - for (uint16 c = 0; c < PAL_ENTRIES; c++) { - pal[c].red = *palPtr++; - pal[c].green = *palPtr++; - pal[c].blue = *palPtr++; - } - _vm->_gfx->setPalette(pal); - } - break; - default: - error("Scene::ProcessSceneResources() Encountered unknown resource type %i", _resourceList[i].resourceType); - break; - } - } -} - -void Scene::draw() { - Surface *backBuffer; - Surface *backGroundSurface; - Rect rect; - - backBuffer = _vm->_gfx->getBackBuffer(); - - backGroundSurface = _vm->_render->getBackGroundSurface(); - - if (_sceneDescription.flags & kSceneFlagISO) { - _vm->_isoMap->adjustScroll(false); - _vm->_isoMap->draw(backBuffer); - } else { - backGroundSurface->getRect(rect); - if (_sceneClip.bottom < rect.bottom) { - rect.bottom = getHeight(); - } - backBuffer->blit(rect, (const byte *)backGroundSurface->pixels); - } -} - -void Scene::endScene() { - Surface *backBuffer; - Surface *backGroundSurface; - Rect rect; - size_t i; - - if (!_sceneLoaded) - return; - - debug(3, "Ending scene..."); - - if (_sceneProc != NULL) { - _sceneProc(SCENE_END, this); - } - - // - _vm->_script->abortAllThreads(); - _vm->_script->_skipSpeeches = false; - - // Copy current screen to render buffer so inset rooms will get proper background - backGroundSurface = _vm->_render->getBackGroundSurface(); - if (!(_sceneDescription.flags & kSceneFlagISO) && !_vm->_scene->isInIntro()) { - BGInfo bgInfo; - - _vm->_scene->getBGInfo(bgInfo); - backGroundSurface->blit(bgInfo.bounds, bgInfo.buffer); - } else { - backBuffer = _vm->_gfx->getBackBuffer(); - backBuffer->getRect(rect); - backGroundSurface->blit(rect, (const byte *)backBuffer->pixels); - } - - // Free scene background - if (_bg.loaded) { - free(_bg.buf); - _bg.loaded = 0; - } - - // Free scene background mask - if (_bgMask.loaded) { - free(_bgMask.buf); - _bgMask.loaded = 0; - } - - // Free scene resource list - for (i = 0; i < _resourceListCount; i++) { - free(_resourceList[i].buffer); - } - - if (_loadDescription) { - free(_resourceList); - } - - // Free animation info list - _vm->_anim->reset(); - - _vm->_palanim->freePalAnim(); - - _objectMap->freeMem(); - _actionMap->freeMem(); - _entryList.freeMem(); - _sceneStrings.freeMem(); - _vm->_isoMap->freeMem(); - - _vm->_events->clearList(); - _textList.clear(); - - _sceneLoaded = false; - -} - -void Scene::cmdSceneChange(int argc, const char **argv) { - int scene_num = 0; - - scene_num = atoi(argv[1]); - - if ((scene_num < 1) || (scene_num >= _sceneCount)) { - _vm->_console->DebugPrintf("Invalid scene number.\n"); - return; - } - - clearSceneQueue(); - - changeScene(scene_num, 0, kTransitionNoFade); -} - -void Scene::cmdActionMapInfo() { - _actionMap->cmdInfo(); -} - -void Scene::cmdObjectMapInfo() { - _objectMap->cmdInfo(); -} - - -void Scene::loadSceneEntryList(const byte* resourcePointer, size_t resourceLength) { - int i; - - _entryList.entryListCount = resourceLength / 8; - - MemoryReadStreamEndian readS(resourcePointer, resourceLength, _sceneContext->isBigEndian); - - - if (_entryList.entryList) - error("Scene::loadSceneEntryList entryList != NULL"); - - _entryList.entryList = (SceneEntry *) malloc(_entryList.entryListCount * sizeof(*_entryList.entryList)); - if (_entryList.entryList == NULL) { - memoryError("Scene::loadSceneEntryList"); - } - - for (i = 0; i < _entryList.entryListCount; i++) { - _entryList.entryList[i].location.x = readS.readSint16(); - _entryList.entryList[i].location.y = readS.readSint16(); - _entryList.entryList[i].location.z = readS.readSint16(); - _entryList.entryList[i].facing = readS.readUint16(); - } -} - -} // End of namespace Saga diff --git a/saga/scene.h b/saga/scene.h deleted file mode 100644 index 7f99140d10..0000000000 --- a/saga/scene.h +++ /dev/null @@ -1,370 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Scene management module private header file - -#ifndef SAGA_SCENE_H -#define SAGA_SCENE_H - -#include "saga/font.h" -#include "saga/list.h" -#include "saga/actor.h" -#include "saga/interface.h" - -namespace Saga { - -#define SCENE_DOORS_MAX 16 - -#define NO_CHAPTER_CHANGE -2 - -class ObjectMap; - -struct Event; - -enum SceneFlags { - kSceneFlagISO = 1, - kSceneFlagShowCursor = 2 -}; - -struct BGInfo { - Rect bounds; - byte *buffer; - size_t bufferLength; -}; - -typedef int (SceneProc) (int, void *); - - -enum SCENE_PROC_PARAMS { - SCENE_BEGIN = 0, - SCENE_END -}; - -// Resource type numbers -enum SAGAResourceTypes { - SAGA_UNKNOWN, - SAGA_ACTOR, - SAGA_OBJECT, - SAGA_BG_IMAGE, - SAGA_BG_MASK, - SAGA_STRINGS, - SAGA_OBJECT_MAP, - SAGA_ACTION_MAP, - SAGA_ISO_IMAGES, - SAGA_ISO_MAP, - SAGA_ISO_PLATFORMS, - SAGA_ISO_METATILES, - SAGA_ENTRY, - SAGA_ANIM, - SAGA_ISO_MULTI, - SAGA_PAL_ANIM, - SAGA_FACES, - SAGA_PALETTE -}; - -#define SAGA_RESLIST_ENTRY_LEN 4 - -struct SceneResourceData { - uint32 resourceId; - int resourceType; - byte *buffer; - size_t size; - bool invalid; -}; - -#define SAGA_SCENE_DESC_LEN 16 - -struct SceneDescription { - int16 flags; - int16 resourceListResourceId; - int16 endSlope; - int16 beginSlope; - uint16 scriptModuleNumber; - uint16 sceneScriptEntrypointNumber; - uint16 startScriptEntrypointNumber; - int16 musicResourceId; - SceneResourceData *resourceList; - size_t resourceListCount; -}; - -struct SceneEntry { - Location location; - int facing; -}; - -struct SceneEntryList { - SceneEntry *entryList; - int entryListCount; - - const SceneEntry * getEntry(int index) { - if ((index < 0) || (index >= entryListCount)) { - error("SceneEntryList::getEntry wrong index (%d)", index); - } - return &entryList[index]; - } - void freeMem() { - free(entryList); - memset(this, 0, sizeof(*this)); - } - SceneEntryList() { - memset(this, 0, sizeof(*this)); - } - ~SceneEntryList() { - freeMem(); - } -}; - -struct SceneImage { - int loaded; - int w; - int h; - int p; - byte *buf; - size_t buf_len; - byte *res_buf; - size_t res_len; - PalEntry pal[256]; -}; - - -enum SceneTransitionType { - kTransitionNoFade, - kTransitionFade -}; - -enum SceneLoadFlags { - kLoadByResourceId, - kLoadBySceneNumber, - kLoadByDescription -}; - -struct LoadSceneParams { - int32 sceneDescriptor; - SceneLoadFlags loadFlag; - SceneDescription* sceneDescription; - SceneProc *sceneProc; - bool sceneSkipTarget; - SceneTransitionType transitionType; - int actorsEntrance; - int chapter; -}; - -typedef Common::List<LoadSceneParams> SceneQueueList; - -///// IHNM-specific stuff -#define IHNM_PALFADE_TIME 1000 -#define IHNM_INTRO_FRAMETIME 80 -#define IHNM_DGLOGO_TIME 8000 -#define IHNM_TITLE_TIME_GM 28750 -#define IHNM_TITLE_TIME_FM 19500 - -///// ITE-specific stuff -#define ITE_INTRO_FRAMETIME 90 - -#define INTRO_CAPTION_Y 170 -#define INTRO_DE_CAPTION_Y 160 -#define VOICE_PAD 50 -#define VOICE_LETTERLEN 90 - -#define PALETTE_FADE_DURATION 1000 -#define DISSOLVE_DURATION 3000 -#define LOGO_DISSOLVE_DURATION 1000 - -#define CREDIT_DURATION1 4000 - -struct IntroDialogue { - uint32 i_voice_rn; - const char *i_str; -}; - -struct IntroCredit { - Common::Language lang; - int game; - int type; - const char *string; -}; - - -class Scene { - public: - Scene(SagaEngine *vm); - ~Scene(); - -// Console functions - void cmdActionMapInfo(); - void cmdObjectMapInfo(); - - void cmdSceneChange(int argc, const char **argv); - - void startScene(); - void nextScene(); - void skipScene(); - void endScene(); - void queueScene(LoadSceneParams *sceneQueue) { - _sceneQueue.push_back(*sceneQueue); - } - - void draw(); - int getFlags() const { return _sceneDescription.flags; } - int getScriptModuleNumber() const { return _sceneDescription.scriptModuleNumber; } - bool isInIntro() { return !_inGame; } - const Rect& getSceneClip() const { return _sceneClip; } - - void getBGMaskInfo(int &width, int &height, byte *&buffer, size_t &bufferLength); - int isBGMaskPresent() { return _bgMask.loaded; } - int getBGMaskType(const Point &testPoint); - bool validBGMaskPoint(const Point &testPoint); - bool canWalk(const Point &testPoint); - bool offscreenPath(Point &testPoint); - - void setDoorState(int doorNumber, int doorState); - int getDoorState(int doorNumber); - void initDoorsState(); - - void getBGInfo(BGInfo &bgInfo); - void getBGPal(PalEntry *&pal) { - pal = (PalEntry *)_bg.pal; - } - - void getSlopes(int &beginSlope, int &endSlope); - - void clearSceneQueue(void) { - _sceneQueue.clear(); - } - void changeScene(int16 sceneNumber, int actorsEntrance, SceneTransitionType transitionType, int chapter = NO_CHAPTER_CHANGE); - - bool isSceneLoaded() const { return _sceneLoaded; } - - int getSceneResourceId(int sceneNumber) { - if ((sceneNumber < 0) || (sceneNumber >= _sceneCount)) { - error("getSceneResourceId: wrong sceneNumber %i", sceneNumber); - } - return _sceneLUT[sceneNumber]; - } - int currentSceneNumber() const { return _sceneNumber; } - int currentChapterNumber() const { return _chapterNumber; } - void setChapterNumber(int ch) { _chapterNumber = ch; } - int getOutsetSceneNumber() const { return _outsetSceneNumber; } - int currentSceneResourceId() const { return _sceneResourceId; } - void cutawaySkip() { - if (_vm->_scene->isInIntro()) - _vm->_framesEsc = 2; - else - _vm->_framesEsc = 1; - } - - void drawTextList(Surface *ds); - - int getHeight() const { - if (_vm->_interface->getMode() == kPanelChapterSelection) - return _vm->_gameDisplayInfo.logicalHeight; - else - return _vm->_gameDisplayInfo.sceneHeight; - } - - private: - void loadScene(LoadSceneParams *loadSceneParams); - void loadSceneDescriptor(uint32 resourceId); - void loadSceneResourceList(uint32 resourceId); - void loadSceneEntryList(const byte* resourcePointer, size_t resourceLength); - void processSceneResources(); - void getResourceTypes(SAGAResourceTypes *&types, int &typesCount); - - - SagaEngine *_vm; - - ResourceContext *_sceneContext; - int *_sceneLUT; - int _sceneCount; - SceneQueueList _sceneQueue; - bool _sceneLoaded; - int _sceneNumber; - int _chapterNumber; - int _outsetSceneNumber; - int _sceneResourceId; - bool _inGame; - bool _loadDescription; - SceneDescription _sceneDescription; - size_t _resourceListCount; - SceneResourceData *_resourceList; - SceneProc *_sceneProc; - SceneImage _bg; - SceneImage _bgMask; - Common::Rect _sceneClip; - - int _sceneDoors[SCENE_DOORS_MAX]; - - - public: - ObjectMap *_actionMap; - ObjectMap *_objectMap; - SceneEntryList _entryList; - StringsTable _sceneStrings; - TextList _textList; - - private: - int IHNMStartProc(); - int ITEStartProc(); - - public: - static int SC_IHNMIntroMovieProc1(int param, void *refCon); - static int SC_IHNMIntroMovieProc2(int param, void *refCon); - static int SC_IHNMIntroMovieProc3(int param, void *refCon); - static int SC_IHNMHateProc(int param, void *refCon); - - private: - int IHNMIntroMovieProc1(int param); - int IHNMIntroMovieProc2(int param); - int IHNMIntroMovieProc3(int param); - int IHNMHateProc(int param); - - public: - static int SC_ITEIntroAnimProc(int param, void *refCon); - static int SC_ITEIntroCave1Proc(int param, void *refCon); - static int SC_ITEIntroCave2Proc(int param, void *refCon); - static int SC_ITEIntroCave3Proc(int param, void *refCon); - static int SC_ITEIntroCave4Proc(int param, void *refCon); - static int SC_ITEIntroValleyProc(int param, void *refCon); - static int SC_ITEIntroTreeHouseProc(int param, void *refCon); - static int SC_ITEIntroFairePathProc(int param, void *refCon); - static int SC_ITEIntroFaireTentProc(int param, void *refCon); - - private: - Event *ITEQueueDialogue(Event *q_event, int n_dialogues, const IntroDialogue dialogue[]); - Event *ITEQueueCredits(int delta_time, int duration, int n_credits, const IntroCredit credits[]); - int ITEIntroAnimProc(int param); - int ITEIntroCave1Proc(int param); - int ITEIntroCave2Proc(int param); - int ITEIntroCave3Proc(int param); - int ITEIntroCave4Proc(int param); - int ITEIntroValleyProc(int param); - int ITEIntroTreeHouseProc(int param); - int ITEIntroFairePathProc(int param); - int ITEIntroFaireTentProc(int param); - -}; - -} // End of namespace Saga - -#endif diff --git a/saga/script.cpp b/saga/script.cpp deleted file mode 100644 index 3d3a626e9f..0000000000 --- a/saga/script.cpp +++ /dev/null @@ -1,806 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Scripting module: Script resource handling functions -#include "saga/saga.h" - -#include "saga/gfx.h" -#include "saga/console.h" - -#include "saga/script.h" -#include "saga/stream.h" -#include "saga/interface.h" -#include "saga/itedata.h" -#include "saga/scene.h" -#include "saga/events.h" -#include "saga/actor.h" -#include "saga/objectmap.h" -#include "saga/isomap.h" -#include "saga/rscfile.h" - -namespace Saga { - - - -// Initializes the scripting module. -// Loads script resource look-up table, initializes script data system -Script::Script(SagaEngine *vm) : _vm(vm) { - ResourceContext *resourceContext; - byte *resourcePointer; - size_t resourceLength; - int prevTell; - int i, j; - byte *stringsPointer; - size_t stringsLength; - - //initialize member variables - _abortEnabled = true; - _skipSpeeches = false; - _conversingThread = NULL; - - _firstObjectSet = false; - _secondObjectNeeded = false; - _pendingVerb = getVerbType(kVerbNone); - _currentVerb = getVerbType(kVerbNone); - _stickyVerb = getVerbType(kVerbWalkTo); - _leftButtonVerb = getVerbType(kVerbNone); - _rightButtonVerb = getVerbType(kVerbNone); - _pointerObject = ID_NOTHING; - - _staticSize = 0; - _commonBufferSize = COMMON_BUFFER_SIZE; - _commonBuffer = (byte*)malloc(_commonBufferSize); - memset(_commonBuffer, 0, _commonBufferSize); - - debug(8, "Initializing scripting subsystem"); - // Load script resource file context - _scriptContext = _vm->_resource->getContext(GAME_SCRIPTFILE); - if (_scriptContext == NULL) { - error("Script::Script() script context not found"); - } - - resourceContext = _vm->_resource->getContext(GAME_RESOURCEFILE); - if (resourceContext == NULL) { - error("Script::Script() resource context not found"); - } - - debug(3, "Loading module LUT from resource %i", _vm->getResourceDescription()->moduleLUTResourceId); - _vm->_resource->loadResource(resourceContext, _vm->getResourceDescription()->moduleLUTResourceId, resourcePointer, resourceLength); - - - // Create logical script LUT from resource - if (resourceLength % S_LUT_ENTRYLEN_ITECD == 0) { - _modulesLUTEntryLen = S_LUT_ENTRYLEN_ITECD; - } else if (resourceLength % S_LUT_ENTRYLEN_ITEDISK == 0) { - _modulesLUTEntryLen = S_LUT_ENTRYLEN_ITEDISK; - } else { - error("Script::Script() Invalid script lookup table length (%i)", resourceLength); - } - - // Calculate number of entries - _modulesCount = resourceLength / _modulesLUTEntryLen; - - debug(3, "LUT has %i entries", _modulesCount); - - // Allocate space for logical LUT - _modules = (ModuleData *)malloc(_modulesCount * sizeof(*_modules)); - if (_modules == NULL) { - memoryError("Script::Script()"); - } - - // Convert LUT resource to logical LUT - MemoryReadStreamEndian scriptS(resourcePointer, resourceLength, resourceContext->isBigEndian); - for (i = 0; i < _modulesCount; i++) { - memset(&_modules[i], 0, sizeof(ModuleData)); - - prevTell = scriptS.pos(); - _modules[i].scriptResourceId = scriptS.readUint16(); - _modules[i].stringsResourceId = scriptS.readUint16(); - _modules[i].voicesResourceId = scriptS.readUint16(); - - // Skip the unused portion of the structure - for (j = scriptS.pos(); j < prevTell + _modulesLUTEntryLen; j++) { - if (scriptS.readByte() != 0) - warning("Unused scriptLUT part isn't really unused for LUT %d (pos: %d)", i, j); - } - } - - free(resourcePointer); - - // TODO - // - // In ITE, the "main strings" resource contains both the verb strings - // and the object names. - // - // In IHNM, the "main strings" contains the verb strings, but not the - // object names. At least, I think that's the case. - - _vm->_resource->loadResource(resourceContext, _vm->getResourceDescription()->mainStringsResourceId, stringsPointer, stringsLength); - - _vm->loadStrings(_mainStrings, stringsPointer, stringsLength); - free(stringsPointer); - - setupScriptFuncList(); -} - -// Shut down script module gracefully; free all allocated module resources -Script::~Script() { - - debug(8, "Shutting down scripting subsystem."); - - _mainStrings.freeMem(); - - freeModules(); - free(_modules); - - free(_commonBuffer); -} - -void Script::loadModule(int scriptModuleNumber) { - byte *resourcePointer; - size_t resourceLength; - - // Validate script number - if ((scriptModuleNumber < 0) || (scriptModuleNumber >= _modulesCount)) { - error("Script::loadScript() Invalid script module number"); - } - - if (_modules[scriptModuleNumber].loaded) { - return; - } - - // Initialize script data structure - debug(3, "Loading script module #%d", scriptModuleNumber); - - _vm->_resource->loadResource(_scriptContext, _modules[scriptModuleNumber].scriptResourceId, resourcePointer, resourceLength); - - loadModuleBase(_modules[scriptModuleNumber], resourcePointer, resourceLength); - free(resourcePointer); - - _vm->_resource->loadResource(_scriptContext, _modules[scriptModuleNumber].stringsResourceId, resourcePointer, resourceLength); - - _vm->loadStrings(_modules[scriptModuleNumber].strings, resourcePointer, resourceLength); - free(resourcePointer); - - if (_modules[scriptModuleNumber].voicesResourceId > 0) { - _vm->_resource->loadResource(_scriptContext, _modules[scriptModuleNumber].voicesResourceId, resourcePointer, resourceLength); - - loadVoiceLUT(_modules[scriptModuleNumber].voiceLUT, resourcePointer, resourceLength); - free(resourcePointer); - } - - _modules[scriptModuleNumber].staticOffset = _staticSize; - _staticSize += _modules[scriptModuleNumber].staticSize; - if (_staticSize > _commonBufferSize) { - error("Script::loadModule() _staticSize > _commonBufferSize"); - } - _modules[scriptModuleNumber].loaded = true; -} - -void Script::freeModules() { - int i; - for (i = 0; i < _modulesCount; i++) { - if (_modules[i].loaded) { - _modules[i].freeMem(); - } - } - _staticSize = 0; -} - -void Script::loadModuleBase(ModuleData &module, const byte *resourcePointer, size_t resourceLength) { - int i; - - debug(3, "Loading module base..."); - - module.moduleBase = (byte*)malloc(resourceLength); - module.moduleBaseSize = resourceLength; - - memcpy(module.moduleBase, resourcePointer, resourceLength); - - MemoryReadStreamEndian scriptS(module.moduleBase, module.moduleBaseSize, _scriptContext->isBigEndian); - - module.entryPointsCount = scriptS.readUint16(); - scriptS.readUint16(); //skip - module.entryPointsTableOffset = scriptS.readUint16(); - scriptS.readUint16(); //skip - - if ((module.moduleBaseSize - module.entryPointsTableOffset) < (module.entryPointsCount * SCRIPT_TBLENTRY_LEN)) { - error("Script::loadModuleBase() Invalid table offset"); - } - - if (module.entryPointsCount > SCRIPT_MAX) { - error("Script::loadModuleBase()Script limit exceeded"); - } - - module.entryPoints = (EntryPoint *)malloc(module.entryPointsCount * sizeof(*module.entryPoints)); - if (module.entryPoints == NULL) { - memoryError("Script::loadModuleBase"); - } - - // Read in the entrypoint table - - module.staticSize = scriptS.readUint16(); - while (scriptS.pos() < module.entryPointsTableOffset) - scriptS.readByte(); - - for (i = 0; i < module.entryPointsCount; i++) { - // First uint16 is the offset of the entrypoint name from the start - // of the bytecode resource, second uint16 is the offset of the - // bytecode itself for said entrypoint - module.entryPoints[i].nameOffset = scriptS.readUint16(); - module.entryPoints[i].offset = scriptS.readUint16(); - - // Perform a simple range check on offset values - if ((module.entryPoints[i].nameOffset >= module.moduleBaseSize) || (module.entryPoints[i].offset >= module.moduleBaseSize)) { - error("Script::loadModuleBase() Invalid offset encountered in script entrypoint table"); - } - } -} - -void Script::loadVoiceLUT(VoiceLUT &voiceLUT, const byte *resourcePointer, size_t resourceLength) { - uint16 i; - - voiceLUT.voicesCount = resourceLength / 2; - - voiceLUT.voices = (uint16 *)malloc(voiceLUT.voicesCount * sizeof(*voiceLUT.voices)); - if (voiceLUT.voices == NULL) { - error("Script::loadVoiceLUT() not enough memory"); - } - - MemoryReadStreamEndian scriptS(resourcePointer, resourceLength, _scriptContext->isBigEndian); - - for (i = 0; i < voiceLUT.voicesCount; i++) { - voiceLUT.voices[i] = scriptS.readUint16(); - } -} - -// verb -void Script::showVerb(int statusColor) { - const char *verbName; - const char *object1Name; - const char *object2Name; - char statusString[STATUS_TEXT_LEN]; - - if (_leftButtonVerb == getVerbType(kVerbNone)) { - _vm->_interface->setStatusText(""); - return; - } - - verbName = _mainStrings.getString(_leftButtonVerb - 1); - - if (objectTypeId(_currentObject[0]) == kGameObjectNone) { - _vm->_interface->setStatusText(verbName, statusColor); - return; - } - - object1Name = _vm->getObjectName(_currentObject[0]); - - if (!_secondObjectNeeded) { - snprintf(statusString, STATUS_TEXT_LEN, "%s %s", verbName, object1Name); - _vm->_interface->setStatusText(statusString, statusColor); - return; - } - - - if (objectTypeId(_currentObject[1]) != kGameObjectNone) { - object2Name = _vm->getObjectName(_currentObject[1]); - } else { - object2Name = ""; - } - - if (_leftButtonVerb == getVerbType(kVerbGive)) { - snprintf(statusString, STATUS_TEXT_LEN, _vm->getTextString(kTextGiveTo), object1Name, object2Name); - _vm->_interface->setStatusText(statusString, statusColor); - } else { - if (_leftButtonVerb == getVerbType(kVerbUse)) { - snprintf(statusString, STATUS_TEXT_LEN, _vm->getTextString(kTextUseWidth), object1Name, object2Name); - _vm->_interface->setStatusText(statusString, statusColor); - } else { - snprintf(statusString, STATUS_TEXT_LEN, "%s %s", verbName, object1Name); - _vm->_interface->setStatusText(statusString, statusColor); - } - } -} - -int Script::getVerbType(VerbTypes verbType) { - if (_vm->getGameType() == GType_ITE) { - switch (verbType) { - case kVerbNone: - return kVerbITENone; - case kVerbWalkTo: - return kVerbITEWalkTo; - case kVerbGive: - return kVerbITEGive; - case kVerbUse: - return kVerbITEUse; - case kVerbEnter: - return kVerbITEEnter; - case kVerbLookAt: - return kVerbITELookAt; - case kVerbPickUp: - return kVerbITEPickUp; - case kVerbOpen: - return kVerbITEOpen; - case kVerbClose: - return kVerbITEClose; - case kVerbTalkTo: - return kVerbITETalkTo; - case kVerbWalkOnly: - return kVerbITEWalkOnly; - case kVerbLookOnly: - return kVerbITELookOnly; - case kVerbOptions: - return kVerbITEOptions; - } - } - else { - switch (verbType) { - case kVerbNone: - return kVerbIHNMNone; - case kVerbWalkTo: - return kVerbIHNMWalk; - case kVerbGive: - return kVerbIHNMGive; - case kVerbUse: - return kVerbIHNMUse; - case kVerbEnter: - return kVerbIHNMEnter; - case kVerbLookAt: - return kVerbIHNMLookAt; - case kVerbPickUp: - return kVerbIHNMTake; - case kVerbOpen: - return -2; - case kVerbClose: - return -2; - case kVerbTalkTo: - return kVerbIHNMTalkTo; - case kVerbWalkOnly: - return kVerbIHNMWalkOnly; - case kVerbLookOnly: - return kVerbIHNMLookOnly; - case kVerbOptions: - return kVerbIHNMOptions; - } - } - error("Script::getVerbType() unknown verb type %d", verbType); -} - -void Script::setVerb(int verb) { - _pendingObject[0] = ID_NOTHING; - _currentObject[0] = ID_NOTHING; - _pendingObject[1] = ID_NOTHING; - _currentObject[1] = ID_NOTHING; - _firstObjectSet = false; - _secondObjectNeeded = false; - - // The pointer object will be updated again immediately. This way the - // new verb will be applied to it. It's not exactly how the original - // engine did it, but it appears to work. - _pointerObject = ID_NOTHING; - - setLeftButtonVerb( verb ); - showVerb(); -} - -void Script::setLeftButtonVerb(int verb) { - int oldVerb = _currentVerb; - - _currentVerb = _leftButtonVerb = verb; - - if ((_currentVerb != oldVerb) && (_vm->_interface->getMode() == kPanelMain)){ - if (oldVerb > getVerbType(kVerbNone)) - _vm->_interface->setVerbState(oldVerb, 2); - - if (_currentVerb > getVerbType(kVerbNone)) - _vm->_interface->setVerbState(_currentVerb, 2); - } -} - -void Script::setRightButtonVerb(int verb) { - int oldVerb = _rightButtonVerb; - - _rightButtonVerb = verb; - - if ((_rightButtonVerb != oldVerb) && (_vm->_interface->getMode() == kPanelMain)){ - if (oldVerb > getVerbType(kVerbNone)) - _vm->_interface->setVerbState(oldVerb, 2); - - if (_rightButtonVerb > getVerbType(kVerbNone)) - _vm->_interface->setVerbState(_rightButtonVerb, 2); - } -} - -void Script::doVerb() { - int scriptEntrypointNumber = 0; - int scriptModuleNumber = 0; - int objectType; - Event event; - const char *excuseText; - int excuseSampleResourceId; - const HitZone *hitZone; - - objectType = objectTypeId(_pendingObject[0]); - - if (_pendingVerb == getVerbType(kVerbGive)) { - scriptEntrypointNumber = _vm->_actor->getObjectScriptEntrypointNumber(_pendingObject[1]); - if (_vm->_actor->getObjectFlags(_pendingObject[1]) & (kFollower|kProtagonist|kExtended)) { - scriptModuleNumber = 0; - } else { - scriptModuleNumber = _vm->_scene->getScriptModuleNumber(); - } - } else { - if (_pendingVerb == getVerbType(kVerbUse)) { - if ((objectTypeId(_pendingObject[1]) > kGameObjectNone) && (objectType < objectTypeId(_pendingObject[1]))) { - SWAP(_pendingObject[0], _pendingObject[1]); - objectType = objectTypeId(_pendingObject[0]); - } - } - - if (objectType == kGameObjectHitZone) { - scriptModuleNumber = _vm->_scene->getScriptModuleNumber(); - hitZone = _vm->_scene->_objectMap->getHitZone(objectIdToIndex(_pendingObject[0])); - if ((hitZone->getFlags() & kHitZoneExit) == 0) { - scriptEntrypointNumber = hitZone->getScriptNumber(); - } - } else { - if (objectType & (kGameObjectActor | kGameObjectObject)) { - scriptEntrypointNumber = _vm->_actor->getObjectScriptEntrypointNumber(_pendingObject[0]); - - if ((objectType == kGameObjectActor) && !(_vm->_actor->getObjectFlags(_pendingObject[0]) & (kFollower|kProtagonist|kExtended))) { - scriptModuleNumber = _vm->_scene->getScriptModuleNumber(); - } else { - scriptModuleNumber = 0; - } - } - } - } - - if (scriptEntrypointNumber > 0) { - - event.type = kEvTOneshot; - event.code = kScriptEvent; - event.op = kEventExecNonBlocking; - event.time = 0; - event.param = scriptModuleNumber; - event.param2 = scriptEntrypointNumber; - event.param3 = _pendingVerb; // Action - event.param4 = _pendingObject[0]; // Object - event.param5 = _pendingObject[1]; // With Object - event.param6 = (objectType == kGameObjectActor) ? _pendingObject[0] : ID_PROTAG; // Actor - - _vm->_events->queue(&event); - - } else { - _vm->getExcuseInfo(_pendingVerb, excuseText, excuseSampleResourceId); - if (excuseText) { - // In Floppy versions we don't have excuse texts - if (!(_vm->getFeatures() & GF_CD_FX)) - excuseSampleResourceId = -1; - - _vm->_actor->actorSpeech(ID_PROTAG, &excuseText, 1, excuseSampleResourceId, 0); - } - } - - if ((_currentVerb == getVerbType(kVerbWalkTo)) || (_currentVerb == getVerbType(kVerbLookAt))) { - _stickyVerb = _currentVerb; - } - - _pendingVerb = getVerbType(kVerbNone); - _currentObject[0] = _currentObject[1] = ID_NOTHING; - setLeftButtonVerb(_stickyVerb); - - setPointerVerb(); -} - -void Script::setPointerVerb() { - if (_vm->_interface->isActive()) { - _pointerObject = ID_PROTAG; - whichObject(_vm->mousePos()); - } -} - -void Script::hitObject(bool leftButton) { - int verb; - verb = leftButton ? _leftButtonVerb : _rightButtonVerb; - - if (verb > getVerbType(kVerbNone)) { - if (_firstObjectSet) { - if (_secondObjectNeeded) { - _pendingObject[0] = _currentObject[0]; - _pendingObject[1] = _currentObject[1]; - _pendingVerb = verb; - - _leftButtonVerb = verb; - if (_pendingVerb > getVerbType(kVerbNone)) - showVerb(kITEColorBrightWhite); - else - showVerb(); - - _secondObjectNeeded = false; - _firstObjectSet = false; - return; - } - } else { - if (verb == getVerbType(kVerbGive)) { - _secondObjectNeeded = true; - } else { - if (verb == getVerbType(kVerbUse)) { - - if (_currentObjectFlags[0] & kObjUseWith) { - _secondObjectNeeded = true; - } - } - } - - if (!_secondObjectNeeded) { - _pendingObject[0] = _currentObject[0]; - _pendingObject[1] = ID_NOTHING; - _pendingVerb = verb; - - _secondObjectNeeded = false; - _firstObjectSet = false; - } else { - _firstObjectSet = true; - } - } - - _leftButtonVerb = verb; - if (_pendingVerb > getVerbType(kVerbNone)) - showVerb(kITEColorBrightWhite); - else - showVerb(); - } - -} - -void Script::playfieldClick(const Point& mousePoint, bool leftButton) { - Location pickLocation; - const HitZone *hitZone; - Point specialPoint; - - _vm->_actor->abortSpeech(); - - if ((_vm->_actor->_protagonist->_currentAction != kActionWait) && - (_vm->_actor->_protagonist->_currentAction != kActionFreeze) && - (_vm->_actor->_protagonist->_currentAction != kActionWalkToLink) && - (_vm->_actor->_protagonist->_currentAction != kActionWalkToPoint)) { - return; - } - if (_pendingVerb > getVerbType(kVerbNone)) { - setLeftButtonVerb(getVerbType(kVerbWalkTo)); - } - - if (_pointerObject != ID_NOTHING) { - hitObject( leftButton ); - } else { - _pendingObject[0] = ID_NOTHING; - _pendingObject[1] = ID_NOTHING; - _pendingVerb = getVerbType(kVerbWalkTo); - } - - - // tiled stuff - if (_vm->_scene->getFlags() & kSceneFlagISO) { - _vm->_isoMap->screenPointToTileCoords(mousePoint, pickLocation); - } else { - pickLocation.fromScreenPoint(mousePoint); - } - - - hitZone = NULL; - - if (objectTypeId(_pendingObject[0]) == kGameObjectHitZone) { - hitZone = _vm->_scene->_objectMap->getHitZone(objectIdToIndex(_pendingObject[0])); - } else { - if ((_pendingVerb == getVerbType(kVerbUse)) && (objectTypeId(_pendingObject[1]) == kGameObjectHitZone)) { - hitZone = _vm->_scene->_objectMap->getHitZone(objectIdToIndex(_pendingObject[1])); - } - } - - if (hitZone != NULL) { - if (hitZone->getFlags() & kHitZoneNoWalk) { - _vm->_actor->actorFaceTowardsPoint(ID_PROTAG, pickLocation); - doVerb(); - return; - } - - if (hitZone->getFlags() & kHitZoneProject) { - if (!hitZone->getSpecialPoint(specialPoint)) { - // Original behaved this way and this prevents from crash - // at ruins. See bug #1257459 - specialPoint.x = specialPoint.y = 0; - } - - // tiled stuff - if (_vm->_scene->getFlags() & kSceneFlagISO) { - pickLocation.u() = specialPoint.x; - pickLocation.v() = specialPoint.y; - pickLocation.z = _vm->_actor->_protagonist->_location.z; - } else { - pickLocation.fromScreenPoint(specialPoint); - } - } - } - - if ((_pendingVerb == getVerbType(kVerbWalkTo)) || - (_pendingVerb == getVerbType(kVerbPickUp)) || - (_pendingVerb == getVerbType(kVerbOpen)) || - (_pendingVerb == getVerbType(kVerbClose)) || - (_pendingVerb == getVerbType(kVerbUse))) { - _vm->_actor->actorWalkTo(ID_PROTAG, pickLocation); - } else { - if (_pendingVerb == getVerbType(kVerbLookAt)) { - if (objectTypeId(_pendingObject[0]) != kGameObjectActor ) { - _vm->_actor->actorWalkTo(ID_PROTAG, pickLocation); - } else { - doVerb(); - } - } else { - if ((_pendingVerb == getVerbType(kVerbTalkTo)) || - (_pendingVerb == getVerbType(kVerbGive))) { - doVerb(); - } - } - } -} - -void Script::whichObject(const Point& mousePoint) { - uint16 objectId; - int16 objectFlags; - int newRightButtonVerb; - uint16 newObjectId; - ActorData *actor; - ObjectData *obj; - Point pickPoint; - Location pickLocation; - int hitZoneIndex; - const HitZone * hitZone; - PanelButton * panelButton; - - objectId = ID_NOTHING; - objectFlags = 0; - _leftButtonVerb = _currentVerb; - newRightButtonVerb = getVerbType(kVerbNone); - - if (_vm->_actor->_protagonist->_currentAction != kActionWalkDir) { - if (_vm->_scene->getHeight() >= mousePoint.y) { - newObjectId = _vm->_actor->hitTest(mousePoint, true); - - if (newObjectId != ID_NOTHING) { - if (objectTypeId(newObjectId) == kGameObjectObject) { - objectId = newObjectId; - objectFlags = 0; - newRightButtonVerb = getVerbType(kVerbLookAt); - - if ((_currentVerb == getVerbType(kVerbTalkTo)) || ((_currentVerb == getVerbType(kVerbGive)) && _firstObjectSet)) { - objectId = ID_NOTHING; - newObjectId = ID_NOTHING; - } - } else { - actor = _vm->_actor->getActor(newObjectId); - objectId = newObjectId; - objectFlags = kObjUseWith; - newRightButtonVerb = getVerbType(kVerbTalkTo); - - if ((_currentVerb == getVerbType(kVerbPickUp)) || - (_currentVerb == getVerbType(kVerbOpen)) || - (_currentVerb == getVerbType(kVerbClose)) || - ((_currentVerb == getVerbType(kVerbGive)) && !_firstObjectSet) || - ((_currentVerb == getVerbType(kVerbUse)) && !(actor->_flags & kFollower))) { - objectId = ID_NOTHING; - newObjectId = ID_NOTHING; - } - } - } - - if (newObjectId == ID_NOTHING) { - - pickPoint = mousePoint; - - if (_vm->_scene->getFlags() & kSceneFlagISO) { - pickPoint.y -= _vm->_actor->_protagonist->_location.z; - _vm->_isoMap->screenPointToTileCoords(pickPoint, pickLocation); - pickLocation.toScreenPointUV(pickPoint); - } - - hitZoneIndex = _vm->_scene->_objectMap->hitTest(pickPoint); - - if ((hitZoneIndex != -1)) { - hitZone = _vm->_scene->_objectMap->getHitZone(hitZoneIndex); - objectId = hitZone->getHitZoneId(); - objectFlags = 0; - newRightButtonVerb = hitZone->getRightButtonVerb() & 0x7f; - - if (_vm->getGameType() == GType_ITE) { - - if (newRightButtonVerb == getVerbType(kVerbWalkOnly)) { - if (_firstObjectSet) { - objectId = ID_NOTHING; - } else { - newRightButtonVerb = _leftButtonVerb = getVerbType(kVerbWalkTo); - } - } else { - if (newRightButtonVerb == getVerbType(kVerbLookOnly)) { - if (_firstObjectSet) { - objectId = ID_NOTHING; - } else { - newRightButtonVerb = _leftButtonVerb = getVerbType(kVerbLookAt); - } - } - } - - if (newRightButtonVerb >= getVerbType(kVerbOptions)) { - newRightButtonVerb = getVerbType(kVerbNone); - } - } - - if ((_currentVerb == getVerbType(kVerbTalkTo)) || ((_currentVerb == getVerbType(kVerbGive)) && _firstObjectSet)) { - objectId = ID_NOTHING; - newObjectId = ID_NOTHING; - } - - if ((_leftButtonVerb == getVerbType(kVerbUse)) && (hitZone->getRightButtonVerb() & 0x80)) { - objectFlags = kObjUseWith; - } - } - } - } else { - if ((_currentVerb == getVerbType(kVerbTalkTo)) || ((_currentVerb == getVerbType(kVerbGive)) && _firstObjectSet)) { - // no way - } else { - panelButton = _vm->_interface->inventoryHitTest(mousePoint); - if (panelButton) { - objectId = _vm->_interface->getInventoryContentByPanelButton(panelButton); - if (objectId != 0) { - obj = _vm->_actor->getObj(objectId); - newRightButtonVerb = getVerbType(kVerbLookAt); - if (obj->_interactBits & kObjUseWith) { - objectFlags = kObjUseWith; - } - } - } - } - - if ((_currentVerb == getVerbType(kVerbPickUp)) || (_currentVerb == getVerbType(kVerbTalkTo)) || (_currentVerb == getVerbType(kVerbWalkTo))) { - _leftButtonVerb = getVerbType(kVerbLookAt); - } - } - } - - if (objectId != _pointerObject) { - _pointerObject = objectId; - _currentObject[_firstObjectSet ? 1 : 0] = objectId; - _currentObjectFlags[_firstObjectSet ? 1 : 0] = objectFlags; - if (_pendingVerb == getVerbType(kVerbNone)) { - showVerb(); - } - } - - if (newRightButtonVerb != _rightButtonVerb) { - setRightButtonVerb(newRightButtonVerb); - } -} - -} // End of namespace Saga diff --git a/saga/script.h b/saga/script.h deleted file mode 100644 index bc11013b3f..0000000000 --- a/saga/script.h +++ /dev/null @@ -1,637 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Scripting module private header - -#ifndef SAGA_SCRIPT_H -#define SAGA_SCRIPT_H - -#include "saga/font.h" -#include "saga/list.h" - -namespace Saga { - -#define COMMON_BUFFER_SIZE 1024 // Why 1024? - -#define S_LUT_ENTRYLEN_ITECD 22 -#define S_LUT_ENTRYLEN_ITEDISK 16 - -#define SCRIPT_TBLENTRY_LEN 4 - -#define SCRIPT_MAX 5000 - -#define ITE_SCRIPT_FUNCTION_MAX 78 -#define IHNM_SCRIPT_FUNCTION_MAX 105 -#define DEFAULT_THREAD_STACK_SIZE 256 - -enum AddressTypes { - kAddressCommon = 0, // offset from global variables - kAddressStatic = 1, // offset from global variables - kAddressModule = 2, // offset from start of module - kAddressStack = 3, // offset from stack - kAddressThread = 4 // offset from thread structure -/* kAddressId = 5, // offset from const id object - kAddressIdIndirect = 6, // offset from stack id object - kAddressIndex = 7 // index from id*/ -}; - -enum VerbTypeIds { - kVerbITENone = 0, - kVerbITEPickUp = 1, - kVerbITELookAt = 2, - kVerbITEWalkTo = 3, - kVerbITETalkTo = 4, - kVerbITEOpen = 5, - kVerbITEClose = 6, - kVerbITEGive = 7, - kVerbITEUse = 8, - kVerbITEOptions = 9, - kVerbITEEnter = 10, - kVerbITELeave = 11, - kVerbITEBegin = 12, - kVerbITEWalkOnly = 13, - kVerbITELookOnly = 14, - - - kVerbIHNMNone = 0, - kVerbIHNMWalk = 1, - kVerbIHNMLookAt = 2, - kVerbIHNMTake = 3, - kVerbIHNMUse = 4, - kVerbIHNMTalkTo = 5, - kVerbIHNMSwallow = 6, - kVerbIHNMGive = 7, - kVerbIHNMPush = 8, - kVerbIHNMOptions = 9, - kVerbIHNMEnter = 10, - kVerbIHNMLeave = 11, - kVerbIHNMBegin = 12, - kVerbIHNMWalkOnly = 13, - kVerbIHNMLookOnly = 14, - - kVerbTypeIdsMax = kVerbITELookOnly + 1 -}; - -enum VerbTypes { - kVerbNone, - kVerbWalkTo, - kVerbGive, - kVerbUse, - kVerbEnter, - kVerbLookAt, - kVerbPickUp, - kVerbOpen, - kVerbClose, - kVerbTalkTo, - kVerbWalkOnly, - kVerbLookOnly, - kVerbOptions -}; - -#define STHREAD_TIMESLICE 8 - -enum ThreadVarTypes { - kThreadVarObject = 0, - kThreadVarWithObject = 1, - kThreadVarAction = 2, - kThreadVarActor = 3, - - kThreadVarMax = kThreadVarActor + 1 -}; - -enum ThreadFlags { - kTFlagNone = 0, - kTFlagWaiting = 1, // wait for even denoted in waitType - kTFlagFinished = 2, - kTFlagAborted = 4, - kTFlagAsleep = kTFlagWaiting | kTFlagFinished | kTFlagAborted // Combination of all flags which can halt a thread -}; - -enum ThreadWaitTypes { - kWaitTypeNone = 0, // waiting for nothing - kWaitTypeDelay = 1, // waiting for a timer - kWaitTypeSpeech = 2, // waiting for speech to finish - kWaitTypeDialogEnd = 3, // waiting for my dialog to finish - kWaitTypeDialogBegin = 4, // waiting for other dialog to finish - kWaitTypeWalk = 5, // waiting to finish walking - kWaitTypeRequest = 6, // a request is up - kWaitTypePause = 7, - kWaitTypePlacard = 8, - kWaitTypeStatusTextInput = 9, - kWaitTypeWaitFrames = 10 // IHNM. waiting for a frame count -}; - -enum OpCodes { - opNextBlock = 0x01, - opDup = 0x02, - opDrop = 0x03, - opZero = 0x04, - opOne = 0x05, - opConstint = 0x06, -//... - opStrlit = 0x08, -//... - opGetFlag = 0x0B, - opGetInt = 0x0C, -//... - opPutFlag = 0x0F, - opPutInt = 0x10, - //... - opPutFlagV = 0x13, - opPutIntV = 0x14, -//... - opCall = 0x17, - opCcall = 0x18, - opCcallV = 0x19, - opEnter = 0x1A, - opReturn = 0x1B, - opReturnV = 0x1C, - opJmp = 0x1D, - opJmpTrueV = 0x1E, - opJmpFalseV = 0x1F, - opJmpTrue = 0x20, - opJmpFalse = 0x21, - opJmpSwitch = 0x22, -//... - opJmpRandom = 0x24, - opNegate = 0x25, - opNot = 0x26, - opCompl = 0x27, - opIncV = 0x28, - opDecV = 0x29, - opPostInc = 0x2A, - opPostDec = 0x2B, - opAdd = 0x2C, - opSub = 0x2D, - opMul = 0x2E, - opDiv = 0x2F, - opMod = 0x30, -//... - opEq = 0x33, - opNe = 0x34, - opGt = 0x35, - opLt = 0x36, - opGe = 0x37, - opLe = 0x38, -//... - opRsh = 0x3F, - opLsh = 0x40, - opAnd = 0x41, - opOr = 0x42, - opXor = 0x43, - opLAnd = 0x44, - opLOr = 0x45, - opLXor = 0x46, -//... - opSpeak = 0x53, - opDialogBegin = 0x54, - opDialogEnd = 0x55, - opReply = 0x56, - opAnimate = 0x57 -}; - -enum CycleFlags { - kCyclePong = 1 << 0, - kCycleOnce = 1 << 1, - kCycleRandom = 1 << 2, - kCycleReverse = 1 << 3 -}; - -enum WalkFlags { - kWalkBackPedal = 1 << 0, - kWalkAsync = 1 << 1, - kWalkUseAngle = 1 << 2, - kWalkFace = 1 << 5 -}; - -enum ReplyFlags { - kReplyOnce = 1 << 0, - kReplySummary = 1 << 1, - kReplyCondition = 1 << 2 -}; - -struct EntryPoint { - uint16 nameOffset; - uint16 offset; -}; - -struct VoiceLUT { - uint16 voicesCount; - uint16 *voices; - void freeMem() { - voicesCount = 0; - free(voices); - } - VoiceLUT() { - memset(this, 0, sizeof(*this)); - } -}; - -struct ModuleData { - bool loaded; // is it loaded or not? - int scriptResourceId; - int stringsResourceId; - int voicesResourceId; - - byte *moduleBase; // all base module - uint16 moduleBaseSize; // base module size - uint16 staticSize; // size of static data - uint staticOffset; // offset of static data begining in _commonBuffer - - uint16 entryPointsTableOffset; // offset of entrypoint table in moduleBase - uint16 entryPointsCount; - EntryPoint *entryPoints; - - StringsTable strings; - VoiceLUT voiceLUT; - void freeMem() { - strings.freeMem(); - voiceLUT.freeMem(); - free(moduleBase); - free(entryPoints); - memset(this, 0x0, sizeof(*this)); - } -}; - -class ScriptThread { -public: - uint16 *_stackBuf; - uint16 _stackSize; // stack size in uint16 - - uint16 _stackTopIndex; - uint16 _frameIndex; - - uint16 _threadVars[kThreadVarMax]; - - byte *_moduleBase; // - uint16 _moduleBaseSize; - - byte *_commonBase; // - byte *_staticBase; // - VoiceLUT *_voiceLUT; // - StringsTable *_strings; // - - int _flags; // ThreadFlags - int _waitType; // ThreadWaitTypes - uint _sleepTime; - void *_threadObj; // which object we're handling - - int16 _returnValue; - - uint16 _instructionOffset; // Instruction offset - - int32 _frameWait; - -public: - byte *baseAddress(byte addrMode) { - switch (addrMode) { - case kAddressCommon: - return _commonBase; - case kAddressStatic: - return _staticBase; - case kAddressModule: - return _moduleBase; - case kAddressStack: - return (byte*)&_stackBuf[_frameIndex]; - case kAddressThread: - return (byte*)_threadVars; - default: - return _commonBase; - } - } - - int16 stackTop() { - return (int16)_stackBuf[_stackTopIndex]; - } - - uint pushedSize() { - return _stackSize - _stackTopIndex - 2; - } - - void push(int16 value) { - if (_stackTopIndex <= 0) { - error("ScriptThread::push() stack overflow"); - } - _stackBuf[--_stackTopIndex] = (uint16)value; - } - - int16 pop() { - if (_stackTopIndex >= _stackSize) { - error("ScriptThread::pop() stack underflow"); - } - return (int16)_stackBuf[_stackTopIndex++]; - } - - -// wait stuff - void wait(int waitType) { - _waitType = waitType; - _flags |= kTFlagWaiting; - } - - void waitWalk(void *threadObj) { - wait(kWaitTypeWalk); - _threadObj = threadObj; - } - - void waitDelay(int sleepTime) { - wait(kWaitTypeDelay); - _sleepTime = sleepTime; - } - - ScriptThread() { - memset(this, 0xFE, sizeof(*this)); - _stackBuf = NULL; - } - ~ScriptThread() { - free(_stackBuf); - } -}; - -typedef SortedList<ScriptThread> ScriptThreadList; - - -#define SCRIPTFUNC_PARAMS ScriptThread *thread, int nArgs, bool &disContinue - -class Script { -public: - StringsTable _mainStrings; - - Script(SagaEngine *vm); - ~Script(); - - void loadModule(int scriptModuleNumber); - void freeModules(); - - void doVerb(); - void showVerb(int statusColor = -1); - void setVerb(int verb); - int getCurrentVerb() const { return _currentVerb; } - void setPointerVerb(); - void whichObject(const Point& mousePoint); - void hitObject(bool leftButton); - void playfieldClick(const Point& mousePoint, bool leftButton); - - void setLeftButtonVerb(int verb); - int getLeftButtonVerb() const { return _leftButtonVerb; } - void setRightButtonVerb(int verb); - int getRightButtonVerb() const { return _rightButtonVerb; } - void setNonPlayfieldVerb() { - setRightButtonVerb(getVerbType(kVerbNone)); - _pointerObject = ID_NOTHING; - _currentObject[_firstObjectSet ? 1 : 0] = ID_NOTHING; - } - void setNoPendingVerb() { - _pendingVerb = getVerbType(kVerbNone); - _currentObject[0] = _currentObject[0] = ID_NOTHING; - setPointerVerb(); - } - int getVerbType(VerbTypes verbType); - -private: - // When reading or writing data to the common buffer, we have to use a - // well-defined byte order since it's stored in savegames. Otherwise, - // we use native byte ordering since that data may be accessed in other - // ways than through these functions. - // - // The "module" area is a special case, which possibly never ever - // happens. But if it does, we need well-defined byte ordering. - - uint16 readUint16(byte *addr, byte addrMode) { - switch (addrMode) { - case kAddressCommon: - case kAddressStatic: - case kAddressModule: - return READ_LE_UINT16(addr); - default: - return READ_UINT16(addr); - } - } - - void writeUint16(byte *addr, uint16 value, byte addrMode) { - switch (addrMode) { - case kAddressCommon: - case kAddressStatic: - case kAddressModule: - WRITE_LE_UINT16(addr, value); - break; - default: - WRITE_UINT16(addr, value); - break; - } - } - - SagaEngine *_vm; - ResourceContext *_scriptContext; - - uint16 _modulesLUTEntryLen; - ModuleData *_modules; - int _modulesCount; - TextListEntry *_placardTextEntry; - -protected: - friend class SagaEngine; - byte *_commonBuffer; - uint _commonBufferSize; - -private: - uint _staticSize; - - ScriptThreadList _threadList; - - ScriptThread *_conversingThread; - -//verb - bool _firstObjectSet; - bool _secondObjectNeeded; - uint16 _currentObject[2]; - int16 _currentObjectFlags[2]; - int _currentVerb; - int _stickyVerb; - int _leftButtonVerb; - int _rightButtonVerb; - -public: - uint16 _pendingObject[2]; - int _pendingVerb; - uint16 _pointerObject; - - bool _skipSpeeches; - bool _abortEnabled; - - VoiceLUT _globalVoiceLUT; - -public: - ScriptThread *createThread(uint16 scriptModuleNumber, uint16 scriptEntryPointNumber); - int executeThread(ScriptThread *thread, int entrypointNumber); - void executeThreads(uint msec); - void completeThread(void); - void abortAllThreads(void); - - void wakeUpActorThread(int waitType, void *threadObj); - void wakeUpThreads(int waitType); - void wakeUpThreadsDelayed(int waitType, int sleepTime); - - void loadVoiceLUT(VoiceLUT &voiceLUT, const byte *resourcePointer, size_t resourceLength); - -private: - void loadModuleBase(ModuleData &module, const byte *resourcePointer, size_t resourceLength); - - // runThread returns true if we should break running of other threads - bool runThread(ScriptThread *thread, uint instructionLimit); - void setThreadEntrypoint(ScriptThread *thread, int entrypointNumber); - -public: - void finishDialog(int replyID, int flags, int bitOffset); - -private: - - typedef void (Script::*ScriptFunctionType)(SCRIPTFUNC_PARAMS); - - struct ScriptFunctionDescription { - ScriptFunctionType scriptFunction; - const char *scriptFunctionName; - }; - const ScriptFunctionDescription *_scriptFunctionsList; - - void setupScriptFuncList(void); - - void sfPutString(SCRIPTFUNC_PARAMS); - void sfWait(SCRIPTFUNC_PARAMS); - void sfTakeObject(SCRIPTFUNC_PARAMS); - void sfIsCarried(SCRIPTFUNC_PARAMS); - void sfStatusBar(SCRIPTFUNC_PARAMS); - void sfMainMode(SCRIPTFUNC_PARAMS); - void sfScriptWalkTo(SCRIPTFUNC_PARAMS); - void sfScriptDoAction(SCRIPTFUNC_PARAMS); - void sfSetActorFacing(SCRIPTFUNC_PARAMS); - void sfStartBgdAnim(SCRIPTFUNC_PARAMS); - void sfStopBgdAnim(SCRIPTFUNC_PARAMS); - void sfLockUser(SCRIPTFUNC_PARAMS); - void sfPreDialog(SCRIPTFUNC_PARAMS); - void sfKillActorThreads(SCRIPTFUNC_PARAMS); - void sfFaceTowards(SCRIPTFUNC_PARAMS); - void sfSetFollower(SCRIPTFUNC_PARAMS); - void sfScriptGotoScene(SCRIPTFUNC_PARAMS); - - void sfSetObjImage(SCRIPTFUNC_PARAMS); - void sfSetObjName(SCRIPTFUNC_PARAMS); - void sfGetObjImage(SCRIPTFUNC_PARAMS); - void sfGetNumber(SCRIPTFUNC_PARAMS); - void sfScriptOpenDoor(SCRIPTFUNC_PARAMS); - void sfScriptCloseDoor(SCRIPTFUNC_PARAMS); - void sfSetBgdAnimSpeed(SCRIPTFUNC_PARAMS); - void SF_cycleColors(SCRIPTFUNC_PARAMS); - void sfDoCenterActor(SCRIPTFUNC_PARAMS); - void sfStartBgdAnimSpeed(SCRIPTFUNC_PARAMS); - void sfScriptWalkToAsync(SCRIPTFUNC_PARAMS); - void sfEnableZone(SCRIPTFUNC_PARAMS); - void sfSetActorState(SCRIPTFUNC_PARAMS); - void sfScriptMoveTo(SCRIPTFUNC_PARAMS); - void sfSceneEq(SCRIPTFUNC_PARAMS); - void sfDropObject(SCRIPTFUNC_PARAMS); - void sfFinishBgdAnim(SCRIPTFUNC_PARAMS); - void sfSwapActors(SCRIPTFUNC_PARAMS); - void sfSimulSpeech(SCRIPTFUNC_PARAMS); - void sfScriptWalk(SCRIPTFUNC_PARAMS); - void sfCycleFrames(SCRIPTFUNC_PARAMS); - void sfSetFrame(SCRIPTFUNC_PARAMS); - void sfSetPortrait(SCRIPTFUNC_PARAMS); - void sfSetProtagPortrait(SCRIPTFUNC_PARAMS); - void sfChainBgdAnim(SCRIPTFUNC_PARAMS); - void sfScriptSpecialWalk(SCRIPTFUNC_PARAMS); - void sfPlaceActor(SCRIPTFUNC_PARAMS); - void sfCheckUserInterrupt(SCRIPTFUNC_PARAMS); - void sfScriptWalkRelative(SCRIPTFUNC_PARAMS); - void sfScriptMoveRelative(SCRIPTFUNC_PARAMS); - void sfSimulSpeech2(SCRIPTFUNC_PARAMS); - void sfPlacard(SCRIPTFUNC_PARAMS); - void sfPlacardOff(SCRIPTFUNC_PARAMS); - void sfSetProtagState(SCRIPTFUNC_PARAMS); - void sfResumeBgdAnim(SCRIPTFUNC_PARAMS); - void sfThrowActor(SCRIPTFUNC_PARAMS); - void sfWaitWalk(SCRIPTFUNC_PARAMS); - void sfScriptSceneID(SCRIPTFUNC_PARAMS); - void sfChangeActorScene(SCRIPTFUNC_PARAMS); - void sfScriptClimb(SCRIPTFUNC_PARAMS); - void sfSetDoorState(SCRIPTFUNC_PARAMS); - void sfSetActorZ(SCRIPTFUNC_PARAMS); - void sfScriptText(SCRIPTFUNC_PARAMS); - void sfGetActorX(SCRIPTFUNC_PARAMS); - void sfGetActorY(SCRIPTFUNC_PARAMS); - void sfEraseDelta(SCRIPTFUNC_PARAMS); - void sfPlayMusic(SCRIPTFUNC_PARAMS); - void sfPickClimbOutPos(SCRIPTFUNC_PARAMS); - void sfTossRif(SCRIPTFUNC_PARAMS); - void sfShowControls(SCRIPTFUNC_PARAMS); - void sfShowMap(SCRIPTFUNC_PARAMS); - void sfPuzzleWon(SCRIPTFUNC_PARAMS); - void sfEnableEscape(SCRIPTFUNC_PARAMS); - void sfPlaySound(SCRIPTFUNC_PARAMS); - void sfPlayLoopedSound(SCRIPTFUNC_PARAMS); - void sfGetDeltaFrame(SCRIPTFUNC_PARAMS); - void sfShowProtect(SCRIPTFUNC_PARAMS); - void sfProtectResult(SCRIPTFUNC_PARAMS); - void sfRand(SCRIPTFUNC_PARAMS); - void sfFadeMusic(SCRIPTFUNC_PARAMS); - void sfScriptStartCutAway(SCRIPTFUNC_PARAMS); - void sfReturnFromCutAway(SCRIPTFUNC_PARAMS); - void sfEndCutAway(SCRIPTFUNC_PARAMS); - void sfGetMouseClicks(SCRIPTFUNC_PARAMS); - void sfResetMouseClicks(SCRIPTFUNC_PARAMS); - void sfWaitFrames(SCRIPTFUNC_PARAMS); - void sfScriptFade(SCRIPTFUNC_PARAMS); - void sfPlayVoice(SCRIPTFUNC_PARAMS); - void sfVstopFX(SCRIPTFUNC_PARAMS); - void sfVstopLoopedFX(SCRIPTFUNC_PARAMS); - void sfDemoIsInteractive(SCRIPTFUNC_PARAMS); - void sfVsetTrack(SCRIPTFUNC_PARAMS); - void sfDebugShowData(SCRIPTFUNC_PARAMS); - void sfNull(SCRIPTFUNC_PARAMS); - void sfWaitFramesEsc(SCRIPTFUNC_PARAMS); - void sfPsychicProfile(SCRIPTFUNC_PARAMS); - void sfPsychicProfileOff(SCRIPTFUNC_PARAMS); - void sfSetSpeechBox(SCRIPTFUNC_PARAMS); - void sfSetChapterPoints(SCRIPTFUNC_PARAMS); - void sfSetPortraitBgColor(SCRIPTFUNC_PARAMS); - void sfScriptStartVideo(SCRIPTFUNC_PARAMS); - void sfScriptReturnFromVideo(SCRIPTFUNC_PARAMS); - void sfScriptEndVideo(SCRIPTFUNC_PARAMS); - void sf87(SCRIPTFUNC_PARAMS); - void sf88(SCRIPTFUNC_PARAMS); - void sf89(SCRIPTFUNC_PARAMS); - void sfGetPoints(SCRIPTFUNC_PARAMS); - void sfSetGlobalFlag(SCRIPTFUNC_PARAMS); - void sfClearGlobalFlag(SCRIPTFUNC_PARAMS); - void sfTestGlobalFlag(SCRIPTFUNC_PARAMS); - void sfSetPoints(SCRIPTFUNC_PARAMS); - void sf103(SCRIPTFUNC_PARAMS); - void sfDisableAbortSpeeches(SCRIPTFUNC_PARAMS); - - void SF_stub(const char *name, ScriptThread *thread, int nArgs); -}; - -} // End of namespace Saga - -#endif diff --git a/saga/sfuncs.cpp b/saga/sfuncs.cpp deleted file mode 100644 index 9caa15150b..0000000000 --- a/saga/sfuncs.cpp +++ /dev/null @@ -1,2038 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Scripting module script function component - -#include "saga/saga.h" - -#include "saga/gfx.h" -#include "saga/actor.h" -#include "saga/animation.h" -#include "saga/console.h" -#include "saga/events.h" -#include "saga/font.h" -#include "saga/interface.h" -#include "saga/music.h" -#include "saga/itedata.h" -#include "saga/puzzle.h" -#include "saga/render.h" -#include "saga/sound.h" -#include "saga/sndres.h" - -#include "saga/script.h" -#include "saga/objectmap.h" - -#include "saga/scene.h" -#include "saga/isomap.h" -#include "saga/resnames.h" - -#include "common/config-manager.h" - -namespace Saga { - -#define OPCODE(x) {&Script::x, #x} - -void Script::setupScriptFuncList(void) { - static const ScriptFunctionDescription ITEscriptFunctionsList[ITE_SCRIPT_FUNCTION_MAX] = { - OPCODE(sfPutString), - OPCODE(sfWait), - OPCODE(sfTakeObject), - OPCODE(sfIsCarried), - OPCODE(sfStatusBar), - OPCODE(sfMainMode), - OPCODE(sfScriptWalkTo), - OPCODE(sfScriptDoAction), - OPCODE(sfSetActorFacing), - OPCODE(sfStartBgdAnim), - OPCODE(sfStopBgdAnim), - OPCODE(sfLockUser), - OPCODE(sfPreDialog), - OPCODE(sfKillActorThreads), - OPCODE(sfFaceTowards), - OPCODE(sfSetFollower), - OPCODE(sfScriptGotoScene), - OPCODE(sfSetObjImage), - OPCODE(sfSetObjName), - OPCODE(sfGetObjImage), - OPCODE(sfGetNumber), - OPCODE(sfScriptOpenDoor), - OPCODE(sfScriptCloseDoor), - OPCODE(sfSetBgdAnimSpeed), - OPCODE(SF_cycleColors), - OPCODE(sfDoCenterActor), - OPCODE(sfStartBgdAnimSpeed), - OPCODE(sfScriptWalkToAsync), - OPCODE(sfEnableZone), - OPCODE(sfSetActorState), - OPCODE(sfScriptMoveTo), - OPCODE(sfSceneEq), - OPCODE(sfDropObject), - OPCODE(sfFinishBgdAnim), - OPCODE(sfSwapActors), - OPCODE(sfSimulSpeech), - OPCODE(sfScriptWalk), - OPCODE(sfCycleFrames), - OPCODE(sfSetFrame), - OPCODE(sfSetPortrait), - OPCODE(sfSetProtagPortrait), - OPCODE(sfChainBgdAnim), - OPCODE(sfScriptSpecialWalk), - OPCODE(sfPlaceActor), - OPCODE(sfCheckUserInterrupt), - OPCODE(sfScriptWalkRelative), - OPCODE(sfScriptMoveRelative), - OPCODE(sfSimulSpeech2), - OPCODE(sfPlacard), - OPCODE(sfPlacardOff), - OPCODE(sfSetProtagState), - OPCODE(sfResumeBgdAnim), - OPCODE(sfThrowActor), - OPCODE(sfWaitWalk), - OPCODE(sfScriptSceneID), - OPCODE(sfChangeActorScene), - OPCODE(sfScriptClimb), - OPCODE(sfSetDoorState), - OPCODE(sfSetActorZ), - OPCODE(sfScriptText), - OPCODE(sfGetActorX), - OPCODE(sfGetActorY), - OPCODE(sfEraseDelta), - OPCODE(sfPlayMusic), - OPCODE(sfPickClimbOutPos), - OPCODE(sfTossRif), - OPCODE(sfShowControls), - OPCODE(sfShowMap), - OPCODE(sfPuzzleWon), - OPCODE(sfEnableEscape), - OPCODE(sfPlaySound), - OPCODE(sfPlayLoopedSound), - OPCODE(sfGetDeltaFrame), - OPCODE(sfShowProtect), - OPCODE(sfProtectResult), - OPCODE(sfRand), - OPCODE(sfFadeMusic), - OPCODE(sfPlayVoice) - }; - -static const ScriptFunctionDescription IHNMscriptFunctionsList[IHNM_SCRIPT_FUNCTION_MAX] = { - OPCODE(sfNull), - OPCODE(sfWait), - OPCODE(sfTakeObject), - OPCODE(sfIsCarried), - OPCODE(sfStatusBar), - OPCODE(sfMainMode), - OPCODE(sfScriptWalkTo), - OPCODE(sfScriptDoAction), - OPCODE(sfSetActorFacing), - OPCODE(sfStartBgdAnim), - OPCODE(sfStopBgdAnim), - OPCODE(sfNull), - OPCODE(sfPreDialog), - OPCODE(sfKillActorThreads), - OPCODE(sfFaceTowards), - OPCODE(sfSetFollower), - OPCODE(sfScriptGotoScene), - OPCODE(sfSetObjImage), - OPCODE(sfSetObjName), - OPCODE(sfGetObjImage), - OPCODE(sfGetNumber), - OPCODE(sfScriptOpenDoor), - OPCODE(sfScriptCloseDoor), - OPCODE(sfSetBgdAnimSpeed), - OPCODE(SF_cycleColors), - OPCODE(sfDoCenterActor), - OPCODE(sfStartBgdAnimSpeed), - OPCODE(sfScriptWalkToAsync), - OPCODE(sfEnableZone), - OPCODE(sfSetActorState), - OPCODE(sfScriptMoveTo), - OPCODE(sfSceneEq), - OPCODE(sfDropObject), - OPCODE(sfFinishBgdAnim), - OPCODE(sfSwapActors), - OPCODE(sfSimulSpeech), - OPCODE(sfScriptWalk), - OPCODE(sfCycleFrames), - OPCODE(sfSetFrame), - OPCODE(sfSetPortrait), - OPCODE(sfSetProtagPortrait), - OPCODE(sfChainBgdAnim), - OPCODE(sfScriptSpecialWalk), - OPCODE(sfPlaceActor), - OPCODE(sfCheckUserInterrupt), - OPCODE(sfScriptWalkRelative), - OPCODE(sfScriptMoveRelative), - OPCODE(sfSimulSpeech2), - OPCODE(sfPsychicProfile), - OPCODE(sfPsychicProfileOff), - OPCODE(sfSetProtagState), - OPCODE(sfResumeBgdAnim), - OPCODE(sfThrowActor), - OPCODE(sfWaitWalk), - OPCODE(sfScriptSceneID), - OPCODE(sfChangeActorScene), - OPCODE(sfScriptClimb), - OPCODE(sfSetDoorState), - OPCODE(sfSetActorZ), - OPCODE(sfScriptText), - OPCODE(sfGetActorX), - OPCODE(sfGetActorY), - OPCODE(sfEraseDelta), - OPCODE(sfPlayMusic), - OPCODE(sfNull), - OPCODE(sfEnableEscape), - OPCODE(sfPlaySound), - OPCODE(sfPlayLoopedSound), - OPCODE(sfGetDeltaFrame), - OPCODE(sfNull), - OPCODE(sfNull), - OPCODE(sfRand), - OPCODE(sfFadeMusic), - OPCODE(sfNull), - OPCODE(sfSetChapterPoints), - OPCODE(sfSetPortraitBgColor), - OPCODE(sfScriptStartCutAway), - OPCODE(sfReturnFromCutAway), - OPCODE(sfEndCutAway), - OPCODE(sfGetMouseClicks), - OPCODE(sfResetMouseClicks), - OPCODE(sfWaitFrames), - OPCODE(sfScriptFade), - OPCODE(sfScriptStartVideo), - OPCODE(sfScriptReturnFromVideo), - OPCODE(sfScriptEndVideo), - OPCODE(sfSetActorZ), - OPCODE(sf87), - OPCODE(sf88), - OPCODE(sf89), - OPCODE(sfVstopFX), - OPCODE(sfVstopLoopedFX), - OPCODE(sfNull), - OPCODE(sfDemoIsInteractive), - OPCODE(sfVsetTrack), - OPCODE(sfGetPoints), - OPCODE(sfSetGlobalFlag), - OPCODE(sfClearGlobalFlag), - OPCODE(sfTestGlobalFlag), - OPCODE(sfSetPoints), - OPCODE(sfSetSpeechBox), - OPCODE(sfDebugShowData), - OPCODE(sfWaitFramesEsc), - OPCODE(sf103), - OPCODE(sfDisableAbortSpeeches) - }; - if (_vm->getGameType() == GType_IHNM) - _scriptFunctionsList = IHNMscriptFunctionsList; - else - _scriptFunctionsList = ITEscriptFunctionsList; -} - -// Script function #0 (0x00) -// Print a debugging message -void Script::sfPutString(SCRIPTFUNC_PARAMS) { - const char *str; - str = thread->_strings->getString(thread->pop()); - - _vm->_console->DebugPrintf("sfPutString: %s\n",str); - debug(0, "sfPutString: %s", str); -} - -// Script function #1 (0x01) blocking -// Param1: time in ticks -void Script::sfWait(SCRIPTFUNC_PARAMS) { - int16 time; - time = thread->pop(); - - if (!_skipSpeeches) { - thread->waitDelay(ticksToMSec(time)); // put thread to sleep - } -} - -// Script function #2 (0x02) -void Script::sfTakeObject(SCRIPTFUNC_PARAMS) { - uint16 objectId = thread->pop(); - ObjectData *obj; - obj = _vm->_actor->getObj(objectId); - if (obj->_sceneNumber != ITE_SCENE_INV) { - obj->_sceneNumber = ITE_SCENE_INV; - //4debug for (int j=0;j<17;j++) - _vm->_interface->addToInventory(objectId); - } -} - -// Script function #3 (0x03) -// Check if an object is carried. -void Script::sfIsCarried(SCRIPTFUNC_PARAMS) { - uint16 objectId = thread->pop(); - CommonObjectData *object; - if (_vm->_actor->validObjId(objectId)) { - object = _vm->_actor->getObj(objectId); - thread->_returnValue = (object->_sceneNumber == ITE_SCENE_INV) ? 1 : 0; - } else { - thread->_returnValue = 0; - } - - -} - -// Script function #4 (0x04) nonblocking -// Set the command display to the specified text string -// Param1: dialogue index of string -void Script::sfStatusBar(SCRIPTFUNC_PARAMS) { - int16 stringIndex = thread->pop(); - - _vm->_interface->setStatusText(thread->_strings->getString(stringIndex)); -} - -// Script function #5 (0x05) -void Script::sfMainMode(SCRIPTFUNC_PARAMS) { - _vm->_actor->_centerActor = _vm->_actor->_protagonist; - - showVerb(); - _vm->_interface->activate(); - _vm->_interface->setMode(kPanelMain); - - if (_vm->getGameType() == GType_ITE) - setPointerVerb(); -} - -// Script function #6 (0x06) blocking -// Param1: actor id -// Param2: actor x -// Param3: actor y -void Script::sfScriptWalkTo(SCRIPTFUNC_PARAMS) { - uint16 actorId; - Location actorLocation; - ActorData *actor; - - actorId = thread->pop(); - actorLocation.x = thread->pop(); - actorLocation.y = thread->pop(); - - actor = _vm->_actor->getActor(actorId); - actorLocation.z = actor->_location.z; - - actor->_flags &= ~kFollower; - - if (_vm->_actor->actorWalkTo(actorId, actorLocation)) { - thread->waitWalk(actor); - } -} - -// Script function #7 (0x07) -// Param1: actor id -// Param2: action -// Param3: theObject -// Param4: withObject -void Script::sfScriptDoAction(SCRIPTFUNC_PARAMS) { - uint16 objectId; - uint16 action; - uint16 theObject; - uint16 withObject; - int16 scriptEntryPointNumber; - int16 moduleNumber; - ActorData *actor; - ObjectData *obj; - const HitZone *hitZone; - Event event; - - objectId = thread->pop(); - action = thread->pop(); - theObject = thread->pop(); - withObject = thread->pop(); - - switch (objectTypeId(objectId)) { - case kGameObjectObject: - obj = _vm->_actor->getObj(objectId); - scriptEntryPointNumber = obj->_scriptEntrypointNumber; - if (scriptEntryPointNumber <= 0) { - return; - } - moduleNumber = 0; - break; - case kGameObjectActor: - actor = _vm->_actor->getActor(objectId); - scriptEntryPointNumber = actor->_scriptEntrypointNumber; - if (scriptEntryPointNumber <= 0) { - return; - } - if (actor->_flags & (kProtagonist | kFollower)) { - moduleNumber = 0; - } else { - moduleNumber = _vm->_scene->getScriptModuleNumber(); - } - break; - case kGameObjectHitZone: - case kGameObjectStepZone: - if (objectTypeId(objectId) == kGameObjectHitZone) { - hitZone = _vm->_scene->_objectMap->getHitZone(objectIdToIndex(objectId)); - } else { - hitZone = _vm->_scene->_actionMap->getHitZone(objectIdToIndex(objectId)); - } - scriptEntryPointNumber = hitZone->getScriptNumber(); - moduleNumber = _vm->_scene->getScriptModuleNumber(); - break; - default: - error("Script::sfScriptDoAction wrong object type 0x%X", objectId); - } - - event.type = kEvTOneshot; - event.code = kScriptEvent; - event.op = kEventExecNonBlocking; - event.time = 0; - event.param = moduleNumber; - event.param2 = scriptEntryPointNumber; - event.param3 = action; // Action - event.param4 = theObject; // Object - event.param5 = withObject; // With Object - event.param6 = objectId; - - _vm->_events->queue(&event); -} - -// Script function #8 (0x08) nonblocking -// Param1: actor id -// Param2: actor orientation -void Script::sfSetActorFacing(SCRIPTFUNC_PARAMS) { - int16 actorId; - int actorDirection; - ActorData *actor; - - actorId = thread->pop(); - actorDirection = thread->pop(); - - actor = _vm->_actor->getActor(actorId); - actor->_facingDirection = actor->_actionDirection = actorDirection; - actor->_targetObject = ID_NOTHING; -} - -// Script function #9 (0x09) -void Script::sfStartBgdAnim(SCRIPTFUNC_PARAMS) { - int16 animId = thread->pop(); - int16 cycles = thread->pop(); - - _vm->_anim->setCycles(animId, cycles); - _vm->_anim->setFrameTime(animId, ticksToMSec(kRepeatSpeedTicks)); - _vm->_anim->play(animId, 0); - - debug(1, "sfStartBgdAnim(%d, %d)", animId, cycles); -} - -// Script function #10 (0x0A) -void Script::sfStopBgdAnim(SCRIPTFUNC_PARAMS) { - int16 animId = thread->pop(); - - _vm->_anim->stop(animId); - - debug(1, "sfStopBgdAnim(%d)", animId); -} - -// Script function #11 (0x0B) nonblocking -// If the parameter is true, the user interface is disabled while script -// continues to run. If the parameter is false, the user interface is -// reenabled. -// Param1: boolean -void Script::sfLockUser(SCRIPTFUNC_PARAMS) { - int16 lock; - - lock = thread->pop(); - - if (lock) { - _vm->_interface->deactivate(); - } else { - _vm->_interface->activate(); - } - -} - -// Script function #12 (0x0C) -// Disables mouse input, etc. -void Script::sfPreDialog(SCRIPTFUNC_PARAMS) { - _vm->_interface->deactivate(); - _vm->_interface->converseClear(); - if (_vm->_interface->isInMainMode()) - _vm->_interface->setMode(kPanelConverse); - else - _vm->_interface->converseDisplayText(); - - _vm->_interface->setMode(kPanelNull); -} - -// Script function #13 (0x0D) -void Script::sfKillActorThreads(SCRIPTFUNC_PARAMS) { - ScriptThread *anotherThread; - ScriptThreadList::iterator threadIterator; - int16 actorId; - - actorId = thread->pop(); - - - for (threadIterator = _threadList.begin(); threadIterator != _threadList.end(); ++threadIterator) { - anotherThread = threadIterator.operator->(); - if ((anotherThread != thread) && (anotherThread->_threadVars[kThreadVarActor] == actorId)) { - anotherThread->_flags &= ~kTFlagWaiting; - anotherThread->_flags |= kTFlagAborted; - } - } -} - -// Script function #14 (0x0E) -// Param1: actor id -// Param2: object id -void Script::sfFaceTowards(SCRIPTFUNC_PARAMS) { - int16 actorId; - int16 targetObject; - ActorData *actor; - - actorId = thread->pop(); - targetObject = thread->pop(); - - actor = _vm->_actor->getActor(actorId); - actor->_targetObject = targetObject; -} - -// Script function #15 (0x0F) -// Param1: actor id -// Param2: target object -void Script::sfSetFollower(SCRIPTFUNC_PARAMS) { - int16 actorId; - int16 targetObject; - - ActorData *actor; - - actorId = thread->pop(); - targetObject = thread->pop(); - - debug(1, "sfSetFollower(%d, %d) [%d]", actorId, targetObject, _vm->_actor->actorIdToIndex(actorId)); - - actor = _vm->_actor->getActor(actorId); - actor->_targetObject = targetObject; - if (targetObject != ID_NOTHING) { - actor->_flags |= kFollower; - actor->_actorFlags &= ~kActorNoFollow; - } else { - actor->_flags &= ~kFollower; - } -} - -// Script function #16 (0x10) -void Script::sfScriptGotoScene(SCRIPTFUNC_PARAMS) { - int16 sceneNumber; - int16 entrance; - - sceneNumber = thread->pop(); - entrance = thread->pop(); - if (sceneNumber < 0) { - _vm->shutDown(); - return; - } - - if (_vm->getGameType() == GType_IHNM) { - warning("FIXME: implement sfScriptGotoScene differences for IHNM"); - - // Since it doesn't look like the IHNM scripts remove the - // cutaway after the intro, this is probably the best place to - // to it. - _vm->_anim->clearCutaway(); - } - - // It is possible to leave scene when converse panel is on, - // particulalrly it may happen at Moneychanger tent. This - // prevent this from happening. - if (_vm->_interface->getMode() == kPanelConverse) { - _vm->_interface->setMode(kPanelMain); - } - - _vm->_scene->changeScene(sceneNumber, entrance, (sceneNumber == ITE_SCENE_ENDCREDIT1) ? kTransitionFade : kTransitionNoFade); - - //TODO: placard stuff - _pendingVerb = _vm->_script->getVerbType(kVerbNone); - _currentObject[0] = _currentObject[1] = ID_NOTHING; - showVerb(); -} - -// Script function #17 (0x11) -// Param1: object id -// Param2: sprite index -void Script::sfSetObjImage(SCRIPTFUNC_PARAMS) { - uint16 objectId; - uint16 spriteId; - ObjectData *obj; - - objectId = thread->pop(); - spriteId = thread->pop(); - - obj = _vm->_actor->getObj(objectId); - obj->_spriteListResourceId = OBJ_SPRITE_BASE + spriteId; - _vm->_interface->refreshInventory(); -} - -// Script function #18 (0x12) -// Param1: object id -// Param2: name index -void Script::sfSetObjName(SCRIPTFUNC_PARAMS) { - uint16 objectId; - uint16 nameIdx; - ObjectData *obj; - - objectId = thread->pop(); - nameIdx = thread->pop(); - - obj = _vm->_actor->getObj(objectId); - obj->_nameIndex = nameIdx; -} - -// Script function #19 (0x13) -// Param1: object id -void Script::sfGetObjImage(SCRIPTFUNC_PARAMS) { - uint16 objectId; - ObjectData *obj; - - objectId = thread->pop(); - - obj = _vm->_actor->getObj(objectId); - - if (_vm->getGameType() == GType_IHNM) - thread->_returnValue = obj->_spriteListResourceId; - else - thread->_returnValue = obj->_spriteListResourceId - OBJ_SPRITE_BASE; -} - -// Script function #20 (0x14) -void Script::sfGetNumber(SCRIPTFUNC_PARAMS) { - if (_vm->_interface->_statusTextInputState == kStatusTextInputFirstRun) { - _vm->_interface->enterStatusString(); - thread->wait(kWaitTypeStatusTextInput); - disContinue = true; - } else { - if (_vm->_interface->_statusTextInputState == kStatusTextInputAborted) { - thread->_returnValue = -1; - } else { - thread->_returnValue = atoi(_vm->_interface->_statusTextInputString); - } - - _vm->_interface->_statusTextInputState = kStatusTextInputFirstRun; - } -} - -// Script function #21 (0x15) -// Param1: door # -void Script::sfScriptOpenDoor(SCRIPTFUNC_PARAMS) { - int16 doorNumber; - doorNumber = thread->pop(); - - if (_vm->_scene->getFlags() & kSceneFlagISO) { - _vm->_isoMap->setTileDoorState(doorNumber, 1); - } else { - _vm->_scene->setDoorState(doorNumber, 0); - } -} - -// Script function #22 (0x16) -// Param1: door # -void Script::sfScriptCloseDoor(SCRIPTFUNC_PARAMS) { - int16 doorNumber; - doorNumber = thread->pop(); - - if (_vm->_scene->getFlags() & kSceneFlagISO) { - _vm->_isoMap->setTileDoorState(doorNumber, 0); - } else { - _vm->_scene->setDoorState(doorNumber, 0xff); - } -} - -// Script function #23 (0x17) -void Script::sfSetBgdAnimSpeed(SCRIPTFUNC_PARAMS) { - int16 animId = thread->pop(); - int16 speed = thread->pop(); - - _vm->_anim->setFrameTime(animId, ticksToMSec(speed)); - debug(1, "sfSetBgdAnimSpeed(%d, %d)", animId, speed); -} - -// Script function #24 (0x18) -void Script::SF_cycleColors(SCRIPTFUNC_PARAMS) { - SF_stub("SF_cycleColors", thread, nArgs); - - error("Please, report this to sev"); -} - -// Script function #25 (0x19) -// Param1: actor id -void Script::sfDoCenterActor(SCRIPTFUNC_PARAMS) { - int16 actorId; - actorId = thread->pop(); - - _vm->_actor->_centerActor = _vm->_actor->getActor(actorId); -} - -// Script function #26 (0x1A) nonblocking -// Starts the specified animation -void Script::sfStartBgdAnimSpeed(SCRIPTFUNC_PARAMS) { - int16 animId = thread->pop(); - int16 cycles = thread->pop(); - int16 speed = thread->pop(); - - _vm->_anim->setCycles(animId, cycles); - _vm->_anim->setFrameTime(animId, ticksToMSec(speed)); - _vm->_anim->play(animId, 0); - - debug(1, "sfStartBgdAnimSpeed(%d, %d, %d)", animId, cycles, speed); -} - -// Script function #27 (0x1B) nonblocking -// Param1: actor id -// Param2: actor x -// Param3: actor y -void Script::sfScriptWalkToAsync(SCRIPTFUNC_PARAMS) { - int16 actorId; - Location actorLocation; - ActorData *actor; - - actorId = thread->pop(); - actorLocation.x = thread->pop(); - actorLocation.y = thread->pop(); - - actor = _vm->_actor->getActor(actorId); - actorLocation.z = actor->_location.z; - - actor->_flags &= ~kFollower; - - _vm->_actor->actorWalkTo(actorId, actorLocation); -} - -// Script function #28 (0x1C) -void Script::sfEnableZone(SCRIPTFUNC_PARAMS) { - uint16 objectId = thread->pop(); - int16 flag = thread->pop(); - HitZone *hitZone; - - if (objectTypeId(objectId) == kGameObjectHitZone) { - hitZone = _vm->_scene->_objectMap->getHitZone(objectIdToIndex(objectId)); - } else { - hitZone = _vm->_scene->_actionMap->getHitZone(objectIdToIndex(objectId)); - } - - if (flag) { - hitZone->setFlag(kHitZoneEnabled); - } else { - hitZone->clearFlag(kHitZoneEnabled); - _vm->_actor->_protagonist->_lastZone = NULL; - } -} - -// Script function #29 (0x1D) -// Param1: actor id -// Param2: current action -void Script::sfSetActorState(SCRIPTFUNC_PARAMS) { - int16 actorId; - int currentAction; - ActorData *actor; - - actorId = thread->pop(); - currentAction = thread->pop(); - - actor = _vm->_actor->getActor(actorId); - - if ((currentAction >= kActionWalkToPoint) && (currentAction <= kActionWalkToPoint)) { - wakeUpActorThread(kWaitTypeWalk, actor); - } - actor->_currentAction = currentAction; - actor->_actorFlags &= ~kActorBackwards; -} - -// Script function #30 (0x1E) nonblocking -// Param1: actor id -// Param2: actor pos x -// Param3: actor pos y -void Script::sfScriptMoveTo(SCRIPTFUNC_PARAMS) { - int16 objectId; - Location location; - ActorData *actor; - ObjectData *obj; - - objectId = thread->pop(); - location.x = thread->pop(); - location.y = thread->pop(); - - if (_vm->_actor->validActorId(objectId)) { - actor = _vm->_actor->getActor(objectId); - - actor->_location.x = location.x; - actor->_location.y = location.y; - } else { - if (_vm->_actor->validObjId(objectId)) { - obj = _vm->_actor->getObj(objectId); - obj->_location.x = location.x; - obj->_location.y = location.y; - } - } -} - -// Script function #31 (0x21) -// Param1: sceneNumber -void Script::sfSceneEq(SCRIPTFUNC_PARAMS) { - int16 sceneNumber = thread->pop(); - - if (_vm->_scene->getSceneResourceId(sceneNumber) == _vm->_scene->currentSceneResourceId()) - thread->_returnValue = 1; - else - thread->_returnValue = 0; -} - -// Script function #32 (0x20) -void Script::sfDropObject(SCRIPTFUNC_PARAMS) { - uint16 objectId; - uint16 spriteId; - int16 x; - int16 y; - ObjectData *obj; - - objectId = thread->pop(); - spriteId = thread->pop(); - x = thread->pop(); - y = thread->pop(); - - obj = _vm->_actor->getObj(objectId); - - if (obj->_sceneNumber == ITE_SCENE_INV) { - _vm->_interface->removeFromInventory(objectId); - } - - obj->_sceneNumber = _vm->_scene->currentSceneNumber(); - - if (_vm->getGameType() == GType_IHNM) - obj->_spriteListResourceId = spriteId; - else - obj->_spriteListResourceId = OBJ_SPRITE_BASE + spriteId; - - obj->_location.x = x; - obj->_location.y = y; -} - -// Script function #33 (0x21) -void Script::sfFinishBgdAnim(SCRIPTFUNC_PARAMS) { - int16 animId = thread->pop(); - - _vm->_anim->finish(animId); - - debug(1, "sfFinishBgdAnim(%d)", animId); -} - -// Script function #34 (0x22) -// Param1: actor id 1 -// Param2: actor id 2 -void Script::sfSwapActors(SCRIPTFUNC_PARAMS) { - int16 actorId1; - int16 actorId2; - ActorData *actor1; - ActorData *actor2; - - actorId1 = thread->pop(); - actorId2 = thread->pop(); - - actor1 = _vm->_actor->getActor(actorId1); - actor2 = _vm->_actor->getActor(actorId2); - - SWAP(actor1->_location, actor2->_location); - - if (actor1->_flags & kProtagonist) { - actor1->_flags &= ~kProtagonist; - actor2->_flags |= kProtagonist; - _vm->_actor->_protagonist = _vm->_actor->_centerActor = actor2; - } else if (actor2->_flags & kProtagonist) { - actor2->_flags &= ~kProtagonist; - actor1->_flags |= kProtagonist; - _vm->_actor->_protagonist = _vm->_actor->_centerActor = actor1; - } - - // Here non-protagonist ID gets saved in variable - if (_vm->getGameType() == GType_IHNM) - warning("sfSwapActors: incomplete implementation"); -} - -// Script function #35 (0x23) -// Param1: string rid -// Param2: actorscount -// Param3: actor id1 -///.... -// Param3: actor idN -void Script::sfSimulSpeech(SCRIPTFUNC_PARAMS) { - int16 stringId; - int16 actorsCount; - int i; - uint16 actorsIds[ACTOR_SPEECH_ACTORS_MAX]; - const char *string; - int16 sampleResourceId = -1; - - stringId = thread->pop(); - actorsCount = thread->pop(); - - if (actorsCount > ACTOR_SPEECH_ACTORS_MAX) - error("sfSimulSpeech actorsCount=0x%X exceed ACTOR_SPEECH_ACTORS_MAX", actorsCount); - - for (i = 0; i < actorsCount; i++) - actorsIds[i] = thread->pop(); - - string = thread->_strings->getString(stringId); - - if (thread->_voiceLUT->voices) { - if (_vm->getGameType() == GType_IHNM && stringId >= 338) { - sampleResourceId = -1; - } else { - sampleResourceId = thread->_voiceLUT->voices[stringId]; - if (sampleResourceId <= 0 || sampleResourceId > 4000) - sampleResourceId = -1; - } - } - - _vm->_actor->simulSpeech(string, actorsIds, actorsCount, 0, sampleResourceId); - thread->wait(kWaitTypeSpeech); -} - -// Script function #36 (0x24) ? -// Param1: actor id -// Param2: actor x -// Param3: actor y -// Param4: actor walk flag -void Script::sfScriptWalk(SCRIPTFUNC_PARAMS) { - int16 actorId; - Location actorLocation; - ActorData *actor; - uint16 walkFlags; - - actorId = thread->pop(); - actorLocation.x = thread->pop(); - actorLocation.y = thread->pop(); - walkFlags = thread->pop(); - - actor = _vm->_actor->getActor(actorId); - actorLocation.z = actor->_location.z; - - _vm->_actor->realLocation(actorLocation, ID_NOTHING, walkFlags); - - actor->_flags &= ~kFollower; - - if (_vm->_actor->actorWalkTo(actorId, actorLocation) && !(walkFlags & kWalkAsync)) { - thread->waitWalk(actor); - } - - if (walkFlags & kWalkBackPedal) { - actor->_actorFlags |= kActorBackwards; - } - - actor->_actorFlags = (actor->_actorFlags & ~kActorFacingMask) | (walkFlags & kActorFacingMask); -} - -// Script function #37 (0x25) nonblocking -// Param1: actor id -// Param2: flags telling how to cycle the frames -// Param3: cycle frame number -// Param4: cycle delay -void Script::sfCycleFrames(SCRIPTFUNC_PARAMS) { - int16 actorId; - int16 flags; - int cycleFrameSequence; - int cycleDelay; - ActorData *actor; - - actorId = thread->pop(); - flags = thread->pop(); - cycleFrameSequence = thread->pop(); - cycleDelay = thread->pop(); - - actor = _vm->_actor->getActor(actorId); - - if (flags & kCyclePong) { - actor->_currentAction = kActionPongFrames; - } else { - actor->_currentAction = kActionCycleFrames; - } - - actor->_actorFlags &= ~(kActorContinuous | kActorRandom | kActorBackwards); - - if (!(flags & kCycleOnce)) { - actor->_actorFlags |= kActorContinuous; - } - if (flags & kCycleRandom) { - actor->_actorFlags |= kActorRandom; - } - if (flags & kCycleReverse) { - actor->_actorFlags |= kActorBackwards; - } - - actor->_cycleFrameSequence = cycleFrameSequence; - actor->_cycleTimeCount = 0; - actor->_cycleDelay = cycleDelay; - actor->_actionCycle = 0; -} - -// Script function #38 (0x26) nonblocking -// Param1: actor id -// Param2: frame type -// Param3: frame offset -void Script::sfSetFrame(SCRIPTFUNC_PARAMS) { - int16 actorId; - int frameType; - int frameOffset; - ActorData *actor; - ActorFrameRange *frameRange; - - actorId = thread->pop(); - frameType = thread->pop(); - frameOffset = thread->pop(); - - actor = _vm->_actor->getActor(actorId); - - frameRange = _vm->_actor->getActorFrameRange(actorId, frameType); - - actor->_frameNumber = frameRange->frameIndex + frameOffset; - - if (actor->_currentAction != kActionFall) { - actor->_currentAction = kActionFreeze; - } -} - -// Script function #39 (0x27) -// Sets the right-hand portrait -void Script::sfSetPortrait(SCRIPTFUNC_PARAMS) { - int16 param = thread->pop(); - - _vm->_interface->setRightPortrait(param); -} - -// Script function #40 (0x28) -// Sets the left-hand portrait -void Script::sfSetProtagPortrait(SCRIPTFUNC_PARAMS) { - int16 param = thread->pop(); - - _vm->_interface->setLeftPortrait(param); -} - -// Script function #41 (0x29) nonblocking -// Links the specified animations for playback - -// Param1: ? -// Param2: total linked frame count -// Param3: animation id link target -// Param4: animation id link source -void Script::sfChainBgdAnim(SCRIPTFUNC_PARAMS) { - int16 animId1 = thread->pop(); - int16 animId = thread->pop(); - int16 cycles = thread->pop(); - int16 speed = thread->pop(); - - if (speed >= 0) { - _vm->_anim->setCycles(animId, cycles); - _vm->_anim->stop(animId); - _vm->_anim->setFrameTime(animId, ticksToMSec(speed)); - } - - _vm->_anim->link(animId1, animId); - debug(1, "sfChainBgdAnim(%d, %d, %d, %d)", animId1, animId, cycles, speed); -} - -// Script function #42 (0x2A) -// Param1: actor id -// Param2: actor x -// Param3: actor y -// Param4: frame seq -void Script::sfScriptSpecialWalk(SCRIPTFUNC_PARAMS) { - int16 actorId; - int16 walkFrameSequence; - Location actorLocation; - ActorData *actor; - - actorId = thread->pop(); - actorLocation.x = thread->pop(); - actorLocation.y = thread->pop(); - walkFrameSequence = thread->pop(); - - actor = _vm->_actor->getActor(actorId); - actorLocation.z = actor->_location.z; - - _vm->_actor->actorWalkTo(actorId, actorLocation); - - actor->_walkFrameSequence = walkFrameSequence; -} - -// Script function #43 (0x2B) nonblocking -// Param1: actor id -// Param2: actor x -// Param3: actor y -// Param4: actor direction -// Param5: actor action -// Param6: actor frame number -void Script::sfPlaceActor(SCRIPTFUNC_PARAMS) { - int16 actorId; - Location actorLocation; - int actorDirection; - int frameType; - int frameOffset; - ActorData *actor; - ActorFrameRange *frameRange; - - actorId = thread->pop(); - actorLocation.x = thread->pop(); - actorLocation.y = thread->pop(); - actorDirection = thread->pop(); - frameType = thread->pop(); - frameOffset = thread->pop(); - - debug(1, "sfPlaceActor(id = 0x%x, x=%d, y=%d, dir=%d, frameType=%d, frameOffset=%d)", actorId, actorLocation.x, - actorLocation.y, actorDirection, frameType, frameOffset); - - actor = _vm->_actor->getActor(actorId); - actor->_location.x = actorLocation.x; - actor->_location.y = actorLocation.y; - actor->_facingDirection = actor->_actionDirection = actorDirection; - - if (!actor->_frames) - _vm->_actor->loadActorResources(actor); //? is not it already loaded ? - - if (frameType >= 0) { - frameRange = _vm->_actor->getActorFrameRange(actorId, frameType); - - if (frameRange->frameCount <= frameOffset) { - error("Wrong frameOffset 0x%X", frameOffset); - } - - actor->_frameNumber = frameRange->frameIndex + frameOffset; - actor->_currentAction = kActionFreeze; - } else { - actor->_currentAction = kActionWait; - } - - actor->_targetObject = ID_NOTHING; -} - -// Script function #44 (0x2C) nonblocking -// Checks to see if the user has interrupted a currently playing -// game cinematic. Pushes a zero or positive value if the game -// has not been interrupted. -void Script::sfCheckUserInterrupt(SCRIPTFUNC_PARAMS) { - thread->_returnValue = (_skipSpeeches == true); -} - -// Script function #45 (0x2D) -// Param1: actor id -// Param2: object id -// Param3: actor x -// Param4: actor y -// Param5: actor walk flag -void Script::sfScriptWalkRelative(SCRIPTFUNC_PARAMS) { - int16 actorId; - int16 objectId; - uint16 walkFlags; - Location actorLocation; - ActorData *actor; - - actorId = thread->pop(); - objectId = thread->pop(); - actorLocation.x = thread->pop(); - actorLocation.y = thread->pop(); - walkFlags = thread->pop(); - - actor = _vm->_actor->getActor(actorId); - actorLocation.z = actor->_location.z; - - _vm->_actor->realLocation(actorLocation, objectId, walkFlags); - - actor->_flags &= ~kFollower; - - if (_vm->_actor->actorWalkTo(actorId, actorLocation) && !(walkFlags & kWalkAsync)) { - thread->waitWalk(actor); - } - - if (walkFlags & kWalkBackPedal) { - actor->_actorFlags |= kActorBackwards; - } - - actor->_actorFlags = (actor->_actorFlags & ~kActorFacingMask) | (walkFlags & kActorFacingMask); -} - -// Script function #46 (0x2E) -// Param1: actor id -// Param2: object id -// Param3: actor x -// Param4: actor y -// Param5: actor walk flag -void Script::sfScriptMoveRelative(SCRIPTFUNC_PARAMS) { - int16 actorId; - int16 objectId; - uint16 walkFlags; - Location actorLocation; - ActorData *actor; - - actorId = thread->pop(); - objectId = thread->pop(); - actorLocation.x = thread->pop(); - actorLocation.y = thread->pop(); - walkFlags = thread->pop(); - - actor = _vm->_actor->getActor(actorId); - actorLocation.z = actor->_location.z; - - _vm->_actor->realLocation(actorLocation, objectId, walkFlags); - - - actor->_location = actorLocation; - actor->_actorFlags = (actor->_actorFlags & ~kActorFacingMask) | (walkFlags & kActorFacingMask); -} - -// Script function #47 (0x2F) -void Script::sfSimulSpeech2(SCRIPTFUNC_PARAMS) { - int16 stringId; - int16 actorsCount; - int16 speechFlags; - int i; - uint16 actorsIds[ACTOR_SPEECH_ACTORS_MAX]; - const char *string; - int16 sampleResourceId = -1; - - stringId = thread->pop(); - actorsCount = thread->pop(); - speechFlags = thread->pop(); - - if (actorsCount > ACTOR_SPEECH_ACTORS_MAX) - error("sfSimulSpeech2 actorsCount=0x%X exceed ACTOR_SPEECH_ACTORS_MAX", actorsCount); - - for (i = 0; i < actorsCount; i++) - actorsIds[i] = thread->pop(); - - string = thread->_strings->getString(stringId); - - if (thread->_voiceLUT->voices) { - sampleResourceId = thread->_voiceLUT->voices[stringId]; - if (sampleResourceId <= 0 || sampleResourceId > 4000) - sampleResourceId = -1; - } - - _vm->_actor->simulSpeech(string, actorsIds, actorsCount, speechFlags, sampleResourceId); - thread->wait(kWaitTypeSpeech); -} - - -// Script function #48 (0x30) -// Param1: string rid -void Script::sfPlacard(SCRIPTFUNC_PARAMS) { - int stringId; - Surface *backBuffer = _vm->_gfx->getBackBuffer(); - static PalEntry cur_pal[PAL_ENTRIES]; - PalEntry *pal; - Event event; - Event *q_event; - - if (_vm->getGameType() == GType_IHNM) { - warning("Psychic profile is not implemented"); - return; - } - - thread->wait(kWaitTypePlacard); - - _vm->_interface->rememberMode(); - _vm->_interface->setMode(kPanelPlacard); - - stringId = thread->pop(); - - event.type = kEvTOneshot; - event.code = kCursorEvent; - event.op = kEventHide; - - q_event = _vm->_events->queue(&event); - - _vm->_gfx->getCurrentPal(cur_pal); - - event.type = kEvTImmediate; - event.code = kPalEvent; - event.op = kEventPalToBlack; - event.time = 0; - event.duration = kNormalFadeDuration; - event.data = cur_pal; - - q_event = _vm->_events->chain(q_event, &event); - - event.type = kEvTOneshot; - event.code = kInterfaceEvent; - event.op = kEventClearStatus; - - q_event = _vm->_events->chain(q_event, &event); - - event.type = kEvTOneshot; - event.code = kGraphicsEvent; - event.op = kEventSetFlag; - event.param = RF_PLACARD; - - q_event = _vm->_events->chain(q_event, &event); - - event.type = kEvTOneshot; - event.code = kGraphicsEvent; - event.op = kEventFillRect; - event.data = backBuffer; - event.param = 138; - event.param2 = 0; - event.param3 = _vm->_scene->getHeight(); - event.param4 = 0; - event.param5 = _vm->getDisplayWidth(); - - q_event = _vm->_events->chain(q_event, &event); - - // Put the text in the center of the viewport, assuming it will fit on - // one line. If we cannot make that assumption we'll need to extend - // the text drawing function so that it can center text around a point. - // It doesn't end up in exactly the same spot as the original did it, - // but it's close enough for now at least. - - TextListEntry textEntry; - - textEntry.knownColor = kKnownColorBrightWhite; - textEntry.effectKnownColor = kKnownColorBlack; - textEntry.point.x = _vm->getDisplayWidth() / 2; - textEntry.point.y = (_vm->_scene->getHeight() - _vm->_font->getHeight(kKnownFontMedium)) / 2; - textEntry.font = kKnownFontMedium; - textEntry.flags = (FontEffectFlags)(kFontOutline | kFontCentered); - textEntry.text = thread->_strings->getString(stringId); - - _placardTextEntry = _vm->_scene->_textList.addEntry(textEntry); - - event.type = kEvTOneshot; - event.code = kTextEvent; - event.op = kEventDisplay; - event.data = _placardTextEntry; - - q_event = _vm->_events->chain(q_event, &event); - - _vm->_scene->getBGPal(pal); - - event.type = kEvTImmediate; - event.code = kPalEvent; - event.op = kEventBlackToPal; - event.time = 0; - event.duration = kNormalFadeDuration; - event.data = pal; - - q_event = _vm->_events->chain(q_event, &event); - - event.type = kEvTOneshot; - event.code = kScriptEvent; - event.op = kEventThreadWake; - event.param = kWaitTypePlacard; - - q_event = _vm->_events->chain(q_event, &event); - -} - -// Script function #49 (0x31) -void Script::sfPlacardOff(SCRIPTFUNC_PARAMS) { - static PalEntry cur_pal[PAL_ENTRIES]; - PalEntry *pal; - Event event; - Event *q_event; - - thread->wait(kWaitTypePlacard); - - _vm->_interface->restoreMode(); - - _vm->_gfx->getCurrentPal(cur_pal); - - event.type = kEvTImmediate; - event.code = kPalEvent; - event.op = kEventPalToBlack; - event.time = 0; - event.duration = kNormalFadeDuration; - event.data = cur_pal; - - q_event = _vm->_events->queue(&event); - - event.type = kEvTOneshot; - event.code = kGraphicsEvent; - event.op = kEventClearFlag; - event.param = RF_PLACARD; - - q_event = _vm->_events->chain(q_event, &event); - - event.type = kEvTOneshot; - event.code = kTextEvent; - event.op = kEventRemove; - event.data = _placardTextEntry; - - q_event = _vm->_events->chain(q_event, &event); - - _vm->_scene->getBGPal(pal); - - event.type = kEvTImmediate; - event.code = kPalEvent; - event.op = kEventBlackToPal; - event.time = 0; - event.duration = kNormalFadeDuration; - event.data = pal; - - q_event = _vm->_events->chain(q_event, &event); - - event.type = kEvTOneshot; - event.code = kCursorEvent; - event.op = kEventShow; - - q_event = _vm->_events->chain(q_event, &event); - - event.type = kEvTOneshot; - event.code = kScriptEvent; - event.op = kEventThreadWake; - event.param = kWaitTypePlacard; - - q_event = _vm->_events->chain(q_event, &event); - -} - -void Script::sfPsychicProfile(SCRIPTFUNC_PARAMS) { - SF_stub("sfPsychicProfile", thread, nArgs); -} - -void Script::sfPsychicProfileOff(SCRIPTFUNC_PARAMS) { - SF_stub("sfPsychicProfileOff", thread, nArgs); -} - -// Script function #50 (0x32) -void Script::sfSetProtagState(SCRIPTFUNC_PARAMS) { - int protagState = thread->pop(); - - _vm->_actor->setProtagState(protagState); -} - -// Script function #51 (0x33) -void Script::sfResumeBgdAnim(SCRIPTFUNC_PARAMS) { - int16 animId = thread->pop(); - int16 cycles = thread->pop(); - - _vm->_anim->resume(animId, cycles); - debug(1, "sfResumeBgdAnimSpeed(%d, %d)", animId, cycles); - -} - -// Script function #52 (0x34) -// Param1: actor id -// Param2: x -// Param3: y -// Param4: unknown -// Param5: actionCycle -// Param6: flags -void Script::sfThrowActor(SCRIPTFUNC_PARAMS) { - int16 actorId; - ActorData *actor; - int16 flags; - int32 actionCycle; - Location location; - - actorId = thread->pop(); - location.x = thread->pop(); - location.y = thread->pop(); - thread->pop(); - actionCycle = thread->pop(); - flags = thread->pop(); - - actor = _vm->_actor->getActor(actorId); - location.z = actor->_location.z; - actor->_currentAction = kActionFall; - actor->_actionCycle = actionCycle; - actor->_fallAcceleration = -20; - actor->_fallVelocity = - (actor->_fallAcceleration * actor->_actionCycle) / 2; - actor->_fallPosition = actor->_location.z << 4; - - actor->_finalTarget = location; - actor->_actionCycle--; - if (!(flags & kWalkAsync)) { - thread->waitWalk(actor); - } -} - -// Script function #53 (0x35) -// Param1: actor id -// Param2: target object -void Script::sfWaitWalk(SCRIPTFUNC_PARAMS) { - int16 actorId; - ActorData *actor; - - actorId = thread->pop(); - actor = _vm->_actor->getActor(actorId); - - if ((actor->_currentAction == kActionWalkToPoint) || - (actor->_currentAction == kActionWalkToLink) || - (actor->_currentAction == kActionFall)) { - thread->waitWalk(actor); - } -} - -// Script function #54 (0x36) -void Script::sfScriptSceneID(SCRIPTFUNC_PARAMS) { - thread->_returnValue = _vm->_scene->currentSceneNumber(); -} - -// Script function #55 (0x37) -// Param1: actor id -// Param2: scene number -void Script::sfChangeActorScene(SCRIPTFUNC_PARAMS) { - int16 actorId; - int32 sceneNumber; - ActorData *actor; - - actorId = thread->pop(); - sceneNumber = thread->pop(); - actor = _vm->_actor->getActor(actorId); - actor->_sceneNumber = sceneNumber; -} - -// Script function #56 (0x38) -// Param1: actor id -// Param2: z -// Param3: frame seq -// Param4: flags -void Script::sfScriptClimb(SCRIPTFUNC_PARAMS) { - int16 actorId; - int16 z; - ActorData *actor; - uint16 flags; - int cycleFrameSequence; - - actorId = thread->pop(); - z = thread->pop(); - cycleFrameSequence = thread->pop(); - flags = thread->pop(); - - actor = _vm->_actor->getActor(actorId); - actor->_finalTarget.z = z; - actor->_flags &= ~kFollower; - actor->_actionCycle = 1; - actor->_cycleFrameSequence = cycleFrameSequence; - actor->_currentAction = kActionClimb; - if (!(flags & kWalkAsync)) { - thread->waitWalk(actor); - } -} - -// Script function #57 (0x39) -// Param1: door # -// Param2: door state -void Script::sfSetDoorState(SCRIPTFUNC_PARAMS) { - int16 doorNumber; - int16 doorState; - doorNumber = thread->pop(); - doorState = thread->pop(); - - if (_vm->_scene->getFlags() & kSceneFlagISO) { - _vm->_isoMap->setTileDoorState(doorNumber, doorState); - } else { - _vm->_scene->setDoorState(doorNumber, doorState); - } -} - -// Script function #58 (0x3A) -// Param1: actor id -// Param2: z -void Script::sfSetActorZ(SCRIPTFUNC_PARAMS) { - int16 objectId; - ActorData *actor; - ObjectData *obj; - int16 z; - - objectId = thread->pop(); - z = thread->pop(); - - - if (_vm->_actor->validActorId(objectId)) { - actor = _vm->_actor->getActor(objectId); - actor->_location.z = z; - } else { - if (_vm->_actor->validObjId(objectId)) { - obj = _vm->_actor->getObj(objectId); - obj->_location.z = z; - } - } -} - -// Script function #59 (0x3B) -// Param1: stringId -// Param2: flags -// Param3: color -// Param4: x -// Param5: y -void Script::sfScriptText(SCRIPTFUNC_PARAMS) { - int16 stringId; - int16 flags; - Rect rect; - int color; - Point point; - int width; - const char*text; - stringId = thread->pop(); - flags = thread->pop(); - color = thread->pop(); - point.x = thread->pop(); - point.y = thread->pop(); - - text = thread->_strings->getString(stringId); - - width = _vm->_font->getStringWidth(kKnownFontScript, text, 0, kFontOutline); - rect.top = point.y - 6; - rect.setHeight(12); - rect.left = point.x - width / 2; - rect.setWidth(width); - - _vm->_actor->setSpeechColor(color, _vm->KnownColor2ColorId(kKnownColorBlack)); - _vm->_actor->nonActorSpeech(rect, &text, 1, -1, flags); -} - -// Script function #60 (0x3C) -// Param1: actor id -void Script::sfGetActorX(SCRIPTFUNC_PARAMS) { - int16 actorId; - ActorData *actor; - - actorId = thread->pop(); - actor = _vm->_actor->getActor(actorId); - - thread->_returnValue = actor->_location.x >> 2; -} - -// Script function #61 (0x3D) -// Param1: actor id -void Script::sfGetActorY(SCRIPTFUNC_PARAMS) { - int16 actorId; - ActorData *actor; - - actorId = thread->pop(); - actor = _vm->_actor->getActor(actorId); - - thread->_returnValue = actor->_location.y >> 2; -} - -// Script function #62 (0x3E) -void Script::sfEraseDelta(SCRIPTFUNC_PARAMS) { - Surface *backGroundSurface; - BGInfo backGroundInfo; - - backGroundSurface = _vm->_render->getBackGroundSurface(); - _vm->_scene->getBGInfo(backGroundInfo); - - backGroundSurface->blit(backGroundInfo.bounds, backGroundInfo.buffer); -} - -// Script function #63 (0x3F) -void Script::sfPlayMusic(SCRIPTFUNC_PARAMS) { - if (_vm->getGameType() == GType_ITE) { - int16 param = thread->pop() + 9; - - if (param >= 9 && param <= 34) { - _vm->_music->setVolume(-1, 1); - _vm->_music->play(param); - } else { - _vm->_music->stop(); - } - } else { - int16 param1 = thread->pop(); - int16 param2 = thread->pop(); - - if (param1 < 0) { - _vm->_music->stop(); - return; - } - - if (param1 >= _vm->_music->_songTableLen) { - warning("sfPlayMusic: Wrong song number (%d > %d)", param1, _vm->_music->_songTableLen - 1); - } else { - _vm->_music->setVolume(-1, 1); - _vm->_music->play(_vm->_music->_songTable[param1], param2 ? MUSIC_LOOP : MUSIC_NORMAL); - } - } -} - -// Script function #64 (0x40) -void Script::sfPickClimbOutPos(SCRIPTFUNC_PARAMS) { - int16 u, v, t; - ActorData *protagonist = _vm->_actor->_protagonist; - while (true) { - - u = (_vm->_rnd.getRandomNumber(63) & 63) + 40; - v = (_vm->_rnd.getRandomNumber(63) & 63) + 40; - t = _vm->_isoMap->getTileIndex(u, v, 6); - if (t == 65) { - protagonist->_location.u() = (u << 4) + 4; - protagonist->_location.v() = (v << 4) + 4; - protagonist->_location.z = 48; - break; - } - - } -} - -// Script function #65 (0x41) -void Script::sfTossRif(SCRIPTFUNC_PARAMS) { - int16 uc , vc; - uint16 direction; - ActorData *protagonist = _vm->_actor->_protagonist; - - uc = protagonist->_location.u() >> 4; - vc = protagonist->_location.v() >> 4; - if (_vm->_isoMap->findNearestChasm(uc, vc, direction)) { - uc <<= 4; - vc <<= 4; - protagonist->_facingDirection = direction; - - protagonist->_finalTarget.u() = uc; - protagonist->_finalTarget.v() = vc; - protagonist->_finalTarget.z = -40; - protagonist->_currentAction = kActionFall; - protagonist->_actionCycle = 24; - protagonist->_fallAcceleration = - 20; - protagonist->_fallVelocity = - (protagonist->_fallAcceleration * 16) / 2 - (44 / 12); - protagonist->_fallPosition = protagonist->_location.z << 4; - protagonist->_actionCycle--; - } -} - -// Script function #66 (0x42) -void Script::sfShowControls(SCRIPTFUNC_PARAMS) { - // It has zero implementation in Win rerelase, and in DOS - // release it deals with video ports. -} - -// Script function #67 (0x43) -void Script::sfShowMap(SCRIPTFUNC_PARAMS) { - _vm->_interface->setMode(kPanelMap); -} - -// Script function #68 (0x44) -void Script::sfPuzzleWon(SCRIPTFUNC_PARAMS) { - thread->_returnValue = _vm->_puzzle->isSolved(); -} - -// Script function #69 (0x45) -void Script::sfEnableEscape(SCRIPTFUNC_PARAMS) { - if (thread->pop()) - _abortEnabled = true; - else { - _skipSpeeches = false; - _abortEnabled = false; - } -} - -// Script function #70 (0x46) -void Script::sfPlaySound(SCRIPTFUNC_PARAMS) { - int16 param = thread->pop(); - int res; - - if (param >= 0 && param < _vm->_sndRes->_fxTableLen) { - res = _vm->_sndRes->_fxTable[param].res; - if (_vm->getFeatures() & GF_CD_FX) - res -= 14; - _vm->_sndRes->playSound(res, _vm->_sndRes->_fxTable[param].vol, false); - } else { - _vm->_sound->stopSound(); - } -} - -// Script function #71 (0x47) -void Script::sfPlayLoopedSound(SCRIPTFUNC_PARAMS) { - int16 param = thread->pop(); - int res; - - if (param >= 0 && param < _vm->_sndRes->_fxTableLen) { - res = _vm->_sndRes->_fxTable[param].res; - if (_vm->getFeatures() & GF_CD_FX) - res -= 14; - - _vm->_sndRes->playSound(res, _vm->_sndRes->_fxTable[param].vol, true); - } else { - _vm->_sound->stopSound(); - } -} - -// Script function #72 (0x48) -void Script::sfGetDeltaFrame(SCRIPTFUNC_PARAMS) { - uint16 animId = (uint16)thread->pop(); - - thread->_returnValue = _vm->_anim->getCurrentFrame(animId); -} - -// Script function #73 (0x49) -void Script::sfShowProtect(SCRIPTFUNC_PARAMS) { - if (_vm->_copyProtection) { - thread->wait(kWaitTypeRequest); - - _vm->_interface->setMode(kPanelProtect); - } -} - -// Script function #74 (0x4A) -void Script::sfProtectResult(SCRIPTFUNC_PARAMS) { - if (_vm->_copyProtection) { - thread->_returnValue = _vm->_interface->getProtectHash(); - } else { - int protectHash; - - //cheating - protectHash = thread->pop(); - thread->push(protectHash); - thread->_returnValue = protectHash; - } -} - -// Script function #75 (0x4b) -void Script::sfRand(SCRIPTFUNC_PARAMS) { - int16 param; - - param = thread->pop(); - thread->_returnValue = _vm->_rnd.getRandomNumber(param - 1); -} - -// Script function #76 (0x4c) -void Script::sfFadeMusic(SCRIPTFUNC_PARAMS) { - _vm->_music->setVolume(0, 1000); -} - -// Script function #77 (0x4d) -void Script::sfPlayVoice(SCRIPTFUNC_PARAMS) { - int16 param = thread->pop(); - - warning("sfPlayVoice(%d)", param); - if (param > 0) { - _vm->_sndRes->playVoice(param + 3712); - } else { - _vm->_sound->stopSound(); - } -} - -void Script::finishDialog(int replyID, int flags, int bitOffset) { - byte *addr; - - if (_conversingThread) { - _vm->_interface->setMode(kPanelNull); - - _conversingThread->_flags &= ~kTFlagWaiting; - - _conversingThread->push(replyID); - - if (flags & kReplyOnce) { - addr = _conversingThread->_staticBase + (bitOffset >> 3); - *addr |= (1 << (bitOffset & 7)); - } - } - - _conversingThread = NULL; - wakeUpThreads(kWaitTypeDialogBegin); -} - -void Script::sfSetChapterPoints(SCRIPTFUNC_PARAMS) { - int16 ethics = thread->pop(); - int16 barometer = thread->pop(); - int chapter = _vm->_scene->currentChapterNumber(); - - _vm->_ethicsPoints[chapter] = ethics; - _vm->_spiritualBarometer = ethics * 256 / barometer; -} - -void Script::sfSetPortraitBgColor(SCRIPTFUNC_PARAMS) { - int16 red = thread->pop(); - int16 green = thread->pop(); - int16 blue = thread->pop(); - - _vm->_interface->setPortraitBgColor(red, green, blue); -} - -void Script::sfScriptStartCutAway(SCRIPTFUNC_PARAMS) { - int16 cut; - int16 fade; - - cut = thread->pop(); - thread->pop(); // Not used - fade = thread->pop(); - - _vm->_anim->playCutaway(cut, fade != 0); -} - -void Script::sfReturnFromCutAway(SCRIPTFUNC_PARAMS) { - _vm->_anim->returnFromCutaway(); -} - -void Script::sfEndCutAway(SCRIPTFUNC_PARAMS) { - _vm->_anim->endCutaway(); -} - -void Script::sfGetMouseClicks(SCRIPTFUNC_PARAMS) { - SF_stub("sfGetMouseClicks", thread, nArgs); -} - -void Script::sfResetMouseClicks(SCRIPTFUNC_PARAMS) { - SF_stub("sfResetMouseClicks", thread, nArgs); -} - -void Script::sfWaitFrames(SCRIPTFUNC_PARAMS) { - SF_stub("sfWaitFrames", thread, nArgs); -} - -void Script::sfScriptFade(SCRIPTFUNC_PARAMS) { - SF_stub("sfScriptFade", thread, nArgs); -} - -void Script::sfScriptStartVideo(SCRIPTFUNC_PARAMS) { - SF_stub("sfScriptStartVideo", thread, nArgs); -} - -void Script::sfScriptReturnFromVideo(SCRIPTFUNC_PARAMS) { - SF_stub("sfScriptReturnFromVideo", thread, nArgs); -} - -void Script::sfScriptEndVideo(SCRIPTFUNC_PARAMS) { - SF_stub("sfScriptEndVideo", thread, nArgs); -} - -void Script::sf87(SCRIPTFUNC_PARAMS) { - SF_stub("sf87", thread, nArgs); -} - -void Script::sf88(SCRIPTFUNC_PARAMS) { - SF_stub("sf88", thread, nArgs); -} - -void Script::sf89(SCRIPTFUNC_PARAMS) { - SF_stub("sf89", thread, nArgs); -} - -void Script::sfVstopFX(SCRIPTFUNC_PARAMS) { - _vm->_sound->stopSound(); -} - -void Script::sfVstopLoopedFX(SCRIPTFUNC_PARAMS) { - _vm->_sound->stopSound(); -} - -void Script::sfDemoIsInteractive(SCRIPTFUNC_PARAMS) { - thread->_returnValue = 0; -} - -void Script::sfVsetTrack(SCRIPTFUNC_PARAMS) { - int16 chapter = thread->pop(); - int16 sceneNumber = thread->pop(); - int16 actorsEntrance = thread->pop(); - - debug(2, "sfVsetTrrack(%d, %d, %d)", chapter, sceneNumber, actorsEntrance); - - _vm->_scene->changeScene(sceneNumber, actorsEntrance, kTransitionFade, chapter); -} - -void Script::sfGetPoints(SCRIPTFUNC_PARAMS) { - int16 index = thread->pop(); - - if (index >= 0 && index < ARRAYSIZE(_vm->_ethicsPoints)) - thread->_returnValue = _vm->_ethicsPoints[index]; - else - thread->_returnValue = 0; -} - -void Script::sfSetGlobalFlag(SCRIPTFUNC_PARAMS) { - int16 flag = thread->pop(); - - if (flag >= 0 && flag < 32) - _vm->_globalFlags |= (1 << flag); -} - -void Script::sfClearGlobalFlag(SCRIPTFUNC_PARAMS) { - int16 flag = thread->pop(); - - if (flag >= 0 && flag < 32) - _vm->_globalFlags &= ~(1 << flag); -} - -void Script::sfTestGlobalFlag(SCRIPTFUNC_PARAMS) { - int16 flag = thread->pop(); - - if (flag >= 0 && flag < 32 && _vm->_globalFlags & (1 << flag)) - thread->_returnValue = 1; - else - thread->_returnValue = 0; -} - -void Script::sfSetPoints(SCRIPTFUNC_PARAMS) { - int16 index = thread->pop(); - int16 points = thread->pop(); - - if (index >= 0 && index < ARRAYSIZE(_vm->_ethicsPoints)) - _vm->_ethicsPoints[index] = points; -} - -void Script::sfSetSpeechBox(SCRIPTFUNC_PARAMS) { - int16 param1 = thread->pop(); - int16 param2 = thread->pop(); - int16 param3 = thread->pop(); - int16 param4 = thread->pop(); - - _vm->_actor->_speechBoxScript.left = param1; - _vm->_actor->_speechBoxScript.top = param2; - _vm->_actor->_speechBoxScript.setWidth(param3); - _vm->_actor->_speechBoxScript.setHeight(param4); -} - -void Script::sfDebugShowData(SCRIPTFUNC_PARAMS) { - int16 param = thread->pop(); - char buf[50]; - - snprintf(buf, 50, "Reached breakpoint %d", param); - - _vm->_interface->setStatusText(buf); -} - -void Script::sfWaitFramesEsc(SCRIPTFUNC_PARAMS) { - thread->_returnValue = _vm->_framesEsc; -} - -void Script::sf103(SCRIPTFUNC_PARAMS) { - SF_stub("sf103", thread, nArgs); -} - -void Script::sfDisableAbortSpeeches(SCRIPTFUNC_PARAMS) { - int value = thread->pop(); - - _vm->_interface->disableAbortSpeeches(value != 0); -} - -void Script::sfNull(SCRIPTFUNC_PARAMS) { - for (int i = 0; i < nArgs; i++) - thread->pop(); -} - -void Script::SF_stub(const char *name, ScriptThread *thread, int nArgs) { - char buf[256], buf1[100]; - - snprintf(buf, 256, "STUB: %s(", name); - - for (int i = 0; i < nArgs; i++) { - snprintf(buf1, 100, "%d", thread->pop()); - strncat(buf, buf1, 256); - if (i + 1 < nArgs) - strncat(buf, ", ", 256); - } - - debug(0, "%s)", buf); -} - -} // End of namespace Saga diff --git a/saga/sndres.cpp b/saga/sndres.cpp deleted file mode 100644 index d3679599fd..0000000000 --- a/saga/sndres.cpp +++ /dev/null @@ -1,297 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Sound resource management class - -#include "saga/saga.h" - -#include "saga/itedata.h" -#include "saga/resnames.h" -#include "saga/rscfile.h" -#include "saga/sndres.h" -#include "saga/sound.h" -#include "saga/stream.h" - -#include "common/file.h" - -#include "sound/voc.h" -#include "sound/wave.h" -#include "sound/adpcm.h" -#include "sound/audiostream.h" - -namespace Saga { - -SndRes::SndRes(SagaEngine *vm) : _vm(vm) { - /* Load sound module resource file contexts */ - _sfxContext = _vm->_resource->getContext(GAME_SOUNDFILE); - if (_sfxContext == NULL) { - error("SndRes::SndRes resource context not found"); - } - - _voiceSerial = -1; - - setVoiceBank(0); - - if (_vm->getGameType() == GType_ITE) { - _fxTable = ITE_SfxTable; - _fxTableLen = ITE_SFXCOUNT; - } else { - ResourceContext *resourceContext; - - resourceContext = _vm->_resource->getContext(GAME_SOUNDFILE); - if (resourceContext == NULL) { - error("Resource::loadGlobalResources() resource context not found"); - } - - byte *resourcePointer; - size_t resourceLength; - - _vm->_resource->loadResource(resourceContext, RID_IHNM_SFX_LUT, - resourcePointer, resourceLength); - - if (resourceLength == 0) { - error("Sndres::SndRes can't read SfxIDs table"); - } - - _fxTableIDsLen = resourceLength / 2; - _fxTableIDs = (int16 *)malloc(_fxTableIDsLen * sizeof(int16)); - - MemoryReadStream metaS(resourcePointer, resourceLength); - for (int i = 0; i < _fxTableIDsLen; i++) - _fxTableIDs[i] = metaS.readSint16LE(); - - free(resourcePointer); - - _fxTable = 0; - _fxTableLen = 0; - } -} - -SndRes::~SndRes() { - if (_vm->getGameType() == GType_IHNM) { - free(_fxTable); - free(_fxTableIDs); - } -} - -void SndRes::setVoiceBank(int serial) -{ - if (_voiceSerial == serial) return; - - _voiceSerial = serial; - - _voiceContext = _vm->_resource->getContext(GAME_VOICEFILE, _voiceSerial); - if (_voiceContext == NULL) { - error("SndRes::SndRes resource context not found"); - } - - -} - -void SndRes::playSound(uint32 resourceId, int volume, bool loop) { - SoundBuffer buffer; - - debug(4, "SndRes::playSound %i", resourceId); - - if (!load(_sfxContext, resourceId, buffer, false)) { - warning("Failed to load sound"); - return; - } - - _vm->_sound->playSound(buffer, volume, loop); -} - -void SndRes::playVoice(uint32 resourceId) { - SoundBuffer buffer; - - debug(4, "SndRes::playVoice %i", resourceId); - - if (!load(_voiceContext, resourceId, buffer, false)) { - warning("Failed to load voice"); - return; - } - - _vm->_sound->playVoice(buffer); -} - -bool SndRes::load(ResourceContext *context, uint32 resourceId, SoundBuffer &buffer, bool onlyHeader) { - byte *soundResource; - AudioStream *voxStream; - size_t soundResourceLength; - bool result = false; - GameSoundTypes resourceType; - byte *data; - int rate; - int size; - byte flags; - size_t voxSize; - const GameSoundInfo *soundInfo; - - if (resourceId == (uint32)-1) { - return false; - } - - - _vm->_resource->loadResource(context, resourceId, soundResource, soundResourceLength); - - if ((context->fileType & GAME_VOICEFILE) != 0) { - soundInfo = _vm->getVoiceInfo(); - } else { - soundInfo = _vm->getSfxInfo(); - } - - context->table[resourceId].fillSoundPatch(soundInfo); - - MemoryReadStream readS(soundResource, soundResourceLength); - - resourceType = soundInfo->resourceType; - buffer.isBigEndian = soundInfo->isBigEndian; - - if (soundResourceLength >= 8) { - if (!memcmp(soundResource, "Creative", 8)) { - resourceType = kSoundVOC; - } else if (!memcmp(soundResource, "RIFF", 4) != 0) { - resourceType = kSoundWAV; - } - } - - - switch (resourceType) { - case kSoundPCM: - buffer.frequency = soundInfo->frequency; - buffer.isSigned = soundInfo->isSigned; - buffer.sampleBits = soundInfo->sampleBits; - buffer.size = soundResourceLength; - buffer.stereo = soundInfo->stereo; - if (onlyHeader) { - buffer.buffer = NULL; - free(soundResource); - } else { - buffer.buffer = soundResource; - } - result = true; - break; - case kSoundMacPCM: - buffer.frequency = soundInfo->frequency; - buffer.isSigned = soundInfo->isSigned; - buffer.sampleBits = soundInfo->sampleBits; - buffer.size = soundResourceLength - 36; - buffer.stereo = soundInfo->stereo; - if (onlyHeader) { - buffer.buffer = NULL; - } else { - buffer.buffer = (byte *)malloc(buffer.size); - memcpy(buffer.buffer, soundResource + 36, buffer.size); - } - free(soundResource); - result = true; - break; - case kSoundVOX: - buffer.frequency = soundInfo->frequency; - buffer.isSigned = soundInfo->isSigned; - buffer.sampleBits = soundInfo->sampleBits; - buffer.stereo = soundInfo->stereo; - buffer.size = soundResourceLength * 4; - if (onlyHeader) { - buffer.buffer = NULL; - free(soundResource); - } else { - voxStream = new ADPCMInputStream(&readS, soundResourceLength, kADPCMOki); - buffer.buffer = (byte *)malloc(buffer.size); - voxSize = voxStream->readBuffer((int16*)buffer.buffer, soundResourceLength * 2); - if (voxSize != soundResourceLength * 2) { - error("SndRes::load() wrong VOX output size"); - } - delete voxStream; - } - result = true; - break; - case kSoundVOC: - data = loadVOCFromStream(readS, size, rate); - if (data) { - buffer.frequency = rate; - buffer.sampleBits = 8; - buffer.stereo = false; - buffer.isSigned = false; - buffer.size = size; - if (onlyHeader) { - buffer.buffer = NULL; - free(data); - } else { - buffer.buffer = data; - } - result = true; - } - free(soundResource); - break; - case kSoundWAV: - if (loadWAVFromStream(readS, size, rate, flags)) { - buffer.frequency = rate; - buffer.sampleBits = 16; - buffer.stereo = ((flags & Audio::Mixer::FLAG_STEREO) != 0); - buffer.isSigned = true; - buffer.size = size; - if (onlyHeader) { - buffer.buffer = NULL; - } else { - buffer.buffer = (byte *)malloc(size); - readS.read(buffer.buffer, size); - } - result = true; - } - free(soundResource); - break; - default: - error("SndRes::load Unknown sound type"); - } - - // In ITE CD De some voices are absent and contain just 5 bytes header - // Round it to even number so soundmanager will not crash. - // See bug #1256701 - buffer.size &= ~(0x1); - - return result; -} - -int SndRes::getVoiceLength(uint32 resourceId) { - double msDouble; - SoundBuffer buffer; - - if (!load(_voiceContext, resourceId, buffer, true)) { - return -1; - } - - msDouble = (double)buffer.size; - if (buffer.sampleBits == 16) { - msDouble /= 2.0; - } - if (buffer.stereo) { - msDouble /= 2.0; - } - - msDouble = msDouble / buffer.frequency * 1000.0; - return (int)msDouble; -} - -} // End of namespace Saga diff --git a/saga/sndres.h b/saga/sndres.h deleted file mode 100644 index 638fb80849..0000000000 --- a/saga/sndres.h +++ /dev/null @@ -1,68 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Sound resource class header - -#ifndef SAGA_SNDRES_H_ -#define SAGA_SNDRES_H_ - -#include "saga/itedata.h" -#include "saga/sound.h" - -namespace Saga { - -class SndRes { -public: - - SndRes(SagaEngine *vm); - ~SndRes(); - - int loadSound(uint32 resourceId); - void playSound(uint32 resourceId, int volume, bool loop); - void playVoice(uint32 resourceId); - int getVoiceLength(uint32 resourceId); - void setVoiceBank(int serial); - - FxTable *_fxTable; - int _fxTableLen; - - int16 *_fxTableIDs; - int _fxTableIDsLen; - - private: - bool load(ResourceContext *context, uint32 resourceId, SoundBuffer &buffer, bool onlyHeader); - bool loadVocSound(byte *soundResource, size_t soundResourceLength, SoundBuffer &buffer); - bool loadWavSound(byte *soundResource, size_t soundResourceLength, SoundBuffer &buffer); - - ResourceContext *_sfxContext; - ResourceContext *_voiceContext; - - int _voiceSerial; // voice bank number - - SagaEngine *_vm; -}; - -} // End of namespace Saga - -#endif diff --git a/saga/sound.cpp b/saga/sound.cpp deleted file mode 100644 index 37f9cf174f..0000000000 --- a/saga/sound.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ -#include "saga/saga.h" - -#include "saga/sound.h" - -#include "sound/audiostream.h" -#include "sound/mixer.h" -#include "sound/adpcm.h" - -namespace Saga { - -Sound::Sound(SagaEngine *vm, Audio::Mixer *mixer, int volume) : - _vm(vm), _mixer(mixer), _voxStream(0) { - - for (int i = 0; i < SOUND_HANDLES; i++) - _handles[i].type = kFreeHandle; - - setVolume(volume == 10 ? 255 : volume * 25); -} - -Sound::~Sound() { - delete _voxStream; -} - -SndHandle *Sound::getHandle() { - for (int i = 0; i < SOUND_HANDLES; i++) { - if (_handles[i].type == kFreeHandle) - return &_handles[i]; - - if (!_mixer->isSoundHandleActive(_handles[i].handle)) { - _handles[i].type = kFreeHandle; - return &_handles[i]; - } - } - - error("Sound::getHandle(): Too many sound handles"); - - return NULL; -} - -void Sound::playSoundBuffer(Audio::SoundHandle *handle, SoundBuffer &buffer, int volume, bool loop) { - byte flags; - - flags = Audio::Mixer::FLAG_AUTOFREE; - - if (loop) - flags |= Audio::Mixer::FLAG_LOOP; - - if (buffer.sampleBits == 16) { - flags |= Audio::Mixer::FLAG_16BITS; - - if (!buffer.isBigEndian) - flags |= Audio::Mixer::FLAG_LITTLE_ENDIAN; - } - if (buffer.stereo) - flags |= Audio::Mixer::FLAG_STEREO; - if (!buffer.isSigned) - flags |= Audio::Mixer::FLAG_UNSIGNED; - - _mixer->playRaw(handle, buffer.buffer, buffer.size, buffer.frequency, flags, -1, volume); -} - -void Sound::playSound(SoundBuffer &buffer, int volume, bool loop) { - SndHandle *handle = getHandle(); - - handle->type = kEffectHandle; - playSoundBuffer(&handle->handle, buffer, 2 * volume, loop); -} - -void Sound::pauseSound() { - for (int i = 0; i < SOUND_HANDLES; i++) - if (_handles[i].type == kEffectHandle) - _mixer->pauseHandle(_handles[i].handle, true); -} - -void Sound::resumeSound() { - for (int i = 0; i < SOUND_HANDLES; i++) - if (_handles[i].type == kEffectHandle) - _mixer->pauseHandle(_handles[i].handle, false); -} - -void Sound::stopSound() { - for (int i = 0; i < SOUND_HANDLES; i++) - if (_handles[i].type == kEffectHandle) { - _mixer->stopHandle(_handles[i].handle); - _handles[i].type = kFreeHandle; - } -} - -void Sound::playVoice(SoundBuffer &buffer) { - SndHandle *handle = getHandle(); - - handle->type = kVoiceHandle; - playSoundBuffer(&handle->handle, buffer, 255, false); -} - -void Sound::pauseVoice() { - for (int i = 0; i < SOUND_HANDLES; i++) - if (_handles[i].type == kVoiceHandle) - _mixer->pauseHandle(_handles[i].handle, true); -} - -void Sound::resumeVoice() { - for (int i = 0; i < SOUND_HANDLES; i++) - if (_handles[i].type == kVoiceHandle) - _mixer->pauseHandle(_handles[i].handle, false); -} - -void Sound::stopVoice() { - for (int i = 0; i < SOUND_HANDLES; i++) - if (_handles[i].type == kVoiceHandle) { - _mixer->stopHandle(_handles[i].handle); - _handles[i].type = kFreeHandle; - } -} - -void Sound::stopAll() { - stopVoice(); - stopSound(); -} - -void Sound::setVolume(int volume) { - _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, volume); - _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, volume); -} - -} // End of namespace Saga diff --git a/saga/sound.h b/saga/sound.h deleted file mode 100644 index 85c3eda748..0000000000 --- a/saga/sound.h +++ /dev/null @@ -1,97 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Sound class - -#ifndef SAGA_SOUND_H_ -#define SAGA_SOUND_H_ - -#include "sound/mixer.h" - -namespace Saga { - -#define SOUND_HANDLES 10 - -enum SOUND_FLAGS { - SOUND_LOOP = 1 -}; - -struct SoundBuffer { - uint16 frequency; - int sampleBits; - bool stereo; - bool isSigned; - - byte *buffer; - size_t size; - bool isBigEndian; -}; - -enum sndHandleType { - kFreeHandle, - kEffectHandle, - kVoiceHandle -}; - -struct SndHandle { - Audio::SoundHandle handle; - sndHandleType type; -}; - -class Sound { -public: - - Sound(SagaEngine *vm, Audio::Mixer *mixer, int volume); - ~Sound(); - - void playSound(SoundBuffer &buffer, int volume, bool loop); - void pauseSound(); - void resumeSound(); - void stopSound(); - - void playVoice(SoundBuffer &buffer); - void pauseVoice(); - void resumeVoice(); - void stopVoice(); - - void stopAll(); - - void setVolume(int volume); - - private: - - void playSoundBuffer(Audio::SoundHandle *handle, SoundBuffer &buffer, int volume, bool loop); - - SndHandle *getHandle(); - - SagaEngine *_vm; - Audio::Mixer *_mixer; - Common::MemoryReadStream *_voxStream; - - SndHandle _handles[SOUND_HANDLES]; -}; - -} // End of namespace Saga - -#endif diff --git a/saga/sprite.cpp b/saga/sprite.cpp deleted file mode 100644 index 5309b1f109..0000000000 --- a/saga/sprite.cpp +++ /dev/null @@ -1,444 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Sprite management module -#include "saga/saga.h" - -#include "saga/gfx.h" -#include "saga/scene.h" -#include "saga/resnames.h" -#include "saga/rscfile.h" -#include "saga/font.h" - -#include "saga/sprite.h" -#include "saga/stream.h" - -namespace Saga { - -Sprite::Sprite(SagaEngine *vm) : _vm(vm) { - debug(8, "Initializing sprite subsystem..."); - - // Load sprite module resource context - _spriteContext = _vm->_resource->getContext(GAME_RESOURCEFILE); - if (_spriteContext == NULL) { - error("Sprite::Sprite resource context not found"); - } - - _decodeBufLen = DECODE_BUF_LEN; - - _decodeBuf = (byte *)malloc(_decodeBufLen); - if (_decodeBuf == NULL) { - memoryError("Sprite::Sprite"); - } - - if (_vm->getGameType() == GType_ITE) { - loadList(_vm->getResourceDescription()->mainSpritesResourceId, _mainSprites); - _arrowSprites = _saveReminderSprites = _inventorySprites = _mainSprites; - } else { - loadList(RID_IHNM_ARROW_SPRITES, _arrowSprites); - loadList(RID_IHNM_SAVEREMINDER_SPRITES, _saveReminderSprites); - } -} - -Sprite::~Sprite(void) { - debug(8, "Shutting down sprite subsystem..."); - _mainSprites.freeMem(); - free(_decodeBuf); -} - -void Sprite::loadList(int resourceId, SpriteList &spriteList) { - SpriteInfo *spriteInfo; - byte *spriteListData; - size_t spriteListLength; - uint16 oldSpriteCount; - uint16 newSpriteCount; - uint16 spriteCount; - int i; - int outputLength, inputLength; - uint32 offset; - const byte *spritePointer; - const byte *spriteDataPointer; - - _vm->_resource->loadResource(_spriteContext, resourceId, spriteListData, spriteListLength); - - if (spriteListLength == 0) { - return; - } - - MemoryReadStreamEndian readS(spriteListData, spriteListLength, _spriteContext->isBigEndian); - - spriteCount = readS.readUint16(); - - debug(9, "Sprites: %d", spriteCount); - - oldSpriteCount = spriteList.spriteCount; - newSpriteCount = spriteList.spriteCount + spriteCount; - - spriteList.infoList = (SpriteInfo *)realloc(spriteList.infoList, newSpriteCount * sizeof(*spriteList.infoList)); - if (spriteList.infoList == NULL) { - memoryError("Sprite::loadList"); - } - - spriteList.spriteCount = newSpriteCount; - - bool bigHeader = _vm->getGameType() != GType_ITE || _vm->isMacResources(); - - for (i = oldSpriteCount; i < spriteList.spriteCount; i++) { - spriteInfo = &spriteList.infoList[i]; - if (bigHeader) - offset = readS.readUint32(); - else - offset = readS.readUint16(); - - if (offset >= spriteListLength) { - error("Sprite::loadList offset exceed"); - } - - spritePointer = spriteListData; - spritePointer += offset; - - if (bigHeader) { - MemoryReadStreamEndian readS2(spritePointer, 8, _spriteContext->isBigEndian); - - spriteInfo->xAlign = readS2.readSint16(); - spriteInfo->yAlign = readS2.readSint16(); - - spriteInfo->width = readS2.readUint16(); - spriteInfo->height = readS2.readUint16(); - - spriteDataPointer = spritePointer + readS2.pos(); - } else { - MemoryReadStreamEndian readS2(spritePointer, 4); - - spriteInfo->xAlign = readS2.readSByte(); - spriteInfo->yAlign = readS2.readSByte(); - - spriteInfo->width = readS2.readByte(); - spriteInfo->height = readS2.readByte(); - spriteDataPointer = spritePointer + readS2.pos(); - } - - outputLength = spriteInfo->width * spriteInfo->height; - inputLength = spriteListLength - (spriteDataPointer - spriteListData); - decodeRLEBuffer(spriteDataPointer, inputLength, outputLength); - spriteInfo->decodedBuffer = (byte *) malloc(outputLength); - if (spriteInfo->decodedBuffer == NULL) { - memoryError("Sprite::loadList"); - } - - // IHNM sprites are upside-down, for reasons which i can only - // assume are perverse. To simplify things, flip them now. Not - // at drawing time. - - if (_vm->getGameType() == GType_IHNM) { - byte *src = _decodeBuf + spriteInfo->width * (spriteInfo->height - 1); - byte *dst = spriteInfo->decodedBuffer; - - for (int j = 0; j < spriteInfo->height; j++) { - memcpy(dst, src, spriteInfo->width); - src -= spriteInfo->width; - dst += spriteInfo->width; - } - } else - memcpy(spriteInfo->decodedBuffer, _decodeBuf, outputLength); - } - - free(spriteListData); -} - -void Sprite::getScaledSpriteBuffer(SpriteList &spriteList, int spriteNumber, int scale, int &width, int &height, int &xAlign, int &yAlign, const byte *&buffer) { - SpriteInfo *spriteInfo; - assert(spriteList.spriteCount>spriteNumber); - spriteInfo = &spriteList.infoList[spriteNumber]; - - if (scale < 256) { - xAlign = (spriteInfo->xAlign * scale) >> 8; - yAlign = (spriteInfo->yAlign * scale) >> 8; - height = (spriteInfo->height * scale + 0x7f) >> 8; - width = (spriteInfo->width * scale + 0x7f) >> 8; - scaleBuffer(spriteInfo->decodedBuffer, spriteInfo->width, spriteInfo->height, scale); - buffer = _decodeBuf; - } else { - xAlign = spriteInfo->xAlign; - yAlign = spriteInfo->yAlign; - height = spriteInfo->height; - width = spriteInfo->width; - buffer = spriteInfo->decodedBuffer; - } -} - -void Sprite::drawClip(Surface *ds, const Rect &clipRect, const Point &spritePointer, int width, int height, const byte *spriteBuffer) { - int clipWidth; - int clipHeight; - - int i, j, jo, io; - byte *bufRowPointer; - const byte *srcRowPointer; - - bufRowPointer = (byte *)ds->pixels + ds->pitch * spritePointer.y; - srcRowPointer = spriteBuffer; - - clipWidth = width; - if (width > (clipRect.right - spritePointer.x)) { - clipWidth = (clipRect.right - spritePointer.x); - } - - clipHeight = height; - if (height > (clipRect.bottom - spritePointer.y)) { - clipHeight = (clipRect.bottom - spritePointer.y); - } - - jo = 0; - io = 0; - if (spritePointer.x < clipRect.left) { - jo = clipRect.left - spritePointer.x; - } - if (spritePointer.y < clipRect.top) { - io = clipRect.top - spritePointer.y; - bufRowPointer += ds->pitch * io; - srcRowPointer += width * io; - } - - for (i = io; i < clipHeight; i++) { - for (j = jo; j < clipWidth; j++) { - assert((byte *)ds->pixels <= (byte *)(bufRowPointer + j + spritePointer.x)); - assert(((byte *)ds->pixels + (_vm->getDisplayWidth() * - _vm->getDisplayHeight())) > (byte *)(bufRowPointer + j + spritePointer.x)); - assert((const byte *)spriteBuffer <= (const byte *)(srcRowPointer + j)); - assert(((const byte *)spriteBuffer + (width * height)) > (const byte *)(srcRowPointer + j)); - - if (*(srcRowPointer + j) != 0) { - *(bufRowPointer + j + spritePointer.x) = *(srcRowPointer + j); - } - } - bufRowPointer += ds->pitch; - srcRowPointer += width; - } -} - -void Sprite::draw(Surface *ds, const Rect &clipRect, SpriteList &spriteList, int32 spriteNumber, const Point &screenCoord, int scale) { - const byte *spriteBuffer; - int width; - int height; - int xAlign; - int yAlign; - Point spritePointer; - - getScaledSpriteBuffer(spriteList, spriteNumber, scale, width, height, xAlign, yAlign, spriteBuffer); - - spritePointer.x = screenCoord.x + xAlign; - spritePointer.y = screenCoord.y + yAlign; - - drawClip(ds, clipRect, spritePointer, width, height, spriteBuffer); -} - -void Sprite::draw(Surface *ds, const Rect &clipRect, SpriteList &spriteList, int32 spriteNumber, const Rect &screenRect, int scale) { - const byte *spriteBuffer; - int width; - int height; - int xAlign, spw; - int yAlign, sph; - Point spritePointer; - - getScaledSpriteBuffer(spriteList, spriteNumber, scale, width, height, xAlign, yAlign, spriteBuffer); - spw = (screenRect.width() - width) / 2; - sph = (screenRect.height() - height) / 2; - if (spw < 0) { - spw = 0; - } - if (sph < 0) { - sph = 0; - } - spritePointer.x = screenRect.left + xAlign + spw; - spritePointer.y = screenRect.top + yAlign + sph; - drawClip(ds, clipRect, spritePointer, width, height, spriteBuffer); -} - -bool Sprite::hitTest(SpriteList &spriteList, int spriteNumber, const Point &screenCoord, int scale, const Point &testPoint) { - const byte *spriteBuffer; - int i, j; - const byte *srcRowPointer; - int width; - int height; - int xAlign; - int yAlign; - Point spritePointer; - - getScaledSpriteBuffer(spriteList, spriteNumber, scale, width, height, xAlign, yAlign, spriteBuffer); - - spritePointer.x = screenCoord.x + xAlign; - spritePointer.y = screenCoord.y + yAlign; - - if ((testPoint.y < spritePointer.y) || (testPoint.y >= spritePointer.y + height)) { - return false; - } - if ((testPoint.x < spritePointer.x) || (testPoint.x >= spritePointer.x + width)) { - return false; - } - i = testPoint.y - spritePointer.y; - j = testPoint.x - spritePointer.x; - srcRowPointer = spriteBuffer + j + i * width; - return *srcRowPointer != 0; -} - -void Sprite::drawOccluded(Surface *ds, const Rect &clipRect, SpriteList &spriteList, int spriteNumber, const Point &screenCoord, int scale, int depth) { - const byte *spriteBuffer; - int x, y; - byte *destRowPointer; - const byte *sourceRowPointer; - const byte *sourcePointer; - byte *destPointer; - byte *maskPointer; - int width; - int height; - int xAlign; - int yAlign; - - ClipData clipData; - - // BG mask variables - int maskWidth; - int maskHeight; - byte *maskBuffer; - size_t maskBufferLength; - byte *maskRowPointer; - int maskZ; - - if (!_vm->_scene->isBGMaskPresent()) { - draw(ds, clipRect, spriteList, spriteNumber, screenCoord, scale); - return; - } - - _vm->_scene->getBGMaskInfo(maskWidth, maskHeight, maskBuffer, maskBufferLength); - - getScaledSpriteBuffer(spriteList, spriteNumber, scale, width, height, xAlign, yAlign, spriteBuffer); - - clipData.destPoint.x = screenCoord.x + xAlign; - clipData.destPoint.y = screenCoord.y + yAlign; - - clipData.sourceRect.left = 0; - clipData.sourceRect.top = 0; - clipData.sourceRect.right = width; - clipData.sourceRect.bottom = height; - - clipData.destRect = clipRect; - - if (!clipData.calcClip()) { - return; - } - - // Finally, draw the occluded sprite - - sourceRowPointer = spriteBuffer + clipData.drawSource.x + (clipData.drawSource.y * width); - destRowPointer = (byte *)ds->pixels + clipData.drawDest.x + (clipData.drawDest.y * ds->pitch); - maskRowPointer = maskBuffer + clipData.drawDest.x + (clipData.drawDest.y * maskWidth); - - for (y = 0; y < clipData.drawHeight; y++) { - sourcePointer = sourceRowPointer; - destPointer = destRowPointer; - maskPointer = maskRowPointer; - for (x = 0; x < clipData.drawWidth; x++) { - if (*sourcePointer != 0) { - maskZ = *maskPointer & SPRITE_ZMASK; - if (maskZ > depth) { - *destPointer = *sourcePointer; - } - } - sourcePointer++; - destPointer++; - maskPointer++; - } - destRowPointer += ds->pitch; - maskRowPointer += maskWidth; - sourceRowPointer += width; - } -} - -void Sprite::decodeRLEBuffer(const byte *inputBuffer, size_t inLength, size_t outLength) { - int bg_runcount; - int fg_runcount; - byte *outPointer; - byte *outPointerEnd; - int c; - - if (outLength > _decodeBufLen) { // TODO: may we should make dynamic growing? - error("Sprite::decodeRLEBuffer outLength > _decodeBufLen"); - } - - outPointer = _decodeBuf; - outPointerEnd = _decodeBuf + outLength; - outPointerEnd--; - - memset(outPointer, 0, outLength); - - MemoryReadStream readS(inputBuffer, inLength); - - while (!readS.eos() && (outPointer < outPointerEnd)) { - bg_runcount = readS.readByte(); - fg_runcount = readS.readByte(); - - for (c = 0; c < bg_runcount && !readS.eos(); c++) { - *outPointer = (byte) 0; - if (outPointer < outPointerEnd) - outPointer++; - else - return; - } - - for (c = 0; c < fg_runcount && !readS.eos(); c++) { - *outPointer = readS.readByte(); - if (outPointer < outPointerEnd) - outPointer++; - else - return; - } - } -} - -void Sprite::scaleBuffer(const byte *src, int width, int height, int scale) { - byte skip = 256 - scale; // skip factor - byte vskip = 0x80, hskip; - byte *dst = _decodeBuf; - - for (int i = 0; i < height; i++) { - vskip += skip; - - if (vskip < skip) { // We had an overflow - src += width; - } else { - hskip = 0x80; - - for (int j = 0; j < width; j++) { - *dst++ = *src++; - - hskip += skip; - if (hskip < skip) // overflow - dst--; - } - } - } -} - - -} // End of namespace Saga diff --git a/saga/sprite.h b/saga/sprite.h deleted file mode 100644 index 03bde8e050..0000000000 --- a/saga/sprite.h +++ /dev/null @@ -1,102 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Sprite management module private header file - -#ifndef SAGA_SPRITE_H__ -#define SAGA_SPRITE_H__ - -namespace Saga { - -#define SPRITE_ZMAX 16 -#define SPRITE_ZMASK 0x0F - -#define DECODE_BUF_LEN 64000 - -struct SpriteInfo { - byte *decodedBuffer; - int width; - int height; - int xAlign; - int yAlign; -}; - -struct SpriteList { - int spriteListResourceId; - int spriteCount; - SpriteInfo *infoList; - - void freeMem() { - int i; - for (i = 0; i < spriteCount; i++) { - free(infoList[i].decodedBuffer); - } - free(infoList); - memset(this, 0, sizeof(*this)); - } - - SpriteList() { - memset(this, 0, sizeof(*this)); - } -}; - - -class Sprite { -public: - SpriteList _mainSprites; - SpriteList _saveReminderSprites; - SpriteList _arrowSprites; - SpriteList _inventorySprites; - - Sprite(SagaEngine *vm); - ~Sprite(void); - - // draw scaled sprite using background scene mask - void drawOccluded(Surface *ds, const Rect &clipRect, SpriteList &spriteList, int spriteNumber, const Point &screenCoord, int scale, int depth); - - // draw scaled sprite using background scene mask - void draw(Surface *ds, const Rect &clipRect, SpriteList &spriteList, int32 spriteNumber, const Point &screenCoord, int scale); - - // main function - void drawClip(Surface *ds, const Rect &clipRect, const Point &spritePointer, int width, int height, const byte *spriteBuffer); - - void draw(Surface *ds, const Rect &clipRect, SpriteList &spriteList, int32 spriteNumber, const Rect &screenRect, int scale); - - void loadList(int resourceId, SpriteList &spriteList); // load or append spriteList - bool hitTest(SpriteList &spriteList, int spriteNumber, const Point &screenCoord, int scale, const Point &testPoint); - void getScaledSpriteBuffer(SpriteList &spriteList, int spriteNumber, int scale, int &width, int &height, int &xAlign, int &yAlign, const byte *&buffer); - -private: - void decodeRLEBuffer(const byte *inputBuffer, size_t inLength, size_t outLength); - void scaleBuffer(const byte *src, int width, int height, int scale); - - SagaEngine *_vm; - ResourceContext *_spriteContext; - byte *_decodeBuf; - size_t _decodeBufLen; -}; - -} // End of namespace Saga - -#endif diff --git a/saga/sthread.cpp b/saga/sthread.cpp deleted file mode 100644 index a6724b588c..0000000000 --- a/saga/sthread.cpp +++ /dev/null @@ -1,746 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. - * - * 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$ - * - */ - -// Scripting module thread management component -#include "saga/saga.h" - -#include "saga/gfx.h" -#include "saga/actor.h" -#include "saga/console.h" -#include "saga/interface.h" - -#include "saga/script.h" - -#include "saga/stream.h" -#include "saga/scene.h" -#include "saga/resnames.h" - -namespace Saga { - -ScriptThread *Script::createThread(uint16 scriptModuleNumber, uint16 scriptEntryPointNumber) { - ScriptThread *newThread; - - loadModule(scriptModuleNumber); - if (_modules[scriptModuleNumber].entryPointsCount <= scriptEntryPointNumber) { - error("Script::createThread wrong scriptEntryPointNumber"); - } - - newThread = _threadList.pushFront().operator->(); - newThread->_flags = kTFlagNone; - newThread->_stackSize = DEFAULT_THREAD_STACK_SIZE; - newThread->_stackBuf = (uint16 *)malloc(newThread->_stackSize * sizeof(*newThread->_stackBuf)); - newThread->_stackTopIndex = newThread->_stackSize - 2; - newThread->_instructionOffset = _modules[scriptModuleNumber].entryPoints[scriptEntryPointNumber].offset; - newThread->_commonBase = _commonBuffer; - newThread->_staticBase = _commonBuffer + _modules[scriptModuleNumber].staticOffset; - newThread->_moduleBase = _modules[scriptModuleNumber].moduleBase; - newThread->_moduleBaseSize = _modules[scriptModuleNumber].moduleBaseSize; - - newThread->_strings = &_modules[scriptModuleNumber].strings; - - if (_vm->getGameType() == GType_IHNM) - newThread->_voiceLUT = &_globalVoiceLUT; - else - newThread->_voiceLUT = &_modules[scriptModuleNumber].voiceLUT; - - return newThread; -} - -void Script::wakeUpActorThread(int waitType, void *threadObj) { - ScriptThread *thread; - ScriptThreadList::iterator threadIterator; - - for (threadIterator = _threadList.begin(); threadIterator != _threadList.end(); ++threadIterator) { - thread = threadIterator.operator->(); - if ((thread->_flags & kTFlagWaiting) && (thread->_waitType == waitType) && (thread->_threadObj == threadObj)) { - thread->_flags &= ~kTFlagWaiting; - } - } -} - -void Script::wakeUpThreads(int waitType) { - ScriptThread *thread; - ScriptThreadList::iterator threadIterator; - - for (threadIterator = _threadList.begin(); threadIterator != _threadList.end(); ++threadIterator) { - thread = threadIterator.operator->(); - if ((thread->_flags & kTFlagWaiting) && (thread->_waitType == waitType)) { - thread->_flags &= ~kTFlagWaiting; - } - } -} - -void Script::wakeUpThreadsDelayed(int waitType, int sleepTime) { - ScriptThread *thread; - ScriptThreadList::iterator threadIterator; - - for (threadIterator = _threadList.begin(); threadIterator != _threadList.end(); ++threadIterator) { - thread = threadIterator.operator->(); - if ((thread->_flags & kTFlagWaiting) && (thread->_waitType == waitType)) { - thread->_waitType = kWaitTypeDelay; - thread->_sleepTime = sleepTime; - } - } -} - -void Script::executeThreads(uint msec) { - ScriptThread *thread; - ScriptThreadList::iterator threadIterator; - - if (_vm->_interface->_statusTextInput) { - return; - } - - threadIterator = _threadList.begin(); - - while (threadIterator != _threadList.end()) { - thread = threadIterator.operator->(); - - if (thread->_flags & (kTFlagFinished | kTFlagAborted)) { - if (thread->_flags & kTFlagFinished) - setPointerVerb(); - - if (_vm->getGameType() == GType_IHNM) { - thread->_flags &= ~kTFlagFinished; - thread->_flags |= kTFlagAborted; - ++threadIterator; - } else { - threadIterator = _threadList.erase(threadIterator); - } - continue; - } - - if (thread->_flags & kTFlagWaiting) { - - switch (thread->_waitType) { - case kWaitTypeDelay: - if (thread->_sleepTime < msec) { - thread->_sleepTime = 0; - } else { - thread->_sleepTime -= msec; - } - - if (thread->_sleepTime == 0) - thread->_flags &= ~kTFlagWaiting; - break; - - case kWaitTypeWalk: - { - ActorData *actor; - actor = (ActorData *)thread->_threadObj; - if (actor->_currentAction == kActionWait) { - thread->_flags &= ~kTFlagWaiting; - } - } - break; - - case kWaitTypeWaitFrames: // IHNM - if (thread->_frameWait < _vm->_frameCount) - thread->_flags &= ~kTFlagWaiting; - break; - } - } - - if (!(thread->_flags & kTFlagWaiting)) { - if (runThread(thread, STHREAD_TIMESLICE)) { - break; - } - } - - ++threadIterator; - } - -} - -void Script::abortAllThreads(void) { - ScriptThread *thread; - ScriptThreadList::iterator threadIterator; - - threadIterator = _threadList.begin(); - - while (threadIterator != _threadList.end()) { - thread = threadIterator.operator->(); - thread->_flags |= kTFlagAborted; - ++threadIterator; - } - executeThreads(0); -} - -void Script::completeThread(void) { - int limit = (_vm->getGameType() == GType_IHNM) ? 100 : 40; - - for (int i = 0; i < limit && !_threadList.isEmpty(); i++) - executeThreads(0); -} - -bool Script::runThread(ScriptThread *thread, uint instructionLimit) { - const char*operandName; - uint instructionCount; - uint16 savedInstructionOffset; - - byte *addr; - byte mode; - uint16 jmpOffset1; - int16 iparam1; - int16 iparam2; - int16 iparam3; - - bool disContinue; - byte argumentsCount; - uint16 functionNumber; - uint16 checkStackTopIndex; - ScriptFunctionType scriptFunction; - - int operandChar; - int i; - - MemoryReadStream scriptS(thread->_moduleBase, thread->_moduleBaseSize); - - scriptS.seek(thread->_instructionOffset); - - for (instructionCount = 0; instructionCount < instructionLimit; instructionCount++) { - if (thread->_flags & (kTFlagAsleep)) - break; - - savedInstructionOffset = thread->_instructionOffset; - operandChar = scriptS.readByte(); - - -#define CASEOP(opName) case opName: \ - if (operandChar == opName) { \ - operandName = #opName; \ - debug(2, operandName); \ - _vm->_console->DebugPrintf("%s\n", operandName); \ - } - - debug(8, "Executing thread offset: %lu (%x) stack: %d", thread->_instructionOffset, operandChar, thread->pushedSize()); - operandName=""; - switch (operandChar) { - CASEOP(opNextBlock) - // Some sort of "jump to the start of the next memory - // page" instruction, I think. - thread->_instructionOffset = (((thread->_instructionOffset) >> 10) + 1) << 10; - break; - -// STACK INSTRUCTIONS - CASEOP(opDup) - thread->push(thread->stackTop()); - break; - CASEOP(opDrop) - thread->pop(); - break; - CASEOP(opZero) - thread->push(0); - break; - CASEOP(opOne) - thread->push(1); - break; - CASEOP(opConstint) - CASEOP(opStrlit) - iparam1 = scriptS.readSint16LE(); - thread->push(iparam1); - debug(8, "0x%X", iparam1); - break; - -// DATA INSTRUCTIONS - CASEOP(opGetFlag) - addr = thread->baseAddress(scriptS.readByte()); - iparam1 = scriptS.readSint16LE(); - addr += (iparam1 >> 3); - iparam1 = (1 << (iparam1 & 7)); - thread->push((*addr) & iparam1 ? 1 : 0); - break; - CASEOP(opGetInt) - mode = scriptS.readByte(); - addr = thread->baseAddress(mode); - iparam1 = scriptS.readSint16LE(); - addr += iparam1; - thread->push(readUint16(addr, mode)); - debug(8, "0x%X", readUint16(addr, mode)); - break; - CASEOP(opPutFlag) - addr = thread->baseAddress(scriptS.readByte()); - iparam1 = scriptS.readSint16LE(); - addr += (iparam1 >> 3); - iparam1 = (1 << (iparam1 & 7)); - if (thread->stackTop()) { - *addr |= iparam1; - } else { - *addr &= ~iparam1; - } - break; - CASEOP(opPutInt) - mode = scriptS.readByte(); - addr = thread->baseAddress(mode); - iparam1 = scriptS.readSint16LE(); - addr += iparam1; - writeUint16(addr, thread->stackTop(), mode); - break; - CASEOP(opPutFlagV) - addr = thread->baseAddress(scriptS.readByte()); - iparam1 = scriptS.readSint16LE(); - addr += (iparam1 >> 3); - iparam1 = (1 << (iparam1 & 7)); - if (thread->pop()) { - *addr |= iparam1; - } else { - *addr &= ~iparam1; - } - break; - CASEOP(opPutIntV) - mode = scriptS.readByte(); - addr = thread->baseAddress(mode); - iparam1 = scriptS.readSint16LE(); - addr += iparam1; - writeUint16(addr, thread->pop(), mode); - break; - -// FUNCTION CALL INSTRUCTIONS - CASEOP(opCall) - argumentsCount = scriptS.readByte(); - iparam1 = scriptS.readByte(); - if (iparam1 != kAddressModule) { - error("Script::runThread iparam1 != kAddressModule"); - } - addr = thread->baseAddress(iparam1); - iparam1 = scriptS.readSint16LE(); - addr += iparam1; - thread->push(argumentsCount); - - jmpOffset1 = scriptS.pos(); - // NOTE: The original pushes the program - // counter as a pointer here. But I don't think - // we will have to do that. - thread->push(jmpOffset1); - // NOTE2: program counter is 32bit - so we should "emulate" it size - because kAddressStack relies on it - thread->push(0); - thread->_instructionOffset = iparam1; - - break; - CASEOP(opCcall) - CASEOP(opCcallV) - argumentsCount = scriptS.readByte(); - functionNumber = scriptS.readUint16LE(); - if (functionNumber >= ((_vm->getGameType() == GType_IHNM) ? - IHNM_SCRIPT_FUNCTION_MAX : ITE_SCRIPT_FUNCTION_MAX)) { - error("Script::runThread() Invalid script function number (%d)", functionNumber); - } - - debug(2, "Calling #%d %s argCount=%i", functionNumber, _scriptFunctionsList[functionNumber].scriptFunctionName, argumentsCount); - scriptFunction = _scriptFunctionsList[functionNumber].scriptFunction; - checkStackTopIndex = thread->_stackTopIndex + argumentsCount; - disContinue = false; - (this->*scriptFunction)(thread, argumentsCount, disContinue); - if (disContinue) { - return true; - } - if (scriptFunction == &Saga::Script::sfScriptGotoScene || - scriptFunction == &Saga::Script::sfVsetTrack) { - return true; // cause abortAllThreads called and _this_ thread destroyed - } - - thread->_stackTopIndex = checkStackTopIndex; - - if (operandChar == opCcall) {// CALL function - thread->push(thread->_returnValue); - } - - if (thread->_flags & kTFlagAsleep) - instructionCount = instructionLimit; // break out of loop! - break; - CASEOP(opEnter) - thread->push(thread->_frameIndex); - thread->_frameIndex = thread->_stackTopIndex; - thread->_stackTopIndex -= (scriptS.readSint16LE() / 2); - break; - CASEOP(opReturn) - thread->_returnValue = thread->pop(); - CASEOP(opReturnV) - thread->_stackTopIndex = thread->_frameIndex; - thread->_frameIndex = thread->pop(); - if (thread->pushedSize() == 0) { - thread->_flags |= kTFlagFinished; - return true; - } else { - thread->pop(); //cause it 0 - thread->_instructionOffset = thread->pop(); - - // Pop all the call parameters off the stack - iparam1 = thread->pop(); - while (iparam1--) { - thread->pop(); - } - - if (operandChar == opReturn) { - thread->push(thread->_returnValue); - } - } - break; - -// BRANCH INSTRUCTIONS - CASEOP(opJmp) - jmpOffset1 = scriptS.readUint16LE(); - thread->_instructionOffset = jmpOffset1; - break; - CASEOP(opJmpTrueV) - jmpOffset1 = scriptS.readUint16LE(); - if (thread->pop()) { - thread->_instructionOffset = jmpOffset1; - } - break; - CASEOP(opJmpFalseV) - jmpOffset1 = scriptS.readUint16LE(); - if (!thread->pop()) { - thread->_instructionOffset = jmpOffset1; - } - break; - CASEOP(opJmpTrue) - jmpOffset1 = scriptS.readUint16LE(); - if (thread->stackTop()) { - thread->_instructionOffset = jmpOffset1; - } - break; - CASEOP(opJmpFalse) - jmpOffset1 = scriptS.readUint16LE(); - if (!thread->stackTop()) { - thread->_instructionOffset = jmpOffset1; - } - break; - CASEOP(opJmpSwitch) - iparam1 = scriptS.readSint16LE(); - iparam2 = thread->pop(); - while (iparam1--) { - iparam3 = scriptS.readUint16LE(); - thread->_instructionOffset = scriptS.readUint16LE(); - if (iparam3 == iparam2) { - break; - } - } - if (iparam1 < 0) { - thread->_instructionOffset = scriptS.readUint16LE(); - } - break; - CASEOP(opJmpRandom) - // Supposedly the number of possible branches. - // The original interpreter ignores it. - scriptS.readUint16LE(); - iparam1 = scriptS.readSint16LE(); - iparam1 = _vm->_rnd.getRandomNumber(iparam1 - 1); - while (1) { - iparam2 = scriptS.readSint16LE(); - thread->_instructionOffset = scriptS.readUint16LE(); - - iparam1 -= iparam2; - if (iparam1 < 0) { - break; - } - } - break; - -// UNARY INSTRUCTIONS - CASEOP(opNegate) - thread->push(-thread->pop()); - break; - CASEOP(opNot) - thread->push(!thread->pop()); - break; - CASEOP(opCompl) - thread->push(~thread->pop()); - break; - - CASEOP(opIncV) - mode = scriptS.readByte(); - addr = thread->baseAddress(mode); - iparam1 = scriptS.readSint16LE(); - addr += iparam1; - iparam1 = readUint16(addr, mode); - writeUint16(addr, iparam1 + 1, mode); - break; - CASEOP(opDecV) - mode = scriptS.readByte(); - addr = thread->baseAddress(mode); - iparam1 = scriptS.readSint16LE(); - addr += iparam1; - iparam1 = readUint16(addr, mode); - writeUint16(addr, iparam1 - 1, mode); - break; - CASEOP(opPostInc) - mode = scriptS.readByte(); - addr = thread->baseAddress(mode); - iparam1 = scriptS.readSint16LE(); - addr += iparam1; - iparam1 = readUint16(addr, mode); - thread->push(iparam1); - writeUint16(addr, iparam1 + 1, mode); - break; - CASEOP(opPostDec) - mode = scriptS.readByte(); - addr = thread->baseAddress(mode); - iparam1 = scriptS.readSint16LE(); - addr += iparam1; - iparam1 = readUint16(addr, mode); - thread->push(iparam1); - writeUint16(addr, iparam1 - 1, mode); - break; - -// ARITHMETIC INSTRUCTIONS - CASEOP(opAdd) - iparam2 = thread->pop(); - iparam1 = thread->pop(); - iparam1 += iparam2; - thread->push(iparam1); - break; - CASEOP(opSub) - iparam2 = thread->pop(); - iparam1 = thread->pop(); - iparam1 -= iparam2; - thread->push(iparam1); - break; - CASEOP(opMul) - iparam2 = thread->pop(); - iparam1 = thread->pop(); - iparam1 *= iparam2; - thread->push(iparam1); - break; - CASEOP(opDiv) - iparam2 = thread->pop(); - iparam1 = thread->pop(); - iparam1 /= iparam2; - thread->push(iparam1); - break; - CASEOP(opMod) - iparam2 = thread->pop(); - iparam1 = thread->pop(); - iparam1 %= iparam2; - thread->push(iparam1); - break; - -// COMPARISION INSTRUCTIONS - CASEOP(opEq) - iparam2 = thread->pop(); - iparam1 = thread->pop(); - thread->push((iparam1 == iparam2) ? 1 : 0); - debug(8, "0x%X 0x%X", iparam1, iparam2); - break; - CASEOP(opNe) - iparam2 = thread->pop(); - iparam1 = thread->pop(); - thread->push((iparam1 != iparam2) ? 1 : 0); - break; - CASEOP(opGt) - iparam2 = thread->pop(); - iparam1 = thread->pop(); - thread->push((iparam1 > iparam2) ? 1 : 0); - break; - CASEOP(opLt) - iparam2 = thread->pop(); - iparam1 = thread->pop(); - thread->push((iparam1 < iparam2) ? 1 : 0); - break; - CASEOP(opGe) - iparam2 = thread->pop(); - iparam1 = thread->pop(); - thread->push((iparam1 >= iparam2) ? 1 : 0); - break; - CASEOP(opLe) - iparam2 = thread->pop(); - iparam1 = thread->pop(); - thread->push((iparam1 <= iparam2) ? 1 : 0); - break; - -// SHIFT INSTRUCTIONS - CASEOP(opRsh) - iparam2 = thread->pop(); - iparam1 = thread->pop(); - iparam1 >>= iparam2; - thread->push(iparam1); - break; - CASEOP(opLsh) - iparam2 = thread->pop(); - iparam1 = thread->pop(); - iparam1 <<= iparam2; - thread->push(iparam1); - break; - -// BITWISE INSTRUCTIONS - CASEOP(opAnd) - iparam2 = thread->pop(); - iparam1 = thread->pop(); - iparam1 &= iparam2; - thread->push(iparam1); - break; - CASEOP(opOr) - iparam2 = thread->pop(); - iparam1 = thread->pop(); - iparam1 |= iparam2; - thread->push(iparam1); - break; - CASEOP(opXor) - iparam2 = thread->pop(); - iparam1 = thread->pop(); - iparam1 ^= iparam2; - thread->push(iparam1); - break; - -// LOGICAL INSTRUCTIONS - CASEOP(opLAnd) - iparam2 = thread->pop(); - iparam1 = thread->pop(); - thread->push((iparam1 && iparam2) ? 1 : 0); - break; - CASEOP(opLOr) - iparam2 = thread->pop(); - iparam1 = thread->pop(); - thread->push((iparam1 || iparam2) ? 1 : 0); - break; - CASEOP(opLXor) - iparam2 = thread->pop(); - iparam1 = thread->pop(); - thread->push(((iparam1 && !iparam2) || (!iparam1 && iparam2)) ? 1 : 0); - break; - -// GAME INSTRUCTIONS - CASEOP(opSpeak) { - int stringsCount; - uint16 actorId; - uint16 speechFlags; - int sampleResourceId = -1; - int16 first; - const char *strings[ACTOR_SPEECH_STRING_MAX]; - - if (_vm->_actor->isSpeaking()) { - thread->wait(kWaitTypeSpeech); - return false; - } - - stringsCount = scriptS.readByte(); - actorId = scriptS.readUint16LE(); - speechFlags = scriptS.readByte(); - scriptS.readUint16LE(); // x,y skip - - if (stringsCount == 0) - error("opSpeak stringsCount == 0"); - - if (stringsCount > ACTOR_SPEECH_STRING_MAX) - error("opSpeak stringsCount=0x%X exceed ACTOR_SPEECH_STRING_MAX", stringsCount); - - iparam1 = first = thread->stackTop(); - for (i = 0; i < stringsCount; i++) { - iparam1 = thread->pop(); - strings[i] = thread->_strings->getString(iparam1); - } - // now data contains last string index - - if (_vm->getGameId() == GID_ITE_DISK_G) { // special ITE dos - if ((_vm->_scene->currentSceneNumber() == ITE_DEFAULT_SCENE) && - (iparam1 >= 288) && (iparam1 <= (RID_SCENE1_VOICE_138 - RID_SCENE1_VOICE_009 + 288))) { - sampleResourceId = RID_SCENE1_VOICE_009 + iparam1 - 288; - } - } else { - if (thread->_voiceLUT->voicesCount > first) { - sampleResourceId = thread->_voiceLUT->voices[first]; - } - } - - if (sampleResourceId < 0 || sampleResourceId > 4000) - sampleResourceId = -1; - - if (_vm->getGameType() == GType_ITE && !sampleResourceId) - sampleResourceId = -1; - - _vm->_actor->actorSpeech(actorId, strings, stringsCount, sampleResourceId, speechFlags); - - if (!(speechFlags & kSpeakAsync)) { - thread->wait(kWaitTypeSpeech); - } - } - break; - CASEOP(opDialogBegin) - if (_conversingThread) { - thread->wait(kWaitTypeDialogBegin); - return false; - } - _conversingThread = thread; - _vm->_interface->converseClear(); - break; - CASEOP(opDialogEnd) - if (thread == _conversingThread) { - _vm->_interface->activate(); - _vm->_interface->setMode(kPanelConverse); - thread->wait(kWaitTypeDialogEnd); - return false; - } - break; - CASEOP(opReply) { - const char *str; - byte replyNum; - byte flags; - replyNum = scriptS.readByte(); - flags = scriptS.readByte(); - iparam1 = 0; - - if (flags & kReplyOnce) { - iparam1 = scriptS.readSint16LE(); - addr = thread->_staticBase + (iparam1 >> 3); - if (*addr & (1 << (iparam1 & 7))) { - break; - } - } - - str = thread->_strings->getString(thread->pop()); - if (_vm->_interface->converseAddText(str, replyNum, flags, iparam1)) - warning("Error adding ConverseText (%s, %d, %d, %d)", str, replyNum, flags, iparam1); - } - break; - CASEOP(opAnimate) - scriptS.readUint16LE(); - scriptS.readUint16LE(); - jmpOffset1 = scriptS.readByte(); - thread->_instructionOffset += jmpOffset1; - break; - - default: - error("Script::runThread() Invalid opcode encountered 0x%X", operandChar); - } - - if (thread->_flags & (kTFlagFinished | kTFlagAborted)) { - error("Wrong flags %d in thread", thread->_flags); - } - - // Set instruction offset only if a previous instruction didn't branch - if (savedInstructionOffset == thread->_instructionOffset) { - thread->_instructionOffset = scriptS.pos(); - } else { - if (thread->_instructionOffset >= scriptS.size()) { - error("Script::runThread() Out of range script execution"); - } - - scriptS.seek(thread->_instructionOffset); - } - } - return false; -} - -} // End of namespace Saga - diff --git a/saga/stream.h b/saga/stream.h deleted file mode 100644 index 4a407216b2..0000000000 --- a/saga/stream.h +++ /dev/null @@ -1,57 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-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$ - * - */ - -#ifndef SAGA_STREAM_H__ -#define SAGA_STREAM_H__ - -#include "common/stream.h" - -namespace Saga { - -using Common::MemoryReadStream; - -class MemoryReadStreamEndian : public Common::MemoryReadStream { -private: -public: - bool _bigEndian; - MemoryReadStreamEndian(const byte *buf, uint32 len, bool bigEndian = false) : MemoryReadStream(buf, len), _bigEndian(bigEndian) {} - - uint16 readUint16() { - return (_bigEndian) ? readUint16BE(): readUint16LE(); - } - - uint32 readUint32() { - return (_bigEndian) ? readUint32BE(): readUint32LE(); - } - - inline int16 readSint16() { - return (int16)readUint16(); - } - - - inline int32 readSint32() { - return (int32)readUint32(); - } -}; - -} // End of namespace Saga -#endif diff --git a/saga/xref.txt b/saga/xref.txt deleted file mode 100644 index 1d3aff0824..0000000000 --- a/saga/xref.txt +++ /dev/null @@ -1,139 +0,0 @@ -$Id$ - -Cross-reference for functions and variables for the original source code and -the ScummVM implementation. - -Watcom C++ arguments order: - - eax, edx, ebx, ecx, stack - -Sceneres.h -========== - LOADREQ_FIGURE - LOADREQ_OBJECT - LOADREQ_BACKGROUND SAGA_BG_IMAGE - LOADREQ_ZBUF SAGA_BG_MASK - LOADREQ_SCENE_SCRIPT - LOADREQ_STRINGS SAGA_OBJECT_NAME_LIST - LOADREQ_HITZONES SAGA_OBJECT_MAP - LOADREQ_STEPZONES SAGA_ACTION_MAP - LOADREQ_TILE_IMAGES SAGA_ISO_TILESET - LOADREQ_TILE_MAP SAGA_ISO_METAMAP - LOADREQ_TILE_PLATFORMS SAGA_ISO_METATILESET - LOADREQ_TILE_METATILES - LOADREQ_ENTRY SAGA_ENTRY - LOADREQ_FRAMELIST - - LOADREQ_ANIM_0 SAGA_ANIM_1 - LOADREQ_ANIM_1 SAGA_ANIM_2 - LOADREQ_ANIM_2 SAGA_ANIM_3 - LOADREQ_ANIM_3 SAGA_ANIM_4 - LOADREQ_ANIM_4 SAGA_ANIM_5 - LOADREQ_ANIM_5 SAGA_ANIM_6 - LOADREQ_ANIM_6 SAGA_ANIM_7 - LOADREQ_ANIM_7 - - LOADREQ_TILE_MULTI - LOADREQ_CYCLES SAGA_PAL_ANIM - LOADREQ_FACES SAGA_FACES - LOADREQ_PALETTE - - hitZone _objectMap - stepZone _actionMap - - HZONEF_EXIT OBJECT_EXIT (in Verb.c), ACTION_EXIT (in Actor.c) - HZONEF_ENABLED OBJECT_ENABLED (in Verb.c), ACTION_ENABLED (in Actor.c) - HZONEF_NOWALK OBJECT_NOWALK - HZONEF_PROJECT OBJECT_PROJECT - HZONEF_AUTOWALK ACTION_AUTOWALK - HZONEF_TERMINUS ACTION_TERMINUS - - FrameRange.startFrame ACTORACTIONITEM.frame_index - FrameRange.frameCount ACTORACTIONITEM.frame_count - - FrameSequence.right ACTORACTION.dir[0] - FrameSequence.left ACTORACTION.dir[1] - FrameSequence.back ACTORACTION.dir[2] - FrameSequence.forward ACTORACTION.dir[3] - -Scene.c -======= - ResToImage() _vm->decodeBGImage() - resInfo->sceneFlags _desc.flags - resInfo->loadList _desc.resListRN - resInfo->horizon _desc.endSlope - resInfo->nearFigureLimit _desc.beginSlope - resInfo->scriptModule _desc.scriptModuleNumber - resInfo->entryScript _desc.sceneScriptEntrypointNumber - resInfo->preScript _desc.startScriptEntrypointNumber - resInfo->backgroundMusic _desc.musicRN - thisScene->ID currentSceneNumber() - -Interp.c -======== - dispatchThreads() executeThreads() - runThread() SThreadCompleteThread() - moduleList _scriptLUT - ModuleEntry->codeID _scriptLUT->script_rn - ModuleEntry->strID _scriptLUT->diag_list_rn - ModuleEntry->vtableID _scriptLUT->voice_lut_rn - threadBase.theAction threadVars[kVarAction] - threadBase.theObject threadVars[kVarObject] - threadBase.withObject threadVars[kVarWithObject] - threadBase.theActor threadVars[kVarActor] - -Actor.h -======= - GOF_PROTAGONIST kProtagonist - GOF_FOLLOWER kFollower - GOF_CYCLE kCycle - GOF_FASTER kFaster - GOF_FASTEST kFastest - GOF_EXTENDED kExtended - -Actor.c -======= - abortAllSpeeches() abortAllSpeeches() - -Main.c -====== - sceneIndexTable _scene->getSceneLUT() - -Main.h -====== -BRIGHT_WHITE kITEColorBrightWhite -WHITE_02 kITEColorWhite -GREY_0A kITEColorGrey -DK_GREY_0B kITEColorDarkGrey -PITCH_BLACK kITEColorBlack -RED_65 kITEColorRed -BLUE_93 kITEColorBlue -GREEB_BA kITEColorGreen - -Note that ScummVM's kITEColorLightGrey does not have any corresponding -constant in the original SAGA engine. We use it for the ITE mouse cursor. See -PtrData[] in Main.c and setCursor() in gfx.cpp - -Tile.h -====== - isoTile.height ISOTILE_ENTRY.tile_h - isoTile.attributes ISOTILE_ENTRY.mask_rule - isoTile.offset ISOTILE_ENTRY.tile_offset - isoTile.terrain_mask ISOTILE_ENTRY.terrain_mask - isoTile.fgd_bgd_attr ISOTILE_ENTRY.mask - - tilePlatform.metaTile ISO_METATILE_ENTRY.mtile_n - tilePlatform.height ISO_METATILE_ENTRY.height - tilePlatform.highestPixel ISO_METATILE_ENTRY.highest_pixel - tilePlatform.vBits ISO_METATILE_ENTRY.v_bits - tilePlatform.uBits ISO_METATILE_ENTRY.u_bits - -Resource.h -========== - PicHeader.width IMAGE_HEADER.width - PicHeader.height IMAGE_HEADER.height - - -Process.c -========= - mainPanelMode Interface::_inMainMode |