Subversion Repositories eduke32

Rev

Rev 5226 | Rev 5352 | 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"
62
#include "net.h"
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
5206 hendricks2 909
InitGame(int32_t argc, const char **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
 
5217 hendricks2 1035
    for (i=0; i < g_defModulesNum; ++i)
1036
        Bfree(g_defModules[i]);
1037
    Bfree(g_defModules);
1038
    g_defModules = NULL;
1039
 
5345 hendricks2 1040
    if (E_PostInit())
1041
        SW_FatalEngineError();
1042
 
5196 hendricks2 1043
    DemoModeMenuInit = TRUE;
1044
    // precache as much stuff as you can
1045
    if (UserMapName[0] == '\0')
1046
    {
1047
        AnimateCacheCursor();
1048
        LoadLevel("$dozer.map");
1049
        AnimateCacheCursor();
1050
        SetupPreCache();
1051
        DoTheCache();
1052
    }
1053
    else
1054
    {
1055
        AnimateCacheCursor();
1056
        LoadLevel(UserMapName);
1057
        AnimateCacheCursor();
1058
        SetupPreCache();
1059
        DoTheCache();
1060
    }
1061
 
1062
    Set_GameMode();
1063
    GraphicsMode = TRUE;
1064
    SetupAspectRatio();
1065
 
1066
    COVERsetbrightness(gs.Brightness,&palette_data[0][0]);
1067
 
1068
    InitFX();   // JBF: do it down here so we get a hold of the window handle
1069
    InitMusic();
1070
 
1071
}
1072
 
1073
 
1074
/*
1075
Directory of C:\DEV\SW\MIDI
1076
EXECUT11 MID
1077
HROSHMA6 MID
1078
HOSHIA02 MID
1079
INTRO131 MID
1080
KOTEC2   MID
1081
KOTOKI12 MID
1082
NIPPON34 MID
1083
NOKI41   MID
1084
SANAI    MID
1085
SIANRA23 MID
1086
TKYO2007 MID
1087
TYTAIK16 MID
1088
YOKOHA03 MID
1089
*/
1090
 
1091
char LevelSong[16];
1092
short SongLevelNum;
1093
//#ifndef SW_SHAREWARE
1094
LEVEL_INFO LevelInfo[MAX_LEVELS_REG+2] =
1095
{
1096
    {"title.map",      "theme.mid", " ", " ", " "  },
1097
    {"$bullet.map",    "e1l01.mid", "Seppuku Station", "0 : 55", "5 : 00"  },
1098
    {"$dozer.map",     "e1l03.mid", "Zilla Construction", "4 : 59", "8 : 00"  },
1099
    {"$shrine.map",    "e1l02.mid", "Master Leep's Temple", "3 : 16", "10 : 00"  },
1100
    {"$woods.map",     "e1l04.mid", "Dark Woods of the Serpent", "7 : 06", "16 : 00"  },
1101
    {"$whirl.map",     "yokoha03.mid", "Rising Son", "5 : 30", "10 : 00"   },
1102
    {"$tank.map",      "nippon34.mid", "Killing Fields", "1 : 46", "4 : 00"   },
1103
    {"$boat.map",      "execut11.mid", "Hara-Kiri Harbor", "1 : 56", "4 : 00"   },
1104
    {"$garden.map",    "execut11.mid", "Zilla's Villa", "1 : 06", "2 : 00"   },
1105
    {"$outpost.map",   "sanai.mid",    "Monastery", "1 : 23", "3 : 00"      },
1106
    {"$hidtemp.map",   "kotec2.mid",   "Raider of the Lost Wang", "2 : 05", "4 : 10"     },
1107
    {"$plax1.map",     "kotec2.mid",   "Sumo Sky Palace", "6 : 32", "12 : 00"     },
1108
    {"$bath.map",      "yokoha03.mid", "Bath House", "10 : 00", "10 : 00"   },
1109
    {"$airport.map",   "nippon34.mid", "Unfriendly Skies", "2 : 59", "6 : 00"   },
1110
    {"$refiner.map",   "kotoki12.mid", "Crude Oil", "2 : 40", "5 : 00"   },
1111
    {"$newmine.map",   "hoshia02.mid", "Coolie Mines", "2 : 48", "6 : 00"   },
1112
    {"$subbase.map",   "hoshia02.mid", "Subpen 7", "2 : 02", "4 : 00"   },
1113
    {"$rock.map",      "kotoki12.mid", "The Great Escape", "3 : 18", "6 : 00"   },
1114
    {"$yamato.map",    "sanai.mid",    "Floating Fortress", "11 : 38", "20 : 00"      },
1115
    {"$seabase.map",   "kotec2.mid",   "Water Torture", "5 : 07", "10 : 00"     },
1116
    {"$volcano.map",   "kotec2.mid",   "Stone Rain", "9 : 15", "20 : 00"     },
1117
    {"$shore.map",     "kotec2.mid",   "Shanghai Shipwreck", "3 : 58", "8 : 00"     },
1118
    {"$auto.map",      "kotec2.mid",   "Auto Maul", "4 : 07", "8 : 00"     },
1119
    {"tank.map",       "kotec2.mid",   "Heavy Metal (DM only)", "10 : 00", "10 : 00"     },
1120
    {"$dmwoods.map",   "kotec2.mid",   "Ripper Valley (DM only)", "10 : 00", "10 : 00"     },
1121
    {"$dmshrin.map",   "kotec2.mid",   "House of Wang (DM only)", "10 : 00", "10 : 00"     },
1122
    {"$rush.map",      "kotec2.mid",   "Lo Wang Rally (DM only)", "10 : 00", "10 : 00"     },
1123
    {"shotgun.map",    "kotec2.mid",   "Ruins of the Ronin (CTF)", "10 : 00", "10 : 00"     },
1124
    {"$dmdrop.map",    "kotec2.mid",   "Killing Fields (CTF)", "10 : 00", "10 : 00"     },
1125
    {NULL, NULL, NULL, NULL, NULL}
1126
};
1127
/*#else
1128
LEVEL_INFO LevelInfo[MAX_LEVELS+2] =  // Shareware
1129
    {
1130
    {"title.map",      "theme.mid", " ", " ", " "  },
1131
    {"$bullet.map",    "e1l01.mid", "Seppuku Station", "0 : 55", "5 : 00"  },
1132
    {"$dozer.map",     "e1l03.mid", "Zilla Construction", "4 : 59", "8 : 00"  },
1133
    {"$shrine.map",    "e1l02.mid", "Master Leep's Temple", "3 : 16", "10 : 00"  },
1134
    {"$woods.map",     "e1l04.mid", "Dark Woods of the Serpent", "7 : 06", "16 : 00"  },
1135
    {NULL, NULL, NULL, NULL, NULL}
1136
    };
1137
#endif*/
1138
 
1139
char EpisodeNames[2][MAX_EPISODE_NAME_LEN+2] =
1140
{
1141
    "^Enter the Wang",
1142
    "^Code of Honor"
1143
};
1144
char EpisodeSubtitles[2][MAX_EPISODE_SUBTITLE_LEN+1] =
1145
{
1146
    "Four levels (Shareware Version)",
1147
    "Eighteen levels (Full Version Only)"
1148
};
1149
char SkillNames[4][MAX_SKILL_NAME_LEN+2] =
1150
{
1151
    "^Tiny grasshopper",
1152
    "^I Have No Fear",
1153
    "^Who Wants Wang",
1154
    "^No Pain, No Gain"
1155
};
1156
 
5198 hendricks2 1157
void InitNewGame(void)
5196 hendricks2 1158
{
1159
    int i, ready_bak;
1160
    int ver_bak;
1161
 
1162
    //waitforeverybody();           // since ready flag resets after this point, need to carefully sync
1163
 
1164
    for (i = 0; i < MAX_SW_PLAYERS; i++)
1165
    {
1166
        // don't jack with the playerreadyflag
1167
        ready_bak = Player[i].playerreadyflag;
1168
        ver_bak = Player[i].PlayerVersion;
1169
        memset(&Player[i], 0, sizeof(Player[i]));
1170
        Player[i].playerreadyflag = ready_bak;
1171
        Player[i].PlayerVersion = ver_bak;
1172
        INITLIST(&Player[i].PanelSpriteList);
1173
    }
1174
 
1175
    memset(puser, 0, sizeof(puser));
1176
}
1177
 
1178
void FindLevelInfo(char *map_name, short *level)
1179
{
1180
    char *ptr;
1181
    char buff[16];
1182
    short i,j;
1183
 
1184
    for (j = 1; j <= MAX_LEVELS; j++)
1185
    {
1186
        if (LevelInfo[j].LevelName)
1187
        {
1188
            if (Bstrcasecmp(map_name, LevelInfo[j].LevelName) == 0)
1189
            {
1190
                *level = j;
1191
                return;
1192
            }
1193
        }
1194
    }
1195
 
1196
    *level = 0;
1197
    return;
1198
}
1199
 
1200
int ChopTics;
5198 hendricks2 1201
void InitLevelGlobals(void)
5196 hendricks2 1202
{
1203
    extern char PlayerGravity;
1204
    extern short wait_active_check_offset;
1205
    //extern short Zombies;
1206
    extern int PlaxCeilGlobZadjust, PlaxFloorGlobZadjust;
5198 hendricks2 1207
    extern SWBOOL left_foot;
1208
    extern SWBOOL serpwasseen;
1209
    extern SWBOOL sumowasseen;
1210
    extern SWBOOL zillawasseen;
5196 hendricks2 1211
    extern short BossSpriteNum[3];
1212
 
1213
    // A few IMPORTANT GLOBAL RESETS
1214
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1
1215
    MapSetup();
1216
    //Zombies = 0;
1217
    ChopTics = 0;
1218
    dimensionmode = 3;
1219
    zoom = 768;
1220
    PlayerGravity = 24;
1221
    wait_active_check_offset = 0;
1222
    PlaxCeilGlobZadjust = PlaxFloorGlobZadjust = Z(500);
1223
    FinishedLevel = FALSE;
1224
    AnimCnt = 0;
1225
    left_foot = FALSE;
1226
    screenpeek = myconnectindex;
1227
 
1228
    gNet.TimeLimitClock = gNet.TimeLimit;
1229
 
1230
    serpwasseen = FALSE;
1231
    sumowasseen = FALSE;
1232
    zillawasseen = FALSE;
1233
    memset(BossSpriteNum,-1,sizeof(BossSpriteNum));
1234
}
1235
 
5198 hendricks2 1236
void InitLevelGlobals2(void)
5196 hendricks2 1237
{
1238
    extern short Bunny_Count;
1239
    // GLOBAL RESETS NOT DONE for LOAD GAME
1240
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1241
    InitTimingVars();
1242
    TotalKillable = 0;
1243
    Bunny_Count = 0;
1244
}
1245
 
5198 hendricks2 1246
void
1247
InitLevel(void)
5196 hendricks2 1248
{
1249
    static int DemoNumber = 0;
1250
 
1251
    MONO_PRINT("InitLevel");
1252
    Terminate3DSounds();
1253
 
1254
    // A few IMPORTANT GLOBAL RESETS
1255
    InitLevelGlobals();
1256
    MONO_PRINT("InitLevelGlobals");
1257
    if (!DemoMode)
1258
        StopSong();
1259
 
1260
    if (LoadGameOutsideMoveLoop)
1261
    {
1262
        MONO_PRINT("Returning from InitLevel");
1263
        return;
1264
    }
1265
 
1266
    InitLevelGlobals2();
1267
    MONO_PRINT("InitLevelGlobals2");
1268
    if (DemoMode)
1269
    {
1270
        Level = 0;
1271
        NewGame = TRUE;
1272
        DemoInitOnce = FALSE;
1273
        strcpy(DemoFileName, DemoName[DemoNumber]);
1274
        DemoNumber++;
1275
        if (!DemoName[DemoNumber][0])
1276
            DemoNumber = 0;
1277
 
1278
        // read header and such
1279
        DemoPlaySetup();
1280
 
1281
        strcpy(LevelName, DemoLevelName);
1282
 
1283
        FindLevelInfo(LevelName, &Level);
1284
        if (Level > 0)
1285
        {
1286
            strcpy(LevelSong, LevelInfo[Level].SongName);
1287
            strcpy(LevelName, LevelInfo[Level].LevelName);
1288
            UserMapName[0] = '\0';
1289
        }
1290
        else
1291
        {
1292
            strcpy(UserMapName, DemoLevelName);
1293
            Level = 0;
1294
        }
1295
 
1296
    }
1297
    else
1298
    {
1299
        if (Level < 0)
1300
            Level = 0;
1301
 
1302
        if (Level > MAX_LEVELS)
1303
            Level = 1;
1304
 
1305
        // extra code in case something is resetting these values
1306
        if (NewGame)
1307
        {
1308
            //Level = 1;
1309
            //DemoPlaying = FALSE;
1310
            DemoMode = FALSE;
1311
            //DemoRecording = FALSE;
1312
            //DemoEdit = FALSE;
1313
        }
1314
 
1315
        if (UserMapName[0])
1316
        {
1317
            strcpy(LevelName, UserMapName);
1318
 
1319
            Level = 0;
1320
            FindLevelInfo(UserMapName, &Level);
1321
 
1322
            if (Level > 0)
1323
            {
1324
                // user map is part of game - treat it as such
1325
                strcpy(LevelSong, LevelInfo[Level].SongName);
1326
                strcpy(LevelName, LevelInfo[Level].LevelName);
1327
                UserMapName[0] = '\0';
1328
            }
1329
        }
1330
        else
1331
        {
1332
            strcpy(LevelName, LevelInfo[Level].LevelName);
1333
            strcpy(LevelSong, LevelInfo[Level].SongName);
1334
        }
1335
    }
1336
 
1337
    PlayingLevel = Level;
1338
 
1339
    if (NewGame)
1340
        InitNewGame();
1341
 
1342
    LoadingLevelScreen(LevelName);
1343
    MONO_PRINT("LoadintLevelScreen");
1344
    if (!DemoMode && !DemoInitOnce)
1345
        DemoPlaySetup();
1346
 
1347
    LoadLevel(LevelName);
1348
 
1349
    if (Bstrcasecmp(CacheLastLevel, LevelName) != 0)
1350
        // clears gotpic and does some bit setting
1351
        SetupPreCache();
1352
    else
1353
        memset(gotpic,0,sizeof(gotpic));
1354
 
1355
    if (sector[0].extra != -1)
1356
    {
5207 hendricks2 1357
        NormalVisibility = g_visibility = sector[0].extra;
5196 hendricks2 1358
        sector[0].extra = 0;
1359
    }
1360
    else
5207 hendricks2 1361
        NormalVisibility = g_visibility;
5196 hendricks2 1362
 
1363
    //
1364
    // Do Player stuff first
1365
    //
1366
 
1367
    InitAllPlayers();
1368
 
1369
#if DEBUG
1370
    // fake Multi-player game setup
1371
    if (FakeMultiNumPlayers && !BotMode)
1372
    {
5198 hendricks2 1373
        uint8_t i;
5196 hendricks2 1374
 
1375
        // insert all needed players except the first one - its already tere
1376
        for (i = 0; i < FakeMultiNumPlayers - 1; i++)
1377
        {
1378
            ManualPlayerInsert(Player);
1379
            // reset control back to 1st player
1380
            myconnectindex = 0;
1381
            screenpeek = 0;
1382
        }
1383
    }
1384
#endif
1385
 
1386
    // Put in the BOTS if called for
1387
    if (FakeMultiNumPlayers && BotMode)
1388
    {
5198 hendricks2 1389
        uint8_t i;
5196 hendricks2 1390
 
1391
        // insert all needed players except the first one - its already tere
1392
        for (i = 0; i < FakeMultiNumPlayers; i++)
1393
        {
1394
            BotPlayerInsert(Player);
1395
            // reset control back to 1st player
1396
            myconnectindex = 0;
1397
            screenpeek = 0;
1398
        }
1399
    }
1400
 
1401
    QueueReset();
1402
    PreMapCombineFloors();
1403
    InitMultiPlayerInfo();
1404
    InitAllPlayerSprites();
1405
 
1406
    //
1407
    // Do setup for sprite, track, panel, sector, etc
1408
    //
1409
 
1410
    // Set levels up
1411
    InitTimingVars();
1412
 
1413
    SpriteSetup();
1414
    SpriteSetupPost(); // post processing - already gone once through the loop
1415
    InitLighting();
1416
 
1417
    TrackSetup();
1418
 
1419
    PlayerPanelSetup();
1420
    MapSetup();
1421
    SectorSetup();
1422
    JS_InitMirrors();
1423
    JS_InitLockouts();   // Setup the lockout linked lists
1424
    JS_ToggleLockouts(); // Init lockouts on/off
1425
 
1426
    PlaceSectorObjectsOnTracks();
1427
    PlaceActorsOnTracks();
1428
    PostSetupSectorObject();
1429
    SetupMirrorTiles();
1430
    initlava();
1431
 
1432
    SongLevelNum = Level;
1433
 
1434
    if (DemoMode)
1435
    {
1436
        DisplayDemoText();
1437
    }
1438
 
1439
 
1440
    if (ArgCheat)
1441
    {
5198 hendricks2 1442
        SWBOOL bak = gs.Messages;
5196 hendricks2 1443
        gs.Messages = FALSE;
1444
        EveryCheatToggle(&Player[0],NULL);
1445
        gs.Messages = bak;
1446
        GodMode = TRUE;
1447
    }
1448
 
1449
    // reset NewGame
1450
    NewGame = FALSE;
1451
 
1452
    DSPRINTF(ds,"End of InitLevel...");
1453
    MONO_PRINT(ds);
1454
 
1455
#if 0
1456
#if DEBUG
1457
    if (!cansee(43594, -92986, 0x3fffffff, 290,
1458
                43180, -91707, 0x3fffffff, 290))
1459
    {
1460
        DSPRINTF(ds,"cansee failed");
1461
        MONO_PRINT(ds);
1462
    }
1463
#endif
1464
#endif
1465
 
1466
}
1467
 
1468
 
5198 hendricks2 1469
void
1470
TerminateLevel(void)
5196 hendricks2 1471
{
5198 hendricks2 1472
    void pClearSpriteList(PLAYERp pp);
5196 hendricks2 1473
    int i, nexti, stat, pnum, ndx;
1474
    SECT_USERp *sectu;
1475
 
1476
//HEAP_CHECK();
1477
 
1478
    DemoTerm();
1479
 
1480
    // Free any track points
1481
    for (ndx = 0; ndx < MAX_TRACKS; ndx++)
1482
    {
1483
        if (Track[ndx].TrackPoint)
1484
        {
1485
            FreeMem(Track[ndx].TrackPoint);
1486
            // !JIM! I added null assigner
1487
            Track[ndx].TrackPoint = NULL;
1488
        }
1489
    }
1490
 
1491
    // Clear the tracks
1492
    memset(Track, 0, sizeof(Track));
1493
 
1494
    StopSound();
1495
    Terminate3DSounds();        // Kill the 3d sounds linked list
1496
    //ClearSoundLocks();
1497
 
1498
    // Clear all anims and any memory associated with them
1499
    // Clear before killing sprites - save a little time
1500
    //AnimClear();
1501
 
1502
    for (stat = STAT_PLAYER0; stat < STAT_PLAYER0 + numplayers; stat++)
1503
    {
1504
 
1505
        pnum = stat - STAT_PLAYER0;
1506
 
1507
        TRAVERSE_SPRITE_STAT(headspritestat[stat], i, nexti)
1508
        {
1509
            if (User[i])
1510
                memcpy(&puser[pnum], User[i], sizeof(USER));
1511
        }
1512
    }
1513
 
1514
    // Kill User memory and delete sprites
1515
    // for (stat = 0; stat < STAT_ALL; stat++)
1516
    for (stat = 0; stat < MAXSTATUS; stat++)
1517
    {
1518
        TRAVERSE_SPRITE_STAT(headspritestat[stat], i, nexti)
1519
        {
1520
            KillSprite(i);
1521
        }
1522
    }
1523
 
1524
    // Free SectUser memory
1525
    for (sectu = &SectUser[0];
1526
         sectu < &SectUser[MAXSECTORS];
1527
         sectu++)
1528
    {
1529
        if (*sectu)
1530
        {
1531
            ////DSPRINTF(ds,"Sect User Free %d",sectu-SectUser);
1532
            //MONO_PRINT(ds);
1533
            FreeMem(*sectu);
1534
            *sectu = NULL;
1535
        }
1536
    }
1537
 
1538
    //memset(&User[0], 0, sizeof(User));
1539
    memset(&SectUser[0], 0, sizeof(SectUser));
1540
 
1541
    TRAVERSE_CONNECT(pnum)
1542
    {
1543
        PLAYERp pp = Player + pnum;
1544
 
1545
        // Free panel sprites for players
1546
        pClearSpriteList(pp);
1547
 
1548
        pp->DoPlayerAction = NULL;
1549
 
1550
        pp->SpriteP = NULL;
1551
        pp->PlayerSprite = -1;
1552
 
1553
        pp->UnderSpriteP = NULL;
1554
        pp->PlayerUnderSprite = -1;
1555
 
1556
        memset(pp->HasKey, 0, sizeof(pp->HasKey));
1557
 
1558
        //pp->WpnFlags = 0;
1559
        pp->CurWpn = NULL;
1560
 
1561
        memset(pp->Wpn, 0, sizeof(pp->Wpn));
1562
        memset(pp->InventorySprite, 0, sizeof(pp->InventorySprite));
1563
        memset(pp->InventoryTics, 0, sizeof(pp->InventoryTics));
1564
 
1565
        pp->Killer = -1;
1566
 
1567
        INITLIST(&pp->PanelSpriteList);
1568
    }
1569
 
1570
    JS_UnInitLockouts();
1571
 
1572
//HEAP_CHECK();
1573
}
1574
 
5198 hendricks2 1575
void
1576
NewLevel(void)
5196 hendricks2 1577
{
1578
 
1579
    DSPRINTF(ds,"NewLevel");
1580
    MONO_PRINT(ds);
1581
 
1582
    if (DemoPlaying)
1583
    {
1584
        FX_SetVolume(0); // Shut the hell up while game is loading!
1585
        InitLevel();
1586
        InitRunLevel();
1587
 
1588
        DemoInitOnce = FALSE;
1589
        if (DemoMode)
1590
        {
1591
            if (DemoModeMenuInit)
1592
            {
1593
                DemoModeMenuInit = FALSE;
1594
                KEY_PRESSED(KEYSC_ESC) = TRUE;
1595
            }
1596
        }
1597
 
1598
        DemoPlayBack();
1599
 
1600
        if (DemoRecording && DemoEdit)
1601
        {
1602
            RunLevel();
1603
        }
1604
    }
1605
    else
1606
    {
1607
        DSPRINTF(ds,"Calling FX_SetVolume");
1608
        MONO_PRINT(ds);
1609
        FX_SetVolume(0); // Shut the hell up while game is loading!
1610
 
1611
        DSPRINTF(ds,"Calling InitLevel");
1612
        MONO_PRINT(ds);
1613
        InitLevel();
1614
 
1615
        DSPRINTF(ds,"Calling RunLevel");
1616
        MONO_PRINT(ds);
1617
        RunLevel();
1618
 
1619
        if (!QuitFlag)
1620
        {
1621
            // for good measure do this
1622
            ready2send = 0;
1623
            waitforeverybody();
1624
        }
1625
 
1626
        StatScreen(&Player[myconnectindex]);
1627
    }
1628
 
1629
    if (LoadGameFromDemo)
1630
        LoadGameFromDemo = FALSE;
1631
    else
1632
        TerminateLevel();
1633
 
1634
    InGame = FALSE;
1635
 
1636
    if (SW_SHAREWARE)
1637
    {
1638
        if (FinishAnim)
1639
            MenuLevel();
1640
    }
1641
    else
1642
    {
1643
        if (FinishAnim == ANIM_ZILLA || FinishAnim == ANIM_SERP)
1644
            MenuLevel();
1645
    }
1646
    FinishAnim = 0;
1647
}
1648
 
5198 hendricks2 1649
void
1650
ResetKeys(void)
5196 hendricks2 1651
{
1652
    int i;
1653
 
1654
    for (i = 0; i < MAXKEYBOARDSCAN; i++)
1655
    {
1656
        KEY_PRESSED(i) = 0;
1657
    }
1658
}
1659
 
5198 hendricks2 1660
SWBOOL
1661
KeyPressed(void)
5196 hendricks2 1662
{
1663
    int i;
1664
 
1665
    for (i = 0; i < MAXKEYBOARDSCAN; i++)
1666
    {
1667
        if (KEY_PRESSED(i))
1668
            return TRUE;
1669
    }
1670
 
1671
    return FALSE;
1672
}
1673
 
5198 hendricks2 1674
uint8_t*
1675
KeyPressedRange(uint8_t* kb, uint8_t* ke)
5196 hendricks2 1676
{
5198 hendricks2 1677
    uint8_t* k;
5196 hendricks2 1678
 
1679
    for (k = kb; k <= ke; k++)
1680
    {
1681
        if (*k)
1682
            return k;
1683
    }
1684
 
1685
    return NULL;
1686
}
1687
 
5198 hendricks2 1688
void
1689
ResetKeyRange(uint8_t* kb, uint8_t* ke)
5196 hendricks2 1690
{
5198 hendricks2 1691
    uint8_t* k;
5196 hendricks2 1692
 
1693
    for (k = kb; k <= ke; k++)
1694
    {
1695
        *k = 0;
1696
    }
1697
}
1698
 
1699
 
5198 hendricks2 1700
void
1701
LogoLevel(void)
5196 hendricks2 1702
{
1703
    char called;
1704
    int fin;
1705
    unsigned char backup_pal[256*3];
1706
    unsigned char pal[PAL_SIZE];
1707
    unsigned char tempbuf[256];
1708
    unsigned char *palook_bak = palookup[0];
1709
    UserInput uinfo = { FALSE, FALSE, dir_None };
1710
    int i;
1711
 
1712
 
1713
    DSPRINTF(ds,"LogoLevel...");
1714
    MONO_PRINT(ds);
1715
 
1716
    for (i = 0; i < 256; i++)
1717
        tempbuf[i] = i;
1718
    palookup[0] = tempbuf;
1719
 
1720
    DSPRINTF(ds,"Created palookup...");
1721
    MONO_PRINT(ds);
1722
 
1723
    // start music at logo
1724
    strcpy(LevelSong,"theme.mid");
1725
    PlaySong(LevelSong, RedBookSong[0], TRUE, TRUE);
1726
 
1727
    DSPRINTF(ds,"After music stuff...");
1728
    MONO_PRINT(ds);
1729
 
1730
    //GetPaletteFromVESA(pal);
1731
    //memcpy(backup_pal, pal, PAL_SIZE);
1732
 
1733
    DSPRINTF(ds,"Got Palette from VESA...");
1734
    MONO_PRINT(ds);
1735
 
1736
    // PreCache Anim
1737
    LoadAnm(0);
1738
 
1739
    if ((fin = kopen4load("3drealms.pal", 0)) != -1)
1740
    {
1741
        kread(fin, pal, PAL_SIZE);
1742
        kclose(fin);
1743
        setbrightness(gs.Brightness, pal, 2);
1744
    }
1745
    DSPRINTF(ds,"Just read in 3drealms.pal...");
1746
    MONO_PRINT(ds);
1747
 
1748
    //FadeOut(0, 0);
1749
    ready2send = 0;
1750
    totalclock = 0;
1751
    ototalclock = 0;
1752
 
1753
    DSPRINTF(ds,"About to display 3drealms pic...");
1754
    MONO_PRINT(ds);
1755
 
1756
    clearview(0);
1757
    rotatesprite(0, 0, RS_SCALE, 0, THREED_REALMS_PIC, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
1758
    nextpage();
1759
    //FadeIn(0, 3);
1760
 
1761
    ResetKeys();
1762
    while (TRUE)
1763
    {
1764
        handleevents();
1765
        CONTROL_GetUserInput(&uinfo);
1766
        CONTROL_ClearUserInput(&uinfo);
1767
        if (quitevent) { QuitFlag = TRUE; break; }
1768
 
1769
        // taken from top of faketimerhandler
1770
        // limits checks to max of 40 times a second
1771
        if (totalclock >= ototalclock + synctics)
1772
        {
1773
            ototalclock += synctics;
1774
        }
1775
 
1776
        if (totalclock > 5*120 || KeyPressed() || uinfo.button0 || uinfo.button1)
1777
        {
1778
            break;
1779
        }
1780
    }
1781
 
1782
    palookup[0] = palook_bak;
1783
 
1784
    clearview(0);
1785
    nextpage();
1786
    //SetPaletteToVESA(backup_pal);
1787
    setbrightness(gs.Brightness, &palette_data[0][0], 2);
1788
 
1789
    // put up a blank screen while loading
1790
 
1791
    DSPRINTF(ds,"End of LogoLevel...");
1792
    MONO_PRINT(ds);
1793
 
1794
}
1795
 
5198 hendricks2 1796
void
1797
CreditsLevel(void)
5196 hendricks2 1798
{
1799
    char called;
1800
    int fin;
1801
    int i;
1802
    int curpic;
1803
    int handle;
5198 hendricks2 1804
    uint32_t timer = 0;
5196 hendricks2 1805
    int zero=0;
1806
    short save;
1807
#define CREDITS1_PIC 5111
1808
#define CREDITS2_PIC 5118
1809
 
1810
    // put up a blank screen while loading
1811
 
1812
    // get rid of all PERM sprites!
1813
    flushperms();
1814
    save = gs.BorderNum;
1815
    SetBorder(Player + myconnectindex,0);
1816
    ClearStartMost();
1817
    gs.BorderNum = save;
1818
    clearview(0);
1819
    nextpage();
1820
 
1821
    // Lo Wang feel like singing!
1822
    handle = PlaySound(DIGI_JG95012,&zero,&zero,&zero,v3df_none);
1823
 
1824
    if (handle > 0)
1825
        while (FX_SoundActive(handle)) ;
1826
 
1827
    // try 14 then 2 then quit
1828
    if (!PlaySong(NULL, 14, FALSE, TRUE))
1829
    {
1830
        if (!PlaySong(NULL, 2, FALSE, TRUE))
1831
        {
1832
            handle = PlaySound(DIGI_NOLIKEMUSIC,&zero,&zero,&zero,v3df_none);
1833
            if (handle > 0)
1834
                while (FX_SoundActive(handle)) handleevents();
1835
            return;
1836
        }
1837
    }
1838
 
1839
    ready2send = 0;
1840
    totalclock = 0;
1841
    ototalclock = 0;
1842
 
1843
    ResetKeys();
1844
    curpic = CREDITS1_PIC;
1845
 
1846
    while (TRUE)
1847
    {
1848
        // taken from top of faketimerhandler
1849
        // limits checks to max of 40 times a second
1850
        if (totalclock >= ototalclock + synctics)
1851
        {
1852
            ototalclock += synctics;
1853
            timer += synctics;
1854
        }
1855
 
1856
        rotatesprite(0, 0, RS_SCALE, 0, curpic, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
1857
 
1858
        nextpage();
1859
 
1860
        if (timer > 8*120)
1861
        {
1862
            curpic = CREDITS2_PIC;
1863
        }
1864
 
1865
        if (timer > 16*120)
1866
        {
1867
            timer = 0;
1868
            curpic = CREDITS1_PIC;
1869
        }
1870
 
1871
 
1872
        if (!SongIsPlaying())
1873
            break;
1874
 
1875
        if (KEY_PRESSED(KEYSC_ESC))
1876
            break;
1877
    }
1878
 
1879
    // put up a blank screen while loading
1880
    clearview(0);
1881
    nextpage();
1882
    ResetKeys();
1883
    StopSong();
1884
}
1885
 
1886
 
5198 hendricks2 1887
void
1888
SybexScreen(void)
5196 hendricks2 1889
{
1890
    if (!SW_SHAREWARE) return;
1891
 
1892
    if (CommEnabled)
1893
        return;
1894
 
1895
    rotatesprite(0, 0, RS_SCALE, 0, 5261, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
1896
    nextpage();
1897
 
1898
    ResetKeys();
1899
    while (!KeyPressed() && !quitevent) handleevents();
1900
}
1901
 
1902
// CTW REMOVED
1903
/*
5198 hendricks2 1904
void
1905
TenScreen(void)
5196 hendricks2 1906
    {
1907
    char called;
1908
    int fin;
1909
    char backup_pal[256*3];
1910
    char pal[PAL_SIZE];
1911
    char tempbuf[256];
1912
    char *palook_bak = palookup[0];
1913
    int i;
5198 hendricks2 1914
    uint32_t bak;
5196 hendricks2 1915
    int bakready2send;
1916
 
1917
    if (CommEnabled)
1918
        return;
1919
 
1920
    bak = totalclock;
1921
 
1922
    flushperms();
1923
    clearview(0);
1924
    nextpage();
1925
 
1926
    for (i = 0; i < 256; i++)
1927
        tempbuf[i] = i;
1928
    palookup[0] = tempbuf;
1929
 
1930
    GetPaletteFromVESA(pal);
1931
    memcpy(backup_pal, pal, PAL_SIZE);
1932
 
1933
    if ((fin = kopen4load("ten.pal", 0)) != -1)
1934
        {
1935
        kread(fin, pal, PAL_SIZE);
1936
        kclose(fin);
1937
        }
1938
 
1939
    // palette to black
1940
    FadeOut(0, 0);
1941
    bakready2send = ready2send;
1942
    //totalclock = 0;
1943
    //ototalclock = 0;
1944
 
1945
    flushperms();
1946
    // draw it
1947
    rotatesprite(0, 0, RS_SCALE, 0, TEN_PIC, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
1948
    // bring to the front - still back palette
1949
    nextpage();
1950
    // set pal
1951
    SetPaletteToVESA(pal);
1952
    //FadeIn(0, 3);
1953
    ResetKeys();
1954
 
1955
    while (!KeyPressed());
1956
 
1957
    palookup[0] = palook_bak;
1958
 
1959
    clearview(0);
1960
    nextpage();
1961
    SetPaletteToVESA(backup_pal);
1962
 
1963
    // put up a blank screen while loading
1964
    clearview(0);
1965
    nextpage();
1966
 
1967
    ready2send = bakready2send;
1968
    totalclock = bak;
1969
    }
1970
*/
1971
// CTW REMOVED END
1972
 
5198 hendricks2 1973
void
1974
TitleLevel(void)
5196 hendricks2 1975
{
1976
    char called;
1977
    int fin;
1978
    unsigned char backup_pal[256*3];
1979
    unsigned char pal[PAL_SIZE];
1980
    unsigned char tempbuf[256];
1981
    unsigned char *palook_bak = palookup[0];
1982
    int i;
1983
 
1984
    for (i = 0; i < 256; i++)
1985
        tempbuf[i] = i;
1986
    palookup[0] = tempbuf;
1987
 
1988
    //GetPaletteFromVESA(pal);
1989
    //memcpy(backup_pal, pal, PAL_SIZE);
1990
 
1991
    clearview(0);
1992
    nextpage();
1993
 
1994
//    if ((fin = kopen4load("title.pal", 0)) != -1)
1995
//        {
1996
//        kread(fin, pal, PAL_SIZE);
1997
//        kclose(fin);
1998
//        SetPaletteToVESA(pal);
1999
//        }
2000
 
2001
//    clearview(0);
2002
//    nextpage();
2003
 
2004
    //FadeOut(0, 0);
2005
    ready2send = 0;
2006
    totalclock = 0;
2007
    ototalclock = 0;
2008
 
2009
    rotatesprite(0, 0, RS_SCALE, 0, TITLE_PIC, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2010
    nextpage();
2011
    //FadeIn(0, 3);
2012
 
2013
    ResetKeys();
2014
    while (TRUE)
2015
    {
2016
        handleevents();
2017
        OSD_DispatchQueued();
2018
 
2019
        // taken from top of faketimerhandler
2020
        // limits checks to max of 40 times a second
2021
        if (totalclock >= ototalclock + synctics)
2022
        {
2023
            //void MNU_CheckForMenusAnyKey( void );
2024
 
2025
            ototalclock += synctics;
2026
            //MNU_CheckForMenusAnyKey();
2027
        }
2028
 
2029
        //if (UsingMenus)
2030
        //    MNU_DrawMenu();
2031
 
2032
        //drawscreen as fast as you can
2033
        rotatesprite(0, 0, RS_SCALE, 0, TITLE_PIC, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2034
 
2035
        nextpage();
2036
 
2037
        if (totalclock > 5*120 || KeyPressed())
2038
        {
2039
            DemoMode = TRUE;
2040
            DemoPlaying = TRUE;
2041
            break;
2042
        }
2043
    }
2044
 
2045
    palookup[0] = palook_bak;
2046
 
2047
//    clearview(0);
2048
//    nextpage();
2049
    //SetPaletteToVESA(backup_pal);
2050
 
2051
    // put up a blank screen while loading
2052
//    clearview(0);
2053
//    nextpage();
2054
}
2055
 
2056
 
5198 hendricks2 2057
void DrawMenuLevelScreen(void)
5196 hendricks2 2058
{
2059
    flushperms();
2060
    clearview(0);
2061
    rotatesprite(0, 0, RS_SCALE, 0, TITLE_PIC, 20, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2062
}
2063
 
5198 hendricks2 2064
void DrawStatScreen(void)
5196 hendricks2 2065
{
2066
    flushperms();
2067
    clearview(0);
2068
    rotatesprite(0, 0, RS_SCALE, 0, STAT_SCREEN_PIC, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2069
}
2070
 
5198 hendricks2 2071
void DrawLoadLevelScreen(void)
5196 hendricks2 2072
{
2073
    flushperms();
2074
    clearview(0);
2075
    rotatesprite(0, 0, RS_SCALE, 0, TITLE_PIC, 20, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2076
}
2077
 
2078
short PlayerQuitMenuLevel = -1;
2079
 
5198 hendricks2 2080
void
2081
IntroAnimLevel(void)
5196 hendricks2 2082
{
2083
    DSPRINTF(ds,"IntroAnimLevel");
2084
    MONO_PRINT(ds);
2085
    playanm(0);
2086
}
2087
 
5198 hendricks2 2088
void
2089
MenuLevel(void)
5196 hendricks2 2090
{
5198 hendricks2 2091
    SWBOOL MNU_StartNetGame(void);
5196 hendricks2 2092
    char called;
2093
    int fin;
2094
    extern int totalclocklock;
2095
    short w,h;
2096
 
2097
    DSPRINTF(ds,"MenuLevel...");
2098
    MONO_PRINT(ds);
2099
 
2100
    if (gs.MusicOn)
2101
    {
2102
        PlaySong(NULL, RedBookSong[0], TRUE, FALSE);
2103
    }
2104
 
2105
    if (AutoNet)
2106
    {
2107
        DrawMenuLevelScreen();
2108
 
2109
        if (CommEnabled)
2110
        {
2111
            sprintf(ds,"Lo Wang is waiting for other players...");
2112
            MNU_MeasureString(ds, &w, &h);
2113
            MNU_DrawString(TEXT_TEST_COL(w), 170, ds, 1, 16);
2114
 
2115
            sprintf(ds,"They are afraid!");
2116
            MNU_MeasureString(ds, &w, &h);
2117
            MNU_DrawString(TEXT_TEST_COL(w), 180, ds, 1, 16);
2118
        }
2119
 
2120
        nextpage();
2121
 
2122
        waitforeverybody();
2123
        FirstTimeIntoGame = TRUE;
2124
        MNU_StartNetGame();
2125
        FirstTimeIntoGame = FALSE;
2126
        waitforeverybody();
2127
        ExitLevel = FALSE;
2128
        FinishedLevel = FALSE;
2129
        BorderAdjust = TRUE;
2130
        UsingMenus = FALSE;
2131
        InMenuLevel = FALSE;
2132
        return;
2133
    }
2134
 
2135
    // do demos only if not playing multi play
2136
    if (!CommEnabled && numplayers <= 1 && !FinishAnim && !NoDemoStartup)
2137
    {
2138
        // demos exist - do demo instead
2139
        if (DemoName[0][0] != '\0')
2140
        {
2141
            DemoMode = TRUE;
2142
            DemoPlaying = TRUE;
2143
            return;
2144
        }
2145
    }
2146
 
2147
    DemoMode = FALSE;
2148
    DemoPlaying = FALSE;
2149
 
2150
    clearview(0);
2151
    nextpage();
2152
 
2153
    //FadeOut(0, 0);
2154
    ready2send = 0;
2155
    totalclock = 0;
2156
    ototalclock = 0;
2157
    ExitLevel = FALSE;
2158
    InMenuLevel = TRUE;
2159
 
2160
    DrawMenuLevelScreen();
2161
 
2162
    if (CommEnabled)
2163
    {
2164
        sprintf(ds,"Lo Wang is waiting for other players...");
2165
        MNU_MeasureString(ds, &w, &h);
2166
        MNU_DrawString(TEXT_TEST_COL(w), 170, ds, 1, 16);
2167
 
2168
        sprintf(ds,"They are afraid!");
2169
        MNU_MeasureString(ds, &w, &h);
2170
        MNU_DrawString(TEXT_TEST_COL(w), 180, ds, 1, 16);
2171
    }
2172
 
2173
    nextpage();
2174
    //FadeIn(0, 3);
2175
 
2176
    waitforeverybody();
2177
 
2178
    // don't allow BorderAdjusting in these menus
2179
    BorderAdjust = FALSE;
2180
 
2181
    ResetKeys();
2182
 
2183
    if (SW_SHAREWARE)
2184
    {
2185
        // go to ordering menu only if shareware
2186
        if (FinishAnim)
2187
        {
2188
            KEY_PRESSED(KEYSC_ESC) = 1;
2189
            ControlPanelType = ct_ordermenu;
2190
            FinishAnim = 0;
2191
        }
2192
    }
2193
    else
2194
    {
2195
        FinishAnim = 0;
2196
    }
2197
 
2198
    while (TRUE)
2199
    {
2200
        handleevents();
2201
        OSD_DispatchQueued();
2202
 
2203
        if (quitevent) QuitFlag = TRUE;
2204
 
2205
        // taken from top of faketimerhandler
2206
        // limits checks to max of 40 times a second
2207
        if (totalclock >= ototalclock + synctics)
2208
        {
2209
            ototalclock += synctics;
2210
            MNU_CheckForMenusAnyKey();
2211
            if (CommEnabled)
2212
                getpackets();
2213
        }
2214
 
2215
        if (CommEnabled)
2216
        {
2217
            if (MultiPlayQuitFlag)
2218
            {
2219
                short pnum;
5198 hendricks2 2220
                uint8_t pbuf[1];
5196 hendricks2 2221
                QuitFlag = TRUE;
2222
                pbuf[0] = PACKET_TYPE_MENU_LEVEL_QUIT;
2223
                netbroadcastpacket(pbuf, 1);                      // TENSW
2224
                break;
2225
            }
2226
 
2227
            if (PlayerQuitMenuLevel >= 0)
2228
            {
2229
                MenuCommPlayerQuit(PlayerQuitMenuLevel);
2230
                PlayerQuitMenuLevel = -1;
2231
            }
2232
        }
2233
 
2234
        if (ExitLevel)
2235
        {
2236
            // Quiting Level
2237
            ExitLevel = FALSE;
2238
            break;
2239
        }
2240
 
2241
        if (QuitFlag)
2242
        {
2243
            // Quiting Game
2244
            break;
2245
        }
2246
 
2247
        // force the use of menus at all time
2248
        if (!UsingMenus && !ConPanel)
2249
        {
2250
            KEY_PRESSED(KEYSC_ESC) = TRUE;
2251
            MNU_CheckForMenusAnyKey();
2252
        }
2253
 
2254
        // must lock the clock for drawing so animations will happen
2255
        totalclocklock = totalclock;
2256
 
2257
        //drawscreen as fast as you can
2258
        DrawMenuLevelScreen();
2259
 
2260
        if (UsingMenus)
2261
            MNU_DrawMenu();
2262
 
2263
        nextpage();
2264
    }
2265
 
2266
    BorderAdjust = TRUE;
2267
    //LoadGameOutsideMoveLoop = FALSE;
2268
    KEY_PRESSED(KEYSC_ESC) = FALSE;
2269
    KB_ClearKeysDown();
2270
    //ExitMenus();
2271
    UsingMenus = FALSE;
2272
    InMenuLevel = FALSE;
2273
    clearview(0);
2274
    nextpage();
2275
}
2276
 
5198 hendricks2 2277
void
2278
SceneLevel(void)
5196 hendricks2 2279
{
5198 hendricks2 2280
    SWBOOL dp_bak;
2281
    SWBOOL dm_bak;
5196 hendricks2 2282
    FILE *fin;
2283
#define CINEMATIC_DEMO_FILE "$scene.dmo"
2284
 
2285
    // make sure it exists
2286
    if ((fin = fopen(CINEMATIC_DEMO_FILE,"rb")) == NULL)
2287
        return;
2288
    else
2289
        fclose(fin);
2290
 
2291
    strcpy(DemoFileName,CINEMATIC_DEMO_FILE);
2292
 
2293
    dp_bak = DemoPlaying;
2294
    dm_bak = DemoMode;
2295
 
2296
    DemoMode = TRUE;
2297
    DemoPlaying = TRUE;
2298
    DemoOverride = TRUE;
2299
    InitLevel();
2300
    DemoOverride = FALSE;
2301
 
2302
    ScenePlayBack();
2303
    TerminateLevel();
2304
    DemoMode = dm_bak;
2305
    DemoPlaying = dp_bak;
2306
}
2307
 
5198 hendricks2 2308
void
5196 hendricks2 2309
LoadingLevelScreen(char *level_name)
2310
{
2311
    short w,h;
5198 hendricks2 2312
    extern SWBOOL DemoMode;
5196 hendricks2 2313
    extern char *MNU_LevelName[28];
2314
    DrawLoadLevelScreen();
2315
 
2316
    if (DemoMode)
2317
        sprintf(ds,"DEMO");
2318
    else
2319
        sprintf(ds,"ENTERING");
2320
 
2321
    MNU_MeasureString(ds, &w, &h);
2322
    MNU_DrawString(TEXT_TEST_COL(w), 170, ds,1,16);
2323
 
2324
    if (UserMapName[0])
2325
        sprintf(ds,"%s",UserMapName);
2326
    else
2327
        sprintf(ds,"%s",LevelInfo[Level].Description);
2328
 
2329
    MNU_MeasureString(ds, &w, &h);
2330
    MNU_DrawString(TEXT_TEST_COL(w), 180, ds,1,16);
2331
 
2332
    nextpage();
2333
}
2334
 
5198 hendricks2 2335
void
5196 hendricks2 2336
gNextState(STATEp *State)
2337
{
2338
    // Transition to the next state
2339
    *State = (*State)->NextState;
2340
 
2341
    if (TEST((*State)->Tics, SF_QUICK_CALL))
2342
    {
2343
        (*(*State)->Animator)(0);
2344
        *State = (*State)->NextState;
2345
    }
2346
}
2347
 
2348
// Generic state control
5198 hendricks2 2349
void
5196 hendricks2 2350
gStateControl(STATEp *State, int *tics)
2351
{
2352
    *tics += synctics;
2353
 
2354
    // Skip states if too much time has passed
2355
    while (*tics >= (*State)->Tics)
2356
    {
2357
        // Set Tics
2358
        *tics -= (*State)->Tics;
2359
        gNextState(State);
2360
    }
2361
 
2362
    // Call the correct animator
2363
    if ((*State)->Animator)
2364
        (*(*State)->Animator)(0);
2365
}
2366
 
2367
int BonusPunchSound(short SpriteNum)
2368
{
2369
    PLAYERp pp = Player + myconnectindex;
2370
    PlaySound(DIGI_PLAYERYELL3, &pp->posx, &pp->posy, &pp->posz, v3df_none);
2371
    return 0;
2372
}
2373
 
2374
int BonusKickSound(short SpriteNum)
2375
{
2376
    PLAYERp pp = Player + myconnectindex;
2377
    PlaySound(DIGI_PLAYERYELL2, &pp->posx, &pp->posy, &pp->posz, v3df_none);
2378
    return 0;
2379
}
2380
 
2381
int BonusGrabSound(short SpriteNum)
2382
{
2383
    PLAYERp pp = Player + myconnectindex;
2384
    PlaySound(DIGI_BONUS_GRAB, &pp->posx, &pp->posy, &pp->posz, v3df_none);
2385
    return 0;
2386
}
2387
 
5198 hendricks2 2388
void
5196 hendricks2 2389
BonusScreen(PLAYERp pp)
2390
{
2391
    int minutes,seconds,second_tics;
5198 hendricks2 2392
    extern SWBOOL FinishedLevel;
5196 hendricks2 2393
    extern int PlayClock;
2394
    extern short LevelSecrets;
2395
    extern short TotalKillable;
2396
    short w,h;
2397
    short pic,limit;
2398
    int zero=0;
2399
    int handle = 0;
2400
    short LI_Num;
2401
 
2402
 
2403
#define BONUS_SCREEN_PIC 5120
2404
#define BONUS_ANIM 5121
2405
#define BONUS_ANIM_FRAMES (5159-5121)
2406
 
2407
#define BREAK_LIGHT_RATE 18
2408
 
2409
#define BONUS_PUNCH 5121
2410
#define BONUS_KICK 5136
2411
#define BONUS_GRAB 5151
2412
#define BONUS_REST 5121
2413
 
2414
#define BONUS_TICS 8
2415
#define BONUS_GRAB_TICS 20
2416
#define BONUS_REST_TICS 50
2417
 
2418
    static STATE s_BonusPunch[] =
2419
    {
2420
        {BONUS_PUNCH + 0, BONUS_TICS, NULL, &s_BonusPunch[1]},
2421
        {BONUS_PUNCH + 1, BONUS_TICS, NULL, &s_BonusPunch[2]},
2422
        {BONUS_PUNCH + 2, BONUS_TICS, NULL, &s_BonusPunch[3]},
2423
        {BONUS_PUNCH + 2, 0|SF_QUICK_CALL, BonusPunchSound, &s_BonusPunch[4]},
2424
        {BONUS_PUNCH + 3, BONUS_TICS, NULL, &s_BonusPunch[5]},
2425
        {BONUS_PUNCH + 4, BONUS_TICS, NULL, &s_BonusPunch[6]},
2426
        {BONUS_PUNCH + 5, BONUS_TICS, NULL, &s_BonusPunch[7]},
2427
        {BONUS_PUNCH + 6, BONUS_TICS, NULL, &s_BonusPunch[8]},
2428
        {BONUS_PUNCH + 7, BONUS_TICS, NULL, &s_BonusPunch[9]},
2429
        {BONUS_PUNCH + 8, BONUS_TICS, NULL, &s_BonusPunch[10]},
2430
        {BONUS_PUNCH + 9, BONUS_TICS, NULL, &s_BonusPunch[11]},
2431
        {BONUS_PUNCH + 10, BONUS_TICS, NULL, &s_BonusPunch[12]},
2432
        {BONUS_PUNCH + 11, BONUS_TICS, NULL, &s_BonusPunch[13]},
2433
        {BONUS_PUNCH + 12, BONUS_TICS, NULL, &s_BonusPunch[14]},
2434
        {BONUS_PUNCH + 14, 90,        NULL, &s_BonusPunch[15]},
2435
        {BONUS_PUNCH + 14, BONUS_TICS, NULL, &s_BonusPunch[15]},
2436
    };
2437
 
2438
    static STATE s_BonusKick[] =
2439
    {
2440
        {BONUS_KICK + 0, BONUS_TICS, NULL, &s_BonusKick[1]},
2441
        {BONUS_KICK + 1, BONUS_TICS, NULL, &s_BonusKick[2]},
2442
        {BONUS_KICK + 2, BONUS_TICS, NULL, &s_BonusKick[3]},
2443
        {BONUS_KICK + 2, 0|SF_QUICK_CALL, BonusKickSound, &s_BonusKick[4]},
2444
        {BONUS_KICK + 3, BONUS_TICS, NULL, &s_BonusKick[5]},
2445
        {BONUS_KICK + 4, BONUS_TICS, NULL, &s_BonusKick[6]},
2446
        {BONUS_KICK + 5, BONUS_TICS, NULL, &s_BonusKick[7]},
2447
        {BONUS_KICK + 6, BONUS_TICS, NULL, &s_BonusKick[8]},
2448
        {BONUS_KICK + 7, BONUS_TICS, NULL, &s_BonusKick[9]},
2449
        {BONUS_KICK + 8, BONUS_TICS, NULL, &s_BonusKick[10]},
2450
        {BONUS_KICK + 9, BONUS_TICS, NULL, &s_BonusKick[11]},
2451
        {BONUS_KICK + 10, BONUS_TICS, NULL, &s_BonusKick[12]},
2452
        {BONUS_KICK + 11, BONUS_TICS, NULL, &s_BonusKick[13]},
2453
        {BONUS_KICK + 12, BONUS_TICS, NULL, &s_BonusKick[14]},
2454
        {BONUS_KICK + 14, 90,        NULL, &s_BonusKick[15]},
2455
        {BONUS_KICK + 14, BONUS_TICS, NULL, &s_BonusKick[15]},
2456
    };
2457
 
2458
    static STATE s_BonusGrab[] =
2459
    {
2460
        {BONUS_GRAB + 0, BONUS_GRAB_TICS, NULL, &s_BonusGrab[1]},
2461
        {BONUS_GRAB + 1, BONUS_GRAB_TICS, NULL, &s_BonusGrab[2]},
2462
        {BONUS_GRAB + 2, BONUS_GRAB_TICS, NULL, &s_BonusGrab[3]},
2463
        {BONUS_GRAB + 2, 0|SF_QUICK_CALL, BonusGrabSound, &s_BonusGrab[4]},
2464
        {BONUS_GRAB + 3, BONUS_GRAB_TICS, NULL, &s_BonusGrab[5]},
2465
        {BONUS_GRAB + 4, BONUS_GRAB_TICS, NULL, &s_BonusGrab[6]},
2466
        {BONUS_GRAB + 5, BONUS_GRAB_TICS, NULL, &s_BonusGrab[7]},
2467
        {BONUS_GRAB + 6, BONUS_GRAB_TICS, NULL, &s_BonusGrab[8]},
2468
        {BONUS_GRAB + 7, BONUS_GRAB_TICS, NULL, &s_BonusGrab[9]},
2469
        {BONUS_GRAB + 8, BONUS_GRAB_TICS, NULL, &s_BonusGrab[10]},
2470
        {BONUS_GRAB + 9, 90,             NULL, &s_BonusGrab[11]},
2471
        {BONUS_GRAB + 9, BONUS_GRAB_TICS, NULL, &s_BonusGrab[11]},
2472
    };
2473
 
2474
#if 1 // Turned off the standing animate because he looks like a FAG!
2475
    static STATE s_BonusRest[] =
2476
    {
2477
        {BONUS_REST + 0, BONUS_REST_TICS, NULL, &s_BonusRest[1]},
2478
        {BONUS_REST + 1, BONUS_REST_TICS, NULL, &s_BonusRest[2]},
2479
        {BONUS_REST + 2, BONUS_REST_TICS, NULL, &s_BonusRest[3]},
2480
        {BONUS_REST + 1, BONUS_REST_TICS, NULL, &s_BonusRest[0]},
2481
    };
2482
#else
2483
    static STATE s_BonusRest[] =
2484
    {
2485
        {BONUS_REST + 0, BONUS_REST_TICS, NULL, &s_BonusRest[1]},
2486
        {BONUS_REST + 0, BONUS_REST_TICS, NULL, &s_BonusRest[0]},
2487
    };
2488
#endif
2489
 
2490
    static STATEp s_BonusAnim[] =
2491
    {
2492
        s_BonusPunch,
2493
        s_BonusKick,
2494
        s_BonusGrab
2495
    };
2496
 
2497
    STATEp State = s_BonusRest;
2498
 
2499
    int Tics = 0;
2500
    int line = 0;
5198 hendricks2 2501
    SWBOOL BonusDone;
5196 hendricks2 2502
    UserInput uinfo = { FALSE, FALSE, dir_None };
2503
 
2504
    if (Level < 0) Level = 0;
2505
 
2506
    clearview(0);
2507
    nextpage();
2508
 
2509
    KB_ClearKeysDown();
2510
 
2511
    totalclock = ototalclock = 0;
2512
    limit = synctics;
2513
 
2514
    if (gs.MusicOn)
2515
    {
2516
        PlaySong(voc[DIGI_ENDLEV].name, 3, TRUE, TRUE);
2517
    }
2518
 
2519
    // special case code because I don't care any more!
2520
    if (FinishAnim)
2521
    {
2522
        flushperms();
2523
        rotatesprite(0, 0, RS_SCALE, 0, 5120, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2524
        rotatesprite(158<<16, 86<<16, RS_SCALE, 0, State->Pic, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2525
        nextpage();
2526
        FadeIn(0,0);
2527
    }
2528
 
2529
    BonusDone = FALSE;
2530
    while (!BonusDone)
2531
    {
2532
        handleevents();
2533
 
2534
        // taken from top of faketimerhandler
2535
        if (totalclock < ototalclock + limit)
2536
        {
2537
            continue;
2538
        }
2539
        ototalclock += limit;
2540
 
2541
        CONTROL_GetUserInput(&uinfo);
2542
        CONTROL_ClearUserInput(&uinfo);
2543
        if (KEY_PRESSED(KEYSC_SPACE) || KEY_PRESSED(KEYSC_ENTER) || uinfo.button0 || uinfo.button1)
2544
        {
2545
            if (State >= s_BonusRest && State < &s_BonusRest[SIZ(s_BonusRest)])
2546
            {
2547
                State = s_BonusAnim[STD_RANDOM_RANGE(SIZ(s_BonusAnim))];
2548
                Tics = 0;
2549
            }
2550
        }
2551
 
2552
        gStateControl(&State, &Tics);
2553
        rotatesprite(0, 0, RS_SCALE, 0, 5120, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2554
 
2555
        if (UserMapName[0])
2556
        {
2557
            sprintf(ds,"%s",UserMapName);
2558
            MNU_MeasureString(ds, &w, &h);
2559
            MNU_DrawString(TEXT_TEST_COL(w), 20, ds,1,19);
2560
        }
2561
        else
2562
        {
2563
            if (PlayingLevel <= 1)
2564
                PlayingLevel = 1;
2565
            sprintf(ds,"%s",LevelInfo[PlayingLevel].Description);
2566
            MNU_MeasureString(ds, &w, &h);
2567
            MNU_DrawString(TEXT_TEST_COL(w), 20, ds,1,19);
2568
        }
2569
 
2570
        sprintf(ds,"Completed");
2571
        MNU_MeasureString(ds, &w, &h);
2572
        MNU_DrawString(TEXT_TEST_COL(w), 30, ds,1,19);
2573
 
2574
        rotatesprite(158<<16, 86<<16, RS_SCALE, 0, State->Pic, 0, 0, TITLE_ROT_FLAGS, 0, 0, xdim - 1, ydim - 1);
2575
 
2576
#define BONUS_LINE(i) (50 + ((i)*20))
2577
 
2578
        line = 0;
2579
        second_tics = (PlayClock/120);
2580
        minutes = (second_tics/60);
2581
        seconds = (second_tics%60);
2582
        sprintf(ds,"Your Time:  %2d : %02d", minutes, seconds);
2583
        MNU_MeasureString(ds, &w, &h);
2584
        MNU_DrawString(60, BONUS_LINE(line), ds,1,16);
2585
 
2586
        if (!UserMapName[0])
2587
        {
2588
            line++;
2589
            sprintf(ds,"3D Realms Best Time:  %s", LevelInfo[PlayingLevel].BestTime);
2590
            MNU_MeasureString(ds, &w, &h);
2591
            MNU_DrawString(40, BONUS_LINE(line), ds,1,16);
2592
 
2593
            line++;
2594
            sprintf(ds,"Par Time:  %s", LevelInfo[PlayingLevel].ParTime);
2595
            MNU_MeasureString(ds, &w, &h);
2596
            MNU_DrawString(40, BONUS_LINE(line), ds,1,16);
2597
        }
2598
 
2599
 
2600
        // always read secrets and kills from the first player
2601
        line++;
2602
        sprintf(ds,"Secrets:  %d / %d", Player->SecretsFound, LevelSecrets);
2603
        MNU_MeasureString(ds, &w, &h);
2604
        MNU_DrawString(60, BONUS_LINE(line), ds,1,16);
2605
 
2606
        line++;
2607
        sprintf(ds,"Kills:  %d / %d", Player->Kills, TotalKillable);
2608
        MNU_MeasureString(ds, &w, &h);
2609
        MNU_DrawString(60, BONUS_LINE(line), ds,1,16);
2610
 
2611
 
2612
        sprintf(ds,"Press SPACE to continue");
2613
        MNU_MeasureString(ds, &w, &h);
2614
        MNU_DrawString(TEXT_TEST_COL(w), 185, ds,1,19);
2615
 
2616
        nextpage();
2617
        ScreenCaptureKeys();
2618
 
2619
        if (State == State->NextState)
2620
            BonusDone = TRUE;
2621
    }
2622
 
2623
    StopSound();
2624
    Terminate3DSounds();
2625
}
2626
 
5198 hendricks2 2627
void EndGameSequence(void)
5196 hendricks2 2628
{
5198 hendricks2 2629
    SWBOOL anim_ok = TRUE;
5196 hendricks2 2630
    FadeOut(0, 5);
2631
 
2632
    if ((gs.ParentalLock || Global_PLock) && FinishAnim == ANIM_SUMO)
2633
        anim_ok = FALSE;
2634
 
2635
    if (anim_ok)
2636
        playanm(FinishAnim);
2637
 
2638
    BonusScreen(Player + myconnectindex);
2639
 
2640
    ExitLevel = FALSE;
2641
    QuitFlag = FALSE;
2642
    AutoNet = FALSE;
2643
 
2644
    if (FinishAnim == ANIM_ZILLA)
2645
        CreditsLevel();
2646
 
2647
    ExitLevel = FALSE;
2648
    QuitFlag = FALSE;
2649
    AutoNet = FALSE;
2650
 
2651
    if (SW_SHAREWARE)
2652
    {
2653
        Level = 0;
2654
    }
2655
    else
2656
    {
2657
        if (Level == 4 || Level == 20)
2658
        {
2659
            Level=0;
2660
        }
2661
        else
2662
            Level++;
2663
    }
2664
}
2665
 
5198 hendricks2 2666
void
5196 hendricks2 2667
StatScreen(PLAYERp mpp)
2668
{
2669
    int minutes,seconds,second_tics;
5198 hendricks2 2670
    extern SWBOOL FinishedLevel;
5196 hendricks2 2671
    extern int PlayClock;
2672
    extern short LevelSecrets;
2673
    extern short TotalKillable;
2674
    short w,h;
2675
    int zero=0;
2676
    int handle=0;
2677
 
2678
    short rows,cols,i,j;
2679
    PLAYERp pp = NULL;
2680
    int x,y;
2681
    short death_total[MAX_SW_PLAYERS_REG];
2682
    short kills[MAX_SW_PLAYERS_REG];
2683
    short pal;
2684
 
2685
#define STAT_START_X 20
2686
#define STAT_START_Y 85
2687
#define STAT_OFF_Y 9
2688
#define STAT_HEADER_Y 14
2689
 
2690
#define SM_SIZ(num) ((num)*4)
2691
 
2692
#define STAT_TABLE_X (STAT_START_X + SM_SIZ(15))
2693
#define STAT_TABLE_XOFF SM_SIZ(6)
2694
 
2695
    // No stats in bot games
2696
    //if (BotMode) return;
2697
 
2698
    ResetPalette(mpp);
2699
    COVER_SetReverb(0); // Reset reverb
2700
    StopSound();
2701
 
2702
    if (FinishAnim)
2703
    {
2704
        EndGameSequence();
2705
        return;
2706
    }
2707
 
2708
    if (gNet.MultiGameType != MULTI_GAME_COMMBAT)
2709
    {
2710
        if (!FinishedLevel)
2711
            return;
2712
        BonusScreen(mpp);
2713
        return;
2714
    }
2715
 
2716
    flushperms();
2717
    DrawStatScreen();
2718
 
2719
    memset(death_total,0,sizeof(death_total));
2720
    memset(kills,0,sizeof(kills));
2721
 
2722
    sprintf(ds,"MULTIPLAYER TOTALS");
2723
    MNU_MeasureString(ds, &w, &h);
2724
    MNU_DrawString(TEXT_TEST_COL(w), 68, ds, 0, 0);
2725
 
2726
    sprintf(ds,"PRESS SPACE BAR TO CONTINUE");
2727
    MNU_MeasureString(ds, &w, &h);
2728
    MNU_DrawString(TEXT_TEST_COL(w), 189, ds, 0, 0);
2729
 
2730
    x = STAT_START_X;
2731
    y = STAT_START_Y;
2732
 
2733
    sprintf(ds,"  NAME         1     2     3     4     5     6     7    8     KILLS");
2734
    DisplayMiniBarSmString(mpp, x, y, 0, ds);
2735
    rows = OrigCommPlayers;
2736
    cols = OrigCommPlayers;
2737
    mpp = Player + myconnectindex;
2738
 
2739
    y += STAT_HEADER_Y;
2740
 
2741
    for (i = 0; i < rows; i++)
2742
    {
2743
        x = STAT_START_X;
2744
        pp = Player + i;
2745
 
2746
        sprintf(ds,"%d", i+1);
2747
        DisplayMiniBarSmString(mpp, x, y, 0, ds);
2748
 
2749
        sprintf(ds,"  %-13s", pp->PlayerName);
2750
        DisplayMiniBarSmString(mpp, x, y, User[pp->PlayerSprite]->spal, ds);
2751
 
2752
        x = STAT_TABLE_X;
2753
        for (j = 0; j < cols; j++)
2754
        {
2755
            pal = 0;
2756
            death_total[j] += pp->KilledPlayer[j];
2757
 
2758
            if (i == j)
2759
            {
2760
                // don't add kill for self or team player
2761
                pal = PALETTE_PLAYER0 + 4;
2762
                kills[i] -= pp->KilledPlayer[j];  // subtract self kills
2763
            }
2764
            else if (gNet.TeamPlay)
2765
            {
2766
                if (User[pp->PlayerSprite]->spal == User[Player[j].PlayerSprite]->spal)
2767
                {
2768
                    // don't add kill for self or team player
2769
                    pal = PALETTE_PLAYER0 + 4;
2770
                    kills[i] -= pp->KilledPlayer[j];  // subtract self kills
2771
                }
2772
                else
2773
                    kills[i] += pp->KilledPlayer[j];  // kills added here
2774
            }
2775
            else
2776
            {
2777
                kills[i] += pp->KilledPlayer[j];  // kills added here
2778
            }
2779
 
2780
            sprintf(ds,"%d", pp->KilledPlayer[j]);
2781
            DisplayMiniBarSmString(mpp, x, y, pal, ds);
2782
            x += STAT_TABLE_XOFF;
2783
        }
2784
 
2785
        y += STAT_OFF_Y;
2786
    }
2787
 
2788
 
2789
    // Deaths
2790
 
2791
    x = STAT_START_X;
2792
    y += STAT_OFF_Y;
2793
 
2794
    sprintf(ds,"   DEATHS");
2795
    DisplayMiniBarSmString(mpp, x, y, 0, ds);
2796
    x = STAT_TABLE_X;
2797
 
2798
    for (j = 0; j < cols; j++)
2799
    {
2800
        sprintf(ds,"%d",death_total[j]);
2801
        DisplayMiniBarSmString(mpp, x, y, 0, ds);
2802
        x += STAT_TABLE_XOFF;
2803
    }
2804
 
2805
    x = STAT_START_X;
2806
    y += STAT_OFF_Y;
2807
 
2808
    // Kills
2809
    x = STAT_TABLE_X + SM_SIZ(50);
2810
    y = STAT_START_Y + STAT_HEADER_Y;
2811
 
2812
    for (i = 0; i < rows; i++)
2813
    {
2814
        pp = Player + i;
2815
 
2816
        sprintf(ds,"%d", kills[i]); //pp->Kills);
2817
        DisplayMiniBarSmString(mpp, x, y, 0, ds);
2818
 
2819
        y += STAT_OFF_Y;
2820
    }
2821
 
2822
    nextpage();
2823
 
2824
    if (KeyPressed())
2825
    {
2826
        while (KeyPressed()) ;
2827
    }
2828
 
2829
    KEY_PRESSED(KEYSC_SPACE) = 0;
2830
    KEY_PRESSED(KEYSC_ENTER) = 0;
2831
 
2832
    if (gs.MusicOn)
2833
    {
2834
        PlaySong(voc[DIGI_ENDLEV].name, 3, TRUE, TRUE);
2835
    }
2836
 
2837
    while (!KEY_PRESSED(KEYSC_SPACE) && !KEY_PRESSED(KEYSC_ENTER))
2838
    {
2839
        handleevents();
2840
 
2841
        ScreenCaptureKeys();
2842
    }
2843
 
2844
    StopSound();
2845
    Terminate3DSounds();
2846
}
2847
 
5198 hendricks2 2848
void
2849
GameIntro(void)
5196 hendricks2 2850
{
2851
 
2852
    DSPRINTF(ds,"GameIntro...");
2853
    MONO_PRINT(ds);
2854
 
2855
    if (DemoPlaying)
2856
        return;
2857
 
2858
    // this could probably be taken out and you could select skill level
2859
    // from menu to start the game
2860
    if (!CommEnabled && UserMapName[0])
2861
        return;
2862
 
2863
    Level = 1;
2864
 
2865
 
2866
 
2867
 
2868
    if (!AutoNet)
2869
    {
2870
        LogoLevel();
2871
        //CreditsLevel();
2872
        //SceneLevel();
2873
        //TitleLevel();
2874
        IntroAnimLevel();
2875
        IntroAnimCount = 0;
2876
    }
2877
 
2878
    MenuLevel();
2879
}
2880
 
5198 hendricks2 2881
void
5206 hendricks2 2882
Control(int32_t argc, const char **argv)
5196 hendricks2 2883
{
2884
 
5206 hendricks2 2885
    InitGame(argc, argv);
5196 hendricks2 2886
 
2887
    MONO_PRINT("InitGame done");
2888
    MNU_InitMenus();
2889
    InGame = TRUE;
2890
    GameIntro();
2891
    //NewGame = TRUE;
2892
 
2893
    while (!QuitFlag)
2894
    {
2895
        handleevents();
2896
        OSD_DispatchQueued();
2897
 
2898
        if (quitevent) QuitFlag = TRUE;
2899
 
2900
        NewLevel();
2901
    }
2902
 
2903
    CleanExit = TRUE;
2904
    TerminateGame();
2905
}
2906
 
2907
 
2908
void
2909
_Assert(char *expr, char *strFile, unsigned uLine)
2910
{
2911
    sprintf(ds, "Assertion failed: %s %s, line %u", expr, strFile, uLine);
2912
    MONO_PRINT(ds);
2913
    TerminateGame();
2914
#if 1 //def RENDERTYPEWIN
2915
    wm_msgbox(apptitle, ds);
2916
#else
2917
    printf("Assertion failed: %s\n %s, line %u\n", expr, strFile, uLine);
2918
#endif
2919
    exit(0);
2920
}
2921
 
2922
 
2923
void
2924
_ErrMsg(char *strFile, unsigned uLine, char *format, ...)
2925
{
2926
    va_list arglist;
2927
 
2928
    //DSPRINTF(ds, "Error: %s, line %u", strFile, uLine);
2929
    //MONO_PRINT(ds);
2930
    TerminateGame();
2931
 
2932
#if 1 //def RENDERTYPEWIN
2933
    {
2934
        char msg[256], *p;
2935
        Bsnprintf(msg, sizeof(msg), "Error: %s, line %u\n", strFile, uLine);
2936
        p = &msg[strlen(msg)];
2937
        va_start(arglist, format);
2938
        Bvsnprintf(msg, sizeof(msg) - (p-msg), format, arglist);
2939
        va_end(arglist);
2940
        wm_msgbox(apptitle, msg);
2941
    }
2942
#else
2943
    printf("Error: %s, line %u\n", strFile, uLine);
2944
 
2945
    va_start(arglist, format);
2946
    vprintf(format, arglist);
2947
    va_end(arglist);
2948
#endif
2949
 
2950
    exit(0);
2951
}
2952
 
2953
void
2954
dsprintf(char *str, char *format, ...)
2955
{
2956
    va_list arglist;
2957
 
2958
    va_start(arglist, format);
2959
    vsprintf(str, format, arglist);
2960
    va_end(arglist);
2961
}
2962
 
2963
void
2964
dsprintf_null(char *str, char *format, ...)
2965
{
2966
    va_list arglist;
2967
}
2968
 
2969
void MoveLoop(void)
2970
{
2971
    int pnum;
2972
 
2973
    getpackets();
2974
 
2975
    if (PredictionOn && CommEnabled)
2976
    {
2977
        while (predictmovefifoplc < Player[myconnectindex].movefifoend)
2978
        {
2979
            DoPrediction(ppp);
2980
        }
2981
    }
2982
 
2983
    //While you have new input packets to process...
2984
    if (!CommEnabled)
2985
        bufferjitter = 0;
2986
 
2987
    while (Player[myconnectindex].movefifoend - movefifoplc > bufferjitter)
2988
    {
2989
        //Make sure you have at least 1 packet from everyone else
2990
        for (pnum=connecthead; pnum>=0; pnum=connectpoint2[pnum])
2991
        {
2992
            if (movefifoplc == Player[pnum].movefifoend)
2993
            {
2994
                break;
2995
            }
2996
        }
2997
 
2998
        //Pnum is >= 0 only if last loop was broken, meaning a player wasn't caught up
2999
        if (pnum >= 0)
3000
            break;
3001
 
3002
        domovethings();
3003
 
3004
#if DEBUG
3005
        //if (DemoSyncRecord)
3006
        //    demosync_record();
3007
#endif
3008
    }
3009
 
3010
    if (!InputMode && !PauseKeySet)
3011
        MNU_CheckForMenus();
3012
}
3013
 
3014
 
3015
void InitPlayerGameSettings(void)
3016
{
3017
    int pnum;
3018
 
3019
    // don't jack with auto aim settings if DemoMode is going
3020
    // what the hell did I do this for?????????
3021
    //if (DemoMode)
3022
    //    return;
3023
 
3024
    if (CommEnabled)
3025
    {
3026
        // everyone gets the same Auto Aim
3027
        TRAVERSE_CONNECT(pnum)
3028
        {
3029
            if (gNet.AutoAim)
3030
                SET(Player[pnum].Flags, PF_AUTO_AIM);
3031
            else
3032
                RESET(Player[pnum].Flags, PF_AUTO_AIM);
3033
        }
3034
    }
3035
    else
3036
    {
3037
        if (gs.AutoAim)
3038
            SET(Player[myconnectindex].Flags, PF_AUTO_AIM);
3039
        else
3040
            RESET(Player[myconnectindex].Flags, PF_AUTO_AIM);
3041
    }
3042
 
3043
    // everyone had their own Auto Run
3044
    if (gs.AutoRun)
3045
        SET(Player[myconnectindex].Flags, PF_LOCK_RUN);
3046
    else
3047
        RESET(Player[myconnectindex].Flags, PF_LOCK_RUN);
3048
 
3049
    if (gs.MouseAimingOn)
3050
        SET(Player[myconnectindex].Flags, PF_MOUSE_AIMING_ON);
3051
    else
3052
        RESET(Player[myconnectindex].Flags, PF_MOUSE_AIMING_ON);
3053
}
3054
 
3055
 
5198 hendricks2 3056
void InitRunLevel(void)
5196 hendricks2 3057
{
3058
    int i;
3059
    if (DemoEdit)
3060
        return;
3061
 
3062
    if (LoadGameOutsideMoveLoop)
3063
    {
3064
        int SavePlayClock;
3065
        extern int PlayClock;
3066
        LoadGameOutsideMoveLoop = FALSE;
3067
        // contains what is needed from calls below
3068
        if (gs.Ambient)
3069
            StartAmbientSound();
3070
        SetCrosshair();
3071
        PlaySong(LevelSong, -1, TRUE, TRUE);
3072
        SetRedrawScreen(Player + myconnectindex);
3073
        // crappy little hack to prevent play clock from being overwritten
3074
        // for load games
3075
        SavePlayClock = PlayClock;
3076
        InitTimingVars();
3077
        PlayClock = SavePlayClock;
3078
        MONO_PRINT("Done with InitRunLevel");
3079
        return;
3080
    }
3081
 
3082
#if 0
3083
    // ensure we are through the initialization code before sending the game
3084
    // version. Otherwise, it is possible to send this too early and have it
3085
    // blown away on the other side.
3086
    waitforeverybody();
3087
#endif
3088
 
3089
    SendVersion(GameVersion);
3090
 
3091
    waitforeverybody();
3092
 
3093
    StopSong();
3094
 
3095
    if (Bstrcasecmp(CacheLastLevel, LevelName) != 0)
3096
        DoTheCache();
3097
 
3098
    // auto aim / auto run / etc
3099
    InitPlayerGameSettings();
3100
 
3101
    // send packets with player info
3102
    InitNetPlayerOptions();
3103
 
3104
    // Initialize Game part of network code (When ready2send != 0)
3105
    InitNetVars();
3106
 
3107
    {
3108
        int track;
3109
        if (Level == 0)
3110
        {
3111
            track = RedBookSong[4+RANDOM_RANGE(10)];
3112
        }
3113
        else
3114
        {
3115
            track = RedBookSong[Level];
3116
        }
3117
        PlaySong(LevelSong, track, TRUE, TRUE);
3118
    }
3119
 
3120
    InitPrediction(&Player[myconnectindex]);
3121
 
3122
    if (!DemoInitOnce)
3123
        DemoRecordSetup();
3124
 
3125
    // everything has been inited at least once for RECORD
3126
    DemoInitOnce = TRUE;
3127
 
3128
//DebugWriteLoc(__FILE__, __LINE__);
3129
    waitforeverybody();
3130
 
3131
    CheckVersion(GameVersion);
3132
 
3133
    // IMPORTANT - MUST be right before game loop AFTER waitforeverybody
3134
    InitTimingVars();
3135
 
3136
    SetRedrawScreen(Player + myconnectindex);
3137
 
3138
    FX_SetVolume(gs.SoundVolume); // Turn volume back up
3139
    if (gs.Ambient)
3140
        StartAmbientSound();
3141
}
3142
 
5198 hendricks2 3143
void
3144
RunLevel(void)
5196 hendricks2 3145
{
3146
    int i;
3147
    InitRunLevel();
3148
 
3149
    FX_SetVolume(gs.SoundVolume);
3150
    SetSongVolume(gs.MusicVolume);
3151
 
3152
#if 0
3153
    waitforeverybody();
3154
#endif
3155
    ready2send = 1;
3156
 
3157
    while (TRUE)
3158
    {
3159
        handleevents();
3160
        OSD_DispatchQueued();
3161
 
3162
        if (quitevent) QuitFlag = TRUE;
3163
 
3164
        //MONO_PRINT("Before MoveLoop");
3165
        MoveLoop();
3166
        //MONO_PRINT("After MoveLoop");
3167
        //MONO_PRINT("Before DrawScreen");
3168
        drawscreen(Player + screenpeek);
3169
        //MONO_PRINT("After DrawScreen");
3170
 
3171
        if (QuitFlag)
3172
            break;
3173
 
3174
        if (ExitLevel)
3175
        {
3176
            ExitLevel = FALSE;
3177
            break;
3178
        }
3179
    }
3180
 
3181
    ready2send = 0;
3182
}
3183
 
3184
void swexit(int exitval)
3185
{
3186
    exit(exitval);
3187
}
3188
 
5198 hendricks2 3189
void DosScreen(void)
5196 hendricks2 3190
{
3191
#if 0
3192
#ifdef SW_SHAREWARE
3193
#define DOS_SCREEN_NAME "SHADSW.BIN"
3194
#else
3195
#define DOS_SCREEN_NAME "SWREG.BIN"
3196
#endif
3197
 
3198
#define DOS_SCREEN_SIZE (4000-(80*2))
3199
#define DOS_SCREEN_PTR ((void *)(0xB8000))
3200
    int fin;
3201
    int i;
3202
    char buffer[DOS_SCREEN_SIZE];
3203
 
3204
    fin = kopen4load(DOS_SCREEN_NAME,0);
3205
    if (fin == -1)
3206
        return;
3207
 
3208
    kread(fin, buffer, sizeof(buffer));
3209
    memcpy(DOS_SCREEN_PTR, buffer, DOS_SCREEN_SIZE);
3210
    kclose(fin);
3211
    move_cursor(23,0);
3212
    _displaycursor(_GCURSORON);
3213
#endif
3214
}
3215
 
3216
#if 0 //PLOCK_VERSION
5198 hendricks2 3217
void AlphaMessage(void)
5196 hendricks2 3218
{
3219
    Global_PLock = TRUE; // Set the hardwired parental lock mode!
3220
    buildputs(""
3221
              "                          SHADOW WARRIOR(tm) Version 1.2                      \n"
3222
              "Copyright (c) 1997 3D Realms Entertainment\n"
3223
              "\n\n"
3224
              "     NOTE: This version of Shadow Warrior has been modified from it's\n"
3225
              "     original form.  All of the violent and mature content has been\n"
3226
              "     removed.  To download a patch to restore this version to its\n"
3227
              "     original form visit www.3drealms.com, www.gtinteractive.com, or look\n"
3228
              "     inside your retail packaging for information about this version.\n\n\n"
3229
              );
3230
}
3231
#endif
3232
 
3233
#if 0 //UK_VERSION
5198 hendricks2 3234
void AlphaMessage(void)
5196 hendricks2 3235
{
3236
    buildputs(""
3237
              "                    SHADOW WARRIOR(tm) Version 1.2 (UK Version)               \n"
3238
              "Copyright (c) 1997 3D Realms Entertainment\n"
3239
      &