ScummVM API documentation
colony.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  * Based on the original sources
21  * https://github.com/Croquetx/thecolony
22  * Copyright (C) 1988, David A. Smith
23  *
24  * Distributed under Apache Version 2.0 License
25  *
26  */
27 
28 #ifndef COLONY_H
29 #define COLONY_H
30 
31 #include "common/array.h"
32 #include "common/random.h"
33 #include "common/rect.h"
34 #include "common/rendermode.h"
35 #include "engines/advancedDetector.h"
36 #include "engines/engine.h"
37 #include "graphics/pixelformat.h"
38 #include "graphics/surface.h"
39 
40 namespace Common {
41 class MacResManager;
42 class SeekableReadStreamEndian;
43 }
44 
45 namespace Graphics {
46 class Cursor;
47 class Font;
48 class FrameLimiter;
49 class MacMenu;
50 class MacWindowManager;
51 class ManagedSurface;
52 }
53 
54 namespace Colony {
55 
56 class Renderer;
57 class Sound;
58 
59 // Engine-wide color packing. The OpenGL renderer's useColor() treats values
60 // with the high byte == 0xFF as direct ARGB (R=bits 16-23, G=8-15, B=0-7) and
61 // values with high byte 0 as palette indices. The PixelFormat below matches
62 // that direct-ARGB layout exactly so we can build colors via ARGBToColor.
63 inline const Graphics::PixelFormat &renderColorFormat() {
64  static const Graphics::PixelFormat fmt(4, 8, 8, 8, 8, 16, 8, 0, 24);
65  return fmt;
66 }
67 
68 inline uint32 packRGB(byte r, byte g, byte b) {
69  return renderColorFormat().ARGBToColor(255, r, g, b);
70 }
71 
72 // Mac native QuickDraw stores RGB as 16-bit-per-channel; we collapse to 8 bits.
73 inline uint32 packMacColor(const uint16 rgb[3]) {
74  return packRGB((byte)(rgb[0] >> 8), (byte)(rgb[1] >> 8), (byte)(rgb[2] >> 8));
75 }
76 
77 enum ColonyAction {
78  kActionNone,
79  kActionMoveForward,
80  kActionMoveBackward,
81  kActionStrafeLeft,
82  kActionStrafeRight,
83  kActionRotateLeft,
84  kActionRotateRight,
85  kActionLookLeft,
86  kActionLookRight,
87  kActionLookBehind,
88  kActionFaceForward,
89  kActionToggleMouselook,
90  kActionToggleDashboard,
91  kActionToggleWireframe,
92  kActionToggleFullscreen,
93  kActionEscape,
94  kActionFire
95 };
96 
97 enum GameMode {
98  kModeColony = 2,
99  kModeBattle = 1
100 };
101 
102 enum WallFeatureType {
103  kWallFeatureNone = 0,
104  kWallFeatureDoor = 2,
105  kWallFeatureWindow = 3,
106  kWallFeatureShelves = 4,
107  kWallFeatureUpStairs = 5,
108  kWallFeatureDnStairs = 6,
109  kWallFeatureChar = 7,
110  kWallFeatureGlyph = 8,
111  kWallFeatureElevator = 9,
112  kWallFeatureTunnel = 10,
113  kWallFeatureAirlock = 11,
114  kWallFeatureColor = 12
115 };
116 
117 enum MapDirection {
118  kDirNorth = 0,
119  kDirEast = 1,
120  kDirWest = 2,
121  kDirSouth = 3,
122  kDirCenter = 4
123 };
124 
125 enum RobotType {
126  kRobEye = 1,
127  kRobPyramid = 2,
128  kRobCube = 3,
129  kRobUPyramid = 4,
130  kRobFEye = 5,
131  kRobFPyramid = 6,
132  kRobFCube = 7,
133  kRobFUPyramid = 8,
134  kRobSEye = 9,
135  kRobSPyramid = 10,
136  kRobSCube = 11,
137  kRobSUPyramid = 12,
138  kRobMEye = 13,
139  kRobMPyramid = 14,
140  kRobMCube = 15,
141  kRobMUPyramid = 16,
142  kRobQueen = 17,
143  kRobDrone = 18,
144  kRobSoldier = 19,
145  kRobSnoop = 20
146 };
147 
148 // 3D bounding radius (max XY extent from center) for each robot type.
149 // Used by clampToWalls to keep robot geometry from intersecting wall polygons.
150 // The original 2D wireframe renderer drew walls over robots (painter's algorithm);
151 // in OpenGL 3D both exist as real geometry, so padding is needed.
152 // Capped at 112 so the robot keeps at least 32 units of movement freedom
153 // within a 256-unit cell (256 - 2*112 = 32).
154 inline int robotWallPad(int robotType) {
155  static const int kMaxPad = 112;
156  switch (robotType) {
157  case kRobEye: return 66;
158  case kRobPyramid:
159  case kRobUPyramid: return 85;
160  case kRobCube: return 100;
161  case kRobQueen: return kMaxPad; // actual 120
162  case kRobDrone:
163  case kRobSoldier: return kMaxPad; // actual 130
164  case kRobSnoop: return kMaxPad; // actual 180
165  default: return 40; // eggs and other small types
166  }
167 }
168 
169 enum ObjectType {
170  kObjDesk = 21,
171  kObjPlant = 22,
172  kObjCChair = 23,
173  kObjBed = 24,
174  kObjTable = 25,
175  kObjCouch = 26,
176  kObjChair = 27,
177  kObjTV = 28,
178  kObjScreen = 29,
179  kObjConsole = 30,
180  kObjPowerSuit = 31,
181  kObjForkLift = 32,
182  kObjCryo = 33,
183  kObjBox1 = 34,
184  kObjBox2 = 35,
185  kObjTeleport = 36,
186  kObjDrawer = 37,
187  kObjTub = 38,
188  kObjSink = 39,
189  kObjToilet = 40,
190  kObjBench = 41,
191  kObjPToilet = 43,
192  kObjCBench = 44,
193  kObjProjector = 45,
194  kObjReactor = 46,
195  kObjFWall = 48,
196  kObjCWall = 49,
197  kObjBBed = 42
198 };
199 
200 enum ObjColor {
201  kColorClear = 0,
202  kColorBlack = 1,
203  kColorDkGray = 9,
204  kColorLtGreen = 11,
205  kColorBath = 17,
206  kColorWater = 18,
207  kColorSilver = 19,
208  kColorReactor = 20,
209  kColorBlanket = 21,
210  kColorSheet = 22,
211  kColorBed = 23,
212  kColorBox = 24,
213  kColorBench = 25,
214  kColorChair = 26,
215  kColorChairBase = 27,
216  kColorCouch = 28,
217  kColorConsole = 29,
218  kColorTV = 30,
219  kColorTVScreen = 31,
220  kColorDrawer = 32,
221  kColorDesk = 37,
222  kColorDeskTop = 38,
223  kColorDeskChair = 39,
224  kColorMac = 40,
225  kColorMacScreen = 41,
226  kColorCryo = 33,
227  kColorCryoGlass = 34,
228  kColorCryoBase = 35,
229  kColorForklift = 49,
230  kColorTread1 = 50,
231  kColorTread2 = 51,
232  kColorPot = 52,
233  kColorPlant = 53,
234  kColorPower = 54,
235  kColorPBase = 55,
236  kColorPSource = 56,
237  kColorTable = 61,
238  kColorTableBase = 62,
239  kColorPStand = 63,
240  kColorPLens = 64,
241  kColorProjector = 65,
242  kColorTele = 66,
243  kColorTeleDoor = 67,
244  kColorWall = 77,
245  kColorRainbow1 = 80,
246  kColorRainbow2 = 81,
247  kColorRainbow3 = 82,
248  kColorRainbow4 = 83,
249  // Robot colors
250  kColorCube = 36,
251  kColorDrone = 42,
252  kColorClaw1 = 43,
253  kColorClaw2 = 44,
254  kColorEyes = 45,
255  kColorEye = 46,
256  kColorIris = 47,
257  kColorPupil = 48,
258  kColorPyramid = 57,
259  kColorQueen = 58,
260  kColorTopSnoop = 59,
261  kColorBottomSnoop = 60,
262  kColorUPyramid = 68,
263  kColorShadow = 74,
264  // Animated reactor/power suit colors (Mac: c_hcore1..c_hcore4, c_ccore, c_color0..c_color3)
265  kColorHCore1 = 100,
266  kColorHCore2 = 101,
267  kColorHCore3 = 102,
268  kColorHCore4 = 103,
269  kColorCCore = 104,
270  // Semantic robot colors that need platform- or level-specific mapping.
271  kColorEyeball = 105,
272  kColorEyeIris = 106,
273  kColorMiniEyeIris = 107,
274  kColorDroneEye = 108,
275  kColorSoldierBody = 109,
276  kColorSoldierEye = 110,
277  kColorQueenBody = 111,
278  kColorQueenEye = 112,
279  kColorQueenWingRed = 113
280 };
281 
282 enum {
283  kColonyDebugMove = 1 << 0,
284  kColonyDebugRender = 1 << 1,
285  kColonyDebugAnimation = 1 << 2,
286  kColonyDebugMap = 1 << 3,
287  kColonyDebugSound = 1 << 4,
288  kColonyDebugUI = 1 << 5,
289  kColonyDebugCombat = 1 << 6,
290 };
291 
292 // Mac menu action IDs (matching original Mac Colony menu structure)
293 enum MenuAction {
294  kMenuActionAbout = 1,
295  kMenuActionNew,
296  kMenuActionOpen,
297  kMenuActionSave,
298  kMenuActionSaveAs,
299  kMenuActionQuit,
300  kMenuActionSound,
301  kMenuActionCrosshair,
302  kMenuActionPolyFill,
303  kMenuActionCursorShoot
304 };
305 
306 static const int kBaseObject = 20;
307 static const int kMeNum = 101;
308 
309 struct Locate {
310  uint8 ang = 0;
311  uint8 look = 0;
312  int8 lookY = 0;
313  int lookx = 0;
314  int delta = 0;
315  int xloc = 0;
316  int yloc = 0;
317  int xindex = 0;
318  int yindex = 0;
319  int xmx = 0, xmn = 0;
320  int zmx = 0, zmn = 0;
321  int32 power[3] = {};
322  int type = 0;
323  int dx = 0, dy = 0;
324  int dist = 0;
325  int wallPad = 0; // 3D bounding radius for wall clamping (0 = use default kWallPad)
326 };
327 
328 struct Thing {
329  int type = 0;
330  int visible = 0;
331  int alive = 0;
332  Common::Rect clip;
333  int count = 0;
334  Locate where;
335  int opcode = 0;
336  int counter = 0;
337  int time = 0;
338  int grow = 0;
339  // void (*make)(); // To be implemented as virtual functions or member function pointers
340  // void (*think)();
341 };
342 
343 // PATCH.C: Tracks object relocations across levels (forklift carry/drop).
344 struct PatchEntry {
345  struct { uint8 level, xindex, yindex; } from;
346  struct { uint8 level, xindex, yindex; int xloc, yloc; uint8 ang; } to;
347  uint8 type;
348  uint8 mapdata[5];
349 };
350 
351 // Temporary location reference for carrying objects.
352 struct PassPatch {
353  uint8 level, xindex, yindex;
354  int xloc, yloc;
355  uint8 ang;
356 };
357 
358 // Per-level persistence: wall state changes (airlock locks) and visit flags.
359 struct LevelData {
360  uint8 visit;
361  uint8 queen;
362  uint8 object[kBaseObject + 1];
363  uint8 count; // airlock open count (termination check)
364  uint8 size; // number of saved wall changes (max 10)
365  uint8 location[10][3]; // [x, y, direction] of each changed wall
366  uint8 data[10][5]; // saved wall feature bytes (5 per location)
367 };
368 
369 struct MacColor {
370  uint16 fg[3];
371  uint16 bg[3];
372  uint16 pattern;
373 };
374 
375 struct Image {
376  int16 width;
377  int16 height;
378  int16 align;
379  int16 rowBytes;
380  int8 bits;
381  int8 planes;
382  byte *data;
383 
384  Image() : width(0), height(0), align(0), rowBytes(0), bits(0), planes(0), data(nullptr) {}
385  ~Image() { delete[] data; }
386 };
387 
388 struct Sprite {
389  Image *fg;
390  Image *mask;
391  Common::Rect clip;
392  Common::Rect locate;
393  bool used;
394 
395  // Per-sprite render cache: bit-pattern + mask are baked into an
396  // alpha-keyed RGBA surface and uploaded once via drawSurface, instead
397  // of issuing setPixel per pixel each frame. Invalidated when the
398  // (fgColor, bgColor) pair changes (level/palette transition).
399  Graphics::Surface *baked;
400  uint64 bakedKey;
401 
402  Sprite() : fg(nullptr), mask(nullptr), used(false), baked(nullptr), bakedKey(0) {}
403  ~Sprite() {
404  delete fg;
405  delete mask;
406  if (baked) {
407  baked->free();
408  delete baked;
409  }
410  }
411 };
412 
414  struct SubObject {
415  int16 spritenum;
416  int16 xloc, yloc;
417  };
418  Common::Array<SubObject> objects;
419  Common::Rect bounds;
420  bool visible;
421  int16 current;
422  int16 xloc, yloc;
423  int16 acurrent;
424  int16 axloc, ayloc;
425  uint8 type;
426  uint8 frozen;
427  uint8 locked;
428  int16 link;
429  int16 key;
430  int16 lock;
431  bool onoff;
432 
433  ComplexSprite() : visible(false), current(0), xloc(0), yloc(0), acurrent(0), axloc(0), ayloc(0), type(0), frozen(0), locked(0), link(0), key(0), lock(0), onoff(true) {}
434 };
435 
436 class Debugger;
437 
438 class ColonyEngine : public Engine {
439  friend class Debugger;
440 public:
441  ColonyEngine(OSystem *syst, const ADGameDescription *gd);
442  virtual ~ColonyEngine();
443 
444  Common::Error run() override;
445  bool hasFeature(EngineFeature f) const override;
446  bool canSaveGameStateCurrently(Common::U32String *msg = nullptr) override;
447  bool canLoadGameStateCurrently(Common::U32String *msg = nullptr) override;
448  Common::Error saveGameStream(Common::WriteStream *stream, bool isAutosave = false) override;
449  Common::Error loadGameStream(Common::SeekableReadStream *stream) override;
450  void pauseEngineIntern(bool pause) override;
451  Common::Platform getPlatform() const { return _gameDescription->platform; }
452  bool isSoundEnabled() const { return _soundOn; }
453  const Graphics::Surface *getSavedScreen() const { return _savedScreen; }
454  bool isMacRenderMode() const { return _renderMode == Common::kRenderMacintosh || _renderMode == Common::kRenderMacintoshBW; }
455  bool isMacColorMode() const { return _renderMode == Common::kRenderMacintosh && _hasMacColors; }
456 
457  void initTrig();
458  void loadMacColors();
459  void loadMap(int mnum);
460  void startNewGame();
461  void corridor();
462  void quadrant();
463  bool hasInteractiveWallFeature(int cx, int cy, int dir) const;
464  void clampToWalls(Locate *p);
465  void clampToDiagonalWalls(Locate *p);
466  int checkwallMoveTo(int xnew, int ynew, int xind2, int yind2, Locate *pobject, uint8 trailCode);
467  int checkwallTryFeature(int xnew, int ynew, int xind2, int yind2, Locate *pobject, int dir);
468  int checkwall(int xnew, int ynew, Locate *pobject);
469  void clearPlayerCellMarker();
470  void setPlayerCellMarker();
471  bool playerIntersectsObjectFootprint(const Thing &obj, int xloc, int yloc) const;
472  void cCommand(int xnew, int ynew, bool allowInteraction);
473  bool scrollInfo(const Graphics::Font *macFont = nullptr);
474  bool checkSkipRequested();
475  bool waitForInput();
476  void checkCenter();
477  void fallThroughHole();
478  void playTunnelEffect(bool falling);
479 
480  void doText(int entry, int center);
481  void inform(const char *text, bool hold);
482  void printMessage(const char *text[], bool hold);
483  void makeMessageRect(Common::Rect &r);
484  int runMacEndgameDialog(const Common::String &message);
485 
486 private:
487  const ADGameDescription *_gameDescription;
488 
489  uint8 _wall[32][32];
490  uint8 _mapData[31][31][5][5];
491  uint8 _robotArray[32][32];
492  uint8 _foodArray[32][32];
493  uint8 _dirXY[32][32];
494  bool _visited[8][32][32]; // per-level fog-of-war: _visited[level-1][x][y]
495  bool _showAutomap;
496 
497  Locate _me;
498  Common::Array<Thing> _objects;
499  int _level;
500  int _robotNum;
501  int _dynamicObjectBase = 0;
502 
503  Renderer *_gfx = nullptr;
504  Sound *_sound = nullptr;
505  Graphics::FrameLimiter *_frameLimiter = nullptr;
506  Common::RenderMode _renderMode;
507  Graphics::Surface *_savedScreen = nullptr;
508 
509 
510  int _tsin = 0, _tcos = 0;
511  int _sint[256];
512  int _cost[256];
513  int _centerX, _centerY;
514  int _width, _height;
515  float _mouseSensitivity;
516  bool _mouseLocked;
517  bool _soundOn = true;
518  bool _showDashBoard;
519  bool _crosshair;
520  bool _cursorShoot = false;
521  bool _insight;
522  bool _hasKeycard;
523  bool _unlocked;
524  int _weapons;
525  bool _wireframe;
526  bool _widescreen;
527  bool _fullscreen;
528  int _speedShift; // 1-5, movement speed = 1 << (_speedShift - 1)
529 
530  // Continuous movement flags (set/cleared by keymapper action events)
531  bool _moveForward;
532  bool _moveBackward;
533  bool _strafeLeft;
534  bool _strafeRight;
535  bool _rotateLeft;
536  bool _rotateRight;
537  bool _sprint;
538 
539  // Sub-unit accumulators for deltaTime-based smooth movement.
540  // Position uses 256-units-per-cell integers, angles are uint8 — these
541  // retain fractional progress between frames so low speeds aren't lost.
542  float _moveAccumX;
543  float _moveAccumY;
544  float _rotAccum;
545 
546  Common::RandomSource _randomSource;
547  Common::Point _mousePos;
548  uint8 _decode1[4];
549  uint8 _decode2[4];
550  uint8 _decode3[4];
551  uint8 _animDisplay[6];
552  int _coreState[2];
553  int _coreHeight[2];
554  int _corePower[3];
555  int _epower[3]; // log2 display levels for power bars (from qlog)
556  int _coreIndex;
557  int _orbit = 0;
558  int _armor = 0;
559  bool _gametest = false;
560  uint32 _blackoutColor = 0;
561  uint32 _lastClickTime = 0;
562  uint32 _displayCount = 0; // Frame counter for COLOR wall animation (Mac: count)
563  uint32 _lastColonyThinkTime = 0; // Last 125ms CThink tick, for render-only interpolation
564  uint32 _lastHotfootTime = 0; // Time-gate for HOTFOOT damage (~8fps)
565  uint32 _lastAnimUpdate = 0;
566  uint32 _lastWarningChimeTime = 0;
567  uint32 _lastCollisionSoundTime = 0;
568  int _action0 = 0, _action1 = 0;
569  int _creature = 0;
570  bool _allGrow = false;
571  bool _suppressCollisionSound = false;
572 
573  // Battle state (battle.c)
574  int _gameMode = kModeColony;
575  Locate _bfight[16]; // 16 battle enemies
576  Locate _battleEnter; // entrance structure
577  Locate _battleShip; // shuttle
578  Locate _battleProj; // enemy projectile
579  bool _projon = false; // projectile active
580  int _pcount = 0; // projectile countdown
581  int _mountains[256]; // mountain height profile
582  int _battledx = 0; // mountain parallax divisor (Width/59)
583  int _battleRound = 0; // AI round-robin counter
584  Locate *_battlePwh[100] = {}; // visible object pointers (for hit detection)
585  int _battleMaxP = 0; // count of visible objects
586  Locate _pyramids[4][4][15]; // pyramid obstacles: 4x4 quadrants, 15 each
587 
588  // PATCH.C: object relocation + wall state persistence
589  Common::Array<PatchEntry> _patches;
590  PassPatch _carryPatch[2]; // [0]=forklift, [1]=carried object
591  int _carryType; // type of object being carried
592  int _fl; // 0=not in forklift, 1=in forklift empty, 2=carrying object
593  LevelData _levelData[8]; // per-level wall state persistence
594 
595  MacColor _macColors[145];
596  bool _hasMacColors;
597  Graphics::Cursor *_macCrossCursor = nullptr;
598  Graphics::Cursor *_macArrowCursor = nullptr;
599  int _lastLoggedCursorMode = -1;
600 
601  // Mac menu bar (MacWindowManager overlay)
602  Graphics::MacWindowManager *_wm = nullptr;
603  Graphics::MacMenu *_macMenu = nullptr;
604  Graphics::ManagedSurface *_menuSurface = nullptr;
605  int _menuBarHeight = 0;
606  void initMacMenus();
607  void loadMacCursorResources();
608  void handleMenuAction(int action);
609  static void menuCommandsCallback(int action, Common::String &text, void *data);
610 
611  int _frntxWall = 0, _frntyWall = 0;
612  int _sidexWall = 0, _sideyWall = 0;
613  int _frntx = 0, _frnty = 0;
614  int _sidex = 0, _sidey = 0;
615  int _front = 0, _side = 0;
616  int _direction = 0;
617 
618  Common::Rect _clip;
619  Common::Rect _screenR;
620  Common::Rect _dashBoardRect;
621  Common::Rect _compassRect; // DOS: compOval (after shrink); Mac: moveWindow
622  Common::Rect _headsUpRect; // DOS: floorRect; Mac: minimap inside moveWindow
623  Common::Rect _powerRect; // DOS: powerRect; Mac: infoWindow
624 
625  // DOS dashboard layout (from original MetaWINDOW pix_per_Qinch values)
626  int _pQx = 0; // pixels per quarter-inch X (24 for EGA 640x350)
627  int _pQy = 0; // pixels per quarter-inch Y (18 for EGA 640x350)
628  int _powerWidth = 0; // width of each of the 3 power bar columns
629  int _powerHeight = 0; // pixel height per power bar unit (max 5)
630 
631  // Cached decoded PICT surfaces for dashboard panels (Mac color mode)
632  Graphics::Surface *_pictPower = nullptr; // PICT -32755 (normal) or -32760 (trouble)
633  Graphics::Surface *_pictPowerNoArmor = nullptr; // PICT -32761 (no armor, color)
634  Graphics::Surface *_pictCompass = nullptr; // PICT -32757
635  int _pictPowerID = 0; // Track which PICT is cached
636  Graphics::Surface *loadPictSurface(int resID);
637  void drawPictAt(Graphics::Surface *surf, int destX, int destY);
638 
639  uint8 wallAt(int x, int y) const;
640  const uint8 *mapFeatureAt(int x, int y, int direction) const;
641  bool _visibleCell[32][32] = {};
642  void computeVisibleCells();
643  void drawStaticObjects();
644 
645 public:
646  struct PrismPartDef {
647  int pointCount;
648  const int (*points)[3];
649  int surfaceCount;
650  const int (*surfaces)[8];
651  };
652 
653 private:
654  void draw3DPrism(Thing &obj, const PrismPartDef &def, bool useLook, int colorOverride = -1, bool accumulateBounds = false, bool forceVisible = false);
655  void draw3DLeaf(const Thing &obj, const PrismPartDef &def);
656  void draw3DSphere(Thing &obj, int pt0x, int pt0y, int pt0z,
657  int pt1x, int pt1y, int pt1z, uint32 fillColor, uint32 outlineColor, bool accumulateBounds = false);
658  void drawPrismOval3D(Thing &thing, const PrismPartDef &def, bool useLook, int colorOverride, bool forceVisible = false);
659  void drawEyeOverlays3D(Thing &thing, const PrismPartDef &irisDef, int irisColorOverride,
660  const PrismPartDef &pupilDef, int pupilColorOverride, bool useLook);
661  float growRenderTickFraction() const;
662  bool drawInterpolatedGrowRobot(Thing &obj, int eyeballColor, int pupilColor);
663  void drawInterpolatedGrowPrism(Thing &obj, const PrismPartDef &fromDef, const PrismPartDef &toDef, float progress);
664  void drawInterpolatedGrowEye(Thing &obj, int fromStage, int toStage, float progress, int eyeballColor, int pupilColor);
665  bool drawStaticObjectPrisms3D(Thing &obj);
666  void initRobots();
667  void renderCorridor3D();
668  void drawWallFeatures3D();
669  void drawWallFeature3D(int cellX, int cellY, int direction);
670  void drawCellFeature3D(int cellX, int cellY);
671  void getWallFace3D(int cellX, int cellY, int direction, float corners[4][3]);
672  void getCellFace3D(int cellX, int cellY, bool ceiling, float corners[4][3]);
673 
674  int occupiedObjectAt(int xnew, int ynew, int x, int y, const Locate *pobject);
675  void interactWithObject(int objNum);
676 
677  // Convert a mouse coord delivered by the event manager into engine
678  // logical coords. With kSupportsArbitraryResolutions declared, the
679  // framework rewrites _currentState.gameWidth to the overlay (window)
680  // pixel size in recalculateDisplayAreas() — so g_system->getWidth()
681  // no longer matches our _width, and mouse events arrive in window
682  // pixels. The engine's hit-test math (whichSprite, _screenR) is in
683  // logical coords, so we have to scale back. Same pattern Freescape
684  // uses in mousePosToCrossairPos (freescape.cpp:593-597).
685  Common::Point eventMouseToLogical(const Common::Point &p) const;
686  // Inverse of eventMouseToLogical: warp the mouse to a position
687  // expressed in engine-logical coords. _system->warpMouse expects
688  // virtual-screen coords, which with kSupportsArbitraryResolutions
689  // is window pixels.
690  void warpMouseLogical(int x, int y);
691 
692  // shoot.c: shooting and power management
693  void setPower(int p0, int p1, int p2);
694  void cShoot();
695  bool isShootableRobotType(int type) const;
696  bool isShotBlockingObjectType(int type) const;
697  int findAimedObject(const Common::Point &aim, bool *isBlocker = nullptr, int *targetDist = nullptr) const;
698  bool hasAimedRobotTarget() const;
699  void destroyRobot(int num);
700  void doShootCircles(int cx, int cy);
701  void doBurnHole(int cx, int cy, int radius);
702  void meGetShot();
703 
704  // battle.c: outdoor battle system (OpenGL 3D)
705  void battleInit();
706  void battleSet();
707  void battleThink();
708  void normalizeBattlePlayerPosition();
709  void enterColonyFromBattle(int mapNum, int xloc, int yloc);
710  void battleCommand(int xnew, int ynew);
711  void battleShoot();
712  void battleProjCommand(int xcheck, int ycheck);
713  void renderBattle();
714  void draw3DBattlePrism(const PrismPartDef &def, int worldX, int worldY, uint8 ang, int zShift = 0);
715  void battleBackdrop();
716  void battleDrawPyramids();
717  void battleDrawTanks();
718 
719  // PATCH.C: object relocation + wall state persistence
720  void resetObjectSlot(int slot, int type, int xloc, int yloc, uint8 ang);
721  bool createObject(int type, int xloc, int yloc, uint8 ang);
722  void saveLevelState();
723  void doPatch();
724  void saveWall(int x, int y, int direction);
725  void getWall();
726  void newPatch(int type, const PassPatch &from, const PassPatch &to, const uint8 *mapdata);
727  bool patchMapTo(const PassPatch &to, uint8 *mapdata);
728  bool patchMapFrom(const PassPatch &from, uint8 *mapdata);
729  void exitForklift();
730  void dropCarriedObject();
731  bool setDoorState(int x, int y, int direction, int state);
732  int openAdjacentDoors(int x, int y);
733  int goToDestination(const uint8 *map, Locate *pobject);
734  int tryPassThroughFeature(int fromX, int fromY, int direction, Locate *pobject);
735  void playTunnelAirlockEffect();
736  void syncMacMenuChecks();
737  void updateMouseCapture(bool recenter = true);
738  Common::Point getAimPoint() const;
739  void updateViewportLayout();
740  void drawDashboardStep1();
741  void drawDashboardMac();
742  void drawDOSBarGraph(int x, int y, int height);
743  void updateDOSPowerBars();
744  static int qlog(int32 x);
745  void drawMiniMapMarker(int x, int y, int halfSize, uint32 color, bool isMac, const Common::Rect *clip = nullptr);
746  bool hasRobotAt(int x, int y) const;
747  bool hasFoodAt(int x, int y) const;
748  void drawMiniMap(uint32 lineColor);
749  void drawAutomap();
750  void markVisited();
751  void automapCellCorner(int dx, int dy, int xloc, int yloc, int lExt, int tsin, int tcos, int ccx, int ccy, int &sx, int &sy);
752  void automapDrawWall(const Common::Rect &vp, int x1, int y1, int x2, int y2, uint32 color);
753  int automapWallFeature(int fx, int fy, int dir);
754  void automapDrawWallWithFeature(const Common::Rect &vp, int wx1, int wy1, int wx2, int wy2, int feat, int lExt, uint32 color);
755  void drawForkliftOverlay();
756  void drawCrosshair();
757  bool clipLineToRect(int &x1, int &y1, int &x2, int &y2, const Common::Rect &clip) const;
758  void wallLine(const float corners[4][3], float u1, float v1, float u2, float v2, uint32 color);
759  void wallPolygon(const float corners[4][3], const float *u, const float *v, int count, uint32 color);
760  void wallChar(const float corners[4][3], uint8 cnum);
761 
762  struct TextIndex {
763  uint32 offset;
764  uint16 ch;
765  uint16 lines;
766  };
767 
768  // Animation system
769  Common::Array<Sprite *> _cSprites;
771  Image *_backgroundMask = nullptr;
772  Image *_backgroundFG = nullptr;
773  // Same render cache convention as Sprite::baked, applied to the
774  // per-animation background image (no Sprite owner, so it lives here).
775  Graphics::Surface *_backgroundBaked = nullptr;
776  uint64 _backgroundBakedKey = 0;
777  Common::Rect _backgroundClip;
778  Common::Rect _backgroundLocate;
779  bool _backgroundActive;
780  Common::MacResManager *_resMan = nullptr;
781  Common::MacResManager *_colorResMan = nullptr;
782  byte _topBG[8] = {};
783  byte _bottomBG[8] = {};
784  int16 _divideBG;
785 
786  // Cache for the animation background pattern. Regenerated only when
787  // pattern bytes / colors / split point change. Replaces a 110k-pixel
788  // setPixel loop with one texture upload, fixing cursor choppiness
789  // during animations on the OpenGL renderer.
790  Graphics::Surface *_animPatternSurface = nullptr;
791  byte _animPatternKeyTopBG[8] = {};
792  byte _animPatternKeyBottomBG[8] = {};
793  int16 _animPatternKeyDivide = -1;
794  uint32 _animPatternKeyTopColor = 0;
795  uint32 _animPatternKeyBotColor = 0;
796  int _animPatternKeyMode = -1; // 0=DOS, 1=Mac B&W, 2=Mac color
797  bool _animPatternValid = false;
798  Common::String _animationName;
799  Common::Array<int16> _animBMColors;
800  bool _animationRunning;
801  int _animationResult;
802  bool _doorOpen;
803  int _liftObject = 0; // sprite index for the carried object in lift animation
804  bool _liftUp = false; // current lift state: true=raised, false=lowered
805  int _elevatorFloor;
806  int _airlockX = -1;
807  int _airlockY = -1;
808  int _airlockDirection = -1;
809  bool _airlockTerminate = false;
810 
811  void playIntro();
812  bool makeStars(const Common::Rect &r, int btn);
813  bool makeBlackHole();
814  bool makePlanet();
815  bool timeSquare(const Common::String &str, const Graphics::Font *macFont = nullptr);
816  bool drawPict(int resID);
817  bool loadAnimation(const Common::String &name);
818  void deleteAnimation();
819  void takeOff();
820  void gameOver(bool kill);
821  int countSavedCryos() const;
822  void playAnimation();
823  void updateAnimation();
824  void drawAnimation();
825  void drawComplexSprite(int index, int ox, int oy);
826  void drawAnimationImage(Image *img, Image *mask, int x, int y, uint32 fillColor,
827  Graphics::Surface *&bakedCache, uint64 &bakedCacheKey);
828  uint32 resolveAnimColor(int16 bmEntry) const;
829  Image *loadImage(Common::SeekableReadStreamEndian &file);
830  void unpackBytes(Common::SeekableReadStreamEndian &file, byte *dst, uint32 len);
832  int whichSprite(const Common::Point &p);
833  void handleAnimationClick(int item);
834  void playCollisionSound();
835  void handleDeskClick(int item);
836  void handleVanityClick(int item);
837  void handleSlidesClick(int item);
838  void handleTeleshowClick(int item);
839  void handleKeypadClick(int item);
840  void handleSuitClick(int item);
841  void handleDoorClick(int item);
842  void handleAirlockClick(int item);
843  void handleElevatorClick(int item);
844  void handleControlsClick(int item);
845  void dolSprite(int index);
846  void moveObject(int index);
847  void setObjectState(int num, int state);
848  int objectState(int num) const;
849  void setObjectOnOff(int num, bool on);
850  void refreshAnimationDisplay();
851  void cryptArray(uint8 sarray[6], int i, int j, int k, int l);
852  void terminateGame(bool blowup);
853 
854  // think.c / shoot.c: colony robot AI, egg growth, and egg eating
855  void cThink();
856  void cubeThink(int num);
857  void pyramidThink(int num);
858  void upyramidThink(int num);
859  void eyeThink(int num);
860  void queenThink(int num);
861  void droneThink(int num);
862  void snoopThink(int num);
863  void eggThink(int num);
864  int getColonyActiveRobotLimit() const;
865  void copyOverflowObjectToSlot(int num);
866  bool layEgg(int type, int xindex, int yindex);
867  void moveThink(int num);
868  void bigGrow(int num);
869  void growRobot(int num);
870  int scanForPlayer(int num);
871  void robotShoot(int num);
872  void meEat();
873  void respawnObject(int num, int type);
874 };
875 
876 } // End of namespace Colony
877 
878 #endif // COLONY_H
Definition: managed_surface.h:51
Definition: framelimiter.h:40
Definition: macresman.h:126
Definition: str.h:59
Definition: font.h:83
Definition: surface.h:67
EngineFeature
Definition: engine.h:258
Definition: stream.h:77
Definition: error.h:81
Definition: array.h:52
Definition: pixelformat.h:138
Definition: advancedDetector.h:164
Definition: colony.h:344
Definition: random.h:44
RenderMode
Definition: rendermode.h:48
Definition: rect.h:524
Definition: colony.h:646
Definition: stream.h:745
Definition: macwindowmanager.h:147
Definition: colony.h:54
Definition: colony.h:352
Definition: colony.h:328
Definition: ustr.h:57
Definition: atari-cursor.h:35
Definition: colony.h:359
Definition: renderer.h:38
Definition: colony.h:414
Definition: cursor.h:42
Definition: algorithm.h:29
Definition: formatinfo.h:28
Definition: rect.h:144
Definition: colony.h:438
Definition: sound.h:40
Definition: macmenu.h:94
Definition: stream.h:944
Definition: console.h:37
uint32 ARGBToColor(uint8 a, uint8 r, uint8 g, uint8 b) const
Definition: pixelformat.h:278
Definition: colony.h:309
Definition: system.h:165
Definition: colony.h:388
Definition: movie_decoder.h:32
Definition: engine.h:144
Definition: colony.h:413
Platform
Definition: platform.h:93
Definition: colony.h:369