Logo Search packages:      
Sourcecode: scummvm version File versions  Download package

game.h

/* 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.
 *
 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/tags/release-1-2-0/engines/draci/game.h $
 * $Id: game.h 50519 2010-06-30 08:27:09Z spalek $
 *
 */

#ifndef DRACI_GAME_H
#define DRACI_GAME_H

#include "common/str.h"
#include "draci/script.h"
#include "draci/walking.h"

namespace Common {
      class Serializer;
}

namespace Draci {

class BArchive;
class DraciEngine;

enum {
      kDragonObject = 0
};

enum {
      kDialogueLines = 4
};

enum {
      kBlackPalette = -1
};

enum {
      kMouseEnableSwitching = -1,
      kMouseDoNotSwitch = -2
};

// Constants tuned such that with ScummVM's default talkspeed kStandardSpeed, the speed
// computed by equation (kBaseSpeechDuration + kSpeechTimeUnit * #characters) /
// talkspeed is equal to the original game.
enum SpeechConstants {
      kBaseSpeechDuration = 12000,
      kSpeechTimeUnit = 2640,
      kStandardSpeed = 60
};

enum FadeConstants {
      // One fading phase called from the game scripts is 50ms.
      kFadingTimeUnit = 50,
      // Fading in/out when entering/leaving a location takes 15 iterations of (at least) 7ms each.
      kBlackFadingIterations = 15,
      kBlackFadingTimeUnit = 7
};

enum AnimationConstants {
      kTimeUnit = 20
};

/** Inventory related magical constants */
00081 enum InventoryConstants {
  kInventoryItemWidth = 25,
  kInventoryItemHeight = 25,
  kInventoryColumns = 7,
  kInventoryLines = 5,
00086   kInventoryX = 70, ///< Used for positioning of the inventory sprite on the X axis
00087   kInventoryY = 30, ///< Used for positioning of the inventory sprite on the Y axis
  kInventorySlots = kInventoryLines * kInventoryColumns,
  kStatusChangeTimeout = 500
};

class GameObject {
public:
      int _absNum;
      uint _init, _look, _use, _canUse;
      bool _imInit, _imLook, _imUse;
      int _walkDir;
      byte _z;
      uint _lookX, _lookY, _useX, _useY;
      SightDirection _lookDir, _useDir;
      GPL2Program _program;
      Common::String _title;
      int _location;
      bool _visible;

      Common::Array<Animation *> _anim;
      int _playingAnim;

      int getAnim(int animID) const;
      int addAnim(Animation *anim);
      int playingAnim() const { return _playingAnim; }
      void playAnim(int i);
      void stopAnim();
      void deleteAnims();
      void deleteAnimsFrom(int index);
      void load(uint objNum, BArchive *archive);
};

struct GameInfo {
      int _startRoom;
      int _mapRoom;
      uint _numObjects;
      uint _numItems;
      byte _numVariables;
      byte _numPersons;
      byte _numDialogues;
      uint _maxItemWidth, _maxItemHeight;
      uint _musicLength;
      uint _crc[4];
      uint _numDialogueBlocks;
};

class GameItem {
public:
      int _absNum;
      uint _init, _look, _use, _canUse;
      bool _imInit, _imLook, _imUse;
      GPL2Program _program;
      Common::String _title;

      Animation *_anim;

      void load(int itemID, BArchive *archive);
};

struct Person {
      uint _x, _y;
      byte _fontColour;
};

struct Dialogue {
      int _canLen;
      byte *_canBlock;
      Common::String _title;
      GPL2Program _program;
};

class Room {
public:
      int _roomNum;
      byte _music;
      int _mapID;
      int _palette;
      int _numOverlays;
      int _init, _look, _use, _canUse;
      bool _imInit, _imLook, _imUse;
      bool _mouseOn, _heroOn;
      double _pers0, _persStep;
      int _escRoom;
      byte _numGates;
      Common::Array<int> _gates;
      GPL2Program _program;

      void load(int roomNum, BArchive *archive);
};

enum LoopStatus {
      kStatusOrdinary,  // normal game-play: everything allowed
      kStatusGate,            // during running init-scripts when entering a room: disable interactivity
      kStatusInventory, // inventory is open: cannot change the room or go to map
      kStatusDialogue         // during a dialogue: cannot change the room, go to inventory
};

enum LoopSubstatus {
      kOuterLoop,       // outer loop: everything is allowed
      kInnerWhileTalk,  // playing a voice: inner loop will exit afterwards
      kInnerWhileFade,  // fading a palette: inner loop will exit when done
      kInnerDuringDialogue,   // selecting continuation block: inner block will exit afterwards
      kInnerUntilExit         // other inner loop: either immediately exiting or waiting for an animation to end (whose callback ends the loop)
};

class Game {
public:
      Game(DraciEngine *vm);
      ~Game();

      void init();
      void start();
      void loop(LoopSubstatus substatus, bool shouldExit);

      // HACK: this is only for testing
      int nextRoomNum() const {
            int n = _currentRoom._roomNum;
            n = n < 37 ? n+1 : n;
            return n;
      }

      // HACK: same as above
      int prevRoomNum() const {
            int n = _currentRoom._roomNum;
            n = n > 0 ? n-1 : n;
            return n;
      }

      Common::Point findNearestWalkable(int x, int y) const { return _walkingMap.findNearestWalkable(x, y); }
      void heroAnimationFinished() { _walkingState.heroAnimationFinished(); }
      void stopWalking() { _walkingState.stopWalking(); }   // and clear callback
      void walkHero(int x, int y, SightDirection dir);      // start walking and leave callback as is
      void setHeroPosition(const Common::Point &p);
      const Common::Point &getHeroPosition() const { return _hero; }
      void positionAnimAsHero(Animation *anim);
      void positionHeroAsAnim(Animation *anim);

      // Makes sure animation anim_index plays on the hero.  If the hero's
      // position has changed, it updates the animation position.  If the new
      // animation is different, it stops the old one and starts the new one,
      // otherwise it just marks dirty rectangles for moving the position.
      // Returns the current animation phase of the new animation (usually 0
      // unless the animation hasn't changed).
      int playHeroAnimation(int anim_index);

      void loadOverlays();
      void loadWalkingMap(int mapID);           // but leaves _currentRoom._mapID untouched
      void switchWalkingAnimations(bool enabled);

      uint getNumObjects() const { return _info._numObjects; }
      GameObject *getObject(uint objNum) { return _objects + objNum; }
      const GameObject *getObjectWithAnimation(const Animation *anim) const;
      void deleteObjectAnimations();
      void deleteAnimationsAfterIndex(int lastAnimIndex);

      int getVariable(int varNum) const { return _variables[varNum]; }
      void setVariable(int varNum, int value) { _variables[varNum] = value; }

      const Person *getPerson(int personID) const { return &_persons[personID]; }

      int getRoomNum() const { return _currentRoom._roomNum; }
      void setRoomNum(int num) { _currentRoom._roomNum = num; }
      int getPreviousRoomNum() const { return _previousRoom; }
      void rememberRoomNumAsPrevious() { _previousRoom = getRoomNum(); }
      void scheduleEnteringRoomUsingGate(int room, int gate) { _newRoom = room; _newGate = gate; }
      void pushNewRoom();
      void popNewRoom();

      double getPers0() const { return _currentRoom._pers0; }
      double getPersStep() const { return _currentRoom._persStep; }
      int getMusicTrack() const { return _currentRoom._music; }
      void setMusicTrack(int num) { _currentRoom._music = num; }

      int getItemStatus(int itemID) const { return _itemStatus[itemID]; }
      void setItemStatus(int itemID, int status) { _itemStatus[itemID] = status; }
      GameItem *getItem(int id) { return id >= 0 && id < (int) _info._numItems ? &_items[id] : NULL; }
      GameItem *getCurrentItem() const { return _currentItem; }
      void setCurrentItem(GameItem *item) { _currentItem = item; }
      int getPreviousItemPosition() const { return _previousItemPosition; }
      void setPreviousItemPosition(int pos) { _previousItemPosition = pos; }
      void removeItem(GameItem *item);
      void loadItemAnimation(GameItem *item);
      void putItem(GameItem *item, int position);
      void addItem(int itemID);

      int getEscRoom() const { return _currentRoom._escRoom; }
      int getMapRoom() const { return _info._mapRoom; }
      int getMapID() const { return _currentRoom._mapID; }

      /**
       * The GPL command Mark sets the animation index (which specifies the
       * order in which animations were loaded in) which is then used by the
       * Release command to delete all animations that have an index greater
       * than the one marked.
       */
      int getMarkedAnimationIndex() const { return _markedAnimationIndex; }
      void setMarkedAnimationIndex(int index) { _markedAnimationIndex = index; }

      void setLoopStatus(LoopStatus status) { _loopStatus = status; }
      void setLoopSubstatus(LoopSubstatus status) { _loopSubstatus = status; }
      LoopStatus getLoopStatus() const { return _loopStatus; }
      LoopSubstatus getLoopSubstatus() const { return _loopSubstatus; }

      bool gameShouldQuit() const { return _shouldQuit; }
      void setQuit(bool quit) { _shouldQuit = quit; }
      bool shouldExitLoop() const { return _shouldExitLoop; }
      void setExitLoop(bool exit) { _shouldExitLoop = exit; }
      bool isReloaded() const { return _isReloaded; }
      void setIsReloaded(bool value) { _isReloaded = value; }

      void setSpeechTiming(uint tick, uint duration);
      void shiftSpeechAndFadeTick(int delta);

      void inventoryInit();
      void inventoryDraw();
      void inventoryDone();
      void inventoryReload();
      void inventorySwitch(int keycode);

      void dialogueMenu(int dialogueID);
      int dialogueDraw();
      void dialogueInit(int dialogID);
      void dialogueDone();

      bool isDialogueBegin() const { return _dialogueBegin; }
      bool shouldExitDialogue() const { return _dialogueExit; }
      void setDialogueExit(bool exit) { _dialogueExit = exit; }
      int getDialogueBlockNum() const { return _blockNum; }
      int getDialogueVar(int dialogueID) const { return _dialogueVars[dialogueID]; }
      void setDialogueVar(int dialogueID, int value) { _dialogueVars[dialogueID] = value; }
      int getCurrentDialogue() const { return _currentDialogue; }
      int getDialogueCurrentBlock() const { return _currentBlock; }
      int getDialogueLastBlock() const { return _lastBlock; }
      int getDialogueLinesNum() const { return _dialogueLinesNum; }
      int getCurrentDialogueOffset() const { return _dialogueOffsets[_currentDialogue]; }

      void schedulePalette(int paletteID) { _scheduledPalette = paletteID; }
      int getScheduledPalette() const { return _scheduledPalette; }
      void initializeFading(int phases);
      void setEnableQuickHero(bool value) { _enableQuickHero = value; }
      bool getEnableQuickHero() const { return _enableQuickHero; }
      void setWantQuickHero(bool value) { _wantQuickHero = value; }
      bool getWantQuickHero() const { return _wantQuickHero; }
      void setEnableSpeedText(bool value) { _enableSpeedText = value; }
      bool getEnableSpeedText() const { return _enableSpeedText; }

      void DoSync(Common::Serializer &s);

private:
      void updateOrdinaryCursor();
      void updateInventoryCursor();
      int inventoryPositionFromMouse() const;
      void handleOrdinaryLoop(int x, int y);
      void handleInventoryLoop();
      void handleDialogueLoop();
      void updateTitle(int x, int y);
      void updateCursor();
      void fadePalette(bool fading_out);
      void advanceAnimationsAndTestLoopExit();
      void handleStatusChangeByMouse();

      void enterNewRoom();
      void initWalkingOverlays();
      void loadRoomObjects();
      void redrawWalkingPath(Animation *anim, byte colour, const WalkingPath &path);

      DraciEngine *_vm;

      GameInfo _info;

      Common::Point _hero;

      int *_variables;
      Person *_persons;
      GameObject *_objects;

      byte *_itemStatus;
      GameItem *_items;
      GameItem *_currentItem;
      GameItem *_itemUnderCursor;

      // Last position in the inventory of the item currently in the hands, resp. of the item that
      // was last in our hands.
      int _previousItemPosition;

      GameItem *_inventory[kInventorySlots];

      Room _currentRoom;
      int _newRoom;
      int _newGate;
      int _previousRoom;
      int _pushedNewRoom;     // used in GPL programs
      int _pushedNewGate;

      uint *_dialogueOffsets;
      int _currentDialogue;
      int *_dialogueVars;
      BArchive *_dialogueArchive;
      Dialogue *_dialogueBlocks;
      bool _dialogueBegin;
      bool _dialogueExit;
      int _currentBlock;
      int _lastBlock;
      int _dialogueLinesNum;
      int _blockNum;
      int _lines[kDialogueLines];
      Animation *_dialogueAnims[kDialogueLines];

      LoopStatus _loopStatus;
      LoopSubstatus _loopSubstatus;

      bool _shouldQuit;
      bool _shouldExitLoop;
      bool _isReloaded;

      uint _speechTick;
      uint _speechDuration;

      const GameObject *_objUnderCursor;
      const Animation *_animUnderCursor;

      int _markedAnimationIndex; ///< Used by the Mark GPL command

      int _scheduledPalette;
      int _fadePhases;
      int _fadePhase;
      uint _fadeTick;
      int _mouseChangeTick;

      bool _enableQuickHero;
      bool _wantQuickHero;
      bool _enableSpeedText;

      WalkingMap _walkingMap;
      WalkingState _walkingState;

      Animation *_titleAnim;
      Animation *_inventoryAnim;
      Animation *_walkingMapOverlay;
      Animation *_walkingShortestPathOverlay;
      Animation *_walkingObliquePathOverlay;
};

} // End of namespace Draci

#endif // DRACI_GAME_H

Generated by  Doxygen 1.6.0   Back to index