1 #include <allegro5/allegro.h>
2 #include <stdio.h>
3 #include <ctype.h>
4 #include "background_scroller.h"
5 #include "demodata.h"
6 #include "game.h"
7 #include "global.h"
8 #include "music.h"
9 #include "framework.h"
10 
11 /* Default values of some config varables */
12 #ifdef ALLEGRO_IPHONE
13 int fullscreen = 1;
14 int controller_id = 1;
15 #else
16 int fullscreen = 0;
17 int controller_id = 0;
18 #endif
19 int bit_depth = 32;
20 int screen_width = 640;
21 int screen_height = 480;
22 int screen_orientation = ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES;
23 int window_width = 640;
24 int window_height = 480;
25 int screen_samples = 1;
26 int use_vsync = 0;
27 int logic_framerate = 100;
28 int max_frame_skip = 5;
29 int limit_framerate = 1;
30 int display_framerate = 1;
31 int reduce_cpu_usage = 1;
32 int sound_volume = 8;
33 int music_volume = 8;
34 
35 int shadow_offset = 2;
36 
37 VCONTROLLER *controller[2];
38 
39 char config_path[DEMO_PATH_LENGTH];
40 char data_path[DEMO_PATH_LENGTH];
41 DATA_ENTRY *demo_data;
42 
43 ALLEGRO_DISPLAY *screen;
44 
45 char *GameError;
46 
47 int load_data(void);
48 
demo_error(int id)49 const char *demo_error(int id)
50 {
51    switch (id) {
52       case DEMO_ERROR_ALLEGRO:
53          return "Allegro error";
54       case DEMO_ERROR_GFX:
55          return "can't find suitable screen update driver";
56       case DEMO_ERROR_MEMORY:
57          return "ran out of memory";
58       case DEMO_ERROR_VIDEOMEMORY:
59          return "not enough VRAM";
60       case DEMO_ERROR_TRIPLEBUFFER:
61          return "triple buffering not supported";
62       case DEMO_ERROR_DATA:
63          return "can't load menu data";
64       case DEMO_ERROR_GAMEDATA:
65          return GameError;
66       case DEMO_OK:
67          return "OK";
68       default:
69          return "unknown";
70    };
71 }
72 
73 
get_config_int(const ALLEGRO_CONFIG * cfg,const char * section,const char * name,int def)74 int get_config_int(const ALLEGRO_CONFIG *cfg, const char *section,
75 		   const char *name, int def)
76 {
77    const char *v = al_get_config_value(cfg, section, name);
78 
79    return (v) ? atoi(v) : def;
80 }
81 
82 
set_config_int(ALLEGRO_CONFIG * cfg,const char * section,const char * name,int val)83 void set_config_int(ALLEGRO_CONFIG *cfg, const char *section, const char *name,
84 		    int val)
85 {
86    char buf[32];
87 
88    sprintf(buf, "%d", val);
89    al_set_config_value(cfg, section, name, buf);
90 }
91 
92 
93 /* read_config:
94  * Load settings from the configuration file, providing default values
95  */
read_global_config(const char * config)96 void read_global_config(const char *config)
97 {
98    ALLEGRO_CONFIG *c = al_load_config_file(config);
99    if (!c) c = al_create_config();
100 
101    fullscreen = get_config_int(c, "GFX", "fullscreen", fullscreen);
102    bit_depth = get_config_int(c, "GFX", "bit_depth", bit_depth);
103    screen_width = get_config_int(c, "GFX", "screen_width", screen_width);
104    screen_height = get_config_int(c, "GFX", "screen_height", screen_height);
105    window_width = get_config_int(c, "GFX", "window_width", window_height);
106    window_height = get_config_int(c, "GFX", "window_height", screen_height);
107    screen_samples = get_config_int(c, "GFX", "samples", screen_samples);
108    use_vsync = get_config_int(c, "GFX", "vsync", use_vsync);
109 
110    logic_framerate =
111       get_config_int(c, "TIMING", "logic_framerate", logic_framerate);
112    limit_framerate =
113       get_config_int(c, "TIMING", "limit_framerate", limit_framerate);
114    max_frame_skip =
115       get_config_int(c, "TIMING", "max_frame_skip", max_frame_skip);
116    display_framerate =
117       get_config_int(c, "TIMING", "display_framerate", display_framerate);
118    reduce_cpu_usage =
119       get_config_int(c, "TIMING", "reduce_cpu_usage", reduce_cpu_usage);
120 
121    sound_volume = get_config_int(c, "SOUND", "sound_volume", sound_volume);
122    music_volume = get_config_int(c, "SOUND", "music_volume", music_volume);
123 
124    set_sound_volume(sound_volume / 10.0);
125    set_music_volume(music_volume / 10.0);
126 
127    controller_id = get_config_int(c, "CONTROLS", "controller_id", controller_id);
128 
129    al_destroy_config(c);
130 }
131 
132 
write_global_config(const char * config)133 void write_global_config(const char *config)
134 {
135    ALLEGRO_CONFIG *c = al_load_config_file(config);
136    if (!c) c = al_create_config();
137 
138    set_config_int(c, "GFX", "fullscreen", fullscreen);
139    set_config_int(c, "GFX", "bit_depth", bit_depth);
140    set_config_int(c, "GFX", "screen_width", screen_width);
141    set_config_int(c, "GFX", "screen_height", screen_height);
142    set_config_int(c, "GFX", "window_width", window_width);
143    set_config_int(c, "GFX", "window_height", window_height);
144    set_config_int(c, "GFX", "samples", screen_samples);
145    set_config_int(c, "GFX", "vsync", use_vsync);
146 
147    set_config_int(c, "TIMING", "logic_framerate", logic_framerate);
148    set_config_int(c, "TIMING", "max_frame_skip", max_frame_skip);
149    set_config_int(c, "TIMING", "limit_framerate", limit_framerate);
150    set_config_int(c, "TIMING", "display_framerate", display_framerate);
151    set_config_int(c, "TIMING", "reduce_cpu_usage", reduce_cpu_usage);
152 
153    set_config_int(c, "SOUND", "sound_volume", sound_volume);
154    set_config_int(c, "SOUND", "music_volume", music_volume);
155 
156    set_config_int(c, "CONTROLS", "controller_id", controller_id);
157 
158    al_save_config_file(config, c);
159    al_destroy_config(c);
160 }
161 
load(DATA_ENTRY * d,int id,char const * type,char const * path,char const * subfolder,char const * name,char const * ext,int size)162 static bool load(DATA_ENTRY *d, int id, char const *type, char const *path,
163    char const *subfolder, char const *name, char const *ext, int size)
164 {
165    static char spath[1024];
166    sprintf(spath, "%s/%s/%s.%s", path, subfolder, name, ext);
167    printf("Loading %s...\n", spath);
168    if (!strcmp(type, "font")) d[id].dat = al_load_font(spath, size, 0);
169    if (!strcmp(type, "bitmap")) d[id].dat = al_load_bitmap(spath);
170    if (!strcmp(type, "sample")) d[id].dat = al_load_sample(spath);
171    if (!strcmp(type, "music")) d[id].dat = al_load_audio_stream(spath, 2, 4096);
172    if (d[id].dat == NULL) {
173       printf("Failed loading %s.\n", name);
174    }
175    d[id].type = type;
176    d[id].path = strdup(path);
177    d[id].subfolder = strdup(subfolder);
178    d[id].name = strdup(name);
179    d[id].ext = strdup(ext);
180    d[id].size = size;
181    return d[id].dat != NULL;
182 }
183 
change_gfx_mode(void)184 int change_gfx_mode(void)
185 {
186    int ret = DEMO_OK;
187    int flags = 0;
188 
189    /* Select appropriate (fullscreen or windowed) gfx mode driver. */
190    if (fullscreen == 0) {
191       flags |= ALLEGRO_WINDOWED | ALLEGRO_RESIZABLE;
192       screen_width = window_width;
193       screen_height = window_height;
194    } else if (fullscreen == 1) {
195       flags |= ALLEGRO_FULLSCREEN_WINDOW;
196    } else {
197       flags |= ALLEGRO_FULLSCREEN;
198    }
199 
200    if (screen) {
201       al_destroy_display(screen);
202    }
203 
204    al_set_new_display_flags(flags);
205 
206    // May be a good idea, but need to add a border to textures for it.
207    // al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR);
208 
209    if (screen_samples > 1) {
210       al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST);
211       al_set_new_display_option(ALLEGRO_SAMPLES, screen_samples, ALLEGRO_SUGGEST);
212    }
213    else {
214       al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 0, ALLEGRO_SUGGEST);
215       al_set_new_display_option(ALLEGRO_SAMPLES, 0, ALLEGRO_SUGGEST);
216    }
217 
218    al_set_new_display_option(ALLEGRO_SUPPORTED_ORIENTATIONS,
219                              ALLEGRO_DISPLAY_ORIENTATION_LANDSCAPE, ALLEGRO_SUGGEST);
220 
221    /* Attempt to set the selected colour depth and gfx mode. */
222    screen = al_create_display(screen_width, screen_height);
223    if (!screen) {
224       return DEMO_ERROR_ALLEGRO;
225    }
226    al_set_window_constraints(screen, 320, 320, 0, 0);
227 
228    screen_width = al_get_display_width(screen);
229    screen_height = al_get_display_height(screen);
230    screen_orientation = ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES;
231 
232    al_register_event_source(event_queue, al_get_display_event_source(screen));
233 
234    /* blank display now, before doing any more complicated stuff */
235    al_clear_to_color(al_map_rgb(0, 0, 0));
236 
237    /* Attempt to load game data. */
238    ret = load_data();
239 
240    /* If loading was successful, initialize the background scroller module. */
241    if (ret == DEMO_OK) {
242       init_background();
243    }
244 
245    return ret;
246 }
247 
load_data_entries(char const * path)248 static DATA_ENTRY *load_data_entries(char const *path)
249 {
250    DATA_ENTRY *d = calloc(DEMO_DATA_COUNT + 1, sizeof *d);
251    load(d, DEMO_BMP_BACK,        "bitmap",   path, "menu",     "back", "png", 0);
252    load(d, DEMO_FONT,            "font",     path, "menu",     "cancunsmall", "png", 0);
253    load(d, DEMO_FONT_LOGO,       "font",     path, "menu",     "logofont", "png", 0);
254    load(d, DEMO_MIDI_INGAME,     "music",    path, "menu",     "skate2", "ogg", 0);
255    load(d, DEMO_MIDI_INTRO,      "music",    path, "menu",     "intro_music", "ogg", 0);
256    load(d, DEMO_MIDI_MENU,       "music",    path, "menu",     "menu_music", "ogg", 0);
257    load(d, DEMO_MIDI_SUCCESS,    "music",    path, "menu",     "endoflevel", "ogg", 0);
258    load(d, DEMO_SAMPLE_BUTTON,   "sample",   path, "menu",     "button", "ogg", 0);
259    load(d, DEMO_SAMPLE_WELCOME,  "sample",   path, "menu",     "welcome", "ogg", 0);
260    load(d, DEMO_SAMPLE_SKATING,  "sample",   path, "audio",    "skating", "ogg", 0);
261    load(d, DEMO_SAMPLE_WAVE,     "sample",   path, "audio",    "wave", "ogg", 0);
262    load(d, DEMO_SAMPLE_DING,     "sample",   path, "audio",    "ding", "ogg", 0);
263    load(d, DEMO_SAMPLE_DOOROPEN, "sample",   path, "audio",    "dooropen", "ogg", 0);
264    load(d, DEMO_SAMPLE_POP,      "sample",   path, "audio",    "pop", "ogg", 0);
265 
266    load(d, DEMO_BMP_BANANAS,     "bitmap",   path, "graphics", "bananas", "png", 0);
267    load(d, DEMO_BMP_CHERRIES,    "bitmap",   path, "graphics", "cherries", "png", 0);
268    load(d, DEMO_BMP_CLOUD,       "bitmap",   path, "graphics", "cloud", "png", 0);
269    load(d, DEMO_BMP_DOOROPEN,    "bitmap",   path, "graphics", "dooropen", "png", 0);
270    load(d, DEMO_BMP_DOORSHUT,    "bitmap",   path, "graphics", "doorshut", "png", 0);
271    load(d, DEMO_BMP_EXITSIGN,    "bitmap",   path, "graphics", "exitsign", "png", 0);
272    load(d, DEMO_BMP_GRASS,       "bitmap",   path, "graphics", "grass", "png", 0);
273    load(d, DEMO_BMP_ICECREAM,    "bitmap",   path, "graphics", "icecream", "png", 0);
274    load(d, DEMO_BMP_ICE,         "bitmap",   path, "graphics", "ice", "png", 0);
275    load(d, DEMO_BMP_ICETIP,      "bitmap",   path, "graphics", "icetip", "png", 0);
276    load(d, DEMO_BMP_ORANGE,      "bitmap",   path, "graphics", "orange", "png", 0);
277    load(d, DEMO_BMP_SKATEFAST,   "bitmap",   path, "graphics", "skatefast", "png", 0);
278    load(d, DEMO_BMP_SKATEMED,    "bitmap",   path, "graphics", "skatemed", "png", 0);
279    load(d, DEMO_BMP_SKATER1,     "bitmap",   path, "graphics", "skater1", "png", 0);
280    load(d, DEMO_BMP_SKATER2,     "bitmap",   path, "graphics", "skater2", "png", 0);
281    load(d, DEMO_BMP_SKATER3,     "bitmap",   path, "graphics", "skater3", "png", 0);
282    load(d, DEMO_BMP_SKATER4,     "bitmap",   path, "graphics", "skater4", "png", 0);
283    load(d, DEMO_BMP_SKATESLOW,   "bitmap",   path, "graphics", "skateslow", "png", 0);
284    load(d, DEMO_BMP_SOIL,        "bitmap",   path, "graphics", "soil", "png", 0);
285    load(d, DEMO_BMP_SWEET,       "bitmap",   path, "graphics", "sweet", "png", 0);
286    load(d, DEMO_BMP_WATER,       "bitmap",   path, "graphics", "water", "png", 0);
287 
288    return d;
289 }
290 
unload_data_entries(DATA_ENTRY * data)291 void unload_data_entries(DATA_ENTRY *data)
292 {
293     while (data && data->dat) {
294         if (!strcmp(data->type, "bitmap")) al_destroy_bitmap(data->dat);
295         if (!strcmp(data->type, "font")) al_destroy_font(data->dat);
296         if (!strcmp(data->type, "sample")) al_destroy_sample(data->dat);
297         if (!strcmp(data->type, "music")) al_destroy_audio_stream(data->dat);
298         data++;
299     }
300 }
301 
load_data(void)302 int load_data(void)
303 {
304    if (demo_data)
305       return DEMO_OK;
306 
307    /* Load the data for the game menus. */
308    demo_data = load_data_entries(data_path);
309    if (demo_data == 0) {
310       return DEMO_ERROR_DATA;
311    }
312 
313    /* Load other game resources. */
314    if ((GameError = load_game_resources(data_path)))
315       return DEMO_ERROR_GAMEDATA;
316 
317    return DEMO_OK;
318 }
319 
320 
unload_data(void)321 void unload_data(void)
322 {
323    if (demo_data != 0) {
324       unload_data_entries(demo_data);
325       unload_game_resources();
326       demo_data = 0;
327    }
328 }
329 
330 
demo_textout(const ALLEGRO_FONT * f,const char * s,int x,int y,ALLEGRO_COLOR color)331 void demo_textout(const ALLEGRO_FONT *f, const char *s, int x, int y,
332                   ALLEGRO_COLOR color)
333 {
334    demo_textprintf(f, x, y, color, "%s", s);
335 }
336 
337 
demo_textout_right(const ALLEGRO_FONT * f,const char * s,int x,int y,ALLEGRO_COLOR color)338 void demo_textout_right(const ALLEGRO_FONT *f, const char *s, int x, int y,
339                   ALLEGRO_COLOR color)
340 {
341    demo_textprintf_right(f, x, y, color, "%s", s);
342 }
343 
344 
demo_textout_centre(const ALLEGRO_FONT * f,const char * s,int x,int y,ALLEGRO_COLOR color)345 void demo_textout_centre(const ALLEGRO_FONT *f, const char *s, int x, int y,
346                   ALLEGRO_COLOR color)
347 {
348    demo_textprintf_centre(f, x, y, color, "%s", s);
349 }
350 
351 
demo_textprintf_centre(const ALLEGRO_FONT * font,int x,int y,ALLEGRO_COLOR col,const char * format,...)352 void demo_textprintf_centre(const ALLEGRO_FONT *font, int x, int y,
353                      ALLEGRO_COLOR col, const char *format, ...)
354 {
355    char buf[512];
356 
357    va_list ap;
358 
359    va_start(ap, format);
360    vsnprintf(buf, sizeof(buf), format, ap);
361    va_end(ap);
362 
363    demo_textprintf_ex(font, x, y, col, 2, "%s", buf);
364 }
365 
366 
demo_textprintf_right(const ALLEGRO_FONT * font,int x,int y,ALLEGRO_COLOR col,const char * format,...)367 void demo_textprintf_right(const ALLEGRO_FONT *font, int x, int y,
368                      ALLEGRO_COLOR col, const char *format, ...)
369 {
370    char buf[512];
371 
372    va_list ap;
373 
374    va_start(ap, format);
375    vsnprintf(buf, sizeof(buf), format, ap);
376    va_end(ap);
377 
378    demo_textprintf_ex(font, x, y, col, 1, "%s", buf);
379 }
380 
381 
demo_textprintf(const ALLEGRO_FONT * font,int x,int y,ALLEGRO_COLOR col,const char * format,...)382 void demo_textprintf(const ALLEGRO_FONT *font, int x, int y,
383                      ALLEGRO_COLOR col, const char *format, ...)
384 {
385    char buf[512];
386 
387    va_list ap;
388 
389    va_start(ap, format);
390    vsnprintf(buf, sizeof(buf), format, ap);
391    va_end(ap);
392 
393    demo_textprintf_ex(font, x, y, col, 0, "%s", buf);
394 }
395 
demo_textprintf_ex(const ALLEGRO_FONT * font,int x,int y,ALLEGRO_COLOR col,int align,const char * format,...)396 void demo_textprintf_ex(const ALLEGRO_FONT *font, int x, int y,
397                      ALLEGRO_COLOR col, int align, const char *format, ...)
398 {
399    char buf[512];
400 
401    va_list ap;
402 
403    va_start(ap, format);
404    vsnprintf(buf, sizeof(buf), format, ap);
405    va_end(ap);
406 
407    switch (align) {
408       case 0:
409          al_draw_textf(font, col, x, y, ALLEGRO_ALIGN_LEFT, "%s", buf);
410          break;
411       case 1:
412          al_draw_textf(font, col, x, y, ALLEGRO_ALIGN_RIGHT, "%s", buf);
413          break;
414       case 2:
415          al_draw_textf(font, col, x, y, ALLEGRO_ALIGN_CENTRE, "%s", buf);
416          break;
417    };
418 
419 }
420 
421 
shadow_textprintf(ALLEGRO_FONT * font,int x,int y,ALLEGRO_COLOR col,int align,const char * format,...)422 void shadow_textprintf(ALLEGRO_FONT *font, int x, int y,
423                      ALLEGRO_COLOR col, int align, const char *format, ...)
424 {
425    char buf[512];
426 
427    va_list ap;
428 
429    va_start(ap, format);
430    vsnprintf(buf, sizeof(buf), format, ap);
431    va_end(ap);
432 
433    demo_textprintf_ex(font, x + shadow_offset, y + shadow_offset, al_map_rgba(0, 0, 0, 128),
434                    align, "%s", buf);
435    demo_textprintf_ex(font, x, y, col, align, "%s", buf);
436 }
437 
my_stricmp(const char * s1,const char * s2)438 int my_stricmp(const char *s1, const char *s2)
439 {
440     char c1, c2;
441     int v;
442 
443     while(1) {
444         c1 = *s1++;
445         c2 = *s2++;
446         v = tolower(c1) - tolower(c2);
447         if (v != 0 || c1 == 0 || c2 == 0) break;
448     }
449 
450     return v;
451 }
452