aboutsummaryrefslogtreecommitdiff
path: root/engines/kyra/kyra_v2.h
blob: e606bdfc1559f96951abe6e3bb902a09f4a00d94 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
/* 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 2
 * 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, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 * $URL$
 * $Id$
 *
 */

#ifndef KYRA_KYRA_V2_H
#define KYRA_KYRA_V2_H

#include "kyra/kyra_v1.h"
#include "kyra/gui.h"
#include "kyra/wsamovie.h"

#include "common/list.h"
#include "common/hashmap.h"

namespace Kyra {

struct FrameControl {
	uint16 index;
	uint16 delay;
};

struct ItemAnimData_v2 {
	int16 itemIndex;
	uint8 numFrames;
	const FrameControl *frames;
};

struct ActiveItemAnim {
	uint16 currentFrame;
	uint32 nextFrame;
};

class Screen_v2;

class KyraEngine_v2 : public KyraEngine_v1 {
friend class Debugger_v2;
friend class GUI_v2;
public:
	struct EngineDesc {
		// Generic shape related
		const int itemShapeStart;
		const uint8 *characterFrameTable;

		// Scene script
		const int firstAnimSceneScript;

		// Animation script specific
		const int animScriptFrameAdd;

		// Item specific
		const int maxItemId;
	};

	KyraEngine_v2(OSystem *system, const GameFlags &flags, const EngineDesc &desc);
	~KyraEngine_v2();

	virtual void pauseEngineIntern(bool pause);

	virtual Screen_v2 *screen_v2() const = 0;
	virtual GUI *gui_v2() const = 0;

	void delay(uint32 time, bool update = false, bool isMainLoop = false);

	const EngineDesc &engineDesc() const { return _desc; }
protected:
	EngineDesc _desc;

	// run
	uint32 _pauseStart;
	bool _runFlag;
	bool _showOutro;

	virtual void update() = 0;
	virtual void updateWithText() = 0;

	// detection
	int _lang;

	// MainMenu
	MainMenu *_menu;

	// Input
	virtual int inputSceneChange(int x, int y, int unk1, int unk2) = 0;

	void updateInput();
	int checkInput(Button *buttonList, bool mainLoop = false);
	void removeInputTop();

	int _mouseX, _mouseY;

	struct Event {
		Common::Event event;
		bool causedSkip;

		Event() : event(), causedSkip(false) {}
		Event(Common::Event e) : event(e), causedSkip(false) {}
		Event(Common::Event e, bool skip) : event(e), causedSkip(skip) {}

		operator Common::Event() const { return event; }
	};
	Common::List<Event> _eventList;

	virtual bool skipFlag() const;
	virtual void resetSkipFlag(bool removeEvent = true);

	// Animator
	struct AnimObj {
		uint16 index;
		uint16 type;
		bool enabled;
		uint16 needRefresh;
		uint16 specialRefresh;
		uint16 animFlags;
		uint16 flags;
		int16 xPos1, yPos1;
		uint8 *shapePtr;
		uint16 shapeIndex1;
		uint16 animNum;
		uint16 shapeIndex3;
		uint16 shapeIndex2;
		int16 xPos2, yPos2;
		int16 xPos3, yPos3;
		int16 width, height;
		int16 width2, height2;
		uint16 palette;
		AnimObj *nextObject;
	};

	void allocAnimObjects(int actors, int anims, int items);
	AnimObj *_animObjects;

	AnimObj *_animActor;
	AnimObj *_animAnims;
	AnimObj *_animItems;

	bool _drawNoShapeFlag;
	AnimObj *_animList;

	AnimObj *initAnimList(AnimObj *list, AnimObj *entry);
	AnimObj *addToAnimListSorted(AnimObj *list, AnimObj *entry);
	AnimObj *deleteAnimListEntry(AnimObj *list, AnimObj *entry);

	virtual void refreshAnimObjects(int force) = 0;
	void refreshAnimObjectsIfNeed();

	void flagAnimObjsSpecialRefresh();
	void flagAnimObjsForRefresh();

	virtual void clearAnimObjects() = 0;

	virtual void drawAnimObjects() = 0;
	virtual void drawSceneAnimObject(AnimObj *obj, int x, int y, int drawLayer) = 0;
	virtual void drawCharacterAnimObject(AnimObj *obj, int x, int y, int drawLayer) = 0;

	virtual void updateCharacterAnim(int) = 0;
	virtual void updateSceneAnim(int anim, int newFrame) = 0;

	void addItemToAnimList(int item);
	void deleteItemAnimEntry(int item);

	virtual void animSetupPaletteEntry(AnimObj *) {}

	virtual void setCharacterAnimDim(int w, int h) = 0;
	virtual void resetCharacterAnimDim() = 0;

	virtual int getScale(int x, int y) = 0;

	uint8 *_screenBuffer;

	// Scene
	struct SceneDesc {
		char filename1[10];
		char filename2[10];

		uint16 exit1, exit2, exit3, exit4;
		uint8 flags;
		uint8 sound;
	};

	SceneDesc *_sceneList;
	int _sceneListSize;
	uint16 _currentScene;

	uint16 _sceneExit1, _sceneExit2, _sceneExit3, _sceneExit4;
	int _sceneEnterX1, _sceneEnterY1, _sceneEnterX2, _sceneEnterY2,
		_sceneEnterX3, _sceneEnterY3, _sceneEnterX4, _sceneEnterY4;
	int _specialExitCount;
	uint16 _specialExitTable[25];
	bool checkSpecialSceneExit(int num, int x, int y);

	bool _overwriteSceneFacing;

	virtual void enterNewScene(uint16 newScene, int facing, int unk1, int unk2, int unk3) = 0;

	void runSceneScript6();

	EMCData _sceneScriptData;
	EMCState _sceneScriptState;

	virtual int trySceneChange(int *moveTable, int unk1, int unk2) = 0;

	// Animation
	virtual void restorePage3() = 0;

	struct SceneAnim {
		uint16 flags;
		int16 x, y;
		int16 x2, y2;
		int16 width, height;
		uint16 specialSize;
		int16 shapeIndex;
		uint16 wsaFlag;
		char filename[14];
	};

	SceneAnim _sceneAnims[16];
	WSAMovie_v2 *_sceneAnimMovie[16];

	void freeSceneAnims();

	bool _specialSceneScriptState[10];
	bool _specialSceneScriptStateBackup[10];
	EMCState _sceneSpecialScripts[10];
	uint32 _sceneSpecialScriptsTimer[10];
	int _lastProcessedSceneScript;
	bool _specialSceneScriptRunFlag;

	void updateSpecialSceneScripts();

	// Sequences
	EMCData _animationScriptData;
	EMCState _animationScriptState;
	Common::Array<const Opcode*> _opcodesAnimation;

	void runAnimationScript(const char *filename, int allowSkip, int resetChar, int newShapes, int shapeUnload);

	int o2a_setAnimationShapes(EMCState *script);
	int o2a_setResetFrame(EMCState *script);

	char _animShapeFilename[14];

	uint8 *_animShapeFiledata;
	int _animShapeCount;
	int _animShapeLastEntry;

	int _animNewFrame;
	int _animDelayTime;

	int _animResetFrame;

	int _animShapeWidth, _animShapeHeight;
	int _animShapeXAdd, _animShapeYAdd;

	bool _animNeedUpdate;

	virtual int initAnimationShapes(uint8 *filedata) = 0;
	void processAnimationScript(int allowSkip, int resetChar);
	virtual void uninitAnimationShapes(int count, uint8 *filedata) = 0;

	// Shapes
	typedef Common::HashMap<int, uint8*> ShapeMap;
	ShapeMap _gameShapes;

	uint8 *getShapePtr(int index) const;
	void addShapeToPool(const uint8 *data, int realIndex, int shape);
	void addShapeToPool(uint8 *shpData, int index);
	void remShapeFromPool(int idx);

	int _characterShapeFile;
	virtual void loadCharacterShapes(int shapes) = 0;
	
	// pathfinder
	int _movFacingTable[600];
	int _pathfinderFlag;

	int findWay(int curX, int curY, int dstX, int dstY, int *moveTable, int moveTableSize);

	bool directLinePassable(int x, int y, int toX, int toY);

	int pathfinderInitPositionTable(int *moveTable);
	int pathfinderAddToPositionTable(int index, int v1, int v2);
	int pathfinderInitPositionIndexTable(int tableLen, int x, int y);
	int pathfinderAddToPositionIndexTable(int index, int v);
	void pathfinderFinializePath(int *moveTable, int unk1, int x, int y, int moveTableSize);

	int _pathfinderPositionTable[400];
	int _pathfinderPositionIndexTable[200];

	// items
	struct Item {
		uint16 id;
		uint16 sceneId;
		int16 x;
		uint8 y;
	};

	void initItemList(int size);

	uint16 _hiddenItems[100];

	Item *_itemList;
	int _itemListSize;

	int _itemInHand;

	int findFreeItem();
	int countAllItems();

	int findItem(uint16 sceneId, uint16 id);
	int findItem(uint16 item);

	void resetItemList();
	void resetItem(int index);

	virtual void setMouseCursor(uint16 item) = 0;

	void setHandItem(uint16 item);
	void removeHandItem();

	// character
	struct Character {
		uint16 sceneId;
		int16 dlgIndex;
		uint8 height;
		uint8 facing;
		uint16 animFrame;
		byte walkspeed;
		uint16 inventory[20];
		int16 x1, y1;
		int16 x2, y2;
		int16 x3, y3;
	};

	Character _mainCharacter;
	int _mainCharX, _mainCharY;
	int _charScale;

	void moveCharacter(int facing, int x, int y);
	int updateCharPos(int *table, int force = 0);
	void updateCharPosWithUpdate();

	uint32 _updateCharPosNextUpdate;

	virtual int getCharacterWalkspeed() const = 0;
	virtual void updateCharAnimFrame(int num, int *table) = 0;

	// chat
	int _vocHigh;

	const char *_chatText;
	int _chatObject;
	uint32 _chatEndTime;
	int _chatVocHigh, _chatVocLow;

	EMCData _chatScriptData;
	EMCState _chatScriptState;

	virtual void setDlgIndex(int dlgIndex) = 0;

	virtual void randomSceneChat() = 0;

	// unknown
	int _unk3, _unk4, _unk5;
	bool _unkSceneScreenFlag1;
	bool _unkHandleSceneChangeFlag;

	// opcodes
	int o2_getCharacterX(EMCState *script);
	int o2_getCharacterY(EMCState *script);
	int o2_getCharacterFacing(EMCState *script);
	int o2_getCharacterScene(EMCState *script);
	int o2_setCharacterFacingOverwrite(EMCState *script);
	int o2_trySceneChange(EMCState *script);
	int o2_moveCharacter(EMCState *script);
	int o2_checkForItem(EMCState *script);
	int o2_defineItem(EMCState *script);
	int o2_addSpecialExit(EMCState *script);
	int o2_delay(EMCState *script);
	int o2_update(EMCState *script);
	int o2_getShapeFlag1(EMCState *script);
	int o2_waitForConfirmationClick(EMCState *script);
	int o2_randomSceneChat(EMCState *script);
	int o2_setDlgIndex(EMCState *script);
	int o2_getDlgIndex(EMCState *script);
	int o2_defineRoomEntrance(EMCState *script);
	int o2_runAnimationScript(EMCState *script);
	int o2_setSpecialSceneScriptRunTime(EMCState *script);
	int o2_defineScene(EMCState *script);
	int o2_setSpecialSceneScriptState(EMCState *script);
	int o2_clearSpecialSceneScriptState(EMCState *script);
	int o2_querySpecialSceneScriptState(EMCState *script);
	int o2_setHiddenItemsEntry(EMCState *script);
	int o2_getHiddenItemsEntry(EMCState *script);
	int o2_disableTimer(EMCState *script);
	int o2_enableTimer(EMCState *script);
	int o2_setTimerCountdown(EMCState *script);
	int o2_setVocHigh(EMCState *script);
	int o2_getVocHigh(EMCState *script);
};

} // end of namespace Kyra

#endif