2 * Copyright (c) 2007-2013, Czirkos Zoltan http://code.google.com/p/gdash/
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
19 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
20 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 #include <glib/gi18n.h>
35 /* on windows, sdl does some hack on the main function.
36 * therefore we need to include this file, even if it seems
41 #include "cave/caveset.hpp"
42 #include "sound/sound.hpp"
43 #include "misc/util.hpp"
44 #include "misc/logger.hpp"
45 #include "misc/about.hpp"
46 #include "settings.hpp"
47 #include "framework/commands.hpp"
48 #include "fileops/loadfile.hpp"
49 #include "fileops/highscore.hpp"
50 #include "fileops/binaryimport.hpp"
51 #include "input/joystick.hpp"
54 #include "editor/editor.hpp"
55 #include "editor/editorcellrenderer.hpp"
56 #include "editor/exporthtml.hpp"
57 #include "gtk/gtkpixbuffactory.hpp"
58 #include "gtk/gtkscreen.hpp"
59 #include "gtk/gtkui.hpp"
60 #include "misc/helphtml.hpp"
63 #include "mainwindow.hpp"
65 /* includes cavesets built in to the executable */
70 int main(int argc
, char *argv
[]) {
74 gboolean editor
= FALSE
;
76 char *gallery_filename
= NULL
;
77 char *png_filename
= NULL
, *png_size
= NULL
;
78 char *save_cave_name
= NULL
, *save_gds_name
= NULL
;
80 int save_doc_lang
= -1;
84 GOptionEntry entries
[] = {
86 {"editor", 'e', 0, G_OPTION_ARG_NONE
, &editor
, N_("Start editor")},
87 {"save-gallery", 'g', 0, G_OPTION_ARG_FILENAME
, &gallery_filename
, N_("Save caveset in a HTML gallery")},
88 {"stylesheet", 0, 0, G_OPTION_ARG_STRING
/* not filename! */, &gd_html_stylesheet_filename
, N_("Link stylesheet from file to a HTML gallery, eg. \"../style.css\"")},
89 {"favicon", 0, 0, G_OPTION_ARG_STRING
/* not filename! */, &gd_html_favicon_filename
, N_("Link shortcut icon to a HTML gallery, eg. \"../favicon.ico\"")},
90 {"save-png", 'p', 0, G_OPTION_ARG_FILENAME
, &png_filename
, N_("Save image of first cave to PNG")},
91 {"png-size", 0, 0, G_OPTION_ARG_STRING
, &png_size
, N_("Set PNG image size. Default is 128x96, set to 0x0 for unscaled")},
93 {"save-bdcff", 's', 0, G_OPTION_ARG_FILENAME
, &save_cave_name
, N_("Save caveset in a BDCFF file")},
94 {"save-gds", 'd', 0, G_OPTION_ARG_FILENAME
, &save_gds_name
, N_("Save imported binary data to a GDS file. An input file name is required.")},
96 {"save-docs", 0, 0, G_OPTION_ARG_INT
, &save_doc_lang
, N_("Save documentation in HTML, in the given language identified by an integer.")},
98 {"quit", 'q', 0, G_OPTION_ARG_NONE
, &quit
, N_("Batch mode: quit after specified tasks")},
102 GOptionContext
*context
= gd_option_context_new();
103 g_option_context_add_main_entries(context
, entries
, PACKAGE
); /* gdash (gtk version) parameters */
105 g_option_context_add_group(context
, gtk_get_option_group(FALSE
)); /* add gtk parameters */
107 g_option_context_parse(context
, &argc
, &argv
, &error
);
108 g_option_context_free(context
);
110 gd_warning(error
->message
);
115 if (gd_param_license
) {
116 /* print license and quit. */
117 g_print("%s %s\n\n%s\n\n", PACKAGE_NAME
, PACKAGE_VERSION
, About::copyright
);
118 std::vector
<std::string
> wrapped_license
= gd_wrap_text(About::license
, 72);
119 for (unsigned i
= 0; i
< wrapped_license
.size(); ++i
)
120 g_print("%s\n", wrapped_license
[i
].c_str());
124 Logger global_logger
;
127 gd_settings_init_dirs();
128 if (!gd_param_load_default_settings
)
130 gd_settings_set_locale();
131 gd_settings_init_translation();
134 /* init gtk and set gtk default icon */
135 gboolean force_quit_no_gtk
= FALSE
;
136 if (!gtk_init_check(&argc
, &argv
))
137 force_quit_no_gtk
= TRUE
;
138 GdkPixbuf
*logo
= gd_icon();
139 gtk_window_set_default_icon(logo
);
140 g_object_unref(logo
);
143 gd_cave_types_init();
144 gd_cave_objects_init();
147 /* if memory snapshot -> gds file conversion requested */
148 if (save_gds_name
!= NULL
) {
150 if (gd_param_cavenames
== NULL
|| g_str_equal(gd_param_cavenames
, "")) {
151 g_print("An input filename must be given for GDS conversion.\n");
154 std::vector
<unsigned char> file
= load_file_to_vector(gd_param_cavenames
[0]);
155 /* -1 because the file loader adds a terminating zero */
156 std::vector
<unsigned char> memory
= load_memory_dump(&file
[0], file
.size() - 1);
157 std::vector
<unsigned char> gds
= gdash_binary_import(memory
);
158 std::fstream
os(save_gds_name
, std::ios::out
| std::ios::binary
);
159 os
.write((char *) &gds
[0], gds
.size());
164 /* LOAD A CAVESET FROM A FILE, OR AN INTERNAL ONE */
165 /* if remaining arguments, they are filenames */
167 if (gd_param_cavenames
&& gd_param_cavenames
[0]) {
168 caveset
= load_caveset_from_file(gd_param_cavenames
[0]);
169 load_highscore(caveset
);
171 /* if nothing requested, load default */
172 caveset
= create_from_buffer(level_pointers
[0], -1);
173 caveset
.name
= level_names
[0];
174 load_highscore(caveset
);
176 } catch (std::exception
&e
) {
177 /// @todo show error to the screen
178 gd_critical(e
.what());
182 /* see if generating a gallery. */
183 /* but only if there are any caves at all. */
184 if (caveset
.has_caves() && gallery_filename
)
185 gd_save_html(gallery_filename
, NULL
, caveset
);
189 unsigned int size_x
= 128, size_y
= 96; /* default size */
191 if (png_size
&& (sscanf(png_size
, "%ux%u", &size_x
, &size_y
) != 2))
192 gd_warning(CPrintf(_("Invalid image size: %s")) % png_size
);
193 if (size_x
< 1 || size_y
< 1) {
198 /* rendering cave for png: seed=0 */
199 CaveRendered
renderedcave(caveset
.cave(0), 0, 0);
201 GTKScreen
scr(pf
, NULL
);
202 EditorCellRenderer
cr(scr
, gd_theme
);
204 GdkPixbuf
*pixbuf
= gd_drawcave_to_pixbuf(&renderedcave
, cr
, size_x
, size_y
, true, false);
205 GError
*error
= NULL
;
206 if (!gdk_pixbuf_save(pixbuf
, png_filename
, "png", &error
, "compression", "9", NULL
)) {
207 gd_critical(CPrintf("Error saving PNG image %s: %s") % png_filename
% error
->message
);
210 g_object_unref(pixbuf
);
215 caveset
.save_to_file(save_cave_name
);
218 gd_register_stock_icons();
220 if (save_doc_lang
!= -1) {
221 if (save_doc_lang
< 1 || save_doc_lang
>= (int)g_strv_length((gchar
**) gd_languages_names
)) {
222 gd_critical("No such language");
225 /* switch to the doc language requested */
226 int language_previous
= gd_language
;
227 gd_language
= save_doc_lang
;
228 gd_settings_set_locale();
229 gd_settings_init_translation();
231 /* the html saver needs a realized widget to render gtk icons, so create a toplevel window,
232 * realize it, but do not show it */
233 GtkWidget
*widget
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
234 gtk_widget_realize(widget
);
235 save_help_to_html(CPrintf("Doc-%s.html") % gd_languages_names
[save_doc_lang
], widget
);
236 gtk_widget_destroy(widget
);
238 /* switch back to original language */
239 gd_language
= language_previous
;
240 gd_settings_set_locale();
241 gd_settings_init_translation();
245 /* if batch mode, quit now */
247 global_logger
.clear();
251 if (force_quit_no_gtk
) {
252 gd_critical("Cannot initialize GTK+");
258 if (SDL_Init(0) == -1) {
259 gd_critical("Cannot initialize SDL");
264 /* select first action */
265 NextAction na
= StartTitle
;
274 gd_sound_set_music_volume();
275 gd_sound_set_chunk_volumes();
277 while (na
!= Quit
&& na
!= Restart
) {
280 main_window_run_title_screen(&caveset
, na
);
285 gd_cave_editor_run(&caveset
);
298 goto restart_from_here
;
301 save_highscore(caveset
);
305 global_logger
.clear();
311 /* free the stuff created by the option context */
312 g_free(gallery_filename
);
313 g_free(gd_html_stylesheet_filename
);
314 g_free(gd_html_favicon_filename
);
315 g_free(png_filename
);
317 g_free(save_gds_name
);