1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #ifndef TWINE_MENU_H 24 #define TWINE_MENU_H 25 26 #include "twine/twine.h" 27 #include "twine/text.h" 28 29 namespace TwinE { 30 31 #define MAX_BUTTONS 10 32 #define PLASMA_WIDTH 320 33 #define PLASMA_HEIGHT 50 34 #define kQuitEngine 9998 35 36 class BodyData; 37 class SpriteData; 38 39 class MenuSettings { 40 private: 41 enum MenuSettingsType { 42 // button number 43 MenuSettings_CurrentLoadedButton = 0, 44 // is used to calc the height where the first button will appear 45 MenuSettings_NumberOfButtons = 1, 46 MenuSettings_ButtonsBoxHeight = 2, 47 MenuSettings_HeaderEnd = 3, // TODO: unknown 48 MenuSettings_FirstButtonState = 4, 49 MenuSettings_FirstButton = 5 50 }; 51 52 int16 _settings[4 + MAX_BUTTONS * 2] {0}; 53 Common::String _buttonTexts[MAX_BUTTONS]; 54 int8 _activeButtonIdx = 0; 55 56 public: getButtonTextId(int buttonIndex)57 TextId getButtonTextId(int buttonIndex) const { 58 return (TextId)_settings[MenuSettings_FirstButton + buttonIndex * 2]; 59 } 60 reset()61 void reset() { 62 for (int32 i = 0; i < MAX_BUTTONS; ++i) { 63 _buttonTexts[i] = ""; 64 } 65 _settings[MenuSettings_NumberOfButtons] = 0; 66 setButtonsBoxHeight(0); 67 setActiveButton(0); 68 } 69 70 // used to calc the height where the first button will appear setButtonsBoxHeight(int16 height)71 void setButtonsBoxHeight(int16 height) { 72 _settings[MenuSettings_ButtonsBoxHeight] = height; 73 } 74 setActiveButton(int16 buttonIdx)75 void setActiveButton(int16 buttonIdx) { 76 _activeButtonIdx = buttonIdx; 77 _settings[MenuSettings_CurrentLoadedButton] = buttonIdx; 78 } 79 setActiveButtonTextId(TextId textIndex)80 void setActiveButtonTextId(TextId textIndex) { 81 setButtonTextId(getActiveButton(), textIndex); 82 } 83 setButtonTextId(int16 buttonIdx,TextId textIndex)84 void setButtonTextId(int16 buttonIdx, TextId textIndex) { 85 _settings[MenuSettings_FirstButton + buttonIdx * 2] = (int16)textIndex; 86 _buttonTexts[buttonIdx].clear(); 87 } 88 getActiveButtonTextId()89 TextId getActiveButtonTextId() const { 90 return getButtonTextId(getActiveButton()); 91 } 92 getActiveButtonState()93 int16 getActiveButtonState() const { 94 return getButtonState(getActiveButton()); 95 } 96 getButtonState(int buttonIndex)97 int16 getButtonState(int buttonIndex) const { 98 return _settings[MenuSettings_FirstButtonState + buttonIndex * 2]; 99 } 100 101 const char *getButtonText(Text *text, int buttonIndex); 102 getActiveButton()103 int16 getActiveButton() const { 104 return _activeButtonIdx; 105 } 106 getButtonBoxHeight()107 int16 getButtonBoxHeight() const { 108 return _settings[MenuSettings_ButtonsBoxHeight]; 109 } 110 getButtonCount()111 int16 getButtonCount() const { 112 return _settings[MenuSettings_NumberOfButtons]; 113 } 114 setTextBankId(TextBankId textBankIndex)115 void setTextBankId(TextBankId textBankIndex) { 116 _settings[MenuSettings_HeaderEnd] = (int16)textBankIndex; 117 } 118 119 void addButton(TextId textId, int16 state = 0) { 120 const int16 i = _settings[MenuSettings_NumberOfButtons]; 121 _settings[i * 2 + MenuSettings_FirstButtonState] = state; 122 _settings[i * 2 + MenuSettings_FirstButton] = (int16)textId; 123 ++_settings[MenuSettings_NumberOfButtons]; 124 } 125 126 void addButton(const char *text, int16 state = 0) { 127 const int16 i = _settings[MenuSettings_NumberOfButtons]; 128 _settings[i * 2 + MenuSettings_FirstButtonState] = state; 129 // will return the button index 130 _settings[i * 2 + MenuSettings_FirstButton] = i; 131 _buttonTexts[i] = text; 132 ++_settings[MenuSettings_NumberOfButtons]; 133 } 134 }; 135 136 class Menu { 137 private: 138 TwinEEngine *_engine; 139 /** Hero behaviour menu entity */ 140 BodyData *_behaviourEntity = nullptr; 141 /** Behaviour menu anim state */ 142 uint _behaviourAnimState[4]; // winTab 143 /** Behaviour menu anim data pointer */ 144 AnimTimerDataStruct _behaviourAnimData[4]; 145 146 int32 _inventorySelectedColor = COLOR_BLACK; 147 int32 _inventorySelectedItem = 0; // currentSelectedObjectInInventory 148 149 /** Plasma Effect pointer to file content: RESS.HQR:51 */ 150 uint8 *_plasmaEffectPtr = nullptr; 151 152 MenuSettings _giveUpMenuWithSaveState; 153 MenuSettings _volumeMenuState; 154 MenuSettings _saveManageMenuState; 155 MenuSettings _giveUpMenuState; 156 MenuSettings _mainMenuState; 157 MenuSettings _advOptionsMenuState; 158 MenuSettings _optionsMenuState; 159 160 // objectRotation 161 int16 _itemAngle[NUM_INVENTORY_ITEMS]; 162 /** Behaviour menu move pointer */ 163 ActorMoveStruct _moveMenu; 164 165 /** 166 * Draws main menu button 167 * @param buttonId current button identification from menu settings 168 * @param dialText 169 * @param hover flag to know if should draw as a hover button or not 170 */ 171 void drawButtonGfx(const MenuSettings *menuSettings, const Common::Rect &rect, int32 buttonId, const char *dialText, bool hover); 172 void plasmaEffectRenderFrame(); 173 /** 174 * Process the menu button draw 175 * @param data menu settings array 176 * @param mode flag to know if should draw as a hover button or not 177 */ 178 int16 drawButtons(MenuSettings *menuSettings, bool hover); 179 /** Used to run the advanced options menu */ 180 int32 advoptionsMenu(); 181 /** Used to run the volume menu */ 182 int32 volumeMenu(); 183 /** Used to run the save game management menu */ 184 int32 savemanageMenu(); 185 void drawInfoMenu(int16 left, int16 top, int16 width); 186 Common::Rect calcBehaviourRect(int32 left, int32 top, HeroBehaviourType behaviour) const; 187 bool isBehaviourHovered(int32 left, int32 top, HeroBehaviourType behaviour) const; 188 void drawBehaviour(int32 left, int32 top, HeroBehaviourType behaviour, int32 angle, bool cantDrawBox); 189 void drawInventoryItems(int32 left, int32 top); 190 void prepareAndDrawBehaviour(int32 left, int32 top, int32 angle, HeroBehaviourType behaviour); 191 void drawBehaviourMenu(int32 left, int32 top, int32 angle); 192 void drawItem(int32 left, int32 top, int32 item); 193 194 void drawSpriteAndString(int32 left, int32 top, const SpriteData &spriteData, const Common::String &str, int32 color = COLOR_GOLD); 195 196 public: 197 Menu(TwinEEngine *engine); 198 ~Menu(); 199 200 /** 201 * Process the plasma effect 202 * @param color plasma effect start color 203 */ 204 void processPlasmaEffect(const Common::Rect &rect, int32 color); 205 206 void drawHealthBar(int32 left, int32 right, int32 top, int32 barLeftPadding, int32 barHeight); 207 void drawCloverLeafs(int32 newBoxLeft, int32 boxRight, int32 top); 208 void drawMagicPointsBar(int32 left, int32 right, int32 top, int32 barLeftPadding, int32 barHeight); 209 void drawCoins(int32 left, int32 top); 210 void drawKeys(int32 left, int32 top); 211 212 /** 213 * Draw the rect lines without filling the area 214 * @param left start width to draw the button 215 * @param top start height to draw the button 216 * @param right end width to draw the button 217 * @param bottom end height to draw the button 218 */ 219 void drawRectBorders(int32 left, int32 top, int32 right, int32 bottom, int32 colorLeftTop = COLOR_79, int32 colorRightBottom = COLOR_73); 220 void drawRectBorders(const Common::Rect &rect, int32 colorLeftTop = COLOR_79, int32 colorRightBottom = COLOR_73); 221 /** 222 * Where the main menu options are processed 223 * @param menuSettings menu settings array with the information to build the menu options 224 * @return pressed menu button identification 225 */ 226 int32 processMenu(MenuSettings *menuSettings, bool showCredits = true); 227 228 bool init(); 229 230 /** Used to run the main menu */ 231 EngineState run(); 232 233 /** Used to run the in-game give-up menu */ 234 int32 giveupMenu(); 235 236 void inGameOptionsMenu(); 237 238 /** Used to run the options menu */ 239 int32 optionsMenu(); 240 241 /** Process hero behaviour menu */ 242 void processBehaviourMenu(); 243 244 /** Process in-game inventory menu */ 245 void processInventoryMenu(); 246 }; 247 248 } // namespace TwinE 249 250 #endif 251