/* 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 3 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, see . * */ #ifndef TOT_H #define TOT_H #include "common/error.h" #include "common/events.h" #include "common/fs.h" #include "common/hash-str.h" #include "common/memstream.h" #include "common/random.h" #include "common/scummsys.h" #include "common/serializer.h" #include "common/system.h" #include "common/util.h" #include "engines/engine.h" #include "engines/savestate.h" #include "graphics/screen.h" #include "tot/chrono.h" #include "tot/detection.h" #include "tot/events.h" #include "tot/graphics.h" #include "tot/mouse.h" #include "tot/sound.h" #include "tot/types.h" namespace Tot { struct TotGameDescription; enum TotAction { kActionEscape, kActionVolume, kActionSaveLoad, kActionTalk, kActionPickup, kActionLookAt, kActionUse, kActionOpen, kActionClose, kActionYes, kActionNo }; class TotEngine : public Engine { private: Common::RandomSource _randomSource; void handleEvent(Common::Event e); /** * Uses a serializer to allow implementing savegame * loading and saving using a single method */ Common::Error syncGame(Common::Serializer &s); int engineStart(); int startGame(); void newGame(); void resumeGame(); void changeRoom(); void loadScrollData(uint roomCode, bool rightScroll, uint horizontalPos, int scrollCorrection); void drawText(uint number); void displayLoading(); void runaroundRed(); void sprites(bool drawCharacter); SavedGame *saveGameToRegister(); void originalSaveLoadScreen(); void loadGame(SavedGame *game); RoomFileRegister *readScreenDataFile(Common::SeekableReadStream *screenDataFile); void lookAtObject(byte objectNumber); void useInventoryObjectWithInventoryObject(int16 obj1, int16 obj2); void pickupScreenObject(); void useScreenObject(); void openScreenObject(); void closeScreenObject(); void action(); void handleAction(byte invPos); void loadInventory(); void obtainName(Common::String &playerName); void calculateRoute(byte zone1, byte zone2, bool extraCorrection = false, bool zonavedada = false); void wcScene(); void advanceAnimations(bool barredZone, bool animateMouse); void updateSecondaryAnimationDepth(); void updateMainCharacterDepth(); void actionLineText(const Common::String &actionLine); void initializeObjectFile(); void saveObjectsData(ScreenObject *object, Common::SeekableWriteStream *out); void scrollLeft(uint horizontalPos); void scrollRight(uint horizontalPos); TextEntry readTextRegister(uint numRegister); void readConversationFile(); void adjustKey(); void adjustKey2(); void animateBat(); void updateVideo(); void nicheAnimation(byte nicheDir, int32 bitmap); void replaceBackpack(byte obj1, uint obj2); void dropObjectInScreen(ScreenObject *replacementObject); void calculateTrajectory(uint finalX, uint finalY); void animatedSequence(uint numSequence); void initScreenPointers(); void loadAnimation(const Common::String &animation); void loadCharAnimation(); void animateGive(uint dir, uint height); void animatePickup1(uint dir, uint height); void animatePickup2(uint dir, uint height); void animateOpen2(uint dir, uint height); void loadTV(); void loadScreen(); void loadScreenLayerWithDepth(uint coordx, uint coordy, uint bitmapSize, int32 bitmapIndex, uint depth); void loadScreenLayer(uint coordx, uint coordy, uint picSize, int32 pic, uint prof); void readBitmap(int32 bitmapOffset, byte *bitmap, uint bitmapSize, uint errorCode); void updateAltScreen(byte altScreenNumber); void freeInventory(); void updateInventory(byte index); void updateObject(uint filePos); void readObject(Common::SeekableReadStream *stream, uint objPos, ScreenObject *thisRegObj); void saveObject(ScreenObject *object, Common::SeekableWriteStream *stream); void saveItemRegister(); void saveTemporaryGame(); void drawLookAtItem(RoomObjectListEntry obj); void putIcon(uint posX, uint posY, uint iconNumber); void drawInventory(byte direction, byte limit); void generateDiploma(Common::String &photoName); void credits(); void checkMouseGrid(); void introduction(); void firstIntroduction(); void readAlphaGraph(Common::String &data, int length, int x, int y, byte barColor); void readAlphaGraphSmall(Common::String &data, int length, int x, int y, byte barColor, byte textColor, Common::Event startEvent); void displayObjectDescription(const Common::String &text); void copyProtection(); void initialLogo(); void mainMenu(bool fade); void exitToDOS(); void soundControls(); void sacrificeScene(); void ending(); void loadBat(); void loadDevil(); void assembleCompleteBackground(byte *image, uint coordx, uint coordy); void assembleScreen(bool scroll = false); void disableSecondAnimation(); void clearGame(); // vars void initVars(); void resetGameState(); void clearVars(); void processEvents(bool &escapePressed); void oldProcessEvents(bool &escapePressed); protected: // Engine APIs Common::Error run() override; void syncSoundSettings() override; public: Graphics::Screen *_screen = nullptr; GraphicsManager *_graphics = nullptr; SoundManager *_sound = nullptr; MouseManager *_mouse = nullptr; ChronoManager *_chrono = nullptr; Tot::TotEventManager *_events = nullptr; const ADGameDescription *_gameDescription; bool _showMouseGrid = false; bool _showScreenGrid = false; bool _showGameGrid = false; bool _drawObjectAreas = false; Common::Language _lang = Common::ES_ESP; Common::MemorySeekableReadWriteStream *_conversationData = nullptr; Common::MemorySeekableReadWriteStream *_rooms = nullptr; Common::MemorySeekableReadWriteStream *_sceneObjectsData = nullptr; bool _roomChange = false; bool _isTVOn = false; bool _isVasePlaced = false; bool _isScytheTaken = false; bool _isTridentTaken = false; bool _isPottersWheelDelivered = false; bool _isMudDelivered = false; bool _isGreenDevilDelivered = false; bool _isRedDevilCaptured = false; bool _isPottersManualDelivered = false; bool _isCupboardOpen = false; bool _isChestOpen = false; bool _isTrapSet = false; bool _isPeterCoughing = false; bool _isSealRemoved = false; bool _inGame = false; bool _firstTimeDone = false; // Flag for first time run of the game. bool _isIntroSeen = false; bool _shouldQuitGame = false; bool _startNewGame = false; // Flag to initialize game bool _continueGame = false; // Flag to resume game bool _isSavingDisabled = false; bool _isDrawingEnabled = false; // true if sprites should be drawn bool _isSecondaryAnimationEnabled = false; // Whether room has secondary animation InventoryEntry _inventory[kInventoryIconCount]; // These are the icons currnetly in the inventory /** * Keeps an array of all inventory icon bitmaps */ byte *_inventoryIconBitmaps[kInventoryIconCount] = { nullptr }; /** * Position within inventory */ byte _inventoryPosition = 0; /** * Animation sequences */ CharacterAnim _mainCharAnimation; uint _mainCharFrameSize = 0; SecondaryAnim _secondaryAnimation; uint _secondaryAnimFrameSize = 0; /** * Currently selected action. */ byte _actionCode = 0; /** * Previously selected action. */ byte _oldActionCode = 0; /** * Number of trajectory changes */ byte _trajectorySteps = 0; /** * index of currently selected door. */ byte _doorIndex = 0; /** * 1 first part, 2 second part */ byte _gamePart = 1; /** * Number of frames of secondary animation */ byte _secondaryAnimationFrameCount = 0; /** * Number of directions of the secondary animation */ byte _secondaryAnimDirCount = 0; /** * Data protection control */ byte _cpCounter = 0, _cpCounter2 = 0; /** * Coordinates of target step */ byte _destinationX = 0, _destinationY = 0; /** * Current character facing direction * 0: upwards * 1: right * 2: downwards * 3: left */ byte _charFacingDirection = 0; /** * Width and height of secondary animation */ uint _secondaryAnimWidth = 0, _secondaryAnimHeight = 0; /** * Code of selected object in the backpack */ uint _backpackObjectCode = 0; /** * Auxiliary vars for grid update */ uint _oldposx = 0, _oldposy = 0; /** * Amplitude of movement */ int _element1 = 0, _element2 = 0; /** * Current position of the main character */ uint16 _characterPosX = 0, _characterPosY = 0; /** * Target position of the main character? */ int _xframe2 = 0, _yframe2 = 0; /** * Text map */ Common::File _verbFile; /** * Auxiliary vars with current inventory object name. */ Common::String _oldInventoryObjectName, _inventoryObjectName; /** * Name of player */ Common::String _characterName = ""; Common::String _decryptionKey; /** * State of the niches in part 2 */ uint _niche[2][4]; RoomFileRegister *_currentRoomData = nullptr; ScreenObject *_curObject = nullptr; // Currently selected object in the screen /** * New movement to execute. */ Route _mainRoute; /** * Matrix of positions for a trajectory between two points */ Common::Point _trajectory[300]; /** * Longitude of the trajectory matrix. */ uint _trajectoryLength = 0; /** * Position within the trajectory matrix */ uint _currentTrajectoryIndex = 0; /** * Position within the trajectory matrix for secondary animation */ uint _currentSecondaryTrajectoryIndex = 0; /** * Screen areas */ byte _currentZone = 0, _targetZone = 0, _oldTargetZone = 0; /** * Amplitude of grid slices */ byte _maxXGrid = 0, _maxYGrid = 0; /** * capture of movement grid of secondary animation */ byte _movementGridForSecondaryAnim[10][10]; /** * capture of mouse grid of secondary animation */ byte _mouseGridForSecondaryAnim[10][10]; /** * movement mask for grid of secondary animation */ byte _maskGridSecondaryAnim[10][10]; /** * mouse mask for grid of secondary animation */ byte _maskMouseSecondaryAnim[10][10]; bool _list1Complete = false, _list2Complete = false, _obtainedList1 = false, // whether we've been given list 1 _obtainedList2 = false; // whether we've been given list 2 /** Conversation topic unlocks */ bool _firstTimeTopicA[kCharacterCount] = { false }, _firstTimeTopicB[kCharacterCount] = { false }, _firstTimeTopicC[kCharacterCount] = { false }, _bookTopic[kCharacterCount] = { false }, _mintTopic[kCharacterCount] = { false }; bool _caves[5] = { false }; /** * First and second lists of objects to retrieve in the game */ uint16 _firstList[5] = { 0 }, _secondList[5] = { 0 }; int32 _screenSize = 65520; /** * Frame number for the animations */ byte _iframe = 0, _iframe2 = 0; /** * Depth of screenobjects */ ObjectInfo _depthMap[kNumScreenOverlays]; /** * Bitmaps of screenobjects */ byte *_screenLayers[kNumScreenOverlays] = { nullptr }; /** * Current frame of main character */ byte *_curCharacterAnimationFrame = nullptr; /** * Current frame of secondary animation */ byte *_curSecondaryAnimationFrame = nullptr; /** * Pointer storing the screen as it displays on the game */ byte *_sceneBackground = nullptr; /** * Dirty patch of screen to repaint on every frame */ byte *_characterDirtyRect = nullptr; /** * Stores a copy of the background bitmap */ byte *_backgroundCopy = nullptr; uint _currentRoomNumber = 0; bool _isLoadingFromLauncher = false; bool _saveAllowed = false; /** * Previous positions of the mouse within the screen grid */ uint _oldGridX = 0, _oldGridY = 0; uint _curDepth = 0; /** * Point of origin of the area surrounding the main character. * Calculated using the position of the character. */ uint16 _dirtyMainSpriteX = 0, _dirtyMainSpriteY = 0; /** * End point of origin of the area surrounding the main character. * Calculated using the position of the character + dimension */ uint _dirtyMainSpriteX2 = 0, _dirtyMainSpriteY2 = 0; byte *_spriteBackground = nullptr; public: TotEngine(OSystem *syst, const ADGameDescription *gameDesc); ~TotEngine() override; uint32 getFeatures() const; /** * Returns the game Id */ Common::String getGameId() const; /** * Gets a random number */ uint32 getRandomNumber(uint maxNum) { return _randomSource.getRandomNumber(maxNum); } bool hasFeature(EngineFeature f) const override { return (f == kSupportsLoadingDuringRuntime) || (f == kSupportsSavingDuringRuntime) || (f == kSupportsReturnToLauncher); }; void drawFontSurface(Graphics::BgiFont &litt); // Save/Load Common::Error saveGameStream(Common::WriteStream *stream, bool isAutosave = false) override; Common::Error loadGameStream(Common::SeekableReadStream *stream) override; bool canLoadGameStateCurrently(Common::U32String *msg = nullptr) override; bool canSaveGameStateCurrently(Common::U32String *msg = nullptr) override; void loadScreenData(uint screenNumber); void clearScreenLayers(); void clearAnimation(); void buttonBorder(uint x1, uint y1, uint x2, uint y2, byte color1, byte color2, byte color3, byte color4, byte color5); void drawMenu(byte menuNumber); void drawLeftArrow(uint x, uint y); void drawRightArrow(uint x, uint y); void readTextFile(); void loadAnimationForDirection(Common::SeekableReadStream *stream, int direction); void sayLine(uint textRef, byte textColor, byte shadowColor, uint &responseNumber, bool isWithinConversation); void goToObject(byte zone1, byte zone2); void readObject(uint objPos); TextEntry readTextRegister(); void drawInventory(); void drawInventoryMask(); void setRoomTrajectories(int height, int width, TRAJECTORIES_OP op, bool fixGrids = true); void saveRoomData(RoomFileRegister *room, Common::SeekableWriteStream *stream); //vars void initializeScreenFile(); }; extern TotEngine *g_engine; #define SHOULD_QUIT ::Tot::g_engine->shouldQuit() } // End of namespace Tot #endif // TOT_H