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