Subversion Repositories eduke32

Rev

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