Subversion Repositories Kolibri OS

Rev

Rev 9133 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

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