Subversion Repositories eduke32

Rev

Rev 8781 | 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));
8797 ny00123 728
        for (i = 0; i < ARRAY_SSIZE(DemoName); i++)
5196 hendricks2 729
        {
730
            if (fscanf(fin, "%s", DemoName[i]) == EOF)
731
                break;
732
        }
8797 ny00123 733
        if (i == ARRAY_SSIZE(DemoName))
734
            initputs("WARNING: demos.run is too long, ignoring remaining files\n");
5196 hendricks2 735
 
736
        fclose(fin);
737
    }
738
 
739
    memset(DemoText,'\0',sizeof(DemoText));
740
    fin = fopen("demotxt.run","r");
741
    if (fin)
742
    {
743
        fgets(ds, 6, fin);
744
        sscanf(ds,"%d",&DemoTextYstart);
8797 ny00123 745
        for (i = 0; i < ARRAY_SSIZE(DemoText); i++)
5196 hendricks2 746
        {
747
            if (fgets(DemoText[i], SIZ(DemoText[0])-1, fin) == NULL)
748
                break;
749
        }
8797 ny00123 750
        if (i == ARRAY_SSIZE(DemoText))
751
            initputs("WARNING: demotxt.run is too long, trimming the text\n");
5196 hendricks2 752
 
753
        fclose(fin);
754
    }
755
}
756
 
757
void DisplayDemoText(void)
758
{
759
    short w,h;
760
    short i;
761
 
762
    for (i = 0; i < 3; i++)
763
    {
764
        MNU_MeasureString(DemoText[i], &w, &h);
765
        PutStringTimer(Player, TEXT_TEST_COL(w), DemoTextYstart+(i*12), DemoText[i], 999);
766
    }
767
}
768
 
769
 
770
void Set_GameMode(void)
771
{
772
    int result;
773
 
8591 hendricks2 774
    //DSPRINTF(ds,"ScreenMode %d, ScreenWidth %d, ScreenHeight %d", ud_setup.ScreenMode, ud_setup.ScreenWidth, ud_setup.ScreenHeight);
5196 hendricks2 775
    //MONO_PRINT(ds);
8591 hendricks2 776
    result = COVERsetgamemode(ud_setup.ScreenMode, ud_setup.ScreenWidth, ud_setup.ScreenHeight, ud_setup.ScreenBPP);
5196 hendricks2 777
 
778
    if (result < 0)
779
    {
780
        buildprintf("Failure setting video mode %dx%dx%d %s! Attempting safer mode...",
8591 hendricks2 781
                    ud_setup.ScreenWidth,ud_setup.ScreenHeight,ud_setup.ScreenBPP,
782
                    ud_setup.ScreenMode ? "fullscreen" : "windowed");
783
        ud_setup.ScreenMode = 0;
784
        ud_setup.ScreenWidth = 640;
785
        ud_setup.ScreenHeight = 480;
786
        ud_setup.ScreenBPP = 8;
5196 hendricks2 787
 
8591 hendricks2 788
        result = COVERsetgamemode(ud_setup.ScreenMode, ud_setup.ScreenWidth, ud_setup.ScreenHeight, ud_setup.ScreenBPP);
5196 hendricks2 789
        if (result < 0)
790
        {
791
            uninitmultiplayers();
792
            //uninitkeys();
793
            KB_Shutdown();
794
            TermSetup();
795
            UnInitSound();
7509 hendricks2 796
            timerUninit();
5196 hendricks2 797
            DosScreen();
798
            uninitgroupfile();
799
            exit(0);
800
        }
801
    }
802
}
803
 
804
void MultiSharewareCheck(void)
805
{
806
    if (!SW_SHAREWARE) return;
807
    if (numplayers > 4)
808
    {
8482 hendricks2 809
#if 1 /* defined RENDERTYPEWIN */
5196 hendricks2 810
        wm_msgbox(apptitle,"To play a Network game with more than 4 players you must purchase "
811
                  "the full version.  Read the Ordering Info screens for details.");
812
#else
813
        printf(
814
            "\n\nTo play a Network game with more than 4 players you must purchase the\n"
815
            "full version.  Read the Ordering Info screens for details.\n\n");
816
#endif
817
        uninitmultiplayers();
818
        //uninitkeys();
819
        KB_Shutdown();
820
        TermSetup();
821
        UnInitSound();
7509 hendricks2 822
        timerUninit();
8270 hendricks2 823
        engineUnInit();
8330 hendricks2 824
        FreeGroups();
5196 hendricks2 825
        uninitgroupfile();
826
        exit(0);
827
    }
828
}
829
 
830
 
831
// Some mem crap for Jim
832
// I reserve 1 meg of heap space for our use out side the cache
833
int TotalMemory = 0;
834
int ActualHeap = 0;
835
 
5198 hendricks2 836
void InitAutoNet(void)
5196 hendricks2 837
{
838
    if (!AutoNet)
839
        return;
840
 
841
    gs.NetGameType      = Auto.Rules;
842
    gs.NetLevel         = Auto.Level;
843
    gs.NetMonsters      = Auto.Enemy;
844
    gs.NetSpawnMarkers  = Auto.Markers;
845
    gs.NetTeamPlay      = Auto.Team;
846
    gs.NetHurtTeammate  = Auto.HurtTeam;
847
    gs.NetKillLimit     = Auto.Kill;
848
    gs.NetTimeLimit     = Auto.Time;
849
    gs.NetColor         = Auto.Color;
850
    gs.NetNuke          = Auto.Nuke;
851
}
852
 
853
 
854
void AnimateCacheCursor(void)
855
{
856
#if 0
857
    struct rccoord old_pos;
858
    static short cursor_num = 0;
859
    static char cache_cursor[] =  {'|','/','-','\\'};
860
 
861
    if (GraphicsMode)
862
        return;
863
 
864
    cursor_num++;
865
    if (cursor_num > 3)
866
        cursor_num = 0;
867
 
868
    //old_pos = _gettextposition();
869
    //_settextposition( old_pos.row, old_pos.col );
870
    //_settextposition( 24,  25);
871
    _settextposition(25,  0);
872
    sprintf(ds,"Loading sound and graphics %c", cache_cursor[cursor_num]);
873
    _outtext(ds);
874
    //_settextposition( old_pos.row, old_pos.col );
875
#endif
876
}
877
 
878
void COVERsetbrightness(int bright, unsigned char *pal)
879
{
8272 hendricks2 880
    paletteSetColorTable(BASEPAL, pal);
881
    videoSetPalette(bright, BASEPAL, 0);
5196 hendricks2 882
}
883
 
884
 
885
static int firstnet = 0;    // JBF
886
 
887
extern int startwin_run(void);
888
 
5345 hendricks2 889
static void SW_FatalEngineError(void)
890
{
891
    wm_msgbox("Build Engine Initialisation Error",
892
              "There was a problem initialising the Build engine: %s", engineerrstr);
893
    exit(1);
894
}
895
 
5198 hendricks2 896
void
5552 hendricks2 897
InitGame(int32_t argc, char const * const * argv)
5196 hendricks2 898
{
899
    extern int MovesPerPacket;
900
    //void *ReserveMem=NULL;
901
    int i;
902
 
903
    DSPRINTF(ds,"InitGame...");
904
    MONO_PRINT(ds);
905
 
7509 hendricks2 906
    if (engineInit())
5345 hendricks2 907
        SW_FatalEngineError();
5196 hendricks2 908
 
8333 hendricks2 909
    {
910
        char tempbuf[256];
911
        snprintf(tempbuf, ARRAY_SIZE(tempbuf), APPNAME " %s", s_buildRev);
912
        OSD_SetVersion(tempbuf, 10,0);
913
    }
914
    OSD_SetParameters(0, 0, 0, 4, 2, 4, "^14", "^14", 0);
915
 
5196 hendricks2 916
    InitSetup();
917
 
918
    InitAutoNet();
919
 
7509 hendricks2 920
    timerInit(120);
5196 hendricks2 921
 
922
    CON_InitConsole();  // Init console command list
923
 
924
    ////DSPRINTF(ds,"%s, %d",__FILE__,__LINE__);   MONO_PRINT(ds);
925
 
926
    //InitFX();
927
 
928
    memcpy(palette_data,palette,768);
929
    InitPalette();
930
    // sets numplayers, connecthead, connectpoint2, myconnectindex
931
 
932
    if (!firstnet)
8667 ny00123 933
        initsingleplayers();
5206 hendricks2 934
    else if (initmultiplayersparms(argc - firstnet, &argv[firstnet]))
5196 hendricks2 935
    {
8743 ny00123 936
        NetBroadcastMode = (networkmode == MMULTI_MODE_P2P);
5196 hendricks2 937
        buildputs("Waiting for players...\n");
938
        while (initmultiplayerscycle())
939
        {
940
            handleevents();
941
            if (quitevent)
942
            {
943
                QuitFlag = TRUE;
944
                return;
945
            }
946
        }
947
    }
948
    initsynccrc();
949
 
950
    // code to duplicate packets
951
    if (numplayers > 4 && MovesPerPacket == 1)
952
    {
953
        MovesPerPacket = 2;
954
    }
955
 
956
    MultiSharewareCheck();
957
 
958
    if (numplayers > 1)
959
    {
960
        CommPlayers = numplayers;
961
        OrigCommPlayers = CommPlayers;
962
        CommEnabled = TRUE;
963
        if (!BotMode)
964
            gNet.MultiGameType = MULTI_GAME_COMMBAT;
965
        else
966
            gNet.MultiGameType = MULTI_GAME_AI_BOTS;
967
 
968
#if 0 //def NET_MODE_MASTER_SLAVE
969
        if (!NetModeOverride)
970
        {
971
            if (numplayers <= 4)
972
                NetBroadcastMode = TRUE;
973
            else
974
                NetBroadcastMode = FALSE;
975
        }
976
#endif
977
    }
978
 
979
    LoadDemoRun();
980
    // Save off total heap for later calculations
981
    //TotalMemory = Z_AvailHeap();
982
    //DSPRINTF(ds,"Available Heap before LoadImages =  %d", TotalMemory);
983
    //MONO_PRINT(ds);
984
    // Reserve 1.5 megs for normal program use
985
    // Generally, SW is consuming about a total of 11 megs including
986
    // all the cached in graphics, etc. per level, so even on a 16 meg
987
    // system, reserving 1.5 megs is fine.
988
    // Note that on a 16 meg machine, Ken was leaving us about
989
    // 24k for use outside the cache!  This was causing out of mem problems
990
    // when songs, etc., greater than the remaining heap were being loaded.
991
    // Even if you pre-cache songs, etc. to help, reserving some heap is
992
    // a very smart idea since the game uses malloc throughout execution.
993
    //ReserveMem = AllocMem(1L<<20);
994
    //if(ReserveMem == 0) MONO_PRINT("Could not allocate 1.5 meg reserve!");
995
 
996
    // LoadImages will now proceed to steal all the remaining heap space
997
    //_outtext("\n\n\n\n\n\n\n\n");
8328 hendricks2 998
    //buildputs("Loading sound and graphics...\n");
5196 hendricks2 999
    //AnimateCacheCursor();
1000
    LoadImages("tiles000.art");
1001
 
1002
    // Now free it up for later use
1003
    /*
1004
    if(ReserveMem)
1005
        {
1006
        // Recalc TotalMemory for later reference
1007
        ActualHeap = Z_AvailHeap() + 1536000L;
1008
        FreeMem(ReserveMem);
1009
        }
1010
    */
1011
 
1012
    Connect();
1013
    SortBreakInfo();
1014
    parallaxtype = 1;
5211 hendricks2 1015
    SW_InitMultiPsky();
5196 hendricks2 1016
 
1017
    memset(Track, 0, sizeof(Track));
1018
 
1019
    memset(Player, 0, sizeof(Player));
1020
    for (i = 0; i < MAX_SW_PLAYERS; i++)
1021
        INITLIST(&Player[i].PanelSpriteList);
1022
 
1023
    LoadKVXFromScript("swvoxfil.txt");    // Load voxels from script file
1024
    LoadPLockFromScript("swplock.txt");   // Get Parental Lock setup info
1025
    if (!SW_SHAREWARE)
1026
        LoadCustomInfoFromScript("swcustom.txt");   // Load user customisation information
1027
 
5217 hendricks2 1028
    if (!loaddefinitionsfile(G_DefFile())) buildputs("Definitions file loaded.\n");
5196 hendricks2 1029
 
6673 hendricks2 1030
    for (char * m : g_defModules)
8515 hendricks2 1031
        Xfree(m);
6673 hendricks2 1032
    g_defModules.clear();
5217 hendricks2 1033
 
7509 hendricks2 1034
    if (enginePostInit())
5345 hendricks2 1035
        SW_FatalEngineError();
1036
 
8469 hendricks2 1037
    palettePostLoadLookups();
1038
 
5196 hendricks2 1039
    DemoModeMenuInit = TRUE;
1040
    // precache as much stuff as you can
1041
    if (UserMapName[0] == '\0')
1042
    {
1043
        AnimateCacheCursor();
1044
        LoadLevel("$dozer.map");
1045
        AnimateCacheCursor();
1046
        SetupPreCache();
1047
        DoTheCache();
1048
    }
1049
    else
1050
    {
1051
        AnimateCacheCursor();
1052
        LoadLevel(UserMapName);
1053
        AnimateCacheCursor();
1054
        SetupPreCache();
1055
        DoTheCache();
1056
    }
1057
 
1058
    Set_GameMode();
1059
    GraphicsMode = TRUE;
1060
    SetupAspectRatio();
1061
 
1062
    COVERsetbrightness(gs.Brightness,&palette_data[0][0]);
1063
 
1064
    InitFX();   // JBF: do it down here so we get a hold of the window handle
1065
    InitMusic();
1066
 
8708 terminx 1067
    enginecompatibilitymode = ENGINE_19961112; // SW 1.0: 19970212, SW 1.1-1.2: 19970522
5196 hendricks2 1068
}
1069
 
1070
 
1071
/*
1072
Directory of C:\DEV\SW\MIDI
1073
EXECUT11 MID
1074
HROSHMA6 MID
1075
HOSHIA02 MID
1076
INTRO131 MID
1077
KOTEC2   MID
1078
KOTOKI12 MID
1079
NIPPON34 MID
1080
NOKI41   MID
1081
SANAI    MID
1082
SIANRA23 MID
1083
TKYO2007 MID
1084
TYTAIK16 MID
1085
YOKOHA03 MID
1086
*/
1087
 
1088
char LevelSong[16];
1089
short SongLevelNum;
1090
//#ifndef SW_SHAREWARE
1091
LEVEL_INFO LevelInfo[MAX_LEVELS_REG+2] =
1092
{
1093
    {"title.map",      "theme.mid", " ", " ", " "  },
1094
    {"$bullet.map",    "e1l01.mid", "Seppuku Station", "0 : 55", "5 : 00"  },
1095
    {"$dozer.map",     "e1l03.mid", "Zilla Construction", "4 : 59", "8 : 00"  },
1096
    {"$shrine.map",    "e1l02.mid", "Master Leep's Temple", "3 : 16", "10 : 00"  },
1097
    {"$woods.map",     "e1l04.mid", "Dark Woods of the Serpent", "7 : 06", "16 : 00"  },
1098
    {"$whirl.map",     "yokoha03.mid", "Rising Son", "5 : 30", "10 : 00"   },
1099
    {"$tank.map",      "nippon34.mid", "Killing Fields", "1 : 46", "4 : 00"   },
1100
    {"$boat.map",      "execut11.mid", "Hara-Kiri Harbor", "1 : 56", "4 : 00"   },
1101
    {"$garden.map",    "execut11.mid", "Zilla's Villa", "1 : 06", "2 : 00"   },
1102
    {"$outpost.map",   "sanai.mid",    "Monastery", "1 : 23", "3 : 00"      },
1103
    {"$hidtemp.map",   "kotec2.mid",   "Raider of the Lost Wang", "2 : 05", "4 : 10"     },
1104
    {"$plax1.map",     "kotec2.mid",   "Sumo Sky Palace", "6 : 32", "12 : 00"     },
1105
    {"$bath.map",      "yokoha03.mid", "Bath House", "10 : 00", "10 : 00"   },
1106
    {"$airport.map",   "nippon34.mid", "Unfriendly Skies", "2 : 59", "6 : 00"   },
1107
    {"$refiner.map",   "kotoki12.mid", "Crude Oil", "2 : 40", "5 : 00"   },
1108
    {"$newmine.map",   "hoshia02.mid", "Coolie Mines", "2 : 48", "6 : 00"   },
1109
    {"$subbase.map",   "hoshia02.mid", "Subpen 7", "2 : 02", "4 : 00"   },
1110
    {"$rock.map",      "kotoki12.mid", "The Great Escape", "3 : 18", "6 : 00"   },
1111
    {"$yamato.map",    "sanai.mid",    "Floating Fortress", "11 : 38", "20 : 00"      },
1112
    {"$seabase.map",   "kotec2.mid",   "Water Torture", "5 : 07", "10 : 00"     },
1113
    {"$volcano.map",   "kotec2.mid",   "Stone Rain", "9 : 15", "20 : 00"     },
1114
    {"$shore.map",     "kotec2.mid",   "Shanghai Shipwreck", "3 : 58", "8 : 00"     },
1115
    {"$auto.map",      "kotec2.mid",   "Auto Maul", "4 : 07", "8 : 00"     },
1116
    {"tank.map",       "kotec2.mid",   "Heavy Metal (DM only)", "10 : 00", "10 : 00"     },
1117
    {"$dmwoods.map",   "kotec2.mid",   "Ripper Valley (DM only)", "10 : 00", "10 : 00"     },
1118
    {"$dmshrin.map",   "kotec2.mid",   "House of Wang (DM only)", "10 : 00", "10 : 00"     },
1119
    {"$rush.map",      "kotec2.mid",   "Lo Wang Rally (DM only)", "10 : 00", "10 : 00"     },
1120
    {"shotgun.map",    "kotec2.mid",   "Ruins of the Ronin (CTF)", "10 : 00", "10 : 00"     },
1121
    {"$dmdrop.map",    "kotec2.mid",   "Killing Fields (CTF)", "10 : 00", "10 : 00"     },
1122
    {NULL, NULL, NULL, NULL, NULL}
1123
};
1124
/*#else
1125
LEVEL_INFO LevelInfo[MAX_LEVELS+2] =  // Shareware
1126
    {
1127
    {"title.map",      "theme.mid", " ", " ", " "  },
1128
    {"$bullet.map",    "e1l01.mid", "Seppuku Station", "0 : 55", "5 : 00"  },
1129
    {"$dozer.map",     "e1l03.mid", "Zilla Construction", "4 : 59", "8 : 00"  },
1130
    {"$shrine.map",    "e1l02.mid", "Master Leep's Temple", "3 : 16", "10 : 00"  },
1131
    {"$woods.map",     "e1l04.mid", "Dark Woods of the Serpent", "7 : 06", "16 : 00"  },
1132
    {NULL, NULL, NULL, NULL, NULL}
1133
    };
1134
#endif*/
1135
 
8510 hendricks2 1136
struct LevelNamePatch
1137
{
1138
    uint8_t index;
1139
    char const * name;
1140
};
1141
// names hex-edited into the exe
1142
static LevelNamePatch const LevelNamesWD[] =
1143
{
1144
    { 5, "Chinatown" },
1145
    { 6, "Monastery" }, // "Monastary"
1146
    { 7, "Trolley Yard" }, // "Trolly Yard"
1147
    { 8, "Restaurant" }, // "Resturant"
1148
    { 9, "Skyscraper" },
1149
    { 10, "Airplane" },
1150
    { 11, "Military Base" },
1151
    { 12, "Train" },
1152
    { 13, "Auto Factory" },
1153
    { 20, "Skyline" },
1154
    { 21, "Redwood Forest" },
1155
    { 22, "The Docks" },
1156
    { 23, "Waterfight (DM only)" },
1157
    { 24, "Wanton DM 1 (DM only)" },
1158
    { 25, "Wanton DM 2 (DM only)" },
1159
    { 27, "Wanton CTF (CTF)" },
1160
};
1161
#if 0
1162
// truncated names hex-edited into the exe
1163
static LevelNamePatch const LevelNamesTD[] =
1164
{
1165
    { 5, "Wang's Home" },
1166
    { 6, "City of Despair" }, // "City Of Despair"
1167
    { 7, "Emergency Room" },
1168
    { 8, "Hide and Seek" }, // "Hide And Seek"
1169
    { 9, "Warehouse" },
1170
    { 10, "Military Research Base" },
1171
    { 11, "Toxic Waste" },
1172
    { 12, "Crazy Train" },
1173
    { 13, "Fishing Village" },
1174
    { 14, "The Garden" },
1175
    { 15, "The Fortress" },
1176
    { 20, "The Palace" },
1177
    { 21, "Prison Camp" },
1178
    { 23, "Ninja Training Camp (DM only)" }, // "Ninja Training Camp"
1179
    { 24, "Death Becomes You (DM only)" }, // "Death Becomes You"
1180
    { 25, "Island Caves (DM only)" }, // "Island Caves"
1181
};
1182
#else
1183
// names from the readme
1184
static LevelNamePatch const LevelNamesTD[] =
1185
{
1186
    { 5, "Home Sweet Home" },
1187
    { 6, "City of Despair" },
1188
    { 7, "Emergency Room" },
1189
    { 8, "Hide and Seek" },
1190
    { 9, "Warehouse Madness" },
1191
    { 10, "Weapons Research Center" },
1192
    { 11, "Toxic Waste Facility" },
1193
    { 12, "Silver Bullet" },
1194
    { 13, "Fishing Village" },
1195
    { 14, "Secret Garden" },
1196
    { 15, "Hung Lo's Fortress" },
1197
    { 20, "Hung Lo's Palace" },
1198
    { 21, "Prison Camp" }, // "Prison Camp (secret level)"
1199
    { 23, "Ninja Training Camp (DM only)" }, // "Ninja Training Camp (dm)"
1200
    { 24, "The Morgue/Mortuary (DM only)" }, // "The Morgue/mortuary (dm)"
1201
    { 25, "Island Caves (DM only)" }, // "Island Caves (dm)"
1202
};
1203
#endif
1204
 
5196 hendricks2 1205
char EpisodeNames[2][MAX_EPISODE_NAME_LEN+2] =
1206
{
1207
    "^Enter the Wang",
1208
    "^Code of Honor"
1209
};
8510 hendricks2 1210
static char const s_EpisodeNameWD[] = "^Wanton Destruction"; // "^Wanton Destr"
1211
static char const s_EpisodeNameTD[] = "^Twin Dragon";
5196 hendricks2 1212
char EpisodeSubtitles[2][MAX_EPISODE_SUBTITLE_LEN+1] =
1213
{
1214
    "Four levels (Shareware Version)",
1215
    "Eighteen levels (Full Version Only)"
1216
};
8510 hendricks2 1217
static char const s_EpisodeSubtitleWD[] = "Twelve levels (Full Version Only)";
1218
static char const s_EpisodeSubtitleTD[] = "Thirteen levels (Full Version Only)";
5196 hendricks2 1219
char SkillNames[4][MAX_SKILL_NAME_LEN+2] =
1220
{
8510 hendricks2 1221
    "^Tiny Grasshopper", // "^Tiny grasshopper"
5196 hendricks2 1222
    "^I Have No Fear",
1223
    "^Who Wants Wang",
1224
    "^No Pain, No Gain"
1225
};
1226
 
5198 hendricks2 1227
void InitNewGame(void)
5196 hendricks2 1228
{
1229
    int i, ready_bak;
1230
    int ver_bak;
1231
 
1232
    //waitforeverybody();           // since ready flag resets after this point, need to carefully sync
1233
 
1234
    for (i = 0; i < MAX_SW_PLAYERS; i++)
1235
    {
1236
        // don't jack with the playerreadyflag
1237
        ready_bak = Player[i].playerreadyflag;
1238
        ver_bak = Player[i].PlayerVersion;
1239
        memset(&Player[i], 0, sizeof(Player[i]));
1240
        Player[i].playerreadyflag = ready_bak;
1241
        Player[i].PlayerVersion = ver_bak;
1242
        INITLIST(&Player[i].PanelSpriteList);
1243
    }
1244
 
1245
    memset(puser, 0, sizeof(puser));
1246
}
1247
 
1248
void FindLevelInfo(char *map_name, short *level)
1249
{
8685 ny00123 1250
    short j;
5196 hendricks2 1251
 
1252
    for (j = 1; j <= MAX_LEVELS; j++)
1253
    {
1254
        if (LevelInfo[j].LevelName)
1255
        {
1256
            if (Bstrcasecmp(map_name, LevelInfo[j].LevelName) == 0)
1257
            {
1258
                *level = j;
1259
                return;
1260
            }
1261
        }
1262
    }
1263
 
1264
    *level = 0;
1265
    return;
1266
}
1267
 
1268
int ChopTics;
5198 hendricks2 1269
void InitLevelGlobals(void)
5196 hendricks2 1270
{
1271
    extern char PlayerGravity;
1272
    extern short wait_active_check_offset;
1273
    //extern short Zombies;
1274
    extern int PlaxCeilGlobZadjust, PlaxFloorGlobZadjust;
5198 hendricks2 1275
    extern SWBOOL left_foot;
1276
    extern SWBOOL serpwasseen;
1277
    extern SWBOOL sumowasseen;
1278
    extern SWBOOL zillawasseen;
5196 hendricks2 1279
    extern short BossSpriteNum[3];
1280
 
1281
    // A few IMPORTANT GLOBAL RESETS
1282
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1
1283
    MapSetup();
1284
    //Zombies = 0;
1285
    ChopTics = 0;
1286
    dimensionmode = 3;
1287
    zoom = 768;
1288
    PlayerGravity = 24;
1289
    wait_active_check_offset = 0;
1290
    PlaxCeilGlobZadjust = PlaxFloorGlobZadjust = Z(500);
1291
    FinishedLevel = FALSE;
1292
    AnimCnt = 0;
1293
    left_foot = FALSE;
1294
    screenpeek = myconnectindex;
1295
 
1296
    gNet.TimeLimitClock = gNet.TimeLimit;
1297
 
1298
    serpwasseen = FALSE;
1299
    sumowasseen = FALSE;
1300
    zillawasseen = FALSE;
1301
    memset(BossSpriteNum,-1,sizeof(BossSpriteNum));
1302
}
1303
 
5198 hendricks2 1304
void InitLevelGlobals2(void)
5196 hendricks2 1305
{
1306
    extern short Bunny_Count;
1307
    // GLOBAL RESETS NOT DONE for LOAD GAME
1308
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1309
    InitTimingVars();
1310
    TotalKillable = 0;
1311
    Bunny_Count = 0;
1312
}
1313
 
5198 hendricks2 1314
void
1315
InitLevel(void)
5196 hendricks2 1316
{
1317
    static int DemoNumber = 0;
1318
 
1319
    MONO_PRINT("InitLevel");
1320
    Terminate3DSounds();
1321
 
1322
    // A few IMPORTANT GLOBAL RESETS
1323
    InitLevelGlobals();
1324
    MONO_PRINT("InitLevelGlobals");
1325
    if (!DemoMode)
1326
        StopSong();
1327
 
1328
    if (LoadGameOutsideMoveLoop)
1329
    {
1330
        MONO_PRINT("Returning from InitLevel");
1331
        return;
1332
    }
1333
 
1334
    InitLevelGlobals2();
1335
    MONO_PRINT("InitLevelGlobals2");
1336
    if (DemoMode)
1337
    {
1338
        Level = 0;
1339
        NewGame = TRUE;
1340
        DemoInitOnce = FALSE;
1341
        strcpy(DemoFileName, DemoName[DemoNumber]);
1342
        DemoNumber++;
1343
        if (!DemoName[DemoNumber][0])
1344
            DemoNumber = 0;
1345
 
1346
        // read header and such
1347
        DemoPlaySetup();
1348
 
1349
        strcpy(LevelName, DemoLevelName);
1350
 
1351
        FindLevelInfo(LevelName, &Level);
1352
        if (Level > 0)
1353
        {
1354
            strcpy(LevelSong, LevelInfo[Level].SongName);
1355
            strcpy(LevelName, LevelInfo[Level].LevelName);
1356
            UserMapName[0] = '\0';
1357
        }
1358
        else
1359
        {
1360
            strcpy(UserMapName, DemoLevelName);
1361
            Level = 0;
1362
        }
1363
 
1364
    }
1365
    else
1366
    {
1367
        if (Level < 0)
1368
            Level = 0;
1369
 
1370
        if (Level > MAX_LEVELS)
1371
            Level = 1;
1372
 
1373
        // extra code in case something is resetting these values
1374
        if (NewGame)
1375
        {
1376
            //Level = 1;
1377
            //DemoPlaying = FALSE;
1378
            DemoMode = FALSE;
1379
            //DemoRecording = FALSE;
1380
            //DemoEdit = FALSE;
1381
        }
1382
 
1383
        if (UserMapName[0])
1384
        {
1385
            strcpy(LevelName, UserMapName);
1386
 
1387
            Level = 0;
1388
            FindLevelInfo(UserMapName, &Level);
1389
 
1390
            if (Level > 0)
1391
            {
1392
                // user map is part of game - treat it as such
1393
                strcpy(LevelSong, LevelInfo[Level].SongName);
1394
                strcpy(LevelName, LevelInfo[Level].LevelName);
1395
                UserMapName[0] = '\0';
1396
            }
1397
        }
1398
        else
1399
        {
1400
            strcpy(LevelName, LevelInfo[Level].LevelName);
1401
            strcpy(LevelSong, LevelInfo[Level].SongName);
1402
        }
1403
    }
1404
 
1405
    PlayingLevel = Level;
1406
 
1407
    if (NewGame)
1408
        InitNewGame();
1409
 
8694 ny00123 1410
    LoadingLevelScreen();
5196 hendricks2 1411
    MONO_PRINT("LoadintLevelScreen");
1412
    if (!DemoMode && !DemoInitOnce)
1413
        DemoPlaySetup();
1414
 
1415
    LoadLevel(LevelName);
1416
 
1417
    if (Bstrcasecmp(CacheLastLevel, LevelName) != 0)
1418
        // clears gotpic and does some bit setting
1419
        SetupPreCache();
1420
    else
1421
        memset(gotpic,0,sizeof(gotpic));
1422
 
1423
    if (sector[0].extra != -1)
1424
    {
5207 hendricks2 1425
        NormalVisibility = g_visibility = sector[0].extra;
5196 hendricks2 1426
        sector[0].extra = 0;
1427
    }
1428
    else
5207 hendricks2 1429
        NormalVisibility = g_visibility;
5196 hendricks2 1430
 
1431
    //
1432
    // Do Player stuff first
1433
    //
1434
 
1435
    InitAllPlayers();
1436
 
1437
#if DEBUG
1438
    // fake Multi-player game setup
1439
    if (FakeMultiNumPlayers && !BotMode)
1440
    {
5198 hendricks2 1441
        uint8_t i;
5196 hendricks2 1442
 
1443
        // insert all needed players except the first one - its already tere
1444
        for (i = 0; i < FakeMultiNumPlayers - 1; i++)
1445
        {
1446
            ManualPlayerInsert(Player);
1447
            // reset control back to 1st player
1448
            myconnectindex = 0;
1449
            screenpeek = 0;
1450
        }
1451
    }
1452
#endif
1453
 
1454
    // Put in the BOTS if called for
1455
    if (FakeMultiNumPlayers && BotMode)
1456
    {
5198 hendricks2 1457
        uint8_t i;
5196 hendricks2 1458
 
1459
        // insert all needed players except the first one - its already tere
1460
        for (i = 0; i < FakeMultiNumPlayers; i++)
1461
        {
1462
            BotPlayerInsert(Player);
1463
            // reset control back to 1st player
1464
            myconnectindex = 0;
1465
            screenpeek = 0;
1466
        }
1467
    }
1468
 
1469
    QueueReset();
1470
    PreMapCombineFloors();
1471
    InitMultiPlayerInfo();
1472
    InitAllPlayerSprites();
1473
 
1474
    //
1475
    // Do setup for sprite, track, panel, sector, etc
1476
    //
1477
 
1478
    // Set levels up
1479
    InitTimingVars();
1480
 
1481
    SpriteSetup();
1482
    SpriteSetupPost(); // post processing - already gone once through the loop
1483
    InitLighting();
1484
 
1485
    TrackSetup();
1486
 
1487
    PlayerPanelSetup();
1488
    MapSetup();
1489
    SectorSetup();
1490
    JS_InitMirrors();
1491
    JS_InitLockouts();   // Setup the lockout linked lists
1492
    JS_ToggleLockouts(); // Init lockouts on/off
1493
 
1494
    PlaceSectorObjectsOnTracks();
1495
    PlaceActorsOnTracks();
1496
    PostSetupSectorObject();
1497
    SetupMirrorTiles();
1498
    initlava();
1499
 
1500
    SongLevelNum = Level;
1501
 
1502
    if (DemoMode)
1503
    {
1504
        DisplayDemoText();
1505
    }
1506
 
1507
 
1508
    if (ArgCheat)
1509
    {
5198 hendricks2 1510
        SWBOOL bak = gs.Messages;
5196 hendricks2 1511
        gs.Messages = FALSE;
1512
        EveryCheatToggle(&Player[0],NULL);
1513
        gs.Messages = bak;
1514
        GodMode = TRUE;
1515
    }
1516
 
1517
    // reset NewGame
1518
    NewGame = FALSE;
1519
 
1520
    DSPRINTF(ds,"End of InitLevel...");
1521
    MONO_PRINT(ds);
1522
 
1523
#if 0
1524
#if DEBUG
1525
    if (!cansee(43594, -92986, 0x3fffffff, 290,
1526
                43180, -91707, 0x3fffffff, 290))
1527
    {
1528
        DSPRINTF(ds,"cansee failed");
1529
        MONO_PRINT(ds);
1530
    }
1531
#endif
1532
#endif
1533
 
1534
}
1535
 
1536
 
5198 hendricks2 1537
void
1538
TerminateLevel(void)
5196 hendricks2 1539
{
5198 hendricks2 1540
    void pClearSpriteList(PLAYERp pp);
5196 hendricks2 1541
    int i, nexti, stat, pnum, ndx;
1542
    SECT_USERp *sectu;
1543
 
1544
//HEAP_CHECK();
1545
 
1546
    DemoTerm();
1547
 
1548
    // Free any track points
1549
    for (ndx = 0; ndx < MAX_TRACKS; ndx++)
1550
    {
1551
        if (Track[ndx].TrackPoint)
1552
        {
1553
            FreeMem(Track[ndx].TrackPoint);
1554
            // !JIM! I added null assigner
1555
            Track[ndx].TrackPoint = NULL;
1556
        }
1557
    }
1558
 
1559
    // Clear the tracks
1560
    memset(Track, 0, sizeof(Track));
1561
 
8627 hendricks2 1562
    StopFX();
5196 hendricks2 1563
    Terminate3DSounds();        // Kill the 3d sounds linked list
1564
    //ClearSoundLocks();
1565
 
1566
    // Clear all anims and any memory associated with them
1567
    // Clear before killing sprites - save a little time
1568
    //AnimClear();
1569
 
1570
    for (stat = STAT_PLAYER0; stat < STAT_PLAYER0 + numplayers; stat++)
1571
    {
1572
 
1573
        pnum = stat - STAT_PLAYER0;
1574
 
1575
        TRAVERSE_SPRITE_STAT(headspritestat[stat], i, nexti)
1576
        {
1577
            if (User[i])
1578
                memcpy(&puser[pnum], User[i], sizeof(USER));
1579
        }
1580
    }
1581
 
1582
    // Kill User memory and delete sprites
1583
    // for (stat = 0; stat < STAT_ALL; stat++)
1584
    for (stat = 0; stat < MAXSTATUS; stat++)
1585
    {
1586
        TRAVERSE_SPRITE_STAT(headspritestat[stat], i, nexti)
1587
        {
1588
            KillSprite(i);
1589
        }
1590
    }
1591
 
1592
    // Free SectUser memory
1593
    for (sectu = &SectUser[0];
1594
         sectu < &SectUser[MAXSECTORS];
1595
         sectu++)
1596
    {
1597
        if (*sectu)
1598
        {
1599
            ////DSPRINTF(ds,"Sect User Free %d",sectu-SectUser);
1600
            //MONO_PRINT(ds);
1601
            FreeMem(*sectu);
1602
            *sectu = NULL;
1603
        }
1604
    }
1605
 
1606
    //memset(&User[0], 0, sizeof(User));
1607
    memset(&SectUser[0], 0, sizeof(SectUser));
1608
 
1609
    TRAVERSE_CONNECT(pnum)
1610
    {
1611
        PLAYERp pp = Player + pnum;
1612
 
1613
        // Free panel sprites for players
1614
        pClearSpriteList(pp);
1615
 
1616
        pp->DoPlayerAction = NULL;
1617
 
1618
        pp->SpriteP = NULL;
1619
        pp->PlayerSprite = -1;
1620
 
1621
        pp->UnderSpriteP = NULL;
1622
        pp->PlayerUnderSprite = -1;
1623
 
1624
        memset(pp->HasKey, 0, sizeof(pp->HasKey));
1625
 
1626
        //pp->WpnFlags = 0;
1627
        pp->CurWpn = NULL;
1628
 
1629
        memset(pp->Wpn, 0, sizeof(pp->Wpn));
1630
        memset(pp->InventorySprite, 0, sizeof(pp->InventorySprite));
1631
        memset(pp->InventoryTics, 0, sizeof(pp->InventoryTics));
1632
 
1633
        pp->Killer = -1;
1634
 
1635
        INITLIST(&pp->PanelSpriteList);
1636
    }
1637
 
1638
    JS_UnInitLockouts();
1639
 
1640
//HEAP_CHECK();
1641
}
1642
 
5198 hendricks2 1643
void
1644
NewLevel(void)
5196 hendricks2 1645
{
1646
 
1647
    DSPRINTF(ds,"NewLevel");
1648
    MONO_PRINT(ds);
1649
 
1650
    if (DemoPlaying)
1651
    {
1652
        FX_SetVolume(0); // Shut the hell up while game is loading!
1653
        InitLevel();
1654
        InitRunLevel();
1655
 
1656
        DemoInitOnce = FALSE;
1657
        if (DemoMode)
1658
        {
1659
            if (DemoModeMenuInit)
1660
            {
1661
                DemoModeMenuInit = FALSE;
1662
                KEY_PRESSED(KEYSC_ESC) = TRUE;
1663
            }
1664
        }
1665
 
1666
        DemoPlayBack();
1667
 
1668
        if (DemoRecording && DemoEdit)
1669
        {
1670
            RunLevel();
1671
        }
1672
    }
1673
    else
1674
    {
1675
        DSPRINTF(ds,"Calling FX_SetVolume");
1676
        MONO_PRINT(ds);
1677
        FX_SetVolume(0); // Shut the hell up while game is loading!
1678
 
1679
        DSPRINTF(ds,"Calling InitLevel");
1680
        MONO_PRINT(ds);
1681
        InitLevel();
1682
 
1683
        DSPRINTF(ds,"Calling RunLevel");
1684
        MONO_PRINT(ds);
1685
        RunLevel();
1686
 
8746 ny00123 1687
        // On map change, or after master player quits
1688
        if (!QuitFlag ||
1689
            (!NetBroadcastMode && TEST_SYNC_KEY(Player + connecthead, SK_QUIT_GAME)))
5196 hendricks2 1690
        {
1691
            // for good measure do this
1692
            ready2send = 0;
1693
            waitforeverybody();
1694
        }
1695
 
1696
        StatScreen(&Player[myconnectindex]);
1697
    }
1698
 
1699
    if (LoadGameFromDemo)
1700
        LoadGameFromDemo = FALSE;
1701
    else
1702
        TerminateLevel();
1703
 
1704
    InGame = FALSE;
1705
 
1706
    if (SW_SHAREWARE)
1707
    {
1708
        if (FinishAnim)
8271 hendricks2 1709
        {
1710
            PlayTheme();
5196 hendricks2 1711
            MenuLevel();
8271 hendricks2 1712
        }
5196 hendricks2 1713
    }
1714
    else
1715
    {
1716
        if (FinishAnim == ANIM_ZILLA || FinishAnim == ANIM_SERP)
8271 hendricks2 1717
        {
1718
            PlayTheme();
5196 hendricks2 1719
            MenuLevel();
8271 hendricks2 1720
        }
5196 hendricks2 1721
    }
1722
    FinishAnim = 0;
1723
}
1724
 
5198 hendricks2 1725
void
1726
ResetKeys(void)
5196 hendricks2 1727
{
1728
    int i;
1729
 
1730
    for (i = 0; i < MAXKEYBOARDSCAN; i++)
1731
    {
1732
        KEY_PRESSED(i) = 0;
1733
    }
1734
}
1735
 
5198 hendricks2 1736
SWBOOL
1737
KeyPressed(void)
5196 hendricks2 1738
{
1739
    int i;
1740
 
1741
    for (i = 0; i < MAXKEYBOARDSCAN; i++)
1742
    {
1743
        if (KEY_PRESSED(i))
1744
            return TRUE;
1745
    }
1746
 
1747
    return FALSE;
1748
}
1749
 
5198 hendricks2 1750
uint8_t*
1751
KeyPressedRange(uint8_t* kb, uint8_t* ke)
5196 hendricks2 1752
{
5198 hendricks2 1753
    uint8_t* k;
5196 hendricks2 1754
 
1755
    for (k = kb; k <= ke; k++)
1756
    {
1757
        if (*k)
1758
            return k;
1759
    }
1760
 
1761
    return NULL;
1762
}
1763
 
5198 hendricks2 1764
void
1765
ResetKeyRange(uint8_t* kb, uint8_t* ke)
5196 hendricks2 1766
{
5198 hendricks2 1767
    uint8_t* k;
5196 hendricks2 1768
 
1769
    for (k = kb; k <= ke; k++)
1770
    {
1771
        *k = 0;
1772
    }
1773
}
1774
 
8271 hendricks2 1775
void PlayTheme()
1776
{
1777
    // start music at logo
1778
    strcpy(LevelSong,"theme.mid");
1779
    PlaySong(LevelSong, RedBookSong[0], TRUE, TRUE);
5196 hendricks2 1780
 
8271 hendricks2 1781
    DSPRINTF(ds,"After music stuff...");
1782
    MONO_PRINT(ds);
1783
}
1784
 
8593 hendricks2 1785
static int g_noLogo;
1786
 
5198 hendricks2 1787
void
1788
LogoLevel(void)
5196 hendricks2 1789
{
8593 hendricks2 1790
    if (g_noLogo)
1791
        return;
1792
 
5196 hendricks2 1793
    int fin;
1794
    unsigned char pal[PAL_SIZE];
1795
    UserInput uinfo = { FALSE, FALSE, dir_None };
1796
 
1797
 
1798
    DSPRINTF(ds,"LogoLevel...");
1799
    MONO_PRINT(ds);
1800
 
1801
    // PreCache Anim
1802
    LoadAnm(0);
1803
 
1804
    if ((fin = kopen4load("3drealms.pal", 0)) != -1)
1805
    {
1806
        kread(fin, pal, PAL_SIZE);
1807
        kclose(fin);
7509 hendricks2 1808
 
8272 hendricks2 1809
        for (auto & c : pal)
1810
            c <<= 2;
1811
 
1812
        paletteSetColorTable(DREALMSPAL, pal);
1813
        videoSetPalette(gs.Brightness, DREALMSPAL, 2);
5196 hendricks2 1814
    }
1815
    DSPRINTF(ds,"Just read in 3drealms.pal...");
1816
    MONO_PRINT(ds);
1817
 
1818
    //FadeOut(0, 0);
1819
    ready2send = 0;
1820
    totalclock = 0;
1821
    ototalclock = 0;
1822
 
1823
    DSPRINTF(ds,"About to display 3drealms pic...");
1824
    MONO_PRINT(ds);
1825
 
1826
    //FadeIn(0, 3);
1827
 
1828
    ResetKeys();
1829
    while (TRUE)
1830
    {
8625 hendricks2 1831
        videoClearViewableArea(0L);
1832
        rotatesprite(0, 0, RS_SCALE, 0, THREED_REALMS_PIC, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
1833
        videoNextPage();
1834
 
5196 hendricks2 1835
        handleevents();
1836
        CONTROL_GetUserInput(&uinfo);
1837
        CONTROL_ClearUserInput(&uinfo);
1838
        if (quitevent) { QuitFlag = TRUE; break; }
1839
 
1840
        // taken from top of faketimerhandler
1841
        // limits checks to max of 40 times a second
1842
        if (totalclock >= ototalclock + synctics)
1843
        {
1844
            ototalclock += synctics;
1845
        }
1846
 
1847
        if (totalclock > 5*120 || KeyPressed() || uinfo.button0 || uinfo.button1)
1848
        {
1849
            break;
1850
        }
1851
    }
1852
 
7509 hendricks2 1853
    videoClearViewableArea(0L);
1854
    videoNextPage();
8272 hendricks2 1855
    videoSetPalette(gs.Brightness, BASEPAL, 2);
5196 hendricks2 1856
 
1857
    // put up a blank screen while loading
1858
 
1859
    DSPRINTF(ds,"End of LogoLevel...");
1860
    MONO_PRINT(ds);
1861
 
1862
}
1863
 
5198 hendricks2 1864
void
1865
CreditsLevel(void)
5196 hendricks2 1866
{
1867
    int curpic;
1868
    int handle;
5198 hendricks2 1869
    uint32_t timer = 0;
5196 hendricks2 1870
    int zero=0;
1871
    short save;
1872
#define CREDITS1_PIC 5111
1873
#define CREDITS2_PIC 5118
1874
 
1875
    // put up a blank screen while loading
1876
 
1877
    // get rid of all PERM sprites!
7509 hendricks2 1878
    renderFlushPerms();
5196 hendricks2 1879
    save = gs.BorderNum;
1880
    ClearStartMost();
1881
    gs.BorderNum = save;
7509 hendricks2 1882
    videoClearViewableArea(0L);
1883
    videoNextPage();
5196 hendricks2 1884
 
1885
    // Lo Wang feel like singing!
1886
    handle = PlaySound(DIGI_JG95012,&zero,&zero,&zero,v3df_none);
1887
 
1888
    if (handle > 0)
1889
        while (FX_SoundActive(handle)) ;
1890
 
1891
    // try 14 then 2 then quit
1892
    if (!PlaySong(NULL, 14, FALSE, TRUE))
1893
    {
1894
        if (!PlaySong(NULL, 2, FALSE, TRUE))
1895
        {
1896
            handle = PlaySound(DIGI_NOLIKEMUSIC,&zero,&zero,&zero,v3df_none);
1897
            if (handle > 0)
1898
                while (FX_SoundActive(handle)) handleevents();
1899
            return;
1900
        }
1901
    }
1902
 
1903
    ready2send = 0;
1904
    totalclock = 0;
1905
    ototalclock = 0;
1906
 
1907
    ResetKeys();
1908
    curpic = CREDITS1_PIC;
1909
 
1910
    while (TRUE)
1911
    {
8626 hendricks2 1912
        handleevents();
1913
 
5196 hendricks2 1914
        // taken from top of faketimerhandler
1915
        // limits checks to max of 40 times a second
1916
        if (totalclock >= ototalclock + synctics)
1917
        {
1918
            ototalclock += synctics;
1919
            timer += synctics;
1920
        }
1921
 
1922
        rotatesprite(0, 0, RS_SCALE, 0, curpic, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
1923
 
7509 hendricks2 1924
        videoNextPage();
5196 hendricks2 1925
 
1926
        if (timer > 8*120)
1927
        {
1928
            curpic = CREDITS2_PIC;
1929
        }
1930
 
1931
        if (timer > 16*120)
1932
        {
1933
            timer = 0;
1934
            curpic = CREDITS1_PIC;
1935
        }
1936
 
1937
 
1938
        if (!SongIsPlaying())
1939
            break;
1940
 
1941
        if (KEY_PRESSED(KEYSC_ESC))
1942
            break;
1943
    }
1944
 
1945
    // put up a blank screen while loading
7509 hendricks2 1946
    videoClearViewableArea(0L);
1947
    videoNextPage();
5196 hendricks2 1948
    ResetKeys();
1949
    StopSong();
1950
}
1951
 
1952
 
5198 hendricks2 1953
void
1954
SybexScreen(void)
5196 hendricks2 1955
{
1956
    if (!SW_SHAREWARE) return;
1957
 
1958
    if (CommEnabled)
1959
        return;
1960
 
1961
    rotatesprite(0, 0, RS_SCALE, 0, 5261, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
7509 hendricks2 1962
    videoNextPage();
5196 hendricks2 1963
 
1964
    ResetKeys();
1965
    while (!KeyPressed() && !quitevent) handleevents();
1966
}
1967
 
1968
// CTW REMOVED
1969
/*
5198 hendricks2 1970
void
1971
TenScreen(void)
5196 hendricks2 1972
    {
1973
    char called;
1974
    int fin;
1975
    char backup_pal[256*3];
1976
    char pal[PAL_SIZE];
1977
    char tempbuf[256];
1978
    char *palook_bak = palookup[0];
1979
    int i;
5198 hendricks2 1980
    uint32_t bak;
5196 hendricks2 1981
    int bakready2send;
1982
 
1983
    if (CommEnabled)
1984
        return;
1985
 
1986
    bak = totalclock;
1987
 
1988
    flushperms();
1989
    clearview(0);
1990
    nextpage();
1991
 
1992
    for (i = 0; i < 256; i++)
1993
        tempbuf[i] = i;
1994
    palookup[0] = tempbuf;
1995
 
1996
    GetPaletteFromVESA(pal);
1997
    memcpy(backup_pal, pal, PAL_SIZE);
1998
 
1999
    if ((fin = kopen4load("ten.pal", 0)) != -1)
2000
        {
2001
        kread(fin, pal, PAL_SIZE);
2002
        kclose(fin);
2003
        }
2004
 
2005
    // palette to black
2006
    FadeOut(0, 0);
2007
    bakready2send = ready2send;
2008
    //totalclock = 0;
2009
    //ototalclock = 0;
2010
 
2011
    flushperms();
2012
    // draw it
2013
    rotatesprite(0, 0, RS_SCALE, 0, TEN_PIC, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2014
    // bring to the front - still back palette
2015
    nextpage();
2016
    // set pal
2017
    SetPaletteToVESA(pal);
2018
    //FadeIn(0, 3);
2019
    ResetKeys();
2020
 
8748 ny00123 2021
    while (!KeyPressed() && !quitevent) handleevents();
5196 hendricks2 2022
 
2023
    palookup[0] = palook_bak;
2024
 
2025
    clearview(0);
2026
    nextpage();
2027
    SetPaletteToVESA(backup_pal);
2028
 
2029
    // put up a blank screen while loading
2030
    clearview(0);
2031
    nextpage();
2032
 
2033
    ready2send = bakready2send;
2034
    totalclock = bak;
2035
    }
2036
*/
2037
// CTW REMOVED END
2038
 
5198 hendricks2 2039
void
2040
TitleLevel(void)
5196 hendricks2 2041
{
6041 hendricks2 2042
    char tempbuf[256];
2043
    char *palook_bak = palookup[0];
5196 hendricks2 2044
    int i;
2045
 
2046
    for (i = 0; i < 256; i++)
2047
        tempbuf[i] = i;
2048
    palookup[0] = tempbuf;
2049
 
8686 ny00123 2050
//    unsigned char backup_pal[256*3];
2051
//    unsigned char pal[PAL_SIZE];
5196 hendricks2 2052
    //GetPaletteFromVESA(pal);
2053
    //memcpy(backup_pal, pal, PAL_SIZE);
2054
 
7509 hendricks2 2055
    videoClearViewableArea(0L);
2056
    videoNextPage();
5196 hendricks2 2057
 
8686 ny00123 2058
//    int fin;
5196 hendricks2 2059
//    if ((fin = kopen4load("title.pal", 0)) != -1)
2060
//        {
2061
//        kread(fin, pal, PAL_SIZE);
2062
//        kclose(fin);
2063
//        SetPaletteToVESA(pal);
2064
//        }
2065
 
2066
//    clearview(0);
2067
//    nextpage();
2068
 
2069
    //FadeOut(0, 0);
2070
    ready2send = 0;
2071
    totalclock = 0;
2072
    ototalclock = 0;
2073
 
2074
    rotatesprite(0, 0, RS_SCALE, 0, TITLE_PIC, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
7509 hendricks2 2075
    videoNextPage();
5196 hendricks2 2076
    //FadeIn(0, 3);
2077
 
2078
    ResetKeys();
2079
    while (TRUE)
2080
    {
2081
        handleevents();
2082
        OSD_DispatchQueued();
2083
 
2084
        // taken from top of faketimerhandler
2085
        // limits checks to max of 40 times a second
2086
        if (totalclock >= ototalclock + synctics)
2087
        {
2088
            //void MNU_CheckForMenusAnyKey( void );
2089
 
2090
            ototalclock += synctics;
2091
            //MNU_CheckForMenusAnyKey();
2092
        }
2093
 
2094
        //if (UsingMenus)
2095
        //    MNU_DrawMenu();
2096
 
2097
        //drawscreen as fast as you can
2098
        rotatesprite(0, 0, RS_SCALE, 0, TITLE_PIC, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2099
 
7509 hendricks2 2100
        videoNextPage();
5196 hendricks2 2101
 
2102
        if (totalclock > 5*120 || KeyPressed())
2103
        {
2104
            DemoMode = TRUE;
2105
            DemoPlaying = TRUE;
2106
            break;
2107
        }
2108
    }
2109
 
2110
    palookup[0] = palook_bak;
2111
 
2112
//    clearview(0);
2113
//    nextpage();
2114
    //SetPaletteToVESA(backup_pal);
2115
 
2116
    // put up a blank screen while loading
2117
//    clearview(0);
2118
//    nextpage();
2119
}
2120
 
2121
 
5198 hendricks2 2122
void DrawMenuLevelScreen(void)
5196 hendricks2 2123
{
7509 hendricks2 2124
    renderFlushPerms();
2125
    videoClearViewableArea(0L);
5196 hendricks2 2126
    rotatesprite(0, 0, RS_SCALE, 0, TITLE_PIC, 20, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2127
}
2128
 
5198 hendricks2 2129
void DrawStatScreen(void)
5196 hendricks2 2130
{
7509 hendricks2 2131
    renderFlushPerms();
2132
    videoClearViewableArea(0L);
5196 hendricks2 2133
    rotatesprite(0, 0, RS_SCALE, 0, STAT_SCREEN_PIC, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2134
}
2135
 
5198 hendricks2 2136
void DrawLoadLevelScreen(void)
5196 hendricks2 2137
{
7509 hendricks2 2138
    renderFlushPerms();
2139
    videoClearViewableArea(0L);
5196 hendricks2 2140
    rotatesprite(0, 0, RS_SCALE, 0, TITLE_PIC, 20, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2141
}
2142
 
2143
short PlayerQuitMenuLevel = -1;
2144
 
5198 hendricks2 2145
void
2146
IntroAnimLevel(void)
5196 hendricks2 2147
{
8593 hendricks2 2148
    if (g_noLogo)
2149
        return;
2150
 
5196 hendricks2 2151
    DSPRINTF(ds,"IntroAnimLevel");
2152
    MONO_PRINT(ds);
2153
    playanm(0);
2154
}
2155
 
5198 hendricks2 2156
void
2157
MenuLevel(void)
5196 hendricks2 2158
{
5198 hendricks2 2159
    SWBOOL MNU_StartNetGame(void);
8050 pogokeen 2160
    extern ClockTicks totalclocklock;
5196 hendricks2 2161
    short w,h;
2162
 
2163
    DSPRINTF(ds,"MenuLevel...");
2164
    MONO_PRINT(ds);
2165
 
2166
    if (AutoNet)
2167
    {
2168
        DrawMenuLevelScreen();
2169
 
2170
        if (CommEnabled)
2171
        {
2172
            sprintf(ds,"Lo Wang is waiting for other players...");
2173
            MNU_MeasureString(ds, &w, &h);
2174
            MNU_DrawString(TEXT_TEST_COL(w), 170, ds, 1, 16);
2175
 
2176
            sprintf(ds,"They are afraid!");
2177
            MNU_MeasureString(ds, &w, &h);
2178
            MNU_DrawString(TEXT_TEST_COL(w), 180, ds, 1, 16);
2179
        }
2180
 
7509 hendricks2 2181
        videoNextPage();
5196 hendricks2 2182
 
2183
        waitforeverybody();
2184
        FirstTimeIntoGame = TRUE;
2185
        MNU_StartNetGame();
2186
        FirstTimeIntoGame = FALSE;
2187
        waitforeverybody();
2188
        ExitLevel = FALSE;
2189
        FinishedLevel = FALSE;
2190
        BorderAdjust = TRUE;
2191
        UsingMenus = FALSE;
2192
        InMenuLevel = FALSE;
2193
        return;
2194
    }
2195
 
2196
    // do demos only if not playing multi play
2197
    if (!CommEnabled && numplayers <= 1 && !FinishAnim && !NoDemoStartup)
2198
    {
2199
        // demos exist - do demo instead
2200
        if (DemoName[0][0] != '\0')
2201
        {
2202
            DemoMode = TRUE;
2203
            DemoPlaying = TRUE;
2204
            return;
2205
        }
2206
    }
2207
 
2208
    DemoMode = FALSE;
2209
    DemoPlaying = FALSE;
2210
 
7509 hendricks2 2211
    videoClearViewableArea(0L);
2212
    videoNextPage();
5196 hendricks2 2213
 
2214
    //FadeOut(0, 0);
2215
    ready2send = 0;
2216
    totalclock = 0;
2217
    ototalclock = 0;
2218
    ExitLevel = FALSE;
2219
    InMenuLevel = TRUE;
2220
 
2221
    DrawMenuLevelScreen();
2222
 
2223
    if (CommEnabled)
2224
    {
2225
        sprintf(ds,"Lo Wang is waiting for other players...");
2226
        MNU_MeasureString(ds, &w, &h);
2227
        MNU_DrawString(TEXT_TEST_COL(w), 170, ds, 1, 16);
2228
 
2229
        sprintf(ds,"They are afraid!");
2230
        MNU_MeasureString(ds, &w, &h);
2231
        MNU_DrawString(TEXT_TEST_COL(w), 180, ds, 1, 16);
2232
    }
2233
 
7509 hendricks2 2234
    videoNextPage();
5196 hendricks2 2235
    //FadeIn(0, 3);
2236
 
2237
    waitforeverybody();
2238
 
2239
    // don't allow BorderAdjusting in these menus
2240
    BorderAdjust = FALSE;
2241
 
2242
    ResetKeys();
2243
 
2244
    if (SW_SHAREWARE)
2245
    {
2246
        // go to ordering menu only if shareware
2247
        if (FinishAnim)
2248
        {
2249
            KEY_PRESSED(KEYSC_ESC) = 1;
2250
            ControlPanelType = ct_ordermenu;
2251
            FinishAnim = 0;
2252
        }
2253
    }
2254
    else
2255
    {
2256
        FinishAnim = 0;
2257
    }
2258
 
2259
    while (TRUE)
2260
    {
2261
        handleevents();
2262
        OSD_DispatchQueued();
2263
 
8750 ny00123 2264
        if (quitevent) CON_Quit();
5196 hendricks2 2265
 
2266
        // taken from top of faketimerhandler
2267
        // limits checks to max of 40 times a second
2268
        if (totalclock >= ototalclock + synctics)
2269
        {
2270
            ototalclock += synctics;
2271
            MNU_CheckForMenusAnyKey();
2272
            if (CommEnabled)
2273
                getpackets();
2274
        }
2275
 
2276
        if (CommEnabled)
2277
        {
2278
            if (MultiPlayQuitFlag)
2279
            {
5198 hendricks2 2280
                uint8_t pbuf[1];
5196 hendricks2 2281
                QuitFlag = TRUE;
2282
                pbuf[0] = PACKET_TYPE_MENU_LEVEL_QUIT;
2283
                netbroadcastpacket(pbuf, 1);                      // TENSW
2284
                break;
2285
            }
2286
 
2287
            if (PlayerQuitMenuLevel >= 0)
2288
            {
2289
                MenuCommPlayerQuit(PlayerQuitMenuLevel);
2290
                PlayerQuitMenuLevel = -1;
2291
            }
2292
        }
2293
 
2294
        if (ExitLevel)
2295
        {
2296
            // Quiting Level
2297
            ExitLevel = FALSE;
2298
            break;
2299
        }
2300
 
2301
        if (QuitFlag)
2302
        {
2303
            // Quiting Game
2304
            break;
2305
        }
2306
 
2307
        // force the use of menus at all time
2308
        if (!UsingMenus && !ConPanel)
2309
        {
2310
            KEY_PRESSED(KEYSC_ESC) = TRUE;
2311
            MNU_CheckForMenusAnyKey();
2312
        }
2313
 
2314
        // must lock the clock for drawing so animations will happen
2315
        totalclocklock = totalclock;
2316
 
2317
        //drawscreen as fast as you can
2318
        DrawMenuLevelScreen();
2319
 
2320
        if (UsingMenus)
2321
            MNU_DrawMenu();
2322
 
7509 hendricks2 2323
        videoNextPage();
5196 hendricks2 2324
    }
2325
 
2326
    BorderAdjust = TRUE;
2327
    //LoadGameOutsideMoveLoop = FALSE;
2328
    KEY_PRESSED(KEYSC_ESC) = FALSE;
2329
    KB_ClearKeysDown();
2330
    //ExitMenus();
2331
    UsingMenus = FALSE;
2332
    InMenuLevel = FALSE;
7509 hendricks2 2333
    videoClearViewableArea(0L);
2334
    videoNextPage();
5196 hendricks2 2335
}
2336
 
5198 hendricks2 2337
void
2338
SceneLevel(void)
5196 hendricks2 2339
{
5198 hendricks2 2340
    SWBOOL dp_bak;
2341
    SWBOOL dm_bak;
5196 hendricks2 2342
    FILE *fin;
2343
#define CINEMATIC_DEMO_FILE "$scene.dmo"
2344
 
2345
    // make sure it exists
2346
    if ((fin = fopen(CINEMATIC_DEMO_FILE,"rb")) == NULL)
2347
        return;
2348
    else
2349
        fclose(fin);
2350
 
2351
    strcpy(DemoFileName,CINEMATIC_DEMO_FILE);
2352
 
2353
    dp_bak = DemoPlaying;
2354
    dm_bak = DemoMode;
2355
 
2356
    DemoMode = TRUE;
2357
    DemoPlaying = TRUE;
2358
    DemoOverride = TRUE;
2359
    InitLevel();
2360
    DemoOverride = FALSE;
2361
 
2362
    ScenePlayBack();
2363
    TerminateLevel();
2364
    DemoMode = dm_bak;
2365
    DemoPlaying = dp_bak;
2366
}
2367
 
5198 hendricks2 2368
void
8694 ny00123 2369
LoadingLevelScreen(void)
5196 hendricks2 2370
{
2371
    short w,h;
5198 hendricks2 2372
    extern SWBOOL DemoMode;
5196 hendricks2 2373
    DrawLoadLevelScreen();
2374
 
2375
    if (DemoMode)
2376
        sprintf(ds,"DEMO");
2377
    else
2378
        sprintf(ds,"ENTERING");
2379
 
2380
    MNU_MeasureString(ds, &w, &h);
2381
    MNU_DrawString(TEXT_TEST_COL(w), 170, ds,1,16);
2382
 
2383
    if (UserMapName[0])
2384
        sprintf(ds,"%s",UserMapName);
2385
    else
2386
        sprintf(ds,"%s",LevelInfo[Level].Description);
2387
 
2388
    MNU_MeasureString(ds, &w, &h);
2389
    MNU_DrawString(TEXT_TEST_COL(w), 180, ds,1,16);
2390
 
7509 hendricks2 2391
    videoNextPage();
5196 hendricks2 2392
}
2393
 
5198 hendricks2 2394
void
5196 hendricks2 2395
gNextState(STATEp *State)
2396
{
2397
    // Transition to the next state
2398
    *State = (*State)->NextState;
2399
 
2400
    if (TEST((*State)->Tics, SF_QUICK_CALL))
2401
    {
2402
        (*(*State)->Animator)(0);
2403
        *State = (*State)->NextState;
2404
    }
2405
}
2406
 
2407
// Generic state control
5198 hendricks2 2408
void
5196 hendricks2 2409
gStateControl(STATEp *State, int *tics)
2410
{
2411
    *tics += synctics;
2412
 
2413
    // Skip states if too much time has passed
2414
    while (*tics >= (*State)->Tics)
2415
    {
2416
        // Set Tics
2417
        *tics -= (*State)->Tics;
2418
        gNextState(State);
2419
    }
2420
 
2421
    // Call the correct animator
2422
    if ((*State)->Animator)
2423
        (*(*State)->Animator)(0);
2424
}
2425
 
8696 ny00123 2426
int BonusPunchSound(short UNUSED(SpriteNum))
5196 hendricks2 2427
{
2428
    PLAYERp pp = Player + myconnectindex;
2429
    PlaySound(DIGI_PLAYERYELL3, &pp->posx, &pp->posy, &pp->posz, v3df_none);
2430
    return 0;
2431
}
2432
 
8696 ny00123 2433
int BonusKickSound(short UNUSED(SpriteNum))
5196 hendricks2 2434
{
2435
    PLAYERp pp = Player + myconnectindex;
2436
    PlaySound(DIGI_PLAYERYELL2, &pp->posx, &pp->posy, &pp->posz, v3df_none);
2437
    return 0;
2438
}
2439
 
8696 ny00123 2440
int BonusGrabSound(short UNUSED(SpriteNum))
5196 hendricks2 2441
{
2442
    PLAYERp pp = Player + myconnectindex;
2443
    PlaySound(DIGI_BONUS_GRAB, &pp->posx, &pp->posy, &pp->posz, v3df_none);
2444
    return 0;
2445
}
2446
 
5198 hendricks2 2447
void
8694 ny00123 2448
BonusScreen(void)
5196 hendricks2 2449
{
2450
    int minutes,seconds,second_tics;
2451
    extern int PlayClock;
2452
    extern short LevelSecrets;
2453
    short w,h;
8685 ny00123 2454
    short limit;
5196 hendricks2 2455
 
2456
 
2457
#define BONUS_SCREEN_PIC 5120
2458
#define BONUS_ANIM 5121
2459
#define BONUS_ANIM_FRAMES (5159-5121)
2460
 
2461
#define BREAK_LIGHT_RATE 18
2462
 
2463
#define BONUS_PUNCH 5121
2464
#define BONUS_KICK 5136
2465
#define BONUS_GRAB 5151
2466
#define BONUS_REST 5121
2467
 
2468
#define BONUS_TICS 8
2469
#define BONUS_GRAB_TICS 20
2470
#define BONUS_REST_TICS 50
2471
 
2472
    static STATE s_BonusPunch[] =
2473
    {
2474
        {BONUS_PUNCH + 0, BONUS_TICS, NULL, &s_BonusPunch[1]},
2475
        {BONUS_PUNCH + 1, BONUS_TICS, NULL, &s_BonusPunch[2]},
2476
        {BONUS_PUNCH + 2, BONUS_TICS, NULL, &s_BonusPunch[3]},
2477
        {BONUS_PUNCH + 2, 0|SF_QUICK_CALL, BonusPunchSound, &s_BonusPunch[4]},
2478
        {BONUS_PUNCH + 3, BONUS_TICS, NULL, &s_BonusPunch[5]},
2479
        {BONUS_PUNCH + 4, BONUS_TICS, NULL, &s_BonusPunch[6]},
2480
        {BONUS_PUNCH + 5, BONUS_TICS, NULL, &s_BonusPunch[7]},
2481
        {BONUS_PUNCH + 6, BONUS_TICS, NULL, &s_BonusPunch[8]},
2482
        {BONUS_PUNCH + 7, BONUS_TICS, NULL, &s_BonusPunch[9]},
2483
        {BONUS_PUNCH + 8, BONUS_TICS, NULL, &s_BonusPunch[10]},
2484
        {BONUS_PUNCH + 9, BONUS_TICS, NULL, &s_BonusPunch[11]},
2485
        {BONUS_PUNCH + 10, BONUS_TICS, NULL, &s_BonusPunch[12]},
2486
        {BONUS_PUNCH + 11, BONUS_TICS, NULL, &s_BonusPunch[13]},
2487
        {BONUS_PUNCH + 12, BONUS_TICS, NULL, &s_BonusPunch[14]},
2488
        {BONUS_PUNCH + 14, 90,        NULL, &s_BonusPunch[15]},
2489
        {BONUS_PUNCH + 14, BONUS_TICS, NULL, &s_BonusPunch[15]},
2490
    };
2491
 
2492
    static STATE s_BonusKick[] =
2493
    {
2494
        {BONUS_KICK + 0, BONUS_TICS, NULL, &s_BonusKick[1]},
2495
        {BONUS_KICK + 1, BONUS_TICS, NULL, &s_BonusKick[2]},
2496
        {BONUS_KICK + 2, BONUS_TICS, NULL, &s_BonusKick[3]},
2497
        {BONUS_KICK + 2, 0|SF_QUICK_CALL, BonusKickSound, &s_BonusKick[4]},
2498
        {BONUS_KICK + 3, BONUS_TICS, NULL, &s_BonusKick[5]},
2499
        {BONUS_KICK + 4, BONUS_TICS, NULL, &s_BonusKick[6]},
2500
        {BONUS_KICK + 5, BONUS_TICS, NULL, &s_BonusKick[7]},
2501
        {BONUS_KICK + 6, BONUS_TICS, NULL, &s_BonusKick[8]},
2502
        {BONUS_KICK + 7, BONUS_TICS, NULL, &s_BonusKick[9]},
2503
        {BONUS_KICK + 8, BONUS_TICS, NULL, &s_BonusKick[10]},
2504
        {BONUS_KICK + 9, BONUS_TICS, NULL, &s_BonusKick[11]},
2505
        {BONUS_KICK + 10, BONUS_TICS, NULL, &s_BonusKick[12]},
2506
        {BONUS_KICK + 11, BONUS_TICS, NULL, &s_BonusKick[13]},
2507
        {BONUS_KICK + 12, BONUS_TICS, NULL, &s_BonusKick[14]},
2508
        {BONUS_KICK + 14, 90,        NULL, &s_BonusKick[15]},
2509
        {BONUS_KICK + 14, BONUS_TICS, NULL, &s_BonusKick[15]},
2510
    };
2511
 
2512
    static STATE s_BonusGrab[] =
2513
    {
2514
        {BONUS_GRAB + 0, BONUS_GRAB_TICS, NULL, &s_BonusGrab[1]},
2515
        {BONUS_GRAB + 1, BONUS_GRAB_TICS, NULL, &s_BonusGrab[2]},
2516
        {BONUS_GRAB + 2, BONUS_GRAB_TICS, NULL, &s_BonusGrab[3]},
2517
        {BONUS_GRAB + 2, 0|SF_QUICK_CALL, BonusGrabSound, &s_BonusGrab[4]},
2518
        {BONUS_GRAB + 3, BONUS_GRAB_TICS, NULL, &s_BonusGrab[5]},
2519
        {BONUS_GRAB + 4, BONUS_GRAB_TICS, NULL, &s_BonusGrab[6]},
2520
        {BONUS_GRAB + 5, BONUS_GRAB_TICS, NULL, &s_BonusGrab[7]},
2521
        {BONUS_GRAB + 6, BONUS_GRAB_TICS, NULL, &s_BonusGrab[8]},
2522
        {BONUS_GRAB + 7, BONUS_GRAB_TICS, NULL, &s_BonusGrab[9]},
2523
        {BONUS_GRAB + 8, BONUS_GRAB_TICS, NULL, &s_BonusGrab[10]},
2524
        {BONUS_GRAB + 9, 90,             NULL, &s_BonusGrab[11]},
2525
        {BONUS_GRAB + 9, BONUS_GRAB_TICS, NULL, &s_BonusGrab[11]},
2526
    };
2527
 
2528
#if 1 // Turned off the standing animate because he looks like a FAG!
2529
    static STATE s_BonusRest[] =
2530
    {
2531
        {BONUS_REST + 0, BONUS_REST_TICS, NULL, &s_BonusRest[1]},
2532
        {BONUS_REST + 1, BONUS_REST_TICS, NULL, &s_BonusRest[2]},
2533
        {BONUS_REST + 2, BONUS_REST_TICS, NULL, &s_BonusRest[3]},
2534
        {BONUS_REST + 1, BONUS_REST_TICS, NULL, &s_BonusRest[0]},
2535
    };
2536
#else
2537
    static STATE s_BonusRest[] =
2538
    {
2539
        {BONUS_REST + 0, BONUS_REST_TICS, NULL, &s_BonusRest[1]},
2540
        {BONUS_REST + 0, BONUS_REST_TICS, NULL, &s_BonusRest[0]},
2541
    };
2542
#endif
2543
 
2544
    static STATEp s_BonusAnim[] =
2545
    {
2546
        s_BonusPunch,
2547
        s_BonusKick,
2548
        s_BonusGrab
2549
    };
2550
 
2551
    STATEp State = s_BonusRest;
2552
 
2553
    int Tics = 0;
2554
    int line = 0;
5198 hendricks2 2555
    SWBOOL BonusDone;
5196 hendricks2 2556
    UserInput uinfo = { FALSE, FALSE, dir_None };
2557
 
2558
    if (Level < 0) Level = 0;
2559
 
7509 hendricks2 2560
    videoClearViewableArea(0L);
2561
    videoNextPage();
5196 hendricks2 2562
 
2563
    KB_ClearKeysDown();
2564
 
2565
    totalclock = ototalclock = 0;
2566
    limit = synctics;
2567
 
2568
    if (gs.MusicOn)
2569
    {
2570
        PlaySong(voc[DIGI_ENDLEV].name, 3, TRUE, TRUE);
2571
    }
2572
 
2573
    // special case code because I don't care any more!
2574
    if (FinishAnim)
2575
    {
7509 hendricks2 2576
        renderFlushPerms();
5196 hendricks2 2577
        rotatesprite(0, 0, RS_SCALE, 0, 5120, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2578
        rotatesprite(158<<16, 86<<16, RS_SCALE, 0, State->Pic, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
7509 hendricks2 2579
        videoNextPage();
5196 hendricks2 2580
        FadeIn(0,0);
2581
    }
2582
 
2583
    BonusDone = FALSE;
2584
    while (!BonusDone)
2585
    {
2586
        handleevents();
8747 ny00123 2587
        getpackets();
5196 hendricks2 2588
 
2589
        // taken from top of faketimerhandler
2590
        if (totalclock < ototalclock + limit)
2591
        {
2592
            continue;
2593
        }
2594
        ototalclock += limit;
2595
 
2596
        CONTROL_GetUserInput(&uinfo);
2597
        CONTROL_ClearUserInput(&uinfo);
2598
        if (KEY_PRESSED(KEYSC_SPACE) || KEY_PRESSED(KEYSC_ENTER) || uinfo.button0 || uinfo.button1)
2599
        {
2600
            if (State >= s_BonusRest && State < &s_BonusRest[SIZ(s_BonusRest)])
2601
            {
2602
                State = s_BonusAnim[STD_RANDOM_RANGE(SIZ(s_BonusAnim))];
2603
                Tics = 0;
2604
            }
2605
        }
2606
 
2607
        gStateControl(&State, &Tics);
8310 hendricks2 2608
 
2609
        videoClearViewableArea(0L);
2610
 
5196 hendricks2 2611
        rotatesprite(0, 0, RS_SCALE, 0, 5120, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2612
 
2613
        if (UserMapName[0])
2614
        {
2615
            sprintf(ds,"%s",UserMapName);
2616
            MNU_MeasureString(ds, &w, &h);
2617
            MNU_DrawString(TEXT_TEST_COL(w), 20, ds,1,19);
2618
        }
2619
        else
2620
        {
2621
            if (PlayingLevel <= 1)
2622
                PlayingLevel = 1;
2623
            sprintf(ds,"%s",LevelInfo[PlayingLevel].Description);
2624
            MNU_MeasureString(ds, &w, &h);
2625
            MNU_DrawString(TEXT_TEST_COL(w), 20, ds,1,19);
2626
        }
2627
 
2628
        sprintf(ds,"Completed");
2629
        MNU_MeasureString(ds, &w, &h);
2630
        MNU_DrawString(TEXT_TEST_COL(w), 30, ds,1,19);
2631
 
2632
        rotatesprite(158<<16, 86<<16, RS_SCALE, 0, State->Pic, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2633
 
2634
#define BONUS_LINE(i) (50 + ((i)*20))
2635
 
2636
        line = 0;
2637
        second_tics = (PlayClock/120);
2638
        minutes = (second_tics/60);
2639
        seconds = (second_tics%60);
2640
        sprintf(ds,"Your Time:  %2d : %02d", minutes, seconds);
2641
        MNU_MeasureString(ds, &w, &h);
2642
        MNU_DrawString(60, BONUS_LINE(line), ds,1,16);
2643
 
2644
        if (!UserMapName[0])
2645
        {
2646
            line++;
2647
            sprintf(ds,"3D Realms Best Time:  %s", LevelInfo[PlayingLevel].BestTime);
2648
            MNU_MeasureString(ds, &w, &h);
2649
            MNU_DrawString(40, BONUS_LINE(line), ds,1,16);
2650
 
2651
            line++;
2652
            sprintf(ds,"Par Time:  %s", LevelInfo[PlayingLevel].ParTime);
2653
            MNU_MeasureString(ds, &w, &h);
2654
            MNU_DrawString(40, BONUS_LINE(line), ds,1,16);
2655
        }
2656
 
2657
 
2658
        // always read secrets and kills from the first player
2659
        line++;
2660
        sprintf(ds,"Secrets:  %d / %d", Player->SecretsFound, LevelSecrets);
2661
        MNU_MeasureString(ds, &w, &h);
2662
        MNU_DrawString(60, BONUS_LINE(line), ds,1,16);
2663
 
2664
        line++;
2665
        sprintf(ds,"Kills:  %d / %d", Player->Kills, TotalKillable);
2666
        MNU_MeasureString(ds, &w, &h);
2667
        MNU_DrawString(60, BONUS_LINE(line), ds,1,16);
2668
 
2669
 
2670
        sprintf(ds,"Press SPACE to continue");
2671
        MNU_MeasureString(ds, &w, &h);
2672
        MNU_DrawString(TEXT_TEST_COL(w), 185, ds,1,19);
2673
 
7509 hendricks2 2674
        videoNextPage();
5196 hendricks2 2675
        ScreenCaptureKeys();
2676
 
2677
        if (State == State->NextState)
2678
            BonusDone = TRUE;
2679
    }
2680
 
2681
    StopSound();
2682
    Terminate3DSounds();
2683
}
2684
 
5198 hendricks2 2685
void EndGameSequence(void)
5196 hendricks2 2686
{
5198 hendricks2 2687
    SWBOOL anim_ok = TRUE;
5196 hendricks2 2688
    FadeOut(0, 5);
2689
 
2690
    if ((gs.ParentalLock || Global_PLock) && FinishAnim == ANIM_SUMO)
2691
        anim_ok = FALSE;
2692
 
2693
    if (anim_ok)
2694
        playanm(FinishAnim);
2695
 
8694 ny00123 2696
    BonusScreen();
5196 hendricks2 2697
 
2698
    ExitLevel = FALSE;
2699
    QuitFlag = FALSE;
2700
    AutoNet = FALSE;
2701
 
2702
    if (FinishAnim == ANIM_ZILLA)
2703
        CreditsLevel();
2704
 
2705
    ExitLevel = FALSE;
2706
    QuitFlag = FALSE;
2707
    AutoNet = FALSE;
2708
 
2709
    if (SW_SHAREWARE)
2710
    {
2711
        Level = 0;
2712
    }
2713
    else
2714
    {
2715
        if (Level == 4 || Level == 20)
2716
        {
2717
            Level=0;
2718
        }
2719
        else
2720
            Level++;
2721
    }
2722
}
2723
 
5198 hendricks2 2724
void
5196 hendricks2 2725
StatScreen(PLAYERp mpp)
2726
{
5198 hendricks2 2727
    extern SWBOOL FinishedLevel;
5196 hendricks2 2728
    short w,h;
2729
 
2730
    short rows,cols,i,j;
2731
    PLAYERp pp = NULL;
2732
    int x,y;
2733
    short death_total[MAX_SW_PLAYERS_REG];
2734
    short kills[MAX_SW_PLAYERS_REG];
2735
    short pal;
2736
 
2737
#define STAT_START_X 20
2738
#define STAT_START_Y 85
2739
#define STAT_OFF_Y 9
2740
#define STAT_HEADER_Y 14
2741
 
2742
#define SM_SIZ(num) ((num)*4)
2743
 
2744
#define STAT_TABLE_X (STAT_START_X + SM_SIZ(15))
2745
#define STAT_TABLE_XOFF SM_SIZ(6)
2746
 
2747
    // No stats in bot games
2748
    //if (BotMode) return;
2749
 
2750
    ResetPalette(mpp);
2751
    COVER_SetReverb(0); // Reset reverb
2752
    StopSound();
2753
 
2754
    if (FinishAnim)
2755
    {
2756
        EndGameSequence();
2757
        return;
2758
    }
2759
 
2760
    if (gNet.MultiGameType != MULTI_GAME_COMMBAT)
2761
    {
2762
        if (!FinishedLevel)
2763
            return;
8694 ny00123 2764
        BonusScreen();
5196 hendricks2 2765
        return;
2766
    }
2767
 
7509 hendricks2 2768
    renderFlushPerms();
5196 hendricks2 2769
    DrawStatScreen();
2770
 
2771
    memset(death_total,0,sizeof(death_total));
2772
    memset(kills,0,sizeof(kills));
2773
 
2774
    sprintf(ds,"MULTIPLAYER TOTALS");
2775
    MNU_MeasureString(ds, &w, &h);
2776
    MNU_DrawString(TEXT_TEST_COL(w), 68, ds, 0, 0);
2777
 
2778
    sprintf(ds,"PRESS SPACE BAR TO CONTINUE");
2779
    MNU_MeasureString(ds, &w, &h);
2780
    MNU_DrawString(TEXT_TEST_COL(w), 189, ds, 0, 0);
2781
 
2782
    x = STAT_START_X;
2783
    y = STAT_START_Y;
2784
 
2785
    sprintf(ds,"  NAME         1     2     3     4     5     6     7    8     KILLS");
2786
    DisplayMiniBarSmString(mpp, x, y, 0, ds);
2787
    rows = OrigCommPlayers;
2788
    cols = OrigCommPlayers;
2789
    mpp = Player + myconnectindex;
2790
 
2791
    y += STAT_HEADER_Y;
2792
 
2793
    for (i = 0; i < rows; i++)
2794
    {
2795
        x = STAT_START_X;
2796
        pp = Player + i;
2797
 
2798
        sprintf(ds,"%d", i+1);
2799
        DisplayMiniBarSmString(mpp, x, y, 0, ds);
2800
 
2801
        sprintf(ds,"  %-13s", pp->PlayerName);
8749 ny00123 2802
        DisplayMiniBarSmString(mpp, x, y, PALETTE_PLAYER0 + pp->TeamColor, ds);
5196 hendricks2 2803
 
2804
        x = STAT_TABLE_X;
2805
        for (j = 0; j < cols; j++)
2806
        {
2807
            pal = 0;
2808
            death_total[j] += pp->KilledPlayer[j];
2809
 
2810
            if (i == j)
2811
            {
2812
                // don't add kill for self or team player
2813
                pal = PALETTE_PLAYER0 + 4;
2814
                kills[i] -= pp->KilledPlayer[j];  // subtract self kills
2815
            }
2816
            else if (gNet.TeamPlay)
2817
            {
8749 ny00123 2818
                if (pp->TeamColor == Player[j].TeamColor)
5196 hendricks2 2819
                {
2820
                    // don't add kill for self or team player
2821
                    pal = PALETTE_PLAYER0 + 4;
2822
                    kills[i] -= pp->KilledPlayer[j];  // subtract self kills
2823
                }
2824
                else
2825
                    kills[i] += pp->KilledPlayer[j];  // kills added here
2826
            }
2827
            else
2828
            {
2829
                kills[i] += pp->KilledPlayer[j];  // kills added here
2830
            }
2831
 
2832
            sprintf(ds,"%d", pp->KilledPlayer[j]);
2833
            DisplayMiniBarSmString(mpp, x, y, pal, ds);
2834
            x += STAT_TABLE_XOFF;
2835
        }
2836
 
2837
        y += STAT_OFF_Y;
2838
    }
2839
 
2840
 
2841
    // Deaths
2842
 
2843
    x = STAT_START_X;
2844
    y += STAT_OFF_Y;
2845
 
2846
    sprintf(ds,"   DEATHS");
2847
    DisplayMiniBarSmString(mpp, x, y, 0, ds);
2848
    x = STAT_TABLE_X;
2849
 
2850
    for (j = 0; j < cols; j++)
2851
    {
2852
        sprintf(ds,"%d",death_total[j]);
2853
        DisplayMiniBarSmString(mpp, x, y, 0, ds);
2854
        x += STAT_TABLE_XOFF;
2855
    }
2856
 
2857
    x = STAT_START_X;
2858
    y += STAT_OFF_Y;
2859
 
2860
    // Kills
2861
    x = STAT_TABLE_X + SM_SIZ(50);
2862
    y = STAT_START_Y + STAT_HEADER_Y;
2863
 
2864
    for (i = 0; i < rows; i++)
2865
    {
2866
        pp = Player + i;
2867
 
2868
        sprintf(ds,"%d", kills[i]); //pp->Kills);
2869
        DisplayMiniBarSmString(mpp, x, y, 0, ds);
2870
 
2871
        y += STAT_OFF_Y;
2872
    }
2873
 
7509 hendricks2 2874
    videoNextPage();
5196 hendricks2 2875
 
2876
    if (KeyPressed())
2877
    {
8748 ny00123 2878
        while (KeyPressed() && !quitevent) { handleevents(); getpackets(); }
5196 hendricks2 2879
    }
2880
 
2881
    KEY_PRESSED(KEYSC_SPACE) = 0;
2882
    KEY_PRESSED(KEYSC_ENTER) = 0;
2883
 
2884
    if (gs.MusicOn)
2885
    {
2886
        PlaySong(voc[DIGI_ENDLEV].name, 3, TRUE, TRUE);
2887
    }
2888
 
2889
    while (!KEY_PRESSED(KEYSC_SPACE) && !KEY_PRESSED(KEYSC_ENTER))
2890
    {
2891
        handleevents();
8747 ny00123 2892
        getpackets();
5196 hendricks2 2893
        ScreenCaptureKeys();
2894
    }
2895
 
2896
    StopSound();
2897
    Terminate3DSounds();
2898
}
2899
 
5198 hendricks2 2900
void
2901
GameIntro(void)
5196 hendricks2 2902
{
2903
 
2904
    DSPRINTF(ds,"GameIntro...");
2905
    MONO_PRINT(ds);
2906
 
2907
    if (DemoPlaying)
2908
        return;
2909
 
2910
    // this could probably be taken out and you could select skill level
2911
    // from menu to start the game
2912
    if (!CommEnabled && UserMapName[0])
2913
        return;
2914
 
2915
    Level = 1;
2916
 
2917
 
2918
 
8271 hendricks2 2919
    PlayTheme();
5196 hendricks2 2920
 
2921
    if (!AutoNet)
2922
    {
2923
        LogoLevel();
2924
        //CreditsLevel();
2925
        //SceneLevel();
2926
        //TitleLevel();
2927
        IntroAnimLevel();
2928
        IntroAnimCount = 0;
2929
    }
2930
 
2931
    MenuLevel();
2932
}
2933
 
5198 hendricks2 2934
void
5552 hendricks2 2935
Control(int32_t argc, char const * const * argv)
5196 hendricks2 2936
{
2937
 
5206 hendricks2 2938
    InitGame(argc, argv);
8704 ny00123 2939
    if (QuitFlag)
2940
        return;
5196 hendricks2 2941
 
2942
    MONO_PRINT("InitGame done");
2943
    MNU_InitMenus();
2944
    InGame = TRUE;
2945
    GameIntro();
2946
    //NewGame = TRUE;
2947
 
2948
    while (!QuitFlag)
2949
    {
2950
        handleevents();
2951
        OSD_DispatchQueued();
2952
 
2953
        if (quitevent) QuitFlag = TRUE;
2954
 
2955
        NewLevel();
2956
    }
2957
 
2958
    CleanExit = TRUE;
2959
    TerminateGame();
2960
}
2961
 
2962
 
2963
void
7499 hendricks2 2964
_Assert(const char *expr, const char *strFile, unsigned uLine)
5196 hendricks2 2965
{
8335 hendricks2 2966
    buildprintf(ds, "Assertion failed: %s %s, line %u", expr, strFile, uLine);
2967
    debug_break();
2968
 
5196 hendricks2 2969
    TerminateGame();
8335 hendricks2 2970
 
8482 hendricks2 2971
#if 1 /* defined RENDERTYPEWIN */
7553 hendricks2 2972
    wm_msgbox(apptitle, "%s", ds);
5196 hendricks2 2973
#else
2974
    printf("Assertion failed: %s\n %s, line %u\n", expr, strFile, uLine);
2975
#endif
2976
    exit(0);
2977
}
2978
 
2979
 
2980
void
7499 hendricks2 2981
_ErrMsg(const char *strFile, unsigned uLine, const char *format, ...)
5196 hendricks2 2982
{
2983
    va_list arglist;
2984
 
2985
    //DSPRINTF(ds, "Error: %s, line %u", strFile, uLine);
2986
    //MONO_PRINT(ds);
2987
    TerminateGame();
2988
 
8482 hendricks2 2989
#if 1 /* defined RENDERTYPEWIN */
5196 hendricks2 2990
    {
2991
        char msg[256], *p;
2992
        Bsnprintf(msg, sizeof(msg), "Error: %s, line %u\n", strFile, uLine);
2993
        p = &msg[strlen(msg)];
2994
        va_start(arglist, format);
2995
        Bvsnprintf(msg, sizeof(msg) - (p-msg), format, arglist);
2996
        va_end(arglist);
7553 hendricks2 2997
        wm_msgbox(apptitle, "%s", msg);
5196 hendricks2 2998
    }
2999
#else
3000
    printf("Error: %s, line %u\n", strFile, uLine);
3001
 
3002
    va_start(arglist, format);
3003
    vprintf(format, arglist);
3004
    va_end(arglist);
3005
#endif
3006
 
3007
    exit(0);
3008
}
3009
 
3010
void
3011
dsprintf(char *str, char *format, ...)
3012
{
3013
    va_list arglist;
3014
 
3015
    va_start(arglist, format);
3016
    vsprintf(str, format, arglist);
3017
    va_end(arglist);
3018
}
3019
 
3020
void
7499 hendricks2 3021
dsprintf_null(char *str, const char *format, ...)
5196 hendricks2 3022
{
3023
    va_list arglist;
3024
}
3025
 
3026
void MoveLoop(void)
3027
{
3028
    int pnum;
3029
 
3030
    getpackets();
3031
 
3032
    if (PredictionOn && CommEnabled)
3033
    {
3034
        while (predictmovefifoplc < Player[myconnectindex].movefifoend)
3035
        {
3036
            DoPrediction(ppp);
3037
        }
3038
    }
3039
 
3040
    //While you have new input packets to process...
3041
    if (!CommEnabled)
3042
        bufferjitter = 0;
3043
 
3044
    while (Player[myconnectindex].movefifoend - movefifoplc > bufferjitter)
3045
    {
3046
        //Make sure you have at least 1 packet from everyone else
3047
        for (pnum=connecthead; pnum>=0; pnum=connectpoint2[pnum])
3048
        {
3049
            if (movefifoplc == Player[pnum].movefifoend)
3050
            {
3051
                break;
3052
            }
3053
        }
3054
 
3055
        //Pnum is >= 0 only if last loop was broken, meaning a player wasn't caught up
3056
        if (pnum >= 0)
3057
            break;
3058
 
3059
        domovethings();
3060
 
3061
#if DEBUG
3062
        //if (DemoSyncRecord)
3063
        //    demosync_record();
3064
#endif
3065
    }
3066
 
3067
    if (!InputMode && !PauseKeySet)
3068
        MNU_CheckForMenus();
3069
}
3070
 
3071
 
3072
void InitPlayerGameSettings(void)
3073
{
3074
    int pnum;
3075
 
3076
    // don't jack with auto aim settings if DemoMode is going
3077
    // what the hell did I do this for?????????
3078
    //if (DemoMode)
3079
    //    return;
3080
 
3081
    if (CommEnabled)
3082
    {
3083
        // everyone gets the same Auto Aim
3084
        TRAVERSE_CONNECT(pnum)
3085
        {
3086
            if (gNet.AutoAim)
3087
                SET(Player[pnum].Flags, PF_AUTO_AIM);
3088
            else
3089
                RESET(Player[pnum].Flags, PF_AUTO_AIM);
3090
        }
3091
    }
3092
    else
3093
    {
3094
        if (gs.AutoAim)
3095
            SET(Player[myconnectindex].Flags, PF_AUTO_AIM);
3096
        else
3097
            RESET(Player[myconnectindex].Flags, PF_AUTO_AIM);
3098
    }
3099
 
3100
    // everyone had their own Auto Run
3101
    if (gs.AutoRun)
3102
        SET(Player[myconnectindex].Flags, PF_LOCK_RUN);
3103
    else
3104
        RESET(Player[myconnectindex].Flags, PF_LOCK_RUN);
3105
 
<