1
///////////////////////////////////////////////
3
// Snipe2d ludum dare 48h compo entry
8
///////////////////////////////////////////////
10
///////////////////////////////////////////////
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.
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:
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.
28
// (eg. same as ZLIB license)
30
///////////////////////////////////////////////
32
// Houses are taken from a satellite picture of glasgow.
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 =)
44
typedef struct oes_joy_t {
45
int style; /* axis style: rel (game) or abs (mousepad) */ //not used yet
46
float scale; /* scaling factor. */
47
int interval; /* handling interval, in milliseconds. */
49
int time; /* timestamp of last handling. */
50
int axes; /* number of axes */
51
int buttons; /* number of buttons. */
52
int state; /* joy shifter state. */
53
float x; /* X axis. */
54
float y; /* Y axis. */
55
float z; /* throttle? */
56
SDL_Joystick* sdljoy; /* SDL Joystick handle. */
58
/* bindings for 32 axes and 32 buttons. */
64
oes_joy_t oesjoy = { 0, };
82
int screen_shot_number=1;
89
static const char *crosshairs_xpm[] = {
114
//SDL_AudioSpec *gAudioSpec = NULL;
115
Mix_Chunk *gAudioZoomSample = NULL;
116
Mix_Chunk *gAudioFireSample = NULL;
117
Mix_Chunk *gAudioZoomOut = NULL;
118
Mix_Chunk *gAudioZoomIn = NULL;
119
Mix_Chunk *gAudioFire = NULL;
120
//Mix_Music *gAudioBGM = NULL;
121
int gAudioZoomSampleLen = 0;
122
int gAudioZoomOutLen = 0;
123
int gAudioZoomInLen = 0;
124
int gAudioZoomOfs = 0;
125
int gAudioFireOfs = 0;
126
int gAudioFireSampleLen = 0;
127
int gAudioFireLen = 0;
131
const char *usage = \
132
"Usage: %s [OPTIONS]...\n\
133
Overhead shooting game; kill red marks, protect blue marks, avoid white marks.\n\
135
Orbital Eunuchs Sniper recognizes the following command parameters:\n\
136
-a | --audio Start with sound\n\
137
-n | --noaudio Start without sound\n\
138
-f | --fullscreen Start in fullscreen mode\n\
139
-w | --window Start in a window\n\
140
-1 | --diff1 Difficulty 1 (Easy)\n\
141
-2 | --diff2 Difficulty 2 (Medium)\n\
142
-3 | --diff3 Difficulty 3 (Hard)\n\
143
-h | --help Display this help message and exit\n\
145
Orbital Eunuchs Sniper is licensed under the same terms as the ZLIB license.\n\
147
/* -d 1|2|3 | --difficulty 1|2|3 Set difficulty level (1 is easiest)\n\ */
150
/* Set SDL cursor. */
161
image = crosshairs_xpm;
163
for ( row=0; row<16; ++row ) {
164
for ( col=0; col<16; ++col ) {
170
data[i] = mask[i] = 0;
172
switch (image[4+row][col]) {
185
sscanf(image[4+row], "%d,%d", &hot_x, &hot_y);
186
cursor = SDL_CreateCursor(data, mask, 16, 16, hot_x, hot_y);
187
SDL_SetCursor (cursor);
195
/********************/
196
/* Background Music */
197
/********************/
200
/* Function for SDL_mixer */
201
static void oes_bgm_loop()
203
sniperbgm_loop(Game.BGM);
208
sniperbgm_init (sniperbgm_t *self)
211
self = (sniperbgm_t*)calloc(1, sizeof(*self));
219
sniperbgm_init_music (sniperbgm_t *self, Mix_Music *m)
221
if ((self = sniperbgm_init(self)))
230
sniperbgm_delete (sniperbgm_t *self)
232
sniperbgm_stop(self); /* Don't wait for fadeout to finish. */
233
Mix_FreeMusic(self->BGM);
238
sniperbgm_music (sniperbgm_t *self)
244
sniperbgm_use (sniperbgm_t *self, Mix_Music *m)
252
sniperbgm_start (sniperbgm_t *self)
256
if (Mix_PlayMusic(self->BGM, 0))
257
printf("Mix_PlayMusic: %s\n", Mix_GetError());
259
Mix_HookMusicFinished(oes_bgm_loop);
261
self->time_start = SDL_GetTicks();
265
sniperbgm_stimulate (sniperbgm_t *self)
267
if (self->playp) return;
268
if (Mix_FadeInMusic(self->BGM, 0, sniperbgm_FadeInTime))
269
printf("Mix_PlayMusic: %s\n", Mix_GetError());
270
Mix_HookMusicFinished(oes_bgm_loop);
272
self->time_start = SDL_GetTicks();
276
sniperbgm_depress (sniperbgm_t *self)
278
Mix_HookMusicFinished(NULL);
279
if (!Mix_FadeOutMusic(sniperbgm_FadeOutTime))
285
sniperbgm_stop (sniperbgm_t *self)
288
Mix_HookMusicFinished(NULL);
293
sniperbgm_pause (sniperbgm_t *self, int newstate)
305
default: /* toggle */
306
if (self->pausep) Mix_ResumeMusic(); else Mix_PauseMusic();
307
self->pausep = !self->pausep;
313
sniperbgm_jumpto (sniperbgm_t *self, float pos)
315
Mix_SetMusicPosition(pos);
319
sniperbgm_rewind (sniperbgm_t *self)
325
sniperbgm_loop (sniperbgm_t *self)
327
sniperbgm_start(self);
328
sniperbgm_jumpto(self, sniperbgm_RepeatJumpPos);
332
sniperbgm_release (sniperbgm_t *self)
334
/* Prepare for release of sound device. */
335
/* Figure out where in the BGM we currently are. */
336
self->time_stop = SDL_GetTicks();
337
self->bookmark = (self->time_stop - self->time_start) / 1000.0;
338
sniperbgm_stop(self);
342
sniperbgm_grab (sniperbgm_t *self)
344
/* Try to resume BGM after reopening sound device. */
345
sniperbgm_start(self);
346
sniperbgm_jumpto(self, self->bookmark);
347
self->time_start -= (int)(self->bookmark * 1000); /* For next pause. */
359
parse_option (PETOPT *pp, PETOPTS *pov, const char *arg)
362
case 'n': // no audio
365
case 'f': // fullscreen
366
gPrefs.fullscreen = 1;
369
gPrefs.fullscreen = 0;
375
gPrefs.difficulty = 1;
378
gPrefs.difficulty = 2;
381
gPrefs.difficulty = 3;
384
fprintf (stderr, usage, invocation);
391
void parse_args(int argc, char **argv)
393
int fs, au, ds, petopt_err;
395
{ 'n', POF_BOOL, "noaudio", &au, "Disable Audio" },
396
{ 'f', POF_BOOL, "fullscreen", &fs, "Enable Fullscreen" },
397
{ 'w', POF_BOOL, "windowed", &fs, "Disable Fullscreen" },
398
{ 'a', POF_BOOL, "audio", &au, "Enable Audio" },
399
{ '1', POF_OPT|POF_INT,"diff1", &ds, "Difficulty Setting 1" },
400
{ '2', POF_OPT|POF_INT,"diff2", &ds, "Difficulty Setting 2" },
401
{ '3', POF_OPT|POF_INT,"diff3", &ds, "Difficulty Setting 3" },
402
{ 'h', 0, "help", NULL, "Extended mode" },
403
{ -1, 0, 0, NULL, NULL },
408
petopt_err = petopt_setup (&pop, 0, argc, argv, pov, parse_option, NULL);
409
if (petopt_err > 0) {
410
fprintf (stderr, "Unable to initialise petopt: %s\n", strerror(petopt_err));
413
petopt_err = petopt_parse (pop, &argc, &argv);
414
if (petopt_err > 0) {
415
fprintf(stderr, "petopt_parse_all: %s\n", strerror(petopt_err));
418
petopt_cleanup (pop);
433
void audiomixer(void *userdata, Uint8 *stream, int len)
436
short * buf = (short*)stream;
437
memset(stream,0,len);
438
if (gPlaySound & (1<<1))
440
gPlaySound &= ~(1<<1);
441
Game.AudioZoom.ofs = 0;
442
Game.AudioZoom.data = Game.AudioZoomOut.data;
443
Game.AudioZoom.len = Game.AudioZoomOut.len;
445
if (gPlaySound & (1<<2))
447
gPlaySound &= ~(1<<2);
448
Game.AudioZoom.ofs = 0;
449
Game.AudioZoom.data = Game.AudioZoomIn.data;
450
Game.AudioZoom.len = Game.AudioZoomIn.len;
452
if (gPlaySound & (1<<3))
454
gPlaySound &= ~(1<<3);
455
Game.AudioFireSample.ofs = 0;
456
Game.AudioFireSample.data = Game.AudioFire.data;
457
Game.AudioFireSample.len = Game.AudioFire.len;
459
if (Game.AudioZoom.data != NULL)
462
if (n + Game.AudioZoom.ofs > Game.AudioZoom.len)
463
n = Game.AudioZoom.len - Game.AudioZoom.ofs;
465
for (i = 0; i < n; i++)
466
buf[i] = Game.AudioZoom.data[i + Game.AudioZoom.ofs] / 2;
467
Game.AudioZoom.ofs += n;
470
Game.AudioZoom.data = NULL;
473
if (Game.AudioFireSample != NULL)
476
if (n + Game.AudioFireSample.ofs > Game.AudioFireSample.len)
477
n = Game.AudioFireSample.len - Game.AudioFireSample.ofs;
479
for (i = 0; i < n; i++)
480
buf[i] += Game.AudioFireSample.data[i + Game.AudioFireSample.ofs] / 2;
481
Game.AudioFireSample.ofs += n;
484
Game.AudioFireSample.data = NULL;
490
/* Sillily expensive, but faster. */
493
void oes_sound_finish (int chan)
498
void oes_sound_play (int aSound)
504
// gPlaySound |= 1 << aSound;
505
// SDL_UnlockAudio();
506
/* Find a free channel. */
507
for (chan = 0; (chan < 16) && (chanuse[chan]); chan++);
508
if (chan >= 16) return; /* out of channels. */
512
Mix_PlayChannel(chan, Game.AudioZoomOut, 0);
515
Mix_PlayChannel(chan, Game.AudioZoomIn, 0);
518
Mix_PlayChannel(chan, Game.AudioFire, 0);
523
int oes_audio_open ()
529
/* XXX: take settings from prefs. */
530
if (Mix_OpenAudio(44100, AUDIO_S16, 2, 4096)) {
531
printf("Mix_OpenAudio(): %s\n", Mix_GetError());
533
Mix_AllocateChannels(17);
534
Mix_ChannelFinished(oes_sound_finish);
536
SDL_AudioSpec *as = (SDL_AudioSpec*)malloc(sizeof(SDL_AudioSpec));
538
as->format = AUDIO_S16;
541
as->callback = audiomixer;
543
if (SDL_OpenAudio(as, NULL) < 0)
545
fprintf(stderr, "Unable to init SDL audio: %s\n", SDL_GetError());
555
int oes_audio_close ()
566
/*****************************/
567
/* Game and system resources */
568
/*****************************/
571
/* initialize game data. */
573
oes_game_init (ORBITALSNIPER *self)
579
self = (ORBITALSNIPER*)calloc(1, sizeof(ORBITALSNIPER));
581
tick = SDL_GetTicks();
585
self->CoordScale = 1.0f;
590
self->ControlState = 0;
594
self->baddy.count = 0;
595
self->WobbleIndex = 0;
597
self->pedestrian.dead = 0;
598
self->baddy.dead = 0;
599
self->SightedCharacter = NULL;
602
SDL_JoystickClose(oesjoy.sdljoy);
603
oesjoy.sdljoy = NULL;
605
oesjoy.x = 0; oesjoy.y = 0; oesjoy.z = 0; oesjoy.state = 0;
606
oesjoy.axes = 0; oesjoy.buttons = 0;
607
if (gPrefs.joystick) {
608
/* want to use joystick. */
609
//printf("Detected %d joysticks\n", SDL_NumJoysticks());
610
if ((oesjoy.sdljoy = SDL_JoystickOpen(gPrefs.joystick - 1))) { /* off-by-one */
611
oesjoy.axes = SDL_JoystickNumAxes(oesjoy.sdljoy);
612
oesjoy.buttons = SDL_JoystickNumButtons(oesjoy.sdljoy);
616
for (i = 0; i < self->num_characters; i++)
618
self->characters[i].mType = -1;
620
for (i = 0; i < (int)(self->num_characters * 0.75f); i++)
622
int id = spawn_ai(2);
624
for (j = 0; j < 1000; j++) // Run 1000 physics loops for all pedestrians..
625
handle_ai(self->characters[id]);
627
self->vip.time = 2000;
628
self->vip.period = 20000;
629
self->baddy.time = 3000;
630
self->baddy.period = 8000;
631
self->WobbleIndex = 0;
632
self->StartTick = tick;
633
self->FrameCount = 0;
634
self->LastTick = tick;
636
self->GameStartTick = tick;
643
/* One-time setup at start. */
647
/* load audio, load images, load models(?), allocate objects. */
649
const char *city_img = "citee2.png";
650
const char *charseq_img = "charseq.png";
651
const char *aimap_img = "aimap.png";
652
const char *font_img = "font4x6.png";
653
const char *zoomin_snd = "camera_in.wav";
654
const char *zoomout_snd = "camera_out.wav";
655
const char *boing_snd = "twang.wav";
656
const char *bgmusic = "oes.ogg";
658
// char path[ strlen(mediaPath) + 1 + 30 + 1 ];
659
// path = (char*)calloc(strlen(mediaPath) + 1 + 30 + 1, sizeof(char));
661
/* free on function exit. */
662
path = (char*)alloca((strlen(Game.mediaPath) + 1 + 30 + 1) * sizeof(char));
665
/* Configure difficulty. */
666
configure_difficulty();
667
/* Initialise high scores. */
671
//if ( SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0 )
672
// if ( SDL_Init(SDL_INIT_VIDEO) < 0 )
673
if ( SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0 )
675
fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
681
//gScreen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE);
683
Game.Screen = SDL_SetVideoMode(640, 480, 16, (gPrefs.fullscreen ? SDL_FULLSCREEN : 0) | SDL_SWSURFACE);
685
Game.Screen = SDL_SetVideoMode(640, 480, 16, (gPrefs.fullscreen ? SDL_FULLSCREEN : 0) | SDL_SWSURFACE | SDL_DOUBLEBUF);
687
SDL_WM_SetCaption("ORBITAL EUNUCHS SNIPER", "ORBITAL_EUNUCHS_SNIPER");
688
if (Game.Screen == NULL)
690
fprintf(stderr, "Unable to set 640x480 video: %s\n", SDL_GetError());
695
// init_logoscreen();
700
Game.BGM = sniperbgm_init(Game.BGM);
702
sprintf(path, "%s/%s", Game.mediaPath, city_img);
703
SDL_Surface *temp = IMG_Load(path);
705
fprintf(stderr, "Unable to load city map from '%s'\n",path);
708
Game.Map = SDL_ConvertSurface(temp, Game.Screen->format,SDL_SWSURFACE);
709
SDL_FreeSurface(temp);
711
sprintf(path, "%s/%s", Game.mediaPath, charseq_img);
712
temp = IMG_Load(path);
714
fprintf(stderr, "Unable to load character image from '%s'\n",path);
717
Game.CharSprite = SDL_ConvertSurface(temp, Game.Screen->format,SDL_SWSURFACE);
718
SDL_FreeSurface(temp);
720
sprintf(path, "%s/%s", Game.mediaPath, aimap_img);
721
Game.AIMap = IMG_Load(path);
723
fprintf(stderr, "Unable to load AI map from '%s'\n",path);
727
// Okay, this is ugly. Load font several times & change the color of each.
729
for (i = 0; i < 5; i++)
731
sprintf(path, "%s/%s", Game.mediaPath, font_img);
732
Game.Font[i] = IMG_Load(path);
734
fprintf(stderr, "Unable to load font %d from '%s'\n",i,path);
737
SDL_SetColorKey(Game.Font[i],SDL_SRCCOLORKEY,1); // set color index 1 (black) transparent
739
*(int*)&(Game.Font[0]->format->palette->colors[0]) = 0x000000; // black
740
*(int*)&(Game.Font[1]->format->palette->colors[0]) = 0xffffff; // white
741
*(int*)&(Game.Font[2]->format->palette->colors[0]) = 0x00ff00; // green
742
*(int*)&(Game.Font[3]->format->palette->colors[0]) = 0x00ffff; // yellow
743
*(int*)&(Game.Font[4]->format->palette->colors[0]) = 0x0000ff; // red
747
Game.num_characters = 2048;
748
Game.characters = (CHARACTER*)calloc(Game.num_characters, sizeof(CHARACTER));
753
sprintf(path, "%s/%s", Game.mediaPath, zoomin_snd);
754
Game.AudioZoomIn = Mix_LoadWAV(path);
755
if (!Game.AudioZoomIn) {
756
fprintf(stderr, "Unable to load zoom in sound from '%s'\n",path);
759
sprintf(path, "%s/%s", Game.mediaPath, zoomout_snd);
760
Game.AudioZoomOut = Mix_LoadWAV(path);
761
if (!Game.AudioZoomOut) {
762
fprintf(stderr, "Unable to load zoom out sound from '%s'\n",path);
765
sprintf(path, "%s/%s", Game.mediaPath, boing_snd);
766
Game.AudioFire = Mix_LoadWAV(path);
767
if (!Game.AudioFire) {
768
fprintf(stderr, "Unable to load fire sound from '%s'\n",path);
771
sprintf(path, "%s/%s", Game.mediaPath, bgmusic);
772
// Game.BGM = Mix_LoadMUS(path);
773
if (!sniperbgm_use(Game.BGM, Mix_LoadMUS(path))) {
774
fprintf(stderr, "Unable to load background music from '%s'\n",path);
778
// SDL_PauseAudio(0); // let it play
782
oes_game_init(&Game);
786
/* One-time teardown at exit. */
792
SDL_JoystickClose(oesjoy.sdljoy);
793
oesjoy.sdljoy = NULL;
797
/* Temporarily release system resources. */
801
if (Game.GameState != OESGAME_PLAY) return 0;
802
sniperbgm_release(Game.BGM);
804
SDL_WM_GrabInput(SDL_GRAB_OFF);
806
Game.GameState = OESGAME_PAUSED;
810
/* Reassert system resources that were temporarily released. */
814
if (Game.GameState != OESGAME_PAUSED) return 0;
818
SDL_WM_GrabInput(SDL_GRAB_ON);
821
sniperbgm_grab(Game.BGM);
822
Game.GameState = OESGAME_UNPAUSED;
835
#define PHYSICS_MS 10
836
// 10ms physics loops == 100 loops per sec, 'should be enough'..
840
Game.SightedCharacter = NULL;
841
int tick = SDL_GetTicks();
845
Game.Reloading -= tick - Game.LastTick;
846
if (Game.Reloading < 0)
850
Game.CenterX = (640.0f - 640.0f * Game.CoordScale) / 2;
851
Game.CenterY = (480.0f - 480.0f * Game.CoordScale) / 2;
852
Game.WobbleX = (float)(sin(Game.WobbleIndex * 0.000654387) +
853
sin(Game.WobbleIndex * 0.000547867)*2 +
854
sin(Game.WobbleIndex * 0.000700133)) * (WOBBLE / 4.0f);
855
Game.WobbleY = (float)(sin(Game.WobbleIndex * 0.000537234) +
856
sin(Game.WobbleIndex * 0.000732897) +
857
sin(Game.WobbleIndex * 0.000600613)*2) * (WOBBLE / 4.0f);
862
zoom_unreal(Game.Map, Game.MouseX + Game.CenterX + Game.WobbleX, Game.MouseY + Game.CenterY + Game.WobbleY, Game.CoordScale);
864
zoom(Game.Map, Game.MouseX + Game.CenterX + Game.WobbleX, Game.MouseY + Game.CenterY + Game.WobbleX, Game.CoordScale);
868
int physics_loops = (tick - Game.LastTick) / PHYSICS_MS;
870
for (i = 0; i < Game.num_characters; i++)
872
for (j = 0; j < physics_loops; j++)
873
handle_ai(Game.characters[i]);
876
drawCharacter(Game.characters[i]);
881
for (j = 0; j < physics_loops; j++)
883
int physicstick = Game.LastTick - Game.GameStartTick;
884
Game.WobbleIndex += PHYSICS_MS;
887
if (physicstick >= Game.vip.time)
890
if (Game.vip.count == 2 && rand() < 2048)
892
if (Game.vip.count == 1 && rand() < 8192)
894
if (Game.vip.count == 0)
896
Game.vip.time += (int)Game.vip.period;
899
if (physicstick >= Game.baddy.time)
902
Game.baddy.time += (int)Game.baddy.period;
904
if (((Game.LastTick / PHYSICS_MS) & 3) == 0)
907
if (Game.baddy.period < 3000)
908
Game.baddy.period = 3000; // Eventually it will be impossible to kill all bad guys.
910
Game.LastTick += PHYSICS_MS;
914
SDL_Flip(Game.Screen);
918
int oes_game_state (int newstate)
920
switch ((Game.GameState = newstate)) {
925
/* main game state. */
931
/* just unpaused. Need re-init, transit to 1. */
934
return Game.GameState;
938
Alter input grab state.
941
-1 = toggle whatever it is.
943
int oes_game_grab (int newstate)
947
if (SDL_GetVideoSurface()->flags & SDL_FULLSCREEN) {
948
/* Don't release grab in fullscreen. */
949
SDL_WM_GrabInput(SDL_GRAB_ON);
954
tryGrabState = (newstate == -1) ? !Game.GrabP : newstate;
955
switch (tryGrabState) {
957
SDL_WM_GrabInput(SDL_GRAB_OFF);
963
SDL_WM_GrabInput(SDL_GRAB_ON);
970
int oes_game_zoom (float amt)
972
float oldcoord = Game.CoordScale;
975
if (Game.MouseZ > 1.25) Game.MouseZ = 1.25;
976
if (Game.MouseZ < 0.05f) Game.MouseZ = 0.05f;
978
Game.CoordScale = Game.MouseZ;
979
#else /* CAMERA_STEPS */
980
Game.CoordScale = ((int)(Game.MouseZ * 4)) / 4.0f;
981
if (Game.CoordScale < 0.05f) Game.CoordScale = 0.05f;
982
#endif /* CAMERA_STEPS */
983
if (oldcoord < Game.CoordScale)
985
if (oldcoord > Game.CoordScale)
992
0 = force play/resume
994
-1 = toggle paused state
996
int oes_game_pause (int newstate)
1001
tryPause = newstate;
1004
if (Game.GameState == OESGAME_PAUSED)
1009
tick = SDL_GetTicks();
1013
if (Game.GameState == OESGAME_PAUSED)
1015
//printf("UNPAUSING\n");
1017
oes_resume(); /* regain system resources. */
1018
Game.AfterPauseTick = tick;
1019
Game.GameStartTick += Game.AfterPauseTick - Game.BeforePauseTick;
1020
Game.GameState = OESGAME_PLAY;
1025
if (Game.GameState == OESGAME_PLAY)
1028
//printf("Pausing\n");
1029
Game.BeforePauseTick = tick;
1030
oes_suspend(); /* release system resources. */
1031
Game.GameState = OESGAME_PAUSED;
1040
oes_game_hide (int newstate)
1042
SDL_WM_IconifyWindow();
1052
/******************/
1053
/* OES Game Binds */
1054
/******************/
1058
int oes_bind_nop (int val)
1065
/* On-release-only binds */
1067
int oes_bind_grab (int val)
1070
return oes_game_grab(-1);
1073
/* toggle fullscreen... on key release */
1074
int oes_bind_fullscreen (int val)
1076
if (val) return 0; /* toggle on release. */
1078
gPrefs.fullscreen = !gPrefs.fullscreen;
1079
if (((Game.Screen->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) ^ (gPrefs.fullscreen)) {
1080
SDL_WM_ToggleFullScreen(Game.Screen);
1082
// SDL_WM_ToggleFullScreen(Game.Screen);
1083
// gPrefs.fullscreen = !gPrefs.fullscreen;
1088
int oes_bind_hide (int val)
1090
if (val) return 0; /* trigger on release */
1095
/* Forceful end of game. */
1097
oes_bind_abandon (int pressed)
1099
if (pressed) return 0;
1101
Game.GameOverReason = OESREASON_AWOL;
1106
/* On-press binds */
1109
int oes_bind_pause (int val)
1112
return oes_game_pause(-1);
1115
/* the extra information around the targeting reticles */
1116
int oes_bind_verbosity (int val)
1119
Game.verbosity = (Game.verbosity + 1) % 3;
1120
gPrefs.verbose = Game.verbosity;
1124
/* save screenshot */
1125
int oes_bind_screenshot (int val)
1128
SDL_SaveBMP(SDL_GetVideoSurface(),"screenshot.bmp");
1129
screen_shot_number++;
1133
int oes_bind_fire (int val)
1136
if (Game.GameState == OESGAME_PLAY) {
1137
if (!Game.Reloading) {
1141
} else if (Game.GameState == OESGAME_PAUSED) {
1142
if (Game.LastTick - Game.SemiPause < 500) {
1143
// Game.GameState = OESGAME_UNPAUSED;
1146
Game.SemiPause = Game.LastTick;
1153
int oes_bind_zoom (int val)
1155
Game.ControlState = val ? 1 : 0;
1156
return Game.ControlState;
1160
int oes_bind_zoomin (int val)
1163
if (Game.GameState != OESGAME_PLAY) return 1;
1164
oes_game_zoom(-0.20f);
1169
int oes_bind_zoomout (int val)
1172
if (Game.GameState != OESGAME_PLAY) return 1;
1173
oes_game_zoom(0.20f);
1179
/* Continuous-value binds */
1181
/* Mouse motion, horizontal */
1182
int oes_bind_mhoriz (int val)
1185
/* A little confusing if not grabbed... */
1188
if (Game.GameState != OESGAME_PLAY) return 1;
1189
if (Game.ControlState == 0) {
1190
Game.MouseX += val * Game.CoordScale;
1191
if (Game.MouseX < -320) Game.MouseX = -320;
1192
if (Game.MouseX > (800 -320)) Game.MouseX = (800 - 320);
1194
/* nothing on horizontal while zoomshift */
1199
/* Mouse motion, vertical */
1200
int oes_bind_mvert (int val)
1203
/* A little confusing if not grabbed... */
1206
if (Game.GameState != OESGAME_PLAY) return 1;
1207
if (Game.ControlState == 0) {
1208
Game.MouseY += val * Game.CoordScale;
1209
if (Game.MouseY < -240) Game.MouseY = -240;
1210
if (Game.MouseY > (600 - 240)) Game.MouseY = (600 - 240);
1212
oes_game_zoom (val * 0.005f);
1217
/* Axis, horizontal */
1218
int oes_bind_jhoriz (int val)
1220
if (!Game.GrabP) return 1;
1221
if (Game.GameState != OESGAME_PLAY) return 1;
1222
oesjoy.x = (val * oesjoy.scale) / 32767.0;
1226
/* Axis, vertical */
1227
int oes_bind_jvert (int val)
1229
if (!Game.GrabP) return 1;
1230
if (Game.GameState != OESGAME_PLAY) return 1;
1231
oesjoy.y = (val * oesjoy.scale) / 32767.0;
1235
/* Axis, depth (zoom) */
1236
int oes_bind_jdeep (int val)
1240
if (!Game.GrabP) return 1;
1241
if (Game.GameState != OESGAME_PLAY) return 1;
1243
/* XXX: what about going backwards? */
1245
/* map oes.joyz from 1.25 to 0.05 */
1247
/* deltas: 1.20 : 32767 */
1248
// joyz = (oesjoy.z * 1.20 / 32767.0) + 0.05;
1249
joyz = 1.25 - (oesjoy.z * 1.20 / 32767.0);
1268
/* game binding names (from config file) */
1269
oes_xlat_t oesxlat[] = {
1270
{ "mousex", oes_bind_mhoriz },
1271
{ "mousey", oes_bind_mvert },
1272
{ "joyx", oes_bind_jhoriz },
1273
{ "joyy", oes_bind_jvert },
1274
{ "joyz", oes_bind_jdeep },
1275
{ "fire", oes_bind_fire },
1276
{ "zoom", oes_bind_zoom },
1277
{ "zoomin", oes_bind_zoomin },
1278
{ "zoomout", oes_bind_zoomout },
1279
{ "verbosity", oes_bind_verbosity },
1280
{ "screenshot", oes_bind_screenshot },
1281
{ "fullscreen", oes_bind_fullscreen },
1282
{ "hide", oes_bind_hide },
1283
{ "abandon", oes_bind_abandon },
1284
{ "pause", oes_bind_pause },
1285
{ "grab", oes_bind_grab },
1292
/*******************/
1293
/* Events handling */
1294
/*******************/
1297
/* Called at intervals, handling joystick axes. */
1298
int oes_game_joystick (int ticks)
1300
/* Joystick axes handling. */
1302
if (!oesjoy.sdljoy) return 0;
1303
if (ticks > oesjoy.time + oesjoy.interval) {
1304
//printf("JOY HANDLE\n");
1305
joyx = (int)(oesjoy.x);
1306
joyy = (int)(oesjoy.y);
1307
switch (oesjoy.state) {
1308
case 0: /* normal */
1309
oes_bind_mhoriz(joyx);
1310
oes_bind_mvert(joyy);
1312
case 1: /* shifted 1 */
1313
oes_game_zoom(joyy * 0.005);
1316
oesjoy.time = ticks;
1322
int oes_game_events ()
1327
oesbind_t binding; /* function pointer */
1329
while (SDL_PollEvent(&event))
1335
kmod = SDL_GetModState();
1336
oeskey = event.key.keysym.sym;
1337
switch (event.key.keysym.sym)
1339
/* Rebindable keys */
1341
binding = oeskeymap_get(&oeskeymap, oeskey);
1349
kmod = SDL_GetModState();
1350
oeskey = event.key.keysym.sym;
1351
switch (event.key.keysym.sym)
1353
/* Hard-coded keys */
1354
case SDLK_F12: /* failsafe */
1357
case SDLK_F4: /* failsafe */
1358
if (kmod & KMOD_ALT) exit(69);
1361
if (kmod & KMOD_ALT)
1363
binding = oes_bind_fullscreen;
1367
if (kmod & KMOD_CTRL)
1369
binding = oes_bind_hide;
1373
if (kmod & KMOD_CTRL)
1375
binding = oes_bind_grab;
1378
/* Rebindable keys */
1380
binding = oeskeymap_get(&oeskeymap, oeskey);
1386
case SDL_MOUSEMOTION:
1387
// binding = oeskeymap_get(&oeskeymap, oeskeymap_resolve("MOUSEX"));
1388
binding = oeskeymap_get(&oeskeymap, keymarkers.mousex);
1390
binding(event.motion.xrel);
1391
binding = oeskeymap_get(&oeskeymap, keymarkers.mousey);
1393
binding(event.motion.yrel);
1394
// oes_bind_mhoriz(event.motion.xrel);
1395
// oes_bind_mvert(event.motion.yrel);
1397
case SDL_MOUSEBUTTONDOWN:
1398
// oeskey = oeskeymap_resolve("MOUSE0") + event.button.button;
1399
oeskey = keymarkers.mouse0 + event.button.button;
1400
binding = oeskeymap_get(&oeskeymap, oeskey);
1404
case SDL_MOUSEBUTTONUP:
1405
oeskey = keymarkers.mouse0 + event.button.button;
1406
binding = oeskeymap_get(&oeskeymap, oeskey);
1410
case SDL_JOYAXISMOTION:
1411
// oeskey = oeskeymap_resolve("AXIS1") + event.jaxis.axis;
1412
oeskey = keymarkers.axis1 + event.jaxis.axis;
1413
binding = oeskeymap_get(&oeskeymap, oeskey);
1416
binding(event.jaxis.value);
1419
case SDL_JOYBUTTONDOWN:
1420
// oeskey = oeskeymap_resolve("JOY1") + event.jbutton.button;
1421
oeskey = keymarkers.joy1 + event.jbutton.button;
1422
binding = oeskeymap_get(&oeskeymap, oeskey);
1426
case SDL_JOYBUTTONUP:
1427
oeskey = keymarkers.joy1 + event.jbutton.button;
1428
binding = oeskeymap_get(&oeskeymap, oeskey);
1433
Game.GameOverReason = OESREASON_QUIT;
1438
} //switch event.type
1439
} //while SDL_PollEvent
1441
if (Game.GameState == OESGAME_PAUSED)
1442
{ /* Don't hog CPU when paused. */
1449
/* Main game stub. */
1455
oesjoy.time = Game.LastTick;
1456
Game.GameStartTick = SDL_GetTicks();
1457
Game.LastTick = Game.GameStartTick;
1458
sniperbgm_stimulate(Game.BGM);
1459
Game.GameOverReason = OESREASON_NONE;
1462
while (Game.GameOverReason == OESREASON_NONE)
1464
tick = SDL_GetTicks();
1465
switch (Game.GameState)
1468
oes_game_init(&Game);
1469
sniperbgm_stimulate(Game.BGM);
1470
Game.GameState = OESGAME_PLAY;
1475
case OESGAME_PAUSED:
1476
Game.LastTick = tick;
1478
case OESGAME_UNPAUSED:
1482
Game.GameState = OESGAME_CHAOS;
1488
/* joystick-interval handling. */
1489
oes_game_joystick(tick);
1491
Game.GameOverTicks = SDL_GetTicks();
1493
sniperbgm_depress(Game.BGM);
1494
Game.GameState = OESGAME_CHAOS;
1496
if (Game.GameOverReason == OESREASON_QUIT)
1502
/* Launche web browser to point to a URI. */
1504
oes_web (const char *uri)
1508
/* Don't check URI protocol. Assume browser understands all. */
1510
snprintf(cmd, sizeof(cmd), "%s \"%s\"", gPrefs.wwwbrowser, uri);
1515
/* Widget signal fallback (unhandled/unblocked widget signals) */
1516
//int oes_uisignal (oesui_t *gui, const char *signame)
1518
oes_uisignal (oesui_t *gui, oesui_signal_t *sig)
1520
const char *signame;
1523
signame = UISIG_NAME(sig);
1525
else if (0 == strcmp(signame, "start-game"))
1527
oesui_event(gui, OESUI_CLOSE, 0);
1529
oesui_open(gui, "gameover");
1534
else if (0 == strcmp(signame, "go-main"))
1536
oesui_open(gui, "main");
1539
else if (0 == strcmp(signame, "go-prefs"))
1541
oesui_open(gui, "prefs");
1544
else if (0 == strcmp(signame, "go-scores"))
1546
oesui_open(gui, "highscores");
1549
else if (0 == strcmp(signame, "frob-fullscreen"))
1551
oes_bind_fullscreen(0);
1552
oesui_event(gui, OESUI_UPDATE, 0);
1555
else if (0 == strcmp(signame, "frob-audio"))
1557
gPrefs.audio = !gPrefs.audio;
1558
oesui_event(gui, OESUI_UPDATE, 0);
1561
else if (0 == strcmp(signame, "frob-skill"))
1563
gPrefs.difficulty++;
1564
if (gPrefs.difficulty > 3)
1565
gPrefs.difficulty = 1;
1566
oesui_event(gui, OESUI_UPDATE, 0);
1569
else if (0 == strcmp(signame, "highscores"))
1571
r.x = UISIG_ARG(sig, 1).i;
1572
r.y = UISIG_ARG(sig, 2).i;
1573
r.w = UISIG_ARG(sig, 3).i;
1574
r.h = UISIG_ARG(sig, 4).i;
1575
draw_hiscores(gui->screen, &r);
1577
else if (0 == strcmp(signame, "gameover"))
1579
r.x = UISIG_ARG(sig, 1).i;
1580
r.y = UISIG_ARG(sig, 2).i;
1581
r.w = UISIG_ARG(sig, 3).i;
1582
r.h = UISIG_ARG(sig, 4).i;
1583
draw_gameover(gui->screen, &r);
1585
else if (0 == strcmp(signame, "quit"))
1590
else if (0 == strcmp(signame, "url-oes"))
1592
#define WEBBROWSER mozilla
1593
/* http://www.icculus.org/oes/ */
1594
oes_web("http://www.icculus.org/oes/");
1596
else if (0 == strcmp(signame, "url-os"))
1598
/* http://www.iki.fi/sol/ */
1599
oes_web("http://www.iki.fi/sol/");
1601
else if (0 == strcmp(signame, "url-td"))
1603
/* http://www.timedoctor.org/ */
1604
oes_web("http://www.timedoctor.org/");
1606
else if (0 == strcmp(signame, "url-io"))
1608
/* http://www.icculus.org/ */
1609
oes_web("http://www.icculus.org/");
1611
else if (0 == strcmp(signame, "url-ov"))
1613
/* http://www.vorbis.com/ */
1614
oes_web("http://www.vorbis.com/");
1623
/* TODO: bind map */
1624
/* sane joystick defaults. */
1626
oesjoy.scale = 10.0f;
1627
oesjoy.interval = 20;
1629
oesjoy.axis[0] = oes_bind_jhoriz;
1630
oesjoy.axis[1] = oes_bind_jvert;
1631
oesjoy.axis[2] = oes_bind_jdeep;
1632
oesjoy.button[0] = oes_bind_fire;
1633
oesjoy.button[1] = oes_bind_zoom;
1634
oesjoy.button[2] = oes_bind_zoomout;
1635
oesjoy.button[3] = oes_bind_zoomin;
1638
oeskeymap_init(&oeskeymap);
1639
oeskeymap_load(&oeskeymap, gPrefs.bindpath);
1640
// oeskeymap_set(&oeskeymap, SDLK_a, oes_bind_fire); //test
1641
oeskeymap_set(&oeskeymap, SDLK_v, oes_bind_verbosity, 1);
1642
oeskeymap_set(&oeskeymap, SDLK_p, oes_bind_pause, 1);
1643
oeskeymap_set(&oeskeymap, SDLK_s, oes_bind_screenshot, 1);
1644
oeskeymap_set(&oeskeymap, SDLK_ESCAPE, oes_bind_abandon, 1);
1645
oeskeymap_set(&oeskeymap, oeskeymap_resolve("MOUSEX"), oes_bind_mhoriz, 1);
1646
oeskeymap_set(&oeskeymap, oeskeymap_resolve("MOUSEY"), oes_bind_mvert, 1);
1647
oeskeymap_set(&oeskeymap, oeskeymap_resolve("MOUSE1"), oes_bind_fire, 1);
1648
oeskeymap_set(&oeskeymap, oeskeymap_resolve("MOUSE2"), oes_bind_zoom, 1);
1649
oeskeymap_set(&oeskeymap, oeskeymap_resolve("MOUSE4"), oes_bind_zoomin, 1);
1650
oeskeymap_set(&oeskeymap, oeskeymap_resolve("MOUSE5"), oes_bind_zoomout, 1);
1651
oeskeymap_set(&oeskeymap, oeskeymap_resolve("JOY1"), oes_bind_fire, 1);
1652
oeskeymap_set(&oeskeymap, oeskeymap_resolve("JOY2"), oes_bind_zoom, 1);
1653
oeskeymap_set(&oeskeymap, oeskeymap_resolve("JOY3"), oes_bind_zoomin, 1);
1654
oeskeymap_set(&oeskeymap, oeskeymap_resolve("JOY4"), oes_bind_zoomout, 1);
1655
oeskeymap_set(&oeskeymap, oeskeymap_resolve("AXIS1"), oes_bind_jhoriz, 10);
1656
oeskeymap_set(&oeskeymap, oeskeymap_resolve("AXIS2"), oes_bind_jvert, 10);
1657
oeskeymap_set(&oeskeymap, oeskeymap_resolve("AXIS3"), oes_bind_jdeep, 10);
1658
keymarkers.mousex = oeskeymap_resolve("MOUSEX");
1659
keymarkers.mousey = oeskeymap_resolve("MOUSEY");
1660
keymarkers.mouse0 = oeskeymap_resolve("MOUSE0");
1661
keymarkers.axis1 = oeskeymap_resolve("AXIS1");
1662
keymarkers.joy1 = oeskeymap_resolve("JOY1");
1668
int main(int argc, char *argv[])
1672
srand(SDL_GetTicks());
1675
Game.mediaPath = (char*)calloc(strlen(argv[0]), sizeof(char));
1676
// invocation = (char*)malloc(strlen(argv[0]) + 1); memcpy(invocation, argv[0], strlen(argv[0]));
1677
invocation = strdup(argv[0]);
1678
sprintf(Game.mediaPath, "%s", dirname(invocation));
1681
Game.mediaPath = strdup(GAMEDATADIR);
1682
invocation = argv[0];
1684
/* Load Preferences. */
1685
prefs_init(&gPrefs);
1686
prefs_load(&gPrefs);
1687
Game.verbosity = gPrefs.verbose;
1689
/* Parse options, which may override saved preferences. */
1690
parse_args(argc, argv);
1693
oes_setup (); /* prefs initialized in here */
1696
gui = oesui_init_surface(NULL, Game.Screen); /* initialise gui */
1697
oesui_load(gui, "menus.cfg"); /* Load gui data */
1698
oesui_sighandle(gui, oes_uisignal); /* widget signal handler */
1699
oesui_open(gui, "main"); /* Main menu */
1700
oesui_loop(gui); /* Main UI loop */
1704
// delete[] mediaPath;
1705
free(Game.mediaPath);
1707
// oes_audio_close();
1712
void configure_difficulty()
1714
gPrefs.difficulty = (gPrefs.difficulty < 1 ? 1 : gPrefs.difficulty);
1715
gPrefs.difficulty = (gPrefs.difficulty > 3 ? 3 : gPrefs.difficulty);
1716
switch (gPrefs.difficulty)
1719
Game.ReloadTime = 1500;
1720
Game.ScoreMod = 1.5;
1723
Game.ReloadTime = 3000;
1724
Game.ScoreMod = 1.0;
1727
Game.ReloadTime = 4000;
1728
Game.ScoreMod = 0.5;
1734
void draw_button (SDL_Surface *b, int x, int y)
1743
SDL_BlitSurface (b, NULL, Game.Screen, &d);
1747
SDL_Surface *oes_load_img (const char *path)
1749
SDL_Surface *sfc = NULL;
1750
char lpath[PATH_MAX];
1751
snprintf (lpath, PATH_MAX, "%s/%s", Game.mediaPath, path);
1752
sfc = IMG_Load (lpath);
1754
fprintf(stderr,"Unable to load image '%s': %s\n",lpath,SDL_GetError());
1761
bool hovering (int x, int y, int w, int h)
1764
SDL_GetMouseState (&lx, &ly);
1765
if ((lx > x) && (ly > y) &&
1766
(lx < x + w) && (ly < y + h))