home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 November / Chip_2002-11_cd1.bin / oddech / orbital / orbital.exe / src / snipe2d.cpp < prev    next >
C/C++ Source or Header  |  2002-07-15  |  15KB  |  481 lines

  1. ///////////////////////////////////////////////
  2. // 
  3. //  Snipe2d ludum dare 48h compo entry
  4. //
  5. //  Jari Komppa aka Sol 
  6. //  http://iki.fi/sol
  7. // 
  8. ///////////////////////////////////////////////
  9. // License
  10. ///////////////////////////////////////////////
  11. // 
  12. //     This software is provided 'as-is', without any express or implied
  13. //     warranty.    In no event will the authors be held liable for any damages
  14. //     arising from the use of this software.
  15. // 
  16. //     Permission is granted to anyone to use this software for any purpose,
  17. //     including commercial applications, and to alter it and redistribute it
  18. //     freely, subject to the following restrictions:
  19. // 
  20. //     1. The origin of this software must not be misrepresented; you must not
  21. //        claim that you wrote the original software. If you use this software
  22. //        in a product, an acknowledgment in the product documentation would be
  23. //        appreciated but is not required.
  24. //     2. Altered source versions must be plainly marked as such, and must not be
  25. //        misrepresented as being the original software.
  26. //     3. This notice may not be removed or altered from any source distribution.
  27. // 
  28. // (eg. same as ZLIB license)
  29. //
  30. ///////////////////////////////////////////////
  31. //
  32. // Houses are taken from a satellite picture of glasgow.
  33. //
  34. // The sources are a mess, as I didn't even try to do anything
  35. // really organized here.. and hey, it's a 48h compo =)
  36. //
  37.  
  38. #include "snipe2d.h"
  39.  
  40. SDL_Surface *gScreen;
  41. SDL_Surface *gMap;
  42. SDL_Surface *gAIMap;
  43. SDL_Surface *gFont[5];
  44.  
  45. float gMouseX = 0, gMouseY = 0, gMouseZ = 1.0f, gCoordScale = 1.0f;
  46. float gWobbleX, gWobbleY, gCenterX, gCenterY;
  47. int gControlState = 0;
  48.  
  49. int gCharacterCount;
  50. CHARACTER *gCharacter;
  51. SPAWNPOINT *gSpawnpoint;
  52. WAYPOINT *gWaypoint;
  53. int gWaypointCount;
  54. int gSpawnpointCount;
  55. int gStartTick;
  56. int gFrameCount;
  57. int gLastTick;
  58. int gGameStartTick;
  59. int gReloading = 0;
  60. int gScore = 0;
  61. float gVIPSpawnTime;
  62. float gVIPSpawnTimePeriod;
  63. float gBadGuySpawnTime;
  64. float gBadGuySpawnTimePeriod;
  65. int gVIPCount = 0;
  66. int gBadGuyCount = 0;
  67. int gWobbleIndex;
  68. int gGameState;
  69. int gPedestrianSpawnCount = 0;
  70. int gBadGuySpawnCount = 0;
  71. int gVIPSpawnCount = 0;
  72. int gVIPsGottenToSafety = 0;
  73. int gPedestriansKilled = 0;
  74. int gBadGuisKilled = 0;
  75. SDL_Surface *gCharSprite;
  76. CHARACTER *gSightedCharacter = NULL;
  77.  
  78. SDL_AudioSpec *gAudioSpec = NULL;
  79. short *gAudioZoomSample = NULL;
  80. short *gAudioFireSample = NULL;
  81. short *gAudioZoomOut = NULL;
  82. short *gAudioZoomIn = NULL;
  83. short *gAudioFire = NULL;
  84. int gAudioZoomSampleLen = 0;
  85. int gAudioZoomOutLen = 0;
  86. int gAudioZoomInLen = 0;
  87. int gAudioZoomOfs = 0;
  88. int gAudioFireOfs = 0;
  89. int gAudioFireSampleLen = 0;
  90. int gAudioFireLen = 0;
  91. int gPlaySound = 0;
  92.  
  93. void reinit()
  94. {
  95.  
  96.     gMouseX = 0;
  97.     gMouseY = 0;
  98.     gMouseZ = 1.0f;
  99.     gCoordScale = 1.0f;
  100.     gWobbleX = 0;
  101.     gWobbleY = 0;
  102.     gCenterX = 0;
  103.     gCenterY = 0;
  104.     gControlState = 0;
  105.     gReloading = 0;
  106.     gScore = 0;
  107.     gVIPCount = 0;
  108.     gBadGuyCount = 0;
  109.     gWobbleIndex = 0;
  110.     gVIPsGottenToSafety = 0;
  111.     gPedestriansKilled = 0;
  112.     gBadGuisKilled = 0;
  113.     gSightedCharacter = NULL;
  114.  
  115.     int i;
  116.     for (i = 0; i < gCharacterCount; i++)
  117.     {
  118.         gCharacter[i].mType = -1;
  119.     }
  120.     for (i = 0; i < (int)(gCharacterCount * 0.75f); i++)
  121.     {
  122.         int id = spawn_ai(2);
  123.         int j;
  124.         for (j = 0; j < 1000; j++) // Run 1000 physics loops for all pedestrians..
  125.             handle_ai(gCharacter[id]);
  126.     }
  127.     gVIPSpawnTime = 2000;
  128.     gVIPSpawnTimePeriod = 20000;
  129.     gBadGuySpawnTime = 3000;
  130.     gBadGuySpawnTimePeriod = 8000;
  131.     gWobbleIndex = 0;
  132.     gStartTick = GetTickCount();
  133.     gFrameCount = 0;
  134.     gLastTick = GetTickCount();
  135.     gGameState = 1;
  136.     gGameStartTick = GetTickCount();
  137.  
  138. }
  139.  
  140. void init()
  141. {
  142.     SDL_Surface *temp = SDL_LoadBMP("citee2.bmp");
  143.     gMap = SDL_ConvertSurface(temp, gScreen->format,SDL_SWSURFACE);
  144.     SDL_FreeSurface(temp);
  145.     
  146.     temp = SDL_LoadBMP("charseq.bmp");
  147.     gCharSprite = SDL_ConvertSurface(temp, gScreen->format,SDL_SWSURFACE);
  148.     SDL_FreeSurface(temp);
  149.     
  150.     gAIMap = SDL_LoadBMP("aimap.bmp");
  151.     
  152.     // Okay, this is ugly. Load font several times & change the color of each.
  153.     
  154.     int i;
  155.     for (i = 0; i < 5; i++)
  156.     {
  157.         gFont[i] = SDL_LoadBMP("font4x6.bmp");
  158.         SDL_SetColorKey(gFont[i],SDL_SRCCOLORKEY,1); // set color index 1 (black) transparent
  159.     }
  160.     *(int*)&(gFont[0]->format->palette->colors[0]) = 0x000000; // black
  161.     *(int*)&(gFont[1]->format->palette->colors[0]) = 0xffffff; // white
  162.     *(int*)&(gFont[2]->format->palette->colors[0]) = 0x00ff00; // green
  163.     *(int*)&(gFont[3]->format->palette->colors[0]) = 0x00ffff; // yellow
  164.     *(int*)&(gFont[4]->format->palette->colors[0]) = 0x0000ff; // red
  165.     
  166.     SDL_ShowCursor(0);
  167.     SDL_WM_GrabInput(SDL_GRAB_ON);
  168.     
  169.     precalc_ai();
  170.     
  171.     gCharacter = new CHARACTER[2048];
  172.     gCharacterCount = 2048;
  173.  
  174.     
  175. #ifdef PLAY_AUDIO
  176.     SDL_AudioSpec as;
  177.     SDL_LoadWAV("camera_in.wav", &as, (Uint8 **)&gAudioZoomIn, (Uint32 *)&gAudioZoomInLen);
  178.     SDL_LoadWAV("camera_out.wav", &as, (Uint8 **)&gAudioZoomOut, (Uint32 *)&gAudioZoomOutLen);
  179.     SDL_LoadWAV("twang.wav", &as, (Uint8 **)&gAudioFire, (Uint32 *)&gAudioFireLen);
  180.     gAudioZoomInLen /= 2;
  181.     gAudioZoomOutLen /= 2;
  182.     gAudioFireLen /= 2;
  183.     
  184.     SDL_PauseAudio(0); // let it play
  185. #endif
  186.     reinit();
  187. }
  188.  
  189. #define PHYSICS_MS 10
  190. // 10ms physics loops == 100 loops per sec, 'should be enough'..
  191.  
  192. void reindeer()
  193. {    
  194.     gSightedCharacter = NULL;
  195.     int tick = GetTickCount();    
  196.     gFrameCount++;
  197.     if (gReloading)
  198.     {
  199.         gReloading -= tick - gLastTick;
  200.         if (gReloading < 0)
  201.             gReloading = 0;
  202.     }
  203.     
  204.     gCenterX = (640.0f - 640.0f * gCoordScale) / 2;
  205.     gCenterY = (480.0f - 480.0f * gCoordScale) / 2;
  206.     gWobbleX = (float)(sin(gWobbleIndex * 0.000654387) + 
  207.         sin(gWobbleIndex * 0.000547867)*2 + 
  208.         sin(gWobbleIndex * 0.000700133)) * (WOBBLE / 4.0f);
  209.     gWobbleY = (float)(sin(gWobbleIndex * 0.000537234) + 
  210.         sin(gWobbleIndex * 0.000732897) + 
  211.         sin(gWobbleIndex * 0.000600613)*2) * (WOBBLE / 4.0f);
  212.     
  213.     
  214.     
  215. #ifdef UNREAL_DITHER
  216.     zoom_unreal(gMap, gMouseX + gCenterX + gWobbleX, gMouseY + gCenterY + gWobbleY, gCoordScale);    
  217. #else
  218.     zoom(gMap, gMouseX + gCenterX + gWobbleX, gMouseY + gCenterY + gWobbleX, gCoordScale);    
  219. #endif   
  220.     
  221.     int i;
  222.     int physics_loops = (tick - gLastTick) / PHYSICS_MS;
  223.     int j;
  224.     for (i = 0; i < gCharacterCount; i++)
  225.     {
  226.         for (j = 0; j < physics_loops; j++)
  227.             handle_ai(gCharacter[i]);
  228.         if (!gGameState)
  229.             return;
  230.         drawCharacter(gCharacter[i]);
  231.     }
  232.     
  233.     target();
  234.     
  235.     for (j = 0; j < physics_loops; j++)
  236.     {
  237.         int physicstick = gLastTick - gGameStartTick;
  238.         gWobbleIndex += PHYSICS_MS;
  239.         
  240.         // spawn VIPs
  241.         if (physicstick >= gVIPSpawnTime)
  242.         {
  243.             
  244.             if (gVIPCount == 2 && rand() < 2048)
  245.                 spawn_ai(1);
  246.             if (gVIPCount == 1 && rand() < 8192)
  247.                 spawn_ai(1);
  248.             if (gVIPCount == 0)            
  249.                 spawn_ai(1);
  250.             gVIPSpawnTime += (int)gVIPSpawnTimePeriod;
  251.         }
  252.         // spawn baddies
  253.         if (physicstick >= gBadGuySpawnTime)
  254.         {
  255.             spawn_ai(0);
  256.             gBadGuySpawnTime += (int)gBadGuySpawnTimePeriod;
  257.         }
  258.         if (((gLastTick / PHYSICS_MS) & 3) == 0) 
  259.             gBadGuySpawnTimePeriod--;
  260.         
  261.         if (gBadGuySpawnTimePeriod < 3000)
  262.             gBadGuySpawnTimePeriod = 3000; // Eventually it will be impossible to kill all bad guys.
  263.         
  264.         gLastTick += PHYSICS_MS;     
  265.     }
  266.     
  267.     
  268.     SDL_UpdateRect(gScreen, 0, 0, 640, 480);    
  269. }
  270.  
  271. void audiomixer(void *userdata, Uint8 *stream, int len)
  272. {
  273.     int l = len / 2;
  274.     short * buf = (short*)stream;
  275.     memset(stream,0,len);
  276.     if (gPlaySound & (1<<1))
  277.     {
  278.         gPlaySound &= ~(1<<1);
  279.         gAudioZoomOfs = 0;
  280.         gAudioZoomSample = gAudioZoomOut;
  281.         gAudioZoomSampleLen = gAudioZoomOutLen;
  282.     }
  283.     if (gPlaySound & (1<<2))
  284.     {
  285.         gPlaySound &= ~(1<<2);
  286.         gAudioZoomOfs = 0;
  287.         gAudioZoomSample = gAudioZoomIn;
  288.         gAudioZoomSampleLen = gAudioZoomInLen;
  289.     }
  290.     if (gPlaySound & (1<<3))
  291.     {
  292.         gPlaySound &= ~(1<<3);
  293.         gAudioFireOfs = 0;
  294.         gAudioFireSample = gAudioFire;
  295.         gAudioFireSampleLen = gAudioFireLen;
  296.     }
  297.     if (gAudioZoomSample != NULL)
  298.     {
  299.         int n = l;
  300.         if (n + gAudioZoomOfs > gAudioZoomSampleLen)
  301.             n = gAudioZoomSampleLen - gAudioZoomOfs;
  302.         int i;
  303.         for (i = 0; i < n; i++)
  304.             buf[i] = gAudioZoomSample[i + gAudioZoomOfs] / 2;
  305.         gAudioZoomOfs += n;
  306.         if (l != n)
  307.         {
  308.             gAudioZoomSample = NULL;
  309.         }
  310.     }
  311.     if (gAudioFireSample != NULL)
  312.     {
  313.         int n = l;
  314.         if (n + gAudioFireOfs > gAudioFireSampleLen)
  315.             n = gAudioFireSampleLen - gAudioFireOfs;
  316.         int i;
  317.         for (i = 0; i < n; i++)
  318.             buf[i] += gAudioFireSample[i + gAudioFireOfs] / 2;
  319.         gAudioFireOfs += n;
  320.         if (l != n)
  321.         {
  322.             gAudioFireSample = NULL;
  323.         }
  324.     }    
  325. }
  326.  
  327. void play_sound(int aSound)
  328. {
  329.     SDL_LockAudio();
  330.     gPlaySound |= 1 << aSound;
  331.     SDL_UnlockAudio();
  332. }
  333.  
  334. int main(int argc, char *argv[])
  335. {
  336.     srand(GetTickCount());
  337.     
  338.     
  339.     //if ( SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0 ) 
  340.     if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) 
  341.     {
  342.         fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
  343.         exit(1);
  344.     }
  345.     
  346.     atexit(SDL_Quit);
  347.     
  348.     //gScreen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE); 
  349.     gScreen = SDL_SetVideoMode(640, 480, 16, SDL_FULLSCREEN | SDL_SWSURFACE);
  350.     if (gScreen == NULL) 
  351.     {
  352.         fprintf(stderr, "Unable to set 640x480 video: %s\n", SDL_GetError());
  353.         exit(1);
  354.     }
  355.     
  356. #ifdef PLAY_AUDIO
  357.     SDL_AudioSpec *as = new SDL_AudioSpec;
  358.     as->freq = 44100;
  359.     as->format = AUDIO_S16;
  360.     as->channels = 2;
  361.     as->samples = 4096;
  362.     as->callback = audiomixer;
  363.     as->userdata = NULL;
  364.     if (SDL_OpenAudio(as, NULL) < 0)
  365.     {
  366.         fprintf(stderr, "Unable to init SDL audio: %s\n", SDL_GetError());
  367.         exit(1);
  368.     }
  369.     gAudioSpec = as;
  370. #endif
  371.     
  372. #ifdef DISPLAY_LOGO_SCREEN
  373.     logoscreen();
  374. #else
  375.     init();
  376. #endif
  377.     
  378.     gGameStartTick = GetTickCount();
  379.     gLastTick = gGameStartTick;
  380.     
  381.     while (1)
  382.     {
  383.         if (!gGameState)
  384.             reinit();
  385.         reindeer();
  386.         if (gGameState)
  387.         {
  388.             SDL_Event event;
  389.             while ( SDL_PollEvent(&event) ) 
  390.             {
  391.                 switch (event.type) 
  392.                 {
  393.                 case SDL_KEYUP:
  394.                     if (event.key.keysym.sym == SDLK_ESCAPE)
  395. #ifdef DISPLAY_GAMEOVER_SCREEN
  396.                         gameoverscreen(0);
  397. #else
  398.                     return 0;
  399. #endif
  400.                     break;
  401.                 case SDL_MOUSEMOTION:
  402.                     if (gControlState == 0)
  403.                     {
  404.                         gMouseX += event.motion.xrel * gCoordScale;
  405.                         gMouseY += event.motion.yrel * gCoordScale;
  406.                         if (gMouseX < -320) gMouseX = -320;
  407.                         if (gMouseY < -240) gMouseY = -240;
  408.                         if (gMouseX > (800 - 320)) gMouseX = (800 - 320);
  409.                         if (gMouseY > (600 - 240)) gMouseY = (600 - 240);
  410.                     }
  411.                     if (gControlState == 1)
  412.                     {
  413.                         gMouseZ += event.motion.yrel * 0.005f;
  414.                         if (gMouseZ > 1.25) gMouseZ = 1.25;
  415.                         if (gMouseZ < 0.05f) gMouseZ = 0.05f;
  416.                         float oldcoord = gCoordScale;
  417. #ifndef CAMERA_STEPS
  418.                         gCoordScale = gMouseZ;
  419. #else
  420.                         gCoordScale = ((int)(gMouseZ * 4)) / 4.0f;
  421.                         if (gCoordScale < 0.05f) gCoordScale = 0.05f;
  422. #endif
  423.                         if (oldcoord < gCoordScale)
  424.                             play_sound(1);
  425.                         if (oldcoord > gCoordScale)
  426.                             play_sound(2);
  427.                     }
  428.                     break;
  429.                 case SDL_MOUSEBUTTONDOWN:
  430.                     if (event.button.button == SDL_BUTTON_RIGHT)
  431.                     {
  432.                         // zooming mode
  433.                         gControlState = 1;
  434.                     }
  435.                     if (event.button.button == SDL_BUTTON_LEFT)
  436.                     {
  437.                         if (!gReloading)
  438.                         {
  439.                             play_sound(3);
  440.                             shoot();
  441.                         }
  442.                     }
  443.                     // SDL kludgy mouse wheel-o-rama:
  444.                     if (event.button.button == 4 || event.button.button == 5)
  445.                     {
  446.                         gMouseZ += (event.button.button == 5) ? 0.2f : -0.2f;
  447.                         if (gMouseZ > 1.25) gMouseZ = 1.25;
  448.                         if (gMouseZ < 0.05f) gMouseZ = 0.05f;
  449.                         float oldcoord = gCoordScale;
  450. #ifndef CAMERA_STEPS
  451.                         gCoordScale = gMouseZ;
  452. #else
  453.                         gCoordScale = ((int)(gMouseZ * 4)) / 4.0f;
  454.                         if (gCoordScale < 0.05f) gCoordScale = 0.05f;
  455. #endif
  456.                         if (oldcoord < gCoordScale)
  457.                             play_sound(1);
  458.                         if (oldcoord > gCoordScale)
  459.                             play_sound(2);
  460.                         
  461.                     }
  462.                     break;
  463.                 case SDL_MOUSEBUTTONUP:
  464.                     if (event.button.button == SDL_BUTTON_RIGHT)
  465.                     {
  466.                         // targeting mode
  467.                         gControlState = 0;
  468.                     }
  469.                     break;
  470.                     
  471.                     
  472.                 case SDL_QUIT:
  473.                     return(0);
  474.                 }
  475.             }
  476.         }
  477.     }
  478.     return 0;
  479. }
  480.  
  481.