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 //#include <windows.h>
38 #include <iostream>
39 #include <stdlib.h>
40 #include <math.h>
41 #include <string.h>
42 #include <libgen.h>
43 #include <SDL/SDL.h>
44 #include <SDL/SDL_image.h>
45 #include <SDL/SDL_mixer.h>
46 #include <sys/types.h>
47 #include <sys/stat.h>
48 #include <fcntl.h>
49 #include <unistd.h>
50 #include <stdio.h>
51 #include <string.h>
52 #include <stdarg.h>
53 #include "petopt.h"
54 
55 #ifdef HAVE_CONFIG_H
56 # include "config.h"
57 #endif
58 
59 // When trying to debug a segfault, you REALLY, REALLY need to be able to
60 // switch windows.  :(
61 #ifdef DEBUG_MODE
62 #undef SDL_GRAB_ON
63 #define SDL_GRAB_ON SDL_GRAB_OFF
64 #endif
65 // Config:
66 
67 #define SHIFT_AMOUNT 12
68 #define CAMERA_STEPS
69 #define UNREAL_DITHER
70 #define WOBBLE 2
71 #define DISPLAY_LOGO_SCREEN
72 #define DISPLAY_GAMEOVER_SCREEN
73 //#define CAMERA_RECOIL
74 //#define RECYCLE_PEDESTRIANS
75 #define PLAY_AUDIO
76 
77 enum COLORSET {
78     COLOR_BLACK = 0,
79     COLOR_WHITE,
80     COLOR_GREEN,
81     COLOR_YELLOW,
82     COLOR_RED
83 };
84 
85 enum CHARTYPES
86 {
87     CHAR_BADGUY = 0,
88     CHAR_VIP = 1,
89     CHAR_PEDESTRIAN = 2
90 };
91 
92 enum SOUNDCHAN {
93   SOUNDCHAN_EFFECT = 0,
94   SOUNDCHAN_MUSIC = 1,
95 };
96 
97 
98 /* Reason for game over */
99 typedef enum OES_ENDREASON {
100   OESREASON_NONE = 0,  /* game in progress */
101   OESREASON_NEGLIGENT,  /* let a VIP die. */
102   OESREASON_AWOL,       /* left post (voluntary game end). */
103   OESREASON_FRAG,       /* hit VIP. */
104   OESREASON_QUIT,       /* forceful quit. */
105 } OES_ENDREASON;
106 
107 
108 /* Game states */
109 typedef enum OES_GAMESTATE {
110   OESGAME_CHAOS = 0,  /* uninitialized. */
111   OESGAME_PLAY,       /* initialized and in play. */
112   OESGAME_PAUSED,     /* paused. */
113   OESGAME_UNPAUSED,   /* un-paused, reinitalize system resources (devices). */
114 } OES_GAMESTATE;
115 
116 
117 /* data types go here. */
118 
119 typedef struct character_
120 {
121     float mX, mY; // position
122     float mXi, mYi; // direction
123     float mSpeed;   // speed of this AI
124     int mType;   // AI type
125     int mTTL;    // time to live, for normal pedestrians
126     int mTarget; // target exit point or target character
127     int mNextWaypoint;   // waypoint towards which this AI is walking
128     int mLastWaypoints[7];   // last 7 waypoints to kill loops
129     int mLastWaypoint;  // counter for above array
130 } CHARACTER;
131 
132 typedef struct waypointstruc
133 {
134     int mX,mY;
135     int *mConnection;
136     int mConnections;
137 } WAYPOINT;
138 
139 typedef struct spawnpointstruc
140 {
141     int mX, mY;
142     int mClosestWaypoint;
143     int mType;
144 } SPAWNPOINT;
145 
146 typedef struct prefs_
147 {
148     char *homedir;
149     char *datadir;
150     char *cfgpath;
151     char *scorepath;
152     char *bindpath;
153     char *keyspath;
154     FILE *f;
155     char verbose;
156     char fullscreen;
157     char audio;
158     char difficulty;
159     char joystick;
160     char *wwwbrowser;
161 } PREFS;
162 
163 typedef struct scores_
164 {
165     char easy_n[10][9];
166     int easy_s[10];
167     char medium_n[10][9];
168     int medium_s[10];
169     char hard_n[10][9];
170     int hard_s[10];
171 } SCORES;
172 
173 typedef struct BUTTONS {
174     SDL_Surface *startgame;
175     SDL_Surface *startgameh;
176     SDL_Surface *fullscreen;
177     SDL_Surface *fullscreenh;
178     SDL_Surface *window;
179     SDL_Surface *windowh;
180     SDL_Surface *audioon;
181     SDL_Surface *audiooff;
182     SDL_Surface *audioonh;
183     SDL_Surface *audiooffh;
184     SDL_Surface *easy;
185     SDL_Surface *easyh;
186     SDL_Surface *medium;
187     SDL_Surface *mediumh;
188     SDL_Surface *hard;
189     SDL_Surface *hardh;
190     SDL_Surface *hiscores;
191     SDL_Surface *hiscoresh;
192     SDL_Surface *prefs;
193     SDL_Surface *prefsh;
194     SDL_Surface *quit;
195     SDL_Surface *quith;
196     SDL_Surface *resume;
197     SDL_Surface *resumeh;
198 } BUTTONS;
199 
200 #if 0
201 class SniperBGM {
202     Mix_Music *BGM;
203     int playp;
204     int pausep;
205     int startTime, stopTime;
206     float bookmark;
207     static const int FadeInTime = 3000;
208     static const int FadeOutTime = 1000;
209     static const float RepeatJumpPos = 0.0;
210   public:
211     SniperBGM();
212     SniperBGM(Mix_Music *m);
213     ~SniperBGM();
214     const SniperBGM & operator=(Mix_Music *m);
215     operator Mix_Music*() const;
216     void use(Mix_Music *m);
217     void start();
218     void stimulate();
219     void depress();
220     void stop();
221     void pause();
222     void pause(int newstate);
223     void jumpto(float pos);
224     void rewind();
225     void loop();
226     void release();
227     void grab();
228 };
229 #endif /* 0 */
230 
231 /* Phasing out class SniperBGM */
232 typedef struct sniperbgm_t {
233   Mix_Music *BGM;
234   int playp;
235   int pausep;
236   int time_start;
237   int time_stop;
238   float bookmark;
239 } sniperbgm_t;
240 
241 #define sniperbgm_FadeInTime 3000
242 #define sniperbgm_FadeOutTime 1000
243 #define sniperbgm_RepeatJumpPos 0.0
244 
245 sniperbgm_t * sniperbgm_init (sniperbgm_t *);
246 sniperbgm_t * sniperbgm_init_music (sniperbgm_t *, Mix_Music *);
247 sniperbgm_t * sniperbgm_destroy (sniperbgm_t *);
248 void sniperbgm_delete (sniperbgm_t *);
249 Mix_Music * sniperbgm_music (sniperbgm_t *);
250 int  sniperbgm_use (sniperbgm_t *, Mix_Music *);
251 void sniperbgm_start (sniperbgm_t *);
252 void sniperbgm_stimulate (sniperbgm_t *);
253 void sniperbgm_depress (sniperbgm_t *);
254 void sniperbgm_stop (sniperbgm_t *);
255 void sniperbgm_pause (sniperbgm_t *, int);
256 void sniperbgm_jumpto (sniperbgm_t *, float);
257 void sniperbgm_rewind (sniperbgm_t *);
258 void sniperbgm_loop (sniperbgm_t *);
259 void sniperbgm_release (sniperbgm_t *);
260 void sniperbgm_grab (sniperbgm_t *);
261 
262 
263 
264 /* character counter/generator state */
265 typedef struct charcount_t {
266   int spawn;      /* SpawnCount */
267   int count;      /* Count */
268   int dead;       /* Killed */
269   int goal;       /* GottenToSafety */
270   float time;     /* SpawnTime */
271   float period;   /* SpawnTimePeriod */
272 } charcount_t;
273 
274 #if 0
275 typedef struct soundeffect_t {
276   Mix_Chunk *data;
277   int len;
278   int ofs;
279 } soundeffect_t;
280 #endif /* 0 */
281 
282 /* game state */
283 typedef struct orbitalsniper_t {
284   SDL_Surface *Screen;
285   SDL_Surface *Map;
286   SDL_Surface *AIMap;
287   SDL_Surface *Font[5];
288   SDL_Surface *CharSprite;
289 
290   int ControlState;
291   float MouseX;
292   float MouseY;
293   float MouseZ;
294   float CoordScale;
295 
296   int WobbleIndex;
297   float WobbleX;
298   float WobbleY;
299   float CenterX;
300   float CenterY;
301 
302   int verbosity;
303   int Reloading;
304   int ReloadTime;
305   int StartTick;
306   int GameStartTick;
307   int GameOverTicks;
308   OES_ENDREASON GameOverReason;
309   int FrameCount;
310   int LastTick;
311   int Score;
312   float ScoreMod;  /* score modifier. */
313 
314   charcount_t vip;    /* keep alive at all costs. */
315   charcount_t baddy;    /* BadGuys */
316   charcount_t pedestrian;  /* collateral damage. */
317 
318   int num_characters;
319   CHARACTER *characters;  /* List of all characters in game */
320   int num_spawnpoints;
321   SPAWNPOINT *spawnpoints;  /* List of spawnpoints */
322   int num_waypoints;
323   WAYPOINT *waypoints;      /* List of waypoints */
324   CHARACTER * SightedCharacter;
325   SCORES HiScore;  /* high scores list */
326 
327 //  soundeffect_t AudioZoomSample;
328 //  soundeffect_t AudioFireSample;
329   Mix_Chunk *AudioZoomOut;
330   Mix_Chunk *AudioZoomIn;
331   Mix_Chunk *AudioFire;
332 
333   int GameState;
334   SDL_AudioSpec *sdlaudio;
335 //  SniperBGM BGM;
336   sniperbgm_t *BGM;
337   int GrabP;  /* mouse grab */
338   int BeforePauseTick;  /* keep spawn-timing across pauses. */
339   int AfterPauseTick;
340   int SemiPause;  /* double-click timer. */
341 
342   char *mediaPath;
343 //  int unreal_dither[];
344 } ORBITALSNIPER;
345 
346 
347 /* globals. */
348 
349 extern BUTTONS gButton;
350 extern int unreal_dither[];
351 extern char *mediaPath;
352 
353 extern ORBITALSNIPER Game;
354 
355 
356 /* function prototypes. */
357 extern float distance(float aX1, float aY1, float aX2, float aY2);
358 extern float distance_wp(int aWaypoint, float aX, float aY);
359 extern float distance_wpwp(int aWaypoint1, int aWaypoint2);
360 extern void handle_ai(CHARACTER &c);
361 extern int spawn_ai(int aType);
362 
363 extern void print(int aXofs, int aYofs, int aColor, const char *aString, ...);
364 extern void printShadow(int aXofs, int aYofs, const char *aString, ...);
365 extern void zoom(SDL_Surface * src, float ofsx, float ofsy, float scale);
366 extern void zoom_unreal(SDL_Surface * src, float ofsx, float ofsy, float scale);
367 extern void drawLine(SDL_Surface * aTarget, int x1,int y1,int x2, int y2, int clr);
368 extern void target();
369 extern void init();
370 extern void init_logoscreen();
371 extern void logoscreen();
372 extern void precalc_ai();
373 extern void shoot();
374 extern void gameoverscreen(int aReason);
375 
376 extern void drawCharacter(CHARACTER &c);
377 
378 extern void configure_difficulty();
379 
380 /* setup and teardown */
381 int oes_setup ();
382 void oes_teardown ();
383 int oes_suspend();
384 int oes_resume();
385 
386 /* Preferences */
387 PREFS *prefs_init (PREFS *);
388 PREFS *prefs_destroy (PREFS *);
389 void prefs_delete (PREFS *);
390 PREFS *prefs_load (PREFS *);
391 PREFS *prefs_save (PREFS *);
392 PREFS *prefs_create (PREFS *);
393 
394 extern void show_hiscores();
395 extern void init_hiscores();
396 extern void process_hiscore();
397 extern void save_hiscores();
398 
399 extern void prefs();
400 
401 
402 void draw_button (SDL_Surface *b, int x, int y);
403 
404 // FIXME:  everybody should use this.
405 SDL_Surface *oes_load_img (const char *path);
406 
407 bool hovering (int x, int y, int w, int h);
408 
409 
410 /* drawing */
411 void oes_fillrect (SDL_Surface *, int x0, int y0, int x1, int y1, int color);
412 
413 int draw_gameover (SDL_Surface *, const SDL_Rect *);
414 int draw_hiscores (SDL_Surface *, const SDL_Rect *);
415 
416 
417 /* S-Expressions (libsexpr) */
418 
419 #define PAIRP(se) ((se)->ty == SEXP_LIST)
420 #define ATOMP(se) ((se)->ty == SEXP_VALUE)
421 #define CAR(se) (ATOMP(se) ? se : hd_sexp(se))
422 #define CDR(se) (ATOMP(se) ? next_sexp(se) : tl_sexp(se))
423 
424 int prefs_load ();
425 int prefs_save ();
426 int prefs_init ();
427 
428 
429 int oes_game ();  /* main game loop */
430 
431 #include "ui.h"
432 
433 
434 
435