Subversion Repositories eduke32

Rev

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