ScummVM API documentation
rebel.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#if !defined(SCUMM_INSANE_REBEL2_H) && defined(ENABLE_SCUMM_7_8)
23#define SCUMM_INSANE_REBEL2_H
24
25#include "scumm/nut_renderer.h"
26
27#include "scumm/smush/smush_player.h"
28
29#include "scumm/insane/insane.h"
30#include "scumm/insane/rebel/rebel_audio.h"
31#include "scumm/insane/rebel/rebel_gamepad.h"
32#include "scumm/insane/rebel/rebel_touch.h"
33#include "scumm/insane/rebel2/releases.h"
34
35#include "common/keyboard.h"
36#include "common/list.h"
37#include "common/rect.h"
38#include "common/events.h"
39#include "common/queue.h"
40
41#include "audio/audiostream.h"
42#include "audio/mixer.h"
43
44#include "graphics/surface.h"
45
46namespace Audio {
47class QueuingAudioStream;
48class SoundHandle;
49}
50
51namespace Scumm {
52
53class InsaneRebel2 : public Insane, public Common::EventObserver {
54
55public:
56 InsaneRebel2(ScummEngine_v7 *scumm);
57 ~InsaneRebel2();
58
59 const Rebel2Release _release;
60
61 bool notifyEvent(const Common::Event &event) override;
62
63 Common::Queue<Common::Event> _menuEventQueue;
64 bool _menuInputActive;
65 bool _virtualKeyboardActive;
66
67 // Menu state.
68 enum GameState {
69 kStateIntro = 0,
70 kStateMainMenu = 1,
71 kStatePilotSelect = 2,
72 kStateChapterSelect = 3,
73 kStateGameplay = 4,
74 kStateCredits = 5,
75 kStateQuit = 6,
76 kStateTopPilots = 8,
77 kStateDifficultySelect = 7,
78 kStateOptions = 9
79 };
80
81 enum MenuResult {
82 kMenuQuit = -1,
83 kMenuResumeDemo = 0,
84 kMenuCredits = 1,
85 kMenuNewGame = 2
86 };
87
88 GameState _gameState;
89 int _menuSelection;
90 int _menuItemCount;
91 int _menuInactivityTimer;
92 bool _menuInactivityTimedOut;
93 int _lastMenuVariant;
94 int _menuRepeatDelay;
95 bool _menuSelectionConfirmed;
96 bool _levelUnlocked[16];
97
98 int runMainMenu();
99 int processMenuInput();
100
101 // Format-code-aware string rendering (^fNN=font, ^cNNN=color)
102 // parseFormatCode: advances str past ^fNN/^cNNN/^^/^l codes.
103 // Returns: fontIdx (>=0) on font change, -2 on color/newline, -1 on no match.
104 static int parseFormatCode(const char *&str, int &outColor);
105
106 int getMenuStringWidth(const char *str) const;
107 void drawMenuString(byte *renderBitmap, const char *str, int x, int y, int defaultColor = 1);
108 void drawMenuStringCentered(byte *renderBitmap, const char *str, int cx, int y, int defaultColor = 1);
109 void drawMenuStringRight(byte *renderBitmap, const char *str, int rx, int y, int defaultColor = 1);
110
111 void drawMenuItems(byte *renderBitmap, int pitch, int width, int height,
112 const char **items, int numItems, int selection,
113 bool leftAligned = false);
114 void drawMenuOverlay(byte *renderBitmap, int pitch, int width, int height);
115 Common::String getRandomMenuVideo();
116 void resetMenu();
117 bool isMenuTextInputActive() const;
118 void setVirtualKeyboardVisible(bool visible);
119 void updateMenuVirtualKeyboard();
120
121 // Chapter selection.
122 enum ChapterSelectResult {
123 kChapterSelectBack = 2,
124 kChapterSelectPlay = 5,
125 kChapterSelectQuit = 0
126 };
127
128 int _chapterSelection;
129 int _chapterItemCount;
130 int _selectedChapter;
131 Common::String _passwordInput;
132 bool _chapterUnlocked[16];
133 bool _debugUnlockAll;
134 bool _noDamage;
135
136 void unlockAllChapters();
137 void updateChapterUnlocks();
138 int runChapterSelect();
139 void drawChapterSelectOverlay(byte *renderBitmap, int pitch, int width, int height);
140 int processChapterSelectInput();
141 void drawPreviewBox(byte *renderBitmap, int pitch, int width, int height);
142
143 int16 _previewOffsetX;
144 int16 _previewOffsetY;
145
146 void drawChapterInfoLine(byte *renderBitmap, int pitch, int width, int height);
147 void drawPilotInfoLines(byte *renderBitmap);
148 Common::String getRankString(int rating);
149 Common::String getChapterPassword(int level, int difficulty);
150
151 // Top pilots.
152 static const int kMaxRankings = 15;
153
154 struct RankingEntry {
155 char name[40];
156 int32 score;
157 int32 rating;
158 int16 difficulty;
159 int16 chapter;
160 };
161
162 RankingEntry _rankings[kMaxRankings];
163 int _numRankings;
164
165 void initDefaultRankings();
166 void insertRanking(const char *name, int32 score, int32 rating, int16 difficulty, int16 chapter);
167 void showTopPilots();
168 void drawTopPilotsOverlay(byte *renderBitmap, int pitch, int width, int height);
169
170 int _topPilotsFrameCount;
171 int _topPilotsMaxFrames;
172
173 // Options menu.
174 void showOptionsMenu();
175 void drawOptionsOverlay(byte *renderBitmap, int pitch, int width, int height);
176 int processOptionsInput();
177
178 int _optionsSelection;
179 int _optionsItemCount;
180 bool _optionsExitRequested;
181 bool _optMusicEnabled;
182 bool _optSfxEnabled;
183 bool _optVoicesEnabled;
184 bool _optTextEnabled;
185 bool _optControlsFlipped;
186 bool _optRapidFire;
187 int _optVolumeLevel;
188
189 // Pilot profiles.
190 static const int kMaxPilots = 10;
191 static const int kMaxPilotNameLen = 15;
192 static const int kNumLevels = 16;
193
194 struct PilotData {
195 char name[kMaxPilotNameLen + 1];
196 int32 score[kNumLevels];
197 int32 lives[kNumLevels];
198 int32 damage[kNumLevels];
199 int16 rating[kNumLevels];
200 int16 difficulty;
201
202 void init(int firstLevel = 1, int initialLives = 4) {
203 memset(name, 0, sizeof(name));
204 memset(rating, 0, sizeof(rating));
205 difficulty = 2;
206 for (int i = 0; i < kNumLevels; i++) {
207 score[i] = 0;
208 lives[i] = 0xFF;
209 damage[i] = 0xFF;
210 }
211 if (firstLevel >= 1 && firstLevel <= kNumLevels) {
212 lives[firstLevel - 1] = initialLives;
213 damage[firstLevel - 1] = 0;
214 }
215 }
216 };
217
218 PilotData _pilots[kMaxPilots];
219 int _numPilots;
220 int _activePilot;
221
222 bool loadPilots();
223 bool savePilots();
224
225 int createNewPilot();
226 void deletePilot(int index);
227 void copyPilot(int srcIndex);
228
229 void updatePilotProgress(int levelIndex, int32 score, int32 lives, int32 damage, int32 rating);
230
231 // Activates a pilot and derives its unlocked chapters, as the pilot menu does.
232 bool selectPilot(int index);
233
234 // Loading a pilot drops straight into the chapter selection.
235 Common::Error loadGameState(int slot, bool startupLoad = false);
236 bool _pilotLoadRequested;
237
238 enum LevelSelectResult {
239 kLevelSelectBack = 0,
240 kLevelSelectPlay = 1,
241 kLevelSelectQuit = 2
242 };
243
244 enum PilotMenuMode {
245 kPilotModeSelect = 0,
246 kPilotModeNameInput = 1,
247 kPilotModeDifficulty = 2,
248 kPilotModeCopySelect = 3,
249 kPilotModeDeleteSelect = 4
250 };
251 PilotMenuMode _pilotMenuMode;
252 Common::String _pilotNameInput;
253 int _pilotEditIndex;
254
255 int _levelSelection;
256 int _levelItemCount;
257 int _selectedLevel;
258 int _difficultySelection;
259
260 int runLevelSelect();
261 void drawLevelSelectOverlay(byte *renderBitmap, int pitch, int width, int height);
262 int processLevelSelectInput();
263
264 // Level playback.
265 enum LevelResult {
266 kLevelCompleted = 0,
267 kLevelNextLevel = 1,
268 kLevelGameOver = 2,
269 kLevelQuit = 3,
270 kLevelReturnToMenu = 4
271 };
272
273 void runGame();
274 void playIntroSequence();
275 void playMissionBriefing();
276 int runLevel(int levelId);
277 void playLevelBegin(int levelId);
278 void playLevelEnd(int levelId);
279 void playLevelEnd(int levelId, int accuracy, int flightErrors, bool skillBonus);
280 void playLevelRetry(int levelId);
281 void playLevelGameOver(int levelId);
282 void playEndingSequence();
283 void playCreditsSequence();
284 Common::String getLevelDir(int levelId);
285 Common::String getLevelPrefix(int levelId);
286
287 // Per-level handlers.
288 class Level1Handler;
289 int runLevel1();
290 class Level2Handler;
291 int runLevel2();
292 int runLevel3();
293 int runLevel4();
294 int runLevel5();
295 int runLevel6();
296 int runLevel7();
297 int runLevel8();
298 int runLevel9();
299 int runLevel10();
300 int runLevel11();
301 int runLevel12();
302 int runLevel13();
303 int runLevel14();
304 int runLevel15();
305
306 // Wave bookkeeping shared by looping combat sections.
307 struct WaveEndResult {
308 WaveEndResult() : creditedBits(0), died(false), quit(false), completed(false), skipped(false) {}
309
310 bool shouldStop() const { return died || quit || completed || skipped; }
311
312 uint16 creditedBits;
313 bool died;
314 bool quit;
315 bool completed;
316 bool skipped;
317 };
318
319 WaveEndResult processWaveEnd(int16 mask, int16 *budget, int16 threshold, uint16 flags);
320
321 // Shared SAN segment dispatcher for scripted level handlers.
322 bool playLevelSegment(const char *filename, uint16 flags, bool recordFrame = true);
323 void enableIOSGamepadController();
324 void restoreIOSGamepadController();
325
326 int calculateAccuracy(int kills, int misses) const;
327
328 bool handleLevelDeath(int levelId, int phase, const char *deathVideo, const char *retryVideo, int &levelResult);
329 void resetLevelAttemptState(int initialPhase);
330 void resetLevelPhaseState(bool clearEnemies);
331 void clearEmbeddedHudFrames();
332 void resetLevelWaveState();
333 void resetExplosions();
334 void resetHandler7FlightState();
335
336 int getRandomVariant(int max);
337 Common::String selectDeathVideoVariant(int levelId, int phase, int frame);
338 void playCinematic(const char *filename, int16 flags = 0x28);
339
340 // Text is progressively revealed during [fadeInFrame, fadeOutFrame)
341 void playVideoWithText(const char *filename, int textID, int textX, int textY,
342 int fadeInFrame, int fadeOutFrame);
343
344 bool _textOverlayActive;
345 int _textOverlayID;
346 int _textOverlayX;
347 int _textOverlayY;
348 int _textOverlayFadeIn;
349 int _textOverlayFadeOut;
350
351 void renderTextOverlay(byte *renderBitmap, int pitch, int width, int height, int curFrame);
352 void renderLevelEndStatsOverlay(byte *renderBitmap, int pitch, int width, int height, int32 curFrame, int32 maxFrame);
353 void drawLevelEndTextBlock(byte *renderBitmap, const char *text, int centerX, int y);
354 void prepareLevelEndStats(int levelId, int accuracy, int flightErrors, bool skillBonus);
355 int calculateLevelEndRating(int accuracy, int accLow, int accHigh, int flightErrors, int errLow, int errHigh, bool skillBonus) const;
356
357 struct LevelEndStatsOverlay {
358 bool active;
359 int levelId;
360 int textX;
361 int textY;
362 int titleStartBeforeEnd;
363 int titleEndBeforeEnd;
364 bool hasAccuracy;
365 bool hasFlightErrors;
366 bool skillBonus;
367 int accuracy;
368 int flightErrors;
369 int bonus;
370 int finalScore;
371 int oldRating;
372 int newRating;
373 };
374 LevelEndStatsOverlay _levelEndStats;
375 void playLevelDeathVariant(int levelId, int phase, int frame);
376 void playLevelRetryVariant(int levelId, int phase);
377
378 void centerGameplayAim();
379 bool _gameplaySectionActive;
380 RebelIOSGamepadControllerState _iosGamepadControllerState;
381 RebelTouchTapDetector _touchTapDetector;
382
383 int _currentPhase;
384 int _deathFrame;
385 int _rebelDeathCause; // 0 = enemy shot, 1 = direct hit, 2 = collision; picks the death video
386 bool _skipSectionRequested;
387
388 // Resources and fonts.
389 NutRenderer *_smush_cockpitNut;
390 NutRenderer *_rebelMsgFont;
391
392 NutRenderer *_smush_talkfontNut;
393 NutRenderer *_smush_smalfontNut;
394 NutRenderer *_smush_titlefontNut;
395 NutRenderer *_smush_povfontNut;
396
397 byte _savedPausePalette[768];
398 Graphics::Surface _savedPauseScreen;
399 bool _pauseOverlayActive;
400
401 bool _introCursorPushed;
402
403
404 int32 processMouse() override;
405 bool isTouchscreenActive() const;
406 bool isSkippableVideoState() const;
407 Common::Point getGameplayAimPoint();
408 Common::Point getGameplayPointerPos();
409 Common::Point getRebelAutoPlayAimPoint();
410 void resetMenuGamepadAxis();
411 bool handleMenuGamepadAxisEvent(const Common::Event &event);
412 bool handleMenuRawJoystickAxisEvent(const Common::Event &event);
413 void updateMenuGamepadAxisKey(int16 oldAxisX, int16 oldAxisY);
414 void queueMenuGamepadAxisKey(Common::KeyCode keycode);
415 void updateGameplayAimFromGamepad();
416 void warpGameplayMouseNow(int x, int y);
417
418 int16 _joystickAxisX;
419 int16 _joystickAxisY;
420
421 bool _gamepadAimActive;
422 uint32 _gameplayMouseSettleUntil;
423 uint32 _lastGameplayMenuCloseTime;
424 uint32 _lastMenuGamepadNavigationTime;
425 int16 _menuGamepadAxisX;
426 int16 _menuGamepadAxisY;
427 int _menuGamepadRawAxis;
428 int16 _menuGamepadRawAxisX;
429 int16 _menuGamepadRawAxisY;
430 void openGameplayMainMenu(SmushPlayer *splayer);
431 void openMenuMainMenu(SmushPlayer *splayer);
432 bool isBitSet(int n) override;
433 void setBit(int n) override;
434
435 int getHandler() const { return _rebelHandler; }
436 int getHandler25GrdSpriteMode() const { return _grdSpriteMode; }
437 bool isHiRes() const;
438
439 void iactRebel2Scene1(byte *renderBitmap, int32 codecparam, int32 setupsan12,
440 int32 setupsan13, Common::SeekableReadStream &b, int32 size, int32 flags,
441 int16 par1, int16 par2, int16 par3, int16 par4);
442
443 void iactRebel2Opcode2(Common::SeekableReadStream &b, int16 par2, int16 par3, int16 par4);
444 void iactRebel2Opcode3(Common::SeekableReadStream &b, int16 par2, int16 par3, int16 par4);
445 void iactRebel2Opcode6(byte *renderBitmap, Common::SeekableReadStream &b, int32 chunkSize, int16 par2, int16 par3, int16 par4);
446 void updateOpcode6Handler(int16 par2);
447 void handleOpcode6Handler8(Common::SeekableReadStream &b, int16 par4);
448 void handleOpcode6Handler7(Common::SeekableReadStream &b, int16 par4);
449 void handleOpcode6Handler25(byte *renderBitmap, Common::SeekableReadStream &b, int16 par2, int16 par3, int16 par4);
450 void handleOpcode6Turret(Common::SeekableReadStream &b, int16 par4);
451 void handleOpcode6GenericInit(int16 par4);
452 void updateOpcode6GenericFlightState();
453 void scanOpcode6EmbeddedAnim(byte *renderBitmap, Common::SeekableReadStream &b, int32 chunkSize, int16 par4);
454 void iactRebel2Opcode8(byte *renderBitmap, Common::SeekableReadStream &b, int32 chunkSize, int16 par2, int16 par3, int16 par4);
455 bool loadOpcode8Handler7FlySprites(Common::SeekableReadStream &b, int64 startPos, int64 remaining, int16 par4);
456 bool loadOpcode8Handler7ShotTable(Common::SeekableReadStream &b, int64 startPos, int64 remaining, int16 par4);
457 bool loadOpcode8EdgeTable(Common::SeekableReadStream &b, int64 startPos, int64 remaining, int16 par4);
458 bool loadOpcode8AuxSfx(Common::SeekableReadStream &b, int64 startPos, int64 remaining, int16 par4);
459 bool loadOpcode8ShotOriginTable(Common::SeekableReadStream &b, int64 startPos, int64 remaining, int16 par4);
460 void loadOpcode8EmbeddedAnim(byte *renderBitmap, Common::SeekableReadStream &b, int64 startPos, int64 remaining, int16 par3, int16 par4);
461 bool handleOpcode8EmbeddedAnim(byte *renderBitmap, byte *animData, int32 animDataSize, int16 par3, int16 par4);
462 void iactRebel2Opcode9(byte *renderBitmap, Common::SeekableReadStream &b, int16 par2, int16 par3, int16 par4);
463
464 void procPostRendering(byte *renderBitmap, int32 codecparam, int32 setupsan12,
465 int32 setupsan13, int32 curFrame, int32 maxFrame) override;
466
467 void procIACT(byte *renderBitmap, int32 codecparam, int32 setupsan12,
468 int32 setupsan13, Common::SeekableReadStream &b, int32 size, int32 flags,
469 int16 par1, int16 par2, int16 par3, int16 par4) override;
470
471 void renderStatusBarBackground(byte *renderBitmap, int pitch, int width, int height,
472 int videoWidth, int videoHeight, int statusBarY);
473
474 void updatePostRenderScroll(int width, int height);
475 void updatePostRenderDeath();
476 void renderPostRenderMenuCursor(byte *renderBitmap, int pitch, int width, int height);
477 bool handlePostRenderMenuModes(byte *renderBitmap, int pitch, int width, int height, bool introPlaying);
478 bool handlePostRenderIntro(byte *renderBitmap, int pitch, int width, int height, int32 curFrame, int32 maxFrame);
479 void prepareHandler7Viewport(byte *renderBitmap, int pitch, int width, int height);
480 void renderGameplayPostFrame(byte *renderBitmap, int pitch, int width, int height,
481 int videoWidth, int videoHeight, int statusBarY, int32 curFrame);
482 void updateGameplayDamageEffects(byte *renderBitmap, int pitch, int width, int height);
483 void updateGameplayTimedTick(int32 curFrame);
484 void checkGameplayPostRenderCollisions(byte *renderBitmap, int pitch, int width, int height, int32 curFrame);
485
486 void renderTurretHudOverlays(byte *renderBitmap, int pitch, int width, int height, int32 curFrame);
487 void renderEmbeddedHudOverlays(byte *renderBitmap, int pitch, int width, int height);
488 void renderStatusBarSprites(byte *renderBitmap, int pitch, int width, int height,
489 int statusBarY, int32 curFrame);
490
491 void renderHandler7Ship(byte *renderBitmap, int pitch, int width, int height);
492 void renderHandler7FlySprite(byte *renderBitmap, int pitch, int width, int height,
493 bool renderHiRes, int renderScale, int nativeViewX, int nativeViewY,
494 int nativeX, int nativeY, NutRenderer *nut, int spriteIndex);
495
496 void renderHandler8Ship(byte *renderBitmap, int pitch, int width, int height);
497 void renderVehicleShotImpacts(byte *renderBitmap, int pitch, int width, int height);
498
499 void renderFallbackShip(byte *renderBitmap, int pitch, int width, int height);
500 void renderEnemyOverlays(byte *renderBitmap, int pitch, int width, int height, int videoWidth);
501 void renderExplosions(byte *renderBitmap, int pitch, int width, int height);
502 void renderLaserShots(byte *renderBitmap, int pitch, int width, int height);
503 void renderCrosshair(byte *renderBitmap, int pitch, int width, int height);
504 void renderHandler8MonitorEffect(byte *renderBitmap, int pitch, int width, int height);
505 void renderHandler8PovOverlay(byte *renderBitmap, int pitch, int width, int height);
506 Common::Point getHandler7ProjectedPointFor(int16 x, int16 y);
507 Common::Point getHandler7ProjectedPoint();
508 Common::Point getHandler7ShotTargetPoint();
509 Common::Point getHandler8ShotTargetPoint();
510
511 void frameEndCleanup();
512
513 // Opcode 8 resource loading.
514 bool loadHandler7FlySprites(Common::SeekableReadStream &b, int64 remaining, int16 par4);
515 bool loadHandler7ShotTable(Common::SeekableReadStream &b, int64 startPos, int64 remaining, int16 par4);
516
517 bool loadTurretHudOverlay(byte *animData, int32 size, int16 selector);
518 bool loadHandler8ShipSprites(byte *animData, int32 size, int16 par4);
519 bool loadHandler25GrdSprites(byte *animData, int32 size, int16 par4);
520
521 // Handler 25 shot-origin table from opcode 8 text.
522 bool loadHandler25ShotOriginTable(Common::SeekableReadStream &b, int64 startPos, int64 remaining);
523
524 bool loadLevel2Background(byte *animData, int32 size, byte *renderBitmap);
525
526 void procSKIP(int32 subSize, Common::SeekableReadStream &b) override;
527 void procPreRendering(byte *renderBitmap) override;
528
529 // Laser beams use color 231 as an opaque texel.
530 void drawTexturedLine(byte *dst, int pitch, int width, int height, int x0, int y0, int x1, int y1, NutRenderer *nut, int spriteIdx, int v, bool mask231 = true);
531
532 // Laser rendering.
533 struct LaserTexture {
534 byte *pixels;
535 int16 width;
536 int16 height;
537 };
538 LaserTexture _laserTexture;
539
540 // Per-level palette lookup for laser edge glow.
541 byte _edgeTable[256 * 256];
542 int16 _rebelDetailMode;
543
544 void initEdgeTable(const byte *data);
545
546 void drawEdgeHighlightLine(byte *dst, int pitch, int width, int height,
547 int16 x0, int16 y0, int16 x1, int16 y1,
548 int16 clipLeft, int16 clipTop, int16 clipRight, int16 clipBottom);
549
550 void initLaserTexture(NutRenderer *nut, int spriteIdx);
551 void freeLaserTexture();
552
553 void drawLaserBeam(byte *dst, int pitch, int width, int height,
554 int16 gunX, int16 gunY, int16 targetX, int16 targetY,
555 int16 animFrame, int16 maxFrames,
556 int16 widthScale, int16 heightScale, int16 thickness);
557 void renderNutSprite(byte *dst, int pitch, int width, int height, int x, int y, NutRenderer *nut, int spriteIdx);
558 void renderNutSpriteMirrored(byte *dst, int pitch, int width, int height, int x, int y, NutRenderer *nut, int spriteIdx, bool mirror);
559
560 struct enemy {
561 int id;
562 int type;
563 Common::Rect rect;
564 int velX, velY; // last per-frame motion, feeds the death explosion drift
565 bool active;
566 bool destroyed;
567 int explosionFrame;
568 bool explosionComplete;
569 byte *savedBackground;
570 int savedBgWidth;
571 int savedBgHeight;
572 };
573
574 void initEnemyStruct(int id, int32 x, int32 y, int32 w, int32 h, bool active, bool destroyed, int32 explosionFrame, int type = 0);
575 void enemyUpdate(byte *renderBitmap, Common::SeekableReadStream &b, int16 par2, int16 par3, int16 par4);
576
577 Common::Point getTargetHitHalfExtents(const enemy &target) const;
578 bool isTargetUnderAim(const enemy &target, const Common::Point &aim) const;
579
580 Common::List<enemy> _enemies;
581
582 // Current gameplay handler.
583 int _rebelHandler;
584 int _rebelLevelType;
585 int _rebelStatusBarSprite;
586
587 // Embedded SAN HUD overlays.
588 struct EmbeddedSanFrame {
589 byte *pixels;
590 int width;
591 int height;
592 int renderX;
593 int renderY;
594 bool valid;
595 };
596
597 EmbeddedSanFrame _rebelEmbeddedHud[16];
598 byte _rebelEmbeddedCodec45Palette[0x300];
599 byte _rebelEmbeddedCodec45Lookup[0x8000];
600
601 void loadEmbeddedSan(int userId, byte *animData, int32 size, byte *renderBitmap) override;
602 void renderEmbeddedFrame(byte *renderBitmap, const EmbeddedSanFrame &frame, int userId);
603 void drawHandler25CorridorOverlay(byte *renderBitmap);
604
605 int16 _rebelLinks[512][3];
606 void clearBit(int n);
607 bool isShootingAllowed();
608
609 struct Explosion {
610 int x, y;
611 int width, height;
612 int counter;
613 int scale;
614 int dx, dy; // carries the victim's last motion (flight buffer space)
615 bool active;
616 };
617
618 enum ExplosionFrameAdvance {
619 kExplosionAdvanceAfterDraw,
620 kExplosionAdvanceBeforeDraw
621 };
622
623 Explosion _explosions[5];
624 void spawnExplosion(int x, int y, int objectHalfWidth, int dx = 0, int dy = 0);
625
626 // Collision zones registered by IACT opcode 5.
627 struct CollisionZone {
628 int16 x1, y1;
629 int16 x2, y2;
630 int16 x3, y3;
631 int16 x4, y4;
632 int16 field1;
633 int16 field2;
634 int16 filterValue;
635 int16 subOpcode;
636 bool active;
637 };
638
639 static const int kMaxCollisionZones = 5;
640 CollisionZone _primaryZones[kMaxCollisionZones];
641 CollisionZone _secondaryZones[kMaxCollisionZones];
642 int _primaryZoneCount;
643 int _secondaryZoneCount;
644
645 int16 _corridorLeftX;
646 int16 _corridorTopY;
647 int16 _corridorRightX;
648 int16 _corridorBottomY;
649
650 int16 _hitCooldown;
651
652 void registerCollisionZone(Common::SeekableReadStream &b, int16 subOpcode, int16 par4);
653 void resetCollisionZones();
654 void checkCollisionZones(byte *renderBitmap, int pitch, int width, int height, int32 curFrame);
655
656 // Handler 7 collision and warning cues.
657 void checkHandler7CollisionZones(byte *renderBitmap, int pitch, int width, int height, int32 curFrame);
658 bool isHandler7ShipInsideObstacleZone(const CollisionZone &zone, int margin);
659 void applyHandler7ObstacleHit(const CollisionZone &zone, int zoneIndex);
660 void awardHandler7DodgeScore();
661 void checkHandler7ObstacleZones(uint16 &warningMask);
662 bool applyPlayerDamage(int damage);
663 bool applyHandler7WallDamage(int wallDamage);
664 void resetHandler7HorizontalVelocity(int16 velocity);
665 void checkHandler7TopBoundary(const CollisionZone &zone, int16 vMargin, int wallDamage, uint16 &warningMask);
666 void checkHandler7BottomBoundary(const CollisionZone &zone, int16 vMargin, int wallDamage, uint16 &warningMask);
667 void checkHandler7LeftBoundary(const CollisionZone &zone, int16 hMargin, int wallDamage);
668 void checkHandler7RightBoundary(const CollisionZone &zone, int16 hMargin, int wallDamage);
669 void checkHandler7BoundaryZones(uint16 &warningMask);
670 void renderHandler7WarningCues(byte *renderBitmap, int pitch, int width, int height, int32 curFrame, uint16 warningMask);
671 void updateLevel7Fork(int32 curFrame);
672 void updateLevel15TypeSwitch(int32 curFrame);
673 void updateLevel9WaveReset(int32 curFrame);
674
675 int16 _playerDamage;
676 int16 _playerShield;
677 int16 _playerLives;
678 int32 _playerScore;
679 int32 _playerRating;
680
681 int _viewX;
682 int _viewY;
683 int _hiResPresentationViewX;
684 int _hiResPresentationViewY;
685 int _gameplayPresentationClipBottom;
686
687 // Palette flash and screen shake after damage.
688 void triggerDamageEffect();
689 void initDamageFlash();
690 void updateDamageFlashPalette();
691 void updateDamageEffect(byte *renderBitmap, int pitch, int width, int height);
692 void resetDamageFlash();
693 void restoreDamageFlashPalette();
694
695 int16 _damageFlashCounter;
696 int16 _damageHighFlashCounter;
697 int16 _damageShakeCounter;
698 byte _damageSavedPalette[0x300];
699 byte _damageRestorePalette[0x300];
700 bool _damageRestorePaletteValid;
701
702 // Per-level counters and debug flags.
703 bool _rebelOp6Initialized;
704 int _rebelHitCounter;
705 int _rebelKillCounter;
706 bool _rebelYodaMode;
707 bool _rebelMovieMode;
708 bool _rebelAutoPlay;
709
710 int _rebelWaveState;
711 int _rebelPhaseState;
712 // Kills and misses banked across the phases of a level 2 style attempt.
713 int _totalKills;
714 int _totalMisses;
715
716 int _rebelAutopilot;
717 int _rebelDamageLevel;
718 int _rebelFlightDir;
719 int _rebelControlMode;
720 int _rebelInputThrottle;
721
722 int _rebelViewOffsetX;
723 int _rebelViewOffsetY;
724 int _rebelViewOffset2X;
725 int _rebelViewOffset2Y;
726 int _rebelViewMode1;
727 int _rebelViewMode2;
728
729 // Turret (0x26) gauge groups, addressed by value 100-109 or bitmask > 0x3ff (bit k-1 -> slot k); surfaces show while nonzero, then blink out.
730 short _rebelValueCounters[10];
731 short _rebelGaugeBlink[10];
732 int _rebelLastCounter;
733
734 // Turret dodge-fail view-shake impulses, ring-filtered into the scroll offset.
735 int16 _turretShakeRingX[15];
736 int16 _turretShakeRingY[15];
737
738 bool _rebelShieldGateActive;
739 bool _rebelShieldDestroyed;
740 bool _rebelReactorMode;
741 bool _rebelGaugeArmed;
742 int _rebelLastArmedSlot;
743 void resetGaugeCounters();
744 void resetShieldGauge();
745 void decrementGaugeGroup(int slot, int targetId);
746
747 // Handler-specific shot state.
748 struct TurretShot {
749 int16 counter;
750 int16 targetX;
751 int16 targetY;
752 int16 seqNum;
753 int16 gunX;
754 int16 gunY;
755 };
756 TurretShot _turretShots[2];
757 int16 _turretShotSeqCounter;
758
759 struct VehicleShot {
760 int16 counter;
761 int16 targetX;
762 int16 targetY;
763 };
764 VehicleShot _vehicleShots[2];
765
766 struct VehicleShotImpact {
767 int16 counter;
768 int16 x;
769 int16 y;
770 int16 spriteIndex;
771 };
772 VehicleShotImpact _vehicleShotImpacts[7];
773 int16 _vehicleShotImpactIndex;
774
775 struct SpaceShot {
776 int16 counter;
777 int16 targetX;
778 int16 targetY;
779 int16 leftGunX;
780 int16 leftGunY;
781 int16 rightGunX;
782 int16 rightGunY;
783 int16 variant;
784 };
785 SpaceShot _spaceShots[2];
786 int16 _spaceShotDirection;
787 int16 _flyLeftGunX[35];
788 int16 _flyLeftGunY[35];
789 int16 _flyRightGunX[35];
790 int16 _flyRightGunY[35];
791 bool _flyLeftGunTableLoaded;
792 bool _flyRightGunTableLoaded;
793
794 void spawnTurretShot(int x, int y);
795 void spawnVehicleShot(int x, int y);
796 void spawnSpaceShot(int x, int y);
797 void spawnHandler25Shot(int x, int y);
798 void spawnShot(int x, int y);
799
800 void renderExplosionFrame(byte *renderBitmap, int pitch, int width, int height,
801 Explosion &explosion, int screenX, int screenY, ExplosionFrameAdvance advance,
802 bool resolutionDependentScale);
803 void renderTurretExplosions(byte *renderBitmap, int pitch, int width, int height);
804 void renderVehicleExplosions(byte *renderBitmap, int pitch, int width, int height);
805 void renderSpaceExplosions(byte *renderBitmap, int pitch, int width, int height);
806 void renderHandler25Explosions(byte *renderBitmap, int pitch, int width, int height);
807
808 void renderTurretLaserShots(byte *renderBitmap, int pitch, int width, int height);
809 void renderVehicleLaserShots(byte *renderBitmap, int pitch, int width, int height);
810 void renderSpaceLaserShots(byte *renderBitmap, int pitch, int width, int height);
811 void renderHandler25LaserShots(byte *renderBitmap, int pitch, int width, int height);
812
813 int16 getShotMaxDuration();
814
815 // Handler 8 ship and background state.
816 NutRenderer *_shipSprite;
817 NutRenderer *_shipSprite2;
818 NutRenderer *_shipOverlay1;
819 NutRenderer *_shipOverlay2;
820
821 byte *_level2Background;
822 bool _level2BackgroundLoaded;
823
824 int16 _shipPosX;
825 int16 _shipPosY;
826 int16 _shipTargetX;
827 int16 _shipTargetY;
828 int16 _shipLevelMode;
829 char _handler8HudGlyph;
830 int16 _handler8HudMessageTimer;
831 int16 _handler8HudMessageIndex;
832
833 // Handler 8 movement range transitions between cover and shooting states.
834 int16 _movementRangeLimit;
835
836 // Handler 7 control mode selects shooting and collision behavior.
837 int16 _flyControlMode;
838
839 bool _shipFiring;
840 uint32 _prevMouseButtons;
841
842 // Rapid-fire cadence counter, re-anchored on each press.
843 int16 _rapidFireCounter;
844
845 int16 _shipDirectionIndex;
846 int16 _shipDirectionH;
847 int16 _shipDirectionV;
848
849 // Handler 7 FLY ship state.
850 NutRenderer *_flyShipSprite;
851 NutRenderer *_flyLaserSprite;
852 NutRenderer *_flyTargetSprite;
853 NutRenderer *_flyHiResSprite;
854 int16 _flyEffectAnimCounter;
855 int16 _flyOverlayRepeatCount;
856
857 int16 _flyShipScreenX;
858 int16 _flyShipScreenY;
859
860 // Level 7 (handler-7 flight) corridor fork: 07PLAY -> 07PLAYB right branch.
861 bool _level7ForkActive; // armed only while 07PLAY is playing
862 bool _level7TookRightFork; // sampled at frame 0x638: ship on the right half
863
864 int16 _smoothedVelocity;
865 int16 _verticalInput;
866 int16 _velocityHistory[25];
867 int16 _windHistoryX[15];
868 int16 _windHistoryY[15];
869 int16 _windParamX;
870 int16 _windParamY;
871
872 int16 _perspectiveX;
873 int16 _perspectiveY;
874 int16 _viewShift;
875 bool _facingRight;
876
877 // Handler 25 GRD ship state.
878 NutRenderer *_grd001Sprite;
879 NutRenderer *_grd002Sprite;
880 NutRenderer *_grd005Sprite;
881
882 int16 _grdShotOriginX[30];
883 int16 _grdShotOriginY[30];
884 bool _grdShotOriginTableLoaded;
885
886 int16 _grdSpriteMode;
887
888 void renderHandler25ShipPre(byte *renderBitmap, int pitch, int width, int height);
889 void renderHandler25Ship(byte *renderBitmap, int pitch, int width, int height);
890
891 // Handler 0x26 turret HUD overlays.
892 NutRenderer *_hudOverlayNut;
893 NutRenderer *_hudOverlay2Nut;
894
895 int _difficulty;
896
897 // Per-level difficulty parameters.
898 typedef Rebel2DifficultyParams LevelDifficultyParams;
899
900 static const LevelDifficultyParams kDifficultyTable[6][17];
901
902 int getDifficultyRow() const;
903 LevelDifficultyParams getDifficultyParams() const;
904 int16 getWaveBudgetBase(int phase) const;
905 bool _level15SecondHalf;
906
907 void addScore(int points);
908 void renderScoreHUD(byte *renderBitmap, int pitch, int width, int height, int statusBarY);
909
910 void showPauseOverlay();
911 void hidePauseOverlay();
912
913 int _targetLockTimer;
914
915 // Audio.
916 RebelAudio _audio;
917
918 void initAudio(int sampleRate);
919 void terminateAudio();
920 void resetVideoAudio();
921 void processAudioFrame(int16 feedSize);
922 void queueAudioData(int trackIdx, uint8 *data, int32 size, int volume, int pan);
923
924 // One-shot SFX.
925 static const int kRA2NumSfx = 8;
926
927 byte *_sfxData[kRA2NumSfx];
928 uint32 _sfxSize[kRA2NumSfx];
929 Audio::SoundHandle _sfxHandles[kRA2NumSfx];
930
931 void loadSfx();
932 void freeSfx();
933 void playSfx(int slot, int volume, int pan);
934
935 // Embedded sound effects.
936 static const int kRA2NumAuxSfx = 4;
937 static const int kRA2AuxBufSize = 30000;
938
939 byte *_auxSfxData[kRA2NumAuxSfx];
940 uint32 _auxSfxSize[kRA2NumAuxSfx];
941 Audio::SoundHandle _auxSfxHandles[kRA2NumAuxSfx];
942
943 void loadAuxSfx(int buffer, const byte *data, uint32 size);
944 void playAuxSfx(int buffer, int volume, int pan);
945
946};
947
948} // namespace Scumm
949
950#endif
Definition: mixer.h:49
Definition: error.h:81
Definition: events.h:337
Definition: list.h:44
Definition: stream.h:745
Definition: str.h:59
Definition: system.h:39
Definition: actor.h:30
Definition: events.h:218
Definition: rect.h:144
Definition: rect.h:536
Definition: surface.h:67