game.cpp 157 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
//-------------------------------------------------------------------------
/*
Copyright (C) 1997, 2005 - 3D Realms Entertainment

This file is part of Shadow Warrior version 1.2

Shadow Warrior is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

Original Source: 1997 - Frank Maddin and Jim Norwood
Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------

// CTW NOTE
/*
Known remaining issues:
- Audio stuttering.
- CD Audio not looping properly (currently hard coded to restart about every 200 seconds.
- Hitting F5 to change resolution causes a crash (currently disabled).
- Multiplayer untested.

Things required to make savegames work:
- Load makesym.wpj and build it.
- In a DOS prompt, run "makesym sw.map swdata.map swcode.map"
- Copy swcode.map to swcode.sym and swdata.map to swdata.sym
*/
// CTW NOTE END

#define MAIN
#define QUIET
#include "build.h"
#include "baselayer.h"
#include "cache1d.h"
#include "osd.h"
48
#include "renderlayer.h"
49
50
51
52
53

#include "keys.h"
#include "names2.h"
#include "panel.h"
#include "game.h"
54
#include "interp.h"
55
#include "interpso.h"
56
57
58
59
60
61
#include "tags.h"
#include "sector.h"
#include "sprite.h"
#include "weapon.h"
#include "player.h"
#include "lists.h"
Evan Ramos's avatar
Evan Ramos committed
62
#include "network.h"
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include "pal.h"
#include "fx_man.h"

#include "mytypes.h"
//#include "config.h"

#include "menus.h"

#include "control.h"
#include "function.h"
#include "gamedefs.h"
#include "config.h"

#include "demo.h"
#include "cache.h"
//#include "exports.h"

#include "anim.h"

#include "colormap.h"
#include "break.h"
#include "ninja.h"
#include "light.h"
#include "track.h"
#include "jsector.h"
#include "keyboard.h"
#include "text.h"
#include "music.h"

92
#include "grpscan.h"
Evan Ramos's avatar
Evan Ramos committed
93
#include "common.h"
Evan Ramos's avatar
Evan Ramos committed
94
95
#include "common_game.h"

96
97
#include "crc32.h"

98
99
100
101
#ifdef _WIN32
# include "winbits.h"
#endif

Evan Ramos's avatar
Evan Ramos committed
102
103
104
105
106
107
const char* AppProperName = "VoidSW";
const char* AppTechnicalName = "voidsw";

#define SETUPFILENAME "voidsw.cfg"
char setupfilename[BMAX_PATH] = SETUPFILENAME;

108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#if DEBUG
#define BETA 0
#endif

#define STAT_SCREEN_PIC 5114
#define TITLE_PIC 2324
#define THREED_REALMS_PIC 2325
#define TITLE_ROT_FLAGS (ROTATE_SPRITE_CORNER|ROTATE_SPRITE_SCREEN_CLIP|ROTATE_SPRITE_NON_MASK)
#define PAL_SIZE (256*3)

char DemoName[15][16];

// Stupid WallMart version!
//#define PLOCK_VERSION TRUE

#if PLOCK_VERSION
Evan Ramos's avatar
Evan Ramos committed
124
SWBOOL Global_PLock = TRUE;
125
#else
Evan Ramos's avatar
Evan Ramos committed
126
SWBOOL Global_PLock = FALSE;
127
128
#endif

129
130
131
// 12 was original source release. For future releases increment by two.
int GameVersion = 15;

132
133
134
char DemoText[3][64];
int DemoTextYstart = 0;

Evan Ramos's avatar
Evan Ramos committed
135
SWBOOL DoubleInitAWE32 = FALSE;
136
137
int Follow_posx=0,Follow_posy=0;

Evan Ramos's avatar
Evan Ramos committed
138
SWBOOL NoMeters = FALSE;
139
140
short IntroAnimCount = 0;
short PlayingLevel = -1;
Evan Ramos's avatar
Evan Ramos committed
141
SWBOOL GraphicsMode = FALSE;
142
143
char CacheLastLevel[32] = "";
char PlayerNameArg[32] = "";
Evan Ramos's avatar
Evan Ramos committed
144
145
146
147
148
149
150
151
152
153
154
155
SWBOOL CleanExit = FALSE;
SWBOOL DemoModeMenuInit = FALSE;
SWBOOL FinishAnim = 0;
SWBOOL ShortGameMode = FALSE;
SWBOOL ReloadPrompt = FALSE;
SWBOOL NewGame = TRUE;
SWBOOL InMenuLevel = FALSE;
SWBOOL LoadGameOutsideMoveLoop = FALSE;
SWBOOL LoadGameFromDemo = FALSE;
SWBOOL ArgCheat = FALSE;
extern SWBOOL NetBroadcastMode, NetModeOverride;
SWBOOL MultiPlayQuitFlag = FALSE;
156
157
158
//Miscellaneous variables
char MessageInputString[256];
char MessageOutputString[256];
Evan Ramos's avatar
Evan Ramos committed
159
160
161
162
163
164
SWBOOL MessageInputMode = FALSE;
SWBOOL ConInputMode = FALSE;
SWBOOL ConPanel = FALSE;
SWBOOL FinishedLevel = FALSE;
SWBOOL HelpInputMode = FALSE;
SWBOOL PanelUpdateMode = TRUE;
165
166
short HelpPage = 0;
short HelpPagePic[] = { 5115, 5116, 5117 };
Evan Ramos's avatar
Evan Ramos committed
167
168
SWBOOL InputMode = FALSE;
SWBOOL MessageInput = FALSE;
169
short screenpeek = 0;
Evan Ramos's avatar
Evan Ramos committed
170
171
172
SWBOOL NoDemoStartup = FALSE;
SWBOOL FirstTimeIntoGame;
extern uint8_t RedBookSong[40];
173

174
175
SWBOOL PedanticMode;

Evan Ramos's avatar
Evan Ramos committed
176
177
178
SWBOOL BorderAdjust = TRUE;
SWBOOL LocationInfo = 0;
void drawoverheadmap(int cposx, int cposy, int czoom, short cang);
179
180
181
182
int DispFrameRate = FALSE;
int DispMono = TRUE;
int Fog = FALSE;
int FogColor;
183
SWBOOL PreCaching = TRUE;
184
int GodMode = FALSE;
185
SWBOOL BotMode = FALSE;
186
187
188
189
190
short Skill = 2;
short BetaVersion = 900;
short TotalKillable;

AUTO_NET Auto;
Evan Ramos's avatar
Evan Ramos committed
191
192
193
SWBOOL AutoNet = FALSE;
SWBOOL HasAutoColor = FALSE;
uint8_t AutoColor;
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211

const GAME_SET gs_defaults =
{
    32768, // mouse speed
    128, // music vol
    192, // fx vol
    2, // border
    0, // brightness
    0, // border tile
    FALSE, // mouse aiming
    FALSE, // mouse look
    FALSE, // mouse invert
    TRUE, // bobbing
    FALSE, // tilting
    TRUE, // shadows
    FALSE, // auto run
    TRUE, // crosshair
    TRUE, // auto aim
212
    TRUE, // interpolate sector objects
213
214
215
216
217
    TRUE, // messages
    TRUE, // fx on
    TRUE, // Music on
    TRUE, // talking
    TRUE, // ambient
218
    FALSE, // Flip Stereo
219
220
221
222
223
224
225
226
227
228
229
230

// Network game settings
    0, // GameType
    0, // Level
    0, // Monsters
    FALSE, // HurtTeammate
    TRUE, // SpawnMarkers Markers
    FALSE, // TeamPlay
    0, // Kill Limit
    0, // Time Limit
    0, // Color
    0, // Parental Lock
231
    "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", // Password
232
233
234
235
236
    TRUE, // nuke
    TRUE, // voxels
    FALSE, // stats
    FALSE, // mouse aiming on
    FALSE, // play cd
237
    "Track??", // waveform track name
238
    FALSE,
239
    TRUE,
Evan Ramos's avatar
Evan Ramos committed
240
    90, // FOV
241
242
243
};
GAME_SET gs;

Evan Ramos's avatar
Evan Ramos committed
244
245
246
247
248
249
250
251
252
253
254
255
256
257
SWBOOL PlayerTrackingMode = FALSE;
SWBOOL PauseMode = FALSE;
SWBOOL PauseKeySet = FALSE;
SWBOOL SlowMode = FALSE;
SWBOOL FrameAdvanceTics = 3;
SWBOOL ScrollMode2D = FALSE;

SWBOOL DebugSO = FALSE;
SWBOOL DebugPanel = FALSE;
SWBOOL DebugSector = FALSE;
SWBOOL DebugActor = FALSE;
SWBOOL DebugAnim = FALSE;
SWBOOL DebugOperate = FALSE;
SWBOOL DebugActorFreeze = FALSE;
258
void LoadingLevelScreen(void);
Evan Ramos's avatar
Evan Ramos committed
259
260

uint8_t FakeMultiNumPlayers;
261
262
263
264
265
266

int totalsynctics;
int turn_scale = 256;
int move_scale = 256;

short Level = 0;
Evan Ramos's avatar
Evan Ramos committed
267
268
269
270
SWBOOL ExitLevel = FALSE;
int16_t OrigCommPlayers=0;
extern uint8_t CommPlayers;
extern SWBOOL CommEnabled;
271
272
extern int bufferjitter;

Evan Ramos's avatar
Evan Ramos committed
273
SWBOOL CameraTestMode = FALSE;
274

Evan Ramos's avatar
Evan Ramos committed
275
char ds[512];                           // debug string
276
277
278
279
280
281
282
283
284
285
286

extern short NormalVisibility;

extern int quotebot, quotebotgoal;     // Multiplayer typing buffer
char recbuf[80];                        // Used as a temp buffer to hold typing text

extern unsigned char palette_data[256][3];             // Global palette array

#define ACT_STATUE 0

int score;
Evan Ramos's avatar
Evan Ramos committed
287
288
SWBOOL QuitFlag = FALSE;
SWBOOL InGame = FALSE;
289

Evan Ramos's avatar
Evan Ramos committed
290
SWBOOL CommandSetup = FALSE;
291
292
293
294

char UserMapName[80]="", buffer[80], ch;
char LevelName[20];

Evan Ramos's avatar
Evan Ramos committed
295
uint8_t DebugPrintColor = 255;
296
297
298
299
300

int krandcount;

/// L O C A L   P R O T O T Y P E S /////////////////////////////////////////////////////////
void BOT_DeleteAllBots(void);
Evan Ramos's avatar
Evan Ramos committed
301
302
303
void BotPlayerInsert(PLAYERp pp);
void SybexScreen(void);
void DosScreen(void);
Evan Ramos's avatar
Evan Ramos committed
304
void PlayTheme(void);
Evan Ramos's avatar
Evan Ramos committed
305
306
307
308
void MenuLevel(void);
void StatScreen(PLAYERp mpp);
void InitRunLevel(void);
void RunLevel(void);
309
310
311
312
/////////////////////////////////////////////////////////////////////////////////////////////

static FILE *debug_fout = NULL;

Evan Ramos's avatar
Evan Ramos committed
313
void DebugWriteString(char *string)
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
{

#if BETA || !DEBUG
    return;
#endif

    if (!debug_fout)
    {
        if ((debug_fout = fopen("dbg.foo", "ab+")) == NULL)
            return;
    }

    fprintf(debug_fout, "%s\n", string);

    //fclose(debug_fout);
    //debug_fout = NULL;

    fflush(debug_fout);
}

Evan Ramos's avatar
Evan Ramos committed
334
void DebugWriteLoc(char *fname, int line)
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
{

#if BETA || !DEBUG
    return;
#endif

    if (!debug_fout)
    {
        if ((debug_fout = fopen("dbg.foo", "ab+")) == NULL)
            return;
    }

    fprintf(debug_fout, "%s, %d\n", fname, line);

    //fclose(debug_fout);
    //debug_fout = NULL;

    fflush(debug_fout);
}

void Mono_Print(char *str)
{
    MONO_PRINT(str);
}


Evan Ramos's avatar
Evan Ramos committed
361
extern SWBOOL DrawScreen;
362
363
#if RANDOM_DEBUG
FILE *fout_err;
Evan Ramos's avatar
Evan Ramos committed
364
SWBOOL RandomPrint;
365
366
367
368
369
int krand1(char *file, unsigned line)
{
    ASSERT(!DrawScreen);
    if (RandomPrint && !Prediction)
    {
Evan Ramos's avatar
Evan Ramos committed
370
        extern uint32_t MoveThingsCount;
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
        sprintf(ds,"mtc %d, %s, line %d, %d",MoveThingsCount,file,line,randomseed);
        DebugWriteString(ds);
    }
    randomseed = ((randomseed * 21 + 1) & 65535);
    return randomseed;
}

int krand2()
{
    ASSERT(!DrawScreen);
    randomseed = ((randomseed * 21 + 1) & 65535);
    return randomseed;
}

#else
int krand1(void)
{
    ASSERT(!DrawScreen);
    krandcount++;
    randomseed = ((randomseed * 21 + 1) & 65535);
    return randomseed;
}

#endif

/*
void HeapCheck(char *file, int line)
{
    switch( _heapchk() )
        {
        case _HEAPOK:
            //printf( "OK - heap is good\n" );
            break;
        case _HEAPEMPTY:
            //printf( "OK - heap is empty\n" );
            break;
        case _HEAPBADBEGIN:
            sprintf(ds, "ERROR - heap is damaged: %s, %d", file, line);
            MONO_PRINT(ds);
            DebugWriteString(ds);
            setvmode(0x3);
            printf( "%s\n", ds);
            exit(0);
            break;
        case _HEAPBADNODE:
            sprintf(ds, "ERROR - bad node in heap: %s, %d", file, line);
            MONO_PRINT(ds);
            DebugWriteString(ds);
            setvmode(0x3);
            printf( "%s\n", ds);
            exit(0);
            break;
        }
}
    */

#if DEBUG
Evan Ramos's avatar
Evan Ramos committed
428
429
SWBOOL
ValidPtr(void *ptr)
430
431
{
    MEM_HDRp mhp;
Evan Ramos's avatar
Evan Ramos committed
432
    uint8_t* check;
433
434
435

    ASSERT(ptr != NULL);

Evan Ramos's avatar
Evan Ramos committed
436
    mhp = (MEM_HDRp)(((uint8_t*) ptr) - sizeof(MEM_HDR));
437
438
439
440
441
442
443

    if (mhp->size == 0 || mhp->checksum == 0)
    {
        printf("ValidPtr(): Size or Checksum == 0!\n");
        return FALSE;
    }

Evan Ramos's avatar
Evan Ramos committed
444
    check = (uint8_t*) & mhp->size;
445
446
447
448
449
450
451
452

    if (mhp->checksum == check[0] + check[1] + check[2] + check[3])
        return TRUE;

    printf("ValidPtr(): Checksum bad!\n");
    return FALSE;
}

Evan Ramos's avatar
Evan Ramos committed
453
454
void
PtrCheckSum(void *ptr, unsigned int *stored, unsigned int *actual)
455
456
{
    MEM_HDRp mhp;
Evan Ramos's avatar
Evan Ramos committed
457
    uint8_t* check;
458
459
460

    ASSERT(ptr != NULL);

Evan Ramos's avatar
Evan Ramos committed
461
    mhp = (MEM_HDRp)(((uint8_t*) ptr) - sizeof(MEM_HDR));
462

Evan Ramos's avatar
Evan Ramos committed
463
    check = (uint8_t*) & mhp->size;
464
465
466
467
468

    *stored = mhp->checksum;
    *actual = check[0] + check[1] + check[2] + check[3];
}

Evan Ramos's avatar
Evan Ramos committed
469
void *
470
471
AllocMem(int size)
{
Evan Ramos's avatar
Evan Ramos committed
472
    uint8_t* bp;
473
    MEM_HDRp mhp;
Evan Ramos's avatar
Evan Ramos committed
474
    uint8_t* check;
475
476
477

    ASSERT(size != 0);

Evan Ramos's avatar
Evan Ramos committed
478
    bp = (uint8_t*) malloc(size + sizeof(MEM_HDR));
479
480
481
482
483
484
485
486
487
488
489
490
491
492

    // Used for debugging, we can remove this at ship time
    if (bp == NULL)
    {
        TerminateGame();
        printf("Memory could NOT be allocated in AllocMem: size = %d\n",size);
        exit(0);
    }

    ASSERT(bp != NULL);

    mhp = (MEM_HDRp) bp;

    mhp->size = size;
Evan Ramos's avatar
Evan Ramos committed
493
    check = (uint8_t*) & mhp->size;
494
495
496
497
498
499
500
    mhp->checksum = check[0] + check[1] + check[2] + check[3];

    bp += sizeof(MEM_HDR);

    return bp;
}

Evan Ramos's avatar
Evan Ramos committed
501
502
void *
ReAllocMem(void *ptr, int size)
503
{
504
505
506
507
508
509
510
511
512
    if (ptr == nullptr)
        return AllocMem(size);

    if (size == 0)
    {
        FreeMem(ptr);
        return nullptr;
    }

Evan Ramos's avatar
Evan Ramos committed
513
    uint8_t* bp;
514
    MEM_HDRp mhp;
Evan Ramos's avatar
Evan Ramos committed
515
    uint8_t* check;
516
517
518

    ASSERT(ValidPtr(ptr));

Evan Ramos's avatar
Evan Ramos committed
519
    mhp = (MEM_HDRp)(((uint8_t*) ptr) - sizeof(MEM_HDR));
520

Evan Ramos's avatar
Evan Ramos committed
521
    bp = (uint8_t*) realloc(mhp, size + sizeof(MEM_HDR));
522
523
524
525
526
527

    ASSERT(bp != NULL);

    mhp = (MEM_HDRp) bp;

    mhp->size = size;
Evan Ramos's avatar
Evan Ramos committed
528
    check = (uint8_t*) & mhp->size;
529
530
531
532
533
534
535
536
537
538
    mhp->checksum = check[0] + check[1] + check[2] + check[3];

    bp += sizeof(MEM_HDR);

    ASSERT(ValidPtr(bp));

    return bp;
}


Evan Ramos's avatar
Evan Ramos committed
539
void *
540
541
CallocMem(int size, int num)
{
Evan Ramos's avatar
Evan Ramos committed
542
    uint8_t* bp;
543
    MEM_HDRp mhp;
Evan Ramos's avatar
Evan Ramos committed
544
    uint8_t* check;
545
546
547
548
549
    int num_bytes;

    ASSERT(size != 0 && num != 0);

    num_bytes = (size * num) + sizeof(MEM_HDR);
Evan Ramos's avatar
Evan Ramos committed
550
    bp = (uint8_t*) calloc(num_bytes, 1);
551
552
553
554
555
556
557
558
559
560
561
562
563
564

    // Used for debugging, we can remove this at ship time
    if (bp == NULL)
    {
        TerminateGame();
        printf("Memory could NOT be allocated in CallocMem: size = %d, num = %d\n",size,num);
        exit(0);
    }

    ASSERT(bp != NULL);

    mhp = (MEM_HDRp) bp;

    mhp->size = size;
Evan Ramos's avatar
Evan Ramos committed
565
    check = (uint8_t*) & mhp->size;
566
567
568
569
570
571
572
    mhp->checksum = check[0] + check[1] + check[2] + check[3];

    bp += sizeof(MEM_HDR);

    return bp;
}

Evan Ramos's avatar
Evan Ramos committed
573
574
void
FreeMem(void *ptr)
575
{
576
577
578
    if (ptr == nullptr)
        return;

579
    MEM_HDRp mhp;
Evan Ramos's avatar
Evan Ramos committed
580
    uint8_t* check;
581
582
583

    ASSERT(ValidPtr(ptr));

Evan Ramos's avatar
Evan Ramos committed
584
585
    mhp = (MEM_HDRp)(((uint8_t*) ptr) - sizeof(MEM_HDR));
    check = (uint8_t*)&mhp->size;
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618

    memset(mhp, 0xCC, mhp->size + sizeof(MEM_HDR));

    free(mhp);
}

#endif

int PointOnLine(int x, int y, int x1, int y1, int x2, int y2)
{
    // the closer to 0 the closer to the line the point is
    return ((x2 - x1) * (y - y1)) - ((y2 - y1) * (x - x1));
}

int
Distance(int x1, int y1, int x2, int y2)
{
    int min;

    if ((x2 = x2 - x1) < 0)
        x2 = -x2;

    if ((y2 = y2 - y1) < 0)
        y2 = -y2;

    if (x2 > y2)
        min = y2;
    else
        min = x2;

    return x2 + y2 - DIV2(min);
}

Evan Ramos's avatar
Evan Ramos committed
619
620
void
MapSetAll2D(uint8_t fill)
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
{
    int i;

    for (i = 0; i < (MAXWALLS >> 3); i++)
        show2dwall[i] = fill;
    for (i = 0; i < (MAXSPRITES >> 3); i++)
        show2dsprite[i] = fill;

    //for (i = 0; i < (MAXSECTORS >> 3); i++)
    for (i = 0; i < MAXSECTORS; i++)
    {
        if (sector[i].ceilingpicnum != 342 && sector[i].floorpicnum != 342)
            show2dsector[i>>3] |= (1<<(i&7));
        //show2dsector[i] = fill;
    }
}

Evan Ramos's avatar
Evan Ramos committed
638
639
void
MapSetup(void)
640
{
641
642
643
#define NO_AUTO_MAPPING FALSE

#if NO_AUTO_MAPPING
644
    MapSetAll2D(0xFF);
645
646
647
#else
    automapping = TRUE;
#endif
648
649
}

Evan Ramos's avatar
Evan Ramos committed
650
651
void
setup2dscreen(void)
652
653
654
655
656
657
{
    // qsetmode640350();
}



Evan Ramos's avatar
Evan Ramos committed
658
659
void
TerminateGame(void)
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
{
    DemoTerm();

    ErrorCorrectionQuit();

    uninitmultiplayers();

    if (CleanExit)
    {
        SybexScreen();
        //TenScreen();
    }

    ////--->>>> sound stuff was there
    //uninitkeys();
    KB_Shutdown();

    TermSetup();

    //Terminate3DSounds();                // Kill the sounds linked list
    UnInitSound();

682
    timerUninit();
683
684
685
686

    if (CleanExit)
        DosScreen();

687
    engineUnInit();
688
    FreeGroups();
689

690
691
692
    uninitgroupfile();
}

Evan Ramos's avatar
Evan Ramos committed
693
void
Evan Ramos's avatar
Evan Ramos committed
694
LoadLevel(const char *filename)
695
{
696
697
    int16_t ang;
    if (engineLoadBoard(filename, SW_SHAREWARE ? 1 : 0, (vec3_t *)&Player[0], &ang, &Player[0].cursectnum) == -1)
698
699
    {
        TerminateGame();
700
701
#if 1 /* defined RENDERTYPEWIN */
        wm_msgbox(apptitle, "Level not found: %s", filename);
702
703
704
705
706
#else
        printf("Level Not Found: %s\n", filename);
#endif
        exit(0);
    }
707
    Player[0].q16ang = fix16_from_int(ang);
708
709
}

Evan Ramos's avatar
Evan Ramos committed
710
void
Evan Ramos's avatar
Evan Ramos committed
711
LoadImages(const char *filename)
712
{
713
    if (artLoadFiles(filename, 32*1048576) == -1)
714
715
    {
        TerminateGame();
716
717
#if 1 /* defined RENDERTYPEWIN */
        wm_msgbox(apptitle, "Art not found. Please check your GRP file.");
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
#else
        printf("Art not found. Please check your GRP file.\n");
#endif
        exit(-1);
    }
}

void LoadDemoRun(void)
{
    short i;
    FILE *fin;

    fin = fopen("demos.run","r");
    if (fin)
    {
        memset(DemoName,'\0',sizeof(DemoName));
734
        for (i = 0; i < ARRAY_SSIZE(DemoName); i++)
735
736
737
738
        {
            if (fscanf(fin, "%s", DemoName[i]) == EOF)
                break;
        }
739
740
        if (i == ARRAY_SSIZE(DemoName))
            initputs("WARNING: demos.run is too long, ignoring remaining files\n");
741
742
743
744
745
746
747
748
749
750

        fclose(fin);
    }

    memset(DemoText,'\0',sizeof(DemoText));
    fin = fopen("demotxt.run","r");
    if (fin)
    {
        fgets(ds, 6, fin);
        sscanf(ds,"%d",&DemoTextYstart);
751
        for (i = 0; i < ARRAY_SSIZE(DemoText); i++)
752
753
754
755
        {
            if (fgets(DemoText[i], SIZ(DemoText[0])-1, fin) == NULL)
                break;
        }
756
757
        if (i == ARRAY_SSIZE(DemoText))
            initputs("WARNING: demotxt.run is too long, trimming the text\n");
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779

        fclose(fin);
    }
}

void DisplayDemoText(void)
{
    short w,h;
    short i;

    for (i = 0; i < 3; i++)
    {
        MNU_MeasureString(DemoText[i], &w, &h);
        PutStringTimer(Player, TEXT_TEST_COL(w), DemoTextYstart+(i*12), DemoText[i], 999);
    }
}


void Set_GameMode(void)
{
    int result;

780
    //DSPRINTF(ds,"ScreenMode %d, ScreenWidth %d, ScreenHeight %d", ud_setup.ScreenMode, ud_setup.ScreenWidth, ud_setup.ScreenHeight);
781
    //MONO_PRINT(ds);
782
    result = COVERsetgamemode(ud_setup.ScreenMode, ud_setup.ScreenWidth, ud_setup.ScreenHeight, ud_setup.ScreenBPP);
783
784
785
786

    if (result < 0)
    {
        buildprintf("Failure setting video mode %dx%dx%d %s! Attempting safer mode...",
787
788
789
790
791
792
793
794
                    ud_setup.ScreenWidth,ud_setup.ScreenHeight,ud_setup.ScreenBPP,
                    ud_setup.ScreenMode ? "fullscreen" : "windowed");
        ud_setup.ScreenMode = 0;
        ud_setup.ScreenWidth = 640;
        ud_setup.ScreenHeight = 480;
        ud_setup.ScreenBPP = 8;

        result = COVERsetgamemode(ud_setup.ScreenMode, ud_setup.ScreenWidth, ud_setup.ScreenHeight, ud_setup.ScreenBPP);
795
796
797
798
799
800
801
        if (result < 0)
        {
            uninitmultiplayers();
            //uninitkeys();
            KB_Shutdown();
            TermSetup();
            UnInitSound();
802
            timerUninit();
803
804
805
806
807
808
809
810
811
812
813
814
            DosScreen();
            uninitgroupfile();
            exit(0);
        }
    }
}

void MultiSharewareCheck(void)
{
    if (!SW_SHAREWARE) return;
    if (numplayers > 4)
    {
815
#if 1 /* defined RENDERTYPEWIN */
816
817
818
819
820
821
822
823
824
825
826
827
        wm_msgbox(apptitle,"To play a Network game with more than 4 players you must purchase "
                  "the full version.  Read the Ordering Info screens for details.");
#else
        printf(
            "\n\nTo play a Network game with more than 4 players you must purchase the\n"
            "full version.  Read the Ordering Info screens for details.\n\n");
#endif
        uninitmultiplayers();
        //uninitkeys();
        KB_Shutdown();
        TermSetup();
        UnInitSound();
828
        timerUninit();
829
        engineUnInit();
830
        FreeGroups();
831
832
833
834
835
836
837
838
839
840
841
        uninitgroupfile();
        exit(0);
    }
}


// Some mem crap for Jim
// I reserve 1 meg of heap space for our use out side the cache
int TotalMemory = 0;
int ActualHeap = 0;

Evan Ramos's avatar
Evan Ramos committed
842
void InitAutoNet(void)
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
{
    if (!AutoNet)
        return;

    gs.NetGameType      = Auto.Rules;
    gs.NetLevel         = Auto.Level;
    gs.NetMonsters      = Auto.Enemy;
    gs.NetSpawnMarkers  = Auto.Markers;
    gs.NetTeamPlay      = Auto.Team;
    gs.NetHurtTeammate  = Auto.HurtTeam;
    gs.NetKillLimit     = Auto.Kill;
    gs.NetTimeLimit     = Auto.Time;
    gs.NetColor         = Auto.Color;
    gs.NetNuke          = Auto.Nuke;
}


void AnimateCacheCursor(void)
{
#if 0
    struct rccoord old_pos;
    static short cursor_num = 0;
    static char cache_cursor[] =  {'|','/','-','\\'};

    if (GraphicsMode)
        return;

    cursor_num++;
    if (cursor_num > 3)
        cursor_num = 0;

    //old_pos = _gettextposition();
    //_settextposition( old_pos.row, old_pos.col );
    //_settextposition( 24,  25);
    _settextposition(25,  0);
    sprintf(ds,"Loading sound and graphics %c", cache_cursor[cursor_num]);
    _outtext(ds);
    //_settextposition( old_pos.row, old_pos.col );
#endif
}

void COVERsetbrightness(int bright, unsigned char *pal)
{
886
887
    paletteSetColorTable(BASEPAL, pal);
    videoSetPalette(bright, BASEPAL, 0);
888
889
890
891
892
893
894
}


static int firstnet = 0;    // JBF

extern int startwin_run(void);

895
896
897
898
899
900
901
static void SW_FatalEngineError(void)
{
    wm_msgbox("Build Engine Initialisation Error",
              "There was a problem initialising the Build engine: %s", engineerrstr);
    exit(1);
}

Evan Ramos's avatar
Evan Ramos committed
902
void
903
InitGame(int32_t argc, char const * const * argv)
904
905
906
907
908
909
910
911
{
    extern int MovesPerPacket;
    //void *ReserveMem=NULL;
    int i;

    DSPRINTF(ds,"InitGame...");
    MONO_PRINT(ds);

912
    if (engineInit())
913
        SW_FatalEngineError();
914

915
916
917
918
919
920
921
    {
        char tempbuf[256];
        snprintf(tempbuf, ARRAY_SIZE(tempbuf), APPNAME " %s", s_buildRev);
        OSD_SetVersion(tempbuf, 10,0);
    }
    OSD_SetParameters(0, 0, 0, 4, 2, 4, "^14", "^14", 0);

922
923
924
925
    InitSetup();

    InitAutoNet();

926
    timerInit(120);
927
928
929
930
931
932
933
934
935
936
937
938

    CON_InitConsole();  // Init console command list

    ////DSPRINTF(ds,"%s, %d",__FILE__,__LINE__);   MONO_PRINT(ds);

    //InitFX();

    memcpy(palette_data,palette,768);
    InitPalette();
    // sets numplayers, connecthead, connectpoint2, myconnectindex

    if (!firstnet)
939
        initsingleplayers();
Evan Ramos's avatar
Evan Ramos committed
940
    else if (initmultiplayersparms(argc - firstnet, &argv[firstnet]))
941
    {
942
        NetBroadcastMode = (networkmode == MMULTI_MODE_P2P);
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
        buildputs("Waiting for players...\n");
        while (initmultiplayerscycle())
        {
            handleevents();
            if (quitevent)
            {
                QuitFlag = TRUE;
                return;
            }
        }
    }
    initsynccrc();

    // code to duplicate packets
    if (numplayers > 4 && MovesPerPacket == 1)
    {
        MovesPerPacket = 2;
    }

    MultiSharewareCheck();

    if (numplayers > 1)
    {
        CommPlayers = numplayers;
        OrigCommPlayers = CommPlayers;
        CommEnabled = TRUE;
        if (!BotMode)
            gNet.MultiGameType = MULTI_GAME_COMMBAT;
        else
            gNet.MultiGameType = MULTI_GAME_AI_BOTS;

#if 0 //def NET_MODE_MASTER_SLAVE
        if (!NetModeOverride)
        {
            if (numplayers <= 4)
                NetBroadcastMode = TRUE;
            else
                NetBroadcastMode = FALSE;
        }
#endif
    }

    LoadDemoRun();
    // Save off total heap for later calculations
    //TotalMemory = Z_AvailHeap();
    //DSPRINTF(ds,"Available Heap before LoadImages =  %d", TotalMemory);
    //MONO_PRINT(ds);
    // Reserve 1.5 megs for normal program use
    // Generally, SW is consuming about a total of 11 megs including
    // all the cached in graphics, etc. per level, so even on a 16 meg
    // system, reserving 1.5 megs is fine.
    // Note that on a 16 meg machine, Ken was leaving us about
    // 24k for use outside the cache!  This was causing out of mem problems
    // when songs, etc., greater than the remaining heap were being loaded.
    // Even if you pre-cache songs, etc. to help, reserving some heap is
    // a very smart idea since the game uses malloc throughout execution.
    //ReserveMem = AllocMem(1L<<20);
    //if(ReserveMem == 0) MONO_PRINT("Could not allocate 1.5 meg reserve!");
For faster browsing, not all history is shown. View entire blame