-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgame.h
390 lines (365 loc) · 15.8 KB
/
game.h
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
/*
* REminiscence - Flashback interpreter
* Copyright (C) 2005-2019 Gregory Montoir ([email protected])
*/
#ifndef GAME_H__
#define GAME_H__
#include "intern.h"
#include "cutscene.h"
#include "menu.h"
#include "mixer.h"
#include "resource.h"
#include "video.h"
struct File;
struct FileSystem;
struct SystemStub;
struct Game {
typedef int (Game::*pge_OpcodeProc)(ObjectOpcodeArgs *args);
typedef int (Game::*pge_ZOrderCallback)(LivePGE *, LivePGE *, uint8_t, uint8_t);
typedef int (Game::*col_Callback1)(LivePGE *, LivePGE *, int16_t, int16_t);
typedef int (Game::*col_Callback2)(LivePGE *, int16_t, int16_t, int16_t);
enum {
kIngameSaveSlot = 0,
kRewindSize = 120, // 10mins (~2MB)
kAutoSaveSlot = 255,
kAutoSaveIntervalMs = 5 * 1000
};
enum {
CT_UP_ROOM = 0x00,
CT_DOWN_ROOM = 0x40,
CT_RIGHT_ROOM = 0x80,
CT_LEFT_ROOM = 0xC0
};
static const Demo _demoInputs[3];
static const Level _gameLevels[];
static const uint16_t _scoreTable[];
static const uint8_t _monsterListLevel1[];
static const uint8_t _monsterListLevel2[];
static const uint8_t _monsterListLevel3[];
static const uint8_t _monsterListLevel4_1[];
static const uint8_t _monsterListLevel4_2[];
static const uint8_t _monsterListLevel5_1[];
static const uint8_t _monsterListLevel5_2[];
static const uint8_t *_monsterListLevels[];
static const uint8_t _monsterPals[4][32];
static const char *_monsterNames[2][4];
static const pge_OpcodeProc _pge_opcodeTable[];
static const uint8_t _pge_modKeysTable[];
static const uint8_t _protectionCodeData[];
static const uint8_t _protectionWordData[];
static const uint8_t _protectionNumberDataAmiga[];
static const uint8_t _protectionCodeDataAmiga[];
static const uint8_t _protectionPal[];
Cutscene _cut;
Menu _menu;
Mixer _mix;
Resource _res;
Video _vid;
SystemStub *_stub;
FileSystem *_fs;
const char *_savePath;
File _rewindBuffer[kRewindSize];
int _rewindPtr, _rewindLen;
const uint8_t *_stringsTable;
const char **_textsTable;
uint8_t _currentLevel;
uint8_t _skillLevel;
int _demoBin;
uint32_t _score;
uint8_t _currentRoom;
uint8_t _currentIcon;
bool _loadMap;
uint8_t _printLevelCodeCounter;
uint32_t _randSeed;
uint16_t _currentInventoryIconNum;
uint16_t _curMonsterFrame;
uint16_t _curMonsterNum;
uint8_t _blinkingConradCounter;
uint16_t _textToDisplay;
bool _eraseBackground;
AnimBufferState _animBuffer0State[41];
AnimBufferState _animBuffer1State[6]; // Conrad
AnimBufferState _animBuffer2State[42];
AnimBufferState _animBuffer3State[12];
AnimBuffers _animBuffers;
uint16_t _deathCutsceneCounter;
bool _saveStateCompleted;
bool _endLoop;
uint32_t _frameTimestamp;
bool _autoSave;
uint32_t _saveTimestamp;
Game(SystemStub *, FileSystem *, const char *savePath, int level, ResourceType ver, Language lang, bool autoSave);
void run();
void displayTitleScreenAmiga();
void resetGameState();
void mainLoop();
void updateTiming();
void playCutscene(int id = -1);
bool hasLevelMap(int level, int room) const;
void loadLevelMap();
void loadLevelData();
void drawIcon(uint8_t iconNum, int16_t x, int16_t y, uint8_t colMask);
void drawCurrentInventoryItem();
void printLevelCode();
void showFinalScore();
bool handleConfigPanel();
bool handleContinueAbort();
void printSaveStateCompleted();
void drawLevelTexts();
void drawStoryTexts();
void drawString(const uint8_t *p, int x, int y, uint8_t color, bool hcenter = false);
void prepareAnims();
void prepareAnimsHelper(LivePGE *pge, int16_t dx, int16_t dy);
void drawAnims();
void drawAnimBuffer(uint8_t stateNum, AnimBufferState *state);
void drawPiege(AnimBufferState *state);
void drawObject(const uint8_t *dataPtr, int16_t x, int16_t y, uint8_t flags);
void drawObjectFrame(const uint8_t *bankDataPtr, const uint8_t *dataPtr, int16_t x, int16_t y, uint8_t flags);
void drawCharacter(const uint8_t *dataPtr, int16_t x, int16_t y, uint8_t a, uint8_t b, uint8_t flags);
int loadMonsterSprites(LivePGE *pge);
void playSound(uint8_t sfxId, uint8_t softVol);
uint16_t getRandomNumber();
void changeLevel();
void handleInventory();
// protection
bool handleProtectionScreenShape();
bool handleProtectionScreenWords();
// pieges
bool _pge_playAnimSound;
GroupPGE _pge_groups[256];
GroupPGE *_pge_groupsTable[256];
GroupPGE *_pge_nextFreeGroup;
LivePGE *_pge_liveTable2[256]; // active pieges list (index = pge number)
LivePGE *_pge_liveTable1[256]; // pieges list by room (index = room)
LivePGE _pgeLive[256];
uint8_t _pge_currentPiegeRoom;
bool _pge_currentPiegeFacingDir; // (false == left)
bool _pge_processOBJ;
uint8_t _pge_inpKeysMask;
uint16_t _pge_opTempVar1;
uint16_t _pge_opTempVar2;
uint16_t _pge_compareVar1;
uint16_t _pge_compareVar2;
void pge_resetGroups();
void pge_removeFromGroup(uint8_t idx);
int pge_isInGroup(LivePGE *pge_dst, uint16_t group_id, uint16_t counter);
void pge_loadForCurrentLevel(uint16_t idx);
void pge_process(LivePGE *pge);
void pge_setupNextAnimFrame(LivePGE *pge, GroupPGE *le);
void pge_playAnimSound(LivePGE *pge, uint16_t arg2);
void pge_setupAnim(LivePGE *pge);
int pge_execute(LivePGE *live_pge, InitPGE *init_pge, const Object *obj);
void pge_prepare();
void pge_setupDefaultAnim(LivePGE *pge);
uint16_t pge_processOBJ(LivePGE *pge);
void pge_setupOtherPieges(LivePGE *pge, InitPGE *init_pge);
void pge_addToCurrentRoomList(LivePGE *pge, uint8_t room);
void pge_getInput();
int pge_op_isInpUp(ObjectOpcodeArgs *args);
int pge_op_isInpBackward(ObjectOpcodeArgs *args);
int pge_op_isInpDown(ObjectOpcodeArgs *args);
int pge_op_isInpForward(ObjectOpcodeArgs *args);
int pge_op_isInpUpMod(ObjectOpcodeArgs *args);
int pge_op_isInpBackwardMod(ObjectOpcodeArgs *args);
int pge_op_isInpDownMod(ObjectOpcodeArgs *args);
int pge_op_isInpForwardMod(ObjectOpcodeArgs *args);
int pge_op_isInpIdle(ObjectOpcodeArgs *args);
int pge_op_isInpNoMod(ObjectOpcodeArgs *args);
int pge_op_getCollision0u(ObjectOpcodeArgs *args);
int pge_op_getCollision00(ObjectOpcodeArgs *args);
int pge_op_getCollision0d(ObjectOpcodeArgs *args);
int pge_op_getCollision1u(ObjectOpcodeArgs *args);
int pge_op_getCollision10(ObjectOpcodeArgs *args);
int pge_op_getCollision1d(ObjectOpcodeArgs *args);
int pge_op_getCollision2u(ObjectOpcodeArgs *args);
int pge_op_getCollision20(ObjectOpcodeArgs *args);
int pge_op_getCollision2d(ObjectOpcodeArgs *args);
int pge_op_doesNotCollide0u(ObjectOpcodeArgs *args);
int pge_op_doesNotCollide00(ObjectOpcodeArgs *args);
int pge_op_doesNotCollide0d(ObjectOpcodeArgs *args);
int pge_op_doesNotCollide1u(ObjectOpcodeArgs *args);
int pge_op_doesNotCollide10(ObjectOpcodeArgs *args);
int pge_op_doesNotCollide1d(ObjectOpcodeArgs *args);
int pge_op_doesNotCollide2u(ObjectOpcodeArgs *args);
int pge_op_doesNotCollide20(ObjectOpcodeArgs *args);
int pge_op_doesNotCollide2d(ObjectOpcodeArgs *args);
int pge_op_collides0o0d(ObjectOpcodeArgs *args);
int pge_op_collides2o2d(ObjectOpcodeArgs *args);
int pge_op_collides0o0u(ObjectOpcodeArgs *args);
int pge_op_collides2o2u(ObjectOpcodeArgs *args);
int pge_op_collides2u2o(ObjectOpcodeArgs *args);
int pge_op_isInGroup(ObjectOpcodeArgs *args);
int pge_op_updateGroup0(ObjectOpcodeArgs *args);
int pge_op_updateGroup1(ObjectOpcodeArgs *args);
int pge_op_updateGroup2(ObjectOpcodeArgs *args);
int pge_op_updateGroup3(ObjectOpcodeArgs *args);
int pge_op_isPiegeDead(ObjectOpcodeArgs *args);
int pge_op_collides1u2o(ObjectOpcodeArgs *args);
int pge_op_collides1u1o(ObjectOpcodeArgs *args);
int pge_op_collides1o1u(ObjectOpcodeArgs *args);
int pge_o_unk0x2B(ObjectOpcodeArgs *args);
int pge_o_unk0x2C(ObjectOpcodeArgs *args);
int pge_o_unk0x2D(ObjectOpcodeArgs *args);
int pge_op_nop(ObjectOpcodeArgs *args);
int pge_op_pickupObject(ObjectOpcodeArgs *args);
int pge_op_addItemToInventory(ObjectOpcodeArgs *args);
int pge_op_copyPiege(ObjectOpcodeArgs *args);
int pge_op_canUseCurrentInventoryItem(ObjectOpcodeArgs *args);
int pge_op_removeItemFromInventory(ObjectOpcodeArgs *args);
int pge_o_unk0x34(ObjectOpcodeArgs *args);
int pge_op_isInpMod(ObjectOpcodeArgs *args);
int pge_op_setCollisionState1(ObjectOpcodeArgs *args);
int pge_op_setCollisionState0(ObjectOpcodeArgs *args);
int pge_op_isInGroup1(ObjectOpcodeArgs *args);
int pge_op_isInGroup2(ObjectOpcodeArgs *args);
int pge_op_isInGroup3(ObjectOpcodeArgs *args);
int pge_op_isInGroup4(ObjectOpcodeArgs *args);
int pge_o_unk0x3C(ObjectOpcodeArgs *args);
int pge_o_unk0x3D(ObjectOpcodeArgs *args);
int pge_op_setPiegeCounter(ObjectOpcodeArgs *args);
int pge_op_decPiegeCounter(ObjectOpcodeArgs *args);
int pge_o_unk0x40(ObjectOpcodeArgs *args);
int pge_op_wakeUpPiege(ObjectOpcodeArgs *args);
int pge_op_removePiege(ObjectOpcodeArgs *args);
int pge_op_removePiegeIfNotNear(ObjectOpcodeArgs *args);
int pge_op_loadPiegeCounter(ObjectOpcodeArgs *args);
int pge_o_unk0x45(ObjectOpcodeArgs *args);
int pge_o_unk0x46(ObjectOpcodeArgs *args);
int pge_o_unk0x47(ObjectOpcodeArgs *args);
int pge_o_unk0x48(ObjectOpcodeArgs *args);
int pge_o_unk0x49(ObjectOpcodeArgs *args);
int pge_o_unk0x4A(ObjectOpcodeArgs *args);
int pge_op_killPiege(ObjectOpcodeArgs *args);
int pge_op_isInCurrentRoom(ObjectOpcodeArgs *args);
int pge_op_isNotInCurrentRoom(ObjectOpcodeArgs *args);
int pge_op_scrollPosY(ObjectOpcodeArgs *args);
int pge_op_playDefaultDeathCutscene(ObjectOpcodeArgs *args);
int pge_o_unk0x50(ObjectOpcodeArgs *args);
int pge_o_unk0x52(ObjectOpcodeArgs *args);
int pge_o_unk0x53(ObjectOpcodeArgs *args);
int pge_op_isPiegeNear(ObjectOpcodeArgs *args);
int pge_op_setLife(ObjectOpcodeArgs *args);
int pge_op_incLife(ObjectOpcodeArgs *args);
int pge_op_setPiegeDefaultAnim(ObjectOpcodeArgs *args);
int pge_op_setLifeCounter(ObjectOpcodeArgs *args);
int pge_op_decLifeCounter(ObjectOpcodeArgs *args);
int pge_op_playCutscene(ObjectOpcodeArgs *args);
int pge_op_isTempVar2Set(ObjectOpcodeArgs *args);
int pge_op_playDeathCutscene(ObjectOpcodeArgs *args);
int pge_o_unk0x5D(ObjectOpcodeArgs *args);
int pge_o_unk0x5E(ObjectOpcodeArgs *args);
int pge_o_unk0x5F(ObjectOpcodeArgs *args);
int pge_op_findAndCopyPiege(ObjectOpcodeArgs *args);
int pge_op_isInRandomRange(ObjectOpcodeArgs *args);
int pge_o_unk0x62(ObjectOpcodeArgs *args);
int pge_o_unk0x63(ObjectOpcodeArgs *args);
int pge_o_unk0x64(ObjectOpcodeArgs *args);
int pge_op_addToCredits(ObjectOpcodeArgs *args);
int pge_op_subFromCredits(ObjectOpcodeArgs *args);
int pge_o_unk0x67(ObjectOpcodeArgs *args);
int pge_op_setCollisionState2(ObjectOpcodeArgs *args);
int pge_op_saveState(ObjectOpcodeArgs *args);
int pge_o_unk0x6A(ObjectOpcodeArgs *args);
int pge_op_isInGroupSlice(ObjectOpcodeArgs *args);
int pge_o_unk0x6C(ObjectOpcodeArgs *args);
int pge_op_isCollidingObject(ObjectOpcodeArgs *args);
int pge_o_unk0x6E(ObjectOpcodeArgs *args);
int pge_o_unk0x6F(ObjectOpcodeArgs *args);
int pge_o_unk0x70(ObjectOpcodeArgs *args);
int pge_o_unk0x71(ObjectOpcodeArgs *args);
int pge_o_unk0x72(ObjectOpcodeArgs *args);
int pge_o_unk0x73(ObjectOpcodeArgs *args);
int pge_op_collides4u(ObjectOpcodeArgs *args);
int pge_op_doesNotCollide4u(ObjectOpcodeArgs *args);
int pge_op_isBelowConrad(ObjectOpcodeArgs *args);
int pge_op_isAboveConrad(ObjectOpcodeArgs *args);
int pge_op_isNotFacingConrad(ObjectOpcodeArgs *args);
int pge_op_isFacingConrad(ObjectOpcodeArgs *args);
int pge_op_collides2u1u(ObjectOpcodeArgs *args);
int pge_op_displayText(ObjectOpcodeArgs *args);
int pge_o_unk0x7C(ObjectOpcodeArgs *args);
int pge_op_playSound(ObjectOpcodeArgs *args);
int pge_o_unk0x7E(ObjectOpcodeArgs *args);
int pge_o_unk0x7F(ObjectOpcodeArgs *args);
int pge_op_setPiegePosX(ObjectOpcodeArgs *args);
int pge_op_setPiegePosModX(ObjectOpcodeArgs *args);
int pge_op_changeRoom(ObjectOpcodeArgs *args);
int pge_op_hasInventoryItem(ObjectOpcodeArgs *args);
int pge_op_changeLevel(ObjectOpcodeArgs *args);
int pge_op_shakeScreen(ObjectOpcodeArgs *args);
int pge_o_unk0x86(ObjectOpcodeArgs *args);
int pge_op_playSoundGroup(ObjectOpcodeArgs *args);
int pge_op_adjustPos(ObjectOpcodeArgs *args);
int pge_op_setTempVar1(ObjectOpcodeArgs *args);
int pge_op_isTempVar1Set(ObjectOpcodeArgs *args);
int pge_setCurrentInventoryObject(LivePGE *pge);
void pge_updateInventory(LivePGE *pge1, LivePGE *pge2);
void pge_reorderInventory(LivePGE *pge);
LivePGE *pge_getInventoryItemBefore(LivePGE *pge, LivePGE *last_pge);
void pge_addToInventory(LivePGE *pge1, LivePGE *pge2, LivePGE *pge3);
int pge_updateCollisionState(LivePGE *pge, int16_t pge_dy, uint8_t var8);
int pge_ZOrder(LivePGE *pge, int16_t num, pge_ZOrderCallback compare, uint16_t unk);
void pge_updateGroup(uint8_t idx, uint8_t unk1, int16_t unk2);
void pge_removeFromInventory(LivePGE *pge1, LivePGE *pge2, LivePGE *pge3);
int pge_ZOrderByAnimY(LivePGE *pge1, LivePGE *pge2, uint8_t comp, uint8_t comp2);
int pge_ZOrderByAnimYIfType(LivePGE *pge1, LivePGE *pge2, uint8_t comp, uint8_t comp2);
int pge_ZOrderIfIndex(LivePGE *pge1, LivePGE *pge2, uint8_t comp, uint8_t comp2);
int pge_ZOrderByIndex(LivePGE *pge1, LivePGE *pge2, uint8_t comp, uint8_t comp2);
int pge_ZOrderByObj(LivePGE *pge1, LivePGE *pge2, uint8_t comp, uint8_t comp2);
int pge_ZOrderIfDifferentDirection(LivePGE *pge1, LivePGE *pge2, uint8_t comp, uint8_t comp2);
int pge_ZOrderIfSameDirection(LivePGE *pge1, LivePGE *pge2, uint8_t comp, uint8_t comp2);
int pge_ZOrderIfTypeAndSameDirection(LivePGE *pge1, LivePGE *pge2, uint8_t comp, uint8_t comp2);
int pge_ZOrderIfTypeAndDifferentDirection(LivePGE *pge1, LivePGE *pge2, uint8_t comp, uint8_t comp2);
int pge_ZOrderByNumber(LivePGE *pge1, LivePGE *pge2, uint8_t comp, uint8_t comp2);
// collision
CollisionSlot _col_slots[256];
uint8_t _col_curPos;
CollisionSlot *_col_slotsTable[256];
CollisionSlot *_col_curSlot;
CollisionSlot2 _col_slots2[256];
CollisionSlot2 *_col_slots2Cur;
CollisionSlot2 *_col_slots2Next;
uint8_t _col_activeCollisionSlots[0x30 * 3]; // left, current, right
uint8_t _col_currentLeftRoom;
uint8_t _col_currentRightRoom;
int16_t _col_currentPiegeGridPosX;
int16_t _col_currentPiegeGridPosY;
void col_prepareRoomState();
void col_clearState();
LivePGE *col_findPiege(LivePGE *pge, uint16_t arg2);
int16_t col_findSlot(int16_t pos);
void col_preparePiegeState(LivePGE *dst_pge);
uint16_t col_getGridPos(LivePGE *pge, int16_t dx);
int16_t col_getGridData(LivePGE *pge, int16_t dy, int16_t dx);
uint8_t col_findCurrentCollidingObject(LivePGE *pge, uint8_t n1, uint8_t n2, uint8_t n3, LivePGE **pge_out);
int16_t col_detectHit(LivePGE *pge, int16_t arg2, int16_t arg4, col_Callback1 callback1, col_Callback2 callback2, int16_t argA, int16_t argC);
int col_detectHitCallback2(LivePGE *pge1, LivePGE *pge2, int16_t unk1, int16_t unk2);
int col_detectHitCallback3(LivePGE *pge1, LivePGE *pge2, int16_t unk1, int16_t unk2);
int col_detectHitCallback4(LivePGE *pge1, LivePGE *pge2, int16_t unk1, int16_t unk2);
int col_detectHitCallback5(LivePGE *pge1, LivePGE *pge2, int16_t unk1, int16_t unk2);
int col_detectHitCallback1(LivePGE *pge, int16_t dy, int16_t unk1, int16_t unk2);
int col_detectHitCallback6(LivePGE *pge, int16_t dy, int16_t unk1, int16_t unk2);
int col_detectHitCallbackHelper(LivePGE *pge, int16_t unk1);
int col_detectGunHitCallback1(LivePGE *pge, int16_t arg2, int16_t arg4, int16_t arg6);
int col_detectGunHitCallback2(LivePGE *pge1, LivePGE *pge2, int16_t arg4, int16_t);
int col_detectGunHitCallback3(LivePGE *pge1, LivePGE *pge2, int16_t arg4, int16_t);
int col_detectGunHit(LivePGE *pge, int16_t arg2, int16_t arg4, col_Callback1 callback1, col_Callback2 callback2, int16_t argA, int16_t argC);
// input
uint8_t _inp_lastKeysHit;
uint8_t _inp_lastKeysHitLeftRight;
int _inp_demPos;
void inp_handleSpecialKeys();
void inp_update();
// save/load state
uint8_t _stateSlot;
bool _validSaveState;
void makeGameStateName(uint8_t slot, char *buf);
bool saveGameState(uint8_t slot);
bool loadGameState(uint8_t slot);
void saveState(File *f);
void loadState(File *f);
void clearStateRewind();
bool saveStateRewind();
bool loadStateRewind();
};
#endif // GAME_H__