1 #include "3dc.h"
2 #include <math.h>
3 #include "inline.h"
4 #include "module.h"
5
6 #include "stratdef.h"
7 #include "gamedef.h"
8 #include "game_statistics.h"
9 #include "messagehistory.h"
10 #include "dynblock.h"
11 #include "dynamics.h"
12
13 #include "bh_types.h"
14 #include "bh_alien.h"
15 #include "pheromon.h"
16 #include "pfarlocs.h"
17 #include "bh_gener.h"
18 #include "pvisible.h"
19 #include "lighting.h"
20 #include "bh_pred.h"
21 #include "bh_lift.h"
22 #include "avpview.h"
23 #include "psnd.h"
24 #include "psndplat.h"
25 #include "particle.h"
26 #include "sfx.h"
27 #include "fmv.h"
28 #include "version.h"
29 #include "bh_rubberduck.h"
30 #include "bh_marin.h"
31 #include "dxlog.h"
32 #include "avp_menus.h"
33 #include "avp_userprofile.h"
34 #include "davehook.h"
35 #include "cdtrackselection.h"
36 #include "savegame.h"
37 // Added 18/11/97 by DHM: all hooks for my code
38
39 #define UseLocalAssert Yes
40 #include "ourasert.h"
41
42 #include "vision.h"
43
44 #include "cheat.h"
45 #include "pldnet.h"
46
47 #include "kshape.h"
48 #include "game.h"
49
50 /* KJL 16:00:13 11/22/96 - One of my evil experiments.... */
51 #define PENTIUM_PROFILING_ON 0
52
53 #define PROFILING_ON 0
54
55 #if PENTIUM_PROFILING_ON
56 #include "pentime.h"
57 #else
58 #define gProfileStart();
59 #define ProfileStop(x);
60 #endif
61
62 #define VERSION_DisableStartupMenus Yes
63 #define VERSION_DisableStartupCredits Yes
64
65 /******************
66 Extern Engine Varibles
67 ******************/
68
69 extern int VideoMode;
70
71 extern int FrameRate;
72 extern int NormalFrameTime;
73 extern int FrameRate;
74
75 extern int HWAccel;
76 extern int Resolution;
77
78 unsigned char Null_Name[8];
79
80 extern int PlaySounds;
81
82 /*******************************
83 EXPORTED GLOBALS
84 *******************************/
85
86
87 AVP_GAME_DESC AvP; /* game description */
88
89 char projectsubdirectory[] = {"avp/"};
90 int SavedFrameRate;
91 int SavedNormalFrameTime;
92
93
94 /* Andy 13/10/97
95
96 This global is set by any initialisation routine if a call to AllocateMem fails.
97 It can be checked during debugging after all game and level initialisation to see
98 if we have run out of memory.
99 */
100 int memoryInitialisationFailure = 0;
101
102
103 /* start inits for the game*/
104
105 void ProcessSystemObjects();
106
107 void LevelSpecificChecks(void);
108
109 /*runtime maintainance*/
110
111 void FindObjectOfFocus();
112 void MaintainPlayer(void);
113
114 extern void CheckCDStatus(void);
115
116 /*********************************************
117
118 Init Game and Start Game
119
120 *********************************************/
121
122
InitGame(void)123 void InitGame(void)
124 {
125 /*
126 RWH
127 InitGame is to be used only to set platform independent
128 varibles. It will be called ONCE only by the game
129 */
130
131 /***** Set up default game settings*/
132
133 AvP.Language = I_English;
134 AvP.GameMode = I_GM_Playing;
135 AvP.Network = I_No_Network;
136 AvP.Difficulty = I_Medium;
137
138 // Modified by Edmond for Mplayer demo
139 #ifdef MPLAYER_DEMO
140 AvP.StartingEnv = I_Dml1;
141 #else
142 AvP.StartingEnv = I_Entrance;
143 #endif
144 AvP.CurrentEnv = AvP.StartingEnv;
145 AvP.PlayerType = I_Marine;
146
147 AvP.GameVideoRequestMode = VideoMode_DX_320x200x8; /* ignored */
148 if(HWAccel)
149 AvP.MenuVideoRequestMode = VideoMode_DX_640x480x15;
150 else
151 AvP.MenuVideoRequestMode = VideoMode_DX_640x480x8;
152
153 AvP.ElapsedSeconds = 0;
154 AvP.ElapsedMinutes = 0;
155 AvP.ElapsedHours = 0;
156
157 AvP.NetworkAIServer = 0;
158
159
160 // Added by DHM 18/11/97: Hook for my initialisation code:
161 DAVEHOOK_Init();
162
163 /* KJL 15:17:35 28/01/98 - Initialise console variables */
164 {
165 extern void CreateGameSpecificConsoleVariables(void);
166 extern void CreateGameSpecificConsoleCommands(void);
167
168 extern void CreateMoreGameSpecificConsoleVariables(void);
169
170 /* KJL 12:03:18 30/01/98 - Init console variables and commands */
171 CreateGameSpecificConsoleVariables();
172 CreateGameSpecificConsoleCommands();
173
174 /* Next one is CDF's */
175 CreateMoreGameSpecificConsoleVariables();
176 }
177 #if DEATHMATCH_DEMO
178 SetToMinimalDetailLevels();
179 #else
180 SetToDefaultDetailLevels();
181 #endif
182 }
183
184 extern void create_strategies_from_list ();
185 extern void AssignAllSBNames();
186 extern BOOL Current_Level_Requires_Mirror_Image();
187
StartGame(void)188 void StartGame(void)
189 {
190 /* called whenever we start a game (NOT when we change */
191 /* environments - destroy anything from a previous game*/
192
193 /*
194 Temporarily disable sounds while loading. Largely to avoid
195 some irritating teletext sounds starting up
196 */
197 int playSoundsStore=PlaySounds;
198 PlaySounds=0;
199
200 //get the cd to start again at the beginning of the play list.
201 ResetCDPlayForLevel();
202
203
204 ProcessSystemObjects();
205
206 create_strategies_from_list ();
207 AssignAllSBNames();
208
209 SetupVision();
210 /*-------------- Patrick 11/1/97 ----------------
211 Initialise visibility system and NPC behaviour
212 systems for new level.
213 -----------------------------------------------*/
214
215 InitObjectVisibilities();
216 InitPheromoneSystem();
217 BuildFarModuleLocs();
218 InitHive();
219 InitSquad();
220
221 InitialiseParticleSystem();
222 InitialiseSfxBlocks();
223 InitialiseLightElementSystem();
224
225 AvP.DestructTimer=-1;
226
227 // DHM 18/11/97: I've put hooks for screen mode changes here for the moment:
228 DAVEHOOK_ScreenModeChange_Setup();
229 DAVEHOOK_ScreenModeChange_Cleanup();
230
231 #if MIRRORING_ON
232 if(Current_Level_Requires_Mirror_Image())
233 {
234 CreatePlayersImageInMirror();
235 }
236 #endif
237
238 /* KJL 16:13:30 01/05/98 - rubber ducks! */
239 CreateRubberDucks();
240
241 CheckCDStatus();
242
243 {
244 extern int LeanScale;
245 if (AvP.PlayerType==I_Alien)
246 {
247 LeanScale=ONE_FIXED*3;
248 }
249 else
250 {
251 LeanScale=ONE_FIXED;
252 }
253 }
254 {
255 extern SCREENDESCRIPTORBLOCK ScreenDescriptorBlock;
256 extern int MotionTrackerScale;
257 MotionTrackerScale = DIV_FIXED(ScreenDescriptorBlock.SDB_Width,640);
258 }
259 // BuildInvSqrtTable();
260
261 InitialiseTriggeredFMVs();
262 CreateStarArray();
263
264 {
265 //check the containing modules for preplaced decals
266 void check_preplaced_decal_modules();
267 check_preplaced_decal_modules();
268 }
269
270 CurrentGameStats_Initialise();
271 MessageHistory_Initialise();
272
273 if (DISCOINFERNO_CHEATMODE || TRIPTASTIC_CHEATMODE)
274 {
275 MakeLightElement(&Player->ObWorld,LIGHTELEMENT_ROTATING);
276 }
277
278 //restore the play sounds setting
279 PlaySounds=playSoundsStore;
280
281 //make sure the visibilities are up to date
282 Global_VDB_Ptr->VDB_World = Player->ObWorld;
283 AllNewModuleHandler();
284 DoObjectVisibilities();
285 }
286
287
288 #define FIXED_MINUTE ONE_FIXED*60
289
DealWithElapsedTime()290 void DealWithElapsedTime()
291 {
292 AvP.ElapsedSeconds += NormalFrameTime;
293
294 if(AvP.ElapsedSeconds >= FIXED_MINUTE)
295 {
296 AvP.ElapsedSeconds -= FIXED_MINUTE;
297 AvP.ElapsedMinutes ++;
298 }
299
300 if(AvP.ElapsedMinutes >= 60)
301 {
302 AvP.ElapsedMinutes -= 60;
303 AvP.ElapsedHours ++;
304 }
305 }
306
307
308
309 /**********************************************
310
311 Main Loop Game Functions
312
313 **********************************************/
UpdateGame(void)314 void UpdateGame(void)
315 {
316 /* Read Keyboard, Keypad, Joystick etc. */
317 ReadUserInput();
318
319 /* DHM 18/11/97: hook for my code */
320 #if PENTIUM_PROFILING_ON
321 ProfileStart();
322 #endif
323 DAVEHOOK_Maintain();
324 #if PENTIUM_PROFILING_ON
325 ProfileStop("DAEMON");
326 #endif
327
328 /*-------------- Patrick 14/11/96 ----------------
329 call the pheronome system maintainence functions
330 -------------------------------------------------*/
331 #if PENTIUM_PROFILING_ON
332 ProfileStart();
333 #endif
334 PlayerPheromoneSystem();
335 AiPheromoneSystem();
336 #if PENTIUM_PROFILING_ON
337 ProfileStop("PHEROMONE");
338 #endif
339
340 /*-------------- Patrick 11/1/97 ----------------
341 Call the alien hive management function
342 -------------------------------------------------*/
343 DoHive();
344 DoSquad();
345
346
347 #if PROFILING_ON
348 ProfileStart();
349 #endif
350 ObjectBehaviours();
351 #if PROFILING_ON
352 ProfileStop("BEHAVS");
353 #endif
354
355 /* KJL 10:32:55 09/24/96 - update player */
356 #if PENTIUM_PROFILING_ON
357 ProfileStart();
358 #endif
359 MaintainPlayer();
360 #if PENTIUM_PROFILING_ON
361 ProfileStop("MNT PLYR");
362 #endif
363
364 /* KJL 12:54:08 21/04/98 - make sure the player's matrix is always normalised */
365 #if PENTIUM_PROFILING_ON
366 ProfileStart();
367 #endif
368 MNormalise(&(Player->ObStrategyBlock->DynPtr->OrientMat));
369 #if PENTIUM_PROFILING_ON
370 ProfileStop("MNorm");
371 #endif
372
373 /* netgame support: it seems necessary to collect all our messages here, as some
374 things depend on the player's behaviour running before anything else...
375 including firing the player's weapon */
376 if(AvP.Network != I_No_Network) NetCollectMessages();
377
378 RemoveDestroyedStrategyBlocks();
379
380 {
381
382 if(SaveGameRequest != SAVELOAD_REQUEST_NONE)
383 {
384 SaveGame();
385 }
386 else if(LoadGameRequest != SAVELOAD_REQUEST_NONE)
387 {
388 LoadSavedGame();
389 }
390 }
391
392 #if PENTIUM_PROFILING_ON
393 ProfileStart();
394 #endif
395 ObjectDynamics();
396 #if PENTIUM_PROFILING_ON
397 ProfileStop("DYNAMICS");
398 #endif
399
400 // now for the env teleports
401
402 if(RequestEnvChangeViaLift)
403 {
404 CleanUpLiftControl();
405 }
406
407 #if 0
408 Player->ObStrategyBlock->DynPtr->Position.vx = -71893;
409 Player->ObStrategyBlock->DynPtr->Position.vy = 36000;
410 Player->ObStrategyBlock->DynPtr->Position.vz = -52249;
411 Player->ObWorld.vx = -71893;
412 Player->ObWorld.vy = 36000;
413 Player->ObWorld.vz = -42249;
414 #endif
415 /* netgame support */
416 if(AvP.Network != I_No_Network) NetSendMessages();
417
418 /* KJL 11:50:18 03/21/97 - cheat modes */
419 HandleCheatModes();
420
421 /*------------Patrick 1/6/97---------------
422 New sound system
423 -------------------------------------------*/
424 #if PENTIUM_PROFILING_ON
425 ProfileStart();
426 #endif
427
428 if(playerPherModule)
429 {
430 PlatSetEnviroment(playerPherModule->m_sound_env_index,playerPherModule->m_sound_reverb);
431 }
432 SoundSys_Management();
433 DoPlayerSounds();
434 #if PENTIUM_PROFILING_ON
435 ProfileStop("SOUND SYS");
436 #endif
437
438 LevelSpecificChecks();
439 // NormaliseTest();
440 MessageHistory_Maintain();
441
442 if(AvP.LevelCompleted)
443 {
444 /*
445 If player is dead and has also completed level , then cancel
446 level completion.
447 */
448 PLAYER_STATUS* PlayerStatusPtr = (PLAYER_STATUS*) Player->ObStrategyBlock->SBdataptr;
449 if(!PlayerStatusPtr->IsAlive)
450 {
451 AvP.LevelCompleted=0;
452 }
453 }
454
455 if (TRIPTASTIC_CHEATMODE)
456 {
457 extern int TripTasticPhase;
458 extern int CloakingPhase;
459 int a = GetSin(CloakingPhase&4095);
460 TripTasticPhase = MUL_FIXED(MUL_FIXED(a,a),128)+64;
461 }
462 if (JOHNWOO_CHEATMODE)
463 {
464 extern int LeanScale;
465 extern int TimeScale;
466 TimeScaleThingy();
467
468 //in john woo mode leanscale is dependent on the TimeScale
469 if (AvP.PlayerType==I_Alien)
470 {
471 LeanScale=ONE_FIXED*3;
472 }
473 else
474 {
475 LeanScale=ONE_FIXED;
476 }
477
478 LeanScale+=(ONE_FIXED-TimeScale)*5;
479
480 }
481
482
483 }
484
485
486
487
488
489 /* MODULE CALL BACK FUNCTIONS .... */
490
491
492
ModuleObjectJustAllocated(MODULE * mptr)493 void ModuleObjectJustAllocated(MODULE *mptr)
494 {
495 }
496
497
ModuleObjectAboutToBeDeallocated(MODULE * mptr)498 void ModuleObjectAboutToBeDeallocated(MODULE *mptr)
499 {
500 }
501
502
NewAndOldModules(int num_new,MODULE ** m_new,int num_old,MODULE ** m_old,char * m_currvis)503 void NewAndOldModules(int num_new, MODULE **m_new, int num_old, MODULE **m_old, char *m_currvis)
504 {
505
506 /* this is the important bit */
507 DoObjectVisibilities();
508
509 }
510
511
LevelSpecificChecks(void)512 void LevelSpecificChecks(void)
513 {
514 /* ahem, level specific hacks might be more accurate */
515 }
516
CheckCDStatus(void)517 extern void CheckCDStatus(void)
518 {
519 #if PREDATOR_DEMO||MARINE_DEMO||ALIEN_DEMO
520 // CDCommand_PlayLoop(2);
521 #endif
522 }
523
524
525
TimeStampedMessage(char * stringPtr)526 void TimeStampedMessage(char *stringPtr)
527 {
528 #if 0
529 static int time=0;
530 int t=timeGetTime();
531 LOGDXFMT(("%s %fs\n",stringPtr,(float)(t-time)/1000.0f ));
532 time = t;
533 #endif
534 }
535