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