/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ /* * This code is based on original Hugo Trilogy source code * * Copyright (c) 1989-1995 David P. Gray * */ #ifndef HUGO_SCHEDULE_H #define HUGO_SCHEDULE_H #include "common/file.h" namespace Hugo { /** * Following defines the action types and action list */ enum Action { // Parameters: ANULL = 0xff, // Special NOP used to 'delete' events in DEL_EVENTS ASCHEDULE = 0, // 0 - Ptr to action list to be rescheduled START_OBJ, // 1 - Object number INIT_OBJXY, // 2 - Object number, x,y PROMPT, // 3 - index of prompt & response string, ptrs to action // lists. First if response matches, 2nd if not. BKGD_COLOR, // 4 - new background color INIT_OBJVXY, // 5 - Object number, vx, vy INIT_CARRY, // 6 - Object number, carried status INIT_HF_COORD, // 7 - Object number (gets hero's 'feet' coordinates) NEW_SCREEN, // 8 - New screen number INIT_OBJSTATE, // 9 - Object number, new object state INIT_PATH, // 10 - Object number, new path type COND_R, // 11 - Conditional on object state - req state, 2 act_lists TEXT, // 12 - Simple text box SWAP_IMAGES, // 13 - Swap 2 object images COND_SCR, // 14 - Conditional on current screen AUTOPILOT, // 15 - Set object to home in on another (stationary) object INIT_OBJ_SEQ, // 16 - Object number, sequence index to set curr_seqPtr to SET_STATE_BITS, // 17 - Objnum, mask to OR with obj states word CLEAR_STATE_BITS, // 18 - Objnum, mask to ~AND with obj states word TEST_STATE_BITS, // 19 - Objnum, mask to test obj states word DEL_EVENTS, // 20 - Action type to delete all occurrences of GAMEOVER, // 21 - Disable hero & commands. Game is over INIT_HH_COORD, // 22 - Object number (gets hero's actual coordinates) EXIT, // 23 - Exit game back to DOS BONUS, // 24 - Get score bonus for an action COND_BOX, // 25 - Conditional on object within bounding box SOUND, // 26 - Set currently playing sound ADD_SCORE, // 27 - Add object's value to current score SUB_SCORE, // 28 - Subtract object's value from current score COND_CARRY, // 29 - Conditional on carrying object INIT_MAZE, // 30 - Start special maze hotspot processing EXIT_MAZE, // 31 - Exit special maze processing INIT_PRIORITY, // 32 - Initialize fbg field INIT_SCREEN, // 33 - Initialize screen field of object AGSCHEDULE, // 34 - Global schedule - lasts over new screen REMAPPAL, // 35 - Remappe palette - palette index, color COND_NOUN, // 36 - Conditional on noun appearing in line SCREEN_STATE, // 37 - Set new screen state - used for comments INIT_LIPS, // 38 - Position lips object for supplied object INIT_STORY_MODE, // 39 - Set story mode TRUE/FALSE (user can't type) WARN, // 40 - Same as TEXT but can't dismiss box by typing COND_BONUS, // 41 - Conditional on bonus having been scored TEXT_TAKE, // 42 - Issue text box with "take" info string YESNO, // 43 - Prompt user for Yes or No STOP_ROUTE, // 44 - Skip any route in progress (hero still walks) COND_ROUTE, // 45 - Conditional on route in progress INIT_JUMPEXIT, // 46 - Initialize status.jumpexit INIT_VIEW, // 47 - Initialize viewx, viewy, dir INIT_OBJ_FRAME, // 48 - Object number, seq,frame to set curr_seqPtr to OLD_SONG = 49 // Added by Strangerke - Set currently playing sound, old way: that is, using a string index instead of a reference in a file }; struct act0 { // Type 0 - Schedule Action _actType; // The type of action int _timer; // Time to set off the action uint16 _actIndex; // Ptr to an action list }; struct act1 { // Type 1 - Start an object Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number int _cycleNumb; // Number of times to cycle Cycle _cycle; // Direction to start cycling }; struct act2 { // Type 2 - Initialize an object coords Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number int _x, _y; // Coordinates }; struct act3 { // Type 3 - Prompt user for text Action _actType; // The type of action int _timer; // Time to set off the action uint16 _promptIndex; // Index of prompt string int *_responsePtr; // Array of indexes to valid response string(s) (terminate list with -1) uint16 _actPassIndex; // Ptr to action list if success uint16 _actFailIndex; // Ptr to action list if failure bool _encodedFl; // (HUGO 1 DOS ONLY) Whether response is encoded or not }; struct act4 { // Type 4 - Set new background color Action _actType; // The type of action int _timer; // Time to set off the action long _newBackgroundColor; // New color }; struct act5 { // Type 5 - Initialize an object velocity Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number int _vx, _vy; // velocity }; struct act6 { // Type 6 - Initialize an object carrying Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number bool _carriedFl; // carrying }; struct act7 { // Type 7 - Initialize an object to hero's coords Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number }; struct act8 { // Type 8 - switch to new screen Action _actType; // The type of action int _timer; // Time to set off the action int _screenIndex; // The new screen number }; struct act9 { // Type 9 - Initialize an object state Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number byte _newState; // New state }; struct act10 { // Type 10 - Initialize an object path type Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number int _newPathType; // New path type int8 _vxPath, _vyPath; // Max delta velocities e.g. for CHASE }; struct act11 { // Type 11 - Conditional on object's state Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number byte _stateReq; // Required state uint16 _actPassIndex; // Ptr to action list if success uint16 _actFailIndex; // Ptr to action list if failure }; struct act12 { // Type 12 - Simple text box Action _actType; // The type of action int _timer; // Time to set off the action int _stringIndex; // Index (enum) of string in strings.dat }; struct act13 { // Type 13 - Swap first object image with second Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex1; // Index of first object int _objIndex2; // 2nd }; struct act14 { // Type 14 - Conditional on current screen Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The required object int _screenReq; // The required screen number uint16 _actPassIndex; // Ptr to action list if success uint16 _actFailIndex; // Ptr to action list if failure }; struct act15 { // Type 15 - Home in on an object Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex1; // The object number homing in int _objIndex2; // The object number to home in on int8 _dx, _dy; // Max delta velocities }; // Note: Don't set a sequence at time 0 of a new screen, it causes // problems clearing the boundary bits of the object! timer > 0 is safe struct act16 { // Type 16 - Set curr_seqPtr to seq Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number int _seqIndex; // The index of seq array to set to }; struct act17 { // Type 17 - SET obj individual state bits Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number int _stateMask; // The mask to OR with current obj state }; struct act18 { // Type 18 - CLEAR obj individual state bits Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number int _stateMask; // The mask to ~AND with current obj state }; struct act19 { // Type 19 - TEST obj individual state bits Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number int _stateMask; // The mask to AND with current obj state uint16 _actPassIndex; // Ptr to action list (all bits set) uint16 _actFailIndex; // Ptr to action list (not all set) }; struct act20 { // Type 20 - Remove all events with this type of action Action _actType; // The type of action int _timer; // Time to set off the action Action _actTypeDel; // The action type to remove }; struct act21 { // Type 21 - Gameover. Disable hero & commands Action _actType; // The type of action int _timer; // Time to set off the action }; struct act22 { // Type 22 - Initialize an object to hero's coords Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number }; struct act23 { // Type 23 - Exit game back to DOS Action _actType; // The type of action int _timer; // Time to set off the action }; struct act24 { // Type 24 - Get bonus score Action _actType; // The type of action int _timer; // Time to set off the action int _pointIndex; // Index into points array }; struct act25 { // Type 25 - Conditional on bounding box Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The required object number int _x1, _y1, _x2, _y2; // The bounding box uint16 _actPassIndex; // Ptr to action list if success uint16 _actFailIndex; // Ptr to action list if failure }; struct act26 { // Type 26 - Play a sound Action _actType; // The type of action int _timer; // Time to set off the action int16 _soundIndex; // Sound index in data file }; struct act27 { // Type 27 - Add object's value to score Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // object number }; struct act28 { // Type 28 - Subtract object's value from score Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // object number }; struct act29 { // Type 29 - Conditional on object carried Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The required object number uint16 _actPassIndex; // Ptr to action list if success uint16 _actFailIndex; // Ptr to action list if failure }; struct act30 { // Type 30 - Start special maze processing Action _actType; // The type of action int _timer; // Time to set off the action byte _mazeSize; // Size of (square) maze int _x1, _y1, _x2, _y2; // Bounding box of maze int _x3, _x4; // Extra x points for perspective correction byte _firstScreenIndex; // First (top left) screen of maze }; struct act31 { // Type 31 - Exit special maze processing Action _actType; // The type of action int _timer; // Time to set off the action }; struct act32 { // Type 32 - Init fbg field of object Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number byte _priority; // Value of foreground/background field }; struct act33 { // Type 33 - Init screen field of object Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number int _screenIndex; // Screen number }; struct act34 { // Type 34 - Global Schedule Action _actType; // The type of action int _timer; // Time to set off the action uint16 _actIndex; // Ptr to an action list }; struct act35 { // Type 35 - Remappe palette Action _actType; // The type of action int _timer; // Time to set off the action int16 _oldColorIndex; // Old color index, 0..15 int16 _newColorIndex; // New color index, 0..15 }; struct act36 { // Type 36 - Conditional on noun mentioned Action _actType; // The type of action int _timer; // Time to set off the action uint16 _nounIndex; // The required noun (list) uint16 _actPassIndex; // Ptr to action list if success uint16 _actFailIndex; // Ptr to action list if failure }; struct act37 { // Type 37 - Set new screen state Action _actType; // The type of action int _timer; // Time to set off the action int _screenIndex; // The screen number byte _newState; // The new state }; struct act38 { // Type 38 - Position lips Action _actType; // The type of action int _timer; // Time to set off the action int _lipsObjIndex; // The LIPS object int _objIndex; // The object to speak byte _dxLips; // Relative offset of x byte _dyLips; // Relative offset of y }; struct act39 { // Type 39 - Init story mode Action _actType; // The type of action int _timer; // Time to set off the action bool _storyModeFl; // New state of story_mode flag }; struct act40 { // Type 40 - Unsolicited text box Action _actType; // The type of action int _timer; // Time to set off the action int _stringIndex; // Index (enum) of string in strings.dat }; struct act41 { // Type 41 - Conditional on bonus scored Action _actType; // The type of action int _timer; // Time to set off the action int _bonusIndex; // Index into bonus list uint16 _actPassIndex; // Index of the action list if scored for the first time uint16 _actFailIndex; // Index of the action list if already scored }; struct act42 { // Type 42 - Text box with "take" string Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object taken }; struct act43 { // Type 43 - Prompt user for Yes or No Action _actType; // The type of action int _timer; // Time to set off the action int _promptIndex; // index of prompt string uint16 _actYesIndex; // Ptr to action list if YES uint16 _actNoIndex; // Ptr to action list if NO }; struct act44 { // Type 44 - Stop any route in progress Action _actType; // The type of action int _timer; // Time to set off the action }; struct act45 { // Type 45 - Conditional on route in progress Action _actType; // The type of action int _timer; // Time to set off the action int _routeIndex; // Must be >= current status.rindex uint16 _actPassIndex; // Ptr to action list if en-route uint16 _actFailIndex; // Ptr to action list if not }; struct act46 { // Type 46 - Init status.jumpexit Action _actType; // The type of action int _timer; // Time to set off the action bool _jumpExitFl; // New state of jumpexit flag }; struct act47 { // Type 47 - Init viewx,viewy,dir Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object int16 _viewx; // object.viewx int16 _viewy; // object.viewy int16 _direction; // object.dir }; struct act48 { // Type 48 - Set curr_seqPtr to frame n Action _actType; // The type of action int _timer; // Time to set off the action int _objIndex; // The object number int _seqIndex; // The index of seq array to set to int _frameIndex; // The index of frame to set to }; struct act49 { // Added by Strangerke - Type 49 - Play a song (DOS way) Action _actType; // The type of action int _timer; // Time to set off the action uint16 _songIndex; // Song index in string array }; union Act { act0 _a0; act1 _a1; act2 _a2; act3 _a3; act4 _a4; act5 _a5; act6 _a6; act7 _a7; act8 _a8; act9 _a9; act10 _a10; act11 _a11; act12 _a12; act13 _a13; act14 _a14; act15 _a15; act16 _a16; act17 _a17; act18 _a18; act19 _a19; act20 _a20; act21 _a21; act22 _a22; act23 _a23; act24 _a24; act25 _a25; act26 _a26; act27 _a27; act28 _a28; act29 _a29; act30 _a30; act31 _a31; act32 _a32; act33 _a33; act34 _a34; act35 _a35; act36 _a36; act37 _a37; act38 _a38; act39 _a39; act40 _a40; act41 _a41; act42 _a42; act43 _a43; act44 _a44; act45 _a45; act46 _a46; act47 _a47; act48 _a48; act49 _a49; }; struct Event { Act *_action; // Ptr to action to perform bool _localActionFl; // true if action is only for this screen uint32 _time; // (absolute) time to perform action struct Event *_prevEvent; // Chain to previous event struct Event *_nextEvent; // Chain to next event }; /** * Following are points for achieving certain actions. */ struct Point { byte _score; // The value of the point bool _scoredFl; // Whether scored yet }; class Scheduler { public: Scheduler(HugoEngine *vm); virtual ~Scheduler(); virtual void decodeString(char *line) = 0; virtual void runScheduler() = 0; int16 calcMaxPoints() const; void freeScheduler(); void initCypher(); void initEventQueue(); void insertActionList(const uint16 actIndex); void loadActListArr(Common::ReadStream &in); void loadAlNewscrIndex(Common::ReadStream &in); void loadPoints(Common::SeekableReadStream &in); void loadScreenAct(Common::SeekableReadStream &in); void newScreen(const int screenIndex); void processBonus(const int bonusIndex); void processMaze(const int x1, const int x2, const int y1, const int y2); void restoreSchedulerData(Common::ReadStream *in); void restoreScreen(const int screenIndex); void saveSchedulerData(Common::WriteStream *out); void waitForRefresh(); protected: HugoEngine *_vm; static const int kFilenameLength = 12; // Max length of a DOS file name static const int kMaxEvents = 50; // Max events in event queue static const int kShiftSize = 8; // Place hero this far inside bounding box Common::String _cypher; uint16 _actListArrSize; uint16 _alNewscrIndex; uint16 _screenActsSize; uint16 **_screenActs; byte _numBonuses; Point *_points; uint32 _curTick; // Current system time in ticks uint32 _oldTime; // The previous wall time in ticks uint32 _refreshTimeout; Event *_freeEvent; // Free list of event structures Event *_headEvent; // Head of list (earliest time) Event *_tailEvent; // Tail of list (latest time) Event _events[kMaxEvents]; // Statically declare event structures Act **_actListArr; virtual const char *getCypher() const = 0; virtual uint32 getTicks() = 0; virtual void promptAction(Act *action) = 0; Event *doAction(Event *curEvent); Event *getQueue(); uint32 getDosTicks(const bool updateFl); uint32 getWinTicks() const; void delEventType(const Action actTypeDel); void delQueue(Event *curEvent); void findAction(const Act* action, int16* index, int16* subElem); void insertAction(Act *action); void readAct(Common::ReadStream &in, Act &curAct); void restoreActions(Common::ReadStream *f); void restoreEvents(Common::ReadStream *f); void restorePoints(Common::ReadStream *in); void saveActions(Common::WriteStream* f) const; void saveEvents(Common::WriteStream *f); void savePoints(Common::WriteStream *out) const; void screenActions(const int screenNum); }; class Scheduler_v1d : public Scheduler { public: Scheduler_v1d(HugoEngine *vm); ~Scheduler_v1d(); virtual void decodeString(char *line); virtual void runScheduler(); protected: virtual const char *getCypher() const; virtual uint32 getTicks(); virtual void promptAction(Act *action); }; class Scheduler_v2d : public Scheduler_v1d { public: Scheduler_v2d(HugoEngine *vm); virtual ~Scheduler_v2d(); void decodeString(char *line); protected: virtual const char *getCypher() const; void promptAction(Act *action); }; class Scheduler_v3d : public Scheduler_v2d { public: Scheduler_v3d(HugoEngine *vm); ~Scheduler_v3d(); protected: const char *getCypher() const; }; class Scheduler_v1w : public Scheduler_v3d { public: Scheduler_v1w(HugoEngine *vm); ~Scheduler_v1w(); void runScheduler(); protected: uint32 getTicks(); }; } // End of namespace Hugo #endif //HUGO_SCHEDULE_H