Initial commit
This commit is contained in:
436
engines/ultima/ultima4/controllers/intro_controller.h
Normal file
436
engines/ultima/ultima4/controllers/intro_controller.h
Normal file
@@ -0,0 +1,436 @@
|
||||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#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<MapTile> _introMap;
|
||||
byte *_sigData;
|
||||
byte *_scriptTable;
|
||||
Tile **_baseTileTable;
|
||||
byte *_beastie1FrameTable;
|
||||
byte *_beastie2FrameTable;
|
||||
Std::vector<Common::String> _introText;
|
||||
Std::vector<Common::String> _introQuestions;
|
||||
Std::vector<Common::String> _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
|
||||
* <ul>
|
||||
* <li>make initial menu a Menu too</li>
|
||||
* <li>get rid of mode and switch(mode) statements</li>
|
||||
* <li>get rid global intro instance -- should only need to be accessed from u4.cpp</li>
|
||||
* </ul>
|
||||
*/
|
||||
class IntroController : public Controller, public Observer<Menu *, MenuEvent &> {
|
||||
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 <AnimPlot> _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<AnimElement> _titles; // list of title elements
|
||||
Std::vector<AnimElement>::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
|
||||
Reference in New Issue
Block a user