Subversion Repositories Kolibri OS

Rev

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