Subversion Repositories Kolibri OS

Rev

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