summaryrefslogtreecommitdiff
path: root/apps/plugins/sdl/progs/wolf3d/wl_main.c
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2019-07-07 22:00:20 -0400
committerFranklin Wei <git@fwei.tk>2019-07-09 11:20:55 -0400
commit3f59fc8b771625aca9c3aefe03cf1038d8461963 (patch)
treee0623a323613baa0b0993411b38bcaed144b27ed /apps/plugins/sdl/progs/wolf3d/wl_main.c
parent439a0d1d91fa040d261fc39b87278bc9f5391dcc (diff)
downloadrockbox-3f59fc8b771625aca9c3aefe03cf1038d8461963.tar.gz
rockbox-3f59fc8b771625aca9c3aefe03cf1038d8461963.zip
Wolfenstein 3-D!
This is a port of Wolf4SDL, which is derived from the original id software source release. The port runs on top of the SDL plugin runtime and is loaded as an overlay. Licensing of the game code is not an issue, as discussed below (essentially, the Debian project treats Wolf4SDL as GPLv2, with an email from John Carmack backing it up): http://forums.rockbox.org/index.php?topic=52872 Included is a copy of MAME's Yamaha OPL sound chip emulator (fmopl_gpl.c). This file was not part of the original Wolf4SDL source (which includes a non-GPL'd version), but was rather rebased from from a later MAME source which had been relicensed to GPLv2. Change-Id: I64c2ba035e0be7e2f49252f40640641416613439
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}