zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
main.cpp
Go to the documentation of this file.
1 /* This file is part of the Zenipex Library (zenilib).
2  * Copyright (C) 2011 Mitchell Keith Bloch (bazald).
3  *
4  * zenilib is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * zenilib is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with zenilib. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include <zeni_rest.h>
19 
20 #include <cassert>
21 #include <ctime>
22 #include <fstream>
23 #include <iostream>
24 
25 #ifdef _WINDOWS
26 #include <direct.h>
27 #else
28 #include <errno.h>
29 #include <unistd.h>
30 #endif
31 
32 #ifdef _MACOSX
33 #include <mach-o/dyld.h>
34 #endif
35 
36 #if defined(_DEBUG) && defined(_WINDOWS)
37 #define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
38 #define new DEBUG_NEW
39 #endif
40 
41 static bool load_config() {
42  Zeni::XML_Document config_xml("config/zenilib.xml");
43  bool user_config = true;
44 
45  {
46  Zeni::File_Ops::preinit(config_xml["Zenilib"]["Uniqname"].to_string());
47  Zeni::File_Ops &fo = Zeni::get_File_Ops(); // Partially to set up IO redirection
48 
49  if(config_xml.try_load(fo.get_appdata_path() + "config/zenilib.xml"))
50  std::cerr << "User-specific config file loaded from '"
51  << fo.get_appdata_path().std_str() + "config/zenilib.xml"
52  << "'." << std::endl;
53  else {
54  std::cerr << "User-specific config file not found." << std::endl;
55  user_config = false;
56  }
57  }
58 
59  Zeni::XML_Element_c zenilib = config_xml["Zenilib"];
60 
61  struct
62 #ifndef _MSC_VER
63  __attribute__ ((visibility("hidden")))
64 #endif
65  {
66  struct {
67  int anisotropy;
68  bool bilinear_filtering;
69  bool mipmapping;
70  } textures;
71 
72  struct {
74  bool full_screen;
75  int multisampling;
76  Zeni::Point2i screen_resolution;
77  bool vertical_sync;
78  } video;
79  } config;
80 
81  {
82  Zeni::XML_Element_c textures = zenilib["Textures"];
83 
84  config.textures.anisotropy = textures["Anisotropy"].to_int();
85  if(config.textures.anisotropy < 0)
86  config.textures.anisotropy = 16;
87 
88  config.textures.bilinear_filtering = textures["Bilinear_Filtering"].to_bool();
89 
90  config.textures.mipmapping = textures["Mipmapping"].to_bool();
91  }
92 
93  {
94  Zeni::XML_Element_c video = zenilib["Video"];
95 
96  const Zeni::String api = video["API"].to_string();
97 #ifndef DISABLE_GL_FIXED
98  if(api == "OpenGL Fixed" || api == "OpenGL")
100  else
101 #endif
102 #ifndef DISABLE_GL_SHADER
103  if(api == "OpenGL Shader")
105  else
106 #endif
107 #ifndef DISABLE_DX9
108  if(api == "Direct3D 9" || api == "DX9")
110  else
111 #endif
112  {
114 
115 #ifndef ANDROID
116  if(api == "Disabled")
118 #endif
119  }
120 
121  config.video.full_screen = video["Full_Screen"].to_bool();
122 
123  config.video.multisampling = video["Multisampling"].to_int();
124  if(config.video.multisampling < 0)
125  config.video.multisampling = 16;
126 
127  {
128  Zeni::XML_Element_c screen_resolution = video["Resolution"];
129 
130  config.video.screen_resolution.x = screen_resolution["Width"].to_int();
131  config.video.screen_resolution.y = screen_resolution["Height"].to_int();
132  }
133 
134  config.video.vertical_sync = video["Vertical_Sync"].to_bool();
135  }
136 
137  // Start engines
138 #ifndef ANDROID
139  Zeni::Window::preinit_resolution(config.video.screen_resolution);
140  Zeni::Window::preinit_full_screen(config.video.full_screen);
143 #endif
144  Zeni::Video::preinit_multisampling(config.video.multisampling);
145  Zeni::Video::preinit_vertical_sync(config.video.vertical_sync);
146 
147  Zeni::Textures::set_texturing_mode(config.textures.anisotropy,
148  config.textures.bilinear_filtering,
149  config.textures.mipmapping);
150 
151  return user_config;
152 }
153 
154 /*** main ***/
155 
156 #include <SDL/SDL_net.h>
157 
158 static void print_errors() {
159 #ifndef ANDROID
160  std::cerr << "Printing all possible error strings:" << std::endl;
161 
162  std::cerr << "SDL : " << (strlen(SDL_GetError() ) ? SDL_GetError() : "no error") << std::endl;
163  std::cerr << "SDL_net : " << (strlen(SDLNet_GetError()) ? SDLNet_GetError() : "no error") << std::endl;
164 
166 
167 #ifndef DISABLE_AL
168  std::cerr << "OpenAL : " << Zeni::Sound_Renderer_AL::errorString() << std::endl;
169 #endif
170 #endif
171 }
172 
173 inline int main2(const int argc, const char * const * const argv) {
174  std::srand(static_cast<unsigned int>(std::time(0)));
175 
176  Zeni::g_argc = argc;
177  Zeni::g_argv = argv;
178 
179  try {
180  // Load config
181  const bool user_config = load_config();
182 
183  // Initialize Game
184  Zeni::Game &gr = Zeni::get_Game();
185 
186  try {
187  // Initialize Gamestate Zero
188  if(Zeni::g_gzi)
189  gr.push_state((*Zeni::g_gzi)());
190 
191 #ifndef ANDROID
192  // Check Rendering Options on Firstrun
194  if(!user_config)
196  else
197  Zeni::get_Video();
198  }
199 #endif
200 
201  // Run Game
202  gr.run();
203  }
204  catch(Zeni::Quit_Event &) {
205  print_errors();
206 
208  //Zeni::Net::completely_destroy();
223 
224  std::cerr << "Exiting normally." << std::endl;
225  }
226  }
227 #ifdef _WINDOWS
228 #pragma warning( push )
229 #pragma warning( disable : 4130 )
230 #endif
231  catch(Zeni::Error &error) {
232  std::cerr << error.msg << std::endl;
233 
234  print_errors();
235 
236  Zeni::message_box(error.msg);
237 
238  return 1;
239  }
240  catch(std::exception &except) {
241  std::cerr << except.what() << std::endl;
242 
243  print_errors();
244 
245 #ifdef __clang__
246  if(strcmp(except.what(), "std::exception"))
247 #endif
248  Zeni::message_box(except.what());
249 
250  return 1;
251  }
252  catch(...) {
253  std::cerr << "Unknown Error (Neither Zeni::Error nor std::exception)";
254 
255  print_errors();
256 
257  Zeni::message_box("Unknown Error caught in main");
258 
259  throw;
260  }
261 #ifdef _WINDOWS
262 #pragma warning( pop )
263 #endif
264 
265  return 0;
266 }
267 
268 // Go up one directory (or strip a file off the end of a directory)
269 #ifndef _WINDOWS
270 static void up_one_dir(char path[], int &length) {
271  for(path[length] = '\0'; length; --length)
272  if(path[length] == '/') {
273  path[length + 1] = '\0';
274  break;
275  }
276 }
277 #endif
278 
279 ZENI_REST_DLL int zenilib_main(int argc, char **argv) {
280 #ifdef _WINDOWS
281  _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
282 
283  if(_chdir("..\\..\\assets")) {
284  std::cerr << "Setting working directory failed with error code ':" << GetLastError() << "'\n";
285  return -1;
286  }
287 #ifdef X64
288  if(!SetDllDirectory("bin\\x64")) {
289 #else
290  if(!SetDllDirectory("bin\\x32")) {
291 #endif
292  std::cerr << "Setting DLL directory failed with error code ':" << GetLastError() << "'\n";
293  return -2;
294  }
295 #else
296  {
297  char application_path[FILENAME_MAX];
298 #ifndef _MACOSX
299  int length = readlink("/proc/self/exe", application_path, FILENAME_MAX);
300  up_one_dir(application_path, length);
301 #else
302  uint32_t size = sizeof(application_path);
303  if(_NSGetExecutablePath(application_path, &size)) {
304  std::cerr << "Loading working directory failed.\n";
305  return -1;
306  }
307  int length = int(strlen(application_path));
308 
309  for(int i = 0; i != 2; ++i)
310  up_one_dir(application_path, length);
311 #endif
312  memcpy(application_path + length, "/assets", 8);
313  if(chdir(application_path)) {
314  std::cerr << "chdir: " << application_path << '\n';
315  std::cerr << "Setting working directory failed with error code: '" << errno << "'\n";
316  std::cerr << strerror(errno) << '\n';
317  return -1;
318  }
319  }
320 #endif
321 
322  return main2(argc, argv);
323 }
String to_string() const
Get the contained string.
Definition: XML.cpp:99
static void preinit_show_frame(const bool &show_frame_=true)
Show a frame around the rendering window when in windowed mode.
Definition: Window.cpp:409
static const bool & is_enabled()
Determine whether the use of rendering is desired.
Definition: Window.hxx:25
bool try_load(const String &filename)
Definition: XML.cpp:314
VIDEO_MODE
Definition: Video.h:96
void run()
Definition: Game.cpp:325
DECLSPEC const char *SDLCALL SDL_GetError(void)
Definition: SDL_error.c:204
static void preinit_full_screen(const bool &full_screen=false)
Set the rendering window to be full screen at launch.
Definition: Window.cpp:405
GLsizei const GLchar *const * path
Definition: glew.h:5828
Game & get_Game()
Get access to the singleton.
Definition: Game.cpp:58
The Gamestate Stack.
Definition: Game.h:71
static void completely_destroy()
bool to_bool() const
Get the contained string as a boolean.
Definition: XML.cpp:83
static void preinit_resolution(const Point2i &resolution=Point2i(800, 600))
Set the rendering window to have a given resolution.
Definition: Window.cpp:401
static void preinit_multisampling(const int &multisampling=0)
Set a multisampling value.
Definition: Video.cpp:328
static void set_enabled(const bool &enabled)
Enable/Disable the use of rendering; This will not close the rendering window once it is open...
Definition: Window.cpp:396
int
Definition: SDL_systhread.c:37
GLsizei GLsizei * length
Definition: gl2ext.h:792
int g_argc
Definition: Game.cpp:32
FT_Error error
Definition: cffdrivr.c:407
void push_state(const Gamestate &state)
Push a new Gamestate onto the stack.
Definition: Game.cpp:76
static bool load_config()
Definition: main.cpp:41
A class to open an XML file and manage the root node.
Definition: XML.h:111
Gamestate_Zero_Initializer * g_gzi
Definition: Game.cpp:31
void message_box(const char *const &msg)
Definition: Error.h:60
static void preinit_vertical_sync(const bool &vertical_sync=false)
Set vertical_sync to true.
Definition: Video.cpp:332
A class to signal that the program is quitting.
Definition: Quit_Event.h:37
static void preinit(const String &unique_app_identifier)
Definition: File_Ops.cpp:276
const char *const * g_argv
Definition: Game.cpp:33
String get_appdata_path()
Get the path that should be used for user-modifiable storage.
Definition: File_Ops.cpp:223
unsigned int uint32_t
static void up_one_dir(char path[], int &length)
Definition: main.cpp:270
#define memcpy
Definition: SDL_malloc.c:634
GLsizei const GLuint * textures
Definition: glew.h:4751
EGLConfig config
Definition: eglext.h:257
static void set_texturing_mode(const int &anisotropic_filtering_, const bool &bilinear_filtering_, const bool &mipmapping_)
Check to see if Textures is set to use lazy loading if possible.
Definition: Textures.cpp:104
std::string std_str() const
Definition: String.h:428
int main2(const int argc, const char *const *const argv)
Definition: main.cpp:173
int to_int() const
Get the contained string as an integer.
Definition: XML.cpp:87
static void print_errors()
Definition: main.cpp:158
int zenilib_main(int argc, char **argv)
Definition: main.cpp:279
Video & get_Video()
Get access to the singleton.
Definition: Video.cpp:149
static void preinit_video_mode(const VIDEO_MODE &vm=ZENI_VIDEO_ANY)
Set which rendering engine to use.
Definition: Video.cpp:324
The Error Class.
Definition: Error.h:52
int i
Definition: pngrutil.c:1377
String msg
Definition: Error.h:57
File_Ops & get_File_Ops()
Get access to the singleton.
Definition: File_Ops.cpp:118
DECLSPEC const char *SDLCALL SDLNet_GetError(void)
Definition: SDLnet.c:76
static void print_errors()
Print any errors that may have occurred.
Definition: Video.cpp:529
GLsizei size
Definition: gl2ext.h:1467
A 2D Point represented with integers.
Definition: Coordinate.h:85