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 |