Subversion Repositories eduke32

Rev

Rev 8271 | Rev 8297 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5196 hendricks2 1
//-------------------------------------------------------------------------
2
/*
3
Copyright (C) 1997, 2005 - 3D Realms Entertainment
4
 
5
This file is part of Shadow Warrior version 1.2
6
 
7
Shadow Warrior is free software; you can redistribute it and/or
8
modify it under the terms of the GNU General Public License
9
as published by the Free Software Foundation; either version 2
10
of the License, or (at your option) any later version.
11
 
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
 
16
See the GNU General Public License for more details.
17
 
18
You should have received a copy of the GNU General Public License
19
along with this program; if not, write to the Free Software
20
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21
 
22
Original Source: 1997 - Frank Maddin and Jim Norwood
23
Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms
24
*/
25
//-------------------------------------------------------------------------
26
 
27
// CTW NOTE
28
/*
29
Known remaining issues:
30
- Audio stuttering.
31
- CD Audio not looping properly (currently hard coded to restart about every 200 seconds.
32
- Hitting F5 to change resolution causes a crash (currently disabled).
33
- Multiplayer untested.
34
 
35
Things required to make savegames work:
36
- Load makesym.wpj and build it.
37
- In a DOS prompt, run "makesym sw.map swdata.map swcode.map"
38
- Copy swcode.map to swcode.sym and swdata.map to swdata.sym
39
*/
40
// CTW NOTE END
41
 
42
#define MAIN
43
#define QUIET
44
#include "build.h"
45
#include "baselayer.h"
46
#include "cache1d.h"
47
#include "osd.h"
8269 hendricks2 48
#include "renderlayer.h"
5196 hendricks2 49
 
50
#include "keys.h"
51
#include "names2.h"
52
#include "panel.h"
53
#include "game.h"
54
#include "tags.h"
55
#include "sector.h"
56
#include "sprite.h"
57
#include "weapon.h"
58
#include "player.h"
59
#include "lists.h"
7443 hendricks2 60
#include "network.h"
5196 hendricks2 61
#include "pal.h"
62
#include "fx_man.h"
63
 
64
#include "mytypes.h"
65
//#include "config.h"
66
 
67
#include "menus.h"
68
 
69
#include "control.h"
70
#include "function.h"
71
#include "gamedefs.h"
72
#include "config.h"
73
 
74
#include "demo.h"
75
#include "cache.h"
76
//#include "exports.h"
77
 
78
#include "anim.h"
79
 
80
#include "colormap.h"
81
#include "break.h"
82
#include "ninja.h"
83
#include "light.h"
84
#include "track.h"
85
#include "jsector.h"
86
#include "keyboard.h"
87
#include "text.h"
88
#include "music.h"
89
 
5217 hendricks2 90
#include "common.h"
5211 hendricks2 91
#include "common_game.h"
92
 
5196 hendricks2 93
#include "crc32.h"
94
 
7537 hendricks2 95
const char* AppProperName = "VoidSW";
96
const char* AppTechnicalName = "voidsw";
97
 
98
#define SETUPFILENAME "voidsw.cfg"
99
char setupfilename[BMAX_PATH] = SETUPFILENAME;
100
 
5196 hendricks2 101
#if DEBUG
102
#define BETA 0
103
#endif
104
 
105
#define STAT_SCREEN_PIC 5114
106
#define TITLE_PIC 2324
107
#define THREED_REALMS_PIC 2325
108
#define TITLE_ROT_FLAGS (ROTATE_SPRITE_CORNER|ROTATE_SPRITE_SCREEN_CLIP|ROTATE_SPRITE_NON_MASK)
109
#define PAL_SIZE (256*3)
110
 
111
char DemoName[15][16];
112
 
113
// Stupid WallMart version!
114
//#define PLOCK_VERSION TRUE
115
 
116
#if PLOCK_VERSION
5198 hendricks2 117
SWBOOL Global_PLock = TRUE;
5196 hendricks2 118
#else
5198 hendricks2 119
SWBOOL Global_PLock = FALSE;
5196 hendricks2 120
#endif
121
 
122
int GameVersion = 13;   // 12 was original source release. For future releases increment by two.
123
char DemoText[3][64];
124
int DemoTextYstart = 0;
125
 
5198 hendricks2 126
SWBOOL DoubleInitAWE32 = FALSE;
5196 hendricks2 127
int Follow_posx=0,Follow_posy=0;
128
 
5198 hendricks2 129
SWBOOL NoMeters = FALSE;
5196 hendricks2 130
short IntroAnimCount = 0;
131
short PlayingLevel = -1;
5198 hendricks2 132
SWBOOL GraphicsMode = FALSE;
5196 hendricks2 133
char CacheLastLevel[32] = "";
134
char PlayerNameArg[32] = "";
5198 hendricks2 135
SWBOOL CleanExit = FALSE;
136
SWBOOL DemoModeMenuInit = FALSE;
137
SWBOOL FinishAnim = 0;
138
SWBOOL ShortGameMode = FALSE;
139
SWBOOL ReloadPrompt = FALSE;
140
SWBOOL ReloadPromptMode = FALSE;
141
SWBOOL NewGame = TRUE;
142
SWBOOL InMenuLevel = FALSE;
143
SWBOOL LoadGameOutsideMoveLoop = FALSE;
144
SWBOOL LoadGameFromDemo = FALSE;
145
SWBOOL ArgCheat = FALSE;
146
extern SWBOOL NetBroadcastMode, NetModeOverride;
147
SWBOOL MultiPlayQuitFlag = FALSE;
5196 hendricks2 148
//Miscellaneous variables
149
char MessageInputString[256];
150
char MessageOutputString[256];
5198 hendricks2 151
SWBOOL MessageInputMode = FALSE;
152
SWBOOL ConInputMode = FALSE;
153
SWBOOL ConPanel = FALSE;
154
SWBOOL FinishedLevel = FALSE;
155
SWBOOL HelpInputMode = FALSE;
156
SWBOOL PanelUpdateMode = TRUE;
5196 hendricks2 157
short HelpPage = 0;
158
short HelpPagePic[] = { 5115, 5116, 5117 };
5198 hendricks2 159
SWBOOL InputMode = FALSE;
160
SWBOOL MessageInput = FALSE;
161
extern SWBOOL GamePaused;
5196 hendricks2 162
short screenpeek = 0;
5198 hendricks2 163
SWBOOL NoDemoStartup = FALSE;
164
SWBOOL FirstTimeIntoGame;
165
extern uint8_t RedBookSong[40];
5196 hendricks2 166
 
5198 hendricks2 167
SWBOOL BorderAdjust = TRUE;
168
SWBOOL LocationInfo = 0;
169
void drawoverheadmap(int cposx, int cposy, int czoom, short cang);
5196 hendricks2 170
int DispFrameRate = FALSE;
171
int DispMono = TRUE;
172
int Fog = FALSE;
173
int FogColor;
5226 hendricks2 174
SWBOOL PreCaching = TRUE;
5196 hendricks2 175
int GodMode = FALSE;
5226 hendricks2 176
SWBOOL BotMode = FALSE;
5196 hendricks2 177
short Skill = 2;
178
short BetaVersion = 900;
179
short TotalKillable;
180
 
181
AUTO_NET Auto;
5198 hendricks2 182
SWBOOL AutoNet = FALSE;
183
SWBOOL HasAutoColor = FALSE;
184
uint8_t AutoColor;
5196 hendricks2 185
 
186
const GAME_SET gs_defaults =
187
{
188
    32768, // mouse speed
189
    128, // music vol
190
    192, // fx vol
191
    2, // border
192
    0, // brightness
193
    0, // border tile
194
    FALSE, // mouse aiming
195
    FALSE, // mouse look
196
    FALSE, // mouse invert
197
    TRUE, // bobbing
198
    FALSE, // tilting
199
    TRUE, // shadows
200
    FALSE, // auto run
201
    TRUE, // crosshair
202
    TRUE, // auto aim
203
    TRUE, // messages
204
    TRUE, // fx on
205
    TRUE, // Music on
206
    TRUE, // talking
207
    TRUE, // ambient
208
    FALSE, // Flip Stereo
209
 
210
// Network game settings
211
    0, // GameType
212
    0, // Level
213
    0, // Monsters
214
    FALSE, // HurtTeammate
215
    TRUE, // SpawnMarkers Markers
216
    FALSE, // TeamPlay
217
    0, // Kill Limit
218
    0, // Time Limit
219
    0, // Color
220
    0, // Parental Lock
7512 hendricks2 221
    "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", // Password
5196 hendricks2 222
    TRUE, // nuke
223
    TRUE, // voxels
224
    FALSE, // stats
225
    FALSE, // mouse aiming on
226
    FALSE, // play cd
5212 hendricks2 227
    "Track??", // waveform track name
5196 hendricks2 228
};
229
GAME_SET gs;
230
 
5198 hendricks2 231
SWBOOL PlayerTrackingMode = FALSE;
232
SWBOOL PauseMode = FALSE;
233
SWBOOL PauseKeySet = FALSE;
234
SWBOOL SlowMode = FALSE;
235
SWBOOL FrameAdvanceTics = 3;
236
SWBOOL ScrollMode2D = FALSE;
5196 hendricks2 237
 
5198 hendricks2 238
SWBOOL DebugSO = FALSE;
239
SWBOOL DebugPanel = FALSE;
240
SWBOOL DebugSector = FALSE;
241
SWBOOL DebugActor = FALSE;
242
SWBOOL DebugAnim = FALSE;
243
SWBOOL DebugOperate = FALSE;
244
SWBOOL DebugActorFreeze = FALSE;
245
void LoadingLevelScreen(char *level_name);
5196 hendricks2 246
 
5198 hendricks2 247
uint8_t FakeMultiNumPlayers;
5196 hendricks2 248
 
249
int totalsynctics;
250
int turn_scale = 256;
251
int move_scale = 256;
252
 
253
short Level = 0;
5198 hendricks2 254
SWBOOL ExitLevel = FALSE;
255
int16_t OrigCommPlayers=0;
256
extern uint8_t CommPlayers;
257
extern SWBOOL CommEnabled;
5196 hendricks2 258
extern int bufferjitter;
259
 
5198 hendricks2 260
SWBOOL CameraTestMode = FALSE;
5196 hendricks2 261
 
7560 hendricks2 262
char ds[512];                           // debug string
5196 hendricks2 263
 
264
extern short NormalVisibility;
265
 
266
extern int quotebot, quotebotgoal;     // Multiplayer typing buffer
267
char recbuf[80];                        // Used as a temp buffer to hold typing text
268
 
269
extern unsigned char palette_data[256][3];             // Global palette array
270
 
271
#define ACT_STATUE 0
272
 
273
int score;
5198 hendricks2 274
SWBOOL QuitFlag = FALSE;
275
SWBOOL InGame = FALSE;
5196 hendricks2 276
 
5198 hendricks2 277
SWBOOL CommandSetup = FALSE;
5196 hendricks2 278
 
279
char UserMapName[80]="", buffer[80], ch;
280
char LevelName[20];
281
 
5198 hendricks2 282
uint8_t DebugPrintColor = 255;
5196 hendricks2 283
 
284
int krandcount;
285
 
286
/// L O C A L   P R O T O T Y P E S /////////////////////////////////////////////////////////
287
void BOT_DeleteAllBots(void);
5198 hendricks2 288
void BotPlayerInsert(PLAYERp pp);
289
void SybexScreen(void);
290
void DosScreen(void);
8271 hendricks2 291
void PlayTheme(void);
5198 hendricks2 292
void MenuLevel(void);
293
void StatScreen(PLAYERp mpp);
294
void InitRunLevel(void);
295
void RunLevel(void);
5196 hendricks2 296
/////////////////////////////////////////////////////////////////////////////////////////////
297
 
298
static FILE *debug_fout = NULL;
299
 
5198 hendricks2 300
void DebugWriteString(char *string)
5196 hendricks2 301
{
302
 
303
#if BETA || !DEBUG
304
    return;
305
#endif
306
 
307
    if (!debug_fout)
308
    {
309
        if ((debug_fout = fopen("dbg.foo", "ab+")) == NULL)
310
            return;
311
    }
312
 
313
    fprintf(debug_fout, "%s\n", string);
314
 
315
    //fclose(debug_fout);
316
    //debug_fout = NULL;
317
 
318
    fflush(debug_fout);
319
}
320
 
5198 hendricks2 321
void DebugWriteLoc(char *fname, int line)
5196 hendricks2 322
{
323
 
324
#if BETA || !DEBUG
325
    return;
326
#endif
327
 
328
    if (!debug_fout)
329
    {
330
        if ((debug_fout = fopen("dbg.foo", "ab+")) == NULL)
331
            return;
332
    }
333
 
334
    fprintf(debug_fout, "%s, %d\n", fname, line);
335
 
336
    //fclose(debug_fout);
337
    //debug_fout = NULL;
338
 
339
    fflush(debug_fout);
340
}
341
 
342
void Mono_Print(char *str)
343
{
344
    MONO_PRINT(str);
345
}
346
 
347
 
5198 hendricks2 348
extern SWBOOL DrawScreen;
5196 hendricks2 349
#if RANDOM_DEBUG
350
FILE *fout_err;
5198 hendricks2 351
SWBOOL RandomPrint;
5196 hendricks2 352
int krand1(char *file, unsigned line)
353
{
354
    ASSERT(!DrawScreen);
355
    if (RandomPrint && !Prediction)
356
    {
5198 hendricks2 357
        extern uint32_t MoveThingsCount;
5196 hendricks2 358
        sprintf(ds,"mtc %d, %s, line %d, %d",MoveThingsCount,file,line,randomseed);
359
        DebugWriteString(ds);
360
    }
361
    randomseed = ((randomseed * 21 + 1) & 65535);
362
    return randomseed;
363
}
364
 
365
int krand2()
366
{
367
    ASSERT(!DrawScreen);
368
    randomseed = ((randomseed * 21 + 1) & 65535);
369
    return randomseed;
370
}
371
 
372
#else
373
int krand1(void)
374
{
375
    ASSERT(!DrawScreen);
376
    krandcount++;
377
    randomseed = ((randomseed * 21 + 1) & 65535);
378
    return randomseed;
379
}
380
 
381
#endif
382
 
383
/*
384
void HeapCheck(char *file, int line)
385
{
386
    switch( _heapchk() )
387
        {
388
        case _HEAPOK:
389
            //printf( "OK - heap is good\n" );
390
            break;
391
        case _HEAPEMPTY:
392
            //printf( "OK - heap is empty\n" );
393
            break;
394
        case _HEAPBADBEGIN:
395
            sprintf(ds, "ERROR - heap is damaged: %s, %d", file, line);
396
            MONO_PRINT(ds);
397
            DebugWriteString(ds);
398
            setvmode(0x3);
399
            printf( "%s\n", ds);
400
            exit(0);
401
            break;
402
        case _HEAPBADNODE:
403
            sprintf(ds, "ERROR - bad node in heap: %s, %d", file, line);
404
            MONO_PRINT(ds);
405
            DebugWriteString(ds);
406
            setvmode(0x3);
407
            printf( "%s\n", ds);
408
            exit(0);
409
            break;
410
        }
411
}
412
    */
413
 
414
#if DEBUG
5198 hendricks2 415
SWBOOL
416
ValidPtr(void *ptr)
5196 hendricks2 417
{
418
    MEM_HDRp mhp;
5198 hendricks2 419
    uint8_t* check;
5196 hendricks2 420
 
421
    ASSERT(ptr != NULL);
422
 
5198 hendricks2 423
    mhp = (MEM_HDRp)(((uint8_t*) ptr) - sizeof(MEM_HDR));
5196 hendricks2 424
 
425
    if (mhp->size == 0 || mhp->checksum == 0)
426
    {
427
        printf("ValidPtr(): Size or Checksum == 0!\n");
428
        return FALSE;
429
    }
430
 
5198 hendricks2 431
    check = (uint8_t*) & mhp->size;
5196 hendricks2 432
 
433
    if (mhp->checksum == check[0] + check[1] + check[2] + check[3])
434
        return TRUE;
435
 
436
    printf("ValidPtr(): Checksum bad!\n");
437
    return FALSE;
438
}
439
 
5198 hendricks2 440
void
441
PtrCheckSum(void *ptr, unsigned int *stored, unsigned int *actual)
5196 hendricks2 442
{
443
    MEM_HDRp mhp;
5198 hendricks2 444
    uint8_t* check;
5196 hendricks2 445
 
446
    ASSERT(ptr != NULL);
447
 
5198 hendricks2 448
    mhp = (MEM_HDRp)(((uint8_t*) ptr) - sizeof(MEM_HDR));
5196 hendricks2 449
 
5198 hendricks2 450
    check = (uint8_t*) & mhp->size;
5196 hendricks2 451
 
452
    *stored = mhp->checksum;
453
    *actual = check[0] + check[1] + check[2] + check[3];
454
}
455
 
5198 hendricks2 456
void *
5196 hendricks2 457
AllocMem(int size)
458
{
5198 hendricks2 459
    uint8_t* bp;
5196 hendricks2 460
    MEM_HDRp mhp;
5198 hendricks2 461
    uint8_t* check;
5196 hendricks2 462
 
463
    ASSERT(size != 0);
464
 
5198 hendricks2 465
    bp = (uint8_t*) malloc(size + sizeof(MEM_HDR));
5196 hendricks2 466
 
467
    // Used for debugging, we can remove this at ship time
468
    if (bp == NULL)
469
    {
470
        TerminateGame();
471
        printf("Memory could NOT be allocated in AllocMem: size = %d\n",size);
472
        exit(0);
473
    }
474
 
475
    ASSERT(bp != NULL);
476
 
477
    mhp = (MEM_HDRp) bp;
478
 
479
    mhp->size = size;
5198 hendricks2 480
    check = (uint8_t*) & mhp->size;
5196 hendricks2 481
    mhp->checksum = check[0] + check[1] + check[2] + check[3];
482
 
483
    bp += sizeof(MEM_HDR);
484
 
485
    return bp;
486
}
487
 
5198 hendricks2 488
void *
489
ReAllocMem(void *ptr, int size)
5196 hendricks2 490
{
5198 hendricks2 491
    uint8_t* bp;
5196 hendricks2 492
    MEM_HDRp mhp;
5198 hendricks2 493
    uint8_t* check;
5196 hendricks2 494
 
495
    ASSERT(size != 0);
496
 
497
    ASSERT(ValidPtr(ptr));
498
 
5198 hendricks2 499
    mhp = (MEM_HDRp)(((uint8_t*) ptr) - sizeof(MEM_HDR));
5196 hendricks2 500
 
5198 hendricks2 501
    bp = (uint8_t*) realloc(mhp, size + sizeof(MEM_HDR));
5196 hendricks2 502
 
503
    ASSERT(bp != NULL);
504
 
505
    mhp = (MEM_HDRp) bp;
506
 
507
    mhp->size = size;
5198 hendricks2 508
    check = (uint8_t*) & mhp->size;
5196 hendricks2 509
    mhp->checksum = check[0] + check[1] + check[2] + check[3];
510
 
511
    bp += sizeof(MEM_HDR);
512
 
513
    ASSERT(ValidPtr(bp));
514
 
515
    return bp;
516
}
517
 
518
 
5198 hendricks2 519
void *
5196 hendricks2 520
CallocMem(int size, int num)
521
{
5198 hendricks2 522
    uint8_t* bp;
5196 hendricks2 523
    MEM_HDRp mhp;
5198 hendricks2 524
    uint8_t* check;
5196 hendricks2 525
    int num_bytes;
526
 
527
    ASSERT(size != 0 && num != 0);
528
 
529
    num_bytes = (size * num) + sizeof(MEM_HDR);
5198 hendricks2 530
    bp = (uint8_t*) calloc(num_bytes, 1);
5196 hendricks2 531
 
532
    // Used for debugging, we can remove this at ship time
533
    if (bp == NULL)
534
    {
535
        TerminateGame();
536
        printf("Memory could NOT be allocated in CallocMem: size = %d, num = %d\n",size,num);
537
        exit(0);
538
    }
539
 
540
    ASSERT(bp != NULL);
541
 
542
    mhp = (MEM_HDRp) bp;
543
 
544
    mhp->size = size;
5198 hendricks2 545
    check = (uint8_t*) & mhp->size;
5196 hendricks2 546
    mhp->checksum = check[0] + check[1] + check[2] + check[3];
547
 
548
    bp += sizeof(MEM_HDR);
549
 
550
    return bp;
551
}
552
 
5198 hendricks2 553
void
554
FreeMem(void *ptr)
5196 hendricks2 555
{
556
    MEM_HDRp mhp;
5198 hendricks2 557
    uint8_t* check;
5196 hendricks2 558
 
559
    ASSERT(ptr != NULL);
560
 
561
    ASSERT(ValidPtr(ptr));
562
 
5198 hendricks2 563
    mhp = (MEM_HDRp)(((uint8_t*) ptr) - sizeof(MEM_HDR));
564
    check = (uint8_t*)&mhp->size;
5196 hendricks2 565
 
566
    memset(mhp, 0xCC, mhp->size + sizeof(MEM_HDR));
567
 
568
    free(mhp);
569
}
570
 
571
#else
5198 hendricks2 572
SWBOOL
573
ValidPtr(void *ptr)
5196 hendricks2 574
{
575
    return TRUE;
576
}
577
 
5198 hendricks2 578
void *
5196 hendricks2 579
AllocMem(int size)
580
{
581
    return malloc(size);
582
}
583
 
5198 hendricks2 584
void *
5196 hendricks2 585
CallocMem(int size, int num)
586
{
587
    return calloc(size, num);
588
}
589
 
5198 hendricks2 590
void *
591
ReAllocMem(void *ptr, int size)
5196 hendricks2 592
{
593
    return realloc(ptr, size);
594
}
595
 
5198 hendricks2 596
void
597
FreeMem(void *ptr)
5196 hendricks2 598
{
599
    free(ptr);
600
}
601
 
602
#endif
603
 
604
int PointOnLine(int x, int y, int x1, int y1, int x2, int y2)
605
{
606
    // the closer to 0 the closer to the line the point is
607
    return ((x2 - x1) * (y - y1)) - ((y2 - y1) * (x - x1));
608
}
609
 
610
int
611
Distance(int x1, int y1, int x2, int y2)
612
{
613
    int min;
614
 
615
    if ((x2 = x2 - x1) < 0)
616
        x2 = -x2;
617
 
618
    if ((y2 = y2 - y1) < 0)
619
        y2 = -y2;
620
 
621
    if (x2 > y2)
622
        min = y2;
623
    else
624
        min = x2;
625
 
626
    return x2 + y2 - DIV2(min);
627
}
628
 
5198 hendricks2 629
void
630
MapSetAll2D(uint8_t fill)
5196 hendricks2 631
{
632
    int i;
633
 
634
    for (i = 0; i < (MAXWALLS >> 3); i++)
635
        show2dwall[i] = fill;
636
    for (i = 0; i < (MAXSPRITES >> 3); i++)
637
        show2dsprite[i] = fill;
638
 
639
    //for (i = 0; i < (MAXSECTORS >> 3); i++)
640
    for (i = 0; i < MAXSECTORS; i++)
641
    {
642
        if (sector[i].ceilingpicnum != 342 && sector[i].floorpicnum != 342)
643
            show2dsector[i>>3] |= (1<<(i&7));
644
        //show2dsector[i] = fill;
645
    }
646
}
647
 
5198 hendricks2 648
void
649
MapSetup(void)
5196 hendricks2 650
{
651
    MapSetAll2D(0xFF);
652
}
653
 
5198 hendricks2 654
void
655
setup2dscreen(void)
5196 hendricks2 656
{
657
    // qsetmode640350();
658
}
659
 
660
 
661
 
5198 hendricks2 662
void
663
TerminateGame(void)
5196 hendricks2 664
{
665
    int i,j;
666
    int oldtotalclock;
667
 
668
    DemoTerm();
669
 
670
    ErrorCorrectionQuit();
671
 
672
    uninitmultiplayers();
673
 
674
    if (CleanExit)
675
    {
676
        SybexScreen();
677
        //TenScreen();
678
    }
679
 
680
    ////--->>>> sound stuff was there
681
    //uninitkeys();
682
    KB_Shutdown();
683
 
684
    TermSetup();
685
 
686
    //Terminate3DSounds();                // Kill the sounds linked list
687
    UnInitSound();
688
 
7509 hendricks2 689
    timerUninit();
5196 hendricks2 690
 
691
    if (CleanExit)
692
        DosScreen();
693
 
8270 hendricks2 694
    engineUnInit();
695
 
5196 hendricks2 696
    uninitgroupfile();
697
}
698
 
5198 hendricks2 699
void
7499 hendricks2 700
LoadLevel(const char *filename)
5196 hendricks2 701
{
702
    int pos;
703
 
7509 hendricks2 704
    if (engineLoadBoard(filename, SW_SHAREWARE ? 1 : 0, (vec3_t *)&Player[0], &Player[0].pang, &Player[0].cursectnum) == -1)
5196 hendricks2 705
    {
706
        TerminateGame();
707
#ifdef RENDERTYPEWIN
708
        {
709
            char msg[256];
710
            Bsnprintf(msg, 256, "Level not found: %s", filename);
711
            wm_msgbox(apptitle, msg);
712
        }
713
#else
714
        printf("Level Not Found: %s\n", filename);
715
#endif
716
        exit(0);
717
    }
718
}
719
 
5198 hendricks2 720
void
7499 hendricks2 721
LoadImages(const char *filename)
5196 hendricks2 722
{
723
    short ndx;
724
    FILE *fin;
725
 
7509 hendricks2 726
    if (artLoadFiles(filename, 32*1048576) == -1)
5196 hendricks2 727
    {
728
        TerminateGame();
729
#ifdef RENDERTYPEWIN
730
        {
731
            wm_msgbox(apptitle, "Art not found. Please check your GRP file.");
732
        }
733
#else
734
        printf("Art not found. Please check your GRP file.\n");
735
#endif
736
        exit(-1);
737
    }
738
}
739
 
740
void LoadDemoRun(void)
741
{
742
    short i;
743
    FILE *fin;
744
 
745
    fin = fopen("demos.run","r");
746
    if (fin)
747
    {
748
        memset(DemoName,'\0',sizeof(DemoName));
749
        for (i = 0; TRUE; i++)
750
        {
751
            if (fscanf(fin, "%s", DemoName[i]) == EOF)
752
                break;
753
        }
754
 
755
        fclose(fin);
756
    }
757
 
758
    memset(DemoText,'\0',sizeof(DemoText));
759
    fin = fopen("demotxt.run","r");
760
    if (fin)
761
    {
762
        fgets(ds, 6, fin);
763
        sscanf(ds,"%d",&DemoTextYstart);
764
        for (i = 0; TRUE; i++)
765
        {
766
            if (fgets(DemoText[i], SIZ(DemoText[0])-1, fin) == NULL)
767
                break;
768
        }
769
 
770
        fclose(fin);
771
    }
772
}
773
 
774
void DisplayDemoText(void)
775
{
776
    short w,h;
777
    short i;
778
 
779
    for (i = 0; i < 3; i++)
780
    {
781
        MNU_MeasureString(DemoText[i], &w, &h);
782
        PutStringTimer(Player, TEXT_TEST_COL(w), DemoTextYstart+(i*12), DemoText[i], 999);
783
    }
784
}
785
 
786
 
787
void Set_GameMode(void)
788
{
789
    extern int ScreenMode, ScreenWidth, ScreenHeight, ScreenBPP;
790
    int result;
791
    char ch;
792
 
793
    //DSPRINTF(ds,"ScreenMode %d, ScreenWidth %d, ScreenHeight %d",ScreenMode, ScreenWidth, ScreenHeight);
794
    //MONO_PRINT(ds);
795
    result = COVERsetgamemode(ScreenMode, ScreenWidth, ScreenHeight, ScreenBPP);
796
 
797
    if (result < 0)
798
    {
799
        buildprintf("Failure setting video mode %dx%dx%d %s! Attempting safer mode...",
800
                    ScreenWidth,ScreenHeight,ScreenBPP,ScreenMode ? "fullscreen" : "windowed");
801
        ScreenMode = 0;
802
        ScreenWidth = 640;
803
        ScreenHeight = 480;
804
        ScreenBPP = 8;
805
 
806
        result = COVERsetgamemode(ScreenMode, ScreenWidth, ScreenHeight, ScreenBPP);
807
        if (result < 0)
808
        {
809
            uninitmultiplayers();
810
            //uninitkeys();
811
            KB_Shutdown();
812
            TermSetup();
813
            UnInitSound();
7509 hendricks2 814
            timerUninit();
5196 hendricks2 815
            DosScreen();
816
            uninitgroupfile();
817
            exit(0);
818
        }
819
    }
820
}
821
 
822
void MultiSharewareCheck(void)
823
{
824
    if (!SW_SHAREWARE) return;
825
    if (numplayers > 4)
826
    {
827
#ifdef RENDERTYPEWIN
828
        wm_msgbox(apptitle,"To play a Network game with more than 4 players you must purchase "
829
                  "the full version.  Read the Ordering Info screens for details.");
830
#else
831
        printf(
832
            "\n\nTo play a Network game with more than 4 players you must purchase the\n"
833
            "full version.  Read the Ordering Info screens for details.\n\n");
834
#endif
835
        uninitmultiplayers();
836
        //uninitkeys();
837
        KB_Shutdown();
838
        TermSetup();
839
        UnInitSound();
7509 hendricks2 840
        timerUninit();
8270 hendricks2 841
        engineUnInit();
5196 hendricks2 842
        uninitgroupfile();
843
        exit(0);
844
    }
845
}
846
 
847
 
848
// Some mem crap for Jim
849
// I reserve 1 meg of heap space for our use out side the cache
850
int TotalMemory = 0;
851
int ActualHeap = 0;
852
 
5198 hendricks2 853
void InitAutoNet(void)
5196 hendricks2 854
{
855
    if (!AutoNet)
856
        return;
857
 
858
    gs.NetGameType      = Auto.Rules;
859
    gs.NetLevel         = Auto.Level;
860
    gs.NetMonsters      = Auto.Enemy;
861
    gs.NetSpawnMarkers  = Auto.Markers;
862
    gs.NetTeamPlay      = Auto.Team;
863
    gs.NetHurtTeammate  = Auto.HurtTeam;
864
    gs.NetKillLimit     = Auto.Kill;
865
    gs.NetTimeLimit     = Auto.Time;
866
    gs.NetColor         = Auto.Color;
867
    gs.NetNuke          = Auto.Nuke;
868
}
869
 
870
 
871
void AnimateCacheCursor(void)
872
{
873
#if 0
874
    struct rccoord old_pos;
875
    static short cursor_num = 0;
876
    static char cache_cursor[] =  {'|','/','-','\\'};
877
 
878
    if (GraphicsMode)
879
        return;
880
 
881
    cursor_num++;
882
    if (cursor_num > 3)
883
        cursor_num = 0;
884
 
885
    //old_pos = _gettextposition();
886
    //_settextposition( old_pos.row, old_pos.col );
887
    //_settextposition( 24,  25);
888
    _settextposition(25,  0);
889
    sprintf(ds,"Loading sound and graphics %c", cache_cursor[cursor_num]);
890
    _outtext(ds);
891
    //_settextposition( old_pos.row, old_pos.col );
892
#endif
893
}
894
 
895
void COVERsetbrightness(int bright, unsigned char *pal)
896
{
8272 hendricks2 897
    paletteSetColorTable(BASEPAL, pal);
898
    videoSetPalette(bright, BASEPAL, 0);
5196 hendricks2 899
}
900
 
901
 
902
static int firstnet = 0;    // JBF
903
int nextvoxid = 0;  // JBF
904
 
905
extern int startwin_run(void);
906
 
5345 hendricks2 907
static void SW_FatalEngineError(void)
908
{
909
    wm_msgbox("Build Engine Initialisation Error",
910
              "There was a problem initialising the Build engine: %s", engineerrstr);
911
    exit(1);
912
}
913
 
5198 hendricks2 914
void
5552 hendricks2 915
InitGame(int32_t argc, char const * const * argv)
5196 hendricks2 916
{
917
    extern int MovesPerPacket;
918
    //void *ReserveMem=NULL;
919
    int i;
920
 
921
    DSPRINTF(ds,"InitGame...");
922
    MONO_PRINT(ds);
923
 
7509 hendricks2 924
    if (engineInit())
5345 hendricks2 925
        SW_FatalEngineError();
5196 hendricks2 926
 
5217 hendricks2 927
    //initgroupfile(G_GrpFile());  // JBF: moving this close to start of program to detect shareware
5196 hendricks2 928
    InitSetup();
929
 
930
    InitAutoNet();
931
 
7509 hendricks2 932
    timerInit(120);
5196 hendricks2 933
 
934
    CON_InitConsole();  // Init console command list
935
 
936
    ////DSPRINTF(ds,"%s, %d",__FILE__,__LINE__);   MONO_PRINT(ds);
937
 
938
    //InitFX();
939
 
940
    memcpy(palette_data,palette,768);
941
    InitPalette();
942
    // sets numplayers, connecthead, connectpoint2, myconnectindex
943
 
944
    if (!firstnet)
945
        initmultiplayers(0, NULL, 0, 0, 0);
5206 hendricks2 946
    else if (initmultiplayersparms(argc - firstnet, &argv[firstnet]))
5196 hendricks2 947
    {
948
        buildputs("Waiting for players...\n");
949
        while (initmultiplayerscycle())
950
        {
951
            handleevents();
952
            if (quitevent)
953
            {
954
                QuitFlag = TRUE;
955
                return;
956
            }
957
        }
958
    }
959
    initsynccrc();
960
 
961
    // code to duplicate packets
962
    if (numplayers > 4 && MovesPerPacket == 1)
963
    {
964
        MovesPerPacket = 2;
965
    }
966
 
967
    MultiSharewareCheck();
968
 
969
    if (numplayers > 1)
970
    {
971
        CommPlayers = numplayers;
972
        OrigCommPlayers = CommPlayers;
973
        CommEnabled = TRUE;
974
        if (!BotMode)
975
            gNet.MultiGameType = MULTI_GAME_COMMBAT;
976
        else
977
            gNet.MultiGameType = MULTI_GAME_AI_BOTS;
978
 
979
#if 0 //def NET_MODE_MASTER_SLAVE
980
        if (!NetModeOverride)
981
        {
982
            if (numplayers <= 4)
983
                NetBroadcastMode = TRUE;
984
            else
985
                NetBroadcastMode = FALSE;
986
        }
987
#endif
988
    }
989
 
990
    LoadDemoRun();
991
    // Save off total heap for later calculations
992
    //TotalMemory = Z_AvailHeap();
993
    //DSPRINTF(ds,"Available Heap before LoadImages =  %d", TotalMemory);
994
    //MONO_PRINT(ds);
995
    // Reserve 1.5 megs for normal program use
996
    // Generally, SW is consuming about a total of 11 megs including
997
    // all the cached in graphics, etc. per level, so even on a 16 meg
998
    // system, reserving 1.5 megs is fine.
999
    // Note that on a 16 meg machine, Ken was leaving us about
1000
    // 24k for use outside the cache!  This was causing out of mem problems
1001
    // when songs, etc., greater than the remaining heap were being loaded.
1002
    // Even if you pre-cache songs, etc. to help, reserving some heap is
1003
    // a very smart idea since the game uses malloc throughout execution.
1004
    //ReserveMem = AllocMem(1L<<20);
1005
    //if(ReserveMem == 0) MONO_PRINT("Could not allocate 1.5 meg reserve!");
1006
 
1007
    // LoadImages will now proceed to steal all the remaining heap space
1008
    //_outtext("\n\n\n\n\n\n\n\n");
1009
    //AnimateCacheCursor();
1010
    buildputs("Loading sound and graphics...\n");
1011
    LoadImages("tiles000.art");
1012
 
1013
    // Now free it up for later use
1014
    /*
1015
    if(ReserveMem)
1016
        {
1017
        // Recalc TotalMemory for later reference
1018
        ActualHeap = Z_AvailHeap() + 1536000L;
1019
        FreeMem(ReserveMem);
1020
        }
1021
    */
1022
 
1023
    Connect();
1024
    SortBreakInfo();
1025
    parallaxtype = 1;
5211 hendricks2 1026
    SW_InitMultiPsky();
5196 hendricks2 1027
 
1028
    memset(Track, 0, sizeof(Track));
1029
 
1030
    memset(Player, 0, sizeof(Player));
1031
    for (i = 0; i < MAX_SW_PLAYERS; i++)
1032
        INITLIST(&Player[i].PanelSpriteList);
1033
 
1034
    LoadKVXFromScript("swvoxfil.txt");    // Load voxels from script file
1035
    LoadPLockFromScript("swplock.txt");   // Get Parental Lock setup info
1036
    if (!SW_SHAREWARE)
1037
        LoadCustomInfoFromScript("swcustom.txt");   // Load user customisation information
1038
 
5217 hendricks2 1039
    if (!loaddefinitionsfile(G_DefFile())) buildputs("Definitions file loaded.\n");
5196 hendricks2 1040
 
6673 hendricks2 1041
    for (char * m : g_defModules)
1042
        free(m);
1043
    g_defModules.clear();
5217 hendricks2 1044
 
7509 hendricks2 1045
    if (enginePostInit())
5345 hendricks2 1046
        SW_FatalEngineError();
1047
 
5196 hendricks2 1048
    DemoModeMenuInit = TRUE;
1049
    // precache as much stuff as you can
1050
    if (UserMapName[0] == '\0')
1051
    {
1052
        AnimateCacheCursor();
1053
        LoadLevel("$dozer.map");
1054
        AnimateCacheCursor();
1055
        SetupPreCache();
1056
        DoTheCache();
1057
    }
1058
    else
1059
    {
1060
        AnimateCacheCursor();
1061
        LoadLevel(UserMapName);
1062
        AnimateCacheCursor();
1063
        SetupPreCache();
1064
        DoTheCache();
1065
    }
1066
 
1067
    Set_GameMode();
1068
    GraphicsMode = TRUE;
1069
    SetupAspectRatio();
1070
 
1071
    COVERsetbrightness(gs.Brightness,&palette_data[0][0]);
1072
 
1073
    InitFX();   // JBF: do it down here so we get a hold of the window handle
1074
    InitMusic();
1075
 
1076
}
1077
 
1078
 
1079
/*
1080
Directory of C:\DEV\SW\MIDI
1081
EXECUT11 MID
1082
HROSHMA6 MID
1083
HOSHIA02 MID
1084
INTRO131 MID
1085
KOTEC2   MID
1086
KOTOKI12 MID
1087
NIPPON34 MID
1088
NOKI41   MID
1089
SANAI    MID
1090
SIANRA23 MID
1091
TKYO2007 MID
1092
TYTAIK16 MID
1093
YOKOHA03 MID
1094
*/
1095
 
1096
char LevelSong[16];
1097
short SongLevelNum;
1098
//#ifndef SW_SHAREWARE
1099
LEVEL_INFO LevelInfo[MAX_LEVELS_REG+2] =
1100
{
1101
    {"title.map",      "theme.mid", " ", " ", " "  },
1102
    {"$bullet.map",    "e1l01.mid", "Seppuku Station", "0 : 55", "5 : 00"  },
1103
    {"$dozer.map",     "e1l03.mid", "Zilla Construction", "4 : 59", "8 : 00"  },
1104
    {"$shrine.map",    "e1l02.mid", "Master Leep's Temple", "3 : 16", "10 : 00"  },
1105
    {"$woods.map",     "e1l04.mid", "Dark Woods of the Serpent", "7 : 06", "16 : 00"  },
1106
    {"$whirl.map",     "yokoha03.mid", "Rising Son", "5 : 30", "10 : 00"   },
1107
    {"$tank.map",      "nippon34.mid", "Killing Fields", "1 : 46", "4 : 00"   },
1108
    {"$boat.map",      "execut11.mid", "Hara-Kiri Harbor", "1 : 56", "4 : 00"   },
1109
    {"$garden.map",    "execut11.mid", "Zilla's Villa", "1 : 06", "2 : 00"   },
1110
    {"$outpost.map",   "sanai.mid",    "Monastery", "1 : 23", "3 : 00"      },
1111
    {"$hidtemp.map",   "kotec2.mid",   "Raider of the Lost Wang", "2 : 05", "4 : 10"     },
1112
    {"$plax1.map",     "kotec2.mid",   "Sumo Sky Palace", "6 : 32", "12 : 00"     },
1113
    {"$bath.map",      "yokoha03.mid", "Bath House", "10 : 00", "10 : 00"   },
1114
    {"$airport.map",   "nippon34.mid", "Unfriendly Skies", "2 : 59", "6 : 00"   },
1115
    {"$refiner.map",   "kotoki12.mid", "Crude Oil", "2 : 40", "5 : 00"   },
1116
    {"$newmine.map",   "hoshia02.mid", "Coolie Mines", "2 : 48", "6 : 00"   },
1117
    {"$subbase.map",   "hoshia02.mid", "Subpen 7", "2 : 02", "4 : 00"   },
1118
    {"$rock.map",      "kotoki12.mid", "The Great Escape", "3 : 18", "6 : 00"   },
1119
    {"$yamato.map",    "sanai.mid",    "Floating Fortress", "11 : 38", "20 : 00"      },
1120
    {"$seabase.map",   "kotec2.mid",   "Water Torture", "5 : 07", "10 : 00"     },
1121
    {"$volcano.map",   "kotec2.mid",   "Stone Rain", "9 : 15", "20 : 00"     },
1122
    {"$shore.map",     "kotec2.mid",   "Shanghai Shipwreck", "3 : 58", "8 : 00"     },
1123
    {"$auto.map",      "kotec2.mid",   "Auto Maul", "4 : 07", "8 : 00"     },
1124
    {"tank.map",       "kotec2.mid",   "Heavy Metal (DM only)", "10 : 00", "10 : 00"     },
1125
    {"$dmwoods.map",   "kotec2.mid",   "Ripper Valley (DM only)", "10 : 00", "10 : 00"     },
1126
    {"$dmshrin.map",   "kotec2.mid",   "House of Wang (DM only)", "10 : 00", "10 : 00"     },
1127
    {"$rush.map",      "kotec2.mid",   "Lo Wang Rally (DM only)", "10 : 00", "10 : 00"     },
1128
    {"shotgun.map",    "kotec2.mid",   "Ruins of the Ronin (CTF)", "10 : 00", "10 : 00"     },
1129
    {"$dmdrop.map",    "kotec2.mid",   "Killing Fields (CTF)", "10 : 00", "10 : 00"     },
1130
    {NULL, NULL, NULL, NULL, NULL}
1131
};
1132
/*#else
1133
LEVEL_INFO LevelInfo[MAX_LEVELS+2] =  // Shareware
1134
    {
1135
    {"title.map",      "theme.mid", " ", " ", " "  },
1136
    {"$bullet.map",    "e1l01.mid", "Seppuku Station", "0 : 55", "5 : 00"  },
1137
    {"$dozer.map",     "e1l03.mid", "Zilla Construction", "4 : 59", "8 : 00"  },
1138
    {"$shrine.map",    "e1l02.mid", "Master Leep's Temple", "3 : 16", "10 : 00"  },
1139
    {"$woods.map",     "e1l04.mid", "Dark Woods of the Serpent", "7 : 06", "16 : 00"  },
1140
    {NULL, NULL, NULL, NULL, NULL}
1141
    };
1142
#endif*/
1143
 
1144
char EpisodeNames[2][MAX_EPISODE_NAME_LEN+2] =
1145
{
1146
    "^Enter the Wang",
1147
    "^Code of Honor"
1148
};
1149
char EpisodeSubtitles[2][MAX_EPISODE_SUBTITLE_LEN+1] =
1150
{
1151
    "Four levels (Shareware Version)",
1152
    "Eighteen levels (Full Version Only)"
1153
};
1154
char SkillNames[4][MAX_SKILL_NAME_LEN+2] =
1155
{
1156
    "^Tiny grasshopper",
1157
    "^I Have No Fear",
1158
    "^Who Wants Wang",
1159
    "^No Pain, No Gain"
1160
};
1161
 
5198 hendricks2 1162
void InitNewGame(void)
5196 hendricks2 1163
{
1164
    int i, ready_bak;
1165
    int ver_bak;
1166
 
1167
    //waitforeverybody();           // since ready flag resets after this point, need to carefully sync
1168
 
1169
    for (i = 0; i < MAX_SW_PLAYERS; i++)
1170
    {
1171
        // don't jack with the playerreadyflag
1172
        ready_bak = Player[i].playerreadyflag;
1173
        ver_bak = Player[i].PlayerVersion;
1174
        memset(&Player[i], 0, sizeof(Player[i]));
1175
        Player[i].playerreadyflag = ready_bak;
1176
        Player[i].PlayerVersion = ver_bak;
1177
        INITLIST(&Player[i].PanelSpriteList);
1178
    }
1179
 
1180
    memset(puser, 0, sizeof(puser));
1181
}
1182
 
1183
void FindLevelInfo(char *map_name, short *level)
1184
{
1185
    char *ptr;
1186
    char buff[16];
1187
    short i,j;
1188
 
1189
    for (j = 1; j <= MAX_LEVELS; j++)
1190
    {
1191
        if (LevelInfo[j].LevelName)
1192
        {
1193
            if (Bstrcasecmp(map_name, LevelInfo[j].LevelName) == 0)
1194
            {
1195
                *level = j;
1196
                return;
1197
            }
1198
        }
1199
    }
1200
 
1201
    *level = 0;
1202
    return;
1203
}
1204
 
1205
int ChopTics;
5198 hendricks2 1206
void InitLevelGlobals(void)
5196 hendricks2 1207
{
1208
    extern char PlayerGravity;
1209
    extern short wait_active_check_offset;
1210
    //extern short Zombies;
1211
    extern int PlaxCeilGlobZadjust, PlaxFloorGlobZadjust;
5198 hendricks2 1212
    extern SWBOOL left_foot;
1213
    extern SWBOOL serpwasseen;
1214
    extern SWBOOL sumowasseen;
1215
    extern SWBOOL zillawasseen;
5196 hendricks2 1216
    extern short BossSpriteNum[3];
1217
 
1218
    // A few IMPORTANT GLOBAL RESETS
1219
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1
1220
    MapSetup();
1221
    //Zombies = 0;
1222
    ChopTics = 0;
1223
    dimensionmode = 3;
1224
    zoom = 768;
1225
    PlayerGravity = 24;
1226
    wait_active_check_offset = 0;
1227
    PlaxCeilGlobZadjust = PlaxFloorGlobZadjust = Z(500);
1228
    FinishedLevel = FALSE;
1229
    AnimCnt = 0;
1230
    left_foot = FALSE;
1231
    screenpeek = myconnectindex;
1232
 
1233
    gNet.TimeLimitClock = gNet.TimeLimit;
1234
 
1235
    serpwasseen = FALSE;
1236
    sumowasseen = FALSE;
1237
    zillawasseen = FALSE;
1238
    memset(BossSpriteNum,-1,sizeof(BossSpriteNum));
1239
}
1240
 
5198 hendricks2 1241
void InitLevelGlobals2(void)
5196 hendricks2 1242
{
1243
    extern short Bunny_Count;
1244
    // GLOBAL RESETS NOT DONE for LOAD GAME
1245
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1246
    InitTimingVars();
1247
    TotalKillable = 0;
1248
    Bunny_Count = 0;
1249
}
1250
 
5198 hendricks2 1251
void
1252
InitLevel(void)
5196 hendricks2 1253
{
1254
    static int DemoNumber = 0;
1255
 
1256
    MONO_PRINT("InitLevel");
1257
    Terminate3DSounds();
1258
 
1259
    // A few IMPORTANT GLOBAL RESETS
1260
    InitLevelGlobals();
1261
    MONO_PRINT("InitLevelGlobals");
1262
    if (!DemoMode)
1263
        StopSong();
1264
 
1265
    if (LoadGameOutsideMoveLoop)
1266
    {
1267
        MONO_PRINT("Returning from InitLevel");
1268
        return;
1269
    }
1270
 
1271
    InitLevelGlobals2();
1272
    MONO_PRINT("InitLevelGlobals2");
1273
    if (DemoMode)
1274
    {
1275
        Level = 0;
1276
        NewGame = TRUE;
1277
        DemoInitOnce = FALSE;
1278
        strcpy(DemoFileName, DemoName[DemoNumber]);
1279
        DemoNumber++;
1280
        if (!DemoName[DemoNumber][0])
1281
            DemoNumber = 0;
1282
 
1283
        // read header and such
1284
        DemoPlaySetup();
1285
 
1286
        strcpy(LevelName, DemoLevelName);
1287
 
1288
        FindLevelInfo(LevelName, &Level);
1289
        if (Level > 0)
1290
        {
1291
            strcpy(LevelSong, LevelInfo[Level].SongName);
1292
            strcpy(LevelName, LevelInfo[Level].LevelName);
1293
            UserMapName[0] = '\0';
1294
        }
1295
        else
1296
        {
1297
            strcpy(UserMapName, DemoLevelName);
1298
            Level = 0;
1299
        }
1300
 
1301
    }
1302
    else
1303
    {
1304
        if (Level < 0)
1305
            Level = 0;
1306
 
1307
        if (Level > MAX_LEVELS)
1308
            Level = 1;
1309
 
1310
        // extra code in case something is resetting these values
1311
        if (NewGame)
1312
        {
1313
            //Level = 1;
1314
            //DemoPlaying = FALSE;
1315
            DemoMode = FALSE;
1316
            //DemoRecording = FALSE;
1317
            //DemoEdit = FALSE;
1318
        }
1319
 
1320
        if (UserMapName[0])
1321
        {
1322
            strcpy(LevelName, UserMapName);
1323
 
1324
            Level = 0;
1325
            FindLevelInfo(UserMapName, &Level);
1326
 
1327
            if (Level > 0)
1328
            {
1329
                // user map is part of game - treat it as such
1330
                strcpy(LevelSong, LevelInfo[Level].SongName);
1331
                strcpy(LevelName, LevelInfo[Level].LevelName);
1332
                UserMapName[0] = '\0';
1333
            }
1334
        }
1335
        else
1336
        {
1337
            strcpy(LevelName, LevelInfo[Level].LevelName);
1338
            strcpy(LevelSong, LevelInfo[Level].SongName);
1339
        }
1340
    }
1341
 
1342
    PlayingLevel = Level;
1343
 
1344
    if (NewGame)
1345
        InitNewGame();
1346
 
1347
    LoadingLevelScreen(LevelName);
1348
    MONO_PRINT("LoadintLevelScreen");
1349
    if (!DemoMode && !DemoInitOnce)
1350
        DemoPlaySetup();
1351
 
1352
    LoadLevel(LevelName);
1353
 
1354
    if (Bstrcasecmp(CacheLastLevel, LevelName) != 0)
1355
        // clears gotpic and does some bit setting
1356
        SetupPreCache();
1357
    else
1358
        memset(gotpic,0,sizeof(gotpic));
1359
 
1360
    if (sector[0].extra != -1)
1361
    {
5207 hendricks2 1362
        NormalVisibility = g_visibility = sector[0].extra;
5196 hendricks2 1363
        sector[0].extra = 0;
1364
    }
1365
    else
5207 hendricks2 1366
        NormalVisibility = g_visibility;
5196 hendricks2 1367
 
1368
    //
1369
    // Do Player stuff first
1370
    //
1371
 
1372
    InitAllPlayers();
1373
 
1374
#if DEBUG
1375
    // fake Multi-player game setup
1376
    if (FakeMultiNumPlayers && !BotMode)
1377
    {
5198 hendricks2 1378
        uint8_t i;
5196 hendricks2 1379
 
1380
        // insert all needed players except the first one - its already tere
1381
        for (i = 0; i < FakeMultiNumPlayers - 1; i++)
1382
        {
1383
            ManualPlayerInsert(Player);
1384
            // reset control back to 1st player
1385
            myconnectindex = 0;
1386
            screenpeek = 0;
1387
        }
1388
    }
1389
#endif
1390
 
1391
    // Put in the BOTS if called for
1392
    if (FakeMultiNumPlayers && BotMode)
1393
    {
5198 hendricks2 1394
        uint8_t i;
5196 hendricks2 1395
 
1396
        // insert all needed players except the first one - its already tere
1397
        for (i = 0; i < FakeMultiNumPlayers; i++)
1398
        {
1399
            BotPlayerInsert(Player);
1400
            // reset control back to 1st player
1401
            myconnectindex = 0;
1402
            screenpeek = 0;
1403
        }
1404
    }
1405
 
1406
    QueueReset();
1407
    PreMapCombineFloors();
1408
    InitMultiPlayerInfo();
1409
    InitAllPlayerSprites();
1410
 
1411
    //
1412
    // Do setup for sprite, track, panel, sector, etc
1413
    //
1414
 
1415
    // Set levels up
1416
    InitTimingVars();
1417
 
1418
    SpriteSetup();
1419
    SpriteSetupPost(); // post processing - already gone once through the loop
1420
    InitLighting();
1421
 
1422
    TrackSetup();
1423
 
1424
    PlayerPanelSetup();
1425
    MapSetup();
1426
    SectorSetup();
1427
    JS_InitMirrors();
1428
    JS_InitLockouts();   // Setup the lockout linked lists
1429
    JS_ToggleLockouts(); // Init lockouts on/off
1430
 
1431
    PlaceSectorObjectsOnTracks();
1432
    PlaceActorsOnTracks();
1433
    PostSetupSectorObject();
1434
    SetupMirrorTiles();
1435
    initlava();
1436
 
1437
    SongLevelNum = Level;
1438
 
1439
    if (DemoMode)
1440
    {
1441
        DisplayDemoText();
1442
    }
1443
 
1444
 
1445
    if (ArgCheat)
1446
    {
5198 hendricks2 1447
        SWBOOL bak = gs.Messages;
5196 hendricks2 1448
        gs.Messages = FALSE;
1449
        EveryCheatToggle(&Player[0],NULL);
1450
        gs.Messages = bak;
1451
        GodMode = TRUE;
1452
    }
1453
 
1454
    // reset NewGame
1455
    NewGame = FALSE;
1456
 
1457
    DSPRINTF(ds,"End of InitLevel...");
1458
    MONO_PRINT(ds);
1459
 
1460
#if 0
1461
#if DEBUG
1462
    if (!cansee(43594, -92986, 0x3fffffff, 290,
1463
                43180, -91707, 0x3fffffff, 290))
1464
    {
1465
        DSPRINTF(ds,"cansee failed");
1466
        MONO_PRINT(ds);
1467
    }
1468
#endif
1469
#endif
1470
 
1471
}
1472
 
1473
 
5198 hendricks2 1474
void
1475
TerminateLevel(void)
5196 hendricks2 1476
{
5198 hendricks2 1477
    void pClearSpriteList(PLAYERp pp);
5196 hendricks2 1478
    int i, nexti, stat, pnum, ndx;
1479
    SECT_USERp *sectu;
1480
 
1481
//HEAP_CHECK();
1482
 
1483
    DemoTerm();
1484
 
1485
    // Free any track points
1486
    for (ndx = 0; ndx < MAX_TRACKS; ndx++)
1487
    {
1488
        if (Track[ndx].TrackPoint)
1489
        {
1490
            FreeMem(Track[ndx].TrackPoint);
1491
            // !JIM! I added null assigner
1492
            Track[ndx].TrackPoint = NULL;
1493
        }
1494
    }
1495
 
1496
    // Clear the tracks
1497
    memset(Track, 0, sizeof(Track));
1498
 
1499
    StopSound();
1500
    Terminate3DSounds();        // Kill the 3d sounds linked list
1501
    //ClearSoundLocks();
1502
 
1503
    // Clear all anims and any memory associated with them
1504
    // Clear before killing sprites - save a little time
1505
    //AnimClear();
1506
 
1507
    for (stat = STAT_PLAYER0; stat < STAT_PLAYER0 + numplayers; stat++)
1508
    {
1509
 
1510
        pnum = stat - STAT_PLAYER0;
1511
 
1512
        TRAVERSE_SPRITE_STAT(headspritestat[stat], i, nexti)
1513
        {
1514
            if (User[i])
1515
                memcpy(&puser[pnum], User[i], sizeof(USER));
1516
        }
1517
    }
1518
 
1519
    // Kill User memory and delete sprites
1520
    // for (stat = 0; stat < STAT_ALL; stat++)
1521
    for (stat = 0; stat < MAXSTATUS; stat++)
1522
    {
1523
        TRAVERSE_SPRITE_STAT(headspritestat[stat], i, nexti)
1524
        {
1525
            KillSprite(i);
1526
        }
1527
    }
1528
 
1529
    // Free SectUser memory
1530
    for (sectu = &SectUser[0];
1531
         sectu < &SectUser[MAXSECTORS];
1532
         sectu++)
1533
    {
1534
        if (*sectu)
1535
        {
1536
            ////DSPRINTF(ds,"Sect User Free %d",sectu-SectUser);
1537
            //MONO_PRINT(ds);
1538
            FreeMem(*sectu);
1539
            *sectu = NULL;
1540
        }
1541
    }
1542
 
1543
    //memset(&User[0], 0, sizeof(User));
1544
    memset(&SectUser[0], 0, sizeof(SectUser));
1545
 
1546
    TRAVERSE_CONNECT(pnum)
1547
    {
1548
        PLAYERp pp = Player + pnum;
1549
 
1550
        // Free panel sprites for players
1551
        pClearSpriteList(pp);
1552
 
1553
        pp->DoPlayerAction = NULL;
1554
 
1555
        pp->SpriteP = NULL;
1556
        pp->PlayerSprite = -1;
1557
 
1558
        pp->UnderSpriteP = NULL;
1559
        pp->PlayerUnderSprite = -1;
1560
 
1561
        memset(pp->HasKey, 0, sizeof(pp->HasKey));
1562
 
1563
        //pp->WpnFlags = 0;
1564
        pp->CurWpn = NULL;
1565
 
1566
        memset(pp->Wpn, 0, sizeof(pp->Wpn));
1567
        memset(pp->InventorySprite, 0, sizeof(pp->InventorySprite));
1568
        memset(pp->InventoryTics, 0, sizeof(pp->InventoryTics));
1569
 
1570
        pp->Killer = -1;
1571
 
1572
        INITLIST(&pp->PanelSpriteList);
1573
    }
1574
 
1575
    JS_UnInitLockouts();
1576
 
1577
//HEAP_CHECK();
1578
}
1579
 
5198 hendricks2 1580
void
1581
NewLevel(void)
5196 hendricks2 1582
{
1583
 
1584
    DSPRINTF(ds,"NewLevel");
1585
    MONO_PRINT(ds);
1586
 
1587
    if (DemoPlaying)
1588
    {
1589
        FX_SetVolume(0); // Shut the hell up while game is loading!
1590
        InitLevel();
1591
        InitRunLevel();
1592
 
1593
        DemoInitOnce = FALSE;
1594
        if (DemoMode)
1595
        {
1596
            if (DemoModeMenuInit)
1597
            {
1598
                DemoModeMenuInit = FALSE;
1599
                KEY_PRESSED(KEYSC_ESC) = TRUE;
1600
            }
1601
        }
1602
 
1603
        DemoPlayBack();
1604
 
1605
        if (DemoRecording && DemoEdit)
1606
        {
1607
            RunLevel();
1608
        }
1609
    }
1610
    else
1611
    {
1612
        DSPRINTF(ds,"Calling FX_SetVolume");
1613
        MONO_PRINT(ds);
1614
        FX_SetVolume(0); // Shut the hell up while game is loading!
1615
 
1616
        DSPRINTF(ds,"Calling InitLevel");
1617
        MONO_PRINT(ds);
1618
        InitLevel();
1619
 
1620
        DSPRINTF(ds,"Calling RunLevel");
1621
        MONO_PRINT(ds);
1622
        RunLevel();
1623
 
1624
        if (!QuitFlag)
1625
        {
1626
            // for good measure do this
1627
            ready2send = 0;
1628
            waitforeverybody();
1629
        }
1630
 
1631
        StatScreen(&Player[myconnectindex]);
1632
    }
1633
 
1634
    if (LoadGameFromDemo)
1635
        LoadGameFromDemo = FALSE;
1636
    else
1637
        TerminateLevel();
1638
 
1639
    InGame = FALSE;
1640
 
1641
    if (SW_SHAREWARE)
1642
    {
1643
        if (FinishAnim)
8271 hendricks2 1644
        {
1645
            PlayTheme();
5196 hendricks2 1646
            MenuLevel();
8271 hendricks2 1647
        }
5196 hendricks2 1648
    }
1649
    else
1650
    {
1651
        if (FinishAnim == ANIM_ZILLA || FinishAnim == ANIM_SERP)
8271 hendricks2 1652
        {
1653
            PlayTheme();
5196 hendricks2 1654
            MenuLevel();
8271 hendricks2 1655
        }
5196 hendricks2 1656
    }
1657
    FinishAnim = 0;
1658
}
1659
 
5198 hendricks2 1660
void
1661
ResetKeys(void)
5196 hendricks2 1662
{
1663
    int i;
1664
 
1665
    for (i = 0; i < MAXKEYBOARDSCAN; i++)
1666
    {
1667
        KEY_PRESSED(i) = 0;
1668
    }
1669
}
1670
 
5198 hendricks2 1671
SWBOOL
1672
KeyPressed(void)
5196 hendricks2 1673
{
1674
    int i;
1675
 
1676
    for (i = 0; i < MAXKEYBOARDSCAN; i++)
1677
    {
1678
        if (KEY_PRESSED(i))
1679
            return TRUE;
1680
    }
1681
 
1682
    return FALSE;
1683
}
1684
 
5198 hendricks2 1685
uint8_t*
1686
KeyPressedRange(uint8_t* kb, uint8_t* ke)
5196 hendricks2 1687
{
5198 hendricks2 1688
    uint8_t* k;
5196 hendricks2 1689
 
1690
    for (k = kb; k <= ke; k++)
1691
    {
1692
        if (*k)
1693
            return k;
1694
    }
1695
 
1696
    return NULL;
1697
}
1698
 
5198 hendricks2 1699
void
1700
ResetKeyRange(uint8_t* kb, uint8_t* ke)
5196 hendricks2 1701
{
5198 hendricks2 1702
    uint8_t* k;
5196 hendricks2 1703
 
1704
    for (k = kb; k <= ke; k++)
1705
    {
1706
        *k = 0;
1707
    }
1708
}
1709
 
8271 hendricks2 1710
void PlayTheme()
1711
{
1712
    // start music at logo
1713
    strcpy(LevelSong,"theme.mid");
1714
    PlaySong(LevelSong, RedBookSong[0], TRUE, TRUE);
5196 hendricks2 1715
 
8271 hendricks2 1716
    DSPRINTF(ds,"After music stuff...");
1717
    MONO_PRINT(ds);
1718
}
1719
 
5198 hendricks2 1720
void
1721
LogoLevel(void)
5196 hendricks2 1722
{
1723
    char called;
1724
    int fin;
1725
    unsigned char pal[PAL_SIZE];
1726
    UserInput uinfo = { FALSE, FALSE, dir_None };
1727
 
1728
 
1729
    DSPRINTF(ds,"LogoLevel...");
1730
    MONO_PRINT(ds);
1731
 
1732
    // PreCache Anim
1733
    LoadAnm(0);
1734
 
1735
    if ((fin = kopen4load("3drealms.pal", 0)) != -1)
1736
    {
1737
        kread(fin, pal, PAL_SIZE);
1738
        kclose(fin);
7509 hendricks2 1739
 
8272 hendricks2 1740
        for (auto & c : pal)
1741
            c <<= 2;
1742
 
1743
        paletteSetColorTable(DREALMSPAL, pal);
1744
        videoSetPalette(gs.Brightness, DREALMSPAL, 2);
5196 hendricks2 1745
    }
1746
    DSPRINTF(ds,"Just read in 3drealms.pal...");
1747
    MONO_PRINT(ds);
1748
 
1749
    //FadeOut(0, 0);
1750
    ready2send = 0;
1751
    totalclock = 0;
1752
    ototalclock = 0;
1753
 
1754
    DSPRINTF(ds,"About to display 3drealms pic...");
1755
    MONO_PRINT(ds);
1756
 
7509 hendricks2 1757
    videoClearViewableArea(0L);
5196 hendricks2 1758
    rotatesprite(0, 0, RS_SCALE, 0, THREED_REALMS_PIC, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
7509 hendricks2 1759
    videoNextPage();
5196 hendricks2 1760
    //FadeIn(0, 3);
1761
 
1762
    ResetKeys();
1763
    while (TRUE)
1764
    {
1765
        handleevents();
1766
        CONTROL_GetUserInput(&uinfo);
1767
        CONTROL_ClearUserInput(&uinfo);
1768
        if (quitevent) { QuitFlag = TRUE; break; }
1769
 
1770
        // taken from top of faketimerhandler
1771
        // limits checks to max of 40 times a second
1772
        if (totalclock >= ototalclock + synctics)
1773
        {
1774
            ototalclock += synctics;
1775
        }
1776
 
1777
        if (totalclock > 5*120 || KeyPressed() || uinfo.button0 || uinfo.button1)
1778
        {
1779
            break;
1780
        }
1781
    }
1782
 
7509 hendricks2 1783
    videoClearViewableArea(0L);
1784
    videoNextPage();
8272 hendricks2 1785
    videoSetPalette(gs.Brightness, BASEPAL, 2);
5196 hendricks2 1786
 
1787
    // put up a blank screen while loading
1788
 
1789
    DSPRINTF(ds,"End of LogoLevel...");
1790
    MONO_PRINT(ds);
1791
 
1792
}
1793
 
5198 hendricks2 1794
void
1795
CreditsLevel(void)
5196 hendricks2 1796
{
1797
    char called;
1798
    int fin;
1799
    int i;
1800
    int curpic;
1801
    int handle;
5198 hendricks2 1802
    uint32_t timer = 0;
5196 hendricks2 1803
    int zero=0;
1804
    short save;
1805
#define CREDITS1_PIC 5111
1806
#define CREDITS2_PIC 5118
1807
 
1808
    // put up a blank screen while loading
1809
 
1810
    // get rid of all PERM sprites!
7509 hendricks2 1811
    renderFlushPerms();
5196 hendricks2 1812
    save = gs.BorderNum;
1813
    SetBorder(Player + myconnectindex,0);
1814
    ClearStartMost();
1815
    gs.BorderNum = save;
7509 hendricks2 1816
    videoClearViewableArea(0L);
1817
    videoNextPage();
5196 hendricks2 1818
 
1819
    // Lo Wang feel like singing!
1820
    handle = PlaySound(DIGI_JG95012,&zero,&zero,&zero,v3df_none);
1821
 
1822
    if (handle > 0)
1823
        while (FX_SoundActive(handle)) ;
1824
 
1825
    // try 14 then 2 then quit
1826
    if (!PlaySong(NULL, 14, FALSE, TRUE))
1827
    {
1828
        if (!PlaySong(NULL, 2, FALSE, TRUE))
1829
        {
1830
            handle = PlaySound(DIGI_NOLIKEMUSIC,&zero,&zero,&zero,v3df_none);
1831
            if (handle > 0)
1832
                while (FX_SoundActive(handle)) handleevents();
1833
            return;
1834
        }
1835
    }
1836
 
1837
    ready2send = 0;
1838
    totalclock = 0;
1839
    ototalclock = 0;
1840
 
1841
    ResetKeys();
1842
    curpic = CREDITS1_PIC;
1843
 
1844
    while (TRUE)
1845
    {
1846
        // taken from top of faketimerhandler
1847
        // limits checks to max of 40 times a second
1848
        if (totalclock >= ototalclock + synctics)
1849
        {
1850
            ototalclock += synctics;
1851
            timer += synctics;
1852
        }
1853
 
1854
        rotatesprite(0, 0, RS_SCALE, 0, curpic, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
1855
 
7509 hendricks2 1856
        videoNextPage();
5196 hendricks2 1857
 
1858
        if (timer > 8*120)
1859
        {
1860
            curpic = CREDITS2_PIC;
1861
        }
1862
 
1863
        if (timer > 16*120)
1864
        {
1865
            timer = 0;
1866
            curpic = CREDITS1_PIC;
1867
        }
1868
 
1869
 
1870
        if (!SongIsPlaying())
1871
            break;
1872
 
1873
        if (KEY_PRESSED(KEYSC_ESC))
1874
            break;
1875
    }
1876
 
1877
    // put up a blank screen while loading
7509 hendricks2 1878
    videoClearViewableArea(0L);
1879
    videoNextPage();
5196 hendricks2 1880
    ResetKeys();
1881
    StopSong();
1882
}
1883
 
1884
 
5198 hendricks2 1885
void
1886
SybexScreen(void)
5196 hendricks2 1887
{
1888
    if (!SW_SHAREWARE) return;
1889
 
1890
    if (CommEnabled)
1891
        return;
1892
 
1893
    rotatesprite(0, 0, RS_SCALE, 0, 5261, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
7509 hendricks2 1894
    videoNextPage();
5196 hendricks2 1895
 
1896
    ResetKeys();
1897
    while (!KeyPressed() && !quitevent) handleevents();
1898
}
1899
 
1900
// CTW REMOVED
1901
/*
5198 hendricks2 1902
void
1903
TenScreen(void)
5196 hendricks2 1904
    {
1905
    char called;
1906
    int fin;
1907
    char backup_pal[256*3];
1908
    char pal[PAL_SIZE];
1909
    char tempbuf[256];
1910
    char *palook_bak = palookup[0];
1911
    int i;
5198 hendricks2 1912
    uint32_t bak;
5196 hendricks2 1913
    int bakready2send;
1914
 
1915
    if (CommEnabled)
1916
        return;
1917
 
1918
    bak = totalclock;
1919
 
1920
    flushperms();
1921
    clearview(0);
1922
    nextpage();
1923
 
1924
    for (i = 0; i < 256; i++)
1925
        tempbuf[i] = i;
1926
    palookup[0] = tempbuf;
1927
 
1928
    GetPaletteFromVESA(pal);
1929
    memcpy(backup_pal, pal, PAL_SIZE);
1930
 
1931
    if ((fin = kopen4load("ten.pal", 0)) != -1)
1932
        {
1933
        kread(fin, pal, PAL_SIZE);
1934
        kclose(fin);
1935
        }
1936
 
1937
    // palette to black
1938
    FadeOut(0, 0);
1939
    bakready2send = ready2send;
1940
    //totalclock = 0;
1941
    //ototalclock = 0;
1942
 
1943
    flushperms();
1944
    // draw it
1945
    rotatesprite(0, 0, RS_SCALE, 0, TEN_PIC, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
1946
    // bring to the front - still back palette
1947
    nextpage();
1948
    // set pal
1949
    SetPaletteToVESA(pal);
1950
    //FadeIn(0, 3);
1951
    ResetKeys();
1952
 
1953
    while (!KeyPressed());
1954
 
1955
    palookup[0] = palook_bak;
1956
 
1957
    clearview(0);
1958
    nextpage();
1959
    SetPaletteToVESA(backup_pal);
1960
 
1961
    // put up a blank screen while loading
1962
    clearview(0);
1963
    nextpage();
1964
 
1965
    ready2send = bakready2send;
1966
    totalclock = bak;
1967
    }
1968
*/
1969
// CTW REMOVED END
1970
 
5198 hendricks2 1971
void
1972
TitleLevel(void)
5196 hendricks2 1973
{
1974
    char called;
1975
    int fin;
1976
    unsigned char backup_pal[256*3];
1977
    unsigned char pal[PAL_SIZE];
6041 hendricks2 1978
    char tempbuf[256];
1979
    char *palook_bak = palookup[0];
5196 hendricks2 1980
    int i;
1981
 
1982
    for (i = 0; i < 256; i++)
1983
        tempbuf[i] = i;
1984
    palookup[0] = tempbuf;
1985
 
1986
    //GetPaletteFromVESA(pal);
1987
    //memcpy(backup_pal, pal, PAL_SIZE);
1988
 
7509 hendricks2 1989
    videoClearViewableArea(0L);
1990
    videoNextPage();
5196 hendricks2 1991
 
1992
//    if ((fin = kopen4load("title.pal", 0)) != -1)
1993
//        {
1994
//        kread(fin, pal, PAL_SIZE);
1995
//        kclose(fin);
1996
//        SetPaletteToVESA(pal);
1997
//        }
1998
 
1999
//    clearview(0);
2000
//    nextpage();
2001
 
2002
    //FadeOut(0, 0);
2003
    ready2send = 0;
2004
    totalclock = 0;
2005
    ototalclock = 0;
2006
 
2007
    rotatesprite(0, 0, RS_SCALE, 0, TITLE_PIC, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
7509 hendricks2 2008
    videoNextPage();
5196 hendricks2 2009
    //FadeIn(0, 3);
2010
 
2011
    ResetKeys();
2012
    while (TRUE)
2013
    {
2014
        handleevents();
2015
        OSD_DispatchQueued();
2016
 
2017
        // taken from top of faketimerhandler
2018
        // limits checks to max of 40 times a second
2019
        if (totalclock >= ototalclock + synctics)
2020
        {
2021
            //void MNU_CheckForMenusAnyKey( void );
2022
 
2023
            ototalclock += synctics;
2024
            //MNU_CheckForMenusAnyKey();
2025
        }
2026
 
2027
        //if (UsingMenus)
2028
        //    MNU_DrawMenu();
2029
 
2030
        //drawscreen as fast as you can
2031
        rotatesprite(0, 0, RS_SCALE, 0, TITLE_PIC, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2032
 
7509 hendricks2 2033
        videoNextPage();
5196 hendricks2 2034
 
2035
        if (totalclock > 5*120 || KeyPressed())
2036
        {
2037
            DemoMode = TRUE;
2038
            DemoPlaying = TRUE;
2039
            break;
2040
        }
2041
    }
2042
 
2043
    palookup[0] = palook_bak;
2044
 
2045
//    clearview(0);
2046
//    nextpage();
2047
    //SetPaletteToVESA(backup_pal);
2048
 
2049
    // put up a blank screen while loading
2050
//    clearview(0);
2051
//    nextpage();
2052
}
2053
 
2054
 
5198 hendricks2 2055
void DrawMenuLevelScreen(void)
5196 hendricks2 2056
{
7509 hendricks2 2057
    renderFlushPerms();
2058
    videoClearViewableArea(0L);
5196 hendricks2 2059
    rotatesprite(0, 0, RS_SCALE, 0, TITLE_PIC, 20, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2060
}
2061
 
5198 hendricks2 2062
void DrawStatScreen(void)
5196 hendricks2 2063
{
7509 hendricks2 2064
    renderFlushPerms();
2065
    videoClearViewableArea(0L);
5196 hendricks2 2066
    rotatesprite(0, 0, RS_SCALE, 0, STAT_SCREEN_PIC, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2067
}
2068
 
5198 hendricks2 2069
void DrawLoadLevelScreen(void)
5196 hendricks2 2070
{
7509 hendricks2 2071
    renderFlushPerms();
2072
    videoClearViewableArea(0L);
5196 hendricks2 2073
    rotatesprite(0, 0, RS_SCALE, 0, TITLE_PIC, 20, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2074
}
2075
 
2076
short PlayerQuitMenuLevel = -1;
2077
 
5198 hendricks2 2078
void
2079
IntroAnimLevel(void)
5196 hendricks2 2080
{
2081
    DSPRINTF(ds,"IntroAnimLevel");
2082
    MONO_PRINT(ds);
2083
    playanm(0);
2084
}
2085
 
5198 hendricks2 2086
void
2087
MenuLevel(void)
5196 hendricks2 2088
{
5198 hendricks2 2089
    SWBOOL MNU_StartNetGame(void);
5196 hendricks2 2090
    char called;
2091
    int fin;
8050 pogokeen 2092
    extern ClockTicks totalclocklock;
5196 hendricks2 2093
    short w,h;
2094
 
2095
    DSPRINTF(ds,"MenuLevel...");
2096
    MONO_PRINT(ds);
2097
 
2098
    if (AutoNet)
2099
    {
2100
        DrawMenuLevelScreen();
2101
 
2102
        if (CommEnabled)
2103
        {
2104
            sprintf(ds,"Lo Wang is waiting for other players...");
2105
            MNU_MeasureString(ds, &w, &h);
2106
            MNU_DrawString(TEXT_TEST_COL(w), 170, ds, 1, 16);
2107
 
2108
            sprintf(ds,"They are afraid!");
2109
            MNU_MeasureString(ds, &w, &h);
2110
            MNU_DrawString(TEXT_TEST_COL(w), 180, ds, 1, 16);
2111
        }
2112
 
7509 hendricks2 2113
        videoNextPage();
5196 hendricks2 2114
 
2115
        waitforeverybody();
2116
        FirstTimeIntoGame = TRUE;
2117
        MNU_StartNetGame();
2118
        FirstTimeIntoGame = FALSE;
2119
        waitforeverybody();
2120
        ExitLevel = FALSE;
2121
        FinishedLevel = FALSE;
2122
        BorderAdjust = TRUE;
2123
        UsingMenus = FALSE;
2124
        InMenuLevel = FALSE;
2125
        return;
2126
    }
2127
 
2128
    // do demos only if not playing multi play
2129
    if (!CommEnabled && numplayers <= 1 && !FinishAnim && !NoDemoStartup)
2130
    {
2131
        // demos exist - do demo instead
2132
        if (DemoName[0][0] != '\0')
2133
        {
2134
            DemoMode = TRUE;
2135
            DemoPlaying = TRUE;
2136
            return;
2137
        }
2138
    }
2139
 
2140
    DemoMode = FALSE;
2141
    DemoPlaying = FALSE;
2142
 
7509 hendricks2 2143
    videoClearViewableArea(0L);
2144
    videoNextPage();
5196 hendricks2 2145
 
2146
    //FadeOut(0, 0);
2147
    ready2send = 0;
2148
    totalclock = 0;
2149
    ototalclock = 0;
2150
    ExitLevel = FALSE;
2151
    InMenuLevel = TRUE;
2152
 
2153
    DrawMenuLevelScreen();
2154
 
2155
    if (CommEnabled)
2156
    {
2157
        sprintf(ds,"Lo Wang is waiting for other players...");
2158
        MNU_MeasureString(ds, &w, &h);
2159
        MNU_DrawString(TEXT_TEST_COL(w), 170, ds, 1, 16);
2160
 
2161
        sprintf(ds,"They are afraid!");
2162
        MNU_MeasureString(ds, &w, &h);
2163
        MNU_DrawString(TEXT_TEST_COL(w), 180, ds, 1, 16);
2164
    }
2165
 
7509 hendricks2 2166
    videoNextPage();
5196 hendricks2 2167
    //FadeIn(0, 3);
2168
 
2169
    waitforeverybody();
2170
 
2171
    // don't allow BorderAdjusting in these menus
2172
    BorderAdjust = FALSE;
2173
 
2174
    ResetKeys();
2175
 
2176
    if (SW_SHAREWARE)
2177
    {
2178
        // go to ordering menu only if shareware
2179
        if (FinishAnim)
2180
        {
2181
            KEY_PRESSED(KEYSC_ESC) = 1;
2182
            ControlPanelType = ct_ordermenu;
2183
            FinishAnim = 0;
2184
        }
2185
    }
2186
    else
2187
    {
2188
        FinishAnim = 0;
2189
    }
2190
 
2191
    while (TRUE)
2192
    {
2193
        handleevents();
2194
        OSD_DispatchQueued();
2195
 
2196
        if (quitevent) QuitFlag = TRUE;
2197
 
2198
        // taken from top of faketimerhandler
2199
        // limits checks to max of 40 times a second
2200
        if (totalclock >= ototalclock + synctics)
2201
        {
2202
            ototalclock += synctics;
2203
            MNU_CheckForMenusAnyKey();
2204
            if (CommEnabled)
2205
                getpackets();
2206
        }
2207
 
2208
        if (CommEnabled)
2209
        {
2210
            if (MultiPlayQuitFlag)
2211
            {
2212
                short pnum;
5198 hendricks2 2213
                uint8_t pbuf[1];
5196 hendricks2 2214
                QuitFlag = TRUE;
2215
                pbuf[0] = PACKET_TYPE_MENU_LEVEL_QUIT;
2216
                netbroadcastpacket(pbuf, 1);                      // TENSW
2217
                break;
2218
            }
2219
 
2220
            if (PlayerQuitMenuLevel >= 0)
2221
            {
2222
                MenuCommPlayerQuit(PlayerQuitMenuLevel);
2223
                PlayerQuitMenuLevel = -1;
2224
            }
2225
        }
2226
 
2227
        if (ExitLevel)
2228
        {
2229
            // Quiting Level
2230
            ExitLevel = FALSE;
2231
            break;
2232
        }
2233
 
2234
        if (QuitFlag)
2235
        {
2236
            // Quiting Game
2237
            break;
2238
        }
2239
 
2240
        // force the use of menus at all time
2241
        if (!UsingMenus && !ConPanel)
2242
        {
2243
            KEY_PRESSED(KEYSC_ESC) = TRUE;
2244
            MNU_CheckForMenusAnyKey();
2245
        }
2246
 
2247
        // must lock the clock for drawing so animations will happen
2248
        totalclocklock = totalclock;
2249
 
2250
        //drawscreen as fast as you can
2251
        DrawMenuLevelScreen();
2252
 
2253
        if (UsingMenus)
2254
            MNU_DrawMenu();
2255
 
7509 hendricks2 2256
        videoNextPage();
5196 hendricks2 2257
    }
2258
 
2259
    BorderAdjust = TRUE;
2260
    //LoadGameOutsideMoveLoop = FALSE;
2261
    KEY_PRESSED(KEYSC_ESC) = FALSE;
2262
    KB_ClearKeysDown();
2263
    //ExitMenus();
2264
    UsingMenus = FALSE;
2265
    InMenuLevel = FALSE;
7509 hendricks2 2266
    videoClearViewableArea(0L);
2267
    videoNextPage();
5196 hendricks2 2268
}
2269
 
5198 hendricks2 2270
void
2271
SceneLevel(void)
5196 hendricks2 2272
{
5198 hendricks2 2273
    SWBOOL dp_bak;
2274
    SWBOOL dm_bak;
5196 hendricks2 2275
    FILE *fin;
2276
#define CINEMATIC_DEMO_FILE "$scene.dmo"
2277
 
2278
    // make sure it exists
2279
    if ((fin = fopen(CINEMATIC_DEMO_FILE,"rb")) == NULL)
2280
        return;
2281
    else
2282
        fclose(fin);
2283
 
2284
    strcpy(DemoFileName,CINEMATIC_DEMO_FILE);
2285
 
2286
    dp_bak = DemoPlaying;
2287
    dm_bak = DemoMode;
2288
 
2289
    DemoMode = TRUE;
2290
    DemoPlaying = TRUE;
2291
    DemoOverride = TRUE;
2292
    InitLevel();
2293
    DemoOverride = FALSE;
2294
 
2295
    ScenePlayBack();
2296
    TerminateLevel();
2297
    DemoMode = dm_bak;
2298
    DemoPlaying = dp_bak;
2299
}
2300
 
5198 hendricks2 2301
void
5196 hendricks2 2302
LoadingLevelScreen(char *level_name)
2303
{
2304
    short w,h;
5198 hendricks2 2305
    extern SWBOOL DemoMode;
5196 hendricks2 2306
    extern char *MNU_LevelName[28];
2307
    DrawLoadLevelScreen();
2308
 
2309
    if (DemoMode)
2310
        sprintf(ds,"DEMO");
2311
    else
2312
        sprintf(ds,"ENTERING");
2313
 
2314
    MNU_MeasureString(ds, &w, &h);
2315
    MNU_DrawString(TEXT_TEST_COL(w), 170, ds,1,16);
2316
 
2317
    if (UserMapName[0])
2318
        sprintf(ds,"%s",UserMapName);
2319
    else
2320
        sprintf(ds,"%s",LevelInfo[Level].Description);
2321
 
2322
    MNU_MeasureString(ds, &w, &h);
2323
    MNU_DrawString(TEXT_TEST_COL(w), 180, ds,1,16);
2324
 
7509 hendricks2 2325
    videoNextPage();
5196 hendricks2 2326
}
2327
 
5198 hendricks2 2328
void
5196 hendricks2 2329
gNextState(STATEp *State)
2330
{
2331
    // Transition to the next state
2332
    *State = (*State)->NextState;
2333
 
2334
    if (TEST((*State)->Tics, SF_QUICK_CALL))
2335
    {
2336
        (*(*State)->Animator)(0);
2337
        *State = (*State)->NextState;
2338
    }
2339
}
2340
 
2341
// Generic state control
5198 hendricks2 2342
void
5196 hendricks2 2343
gStateControl(STATEp *State, int *tics)
2344
{
2345
    *tics += synctics;
2346
 
2347
    // Skip states if too much time has passed
2348
    while (*tics >= (*State)->Tics)
2349
    {
2350
        // Set Tics
2351
        *tics -= (*State)->Tics;
2352
        gNextState(State);
2353
    }
2354
 
2355
    // Call the correct animator
2356
    if ((*State)->Animator)
2357
        (*(*State)->Animator)(0);
2358
}
2359
 
2360
int BonusPunchSound(short SpriteNum)
2361
{
2362
    PLAYERp pp = Player + myconnectindex;
2363
    PlaySound(DIGI_PLAYERYELL3, &pp->posx, &pp->posy, &pp->posz, v3df_none);
2364
    return 0;
2365
}
2366
 
2367
int BonusKickSound(short SpriteNum)
2368
{
2369
    PLAYERp pp = Player + myconnectindex;
2370
    PlaySound(DIGI_PLAYERYELL2, &pp->posx, &pp->posy, &pp->posz, v3df_none);
2371
    return 0;
2372
}
2373
 
2374
int BonusGrabSound(short SpriteNum)
2375
{
2376
    PLAYERp pp = Player + myconnectindex;
2377
    PlaySound(DIGI_BONUS_GRAB, &pp->posx, &pp->posy, &pp->posz, v3df_none);
2378
    return 0;
2379
}
2380
 
5198 hendricks2 2381
void
5196 hendricks2 2382
BonusScreen(PLAYERp pp)
2383
{
2384
    int minutes,seconds,second_tics;
5198 hendricks2 2385
    extern SWBOOL FinishedLevel;
5196 hendricks2 2386
    extern int PlayClock;
2387
    extern short LevelSecrets;
2388
    extern short TotalKillable;
2389
    short w,h;
2390
    short pic,limit;
2391
    int zero=0;
2392
    int handle = 0;
2393
    short LI_Num;
2394
 
2395
 
2396
#define BONUS_SCREEN_PIC 5120
2397
#define BONUS_ANIM 5121
2398
#define BONUS_ANIM_FRAMES (5159-5121)
2399
 
2400
#define BREAK_LIGHT_RATE 18
2401
 
2402
#define BONUS_PUNCH 5121
2403
#define BONUS_KICK 5136
2404
#define BONUS_GRAB 5151
2405
#define BONUS_REST 5121
2406
 
2407
#define BONUS_TICS 8
2408
#define BONUS_GRAB_TICS 20
2409
#define BONUS_REST_TICS 50
2410
 
2411
    static STATE s_BonusPunch[] =
2412
    {
2413
        {BONUS_PUNCH + 0, BONUS_TICS, NULL, &s_BonusPunch[1]},
2414
        {BONUS_PUNCH + 1, BONUS_TICS, NULL, &s_BonusPunch[2]},
2415
        {BONUS_PUNCH + 2, BONUS_TICS, NULL, &s_BonusPunch[3]},
2416
        {BONUS_PUNCH + 2, 0|SF_QUICK_CALL, BonusPunchSound, &s_BonusPunch[4]},
2417
        {BONUS_PUNCH + 3, BONUS_TICS, NULL, &s_BonusPunch[5]},
2418
        {BONUS_PUNCH + 4, BONUS_TICS, NULL, &s_BonusPunch[6]},
2419
        {BONUS_PUNCH + 5, BONUS_TICS, NULL, &s_BonusPunch[7]},
2420
        {BONUS_PUNCH + 6, BONUS_TICS, NULL, &s_BonusPunch[8]},
2421
        {BONUS_PUNCH + 7, BONUS_TICS, NULL, &s_BonusPunch[9]},
2422
        {BONUS_PUNCH + 8, BONUS_TICS, NULL, &s_BonusPunch[10]},
2423
        {BONUS_PUNCH + 9, BONUS_TICS, NULL, &s_BonusPunch[11]},
2424
        {BONUS_PUNCH + 10, BONUS_TICS, NULL, &s_BonusPunch[12]},
2425
        {BONUS_PUNCH + 11, BONUS_TICS, NULL, &s_BonusPunch[13]},
2426
        {BONUS_PUNCH + 12, BONUS_TICS, NULL, &s_BonusPunch[14]},
2427
        {BONUS_PUNCH + 14, 90,        NULL, &s_BonusPunch[15]},
2428
        {BONUS_PUNCH + 14, BONUS_TICS, NULL, &s_BonusPunch[15]},
2429
    };
2430
 
2431
    static STATE s_BonusKick[] =
2432
    {
2433
        {BONUS_KICK + 0, BONUS_TICS, NULL, &s_BonusKick[1]},
2434
        {BONUS_KICK + 1, BONUS_TICS, NULL, &s_BonusKick[2]},
2435
        {BONUS_KICK + 2, BONUS_TICS, NULL, &s_BonusKick[3]},
2436
        {BONUS_KICK + 2, 0|SF_QUICK_CALL, BonusKickSound, &s_BonusKick[4]},
2437
        {BONUS_KICK + 3, BONUS_TICS, NULL, &s_BonusKick[5]},
2438
        {BONUS_KICK + 4, BONUS_TICS, NULL, &s_BonusKick[6]},
2439
        {BONUS_KICK + 5, BONUS_TICS, NULL, &s_BonusKick[7]},
2440
        {BONUS_KICK + 6, BONUS_TICS, NULL, &s_BonusKick[8]},
2441
        {BONUS_KICK + 7, BONUS_TICS, NULL, &s_BonusKick[9]},
2442
        {BONUS_KICK + 8, BONUS_TICS, NULL, &s_BonusKick[10]},
2443
        {BONUS_KICK + 9, BONUS_TICS, NULL, &s_BonusKick[11]},
2444
        {BONUS_KICK + 10, BONUS_TICS, NULL, &s_BonusKick[12]},
2445
        {BONUS_KICK + 11, BONUS_TICS, NULL, &s_BonusKick[13]},
2446
        {BONUS_KICK + 12, BONUS_TICS, NULL, &s_BonusKick[14]},
2447
        {BONUS_KICK + 14, 90,        NULL, &s_BonusKick[15]},
2448
        {BONUS_KICK + 14, BONUS_TICS, NULL, &s_BonusKick[15]},
2449
    };
2450
 
2451
    static STATE s_BonusGrab[] =
2452
    {
2453
        {BONUS_GRAB + 0, BONUS_GRAB_TICS, NULL, &s_BonusGrab[1]},
2454
        {BONUS_GRAB + 1, BONUS_GRAB_TICS, NULL, &s_BonusGrab[2]},
2455
        {BONUS_GRAB + 2, BONUS_GRAB_TICS, NULL, &s_BonusGrab[3]},
2456
        {BONUS_GRAB + 2, 0|SF_QUICK_CALL, BonusGrabSound, &s_BonusGrab[4]},
2457
        {BONUS_GRAB + 3, BONUS_GRAB_TICS, NULL, &s_BonusGrab[5]},
2458
        {BONUS_GRAB + 4, BONUS_GRAB_TICS, NULL, &s_BonusGrab[6]},
2459
        {BONUS_GRAB + 5, BONUS_GRAB_TICS, NULL, &s_BonusGrab[7]},
2460
        {BONUS_GRAB + 6, BONUS_GRAB_TICS, NULL, &s_BonusGrab[8]},
2461
        {BONUS_GRAB + 7, BONUS_GRAB_TICS, NULL, &s_BonusGrab[9]},
2462
        {BONUS_GRAB + 8, BONUS_GRAB_TICS, NULL, &s_BonusGrab[10]},
2463
        {BONUS_GRAB + 9, 90,             NULL, &s_BonusGrab[11]},
2464
        {BONUS_GRAB + 9, BONUS_GRAB_TICS, NULL, &s_BonusGrab[11]},
2465
    };
2466
 
2467
#if 1 // Turned off the standing animate because he looks like a FAG!
2468
    static STATE s_BonusRest[] =
2469
    {
2470
        {BONUS_REST + 0, BONUS_REST_TICS, NULL, &s_BonusRest[1]},
2471
        {BONUS_REST + 1, BONUS_REST_TICS, NULL, &s_BonusRest[2]},
2472
        {BONUS_REST + 2, BONUS_REST_TICS, NULL, &s_BonusRest[3]},
2473
        {BONUS_REST + 1, BONUS_REST_TICS, NULL, &s_BonusRest[0]},
2474
    };
2475
#else
2476
    static STATE s_BonusRest[] =
2477
    {
2478
        {BONUS_REST + 0, BONUS_REST_TICS, NULL, &s_BonusRest[1]},
2479
        {BONUS_REST + 0, BONUS_REST_TICS, NULL, &s_BonusRest[0]},
2480
    };
2481
#endif
2482
 
2483
    static STATEp s_BonusAnim[] =
2484
    {
2485
        s_BonusPunch,
2486
        s_BonusKick,
2487
        s_BonusGrab
2488
    };
2489
 
2490
    STATEp State = s_BonusRest;
2491
 
2492
    int Tics = 0;
2493
    int line = 0;
5198 hendricks2 2494
    SWBOOL BonusDone;
5196 hendricks2 2495
    UserInput uinfo = { FALSE, FALSE, dir_None };
2496
 
2497
    if (Level < 0) Level = 0;
2498
 
7509 hendricks2 2499
    videoClearViewableArea(0L);
2500
    videoNextPage();
5196 hendricks2 2501
 
2502
    KB_ClearKeysDown();
2503
 
2504
    totalclock = ototalclock = 0;
2505
    limit = synctics;
2506
 
2507
    if (gs.MusicOn)
2508
    {
2509
        PlaySong(voc[DIGI_ENDLEV].name, 3, TRUE, TRUE);
2510
    }
2511
 
2512
    // special case code because I don't care any more!
2513
    if (FinishAnim)
2514
    {
7509 hendricks2 2515
        renderFlushPerms();
5196 hendricks2 2516
        rotatesprite(0, 0, RS_SCALE, 0, 5120, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2517
        rotatesprite(158<<16, 86<<16, RS_SCALE, 0, State->Pic, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
7509 hendricks2 2518
        videoNextPage();
5196 hendricks2 2519
        FadeIn(0,0);
2520
    }
2521
 
2522
    BonusDone = FALSE;
2523
    while (!BonusDone)
2524
    {
2525
        handleevents();
2526
 
2527
        // taken from top of faketimerhandler
2528
        if (totalclock < ototalclock + limit)
2529
        {
2530
            continue;
2531
        }
2532
        ototalclock += limit;
2533
 
2534
        CONTROL_GetUserInput(&uinfo);
2535
        CONTROL_ClearUserInput(&uinfo);
2536
        if (KEY_PRESSED(KEYSC_SPACE) || KEY_PRESSED(KEYSC_ENTER) || uinfo.button0 || uinfo.button1)
2537
        {
2538
            if (State >= s_BonusRest && State < &s_BonusRest[SIZ(s_BonusRest)])
2539
            {
2540
                State = s_BonusAnim[STD_RANDOM_RANGE(SIZ(s_BonusAnim))];
2541
                Tics = 0;
2542
            }
2543
        }
2544
 
2545
        gStateControl(&State, &Tics);
2546
        rotatesprite(0, 0, RS_SCALE, 0, 5120, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2547
 
2548
        if (UserMapName[0])
2549
        {
2550
            sprintf(ds,"%s",UserMapName);
2551
            MNU_MeasureString(ds, &w, &h);
2552
            MNU_DrawString(TEXT_TEST_COL(w), 20, ds,1,19);
2553
        }
2554
        else
2555
        {
2556
            if (PlayingLevel <= 1)
2557
                PlayingLevel = 1;
2558
            sprintf(ds,"%s",LevelInfo[PlayingLevel].Description);
2559
            MNU_MeasureString(ds, &w, &h);
2560
            MNU_DrawString(TEXT_TEST_COL(w), 20, ds,1,19);
2561
        }
2562
 
2563
        sprintf(ds,"Completed");
2564
        MNU_MeasureString(ds, &w, &h);
2565
        MNU_DrawString(TEXT_TEST_COL(w), 30, ds,1,19);
2566
 
2567
        rotatesprite(158<<16, 86<<16, RS_SCALE, 0, State->Pic, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2568
 
2569
#define BONUS_LINE(i) (50 + ((i)*20))
2570
 
2571
        line = 0;
2572
        second_tics = (PlayClock/120);
2573
        minutes = (second_tics/60);
2574
        seconds = (second_tics%60);
2575
        sprintf(ds,"Your Time:  %2d : %02d", minutes, seconds);
2576
        MNU_MeasureString(ds, &w, &h);
2577
        MNU_DrawString(60, BONUS_LINE(line), ds,1,16);
2578
 
2579
        if (!UserMapName[0])
2580
        {
2581
            line++;
2582
            sprintf(ds,"3D Realms Best Time:  %s", LevelInfo[PlayingLevel].BestTime);
2583
            MNU_MeasureString(ds, &w, &h);
2584
            MNU_DrawString(40, BONUS_LINE(line), ds,1,16);
2585
 
2586
            line++;
2587
            sprintf(ds,"Par Time:  %s", LevelInfo[PlayingLevel].ParTime);
2588
            MNU_MeasureString(ds, &w, &h);
2589
            MNU_DrawString(40, BONUS_LINE(line), ds,1,16);
2590
        }
2591
 
2592
 
2593
        // always read secrets and kills from the first player
2594
        line++;
2595
        sprintf(ds,"Secrets:  %d / %d", Player->SecretsFound, LevelSecrets);
2596
        MNU_MeasureString(ds, &w, &h);
2597
        MNU_DrawString(60, BONUS_LINE(line), ds,1,16);
2598
 
2599
        line++;
2600
        sprintf(ds,"Kills:  %d / %d", Player->Kills, TotalKillable);
2601
        MNU_MeasureString(ds, &w, &h);
2602
        MNU_DrawString(60, BONUS_LINE(line), ds,1,16);
2603
 
2604
 
2605
        sprintf(ds,"Press SPACE to continue");
2606
        MNU_MeasureString(ds, &w, &h);
2607
        MNU_DrawString(TEXT_TEST_COL(w), 185, ds,1,19);
2608
 
7509 hendricks2 2609
        videoNextPage();
5196 hendricks2 2610
        ScreenCaptureKeys();
2611
 
2612
        if (State == State->NextState)
2613
            BonusDone = TRUE;
2614
    }
2615
 
2616
    StopSound();
2617
    Terminate3DSounds();
2618
}
2619
 
5198 hendricks2 2620
void EndGameSequence(void)
5196 hendricks2 2621
{
5198 hendricks2 2622
    SWBOOL anim_ok = TRUE;
5196 hendricks2 2623
    FadeOut(0, 5);
2624
 
2625
    if ((gs.ParentalLock || Global_PLock) && FinishAnim == ANIM_SUMO)
2626
        anim_ok = FALSE;
2627
 
2628
    if (anim_ok)
2629
        playanm(FinishAnim);
2630
 
2631
    BonusScreen(Player + myconnectindex);
2632
 
2633
    ExitLevel = FALSE;
2634
    QuitFlag = FALSE;
2635
    AutoNet = FALSE;
2636
 
2637
    if (FinishAnim == ANIM_ZILLA)
2638
        CreditsLevel();
2639
 
2640
    ExitLevel = FALSE;
2641
    QuitFlag = FALSE;
2642
    AutoNet = FALSE;
2643
 
2644
    if (SW_SHAREWARE)
2645
    {
2646
        Level = 0;
2647
    }
2648
    else
2649
    {
2650
        if (Level == 4 || Level == 20)
2651
        {
2652
            Level=0;
2653
        }
2654
        else
2655
            Level++;
2656
    }
2657
}
2658
 
5198 hendricks2 2659
void
5196 hendricks2 2660
StatScreen(PLAYERp mpp)
2661
{
2662
    int minutes,seconds,second_tics;
5198 hendricks2 2663
    extern SWBOOL FinishedLevel;
5196 hendricks2 2664
    extern int PlayClock;
2665
    extern short LevelSecrets;
2666
    extern short TotalKillable;
2667
    short w,h;
2668
    int zero=0;
2669
    int handle=0;
2670
 
2671
    short rows,cols,i,j;
2672
    PLAYERp pp = NULL;
2673
    int x,y;
2674
    short death_total[MAX_SW_PLAYERS_REG];
2675
    short kills[MAX_SW_PLAYERS_REG];
2676
    short pal;
2677
 
2678
#define STAT_START_X 20
2679
#define STAT_START_Y 85
2680
#define STAT_OFF_Y 9
2681
#define STAT_HEADER_Y 14
2682
 
2683
#define SM_SIZ(num) ((num)*4)
2684
 
2685
#define STAT_TABLE_X (STAT_START_X + SM_SIZ(15))
2686
#define STAT_TABLE_XOFF SM_SIZ(6)
2687
 
2688
    // No stats in bot games
2689
    //if (BotMode) return;
2690
 
2691
    ResetPalette(mpp);
2692
    COVER_SetReverb(0); // Reset reverb
2693
    StopSound();
2694
 
2695
    if (FinishAnim)
2696
    {
2697
        EndGameSequence();
2698
        return;
2699
    }
2700
 
2701
    if (gNet.MultiGameType != MULTI_GAME_COMMBAT)
2702
    {
2703
        if (!FinishedLevel)
2704
            return;
2705
        BonusScreen(mpp);
2706
        return;
2707
    }
2708
 
7509 hendricks2 2709
    renderFlushPerms();
5196 hendricks2 2710
    DrawStatScreen();
2711
 
2712
    memset(death_total,0,sizeof(death_total));
2713
    memset(kills,0,sizeof(kills));
2714
 
2715
    sprintf(ds,"MULTIPLAYER TOTALS");
2716
    MNU_MeasureString(ds, &w, &h);
2717
    MNU_DrawString(TEXT_TEST_COL(w), 68, ds, 0, 0);
2718
 
2719
    sprintf(ds,"PRESS SPACE BAR TO CONTINUE");
2720
    MNU_MeasureString(ds, &w, &h);
2721
    MNU_DrawString(TEXT_TEST_COL(w), 189, ds, 0, 0);
2722
 
2723
    x = STAT_START_X;
2724
    y = STAT_START_Y;
2725
 
2726
    sprintf(ds,"  NAME         1     2     3     4     5     6     7    8     KILLS");
2727
    DisplayMiniBarSmString(mpp, x, y, 0, ds);
2728
    rows = OrigCommPlayers;
2729
    cols = OrigCommPlayers;
2730
    mpp = Player + myconnectindex;
2731
 
2732
    y += STAT_HEADER_Y;
2733
 
2734
    for (i = 0; i < rows; i++)
2735
    {
2736
        x = STAT_START_X;
2737
        pp = Player + i;
2738
 
2739
        sprintf(ds,"%d", i+1);
2740
        DisplayMiniBarSmString(mpp, x, y, 0, ds);
2741
 
2742
        sprintf(ds,"  %-13s", pp->PlayerName);
2743
        DisplayMiniBarSmString(mpp, x, y, User[pp->PlayerSprite]->spal, ds);
2744
 
2745
        x = STAT_TABLE_X;
2746
        for (j = 0; j < cols; j++)
2747
        {
2748
            pal = 0;
2749
            death_total[j] += pp->KilledPlayer[j];
2750
 
2751
            if (i == j)
2752
            {
2753
                // don't add kill for self or team player
2754
                pal = PALETTE_PLAYER0 + 4;
2755
                kills[i] -= pp->KilledPlayer[j];  // subtract self kills
2756
            }
2757
            else if (gNet.TeamPlay)
2758
            {
2759
                if (User[pp->PlayerSprite]->spal == User[Player[j].PlayerSprite]->spal)
2760
                {
2761
                    // don't add kill for self or team player
2762
                    pal = PALETTE_PLAYER0 + 4;
2763
                    kills[i] -= pp->KilledPlayer[j];  // subtract self kills
2764
                }
2765
                else
2766
                    kills[i] += pp->KilledPlayer[j];  // kills added here
2767
            }
2768
            else
2769
            {
2770
                kills[i] += pp->KilledPlayer[j];  // kills added here
2771
            }
2772
 
2773
            sprintf(ds,"%d", pp->KilledPlayer[j]);
2774
            DisplayMiniBarSmString(mpp, x, y, pal, ds);
2775
            x += STAT_TABLE_XOFF;
2776
        }
2777
 
2778
        y += STAT_OFF_Y;
2779
    }
2780
 
2781
 
2782
    // Deaths
2783
 
2784
    x = STAT_START_X;
2785
    y += STAT_OFF_Y;
2786
 
2787
    sprintf(ds,"   DEATHS");
2788
    DisplayMiniBarSmString(mpp, x, y, 0, ds);
2789
    x = STAT_TABLE_X;
2790
 
2791
    for (j = 0; j < cols; j++)
2792
    {
2793
        sprintf(ds,"%d",death_total[j]);
2794
        DisplayMiniBarSmString(mpp, x, y, 0, ds);
2795
        x += STAT_TABLE_XOFF;
2796
    }
2797
 
2798
    x = STAT_START_X;
2799
    y += STAT_OFF_Y;
2800
 
2801
    // Kills
2802
    x = STAT_TABLE_X + SM_SIZ(50);
2803
    y = STAT_START_Y + STAT_HEADER_Y;
2804
 
2805
    for (i = 0; i < rows; i++)
2806
    {
2807
        pp = Player + i;
2808
 
2809
        sprintf(ds,"%d", kills[i]); //pp->Kills);
2810
        DisplayMiniBarSmString(mpp, x, y, 0, ds);
2811
 
2812
        y += STAT_OFF_Y;
2813
    }
2814
 
7509 hendricks2 2815
    videoNextPage();
5196 hendricks2 2816
 
2817
    if (KeyPressed())
2818
    {
2819
        while (KeyPressed()) ;
2820
    }
2821
 
2822
    KEY_PRESSED(KEYSC_SPACE) = 0;
2823
    KEY_PRESSED(KEYSC_ENTER) = 0;
2824
 
2825
    if (gs.MusicOn)
2826
    {
2827
        PlaySong(voc[DIGI_ENDLEV].name, 3, TRUE, TRUE);
2828
    }
2829
 
2830
    while (!KEY_PRESSED(KEYSC_SPACE) && !KEY_PRESSED(KEYSC_ENTER))
2831
    {
2832
        handleevents();
2833
 
2834
        ScreenCaptureKeys();
2835
    }
2836
 
2837
    StopSound();
2838
    Terminate3DSounds();
2839
}
2840
 
5198 hendricks2 2841
void
2842
GameIntro(void)
5196 hendricks2 2843
{
2844
 
2845
    DSPRINTF(ds,"GameIntro...");
2846
    MONO_PRINT(ds);
2847
 
2848
    if (DemoPlaying)
2849
        return;
2850
 
2851
    // this could probably be taken out and you could select skill level
2852
    // from menu to start the game
2853
    if (!CommEnabled && UserMapName[0])
2854
        return;
2855
 
2856
    Level = 1;
2857
 
2858
 
2859
 
8271 hendricks2 2860
    PlayTheme();
5196 hendricks2 2861
 
2862
    if (!AutoNet)
2863
    {
2864
        LogoLevel();
2865
        //CreditsLevel();
2866
        //SceneLevel();
2867
        //TitleLevel();
2868
        IntroAnimLevel();
2869
        IntroAnimCount = 0;
2870
    }
2871
 
2872
    MenuLevel();
2873
}
2874
 
5198 hendricks2 2875
void
5552 hendricks2 2876
Control(int32_t argc, char const * const * argv)
5196 hendricks2 2877
{
2878
 
5206 hendricks2 2879
    InitGame(argc, argv);
5196 hendricks2 2880
 
2881
    MONO_PRINT("InitGame done");
2882
    MNU_InitMenus();
2883
    InGame = TRUE;
2884
    GameIntro();
2885
    //NewGame = TRUE;
2886
 
2887
    while (!QuitFlag)
2888
    {
2889
        handleevents();
2890
        OSD_DispatchQueued();
2891
 
2892
        if (quitevent) QuitFlag = TRUE;
2893
 
2894
        NewLevel();
2895
    }
2896
 
2897
    CleanExit = TRUE;
2898
    TerminateGame();
2899
}
2900
 
2901
 
2902
void
7499 hendricks2 2903
_Assert(const char *expr, const char *strFile, unsigned uLine)
5196 hendricks2 2904
{
2905
    sprintf(ds, "Assertion failed: %s %s, line %u", expr, strFile, uLine);
2906
    MONO_PRINT(ds);
2907
    TerminateGame();
2908
#if 1 //def RENDERTYPEWIN
7553 hendricks2 2909
    wm_msgbox(apptitle, "%s", ds);
5196 hendricks2 2910
#else
2911
    printf("Assertion failed: %s\n %s, line %u\n", expr, strFile, uLine);
2912
#endif
2913
    exit(0);
2914
}
2915
 
2916
 
2917
void
7499 hendricks2 2918
_ErrMsg(const char *strFile, unsigned uLine, const char *format, ...)
5196 hendricks2 2919
{
2920
    va_list arglist;
2921
 
2922
    //DSPRINTF(ds, "Error: %s, line %u", strFile, uLine);
2923
    //MONO_PRINT(ds);
2924
    TerminateGame();
2925
 
2926
#if 1 //def RENDERTYPEWIN
2927
    {
2928
        char msg[256], *p;
2929
        Bsnprintf(msg, sizeof(msg), "Error: %s, line %u\n", strFile, uLine);
2930
        p = &msg[strlen(msg)];
2931
        va_start(arglist, format);
2932
        Bvsnprintf(msg, sizeof(msg) - (p-msg), format, arglist);
2933
        va_end(arglist);
7553 hendricks2 2934
        wm_msgbox(apptitle, "%s", msg);
5196 hendricks2 2935
    }
2936
#else
2937
    printf("Error: %s, line %u\n", strFile, uLine);
2938
 
2939
    va_start(arglist, format);
2940
    vprintf(format, arglist);
2941
    va_end(arglist);
2942
#endif
2943
 
2944
    exit(0);
2945
}
2946
 
2947
void
2948
dsprintf(char *str, char *format, ...)
2949
{
2950
    va_list arglist;
2951
 
2952
    va_start(arglist, format);
2953
    vsprintf(str, format, arglist);
2954
    va_end(arglist);
2955
}
2956
 
2957
void
7499 hendricks2 2958
dsprintf_null(char *str, const char *format, ...)
5196 hendricks2 2959
{
2960
    va_list arglist;
2961
}
2962
 
2963
void MoveLoop(void)
2964
{
2965
    int pnum;
2966
 
2967
    getpackets();
2968
 
2969
    if (PredictionOn && CommEnabled)
2970
    {
2971
        while (predictmovefifoplc < Player[myconnectindex].movefifoend)
2972
        {
2973
            DoPrediction(ppp);
2974
        }
2975
    }
2976
 
2977
    //While you have new input packets to process...
2978
    if (!CommEnabled)
2979
        bufferjitter = 0;
2980
 
2981
    while (Player[myconnectindex].movefifoend - movefifoplc > bufferjitter)
2982
    {
2983
        //Make sure you have at least 1 packet from everyone else
2984
        for (pnum=connecthead; pnum>=0; pnum=connectpoint2[pnum])
2985
        {
2986
            if (movefifoplc == Player[pnum].movefifoend)
2987
            {
2988
                break;
2989
            }
2990
        }
2991
 
2992
        //Pnum is >= 0 only if last loop was broken, meaning a player wasn't caught up
2993
        if (pnum >= 0)
2994
            break;
2995
 
2996
        domovethings();
2997
 
2998
#if DEBUG
2999
        //if (DemoSyncRecord)
3000
        //    demosync_record();
3001
#endif
3002
    }
3003
 
3004
    if (!InputMode && !PauseKeySet)
3005
        MNU_CheckForMenus();
3006
}
3007
 
3008
 
3009
void InitPlayerGameSettings(void)
3010
{
3011
    int pnum;
3012
 
3013
    // don't jack with auto aim settings if DemoMode is going
3014
    // what the hell did I do this for?????????
3015
    //if (DemoMode)
3016
    //    return;
3017
 
3018
    if (CommEnabled)
3019
    {
3020
        // everyone gets the same Auto Aim
3021
        TRAVERSE_CONNECT(pnum)
3022
        {
3023
            if (gNet.AutoAim)
3024
                SET(Player[pnum].Flags, PF_AUTO_AIM);
3025
            else
3026
                RESET(Player[pnum].Flags, PF_AUTO_AIM);
3027
        }
3028
    }
3029
    else
3030
    {
3031
        if (gs.AutoAim)
3032
            SET(Player[myconnectindex].Flags, PF_AUTO_AIM);
3033
        else
3034
            RESET(Player[myconnectindex].Flags, PF_AUTO_AIM);
3035
    }
3036
 
3037
    // everyone had their own Auto Run
3038
    if (gs.AutoRun)
3039
        SET(Player[myconnectindex].Flags, PF_LOCK_RUN);
3040
    else
3041
        RESET(Player[myconnectindex].Flags, PF_LOCK_RUN);
3042
 
3043
    if (gs.MouseAimingOn)
3044
        SET(Player[myconnectindex].Flags, PF_MOUSE_AIMING_ON);
3045
    else
3046
        RESET(Player[myconnectindex].Flags, PF_MOUSE_AIMING_ON);
3047
}
3048
 
3049
 
5198 hendricks2 3050
void InitRunLevel(void)
5196 hendricks2 3051
{
3052
    int i;
3053
    if (DemoEdit)
3054
        return;
3055
 
3056
    if (LoadGameOutsideMoveLoop)
3057
    {
3058
        int SavePlayClock;
3059
        extern int PlayClock;
3060
        LoadGameOutsideMoveLoop = FALSE;
3061
        // contains what is needed from calls below
3062
        if (gs.Ambient)
3063
            StartAmbientSound();
3064
        SetCrosshair();
3065
        PlaySong(LevelSong, -1, TRUE, TRUE);
3066
        SetRedrawScreen(Player + myconnectindex);
3067
        // crappy little hack to prevent play clock from being overwritten
3068
        // for load games
3069
        SavePlayClock = PlayClock;
3070
        InitTimingVars();
3071
        PlayClock = SavePlayClock;
3072
        MONO_PRINT("Done with InitRunLevel");
3073
        return;
3074
    }
3075
 
3076
#if 0
3077
    // ensure we are through the initialization code before sending the game
3078
    // version. Otherwise, it is possible to send this too early and have it
3079
    // blown away on the other side.
3080
    waitforeverybody();
3081
#endif
3082
 
3083
    SendVersion(GameVersion);
3084
 
3085
    waitforeverybody();
3086
 
3087
    StopSong();
3088
 
3089
    if (Bstrcasecmp(CacheLastLevel, LevelName) != 0)
3090
        DoTheCache();
3091
 
3092
    // auto aim / auto run / etc
3093
    InitPlayerGameSettings();
3094
 
3095
    // send packets with player info
3096
    InitNetPlayerOptions();
3097
 
3098
    // Initialize Game part of network code (When ready2send != 0)
3099
    InitNetVars();
3100
 
3101
    {
3102
        int track;
3103
        if (Level == 0)
3104
        {
3105
            track = RedBookSong[4+RANDOM_RANGE(10)];
3106
        }
3107
        else
3108
        {
3109
            track = RedBookSong[Level];
3110
        }
3111
        PlaySong(LevelSong, track, TRUE, TRUE);
3112
    }
3113
 
3114
    InitPrediction(&Player[myconnectindex]);
3115
 
3116
    if (!DemoInitOnce)
3117
        DemoRecordSetup();
3118
 
3119
    // everything has been inited at least once for RECORD
3120
    DemoInitOnce = TRUE;
3121
 
3122
//DebugWriteLoc(__FILE__, __LINE__);
3123
    waitforeverybody();
3124
 
3125
    CheckVersion(GameVersion);
3126
 
3127
    // IMPORTANT - MUST be right before game loop AFTER waitforeverybody
3128
    InitTimingVars();
3129
 
3130
    SetRedrawScreen(Player + myconnectindex);
3131
 
3132
    FX_SetVolume(gs.SoundVolume); // Turn volume back up
3133
    if (gs.Ambient)
3134
        StartAmbientSound();
3135
}
3136
 
5198 hendricks2 3137
void
3138
RunLevel(void)
5196 hendricks2 3139
{
3140
    int i;
3141
    InitRunLevel();
3142
 
3143
    FX_SetVolume(gs.SoundVolume);
3144
    SetSongVolume(gs.MusicVolume);
3145
 
3146
#if 0
3147
    waitforeverybody();
3148
#endif
3149
    ready2send = 1;
3150
 
3151
    while (TRUE)
3152
    {
3153
        handleevents();
3154
        OSD_DispatchQueued();
3155
 
3156
        if (quitevent) QuitFlag = TRUE;
3157
 
3158
        //MONO_PRINT("Before MoveLoop");
3159
        MoveLoop();
3160
        //MONO_PRINT("After MoveLoop");
3161
        //MONO_PRINT("Before DrawScreen");
3162
        drawscreen(Player + screenpeek);
3163
        //MONO_PRINT("After DrawScreen");
3164
 
3165
        if (QuitFlag)
3166
            break;
3167
 
3168
        if (ExitLevel)
3169
        {
3170
            ExitLevel = FALSE;
3171
            break;
3172
        }
3173
    }
3174
 
3175
    ready2send = 0;
3176
}
3177
 
3178
void swexit(int exitval)
3179
{
3180
    exit(exitval);
3181
}
3182
 
5198 hendricks2 3183
void DosScreen