Subversion Repositories eduke32

Rev

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

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