4b825dc642cb6eb9a060e54bf8d69288fbee4904ebd360ec63ec976c05699f3180e866b3f69e5472
 
 
1
#include <unistd.h>
 
 
2
#include <GL/gl.h>
 
 
3
#include <libpng/png.h>
 
 
4
#include "system.h"
 
 
5
#include "species_sound.h"
 
 
6
#include "stratdef.h"
 
 
7
#include "bh_types.h"
 
 
8
#include "weapons.h"
 
 
9
#include "net.h"
 
 
10
#include "psndplat.h"
 
 
11
#include "hud.h"
 
 
12
#include "dynamics.h"
 
 
13
#include "pheromon.h"
 
 
14
#include "pfarlocs.h"
 
 
15
#include "generator.h"
 
 
16
#include "pvisible.h"
 
 
17
#include "lighting.h"
 
 
18
#include "npc_marine.h"
 
 
19
#include "userprofile.h"
 
 
20
#include "savegame.h"
 
 
21
#include "kshape.h"
 
 
22
#include "paintball.h"
 
 
23
#include "frustum.h"
 
 
24
#include "files.h"
 
 
25
 
 
 
26
extern int load_level(const char * fname, int);
 
 
27
extern void EmptyHierarchyLibrary();
 
 
28
extern void PurgeMSLShapeList();
 
 
29
extern void Deallocate_cplusplus();
 
 
30
extern void create_strategies_from_list();
 
 
31
extern void roll_credits();
 
 
32
extern void shutdown_network();
 
 
33
extern void DeallocateEnvImages();
 
 
34
extern void DeallocateModules();
 
 
35
extern void BuildMultiplayerLevelNameArray();
 
 
36
extern void PlayerDamagedOverlay(int intensity);
 
 
37
extern void Generate_Sphere();
 
 
38
extern void AddShapes();
 
 
39
extern int InitPlayer();
 
 
40
extern int InitTimer();
 
 
41
extern void PlayerBehaviour();
 
 
42
extern void shuffle_textures();
 
 
43
extern void assign_textures();
 
 
44
extern void mission_messages_add(const char *);
 
 
45
extern void InitGameDirectories(char *argv0);
 
 
46
extern int LoadCommonTextures();
 
 
47
extern void ThisFramesRenderingHasFinished();
 
 
48
extern void ThisFramesRenderingHasBegun();
 
 
49
extern void RenderStringCentred(char *stringPtr, int centreX, int y, int colour);
 
 
50
extern void ConstructOneOverSinTable();
 
 
51
extern int Destroy_CurrentEnvironment();
 
 
52
extern void FadeDownScreen(int brightness, int colour);
 
 
53
extern int InitNPCs();
 
 
54
extern void DeallocateAllImages();
 
 
55
extern void InitOpenGL();
 
 
56
extern void ResetOpenGL();
 
 
57
extern void RequestChangeOfWeaponNo(int weapon_nr);
 
 
58
extern void cleanup_strings();
 
 
59
 
 
 
60
SCREENDESCRIPTORBLOCK ScreenDescriptorBlock;
 
 
61
extern int CloakingPhase;
 
 
62
extern int numVisMods;
 
 
63
extern int numVisObjs;
 
 
64
extern int CheaterCounter;
 
 
65
extern int LevelHasStars;
 
 
66
extern int DrawingAReflection;
 
 
67
extern int current_decal_index;
 
 
68
extern int NumActiveDecals;
 
 
69
extern int PlanarGravity;
 
 
70
 
 
 
71
extern SCENEMODULE MainScene;
 
 
72
 
 
 
73
AVP_GAME_DESC AvP = { I_Marine, SinglePlayer, I_Medium, 0, 0,0,0,0,0,0,0,{'\0'} };
 
 
74
 
 
 
75
static SDL_Surface *surface = NULL;
 
 
76
static SDL_Rect **modes = NULL;
 
 
77
 
 
 
78
char * mission_messages = NULL;
 
 
79
const uint8_t Null_Name[8] = { '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0' };
 
 
80
 
 
 
81
uint8_t* Keyboard;
 
 
82
int32_t lastTickCount;
 
 
83
 
 
 
84
struct shapeheader** mainshapelist;
 
 
85
 
 
 
86
int maxshapes = 2500;
 
 
87
int render_sky = 0;
 
 
88
int memoryInitialisationFailure = 0;
 
 
89
static int FrameRate;
 
 
90
int PrevNormalFrameTime;
 
 
91
int TimeScale = 65536;
 
 
92
int NormalFrameTime;
 
 
93
int RealFrameTime;
 
 
94
int GlobalFrameCounter;
 
 
95
int RouteFinder_CallsThisFrame;
 
 
96
unsigned int mission_messages_timer = 0;
 
 
97
int number_of_available_keys = 0;
 
 
98
int show_console = 0;
 
 
99
char current_key_pressed;
 
 
100
uint8_t GotAnyKey = 0;
 
 
101
 
 
 
102
static int max_videomodes;
 
 
103
static int current_video_mode_index = 0;
 
 
104
 
 
 
105
int SetVideoMode()
 
 
106
{
 
 
107
    int width = UserProfile.screen.width;
 
 
108
    int height = UserProfile.screen.height;
 
 
109
 
 
 
110
    if (NULL != (surface = SDL_SetVideoMode(width, height, 0, SDL_OPENGL | (UserProfile.fullscreen ? SDL_FULLSCREEN : 0)))) 
 
 
111
    {
 
 
112
        ScreenDescriptorBlock.SDB_Width     = width;
 
 
113
        ScreenDescriptorBlock.SDB_Height    = height;
 
 
114
        ScreenDescriptorBlock.SDB_CentreX   = width / 2;
 
 
115
        ScreenDescriptorBlock.SDB_CentreY   = height / 2;
 
 
116
        glViewport(0, 0, width, height);
 
 
117
        return 1;
 
 
118
    }
 
 
119
 
 
 
120
    fprintf(stderr, "(OpenGL) SDL SetVideoMode failed: %s\n", SDL_GetError());
 
 
121
 
 
 
122
return 0;
 
 
123
}
 
 
124
 
 
 
125
void toggle_mouse_grab()
 
 
126
{
 
 
127
    SDL_WM_GrabInput(((SDL_GRAB_OFF == SDL_WM_GrabInput(SDL_GRAB_QUERY)) ? SDL_GRAB_ON : SDL_GRAB_OFF));
 
 
128
}
 
 
129
 
 
 
130
static int InitSDL()
 
 
131
{
 
 
132
    if (!SDL_Init(SDL_INIT_VIDEO)) 
 
 
133
    {
 
 
134
        SDL_ShowCursor(0);
 
 
135
        SDL_EnableUNICODE(1);
 
 
136
        Keyboard = SDL_GetKeyState(&number_of_available_keys);
 
 
137
        int number_of_available_keys;
 
 
138
 
 
 
139
        atexit(SDL_Quit);
 
 
140
 
 
 
141
        if( (-1 != UserProfile.screen.height) && (-1 != UserProfile.screen.width)
 
 
142
        &&
 
 
143
        (!SDL_VideoModeOK(UserProfile.screen.height, UserProfile.screen.height, 0, SDL_OPENGL | (UserProfile.fullscreen ? SDL_FULLSCREEN : 0))))
 
 
144
        {
 
 
145
        }
 
 
146
        else
 
 
147
        {
 
 
148
            modes = SDL_ListModes(NULL, SDL_OPENGL | SDL_FULLSCREEN);
 
 
149
 
 
 
150
            if (NULL != modes)
 
 
151
            {
 
 
152
                if(((SDL_Rect**)-1) == modes) 
 
 
153
                {
 
 
154
                    const SDL_VideoInfo *video_info = SDL_GetVideoInfo();
 
 
155
                    UserProfile.screen.width = video_info->current_w;
 
 
156
                    UserProfile.screen.height = video_info->current_h;
 
 
157
                }
 
 
158
                else
 
 
159
                {
 
 
160
                    for (max_videomodes=0; modes[max_videomodes]; max_videomodes++)
 
 
161
                    {
 
 
162
                        UserProfile.screen.width = modes[max_videomodes]->w;
 
 
163
                        UserProfile.screen.height = modes[max_videomodes]->h;
 
 
164
                    }
 
 
165
                }
 
 
166
            }
 
 
167
        }
 
 
168
 
 
 
169
        return SetVideoMode();
 
 
170
    }
 
 
171
 
 
 
172
    fprintf(stderr, "%s\n", SDL_GetError());
 
 
173
 
 
 
174
return 0;
 
 
175
}
 
 
176
 
 
 
177
void change_video_mode(int next)
 
 
178
{
 
 
179
    if (NULL == modes)
 
 
180
    {
 
 
181
        modes = SDL_ListModes(NULL, SDL_OPENGL | SDL_FULLSCREEN);
 
 
182
 
 
 
183
        if ((NULL == modes) || ((SDL_Rect**)-1) == modes) 
 
 
184
            return;
 
 
185
 
 
 
186
        for (max_videomodes=0; modes[max_videomodes]; max_videomodes++)
 
 
187
        {}
 
 
188
    }
 
 
189
 
 
 
190
    if ((NULL != modes) && ((SDL_Rect**)-1) != modes) 
 
 
191
    {
 
 
192
        if(next)
 
 
193
        {
 
 
194
            if(current_video_mode_index >= max_videomodes -1)
 
 
195
                current_video_mode_index = 0;
 
 
196
            else
 
 
197
                current_video_mode_index++;
 
 
198
        }
 
 
199
        else
 
 
200
        {
 
 
201
            if(current_video_mode_index <= 0)
 
 
202
                current_video_mode_index = --max_videomodes;
 
 
203
            else
 
 
204
                current_video_mode_index--;
 
 
205
        }
 
 
206
 
 
 
207
        UserProfile.screen.width = modes[current_video_mode_index]->w;
 
 
208
        UserProfile.screen.height = modes[current_video_mode_index]->h;
 
 
209
 
 
 
210
        SetVideoMode();
 
 
211
    }
 
 
212
}
 
 
213
 
 
 
214
#define TimerFrame    1000
 
 
215
 
 
 
216
/*
 
 
217
    Timer functions are based on Windows timer
 
 
218
    giving number of millisecond ticks since Windows
 
 
219
    was last booted.  Note this will wrap round after
 
 
220
    Windows has been up continuously for  approximately
 
 
221
    49.7 days.  This is not considered to be too
 
 
222
    significant a limitation...
 
 
223
*/
 
 
224
 
 
 
225
static void ResetFrameCounter()
 
 
226
{
 
 
227
    InitTimer();
 
 
228
    lastTickCount = timeGetTime();
 
 
229
 
 
 
230
    /* KJL 15:03:33 12/16/96 - I'm setting NormalFrameTime too, rather than checking that it's
 
 
231
    non-zero everytime I have to divide by it, since it usually is zero on the first frame. */
 
 
232
    NormalFrameTime = 65536 >> 4;
 
 
233
    PrevNormalFrameTime = RealFrameTime = NormalFrameTime;
 
 
234
    FrameRate = 16;
 
 
235
    GlobalFrameCounter = 0;
 
 
236
    CloakingPhase = 0;
 
 
237
    RouteFinder_CallsThisFrame = 0;
 
 
238
}
 
 
239
 
 
 
240
void FrameCounterHandler()
 
 
241
{
 
 
242
    int newTickCount = timeGetTime();
 
 
243
    int fcnt = newTickCount - lastTickCount;
 
 
244
    lastTickCount = newTickCount;
 
 
245
 
 
 
246
    if (!fcnt)
 
 
247
        fcnt = 1; /* for safety */
 
 
248
 
 
 
249
    FrameRate = TimerFrame / fcnt;
 
 
250
 
 
 
251
    PrevNormalFrameTime = NormalFrameTime;
 
 
252
    RealFrameTime = NormalFrameTime = DIV_FIXED(fcnt, TimerFrame);
 
 
253
 
 
 
254
    if (TimeScale != ONE_FIXED)
 
 
255
        NormalFrameTime = MUL_FIXED(NormalFrameTime, TimeScale);
 
 
256
 
 
 
257
    /* cap NormalFrameTime if frame rate is really low */
 
 
258
    if (NormalFrameTime > 16384)
 
 
259
        NormalFrameTime = 16384;
 
 
260
 
 
 
261
    GlobalFrameCounter++;
 
 
262
    CloakingPhase += NormalFrameTime >> 5;
 
 
263
 
 
 
264
    RouteFinder_CallsThisFrame = 0;
 
 
265
}
 
 
266
 
 
 
267
static void show_mission_messages()
 
 
268
{
 
 
269
    static const int color =((255 << 24) + (95 << 16) + (179 << 8) + 39);
 
 
270
    int x = ScreenDescriptorBlock.SDB_CentreX;
 
 
271
    int y = ScreenDescriptorBlock.SDB_Width/8;
 
 
272
    int len = strlen(mission_messages);
 
 
273
 
 
 
274
    if (len < 71)
 
 
275
    {
 
 
276
        RenderStringCentred(mission_messages, x , y, color);
 
 
277
    }
 
 
278
    else
 
 
279
    {
 
 
280
        char *ptr = malloc(len + 1);
 
 
281
 
 
 
282
        if (ptr)
 
 
283
        {
 
 
284
            int i = 0;
 
 
285
            int height = 0;
 
 
286
            strcpy(ptr, mission_messages);
 
 
287
            char *ptr_mesg_org = ptr;
 
 
288
 
 
 
289
            for (; i < len; i++)
 
 
290
            {
 
 
291
                switch(ptr[i])
 
 
292
                {
 
 
293
                    case '\n':
 
 
294
                    {
 
 
295
                        height += 14;
 
 
296
                        ptr[i] = '\0';
 
 
297
                        RenderStringCentred(ptr, x , (y + height), color);
 
 
298
                        ptr += i + 1;
 
 
299
                        len -= i;
 
 
300
                        i = 0;
 
 
301
                    break;
 
 
302
                    }
 
 
303
                    default:
 
 
304
                    break;
 
 
305
                }
 
 
306
            }
 
 
307
 
 
 
308
            height += 14;
 
 
309
            RenderStringCentred(ptr, x , (y + height), color);
 
 
310
 
 
 
311
            free(ptr_mesg_org);
 
 
312
        }
 
 
313
    }
 
 
314
 
 
 
315
    if (mission_messages_timer < timeGetTime())
 
 
316
    {
 
 
317
        mission_messages_add(mission_messages);
 
 
318
        mission_messages = NULL;
 
 
319
        mission_messages_timer = 0;
 
 
320
    }
 
 
321
}
 
 
322
 
 
 
323
int got_any_key()
 
 
324
{
 
 
325
    static int GotAnyKeyDebounced = 0;
 
 
326
 
 
 
327
    if (GotAnyKey)
 
 
328
    {
 
 
329
        if (GotAnyKeyDebounced)
 
 
330
        {
 
 
331
            GotAnyKeyDebounced = 0;
 
 
332
            return 1;
 
 
333
        }
 
 
334
    }
 
 
335
    else
 
 
336
        GotAnyKeyDebounced = 1;
 
 
337
 
 
 
338
return 0;
 
 
339
}
 
 
340
 
 
 
341
static void ScreenShot()
 
 
342
{
 
 
343
    char Name[40]= {'\0'} ;
 
 
344
    int length = strlen("screen_shot");
 
 
345
    sprintf(Name, "screen_shot00.png");
 
 
346
 
 
 
347
    static int image_number = 0;
 
 
348
 
 
 
349
    for(; image_number < 100; image_number++)
 
 
350
    {
 
 
351
        Name[length] = image_number / 10 + '0';
 
 
352
        Name[length+1] = (image_number % 10) + '0';
 
 
353
        FILE* tempfp = OpenGameFile(Name, 1, FILETYPE_CONFIG);
 
 
354
 
 
 
355
        if(!tempfp)
 
 
356
            break;
 
 
357
        else
 
 
358
            fclose(tempfp);
 
 
359
    }
 
 
360
 
 
 
361
    if(100 == image_number)
 
 
362
        return;
 
 
363
 
 
 
364
    png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
 
 
365
 
 
 
366
    if (png_ptr)
 
 
367
    {
 
 
368
        png_infop info_ptr = png_create_info_struct(png_ptr);
 
 
369
 
 
 
370
        if (info_ptr)
 
 
371
        {
 
 
372
            FILE *fp = OpenGameFile(Name, 0, FILETYPE_CONFIG);
 
 
373
 
 
 
374
            if (fp)
 
 
375
            {
 
 
376
                png_init_io(png_ptr, fp);
 
 
377
                png_set_IHDR(png_ptr, info_ptr, surface->w, surface->h, 16, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
PNG_FILTER_TYPE_BASE);
 
 
378
                png_write_info(png_ptr, info_ptr);
 
 
379
 
 
 
380
                unsigned short screenbuf[surface->h][surface->w * 3];
 
 
381
                glReadPixels(0, 0, surface->w, surface->h, GL_RGB, GL_UNSIGNED_SHORT, screenbuf);
 
 
382
 
 
 
383
        #if 0
 
 
384
            {
 
 
385
                int i = surface->h - 1;
 
 
386
                for (; i >= 0; i--)
 
 
387
                    png_write_row(png_ptr, screenbuf[i]);
 
 
388
            }
 
 
389
        #else
 
 
390
            {
 
 
391
                int i = 0;
 
 
392
                unsigned short *rows[surface->h];
 
 
393
 
 
 
394
                for (; i < surface->h; i++)
 
 
395
                    rows[i] = screenbuf[surface->h - i - 1];
 
 
396
 
 
 
397
                png_write_image(png_ptr, rows);
 
 
398
            }
 
 
399
        #endif
 
 
400
                //png_write_end(png_ptr, NULL);
 
 
401
                png_write_flush(png_ptr);
 
 
402
                png_destroy_write_struct(&png_ptr, &info_ptr);
 
 
403
                fclose(fp);
 
 
404
            }
 
 
405
            else
 
 
406
            printf("Error creating image file %s\n", Name);
 
 
407
        }
 
 
408
        else
 
 
409
        {
 
 
410
            png_destroy_write_struct(&png_ptr, NULL);
 
 
411
        }
 
 
412
    }
 
 
413
}
 
 
414
 
 
 
415
void read_user_input()
 
 
416
{
 
 
417
    SDL_Event sdl_event;
 
 
418
    current_key_pressed = '\0';
 
 
419
 
 
 
420
    Keyboard[SDL_BUTTON_WHEELUP] = Keyboard[SDL_BUTTON_WHEELDOWN] = GotAnyKey = 0;
 
 
421
 
 
 
422
    while (SDL_PollEvent(&sdl_event))
 
 
423
    {
 
 
424
        switch(sdl_event.type)
 
 
425
        {
 
 
426
            case SDL_MOUSEBUTTONDOWN:
 
 
427
                Keyboard[sdl_event.button.button] = GotAnyKey = 1;
 
 
428
            break;
 
 
429
            case SDL_MOUSEBUTTONUP:
 
 
430
                Keyboard[SDL_BUTTON_LEFT] = Keyboard[SDL_BUTTON_RIGHT] = Keyboard[SDL_BUTTON_MIDDLE] = 0;
 
 
431
            break;
 
 
432
            case SDL_KEYDOWN:
 
 
433
            {
 
 
434
                switch(sdl_event.key.keysym.sym)
 
 
435
                {
 
 
436
                    case  SDLK_F2:
 
 
437
                        show_console = !show_console;
 
 
438
                    break;
 
 
439
                    case SDLK_ESCAPE:
 
 
440
                    {
 
 
441
                        extern void TriggerInGameMenus();
 
 
442
                        if (AvP.MainLoopRunning)
 
 
443
                            TriggerInGameMenus();
 
 
444
                    }
 
 
445
                    break;
 
 
446
                    case SDLK_1:
 
 
447
                        if (!PaintBallMode.IsOn)
 
 
448
                            RequestChangeOfWeaponNo(0);
 
 
449
                        else
 
 
450
                            PaintBallMode_ChangeSubclass(+1);
 
 
451
                    break;
 
 
452
                    case SDLK_2:
 
 
453
                        if (!PaintBallMode.IsOn)
 
 
454
                            RequestChangeOfWeaponNo(1);
 
 
455
                        else
 
 
456
                            PaintBallMode_ChangeSubclass(-1);
 
 
457
                    break;
 
 
458
                    case SDLK_3:
 
 
459
                        if (!PaintBallMode.IsOn)
 
 
460
                            RequestChangeOfWeaponNo(2);
 
 
461
                        else
 
 
462
                            PaintBallMode.DecalIsInverted = ~PaintBallMode.DecalIsInverted;
 
 
463
                    break;
 
 
464
                    case SDLK_4:
 
 
465
                        if (!PaintBallMode.IsOn)
 
 
466
                            RequestChangeOfWeaponNo(3);
 
 
467
                        else
 
 
468
                            PaintBallMode_Randomise();
 
 
469
                    break;
 
 
470
                    case SDLK_5:
 
 
471
                            RequestChangeOfWeaponNo(4);
 
 
472
                    break;
 
 
473
                    case SDLK_6:
 
 
474
                            RequestChangeOfWeaponNo(5);
 
 
475
                    break;
 
 
476
                    case SDLK_7:
 
 
477
                            RequestChangeOfWeaponNo(6);
 
 
478
                    break;
 
 
479
                    case SDLK_8:
 
 
480
                            RequestChangeOfWeaponNo(7);
 
 
481
                    break;
 
 
482
                    case SDLK_9:
 
 
483
                            RequestChangeOfWeaponNo(8);
 
 
484
                    break;
 
 
485
                    case SDLK_0:
 
 
486
                            RequestChangeOfWeaponNo(9);
 
 
487
                    default:
 
 
488
                        break;
 
 
489
                }
 
 
490
 
 
 
491
                current_key_pressed = sdl_event.key.keysym.unicode;
 
 
492
 
 
 
493
                GotAnyKey = 1;
 
 
494
            }
 
 
495
            default:
 
 
496
            break;
 
 
497
        }
 
 
498
    }
 
 
499
}
 
 
500
 
 
 
501
static void DoLevelStatisticsScreen()
 
 
502
{
 
 
503
    if(AvP.LevelCompleted)
 
 
504
    {
 
 
505
        SDL_Event sdl_event;
 
 
506
        glClear(GL_COLOR_BUFFER_BIT);
 
 
507
 
 
 
508
        SDL_GL_SwapBuffers();
 
 
509
 
 
 
510
        if ((-1 == AvP.LevelCompleted) || CheaterCounter)
 
 
511
        {
 
 
512
            RenderStringCentred("Level Completed With Cheats", ScreenDescriptorBlock.SDB_CentreX, 20, 0xffff0000);
 
 
513
 
 
 
514
            if(CheaterCounter) // let user complete level if no other cheats is activated, bonus mode will not be unlocked if present.
 
 
515
            {
 
 
516
                RenderStringCentred("Press any key to restart game", ScreenDescriptorBlock.SDB_CentreX, ScreenDescriptorBlock.SDB_Height-20,
0xffffffff);
 
 
517
                AvP.LevelCompleted = 0;
 
 
518
            }
 
 
519
            else
 
 
520
            {
 
 
521
                RenderStringCentred("Press ESCAPE to restart level, or any other key to continue", ScreenDescriptorBlock.SDB_CentreX,
ScreenDescriptorBlock.SDB_Height-20, 0xffffffff);
 
 
522
            }
 
 
523
 
 
 
524
            //if (!deathFadeLevel) 
 
 
525
            //FadeDownScreen(deathFadeLevel, 0);
 
 
526
        }
 
 
527
        else
 
 
528
        {
 
 
529
            //FadeDownScreen(0, 0);
 
 
530
            DoStatisticsScreen();
 
 
531
            RenderStringCentred("Press ESCAPE to restart level, or any other key to continue", ScreenDescriptorBlock.SDB_CentreX,
ScreenDescriptorBlock.SDB_Height-20, 0xffffffff);
 
 
532
        }
 
 
533
 
 
 
534
        SDL_GL_SwapBuffers();
 
 
535
 
 
 
536
        while (SDL_WaitEvent(&sdl_event))
 
 
537
        {
 
 
538
            if(SDL_KEYDOWN == sdl_event.type)
 
 
539
            {
 
 
540
                AvP.RestartLevel = (Keyboard[SDLK_ESCAPE] || !AvP.LevelCompleted);
 
 
541
                glClear(GL_COLOR_BUFFER_BIT);
 
 
542
                show_console = 0;
 
 
543
                break;
 
 
544
            }
 
 
545
        }
 
 
546
    }
 
 
547
}
 
 
548
 
 
 
549
static void load_common_sounds()
 
 
550
{
 
 
551
    extern const char * common_sounds[];
 
 
552
    int soundIndex = 0;
 
 
553
 
 
 
554
    for (; soundIndex < SID_STARTOF_SCREAMSLOTS; soundIndex++)
 
 
555
    {
 
 
556
        if (LoadWavFile(soundIndex, "common", common_sounds[soundIndex]))
 
 
557
        {
 
 
558
            switch(soundIndex)
 
 
559
            {
 
 
560
                case SID_PRED_LAUNCHER:
 
 
561
                    GameSounds[soundIndex].pitch = -3;        
 
 
562
                break;
 
 
563
                case SID_PULSE_START:
 
 
564
                case SID_PULSE_LOOP:
 
 
565
                case SID_PULSE_END:
 
 
566
                case SID_ALIEN_KILL:
 
 
567
                case SID_ACID_SPRAY:
 
 
568
                case SID_DOORSTART:
 
 
569
                case SID_DOORMID:
 
 
570
                case SID_NOAMMO:
 
 
571
                    GameSounds[soundIndex].pitch = -2;        
 
 
572
                break;
 
 
573
                case SID_TELETEXT:
 
 
574
                case SID_PRED_VISION_ON:
 
 
575
                case SID_INCIN_START:
 
 
576
                case SID_INCIN_LOOP:
 
 
577
                case SID_INCIN_END:
 
 
578
                case SID_SHOTGUN:
 
 
579
                case SID_SMART1:
 
 
580
                case SID_SMART2:
 
 
581
                case SID_SMART3:
 
 
582
                case SID_EXPLOSION:
 
 
583
                    GameSounds[soundIndex].pitch = -4;        
 
 
584
                break;
 
 
585
                default:
 
 
586
                    continue;
 
 
587
            }
 
 
588
                /* pitch offset is in semitones: need to convert to 1/128ths */
 
 
589
                InitialiseBaseFrequency(soundIndex);
 
 
590
        }
 
 
591
    }
 
 
592
}
 
 
593
 
 
 
594
static void Game_Has_Loaded()
 
 
595
{
 
 
596
    do
 
 
597
    {
 
 
598
        glClear(GL_COLOR_BUFFER_BIT);
 
 
599
 
 
 
600
        ThisFramesRenderingHasBegun();
 
 
601
 
 
 
602
        RenderStringCentred("Press any key to continue", ScreenDescriptorBlock.SDB_CentreX, (ScreenDescriptorBlock.SDB_Height*23)/24-9, 0xffffffff);
 
 
603
 
 
 
604
        SDL_GL_SwapBuffers();
 
 
605
 
 
 
606
        FrameCounterHandler();
 
 
607
 
 
 
608
        /* If in a network game then we may as well check the network messages while waiting*/
 
 
609
        if(SinglePlayer != AvP.PlayMode)
 
 
610
        {
 
 
611
            //send messages , mainly  needed so that the host will send the game description
 
 
612
            //allowing people to join while the host is loading
 
 
613
            NetSendMessages();
 
 
614
        }
 
 
615
 
 
 
616
        read_user_input();
 
 
617
 
 
 
618
        /* after this call, no more graphics can be drawn until the next frame */
 
 
619
        ThisFramesRenderingHasFinished();
 
 
620
 
 
 
621
    } while(!got_any_key());
 
 
622
}
 
 
623
 
 
 
624
int main(int argc, char *argv[])
 
 
625
{
 
 
626
    InitGameDirectories(argv[0]);
 
 
627
    LoadUserProfile();
 
 
628
 
 
 
629
    if (!InitSDL())
 
 
630
    {
 
 
631
        fprintf(stderr, "Could not find a sutable resolution!\n");
 
 
632
        fprintf(stderr, "At least 640x480 is needed.  Does OpenGL work?\n");
 
 
633
        return 1;
 
 
634
    }
 
 
635
 
 
 
636
    mainshapelist = calloc(maxshapes, sizeof(struct shapeheader*));
 
 
637
 
 
 
638
    if(!mainshapelist)
 
 
639
    {
 
 
640
        exit(EXIT_FAILURE);
 
 
641
    }
 
 
642
    else
 
 
643
    {
 
 
644
        int i;
 
 
645
        for(i = 0; i < maxshapes; i++)
 
 
646
            mainshapelist[i] = NULL;
 
 
647
    }
 
 
648
 
 
 
649
    SetDefaultMultiplayerConfig();
 
 
650
    SetFastRandom();
 
 
651
        ConstructOneOverSinTable();
 
 
652
    BuildMultiplayerLevelNameArray();
 
 
653
    InitialiseDynamicsBlocks();
 
 
654
    InitialiseStrategyBlocks();
 
 
655
    InitialiseLightBlocks();
 
 
656
    init_sky();
 
 
657
    Generate_Sphere();
 
 
658
 
 
 
659
    if (PlatStartSoundSys())
 
 
660
    {
 
 
661
        load_common_sounds();
 
 
662
        LoadSpeciesSounds();
 
 
663
    }
 
 
664
 
 
 
665
    if(UserProfile.grabmouse)
 
 
666
        toggle_mouse_grab();
 
 
667
 
 
 
668
    if(LoadCommonTextures() && InitNPCs())
 
 
669
    {
 
 
670
        //PlayIntroSequence();
 
 
671
        int random_textures = (UserProfile.CheatMode[CHEATMODE_RANDOMTEXTURES] && (CHEATMODE_RANDOMTEXTURES == UserProfile.active_bonus));
 
 
672
 
 
 
673
        if (!random_textures)
 
 
674
            assign_textures(); //to npc and player
 
 
675
 
 
 
676
        InitOpenGL();
 
 
677
 
 
 
678
        while(AvP.RestartLevel || (LoadGameRequest != SAVELOAD_REQUEST_NONE ) || MainMenus())
 
 
679
        {
 
 
680
            CheaterCounter = 0;
 
 
681
            DrawingAReflection = 0;
 
 
682
            numVisMods = numVisObjs = 0;
 
 
683
            NumActiveLightElements = 0;
 
 
684
            NumActiveDecals = current_decal_index = 0;
 
 
685
 
 
 
686
            ResetFrameCounter();
 
 
687
            InitHive();
 
 
688
            InitSquad();
 
 
689
            CurrentGameStats_Initialise();
 
 
690
            InitialiseTxAnimBlocks(); 
 
 
691
            InitialiseObjectBlocks();
 
 
692
            InitialiseParticleSystem();
 
 
693
            InitialiseSfxBlocks();
 
 
694
 
 
 
695
            if(!AvP.RestartLevel)
 
 
696
            {
 
 
697
                //PrintHierarchyLibrary();
 
 
698
                MirroringActive = 0;
 
 
699
 
 
 
700
                if (!load_level(AvP.LevelName, UserProfile.GameOptions.MapPrelighting))
 
 
701
                    break;
 
 
702
 
 
 
703
                assign_textures(); // to level
 
 
704
 
 
 
705
                if (random_textures)
 
 
706
                    shuffle_textures();
 
 
707
            }
 
 
708
            else
 
 
709
            {
 
 
710
                //reset the displayblock for modules to 0
 
 
711
                int i=2;
 
 
712
 
 
 
713
                while(!MainScene.sm_module[i].end_module)
 
 
714
                    MainScene.sm_module[i++].m_dptr = NULL;
 
 
715
            }
 
 
716
 
 
 
717
            InitPlayer();
 
 
718
            create_strategies_from_list();
 
 
719
            AssignAllSBNames();
 
 
720
            ActivateHive();
 
 
721
 
 
 
722
            if(SinglePlayer != AvP.PlayMode)
 
 
723
            {
 
 
724
                /*Need to choose a starting position for the player , but first we must look
 
 
725
                through the network messages to find out which generator spots are currently clear*/
 
 
726
                netGameData.myGameState = NGS_Playing;
 
 
727
                TeleportNetPlayerToAStartingPosition(1);
 
 
728
            }
 
 
729
            else
 
 
730
            {
 
 
731
                FrameCounterHandler();
 
 
732
 
 
 
733
                if(LoadSavedGame()) // error occurred; restart level.
 
 
734
                {
 
 
735
                    DestroyAllStrategyBlocks();
 
 
736
                    LoadGameRequest = SAVELOAD_REQUEST_NONE;
 
 
737
                    AvP.RestartLevel = 1;
 
 
738
                    continue;
 
 
739
                }
 
 
740
            }
 
 
741
 
 
 
742
            PlanarGravity = 1;
 
 
743
            TimeScale = ONE_FIXED;
 
 
744
 
 
 
745
            switch(UserProfile.active_bonus)
 
 
746
            {
 
 
747
                case CHEATMODE_FREEFALL:
 
 
748
                    PlanarGravity = 0;
 
 
749
                break;
 
 
750
                case CHEATMODE_DISCOINFERNO:
 
 
751
                case CHEATMODE_TRIPTASTIC:
 
 
752
                    MakeLightElement(&PlayerStatus.DisplayBlock->ObWorld, LIGHTELEMENT_ROTATING);
 
 
753
                break;
 
 
754
                case CHEATMODE_WARPSPEED:
 
 
755
                    TimeScale = 2 * ONE_FIXED;
 
 
756
                break;
 
 
757
                case CHEATMODE_LANDOFTHEGIANTS:
 
 
758
                    TimeScale = ONE_FIXED / 2;
 
 
759
                break;
 
 
760
                case CHEATMODE_UNDERWATER:
 
 
761
                    TimeScale = (ONE_FIXED * 7) / 10;
 
 
762
                default:
 
 
763
                break;
 
 
764
            }
 
 
765
 
 
 
766
            switch(AvP.PlayMode)
 
 
767
            {
 
 
768
                case NetworkPeer:
 
 
769
                case NetworkHost:
 
 
770
                    AvP.Network = 1;
 
 
771
                break;
 
 
772
                default:
 
 
773
                    AvP.Network = 0;
 
 
774
            }
 
 
775
 
 
 
776
    {
 
 
777
    //UserProfile.active_bonus = CHEATMODE_DRAWFULLBRIGHT;
 
 
778
    GiveAllWeaponsCheat();
 
 
779
    //PlayerStatus.sbptr->DamageBlock.Indestructable = 1;
 
 
780
    }
 
 
781
 
 
 
782
            AvP.MainLoopRunning = 1;
 
 
783
            AvP.RestartLevel = 0;
 
 
784
 
 
 
785
            ChooseLightingModel();
 
 
786
 
 
 
787
            //Game_Has_Loaded();
 
 
788
            ResetOpeGL();
 
 
789
 
 
 
790
            while(AvP.MainLoopRunning)
 
 
791
            {
 
 
792
                FrameCounterHandler();
 
 
793
                ThisFramesRenderingHasBegun();
 
 
794
                read_user_input();
 
 
795
                PlayerBehaviour();
 
 
796
                TranslationSetup();
 
 
797
                PlayerPheromoneSystem();
 
 
798
                ModuleHandler();
 
 
799
    //PlayerStatus.sbptr->DamageBlock.Indestructable = 1;
 
 
800
 
 
 
801
//glDepthFunc(GL_ALWAYS);
 
 
802
                ExecuteBehaviour();
 
 
803
//glDepthFunc(GL_FALSE);
 
 
804
                if(render_sky)
 
 
805
                {
 
 
806
                    glClear(GL_COLOR_BUFFER_BIT);
 
 
807
                    LevelHasStars ? RenderStarfield() : RenderSky();
 
 
808
                }
 
 
809
 
 
 
810
                ObjectDynamics();
 
 
811
                UpdateRunTimeLights();
 
 
812
                AddShapes();
 
 
813
                HandleParticleSystem();
 
 
814
 
 
 
815
                if (PlayerStatus.RequestsToStandUp)
 
 
816
                    TestForValidPlayerStandUp(PlayerStatus.sbptr);
 
 
817
 
 
 
818
glClear(GL_DEPTH_BUFFER_BIT);
 
 
819
                if(PlayerStatus.FirstPersonView)
 
 
820
                    PlayerStatus.Hud();
 
 
821
 
 
 
822
                if (mission_messages_timer)
 
 
823
                    show_mission_messages();
 
 
824
 
 
 
825
                if (show_console)
 
 
826
                {
 
 
827
                    static char console_command[30] = {'\0'};
 
 
828
                    static int current_console_text_pos = 0;
 
 
829
 
 
 
830
                    if (Keyboard[SDLK_BACKSPACE])
 
 
831
                    { 
 
 
832
                        if (current_console_text_pos > 0)
 
 
833
                        console_command[--current_console_text_pos] = '\0';
 
 
834
                    }
 
 
835
                    else if (Keyboard[SDLK_RETURN])
 
 
836
                    {
 
 
837
                        extern int parse_and_exec_console_command();
 
 
838
 
 
 
839
                        if(parse_and_exec_console_command(console_command))
 
 
840
                        {
 
 
841
                            //memset(console_command, 0, 30);
 
 
842
                            //current_console_text_pos = 0;
 
 
843
                            Sound_Play(SID_MENUS_SELECT_ITEM, "r");
 
 
844
                        }
 
 
845
                    }
 
 
846
                    else if (Keyboard[SDLK_UP] || Keyboard[SDLK_TAB] || Keyboard[SDLK_RIGHT])
 
 
847
                    {
 
 
848
                        extern const char* next_console_command();
 
 
849
                        strncpy(console_command, next_console_command(), 29);
 
 
850
                        current_console_text_pos = strlen(console_command);
 
 
851
                    }
 
 
852
                    else if (Keyboard[SDLK_DOWN] || Keyboard[SDLK_LEFT])
 
 
853
                    {
 
 
854
                        extern const char * prev_console_command();
 
 
855
                        strncpy(console_command, prev_console_command(), 29);
 
 
856
                        current_console_text_pos = strlen(console_command);
 
 
857
                    }
 
 
858
                    else if (current_key_pressed)
 
 
859
                    {
 
 
860
                        if (current_console_text_pos < 30)
 
 
861
                            console_command[current_console_text_pos++] = current_key_pressed;
 
 
862
                    }
 
 
863
 
 
 
864
                    RenderStringCentred("Console", ScreenDescriptorBlock.SDB_CentreX, ScreenDescriptorBlock.SDB_CentreY  -HUD_FONT_HEIGHT *2 ,
0xffff0000);
 
 
865
                    RenderStringCentred(console_command, ScreenDescriptorBlock.SDB_CentreX, ScreenDescriptorBlock.SDB_CentreY, 0xffff0000);
 
 
866
                    memset(Keyboard, 0, number_of_available_keys);
 
 
867
                }
 
 
868
 
 
 
869
                if (PlayerStatus.sbptr->DamageBlock.IsOnFire)
 
 
870
                {
 
 
871
                    extern void PlayerOnFireOverlay();
 
 
872
                    extern int myNetworkKillerId;
 
 
873
                    extern int myIgniterId;
 
 
874
                    extern int AVPDPNetID;
 
 
875
                    DAMAGEBLOCK * player_damage = &PlayerStatus.sbptr->DamageBlock;
 
 
876
 
 
 
877
                    if(PlayerStatus.FirstPersonView)
 
 
878
                        PlayerOnFireOverlay();
 
 
879
 
 
 
880
                    myNetworkKillerId = myIgniterId;
 
 
881
                    CauseDamageToObject(PlayerStatus.sbptr, &damage_profiles[FIREDAMAGE], NormalFrameTime, NULL);
 
 
882
                    myNetworkKillerId = AVPDPNetID;
 
 
883
 
 
 
884
                    if (PlayerStatus.soundCracklingFire != SOUND_NOACTIVEINDEX) 
 
 
885
                        Sound_Update3d(PlayerStatus.soundCracklingFire, &PlayerStatus.sbptr->DynPtr->Position);
 
 
886
                    else
 
 
887
                        Sound_Play(SID_FIRE, "dle", &PlayerStatus.sbptr->DynPtr->Position, &PlayerStatus.soundCracklingFire);
 
 
888
 
 
 
889
                    /* Put the fire out... */
 
 
890
                    if((I_Alien == AvP.PlayerType) && (PlayerStatus.incidentFlag && ((FastRandom() & 65535) < 32767)))
 
 
891
                    {
 
 
892
                        PlayerStatus.sbptr->DamageBlock.IsOnFire = 0;
 
 
893
                        Sound_Stop(PlayerStatus.soundCracklingFire);
 
 
894
                    }
 
 
895
                    else
 
 
896
                    {
 
 
897
                        int speed = Approximate3dMagnitude(&PlayerStatus.sbptr->DynPtr->LinVelocity);
 
 
898
                        /* Go out? */
 
 
899
 
 
 
900
                        if (speed > 22000)
 
 
901
                        {
 
 
902
                            /* Jumping alien. */
 
 
903
                            player_damage->IsOnFire -= NormalFrameTime * 6;
 
 
904
                        }
 
 
905
                        else if (speed > 15000) 
 
 
906
                        {
 
 
907
                            /* Running alien. */
 
 
908
                            player_damage->IsOnFire -= NormalFrameTime << 2;
 
 
909
                        }
 
 
910
                        else 
 
 
911
                        {
 
 
912
                            /* Normal bloke. */
 
 
913
                            player_damage->IsOnFire -= NormalFrameTime;
 
 
914
                        }
 
 
915
 
 
 
916
                        if (player_damage->IsOnFire < 0) 
 
 
917
                        {
 
 
918
                            PlayerStatus.sbptr->DamageBlock.IsOnFire = 0;
 
 
919
                            Sound_Stop(PlayerStatus.soundCracklingFire);
 
 
920
                        }
 
 
921
                    }
 
 
922
                }
 
 
923
                else if (PlayerStatus.DamagedOverlayIntensity)
 
 
924
                {
 
 
925
                    int intensity = PlayerStatus.DamagedOverlayIntensity >> 12;
 
 
926
 
 
 
927
                    if (intensity > 128)
 
 
928
                        intensity = 128;
 
 
929
 
 
 
930
                    if (intensity)
 
 
931
                        PlayerDamagedOverlay(intensity);
 
 
932
 
 
 
933
                    PlayerStatus.DamagedOverlayIntensity -= NormalFrameTime << 5;
 
 
934
 
 
 
935
                    if (PlayerStatus.DamagedOverlayIntensity < 0)
 
 
936
                        PlayerStatus.DamagedOverlayIntensity = 0;
 
 
937
                }
 
 
938
 
 
 
939
                switch(AvP.PlayMode)
 
 
940
                {
 
 
941
                    case SinglePlayer:
 
 
942
                        DoHive();
 
 
943
                    break;
 
 
944
                    case Skirmish:
 
 
945
                        DoMultiplayerSpecificHud();
 
 
946
                        DoHive();
 
 
947
                    break;
 
 
948
                    case NetworkHost:
 
 
949
                        DoHive();
 
 
950
                    case NetworkPeer:
 
 
951
                        NetCollectMessages();
 
 
952
                        NetSendMessages();
 
 
953
                        DoMultiplayerSpecificHud();
 
 
954
                }
 
 
955
 
 
 
956
                SoundSys_Management();
 
 
957
 
 
 
958
                glClear(GL_DEPTH_BUFFER_BIT);
 
 
959
                LightBlockDeallocation();
 
 
960
                ThisFramesRenderingHasFinished();
 
 
961
                SDL_GL_SwapBuffers();
 
 
962
 
 
 
963
                if (Keyboard[SDLK_PRINT])
 
 
964
                    ScreenShot();
 
 
965
 
 
 
966
                //printf("FPS %d\n", FrameRate);
 
 
967
                DoSquad();
 
 
968
 
 
 
969
                AvP.ElapsedSeconds += NormalFrameTime;
 
 
970
 
 
 
971
                if(AvP.ElapsedSeconds  >= FIXED_MINUTE)
 
 
972
                {
 
 
973
                    AvP.ElapsedSeconds -= FIXED_MINUTE;
 
 
974
                    AvP.ElapsedMinutes++;
 
 
975
                }
 
 
976
 
 
 
977
                if(AvP.ElapsedMinutes >= 60)
 
 
978
                {
 
 
979
                    AvP.ElapsedMinutes -= 60;
 
 
980
                    AvP.ElapsedHours++;
 
 
981
                }
 
 
982
            }
 
 
983
 
 
 
984
            SoundSys_ResetFadeLevel();
 
 
985
            SoundSys_StopAll();
 
 
986
            DestroyAllStrategyBlocks();
 
 
987
 
 
 
988
            DoLevelStatisticsScreen();
 
 
989
 
 
 
990
            if(!AvP.RestartLevel)
 
 
991
            {
 
 
992
                if (random_textures)
 
 
993
                    shuffle_textures(); // restore order
 
 
994
 
 
 
995
                DeallocateEnvImages();
 
 
996
                KillFarModuleLocs();
 
 
997
                CleanUpPheromoneSystem();
 
 
998
                DeallocateModules();
 
 
999
                Deallocate_cplusplus();
 
 
1000
 
 
 
1001
                if(SinglePlayer != AvP.PlayMode)
 
 
1002
                    EndAVPNetGame();
 
 
1003
            }
 
 
1004
        }
 
 
1005
    }
 
 
1006
 
 
 
1007
SaveUserProfile();
 
 
1008
//roll_credits();
 
 
1009
EmptyHierarchyLibrary();
 
 
1010
DeallocateAllImages();
 
 
1011
UnloadSpeciesSounds();
 
 
1012
free(mainshapelist);
 
 
1013
cleanup_openal();
 
 
1014
cleanup_strings();
 
 
1015
 
 
 
1016
return 0;
 
 
1017
}