Adonthell  0.4
main.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 1999/2000/2001/2002/2003/2004 Kai Sterker
3  Part of the Adonthell Project <http://adonthell.nongnu.org>
4 
5  Adonthell 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 2 of the License, or
8  (at your option) any later version.
9 
10  Adonthell 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 Adonthell. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 
20 /**
21  * @file main.cc
22  * @author Kai Sterker <kai.sterker@gmail.com>
23  *
24  * @brief Contains the main() function.
25  *
26  *
27  */
28 
29 #include "achievements.h"
30 #include "audio.h"
31 #include "event_handler.h"
32 #include "game.h"
33 #include "gamedata.h"
34 #include "gametime.h"
35 #include "input.h"
36 #include "nls.h"
37 #include "python_class.h"
38 #include "screen.h"
39 #include "yarg.h"
40 #include "win_manager.h"
41 
42 #ifdef MEMORY_LEAKS
43 #include <mcheck.h>
44 #endif
45 
46 using namespace std;
47 
48 /*
49  * SWIG init prototypes. Should we use dynamic linking???
50  */
51 extern "C"
52 {
53  /**
54  * SWIG init prototype.
55  *
56  */
57 #if PY_VERSION_HEX >= 0x03000000
58  PyObject* PyInit__adonthell (void);
59 #else
60  void init_adonthell (void);
61 #endif
62 }
63 
64 static bool init_python(const char *application)
65 {
66 #if PY_VERSION_HEX >= 0x03000000
67  // one would assume that this is properly handled by SWIG,
68  // but it seems some extra effort is required on our side
69  // to use a static module
70  if (PyImport_AppendInittab ("_adonthell", PyInit__adonthell) < 0)
71  {
72  return false;
73  }
74 #if PY_VERSION_HEX >= 0x03050000
75  wchar_t *program = Py_DecodeLocale(application, NULL);
76  if (program != NULL)
77  {
78  Py_SetProgramName(program);
79  }
80 #endif
81 #endif
82 
83  python::init ();
84 
85  // Initialise the import path.
86  // Shared modules path
87  string t;
88  t = game::global_data_dir() + "/modules";
89  python::insert_path ((char *) t.c_str());
90 
91  // Game specific path
92  t = game::game_data_dir () + "/scripts/modules";
93  python::insert_path ((char *) t.c_str ());
94  t = game::game_data_dir () + "/scripts";
95  python::insert_path ((char *) t.c_str ());
96 
97  // Initialise SWIG module. This should go if we ever switch
98  // to dynamic linking
99 #if PY_VERSION_HEX < 0x03000000
100  init_adonthell();
101 #endif
102 
103  python::module = python::import_module ("adonthell");
104  if (!python::module) return false;
105 
106  data::globals = PyModule_GetDict (python::module);
107 
108  return true;
109 }
110 
111 /**
112  * Game's main function.
113  * It simply initialises the game and runs the "init.py" file in the game
114  * directory given as first argument. Once the execution is finished,
115  * it cleans everything up, and exits.
116  *
117  * @param argc Number of arguments to the program.
118  * @param argv Array of strings containing the program's arguments.
119  *
120  * @return 0 in case of success, error code otherwise.
121  *
122  */
123 extern "C"
124 int main(int argc, char * argv[])
125 {
126  config myconfig;
127 
128 #ifdef MEMORY_LEAKS
129  // to debug memory leaks with mtrace. It's better to use
130  // a tool like memprof, mpatrol or valgrind though.
131  mtrace ();
132 #endif
133 
134  // init game environment
135 #if !defined (SINGLE_DIR_INST)
136  game::init (DATA_DIR);
137 #else
138  // change working directory to the application's location.
139  if (argc && argv[0])
140  {
141  char *str = argv[0];
142  do if (*str == '\\') *str = '/';
143  while (*(str++));
144 
145  str = strrchr (argv[0], '/');
146  *(str + 1) = 0;
147  chdir (argv[0]);
148 
149  *(str + 1) = '/';
150  }
151 
152  // get absolute path to current working directory
153  char buf[500];
154  getcwd (buf, sizeof (buf));
155 
156  char *str = buf;
157  do if (*str == '\\') *str = '/';
158  while (*(str++));
159 
160  // get absolute path to data directory
161  string data_dir(DATA_DIR);
162  while (data_dir.size() >= 3 && data_dir.compare(0, 3, "../") == 0)
163  {
164  str = strrchr (buf, '/');
165  if (str != NULL)
166  {
167  *(str+1) = 0;
168  }
169  data_dir = data_dir.substr(3);
170  }
171 
172  game::init (string(buf) + data_dir);
173 #endif
174 
175  // read the $HOME/.adonthell/adonthellrc file
176  // and check the arguments we recieved.
177  myconfig.read_adonthellrc ();
178  myconfig.parse_arguments (argc, argv);
179 
180  // init national language support
181  nls::init (myconfig);
182 
184 
185  // init game loading/saving system
187  myconfig.game_name, myconfig.quick_load);
188 
189  // init achievements
191 
192  // init video subsystem
193  if (!screen::init (320, 240, 0, myconfig))
194  {
195  printf("%s\n", screen::info().c_str());
196  SDL_Quit();
197  return 1;
198  }
199 
200 #ifdef DEBUG
201  printf("%s\n", screen::info().c_str());
202 #endif
203 
204  // init audio subsystem
205  if (myconfig.audio_volume > 0)
206  audio::init (&myconfig);
207 
208  // init input subsystem
209  input::init ();
210 
211  // init python interpreter
212  if (!init_python(argv[0]))
213  {
214  std::cout << "Initializing Python module failed" << std::endl;
215  SDL_Quit ();
216  return false;
217  }
218 
219  // init the game data
220  data::engine = new adonthell;
221  data::the_player = NULL;
222 
223  // init window manager
224  win_manager::init (myconfig.font);
225 
226  // event system
228 
229  // gametime system
230  // (180 realtime minutes make approx. 1 gametime day)
231  gametime::init (180);
232 
233  // init random number generator
234  yarg::init (myconfig.game_name);
235  yarg::randomize ();
236 
237  // It's up to the game what happens here
238  python::exec_file ("init");
239 
240  // close all windows
241  // delete all themes and fonts
243 
244  // shutdown input subsystem
245  input::shutdown ();
246 
247  // shutdown audio
248  audio::cleanup ();
249 
250  // cleanup the saves
251  gamedata::cleanup ();
252 
253  // cleanup data
254  delete data::engine;
255  if (data::the_player)
256  delete data::the_player;
257 
258  // cleanup event system
260 
261  // shutdown python
262  python::cleanup ();
263 
264  // shutdown screen
265  screen::cleanup ();
266 
267  // shutdown video and SDL
268  SDL_Quit ();
269 
270  return 0;
271 }
data::globals
PyObject * globals
Global namespace to use in scripts.
Definition: python_class.cc:33
python::exec_file
static bool exec_file(string filename)
Executes a Python script.
Definition: python_class.cc:87
screen::info
static string info()
Returns information about the current screen settings, suitable for being displayed to the user.
Definition: screen.cc:179
nls.h
National Language Support.
gamedata::cleanup
static void cleanup()
Cleanup the saved game array.
Definition: gamedata.cc:612
event_handler.h
Declares the event_handler class.
config::read_adonthellrc
bool read_adonthellrc()
Reads the configuration file.
Definition: prefs.cc:290
screen.h
Declares the screen class.
gametime::init
static void init(u_int16 rt_minutes)
Initialize the gametime class.
Definition: gametime.cc:36
config::game_name
string game_name
Name of the game that is running at present.
Definition: prefs.h:135
game::user_data_dir
static string user_data_dir()
Returns the absolute path to the user data directory (usually ~/.adonthell).
Definition: game.h:80
python_class.h
Defines the python class. This file is named this way so it doesn't conflicts with Python....
gamedata.h
Declares the gamedata and data classes.
gamedata::init
static bool init(string udir, string gdir, string gname, u_int8 qload)
Initialise the saved games array.
Definition: gamedata.cc:544
python::insert_path
static void insert_path(char *name)
Adds a directory to Python's include path.
Definition: python_class.cc:64
event_handler::init
static void init()
Instanciate the actual event handlers.
Definition: event_handler.cc:45
nls::init
static void init(config &myconfig)
Initialize national language support.
Definition: nls.cc:37
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
win_manager.h
Declares the win_manager class.
config::audio_volume
u_int8 audio_volume
The volume: a value betwen 0 and 100.
Definition: prefs.h:168
main
int main(int argc, char *argv[])
Game's main function.
Definition: main.cc:124
win_manager::cleanup
static void cleanup()
Delete all themes and fonts currently loaded.
Definition: win_manager.cc:92
python::cleanup
static void cleanup()
Cleanup Python.
Definition: python_class.cc:52
achievements::init
static void init()
Initialize achievements by loading all available achievements and their permanent unlocked status.
Definition: achievements.cc:166
config
This class contains the engine's configuration read either from the config file or from the command l...
Definition: prefs.h:74
init_adonthell
void init_adonthell(void)
SWIG init prototype.
input::init
static void init()
Initialise the input system.
Definition: input.cc:48
config::gamedir
string gamedir
Path of the directory that contains the game running at present.
Definition: prefs.h:139
python::import_module
static PyObject * import_module(string filename)
Imports a Python module.
Definition: python_class.cc:117
config::parse_arguments
void parse_arguments(int argc, char *argv[])
See whether any options have been specified on the command line.
Definition: prefs.cc:106
input::shutdown
static void shutdown()
Free resources occupied by the input system.
Definition: input.cc:59
game.h
Declares the game class.
event_handler::cleanup
static void cleanup()
Delete the event handlers.
Definition: event_handler.cc:61
game::init
static void init(string game_dir)
Initialise the game framework.
Definition: game.cc:45
config::quick_load
u_int8 quick_load
Whether the quick-load feature is enabled (1) or not (0)
Definition: prefs.h:151
adonthell
This is the heart of the Adonthell engine.
Definition: adonthell.h:44
python::init
static void init()
Initialise Python and insert the Adonthell include paths.
Definition: python_class.cc:44
screen::init
static bool init(u_int16 nl, u_int16 nh, u_int8 depth, const config &myconfig)
Initializes the video subsystem and creates the required resources.
Definition: screen.cc:65
gametime.h
Declares the gametime class.
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
input.h
Declares the input class.
win_manager::init
static void init(const string &font)
Empty for now.
Definition: win_manager.cc:85
achievements.h
Manages in-game achievements.
game::global_data_dir
static string global_data_dir()
Returns the absolute path to the global data directory.
Definition: game.h:91