Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 1 | pmbaty | 1 | /* |
| 2 | * Portions of this file are copyright Rebirth contributors and licensed as |
||
| 3 | * described in COPYING.txt. |
||
| 4 | * Portions of this file are copyright Parallax Software and licensed |
||
| 5 | * according to the Parallax license below. |
||
| 6 | * See COPYING.txt for license details. |
||
| 7 | |||
| 8 | THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX |
||
| 9 | SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO |
||
| 10 | END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A |
||
| 11 | ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS |
||
| 12 | IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS |
||
| 13 | SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE |
||
| 14 | FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE |
||
| 15 | CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS |
||
| 16 | AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. |
||
| 17 | COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. |
||
| 18 | */ |
||
| 19 | |||
| 20 | /* |
||
| 21 | * |
||
| 22 | * Constants & prototypes which pertain to the game only |
||
| 23 | * |
||
| 24 | */ |
||
| 25 | |||
| 26 | #pragma once |
||
| 27 | |||
| 28 | #include <physfs.h> |
||
| 29 | #include "maths.h" |
||
| 30 | |||
| 31 | #ifdef __cplusplus |
||
| 32 | #include <chrono> |
||
| 33 | #include <cstdint> |
||
| 34 | #include "pack.h" |
||
| 35 | #include "fwd-object.h" |
||
| 36 | #include "fwd-player.h" |
||
| 37 | #include "fwd-segment.h" |
||
| 38 | #include "fwd-window.h" |
||
| 39 | #include "wall.h" |
||
| 40 | |||
| 41 | #define DESIGNATED_GAME_FPS 30 // assuming the original intended Framerate was 30 |
||
| 42 | #define DESIGNATED_GAME_FRAMETIME (F1_0/DESIGNATED_GAME_FPS) |
||
| 43 | |||
| 44 | #ifdef NDEBUG |
||
| 45 | #define MINIMUM_FPS DESIGNATED_GAME_FPS |
||
| 46 | #define MAXIMUM_FPS 200 |
||
| 47 | #else |
||
| 48 | #define MINIMUM_FPS 1 |
||
| 49 | #define MAXIMUM_FPS 1000 |
||
| 50 | #endif |
||
| 51 | |||
| 52 | extern class window *Game_wind; |
||
| 53 | |||
| 54 | // from mglobal.c |
||
| 55 | namespace dcx { |
||
| 56 | using d_time_fix = std::chrono::duration<uint32_t, std::ratio<1, F1_0>>; |
||
| 57 | extern fix FrameTime; // time in seconds since last frame |
||
| 58 | extern fix64 GameTime64; // time in game (sum of FrameTime) |
||
| 59 | extern int d_tick_count; // increments according to DESIGNATED_GAME_FRAMETIME |
||
| 60 | extern int d_tick_step; // true once in interval of DESIGNATED_GAME_FRAMETIME |
||
| 61 | } |
||
| 62 | |||
| 63 | #if defined(DXX_BUILD_DESCENT_II) |
||
| 64 | class object_signature_t; |
||
| 65 | namespace dsx { |
||
| 66 | extern struct object *Missile_viewer; |
||
| 67 | extern object_signature_t Missile_viewer_sig; |
||
| 68 | |||
| 69 | #define CV_NONE 0 |
||
| 70 | #define CV_ESCORT 1 |
||
| 71 | #define CV_REAR 2 |
||
| 72 | #define CV_COOP 3 |
||
| 73 | #define CV_MARKER 4 |
||
| 74 | |||
| 75 | extern std::array<unsigned, 2> Coop_view_player; // left & right |
||
| 76 | extern std::array<game_marker_index, 2> Marker_viewer_num; // left & right |
||
| 77 | } |
||
| 78 | #endif |
||
| 79 | |||
| 80 | // The following bits define the game modes. |
||
| 81 | //#define GM_EDITOR 1 // You came into the game from the editor. Now obsolete - FYI only |
||
| 82 | // #define GM_SERIAL 2 // You are in serial mode // OBSOLETE |
||
| 83 | #define GM_NETWORK 4 // You are in network mode |
||
| 84 | #define GM_MULTI_ROBOTS 8 // You are in a multiplayer mode with robots. |
||
| 85 | #define GM_MULTI_COOP 16 // You are in a multiplayer mode and can't hurt other players. |
||
| 86 | // #define GM_MODEM 32 // You are in a modem (serial) game // OBSOLETE |
||
| 87 | #define GM_UNKNOWN 64 // You are not in any mode, kind of dangerous... |
||
| 88 | #define GM_GAME_OVER 128 // Game has been finished |
||
| 89 | #define GM_TEAM 256 // Team mode for network play |
||
| 90 | #if defined(DXX_BUILD_DESCENT_I) |
||
| 91 | #define GM_BOUNTY 512 // New bounty mode by Matt1360 |
||
| 92 | #elif defined(DXX_BUILD_DESCENT_II) |
||
| 93 | #define GM_CAPTURE 512 // Capture the flag mode for D2 |
||
| 94 | #define GM_HOARD 1024 // New hoard mode for D2 Christmas |
||
| 95 | #define GM_BOUNTY 2048 /* New bounty mode by Matt1360 */ |
||
| 96 | #endif |
||
| 97 | #define GM_NORMAL 0 // You are in normal play mode, no multiplayer stuff |
||
| 98 | #define GM_MULTI GM_NETWORK // You are in some type of multiplayer game (GM_NETWORK /* | GM_SERIAL | GM_MODEM */) |
||
| 99 | |||
| 100 | |||
| 101 | #define NDL 5 // Number of difficulty levels. |
||
| 102 | |||
| 103 | namespace dcx { |
||
| 104 | extern int Game_mode; |
||
| 105 | extern screen_mode Game_screen_mode; |
||
| 106 | } |
||
| 107 | |||
| 108 | #ifndef NDEBUG // if debugging, these are variables |
||
| 109 | |||
| 110 | extern int Slew_on; // in slew or sim mode? |
||
| 111 | |||
| 112 | #else // if not debugging, these are constants |
||
| 113 | |||
| 114 | #define Slew_on 0 // no slewing in real game |
||
| 115 | |||
| 116 | #endif |
||
| 117 | |||
| 118 | // Suspend flags |
||
| 119 | |||
| 120 | #define SUSP_ROBOTS 1 // Robot AI doesn't move |
||
| 121 | |||
| 122 | #define SHOW_EXIT_PATH 1 |
||
| 123 | |||
| 124 | |||
| 125 | // from game.c |
||
| 126 | void close_game(void); |
||
| 127 | void calc_frame_time(void); |
||
| 128 | namespace dcx { |
||
| 129 | void calc_d_tick(); |
||
| 130 | |||
| 131 | extern int Game_suspended; // if non-zero, nothing moves but player |
||
| 132 | |||
| 133 | /* This must be a signed type. Some sites, such as `bump_this_object`, |
||
| 134 | * use Difficulty_level_type in arithmetic expressions, and those |
||
| 135 | * expressions must be signed to produce the correct result. |
||
| 136 | */ |
||
| 137 | enum Difficulty_level_type : signed int |
||
| 138 | { |
||
| 139 | Difficulty_0, |
||
| 140 | Difficulty_1, |
||
| 141 | Difficulty_2, |
||
| 142 | Difficulty_3, |
||
| 143 | Difficulty_4, |
||
| 144 | }; |
||
| 145 | |||
| 146 | constexpr Difficulty_level_type DEFAULT_DIFFICULTY = Difficulty_1; |
||
| 147 | |||
| 148 | static inline Difficulty_level_type cast_clamp_difficulty(const unsigned d) |
||
| 149 | { |
||
| 150 | return (d <= Difficulty_4) ? static_cast<Difficulty_level_type>(d) : Difficulty_4; |
||
| 151 | } |
||
| 152 | |||
| 153 | struct d_game_shared_state |
||
| 154 | { |
||
| 155 | }; |
||
| 156 | |||
| 157 | struct d_game_unique_state |
||
| 158 | { |
||
| 159 | using savegame_file_path = std::array<char, PATH_MAX>; |
||
| 160 | /* 20 is required by the save game ABI and the multiplayer |
||
| 161 | * save/restore command ABI. |
||
| 162 | */ |
||
| 163 | using savegame_description = std::array<char, 20>; |
||
| 164 | static constexpr std::integral_constant<unsigned, 11> MAXIMUM_SAVE_SLOTS{}; |
||
| 165 | enum class save_slot : unsigned |
||
| 166 | { |
||
| 167 | _0, |
||
| 168 | _1, |
||
| 169 | _2, |
||
| 170 | _3, |
||
| 171 | _4, |
||
| 172 | _5, |
||
| 173 | _6, |
||
| 174 | _7, |
||
| 175 | _8, |
||
| 176 | _9, |
||
| 177 | _autosave, |
||
| 178 | secret_save_filename_override = MAXIMUM_SAVE_SLOTS + 1, |
||
| 179 | None = UINT32_MAX |
||
| 180 | }; |
||
| 181 | Difficulty_level_type Difficulty_level; // Difficulty level in 0..NDL-1, 0 = easiest, NDL-1 = hardest |
||
| 182 | fix Boss_gate_interval; |
||
| 183 | unsigned accumulated_robots; |
||
| 184 | unsigned total_hostages; |
||
| 185 | std::chrono::steady_clock::time_point Next_autosave; |
||
| 186 | save_slot quicksave_selection = save_slot::None; |
||
| 187 | static constexpr unsigned valid_save_slot(const save_slot s) |
||
| 188 | { |
||
| 189 | return static_cast<unsigned>(s) < static_cast<unsigned>(save_slot::_autosave); |
||
| 190 | } |
||
| 191 | static constexpr unsigned valid_load_slot(const save_slot s) |
||
| 192 | { |
||
| 193 | return static_cast<unsigned>(s) <= static_cast<unsigned>(save_slot::_autosave); |
||
| 194 | } |
||
| 195 | }; |
||
| 196 | |||
| 197 | extern int Global_missile_firing_count; |
||
| 198 | |||
| 199 | extern int PaletteRedAdd, PaletteGreenAdd, PaletteBlueAdd; |
||
| 200 | } |
||
| 201 | |||
| 202 | #define MAX_PALETTE_ADD 30 |
||
| 203 | |||
| 204 | #if defined(DXX_BUILD_DESCENT_I) || defined(DXX_BUILD_DESCENT_II) |
||
| 205 | namespace dsx { |
||
| 206 | void game(); |
||
| 207 | void init_game(); |
||
| 208 | void init_cockpit(); |
||
| 209 | extern void PALETTE_FLASH_ADD(int dr, int dg, int db); |
||
| 210 | |||
| 211 | struct d_game_shared_state : ::dcx::d_game_shared_state |
||
| 212 | { |
||
| 213 | wall_animations_array WallAnims; |
||
| 214 | }; |
||
| 215 | |||
| 216 | #if defined(DXX_BUILD_DESCENT_II) |
||
| 217 | struct d_game_unique_state : ::dcx::d_game_unique_state |
||
| 218 | { |
||
| 219 | fix Final_boss_countdown_time; |
||
| 220 | }; |
||
| 221 | |||
| 222 | struct d_level_shared_seismic_state |
||
| 223 | { |
||
| 224 | fix Level_shake_frequency; |
||
| 225 | fix Level_shake_duration; |
||
| 226 | }; |
||
| 227 | |||
| 228 | struct d_level_unique_seismic_state |
||
| 229 | { |
||
| 230 | fix64 Seismic_disturbance_end_time; |
||
| 231 | fix64 Next_seismic_sound_time; |
||
| 232 | int Seismic_tremor_volume; |
||
| 233 | fix Seismic_tremor_magnitude; |
||
| 234 | std::array<fix64, 4> Earthshaker_detonate_times; |
||
| 235 | }; |
||
| 236 | |||
| 237 | extern d_level_shared_seismic_state LevelSharedSeismicState; |
||
| 238 | extern d_level_unique_seismic_state LevelUniqueSeismicState; |
||
| 239 | #endif |
||
| 240 | |||
| 241 | extern d_game_shared_state GameSharedState; |
||
| 242 | extern d_game_unique_state GameUniqueState; |
||
| 243 | } |
||
| 244 | #endif |
||
| 245 | |||
| 246 | //sets the rgb values for palette flash |
||
| 247 | #define PALETTE_FLASH_SET(_r,_g,_b) PaletteRedAdd=(_r), PaletteGreenAdd=(_g), PaletteBlueAdd=(_b) |
||
| 248 | |||
| 249 | namespace dcx { |
||
| 250 | void game_flush_respawn_inputs(); |
||
| 251 | |||
| 252 | extern int last_drawn_cockpit; |
||
| 253 | |||
| 254 | class pause_game_world_time |
||
| 255 | { |
||
| 256 | public: |
||
| 257 | pause_game_world_time(); |
||
| 258 | ~pause_game_world_time(); |
||
| 259 | }; |
||
| 260 | |||
| 261 | void stop_time(); |
||
| 262 | void start_time(); |
||
| 263 | void reset_time(); // called when starting level |
||
| 264 | } |
||
| 265 | |||
| 266 | #if DXX_USE_SCREENSHOT |
||
| 267 | #if defined(DXX_BUILD_DESCENT_I) || defined(DXX_BUILD_DESCENT_II) |
||
| 268 | namespace dcx { |
||
| 269 | |||
| 270 | // If automap_flag == 1, then call automap routine to write message. |
||
| 271 | #if DXX_USE_SCREENSHOT_FORMAT_LEGACY |
||
| 272 | void write_bmp(PHYSFS_File *, unsigned w, unsigned h); |
||
| 273 | #endif |
||
| 274 | extern void save_screen_shot(int automap_flag); |
||
| 275 | |||
| 276 | } |
||
| 277 | #endif |
||
| 278 | #endif |
||
| 279 | |||
| 280 | enum cockpit_mode_t |
||
| 281 | { |
||
| 282 | //valid modes for cockpit |
||
| 283 | CM_FULL_COCKPIT, // normal screen with cockpit |
||
| 284 | CM_REAR_VIEW, // looking back with bitmap |
||
| 285 | CM_STATUS_BAR, // small status bar, w/ reticle |
||
| 286 | CM_FULL_SCREEN, // full screen, no cockpit (w/ reticle) |
||
| 287 | CM_LETTERBOX // half-height window (for cutscenes) |
||
| 288 | }; |
||
| 289 | |||
| 290 | extern int Rear_view; // if true, looking back. |
||
| 291 | |||
| 292 | #ifdef dsx |
||
| 293 | namespace dsx { |
||
| 294 | void game_flush_inputs(); // clear all inputs |
||
| 295 | // initalize flying |
||
| 296 | } |
||
| 297 | #endif |
||
| 298 | |||
| 299 | // selects a given cockpit (or lack of one). |
||
| 300 | void select_cockpit(cockpit_mode_t mode); |
||
| 301 | |||
| 302 | // force cockpit redraw next time. call this if you've trashed the screen |
||
| 303 | namespace dcx { |
||
| 304 | void fly_init(object_base &obj); |
||
| 305 | void reset_cockpit(); // called if you've trashed the screen |
||
| 306 | |||
| 307 | // functions to save, clear, and resture palette flash effects |
||
| 308 | void reset_palette_add(void); |
||
| 309 | } |
||
| 310 | #ifdef dsx |
||
| 311 | namespace dsx { |
||
| 312 | void palette_restore(void); |
||
| 313 | } |
||
| 314 | #endif |
||
| 315 | #if defined(DXX_BUILD_DESCENT_I) |
||
| 316 | void palette_save(); |
||
| 317 | static inline void full_palette_save(void) |
||
| 318 | { |
||
| 319 | palette_save(); |
||
| 320 | } |
||
| 321 | #elif defined(DXX_BUILD_DESCENT_II) |
||
| 322 | void full_palette_save(void); // all of the above plus gr_palette_load(gr_palette) |
||
| 323 | #endif |
||
| 324 | |||
| 325 | // put up the help message |
||
| 326 | void show_help(); |
||
| 327 | void show_netgame_help(); |
||
| 328 | void show_newdemo_help(); |
||
| 329 | |||
| 330 | // show a message in a nice little box |
||
| 331 | void show_boxed_message(const char *msg, int RenderFlag); |
||
| 332 | |||
| 333 | // turns off rear view & rear view cockpit |
||
| 334 | void reset_rear_view(void); |
||
| 335 | |||
| 336 | namespace dcx { |
||
| 337 | void game_init_render_sub_buffers(int x, int y, int w, int h); |
||
| 338 | // Sets up the canvases we will be rendering to |
||
| 339 | static inline void game_init_render_buffers (int render_max_w, int render_max_h) |
||
| 340 | { |
||
| 341 | game_init_render_sub_buffers( 0, 0, render_max_w, render_max_h ); |
||
| 342 | } |
||
| 343 | |||
| 344 | extern int netplayerinfo_on; |
||
| 345 | } |
||
| 346 | |||
| 347 | #ifdef dsx |
||
| 348 | namespace dsx { |
||
| 349 | #if defined(DXX_BUILD_DESCENT_I) |
||
| 350 | static inline int game_mode_capture_flag() |
||
| 351 | { |
||
| 352 | return 0; |
||
| 353 | } |
||
| 354 | static inline int game_mode_hoard() |
||
| 355 | { |
||
| 356 | return 0; |
||
| 357 | } |
||
| 358 | #elif defined(DXX_BUILD_DESCENT_II) |
||
| 359 | static inline int game_mode_capture_flag() |
||
| 360 | { |
||
| 361 | return (Game_mode & GM_CAPTURE); |
||
| 362 | } |
||
| 363 | static inline int game_mode_hoard() |
||
| 364 | { |
||
| 365 | return (Game_mode & GM_HOARD); |
||
| 366 | } |
||
| 367 | |||
| 368 | //Flickering light system |
||
| 369 | struct flickering_light { |
||
| 370 | segnum_t segnum; |
||
| 371 | uint8_t sidenum; |
||
| 372 | uint32_t mask; // determines flicker pattern |
||
| 373 | fix timer; // time until next change |
||
| 374 | fix delay; // time between changes |
||
| 375 | }; |
||
| 376 | |||
| 377 | struct d_flickering_light_state |
||
| 378 | { |
||
| 379 | using Flickering_light_array_t = std::array<flickering_light, 100>; |
||
| 380 | unsigned Num_flickering_lights; |
||
| 381 | Flickering_light_array_t Flickering_lights; |
||
| 382 | }; |
||
| 383 | |||
| 384 | extern d_flickering_light_state Flickering_light_state; |
||
| 385 | |||
| 386 | extern int BigWindowSwitch; |
||
| 387 | void compute_slide_segs(); |
||
| 388 | |||
| 389 | // turn flickering off (because light has been turned off) |
||
| 390 | void disable_flicker(d_flickering_light_state &fls, vmsegidx_t segnum, unsigned sidenum); |
||
| 391 | |||
| 392 | // turn flickering off (because light has been turned on) |
||
| 393 | void enable_flicker(d_flickering_light_state &fls, vmsegidx_t segnum, unsigned sidenum); |
||
| 394 | |||
| 395 | /* |
||
| 396 | * reads a flickering_light structure from a PHYSFS_File |
||
| 397 | */ |
||
| 398 | void flickering_light_read(flickering_light &fl, PHYSFS_File *fp); |
||
| 399 | void flickering_light_write(const flickering_light &fl, PHYSFS_File *fp); |
||
| 400 | #endif |
||
| 401 | |||
| 402 | void game_render_frame_mono(); |
||
| 403 | static inline void game_render_frame_mono(int skip_flip) |
||
| 404 | { |
||
| 405 | game_render_frame_mono(); |
||
| 406 | if (!skip_flip) |
||
| 407 | gr_flip(); |
||
| 408 | } |
||
| 409 | } |
||
| 410 | #endif |
||
| 411 | void game_leave_menus(void); |
||
| 412 | |||
| 413 | //Cheats |
||
| 414 | #ifdef dsx |
||
| 415 | namespace dsx { |
||
| 416 | struct game_cheats : prohibit_void_ptr<game_cheats> |
||
| 417 | { |
||
| 418 | int enabled; |
||
| 419 | int wowie; |
||
| 420 | int allkeys; |
||
| 421 | int invul; |
||
| 422 | int shields; |
||
| 423 | int killreactor; |
||
| 424 | int exitpath; |
||
| 425 | int levelwarp; |
||
| 426 | int fullautomap; |
||
| 427 | int ghostphysics; |
||
| 428 | int rapidfire; |
||
| 429 | int turbo; |
||
| 430 | int robotfiringsuspended; |
||
| 431 | int acid; |
||
| 432 | #if defined(DXX_BUILD_DESCENT_I) |
||
| 433 | int wowie2; |
||
| 434 | int cloak; |
||
| 435 | int extralife; |
||
| 436 | int baldguy; |
||
| 437 | #elif defined(DXX_BUILD_DESCENT_II) |
||
| 438 | int lamer; |
||
| 439 | int accessory; |
||
| 440 | int bouncyfire; |
||
| 441 | int homingfire; |
||
| 442 | int killallrobots; |
||
| 443 | int robotskillrobots; |
||
| 444 | int monsterdamage; |
||
| 445 | int buddyclone; |
||
| 446 | int buddyangry; |
||
| 447 | #endif |
||
| 448 | }; |
||
| 449 | extern game_cheats cheats; |
||
| 450 | |||
| 451 | window *game_setup(); |
||
| 452 | window_event_result game_handler(window *wind,const d_event &event, const unused_window_userdata_t *); |
||
| 453 | window_event_result ReadControls(const d_event &event); |
||
| 454 | bool allowed_to_fire_laser(const player_info &); |
||
| 455 | void reset_globals_for_new_game(); |
||
| 456 | } |
||
| 457 | #endif |
||
| 458 | int cheats_enabled(); |
||
| 459 | void game_disable_cheats(); |
||
| 460 | void check_rear_view(void); |
||
| 461 | int create_special_path(void); |
||
| 462 | window_event_result ReadControls(const d_event &event); |
||
| 463 | void toggle_cockpit(void); |
||
| 464 | void game_render_frame(); |
||
| 465 | extern fix Show_view_text_timer; |
||
| 466 | extern d_time_fix ThisLevelTime; |
||
| 467 | extern int Last_level_path_created; |
||
| 468 | namespace dcx { |
||
| 469 | extern int force_cockpit_redraw; |
||
| 470 | } |
||
| 471 | #if defined(DXX_BUILD_DESCENT_II) |
||
| 472 | namespace dsx { |
||
| 473 | extern ubyte DemoDoingRight,DemoDoingLeft; |
||
| 474 | extern fix64 Time_flash_last_played; |
||
| 475 | } |
||
| 476 | #endif |
||
| 477 | |||
| 478 | #if DXX_USE_EDITOR |
||
| 479 | #ifdef dsx |
||
| 480 | namespace dsx { |
||
| 481 | void dump_used_textures_all(); |
||
| 482 | void move_player_2_segment(vmsegptridx_t seg, unsigned side); |
||
| 483 | } |
||
| 484 | #endif |
||
| 485 | #endif |
||
| 486 | |||
| 487 | #endif |