Subversion Repositories eduke32

Rev

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

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