ScummVM API documentation
view1.h
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 modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (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, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef MACS2_VIEW1_H
23 #define MACS2_VIEW1_H
24 
25 #include "macs2/events.h"
26 #include "macs2/macs2.h"
27 
28 namespace Macs2 {
29 
30 class ScummUI;
31 class GameObject;
32 
33 enum class ViewMode {
34  VM_GAME,
35  VM_HELP
36 };
37 
38 enum class FadeMode {
39  None,
40  FromBlack,
41  ToBlack
42 };
43 
44 class Button {
45 public:
46  Common::Point _position;
47  Common::Point _size;
48  Common::String _caption;
49 
50  bool isPointInside(const Common::Point &p) const;
51 
52  void render(Graphics::ManagedSurface &s);
53 };
54 
55 class Character {
56 private:
57  Common::Point _startPosition;
58 
59  uint32 _startTime = 0;
60  uint32 _duration = 0;
61 
62  bool _lerpIgnoresObstacles = false;
63 
64  // If this is set, a lerp to a location becomes picking up
65  Macs2::GameObject *_pickedUpObject = nullptr;
66 
67  // Frame counter for pickup animation (runtime+0x215).
68  // Increments each frame while orientation == 0x11.
69  // At _pickupFrameStart: item is transferred to inventory.
70  // At _pickupFrameEnd: animation ends, orientation restored.
71 public:
72  uint16 _pickupFrameCounter = 0;
73  bool _pickupItemTransferred = false;
74  bool _markedForDeletion = false;
75 
76  uint8 _previousOrientation = 0;
77 
78 private:
79  // Handle when the character has moved into a non-walkable area, push them out if
80  // they did and return true, return false otherwise
81  bool HandleWalkability(Character *c);
82 
83  // fn0037_0E8C proc
84  uint16 lookupWalkability(const Common::Point &p) const;
85 
86 public:
87  Character();
88 
89  // Walk state from walkAlongPath (1008:1b8f) - runtime offsets +0x00..+0x0A, +0x18, +0x33
90  Common::Point _targetPosition; // runtime[+0x00, +0x02]: next waypoint
91  int16 _stepDeltaX = 0; // runtime[+0x04]: abs(endX - startX)
92  int16 _stepDeltaY = 0; // runtime[+0x06]: abs(endY - startY)
93  int16 _stepError = 0; // runtime[+0x18]: Bresenham error accumulator
94  bool _stepDirectionSet = false; // runtime[+0x33]: direction has been calculated
95 
97  int16 _currentPathIndex = 0;
98  // Raw 32-byte runtime path block at object runtime +0x0C. The original game
99  // stores opaque per-waypoint data here (not just node indices). We preserve
100  // it verbatim across save/load so DOS saves round-trip byte-for-byte; our own
101  // pathfinding uses _path. Saved/restored by syncGame.
102  uint8 _pathBlockRaw[32] = {0};
103  Common::Point _pathFinalDestination;
104  Common::Array<uint8> _pathfindingOverlay;
105 
106  bool isWalkable(const Common::Point &p) const;
107  bool calculatePath(Common::Point target);
108  bool canNodeConnectSourceToTarget(uint16 nodeIndex, const Common::Point &charPos, const Common::Point &target, const bool *reachable, int nodeCount);
109  void floodFillConnectedNodes(int nodeIndex, bool *visited, int nodeCount);
110  // Returns false if we are at the end of the path already or the path is not valid
111  bool walkAlongPath();
112  void startLerpTo(const Common::Point &target, uint32 duration, bool ignoreObstacles = false);
113  void startPickup(Macs2::GameObject *object);
114 
115  Common::Point getPosition() const;
116  void setPosition(const Common::Point &newPosition);
117  Macs2::GameObject *_gameObject = nullptr;
118 
119  uint16 getVerticalOffset() const;
120 
121  uint8 _animationIndex = 1;
122  uint16 _motionTargetVerticalOffset = 0;
123  uint16 _motionVerticalOffsetDelta = 0;
124  uint16 _motionDistanceUnits = 0;
125  uint16 _motionProgress = 0;
126  uint16 _motionStartVerticalOffset = 0;
127  bool _shouldMirrorCurrentAnimation = false;
128 
129  // Binary walkAlongPath (1008:1b8f): no separate motion flag; active when
130  // runtime+0x21D >= 0 and differs from object vertical offset (+0x08).
131  bool hasPendingVerticalMotion() const;
132  bool shouldStepVerticalMotion() const;
133 
134  bool isAnimationMirrored() const;
135  uint8 getMirroredAnimation(uint8 original) const;
136 
137  // advanceMode matches drawAnimFrame/advanceAnimFrame (1010:16e7): 0=current frame,
138  // 2=advance sequence after returning current frame. Hit testing uses 0; drawing uses 2.
139  bool fillCurrentAnimationFrame(uint16 advanceMode, Macs2::AnimFrame &out);
140  Macs2::AnimFrame *getCurrentAnimationFrame(uint16 advanceMode);
141  Macs2::AnimFrame *getCurrentPortrait(bool onRightSide = false, uint16 frameIndex = 2);
142 
143  void update();
144 };
145 
146 // Binary scriptMoveObject (1008:aa83): copies object x/y into runtime position and target.
147 void resetCharacterWalkPath(Character *character);
148 
149 // cf https://stackoverflow.com/a/51497820
150 template<typename T, T V>
152 
153 template<typename T, T V>
154 constexpr bool is_in_list_helper(T const &t, is_in_list_value<T, V>) {
155  return t == V;
156 }
157 
158 template<typename T, T V, T W, T... Rest>
159 constexpr bool is_in_list_helper(T const &t, is_in_list_value<T, V>, is_in_list_value<T, W>, is_in_list_value<T, Rest>...) {
160  return (t == V) || is_in_list_helper(t, is_in_list_value<T, W>(), is_in_list_value<T, Rest>()...);
161 }
162 
163 template<typename T, T... ts>
164 constexpr bool is_in_list(T const &t) {
165  return is_in_list_helper(t, is_in_list_value<T, ts>()...);
166 }
167 
168 
170  Character *speaker = nullptr;
172  Common::Point position;
173  bool onRightSide = false;
174  // Mouth animation counter from handleTimerCallback (1008:d38b).
175  // Decremented each frame. Controls which portrait frame is drawn:
176  // >1: draw frame 2 from primary portrait blob (+0x14C)
177  // ==0: draw frame 1 from alternate portrait blob (+0x15C) (mouth open)
178  // <0: draw frame 2 from alternate portrait blob (+0x15C) (mouth closed)
179  int16 mouthAnimCounter = 0;
180  bool mouthAnimActive = false;
181 };
182 
184  uint16 characterY;
185  uint16 scalingFactor;
186 };
187 
188 class View1 : public UIElement {
189  friend class ScummUI;
190 
191 private:
192  // drawSpriteTransparent @ 1010:0ed1 (drawAnimFrameDepth @ 1010:172c)
193  void drawSpriteTransparent(int shadingTableOffset, uint8 depthThreshold, uint16 scalingFactor,
194  int16 drawX, int16 drawY, uint16 srcWidth, uint16 srcHeight,
195  const byte *srcPixels, Graphics::ManagedSurface &s);
196  // drawSpriteScaled @ 1010:102b (drawAnimFrameShaded @ 1010:1785)
197  void drawSpriteScaled(int shadingTableOffset, uint8 depthThreshold, int16 drawX, int16 drawY,
198  uint16 srcWidth, uint16 srcHeight, const byte *srcPixels,
200 
201  // Set by action bar map button on press; enterMapMode() runs on panel release.
202  bool _pendingMapOpen = false;
203 
204  ScummUI *_scummUI = nullptr;
205 
206  // Saved scene visuals for help screen restore (avoids changeScene on exit)
207  byte _savedPalVanilla[256 * 3] = {0};
208  Graphics::ManagedSurface _savedDepthMap;
209  int _offset = 0; // TODO: palette cycling?
210 
211  // Tick counter gating the mode-dependent palette brighten effect
212  // (updateBackgroundAnimationPalette). Matches g_wBgAnimTickCounter in the
213  // binary gameTick (1008:e556).
214  uint32 _bgAnimTickCounter = 0;
215 
216  // Save/Load panel from handleSaveLoadPanelClick (1008:86a4).
217  // Opened by right-click during script execution or action bar button 8.
218  //
219  // Sub-mode 1 (Load): clicking a slot loads the game from that file
220  // Sub-mode 2 (Save): clicking a slot opens text input for save name
221  //
222  // Button bar (7 buttons):
223  // Button 1 = Enter load mode (sub-mode=1)
224  // Button 2 = Enter save mode (sub-mode=2)
225  // Button 3 = Toggle music on/off
226  // Button 4 = Page scroll (cycles 0->1->2->0)
227  // Button 5 = Confirm save (double-click pattern)
228  // Button 6 = Confirm load (double-click pattern)
229  // Button 7 = Play music / close panel
230  enum class SaveLoadSubMode {
231  None = 0,
232  Load = 1,
233  Save = 2
234  };
235  SaveLoadSubMode _saveLoadSubMode = SaveLoadSubMode::None;
236  uint16 _saveLoadPageIndex = 0;
237  bool _saveConfirmArmed = false;
238  bool _loadConfirmArmed = false;
239  bool _helpButtonDisabled = false; // g_wMapDisabledFlag (1020:23b4): disables action bar help button AND save/load panel buttons 1-2
240  uint16 _clickedButtonIndex = 0; // g_wClickedButtonIndex: last clicked button (0=none)
241  Common::String _saveSlotNames[30]; // 3 pages x 10 slots
242 
243  // Save/Load panel geometry (binary globals: g_wUiPanelX/Y/Width/Height, g_wActionBarButtonWidth/Height)
244  Common::Rect _saveLoadPanelRect;
245  Common::Rect _saveLoadButtonRects[7];
246  uint16 _saveLoadButtonWidth = 0; // g_wActionBarButtonWidth (after +6)
247  uint16 _saveLoadButtonHeight = 0; // g_wActionBarButtonHeight (after +6)
248 
249  void openOriginalSaveLoadPanel();
250  void drawOriginalSaveLoadPanel(Graphics::ManagedSurface &s);
251  void handleOriginalSaveLoadClick(const Common::Point &pos);
252  void closeOriginalSaveLoadPanel();
253 
254  int _currentFadeValue = -1;
255  FadeMode _fadeMode = FadeMode::None;
256  bool _cursorSuppressedForFade = false;
257  bool _cursorWasVisibleBeforeFade = false;
258 
259  void drawDarkRectangle(uint16 x, uint16 y, uint16 width, uint16 height);
260  void drawBackgroundAnimations(Graphics::ManagedSurface &s);
261  void drawCurrentSpeaker(Graphics::ManagedSurface &s);
262 
263  void beginFadeCursorSuppression();
264  void endFadeCursorSuppression(const byte *palette);
265 
266  bool handleInventoryClick(const MouseDownMessage &msg);
267  bool handleContainerInventoryClick(const MouseDownMessage &msg);
268  // Binary handleInventoryClick / handleContainerInventoryClick epilogue:
269  // if pending != 0 -> uiBackgroundRestorePending=1; flip; runScriptExecutor; pending=0.
270  void runInventoryPanelScriptIfPending(bool excludeCloseButton);
271  bool handleActionBarClick(const MouseDownMessage &msg);
272 
273  // Input state machine from handleInput (1008:e8bf).
274  // The original game's input handler has two major branches:
275  //
276  // 1. NORMAL MODE (scene data offset 0x61db == 0):
277  // Two sub-modes based on whether a script is executing (0f88):
278  // a) Script NOT executing: Full interaction
279  // - Left click + Walk mode (0x16): pathfind to click position
280  // - Left click + other modes: hit-test hotspots/characters, run script
281  // - Right click: open action bar popup (g_wUiPanelState=1)
282  // - Button flag 8 (skip): fast-forward script to opcode 0x1D
283  // b) Script IS executing: Limited interaction
284  // - Left click: dismiss text boxes, dialogue choices, timer clicks
285  // - Right click: open map/save panel (state=4) if no UI is blocking
286  //
287  // 2. MAP MODE (scene data offset 0x61db != 0):
288  // - Left click: getDepthAtPoint() at click position
289  // depth 1..0xF9: preview that scene image
290  // depth 0xFF: full scene change back to main scene
291  //
292  // UI Panel States (g_wUiPanelState):
293  // 0 = Normal gameplay
294  // 1 = Action bar (right-click popup)
295  // 2 = Inventory panel
296  // 3 = Dialogue/save panel
297  // 4 = Map panel
298  //
299  // Panel dismissal uses keyboard scancode in PTR_LOOP_1020_0fe8:
300  // 6 = close inventory/dialogue panels
301  // 7 = close map panel
302  bool handleInput(const MouseDownMessage &msg);
303  // Binary handleInput (1008:e8bf): panel close on mouse release when
304  // g_wClickedButtonIndex != 0 and buttonFlags != 1.
305  bool handlePanelRelease(const MouseUpMessage &msg);
306  bool handleHelpClick(const MouseDownMessage &msg);
307 
308  void showStringBox(const Common::StringArray &sa);
309 
310  void renderString(uint16 x, uint16 y, const Common::String &s);
311  void renderString(const Common::Point pos, const Common::String &s);
312  void renderStringTo(uint16 x, uint16 y, const Common::String &s, Graphics::ManagedSurface &surf);
313  void renderStringWithFont(uint16 x, uint16 y, const Common::String &s, const GlyphData *glyphs, uint16 numGlyphs);
314  void renderStringWithFontTo(uint16 x, uint16 y, const Common::String &s, const GlyphData *glyphs,
315  uint16 numGlyphs, Graphics::ManagedSurface &surf);
316  int measureStringWithFont(const Common::String &s, const GlyphData *glyphs, uint16 numGlyphs);
317 
318  Common::Array<Common::Rect> _mainMenuButtonLocations;
319  Common::Rect _mainMenuRect;
320  Common::Point _inventoryGridUpperLeft;
321  Common::Point _inventorySlotSize;
322  Common::Array<Common::Rect> _inventoryButtonLocations;
323  uint16 _inventoryScrollOffset = 0;
324 
325  void drawSprite(int16 x, int16 y, uint16 width, uint16 height, byte *data, Graphics::ManagedSurface &s, bool mirrored, bool useDepth = false, uint8 depth = 0, bool clipToGameArea = false);
326  void drawSprite(int16 x, int16 y, const Sprite &sprite, Graphics::ManagedSurface &s, bool mirrored, bool useDepth = false, uint8 depth = 0, bool clipToGameArea = false);
327  void drawSprite(const Common::Point &pos, uint16 width, uint16 height, byte *data, Graphics::ManagedSurface &s, bool mirrored, bool useDepth = false, uint8 depth = 0, bool clipToGameArea = false);
328 
329  void drawSpriteClipped(uint16 x, uint16 y, Common::Rect &clippingRect, uint16 width, uint16 height, const byte *const data, Graphics::ManagedSurface &s);
330  void drawSpriteClipped(uint16 x, uint16 y, Common::Rect &clippingRect, const Sprite &sprite, Graphics::ManagedSurface &s);
331  void drawSpriteFitted(const Common::Rect &bounds, const Sprite &sprite, Graphics::ManagedSurface &s, uint16 inset = 6);
332 
333  // Binary sortObjectListByY (1008:8cf2) + buildSortedObjectList (1008:8c5a):
334  // scan 512 objects, collect current-scene indices at 0xFAC, quicksort by Y.
335  // Table is 1-indexed: slots 1..g_wSortedObjectCount hold object indices.
336  static const uint16 kMaxSceneObjects = 0x200;
337  void sortObjectListByY() const;
338  void buildSortedObjectList(int low, int high) const;
339  mutable uint16 _sortedObjectCount = 0;
340  mutable uint16 _sortedObjectIndices[kMaxSceneObjects + 1];
341  mutable Character *_characterByObjectIndex[kMaxSceneObjects + 1] = {};
342 
343  // drawAllCharacters @ 1008:90a2 - param_1: 0=draw only, 1=walk+draw (fullUpdate).
344  void drawAllCharacters(Graphics::ManagedSurface *surface = nullptr, bool fullUpdate = true);
345 
346  int findInventoryItem(const GameObject *item);
347  void setViewPaletteSafely(const byte *colors);
348  void applyPaletteWithFade(const byte *sourcePalette, int fadeValue);
349 
350 public:
351  View1();
352  virtual ~View1();
353 
354  bool hasScummVerbUI() const;
355  bool shouldShowScummVerbUI() const;
356  void ensureScummVerbUI();
357 
358  // g_wHelpButtonDisabled (1020:23B4): when non-zero, help/map button is disabled
359  // and script scene changes use applyScenePaletteEffect instead of palette fades.
360  // Map overlay mode is scene+0x61db (_currentMode == VM_HELP), not this flag.
361  bool isHelpButtonDisabled() const { return _helpButtonDisabled; }
362 
363  void restoreUiPaletteEntries();
364 
365  void clearClickedButtonIndex() { _clickedButtonIndex = 0; }
366 
367  ScalingValues _scalingValues;
368 
369  ViewMode _currentMode = ViewMode::VM_GAME;
370 
371  AnimFrame *getInventoryIcon(GameObject *gameObject);
372 
373  // TODO: use Graphics::Palette
374  byte _pal[256 * 3] = {0};
375  bool _paletteDirty = true;
376 
377  // Background animation timing from gameTick (1008:e556).
378  // The original game increments a tick counter each frame (~70Hz DOS timer)
379  // and advances background animations when the counter exceeds a threshold:
380  // Background animation timing from gameTick (1008:e556).
381  // g_wBgAnimTickCounter is incremented once per game frame (~20fps).
382  // Background animation tick counter (mode 2: threshold 0x27, mode 3: threshold 1)
383  static constexpr uint32 kGameFrameRate = 20;
384 
385  // Binary g_wIsShowingTextBox (1020:0ff6): set by scriptPrintString, cleared by handleTextBoxInput
386  bool _isShowingTextBox = false;
387  // Binary g_wIsShowingDialoguePanel (1020:1008): set by scriptShowDialogue, cleared by dismissDialoguePanel
388  bool _isShowingDialoguePanel = false;
389  Common::StringArray _drawnStringBox;
390  bool _continueScriptAfterUI = false;
391  uint16 _dialogueChoiceCount = 0;
392  Common::Array<uint16> _dialogueChoiceLineCounts;
393  SpeechActData currentSpeechActData;
394  Graphics::ManagedSurface _backgroundSurface;
395 
396  bool _started = false;
397  // As long as this debug bool is active, apply any click possible whenever it makes sense
398  bool _autoclickActive = false;
399 
400  Common::Array<Character *> _characters;
401  Common::Array<Character *> _pendingCharacterDeletes;
402  void flushPendingCharacterDeletes();
403  // Binary drawAllCharacters (1008:90a2) pickup frame: sceneIndex + inventory sync.
404  void transferPickupTarget(GameObject *targetObject);
405  // If this is the protagonist, we have our normal inventory
406  // If this is another object, it is the inventory of a storage container
407  GameObject *_inventorySource = nullptr;
408 
409  // TODO: Find a better place for those
410  // The inventory items for the currently opened inventory
411  Common::Array<GameObject *> _inventoryItems;
412 
413  // If this is not null, we are using this object
414  GameObject *_activeInventoryItem = nullptr;
415 
416  Common::Point _stringBoxPosition;
417 
418  // Binary g_wUiPanelState: 0=none, 1=action bar, 2=protagonist inv, 3=container inv, 4=save/load
419  enum UiPanelState : uint16 {
420  kUiPanelNone = 0,
421  kUiPanelActionBar = 1,
422  kUiPanelInventory = 2,
423  kUiPanelContainerInventory = 3,
424  kUiPanelSaveLoad = 4
425  };
426  UiPanelState _uiPanelState = kUiPanelNone;
427 
428  void finishPanelCloseAfterRelease(UiPanelState closedFromState);
429 
430  // Binary scene+0x53B9: dialogue choice input mode active (waiting for player to pick an answer)
431  bool _isDialogueChoiceInputActive = false;
432 
433  // Binary g_wPendingPanelRequest (1020:1034): deferred panel open request.
434  // Set while action bar is active; processed by gameTick when _uiPanelState returns to kUiPanelNone.
435  // Values: 0=none, 1=protagonist inventory, 2=container inventory, 3=save/load
436  enum PendingPanelRequest : uint16 {
437  kPanelRequestNone = 0,
438  kPanelRequestInventory = 1,
439  kPanelRequestContainerInventory = 2,
440  kPanelRequestSaveLoad = 3,
441  kPanelRequestSaveLoadActive = 4 // Set by handleSaveLoadPanelClick to keep panel alive
442  };
443  PendingPanelRequest _pendingPanelRequest = kPanelRequestNone;
444 
445  // Binary g_wUiBackgroundRestorePending: set when panel was open and background needs redraw
446  bool _uiBackgroundRestorePending = false;
447 
448  // Binary g_wSavedCursorMode [scene+0xFEA]: saved before opening action bar panel
449  Script::MouseMode _savedCursorMode = Script::MouseMode::Walk;
450 
451  enum class InventoryButtonIndex {
452  Look = 0,
453  Hand = 1,
454  Up = 2,
455  Down = 3,
456  Drop = 4,
457  Close = 5
458  };
459 
460  // Action bar button layout from handleActionBarClick (1008:42dc).
461  // The action bar is a 3x3 grid of buttons, centered on the right-click
462  // position. Each button is sized to fit the largest cursor icon + 6px padding.
463  // The panel is clamped to screen bounds (320x200).
464  enum class MainMenuButtonIndex {
465  Talk = 0, // Sets cursor mode to 0x13 (Talk)
466  Look = 1, // Sets cursor mode to 0x14 (Look)
467  Use = 2, // Sets cursor mode to 0x15 (Use)
468  Walk = 3, // Sets cursor mode to 0x16 (Walk)
469  Inventory = 4, // Opens inventory panel (g_wHasSavedUiBackground=1)
470  InventoryUse = 5, // Uses selected inventory item (cursor 0x17), only if item selected
471  Map = 6, // Opens help/info screen (sets scene+0x61db=1 for map panel mode)
472  SaveLoad = 7, // Opens dialogue/save panel (g_wHasSavedUiBackground=3)
473  Close = 8 // Implicit close (clicking outside any button)
474  };
475 
476  // Debug: last hovered area/hotspot (updated every mouse move for ImGui)
477  uint16 _hoverAreaId = 0;
478  uint16 _hoverHotspotId = 0;
479 
480  // debug tools
481  void drawPathfindingPoints(Graphics::ManagedSurface &s);
482  void drawDebugOutput(Graphics::ManagedSurface &s);
483  void drawPath(Graphics::ManagedSurface &s);
484 
485  // Sets the source for the to-be-opened inventory and updats the array of inventory objects
486  void setInventorySource(GameObject *newInventorySource);
487  void refreshProtagonistInventoryAfterLoad(uint16 actorIndex);
488  void openInventory(GameObject *newInventorySource);
489  // Binary handleInput (1008:e8bf) close path for the inventory panels.
490  void closeInventory();
491 
492  bool isInventorySourceProtagonist() const;
493 
494  void transferInventoryItem(GameObject *item, GameObject *targetContainer);
495 
496  Character *getCharacterByIndex(uint16 index) const;
497  void rebuildCharacterLookupTable() const;
498 
499  int getCharacterArrayIndex(const Character *c) const;
500 
501  // Updates the cursor from the mode set in the engine - TODO: Clean up, this should not
502  // be so separated
503  void updateCursor(const byte *palette = nullptr);
504 
505  bool msgFocus(const FocusMessage &msg) override;
506  bool msgKeypress(const KeypressMessage &msg) override;
507  bool msgAction(const ActionMessage &msg) override;
508 
509  bool msgMouseDown(const MouseDownMessage &msg) override;
510  bool msgMouseUp(const MouseUpMessage &msg) override;
511  bool msgMouseMove(const MouseMoveMessage &msg) override;
512  void draw() override;
513  bool tick() override;
514 
515  void drawInventory(Graphics::ManagedSurface &s);
516  GameObject *getClickedInventoryItem(const Common::Point &p);
517 
518  void openMainMenu(Common::Point clickedPosition);
519  void enterMapMode();
520 
521  // Binary openActionBarAtPosition (1008:3fba): stores button hit rects at panel+4+col*(btnW+4).
522  void layoutActionBarButtons();
523  void drawMainMenu(Graphics::ManagedSurface &s);
524  void drawSceneUpdate();
525 
526  void handleTextBoxInput();
527  void dismissDialoguePanel();
528  bool handleDialogueChoiceClick(int clickY, int clickX);
529 
530  void startFading(uint16 speed = 4);
531  void fadePaletteToBlack(uint16 speed, const byte *sourcePalette);
532  void startFadeToBlack(uint16 speed = 4);
533  void startFadingWithSpeed(uint16 speed);
534  // Mode-1 scene transition: clearScreen + full palette (1008:ad6e local_6==1).
535  void instantSceneCut();
536  // Draw the current scene and push pixels to the physical screen immediately.
537  void presentFrame();
538 
539  void showSpeechAct(uint16 characterIndex, const Common::Array<Common::String> &strings, const Common::Point &position, bool onRightSide = false);
540 
541  struct BorderStyle {
542  uint32 outerEdge; // sprite for outer frame (0x1010 = black)
543  uint32 topLeft; // sprite for top/left edge
544  uint32 bottomRight; // sprite for bottom/right edge
545  };
546  static const BorderStyle kBorderRaised;
547  static const BorderStyle kBorderPressed;
548 
549  void drawNinePatchBorder(const Common::Point &pos, const Common::Point &size,
550  const BorderStyle &style, bool fillCenter, bool fillSides,
552  void drawBorder(const Common::Point &pos, const Common::Point &size, Graphics::ManagedSurface &s);
553  void drawBorderSide(const Common::Point &pos, const Common::Point &size, Graphics::ManagedSurface &s);
554 
555  Macs2::AnimFrame *getUISprite(uint32 offset);
556 
557  // fn0037_3737 proc
558  void drawHorizontalBorderHighlight(const Common::Point &pos, int16 width, uint32 spriteAddress, Graphics::ManagedSurface &s);
559  // 0037h:3876h
560  void drawVerticalBorderHighlight(const Common::Point &pos, int16 height, uint32 spriteAddress, Graphics::ManagedSurface &s);
561 
562  void drawImageResources(Graphics::ManagedSurface &s);
563 
564  void showDialogueChoice(uint16 speakerObjectID, const Common::Array<Common::StringArray> &choices, const Common::Point &position, bool onRightSide = false);
565 
566  void triggerDialogueChoice(uint8 index);
567 
569  Common::Point position;
570  uint8 alignment = 0;
571  Common::String text;
572  };
573 
574  void addOverlayTextEntry(const OverlayTextEntry &entry);
575  void clearOverlayTextEntries();
576  void drawOverlayTextEntries();
577 
578  Common::Array<OverlayTextEntry> _overlayTextEntries;
579 
580  uint16 getHitObjectID(const Common::Point &pos) const;
581 };
582 
583 } // namespace Macs2
584 
585 #endif
Definition: managed_surface.h:51
Definition: str.h:59
Definition: messages.h:58
Definition: gameobjects.h:86
Definition: events.h:54
Definition: view1.h:169
Definition: messages.h:75
Definition: messages.h:69
Definition: rect.h:536
Definition: view1.h:568
Definition: view1.h:541
Definition: messages.h:63
Definition: view1.h:55
Definition: view1.h:151
Definition: view1.h:188
Definition: view1.h:44
Definition: macs2.h:105
Definition: rect.h:144
Definition: messages.h:42
Definition: messages.h:33
Definition: macs2.h:99
Definition: macs2.h:112
Definition: scummui.h:36
Definition: debugtools.h:25
Definition: view1.h:183