Adonthell  0.4
game.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 1999/2000/2001/2002 Kai Sterker <kai.sterker@gmail.com>
3  Copyright (C) 2002 Alexandre Courbot <alexandrecourbot@linuxgames.com>
4  Part of the Adonthell Project <http://adonthell.nongnu.org>
5 
6  Adonthell is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  Adonthell is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with Adonthell. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 /**
21  * @file game.cc
22  * @author Kai Sterker <kai.sterker@gmail.com>
23  * @author Alexandre Courbot <alexandrecourbot@linuxgames.com>
24  *
25  * @brief Defines the game class.
26  *
27  *
28  */
29 
30 
31 #include "game.h"
32 #include <iostream>
33 #include <errno.h>
34 #include <stdlib.h>
35 #include <sys/stat.h>
36 #include <sys/types.h>
37 #include <dirent.h>
38 
39 
40 string game::User_data_dir;
41 string game::Global_data_dir;
42 string game::Game_data_dir;
43 
44 
45 void game::init (string game_dir)
46 {
47  Global_data_dir = game_dir;
48 
49  // set OS specific directory containing the saved games
50  User_data_dir = get_system_dir(USER_DATA);
51 }
52 
53 void game::set_game_data_dir(string game_dir)
54 {
55  Game_data_dir = game_dir;
56 }
57 
58 string game::get_system_dir(const sys_dir_type & type)
59 {
60  std::string result;
61 #if defined(__APPLE__)
62  // OSX
63  result = string (getenv ("HOME")) + "/Library/Application Support/Adonthell/";
64 #elif defined (WIN32)
65  // Windows
66  char *appDataDir = getenv ("APPDATA");
67  if (appDataDir != NULL && strlen (appDataDir) > 0)
68  result = string (getenv("APPDATA")) + "/Adonthell/";
69  else
70  result = "./";
71 #else
72  // Unix
73  const char* xdgEnv = type == USER_DATA ? "XDG_DATA_HOME" : "XDG_CONFIG_HOME";
74  char *xdgDir = getenv (xdgEnv);
75  if (xdgDir != NULL && strlen (xdgDir) > 0)
76  result = string (xdgDir) + "/adonthell";
77  else
78  {
79  if (type == USER_DATA)
80  result = string (getenv ("HOME")) + "/.local/share/adonthell/";
81  else
82  result = string (getenv ("HOME")) + "/.config/adonthell/";
83  }
84 #endif
85 
86  // make sure save data directory exists, otherwise create it
87  if (!game::directory_exist (result))
88  {
89 #ifndef WIN32
90  if (mkdir (result.c_str (), 0700) == -1)
91 #else
92  if (mkdir (result.c_str ()) == -1)
93 #endif
94  {
95  int ecd = errno;
96  std::cerr << "Creating directory '" << result << "' failed: "
97  << strerror (ecd) << std::endl;
98  }
99  }
100 
101  return result;
102 }
103 
104 bool game::directory_exist (const string & dirname)
105 {
106  DIR * dir = opendir (dirname.c_str ());
107 
108  if (dir)
109  {
110  closedir (dir);
111  return true;
112  }
113 
114  return false;
115 }
116 
117 bool game::file_exist (const string & fname)
118 {
119  FILE * file = fopen (fname.c_str (), "r");
120 
121  if (file)
122  {
123  fclose (file);
124  return true;
125  }
126 
127  return false;
128 }
129 
130 string game::find_file (const string & fname)
131 {
132  string ret;
133 
134  // If the name is already absolute, no need to search...
135  if (fname[0] == '/') return fname;
136 
137  // First check in the current game directory
138  if ((ret = game_data_dir () + "/") != "/" && file_exist (ret + fname))
139  ret += fname;
140  // Then check the global data directory
141  else if (file_exist ((ret = global_data_dir () + "/") + fname))
142  ret += fname;
143  // Finally, try the user data directory
144  else if (file_exist ((ret = user_data_dir () + "/") + fname))
145  ret += fname;
146  // Nothing found! So bad...
147  else ret = "";
148 
149  return ret;
150 }
151 
152 string game::find_directory (const string & dirname)
153 {
154  string ret;
155 
156  // If the name is already absolute, no need to search...
157  if (dirname[0] == '/') return dirname;
158 
159  // First check in the current game directory
160  if ((ret = game_data_dir () + "/") != "/" && directory_exist (ret + dirname))
161  ret += dirname;
162  // Then check the global data directory
163  else if (directory_exist ((ret = global_data_dir () + "/") + dirname))
164  ret += dirname;
165  // Finally, try the user data directory
166  else if (directory_exist ((ret = user_data_dir () + "/") + dirname))
167  ret += dirname;
168  // Nothing found! So bad...
169  else ret = "";
170 
171  return ret;
172 }
game::user_data_dir
static string user_data_dir()
Returns the absolute path to the user data directory (usually ~/.adonthell).
Definition: game.h:80
game::set_game_data_dir
static void set_game_data_dir(string game_dir)
Specify an additional data directory containing game data.
Definition: game.cc:53
game::find_directory
static string find_directory(const string &dirname)
Finds a directory in the directories hierarchy, starting searching from game_data_dir(),...
Definition: game.cc:152
game.h
Declares the game class.
game::init
static void init(string game_dir)
Initialise the game framework.
Definition: game.cc:45
game::find_file
static string find_file(const string &fname)
Finds a file in the directories hierarchy, starting searching from game_data_dir(),...
Definition: game.cc:130
game::get_system_dir
static string get_system_dir(const sys_dir_type &type)
Return the OS-specific directory of the given type.
Definition: game.cc:58
game::game_data_dir
static string game_data_dir()
Returns the absolute path to the current game's directory (if any).
Definition: game.h:102
game::global_data_dir
static string global_data_dir()
Returns the absolute path to the global data directory.
Definition: game.h:91