Subversion Repositories eduke32

Rev

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

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