Subversion Repositories eduke32

Rev

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

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