Subversion Repositories Kolibri OS

Rev

Rev 8596 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
8557 maxcodehac 1
// WL_MAIN.C
2
 
3
#ifdef _WIN32
4
    #include 
5
#else
6
    #include 
7
#endif
8
 
9
#include "wl_def.h"
10
#pragma hdrstop
11
#include "wl_atmos.h"
12
#include 
13
 
14
 
15
/*
16
=============================================================================
17
 
18
                             WOLFENSTEIN 3-D
19
 
20
                        An Id Software production
21
 
22
                             by John Carmack
23
 
24
=============================================================================
25
*/
26
 
27
extern byte signon[];
28
 
29
/*
30
=============================================================================
31
 
32
                             LOCAL CONSTANTS
33
 
34
=============================================================================
35
*/
36
 
37
 
38
#define FOCALLENGTH     (0x5700l)               // in global coordinates
39
#define VIEWGLOBAL      0x10000                 // globals visable flush to wall
40
 
41
#define VIEWWIDTH       256                     // size of view window
42
#define VIEWHEIGHT      144
43
 
44
/*
45
=============================================================================
46
 
47
                            GLOBAL VARIABLES
48
 
49
=============================================================================
50
*/
51
 
52
char    str[80];
53
int     dirangle[9] = {0,ANGLES/8,2*ANGLES/8,3*ANGLES/8,4*ANGLES/8,
54
                       5*ANGLES/8,6*ANGLES/8,7*ANGLES/8,ANGLES};
55
 
56
//
57
// proejection variables
58
//
59
fixed    focallength;
60
unsigned screenofs;
61
int      viewscreenx, viewscreeny;
62
int      viewwidth;
63
int      viewheight;
64
short    centerx;
65
int      shootdelta;           // pixels away from centerx a target can be
66
fixed    scale;
67
int32_t  heightnumerator;
68
 
69
 
70
void    Quit (const char *error,...);
71
 
72
boolean startgame;
73
boolean loadedgame;
74
int     mouseadjustment;
75
 
76
char    configdir[256] = "";
77
char    configname[13] = "config.";
78
 
79
//
80
// Command line parameter variables
81
//
82
boolean param_debugmode = false;
83
boolean param_nowait = false;
84
int     param_difficulty = 1;           // default is "normal"
85
int     param_tedlevel = -1;            // default is not to start a level
86
int     param_joystickindex = 0;
87
 
88
#if defined(_arch_dreamcast)
89
int     param_joystickhat = 0;
90
int     param_samplerate = 11025;       // higher samplerates result in "out of memory"
91
int     param_audiobuffer = 4096 / (44100 / param_samplerate);
92
#elif defined(GP2X_940)
93
int     param_joystickhat = -1;
94
int     param_samplerate = 11025;       // higher samplerates result in "out of memory"
95
int     param_audiobuffer = 128;
96
#else
97
int     param_joystickhat = -1;
98
int     param_samplerate = 44100;
99
int     param_audiobuffer = 2048 / (44100 / param_samplerate);
100
#endif
101
 
102
int     param_mission = 0;
103
boolean param_goodtimes = false;
104
boolean param_ignorenumchunks = false;
105
 
106
/*
107
=============================================================================
108
 
109
                            LOCAL VARIABLES
110
 
111
=============================================================================
112
*/
113
 
114
 
115
/*
116
====================
117
=
118
= ReadConfig
119
=
120
====================
121
*/
122
 
123
void ReadConfig(void)
124
{
125
    SDMode  sd;
126
    SMMode  sm;
127
    SDSMode sds;
128
 
129
    char configpath[300];
130
 
131
#ifdef _arch_dreamcast
132
    DC_LoadFromVMU(configname);
133
#endif
134
 
135
    if(configdir[0])
136
        snprintf(configpath, sizeof(configpath), "%s/%s", configdir, configname);
137
    else
138
        strcpy(configpath, configname);
139
 
140
    const int file = open(configpath, O_RDONLY | O_BINARY);
141
    if (file != -1)
142
    {
143
        //
144
        // valid config file
145
        //
146
        word tmp;
147
        read(file,&tmp,sizeof(tmp));
148
        if(tmp!=0xfefa)
149
        {
150
            close(file);
151
            goto noconfig;
152
        }
153
        read(file,Scores,sizeof(HighScore) * MaxScores);
154
 
155
        read(file,&sd,sizeof(sd));
156
        read(file,&sm,sizeof(sm));
157
        read(file,&sds,sizeof(sds));
158
 
159
        read(file,&mouseenabled,sizeof(mouseenabled));
160
        read(file,&joystickenabled,sizeof(joystickenabled));
161
        boolean dummyJoypadEnabled;
162
        read(file,&dummyJoypadEnabled,sizeof(dummyJoypadEnabled));
163
        boolean dummyJoystickProgressive;
164
        read(file,&dummyJoystickProgressive,sizeof(dummyJoystickProgressive));
165
        int dummyJoystickPort = 0;
166
        read(file,&dummyJoystickPort,sizeof(dummyJoystickPort));
167
 
168
        read(file,dirscan,sizeof(dirscan));
169
        read(file,buttonscan,sizeof(buttonscan));
170
        read(file,buttonmouse,sizeof(buttonmouse));
171
        read(file,buttonjoy,sizeof(buttonjoy));
172
 
173
        read(file,&viewsize,sizeof(viewsize));
174
        read(file,&mouseadjustment,sizeof(mouseadjustment));
175
 
176
        close(file);
177
 
178
        if ((sd == sdm_AdLib || sm == smm_AdLib) && !AdLibPresent
179
                && !SoundBlasterPresent)
180
        {
181
            sd = sdm_PC;
182
            sm = smm_Off;
183
        }
184
 
185
        if ((sds == sds_SoundBlaster && !SoundBlasterPresent))
186
            sds = sds_Off;
187
 
188
        // make sure values are correct
189
 
190
        if(mouseenabled) mouseenabled=true;
191
        if(joystickenabled) joystickenabled=true;
192
 
193
        if (!MousePresent)
194
            mouseenabled = false;
195
        if (!IN_JoyPresent())
196
            joystickenabled = false;
197
 
198
        if(mouseadjustment<0) mouseadjustment=0;
199
        else if(mouseadjustment>9) mouseadjustment=9;
200
 
201
        if(viewsize<4) viewsize=4;
202
        else if(viewsize>21) viewsize=21;
203
 
204
        MainMenu[6].active=1;
205
        MainItems.curpos=0;
206
    }
207
    else
208
    {
209
        //
210
        // no config file, so select by hardware
211
        //
212
noconfig:
213
        if (SoundBlasterPresent || AdLibPresent)
214
        {
215
            sd = sdm_AdLib;
216
            sm = smm_AdLib;
217
        }
218
        else
219
        {
220
            sd = sdm_PC;
221
            sm = smm_Off;
222
        }
223
 
224
        if (SoundBlasterPresent)
225
            sds = sds_SoundBlaster;
226
        else
227
            sds = sds_Off;
228
 
229
        if (MousePresent)
230
            mouseenabled = true;
231
 
232
        if (IN_JoyPresent())
233
            joystickenabled = true;
234
 
235
        viewsize = 19;                          // start with a good size
236
        mouseadjustment=5;
237
    }
238
 
239
    SD_SetMusicMode (sm);
240
    SD_SetSoundMode (sd);
241
    SD_SetDigiDevice (sds);
242
}
243
 
244
/*
245
====================
246
=
247
= WriteConfig
248
=
249
====================
250
*/
251
 
252
void WriteConfig(void)
253
{
254
    char configpath[300];
255
 
256
#ifdef _arch_dreamcast
257
    fs_unlink(configname);
258
#endif
259
 
260
    if(configdir[0])
261
        snprintf(configpath, sizeof(configpath), "%s/%s", configdir, configname);
262
    else
263
        strcpy(configpath, configname);
264
 
265
    const int file = open(configpath, O_CREAT | O_WRONLY | O_BINARY, 0644);
266
    if (file != -1)
267
    {
268
        word tmp=0xfefa;
269
        write(file,&tmp,sizeof(tmp));
270
        write(file,Scores,sizeof(HighScore) * MaxScores);
271
 
272
        write(file,&SoundMode,sizeof(SoundMode));
273
        write(file,&MusicMode,sizeof(MusicMode));
274
        write(file,&DigiMode,sizeof(DigiMode));
275
 
276
        write(file,&mouseenabled,sizeof(mouseenabled));
277
        write(file,&joystickenabled,sizeof(joystickenabled));
278
        boolean dummyJoypadEnabled = false;
279
        write(file,&dummyJoypadEnabled,sizeof(dummyJoypadEnabled));
280
        boolean dummyJoystickProgressive = false;
281
        write(file,&dummyJoystickProgressive,sizeof(dummyJoystickProgressive));
282
        int dummyJoystickPort = 0;
283
        write(file,&dummyJoystickPort,sizeof(dummyJoystickPort));
284
 
285
        write(file,dirscan,sizeof(dirscan));
286
        write(file,buttonscan,sizeof(buttonscan));
287
        write(file,buttonmouse,sizeof(buttonmouse));
288
        write(file,buttonjoy,sizeof(buttonjoy));
289
 
290
        write(file,&viewsize,sizeof(viewsize));
291
        write(file,&mouseadjustment,sizeof(mouseadjustment));
292
 
293
        close(file);
294
    }
295
#ifdef _arch_dreamcast
296
    DC_SaveToVMU(configname, NULL);
297
#endif
298
}
299
 
300
 
301
//===========================================================================
302
 
303
/*
304
=====================
305
=
306
= NewGame
307
=
308
= Set up new game to start from the beginning
309
=
310
=====================
311
*/
312
 
313
void NewGame (int difficulty,int episode)
314
{
315
    memset (&gamestate,0,sizeof(gamestate));
316
    gamestate.difficulty = difficulty;
317
    gamestate.weapon = gamestate.bestweapon
318
            = gamestate.chosenweapon = wp_pistol;
319
    gamestate.health = 100;
320
    gamestate.ammo = STARTAMMO;
321
    gamestate.lives = 3;
322
    gamestate.nextextra = EXTRAPOINTS;
323
    gamestate.episode=episode;
324
 
325
    startgame = true;
326
}
327
 
328
//===========================================================================
329
 
330
void DiskFlopAnim(int x,int y)
331
{
332
    static int8_t which=0;
333
    if (!x && !y)
334
        return;
335
    VWB_DrawPic(x,y,C_DISKLOADING1PIC+which);
336
    VW_UpdateScreen();
337
    which^=1;
338
}
339
 
340
 
341
int32_t DoChecksum(byte *source,unsigned size,int32_t checksum)
342
{
343
    unsigned i;
344
 
345
    for (i=0;i
346
    checksum += source[i]^source[i+1];
347
 
348
    return checksum;
349
}
350
 
351
 
352
/*
353
==================
354
=
355
= SaveTheGame
356
=
357
==================
358
*/
359
 
360
extern statetype s_grdstand;
361
extern statetype s_player;
362
 
363
boolean SaveTheGame(FILE *file,int x,int y)
364
{
365
//    struct diskfree_t dfree;
366
//    int32_t avail,size,checksum;
367
    int checksum;
368
    objtype *ob;
369
    objtype nullobj;
370
    statobj_t nullstat;
371
 
372
/*    if (_dos_getdiskfree(0,&dfree))
373
        Quit("Error in _dos_getdiskfree call");
374
 
375
    avail = (int32_t)dfree.avail_clusters *
376
                  dfree.bytes_per_sector *
377
                  dfree.sectors_per_cluster;
378
 
379
    size = 0;
380
    for (ob = player; ob ; ob=ob->next)
381
        size += sizeof(*ob);
382
    size += sizeof(nullobj);
383
 
384
    size += sizeof(gamestate) +
385
            sizeof(LRstruct)*LRpack +
386
            sizeof(tilemap) +
387
            sizeof(actorat) +
388
            sizeof(laststatobj) +
389
            sizeof(statobjlist) +
390
            sizeof(doorposition) +
391
            sizeof(pwallstate) +
392
            sizeof(pwalltile) +
393
            sizeof(pwallx) +
394
            sizeof(pwally) +
395
            sizeof(pwalldir) +
396
            sizeof(pwallpos);
397
 
398
    if (avail < size)
399
    {
400
        Message(STR_NOSPACE1"\n"STR_NOSPACE2);
401
        return false;
402
    }*/
403
 
404
    checksum = 0;
405
 
406
    DiskFlopAnim(x,y);
407
    fwrite(&gamestate,sizeof(gamestate),1,file);
408
    checksum = DoChecksum((byte *)&gamestate,sizeof(gamestate),checksum);
409
 
410
    DiskFlopAnim(x,y);
411
    fwrite(&LevelRatios[0],sizeof(LRstruct)*LRpack,1,file);
412
    checksum = DoChecksum((byte *)&LevelRatios[0],sizeof(LRstruct)*LRpack,checksum);
413
 
414
    DiskFlopAnim(x,y);
415
    fwrite(tilemap,sizeof(tilemap),1,file);
416
    checksum = DoChecksum((byte *)tilemap,sizeof(tilemap),checksum);
417
    DiskFlopAnim(x,y);
418
 
419
    int i;
420
    for(i=0;i
421
    {
422
        for(int j=0;j
423
        {
424
            word actnum;
425
            objtype *objptr=actorat[i][j];
426
            if(ISPOINTER(objptr))
427
                actnum=0x8000 | (word)(objptr-objlist);
428
            else
429
                actnum=(word)(uintptr_t)objptr;
430
            fwrite(&actnum,sizeof(actnum),1,file);
431
            checksum = DoChecksum((byte *)&actnum,sizeof(actnum),checksum);
432
        }
433
    }
434
 
435
    fwrite (areaconnect,sizeof(areaconnect),1,file);
436
    fwrite (areabyplayer,sizeof(areabyplayer),1,file);
437
 
438
    // player object needs special treatment as it's in WL_AGENT.CPP and not in
439
    // WL_ACT2.CPP which could cause problems for the relative addressing
440
 
441
    ob = player;
442
    DiskFlopAnim(x,y);
443
    memcpy(&nullobj,ob,sizeof(nullobj));
444
    nullobj.state=(statetype *) ((uintptr_t)nullobj.state-(uintptr_t)&s_player);
445
    fwrite(&nullobj,sizeof(nullobj),1,file);
446
    ob = ob->next;
447
 
448
    DiskFlopAnim(x,y);
449
    for (; ob ; ob=ob->next)
450
    {
451
        memcpy(&nullobj,ob,sizeof(nullobj));
452
        nullobj.state=(statetype *) ((uintptr_t)nullobj.state-(uintptr_t)&s_grdstand);
453
        fwrite(&nullobj,sizeof(nullobj),1,file);
454
    }
455
    nullobj.active = ac_badobject;          // end of file marker
456
    DiskFlopAnim(x,y);
457
    fwrite(&nullobj,sizeof(nullobj),1,file);
458
 
459
    DiskFlopAnim(x,y);
460
    word laststatobjnum=(word) (laststatobj-statobjlist);
461
    fwrite(&laststatobjnum,sizeof(laststatobjnum),1,file);
462
    checksum = DoChecksum((byte *)&laststatobjnum,sizeof(laststatobjnum),checksum);
463
 
464
    DiskFlopAnim(x,y);
465
    for(i=0;i
466
    {
467
        memcpy(&nullstat,statobjlist+i,sizeof(nullstat));
468
        nullstat.visspot=(byte *) ((uintptr_t) nullstat.visspot-(uintptr_t)spotvis);
469
        fwrite(&nullstat,sizeof(nullstat),1,file);
470
        checksum = DoChecksum((byte *)&nullstat,sizeof(nullstat),checksum);
471
    }
472
 
473
    DiskFlopAnim(x,y);
474
    fwrite (doorposition,sizeof(doorposition),1,file);
475
    checksum = DoChecksum((byte *)doorposition,sizeof(doorposition),checksum);
476
    DiskFlopAnim(x,y);
477
    fwrite (doorobjlist,sizeof(doorobjlist),1,file);
478
    checksum = DoChecksum((byte *)doorobjlist,sizeof(doorobjlist),checksum);
479
 
480
    DiskFlopAnim(x,y);
481
    fwrite (&pwallstate,sizeof(pwallstate),1,file);
482
    checksum = DoChecksum((byte *)&pwallstate,sizeof(pwallstate),checksum);
483
    fwrite (&pwalltile,sizeof(pwalltile),1,file);
484
    checksum = DoChecksum((byte *)&pwalltile,sizeof(pwalltile),checksum);
485
    fwrite (&pwallx,sizeof(pwallx),1,file);
486
    checksum = DoChecksum((byte *)&pwallx,sizeof(pwallx),checksum);
487
    fwrite (&pwally,sizeof(pwally),1,file);
488
    checksum = DoChecksum((byte *)&pwally,sizeof(pwally),checksum);
489
    fwrite (&pwalldir,sizeof(pwalldir),1,file);
490
    checksum = DoChecksum((byte *)&pwalldir,sizeof(pwalldir),checksum);
491
    fwrite (&pwallpos,sizeof(pwallpos),1,file);
492
    checksum = DoChecksum((byte *)&pwallpos,sizeof(pwallpos),checksum);
493
 
494
    //
495
    // WRITE OUT CHECKSUM
496
    //
497
    fwrite (&checksum,sizeof(checksum),1,file);
498
 
499
    fwrite (&lastgamemusicoffset,sizeof(lastgamemusicoffset),1,file);
500
 
501
    return(true);
502
}
503
 
504
//===========================================================================
505
 
506
/*
507
==================
508
=
509
= LoadTheGame
510
=
511
==================
512
*/
513
 
514
boolean LoadTheGame(FILE *file,int x,int y)
515
{
516
    int32_t checksum,oldchecksum;
517
    objtype nullobj;
518
    statobj_t nullstat;
519
 
520
    checksum = 0;
521
 
522
    DiskFlopAnim(x,y);
523
    fread (&gamestate,sizeof(gamestate),1,file);
524
    checksum = DoChecksum((byte *)&gamestate,sizeof(gamestate),checksum);
525
 
526
    DiskFlopAnim(x,y);
527
    fread (&LevelRatios[0],sizeof(LRstruct)*LRpack,1,file);
528
    checksum = DoChecksum((byte *)&LevelRatios[0],sizeof(LRstruct)*LRpack,checksum);
529
 
530
    DiskFlopAnim(x,y);
531
    SetupGameLevel ();
532
 
533
    DiskFlopAnim(x,y);
534
    fread (tilemap,sizeof(tilemap),1,file);
535
    checksum = DoChecksum((byte *)tilemap,sizeof(tilemap),checksum);
536
 
537
    DiskFlopAnim(x,y);
538
 
539
    int actnum=0, i;
540
    for(i=0;i
541
    {
542
        for(int j=0;j
543
        {
544
            fread (&actnum,sizeof(word),1,file);
545
            checksum = DoChecksum((byte *) &actnum,sizeof(word),checksum);
546
            if(actnum&0x8000)
547
                actorat[i][j]=objlist+(actnum&0x7fff);
548
            else
549
                actorat[i][j]=(objtype *)(uintptr_t) actnum;
550
        }
551
    }
552
 
553
    fread (areaconnect,sizeof(areaconnect),1,file);
554
    fread (areabyplayer,sizeof(areabyplayer),1,file);
555
 
556
    InitActorList ();
557
    DiskFlopAnim(x,y);
558
    fread (player,sizeof(*player),1,file);
559
    player->state=(statetype *) ((uintptr_t)player->state+(uintptr_t)&s_player);
560
 
561
    while (1)
562
    {
563
        DiskFlopAnim(x,y);
564
        fread (&nullobj,sizeof(nullobj),1,file);
565
        if (nullobj.active == ac_badobject)
566
            break;
567
        GetNewActor ();
568
        nullobj.state=(statetype *) ((uintptr_t)nullobj.state+(uintptr_t)&s_grdstand);
569
        // don't copy over the links
570
        memcpy (newobj,&nullobj,sizeof(nullobj)-8);
571
    }
572
 
573
    DiskFlopAnim(x,y);
574
    word laststatobjnum;
575
    fread (&laststatobjnum,sizeof(laststatobjnum),1,file);
576
    laststatobj=statobjlist+laststatobjnum;
577
    checksum = DoChecksum((byte *)&laststatobjnum,sizeof(laststatobjnum),checksum);
578
 
579
    DiskFlopAnim(x,y);
580
    for(i=0;i
581
    {
582
        fread(&nullstat,sizeof(nullstat),1,file);
583
        checksum = DoChecksum((byte *)&nullstat,sizeof(nullstat),checksum);
584
        nullstat.visspot=(byte *) ((uintptr_t)nullstat.visspot+(uintptr_t)spotvis);
585
        memcpy(statobjlist+i,&nullstat,sizeof(nullstat));
586
    }
587
 
588
    DiskFlopAnim(x,y);
589
    fread (doorposition,sizeof(doorposition),1,file);
590
    checksum = DoChecksum((byte *)doorposition,sizeof(doorposition),checksum);
591
    DiskFlopAnim(x,y);
592
    fread (doorobjlist,sizeof(doorobjlist),1,file);
593
    checksum = DoChecksum((byte *)doorobjlist,sizeof(doorobjlist),checksum);
594
 
595
    DiskFlopAnim(x,y);
596
    fread (&pwallstate,sizeof(pwallstate),1,file);
597
    checksum = DoChecksum((byte *)&pwallstate,sizeof(pwallstate),checksum);
598
    fread (&pwalltile,sizeof(pwalltile),1,file);
599
    checksum = DoChecksum((byte *)&pwalltile,sizeof(pwalltile),checksum);
600
    fread (&pwallx,sizeof(pwallx),1,file);
601
    checksum = DoChecksum((byte *)&pwallx,sizeof(pwallx),checksum);
602
    fread (&pwally,sizeof(pwally),1,file);
603
    checksum = DoChecksum((byte *)&pwally,sizeof(pwally),checksum);
604
    fread (&pwalldir,sizeof(pwalldir),1,file);
605
    checksum = DoChecksum((byte *)&pwalldir,sizeof(pwalldir),checksum);
606
    fread (&pwallpos,sizeof(pwallpos),1,file);
607
    checksum = DoChecksum((byte *)&pwallpos,sizeof(pwallpos),checksum);
608
 
609
    if (gamestate.secretcount)      // assign valid floorcodes under moved pushwalls
610
    {
611
        word *map, *obj; word tile, sprite;
612
        map = mapsegs[0]; obj = mapsegs[1];
613
        for (y=0;y
614
            for (x=0;x
615
            {
616
                tile = *map++; sprite = *obj++;
617
                if (sprite == PUSHABLETILE && !tilemap[x][y]
618
                    && (tile < AREATILE || tile >= (AREATILE+NUMMAPS)))
619
                {
620
                    if (*map >= AREATILE)
621
                        tile = *map;
622
                    if (*(map-1-mapwidth) >= AREATILE)
623
                        tile = *(map-1-mapwidth);
624
                    if (*(map-1+mapwidth) >= AREATILE)
625
                        tile = *(map-1+mapwidth);
626
                    if ( *(map-2) >= AREATILE)
627
                        tile = *(map-2);
628
 
629
                    *(map-1) = tile; *(obj-1) = 0;
630
                }
631
            }
632
    }
633
 
634
    Thrust(0,0);    // set player->areanumber to the floortile you're standing on
635
 
636
    fread (&oldchecksum,sizeof(oldchecksum),1,file);
637
 
638
    fread (&lastgamemusicoffset,sizeof(lastgamemusicoffset),1,file);
639
    if(lastgamemusicoffset<0) lastgamemusicoffset=0;
640
 
641
 
642
    if (oldchecksum != checksum)
643
    {
644
        Message(STR_SAVECHT1"\n"
645
                STR_SAVECHT2"\n"
646
                STR_SAVECHT3"\n"
647
                STR_SAVECHT4);
648
 
649
        IN_ClearKeysDown();
650
        IN_Ack();
651
 
652
        gamestate.oldscore = gamestate.score = 0;
653
        gamestate.lives = 1;
654
        gamestate.weapon =
655
            gamestate.chosenweapon =
656
            gamestate.bestweapon = wp_pistol;
657
        gamestate.ammo = 8;
658
    }
659
 
660
    return true;
661
}
662
 
663
//===========================================================================
664
 
665
/*
666
==========================
667
=
668
= ShutdownId
669
=
670
= Shuts down all ID_?? managers
671
=
672
==========================
673
*/
674
 
675
void ShutdownId (void)
676
{
677
    US_Shutdown ();         // This line is completely useless...
678
    SD_Shutdown ();
679
    PM_Shutdown ();
680
    IN_Shutdown ();
681
    VW_Shutdown ();
682
    CA_Shutdown ();
683
#if defined(GP2X_940)
684
    GP2X_Shutdown();
685
#endif
686
}
687
 
688
 
689
//===========================================================================
690
 
691
/*
692
==================
693
=
694
= BuildTables
695
=
696
= Calculates:
697
=
698
= scale                 projection constant
699
= sintable/costable     overlapping fractional tables
700
=
701
==================
702
*/
703
 
704
const float radtoint = (float)(FINEANGLES/2/PI);
705
 
706
void BuildTables (void)
707
{
708
    //
709
    // calculate fine tangents
710
    //
711
 
712
    int i;
713
    for(i=0;i
714
    {
715
        double tang=tan((i+0.5)/radtoint);
716
        finetangent[i]=(int32_t)(tang*GLOBAL1);
717
        finetangent[FINEANGLES/4-1-i]=(int32_t)((1/tang)*GLOBAL1);
718
    }
719
 
720
    //
721
    // costable overlays sintable with a quarter phase shift
722
    // ANGLES is assumed to be divisable by four
723
    //
724
 
725
    float angle=0;
726
    float anglestep=(float)(PI/2/ANGLEQUAD);
727
    for(i=0; i
728
    {
729
        fixed value=(int32_t)(GLOBAL1*sin(angle));
730
        sintable[i]=sintable[i+ANGLES]=sintable[ANGLES/2-i]=value;
731
        sintable[ANGLES-i]=sintable[ANGLES/2+i]=-value;
732
        angle+=anglestep;
733
    }
734
    sintable[ANGLEQUAD] = 65536;
735
    sintable[3*ANGLEQUAD] = -65536;
736
 
737
#if defined(USE_STARSKY) || defined(USE_RAIN) || defined(USE_SNOW)
738
    Init3DPoints();
739
#endif
740
}
741
 
742
//===========================================================================
743
 
744
 
745
/*
746
====================
747
=
748
= CalcProjection
749
=
750
= Uses focallength
751
=
752
====================
753
*/
754
 
755
void CalcProjection (int32_t focal)
756
{
757
    int     i;
758
    int    intang;
759
    float   angle;
760
    double  tang;
761
    int     halfview;
762
    double  facedist;
763
 
764
    focallength = focal;
765
    facedist = focal+MINDIST;
766
    halfview = viewwidth/2;                                 // half view in pixels
767
 
768
    //
769
    // calculate scale value for vertical height calculations
770
    // and sprite x calculations
771
    //
772
    scale = (fixed) (halfview*facedist/(VIEWGLOBAL/2));
773
 
774
    //
775
    // divide heightnumerator by a posts distance to get the posts height for
776
    // the heightbuffer.  The pixel height is height>>2
777
    //
778
    heightnumerator = (TILEGLOBAL*scale)>>6;
779
 
780
    //
781
    // calculate the angle offset from view angle of each pixel's ray
782
    //
783
 
784
    for (i=0;i
785
    {
786
        // start 1/2 pixel over, so viewangle bisects two middle pixels
787
        tang = (int32_t)i*VIEWGLOBAL/viewwidth/facedist;
788
        angle = (float) atan(tang);
789
        intang = (int) (angle*radtoint);
790
        pixelangle[halfview-1-i] = intang;
791
        pixelangle[halfview+i] = -intang;
792
    }
793
}
794
 
795
 
796
 
797
//===========================================================================
798
 
799
/*
800
===================
801
=
802
= SetupWalls
803
=
804
= Map tile values to scaled pics
805
=
806
===================
807
*/
808
 
809
void SetupWalls (void)
810
{
811
    int     i;
812
 
813
    horizwall[0]=0;
814
    vertwall[0]=0;
815
 
816
    for (i=1;i
817
    {
818
        horizwall[i]=(i-1)*2;
819
        vertwall[i]=(i-1)*2+1;
820
    }
821
}
822
 
823
//===========================================================================
824
 
825
/*
826
==========================
827
=
828
= SignonScreen
829
=
830
==========================
831
*/
832
 
833
void SignonScreen (void)                        // VGA version
834
{
835
    VL_SetVGAPlaneMode ();
836
 
837
    VL_MungePic (signon,320,200);
838
    VL_MemToScreen (signon,320,200,0,0);
839
}
840
 
841
 
842
/*
843
==========================
844
=
845
= FinishSignon
846
=
847
==========================
848
*/
849
 
850
void FinishSignon (void)
851
{
852
#ifndef SPEAR
853
    VW_Bar (0,189,300,11,VL_GetPixel(0,0));
854
    WindowX = 0;
855
    WindowW = 320;
856
    PrintY = 190;
857
 
858
    #ifndef JAPAN
859
    SETFONTCOLOR(14,4);
860
 
861
    #ifdef SPANISH
862
    US_CPrint ("Oprima una tecla");
863
    #else
864
    US_CPrint ("Press a key");
865
    #endif
866
 
867
    #endif
868
 
869
    VH_UpdateScreen();
870
 
871
    if (!param_nowait)
872
        IN_Ack ();
873
 
874
    #ifndef JAPAN
875
    VW_Bar (0,189,300,11,VL_GetPixel(0,0));
876
 
877
    PrintY = 190;
878
    SETFONTCOLOR(10,4);
879
 
880
    #ifdef SPANISH
881
    US_CPrint ("pensando...");
882
    #else
883
    US_CPrint ("Working...");
884
    #endif
885
 
886
    VH_UpdateScreen();
887
    #endif
888
 
889
    SETFONTCOLOR(0,15);
890
#else
891
    VH_UpdateScreen();
892
 
893
    if (!param_nowait)
894
        VW_WaitVBL(3*70);
895
#endif
896
}
897
 
898
//===========================================================================
899
 
900
/*
901
=====================
902
=
903
= InitDigiMap
904
=
905
=====================
906
*/
907
 
908
// channel mapping:
909
//  -1: any non reserved channel
910
//   0: player weapons
911
//   1: boss weapons
912
 
913
static int wolfdigimap[] =
914
    {
915
        // These first sounds are in the upload version
916
#ifndef SPEAR
917
        HALTSND,                0,  -1,
918
        DOGBARKSND,             1,  -1,
919
        CLOSEDOORSND,           2,  -1,
920
        OPENDOORSND,            3,  -1,
921
        ATKMACHINEGUNSND,       4,   0,
922
        ATKPISTOLSND,           5,   0,
923
        ATKGATLINGSND,          6,   0,
924
        SCHUTZADSND,            7,  -1,
925
        GUTENTAGSND,            8,  -1,
926
        MUTTISND,               9,  -1,
927
        BOSSFIRESND,            10,  1,
928
        SSFIRESND,              11, -1,
929
        DEATHSCREAM1SND,        12, -1,
930
        DEATHSCREAM2SND,        13, -1,
931
        DEATHSCREAM3SND,        13, -1,
932
        TAKEDAMAGESND,          14, -1,
933
        PUSHWALLSND,            15, -1,
934
 
935
        LEBENSND,               20, -1,
936
        NAZIFIRESND,            21, -1,
937
        SLURPIESND,             22, -1,
938
 
939
        YEAHSND,                32, -1,
940
 
941
#ifndef UPLOAD
942
        // These are in all other episodes
943
        DOGDEATHSND,            16, -1,
944
        AHHHGSND,               17, -1,
945
        DIESND,                 18, -1,
946
        EVASND,                 19, -1,
947
 
948
        TOT_HUNDSND,            23, -1,
949
        MEINGOTTSND,            24, -1,
950
        SCHABBSHASND,           25, -1,
951
        HITLERHASND,            26, -1,
952
        SPIONSND,               27, -1,
953
        NEINSOVASSND,           28, -1,
954
        DOGATTACKSND,           29, -1,
955
        LEVELDONESND,           30, -1,
956
        MECHSTEPSND,            31, -1,
957
 
958
        SCHEISTSND,             33, -1,
959
        DEATHSCREAM4SND,        34, -1,         // AIIEEE
960
        DEATHSCREAM5SND,        35, -1,         // DEE-DEE
961
        DONNERSND,              36, -1,         // EPISODE 4 BOSS DIE
962
        EINESND,                37, -1,         // EPISODE 4 BOSS SIGHTING
963
        ERLAUBENSND,            38, -1,         // EPISODE 6 BOSS SIGHTING
964
        DEATHSCREAM6SND,        39, -1,         // FART
965
        DEATHSCREAM7SND,        40, -1,         // GASP
966
        DEATHSCREAM8SND,        41, -1,         // GUH-BOY!
967
        DEATHSCREAM9SND,        42, -1,         // AH GEEZ!
968
        KEINSND,                43, -1,         // EPISODE 5 BOSS SIGHTING
969
        MEINSND,                44, -1,         // EPISODE 6 BOSS DIE
970
        ROSESND,                45, -1,         // EPISODE 5 BOSS DIE
971
 
972
#endif
973
#else
974
//
975
// SPEAR OF DESTINY DIGISOUNDS
976
//
977
        HALTSND,                0,  -1,
978
        CLOSEDOORSND,           2,  -1,
979
        OPENDOORSND,            3,  -1,
980
        ATKMACHINEGUNSND,       4,   0,
981
        ATKPISTOLSND,           5,   0,
982
        ATKGATLINGSND,          6,   0,
983
        SCHUTZADSND,            7,  -1,
984
        BOSSFIRESND,            8,   1,
985
        SSFIRESND,              9,  -1,
986
        DEATHSCREAM1SND,        10, -1,
987
        DEATHSCREAM2SND,        11, -1,
988
        TAKEDAMAGESND,          12, -1,
989
        PUSHWALLSND,            13, -1,
990
        AHHHGSND,               15, -1,
991
        LEBENSND,               16, -1,
992
        NAZIFIRESND,            17, -1,
993
        SLURPIESND,             18, -1,
994
        LEVELDONESND,           22, -1,
995
        DEATHSCREAM4SND,        23, -1,         // AIIEEE
996
        DEATHSCREAM3SND,        23, -1,         // DOUBLY-MAPPED!!!
997
        DEATHSCREAM5SND,        24, -1,         // DEE-DEE
998
        DEATHSCREAM6SND,        25, -1,         // FART
999
        DEATHSCREAM7SND,        26, -1,         // GASP
1000
        DEATHSCREAM8SND,        27, -1,         // GUH-BOY!
1001
        DEATHSCREAM9SND,        28, -1,         // AH GEEZ!
1002
        GETGATLINGSND,          38, -1,         // Got Gat replacement
1003
 
1004
#ifndef SPEARDEMO
1005
        DOGBARKSND,             1,  -1,
1006
        DOGDEATHSND,            14, -1,
1007
        SPIONSND,               19, -1,
1008
        NEINSOVASSND,           20, -1,
1009
        DOGATTACKSND,           21, -1,
1010
        TRANSSIGHTSND,          29, -1,         // Trans Sight
1011
        TRANSDEATHSND,          30, -1,         // Trans Death
1012
        WILHELMSIGHTSND,        31, -1,         // Wilhelm Sight
1013
        WILHELMDEATHSND,        32, -1,         // Wilhelm Death
1014
        UBERDEATHSND,           33, -1,         // Uber Death
1015
        KNIGHTSIGHTSND,         34, -1,         // Death Knight Sight
1016
        KNIGHTDEATHSND,         35, -1,         // Death Knight Death
1017
        ANGELSIGHTSND,          36, -1,         // Angel Sight
1018
        ANGELDEATHSND,          37, -1,         // Angel Death
1019
        GETSPEARSND,            39, -1,         // Got Spear replacement
1020
#endif
1021
#endif
1022
        LASTSOUND
1023
    };
1024
 
1025
 
1026
void InitDigiMap (void)
1027
{
1028
    int *map;
1029
 
1030
    for (map = wolfdigimap; *map != LASTSOUND; map += 3)
1031
    {
1032
        DigiMap[map[0]] = map[1];
1033
        DigiChannel[map[1]] = map[2];
1034
        SD_PrepareSound(map[1]);
1035
    }
1036
}
1037
 
1038
#ifndef SPEAR
1039
CP_iteminfo MusicItems={CTL_X,CTL_Y,6,0,32};
1040
CP_itemtype MusicMenu[]=
1041
    {
1042
        {1,"Get Them!",0},
1043
        {1,"Searching",0},
1044
        {1,"P.O.W.",0},
1045
        {1,"Suspense",0},
1046
        {1,"War March",0},
1047
        {1,"Around The Corner!",0},
1048
 
1049
        {1,"Nazi Anthem",0},
1050
        {1,"Lurking...",0},
1051
        {1,"Going After Hitler",0},
1052
        {1,"Pounding Headache",0},
1053
        {1,"Into the Dungeons",0},
1054
        {1,"Ultimate Conquest",0},
1055
 
1056
        {1,"Kill the S.O.B.",0},
1057
        {1,"The Nazi Rap",0},
1058
        {1,"Twelfth Hour",0},
1059
        {1,"Zero Hour",0},
1060
        {1,"Ultimate Conquest",0},
1061
        {1,"Wolfpack",0}
1062
    };
1063
#else
1064
CP_iteminfo MusicItems={CTL_X,CTL_Y-20,9,0,32};
1065
CP_itemtype MusicMenu[]=
1066
    {
1067
        {1,"Funky Colonel Bill",0},
1068
        {1,"Death To The Nazis",0},
1069
        {1,"Tiptoeing Around",0},
1070
        {1,"Is This THE END?",0},
1071
        {1,"Evil Incarnate",0},
1072
        {1,"Jazzin' Them Nazis",0},
1073
        {1,"Puttin' It To The Enemy",0},
1074
        {1,"The SS Gonna Get You",0},
1075
        {1,"Towering Above",0}
1076
    };
1077
#endif
1078
 
1079
#ifndef SPEARDEMO
1080
void DoJukebox(void)
1081
{
1082
    int which,lastsong=-1;
1083
    unsigned start;
1084
    unsigned songs[]=
1085
        {
1086
#ifndef SPEAR
1087
            GETTHEM_MUS,
1088
            SEARCHN_MUS,
1089
            POW_MUS,
1090
            SUSPENSE_MUS,
1091
            WARMARCH_MUS,
1092
            CORNER_MUS,
1093
 
1094
            NAZI_OMI_MUS,
1095
            PREGNANT_MUS,
1096
            GOINGAFT_MUS,
1097
            HEADACHE_MUS,
1098
            DUNGEON_MUS,
1099
            ULTIMATE_MUS,
1100
 
1101
            INTROCW3_MUS,
1102
            NAZI_RAP_MUS,
1103
            TWELFTH_MUS,
1104
            ZEROHOUR_MUS,
1105
            ULTIMATE_MUS,
1106
            PACMAN_MUS
1107
#else
1108
            XFUNKIE_MUS,             // 0
1109
            XDEATH_MUS,              // 2
1110
            XTIPTOE_MUS,             // 4
1111
            XTHEEND_MUS,             // 7
1112
            XEVIL_MUS,               // 17
1113
            XJAZNAZI_MUS,            // 18
1114
            XPUTIT_MUS,              // 21
1115
            XGETYOU_MUS,             // 22
1116
            XTOWER2_MUS              // 23
1117
#endif
1118
        };
1119
 
1120
    IN_ClearKeysDown();
1121
    if (!AdLibPresent && !SoundBlasterPresent)
1122
        return;
1123
 
1124
    MenuFadeOut();
1125
 
1126
#ifndef SPEAR
1127
#ifndef UPLOAD
1128
    start = ((SDL_GetTicks()/10)%3)*6;
1129
#else
1130
    start = 0;
1131
#endif
1132
#else
1133
    start = 0;
1134
#endif
1135
 
1136
    CA_CacheGrChunk (STARTFONT+1);
1137
#ifdef SPEAR
1138
    CacheLump (BACKDROP_LUMP_START,BACKDROP_LUMP_END);
1139
#else
1140
    CacheLump (CONTROLS_LUMP_START,CONTROLS_LUMP_END);
1141
#endif
1142
    CA_LoadAllSounds ();
1143
 
1144
    fontnumber=1;
1145
    ClearMScreen ();
1146
    VWB_DrawPic(112,184,C_MOUSELBACKPIC);
1147
    DrawStripes (10);
1148
    SETFONTCOLOR (TEXTCOLOR,BKGDCOLOR);
1149
 
1150
#ifndef SPEAR
1151
    DrawWindow (CTL_X-2,CTL_Y-6,280,13*7,BKGDCOLOR);
1152
#else
1153
    DrawWindow (CTL_X-2,CTL_Y-26,280,13*10,BKGDCOLOR);
1154
#endif
1155
 
1156
    DrawMenu (&MusicItems,&MusicMenu[start]);
1157
 
1158
    SETFONTCOLOR (READHCOLOR,BKGDCOLOR);
1159
    PrintY=15;
1160
    WindowX = 0;
1161
    WindowY = 320;
1162
    US_CPrint ("Robert's Jukebox");
1163
 
1164
    SETFONTCOLOR (TEXTCOLOR,BKGDCOLOR);
1165
    VW_UpdateScreen();
1166
    MenuFadeIn();
1167
 
1168
    do
1169
    {
1170
        which = HandleMenu(&MusicItems,&MusicMenu[start],NULL);
1171
        if (which>=0)
1172
        {
1173
            if (lastsong >= 0)
1174
                MusicMenu[start+lastsong].active = 1;
1175
 
1176
            StartCPMusic(songs[start + which]);
1177
            MusicMenu[start+which].active = 2;
1178
            DrawMenu (&MusicItems,&MusicMenu[start]);
1179
            VW_UpdateScreen();
1180
            lastsong = which;
1181
        }
1182
    } while(which>=0);
1183
 
1184
    MenuFadeOut();
1185
    IN_ClearKeysDown();
1186
#ifdef SPEAR
1187
    UnCacheLump (BACKDROP_LUMP_START,BACKDROP_LUMP_END);
1188
#else
1189
    UnCacheLump (CONTROLS_LUMP_START,CONTROLS_LUMP_END);
1190
#endif
1191
}
1192
#endif
1193
 
1194
/*
1195
==========================
1196
=
1197
= InitGame
1198
=
1199
= Load a few things right away
1200
=
1201
==========================
1202
*/
1203
 
1204
static void InitGame()
1205
{
1206
#ifndef SPEARDEMO
1207
    boolean didjukebox=false;
1208
#endif
1209
 
1210
    // initialize SDL
1211
#if defined _WIN32
1212
    putenv("SDL_VIDEODRIVER=directx");
1213
#endif
1214
    if(SDL_Init(SDL_INIT_VIDEO /*| SDL_INIT_AUDIO | SDL_INIT_JOYSTICK*/) < 0)
1215
    {
1216
        printf("Unable to init SDL: %s\n", SDL_GetError());
1217
        exit(1);
1218
    }
1219
    atexit(SDL_Quit);
1220
 
1221
    int numJoysticks = SDL_NumJoysticks();
1222
    if(param_joystickindex && (param_joystickindex < -1 || param_joystickindex >= numJoysticks))
1223
    {
1224
        if(!numJoysticks)
1225
            printf("No joysticks are available to SDL!\n");
1226
        else
1227
            printf("The joystick index must be between -1 and %i!\n", numJoysticks - 1);
1228
        exit(1);
1229
    }
1230
 
1231
#if defined(GP2X_940)
1232
    GP2X_MemoryInit();
1233
#endif
1234
 
1235
    SignonScreen ();
1236
 
1237
#if defined _WIN32
1238
    if(!fullscreen)
1239
    {
1240
        struct SDL_SysWMinfo wmInfo;
1241
        SDL_VERSION(&wmInfo.version);
1242
 
1243
        if(SDL_GetWMInfo(&wmInfo) != -1)
1244
        {
1245
            HWND hwndSDL = wmInfo.window;
1246
            DWORD style = GetWindowLong(hwndSDL, GWL_STYLE) & ~WS_SYSMENU;
1247
            SetWindowLong(hwndSDL, GWL_STYLE, style);
1248
            SetWindowPos(hwndSDL, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
1249
        }
1250
    }
1251
#endif
1252
	VW_UpdateScreen();
1253
 
1254
    VH_Startup ();
1255
    IN_Startup ();
1256
    PM_Startup ();
1257
    SD_Startup ();
1258
    CA_Startup ();
1259
    US_Startup ();
1260
 
1261
    // TODO: Will any memory checking be needed someday??
1262
#ifdef NOTYET
1263
#ifndef SPEAR
1264
    if (mminfo.mainmem < 235000L)
1265
#else
1266
    if (mminfo.mainmem < 257000L && !MS_CheckParm("debugmode"))
1267
#endif
1268
    {
1269
        byte *screen;
1270
 
1271
        CA_CacheGrChunk (ERRORSCREEN);
1272
        screen = grsegs[ERRORSCREEN];
1273
        ShutdownId();
1274
/*        memcpy((byte *)0xb8000,screen+7+7*160,17*160);
1275
        gotoxy (1,23);*/
1276
        exit(1);
1277
    }
1278
#endif
1279
 
1280
 
1281
//
1282
// build some tables
1283
//
1284
    InitDigiMap ();
1285
 
1286
    ReadConfig ();
1287
 
1288
    SetupSaveGames();
1289
 
1290
//
1291
// HOLDING DOWN 'M' KEY?
1292
//
1293
	IN_ProcessEvents();
1294
 
1295
#ifndef SPEARDEMO
1296
    if (Keyboard[sc_M])
1297
    {
1298
        DoJukebox();
1299
        didjukebox=true;
1300
    }
1301
    else
1302
#endif
1303
 
1304
//
1305
// draw intro screen stuff
1306
//
1307
    IntroScreen ();
1308
 
1309
#ifdef _arch_dreamcast
1310
    //TODO: VMU Selection Screen
1311
#endif
1312
 
1313
//
1314
// load in and lock down some basic chunks
1315
//
1316
 
1317
    CA_CacheGrChunk(STARTFONT);
1318
    CA_CacheGrChunk(STATUSBARPIC);
1319
 
1320
    LoadLatchMem ();
1321
    BuildTables ();          // trig tables
1322
    SetupWalls ();
1323
 
1324
    NewViewSize (viewsize);
1325
 
1326
//
1327
// initialize variables
1328
//
1329
    InitRedShifts ();
1330
#ifndef SPEARDEMO
1331
    if(!didjukebox)
1332
#endif
1333
        FinishSignon();
1334
 
1335
#ifdef NOTYET
1336
    vdisp = (byte *) (0xa0000+PAGE1START);
1337
    vbuf = (byte *) (0xa0000+PAGE2START);
1338
#endif
1339
}
1340
 
1341
//===========================================================================
1342
 
1343
/*
1344
==========================
1345
=
1346
= SetViewSize
1347
=
1348
==========================
1349
*/
1350
 
1351
boolean SetViewSize (unsigned width, unsigned height)
1352
{
1353
    viewwidth = width&~15;                  // must be divisable by 16
1354
    viewheight = height&~1;                 // must be even
1355
    centerx = viewwidth/2-1;
1356
    shootdelta = viewwidth/10;
1357
    if((unsigned) viewheight == screenHeight)
1358
        viewscreenx = viewscreeny = screenofs = 0;
1359
    else
1360
    {
1361
        viewscreenx = (screenWidth-viewwidth) / 2;
1362
        viewscreeny = (screenHeight-scaleFactor*STATUSLINES-viewheight)/2;
1363
        screenofs = viewscreeny*screenWidth+viewscreenx;
1364
    }
1365
 
1366
//
1367
// calculate trace angles and projection constants
1368
//
1369
    CalcProjection (FOCALLENGTH);
1370
 
1371
    return true;
1372
}
1373
 
1374
 
1375
void ShowViewSize (int width)
1376
{
1377
    int oldwidth,oldheight;
1378
 
1379
    oldwidth = viewwidth;
1380
    oldheight = viewheight;
1381
 
1382
    if(width == 21)
1383
    {
1384
        viewwidth = screenWidth;
1385
        viewheight = screenHeight;
1386
        VWB_BarScaledCoord (0, 0, screenWidth, screenHeight, 0);
1387
    }
1388
    else if(width == 20)
1389
    {
1390
        viewwidth = screenWidth;
1391
        viewheight = screenHeight - scaleFactor*STATUSLINES;
1392
        DrawPlayBorder ();
1393
    }
1394
    else
1395
    {
1396
        viewwidth = width*16*screenWidth/320;
1397
        viewheight = (int) (width*16*HEIGHTRATIO*screenHeight/200);
1398
        DrawPlayBorder ();
1399
    }
1400
 
1401
    viewwidth = oldwidth;
1402
    viewheight = oldheight;
1403
}
1404
 
1405
 
1406
void NewViewSize (int width)
1407
{
1408
    viewsize = width;
1409
    if(viewsize == 21)
1410
        SetViewSize(screenWidth, screenHeight);
1411
    else if(viewsize == 20)
1412
        SetViewSize(screenWidth, screenHeight - scaleFactor * STATUSLINES);
1413
    else
1414
        SetViewSize(width*16*screenWidth/320, (unsigned) (width*16*HEIGHTRATIO*screenHeight/200));
1415
}
1416
 
1417
 
1418
 
1419
//===========================================================================
1420
 
1421
/*
1422
==========================
1423
=
1424
= Quit
1425
=
1426
==========================
1427
*/
1428
 
1429
void Quit (const char *errorStr, ...)
1430
{
1431
#ifdef NOTYET
1432
    byte *screen;
1433
#endif
1434
    char error[256];
1435
    if(errorStr != NULL)
1436
    {
1437
        va_list vlist;
1438
        va_start(vlist, errorStr);
1439
        vsprintf(error, errorStr, vlist);
1440
        va_end(vlist);
1441
    }
1442
    else error[0] = 0;
1443
 
1444
    if (!pictable)  // don't try to display the red box before it's loaded
1445
    {
1446
        ShutdownId();
1447
        if (error && *error)
1448
        {
1449
#ifdef NOTYET
1450
            SetTextCursor(0,0);
1451
#endif
1452
            puts(error);
1453
#ifdef NOTYET
1454
            SetTextCursor(0,2);
1455
#endif
1456
            VW_WaitVBL(100);
1457
        }
1458
        exit(1);
1459
    }
1460
 
1461
    if (!error || !*error)
1462
    {
1463
#ifdef NOTYET
1464
        #ifndef JAPAN
1465
        CA_CacheGrChunk (ORDERSCREEN);
1466
        screen = grsegs[ORDERSCREEN];
1467
        #endif
1468
#endif
1469
        WriteConfig ();
1470
    }
1471
#ifdef NOTYET
1472
    else
1473
    {
1474
        CA_CacheGrChunk (ERRORSCREEN);
1475
        screen = grsegs[ERRORSCREEN];
1476
    }
1477
#endif
1478
 
1479
    ShutdownId ();
1480
 
1481
    if (error && *error)
1482
    {
1483
#ifdef NOTYET
1484
        memcpy((byte *)0xb8000,screen+7,7*160);
1485
        SetTextCursor(9,3);
1486
#endif
1487
        puts(error);
1488
#ifdef NOTYET
1489
        SetTextCursor(0,7);
1490
#endif
1491
        VW_WaitVBL(200);
1492
        exit(1);
1493
    }
1494
    else
1495
    if (!error || !(*error))
1496
    {
1497
#ifdef NOTYET
1498
        #ifndef JAPAN
1499
        memcpy((byte *)0xb8000,screen+7,24*160); // 24 for SPEAR/UPLOAD compatibility
1500
        #endif
1501
        SetTextCursor(0,23);
1502
#endif
1503
    }
1504
 
1505
    exit(0);
1506
}
1507
 
1508
//===========================================================================
1509
 
1510
 
1511
 
1512
/*
1513
=====================
1514
=
1515
= DemoLoop
1516
=
1517
=====================
1518
*/
1519
 
1520
 
1521
static void DemoLoop()
1522
{
1523
    int LastDemo = 0;
1524
 
1525
//
1526
// check for launch from ted
1527
//
1528
    if (param_tedlevel != -1)
1529
    {
1530
        param_nowait = true;
1531
        EnableEndGameMenuItem();
1532
        NewGame(param_difficulty,0);
1533
 
1534
#ifndef SPEAR
1535
        gamestate.episode = param_tedlevel/10;
1536
        gamestate.mapon = param_tedlevel%10;
1537
#else
1538
        gamestate.episode = 0;
1539
        gamestate.mapon = param_tedlevel;
1540
#endif
1541
        GameLoop();
1542
        Quit (NULL);
1543
    }
1544
 
1545
 
1546
//
1547
// main game cycle
1548
//
1549
 
1550
#ifndef DEMOTEST
1551
 
1552
    #ifndef UPLOAD
1553
 
1554
        #ifndef GOODTIMES
1555
        #ifndef SPEAR
1556
        #ifndef JAPAN
1557
        if (!param_nowait)
1558
            NonShareware();
1559
        #endif
1560
        #else
1561
            #ifndef GOODTIMES
1562
            #ifndef SPEARDEMO
1563
            extern void CopyProtection(void);
1564
            if(!param_goodtimes)
1565
                CopyProtection();
1566
            #endif
1567
            #endif
1568
        #endif
1569
        #endif
1570
    #endif
1571
 
1572
    StartCPMusic(INTROSONG);
1573
 
1574
#ifndef JAPAN
1575
    if (!param_nowait)
1576
        PG13 ();
1577
#endif
1578
 
1579
#endif
1580
 
1581
    while (1)
1582
    {
1583
        while (!param_nowait)
1584
        {
1585
//
1586
// title page
1587
//
1588
#ifndef DEMOTEST
1589
 
1590
#ifdef SPEAR
1591
            SDL_Color pal[256];
1592
            CA_CacheGrChunk (TITLEPALETTE);
1593
            VL_ConvertPalette(grsegs[TITLEPALETTE], pal, 256);
1594
 
1595
            CA_CacheGrChunk (TITLE1PIC);
1596
            VWB_DrawPic (0,0,TITLE1PIC);
1597
            UNCACHEGRCHUNK (TITLE1PIC);
1598
 
1599
            CA_CacheGrChunk (TITLE2PIC);
1600
            VWB_DrawPic (0,80,TITLE2PIC);
1601
            UNCACHEGRCHUNK (TITLE2PIC);
1602
            VW_UpdateScreen ();
1603
            VL_FadeIn(0,255,pal,30);
1604
 
1605
            UNCACHEGRCHUNK (TITLEPALETTE);
1606
#else
1607
            CA_CacheScreen (TITLEPIC);
1608
            VW_UpdateScreen ();
1609
            VW_FadeIn();
1610
#endif
1611
            if (IN_UserInput(TickBase*15))
1612
                break;
1613
            VW_FadeOut();
1614
//
1615
// credits page
1616
//
1617
            CA_CacheScreen (CREDITSPIC);
1618
            VW_UpdateScreen();
1619
            VW_FadeIn ();
1620
            if (IN_UserInput(TickBase*10))
1621
                break;
1622
            VW_FadeOut ();
1623
//
1624
// high scores
1625
//
1626
            DrawHighScores ();
1627
            VW_UpdateScreen ();
1628
            VW_FadeIn ();
1629
 
1630
            if (IN_UserInput(TickBase*10))
1631
                break;
1632
#endif
1633
//
1634
// demo
1635
//
1636
 
1637
            #ifndef SPEARDEMO
1638
            PlayDemo (LastDemo++%4);
1639
            #else
1640
            PlayDemo (0);
1641
            #endif
1642
 
1643
            if (playstate == ex_abort)
1644
                break;
1645
            VW_FadeOut();
1646
            if(screenHeight % 200 != 0)
1647
                VL_ClearScreen(0);
1648
            StartCPMusic(INTROSONG);
1649
        }
1650
 
1651
        VW_FadeOut ();
1652
 
1653
#ifdef DEBUGKEYS
1654
        if (Keyboard[sc_Tab] && param_debugmode)
1655
            RecordDemo ();
1656
        else
1657
            US_ControlPanel (0);
1658
#else
1659
        US_ControlPanel (0);
1660
#endif
1661
 
1662
        if (startgame || loadedgame)
1663
        {
1664
            GameLoop ();
1665
            if(!param_nowait)
1666
            {
1667
                VW_FadeOut();
1668
                StartCPMusic(INTROSONG);
1669
            }
1670
        }
1671
    }
1672
}
1673
 
1674
 
1675
//===========================================================================
1676
 
1677
#define IFARG(str) if(!strcmp(arg, (str)))
1678
 
1679
void CheckParameters(int argc, char *argv[])
1680
{
1681
    bool hasError = false, showHelp = false;
1682
    bool sampleRateGiven = false, audioBufferGiven = false;
1683
    int defaultSampleRate = param_samplerate;
1684
 
1685
    for(int i = 1; i < argc; i++)
1686
    {
1687
        char *arg = argv[i];
1688
#ifndef SPEAR
1689
        IFARG("--goobers")
1690
#else
1691
        IFARG("--debugmode")
1692
#endif
1693
            param_debugmode = true;
1694
        else IFARG("--baby")
1695
            param_difficulty = 0;
1696
        else IFARG("--easy")
1697
            param_difficulty = 1;
1698
        else IFARG("--normal")
1699
            param_difficulty = 2;
1700
        else IFARG("--hard")
1701
            param_difficulty = 3;
1702
        else IFARG("--nowait")
1703
            param_nowait = true;
1704
        else IFARG("--tedlevel")
1705
        {
1706
            if(++i >= argc)
1707
            {
1708
                printf("The tedlevel option is missing the level argument!\n");
1709
                hasError = true;
1710
            }
1711
            else param_tedlevel = atoi(argv[i]);
1712
        }
1713
        else IFARG("--windowed")
1714
            fullscreen = false;
1715
        else IFARG("--windowed-mouse")
1716
        {
1717
            fullscreen = false;
1718
            forcegrabmouse = true;
1719
        }
1720
        else IFARG("--res")
1721
        {
1722
            if(i + 2 >= argc)
1723
            {
1724
                printf("The res option needs the width and/or the height argument!\n");
1725
                hasError = true;
1726
            }
1727
            else
1728
            {
1729
                screenWidth = atoi(argv[++i]);
1730
                screenHeight = atoi(argv[++i]);
1731
                unsigned factor = screenWidth / 320;
1732
                if(screenWidth % 320 || screenHeight != 200 * factor && screenHeight != 240 * factor)
1733
                    printf("Screen size must be a multiple of 320x200 or 320x240!\n"), hasError = true;
1734
            }
1735
        }
1736
        else IFARG("--resf")
1737
        {
1738
            if(i + 2 >= argc)
1739
            {
1740
                printf("The resf option needs the width and/or the height argument!\n");
1741
                hasError = true;
1742
            }
1743
            else
1744
            {
1745
                screenWidth = atoi(argv[++i]);
1746
                screenHeight = atoi(argv[++i]);
1747
                if(screenWidth < 320)
1748
                    printf("Screen width must be at least 320!\n"), hasError = true;
1749
                if(screenHeight < 200)
1750
                    printf("Screen height must be at least 200!\n"), hasError = true;
1751
            }
1752
        }
1753
        else IFARG("--bits")
1754
        {
1755
            if(++i >= argc)
1756
            {
1757
                printf("The bits option is missing the color depth argument!\n");
1758
                hasError = true;
1759
            }
1760
            else
1761
            {
1762
                screenBits = atoi(argv[i]);
1763
                switch(screenBits)
1764
                {
1765
                    case 8:
1766
                    case 16:
1767
                    case 24:
1768
                    case 32:
1769
                        break;
1770
 
1771
                    default:
1772
                        printf("Screen color depth must be 8, 16, 24, or 32!\n");
1773
                        hasError = true;
1774
                        break;
1775
                }
1776
            }
1777
        }
1778
        else IFARG("--nodblbuf")
1779
            usedoublebuffering = false;
1780
        else IFARG("--extravbls")
1781
        {
1782
            if(++i >= argc)
1783
            {
1784
                printf("The extravbls option is missing the vbls argument!\n");
1785
                hasError = true;
1786
            }
1787
            else
1788
            {
1789
                extravbls = atoi(argv[i]);
1790
                if(extravbls < 0)
1791
                {
1792
                    printf("Extravbls must be positive!\n");
1793
                    hasError = true;
1794
                }
1795
            }
1796
        }
1797
        else IFARG("--joystick")
1798
        {
1799
            if(++i >= argc)
1800
            {
1801
                printf("The joystick option is missing the index argument!\n");
1802
                hasError = true;
1803
            }
1804
            else param_joystickindex = atoi(argv[i]);   // index is checked in InitGame
1805
        }
1806
        else IFARG("--joystickhat")
1807
        {
1808
            if(++i >= argc)
1809
            {
1810
                printf("The joystickhat option is missing the index argument!\n");
1811
                hasError = true;
1812
            }
1813
            else param_joystickhat = atoi(argv[i]);
1814
        }
1815
        else IFARG("--samplerate")
1816
        {
1817
            if(++i >= argc)
1818
            {
1819
                printf("The samplerate option is missing the rate argument!\n");
1820
                hasError = true;
1821
            }
1822
            else param_samplerate = atoi(argv[i]);
1823
            sampleRateGiven = true;
1824
        }
1825
        else IFARG("--audiobuffer")
1826
        {
1827
            if(++i >= argc)
1828
            {
1829
                printf("The audiobuffer option is missing the size argument!\n");
1830
                hasError = true;
1831
            }
1832
            else param_audiobuffer = atoi(argv[i]);
1833
            audioBufferGiven = true;
1834
        }
1835
        else IFARG("--mission")
1836
        {
1837
            if(++i >= argc)
1838
            {
1839
                printf("The mission option is missing the mission argument!\n");
1840
                hasError = true;
1841
            }
1842
            else
1843
            {
1844
                param_mission = atoi(argv[i]);
1845
                if(param_mission < 0 || param_mission > 3)
1846
                {
1847
                    printf("The mission option must be between 0 and 3!\n");
1848
                    hasError = true;
1849
                }
1850
            }
1851
        }
1852
        else IFARG("--configdir")
1853
        {
1854
            if(++i >= argc)
1855
            {
1856
                printf("The configdir option is missing the dir argument!\n");
1857
                hasError = true;
1858
            }
1859
            else
1860
            {
1861
                size_t len = strlen(argv[i]);
1862
                if(len + 2 > sizeof(configdir))
1863
                {
1864
                    printf("The config directory is too long!\n");
1865
                    hasError = true;
1866
                }
1867
                else
1868
                {
1869
                    strcpy(configdir, argv[i]);
1870
                    if(argv[i][len] != '/' && argv[i][len] != '\\')
1871
                        strcat(configdir, "/");
1872
                }
1873
            }
1874
        }
1875
        else IFARG("--goodtimes")
1876
            param_goodtimes = true;
1877
        else IFARG("--ignorenumchunks")
1878
            param_ignorenumchunks = true;
1879
        else IFARG("--help")
1880
            showHelp = true;
1881
        else hasError = true;
1882
    }
1883
    if(hasError || showHelp)
1884
    {
1885
        if(hasError) printf("\n");
1886
        printf(
1887
            "Wolf4SDL v1.7 ($Revision$)\n"
1888
            "Ported by Chaos-Software (http://www.chaos-software.de.vu)\n"
1889
            "Original Wolfenstein 3D by id Software\n\n"
1890
            "Usage: Wolf4SDL [options]\n"
1891
            "Options:\n"
1892
            " --help                 This help page\n"
1893
            " --tedlevel      Starts the game in the given level\n"
1894
            " --baby                 Sets the difficulty to baby for tedlevel\n"
1895
            " --easy                 Sets the difficulty to easy for tedlevel\n"
1896
            " --normal               Sets the difficulty to normal for tedlevel\n"
1897
            " --hard                 Sets the difficulty to hard for tedlevel\n"
1898
            " --nowait               Skips intro screens\n"
1899
            " --windowed[-mouse]     Starts the game in a window [and grabs mouse]\n"
1900
            " --res   Sets the screen resolution\n"
1901
            "                        (must be multiple of 320x200 or 320x240)\n"
1902
            " --resf           Sets any screen resolution >= 320x200\n"
1903
            "                        (which may result in graphic errors)\n"
1904
            " --bits              Sets the screen color depth\n"
1905
            "                        (use this when you have palette/fading problems\n"
1906
            "                        allowed: 8, 16, 24, 32, default: \"best\" depth)\n"
1907
            " --nodblbuf             Don't use SDL's double buffering\n"
1908
            " --extravbls      Sets a delay after each frame, which may help to\n"
1909
            "                        reduce flickering (unit is currently 8 ms, default: 0)\n"
1910
            " --joystick      Use the index-th joystick if available\n"
1911
            "                        (-1 to disable joystick, default: 0)\n"
1912
            " --joystickhat   Enables movement with the given coolie hat\n"
1913
            " --samplerate     Sets the sound sample rate (given in Hz, default: %i)\n"
1914
            " --audiobuffer    Sets the size of the audio buffer (-> sound latency)\n"
1915
            "                        (given in bytes, default: 2048 / (44100 / samplerate))\n"
1916
            " --ignorenumchunks      Ignores the number of chunks in VGAHEAD.*\n"
1917
            "                        (may be useful for some broken mods)\n"
1918
            " --configdir       Directory where config file and save games are stored\n"
1919
#if defined(_arch_dreamcast) || defined(_WIN32)
1920
            "                        (default: current directory)\n"
1921
#else
1922
            "                        (default: $HOME/.wolf4sdl)\n"
1923
#endif
1924
#if defined(SPEAR) && !defined(SPEARDEMO)
1925
            " --mission     Mission number to play (0-3)\n"
1926
            "                        (default: 0 -> .sod, 1-3 -> .sd*)\n"
1927
            " --goodtimes            Disable copy protection quiz\n"
1928
#endif
1929
            , defaultSampleRate
1930
        );
1931
        exit(1);
1932
    }
1933
 
1934
    if(sampleRateGiven && !audioBufferGiven)
1935
        param_audiobuffer = 2048 / (44100 / param_samplerate);
1936
}
1937
 
1938
/*
1939
==========================
1940
=
1941
= main
1942
=
1943
==========================
1944
*/
1945
 
1946
int main (int argc, char *argv[])
1947
{
1948
#if defined(_arch_dreamcast)
1949
    DC_Init();
1950
#else
1951
    CheckParameters(argc, argv);
1952
#endif
1953
 
1954
    CheckForEpisodes();
1955
 
1956
    InitGame();
1957
 
1958
    DemoLoop();
1959
 
1960
    Quit("Demo loop exited???");
1961
    return 1;
1962
}