nSnake
A ncurses implementation of the classic Snake game
 All Data Structures Files Functions Variables Enumerations Macros Pages
hscores.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
2  * nSnake - The classic snake game with ncurses. *
3  * Copyright (C) 2011-2012 Alexandre Dantas (kure) *
4  * *
5  * This file is part of nSnake. *
6  * *
7  * nSnake is free software: you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation, either version 3 of the License, or *
10  * any later version. *
11  * *
12  * This program is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU General Public License *
18  * along with this program. If not, see <http://www.gnu.org/licenses/>. *
19  * *
20  * homepage: http://sourceforge.net/projects/nsnake/ *
21  * *
22 \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
23 
29 // We get one define from the Makefile:
30 // SCORE_FILE -> Filename of the high score file
31 //
32 // They can be changed by the user there, but the defaul is
33 // SCORE_FILE -> high-scores.bin
34 
35 // If we're on Windows, there's no home dir!
36 // So we create the file on the same directory as the .exe
37 #if (defined __WIN32__) && (!defined __CYGWIN__)
38  #undef SCORE_PATH
39  #define SCORE_PATH "hscores.bin"
40 #endif
41 
42 
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <sys/stat.h> /* mkdir(), stat() */
47 #include <sys/types.h> /* mkdir(), stat() */
48 #include <errno.h> /* errno */
49 
50 #include "hscores.h"
51 #include "player.h"
52 
53 
56 
59 
62 
64 char SCORE_DIR[255];
65 
67 char SCORE_PATH[255];
68 
73 {
74  static int initialized = 0;
75 
76  if (initialized)
77  return -1;
78 
79  initialized = 1;
81 
82  memset(SCORE_DIR, '\0', 255);
83  memset(SCORE_PATH, '\0', 255);
84  if (getenv("HOME") == NULL)
85  {
86  strncpy(SCORE_DIR, "/dev", 254);
87  strncpy(SCORE_PATH, "/dev/null", 254);
89  return -1;
90  }
91 
92  strncpy(SCORE_DIR, getenv("HOME"), 254);
93  strncat(SCORE_DIR, "/.nsnake", 254);
94  strncpy(SCORE_PATH, SCORE_DIR, 254);
95  strncat(SCORE_PATH, "/", 1);
96  strncat(SCORE_PATH, SCORE_FILE, 254);
97  return 0;
98 }
99 
104 int directory_exists(char* path)
105 {
106  struct stat s;
107  int err = stat(path, &s);
108  if (err == -1)
109  {
110  if (errno == ENOENT) /* doesn't exist */
111  return 0;
112  }
113 // else
114 // {
115 // if (S_ISDIR(s.st_mode))
116 // // exists and it's a directory
117 // else
118 // // exists but it's not a directory
119 // }
120  return 1;
121 }
122 
127 int create_directory(char* path)
128 {
129  return mkdir(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH);
130 }
131 
135 int file_exists(char* path)
136 {
137  struct stat s;
138  int err = stat(path, &s);
139  if (err == -1)
140  {
141  if (errno == ENOENT) /* doesn't exist */
142  return 0;
143  }
144  else
145  {
146  // exists and it's not a directory
147  if (!(S_ISDIR(s.st_mode)))
148  return 1;
149  }
150  // it's a directory, WHAT
151  return 1;
152 }
153 
157 int create_file(char* path)
158 {
159  FILE* file = fopen(path, "wb");
160  if (!file)
161  return 0;
162 
163  fclose(file);
164  return 1;
165 }
166 
171 {
173  return 0;
174 
175  /* Try to create the directory */
176  int retval = create_directory(SCORE_DIR);
177  if (retval == -1)
178  return 1;
179 
180  /* Try to create the file */
181  retval = create_file(SCORE_PATH);
182  if (retval == 0)
183  return 1;
184 
185  retval = hscore_clean();
186  if (retval == -1)
187  {
189  return 0;
190  }
191 
192  /* And now, after creating them both... */
194  return 0;
195 
196  return 1;
197 }
198 
204 {
206 
207  /* Set highscores to default only if it's not already
208  * set. This way, scores are not reset between turns
209  * when the highscore file isn't available. */
210  if (HIGH_SCORE_BORDERS == 0)
212 
213  if (HIGH_SCORE_BORDERS_OFF == 0)
215 
216  FILE* file = fopen(SCORE_PATH, "wb");
217  if (!file)
218  return -1;
219 
220  fwrite (&HIGH_SCORE_BORDERS, sizeof (int), 1, file);
221  fwrite (&HIGH_SCORE_BORDERS_OFF, sizeof (int), 1, file);
222  fclose (file);
223  return 0;
224 }
225 
226 
236 void hscore_init ()
237 {
239 
240  int retval = hscore_file_check();
241  if (retval == 1)
242  {
244  return;
245  }
246 
247  FILE* file = fopen (SCORE_PATH, "rb");
248  if (!file)
249  {
250  retval = hscore_clean();
251  if (retval == -1)
252  {
254  return;
255  }
256 
257  file = fopen (SCORE_PATH, "rb");
258  if (!file) /* This time it really couldnt open the score file */
259  {
261  return;
262  }
263  }
264 
265  /* All right, opened the file! */
266  int items_read = fread(&HIGH_SCORE_BORDERS, sizeof (int), 1, file);
267  if (items_read != 1)
268  nsnake_abort("Highscore File I/O error!\n"
269  "Try cleaning the scores file!");
270 
271  items_read = fread(&HIGH_SCORE_BORDERS_OFF, sizeof (int), 1, file);
272  if (items_read != 1)
273  nsnake_abort("Highscore File I/O error!\n"
274  "Try cleaning the scores file!");
275 
276  fclose(file);
277 }
278 
279 
283 {
285 
286  int retval = hscore_file_check();
287  if (retval == 1)
288  {
289  retval = hscore_clean();
290  if (retval == -1)
291  {
293  return;
294  }
295  }
296 
297  FILE* file = fopen (SCORE_PATH, "r+b");
298  if (!file)// We really couldn't open the high scores file
299  {
301  return;
302  }
303 
304  if (game.mode == BORDERS_ON)
305  {
307  fwrite (&HIGH_SCORE_BORDERS, sizeof (int), 1, file);
308  }
309 
310  else if (game.mode == BORDERS_OFF)
311  {
313  fseek (file, sizeof (int), SEEK_SET);
314  fwrite (&HIGH_SCORE_BORDERS_OFF, sizeof (int), 1, file);
315  }
316  else
317  {
318  // oh my god, what should i do?
319  }
320 
321  fclose (file);
322 }
323