Subversion Repositories eduke32

Rev

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

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