Subversion Repositories eduke32

Rev

Rev 8469 | Rev 8480 | 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
 
214
// Network game settings
215
    0, // GameType
216
    0, // Level
217
    0, // Monsters
218
    FALSE, // HurtTeammate
219
    TRUE, // SpawnMarkers Markers
220
    FALSE, // TeamPlay
221
    0, // Kill Limit
222
    0, // Time Limit
223
    0, // Color
224
    0, // Parental Lock
7512 hendricks2 225
    "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", // Password
5196 hendricks2 226
    TRUE, // nuke
227
    TRUE, // voxels
228
    FALSE, // stats
229
    FALSE, // mouse aiming on
230
    FALSE, // play cd
5212 hendricks2 231
    "Track??", // waveform track name
8338 hendricks2 232
    FALSE,
8339 hendricks2 233
    TRUE,
5196 hendricks2 234
};
235
GAME_SET gs;
236
 
5198 hendricks2 237
SWBOOL PlayerTrackingMode = FALSE;
238
SWBOOL PauseMode = FALSE;
239
SWBOOL PauseKeySet = FALSE;
240
SWBOOL SlowMode = FALSE;
241
SWBOOL FrameAdvanceTics = 3;
242
SWBOOL ScrollMode2D = FALSE;
5196 hendricks2 243
 
5198 hendricks2 244
SWBOOL DebugSO = FALSE;
245
SWBOOL DebugPanel = FALSE;
246
SWBOOL DebugSector = FALSE;
247
SWBOOL DebugActor = FALSE;
248
SWBOOL DebugAnim = FALSE;
249
SWBOOL DebugOperate = FALSE;
250
SWBOOL DebugActorFreeze = FALSE;
251
void LoadingLevelScreen(char *level_name);
5196 hendricks2 252
 
5198 hendricks2 253
uint8_t FakeMultiNumPlayers;
5196 hendricks2 254
 
255
int totalsynctics;
256
int turn_scale = 256;
257
int move_scale = 256;
258
 
259
short Level = 0;
5198 hendricks2 260
SWBOOL ExitLevel = FALSE;
261
int16_t OrigCommPlayers=0;
262
extern uint8_t CommPlayers;
263
extern SWBOOL CommEnabled;
5196 hendricks2 264
extern int bufferjitter;
265
 
5198 hendricks2 266
SWBOOL CameraTestMode = FALSE;
5196 hendricks2 267
 
7560 hendricks2 268
char ds[512];                           // debug string
5196 hendricks2 269
 
270
extern short NormalVisibility;
271
 
272
extern int quotebot, quotebotgoal;     // Multiplayer typing buffer
273
char recbuf[80];                        // Used as a temp buffer to hold typing text
274
 
275
extern unsigned char palette_data[256][3];             // Global palette array
276
 
277
#define ACT_STATUE 0
278
 
279
int score;
5198 hendricks2 280
SWBOOL QuitFlag = FALSE;
281
SWBOOL InGame = FALSE;
5196 hendricks2 282
 
5198 hendricks2 283
SWBOOL CommandSetup = FALSE;
5196 hendricks2 284
 
285
char UserMapName[80]="", buffer[80], ch;
286
char LevelName[20];
287
 
5198 hendricks2 288
uint8_t DebugPrintColor = 255;
5196 hendricks2 289
 
290
int krandcount;
291
 
292
/// L O C A L   P R O T O T Y P E S /////////////////////////////////////////////////////////
293
void BOT_DeleteAllBots(void);
5198 hendricks2 294
void BotPlayerInsert(PLAYERp pp);
295
void SybexScreen(void);
296
void DosScreen(void);
8271 hendricks2 297
void PlayTheme(void);
5198 hendricks2 298
void MenuLevel(void);
299
void StatScreen(PLAYERp mpp);
300
void InitRunLevel(void);
301
void RunLevel(void);
5196 hendricks2 302
/////////////////////////////////////////////////////////////////////////////////////////////
303
 
304
static FILE *debug_fout = NULL;
305
 
5198 hendricks2 306
void DebugWriteString(char *string)
5196 hendricks2 307
{
308
 
309
#if BETA || !DEBUG
310
    return;
311
#endif
312
 
313
    if (!debug_fout)
314
    {
315
        if ((debug_fout = fopen("dbg.foo", "ab+")) == NULL)
316
            return;
317
    }
318
 
319
    fprintf(debug_fout, "%s\n", string);
320
 
321
    //fclose(debug_fout);
322
    //debug_fout = NULL;
323
 
324
    fflush(debug_fout);
325
}
326
 
5198 hendricks2 327
void DebugWriteLoc(char *fname, int line)
5196 hendricks2 328
{
329
 
330
#if BETA || !DEBUG
331
    return;
332
#endif
333
 
334
    if (!debug_fout)
335
    {
336
        if ((debug_fout = fopen("dbg.foo", "ab+")) == NULL)
337
            return;
338
    }
339
 
340
    fprintf(debug_fout, "%s, %d\n", fname, line);
341
 
342
    //fclose(debug_fout);
343
    //debug_fout = NULL;
344
 
345
    fflush(debug_fout);
346
}
347
 
348
void Mono_Print(char *str)
349
{
350
    MONO_PRINT(str);
351
}
352
 
353
 
5198 hendricks2 354
extern SWBOOL DrawScreen;
5196 hendricks2 355
#if RANDOM_DEBUG
356
FILE *fout_err;
5198 hendricks2 357
SWBOOL RandomPrint;
5196 hendricks2 358
int krand1(char *file, unsigned line)
359
{
360
    ASSERT(!DrawScreen);
361
    if (RandomPrint && !Prediction)
362
    {
5198 hendricks2 363
        extern uint32_t MoveThingsCount;
5196 hendricks2 364
        sprintf(ds,"mtc %d, %s, line %d, %d",MoveThingsCount,file,line,randomseed);
365
        DebugWriteString(ds);
366
    }
367
    randomseed = ((randomseed * 21 + 1) & 65535);
368
    return randomseed;
369
}
370
 
371
int krand2()
372
{
373
    ASSERT(!DrawScreen);
374
    randomseed = ((randomseed * 21 + 1) & 65535);
375
    return randomseed;
376
}
377
 
378
#else
379
int krand1(void)
380
{
381
    ASSERT(!DrawScreen);
382
    krandcount++;
383
    randomseed = ((randomseed * 21 + 1) & 65535);
384
    return randomseed;
385
}
386
 
387
#endif
388
 
389
/*
390
void HeapCheck(char *file, int line)
391
{
392
    switch( _heapchk() )
393
        {
394
        case _HEAPOK:
395
            //printf( "OK - heap is good\n" );
396
            break;
397
        case _HEAPEMPTY:
398
            //printf( "OK - heap is empty\n" );
399
            break;
400
        case _HEAPBADBEGIN:
401
            sprintf(ds, "ERROR - heap is damaged: %s, %d", file, line);
402
            MONO_PRINT(ds);
403
            DebugWriteString(ds);
404
            setvmode(0x3);
405
            printf( "%s\n", ds);
406
            exit(0);
407
            break;
408
        case _HEAPBADNODE:
409
            sprintf(ds, "ERROR - bad node in heap: %s, %d", file, line);
410
            MONO_PRINT(ds);
411
            DebugWriteString(ds);
412
            setvmode(0x3);
413
            printf( "%s\n", ds);
414
            exit(0);
415
            break;
416
        }
417
}
418
    */
419
 
420
#if DEBUG
5198 hendricks2 421
SWBOOL
422
ValidPtr(void *ptr)
5196 hendricks2 423
{
424
    MEM_HDRp mhp;
5198 hendricks2 425
    uint8_t* check;
5196 hendricks2 426
 
427
    ASSERT(ptr != NULL);
428
 
5198 hendricks2 429
    mhp = (MEM_HDRp)(((uint8_t*) ptr) - sizeof(MEM_HDR));
5196 hendricks2 430
 
431
    if (mhp->size == 0 || mhp->checksum == 0)
432
    {
433
        printf("ValidPtr(): Size or Checksum == 0!\n");
434
        return FALSE;
435
    }
436
 
5198 hendricks2 437
    check = (uint8_t*) & mhp->size;
5196 hendricks2 438
 
439
    if (mhp->checksum == check[0] + check[1] + check[2] + check[3])
440
        return TRUE;
441
 
442
    printf("ValidPtr(): Checksum bad!\n");
443
    return FALSE;
444
}
445
 
5198 hendricks2 446
void
447
PtrCheckSum(void *ptr, unsigned int *stored, unsigned int *actual)
5196 hendricks2 448
{
449
    MEM_HDRp mhp;
5198 hendricks2 450
    uint8_t* check;
5196 hendricks2 451
 
452
    ASSERT(ptr != NULL);
453
 
5198 hendricks2 454
    mhp = (MEM_HDRp)(((uint8_t*) ptr) - sizeof(MEM_HDR));
5196 hendricks2 455
 
5198 hendricks2 456
    check = (uint8_t*) & mhp->size;
5196 hendricks2 457
 
458
    *stored = mhp->checksum;
459
    *actual = check[0] + check[1] + check[2] + check[3];
460
}
461
 
5198 hendricks2 462
void *
5196 hendricks2 463
AllocMem(int size)
464
{
5198 hendricks2 465
    uint8_t* bp;
5196 hendricks2 466
    MEM_HDRp mhp;
5198 hendricks2 467
    uint8_t* check;
5196 hendricks2 468
 
469
    ASSERT(size != 0);
470
 
5198 hendricks2 471
    bp = (uint8_t*) malloc(size + sizeof(MEM_HDR));
5196 hendricks2 472
 
473
    // Used for debugging, we can remove this at ship time
474
    if (bp == NULL)
475
    {
476
        TerminateGame();
477
        printf("Memory could NOT be allocated in AllocMem: size = %d\n",size);
478
        exit(0);
479
    }
480
 
481
    ASSERT(bp != NULL);
482
 
483
    mhp = (MEM_HDRp) bp;
484
 
485
    mhp->size = size;
5198 hendricks2 486
    check = (uint8_t*) & mhp->size;
5196 hendricks2 487
    mhp->checksum = check[0] + check[1] + check[2] + check[3];
488
 
489
    bp += sizeof(MEM_HDR);
490
 
491
    return bp;
492
}
493
 
5198 hendricks2 494
void *
495
ReAllocMem(void *ptr, int size)
5196 hendricks2 496
{
5198 hendricks2 497
    uint8_t* bp;
5196 hendricks2 498
    MEM_HDRp mhp;
5198 hendricks2 499
    uint8_t* check;
5196 hendricks2 500
 
501
    ASSERT(size != 0);
502
 
503
    ASSERT(ValidPtr(ptr));
504
 
5198 hendricks2 505
    mhp = (MEM_HDRp)(((uint8_t*) ptr) - sizeof(MEM_HDR));
5196 hendricks2 506
 
5198 hendricks2 507
    bp = (uint8_t*) realloc(mhp, size + sizeof(MEM_HDR));
5196 hendricks2 508
 
509
    ASSERT(bp != NULL);
510
 
511
    mhp = (MEM_HDRp) bp;
512
 
513
    mhp->size = size;
5198 hendricks2 514
    check = (uint8_t*) & mhp->size;
5196 hendricks2 515
    mhp->checksum = check[0] + check[1] + check[2] + check[3];
516
 
517
    bp += sizeof(MEM_HDR);
518
 
519
    ASSERT(ValidPtr(bp));
520
 
521
    return bp;
522
}
523
 
524
 
5198 hendricks2 525
void *
5196 hendricks2 526
CallocMem(int size, int num)
527
{
5198 hendricks2 528
    uint8_t* bp;
5196 hendricks2 529
    MEM_HDRp mhp;
5198 hendricks2 530
    uint8_t* check;
5196 hendricks2 531
    int num_bytes;
532
 
533
    ASSERT(size != 0 && num != 0);
534
 
535
    num_bytes = (size * num) + sizeof(MEM_HDR);
5198 hendricks2 536
    bp = (uint8_t*) calloc(num_bytes, 1);
5196 hendricks2 537
 
538
    // Used for debugging, we can remove this at ship time
539
    if (bp == NULL)
540
    {
541
        TerminateGame();
542
        printf("Memory could NOT be allocated in CallocMem: size = %d, num = %d\n",size,num);
543
        exit(0);
544
    }
545
 
546
    ASSERT(bp != NULL);
547
 
548
    mhp = (MEM_HDRp) bp;
549
 
550
    mhp->size = size;
5198 hendricks2 551
    check = (uint8_t*) & mhp->size;
5196 hendricks2 552
    mhp->checksum = check[0] + check[1] + check[2] + check[3];
553
 
554
    bp += sizeof(MEM_HDR);
555
 
556
    return bp;
557
}
558
 
5198 hendricks2 559
void
560
FreeMem(void *ptr)
5196 hendricks2 561
{
562
    MEM_HDRp mhp;
5198 hendricks2 563
    uint8_t* check;
5196 hendricks2 564
 
565
    ASSERT(ptr != NULL);
566
 
567
    ASSERT(ValidPtr(ptr));
568
 
5198 hendricks2 569
    mhp = (MEM_HDRp)(((uint8_t*) ptr) - sizeof(MEM_HDR));
570
    check = (uint8_t*)&mhp->size;
5196 hendricks2 571
 
572
    memset(mhp, 0xCC, mhp->size + sizeof(MEM_HDR));
573
 
574
    free(mhp);
575
}
576
 
577
#else
5198 hendricks2 578
SWBOOL
579
ValidPtr(void *ptr)
5196 hendricks2 580
{
581
    return TRUE;
582
}
583
 
5198 hendricks2 584
void *
5196 hendricks2 585
AllocMem(int size)
586
{
587
    return malloc(size);
588
}
589
 
5198 hendricks2 590
void *
5196 hendricks2 591
CallocMem(int size, int num)
592
{
593
    return calloc(size, num);
594
}
595
 
5198 hendricks2 596
void *
597
ReAllocMem(void *ptr, int size)
5196 hendricks2 598
{
599
    return realloc(ptr, size);
600
}
601
 
5198 hendricks2 602
void
603
FreeMem(void *ptr)
5196 hendricks2 604
{
605
    free(ptr);
606
}
607
 
608
#endif
609
 
610
int PointOnLine(int x, int y, int x1, int y1, int x2, int y2)
611
{
612
    // the closer to 0 the closer to the line the point is
613
    return ((x2 - x1) * (y - y1)) - ((y2 - y1) * (x - x1));
614
}
615
 
616
int
617
Distance(int x1, int y1, int x2, int y2)
618
{
619
    int min;
620
 
621
    if ((x2 = x2 - x1) < 0)
622
        x2 = -x2;
623
 
624
    if ((y2 = y2 - y1) < 0)
625
        y2 = -y2;
626
 
627
    if (x2 > y2)
628
        min = y2;
629
    else
630
        min = x2;
631
 
632
    return x2 + y2 - DIV2(min);
633
}
634
 
5198 hendricks2 635
void
636
MapSetAll2D(uint8_t fill)
5196 hendricks2 637
{
638
    int i;
639
 
640
    for (i = 0; i < (MAXWALLS >> 3); i++)
641
        show2dwall[i] = fill;
642
    for (i = 0; i < (MAXSPRITES >> 3); i++)
643
        show2dsprite[i] = fill;
644
 
645
    //for (i = 0; i < (MAXSECTORS >> 3); i++)
646
    for (i = 0; i < MAXSECTORS; i++)
647
    {
648
        if (sector[i].ceilingpicnum != 342 && sector[i].floorpicnum != 342)
649
            show2dsector[i>>3] |= (1<<(i&7));
650
        //show2dsector[i] = fill;
651
    }
652
}
653
 
5198 hendricks2 654
void
655
MapSetup(void)
5196 hendricks2 656
{
657
    MapSetAll2D(0xFF);
658
}
659
 
5198 hendricks2 660
void
661
setup2dscreen(void)
5196 hendricks2 662
{
663
    // qsetmode640350();
664
}
665
 
666
 
667
 
5198 hendricks2 668
void
669
TerminateGame(void)
5196 hendricks2 670
{
671
    int i,j;
672
    int oldtotalclock;
673
 
674
    DemoTerm();
675
 
676
    ErrorCorrectionQuit();
677
 
678
    uninitmultiplayers();
679
 
680
    if (CleanExit)
681
    {
682
        SybexScreen();
683
        //TenScreen();
684
    }
685
 
686
    ////--->>>> sound stuff was there
687
    //uninitkeys();
688
    KB_Shutdown();
689
 
690
    TermSetup();
691
 
692
    //Terminate3DSounds();                // Kill the sounds linked list
693
    UnInitSound();
694
 
7509 hendricks2 695
    timerUninit();
5196 hendricks2 696
 
697
    if (CleanExit)
698
        DosScreen();
699
 
8270 hendricks2 700
    engineUnInit();
8330 hendricks2 701
    FreeGroups();
8270 hendricks2 702
 
5196 hendricks2 703
    uninitgroupfile();
704
}
705
 
5198 hendricks2 706
void
7499 hendricks2 707
LoadLevel(const char *filename)
5196 hendricks2 708
{
709
    int pos;
710
 
7509 hendricks2 711
    if (engineLoadBoard(filename, SW_SHAREWARE ? 1 : 0, (vec3_t *)&Player[0], &Player[0].pang, &Player[0].cursectnum) == -1)
5196 hendricks2 712
    {
713
        TerminateGame();
714
#ifdef RENDERTYPEWIN
715
        {
716
            char msg[256];
717
            Bsnprintf(msg, 256, "Level not found: %s", filename);
718
            wm_msgbox(apptitle, msg);
719
        }
720
#else
721
        printf("Level Not Found: %s\n", filename);
722
#endif
723
        exit(0);
724
    }
725
}
726
 
5198 hendricks2 727
void
7499 hendricks2 728
LoadImages(const char *filename)
5196 hendricks2 729
{
730
    short ndx;
731
    FILE *fin;
732
 
7509 hendricks2 733
    if (artLoadFiles(filename, 32*1048576) == -1)
5196 hendricks2 734
    {
735
        TerminateGame();
736
#ifdef RENDERTYPEWIN
737
        {
738
            wm_msgbox(apptitle, "Art not found. Please check your GRP file.");
739
        }
740
#else
741
        printf("Art not found. Please check your GRP file.\n");
742
#endif
743
        exit(-1);
744
    }
745
}
746
 
747
void LoadDemoRun(void)
748
{
749
    short i;
750
    FILE *fin;
751
 
752
    fin = fopen("demos.run","r");
753
    if (fin)
754
    {
755
        memset(DemoName,'\0',sizeof(DemoName));
756
        for (i = 0; TRUE; i++)
757
        {
758
            if (fscanf(fin, "%s", DemoName[i]) == EOF)
759
                break;
760
        }
761
 
762
        fclose(fin);
763
    }
764
 
765
    memset(DemoText,'\0',sizeof(DemoText));
766
    fin = fopen("demotxt.run","r");
767
    if (fin)
768
    {
769
        fgets(ds, 6, fin);
770
        sscanf(ds,"%d",&DemoTextYstart);
771
        for (i = 0; TRUE; i++)
772
        {
773
            if (fgets(DemoText[i], SIZ(DemoText[0])-1, fin) == NULL)
774
                break;
775
        }
776
 
777
        fclose(fin);
778
    }
779
}
780
 
781
void DisplayDemoText(void)
782
{
783
    short w,h;
784
    short i;
785
 
786
    for (i = 0; i < 3; i++)
787
    {
788
        MNU_MeasureString(DemoText[i], &w, &h);
789
        PutStringTimer(Player, TEXT_TEST_COL(w), DemoTextYstart+(i*12), DemoText[i], 999);
790
    }
791
}
792
 
793
 
794
void Set_GameMode(void)
795
{
796
    extern int ScreenMode, ScreenWidth, ScreenHeight, ScreenBPP;
797
    int result;
798
    char ch;
799
 
800
    //DSPRINTF(ds,"ScreenMode %d, ScreenWidth %d, ScreenHeight %d",ScreenMode, ScreenWidth, ScreenHeight);
801
    //MONO_PRINT(ds);
802
    result = COVERsetgamemode(ScreenMode, ScreenWidth, ScreenHeight, ScreenBPP);
803
 
804
    if (result < 0)
805
    {
806
        buildprintf("Failure setting video mode %dx%dx%d %s! Attempting safer mode...",
807
                    ScreenWidth,ScreenHeight,ScreenBPP,ScreenMode ? "fullscreen" : "windowed");
808
        ScreenMode = 0;
809
        ScreenWidth = 640;
810
        ScreenHeight = 480;
811
        ScreenBPP = 8;
812
 
813
        result = COVERsetgamemode(ScreenMode, ScreenWidth, ScreenHeight, ScreenBPP);
814
        if (result < 0)
815
        {
816
            uninitmultiplayers();
817
            //uninitkeys();
818
            KB_Shutdown();
819
            TermSetup();
820
            UnInitSound();
7509 hendricks2 821
            timerUninit();
5196 hendricks2 822
            DosScreen();
823
            uninitgroupfile();
824
            exit(0);
825
        }
826
    }
827
}
828
 
829
void MultiSharewareCheck(void)
830
{
831
    if (!SW_SHAREWARE) return;
832
    if (numplayers > 4)
833
    {
834
#ifdef RENDERTYPEWIN
835
        wm_msgbox(apptitle,"To play a Network game with more than 4 players you must purchase "
836
                  "the full version.  Read the Ordering Info screens for details.");
837
#else
838
        printf(
839
            "\n\nTo play a Network game with more than 4 players you must purchase the\n"
840
            "full version.  Read the Ordering Info screens for details.\n\n");
841
#endif
842
        uninitmultiplayers();
843
        //uninitkeys();
844
        KB_Shutdown();
845
        TermSetup();
846
        UnInitSound();
7509 hendricks2 847
        timerUninit();
8270 hendricks2 848
        engineUnInit();
8330 hendricks2 849
        FreeGroups();
5196 hendricks2 850
        uninitgroupfile();
851
        exit(0);
852
    }
853
}
854
 
855
 
856
// Some mem crap for Jim
857
// I reserve 1 meg of heap space for our use out side the cache
858
int TotalMemory = 0;
859
int ActualHeap = 0;
860
 
5198 hendricks2 861
void InitAutoNet(void)
5196 hendricks2 862
{
863
    if (!AutoNet)
864
        return;
865
 
866
    gs.NetGameType      = Auto.Rules;
867
    gs.NetLevel         = Auto.Level;
868
    gs.NetMonsters      = Auto.Enemy;
869
    gs.NetSpawnMarkers  = Auto.Markers;
870
    gs.NetTeamPlay      = Auto.Team;
871
    gs.NetHurtTeammate  = Auto.HurtTeam;
872
    gs.NetKillLimit     = Auto.Kill;
873
    gs.NetTimeLimit     = Auto.Time;
874
    gs.NetColor         = Auto.Color;
875
    gs.NetNuke          = Auto.Nuke;
876
}
877
 
878
 
879
void AnimateCacheCursor(void)
880
{
881
#if 0
882
    struct rccoord old_pos;
883
    static short cursor_num = 0;
884
    static char cache_cursor[] =  {'|','/','-','\\'};
885
 
886
    if (GraphicsMode)
887
        return;
888
 
889
    cursor_num++;
890
    if (cursor_num > 3)
891
        cursor_num = 0;
892
 
893
    //old_pos = _gettextposition();
894
    //_settextposition( old_pos.row, old_pos.col );
895
    //_settextposition( 24,  25);
896
    _settextposition(25,  0);
897
    sprintf(ds,"Loading sound and graphics %c", cache_cursor[cursor_num]);
898
    _outtext(ds);
899
    //_settextposition( old_pos.row, old_pos.col );
900
#endif
901
}
902
 
903
void COVERsetbrightness(int bright, unsigned char *pal)
904
{
8272 hendricks2 905
    paletteSetColorTable(BASEPAL, pal);
906
    videoSetPalette(bright, BASEPAL, 0);
5196 hendricks2 907
}
908
 
909
 
910
static int firstnet = 0;    // JBF
911
 
912
extern int startwin_run(void);
913
 
5345 hendricks2 914
static void SW_FatalEngineError(void)
915
{
916
    wm_msgbox("Build Engine Initialisation Error",
917
              "There was a problem initialising the Build engine: %s", engineerrstr);
918
    exit(1);
919
}
920
 
5198 hendricks2 921
void
5552 hendricks2 922
InitGame(int32_t argc, char const * const * argv)
5196 hendricks2 923
{
924
    extern int MovesPerPacket;
925
    //void *ReserveMem=NULL;
926
    int i;
927
 
928
    DSPRINTF(ds,"InitGame...");
929
    MONO_PRINT(ds);
930
 
7509 hendricks2 931
    if (engineInit())
5345 hendricks2 932
        SW_FatalEngineError();
5196 hendricks2 933
 
8333 hendricks2 934
    {
935
        char tempbuf[256];
936
        snprintf(tempbuf, ARRAY_SIZE(tempbuf), APPNAME " %s", s_buildRev);
937
        OSD_SetVersion(tempbuf, 10,0);
938
    }
939
    OSD_SetParameters(0, 0, 0, 4, 2, 4, "^14", "^14", 0);
940
 
5196 hendricks2 941
    InitSetup();
942
 
943
    InitAutoNet();
944
 
7509 hendricks2 945
    timerInit(120);
5196 hendricks2 946
 
947
    CON_InitConsole();  // Init console command list
948
 
949
    ////DSPRINTF(ds,"%s, %d",__FILE__,__LINE__);   MONO_PRINT(ds);
950
 
951
    //InitFX();
952
 
953
    memcpy(palette_data,palette,768);
954
    InitPalette();
955
    // sets numplayers, connecthead, connectpoint2, myconnectindex
956
 
957
    if (!firstnet)
958
        initmultiplayers(0, NULL, 0, 0, 0);
5206 hendricks2 959
    else if (initmultiplayersparms(argc - firstnet, &argv[firstnet]))
5196 hendricks2 960
    {
961
        buildputs("Waiting for players...\n");
962
        while (initmultiplayerscycle())
963
        {
964
            handleevents();
965
            if (quitevent)
966
            {
967
                QuitFlag = TRUE;
968
                return;
969
            }
970
        }
971
    }
972
    initsynccrc();
973
 
974
    // code to duplicate packets
975
    if (numplayers > 4 && MovesPerPacket == 1)
976
    {
977
        MovesPerPacket = 2;
978
    }
979
 
980
    MultiSharewareCheck();
981
 
982
    if (numplayers > 1)
983
    {
984
        CommPlayers = numplayers;
985
        OrigCommPlayers = CommPlayers;
986
        CommEnabled = TRUE;
987
        if (!BotMode)
988
            gNet.MultiGameType = MULTI_GAME_COMMBAT;
989
        else
990
            gNet.MultiGameType = MULTI_GAME_AI_BOTS;
991
 
992
#if 0 //def NET_MODE_MASTER_SLAVE
993
        if (!NetModeOverride)
994
        {
995
            if (numplayers <= 4)
996
                NetBroadcastMode = TRUE;
997
            else
998
                NetBroadcastMode = FALSE;
999
        }
1000
#endif
1001
    }
1002
 
1003
    LoadDemoRun();
1004
    // Save off total heap for later calculations
1005
    //TotalMemory = Z_AvailHeap();
1006
    //DSPRINTF(ds,"Available Heap before LoadImages =  %d", TotalMemory);
1007
    //MONO_PRINT(ds);
1008
    // Reserve 1.5 megs for normal program use
1009
    // Generally, SW is consuming about a total of 11 megs including
1010
    // all the cached in graphics, etc. per level, so even on a 16 meg
1011
    // system, reserving 1.5 megs is fine.
1012
    // Note that on a 16 meg machine, Ken was leaving us about
1013
    // 24k for use outside the cache!  This was causing out of mem problems
1014
    // when songs, etc., greater than the remaining heap were being loaded.
1015
    // Even if you pre-cache songs, etc. to help, reserving some heap is
1016
    // a very smart idea since the game uses malloc throughout execution.
1017
    //ReserveMem = AllocMem(1L<<20);
1018
    //if(ReserveMem == 0) MONO_PRINT("Could not allocate 1.5 meg reserve!");
1019
 
1020
    // LoadImages will now proceed to steal all the remaining heap space
1021
    //_outtext("\n\n\n\n\n\n\n\n");
8328 hendricks2 1022
    //buildputs("Loading sound and graphics...\n");
5196 hendricks2 1023
    //AnimateCacheCursor();
1024
    LoadImages("tiles000.art");
1025
 
1026
    // Now free it up for later use
1027
    /*
1028
    if(ReserveMem)
1029
        {
1030
        // Recalc TotalMemory for later reference
1031
        ActualHeap = Z_AvailHeap() + 1536000L;
1032
        FreeMem(ReserveMem);
1033
        }
1034
    */
1035
 
1036
    Connect();
1037
    SortBreakInfo();
1038
    parallaxtype = 1;
5211 hendricks2 1039
    SW_InitMultiPsky();
5196 hendricks2 1040
 
1041
    memset(Track, 0, sizeof(Track));
1042
 
1043
    memset(Player, 0, sizeof(Player));
1044
    for (i = 0; i < MAX_SW_PLAYERS; i++)
1045
        INITLIST(&Player[i].PanelSpriteList);
1046
 
1047
    LoadKVXFromScript("swvoxfil.txt");    // Load voxels from script file
1048
    LoadPLockFromScript("swplock.txt");   // Get Parental Lock setup info
1049
    if (!SW_SHAREWARE)
1050
        LoadCustomInfoFromScript("swcustom.txt");   // Load user customisation information
1051
 
5217 hendricks2 1052
    if (!loaddefinitionsfile(G_DefFile())) buildputs("Definitions file loaded.\n");
5196 hendricks2 1053
 
6673 hendricks2 1054
    for (char * m : g_defModules)
1055
        free(m);
1056
    g_defModules.clear();
5217 hendricks2 1057
 
7509 hendricks2 1058
    if (enginePostInit())
5345 hendricks2 1059
        SW_FatalEngineError();
1060
 
8469 hendricks2 1061
    palettePostLoadLookups();
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
    ClearStartMost();
1829
    gs.BorderNum = save;
7509 hendricks2 1830
    videoClearViewableArea(0L);
1831
    videoNextPage();
5196 hendricks2 1832
 
1833
    // Lo Wang feel like singing!
1834
    handle = PlaySound(DIGI_JG95012,&zero,&zero,&zero,v3df_none);
1835
 
1836
    if (handle > 0)
1837
        while (FX_SoundActive(handle)) ;
1838
 
1839
    // try 14 then 2 then quit
1840
    if (!PlaySong(NULL, 14, FALSE, TRUE))
1841
    {
1842
        if (!PlaySong(NULL, 2, FALSE, TRUE))
1843
        {
1844
            handle = PlaySound(DIGI_NOLIKEMUSIC,&zero,&zero,&zero,v3df_none);
1845
            if (handle > 0)
1846
                while (FX_SoundActive(handle)) handleevents();
1847
            return;
1848
        }
1849
    }
1850
 
1851
    ready2send = 0;
1852
    totalclock = 0;
1853
    ototalclock = 0;
1854
 
1855
    ResetKeys();
1856
    curpic = CREDITS1_PIC;
1857
 
1858
    while (TRUE)
1859
    {
1860
        // taken from top of faketimerhandler
1861
        // limits checks to max of 40 times a second
1862
        if (totalclock >= ototalclock + synctics)
1863
        {
1864
            ototalclock += synctics;
1865
            timer += synctics;
1866
        }
1867
 
1868
        rotatesprite(0, 0, RS_SCALE, 0, curpic, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
1869
 
7509 hendricks2 1870
        videoNextPage();
5196 hendricks2 1871
 
1872
        if (timer > 8*120)
1873
        {
1874
            curpic = CREDITS2_PIC;
1875
        }
1876
 
1877
        if (timer > 16*120)
1878
        {
1879
            timer = 0;
1880
            curpic = CREDITS1_PIC;
1881
        }
1882
 
1883
 
1884
        if (!SongIsPlaying())
1885
            break;
1886
 
1887
        if (KEY_PRESSED(KEYSC_ESC))
1888
            break;
1889
    }
1890
 
1891
    // put up a blank screen while loading
7509 hendricks2 1892
    videoClearViewableArea(0L);
1893
    videoNextPage();
5196 hendricks2 1894
    ResetKeys();
1895
    StopSong();
1896
}
1897
 
1898
 
5198 hendricks2 1899
void
1900
SybexScreen(void)
5196 hendricks2 1901
{
1902
    if (!SW_SHAREWARE) return;
1903
 
1904
    if (CommEnabled)
1905
        return;
1906
 
1907
    rotatesprite(0, 0, RS_SCALE, 0, 5261, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
7509 hendricks2 1908
    videoNextPage();
5196 hendricks2 1909
 
1910
    ResetKeys();
1911
    while (!KeyPressed() && !quitevent) handleevents();
1912
}
1913
 
1914
// CTW REMOVED
1915
/*
5198 hendricks2 1916
void
1917
TenScreen(void)
5196 hendricks2 1918
    {
1919
    char called;
1920
    int fin;
1921
    char backup_pal[256*3];
1922
    char pal[PAL_SIZE];
1923
    char tempbuf[256];
1924
    char *palook_bak = palookup[0];
1925
    int i;
5198 hendricks2 1926
    uint32_t bak;
5196 hendricks2 1927
    int bakready2send;
1928
 
1929
    if (CommEnabled)
1930
        return;
1931
 
1932
    bak = totalclock;
1933
 
1934
    flushperms();
1935
    clearview(0);
1936
    nextpage();
1937
 
1938
    for (i = 0; i < 256; i++)
1939
        tempbuf[i] = i;
1940
    palookup[0] = tempbuf;
1941
 
1942
    GetPaletteFromVESA(pal);
1943
    memcpy(backup_pal, pal, PAL_SIZE);
1944
 
1945
    if ((fin = kopen4load("ten.pal", 0)) != -1)
1946
        {
1947
        kread(fin, pal, PAL_SIZE);
1948
        kclose(fin);
1949
        }
1950
 
1951
    // palette to black
1952
    FadeOut(0, 0);
1953
    bakready2send = ready2send;
1954
    //totalclock = 0;
1955
    //ototalclock = 0;
1956
 
1957
    flushperms();
1958
    // draw it
1959
    rotatesprite(0, 0, RS_SCALE, 0, TEN_PIC, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
1960
    // bring to the front - still back palette
1961
    nextpage();
1962
    // set pal
1963
    SetPaletteToVESA(pal);
1964
    //FadeIn(0, 3);
1965
    ResetKeys();
1966
 
1967
    while (!KeyPressed());
1968
 
1969
    palookup[0] = palook_bak;
1970
 
1971
    clearview(0);
1972
    nextpage();
1973
    SetPaletteToVESA(backup_pal);
1974
 
1975
    // put up a blank screen while loading
1976
    clearview(0);
1977
    nextpage();
1978
 
1979
    ready2send = bakready2send;
1980
    totalclock = bak;
1981
    }
1982
*/
1983
// CTW REMOVED END
1984
 
5198 hendricks2 1985
void
1986
TitleLevel(void)
5196 hendricks2 1987
{
1988
    char called;
1989
    int fin;
1990
    unsigned char backup_pal[256*3];
1991
    unsigned char pal[PAL_SIZE];
6041 hendricks2 1992
    char tempbuf[256];
1993
    char *palook_bak = palookup[0];
5196 hendricks2 1994
    int i;
1995
 
1996
    for (i = 0; i < 256; i++)
1997
        tempbuf[i] = i;
1998
    palookup[0] = tempbuf;
1999
 
2000
    //GetPaletteFromVESA(pal);
2001
    //memcpy(backup_pal, pal, PAL_SIZE);
2002
 
7509 hendricks2 2003
    videoClearViewableArea(0L);
2004
    videoNextPage();
5196 hendricks2 2005
 
2006
//    if ((fin = kopen4load("title.pal", 0)) != -1)
2007
//        {
2008
//        kread(fin, pal, PAL_SIZE);
2009
//        kclose(fin);
2010
//        SetPaletteToVESA(pal);
2011
//        }
2012
 
2013
//    clearview(0);
2014
//    nextpage();
2015
 
2016
    //FadeOut(0, 0);
2017
    ready2send = 0;
2018
    totalclock = 0;
2019
    ototalclock = 0;
2020
 
2021
    rotatesprite(0, 0, RS_SCALE, 0, TITLE_PIC, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
7509 hendricks2 2022
    videoNextPage();
5196 hendricks2 2023
    //FadeIn(0, 3);
2024
 
2025
    ResetKeys();
2026
    while (TRUE)
2027
    {
2028
        handleevents();
2029
        OSD_DispatchQueued();
2030
 
2031
        // taken from top of faketimerhandler
2032
        // limits checks to max of 40 times a second
2033
        if (totalclock >= ototalclock + synctics)
2034
        {
2035
            //void MNU_CheckForMenusAnyKey( void );
2036
 
2037
            ototalclock += synctics;
2038
            //MNU_CheckForMenusAnyKey();
2039
        }
2040
 
2041
        //if (UsingMenus)
2042
        //    MNU_DrawMenu();
2043
 
2044
        //drawscreen as fast as you can
2045
        rotatesprite(0, 0, RS_SCALE, 0, TITLE_PIC, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2046
 
7509 hendricks2 2047
        videoNextPage();
5196 hendricks2 2048
 
2049
        if (totalclock > 5*120 || KeyPressed())
2050
        {
2051
            DemoMode = TRUE;
2052
            DemoPlaying = TRUE;
2053
            break;
2054
        }
2055
    }
2056
 
2057
    palookup[0] = palook_bak;
2058
 
2059
//    clearview(0);
2060
//    nextpage();
2061
    //SetPaletteToVESA(backup_pal);
2062
 
2063
    // put up a blank screen while loading
2064
//    clearview(0);
2065
//    nextpage();
2066
}
2067
 
2068
 
5198 hendricks2 2069
void DrawMenuLevelScreen(void)
5196 hendricks2 2070
{
7509 hendricks2 2071
    renderFlushPerms();
2072
    videoClearViewableArea(0L);
5196 hendricks2 2073
    rotatesprite(0, 0, RS_SCALE, 0, TITLE_PIC, 20, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2074
}
2075
 
5198 hendricks2 2076
void DrawStatScreen(void)
5196 hendricks2 2077
{
7509 hendricks2 2078
    renderFlushPerms();
2079
    videoClearViewableArea(0L);
5196 hendricks2 2080
    rotatesprite(0, 0, RS_SCALE, 0, STAT_SCREEN_PIC, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2081
}
2082
 
5198 hendricks2 2083
void DrawLoadLevelScreen(void)
5196 hendricks2 2084
{
7509 hendricks2 2085
    renderFlushPerms();
2086
    videoClearViewableArea(0L);
5196 hendricks2 2087
    rotatesprite(0, 0, RS_SCALE, 0, TITLE_PIC, 20, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2088
}
2089
 
2090
short PlayerQuitMenuLevel = -1;
2091
 
5198 hendricks2 2092
void
2093
IntroAnimLevel(void)
5196 hendricks2 2094
{
2095
    DSPRINTF(ds,"IntroAnimLevel");
2096
    MONO_PRINT(ds);
2097
    playanm(0);
2098
}
2099
 
5198 hendricks2 2100
void
2101
MenuLevel(void)
5196 hendricks2 2102
{
5198 hendricks2 2103
    SWBOOL MNU_StartNetGame(void);
5196 hendricks2 2104
    char called;
2105
    int fin;
8050 pogokeen 2106
    extern ClockTicks totalclocklock;
5196 hendricks2 2107
    short w,h;
2108
 
2109
    DSPRINTF(ds,"MenuLevel...");
2110
    MONO_PRINT(ds);
2111
 
2112
    if (AutoNet)
2113
    {
2114
        DrawMenuLevelScreen();
2115
 
2116
        if (CommEnabled)
2117
        {
2118
            sprintf(ds,"Lo Wang is waiting for other players...");
2119
            MNU_MeasureString(ds, &w, &h);
2120
            MNU_DrawString(TEXT_TEST_COL(w), 170, ds, 1, 16);
2121
 
2122
            sprintf(ds,"They are afraid!");
2123
            MNU_MeasureString(ds, &w, &h);
2124
            MNU_DrawString(TEXT_TEST_COL(w), 180, ds, 1, 16);
2125
        }
2126
 
7509 hendricks2 2127
        videoNextPage();
5196 hendricks2 2128
 
2129
        waitforeverybody();
2130
        FirstTimeIntoGame = TRUE;
2131
        MNU_StartNetGame();
2132
        FirstTimeIntoGame = FALSE;
2133
        waitforeverybody();
2134
        ExitLevel = FALSE;
2135
        FinishedLevel = FALSE;
2136
        BorderAdjust = TRUE;
2137
        UsingMenus = FALSE;
2138
        InMenuLevel = FALSE;
2139
        return;
2140
    }
2141
 
2142
    // do demos only if not playing multi play
2143
    if (!CommEnabled && numplayers <= 1 && !FinishAnim && !NoDemoStartup)
2144
    {
2145
        // demos exist - do demo instead
2146
        if (DemoName[0][0] != '\0')
2147
        {
2148
            DemoMode = TRUE;
2149
            DemoPlaying = TRUE;
2150
            return;
2151
        }
2152
    }
2153
 
2154
    DemoMode = FALSE;
2155
    DemoPlaying = FALSE;
2156
 
7509 hendricks2 2157
    videoClearViewableArea(0L);
2158
    videoNextPage();
5196 hendricks2 2159
 
2160
    //FadeOut(0, 0);
2161
    ready2send = 0;
2162
    totalclock = 0;
2163
    ototalclock = 0;
2164
    ExitLevel = FALSE;
2165
    InMenuLevel = TRUE;
2166
 
2167
    DrawMenuLevelScreen();
2168
 
2169
    if (CommEnabled)
2170
    {
2171
        sprintf(ds,"Lo Wang is waiting for other players...");
2172
        MNU_MeasureString(ds, &w, &h);
2173
        MNU_DrawString(TEXT_TEST_COL(w), 170, ds, 1, 16);
2174
 
2175
        sprintf(ds,"They are afraid!");
2176
        MNU_MeasureString(ds, &w, &h);
2177
        MNU_DrawString(TEXT_TEST_COL(w), 180, ds, 1, 16);
2178
    }
2179
 
7509 hendricks2 2180
    videoNextPage();
5196 hendricks2 2181
    //FadeIn(0, 3);
2182
 
2183
    waitforeverybody();
2184
 
2185
    // don't allow BorderAdjusting in these menus
2186
    BorderAdjust = FALSE;
2187
 
2188
    ResetKeys();
2189
 
2190
    if (SW_SHAREWARE)
2191
    {
2192
        // go to ordering menu only if shareware
2193
        if (FinishAnim)
2194
        {
2195
            KEY_PRESSED(KEYSC_ESC) = 1;
2196
            ControlPanelType = ct_ordermenu;
2197
            FinishAnim = 0;
2198
        }
2199
    }
2200
    else
2201
    {
2202
        FinishAnim = 0;
2203
    }
2204
 
2205
    while (TRUE)
2206
    {
2207
        handleevents();
2208
        OSD_DispatchQueued();
2209
 
2210
        if (quitevent) QuitFlag = TRUE;
2211
 
2212
        // taken from top of faketimerhandler
2213
        // limits checks to max of 40 times a second
2214
        if (totalclock >= ototalclock + synctics)
2215
        {
2216
            ototalclock += synctics;
2217
            MNU_CheckForMenusAnyKey();
2218
            if (CommEnabled)
2219
                getpackets();
2220
        }
2221
 
2222
        if (CommEnabled)
2223
        {
2224
            if (MultiPlayQuitFlag)
2225
            {
2226
                short pnum;
5198 hendricks2 2227
                uint8_t pbuf[1];
5196 hendricks2 2228
                QuitFlag = TRUE;
2229
                pbuf[0] = PACKET_TYPE_MENU_LEVEL_QUIT;
2230
                netbroadcastpacket(pbuf, 1);                      // TENSW
2231
                break;
2232
            }
2233
 
2234
            if (PlayerQuitMenuLevel >= 0)
2235
            {
2236
                MenuCommPlayerQuit(PlayerQuitMenuLevel);
2237
                PlayerQuitMenuLevel = -1;
2238
            }
2239
        }
2240
 
2241
        if (ExitLevel)
2242
        {
2243
            // Quiting Level
2244
            ExitLevel = FALSE;
2245
            break;
2246
        }
2247
 
2248
        if (QuitFlag)
2249
        {
2250
            // Quiting Game
2251
            break;
2252
        }
2253
 
2254
        // force the use of menus at all time
2255
        if (!UsingMenus && !ConPanel)
2256
        {
2257
            KEY_PRESSED(KEYSC_ESC) = TRUE;
2258
            MNU_CheckForMenusAnyKey();
2259
        }
2260
 
2261
        // must lock the clock for drawing so animations will happen
2262
        totalclocklock = totalclock;
2263
 
2264
        //drawscreen as fast as you can
2265
        DrawMenuLevelScreen();
2266
 
2267
        if (UsingMenus)
2268
            MNU_DrawMenu();
2269
 
7509 hendricks2 2270
        videoNextPage();
5196 hendricks2 2271
    }
2272
 
2273
    BorderAdjust = TRUE;
2274
    //LoadGameOutsideMoveLoop = FALSE;
2275
    KEY_PRESSED(KEYSC_ESC) = FALSE;
2276
    KB_ClearKeysDown();
2277
    //ExitMenus();
2278
    UsingMenus = FALSE;
2279
    InMenuLevel = FALSE;
7509 hendricks2 2280
    videoClearViewableArea(0L);
2281
    videoNextPage();
5196 hendricks2 2282
}
2283
 
5198 hendricks2 2284
void
2285
SceneLevel(void)
5196 hendricks2 2286
{
5198 hendricks2 2287
    SWBOOL dp_bak;
2288
    SWBOOL dm_bak;
5196 hendricks2 2289
    FILE *fin;
2290
#define CINEMATIC_DEMO_FILE "$scene.dmo"
2291
 
2292
    // make sure it exists
2293
    if ((fin = fopen(CINEMATIC_DEMO_FILE,"rb")) == NULL)
2294
        return;
2295
    else
2296
        fclose(fin);
2297
 
2298
    strcpy(DemoFileName,CINEMATIC_DEMO_FILE);
2299
 
2300
    dp_bak = DemoPlaying;
2301
    dm_bak = DemoMode;
2302
 
2303
    DemoMode = TRUE;
2304
    DemoPlaying = TRUE;
2305
    DemoOverride = TRUE;
2306
    InitLevel();
2307
    DemoOverride = FALSE;
2308
 
2309
    ScenePlayBack();
2310
    TerminateLevel();
2311
    DemoMode = dm_bak;
2312
    DemoPlaying = dp_bak;
2313
}
2314
 
5198 hendricks2 2315
void
5196 hendricks2 2316
LoadingLevelScreen(char *level_name)
2317
{
2318
    short w,h;
5198 hendricks2 2319
    extern SWBOOL DemoMode;
5196 hendricks2 2320
    extern char *MNU_LevelName[28];
2321
    DrawLoadLevelScreen();
2322
 
2323
    if (DemoMode)
2324
        sprintf(ds,"DEMO");
2325
    else
2326
        sprintf(ds,"ENTERING");
2327
 
2328
    MNU_MeasureString(ds, &w, &h);
2329
    MNU_DrawString(TEXT_TEST_COL(w), 170, ds,1,16);
2330
 
2331
    if (UserMapName[0])
2332
        sprintf(ds,"%s",UserMapName);
2333
    else
2334
        sprintf(ds,"%s",LevelInfo[Level].Description);
2335
 
2336
    MNU_MeasureString(ds, &w, &h);
2337
    MNU_DrawString(TEXT_TEST_COL(w), 180, ds,1,16);
2338
 
7509 hendricks2 2339
    videoNextPage();
5196 hendricks2 2340
}
2341
 
5198 hendricks2 2342
void
5196 hendricks2 2343
gNextState(STATEp *State)
2344
{
2345
    // Transition to the next state
2346
    *State = (*State)->NextState;
2347
 
2348
    if (TEST((*State)->Tics, SF_QUICK_CALL))
2349
    {
2350
        (*(*State)->Animator)(0);
2351
        *State = (*State)->NextState;
2352
    }
2353
}
2354
 
2355
// Generic state control
5198 hendricks2 2356
void
5196 hendricks2 2357
gStateControl(STATEp *State, int *tics)
2358
{
2359
    *tics += synctics;
2360
 
2361
    // Skip states if too much time has passed
2362
    while (*tics >= (*State)->Tics)
2363
    {
2364
        // Set Tics
2365
        *tics -= (*State)->Tics;
2366
        gNextState(State);
2367
    }
2368
 
2369
    // Call the correct animator
2370
    if ((*State)->Animator)
2371
        (*(*State)->Animator)(0);
2372
}
2373
 
2374
int BonusPunchSound(short SpriteNum)
2375
{
2376
    PLAYERp pp = Player + myconnectindex;
2377
    PlaySound(DIGI_PLAYERYELL3, &pp->posx, &pp->posy, &pp->posz, v3df_none);
2378
    return 0;
2379
}
2380
 
2381
int BonusKickSound(short SpriteNum)
2382
{
2383
    PLAYERp pp = Player + myconnectindex;
2384
    PlaySound(DIGI_PLAYERYELL2, &pp->posx, &pp->posy, &pp->posz, v3df_none);
2385
    return 0;
2386
}
2387
 
2388
int BonusGrabSound(short SpriteNum)
2389
{
2390
    PLAYERp pp = Player + myconnectindex;
2391
    PlaySound(DIGI_BONUS_GRAB, &pp->posx, &pp->posy, &pp->posz, v3df_none);
2392
    return 0;
2393
}
2394
 
5198 hendricks2 2395
void
5196 hendricks2 2396
BonusScreen(PLAYERp pp)
2397
{
2398
    int minutes,seconds,second_tics;
5198 hendricks2 2399
    extern SWBOOL FinishedLevel;
5196 hendricks2 2400
    extern int PlayClock;
2401
    extern short LevelSecrets;
2402
    extern short TotalKillable;
2403
    short w,h;
2404
    short pic,limit;
2405
    int zero=0;
2406
    int handle = 0;
2407
    short LI_Num;
2408
 
2409
 
2410
#define BONUS_SCREEN_PIC 5120
2411
#define BONUS_ANIM 5121
2412
#define BONUS_ANIM_FRAMES (5159-5121)
2413
 
2414
#define BREAK_LIGHT_RATE 18
2415
 
2416
#define BONUS_PUNCH 5121
2417
#define BONUS_KICK 5136
2418
#define BONUS_GRAB 5151
2419
#define BONUS_REST 5121
2420
 
2421
#define BONUS_TICS 8
2422
#define BONUS_GRAB_TICS 20
2423
#define BONUS_REST_TICS 50
2424
 
2425
    static STATE s_BonusPunch[] =
2426
    {
2427
        {BONUS_PUNCH + 0, BONUS_TICS, NULL, &s_BonusPunch[1]},
2428
        {BONUS_PUNCH + 1, BONUS_TICS, NULL, &s_BonusPunch[2]},
2429
        {BONUS_PUNCH + 2, BONUS_TICS, NULL, &s_BonusPunch[3]},
2430
        {BONUS_PUNCH + 2, 0|SF_QUICK_CALL, BonusPunchSound, &s_BonusPunch[4]},
2431
        {BONUS_PUNCH + 3, BONUS_TICS, NULL, &s_BonusPunch[5]},
2432
        {BONUS_PUNCH + 4, BONUS_TICS, NULL, &s_BonusPunch[6]},
2433
        {BONUS_PUNCH + 5, BONUS_TICS, NULL, &s_BonusPunch[7]},
2434
        {BONUS_PUNCH + 6, BONUS_TICS, NULL, &s_BonusPunch[8]},
2435
        {BONUS_PUNCH + 7, BONUS_TICS, NULL, &s_BonusPunch[9]},
2436
        {BONUS_PUNCH + 8, BONUS_TICS, NULL, &s_BonusPunch[10]},
2437
        {BONUS_PUNCH + 9, BONUS_TICS, NULL, &s_BonusPunch[11]},
2438
        {BONUS_PUNCH + 10, BONUS_TICS, NULL, &s_BonusPunch[12]},
2439
        {BONUS_PUNCH + 11, BONUS_TICS, NULL, &s_BonusPunch[13]},
2440
        {BONUS_PUNCH + 12, BONUS_TICS, NULL, &s_BonusPunch[14]},
2441
        {BONUS_PUNCH + 14, 90,        NULL, &s_BonusPunch[15]},
2442
        {BONUS_PUNCH + 14, BONUS_TICS, NULL, &s_BonusPunch[15]},
2443
    };
2444
 
2445
    static STATE s_BonusKick[] =
2446
    {
2447
        {BONUS_KICK + 0, BONUS_TICS, NULL, &s_BonusKick[1]},
2448
        {BONUS_KICK + 1, BONUS_TICS, NULL, &s_BonusKick[2]},
2449
        {BONUS_KICK + 2, BONUS_TICS, NULL, &s_BonusKick[3]},
2450
        {BONUS_KICK + 2, 0|SF_QUICK_CALL, BonusKickSound, &s_BonusKick[4]},
2451
        {BONUS_KICK + 3, BONUS_TICS, NULL, &s_BonusKick[5]},
2452
        {BONUS_KICK + 4, BONUS_TICS, NULL, &s_BonusKick[6]},
2453
        {BONUS_KICK + 5, BONUS_TICS, NULL, &s_BonusKick[7]},
2454
        {BONUS_KICK + 6, BONUS_TICS, NULL, &s_BonusKick[8]},
2455
        {BONUS_KICK + 7, BONUS_TICS, NULL, &s_BonusKick[9]},
2456
        {BONUS_KICK + 8, BONUS_TICS, NULL, &s_BonusKick[10]},
2457
        {BONUS_KICK + 9, BONUS_TICS, NULL, &s_BonusKick[11]},
2458
        {BONUS_KICK + 10, BONUS_TICS, NULL, &s_BonusKick[12]},
2459
        {BONUS_KICK + 11, BONUS_TICS, NULL, &s_BonusKick[13]},
2460
        {BONUS_KICK + 12, BONUS_TICS, NULL, &s_BonusKick[14]},
2461
        {BONUS_KICK + 14, 90,        NULL, &s_BonusKick[15]},
2462
        {BONUS_KICK + 14, BONUS_TICS, NULL, &s_BonusKick[15]},
2463
    };
2464
 
2465
    static STATE s_BonusGrab[] =
2466
    {
2467
        {BONUS_GRAB + 0, BONUS_GRAB_TICS, NULL, &s_BonusGrab[1]},
2468
        {BONUS_GRAB + 1, BONUS_GRAB_TICS, NULL, &s_BonusGrab[2]},
2469
        {BONUS_GRAB + 2, BONUS_GRAB_TICS, NULL, &s_BonusGrab[3]},
2470
        {BONUS_GRAB + 2, 0|SF_QUICK_CALL, BonusGrabSound, &s_BonusGrab[4]},
2471
        {BONUS_GRAB + 3, BONUS_GRAB_TICS, NULL, &s_BonusGrab[5]},
2472
        {BONUS_GRAB + 4, BONUS_GRAB_TICS, NULL, &s_BonusGrab[6]},
2473
        {BONUS_GRAB + 5, BONUS_GRAB_TICS, NULL, &s_BonusGrab[7]},
2474
        {BONUS_GRAB + 6, BONUS_GRAB_TICS, NULL, &s_BonusGrab[8]},
2475
        {BONUS_GRAB + 7, BONUS_GRAB_TICS, NULL, &s_BonusGrab[9]},
2476
        {BONUS_GRAB + 8, BONUS_GRAB_TICS, NULL, &s_BonusGrab[10]},
2477
        {BONUS_GRAB + 9, 90,             NULL, &s_BonusGrab[11]},
2478
        {BONUS_GRAB + 9, BONUS_GRAB_TICS, NULL, &s_BonusGrab[11]},
2479
    };
2480
 
2481
#if 1 // Turned off the standing animate because he looks like a FAG!
2482
    static STATE s_BonusRest[] =
2483
    {
2484
        {BONUS_REST + 0, BONUS_REST_TICS, NULL, &s_BonusRest[1]},
2485
        {BONUS_REST + 1, BONUS_REST_TICS, NULL, &s_BonusRest[2]},
2486
        {BONUS_REST + 2, BONUS_REST_TICS, NULL, &s_BonusRest[3]},
2487
        {BONUS_REST + 1, BONUS_REST_TICS, NULL, &s_BonusRest[0]},
2488
    };
2489
#else
2490
    static STATE s_BonusRest[] =
2491
    {
2492
        {BONUS_REST + 0, BONUS_REST_TICS, NULL, &s_BonusRest[1]},
2493
        {BONUS_REST + 0, BONUS_REST_TICS, NULL, &s_BonusRest[0]},
2494
    };
2495
#endif
2496
 
2497
    static STATEp s_BonusAnim[] =
2498
    {
2499
        s_BonusPunch,
2500
        s_BonusKick,
2501
        s_BonusGrab
2502
    };
2503
 
2504
    STATEp State = s_BonusRest;
2505
 
2506
    int Tics = 0;
2507
    int line = 0;
5198 hendricks2 2508
    SWBOOL BonusDone;
5196 hendricks2 2509
    UserInput uinfo = { FALSE, FALSE, dir_None };
2510
 
2511
    if (Level < 0) Level = 0;
2512
 
7509 hendricks2 2513
    videoClearViewableArea(0L);
2514
    videoNextPage();
5196 hendricks2 2515
 
2516
    KB_ClearKeysDown();
2517
 
2518
    totalclock = ototalclock = 0;
2519
    limit = synctics;
2520
 
2521
    if (gs.MusicOn)
2522
    {
2523
        PlaySong(voc[DIGI_ENDLEV].name, 3, TRUE, TRUE);
2524
    }
2525
 
2526
    // special case code because I don't care any more!
2527
    if (FinishAnim)
2528
    {
7509 hendricks2 2529
        renderFlushPerms();
5196 hendricks2 2530
        rotatesprite(0, 0, RS_SCALE, 0, 5120, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2531
        rotatesprite(158<<16, 86<<16, RS_SCALE, 0, State->Pic, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
7509 hendricks2 2532
        videoNextPage();
5196 hendricks2 2533
        FadeIn(0,0);
2534
    }
2535
 
2536
    BonusDone = FALSE;
2537
    while (!BonusDone)
2538
    {
2539
        handleevents();
2540
 
2541
        // taken from top of faketimerhandler
2542
        if (totalclock < ototalclock + limit)
2543
        {
2544
            continue;
2545
        }
2546
        ototalclock += limit;
2547
 
2548
        CONTROL_GetUserInput(&uinfo);
2549
        CONTROL_ClearUserInput(&uinfo);
2550
        if (KEY_PRESSED(KEYSC_SPACE) || KEY_PRESSED(KEYSC_ENTER) || uinfo.button0 || uinfo.button1)
2551
        {
2552
            if (State >= s_BonusRest && State < &s_BonusRest[SIZ(s_BonusRest)])
2553
            {
2554
                State = s_BonusAnim[STD_RANDOM_RANGE(SIZ(s_BonusAnim))];
2555
                Tics = 0;
2556
            }
2557
        }
2558
 
2559
        gStateControl(&State, &Tics);
8310 hendricks2 2560
 
2561
        videoClearViewableArea(0L);
2562
 
5196 hendricks2 2563
        rotatesprite(0, 0, RS_SCALE, 0, 5120, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2564
 
2565
        if (UserMapName[0])
2566
        {
2567
            sprintf(ds,"%s",UserMapName);
2568
            MNU_MeasureString(ds, &w, &h);
2569
            MNU_DrawString(TEXT_TEST_COL(w), 20, ds,1,19);
2570
        }
2571
        else
2572
        {
2573
            if (PlayingLevel <= 1)
2574
                PlayingLevel = 1;
2575
            sprintf(ds,"%s",LevelInfo[PlayingLevel].Description);
2576
            MNU_MeasureString(ds, &w, &h);
2577
            MNU_DrawString(TEXT_TEST_COL(w), 20, ds,1,19);
2578
        }
2579
 
2580
        sprintf(ds,"Completed");
2581
        MNU_MeasureString(ds, &w, &h);
2582
        MNU_DrawString(TEXT_TEST_COL(w), 30, ds,1,19);
2583
 
2584
        rotatesprite(158<<16, 86<<16, RS_SCALE, 0, State->Pic, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2585
 
2586
#define BONUS_LINE(i) (50 + ((i)*20))
2587
 
2588
        line = 0;
2589
        second_tics = (PlayClock/120);
2590
        minutes = (second_tics/60);
2591
        seconds = (second_tics%60);
2592
        sprintf(ds,"Your Time:  %2d : %02d", minutes, seconds);
2593
        MNU_MeasureString(ds, &w, &h);
2594
        MNU_DrawString(60, BONUS_LINE(line), ds,1,16);
2595
 
2596
        if (!UserMapName[0])
2597
        {
2598
            line++;
2599
            sprintf(ds,"3D Realms Best Time:  %s", LevelInfo[PlayingLevel].BestTime);
2600
            MNU_MeasureString(ds, &w, &h);
2601
            MNU_DrawString(40, BONUS_LINE(line), ds,1,16);
2602
 
2603
            line++;
2604
            sprintf(ds,"Par Time:  %s", LevelInfo[PlayingLevel].ParTime);
2605
            MNU_MeasureString(ds, &w, &h);
2606
            MNU_DrawString(40, BONUS_LINE(line), ds,1,16);
2607
        }
2608
 
2609
 
2610
        // always read secrets and kills from the first player
2611
        line++;
2612
        sprintf(ds,"Secrets:  %d / %d", Player->SecretsFound, LevelSecrets);
2613
        MNU_MeasureString(ds, &w, &h);
2614
        MNU_DrawString(60, BONUS_LINE(line), ds,1,16);
2615
 
2616
        line++;
2617
        sprintf(ds,"Kills:  %d / %d", Player->Kills, TotalKillable);
2618
        MNU_MeasureString(ds, &w, &h);
2619
        MNU_DrawString(60, BONUS_LINE(line), ds,1,16);
2620
 
2621
 
2622
        sprintf(ds,"Press SPACE to continue");
2623
        MNU_MeasureString(ds, &w, &h);
2624
        MNU_DrawString(TEXT_TEST_COL(w), 185, ds,1,19);
2625
 
7509 hendricks2 2626
        videoNextPage();
5196 hendricks2 2627
        ScreenCaptureKeys();
2628
 
2629
        if (State == State->NextState)
2630
            BonusDone = TRUE;
2631
    }
2632
 
2633
    StopSound();
2634
    Terminate3DSounds();
2635
}
2636
 
5198 hendricks2 2637
void EndGameSequence(void)
5196 hendricks2 2638
{
5198 hendricks2 2639
    SWBOOL anim_ok = TRUE;
5196 hendricks2 2640
    FadeOut(0, 5);
2641
 
2642
    if ((gs.ParentalLock || Global_PLock) && FinishAnim == ANIM_SUMO)
2643
        anim_ok = FALSE;
2644
 
2645
    if (anim_ok)
2646
        playanm(FinishAnim);
2647
 
2648
    BonusScreen(Player + myconnectindex);
2649
 
2650
    ExitLevel = FALSE;
2651
    QuitFlag = FALSE;
2652
    AutoNet = FALSE;
2653
 
2654
    if (FinishAnim == ANIM_ZILLA)
2655
        CreditsLevel();
2656
 
2657
    ExitLevel = FALSE;
2658
    QuitFlag = FALSE;
2659
    AutoNet = FALSE;
2660
 
2661
    if (SW_SHAREWARE)
2662
    {
2663
        Level = 0;
2664
    }
2665
    else
2666
    {
2667
        if (Level == 4 || Level == 20)
2668
        {
2669
            Level=0;
2670
        }
2671
        else
2672
            Level++;
2673
    }
2674
}
2675
 
5198 hendricks2 2676
void
5196 hendricks2 2677
StatScreen(PLAYERp mpp)
2678
{
2679
    int minutes,seconds,second_tics;
5198 hendricks2 2680
    extern SWBOOL FinishedLevel;
5196 hendricks2 2681
    extern int PlayClock;
2682
    extern short LevelSecrets;
2683
    extern short TotalKillable;
2684
    short w,h;
2685
    int zero=0;
2686
    int handle=0;
2687
 
2688
    short rows,cols,i,j;
2689
    PLAYERp pp = NULL;
2690
    int x,y;
2691
    short death_total[MAX_SW_PLAYERS_REG];
2692
    short kills[MAX_SW_PLAYERS_REG];
2693
    short pal;
2694
 
2695
#define STAT_START_X 20
2696
#define STAT_START_Y 85
2697
#define STAT_OFF_Y 9
2698
#define STAT_HEADER_Y 14
2699
 
2700
#define SM_SIZ(num) ((num)*4)
2701
 
2702
#define STAT_TABLE_X (STAT_START_X + SM_SIZ(15))
2703
#define STAT_TABLE_XOFF SM_SIZ(6)
2704
 
2705
    // No stats in bot games
2706
    //if (BotMode) return;
2707
 
2708
    ResetPalette(mpp);
2709
    COVER_SetReverb(0); // Reset reverb
2710
    StopSound();
2711
 
2712
    if (FinishAnim)
2713
    {
2714
        EndGameSequence();
2715
        return;
2716
    }
2717
 
2718
    if (gNet.MultiGameType != MULTI_GAME_COMMBAT)
2719
    {
2720
        if (!FinishedLevel)
2721
            return;
2722
        BonusScreen(mpp);
2723
        return;
2724
    }
2725
 
7509 hendricks2 2726
    renderFlushPerms();
5196 hendricks2 2727
    DrawStatScreen();
2728
 
2729
    memset(death_total,0,sizeof(death_total));
2730
    memset(kills,0,sizeof(kills));
2731
 
2732
    sprintf(ds,"MULTIPLAYER TOTALS");
2733
    MNU_MeasureString(ds, &w, &h);
2734
    MNU_DrawString(TEXT_TEST_COL(w), 68, ds, 0, 0);
2735
 
2736
    sprintf(ds,"PRESS SPACE BAR TO CONTINUE");
2737
    MNU_MeasureString(ds, &w, &h);
2738
    MNU_DrawString(TEXT_TEST_COL(w), 189, ds, 0, 0);
2739
 
2740
    x = STAT_START_X;
2741
    y = STAT_START_Y;
2742
 
2743
    sprintf(ds,"  NAME         1     2     3     4     5     6     7    8     KILLS");
2744
    DisplayMiniBarSmString(mpp, x, y, 0, ds);
2745
    rows = OrigCommPlayers;
2746
    cols = OrigCommPlayers;
2747
    mpp = Player + myconnectindex;
2748
 
2749
    y += STAT_HEADER_Y;
2750
 
2751
    for (i = 0; i < rows; i++)
2752
    {
2753
        x = STAT_START_X;
2754
        pp = Player + i;
2755
 
2756
        sprintf(ds,"%d", i+1);
2757
        DisplayMiniBarSmString(mpp, x, y, 0, ds);
2758
 
2759
        sprintf(ds,"  %-13s", pp->PlayerName);
2760
        DisplayMiniBarSmString(mpp, x, y, User[pp->PlayerSprite]->spal, ds);
2761
 
2762
        x = STAT_TABLE_X;
2763
        for (j = 0; j < cols; j++)
2764
        {
2765
            pal = 0;
2766
            death_total[j] += pp->KilledPlayer[j];
2767
 
2768
            if (i == j)
2769
            {
2770
                // don't add kill for self or team player
2771
                pal = PALETTE_PLAYER0 + 4;
2772
                kills[i] -= pp->KilledPlayer[j];  // subtract self kills
2773
            }
2774
            else if (gNet.TeamPlay)
2775
            {
2776
                if (User[pp->PlayerSprite]->spal == User[Player[j].PlayerSprite]->spal)
2777
                {
2778
                    // don't add kill for self or team player
2779
                    pal = PALETTE_PLAYER0 + 4;
2780
                    kills[i] -= pp->KilledPlayer[j];  // subtract self kills
2781
                }
2782
                else
2783
                    kills[i] += pp->KilledPlayer[j];  // kills added here
2784
            }
2785
            else
2786
            {
2787
                kills[i] += pp->KilledPlayer[j];  // kills added here
2788
            }
2789
 
2790
            sprintf(ds,"%d", pp->KilledPlayer[j]);
2791
            DisplayMiniBarSmString(mpp, x, y, pal, ds);
2792
            x += STAT_TABLE_XOFF;
2793
        }
2794
 
2795
        y += STAT_OFF_Y;
2796
    }
2797
 
2798
 
2799
    // Deaths
2800
 
2801
    x = STAT_START_X;
2802
    y += STAT_OFF_Y;
2803
 
2804
    sprintf(ds,"   DEATHS");
2805
    DisplayMiniBarSmString(mpp, x, y, 0, ds);
2806
    x = STAT_TABLE_X;
2807
 
2808
    for (j = 0; j < cols; j++)
2809
    {
2810
        sprintf(ds,"%d",death_total[j]);
2811
        DisplayMiniBarSmString(mpp, x, y, 0, ds);
2812
        x += STAT_TABLE_XOFF;
2813
    }
2814
 
2815
    x = STAT_START_X;
2816
    y += STAT_OFF_Y;
2817
 
2818
    // Kills
2819
    x = STAT_TABLE_X + SM_SIZ(50);
2820
    y = STAT_START_Y + STAT_HEADER_Y;
2821
 
2822
    for (i = 0; i < rows; i++)
2823
    {
2824
        pp = Player + i;
2825
 
2826
        sprintf(ds,"%d", kills[i]); //pp->Kills);
2827
        DisplayMiniBarSmString(mpp, x, y, 0, ds);
2828
 
2829
        y += STAT_OFF_Y;
2830
    }
2831
 
7509 hendricks2 2832
    videoNextPage();
5196 hendricks2 2833
 
2834
    if (KeyPressed())
2835
    {
2836
        while (KeyPressed()) ;
2837
    }
2838
 
2839
    KEY_PRESSED(KEYSC_SPACE) = 0;
2840
    KEY_PRESSED(KEYSC_ENTER) = 0;
2841
 
2842
    if (gs.MusicOn)
2843
    {
2844
        PlaySong(voc[DIGI_ENDLEV].name, 3, TRUE, TRUE);
2845
    }
2846
 
2847
    while (!KEY_PRESSED(KEYSC_SPACE) && !KEY_PRESSED(KEYSC_ENTER))
2848
    {
2849
        handleevents();
2850
 
2851
        ScreenCaptureKeys();
2852
    }
2853
 
2854
    StopSound();
2855
    Terminate3DSounds();
2856
}
2857
 
5198 hendricks2 2858
void
2859
GameIntro(void)
5196 hendricks2 2860
{
2861
 
2862
    DSPRINTF(ds,"GameIntro...");
2863
    MONO_PRINT(ds);
2864
 
2865
    if (DemoPlaying)
2866
        return;
2867
 
2868
    // this could probably be taken out and you could select skill level
2869
    // from menu to start the game
2870
    if (!CommEnabled && UserMapName[0])
2871
        return;
2872
 
2873
    Level = 1;
2874
 
2875
 
2876
 
8271 hendricks2 2877
    PlayTheme();
5196 hendricks2 2878
 
2879
    if (!AutoNet)
2880
    {
2881
        LogoLevel();
2882
        //CreditsLevel();
2883
        //SceneLevel();
2884
        //TitleLevel();
2885
        IntroAnimLevel();
2886
        IntroAnimCount = 0;
2887
    }
2888
 
2889
    MenuLevel();
2890
}
2891
 
5198 hendricks2 2892
void
5552 hendricks2 2893
Control(int32_t argc, char const * const * argv)
5196 hendricks2 2894
{
2895
 
5206 hendricks2 2896
    InitGame(argc, argv);
5196 hendricks2 2897
 
2898
    MONO_PRINT("InitGame done");
2899
    MNU_InitMenus();
2900
    InGame = TRUE;
2901
    GameIntro();
2902
    //NewGame = TRUE;
2903
 
2904
    while (!QuitFlag)
2905
    {
2906
        handleevents();
2907
        OSD_DispatchQueued();
2908
 
2909
        if (quitevent) QuitFlag = TRUE;
2910
 
2911
        NewLevel();
2912
    }
2913
 
2914
    CleanExit = TRUE;
2915
    TerminateGame();
2916
}
2917
 
2918
 
2919
void
7499 hendricks2 2920
_Assert(const char *expr, const char *strFile, unsigned uLine)
5196 hendricks2 2921
{
8335 hendricks2 2922
    buildprintf(ds, "Assertion failed: %s %s, line %u", expr, strFile, uLine);
2923
    debug_break();
2924
 
5196 hendricks2 2925
    TerminateGame();
8335 hendricks2 2926
 
5196 hendricks2 2927
#if 1 //def RENDERTYPEWIN
7553 hendricks2 2928
    wm_msgbox(apptitle, "%s", ds);
5196 hendricks2 2929
#else
2930
    printf("Assertion failed: %s\n %s, line %u\n", expr, strFile, uLine);
2931
#endif
2932
    exit(0);
2933
}
2934
 
2935
 
2936
void
7499 hendricks2 2937
_ErrMsg(const char *strFile, unsigned uLine, const char *format, ...)
5196 hendricks2 2938
{
2939
    va_list arglist;
2940
 
2941
    //DSPRINTF(ds, "Error: %s, line %u", strFile, uLine);
2942
    //MONO_PRINT(ds);
2943
    TerminateGame();
2944
 
2945
#if 1 //def RENDERTYPEWIN
2946
    {
2947
        char msg[256], *p;
2948
        Bsnprintf(msg, sizeof(msg), "Error: %s, line %u\n", strFile, uLine);
2949
        p = &msg[strlen(msg)];
2950
        va_start(arglist, format);
2951
        Bvsnprintf(msg, sizeof(msg) - (p-msg), format, arglist);
2952
        va_end(arglist);
7553 hendricks2 2953
        wm_msgbox(apptitle, "%s", msg);
5196 hendricks2 2954
    }
2955
#else
2956
    printf("Error: %s, line %u\n", strFile, uLine);
2957
 
2958
    va_start(arglist, format);
2959
    vprintf(format, arglist);
2960
    va_end(arglist);
2961
#endif
2962
 
2963
    exit(0);
2964
}
2965
 
2966
void
2967
dsprintf(char *str, char *format, ...)
2968
{
2969
    va_list arglist;
2970
 
2971
    va_start(arglist, format);
2972
    vsprintf(str, format, arglist);
2973
    va_end(arglist);
2974
}
2975
 
2976
void
7499 hendricks2 2977
dsprintf_null(char *str, const char *format, ...)
5196 hendricks2 2978
{
2979
    va_list arglist;
2980
}
2981
 
2982
void MoveLoop(void)
2983
{
2984
    int pnum;
2985
 
2986
    getpackets();
2987
 
2988
    if (PredictionOn && CommEnabled)
2989
    {
2990
        while (predictmovefifoplc < Player[myconnectindex].movefifoend)
2991
        {
2992
            DoPrediction(ppp);
2993
        }
2994
    }
2995
 
2996
    //While you have new input packets to process...
2997
    if (!CommEnabled)
2998
        bufferjitter = 0;
2999
 
3000
    while (Player[myconnectindex].movefifoend - movefifoplc > bufferjitter)
3001
    {
3002
        //Make sure you have at least 1 packet from everyone else
3003
        for (pnum=connecthead; pnum>=0; pnum=connectpoint2[pnum])
3004
        {
3005
            if (movefifoplc == Player[pnum].movefifoend)
3006
            {
3007
                break;
3008
            }
3009
        }
3010
 
3011
        //Pnum is >= 0 only if last loop was broken, meaning a player wasn't caught up
3012
        if (pnum >= 0)
3013
            break;
3014
 
3015
        domovethings();
3016
 
3017
#if DEBUG
3018
        //if (DemoSyncRecord)
3019
        //    demosync_record();
3020
#endif
3021
    }
3022
 
3023
    if (!InputMode && !PauseKeySet)
3024
        MNU_CheckForMenus();
3025
}
3026
 
3027
 
3028
void InitPlayerGameSettings(void)
3029
{
3030
    int pnum;
3031
 
3032
    // don't jack with auto aim settings if DemoMode is going
3033
    // what the hell did I do this for?????????
3034
    //if (DemoMode)
3035
    //    return;
3036
 
3037
    if (CommEnabled)
3038
    {
3039
        // everyone gets the same Auto Aim
3040
        TRAVERSE_CONNECT(pnum)
3041
        {
3042
            if (gNet.AutoAim)
3043
                SET(Player[pnum].Flags, PF_AUTO_AIM);
3044
            else
3045
                RESET(Player[pnum].Flags, PF_AUTO_AIM);
3046
        }
3047
    }
3048
    else
3049
    {
3050
        if (gs.AutoAim)
3051
            SET(Player[myconnectindex].Flags, PF_AUTO_AIM);
3052
        else
3053
            RESET(Player[myconnectindex].Flags, PF_AUTO_AIM);
3054
    }
3055
 
3056
    // everyone had their own Auto Run
3057
    if (gs.AutoRun)
3058
        SET(Player[myconnectindex].Flags, PF_LOCK_RUN);
3059
    else
3060
        RESET(Player[myconnectindex].Flags, PF_LOCK_RUN);
3061
 
3062
    if (gs.MouseAimingOn)
3063
        SET(Player[myconnectindex].Flags, PF_MOUSE_AIMING_ON);
3064
    else
3065
        RESET(Player[myconnectindex].Flags, PF_MOUSE_AIMING_ON);
3066
}
3067
 
3068
 
5198 hendricks2 3069
void InitRunLevel(void)
5196 hendricks2 3070
{
3071
    int i;
3072
    if (DemoEdit)
3073
        return;
3074
 
3075
    if (LoadGameOutsideMoveLoop)
3076
    {
3077
        int SavePlayClock;
3078
        extern int PlayClock;
3079
        LoadGameOutsideMoveLoop = FALSE;
3080
        // contains what is needed from calls below
3081
        if (gs.Ambient)
3082
            StartAmbientSound();
3083
        SetCrosshair();
3084
        PlaySong(LevelSong, -1, TRUE, TRUE);
3085
        SetRedrawScreen(Player + myconnectindex);
3086
        // crappy little hack to prevent play clock from being overwritten
3087
        // for load games
3088
        SavePlayClock = PlayClock;
3089
        InitTimingVars();
3090
        PlayClock = SavePlayClock;
3091
        MONO_PRINT("Done with InitRunLevel");
3092
        return;
3093
    }
3094
 
3095
#if 0
3096
    // ensure we are through the initialization code before sending the game
3097
    // version. Otherwise, it is possible to send this too early and have it
3098
    // blown away on the other side.
3099
    waitforeverybody();
3100
#endif
3101
 
3102
    SendVersion(GameVersion);
3103
 
3104
    waitforeverybody();
3105
 
3106
    StopSong();
3107
 
3108
    if (Bstrcasecmp(CacheLastLevel, LevelName) != 0)
3109
        DoTheCache();
3110
 
3111
    // auto aim / auto run / etc
3112
    InitPlayerGameSettings();
3113
 
3114
    // send packets with player info
3115
    InitNetPlayerOptions();
3116
 
3117
    // Initialize Game part of network code (When ready2send != 0)
3118
    InitNetVars();
3119
 
3120
    {
3121
        int track;
3122
        if (Level == 0)
3123
        {
3124
            track = RedBookSong[4+RANDOM_RANGE(10)];
3125
        }
3126
        else
3127
        {
3128
            track = RedBookSong[Level];
3129
        }
3130
        PlaySong(LevelSong, track, TRUE, TRUE);
3131
    }
3132
 
3133
    InitPrediction(&Player[myconnectindex]);
3134
 
3135
    if (!DemoInitOnce)
3136
        DemoRecordSetup();
3137
 
3138
    // everything has been inited at least once for RECORD
3139
    DemoInitOnce = TRUE;
3140
 
3141
//DebugWriteLoc(__FILE__, __LINE__);
3142
    waitforeverybody();
3143
 
3144
    CheckVersion(GameVersion);
3145
 
3146
    // IMPORTANT - MUST be right before game loop AFTER waitforeverybody
3147
    InitTimingVars();
3148
 
3149
    SetRedrawScreen(Player + myconnectindex);
3150
 
3151
    FX_SetVolume(gs.SoundVolume); // Turn volume back up
3152
    if (gs.Ambient)
3153
        StartAmbientSound();
3154
}
3155
 
5198 hendricks2 3156
void
3157
RunLevel(void)
5196 hendricks2 3158
{
3159
    int i;
3160
    InitRunLevel();
3161
 
3162
    FX_SetVolume(gs.SoundVolume);
3163
    SetSongVolume(gs.MusicVolume);
3164
 
3165
#if 0
3166
    waitforeverybody();
3167
#endif
3168
    ready2send = 1;
3169
 
3170
    while (TRUE)
3171
    {
3172
        handleevents();
3173
        OSD_DispatchQueued();
3174
 
3175
        if (quitevent) QuitFlag