home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2002 November
/
Chip_2002-11_cd1.bin
/
oddech
/
orbital
/
orbital.exe
/
src
/
snipe2d.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
2002-07-15
|
15KB
|
481 lines
///////////////////////////////////////////////
//
// Snipe2d ludum dare 48h compo entry
//
// Jari Komppa aka Sol
// http://iki.fi/sol
//
///////////////////////////////////////////////
// License
///////////////////////////////////////////////
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
//
// (eg. same as ZLIB license)
//
///////////////////////////////////////////////
//
// Houses are taken from a satellite picture of glasgow.
//
// The sources are a mess, as I didn't even try to do anything
// really organized here.. and hey, it's a 48h compo =)
//
#include "snipe2d.h"
SDL_Surface *gScreen;
SDL_Surface *gMap;
SDL_Surface *gAIMap;
SDL_Surface *gFont[5];
float gMouseX = 0, gMouseY = 0, gMouseZ = 1.0f, gCoordScale = 1.0f;
float gWobbleX, gWobbleY, gCenterX, gCenterY;
int gControlState = 0;
int gCharacterCount;
CHARACTER *gCharacter;
SPAWNPOINT *gSpawnpoint;
WAYPOINT *gWaypoint;
int gWaypointCount;
int gSpawnpointCount;
int gStartTick;
int gFrameCount;
int gLastTick;
int gGameStartTick;
int gReloading = 0;
int gScore = 0;
float gVIPSpawnTime;
float gVIPSpawnTimePeriod;
float gBadGuySpawnTime;
float gBadGuySpawnTimePeriod;
int gVIPCount = 0;
int gBadGuyCount = 0;
int gWobbleIndex;
int gGameState;
int gPedestrianSpawnCount = 0;
int gBadGuySpawnCount = 0;
int gVIPSpawnCount = 0;
int gVIPsGottenToSafety = 0;
int gPedestriansKilled = 0;
int gBadGuisKilled = 0;
SDL_Surface *gCharSprite;
CHARACTER *gSightedCharacter = NULL;
SDL_AudioSpec *gAudioSpec = NULL;
short *gAudioZoomSample = NULL;
short *gAudioFireSample = NULL;
short *gAudioZoomOut = NULL;
short *gAudioZoomIn = NULL;
short *gAudioFire = NULL;
int gAudioZoomSampleLen = 0;
int gAudioZoomOutLen = 0;
int gAudioZoomInLen = 0;
int gAudioZoomOfs = 0;
int gAudioFireOfs = 0;
int gAudioFireSampleLen = 0;
int gAudioFireLen = 0;
int gPlaySound = 0;
void reinit()
{
gMouseX = 0;
gMouseY = 0;
gMouseZ = 1.0f;
gCoordScale = 1.0f;
gWobbleX = 0;
gWobbleY = 0;
gCenterX = 0;
gCenterY = 0;
gControlState = 0;
gReloading = 0;
gScore = 0;
gVIPCount = 0;
gBadGuyCount = 0;
gWobbleIndex = 0;
gVIPsGottenToSafety = 0;
gPedestriansKilled = 0;
gBadGuisKilled = 0;
gSightedCharacter = NULL;
int i;
for (i = 0; i < gCharacterCount; i++)
{
gCharacter[i].mType = -1;
}
for (i = 0; i < (int)(gCharacterCount * 0.75f); i++)
{
int id = spawn_ai(2);
int j;
for (j = 0; j < 1000; j++) // Run 1000 physics loops for all pedestrians..
handle_ai(gCharacter[id]);
}
gVIPSpawnTime = 2000;
gVIPSpawnTimePeriod = 20000;
gBadGuySpawnTime = 3000;
gBadGuySpawnTimePeriod = 8000;
gWobbleIndex = 0;
gStartTick = GetTickCount();
gFrameCount = 0;
gLastTick = GetTickCount();
gGameState = 1;
gGameStartTick = GetTickCount();
}
void init()
{
SDL_Surface *temp = SDL_LoadBMP("citee2.bmp");
gMap = SDL_ConvertSurface(temp, gScreen->format,SDL_SWSURFACE);
SDL_FreeSurface(temp);
temp = SDL_LoadBMP("charseq.bmp");
gCharSprite = SDL_ConvertSurface(temp, gScreen->format,SDL_SWSURFACE);
SDL_FreeSurface(temp);
gAIMap = SDL_LoadBMP("aimap.bmp");
// Okay, this is ugly. Load font several times & change the color of each.
int i;
for (i = 0; i < 5; i++)
{
gFont[i] = SDL_LoadBMP("font4x6.bmp");
SDL_SetColorKey(gFont[i],SDL_SRCCOLORKEY,1); // set color index 1 (black) transparent
}
*(int*)&(gFont[0]->format->palette->colors[0]) = 0x000000; // black
*(int*)&(gFont[1]->format->palette->colors[0]) = 0xffffff; // white
*(int*)&(gFont[2]->format->palette->colors[0]) = 0x00ff00; // green
*(int*)&(gFont[3]->format->palette->colors[0]) = 0x00ffff; // yellow
*(int*)&(gFont[4]->format->palette->colors[0]) = 0x0000ff; // red
SDL_ShowCursor(0);
SDL_WM_GrabInput(SDL_GRAB_ON);
precalc_ai();
gCharacter = new CHARACTER[2048];
gCharacterCount = 2048;
#ifdef PLAY_AUDIO
SDL_AudioSpec as;
SDL_LoadWAV("camera_in.wav", &as, (Uint8 **)&gAudioZoomIn, (Uint32 *)&gAudioZoomInLen);
SDL_LoadWAV("camera_out.wav", &as, (Uint8 **)&gAudioZoomOut, (Uint32 *)&gAudioZoomOutLen);
SDL_LoadWAV("twang.wav", &as, (Uint8 **)&gAudioFire, (Uint32 *)&gAudioFireLen);
gAudioZoomInLen /= 2;
gAudioZoomOutLen /= 2;
gAudioFireLen /= 2;
SDL_PauseAudio(0); // let it play
#endif
reinit();
}
#define PHYSICS_MS 10
// 10ms physics loops == 100 loops per sec, 'should be enough'..
void reindeer()
{
gSightedCharacter = NULL;
int tick = GetTickCount();
gFrameCount++;
if (gReloading)
{
gReloading -= tick - gLastTick;
if (gReloading < 0)
gReloading = 0;
}
gCenterX = (640.0f - 640.0f * gCoordScale) / 2;
gCenterY = (480.0f - 480.0f * gCoordScale) / 2;
gWobbleX = (float)(sin(gWobbleIndex * 0.000654387) +
sin(gWobbleIndex * 0.000547867)*2 +
sin(gWobbleIndex * 0.000700133)) * (WOBBLE / 4.0f);
gWobbleY = (float)(sin(gWobbleIndex * 0.000537234) +
sin(gWobbleIndex * 0.000732897) +
sin(gWobbleIndex * 0.000600613)*2) * (WOBBLE / 4.0f);
#ifdef UNREAL_DITHER
zoom_unreal(gMap, gMouseX + gCenterX + gWobbleX, gMouseY + gCenterY + gWobbleY, gCoordScale);
#else
zoom(gMap, gMouseX + gCenterX + gWobbleX, gMouseY + gCenterY + gWobbleX, gCoordScale);
#endif
int i;
int physics_loops = (tick - gLastTick) / PHYSICS_MS;
int j;
for (i = 0; i < gCharacterCount; i++)
{
for (j = 0; j < physics_loops; j++)
handle_ai(gCharacter[i]);
if (!gGameState)
return;
drawCharacter(gCharacter[i]);
}
target();
for (j = 0; j < physics_loops; j++)
{
int physicstick = gLastTick - gGameStartTick;
gWobbleIndex += PHYSICS_MS;
// spawn VIPs
if (physicstick >= gVIPSpawnTime)
{
if (gVIPCount == 2 && rand() < 2048)
spawn_ai(1);
if (gVIPCount == 1 && rand() < 8192)
spawn_ai(1);
if (gVIPCount == 0)
spawn_ai(1);
gVIPSpawnTime += (int)gVIPSpawnTimePeriod;
}
// spawn baddies
if (physicstick >= gBadGuySpawnTime)
{
spawn_ai(0);
gBadGuySpawnTime += (int)gBadGuySpawnTimePeriod;
}
if (((gLastTick / PHYSICS_MS) & 3) == 0)
gBadGuySpawnTimePeriod--;
if (gBadGuySpawnTimePeriod < 3000)
gBadGuySpawnTimePeriod = 3000; // Eventually it will be impossible to kill all bad guys.
gLastTick += PHYSICS_MS;
}
SDL_UpdateRect(gScreen, 0, 0, 640, 480);
}
void audiomixer(void *userdata, Uint8 *stream, int len)
{
int l = len / 2;
short * buf = (short*)stream;
memset(stream,0,len);
if (gPlaySound & (1<<1))
{
gPlaySound &= ~(1<<1);
gAudioZoomOfs = 0;
gAudioZoomSample = gAudioZoomOut;
gAudioZoomSampleLen = gAudioZoomOutLen;
}
if (gPlaySound & (1<<2))
{
gPlaySound &= ~(1<<2);
gAudioZoomOfs = 0;
gAudioZoomSample = gAudioZoomIn;
gAudioZoomSampleLen = gAudioZoomInLen;
}
if (gPlaySound & (1<<3))
{
gPlaySound &= ~(1<<3);
gAudioFireOfs = 0;
gAudioFireSample = gAudioFire;
gAudioFireSampleLen = gAudioFireLen;
}
if (gAudioZoomSample != NULL)
{
int n = l;
if (n + gAudioZoomOfs > gAudioZoomSampleLen)
n = gAudioZoomSampleLen - gAudioZoomOfs;
int i;
for (i = 0; i < n; i++)
buf[i] = gAudioZoomSample[i + gAudioZoomOfs] / 2;
gAudioZoomOfs += n;
if (l != n)
{
gAudioZoomSample = NULL;
}
}
if (gAudioFireSample != NULL)
{
int n = l;
if (n + gAudioFireOfs > gAudioFireSampleLen)
n = gAudioFireSampleLen - gAudioFireOfs;
int i;
for (i = 0; i < n; i++)
buf[i] += gAudioFireSample[i + gAudioFireOfs] / 2;
gAudioFireOfs += n;
if (l != n)
{
gAudioFireSample = NULL;
}
}
}
void play_sound(int aSound)
{
SDL_LockAudio();
gPlaySound |= 1 << aSound;
SDL_UnlockAudio();
}
int main(int argc, char *argv[])
{
srand(GetTickCount());
//if ( SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0 )
if ( SDL_Init(SDL_INIT_VIDEO) < 0 )
{
fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
exit(1);
}
atexit(SDL_Quit);
//gScreen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE);
gScreen = SDL_SetVideoMode(640, 480, 16, SDL_FULLSCREEN | SDL_SWSURFACE);
if (gScreen == NULL)
{
fprintf(stderr, "Unable to set 640x480 video: %s\n", SDL_GetError());
exit(1);
}
#ifdef PLAY_AUDIO
SDL_AudioSpec *as = new SDL_AudioSpec;
as->freq = 44100;
as->format = AUDIO_S16;
as->channels = 2;
as->samples = 4096;
as->callback = audiomixer;
as->userdata = NULL;
if (SDL_OpenAudio(as, NULL) < 0)
{
fprintf(stderr, "Unable to init SDL audio: %s\n", SDL_GetError());
exit(1);
}
gAudioSpec = as;
#endif
#ifdef DISPLAY_LOGO_SCREEN
logoscreen();
#else
init();
#endif
gGameStartTick = GetTickCount();
gLastTick = gGameStartTick;
while (1)
{
if (!gGameState)
reinit();
reindeer();
if (gGameState)
{
SDL_Event event;
while ( SDL_PollEvent(&event) )
{
switch (event.type)
{
case SDL_KEYUP:
if (event.key.keysym.sym == SDLK_ESCAPE)
#ifdef DISPLAY_GAMEOVER_SCREEN
gameoverscreen(0);
#else
return 0;
#endif
break;
case SDL_MOUSEMOTION:
if (gControlState == 0)
{
gMouseX += event.motion.xrel * gCoordScale;
gMouseY += event.motion.yrel * gCoordScale;
if (gMouseX < -320) gMouseX = -320;
if (gMouseY < -240) gMouseY = -240;
if (gMouseX > (800 - 320)) gMouseX = (800 - 320);
if (gMouseY > (600 - 240)) gMouseY = (600 - 240);
}
if (gControlState == 1)
{
gMouseZ += event.motion.yrel * 0.005f;
if (gMouseZ > 1.25) gMouseZ = 1.25;
if (gMouseZ < 0.05f) gMouseZ = 0.05f;
float oldcoord = gCoordScale;
#ifndef CAMERA_STEPS
gCoordScale = gMouseZ;
#else
gCoordScale = ((int)(gMouseZ * 4)) / 4.0f;
if (gCoordScale < 0.05f) gCoordScale = 0.05f;
#endif
if (oldcoord < gCoordScale)
play_sound(1);
if (oldcoord > gCoordScale)
play_sound(2);
}
break;
case SDL_MOUSEBUTTONDOWN:
if (event.button.button == SDL_BUTTON_RIGHT)
{
// zooming mode
gControlState = 1;
}
if (event.button.button == SDL_BUTTON_LEFT)
{
if (!gReloading)
{
play_sound(3);
shoot();
}
}
// SDL kludgy mouse wheel-o-rama:
if (event.button.button == 4 || event.button.button == 5)
{
gMouseZ += (event.button.button == 5) ? 0.2f : -0.2f;
if (gMouseZ > 1.25) gMouseZ = 1.25;
if (gMouseZ < 0.05f) gMouseZ = 0.05f;
float oldcoord = gCoordScale;
#ifndef CAMERA_STEPS
gCoordScale = gMouseZ;
#else
gCoordScale = ((int)(gMouseZ * 4)) / 4.0f;
if (gCoordScale < 0.05f) gCoordScale = 0.05f;
#endif
if (oldcoord < gCoordScale)
play_sound(1);
if (oldcoord > gCoordScale)
play_sound(2);
}
break;
case SDL_MOUSEBUTTONUP:
if (event.button.button == SDL_BUTTON_RIGHT)
{
// targeting mode
gControlState = 0;
}
break;
case SDL_QUIT:
return(0);
}
}
}
}
return 0;
}