e40503b8d8bf8b98a69b4ae112efdbfd5ba28c7e
[supertux.git] / src / supertux / command_line_arguments.cpp
1 //  SuperTux
2 //  Copyright (C) 2014 Ingo Ruhnke <grumbel@gmail.com>
3 //
4 //  This program is free software: you can redistribute it and/or modify
5 //  it under the terms of the GNU 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 //  This program 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 General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17 #include "supertux/command_line_arguments.hpp"
18
19 #include <boost/format.hpp>
20 #include <iostream>
21 #include <physfs.h>
22 #include <stdexcept>
23
24 #include "supertux/gameconfig.hpp"
25 #include "supertux/main.hpp"
26 #include "util/gettext.hpp"
27 #include "version.h"
28
29 CommandLineArguments::CommandLineArguments() :
30   m_action(NO_ACTION),
31   m_log_level(LOG_WARNING),
32   datadir(),
33   userdir(),
34   fullscreen_size(),
35   fullscreen_refresh_rate(),
36   window_size(),
37   aspect_size(),
38   use_fullscreen(),
39   video(),
40   show_fps(),
41   sound_enabled(),
42   music_enabled(),
43   console_enabled(),
44   start_level(),
45   enable_script_debugger(),
46   start_demo(),
47   record_demo(),
48   developer_mode()
49 {
50 }
51
52 CommandLineArguments::~CommandLineArguments()
53 {
54 }
55
56 void
57 CommandLineArguments::print_datadir()
58 {
59   // Print the datadir searchpath to stdout, one path per
60   // line. Then exit. Intended for use by the supertux-editor.
61   char **sp;
62   size_t sp_index;
63   sp = PHYSFS_getSearchPath();
64   if (sp)
65     for (sp_index = 0; sp[sp_index]; sp_index++)
66       std::cout << sp[sp_index] << std::endl;
67   PHYSFS_freeList(sp);
68 }
69
70 void
71 CommandLineArguments::print_help(const char* arg0)
72 {
73   std::cerr
74             << boost::format(_(     "Usage: %s [OPTIONS] [LEVELFILE]")) % arg0 << "\n" << "\n"
75             << _(     "General Options:" ) << "\n"
76             << _(     "  -h, --help                   Show this help message and quit") << "\n"
77             << _(     "  -v, --version                Show SuperTux version and quit") << "\n"
78             << _(     "  --verbose                    Print verbose messages") << "\n"
79             << _(     "  --debug                      Print extra verbose messages") << "\n"
80             << _( "  --print-datadir              Print supertux's primary data directory.") << "\n" << "\n"
81             << _(     "Video Options:") << "\n"
82             << _(     "  -f, --fullscreen             Run in fullscreen mode") << "\n"
83             << _(     "  -w, --window                 Run in window mode") << "\n"
84             << _(     "  -g, --geometry WIDTHxHEIGHT  Run SuperTux in given resolution") << "\n"
85             << _(     "  -a, --aspect WIDTH:HEIGHT    Run SuperTux with given aspect ratio") << "\n"
86             << _(     "  -d, --default                Reset video settings to default values") << "\n"
87             << _(     "  --renderer RENDERER          Use sdl, opengl, or auto to render") << "\n" << "\n"
88             << _(     "Audio Options:") << "\n"
89             << _(     "  --disable-sound              Disable sound effects") << "\n"
90             << _(     "  --disable-music              Disable music") << "\n" << "\n"
91             << _(     "Game Options:") << "\n"
92             << _(     "  --console                    Enable ingame scripting console") << "\n"
93             << _(     "  --noconsole                  Disable ingame scripting console") << "\n"
94             << _(     "  --show-fps                   Display framerate in levels") << "\n"
95             << _(     "  --no-show-fps                Do not display framerate in levels") << "\n"
96             << _(     "  --developer                  Switch on developer feature") << "\n"
97             << _(     "  -s, --debug-scripts          Enable script debugger.") << "\n" << "\n"
98             << _(     "Demo Recording Options:") << "\n"
99             << _(     "  --record-demo FILE LEVEL     Record a demo to FILE") << "\n"
100             << _(     "  --play-demo FILE LEVEL       Play a recorded demo") << "\n" << "\n"
101             << _(     "Directory Options:") << "\n"
102             << _(     "  --datadir DIR                Set the directory for the games datafiles") << "\n"
103             << _(     "  --userdir DIR                Set the directory for user data (savegames, etc.)") << "\n" << "\n"
104             << _(     "Environment variables:") << "\n"
105             << _(     "  SUPERTUX2_USER_DIR           Directory for user data (savegames, etc.)" ) << "\n"
106             << _(     "  SUPERTUX2_DATA_DIR           Directory for the games datafiles" ) << "\n"<< "\n"
107     
108                  
109     
110             << std::flush;
111 }
112
113 void
114 CommandLineArguments::print_version()
115 {
116   std::cout << PACKAGE_NAME << " " << PACKAGE_VERSION << std::endl;
117 }
118
119 void
120 CommandLineArguments::parse_args(int argc, char** argv)
121 {
122   for(int i = 1; i < argc; ++i)
123   {
124     std::string arg = argv[i];
125
126     if (arg == "--version" || arg == "-v")
127     {
128       m_action = PRINT_VERSION;
129
130     }
131     else if (arg == "--help" || arg == "-h")
132     {
133       m_action = PRINT_HELP;
134     }
135     else if (arg == "--print-datadir")
136     {
137       m_action = PRINT_DATADIR;
138     }
139     else if (arg == "--debug")
140     {
141       m_log_level = LOG_DEBUG;
142     }
143     else if (arg == "--verbose")
144     {
145       if (m_log_level < LOG_INFO)
146       {
147         m_log_level = LOG_INFO;
148       }
149     }
150     else if (arg == "--datadir")
151     {
152       if (i+1 >= argc)
153       {
154         throw std::runtime_error("Need to specify a directory for --datadir");
155       }
156       else
157       {
158         datadir = argv[++i];
159       }
160     }
161     else if (arg == "--userdir")
162     {
163       if (i+1 >= argc)
164       {
165         throw std::runtime_error("Need to specify a directory for --userdir");
166       }
167       else
168       {
169         userdir = argv[++i];
170       }
171     }
172     else if (arg == "--fullscreen" || arg == "-f")
173     {
174       use_fullscreen = true;
175     }
176     else if (arg == "--default" || arg == "-d")
177     {
178       use_fullscreen = false;
179
180       window_size = Size(1280, 800);
181       fullscreen_size = Size(1280, 800);
182       fullscreen_refresh_rate = 0;
183       aspect_size = Size(0, 0);  // auto detect
184     }
185     else if (arg == "--window" || arg == "-w")
186     {
187       use_fullscreen = false;
188     }
189     else if (arg == "--geometry" || arg == "-g")
190     {
191       i += 1;
192       if (i >= argc)
193       {
194         throw std::runtime_error("Need to specify a size (WIDTHxHEIGHT) for geometry argument");
195       }
196       else
197       {
198         int width, height;
199         if (sscanf(argv[i], "%dx%d", &width, &height) != 2)
200         {
201           throw std::runtime_error("Invalid geometry spec, should be WIDTHxHEIGHT");
202         }
203         else
204         {
205           window_size     = Size(width, height);
206           fullscreen_size = Size(width, height);
207           fullscreen_refresh_rate = 0;
208         }
209       }
210     }
211     else if (arg == "--aspect" || arg == "-a")
212     {
213       i += 1;
214       if (i >= argc)
215       {
216         throw std::runtime_error("Need to specify a ratio (WIDTH:HEIGHT) for aspect ratio");
217       }
218       else
219       {
220         int aspect_width  = 0;
221         int aspect_height = 0;
222         if (strcmp(argv[i], "auto") == 0)
223         {
224           aspect_width  = 0;
225           aspect_height = 0;
226         }
227         else if (sscanf(argv[i], "%d:%d", &aspect_width, &aspect_height) != 2)
228         {
229           throw std::runtime_error("Invalid aspect spec, should be WIDTH:HEIGHT or auto");
230         }
231         else
232         {
233           float aspect_ratio = static_cast<float>(aspect_width) / static_cast<float>(aspect_height);
234
235           // use aspect ratio to calculate logical resolution
236           if (aspect_ratio > 1) {
237             aspect_size = Size(static_cast<int>(600 * aspect_ratio + 0.5),
238                                          600);
239           } else {
240             aspect_size = Size(600,
241                                          static_cast<int>(600 * 1/aspect_ratio + 0.5));
242           }
243         }
244       }
245     }
246     else if (arg == "--renderer")
247     {
248       i += 1;
249       if (i >= argc)
250       {
251         throw std::runtime_error("Need to specify a renderer for renderer argument");
252       }
253       else
254       {
255         video = VideoSystem::get_video_system(argv[i]);
256       }
257     }
258     else if (arg == "--show-fps")
259     {
260       show_fps = true;
261     }
262     else if (arg == "--no-show-fps")
263     {
264       show_fps = false;
265     }
266     else if (arg == "--developer")
267     {
268       developer_mode = true;
269     }
270     else if (arg == "--console")
271     {
272       console_enabled = true;
273     }
274     else if (arg == "--noconsole")
275     {
276       console_enabled = false;
277     }
278     else if (arg == "--disable-sound" || arg == "--disable-sfx")
279     {
280       sound_enabled = false;
281     }
282     else if (arg == "--disable-music")
283     {
284       music_enabled = false;
285     }
286     else if (arg == "--play-demo")
287     {
288       if (i+1 >= argc)
289       {
290         throw std::runtime_error("Need to specify a demo filename");
291       }
292       else
293       {
294         start_demo = argv[++i];
295       }
296     }
297     else if (arg == "--record-demo")
298     {
299       if (i+1 >= argc)
300       {
301         throw std::runtime_error("Need to specify a demo filename");
302       }
303       else
304       {
305         record_demo = argv[++i];
306       }
307     }
308     else if (arg == "--debug-scripts" || arg == "-s")
309     {
310       enable_script_debugger = true;
311     }
312     else if (arg[0] != '-')
313     {
314       start_level = arg;
315     }
316     else
317     {
318       throw std::runtime_error((boost::format("Unknown option '%1%''. Use --help to see a list of options") % arg).str());
319     }
320   }
321 }
322
323 void
324 CommandLineArguments::merge_into(Config& config)
325 {
326 #define merge_option(x) if (x) { config.x = *x; }
327
328   merge_option(fullscreen_size);
329   merge_option(fullscreen_refresh_rate);
330   merge_option(window_size);
331   merge_option(aspect_size);
332   merge_option(use_fullscreen);
333   merge_option(video);
334   merge_option(show_fps);
335   merge_option(sound_enabled);
336   merge_option(music_enabled);
337   merge_option(console_enabled);
338   merge_option(start_level);
339   merge_option(enable_script_debugger);
340   merge_option(start_demo);
341   merge_option(record_demo);
342   merge_option(developer_mode);
343
344 #undef merge_option
345 }
346
347 /* EOF */