ScummVM API documentation
lastexpress.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 LASTEXPRESS_LASTEXPRESS_H
23#define LASTEXPRESS_LASTEXPRESS_H
24
25#include "lastexpress/debug.h"
26#include "lastexpress/game/beetle.h"
27#include "lastexpress/game/vcr.h"
28#include "lastexpress/game/savegame.h"
29#include "lastexpress/sound/slot.h"
30#include "lastexpress/sound/sound.h"
31#include "lastexpress/sound/subtitle.h"
32#include "lastexpress/game/logic.h"
33#include "lastexpress/data/sprites.h"
34#include "lastexpress/game/nis.h"
35#include "lastexpress/game/otis.h"
36#include "lastexpress/game/events.h"
37#include "lastexpress/fight/fight.h"
38#include "lastexpress/menu/menu.h"
39#include "lastexpress/graphics.h"
40#include "lastexpress/memory.h"
41
42#include "common/random.h"
43#include "common/file.h"
44
45#include "engines/engine.h"
46
47#include "graphics/pixelformat.h"
48
50
73namespace LastExpress {
74
75class ArchiveManager;
76class GoldArchiveManager;
77class CBeetle;
78class CFight;
79class Clock;
80class GraphicsManager;
81class LogicManager;
82class MemoryManager;
83class Menu;
84class MessageManager;
85class NISManager;
86class OtisManager;
87class ResourceManager;
88class SaveManager;
89class Slot;
90class SoundManager;
91class SpriteManager;
92class SubtitleManager;
93class VCR;
94
95struct Extent;
96
97enum {
98 GF_COMPRESSED = 1 << 0
99};
100
101typedef struct Item {
102 uint8 mnum;
103 uint16 closeUp;
104 int8 useable;
105 int8 haveIt;
106 int8 inPocket;
107 int8 floating;
108
109 Item() {
110 clear();
111 }
112
113 void clear() {
114 mnum = 0;
115 closeUp = 0;
116 useable = 0;
117 haveIt = 0;
118 inPocket = 0;
119 floating = 0;
120 }
121} Item;
122
123typedef struct Door {
124 int8 who;
125 int8 status;
126 uint8 windowCursor;
127 uint8 handleCursor;
128 int8 model;
129
130 Door() {
131 clear();
132 }
133
134 void clear() {
135 who = 0;
136 status = 0;
137 windowCursor = 0;
138 handleCursor = 0;
139 model = 0;
140 }
141} Door;
142
143typedef struct Position {
144 uint16 position;
145 uint16 location;
146 uint16 car;
147
148 Position() {
149 clear();
150 }
151
152 void clear() {
153 position = 0;
154 location = 0;
155 car = 0;
156 }
157} Position;
158
159typedef struct Sprite {
160 byte *compData;
161 byte *eraseMask;
162 uint16 *colorPalette;
163 Extent rect;
164 uint16 hotspotX1;
165 uint16 hotspotX2;
166 uint16 hotspotY1;
167 uint16 hotspotY2;
168 byte compBits;
169 byte compType;
170 byte copyScreenAndRedrawFlag;
171 byte spritesUnk3;
172 byte ticksToWaitUntilCycleRestart;
173 byte soundDelay;
174 byte soundAction;
175 byte flags;
176 byte position;
177 byte spritesUnk9;
178 byte spritesUnk10;
179 byte spritesUnk11;
180 int spritesUnk8;
181 uint16 visibilityDist;
182 uint16 hotspotPriority;
183 Sprite *nextSprite;
184
185 Sprite() {
186 compData = nullptr;
187 eraseMask = nullptr;
188 colorPalette = nullptr;
189 hotspotX1 = 0;
190 hotspotX2 = 0;
191 hotspotY1 = 0;
192 hotspotY2 = 0;
193 compBits = 0;
194 compType = 0;
195 copyScreenAndRedrawFlag = 0;
196 spritesUnk3 = 0;
197 ticksToWaitUntilCycleRestart = 0;
198 soundDelay = 0;
199 soundAction = 0;
200 flags = 0;
201 position = 0;
202 spritesUnk9 = 0;
203 spritesUnk10 = 0;
204 spritesUnk11 = 0;
205 spritesUnk8 = 0;
206 visibilityDist = 0;
207 hotspotPriority = 0;
208 nextSprite = nullptr;
209 }
210} Sprite;
211
212typedef struct Seq {
213 int numFrames;
214 Sprite *sprites;
215 Sprite spriteArrayStart;
216 byte gap[18];
217 byte *rawSeqData;
218
219 Seq() {
220 numFrames = 0;
221 sprites = nullptr;
222 memset(gap, 0, sizeof(gap));
223 rawSeqData = nullptr;
224 }
225
226 ~Seq() {
227 delete[] sprites;
228 sprites = nullptr;
229 }
230} Seq;
231
232typedef struct CharacterCallParams {
233 int parameters[32];
234
236 clear();
237 }
238
239 void clear() {
240 for (int i = 0; i < 32; i++) {
241 parameters[i] = 0;
242 }
243 }
245
246typedef struct Character {
247 CharacterCallParams callParams[9];
248 uint8 callbacks[16];
249 uint8 currentCall;
250 Position characterPosition;
251 uint8 walkCounter;
252 int8 attachedConductor;
253 uint8 inventoryItem;
254 int8 direction;
255 int16 waitedTicksUntilCycleRestart;
256 int16 currentFrameSeq1;
257 int16 currentFrameSeq2;
258 int16 elapsedFrames;
259 int16 walkStepSize;
260 int8 clothes;
261 int8 position2;
262 int8 car2;
263 int8 doProcessEntity;
264 int8 needsPosFudge;
265 int8 needsSecondaryPosFudge;
266 int8 directionSwitch;
267 char sequenceName[13];
268 char sequenceName2[13];
269 char sequenceNamePrefix[7];
270 char sequenceNameCopy[13];
271 Sprite *frame1;
272 Sprite *frame2;
273 Seq *sequence1;
274 Seq *sequence2;
275 Seq *sequence3;
276
277 Character() {
278 reset();
279 }
280
281 void reset() {
282 memset(callbacks, 0, sizeof(callbacks));
283 currentCall = 0;
284 walkCounter = 0;
285 attachedConductor = 0;
286 inventoryItem = 0;
287 direction = 0;
288 waitedTicksUntilCycleRestart = 0;
289 currentFrameSeq1 = 0;
290 currentFrameSeq2 = 0;
291 elapsedFrames = 0;
292 walkStepSize = 0;
293 clothes = 0;
294 position2 = 0;
295 car2 = 0;
296 doProcessEntity = 0;
297 needsPosFudge = 0;
298 needsSecondaryPosFudge = 0;
299 directionSwitch = 0;
300
301 memset(sequenceName, 0, sizeof(sequenceName));
302 memset(sequenceName2, 0, sizeof(sequenceName2));
303 memset(sequenceNamePrefix, 0, sizeof(sequenceNamePrefix));
304 memset(sequenceNameCopy, 0, sizeof(sequenceNameCopy));
305
306 frame1 = nullptr;
307 frame2 = nullptr;
308 sequence1 = nullptr;
309 sequence2 = nullptr;
310 sequence3 = nullptr;
311 }
312
313} Character;
314
315typedef struct Characters {
316 Character characters[40];
317} Characters;
318
319typedef struct Line7 {
320 int slope;
321 int intercept;
322 char lineType;
323 Line7 *next;
324
325 Line7() {
326 slope = 0;
327 intercept = 0;
328 lineType = 0;
329 next = nullptr;
330 }
331
332 ~Line7() {
333 if (next) {
334 delete next;
335 next = nullptr;
336 }
337 }
338
339} Line7;
340
341typedef struct Link {
342 uint16 left;
343 uint16 right;
344 uint16 top;
345 uint16 bottom;
346 Line7 *lineList;
347 uint16 scene;
348 uint8 location;
349 uint8 action;
350 uint8 param1;
351 uint8 param2;
352 uint8 param3;
353 uint8 cursor;
354 Link *next;
355
356 Link() {
357 left = 0;
358 right = 0;
359 top = 0;
360 bottom = 0;
361 lineList = nullptr;
362 scene = 0;
363 location = 0;
364 action = 0;
365 param1 = 0;
366 param2 = 0;
367 param3 = 0;
368 cursor = 0;
369 next = nullptr;
370 }
371
372 ~Link() {
373 if (lineList) {
374 delete lineList;
375 lineList = nullptr;
376 }
377
378 if (next) {
379 delete next;
380 next = nullptr;
381 }
382 }
383
384 void copyFrom(Link *otherLink) {
385 left = otherLink->left;
386 right = otherLink->right;
387 top = otherLink->top;
388 bottom = otherLink->bottom;
389 lineList = nullptr;
390 scene = otherLink->scene;
391 location = otherLink->location;
392 action = otherLink->action;
393 param1 = otherLink->param1;
394 param2 = otherLink->param2;
395 param3 = otherLink->param3;
396 cursor = otherLink->cursor;
397 next = nullptr;
398 }
399} Link;
400
401typedef struct Node {
402 char sceneFilename[9];
403 Position nodePosition;
404 uint8 cathDir;
405 uint8 property;
406 uint8 parameter1;
407 uint8 parameter2;
408 uint8 parameter3;
409 Link *link;
410
411 Node() {
412 memset(sceneFilename, 0, sizeof(sceneFilename));
413 cathDir = 0;
414 property = 0;
415 parameter1 = 0;
416 parameter2 = 0;
417 parameter3 = 0;
418 link = nullptr;
419 }
420
421 ~Node() {
422 if (link) {
423 delete link;
424 link = nullptr;
425 }
426 }
427} Node;
428
429#include "common/pack-start.h"
430typedef struct TGAHeader {
431 uint8 idLength;
432 uint8 colorMapType;
433 uint8 imageType;
434 uint16 colorMapFirstEntryIndex;
435 uint16 colorMapLength;
436 uint8 colorMapEntrySize;
437 uint16 xOrigin;
438 uint16 yOrigin;
439 uint16 width;
440 uint16 height;
441 uint8 bitsPerPixel;
442 uint8 imageDescriptor;
443 byte *rawDataPtr; // Not in the original, but we need it to avoid pointer fix-ups...
444
445 TGAHeader() {
446 idLength = 0;
447 colorMapType = 0;
448 imageType = 0;
449 colorMapFirstEntryIndex = 0;
450 colorMapLength = 0;
451 colorMapEntrySize = 0;
452 xOrigin = 0;
453 yOrigin = 0;
454 width = 0;
455 height = 0;
456 bitsPerPixel = 0;
457 imageDescriptor = 0;
458 rawDataPtr = nullptr;
459 }
460} TGAHeader;
461#include "common/pack-end.h"
462
463typedef struct FontData {
464 uint16 palette[16];
465 uint8 charMap[256];
466 uint8 charKerning[256];
467 byte *fontData;
468
469 FontData() {
470 memset(palette, 0, sizeof(palette));
471 memset(charMap, 0, sizeof(charMap));
472 memset(charKerning, 0, sizeof(charKerning));
473 fontData = nullptr;
474 }
475
476 ~FontData() {
477 memset(palette, 0, sizeof(palette));
478 memset(charMap, 0, sizeof(charMap));
479 memset(charKerning, 0, sizeof(charKerning));
480
481 if (fontData) {
482 free(fontData);
483 fontData = nullptr;
484 }
485 }
486} FontData;
487
488typedef struct NisSprite {
489 byte *compData;
490 byte *eraseMask;
491 uint16 *colorPalette;
492 Extent rect;
493 uint16 gammaPalette[128];
494 byte compBits;
495
496 NisSprite() {
497 compData = nullptr;
498 eraseMask = nullptr;
499 colorPalette = nullptr;
500 memset(gammaPalette, 0, sizeof(gammaPalette));
501 compBits = 0;
502 }
503} NisSprite;
504
505typedef struct NisEvents {
506 int16 eventType;
507 int16 eventTime;
508 int32 eventSize;
509
510 NisEvents() {
511 eventType = 0;
512 eventTime = 0;
513 eventSize = 0;
514 }
515} NisEvents;
516
517#define MEM_PAGE_SIZE 0x800
518
519#define DEMO_TIMEOUT 2700
520
521typedef uint16 PixMap;
522
523class LastExpressEngine : public Engine {
524 // AARGH! Remove!
525 friend class VCR;
526 friend class SubtitleManager;
527
528protected:
529 // Engine APIs
530 Common::Error run() override;
531 bool hasFeature(EngineFeature f) const override;
532
533public:
535 ~LastExpressEngine() override;
536
537 // Misc
538 Common::RandomSource& getRandom() {return _random; }
539
540 // Managers
541 ArchiveManager *getArchiveManager() const { return _archiveMan; }
542 GraphicsManager *getGraphicsManager() const { return _graphicsMan; }
543 SubtitleManager *getSubtitleManager() const { return _subtitleMan; }
544
545 MemoryManager *getMemoryManager() const { return _memMan; }
546 MessageManager *getMessageManager() const { return _msgMan; }
547 NISManager *getNISManager() const { return _nisMan; }
548 SoundManager *getSoundManager() const { return _soundMan; }
549 LogicManager *getLogicManager() const { return _logicMan; }
550 OtisManager *getOtisManager() const { return _otisMan; }
551 SpriteManager *getSpriteManager() const { return _spriteMan; }
552 SaveManager *getSaveManager() const { return _saveMan; }
553
554 VCR *getVCR() const { return _vcr; }
555 Menu *getMenu() const { return _menu; }
556 Clock *getClock() const { return _clock; }
557
558 // Event handling
559 bool handleEvents();
560
561 bool isDemo() const;
562 bool isGoldEdition() const;
563 bool isCompressed() const;
564
565 Common::String getTargetName() const;
566
567 // NEW STUFF
568 static void soundTimerHandler(void *refCon);
569
570 int32 _soundFrameCounter = 0;
571
572 Common::Mutex *_soundMutex;
573 const char *_savegameFilename = nullptr;
574 const char *_savegameTempNames[7] = {
575 "blue.tmp",
576 "red.tmp",
577 "green.tmp",
578 "purple.tmp",
579 "teal.tmp",
580 "gold.tmp",
581 "temp.tmp"
582 };
583
584 const char *_savegameNames[6] = {
585 "blue.egg",
586 "red.egg",
587 "green.egg",
588 "purple.egg",
589 "teal.egg",
590 "gold.egg"
591 };
592
593 CVCRFile *_savegame = nullptr;
594
595 int32 _currentGameFileColorId = -1;
596 int32 _gracePeriodTimer = 0;
597 bool _eventTickInternal = false;
598
599 bool _doShowCredits = false;
600 int32 _currentSavePoint = 0;
601 int32 _lastSavePointIdInFile = 0;
602 int32 _gameTimeOfLastSavePointInFile = 0;
603 int32 _gracePeriodIndex = 0;
604 int32 _fightSkipCounter = 0;
605
606 bool _navigationEngineIsRunning = false;
607 bool _stopUpdatingCharacters = false;
608 bool _charactersUpdateRecursionFlag = false;
609 bool _mouseHasLeftClicked = false;
610 bool _mouseHasRightClicked = false;
611 bool _fastWalkJustDeactivated = false;
612
613 int32 _cursorX = 320;
614 int32 _cursorY = 240;
615 int32 _cursorXOffscreenOffset = 0;
616 int32 _cursorYOffscreenOffset = 0;
617 int _cursorType = 0;
618
619 bool _systemEventLeftMouseDown = false;
620 bool _systemEventRightMouseDown = false;
621 Common::Point _systemEventLastMouseCoords;
622
623 bool _pendingExitEvent = false;
624 bool _exitFromMenuButton = false;
625 int32 _lastForcedScreenUpdateTicks = 0; // Not in the original
626
627 Seq *_doorSeqs[8] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr };
628 Seq *_clockHandsSeqs[2] = { nullptr, nullptr };
629 int32 _clockHandsValues[2] = { 0, 0 };
630
631 int32 _fudgePosition[41] = {
632 0, 851, 1430, 2110, 0, 2410, 2980, 3450,
633 3760, 4100, 4680, 5140, 5440, 5810, 6410, 6850,
634 7160, 7510, 8514, 0, 0, 0, 2086, 2690,
635 0, 3110, 3390, 3890, 4460, 4770, 5090, 5610,
636 6160, 6460, 6800, 7320, 7870, 8160, 8500, 9020,
637 9269
638 };
639
640 // DYNAMIC ALLOC
641 byte *_globalMemoryPool = nullptr;
642 byte *_soundMemoryPool = nullptr;
643 byte *_cursorsMemoryPool = nullptr;
644 Characters *_characters = nullptr;
645
646 SVCRSavePointHeader *_savePointHeaders = nullptr;
647
648 // GENERAL
649 void startUp();
650 void shutDown();
651
652 void waitForTimer(int millis);
653 void initGameData();
654 void startNewGame();
655 void engineEventHandler(Event *event);
656
657 int32 getSoundFrameCounter();
658
659 bool getEventTickInternal();
660 void setEventTickInternal(bool flag);
661
662 void mouseSetLeftClicked(bool hasClicked);
663 void mouseSetRightClicked(bool hasClicked);
664 bool mouseHasLeftClicked();
665 bool mouseHasRightClicked();
666
667 // BEETLE
668 CBeetle *_beetle = nullptr;
669 void doBeetle();
670 void endBeetle();
671 void positionSprite(Sprite *sprite, Common::Point coord);
672
673 // CREDITS
674 void doCredits();
675 void abortCredits();
676 void creditsMouse(Event *event);
677 void creditsTimer(Event *event);
678 int32 readTGAIntoMemory(const char *filename, TGAHeader *tgaHeader);
679 void constructPalette(TGAHeader *tgaHeader, uint16 *palette);
680
681 // DEMO CREDITS
682 bool demoEnding(bool wonGame);
683 void demoEndingMouse(Event *event);
684 void demoEndingTimer(Event *event);
685
686 // EVENT HANDLERS
687 void engineEventHandlerWrapper(Event *event);
688
689 void nodeStepMouseWrapper(Event *event);
690 void nodeStepTimerWrapper(Event *event);
691
692 void eggMouseWrapper(Event *event);
693 void eggTimerWrapper(Event *event);
694
695 void nisMouseWrapper(Event *event);
696 void nisTimerWrapper(Event *event);
697
698 void creditsMouseWrapper(Event *event);
699 void creditsTimerWrapper(Event *event);
700
701 void demoEndingMouseWrapper(Event *event);
702 void demoEndingTimerWrapper(Event *event);
703
704 void fightMouseWrapper(Event *event);
705 void fightTimerWrapper(Event *event);
706
707 void emptyHandler(Event *event);
708
709 int _savedFrameCounter = 0;
710 int32 _savedFrameInterval = 0;
711 int _doCredits = 0;
712
713 void (LastExpressEngine::*_savedTimerEventHandle)(Event *) = nullptr;
714 void (LastExpressEngine::*_savedMouseEventHandle)(Event *) = nullptr;
715
716 // FIGHT
717 int doFight(int fightId);
718 void abortFight();
719
720 CFight *_fight = nullptr;
721
722 // DEBUGGER
723 void showEngineInfo();
724
725 bool _lockGracePeriod = false;
726
727private:
728 const ADGameDescription *_gameDescription;
729 Graphics::PixelFormat _pixelFormat;
730
731 // Misc
732 Debugger *_debugger;
733 Common::RandomSource _random;
734
735 // Game
736 Menu *_menu = nullptr;
737 Clock *_clock = nullptr;
738 VCR *_vcr = nullptr;
739
740 // Managers
741 ArchiveManager *_archiveMan = nullptr;
742 GraphicsManager *_graphicsMan = nullptr;
743 SoundManager *_soundMan = nullptr;
744 LogicManager *_logicMan = nullptr;
745 OtisManager *_otisMan = nullptr;
746 SpriteManager *_spriteMan = nullptr;
747 MemoryManager *_memMan = nullptr;
748 MessageManager *_msgMan = nullptr;
749 NISManager *_nisMan = nullptr;
750 SaveManager *_saveMan = nullptr;
751 SubtitleManager *_subtitleMan = nullptr;
752};
753
754} // End of namespace LastExpress
755
756#endif // LASTEXPRESS_LASTEXPRESS_H
Definition: error.h:81
Definition: mutex.h:67
Definition: random.h:44
Definition: str.h:59
Definition: engine.h:149
EngineFeature
Definition: engine.h:282
Definition: graphics.h:38
Definition: archive.h:77
Definition: lastexpress.h:523
Common::Error run() override
bool hasFeature(EngineFeature f) const override
Definition: subtitle.h:57
Definition: vcr.h:36
Definition: system.h:166
Definition: archive.h:29
Definition: advancedDetector.h:164
Definition: rect.h:144
Definition: pixelformat.h:138
Definition: lastexpress.h:232
Definition: lastexpress.h:246
Definition: lastexpress.h:315
Definition: lastexpress.h:123
Definition: sprites.h:31
Definition: lastexpress.h:463
Definition: lastexpress.h:101
Definition: lastexpress.h:319
Definition: lastexpress.h:505
Definition: lastexpress.h:488
Definition: lastexpress.h:401
Definition: lastexpress.h:143
Definition: lastexpress.h:212
Definition: lastexpress.h:159
Definition: lastexpress.h:430