1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (C) 2004-2011 by The Allacrost Project
3 // Copyright (C) 2012-2017 by Bertram (Valyria Tear)
4 // All Rights Reserved
5 //
6 // This code is licensed under the GNU GPL version 2. It is free software
7 // and you may modify it and/or redistribute it under the terms of this license.
8 // See https://www.gnu.org/copyleft/gpl.html for details.
9 ///////////////////////////////////////////////////////////////////////////////
10
11 /** ***************************************************************************
12 *** \file main_options.cpp
13 *** \author Tyler Olsen, roots@allacrost.org
14 *** \author Yohann Ferreira, yohann ferreira orange fr
15 *** \brief Implementations for functions that handle command-line arguments.
16 *** **************************************************************************/
17
18 #include "main_options.h"
19
20 #include "engine/audio/audio.h"
21 #include "engine/video/video.h"
22 #include "script/script_write.h"
23 #include "engine/input.h"
24 #include "engine/system.h"
25 #include "engine/mode_manager.h"
26
27 #include "utils/utils_files.h"
28
29 #include "common/app_name.h"
30 #include "common/app_settings.h"
31 #include "common/global/global.h"
32
33 #include <SDL2/SDL_ttf.h>
34
35 namespace vt_battle {
36 extern bool BATTLE_DEBUG;
37 }
38 namespace vt_boot {
39 extern bool BOOT_DEBUG;
40 }
41 namespace vt_common {
42 extern bool COMMON_DEBUG;
43 }
44 namespace vt_menu {
45 extern bool MENU_DEBUG;
46 }
47 namespace vt_pause {
48 extern bool PAUSE_DEBUG;
49 }
50 namespace vt_shop {
51 extern bool SHOP_DEBUG;
52 }
53
54 using namespace vt_utils;
55 using namespace vt_common;
56
57 namespace vt_main
58 {
59
ParseProgramOptions(int32_t & return_code,int32_t argc,char * argv[])60 bool ParseProgramOptions(int32_t &return_code, int32_t argc, char* argv[])
61 {
62 // Convert the argument list to a vector of strings for convenience
63 std::vector<std::string> options(argv, argv + argc);
64 return_code = 0;
65
66 for(uint32_t i = 1; i < options.size(); i++) {
67 if(options[i] == "-d" || options[i] == "--debug") {
68 if((i + 1) >= options.size()) {
69 std::cerr << "Option " << options[i] << " requires an argument." << std::endl;
70 PrintUsage();
71 return_code = 1;
72 return false;
73 }
74 if(EnableDebugging(options[i + 1]) == false) {
75 return_code = 1;
76 return false;
77 }
78 i++;
79 } else if(options[i] == "--disable-audio") {
80 vt_audio::AUDIO_ENABLE = false;
81 } else if(options[i] == "-h" || options[i] == "--help") {
82 PrintUsage();
83 return_code = 0;
84 return false;
85 } else if(options[i] == "-i" || options[i] == "--info") {
86 if(PrintSystemInformation()) {
87 return_code = 0;
88 } else {
89 return_code = 1;
90 }
91 return false;
92 } else if(options[i] == "-r" || options[i] == "--reset") {
93 if(ResetSettings()) {
94 return_code = 0;
95 } else {
96 return_code = 1;
97 }
98 return_code = 0;
99 return false;
100 } else {
101 std::cerr << "Unrecognized option: " << options[i] << std::endl;
102 PrintUsage();
103 return_code = 1;
104 return false;
105 }
106 }
107
108 return true;
109 } // bool ParseProgramOptions(int32_t &return_code, int32_t argc, char *argv[])
110
ParseSecondaryOptions(const std::string & vars,std::vector<std::string> & options)111 bool ParseSecondaryOptions(const std::string &vars, std::vector<std::string>& options)
112 {
113 uint32_t sbegin = 0;
114
115 if(vars.empty()) {
116 std::cerr << "ERROR: debug specifier string is empty" << std::endl;
117 return false;
118 }
119
120 // Find the first non-whitespace character
121 // TODO: this loop needs to be made more robust to errors
122 while(vars[sbegin] == ' ' || vars[sbegin] == '\t') {
123 sbegin++;
124 if(sbegin >= vars.size()) {
125 std::cerr << "ERROR: no white-space characters in debug specifier string" << std::endl;
126 return false;
127 }
128 }
129
130 // Parse the vars string on white-space characters and fill the args vector
131 // TODO: this loop needs to be made more robust to errors
132 for(uint32_t i = sbegin; i < vars.size(); i++) {
133 if(vars[i] == ' ' || vars[i] == '\t') {
134 options.push_back(vars.substr(sbegin, i - sbegin));
135 sbegin = i + 1;
136 }
137 }
138 options.push_back(vars.substr(sbegin, vars.size() - sbegin));
139 return true;
140 } // bool ParseSecondaryOptions(string vars, vector<string>& options);
141
142
143 // Prints out the usage options (arguments) for running the program (work in progress)
PrintUsage()144 void PrintUsage()
145 {
146 std::cout
147 << "usage: " APPSHORTNAME " [options]" << std::endl
148 << " --debug/-d <args> :: enables debug statements in specified sections of the" << std::endl
149 << " program, where <args> can be:" << std::endl
150 << " all, audio, battle, boot, data, global, input," << std::endl
151 << " map, mode_manager, pause, quit, scene, system" << std::endl
152 << " utils, video" << std::endl
153 << " --disable-audio :: disables loading and playing audio" << std::endl
154 << " --help/-h :: prints this help menu" << std::endl
155 << " --info/-i :: prints information about the user's system" << std::endl
156 << " --reset/-r :: resets game configuration to use default settings" << std::endl;
157 }
158
PrintSystemInformation()159 bool PrintSystemInformation()
160 {
161 printf("\n===== System Information\n");
162
163 // Initialize SDL and its subsystems and make sure it shutdowns properly on exit
164 if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) != 0) {
165 std::cerr << "ERROR: Unable to initialize SDL: " << SDL_GetError() << std::endl;
166 return false;
167 }
168 atexit(SDL_Quit);
169
170 SDL_version sdl_linked_ver;
171 SDL_GetVersion(&sdl_linked_ver);
172
173 std::cout
174 << "SDL version (compiled): "
175 << SDL_MAJOR_VERSION << '.' << SDL_MINOR_VERSION << '.' << SDL_PATCHLEVEL
176 << std::endl;
177 std::cout
178 << "SDL version (linked): "
179 << sdl_linked_ver.major << '.'
180 << sdl_linked_ver.minor << '.'
181 << sdl_linked_ver.patch
182 << std::endl;
183
184 int32_t js_num = SDL_NumJoysticks();
185 printf("Number of joysticks found: %d\n", js_num);
186
187 // Print out information about each joystick
188 for(int32_t i = 0; i < js_num; i++) {
189 printf(" Joystick #%d\n", i);
190 //printf(" Joystick Name: %s\n", SDL_GameControllerNameForIndex(i));
191 SDL_Joystick* js_test = SDL_JoystickOpen(i);
192 if(js_test == nullptr)
193 printf(" ERROR: SDL was unable to open joystick #%d!\n", i);
194 else {
195 printf(" Number Axes: %d\n", SDL_JoystickNumAxes(js_test));
196 printf(" Number Buttons: %d\n", SDL_JoystickNumButtons(js_test));
197 printf(" Number Trackballs: %d\n", SDL_JoystickNumBalls(js_test));
198 printf(" Number Hat Switches: %d\n", SDL_JoystickNumHats(js_test));
199 SDL_JoystickClose(js_test);
200 }
201 }
202
203 printf("\n===== Video Information\n");
204
205 // TODO: This code should be re-located to a function (DEBUG_PrintInfo()) in the video engine
206 // vt_video::VideoManager = vt_video::VideoEngine::SingletonCreate();
207 // if (vt_video::VideoManager->SingletonInitialize() == false) {
208 // cerr << "ERROR: unable to initialize the VideoManager" << std::endl;
209 // return false;
210 // }
211 // else {
212 // vt_video::VideoManager->DEBUG_PrintInfo();
213 // }
214 // vt_video::VideoEngine::SingletonDestroy();
215
216 // TODO: print the OpenGL version number here
217
218 printf("SDL_ttf version (compiled): %d.%d.%d\n",
219 SDL_TTF_MAJOR_VERSION, SDL_TTF_MINOR_VERSION, SDL_TTF_PATCHLEVEL);
220 /*
221 char video_driver[80];
222 SDL_VideoDriverName(video_driver, 80);
223 printf("Name of video driver: %s\n", video_driver);
224
225 const SDL_VideoInfo *user_video;
226 user_video = SDL_GetVideoInfo(); // Get information about the user's video system
227 std::cout << " Best available video mode" << std::endl
228 << " Creates hardware surfaces: ";
229 if(user_video->hw_available == 1)
230 std::cout << "yes\n";
231 else
232 std::cout << "no\n";
233 std::cout << " Has window manager available: ";
234 if(user_video->wm_available == 1)
235 std::cout << "yes\n";
236 else
237 std::cout << "no\n";
238 std::cout << " Hardware to hardware blits accelerated: ";
239 if(user_video->blit_hw == 1)
240 std::cout << "yes\n";
241 else
242 std::cout << "no\n";
243 std::cout << " Hardware to hardware colorkey blits accelerated: ";
244 if(user_video->blit_hw_CC == 1)
245 std::cout << "yes\n";
246 else
247 std::cout << "no\n";
248 std::cout << " Hardware to hardware alpha blits accelerated: ";
249 if(user_video->blit_hw_A == 1)
250 std::cout << "yes\n";
251 else
252 std::cout << "no\n";
253 std::cout << " Software to hardware blits acceleerated: ";
254 if(user_video->blit_sw == 1)
255 std::cout << "yes\n";
256 else
257 std::cout << "no\n";
258 std::cout << " Software to hardware colorkey blits accelerated: ";
259 if(user_video->blit_sw_CC == 1)
260 std::cout << "yes\n";
261 else
262 std::cout << "no\n";
263 std::cout << " Software to hardware alpha blits accelerated: ";
264 if(user_video->blit_sw_A == 1)
265 std::cout << "yes\n";
266 else
267 std::cout << "no\n";
268 std::cout << " Color fills accelerated: ";
269 if(user_video->blit_fill == 1)
270 std::cout << "yes\n";
271 else
272 std::cout << "no\n";
273 std::cout << " Total video memory: " << user_video->video_mem << " kilobytes" << std::endl;
274 // std::cout << " Best pixel format: " << user_video->vfmt << std::endl;
275 */
276 printf("\n===== Audio Information\n");
277
278 vt_audio::AudioManager = vt_audio::AudioEngine::SingletonCreate();
279 if(vt_audio::AudioManager->SingletonInitialize() == false) {
280 std::cerr << "ERROR: unable to initialize the AudioManager" << std::endl;
281 return false;
282 }
283 vt_audio::AudioManager->DEBUG_PrintInfo();
284 vt_audio::AudioEngine::SingletonDestroy();
285
286 std::cout << std::endl;
287
288 return true;
289 } // bool PrintSystemInformation()
290
ResetSettings()291 bool ResetSettings()
292 {
293 std::string file = GetUserConfigPath() + "settings.lua";
294
295 // Copy the default file to the user location.
296 vt_utils::CopyAFile(std::string("data/config/settings.lua"), file);
297 std::cout << "Copied default settings.lua file to: " << file << std::endl;
298
299 return false;
300 } // bool ResetSettings()
301
EnableDebugging(const std::string & vars)302 bool EnableDebugging(const std::string &vars)
303 {
304 // A vector of all the debug arguments
305 std::vector<std::string> args;
306 ParseSecondaryOptions(vars, args);
307
308 // Enable all specified debug variables
309 for(uint32_t i = 0; i < args.size(); i++) {
310 if(args[i] == "all") {
311 // This causes every call to SDL_SetError to also print an error message on stderr.
312 // NOTE: commented out because apparently SDL_putenv is not yet an available function on some systems
313 // SDL_putenv("SDL_DEBUG=1");
314
315 vt_audio::AUDIO_DEBUG = true;
316 vt_battle::BATTLE_DEBUG = true;
317 vt_boot::BOOT_DEBUG = true;
318 vt_common::COMMON_DEBUG = true;
319 vt_script::SCRIPT_DEBUG = true;
320 vt_mode_manager::MODE_MANAGER_DEBUG = true;
321 vt_input::INPUT_DEBUG = true;
322 vt_system::SYSTEM_DEBUG = true;
323 vt_global::GLOBAL_DEBUG = true;
324 vt_map::MAP_DEBUG = true;
325 vt_menu::MENU_DEBUG = true;
326 vt_pause::PAUSE_DEBUG = true;
327 vt_shop::SHOP_DEBUG = true;
328 vt_video::VIDEO_DEBUG = true;
329 } else if(args[i] == "audio") {
330 vt_audio::AUDIO_DEBUG = true;
331 } else if(args[i] == "battle") {
332 vt_battle::BATTLE_DEBUG = true;
333 } else if(args[i] == "boot") {
334 vt_boot::BOOT_DEBUG = true;
335 } else if(args[i] == "common") {
336 vt_common::COMMON_DEBUG = true;
337 } else if(args[i] == "data") {
338 vt_script::SCRIPT_DEBUG = true;
339 } else if(args[i] == "mode_manager") {
340 vt_mode_manager::MODE_MANAGER_DEBUG = true;
341 } else if(args[i] == "input") {
342 vt_input::INPUT_DEBUG = true;
343 } else if(args[i] == "system") {
344 vt_system::SYSTEM_DEBUG = true;
345 } else if(args[i] == "global") {
346 vt_global::GLOBAL_DEBUG = true;
347 } else if(args[i] == "map") {
348 vt_map::MAP_DEBUG = true;
349 } else if(args[i] == "menu") {
350 vt_menu::MENU_DEBUG = true;
351 } else if(args[i] == "pause") {
352 vt_pause::PAUSE_DEBUG = true;
353 } else if(args[i] == "shop") {
354 vt_shop::SHOP_DEBUG = true;
355 } else if(args[i] == "video") {
356 vt_video::VIDEO_DEBUG = true;
357 } else {
358 std::cerr << "ERROR: invalid debug argument: " << args[i] << std::endl;
359 return false;
360 }
361 } // for (uint32_t i = 0; i < args.size(); i++)
362
363 return true;
364 } // bool EnableDebugging(string vars)
365
366 } // namespace vt_main
367