/* 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 ULTIMA4_CONTROLLERS_INTRO_CONTROLLER_H #define ULTIMA4_CONTROLLERS_INTRO_CONTROLLER_H #include "ultima/ultima4/controllers/controller.h" #include "ultima/ultima4/core/observer.h" #include "ultima/ultima4/filesys/savegame.h" #include "ultima/ultima4/views/menu.h" #include "ultima/ultima4/views/textview.h" #include "ultima/ultima4/views/imageview.h" #include "ultima/ultima4/views/tileview.h" #include "common/file.h" namespace Ultima { namespace Ultima4 { class IntroObjectState; class Tile; /** * Binary data loaded from the U4DOS title.exe file. */ class IntroBinData { private: // disallow assignments, copy construction IntroBinData(const IntroBinData &); const IntroBinData &operator=(const IntroBinData &); void openFile(Common::File &f, const Common::String &name); public: IntroBinData(); ~IntroBinData(); bool load(); Std::vector _introMap; byte *_sigData; byte *_scriptTable; Tile **_baseTileTable; byte *_beastie1FrameTable; byte *_beastie2FrameTable; Std::vector _introText; Std::vector _introQuestions; Std::vector _introGypsy; }; /** * Controls the title animation sequences, including the traditional * plotted "Lord British" signature, the pixelized fade-in of the * "Ultima IV" game title, as well as the other more simple animated * features, followed by the traditional animated map and "Journey * Onward" menu, plus the xU4-specific configuration menu. * * @todo *
    *
  • make initial menu a Menu too
  • *
  • get rid of mode and switch(mode) statements
  • *
  • get rid global intro instance -- should only need to be accessed from u4.cpp
  • *
*/ class IntroController : public Controller, public Observer { public: IntroController(); ~IntroController() override; /** * Initializes intro state and loads in introduction graphics, text * and map data from title.exe. */ bool init(); bool hasInitiatedNewGame(); /** * Frees up data not needed after introduction. */ void deleteIntro(); /** * Handles keystrokes during the introduction. */ bool keyPressed(int key) override; /** * Mouse button was pressed */ bool mousePressed(const Common::Point &mousePos) override; byte *getSigData(); /** * Paints the screen. */ void updateScreen(); /** * Timer callback for the intro sequence. Handles animating the intro * map, the beasties, etc.. */ void timerFired() override; /** * Preload map tiles */ void preloadMap(); /** * Update the screen when an observed menu is reset or has an item * activated. * TODO: Reduce duped code. */ void update(Menu *menu, MenuEvent &event) override; void updateConfMenu(MenuEvent &event); void updateVideoMenu(MenuEvent &event); void updateGfxMenu(MenuEvent &event); void updateSoundMenu(MenuEvent &event); void updateInputMenu(MenuEvent &event); void updateSpeedMenu(MenuEvent &event); void updateGameplayMenu(MenuEvent &event); void updateInterfaceMenu(MenuEvent &event); // // Title methods // /** * Initialize the title elements */ void initTitles(); /** * Update the title element, drawing the appropriate frame of animation */ bool updateTitle(); private: /** * Draws the small map on the intro screen. */ void drawMap(); void drawMapStatic(); void drawMapAnimated(); /** * Draws the animated beasts in the upper corners of the screen. */ void drawBeasties(); /** * Animates the "beasties". The animate intro image is made up frames * for the two creatures in the top left and top right corners of the * screen. This function draws the frame for the given beastie on the * screen. vertoffset is used lower the creatures down from the top * of the screen. */ void drawBeastie(int beast, int vertoffset, int frame); /** * Animates the moongate in the tree intro image. There are two * overlays in the part of the image normally covered by the text. If * the frame parameter is "moongate", the moongate overlay is painted * over the image. If frame is "items", the second overlay is * painted: the circle without the moongate, but with a small white * dot representing the anhk and history book. */ void animateTree(const Common::String &frame); /** * Draws the cards in the character creation sequence with the gypsy. */ void drawCard(int pos, int card); /** * Draws the beads in the abacus during the character creation sequence */ void drawAbacusBeads(int row, int selectedVirtue, int rejectedVirtue); /** * Initializes the question tree. The tree starts off with the first * eight entries set to the numbers 0-7 in a random order. */ void initQuestionTree(); /** * Updates the question tree with the given answer, and advances to * the next round. * @return true if all questions have been answered, false otherwise */ bool doQuestion(int answer); /** * Build the initial avatar player record from the answers to the * gypsy's questions. */ void initPlayers(SaveGame *saveGame); /** * Get the text for the question giving a choice between virtue v1 and * virtue v2 (zero based virtue index, starting at honesty). */ Common::String getQuestion(int v1, int v2); #ifdef IOS_ULTIMA4 public: /** * Try to put the intro music back at just the correct moment on iOS; * don't play it at the very beginning. */ void tryTriggerIntroMusic(); #endif /** * Initiate a new savegame by reading the name, sex, then presenting a * series of questions to determine the class of the new character. */ void initiateNewGame(); void finishInitiateGame(const Common::String &nameBuffer, SexType sex); /** * Starts the gypsys questioning that eventually determines the new * characters class. */ void startQuestions(); void showStory(); /** * Starts the game. */ void journeyOnward(); /** * Shows an about box. */ void about(); #ifdef IOS_ULTIMA4 private: #endif /** * Shows text in the question area. */ void showText(const Common::String &text); /** * Run a menu and return when the menu has been closed. Screen * updates are handled by observing the menu. */ void runMenu(Menu *menu, TextView *view, bool withBeasties); /** * The states of the intro. */ enum { INTRO_TITLES, // displaying the animated intro titles INTRO_MAP, // displaying the animated intro map INTRO_MENU, // displaying the main menu: journey onward, etc. INTRO_ABOUT } _mode; enum MenuConstants { MI_CONF_VIDEO, MI_CONF_SOUND, MI_CONF_INPUT, MI_CONF_SPEED, MI_CONF_GAMEPLAY, MI_CONF_INTERFACE, MI_CONF_01, MI_VIDEO_CONF_GFX, MI_VIDEO_02, MI_VIDEO_03, MI_VIDEO_07, MI_VIDEO_08, MI_GFX_SCHEME, MI_GFX_TILE_TRANSPARENCY, MI_GFX_TILE_TRANSPARENCY_SHADOW_SIZE, MI_GFX_TILE_TRANSPARENCY_SHADOW_OPACITY, MI_GFX_RETURN, MI_SOUND_03, MI_INPUT_03, MI_SPEED_01, MI_SPEED_02, MI_SPEED_03, MI_SPEED_04, MI_SPEED_05, MI_SPEED_06, MI_SPEED_07, MI_GAMEPLAY_01, MI_GAMEPLAY_02, MI_GAMEPLAY_03, MI_GAMEPLAY_04, MI_GAMEPLAY_05, MI_GAMEPLAY_06, MI_INTERFACE_01, MI_INTERFACE_02, MI_INTERFACE_03, MI_INTERFACE_04, MI_INTERFACE_05, MI_INTERFACE_06, USE_SETTINGS = 0xFE, CANCEL = 0xFF }; ImageView _backgroundArea; TextView _menuArea; TextView _extendedMenuArea; TextView _questionArea; TileView _mapArea; Image *_mapScreen; // menus Menu _mainMenu; Menu _confMenu; Menu _videoMenu; Menu _gfxMenu; Menu _soundMenu; Menu _inputMenu; Menu _speedMenu; Menu _gameplayMenu; Menu _interfaceMenu; // data loaded in from title.exe IntroBinData *_binData; // additional introduction state data Common::String _errorMessage; int _answerInd; int _questionRound; int _questionTree[15]; int _beastie1Cycle; int _beastie2Cycle; int _beastieOffset; bool _beastiesVisible; int _sleepCycles; int _scrPos; /* current position in the script table */ IntroObjectState *_objectStateTable; bool _justInitiatedNewGame; Common::String _profileName; bool _useProfile; // // Title defs, structs, methods, and data members // enum AnimType { SIGNATURE, AND, BAR, ORIGIN, PRESENT, TITLE, SUBTITLE, MAP }; struct AnimPlot { uint8 x, y; uint8 r, g, b, a; }; struct AnimElement { void shufflePlotData(); int _rx, _ry; // screen/source x and y int _rw, _rh; // source width and height AnimType _method; // render method int _animStep; // tracks animation position int _animStepMax; int _timeBase; // initial animation time uint32 _timeDelay; // delay before rendering begins int _timeDuration; // total animation time Image *_srcImage; // storage for the source image Image *_destImage; // storage for the animation frame Std::vector _plotData; // plot data bool _prescaled; }; /** * Add the intro element to the element list */ void addTitle(int x, int y, int w, int h, AnimType method, uint32 delay, int duration); /** * The title element has finished drawing all frames, so delete, remove, * or free data that is no longer needed */ void compactTitle(); /** * Scale the animation canvas, then draw it to the screen */ void drawTitle(); /** * Get the source data for title elements that have already been initialized */ void getTitleSourceData(); /** * skip the remaining titles */ void skipTitles(); Std::vector _titles; // list of title elements Std::vector::iterator _title; // current title element int _transparentIndex; // palette index for transparency RGBA _transparentColor; // palette color for transparency bool _bSkipTitles; // Temporary place-holder for settings changes SettingsData _settingsChanged; }; extern IntroController *g_intro; } // End of namespace Ultima4 } // End of namespace Ultima #endif