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 NEVERHOOD_SCENE_H
24 #define NEVERHOOD_SCENE_H
25 
26 #include "common/array.h"
27 #include "neverhood/neverhood.h"
28 #include "neverhood/background.h"
29 #include "neverhood/entity.h"
30 #include "neverhood/graphics.h"
31 #include "neverhood/klaymen.h"
32 #include "neverhood/module.h"
33 #include "neverhood/palette.h"
34 #include "neverhood/sprite.h"
35 #include "neverhood/staticdata.h"
36 
37 namespace Neverhood {
38 
39 class Console;
40 class SmackerPlayer;
41 
42 class Scene : public Entity {
43 public:
44 	Scene(NeverhoodEngine *vm, Module *parentModule);
45 	~Scene() override;
46 	void draw() override;
47 	void addEntity(Entity *entity);
48 	bool removeEntity(Entity *entity);
49 	void addSurface(BaseSurface *surface);
50 	bool removeSurface(BaseSurface *surface);
51 	void printSurfaces(Console *con);
52 	Sprite *addSprite(Sprite *sprite);
53 	void removeSprite(Sprite *sprite);
54 	void setSurfacePriority(BaseSurface *surface, int priority);
55 	void setSpriteSurfacePriority(Sprite *sprite, int priority);
56 	void deleteSprite(Sprite **sprite);
57 	Background *addBackground(Background *background);
58 	void setBackground(uint32 fileHash);
59 	void changeBackground(uint32 fileHash);
setBackgroundY(int16 y)60 	void setBackgroundY(int16 y) { _background->getSurface()->getDrawRect().y = y; }
getBackgroundY()61 	int16 getBackgroundY() { return _background->getSurface()->getDrawRect().y; }
62 	void setPalette(uint32 fileHash = 0);
63 	void setHitRects(uint32 id);
64 	Sprite *insertStaticSprite(uint32 fileHash, int surfacePriority);
65 	void insertScreenMouse(uint32 fileHash, const NRect *mouseRect = NULL);
66 	void insertPuzzleMouse(uint32 fileHash, int16 x1, int16 x2);
67 	void insertNavigationMouse(uint32 fileHash, int type);
68 	void showMouse(bool visible);
69 	void changeMouseCursor(uint32 fileHash);
70 	SmackerPlayer *addSmackerPlayer(SmackerPlayer *smackerPlayer);
71 	void update();
72 	void leaveScene(uint32 result);
73 	HitRect *findHitRectAtPos(int16 x, int16 y);
74 	void addCollisionSprite(Sprite *sprite);
75 	void removeCollisionSprite(Sprite *sprite);
76 	void checkCollision(Sprite *sprite, uint16 flags, int messageNum, uint32 messageParam);
77 	// Some crazy templated functions to make the logic code smaller/simpler (imo!)
78 	// insertKlaymen
79 	template<class T>
insertKlaymen()80 	void insertKlaymen() {
81 		_klaymen = (T*)addSprite(new T(_vm, this));
82 	}
83 	template<class T, class Arg1>
insertKlaymen(Arg1 arg1)84 	void insertKlaymen(Arg1 arg1) {
85 		_klaymen = (T*)addSprite(new T(_vm, this, arg1));
86 	}
87 	template<class T, class Arg1, class Arg2>
insertKlaymen(Arg1 arg1,Arg2 arg2)88 	void insertKlaymen(Arg1 arg1, Arg2 arg2) {
89 		_klaymen = (T*)addSprite(new T(_vm, this, arg1, arg2));
90 	}
91 	template<class T, class Arg1, class Arg2, class Arg3>
insertKlaymen(Arg1 arg1,Arg2 arg2,Arg3 arg3)92 	void insertKlaymen(Arg1 arg1, Arg2 arg2, Arg3 arg3) {
93 		_klaymen = (T*)addSprite(new T(_vm, this, arg1, arg2, arg3));
94 	}
95 	template<class T, class Arg1, class Arg2, class Arg3, class Arg4>
insertKlaymen(Arg1 arg1,Arg2 arg2,Arg3 arg3,Arg4 arg4)96 	void insertKlaymen(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) {
97 		_klaymen = (T*)addSprite(new T(_vm, this, arg1, arg2, arg3, arg4));
98 	}
99 	template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5>
insertKlaymen(Arg1 arg1,Arg2 arg2,Arg3 arg3,Arg4 arg4,Arg5 arg5)100 	void insertKlaymen(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) {
101 		_klaymen = (T*)addSprite(new T(_vm, this, arg1, arg2, arg3, arg4, arg5));
102 	}
103 	template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6>
insertKlaymen(Arg1 arg1,Arg2 arg2,Arg3 arg3,Arg4 arg4,Arg5 arg5,Arg6 arg6)104 	void insertKlaymen(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) {
105 		_klaymen = (T*)addSprite(new T(_vm, this, arg1, arg2, arg3, arg4, arg5, arg6));
106 	}
107 	// insertSprite
108 	template<class T>
insertSprite()109 	T* insertSprite() {
110 		return (T*)addSprite(new T(_vm));
111 	}
112 	template<class T, class Arg1>
insertSprite(Arg1 arg1)113 	T* insertSprite(Arg1 arg1) {
114 		return (T*)addSprite(new T(_vm, arg1));
115 	}
116 	template<class T, class Arg1, class Arg2>
insertSprite(Arg1 arg1,Arg2 arg2)117 	T* insertSprite(Arg1 arg1, Arg2 arg2) {
118 		return (T*)addSprite(new T(_vm, arg1, arg2));
119 	}
120 	template<class T, class Arg1, class Arg2, class Arg3>
insertSprite(Arg1 arg1,Arg2 arg2,Arg3 arg3)121 	T* insertSprite(Arg1 arg1, Arg2 arg2, Arg3 arg3) {
122 		return (T*)addSprite(new T(_vm, arg1, arg2, arg3));
123 	}
124 	template<class T, class Arg1, class Arg2, class Arg3, class Arg4>
insertSprite(Arg1 arg1,Arg2 arg2,Arg3 arg3,Arg4 arg4)125 	T* insertSprite(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) {
126 		return (T*)addSprite(new T(_vm, arg1, arg2, arg3, arg4));
127 	}
128 	template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5>
insertSprite(Arg1 arg1,Arg2 arg2,Arg3 arg3,Arg4 arg4,Arg5 arg5)129 	T* insertSprite(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) {
130 		return (T*)addSprite(new T(_vm, arg1, arg2, arg3, arg4, arg5));
131 	}
132 	template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6>
insertSprite(Arg1 arg1,Arg2 arg2,Arg3 arg3,Arg4 arg4,Arg5 arg5,Arg6 arg6)133 	T* insertSprite(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) {
134 		return (T*)addSprite(new T(_vm, arg1, arg2, arg3, arg4, arg5, arg6));
135 	}
136 	// createSprite
137 	template<class T>
createSprite()138 	T* createSprite() {
139 		return new T(_vm);
140 	}
141 	template<class T, class Arg1>
createSprite(Arg1 arg1)142 	T* createSprite(Arg1 arg1) {
143 		return new T(_vm, arg1);
144 	}
145 	template<class T, class Arg1, class Arg2>
createSprite(Arg1 arg1,Arg2 arg2)146 	T* createSprite(Arg1 arg1, Arg2 arg2) {
147 		return new T(_vm, arg1, arg2);
148 	}
149 	template<class T, class Arg1, class Arg2, class Arg3>
createSprite(Arg1 arg1,Arg2 arg2,Arg3 arg3)150 	T* createSprite(Arg1 arg1, Arg2 arg2, Arg3 arg3) {
151 		return new T(_vm, arg1, arg2, arg3);
152 	}
153 	template<class T, class Arg1, class Arg2, class Arg3, class Arg4>
createSprite(Arg1 arg1,Arg2 arg2,Arg3 arg3,Arg4 arg4)154 	T* createSprite(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) {
155 		return new T(_vm, arg1, arg2, arg3, arg4);
156 	}
157 	template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5>
createSprite(Arg1 arg1,Arg2 arg2,Arg3 arg3,Arg4 arg4,Arg5 arg5)158 	T* createSprite(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) {
159 		return new T(_vm, arg1, arg2, arg3, arg4, arg5);
160 	}
161 	template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6>
createSprite(Arg1 arg1,Arg2 arg2,Arg3 arg3,Arg4 arg4,Arg5 arg5,Arg6 arg6)162 	T* createSprite(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) {
163 		return new T(_vm, arg1, arg2, arg3, arg4, arg5, arg6);
164 	}
165 
getBackgroundFileHash()166 	uint32 getBackgroundFileHash() const { return _backgroundFileHash; }
getCursorFileHash()167 	uint32 getCursorFileHash() const { return _cursorFileHash; }
168 
169 protected:
170 	Module *_parentModule;
171 	Common::Array<Entity*> _entities;
172 	Common::Array<BaseSurface*> _surfaces;
173 
174 	Klaymen *_klaymen;
175 	Background *_background;
176 	Palette *_palette;
177 	SmackerPlayer *_smackerPlayer;
178 
179 	MessageList *_messageList;
180 	MessageList *_messageList2;
181 	int _messageListStatus;
182 	uint _messageListCount;
183 	uint _messageListIndex;
184 	bool _doConvertMessages;
185 
186 	bool _canAcceptInput;
187 	bool _isKlaymenBusy;
188 	bool _isMessageListBusy;
189 
190 	Mouse *_mouseCursor;
191 	NPoint _mouseClickPos;
192 	bool _mouseClicked;
193 	bool _mouseCursorWasVisible;
194 
195 	int _rectType;
196 	RectList *_rectList;
197 	DataResource _dataResource;
198 
199 	HitRectList _hitRectList;
200 
201 	HitRectList *_hitRects;
202 	Common::Array<Sprite*> _collisionSprites;
203 
204 	// Used for debugging
205 	uint32 _backgroundFileHash, _cursorFileHash;    // for StaticScene and all Scene* classes
206 
207 	int _messageValue;
208 	uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
209 	bool queryPositionSprite(int16 mouseX, int16 mouseY);
210 	bool queryPositionRectList(int16 mouseX, int16 mouseY);
211 	void setMessageList(uint32 id, bool canAcceptInput = true, bool doConvertMessages = false);
212 	void setMessageList(MessageList *messageList, bool canAcceptInput = true, bool doConvertMessages = false);
213 	bool setMessageList2(uint32 id, bool canAcceptInput = true, bool doConvertMessages = false);
214 	bool setMessageList2(MessageList *messageList, bool canAcceptInput = true, bool doConvertMessages = false);
215 	bool isMessageList2(uint32 id);
216 	void processMessageList();
217 	void setRectList(uint32 id);
218 	void setRectList(RectList *rectList);
219 	void clearRectList();
220 	void loadHitRectList();
221 	void cancelMessageList();
222 	void loadDataResource(uint32 fileHash);
223 	uint16 convertMessageNum(uint32 messageNum);
224 
225 	void setHitRects(HitRectList *hitRects);
226 	void clearHitRects();
227 	void clearCollisionSprites();
228 
229 	void insertMouse(Mouse *mouseCursor);
230 };
231 
232 
233 class StaticScene : public Scene {
234 public:
235 	StaticScene(NeverhoodEngine *vm, Module *parentModule, uint32 backgroundFileHash, uint32 cursorFileHash);
236 protected:
237 	uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
238 };
239 
240 } // End of namespace Neverhood
241 
242 #endif /* NEVERHOOD_SCENE_H */
243