ScummVM API documentation
cursor.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 NANCY_CURSOR_H
23 #define NANCY_CURSOR_H
24 
25 #include "common/array.h"
26 #include "common/stream.h"
27 
28 #include "graphics/managed_surface.h"
29 
30 namespace Nancy {
31 
33 
34 public:
35  enum CursorType {
36  kNormal = 0, // Eyeglass (except in TVD), non-highlighted
37  kHotspot = 1, // Eyeglass (except in TVD), highlighted
38  kMove = 2, // Used for movement in early games
39  kExit = 3, // Used for movement, some games use it for exiting puzzles
40  kRotateCW = 4, // Used in puzzles only
41  kRotateCCW = 5, // Used in puzzles only
42  kMoveLeft = 6, // Used for movement, some games used it for turning in 360 scenes
43  kMoveRight = 7, // Used for movement, some games used it for turning in 360 scenes
44  kMoveForward = 8, // Used for movement
45  kMoveBackward = 9, // Used for movement, some games use it for exiting puzzles
46  kMoveUp = 10, // Used for movement
47  kMoveDown = 11, // Used for movement
48  kRotateLeft = 12, // Used in 360 scenes in nancy6 and up
49  kRotateRight = 13, // Used in 360 scenes in nancy6 and up
50  kInvertedRotateRight = 14, // Used in 360 scenes with inverted rotation; nancy6 and up
51  kInvertedRotateLeft = 15, // Used in 360 scenes with inverted rotation; nancy6 and up
52  kCustom1 = 16, // Custom cursors change between games; Likely used in puzzles
53  kCustom1Hotspot = 17,
54  kCustom2 = 18,
55  kCustom2Hotspot = 19,
56  kNormalArrow = 20,
57  kHotspotArrow = 21,
58  kHotspotTalk = 22, // Speech-bubble hover cursor (Nancy 10+)
59  kDragHand = 23, // Hand cursor used when dragging an item (Nancy 10+)
60  kDropHand = 24, // Drop-hand cursor used while a piece is held over a target (Nancy 10+)
61  kPuzzleArrow = 25, // Puzzle arrow cursor shown when hovering a clickable puzzle hotspot (Nancy 10+)
62  kDialCW = 26, // Dial turn cursors used by SafeDialPuzzle (Nancy 10+); the older
63  kDialCCW = 27, // games use kRotateCW / kRotateCCW instead
64 
65  // Cursors in Nancy10 and newer games. The CURS chunk holds 37 system
66  // cursor types in pairs; type T's idle slot is (T*2) and its hotspot
67  // slot is (T*2 + 1). Types 0–4 and 18–26 have visually distinct idle
68  // vs. hotspot sprites; types 5–17 and 27–36 use the same sprite for
69  // both. Types 18+ are Nancy 10-specific puzzle/inventory cursors.
70  kNewNormal = 0, // Type 0 — Eyeglass
71  kNewHotspot = 1, // Type 0 hotspot — Eyeglass highlighted
72  kNewUse = 2, // Type 1 — Open-hand "use" cursor (interact with characters/objects)
73  kNewHotspotUse = 3, // Type 1 hotspot
74  kNewLockedUse = 4, // Type 2 — Locked variant of the use hand
75  kNewHotspotLockedUse = 5, // Type 2 hotspot
76  kNewTalk = 6, // Type 3 — Speech-bubble (talking to characters)
77  kNewHotspotTalk = 7, // Type 3 hotspot
78  kNewNormalArrow = 8, // Type 4 — Taskbar arrow
79  kNewHotspotArrow = 9, // Type 4 hotspot
80  kNewExit = 10, // Type 5 — Exit / back movement
81  kNewMoveLeft = 12, // Type 6 — Movement / 360 turn
82  kNewMoveRight = 14, // Type 7 — Movement / 360 turn
83  kNewMoveForward = 16, // Type 8 — Movement
84  kNewMoveBackward = 18, // Type 9 — Movement / exit puzzles
85  kNewMoveUp = 20, // Type 10 — Movement
86  kNewMoveDown = 22, // Type 11 — Movement
87  kNewRotateCW = 24, // Type 12 — Puzzle rotation
88  kNewRotateCCW = 26, // Type 13 — Puzzle rotation
89  kNewRotateRight = 28, // Type 14 — 360 scenes
90  kNewRotateLeft = 30, // Type 15 — 360 scenes
91  kNewInvertedRotateRight = 32, // Type 16 — Inverted 360 rotation
92  kNewInvertedRotateLeft = 34, // Type 17 — Inverted 360 rotation
93  kNewUseHand = 36, // Type 18 — Open hand, used while using items and while carrying a puzzle piece
94  kNewUseHandHotspot = 37, // Type 18 hotspot — Open hand shown over a slot a carried piece can be dropped into
95  kNewDragHand = 38, // Type 19 — Closed hand, used while dragging puzzle pieces
96  kNewDragHandHotspot = 39, // Type 19 hotspot — Closed hand shown over a piece that can be picked up
97  kNewRotatePiece = 40, // Type 20 — Rotate arrows shown over a rotatable puzzle piece
98  kNewDialCW = 41, // Type 20 hotspot — Dial turn cursors, used by SafeDialPuzzle
99  kNewDialCCW = 43, // Type 21 hotspot
100  kNewPuzzleArrow = 45, // Type 22 hotspot — Arrow cursor shown when hovering a clickable puzzle hotspot
101  kNewPuzzleSlideUp = 47, // Type 23 hotspot — Slide-arrow shown over a movable tile in CollisionPuzzle/TileMovePuzzle
102  kNewPuzzleSlideDown = 49, // Type 24 hotspot
103  kNewPuzzleSlideLeft = 51, // Type 25 hotspot
104  kNewPuzzleSlideRight = 53, // Type 26 hotspot
105  kNewDropHand = 64, // Type 32 — Hand shown when a held piece is dropped (briefly set on the drop action)
106  kNewBlank = 72, // Type 36 — Empty sprite, used while a puzzle draws a carried piece at the mouse itself
107 
108  // Cursor types in Nancy13 and newer games. Nancy13 rebuilt the CURS
109  // sheet with 45 system cursor types, each stored as an [idle, hotspot]
110  // pair at slots (type * 2, type * 2 + 1). These constants are Nancy13
111  // system TYPE indices (not slot indices); resolveNancy13CursorID turns a
112  // type into the idle or hotspot slot.
113  // Types 25-34 are the blue in-puzzle variants of the plain ones.
114  kNancy13Normal = 0, // Eyeglass
115  kNancy13Talk = 5,
116  kNancy13MoveUp = 6,
117  kNancy13MoveDown = 7,
118  kNancy13MoveLeft = 8,
119  kNancy13MoveRight = 9,
120  kNancy13MoveBackward = 10,
121  kNancy13MoveForward = 12,
122  kNancy13Arrow = 14,
123  kNancy13RotateRight = 17,
124  kNancy13RotateLeft = 18,
125  kNancy13Exit = 19,
126  kNancy13InvertedRotateRight = 20,
127  kNancy13InvertedRotateLeft = 21,
128  // Empty. Selected while the cell phone's camera viewfinder is up, so
129  // only the viewfinder is seen.
130  kNancy13Blank = 24,
131  kNancy13PuzzleRotateCW = 25,
132  kNancy13PuzzleRotateCCW = 26,
133  kNancy13PuzzleDragHand = 28,
134  kNancy13PuzzleDropHand = 29,
135  kNancy13PuzzleMoveUp = 30,
136  kNancy13PuzzleMoveDown = 31,
137  kNancy13PuzzleArrow = 34
138  };
139 
140  CursorManager();
141 
142  void init(Common::SeekableReadStream *chunkStream);
143 
144  // Change the current cursor ID. Does not change the graphic.
145  // When setFromScript is set, type is a raw Nancy 10+ system cursor type
146  // index resolved to its flat slot; hotspotVariant then picks the hotspot
147  // (type*2 + 1) or idle (type*2) sprite of the pair.
148  void setCursor(CursorType type, int16 itemID, bool setFromScript, bool hotspotVariant = true);
149  void setCursorType(CursorType type, bool setFromScript = false, bool hotspotVariant = true);
150  void setCursorItemID(int16 itemID);
151  void showCursor(bool shouldShow);
152 
153  void warpCursor(const Common::Point &pos);
154 
155  // Change the cursor graphic. Should be called right before drawing to screen
156  void applyCursor();
157 
158  const Common::Point &getCurrentCursorHotspot() { return _cursors[_curCursorID].hotspot;}
159  const Common::Rect &getPrimaryVideoInactiveZone() { return _primaryVideoInactiveZone; }
160  const Common::Point &getPrimaryVideoInitialPos() { return _primaryVideoInitialPos; }
161 
162  const CursorType _puzzleExitCursor;
163 
164 private:
165  void adjustCursorHotspot();
166 
167  // Resolve a CursorType + held-item pair to a Nancy 10+ cursor ID.
168  uint resolveNancy10CursorID(CursorType type, int16 itemID, bool setFromScript, bool hotspotVariant);
169 
170  // Nancy13 rebuilt the cursor sheet (45 system types, new layout) and split
171  // held-item cursors into _invCursorsSurface. System cursors use a dedicated
172  // Nancy13 slot table.
173  uint resolveNancy13CursorID(CursorType type, int16 itemID, bool setFromScript, bool hotspotVariant);
174 
175  struct Cursor {
176  Common::Rect bounds;
177  Common::Point hotspot;
178  };
179 
180  // CURS data
181  Common::Array<Cursor> _cursors;
182 
183  Common::Rect _primaryVideoInactiveZone;
184  Common::Point _primaryVideoInitialPos;
185 
186  Graphics::ManagedSurface _invCursorsSurface;
187  Graphics::ManagedSurface _uiCursorsSurface; // Nancy13+
188 
189  Common::Point _warpedMousePos;
190  CursorType _curCursorType;
191  int16 _curItemID;
192  uint _curCursorID;
193  uint _lastCursorID;
194  bool _hasItem;
195  bool _isInitialized;
196  int _numCursorTypes;
197 };
198 
199 } // End of namespace Nancy
200 
201 #endif // NANCY_CURSOR_H
Definition: managed_surface.h:51
Definition: cursor.h:32
Definition: rect.h:536
Definition: stream.h:745
Definition: rect.h:144
Definition: actionmanager.h:32