From 189e08bc7985fc5664e7ab95195bbade07488f48 Mon Sep 17 00:00:00 2001 From: Robert Göffringmann Date: Tue, 16 Dec 2003 02:10:15 +0000 Subject: Broken Sword 1: initial import svn-id: r11664 --- sword1/collision.h | 44 + sword1/debug.cpp | 114 + sword1/debug.h | 37 + sword1/eventman.cpp | 99 + sword1/eventman.h | 46 + sword1/logic.cpp | 1634 ++++++++++++++ sword1/logic.h | 198 ++ sword1/memman.cpp | 123 ++ sword1/memman.h | 58 + sword1/menu.cpp | 158 ++ sword1/menu.h | 80 + sword1/mouse.cpp | 230 ++ sword1/mouse.h | 99 + sword1/music.cpp | 129 ++ sword1/music.h | 59 + sword1/object.h | 125 ++ sword1/objectman.cpp | 133 ++ sword1/objectman.h | 57 + sword1/resman.cpp | 297 +++ sword1/resman.h | 80 + sword1/router.cpp | 1968 +++++++++++++++++ sword1/router.h | 161 ++ sword1/screen.cpp | 884 ++++++++ sword1/screen.h | 153 ++ sword1/sound.cpp | 214 ++ sword1/sound.h | 99 + sword1/staticres.cpp | 6022 ++++++++++++++++++++++++++++++++++++++++++++++++++ sword1/sword1.cpp | 293 +++ sword1/sword1.h | 93 + sword1/sworddefs.h | 1391 ++++++++++++ sword1/swordres.h | 5216 +++++++++++++++++++++++++++++++++++++++++++ sword1/text.cpp | 177 ++ sword1/text.h | 58 + 33 files changed, 20529 insertions(+) create mode 100644 sword1/collision.h create mode 100644 sword1/debug.cpp create mode 100644 sword1/debug.h create mode 100644 sword1/eventman.cpp create mode 100644 sword1/eventman.h create mode 100644 sword1/logic.cpp create mode 100644 sword1/logic.h create mode 100644 sword1/memman.cpp create mode 100644 sword1/memman.h create mode 100644 sword1/menu.cpp create mode 100644 sword1/menu.h create mode 100644 sword1/mouse.cpp create mode 100644 sword1/mouse.h create mode 100644 sword1/music.cpp create mode 100644 sword1/music.h create mode 100644 sword1/object.h create mode 100644 sword1/objectman.cpp create mode 100644 sword1/objectman.h create mode 100644 sword1/resman.cpp create mode 100644 sword1/resman.h create mode 100644 sword1/router.cpp create mode 100644 sword1/router.h create mode 100644 sword1/screen.cpp create mode 100644 sword1/screen.h create mode 100644 sword1/sound.cpp create mode 100644 sword1/sound.h create mode 100644 sword1/staticres.cpp create mode 100644 sword1/sword1.cpp create mode 100644 sword1/sword1.h create mode 100644 sword1/sworddefs.h create mode 100644 sword1/swordres.h create mode 100644 sword1/text.cpp create mode 100644 sword1/text.h (limited to 'sword1') diff --git a/sword1/collision.h b/sword1/collision.h new file mode 100644 index 0000000000..01f75caf46 --- /dev/null +++ b/sword1/collision.h @@ -0,0 +1,44 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#ifndef BSCOLLISION_H +#define BSCOLLISION_H + +/*#include "objectman.h" + +class SwordLogic; + +class SwordCollision { +public: + SwordCollision(ObjectMan *pObjMan, SwordLogic *pLogic); + ~SwordCollision(void); + void checkCollisions(void); + void fnBumpOff(void); + void fnBumpOn(void); +private: + int32 getIntersect(int32 x0, int32 y0, int32 x1, int32 y1, int32 x2, int32 y2, int32 x3, int32 y3); + int noCol; + ObjectMan *_objMan; + SwordLogic *_logic; // for CFN_preset_script +};*/ +// maybe it's better to make this part of SwordRouter + +#endif // BSCOLLISION_H diff --git a/sword1/debug.cpp b/sword1/debug.cpp new file mode 100644 index 0000000000..66b8dd927a --- /dev/null +++ b/sword1/debug.cpp @@ -0,0 +1,114 @@ +#include "stdafx.h" +#include "debug.h" +#include "common/util.h" + +void SwordDebug::interpretScript(uint32 id, uint32 level, uint32 script, uint32 pc) { + debug(8, "\nInterpreting %d@%d: script %X from %X", id, level, script, pc); +} + +void SwordDebug::callMCode(uint32 mcodeNum, uint32 paramCount, int32 a, int32 b, int32 c, int32 d, int32 e, int32 f) { + debug(9, "mcode: %s(%d, %d, %d, %d, %d, %d) [%d]", _mCodeNames[mcodeNum], a, b, c, d, e, f, paramCount); +} + +const char SwordDebug::_mCodeNames[100][35] = { + "fnBackground", + "fnForeground", + "fnSort", + "fnNoSprite", + "fnMegaSet", + "fnAnim", + "fnSetFrame", + "fnFullAnim", + "fnFullSetFrame", + "fnFadeDown", + "fnFadeUp", + "fnCheckFade", + "fnSetSpritePalette", + "fnSetWholePalette", + "fnSetFadeTargetPalette", + "fnSetPaletteToFade", + "fnSetPaletteToCut", + "fnPlaySequence", + "fnIdle", + "fnPause", + "fnPauseSeconds", + "fnQuit", + "fnKillId", + "fnSuicide", + "fnNewScript", + "fnSubScript", + "fnRestartScript", + "fnSetBookmark", + "fnGotoBookmark", + "fnSendSync", + "fnWaitSync", + "cfnClickInteract", + "cfnSetScript", + "cfnPresetScript", + "fnInteract", + "fnIssueEvent", + "fnCheckForEvent", + "fnWipeHands", + "fnISpeak", + "fnTheyDo", + "fnTheyDoWeWait", + "fnWeWait", + "fnChangeSpeechText", + "fnTalkError", + "fnStartTalk", + "fnCheckForTextLine", + "fnAddTalkWaitStatusBit", + "fnRemoveTalkWaitStatusBit", + "fnNoHuman", + "fnAddHuman", + "fnBlankMouse", + "fnNormalMouse", + "fnLockMouse", + "fnUnlockMouse", + "fnSetMousePointer", + "fnSetMouseLuggage", + "fnMouseOn", + "fnMouseOff", + "fnChooser", + "fnEndChooser", + "fnStartMenu", + "fnEndMenu", + "cfnReleaseMenu", + "fnAddSubject", + "fnAddObject", + "fnRemoveObject", + "fnEnterSection", + "fnLeaveSection", + "fnChangeFloor", + "fnWalk", + "fnTurn", + "fnStand", + "fnStandAt", + "fnFace", + "fnFaceXy", + "fnIsFacing", + "fnGetTo", + "fnGetToError", + "fnGetPos", + "fnGetGamepadXy", + "fnPlayFx", + "fnStopFx", + "fnPlayMusic", + "fnStopMusic", + "fnInnerSpace", + "fnRandom", + "fnSetScreen", + "fnPreload", + "fnCheckCD", + "fnRestartGame", + "fnQuitGame", + "fnDeathScreen", + "fnSetParallax", + "fnTdebug", + "fnRedFlash", + "fnBlueFlash", + "fnYellow", + "fnGreen", + "fnPurple", + "fnBlack" +}; \ No newline at end of file diff --git a/sword1/debug.h b/sword1/debug.h new file mode 100644 index 0000000000..ee902d83b3 --- /dev/null +++ b/sword1/debug.h @@ -0,0 +1,37 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#ifndef BSDEBUG_H +#define BSDEBUG_H + +#include "scummsys.h" + +class SwordDebug { +public: + static void interpretScript(uint32 id, uint32 level, uint32 script, uint32 pc); + static void callMCode(uint32 mcodeNum, uint32 paramCount, int32 a, int32 b, int32 c, int32 d, int32 e, int32 f); + +private: + static const char _mCodeNames[100][35]; +}; + +#endif // BSDEBUG_H + diff --git a/sword1/eventman.cpp b/sword1/eventman.cpp new file mode 100644 index 0000000000..8f7692d93e --- /dev/null +++ b/sword1/eventman.cpp @@ -0,0 +1,99 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#include "stdafx.h" +#include "eventman.h" +#include "sworddefs.h" +#include "common/util.h" + +EventManager::EventManager(void) { + for (uint8 cnt = 0; cnt < TOTAL_EVENT_SLOTS; cnt++) + _eventPendingList[cnt].delay = _eventPendingList[cnt].eventNumber = 0; +} + +void EventManager::serviceGlobalEventList(void) { + for (uint8 slot = 0; slot < TOTAL_EVENT_SLOTS; slot++) + if (_eventPendingList[slot].delay) + _eventPendingList[slot].delay--; +} + +void EventManager::checkForEvent(BsObject *compact) { + for (uint8 objCnt = 0; objCnt < O_TOTAL_EVENTS; objCnt++) { + if (compact->o_event_list[objCnt].o_event) + for (uint8 globCnt = 0; globCnt < TOTAL_EVENT_SLOTS; globCnt++) { + if (_eventPendingList[globCnt].delay && + (_eventPendingList[globCnt].eventNumber == compact->o_event_list[objCnt].o_event)) { + compact->o_logic = LOGIC_script; //force into script mode + _eventPendingList[globCnt].delay = 0; //started, so remove from queue + compact->o_tree.o_script_level++; + compact->o_tree.o_script_id[compact->o_tree.o_script_level] = + compact->o_event_list[objCnt].o_event_script; + compact->o_tree.o_script_pc[compact->o_tree.o_script_level] = + compact->o_event_list[objCnt].o_event_script; + } + } + } +} + +bool EventManager::eventValid(int32 event) { + for (uint8 slot = 0; slot < TOTAL_EVENT_SLOTS; slot++) + if ((_eventPendingList[slot].eventNumber == event) && + (_eventPendingList[slot].delay)) + return true; + return false; +} + +int EventManager::fnCheckForEvent(BsObject *cpt, int32 id, int32 pause) { + if (pause) { + cpt->o_pause = pause; + cpt->o_logic = LOGIC_pause_for_event; + return SCRIPT_STOP; + } + + for (uint8 objCnt = 0; objCnt < O_TOTAL_EVENTS; objCnt++) { + if (cpt->o_event_list[objCnt].o_event) + for (uint8 globCnt = 0; globCnt < TOTAL_EVENT_SLOTS; globCnt++) { + if (_eventPendingList[globCnt].delay && + (_eventPendingList[globCnt].eventNumber == cpt->o_event_list[objCnt].o_event)) { + cpt->o_logic = LOGIC_script; //force into script mode + _eventPendingList[globCnt].delay = 0; //started, so remove from queue + cpt->o_tree.o_script_level++; + cpt->o_tree.o_script_id[cpt->o_tree.o_script_level] = + cpt->o_event_list[objCnt].o_event_script; + cpt->o_tree.o_script_pc[cpt->o_tree.o_script_level] = + cpt->o_event_list[objCnt].o_event_script; + return SCRIPT_STOP; + } + } + } + return SCRIPT_CONT; +} + +void EventManager::fnIssueEvent(BsObject *compact, int32 id, int32 event, int32 delay) { + uint8 evSlot = 0; + while (_eventPendingList[evSlot].delay) + evSlot++; + if (evSlot >= TOTAL_EVENT_SLOTS) + error("EventManager ran out of event slots!"); + _eventPendingList[evSlot].delay = delay; + _eventPendingList[evSlot].eventNumber = event; +} + diff --git a/sword1/eventman.h b/sword1/eventman.h new file mode 100644 index 0000000000..bcd3b48d24 --- /dev/null +++ b/sword1/eventman.h @@ -0,0 +1,46 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#ifndef BSEVENTMAN_H +#define BSEVENTMAN_H + +#include "object.h" + +#define TOTAL_EVENT_SLOTS 20 + +struct GlobalEvent { + int32 eventNumber; + int32 delay; +}; + +class EventManager { +public: + EventManager(void); + void serviceGlobalEventList(void); + void checkForEvent(BsObject *compact); + int fnCheckForEvent(BsObject *cpt, int32 id, int32 pause); + void fnIssueEvent(BsObject *compact, int32 id, int32 event, int32 delay); + bool eventValid(int32 event); +private: + GlobalEvent _eventPendingList[TOTAL_EVENT_SLOTS]; +}; + +#endif // BSEVENTMAN_H diff --git a/sword1/logic.cpp b/sword1/logic.cpp new file mode 100644 index 0000000000..ddc8a224ff --- /dev/null +++ b/sword1/logic.cpp @@ -0,0 +1,1634 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#include "stdafx.h" +#include "logic.h" +#include "text.h" +#include "sound.h" +#include "eventman.h" +#include "menu.h" +#include "common/util.h" +#include "router.h" +#include "screen.h" +#include "mouse.h" +#include "sword1.h" +#include "music.h" + +#include "debug.h" + +#define MAX_STACK_SIZE 10 +#define SCRIPT_VERSION 13 +#define LAST_FRAME 999 + +uint32 SwordLogic::_scriptVars[NUM_SCRIPT_VARS]; + +SwordLogic::SwordLogic(ObjectMan *pObjMan, ResMan *resMan, SwordScreen *pScreen, SwordMouse *pMouse, SwordSound *pSound, SwordMusic *pMusic, SwordMenu *pMenu) { + _objMan = pObjMan; + _resMan = resMan; + _screen = pScreen; + _mouse = pMouse; + _music = pMusic; + _sound = pSound; + _menu = pMenu; + _textMan = new SwordText(_objMan, _resMan, false); + _screen->useTextManager(_textMan); + _router = new SwordRouter(_objMan, _resMan); + + //_collision = new SwordCollision(_objMan, this); + _eventMan = new EventManager(); + + memset(_scriptVars, 0, NUM_SCRIPT_VARS * sizeof(uint32)); + for (uint8 cnt = 0; cnt < NON_ZERO_SCRIPT_VARS; cnt++) + _scriptVars[_scriptVarInit[cnt][0]] = _scriptVarInit[cnt][1]; + + _textRunning = _speechRunning = false; + _speechFinished = true; +} + +void SwordLogic::newScreen(uint32 newScreen) { + BsObject *compact = (BsObject*)_objMan->fetchObject(PLAYER); + + //Tdebug("locked player"); + + if (SwordEngine::_systemVars.justRestoredGame) // if we've just restored a game - we want George to be exactly as saved + { + if (_scriptVars[GEORGE_WALKING]) // except that if George was walking when we saveed the game + { + fnStandAt(compact, PLAYER, _scriptVars[CHANGE_X], _scriptVars[CHANGE_Y], _scriptVars[CHANGE_DIR], _scriptVars[CHANGE_STANCE], 0,0); + fnIdle(compact,PLAYER,0,0,0,0,0,0); + _scriptVars[GEORGE_WALKING] = 0; + } + + SwordEngine::_systemVars.justRestoredGame = 0; + } + else // if we haven't just restored a game, set George to stand, etc + { + compact->o_screen = _scriptVars[NEW_SCREEN]; //move the mega/player at this point between screens + //Tdebug("FN_stand_at..."); + fnStandAt(compact, PLAYER, _scriptVars[CHANGE_X], _scriptVars[CHANGE_Y], _scriptVars[CHANGE_DIR], _scriptVars[CHANGE_STANCE], 0,0); + //Tdebug("FN_change_floor..."); + fnChangeFloor(compact, PLAYER, _scriptVars[CHANGE_PLACE], 0, 0, 0, 0, 0); + //Tdebug("done"); + } +} + +void SwordLogic::engine(void) { + _eventMan->serviceGlobalEventList(); + + for (uint16 sectCnt = 0; sectCnt < TOTAL_SECTIONS; sectCnt++) { + if (_objMan->sectionAlive(sectCnt)) { + uint32 numCpts = _objMan->fetchNoObjects(sectCnt); + for (uint32 cptCnt = 0; cptCnt < numCpts; cptCnt++) { + uint32 currentId = sectCnt * ITM_PER_SEC + cptCnt; + BsObject *compact = _objMan->fetchObject(currentId); + + if (compact->o_status & STAT_LOGIC) { // does the object want to be processed? + if (compact->o_status & STAT_EVENTS) { + //subscribed to the global-event-switcher? and in logic mode + switch(compact->o_logic) { + case LOGIC_pause_for_event: + case LOGIC_idle: + case LOGIC_AR_animate: + _eventMan->checkForEvent(compact); + break; + } + } + debug(7, "SwordLogic::engine: handling compact %d (%X)", currentId, currentId); + processLogic(compact, currentId); + compact->o_sync = 0; // syncs are only available for 1 cycle. + } + + if (compact->o_screen == _scriptVars[SCREEN]) { + if (compact->o_status & STAT_FORE) + _screen->addToGraphicList(0, currentId); + if (compact->o_status & STAT_SORT) + _screen->addToGraphicList(1, currentId); + if (compact->o_status & STAT_BACK) + _screen->addToGraphicList(2, currentId); + + if (compact->o_status & STAT_MOUSE) + _mouse->addToList(currentId, compact); + } + } + } + } + //_collision->checkCollisions(); + +} + +void SwordLogic::processLogic(BsObject *compact, uint32 id) { + int logicRet; + do { + switch(compact->o_logic) { + case LOGIC_idle: + logicRet = 0; + break; + case LOGIC_pause: + case LOGIC_pause_for_event: + if (compact->o_pause) { + compact->o_pause--; + logicRet = 0; + } else { + compact->o_logic = LOGIC_script; + logicRet = 1; + } + break; + case LOGIC_quit: + compact->o_logic = LOGIC_script; + logicRet = 0; + break; + case LOGIC_wait_for_sync: + if (compact->o_sync) { + logicRet = 1; + compact->o_logic = LOGIC_script; + } else + logicRet = 0; + break; + case LOGIC_choose: + _scriptVars[CUR_ID] = id; + logicRet = _menu->logicChooser(compact); + break; + case LOGIC_wait_for_talk: + logicRet = logicWaitTalk(compact); + break; + case LOGIC_start_talk: + logicRet = logicStartTalk(compact); + case LOGIC_script: + _scriptVars[CUR_ID] = id; + logicRet = scriptManager(compact, id); + break; + case LOGIC_new_script: + compact->o_tree.o_script_pc[compact->o_tree.o_script_level] = _newScript; + compact->o_tree.o_script_id[compact->o_tree.o_script_level] = _newScript; + compact->o_logic = LOGIC_script; + logicRet = 1; + break; + case LOGIC_AR_animate: + logicRet = logicArAnimate(compact, id); + break; + case LOGIC_restart: + compact->o_tree.o_script_pc[compact->o_tree.o_script_level] = compact->o_tree.o_script_id[compact->o_tree.o_script_level]; + compact->o_logic = LOGIC_script; + logicRet=1; + break; + case LOGIC_bookmark: + memcpy(&(compact->o_tree.o_script_level), &(compact->o_bookmark.o_script_level), sizeof(ScriptTree)); + compact->o_logic = LOGIC_script; + logicRet = 1; + break; + case LOGIC_speech: + logicRet = speechDriver(compact); + break; + case LOGIC_full_anim: + logicRet = fullAnimDriver(compact); + break; + case LOGIC_anim: + logicRet = animDriver(compact); + break; + + default: + error("Fatal error: compact %d's logic == %X!", id, compact->o_logic); + break; + } + } while(logicRet); +} + +int SwordLogic::logicWaitTalk(BsObject *compact) { + BsObject *target = _objMan->fetchObject(compact->o_target); + + if (target->o_status & STAT_TALK_WAIT) { + compact->o_logic = LOGIC_script; + return 1; + } else { + return 0; + } +} + +int SwordLogic::logicStartTalk(BsObject *compact) { + BsObject *target = _objMan->fetchObject(compact->o_down_flag); //holds id of person we're waiting for + if (target->o_status & STAT_TALK_WAIT) { //response? + compact->o_logic = LOGIC_script; //back to script again + return SCRIPT_CONT; + } + if (_eventMan->eventValid(compact->o_down_flag)) + return SCRIPT_STOP; //event still valid - keep waiting + //the event has gone - so back to script with error code + compact->o_down_flag = 0; + compact->o_logic = LOGIC_script; + return SCRIPT_CONT; +} + +int SwordLogic::logicArAnimate(BsObject *compact, uint32 id) { + WalkData *route; + int32 walkPc; + if ((_scriptVars[GEORGE_WALKING] == 0) && (id == PLAYER)) + _scriptVars[GEORGE_WALKING] = 1; + + compact->o_resource = compact->o_walk_resource; + compact->o_status |= STAT_SHRINK; + route = compact->o_route; + + walkPc =compact->o_walk_pc; + compact->o_frame =route[walkPc].frame; + compact->o_dir =route[walkPc].dir; + compact->o_xcoord =route[walkPc].x; + compact->o_ycoord =route[walkPc].y; + compact->o_anim_x =compact->o_xcoord; + compact->o_anim_y =compact->o_ycoord; + + if (((_scriptVars[GEORGE_WALKING] == 2) && (walkPc > 5) && (id == PLAYER) && + (route[walkPc - 1].step == 5) && (route[walkPc].step == 0)) || + ((_scriptVars[GEORGE_WALKING] == 3) && (id == PLAYER))) { + + compact->o_frame = 96 + compact->o_dir; //reset + if ((compact->o_dir != 2) && (compact->o_dir != 6)) { // on verticals and diagonals stand where george is + compact->o_xcoord = route[walkPc - 1].x; + compact->o_ycoord = route[walkPc - 1].y; + compact->o_anim_x = compact->o_xcoord; + compact->o_anim_y = compact->o_ycoord; + } + compact->o_logic = LOGIC_script; + compact->o_down_flag = 0; //0 means error + _scriptVars[GEORGE_WALKING] = 0; + route[compact->o_walk_pc+1].frame = 512; //end of sequence + if (_scriptVars[MEGA_ON_GRID] == 2) + _scriptVars[MEGA_ON_GRID] = 0; + } + compact->o_walk_pc++; + + if (route[compact->o_walk_pc].frame == 512) //end of sequence + { + compact->o_logic = LOGIC_script; + if (((_scriptVars[GEORGE_WALKING] == 2) || (_scriptVars[GEORGE_WALKING] == 1)) && + (id == PLAYER)) { + _scriptVars[GEORGE_WALKING] = 0; + if (_scriptVars[MEGA_ON_GRID] == 2) + _scriptVars[MEGA_ON_GRID] = 0; + } + } + return 0; +} + +int SwordLogic::speechDriver(BsObject *compact) { + if ((!_speechClickDelay) && (_mouse->testEvent() & BS1L_BUTTON_DOWN)) + _speechFinished = true; + if (_speechClickDelay) + _speechClickDelay--; + + if (_speechRunning) { + if (_sound->speechFinished()) + _speechFinished = true; + } else { + if (!compact->o_speech_time) + _speechFinished = true; + else + compact->o_speech_time--; + } + if (_speechFinished) { + if (_speechRunning) + _sound->stopSpeech(); + compact->o_logic = LOGIC_script; + if (_textRunning) { + _textMan->releaseText(compact->o_text_id); + _objMan->fetchObject(compact->o_text_id)->o_status = 0; // kill compact linking text sprite + } + _speechRunning = _textRunning = false; + _speechFinished = true; + } + if (compact->o_anim_resource) { + uint8 *animData = ((uint8*)_resMan->openFetchRes(compact->o_anim_resource)) + sizeof(Header); + int32 numFrames = READ_LE_UINT32(animData); + animData += 4; + + if (_speechFinished || (compact->o_anim_pc >= numFrames) || + (_speechRunning && (_sound->amISpeaking() == 0))) + compact->o_anim_pc = 0; + + AnimUnit *animPtr = (AnimUnit*)(animData + sizeof(AnimUnit) * compact->o_anim_pc); + if (!(compact->o_status & STAT_SHRINK)) { + compact->o_anim_x = FROM_LE_32(animPtr->animX); + compact->o_anim_y = FROM_LE_32(animPtr->animY); + } + compact->o_frame = FROM_LE_32(animPtr->animFrame); + _resMan->resClose(compact->o_anim_resource); + } + return 0; +} + +int SwordLogic::fullAnimDriver(BsObject *compact) { + if (compact->o_sync) { // return to script immediately if we've received a sync + compact->o_logic = LOGIC_script; + return 1; + } + uint8 *data = ((uint8*)_resMan->openFetchRes(compact->o_anim_resource)) + sizeof(Header); + uint16 numFrames = READ_LE_UINT32(data); + data += 4; + AnimUnit *animPtr = (AnimUnit*)(data + compact->o_anim_pc * sizeof(AnimUnit)); + + compact->o_anim_x = compact->o_xcoord = FROM_LE_32(animPtr->animX); + compact->o_anim_y = compact->o_ycoord = FROM_LE_32(animPtr->animY); + compact->o_frame = FROM_LE_32(animPtr->animFrame); + + compact->o_anim_pc++; + if (compact->o_anim_pc == numFrames) + compact->o_logic = LOGIC_script; + + _resMan->resClose(compact->o_anim_resource); + return 0; +} + +int SwordLogic::animDriver(BsObject *compact) { + if (compact->o_sync) { + compact->o_logic = LOGIC_script; + return 1; + } + uint8 *data = ((uint8*)_resMan->openFetchRes(compact->o_anim_resource)) + sizeof(Header); + uint16 numFrames = READ_LE_UINT32(data); + AnimUnit *animPtr = (AnimUnit*)(data + 4 + compact->o_anim_pc * sizeof(AnimUnit)); + + if (!(compact->o_status & STAT_SHRINK)) { + compact->o_anim_x = animPtr->animX; + compact->o_anim_y = animPtr->animY; + } + + compact->o_frame = animPtr->animFrame; + compact->o_anim_pc++; + if (compact->o_anim_pc == numFrames) + compact->o_logic = LOGIC_script; + + _resMan->resClose(compact->o_anim_resource); + return 0; +} + +void SwordLogic::updateScreenParams(void) { + BsObject *compact = (BsObject*)_objMan->fetchObject(PLAYER); + _screen->setScrolling((int16)(compact->o_xcoord - _scriptVars[FEET_X]), + (int16)(compact->o_ycoord - _scriptVars[FEET_Y])); +} + +int SwordLogic::scriptManager(BsObject *compact, uint32 id) { + int ret; + do { + uint32 level = compact->o_tree.o_script_level; + uint32 script = compact->o_tree.o_script_id[level]; + SwordDebug::interpretScript(id, level, script, compact->o_tree.o_script_pc[level] & ITM_ID); + ret = interpretScript(compact, id, _resMan->lockScript(script), script, compact->o_tree.o_script_pc[level] & ITM_ID); + _resMan->unlockScript(script); + if (!ret) { + if (compact->o_tree.o_script_level) + compact->o_tree.o_script_level--; + else + error("ScriptManager: basescript %d for cpt %d ended!", script, id); + } else + compact->o_tree.o_script_pc[level] = ret; + } while (!ret); + return 1; + //Logic continues - but the script must have changed logic mode + //this is a radical change from S2.0 where once a script finished there + //was no more processing for that object on that cycle - the Logic_engine terminated. + //This meant that new logics that needed immediate action got a first call from the + //setup function. This was a bit tweeky. This technique ensures that the script is a + //totally seamless concept that takes up zero cycle time. The only downside is that + //an FN_quit becomes slightly more convoluted, but so what you might ask. +} + +void SwordLogic::runMouseScript(BsObject *cpt, int32 scriptId) { + Header *script = _resMan->lockScript(scriptId); + debug(9, "running mouse script %d", scriptId); + interpretScript(cpt, _scriptVars[SPECIAL_ITEM], script, scriptId, scriptId); + _resMan->unlockScript(scriptId); +} + +int SwordLogic::interpretScript(BsObject *compact, int id, Header *scriptModule, int scriptBase, int scriptNum) { + int32 *scriptCode = (int32*)(((uint8*)scriptModule) + sizeof(Header)); + int32 stack[MAX_STACK_SIZE]; + int32 stackIdx = 0; + int32 offset; + int32 pc; + if (memcmp(scriptModule->type, "Script", 6)) + error("Invalid script module!"); + if (scriptModule->version != SCRIPT_VERSION) + error("Illegal script version!"); + if (scriptNum < 0) + error("negative script number"); + if ((uint32)scriptNum >= scriptModule->decomp_length) + error("Script number out of bounds"); + + if (scriptNum < scriptCode[0]) + pc = scriptCode[scriptNum + 1]; + else + pc = scriptNum; + int32 startOfScript = scriptCode[(scriptBase & ITM_ID) + 1]; + + int32 a, b, c, d, e, f; + int mCodeReturn = 0; + int32 mCodeNumber = 0, mCodeArguments = 0; + while (1) { + assert((stackIdx >= 0) && (stackIdx <= MAX_STACK_SIZE)); + switch (scriptCode[pc++]) { + case IT_MCODE: + a = b = c = d = e = f = 0; + mCodeNumber = scriptCode[pc++]; + mCodeArguments = scriptCode[pc++]; + switch (mCodeArguments) { + case 6: f = stack[--stackIdx]; + case 5: e = stack[--stackIdx]; + case 4: d = stack[--stackIdx]; + case 3: c = stack[--stackIdx]; + case 2: b = stack[--stackIdx]; + case 1: a = stack[--stackIdx]; + case 0: + SwordDebug::callMCode(mCodeNumber, mCodeArguments, a, b, c, d, e, f); + mCodeReturn = (this->*_mcodeTable[mCodeNumber])(compact, id, a, b, c, d, e, f); + break; + default: + warning("mcode[%d]: too many arguments(%d)", mCodeNumber, mCodeArguments); + } + if (mCodeReturn == 0) + return pc; + break; + case IT_PUSHNUMBER: + debug(9, "IT_PUSH: %d", scriptCode[pc]); + stack[stackIdx++] = scriptCode[pc++]; + break; + case IT_PUSHVARIABLE: + debug(9, "IT_PUSHVARIABLE: ScriptVar[%d] => %d", scriptCode[pc], _scriptVars[scriptCode[pc]]); + stack[stackIdx++] = _scriptVars[scriptCode[pc++]]; + break; + case IT_NOTEQUAL: + stackIdx--; + debug(9, "IT_NOTEQUAL: RESULT = %d", stack[stackIdx - 1] != stack[stackIdx]); + stack[stackIdx - 1] = (stack[stackIdx - 1] != stack[stackIdx]); + break; + case IT_ISEQUAL: + stackIdx--; + debug(9, "IT_ISEQUAL: RESULT = %d", stack[stackIdx - 1] == stack[stackIdx]); + stack[stackIdx - 1] = (stack[stackIdx - 1] == stack[stackIdx]); + break; + case IT_PLUS: + stackIdx--; + debug(9, "IT_PLUS: RESULT = %d", stack[stackIdx - 1] + stack[stackIdx]); + stack[stackIdx - 1] = (stack[stackIdx - 1] + stack[stackIdx]); + break; + case IT_TIMES: + stackIdx--; + debug(9, "IT_TIMES: RESULT = %d", stack[stackIdx - 1] * stack[stackIdx]); + stack[stackIdx - 1] = (stack[stackIdx - 1] * stack[stackIdx]); + break; + case IT_ANDAND: + stackIdx--; + debug(9, "IT_ANDAND: RESULT = %d", stack[stackIdx - 1] && stack[stackIdx]); + stack[stackIdx - 1] = (stack[stackIdx - 1] && stack[stackIdx]); + break; + case IT_OROR: // || + stackIdx--; + debug(9, "IT_OROR: RESULT = %d", stack[stackIdx - 1] || stack[stackIdx]); + stack[stackIdx - 1] = (stack[stackIdx - 1] || stack[stackIdx]); + break; + case IT_LESSTHAN: + stackIdx--; + debug(9, "IT_LESSTHAN: RESULT = %d", stack[stackIdx - 1] < stack[stackIdx]); + stack[stackIdx - 1] = (stack[stackIdx - 1] < stack[stackIdx]); + break; + case IT_NOT: + debug(9, "IT_NOT: RESULT = %d", stack[stackIdx - 1] ? 0 : 1); + if (stack[stackIdx - 1]) + stack[stackIdx - 1] = 0; + else + stack[stackIdx - 1] = 1; + break; + case IT_MINUS: + stackIdx--; + debug(9, "IT_MINUS: RESULT = %d", stack[stackIdx - 1] - stack[stackIdx]); + stack[stackIdx - 1] = (stack[stackIdx - 1] - stack[stackIdx]); + break; + case IT_AND: + stackIdx--; + debug(9, "IT_AND: RESULT = %d", stack[stackIdx - 1] & stack[stackIdx]); + stack[stackIdx - 1] = (stack[stackIdx - 1] & stack[stackIdx]); + break; + case IT_OR: + stackIdx--; + debug(9, "IT_OR: RESULT = %d", stack[stackIdx - 1] | stack[stackIdx]); + stack[stackIdx - 1] = (stack[stackIdx - 1] | stack[stackIdx]); + break; + case IT_GTE: + stackIdx--; + debug(9, "IT_GTE: RESULT = %d", stack[stackIdx - 1] >= stack[stackIdx]); + stack[stackIdx - 1] = (stack[stackIdx - 1] >= stack[stackIdx]); + break; + case IT_LTE: + stackIdx--; + debug(9, "IT_LTE: RESULT = %d", stack[stackIdx - 1] <= stack[stackIdx]); + stack[stackIdx - 1] = (stack[stackIdx - 1] <= stack[stackIdx]); + break; + case IT_DEVIDE: + stackIdx--; + debug(9, "IT_DEVIDE: RESULT = %d", stack[stackIdx - 1] / stack[stackIdx]); + stack[stackIdx - 1] = (stack[stackIdx - 1] / stack[stackIdx]); + break; + case IT_GT: + stackIdx--; + debug(9, "IT_GT: RESULT = %d", stack[stackIdx - 1] > stack[stackIdx]); + stack[stackIdx - 1] = (stack[stackIdx - 1] > stack[stackIdx]); + break; + case IT_SCRIPTEND: + debug(9, "IT_SCRIPTEND"); + return 0; + case IT_POPVAR: // pop a variable + debug(9, "IT_POPVAR: ScriptVars[%d] = %d", scriptCode[pc], stack[stackIdx-1]); + _scriptVars[scriptCode[pc++]] = stack[--stackIdx]; + break; + case IT_POPLONGOFFSET: + offset = scriptCode[pc++]; + debug(9, "IT_POPLONGOFFSET: Cpt[%d] = %d", offset, stack[stackIdx - 1]); + *((int32 *)((uint8*)compact + offset)) = stack[--stackIdx]; + break; + case IT_PUSHLONGOFFSET: + offset = scriptCode[pc++]; + debug(9, "IT_PUSHLONGOFFSET: PUSH Cpt[%d] (==%d)", offset, *((int32 *)((uint8*)compact + offset))); + stack[stackIdx++] = *((int32 *)((uint8*)compact + offset)); + break; + case IT_SKIPONFALSE: + debug(9, "IT_SKIPONFALSE: %d (%s)", scriptCode[pc], (stack[stackIdx-1] ? "IS TRUE (NOT SKIPPED)" : "IS FALSE (SKIPPED)")); + if (stack[--stackIdx]) + pc++; + else + pc += scriptCode[pc]; + break; + case IT_SKIP: + debug(9, "IT_SKIP: %d", scriptCode[pc]); + pc += scriptCode[pc]; + break; + case IT_SWITCH: // The mega switch statement + debug(9, "IT_SWITCH: [SORRY, NO DEBUG INFO]"); + { + int switchValue = stack[--stackIdx]; + int switchCount = scriptCode[pc++]; + int doneSwitch=0; + + for (int cnt = 0; (cnt < switchCount) && (doneSwitch==0); cnt++) { + if (switchValue == scriptCode[pc]) { + pc += scriptCode[pc+1]; + doneSwitch=1; + } else + pc += 2; + + } + if (doneSwitch == 0) + pc += scriptCode[pc]; + } + break; + case IT_SKIPONTRUE: // skip if expression true + debug(9, "IT_SKIPONFALSE: %d (%s)", scriptCode[pc], (stack[stackIdx-1] ? "IS TRUE (SKIPPED)" : "IS FALSE (NOT SKIPPED)")); + stackIdx--; + if (stack[stackIdx]) + pc += scriptCode[pc]; + else + pc++; + break; + case IT_PRINTF: + debug(0, "IT_PRINTF(%d)",stack[stackIdx]); + break; + case IT_RESTARTSCRIPT: + debug(9, "IT_RESTARTSCRIPT"); + pc = startOfScript; + break; + case IT_POPWORDOFFSET: + offset = scriptCode[pc++]; + debug(9, "IT_POPWORDOFFSET: Cpt[%d] = %d", offset, stack[stackIdx - 1] & 0xFFFF); + *((int32 *)((uint8*)compact + offset)) = stack[--stackIdx] & 0xffff; + break; + case IT_PUSHWORDOFFSET: + offset = scriptCode[pc++]; + debug(9, "IT_PUSHWORDOFFSET: PUSH Cpt[%d] == %d", offset, (*((int32 *)((uint8*)compact + offset))) & 0xffff); + stack[stackIdx++] = (*((int32 *)((uint8*)compact + offset))) & 0xffff; + break; + default: + error("Invalid operator %d",scriptCode[pc-1]); + return 0; + } + } +} + +BSMcodeTable SwordLogic::_mcodeTable[100] = { + &SwordLogic::fnBackground, + &SwordLogic::fnForeground, + &SwordLogic::fnSort, + &SwordLogic::fnNoSprite, + &SwordLogic::fnMegaSet, + &SwordLogic::fnAnim, + &SwordLogic::fnSetFrame, + &SwordLogic::fnFullAnim, + &SwordLogic::fnFullSetFrame, + &SwordLogic::fnFadeDown, + &SwordLogic::fnFadeUp, + &SwordLogic::fnCheckFade, + &SwordLogic::fnSetSpritePalette, + &SwordLogic::fnSetWholePalette, + &SwordLogic::fnSetFadeTargetPalette, + &SwordLogic::fnSetPaletteToFade, + &SwordLogic::fnSetPaletteToCut, + &SwordLogic::fnPlaySequence, + &SwordLogic::fnIdle, + &SwordLogic::fnPause, + &SwordLogic::fnPauseSeconds, + &SwordLogic::fnQuit, + &SwordLogic::fnKillId, + &SwordLogic::fnSuicide, + &SwordLogic::fnNewScript, + &SwordLogic::fnSubScript, + &SwordLogic::fnRestartScript, + &SwordLogic::fnSetBookmark, + &SwordLogic::fnGotoBookmark, + &SwordLogic::fnSendSync, + &SwordLogic::fnWaitSync, + &SwordLogic::cfnClickInteract, + &SwordLogic::cfnSetScript, + &SwordLogic::cfnPresetScript, + &SwordLogic::fnInteract, + &SwordLogic::fnIssueEvent, + &SwordLogic::fnCheckForEvent, + &SwordLogic::fnWipeHands, + &SwordLogic::fnISpeak, + &SwordLogic::fnTheyDo, + &SwordLogic::fnTheyDoWeWait, + &SwordLogic::fnWeWait, + &SwordLogic::fnChangeSpeechText, + &SwordLogic::fnTalkError, + &SwordLogic::fnStartTalk, + &SwordLogic::fnCheckForTextLine, + &SwordLogic::fnAddTalkWaitStatusBit, + &SwordLogic::fnRemoveTalkWaitStatusBit, + &SwordLogic::fnNoHuman, + &SwordLogic::fnAddHuman, + &SwordLogic::fnBlankMouse, + &SwordLogic::fnNormalMouse, + &SwordLogic::fnLockMouse, + &SwordLogic::fnUnlockMouse, + &SwordLogic::fnSetMousePointer, + &SwordLogic::fnSetMouseLuggage, + &SwordLogic::fnMouseOn, + &SwordLogic::fnMouseOff, + &SwordLogic::fnChooser, + &SwordLogic::fnEndChooser, + &SwordLogic::fnStartMenu, + &SwordLogic::fnEndMenu, + &SwordLogic::cfnReleaseMenu, + &SwordLogic::fnAddSubject, + &SwordLogic::fnAddObject, + &SwordLogic::fnRemoveObject, + &SwordLogic::fnEnterSection, + &SwordLogic::fnLeaveSection, + &SwordLogic::fnChangeFloor, + &SwordLogic::fnWalk, + &SwordLogic::fnTurn, + &SwordLogic::fnStand, + &SwordLogic::fnStandAt, + &SwordLogic::fnFace, + &SwordLogic::fnFaceXy, + &SwordLogic::fnIsFacing, + &SwordLogic::fnGetTo, + &SwordLogic::fnGetToError, + &SwordLogic::fnGetPos, + &SwordLogic::fnGetGamepadXy, + &SwordLogic::fnPlayFx, + &SwordLogic::fnStopFx, + &SwordLogic::fnPlayMusic, + &SwordLogic::fnStopMusic, + &SwordLogic::fnInnerSpace, + &SwordLogic::fnRandom, + &SwordLogic::fnSetScreen, + &SwordLogic::fnPreload, + &SwordLogic::fnCheckCD, + &SwordLogic::fnRestartGame, + &SwordLogic::fnQuitGame, + &SwordLogic::fnDeathScreen, + &SwordLogic::fnSetParallax, + &SwordLogic::fnTdebug, + &SwordLogic::fnRedFlash, + &SwordLogic::fnBlueFlash, + &SwordLogic::fnYellow, + &SwordLogic::fnGreen, + &SwordLogic::fnPurple, + &SwordLogic::fnBlack +}; + +int SwordLogic::fnBackground(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + + cpt->o_status &= ~(STAT_FORE | STAT_SORT); + cpt->o_status |= STAT_BACK; + return SCRIPT_CONT; +} + +int SwordLogic::fnForeground(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + cpt->o_status &= ~(STAT_BACK | STAT_SORT); + cpt->o_status |= STAT_FORE; + return SCRIPT_CONT; +} + +int SwordLogic::fnSort(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + cpt->o_status &= ~(STAT_BACK | STAT_FORE); + cpt->o_status |= STAT_SORT; + return SCRIPT_CONT; +} + +int SwordLogic::fnNoSprite(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + cpt->o_status &= ~(STAT_BACK | STAT_FORE | STAT_SORT); + return SCRIPT_CONT; +} + +int SwordLogic::fnMegaSet(BsObject *cpt, int32 id, int32 walk_data, int32 spr, int32 e, int32 f, int32 z, int32 x) { + cpt->o_mega_resource = walk_data; + cpt->o_walk_resource = spr; + return SCRIPT_CONT; +} + +int SwordLogic::fnAnim(BsObject *cpt, int32 id, int32 cdt, int32 spr, int32 e, int32 f, int32 z, int32 x) { + AnimSet *animTab; + + if (cdt && (!spr)) { + animTab = (AnimSet*)((uint8*)_resMan->openFetchRes(cdt) + sizeof(Header)); + animTab += cpt->o_dir; + + cpt->o_anim_resource = FROM_LE_32(animTab->cdt); + cpt->o_resource = FROM_LE_32(animTab->spr); + _resMan->resClose(cdt); + } else { + cpt->o_anim_resource = cdt; + cpt->o_resource = spr; + } + if ((cpt->o_anim_resource == 0) || (cpt->o_resource == 0)) + error("fnAnim called width (%d/%d) => (%d/%d)", cdt, spr, cpt->o_anim_resource, cpt->o_resource); + + FrameHeader *frameHead = _resMan->fetchFrame(_resMan->openFetchRes(cpt->o_resource), 0); + if (frameHead->offsetX || frameHead->offsetY) { // boxed mega anim? + cpt->o_status |= STAT_SHRINK; + cpt->o_anim_x = cpt->o_xcoord; // set anim coords to 'feet' coords - only need to do this once + cpt->o_anim_y = cpt->o_ycoord; + } else { + // Anim_driver sets anim coords to cdt coords for every frame of a loose anim + cpt->o_status &= ~STAT_SHRINK; + } + _resMan->resClose(cpt->o_resource); + + cpt->o_logic = LOGIC_anim; + cpt->o_anim_pc = 0; + cpt->o_sync = 0; + return SCRIPT_STOP; +} + +int SwordLogic::fnSetFrame(BsObject *cpt, int32 id, int32 cdt, int32 spr, int32 frameNo, int32 f, int32 z, int32 x) { + + AnimUnit *animPtr; + + uint8 *data = (uint8*)_resMan->openFetchRes(cdt); + data += sizeof(Header); + if (frameNo == LAST_FRAME) + frameNo = READ_LE_UINT32(data) - 1; + + data += 4; + animPtr = (AnimUnit*)(data + frameNo * sizeof(AnimUnit)); + + cpt->o_anim_x = FROM_LE_32(animPtr->animX); + cpt->o_anim_y = FROM_LE_32(animPtr->animY); + cpt->o_frame = FROM_LE_32(animPtr->animFrame); + + cpt->o_resource = spr; + cpt->o_status &= ~STAT_SHRINK; + _resMan->resClose(cdt); + return SCRIPT_CONT; +} + +int SwordLogic::fnFullAnim(BsObject *cpt, int32 id, int32 anim, int32 graphic, int32 e, int32 f, int32 z, int32 x) { + cpt->o_logic = LOGIC_full_anim; + + cpt->o_anim_pc = 0; + cpt->o_anim_resource = anim; + cpt->o_resource = graphic; + cpt->o_status &= ~STAT_SHRINK; + cpt->o_sync = 0; + return SCRIPT_STOP; +} + +int SwordLogic::fnFullSetFrame(BsObject *cpt, int32 id, int32 cdt, int32 spr, int32 frameNo, int32 f, int32 z, int32 x) { + uint8 *data = (uint8*)_resMan->openFetchRes(cdt) + sizeof(Header); + + if (frameNo == LAST_FRAME) + frameNo = READ_LE_UINT32(data) - 1; + data += 4; + + AnimUnit *animPtr = (AnimUnit*)(data + sizeof(AnimUnit) * frameNo); + cpt->o_anim_x = cpt->o_xcoord = FROM_LE_32(animPtr->animX); + cpt->o_anim_y = cpt->o_ycoord = FROM_LE_32(animPtr->animY); + cpt->o_frame = FROM_LE_32(animPtr->animFrame); + + cpt->o_resource = spr; + cpt->o_status &= ~STAT_SHRINK; + + _resMan->resClose(cdt); + return SCRIPT_CONT; +} + +int SwordLogic::fnFadeDown(BsObject *cpt, int32 id, int32 speed, int32 d, int32 e, int32 f, int32 z, int32 x) { + warning("fnFadeDown speed = %d", speed); + _screen->fadeDownPalette(); + return SCRIPT_CONT; +} + +int SwordLogic::fnFadeUp(BsObject *cpt, int32 id, int32 speed, int32 d, int32 e, int32 f, int32 z, int32 x) { + warning("fnFadeUp speed = %d", speed); + _screen->fadeUpPalette(); + return SCRIPT_CONT; +} + +int SwordLogic::fnCheckFade(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + + _scriptVars[RETURN_VALUE] = (uint8)_screen->stillFading(); + return SCRIPT_CONT; +} + +int SwordLogic::fnSetSpritePalette(BsObject *cpt, int32 id, int32 spritePal, int32 d, int32 e, int32 f, int32 z, int32 x) { + _screen->fnSetPalette(184, 72, (uint8*)_resMan->openFetchRes(spritePal)); + _resMan->resClose(spritePal); + return SCRIPT_CONT; +} + +int SwordLogic::fnSetWholePalette(BsObject *cpt, int32 id, int32 spritePal, int32 d, int32 e, int32 f, int32 z, int32 x) { + uint8 *pal = (uint8*)_resMan->openFetchRes(spritePal); + pal[0] = pal[1] = pal[2] = 0; + _screen->fnSetPalette(0, 256, pal); + _resMan->resClose(spritePal); + return SCRIPT_CONT; +} + +int SwordLogic::fnSetFadeTargetPalette(BsObject *cpt, int32 id, int32 spritePal, int32 d, int32 e, int32 f, int32 z, int32 x) { + uint8 *pal = (uint8*)_resMan->openFetchRes(spritePal); + pal[0] = pal[1] = pal[2] = 0; + _resMan->resClose(spritePal); + return SCRIPT_CONT; +} + +int SwordLogic::fnSetPaletteToFade(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + warning("called unknown routine: fnSetPaletteToFade()"); + return SCRIPT_CONT; +} + +int SwordLogic::fnSetPaletteToCut(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + warning("Called unknown routine: fnSetPaletteToCut()"); + return SCRIPT_CONT; +} + +int SwordLogic::fnPlaySequence(BsObject *cpt, int32 id, int32 sequenceId, int32 d, int32 e, int32 f, int32 z, int32 x) { + warning("fnPlaySequence(%d) called", sequenceId); + return SCRIPT_CONT; +} + +int SwordLogic::fnIdle(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + cpt->o_tree.o_script_level = 0; // force to level 0 + cpt->o_logic = LOGIC_idle; + return SCRIPT_STOP; +} + +int SwordLogic::fnPause(BsObject *cpt, int32 id, int32 pause, int32 d, int32 e, int32 f, int32 z, int32 x) { + cpt->o_pause = pause; + cpt->o_logic = LOGIC_pause; + return SCRIPT_STOP; +} + +int SwordLogic::fnPauseSeconds(BsObject *cpt, int32 id, int32 pause, int32 d, int32 e, int32 f, int32 z, int32 x) { + cpt->o_pause = pause * FRAME_RATE; + cpt->o_logic = LOGIC_pause; + return SCRIPT_STOP; +} + +int SwordLogic::fnQuit(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + cpt->o_logic = LOGIC_quit; + return SCRIPT_STOP; +} + +int SwordLogic::fnKillId(BsObject *cpt, int32 id, int32 target, int32 d, int32 e, int32 f, int32 z, int32 x) { + BsObject *targetObj = _objMan->fetchObject(target); + targetObj->o_status = 0; + return SCRIPT_CONT; +} + +int SwordLogic::fnSuicide(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + cpt->o_status = 0; + cpt->o_logic = LOGIC_quit; + return SCRIPT_STOP; +} + +int SwordLogic::fnNewScript(BsObject *cpt, int32 id, int32 script, int32 d, int32 e, int32 f, int32 z, int32 x) { + cpt->o_logic = LOGIC_new_script; + _newScript = script; + return SCRIPT_STOP; +} + +int SwordLogic::fnSubScript(BsObject *cpt, int32 id, int32 script, int32 d, int32 e, int32 f, int32 z, int32 x) { + cpt->o_tree.o_script_level++; + if (cpt->o_tree.o_script_level == TOTAL_script_levels) + error("Compact %d: script level exceeded in fnSubScript.", id); + cpt->o_tree.o_script_pc[cpt->o_tree.o_script_level] = script; + cpt->o_tree.o_script_id[cpt->o_tree.o_script_level] = script; + return SCRIPT_STOP; +} + +int SwordLogic::fnRestartScript(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + cpt->o_logic = LOGIC_restart; + return SCRIPT_STOP; +} + +int SwordLogic::fnSetBookmark(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + memcpy(&cpt->o_bookmark.o_script_level, &cpt->o_tree.o_script_level, sizeof(ScriptTree)); + return SCRIPT_CONT; +} + +int SwordLogic::fnGotoBookmark(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + cpt->o_logic = LOGIC_bookmark; + return SCRIPT_STOP; +} + +int SwordLogic::fnSendSync(BsObject *cpt, int32 id, int32 sendId, int32 syncValue, int32 e, int32 f, int32 z, int32 x) { + BsObject *target = _objMan->fetchObject(sendId); + target->o_sync = syncValue; + return SCRIPT_CONT; +} + +int SwordLogic::fnWaitSync(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + cpt->o_logic = LOGIC_wait_for_sync; + return SCRIPT_STOP; +} + +int SwordLogic::cfnClickInteract(BsObject *cpt, int32 id, int32 target, int32 d, int32 e, int32 f, int32 z, int32 x) { + BsObject *tar = _objMan->fetchObject(target); + cpt = _objMan->fetchObject(PLAYER); + cpt->o_tree.o_script_level = 0; + cpt->o_tree.o_script_pc[0] = tar->o_interact; + cpt->o_tree.o_script_id[0] = tar->o_interact; + cpt->o_logic = LOGIC_script; + return SCRIPT_STOP; +} + +int SwordLogic::cfnSetScript(BsObject *cpt, int32 id, int32 target, int32 script, int32 e, int32 f, int32 z, int32 x) { + BsObject *tar = _objMan->fetchObject(target); + tar->o_tree.o_script_level = 0; + tar->o_tree.o_script_pc[0] = script; + tar->o_tree.o_script_id[0] = script; + tar->o_logic = LOGIC_script; + return SCRIPT_CONT; +} + +int SwordLogic::cfnPresetScript(BsObject *cpt, int32 id, int32 target, int32 script, int32 e, int32 f, int32 z, int32 x) { + BsObject *tar = _objMan->fetchObject(target); + tar->o_tree.o_script_level = 0; + tar->o_tree.o_script_pc[0] = script; + tar->o_tree.o_script_id[0] = script; + if (tar->o_logic == LOGIC_idle) + tar->o_logic = LOGIC_script; + return SCRIPT_CONT; +} + +int SwordLogic::fnInteract(BsObject *cpt, int32 id, int32 target, int32 d, int32 e, int32 f, int32 z, int32 x) { + BsObject *tar = _objMan->fetchObject(target); + cpt->o_place = tar->o_place; + + BsObject *floorObject = _objMan->fetchObject(tar->o_place); + cpt->o_scale_a = floorObject->o_scale_a; + cpt->o_scale_b = floorObject->o_scale_b; + + cpt->o_tree.o_script_level++; + cpt->o_tree.o_script_pc[cpt->o_tree.o_script_level] = tar->o_interact; + cpt->o_tree.o_script_id[cpt->o_tree.o_script_level] = tar->o_interact; + + return SCRIPT_STOP; +} + +int SwordLogic::fnIssueEvent(BsObject *cpt, int32 id, int32 event, int32 delay, int32 e, int32 f, int32 z, int32 x) { + _eventMan->fnIssueEvent(cpt, id, event, delay); + return SCRIPT_CONT; +} + +int SwordLogic::fnCheckForEvent(BsObject *cpt, int32 id, int32 pause, int32 d, int32 e, int32 f, int32 z, int32 x) { + return _eventMan->fnCheckForEvent(cpt, id, pause); +} + +int SwordLogic::fnWipeHands(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + _scriptVars[OBJECT_HELD] = 0; + _mouse->setLuggage(0, 0); + _menu->refresh(MENU_TOP); + return SCRIPT_CONT; +} + +int SwordLogic::fnISpeak(BsObject *cpt, int32 id, int32 cdt, int32 textNo, int32 spr, int32 f, int32 z, int32 x) { + _speechClickDelay = 3; + _mouse->flushEvents(); // prevent player from accidently clicking text away within first three frames + cpt->o_logic = LOGIC_speech; + + // first setup the talk animation + if (cdt && (!spr)) { // if 'cdt' is non-zero but 'spr' is zero - 'cdt' is an anim table tag + AnimSet *animTab = (AnimSet*)((uint8*)_resMan->openFetchRes(cdt) + sizeof(Header)); + animTab += cpt->o_dir; + + cpt->o_anim_resource = FROM_LE_32(animTab->cdt); + if (animTab->cdt) + cpt->o_resource = FROM_LE_32(animTab->spr); + _resMan->resClose(cdt); + } else { + cpt->o_anim_resource = cdt; + if (cdt) + cpt->o_resource = spr; + } + cpt->o_anim_pc = 0; // start anim from first frame + if (cpt->o_anim_resource) { + if (!cpt->o_resource) + error("ID %d: Can't run anim with cdt=%d, spr=%d", id, cdt, spr); + + FrameHeader *frameHead = _resMan->fetchFrame(_resMan->openFetchRes(cpt->o_resource), 0); + if (frameHead->offsetX && frameHead->offsetY) { // is this a boxed mega? + cpt->o_status |= STAT_SHRINK; + cpt->o_anim_x = cpt->o_xcoord; + cpt->o_anim_y = cpt->o_ycoord; + } else + cpt->o_status &= ~STAT_SHRINK; + + _resMan->resClose(cpt->o_resource); + } + if (SwordEngine::_systemVars.playSpeech) + _speechRunning = _sound->startSpeech(textNo >> 16, textNo & 0xFFFF); + else + _speechRunning = false; + _speechFinished = false; + if (SwordEngine::_systemVars.showText || (!_speechRunning)) { + _textRunning = true; + + char *text = _objMan->lockText(textNo); + cpt->o_speech_time = strlen(text) + 5; + uint32 textCptId = _textMan->lowTextManager((uint8*)text, cpt->o_speech_width, (uint8)cpt->o_speech_pen); + _objMan->unlockText(textNo); + + BsObject * textCpt = _objMan->fetchObject(textCptId); + + // the graphic is a property of SwordText, so we don't lock/unlock it. + uint16 textSpriteWidth = _textMan->giveSpriteData(cpt->o_target)->width; + uint16 textSpriteHeight = _textMan->giveSpriteData(cpt->o_target)->height; + + textCpt->o_screen = cpt->o_screen; + cpt->o_text_id = textCptId; + + // now set text coords, above the player, usually + +#define TEXT_MARGIN 3 // distance kept from edges of screen +#define ABOVE_HEAD 20 // distance kept above talking sprite + uint16 textX, textY; + if ((id == GEORGE) || ((id == NICO) && (_scriptVars[SCREEN] == 10)) && (!cpt->o_anim_resource)) { + // if George is doing Voice-Over text (centered at the bottom of the screen) + textX = _scriptVars[SCROLL_OFFSET_X] + 128 + (640 / 2) - textSpriteWidth / 2; + textY = _scriptVars[SCROLL_OFFSET_Y] + 128 + 400; + } else { + if ((id == GEORGE) && (_scriptVars[SCREEN] == 79)) + textX = cpt->o_mouse_x2; // move it off george's head + else + textX = (cpt->o_mouse_x1 + cpt->o_mouse_x2) / 2 - textSpriteWidth / 2; + + textY = cpt->o_mouse_y1 - textSpriteHeight - ABOVE_HEAD; + } + // now ensure text is within visible screen + uint16 textLeftMargin, textRightMargin, textTopMargin, textBottomMargin; + textLeftMargin = SCREEN_LEFT_EDGE + TEXT_MARGIN + _scriptVars[SCROLL_OFFSET_X]; + textRightMargin = SCREEN_RIGHT_EDGE - TEXT_MARGIN + _scriptVars[SCROLL_OFFSET_X] - textSpriteWidth; + textTopMargin = SCREEN_TOP_EDGE + TEXT_MARGIN + _scriptVars[SCROLL_OFFSET_Y]; + textBottomMargin = SCREEN_BOTTOM_EDGE - TEXT_MARGIN + _scriptVars[SCROLL_OFFSET_Y] - textSpriteHeight; + + textCpt->o_anim_x = textCpt->o_xcoord = inRange(textLeftMargin, textX, textRightMargin); + textCpt->o_anim_y = textCpt->o_ycoord = inRange(textTopMargin, textY, textBottomMargin); + } + return SCRIPT_STOP; +} + +//send instructions to mega in conversation with player +//the instruction is interpreted by the script mega_interact +int SwordLogic::fnTheyDo(BsObject *cpt, int32 id, int32 tar, int32 instruc, int32 param1, int32 param2, int32 param3, int32 x) { + BsObject *target; + target = _objMan->fetchObject(tar); + target->o_down_flag = instruc; // instruction for the mega + target->o_ins1 = param1; + target->o_ins2 = param2; + target->o_ins3 = param3; + return SCRIPT_CONT; +} + +//send an instruction to mega we're talking to and wait +//until it has finished before returning to script +int SwordLogic::fnTheyDoWeWait(BsObject *cpt, int32 id, int32 tar, int32 instruc, int32 param1, int32 param2, int32 param3, int32 x) { + BsObject *target; + target = _objMan->fetchObject(tar); + target->o_down_flag = instruc; // instruction for the mega + target->o_ins1 = param1; + target->o_ins2 = param2; + target->o_ins3 = param3; + target->o_status &= ~STAT_TALK_WAIT; + + cpt->o_logic = LOGIC_wait_for_talk; + cpt->o_down_flag = tar; + return SCRIPT_STOP; +} + +int SwordLogic::fnWeWait(BsObject *cpt, int32 id, int32 tar, int32 d, int32 e, int32 f, int32 z, int32 x) { + BsObject *target = _objMan->fetchObject(tar); + target->o_status &= ~STAT_TALK_WAIT; + + cpt->o_logic = LOGIC_wait_for_talk; + cpt->o_down_flag = tar; + + return SCRIPT_STOP; +} + +int SwordLogic::fnChangeSpeechText(BsObject *cpt, int32 id, int32 tar, int32 width, int32 pen, int32 f, int32 z, int32 x) { + BsObject *target = _objMan->fetchObject(tar); + target->o_speech_width = width; + target->o_speech_pen = pen; + return SCRIPT_STOP; +} + +//mega_interact has received an instruction it does not understand - +//The game is halted for debugging. Maybe we'll remove this later. +int SwordLogic::fnTalkError(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + error("fnTalkError for id %d, instruction %d", id, cpt->o_down_flag); + return SCRIPT_STOP; +} + +int SwordLogic::fnStartTalk(BsObject *cpt, int32 id, int32 target, int32 d, int32 e, int32 f, int32 z, int32 x) { + cpt->o_down_flag = target; + cpt->o_logic = LOGIC_start_talk; + return SCRIPT_STOP; +} + +int SwordLogic::fnCheckForTextLine(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + _scriptVars[RETURN_VALUE] = _objMan->fnCheckForTextLine(id); + return SCRIPT_CONT; +} + +int SwordLogic::fnAddTalkWaitStatusBit(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + cpt->o_status |= STAT_TALK_WAIT; + return SCRIPT_CONT; +} + +int SwordLogic::fnRemoveTalkWaitStatusBit(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + cpt->o_status &= ~STAT_TALK_WAIT; + return SCRIPT_CONT; +} + +int SwordLogic::fnNoHuman(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + _mouse->fnNoHuman(); + return SCRIPT_CONT; +} + +int SwordLogic::fnAddHuman(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + _mouse->fnAddHuman(); + return SCRIPT_CONT; +} + +int SwordLogic::fnBlankMouse(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + _mouse->fnBlankMouse(); + return SCRIPT_CONT; +} + +int SwordLogic::fnNormalMouse(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + _mouse->fnNormalMouse(); + return SCRIPT_CONT; +} + +int SwordLogic::fnLockMouse(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + _mouse->fnLockMouse(); + return SCRIPT_CONT; +} + +int SwordLogic::fnUnlockMouse(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + _mouse->fnUnlockMouse(); + return SCRIPT_CONT; +} + +int SwordLogic::fnSetMousePointer(BsObject *cpt, int32 id, int32 tag, int32 rate, int32 e, int32 f, int32 z, int32 x) { + _mouse->setPointer(tag, rate); + return SCRIPT_CONT; +} + +int SwordLogic::fnSetMouseLuggage(BsObject *cpt, int32 id, int32 tag, int32 rate, int32 e, int32 f, int32 z, int32 x) { + _mouse->setLuggage(tag, rate); + return SCRIPT_CONT; +} + +int SwordLogic::fnMouseOn(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + cpt->o_status |= STAT_MOUSE; + return SCRIPT_CONT; +} + +int SwordLogic::fnMouseOff(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + cpt->o_status &= ~STAT_MOUSE; + return SCRIPT_CONT; +} + +int SwordLogic::fnChooser(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + _menu->fnChooser(cpt); + return SCRIPT_STOP; +} + +int SwordLogic::fnEndChooser(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + _menu->fnEndChooser(); + return SCRIPT_CONT; +} + +int SwordLogic::fnStartMenu(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + _menu->fnStartMenu(); + return SCRIPT_CONT; +} + +int SwordLogic::fnEndMenu(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + _menu->fnEndMenu(); + return SCRIPT_CONT; +} + +int SwordLogic::cfnReleaseMenu(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x) { + _menu->cfnReleaseMenu(); + return SCRIPT_STOP; +} + +int SwordLogic::fnAddSubject(BsObject *cpt, int32 id, int32 sub, int32 d, int32 e, int32 f, int32 z, int32 x) { + _menu->fnAddSubject(sub); + return SCRIPT_CONT; +} + +int SwordLogic::fnAddObject(BsObject *cpt, int32 id, int32 objectNo, int32 d, int32 e, int32 f, int32 z, int32 x) { + _scriptVars[POCKET_1 + objectNo - 1] = 1; // basically means: carrying object objectNo = true; + return SCRIPT_CONT; +} + +int SwordLogic::fnRemoveObject(BsObject *cpt, int32 id, int32 objectNo, int32 d, int32 e, int32 f, int32 z, int32 x) { + _scriptVars[POCKET_1 + objectNo - 1] = 0; + return SCRIPT_CONT; +} + +int SwordLogic::fnEnterSection(BsObject *cpt, int32 id, int32 screen, int32 d, int32 e, int32 f, int32 z, int32 x) { + if (screen >= TOTAL_SECTIONS) + error("mega %d tried entering section %d", id, screen); + + if (cpt->o_type == TYPE_PLAYER) + _scriptVars[NEW_SCREEN] = screen; + else + cpt->o_screen = screen; // move the mega + _objMan->megaEntering(screen); + return SCRIPT_CONT; +} + +int SwordLogic::fnLeaveSection(BsObject *cpt, int32 id, int32 oldScreen, int32 d, int32 e, int32 f, int32 z, int32 x) { + if (oldScreen >= TOTAL_SECTIONS) + error("mega %d leaving section %d", id, oldScreen); + _objMan->megaLeaving(oldScreen, id); + return SCRIPT_CONT; +} + +int SwordLogic::fnChangeFloor(BsObject *cpt, int32 id, int32 floor, int32 d, int32 e, int32 f, int32 z, int32 x) { + cpt->o_place = floor; + BsObject *floorCpt = _objMan->fetchObject(floor); + cpt->o_scale_a = floorCpt->o_scale_a; + cpt->o_scale_b = floorCpt->o_scale_b; + return SCRIPT_CONT; +} + +int SwordLogic::fnWalk(BsObject *cpt, int32 id, int32 x, int32 y, int32 dir, int32 stance, int32 a, int32 b) { + if (stance > 0) + dir = 9; + cpt->o_walk_pc = 0; + cpt->o_route[1].frame = 512; // end of sequence + if (id == PLAYER) + _router->setPlayerTarget(x, y, dir, stance); + + int32 routeRes = _router->routeFinder(id, cpt, x, y, dir); + + if (id == PLAYER) { + _router->resetExtraData(); + if ((routeRes == 1) || (routeRes == 2)) { + _scriptVars[MEGA_ON_GRID] = 0; + _scriptVars[REROUTE_GEORGE] = 0; + } + } + if ((routeRes == 1) || (routeRes == 2)) { + cpt->o_down_flag = 1; // 1 means okay. + // if both mouse buttons were pressed on an exit => skip george's walk + if ((id == GEORGE) && (_mouse->testEvent() == MOUSE_BOTH_BUTTONS)) { + _mouse->flushEvents(); + int32 target = _scriptVars[CLICK_ID]; + // exceptions: compacts that use hand pointers but are not actually exits + if ((target != LEFT_SCROLL_POINTER) && (target != RIGHT_SCROLL_POINTER) && + (target != FLOOR_63) && (target != ROOF_63) && (target != GUARD_ROOF_63) && + (target != LEFT_TREE_POINTER_71) && (target != RIGHT_TREE_POINTER_71)) { + + target = _objMan->fetchObject(_scriptVars[CLICK_ID])->o_mouse_on; + if ((target >= SCR_exit0) && (target <= SCR_exit9)) { + fnStandAt(cpt,id,x,y,dir,stance,0,0); + return SCRIPT_STOP; + } + } + } + cpt->o_logic = LOGIC_AR_animate; + return SCRIPT_STOP; + } else if (routeRes == 3) + cpt->o_down_flag = 1; // pretend it was successful + else + cpt->o_down_flag = 0; // 0 means error + + return SCRIPT_CONT; +} + +int SwordLogic::fnTurn(BsObject *cpt, int32 id, int32 dir, int32 stance, int32 c, int32 d, int32 a, int32 b) { + if (stance > 0) + dir = 9; + int route = _router->routeFinder(id, cpt, cpt->o_xcoord, cpt->o_ycoord, dir); + + if (route) + cpt->o_down_flag = 1; //1 means ok + else + cpt->o_down_flag = 0; //0 means error + + cpt->o_logic = LOGIC_AR_animate; + cpt->o_walk_pc = 0; //reset + + return SCRIPT_STOP; +} + +int SwordLogic::fnStand(BsObject *cpt, int32 id, int32 dir, int32 stance, int32 c, int32 d, int32 a, int32 b) { + if ((dir < 0) || (dir > 8)) { + warning("fnStand:: invalid direction %d", dir); + return SCRIPT_CONT; + } + if (dir == 8) + dir = cpt->o_dir; + cpt->o_resource = cpt->o_walk_resource; + cpt->o_status |= STAT_SHRINK; + cpt->o_anim_x = cpt->o_xcoord; + cpt->o_anim_y = cpt->o_ycoord; + cpt->o_frame = 96 + dir; + cpt->o_dir = dir; + return SCRIPT_STOP; +} + +int SwordLogic::fnStandAt(BsObject *cpt, int32 id, int32 x, int32 y, int32 dir, int32 stance, int32 a, int32 b) { + if ((dir < 0) || (dir > 8)) { + warning("fnStandAt:: invalid direction %d", dir); + return SCRIPT_CONT; + } + if (dir == 8) + dir = cpt->o_dir; + cpt->o_xcoord = x; + cpt->o_ycoord = y; + return fnStand(cpt, id, dir, stance, 0, 0, 0, 0); +} + +int SwordLogic::fnFace(BsObject *cpt, int32 id, int32 targetId, int32 b, int32 c, int32 d, int32 a, int32 z) { + BsObject *target = _objMan->fetchObject(targetId); + int32 x, y; + if ((target->o_type == TYPE_MEGA) || (target->o_type == TYPE_PLAYER)) { + x = target->o_xcoord; + y = target->o_ycoord; + } else { + x = (target->o_mouse_x1 + target->o_mouse_x2) / 2; + y = (target->o_mouse_y1 + target->o_mouse_y2) / 2; + } + int32 megaTarDir = _router->whatTarget(cpt->o_xcoord, cpt->o_ycoord, x, y); + fnTurn(cpt, id, megaTarDir, 0, 0, 0, 0, 0); + return SCRIPT_STOP; +} + +int SwordLogic::fnFaceXy(BsObject *cpt, int32 id, int32 x, int32 y, int32 c, int32 d, int32 a, int32 b) { + int megaTarDir = _router->whatTarget(cpt->o_xcoord, cpt->o_ycoord, x, y); + fnTurn(cpt, id, megaTarDir, 0, 0, 0, 0, 0); + return SCRIPT_STOP; +} + +int SwordLogic::fnIsFacing(BsObject *cpt, int32 id, int32 targetId, int32 b, int32 c, int32 d, int32 a, int32 z) { + BsObject *target = _objMan->fetchObject(targetId); + int32 x, y, dir; + if ((target->o_type == TYPE_MEGA) || (target->o_type == TYPE_PLAYER)) { + x = target->o_xcoord; + y = target->o_ycoord; + dir = target->o_dir; + } else + error("fnIsFacing:: Target isn't a mega!"); + + int32 lookDir = _router->whatTarget(x, y, cpt->o_xcoord, cpt->o_ycoord); + lookDir -= dir; + lookDir = abs(lookDir); + + if (lookDir > 4) + lookDir = 8 - lookDir; + + _scriptVars[RETURN_VALUE] = lookDir; + return SCRIPT_STOP; +} + +int SwordLogic::fnGetTo(BsObject *cpt, int32 id, int32 a, int32 b, int32 c, int32 d, int32 z, int32 x) { + BsObject *place = _objMan->fetchObject(cpt->o_place); + + cpt->o_tree.o_script_level++; + cpt->o_tree.o_script_pc[cpt->o_tree.o_script_level] = place->o_get_to_script; + cpt->o_tree.o_script_id[cpt->o_tree.o_script_level] = place->o_get_to_script; + return SCRIPT_STOP; +} + +int SwordLogic::fnGetToError(BsObject *cpt, int32 id, int32 a, int32 b, int32 c, int32 d, int32 z, int32 x) { + debug(1, "fnGetToError: compact %d at place %d no get-to for target %d, click_id %d\n", id, cpt->o_place, cpt->o_target, _scriptVars[CLICK_ID]); + return SCRIPT_CONT; +} + +int SwordLogic::fnRandom(BsObject *compact, int32 id, int32 min, int32 max, int32 e, int32 f, int32 z, int32 x) { + _scriptVars[RETURN_VALUE] = _rnd.getRandomNumberRng(min, max); + return SCRIPT_CONT; +} + +int SwordLogic::fnGetPos(BsObject *cpt, int32 id, int32 targetId, int32 b, int32 c, int32 d, int32 z, int32 x) { + BsObject *target = _objMan->fetchObject(targetId); + if ((target->o_type == TYPE_MEGA) || (target->o_type == TYPE_PLAYER)) { + _scriptVars[RETURN_VALUE] = target->o_xcoord; + _scriptVars[RETURN_VALUE_2] = target->o_ycoord; + } else { + _scriptVars[RETURN_VALUE] = (target->o_mouse_x1 + target->o_mouse_x2) / 2; + _scriptVars[RETURN_VALUE_2] = target->o_mouse_y2; + } + _scriptVars[RETURN_VALUE_3] = target->o_dir; + + int32 megaSeperation; + if (targetId == DUANE) + megaSeperation = 70; // George & Duane stand with feet 70 pixels apart when at full scale + else if (targetId == BENOIR) + megaSeperation = 61; // George & Benoir + else + megaSeperation = 42; // George & Nico/Goinfre stand with feet 42 pixels apart when at full scale + + if (target->o_status & STAT_SHRINK) { + int32 scale = (target->o_scale_a * target->o_ycoord + target->o_scale_b) / 256; + _scriptVars[RETURN_VALUE_4] = (megaSeperation * scale) / 256; + debug(1, "fnGetPos: scaled megaSeperation = %d", _scriptVars[RETURN_VALUE_4]); + } else + _scriptVars[RETURN_VALUE_4] = megaSeperation; + return SCRIPT_CONT; +} + +int SwordLogic::fnGetGamepadXy(BsObject *cpt, int32 id, int32 a, int32 b, int32 c, int32 d, int32 z, int32 x) { + // playstation only + return SCRIPT_CONT; +} + +int SwordLogic::fnPlayFx(BsObject *cpt, int32 id, int32 fxNo, int32 b, int32 c, int32 d, int32 z, int32 x) { + _scriptVars[RETURN_VALUE] = _sound->addToQueue(fxNo); + return SCRIPT_CONT; +} + +int SwordLogic::fnStopFx(BsObject *cpt, int32 id, int32 fxNo, int32 b, int32 c, int32 d, int32 z, int32 x) { + _sound->fnStopFx(fxNo); + //_sound->removeFromQueue(fxNo); + return SCRIPT_CONT; +} + +int SwordLogic::fnPlayMusic(BsObject *cpt, int32 id, int32 tuneId, int32 loopFlag, int32 c, int32 d, int32 z, int32 x) { + if (loopFlag == LOOPED) + SwordEngine::_systemVars.currentMusic = tuneId; // so it gets restarted when saving & reloading + else + SwordEngine::_systemVars.currentMusic = 0; + + _music->startMusic(tuneId, loopFlag); + return SCRIPT_CONT; +} + +int SwordLogic::fnStopMusic(BsObject *cpt, int32 id, int32 a, int32 b, int32 c, int32 d, int32 z, int32 x) { + SwordEngine::_systemVars.currentMusic = 0; + _music->fadeDown(); + return SCRIPT_CONT; +} + +int SwordLogic::fnInnerSpace(BsObject *cpt, int32 id, int32 a, int32 b, int32 c, int32 d, int32 z, int32 x) { + error("fnInnerSpace() not working."); + return SCRIPT_STOP; +} + +int SwordLogic::fnSetScreen(BsObject *cpt, int32 id, int32 target, int32 newScreen, int32 c, int32 d, int32 z, int32 x) { + _objMan->fetchObject(target)->o_screen = newScreen; + return SCRIPT_CONT; +} + +int SwordLogic::fnPreload(BsObject *cpt, int32 id, int32 resId, int32 b, int32 c, int32 d, int32 z, int32 x) { + _resMan->resOpen(resId); + _resMan->resClose(resId); + return SCRIPT_CONT; +} + +int SwordLogic::fnCheckCD(BsObject *cpt, int32 id, int32 newScreen, int32 b, int32 c, int32 d, int32 z, int32 x) { + warning("fnCheckCd called"); + // Not sure if we really have to check that here. I think we can do it in the main loop + // and leave a dummy here. + return SCRIPT_CONT; +} + +int SwordLogic::fnRestartGame(BsObject *cpt, int32 id, int32 a, int32 b, int32 c, int32 d, int32 z, int32 x) { + SwordEngine::_systemVars.saveGameFlag = 3; + cpt->o_logic = LOGIC_quit; + return SCRIPT_STOP; +} + +int SwordLogic::fnQuitGame(BsObject *cpt, int32 id, int32 a, int32 b, int32 c, int32 d, int32 z, int32 x) { + error("fnQuitGame() called"); + return SCRIPT_STOP; +} + +int SwordLogic::fnDeathScreen(BsObject *cpt, int32 id, int32 a, int32 b, int32 c, int32 d, int32 z, int32 x) { + SwordEngine::_systemVars.saveGameFlag = 1; + SwordEngine::_systemVars.snrStatus = 1; + if (_scriptVars[FINALE_OPTION_FLAG] == 4) // successful end of game! + SwordEngine::_systemVars.deathScreenFlag = 2; + else + SwordEngine::_systemVars.deathScreenFlag = 1; + + cpt->o_logic = LOGIC_quit; + return SCRIPT_STOP; +} + +int SwordLogic::fnSetParallax(BsObject *cpt, int32 id, int32 screen, int32 resId, int32 c, int32 d, int32 z, int32 x) { + _screen->fnSetParallax(screen, resId); + return SCRIPT_CONT; +} + +int SwordLogic::fnTdebug(BsObject *cpt, int32 id, int32 a, int32 b, int32 c, int32 d, int32 z, int32 x) { + debug(1, "Script TDebug id %d code %d, %d", id, a, b); + return SCRIPT_CONT; +} + +int SwordLogic::fnRedFlash(BsObject *cpt, int32 id, int32 a, int32 b, int32 c, int32 d, int32 z, int32 x) { + _screen->fnFlash(FLASH_RED); + return SCRIPT_CONT; +} + +int SwordLogic::fnBlueFlash(BsObject *cpt, int32 id, int32 a, int32 b, int32 c, int32 d, int32 z, int32 x) { + _screen->fnFlash(FLASH_BLUE); + return SCRIPT_CONT; +} + +int SwordLogic::fnYellow(BsObject *cpt, int32 id, int32 a, int32 b, int32 c, int32 d, int32 z, int32 x) { + _screen->fnFlash(BORDER_YELLOW); + return SCRIPT_CONT; +} + +int SwordLogic::fnGreen(BsObject *cpt, int32 id, int32 a, int32 b, int32 c, int32 d, int32 z, int32 x) { + _screen->fnFlash(BORDER_GREEN); + return SCRIPT_CONT; +} + +int SwordLogic::fnPurple(BsObject *cpt, int32 id, int32 a, int32 b, int32 c, int32 d, int32 z, int32 x) { + _screen->fnFlash(BORDER_PURPLE); + return SCRIPT_CONT; +} + +int SwordLogic::fnBlack(BsObject *cpt, int32 id, int32 a, int32 b, int32 c, int32 d, int32 z, int32 x) { + _screen->fnFlash(BORDER_BLACK); + return SCRIPT_CONT; +} + +uint16 SwordLogic::inRange(uint16 a, uint16 b, uint16 c) { + return (a > b)? a : (((b > c) ? c : b)); +} + +const uint32 SwordLogic::_scriptVarInit[NON_ZERO_SCRIPT_VARS][2] = { + { 42, 448}, { 43, 378}, { 51, 1}, { 92, 1}, { 147, 71}, { 201, 1}, + { 209, 1}, { 215, 1}, { 242, 2}, { 244, 1}, { 246, 3}, { 247, 1}, + { 253, 1}, { 297, 1}, { 398, 1}, { 508, 1}, { 605, 1}, { 606, 1}, + { 701, 1}, { 709, 1}, { 773, 1}, { 843, 1}, { 907, 1}, { 923, 1}, + { 966, 1}, { 988, 2}, {1058, 1}, {1059, 2}, {1060, 3}, {1061, 4}, + {1062, 5}, {1063, 6}, {1064, 7}, {1065, 8}, {1066, 9}, {1067, 10}, + {1068, 11}, {1069, 12}, {1070, 13}, {1071, 14}, {1072, 15}, {1073, 16}, + {1074, 17}, {1075, 18}, {1076, 19}, {1077, 20}, {1078, 21}, {1079, 22}, + {1080, 23}, {1081, 24}, {1082, 25}, {1083, 26}, {1084, 27}, {1085, 28}, + {1086, 29}, {1087, 30}, {1088, 31}, {1089, 32}, {1090, 33}, {1091, 34}, + {1092, 35}, {1093, 36}, {1094, 37}, {1095, 38}, {1096, 39}, {1097, 40}, + {1098, 41}, {1099, 42}, {1100, 43}, {1101, 44}, {1102, 48}, {1103, 45}, + {1104, 47}, {1105, 49}, {1106, 50}, {1107, 52}, {1108, 54}, {1109, 56}, + {1110, 57}, {1111, 58}, {1112, 59}, {1113, 60}, {1114, 61}, {1115, 62}, + {1116, 63}, {1117, 64}, {1118, 65}, {1119, 66}, {1120, 67}, {1121, 68}, + {1122, 69}, {1123, 71}, {1124, 72}, {1125, 73}, {1126, 74} +}; diff --git a/sword1/logic.h b/sword1/logic.h new file mode 100644 index 0000000000..e13ebc542d --- /dev/null +++ b/sword1/logic.h @@ -0,0 +1,198 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#ifndef BSLOGIC_H +#define BSLOGIC_H +// combination of logic.c and scr_int.c + +#include "sworddefs.h" +#include "objectman.h" +#include "common/util.h" + +#define NON_ZERO_SCRIPT_VARS 95 +#define NUM_SCRIPT_VARS 1179 + +class SwordText; +class SwordSound; +class EventManager; +class SwordMenu; +class SwordRouter; +class SwordScreen; +class SwordMouse; +class SwordMusic; + +class SwordLogic; +typedef int (SwordLogic::*BSMcodeTable)(BsObject *, int32, int32, int32, int32, int32, int32, int32); + +class SwordLogic { +public: + SwordLogic(ObjectMan *pObjMan, ResMan *resMan, SwordScreen *pScreen, SwordMouse *pMouse, SwordSound *pSound, SwordMusic *pMusic, SwordMenu *pMenu); + ~SwordLogic(void); + void newScreen(uint32 newScreen); + void engine(void); + void updateScreenParams(void); + void runMouseScript(BsObject *cpt, int32 scriptId); + SwordRouter *giveRouter(void) { return _router; }; // for router debugging + + static uint32 _scriptVars[NUM_SCRIPT_VARS]; +private: + ObjectMan *_objMan; + ResMan *_resMan; + SwordScreen *_screen; + SwordSound *_sound; + SwordMouse *_mouse; + SwordRouter *_router; + SwordText *_textMan; + EventManager *_eventMan; + SwordMenu *_menu; + SwordMusic *_music; + uint32 _newScript; // <= ugly, but I can't avoid it. + bool _speechRunning, _speechFinished, _textRunning; + uint8 _speechClickDelay; + Common::RandomSource _rnd; + + int scriptManager(BsObject *compact, uint32 id); + void processLogic(BsObject *compact, uint32 id); + int interpretScript(BsObject *compact, int id, Header *scriptModule, int scriptBase, int scriptNum); + + int logicWaitTalk(BsObject *compact); + int logicStartTalk(BsObject *compact); + int logicArAnimate(BsObject *compact, uint32 id); + int speechDriver(BsObject *compact); + int fullAnimDriver(BsObject *compact); + int animDriver(BsObject *compact); + + static BSMcodeTable _mcodeTable[100]; + + uint16 inRange(uint16 a, uint16 b, uint16 c); + +//- mcodeTable: + int fnBackground (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnForeground (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnSort (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnNoSprite (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnMegaSet (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnAnim (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnSetFrame (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnFullAnim (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnFullSetFrame (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnFadeDown (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnFadeUp (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnCheckFade (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnSetSpritePalette(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnSetWholePalette(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnSetFadeTargetPalette(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnSetPaletteToFade(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnSetPaletteToCut(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnPlaySequence (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + + int fnIdle (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnPause (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnPauseSeconds (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnQuit (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnKillId (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnSuicide (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnNewScript (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnSubScript (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnRestartScript (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnSetBookmark (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnGotoBookmark (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnSendSync (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnWaitSync (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + + int cfnClickInteract(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int cfnSetScript (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int cfnPresetScript (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + + int fnInteract (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnIssueEvent (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnCheckForEvent (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnWipeHands (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnISpeak (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnTheyDo (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnTheyDoWeWait (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnWeWait (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnChangeSpeechText(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnTalkError (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnStartTalk (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnCheckForTextLine(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnAddTalkWaitStatusBit(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnRemoveTalkWaitStatusBit(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + + int fnNoHuman (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnAddHuman (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnBlankMouse (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnNormalMouse (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnLockMouse (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnUnlockMouse (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnSetMousePointer(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnSetMouseLuggage(BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnMouseOn (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnMouseOff (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnChooser (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnEndChooser (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnStartMenu (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnEndMenu (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + + int cfnReleaseMenu (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + + int fnAddSubject (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnAddObject (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnRemoveObject (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnEnterSection (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnLeaveSection (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnChangeFloor (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnWalk (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnTurn (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnStand (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnStandAt (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnFace (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnFaceXy (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnIsFacing (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnGetTo (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnGetToError (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnGetPos (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnGetGamepadXy (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnPlayFx (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnStopFx (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnPlayMusic (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnStopMusic (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnInnerSpace (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnRandom (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnSetScreen (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnPreload (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnCheckCD (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnRestartGame (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnQuitGame (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnDeathScreen (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnSetParallax (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnTdebug (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + + int fnRedFlash (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnBlueFlash (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnYellow (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnGreen (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnPurple (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + int fnBlack (BsObject *cpt, int32 id, int32 c, int32 d, int32 e, int32 f, int32 z, int32 x); + static const uint32 _scriptVarInit[NON_ZERO_SCRIPT_VARS][2]; +}; + +#endif //BSLOGIC_H diff --git a/sword1/memman.cpp b/sword1/memman.cpp new file mode 100644 index 0000000000..82e5fd7b8c --- /dev/null +++ b/sword1/memman.cpp @@ -0,0 +1,123 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#include "stdafx.h" +#include "memman.h" +#include "common/util.h" + +MemMan::MemMan(void) { + _alloced = 0; + _memListFree = _memListFreeEnd = NULL; +} + +MemMan::~MemMan(void) { +} + +void MemMan::alloc(BsMemHandle *bsMem, uint32 pSize, uint16 pCond) { + _alloced += pSize; + bsMem->data = (void*)malloc(pSize); + if (!bsMem->data) + error("MemMan::alloc(): Can't alloc %d bytes of memory.", pSize); + bsMem->cond = pCond; + bsMem->size = pSize; + if (pCond == MEM_CAN_FREE) { + warning("%d Bytes alloced as FREEABLE.", pSize); // why should one want to alloc mem if it can be freed? + addToFreeList(bsMem); + } else if (bsMem->next || bsMem->prev) // it's in our _freeAble list, remove it from there + removeFromFreeList(bsMem); + checkMemoryUsage(); +} + +void MemMan::freeNow(BsMemHandle *bsMem) { + if (bsMem->cond != MEM_FREED) { + _alloced -= bsMem->size; + removeFromFreeList(bsMem); + free(bsMem->data); + bsMem->cond = MEM_FREED; + } +} + +void MemMan::setCondition(BsMemHandle *bsMem, uint16 pCond) { + if ((pCond == MEM_FREED) || (pCond > MEM_DONT_FREE)) + error("MemMan::setCondition: program tried to set illegal memory condition"); + if (bsMem->cond != pCond) { + bsMem->cond = pCond; + if (pCond == MEM_DONT_FREE) + removeFromFreeList(bsMem); + else if (pCond == MEM_CAN_FREE) + addToFreeList(bsMem); + } +} + +void MemMan::checkMemoryUsage(void) { + while ((_alloced > MAX_ALLOC) && _memListFree) { + free(_memListFreeEnd->data); + _memListFreeEnd->data = NULL; + _memListFreeEnd->cond = MEM_FREED; + _alloced -= _memListFreeEnd->size; + removeFromFreeList(_memListFreeEnd); + } +} + +void MemMan::addToFreeList(BsMemHandle *bsMem) { + if (bsMem->next || bsMem->prev) { + warning("addToFreeList: mem block is already in freeList"); + return; + } + bsMem->prev = NULL; + bsMem->next = _memListFree; + if (bsMem->next) + bsMem->next->prev = bsMem; + _memListFree = bsMem; + if (!_memListFreeEnd) + _memListFreeEnd = _memListFree; +} + +void MemMan::removeFromFreeList(BsMemHandle *bsMem) { + /*BsMemHandle *forw = _memListFree; + BsMemHandle *rev = _memListFreeEnd; + + while (forw || rev) { + if (!(forw && rev)) + error("mem list is completely fubared"); + printf("%p <-> %p\n", forw, rev); + forw = forw->next; + rev = rev->prev; + } + printf("\n");*/ + if (!(bsMem->prev || bsMem->next)) + warning("removeFromFreeList: memory block wasn't in list"); + if (_memListFree == bsMem) + _memListFree = bsMem->next; + if (_memListFreeEnd == bsMem) + _memListFreeEnd = bsMem->prev; + + if (bsMem->next) + bsMem->next->prev = bsMem->prev; + if (bsMem->prev) + bsMem->prev->next = bsMem->next; + bsMem->next = bsMem->prev = NULL; +} + +void MemMan::initHandle(BsMemHandle *bsMem) { + memset(bsMem, 0, sizeof(BsMemHandle)); +} + diff --git a/sword1/memman.h b/sword1/memman.h new file mode 100644 index 0000000000..5ff7f298d3 --- /dev/null +++ b/sword1/memman.h @@ -0,0 +1,58 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#ifndef MEMMAN_H +#define MEMMAN_H + +#include "scummsys.h" + +struct BsMemHandle { + void *data; + uint32 size; + uint32 refCount; + uint16 cond; + BsMemHandle *next, *prev; +}; +// mem conditions: +#define MEM_FREED 0 +#define MEM_CAN_FREE 1 +#define MEM_DONT_FREE 2 + +#define MAX_ALLOC (6*1024*1024) // max amount of mem we want to alloc(). + +class MemMan { +public: + MemMan(void); + ~MemMan(void); + void alloc(BsMemHandle *bsMem, uint32 pSize, uint16 pCond = MEM_DONT_FREE); + void setCondition(BsMemHandle *bsMem, uint16 pCond); + void freeNow(BsMemHandle *bsMem); + void initHandle(BsMemHandle *bsMem); +private: + void addToFreeList(BsMemHandle *bsMem); + void removeFromFreeList(BsMemHandle *bsMem); + void checkMemoryUsage(void); + uint32 _alloced; //currently allocated memory + BsMemHandle *_memListFree; + BsMemHandle *_memListFreeEnd; +}; + +#endif //MEMMAN_H diff --git a/sword1/menu.cpp b/sword1/menu.cpp new file mode 100644 index 0000000000..0fcc614ebc --- /dev/null +++ b/sword1/menu.cpp @@ -0,0 +1,158 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#include "stdafx.h" +#include "menu.h" +#include "resman.h" +#include "scummsys.h" +#include "common/util.h" +#include "system.h" +#include "mouse.h" +#include "screen.h" +#include "logic.h" + +SwordMenuIcon::SwordMenuIcon(uint8 menuType, uint8 menuPos, uint32 resId, uint32 frame, SwordScreen *screen) { + _menuType = menuType; + _menuPos = menuPos; + _resId = resId; + _frame = frame; + _screen = screen; + _selected = false; +} + +bool SwordMenuIcon::wasClicked(uint16 mouseX, uint16 mouseY) { + return false; +} + +void SwordMenuIcon::setSelect(bool pSel) { + _selected = pSel; +} + +void SwordMenuIcon::draw(void) { + uint16 x = _menuPos * 40; + uint16 y = (_menuType == MENU_TOP)?(0):(440); + _screen->showFrame(x, y, _resId, _frame + (_selected ? 1 : 0)); +} + +SwordMenu::SwordMenu(SwordScreen *pScreen, SwordMouse *pMouse) { + _screen = pScreen; + _mouse = pMouse; + for (uint8 cnt = 0; cnt < 16; cnt++) + _subjects[cnt] = NULL; +} + +uint8 SwordMenu::checkMenuClick(uint8 menuType) { + uint16 mouseEvent = _mouse->testEvent(); + if (!mouseEvent) + return 0; + uint16 x, y; + _mouse->giveCoords(&x, &y); + if (menuType == MENU_BOT) { + for (uint8 cnt = 0; cnt < SwordLogic::_scriptVars[IN_SUBJECT]; cnt++) + if (_subjects[cnt]->wasClicked(x, y)) + if (mouseEvent == BS1L_BUTTON_DOWN) { + SwordLogic::_scriptVars[OBJECT_HELD] = _subjectBar[cnt]; + buildSubjects(); + return 0; + } else if (mouseEvent == BS1L_BUTTON_UP) { + if (SwordLogic::_scriptVars[OBJECT_HELD] == _subjectBar[cnt]) + return cnt + 1; + else { + SwordLogic::_scriptVars[OBJECT_HELD] = 0; + buildSubjects(); + return 0; + } + } + } else { + return 0; + } + return 0; +} + +void SwordMenu::buildSubjects(void) { + uint8 subDest = 0; + clearMenu(MENU_BOT); + for (uint8 cnt = 0; cnt < 16; cnt++) + if (_subjects[cnt]) { + delete _subjects[cnt]; + _subjects[cnt] = NULL; + } + for (uint8 cnt = 0; cnt < SwordLogic::_scriptVars[IN_SUBJECT]; cnt++) { + uint32 res = _subjectList[(_subjectBar[cnt] & 65535) - BASE_SUBJECT].subjectRes; + uint32 frame = _subjectList[(_subjectBar[cnt] & 65535) - BASE_SUBJECT].frameNo; + _subjects[cnt] = new SwordMenuIcon(MENU_BOT, cnt, res, frame, _screen); + _subjects[cnt]->setSelect(SwordLogic::_scriptVars[OBJECT_HELD] == (_subjectBar[cnt]&0xFFFF)); + _subjects[cnt]->draw(); + } + //_system->update_screen(); +} + +void SwordMenu::refresh(uint8 menuType) { + //warning("stub: SwordMenu::refresh())"); +} + +void SwordMenu::clearMenu(uint8 menuType) { + warning("stub: SwordMenu::clearMenu()"); +} + +void SwordMenu::fnStartMenu(void) { + warning("stub: SwordMenu::fnStartMenu()"); +} + +void SwordMenu::fnEndMenu(void) { + warning("stub: SwordMenu::clearMenu()"); +} + +void SwordMenu::fnChooser(BsObject *compact) { + SwordLogic::_scriptVars[OBJECT_HELD] = 0; + buildSubjects(); + compact->o_logic = LOGIC_choose; +} + +void SwordMenu::fnEndChooser(void) { + SwordLogic::_scriptVars[OBJECT_HELD] = 0; + clearMenu(MENU_BOT); + clearMenu(MENU_TOP); + //_system->update_screen(); + for (uint8 cnt = 0; cnt < 16; cnt++) + if (_subjects[cnt]) { + delete _subjects[cnt]; + _subjects[cnt] = NULL; + } +} + +int SwordMenu::logicChooser(BsObject *compact) { + if (checkMenuClick(MENU_BOT)) { + compact->o_logic = LOGIC_script; + return 1; + } else + return 0; +} + +void SwordMenu::fnAddSubject(int32 sub) { + _subjectBar[SwordLogic::_scriptVars[IN_SUBJECT]] = sub; + SwordLogic::_scriptVars[IN_SUBJECT]++; +} + +void SwordMenu::cfnReleaseMenu(void) { + clearMenu(MENU_TOP); + //_system->update_screen(); +} diff --git a/sword1/menu.h b/sword1/menu.h new file mode 100644 index 0000000000..e17a8a7d38 --- /dev/null +++ b/sword1/menu.h @@ -0,0 +1,80 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#ifndef BSMENU_H +#define BSMENU_H + +#include "sworddefs.h" +#include "object.h" + +class SwordScreen; +class SwordMouse; +class ResMan; + +#define MENU_TOP 0 +#define MENU_BOT 1 + +struct Subject { + uint32 subjectRes; + uint32 frameNo; +}; + +class SwordMenuIcon { +public: + SwordMenuIcon(uint8 menuType, uint8 menuPos, uint32 resId, uint32 frame, SwordScreen *screen); + bool wasClicked(uint16 mouseX, uint16 mouseY); + void setSelect(bool pSel); + void draw(void); + +private: + uint8 _menuType, _menuPos; + uint32 _resId, _frame; + bool _selected; + SwordScreen *_screen; +}; + +class SwordMenu { +public: + SwordMenu(SwordScreen *pScreen, SwordMouse *pMouse); + void fnChooser(BsObject *compact); + void fnEndChooser(void); + void fnAddSubject(int32 sub); + void cfnReleaseMenu(void); + int logicChooser(BsObject *compact); + void engine(void); + void refresh(uint8 menuType); + void fnStartMenu(void); + void fnEndMenu(void); + +private: + void buildSubjects(void); + void clearMenu(uint8 menuType); + uint8 checkMenuClick(uint8 menuType); + SwordMenuIcon *_subjects[16]; + uint32 _subjectBar[16]; + + SwordScreen *_screen; + SwordMouse *_mouse; + static const Subject _subjectList[TOTAL_subjects]; + +}; + +#endif //BSMENU_H diff --git a/sword1/mouse.cpp b/sword1/mouse.cpp new file mode 100644 index 0000000000..f0eeca0e71 --- /dev/null +++ b/sword1/mouse.cpp @@ -0,0 +1,230 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#include "stdafx.h" +#include "mouse.h" +#include "menu.h" +#include "screen.h" +#include "logic.h" +#include "resman.h" +#include "objectman.h" +#include "sworddefs.h" +#include "system.h" +#include "swordres.h" + +SwordMouse::SwordMouse(OSystem *system, ResMan *pResMan, ObjectMan *pObjMan) { + _resMan = pResMan; + _objMan = pObjMan; + _system = system; + _numObjs = 0; + _mouseStatus = 0; // mouse off and unlocked + _getOff = 0; + + for (uint8 cnt = 0; cnt < 17; cnt++) { + _pointers[cnt] = (MousePtr*)_resMan->openFetchRes(MSE_POINTER + cnt); +#ifdef SCUMM_BIG_ENDIAN + uint16 *data = (uint16*)pointers[cnt]; + for (uint8 endCnt = 0; endCnt < 5; endCnt++) + data[endCnt] = READ_LE_UINT16(data + endCnt); +#endif + fixTransparency(_pointers[cnt]->data + 0x30, _pointers[cnt]->sizeX * _pointers[cnt]->sizeY * _pointers[cnt]->numFrames); + } + /*_resMan->resOpen(MSE_POINTER); // normal mouse (1 frame anim) + _resMan->resOpen(MSE_OPERATE); + _resMan->resOpen(MSE_PICKUP); + _resMan->resOpen(MSE_EXAMINE); + _resMan->resOpen(MSE_MOUTH); + _resMan->resOpen(MSE_BECKON_L); + _resMan->resOpen(MSE_BECKON_R); + _resMan->resOpen(MSE_ARROW0); + _resMan->resOpen(MSE_ARROW1); + _resMan->resOpen(MSE_ARROW2); + _resMan->resOpen(MSE_ARROW3); + _resMan->resOpen(MSE_ARROW4); + _resMan->resOpen(MSE_ARROW5); + _resMan->resOpen(MSE_ARROW6); + _resMan->resOpen(MSE_ARROW7); + _resMan->resOpen(MSE_ARROW8); // UPWARDS + _resMan->resOpen(MSE_ARROW9);*/ // DOWNWARDS + // luggage & chess stuff is opened dynamically +} + +void SwordMouse::useLogic(SwordLogic *pLogic) { + _logic = pLogic; +} + +void SwordMouse::addToList(int id, BsObject *compact) { + _objList[_numObjs].id = id; + _objList[_numObjs].compact = compact; + _numObjs++; +} + +void SwordMouse::flushEvents(void) { + _lastState = _state = 0; +} + +void SwordMouse::engine(uint16 x, uint16 y, uint16 eventFlags) { + //warning("Stub: SwordMouse::engine"); + _state = 0; // all mouse events are flushed after one cycle. + if (_lastState) { // delay all events by one cycle to notice L_button + R_button clicks correctly. + _state = _lastState | eventFlags; + _lastState = 0; + } else if (eventFlags) + _lastState = eventFlags; + if (!(_mouseStatus & 1)) { // no human? + // if the mouse is turned off, I want the menu automatically removed, + // except while in conversation, while examining a menu object or while combining two menu objects! + /*if ((!subject_status)&&(!menu_looking)&&(!second_icon)) + { + HideMenu(TOP_MENU); + menu_status=0; + }*/ + _numObjs = 0; + return; // no human, so we don't want the mouse engine + } + // todo: check menus here. + SwordLogic::_scriptVars[MOUSE_X] = SwordLogic::_scriptVars[SCROLL_OFFSET_X] + x + 128; + SwordLogic::_scriptVars[MOUSE_Y] = SwordLogic::_scriptVars[SCROLL_OFFSET_Y] + y + 128 - 40; + + //- + int32 touchedId = 0; + uint16 clicked; + if (y > 40) { + for (uint16 priority = 0; (priority < 10) && (!touchedId); priority++) { + for (uint16 cnt = 0; cnt < _numObjs; cnt++) { + if ((_objList[cnt].compact->o_priority == priority) && + (SwordLogic::_scriptVars[MOUSE_X] >= (uint32)_objList[cnt].compact->o_mouse_x1) && + (SwordLogic::_scriptVars[MOUSE_X] <= (uint32)_objList[cnt].compact->o_mouse_x2) && + (SwordLogic::_scriptVars[MOUSE_Y] >= (uint32)_objList[cnt].compact->o_mouse_y1) && + (SwordLogic::_scriptVars[MOUSE_Y] <= (uint32)_objList[cnt].compact->o_mouse_y2)) { + touchedId = _objList[cnt].id; + clicked = cnt; + } + } + } + if (touchedId != SwordLogic::_scriptVars[SPECIAL_ITEM]) { //the mouse collision situation has changed in one way or another + SwordLogic::_scriptVars[SPECIAL_ITEM] = touchedId; + debug(9, "New special item: %X\n", touchedId); + if (_getOff) { // there was something else selected before, run its get-off script + _logic->runMouseScript(NULL, _getOff); + _getOff = 0; + } + if (touchedId) { // there's something new selected, now. + BsObject *compact = _objMan->fetchObject(SwordLogic::_scriptVars[SPECIAL_ITEM]); + + if (_objList[clicked].compact->o_mouse_on) //run its get on + _logic->runMouseScript(_objList[clicked].compact, _objList[clicked].compact->o_mouse_on); + + _getOff = _objList[clicked].compact->o_mouse_off; //setup get-off for later + } + } + } else + SwordLogic::_scriptVars[SPECIAL_ITEM] = 0; + if (_state & (BS1L_BUTTON_DOWN | BS1R_BUTTON_DOWN)) { + // todo: handle menus + SwordLogic::_scriptVars[MOUSE_BUTTON] = _state; + if (SwordLogic::_scriptVars[SPECIAL_ITEM]) { + BsObject *compact = _objMan->fetchObject(SwordLogic::_scriptVars[SPECIAL_ITEM]); + _logic->runMouseScript(compact, compact->o_mouse_click); + } + } + _numObjs = 0; +} + +uint16 SwordMouse::testEvent(void) { + return _state; +} + +void SwordMouse::setLuggage(uint32 resId, uint32 rate) { + warning("stub: SwordMouse::setLuggage(%d, %d)", resId, rate); +} + +void SwordMouse::setPointer(uint32 resId, uint32 rate) { + _currentPtrId = resId - MSE_POINTER; + _rate = rate; + _rateCnt = 1; + _frame = 0; + if (resId == 0) { + _system->set_mouse_cursor(NULL, 0, 0, 0, 0); + _system->show_mouse(false); + } else { + animate(); + _system->show_mouse(true); + } +} + +void SwordMouse::animate(void) { + if (_rateCnt && (_mouseStatus == 1)) { + _rateCnt--; + if (!_rateCnt) { + _rateCnt = _rate; + _frame = (_frame + 1) % _pointers[_currentPtrId]->numFrames; + uint16 size = _pointers[_currentPtrId]->sizeX * _pointers[_currentPtrId]->sizeY; + _system->set_mouse_cursor(_pointers[_currentPtrId]->data + 0x30 + _frame * size, _pointers[_currentPtrId]->sizeX, _pointers[_currentPtrId]->sizeY, _pointers[_currentPtrId]->hotSpotX, _pointers[_currentPtrId]->hotSpotY); + } + } +} + +void SwordMouse::fnNoHuman(void) { + if (_mouseStatus & 2) // locked, can't do anything + return ; + _mouseStatus = 0; // off & unlocked + setLuggage(0, 0); + setPointer(0, 0); +} + +void SwordMouse::fnAddHuman(void) { + if (_mouseStatus & 2) // locked, can't do anything + return ; + _mouseStatus = 1; + SwordLogic::_scriptVars[SPECIAL_ITEM] = -1; + _getOff = SCR_std_off; + setPointer(MSE_POINTER, 0); + _mouseCount = 3; + +} + +void SwordMouse::fnBlankMouse(void) { + setPointer(0, 0); +} + +void SwordMouse::fnNormalMouse(void) { + setPointer(MSE_POINTER, 0); +} + +void SwordMouse::fnLockMouse(void) { + _mouseStatus |= 2; +} + +void SwordMouse::fnUnlockMouse(void) { + _mouseStatus &= 1; +} + +void SwordMouse::giveCoords(uint16 *x, uint16 *y) { + *x = _mouseX; + *y = _mouseY; +} + +void SwordMouse::fixTransparency(uint8 *data, uint32 size) { + for (uint32 cnt = 0; cnt < size; cnt++) + if (data[cnt] == 0) + data[cnt] = 255; +} diff --git a/sword1/mouse.h b/sword1/mouse.h new file mode 100644 index 0000000000..a37b9ef0db --- /dev/null +++ b/sword1/mouse.h @@ -0,0 +1,99 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#ifndef BSMOUSE_H +#define BSMOUSE_H + +#include "scummsys.h" +#include "sworddefs.h" +#include "object.h" + +#define MAX_MOUSE 30 + +#define BS1L_BUTTON_DOWN 2 +#define BS1L_BUTTON_UP 4 +#define BS1R_BUTTON_DOWN 8 +#define BS1R_BUTTON_UP 16 +#define MOUSE_BOTH_BUTTONS (BS1L_BUTTON_DOWN | BS1R_BUTTON_DOWN) + +struct MouseObj { + int id; + BsObject *compact; +}; + +#if !defined(__GNUC__) + #pragma START_PACK_STRUCTS +#endif + +struct MousePtr { + uint16 numFrames; + uint16 sizeX; + uint16 sizeY; + uint16 hotSpotX; + uint16 hotSpotY; + uint8 data[2]; // arbitrary number. +} GCC_PACK; + +#if !defined(__GNUC__) + #pragma END_PACK_STRUCTS +#endif + +class SwordLogic; +class ResMan; +class ObjectMan; +class OSystem; + +class SwordMouse { +public: + SwordMouse(OSystem *system, ResMan *pResMan, ObjectMan *pObjMan); + void addToList(int id, BsObject *compact); + void useLogic(SwordLogic *pLogic); + void setLuggage(uint32 resID, uint32 rate); + void setPointer(uint32 resID, uint32 rate); + void animate(void); + void engine(uint16 x, uint16 y, uint16 eventFlags); + uint16 testEvent(void); + void flushEvents(void); + void giveCoords(uint16 *x, uint16 *y); + void fnNoHuman(void); + void fnAddHuman(void); + void fnBlankMouse(void); + void fnNormalMouse(void); + void fnLockMouse(void); + void fnUnlockMouse(void); +private: + void fixTransparency(uint8 *data, uint32 size); + MousePtr *_pointers[17]; + uint32 _currentPtrId, _rate, _rateCnt, _frame; + OSystem *_system; + SwordLogic *_logic; + MouseObj _objList[MAX_MOUSE]; + ResMan *_resMan; + ObjectMan *_objMan; + uint16 _mouseX, _mouseY; + + uint8 _mouseStatus, _mouseCount; + uint16 _numObjs; + uint16 _lastState, _state; + uint32 _getOff; +}; + +#endif //BSMOUSE_H diff --git a/sword1/music.cpp b/sword1/music.cpp new file mode 100644 index 0000000000..8f6bd97a0b --- /dev/null +++ b/sword1/music.cpp @@ -0,0 +1,129 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +// todo: add fadeout, crossfading. +// this code always loops. make it depend on _loopFlag + +#include "stdafx.h" +#include "music.h" +#include "sound/mixer.h" +#include "common/util.h" +#include "common/file.h" + +SwordMusic::SwordMusic(OSystem *system, SoundMixer *pMixer) { + _system = system; + _mixer = pMixer; + _mixer->setupPremix(passMixerFunc, this); + _fading = 0; + _playing = false; + _loop = false; + _mutex = _system->create_mutex(); + _waveSize = _wavePos = _bufPos = _smpInBuf = 0; + assert(_mixer->getOutputRate() == 22050); +} + +void SwordMusic::passMixerFunc(void *param, int16 *buf, uint len) { + ((SwordMusic*)param)->mixer(buf, len); +} + +void SwordMusic::mixer(int16 *buf, uint len) { + if (!_playing) + memset(buf, 0, 2 * len * sizeof(int16)); + else { + _system->lock_mutex(_mutex); + len >>= 1; + if (len > _smpInBuf) + warning("SwordMusic::mixer: sample buffer underrun"); + else { + uint32 maxLen = BUFSIZE - _bufPos; + if (len >= maxLen) { + for (uint32 cnt = 0; cnt < maxLen; cnt++) + buf[(cnt << 2) | 0] = buf[(cnt << 2) | 1] = + buf[(cnt << 2) | 2] = buf[(cnt << 2) | 3] = _musicBuf[_bufPos + cnt]; + _smpInBuf -= maxLen; + _bufPos = 0; + len -= maxLen; + buf += maxLen * 4; + } + if (len) { + for (uint32 cnt = 0; cnt < len; cnt++) + buf[(cnt << 2) | 0] = buf[(cnt << 2) | 1] = + buf[(cnt << 2) | 2] = buf[(cnt << 2) | 3] = _musicBuf[_bufPos + cnt]; + _smpInBuf -= len; + _bufPos += len; + } + } + _system->unlock_mutex(_mutex); + } +} + +void SwordMusic::stream(void) { + // make sure we've got enough samples in buffer. + if ((_smpInBuf < SAMPLERATE) && _playing) { + _system->lock_mutex(_mutex); + uint32 loadTotal = BUFSIZE - _smpInBuf; + while (uint32 doLoad = loadTotal) { + if (BUFSIZE - ((_bufPos + _smpInBuf) % BUFSIZE) < loadTotal) + doLoad = BUFSIZE - (_bufPos + _smpInBuf) % BUFSIZE; + if (_waveSize - _wavePos < doLoad) + doLoad = _waveSize - _wavePos; + int16 *dest = _musicBuf + ((_bufPos + _smpInBuf) % BUFSIZE); + _musicFile.read(dest, doLoad * 2); + _wavePos += doLoad; + if (_wavePos == _waveSize) { + _wavePos = 0; + _musicFile.seek(WAVEHEADERSIZE); + } + loadTotal -= doLoad; + _smpInBuf += doLoad; + } + _system->unlock_mutex(_mutex); + } +} + +void SwordMusic::startMusic(int32 tuneId, int32 loopFlag) { + _system->lock_mutex(_mutex); + _loop = (loopFlag > 0); + if (tuneId) { + if (_musicFile.isOpen()) + _musicFile.close(); + char fName[20]; + sprintf(fName, "MUSIC1\\%s.wav", _tuneList[tuneId]); + _musicFile.open(fName); + if (_musicFile.isOpen()) { + _musicFile.seek(0x28); + _waveSize = _musicFile.readUint32LE() / 2; + _wavePos = 0; + _smpInBuf = 0; + _bufPos = 0; + _playing = true; + } else + _playing = false; + } else + _playing = false; + _system->unlock_mutex(_mutex); + stream(); +} + +void SwordMusic::fadeDown(void) { + warning("stub: SwordMusic::fadeDown"); +} + diff --git a/sword1/music.h b/sword1/music.h new file mode 100644 index 0000000000..d55e96f432 --- /dev/null +++ b/sword1/music.h @@ -0,0 +1,59 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#ifndef BSMUSIC_H +#define BSMUSIC_H + +#include "scummsys.h" +#include "common/system.h" +#include "common/file.h" +#define TOTAL_TUNES 270 + +#define SAMPLERATE 11025 +#define BUFSIZE (4 * SAMPLERATE) +#define WAVEHEADERSIZE 0x2C + +class SoundMixer; +//class File; + +class SwordMusic { +public: + SwordMusic(OSystem *system, SoundMixer *pMixer); + void stream(void); + void startMusic(int32 tuneId, int32 loopFlag); + void fadeDown(void); +private: + File _musicFile; + OSystem *_system; + SoundMixer *_mixer; + uint16 _fading; + bool _playing; + bool _loop; + OSystem::MutexRef _mutex; + static void passMixerFunc(void *param, int16 *buf, uint len); + void mixer(int16 *buf, uint len); + static const char _tuneList[TOTAL_TUNES][8]; // in staticres.cpp + uint32 _waveSize, _wavePos; + uint32 _bufPos, _smpInBuf; + int16 _musicBuf[BUFSIZE]; // samples for 8 seconds +}; + +#endif // BSMUSIC_H diff --git a/sword1/object.h b/sword1/object.h new file mode 100644 index 0000000000..23783527ae --- /dev/null +++ b/sword1/object.h @@ -0,0 +1,125 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#ifndef BSOBJECT_H +#define BSOBJECT_H + +#include "scummsys.h" + +#define O_TOTAL_EVENTS 5 +#define O_WALKANIM_SIZE 600 //max number of nodes in router output +#define O_GRID_SIZE 200 +#define EXTRA_GRID_SIZE 20 +//-------------------------------------------------------------------------------------- + +struct OEventSlot { //receiving event list in the compact - + int32 o_event; //array of these with O_TOTAL_EVENTS elements + int32 o_event_script; +}; + +#define TOTAL_script_levels 5 +//----- +struct ScriptTree { //this is a logic tree, used by OBJECTs + int32 o_script_level; //logic level + int32 o_script_id[TOTAL_script_levels]; //script id's (are unique to each level) + int32 o_script_pc[TOTAL_script_levels]; //pc of script for each (if script_manager) +}; // size = 11*int32 = 44 bytes +//-------------------------------------------------------------------------------------- +struct TalkOffset { + int32 x; + int32 y; +}; // size = 2*int32 = 8 bytes +//-------------------------------------------------------------------------------------- +struct WalkData { + int32 frame; + int32 x; + int32 y; + int32 step; + int32 dir; +}; // size = 5*int32 = 20 bytes + +struct BsObject { + int32 o_type; // 0 broad description of type - object, floor, etc. + int32 o_status; // 4 bit flags for logic, graphics, mouse, etc. + int32 o_logic; // 8 logic type + int32 o_place; // 12 where is the mega character + int32 o_down_flag; // 16 pass back down with this - with C possibly both are unnecessary? + int32 o_target; // 20 target object for the GTM *these are linked to script + int32 o_screen; // 24 physical screen/section + int32 o_frame; // 28 frame number & + int32 o_resource; // 32 id of spr file it comes from + int32 o_sync; // 36 receive sync here + int32 o_pause; // 40 logic_engine() pauses these cycles + int32 o_xcoord; // 44 + int32 o_ycoord; // 48 + int32 o_mouse_x1; // 52 top-left of mouse area is (x1,y1) + int32 o_mouse_y1; // 56 + int32 o_mouse_x2; // 60 bottom-right of area is (x2,y2) (these coords are inclusive) + int32 o_mouse_y2; // 64 + int32 o_priority; // 68 + int32 o_mouse_on; // 72 + int32 o_mouse_off; // 76 + int32 o_mouse_click; // 80 + int32 o_interact; // 84 + int32 o_get_to_script; // 88 + int32 o_scale_a; // 92 used by floors + int32 o_scale_b; // 96 + int32 o_anim_x; // 100 + int32 o_anim_y; // 104 + + ScriptTree o_tree; // 108 size = 44 bytes + ScriptTree o_bookmark; // 152 size = 44 bytes + + int32 o_dir; // 196 + int32 o_speech_pen; // 200 + int32 o_speech_width; // 204 + int32 o_speech_time; // 208 + int32 o_text_id; // 212 working back from o_ins1 + int32 o_tag; // 216 + int32 o_anim_pc; // 220 position within an animation structure + int32 o_anim_resource; // 224 cdt or anim table + + int32 o_walk_pc; // 228 + + TalkOffset talk_table[6]; // 232 size = 6*8 bytes = 48 + + OEventSlot o_event_list[O_TOTAL_EVENTS]; // 280 size = 5*8 bytes = 40 + + int32 o_ins1; // 320 + int32 o_ins2; // 324 + int32 o_ins3; // 328 + + int32 o_mega_resource; // 332 + int32 o_walk_resource; // 336 + + WalkData o_route[O_WALKANIM_SIZE]; // 340 size = 600*20 bytes = 12000 + // mega size = 12340 bytes (+ 8 byte offset table + 20 byte header = 12368) +}; + +struct _collisionData { + BsObject *compact; + int32 w[24]; + int32 h[24]; + WalkData route[24]; +}; + +#endif //BSOBJECT_H + diff --git a/sword1/objectman.cpp b/sword1/objectman.cpp new file mode 100644 index 0000000000..94fa4b65dd --- /dev/null +++ b/sword1/objectman.cpp @@ -0,0 +1,133 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#include "stdafx.h" +#include "objectman.h" +#include "scummsys.h" +#include "common/util.h" +#include "sworddefs.h" +#include "swordres.h" +#include "sword1.h" + +ObjectMan::ObjectMan(ResMan *pResourceMan) { + _resMan = pResourceMan; + for (uint16 cnt = 0; cnt < TOTAL_SECTIONS; cnt++) + _liveList[cnt] = 0; + + _liveList[128] = _liveList[129] = _liveList[130] = _liveList[131] = _liveList[133] = + _liveList[134] = _liveList[145] = _liveList[146] = _liveList[TEXT_sect] = 1; + + for (uint16 cnt = 0; cnt < TOTAL_SECTIONS; cnt++) { + if (_liveList[cnt]) + _cptData[cnt] = (uint8*)_resMan->cptResOpen(_objectList[cnt]) + sizeof(Header); + else + _cptData[cnt] = NULL; + } + +} + +ObjectMan::~ObjectMan(void) { + for (uint16 cnt = 0; cnt < TOTAL_SECTIONS; cnt++) + if (_liveList[cnt]) + _resMan->resClose(_objectList[cnt]); +} + +bool ObjectMan::sectionAlive(uint16 section) { + return (_liveList[section] > 0); +} + +void ObjectMan::megaEntering(uint16 section) { + _liveList[section]++; + if (_liveList[section] == 1) + _cptData[section] = ((uint8*)_resMan->cptResOpen(_objectList[section])) + sizeof(Header); +} + +void ObjectMan::megaLeaving(uint16 section, int id) { + if (_liveList[section] == 0) + error("mega %d is leaving empty section %d", id, section); + _liveList[section]--; + if ((_liveList[section] == 0) && (id != PLAYER)) { + _resMan->resClose(_liveList[section]); + _cptData[section] = NULL; + } + /* if the player is leaving the section then we have to close the resources after + mainloop ends, because the screen will still need the resources*/ +} + +uint8 ObjectMan::fnCheckForTextLine(uint32 textId) { + uint8 retVal = 0; + if (!_textList[textId / ITM_PER_SEC][0]) + return 0; // section does not exist + + uint8 lang = SwordEngine::_systemVars.language; + uint32 *textData = (uint32*)((uint8*)_resMan->openFetchRes(_textList[textId / ITM_PER_SEC][lang]) + sizeof(Header)); + if ((textId & ITM_ID) < READ_LE_UINT32(textData)) { + textData++; + if (textData[textId & ITM_ID]) + retVal = 1; + } + _resMan->resClose(_textList[textId / ITM_PER_SEC][lang]); + return retVal; +} + +char *ObjectMan::lockText(uint32 textId) { + uint8 lang = SwordEngine::_systemVars.language; + char *addr = (char*)_resMan->openFetchRes(_textList[textId / ITM_PER_SEC][lang]) + sizeof(Header); + if ((textId & ITM_ID) >= READ_LE_UINT32(addr)) { + warning("ObjectMan::lockText(%d): only %d texts in file", textId & ITM_ID, READ_LE_UINT32(addr)); + textId = 0; // get first line instead + } + uint32 offset = READ_LE_UINT32(addr + ((textId & ITM_ID) + 1)* 4); + if (offset == 0) + warning("ObjectMan::lockText(%d): text number has no text lines", textId); + return addr + offset; +} + +void ObjectMan::unlockText(uint32 textId) { + _resMan->resClose(_textList[textId / ITM_PER_SEC][SwordEngine::_systemVars.language]); +} + +uint32 ObjectMan::lastTextNumber(int section) { + uint8 *data = (uint8*)_resMan->openFetchRes(_textList[section][SwordEngine::_systemVars.language]) + sizeof(Header); + uint32 result = READ_LE_UINT32(data) - 1; + _resMan->resClose(_textList[section][SwordEngine::_systemVars.language]); + return result; +} + +BsObject *ObjectMan::fetchObject(uint32 id) { + uint8 *addr = _cptData[id / ITM_PER_SEC]; + if (!addr) + error("fetchObject: section %d is not open!", id / ITM_PER_SEC); + id &= ITM_ID; + // DON'T do endian conversion here. it's already done. + return (BsObject*)(addr + *(uint32*)(addr + (id + 1)*4)); +} + +uint32 ObjectMan::fetchNoObjects(int section) { + if (_cptData[section] == NULL) + error("fetchNoObjects: section %d is not open!", section); + return *(uint32*)_cptData[section]; +} + +void ObjectMan::closeSection(uint32 screen) { + if (_liveList[screen] == 0) // close the section that PLAYER has just left, if it's empty now + _resMan->resClose(_objectList[screen]); +} diff --git a/sword1/objectman.h b/sword1/objectman.h new file mode 100644 index 0000000000..04e1aa38bd --- /dev/null +++ b/sword1/objectman.h @@ -0,0 +1,57 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +// this is the object manager. our equivalent to protocol.c and coredata.c + +#ifndef OBJECTMAN_H +#define OBJECTMAN_H + +#include "resman.h" +#include "sworddefs.h" +#include "object.h" + +class ObjectMan { +public: + ObjectMan(ResMan *pResourceMan); + ~ObjectMan(void); + BsObject *fetchObject(uint32 id); + //void unlockObject(uint32 id); + uint32 fetchNoObjects(int section); + bool sectionAlive(uint16 section); + void megaEntering(uint16 section); + void megaLeaving(uint16 section, int id); + + uint8 fnCheckForTextLine(uint32 textId); + char *lockText(uint32 textId); + void unlockText(uint32 textId); + uint32 lastTextNumber(int section); + + void closeSection(uint32 screen); +private: + ResMan *_resMan; + static const uint32 _objectList[TOTAL_SECTIONS]; //a table of pointers to object files + static const uint32 _textList[TOTAL_SECTIONS][7]; //a table of pointers to text files + int _liveList[TOTAL_SECTIONS]; //which sections are active + uint8 *_cptData[TOTAL_SECTIONS]; +}; + +#endif //OBJECTMAN_H + diff --git a/sword1/resman.cpp b/sword1/resman.cpp new file mode 100644 index 0000000000..9dd37c74fa --- /dev/null +++ b/sword1/resman.cpp @@ -0,0 +1,297 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#include "stdafx.h" +#include "scummsys.h" +#include +#include +#include "memman.h" +#include "resman.h" +#include "sworddefs.h" +#include "base/engine.h" +#include "common/util.h" +#include "swordres.h" + +#define MAX_PATH_LEN 260 + +ResMan::ResMan(const char *resFile, MemMan *pMemoMan) { + _memMan = pMemoMan; + loadCluDescript(resFile); +} + +ResMan::~ResMan(void) { + freeCluDescript(); +} + +void ResMan::loadCluDescript(const char *fileName) { + File resFile; + resFile.open(fileName); + if (!resFile.isOpen()) + error("ResMan::loadCluDescript(): File %s not found!", fileName); + + _prj.noClu = resFile.readUint32LE(); + _prj.clu = new BsClu*[_prj.noClu]; + + uint32 *cluIndex = (uint32*)malloc(_prj.noClu * 4); + resFile.read(cluIndex, _prj.noClu * 4); + + for (uint32 clusCnt = 0; clusCnt < _prj.noClu; clusCnt++) + if (cluIndex[clusCnt]) { + BsClu *cluster = _prj.clu[clusCnt] = new BsClu; + resFile.read(cluster->label, MAX_LABEL_SIZE); + + cluster->noGrp = resFile.readUint32LE(); + cluster->grp = new BsGrp*[cluster->noGrp]; + + uint32 *grpIndex = (uint32*)malloc(cluster->noGrp * 4); + resFile.read(grpIndex, cluster->noGrp * 4); + + for (uint32 grpCnt = 0; grpCnt < cluster->noGrp; grpCnt++) + if (grpIndex[grpCnt]) { + BsGrp *group = cluster->grp[grpCnt] = new BsGrp; + group->noRes = resFile.readUint32LE(); + group->resHandle = new BsMemHandle[group->noRes]; + group->offset = new uint32[group->noRes]; + group->length = new uint32[group->noRes]; + uint32 *resIdIdx = (uint32*)malloc(group->noRes * 4); + resFile.read(resIdIdx, group->noRes * 4); + + for (uint32 resCnt = 0; resCnt < group->noRes; resCnt++) { + if (resIdIdx[resCnt]) { + group->offset[resCnt] = resFile.readUint32LE(); + group->length[resCnt] = resFile.readUint32LE(); + _memMan->initHandle(group->resHandle + resCnt); + } else { + group->offset[resCnt] = 0xFFFFFFFF; + group->length[resCnt] = 0; + _memMan->initHandle(group->resHandle + resCnt); + } + } + free(resIdIdx); + } else + cluster->grp[grpCnt] = NULL; + free(grpIndex); + } else + _prj.clu[clusCnt] = NULL; + free(cluIndex); +} + +void ResMan::freeCluDescript(void) { + + for (uint32 clusCnt = 0; clusCnt < _prj.noClu; clusCnt++) + if (BsClu *cluster = _prj.clu[clusCnt]) { + for (uint32 grpCnt = 0; grpCnt < cluster->noGrp; grpCnt++) + if (BsGrp *group = cluster->grp[grpCnt]) { + _memMan->freeNow(group->resHandle); + delete[] group->resHandle; + delete[] group->offset; + delete[] group->length; + delete group; + } + delete[] cluster->grp; + delete cluster; + } + delete[] _prj.clu; +} + +void *ResMan::fetchRes(uint32 id) { + BsMemHandle *memHandle = resHandle(id); + if (!memHandle->data) + error("fetchRes:: resource %d is not open!", id); + return memHandle->data; +} + +void *ResMan::openFetchRes(uint32 id) { + resOpen(id); + return fetchRes(id); +} + +void ResMan::dumpRes(uint32 id) { + char outn[30]; + sprintf(outn, "DUMP%08X.BIN", id); + FILE *outf = fopen( outn, "wb"); + resOpen(id); + BsMemHandle *memHandle = resHandle(id); + fwrite(memHandle->data, 1, memHandle->size, outf); + fclose(outf); + resClose(id); +} + +Header *ResMan::lockScript(uint32 scrID) { + if (!_scriptList[scrID / ITM_PER_SEC]) + error("Script id %d not found.\n", scrID); + scrID = _scriptList[scrID / ITM_PER_SEC]; +#ifdef SCUMM_BIG_ENDIAN + BsMemHandle *memHandle = resHandle(scrID); + if (memHandle->cond == MEM_FREED) + openScriptResourceBigEndian(scrID); + else + resOpen(scrID); +#else + resOpen(scrID); +#endif + return (Header*)resHandle(scrID)->data; +} + +void ResMan::unlockScript(uint32 scrID) { + resClose(_scriptList[scrID / ITM_PER_SEC]); +} + +void *ResMan::cptResOpen(uint32 id) { +#ifdef SCUMM_BIG_ENDIAN + BsMemHandle *memHandle = resHandle(id); + if (memHandle->cond == MEM_FREED) + openCptResourceBigEndian(id); + else + resOpen(id); +#else + resOpen(id); +#endif + return resHandle(id)->data; +} + +void ResMan::resOpen(uint32 id) { // load resource ID into memory + BsMemHandle *memHandle = resHandle(id); + if (memHandle->cond == MEM_FREED) { // memory has been freed + uint32 size = resLength(id); + _memMan->alloc(memHandle, size); + uint8 *dest = (uint8*)memHandle->data; + File *clusFile = openClusterFile(id); + clusFile->seek( resOffset(id) ); + clusFile->read( memHandle->data, size); + if (clusFile->ioFailed()) + error("Can't read %d bytes from cluster %d\n", size, id); + // original loop was a lot more complicated, more error handling and + // some calls to the music system, don't think we'll need that. + clusFile->close(); + delete clusFile; + } else + _memMan->setCondition(memHandle, MEM_DONT_FREE); + memHandle->refCount++; + if (memHandle->refCount > 20) { + debug(1, "%d references to id %d. Guess there's something wrong.", memHandle->refCount, id); + } +} + +void ResMan::resClose(uint32 id) { + BsMemHandle *handle = resHandle(id); + if (!handle->refCount) { + warning("Resource Manager fail: unlocking object with refCount 0. Id: %d\n", id); + } else + handle->refCount--; + if (!handle->refCount) + _memMan->setCondition( handle, MEM_CAN_FREE); +} + +FrameHeader *ResMan::fetchFrame(void *resourceData, uint32 frameNo) { + uint8 *frameFile = (uint8*)resourceData; + uint8 *idxData = frameFile + sizeof(Header); + if (frameNo >= READ_LE_UINT32(idxData)) + error("fetchFrame:: frame %d doesn't exist in resource.", frameNo); + frameFile += READ_LE_UINT32(idxData + (frameNo+1) * 4); + return (FrameHeader*)frameFile; +} + +File *ResMan::openClusterFile(uint32 id) { + File *clusFile = new File();; + char fullPath[MAX_PATH_LEN]; + char fileName[15]; + makePathToCluster(fullPath); + sprintf(fileName, "%s.CLU", _prj.clu[(id >> 24)-1]->label); + clusFile->open(fileName); + if (!clusFile->isOpen()) + error("Can't open cluster file %s in directory: %s\n", fileName, fullPath); + return clusFile; +} + +BsMemHandle *ResMan::resHandle(uint32 id) { + uint8 cluster = (uint8)((id >> 24) - 1); + uint8 group = (uint8)(id >> 16); + + return &(_prj.clu[cluster]->grp[group]->resHandle[id & 0xFFFF]); +} + +uint32 ResMan::resLength(uint32 id) { + uint8 cluster = (uint8)((id >> 24) - 1); + uint8 group = (uint8)(id >> 16); + + return _prj.clu[cluster]->grp[group]->length[id & 0xFFFF]; +} + +uint32 ResMan::resOffset(uint32 id) { + uint8 cluster = (uint8)((id >> 24) - 1); + uint8 group = (uint8)(id >> 16); + + return _prj.clu[cluster]->grp[group]->offset[id & 0xFFFF]; +} + +void ResMan::makePathToCluster(char *str) { + *str = '\0'; + // todo: add search stuff, cd1, cd2, etc. +} + +void ResMan::openCptResourceBigEndian(uint32 id) { + resOpen(id); + BsMemHandle *handle = resHandle(id); + uint32 totSize = handle->size; + uint8 *data = ((uint8*)handle->data) + sizeof(Header); + totSize -= sizeof(Header); + + uint32 numCpts = *(uint32*)data = READ_LE_UINT32(data); + data += 4; + uint32 *dataIdx = (uint32*)data; + + for (uint32 cnt = 0; cnt < numCpts; cnt++) { + uint32 cptSize; + //uint32 cptPos = READ_LE_UINT32(data + cnt * 4); + uint32 cptPos = dataIdx[cnt] = READ_LE_UINT32(dataIdx + cnt); + if (cnt == numCpts-1) + cptSize = totSize - cptPos - 4; + else + cptSize = READ_LE_UINT32(data + (cnt + 1) * 4) - cptPos; + if (cptSize & 3) + error("Odd compact size during endian conversion. Resource ID = %d, Cpt = %d of %d, Size %d\n", id, cnt, numCpts, cptSize); + + cptSize >>= 2; + uint32 *cptData = (uint32*)(data + cptPos); + for (uint32 elemCnt = 0; elemCnt < cptSize; elemCnt++) + cptData[elemCnt] = READ_LE_UINT32(cptData + elemCnt); + } +} + +void ResMan::openScriptResourceBigEndian(uint32 id) { + resOpen(id); + BsMemHandle *handle = resHandle(id); + uint32 totSize = handle->size; + Header *head = (Header*)handle->data; + head->comp_length = FROM_LE_32(head->comp_length); + head->decomp_length = FROM_LE_32(head->decomp_length); + head->version = FROM_LE_16(head->version); + uint32 *data = (uint32*)((uint8*)handle->data + sizeof(Header)); + uint32 size = handle->size - sizeof(Header); + if (size & 3) + error("Odd size during script endian conversion. Resource ID =%d, size = %d", id, size); + size >>= 2; + for (uint32 cnt = 0; cnt < size; cnt++) { + *data = READ_LE_UINT32(data); + data++; + } +} diff --git a/sword1/resman.h b/sword1/resman.h new file mode 100644 index 0000000000..1e69844414 --- /dev/null +++ b/sword1/resman.h @@ -0,0 +1,80 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#ifndef RESMAN_H +#define RESMAN_H + +#include "memman.h" +#include "file.h" +#include "sworddefs.h" + +#define MAX_LABEL_SIZE (31+1) + +struct BsGrp { + uint32 noRes; + BsMemHandle *resHandle; + uint32 *offset; + uint32 *length; +}; + +struct BsClu { + char label[MAX_LABEL_SIZE]; + uint32 noGrp; + BsGrp **grp; +}; + +struct BsPrj { + uint32 noClu; + BsClu **clu; +}; + +class ResMan { +public: + ResMan(const char *resFile, MemMan *pMemoMan); + ~ResMan(void); + void resClose(uint32 id); + //void resOpen(uint32 id); + void resOpen(uint32 id); + void *fetchRes(uint32 id); + void dumpRes(uint32 id); + void *openFetchRes(uint32 id); + void *cptResOpen(uint32 id); + Header *lockScript(uint32 scrID); + void unlockScript(uint32 scrID); + FrameHeader *fetchFrame(void *resourceData, uint32 frameNo); + uint32 resLength(uint32 id); // this should be private. it's used in SwordSound for endian conversion, though + // make it private again when the mixer supports little endian data. +private: + BsMemHandle *resHandle(uint32 id); + uint32 resOffset(uint32 id); + void openCptResourceBigEndian(uint32 id); + void openScriptResourceBigEndian(uint32 id); + + File *openClusterFile(uint32 id); + void makePathToCluster(char *str); + void loadCluDescript(const char *fileName); + void freeCluDescript(void); + BsPrj _prj; + MemMan *_memMan; + static const uint32 _scriptList[TOTAL_SECTIONS]; //a table of resource tags +}; + +#endif //RESMAN_H diff --git a/sword1/router.cpp b/sword1/router.cpp new file mode 100644 index 0000000000..cd2c2e5ed3 --- /dev/null +++ b/sword1/router.cpp @@ -0,0 +1,1968 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) Revolution Software Ltd. + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#include "stdafx.h" +#include "router.h" +#include "util.h" +#include "objectman.h" +#include "resman.h" +#include "sworddefs.h" + +#define SLOW_IN 3 +#define SLOW_OUT 7 + +SwordRouter::SwordRouter(ObjectMan *pObjMan, ResMan *pResMan) { + _objMan = pObjMan; + _resMan = pResMan; + _numExtraBars = _numExtraNodes = 0; + _nNodes = _nBars = 0; + _playerTargetX = _playerTargetY = _playerTargetDir = _playerTargetStance = 0; +} + +int SwordRouter::routeFinder(int32 id, BsObject *mega, int32 x, int32 y, int32 targetDir) { + loadWalkResources(id, mega, x, y, targetDir); // init vars for subs + // init offset pointers + FrameInfos frameInfo; + + frameInfo.framesPerStep = _nWalkFrames / 2; + frameInfo.framesPerChar = _nWalkFrames * NO_DIRECTIONS; + frameInfo.standFrames = frameInfo.framesPerChar; + frameInfo.turnFramesLeft = frameInfo.framesPerChar; + frameInfo.turnFramesRight = frameInfo.framesPerChar; + frameInfo.walkFramesLeft = 0; + frameInfo.walkFramesRight = 0; + frameInfo.slowInFrames = 0; + frameInfo.slowOutFrames = 0; + frameInfo.startX = mega->o_xcoord; + frameInfo.startY = mega->o_ycoord; + frameInfo.targetX = x; + frameInfo.targetY = y; + frameInfo.targetDir = targetDir; + frameInfo.scaleA = mega->o_scale_a; + frameInfo.scaleB = mega->o_scale_b; + + if (id == GEORGE) { + frameInfo.turnFramesLeft = 3 * frameInfo.framesPerChar + NO_DIRECTIONS + 2 * SLOW_IN + 4 * SLOW_OUT; + frameInfo.turnFramesRight = 3 * frameInfo.framesPerChar + NO_DIRECTIONS + 2 * SLOW_IN + 4 * SLOW_OUT + NO_DIRECTIONS; + frameInfo.walkFramesLeft = frameInfo.framesPerChar + NO_DIRECTIONS; + frameInfo.walkFramesRight = 2 * frameInfo.framesPerChar + NO_DIRECTIONS; + frameInfo.slowInFrames = 3 * frameInfo.framesPerChar + NO_DIRECTIONS; + frameInfo.slowOutFrames = 3 * frameInfo.framesPerChar + NO_DIRECTIONS + 2 * SLOW_IN; + } else if (id == NICO) { + frameInfo.turnFramesLeft = frameInfo.framesPerChar + NO_DIRECTIONS; + frameInfo.turnFramesRight = frameInfo.framesPerChar + 2 * NO_DIRECTIONS; + frameInfo.walkFramesLeft = 0; + frameInfo.walkFramesRight = 0; + frameInfo.slowInFrames = 0; + frameInfo.slowOutFrames = 0; + } + int32 routeFlag = getRoute(); + int32 routeLength; + if (routeFlag == 1) { + // extract the route as nodes and the directions to go between each node + // route.X,route.Y and route.Dir now hold all the route infomation with + // the target dir or route continuation + routeLength = extractRoute(targetDir); + } + int32 solidFlag = 0; + if (routeFlag == 2) //special case for zero length route + { + if (targetDir >7)// if target direction specified as any + targetDir = mega->o_dir; + // just a turn on the spot is required set an end module for the route let the animator deal with it + // modularPath is normally set by ExtractRoute + _modularPath[0].dir = mega->o_dir; + _modularPath[0].num = 0; + _modularPath[0].x = mega->o_xcoord; + _modularPath[0].y = mega->o_ycoord; + _modularPath[1].dir = targetDir; + _modularPath[1].num = 0; + _modularPath[1].x = mega->o_xcoord; + _modularPath[1].y = mega->o_ycoord; + _modularPath[2].dir = 9; + _modularPath[2].num = ROUTE_END_FLAG; + + slidyWalkAnimator(mega->o_route, &frameInfo, id); + routeFlag = 2; + } else if (routeFlag == 1) { // a normal route + smoothestPath(mega->o_xcoord, mega->o_ycoord, mega->o_dir, routeLength);//Converts the route to an exact path + // The Route had waypoints and direction options + // The Path is an exact set of lines in 8 directions that reach the target. + // The path is in module format, but steps taken in each direction are not accurate + // if target dir = 8 then the walk isn't linked to an anim so + // we can create a route without sliding and miss the exact target + if (targetDir == NO_DIRECTIONS) { + solidPath(mega->o_scale_a, mega->o_scale_b); + solidFlag = solidWalkAnimator(mega->o_route, &frameInfo, id); + } + + if (!solidFlag) { + slidyPath(mega->o_scale_a, mega->o_scale_b, targetDir); + slidyWalkAnimator(mega->o_route, &frameInfo, id); + } + } + return routeFlag; +} + +void SwordRouter::slidyPath(int32 scaleA, int32 scaleB, uint16 targetDir) { + /**************************************************************************** + * SlidyPath creates a path based on part steps with no sliding to get + * as near as possible to the target without any sliding this routine is + * currently unused, but is intended for use when just clicking about. + * + * produce a module list from the line data + * + ****************************************************************************/ + int32 smooth; + int32 slidy; + int32 scale; + int32 stepX; + int32 stepY; + int32 deltaX; + int32 deltaY; + + // strip out the short sections + slidy = 1; + smooth = 1; + _modularPath[0].x = _smoothPath[0].x; + _modularPath[0].y = _smoothPath[0].y; + _modularPath[0].dir = _smoothPath[0].dir; + _modularPath[0].num = 0; + + while (_smoothPath[smooth].num < ROUTE_END_FLAG) + { + scale = scaleA * _smoothPath[smooth].y + scaleB; + deltaX = _smoothPath[smooth].x - _modularPath[slidy-1].x; + deltaY = _smoothPath[smooth].y - _modularPath[slidy-1].y; + stepX = _modX[_smoothPath[smooth].dir]; + stepY = _modY[_smoothPath[smooth].dir]; + stepX = stepX * scale; + stepY = stepY * scale; + stepX = stepX >> 19;// quarter a step minimum + stepY = stepY >> 19; + if ((abs(deltaX)>=abs(stepX)) && (abs(deltaY)>=abs(stepY))) + { + _modularPath[slidy].x = _smoothPath[smooth].x; + _modularPath[slidy].y = _smoothPath[smooth].y; + _modularPath[slidy].dir = _smoothPath[smooth].dir; + _modularPath[slidy].num = 1; + slidy += 1; + } + smooth += 1; + } + // in case the last bit had no steps + if (slidy > 1) + { + _modularPath[slidy-1].x = _smoothPath[smooth-1].x; + _modularPath[slidy-1].y = _smoothPath[smooth-1].y; + } + // set up the end of the walk + _modularPath[slidy].x = _smoothPath[smooth-1].x; + _modularPath[slidy].y = _smoothPath[smooth-1].y; + _modularPath[slidy].dir = targetDir; + _modularPath[slidy].num = 0; + slidy += 1; + _modularPath[slidy].x = _smoothPath[smooth-1].x; + _modularPath[slidy].y = _smoothPath[smooth-1].y; + _modularPath[slidy].dir = 9; + _modularPath[slidy].num = ROUTE_END_FLAG; +} + +int32 SwordRouter::solidPath(int32 scaleA, int32 scaleB) { +/**************************************************************************** + * SolidPath creates a path based on whole steps with no sliding to get + * as near as possible to the target without any sliding this routine is + * currently unused, but is intended for use when just clicking about. + * + * produce a module list from the line data + * + ****************************************************************************/ + int32 smooth; + int32 solid; + int32 scale; + int32 stepX; + int32 stepY; + int32 deltaX; + int32 deltaY; + + solid = 1; + smooth = 1; + _modularPath[0].x = _smoothPath[0].x; + _modularPath[0].y = _smoothPath[0].y; + _modularPath[0].dir = _smoothPath[0].dir; + _modularPath[0].num = 0; + + do { + scale = scaleA * _smoothPath[smooth].y + scaleB; + deltaX = _smoothPath[smooth].x - _modularPath[solid-1].x; + deltaY = _smoothPath[smooth].y - _modularPath[solid-1].y; + stepX = _modX[_smoothPath[smooth].dir]; + stepY = _modY[_smoothPath[smooth].dir]; + stepX = stepX * scale; + stepY = stepY * scale; + stepX = stepX >> 16; + stepY = stepY >> 16; + if ((abs(deltaX)>=abs(stepX)) && (abs(deltaY)>=abs(stepY))) { + _modularPath[solid].x = _smoothPath[smooth].x; + _modularPath[solid].y = _smoothPath[smooth].y; + _modularPath[solid].dir = _smoothPath[smooth].dir; + _modularPath[solid].num = 1; + solid += 1; + } + smooth += 1; + } while (_smoothPath[smooth].num < ROUTE_END_FLAG); + // in case the last bit had no steps + if (solid == 1) { //there were no paths so put in a dummy end + solid = 2; + _modularPath[1].dir = _smoothPath[0].dir; + _modularPath[1].num = 0; + } + _modularPath[solid-1].x = _smoothPath[smooth-1].x; + _modularPath[solid-1].y = _smoothPath[smooth-1].y; + // set up the end of the walk + _modularPath[solid].x = _smoothPath[smooth-1].x; + _modularPath[solid].y = _smoothPath[smooth-1].y; + _modularPath[solid].dir = 9; + _modularPath[solid].num = ROUTE_END_FLAG; + return 1; +} + +int32 SwordRouter::solidWalkAnimator(WalkData *walkAnim, FrameInfos *frInfo, int32 megaId) { + int32 p; + int32 i; + int32 left; + int32 lastDir; + int32 currentDir; + int32 turnDir; + int32 scale; + int32 step; + int32 module; + int32 moduleX; + int32 moduleY; + int32 module16X; + int32 module16Y; + int32 errorX; + int32 errorY; + int32 moduleEnd; + int32 slowStart; + int32 stepCount; + int32 lastCount; + int32 frame; +// start at the begining for a change + lastDir = _modularPath[0].dir; + p = 1; + currentDir = _modularPath[1].dir; + module = frInfo->framesPerChar + lastDir; + moduleX = frInfo->startX; + moduleY = frInfo->startY; + module16X = moduleX << 16; + module16Y = moduleY << 16; + slowStart = 0; + stepCount = 0; + + //**************************************************************************** + // SOLID + // START THE WALK WITH THE FIRST STANDFRAME THIS MAY CAUSE A DELAY + // BUT IT STOPS THE PLAYER MOVING FOR COLLISIONS ARE DETECTED + //**************************************************************************** + walkAnim[stepCount].frame = module; + walkAnim[stepCount].step = 0; + walkAnim[stepCount].dir = lastDir; + walkAnim[stepCount].x = moduleX; + walkAnim[stepCount].y = moduleY; + stepCount += 1; + + //**************************************************************************** + // SOLID + // TURN TO START THE WALK + //**************************************************************************** + // rotate if we need to + if (lastDir != currentDir) + { + // get the direction to turn + turnDir = currentDir - lastDir; + if ( turnDir < 0) + turnDir += NO_DIRECTIONS; + + if (turnDir > 4) + turnDir = -1; + else if (turnDir > 0) + turnDir = 1; + + // rotate to new walk direction + // for george and nico put in a head turn at the start + if ((megaId == GEORGE) || (megaId == NICO)) + { + if ( turnDir < 0) // new frames for turn frames 29oct95jps + { + module = frInfo->turnFramesLeft + lastDir; + } + else + { + module = frInfo->turnFramesRight + lastDir; + } + walkAnim[stepCount].frame = module; + walkAnim[stepCount].step = 0; + walkAnim[stepCount].dir = lastDir; + walkAnim[stepCount].x = moduleX; + walkAnim[stepCount].y = moduleY; + stepCount += 1; + } + + // rotate till were facing new dir then go back 45 degrees + while (lastDir != currentDir) + { + lastDir += turnDir; + if ( turnDir < 0) // new frames for turn frames 29oct95jps + { + if ( lastDir < 0) + lastDir += NO_DIRECTIONS; + module = frInfo->turnFramesLeft + lastDir; + } + else + { + if ( lastDir > 7) + lastDir -= NO_DIRECTIONS; + module = frInfo->turnFramesRight + lastDir; + } + walkAnim[stepCount].frame = module; + walkAnim[stepCount].step = 0; + walkAnim[stepCount].dir = lastDir; + walkAnim[stepCount].x = moduleX; + walkAnim[stepCount].y = moduleY; + stepCount += 1; + } + // the back 45 degrees bit + stepCount -= 1;// step back one because new head turn for george takes us past the new dir + } + + //**************************************************************************** + // SOLID + // THE SLOW IN + //**************************************************************************** + + // do start frames if its george and left or right + if (megaId == GEORGE) + { + if (_modularPath[1].num > 0) + { + if (currentDir == 2) // only for george + { + slowStart = 1; + walkAnim[stepCount].frame = 296; + walkAnim[stepCount].step = 0; + walkAnim[stepCount].dir = currentDir; + walkAnim[stepCount].x = moduleX; + walkAnim[stepCount].y = moduleY; + stepCount += 1; + walkAnim[stepCount].frame = 297; + walkAnim[stepCount].step = 0; + walkAnim[stepCount].dir = currentDir; + walkAnim[stepCount].x = moduleX; + walkAnim[stepCount].y = moduleY; + stepCount += 1; + walkAnim[stepCount].frame = 298; + walkAnim[stepCount].step = 0; + walkAnim[stepCount].dir = currentDir; + walkAnim[stepCount].x = moduleX; + walkAnim[stepCount].y = moduleY; + stepCount += 1; + } + else if (currentDir == 6) // only for george + { + slowStart = 1; + walkAnim[stepCount].frame = 299; + walkAnim[stepCount].step = 0; + walkAnim[stepCount].dir = currentDir; + walkAnim[stepCount].x = moduleX; + walkAnim[stepCount].y = moduleY; + stepCount += 1; + walkAnim[stepCount].frame = 300; + walkAnim[stepCount].step = 0; + walkAnim[stepCount].dir = currentDir; + walkAnim[stepCount].x = moduleX; + walkAnim[stepCount].y = moduleY; + stepCount += 1; + walkAnim[stepCount].frame = 301; + walkAnim[stepCount].step = 0; + walkAnim[stepCount].dir = currentDir; + walkAnim[stepCount].x = moduleX; + walkAnim[stepCount].y = moduleY; + stepCount += 1; + } + } + } + //**************************************************************************** + // SOLID + // THE WALK + //**************************************************************************** + + if (currentDir > 4) + left = frInfo->framesPerStep; + else + left = 0; + + lastCount = stepCount; + lastDir = 99;// this ensures that we don't put in turn frames for the start + currentDir = 99;// this ensures that we don't put in turn frames for the start + + do + { + while(_modularPath[p].num > 0) + { + currentDir = _modularPath[p].dir; + if (currentDir< NO_DIRECTIONS) + { + + module = currentDir * frInfo->framesPerStep * 2 + left; + if (left == 0) + left = frInfo->framesPerStep; + else + left = 0; + moduleEnd = module + frInfo->framesPerStep; + step = 0; + scale = (frInfo->scaleA * moduleY + frInfo->scaleB); + do + { + module16X += _dx[module]*scale; + module16Y += _dy[module]*scale; + moduleX = module16X >> 16; + moduleY = module16Y >> 16; + walkAnim[stepCount].frame = module; + walkAnim[stepCount].step = step; + walkAnim[stepCount].dir = currentDir; + walkAnim[stepCount].x = moduleX; + walkAnim[stepCount].y = moduleY; + stepCount += 1; + module += 1; + step += 1; + } + while( module < moduleEnd) ; + errorX = _modularPath[p].x - moduleX; + errorX = errorX * _modX[_modularPath[p].dir]; + errorY = _modularPath[p].y - moduleY; + errorY = errorY * _modY[_modularPath[p].dir]; + if ((errorX < 0) || (errorY < 0)) + { + _modularPath[p].num = 0; + stepCount -= frInfo->framesPerStep; + if (left == 0) + left = frInfo->framesPerStep; + else + left = 0; + // Okay this is the end of a section + moduleX = walkAnim[stepCount-1].x; + moduleY = walkAnim[stepCount-1].y; + module16X = moduleX << 16; + module16Y = moduleY << 16; + _modularPath[p].x =moduleX; + _modularPath[p].y =moduleY; + // Now is the time to put in the turn frames for the last turn + if ((stepCount - lastCount) < frInfo->framesPerStep)// no step taken + { + currentDir = 99;// this ensures that we don't put in turn frames for this walk or the next + if (slowStart == 1)// clean up if a slow in but no walk + { + stepCount -= 3; + lastCount -= 3; + slowStart = 0; + } + } + // check each turn condition in turn + if (((lastDir != 99) && (currentDir != 99)) && (megaId == GEORGE)) // only for george + { + lastDir = currentDir - lastDir;//1 and -7 going right -1 and 7 going left + if (((lastDir == -1) || (lastDir == 7)) || ((lastDir == -2) || (lastDir == 6))) + { + // turn at the end of the last walk + frame = lastCount - frInfo->framesPerStep; + do + { + walkAnim[frame].frame += 104;//turning left + frame += 1; + } + while(frame < lastCount ); + } + if (((lastDir == 1) || (lastDir == -7)) || ((lastDir == 2) || (lastDir == -6))) + { + // turn at the end of the current walk + frame = lastCount - frInfo->framesPerStep; + do + { + walkAnim[frame].frame += 200; //was 60 now 116 + frame += 1; + } + while(frame < lastCount ); + } + } + // all turns checked + lastCount = stepCount; + } + } + } + p = p + 1; + lastDir = currentDir; + slowStart = 0; //can only be valid first time round + } + while (_modularPath[p].dir < NO_DIRECTIONS); + + //**************************************************************************** + // SOLID + // THE SLOW OUT + //**************************************************************************** + + if ((currentDir == 2) && (megaId == GEORGE)) // only for george + { + // place stop frames here + // slowdown at the end of the last walk + frame = lastCount - frInfo->framesPerStep; + if (walkAnim[frame].frame == 24) + { + do + { + walkAnim[frame].frame += 278;//stopping right + frame += 1; + } + while(frame < lastCount ); + walkAnim[stepCount].frame = 308; + walkAnim[stepCount].step = 7; + walkAnim[stepCount].dir = currentDir; + walkAnim[stepCount].x = moduleX; + walkAnim[stepCount].y = moduleY; + stepCount += 1; + } + else if (walkAnim[frame].frame == 30) + { + do + { + walkAnim[frame].frame += 279;//stopping right + frame += 1; + } + while(frame < lastCount ); + walkAnim[stepCount].frame = 315; + walkAnim[stepCount].step = 7; + walkAnim[stepCount].dir = currentDir; + walkAnim[stepCount].x = moduleX; + walkAnim[stepCount].y = moduleY; + stepCount += 1; + } + } + else if ((currentDir == 6) && (megaId == GEORGE)) // only for george + { + // place stop frames here + // slowdown at the end of the last walk + frame = lastCount - frInfo->framesPerStep; + if (walkAnim[frame].frame == 72) + { + do + { + walkAnim[frame].frame += 244;//stopping left + frame += 1; + } + while(frame < lastCount ); + walkAnim[stepCount].frame = 322; + walkAnim[stepCount].step = 7; + walkAnim[stepCount].dir = currentDir; + walkAnim[stepCount].x = moduleX; + walkAnim[stepCount].y = moduleY; + stepCount += 1; + } + else if (walkAnim[frame].frame == 78) + { + do + { + walkAnim[frame].frame += 245;//stopping left + frame += 1; + } + while(frame < lastCount ); + walkAnim[stepCount].frame = 329; + walkAnim[stepCount].step = 7; + walkAnim[stepCount].dir = currentDir; + walkAnim[stepCount].x = moduleX; + walkAnim[stepCount].y = moduleY; + stepCount += 1; + } + } + module = frInfo->framesPerChar + _modularPath[p-1].dir; + walkAnim[stepCount].frame = module; + walkAnim[stepCount].step = 0; + walkAnim[stepCount].dir = _modularPath[p-1].dir; + walkAnim[stepCount].x = moduleX; + walkAnim[stepCount].y = moduleY; + stepCount += 1; + + walkAnim[stepCount].frame = 512; + stepCount += 1; + walkAnim[stepCount].frame = 512; + stepCount += 1; + walkAnim[stepCount].frame = 512; + + //**************************************************************************** + // SOLID + // NO END TURNS + //**************************************************************************** + +// Tdebug("RouteFinder RouteSize is %d", stepCount); +// now check the route + i = 0; + do + { + if (!check(_modularPath[i].x, _modularPath[i].y, _modularPath[i+1].x, _modularPath[i+1].y)) + p=0; + i += 1; + } + while(itargetDir = _modularPath[p-1].dir; + if (checkTarget(moduleX,moduleY) == 3)// new target on a line + p = 0; + } + + return p; +} + +int32 SwordRouter::smoothestPath(uint16 startX, uint16 startY, uint16 startDir, int32 routeLength) { +/* + * This is the second big part of the route finder and the the only bit that tries to be clever + * (the other bits are clever). + * This part of the autorouter creates a list of modules from a set of lines running across the screen + * The task is complicated by two things; + * Firstly in chosing a route through the maze of nodes the routine tries to minimise the amount of each + * individual turn avoiding 90 degree and greater turns (where possible) and reduces the total nuber of + * turns (subject to two 45 degree turns being better than one 90 degree turn). + * Secondly when walking in a given direction the number of steps required to reach the end of that run + * is not calculated accurately. This is because I was unable to derive a function to relate number of + * steps taken between two points to the shrunken step size + * + */ + int32 dirS; + int32 dirD; + int32 dS; + int32 dD; + int32 dSS; + int32 dSD; + int32 dDS; + int32 dDD; + int32 SS; + int32 SD; + int32 DS; + int32 DD; + int32 temp; + int32 steps; + int32 option; + int32 options; + int32 lastDir; + int32 nextDirS; + int32 nextDirD; + int32 tempturns[4]; + int32 turns[4]; + int32 turntable[NO_DIRECTIONS] = {0,1,3,5,7,5,3,1}; + + // route.X route.Y and route.Dir start at far end + _smoothPath[0].x = startX; + _smoothPath[0].y = startY; + _smoothPath[0].dir = startDir; + _smoothPath[0].num = 0; + lastDir = startDir; + // for each section of the route + for (int32 p = 0; p < routeLength; p++) { + dirS = _route[p].dirS; + dirD = _route[p].dirD; + nextDirS = _route[p+1].dirS; + nextDirD = _route[p+1].dirD; + + // Check directions into and out of a pair of nodes + // going in + dS = dirS - lastDir; + if ( dS < 0) + dS = dS + NO_DIRECTIONS; + + dD = dirD - lastDir; + if ( dD < 0) + dD = dD + NO_DIRECTIONS; + + // coming out + dSS = dirS - nextDirS; + if ( dSS < 0) + dSS = dSS + NO_DIRECTIONS; + + dDD = dirD - nextDirD; + if ( dDD < 0) + dDD = dDD + NO_DIRECTIONS; + + dSD = dirS - nextDirD; + if ( dSD < 0) + dSD = dSD + NO_DIRECTIONS; + + dDS = dirD - nextDirS; + if ( dDS < 0) + dDS = dDS + NO_DIRECTIONS; + + // Determine the amount of turning involved in each possible path + dS = turntable[dS]; + dD = turntable[dD]; + dSS = turntable[dSS]; + dDD = turntable[dDD]; + dSD = turntable[dSD]; + dDS = turntable[dDS]; + // get the best path out ie assume next section uses best direction + if (dSD < dSS) + dSS = dSD; + if (dDS < dDD) + dDD = dDS; + // rate each option + SS = dS + dSS + 3; // Split routes look crap so weight against them + SD = dS + dDD; + DS = dD + dSS; + DD = dD + dDD + 3; + // set up turns as a sorted array of the turn values + tempturns[0] = SS; + turns[0] = 0; + tempturns[1] = SD; + turns[1] = 1; + tempturns[2] = DS; + turns[2] = 2; + tempturns[3] = DD; + turns[3] = 3; + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + if (tempturns[j] > tempturns[j + 1]) { + temp = turns[j]; + turns[j] = turns[j+1]; + turns[j+1] = temp; + temp = tempturns[j]; + tempturns[j] = tempturns[j+1]; + tempturns[j+1] = temp; + } + } + } + + // best option matched in order of the priority we would like to see on the screen + // but each option must be checked to see if it can be walked + + options = newCheck(1, _route[p].x, _route[p].y, _route[p + 1].x, _route[p + 1].y); + + if (options == 0) + error("BestTurns failed"); + steps = 0; + for (int i = 0; (i < 4) && (steps == 0); i++) { + option = 1 << turns[i]; + if (option & options) + steps = smoothCheck(turns[i],p,dirS,dirD); + } + + if (steps == 0) + error("BestTurns failed"); + // route.X route.Y route.dir and bestTurns start at far end + } + _smoothPath[steps].dir = 9; + _smoothPath[steps].num = ROUTE_END_FLAG; + return 1; +} + +int32 SwordRouter::smoothCheck(int32 best, int32 p, int32 dirS, int32 dirD) { + static int32 k; + int32 tempK; + int32 x; + int32 y; + int32 x2; + int32 y2; + int32 dx; + int32 dy; + int32 dsx; + int32 dsy; + int32 ddx; + int32 ddy; + int32 dirX; + int32 dirY; + int32 ss0; + int32 ss1; + int32 ss2; + int32 sd0; + int32 sd1; + int32 sd2; + + if (p == 0) + k = 1; + tempK = 0; + x = _route[p].x; + y = _route[p].y; + x2 = _route[p + 1].x; + y2 = _route[p + 1].y; + dx = x2 - x; + dy = y2 - y; + dirX = 1; + dirY = 1; + if (dx < 0) { + dx = -dx; + dirX = -1; + } + + if (dy < 0) { + dy = -dy; + dirY = -1; + } + +// set up sd0-ss2 to reflect possible movement in each direction + if ((dirS == 0) || (dirS == 4)) { // vert and diag + ddx = dx; + ddy = (dx*_diagonaly)/_diagonalx; + dsy = dy - ddy; + ddx = ddx * dirX; + ddy = ddy * dirY; + dsy = dsy * dirY; + dsx = 0; + + sd0 = (ddx + _modX[dirD]/2) / _modX[dirD]; + ss0 = (dsy + _modY[dirS]/2) / _modY[dirS]; + sd1 = sd0/2; + ss1 = ss0/2; + sd2 = sd0 - sd1; + ss2 = ss0 - ss1; + } else { + ddy = dy; + ddx = (dy*_diagonalx)/_diagonaly; + dsx = dx - ddx; + ddy = ddy * dirY; + ddx = ddx * dirX; + dsx = dsx * dirX; + dsy = 0; + + sd0 = (ddy + _modY[dirD]/2) / _modY[dirD]; + ss0 = (dsx + _modX[dirS]/2) / _modX[dirS]; + sd1 = sd0/2; + ss1 = ss0/2; + sd2 = sd0 - sd1; + ss2 = ss0 - ss1; + } + + if (best == 0) { //halfsquare, diagonal, halfsquare + _smoothPath[k].x = x+dsx/2; + _smoothPath[k].y = y+dsy/2; + _smoothPath[k].dir = dirS; + _smoothPath[k].num = ss1; + k = k + 1; + _smoothPath[k].x = x+dsx/2+ddx; + _smoothPath[k].y = y+dsy/2+ddy; + _smoothPath[k].dir = dirD; + _smoothPath[k].num = sd0; + k = k + 1; + _smoothPath[k].x = x+dsx+ddx; + _smoothPath[k].y = y+dsy+ddy; + _smoothPath[k].dir = dirS; + _smoothPath[k].num = ss2; + k = k + 1; + tempK = k; + } else if (best == 1) { //square, diagonal + _smoothPath[k].x = x+dsx; + _smoothPath[k].y = y+dsy; + _smoothPath[k].dir = dirS; + _smoothPath[k].num = ss0; + k = k + 1; + _smoothPath[k].x = x2; + _smoothPath[k].y = y2; + _smoothPath[k].dir = dirD; + _smoothPath[k].num = sd0; + k = k + 1; + tempK = k; + } else if (best == 2) { //diagonal square + _smoothPath[k].x = x+ddx; + _smoothPath[k].y = y+ddy; + _smoothPath[k].dir = dirD; + _smoothPath[k].num = sd0; + k = k + 1; + _smoothPath[k].x = x2; + _smoothPath[k].y = y2; + _smoothPath[k].dir = dirS; + _smoothPath[k].num = ss0; + k = k + 1; + tempK = k; + } else { //halfdiagonal, square, halfdiagonal + _smoothPath[k].x = x+ddx/2; + _smoothPath[k].y = y+ddy/2; + _smoothPath[k].dir = dirD; + _smoothPath[k].num = sd1; + k = k + 1; + _smoothPath[k].x = x+dsx+ddx/2; + _smoothPath[k].y = y+dsy+ddy/2; + _smoothPath[k].dir = dirS; + _smoothPath[k].num = ss0; + k = k + 1; + _smoothPath[k].x = x2; + _smoothPath[k].y = y2; + _smoothPath[k].dir = dirD; + _smoothPath[k].num = sd2; + k = k + 1; + tempK = k; + } + return tempK; +} + +void SwordRouter::slidyWalkAnimator(WalkData *walkAnim, FrameInfos *frInfo, int32 megaId) { +/**************************************************************************** + * Skidding every where HardWalk creates an animation that exactly fits the + * smoothPath and uses foot slipping to fit whole steps into the route + * Parameters: georgeg,mouseg + * Returns: rout + * + * produce a module list from the line data + * + ****************************************************************************/ + static int32 left = 0; + int32 p; + int32 lastDir; + int32 lastRealDir; + int32 currentDir; + int32 turnDir; + int32 scale; + int32 step; + int32 module; + int32 moduleEnd; + int32 moduleX; + int32 moduleY; + int32 module16X = 0; + int32 module16Y = 0; + int32 stepX; + int32 stepY; + int32 errorX; + int32 errorY; + int32 lastErrorX; + int32 lastErrorY; + int32 lastCount; + int32 stepCount; + int32 frameCount; + int32 frames; + int32 frame; + + lastDir = _modularPath[0].dir; + currentDir = _modularPath[1].dir; + if (currentDir == NO_DIRECTIONS) + currentDir = lastDir; + moduleX = frInfo->startX; + moduleY = frInfo->startY; + module16X = moduleX << 16; + module16Y = moduleY << 16; + stepCount = 0; + //**************************************************************************** + // SLIDY + // START THE WALK WITH THE FIRST STANDFRAME THIS MAY CAUSE A DELAY + // BUT IT STOPS THE PLAYER MOVING FOR COLLISIONS ARE DETECTED + //**************************************************************************** + module = frInfo->framesPerChar + lastDir; + walkAnim[stepCount].frame = module; + walkAnim[stepCount].step = 0; + walkAnim[stepCount].dir = lastDir; + walkAnim[stepCount].x = moduleX; + walkAnim[stepCount].y = moduleY; + stepCount += 1; + + //**************************************************************************** + // SLIDY + // TURN TO START THE WALK + //**************************************************************************** + // rotate if we need to + if (lastDir != currentDir) + { + // get the direction to turn + turnDir = currentDir - lastDir; + if ( turnDir < 0) + turnDir += NO_DIRECTIONS; + + if (turnDir > 4) + turnDir = -1; + else if (turnDir > 0) + turnDir = 1; + + // rotate to new walk direction + // for george and nico put in a head turn at the start + if ((megaId == GEORGE) || (megaId == NICO)) + { + if ( turnDir < 0) // new frames for turn frames 29oct95jps + { + module = frInfo->turnFramesLeft + lastDir; + } + else + { + module = frInfo->turnFramesRight + lastDir; + } + walkAnim[stepCount].frame = module; + walkAnim[stepCount].step = 0; + walkAnim[stepCount].dir = lastDir; + walkAnim[stepCount].x = moduleX; + walkAnim[stepCount].y = moduleY; + stepCount += 1; + } + + // rotate till were facing new dir then go back 45 degrees + while (lastDir != currentDir) { + lastDir += turnDir; + if ( turnDir < 0) { // new frames for turn frames + if ( lastDir < 0) + lastDir += NO_DIRECTIONS; + module = frInfo->turnFramesLeft + lastDir; + } else { + if ( lastDir > 7) + lastDir -= NO_DIRECTIONS; + module = frInfo->turnFramesRight + lastDir; + } + walkAnim[stepCount].frame = module; + walkAnim[stepCount].step = 0; + walkAnim[stepCount].dir = lastDir; + walkAnim[stepCount].x = moduleX; + walkAnim[stepCount].y = moduleY; + stepCount += 1; + } + // the back 45 degrees bit + stepCount -= 1;// step back one because new head turn for george takes us past the new dir + } + // his head is in the right direction + lastRealDir = currentDir; + + //**************************************************************************** + // SLIDY + // THE WALK + //**************************************************************************** + + if (left == 0) + left = frInfo->framesPerStep; + else + left = 0; + + lastCount = stepCount; + lastDir = 99;// this ensures that we don't put in turn frames for the start + currentDir = 99;// this ensures that we don't put in turn frames for the start + p = 0; + do + { + while (_modularPath[p].num == 0) + { + p = p + 1; + if (currentDir != 99) + lastRealDir = currentDir; + lastDir = currentDir; + lastCount = stepCount; + } + //calculate average amount to lose in each step on the way to the next node + currentDir = _modularPath[p].dir; + if (currentDir < NO_DIRECTIONS) + { + module = currentDir * frInfo->framesPerStep * 2 + left; + if (left == 0) + left = frInfo->framesPerStep; + else + left = 0; + moduleEnd = module + frInfo->framesPerStep; + step = 0; + scale = (frInfo->scaleA * moduleY + frInfo->scaleB); + do { + module16X += _dx[module]*scale; + module16Y += _dy[module]*scale; + moduleX = module16X >> 16; + moduleY = module16Y >> 16; + walkAnim[stepCount].frame = module; + walkAnim[stepCount].step = step; + walkAnim[stepCount].dir = currentDir; + walkAnim[stepCount].x = moduleX; + walkAnim[stepCount].y = moduleY; + stepCount += 1; + step += 1; + module += 1; + } while( module < moduleEnd); + stepX = _modX[_modularPath[p].dir]; + stepY = _modY[_modularPath[p].dir]; + errorX = _modularPath[p].x - moduleX; + errorX = errorX * stepX; + errorY = _modularPath[p].y - moduleY; + errorY = errorY * stepY; + if ((errorX < 0) || (errorY < 0)) { + _modularPath[p].num = 0; // the end of the path + // okay those last steps took us past our target but do we want to scoot or moonwalk + frames = stepCount - lastCount; + errorX = _modularPath[p].x - walkAnim[stepCount-1].x; + errorY = _modularPath[p].y - walkAnim[stepCount-1].y; + + if (frames > frInfo->framesPerStep) { + lastErrorX = _modularPath[p].x - walkAnim[stepCount-7].x; + lastErrorY = _modularPath[p].y - walkAnim[stepCount-7].y; + if (stepX==0) { + if (3*abs(lastErrorY) < abs(errorY)) { //the last stop was closest + stepCount -= frInfo->framesPerStep; + if (left == 0) + left = frInfo->framesPerStep; + else + left = 0; + } + } else { + if (3*abs(lastErrorX) < abs(errorX)) { //the last stop was closest + stepCount -= frInfo->framesPerStep; + if (left == 0) + left = frInfo->framesPerStep; + else + left = 0; + } + } + } + errorX = _modularPath[p].x - walkAnim[stepCount-1].x; + errorY = _modularPath[p].y - walkAnim[stepCount-1].y; + // okay we've reached the end but we still have an error + if (errorX != 0) { + frameCount = 0; + frames = stepCount - lastCount; + do { + frameCount += 1; + walkAnim[lastCount + frameCount - 1].x += errorX*frameCount/frames; + } while(frameCountframesPerStep) + currentDir = 99;// this ensures that we don't put in turn frames for this walk or the next + if (currentDir != 99) + lastRealDir = currentDir; + // check each turn condition in turn + if (((lastDir != 99) && (currentDir != 99)) && (megaId == GEORGE)) { // only for george + lastDir = currentDir - lastDir;//1 and -7 going right -1 and 7 going left + if (((lastDir == -1) || (lastDir == 7)) || ((lastDir == -2) || (lastDir == 6))) { + // turn at the end of the last walk + frame = lastCount - frInfo->framesPerStep; + do { + walkAnim[frame].frame += 104;//turning left + frame += 1; + } while(frame < lastCount ); + } + if (((lastDir == 1) || (lastDir == -7)) || ((lastDir == 2) || (lastDir == -6))) { + // turn at the end of the current walk + frame = lastCount - frInfo->framesPerStep; + do { + walkAnim[frame].frame += 200; //was 60 now 116 + frame += 1; + } while(frame < lastCount ); + } + lastDir = currentDir; + } + // all turns checked + + lastCount = stepCount; + moduleX = walkAnim[stepCount-1].x; + moduleY = walkAnim[stepCount-1].y; + module16X = moduleX << 16; + module16Y = moduleY << 16; + } + } + } while (_modularPath[p].dir < NO_DIRECTIONS); + + if (lastRealDir == 99) + error("SlidyWalkAnimator direction error"); + + if (frInfo->targetDir == NO_DIRECTIONS) { // stand in the last direction + module = frInfo->standFrames + lastRealDir; + frInfo->targetDir = lastRealDir; + walkAnim[stepCount].frame = module; + walkAnim[stepCount].step = 0; + walkAnim[stepCount].dir = lastRealDir; + walkAnim[stepCount].x = moduleX; + walkAnim[stepCount].y = moduleY; + stepCount += 1; + } + if (frInfo->targetDir == 9) { + if (stepCount == 0) { + module = frInfo->framesPerChar + lastRealDir; + walkAnim[stepCount].frame = module; + walkAnim[stepCount].step = 0; + walkAnim[stepCount].dir = lastRealDir; + walkAnim[stepCount].x = moduleX; + walkAnim[stepCount].y = moduleY; + stepCount += 1; + } + } else if (frInfo->targetDir != lastRealDir) { // rotate to targetDir + // rotate to target direction + turnDir = frInfo->targetDir - lastRealDir; + if ( turnDir < 0) + turnDir += NO_DIRECTIONS; + + if (turnDir > 4) + turnDir = -1; + else if (turnDir > 0) + turnDir = 1; + + // rotate to target direction + // for george and nico put in a head turn at the start + if ((megaId == GEORGE) || (megaId == NICO)) { + if ( turnDir < 0) // new frames for turn frames 29oct95jps + module = frInfo->turnFramesLeft + lastDir; + else + module = frInfo->turnFramesRight + lastDir; + walkAnim[stepCount].frame = module; + walkAnim[stepCount].step = 0; + walkAnim[stepCount].dir = lastRealDir; + walkAnim[stepCount].x = moduleX; + walkAnim[stepCount].y = moduleY; + stepCount += 1; + } + + // rotate if we need to + while (lastRealDir != frInfo->targetDir) { + lastRealDir += turnDir; + if ( turnDir < 0) { // new frames for turn frames 29oct95jps + if ( lastRealDir < 0) + lastRealDir += NO_DIRECTIONS; + module = frInfo->turnFramesLeft + lastRealDir; + } else { + if ( lastRealDir > 7) + lastRealDir -= NO_DIRECTIONS; + module = frInfo->turnFramesRight + lastRealDir; + } + walkAnim[stepCount].frame = module; + walkAnim[stepCount].step = 0; + walkAnim[stepCount].dir = lastRealDir; + walkAnim[stepCount].x = moduleX; + walkAnim[stepCount].y = moduleY; + stepCount += 1; + } + module = frInfo->standFrames + lastRealDir; + walkAnim[stepCount-1].frame = module; + } else { // just stand at the end + module = frInfo->standFrames + lastRealDir; + walkAnim[stepCount].frame = module; + walkAnim[stepCount].step = 0; + walkAnim[stepCount].dir = lastRealDir; + walkAnim[stepCount].x = moduleX; + walkAnim[stepCount].y = moduleY; + stepCount += 1; + } + + walkAnim[stepCount].frame = 512; + stepCount += 1; + walkAnim[stepCount].frame = 512; + stepCount += 1; + walkAnim[stepCount].frame = 512; +} + +/**************************************************************************** + * ExtractRoute gets route from the node data after a full scan, route is + * written with just the basic way points and direction options for heading + * to the next point. + ****************************************************************************/ +int32 SwordRouter::extractRoute(int32 targetDir) { + int32 prev; + int32 prevx; + int32 prevy; + int32 last; + int32 point; + int32 dirx; + int32 diry; + int32 dir; + + // extract the route from the node data + prev = _nNodes; + last = prev; + point = O_ROUTE_SIZE - 1; + _route[point].x = _node[last].x; + _route[point].y = _node[last].y; + while (prev > 0) { + point = point - 1; + prev = _node[last].prev; + prevx = _node[prev].x; + prevy = _node[prev].y; + _route[point].x = prevx; + _route[point].y = prevy; + last = prev; + } + + int32 routeLength = 0; + do { + _route[routeLength].x = _route[point].x; + _route[routeLength].y = _route[point].y; + point = point + 1; + routeLength = routeLength + 1; + } while (point < O_ROUTE_SIZE); + + for (int p = 0; p < routeLength; p++) { + int32 dx = _route[p+1].x - _route[p].x; + int32 dy = _route[p+1].y - _route[p].y; + dirx = 1; + diry = 1; + if (dx < 0) + { + dx = -dx; + dirx = -1; + } + if (dy < 0) + { + dy = -dy; + diry = -1; + } + + if ((_diagonaly * dx) > (_diagonalx * dy)) // dir = 1,2 or 2,3 or 5,6 or 6,7 + { + dir = 4 - 2 * dirx; // 2 or 6 + _route[p].dirS = dir; + dir = dir + diry * dirx; // 1,3,5 or 7 + _route[p].dirD = dir; + } + else // dir = 7,0 or 0,1 or 3,4 or 4,5 + { + dir = 2 + 2 * diry; // 0 or 4 + _route[p].dirS = dir; + dir = 4 - 2 * dirx; // 2 or 6 + dir = dir + diry * dirx; // 1,3,5 or 7 + _route[p].dirD = dir; + } + } + if (targetDir == 8) // ANY direction + { + _route[routeLength].dirS = _route[routeLength-1].dirS; + _route[routeLength].dirD = _route[routeLength-1].dirD; + } + else + { + _route[routeLength].dirS = targetDir; + _route[routeLength].dirD = targetDir; + } + return routeLength; +} + +int SwordRouter::getRoute() { + int32 routeRes; + if ((_node[0].x == _node[_nNodes].x) && (_node[0].y == _node[_nNodes].y)) + routeRes = 2; // start is the same as destination + else + routeRes = checkTarget(_node[_nNodes].x, _node[_nNodes].y); + + if (routeRes == 0) { // still looking for a route check if target is within a pixel of a line + int32 level = 1; + int changed; + do + { + changed = scan(level); + level++; + } while(changed == 1); + if (_node[_nNodes].dist < 9999) // did we reach the target? + routeRes = 1; + } + return routeRes; +} + +int SwordRouter::scan(int32 level) { + int32 distance; + int changed = 0; + // For all the nodes that have new values and a distance less than enddist + // ie dont check for new routes from a point we checked before or from a point + // that is already further away than the best route so far. + for (int32 i = 0; i < _nNodes; i++) { + if ((_node[i].dist < _node[_nNodes].dist) && (_node[i].level == level)) { + int16 x1 = _node[i].x; + int16 y1 = _node[i].y; + + for (int32 k = _nNodes; k > 0; k--) { + if (_node[k].dist > _node[i].dist) { + int16 x2 = _node[k].x; + int16 y2 = _node[k].y; + if (abs(x2 - x1) > (4.5 * abs(y2 - y1))) + distance = (8 * abs(x2 - x1) + 18 * abs(y2 - y1)) / (54 * 8) + 1; + else + distance = (6 * abs(x2 - x1) + 36 * abs(y2 - y1)) / (36 * 14) + 1; + + if ((distance + _node[i].dist < _node[_nNodes].dist) && (distance + _node[i].dist < _node[k].dist)) { + //if (int temp = newCheck(0, x1, y1, x2, y2)) { + if (newCheck(0, x1, y1, x2, y2)) { + _node[k].level = level + 1; + _node[k].dist = distance + _node[i].dist; + _node[k].prev = i; + changed = 1; + } + } + } + } + } + } + return changed; +} + +/******************************************************************************* + * NewCheck routine checks if the route between two points can be achieved + * without crossing any of the bars in the Bars array. + * + * NewCheck differs from check in that that 4 route options are considered + * corresponding to actual walked routes. + * + * Note distance doesnt take account of shrinking ??? + * + * Note Bars array must be properly calculated ie min max dx dy co + *******************************************************************************/ +int SwordRouter::newCheck(int32 status, int16 x1, int16 x2, int16 y1, int16 y2) { + + int32 ldx; + int32 ldy; + int32 dlx; + int32 dly; + int32 dirX; + int32 dirY; + int32 step1; + int32 step2; + int32 step3; + int32 steps; + int32 options; + + steps = 0; + options = 0; + ldx = x2 - x1; + ldy = y2 - y1; + dirX = 1; + dirY = 1; + + if (ldx < 0) { + ldx = -ldx; + dirX = -1; + } + + if (ldy < 0) { + ldy = -ldy; + dirY = -1; + } + + // make the route options + + if (_diagonaly * ldx > _diagonalx * ldy) { + // dir = 1,2 or 2,3 or 5,6 or 6,7 + + dly = ldy; + dlx = (ldy * _diagonalx) / _diagonaly; + ldx = ldx - dlx; + dlx = dlx * dirX; + dly = dly * dirY; + ldx = ldx * dirX; + ldy = 0; + + //options are + //square, diagonal a code 1 route + + step1 = check(x1, y1, x1 + ldx, y1); + if (step1 != 0) { + step2 = check(x1 + ldx, y1, x2, y2); + if (step2 != 0) { + steps = step1 + step2; + options = options + 2; + } + } + + //diagonal, square a code 2 route + + if (steps == 0 || status == 1) { + step1 = check(x1, y1, x1 + dlx, y1 + dly); + if (step1 != 0) { + step2 = check(x1 + dlx, y2, x2, y2); + if (step2 != 0) { + steps = step1 + step2; + options = options + 4; + } + } + } + + //halfsquare, diagonal, halfsquare a code 0 route + + if (steps == 0 || status == 1) { + step1 = check(x1, y1, x1 + ldx / 2, y1); + if (step1 != 0) { + step2 = check(x1 + ldx / 2, y1, x1 + ldx / 2 + dlx, y2); + if (step2 != 0) { + step3 = check(x1 + ldx / 2 + dlx, y2, x2, y2); + if (step3 != 0) { + steps = step1 + step2 + step3; + options++; + } + } + } + } + + //halfdiagonal, square, halfdiagonal a code 3 route + + if (steps == 0 || status == 1) { + step1 = check(x1, y1, x1 + dlx / 2, y1 + dly / 2); + if (step1 != 0) { + step2 = check(x1 + dlx / 2, y1 + dly / 2, x1 + ldx + dlx / 2, y1 + dly / 2); + if (step2 != 0) { + step3 = check(x1 + ldx + dlx / 2, y1 + dly / 2, x2, y2); + if (step3 != 0) { + steps = step1 + step2 + step3; + options = options + 8; + } + } + } + } + } else { + // dir = 7,0 or 0,1 or 3,4 or 4,5 + + dlx = ldx; + dly = (ldx * _diagonaly) / _diagonalx; + ldy = ldy - dly; + dlx = dlx * dirX; + dly = dly * dirY; + ldy = ldy * dirY; + ldx = 0; + + //options are + //square, diagonal a code 1 route + + step1 = check(x1 ,y1, x1, y1 + ldy); + if (step1 != 0) { + step2 = check(x1, y1 + ldy, x2, y2); + if (step2 != 0) { + steps = step1 + step2; + options = options + 2; + } + } + + //diagonal, square a code 2 route + + if (steps == 0 || status == 1) { + step1 = check(x1, y1, x2, y1 + dly); + if (step1 != 0) { + step2 = check(x2, y1 + dly, x2, y2); + if (step2 != 0) { + steps = step1 + step2; + options = options + 4; + } + } + } + + //halfsquare, diagonal, halfsquare a code 0 route + + if (steps == 0 || status == 1) { + step1 = check(x1, y1, x1, y1 + ldy / 2); + if (step1 != 0) { + step2 = check(x1, y1 + ldy / 2, x2, y1 + ldy / 2 + dly); + if (step2 != 0) { + step3 = check(x2, y1 + ldy / 2 + dly, x2, y2); + if (step3 != 0) { + steps = step1 + step2 + step3; + options++; + } + } + } + } + + //halfdiagonal, square, halfdiagonal a code 3 route + + if (steps == 0 || status == 1) { + step1 = check(x1, y1, x1 + dlx / 2, y1 + dly / 2); + if (step1 != 0) { + step2 = check(x1 + dlx / 2, y1 + dly / 2, x1 + dlx / 2, y1 + ldy + dly / 2); + if (step2 != 0) { + step3 = check(x1 + dlx / 2, y1 + ldy + dly / 2, x2, y2); + if (step3 != 0) { + steps = step1 + step2 + step3; + options = options + 8; + } + } + } + } + } + + if (status == 0) + status = steps; + else + status = options; + + return status; +} + +int SwordRouter::check(int16 x1, int16 y1, int16 x2, int16 y2) { + //call the fastest line check for the given line + //returns 1 if line didn't cross any bars + int steps; + + if ((x1 == x2) && (y1 == y2)) + steps = 1; + else if (x1 == x2) + steps = vertCheck(x1, y1, y2); + else if (y1 == y2) + steps = horizCheck(x1, y1, x2); + else + steps = lineCheck(x1, y1, x2, y2); + return steps; +} + +int SwordRouter::horizCheck(int16 x1, int16 y, int16 x2) { + int32 ldy; + int32 i; + int32 xc; + int32 xmin; + int32 xmax; + int32 linesCrossed = 1; + + if (x1 > x2) { + xmin = x2; + xmax = x1; + } else { + xmin = x1; + xmax = x2; + } + + // line set to go one step in chosen direction + // so ignore if it hits anything + + i = 0; + + do { + // skip if not on module + if (xmax >= _bars[i].xmin && xmin <= _bars[i].xmax) { + // skip if not on module + if (y >= _bars[i].ymin && y <= _bars[i].ymax) { + // okay its a valid line calculate an intercept + // wow but all this arithmetic we must have + // loads of time + + if (_bars[i].dy == 0) + linesCrossed = 0; + else { + ldy = y - _bars[i].y1; + xc = _bars[i].x1 + (_bars[i].dx * ldy) / _bars[i].dy; + // skip if not on module + if (xc >= xmin - 1 && xc <= xmax + 1) + linesCrossed = 0; + } + } + } + i++; + } while (i < _nBars && linesCrossed); + + return linesCrossed; +} + +int SwordRouter::vertCheck(int16 x, int16 y1, int16 y2) { + int32 ldx; + int32 i; + int32 yc; + int32 ymin; + int32 ymax; + int32 linesCrossed = 1; + + if (y1 > y2) { + ymin = y2; + ymax = y1; + } else { + ymin = y1; + ymax = y2; + } + + // line set to go one step in chosen direction + // so ignore if it hits anything + + i = 0; + + do { + if (x >= _bars[i].xmin && x <= _bars[i].xmax) { + // overlapping + // skip if not on module + if (ymax >= _bars[i].ymin && ymin <= _bars[i].ymax) { + // okay its a valid line calculate an intercept + // wow but all this arithmetic we must have + // loads of time + + // both lines vertical and overlap in x and y + // so they cross + + if (_bars[i].dx == 0) + linesCrossed = 0; + else { + ldx = x - _bars[i].x1; + yc = _bars[i].y1 + (_bars[i].dy * ldx) / _bars[i].dx; + // the intercept overlaps + if (yc >= ymin - 1 && yc <= ymax + 1) + linesCrossed = 0; + } + } + } + i++; + } while (i < _nBars && linesCrossed); + + return linesCrossed; +} + +int SwordRouter::lineCheck(int16 x1, int16 y1, int16 x2, int16 y2) { + int32 dirx; + int32 diry; + int32 co; + int32 slope; + int32 i; + int32 xc; + int32 yc; + int32 xmin; + int32 ymin; + int32 xmax; + int32 ymax; + int32 linesCrossed = 1; + + if (x1 > x2) { + xmin = x2; + xmax = x1; + } else { + xmin = x1; + xmax = x2; + } + + if (y1 > y2) { + ymin = y2; + ymax = y1; + } else { + ymin = y1; + ymax = y2; + } + + // line set to go one step in chosen direction + // so ignore if it hits anything + + dirx = x2 - x1; + diry = y2 - y1; + + co = (y1 * dirx)- (x1 * diry); // new line equation + + i = 0; + + do { + // skip if not on module + if (xmax >= _bars[i].xmin && xmin <= _bars[i].xmax) { + // skip if not on module + if (ymax >= _bars[i].ymin && ymin <= _bars[i].ymax) { + // okay its a valid line calculate an intercept + // wow but all this arithmetic we must have + // loads of time + + // slope it he slope between the two lines + slope = (_bars[i].dx * diry) - (_bars[i].dy *dirx); + // assuming parallel lines don't cross + if (slope != 0) { + // calculate x intercept and check its + // on both lines + xc = ((_bars[i].co * dirx) - (co * _bars[i].dx)) / slope; + + // skip if not on module + if (xc >= xmin - 1 && xc <= xmax + 1) { + // skip if not on line + if (xc >= _bars[i].xmin - 1 && xc <= _bars[i].xmax + 1) { + yc = ((_bars[i].co * diry) - (co * _bars[i].dy)) / slope; + + // skip if not on module + if (yc >= ymin - 1 && yc <= ymax + 1) { + // skip if not on line + if (yc >= _bars[i].ymin - 1 && yc <= _bars[i].ymax + 1) { + linesCrossed = 0; + } + } + } + } + } + } + } + i++; + } while (i < _nBars && linesCrossed); + + return linesCrossed; +} + +int SwordRouter::checkTarget(int16 x, int16 y) { + int32 dx, dy, xc, yc, xmin, xmax, ymin, ymax; + int32 onLine = 0; + + xmin = x - 1; + xmax = x + 1; + ymin = y - 1; + ymax = y + 1; + + for (int i = 0; (i < _nBars) && (onLine == 0); i++) { + if ((xmax >= _bars[i].xmin) && (xmin <= _bars[i].xmax)) { //overlapping line + if ((ymax >= _bars[i].ymin) && ( ymin <= _bars[i].ymax)) { //overlapping line + // okay this line overlaps the target, calculate an y intersept for x + + if (_bars[i].dx == 0) // vertical line so we know it overlaps y + yc = 0; + else { + dx = x - _bars[i].x1; + yc = _bars[i].y1 + (_bars[i].dy * dx) / _bars[i].dx; + } + if ((yc >= ymin) && (yc <= ymax)) //overlapping point for y + onLine = 3; // target on a line so drop out + else { + if (_bars[i].dy == 0) // vertical line so we know it overlaps y + xc = 0; + else { + dy = y- _bars[i].y1; + xc = _bars[i].x1 + (_bars[i].dx * dy) / _bars[i].dy; + } + if ((xc >= xmin) && (xc <= xmax)) //skip if not on module + onLine = 3;// target on a line so drop out + } + } + } + } + return onLine; +} + +void SwordRouter::resetExtraData(void) { + _numExtraBars = _numExtraNodes = 0; +} + +void SwordRouter::setPlayerTarget(int32 x, int32 y, int32 dir, int32 stance) { + _playerTargetX = x; + _playerTargetY = y; + _playerTargetDir = dir; + _playerTargetStance = stance; +} + +void SwordRouter::loadWalkResources(int32 megaId, BsObject *mega, int32 x, int32 y, int32 dir) { + WalkGridHeader *floorHeader; + + int32 walkGridId = _objMan->fetchObject(mega->o_place)->o_resource; + + uint8 *fPolyGrid = (uint8*)_resMan->openFetchRes(walkGridId); + floorHeader = (WalkGridHeader*)(fPolyGrid + sizeof(Header)); + fPolyGrid += sizeof(WalkGridHeader) + sizeof(Header); + + _nBars = FROM_LE_32(floorHeader->numBars); + _nNodes = FROM_LE_32(floorHeader->numNodes) + 1; + if ((_nBars >= O_GRID_SIZE) || (_nNodes >= O_GRID_SIZE)) + error("loadWalkResources: resource has %d bars and %d nodes", _nBars, _nNodes); + + for (int32 cnt = 0; cnt < _nBars; cnt++) { + _bars[cnt].x1 = READ_LE_UINT16(fPolyGrid); fPolyGrid += 2; + _bars[cnt].y1 = READ_LE_UINT16(fPolyGrid); fPolyGrid += 2; + _bars[cnt].x2 = READ_LE_UINT16(fPolyGrid); fPolyGrid += 2; + _bars[cnt].y2 = READ_LE_UINT16(fPolyGrid); fPolyGrid += 2; + _bars[cnt].xmin = READ_LE_UINT16(fPolyGrid); fPolyGrid += 2; + _bars[cnt].ymin = READ_LE_UINT16(fPolyGrid); fPolyGrid += 2; + _bars[cnt].xmax = READ_LE_UINT16(fPolyGrid); fPolyGrid += 2; + _bars[cnt].ymax = READ_LE_UINT16(fPolyGrid); fPolyGrid += 2; + _bars[cnt].dx = READ_LE_UINT16(fPolyGrid); fPolyGrid += 2; + _bars[cnt].dy = READ_LE_UINT16(fPolyGrid); fPolyGrid += 2; + _bars[cnt].co = READ_LE_UINT32(fPolyGrid); fPolyGrid += 4; + } + //_nBars = 0; + + // leave node 0 for start node + for (int32 cnt = 1; cnt < _nNodes; cnt++) { + _node[cnt].x = READ_LE_UINT16(fPolyGrid); fPolyGrid += 2; + _node[cnt].y = READ_LE_UINT16(fPolyGrid); fPolyGrid += 2; + } + _resMan->resClose(walkGridId); + + // floor grid loaded. Copy george's extra bars and nodes. + if (megaId == GEORGE) { + memcpy(_bars + _nBars, _extraBars, _numExtraBars * sizeof(BarData)); + _nBars += _numExtraBars; + for (int32 cnt = 0; cnt < _numExtraNodes; cnt++) { + _node[_nNodes + cnt].x = _extraNodes[cnt].x; + _node[_nNodes + cnt].y = _extraNodes[cnt].y; + } + _nNodes += _numExtraNodes; + } + + uint8 *walkData = (uint8*)_resMan->openFetchRes(mega->o_mega_resource); + _nWalkFrames = walkData[0]; + _nTurnFrames = walkData[1]; + walkData += 2; + + for (int32 cnt = 0; cnt < NO_DIRECTIONS * (_nWalkFrames + 1 + _nTurnFrames); cnt++) { + _dx[cnt] = READ_LE_UINT32(walkData); + walkData += 4; + } + for (int32 cnt = 0; cnt < NO_DIRECTIONS * (_nWalkFrames + 1 + _nTurnFrames); cnt++) { + _dy[cnt] = READ_LE_UINT32(walkData); + walkData += 4; + } + for (int32 cnt = 0; cnt < NO_DIRECTIONS; cnt++) { + _modX[cnt] = READ_LE_UINT32(walkData); + walkData += 4; + } + for (int32 cnt = 0; cnt < NO_DIRECTIONS; cnt++) { + _modY[cnt] = READ_LE_UINT32(walkData); + walkData += 4; + } + _resMan->resClose(mega->o_mega_resource); + _diagonalx = _modX[3]; + _diagonaly = _modY[3]; + if ((_diagonalx != 36) || (_diagonaly != 8)) + warning("DiagX = %d, DiagY = %d", _diagonalx, _diagonaly); + // mega data ready + // finish setting grid by putting mega node at begining + // and target node at end and reset current values + + _node[0].x = mega->o_xcoord; // the start + _node[0].y = mega->o_ycoord; // + _node[0].dist = 0; + _node[0].prev = 0; + _node[0].level = 1; + + for (int32 cnt = 1; cnt <= _nNodes; cnt++) { + _node[cnt].dist = 9999; + _node[cnt].prev = 0; + _node[cnt].level = 0; + } + _node[_nNodes].x = x; // the destination + _node[_nNodes].y = y; // +} + +int SwordRouter::whatTarget(int32 startX, int32 startY, int32 destX, int32 destY) { + int tar_dir; +//setting up + int deltaX = destX-startX; + int deltaY = destY-startY; + int signX = (deltaX > 0); + int signY = (deltaY > 0); + int slope; + + if ( (abs(deltaY) * _diagonalx ) < (abs(deltaX) * _diagonaly / 2)) + slope = 0;// its flat + else if ( (abs(deltaY) * _diagonalx / 2) > (abs(deltaX) * _diagonaly ) ) + slope = 2;// its vertical + else + slope = 1;// its diagonal + + if (slope == 0) { //flat + if (signX == 1) // going right + tar_dir = 2; + else + tar_dir = 6; + } else if (slope == 2) { //vertical + if (signY == 1) // going down + tar_dir = 4; + else + tar_dir = 0; + } else if (signX == 1) { //right diagonal + if (signY == 1) // going down + tar_dir = 3; + else + tar_dir = 1; + } else { //left diagonal + if (signY == 1) // going down + tar_dir = 5; + else + tar_dir = 7; + } + return tar_dir; +} diff --git a/sword1/router.h b/sword1/router.h new file mode 100644 index 0000000000..bb1ac17bea --- /dev/null +++ b/sword1/router.h @@ -0,0 +1,161 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) Revolution Software Ltd. + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#ifndef BSROUTER_H +#define BSROUTER_H + +#include "scummsys.h" +#include "object.h" + +#define EXTRA_GRID_SIZE 20 +#define O_GRID_SIZE 200 + +#if !defined(__GNUC__) + #pragma START_PACK_STRUCTS +#endif + +struct BarData { + int16 x1; + int16 y1; + int16 x2; + int16 y2; + int16 xmin; + int16 ymin; + int16 xmax; + int16 ymax; + int16 dx; // x2 - x1 + int16 dy; // y2 - y1 + int32 co; // co = (y1 *dx)- (x1*dy) from an equation for a line y*dx = x*dy + co +} GCC_PACK; + +struct NodeData { + int16 x; + int16 y; + int16 level; + int16 prev; + int16 dist; +} GCC_PACK; + +#if !defined(__GNUC__) + #pragma END_PACK_STRUCTS +#endif + +struct FloorData { + int32 nbars; + BarData *bars; + int32 nnodes; + NodeData *node; +}; + +struct RouteData { + int32 x; + int32 y; + int32 dirS; + int32 dirD; +}; + +struct PathData { + int32 x; + int32 y; + int32 dir; + int32 num; +}; + +struct FrameInfos { + int32 framesPerStep, framesPerChar; + int32 standFrames; + int32 slowInFrames, slowOutFrames; + int32 turnFramesLeft, turnFramesRight; + int32 walkFramesLeft, walkFramesRight; + uint16 startX, startY, targetX, targetY, targetDir; + int32 scaleA, scaleB; +}; + +#define ROUTE_END_FLAG 255 +#define NO_DIRECTIONS 8 +#define MAX_FRAMES_PER_CYCLE 16 +#define MAX_FRAMES_PER_CHAR (MAX_FRAMES_PER_CYCLE * NO_DIRECTIONS) +#define O_ROUTE_SIZE 50 + +class ObjectMan; +class ResMan; + +class SwordRouter { +public: + SwordRouter(ObjectMan *pObjMan, ResMan *pResMan); + ~SwordRouter(void); + int routeFinder(int32 id, BsObject *mega, int32 x, int32 y, int32 dir); + int whatTarget(int32 startX, int32 startY, int32 destX, int32 destY); + void setPlayerTarget(int32 x, int32 y, int32 dir, int32 stance); + void resetExtraData(void); + + // these should be private but are read by SwordScreen for debugging: + int32 _nBars, _nNodes; + BarData _bars[O_GRID_SIZE + EXTRA_GRID_SIZE]; + NodeData _node[O_GRID_SIZE + EXTRA_GRID_SIZE]; +private: + // when the player collides with another mega, we'll receive a ReRouteRequest here. + // that's why we need to remember the player's target coordinates + int32 _playerTargetX, _playerTargetY, _playerTargetDir, _playerTargetStance; + // additional route data to block parts of the floor and enable routine around megas: + int32 _numExtraBars, _numExtraNodes; + BarData _extraBars[EXTRA_GRID_SIZE]; + NodeData _extraNodes[EXTRA_GRID_SIZE]; + ObjectMan *_objMan; + ResMan *_resMan; + + uint8 _nWalkFrames, _nTurnFrames; + int32 _dx[NO_DIRECTIONS + MAX_FRAMES_PER_CHAR]; + int32 _dy[NO_DIRECTIONS + MAX_FRAMES_PER_CHAR]; + int32 _modX[NO_DIRECTIONS]; + int32 _modY[NO_DIRECTIONS]; + int32 _diagonalx, _diagonaly; + + RouteData _route[O_ROUTE_SIZE]; + //int32 _routeLength; + PathData _smoothPath[O_ROUTE_SIZE]; + PathData _modularPath[O_ROUTE_SIZE]; + + + void loadWalkResources(int32 megaId, BsObject *mega, int32 x, int32 y, int32 targetDir); + int getRoute(void); + int checkTarget(int16 x, int16 y); + + int scan(int32 level); + int newCheck(int32 status, int16 x1, int16 x2, int16 y1, int16 y2); + int check(int16 x1, int16 y1, int16 x2, int16 y2); + int horizCheck(int16 x1, int16 y, int16 x2); + int vertCheck(int16 x, int16 y1, int16 y2); + int lineCheck(int16 x1, int16 y1, int16 x2, int16 y2); + + int32 extractRoute(int32 targetDir); + + void slidyPath(int32 scaleA, int32 scaleB, uint16 targetDir); + void slidyWalkAnimator(WalkData *walkAnim, FrameInfos *frInfo, int32 megaId); + + int32 smoothestPath(uint16 startX, uint16 startY, uint16 startDir, int32 routeLength); + int32 smoothCheck(int32 best, int32 p, int32 dirS, int32 dirD); + + int32 solidPath(int32 scaleA, int32 scaleB); + int32 solidWalkAnimator(WalkData *walkAnim, FrameInfos *frInfo, int32 megaId); +}; + +#endif //BSROUTER_H diff --git a/sword1/screen.cpp b/sword1/screen.cpp new file mode 100644 index 0000000000..17ad57ce30 --- /dev/null +++ b/sword1/screen.cpp @@ -0,0 +1,884 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#include "stdafx.h" +#include "screen.h" +#include "logic.h" +#include "sworddefs.h" +#include "text.h" +#include "resman.h" +#include "objectman.h" +#include "scummsys.h" +#include "common/util.h" +#include "system.h" +#include "router.h" + +#define SCROLL_FRACTION 16 +#define MAX_SCROLL_DISTANCE 8 +#define FADE_UP 1 +#define FADE_DOWN -1 + +SwordScreen::SwordScreen(OSystem *system, ResMan *pResMan, ObjectMan *pObjMan) { + _system = system; + _resMan = pResMan; + _objMan = pObjMan; + _screenBuf = _screenGrid = NULL; + _backLength = _foreLength = _sortLength = 0; + _fadingStep = 0; +} + +void SwordScreen::useTextManager(SwordText *pTextMan) { + _textMan = pTextMan; +} + +int32 SwordScreen::inRange(int32 a, int32 b, int32 c) { // return b(!) so that: a <= b <= c + return (a > b) ? (a) : ((b < c) ? b : c); +} + +void SwordScreen::setScrolling(int16 offsetX, int16 offsetY) { + if (!SwordLogic::_scriptVars[SCROLL_FLAG]) + return ; // screen is smaller than 640x400 => no need for scrolling + + int32 dx, dy; + uint32 scrlDistX, scrlDistY; + uint32 scrlToX, scrlToY; + + offsetX = inRange(0, offsetX, SwordLogic::_scriptVars[MAX_SCROLL_OFFSET_X]); + offsetY = inRange(0, offsetY, SwordLogic::_scriptVars[MAX_SCROLL_OFFSET_Y]); + _oldScrollX = SwordLogic::_scriptVars[SCROLL_OFFSET_X]; + _oldScrollY = SwordLogic::_scriptVars[SCROLL_OFFSET_Y]; + + if (SwordLogic::_scriptVars[SCROLL_FLAG] == 2) { // first time on this screen - need absolute scroll immediately! + scrlToX = (uint32)offsetX; + scrlToY = (uint32)offsetY; + } else { // catch up with required scroll offsets - speed depending on distance to catch up (dx and dy) & 'SCROLL_FRACTION' used + // but limit to certain number of pixels per cycle (MAX_SCROLL_DISTANCE) + dx = SwordLogic::_scriptVars[SCROLL_OFFSET_X] - offsetX; + dy = SwordLogic::_scriptVars[SCROLL_OFFSET_Y] - offsetY; + int8 sig = (dx < 0) ? (-1) : 1; + if (dx < 0) + dx = -dx; + scrlDistX = 1 + dx/SCROLL_FRACTION; + scrlDistX = inRange(0, scrlDistX, MAX_SCROLL_DISTANCE); + scrlToX = SwordLogic::_scriptVars[SCROLL_OFFSET_X] + sig * scrlDistX; + + sig = (dy < 0) ? (-1) : 1; + if (dy < 0) + dy = -dy; + scrlDistY = 1 + dy/SCROLL_FRACTION; + scrlDistY = inRange(0, scrlDistY, MAX_SCROLL_DISTANCE); + scrlToY = SwordLogic::_scriptVars[SCROLL_OFFSET_Y] + sig * scrlDistY; + } + scrlToX = inRange(0, scrlToX, SwordLogic::_scriptVars[MAX_SCROLL_OFFSET_X]); + scrlToY = inRange(0, scrlToY, SwordLogic::_scriptVars[MAX_SCROLL_OFFSET_Y]); + if ((scrlToX != SwordLogic::_scriptVars[SCROLL_OFFSET_X]) || (scrlToY != SwordLogic::_scriptVars[SCROLL_OFFSET_Y])) { + _fullRefresh = true; + SwordLogic::_scriptVars[SCROLL_OFFSET_X] = scrlToX; + SwordLogic::_scriptVars[SCROLL_OFFSET_Y] = scrlToY; + } else + _fullRefresh = false; + if (SwordLogic::_scriptVars[SCROLL_FLAG] == 2) { + _oldScrollX = scrlToX; + _oldScrollY = scrlToY; + SwordLogic::_scriptVars[SCROLL_FLAG] = 1; + } +} + +void SwordScreen::fadeDownPalette(void) { + _fadingStep = 15; + _fadingDirection = FADE_DOWN; +} + +void SwordScreen::fadeUpPalette(void) { + _fadingStep = 15; + _fadingDirection = FADE_UP; +} + +void SwordScreen::fnSetPalette(uint8 start, uint16 length, uint8 *data) { + memcpy(_targetPalette + start * 3, data, length * 3); + _system->set_palette(data, start, length); +} + +void SwordScreen::fnSetFadeTargetPalette(uint8 start, uint16 length, uint8 *data) { + memcpy(_targetPalette + start * 3, data, length * 3); + debug(1, "fnSetFadeTargetPalette called"); +} + +bool SwordScreen::stillFading(void) { + return (_fadingStep > 0); +} + +void SwordScreen::updateScreen(void) { + if (SwordLogic::_scriptVars[NEW_PALETTE]) { + _fadingStep = 1; + _fadingDirection = FADE_UP; + memcpy(_targetPalette, _resMan->openFetchRes(_roomDefTable[_currentScreen].palettes[0]), 184 * 3); // set colours 0-183 for background palette + _resMan->resClose(_roomDefTable[_currentScreen].palettes[0]); + memcpy(_targetPalette + 184 * 3, _resMan->openFetchRes(_roomDefTable[_currentScreen].palettes[1]), 72 * 3); // set colours 184-255 for sprite palette - george, icons & menubar + _resMan->resClose(_roomDefTable[_currentScreen].palettes[1]); + SwordLogic::_scriptVars[NEW_PALETTE] = 0; + } + if (_fadingStep) { + fadePalette(); + _system->set_palette(_currentPalette, 0, 256); + } + + uint16 scrlX = (uint16)SwordLogic::_scriptVars[SCROLL_OFFSET_X]; + uint16 scrlY = (uint16)SwordLogic::_scriptVars[SCROLL_OFFSET_Y]; + _fullRefresh = true; + if (_fullRefresh) { + _fullRefresh = false; + uint16 copyWidth = SCREEN_WIDTH; + uint16 copyHeight = SCREEN_DEPTH; + if (scrlX + copyWidth > _scrnSizeX) + copyWidth = _scrnSizeX - scrlX; + if (scrlY + copyHeight > _scrnSizeY) + copyHeight = _scrnSizeY - scrlY; + _system->copy_rect(_screenBuf + scrlY * _scrnSizeX + scrlX, _scrnSizeX, 0, 40, copyWidth, copyHeight); + } else { + // partial screen update only. The screen coordinates probably won't fit to the + // grid holding the informations on which blocks have to be updated. + // as the grid will be X pixel higher and Y pixel more to the left, this can be cured + // by first checking the top border, then the left column and then the remaining (aligned) part. + uint8 *gridPos = _screenGrid + (scrlX / SCRNGRID_X) + (scrlY / SCRNGRID_Y) * _gridSizeX; + uint8 *scrnBuf = _screenBuf + scrlY * _scrnSizeX + scrlX; + uint8 diffX = (uint8)(scrlX % SCRNGRID_X); + uint8 diffY = (uint8)(scrlY % SCRNGRID_Y); + uint16 gridW = SCREEN_WIDTH / SCRNGRID_X; + uint16 gridH = SCREEN_DEPTH / SCRNGRID_Y; + if (diffY) { + uint8 cpHeight = SCRNGRID_Y - diffY; + uint16 cpWidth = 0; + for (uint16 cntx = 0; cntx < gridW; cntx++) + if (gridPos[cntx] & 1) { + gridPos[cntx] &= ~1; + cpWidth++; + } else if (cpWidth) { + int16 xPos = (cntx - cpWidth) * SCRNGRID_X - diffX; + if (xPos < 0) + xPos = 0; + _system->copy_rect(scrnBuf + xPos, _scrnSizeX, xPos, 40, cpWidth * SCRNGRID_X, cpHeight); + cpWidth = 0; + } + if (cpWidth) { + int16 xPos = (gridW - cpWidth) * SCRNGRID_X - diffX; + if (xPos < 0) + xPos = 0; + _system->copy_rect(scrnBuf + xPos, _scrnSizeX, xPos, 40, SCREEN_WIDTH - xPos, cpHeight); + } + } // okay, y scrolling is compensated. check x now. + gridPos += _gridSizeX; + scrnBuf = _screenBuf + scrlX + diffY * _scrnSizeX; + if (diffX) { + uint8 cpWidth = SCRNGRID_X - diffX; + uint16 cpHeight = 0; + for (uint16 cnty = 0; cnty < gridH; cnty++) + if (gridPos[cnty * SCRNGRID_X] & 1) { + gridPos[cnty * SCRNGRID_X] &= ~1; + cpHeight++; + } else if (cpHeight) { + uint16 yPos = (cnty - cpHeight) * SCRNGRID_Y; + _system->copy_rect(scrnBuf + yPos * _scrnSizeX, _scrnSizeX, 0, yPos + diffY + 40, cpWidth, cpHeight * SCRNGRID_Y); + } + if (cpHeight) { + uint16 yPos = (gridH - cpHeight) * SCRNGRID_Y; + _system->copy_rect(scrnBuf + yPos * _scrnSizeX, _scrnSizeX, 0, yPos + diffY + 40, cpWidth, SCREEN_DEPTH - (yPos + diffY)); + } + } // x scroll is compensated, too. check the rest of the screen, now. + scrlX = (scrlX + SCRNGRID_X - 1) &~ (SCRNGRID_X - 1); + scrlY = (scrlY + SCRNGRID_Y - 1) &~ (SCRNGRID_Y - 1); + scrnBuf = _screenBuf + scrlY * _scrnSizeX + scrlX; + gridPos++; + for (uint16 cnty = 0; cnty < gridH; cnty++) { + uint16 cpWidth = 0; + uint16 cpHeight = SCRNGRID_Y; + if (cnty == gridH - 1) + cpHeight = SCRNGRID_Y - diffY; + for (uint16 cntx = 0; cntx < gridW; cntx++) + if (gridPos[cntx] & 1) { + gridPos[cntx] &= ~1; + cpWidth++; + } else if (cpWidth) { + _system->copy_rect(scrnBuf + (cntx - cpWidth) * SCRNGRID_X, _scrnSizeX, (cntx - cpWidth) * SCRNGRID_X + diffX, cnty * SCRNGRID_Y + diffY + 40, cpWidth * SCRNGRID_X, cpHeight); + } + if (cpWidth) { + uint16 xPos = (gridW - cpWidth) * SCRNGRID_X; + _system->copy_rect(scrnBuf + xPos, _scrnSizeX, xPos + diffX, cnty * SCRNGRID_Y + diffY + 40, SCREEN_WIDTH - (xPos + diffX), cpHeight); + } + gridPos += _gridSizeX; + scrnBuf += _scrnSizeX * SCRNGRID_Y; + } + } + _system->update_screen(); +} + +void SwordScreen::newScreen(uint32 screen) { + // set sizes and scrolling, initialize/load screengrid, force screen refresh + // force palette fadeup? + _currentScreen = screen; + _scrnSizeX = _roomDefTable[screen].sizeX; + _scrnSizeY = _roomDefTable[screen].sizeY; + _gridSizeX = _scrnSizeX / SCRNGRID_X; + _gridSizeY = _scrnSizeY / SCRNGRID_Y; + if ((_scrnSizeX % SCRNGRID_X) || (_scrnSizeY % SCRNGRID_Y)) + error("Illegal screensize: %d: %d/%d", screen, _scrnSizeX, _scrnSizeY); + if ((_scrnSizeX > SCREEN_WIDTH) || (_scrnSizeY > SCREEN_DEPTH)) { + SwordLogic::_scriptVars[SCROLL_FLAG] = 2; + SwordLogic::_scriptVars[MAX_SCROLL_OFFSET_X] = _scrnSizeX - SCREEN_WIDTH; + SwordLogic::_scriptVars[MAX_SCROLL_OFFSET_Y] = _scrnSizeY - SCREEN_DEPTH; + } else { + SwordLogic::_scriptVars[SCROLL_FLAG] = 0; + SwordLogic::_scriptVars[MAX_SCROLL_OFFSET_X] = 0; + SwordLogic::_scriptVars[MAX_SCROLL_OFFSET_Y] = 0; + SwordLogic::_scriptVars[SCROLL_OFFSET_X] = 0; + SwordLogic::_scriptVars[SCROLL_OFFSET_Y] = 0; + } + _screenBuf = (uint8*)malloc(_scrnSizeX * _scrnSizeY); + _screenGrid = (uint8*)malloc(_gridSizeX * _gridSizeY); + memset(_screenGrid, 0x80, _gridSizeX * _gridSizeY); // force refresh + for (uint8 cnt = 0; cnt < _roomDefTable[_currentScreen].totalLayers; cnt++) { + // open and lock all resources, will be closed in closeScreen() + _layerBlocks[cnt] = (uint8*)_resMan->openFetchRes(_roomDefTable[_currentScreen].layers[cnt]); + } + for (uint8 cnt = 0; cnt < _roomDefTable[_currentScreen].totalLayers - 1; cnt++) { + // there's no grid for the background layer, so it's totalLayers - 1 + _layerGrid[cnt] = (uint16*)_resMan->openFetchRes(_roomDefTable[_currentScreen].grids[cnt]); + _layerGrid[cnt] += 0x12; // not sure about the 0x12 + } + _parallax[0] = _parallax[1] = NULL; + if (_roomDefTable[_currentScreen].parallax[0]) + _parallax[0] = (uint8*)_resMan->openFetchRes(_roomDefTable[_currentScreen].parallax[0]); + if (_roomDefTable[_currentScreen].parallax[1]) + _parallax[1] = (uint8*)_resMan->openFetchRes(_roomDefTable[_currentScreen].parallax[1]); + + // TEMPORARY! + uint8 *bgPal = (uint8*)_resMan->openFetchRes(_roomDefTable[_currentScreen].palettes[0]); + uint8 *sprPal = (uint8*)_resMan->openFetchRes(_roomDefTable[_currentScreen].palettes[1]); + for (uint16 cnt = 0; cnt < 256; cnt++) { + _targetPalette[cnt * 4 + 0] = bgPal[cnt * 3 + 0] << 2; + _targetPalette[cnt * 4 + 1] = bgPal[cnt * 3 + 1] << 2; + _targetPalette[cnt * 4 + 2] = bgPal[cnt * 3 + 2] << 2; + } + /*for (uint16 cnt = 0; cnt < 72; cnt++) { + _targetPalette[(cnt + 184) * 4 + 0] = bgPal[cnt * 3 + 0]; + _targetPalette[(cnt + 184) * 4 + 1] = bgPal[cnt * 3 + 1]; + _targetPalette[(cnt + 184) * 4 + 2] = bgPal[cnt * 3 + 2]; + }*/ + _targetPalette[0] = _targetPalette[1] = _targetPalette[2] = 0; + _system->set_palette(_targetPalette, 0, 256); + _resMan->resClose(_roomDefTable[_currentScreen].palettes[0]); + _resMan->resClose(_roomDefTable[_currentScreen].palettes[1]); +} + +void SwordScreen::quitScreen(void) { + for (uint8 cnt = 0; cnt < _roomDefTable[_currentScreen].totalLayers; cnt++) + _resMan->resClose(_roomDefTable[_currentScreen].layers[cnt]); + for (uint8 cnt = 0; cnt < _roomDefTable[_currentScreen].totalLayers - 1; cnt++) + _resMan->resClose(_roomDefTable[_currentScreen].grids[cnt]); + if (_roomDefTable[_currentScreen].parallax[0]) + _resMan->resClose(_roomDefTable[_currentScreen].parallax[0]); + if (_roomDefTable[_currentScreen].parallax[1]) + _resMan->resClose(_roomDefTable[_currentScreen].parallax[1]); +} + +void SwordScreen::recreate() { + memcpy(_screenBuf, _layerBlocks[0], _scrnSizeX * _scrnSizeY); +} + +void SwordScreen::spritesAndParallax(void) { + if ((_currentScreen == 54) && _parallax[0]) + renderParallax(_parallax[0]); // rm54 has a BACKGROUND parallax layer in parallax[0] + + for (uint8 cnt = 0; cnt < _backLength; cnt++) + processImage(_backList[cnt]); + + SortSpr temp; + for (uint8 cnt = 0; cnt < _sortLength - 1; cnt++) + for (uint8 sCnt = 0; sCnt < _sortLength - 1; sCnt++) + if (_sortList[sCnt].y > _sortList[sCnt + 1].y) { + temp = _sortList[sCnt]; + _sortList[sCnt] = _sortList[sCnt + 1]; + _sortList[sCnt + 1] = temp; + } + for (uint8 cnt = 0; cnt < _sortLength; cnt++) + processImage(_sortList[cnt].id); + + if ((_currentScreen != 54) && _parallax[0]) + renderParallax(_parallax[0]); // screens other than 54 have FOREGROUND parallax layer in parallax[0] + if (_parallax[1]) + renderParallax(_parallax[1]); + + for (uint8 cnt = 0; cnt < _foreLength; cnt++) + processImage(_foreList[cnt]); + + _backLength = _sortLength = _foreLength = 0; +} + +void SwordScreen::processImage(uint32 id) { + BsObject *compact; + FrameHeader *frameHead; + int scale; + + compact = _objMan->fetchObject(id); + if (compact->o_type == TYPE_TEXT) + frameHead = _textMan->giveSpriteData((uint8)compact->o_target); + else + frameHead = _resMan->fetchFrame(_resMan->openFetchRes(compact->o_resource), compact->o_frame); + + uint8 *sprData = ((uint8*)frameHead) + sizeof(FrameHeader); + + uint16 spriteX = compact->o_anim_x; + uint16 spriteY = compact->o_anim_y; + if (compact->o_status & STAT_SHRINK) { + scale = (compact->o_scale_a * compact->o_ycoord + compact->o_scale_b) / 256; + spriteX += (FROM_LE_16(frameHead->offsetX) * scale) / 256; + spriteY += (FROM_LE_16(frameHead->offsetY) * scale) / 256; + } else { + scale = 256; + spriteX += FROM_LE_16(frameHead->offsetX); + spriteY += FROM_LE_16(frameHead->offsetY); + } + if (scale > 512) + debug(1, "compact %d is oversized: scale = %d", id, scale); + + uint8 *tonyBuf = NULL; + if (frameHead->runTimeComp[3] == '7') { // RLE7 encoded? + decompressRLE7(sprData, FROM_LE_32(frameHead->compSize), _rleBuffer); + sprData = _rleBuffer; + } else if (frameHead->runTimeComp[3] == '0') { // RLE0 encoded? + decompressRLE0(sprData, FROM_LE_32(frameHead->compSize), _rleBuffer, FROM_LE_16(frameHead->width)); + sprData = _rleBuffer; + } else if (frameHead->runTimeComp[1] == 'I') { // new type + tonyBuf = (uint8*)malloc(FROM_LE_16(frameHead->width) * FROM_LE_16(frameHead->height)); + decompressTony(sprData, FROM_LE_32(frameHead->compSize), tonyBuf); + sprData = tonyBuf; + } + + uint16 sprSizeX, sprSizeY; + if (compact->o_status & STAT_SHRINK) { + sprSizeX = (scale * FROM_LE_16(frameHead->width)) / 256; + sprSizeY = (scale * FROM_LE_16(frameHead->height)) / 256; + fastShrink(sprData, FROM_LE_16(frameHead->width), FROM_LE_16(frameHead->height), scale, _shrinkBuffer); + sprData = _shrinkBuffer; + } else { + sprSizeX = FROM_LE_16(frameHead->width); + sprSizeY = FROM_LE_16(frameHead->height); + } + if (!(compact->o_status & STAT_OVERRIDE)) { + //mouse size linked to exact size & coordinates of sprite box - shrink friendly + if ((frameHead->offsetX) || (frameHead->offsetY)) { + //for megas the mouse area is reduced to account for sprite not + //filling the box size is reduced to 1/2 width, 4/5 height + compact->o_mouse_x1 = spriteX + sprSizeX / 4; + compact->o_mouse_x2 = spriteX + (3 * sprSizeX) / 4; + compact->o_mouse_y1 = spriteY + sprSizeY / 10; + compact->o_mouse_y2 = spriteY + (9 * sprSizeY) / 10; + } else { + compact->o_mouse_x1 = spriteX; + compact->o_mouse_x2 = spriteX + sprSizeX; + compact->o_mouse_y1 = spriteY; + compact->o_mouse_y2 = spriteY + sprSizeY; + } + } + uint16 sprPitch = sprSizeX; + uint16 incr; + spriteClipAndSet(&spriteX, &spriteY, &sprSizeX, &sprSizeY, &incr); + if ((sprSizeX > 0) && (sprSizeY > 0)) { + drawSprite(sprData + incr, spriteX, spriteY, sprSizeX, sprSizeY, sprPitch); + if (!(compact->o_status&STAT_FORE)) + verticalMask(spriteX, spriteY, sprSizeX, sprSizeY); + } + if (compact->o_type != TYPE_TEXT) + _resMan->resClose(compact->o_resource); + if (tonyBuf) + free(tonyBuf); +} + +void SwordScreen::verticalMask(uint16 x, uint16 y, uint16 bWidth, uint16 bHeight) { + if (_roomDefTable[_currentScreen].totalLayers <= 1) + return; + bWidth = (bWidth + (SCRNGRID_X - 1)) / SCRNGRID_X; + bHeight = (bHeight + (SCRNGRID_Y - 1)) / SCRNGRID_Y; + + if (x & (SCRNGRID_X - 1)) + bWidth++; + if (y & (SCRNGRID_Y - 1)) + bHeight++; + + x /= SCRNGRID_X; + y /= SCRNGRID_Y; + if (x + bWidth > _gridSizeX) + bWidth = _gridSizeX - x; + if (y + bHeight > _gridSizeY) + bHeight = _gridSizeY - y; + + for (uint16 blkx = 0; blkx < bWidth; blkx++) { + for (uint8 z = 1; z < _roomDefTable[_currentScreen].totalLayers; z++) { // current layer + uint16 *grid = _layerGrid[z - 1] + x + blkx + y * _gridSizeX; + for (uint16 blky = 0; blky < bHeight; blky++) { + if (*grid) { + uint8 *blkData = _layerBlocks[z] + (READ_LE_UINT16(grid) - 1) * 128; + blitBlockClear(x + blkx, y + blky, blkData); + } + grid += _gridSizeX; + } + } + } +} + +void SwordScreen::blitBlockClear(uint16 x, uint16 y, uint8 *data) { + uint8 *dest = _screenBuf + (y * SCRNGRID_Y) * _scrnSizeX + (x * SCRNGRID_X); + for (uint8 cnty = 0; cnty < SCRNGRID_Y; cnty++) { + for (uint8 cntx = 0; cntx < SCRNGRID_X; cntx++) + if (data[cntx]) + dest[cntx] = data[cntx]; + data += SCRNGRID_X; + dest += _scrnSizeX; + } +} + +void SwordScreen::renderParallax(uint8 *data) { + ParallaxHeader *header = (ParallaxHeader*)data; + assert((FROM_LE_16(header->sizeX) >= SCREEN_WIDTH) && (FROM_LE_16(header->sizeY) >= SCREEN_DEPTH)); + double scrlfx = FROM_LE_16(header->sizeX) / ((double)_scrnSizeX ); + double scrlfy = FROM_LE_16(header->sizeY) / ((double)_scrnSizeY ); + uint16 scrlX = (uint16)(SwordLogic::_scriptVars[SCROLL_OFFSET_X] * scrlfx); + uint16 scrlY = (uint16)(SwordLogic::_scriptVars[SCROLL_OFFSET_Y] * scrlfy); + + for (uint16 cnty = 0; cnty < SCREEN_DEPTH; cnty++) { + uint8 *src = data + READ_LE_UINT32(header->lineIndexes + cnty + scrlY); + uint8 *dest = _screenBuf + SwordLogic::_scriptVars[SCROLL_OFFSET_X] + cnty * _scrnSizeX; + uint16 remain = scrlX; + uint16 xPos = 0; + bool copyFirst = false; + while (remain) { // skip past the first part of the parallax to get to the right scrolling position + uint8 doSkip = *src++; + if (doSkip <= remain) + remain -= doSkip; + else { + xPos = doSkip - remain; + dest += xPos; + remain = 0; + } + if (remain) { + uint8 doCopy = *src++; + if (doCopy <= remain) { + remain -= doCopy; + src += doCopy; + } else { + uint16 remCopy = doCopy - remain; + memcpy(dest, src + remain, remCopy); + dest += remCopy; + src += doCopy; + xPos = remCopy; + remain = 0; + } + } else + copyFirst = true; + } + while (xPos < SCREEN_WIDTH) { + if (!copyFirst) { + if (uint8 skip = *src++) { + dest += skip; + xPos += skip; + } + } else + copyFirst = false; + if (xPos < SCREEN_WIDTH) { + if (uint8 doCopy = *src++) { + if (xPos + doCopy > SCREEN_WIDTH) + doCopy = SCREEN_WIDTH - xPos; + memcpy(dest, src, doCopy); + dest += doCopy; + xPos += doCopy; + src += doCopy; + } + } + } + } +} + +void SwordScreen::drawSprite(uint8 *sprData, uint16 sprX, uint16 sprY, uint16 sprWidth, uint16 sprHeight, uint16 sprPitch) { + uint8 *dest = _screenBuf + (sprY * _scrnSizeX) + sprX; + for (uint16 cnty = 0; cnty < sprHeight; cnty++) { + for (uint16 cntx = 0; cntx < sprWidth; cntx++) + if (sprData[cntx]) + dest[cntx] = sprData[cntx]; + sprData += sprPitch; + dest += _scrnSizeX; + } +} + +// nearest neighbor filter: +void SwordScreen::fastShrink(uint8 *src, uint32 width, uint32 height, uint32 scale, uint8 *dest) { + uint32 resHeight = (height * scale) >> 8; + uint32 resWidth = (width * scale) >> 8; + uint32 step = 0x10000 / scale; + uint8 columnTab[160]; + uint32 res = step >> 1; + for (uint16 cnt = 0; cnt < resWidth; cnt++) { + columnTab[cnt] = (uint8)(res >> 8); + res += step; + } + + uint32 newRow = step >> 1; + uint32 oldRow = 0; + + uint8 *destPos = dest; + for (uint16 lnCnt = 0; lnCnt < resHeight; lnCnt++) { + while (oldRow < (newRow >> 8)) { + oldRow++; + src += width; + } + for (uint16 colCnt = 0; colCnt < resWidth; colCnt++) { + *destPos++ = src[columnTab[colCnt]]; + } + newRow += step; + } + // scaled, now stipple shadows if there are any + for (uint16 lnCnt = 0; lnCnt < resHeight; lnCnt++) { + uint16 xCnt = lnCnt & 1; + destPos = dest + lnCnt * resWidth + (lnCnt & 1); + while (xCnt < resWidth) { + if (*destPos == 200) + *destPos = 0; + destPos += 2; + xCnt += 2; + } + } +} + +void SwordScreen::addToGraphicList(uint8 listId, uint32 objId) { + if (listId == 0) { + _foreList[_foreLength++] = objId; + if (_foreLength > MAX_FORE) + error("foreList exceeded!"); + } + if (listId == 1) { + BsObject *cpt = _objMan->fetchObject(objId); + _sortList[_sortLength].id = objId; + _sortList[_sortLength].y = cpt->o_anim_y; // gives feet coords if boxed mega, otherwise top of sprite box + if (!(cpt->o_status & STAT_SHRINK)) { // not a boxed mega using shrinking + Header *frameRaw = (Header*)_resMan->openFetchRes(cpt->o_resource); + FrameHeader *frameHead = _resMan->fetchFrame(frameRaw, cpt->o_frame); + _sortList[_sortLength].y += frameHead->height - 1; // now pointing to base of sprite + _resMan->resClose(cpt->o_resource); + } + _sortLength++; + if (_sortLength > MAX_SORT) + error("sortList exceeded!"); + } + if (listId == 2) { + _backList[_backLength++] = objId; + if (_backLength > MAX_BACK) + error("backList exceeded!"); + } +} + +void SwordScreen::decompressTony(uint8 *src, uint32 compSize, uint8 *dest) { + uint8 *endOfData = src + compSize; + while (src < endOfData) { + uint8 numFlat = *src++; + if (numFlat) { + memset(dest, *src, numFlat); + src++; + dest += numFlat; + } + if (src < endOfData) { + uint8 numNoFlat = *src++; + memcpy(dest, src, numNoFlat); + src += numNoFlat; + dest += numNoFlat; + } + } +} + +void SwordScreen::decompressRLE7(uint8 *src, uint32 compSize, uint8 *dest) { + uint8 *compBufEnd = src + compSize; + while (src < compBufEnd) { + uint8 code = *src++; + if ((code > 127) || (code == 0)) + *dest++ = code; + else { + code++; + memset(dest, *src++, code); + dest += code; + } + } +} + +void SwordScreen::decompressRLE0(uint8 *src, uint32 compSize, uint8 *dest, uint16 width) { + // these are saved vertically flipped. *SIIIIIIIGH* + uint8 *srcBufEnd = src + compSize; + uint16 destX = width-1; + while (src < srcBufEnd) { + uint8 color = *src++; + if (color) { + dest[destX] = color; + if (destX == 0) { + destX = width-1; + dest += width; + } else + destX--; + } else { + uint8 skip = *src++; + for (uint16 cnt = 0; cnt < skip; cnt++) { + dest[destX] = 0; + if (destX == 0) { + destX = width-1; + dest += width; + } else + destX--; + } + } + } +} + +void SwordScreen::fadePalette(void) { + if (_fadingStep == 16) + memcpy(_currentPalette, _targetPalette, 256 * 4); + else + for (uint16 cnt = 0; cnt < 256 * 4; cnt++) + _currentPalette[cnt] = (_targetPalette[cnt] * _fadingStep) >> 4; + + _fadingStep += _fadingDirection; + if (_fadingStep == 17) + _fadingStep = 0; +} + +void SwordScreen::fnSetParallax(uint32 screen, uint32 resId) { + if ((screen == _currentScreen) && (resId != _roomDefTable[screen].parallax[0])) + warning("fnSetParallax: setting parallax for current room!!"); + _roomDefTable[screen].parallax[0] = resId; +} + +void SwordScreen::spriteClipAndSet(uint16 *pSprX, uint16 *pSprY, uint16 *pSprWidth, uint16 *pSprHeight, uint16 *incr) { + int16 sprX = *pSprX - SCREEN_LEFT_EDGE; + int16 sprY = *pSprY - SCREEN_TOP_EDGE; + int16 sprW = *pSprWidth; + int16 sprH = *pSprHeight; + + if (sprY < 0) { + *incr = (uint16)((-sprY) * sprW); + sprH += sprY; + sprY = 0; + } else + *incr = 0; + if (sprX < 0) { + *incr -= sprX; + sprW += sprX; + sprX = 0; + } + + if (sprY + sprH > _scrnSizeY) + sprH = _scrnSizeY - sprY; + if (sprX + sprW > _scrnSizeX) + sprW = _scrnSizeX - sprX; + + if (sprH < 0) + *pSprHeight = 0; + else + *pSprHeight = (uint16)sprH; + if (sprW < 0) + *pSprWidth = 0; + else + *pSprWidth = (uint16)sprW; + *pSprX = (uint16)sprX; + *pSprY = (uint16)sprY; + + uint16 gridH = (*pSprHeight + SCRNGRID_Y - 1) / SCRNGRID_Y; + uint16 gridW = (*pSprWidth + SCRNGRID_X - 1) / SCRNGRID_X; + uint16 gridX = sprX / SCRNGRID_X; + uint16 gridY = sprY / SCRNGRID_Y; + uint8 *gridBuf = _screenGrid + gridX + gridY * _gridSizeX; + if (gridX + gridW > _gridSizeX) + gridW = _gridSizeX - gridX; + if (gridY + gridH > _gridSizeY) + gridH = _gridSizeY - gridY; + + for (uint16 cnty = 0; cnty < gridH; cnty++) { + for (uint16 cntx = 0; cntx < gridW; cntx++) + gridBuf[cntx] |= 0x80; + gridBuf += _gridSizeX; + } +} + +void SwordScreen::showFrame(uint16 x, uint16 y, uint32 resId, uint32 frameNo) { + warning("stub: SwordScreen::showFrame(%d, %d, %d, %d)", x, y, resId, frameNo); +} + +void SwordScreen::fnFlash(uint8 color) { + warning("stub: SwordScreen::fnFlash(%d)", color); +} + +// ------------------- router debugging code -------------------------------- + +void SwordScreen::vline(uint16 x, uint16 y1, uint16 y2) { + for (uint16 cnty = y1; cnty <= y2; cnty++) + _screenBuf[x + _scrnSizeX * cnty] = 0; +} + +void SwordScreen::hline(uint16 x1, uint16 x2, uint16 y) { + for (uint16 cntx = x1; cntx <= x2; cntx++) + _screenBuf[y * _scrnSizeX + cntx] = 0; +} + +void SwordScreen::bsubline_1(uint16 x1, uint16 y1, uint16 x2, uint16 y2) { + int x, y, ddx, ddy, e; + ddx = abs(x2 - x1); + ddy = abs(y2 - y1) << 1; + e = ddx - ddy; + ddx <<= 1; + + if (x1 > x2) { + uint16 tmp; + tmp = x1; x1 = x2; x2 = tmp; + tmp = y1; y1 = y2; y2 = tmp; + } + + for (x = x1, y = y1; x <= x2; x++) { + _screenBuf[y * _scrnSizeX + x] = 0; + if (e < 0) { + y++; + e += ddx - ddy; + } else { + e -= ddy; + } + } +} + +void SwordScreen::bsubline_2(uint16 x1, uint16 y1, uint16 x2, uint16 y2) { + int x, y, ddx, ddy, e; + ddx = abs(x2 - x1) << 1; + ddy = abs(y2 - y1); + e = ddy - ddx; + ddy <<= 1; + + if (y1 > y2) { + uint16 tmp; + tmp = x1; x1 = x2; x2 = tmp; + tmp = y1; y1 = y2; y2 = tmp; + } + + for (y = y1, x = x1; y <= y2; y++) { + _screenBuf[y * _scrnSizeX + x] = 0; + if (e < 0) { + x++; + e += ddy - ddx; + } else { + e -= ddx; + } + } +} + +void SwordScreen::bsubline_3(uint16 x1, uint16 y1, uint16 x2, uint16 y2) { + int x, y, ddx, ddy, e; + ddx = abs(x1 - x2) << 1; + ddy = abs(y2 - y1); + e = ddy - ddx; + ddy <<= 1; + + if (y1 > y2) { + uint16 tmp; + tmp = x1; x1 = x2; x2 = tmp; + tmp = y1; y1 = y2; y2 = tmp; + } + + for (y = y1, x = x1; y <= y2; y++) { + _screenBuf[y * _scrnSizeX + x] = 0; + if (e < 0) { + x--; + e += ddy - ddx; + } else { + e -= ddx; + } + } +} + +void SwordScreen::bsubline_4(uint16 x1, uint16 y1, uint16 x2, uint16 y2) { + int x, y, ddx, ddy, e; + ddy = abs(y2 - y1) << 1; + ddx = abs(x1 - x2); + e = ddx - ddy; + ddx <<= 1; + + if (x1 > x2) { + uint16 tmp; + tmp = x1; x1 = x2; x2 = tmp; + tmp = y1; y1 = y2; y2 = tmp; + } + + for (x = x1, y = y1; x <= x2; x++) { + _screenBuf[y * _scrnSizeX + x] = 0; + if (e < 0) { + y--; + e += ddx - ddy; + } else { + e -= ddy; + } + } +} + +void SwordScreen::drawLine(uint16 x1, uint16 y1, uint16 x2, uint16 y2) { + if ((x1 == x2) && (y1 == y2)) { + _screenBuf[x1 + y1 * _scrnSizeX] = 0; + } + if (x1 == x2) { + vline(x1, min(y1, y2), max(y1, y2)); + return; + } + + if (y1 == y2) { + hline(min(x1, x2), max(x1, x2), y1); + return; + } + + float k = float(y2 - y1) / float(x2 - x1); + + if ((k >= 0) && (k <= 1)) { + bsubline_1(x1, y1, x2, y2); + } else if (k > 1) { + bsubline_2(x1, y1, x2, y2); + } else if ((k < 0) && (k >= -1)) { + bsubline_4(x1, y1, x2, y2); + } else { + bsubline_3(x1, y1, x2, y2); + } + +} + +void SwordScreen::showBarsAndNodes(SwordRouter *router) { + for (uint16 cnt = 0; cnt < router->_nBars; cnt++) { + drawLine(router->_bars[cnt].x1 - 128, router->_bars[cnt].y1 - 128, router->_bars[cnt].x2 - 128, router->_bars[cnt].y2 - 128); + } + if (!router->_nNodes) + return; + for (uint16 cnt = 0; cnt <= router->_nNodes; cnt++) { + uint16 y = router->_node[cnt].y - 128; + uint16 x = router->_node[cnt].x - 128; + vline(x, y - 2, y + 2); + hline(x - 2, x + 2, y); + if (router->_node[cnt].dist != 9999) { + drawLine(x, y, router->_node[router->_node[cnt].prev].x - 128, router->_node[router->_node[cnt].prev].y - 128); + } + } +} + diff --git a/sword1/screen.h b/sword1/screen.h new file mode 100644 index 0000000000..7861b6d501 --- /dev/null +++ b/sword1/screen.h @@ -0,0 +1,153 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +// vertical_mask from layers.c belongs here, as well. + +#ifndef BSSCREEN_H +#define BSSCREEN_H + +#include "sworddefs.h" + +#define MAX_FORE 20 +#define MAX_BACK 20 +#define MAX_SORT 20 + +struct SortSpr { + int32 id, y; +}; + +struct RoomDef { + int totalLayers; + int sizeX; + int sizeY; + int gridWidth; //number of 16*16 grid blocks across - including off screen edges. + uint32 layers[4]; + uint32 grids[3]; + uint32 palettes[2]; + uint32 parallax[2]; +}; + +#define SCRNGRID_X 16 +#define SCRNGRID_Y 8 +#define SHRINK_BUFFER_SIZE 50000 +#define RLE_BUFFER_SIZE 50000 + +#define FLASH_RED 0 +#define FLASH_BLUE 1 +#define BORDER_YELLOW 2 +#define BORDER_GREEN 3 +#define BORDER_PURPLE 4 +#define BORDER_BLACK 5 + +class ResMan; +class ObjectMan; +class SwordText; // Text objects use sprites that are created internally at run-time + // the buffer belongs to SwordText, so we need a reference here. +class SwordRouter; +class OSystem; + +class SwordScreen { +public: + SwordScreen(OSystem *system, ResMan *pResMan, ObjectMan *pObjMan); + void useTextManager(SwordText *pTextMan); + ~SwordScreen(void); + void flushSprites(void) { _backLength = _sortLength = _foreLength = 0; }; + + void quitScreen(void); + void newScreen(uint32 screen); + + void setScrolling(int16 offsetX, int16 offsetY); + + void addToGraphicList(uint8 listId, uint32 objId); + + void recreate(); + void spritesAndParallax(void); //=> background_parallax, backsprites, sortsprites + // foreground_parallax, foresprites + void fadeDownPalette(void); + void fadeUpPalette(void); + void fnSetPalette(uint8 start, uint16 length, uint8 *data); + void fnSetFadeTargetPalette(uint8 start, uint16 length, uint8 *data); + bool stillFading(void); + + void updateScreen(void); + void showFrame(uint16 x, uint16 y, uint32 resId, uint32 frameNo); + + void fnSetParallax(uint32 screen, uint32 resId); + void fnFlash(uint8 color); + void fnBorder(uint8 color); + + void showBarsAndNodes(SwordRouter *router); + +private: + // for router debugging + void drawLine(uint16 x1, uint16 y1, uint16 x2, uint16 y2); + void vline(uint16 x, uint16 y1, uint16 y2); + void hline(uint16 x1, uint16 x2, uint16 y); + void bsubline_1(uint16 x1, uint16 y1, uint16 x2, uint16 y2); + void bsubline_2(uint16 x1, uint16 y1, uint16 x2, uint16 y2); + void bsubline_3(uint16 x1, uint16 y1, uint16 x2, uint16 y2); + void bsubline_4(uint16 x1, uint16 y1, uint16 x2, uint16 y2); + + void verticalMask(uint16 x, uint16 y, uint16 bWidth, uint16 bHeight); + void blitBlockClear(uint16 x, uint16 y, uint8 *data); + void renderParallax(uint8 *data); + void processImage(uint32 id); + void spriteClipAndSet(uint16 *pSprX, uint16 *pSprY, uint16 *sprWidth, uint16 *sprHeight, uint16 *incr); + void drawSprite(uint8 *sprData, uint16 sprX, uint16 sprY, uint16 sprWidth, uint16 sprHeight, uint16 sprPitch); + void decompressRLE7(uint8 *src, uint32 compSize, uint8 *dest); + void decompressRLE0(uint8 *src, uint32 compSize, uint8 *dest, uint16 width); + void decompressTony(uint8 *src, uint32 compSize, uint8 *dest); + void fastShrink(uint8 *src, uint32 width, uint32 height, uint32 scale, uint8 *dest); + int32 inRange(int32 a, int32 b, int32 c); + void fadePalette(void); + + OSystem *_system; + ResMan *_resMan; + ObjectMan *_objMan; + SwordText *_textMan; + + uint16 _currentScreen; + uint8 *_screenBuf; + uint8 *_screenGrid; + uint16 *_layerGrid[4]; + uint8 *_layerBlocks[4]; + uint8 *_parallax[2]; + uint8 _rleBuffer[RLE_BUFFER_SIZE]; + uint8 _shrinkBuffer[SHRINK_BUFFER_SIZE]; + bool _fullRefresh; + uint16 _oldScrollX, _oldScrollY; // for drawing additional frames + + uint32 _foreList[MAX_FORE]; + uint32 _backList[MAX_BACK]; + SortSpr _sortList[MAX_SORT]; + uint8 _foreLength, _backLength, _sortLength; + uint16 _scrnSizeX, _scrnSizeY, _gridSizeX, _gridSizeY; + + static RoomDef _roomDefTable[TOTAL_ROOMS]; // from ROOMS.C (not const, see fnSetParallax) + + uint8 _targetPalette[256 * 4]; + uint8 _currentPalette[256 * 4]; // for fading + uint8 _fadingStep; + int8 _fadingDirection; // 1 for fade up, -1 for fade down +}; + +#endif //BSSCREEN_H + diff --git a/sword1/sound.cpp b/sword1/sound.cpp new file mode 100644 index 0000000000..be82e44307 --- /dev/null +++ b/sword1/sound.cpp @@ -0,0 +1,214 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#include "stdafx.h" +#include "sound.h" +#include "common/util.h" +#include "resman.h" +#include "logic.h" + +#define SOUND_SPEECH_ID 1 +#define SPEECH_FLAGS (SoundMixer::FLAG_16BITS | SoundMixer::FLAG_AUTOFREE | SoundMixer::FLAG_LITTLE_ENDIAN) + +SwordSound::SwordSound(const char *searchPath, SoundMixer *mixer, ResMan *pResMan) { + strcpy(_filePath, searchPath); + _mixer = mixer; + _resMan = pResMan; + _cowHeader = NULL; + initCowSystem(); + _endOfQueue = 0; +} + +int SwordSound::addToQueue(int32 fxNo) { + bool alreadyInQueue = false; + for (uint8 cnt = 0; (cnt < _endOfQueue) && (!alreadyInQueue); cnt++) + if (_fxQueue[cnt].id == fxNo) + alreadyInQueue = true; + if (!alreadyInQueue) { + if (_endOfQueue == MAX_FXQ_LENGTH) + error("Sound queue overflow"); + _resMan->resOpen(_fxList[fxNo].sampleId); + _fxQueue[_endOfQueue].id = fxNo; + if (_fxList[fxNo].type == FX_SPOT) + _fxQueue[_endOfQueue].delay = _fxList[fxNo].delay + 1; + else + _fxQueue[_endOfQueue].delay = 1; + _endOfQueue++; + return 1; + } + return 0; +} + +void SwordSound::engine(void) { + // first of all, add any random sfx to the queue... + for (uint16 cnt = 0; cnt < TOTAL_FX_PER_ROOM; cnt++) { + uint16 fxNo; + if (fxNo = _roomsFixedFx[SwordLogic::_scriptVars[SCREEN]][cnt]) { + if (_fxList[fxNo].type == FX_RANDOM) { + if (_rnd.getRandomNumber(_fxList[fxNo].delay) == 0) + addToQueue(fxNo); + } + } else + break; + } + // now process the queue + for (uint8 cnt = 0; cnt < _endOfQueue; cnt++) { + if (_fxQueue[cnt].delay > 0) { + _fxQueue[cnt].delay--; + if (_fxQueue[cnt].delay == 0) + playSample(_fxQueue[cnt]); + } else { + if (!_fxQueue[cnt].handle) { // sound finished + _resMan->resClose(_fxQueue[cnt].id); + if (cnt != _endOfQueue-1) + _fxQueue[cnt] = _fxQueue[_endOfQueue - 1]; + _endOfQueue--; + } + } + } +} + +bool SwordSound::amISpeaking(void) { + return true; +} + +void SwordSound::clearAllFx(void) { + warning("Stub: SwordSound::clearAllFx()"); +} + +void SwordSound::closeCowSysten(void) { + warning("stub: SwordSound::closeCowSystem()"); +} + +void SwordSound::fnStopFx(int32 fxNo) { + warning("stub: SwordSound::fnStopFx(%d)", fxNo); +} + +bool SwordSound::speechFinished(void) { + //warning("stub: SwordSound::speechFinished()"); + //return true; + return (_speechHandle == 0); +} + +void SwordSound::startFxForScreen(uint16 screen) { // do we need this? + warning("stub: SwordSound::startFxForScreen(%d)", screen); +} + +void SwordSound::playSample(QueueElement elem) { + + uint8 *sampleData = (uint8*)_resMan->fetchRes(_fxList[elem.id].sampleId); + for (uint16 cnt = 0; cnt < MAX_ROOMS_PER_FX; cnt++) { + if (_fxList[elem.id].roomVolList[cnt].roomNo) { + if ((_fxList[elem.id].roomVolList[cnt].roomNo == SwordLogic::_scriptVars[SCREEN]) || + (_fxList[elem.id].roomVolList[cnt].roomNo == -1)) { + + uint8 volL = _fxList[elem.id].roomVolList[cnt].leftVol * 10; + uint8 volR = _fxList[elem.id].roomVolList[cnt].rightVol * 10; + int8 pan = (volR - volL) / 2; + uint8 volume = (volR + volL) / 2; + uint32 size = READ_LE_UINT32(sampleData + 0x28); + uint8 flags; + if (READ_LE_UINT16(sampleData + 0x22) == 16) + flags = SoundMixer::FLAG_16BITS | SoundMixer::FLAG_LITTLE_ENDIAN; + else + flags = SoundMixer::FLAG_UNSIGNED; + _mixer->playRaw(&elem.handle, sampleData + 0x2C, size, 11025, flags, elem.id, volume, pan); + } + } else + break; + } +} + +uint32 SwordSound::uncompressedSize(uint8 *data) { + return READ_LE_UINT32(data + 0x28); +} + +bool SwordSound::startSpeech(uint16 roomNo, uint16 localNo) { + if (_cowHeader == NULL) { + warning("SwordSound::startSpeech: COW file isn't open!"); + return false; + } + + uint32 locIndex = _cowHeader[roomNo] >> 2; + uint32 sampleSize = _cowHeader[locIndex + (localNo * 2)]; + uint32 index = _cowHeader[locIndex + (localNo * 2) - 1]; + debug(4, "startSpeech(%d, %d): locIndex %d, sampleSize %d, index %d", roomNo, localNo, locIndex, sampleSize, index); + if (sampleSize) { + _cowFile.seek(index + _cowHeaderSize); + uint8 *buf = (uint8*)malloc(sampleSize); + _cowFile.read(buf, sampleSize); + uint8 *smpBuf = (uint8*)malloc(uncompressedSize(buf)); + uint32 size = expandSpeech(buf, smpBuf, sampleSize); + free(buf); + if (!size) { + free(smpBuf); + return false; + } + _mixer->playRaw(&_speechHandle, smpBuf, size, 11025, SPEECH_FLAGS, SOUND_SPEECH_ID); + return true; + } else + return false; +} + +uint32 SwordSound::expandSpeech(void *src, void *dest, uint32 srcSize) { + int16 *compData = (int16*)src; + if (READ_BE_UINT32(compData + 0x12) != 'data') { + warning("SwordSound::expandSpeech: 'data' tag not found in wave header"); + return 0; + } + srcSize >>= 1; + int16 *expData = (int16*)dest; + compData += 0x16; + srcSize -= 0x16; + + uint32 srcPos = 0; + while (srcPos < srcSize) { + if (compData[srcPos] < 0) { + uint16 len = (uint16)(-compData[srcPos]); + for (uint32 cnt = 0; cnt < len; cnt++) + *expData++ = compData[srcPos + 1]; + srcPos += 2; + } else { + uint32 len = (uint32)compData[srcPos]; + memcpy(expData, compData + srcPos + 1, len * 2); + expData += len; + srcPos += len + 1; + } + } + return (uint8*)expData - (uint8*)dest; +} + +void SwordSound::stopSpeech(void) { + _mixer->stopID(SOUND_SPEECH_ID); +} + +void SwordSound::initCowSystem(void) { + _cowFile.open("SPEECH.CLU"); + if (_cowFile.isOpen()) { + _cowHeaderSize = _cowFile.readUint32LE(); + _cowHeader = (uint32*)malloc(_cowHeaderSize); + if (_cowHeaderSize & 3) + error("Unexpected cow header size %d", _cowHeaderSize); + for (uint32 cnt = 0; cnt < (_cowHeaderSize / 4) - 1; cnt++) + _cowHeader[cnt] = _cowFile.readUint32LE(); + } else + warning("SwordSound::initCowSystem: Can't open SPEECH.CLU"); +} diff --git a/sword1/sound.h b/sword1/sound.h new file mode 100644 index 0000000000..4d17863021 --- /dev/null +++ b/sword1/sound.h @@ -0,0 +1,99 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#ifndef BSSOUND_H +#define BSSOUND_H + +#include "object.h" +#include "sworddefs.h" +#include "common/file.h" +#include "sound/mixer.h" +#include "common/util.h" + +#define TOTAL_FX_PER_ROOM 7 // total loop & random fx per room (see fx_list.c) +#define MAX_ROOMS_PER_FX 7 // max no. of rooms in the fx's room,vol list +#define MAX_FXQ_LENGTH 32 // max length of sound queue - ie. max number of fx that can be stored up/playing together + +#define FX_SPOT 1 +#define FX_LOOP 2 +#define FX_RANDOM 3 + +struct QueueElement { + uint32 id, delay; + PlayingSoundHandle handle; + uint16 *data; // FIXME: This is a hack, because our mixer only supports Big endian data (currently) +}; + +struct RoomVol { + int32 roomNo, leftVol, rightVol; +}; + +struct FxDef { + uint32 sampleId, type, delay; + RoomVol roomVolList[MAX_ROOMS_PER_FX]; +}; + +class SoundMixer; +class ResMan; + +class SwordSound { +public: + SwordSound(const char *searchPath, SoundMixer *mixer, ResMan *pResMan); + ~SwordSound(void); + void startFxForScreen(uint16 screen); + + bool startSpeech(uint16 roomNo, uint16 localNo); // this should work more or less. + // Maybe we'll need a delay of 3 gameCycles. + bool speechFinished(void); + void stopSpeech(); + bool amISpeaking(void); // this is supposed to return if the sounddata is near the ending or very silent... + + void fnStopFx(int32 fxNo); + void clearAllFx(void); + int addToQueue(int32 fxNo); + //void removeFromQueue(int32 fxNo); + // ^= part of fnPlayFx + + void engine(void); + +private: + void playSample(QueueElement elem); + void initCowSystem(void); + void closeCowSysten(void); + uint32 uncompressedSize(uint8 *data); + uint32 expandSpeech(void *src, void *dest, uint32 srcSize); + File _cowFile; + uint32 *_cowHeader; + uint32 _cowHeaderSize; + PlayingSoundHandle _speechHandle, _fxHandle; + Common::RandomSource _rnd; + + QueueElement _fxQueue[MAX_FXQ_LENGTH]; + uint8 _endOfQueue; + SoundMixer *_mixer; + ResMan *_resMan; + char _filePath[100]; + static const char _musicList[270]; + static const uint16 _roomsFixedFx[TOTAL_ROOMS][TOTAL_FX_PER_ROOM]; + static const FxDef _fxList[312]; +}; + +#endif //BSSOUND_H diff --git a/sword1/staticres.cpp b/sword1/staticres.cpp new file mode 100644 index 0000000000..398cecd394 --- /dev/null +++ b/sword1/staticres.cpp @@ -0,0 +1,6022 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#include "sworddefs.h" +#include "swordres.h" +#include "screen.h" +#include "resman.h" +#include "objectman.h" +#include "menu.h" +#include "music.h" +#include "sound.h" + +const Subject SwordMenu::_subjectList[TOTAL_subjects] = { + { // 256 + 0, // subject_res + 0 // subject_frame + }, + { // 257 + ICON_BEER, // subject_res + 0 // subject_frame + }, + { // 258 + ICON_CASTLE, // subject_res + 0 // subject_frame + }, + { // 259 + ICON_YES, // subject_res + 0 // subject_frame + }, + { // 260 + ICON_NO, // subject_res + 0 // subject_frame + }, + { // 261 + ICON_PEAGRAM, // subject_res + 0 // subject_frame + }, + { // 262 + ICON_DIG, // subject_res + 0 // subject_frame + }, + { // 263 + ICON_SEAN, // subject_res + 0 // subject_frame + }, + { // 264 + ICON_GEM, // subject_res + 0 // subject_frame + }, + { // 265 + ICON_TEMPLARS, // subject_res + 0 // subject_frame + }, + { // 266 + ICON_LEPRECHAUN, // subject_res + 0 // subject_frame + }, + { // 267 + ICON_GOODBYE, // subject_res + 0 // subject_frame + }, + { // 268 + ICON_GEORGE, // subject_res + 0 // subject_frame + }, + { // 269 + ICON_ROSSO, // subject_res + 0 // subject_frame + }, + { // 270 + ICON_GHOST, // subject_res + 0 // subject_frame + }, + { // 271 + ICON_CLOWN, // subject_res + 0 // subject_frame + }, + { // 272 + ICON_CAR, // subject_res + 0 // subject_frame + }, + { // 273 + ICON_MOUE, // subject_res + 0 // subject_frame + }, + { // 274 + ICON_NICO, // subject_res + 0 // subject_frame + }, + { // 275 + ICON_MOB, // subject_res + 0 // subject_frame + }, + { // 276 + ICON_CHANTELLE, // subject_res + 0 // subject_frame + }, + { // 277 + ICON_PLANTARD, // subject_res + 0 // subject_frame + }, + { // 278 + ICON_JACKET, // subject_res + 0 // subject_frame + }, + { // 279 + ICON_BRIEFCASE, // subject_res + 0 // subject_frame + }, + { + 0, //ICON_GLASS, // subject_res + 0 // subject_frame + }, + { // 281 + ICON_GLASS_EYE, // subject_res + 0 // subject_frame + }, + { // 282 + ICON_BULL, // subject_res + 0 // subject_frame + }, + { // 283 + ICON_KLAUSNER, // subject_res + 0 // subject_frame + }, + { // 284 + 0, //ICON_LOOM, // subject_res + 0 // subject_frame + }, + { // 285 + ICON_ULTAR, // subject_res + 0 // subject_frame + }, + { // 286 + ICON_PHONE, // subject_res + 0 // subject_frame + }, + { // 287 + ICON_PHOTOGRAPH, // subject_res + 0 // subject_frame + }, + { // 288 + ICON_CREST, // subject_res + 0 // subject_frame + }, + { // 289 + ICON_LOBINEAU, // subject_res + 0 // subject_frame + }, + { // 290 + ICON_BOOK, // subject_res + 0 // subject_frame + }, + { // 291 (SNARE) + ICON_FUSE_WIRE, // subject_res + 0 // subject_frame + }, + { // 292 + ICON_LEARY, // subject_res + 0 // subject_frame + }, + { // 293 + ICON_LADDER, // subject_res + 0 // subject_frame + }, + { // 294 + ICON_GOAT, // subject_res + 0 // subject_frame + }, + { // 295 + ICON_TOOLBOX, // subject_res + 0 // subject_frame + }, + { // 296 + ICON_PACKAGE, // subject_res + 0 // subject_frame + }, + { // 297 + ICON_FISH, // subject_res + 0 // subject_frame + }, + { // 298 + ICON_NEJO, // subject_res + 0 // subject_frame + }, + { // 299 + ICON_CAT, // subject_res + 0 // subject_frame + }, + { // 300 + ICON_AYUB, // subject_res + 0 // subject_frame + }, + { // 301 + ICON_STATUETTE, // subject_res + 0 // subject_frame + }, + { // 302 + ICON_NEJO_STALL, // subject_res + 0 // subject_frame + }, + { // 303 + ICON_TEMPLARS, // subject_res + 0 // subject_frame + }, + { // 304 + ICON_ARTO, // subject_res + 0 // subject_frame + }, + { // 305 + ICON_HENDERSONS, // subject_res + 0 // subject_frame + }, + { // 306 + ICON_CLUB, // subject_res + 0 // subject_frame + }, + { // 307 + ICON_SIGN, // subject_res + 0 // subject_frame + }, + { // 308 + ICON_TAXI, // subject_res + 0 // subject_frame + }, + { // 309 + ICON_BULLS_HEAD, // subject_res + 0 // subject_frame + }, + { // 310 + ICON_DUANE, // subject_res + 0 // subject_frame + }, + { // 311 + ICON_PEARL, // subject_res + 0 // subject_frame + }, + { // 312 + ICON_TRUTH, // subject_res + 0 // subject_frame + }, + { // 313 + ICON_LIE, // subject_res + 0 // subject_frame + }, + { // 314 + 0, //ICON_SUBJECT,// subject_res + 0 // subject_frame + }, + { // 315 KEY + ICON_HOTEL_KEY, // subject_res + 0 // subject_frame + }, + { // 316 + ICON_FLOWERS, // subject_res + 0 // subject_frame + }, + { // 317 + ICON_BUST, // subject_res + 0 // subject_frame + }, + { // 318 + ICON_MANUSCRIPT, // subject_res + 0 // subject_frame + }, + { // 319 + ICON_WEASEL, // subject_res + 0 // subject_frame + }, + { // 320 + ICON_BANANA, // subject_res + 0 // subject_frame + }, + { // 321 + ICON_WEAVER, // subject_res + 0 // subject_frame + }, + { // 322 + ICON_KNIGHT, // subject_res + 0 // subject_frame + }, + { // 323 + ICON_QUEEN, // subject_res + 0 // subject_frame + }, + { // 324 + ICON_PIERMONT, // subject_res + 0 // subject_frame + }, + { // 325 + ICON_BALL, // subject_res + 0 // subject_frame + }, + { // 326 + ICON_COUNTESS, // subject_res + 0 // subject_frame + }, + { // 327 + ICON_MARQUET, // subject_res + 0 // subject_frame + }, + { // 328 + ICON_SAFE, // subject_res + 0 // subject_frame + }, + { // 329 + ICON_COINS, // subject_res + 0 // subject_frame + }, + { // 330 + ICON_CHESS_SET, // subject_res + 0 // subject_frame + }, + { // 331 + ICON_TOMB, // subject_res + 0 // subject_frame + }, + { // 332 + ICON_CANDLE, // subject_res + 0 // subject_frame + }, + { // 333 + ICON_MARY, // subject_res + 0 // subject_frame + }, + { // 334 + ICON_CHESSBOARD, // subject_res + 0 // subject_frame + }, + { // 335 + ICON_TRIPOD, // subject_res + 0 // subject_frame + }, + { // 336 + ICON_POTS, // subject_res + 0 // subject_frame + }, + { // 337 + ICON_ALARM, // subject_res + 0 // subject_frame + }, + { // 338 + ICON_BAPHOMET, // subject_res + 0 // subject_frame + }, + { // 339 + ICON_PHRASE, // subject_res + 0 // subject_frame + }, + { // 340 + ICON_POLISHED_CHALICE, // subject_res + 0 // subject_frame + }, + { // 341 + ICON_NURSE, // subject_res + 0 // subject_frame + }, + { // 342 + ICON_WELL, // subject_res + 0 // subject_frame + }, + { // 343 + ICON_WELL2, // subject_res + 0 // subject_frame + }, + { // 344 + ICON_HAZEL_WAND, // subject_res + 0 // subject_frame + }, + { // 345 + ICON_CHALICE, // subject_res + 0 // subject_frame + }, + { // 346 + ICON_MR_SHINY, // subject_res + 0 // subject_frame + }, + { // 347 + ICON_PHOTOGRAPH, // subject_res + 0 // subject_frame + }, + { // 348 + ICON_PHILIPPE, // subject_res + 0 // subject_frame + }, + { // 349 + ICON_ERIC, // subject_res + 0 // subject_frame + }, + { // 350 + ICON_ROZZER, // subject_res + 0 // subject_frame + }, + { // 351 + ICON_JUGGLER, // subject_res + 0 // subject_frame + }, + { // 352 + ICON_PRIEST, // subject_res + 0 // subject_frame + }, + { // 353 + ICON_WINDOW, // subject_res + 0 // subject_frame + }, + { // 354 + ICON_SCROLL, // subject_res + 0 // subject_frame + }, + { // 355 + ICON_PRESSURE_GAUGE, // subject_res + 0 // subject_frame + }, + { // 356 + ICON_RENEE, // subject_res + 0 // subject_frame + }, + { // 357 + ICON_CHURCH, // subject_res + 0 // subject_frame + }, + { // 358 + ICON_EKLUND, // subject_res + 0 // subject_frame + }, + { // 359 + ICON_FORTUNE, // subject_res + 0 // subject_frame + }, + { // 360 + ICON_PAINTER, // subject_res + 0 // subject_frame + }, + { // 361 + 0, //ICON_SWORD, // subject_res + 0 // subject_frame + }, + { // 362 + ICON_GUARD, // subject_res + 0 // subject_frame + }, + { // 363 + ICON_THERMOSTAT, // subject_res + 0 // subject_frame + }, + { // 364 + ICON_TOILET, // subject_res + 0 // subject_frame + }, + { // 365 + ICON_MONTFAUCON, // subject_res + 0 // subject_frame + }, + { // 366 + ICON_ASSASSIN, // subject_res + 0 // subject_frame + }, + { // 367 + ICON_HASH, // subject_res + 0 // subject_frame + }, + { // 368 + ICON_DOG, // subject_res + 0 // subject_frame + }, + { // 369 + ICON_AYUB, // subject_res + 0 // subject_frame + }, + { // 370 + ICON_LENS, // subject_res + 0 // subject_frame + }, + { // 371 + ICON_RED_NOSE, // subject_res + 0 // subject_frame + }, + { // 372 + 0, // subject_res + 0 // subject_frame + }, + { // 373 + 0, // subject_res + 0 // subject_frame + }, + { // 374 + 0, // subject_res + 0 // subject_frame + } +}; + +const uint32 ResMan::_scriptList[TOTAL_SECTIONS] = { //a table of resource tags + SCRIPT0, // 0 STANDARD SCRIPTS + + SCRIPT1, // 1 PARIS 1 + SCRIPT2, // 2 + SCRIPT3, // 3 + SCRIPT4, // 4 + SCRIPT5, // 5 + SCRIPT6, // 6 + SCRIPT7, // 7 + SCRIPT8, // 8 + + SCRIPT9, // 9 PARIS 2 + SCRIPT10, // 10 + SCRIPT11, // 11 + SCRIPT12, // 12 + SCRIPT13, // 13 + SCRIPT14, // 14 + SCRIPT15, // 15 + SCRIPT16, // 16 + SCRIPT17, // 17 + SCRIPT18, // 18 + + SCRIPT19, // 19 IRELAND + SCRIPT20, // 20 + SCRIPT21, // 21 + SCRIPT22, // 22 + SCRIPT23, // 23 + SCRIPT24, // 24 + SCRIPT25, // 25 + SCRIPT26, // 26 + + SCRIPT27, // 27 PARIS 3 + SCRIPT28, // 28 + SCRIPT29, // 29 + 0, // 30 + SCRIPT31, // 31 + SCRIPT32, // 32 + SCRIPT33, // 33 + SCRIPT34, // 34 + SCRIPT35, // 35 + + SCRIPT36, // 36 PARIS 4 + SCRIPT37, // 37 + SCRIPT38, // 38 + SCRIPT39, // 39 + SCRIPT40, // 40 + SCRIPT41, // 41 + SCRIPT42, // 42 + SCRIPT43, // 43 + 0, // 44 + + SCRIPT45, // 45 SYRIA + SCRIPT46, // 46 PARIS 4 + SCRIPT47, // 47 + SCRIPT48, // 48 PARIS 4 + SCRIPT49, // 49 + SCRIPT50, // 50 + 0, // 51 + 0, // 52 + 0, // 53 + SCRIPT54, // 54 + SCRIPT55, // 55 + + SCRIPT56, // 56 SPAIN + SCRIPT57, // 57 + SCRIPT58, // 58 + SCRIPT59, // 59 + SCRIPT60, // 60 + SCRIPT61, // 61 + SCRIPT62, // 62 + + SCRIPT63, // 63 NIGHT TRAIN + 0, // 64 + SCRIPT65, // 65 + SCRIPT66, // 66 + SCRIPT67, // 67 + 0, // 68 + SCRIPT69, // 69 + 0, // 70 + + SCRIPT71, // 71 SCOTLAND + SCRIPT72, // 72 + SCRIPT73, // 73 + SCRIPT74, // 74 + + 0, // 75 + 0, // 76 + 0, // 77 + 0, // 78 + 0, // 79 + SCRIPT80, // 80 + 0, // 81 + 0, // 82 + 0, // 83 + 0, // 84 + 0, // 85 + SCRIPT86, // 86 + 0, // 87 + 0, // 88 + 0, // 89 + SCRIPT90, // 90 + 0, // 91 + 0, // 92 + 0, // 93 + 0, // 94 + 0, // 95 + 0, // 96 + 0, // 97 + 0, // 98 + 0, // 99 + 0, // 100 + 0, // 101 + 0, // 102 + 0, // 103 + 0, // 104 + 0, // 105 + 0, // 106 + 0, // 107 + 0, // 108 + 0, // 109 + 0, // 110 + 0, // 111 + 0, // 112 + 0, // 113 + 0, // 114 + 0, // 115 + 0, // 116 + 0, // 117 + 0, // 118 + 0, // 119 + 0, // 120 + 0, // 121 + 0, // 122 + 0, // 123 + 0, // 124 + 0, // 125 + 0, // 126 + 0, // 127 + SCRIPT128, // 128 + + SCRIPT129, // 129 + SCRIPT130, // 130 + SCRIPT131, // 131 + 0, // 132 + SCRIPT133, // 133 + SCRIPT134, // 134 + 0, // 135 + 0, // 136 + 0, // 137 + 0, // 138 + 0, // 139 + 0, // 140 + 0, // 141 + 0, // 142 + 0, // 143 + 0, // 144 + SCRIPT145, // 145 + SCRIPT146, // 146 + 0, // 147 + 0, // 148 + 0, // 149 +}; + +const uint32 ObjectMan::_objectList[TOTAL_SECTIONS] = { //a table of pointers to object files + 0, // 0 + + COMP1, // 1 PARIS 1 + COMP2, // 2 + COMP3, // 3 + COMP4, // 4 + COMP5, // 5 + COMP6, // 6 + COMP7, // 7 + COMP8, // 8 + + COMP9, // 9 PARIS 2 + COMP10, // 10 + COMP11, // 11 + COMP12, // 12 + COMP13, // 13 + COMP14, // 14 + COMP15, // 15 + COMP16, // 16 + COMP17, // 17 + COMP18, // 18 + + COMP19, // 19 IRELAND + COMP20, // 20 + COMP21, // 21 + COMP22, // 22 + COMP23, // 23 + COMP24, // 24 + COMP25, // 25 + COMP26, // 26 + + COMP27, // 27 PARIS 3 + COMP28, // 28 + COMP29, // 29 + COMP30, // 30 - Heart Monitor + COMP31, // 31 + COMP32, // 32 + COMP33, // 33 + COMP34, // 34 + COMP35, // 35 + + COMP36, // 36 PARIS 4 + COMP37, // 37 + COMP38, // 38 + COMP39, // 39 + COMP40, // 40 + COMP41, // 41 + COMP42, // 42 + COMP43, // 43 + 0, // 44 + + COMP45, // 45 SYRIA + COMP46, // 46 PARIS 4 + COMP47, // 47 + COMP48, // 48 PARIS 4 + COMP49, // 49 + COMP50, // 50 + 0, // 51 + 0, // 52 + COMP53, // 53 + COMP54, // 54 + COMP55, // 55 + + COMP56, // 56 SPAIN + COMP57, // 57 + COMP58, // 58 + COMP59, // 59 + COMP60, // 60 + COMP61, // 61 + COMP62, // 62 + + COMP63, // 63 NIGHT TRAIN + 0, // 64 + COMP65, // 65 + COMP66, // 66 + COMP67, // 67 + 0, // 68 + COMP69, // 69 + 0, // 70 + + COMP71, // 71 SCOTLAND + COMP72, // 72 + COMP73, // 73 + COMP74, // 74 END SEQUENCE IN SECRET_CRYPT + COMP75, // 75 + COMP76, // 76 + COMP77, // 77 + COMP78, // 78 + COMP79, // 79 + + COMP80, // 80 PARIS MAP + + COMP81, // 81 Full-screen for "Asstair" in Paris2 + + COMP55, // 82 Full-screen BRITMAP in sc55 (Syrian Cave) + 0, // 83 + 0, // 84 + 0, // 85 + + COMP86, // 86 EUROPE MAP + COMP48, // 87 fudged in for normal window (sc48) + COMP48, // 88 fudged in for filtered window (sc48) + 0, // 89 + + COMP90, // 90 PHONE SCREEN + COMP91, // 91 ENVELOPE SCREEN + COMP17, // 92 fudged in for George close-up surprised in sc17 wardrobe + COMP17, // 93 fudged in for George close-up inquisitive in sc17 wardrobe + COMP29, // 94 fudged in for George close-up in sc29 sarcophagus + COMP38, // 95 fudged in for George close-up in sc29 sarcophagus + COMP42, // 96 fudged in for chalice close-up from sc42 + 0, // 97 + 0, // 98 + COMP99, // 99 MESSAGE SCREEN (BLANK) + + 0, // 100 + 0, // 101 + 0, // 102 + 0, // 103 + 0, // 104 + 0, // 105 + 0, // 106 + 0, // 107 + 0, // 108 + 0, // 109 + + 0, // 110 + 0, // 111 + 0, // 112 + 0, // 113 + 0, // 114 + 0, // 115 + 0, // 116 + 0, // 117 + 0, // 118 + 0, // 119 + + 0, // 120 + 0, // 121 + 0, // 122 + 0, // 123 + 0, // 124 + 0, // 125 + 0, // 126 + 0, // 127 + +//mega sections + MEGA_GEO, // 128 mega_one the player + MEGA_NICO, // 129 mega_two + MEGA_MUS, // 130 + MEGA_BENOIR, // 131 + 0, // 132 + MEGA_ROSSO, // 133 + MEGA_DUANE, // 134 +// james megas + 0, // 135 + 0, // 136 + 0, // 137 + 0, // 138 + 0, // 139 + 0, // 140 + 0, // 141 + 0, // 142 + 0, // 143 + +// jeremy megas + 0, // 144 mega_phone + MEGA_MOUE, // 145 mega_moue + MEGA_ALBERT, // 146 mega_albert + 0, // 147 + 0, // 148 + TEXT_OBS, // 149 +}; + +const uint32 ObjectMan::_textList[TOTAL_SECTIONS][7] = { + {ENGLISH0, FRENCH0, GERMAN0, ITALIAN0, SPANISH0, CZECH0, PORT0}, // 0 INVENTORY BOTH CD'S - used in almost all locations + {ENGLISH1, FRENCH1, GERMAN1, ITALIAN1, SPANISH1, CZECH1, PORT1}, // 1 PARIS 1 CD1 + {ENGLISH2, FRENCH2, GERMAN2, ITALIAN2, SPANISH2, CZECH2, PORT2}, // 2 CD1 + {ENGLISH3, FRENCH3, GERMAN3, ITALIAN3, SPANISH3, CZECH3, PORT3}, // 3 CD1 + {ENGLISH4, FRENCH4, GERMAN4, ITALIAN4, SPANISH4, CZECH4, PORT4}, // 4 CD1 + {ENGLISH5, FRENCH5, GERMAN5, ITALIAN5, SPANISH5, CZECH5, PORT5}, // 5 CD1 + {ENGLISH6, FRENCH6, GERMAN6, ITALIAN6, SPANISH6, CZECH6, PORT6}, // 6 CD1 + {ENGLISH7, FRENCH7, GERMAN7, ITALIAN7, SPANISH7, CZECH7, PORT7}, // 7 CD1 + {0}, // 8 - + {ENGLISH9, FRENCH9, GERMAN9, ITALIAN9, SPANISH9, CZECH9, PORT9}, // 9 PARIS 2 CD1 + {0}, // 10 - + {ENGLISH11, FRENCH11, GERMAN11, ITALIAN11, SPANISH11, CZECH11, PORT11}, // 11 CD1 + {ENGLISH12, FRENCH12, GERMAN12, ITALIAN12, SPANISH12, CZECH12, PORT12}, // 12 CD1 + {ENGLISH13, FRENCH13, GERMAN13, ITALIAN13, SPANISH13, CZECH13, PORT13}, // 13 CD1 + {ENGLISH14, FRENCH14, GERMAN14, ITALIAN14, SPANISH14, CZECH14, PORT14}, // 14 CD1 + {ENGLISH15, FRENCH15, GERMAN15, ITALIAN15, SPANISH15, CZECH15, PORT15}, // 15 CD1 + {ENGLISH16, FRENCH16, GERMAN16, ITALIAN16, SPANISH16, CZECH16, PORT16}, // 16 CD1 + {ENGLISH17, FRENCH17, GERMAN17, ITALIAN17, SPANISH17, CZECH17, PORT17}, // 17 CD1 + {ENGLISH18, FRENCH18, GERMAN18, ITALIAN18, SPANISH18, CZECH18, PORT18}, // 18 CD1 + {ENGLISH19, FRENCH19, GERMAN19, ITALIAN19, SPANISH19, CZECH19, PORT19}, // 19 IRELAND CD2 + {ENGLISH20, FRENCH20, GERMAN20, ITALIAN20, SPANISH20, CZECH20, PORT20}, // 20 CD2 + {ENGLISH21, FRENCH21, GERMAN21, ITALIAN21, SPANISH21, CZECH21, PORT21}, // 21 CD2 + {ENGLISH22, FRENCH22, GERMAN22, ITALIAN22, SPANISH22, CZECH22, PORT22}, // 22 CD2 + {ENGLISH23, FRENCH23, GERMAN23, ITALIAN23, SPANISH23, CZECH23, PORT23}, // 23 CD2 + {ENGLISH24, FRENCH24, GERMAN24, ITALIAN24, SPANISH24, CZECH24, PORT24}, // 24 CD2 + {ENGLISH25, FRENCH25, GERMAN25, ITALIAN25, SPANISH25, CZECH25, PORT25}, // 25 CD2 + {0}, // 26 - + {ENGLISH27, FRENCH27, GERMAN27, ITALIAN27, SPANISH27, CZECH27, PORT27}, // 27 PARIS 3 CD1 + {ENGLISH28, FRENCH28, GERMAN28, ITALIAN28, SPANISH28, CZECH28, PORT28}, // 28 CD1 + {ENGLISH29, FRENCH29, GERMAN29, ITALIAN29, SPANISH29, CZECH29, PORT29}, // 29 CD1 + {0}, // 30 - + {ENGLISH31, FRENCH31, GERMAN31, ITALIAN31, SPANISH31, CZECH31, PORT31}, // 31 CD1 + {ENGLISH32, FRENCH32, GERMAN32, ITALIAN32, SPANISH32, CZECH32, PORT32}, // 32 CD1 + {ENGLISH33, FRENCH33, GERMAN33, ITALIAN33, SPANISH33, CZECH33, PORT33}, // 33 CD1 + {ENGLISH34, FRENCH34, GERMAN34, ITALIAN34, SPANISH34, CZECH34, PORT34}, // 34 CD1 + {ENGLISH35, FRENCH35, GERMAN35, ITALIAN35, SPANISH35, CZECH35, PORT35}, // 35 CD1 + {ENGLISH36, FRENCH36, GERMAN36, ITALIAN36, SPANISH36, CZECH36, PORT36}, // 36 PARIS 4 CD1 + {ENGLISH37, FRENCH37, GERMAN37, ITALIAN37, SPANISH37, CZECH37, PORT37}, // 37 CD1 + {ENGLISH38, FRENCH38, GERMAN38, ITALIAN38, SPANISH38, CZECH38, PORT38}, // 38 CD1 + {ENGLISH39, FRENCH39, GERMAN39, ITALIAN39, SPANISH39, CZECH39, PORT39}, // 39 CD1 + {ENGLISH40, FRENCH40, GERMAN40, ITALIAN40, SPANISH40, CZECH40, PORT40}, // 40 CD1 + {ENGLISH41, FRENCH41, GERMAN41, ITALIAN41, SPANISH41, CZECH41, PORT41}, // 41 CD1 + {ENGLISH42, FRENCH42, GERMAN42, ITALIAN42, SPANISH42, CZECH42, PORT42}, // 42 CD1 + {ENGLISH43, FRENCH43, GERMAN43, ITALIAN43, SPANISH43, CZECH43, PORT43}, // 43 CD1 + {0}, // 44 - + {ENGLISH45, FRENCH45, GERMAN45, ITALIAN45, SPANISH45, CZECH45, PORT45}, // 45 SYRIA CD2 + {0}, // 46 (PARIS 4) - + {ENGLISH47, FRENCH47, GERMAN47, ITALIAN47, SPANISH47, CZECH47, PORT47}, // 47 CD2 + {ENGLISH48, FRENCH48, GERMAN48, ITALIAN48, SPANISH48, CZECH48, PORT48}, // 48 (PARIS 4) CD1 + {ENGLISH49, FRENCH49, GERMAN49, ITALIAN49, SPANISH49, CZECH49, PORT49}, // 49 CD2 + {ENGLISH50, FRENCH50, GERMAN50, ITALIAN50, SPANISH50, CZECH50, PORT50}, // 50 CD2 + {0}, // 51 - + {0}, // 52 - + {0}, // 53 - + {ENGLISH54, FRENCH54, GERMAN54, ITALIAN54, SPANISH54, CZECH54, PORT54}, // 54 CD2 + {ENGLISH55, FRENCH55, GERMAN55, ITALIAN55, SPANISH55, CZECH55, PORT55}, // 55 CD2 + {ENGLISH56, FRENCH56, GERMAN56, ITALIAN56, SPANISH56, CZECH56, PORT56}, // 56 SPAIN CD2 + {ENGLISH57, FRENCH57, GERMAN57, ITALIAN57, SPANISH57, CZECH57, PORT57}, // 57 CD2 + {ENGLISH58, FRENCH58, GERMAN58, ITALIAN58, SPANISH58, CZECH58, PORT58}, // 58 CD2 + {ENGLISH59, FRENCH59, GERMAN59, ITALIAN59, SPANISH59, CZECH59, PORT59}, // 59 CD2 + {ENGLISH60, FRENCH60, GERMAN60, ITALIAN60, SPANISH60, CZECH60, PORT60}, // 60 CD2 + {ENGLISH61, FRENCH61, GERMAN61, ITALIAN61, SPANISH61, CZECH61, PORT61}, // 61 CD2 + {0}, // 62 - + {ENGLISH63, FRENCH63, GERMAN63, ITALIAN63, SPANISH63, CZECH63, PORT63}, // 63 TRAIN CD2 + {0}, // 64 - + {ENGLISH65, FRENCH65, GERMAN65, ITALIAN65, SPANISH65, CZECH65, PORT65}, // 65 CD2 + {ENGLISH66, FRENCH66, GERMAN66, ITALIAN66, SPANISH66, CZECH66, PORT66}, // 66 CD2 + {0}, // 67 - + {0}, // 68 - + {ENGLISH69, FRENCH69, GERMAN69, ITALIAN69, SPANISH69, CZECH69, PORT69}, // 69 CD2 + {0}, // 70 - + {ENGLISH71, FRENCH71, GERMAN71, ITALIAN71, SPANISH71, CZECH71, PORT71}, // 71 SCOTLAND CD2 + {ENGLISH72, FRENCH72, GERMAN72, ITALIAN72, SPANISH72, CZECH72, PORT72}, // 72 CD2 + {ENGLISH73, FRENCH73, GERMAN73, ITALIAN73, SPANISH73, CZECH73, PORT73}, // 73 CD2 + {ENGLISH74, FRENCH74, GERMAN74, ITALIAN74, SPANISH74, CZECH74, PORT74}, // 74 CD2 + {0}, // 75 - + {0}, // 76 - + {0}, // 77 - + {0}, // 78 - + {0}, // 79 - + {0}, // 80 - + {0}, // 81 - + {0}, // 82 - + {0}, // 83 - + {0}, // 84 - + {0}, // 85 - + {0}, // 86 - + {0}, // 87 - + {0}, // 88 - + {0}, // 89 - + {ENGLISH90, FRENCH90, GERMAN90, ITALIAN90, SPANISH90, CZECH90, PORT90}, // 90 PHONE BOTH CD'S (NICO & TODRYK PHONE TEXT - can phone nico from a number of sections + {0}, // 91 - + {0}, // 92 - + {0}, // 93 - + {0}, // 94 - + {0}, // 95 - + {0}, // 96 - + {0}, // 97 - + {0}, // 98 - + {ENGLISH99, FRENCH99, GERMAN99, ITALIAN99, SPANISH99, CZECH99, PORT99}, // 99 MESSAGES BOTH CD'S - contains general text, most not requiring samples, but includes demo samples + {0}, // 100 - + {0}, // 101 - + {0}, // 102 - + {0}, // 103 - + {0}, // 104 - + {0}, // 105 - + {0}, // 106 - + {0}, // 107 - + {0}, // 108 - + {0}, // 109 - + {0}, // 110 - + {0}, // 111 - + {0}, // 112 - + {0}, // 113 - + {0}, // 114 - + {0}, // 115 - + {0}, // 116 - + {0}, // 117 - + {0}, // 118 - + {0}, // 119 - + {0}, // 120 - + {0}, // 121 - + {0}, // 122 - + {0}, // 123 - + {0}, // 124 - + {0}, // 125 - + {0}, // 126 - + {0}, // 127 - + {0}, // 128 - + {ENGLISH129, FRENCH129, GERMAN129, ITALIAN129, SPANISH129, CZECH129, PORT129}, // 129 NICO BOTH CD'S - used in screens 1,10,71,72,73 + {0}, // 130 - + {ENGLISH131, FRENCH131, GERMAN131, ITALIAN131, SPANISH131, CZECH131, PORT131}, // 131 BENOIR CD1 - used in screens 31..35 + {0}, // 132 - + {ENGLISH133, FRENCH133, GERMAN133, ITALIAN133, SPANISH133, CZECH133, PORT133}, // 133 ROSSO CD1 - used in screen 18 + {0}, // 134 - + {0}, // 135 - + {0}, // 136 - + {0}, // 137 - + {0}, // 138 - + {0}, // 139 - + {0}, // 140 - + {0}, // 141 - + {0}, // 142 - + {0}, // 143 - + {0}, // 144 - + {ENGLISH145, FRENCH145, GERMAN145, ITALIAN145, SPANISH145, CZECH145, PORT145}, // 145 MOUE CD1 - used in screens 1 & 18 + {ENGLISH146, FRENCH146, GERMAN146, ITALIAN146, SPANISH146, CZECH146, PORT146}, // 146 ALBERT CD1 - used in screens 4 & 5 + {0}, // 147 - + {0}, // 148 - + {0}, // 149 - +}; + + +RoomDef SwordScreen::_roomDefTable[TOTAL_ROOMS] = { // these are NOT const + { + 0, //total_layers --- room 0 NOT USED + 0, //size_x = width + 0, //size_y = height + 0, //grid_width = width/16 + 16 + {0,0,0,0}, //layers + {0,0,0}, //grids + {0,0}, //palettes { background palette [0..183], sprite palette [184..255] } + {0,0}, //parallax layers + }, + + //------------------------------------------------------------------------ + // PARIS 1 + + { + 3, //total_layers //room 1 + 784, //size_x + 400, //size_y + 65, //grid_width + {room1_l0,room1_l1,room1_l2}, //layers + {room1_gd1,room1_gd2}, //grids + {room1_PAL,PARIS1_PAL}, //palettes + {room1_plx,0}, //parallax layers + }, + { + 3, //total_layers //room 2 + 640, //size_x + 400, //size_y + 56, //grid_width + {room2_l0,room2_l1,room2_l2,0}, //layers + {room2_gd1,room2_gd2,0}, //grids + {room2_PAL,PARIS1_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 3, //total_layers //room 3 + 640, //size_x + 400, //size_y + 56, //grid_width + {room3_l0,room3_l1,room3_l2,0}, //layers + {room3_gd1,room3_gd2,0}, //grids + {room3_PAL,PARIS1_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 3, //total_layers //room 4 + 640, //size_x + 400, //size_y + 56, //grid_width + {room4_l0,room4_l1,room4_l2,0}, //layers + {room4_gd1,room4_gd2,0}, //grids + {room4_PAL,PARIS1_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 3, //total_layers //room 5 + 640, //size_x + 400, //size_y + 56, //grid_width + {room5_l0,room5_l1,room5_l2,0}, //layers + {room5_gd1,room5_gd2,0}, //grids + {room5_PAL,PARIS1_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 2, //total_layers //room 6 + 640, //size_x + 400, //size_y + 56, //grid_width + {room6_l0,room6_l1,0,0}, //layers + {room6_gd1,0,0}, //grids + {room6_PAL,SEWER_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 3, //total_layers //room 7 + 640, //size_x + 400, //size_y + 56, //grid_width + {room7_l0,room7_l1,room7_l2,0}, //layers + {room7_gd1,room7_gd2,0}, //grids + {room7_PAL,SEWER_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 3, //total_layers //room 8 + 784, //size_x + 400, //size_y + 65, //grid_width + {room8_l0,room8_l1,room8_l2,0}, //layers + {room8_gd1,room8_gd2,0}, //grids + {room8_PAL,PARIS1_PAL}, //palettes + {room8_plx,0}, //parallax layers + }, + + //------------------------------------------------------------------------ + // PARIS 2 + + { + 3, //total_layers //room 9 + 640, //size_x + 400, //size_y + 56, //grid_width + {room9_l0,room9_l1,room9_l2,0}, //layers + {room9_gd1,room9_gd2,0}, //grids + {room9_PAL,PARIS2_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 2, //total_layers //room 10 + 640, //size_x + 400, //size_y + 56, //grid_width + {room10_l0,room10_l1,0,0}, //layers + {room10_gd1,0,0}, //grids + {room10_PAL,R10SPRPAL}, //palettes + {0,0}, //parallax layers + }, + { + 3, //total_layers //room 11 + 640, //size_x + 400, //size_y + 56, //grid_width + {room11_l0,room11_l1,room11_l2,0}, //layers + {room11_gd1,room11_gd2,0}, //grids + {room11_PAL,PARIS2_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 2, //total_layers //room 12 + 640, //size_x + 400, //size_y + 56, //grid_width + {room12_l0,room12_l1,0,0}, //layers + {room12_gd1,0,0}, //grids + {room12_PAL,PARIS2_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 3, //total_layers //room 13 + 976, //size_x + 400, //size_y + 77, //grid_width + {room13_l0,room13_l1,room13_l2,0}, //layers + {room13_gd1,room13_gd2,0}, //grids + {room13_PAL,R13SPRPAL}, //palettes + {0,0}, //parallax layers + }, + { + 2, //total_layers //room 14 + 640, //size_x + 400, //size_y + 56, //grid_width + {room14_l0,room14_l1,0,0}, //layers + {room14_gd1,0,0}, //grids + {room14_PAL,PARIS2_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 3, //total_layers //room 15 + 640, //size_x + 400, //size_y + 56, //grid_width + {room15_l0,room15_l1,room15_l2,0}, //layers + {room15_gd1,room15_gd2,0}, //grids + {room15_PAL,PARIS2_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 2, //total_layers //room 16 + 640, //size_x + 400, //size_y + 56, //grid_width + {R16L0,R16L1,0,0}, //layers + {R16G1,0,0}, //grids + {room16_PAL,PARIS2_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 3, //total_layers //room 17 + 640, //size_x + 400, //size_y + 56, //grid_width + {room17_l0,room17_l1,room17_l2,0}, //layers + {room17_gd1,room17_gd2,0}, //grids + {room17_PAL,PARIS2_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 3, //total_layers //room 18 + 640, //size_x + 400, //size_y + 56, //grid_width + {room18_l0,room18_l1,room18_l2,0}, //layers + {room18_gd1,room18_gd2,0}, //grids + {room18_PAL,R18SPRPAL}, //palettes + {0,0}, //parallax layers + }, + + //------------------------------------------------------------------------ + // IRELAND + + { + 3, //total_layers //room 19 - Ireland Street + 848, //size_x + 864, //size_y + 69, //grid_width + {R19L0,R19L1,R19L2,0}, //layers + {R19G1,R19G2,0}, //grids + {R19PAL,R19SPRPAL}, //palettes + {0,0}, //parallax layers + }, + { + 4, //total_layers //room 20 - Macdevitts + 640, //size_x + 400, //size_y + 56, //grid_width + {R20L0,R20L1,R20L2,R20L3}, //layers + {R20G1,R20G2,R20G3}, //grids + {R20PAL,R20SPRPAL}, //palettes + {0,0}, //parallax layers + }, + { + 3, //total_layers //room 21 - Pub Cellar + 640, //size_x + 400, //size_y + 56, //grid_width + {R21L0,R21L1,R21L2,0}, //layers + {R21G1,R21G2,0}, //grids + {R21PAL,SPRITE_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 2, //total_layers //room 22 - Castle Gate + 784, //size_x + 400, //size_y + 65, //grid_width + {R22L0,R22L1,0,0}, //layers + {R22G1,0,0}, //grids + {R22PAL,R22SPRPAL}, //palettes + {0,0}, //parallax layers + }, + { + 1, //total_layers //room 23 - Castle Hay Top + 640, //size_x + 400, //size_y + 56, //grid_width + {R23L0,0,0,0}, //layers + {0,0,0}, //grids + {R23PAL,SPRITE_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 2, //total_layers //room 24 - Castle Yard + 880, //size_x + 400, //size_y + 71, //grid_width + {R24L0,R24L1,0,0}, //layers + {R24G1,0,0}, //grids + {R24PAL,SPRITE_PAL}, //palettes + {R24PLX,0}, //parallax layers + }, + { + 2, //total_layers //room 25 - Castle Dig + 640, //size_x + 400, //size_y + 56, //grid_width + {R25L0,R25L1,0,0}, //layers + {R25G1,0,0}, //grids + {R25PAL,R25SPRPAL}, //palettes + {0,0}, //parallax layers + }, + { + 3, //total_layers //room 26 - Cellar Dark + 640, //size_x + 400, //size_y + 56, //grid_width + {R26L0,R26L1,R26L2,0}, //layers + {R26G1,R26G2,0}, //grids + {R26PAL,R26SPRPAL}, //palettes + {0,0}, //parallax layers + }, + + //------------------------------------------------------------------------ + // PARIS 3 + + { + 3, //total_layers //room 27 + 640, //size_x + 400, //size_y + 56, //grid_width + {R27L0,R27L1,R27L2,0}, //layers + {R27G1,R27G2,0}, //grids + {room27_PAL,SPRITE_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 3, //total_layers //room 28 + 640, //size_x + 400, //size_y + 56, //grid_width + {R28L0,R28L1,R28L2,0}, //layers + {R28G1,R28G2,0}, //grids + {R28PAL,R28SPRPAL}, //palettes + {0,0}, //parallax layers + }, + { + 2, //total_layers //room 29 + 640, //size_x + 400, //size_y + 56, //grid_width + {R29L0,R29L1,0,0}, //layers + {R29G1,0,0}, //grids + {R29PAL,R29SPRPAL}, //palettes + {0,0}, //parallax layers + }, + { + 1, //total_layers //room 30 - for MONITOR seen while player in rm34 + 640, //size_x + 400, //size_y + 56, //grid_width + {MONITOR,0,0,0}, //layers + {0,0,0}, //grids + {MONITOR_PAL,PARIS3_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 1, //total_layers //room 31 + 640, //size_x + 400, //size_y + 56, //grid_width + {room31_l0,0,0,0}, //layers + {0,0,0}, //grids + {room31_PAL,PARIS3_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 3, //total_layers //room 32 + 640, //size_x + 400, //size_y + 56, //grid_width + {room32_l0,room32_l1,room32_l2,0}, //layers + {room32_gd1,room32_gd2,0}, //grids + {room32_PAL,PARIS3_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 3, //total_layers //room 33 + 640, //size_x + 400, //size_y + 56, //grid_width + {room33_l0,room33_l1,room33_l2,0}, //layers + {room33_gd1,room33_gd2,0}, //grids + {room33_PAL,PARIS3_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 4, //total_layers //room 34 + 1120, //size_x + 400, //size_y + 86, //grid_width + {room34_l0,room34_l1,room34_l2,room34_l3}, //layers + {room34_gd1,room34_gd2,room34_gd3}, //grids + {room34_PAL,PARIS3_PAL}, //palettes + {R34PLX,0}, //parallax layers + }, + { + 2, //total_layers //room 35 + 640, //size_x + 400, //size_y + 56, //grid_width + {room35_l0,room35_l1,0}, //layers + {room35_gd1,0}, //grids + {room35_PAL,PARIS3_PAL}, //palettes + {0,0}, //parallax layers + }, + + //------------------------------------------------------------------------ + // PARIS 4 + + { + 2, //total_layers //room 36 + 960, //size_x + 400, //size_y + 76, //grid_width + {R36L0,R36L1,0,0}, //layers + {R36G1,0,0}, //grids + {room36_PAL,R36SPRPAL}, //palettes + {R36PLX,0}, //parallax layers + }, + { + 2, //total_layers //room 37 + 640, //size_x + 400, //size_y + 56, //grid_width + {R37L0,R37L1,0,0}, //layers + {R37G1,0,0}, //grids + {room37_PAL,SPRITE_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 2, //total_layers //room 38 + 640, //size_x + 400, //size_y + 56, //grid_width + {R38L0,R38L1,0,0}, //layers + {R38G1,0,0}, //grids + {room38_PAL,R38SPRPAL}, //palettes + {0,0}, //parallax layers + }, + { + 2, //total_layers //room 39 + 640, //size_x + 400, //size_y + 56, //grid_width + {R39L0,R39L1,0,0}, //layers + {R39G1,0,0}, //grids + {room39_PAL,R39SPRPAL}, //palettes + {0,0}, //parallax layers + }, + { + 1, //total_layers //room 40 + 640, //size_x + 400, //size_y + 56, //grid_width + {R40L0,0,0,0}, //layers + {0,0,0}, //grids + {room40_PAL,SPRITE_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 2, //total_layers //room 41 + 640, //size_x + 400, //size_y + 56, //grid_width + {R41L0,R41L1,0,0}, //layers + {R41G1,0,0}, //grids + {room41_PAL,SPRITE_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 3, //total_layers //room 42 + 640, //size_x + 400, //size_y + 56, //grid_width + {R42L0,R42L1,R42L2,0}, //layers + {R42G1,R42G2,0}, //grids + {room42_PAL,SPRITE_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 2, //total_layers //room 43 + 640, //size_x + 400, //size_y + 56, //grid_width + {R43L0,R43L1,0,0}, //layers + {R43G1,0,0}, //grids + {room43_PAL,SPRITE_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 0, //total_layers //room 44 + 0, //size_x + 0, //size_y + 0, //grid_width + {0,0,0,0}, //layers + {0,0,0}, //grids + {0,0}, //palettes + {0,0}, //parallax layers + }, + + //------------------------------------------------------------------------ + // SYRIA + + { + 2, //total_layers //room 45 - Syria Stall + 1152, //size_x + 400, //size_y + 88, //grid_width + {R45L0,R45L1,0,0}, //layers + {R45G1,0,0}, //grids + {R45PAL,R45SPRPAL}, //palettes + {R45PLX,0}, //parallax layers + }, + { + 3, //total_layers //room 46 (Hotel Alley, Paris 2) + 640, //size_x + 400, //size_y + 56, //grid_width + {room46_l0,room46_l1,room46_l2,0}, //layers + {room46_gd1,room46_gd2,0}, //grids + {room46_PAL,PARIS2_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 3, //total_layers //room 47 - Syria Carpet + 640, //size_x + 800, //size_y + 56, //grid_width + {R47L0,R47L1,R47L2,0}, //layers + {R47G1,R47G2,0}, //grids + {R47PAL,SYRIA_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 3, //total_layers //room 48 (Templar Church, Paris 4) + 1184, //size_x + 400, //size_y + 90, //grid_width + {R48L0,R48L1,R48L2,0}, //layers + {R48G1,R48G2,0}, //grids + {R48PAL,R48SPRPAL}, //palettes + {R48PLX,0}, //parallax layers + }, + { + 3, //total_layers //room 49 - Syria Club + 640, //size_x + 400, //size_y + 56, //grid_width + {R49L0,R49L1,R49L2,0}, //layers + {R49G1,R49G2,0}, //grids + {R49PAL,SYRIA_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 4, //total_layers //room 50 - Syria Toilet + 640, //size_x + 400, //size_y + 56, //grid_width + {R50L0,R50L1,R50L2,R50L3}, //layers + {R50G1,R50G2,R50G3}, //grids + {R50PAL,SYRIA_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 0, //total_layers //room 51 - NOT USED + 0, //size_x + 0, //size_y + 0, //grid_width + {0,0,0,0}, //layers + {0,0,0}, //grids + {0,0}, //palettes + {0,0}, //parallax layers + }, + { + 0, //total_layers //room 52 - NOT USED + 0, //size_x + 0, //size_y + 0, //grid_width + {0,0,0,0}, //layers + {0,0,0}, //grids + {0,0}, //palettes + {0,0}, //parallax layers + }, + { + 1, //total_layers //room 53 - Bull Head Pan + 880, //size_x + 1736, //size_y + 71, //grid_width + {R53L0,0,0,0}, //layers + {0,0,0}, //grids + {R53PAL,R53SPRPAL}, //palettes + {FRONT53PLX,BACK53PLX}, //parallax layers + }, + { + 2, //total_layers //room 54 - Bull Head + 896, //size_x + 1112, //size_y + 72, //grid_width + {R54L0,R54L1,0,0}, //layers + {R54G1,0,0}, //grids + {R54PAL,SYRIA_PAL}, //palettes + {R54PLX,0}, //parallax layers - SPECIAL BACKGROUND PARALLAX - MUST GO IN FIRST SLOT + }, + { + 1, //total_layers //room 55 - Bull Secret + 1040, //size_x + 400, //size_y + 81, //grid_width + {R55L0,0,0,0}, //layers + {0,0,0}, //grids + {R55PAL,R55SPRPAL}, //palettes + {R55PLX,0}, //parallax layers + }, + + //------------------------------------------------------------------------ + // SPAIN + + { + 3, //total_layers //room 56 - Countess' room + 640, //size_x + 400, //size_y + 56, //grid_width + {R56L0,R56L1,R56L2,0}, //layers + {R56G1,R56G2,0}, //grids + {R56PAL,SPAIN_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 2, //total_layers //room 57 - Spain Drive + 1760, //size_x + 400, //size_y + 126, //grid_width + {R57L0,R57L1,0,0}, //layers + {R57G1,0,0}, //grids + {R57PAL,SPAIN_PAL}, //palettes + {R57PLX,0}, //parallax layers + }, + { + 2, //total_layers //room 58 - Mausoleum Exterior + 864, //size_x + 400, //size_y + 70, //grid_width + {R58L0,R58L1,0,0}, //layers + {R58G1,0,0}, //grids + {R58PAL,SPAIN_PAL}, //palettes + {R58PLX,0}, //parallax layers + }, + { + 3, //total_layers //room 59 - Mausoleum Interior + 640, //size_x + 400, //size_y + 56, //grid_width + {R59L0,R59L1,R59L2,0}, //layers + {R59G1,R59G2,0}, //grids + {R59PAL,SPAIN_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 3, //total_layers //room 60 - Spain Reception + 640, //size_x + 400, //size_y + 56, //grid_width + {R60L0,R60L1,R60L2,0}, //layers + {R60G1,R60G2,0}, //grids + {R60PAL,SPAIN_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 2, //total_layers //room 61 - Spain Well + 640, //size_x + 400, //size_y + 56, //grid_width + {R61L0,R61L1,0,0}, //layers + {R61G1,0,0}, //grids + {R61PAL,SPAIN_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 1, //total_layers //room 62 - CHESS PUZZLE + 640, //size_x + 400, //size_y + 56, //grid_width + {R62L0,0,0,0}, //layers + {0,0,0}, //grids + {R62PAL,SPRITE_PAL}, //palettes + {0,0}, //parallax layers + }, + + //------------------------------------------------------------------------ + // NIGHT TRAIN + + { + 2, //total_layers //room 63 - train_one + 2160, //size_x + 400, //size_y + 151, //grid_width + {R63L0,R63L1,0,0}, //layers + {R63G1,0,0}, //grids + {R63PAL,TRAIN_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 0, //total_layers //room 64 - NOT USED + 0, //size_x + 0, //size_y + 0, //grid_width + {0,0,0,0}, //layers + {0,0,0}, //grids + {0,0}, //palettes + {0,0}, //parallax layers + }, + { + 2, //total_layers //room 65 - compt_one + 640, //size_x + 400, //size_y + 56, //grid_width + {R65L0,R65L1,0,0}, //layers + {R65G1,0,0}, //grids + {R65PAL,TRAIN_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 1, //total_layers //room 66 - compt_two + 640, //size_x + 400, //size_y + 56, //grid_width + {R66L0,0,0,0}, //layers + {0,0,0}, //grids + {R66PAL,TRAIN_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 2, //total_layers //room 67 - compt_three + 640, //size_x + 400, //size_y + 56, //grid_width + {R67L0,R67L1,0,0}, //layers + {R67G1,0,0}, //grids + {R67PAL,TRAIN_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 0, //total_layers //room 68 - NOT USED + 0, //size_x + 0, //size_y + 0, //grid_width + {0,0,0,0}, //layers + {0,0,0}, //grids + {0,0}, //palettes + {0,0}, //parallax layers + }, + { + 2, //total_layers //room 69 - train_guard + 640, //size_x + 400, //size_y + 56, //grid_width + {R69L0,R69L1,0,0}, //layers + {R69G1,0,0}, //grids + {R69PAL,R69SPRPAL}, //palettes + {0,0}, //parallax layers + }, + { + 0, //total_layers //room 70 - NOT USED + 0, //size_x + 0, //size_y + 0, //grid_width + {0,0,0,0}, //layers + {0,0,0}, //grids + {0,0}, //palettes + {0,0}, //parallax layers + }, + + //------------------------------------------------------------------------ + // SCOTLAND + + { + 2, //total_layers //room 71 - churchyard + 1760, //size_x + 400, //size_y + 126, //grid_width + {R71L0,R71L1,0,0}, //layers + {R71G1,0,0}, //grids + {R71PAL,SPRITE_PAL}, //palettes + {R71PLX,0}, //parallax layers + }, + { + 2, //total_layers //room 72 - church_tower + 640, //size_x + 400, //size_y + 56, //grid_width + {R72L0,R72L1,0,0}, //layers + {R72G1,0,0}, //grids + {R72PAL,SPRITE_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 3, //total_layers //room 73 - crypt + 640, //size_x + 400, //size_y + 56, //grid_width + {R73L0,R73L1,R73L2,0}, //layers + {R73G1,R73G2,0}, //grids + {R73PAL,R73SPRPAL}, //palettes + {0,0}, //parallax layers + }, + { + 2, //total_layers //room 74 - secret_crypt + 1136, //size_x + 400, //size_y + 87, //grid_width + {R74L0,R74L1,0,0}, //layers + {R74G1,0,0}, //grids + {R74PAL,ENDSPRPAL}, //palettes + {0,0}, //parallax layers + }, + { + 1, //total_layers //room 75 - secret_crypt + 640, //size_x + 400, //size_y + 56, //grid_width + {R75L0,0,0,0}, //layers + {0,0,0}, //grids + {R75PAL,ENDSPRPAL}, //palettes + {0,0}, //parallax layers + }, + { + 1, //total_layers //room 76 - secret_crypt + 640, //size_x + 400, //size_y + 56, //grid_width + {R76L0,0,0,0}, //layers + {0,0,0}, //grids + {R76PAL,ENDSPRPAL}, //palettes + {0,0}, //parallax layers + }, + { + 1, //total_layers //room 77 - secret_crypt + 640, //size_x + 400, //size_y + 56, //grid_width + {R77L0,0,0,0}, //layers + {0,0,0}, //grids + {R77PAL,ENDSPRPAL}, //palettes + {0,0}, //parallax layers + }, + { + 1, //total_layers //room 78 - secret_crypt + 640, //size_x + 400, //size_y + 56, //grid_width + {R78L0,0,0,0}, //layers + {0,0,0}, //grids + {R78PAL,ENDSPRPAL}, //palettes + {0,0}, //parallax layers + }, + { + 1, //total_layers //room 79 - secret_crypt + 640, //size_x + 400, //size_y + 56, //grid_width + {R79L0,0,0,0}, //layers + {0,0,0}, //grids + {R79PAL,ENDSPRPAL}, //palettes + {0,0}, //parallax layers + }, + + //------------------------------------------------------------------------ + // MAPS + + { + 1, //total_layers //room 80 - paris map + 640, //size_x + 400, //size_y + 56, //grid_width + {room80_l0,0,0,0}, //layers + {0,0,0}, //grids + {room80_PAL,SPRITE_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 1, //total_layers //room 81 - for sequence of Assassin coming up stairs to rm17 + 640, //size_x + 400, //size_y + 56, //grid_width + {ASSTAIR2,0,0,0}, //layers + {0,0,0}, //grids + {ASSTAIR2_PAL,SPRITE_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 1, //total_layers //room 82 - Map of Britain, viewed frrom sc55 (Syria Cave) + 640, //size_x + 400, //size_y + 56, //grid_width + {BRITMAP,0,0,0}, //layers + {0,0,0}, //grids + {BRITMAP_PAL,SPRITE_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 0, //total_layers //room 83 - NOT USED + 0, //size_x + 0, //size_y + 0, //grid_width + {0,0,0,0}, //layers + {0,0,0}, //grids + {0,0}, //palettes + {0,0}, //parallax layers + }, + { + 0, //total_layers //room 84 - NOT USED + 0, //size_x + 0, //size_y + 0, //grid_width + {0,0,0,0}, //layers + {0,0,0}, //grids + {0,0}, //palettes + {0,0}, //parallax layers + }, + { + 0, //total_layers //room 85 - NOT USED + 0, //size_x + 0, //size_y + 0, //grid_width + {0,0,0,0}, //layers + {0,0,0}, //grids + {0,0}, //palettes + {0,0}, //parallax layers + }, + { + 1, //total_layers //room 86 - europe map + 640, //size_x + 400, //size_y + 56, //grid_width + {room86_l0,0,0,0}, //layers + {0,0,0}, //grids + {room86_PAL,SPRITE_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 1, //total_layers //room 87 - normal window in sc48 + 640, //size_x + 400, //size_y + 56, //grid_width + {WINDOW1,0,0,0}, //layers + {0,0,0}, //grids + {WINDOW1_PAL,SPRITE_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 1, //total_layers //room 88 - filtered window in sc48 + 640, //size_x + 400, //size_y + 56, //grid_width + {WINDOW2,0,0,0}, //layers + {0,0,0}, //grids + {WINDOW2_PAL,SPRITE_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 0, //total_layers //room 89 - NOT USED + 0, //size_x + 0, //size_y + 0, //grid_width + {0,0,0,0}, //layers + {0,0,0}, //grids + {0,0}, //palettes + {0,0}, //parallax layers + }, + { + 1, //total_layers //room 90 - phone screen + 640, //size_x + 400, //size_y + 56, //grid_width + {R90L0,0,0,0}, //layers + {0,0,0}, //grids + {R90PAL,PHONE_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 1, //total_layers //room 91 - envelope screen + 640, //size_x + 400, //size_y + 56, //grid_width + {R91L0,0,0,0}, //layers + {0,0,0}, //grids + {R91PAL,SPRITE_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 1, //total_layers //room 92 - for close up of George surprised in wardrobe in sc17 + 640, //size_x + 400, //size_y + 56, //grid_width + {SBACK17,0,0,0}, //layers + {0,0,0}, //grids + {SBACK17PAL,SPRITE_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 1, //total_layers //room 93 - for close up of George inquisitive in wardrobe in sc17 + 640, //size_x + 400, //size_y + 56, //grid_width + {IBACK17,0,0,0}, //layers + {0,0,0}, //grids + {IBACK17PAL,SPRITE_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 1, //total_layers //room 94 - for close up of George in sarcophagus in sc29 + 640, //size_x + 400, //size_y + 56, //grid_width + {BBACK29,0,0,0}, //layers + {0,0,0}, //grids + {BBACK29PAL,BBACK29SPRPAL}, //palettes + {0,0}, //parallax layers + }, + { + 1, //total_layers //room 95 - for close up of George during templar meeting, in sc38 + 640, //size_x + 400, //size_y + 56, //grid_width + {BBACK38,0,0,0}, //layers + {0,0,0}, //grids + {BBACK38PAL,SPRITE_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 1, //total_layers //room 96 - close up of chalice projection + 640, //size_x + 400, //size_y + 56, //grid_width + {CHALICE42,0,0,0}, //layers + {0,0,0}, //grids + {CHALICE42_PAL,SPRITE_PAL}, //palettes + {0,0}, //parallax layers + }, + { + 0, //total_layers //room 97 - NOT USED + 0, //size_x + 0, //size_y + 0, //grid_width + {0,0,0,0}, //layers + {0,0,0}, //grids + {0,0}, //palettes + {0,0}, //parallax layers + }, + { + 0, //total_layers //room 98 - NOT USED + 0, //size_x + 0, //size_y + 0, //grid_width + {0,0,0,0}, //layers + {0,0,0}, //grids + {0,0}, //palettes + {0,0}, //parallax layers + }, + { + 1, //total_layers //room 99 - blank screen + 640, //size_x + 400, //size_y + 56, //grid_width + {room99_l0,0,0,0}, //layers + {0,0,0}, //grids + {room99_PAL,SPRITE_PAL}, //palettes + {0,0}, //parallax layers + } +}; + +const char SwordMusic::_tuneList[TOTAL_TUNES][8] = { + "", // 0 SPARE + "1m2", // DONE 1 George picks up the newspaper + "1m3", // DONE 2 In the alley for the first time + "1m4", // DONE 3 Alleycat surprises George + "1m6", // DONE 4 George fails to remove manhole cover. Even numbered attempts + "1m7", // !!!! 5 George fails to remove manhole cover. Odd numbered attempts + "1m8", // DONE 6 George leaves alley + "1m9", // DONE 7 George enters cafe for the first time + "1m10", // DONE 8 Waitress + "1m11", // DONE 9 Lying doctor + + "1m12", // DONE 10 Truthful George + "1m13", // DONE 11 Yes, drink brandy + "1m14", // DONE 12 Yes, he's dead (Maybe 1m14a) + "1m15", // DONE 13 From, "...clown entered?" + "1m16", // DONE 14 From, "How did the old man behave?" + "1m17", // DONE 15 Salah-eh-Din + "1m18", // DONE 16 From, "Stay here, mademoiselle" + "1m19", // DONE 17 Leaving the cafe + "1m20", // DONE 18 Stick-up on Moue's gun + "1m21", // DONE 19 From, "Stop that, monsieur" + + "1m22", // DONE 20 From, "If you can" + "1m23", // DONE 21 From, "Yeah,...clown" + "1m24", // DONE 22 From, he claimed to be a doctor + "1m25", // DONE 23 First time George meets Nico + "1m26", // DONE 24 From, "Oh God, him again." (Read notes on list) + "1m27", // DONE 25 From, "He's inside" + "1m28", // DONE 26 From, "You speak very good English" + "1m29", // DONE 27 From, "Why won't you tell me about this clown?" + "1m28a", // DONE 28 Costumed killers from, "How did Plantard get your name?" + "1m30", // DONE 29 From, "I really did see the clown" when talking to Moue at cafe doorway + + "1m31", // DONE 30 From, "I found this (paper) in the street" (talking to Moue) + "1m32", // DONE 31 From, "What's the difference?" + "1m34", // DONE 32 Roadworker "Did you see a clown?" + "1m35", // DONE 33 Worker re: explosion, "I guess not" + "2m1", // DONE 34 From, "What about the waitress?" + "2m2", // DONE 35 From, "Did you see the old guy with the briefcase?" + "2m4", // DONE 36 "Would you like to read my newspaper?" (2M3 is at position 144) + "2m5", // DONE 37 From, "Ah, what's this Saleh-eh-Din?" + "2m6", // DONE 38 From, "It was a battered old tool box". + "2m7", // DONE 39 George "borrows" the lifting key + + "2m8", // DONE 40 From 'phone page. Call Nico + "2m9", // DONE 41 Leaving the workman's tent + "2m10", // DONE 42 Use lifting keys on manhole + "2m11", // DONE 43 Into sewer no.1 from George on his knees (Alternative: 2m12) + "2m12", // DONE 44 Into sewer (alternative to 2m11) + "2m13", // DONE 45 George bends to pick up the red nose + "2m14", // DONE 46 Paper tissue, "It was a soggy..." + "2m15", // DONE 47 Cloth, as George picks it up. (Alternative: 2m16) + "2m16", // !!!! 48 Alternative cloth music + "2m17", // DONE 49 George climbs out of sewer. + + "2m18", // DONE 50 From, "The man I chased..." + "2m19", // DONE 51 Spooky music for sewers. + "2m20", // DONE 52 "She isn't hurt, is she?" + "2m21", // DONE 53 Click on material icon + "2m22", // DONE 54 Spooky music for sewers. + "2m23", // DONE 55 From, "So you don't want to hear my experiences in the desert?" + "2m24", // DONE 56 On the material icon with Albert (suit icon instead, because material icon done) + "2m25", // DONE 57 After "What was on the label?" i.e. the 'phone number. + "2m26", // DONE 58 Leaving yard, after, "I hope you catch that killer soon." Also for the Musee Crune icon on the map (5M7). + "2m27", // DONE 59 As George starts to 'phone Todryk. (Repeated every time he calls him). Also, when the aeroport is clicked on (5M21). + + "2m28", // DONE 60 Todryk conversation after, "Truth and justice" + "2m29", // DONE 61 'Phoning Nico from the roadworks. Also, 'phoning her from Ireland, ideally looping and fading on finish (6M10). + "2m30", // DONE 62 First time on Paris map + "2m31", // DONE 63 Click on Rue d'Alfred Jarry + "2m32", // DONE 64 From, "Will you tell me my fortune?" + "2m33", // DONE 65 After "Can you really tell my future?" + "1m28", // DONE 66 "What about the tall yellow ones?" Copy from 1M28. + "2m24", // DONE 67 Material Icon. Copy from 2M24 + "2m6", // DONE 68 Exit icon on "See you later". Copy from 2M6. + "1m25", // DONE 69 On opening the front foor to Nico's. Copy from 1M25. . + + "2m38", // DONE 70 Victim 1: From, "Tell me more about the clown's previous victims." + "2m39", // DONE 71 Victim 2: After, "What about the clown's second victim?" + "2m40", // DONE 72 Victim 3: On clown icon for 3rd victim. + "3m1", // DONE 73 George passes Nico the nose. + "3m2", // DONE 74 With Nico. From, "I found a piece of material..." + "3m3", // DONE 75 After George says, "... or clowns?" + "3m4", // DONE 76 After, "Did you live with your father?" + "1m28", // DONE 77 After, "Do you have a boyfriend?". Copy from 1M28. + "2m26", // DONE 78 After, "Good idea" (about going to costumier's). Copy from 2M26. + "3m7", // DONE 79 On costumier's icon on map. + + "3m8", // DONE 80 Costumier's, after, "Come in, welcome." + "3m9", // DONE 81 On entering costumier's on later visits + "3m10", // DONE 82 After, "A description, perhaps." + "2m13", // DONE 83 Red nose icon at costumier's. Copy 2M13. + "3m12", // DONE 84 Tissue icon. Also, after Nico's "No, I write it (the magazine) 5M19. + "3m13", // DONE 85 Photo icon over, "Do you recognise this man?" + "3m14", // DONE 86 Exit icon, over, "Thanks for your help, buddy." + "2m9", // DONE 87 Clicking on police station on the map. + "3m17", // DONE 88 Police station on, "I've tracked down the clown's movements." + "3m18", // DONE 89 "One moment, m'sieur," as Moue turns. + + "3m19", // DONE 90 G. on Rosso. "If he was trying to impress me..." + "3m20", // DONE 91 G. thinks, "He looked at me as if I'd farted." + "3m21", // DONE 92 Over Rosso's, "I've washed my hands of the whole affair." + "3m22", // DONE 93 Played over, "So long, inspector." + "3m24", // DONE 94 Conversation with Todrk, "He bought a suit from you, remember?" + "3m26", // !!!! 95 This piece is a problem. Don't worry about it for present. + "3m27", // DONE 96 George to Nico (in the flat): "Have you found out anymore?" [about the murders? or about the templars? JEL] + "2m26", // DONE 97 After, "Don't worry, I will." on leaving Nico's. + "3m29", // DONE 98 Ubu icon on the map. + "3m30", // DONE 99 G and Flap. After, "I love the clowns. Don't you?" AND "after "Not if you see me first" (3M31) + + "3m32", // DONE 100 Source music for Lady Piermont. + "3m33", // DONE 101 More music for Lady P. + "2m13", // DONE 102 Red Nose music Copy 2M13 + "4m3", // DONE 103 On photo, "Do you recognise the man in this photograph" + "4m4", // DONE 104 With Lady P. After, "Hi there, ma'am." + "4m5", // DONE 105 After, "I think the word you're looking for is...dick" + "4m6", // DONE 106 After, "English arrogance might do the trick." Also for "More English arrogance" (4M27) + "4m8", // !!!! 107 As George grabs key. + "4m9", // DONE 108 Room 21, on "Maybe it wasn't the right room" + "4m10", // DONE 109 On coming into 21 on subsequent occasions. + + "4m11", // DONE 110 As George steps upto window. + "4m12", // DONE 111 Alternative times he steps up to the window. + "4m13", // DONE 112 In Moerlin's room + "4m14", // DONE 113 Sees "Moerlin" on the Stairs + "4m15", // DONE 114 George closing wardrobe door aftre Moerlin's gone. + "4m17", // DONE 115 After, "take your mind off the inquest" + "4m18", // DONE 116 "It was just as I'd imagined." + "4m19", // DONE 117 Show photo to Lady P + "4m20", // DONE 118 Lady P is "shocked" after the name "Khan". + "4m21", // DONE 119 After, "A bundle of papers, perhaps". + + "4m22", // DONE 120 After, "Plantard's briefcase" + "4m24", // DONE 121 On fade to black as George leaves the hotel (prior to being searched) + "4m25", // DONE 122 After, "I break your fingers" + "4m28", // DONE 123 After clerk says, "Voila, m'sieur. Le manuscript..." + "4m29", // DONE 124 Onto the window sill after getting the manuscript. + "4m31", // DONE 125 Searched after he's dumped the manuscript in the alleyway. + "4m32", // DONE 126 Recovering the manuscript in the alley, "If the manuscript was..." + "5m1", // DONE 127 The manuscript, just after, "It's worth enough to kill for." + "5m2", // !SMK 128 The Templars after, "...over 800 years ago." + "5m3", // DONE 129 After, "Let's take another look at that manuscript" + + "5m4", // DONE 130 On "Knight with a crystal ball" icon + "5m5", // DONE 131 On Nico's, "Patience" + "5m6", // DONE 132 After "I'm sure it will come in useful" when George leaves. Also, George leaving Nico after, "Keep me informed if you find anything new" (5M20). + "just take care of yourself" + "5m8", // DONE 133 Entering the museum for the first time on the fade. + "5m9", // DONE 134 George with guard after, "park their cars." Guard saying "No, no, no" + "5m10", // DONE 135 Incidental looking around the museum music. + fading from map to museum street, when lobineau is in museum + "5m11", // DONE 136 From "In the case was a spindly tripod, blackened with age and pitted with rust...". George answers Tripod ((?)That's what the cue list says). Also 5M15 and 5M16) + "5m12", // DONE 137 More looking around music. + "5m13", // DONE 138 Opening the mummy case. + "5m14", // DONE 139 High above me was a window + + "5m17", // DONE 140 "As I reached toward the display case" (5M18 is in slot 165) + "5m22", // !SMK 141 From Ireland on the Europe map. + "5m23", // !!!! 142 IN front of the pub, searching. + "5m24", // DONE 143 Cheeky Maguire, "Wait 'til I get back" + "2m3", // DONE 144 Before, "Did anybody at the village work at the dig?" Loop and fade. + "6m1", // DONE 145 After, "You know something ... not telling me, don't you?" + "6m2", // DONE 146 On, "Mister, I seen it with my own eyes." + "6m3", // DONE 147 After, "Did you get to see the ghost" + On George's, "As soon as I saw the flickering torches..." in SCR_SC73.txt. + "6m4", // DONE 148 "the bloody place is haunted", just after G's "rational explanation... the castle" + "6m5", // DONE 149 Pub fiddler 1. Please programme stops between numbers - about 20" and a longer one every four or five minutes. + + "6m6", // DONE 150 Pub fiddler 2. + "6m7", // DONE 151 Pub fiddler 3. + "6m8", // DONE 152 Pub fiddler 4. + "6m12", // DONE 153 Exit pub (as door opens). Copy from 2M6. + "2m6", // DONE 154 Going to the castle, start on the path blackout. + "5m1", // DONE 155 On, "Where was the Templar preceptory?" Copy 5M1 + "6m15", // DONE 156 "On, "Do you mind if I climb up your hay stack..." + "7m1", // DONE 157 On plastic box, "It was a featureless..." + "7m2", // DONE 158 On tapping the plastic box with the sewer key + "7m4", // !!!! 159 "Shame on you, Patrick!" Fitzgerald was at the dig + + "7m5", // !!!! 160 On the icon that leads to, "Maguire says that he saw you at the dig" + "7m6", // !!!! 161 On "The man from Paris" + "7m7", // !!!! 162 On, "I wish I'd never heard of..." + "7m8", // DONE 163 Exit pub + "7m11", // DONE 164 George picks up gem. + "7m14", // DONE 165 On George's icon, "the driver of the Ferrari..." + "7m15", // DONE 166 After George, "His name is Sean Fitzgerald" + "5m18", // DONE 167 Leaving museum after discovering tripod. + "6m11", // !!!! 168 With Fitz. On G's, "Did you work at...?". This is triggered here and on each subsequent question, fading at the end. + "7m17", // DONE 169 "You don't have to demolish the haystack" + + "7m18", // DONE 170 George begins to climb the haystack. + "7m19", // DONE 171 Alternative climbing haystack music. These two tracks can be rotated with an ascent with FX only). + "7m20", // DONE 172 Attempting to get over the wall. + "7m21", // DONE 173 Descending the haystack + "7m22", // !!!! 174 Useful general purpose walking about music. + "7m23", // DONE 175 "Plastic cover" The exposed box, LB and RB. + "7m28", // !!!! 176 "No return" + "7m30", // !!!! 177 Picking up drink music (This will definitely clash with the fiddle music. We'll use it for something else). * + "7m31", // !!!! 178 Showing the landlord the electrician's ID. + "7m32", // !!!! 179 Stealing the wire (Probable clash again) * + + "7m33", // DONE 180 On fade to black before going down into dark cellar. + "7m34", // DONE 181 On opening the grate, as George says, "I lifted the..." Khan's entrance. + "8m1", // DONE 182 Going down into the light cellar, starting as he goes through bar door. + "8m2", // DONE 183 General cellar music on, "It was an empty carton". + "8m4", // !!!! 184 Trying to get the bar towel. On, "The man's arm lay across..." * + "8m7", // DONE 185 Squeeze towel into drain. On, "Silly boy..." + "8m10", // DONE 186 Entering the castle as he places his foot on the tool embedded into the wall. + "8m11", // DONE 187 On, "Hey, billy." Goat confrontation music. + "8m12", // DONE 188 First butt from goat at moment of impact. + "8m13", // DONE 189 On examining the plough. + + "8m14", // DONE 190 Second butt from goat. + "8m15", // DONE 191 Third butt from goat. + "8m16", // DONE 192 All subsequent butts, alternating with no music. + "8m18", // DONE 193 Poking around in the excavation music. I'd trigger it as he starts to descend the ladder into the dig. + "8m19", // DONE 194 "There was a pattern..." The five holes. + "8m20", // DONE 195 George actually touches the stone. Cooling carving (?) + "8m21", // DONE 196 "As I swung the stone upright" coming in on "Upright" + "8m22", // DONE 197 "The sack contained" + "8m24", // DONE 198 Down wall. As screen goes black. George over wall to haystack. + "8m26", // DONE 199 Wetting the towel + + "8m28", // DONE 200 Wetting plaster. As George reaches for the towel prior to wringing water onto the plaster. + "8m29", // DONE 201 Mould in "The hardened plaster..." + "8m30", // DONE 202 Entering castle. As George steps in. + "8m31", // DONE 203 After George, "Hardly - he was dead." in nico_scr.txt + "8m37", // !!!! 204 Talking to Lobineau about the Templars. 5M2Keep looping and fade at the end. + // The problem is that it's an enormous sample and will have to be reduced in volume. + // I suggest forgetting about this one for the time being. + // If there's room when the rest of the game's in, then I'll re-record it more quietly and call it 8M37, okay? + "8m38", // DONE 205 "A female friend" + "8m39", // DONE 206 "Public toilet" + "8m40", // DONE 207 When George asks, "Where was the site at Montfaucon?" (to Lobineau, I suppose) + "8m41", // DONE 208 On matchbox icon. "Does this matchbook mean anything to you?" + "9m1", // DONE 209 On George, "It was the king of France" in ross_scr.txt + + "9m2", // DONE 210 George, "Why do you get wound up...?" in ross_scr.txt + "9m3", // DONE 211 Ever heard of a guy called Marquet? Jacques Marquet? + "9m5", // DONE 212 On fade up at the hospital drive + "9m6", // DONE 213 On fade up inside the hospital + "9m7", // DONE 214 With Eva talking about Marquet. Before, "I'm conducting a private investigation." + "9m8", // DONE 215 With Eva, showing her the ID card. + "9m9", // DONE 216 With Eva, second NURSE click, "If nurse Grendel is that bad..." + "9m10", // DONE 217 Saying goodbye to Eva on the conversation where he discovers Marquet's location + on fade up on Sam's screen after being kicked off the ward + "9m11", // DONE 218 Talking to Sam. On, "Oh - hiya!" + first click on MR_SHINY + "9m13", // DONE 219 When George drinks from the cooler. + + "9m14", // DONE 220 To Grendel, third MARQUET click. On "Do you know who paid for Marquet's room?" + "9m15", // DONE 221 To Grendel on first CLOWN click, "Do you have any clowns on the ward?" + "9m17", // DONE 222 When George pulls Shiny's plug the first time, on "As I tugged the plug..." + "9m18", // DONE 223 On subsequent plug tuggings if George has failed to get the white coat. + "9m19", // DONE 224 With the consultant, on "Excuse me, sir..." + "9m20", // DONE 225 Talking to Grendel. Launch immediately after she gives him the long metal box and "a stunning smile" + "9m21", // DONE 226 On Eric's, "Doctor!" when George is trying to get by for the first time, i.e. ward_stop_flag==0. + "9m22", // DONE 227 On Eric's, "Oh, Doctor!" when George is trying to get by for the second time, i.e. ward_stop_flag==1. + "9m23", // DONE 228 On Eric's, "You haven't finished taking my blood pressure!" when George is trying to get by for the third+ time, i.e. ward_stop_flag>1. + "9m24", // DONE 229 Giving the pressure gauge to Benoir, on, "Here, take this pressure gauge." + + "9m25", // DONE 230 With Benoir, suggesting he use the gauge on the nurse. On, "Use it on Nurse Grendel." + "10m1", // DONE 231 Immediately after Marquet's, "Well, what are you waiting for? Get it over with!" + "10m2", // DONE 232 When George pulls open the sarcophagus lid prior to his successful hiding before the raid. + "10m3", // DONE 233 On fade to black as George spies on the Neo-Templars. + "10m4", // DONE 234 On second peer through the hole at the "Templars" + "11m1", // DONE 235 On clicking on the Marib button. + "11m3", // DONE 236 Loop in the Club Alamut, alternating with... + "11m4", // DONE 237 Loop in the Club Alamut. + "11m7", // DONE 238 When the door in the Bull's Mouth closes on George. + "11m8", // DONE 239 When the door opens to reveal Khan, immediately after, "You!" in KHAN_55.TXT. + + "11m9", // !SMK 240 Over the "Going to the Bull's Head" smacker. Probably. + "12m1", // DONE 241 Clicking on the Spain icon from the aeroport. (AFTER CHANGING CD!) + "11m2", // DONE 242 Loop in the marketplace of Marib. + "spm2", // DONE 243 On fade up in the Countess' room for the first time. + "spm3", // DONE 244 At the end of VAS1SC56, triggered immediately before the Countess says, "Senor Stobbart, if I find that you are wasting my time..." + "spm4", // DONE 245 Immediately before Lopez enters the mausoleum with the chess set. + "spm5", // DONE 246 (This is actually 5m2 copied for CD2) Played through the chess puzzle. Ideally, when it finsishes, give it a couple of seconds and then launch 12m1. When that finishes, a couple of seconds and then back to this and so on and so forth. + "spm6", // DONE 247 On fade up from completing the chess puzzle. The climax is now "spm6b" + "scm1", // DONE 248 This is used whenever George goes out of a carriage and onto the corridor. + "scm2", // DONE 249 As George climbs out of the train window. + + "scm3", // DONE 250 As George lands inside the guard's van. + "scm4", // DONE 251 On Khan's death speech, "A noble foe..." + "scm5", // DONE 252 George to Khan. On, "You're talking in riddles!" + "scm6", // DONE 253 Before, "He's dead" + "scm7", // DONE 254 Kissing Nico. After, "Where do you think you're going?" + "scm8", // DONE 255 In the churchyard after Nico's, "I rather hope it did" + "scm11", // DONE 256 Click on the opened secret door. + "rm3a", // DONE 257 Immediately they fade up in the great cave. + "rm3b", // DONE 258 The scene change immediately after Eklund says, "If you wish to live much longer..." + "scm16", // DONE 259 The big end sequence from when the torch hits the gunpowder. Cross fade with the shortened version that fits on the Smacker. + + "scm1b", // DONE 260 When George passes the trigger point toward the back of the train and he sees Guido. + "spm6b", // DONE 261 The climax of "spm6", which should coincide with the Countess holding up the chalice. + "marquet", // DONE 262 Starts at the fade down when George is asked to leave Jacques' room + "rm4", // DONE 263 "On crystal stand icon. As George walks to the centre of the cavern." I'd do this on the first LMB on the stump. + "rm5", // DONE 264 "On icon. As George places the crystal on top of the stand." When the player places the gem luggage on the emplaced tripod. + "rm6", // DONE 265 "Chalice reflection. On icon as George places Chalice on floor of Church" i.e. the mosaic in the Baphomet dig. It's over thirty seconds long so it had best start running when the chalice luggage is placed on the mosaic so it runs through the big screen of the reflection. + "rm7", // DONE 266 "Burning candle. On icon as George sets about lighting candle." One minute forty-eight, this one. I've no idea how long the burning candle Smacker is but the cue description seems to indicate it should run from the moment the burning tissue successfully lights the candle, i.e. the window is shut. + "rm8", // DONE 267 "Down well. George descends into circus trap well." I think the circus reference refers to the lion. Run it from the moment that George gets off the rope and has a look around. Run it once only. + + "rm3c", // DONE 268 On the scene change to the Grand Master standing between the pillars as the earth power whomps him. + "rm3d", // DONE 269 ONe the scene change after the Grand Master says, "George, we have watched you..." This one might need a bit of fiddling to get it to match to the fisticuffs. +}; + +const FxDef SwordSound::_fxList[312] = { + // 0 + { + 0, // sampleId + 0, // type (FX_LOOP, FX_RANDOM or FX_SPOT) + 0, // delay (random chance for FX_RANDOM sound fx) + { // roomVolList + {0,0,0}, // {roomNo,leftVol,rightVol} + }, + }, + //------------------------ + // 1 Newton's cradle. Anim=NEWTON. + { + FX_NEWTON, // sampleId + FX_SPOT, // type + 7, // delay (or random chance) + { // roomVolList + {45,4,2}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 2 + { + FX_TRAFFIC2, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) + { // roomVolList + {1,12,12}, // {roomNo,leftVol,rightVol} + {2,1,1}, + {3,1,1}, + {4,13,13}, + {5,1,1}, + {8,7,7}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 3 + { + FX_HORN1, // sampleId + FX_RANDOM, // type + 1200, // delay (or random chance) + { // roomVolList + {1,3,3}, // {roomNo,leftVol,rightVol} + {3,1,1}, + {4,1,1}, + {5,2,2}, + {8,4,4}, + {18,2,3}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 4 + { + FX_HORN2, // sampleId + FX_RANDOM, // type + 1200, // delay (or random chance) + { // roomVolList + {1,4,4}, // {roomNo,leftVol,rightVol} + {3,2,2}, + {4,3,3}, + {5,2,2}, + {8,4,4}, + {18,1,1}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 5 + { + FX_HORN3, // sampleId + FX_RANDOM, // type + 1200, // delay (or random chance) + { // roomVolList + {1,4,4}, // {roomNo,leftVol,rightVol} + {2,4,4}, + {3,2,2}, + {4,3,3}, + {5,2,2}, + {8,4,4}, + {18,1,1}, + }, + }, + //------------------------ + // 6 + { + FX_CAMERA1, // sampleId + FX_SPOT, // type + 25, // delay (or random chance) + { // roomVolList + {1,8,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 7 + { + FX_CAMERA2, // sampleId + FX_SPOT, // type + 25, // delay (or random chance) + { // roomVolList + {1,8,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 8 + { + FX_CAMERA3, // sampleId + FX_SPOT, // type + 25, // delay (or random chance) + { // roomVolList + {1,8,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 9 + { + FX_SWATER1, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) + { // roomVolList + {7,12,12}, // {roomNo,leftVol,rightVol} + {6,12,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 10 Mad dogs in Spain, triggered by George going around the corner in the villa hall. + // In 56 and 57, the dogs will continue barking after George has either been ejected or sneaked up stairs + // for a couple of loops before stopping. + { + FX_DOGS56, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) + { // roomVolList + {60,16,16}, // {roomNo,leftVol,rightVol} + {0,0,0} // NULL-TERMINATOR + }, + }, + //------------------------ + // 11 + { + FX_DRIP1, // sampleId + FX_RANDOM, // type + 20, // delay (or random chance) + { // roomVolList + {7,15,15}, // {roomNo,leftVol,rightVol} + {6,8,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 12 + { + FX_DRIP2, // sampleId + FX_RANDOM, // type + 30, // delay (or random chance) + { // roomVolList + {7,15,15}, // {roomNo,leftVol,rightVol} + {6,8,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 13 + { + FX_DRIP3, // sampleId + FX_RANDOM, // type + 40, // delay (or random chance) + { // roomVolList + {7,15,15}, // {roomNo,leftVol,rightVol} + {6,8,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 14 + { + FX_TWEET1, // sampleId + FX_SPOT, // type + 10, // delay (or random chance) + { // roomVolList + {1,5,5}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 15 + { + FX_TWEET2, // sampleId + FX_SPOT, // type + 10, // delay (or random chance) + { // roomVolList + {1,5,5}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 16 + { + FX_TWEET3, // sampleId + FX_SPOT, // type + 10, // delay (or random chance) + { // roomVolList + {1,5,5}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 17 + { + FX_TWEET4, // sampleId + FX_SPOT, // type + 10, // delay (or random chance) + { // roomVolList + {1,5,5}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 18 + { + FX_TWEET5, // sampleId + FX_SPOT, // type + 10, // delay (or random chance) + { // roomVolList + {1,5,5}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 19 Tied to large bird flying up screen anim + { + FX_CAW1, // sampleId + FX_SPOT, // type + 20, // delay (or random chance) + { // roomVolList + {1,5,5}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + //------------------------ + // 20 George picking the canopy up: GEOCAN + { + FX_CANUP, // sampleId + FX_SPOT, // type + 5, // delay (or random chance) * + { // roomVolList + {1,10,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 21 George dropping the canopy: GEOCAN + { + FX_CANDO, // sampleId + FX_SPOT, // type + 52, // delay (or random chance) * + { // roomVolList + {1,10,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 22 George dusts himself down: GEOCAN + { + FX_DUST, // sampleId + FX_SPOT, // type + 58, // delay (or random chance) * + { // roomVolList + {1,10,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 23 George picks up the paper and opens it: GEOPAP + { + FX_PAP1, // sampleId + FX_SPOT, // type + 23, // delay (or random chance) * + { // roomVolList + {1,10,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 24 George puts the paper away: GEOPAP2 + { + FX_PAP2, // sampleId + FX_SPOT, // type + 3, // delay (or random chance) * + { // roomVolList + {1,10,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 25 George gives the paper away: GEOWRK8 + { + FX_PAP3, // sampleId + FX_SPOT, // type + 13, // delay (or random chance) * + { // roomVolList + {4,14,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 26 Workman examines paper: WRKOPN - it's now just WRKPPR + { + FX_PAP4, // sampleId + FX_SPOT, // type + 15, // delay (or random chance) * + { // roomVolList + {4,14,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 27 Workman puts paper down: WRKOPN (REVERSED) - now just WRKCLM + { + FX_PAP5, // sampleId + FX_SPOT, // type + 2, // delay (or random chance)* + { // roomVolList + {4,14,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 28 Pickaxe sound 1:, Screen 4 - WRKDIG + { + FX_PICK1, // sampleId + FX_SPOT, // type + 11, // delay (or random chance) * + { // roomVolList + {4,10,10}, + {0,0,0} // NULL-TERMINATOR + }, + }, + //------------------------ + // 29 Pickaxe sound 2:, Screen 4 - WRKDIG + { + FX_PICK2, // sampleId + FX_SPOT, // type + 11, // delay (or random chance) * + { // roomVolList + {4,10,10}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + //------------------------ + // 30 Pickaxe sound 3:, Screen 4 - WRKDIG + { + FX_PICK3, // sampleId + FX_SPOT, // type + 11, // delay (or random chance) * + { // roomVolList + {4,10,10}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 31 Pickaxe sound 4:, Screen 4 - WRKDIG + { + FX_PICK4, // sampleId + FX_SPOT, // type + 11, // delay (or random chance) * + { // roomVolList + {4,10,10}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 32 Shorting light: FLICKER + { + FX_LIGHT, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) * + { // roomVolList + {3,15,15}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 33 Cat leaps out of bin and runs: CATJMP! + { + FX_CAT, // sampleId + FX_SPOT, // type + 20, // delay (or random chance) * + { // roomVolList + {2,10,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 34 George rocks plastic crate: GEOCRT + { + FX_CRATE, // sampleId + FX_SPOT, // type + 10, // delay (or random chance) * + { // roomVolList + {2,8,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 35 George tries to climb drainpipe: GEOCLM02 + { + FX_DRAIN, // sampleId + FX_SPOT, // type + 9, // delay (or random chance) * + { // roomVolList + {2,10,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 36 George removes manhole cover: GEOMAN8 + { + FX_HOLE, // sampleId + FX_SPOT, // type + 19, // delay (or random chance) ? + { // roomVolList + {2,12,11}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 37 Brandy bottle put down: CHNDRN + { + FX_BOTDN, // sampleId + FX_SPOT, // type + 43, // delay (or random chance) * + { // roomVolList + {3,8,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 38 Brandy bottle picked up: GEOBOT3 + { + FX_BOTUP, // sampleId + FX_SPOT, // type + 9, // delay (or random chance) * + { // roomVolList + {3,10,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 39 Chantelle gulps on brandy: CHNDRN + { + FX_GULP, // sampleId + FX_SPOT, // type + 23, // delay (or random chance) * + { // roomVolList + {3,4,3}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 40 Chantelle picked up off the floor: GEOCHN + { + FX_PIKUP, // sampleId + FX_SPOT, // type + 28, // delay (or random chance) * + { // roomVolList + {3,11,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 41 George searches Plantard's body: GEOCPS + { + FX_BODY, // sampleId + FX_SPOT, // type + 10, // delay (or random chance) * + { // roomVolList + {3,10,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 42 Moue cocks handgun. MOUENT + { + FX_PISTOL, // sampleId + FX_SPOT, // type + 23, // delay (or random chance) * + { // roomVolList + {4,4,7}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 43 George rummages in toolbox: GEOTBX + { + FX_TBOX, // sampleId + FX_SPOT, // type + 12, // delay (or random chance) * + { // roomVolList + {4,12,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 44 rat squeak 1 + { + FX_RAT1, // sampleId + FX_RANDOM, // type + 193, // delay (or random chance) + { // roomVolList + {6,5,7}, // {roomNo,leftVol,rightVol} + {7,5,3}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 45 rat squeak 2 + { + FX_RAT2, // sampleId + FX_RANDOM, // type + 201, // delay (or random chance) + { // roomVolList + {6,3,5}, // {roomNo,leftVol,rightVol} + {7,4,6}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 46 George climbs down ladder: + { + FX_LADD1, // sampleId + FX_SPOT, // type + 10, // delay (or random chance) + { // roomVolList + {6,10,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 47 Rushing water loop + { + FX_SWATER3, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) + { // roomVolList + {6,10,11}, // {roomNo,leftVol,rightVol} + {7,12,11}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 48 Left hand bin being opened: GEOCAT? + { + FX_BIN3, // sampleId + FX_SPOT, // type + 12, // delay (or random chance) + { // roomVolList + {2,12,11}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 49 Middle bin being opened: GEOBIN + { + FX_BIN2, // sampleId + FX_SPOT, // type + 12, // delay (or random chance) + { // roomVolList + {2,11,11}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 50 Right hand bin being opened: GEOLID? + { + FX_BIN1, // sampleId + FX_SPOT, // type + 12, // delay (or random chance) + { // roomVolList + {2,10,11}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 51 Passing car sound + { + FX_CARS, // sampleId + FX_RANDOM, // type + 120, // delay (or random chance) + { // roomVolList + {10,8,1}, + {12,7,7}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 52 Passing car sound + { + FX_FIESTA, // sampleId + FX_RANDOM, // type + 127, // delay (or random chance) + { // roomVolList + {10,8,1}, + {12,7,7}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 53 Passing car sound + { + FX_CARLTON , // sampleId + FX_RANDOM, // type + 119, // delay (or random chance) + { // roomVolList + {10,8,1}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 54 Bird + { + FX_BIRD, // sampleId + FX_RANDOM, // type + 500, // delay (or random chance) + { // roomVolList + {9,10,10}, // {roomNo,leftVol,rightVol} + {10,2,1}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 55 George tries the door: GEOTRY + { + FX_DOORTRY, // sampleId + FX_SPOT, // type + 7, // delay (or random chance) + { // roomVolList + {9,9,9}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 56 George opens the door: GEODOOR9 + { + FX_FLATDOOR, // sampleId + FX_SPOT, // type + 10, // delay (or random chance) + { // roomVolList + {9,9,9}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 57 George picks the 'phone up: GEOPHN10 + { + FX_FONEUP, // sampleId + FX_SPOT, // type + 15, // delay (or random chance) + { // roomVolList + {10,9,9}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 58 George puts the 'phone down: GEPDWN10 + { + FX_FONEDN, // sampleId + FX_SPOT, // type + 4, // delay (or random chance) + { // roomVolList + {10,9,9}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 59 Albert opens the door: ALBOPEN + { + FX_ALBOP, // sampleId + FX_SPOT, // type + 13, // delay (or random chance) + { // roomVolList + {5,10,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + //------------------------ + // 60 Albert closes the door: ALBCLOSE + { + FX_ALBCLO, // sampleId + FX_SPOT, // type + 20, // delay (or random chance) + { // roomVolList + {5,9,9}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 61 George enter Nico's flat. GEOENT10 + { + FX_NICOPEN, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) + { // roomVolList + {10,7,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 62 George leaves Nico's. GEOLVS10 + { + FX_NICLOSE, // sampleId + FX_SPOT, // type + 13, // delay (or random chance) + { // roomVolList + {10,7,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 63 Another bird for the street. + { + FX_BIRD2, // sampleId + FX_RANDOM, // type + 500, // WAS 15 (TOO LATE) + { // roomVolList + {9,10,10}, // {roomNo,leftVol,rightVol} + {10,2,1}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 64 George sits in the chair: GEOCHR + { + FX_GEOCHAIR, // sampleId + FX_SPOT, // type + 14, // delay (or random chance) + { // roomVolList + {10,5,5}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 65 George sits on the couch: GEOCCH + { + FX_GEOCCH, // sampleId + FX_SPOT, // type + 14, // delay (or random chance) + { // roomVolList + {10,5,5}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 66 George gets up from the chair: GEOCHR9 + { + FX_GEOCHR9, // sampleId + FX_SPOT, // type + 5, // delay (or random chance) + { // roomVolList + {10,3,3}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 67 George is electrocuted: COSSHK + { + FX_SHOCK1, // sampleId + FX_SPOT, // type + 19, // delay (or random chance) + { // roomVolList + {11,10,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 68 George plays record: GEOWIND + { + FX_GRAMOFON, // sampleId + FX_SPOT, // type + 0, // delay (or random chance) + { // roomVolList + {11,11,13}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 69 George is frisked: GORFRK + { + FX_FRISK, // sampleId + FX_SPOT, // type + 6, // delay (or random chance) + { // roomVolList + {12,8,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 70 Traffic sound + { + FX_TRAFFIC3, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) + { // roomVolList + {11,5,4}, + {12,1,1}, + {16,4,4}, + {18,2,3}, + {46,4,3}, + {0,0,0}, // NULL-TERMINATOR + } + }, + //------------------------ + // 71 Latvian reading: LATRDS + { + FX_PAPER6, // sampleId + FX_SPOT, // type + 8, // delay (or random chance) + { // roomVolList + {13,8,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 72 Deskbell + { + FX_DESKBELL, // sampleId + FX_SPOT, // type + 0, // delay (or random chance) + { // roomVolList + {13,10,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 73 George picks up hotel 'phone: GEOTEL + { + FX_PHONEUP2, // sampleId + FX_SPOT, // type + 10, // delay (or random chance) + { // roomVolList + {13,8,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 74 George puts down hotel 'phone: GEOTEL9 + { + FX_PHONEDN2, // sampleId + FX_SPOT, // type + 10, // delay (or random chance) + { // roomVolList + {13,8,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 75 George tries doors in corridor: GEODOR + { + FX_TRYDOR14, // sampleId + FX_SPOT, // type + 10, // delay (or random chance) + { // roomVolList + {14,8,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 76 George opens bedside cabinet: BEDDOR + { + FX_CABOPEN, // sampleId + FX_SPOT, // type + 11, // delay (or random chance) + { // roomVolList + {15,10,14}, // {roomNo,leftVol,rightVol} + {17,10,14}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 77 George closes bedside cabinet: BEDDOR (reversed) + { + FX_CABCLOSE, // sampleId + FX_SPOT, // type + 5, // delay (or random chance) + { // roomVolList + {15,10,14}, // {roomNo,leftVol,rightVol} + {17,10,14}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 78 George opens the window: WINDOW + { + FX_WINDOPEN, // sampleId + FX_SPOT, // type + 19, // delay (or random chance) + { // roomVolList + {15,8,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 79 George goes right along the ledge: GEOIRW + { + FX_LEDGE1, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) + { // roomVolList + {16,12,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + //------------------------ + // 80 George goes left along the ledge: GEOILW + { + FX_LEDGE2, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) + { // roomVolList + {16,12,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 81 Pigeon noises + { + FX_COO, // sampleId + FX_RANDOM, // type + 80, // delay (or random chance) + { // roomVolList + {16,7,9}, // {roomNo,leftVol,rightVol} + {46,5,4}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 82 Pigeon noises + { + FX_COO2, // sampleId + FX_RANDOM, // type + 60, // delay (or random chance) + { // roomVolList + {15,3,4}, // {roomNo,leftVol,rightVol} + {16,8,5}, // {roomNo,leftVol,rightVol} + {17,3,4}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 83 George picks up and opens case: GEOBFC + { + FX_BRIEFON, // sampleId + FX_SPOT, // type + 16, // delay (or random chance) + { // roomVolList + {17,12,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 84 George closes and puts down case: GEOBFC (reversed) + { + FX_BRIEFOFF, // sampleId + FX_SPOT, // type + 12, // delay (or random chance) + { // roomVolList + {17,12,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 85 George gets into wardrobe. GEOWRB2 Attention, James. This is new as of 15/7/96 + { + FX_WARDIN, // sampleId + FX_SPOT, // type + 6, // delay (or random chance) + { // roomVolList + {17,4,4}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 86 George gets out of wardrobe. GEOWRB2 (Reversed). Attention, James. This is new as of 15/7/96 + { + FX_WARDOUT, // sampleId + FX_SPOT, // type + 41, // delay (or random chance) + { // roomVolList + {17,4,4}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 87 George jumps in through window: GEOWIN2 + { + FX_JUMPIN, // sampleId + FX_SPOT, // type + 7, // delay (or random chance) + { // roomVolList + {15,8,10}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 88 George climbs in: GEOWIN2/GEOWIN8 + { + FX_CLIMBIN, // sampleId + FX_SPOT, // type + 0, // delay (or random chance) + { // roomVolList + {17,8,16}, // {roomNo,leftVol,rightVol} + {15,8,16}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 89 George climbs out: GEOWIN1/GEOWIN9 + { + FX_CLIMBOUT, // sampleId + FX_SPOT, // type + 17, // delay (or random chance) + { // roomVolList + {17,9,10}, // {roomNo,leftVol,rightVol} + {15,9,10}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 90 George picks the 'phone up: GEOTEL18 + { + FX_FONEUP, // sampleId + FX_SPOT, // type + 10, // delay (or random chance) + { // roomVolList + {18,4,3}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 91 George puts the 'phone down: GEOTL18A + { + FX_FONEDN, // sampleId + FX_SPOT, // type + 11, // delay (or random chance) + { // roomVolList + {18,4,3}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 92 George tries to get keys. GEOKEY + { + FX_KEY13, // sampleId + FX_SPOT, // type + 8, // delay (or random chance) + { // roomVolList + {13,3,2}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 93 George manages to get keys. GEOKEY13 + { + FX_KEY13, // sampleId + FX_SPOT, // type + 9, // delay (or random chance) + { // roomVolList + {13,3,2}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 94 George electrocutes Maguire: MAGSHK + { + FX_SHOCK2, // sampleId + FX_SPOT, // type + 8, // delay (or random chance) + { // roomVolList + {19,9,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 95 George opens dray door : GEOTRP8 + { + FX_TRAPOPEN, // sampleId + FX_SPOT, // type + 20, // delay (or random chance) + { // roomVolList + {19,10,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 96 George breaks switch : Which anim? + { + FX_SWITCH19, // sampleId + FX_SPOT, // type + 10, // delay (or random chance) + { // roomVolList + {19,10,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 97 Leary pulls pint: LESPMP + { + FX_PULLPINT, // sampleId + FX_SPOT, // type + 6, // delay (or random chance) + { // roomVolList + {20,10,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 98 Glasswasher fuse blows (and the glass washer grinds to a halt) + { + FX_FUSE20, // sampleId + FX_SPOT, // type + 0, // delay (or random chance) + { // roomVolList + {20,8,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 99 Fitz leaps to his feet: FTZSTD + { + FX_FITZUP, // sampleId + FX_SPOT, // type + 5, // delay (or random chance) + { // roomVolList + {20,8,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + //------------------------ + // 100 Fitz runs for it: FTZRUN + { + FX_FITZRUN, // sampleId + FX_SPOT, // type + 15, // delay (or random chance) + { // roomVolList + {20,12,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 101 George pulls lever: GEOLVR & GEOLVR26 + { + FX_LEVER, // sampleId + FX_SPOT, // type + 26, // delay (or random chance) + { // roomVolList + {21,8,10}, // {roomNo,leftVol,rightVol} + {26,8,10}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 102 George pulls lever: GEOLVR8 & GEOLVR08 + { + FX_LEVER2, // sampleId + FX_SPOT, // type + 9, // delay (or random chance) + { // roomVolList + {21,8,10}, // {roomNo,leftVol,rightVol} + {26,8,10}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 103 George opens tap: No idea what the anim is + { + FX_TAP, // sampleId + FX_SPOT, // type + 10, // delay (or random chance) + { // roomVolList + {21,8,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 104 George closes tap: No idea what this anim is either + { + FX_TAP2, // sampleId + FX_SPOT, // type + 10, // delay (or random chance) + { // roomVolList + {21,8,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 105 Bar flap: FLPOPN + { + FX_BARFLAP, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) + { // roomVolList + {20,6,6}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 106 Farmer leaves: FRMWLK + { + FX_FARMERGO, // sampleId + FX_SPOT, // type + 11, // delay (or random chance) + { // roomVolList + {22,6,9}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 107 George climbs haystack: GEOCLM + { + FX_CLIMBHAY, // sampleId + FX_SPOT, // type + 11, // delay (or random chance) + { // roomVolList + {22,14,14}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 108 George drives sewer key into wall: GEOKEY23 + { + FX_KEYSTEP, // sampleId + FX_SPOT, // type + 39, // delay (or random chance) + { // roomVolList + {23,8,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 109 George climbs over wall: GEOCLM23 + { + FX_CASTLWAL, // sampleId + FX_SPOT, // type + 17, // delay (or random chance) + { // roomVolList + {23,8,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + //------------------------ + // 110 George falls from wall: GEOTRY23 + { + FX_CLIMBFAL, // sampleId + FX_SPOT, // type + 43, // delay (or random chance) + { // roomVolList + {23,12,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 111 Goat chewing: GOTEAT + { + FX_GOATCHEW, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) + { // roomVolList + {24,10,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 112 George moves plough: GEOPLW + { + FX_PLOUGH, // sampleId + FX_SPOT, // type + 8, // delay (or random chance) + { // roomVolList + {24,10,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 113 George drops slab: STNFALL + { + FX_SLABFALL, // sampleId + FX_SPOT, // type + 6, // delay (or random chance) + { // roomVolList + {25,10,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 114 George picks up slab: GEOSTN8 + { + FX_SLABUP, // sampleId + FX_SPOT, // type + 29, // delay (or random chance) + { // roomVolList + {25,10,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 115 Secret door opens: ALTOPN + { + FX_SECDOR25, // sampleId + FX_SPOT, // type + 17, // delay (or random chance) + { // roomVolList + {25,10,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 116 George wrings out cloth: GEOTWL25 + { + FX_WRING, // sampleId + FX_SPOT, // type + 24, // delay (or random chance) + { // roomVolList + {25,10,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 117 Rat running across barrels: RATJMP + { + FX_RAT3A, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) + { // roomVolList + {26,8,5}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 118 Rat running across barrels: RATJMP + { + FX_RAT3B, // sampleId + FX_SPOT, // type + 8, // delay (or random chance) + { // roomVolList + {26,7,6}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 119 Rat running across barrels: RATJMP + { + FX_RAT3C, // sampleId + FX_SPOT, // type + 26, // delay (or random chance) + { // roomVolList + {26,8,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + //------------------------ + // 120 Irish bird song 1: + { + FX_EIRBIRD1, // sampleId + FX_RANDOM, // type + 720, // delay (or random chance) + { // roomVolList + {19,6,8}, // {roomNo,leftVol,rightVol} + {21,2,3}, + {22,8,5}, + {23,6,5}, + {24,8,8}, + {0,0,0}, // NULL-TERMINATOR + } + }, + //------------------------ + // 121 Irish bird song 2: + { + FX_EIRBIRD2, // sampleId + FX_RANDOM, // type + 720, // delay (or random chance) + { // roomVolList + {19,8,6}, // {roomNo,leftVol,rightVol} + {21,2,3}, + {22,6,8}, + {23,5,5}, + {24,8,8}, + {0,0,0}, // NULL-TERMINATOR + } + }, + //------------------------ + // 122 Irish bird song 3: + { + FX_EIRBIRD3, // sampleId + FX_RANDOM, // type + 720, // delay (or random chance) + { // roomVolList + {19,8,8}, // {roomNo,leftVol,rightVol} + {21,3,4}, + {22,8,8}, + {23,5,6}, + {24,6,8}, + {0,0,0}, // NULL-TERMINATOR + } + }, + //------------------------ + // 123 Rat 3D: + { + FX_RAT3D, // sampleId + FX_RANDOM, // type + 600, // delay (or random chance) + { // roomVolList + {26,2,3}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + } + }, + //------------------------ + // 124 Wind atop the battlements + { + FX_WIND, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) + { // roomVolList + {23,6,6}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + } + }, + //------------------------ + // 125 Glasswasher in the pub (Room 20) *JEL* Stops after fuse blows and starts when george fixes it. + { + FX_WASHER, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) + { // roomVolList + {20,4,4}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + } + }, + //------------------------ + // 126 Running tap in the cellar: (Room 21) *JEL* Only when the tap is on. + { + FX_CELTAP, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) + { // roomVolList + {21,3,3}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + } + }, + //------------------------ + // 127 Lopez's hose. Basically a loop but stops when George cuts the water supply. Replaces MUTTER1. + { + FX_HOSE57, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) + { // roomVolList + {57,3,1}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + } + }, + //------------------------ + // 128 Lopez's hose being switched off. Anim GARD05. Replaces MUTTER2. + { + FX_HOSE57B, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) + { // roomVolList + {57,3,2}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + } + }, + //------------------------ + // 129 Nejo bouncing the ball off the door. NEJ8 + { + FX_BALLPLAY, // sampleId + FX_SPOT, // type + 13, // delay (or random chance) + { // roomVolList + {45,5,1}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + } + }, + //------------------------ + //------------------------ + // 130 Cricket loop for Syrian desert Only audible in 55 when the cave door is open. + { + FX_CRICKET, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) + { // roomVolList + {54,8,8}, // {roomNo,leftVol,rightVol} + {55,3,5}, + {0,0,0}, // NULL-TERMINATOR + } + }, + //------------------------ + // 131 Display case shatters: GEOTOTB + { + FX_SMASHGLA, // sampleId + FX_SPOT, // type + 35, // delay (or random chance) + { // roomVolList + {29,16,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + } + }, + //------------------------ + // 132 Burglar alarm: Once the case is smashed (see 131) + { + FX_ALARM, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) + { // roomVolList + {28,12,12}, // {roomNo,leftVol,rightVol} + {29,16,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + } + }, + //------------------------ + // 133 Guido fires: GUIGUN + { + FX_GUN1, // sampleId + FX_SPOT, // type + 7, // delay (or random chance) + { // roomVolList + {29,16,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + } + }, + //------------------------ + // 134 Guido knocked down: NICPUS1 + { + FX_GUI_HIT, // sampleId + FX_SPOT, // type + 40, // delay (or random chance) + { // roomVolList + {29,10,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + } + }, + //------------------------ + // 135 Museum exterior ambience + { + FX_MUESEXT, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) + { // roomVolList + {27,10,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + } + }, + //------------------------ + // 136 Cat gets nowty: CAT3 + { + FX_STALLCAT, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) + { // roomVolList + {45,10,6}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + } + }, + //------------------------ + // 137 Cat gets very nowty: CAT5 + { + FX_CATHIT, // sampleId + FX_SPOT, // type + 4, // delay (or random chance) + { // roomVolList + {45,10,6}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + } + }, + //------------------------ + // 138 Desert wind: Only audible in 55 when the cave door is open. + { + FX_SYRIWIND, // sampleId + FX_RANDOM, // type + 720, // delay (or random chance) + { // roomVolList + {54,10,10}, // {roomNo,leftVol,rightVol} + {55,5,7}, + {0,0,0}, // NULL-TERMINATOR + } + }, + //------------------------ + // 139 Bell on Nejo's stall: GEOSYR7 + { + FX_STALLBEL, // sampleId + FX_SPOT, // type + 7, // delay (or random chance) + { // roomVolList + {45,10,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + } + }, + //------------------------ + //------------------------ + // 140 George electrocutes Khan: GEOSYR40 + { + FX_SHOCK3, // sampleId + FX_SPOT, // type + 6, // delay (or random chance) + { // roomVolList + {54,10,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 141 George thumps Khan: GEOSYR40 + { + FX_THUMP1, // sampleId + FX_SPOT, // type + 22, // delay (or random chance) + { // roomVolList + {54,12,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 142 Khan hits the floor: KHS9 + { + FX_KHANDOWN, // sampleId + FX_SPOT, // type + 24, // delay (or random chance) + { // roomVolList + {54,8,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 143 Hospital ambience + { + FX_HOSPNOIS, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) + { // roomVolList + {32,6,4}, // {roomNo,leftVol,rightVol} + {33,7,7}, + {34,3,4}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 144 Mr Shiny switched on: DOMPLG (Start FX_SHINY) + { + FX_SHINYON, // sampleId + FX_SPOT, // type + 0, // delay (or random chance) + { // roomVolList + {33,12,14}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 145 Mr Shiny running + { + FX_SHINY, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) + { // roomVolList + {32,4,3}, // {roomNo,leftVol,rightVol} + {33,12,14}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 146 Mr Shiny switched off: GEOPLG33 (Turn off FX_SHINY at the same time) + { + FX_SHINYOFF, // sampleId + FX_SPOT, // type + 0, // delay (or random chance) + { // roomVolList + {33,12,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 147 Benoir takes blood pressure: BENBP1 or BENBP2 + { + FX_BLOODPRE, // sampleId + FX_SPOT, // type + 39, // delay (or random chance) + { // roomVolList + {34,14,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 148 George takes blood pressure: GEOBP1 or GEOBP2 + { + FX_BLOODPRE, // sampleId + FX_SPOT, // type + 62, // delay (or random chance) + { // roomVolList + {34,14,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 149 Goat baas as it attacks: GOTCR and GOTCL + { + FX_GOATBAA, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) + { // roomVolList + {24,12,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + //------------------------ + // 150 Goat peeved at being trapped: GOTPLW (I'd advise triggering this anim randomly if you haven't done that) + { + FX_GOATDOH, // sampleId + FX_SPOT, // type + 7, // delay (or random chance) + { // roomVolList + {24,7,6}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 151 George triggers the Irish secret door: GEOPUT + { + FX_TRIGER25, // sampleId + FX_SPOT, // type + 35, // delay (or random chance) + { // roomVolList + {25,6,5}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 152 George winds up gramophone: GEOWIND + { + FX_WINDUP11, // sampleId + FX_SPOT, // type + 16, // delay (or random chance) + { // roomVolList + {11,7,7}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 153 Marib ambience + { + FX_MARIB, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) + { // roomVolList + {45,7,7}, // {roomNo,leftVol,rightVol} + {47,5,5}, + {50,5,4}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 154 Statuette breaks: STA2 + { + FX_STATBREK, // sampleId + FX_SPOT, // type + 10, // delay (or random chance) + { // roomVolList + {45,7,4}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 155 George opens toilet door: CUBDOR50 + { + FX_CUBDOR, // sampleId + FX_SPOT, // type + 6, // delay (or random chance) + { // roomVolList + {50,6,6}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 156 Crowd goes, "Ooh!": CRO36APP + { + FX_OOH, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) + { // roomVolList + {36,6,7}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 157 Phone rings: When Nico calls back in room 41. Loops until the guard answers it. + { + FX_PHONCALL, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) + { // roomVolList + {41,16,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 158 Phone picked up in 41: GUA41ANS + { + FX_FONEUP41, // sampleId + FX_SPOT, // type + 18, // delay (or random chance) + { // roomVolList + {41,5,6}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 159 George turns thermostat: GEO41THE (another dummy). Also used on the reverse. + { + FX_THERMO1, // sampleId + FX_SPOT, // type + 10, // delay (or random chance) + { // roomVolList + {41,6,5}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 160 Low echoing rumble of large church + { + FX_CHURCHFX, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) + { // roomVolList + {38,5,5}, // {roomNo,leftVol,rightVol} + {48,5,5}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 161 George drys hand: GEO43HAN + { + FX_DRIER1, // sampleId + FX_SPOT, // type + 9, // delay (or random chance) + { // roomVolList + {43,16,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 162 George jumps in through window: GEOWIN8 + { + FX_JUMPIN, // sampleId + FX_SPOT, // type + 49, // delay (or random chance) + { // roomVolList + {17,8,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 163 Khan fires: KHS12 + { + FX_SHOTKHAN, // sampleId + FX_SPOT, // type + 30, // delay (or random chance) + { // roomVolList + {54,5,5}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 164 Khan fires: KHS5 + { + FX_SHOTKHAN, // sampleId + FX_SPOT, // type + 5, // delay (or random chance) + { // roomVolList + {54,5,5}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 165 George falls: GEOSYR37 + { + FX_GEOFAL54, // sampleId + FX_SPOT, // type + 25, // delay (or random chance) + { // roomVolList + {54,5,5}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 166 George falls after going for the gun (GEOSYR42) + { + FX_GEOFAL54, // sampleId + FX_SPOT, // type + 46, // delay (or random chance) + { // roomVolList + {54,5,5}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 167 Pickaxe sound 5: Screen 1 - WRKDIG01 + { + FX_PICK5, // sampleId + FX_SPOT, // type + 9, // delay (or random chance) * + { // roomVolList + {1,3,3}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 168 George climbs ladder in 7: GEOASC07 + { + FX_SEWLADU7, // sampleId + FX_SPOT, // type + 7, // delay (or random chance) * + { // roomVolList + {7,8,9}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 169 George picks keys up in Alamut: GEOKEYS1 + { + FX_KEYS49, // sampleId + FX_SPOT, // type + 9, // delay (or random chance) * + { // roomVolList + {49,8,7}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + //------------------------ + // 170 George puts down keys up in Alamut: GEOKEYS2 + { + FX_KEYS49, // sampleId + FX_SPOT, // type + 7, // delay (or random chance) * + { // roomVolList + {49,8,7}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 171 George unlocks toilet door: GEOSYR43 + { + FX_UNLOCK49, // sampleId + FX_SPOT, // type + 16, // delay (or random chance) * + { // roomVolList + {49,6,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 172 George breaks the toilet chain. GEOSYR48 + { + FX_WCCHAIN, // sampleId + FX_SPOT, // type + 10, // delay (or random chance) * + { // roomVolList + {50,6,7}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 173 George breaks the branch of the cliff edge tree. GEOSYR20 + { + FX_BREKSTIK, // sampleId + FX_SPOT, // type + 16, // delay (or random chance) * + { // roomVolList + {54,6,6}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 174 George climbs down the cliff face. GEOSYR23 + { + FX_CLIMBDWN, // sampleId + FX_SPOT, // type + 6, // delay (or random chance) * + { // roomVolList + {54,6,7}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 175 George pulls ring: GEOSYR26 + { + FX_RINGPULL, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) * + { // roomVolList + {54,7,4}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 176 Bull's Head door opens: SECDOR + { + FX_SECDOR54, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) * + { // roomVolList + {54,7,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 177 Inside Bull's Head door opens: DOOR55 (and its reverse). + { + FX_SECDOR55, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) * + { // roomVolList + {55,4,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 178 Ayub opens door. AYU1 + { + FX_AYUBDOOR, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) * + { // roomVolList + {45,8,3}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 179 George knocks at the door in location 4: GEONOK followed by reverse of GEONOK + { + FX_KNOKKNOK, // sampleId + FX_SPOT, // type + 13, // delay (or random chance) * + { // roomVolList + {4,16,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 180 George knocks at the door in location 5: GEONOK05 + { + FX_KNOKKNOK, // sampleId + FX_SPOT, // type + 8, // delay (or random chance) * + { // roomVolList + {5,8,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 181 Those pesky Irish birds turn up in Spain, too. + { + FX_SPNBIRD1, // sampleId + FX_RANDOM, // type + 720, // delay (or random chance) * + { // roomVolList + {57,1,4}, + {58,8,4}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 182 Those pesky Irish birds turn up in Spain, too. + { + FX_SPNBIRD2, // sampleId + FX_RANDOM, // type + 697, // delay (or random chance) * + { // roomVolList + {57,4,8}, // {roomNo,leftVol,rightVol} + {58,4,1}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 183 The secret door in the well: SECDOR61 anim + { + FX_SECDOR61, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) * + { // roomVolList + {61,4,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 184 Spanish countryside ambience + { + FX_SPAIN, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) * + { // roomVolList + {57,1,2}, // + {58,2,2}, // + {60,1,1}, // + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 185 Spanish well ambience + { + FX_WELLDRIP, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) * + { // roomVolList + {61,4,4}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 186 Fish falls on George's head: GEOTOT29 + { + FX_FISHFALL, // sampleId + FX_SPOT, // type + 60, // delay (or random chance) * + { // roomVolList + {29,10,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 187 Hospital exterior ambience + { + FX_HOSPEXT, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) * + { // roomVolList + {31,3,4}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 188 Hospital exterior gravel footstep #1 + { + FX_GRAVEL1, // sampleId + FX_SPOT, // type + 0, // delay (or random chance) * + { // roomVolList + {31,16,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 189 Hospital exterior gravel footstep #2 + { + FX_GRAVEL2, // sampleId + FX_SPOT, // type + 0, // delay (or random chance) * + { // roomVolList + {31,16,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + //------------------------ + // 190 George opens sarcophagus: GEOSAR + { + FX_SARCO28A, // sampleId + FX_SPOT, // type + 26, // delay (or random chance) * + { // roomVolList + {28,6,6}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 191 George closes sarcophagus: GEOSAR2 + { + FX_SARCO28B, // sampleId + FX_SPOT, // type + 24, // delay (or random chance) * + { // roomVolList + {28,3,3}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 192 Guard opens sarcophagus: MUSOPN + { + FX_SARCO28C, // sampleId + FX_SPOT, // type + 14, // delay (or random chance) * + { // roomVolList + {28,3,3}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 193 George peeks out of sarcophagus: GEOPEEK + { + FX_SARCO29, // sampleId + FX_SPOT, // type + 4, // delay (or random chance) * + { // roomVolList + {29,5,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 194 The rope drops into the room: ROPE29 + { + FX_ROPEDOWN, // sampleId + FX_SPOT, // type + 3, // delay (or random chance) * + { // roomVolList + {29,3,3}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 195 George pushes the totem pole: GEOTOT29 + { + FX_TOTEM29A, // sampleId + FX_SPOT, // type + 30, // delay (or random chance) * + { // roomVolList + {29,12,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 196 George pushes the totem pole over: GEOTOTB + { + FX_TOTEM29B, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) * + { // roomVolList + {29,16,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 197 George rocks the totem pole in museum hours: TOTEM28 + { + FX_TOTEM28A, // sampleId + FX_SPOT, // type + 8, // delay (or random chance) * + { // roomVolList + {28,4,4}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 198 Ambient sound for Montfauçon Square + { + FX_MONTAMB, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) * + { // roomVolList + {36,6,6}, // {roomNo,leftVol,rightVol} + {40,6,6}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 199 Ambient sound churchyard. + { + FX_WIND71, // sampleId + FX_RANDOM, // type + 720, // delay (or random chance) * + { // roomVolList + {71,10,10}, // {roomNo,leftVol,rightVol} + {72,7,7}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 200 Owl cry #1 in churchyard + { + FX_OWL71A, // sampleId + FX_RANDOM, // type + 720, // delay (or random chance) * + { // roomVolList + {71,8,8}, // {roomNo,leftVol,rightVol} + {72,6,4}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 201 Owl cry #2 in churchyard + { + FX_OWL71B, // sampleId + FX_RANDOM, // type + 1080, // delay (or random chance) * + { // roomVolList + {71,8,8}, // {roomNo,leftVol,rightVol} + {72,7,6}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 202 Air conditioner in the museum + { + FX_AIRCON28, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) * + { // roomVolList + {28,6,6}, // {roomNo,leftVol,rightVol} + {29,3,3}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 203 George breaks the handle off in the church tower. GEOWND72 + { + FX_COG72A, // sampleId + FX_SPOT, // type + 5, // delay (or random chance) * + { // roomVolList + {72,10,10}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 204 Countess' room ambience + { + FX_AMBIEN56, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) * + { // roomVolList + {56,3,2}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 205 Musical effect for George drinking beer. GEODRN20 + { + FX_DRINK, // sampleId + FX_SPOT, // type + 17, // delay (or random chance) * + { // roomVolList + {20,12,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 206 Torch thrown through the air. GEOTHROW + { + FX_TORCH73, // sampleId + FX_SPOT, // type + 14, // delay (or random chance) * + { // roomVolList + {73,16,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 207 Internal train ambience. + { + FX_TRAININT, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) * + { // roomVolList + {63,3,3}, // {roomNo,leftVol,rightVol} + {65,2,2}, + {66,2,2}, + {67,2,2}, + {69,2,2}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 208 Countess' clock. PENDULUM. Note: Trigger the sound effect on alternate runs of the pendulum animation. + { + FX_PENDULUM, // sampleId + FX_SPOT, // type + 6, // delay (or random chance) * + { // roomVolList + {56,2,2}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 209 Compartment door. DOOR65 + { + FX_DOOR65, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) * + { // roomVolList + {65,3,3}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + //------------------------ + // 210 Opening window. GEOOPN1 + { + FX_WINDOW66, // sampleId + FX_SPOT, // type + 8, // delay (or random chance) * + { // roomVolList + {66,5,5}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 211 Wind rip by the open window. Triggered at the end of effect 210. + { + FX_WIND66, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) * + { // roomVolList + {66,5,5}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 212 George electrocutes himself on the pantograph. Fool. GEOSHK64 + { + FX_SHOCK63, // sampleId + FX_SPOT, // type + 11, // delay (or random chance) * + { // roomVolList + {63,12,14}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 213 The train brakes violently. GEOSTP69 + { + FX_BRAKES, // sampleId + FX_SPOT, // type + 13, // delay (or random chance) * + { // roomVolList + {69,16,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 214 The train ticks over. From the end of BRAKE. + { + FX_TICK69, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) * + { // roomVolList + {69,8,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 215 Eklund shoot Khan. FIGHT69 + { + FX_EKSHOOT, // sampleId + FX_SPOT, // type + 120, // delay (or random chance) * + { // roomVolList + {69,12,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 216 Eklund shoots George. GEODIE69 + { + FX_EKSHOOT, // sampleId + FX_SPOT, // type + 21, // delay (or random chance) * + { // roomVolList + {69,12,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 217 Khan pulls the door open. FIGHT69 + { + FX_DOOR69, // sampleId + FX_SPOT, // type + 42, // delay (or random chance) * + { // roomVolList + {69,8,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 218 Wind shriek. Loops from the end of DOOR69 wav to the beginning of BRAKES. + { + FX_WIND66, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) * + { // roomVolList + {69,8,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 219 Brakes releasing pressure. Only after BRAKE has been run. + { + FX_PNEUMO69, // sampleId + FX_RANDOM, // type + 720, // delay (or random chance) * + { // roomVolList + {69,8,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 220 External train sound. Played while George is on the top of the train. + { + FX_TRAINEXT, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) * + { // roomVolList + {63,8,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 221 The passing train. FIGHT69 + { + FX_TRNPASS, // sampleId + FX_SPOT, // type + 102, // delay (or random chance) * + { // roomVolList + {69,4,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 222 George descends into sewer. GEODESO6 + { + FX_LADD2, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) * + { // roomVolList + {6,4,4}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 223 George ascends into alley. GEOASC06 + { + FX_LADD3, // sampleId + FX_SPOT, // type + 10, // delay (or random chance) * + { // roomVolList + {6,4,4}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 224 George replaces manhole cover. GEOMAN9 + { + FX_COVERON2, // sampleId + FX_SPOT, // type + 19, // delay (or random chance) * + { // roomVolList + {2,12,11}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 225 Montfaucon sewer ambience. + { + FX_AMBIEN37, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) * + { // roomVolList + {37,5,5}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 226 George's winning smile. GEOJMP72. + { + FX_PING, // sampleId + FX_SPOT, // type + 26, // delay (or random chance) * + { // roomVolList + {72,10,14}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 227 George starts to open the manhole. GEO36KNE + { + FX_MANOP36, // sampleId + FX_SPOT, // type + 19, // delay (or random chance) * + { // roomVolList + {36,4,6}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 228 George opens the manhole. GEO36OPE + { + FX_PULLUP36, // sampleId + FX_SPOT, // type + 9, // delay (or random chance) * + { // roomVolList + {36,4,6}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 229 George replaces the manhole cover. GEO36CLO + { + FX_REPLCE36, // sampleId + FX_SPOT, // type + 20, // delay (or random chance) * + { // roomVolList + {36,4,6}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + //------------------------ + // 230 George knocks at righthand arch. GEO37TA3 + { + FX_KNOCK37, // sampleId + FX_SPOT, // type + 20, // delay (or random chance) * + { // roomVolList + {37,6,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 231 George knocks at middle or lefthand arch. GEO37TA1 or GEO37TA2. + { + FX_KNOCK37B, // sampleId + FX_SPOT, // type + 20, // delay (or random chance) * + { // roomVolList + {37,4,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 232 George winds the chain down HOO37LBO + { + FX_CHAIN37, // sampleId + FX_SPOT, // type + 14, // delay (or random chance) * + { // roomVolList + {37,6,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 233 George winds the chain up. HOO37LBO (In reverse) + { + FX_CHAIN37B, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) * + { // roomVolList + {37,6,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 234 George breaks hole in door. GEO37TA4 + { + FX_HOLE37, // sampleId + FX_SPOT, // type + 11, // delay (or random chance) * + { // roomVolList + {37,6,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 235 Plaster door collapses. DOR37COL + { + FX_DOOR37, // sampleId + FX_SPOT, // type + 23, // delay (or random chance) * + { // roomVolList + {37,8,15}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 236 Barge winch. GEO37TUL (If it runs more than once, trigger the effect on frame one. Incidentally, this is a reversible so the effect must launch on frame one of the .cdr version as well. ) + { + FX_WINCH37, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) * + { // roomVolList + {37,16,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 237 George places chess piece. GEOSPA17 + { + FX_CHESS, // sampleId + FX_SPOT, // type + 23, // delay (or random chance) * + { // roomVolList + {59,4,4}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 238 Piano loop for the upstairs hotel corridor. + { + FX_PIANO14, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) * + { // roomVolList + {14,2,2}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 239 Door opens in church tower. PANEL72 + { + FX_SECDOR72, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) * + { // roomVolList + {72,8,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + //------------------------ + // 240 George rummages through debris. Tied to the end of the whichever crouch is used. Use either this one or RUMMAGE2 alternatively or randomly. Same kind of schtick as the pick axe noises, I suppose. + { + FX_RUMMAGE1, // sampleId + FX_SPOT, // type + 9, // delay (or random chance) * + { // roomVolList + {72,8,6}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 241 George rummages through debris. See above for notes. + { + FX_RUMMAGE2, // sampleId + FX_SPOT, // type + 9, // delay (or random chance) * + { // roomVolList + {72,8,6}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 242 Gust of wind in the graveyard. + { + FX_GUST71, // sampleId + FX_RANDOM, // type + 1080, // delay (or random chance) * + { // roomVolList + {71,3,3}, // {roomNo,leftVol,rightVol} + {72,2,1}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 243 Violin ambience for Ireland. + { + FX_VIOLIN19, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) * + { // roomVolList + {19,3,3}, // {roomNo,leftVol,rightVol} + {21,2,2}, + {26,2,2}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 244 Footstep #1 for underground locations. Same schtick as for 188 and 189. + { + FX_SEWSTEP1, // sampleId + FX_SPOT, // type + 0, // delay (or random chance) * + { // roomVolList + {6,8,8}, // {roomNo,leftVol,rightVol} + {7,8,8}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 245 Footstep #2 for underground locations. Same schtick as for 188 and 189. + { + FX_SEWSTEP2, // sampleId + FX_SPOT, // type + 0, // delay (or random chance) * + { // roomVolList + {6,16,16}, // {roomNo,leftVol,rightVol} + {7,16,16}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 246 Nico's carabiner as she descends into the museum. NICPUS1 + { + FX_CARABINE, // sampleId + FX_SPOT, // type + 4, // delay (or random chance) * + { // roomVolList + {29,8,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 247 Rosso is shot (with a piece of field artillery). ROSSHOT + { + FX_GUN79, // sampleId + FX_SPOT, // type + 2, // delay (or random chance) * + { // roomVolList + {79,16,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 248 George is hit by the thrown stilletto. GEODIE1 + { + FX_DAGGER1, // sampleId + FX_SPOT, // type + 2, // delay (or random chance) * + { // roomVolList + {73,12,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 249 George is hit by the thrown stilletto after walking forward. GEODIE2 + { + FX_DAGGER1, // sampleId + FX_SPOT, // type + 9, // delay (or random chance) * + { // roomVolList + {73,12,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + //------------------------ + // 250 Can hits the well water. The cue is in GAR2SC57.TXT immediately after the line, "over: Lopez threw the can away. It seemed to fall an awfully long way." + { + FX_CANFALL, // sampleId + FX_SPOT, // type + 4, // delay (or random chance) * + { // roomVolList + {57,16,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 251 Mad, fizzing damp and ancient gunpowder after the application of a torch. + { + FX_GUNPOWDR, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) * + { // roomVolList + {73,12,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 252 Maguire whistling. MAGSLK. Plays while Maguire is idling, stops abruptly when he does something else. + { + FX_WHISTLE, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) * + { // roomVolList + {19,2,5}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 253 George is hit by the goat. GEOHITR and GEOHITL. + { + FX_GEOGOAT, // sampleId + FX_SPOT, // type + 11, // delay (or random chance) * + { // roomVolList + {24,10,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 254 Manager says, "Hello". MAN2 + { + FX_MANG1, // sampleId + FX_SPOT, // type + 7, // delay (or random chance) * + { // roomVolList + {49,6,5}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 255 Manager says, Don't go in there!" MAN3 + { + FX_MANG2, // sampleId + FX_SPOT, // type + 11, // delay (or random chance) * + { // roomVolList + {49,6,5}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 256 Manager says, "Here are the keys." MAN4 + { + FX_MANG3, // sampleId + FX_SPOT, // type + 6, // delay (or random chance) * + { // roomVolList + {49,6,5}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 257 George pulls the lion's tooth. GEOSPA26 + { + FX_TOOTHPUL, // sampleId + FX_SPOT, // type + 19, // delay (or random chance) * + { // roomVolList + {61,8,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 258 George escapes the lion. LION1 + { + FX_LIONFALL, // sampleId + FX_SPOT, // type + 7, // delay (or random chance) * + { // roomVolList + {61,8,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 259 George gets flattened. LION2 + { + FX_LIONFAL2, // sampleId + FX_SPOT, // type + 4, // delay (or random chance) * + { // roomVolList + {61,8,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 260 Rosso dies. ROSSFALL + { + FX_ROSSODIE, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) * + { // roomVolList + {74,16,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 261 Eklund chokes George. FIGHT79 + { + FX_CHOKE1, // sampleId + FX_SPOT, // type + 9, // delay (or random chance) * + { // roomVolList + {79,16,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 262 Eklund chokes George some more. FIGHT79 + { + FX_CHOKE2, // sampleId + FX_SPOT, // type + 54, // delay (or random chance) * + { // roomVolList + {79,16,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 263 Eklund dies. FIGHT79 + { + FX_FIGHT2, // sampleId + FX_SPOT, // type + 44, // delay (or random chance) * + { // roomVolList + {79,16,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 264 George hears museum break-in. GEOSUR29 + { + FX_DOOR29, // sampleId + FX_SPOT, // type + 10, // delay (or random chance) * + { // roomVolList + {94,14,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 265 George hits the floor having been shot. GEODED. + { + FX_GDROP29, // sampleId + FX_SPOT, // type + 27, // delay (or random chance) * + { // roomVolList + {29,10,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 266 George hits the floor having been stunned. GEOFISH + { + FX_GDROP29, // sampleId + FX_SPOT, // type + 27, // delay (or random chance) * + { // roomVolList + {29,10,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 267 Fitz being knocked down as heard from inside the pub. Triggered from the script, I think. This is just a stopgap until Hackenbacker do the full version for the Smacker, then I'll sample the requisite bit and put it in here. + { + FX_FITZHIT, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) * + { // roomVolList + {20,16,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 268 Gendarme shoots lock off. GENSHOT + { + FX_GUN34, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) * + { // roomVolList + {34,16,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 269 ECG alarm, Marquet in trouble. Start looping imeediately before George says, "Thanks, Bunny". + // Incidentally, James, please switch off Mr Shiney permanently when George first gets into Marquet's room. He gets in the way when they're figuring out that Eklund's an imposter. + { + FX_PULSE2, // sampleId + FX_LOOP, // type + 1, // delay (or random chance) * + { // roomVolList + {30,16,16}, // {roomNo,leftVol,rightVol} + {34,12,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + //------------------------ + // 270 ECG alarm, Marquet dead. Switch off the previous effect and replace with this immediately before the gendarme says, "Stand back, messieurs." + { + FX_PULSE3, // sampleId + FX_LOOP, // type + 1, // delay (or random chance) * + { // roomVolList + {30,16,16}, // {roomNo,leftVol,rightVol} + {34,13,13}, + {35,13,13}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 271 Door closing. GEOENT15 + { + FX_DORCLOSE, // sampleId + FX_SPOT, // type + 4, // delay (or random chance) * + { // roomVolList + {15,12,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 272 Cupboard opening. GEOCOT + { + FX_CUPBOPEN, // sampleId + FX_SPOT, // type + 8, // delay (or random chance) * + { // roomVolList + {33,12,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 273 Cupboard closing. GEOCOT + { + FX_CUPBCLOS, // sampleId + FX_SPOT, // type + 33, // delay (or random chance) * + { // roomVolList + {33,12,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 274 Closing door when George leaves hotel room. GEOLVS15 and GEODOR17 (they're identical). + { + FX_DORCLOSE, // sampleId + FX_SPOT, // type + 44, // delay (or random chance) * + { // roomVolList + {15,12,12}, // {roomNo,leftVol,rightVol} + {17,12,12}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 275 Closing door when George leaves the pub. DOROPN20 (Reversed) + { + FX_DORCLOSE20,// sampleId + FX_SPOT, // type + 11, // delay (or random chance) * + { // roomVolList + {20,12,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 276 Nico call for a cab. NICPHN10 + { + FX_PHONICO1, // sampleId + FX_SPOT, // type + 15, // delay (or random chance) * + { // roomVolList + {10,12,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 277 Nico puts down the phone. NICDWN10 + { + FX_FONEDN, // sampleId + FX_SPOT, // type + 6, // delay (or random chance) * + { // roomVolList + {10,12,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 278 Painter puts down the phone. PAI41HAN + { + FX_FONEDN41, // sampleId + FX_SPOT, // type + 5, // delay (or random chance) * + { // roomVolList + {41,12,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 279 Mechanical hum of heating system in the dig lobby. + { + FX_AIRCON41, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) * + { // roomVolList + {41,6,6}, // {roomNo,leftVol,rightVol} + {43,8,8}, + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + //------------------------ + // 280 The Sword is Reforged (Grandmaster gets zapped) GMPOWER + { + FX_REFORGE1, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) * + { // roomVolList + {78,16,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 281 The Sword is Reforged (G&N gawp at the spectacle) There's no anim I know of to tie it to unless the flickering blue light is one. + { + FX_REFORGE2, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) * + { // roomVolList + {75,12,12}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 282 The Sword is Reforged (We watch over G&N's heads as the Grandmaster gets zapped) GMWRIT74 + { + FX_REFORGE2, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) * + { // roomVolList + {74,14,14}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 283 The Sword is Reforged (Grandmaster finishes being zapped) GMWRITH + { + FX_REFORGE4, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) * + { // roomVolList + {78,16,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 284 Baphomet Cavern Ambience + { + FX_BAPHAMB, // sampleId + FX_LOOP, // type + 0, // delay (or random chance) * + { // roomVolList + {74,6,8}, // {roomNo,leftVol,rightVol} + {75,7,8}, // {roomNo,leftVol,rightVol} + {76,8,8}, // {roomNo,leftVol,rightVol} + {77,8,8}, // {roomNo,leftVol,rightVol} + {78,8,8}, // {roomNo,leftVol,rightVol} + {79,7,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 285 Duane's Happy-Snappy Camera. XDNEPHO3 and XDNEPHO5. + { + FX_CAMERA45, // sampleId + FX_SPOT, // type + 30, // delay (or random chance) * + { // roomVolList + {45,4,4}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 286 Grand Master strikes the floor with his cane. GMENTER + { + FX_STAFF, // sampleId + FX_SPOT, // type + 28, // delay (or random chance) * + { // roomVolList + {73,8,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 287 George descends ladder in 7: GEOASC07 (Reversed) This used to be handled by effect #46 but it didn't fit at all. + { + FX_SEWLADD7, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) * + { // roomVolList + {7,8,9}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 288 Sam kicks the recalcitrant Mr. Shiny. DOMKIK + { + FX_KIKSHINY, // sampleId + FX_SPOT, // type + 16, // delay (or random chance) * + { // roomVolList + {33,9,9}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 289 Gust of wind outside bombed cafe. LVSFLY + { + FX_LVSFLY, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) * + { // roomVolList + {1,16,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 290 Ron's disgusting No.1 Sneeze. Either this or the next effect (randomly chosen) is used for the following animations, RONSNZ & RONSNZ2 + { + FX_SNEEZE1, // sampleId + FX_SPOT, // type + 11, // delay (or random chance) * + { // roomVolList + {20,10,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 291 Ron's disgusting No.2 Sneeze. Either this or the previous effect (randomly chosen) is used for the following animations, RONSNZ & RONSNZ2 + { + FX_SNEEZE2, // sampleId + FX_SPOT, // type + 11, // delay (or random chance) * + { // roomVolList + {20,10,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 292 Dripping tap in the pub cellar. TAPDRP + { + FX_DRIPIRE, // sampleId + FX_SPOT, // type + 9, // delay (or random chance) * + { // roomVolList + {21,4,4}, // {roomNo,leftVol,rightVol} + {26,4,4}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 293 Dripping tap in the pub cellar. TAPDRP + { + FX_DRIPIRE2, // sampleId + FX_SPOT, // type + 9, // delay (or random chance) * + { // roomVolList + {21,4,4}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 294 Dripping tap in the excavation toilet. (see WATER43 - but it's looped anyway, not triggered with anim) + { + FX_TAPDRIP, // sampleId + FX_SPOT, // type + 6, // delay (or random chance) * + { // roomVolList + {43,8,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 295 George closes the mausoleum window. GEOSPA23 + { + FX_WINDOW59, // sampleId + FX_SPOT, // type + 24, // delay (or random chance) * + { // roomVolList + {59,10,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 296 George opens the mausoleum window, the feebleminded loon. GEOSPA23 reversed. + { + FX_WINDOW59, // sampleId + FX_SPOT, // type + 14, // delay (or random chance) * + { // roomVolList + {59,10,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 297 When George & Nico hear chanting from sc73 + { + FX_CHANT, // sampleId + FX_SPOT, // type + 10, // delay (or random chance) * + { // roomVolList + {73,2,4}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 298 EKFIGHT + { + FX_FIGHT1, // sampleId + FX_SPOT, // type + 31, // delay (or random chance) * + { // roomVolList + {74,16,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 299 Small van passes, left to right. CARA9 and CARC9 + { + FX_LITEVEHR, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) * + { // roomVolList + {9,16,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 300 Small van passes, right to left to right. CARB9 + { + FX_LITEVEHL, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) * + { // roomVolList + {9,16,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 301 Truck passes, left to right. TRUCKA9 and TRUCKB9 + { + FX_HVYVEHR, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) * + { // roomVolList + {9,14,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 302 Truck passes, right to left. TRUCKC9 + { + FX_HVYVEHL, // sampleId + FX_SPOT, // type + 1, // delay (or random chance) * + { // roomVolList + {9,14,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 303 With anim FIGHT69 + { + FX_FIGHT69, // sampleId + FX_SPOT, // type + 78, // delay (or random chance) * + { // roomVolList + {69,12,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 304 With anim GEODIE1 in sc73 + { + FX_GDROP73, // sampleId + FX_SPOT, // type + 14, // delay (or random chance) * + { // roomVolList + {73,12,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 305 With anim GEODIE2 in sc73 + { + FX_GDROP73, // sampleId + FX_SPOT, // type + 21, // delay (or random chance) * + { // roomVolList + {73,12,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 306 With anim GEODES25 + { + FX_LADDWN25, // sampleId + FX_SPOT, // type + 0, // delay (or random chance) * + { // roomVolList + {25,12,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 307 With anim GEOASC25 + { + FX_LADDUP25, // sampleId + FX_SPOT, // type + 8, // delay (or random chance) * + { // roomVolList + {25,12,8}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 308 With anim GKSWORD in sc76 + { + FX_GKSWORD, // sampleId + FX_SPOT, // type + 9, // delay (or random chance) * + { // roomVolList + {76,10,10}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 309 With anim GEO36KNE in sc36 + { + FX_KEYIN, // sampleId + FX_SPOT, // type + 18, // delay (or random chance) * + { // roomVolList + {36,14,14}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 310 With anim GEO36ENT in sc36 + { + FX_COVDWN, // sampleId + FX_SPOT, // type + 85, // delay (or random chance) * + { // roomVolList + {36,14,14}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ + // 311 With anim SECDOR59 in sc59 + { + FX_SECDOR59, // sampleId + FX_SPOT, // type + 0, // delay (or random chance) * + { // roomVolList + {59,16,16}, // {roomNo,leftVol,rightVol} + {0,0,0}, // NULL-TERMINATOR + }, + }, + //------------------------ +}; +//-------------------------------------------------------------------------------------- +// Continuous & random background sound effects for each location + +// NB. There must be a list for each room number, even if location doesn't exist in game + +const uint16 SwordSound::_roomsFixedFx[TOTAL_ROOMS][TOTAL_FX_PER_ROOM] = +{ + {0}, // 0 + + // PARIS 1 + {2,3,4,5,0}, // 1 + {2,0}, // 2 + {2,3,4,5,32,0}, // 3 + {2,3,4,5,0}, // 4 + {2,3,4,5,0}, // 5 + {9,11,12,13,44,45,47}, // 6 + {9,11,12,13,44,45,47}, // 7 + {2,3,4,5,0}, // 8 + + // PARIS 2 + {54,63,0}, // 9 + {51,52,53,54,63,0}, // 10 + {70,0}, // 11 + {51,52,70,0}, // 12 + {0}, // 13 + {238,0}, // 14 + {82,0}, // 15 + {70,81,82,0}, // 16 + {82,0}, // 17 + {3,4,5,70,0}, // 18 + + // IRELAND + {120,121,122,243,0}, // 19 + {0}, // 20 Violin makes the ambience.. + {120,121,122,243,0}, // 21 + {120,121,122,0}, // 22 + {120,121,122,124,0}, // 23 + {120,121,122,0}, // 24 + {0}, // 25 + {123,243,0}, // 26 + + // PARIS 3 + {135,0}, // 27 + {202,0}, // 28 + {202,0}, // 29 + {0}, // 30 + {187,0}, // 31 + {143,145,0}, // 32 + {143,0}, // 33 + {143,0}, // 34 + {0}, // 35 + + // PARIS 4 + {198,0}, // 36 + {225,0}, // 37 + {160,0}, // 38 + {0}, // 39 + {198,0}, // 40 + {279,0}, // 41 + {0}, // 42 + {279,0}, // 43 + {0}, // 44 Doesn't exist + + // SYRIA + {153,0}, // 45 + {70,81,0}, // 46 - PARIS 2 + {153,0}, // 47 + {160,0}, // 48 - PARIS 4 + {0}, // 49 + {153,0}, // 50 + {0}, // 51 + {0}, // 52 + {0}, // 53 + {130,138,0}, // 54 + {0}, // 55 + + // SPAIN + {204,0}, // 56 + {181,182,184,0}, // 57 + {181,182,184,0}, // 58 + {0}, // 59 + {184,0}, // 60 + {185,0}, // 61 + {0}, // 62 Just music + + // NIGHT TRAIN + {207,0,0}, // 63 + {0}, // 64 Doesn't exist + {207,0}, // 65 + {207,0}, // 66 + {207,0}, // 67 + {0}, // 68 Disnae exist + {0}, // 69 + + // SCOTLAND + FINALE + {0}, // 70 Disnae exist + {199,200,201,242,0}, // 71 + {199,200,201,242,0}, // 72 + {0}, // 73 + {284,0}, // 74 + {284,0}, // 75 + {284,0}, // 76 + {284,0}, // 77 + {284,0}, // 78 + {284,0}, // 79 + {0}, // 80 + {0}, // 81 + {0}, // 82 + {0}, // 83 + {0}, // 84 + {0}, // 85 + {0}, // 86 + {0}, // 87 + {0}, // 88 + {0}, // 89 + {0}, // 90 + {0}, // 91 + {0}, // 92 + {0}, // 93 + {0}, // 94 + {0}, // 95 + {0}, // 96 + {0}, // 97 + {0}, // 98 + {0}, // 99 +}; diff --git a/sword1/sword1.cpp b/sword1/sword1.cpp new file mode 100644 index 0000000000..e76749ea76 --- /dev/null +++ b/sword1/sword1.cpp @@ -0,0 +1,293 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#include "stdafx.h" +#include "sword1.h" + +#include "backends/fs/fs.h" + +#include "base/plugins.h" +#include "common/config-manager.h" +#include "common/file.h" +#include "common/timer.h" + +#include "memman.h" +#include "resman.h" +#include "objectman.h" +#include "mouse.h" +#include "logic.h" +#include "sound.h" +#include "screen.h" +#include "swordres.h" +#include "menu.h" +#include "music.h" + +// taken from Sword2.cpp +struct Sword1GameSettings { + const char *name; + const char *description; + uint32 features; + const char *detectname; + GameSettings toGameSettings() const { + GameSettings dummy = { name, description, features }; + return dummy; + } +}; + +static const Sword1GameSettings sword1_settings[] = { + /* Broken Sword 1 */ + {"sword1", "Broken Sword I", GF_DEFAULT_TO_1X_SCALER, "swordres.rif" }, + {NULL, NULL, 0, NULL} +}; + +GameList Engine_SWORD1_gameList() { + const Sword1GameSettings *g = sword1_settings; + GameList games; + while (g->name) { + games.push_back(g->toGameSettings()); + g++; + } + return games; +} + +GameList Engine_SWORD1_detectGames(const FSList &fslist) { + GameList detectedGames; + const Sword1GameSettings *g; + + for (g = sword1_settings; g->name; ++g) { + // Iterate over all files in the given directory + for (FSList::ConstIterator file = fslist.begin(); file != fslist.end(); ++file) { + const char *gameName = file->displayName().c_str(); + + if (0 == scumm_stricmp(g->detectname, gameName)) { + // Match found, add to list of candidates, then abort inner loop. + detectedGames.push_back(g->toGameSettings()); + break; + } + } + } + return detectedGames; +} + +Engine *Engine_SWORD1_create(GameDetector *detector, OSystem *syst) { + return new SwordEngine(detector, syst); +} + +REGISTER_PLUGIN("Broken Sword", Engine_SWORD1_gameList, Engine_SWORD1_create, Engine_SWORD1_detectGames) + +SystemVars SwordEngine::_systemVars; + +void SwordEngine::errorString(const char *buf1, char *buf2) { + strcpy(buf2, buf1); +} + +extern uint16 _debugLevel; + +SwordEngine::SwordEngine(GameDetector *detector, OSystem *syst) + : Engine(syst) { + + _detector = detector; + _system = syst; + _debugLevel = ConfMan.getInt("debuglevel"); + + if (!_mixer->bindToSystem(syst)) + warning("Sound initialization failed"); +} + +SwordEngine::~SwordEngine() { +} + +void SwordEngine::initialize(void) { + _system->init_size(640, 480); + debug(5, "Starting memory manager"); + _memMan = new MemMan(); + debug(5, "Starting resource manager"); + _resMan = new ResMan("swordres.rif", _memMan); + debug(5, "Starting object manager"); + _objectMan = new ObjectMan(_resMan); + _mixer->setVolume(255); + _mouse = new SwordMouse(_system, _resMan, _objectMan); + _screen = new SwordScreen(_system, _resMan, _objectMan); + _music = new SwordMusic(_system, _mixer); + _sound = new SwordSound("", _mixer, _resMan); + _menu = new SwordMenu(_screen, _mouse); + _logic = new SwordLogic(_objectMan, _resMan, _screen, _mouse, _sound, _music, _menu); + _mouse->useLogic(_logic); + + _systemVars.justRestoredGame = _systemVars.currentCD = + _systemVars.gamePaused = _systemVars.saveGameFlag = + _systemVars.deathScreenFlag = _systemVars.currentMusic = 0; + _systemVars.snrStatus = 0; + _systemVars.rate = 8; + _systemVars.language = 2; + _systemVars.playSpeech = 1; + //- start.c: + // todo: move these to somewhere else + SwordLogic::_scriptVars[GEORGE_CDT_FLAG] = GEO_TLK_TABLE; + SwordLogic::_scriptVars[CHANGE_X] = 481; + SwordLogic::_scriptVars[CHANGE_Y] = 413; + SwordLogic::_scriptVars[CHANGE_DIR] = DOWN; + SwordLogic::_scriptVars[CHANGE_PLACE] = FLOOR_1; + + SwordLogic::_scriptVars[NEW_SCREEN] = 1; + _objectMan->fetchObject(PLAYER)->o_screen = 1; + _objectMan->megaEntering(1); + + SwordLogic::_scriptVars[CHANGE_STANCE] = STAND; + _mouseState = 0; +} + +void SwordEngine::go(void) { + + initialize(); + // check if we have savegames. if we do, show control panel, else start intro. + do { + mainLoop(); + // mainLoop was left, show control panel + } while (true); +} + +void SwordEngine::mainLoop(void) { + uint32 newTime, frameTime; + do { + // do we need the section45-hack from sword.c here? + // todo: ensure right cd is inserted + _screen->newScreen(SwordLogic::_scriptVars[NEW_SCREEN]); + _logic->newScreen(SwordLogic::_scriptVars[NEW_SCREEN]); + SwordLogic::_scriptVars[SCREEN] = SwordLogic::_scriptVars[NEW_SCREEN]; + // let swordSound start room sfx + do { + _music->stream(); + frameTime = _system->get_msecs(); + _systemVars.saveGameFlag = 0; + debug(5, "\n\nNext logic cycle"); + _logic->engine(); + _logic->updateScreenParams(); // sets scrolling + + _screen->recreate(); + _screen->spritesAndParallax(); + _mouse->animate(); + + newTime = _system->get_msecs(); + /*if ((newTime - frameTime < 50) && (!SwordLogic::_scriptVars[NEW_PALETTE])) { + RenderScreenGDK(); + BlitMenusGDK(); + BlitMousePm(); + if (newTime - frameTime < 40) + _system->delay_msecs(40 - (newTime - frameTime)); + FlipScreens(); + }*/ + + _sound->engine(); + _screen->showBarsAndNodes(_logic->giveRouter()); + _screen->updateScreen(); + //- + _menu->refresh(MENU_TOP); + _menu->refresh(MENU_BOT); + + newTime = _system->get_msecs(); + if (newTime - frameTime < 80) + delay(80 - (newTime - frameTime)); + else + delay(0); + + /*FlipScreens(); this is done in SwordScreen::updateScreen() now. + if (SwordLogic::_scriptVars[NEW_PALETTE]) { + SwordLogic::_scriptVars[NEW_PALETTE] = 0; + startFadePaletteUp(); + }*/ + + _mouse->engine( _mouseX, _mouseY, _mouseState); + _mouseState = 0; + // do something smart here to implement pausing the game. If we even want that, that is. + } while ((SwordLogic::_scriptVars[SCREEN] == SwordLogic::_scriptVars[NEW_SCREEN]) && + (_systemVars.saveGameFlag < 2)); // change screen + + if (SwordLogic::_scriptVars[SCREEN] != 53) // don't fade down after syria pan + _screen->fadeDownPalette(); + while (_screen->stillFading()) { + _screen->updateScreen(); + delay(1000/12); + // todo: fade sfx? + } + + _screen->quitScreen(); // close graphic resources + _objectMan->closeSection(SwordLogic::_scriptVars[SCREEN]); // close the section that PLAYER has just left, if it's empty now + // todo: stop sfx, clear sfx queue, free sfx memory + } while (_systemVars.saveGameFlag < 2); +} + +void SwordEngine::delay(uint amount) { //copied and mutilated from sky.cpp + + OSystem::Event event; + + uint32 start = _system->get_msecs(); + uint32 cur = start; + uint16 _key_pressed = 0; //reset + + do { + while (_system->poll_event(&event)) { + switch (event.event_code) { + case OSystem::EVENT_KEYDOWN: + + // Make sure backspace works right (this fixes a small issue on OS X) + if (event.kbd.keycode == 8) + _key_pressed = 8; + else + _key_pressed = (byte)event.kbd.ascii; + break; + case OSystem::EVENT_MOUSEMOVE: + _mouseX = event.mouse.x; + _mouseY = event.mouse.y; + break; + case OSystem::EVENT_LBUTTONDOWN: + _mouseState |= BS1L_BUTTON_DOWN; +#ifdef _WIN32_WCE + _mouseX = event.mouse.x; + _mouseY = event.mouse.y; +#endif + break; + case OSystem::EVENT_RBUTTONDOWN: + _mouseState |= BS1R_BUTTON_DOWN; + break; + case OSystem::EVENT_QUIT: + _system->quit(); + break; + default: + break; + } + } + + if (amount == 0) + break; + + { + uint this_delay = 20; // 1? +#ifdef _WIN32_WCE + this_delay = 10; +#endif + if (this_delay > amount) + this_delay = amount; + _system->delay_msecs(this_delay); + } + cur = _system->get_msecs(); + } while (cur < start + amount); +} diff --git a/sword1/sword1.h b/sword1/sword1.h new file mode 100644 index 0000000000..a59fe70c92 --- /dev/null +++ b/sword1/sword1.h @@ -0,0 +1,93 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#include +#include "base/engine.h" +#include "common/util.h" +#include "sound/mixer.h" +#include "base/gameDetector.h" + +class SwordScreen; +class SwordSound; +class SwordLogic; +class SwordMouse; +class ResMan; +class MemMan; +class ObjectMan; +class SwordMenu; +class SwordMusic; + +struct SystemVars { + // todo: move these to a better place + uint32 currentCD; // starts at zero, then either 1 or 2 depending on section being played + uint32 justRestoredGame; // see main() in sword.c & New_screen() in gtm_core.c + uint32 gamePaused; // 1 when paused + uint32 rate; // game rate => what's this for? + //uint32 textNumber; // holds last text_no displayed => I think it was only for debugging + //uint32 endOfQ; // next available slot in sound fx queue + //uint8 debug; // toggles tdebug file + + uint8 saveGameFlag; // controls save game loop 0=off 1=save game 2=restore game 3=restart 4=quit to dos + uint8 deathScreenFlag; // 1 death screen version of the control panel, 2 = successful end of game + uint8 playSpeech; + uint8 showText; + uint8 snrStatus; + // ^=> move into SwordControl... or whatever it will be. + //uint8 displayText; // toggles debug text display on "t" + //uint8 displayGrid; // toggles debug grid display on "g" + //uint8 displayMouse; // toggles debug mouse display on "m" + //uint8 framesPerSecond; // toggles one frame pre second mode on "1" + //uint8 writingPCXs; // writing a PCX every frame on "f" + //int16 parallaxOn; I think we don't need this. + uint8 language; + int32 currentMusic; + //uint32 gameCycle; +}; + +class SwordEngine : public Engine { + void errorString(const char *buf_input, char *buf_output); +public: + SwordEngine(GameDetector *detector, OSystem *syst); + virtual ~SwordEngine(); + static SystemVars _systemVars; +protected: + void go(); +private: + void delay(uint amount); + void initialize(void); + void mainLoop(void); + void fnCheckCd(uint32 newScreen); + + uint16 _mouseX, _mouseY, _mouseState; + + GameDetector *_detector; + OSystem *_system; + + MemMan *_memMan; + ResMan *_resMan; + ObjectMan *_objectMan; + SwordScreen *_screen; + SwordMouse *_mouse; + SwordLogic *_logic; + SwordSound *_sound; + SwordMenu *_menu; + SwordMusic *_music; +}; \ No newline at end of file diff --git a/sword1/sworddefs.h b/sword1/sworddefs.h new file mode 100644 index 0000000000..282e2ff78c --- /dev/null +++ b/sword1/sworddefs.h @@ -0,0 +1,1391 @@ +#ifndef SWORDDEFS_H +#define SWORDDEFS_H + +#include "scummsys.h" + +#define LOOPED 1 + +#define FRAME_RATE 12 // number of frames per second (max rate) +#define SCREEN_WIDTH 640 +#define SCREEN_DEPTH 400 +#define SCREEN_LEFT_EDGE 128 +#define SCREEN_RIGHT_EDGE (128+SCREEN_WIDTH-1) +#define SCREEN_TOP_EDGE 128 +#define SCREEN_BOTTOM_EDGE (128+SCREEN_DEPTH-1) +#define TYPE_FLOOR 1 +#define TYPE_MOUSE 2 +#define TYPE_SPRITE 3 +#define TYPE_NON_MEGA 4 +#define TYPE_MEGA 5 +#define TYPE_PLAYER 6 +#define TYPE_TEXT 7 +#define STAT_MOUSE 1 +#define STAT_LOGIC 2 +#define STAT_EVENTS 4 +#define STAT_FORE 8 +#define STAT_BACK 16 +#define STAT_SORT 32 +#define STAT_SHRINK 64 +#define STAT_BOOKMARK 128 +#define STAT_TALK_WAIT 256 +#define STAT_OVERRIDE 512 + +#define LOGIC_idle 0 +#define LOGIC_script 1 +#define LOGIC_AR_animate 2 +#define LOGIC_interaction 3 +#define LOGIC_speech 4 +#define LOGIC_full_anim 5 +#define LOGIC_anim 6 +#define LOGIC_pause 7 +#define LOGIC_wait_for_sync 8 +#define LOGIC_quit 9 +#define LOGIC_restart 10 +#define LOGIC_bookmark 11 +#define LOGIC_wait_for_talk 12 +#define LOGIC_start_talk 13 +#define LOGIC_choose 14 +#define LOGIC_new_script 15 +#define LOGIC_pause_for_event 16 + +#define TOTAL_subjects (375-256+1) +#define BASE_SUBJECT 256 + +#define TOTAL_SECTIONS 150 //number of sections, rooms + mega sections +#define TOTAL_ROOMS 100 //total number of rooms +#define ITM_PER_SEC 0x10000 //65536 items per section -> was originally called "SIZE" +#define ITM_ID 0xFFFF //& with this -> originally "NuSIZE" + +#define MAX_text_obs 2 //text compacts +#define TEXT_sect 149 //text compacts exist in section 149, probably after all the megas + +/*struct Header { + // I took this one from QEADER.H, but it looks like it's something different than _header. + // => commented out. + int16 version; + char type[4]; + int32 comp_length; + char compression[4]; + int32 decomp_length; +};*/ + +#if !defined(__GNUC__) + #pragma START_PACK_STRUCTS +#endif + +struct Header { + char type[6]; + uint16 version; + uint32 comp_length; + char compression[4]; + uint32 decomp_length; +} GCC_PACK; + +struct FrameHeader { + uint8 runTimeComp[4]; + uint32 compSize; + uint16 width; + uint16 height; + int16 offsetX; + int16 offsetY; +} GCC_PACK; + +struct ParallaxHeader { + char type[16]; + uint16 sizeX; + uint16 sizeY; + uint32 lineIndexes[2]; //2 is arbitrary number +} GCC_PACK; + +struct AnimUnit { + uint32 animX; + uint32 animY; + uint32 animFrame; +} GCC_PACK; + +struct AnimSet { + uint32 cdt; + uint32 spr; +} GCC_PACK; + +struct WalkGridHeader { + int32 scaleA; + int32 scaleB; + int32 numBars; + int32 numNodes; +} GCC_PACK; + +#if !defined(__GNUC__) + #pragma END_PACK_STRUCTS +#endif + +/*struct RSprite { + Header header; + uint32 totalSprites; + uint32 spriteOffset[2]; //2 is arbitrary number +}*/ + +enum Language { + BS1_ENGLISH = 0, + BS1_FRENCH, + BS1_GERMAN, + BS1_ITALIAN, + BS1_SPANISH, + BS1_CZECH, + BS1_PORT +}; + +#define SCRIPT_CONT 1 +#define SCRIPT_STOP 0 + +#define PLAYER 8388608 +#define NICO 8454144 +#define GEORGE 8388608 +#define DOWN 4 +#define FLOOR_1 65536 +#define BENOIR 8585216 +#define ROSSO 8716288 +#define MOUE 9502720 +#define ALBERT 9568256 +#define DUANE 8781824 + +#define IT_MCODE 1 // Call an mcode routine +#define IT_PUSHNUMBER 2 // push a number on the stack +#define IT_PUSHVARIABLE 3 // push a variable on the stack + +#define IT_FIRSTOPERATOR 4 // Operators come after this and must stay in the same order for precedence table + +#define IT_NOTEQUAL 4 +#define IT_ISEQUAL 5 +#define IT_PLUS 6 +#define IT_TIMES 7 +#define IT_ANDAND 8 +#define IT_OROR 9 +#define IT_LESSTHAN 10 +#define IT_NOT 11 +#define IT_MINUS 12 +#define IT_AND 13 +#define IT_OR 14 +#define IT_GTE 15 // >= +#define IT_LTE 16 // <= +#define IT_DEVIDE 17 // <= +#define IT_GT 18 // > + +#define IT_SCRIPTEND 20 +#define IT_POPVAR 21 +#define IT_POPLONGOFFSET 22 +#define IT_PUSHLONGOFFSET 23 +#define IT_SKIPONFALSE 24 +#define IT_SKIP 25 +#define IT_SWITCH 26 +#define IT_SKIPONTRUE 27 +#define IT_PRINTF 28 +#define IT_RESTARTSCRIPT 30 +#define IT_POPWORDOFFSET 31 +#define IT_PUSHWORDOFFSET 32 + +#define STAND 0 + +enum ScriptVariableNames { + RETURN_VALUE = 0, + RETURN_VALUE_2, + RETURN_VALUE_3, + RETURN_VALUE_4, + DEFAULT_ICON_TEXT, + MENU_LOOKING, + TOP_MENU_DISABLED, + GEORGE_DOING_REST_ANIM, + GEORGE_WALKING, + ADVISOR_188_FLAG, + MEGA_ON_GRID, + REROUTE_GEORGE, + WALK_FLAG, + WALK_ATTEMPT, + TARGET_X, + TARGET_Y, + DISTANCE_APART, + ID_LOW_FLOOR, + NEW_SCREEN, + CUR_ID, + MOUSE_STATUS, + PALETTE, + NEW_PALETTE, + MOUSE_X, + MOUSE_Y, + SPECIAL_ITEM, + CLICK_ID, + MOUSE_BUTTON, + BUTTON, + BOTH_BUTTONS, // not used anymore + SAFE_X, + SAFE_Y, + CHANGE_X, + CHANGE_Y, + CHANGE_PLACE, + CHANGE_DIR, + CHANGE_STANCE, + SCROLL_FLAG, + SCROLL_OFFSET_X, + SCROLL_OFFSET_Y, + MAX_SCROLL_OFFSET_X, + MAX_SCROLL_OFFSET_Y, + FEET_X, + FEET_Y, + SECOND_ICON, + SUBJECT_CHOSEN, + IN_SUBJECT, + DEBUG_FLAG_1, + DEBUG_FLAG_2, + DEBUG_FLAG_3, + FIRST_WATCH, + GEORGE_ALLOWED_REST_ANIMS, + CURRENT_MUSIC, + TESTLINENO, + LASTLINENO, + WANTPREVIOUSLINE, + PLAYINGDEMO, + TEMP_FLAG, + PHOTOS_FLAG, + PHONE_FLOOR_FLAG, + PHONE_ROOM_FLAG, + BENOIR_FLAG, + GUARD_FLAG, + MOUE_DOOR_FLAG, + CANOPY_FLAG, + GOT_NEWSPAPER_FLAG, + DEMO_NICO_FLAG, + NICO_TARGET, + NICO_DIR, + BEEN_TO_ALLEY, + DUSTBIN_FLAG, + DUSTBIN_2_FLAG, + TRIED_MANHOLE_FLAG, + MANHOLE_FLAG, + DRAINPIPE_FLAG, + OPENED_MANHOLE_2_BEFORE, + SEARCHED_PLANTARD_FLAG, + ENTERED_CAFE_ONCE, + BOTTLE_3_FLAG, + TOOLBOX_4_FLAG, + CALL_ALB_FLAG, + CALL_ALBERT_FLAG, + GOT_NOSE_FLAG, + GOT_MATERIAL_FLAG, + GOT_TISSUE_FLAG, + RAILING_7_FLAG, + SEEN_FLOWERS_FLAG, + SEEN_DRESS_SHOP_FLAG, + DOOR_9_FLAG, + PHONE_10_FLAG, + MANUSCRIPT_ON_TABLE_10_FLAG, + DOG_TURD_FLAG, + PIERMONT_AT_PIANO_FLAG, + GOT_KEY_FLAG, + USED_HOTEL_KEY_ONCE, + WINDOW_15_OPEN, + CLIMBED_OUT_15_FLAG, + WINDOW_16_FLAG, + HOTEL_ASSASSIN_BEEN, + WARDROBE_17_OPEN, + SEARCHED_TROUSERS_17, + ENTERED_17_FLAG, + WINDOW_27_FLAG, + CASE_1_LOCKED_FLAG, + CASE_2_LOCKED_FLAG, + CASE_3_LOCKED_FLAG, + CASE_4_LOCKED_FLAG, + SEEN_ARMOUR_28_FLAG, + CLOSED_WINDOW_28_FLAG, + WINDOW_28_FLAG, + WINDOW_DRAUGHT_FLAG, + SEEN_WINDOW_28_FLAG, + FACING_WINDOW_FLAG, + CLOSING_WINDOW_FLAG, + SARCOPHAGUS_FLAG, + ENTERED_MUSEUM_28_FLAG, + SARCOPHAGUS_DOOR_29_OPEN, + AMBULANCE_31_FLAG, + CONSULTANT_HERE, + SEEN_MR_SHINY_FLAG, + SEEN_CUPBOARD_FLAG, + PLUG_33_UNPLUGGED, + SAM_RETURNING, + PULLED_PLUG_33, + PULSE_34_FLAG, + DOOR_34_OPEN, + MARQUET_AWAKE_FLAG, + JUGGLER_FLAG, + JUGGLE_FLAG, + CROWD_FLAG, + MANHOLE_36_FLAG, + DOOR_37_FLAG, + IN_BOAT_FLAG, + GOT_HOOK_FLAG, + HOOK_FLAG, + STEPS_38_FLAG, + TRIPOD_PUZZLE_FLAG, + SOAP_43_FLAG, + SEEN_WASHBASIN_43, + HOSPITAL_FLAG, + SEEN_PARIS_MAP, + PHONE_SCREEN_FLAG, + PHONE_PLACE_FLAG, + SEAN_DEAD, + SPAIN_VISIT, + WET_BEER_TOWEL_TIMER, + BEER_TOWEL_BEEN_WET, + NICO_SCOT_SCREEN, + NICO_AT_PANEL_72, + NICO_POSITION_71, + SEEN_DRAIN_19, + SEEN_MENU_19, + PUB_TRAP_DOOR, + ASSASSIN_EIRE_DONE, + BAR_TOWEL_TAKEN, + GLASS_WASH_FLAG, + PUB_DOOR_FLAG, + PUB_FLAP_FLAG, + DOYLE_DRINKING, + RON_SNEEZING, + FUSE_WIRE_TAKEN, + FUSE_WIRE_ON_TABLE, + GLASS_20_FLAG, + MAGUIRE_PUB_DONE, + PINT_LEVEL_FLAG, + GEM_21_TAKEN, + MAGUIRE_CEL_DONE, + TORCH_21_TAKEN, + BEEN_UP_HAYBAILS, + LIFTING_KEYS_IN_HOLE_23, + SEEN_STEPS_SEQUENCE, + SEEN_GOAT_24, + FLEECY_TANGLED, + FLEECY_STUCK, + FLEECY_BACKING_OFF, + SEEN_LADDER_SEQUENCE, + BUTT_COUNT_24, + KEYSTONE_FLAG, + PANEL_25_MOVED, + SACK_25_FLAG, + SAND_FLAG, + SEEN_HOLES_25, + REPLICA_IN_CAVITY, + SEEN_RAT_26, + ENTERED_CELLAR_BEFORE, + CAT_ON_SHELF, + CAT_RAN_OFF, + CAT_TIMER, + STATUETTE_FLAG, + SEEN_TOP_SHELF_45, + DUANE_TARGET, + AYUB_OPENING_DOOR, + GEORGE_TALKING_TO_PEARL, + CARPET_DOOR_47_OPEN, + TOILET_KEYS_ON_BAR, + EXPLAINED_RETURNING_KEYS, + DOOR_49_OPEN, + TOILET_CHAIN_50_TAKEN, + TOWEL_DISPENSER_50_OPEN, + TOWEL_50_TAKEN, + CUBICLE_DOOR_50_OPEN, + DOOR_50_OPEN, + MAX_ITERATION, + ITERATION, + STICK_54_FLAG, + TOWEL_IN_CRACK_54, + CAVE_54_OPEN, + GUN_54_FLAG, + KHAN_54_HERE, + DOOR_55_OPEN, + READ_INSCRIPTION_55, + SEEN_STATUE_55, + VISITED_COUNTESS_56_AGAIN, + CHALICE_56_GIVEN, + CHESS_PIECE_56_GIVEN, + GARDENER_57_HERE, + PRESSURE_GAUGE_57_FLAG, + FOUND_WELL_57, + DOOR_58_OPEN, + COUNTESS_58_HERE, + GARDENER_58_HERE, + COUNTESS_59_HERE, + BIBLE_59_FLAG, + WINDOW_59_SHUT, + CHALICE_59_TAKEN, + SECRET_DOOR_59_OPEN, + HOLDING_SNUFFER, + TISSUE_ON_SNUFFER, + TISSUE_59_CHARRED, + TISSUE_59_BURNING, + CANDLE_59_BURNT, + LECTERN_CANDLES_59_LIT, + TISSUE_FLAME_59_ON, + GARDENER_60_POSITION, + GARDENER_60_CHECKING_DOGS, + DOGS_DISTURBED, + MIRROR_60_TAKEN, + SEEN_LEFT_ROCKFALL_61, + LION_HEAD_FALLING, + LION_FANG_FLAG, + DOOR_61_FLAG, + GEORGE_HOLDING_PIECE, + CHESS_SQUARE_1_FLAG, + CHESS_SQUARE_2_FLAG, + CHESS_SQUARE_3_FLAG, + CHESS_SQUARE_4_FLAG, + CHESS_SQUARE_5_FLAG, + DOOR_ONE_63_OPEN, + DOOR_TWO_63_OPEN, + DOOR_THREE_63_OPEN, + GEORGE_ON_ROOF, + SEEN_EKLUND_63, + DOOR_65_OPEN, + DOOR_67_OPEN, + WINDOW_66_OPEN, + SEQUENCE_69_FLAG, + SC69_TIMER, + LEFT_TREE_POINTER_71_FLAG, + RIGHT_TREE_POINTER_71_FLAG, + RUBBLE_72_FLAG, + MACHINERY_HANDLE_FLAG, + MACHINERY_COG_FLAG, + DEMON_RB_FLAG, + DEMON_LB_FLAG, + DEMON_COGS_FLAG, + DEMON_PIPE_FLAG, + DEMON_NOSE_FLAG, + DEMON_LEFT_COG_FLAG, + DEMON_RIGHT_COG_FLAG, + PANEL_72_FLAG, + SEEN_CRYPT_73, + SEEN_GUNPOWDER_73, + GUIDO_73_HERE, + NICO_POSITION_73, + ALBERT_ANNOYED_FLAG, + ALBERT_BRIEFCASE_FLAG, + ALBERT_BUZZER_FLAG, + ALBERT_CDT_FLAG, + ALBERT_CHANTELLE_FLAG, + ALBERT_CHAT_FLAG, + ALBERT_CLOWN_FLAG, + ALBERT_JACKET_FLAG, + ALBERT_KEYS_FLAG, + ALBERT_NOSE_FLAG, + ALBERT_PLANTARD_FLAG, + ALBERT_POLICE_FLAG, + ALBERT_POS_FLAG, + ALBERT_TALK_FLAG, + ALBERT_TISSUE_FLAG, + ALBERT_TEXT, + ALBERT_INFO_FLAG, + ARTO_BULL_FLAG, + ARTO_BRUSH_FLAG, + ARTO_IRRITATION_FLAG, + ARTO_KLAUSNER_FLAG, + ARTO_LOOM_FLAG, + ARTO_OBJECT_FLAG, + ARTO_PHRASE_FLAG, + ARTO_TEXT, + ASSASSIN_BOOK_FLAG, + ASSASSIN_BULL_FLAG, + ASSASSIN_CHURCH_FLAG, + ASSASSIN_EIRE_TEXT, + ASSASSIN_SWORD_FLAG, + ASSASSIN_TEMPLAR_FLAG, + ASSASSIN_TEXT, + AYUB_BULL_FLAG, + AYUB_KLAUSNER_FLAG, + AYUB_LOOM_FLAG, + AYUB_ULTAR_FLAG, + AYUB_TEXT, + BASHER_BEER_FLAG, + BASHER_COMPLAIN_FLAG, + BASHER_EKLUND_FLAG, + BASHER_HELP_FLAG, + BASHER_NICO_FLAG, + BASHER_STOP_FLAG, + BASHER_WEASEL_FLAG, + BASHER_WINDOW_FLAG, + BASHER_TEXT, + BENOIR_BUZZER_FLAG, + BENOIR_GAUGE_FLAG, + BENOIR_MARQUET_FLAG, + BENOIR_NURSE_FLAG, + BENOIR_RENEE_FLAG, + BENOIR_TEXT, + CARPET_TEXT, + CARPET_OBJECT_FLAG, + CHANTELLE_BRIEFCASE_FLAG, + CHANTELLE_CLOWN_FLAG, + CHANTELLE_DOCTOR_FLAG, + CHANTELLE_EYE_FLAG, + CHANTELLE_FAINT_FLAG, + CHANTELLE_NEWSPAPER_FLAG, + CHANTELLE_PLANTARD_FLAG, + CHANTELLE_TEXT, + CHANTELLE_WAKE_COUNTER, + CLERK_ASSASSIN_FLAG, + CLERK_BUZZER_FLAG, + CLERK_CLOWN_FLAG, + CLERK_ENOUGH_FLAG, + CLERK_HKEY_FLAG, + CLERK_KEY_FLAG, + CLERK_KEY_STOP_FLAG, + CLERK_NOSE_FLAG, + CLERK_PASS_FLAG, + CLERK_PHOTO_FLAG, + CLERK_PIERMONT_FLAG, + CLERK_PLANTARD_FLAG, + CLERK_POLITE_FLAG, + CLERK_SAFE_FLAG, + CLERK_TEMPLAR_FLAG, + CLERK_TEXT, + CLERK_TISSUE_FLAG, + CLERK_WEASEL_FLAG, + CONSULT_CHALICE_FLAG, + CONSULT_GAUGE_FLAG, + CONSULT_GEM_FLAG, + CONSULT_LIFTKEY_FLAG, + CONSULT_MARQUET_FLAG, + CONSULT_NOSE_FLAG, + CONSULT_PHOTO_FLAG, + CONSULT_TEXT, + CONSULT_TISSUE_FLAG, + COSTUMIER_BALL_FLAG, + COSTUMIER_BUZZER_FLAG, + COSTUMIER_CLOWN_FLAG, + COSTUMIER_PHOTO_FLAG, + COSTUMIER_PLANTARD_FLAG, + COSTUMIER_TISSUE_FLAG, + COSTUMIER_TEXT, + DOYLE_BEER_FLAG, + DOYLE_BUZZER_FLAG, + DOYLE_CASTLE_FLAG, + DOYLE_DIG_FLAG, + DOYLE_FLASHLIGHT_FLAG, + DOYLE_GEM_FLAG, + DOYLE_JEWEL_FLAG, + DOYLE_JOB_FLAG, + DOYLE_KEYS_FLAG, + DOYLE_LEPRECHAUN_FLAG, + DOYLE_NOSE_FLAG, + DOYLE_PEAGRAM_FLAG, + DOYLE_PHOTOGRAPH_FLAG, + DOYLE_SEAN_FLAG, + DOYLE_TEMPLAR_FLAG, + DOYLE_TEXT, + DOYLE_TISSUE_FLAG, + DOYLE_TOWEL_FLAG, + DUANE_ARTO_FLAG, + DUANE_BULL_FLAG, + DUANE_CLEVE_FLAG, + DUANE_DUANE_FLAG, + DUANE_PEARL_FLAG, + DUANE_PHOTO_FLAG, + DUANE_KEYS_FLAG, + DUANE_MANUSCRIPT_FLAG, + DUANE_NEJO_FLAG, + DUANE_PHRASE_FLAG, + DUANE_QUEEN_FLAG, + DUANE_STATUETTE_FLAG, + DUANE_TEMPLAR_FLAG, + DUANE_TEXT, + DUANE_ULTAR_FLAG, + ERIC_MARQUET_FLAG, + ERIC_NURSE_FLAG, + ERIC_PHOTO_FLAG, + EVA_CLOWN_FLAG, + EVA_LENS_FLAG, + EVA_MARQUET_FLAG, + EVA_MOB_FLAG, + EVA_NURSE_FLAG, + EVA_TEXT, + FARMER_BEER_FLAG, + FARMER_BOOK_FLAG, + FARMER_BUZZER_FLAG, + FARMER_CAR_FLAG, + FARMER_CASTLE_FLAG, + FARMER_FLASHLIGHT_FLAG, + FARMER_GEM_FLAG, + FARMER_GHOST_FLAG, + FARMER_LAST_STRAW, + FARMER_LIFTKEYS_FLAG, + FARMER_MOVED_FLAG, + FARMER_NOSE_FLAG, + FARMER_PASS_FLAG, + FARMER_PEAGRAM_FLAG, + FARMER_PHOTO_FLAG, + FARMER_SEAN_FLAG, + FARMER_TEMPLAR_FLAG, + FARMER_TEXT, + FARMER_TISSUE_FLAG, + FARMER_WIRE_FLAG, + FLEECY_TEXT, + FLOWER_FLOWER_FLAG, + FLOWER_FORTUNE_FLAG, + FLOWER_GAUGE_FLAG, + FLOWER_GEM_FLAG, + FLOWER_LIFTKEYS_FLAG, + FLOWER_NICO_FLAG, + FLOWER_PASS_FLAG, + FLOWER_PHOTO_FLAG, + FLOWER_TEXT, + GARD_ATTEMPT, + GARD_BY_WELL, + GARDENER_COUNTESS_FLAG, + GARDENER_CHALICE_FLAG, + GARDENER_FLOPPO_FLAG, + GARDENER_GOODBYE_FLAG, + GARDENER_HOSE_FLAG, + GARDENER_IRRITATION, + GARDENER_SPEECH_FLAG, + GARDENER_TEMPLAR_FLAG, + GARDENER_TEXT, + GATEKEEPER_TALK_FLAG, + GATEKEEPER_CDT_FLAG, + GMASTER_TALK_FLAG, + GMASTER_CDT_FLAG, + GENDARME_CARD_FLAG, + GENDARME_CLOWN_FLAG, + GENDARME_MOUE_FLAG, + GENDARME_NOSE_FLAG, + GEND_PAPER_FLAG, + GENDARME_PHOTO_FLAG, + GENDARME_ROSSO_FLAG, + GENDARME_TEXT, + GENDARME_TISSUE_FLAG, + GENDARME_WEASEL_FLAG, + GOINFRE_ALARM_FLAG, + GOINFRE_EXHIBIT_FLAG, + GOINFRE_GEM_FLAG, + GOINFRE_KEYS_FLAG, + GOINFRE_LOBINEAU_FLAG, + GOINFRE_MS_FLAG, + GOINFRE_SARCOPHAGUS_FLAG, + GOINFRE_SCOLD_FLAG, + GOINFRE_TEMPLAR_FLAG, + GOINFRE_TEXT, + GOINFRE_TISSUE_FLAG, + GOINFRE_TRIPOD_FLAG, + GOINFRE_WINDOW_FLAG, + GORILLA_CLOWN_FLAG, + GORILLA_KHAN_FLAG, + GORILLA_PASS_FLAG, + GORILLA_PLANTARD_FLAG, + GORILLA_SEARCH_FLAG, + GORILLA_TEXT, + GORILLA_TISSUE_FLAG, + GORILLA_WEASEL_FLAG, + HOSCOP_ALERT_FLAG, + HOSCOP_MARQUET_FLAG, + HOSCOP_MOB_FLAG, + HOSCOP_TEXT, + JUGGLER_JUGGLER_FLAG, + JUGGLER_TEMPLAR_FLAG, + JUGGLER_GEM_FLAG, + JUGGLER_TEXT, + KHAN_SUBJECT_FLAG, + KHAN_PREAMBLE_FLAG, + LATVIAN_CLOWN_FLAG, + LATVIAN_EYE_FLAG, + LATVIAN_LIFTKEYS_FLAG, + LATVIAN_MATCHBOOK_FLAG, + LATVIAN_MS_FLAG, + LATVIAN_NOSE_FLAG, + LATVIAN_PHOTO_FLAG, + LATVIAN_PLANTARD_FLAG, + LATVIAN_TEXT, + LEARY_BEER_FLAG, + LEARY_BUZZER_FLAG, + LEARY_CASTLE_FLAG, + LEARY_CLOWN_FLAG, + LEARY_FISH_FLAG, + LEARY_FLAP_FLAG, + LEARY_FLAPALERT_FLAG, + LEARY_KEYS_FLAG, + LEARY_NOSE_FLAG, + LEARY_PASS_FLAG, + LEARY_PEAGRAM_FLAG, + LEARY_PHONE_FLAG, + LEARY_PHOTO_FLAG, + LEARY_PLASTER_FLAG, + LEARY_PLUG_FLAG, + LEARY_SEAN_FLAG, + LEARY_SNARE_FLAG, + LEARY_TEMPLAR_FLAG, + LEARY_TEXT, + LEARY_TISSUE_FLAG, + LEARY_TOWEL_FLAG, + LEARY_WASHER_FLAG, + LEARY_WILD_FLAG, + LEARY_WIRE_FLAG, + LOBINEAU_ARTEFACT_FLAG, + LOBINEAU_BALL_FLAG, + LOBINEAU_BEL_FLAG, + LOBINEAU_GEM_FLAG, + LOBINEAU_HASH_FLAG, + LOBINEAU_KEYS_FLAG, + LOBINEAU_MANUSCRIPT_FLAG, + LOBINEAU_MATCHBOOK_FLAG, + LOBINEAU_MONTFAUCON_FLAG, + LOBINEAU_NICO_FLAG, + LOBINEAU_PANTS_FLAG, + LOBINEAU_PEAGRAM_FLAG, + LOBINEAU_STATUE_FLAG, + LOBINEAU_SYRIA_FLAG, + LOBINEAU_TEMPLAR_FLAG, + LOBINEAU_TEXT, + LOBINEAU_TRIPOD_FLAG, + MAGUIRE_CAR_FLAG, + MAGUIRE_CASTLE_FLAG, + MAGUIRE_CDT_FLAG, + MAGUIRE_CLOWN_FLAG, + MAGUIRE_COP_FLAG, + MAGUIRE_DIG_FLAG, + MAGUIRE_GEM_FLAG, + MAGUIRE_GHOST_FLAG, + MAGUIRE_JEWEL_FLAG, + MAGUIRE_KEYS_FLAG, + MAGUIRE_LEPRECHAUN_FLAG, + MAGUIRE_NOSE_FLAG, + MAGUIRE_PEAGRAM_FLAG, + MAGUIRE_SEAN_FLAG, + MAGUIRE_SHOCK_FLAG, + MAGUIRE_TALK_FLAG, + MAGUIRE_TEXT, + MAGUIRE_WIRE_FLAG, + MANAGER_TEXT, + MANAGER_BRUSH_FLAG, + MANAGER_SPEECH_FLAG, + MOUE_BALL_FLAG, + MOUE_BRIEFCASE_FLAG, + MOUE_CARD_FLAG, + MOUE_CDT_FLAG, + MOUE_CLOWN_FLAG, + MOUE_EYE_FLAG, + MOUE_FETCH_FLAG, + MOUE_HASH_FLAG, + MOUE_KEY_FLAG, + MOUE_MARQUET_FLAG, + MOUE_MATCHBOOK_FLAG, + MOUE_MATERIAL_FLAG, + MOUE_MOB_FLAG, + MOUE_NEWSPAPER_FLAG, + MOUE_NICO_FLAG, + MOUE_NOSE_FLAG, + MOUE_PHOTO_FLAG, + MOUE_PLANTARD_FLAG, + MOUE_ROSSO_FLAG, + MOUE_STOP_FLAG, + MOUE_TALK_FLAG, + MOUE_TEXT, + MOUE_TISSUE_FLAG, + NEJO_ARTO_FLAG, + NEJO_AYUB_FLAG, + NEJO_BALL_FLAG, + NEJO_BALL_TALK, + NEJO_BULL_FLAG, + NEJO_CAT_FLAG, + NEJO_CHALICE_FLAG, + NEJO_DOLLAR_FLAG, + NEJO_GOODBYE_FLAG, + NEJO_HENDERSONS_FLAG, + NEJO_LOOM_FLAG, + NEJO_NEJO_FLAG, + NEJO_PHRASE_FLAG, + NEJO_PLASTER_FLAG, + NEJO_PRESSURE_GAUGE_FLAG, + NEJO_STALL_FLAG, + NEJO_STATUE_FLAG, + NEJO_TEMPLAR_FLAG, + NEJO_TEXT, + NEJO_ULTAR_FLAG, + NICO_ALBERT_FLAG, + NICO_ASSASSIN_FLAG, + NICO_BALL_FLAG, + NICO_BRIEFCASE_FLAG, + NICO_BULL_FLAG, + NICO_BUZZER_FLAG, + NICO_CHALICE_FLAG, + NICO_CDT_FLAG, + NICO_CLOWN_FLAG, + NICO_EKLUND_FLAG, + NICO_GAUGE_FLAG, + NICO_GEM_FLAG, + NICO_GOODBYE_FLAG, + NICO_GUIDO_FLAG, + NICO_HASH_FLAG, + NICO_IRELAND_FLAG, + NICO_KNIGHT_FLAG, + NICO_LIFTKEYS_FLAG, + NICO_LENS_FLAG, + NICO_LOBINEAU_FLAG, + NICO_MANUSCRIPT_FLAG, + NICO_MARQUET_FLAG, + NICO_MATCHBOOK_FLAG, + NICO_MATERIAL_FLAG, + NICO_NEWSPAPER_FLAG, + NICO_NICO_FLAG, + NICO_NOSE_FLAG, + NICO_PASS_FLAG, + NICO_PEAGRAM_FLAG, + NICO_PLANTARD_FLAG, + NICO_PLASTER_FLAG, + NICO_PHOTO_FLAG, + NICO_PHONE_TEXT, + NICO_POS_FLAG, + NICO_QUEEN_FLAG, + NICO_RINGING_BACK_FLAG, + NICO_ROSSO_FLAG, + NICO_SEWER_FLAG, + NICO_SPAIN_FLAG, + NICO_SYRIA_FLAG, + NICO_TALK_FLAG, + NICO_TEMPLAR_FLAG, + NICO_TEXT, + NICO_TISSUE_FLAG, + NICO_TRAIN_FLAG, + NICO_TRIPOD_FLAG, + NICO_WEAVER_FLAG, + NIC_BAG_TALK_FLAG, + NIC_BAG_CDT_FLAG, + NICO_LEAVING_CAFE_SCREEN, + NURSE_BENOIR_FLAG, + NURSE_CLOWN_FLAG, + NURSE_GAUGE_FLAG, + NURSE_MARQUET_FLAG, + NURSE_INTERRUPTION_FLAG, + NURSE_TEXT, + OBRIEN_BUZZER_FLAG, + OBRIEN_CASTLE_FLAG, + OBRIEN_FLASHLIGHT_FLAG, + OBRIEN_GEM_FLAG, + OBRIEN_JEWEL_FLAG, + OBRIEN_JOB_FLAG, + OBRIEN_KEYS_FLAG, + OBRIEN_LEARY_FLAG, + OBRIEN_MAGUIRE_FLAG, + OBRIEN_NOSE_FLAG, + OBRIEN_PEAGRAM_FLAG, + OBRIEN_SEAN_FLAG, + OBRIEN_TEMPLAR_FLAG, + OBRIEN_TEXT, + OBRIEN_TISSUE_FLAG, + OBRIEN_TOWEL_FLAG, + OLD_NOSE_FLAG, + OLD_PHOTO_FLAG, + OLD_LIFT_FLAG, + OLD_BUZZER_FLAG, + PAINTER_DIG_FLAG, + PAINTER_DISTRACTION_FLAG, + PAINTER_PAINTER_FLAG, + PAINTER_TEMPLAR_FLAG, + PAINTER_CONTROL_FLAG, + PAINTER_TEXT, + PEARL_AKRON_FLAG, + PEARL_ARTO_FLAG, + PEARL_BULL_FLAG, + PEARL_DUANE_FLAG, + PEARL_NEJO_FLAG, + PEARL_PEARL_FLAG, + PEARL_PHRASE_FLAG, + PEARL_POEMS_FLAG, + PEARL_STATUE_FLAG, + PEARL_TEMPLAR_FLAG, + PEARL_TEXT, + PEARL_ULTAR_FLAG, + PEARL_TALK_FLAG, + PEARL_CDT_FLAG, + PEARL_STALL_FLAG, + PEARL_WEAVER_FLAG, + PIERMONT_ASSASSIN_FLAG, + PIERMONT_BUZZER_FLAG, + PIERMONT_CLOWN_FLAG, + PIERMONT_GEM_FLAG, + PIERMONT_HKEY_FLAG, + PIERMONT_KEY_FLAG, + PIERMONT_KEY_ALERT_FLAG, + PIERMONT_MS_FLAG, + PIERMONT_NOSE_FLAG, + PIERMONT_PASS_FLAG, + PIERMONT_PHOTO_FLAG, + PIERMONT_PIERMONT_FLAG, + PIERMONT_TEMPLAR_FLAG, + PIERMONT_TEXT, + PIERMONT_TISSUE_FLAG, + PIERMONT_WEASEL_FLAG, + PRIEST_TEXT, + PRIEST_CHALICE_FLAG, + PRIEST_CHALICE2_FLAG, + PRIEST_TEMPLAR_FLAG, + PRIEST_PRIEST_FLAG, + PRIEST_WINDO1_FLAG, + PRIEST_WINDO2_FLAG, + PRIEST_WINDO3_FLAG, + RENEE_MARQUET_FLAG, + RENEE_PHOTO_FLAG, + RENEE_RENEE_FLAG, + RENEE_TEXT, + RON_ALERT_FLAG, + RON_BEER_FLAG, + RON_CASTLE_FLAG, + RON_DIG_FLAG, + RON_FLASHLIGHT_FLAG, + RON_GHOST_FLAG, + RON_NOSE_FLAG, + RON_PASS_FLAG, + RON_PEAGRAM_FLAG, + RON_PHOTO_FLAG, + RON_POLICE_FLAG, + RON_SEAN_FLAG, + RON_SNARE_FLAG, + RON_STOP_FLAG, + RON_TEXT, + RON_UPSET_FLAG, + ROSSO_CDT_FLAG, + ROSSO_CLOWN_FLAG, + ROSSO_DOCTOR_FLAG, + ROSSO_FORTUNE_FLAG, + ROSSO_GEM_FLAG, + ROSSO_MARQUET_FLAG, + ROSSO_MATCHBOOK_FLAG, + ROSSO_MOUE_FLAG, + ROSSO_OPINION_FLAG, + ROSSO_PASS_FLAG, + ROSSO_PEAGRAM_FLAG, + ROSSO_PHOTO_FLAG, + ROSSO_PLANTARD_FLAG, + ROSSO_ROSSO_FLAG, + ROSSO_TALK_FLAG, + ROSSO_TEMPLAR_FLAG, + ROSSO_TEXT, + ROSSO_THUGS_FLAG, + ROZZER_36_FLAG, + ROZZER_JUGGLER_FLAG, + ROZZER_MANHOLE_FLAG, + ROZZER_PLASTER_FLAG, + ROZZER_ROZZER_FLAG, + ROZZER_TEMPLAR_FLAG, + ROZZER_TEXT, + SAM_BREAKDOWN_FLAG, + SAM_BUZZER_FLAG, + SAM_CUPBOARD_FLAG, + SAM_GEM_FLAG, + SAM_MARQUET_FLAG, + SAM_MATCHBOOK_FLAG, + SAM_MOB_FLAG, + SAM_NOSE_FLAG, + SAM_NURSE_FLAG, + SAM_PHOTO_FLAG, + SAM_PLASTER_FLAG, + SAM_SHINY_FLAG, + SAM_SOCKET_FLAG, + SAM_STOP_FLAG, + SAM_TEXT, + SEAN_ASSASSIN_FLAG, + SEAN_BEER_FLAG, + SEAN_CASTLE_FLAG, + SEAN_DIG_FLAG, + SEAN_GEM_FLAG, + SEAN_LKEYS_FLAG, + SEAN_NOSE_FLAG, + SEAN_OPINION, + SEAN_PACKAGE_FLAG, + SEAN_PEAGRAM_FLAG, + SEAN_SELF_FLAG, + SEAN_SNAP_FLAG, + SEAN_TEXT, + STATUE_GUARD_CONTROL_FLAG, + STATUE_GUARD_FLAG, + STATUE_GUARD_GUARD_FLAG, + STATUE_GUARD_KEY, + GUARD_GLOVE_FLAG, + STATUE_GUARD_TEMPLAR_FLAG, + STATUE_GUARD_THERMO_FLAG, + STATUE_GUARD_TEXT, + STATUE_GUARD_TALK_FLAG, + STATUE_GUARD_CDT_FLAG, + TCLERK_PIERMONT_FLAG, + TNIC_ENQUIRY_FLAG, + TODRYK_CLOWN_FLAG, + TODRYK_EYE_FLAG, + TODRYK_GEORGE_FLAG, + TODRYK_OPINION_FLAG, + TODRYK_PHOTO_FLAG, + TODRYK_PLANTARD_FLAG, + TODRYK_ROSSO_FLAG, + TODRYK_TEXT, + ULTAR_ARTO_FLAG, + ULTAR_BALL_FLAG, + ULTAR_BULL_FLAG, + ULTAR_BUZZER_FLAG, + ULTAR_CHALICE_FLAG, + ULTAR_CLUB_FLAG, + ULTAR_DOLLARS_FLAG, + ULTAR_GOODBYE_FLAG, + ULTAR_HENDERSONS_FLAG, + ULTAR_KLAUSNER_FLAG, + ULTAR_LAB_PASS_FLAG, + ULTAR_LIFTING_KEYS_FLAG, + ULTAR_LOOM_FLAG, + ULTAR_NEJO_FLAG, + ULTAR_PHOTOGRAPH_FLAG, + ULTAR_PHRASE_FLAG, + ULTAR_PRESSURE_GAUGE_FLAG, + ULTAR_RED_NOSE_FLAG, + ULTAR_SIGN_FLAG, + ULTAR_STATUETTE_FLAG, + ULTAR_STATUETTE_PAINT_FLAG, + ULTAR_TISSUE_FLAG, + ULTAR_TEMPLAR_FLAG, + ULTAR_TAXI_FLAG, + ULTAR_TOILET_BRUSH_FLAG, + ULTAR_TOILET_CHAIN_FLAG, + ULTAR_TOILET_KEY_FLAG, + ULTAR_TOWEL_FLAG, + ULTAR_PLASTER_FLAG, + ULTAR_TEXT, + COUNTESS_56A_SUBJECT_FLAG, + COUNTESS_56A_GOODBYE_FLAG, + COUNTESS_56B_GOODBYE_FLAG, + COUNTESS_TALK_FLAG, + COUNTESS_CDT_FLAG, + VAS_BALL_FLAG, + VAS_COUNTESS_FLAG, + VAS_GOODBYE_FLAG, + VAS_KEY_FLAG, + VAS_PHOTO_FLAG, + VAS_TALK, + VAS_TEXT, + VAS_TEXT_TOGGLE, + VAS_TEMPLAR_FLAG, + VAS_CURSE_FLAG, + VAS_PCHALICE_FLAG, + GEORGE59A, + VAIL_TEXT, + VAIL_TALK_FLAG, + VAIL_CDT_FLAG, + WEASEL_CLOWN_FLAG, + WEASEL_KHAN_FLAG, + WEASEL_GUIDO_FLAG, + WEASEL_PLANTARD_FLAG, + WEASEL_ROSSO_FLAG, + WEASEL_STOP_FLAG, + WEASEL_TEXT, + WORKMAN_CLOWN_FLAG, + WORKMAN_COP_FLAG, + WORKMAN_PHONE_ALERT_FLAG, + WORKMAN_PLANTARD_FLAG, + WORKMAN_ROSSO_CARD, + WORKMAN_STOP_FLAG, + WORKMAN_TOOL_FLAG, + WORKMAN_TOOLBOX_FLAG, + WORKMAN_TEXT, + GEORGE_TALK_FLAG, + GEORGE_CDT_FLAG, + CHOOSER_COUNT_FLAG, + HURRY_FLAG, + IRELAND_FLAG, + IRELAND_MAP_FLAG, + KNOWS_PEAGRAM_FLAG, + KNOWS_PHILIP_FLAG, + MANUSCRIPT_FLAG, + OBJECT_HELD, + OBJECT_ICON, + OBJECT_TALK, + PARIS_FLAG, + RESPONSERECEIVED, + SCENE_FLAG, + SCREEN, + SCORE_FLAG, + SCOTLAND_MAP_FLAG, + SPAIN_MAP_FLAG, + SYRIA_FLAG, + TALK_FLAG, + WEIRD_ZONE, + TARGET_MEGA, + CHURCH_ARRIVAL_FLAG, + SHH_ALERT_FLAG, + AEROPORT_ADDRESS_FLAG, + CHANTELLE_BRANDY_FLAG, + CHURCH_FLAG, + CHOOSE_GAUGE_FLAG, + CLERK_AT_DESK_FLAG, + CONSULTANT_STOP_FLAG, + COSTUMES_ADDRESS_FLAG, + COSTUMES_PHONE_FLAG, + FOUND_WARD_FLAG, + GEORGE_POS_FLAG, + GOT_BENOIR_FLAG, + HOLE_FLAG, + HOSPITAL_ADDRESS_FLAG, + HOSPITAL_VISIT_FLAG, + HOS_POS_FLAG, + HOTEL_ADDRESS_FLAG, + IRELAND_ALERT_FLAG, + KEY_ALERT_FLAG, + KEYRING_FLAG, + KEY_TALK, + KNOWS_MOERLIN_FLAG, + LENS_FLAG, + MACDEVITTS_PHONE_FLAG, + MANUSCRIPT_ALERT_FLAG, + MANUSCRIPT_VIEW_FLAG, + MEETING_FLAG, + MESSAGE_FLAG, + MONTFACN_ADDRESS_FLAG, + MONTFAUCON_CONTROL_FLAG, + MUSEUM_ADDRESS_FLAG, + MUSEUM_CLOSING_FLAG, + MUSEUM_PHONE_FLAG, + NERVAL_ADDRESS_FLAG, + NICO_ADDRESS_FLAG, + NICO_APT_FLAG, + NICO_DOOR_FLAG, + NICO_GONE_HOME_FLAG, + NICO_PHONE_FLAG, + NICO_VISIT_FLAG, + NURSE_TELEPHONE_FLAG, + PAINT_TALK, + PAINTPOT_FLAG, + PARIS_STATUE_FLAG, + PHONE_CHECK, + PHONE_REQUEST, + POLICE_ADDRESS_FLAG, + POLICE_PHONE_FLAG, + POLISHER_PLUG_FLAG, + POS_FLAG, + RADIO_ALERT_FLAG, + READ_NEWSPAPER, + READ_NOSE_FLAG, + SARCOPHAGUS_ALERT_FLAG, + SC28_COIN_FLAG, + SC28_POTTERY_FLAG, + SC48_SCROLL_FLAG, + SEEN_BRIEFCASE_FLAG, + SEEN_DOOR22_FLAG, + SEEN_KEY_FLAG, + SEEN_MANHOLE_FLAG, + SEEN_PLANTARD_FLAG, + SEEN_REGISTER_FLAG, + SEEN_SEWERS_FLAG, + SEEN_TRIPOD_FLAG, + SEWER_EXIT_FLAG, + SKIP_TALK, + SOAP_FLAG, + ERIC_TEXT, + TAILOR_PHONE_FLAG, + THERMO_FLAG, + TOILET_TALK, + TOMB_FLAG, + TORCH_ALERT_FLAG, + TOTEM_ALERT_FLAG, + TRIPOD_FLAG, + TRIPOD_ALERT_FLAG, + TRIPOD_STOLEN_FLAG, + WARD_STOP_FLAG, + WHITE_COAT_FLAG, + WINDOW_ALERT_FLAG, + WORKMAN_GONE_FLAG, + CLIMBING_CART_FLAG, + FIDDLER_TEXT, + PEAGRAM_GONE_FLAG, + PINT_FLAG, + PUB_ELEC_FLAG, + PUB_INTERRUPTION_FLAG, + PUB_TAP_FLAG, + SEEN_GOAT_FLAG, + SYRIA_BOOK_FLAG, + SEEN_BRUSH_FLAG, + SEEN_STATUE_FLAG, + SYRIA_DEAD_FLAG, + SYRIA_NICHE_FLAG, + ARMOUR_HIDE_FLAG, + CANDLE59_FLAG, + CANDLE_BURNT, + CHALICE_FLAG, + CHESSET_FLAG, + CHESSBOARD_FLAG, + DOOR_REVEALED, + DOWSE_FLAG, + GEORGE_POSITION, + GEORGE_SAFE, + GEORGE_WELL_FLAG, + HAZEL_FLAG, + INTRO_FLAG, + LION_FANG, + LOGS_56_FLAG, + MARY_FLAG, + MIRROR_HINT, + ROCKFALL_1, + ROCKFALL_2, + SECOND_CURSE_FLAG, + SPAIN_CODA, + TOMBS59_FLAG, + ASSASSIN_KILLED_FLAG, + AXE_ALERT_FLAG, + DOOR_SC69_ALERT_FLAG, + DOOR_SC65_FLAG, + EKLUND_KILLED, + FINALE_OPTION_FLAG, + NICO_GONE_FLAG, + NICO_TIED_FLAG, + PIPE_ALERT_FLAG, + SEEN_GUIDO_63, + END_SCENE, + MASTER_39_TALK_FLAG, + MASTER_39_CDT_FLAG, + COLONEL_TALK_FLAG, + COLONEL_CDT_FLAG, + EXEC_TALK_FLAG, + EXEC_CDT_FLAG, + CIVIL_TALK_FLAG, + CIVIL_CDT_FLAG, + LATVIAN_39_TALK_FLAG, + LATVIAN_39_CDT_FLAG, + EKLUND_39_TALK_FLAG, + EKLUND_39_CDT_FLAG, + CAFE_BOMBED, + BLIND_ALLEY, + CAFE_INTERIOR, + ROAD_WORKS, + COURT_YARD, + SEWER_ONE, + SEWER_TWO, + CAFE_REPAIRED, + APT_STREET, + APT_NICO, + COSTUME_SHOP, + HOTEL_STREET, + HOTEL_DESK, + HOTEL_CORRIDOR, + HOTEL_EMPTY, + HOTEL_LEDGE, + HOTEL_ASSASSIN, + GENDARMERIE, + IRELAND_STREET, + MACDEVITTS, + PUB_CELLAR, + CASTLE_GATE, + CASTLE_HAY_TOP, + CASTLE_YARD, + CASTLE_DIG, + CELLAR_DARK, + MUSEUM_STREET, + MUSEUM_ONE, + MUSEUM_TWO, + MUSEUM_HIDING, + HOSPITAL_STREET, + HOSPITAL_DESK, + HOSPITAL_CORRIDOR, + HOSPITAL_WARD, + HOSPITAL_JACQUES, + MONTFAUCON, + CATACOMB_SEWER, + CATACOMB_ROOM, + CATACOMB_MEETING, + EXCAVATION_EXT, + EXCAVATION_LOBBY, + EXCAVATION_DIG, + EXCAVATION_TOILET, + EXCAVATION_SECRET, + TEMPLAR_CHURCH, + SYRIA_STALL, + SYRIA_CARPET, + SYRIA_CLUB, + SYRIA_TOILET, + BULL_CLIFF, + BULL_INTERIOR, + MAUSOLEUM_EXT, + SPAIN_DRIVE, + SPAIN_GARDEN, + MAUSOLEUM_INT, + SPAIN_RECEPTION, + SPAIN_WELL, + SPAIN_SECRET, + TRAIN_ONE, + TRAIN_TWO, + COMPT_ONE, + COMPT_TWO, + COMPT_THREE, + COMPT_FOUR, + TRAIN_GUARD, + CHURCHYARD, + CHURCH_TOWER, + CRYPT, + SECRET_CRYPT, + POCKET_1, + POCKET_2, + POCKET_3, + POCKET_4, + POCKET_5, + POCKET_6, + POCKET_7, + POCKET_8, + POCKET_9, + POCKET_10, + POCKET_11, + POCKET_12, + POCKET_13, + POCKET_14, + POCKET_15, + POCKET_16, + POCKET_17, + POCKET_18, + POCKET_19, + POCKET_20, + POCKET_21, + POCKET_22, + POCKET_23, + POCKET_24, + POCKET_25, + POCKET_26, + POCKET_27, + POCKET_28, + POCKET_29, + POCKET_30, + POCKET_31, + POCKET_32, + POCKET_33, + POCKET_34, + POCKET_35, + POCKET_36, + POCKET_37, + POCKET_38, + POCKET_39, + POCKET_40, + POCKET_41, + POCKET_42, + POCKET_43, + POCKET_44, + POCKET_45, + POCKET_46, + POCKET_47, + POCKET_48, + POCKET_49, + POCKET_50, + POCKET_51, + POCKET_52 +}; + +#define SCR_std_off (0*0x10000 + 6) +#define SCR_exit0 (0*0x10000 + 7) +#define SCR_exit1 (0*0x10000 + 8) +#define SCR_exit2 (0*0x10000 + 9) +#define SCR_exit3 (0*0x10000 + 10) +#define SCR_exit4 (0*0x10000 + 11) +#define SCR_exit5 (0*0x10000 + 12) +#define SCR_exit6 (0*0x10000 + 13) +#define SCR_exit7 (0*0x10000 + 14) +#define SCR_exit8 (0*0x10000 + 15) +#define SCR_exit9 (0*0x10000 + 16) +#define LEFT_SCROLL_POINTER 8388610 +#define RIGHT_SCROLL_POINTER 8388611 +#define FLOOR_63 4128768 +#define ROOF_63 4128779 +#define GUARD_ROOF_63 4128781 +#define LEFT_TREE_POINTER_71 4653058 +#define RIGHT_TREE_POINTER_71 4653059 + + +#endif //SWORDDEFS_H \ No newline at end of file diff --git a/sword1/swordres.h b/sword1/swordres.h new file mode 100644 index 0000000000..a1a9edb9e2 --- /dev/null +++ b/sword1/swordres.h @@ -0,0 +1,5216 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#ifndef SWORDRES_H +#define SWORDRES_H + +// scripts + // standard +#define SCRIPT0 0x01000000 + // 1 entities in TXTs, 1 in datafiles. + // megas +#define SCRIPT128 0x01010000 +#define SCRIPT129 0x01010001 +#define SCRIPT130 0x01010002 +#define SCRIPT131 0x01010003 +#define SCRIPT133 0x01010004 +#define SCRIPT134 0x01010005 +#define SCRIPT145 0x01010006 +#define SCRIPT146 0x01010007 + // 8 entities in TXTs, 8 in datafiles. + // maps +#define SCRIPT80 0x01020000 +#define SCRIPT86 0x01020001 +#define SCRIPT90 0x01020002 + // 3 entities in TXTs, 3 in datafiles. + // paris1 +#define SCRIPT1 0x01030000 +#define SCRIPT2 0x01030001 +#define SCRIPT3 0x01030002 +#define SCRIPT4 0x01030003 +#define SCRIPT5 0x01030004 +#define SCRIPT6 0x01030005 +#define SCRIPT7 0x01030006 +#define SCRIPT8 0x01030007 + // 8 entities in TXTs, 8 in datafiles. + // paris2 +#define SCRIPT9 0x01040000 +#define SCRIPT10 0x01040001 +#define SCRIPT11 0x01040002 +#define SCRIPT12 0x01040003 +#define SCRIPT13 0x01040004 +#define SCRIPT14 0x01040005 +#define SCRIPT15 0x01040006 +#define SCRIPT16 0x01040007 +#define SCRIPT17 0x01040008 +#define SCRIPT18 0x01040009 +#define SCRIPT46 0x0104000A + // 11 entities in TXTs, 11 in datafiles. + // paris3 +#define SCRIPT27 0x01050000 +#define SCRIPT28 0x01050001 +#define SCRIPT29 0x01050002 +#define SCRIPT31 0x01050003 +#define SCRIPT32 0x01050004 +#define SCRIPT33 0x01050005 +#define SCRIPT34 0x01050006 +#define SCRIPT35 0x01050007 + // 8 entities in TXTs, 8 in datafiles. + // paris4 +#define SCRIPT36 0x01060000 +#define SCRIPT37 0x01060001 +#define SCRIPT38 0x01060002 +#define SCRIPT39 0x01060003 +#define SCRIPT40 0x01060004 +#define SCRIPT41 0x01060005 +#define SCRIPT42 0x01060006 +#define SCRIPT43 0x01060007 +#define SCRIPT48 0x01060008 + // 9 entities in TXTs, 9 in datafiles. + // ireland +#define SCRIPT19 0x01070000 +#define SCRIPT20 0x01070001 +#define SCRIPT21 0x01070002 +#define SCRIPT22 0x01070003 +#define SCRIPT23 0x01070004 +#define SCRIPT24 0x01070005 +#define SCRIPT25 0x01070006 +#define SCRIPT26 0x01070007 + // 8 entities in TXTs, 8 in datafiles. + // spain +#define SCRIPT56 0x01080000 +#define SCRIPT57 0x01080001 +#define SCRIPT58 0x01080002 +#define SCRIPT59 0x01080003 +#define SCRIPT60 0x01080004 +#define SCRIPT61 0x01080005 +#define SCRIPT62 0x01080006 + // 7 entities in TXTs, 7 in datafiles. + // syria +#define SCRIPT45 0x01090000 +#define SCRIPT47 0x01090001 +#define SCRIPT49 0x01090002 +#define SCRIPT50 0x01090003 +#define SCRIPT54 0x01090004 +#define SCRIPT55 0x01090005 + // 6 entities in TXTs, 6 in datafiles. + // train +#define SCRIPT63 0x010A0000 +#define SCRIPT65 0x010A0001 +#define SCRIPT66 0x010A0002 +#define SCRIPT67 0x010A0003 +#define SCRIPT69 0x010A0004 + // 5 entities in TXTs, 5 in datafiles. + // scotland +#define SCRIPT71 0x010B0000 +#define SCRIPT72 0x010B0001 +#define SCRIPT73 0x010B0002 +#define SCRIPT74 0x010B0003 + // 4 entities in TXTs, 4 in datafiles. +// compacts + // standard +#define TEXT_OBS 0x02000000 + // 1 entities in TXTs, 1 in datafiles. + // megas +#define MEGA_GEO 0x02010000 +#define GEO_TLK_TABLE 0x02010001 +#define WHT_TLK_TABLE 0x02010002 +#define GEO_SHRUG_TABLE 0x02010003 +#define GEO_GIVE_TABLE 0x02010004 +#define GEO_GIVER_TABLE 0x02010005 +#define GEO_CROUCH_TABLE 0x02010006 +#define GEO_CROUCHR_TABLE 0x02010007 +#define GEO_PICKUP_TABLE 0x02010008 +#define GEO_RELAX_TABLE 0x02010009 +#define GEO_RELAXR_TABLE 0x0201000A +#define GEO_HAIR_TABLE 0x0201000B +#define GEO_BLINK_TABLE 0x0201000C +#define GEOPHN_TABLE 0x0201000D +#define GEO_GAUGE_TABLE 0x0201000E +#define GEO_SHOW_TABLE 0x0201000F +#define GEO_SHOWR_TABLE 0x02010010 +#define GEOSTA_TABLE 0x02010011 +#define GEOMON_TABLE 0x02010012 +#define MEGA_DUANE 0x02010013 +#define DUA5_TABLE 0x02010014 +#define DUA6_TABLE 0x02010015 +#define DUA7_TABLE 0x02010016 +#define DUA8_TABLE 0x02010017 +#define DUA9_TABLE 0x02010018 +#define MEGA_NICO 0x02010019 +#define NIC_TLK_TABLE 0x0201001A +#define NIC_PHOTO_TABLE 0x0201001B +#define NICPHN_TABLE 0x0201001C +#define MEGA_MUS 0x0201001D +#define MUS_TLK_TABLE 0x0201001E +#define MEGA_BENOIR 0x0201001F +#define BEN_GAUGE_TABLE 0x02010020 +#define BEN_TLK_TABLE 0x02010021 +#define MEGA_ROSSO 0x02010022 +#define MEGA_MOUE 0x02010023 +#define MEGA_ALBERT 0x02010024 + // 37 entities in TXTs, 37 in datafiles. + // maps +#define COMP80 0x02020000 +#define COMP86 0x02020001 +#define COMP90 0x02020002 +#define COMP91 0x02020003 +#define COMP99 0x02020004 + // 5 entities in TXTs, 5 in datafiles. + // paris1 +#define COMP1 0x02030000 +#define COMP2 0x02030001 +#define COMP3 0x02030002 +#define COMP4 0x02030003 +#define COMP5 0x02030004 +#define COMP6 0x02030005 +#define COMP7 0x02030006 +#define COMP8 0x02030007 + // 8 entities in TXTs, 8 in datafiles. + // paris2 +#define COMP9 0x02040000 +#define COMP10 0x02040001 +#define COMP11 0x02040002 +#define COMP12 0x02040003 +#define COMP13 0x02040004 +#define COMP14 0x02040005 +#define COMP15 0x02040006 +#define COMP16 0x02040007 +#define COMP17 0x02040008 +#define COMP18 0x02040009 +#define COMP81 0x0204000A +#define COMP46 0x0204000B + // 12 entities in TXTs, 12 in datafiles. + // paris3 +#define COMP27 0x02050000 +#define COMP28 0x02050001 +#define COMP29 0x02050002 +#define COMP30 0x02050003 +#define COMP31 0x02050004 +#define COMP32 0x02050005 +#define COMP33 0x02050006 +#define COMP34 0x02050007 +#define COMP35 0x02050008 + // 9 entities in TXTs, 9 in datafiles. + // paris4 +#define COMP36 0x02060000 +#define COMP37 0x02060001 +#define COMP38 0x02060002 +#define COMP39 0x02060003 +#define COMP40 0x02060004 +#define COMP41 0x02060005 +#define COMP42 0x02060006 +#define COMP43 0x02060007 +#define COMP48 0x02060008 + // 9 entities in TXTs, 9 in datafiles. + // ireland +#define COMP19 0x02070000 +#define COMP20 0x02070001 +#define COMP21 0x02070002 +#define COMP22 0x02070003 +#define COMP23 0x02070004 +#define COMP24 0x02070005 +#define COMP25 0x02070006 +#define COMP26 0x02070007 + // 8 entities in TXTs, 8 in datafiles. + // spain +#define COMP56 0x02080000 +#define COMP57 0x02080001 +#define COMP58 0x02080002 +#define COMP59 0x02080003 +#define COMP60 0x02080004 +#define COMP61 0x02080005 +#define COMP62 0x02080006 + // 7 entities in TXTs, 7 in datafiles. + // syria +#define COMP45 0x02090000 +#define COMP47 0x02090001 +#define COMP49 0x02090002 +#define COMP50 0x02090003 +#define COMP53 0x02090004 +#define COMP54 0x02090005 +#define COMP55 0x02090006 + // 7 entities in TXTs, 7 in datafiles. + // train +#define COMP63 0x020A0000 +#define COMP65 0x020A0001 +#define COMP66 0x020A0002 +#define COMP67 0x020A0003 +#define COMP69 0x020A0004 + // 5 entities in TXTs, 5 in datafiles. + // scotland +#define COMP71 0x020B0000 +#define COMP72 0x020B0001 +#define COMP73 0x020B0002 +#define COMP74 0x020B0003 +#define COMP75 0x020B0004 +#define COMP76 0x020B0005 +#define COMP77 0x020B0006 +#define COMP78 0x020B0007 +#define COMP79 0x020B0008 + // 9 entities in TXTs, 9 in datafiles. +// text + // english +#define ENGLISH0 0x03000000 +#define ENGLISH1 0x03000001 +#define ENGLISH2 0x03000002 +#define ENGLISH3 0x03000003 +#define ENGLISH4 0x03000004 +#define ENGLISH5 0x03000005 +#define ENGLISH6 0x03000006 +#define ENGLISH7 0x03000007 +#define ENGLISH9 0x03000008 +#define ENGLISH11 0x03000009 +#define ENGLISH12 0x0300000A +#define ENGLISH13 0x0300000B +#define ENGLISH14 0x0300000C +#define ENGLISH15 0x0300000D +#define ENGLISH16 0x0300000E +#define ENGLISH17 0x0300000F +#define ENGLISH18 0x03000010 +#define ENGLISH19 0x03000011 +#define ENGLISH20 0x03000012 +#define ENGLISH21 0x03000013 +#define ENGLISH22 0x03000014 +#define ENGLISH23 0x03000015 +#define ENGLISH24 0x03000016 +#define ENGLISH25 0x03000017 +#define ENGLISH27 0x03000018 +#define ENGLISH28 0x03000019 +#define ENGLISH29 0x0300001A +#define ENGLISH31 0x0300001B +#define ENGLISH32 0x0300001C +#define ENGLISH33 0x0300001D +#define ENGLISH34 0x0300001E +#define ENGLISH35 0x0300001F +#define ENGLISH36 0x03000020 +#define ENGLISH37 0x03000021 +#define ENGLISH38 0x03000022 +#define ENGLISH39 0x03000023 +#define ENGLISH40 0x03000024 +#define ENGLISH41 0x03000025 +#define ENGLISH42 0x03000026 +#define ENGLISH43 0x03000027 +#define ENGLISH45 0x03000028 +#define ENGLISH47 0x03000029 +#define ENGLISH48 0x0300002A +#define ENGLISH49 0x0300002B +#define ENGLISH50 0x0300002C +#define ENGLISH54 0x0300002D +#define ENGLISH55 0x0300002E +#define ENGLISH56 0x0300002F +#define ENGLISH57 0x03000030 +#define ENGLISH58 0x03000031 +#define ENGLISH59 0x03000032 +#define ENGLISH60 0x03000033 +#define ENGLISH61 0x03000034 +#define ENGLISH63 0x03000035 +#define ENGLISH65 0x03000036 +#define ENGLISH66 0x03000037 +#define ENGLISH69 0x03000038 +#define ENGLISH71 0x03000039 +#define ENGLISH72 0x0300003A +#define ENGLISH73 0x0300003B +#define ENGLISH74 0x0300003C +#define ENGLISH90 0x0300003D +#define ENGLISH99 0x0300003E +#define ENGLISH129 0x0300003F +#define ENGLISH131 0x03000040 +#define ENGLISH133 0x03000041 +#define ENGLISH145 0x03000042 +#define ENGLISH146 0x03000043 + // 68 entities in TXTs, 68 in datafiles. + // french +#define FRENCH0 0x03010000 +#define FRENCH1 0x03010001 +#define FRENCH2 0x03010002 +#define FRENCH3 0x03010003 +#define FRENCH4 0x03010004 +#define FRENCH5 0x03010005 +#define FRENCH6 0x03010006 +#define FRENCH7 0x03010007 +#define FRENCH9 0x03010008 +#define FRENCH11 0x03010009 +#define FRENCH12 0x0301000A +#define FRENCH13 0x0301000B +#define FRENCH14 0x0301000C +#define FRENCH15 0x0301000D +#define FRENCH16 0x0301000E +#define FRENCH17 0x0301000F +#define FRENCH18 0x03010010 +#define FRENCH19 0x03010011 +#define FRENCH20 0x03010012 +#define FRENCH21 0x03010013 +#define FRENCH22 0x03010014 +#define FRENCH23 0x03010015 +#define FRENCH24 0x03010016 +#define FRENCH25 0x03010017 +#define FRENCH27 0x03010018 +#define FRENCH28 0x03010019 +#define FRENCH29 0x0301001A +#define FRENCH31 0x0301001B +#define FRENCH32 0x0301001C +#define FRENCH33 0x0301001D +#define FRENCH34 0x0301001E +#define FRENCH35 0x0301001F +#define FRENCH36 0x03010020 +#define FRENCH37 0x03010021 +#define FRENCH38 0x03010022 +#define FRENCH39 0x03010023 +#define FRENCH40 0x03010024 +#define FRENCH41 0x03010025 +#define FRENCH42 0x03010026 +#define FRENCH43 0x03010027 +#define FRENCH45 0x03010028 +#define FRENCH47 0x03010029 +#define FRENCH48 0x0301002A +#define FRENCH49 0x0301002B +#define FRENCH50 0x0301002C +#define FRENCH54 0x0301002D +#define FRENCH55 0x0301002E +#define FRENCH56 0x0301002F +#define FRENCH57 0x03010030 +#define FRENCH58 0x03010031 +#define FRENCH59 0x03010032 +#define FRENCH60 0x03010033 +#define FRENCH61 0x03010034 +#define FRENCH63 0x03010035 +#define FRENCH65 0x03010036 +#define FRENCH66 0x03010037 +#define FRENCH69 0x03010038 +#define FRENCH71 0x03010039 +#define FRENCH72 0x0301003A +#define FRENCH73 0x0301003B +#define FRENCH74 0x0301003C +#define FRENCH90 0x0301003D +#define FRENCH99 0x0301003E +#define FRENCH129 0x0301003F +#define FRENCH131 0x03010040 +#define FRENCH133 0x03010041 +#define FRENCH145 0x03010042 +#define FRENCH146 0x03010043 + // 68 entities in TXTs, 68 in datafiles. + // german +#define GERMAN0 0x03020000 +#define GERMAN1 0x03020001 +#define GERMAN2 0x03020002 +#define GERMAN3 0x03020003 +#define GERMAN4 0x03020004 +#define GERMAN5 0x03020005 +#define GERMAN6 0x03020006 +#define GERMAN7 0x03020007 +#define GERMAN9 0x03020008 +#define GERMAN11 0x03020009 +#define GERMAN12 0x0302000A +#define GERMAN13 0x0302000B +#define GERMAN14 0x0302000C +#define GERMAN15 0x0302000D +#define GERMAN16 0x0302000E +#define GERMAN17 0x0302000F +#define GERMAN18 0x03020010 +#define GERMAN19 0x03020011 +#define GERMAN20 0x03020012 +#define GERMAN21 0x03020013 +#define GERMAN22 0x03020014 +#define GERMAN23 0x03020015 +#define GERMAN24 0x03020016 +#define GERMAN25 0x03020017 +#define GERMAN27 0x03020018 +#define GERMAN28 0x03020019 +#define GERMAN29 0x0302001A +#define GERMAN31 0x0302001B +#define GERMAN32 0x0302001C +#define GERMAN33 0x0302001D +#define GERMAN34 0x0302001E +#define GERMAN35 0x0302001F +#define GERMAN36 0x03020020 +#define GERMAN37 0x03020021 +#define GERMAN38 0x03020022 +#define GERMAN39 0x03020023 +#define GERMAN40 0x03020024 +#define GERMAN41 0x03020025 +#define GERMAN42 0x03020026 +#define GERMAN43 0x03020027 +#define GERMAN45 0x03020028 +#define GERMAN47 0x03020029 +#define GERMAN48 0x0302002A +#define GERMAN49 0x0302002B +#define GERMAN50 0x0302002C +#define GERMAN54 0x0302002D +#define GERMAN55 0x0302002E +#define GERMAN56 0x0302002F +#define GERMAN57 0x03020030 +#define GERMAN58 0x03020031 +#define GERMAN59 0x03020032 +#define GERMAN60 0x03020033 +#define GERMAN61 0x03020034 +#define GERMAN63 0x03020035 +#define GERMAN65 0x03020036 +#define GERMAN66 0x03020037 +#define GERMAN69 0x03020038 +#define GERMAN71 0x03020039 +#define GERMAN72 0x0302003A +#define GERMAN73 0x0302003B +#define GERMAN74 0x0302003C +#define GERMAN90 0x0302003D +#define GERMAN99 0x0302003E +#define GERMAN129 0x0302003F +#define GERMAN131 0x03020040 +#define GERMAN133 0x03020041 +#define GERMAN145 0x03020042 +#define GERMAN146 0x03020043 + // 68 entities in TXTs, 68 in datafiles. + // italian +#define ITALIAN0 0x03030000 +#define ITALIAN1 0x03030001 +#define ITALIAN2 0x03030002 +#define ITALIAN3 0x03030003 +#define ITALIAN4 0x03030004 +#define ITALIAN5 0x03030005 +#define ITALIAN6 0x03030006 +#define ITALIAN7 0x03030007 +#define ITALIAN9 0x03030008 +#define ITALIAN11 0x03030009 +#define ITALIAN12 0x0303000A +#define ITALIAN13 0x0303000B +#define ITALIAN14 0x0303000C +#define ITALIAN15 0x0303000D +#define ITALIAN16 0x0303000E +#define ITALIAN17 0x0303000F +#define ITALIAN18 0x03030010 +#define ITALIAN19 0x03030011 +#define ITALIAN20 0x03030012 +#define ITALIAN21 0x03030013 +#define ITALIAN22 0x03030014 +#define ITALIAN23 0x03030015 +#define ITALIAN24 0x03030016 +#define ITALIAN25 0x03030017 +#define ITALIAN27 0x03030018 +#define ITALIAN28 0x03030019 +#define ITALIAN29 0x0303001A +#define ITALIAN31 0x0303001B +#define ITALIAN32 0x0303001C +#define ITALIAN33 0x0303001D +#define ITALIAN34 0x0303001E +#define ITALIAN35 0x0303001F +#define ITALIAN36 0x03030020 +#define ITALIAN37 0x03030021 +#define ITALIAN38 0x03030022 +#define ITALIAN39 0x03030023 +#define ITALIAN40 0x03030024 +#define ITALIAN41 0x03030025 +#define ITALIAN42 0x03030026 +#define ITALIAN43 0x03030027 +#define ITALIAN45 0x03030028 +#define ITALIAN47 0x03030029 +#define ITALIAN48 0x0303002A +#define ITALIAN49 0x0303002B +#define ITALIAN50 0x0303002C +#define ITALIAN54 0x0303002D +#define ITALIAN55 0x0303002E +#define ITALIAN56 0x0303002F +#define ITALIAN57 0x03030030 +#define ITALIAN58 0x03030031 +#define ITALIAN59 0x03030032 +#define ITALIAN60 0x03030033 +#define ITALIAN61 0x03030034 +#define ITALIAN63 0x03030035 +#define ITALIAN65 0x03030036 +#define ITALIAN66 0x03030037 +#define ITALIAN69 0x03030038 +#define ITALIAN71 0x03030039 +#define ITALIAN72 0x0303003A +#define ITALIAN73 0x0303003B +#define ITALIAN74 0x0303003C +#define ITALIAN90 0x0303003D +#define ITALIAN99 0x0303003E +#define ITALIAN129 0x0303003F +#define ITALIAN131 0x03030040 +#define ITALIAN133 0x03030041 +#define ITALIAN145 0x03030042 +#define ITALIAN146 0x03030043 + // 68 entities in TXTs, 68 in datafiles. + // spanish +#define SPANISH0 0x03040000 +#define SPANISH1 0x03040001 +#define SPANISH2 0x03040002 +#define SPANISH3 0x03040003 +#define SPANISH4 0x03040004 +#define SPANISH5 0x03040005 +#define SPANISH6 0x03040006 +#define SPANISH7 0x03040007 +#define SPANISH9 0x03040008 +#define SPANISH11 0x03040009 +#define SPANISH12 0x0304000A +#define SPANISH13 0x0304000B +#define SPANISH14 0x0304000C +#define SPANISH15 0x0304000D +#define SPANISH16 0x0304000E +#define SPANISH17 0x0304000F +#define SPANISH18 0x03040010 +#define SPANISH19 0x03040011 +#define SPANISH20 0x03040012 +#define SPANISH21 0x03040013 +#define SPANISH22 0x03040014 +#define SPANISH23 0x03040015 +#define SPANISH24 0x03040016 +#define SPANISH25 0x03040017 +#define SPANISH27 0x03040018 +#define SPANISH28 0x03040019 +#define SPANISH29 0x0304001A +#define SPANISH31 0x0304001B +#define SPANISH32 0x0304001C +#define SPANISH33 0x0304001D +#define SPANISH34 0x0304001E +#define SPANISH35 0x0304001F +#define SPANISH36 0x03040020 +#define SPANISH37 0x03040021 +#define SPANISH38 0x03040022 +#define SPANISH39 0x03040023 +#define SPANISH40 0x03040024 +#define SPANISH41 0x03040025 +#define SPANISH42 0x03040026 +#define SPANISH43 0x03040027 +#define SPANISH45 0x03040028 +#define SPANISH47 0x03040029 +#define SPANISH48 0x0304002A +#define SPANISH49 0x0304002B +#define SPANISH50 0x0304002C +#define SPANISH54 0x0304002D +#define SPANISH55 0x0304002E +#define SPANISH56 0x0304002F +#define SPANISH57 0x03040030 +#define SPANISH58 0x03040031 +#define SPANISH59 0x03040032 +#define SPANISH60 0x03040033 +#define SPANISH61 0x03040034 +#define SPANISH63 0x03040035 +#define SPANISH65 0x03040036 +#define SPANISH66 0x03040037 +#define SPANISH69 0x03040038 +#define SPANISH71 0x03040039 +#define SPANISH72 0x0304003A +#define SPANISH73 0x0304003B +#define SPANISH74 0x0304003C +#define SPANISH90 0x0304003D +#define SPANISH99 0x0304003E +#define SPANISH129 0x0304003F +#define SPANISH131 0x03040040 +#define SPANISH133 0x03040041 +#define SPANISH145 0x03040042 +#define SPANISH146 0x03040043 + // 68 entities in TXTs, 68 in datafiles. + // czech +#define CZECH0 0x03050000 +#define CZECH1 0x03050001 +#define CZECH2 0x03050002 +#define CZECH3 0x03050003 +#define CZECH4 0x03050004 +#define CZECH5 0x03050005 +#define CZECH6 0x03050006 +#define CZECH7 0x03050007 +#define CZECH9 0x03050008 +#define CZECH11 0x03050009 +#define CZECH12 0x0305000A +#define CZECH13 0x0305000B +#define CZECH14 0x0305000C +#define CZECH15 0x0305000D +#define CZECH16 0x0305000E +#define CZECH17 0x0305000F +#define CZECH18 0x03050010 +#define CZECH19 0x03050011 +#define CZECH20 0x03050012 +#define CZECH21 0x03050013 +#define CZECH22 0x03050014 +#define CZECH23 0x03050015 +#define CZECH24 0x03050016 +#define CZECH25 0x03050017 +#define CZECH27 0x03050018 +#define CZECH28 0x03050019 +#define CZECH29 0x0305001A +#define CZECH31 0x0305001B +#define CZECH32 0x0305001C +#define CZECH33 0x0305001D +#define CZECH34 0x0305001E +#define CZECH35 0x0305001F +#define CZECH36 0x03050020 +#define CZECH37 0x03050021 +#define CZECH38 0x03050022 +#define CZECH39 0x03050023 +#define CZECH40 0x03050024 +#define CZECH41 0x03050025 +#define CZECH42 0x03050026 +#define CZECH43 0x03050027 +#define CZECH45 0x03050028 +#define CZECH47 0x03050029 +#define CZECH48 0x0305002A +#define CZECH49 0x0305002B +#define CZECH50 0x0305002C +#define CZECH54 0x0305002D +#define CZECH55 0x0305002E +#define CZECH56 0x0305002F +#define CZECH57 0x03050030 +#define CZECH58 0x03050031 +#define CZECH59 0x03050032 +#define CZECH60 0x03050033 +#define CZECH61 0x03050034 +#define CZECH63 0x03050035 +#define CZECH65 0x03050036 +#define CZECH66 0x03050037 +#define CZECH69 0x03050038 +#define CZECH71 0x03050039 +#define CZECH72 0x0305003A +#define CZECH73 0x0305003B +#define CZECH74 0x0305003C +#define CZECH90 0x0305003D +#define CZECH99 0x0305003E +#define CZECH129 0x0305003F +#define CZECH131 0x03050040 +#define CZECH133 0x03050041 +#define CZECH145 0x03050042 +#define CZECH146 0x03050043 + // 68 entities in TXTs, ??? in datafiles. + // portugese +#define PORT0 0x03060000 +#define PORT1 0x03060001 +#define PORT2 0x03060002 +#define PORT3 0x03060003 +#define PORT4 0x03060004 +#define PORT5 0x03060005 +#define PORT6 0x03060006 +#define PORT7 0x03060007 +#define PORT9 0x03060008 +#define PORT11 0x03060009 +#define PORT12 0x0306000A +#define PORT13 0x0306000B +#define PORT14 0x0306000C +#define PORT15 0x0306000D +#define PORT16 0x0306000E +#define PORT17 0x0306000F +#define PORT18 0x03060010 +#define PORT19 0x03060011 +#define PORT20 0x03060012 +#define PORT21 0x03060013 +#define PORT22 0x03060014 +#define PORT23 0x03060015 +#define PORT24 0x03060016 +#define PORT25 0x03060017 +#define PORT27 0x03060018 +#define PORT28 0x03060019 +#define PORT29 0x0306001A +#define PORT31 0x0306001B +#define PORT32 0x0306001C +#define PORT33 0x0306001D +#define PORT34 0x0306001E +#define PORT35 0x0306001F +#define PORT36 0x03060020 +#define PORT37 0x03060021 +#define PORT38 0x03060022 +#define PORT39 0x03060023 +#define PORT40 0x03060024 +#define PORT41 0x03060025 +#define PORT42 0x03060026 +#define PORT43 0x03060027 +#define PORT45 0x03060028 +#define PORT47 0x03060029 +#define PORT48 0x0306002A +#define PORT49 0x0306002B +#define PORT50 0x0306002C +#define PORT54 0x0306002D +#define PORT55 0x0306002E +#define PORT56 0x0306002F +#define PORT57 0x03060030 +#define PORT58 0x03060031 +#define PORT59 0x03060032 +#define PORT60 0x03060033 +#define PORT61 0x03060034 +#define PORT63 0x03060035 +#define PORT65 0x03060036 +#define PORT66 0x03060037 +#define PORT69 0x03060038 +#define PORT71 0x03060039 +#define PORT72 0x0306003A +#define PORT73 0x0306003B +#define PORT74 0x0306003C +#define PORT90 0x0306003D +#define PORT99 0x0306003E +#define PORT129 0x0306003F +#define PORT131 0x03060040 +#define PORT133 0x03060041 +#define PORT145 0x03060042 +#define PORT146 0x03060043 + // 68 entities in TXTs, ??? in datafiles. +// general + // fonts +#define GAME_FONT 0x04000000 +#define SR_FONT 0x04000001 +#define SR_REDFONT 0x04000002 +#define SR_DEATHFONT 0x04000003 +#define CZECH_GAME_FONT 0x04000004 +#define CZECH_SR_FONT 0x04000005 +#define CZECH_SR_REDFONT 0x04000006 +#define CZECH_SR_DEATHFONT 0x04000007 + // 8 entities in TXTs, 1 in datafiles. + // pointers +#define MSE_POINTER 0x04010000 +#define MSE_OPERATE 0x04010001 +#define MSE_PICKUP 0x04010002 +#define MSE_EXAMINE 0x04010003 +#define MSE_MOUTH 0x04010004 +#define MSE_BECKON_L 0x04010005 +#define MSE_BECKON_R 0x04010006 +#define MSE_ARROW0 0x04010007 +#define MSE_ARROW1 0x04010008 +#define MSE_ARROW2 0x04010009 +#define MSE_ARROW3 0x0401000A +#define MSE_ARROW4 0x0401000B +#define MSE_ARROW5 0x0401000C +#define MSE_ARROW6 0x0401000D +#define MSE_ARROW7 0x0401000E +#define MSE_ARROW8 0x0401000F +#define MSE_ARROW9 0x04010010 + // 17 entities in TXTs, 17 in datafiles. + // luggage +#define LUGG_NEWSPAPER 0x04020000 +#define LUGG_HAZEL_WAND 0x04020001 +#define LUGG_BEER_TOWEL 0x04020002 +#define LUGG_HOTEL_KEY 0x04020003 +#define LUGG_BALL 0x04020004 +#define LUGG_STATUETTE 0x04020005 +#define LUGG_RED_NOSE 0x04020006 +#define LUGG_POLISHED_CHALICE 0x04020007 +#define LUGG_DOLLAR_BILL 0x04020008 +#define LUGG_PHOTOGRAPH 0x04020009 +#define LUGG_FLASHLIGHT 0x0402000A +#define LUGG_FUSE_WIRE 0x0402000B +#define LUGG_GEM 0x0402000C +#define LUGG_STATUETTE_PAINT 0x0402000D +#define LUGG_STICK 0x0402000E +#define LUGG_EXCAV_KEY 0x0402000F +#define LUGG_LAB_PASS 0x04020010 +#define LUGG_LIFTING_KEYS 0x04020011 +#define LUGG_MANUSCRIPT 0x04020012 +#define LUGG_MATCHBOOK 0x04020013 +#define LUGG_SUIT_MATERIAL 0x04020014 +#define LUGG_STICK_TOWEL 0x04020015 +#define LUGG_PLASTER 0x04020016 +#define LUGG_PRESSURE_GAUGE 0x04020017 +#define LUGG_RAILWAY_TICKET 0x04020018 +#define LUGG_BUZZER 0x04020019 +#define LUGG_ROSSO_CARD 0x0402001A +#define LUGG_TOILET_KEY 0x0402001B +#define LUGG_SOAP 0x0402001C +#define LUGG_STONE_KEY 0x0402001D +#define LUGG_CHALICE 0x0402001E +#define LUGG_TISSUE 0x0402001F +#define LUGG_TOILET_BRUSH 0x04020020 +#define LUGG_TOILET_CHAIN 0x04020021 +#define LUGG_TOWEL 0x04020022 +#define LUGG_TRIPOD 0x04020023 +#define LUGG_LENS 0x04020024 +#define LUGG_MIRROR 0x04020025 +#define LUGG_TOWEL_CUT 0x04020026 +#define LUGG_BIBLE 0x04020027 +#define LUGG_TISSUE_CHARRED 0x04020028 +#define LUGG_FALSE_KEY 0x04020029 +#define LUGG_KEYRING 0x0402002A +#define LUGG_SOAP_IMP 0x0402002B +#define LUGG_SOAP_PLAS 0x0402002C +#define LUGG_COG_1 0x0402002D +#define LUGG_COG_2 0x0402002E +#define LUGG_HANDLE 0x0402002F +#define LUGG_COIN 0x04020030 +#define LUGG_BIRO 0x04020031 +#define LUGG_PIPE 0x04020032 +#define LUGG_KING 0x04020033 +#define LUGG_KNIGHT 0x04020034 +#define LUGG_BISHOP 0x04020035 + // 54 entities in TXTs, 54 in datafiles. + // object_icons +#define ICON_LEFT_ARROW 0x04030000 +#define ICON_RIGHT_ARROW 0x04030001 +#define ICON_NEWSPAPER 0x04030002 +#define ICON_HAZEL_WAND 0x04030003 +#define ICON_BEER_TOWEL 0x04030004 +#define ICON_HOTEL_KEY 0x04030005 +#define ICON_BALL 0x04030006 +#define ICON_STATUETTE 0x04030007 +#define ICON_RED_NOSE 0x04030008 +#define ICON_POLISHED_CHALICE 0x04030009 +#define ICON_DOLLAR_BILL 0x0403000A +#define ICON_PHOTOGRAPH 0x0403000B +#define ICON_FLASHLIGHT 0x0403000C +#define ICON_FUSE_WIRE 0x0403000D +#define ICON_GEM 0x0403000E +#define ICON_STATUETTE_PAINT 0x0403000F +#define ICON_STICK 0x04030010 +#define ICON_EXCAV_KEY 0x04030011 +#define ICON_LAB_PASS 0x04030012 +#define ICON_LIFTING_KEYS 0x04030013 +#define ICON_MANUSCRIPT 0x04030014 +#define ICON_MATCHBOOK 0x04030015 +#define ICON_SUIT_MATERIAL 0x04030016 +#define ICON_STICK_TOWEL 0x04030017 +#define ICON_PLASTER 0x04030018 +#define ICON_PRESSURE_GAUGE 0x04030019 +#define ICON_RAILWAY_TICKET 0x0403001A +#define ICON_BUZZER 0x0403001B +#define ICON_ROSSO_CARD 0x0403001C +#define ICON_TOILET_KEY 0x0403001D +#define ICON_SOAP 0x0403001E +#define ICON_STONE_KEY 0x0403001F +#define ICON_CHALICE 0x04030020 +#define ICON_TISSUE 0x04030021 +#define ICON_TOILET_BRUSH 0x04030022 +#define ICON_TOILET_CHAIN 0x04030023 +#define ICON_TOWEL 0x04030024 +#define ICON_TRIPOD 0x04030025 +#define ICON_LENS 0x04030026 +#define ICON_MIRROR 0x04030027 +#define ICON_TOWEL_CUT 0x04030028 +#define ICON_BIBLE 0x04030029 +#define ICON_TISSUE_CHARRED 0x0403002A +#define ICON_FALSE_KEY 0x0403002B +#define ICON_KEYRING 0x0403002C +#define ICON_SOAP_IMP 0x0403002D +#define ICON_SOAP_PLAS 0x0403002E +#define ICON_COG_1 0x0403002F +#define ICON_COG_2 0x04030030 +#define ICON_HANDLE 0x04030031 +#define ICON_COIN 0x04030032 +#define ICON_BIRO 0x04030033 +#define ICON_PIPE 0x04030034 + // 53 entities in TXTs, 53 in datafiles. + // subject_icons +#define ICON_ALARM 0x04040000 +#define ICON_ARTO 0x04040001 +#define ICON_ASSASSIN 0x04040002 +#define ICON_AYUB 0x04040003 +#define ICON_BANANA 0x04040004 +#define ICON_BAPHOMET 0x04040005 +#define ICON_BEER 0x04040006 +#define ICON_BOOK 0x04040007 +#define ICON_BRIEFCASE 0x04040008 +#define ICON_BULL 0x04040009 +#define ICON_BULLS_HEAD 0x0404000A +#define ICON_BUST 0x0404000B +#define ICON_CANDLE 0x0404000C +#define ICON_CAR 0x0404000D +#define ICON_CASTLE 0x0404000E +#define ICON_CAT 0x0404000F +#define ICON_CHANTELLE 0x04040010 +#define ICON_CHESSBOARD 0x04040011 +#define ICON_CHESS_SET 0x04040012 +#define ICON_CHURCH 0x04040013 +#define ICON_CLOWN 0x04040014 +#define ICON_CLUB 0x04040015 +#define ICON_COINS 0x04040016 +#define ICON_COUNTESS 0x04040017 +#define ICON_CREST 0x04040018 +#define ICON_DIG 0x04040019 +#define ICON_DOG 0x0404001A +#define ICON_DUANE 0x0404001B +#define ICON_EKLUND 0x0404001C +#define ICON_ERIC 0x0404001D +#define ICON_FISH 0x0404001E +#define ICON_FLOWERS 0x0404001F +#define ICON_FORTUNE 0x04040020 +#define ICON_GEORGE 0x04040021 +#define ICON_GHOST 0x04040022 +#define ICON_GLASS_EYE 0x04040023 +#define ICON_GOAT 0x04040024 +#define ICON_GOODBYE 0x04040025 +#define ICON_GUARD 0x04040026 +#define ICON_HASH 0x04040027 +#define ICON_HENDERSONS 0x04040028 +#define ICON_JACKET 0x04040029 +#define ICON_JUGGLER 0x0404002A +#define ICON_KLAUSNER 0x0404002B +#define ICON_KNIGHT 0x0404002C +#define ICON_LADDER 0x0404002D +#define ICON_LEARY 0x0404002E +#define ICON_LEPRECHAUN 0x0404002F +#define ICON_LIE 0x04040030 +#define ICON_LOBINEAU 0x04040031 +#define ICON_MARQUET 0x04040032 +#define ICON_MARY 0x04040033 +#define ICON_MOB 0x04040034 +#define ICON_MONTFAUCON 0x04040035 +#define ICON_MOUE 0x04040036 +#define ICON_MR_SHINY 0x04040037 +#define ICON_NEJO 0x04040038 +#define ICON_NEJO_STALL 0x04040039 +#define ICON_NICO 0x0404003A +#define ICON_NO 0x0404003B +#define ICON_NURSE 0x0404003C +#define ICON_PACKAGE 0x0404003D +#define ICON_PAINTER 0x0404003E +#define ICON_PEAGRAM 0x0404003F +#define ICON_PEARL 0x04040040 +#define ICON_PHILIPPE 0x04040041 +#define ICON_PHONE 0x04040042 +#define ICON_PHRASE 0x04040043 +#define ICON_PIERMONT 0x04040044 +#define ICON_PLANTARD 0x04040045 +#define ICON_POTS 0x04040046 +#define ICON_PRIEST 0x04040047 +#define ICON_QUEEN 0x04040048 +#define ICON_RENEE 0x04040049 +#define ICON_ROSSO 0x0404004A +#define ICON_ROZZER 0x0404004B +#define ICON_SAFE 0x0404004C +#define ICON_SCROLL 0x0404004D +#define ICON_SEAN 0x0404004E +#define ICON_SIGN 0x0404004F +#define ICON_TAXI 0x04040050 +#define ICON_TEMPLARS 0x04040051 +#define ICON_THERMOSTAT 0x04040052 +#define ICON_TOILET 0x04040053 +#define ICON_TOMB 0x04040054 +#define ICON_TOOLBOX 0x04040055 +#define ICON_TRUTH 0x04040056 +#define ICON_ULTAR 0x04040057 +#define ICON_WEASEL 0x04040058 +#define ICON_WEAVER 0x04040059 +#define ICON_WELL 0x0404005A +#define ICON_WELL2 0x0404005B +#define ICON_WINDOW 0x0404005C +#define ICON_YES 0x0404005D + // 94 entities in TXTs, 94 in datafiles. + // save_menu +#define SR_BUTTON 0x04050000 +#define SR_PALETTE 0x04050001 +#define SR_PANEL_ENGLISH 0x04050002 +#define SR_PANEL_FRENCH 0x04050003 +#define SR_PANEL_GERMAN 0x04050004 +#define SR_PANEL_ITALIAN 0x04050005 +#define SR_PANEL_SPANISH 0x04050006 +#define SR_PANEL_AMERICAN 0x04050007 +#define SR_TEXT_BUTTON 0x04050008 +#define SR_SPEED 0x04050009 +#define SR_SCROLL1 0x0405000A +#define SR_SCROLL2 0x0405000B +#define SR_CONFIRM 0x0405000C +#define SR_VOLUME 0x0405000D +#define SR_VLIGHT 0x0405000E +#define SR_VKNOB 0x0405000F +#define SR_WINDOW 0x04050010 +#define SR_SLAB1 0x04050011 +#define SR_SLAB2 0x04050012 +#define SR_SLAB3 0x04050013 +#define SR_SLAB4 0x04050014 +#define SR_BUTUF 0x04050015 +#define SR_BUTUS 0x04050016 +#define SR_BUTDS 0x04050017 +#define SR_BUTDF 0x04050018 +#define SR_DEATHPANEL 0x04050019 + // 26 entities in TXTs, 29 in datafiles. + // george +#define GEORGE_MEGA 0x04060000 +#define GEORGE_WLK 0x04060001 +#define GEOSHO1 0x04060002 +#define GEOSHO1CDT 0x04060003 +#define GEOSHO1CDR 0x04060004 +#define GEOSHO2 0x04060005 +#define GEOSHO2CDT 0x04060006 +#define GEOSHO2CDR 0x04060007 +#define GEOSHO3 0x04060008 +#define GEOSHO3CDT 0x04060009 +#define GEOSHO3CDR 0x0406000A +#define GEOSHO5 0x0406000B +#define GEOSHO5CDT 0x0406000C +#define GEOSHO5CDR 0x0406000D +#define GEOSHO6 0x0406000E +#define GEOSHO6CDT 0x0406000F +#define GEOSHO6CDR 0x04060010 +#define GEOSHO7 0x04060011 +#define GEOSHO7CDT 0x04060012 +#define GEOSHO7CDR 0x04060013 +#define GEOTLK0 0x04060014 +#define GEOTLK0CDT 0x04060015 +#define GEOTLK1 0x04060016 +#define GEOTLK1CDT 0x04060017 +#define GEOTLK2 0x04060018 +#define GEOTLK2CDT 0x04060019 +#define GEOTLK3 0x0406001A +#define GEOTLK3CDT 0x0406001B +#define GEOTLK4 0x0406001C +#define GEOTLK4CDT 0x0406001D +#define GEOTLK5 0x0406001E +#define GEOTLK5CDT 0x0406001F +#define GEOTLK6 0x04060020 +#define GEOTLK6CDT 0x04060021 +#define GEOTLK7 0x04060022 +#define GEOTLK7CDT 0x04060023 +#define XGEOCRW0 0x04060024 +#define XGEOCRW0CDT 0x04060025 +#define XGEOCRW0CDR 0x04060026 +#define XGEOCRW1 0x04060027 +#define XGEOCRW1CDT 0x04060028 +#define XGEOCRW1CDR 0x04060029 +#define XGEOCRW2 0x0406002A +#define XGEOCRW2CDT 0x0406002B +#define XGEOCRW2CDR 0x0406002C +#define XGEOCRW3 0x0406002D +#define XGEOCRW3CDT 0x0406002E +#define XGEOCRW3CDR 0x0406002F +#define XGEOCRW4 0x04060030 +#define XGEOCRW4CDT 0x04060031 +#define XGEOCRW4CDR 0x04060032 +#define XGEOCRW5 0x04060033 +#define XGEOCRW5CDT 0x04060034 +#define XGEOCRW5CDR 0x04060035 +#define XGEOCRW6 0x04060036 +#define XGEOCRW6CDT 0x04060037 +#define XGEOCRW6CDR 0x04060038 +#define XGEOCRW7 0x04060039 +#define XGEOCRW7CDT 0x0406003A +#define XGEOCRW7CDR 0x0406003B +#define XGEOGIV0 0x0406003C +#define XGEOGIV0CDT 0x0406003D +#define XGEOGIV0CDR 0x0406003E +#define XGEOGIV1 0x0406003F +#define XGEOGIV1CDT 0x04060040 +#define XGEOGIV1CDR 0x04060041 +#define XGEOGIV2 0x04060042 +#define XGEOGIV2CDT 0x04060043 +#define XGEOGIV2CDR 0x04060044 +#define XGEOGIV3 0x04060045 +#define XGEOGIV3CDT 0x04060046 +#define XGEOGIV3CDR 0x04060047 +#define XGEOGIV4 0x04060048 +#define XGEOGIV4CDT 0x04060049 +#define XGEOGIV4CDR 0x0406004A +#define XGEOGIV5 0x0406004B +#define XGEOGIV5CDT 0x0406004C +#define XGEOGIV5CDR 0x0406004D +#define XGEOGIV6 0x0406004E +#define XGEOGIV6CDT 0x0406004F +#define XGEOGIV6CDR 0x04060050 +#define XGEOGIV7 0x04060051 +#define XGEOGIV7CDT 0x04060052 +#define XGEOGIV7CDR 0x04060053 +#define XGEOLUK3 0x04060054 +#define XGEOLUK3CDT 0x04060055 +#define XGEOLUK5 0x04060056 +#define XGEOLUK5CDT 0x04060057 +#define XGEOPIC0 0x04060058 +#define XGEOPIC0CDT 0x04060059 +#define XGEOPIC1 0x0406005A +#define XGEOPIC1CDT 0x0406005B +#define XGEOPIC2 0x0406005C +#define XGEOPIC2CDT 0x0406005D +#define XGEOPIC3 0x0406005E +#define XGEOPIC3CDT 0x0406005F +#define XGEOPIC4 0x04060060 +#define XGEOPIC4CDT 0x04060061 +#define XGEOPIC5 0x04060062 +#define XGEOPIC5CDT 0x04060063 +#define XGEOPIC6 0x04060064 +#define XGEOPIC6CDT 0x04060065 +#define XGEOPIC7 0x04060066 +#define XGEOPIC7CDT 0x04060067 +#define XGEOSHG0 0x04060068 +#define XGEOSHG0CDT 0x04060069 +#define XGEOSHG1 0x0406006A +#define XGEOSHG1CDT 0x0406006B +#define XGEOSHG2 0x0406006C +#define XGEOSHG2CDT 0x0406006D +#define XGEOSHG3 0x0406006E +#define XGEOSHG3CDT 0x0406006F +#define XGEOSHG4 0x04060070 +#define XGEOSHG4CDT 0x04060071 +#define XGEOSHG5 0x04060072 +#define XGEOSHG5CDT 0x04060073 +#define XGEOSHG6 0x04060074 +#define XGEOSHG6CDT 0x04060075 +#define XGEOSHG7 0x04060076 +#define XGEOSHG7CDT 0x04060077 +#define XGHAIR2 0x04060078 +#define XGHAIR2CDT 0x04060079 +#define XGHAIR6 0x0406007A +#define XGHAIR6CDT 0x0406007B +#define GEOBLNK2 0x0406007C +#define GEOBLNK2CDT 0x0406007D +#define GEOBLNK3 0x0406007E +#define GEOBLNK3CDT 0x0406007F +#define GEOBLNK4 0x04060080 +#define GEOBLNK4CDT 0x04060081 +#define GEOBLNK5 0x04060082 +#define GEOBLNK5CDT 0x04060083 +#define GEOBLNK6 0x04060084 +#define GEOBLNK6CDT 0x04060085 +#define XGRELAX0 0x04060086 +#define XGRELAX0CDT 0x04060087 +#define XGRELAX0CDR 0x04060088 +#define XGRELAX1 0x04060089 +#define XGRELAX1CDT 0x0406008A +#define XGRELAX1CDR 0x0406008B +#define XGRELAX2 0x0406008C +#define XGRELAX2CDT 0x0406008D +#define XGRELAX2CDR 0x0406008E +#define XGRELAX3 0x0406008F +#define XGRELAX3CDT 0x04060090 +#define XGRELAX3CDR 0x04060091 +#define XGRELAX4 0x04060092 +#define XGRELAX4CDT 0x04060093 +#define XGRELAX4CDR 0x04060094 +#define XGRELAX5 0x04060095 +#define XGRELAX5CDT 0x04060096 +#define XGRELAX5CDR 0x04060097 +#define XGRELAX6 0x04060098 +#define XGRELAX6CDT 0x04060099 +#define XGRELAX6CDR 0x0406009A +#define XGRELAX7 0x0406009B +#define XGRELAX7CDT 0x0406009C +#define XGRELAX7CDR 0x0406009D + // 158 entities in TXTs, 158 in datafiles. + // nico +#define MEGANICO 0x04070000 +#define NICO_WLK 0x04070001 +#define NICTLK0 0x04070002 +#define NICTLK0CDT 0x04070003 +#define NICTLK1 0x04070004 +#define NICTLK1CDT 0x04070005 +#define NICTLK2 0x04070006 +#define NICTLK2CDT 0x04070007 +#define NICTLK3 0x04070008 +#define NICTLK3CDT 0x04070009 +#define NICTLK4 0x0407000A +#define NICTLK4CDT 0x0407000B +#define NICTLK5 0x0407000C +#define NICTLK5CDT 0x0407000D +#define NICTLK6 0x0407000E +#define NICTLK6CDT 0x0407000F +#define NICTLK7 0x04070010 +#define NICTLK7CDT 0x04070011 + // 18 entities in TXTs, 18 in datafiles. +// maps + // room80 +#define room80_PAL 0x05000000 +#define room80_l0 0x05000001 +#define TEST_FLR 0x05000002 +#define SPRITE_PAL 0x05000003 +#define AEROPORTCDT 0x05000004 +#define AEROPORT 0x05000005 +#define APRTSTRTCDT 0x05000006 +#define APRTSTRT 0x05000007 +#define BAPHOMETCDT 0x05000008 +#define BAPHOMET 0x05000009 +#define CAFECDT 0x0500000A +#define CAFE 0x0500000B +#define COSTUMESCDT 0x0500000C +#define COSTUMES 0x0500000D +#define HOSPITALCDT 0x0500000E +#define HOSPITAL 0x0500000F +#define HOTELCDT 0x05000010 +#define HOTEL 0x05000011 +#define MONTFACNCDT 0x05000012 +#define MONTFACN 0x05000013 +#define MUSEUMCDT 0x05000014 +#define MUSEUM 0x05000015 +#define POLICECDT 0x05000016 +#define POLICE 0x05000017 + // 24 entities in TXTs, 24 in datafiles. + // room86 +#define room86_PAL 0x05010000 +#define room86_l0 0x05010001 +#define BANNOCKCDT 0x05010002 +#define BANNOCK 0x05010003 +#define MARIBCDT 0x05010004 +#define MARIB 0x05010005 +#define LOCHMARNCDT 0x05010006 +#define LOCHMARN 0x05010007 +#define PARISCDT 0x05010008 +#define PARIS 0x05010009 +#define VILLAVASCDT 0x0501000A +#define VILLAVAS 0x0501000B + // 12 entities in TXTs, 12 in datafiles. + // room90 +#define R90L0 0x05020000 +#define R90PAL 0x05020001 +#define PHONE_PAL 0x05020002 +#define GBLINK 0x05020003 +#define GBLINKCDT 0x05020004 +#define GRISE 0x05020005 +#define GRISECDT 0x05020006 +#define GRISECDR 0x05020007 +#define GTALK 0x05020008 +#define GTALKCDT 0x05020009 +#define NBLINK 0x0502000A +#define NBLINKCDT 0x0502000B +#define NRISE 0x0502000C +#define NRISECDT 0x0502000D +#define NRISECDR 0x0502000E +#define NTALK 0x0502000F +#define NTALKCDT 0x05020010 +#define TODTALK 0x05020011 +#define TODTALKCDT 0x05020012 + // 19 entities in TXTs, 19 in datafiles. + // room91 +#define R91L0 0x05030000 +#define R91PAL 0x05030001 +#define CLOWN 0x05030002 +#define CLOWNCDT 0x05030003 +#define DESVAS 0x05030004 +#define DESVASCDT 0x05030005 +#define EIFTOWER 0x05030006 +#define EIFTOWERCDT 0x05030007 +#define HORSETIP 0x05030008 +#define HORSETIPCDT 0x05030009 +#define LOBIN91 0x0503000A +#define LOBIN91CDT 0x0503000B +#define MONTFCON 0x0503000C +#define MONTFCONCDT 0x0503000D +#define NICOADD 0x0503000E +#define NICOADDCDT 0x0503000F +#define NICOPHN 0x05030010 +#define NICOPHNCDT 0x05030011 +#define TAILOR 0x05030012 +#define TAILORCDT 0x05030013 + // 20 entities in TXTs, 20 in datafiles. + // room99 +#define room99_PAL 0x05040000 +#define room99_l0 0x05040001 + // 2 entities in TXTs, 2 in datafiles. +// paris_1 + // sound_fx +#define FX_CAMERA1 0x06000000 +#define FX_CAMERA2 0x06000001 +#define FX_CAMERA3 0x06000002 +#define FX_CANDO 0x06000003 +#define FX_CANUP 0x06000004 +#define FX_CAW1 0x06000005 +#define FX_DUST 0x06000006 +#define FX_HORN1 0x06000007 +#define FX_HORN2 0x06000008 +#define FX_HORN3 0x06000009 +#define FX_LVSFLY 0x0600000A +#define FX_PAP1 0x0600000B +#define FX_PAP2 0x0600000C +#define FX_PICK1 0x0600000D +#define FX_PICK2 0x0600000E +#define FX_PICK3 0x0600000F +#define FX_PICK4 0x06000010 +#define FX_PICK5 0x06000011 +#define FX_TRAFFIC2 0x06000012 +#define FX_TWEET1 0x06000013 +#define FX_TWEET2 0x06000014 +#define FX_TWEET3 0x06000015 +#define FX_TWEET4 0x06000016 +#define FX_TWEET5 0x06000017 +#define FX_BIN1 0x06000018 +#define FX_BIN2 0x06000019 +#define FX_BIN3 0x0600001A +#define FX_CAT 0x0600001B +#define FX_COVERON2 0x0600001C +#define FX_CRATE 0x0600001D +#define FX_DRAIN 0x0600001E +#define FX_HOLE 0x0600001F +#define FX_BODY 0x06000020 +#define FX_BOTDN 0x06000021 +#define FX_BOTUP 0x06000022 +#define FX_GULP 0x06000023 +#define FX_LIGHT 0x06000024 +#define FX_PIKUP 0x06000025 +#define FX_PAP3 0x06000026 +#define FX_PAP4 0x06000027 +#define FX_PAP5 0x06000028 +#define FX_PISTOL 0x06000029 +#define FX_TBOX 0x0600002A +#define FX_KNOKKNOK 0x0600002B +#define FX_ALBCLO 0x0600002C +#define FX_ALBOP 0x0600002D +#define FX_LADD1 0x0600002E +#define FX_LADD2 0x0600002F +#define FX_LADD3 0x06000030 +#define FX_RAT1 0x06000031 +#define FX_RAT2 0x06000032 +#define FX_SEWSTEP1 0x06000033 +#define FX_SEWSTEP2 0x06000034 +#define FX_SWATER3 0x06000035 +#define FX_DRIP1 0x06000036 +#define FX_DRIP2 0x06000037 +#define FX_DRIP3 0x06000038 +#define FX_SWATER1 0x06000039 +#define FX_SEWLADD7 0x0600003A +#define FX_SEWLADU7 0x0600003B + // 60 entities in TXTs, 60 in datafiles. + // room1 +#define PARIS1_PAL 0x06010000 +#define room1_PAL 0x06010001 +#define room1_l0 0x06010002 +#define room1_l1 0x06010003 +#define room1_l2 0x06010004 +#define room1_gd1 0x06010005 +#define room1_gd2 0x06010006 +#define room1_flr 0x06010007 +#define room1_plx 0x06010008 +#define BIRDS 0x06010009 +#define BIRDSCDT 0x0601000A +#define BIRDSA 0x0601000B +#define BIRDSACDT 0x0601000C +#define BIRDSB 0x0601000D +#define BIRDSBCDT 0x0601000E +#define BIRDSC 0x0601000F +#define BIRDSCCDT 0x06010010 +#define BIRDSD 0x06010011 +#define BIRDSDCDT 0x06010012 +#define BIRDSE 0x06010013 +#define BIRDSECDT 0x06010014 +#define BIRDSF 0x06010015 +#define BIRDSFCDT 0x06010016 +#define BIRDSG 0x06010017 +#define BIRDSGCDT 0x06010018 +#define BIRDSH 0x06010019 +#define BIRDSHCDT 0x0601001A +#define BIRDSI 0x0601001B +#define BIRDSICDT 0x0601001C +#define CANOPY 0x0601001D +#define CANOPYCDT 0x0601001E +#define GEOCAN 0x0601001F +#define GEOCANCDT 0x06010020 +#define GEONIC 0x06010021 +#define GEONICCDT 0x06010022 +#define GEOPAP 0x06010023 +#define GEOPAPCDT 0x06010024 +#define GEOPAP2 0x06010025 +#define GEOPAP2CDT 0x06010026 +#define LVSFLY 0x06010027 +#define LVSFLYCDT 0x06010028 +#define MOUGRD 0x06010029 +#define MOUGRDCDT 0x0601002A +#define MOUTLK01 0x0601002B +#define MOUTLK01CDT 0x0601002C +#define MOUWLK01 0x0601002D +#define MOUWLK01CDT 0x0601002E +#define NICPHT1CDT 0x0601002F +#define NICPHT1 0x06010030 +#define NICPHT2CDT 0x06010031 +#define NICPHT2 0x06010032 +#define NICPHT3CDT 0x06010033 +#define NICPHT3 0x06010034 +#define NICPHT5CDT 0x06010035 +#define NICPHT5 0x06010036 +#define NICPHT6CDT 0x06010037 +#define NICPHT6 0x06010038 +#define NICPHT7CDT 0x06010039 +#define NICPHT7 0x0601003A +#define NICWLK01 0x0601003B +#define NICWLK01CDT 0x0601003C +#define NWPAPER 0x0601003D +#define NWPAPERCDT 0x0601003E +#define WRKDIG01 0x0601003F +#define WRKDIG01CDT 0x06010040 +#define XGEOPHN3 0x06010041 +#define XGEOPHN3CDT 0x06010042 +#define XGEOPHN5 0x06010043 +#define XGEOPHN5CDT 0x06010044 +#define XNICPHN3CDT 0x06010045 +#define XNICPHN3 0x06010046 +#define XNICPHN5CDT 0x06010047 +#define XNICPHN5 0x06010048 + // 73 entities in TXTs, 73 in datafiles. + // room2 +#define room2_PAL 0x06020000 +#define room2_l0 0x06020001 +#define room2_l1 0x06020002 +#define room2_l2 0x06020003 +#define room2_gd1 0x06020004 +#define room2_gd2 0x06020005 +#define room2_flr 0x06020006 +#define BIN1 0x06020007 +#define BIN1CDT 0x06020008 +#define BIN2 0x06020009 +#define BIN2CDT 0x0602000A +#define BIN3 0x0602000B +#define BIN3CDT 0x0602000C +#define CATJMP 0x0602000D +#define CATJMPCDT 0x0602000E +#define CRATE 0x0602000F +#define CRATECDT 0x06020010 +#define DRNBRK 0x06020011 +#define DRNBRKCDT 0x06020012 +#define GEOBIN 0x06020013 +#define GEOBINCDT 0x06020014 +#define GEOBOX 0x06020015 +#define GEOBOXCDT 0x06020016 +#define GEOBRS 0x06020017 +#define GEOBRSCDT 0x06020018 +#define GEOCAT 0x06020019 +#define GEOCATCDT 0x0602001A +#define GEOCATE 0x0602001B +#define GEOCATECDT 0x0602001C +#define GEOCLM02 0x0602001D +#define GEOCLM02CDT 0x0602001E +#define GEOCRT 0x0602001F +#define GEOCRTCDT 0x06020020 +#define GEODWN 0x06020021 +#define GEODWNCDT 0x06020022 +#define GEOLID 0x06020023 +#define GEOLIDCDT 0x06020024 +#define GEOLIDCDR 0x06020025 +#define GEOMAN8 0x06020026 +#define GEOMAN8CDT 0x06020027 +#define GEOMAN9 0x06020028 +#define GEOMAN9CDT 0x06020029 +#define GEOOUT 0x0602002A +#define GEOOUTCDT 0x0602002B +#define GEOPLL02 0x0602002C +#define GEOPLL02CDT 0x0602002D +#define GEOTRY02 0x0602002E +#define GEOTRY02CDT 0x0602002F +#define MANCOV 0x06020030 +#define MANCOVCDT 0x06020031 +#define MANCVOFF 0x06020032 +#define MANCVOFFCDT 0x06020033 + // 52 entities in TXTs, 52 in datafiles. + // room3 +#define room3_PAL 0x06030000 +#define room3_l0 0x06030001 +#define room3_l1 0x06030002 +#define room3_l2 0x06030003 +#define room3_gd1 0x06030004 +#define room3_gd2 0x06030005 +#define room3_flr 0x06030006 +#define BOTTLE 0x06030007 +#define BOTTLECDT 0x06030008 +#define BOTTLE1 0x06030009 +#define BOTTLE1CDT 0x0603000A +#define CHNDRN 0x0603000B +#define CHNDRNCDT 0x0603000C +#define CHNFNT 0x0603000D +#define CHNFNTCDT 0x0603000E +#define CHNSITA 0x0603000F +#define CHNSITACDT 0x06030010 +#define CHNSIT 0x06030011 +#define CHNSITCDT 0x06030012 +#define CHNTLK 0x06030013 +#define CHNTLKCDT 0x06030014 +#define CHNUPP 0x06030015 +#define CHNUPPCDT 0x06030016 +#define CHNUPPCDR 0x06030017 +#define CORPSE 0x06030018 +#define CORPSECDT 0x06030019 +#define FLICKER 0x0603001A +#define FLICKERCDT 0x0603001B +#define GEOBOT3 0x0603001C +#define GEOBOT3CDT 0x0603001D +#define GEOCARD3 0x0603001E +#define GEOCARD3CDT 0x0603001F +#define GEOCHN 0x06030020 +#define GEOCHNCDT 0x06030021 +#define GEOCPS 0x06030022 +#define GEOCPSCDT 0x06030023 +#define GEOCPSCDR 0x06030024 +#define MOUCHN 0x06030025 +#define MOUCHNCDT 0x06030026 +#define MOUCHN8 0x06030027 +#define MOUCHN8CDT 0x06030028 +#define MOUCPS 0x06030029 +#define MOUCPSCDT 0x0603002A +#define MOUCPSTK 0x0603002B +#define MOUCPSTKCDT 0x0603002C +#define MOUDOR03 0x0603002D +#define MOUDOR03CDT 0x0603002E +#define MOUROS 0x0603002F +#define MOUROSCDT 0x06030030 +#define MOUROS1 0x06030031 +#define MOUROS1CDT 0x06030032 +#define MOUROS1CDR 0x06030033 +#define MOUROS2 0x06030034 +#define MOUROS2CDT 0x06030035 +#define MOUSTD 0x06030036 +#define MOUSTDCDT 0x06030037 +#define MOUTALK 0x06030038 +#define MOUTALKCDT 0x06030039 +#define MOUTLK1 0x0603003A +#define MOUTLK1CDT 0x0603003B +#define MOUTRN03 0x0603003C +#define MOUTRN03CDT 0x0603003D +#define MOUTRN03CDR 0x0603003E +#define MOUTRN2 0x0603003F +#define MOUTRN2CDT 0x06030040 +#define MOUTRN2CDR 0x06030041 +#define MOUWLK 0x06030042 +#define MOUWLKCDT 0x06030043 +#define MOUWLK03 0x06030044 +#define MOUWLK03CDT 0x06030045 +#define ROSCARD 0x06030046 +#define ROSCARDCDT 0x06030047 +#define ROSCHN 0x06030048 +#define ROSCHNCDT 0x06030049 +#define ROSCHNCDR 0x0603004A +#define ROSGEO 0x0603004B +#define ROSGEOCDT 0x0603004C +#define ROSGEOA 0x0603004D +#define ROSGEOACDT 0x0603004E +#define ROSGEOB 0x0603004F +#define ROSGEOBCDT 0x06030050 +#define ROSGEOC 0x06030051 +#define ROSGEOCCDT 0x06030052 +#define ROSLIK 0x06030053 +#define ROSLIKCDT 0x06030054 +#define ROSLUK 0x06030055 +#define ROSLUKCDT 0x06030056 +#define ROSMOU 0x06030057 +#define ROSMOUCDT 0x06030058 +#define ROSNBK 0x06030059 +#define ROSNBKCDT 0x0603005A +#define ROSNBK8 0x0603005B +#define ROSNBK8CDT 0x0603005C +#define ROSPKT 0x0603005D +#define ROSPKTCDT 0x0603005E +#define ROSTMP 0x0603005F +#define ROSTMPCDT 0x06030060 +#define ROSTMP8 0x06030061 +#define ROSTMP8CDT 0x06030062 +#define ROSTURNA 0x06030063 +#define ROSTURNACDT 0x06030064 +#define ROSTURNB 0x06030065 +#define ROSTURNBCDT 0x06030066 +#define ROSTRN2 0x06030067 +#define ROSTRN2CDT 0x06030068 +#define ROSWRT 0x06030069 +#define ROSWRTCDT 0x0603006A + // 107 entities in TXTs, 107 in datafiles. + // room4 +#define room4_PAL 0x06040000 +#define room4_l0 0x06040001 +#define room4_l1 0x06040002 +#define room4_l2 0x06040003 +#define room4_gd1 0x06040004 +#define room4_gd2 0x06040005 +#define room4_flr 0x06040006 +#define ALBDOR 0x06040007 +#define ALBDORCDR 0x06040008 +#define ALBDORCDT 0x06040009 +#define ALBDOR8 0x0604000A +#define ALBDOR8CDT 0x0604000B +#define GEONOK 0x0604000C +#define GEONOKCDT 0x0604000D +#define GEONOKCDR 0x0604000E +#define GEOTBX 0x0604000F +#define GEOTBXCDT 0x06040010 +#define GEOWRK 0x06040011 +#define GEOWRKCDT 0x06040012 +#define GEOWRK8 0x06040013 +#define GEOWRK8CDT 0x06040014 +#define MOUENT 0x06040015 +#define MOUENTCDT 0x06040016 +#define MOUSHG 0x06040017 +#define MOUSHGCDT 0x06040018 +#define MOUSTR 0x06040019 +#define MOUSTRCDT 0x0604001A +#define MOUTLK04 0x0604001B +#define MOUTLK04CDT 0x0604001C +#define MOUWLK04 0x0604001D +#define MOUWLK04CDT 0x0604001E +#define ROSENT 0x0604001F +#define ROSENTCDT 0x06040020 +#define ROSTLK04 0x06040021 +#define ROSTLK04CDT 0x06040022 +#define ROSWLK 0x06040023 +#define ROSWLKCDT 0x06040024 +#define PHONE4 0x06040025 +#define PHONE4CDT 0x06040026 +#define WRKAXE 0x06040027 +#define WRKAXECDT 0x06040028 +#define WRKBLINK 0x06040029 +#define WRKBLINKCDT 0x0604002A +#define WRKCLM 0x0604002B +#define WRKCLMCDT 0x0604002C +#define WRKDIG 0x0604002D +#define WRKDIGCDT 0x0604002E +#define WRKPPR 0x0604002F +#define WRKPPRCDT 0x06040030 +#define WRKTLK 0x06040031 +#define WRKTLKCDT 0x06040032 +#define WRKTLK8 0x06040033 +#define WRKTLK8CDT 0x06040034 +#define WRKTLK9 0x06040035 +#define WRKTLK9CDT 0x06040036 +#define WRKTRN 0x06040037 +#define WRKTRNCDR 0x06040038 +#define WRKTRNCDT 0x06040039 +#define WRKXIT 0x0604003A +#define WRKXITCDT 0x0604003B + // 60 entities in TXTs, 60 in datafiles. + // room5 +#define room5_PAL 0x06050000 +#define room5_l0 0x06050001 +#define room5_l1 0x06050002 +#define room5_l2 0x06050003 +#define room5_gd1 0x06050004 +#define room5_gd2 0x06050005 +#define room5_flr 0x06050006 +#define ALBAPT 0x06050007 +#define ALBAPTCDT 0x06050008 +#define ALBAPTCDR 0x06050009 +#define ALBCLOSECDT 0x0605000A +#define ALBCLOSE 0x0605000B +#define ALBCRD8 0x0605000C +#define ALBCRD8CDT 0x0605000D +#define ALBDORTKCDT 0x0605000E +#define ALBDORTK 0x0605000F +#define ALBDRTK2CDT 0x06050010 +#define ALBDRTK2 0x06050011 +#define ALBHND 0x06050012 +#define ALBHNDCDT 0x06050013 +#define ALBOBJ 0x06050014 +#define ALBOBJCDT 0x06050015 +#define ALBOPENCDT 0x06050016 +#define ALBOPEN 0x06050017 +#define ALBPKT 0x06050018 +#define ALBPKTCDT 0x06050019 +#define ALBTLK 0x0605001A +#define ALBTLKCDT 0x0605001B +#define ALBWLK9CDT 0x0605001C +#define ALBWLK9 0x0605001D +#define GEOCRD05 0x0605001E +#define GEOCRD05CDT 0x0605001F +#define GEODOR05CDT 0x06050020 +#define GEODOR05 0x06050021 +#define GEOEMG 0x06050022 +#define GEOEMGCDT 0x06050023 +#define GEOEMGCDR 0x06050024 +#define GEOEMGA 0x06050025 +#define GEOEMGACDT 0x06050026 +#define GEOEMGACDR 0x06050027 +#define GEOEMGB 0x06050028 +#define GEOEMGBCDT 0x06050029 +#define GEOEMGBCDR 0x0605002A +#define GEOEXITCDT 0x0605002B +#define GEOEXIT 0x0605002C +#define GEOHND05 0x0605002D +#define GEOHND05CDT 0x0605002E +#define GEONOK05CDT 0x0605002F +#define GEONOK05 0x06050030 +#define GEOTLK05 0x06050031 +#define GEOTLK05CDT 0x06050032 + // 51 entities in TXTs, 51 in datafiles. + // room6 +#define SEWER_PAL 0x06060000 +#define room6_PAL 0x06060001 +#define room6_l0 0x06060002 +#define room6_l1 0x06060003 +#define room6_gd1 0x06060004 +#define room6_flr 0x06060005 +#define GEOASC06 0x06060006 +#define GEOASC06CDT 0x06060007 +#define GEODES06 0x06060008 +#define GEODES06CDT 0x06060009 +#define GEONOSE 0x0606000A +#define GEONOSECDT 0x0606000B +#define REDNOSE 0x0606000C +#define REDNOSECDT 0x0606000D +#define WATER06 0x0606000E +#define WATER06CDT 0x0606000F + // 16 entities in TXTs, 16 in datafiles. + // room7 +#define room7_PAL 0x06070000 +#define room7_l0 0x06070001 +#define room7_l1 0x06070002 +#define room7_l2 0x06070003 +#define room7_gd1 0x06070004 +#define room7_gd2 0x06070005 +#define room7_flr 0x06070006 +#define GEOASC07 0x06070007 +#define GEOASC07CDT 0x06070008 +#define GEOASC07CDR 0x06070009 +#define GEOPLL07 0x0607000A +#define GEOPLL07CDT 0x0607000B +#define GEOPLL07CDR 0x0607000C +#define GEOSPK 0x0607000D +#define GEOSPKCDT 0x0607000E +#define GEOTIS 0x0607000F +#define GEOTISCDT 0x06070010 +#define MATERIAL 0x06070011 +#define MATERIALCDT 0x06070012 +#define TISSUE7 0x06070013 +#define TISSUE7CDT 0x06070014 +#define WATER07 0x06070015 +#define WATER07CDT 0x06070016 + // 23 entities in TXTs, 23 in datafiles. + // room8 +#define room8_PAL 0x06080000 +#define room8_l0 0x06080001 +#define room8_l1 0x06080002 +#define room8_l2 0x06080003 +#define room8_gd1 0x06080004 +#define room8_gd2 0x06080005 +#define room8_flr 0x06080006 +#define room8_plx 0x06080007 + // 8 entities in TXTs, 8 in datafiles. +// paris_2 + // sound_fx +#define FX_BIRD 0x07000000 +#define FX_BIRD2 0x07000001 +#define FX_CARLTON 0x07000002 +#define FX_CARS 0x07000003 +#define FX_DOORTRY 0x07000004 +#define FX_FIESTA 0x07000005 +#define FX_FLATDOOR 0x07000006 +#define FX_HVYVEHL 0x07000007 +#define FX_HVYVEHR 0x07000008 +#define FX_LITEVEHL 0x07000009 +#define FX_LITEVEHR 0x0700000A +#define FX_FONEUP 0x0700000B +#define FX_FONEDN 0x0700000C +#define FX_GEOCCH 0x0700000D +#define FX_GEOCHAIR 0x0700000E +#define FX_GEOCHR9 0x0700000F +#define FX_NICOPEN 0x07000010 +#define FX_NICLOSE 0x07000011 +#define FX_PHONICO1 0x07000012 +#define FX_GRAMOFON 0x07000013 +#define FX_SHOCK1 0x07000014 +#define FX_WINDUP11 0x07000015 +#define FX_FRISK 0x07000016 +#define FX_TRAFFIC3 0x07000017 +#define FX_DESKBELL 0x07000018 +#define FX_KEY13 0x07000019 +#define FX_PAPER6 0x0700001A +#define FX_PHONEDN2 0x0700001B +#define FX_PHONEUP2 0x0700001C +#define FX_PIANO14 0x0700001D +#define FX_TRYDOR14 0x0700001E +#define FX_CABCLOSE 0x0700001F +#define FX_CABOPEN 0x07000020 +#define FX_DORCLOSE 0x07000021 +#define FX_WINDOPEN 0x07000022 +#define FX_COO 0x07000023 +#define FX_COO2 0x07000024 +#define FX_LEDGE1 0x07000025 +#define FX_LEDGE2 0x07000026 +#define FX_BRIEFOFF 0x07000027 +#define FX_BRIEFON 0x07000028 +#define FX_JUMPIN 0x07000029 +#define FX_WARDIN 0x0700002A +#define FX_WARDOUT 0x0700002B +#define FX_CLIMBIN 0x0700002C +#define FX_CLIMBOUT 0x0700002D + // 46 entities in TXTs, 46 in datafiles. + // room9 +#define PARIS2_PAL 0x07010000 +#define room9_PAL 0x07010001 +#define room9_l0 0x07010002 +#define room9_l1 0x07010003 +#define room9_l2 0x07010004 +#define room9_gd1 0x07010005 +#define room9_gd2 0x07010006 +#define room9_flr 0x07010007 +#define CARA9CDT 0x07010008 +#define CARA9 0x07010009 +#define CARB9CDT 0x0701000A +#define CARB9 0x0701000B +#define CARC9CDT 0x0701000C +#define CARC9 0x0701000D +#define DOROPN09CDR 0x0701000E +#define DOROPN09CDT 0x0701000F +#define DOROPN09 0x07010010 +#define FLWLUKCDR 0x07010011 +#define FLWLUKCDT 0x07010012 +#define FLWLUK 0x07010013 +#define FLWNITCDT 0x07010014 +#define FLWNIT 0x07010015 +#define FLWTLKCDT 0x07010016 +#define FLWTLK 0x07010017 +#define GEODOOR9 0x07010018 +#define GEODOOR9CDT 0x07010019 +#define GEOSTPCDT 0x0701001A +#define GEOSTP 0x0701001B +#define GEOSTP8CDT 0x0701001C +#define GEOSTP8 0x0701001D +#define GEOTRY 0x0701001E +#define GEOTRYCDT 0x0701001F +#define TRUCKA9CDT 0x07010020 +#define TRUCKA9 0x07010021 +#define TRUCKB9CDT 0x07010022 +#define TRUCKB9 0x07010023 +#define TRUCKC9CDT 0x07010024 +#define TRUCKC9 0x07010025 + // 38 entities in TXTs, 38 in datafiles. + // room10 +#define R10SPRPAL 0x07020000 +#define room10_PAL 0x07020001 +#define room10_l0 0x07020002 +#define room10_l1 0x07020003 +#define room10_gd1 0x07020004 +#define room10_flr 0x07020005 +#define DOORCDT 0x07020006 +#define DOOR 0x07020007 +#define GEOCCHCDT 0x07020008 +#define GEOCCHCDR 0x07020009 +#define GEOCCH 0x0702000A +#define GEOCCH8CDT 0x0702000B +#define GEOCCH8 0x0702000C +#define GEOCCH9CDT 0x0702000D +#define GEOCCH9 0x0702000E +#define GEOCHRCDT 0x0702000F +#define GEOCHR 0x07020010 +#define GEOCHR8CDT 0x07020011 +#define GEOCHR8 0x07020012 +#define GEOCHR9CDT 0x07020013 +#define GEOCHR9 0x07020014 +#define GEODWN10CDT 0x07020015 +#define GEODWN10 0x07020016 +#define GEOENT10CDT 0x07020017 +#define GEOENT10 0x07020018 +#define GEOGEM10CDT 0x07020019 +#define GEOGEM10 0x0702001A +#define GEOGEMBCDT 0x0702001B +#define GEOGEMB 0x0702001C +#define GEOLUK10CDT 0x0702001D +#define GEOLUK10 0x0702001E +#define GEOLVS10CDT 0x0702001F +#define GEOLVS10 0x07020020 +#define GEOMAGTKCDT 0x07020021 +#define GEOMAGTK 0x07020022 +#define GEOMAT10CDT 0x07020023 +#define GEOMAT10 0x07020024 +#define GEOMATBCDT 0x07020025 +#define GEOMATB 0x07020026 +#define GEOMATCCDT 0x07020027 +#define GEOMATC 0x07020028 +#define GEONIC10CDR 0x07020029 +#define GEONIC10CDT 0x0702002A +#define GEONIC10 0x0702002B +#define GEONOSCDT 0x0702002C +#define GEONOS 0x0702002D +#define GEONOS10CDT 0x0702002E +#define GEONOS10 0x0702002F +#define GEONWPAPCDT 0x07020030 +#define GEONWPAP 0x07020031 +#define GEOPHN10CDT 0x07020032 +#define GEOPHN10 0x07020033 +#define GEOPHTCDT 0x07020034 +#define GEOPHT 0x07020035 +#define GEOPHT10CDT 0x07020036 +#define GEOPHT10 0x07020037 +#define GEOPHTLKCDT 0x07020038 +#define GEOPHTLK 0x07020039 +#define GEOPPR10CDT 0x0702003A +#define GEOPPR10 0x0702003B +#define GEOPRDCDT 0x0702003C +#define GEOPRD 0x0702003D +#define GEOREDCDT 0x0702003E +#define GEORED 0x0702003F +#define GEORELCDR 0x07020040 +#define GEORELCDT 0x07020041 +#define GEOREL 0x07020042 +#define GEORXTCDT 0x07020043 +#define GEORXT 0x07020044 +#define GEOTIS10CDT 0x07020045 +#define GEOTIS10 0x07020046 +#define GEOTISBCDT 0x07020047 +#define GEOTISB 0x07020048 +#define GEOTRIP1CDT 0x07020049 +#define GEOTRIP1 0x0702004A +#define GEOTRIP2CDT 0x0702004B +#define GEOTRIP2 0x0702004C +#define LOBTLK10CDT 0x0702004D +#define LOBTLK10 0x0702004E +#define MANUCDT 0x0702004F +#define MANU 0x07020050 +#define NICCHR9CDR 0x07020051 +#define NICCHR9CDT 0x07020052 +#define NICCHR9 0x07020053 +#define NICDWN10CDT 0x07020054 +#define NICDWN10 0x07020055 +#define NICLUK10CDT 0x07020056 +#define NICLUK10 0x07020057 +#define NICMAGCDR 0x07020058 +#define NICMAGCDT 0x07020059 +#define NICMAG 0x0702005A +#define NICNOSCDT 0x0702005B +#define NICNOS 0x0702005C +#define NICNOS10CDT 0x0702005D +#define NICNOS10 0x0702005E +#define NICNOSBCDT 0x0702005F +#define NICNOSB 0x07020060 +#define NICPHN10CDT 0x07020061 +#define NICPHN10 0x07020062 +#define NICPHT10CDT 0x07020063 +#define NICPHT10 0x07020064 +#define NICPPRCDT 0x07020065 +#define NICPPR 0x07020066 +#define NICPPR2CDT 0x07020067 +#define NICPPR2 0x07020068 +#define NICREDCDT 0x07020069 +#define NICRED 0x0702006A +#define NICRED2CDR 0x0702006B +#define NICRED2CDT 0x0702006C +#define NICRED2 0x0702006D +#define NICSIT 0x0702006E +#define NICSITCDT 0x0702006F +#define NICTLK10CDT 0x07020070 +#define NICTLK10 0x07020071 +#define NICTLKL 0x07020072 +#define NICTLKLCDT 0x07020073 +#define NICTLKR 0x07020074 +#define NICTLKRCDT 0x07020075 +#define NICTLKX 0x07020076 +#define NICTLKXCDT 0x07020077 +#define NICTLKXCDR 0x07020078 +#define NICTRIPCDT 0x07020079 +#define NICTRIP 0x0702007A +#define NICTURN 0x0702007B +#define NICTURNCDT 0x0702007C +#define NICTURNCDR 0x0702007D +#define NICWRT 0x0702007E +#define NICWRTCDT 0x0702007F +#define PHONE10CDT 0x07020080 +#define PHONE10 0x07020081 +#define PEAPAGECDT 0x07020082 +#define PEAPAGE 0x07020083 +#define PEAPAGE_PAL 0x07020084 +#define MANUSCRPCDT 0x07020085 +#define MANUSCRP 0x07020086 +#define MANUSCRP_PAL 0x07020087 +#define TRIPOD10CDT 0x07020088 +#define TRIPOD10 0x07020089 + // 138 entities in TXTs, 138 in datafiles. + // room11 +#define room11_PAL 0x07030000 +#define room11_l0 0x07030001 +#define room11_l1 0x07030002 +#define room11_l2 0x07030003 +#define room11_gd1 0x07030004 +#define room11_gd2 0x07030005 +#define room11_flr 0x07030006 +#define COSGIVCDR 0x07030007 +#define COSGIVCDT 0x07030008 +#define COSGIV 0x07030009 +#define COSLOOPCDT 0x0703000A +#define COSLOOP 0x0703000B +#define COSSHKCDT 0x0703000C +#define COSSHK 0x0703000D +#define COSSNFCDT 0x0703000E +#define COSSNF 0x0703000F +#define COSTLKCDT 0x07030010 +#define COSTLK 0x07030011 +#define DISCSPINCDT 0x07030012 +#define DISCSPIN 0x07030013 +#define GEOPIC11CDR 0x07030014 +#define GEOPIC11CDT 0x07030015 +#define GEOPIC11 0x07030016 +#define GEOSHK11CDT 0x07030017 +#define GEOSHK11 0x07030018 +#define GEOTURDCDT 0x07030019 +#define GEOTURD 0x0703001A +#define GEOTIS11CDT 0x0703001B +#define GEOTIS11 0x0703001C +#define GEOWINDCDT 0x0703001D +#define GEOWIND 0x0703001E +#define WINDUPCDT 0x0703001F +#define WINDUP 0x07030020 + // 33 entities in TXTs, 33 in datafiles. + // room12 +#define room12_PAL 0x07040000 +#define room12_l0 0x07040001 +#define room12_l1 0x07040002 +#define room12_gd1 0x07040003 +#define room12_flr 0x07040004 +#define FLAGSCDT 0x07040005 +#define FLAGS 0x07040006 +#define GEOAPPCDT 0x07040007 +#define GEOAPP 0x07040008 +#define GEOARMCDT 0x07040009 +#define GEOARM 0x0704000A +#define GEOASC12CDT 0x0704000B +#define GEOASC12 0x0704000C +#define GEODES12CDT 0x0704000D +#define GEODES12 0x0704000E +#define GORCOINCDT 0x0704000F +#define GORCOIN 0x07040010 +#define GORFRKCDT 0x07040011 +#define GORFRK 0x07040012 +#define GORMANCDT 0x07040013 +#define GORMAN 0x07040014 +#define GORTALKCDT 0x07040015 +#define GORTALK 0x07040016 +#define GORTLKCDT 0x07040017 +#define GORTLK 0x07040018 +#define GORTURNCDR 0x07040019 +#define GORTURNCDT 0x0704001A +#define GORTURN 0x0704001B +#define LATVIAN12CDT 0x0704001C +#define LATVIAN12 0x0704001D +#define WEABAKCDT 0x0704001E +#define WEABAK 0x0704001F +#define WEASMKCDT 0x07040020 +#define WEASMK 0x07040021 +#define WEATLKCDT 0x07040022 +#define WEATLK 0x07040023 +#define WEATLK12CDT 0x07040024 +#define WEATLK12 0x07040025 +#define WEATRNCDR 0x07040026 +#define WEATRNCDT 0x07040027 +#define WEATRN 0x07040028 + // 41 entities in TXTs, 41 in datafiles. + // room13 +#define R13SPRPAL 0x07050000 +#define room13_PAL 0x07050001 +#define room13_l0 0x07050002 +#define room13_l1 0x07050003 +#define room13_l2 0x07050004 +#define room13_gd1 0x07050005 +#define room13_gd2 0x07050006 +#define room13_flr 0x07050007 +#define CLKIDLCDT 0x07050008 +#define CLKIDL 0x07050009 +#define CLKMANCDT 0x0705000A +#define CLKMAN 0x0705000B +#define CLKTAKCDT 0x0705000C +#define CLKTAK 0x0705000D +#define CLKTLKCDT 0x0705000E +#define CLKTLK 0x0705000F +#define CLKTLK2CDT 0x07050010 +#define CLKTLK2 0x07050011 +#define CLKTLK3CDT 0x07050012 +#define CLKTLK3 0x07050013 +#define CLKTURNCDR 0x07050014 +#define CLKTURNCDT 0x07050015 +#define CLKTURN 0x07050016 +#define CLKWLKCDT 0x07050017 +#define CLKWLK 0x07050018 +#define CLKWLK2CDT 0x07050019 +#define CLKWLK2 0x0705001A +#define CLKWLK3CDT 0x0705001B +#define CLKWLK3 0x0705001C +#define CLKWULCDT 0x0705001D +#define CLKWUL 0x0705001E +#define GEOASC13CDT 0x0705001F +#define GEOASC13 0x07050020 +#define GEODES13CDT 0x07050021 +#define GEODES13 0x07050022 +#define GEOKEYCDT 0x07050023 +#define GEOKEY 0x07050024 +#define GEOKEY13CDT 0x07050025 +#define GEOKEY13 0x07050026 +#define GEOMAN13CDT 0x07050027 +#define GEOMAN13 0x07050028 +#define GEOTELCDT 0x07050029 +#define GEOTEL 0x0705002A +#define GEOTEL9CDT 0x0705002B +#define GEOTEL9 0x0705002C +#define KEY13CDT 0x0705002D +#define KEY13 0x0705002E +#define LATLUKCDR 0x0705002F +#define LATLUKCDT 0x07050030 +#define LATLUK 0x07050031 +#define LATRDSCDT 0x07050032 +#define LATRDS 0x07050033 +#define LATTLKCDT 0x07050034 +#define LATTLK 0x07050035 +#define PMTGIVCDT 0x07050036 +#define PMTGIV 0x07050037 +#define PMTPNOCDT 0x07050038 +#define PMTPNO 0x07050039 +#define PMTSTDCDT 0x0705003A +#define PMTSTD 0x0705003B +#define PMTTLKCDT 0x0705003C +#define PMTTLK 0x0705003D +#define PMTTLK8CDT 0x0705003E +#define PMTTLK8 0x0705003F +#define PMTTLK9CDT 0x07050040 +#define PMTTLK9 0x07050041 +#define PMTTOTLKCDR 0x07050042 +#define PMTTOTLKCDT 0x07050043 +#define PMTTOTLK 0x07050044 +#define PMTTURNCDR 0x07050045 +#define PMTTURNCDT 0x07050046 +#define PMTTURN 0x07050047 +#define PMTWLK1CDT 0x07050048 +#define PMTWLK1 0x07050049 +#define PMTWLK2CDT 0x0705004A +#define PMTWLK2 0x0705004B + // 76 entities in TXTs, 76 in datafiles. + // room14 +#define room14_PAL 0x07060000 +#define room14_l0 0x07060001 +#define room14_l1 0x07060002 +#define room14_gd1 0x07060003 +#define room14_flr 0x07060004 +#define GEOASC14CDT 0x07060005 +#define GEOASC14 0x07060006 +#define GEODES14CDT 0x07060007 +#define GEODES14 0x07060008 +#define GEODORCDR 0x07060009 +#define GEODORCDT 0x0706000A +#define GEODOR 0x0706000B + // 12 entities in TXTs, 12 in datafiles. + // room15 +#define room15_PAL 0x07070000 +#define room15_l0 0x07070001 +#define room15_l1 0x07070002 +#define room15_l2 0x07070003 +#define room15_gd1 0x07070004 +#define room15_gd2 0x07070005 +#define room15_flr 0x07070006 +#define DOROPN15CDT 0x07070007 +#define DOROPN15 0x07070008 +#define GEOBEDCDR 0x07070009 +#define GEOBEDCDT 0x0707000A +#define GEOBED 0x0707000B +#define GEODOR15CDT 0x0707000C +#define GEODOR15 0x0707000D +#define GEOENT15CDT 0x0707000E +#define GEOENT15 0x0707000F +#define GEOWIN1CDT 0x07070010 +#define GEOWIN1 0x07070011 +#define GEOWIN15CDT 0x07070012 +#define GEOWIN15 0x07070013 +#define GEOWIN2CDT 0x07070014 +#define GEOWIN2 0x07070015 +#define GEOWRBCDR 0x07070016 +#define GEOWRBCDT 0x07070017 +#define GEOWRB 0x07070018 +#define WINDOWCDT 0x07070019 +#define WINDOW 0x0707001A + // 27 entities in TXTs, 27 in datafiles. + // room16 +#define room16_PAL 0x07080000 +#define R16L0 0x07080001 +#define R16L1 0x07080002 +#define R16G1 0x07080003 +#define GEOILWCDT 0x07080004 +#define GEOILW 0x07080005 +#define GEOIRWCDT 0x07080006 +#define GEOIRW 0x07080007 +#define GEOMANLCDT 0x07080008 +#define GEOMANL 0x07080009 +#define GEOMANRCDT 0x0708000A +#define GEOMANR 0x0708000B +#define GEOMLWCDT 0x0708000C +#define GEOMLW 0x0708000D +#define GEOMRWCDT 0x0708000E +#define GEOMRW 0x0708000F +#define GEOOLWCDT 0x07080010 +#define GEOOLWCDR 0x07080011 +#define GEOOLW 0x07080012 +#define GEOORWCDT 0x07080013 +#define GEOORWCDR 0x07080014 +#define GEOORW 0x07080015 +#define MANLCDT 0x07080016 +#define MANL 0x07080017 +#define MANRCDT 0x07080018 +#define MANR 0x07080019 + // 26 entities in TXTs, 26 in datafiles. + // room17 +#define room17_PAL 0x07090000 +#define room17_l0 0x07090001 +#define room17_l1 0x07090002 +#define room17_l2 0x07090003 +#define room17_gd1 0x07090004 +#define room17_gd2 0x07090005 +#define room17_flr 0x07090006 +#define IBACK17 0x07090007 +#define IBACK17PAL 0x07090008 +#define GEOINQ17 0x07090009 +#define GEOINQ17CDT 0x0709000A +#define SBACK17 0x0709000B +#define SBACK17PAL 0x0709000C +#define GEOSUR17 0x0709000D +#define GEOSUR17CDT 0x0709000E +#define ASSTAIR2_PAL 0x0709000F +#define ASSTAIR2 0x07090010 +#define ASSTAIRCDT 0x07090011 +#define ASSTAIR 0x07090012 +#define ASSDORCDT 0x07090013 +#define ASSDOR 0x07090014 +#define ASSDOR2CDT 0x07090015 +#define ASSDOR2 0x07090016 +#define ASSTRWCDT 0x07090017 +#define ASSTRW 0x07090018 +#define ASSWRBCDT 0x07090019 +#define ASSWRB 0x0709001A +#define ASWLK17CDT 0x0709001B +#define ASWLK17 0x0709001C +#define BRFCASECDT 0x0709001D +#define BRFCASE 0x0709001E +#define GEOBCBCDR 0x0709001F +#define GEOBCBCDT 0x07090020 +#define GEOBCB 0x07090021 +#define GEOBED17CDT 0x07090022 +#define GEOBED17 0x07090023 +#define GEOBFCCDR 0x07090024 +#define GEOBFCCDT 0x07090025 +#define GEOBFC 0x07090026 +#define GEODOR17CDT 0x07090027 +#define GEODOR17 0x07090028 +#define GEODOR2CDR 0x07090029 +#define GEODOR2CDT 0x0709002A +#define GEODOR2 0x0709002B +#define GEOPANTSCDT 0x0709002C +#define GEOPANTS 0x0709002D +#define GEOWIN8CDT 0x0709002E +#define GEOWIN8 0x0709002F +#define GEOWIN9CDT 0x07090030 +#define GEOWIN9 0x07090031 +#define GEOWRB1CDR 0x07090032 +#define GEOWRB1CDT 0x07090033 +#define GEOWRB1 0x07090034 +#define GEOWRB2CDT 0x07090035 +#define GEOWRB2 0x07090036 +#define GEOWRB3CDR 0x07090037 +#define GEOWRB3CDT 0x07090038 +#define GEOWRB3 0x07090039 +#define GEOWRB4CDT 0x0709003A +#define GEOWRB4 0x0709003B +#define PANTS2CDT 0x0709003C +#define PANTS2 0x0709003D +#define PANTWRBCDT 0x0709003E +#define PANTWRB 0x0709003F +#define STATDOORCDT 0x07090040 +#define STATDOOR 0x07090041 +#define WRBDOR17CDT 0x07090042 +#define WRBDOR17 0x07090043 + // 68 entities in TXTs, 68 in datafiles. + // room18 +#define R18SPRPAL 0x070A0000 +#define room18_PAL 0x070A0001 +#define room18_l0 0x070A0002 +#define room18_l1 0x070A0003 +#define room18_l2 0x070A0004 +#define room18_gd1 0x070A0005 +#define room18_gd2 0x070A0006 +#define room18_flr 0x070A0007 +#define FAN18CDT 0x070A0008 +#define FAN18 0x070A0009 +#define GENBNDCDT 0x070A000A +#define GENBND 0x070A000B +#define GENSTRCDT 0x070A000C +#define GENSTR 0x070A000D +#define GENTLK18CDT 0x070A000E +#define GENTLK18 0x070A000F +#define GEOLVE18CDT 0x070A0010 +#define GEOLVE18 0x070A0011 +#define MOUBAK18CDT 0x070A0012 +#define MOUBAK18 0x070A0013 +#define MOUBUSYCDT 0x070A0014 +#define MOUBUSY 0x070A0015 +#define MOUTKROSCDT 0x070A0016 +#define MOUTKROS 0x070A0017 +#define MOUTLK18CDT 0x070A0018 +#define MOUTLK18 0x070A0019 +#define MOUWLK18CDT 0x070A001A +#define MOUWLK18 0x070A001B +#define ROSBAK18CDT 0x070A001C +#define ROSBAK18 0x070A001D +#define ROSBUSYCDT 0x070A001E +#define ROSBUSY 0x070A001F +#define ROSSTDCDT 0x070A0020 +#define ROSSTD 0x070A0021 +#define ROSTLK18CDT 0x070A0022 +#define ROSTLK18 0x070A0023 +#define ROSTLKXCDT 0x070A0024 +#define ROSTLKX 0x070A0025 +#define ROSTURNCDR 0x070A0026 +#define ROSTURNCDT 0x070A0027 +#define ROSTURN 0x070A0028 +#define ROSWLK18CDT 0x070A0029 +#define ROSWLK18 0x070A002A + // 43 entities in TXTs, 43 in datafiles. + // room46 +#define room46_PAL 0x070B0000 +#define room46_l0 0x070B0001 +#define room46_l1 0x070B0002 +#define room46_l2 0x070B0003 +#define room46_gd1 0x070B0004 +#define room46_gd2 0x070B0005 +#define room46_flr 0x070B0006 +#define MANU46CDT 0x070B0007 +#define MANU46 0x070B0008 + // 9 entities in TXTs, 9 in datafiles. +// paris_3 + // sound_fx +#define FX_MUESEXT 0x08000000 +#define FX_AIRCON28 0x08000001 +#define FX_SARCO28A 0x08000002 +#define FX_SARCO28B 0x08000003 +#define FX_SARCO28C 0x08000004 +#define FX_TOTEM28A 0x08000005 +#define FX_ALARM 0x08000006 +#define FX_CARABINE 0x08000007 +#define FX_DOOR29 0x08000008 +#define FX_FISHFALL 0x08000009 +#define FX_GDROP29 0x0800000A +#define FX_GUI_HIT 0x0800000B +#define FX_GUN1 0x0800000C +#define FX_ROPEDOWN 0x0800000D +#define FX_SARCO29 0x0800000E +#define FX_SMASHGLA 0x0800000F +#define FX_TOTEM29A 0x08000010 +#define FX_TOTEM29B 0x08000011 +#define FX_HOSPEXT 0x08000012 +#define FX_GRAVEL1 0x08000013 +#define FX_GRAVEL2 0x08000014 +#define FX_HOSPNOIS 0x08000015 +#define FX_CUPBOPEN 0x08000016 +#define FX_CUPBCLOS 0x08000017 +#define FX_KIKSHINY 0x08000018 +#define FX_SHINY 0x08000019 +#define FX_SHINYOFF 0x0800001A +#define FX_SHINYON 0x0800001B +#define FX_BLOODPRE 0x0800001C +#define FX_GUN34 0x0800001D +#define FX_PULSE2 0x0800001E +#define FX_PULSE3 0x0800001F + // 32 entities in TXTs, 32 in datafiles. + // benoir +#define MEGABEN 0x08010000 +#define BEN_WLK 0x08010001 +#define STDTAL1 0x08010002 +#define STDTAL1CDT 0x08010003 +#define STDTAL3 0x08010004 +#define STDTAL3CDT 0x08010005 +#define STDTAL5 0x08010006 +#define STDTAL5CDT 0x08010007 +#define XBENPG3 0x08010008 +#define XBENPG3CDT 0x08010009 +#define XBENPG5 0x0801000A +#define XBENPG5CDT 0x0801000B + // 12 entities in TXTs, 12 in datafiles. + // mus +#define MEGAMUS 0x08020000 +#define MUS_WLK 0x08020001 +#define MUSTLK0 0x08020002 +#define MUSTLK0CDT 0x08020003 +#define MUSTLK1 0x08020004 +#define MUSTLK1CDT 0x08020005 +#define MUSTLK2 0x08020006 +#define MUSTLK2CDT 0x08020007 +#define MUSTLK3 0x08020008 +#define MUSTLK3CDT 0x08020009 +#define MUSTLK4 0x0802000A +#define MUSTLK4CDT 0x0802000B +#define MUSTLK5 0x0802000C +#define MUSTLK5CDT 0x0802000D +#define MUSTLK6 0x0802000E +#define MUSTLK6CDT 0x0802000F +#define MUSTLK7 0x08020010 +#define MUSTLK7CDT 0x08020011 + // 18 entities in TXTs, 18 in datafiles. + // white +#define MEGA_WHITE 0x08030000 +#define WHTTLK0 0x08030001 +#define WHTTLK0CDT 0x08030002 +#define WHTTLK1 0x08030003 +#define WHTTLK1CDT 0x08030004 +#define WHTTLK2 0x08030005 +#define WHTTLK2CDT 0x08030006 +#define WHTTLK3 0x08030007 +#define WHTTLK3CDT 0x08030008 +#define WHTTLK4 0x08030009 +#define WHTTLK4CDT 0x0803000A +#define WHTTLK5 0x0803000B +#define WHTTLK5CDT 0x0803000C +#define WHTTLK6 0x0803000D +#define WHTTLK6CDT 0x0803000E +#define WHTTLK7 0x0803000F +#define WHTTLK7CDT 0x08030010 +#define WHTSHRUG 0x08030011 +#define WHTSHRUGCDT 0x08030012 +#define XGEOPG3 0x08030013 +#define XGEOPG3CDT 0x08030014 +#define XGEOPG5 0x08030015 +#define XGEOPG5CDT 0x08030016 + // 23 entities in TXTs, 23 in datafiles. + // room27 +#define PARIS3_PAL 0x08040000 +#define room27_PAL 0x08040001 +#define R27L0 0x08040002 +#define R27L1 0x08040003 +#define R27L2 0x08040004 +#define R27G1 0x08040005 +#define R27G2 0x08040006 +#define room27_flr 0x08040007 +#define GEOWIN27CDR 0x08040008 +#define GEOWIN27CDT 0x08040009 +#define GEOWIN27 0x0804000A + // 11 entities in TXTs, 11 in datafiles. + // room28 +#define R28SPRPAL 0x08050000 +#define R28PAL 0x08050001 +#define R28L0 0x08050002 +#define R28L1 0x08050003 +#define R28L2 0x08050004 +#define R28G1 0x08050005 +#define R28G2 0x08050006 +#define room28_flr 0x08050007 +#define GEOALMCDT 0x08050008 +#define GEOALM 0x08050009 +#define GEOSARCDT 0x0805000A +#define GEOSAR 0x0805000B +#define GEOSAR1CDT 0x0805000C +#define GEOSAR1 0x0805000D +#define GEOSAR2CDR 0x0805000E +#define GEOSAR2CDT 0x0805000F +#define GEOSAR2 0x08050010 +#define GEOSHK28CDT 0x08050011 +#define GEOSHK28 0x08050012 +#define GEOTOTCDT 0x08050013 +#define GEOTOT 0x08050014 +#define GEOWINCDT 0x08050015 +#define GEOWIN 0x08050016 +#define GUAWINCDT 0x08050017 +#define GUAWIN 0x08050018 +#define LOBEXITCDT 0x08050019 +#define LOBEXIT 0x0805001A +#define LOBMANCDT 0x0805001B +#define LOBMAN 0x0805001C +#define LOBSTUCDT 0x0805001D +#define LOBSTU 0x0805001E +#define LOBTLKCDT 0x0805001F +#define LOBTLK 0x08050020 +#define LOBTURN1CDT 0x08050021 +#define LOBTURN1 0x08050022 +#define LOBTURN2CDT 0x08050023 +#define LOBTURN2 0x08050024 +#define MUSOPNCDT 0x08050025 +#define MUSOPN 0x08050026 +#define SARDOR28CDT 0x08050027 +#define SARDOR28 0x08050028 +#define TOTEM28CDT 0x08050029 +#define TOTEM28 0x0805002A +#define TRIPOD28CDT 0x0805002B +#define TRIPOD28 0x0805002C +#define WINDO28CDR 0x0805002D +#define WINDO28CDT 0x0805002E +#define WINDO28 0x0805002F +#define WINROD28CDT 0x08050030 +#define WINROD28 0x08050031 + // 50 entities in TXTs, 50 in datafiles. + // room29 +#define R29SPRPAL 0x08060000 +#define BBACK29SPRPAL 0x08060001 +#define R29PAL 0x08060002 +#define R29L0 0x08060003 +#define R29L1 0x08060004 +#define R29G1 0x08060005 +#define room29_flr 0x08060006 +#define BBACK29 0x08060007 +#define BBACK29PAL 0x08060008 +#define GEOSUR29CDT 0x08060009 +#define GEOSUR29 0x0806000A +#define CASECDT 0x0806000B +#define CASE 0x0806000C +#define DOOR29CDT 0x0806000D +#define DOOR29 0x0806000E +#define FISH29CDT 0x0806000F +#define FISH29 0x08060010 +#define FLAPENTCDT 0x08060011 +#define FLAPENT 0x08060012 +#define FLAPTLK1CDT 0x08060013 +#define FLAPTLK1 0x08060014 +#define FLAPTLK3CDT 0x08060015 +#define FLAPTLK3 0x08060016 +#define FLAPTOR1CDR 0x08060017 +#define FLAPTOR1CDT 0x08060018 +#define FLAPTOR1 0x08060019 +#define FLAPTOR4CDT 0x0806001A +#define FLAPTOR4 0x0806001B +#define FLAPWLKCDT 0x0806001C +#define FLAPWLK 0x0806001D +#define GEODEDCDT 0x0806001E +#define GEODED 0x0806001F +#define GEOFISHCDT 0x08060020 +#define GEOFISH 0x08060021 +#define GEOFWDCDT 0x08060022 +#define GEOFWD 0x08060023 +#define GEOPEEKCDT 0x08060024 +#define GEOPEEK 0x08060025 +#define GEOSAR6CDT 0x08060026 +#define GEOSAR6 0x08060027 +#define GEOTOT29CDT 0x08060028 +#define GEOTOT29 0x08060029 +#define GEOTOTBCDT 0x0806002A +#define GEOTOTB 0x0806002B +#define GEOTPTOCDT 0x0806002C +#define GEOTPTO 0x0806002D +#define GUIENTCDT 0x0806002E +#define GUIENT 0x0806002F +#define GUIGUNCDT 0x08060030 +#define GUIGUN 0x08060031 +#define GUIKNECDT 0x08060032 +#define GUIKNE 0x08060033 +#define GUIKNE1CDT 0x08060034 +#define GUIKNE1 0x08060035 +#define GUITLK1CDT 0x08060036 +#define GUITLK1 0x08060037 +#define GUITLK3CDT 0x08060038 +#define GUITLK3 0x08060039 +#define GUITLK4CDT 0x0806003A +#define GUITLK4 0x0806003B +#define GUIWLKCDT 0x0806003C +#define GUIWLK 0x0806003D +#define NICPUS1CDT 0x0806003E +#define NICPUS1 0x0806003F +#define ROPE29CDT 0x08060040 +#define ROPE29 0x08060041 +#define SARDOORCDT 0x08060042 +#define SARDOOR 0x08060043 +#define TOR1CDT 0x08060044 +#define TOR1 0x08060045 +#define TOR3CDR 0x08060046 +#define TOR3CDT 0x08060047 +#define TOR3 0x08060048 +#define TOR4CDT 0x08060049 +#define TOR4 0x0806004A +#define TOR6CDT 0x0806004B +#define TOR6 0x0806004C +#define TOR7CDT 0x0806004D +#define TOR7 0x0806004E +#define TOTFALLCDT 0x0806004F +#define TOTFALL 0x08060050 + // 81 entities in TXTs, 81 in datafiles. + // room31 +#define room31_PAL 0x08070000 +#define room31_l0 0x08070001 +#define room31_flr 0x08070002 +#define GEOAMBCDT 0x08070003 +#define GEOAMB 0x08070004 +#define GEODOR31CDT 0x08070005 +#define GEODOR31 0x08070006 + // 7 entities in TXTs, 7 in datafiles. + // room32 +#define room32_PAL 0x08080000 +#define room32_l0 0x08080001 +#define room32_l1 0x08080002 +#define room32_l2 0x08080003 +#define room32_gd1 0x08080004 +#define room32_gd2 0x08080005 +#define room32_flr 0x08080006 +#define CONSTPCDT 0x08080007 +#define CONSTP 0x08080008 +#define CONTLKCDT 0x08080009 +#define CONTLK 0x0808000A +#define CONTLK2CDT 0x0808000B +#define CONTLK2 0x0808000C +#define CONWLKCDT 0x0808000D +#define CONWLK 0x0808000E +#define RECCOMCDT 0x0808000F +#define RECCOM 0x08080010 +#define RECKEYCDT 0x08080011 +#define RECKEY 0x08080012 +#define RECTLKCDT 0x08080013 +#define RECTLK 0x08080014 +#define RECTLK2CDT 0x08080015 +#define RECTLK2 0x08080016 +#define RECTRNCDT 0x08080017 +#define RECTRN 0x08080018 + // 25 entities in TXTs, 25 in datafiles. + // room33 +#define room33_PAL 0x08090000 +#define room33_l0 0x08090001 +#define room33_l1 0x08090002 +#define room33_l2 0x08090003 +#define room33_gd1 0x08090004 +#define room33_gd2 0x08090005 +#define room33_flr 0x08090006 +#define DOMDRNCDT 0x08090007 +#define DOMDRN 0x08090008 +#define DOMDUHCDT 0x08090009 +#define DOMDUH 0x0809000A +#define DOMKIKCDT 0x0809000B +#define DOMKIK 0x0809000C +#define DOMPLGCDT 0x0809000D +#define DOMPLG 0x0809000E +#define DOMTLKCDT 0x0809000F +#define DOMTLK 0x08090010 +#define DOMVACCDT 0x08090011 +#define DOMVAC 0x08090012 +#define DOMWLKCDT 0x08090013 +#define DOMWLK 0x08090014 +#define DOMWLK2CDT 0x08090015 +#define DOMWLK2 0x08090016 +#define DOMWLK3CDT 0x08090017 +#define DOMWLK3 0x08090018 +#define DOMWLK4CDT 0x08090019 +#define DOMWLK4 0x0809001A +#define GEOCOTCDT 0x0809001B +#define GEOCOT 0x0809001C +#define GEOPLG33CDT 0x0809001D +#define GEOPLG33 0x0809001E +#define GEOWATCDT 0x0809001F +#define GEOWAT 0x08090020 +#define GEOWWATCDT 0x08090021 +#define GEOWWAT 0x08090022 +#define LEAD1CDT 0x08090023 +#define LEAD1 0x08090024 +#define LEAD2CDT 0x08090025 +#define LEAD2 0x08090026 +#define SHINY33CDT 0x08090027 +#define SHINY33 0x08090028 + // 41 entities in TXTs, 41 in datafiles. + // room34 +#define room34_PAL 0x080A0000 +#define room34_l0 0x080A0001 +#define room34_l1 0x080A0002 +#define room34_l2 0x080A0003 +#define room34_l3 0x080A0004 +#define room34_gd1 0x080A0005 +#define room34_gd2 0x080A0006 +#define room34_gd3 0x080A0007 +#define room34_flr 0x080A0008 +#define R34PLX 0x080A0009 +#define BENBP1CDT 0x080A000A +#define BENBP1 0x080A000B +#define BENBP2CDT 0x080A000C +#define BENBP2 0x080A000D +#define DOOR34CDR 0x080A000E +#define DOOR34CDT 0x080A000F +#define DOOR34 0x080A0010 +#define GENDTLKCDT 0x080A0011 +#define GENDTLK 0x080A0012 +#define GENENTCDT 0x080A0013 +#define GENENT 0x080A0014 +#define GENSHOTCDT 0x080A0015 +#define GENSHOT 0x080A0016 +#define GENSTLKCDT 0x080A0017 +#define GENSTLK 0x080A0018 +#define GENSUPCDT 0x080A0019 +#define GENSUP 0x080A001A +#define GENTRNCDT 0x080A001B +#define GENTRN 0x080A001C +#define GEOBAKCDT 0x080A001D +#define GEOBAK 0x080A001E +#define GEOBP2CDT 0x080A001F +#define GEOBP2 0x080A0020 +#define GEOCH1CDR 0x080A0021 +#define GEOCH1CDT 0x080A0022 +#define GEOCH1 0x080A0023 +#define GEOCH2CDR 0x080A0024 +#define GEOCH2CDT 0x080A0025 +#define GEOCH2 0x080A0026 +#define GEOCH3CDR 0x080A0027 +#define GEOCH3CDT 0x080A0028 +#define GEOCH3 0x080A0029 +#define GEODOR34CDT 0x080A002A +#define GEODOR34 0x080A002B +#define GEOENT34CDT 0x080A002C +#define GEOENT34 0x080A002D +#define GEONURBPCDT 0x080A002E +#define GEONURBP 0x080A002F +#define GEOTAKCDT 0x080A0030 +#define GEOTAK 0x080A0031 +#define GEOTRYDCDT 0x080A0032 +#define GEOTRYD 0x080A0033 +#define GEOTRYTKCDT 0x080A0034 +#define GEOTRYTK 0x080A0035 +#define HATGIVCDT 0x080A0036 +#define HATGIV 0x080A0037 +#define HATSTPCDT 0x080A0038 +#define HATSTP 0x080A0039 +#define HATTLKCDT 0x080A003A +#define HATTLK 0x080A003B +#define HATWLKCDT 0x080A003C +#define HATWLK 0x080A003D +#define HATWLK2CDT 0x080A003E +#define HATWLK2 0x080A003F +#define MONITOR 0x080A0040 +#define MONITOR_PAL 0x080A0041 +#define PULSE1CDT 0x080A0042 +#define PULSE1 0x080A0043 +#define PULSE2CDT 0x080A0044 +#define PULSE2 0x080A0045 +#define PULSE3CDT 0x080A0046 +#define PULSE3 0x080A0047 +#define RENTLKCDT 0x080A0048 +#define RENTLK 0x080A0049 +#define SMARMCDR 0x080A004A +#define SMARMCDT 0x080A004B +#define SMARM 0x080A004C +#define SMSTPCDR 0x080A004D +#define SMSTPCDT 0x080A004E +#define SMSTP 0x080A004F +#define SMTALKCDT 0x080A0050 +#define SMTALK 0x080A0051 +#define SMTALK2CDT 0x080A0052 +#define SMTALK2 0x080A0053 +#define STUDENTCDT 0x080A0054 +#define STUDENT 0x080A0055 +#define STUDGIVCDT 0x080A0056 +#define STUDGIV 0x080A0057 +#define STUDMOVCDT 0x080A0058 +#define STUDMOV 0x080A0059 + // 90 entities in TXTs, 90 in datafiles. + // room35 +#define room35_PAL 0x080B0000 +#define room35_l0 0x080B0001 +#define room35_l1 0x080B0002 +#define room35_gd1 0x080B0003 +#define room35_flr 0x080B0004 +#define ALSHOCKCDT 0x080B0005 +#define ALSHOCK 0x080B0006 +#define CURFLATCDT 0x080B0007 +#define CURFLAT 0x080B0008 +#define EKLBED35CDT 0x080B0009 +#define EKLBED35 0x080B000A +#define EKLTLK35CDT 0x080B000B +#define EKLTLK35 0x080B000C +#define EKLWLK35CDT 0x080B000D +#define EKLWLK35 0x080B000E +#define GEORCT35CDT 0x080B000F +#define GEORCT35 0x080B0010 +#define GEOSIT35CDR 0x080B0011 +#define GEOSIT35CDT 0x080B0012 +#define GEOSIT35 0x080B0013 +#define GEOTLKCDT 0x080B0014 +#define GEOTLK 0x080B0015 +#define GEOTLK35CDT 0x080B0016 +#define GEOTLK35 0x080B0017 +#define GEOTRN35CDT 0x080B0018 +#define GEOTRN35 0x080B0019 +#define JAQTLK1CDT 0x080B001A +#define JAQTLK1 0x080B001B +#define JAQTLK2CDT 0x080B001C +#define JAQTLK2 0x080B001D + // 30 entities in TXTs, 30 in datafiles. +// paris_4 + // sound_fx +#define FX_COVDWN 0x09000000 +#define FX_KEYIN 0x09000001 +#define FX_MANOP36 0x09000002 +#define FX_MONTAMB 0x09000003 +#define FX_OOH 0x09000004 +#define FX_PULLUP36 0x09000005 +#define FX_REPLCE36 0x09000006 +#define FX_AMBIEN37 0x09000007 +#define FX_CHAIN37 0x09000008 +#define FX_CHAIN37B 0x09000009 +#define FX_DOOR37 0x0900000A +#define FX_HOLE37 0x0900000B +#define FX_KNOCK37 0x0900000C +#define FX_KNOCK37B 0x0900000D +#define FX_WINCH37 0x0900000E +#define FX_AIRCON41 0x0900000F +#define FX_FONEDN41 0x09000010 +#define FX_FONEUP41 0x09000011 +#define FX_PHONCALL 0x09000012 +#define FX_THERMO1 0x09000013 +#define FX_TAPDRIP 0x09000014 +#define FX_DRIER1 0x09000015 +#define FX_CHURCHFX 0x09000016 + // 23 entities in TXTs, 23 in datafiles. + // room36 +#define R36SPRPAL 0x09010000 +#define R36L0 0x09010001 +#define R36L1 0x09010002 +#define R36G1 0x09010003 +#define room36_PAL 0x09010004 +#define room36_flr 0x09010005 +#define R36PLX 0x09010006 +#define BAL36CDT 0x09010007 +#define BAL36 0x09010008 +#define CRO36APPCDT 0x09010009 +#define CRO36APP 0x0901000A +#define CRO36GEOCDT 0x0901000B +#define CRO36GEO 0x0901000C +#define CRO36IDLCDT 0x0901000D +#define CRO36IDL 0x0901000E +#define CRO36JUGCDT 0x0901000F +#define CRO36JUG 0x09010010 +#define CRO36UNICDT 0x09010011 +#define CRO36UNI 0x09010012 +#define GEN36DRICDT 0x09010013 +#define GEN36DRI 0x09010014 +#define GEN36FEHCDT 0x09010015 +#define GEN36FEH 0x09010016 +#define GEN36HURCDT 0x09010017 +#define GEN36HUR 0x09010018 +#define GEN36LEACDT 0x09010019 +#define GEN36LEA 0x0901001A +#define GEN36POICDR 0x0901001B +#define GEN36POICDT 0x0901001C +#define GEN36POI 0x0901001D +#define GEN36SPECDT 0x0901001E +#define GEN36SPE 0x0901001F +#define GEN36TALCDT 0x09010020 +#define GEN36TAL 0x09010021 +#define GEO36CLOCDT 0x09010022 +#define GEO36CLO 0x09010023 +#define GEO36ENTCDT 0x09010024 +#define GEO36ENT 0x09010025 +#define GEO36EXTCDT 0x09010026 +#define GEO36EXT 0x09010027 +#define GEO36JUGCDT 0x09010028 +#define GEO36JUG 0x09010029 +#define GEO36KNECDR 0x0901002A +#define GEO36KNECDT 0x0901002B +#define GEO36KNE 0x0901002C +#define GEO36LUKCDR 0x0901002D +#define GEO36LUKCDT 0x0901002E +#define GEO36LUK 0x0901002F +#define GEO36NOSCDT 0x09010030 +#define GEO36NOS 0x09010031 +#define GEO36OPECDT 0x09010032 +#define GEO36OPE 0x09010033 +#define GEO36POPCDT 0x09010034 +#define GEO36POP 0x09010035 +#define GEO36SHOCDR 0x09010036 +#define GEO36SHOCDT 0x09010037 +#define GEO36SHO 0x09010038 +#define GEO36SNTCDT 0x09010039 +#define GEO36SNT 0x0901003A +#define GEO36STDCDT 0x0901003B +#define GEO36STD 0x0901003C +#define GEO36STUCDT 0x0901003D +#define GEO36STU 0x0901003E +#define GEO36TAKCDT 0x0901003F +#define GEO36TAK 0x09010040 +#define HAT36CDT 0x09010041 +#define HAT36 0x09010042 +#define JUG36FINCDT 0x09010043 +#define JUG36FIN 0x09010044 +#define JUG36FURCDT 0x09010045 +#define JUG36FUR 0x09010046 +#define JUG36GIVCDT 0x09010047 +#define JUG36GIV 0x09010048 +#define JUG36GOCDT 0x09010049 +#define JUG36GO 0x0901004A +#define JUG36JUGCDT 0x0901004B +#define JUG36JUG 0x0901004C +#define JUG36LAFCDT 0x0901004D +#define JUG36LAF 0x0901004E +#define JUG36STACDT 0x0901004F +#define JUG36STA 0x09010050 +#define JUG36TAKCDT 0x09010051 +#define JUG36TAK 0x09010052 +#define JUG36TALCDT 0x09010053 +#define JUG36TAL 0x09010054 +#define MANCOV36CDT 0x09010055 +#define MANCOV36 0x09010056 +#define MANOFF36CDT 0x09010057 +#define MANOFF36 0x09010058 +#define VIN36CDT 0x09010059 +#define VIN36 0x0901005A + // 91 entities in TXTs, 91 in datafiles. + // room37 +#define room37_PAL 0x09020000 +#define R37L0 0x09020001 +#define R37L1 0x09020002 +#define R37G1 0x09020003 +#define room37_flr 0x09020004 +#define DOR37COLCDT 0x09020005 +#define DOR37COL 0x09020006 +#define GEO37ASCCDT 0x09020007 +#define GEO37ASC 0x09020008 +#define GEO37COGCDT 0x09020009 +#define GEO37COG 0x0902000A +#define GEO37DESCDT 0x0902000B +#define GEO37DES 0x0902000C +#define GEO37HUKCDR 0x0902000D +#define GEO37HUKCDT 0x0902000E +#define GEO37HUK 0x0902000F +#define GEO37INBCDT 0x09020010 +#define GEO37INB 0x09020011 +#define GEO37LEVCDT 0x09020012 +#define GEO37LEV 0x09020013 +#define GEO37OUTCDT 0x09020014 +#define GEO37OUT 0x09020015 +#define GEO37RUNCDT 0x09020016 +#define GEO37RUN 0x09020017 +#define GEO37TA1CDT 0x09020018 +#define GEO37TA1 0x09020019 +#define GEO37TA2CDT 0x0902001A +#define GEO37TA2 0x0902001B +#define GEO37TA3CDT 0x0902001C +#define GEO37TA3 0x0902001D +#define GEO37TA4CDT 0x0902001E +#define GEO37TA4 0x0902001F +#define GEO37TU1CDR 0x09020020 +#define GEO37TU1CDT 0x09020021 +#define GEO37TU1 0x09020022 +#define GEO37TU2CDT 0x09020023 +#define GEO37TU2 0x09020024 +#define GEO37WLCDR 0x09020025 +#define GEO37WLCDT 0x09020026 +#define GEO37WL 0x09020027 +#define HOO37LBOCDR 0x09020028 +#define HOO37LBOCDT 0x09020029 +#define HOO37LBO 0x0902002A +#define HOO37PULCDT 0x0902002B +#define HOO37PUL 0x0902002C +#define ROCKS1CDT 0x0902002D +#define ROCKS1 0x0902002E +#define WAL37BRECDT 0x0902002F +#define WAL37BRE 0x09020030 +#define WAL37SLICDT 0x09020031 +#define WAL37SLI 0x09020032 +#define WATER37CDT 0x09020033 +#define WATER37 0x09020034 +#define WATER37ACDT 0x09020035 +#define WATER37A 0x09020036 +#define WHEEL37CDT 0x09020037 +#define WHEEL37 0x09020038 + // 57 entities in TXTs, 57 in datafiles. + // room38 +#define R38SPRPAL 0x09030000 +#define room38_PAL 0x09030001 +#define R38L0 0x09030002 +#define R38L1 0x09030003 +#define R38G1 0x09030004 +#define room38_flr 0x09030005 +#define BBACK38 0x09030006 +#define BBACK38PAL 0x09030007 +#define GEOINQ38CDT 0x09030008 +#define GEOINQ38 0x09030009 +#define GEO38AS1CDT 0x0903000A +#define GEO38AS1 0x0903000B +#define GEO38AS2CDT 0x0903000C +#define GEO38AS2 0x0903000D +#define GEO38DE1CDT 0x0903000E +#define GEO38DE1 0x0903000F +#define GEO38DE2CDT 0x09030010 +#define GEO38DE2 0x09030011 +#define GEO38LUKCDR 0x09030012 +#define GEO38LUKCDT 0x09030013 +#define GEO38LUK 0x09030014 + // 21 entities in TXTs, 21 in datafiles. + // room39 +#define R39SPRPAL 0x09040000 +#define R39L0 0x09040001 +#define R39L1 0x09040002 +#define R39G1 0x09040003 +#define room39_PAL 0x09040004 +#define room39_flr 0x09040005 +#define R39PLX 0x09040006 +#define BOA39GOACDT 0x09040007 +#define BOA39GOA 0x09040008 +#define BOA39SPRCDT 0x09040009 +#define BOA39SPR 0x0904000A +#define CIV391T2CDR 0x0904000B +#define CIV391T2CDT 0x0904000C +#define CIV391T2 0x0904000D +#define CIV391T3CDR 0x0904000E +#define CIV391T3CDT 0x0904000F +#define CIV391T3 0x09040010 +#define CIV392T3CDR 0x09040011 +#define CIV392T3CDT 0x09040012 +#define CIV392T3 0x09040013 +#define CIV39T1CDT 0x09040014 +#define CIV39T1 0x09040015 +#define CIV39T2CDT 0x09040016 +#define CIV39T2 0x09040017 +#define CIV39T3CDT 0x09040018 +#define CIV39T3 0x09040019 +#define CIVLIST1CDT 0x0904001A +#define CIVLIST1 0x0904001B +#define CIVLIST2CDT 0x0904001C +#define CIVLIST2 0x0904001D +#define CIVLIST3CDT 0x0904001E +#define CIVLIST3 0x0904001F +#define COL391T2CDR 0x09040020 +#define COL391T2CDT 0x09040021 +#define COL391T2 0x09040022 +#define COL391T3CDR 0x09040023 +#define COL391T3CDT 0x09040024 +#define COL391T3 0x09040025 +#define COL392T3CDR 0x09040026 +#define COL392T3CDT 0x09040027 +#define COL392T3 0x09040028 +#define COL39T1CDT 0x09040029 +#define COL39T1 0x0904002A +#define COL39T2CDT 0x0904002B +#define COL39T2 0x0904002C +#define COL39T3CDT 0x0904002D +#define COL39T3 0x0904002E +#define COLLIST2CDT 0x0904002F +#define COLLIST2 0x09040030 +#define COLLIST3CDT 0x09040031 +#define COLLIST3 0x09040032 +#define CON39TALCDT 0x09040033 +#define CON39TAL 0x09040034 +#define EKL391T2CDR 0x09040035 +#define EKL391T2CDT 0x09040036 +#define EKL391T2 0x09040037 +#define EKL391T3CDR 0x09040038 +#define EKL391T3CDT 0x09040039 +#define EKL391T3 0x0904003A +#define EKL392T3CDR 0x0904003B +#define EKL392T3CDT 0x0904003C +#define EKL392T3 0x0904003D +#define EKL39T1CDT 0x0904003E +#define EKL39T1 0x0904003F +#define EKL39T2CDT 0x09040040 +#define EKL39T2 0x09040041 +#define EKL39T3CDT 0x09040042 +#define EKL39T3 0x09040043 +#define EKLLIST1CDT 0x09040044 +#define EKLLIST1 0x09040045 +#define EKLLIST2CDT 0x09040046 +#define EKLLIST2 0x09040047 +#define EKLLIST3CDT 0x09040048 +#define EKLLIST3 0x09040049 +#define EXE391T2CDR 0x0904004A +#define EXE391T2CDT 0x0904004B +#define EXE391T2 0x0904004C +#define EXE391T3CDR 0x0904004D +#define EXE391T3CDT 0x0904004E +#define EXE391T3 0x0904004F +#define EXE392T3CDR 0x09040050 +#define EXE392T3CDT 0x09040051 +#define EXE392T3 0x09040052 +#define EXE39T1CDT 0x09040053 +#define EXE39T1 0x09040054 +#define EXE39T2CDT 0x09040055 +#define EXE39T2 0x09040056 +#define EXE39T3CDT 0x09040057 +#define EXE39T3 0x09040058 +#define GEO39ENTCDT 0x09040059 +#define GEO39ENT 0x0904005A +#define GEO39EXTCDT 0x0904005B +#define GEO39EXT 0x0904005C +#define GEO39GEMCDR 0x0904005D +#define GEO39GEMCDT 0x0904005E +#define GEO39GEM 0x0904005F +#define GEO39TRICDR 0x09040060 +#define GEO39TRICDT 0x09040061 +#define GEO39TRI 0x09040062 +#define LAT391T2CDR 0x09040063 +#define LAT391T2CDT 0x09040064 +#define LAT391T2 0x09040065 +#define LAT391T3CDR 0x09040066 +#define LAT391T3CDT 0x09040067 +#define LAT391T3 0x09040068 +#define LAT392T3CDR 0x09040069 +#define LAT392T3CDT 0x0904006A +#define LAT392T3 0x0904006B +#define LAT39T1CDT 0x0904006C +#define LAT39T1 0x0904006D +#define LAT39T2CDT 0x0904006E +#define LAT39T2 0x0904006F +#define LAT39T3CDT 0x09040070 +#define LAT39T3 0x09040071 +#define LATLIST1CDT 0x09040072 +#define LATLIST1 0x09040073 +#define LATLIST2CDT 0x09040074 +#define LATLIST2 0x09040075 +#define LATLIST3CDT 0x09040076 +#define LATLIST3 0x09040077 +#define MAS391T2CDR 0x09040078 +#define MAS391T2CDT 0x09040079 +#define MAS391T2 0x0904007A +#define MAS391T3CDR 0x0904007B +#define MAS391T3CDT 0x0904007C +#define MAS391T3 0x0904007D +#define MAS392T3CDR 0x0904007E +#define MAS392T3CDT 0x0904007F +#define MAS392T3 0x09040080 +#define MAS39T1CDT 0x09040081 +#define MAS39T1 0x09040082 +#define MAS39T2CDT 0x09040083 +#define MAS39T2 0x09040084 +#define MAS39T3CDT 0x09040085 +#define MAS39T3 0x09040086 +#define MASLIST1CDT 0x09040087 +#define MASLIST1 0x09040088 +#define MASLIST2CDT 0x09040089 +#define MASLIST2 0x0904008A +#define MASLIST3CDT 0x0904008B +#define MASLIST3 0x0904008C +#define RAYS39CDT 0x0904008D +#define RAYS39 0x0904008E +#define TRI39ALOCDT 0x0904008F +#define TRI39ALO 0x09040090 +#define TRI39GEMCDT 0x09040091 +#define TRI39GEM 0x09040092 + // 147 entities in TXTs, 147 in datafiles. + // room40 +#define R40L0 0x09050000 +#define room40_PAL 0x09050001 +#define room40_flr 0x09050002 +#define GEO40ASCCDT 0x09050003 +#define GEO40ASC 0x09050004 +#define GEO40DESCDT 0x09050005 +#define GEO40DES 0x09050006 +#define GEO40DIPCDT 0x09050007 +#define GEO40DIP 0x09050008 +#define GUA40ENTCDT 0x09050009 +#define GUA40ENT 0x0905000A +#define GUA40STACDT 0x0905000B +#define GUA40STA 0x0905000C +#define GUA40TALCDT 0x0905000D +#define GUA40TAL 0x0905000E +#define PAI40FAGCDT 0x0905000F +#define PAI40FAG 0x09050010 +#define PAI40IDLCDT 0x09050011 +#define PAI40IDL 0x09050012 +#define PAI40LEACDT 0x09050013 +#define PAI40LEA 0x09050014 +#define PAI40STACDR 0x09050015 +#define PAI40STACDT 0x09050016 +#define PAI40STA 0x09050017 +#define PAI40TALCDT 0x09050018 +#define PAI40TAL 0x09050019 + // 26 entities in TXTs, 26 in datafiles. + // room41 +#define R41L0 0x09060000 +#define R41L1 0x09060001 +#define R41G1 0x09060002 +#define room41_PAL 0x09060003 +#define room41_flr 0x09060004 +#define GEO41ENTCDT 0x09060005 +#define GEO41ENT 0x09060006 +#define GEO41OP2CDT 0x09060007 +#define GEO41OP2 0x09060008 +#define GEO41OPECDT 0x09060009 +#define GEO41OPE 0x0906000A +#define GEO41THECDR 0x0906000B +#define GEO41THECDT 0x0906000C +#define GEO41THE 0x0906000D +#define GLO41IDLCDT 0x0906000E +#define GLO41IDL 0x0906000F +#define GLO41KEYCDR 0x09060010 +#define GLO41KEYCDT 0x09060011 +#define GLO41KEY 0x09060012 +#define GLO41TALCDT 0x09060013 +#define GLO41TAL 0x09060014 +#define GUA41ANSCDT 0x09060015 +#define GUA41ANS 0x09060016 +#define GUA41GLOCDT 0x09060017 +#define GUA41GLO 0x09060018 +#define GUA41IDLCDT 0x09060019 +#define GUA41IDL 0x0906001A +#define GUA41KEYCDR 0x0906001B +#define GUA41KEYCDT 0x0906001C +#define GUA41KEY 0x0906001D +#define GUA41PHOCDT 0x0906001E +#define GUA41PHO 0x0906001F +#define GUA41TALCDT 0x09060020 +#define GUA41TAL 0x09060021 +#define PAI41HANCDT 0x09060022 +#define PAI41HAN 0x09060023 +#define PAI41LEACDT 0x09060024 +#define PAI41LEA 0x09060025 +#define PAI41TALCDT 0x09060026 +#define PAI41TAL 0x09060027 +#define PHONE41CDT 0x09060028 +#define PHONE41 0x09060029 + // 42 entities in TXTs, 42 in datafiles. + // room42 +#define room42_PAL 0x09070000 +#define R42L0 0x09070001 +#define R42L1 0x09070002 +#define R42L2 0x09070003 +#define R42G1 0x09070004 +#define R42G2 0x09070005 +#define room42_flr 0x09070006 +#define CHALICE42 0x09070007 +#define CHALICE42_PAL 0x09070008 +#define GEO42CHACDT 0x09070009 +#define GEO42CHA 0x0907000A +#define GEO42DESCDR 0x0907000B +#define GEO42DESCDT 0x0907000C +#define GEO42DES 0x0907000D + // 14 entities in TXTs, 14 in datafiles. + // room43 +#define room43_PAL 0x09080000 +#define R43L0 0x09080001 +#define R43L1 0x09080002 +#define R43G1 0x09080003 +#define room43_flr 0x09080004 +#define GEO43DR2CDT 0x09080005 +#define GEO43DR2 0x09080006 +#define GEO43DRYCDT 0x09080007 +#define GEO43DRY 0x09080008 +#define GEO43HAN 0x09080009 +#define GEO43HANCDT 0x0908000A +#define GEO43KEYCDT 0x0908000B +#define GEO43KEY 0x0908000C +#define GEO43PLACDT 0x0908000D +#define GEO43PLA 0x0908000E +#define GEO43PRECDT 0x0908000F +#define GEO43PRE 0x09080010 +#define GEO43SOACDT 0x09080011 +#define GEO43SOA 0x09080012 +#define GEO43SWPCDT 0x09080013 +#define GEO43SWP 0x09080014 +#define GEO43WATCDT 0x09080015 +#define GEO43WAT 0x09080016 +#define SOAP43CDT 0x09080017 +#define SOAP43 0x09080018 +#define WATER43CDT 0x09080019 +#define WATER43 0x0908001A + // 27 entities in TXTs, 27 in datafiles. + // room48 +#define R48SPRPAL 0x09090000 +#define R48L0 0x09090001 +#define R48L1 0x09090002 +#define R48L2 0x09090003 +#define R48G1 0x09090004 +#define R48G2 0x09090005 +#define R48PAL 0x09090006 +#define room48_flr 0x09090007 +#define R48PLX 0x09090008 +#define GEO48BENCDR 0x09090009 +#define GEO48BENCDT 0x0909000A +#define GEO48BEN 0x0909000B +#define GEO48GIVCDR 0x0909000C +#define GEO48GIVCDT 0x0909000D +#define GEO48GIV 0x0909000E +#define GEO48LENCDT 0x0909000F +#define GEO48LEN 0x09090010 +#define PRI48CANCDR 0x09090011 +#define PRI48CANCDT 0x09090012 +#define PRI48CAN 0x09090013 +#define PRI48IDLCDT 0x09090014 +#define PRI48IDL 0x09090015 +#define PRI48PO1CDT 0x09090016 +#define PRI48PO1 0x09090017 +#define PRI48PO2CDT 0x09090018 +#define PRI48PO2 0x09090019 +#define PRI48RETCDT 0x0909001A +#define PRI48RET 0x0909001B +#define PRI48TAKCDT 0x0909001C +#define PRI48TAK 0x0909001D +#define PRI48TALCDT 0x0909001E +#define PRI48TAL 0x0909001F +#define PRI48TURCDR 0x09090020 +#define PRI48TURCDT 0x09090021 +#define PRI48TUR 0x09090022 +#define WINDOW1 0x09090023 +#define WINDOW1_PAL 0x09090024 +#define WINDOW2 0x09090025 +#define WINDOW2_PAL 0x09090026 + // 39 entities in TXTs, 39 in datafiles. +// ireland + // sound_fx +#define FX_EIRBIRD3 0x0A000000 +#define FX_SHOCK2 0x0A000001 +#define FX_EIRBIRD1 0x0A000002 +#define FX_EIRBIRD2 0x0A000003 +#define FX_SWITCH19 0x0A000004 +#define FX_TRAPOPEN 0x0A000005 +#define FX_VIOLIN19 0x0A000006 +#define FX_WHISTLE 0x0A000007 +#define FX_BARFLAP 0x0A000008 +#define FX_DORCLOSE20 0x0A000009 +#define FX_DRINK 0x0A00000A +#define FX_FITZHIT 0x0A00000B +#define FX_FITZRUN 0x0A00000C +#define FX_FITZUP 0x0A00000D +#define FX_FUSE20 0x0A00000E +#define FX_PULLPINT 0x0A00000F +#define FX_SNEEZE1 0x0A000010 +#define FX_SNEEZE2 0x0A000011 +#define FX_WASHER 0x0A000012 +#define FX_CELTAP 0x0A000013 +#define FX_DRIPIRE 0x0A000014 +#define FX_DRIPIRE2 0x0A000015 +#define FX_TAP 0x0A000016 +#define FX_TAP2 0x0A000017 +#define FX_CLIMBHAY 0x0A000018 +#define FX_FARMERGO 0x0A000019 +#define FX_CASTLWAL 0x0A00001A +#define FX_CLIMBFAL 0x0A00001B +#define FX_KEYSTEP 0x0A00001C +#define FX_WIND 0x0A00001D +#define FX_GEOGOAT 0x0A00001E +#define FX_GOATBAA 0x0A00001F +#define FX_GOATCHEW 0x0A000020 +#define FX_GOATDOH 0x0A000021 +#define FX_PLOUGH 0x0A000022 +#define FX_EIRDRIP1 0x0A000023 +#define FX_EIRDRIP2 0x0A000024 +#define FX_LADDWN25 0x0A000025 +#define FX_LADDUP25 0x0A000026 +#define FX_SECDOR25 0x0A000027 +#define FX_SLABFALL 0x0A000028 +#define FX_SLABUP 0x0A000029 +#define FX_TRIGER25 0x0A00002A +#define FX_WRING 0x0A00002B +#define FX_LEVER 0x0A00002C +#define FX_LEVER2 0x0A00002D +#define FX_RAT3A 0x0A00002E +#define FX_RAT3B 0x0A00002F +#define FX_RAT3C 0x0A000030 +#define FX_RAT3D 0x0A000031 + // 50 entities in TXTs, 50 in datafiles. + // room19 +#define R19SPRPAL 0x0A010000 +#define R19L0 0x0A010001 +#define R19L1 0x0A010002 +#define R19L2 0x0A010003 +#define R19G1 0x0A010004 +#define R19G2 0x0A010005 +#define R19PAL 0x0A010006 +#define R19FLR 0x0A010007 +#define ASSTAP 0x0A010008 +#define ASSTAPCDT 0x0A010009 +#define ASSTLK19 0x0A01000A +#define ASSTLK19CDT 0x0A01000B +#define ASSWLK2 0x0A01000C +#define ASSWLK2CDT 0x0A01000D +#define ASSWLK6 0x0A01000E +#define ASSWLK6CDT 0x0A01000F +#define BOXCVR 0x0A010010 +#define BOXCVRCDT 0x0A010011 +#define GEODRN 0x0A010012 +#define GEODRNCDT 0x0A010013 +#define GEOMAG 0x0A010014 +#define GEOMAGCDT 0x0A010015 +#define GEORCT 0x0A010016 +#define GEORCTCDT 0x0A010017 +#define GEOTRP 0x0A010018 +#define GEOTRPCDT 0x0A010019 +#define GEOTRP8 0x0A01001A +#define GEOTRP8CDT 0x0A01001B +#define GEOWRN 0x0A01001C +#define GEOWRNCDT 0x0A01001D +#define LID19 0x0A01001E +#define LID19CDT 0x0A01001F +#define MAGCON 0x0A010020 +#define MAGCONCDT 0x0A010021 +#define MAGCONCDR 0x0A010022 +#define MAGMOV 0x0A010023 +#define MAGMOVCDT 0x0A010024 +#define MAGMOVCDR 0x0A010025 +#define MAGSHK 0x0A010026 +#define MAGSHKCDT 0x0A010027 +#define MAGSHY 0x0A010028 +#define MAGSHYCDT 0x0A010029 +#define MAGSHYCDR 0x0A01002A +#define MAGSLK 0x0A01002B +#define MAGSLKCDT 0x0A01002C +#define MAGTALK 0x0A01002D +#define MAGTALKCDT 0x0A01002E +#define MAGTLK 0x0A01002F +#define MAGTLKCDT 0x0A010030 +#define MAGTLK8 0x0A010031 +#define MAGTLK8CDT 0x0A010032 +#define TRPOPN 0x0A010033 +#define TRPOPNCDT 0x0A010034 + // 53 entities in TXTs, 53 in datafiles. + // room20 +#define R20SPRPAL 0x0A020000 +#define R20L0 0x0A020001 +#define R20L1 0x0A020002 +#define R20L2 0x0A020003 +#define R20L3 0x0A020004 +#define R20G1 0x0A020005 +#define R20G2 0x0A020006 +#define R20G3 0x0A020007 +#define R20PAL 0x0A020008 +#define R20FLR 0x0A020009 +#define BARTPS 0x0A02000A +#define BARTPSCDT 0x0A02000B +#define BARTWL 0x0A02000C +#define BARTWLCDT 0x0A02000D +#define BRIDRN 0x0A02000E +#define BRIDRNCDT 0x0A02000F +#define BRIDRNCDR 0x0A020010 +#define BRIFTZ 0x0A020011 +#define BRIFTZCDT 0x0A020012 +#define BRIFTZCDR 0x0A020013 +#define BRITLK 0x0A020014 +#define BRITLKCDT 0x0A020015 +#define BRITLK8 0x0A020016 +#define BRITLK8CDT 0x0A020017 +#define BRITLK9 0x0A020018 +#define BRITLK9CDT 0x0A020019 +#define BRITRN 0x0A02001A +#define BRITRNCDT 0x0A02001B +#define BRITRNCDR 0x0A02001C +#define DOROPN20 0x0A02001D +#define DOROPN20CDT 0x0A02001E +#define DOROPN20CDR 0x0A02001F +#define DOYDRN 0x0A020020 +#define DOYDRNCDT 0x0A020021 +#define DOYDRNCDR 0x0A020022 +#define DOYFTZ 0x0A020023 +#define DOYFTZCDT 0x0A020024 +#define DOYFTZCDR 0x0A020025 +#define DOYTLK 0x0A020026 +#define DOYTLKCDT 0x0A020027 +#define DOYTLK20 0x0A020028 +#define DOYTLK20CDT 0x0A020029 +#define DOYTLK8 0x0A02002A +#define DOYTLK8CDT 0x0A02002B +#define DOYTLK9 0x0A02002C +#define DOYTLK9CDT 0x0A02002D +#define DOYTRN 0x0A02002E +#define DOYTRNCDT 0x0A02002F +#define DOYTRNCDR 0x0A020030 +#define DOYTRN20 0x0A020031 +#define DOYTRN20CDT 0x0A020032 +#define DOYTRN20CDR 0x0A020033 +#define DOYTRN8 0x0A020034 +#define DOYTRN8CDT 0x0A020035 +#define DOYTRN8CDR 0x0A020036 +#define DOYTRN9 0x0A020037 +#define DOYTRN9CDT 0x0A020038 +#define DOYTRN9CDR 0x0A020039 +#define FIDPLY 0x0A02003A +#define FIDPLYCDT 0x0A02003B +#define FLPOPN 0x0A02003C +#define FLPOPNCDT 0x0A02003D +#define FRMTLK20 0x0A02003E +#define FRMTLK20CDT 0x0A02003F +#define FTZAGT 0x0A020040 +#define FTZAGTCDT 0x0A020041 +#define FTZGET 0x0A020042 +#define FTZGETCDT 0x0A020043 +#define FTZGETCDR 0x0A020044 +#define FTZRUN 0x0A020045 +#define FTZRUNCDT 0x0A020046 +#define FTZSTD 0x0A020047 +#define FTZSTDCDT 0x0A020048 +#define FTZTALK 0x0A020049 +#define FTZTALKCDT 0x0A02004A +#define FTZTLK 0x0A02004B +#define FTZTLKCDT 0x0A02004C +#define FTZTLK8 0x0A02004D +#define FTZTLK8CDT 0x0A02004E +#define GEODRN20 0x0A02004F +#define GEODRN20CDT 0x0A020050 +#define GEOPHN20 0x0A020051 +#define GEOPHN20CDT 0x0A020052 +#define GEOPHN20CDR 0x0A020053 +#define GEOPLG 0x0A020054 +#define GEOPLGCDT 0x0A020055 +#define GEOPLG8 0x0A020056 +#define GEOPLG8CDT 0x0A020057 +#define GEOSEE 0x0A020058 +#define GEOSEECDT 0x0A020059 +#define GEOSNR 0x0A02005A +#define GEOSNRCDT 0x0A02005B +#define GEOSNR8 0x0A02005C +#define GEOSNR8CDT 0x0A02005D +#define GEOTWL20 0x0A02005E +#define GEOTWL20CDT 0x0A02005F +#define GEOXIT20 0x0A020060 +#define GEOXIT20CDT 0x0A020061 +#define GLSGEO 0x0A020062 +#define GLSGEOCDT 0x0A020063 +#define GLSWSH 0x0A020064 +#define GLSWSHCDT 0x0A020065 +#define LESDOR 0x0A020066 +#define LESDORCDT 0x0A020067 +#define LESDOY 0x0A020068 +#define LESDOYCDT 0x0A020069 +#define LESFLP 0x0A02006A +#define LESFLPCDT 0x0A02006B +#define LESFTZ 0x0A02006C +#define LESFTZCDT 0x0A02006D +#define LESFTZCDR 0x0A02006E +#define LESGLS 0x0A02006F +#define LESGLSCDT 0x0A020070 +#define LESGLSCDR 0x0A020071 +#define LESLNS 0x0A020072 +#define LESLNSCDT 0x0A020073 +#define LESLNSCDR 0x0A020074 +#define LESMOV 0x0A020075 +#define LESMOVCDT 0x0A020076 +#define LESMOVCDR 0x0A020077 +#define LESPMP 0x0A020078 +#define LESPMPCDT 0x0A020079 +#define LESPNT 0x0A02007A +#define LESPNTCDT 0x0A02007B +#define LESPNT20 0x0A02007C +#define LESPNT20CDT 0x0A02007D +#define LESPNT8 0x0A02007E +#define LESPNT8CDT 0x0A02007F +#define LESPNT8CDR 0x0A020080 +#define LESTALK 0x0A020081 +#define LESTALKCDT 0x0A020082 +#define LESTLK 0x0A020083 +#define LESTLKCDT 0x0A020084 +#define LESTLK20 0x0A020085 +#define LESTLK20CDT 0x0A020086 +#define LESTLK8 0x0A020087 +#define LESTLK8CDT 0x0A020088 +#define LESTLK9 0x0A020089 +#define LESTLK9CDT 0x0A02008A +#define LESTURN 0x0A02008B +#define LESTURNCDT 0x0A02008C +#define LESTURNCDR 0x0A02008D +#define LESWLK 0x0A02008E +#define LESWLKCDT 0x0A02008F +#define LESWLK8 0x0A020090 +#define LESWLK8CDT 0x0A020091 +#define LESWSH 0x0A020092 +#define LESWSHCDT 0x0A020093 +#define LESWSHCDR 0x0A020094 +#define MAGENT 0x0A020095 +#define MAGENTCDT 0x0A020096 +#define MAGEXIT 0x0A020097 +#define MAGEXITCDT 0x0A020098 +#define MAGMOV20 0x0A020099 +#define MAGMOV20CDT 0x0A02009A +#define MAGTEST 0x0A02009B +#define MAGTESTCDT 0x0A02009C +#define MAGTLK20 0x0A02009D +#define MAGTLK20CDT 0x0A02009E +#define PLGWLL 0x0A02009F +#define PLGWLLCDT 0x0A0200A0 +#define RONDRN 0x0A0200A1 +#define RONDRNCDT 0x0A0200A2 +#define RONDRNCDR 0x0A0200A3 +#define RONDRP 0x0A0200A4 +#define RONDRPCDT 0x0A0200A5 +#define RONFTZ 0x0A0200A6 +#define RONFTZCDT 0x0A0200A7 +#define RONFTZCDR 0x0A0200A8 +#define RONGEO 0x0A0200A9 +#define RONGEOCDT 0x0A0200AA +#define RONGEOCDR 0x0A0200AB +#define RONGLS 0x0A0200AC +#define RONGLSCDT 0x0A0200AD +#define RONGLSCDR 0x0A0200AE +#define RONGLS8 0x0A0200AF +#define RONGLS8CDT 0x0A0200B0 +#define RONPIK 0x0A0200B1 +#define RONPIKCDT 0x0A0200B2 +#define RONPKT 0x0A0200B3 +#define RONPKTCDT 0x0A0200B4 +#define RONPKTCDR 0x0A0200B5 +#define RONSNR 0x0A0200B6 +#define RONSNRCDT 0x0A0200B7 +#define RONSNZ 0x0A0200B8 +#define RONSNZCDT 0x0A0200B9 +#define RONSNZ2 0x0A0200BA +#define RONSNZ2CDT 0x0A0200BB +#define RONTLK 0x0A0200BC +#define RONTLKCDT 0x0A0200BD +#define RONTLK2 0x0A0200BE +#define RONTLK2CDT 0x0A0200BF +#define RONWIR 0x0A0200C0 +#define RONWIRCDT 0x0A0200C1 +#define RONWIRCDR 0x0A0200C2 +#define SNRTBL 0x0A0200C3 +#define SNRTBLCDT 0x0A0200C4 + // 197 entities in TXTs, 197 in datafiles. + // room21 +#define R21L0 0x0A030000 +#define R21L1 0x0A030001 +#define R21L2 0x0A030002 +#define R21G1 0x0A030003 +#define R21G2 0x0A030004 +#define R21PAL 0x0A030005 +#define R21FLR 0x0A030006 +#define CALBLO 0x0A030007 +#define CALBLOCDT 0x0A030008 +#define GEMSHN 0x0A030009 +#define GEMSHNCDT 0x0A03000A +#define GEOGEM 0x0A03000B +#define GEOGEMCDT 0x0A03000C +#define GEOGEM8 0x0A03000D +#define GEOGEM8CDT 0x0A03000E +#define GEOLVR 0x0A03000F +#define GEOLVRCDT 0x0A030010 +#define GEOLVR21 0x0A030011 +#define GEOLVR21CDT 0x0A030012 +#define GEOLVR8 0x0A030013 +#define GEOLVR8CDT 0x0A030014 +#define GEOTAP 0x0A030015 +#define GEOTAPCDT 0x0A030016 +#define GEOTLK21 0x0A030017 +#define GEOTLK21CDT 0x0A030018 +#define GEOTORCH 0x0A030019 +#define GEOTORCHCDT 0x0A03001A +#define GEOTRN21 0x0A03001B +#define GEOTRN21CDT 0x0A03001C +#define GEOTRN21CDR 0x0A03001D +#define GEOTWL21 0x0A03001E +#define GEOTWL21CDT 0x0A03001F +#define LVRPSH 0x0A030020 +#define LVRPSHCDT 0x0A030021 +#define MAGCEL 0x0A030022 +#define MAGCELCDT 0x0A030023 +#define MAGCELCDR 0x0A030024 +#define MAGTLK21 0x0A030025 +#define MAGTLK21CDT 0x0A030026 +#define TAPDRP 0x0A030027 +#define TAPDRPCDT 0x0A030028 +#define TAPRUN 0x0A030029 +#define TAPRUNCDT 0x0A03002A +#define TORCH21 0x0A03002B +#define TORCH21CDT 0x0A03002C + // 45 entities in TXTs, 45 in datafiles. + // room22 +#define R22SPRPAL 0x0A040000 +#define R22L0 0x0A040001 +#define R22L1 0x0A040002 +#define R22G1 0x0A040003 +#define R22PAL 0x0A040004 +#define R22FLR 0x0A040005 +#define FRMBUK 0x0A040006 +#define FRMBUKCDT 0x0A040007 +#define FRMSTD 0x0A040008 +#define FRMSTDCDT 0x0A040009 +#define FRMTLK 0x0A04000A +#define FRMTLKCDT 0x0A04000B +#define FRMWLK 0x0A04000C +#define FRMWLKCDT 0x0A04000D +#define GEOCLM 0x0A04000E +#define GEOCLMCDT 0x0A04000F +#define GEOCLMCDR 0x0A040010 +#define GEOPSH22 0x0A040011 +#define GEOPSH22CDT 0x0A040012 + // 19 entities in TXTs, 19 in datafiles. + // room23 +#define R23L0 0x0A050000 +#define R23PAL 0x0A050001 +#define GEOCLM23 0x0A050002 +#define GEOCLM23CDT 0x0A050003 +#define GEOCLM23CDR 0x0A050004 +#define GEOKEY23 0x0A050005 +#define GEOKEY23CDT 0x0A050006 +#define GEOTOP 0x0A050007 +#define GEOTOPCDT 0x0A050008 +#define GEOTOPCDR 0x0A050009 +#define GEOTRY23 0x0A05000A +#define GEOTRY23CDT 0x0A05000B +#define GEOTUG23 0x0A05000C +#define GEOTUG23CDT 0x0A05000D +#define LFTKEY23 0x0A05000E +#define LFTKEY23CDT 0x0A05000F + // 16 entities in TXTs, 16 in datafiles. + // room24 +#define R24L0 0x0A060000 +#define R24L1 0x0A060001 +#define R24G1 0x0A060002 +#define R24PLX 0x0A060003 +#define R24PAL 0x0A060004 +#define R24FLR 0x0A060005 +#define GEOASC24 0x0A060006 +#define GEOASC24CDT 0x0A060007 +#define GEODES24 0x0A060008 +#define GEODES24CDT 0x0A060009 +#define GEOHITL 0x0A06000A +#define GEOHITLCDT 0x0A06000B +#define GEOHITR 0x0A06000C +#define GEOHITRCDT 0x0A06000D +#define GEOLAD 0x0A06000E +#define GEOLADCDT 0x0A06000F +#define GEOLAD8 0x0A060010 +#define GEOLAD8CDT 0x0A060011 +#define GEOPLW 0x0A060012 +#define GEOPLWCDT 0x0A060013 +#define GEORUN 0x0A060014 +#define GEORUNCDT 0x0A060015 +#define GEOUPL24 0x0A060016 +#define GEOUPL24CDT 0x0A060017 +#define GEOUPR24 0x0A060018 +#define GEOUPR24CDT 0x0A060019 +#define GOTBAKL 0x0A06001A +#define GOTBAKLCDT 0x0A06001B +#define GOTBAKR 0x0A06001C +#define GOTBAKRCDT 0x0A06001D +#define GOTCL 0x0A06001E +#define GOTCLCDT 0x0A06001F +#define GOTCR 0x0A060020 +#define GOTCRCDT 0x0A060021 +#define GOTEAT 0x0A060022 +#define GOTEATCDT 0x0A060023 +#define GOTPLW 0x0A060024 +#define GOTPLWCDT 0x0A060025 +#define GOTPLW1 0x0A060026 +#define GOTPLW1CDT 0x0A060027 +#define GOTRIS 0x0A060028 +#define GOTRISCDT 0x0A060029 +#define GOTRISCDR 0x0A06002A +#define PLWMOV 0x0A06002B +#define PLWMOVCDT 0x0A06002C + // 45 entities in TXTs, 45 in datafiles. + // room25 +#define R25SPRPAL 0x0A070000 +#define R25L0 0x0A070001 +#define R25L1 0x0A070002 +#define R25G1 0x0A070003 +#define R25PAL 0x0A070004 +#define R25FLR 0x0A070005 +#define ALTOPN 0x0A070006 +#define ALTOPNCDT 0x0A070007 +#define GEOASC25 0x0A070008 +#define GEOASC25CDT 0x0A070009 +#define GEOCLM25 0x0A07000A +#define GEOCLM25CDT 0x0A07000B +#define GEODES25 0x0A07000C +#define GEODES25CDT 0x0A07000D +#define GEODRY25 0x0A07000E +#define GEODRY25CDT 0x0A07000F +#define GEOFIN25 0x0A070010 +#define GEOFIN25CDT 0x0A070011 +#define GEOPLAS 0x0A070012 +#define GEOPLASCDT 0x0A070013 +#define GEOPLASCDR 0x0A070014 +#define GEOPLS 0x0A070015 +#define GEOPLSCDT 0x0A070016 +#define GEOPSH25 0x0A070017 +#define GEOPSH25CDT 0x0A070018 +#define GEOPUT 0x0A070019 +#define GEOPUTCDT 0x0A07001A +#define GEOSAC 0x0A07001B +#define GEOSACCDT 0x0A07001C +#define GEOSAC25 0x0A07001D +#define GEOSAC25CDT 0x0A07001E +#define GEOSTD25 0x0A07001F +#define GEOSTD25CDT 0x0A070020 +#define GEOSTN 0x0A070021 +#define GEOSTNCDT 0x0A070022 +#define GEOSTN8 0x0A070023 +#define GEOSTN8CDT 0x0A070024 +#define GEOTWL25 0x0A070025 +#define GEOTWL25CDT 0x0A070026 +#define GEOWALF2 0x0A070027 +#define GEOWALF2CDT 0x0A070028 +#define IMPFLR 0x0A070029 +#define IMPFLRCDT 0x0A07002A +#define IMPPLS 0x0A07002B +#define IMPPLSCDT 0x0A07002C +#define PLASWALL 0x0A07002D +#define PLASWALLCDT 0x0A07002E +#define STNFALL 0x0A07002F +#define STNFALLCDT 0x0A070030 + // 49 entities in TXTs, 49 in datafiles. + // room26 +#define R26SPRPAL 0x0A080000 +#define R26L0 0x0A080001 +#define R26L1 0x0A080002 +#define R26L2 0x0A080003 +#define R26G1 0x0A080004 +#define R26G2 0x0A080005 +#define R26PAL 0x0A080006 +#define R26FLR 0x0A080007 +#define GEOLVR08 0x0A080008 +#define GEOLVR08CDT 0x0A080009 +#define GEOLVR26 0x0A08000A +#define GEOLVR26CDT 0x0A08000B +#define LVRDRK 0x0A08000C +#define LVRDRKCDT 0x0A08000D +#define RATJMP 0x0A08000E +#define RATJMPCDT 0x0A08000F + // 16 entities in TXTs, 16 in datafiles. +// spain + // sound_fx +#define FX_SPNBIRD1 0x0B000000 +#define FX_SPNBIRD2 0x0B000001 +#define FX_AMBIEN56 0x0B000002 +#define FX_DOGS56 0x0B000003 +#define FX_PENDULUM 0x0B000004 +#define FX_CANFALL 0x0B000005 +#define FX_HOSE57 0x0B000006 +#define FX_HOSE57B 0x0B000007 +#define FX_SPAIN 0x0B000008 +#define FX_CHESS 0x0B000009 +#define FX_SECDOR59 0x0B00000A +#define FX_WINDOW59 0x0B00000B +#define FX_LIONFALL 0x0B00000C +#define FX_LIONFAL2 0x0B00000D +#define FX_TOOTHPUL 0x0B00000E +#define FX_SECDOR61 0x0B00000F +#define FX_WELLDRIP 0x0B000010 + // 17 entities in TXTs, 17 in datafiles. + // room56 +#define SPAIN_PAL 0x0B010000 +#define R56L0 0x0B010001 +#define R56L1 0x0B010002 +#define R56L2 0x0B010003 +#define R56G1 0x0B010004 +#define R56G2 0x0B010005 +#define R56PAL 0x0B010006 +#define R56FLR 0x0B010007 +#define CHALIC56 0x0B010008 +#define CHALIC56CDT 0x0B010009 +#define GARD20 0x0B01000A +#define GARD20CDT 0x0B01000B +#define GARD21 0x0B01000C +#define GARD21CDT 0x0B01000D +#define GARD22 0x0B01000E +#define GARD22CDT 0x0B01000F +#define GEOSPA10 0x0B010010 +#define GEOSPA10CDT 0x0B010011 +#define GEOSPA10CDR 0x0B010012 +#define GEOSPA11 0x0B010013 +#define GEOSPA11CDT 0x0B010014 +#define GEOSPA13 0x0B010015 +#define GEOSPA13CDT 0x0B010016 +#define GEOSPA13CDR 0x0B010017 +#define GEOSPA19 0x0B010018 +#define GEOSPA19CDT 0x0B010019 +#define GEOSPA44 0x0B01001A +#define GEOSPA44CDT 0x0B01001B +#define GEOSPA48 0x0B01001C +#define GEOSPA48CDT 0x0B01001D +#define PENDULUM 0x0B01001E +#define PENDULUMCDT 0x0B01001F +#define PIECE56 0x0B010020 +#define PIECE56CDT 0x0B010021 +#define VASC01 0x0B010022 +#define VASC01CDT 0x0B010023 +#define VASC02 0x0B010024 +#define VASC02CDT 0x0B010025 +#define VASC04 0x0B010026 +#define VASC04CDT 0x0B010027 +#define VASC05 0x0B010028 +#define VASC05CDT 0x0B010029 +#define VASC05CDR 0x0B01002A +#define VASC06 0x0B01002B +#define VASC06CDT 0x0B01002C +#define VASC26 0x0B01002D +#define VASC26CDT 0x0B01002E +#define VASC26CDR 0x0B01002F +#define VASC27 0x0B010030 +#define VASC27CDT 0x0B010031 +#define VASC28 0x0B010032 +#define VASC28CDT 0x0B010033 +#define VASC29 0x0B010034 +#define VASC29CDT 0x0B010035 +#define VASC29CDR 0x0B010036 +#define VASC30 0x0B010037 +#define VASC30CDT 0x0B010038 +#define VASC30CDR 0x0B010039 +#define VASC32 0x0B01003A +#define VASC32CDT 0x0B01003B + // 60 entities in TXTs, 60 in datafiles. + // room57 +#define R57L0 0x0B020000 +#define R57L1 0x0B020001 +#define R57G1 0x0B020002 +#define R57PAL 0x0B020003 +#define R57FLR 0x0B020004 +#define R57PLX 0x0B020005 +#define MEGA_DOWSE 0x0B020006 +#define GAR57GOB 0x0B020007 +#define GAR57GOBCDT 0x0B020008 +#define GARD01 0x0B020009 +#define GARD01CDT 0x0B02000A +#define GARD02 0x0B02000B +#define GARD02CDT 0x0B02000C +#define GARD03 0x0B02000D +#define GARD03CDT 0x0B02000E +#define GARD04 0x0B02000F +#define GARD04CDT 0x0B020010 +#define GARD04CDR 0x0B020011 +#define GARD05 0x0B020012 +#define GARD05CDT 0x0B020013 +#define GARD06 0x0B020014 +#define GARD06CDT 0x0B020015 +#define GARD07 0x0B020016 +#define GARD07CDT 0x0B020017 +#define GARD07CDR 0x0B020018 +#define GARD08 0x0B020019 +#define GARD08CDT 0x0B02001A +#define GARD09 0x0B02001B +#define GARD09CDT 0x0B02001C +#define GARD17 0x0B02001D +#define GARD17CDT 0x0B02001E +#define GARD17CDR 0x0B02001F +#define GARD18 0x0B020020 +#define GARD18CDT 0x0B020021 +#define GARD31 0x0B020022 +#define GARD31CDT 0x0B020023 +#define GARD31CDR 0x0B020024 +#define GARD32 0x0B020025 +#define GARD32CDT 0x0B020026 +#define GARD34 0x0B020027 +#define GARD34CDT 0x0B020028 +#define GARD35 0x0B020029 +#define GARD35CDT 0x0B02002A +#define GARD36 0x0B02002B +#define GARD36CDT 0x0B02002C +#define GARD37 0x0B02002D +#define GARD37CDT 0x0B02002E +#define GARD38 0x0B02002F +#define GARD38CDT 0x0B020030 +#define GARD39 0x0B020031 +#define GARD39CDT 0x0B020032 +#define GARD40 0x0B020033 +#define GARD40CDT 0x0B020034 +#define GARD40CDR 0x0B020035 +#define GARD41 0x0B020036 +#define GARD41CDT 0x0B020037 +#define GARD42 0x0B020038 +#define GARD42CDT 0x0B020039 +#define GARD43 0x0B02003A +#define GARD43CDT 0x0B02003B +#define GARD44 0x0B02003C +#define GARD44CDT 0x0B02003D +#define GARD44CDR 0x0B02003E +#define GARD45 0x0B02003F +#define GARD45CDT 0x0B020040 +#define GARDKNE 0x0B020041 +#define GARDKNECDT 0x0B020042 +#define GAUGE57 0x0B020043 +#define GAUGE57CDT 0x0B020044 +#define GEOSPA01 0x0B020045 +#define GEOSPA01CDT 0x0B020046 +#define GEOSPA20 0x0B020047 +#define GEOSPA20CDT 0x0B020048 +#define GEOSPA22 0x0B020049 +#define GEOSPA22CDT 0x0B02004A +#define GEOSPA42 0x0B02004B +#define GEOSPA42CDT 0x0B02004C +#define GEOSPA47 0x0B02004D +#define GEOSPA47CDT 0x0B02004E +#define HOLE57 0x0B02004F +#define HOLE57CDT 0x0B020050 +#define HOSE57 0x0B020051 +#define HOSE57CDT 0x0B020052 + // 83 entities in TXTs, 83 in datafiles. + // room58 +#define R58L0 0x0B030000 +#define R58L1 0x0B030001 +#define R58G1 0x0B030002 +#define R58PAL 0x0B030003 +#define R58FLR 0x0B030004 +#define R58PLX 0x0B030005 +#define GARD24 0x0B030006 +#define GARD24CDT 0x0B030007 +#define GARD25 0x0B030008 +#define GARD25CDT 0x0B030009 +#define GARD26 0x0B03000A +#define GARD26CDT 0x0B03000B +#define MAUSDOOR 0x0B03000C +#define MAUSDOORCDT 0x0B03000D +#define VASC07 0x0B03000E +#define VASC07CDT 0x0B03000F +#define VASC08 0x0B030010 +#define VASC08CDT 0x0B030011 +#define VASC09 0x0B030012 +#define VASC09CDT 0x0B030013 +#define VASC10 0x0B030014 +#define VASC10CDT 0x0B030015 +#define VASC11 0x0B030016 +#define VASC11CDT 0x0B030017 +#define VASC12 0x0B030018 +#define VASC12CDT 0x0B030019 + // 26 entities in TXTs, 26 in datafiles. + // room59 +#define R59L0 0x0B040000 +#define R59L1 0x0B040001 +#define R59L2 0x0B040002 +#define R59G1 0x0B040003 +#define R59G2 0x0B040004 +#define R59PAL 0x0B040005 +#define R59FLR 0x0B040006 +#define BIBLE59 0x0B040007 +#define BIBLE59CDT 0x0B040008 +#define BLOWOUT 0x0B040009 +#define BLOWOUTCDT 0x0B04000A +#define CANDLE59 0x0B04000B +#define CANDLE59CDT 0x0B04000C +#define CHAL59 0x0B04000D +#define CHAL59CDT 0x0B04000E +#define FLAMEL59 0x0B04000F +#define FLAMEL59CDT 0x0B040010 +#define FLAMER59 0x0B040011 +#define FLAMER59CDT 0x0B040012 +#define FLAMET59 0x0B040013 +#define FLAMET59CDT 0x0B040014 +#define GARD27 0x0B040015 +#define GARD27CDT 0x0B040016 +#define GARD28 0x0B040017 +#define GARD28CDT 0x0B040018 +#define GARD29 0x0B040019 +#define GARD29CDT 0x0B04001A +#define GARD30 0x0B04001B +#define GARD30CDT 0x0B04001C +#define GEOBIBLE 0x0B04001D +#define GEOBIBLECDT 0x0B04001E +#define GEOSPA12 0x0B04001F +#define GEOSPA12CDT 0x0B040020 +#define GEOSPA16 0x0B040021 +#define GEOSPA16CDT 0x0B040022 +#define GEOSPA17 0x0B040023 +#define GEOSPA17CDT 0x0B040024 +#define GEOSPA18 0x0B040025 +#define GEOSPA18CDT 0x0B040026 +#define GEOSPA18CDR 0x0B040027 +#define GEOSPA23 0x0B040028 +#define GEOSPA23CDT 0x0B040029 +#define GEOSPA23CDR 0x0B04002A +#define GEOSPA37 0x0B04002B +#define GEOSPA37CDT 0x0B04002C +#define GEOSPA37CDR 0x0B04002D +#define GEOSPA38 0x0B04002E +#define GEOSPA38CDT 0x0B04002F +#define GEOSPA39 0x0B040030 +#define GEOSPA39CDT 0x0B040031 +#define GEOSPA40 0x0B040032 +#define GEOSPA40CDT 0x0B040033 +#define GEOSPA41 0x0B040034 +#define GEOSPA41CDT 0x0B040035 +#define GEOSPA43 0x0B040036 +#define GEOSPA43CDT 0x0B040037 +#define GEOSPA45 0x0B040038 +#define GEOSPA45CDT 0x0B040039 +#define GEOSPA46 0x0B04003A +#define GEOSPA46CDT 0x0B04003B +#define SECDOR59 0x0B04003C +#define SECDOR59CDT 0x0B04003D +#define SNUFF59 0x0B04003E +#define SNUFF59CDT 0x0B04003F +#define TISSUE59 0x0B040040 +#define TISSUE59CDT 0x0B040041 +#define VASC13 0x0B040042 +#define VASC13CDT 0x0B040043 +#define VASC14 0x0B040044 +#define VASC14CDT 0x0B040045 +#define VASC15 0x0B040046 +#define VASC15CDT 0x0B040047 +#define VASC16 0x0B040048 +#define VASC16CDT 0x0B040049 +#define VASC17 0x0B04004A +#define VASC17CDT 0x0B04004B +#define VASC18 0x0B04004C +#define VASC18CDT 0x0B04004D +#define VASC19 0x0B04004E +#define VASC19CDT 0x0B04004F +#define VASC20 0x0B040050 +#define VASC20CDT 0x0B040051 +#define VASC20CDR 0x0B040052 +#define VASC21 0x0B040053 +#define VASC21CDT 0x0B040054 +#define VASC22 0x0B040055 +#define VASC22CDT 0x0B040056 +#define VASC23 0x0B040057 +#define VASC23CDT 0x0B040058 +#define VASC24 0x0B040059 +#define VASC24CDT 0x0B04005A +#define VASC25 0x0B04005B +#define VASC25CDT 0x0B04005C +#define VASC31 0x0B04005D +#define VASC31CDT 0x0B04005E +#define WINDSHUT 0x0B04005F +#define WINDSHUTCDT 0x0B040060 +#define WINDSHUTCDR 0x0B040061 + // 98 entities in TXTs, 98 in datafiles. + // room60 +#define R60L0 0x0B050000 +#define R60L1 0x0B050001 +#define R60L2 0x0B050002 +#define R60G1 0x0B050003 +#define R60G2 0x0B050004 +#define R60PAL 0x0B050005 +#define R60FLR 0x0B050006 +#define GARD10 0x0B050007 +#define GARD10CDT 0x0B050008 +#define GARD11 0x0B050009 +#define GARD11CDT 0x0B05000A +#define GARD13 0x0B05000B +#define GARD13CDT 0x0B05000C +#define GARD16 0x0B05000D +#define GARD16CDT 0x0B05000E +#define GARD19 0x0B05000F +#define GARD19CDT 0x0B050010 +#define GEOSPA05 0x0B050011 +#define GEOSPA05CDT 0x0B050012 +#define GEOSPA05CDR 0x0B050013 +#define GEOSPA08 0x0B050014 +#define GEOSPA08CDT 0x0B050015 +#define GEOSPA09 0x0B050016 +#define GEOSPA09CDT 0x0B050017 +#define GEOSPA09CDR 0x0B050018 +#define GEOSPA21 0x0B050019 +#define GEOSPA21CDT 0x0B05001A +#define MIRROR60 0x0B05001B +#define MIRROR60CDT 0x0B05001C + // 29 entities in TXTs, 29 in datafiles. + // room61 +#define R61L0 0x0B060000 +#define R61L1 0x0B060001 +#define R61G1 0x0B060002 +#define R61PAL 0x0B060003 +#define R61FLR 0x0B060004 +#define DUST 0x0B060005 +#define DUSTCDT 0x0B060006 +#define GEOSPA24 0x0B060007 +#define GEOSPA24CDT 0x0B060008 +#define GEOSPA25 0x0B060009 +#define GEOSPA25CDT 0x0B06000A +#define GEOSPA26 0x0B06000B +#define GEOSPA26CDT 0x0B06000C +#define GEOSPA27 0x0B06000D +#define GEOSPA27CDT 0x0B06000E +#define GEOSPA30 0x0B06000F +#define GEOSPA30CDT 0x0B060010 +#define GEOSPA31 0x0B060011 +#define GEOSPA31CDT 0x0B060012 +#define GEOSPA32 0x0B060013 +#define GEOSPA32CDT 0x0B060014 +#define GEOSPA33 0x0B060015 +#define GEOSPA33CDT 0x0B060016 +#define GEOSPA35 0x0B060017 +#define GEOSPA35CDT 0x0B060018 +#define LION1 0x0B060019 +#define LION1CDT 0x0B06001A +#define LION2 0x0B06001B +#define LION2CDT 0x0B06001C +#define LIONDOOR 0x0B06001D +#define LIONDOORCDT 0x0B06001E +#define LIONFLOR 0x0B06001F +#define LIONFLORCDT 0x0B060020 +#define ROPE61 0x0B060021 +#define ROPE61CDT 0x0B060022 +#define SECDOR61 0x0B060023 +#define SECDOR61CDT 0x0B060024 + // 37 entities in TXTs, 37 in datafiles. + // room62 +#define R62L0 0x0B070000 +#define R62PAL 0x0B070001 +#define BISHOP62 0x0B070002 +#define BISHOP62CDT 0x0B070003 +#define KING62 0x0B070004 +#define KING62CDT 0x0B070005 +#define KNIGHT62 0x0B070006 +#define KNIGHT62CDT 0x0B070007 + // 8 entities in TXTs, 8 in datafiles. +// syria + // sound_fx +#define FX_CAMERA45 0x0C000000 +#define FX_SHOCK3 0x0C000001 +#define FX_STALLBEL 0x0C000002 +#define FX_AYUBDOOR 0x0C000003 +#define FX_BALLPLAY 0x0C000004 +#define FX_CATHIT 0x0C000005 +#define FX_MARIB 0x0C000006 +#define FX_NEWTON 0x0C000007 +#define FX_STALLCAT 0x0C000008 +#define FX_STATBREK 0x0C000009 +#define FX_KEYS49 0x0C00000A +#define FX_MANG1 0x0C00000B +#define FX_MANG2 0x0C00000C +#define FX_MANG3 0x0C00000D +#define FX_UNLOCK49 0x0C00000E +#define FX_WCCHAIN 0x0C00000F +#define FX_CUBDOR 0x0C000010 +#define FX_BREKSTIK 0x0C000011 +#define FX_CLIMBDWN 0x0C000012 +#define FX_CRICKET 0x0C000013 +#define FX_GEOFAL54 0x0C000014 +#define FX_KHANDOWN 0x0C000015 +#define FX_RINGPULL 0x0C000016 +#define FX_SECDOR54 0x0C000017 +#define FX_SHOTKHAN 0x0C000018 +#define FX_SYRIWIND 0x0C000019 +#define FX_THUMP1 0x0C00001A +#define FX_SECDOR55 0x0C00001B + // 28 entities in TXTs, 28 in datafiles. + // duane +#define DUANE_MEGA 0x0C010000 +#define DUANE_WLK 0x0C010001 +#define DNETLK3 0x0C010002 +#define DNETLK3CDT 0x0C010003 +#define DNETLK5 0x0C010004 +#define DNETLK5CDT 0x0C010005 +#define XDNEMON3 0x0C010006 +#define XDNEMON3CDT 0x0C010007 +#define XDNEMON5 0x0C010008 +#define XDNEMON5CDT 0x0C010009 +#define XDNESTA3 0x0C01000A +#define XDNESTA3CDT 0x0C01000B +#define XDNESTA5 0x0C01000C +#define XDNESTA5CDT 0x0C01000D +#define XDNEPHO3 0x0C01000E +#define XDNEPHO3CDT 0x0C01000F +#define XDNEPHO5 0x0C010010 +#define XDNEPHO5CDT 0x0C010011 + // 18 entities in TXTs, 18 in datafiles. + // room45 +#define SYRIA_PAL 0x0C020000 +#define R45SPRPAL 0x0C020001 +#define R45L0 0x0C020002 +#define R45L1 0x0C020003 +#define R45G1 0x0C020004 +#define R45PAL 0x0C020005 +#define R45FLR 0x0C020006 +#define R45PLX 0x0C020007 +#define ART1 0x0C020008 +#define ART1CDT 0x0C020009 +#define ART2 0x0C02000A +#define ART2CDT 0x0C02000B +#define ART3A 0x0C02000C +#define ART3ACDT 0x0C02000D +#define ART3ACDR 0x0C02000E +#define ART4 0x0C02000F +#define ART4CDT 0x0C020010 +#define ART5 0x0C020011 +#define ART5CDT 0x0C020012 +#define ART6 0x0C020013 +#define ART6CDT 0x0C020014 +#define ART7 0x0C020015 +#define ART7CDT 0x0C020016 +#define AYU1 0x0C020017 +#define AYU1CDT 0x0C020018 +#define AYU1A 0x0C020019 +#define AYU1ACDT 0x0C02001A +#define AYU1B 0x0C02001B +#define AYU1BCDT 0x0C02001C +#define AYU5 0x0C02001D +#define AYU5CDT 0x0C02001E +#define BRUSH 0x0C02001F +#define BRUSHCDT 0x0C020020 +#define CAT1 0x0C020021 +#define CAT1CDT 0x0C020022 +#define CAT3 0x0C020023 +#define CAT3CDT 0x0C020024 +#define CAT4 0x0C020025 +#define CAT4CDT 0x0C020026 +#define CAT5 0x0C020027 +#define CAT5CDT 0x0C020028 +#define GEOCHA 0x0C020029 +#define GEOCHACDT 0x0C02002A +#define GEOSYR1 0x0C02002B +#define GEOSYR1CDT 0x0C02002C +#define GEOSYR10 0x0C02002D +#define GEOSYR10CDT 0x0C02002E +#define GEOSYR10CDR 0x0C02002F +#define GEOSYR18 0x0C020030 +#define GEOSYR18CDT 0x0C020031 +#define GEOSYR2 0x0C020032 +#define GEOSYR2CDT 0x0C020033 +#define GEOSYR5 0x0C020034 +#define GEOSYR5CDT 0x0C020035 +#define GEOSYR6 0x0C020036 +#define GEOSYR6CDT 0x0C020037 +#define GEOSYR7 0x0C020038 +#define GEOSYR7CDT 0x0C020039 +#define NEJ1 0x0C02003A +#define NEJ1CDT 0x0C02003B +#define NEJ10 0x0C02003C +#define NEJ10CDT 0x0C02003D +#define NEJ12 0x0C02003E +#define NEJ12CDT 0x0C02003F +#define NEJ13 0x0C020040 +#define NEJ13CDT 0x0C020041 +#define NEJ13CDR 0x0C020042 +#define NEJ2 0x0C020043 +#define NEJ2CDT 0x0C020044 +#define NEJ2B 0x0C020045 +#define NEJ2BCDT 0x0C020046 +#define NEJ4 0x0C020047 +#define NEJ4CDT 0x0C020048 +#define NEJ6 0x0C020049 +#define NEJ6CDT 0x0C02004A +#define NEJ7 0x0C02004B +#define NEJ7CDT 0x0C02004C +#define NEJ7B 0x0C02004D +#define NEJ7BCDT 0x0C02004E +#define NEJ8 0x0C02004F +#define NEJ8CDT 0x0C020050 +#define NEJ9 0x0C020051 +#define NEJ9CDT 0x0C020052 +#define NEWTON 0x0C020053 +#define NEWTONCDT 0x0C020054 +#define PRL1 0x0C020055 +#define PRL1CDT 0x0C020056 +#define PRL2 0x0C020057 +#define PRL2CDT 0x0C020058 +#define PRL6 0x0C020059 +#define PRL6CDT 0x0C02005A +#define PRL7 0x0C02005B +#define PRL7CDT 0x0C02005C +#define PRL8 0x0C02005D +#define PRL8CDT 0x0C02005E +#define SHO1 0x0C02005F +#define SHO1CDT 0x0C020060 +#define SHO2 0x0C020061 +#define SHO2CDT 0x0C020062 +#define SHT1 0x0C020063 +#define SHT1CDT 0x0C020064 +#define SHT2 0x0C020065 +#define SHT2CDT 0x0C020066 +#define SHT3 0x0C020067 +#define SHT3CDT 0x0C020068 +#define STA2 0x0C020069 +#define STA2CDT 0x0C02006A +#define STEAM45 0x0C02006B +#define STEAM45CDT 0x0C02006C +#define TRUCK45 0x0C02006D +#define TRUCK45CDT 0x0C02006E +#define TRUCKEMP 0x0C02006F +#define TRUCKEMPCDT 0x0C020070 +#define ULT6 0x0C020071 +#define ULT6CDT 0x0C020072 +#define ULT7 0x0C020073 +#define ULT7CDT 0x0C020074 +#define ULT8 0x0C020075 +#define ULT8CDT 0x0C020076 +#define ULT9 0x0C020077 +#define ULT9CDT 0x0C020078 +#define XGEOMON3 0x0C020079 +#define XGEOMON3CDT 0x0C02007A +#define XGEOMON5 0x0C02007B +#define XGEOMON5CDT 0x0C02007C +#define XGEOSTA3 0x0C02007D +#define XGEOSTA3CDT 0x0C02007E +#define XGEOSTA5 0x0C02007F +#define XGEOSTA5CDT 0x0C020080 +#define XGEOSTAT 0x0C020081 +#define XGEOSTATCDT 0x0C020082 + // 131 entities in TXTs, 131 in datafiles. + // room47 +#define R47L0 0x0C030000 +#define R47L1 0x0C030001 +#define R47L2 0x0C030002 +#define R47G1 0x0C030003 +#define R47G2 0x0C030004 +#define R47PAL 0x0C030005 +#define R47FLR 0x0C030006 +#define CAR1 0x0C030007 +#define CAR1CDT 0x0C030008 +#define CAR2 0x0C030009 +#define CAR2CDT 0x0C03000A +#define CAR3 0x0C03000B +#define CAR3CDT 0x0C03000C +#define CAR4 0x0C03000D +#define CAR4CDT 0x0C03000E +#define CAR5 0x0C03000F +#define CAR5CDT 0x0C030010 +#define CAR6 0x0C030011 +#define CAR6CDT 0x0C030012 +#define CRPMOV 0x0C030013 +#define CRPMOVCDT 0x0C030014 +#define GEOSYR3 0x0C030015 +#define GEOSYR3CDT 0x0C030016 +#define GEOSYR3A 0x0C030017 +#define GEOSYR3ACDT 0x0C030018 +#define GEOSYR4 0x0C030019 +#define GEOSYR4CDT 0x0C03001A +#define GEOSYR4A 0x0C03001B +#define GEOSYR4ACDT 0x0C03001C + // 29 entities in TXTs, 29 in datafiles. + // room49 +#define R49L0 0x0C040000 +#define R49L1 0x0C040001 +#define R49L2 0x0C040002 +#define R49G1 0x0C040003 +#define R49G2 0x0C040004 +#define R49PAL 0x0C040005 +#define R49FLR 0x0C040006 +#define DOOR49 0x0C040007 +#define DOOR49CDT 0x0C040008 +#define DOOR49CDR 0x0C040009 +#define GEOKEYS1 0x0C04000A +#define GEOKEYS1CDT 0x0C04000B +#define GEOSYR43 0x0C04000C +#define GEOSYR43CDT 0x0C04000D +#define KEYS 0x0C04000E +#define KEYSCDT 0x0C04000F +#define MAN1 0x0C040010 +#define MAN1CDT 0x0C040011 +#define MAN2 0x0C040012 +#define MAN2CDT 0x0C040013 +#define MAN3 0x0C040014 +#define MAN3CDT 0x0C040015 +#define MAN4 0x0C040016 +#define MAN4CDT 0x0C040017 +#define MAN4A 0x0C040018 +#define MAN4ACDT 0x0C040019 +#define ULT10 0x0C04001A +#define ULT10CDT 0x0C04001B +#define ULT15 0x0C04001C +#define ULT15CDT 0x0C04001D +#define ULT3 0x0C04001E +#define ULT3CDT 0x0C04001F +#define ULTTAK 0x0C040020 +#define ULTTAKCDT 0x0C040021 + // 34 entities in TXTs, 34 in datafiles. + // room50 +#define R50L0 0x0C050000 +#define R50L1 0x0C050001 +#define R50L2 0x0C050002 +#define R50L3 0x0C050003 +#define R50G1 0x0C050004 +#define R50G2 0x0C050005 +#define R50G3 0x0C050006 +#define R50PAL 0x0C050007 +#define R50FLR 0x0C050008 +#define CHAIN50 0x0C050009 +#define CHAIN50CDT 0x0C05000A +#define CUBDOR50 0x0C05000B +#define CUBDOR50CDT 0x0C05000C +#define DOOR50 0x0C05000D +#define DOOR50CDT 0x0C05000E +#define DOOR50CDR 0x0C05000F +#define GEOSYR48 0x0C050010 +#define GEOSYR48CDT 0x0C050011 +#define GEOSYR49 0x0C050012 +#define GEOSYR49CDT 0x0C050013 +#define GEOSYR50 0x0C050014 +#define GEOSYR50CDT 0x0C050015 +#define GEOSYR51 0x0C050016 +#define GEOSYR51CDT 0x0C050017 +#define GEOSYR51CDR 0x0C050018 +#define GEOSYR52 0x0C050019 +#define GEOSYR52CDT 0x0C05001A +#define GEOSYR53 0x0C05001B +#define GEOSYR53CDT 0x0C05001C +#define GEOSYR54 0x0C05001D +#define GEOSYR54CDT 0x0C05001E +#define TOWEL1 0x0C05001F +#define TOWEL1CDT 0x0C050020 +#define TOWEL4 0x0C050021 +#define TOWEL4CDT 0x0C050022 + // 35 entities in TXTs, 35 in datafiles. + // room53 +#define R53L0 0x0C060000 +#define R53PAL 0x0C060001 +#define BACK53PLX 0x0C060002 +#define FRONT53PLX 0x0C060003 +#define R53SPRPAL 0x0C060004 + // 5 entities in TXTs, 5 in datafiles. + // room54 +#define R54L0 0x0C070000 +#define R54L1 0x0C070001 +#define R54G1 0x0C070002 +#define R54PAL 0x0C070003 +#define R54FLR 0x0C070004 +#define R54PLX 0x0C070005 +#define GEOSYR19 0x0C070006 +#define GEOSYR19CDT 0x0C070007 +#define GEOSYR20 0x0C070008 +#define GEOSYR20CDT 0x0C070009 +#define GEOSYR22 0x0C07000A +#define GEOSYR22CDT 0x0C07000B +#define GEOSYR23 0x0C07000C +#define GEOSYR23CDT 0x0C07000D +#define GEOSYR25 0x0C07000E +#define GEOSYR25CDT 0x0C07000F +#define GEOSYR26 0x0C070010 +#define GEOSYR26CDT 0x0C070011 +#define GEOSYR27 0x0C070012 +#define GEOSYR27CDT 0x0C070013 +#define GEOSYR37 0x0C070014 +#define GEOSYR37CDT 0x0C070015 +#define GEOSYR39 0x0C070016 +#define GEOSYR39CDT 0x0C070017 +#define GEOSYR40 0x0C070018 +#define GEOSYR40CDT 0x0C070019 +#define GEOSYR41 0x0C07001A +#define GEOSYR41CDT 0x0C07001B +#define GEOSYR42 0x0C07001C +#define GEOSYR42CDT 0x0C07001D +#define GEOSYR99 0x0C07001E +#define GEOSYR99CDT 0x0C07001F +#define GUN54 0x0C070020 +#define GUN54CDT 0x0C070021 +#define KHS10 0x0C070022 +#define KHS10CDT 0x0C070023 +#define KHS12 0x0C070024 +#define KHS12CDT 0x0C070025 +#define KHS5 0x0C070026 +#define KHS5CDT 0x0C070027 +#define KHS7 0x0C070028 +#define KHS7CDT 0x0C070029 +#define KHS8 0x0C07002A +#define KHS8CDT 0x0C07002B +#define KHS9 0x0C07002C +#define KHS9CDT 0x0C07002D +#define KHSTLK54 0x0C07002E +#define KHSTLK54CDT 0x0C07002F +#define SECDOR 0x0C070030 +#define SECDORCDT 0x0C070031 +#define STCKTREE 0x0C070032 +#define STCKTREECDT 0x0C070033 +#define STICKIN 0x0C070034 +#define STICKINCDT 0x0C070035 +#define XGEOSY21 0x0C070036 +#define XGEOSY21CDT 0x0C070037 + // 56 entities in TXTs, 56 in datafiles. + // room55 +#define R55SPRPAL 0x0C080000 +#define R55L0 0x0C080001 +#define R55PAL 0x0C080002 +#define R55FLR 0x0C080003 +#define R55PLX 0x0C080004 +#define BODY55 0x0C080005 +#define BODY55CDT 0x0C080006 +#define BRITMAP 0x0C080007 +#define BRITMAP_PAL 0x0C080008 +#define DOOR55 0x0C080009 +#define DOOR55CDT 0x0C08000A +#define DOOR55CDR 0x0C08000B +#define GEOSY30T 0x0C08000C +#define GEOSY30TCDT 0x0C08000D +#define GEOSY30U 0x0C08000E +#define GEOSY30UCDT 0x0C08000F +#define GEOSYR29 0x0C080010 +#define GEOSYR29CDT 0x0C080011 +#define GEOSYR30 0x0C080012 +#define GEOSYR30CDT 0x0C080013 +#define GEOSYR31 0x0C080014 +#define GEOSYR31CDT 0x0C080015 +#define GEOSYR33 0x0C080016 +#define GEOSYR33CDT 0x0C080017 +#define GEOSYR34 0x0C080018 +#define GEOSYR34CDT 0x0C080019 +#define GEOSYR34CDR 0x0C08001A +#define GEOSYR35 0x0C08001B +#define GEOSYR35CDT 0x0C08001C +#define GEOSYR56 0x0C08001D +#define GEOSYR56CDT 0x0C08001E +#define KHS2 0x0C08001F +#define KHS2CDT 0x0C080020 +#define KHS3 0x0C080021 +#define KHS3CDT 0x0C080022 +#define KHS6 0x0C080023 +#define KHS6CDT 0x0C080024 + // 37 entities in TXTs, 37 in datafiles. +// train + // sound_fx +#define FX_SHOCK63 0x0D000000 +#define FX_TRAINEXT 0x0D000001 +#define FX_TRAININT 0x0D000002 +#define FX_DOOR65 0x0D000003 +#define FX_WIND66 0x0D000004 +#define FX_WINDOW66 0x0D000005 +#define FX_BRAKES 0x0D000006 +#define FX_DOOR69 0x0D000007 +#define FX_EKSHOOT 0x0D000008 +#define FX_FIGHT69 0x0D000009 +#define FX_PNEUMO69 0x0D00000A +#define FX_TICK69 0x0D00000B +#define FX_TRNPASS 0x0D00000C + // 13 entities in TXTs, 13 in datafiles. + // room63 +#define TRAIN_PAL 0x0D010000 +#define R63L0 0x0D010001 +#define R63L1 0x0D010002 +#define R63G1 0x0D010003 +#define R63PAL 0x0D010004 +#define R63FLR 0x0D010005 +#define GEOTRAIN_MEGA 0x0D010006 +#define GEOTRAIN_WLK 0x0D010007 +#define BASHER63 0x0D010008 +#define BASHER63CDT 0x0D010009 +#define BOXDOR64 0x0D01000A +#define BOXDOR64CDT 0x0D01000B +#define BUSHA63 0x0D01000C +#define BUSHA63CDT 0x0D01000D +#define BUSHB63 0x0D01000E +#define BUSHB63CDT 0x0D01000F +#define BUSHC63 0x0D010010 +#define BUSHC63CDT 0x0D010011 +#define DOOR63C1 0x0D010012 +#define DOOR63C1CDT 0x0D010013 +#define DOOR63C1CDR 0x0D010014 +#define DOOR63C2 0x0D010015 +#define DOOR63C2CDT 0x0D010016 +#define DOOR63C2CDR 0x0D010017 +#define DOOR63C3 0x0D010018 +#define DOOR63C3CDT 0x0D010019 +#define DOOR63C3CDR 0x0D01001A +#define GEOCLI64 0x0D01001B +#define GEOCLI64CDT 0x0D01001C +#define GEOJGL64 0x0D01001D +#define GEOJGL64CDT 0x0D01001E +#define GEOJGR64 0x0D01001F +#define GEOJGR64CDT 0x0D010020 +#define GEOLAD64 0x0D010021 +#define GEOLAD64CDT 0x0D010022 +#define GEOSHK64 0x0D010023 +#define GEOSHK64CDT 0x0D010024 +#define GEOSTDL 0x0D010025 +#define GEOSTDLCDT 0x0D010026 +#define GEOSTDR 0x0D010027 +#define GEOSTDRCDT 0x0D010028 +#define GUIDOR63 0x0D010029 +#define GUIDOR63CDT 0x0D01002A +#define GUIDSM63 0x0D01002B +#define GUIDSM63CDT 0x0D01002C +#define LADY63 0x0D01002D +#define LADY63CDT 0x0D01002E +#define LIGHT63A 0x0D01002F +#define LIGHT63ACDT 0x0D010030 +#define LIGHT63B 0x0D010031 +#define LIGHT63BCDT 0x0D010032 +#define LIGHT63C 0x0D010033 +#define LIGHT63CCDT 0x0D010034 +#define LIGHT63D 0x0D010035 +#define LIGHT63DCDT 0x0D010036 +#define LIGHT63E 0x0D010037 +#define LIGHT63ECDT 0x0D010038 +#define NICO63 0x0D010039 +#define NICO63CDT 0x0D01003A +#define POLE63 0x0D01003B +#define POLE63CDT 0x0D01003C +#define WHEELA63 0x0D01003D +#define WHEELA63CDT 0x0D01003E +#define WHEELB63 0x0D01003F +#define WHEELB63CDT 0x0D010040 +#define WHEELC63 0x0D010041 +#define WHEELC63CDT 0x0D010042 +#define WHEELD63 0x0D010043 +#define WHEELD63CDT 0x0D010044 +#define WHEELE63 0x0D010045 +#define WHEELE63CDT 0x0D010046 +#define WHEELF63 0x0D010047 +#define WHEELF63CDT 0x0D010048 + // 73 entities in TXTs, 73 in datafiles. + // room65 +#define R65L0 0x0D020000 +#define R65L1 0x0D020001 +#define R65G1 0x0D020002 +#define R65PAL 0x0D020003 +#define R65FLR 0x0D020004 +#define DOOR65 0x0D020005 +#define DOOR65CDT 0x0D020006 +#define DOOR65CDR 0x0D020007 +#define GEOGUA 0x0D020008 +#define GEOGUACDT 0x0D020009 +#define GEOLNK3 0x0D02000A +#define GEOLNK3CDT 0x0D02000B +#define GEONIC65 0x0D02000C +#define GEONIC65CDT 0x0D02000D +#define GEOSIT 0x0D02000E +#define GEOSITCDT 0x0D02000F +#define GEOSIT65 0x0D020010 +#define GEOSIT65CDT 0x0D020011 +#define GEOSTD65 0x0D020012 +#define GEOSTD65CDT 0x0D020013 +#define GEOSTD65CDR 0x0D020014 +#define GEOTIK 0x0D020015 +#define GEOTIKCDT 0x0D020016 +#define GEOTN652 0x0D020017 +#define GEOTN652CDT 0x0D020018 +#define GEOTN652CDR 0x0D020019 +#define GEOTRN65 0x0D02001A +#define GEOTRN65CDT 0x0D02001B +#define GEOTRN65CDR 0x0D02001C +#define GUADOR65 0x0D02001D +#define GUADOR65CDT 0x0D02001E +#define GUALEA65 0x0D02001F +#define GUALEA65CDT 0x0D020020 +#define GUATGN 0x0D020021 +#define GUATGNCDT 0x0D020022 +#define GUATGNCDR 0x0D020023 +#define GUATIK1 0x0D020024 +#define GUATIK1CDT 0x0D020025 +#define GUATIK2 0x0D020026 +#define GUATIK2CDT 0x0D020027 +#define GUATLK1 0x0D020028 +#define GUATLK1CDT 0x0D020029 +#define GUATLK2 0x0D02002A +#define GUATLK2CDT 0x0D02002B +#define NICGEO65 0x0D02002C +#define NICGEO65CDT 0x0D02002D +#define NICSIT65 0x0D02002E +#define NICSIT65CDT 0x0D02002F +#define NICTRN65 0x0D020030 +#define NICTRN65CDT 0x0D020031 +#define NICTRN65CDR 0x0D020032 +#define OLDREAD 0x0D020033 +#define OLDREADCDT 0x0D020034 +#define OLDREADCDR 0x0D020035 +#define OLDTIK1 0x0D020036 +#define OLDTIK1CDT 0x0D020037 +#define OLDTLK1 0x0D020038 +#define OLDTLK1CDT 0x0D020039 + // 58 entities in TXTs, 58 in datafiles. + // room66 +#define R66L0 0x0D030000 +#define R66PAL 0x0D030001 +#define R66FLR 0x0D030002 +#define BASHBURP 0x0D030003 +#define BASHBURPCDT 0x0D030004 +#define BASHCAN 0x0D030005 +#define BASHCANCDT 0x0D030006 +#define BASHCLA 0x0D030007 +#define BASHCLACDT 0x0D030008 +#define BASHDRI 0x0D030009 +#define BASHDRICDT 0x0D03000A +#define BASHSTD 0x0D03000B +#define BASHSTDCDT 0x0D03000C +#define BASHTLK1 0x0D03000D +#define BASHTLK1CDT 0x0D03000E +#define CAN66 0x0D03000F +#define CAN66CDT 0x0D030010 +#define GEOLEA 0x0D030011 +#define GEOLEACDT 0x0D030012 +#define GEOOPN1 0x0D030013 +#define GEOOPN1CDT 0x0D030014 +#define GEOOUT66 0x0D030015 +#define GEOOUT66CDT 0x0D030016 +#define SLEEPY1 0x0D030017 +#define SLEEPY1CDT 0x0D030018 +#define SLEEPY1CDR 0x0D030019 +#define SLEEPY2 0x0D03001A +#define SLEEPY2CDT 0x0D03001B + // 28 entities in TXTs, 28 in datafiles. + // room67 +#define R67L0 0x0D040000 +#define R67L1 0x0D040001 +#define R67G1 0x0D040002 +#define R67PAL 0x0D040003 +#define R67FLR 0x0D040004 +#define DOOR67 0x0D040005 +#define DOOR67CDT 0x0D040006 +#define DOOR67CDR 0x0D040007 + // 8 entities in TXTs, 8 in datafiles. + // room69 +#define R69SPRPAL 0x0D050000 +#define R69L0 0x0D050001 +#define R69L1 0x0D050002 +#define R69G1 0x0D050003 +#define R69PAL 0x0D050004 +#define R69FLR 0x0D050005 +#define ASSDIE69 0x0D050006 +#define ASSDIE69CDT 0x0D050007 +#define ASSDWN69 0x0D050008 +#define ASSDWN69CDT 0x0D050009 +#define ASSLIFT 0x0D05000A +#define ASSLIFTCDT 0x0D05000B +#define ASSTLK69 0x0D05000C +#define ASSTLK69CDT 0x0D05000D +#define BOXES69 0x0D05000E +#define BOXES69CDT 0x0D05000F +#define EKLBOX69 0x0D050010 +#define EKLBOX69CDT 0x0D050011 +#define EKLGUN 0x0D050012 +#define EKLGUNCDT 0x0D050013 +#define EKLGUN69 0x0D050014 +#define EKLGUN69CDT 0x0D050015 +#define EKLTLK69 0x0D050016 +#define EKLTLK69CDT 0x0D050017 +#define EKLFIGHT 0x0D050018 +#define EKLFIGHTCDT 0x0D050019 +#define FIGHT69 0x0D05001A +#define FIGHT69CDT 0x0D05001B +#define GEODIE69 0x0D05001C +#define GEODIE69CDT 0x0D05001D +#define GEOENT69 0x0D05001E +#define GEOENT69CDT 0x0D05001F +#define GEOSTD69 0x0D050020 +#define GEOSTD69CDT 0x0D050021 +#define GEOSTP69 0x0D050022 +#define GEOSTP69CDT 0x0D050023 +#define GEOTLK69 0x0D050024 +#define GEOTLK69CDT 0x0D050025 +#define GEOUNTIE 0x0D050026 +#define GEOUNTIECDT 0x0D050027 +#define GEOXIT69 0x0D050028 +#define GEOXIT69CDT 0x0D050029 +#define NICTKB69 0x0D05002A +#define NICTKB69CDT 0x0D05002B +#define NICTLK69 0x0D05002C +#define NICTLK69CDT 0x0D05002D +#define NICTRN69 0x0D05002E +#define NICTRN69CDT 0x0D05002F +#define NICTRN69CDR 0x0D050030 +#define NICTUG69 0x0D050031 +#define NICTUG69CDT 0x0D050032 +#define NICWLK69 0x0D050033 +#define NICWLK69CDT 0x0D050034 +#define NICXIT69 0x0D050035 +#define NICXIT69CDT 0x0D050036 +#define RGTDOR69 0x0D050037 +#define RGTDOR69CDT 0x0D050038 + // 57 entities in TXTs, 57 in datafiles. +// scotland + // sound_fx +#define FX_WIND71 0x0E000000 +#define FX_GUST71 0x0E000001 +#define FX_OWL71A 0x0E000002 +#define FX_OWL71B 0x0E000003 +#define FX_COG72A 0x0E000004 +#define FX_PING 0x0E000005 +#define FX_RUMMAGE1 0x0E000006 +#define FX_RUMMAGE2 0x0E000007 +#define FX_SECDOR72 0x0E000008 +#define FX_CHANT 0x0E000009 +#define FX_DAGGER1 0x0E00000A +#define FX_GDROP73 0x0E00000B +#define FX_GUNPOWDR 0x0E00000C +#define FX_STAFF 0x0E00000D +#define FX_TORCH73 0x0E00000E +#define FX_BAPHAMB 0x0E00000F +#define FX_FIGHT1 0x0E000010 +#define FX_REFORGE2 0x0E000011 +#define FX_ROSSODIE 0x0E000012 +#define FX_GKSWORD 0x0E000013 +#define FX_REFORGE1 0x0E000014 +#define FX_REFORGE4 0x0E000015 +#define FX_CHOKE1 0x0E000016 +#define FX_CHOKE2 0x0E000017 +#define FX_EKDIES 0x0E000018 +#define FX_FIGHT2 0x0E000019 +#define FX_GUN79 0x0E00001A + // 27 entities in TXTs, 27 in datafiles. + // room71 +#define R71L0 0x0E010000 +#define R71L1 0x0E010001 +#define R71G1 0x0E010002 +#define R71PAL 0x0E010003 +#define R71FLR 0x0E010004 +#define R71PLX 0x0E010005 + // 6 entities in TXTs, 6 in datafiles. + // room72 +#define R72L0 0x0E020000 +#define R72L1 0x0E020001 +#define R72G1 0x0E020002 +#define R72PAL 0x0E020003 +#define R72FLR 0x0E020004 +#define COGL72 0x0E020005 +#define COGL72CDT 0x0E020006 +#define COGR72 0x0E020007 +#define COGR72CDT 0x0E020008 +#define GEOJMP72 0x0E020009 +#define GEOJMP72CDT 0x0E02000A +#define GEOPIPE 0x0E02000B +#define GEOPIPECDT 0x0E02000C +#define GEOPIPECDR 0x0E02000D +#define GEOPSH72 0x0E02000E +#define GEOPSH72CDT 0x0E02000F +#define GEOPUT72 0x0E020010 +#define GEOPUT72CDT 0x0E020011 +#define GEOTAK72 0x0E020012 +#define GEOTAK72CDT 0x0E020013 +#define GEOTAK72CDR 0x0E020014 +#define GEOTRY72 0x0E020015 +#define GEOTRY72CDT 0x0E020016 +#define GEOWIND2 0x0E020017 +#define GEOWIND2CDT 0x0E020018 +#define GEOWIND3 0x0E020019 +#define GEOWIND3CDT 0x0E02001A +#define GEOWIND4 0x0E02001B +#define GEOWIND4CDT 0x0E02001C +#define GEOWND72 0x0E02001D +#define GEOWND72CDT 0x0E02001E +#define HANDLE72 0x0E02001F +#define HANDLE72CDT 0x0E020020 +#define NICGEO72 0x0E020021 +#define NICGEO72CDT 0x0E020022 +#define NICJMP72 0x0E020023 +#define NICJMP72CDT 0x0E020024 +#define NICLNK72 0x0E020025 +#define NICLNK72CDT 0x0E020026 +#define NICLNK72CDR 0x0E020027 +#define NICOPY72 0x0E020028 +#define NICOPY72CDT 0x0E020029 +#define NICOPY72CDR 0x0E02002A +#define NICTLK72 0x0E02002B +#define NICTLK72CDT 0x0E02002C +#define NOSE72 0x0E02002D +#define NOSE72CDT 0x0E02002E +#define PANEL72 0x0E02002F +#define PANEL72CDT 0x0E020030 +#define PIPE72 0x0E020031 +#define PIPE72CDT 0x0E020032 +#define SPINDL72 0x0E020033 +#define SPINDL72CDT 0x0E020034 +#define WHEEL72 0x0E020035 +#define WHEEL72CDT 0x0E020036 + // 55 entities in TXTs, 55 in datafiles. + // room73 +#define R73SPRPAL 0x0E030000 +#define R73L0 0x0E030001 +#define R73L1 0x0E030002 +#define R73L2 0x0E030003 +#define R73G1 0x0E030004 +#define R73G2 0x0E030005 +#define R73PAL 0x0E030006 +#define R73FLR 0x0E030007 +#define DAGGER1 0x0E030008 +#define DAGGER1CDT 0x0E030009 +#define DAGGER2 0x0E03000A +#define DAGGER2CDT 0x0E03000B +#define DARKWALL 0x0E03000C +#define DARKWALLCDT 0x0E03000D +#define FLAME73 0x0E03000E +#define FLAME73CDT 0x0E03000F +#define GEOCRCH 0x0E030010 +#define GEOCRCHCDT 0x0E030011 +#define GEOCREEP 0x0E030012 +#define GEOCREEPCDT 0x0E030013 +#define GEODIE1 0x0E030014 +#define GEODIE1CDT 0x0E030015 +#define GEODIE2 0x0E030016 +#define GEODIE2CDT 0x0E030017 +#define GEOTHROW 0x0E030018 +#define GEOTHROWCDT 0x0E030019 +#define GEOTLK73 0x0E03001A +#define GEOTLK73CDT 0x0E03001B +#define GEOTN73 0x0E03001C +#define GEOTN73CDT 0x0E03001D +#define GEOTN73CDR 0x0E03001E +#define GMENTER 0x0E03001F +#define GMENTERCDT 0x0E030020 +#define GMSPEAK 0x0E030021 +#define GMSPEAKCDT 0x0E030022 +#define GUIDLE 0x0E030023 +#define GUIDLECDT 0x0E030024 +#define GUITALK 0x0E030025 +#define GUITALKCDT 0x0E030026 +#define GUITHROW 0x0E030027 +#define GUITHROWCDT 0x0E030028 +#define GUITURN7 0x0E030029 +#define GUITURN7CDT 0x0E03002A +#define GUITURN7CDR 0x0E03002B +#define NICENT73 0x0E03002C +#define NICENT73CDT 0x0E03002D +#define NICEX73 0x0E03002E +#define NICEX73CDT 0x0E03002F +#define NICOTHRO 0x0E030030 +#define NICOTHROCDT 0x0E030031 +#define NICPANIC 0x0E030032 +#define NICPANICCDT 0x0E030033 +#define NICTLK73 0x0E030034 +#define NICTLK73CDT 0x0E030035 +#define NICTRN73 0x0E030036 +#define NICTRN73CDT 0x0E030037 +#define NICTRN73CDR 0x0E030038 +#define NITALK73 0x0E030039 +#define NITALK73CDT 0x0E03003A +#define SPARKING 0x0E03003B +#define SPARKINGCDT 0x0E03003C +#define TORCH1 0x0E03003D +#define TORCH1CDT 0x0E03003E +#define TORCH2 0x0E03003F +#define TORCH2CDT 0x0E030040 +#define TORCH3 0x0E030041 +#define TORCH3CDT 0x0E030042 + // 67 entities in TXTs, 67 in datafiles. + // room74 +#define ENDSPRPAL 0x0E040000 +#define R74L0 0x0E040001 +#define R74L1 0x0E040002 +#define R74G1 0x0E040003 +#define R74PAL 0x0E040004 +#define R74APAL 0x0E040005 +#define R74BPAL 0x0E040006 +#define R74CPAL 0x0E040007 +#define R74DPAL 0x0E040008 +#define CHANT74 0x0E040009 +#define CHANT74CDT 0x0E04000A +#define EKFIGHT 0x0E04000B +#define EKFIGHTCDT 0x0E04000C +#define EKGUN74 0x0E04000D +#define EKGUN74CDT 0x0E04000E +#define GEOFIGHT 0x0E04000F +#define GEOFIGHTCDT 0x0E040010 +#define GEOLUK74 0x0E040011 +#define GEOLUK74CDT 0x0E040012 +#define GEOLUK74CDR 0x0E040013 +#define GEORCT74 0x0E040014 +#define GEORCT74CDT 0x0E040015 +#define GEORUN74 0x0E040016 +#define GEORUN74CDT 0x0E040017 +#define GEOSTND 0x0E040018 +#define GEOSTNDCDT 0x0E040019 +#define GEOTLK74 0x0E04001A +#define GEOTLK74CDT 0x0E04001B +#define GKKNEE 0x0E04001C +#define GKKNEECDT 0x0E04001D +#define GMGUN 0x0E04001E +#define GMGUNCDT 0x0E04001F +#define GMMOV1 0x0E040020 +#define GMMOV1CDT 0x0E040021 +#define GMMOV2 0x0E040022 +#define GMMOV2CDT 0x0E040023 +#define GMMOV3 0x0E040024 +#define GMMOV3CDT 0x0E040025 +#define GMMOV4 0x0E040026 +#define GMMOV4CDT 0x0E040027 +#define GMMOV5 0x0E040028 +#define GMMOV5CDT 0x0E040029 +#define GMMOV6 0x0E04002A +#define GMMOV6CDT 0x0E04002B +#define GMTLK1 0x0E04002C +#define GMTLK1CDT 0x0E04002D +#define GMTLK2 0x0E04002E +#define GMTLK2CDT 0x0E04002F +#define GMTLK3 0x0E040030 +#define GMTLK3CDT 0x0E040031 +#define GMTLK4 0x0E040032 +#define GMTLK4CDT 0x0E040033 +#define GMTLK5 0x0E040034 +#define GMTLK5CDT 0x0E040035 +#define GMTLK6 0x0E040036 +#define GMTLK6CDT 0x0E040037 +#define GMTLK7 0x0E040038 +#define GMTLK7CDT 0x0E040039 +#define GMTLK74 0x0E04003A +#define GMTLK74CDT 0x0E04003B +#define GMWLK 0x0E04003C +#define GMWLKCDT 0x0E04003D +#define GMWRIT74 0x0E04003E +#define GMWRIT74CDT 0x0E04003F +#define MONKFALL 0x0E040040 +#define MONKFALLCDT 0x0E040041 +#define MONKRISE 0x0E040042 +#define MONKRISECDT 0x0E040043 +#define MONKSTRS 0x0E040044 +#define MONKSTRSCDT 0x0E040045 +#define MONKTURN 0x0E040046 +#define MONKTURNCDT 0x0E040047 +#define NICFIGHT 0x0E040048 +#define NICFIGHTCDT 0x0E040049 +#define NICLUK74 0x0E04004A +#define NICLUK74CDT 0x0E04004B +#define NICLUK74CDR 0x0E04004C +#define NICRCVR 0x0E04004D +#define NICRCVRCDT 0x0E04004E +#define NICRUN74 0x0E04004F +#define NICRUN74CDT 0x0E040050 +#define NICSTND 0x0E040051 +#define NICSTNDCDT 0x0E040052 +#define NICTLK74 0x0E040053 +#define NICTLK74CDT 0x0E040054 +#define ROSSFALL 0x0E040055 +#define ROSSFALLCDT 0x0E040056 +#define ROSSTAIR 0x0E040057 +#define ROSSTAIRCDT 0x0E040058 +#define ROSSTND 0x0E040059 +#define ROSSTNDCDT 0x0E04005A +#define ROSSWLK 0x0E04005B +#define ROSSWLKCDT 0x0E04005C +#define RUBBLE 0x0E04005D +#define RUBBLECDT 0x0E04005E +#define STONLIT1 0x0E04005F +#define STONLIT1CDT 0x0E040060 +#define STONLIT2 0x0E040061 +#define STONLIT2CDT 0x0E040062 +#define STONWHT1 0x0E040063 +#define STONWHT1CDT 0x0E040064 +#define STONWHT2 0x0E040065 +#define STONWHT2CDT 0x0E040066 + // 103 entities in TXTs, 103 in datafiles. + // room75 +#define R75L0 0x0E050000 +#define R75PAL 0x0E050001 +#define R75APAL 0x0E050002 +#define R75BPAL 0x0E050003 +#define R75CPAL 0x0E050004 +#define R75DPAL 0x0E050005 +#define EKGUN 0x0E050006 +#define EKGUNCDT 0x0E050007 +#define EKGUN2 0x0E050008 +#define EKGUN2CDT 0x0E050009 +#define EKLITE 0x0E05000A +#define EKLITECDT 0x0E05000B +#define EKRELAX 0x0E05000C +#define EKRELAXCDT 0x0E05000D +#define EKTLK75 0x0E05000E +#define EKTLK75CDT 0x0E05000F +#define GEOLUK75 0x0E050010 +#define GEOLUK75CDT 0x0E050011 +#define GEOLUK75CDR 0x0E050012 +#define GTMP 0x0E050013 +#define GTMPCDT 0x0E050014 +#define NICLUK75 0x0E050015 +#define NICLUK75CDT 0x0E050016 +#define NICLUK75CDR 0x0E050017 +#define NTMP 0x0E050018 +#define NTMPCDT 0x0E050019 +#define TORCH75 0x0E05001A +#define TORCH75CDT 0x0E05001B + // 28 entities in TXTs, 28 in datafiles. + // room76 +#define R76L0 0x0E060000 +#define R76PAL 0x0E060001 +#define CHANT76 0x0E060002 +#define CHANT76CDT 0x0E060003 +#define EKGUN76 0x0E060004 +#define EKGUN76CDT 0x0E060005 +#define GKBAK 0x0E060006 +#define GKBAKCDT 0x0E060007 +#define GKKNEE76 0x0E060008 +#define GKKNEE76CDT 0x0E060009 +#define GKLOWER 0x0E06000A +#define GKLOWERCDT 0x0E06000B +#define GKSWORD 0x0E06000C +#define GKSWORDCDT 0x0E06000D +#define GKTLK 0x0E06000E +#define GKTLKCDT 0x0E06000F +#define GKTLK2 0x0E060010 +#define GKTLK2CDT 0x0E060011 +#define GMARMS 0x0E060012 +#define GMARMSCDT 0x0E060013 +#define GMSTONES 0x0E060014 +#define GMSTONESCDT 0x0E060015 +#define GMTLK76 0x0E060016 +#define GMTLK76CDT 0x0E060017 +#define GMTRN76 0x0E060018 +#define GMTRN76CDT 0x0E060019 +#define LSTONE76 0x0E06001A +#define LSTONE76CDT 0x0E06001B +#define MONKNEE 0x0E06001C +#define MONKNEECDT 0x0E06001D +#define ROSSTND76 0x0E06001E +#define ROSSTND76CDT 0x0E06001F +#define RSTONE76 0x0E060020 +#define RSTONE76CDT 0x0E060021 + // 34 entities in TXTs, 34 in datafiles. + // room77 +#define R77L0 0x0E070000 +#define R77PAL 0x0E070001 +#define CHANT77 0x0E070002 +#define CHANT77CDT 0x0E070003 +#define GEOPEER 0x0E070004 +#define GEOPEERCDT 0x0E070005 +#define GMHEAD 0x0E070006 +#define GMHEADCDT 0x0E070007 +#define NICPEER 0x0E070008 +#define NICPEERCDT 0x0E070009 +#define NICTLK77 0x0E07000A +#define NICTLK77CDT 0x0E07000B +#define ROSLUK77 0x0E07000C +#define ROSLUK77CDT 0x0E07000D + // 14 entities in TXTs, 14 in datafiles. + // room78 +#define R78L0 0x0E080000 +#define R78PAL 0x0E080001 +#define R78APAL 0x0E080002 +#define R78BPAL 0x0E080003 +#define R78CPAL 0x0E080004 +#define R78DPAL 0x0E080005 +#define R78EPAL 0x0E080006 +#define R78FPAL 0x0E080007 +#define LSTONE78 0x0E080008 +#define LSTONE78CDT 0x0E080009 +#define LSTONE78CDR 0x0E08000A +#define GMPOWER 0x0E08000B +#define GMPOWERCDT 0x0E08000C +#define GMWRITH 0x0E08000D +#define GMWRITHCDT 0x0E08000E +#define RSTONE78 0x0E08000F +#define RSTONE78CDT 0x0E080010 +#define RSTONE78CDR 0x0E080011 + // 18 entities in TXTs, 18 in datafiles. + // room79 +#define R79L0 0x0E090000 +#define R79PAL 0x0E090001 +#define EKSTD79 0x0E090002 +#define EKSTD79CDT 0x0E090003 +#define FIGHT79 0x0E090004 +#define FIGHT79CDT 0x0E090005 +#define GEOANG79 0x0E090006 +#define GEOANG79CDT 0x0E090007 +#define GEOTLK79 0x0E090008 +#define GEOTLK79CDT 0x0E090009 +#define NICSTD79 0x0E09000A +#define NICSTD79CDT 0x0E09000B +#define ROSENT79 0x0E09000C +#define ROSENT79CDT 0x0E09000D +#define ROSSHOT 0x0E09000E +#define ROSSHOTCDT 0x0E09000F +#define ROSTLK79 0x0E090010 +#define ROSTLK79CDT 0x0E090011 + // 18 entities in TXTs, 18 in datafiles. + +#endif //SWORDRES_H diff --git a/sword1/text.cpp b/sword1/text.cpp new file mode 100644 index 0000000000..6b4f354e72 --- /dev/null +++ b/sword1/text.cpp @@ -0,0 +1,177 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#include "stdafx.h" +#include "text.h" +#include "resman.h" +#include "objectman.h" +#include "common/util.h" +#include "swordres.h" +#include "sworddefs.h" + +#define OVERLAP 3 +#define SPACE ' ' +#define BORDER_COL 200 +#define LETTER_COL 193 +#define NO_COL 0 // sprite background - 0 for transparency +#define MAX_LINES 30 + + +SwordText::SwordText(ObjectMan *pObjMan, ResMan *pResMan, bool czechVersion) { + _objMan = pObjMan; + _resMan = pResMan; + _textCount = 0; + if (czechVersion) + _font = (uint8*)_resMan->openFetchRes(CZECH_GAME_FONT); + else + _font = (uint8*)_resMan->openFetchRes(GAME_FONT); + _joinWidth = charWidth( SPACE ) - 2 * OVERLAP; + _charHeight = _resMan->fetchFrame(_font, 0)->height; // all chars have the same height + _textBlocks[0] = _textBlocks[1] = 0; +} + +uint32 SwordText::lowTextManager(uint8 *ascii, int32 width, uint8 pen) { + // get rid of that textId thing! + _textCount++; + if (_textCount > MAX_TEXT_OBS) + error("SwordText::lowTextManager: MAX_TEXT_OBS exceeded!"); + uint32 textObjId = (TEXT_sect * ITM_PER_SEC) - 1; + do { + textObjId++; + } while(_objMan->fetchObject(textObjId)->o_status); + // okay, found a free text object + + _objMan->fetchObject(textObjId)->o_status = STAT_FORE; + makeTextSprite((uint8)textObjId, ascii, (uint16)width, pen); + + return textObjId; +} + +void SwordText::makeTextSprite(uint8 slot, uint8 *text, uint16 maxWidth, uint8 pen) { + LineInfo lines[MAX_LINES]; + uint16 numLines = analyzeSentence(text, maxWidth, lines); + + uint16 sprWidth = 0; + for (uint16 lineCnt = 0; lineCnt < numLines; lineCnt++) + if (lines[lineCnt].width > sprWidth) + sprWidth = lines[lineCnt].width; + uint16 sprHeight = _charHeight * numLines; + uint32 sprSize = sprWidth * sprHeight; + assert(!_textBlocks[slot]); // if this triggers, the speechDriver failed to call SwordText::releaseText. + _textBlocks[slot] = (FrameHeader*)malloc(sprSize + sizeof(FrameHeader)); + + memcpy( _textBlocks[slot]->runTimeComp, "Nu ", 4); + _textBlocks[slot]->compSize = 0; + _textBlocks[slot]->width = sprWidth; + _textBlocks[slot]->height = sprHeight; + _textBlocks[slot]->offsetX = 0; + _textBlocks[slot]->offsetY = 0; + + uint8 *linePtr = ((uint8*)_textBlocks[slot]) + sizeof(FrameHeader); + memset(linePtr, NO_COL, sprSize); + for (uint16 lineCnt = 0; lineCnt < numLines; lineCnt++) { + uint8 *sprPtr = linePtr + (sprWidth - lines[lineCnt].width) / 2; // center the text + for (uint16 pos = 0; pos < lines[lineCnt].length; pos++) + sprPtr += copyChar(*text++, sprPtr, sprWidth, pen) - OVERLAP; + text++; // skip space at the end of the line + linePtr += _charHeight * sprWidth; + } +} + +uint16 SwordText::charWidth(uint8 ch) { + if (ch < SPACE) + ch = 64; + return _resMan->fetchFrame(_font, ch - SPACE)->width; +} + +uint16 SwordText::analyzeSentence(uint8 *text, uint16 maxWidth, LineInfo *line) { + uint16 lineNo = 0; + + bool firstWord = true; + while (*text) { + uint16 wordWidth = 0; + uint16 wordLength = 0; + + while ((*text != SPACE) && *text) { + wordWidth += charWidth(*text) - OVERLAP; + wordLength++; + text++; + } + if (*text == SPACE) + text++; + + wordWidth += OVERLAP; // no overlap on final letter of word! + if( firstWord ) { // first word on first line, so no separating SPACE needed + line[0].width = wordWidth; + line[0].length = wordLength; + firstWord = false; + } else { + // see how much extra space this word will need to fit on current line + // (with a separating space character - also overlapped) + uint16 spaceNeeded = _joinWidth + wordWidth; + + if (line[lineNo].width + spaceNeeded <= maxWidth ) { + line[lineNo].width += spaceNeeded; + line[lineNo].length += 1 + wordLength; // NB. space+word characters + } else { // put word (without separating SPACE) at start of next line + lineNo++; + assert( lineNo < MAX_LINES ); + line[lineNo].width = wordWidth; + line[lineNo].length = wordLength; + } + } + } + return lineNo+1; // return no of lines +} + +uint16 SwordText::copyChar(uint8 ch, uint8 *sprPtr, uint16 sprWidth, uint8 pen) { + FrameHeader *chFrame = _resMan->fetchFrame(_font, ch - SPACE); + uint8 *chData = ((uint8*)chFrame) + sizeof(FrameHeader); + uint8 *dest = sprPtr; + for (uint16 cnty = 0; cnty < chFrame->height; cnty++) { + for (uint16 cntx = 0; cntx < chFrame->width; cntx++) { + if (*chData == LETTER_COL) + dest[cntx] = pen; + else if ((*chData == BORDER_COL) && (!dest[cntx])) // don't do a border if there's already a color underneath (chars can overlap) + dest[cntx] = BORDER_COL; + chData++; + } + dest += sprWidth; + } + return chFrame->width; +} + +FrameHeader *SwordText::giveSpriteData(uint32 textTarget) { + // textTarget is the resource ID of the Compact linking the textdata. + // that's 0x950000 for slot 0 and 0x950001 for slot 1. easy, huh? :) + textTarget &= ITM_ID; + assert(textTarget <= 1); + + return _textBlocks[textTarget]; +} + +void SwordText::releaseText(uint32 id) { + id &= ITM_ID; + assert(id <= 1); + free(_textBlocks[id]); + _textBlocks[id] = NULL; + _textCount--; +} diff --git a/sword1/text.h b/sword1/text.h new file mode 100644 index 0000000000..e74f1ca219 --- /dev/null +++ b/sword1/text.h @@ -0,0 +1,58 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#ifndef BSTEXT_H +#define BSTEXT_H + +#define MAX_TEXT_OBS 2 + +#include "object.h" +#include "sworddefs.h" +class ObjectMan; +class ResMan; + +struct LineInfo { + uint16 width; // width of line in pixels + uint16 length; // length of line in characters +}; + +class SwordText { +public: + SwordText(ObjectMan *pObjMan, ResMan *pResMan, bool czechVersion); + ~SwordText(void); + FrameHeader *giveSpriteData(uint32 textTarget); + uint32 lowTextManager(uint8 *text, int32 width, uint8 pen); + void releaseText(uint32 id); + +private: + void makeTextSprite(uint8 slot, uint8 *text, uint16 maxWidth, uint8 pen); + uint16 analyzeSentence(uint8 *text, uint16 maxWidth, LineInfo *info); + uint16 charWidth(uint8 ch); + uint16 copyChar(uint8 ch, uint8 *sprPtr, uint16 sprWidth, uint8 pen); + uint8 *_font; + uint8 _textCount; + uint16 _charHeight, _joinWidth; + ObjectMan *_objMan; + ResMan *_resMan; + FrameHeader *_textBlocks[MAX_TEXT_OBS]; +}; + +#endif //BSTEXT_H -- cgit v1.2.3