20130320
[gdash.git] / src / gtkmain.cpp
blobc0e5c8ad62f214f8df1d6d935faf767caa98d52b
1 /*
2 * Copyright (c) 2007-2013, Czirkos Zoltan http://code.google.com/p/gdash/
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #include "config.h"
19 #include <gdk/gdkkeysyms.h>
20 #include <gtk/gtk.h>
21 #include <glib/gi18n.h>
22 #include <fstream>
24 #ifdef HAVE_SDL
25 /* on windows, sdl does some hack on the main function.
26 * therefore we need to include this file, even if it seems
27 * to do nothing. */
28 #include <SDL/SDL.h>
29 #endif
31 #include "cave/caveset.hpp"
32 #include "sound/sound.hpp"
33 #include "misc/util.hpp"
34 #include "misc/logger.hpp"
35 #include "misc/about.hpp"
36 #include "settings.hpp"
37 #include "framework/commands.hpp"
38 #include "fileops/loadfile.hpp"
39 #include "fileops/binaryimport.hpp"
40 #include "input/joystick.hpp"
42 #ifdef HAVE_SDL
43 #include "sdl/sdlmainwindow.hpp"
44 #endif
45 #ifdef HAVE_GTK
46 #include "gtk/gtkmainwindow.hpp"
47 #include "editor/editor.hpp"
48 #include "editor/editorcellrenderer.hpp"
49 #include "editor/exporthtml.hpp"
50 #include "gtk/gtkpixbuffactory.hpp"
51 #include "gtk/gtkui.hpp"
52 #endif
54 /* includes cavesets built in to the executable */
55 #include "levels.cpp"
59 int main(int argc, char *argv[]) {
60 CaveSet caveset;
61 int quit=0;
62 gboolean editor=FALSE;
63 char *gallery_filename=NULL;
64 char *png_filename=NULL, *png_size=NULL;
65 char *save_cave_name=NULL, *save_gds_name=NULL;
66 gboolean force_quit_no_gtk;
68 GError *error=NULL;
69 GOptionEntry entries[] = {
70 {"editor", 'e', 0, G_OPTION_ARG_NONE, &editor, N_("Start editor")},
71 {"save-gallery", 'g', 0, G_OPTION_ARG_FILENAME, &gallery_filename, N_("Save caveset in a HTML gallery")},
72 {"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\"")},
73 {"favicon", 0, 0, G_OPTION_ARG_STRING /* not filename! */, &gd_html_favicon_filename, N_("Link shortcut icon to a HTML gallery, eg. \"../favicon.ico\"")},
74 {"save-png", 'p', 0, G_OPTION_ARG_FILENAME, &png_filename, N_("Save image of first cave to PNG")},
75 {"png-size", 0, 0, G_OPTION_ARG_STRING, &png_size, N_("Set PNG image size. Default is 128x96, set to 0x0 for unscaled")},
76 {"save-bdcff", 's', 0, G_OPTION_ARG_FILENAME, &save_cave_name, N_("Save caveset in a BDCFF file")},
77 {"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.")},
78 {"quit", 'q', 0, G_OPTION_ARG_NONE, &quit, N_("Batch mode: quit after specified tasks")},
79 {NULL}
82 GOptionContext *context=gd_option_context_new();
83 g_option_context_add_main_entries(context, entries, PACKAGE); /* gdash (gtk version) parameters */
84 g_option_context_add_group(context, gtk_get_option_group(FALSE)); /* add gtk parameters */
85 g_option_context_parse(context, &argc, &argv, &error);
86 g_option_context_free(context);
87 if (error) {
88 gd_warning(error->message);
89 g_error_free(error);
92 /* show license? */
93 if (gd_param_license) {
94 /* print license and quit. */
95 g_print("%s %s\n\n%s\n\n", PACKAGE_NAME, PACKAGE_VERSION, About::copyright);
96 std::vector<std::string> wrapped_license = gd_wrap_text(About::license, 72);
97 for (unsigned i = 0; i < wrapped_license.size(); ++i)
98 g_print("%s\n", wrapped_license[i].c_str());
99 return 0;
102 Logger global_logger;
104 gd_settings_init();
105 gd_settings_init_dirs();
106 gd_load_settings();
107 gd_settings_set_locale();
108 gd_settings_init_translation();
110 force_quit_no_gtk=FALSE;
111 if (!gtk_init_check(&argc, &argv))
112 force_quit_no_gtk=TRUE;
115 gd_cave_types_init();
116 gd_cave_objects_init();
117 Joystick::init();
119 /* if memory snapshot -> gds file conversion requested */
120 if (save_gds_name != NULL) {
121 Logger thislogger;
122 if (gd_param_cavenames==NULL || g_str_equal(gd_param_cavenames, "")) {
123 g_print("An input filename must be given for GDS conversion.\n");
124 return 1;
126 std::vector<unsigned char> file = load_file_to_vector(gd_param_cavenames[0]);
127 /* -1 because the file loader adds a terminating zero */
128 std::vector<unsigned char> memory = load_memory_dump(&file[0], file.size()-1);
129 std::vector<unsigned char> gds = gdash_binary_import(memory);
130 std::fstream os(save_gds_name, std::ios::out | std::ios::binary);
131 os.write((char *) &gds[0], gds.size());
133 thislogger.clear();
136 /* LOAD A CAVESET FROM A FILE, OR AN INTERNAL ONE */
137 /* if remaining arguments, they are filenames */
138 try {
139 if (gd_param_cavenames && gd_param_cavenames[0]) {
140 caveset = create_from_file(gd_param_cavenames[0]);
141 } else {
142 /* if nothing requested, load default */
143 caveset = create_from_buffer(level_pointers[0], -1);
144 caveset.name = level_names[0];
145 caveset.load_highscore(gd_user_config_dir);
147 } catch (std::exception &e) {
148 /// @todo show error to the screen
149 gd_critical(e.what());
152 /* see if generating a gallery. */
153 /* but only if there are any caves at all. */
154 if (caveset.has_caves() && gallery_filename)
155 gd_save_html(gallery_filename, NULL, caveset);
157 /* save cave png */
158 if (png_filename) {
159 unsigned int size_x=128, size_y=96; /* default size */
161 if (png_size && (sscanf(png_size, "%ux%u", &size_x, &size_y) != 2))
162 gd_warning(CPrintf(_("Invalid image size: %s")) % png_size);
163 if (size_x<1 || size_y<1) {
164 size_x=0;
165 size_y=0;
168 /* rendering cave for png: seed=0 */
169 CaveRendered renderedcave(caveset.cave(0), 0, 0);
170 GTKPixbufFactory pf;
171 EditorCellRenderer cr(pf, gd_theme);
173 GdkPixbuf *pixbuf = gd_drawcave_to_pixbuf(&renderedcave, cr, size_x, size_y, true, false);
174 GError *error=NULL;
175 if (!gdk_pixbuf_save(pixbuf, png_filename, "png", &error, "compression", "9", NULL)) {
176 gd_critical(CPrintf("Error saving PNG image %s: %s") % png_filename % error->message);
177 g_error_free(error);
179 g_object_unref(pixbuf);
182 if (save_cave_name)
183 caveset.save_to_file(save_cave_name);
185 /* if batch mode, quit now */
186 if (quit) {
187 global_logger.clear();
188 return 0;
190 if (force_quit_no_gtk) {
191 gd_critical("Cannot initialize GUI");
192 return 1;
195 gd_register_stock_icons();
196 /* set gtk default icon */
197 GdkPixbuf *logo = gd_icon();
198 gtk_window_set_default_icon(logo);
199 g_object_unref(logo);
201 /* select first action */
202 NextAction na;
203 if (editor)
204 na = StartEditor;
205 else
206 na = StartTitle;
208 restart_from_here:
210 gd_sound_init();
211 gd_sound_set_music_volume();
212 gd_sound_set_chunk_volumes();
214 while (na != Quit) {
215 switch (na) {
216 case StartTitle:
217 gd_main_window_sdl_run(&caveset, na);
218 //~ gd_main_window_gtk_run(&caveset, na);
219 break;
220 case StartEditor:
221 na = StartTitle;
222 gd_cave_editor_run(&caveset);
223 break;
224 case Restart:
225 gd_sound_close();
226 na = StartTitle;
227 goto restart_from_here;
228 break;
229 case Quit:
230 break;
234 gd_sound_close();
236 caveset.save_highscore(gd_user_config_dir);
238 gd_save_settings();
240 global_logger.clear();
242 return 0;