Subversion Repositories eduke32

Rev

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

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