scummvm/engines/draci/game.h
Robert Špalek 403668898f Implement flipping the QuickHero and SpeedText flags in GPL2.
All GPL2 callbacks are now fully implemented.  It remains to implement
proper walking.

svn-id: r45501
2009-10-29 15:26:48 +00:00

451 lines
10 KiB
C++

/* 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$
* $Id$
*
*/
#ifndef DRACI_GAME_H
#define DRACI_GAME_H
#include "common/str.h"
#include "common/serializer.h"
#include "draci/barchive.h"
#include "draci/script.h"
#include "draci/animation.h"
#include "draci/sprite.h"
namespace Draci {
class DraciEngine;
enum {
kDragonObject = 0
};
enum StructSizes {
personSize = sizeof(uint16) * 2 + sizeof(byte)
};
// Used as a return value for Game::getObjectWithAnimation() if no object
// owns the animation in question
enum {
kObjectNotFound = -1
};
// Used as the value of the _escRoom field of the current room if there is
// no escape room defined
enum {
kNoEscRoom = -1
};
// Used as a value to Game::_currentIcon and means there is no item selected
// and a "real" cursor image is used
enum {
kNoItem = -1
};
// Used as a default parameter in Game::loadWalkingMap() to specify that the default
// walking map to the room is to be loaded.
enum {
kDefaultRoomMap = -1
};
enum {
kNoDialogue = -1,
kDialogueLines = 4
};
enum {
kBlackPalette = -1
};
// 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
};
// One fading phase is 50ms.
enum FadeConstants {
kFadingTimeUnit = 50
};
/** Inventory related magical constants */
enum InventoryConstants {
kInventoryItemWidth = 25,
kInventoryItemHeight = 25,
kInventoryColumns = 7,
kInventoryLines = 5,
kInventoryX = 70, ///< Used for positioning of the inventory sprite on the X axis
kInventoryY = 30, ///< Used for positioning of the inventory sprite on the Y axis
kInventorySlots = kInventoryLines * kInventoryColumns
};
class WalkingMap {
public:
WalkingMap() {
_realWidth = 0;
_realHeight = 0;
_mapWidth = 0;
_mapHeight = 0;
_byteWidth = 0;
_data = NULL;
}
void load(const byte *data, uint length) {
Common::MemoryReadStream mapReader(data, length);
_realWidth = mapReader.readUint16LE();
_realHeight = mapReader.readUint16LE();
_deltaX = mapReader.readUint16LE();
_deltaY = mapReader.readUint16LE();
_mapWidth = mapReader.readUint16LE();
_mapHeight = mapReader.readUint16LE();
_byteWidth = mapReader.readUint16LE();
// Set the data pointer to raw map data
_data = data + mapReader.pos();
}
bool isWalkable(int x, int y) const;
Common::Point findNearestWalkable(int x, int y, Common::Rect searchRect) const;
private:
int _realWidth, _realHeight;
int _deltaX, _deltaY;
int _mapWidth, _mapHeight;
int _byteWidth;
const byte *_data;
};
/*
* Enumerates the directions the dragon can look into when arrived.
*/
enum SightDirection {
kDirectionLast, kDirectionMouse, kDirectionUnknown,
kDirectionRight, kDirectionLeft, kDirectionIntelligent
};
struct GameObject {
uint _init, _look, _use, _canUse;
bool _imInit, _imLook, _imUse;
int _walkDir;
byte _z;
uint _lookX, _lookY, _useX, _useY;
SightDirection _lookDir, _useDir;
uint _absNum;
Common::Array<int> _anim;
GPL2Program _program;
Common::String _title;
int _location;
bool _visible;
};
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;
};
struct GameItem {
uint _init, _look, _use, _canUse;
bool _imInit, _imLook, _imUse;
GPL2Program _program;
Common::String _title;
};
struct Person {
uint _x, _y;
byte _fontColour;
};
struct Dialogue {
int _canLen;
byte *_canBlock;
Common::String _title;
GPL2Program _program;
};
struct Room {
int _roomNum;
byte _music;
WalkingMap _walkingMap;
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;
};
enum LoopStatus {
kStatusOrdinary,
kStatusGate,
kStatusInventory,
kStatusDialogue
};
enum LoopSubstatus {
kSubstatusOrdinary,
kSubstatusTalk,
kSubstatusFade,
kSubstatusStrange
};
/**
* Enumerates the animations for the dragon's movement.
*/
enum Movement {
kMoveUndefined = -1,
kMoveDown, kMoveUp, kMoveRight, kMoveLeft,
kMoveRightDown, kMoveRightUp, kMoveLeftDown, kMoveLeftUp,
kMoveDownRight, kMoveUpRight, kMoveDownLeft, kMoveUpLeft,
kMoveLeftRight, kMoveRightLeft, kMoveUpStopLeft, kMoveUpStopRight,
kSpeakRight, kSpeakLeft, kStopRight, kStopLeft
};
class Game {
public:
Game(DraciEngine *vm);
~Game();
void init();
void start();
void loop();
// HACK: this is only for testing
int nextRoomNum() const {
int n = _currentRoom._roomNum;
n = n < 37 ? n+1 : n;
// disable former distributor logo
if (n == 30)
++n;
return n;
}
// HACK: same as above
int prevRoomNum() const {
int n = _currentRoom._roomNum;
n = n > 0 ? n-1 : n;
// disable former distributor logo
if (n == 30)
--n;
return n;
}
void walkHero(int x, int y, SightDirection dir);
int getHeroX() const;
int getHeroY() const;
void positionAnimAsHero(Animation *anim);
void playHeroAnimation(int anim_index);
int loadAnimation(uint animNum, uint z);
void loadOverlays();
void loadObject(uint numObj);
void loadWalkingMap(int mapID = kDefaultRoomMap);
void loadItem(int itemID);
uint getNumObjects() const;
GameObject *getObject(uint objNum);
int getObjectWithAnimation(int animID) const;
void deleteObjectAnimations();
void deleteAnimationsAfterIndex(int lastAnimIndex);
void stopObjectAnimations(const GameObject *obj);
int playingObjectAnimation(const GameObject *obj) const;
int getVariable(int varNum) const;
void setVariable(int varNum, int value);
const Person *getPerson(int personID) const;
int getRoomNum() const;
void setRoomNum(int num);
int getPreviousRoomNum() const;
void rememberRoomNumAsPrevious();
void scheduleEnteringRoomUsingGate(int room, int gate);
void pushNewRoom();
void popNewRoom();
double getPers0() const;
double getPersStep() const;
int getMusicTrack() const;
void setMusicTrack(int num);
int getItemStatus(int itemID) const;
void setItemStatus(int itemID, int status);
int getCurrentItem() const;
void setCurrentItem(int itemID);
void removeItem(int itemID);
void putItem(int itemID, int position);
void addItem(int itemID);
int getEscRoom() const;
int getMapRoom() const;
int getMarkedAnimationIndex() const;
void setMarkedAnimationIndex(int index);
void setLoopStatus(LoopStatus status);
void setLoopSubstatus(LoopSubstatus status);
LoopStatus getLoopStatus() const;
LoopSubstatus getLoopSubstatus() const;
bool shouldQuit() const { return _shouldQuit; }
void setQuit(bool quit) { _shouldQuit = quit; }
int shouldExitLoop() const { return _shouldExitLoop; }
void setExitLoop(int exit) { _shouldExitLoop = exit; }
void setSpeechTiming(uint tick, uint duration);
void shiftSpeechAndFadeTick(int delta);
void updateTitle();
void updateCursor();
void inventoryInit();
void inventoryDraw();
void inventoryDone();
void inventoryReload();
void dialogueMenu(int dialogueID);
int dialogueDraw();
void dialogueInit(int dialogID);
void dialogueDone();
void runDialogueProg(GPL2Program, int offset);
bool isDialogueBegin() const;
bool shouldExitDialogue() const;
void setDialogueExit(bool exit);
int getDialogueBlockNum() const;
int getDialogueVar(int dialogueID) const;
void setDialogueVar(int dialogueID, int value);
int getCurrentDialogue() const;
int getDialogueCurrentBlock() const;
int getDialogueLastBlock() const;
int getDialogueLinesNum() const;
int getCurrentDialogueOffset() const;
void schedulePalette(int paletteID);
int getScheduledPalette() const;
void initializeFading(int phases);
void setEnableQuickHero(bool value);
bool getEnableQuickHero() const { return _enableQuickHero; }
void setWantQuickHero(bool value);
bool getWantQuickHero() const { return _wantQuickHero; }
void setEnableSpeedText(bool value);
bool getEnableSpeedText() const { return _enableSpeedText; }
void DoSync(Common::Serializer &s);
private:
void enterNewRoom(bool force_reload);
void loadRoom(int roomNum);
void runGateProgram(int gate);
DraciEngine *_vm;
GameInfo _info;
Common::Point _hero;
int *_variables;
Person *_persons;
GameObject *_objects;
byte *_itemStatus;
GameItem *_items;
int _currentItem;
int _itemUnderCursor;
int _inventory[kInventorySlots];
bool _inventoryExit;
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;
int _shouldExitLoop; // 0=false and 1=true are normal, 2=immediate exit after loading
uint _speechTick;
uint _speechDuration;
int _objUnderCursor;
int _oldObjUnderCursor;
int _animUnderCursor;
int _markedAnimationIndex; ///< Used by the Mark GPL command
int _scheduledPalette;
int _fadePhases;
int _fadePhase;
uint _fadeTick;
bool _enableQuickHero;
bool _wantQuickHero;
bool _enableSpeedText;
};
} // End of namespace Draci
#endif // DRACI_GAME_H