Subversion Repositories Kolibri OS

Rev

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