Subversion Repositories eduke32

Rev

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

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