1 /*
2     FreeBlocks -  A simple puzzle game, similar to Tetris Attack
3     Copyright (C) 2012 Justin Jacobs
4 
5     This program is free software: you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation, either version 3 of the License, or
8     (at your option) any later version.
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <sys/stat.h>
23 #include <sys/types.h>
24 
25 #include <SDL.h>
26 #include <SDL_image.h>
27 #include <SDL_ttf.h>
28 #include <SDL_mixer.h>
29 
30 #include "sys.h"
31 
32 #ifdef __GCW0__
33 #define SDL_FLAGS (SDL_HWSURFACE|SDL_TRIPLEBUF)
34 #else
35 #define SDL_FLAGS (SDL_HWSURFACE)
36 #endif
37 
38 const char* const key_desc[] = {
39     "Switch blocks",
40     "Raise blocks",
41     "Accept",
42     "Pause",
43     "Exit",
44     "Left",
45     "Right",
46     "Up",
47     "Down"
48 };
49 
50 SDL_Surface* screen = NULL;
51 TTF_Font* font = NULL;
52 SDL_Surface* surface_blocks = NULL;
53 SDL_Surface* surface_clear = NULL;
54 SDL_Surface* surface_cursor = NULL;
55 SDL_Surface* surface_cursor_highlight = NULL;
56 SDL_Surface* surface_cursor_single = NULL;
57 SDL_Surface* surface_bar = NULL;
58 SDL_Surface* surface_bar_inactive = NULL;
59 SDL_Surface* surface_background = NULL;
60 SDL_Surface* surface_background_jewels = NULL;
61 SDL_Surface* surface_title = NULL;
62 SDL_Surface* surface_highscores = NULL;
63 Mix_Music* music = NULL;
64 Mix_Music* music_jewels = NULL;
65 Mix_Chunk* sound_menu = NULL;
66 Mix_Chunk* sound_switch = NULL;
67 Mix_Chunk* sound_match = NULL;
68 Mix_Chunk* sound_drop = NULL;
69 SDL_Joystick* joy = NULL;
70 
71 int score = 0;
72 int high_scores[10];
73 bool title_screen = true;
74 bool high_scores_screen = false;
75 int options_screen = -1;
76 bool game_over = false;
77 bool paused = false;
78 bool quit = false;
79 
80 int game_mode = GAME_MODE_DEFAULT;
81 
82 struct Cursor cursor;
83 
84 int action_cooldown = 0;
85 ActionMove action_move = ACTION_NONE;
86 ActionMove action_last_move = ACTION_NONE;
87 bool action_switch = false;
88 bool action_bump = false;
89 bool action_accept = false;
90 bool action_pause = false;
91 bool action_exit = false;
92 
93 Dork_String path_dir_config;
94 Dork_String path_file_config;
95 Dork_String path_file_highscores;
96 Dork_String path_file_highscores_jewels;
97 
98 int option_joystick = -1;
99 int option_sound = 8;
100 int option_music = 8;
101 
102 #ifdef __GCW0__
103 int option_fullscreen = 1;
104 #else
105 int option_fullscreen = 0;
106 #endif
107 
108 SDLKey option_key[9];
109 int option_joy_button[5];
110 int option_joy_axis_x;
111 int option_joy_axis_y;
112 
113 SDLKey last_key = SDLK_UNKNOWN;
114 int last_joy_button = -1;
115 
116 SDL_Event event;
117 
118 // Timers
119 unsigned int startTimer;
120 unsigned int endTimer;
121 unsigned int deltaTimer;
122 
sysInit()123 bool sysInit() {
124     if(SDL_Init(SDL_INIT_EVERYTHING) == -1) return false;
125 
126     screen = SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,SDL_FLAGS);
127 
128     if(screen == NULL) return false;
129 
130     if(TTF_Init() == -1) return false;
131 
132     if(Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 1024) == -1 ) return false;
133 
134     SDL_WM_SetCaption("FreeBlocks v0.5",NULL);
135 
136     // set up the default controls
137     option_key[KEY_SWITCH] = SDLK_LCTRL;
138     option_key[KEY_BUMP] = SDLK_LALT;
139     option_key[KEY_ACCEPT] = SDLK_RETURN;
140     option_key[KEY_EXIT] = SDLK_ESCAPE;
141 
142     option_key[KEY_LEFT] = SDLK_LEFT;
143     option_key[KEY_RIGHT] = SDLK_RIGHT;
144     option_key[KEY_UP] = SDLK_UP;
145     option_key[KEY_DOWN] = SDLK_DOWN;
146 
147 #ifdef __GCW0__
148     option_key[KEY_PAUSE] = SDLK_RETURN;
149 #else
150     option_key[KEY_PAUSE] = SDLK_ESCAPE;
151 #endif
152 
153     option_joy_button[KEY_SWITCH] = 0;
154     option_joy_button[KEY_BUMP] = 1;
155     option_joy_button[KEY_ACCEPT] = 9;
156     option_joy_button[KEY_PAUSE] = 9;
157     option_joy_button[KEY_EXIT] = 8;
158 
159     option_joy_axis_x = 0;
160     option_joy_axis_y = 1;
161 
162     // load config
163     sysConfigSetPaths();
164     sysConfigLoad();
165 
166     //load high scores
167     sysHighScoresClear();
168     sysHighScoresLoad();
169 
170     return true;
171 }
172 
sysGetFilePath(Dork_String * dest,const char * path,bool is_gfx)173 char* sysGetFilePath(Dork_String *dest, const char* path, bool is_gfx) {
174     if (dest == NULL) return NULL;
175 
176     struct stat st;
177 
178     // try current directory
179     Dork_StringClear(dest);
180     Dork_StringAppend(dest, "./res");
181     if (is_gfx) {
182         Dork_StringAppend(dest, GFX_PREFIX);
183     }
184     Dork_StringAppend(dest, path);
185 
186     if (stat(Dork_StringGetData(dest), &st) == 0)
187         return Dork_StringGetData(dest);
188 
189     // try install directory
190     Dork_StringClear(dest);
191     Dork_StringAppend(dest, PKGDATADIR);
192     if (is_gfx) {
193         Dork_StringAppend(dest, GFX_PREFIX);
194     }
195     Dork_StringAppend(dest, path);
196 
197     if (stat(Dork_StringGetData(dest), &st) == 0)
198         return Dork_StringGetData(dest);
199 
200     // failure, just return NULL
201     return NULL;
202 }
203 
sysLoadImage(SDL_Surface ** dest,const char * path)204 bool sysLoadImage(SDL_Surface** dest, const char* path) {
205     Dork_String temp;
206     Dork_StringInit(&temp);
207 
208     *dest = IMG_Load(sysGetFilePath(&temp, path, true));
209     if (*dest == NULL) {
210         Dork_StringClear(&temp);
211         return false;
212     }
213     else {
214         SDL_Surface *cleanup = *dest;
215         *dest = SDL_DisplayFormatAlpha(cleanup);
216         SDL_FreeSurface(cleanup);
217     }
218 
219     Dork_StringClear(&temp);
220     return true;
221 }
222 
sysLoadFont(TTF_Font ** dest,const char * path,int font_size)223 bool sysLoadFont(TTF_Font** dest, const char* path, int font_size) {
224     Dork_String temp;
225     Dork_StringInit(&temp);
226 
227     *dest = TTF_OpenFont(sysGetFilePath(&temp, path, false), font_size);
228     if(*dest == NULL) {
229         Dork_StringClear(&temp);
230         return false;
231     }
232     else TTF_SetFontHinting(*dest, TTF_HINTING_LIGHT);
233 
234     Dork_StringClear(&temp);
235     return true;
236 }
237 
sysLoadMusic(Mix_Music ** dest,const char * path)238 bool sysLoadMusic(Mix_Music** dest, const char* path) {
239     Dork_String temp;
240     Dork_StringInit(&temp);
241 
242     *dest = Mix_LoadMUS(sysGetFilePath(&temp, path, false));
243     if (*dest == NULL) {
244         Dork_StringClear(&temp);
245         return false;
246     }
247 
248     Dork_StringClear(&temp);
249     return true;
250 }
251 
sysLoadSound(Mix_Chunk ** dest,const char * path)252 bool sysLoadSound(Mix_Chunk** dest, const char* path) {
253     Dork_String temp;
254     Dork_StringInit(&temp);
255 
256     *dest = Mix_LoadWAV(sysGetFilePath(&temp, path, false));
257     if (*dest == NULL) {
258         Dork_StringClear(&temp);
259         return false;
260     }
261 
262     Dork_StringClear(&temp);
263     return true;
264 }
265 
sysLoadFiles()266 bool sysLoadFiles() {
267     // font
268     if (!sysLoadFont(&font, "/fonts/Alegreya-Regular.ttf", FONT_SIZE)) return false;
269 
270     // graphics
271     if (!sysLoadImage(&surface_blocks, "blocks.png")) return false;
272     if (!sysLoadImage(&surface_clear, "clear.png")) return false;
273     if (!sysLoadImage(&surface_cursor, "cursor.png")) return false;
274     if (!sysLoadImage(&surface_cursor_highlight, "cursor_highlight.png")) return false;
275     if (!sysLoadImage(&surface_bar, "bar.png")) return false;
276     if (!sysLoadImage(&surface_bar_inactive, "bar_inactive.png")) return false;
277     if (!sysLoadImage(&surface_background, "background.png")) return false;
278     if (!sysLoadImage(&surface_background_jewels, "background_jewels.png")) return false;
279     if (!sysLoadImage(&surface_title, "title.png")) return false;
280     if (!sysLoadImage(&surface_highscores, "highscores.png")) return false;
281 
282     // background music
283     if (!sysLoadMusic(&music, "/sounds/music.ogg")) return false;
284     if (!sysLoadMusic(&music_jewels, "/sounds/music_jewels.ogg")) return false;
285 
286     // sound effects
287     if (!sysLoadSound(&sound_menu, "/sounds/menu.wav")) return false;
288     if (!sysLoadSound(&sound_switch, "/sounds/switch.wav")) return false;
289     if (!sysLoadSound(&sound_match, "/sounds/match.wav")) return false;
290     if (!sysLoadSound(&sound_drop, "/sounds/drop.wav")) return false;
291 
292     return true;
293 }
294 
sysCleanup()295 void sysCleanup() {
296     sysConfigSave();
297 
298     Dork_StringClear(&path_dir_config);
299     Dork_StringClear(&path_file_config);
300     Dork_StringClear(&path_file_highscores);
301     Dork_StringClear(&path_file_highscores_jewels);
302 
303     Mix_HaltMusic();
304 
305     TTF_CloseFont(font);
306     SDL_FreeSurface(surface_blocks);
307     SDL_FreeSurface(surface_clear);
308     SDL_FreeSurface(surface_cursor);
309     SDL_FreeSurface(surface_cursor_highlight);
310     SDL_FreeSurface(surface_bar);
311     SDL_FreeSurface(surface_background);
312     SDL_FreeSurface(surface_background_jewels);
313     SDL_FreeSurface(surface_title);
314     SDL_FreeSurface(surface_highscores);
315     Mix_FreeMusic(music);
316     Mix_FreeMusic(music_jewels);
317     Mix_FreeChunk(sound_menu);
318     Mix_FreeChunk(sound_switch);
319     Mix_FreeChunk(sound_match);
320     Mix_FreeChunk(sound_drop);
321     SDL_Quit();
322 }
323 
sysInput()324 void sysInput() {
325     while (SDL_PollEvent(&event)) {
326         if (event.type == SDL_KEYDOWN) {
327             last_key = event.key.keysym.sym;
328 
329             if (event.key.keysym.sym == option_key[KEY_LEFT])
330                 action_move = ACTION_LEFT;
331             if (event.key.keysym.sym == option_key[KEY_RIGHT])
332                 action_move = ACTION_RIGHT;
333             if (event.key.keysym.sym == option_key[KEY_UP])
334                 action_move = ACTION_UP;
335             if (event.key.keysym.sym == option_key[KEY_DOWN])
336                 action_move = ACTION_DOWN;
337             if (event.key.keysym.sym == option_key[KEY_SWITCH])
338                 action_switch = true;
339             if (event.key.keysym.sym == option_key[KEY_BUMP])
340                 action_bump = true;
341             if (event.key.keysym.sym == option_key[KEY_ACCEPT])
342                 action_accept = true;
343             if (event.key.keysym.sym == option_key[KEY_PAUSE])
344                 action_pause = true;
345             if (event.key.keysym.sym == option_key[KEY_EXIT])
346                 action_exit = true;
347         }
348 
349         else if (event.type == SDL_KEYUP) {
350             if ((event.key.keysym.sym == option_key[KEY_LEFT] && action_move == ACTION_LEFT) ||
351                (event.key.keysym.sym == option_key[KEY_RIGHT] && action_move == ACTION_RIGHT) ||
352                (event.key.keysym.sym == option_key[KEY_UP] && action_move == ACTION_UP) ||
353                (event.key.keysym.sym == option_key[KEY_DOWN] && action_move == ACTION_DOWN)) {
354                 action_move = ACTION_NONE;
355                 action_last_move = ACTION_NONE;
356             }
357             if (event.key.keysym.sym == option_key[KEY_SWITCH])
358                 action_switch = false;
359             if (event.key.keysym.sym == option_key[KEY_BUMP])
360                 action_bump = false;
361             if (event.key.keysym.sym == option_key[KEY_ACCEPT])
362                 action_accept = false;
363             if (event.key.keysym.sym == option_key[KEY_PAUSE])
364                 action_pause = false;
365             if (event.key.keysym.sym == option_key[KEY_EXIT])
366                 action_exit = false;
367         }
368 
369         else if (option_joystick > -1 && event.type == SDL_JOYBUTTONDOWN) {
370             if (event.jbutton.which == option_joystick) {
371                 last_joy_button = event.jbutton.button;
372 
373                 if (event.jbutton.button == option_joy_button[KEY_SWITCH])
374                     action_switch = true;
375                 if (event.jbutton.button == option_joy_button[KEY_BUMP])
376                     action_bump = true;
377                 if (event.jbutton.button == option_joy_button[KEY_ACCEPT])
378                     action_accept = true;
379                 if (event.jbutton.button == option_joy_button[KEY_PAUSE])
380                     action_pause = true;
381                 if (event.jbutton.button == option_joy_button[KEY_EXIT])
382                     action_exit = true;
383             }
384         }
385 
386         else if (option_joystick > -1 && event.type == SDL_JOYBUTTONUP) {
387             if (event.jbutton.which == option_joystick) {
388                 if (event.jbutton.button == option_joy_button[KEY_SWITCH])
389                     action_switch = false;
390                 if (event.jbutton.button == option_joy_button[KEY_BUMP])
391                     action_bump = false;
392                 if (event.jbutton.button == option_joy_button[KEY_ACCEPT])
393                     action_accept = false;
394                 if (event.jbutton.button == option_joy_button[KEY_PAUSE])
395                     action_pause = false;
396                 if (event.jbutton.button == option_joy_button[KEY_EXIT])
397                     action_exit = false;
398             }
399         }
400 
401         else if (event.type == SDL_QUIT) {
402             quit = true;
403         }
404     }
405 
406     if (joy && event.type != SDL_KEYDOWN && event.type != SDL_KEYUP) {
407         int joy_x = SDL_JoystickGetAxis(joy, 0);
408         int joy_y = SDL_JoystickGetAxis(joy, 1);
409 
410         // x axis
411         if (joy_x < -JOY_DEADZONE) {
412             action_move = ACTION_LEFT;
413         } else if (joy_x > JOY_DEADZONE) {
414             action_move = ACTION_RIGHT;
415         }
416 
417         // y axis
418         if (joy_y < -JOY_DEADZONE) {
419             action_move = ACTION_UP;
420         } else if (joy_y > JOY_DEADZONE) {
421             action_move = ACTION_DOWN;
422         }
423 
424         if (joy_x >= -JOY_DEADZONE && joy_x <= JOY_DEADZONE && joy_y >= -JOY_DEADZONE && joy_y <= JOY_DEADZONE) {
425             action_move = ACTION_NONE;
426         }
427     }
428 }
429 
sysInputReset()430 void sysInputReset() {
431     action_move = ACTION_NONE;
432     action_switch = false;
433     action_bump = false;
434     action_accept = false;
435     action_pause = false;
436     action_exit = false;
437 }
438 
sysConfigSetPaths()439 void sysConfigSetPaths() {
440     Dork_StringInit(&path_dir_config);
441     Dork_StringAppend(&path_dir_config, getenv(HOME_DIR_ENV));
442     Dork_StringAppend(&path_dir_config, "/.freeblocks");
443 
444     Dork_StringInit(&path_file_config);
445     Dork_StringAppend(&path_file_config, Dork_StringGetData(&path_dir_config));
446     Dork_StringAppend(&path_file_config, "/config");
447 
448     Dork_StringInit(&path_file_highscores);
449     Dork_StringAppend(&path_file_highscores, Dork_StringGetData(&path_dir_config));
450     Dork_StringAppend(&path_file_highscores, "/highscores");
451 
452     Dork_StringInit(&path_file_highscores_jewels);
453     Dork_StringAppend(&path_file_highscores_jewels, Dork_StringGetData(&path_dir_config));
454     Dork_StringAppend(&path_file_highscores_jewels, "/highscores_jewels");
455 }
456 
sysConfigLoad()457 void sysConfigLoad() {
458     char buffer[BUFSIZ];
459     char *key = NULL;
460     char *temp = NULL;
461 
462     mkdir(Dork_StringGetData(&path_dir_config), MKDIR_MODE);
463 
464     FILE *config_file = fopen(Dork_StringGetData(&path_file_config),"r+");
465     if (config_file) {
466         while (fgets(buffer,BUFSIZ,config_file)) {
467             temp = buffer;
468             if (temp[0] == '#') continue;
469             key = strtok(temp,"=");
470             if (strcmp(key,"joystick") == 0) option_joystick = atoi(strtok(NULL,"\n"));
471             else if (strcmp(key,"sound") == 0) option_sound = atoi(strtok(NULL,"\n"));
472             else if (strcmp(key,"music") == 0) option_music = atoi(strtok(NULL,"\n"));
473             else if (strcmp(key,"fullscreen") == 0) option_fullscreen = atoi(strtok(NULL,"\n"));
474 
475             else if (strcmp(key,"key_switch") == 0) option_key[KEY_SWITCH] = (SDLKey)atoi(strtok(NULL,"\n"));
476             else if (strcmp(key,"key_bump") == 0) option_key[KEY_BUMP] = (SDLKey)atoi(strtok(NULL,"\n"));
477             else if (strcmp(key,"key_accept") == 0) option_key[KEY_ACCEPT] = (SDLKey)atoi(strtok(NULL,"\n"));
478             else if (strcmp(key,"key_pause") == 0) option_key[KEY_PAUSE] = (SDLKey)atoi(strtok(NULL,"\n"));
479             else if (strcmp(key,"key_exit") == 0) option_key[KEY_EXIT] = (SDLKey)atoi(strtok(NULL,"\n"));
480             else if (strcmp(key,"key_left") == 0) option_key[KEY_LEFT] = (SDLKey)atoi(strtok(NULL,"\n"));
481             else if (strcmp(key,"key_right") == 0) option_key[KEY_RIGHT] = (SDLKey)atoi(strtok(NULL,"\n"));
482             else if (strcmp(key,"key_up") == 0) option_key[KEY_UP] = (SDLKey)atoi(strtok(NULL,"\n"));
483             else if (strcmp(key,"key_down") == 0) option_key[KEY_DOWN] = (SDLKey)atoi(strtok(NULL,"\n"));
484 
485             else if (strcmp(key,"joy_switch") == 0) option_joy_button[KEY_SWITCH] = (SDLKey)atoi(strtok(NULL,"\n"));
486             else if (strcmp(key,"joy_bump") == 0) option_joy_button[KEY_BUMP] = (SDLKey)atoi(strtok(NULL,"\n"));
487             else if (strcmp(key,"joy_accept") == 0) option_joy_button[KEY_ACCEPT] = (SDLKey)atoi(strtok(NULL,"\n"));
488             else if (strcmp(key,"joy_pause") == 0) option_joy_button[KEY_PAUSE] = (SDLKey)atoi(strtok(NULL,"\n"));
489             else if (strcmp(key,"joy_exit") == 0) option_joy_button[KEY_EXIT] = (SDLKey)atoi(strtok(NULL,"\n"));
490 
491             else if (strcmp(key,"joy_axis_x") == 0) option_joy_axis_x = (SDLKey)atoi(strtok(NULL,"\n"));
492             else if (strcmp(key,"joy_axis_y") == 0) option_joy_axis_y = (SDLKey)atoi(strtok(NULL,"\n"));
493         }
494         fclose(config_file);
495         sysConfigApply();
496     } else {
497         printf ("Error: Couldn't load config file. Creating new config...\n");
498         sysConfigSave();
499     }
500 }
501 
sysConfigSave()502 void sysConfigSave() {
503     mkdir(Dork_StringGetData(&path_dir_config), MKDIR_MODE);
504 
505     FILE *config_file = fopen(Dork_StringGetData(&path_file_config),"w+");
506     if (config_file) {
507         fprintf(config_file,"joystick=%d\n",option_joystick);
508         fprintf(config_file,"sound=%d\n",option_sound);
509         fprintf(config_file,"music=%d\n",option_music);
510         fprintf(config_file,"fullscreen=%d\n",option_fullscreen);
511 
512         fprintf(config_file,"\n# keyboard/GCW-Zero bindings\n");
513         fprintf(config_file,"key_switch=%d\n",(int)option_key[KEY_SWITCH]);
514         fprintf(config_file,"key_bump=%d\n",(int)option_key[KEY_BUMP]);
515         fprintf(config_file,"key_accept=%d\n",(int)option_key[KEY_ACCEPT]);
516         fprintf(config_file,"key_pause=%d\n",(int)option_key[KEY_PAUSE]);
517         fprintf(config_file,"key_exit=%d\n",(int)option_key[KEY_EXIT]);
518         fprintf(config_file,"key_left=%d\n",(int)option_key[KEY_LEFT]);
519         fprintf(config_file,"key_right=%d\n",(int)option_key[KEY_RIGHT]);
520         fprintf(config_file,"key_up=%d\n",(int)option_key[KEY_UP]);
521         fprintf(config_file,"key_down=%d\n",(int)option_key[KEY_DOWN]);
522 
523         fprintf(config_file,"\n# joystick bindings\n");
524         fprintf(config_file,"joy_switch=%d\n",(int)option_joy_button[KEY_SWITCH]);
525         fprintf(config_file,"joy_bump=%d\n",(int)option_joy_button[KEY_BUMP]);
526         fprintf(config_file,"joy_accept=%d\n",(int)option_joy_button[KEY_ACCEPT]);
527         fprintf(config_file,"joy_pause=%d\n",(int)option_joy_button[KEY_PAUSE]);
528         fprintf(config_file,"joy_exit=%d\n",(int)option_joy_button[KEY_EXIT]);
529         fprintf(config_file,"joy_axis_x=%d\n",option_joy_axis_x);
530         fprintf(config_file,"joy_axis_y=%d\n",option_joy_axis_y);
531 
532         fclose(config_file);
533     } else printf("Error: Couldn't write to config file.\n");
534 
535     sysConfigApply();
536 }
537 
sysConfigApply()538 void sysConfigApply() {
539     if (joy) SDL_JoystickClose(joy);
540     if (SDL_NumJoysticks() > 0 && option_joystick > -1) joy = SDL_JoystickOpen(option_joystick);
541     else {
542         option_joystick = -1;
543         joy = NULL;
544     }
545 
546     Mix_Volume(-1,option_sound*16);
547     Mix_VolumeMusic(option_music*16);
548 
549     if (option_fullscreen == 1) {
550         screen = SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,SDL_FLAGS|SDL_FULLSCREEN);
551     }
552     if (!screen || option_fullscreen != 1) {
553         screen = SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,SDL_FLAGS);
554     }
555 }
556 
sysHighScoresLoad()557 void sysHighScoresLoad() {
558     FILE *file = NULL;
559     char buffer[BUFSIZ];
560     char *temp;
561     int i = 0;
562 
563     mkdir(Dork_StringGetData(&path_dir_config), MKDIR_MODE);
564 
565     if (game_mode == GAME_MODE_JEWELS)
566         file = fopen(Dork_StringGetData(&path_file_highscores_jewels),"r+");
567     else
568         file = fopen(Dork_StringGetData(&path_file_highscores),"r+");
569 
570     if (file) {
571         while (fgets(buffer,BUFSIZ,file)) {
572             temp = buffer;
573             if (i < 10) high_scores[i] = atoi(strtok(temp,"\n"));
574             else break;
575             i++;
576         }
577         fclose(file);
578     } else {
579         printf ("Error: Couldn't load high scores.\n");
580         for (int j=0; j<10; j++) {
581             high_scores[j] = 0;
582         }
583         sysHighScoresSave();
584     }
585 }
586 
sysHighScoresSave()587 void sysHighScoresSave() {
588     FILE *file = NULL;
589     int i = 0;
590 
591     mkdir(Dork_StringGetData(&path_dir_config), MKDIR_MODE);
592 
593     if (game_mode == GAME_MODE_JEWELS)
594         file = fopen(Dork_StringGetData(&path_file_highscores_jewels),"w+");
595     else
596         file = fopen(Dork_StringGetData(&path_file_highscores),"w+");
597 
598     if (file) {
599         for (i=0;i<10;i++) {
600             fprintf(file,"%d\n",high_scores[i]);
601         }
602         fclose(file);
603     } else printf("Error: Couldn't save high scores.\n");
604 }
605 
sysHighScoresClear()606 void sysHighScoresClear() {
607     for (int i=0; i<10; i++) {
608         high_scores[i] = 0;
609     }
610 }
611 
612