c76a6148bf84abb6a8b48c03f92f1e6de4055185
[chaz/yoink] / src / Main.cc
1
2 /*] Copyright (c) 2009-2010, Charles McGarvey [**************************
3 **] All rights reserved.
4 *
5 * vi:ts=4 sw=4 tw=75
6 *
7 * Distributable under the terms and conditions of the 2-clause BSD license;
8 * see the file COPYING for a complete text of the license.
9 *
10 **************************************************************************/
11
12 #include "config.h"
13
14 #include <cstdlib> // atexit
15 #include <exception>
16 #include <functional>
17 #include <iostream>
18 #include <string>
19
20 #if !defined(__WIN32)
21 #include <termios.h>
22 #else
23 inline int isatty(int dummy) { return 0; }
24 #endif
25
26 #include <stlplus/portability/file_system.hpp>
27 #include <stlplus/portability/subprocesses.hpp>
28
29 #include <moof/log.hh>
30 #include <moof/modal_dialog.hh>
31 #include <moof/opengl.hh>
32 #include <moof/resource.hh>
33 #include <moof/settings.hh>
34 #include <moof/string.hh>
35 #include <moof/video.hh>
36
37 #include "GameLayer.hh"
38 #include "Main.hh"
39 #include "TitleLayer.hh"
40 #include "version.h"
41
42
43 Main::Main(moof::settings& settings, moof::video& video) :
44 moof::view(settings, video)
45 {
46 moof::dispatcher& dispatcher = moof::dispatcher::global();
47 video_reloaded_ = dispatcher.add_target("video.newcontext",
48 boost::bind(&Main::setup_opengl));
49 setup_opengl();
50
51 #if ENABLE_HOTLOADING
52 hotload_timer_.init(boost::bind(&moof::resource::reload_as_needed),
53 SCALAR(0.25),
54 moof::timer::repeat);
55 #endif
56 }
57
58
59 void Main::update(moof::scalar t, moof::scalar dt)
60 {
61 if (children().size() == 0)
62 {
63 //moof::log_warning("main view has no children");
64 //stop();
65 //return;
66 add_child(TitleLayer::alloc());
67 }
68
69 moof::view::update(t, dt);
70 }
71
72 void Main::draw(moof::scalar alpha) const
73 {
74 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
75
76 glMatrixMode(GL_PROJECTION);
77 glLoadIdentity();
78
79 glMatrixMode(GL_MODELVIEW);
80 glLoadIdentity();
81
82 moof::view::draw(alpha);
83 }
84
85 bool Main::handle_event(const moof::event& event)
86 {
87 if (moof::view::handle_event(event)) return true;
88
89 switch (event.type)
90 {
91 case SDL_KEYUP:
92 if (event.key.keysym.sym == SDLK_f)
93 {
94 video().toggle_fullscreen();
95 }
96 else if (event.key.keysym.sym == SDLK_l)
97 {
98 video().toggle_cursor_captured();
99 video().toggle_cursor_visible();
100 }
101 break;
102
103 case SDL_VIDEORESIZE:
104 glViewport(0, 0, event.resize.w, event.resize.h);
105 break;
106
107 case SDL_QUIT:
108 stop();
109 return true;
110 }
111
112 return false;
113 }
114
115
116 std::string Main::search_paths()
117 {
118 // Add search paths; they should be searched in this order:
119 // 1. YOINK_DATADIR (environment)
120 // 2. YOINK_DATADIR (configure)
121
122 std::string path;
123 std::string datadir = stlplus::env_vector()["YOINK_DATADIR"];
124 if (!datadir.empty())
125 {
126 path += datadir;
127 path += ":";
128 }
129 path += YOINK_DATADIR;
130
131 return path;
132 }
133
134 std::string Main::config_paths()
135 {
136 // Build the list of config files to search for, in this order:
137 // 1. YOINK_DATADIR/yoinkrc
138 // 2. /etc/yoinkrc (not for Windows)
139 // 3. $HOME/.yoinkrc
140 // 4. YOINKRC (environment)
141
142 std::string path = moof::resource::find_file("yoinkrc");
143
144 #if !defined(_WIN32)
145 path += ":/etc/yoinkrc";
146 #endif
147 path += ":$HOME/.yoinkrc";
148
149 std::string rc_file = stlplus::env_vector()["YOINKRC"];
150 if (!rc_file.empty())
151 {
152 path += ":";
153 path += rc_file;
154 }
155
156 return path;
157 }
158
159
160 void Main::setup_opengl()
161 {
162 //glEnable(GL_TEXTURE_2D);
163 glEnable(GL_DEPTH_TEST);
164 //glEnable(GL_CULL_FACE);
165
166 glEnable(GL_POINT_SMOOTH);
167 glEnable(GL_LINE_SMOOTH);
168 glEnable(GL_POLYGON_SMOOTH);
169 glShadeModel(GL_SMOOTH);
170
171 //glEnable(GL_BLEND);
172 //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
173 glEnable(GL_ALPHA_TEST);
174 glAlphaFunc(GL_GREATER, 0.0);
175
176 glClearColor(0.0, 0.0, 0.0, 1.0);
177
178 //glEnable(GL_LIGHTING);
179 glEnable(GL_LIGHT0);
180
181 glEnable(GL_COLOR_MATERIAL);
182 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
183
184 float amb[] = {0.1f, 0.1f, 0.1f, 1.0f};
185 float dif[] = {0.6f, 0.6f, 0.6f, 1.0f};
186 //glLightModelfv(GL_LIGHT_MODEL_AMBIENT, light);
187 glLightfv(GL_LIGHT0, GL_AMBIENT, amb);
188 glLightfv(GL_LIGHT0, GL_DIFFUSE, dif);
189
190 float spec[] = {1.0f, 1.0f, 1.0f, 1.0f};
191 glLightfv(GL_LIGHT0, GL_SPECULAR, spec);
192 }
193
194
195 void Main::print_usage()
196 {
197 std::cout << "Usage: "
198 << PACKAGE" [-h|--help] [-i|--info] [OPTION=VALUE]..."
199 << std::endl
200 << "The alien-smashing action game." << std::endl
201 << std::endl
202 << "Options:" << std::endl
203 << " -h, --help" << std::endl
204 << " show this help and exit" << std::endl
205 << " -i, --info" << std::endl
206 << " show version and build information" << std::endl
207 << " detail=1|2|3" << std::endl
208 << " the level of detail of game scenes" << std::endl
209 << " fullscreen=true|false" << std::endl
210 << " if true, uses the entire display" << std::endl
211 << " framerate=num" << std::endl
212 << " number of frames to draw per second" << std::endl
213 << std::endl
214 << "See documentation for more options." << std::endl;
215 }
216
217
218 void Main::print_info(int argc, char* argv[])
219 {
220 bool color = (isatty(1) == 1);
221
222 stlplus::env_vector environment;
223
224 std::string assets;
225 assets.assign(YOINK_DATADIR);
226 if (!stlplus::file_readable(assets))
227 {
228 assets += " ";
229 if (color) assets += "\033[1;91m";
230 assets += "(no access)";
231 if (color) assets += "\033[0m";
232 }
233
234 std::string datadir = environment["YOINK_DATADIR"];
235 if (!datadir.empty())
236 {
237 if (!stlplus::folder_readable(datadir))
238 {
239 datadir += " ";
240 if (color) datadir += "\033[1;91m";
241 datadir += "(no access)";
242 if (color) datadir += "\033[0m";
243 }
244 }
245
246 std::string rc_file = environment["YOINKRC"];
247 if (!rc_file.empty())
248 {
249 if (!stlplus::file_readable(rc_file)) rc_file += " (no access)";
250 }
251
252 std::cout << " Executable: " << argv[0] << std::endl
253 #ifdef YOINK_GITHEAD
254 << " Commit: "YOINK_GITHEAD << std::endl
255 #endif
256 << " Version: " << PACKAGE_VERSION << std::endl
257 << " Built: " << COMPILE_TIME << std::endl
258 << " Compiler: " << COMPILER_STRING << std::endl
259 << " Assets: " << assets << std::endl
260 << "Build options: ";
261
262 #if ENABLE_CLOCK_GETTIME
263 print_option("clock_gettime", true);
264 #else
265 print_option("clock_gettime", false);
266 #endif
267 #if DEBUG
268 print_option("debug", true);
269 #else
270 print_option("debug", false);
271 #endif
272 #if WITH_GTK
273 print_option("gtk", true);
274 #else
275 print_option("gtk", false);
276 #endif
277 #if ENABLE_HOTLOADING
278 print_option("hotload", true);
279 #else
280 print_option("hotload", false);
281 #endif
282 #if PROFILING_ENABLED
283 print_option("profile", true);
284 #else
285 print_option("profile", false);
286 #endif
287 #if WITH_QT4
288 print_option("qt4", true);
289 #else
290 print_option("qt4", false);
291 #endif
292 #if ENABLE_THREADS
293 print_option("threads", true);
294 #else
295 print_option("threads", false);
296 #endif
297 std::cout << std::endl;
298 std::cout << " YOINKRC: " << rc_file << std::endl
299 << "YOINK_DATADIR: " << datadir << std::endl;
300 }
301
302 void Main::print_option(const std::string& option, bool enabled)
303 {
304 if (isatty(1) == 1)
305 {
306 if (enabled) std::cout << "\033[1;94m";
307 else std::cout << "\033[1m";
308 }
309 if (!enabled) std::cout << "-";
310 std::cout << option;
311 if (isatty(1) == 1) std::cout << "\033[0m";
312 std::cout << " ";
313 }
314
315
316 void hello()
317 {
318 if (isatty(1) == 1) std::cout << "\033[94m";
319 std::cout << std::endl << PACKAGE_STRING << std::endl
320 << "Compiled " << __TIME__ " " __DATE__ << std::endl
321 << "Send patches and bug reports to <"
322 PACKAGE_BUGREPORT << ">." << std::endl << moof::log::endl;
323 }
324
325 void goodbye()
326 {
327 if (isatty(1) == 1) std::cout << "\033[94m";
328 std::cout << std::endl << "Goodbye." << std::endl << moof::log::endl;
329 }
330
331
332 int main(int argc, char* argv[])
333 {
334 //moof::backend backend;
335
336 if (argc > 1)
337 {
338 std::string arg(argv[1]);
339 if (arg == "-h" || arg == "--help")
340 {
341 Main::print_usage();
342 return 0;
343 }
344 else if (arg == "-i" || arg == "--info")
345 {
346 Main::print_info(argc, argv);
347 return 0;
348 }
349 }
350
351 hello();
352 atexit(goodbye);
353
354 moof::resource::set_search_paths(Main::search_paths());
355
356 moof::settings settings(argc, argv, Main::config_paths());
357
358 enum moof::log::level logLevel = moof::log::info;
359 settings.get("loglevel", logLevel);
360 moof::log::level(logLevel);
361
362 try
363 {
364 //std::string iconPath(PACKAGE".png");
365 //iconPath = moof::resource::find_file(iconPath);
366 //moof::image icon(iconPath);
367 //icon.set_as_icon();
368 moof::image_handle icon(PACKAGE, "png");
369 if (icon) icon->set_as_icon();
370 else moof::log_error("no icon loaded");
371 icon.unload();
372
373 class moof::video::attributes attributes(settings);
374 moof::video video(PACKAGE_STRING, attributes);
375 Main mainView(settings, video);
376
377 mainView.run();
378 return 0;
379 }
380 catch (const std::exception& e)
381 {
382 moof::modal_dialog dialog(moof::modal_dialog::error,
383 PACKAGE_STRING, "unhandled exception",
384 e.what());
385 dialog.run();
386 }
387 catch (const char* e)
388 {
389 moof::modal_dialog dialog(moof::modal_dialog::error,
390 PACKAGE_STRING, "unhandled exception",
391 e);
392 dialog.run();
393 }
394
395 return 1;
396 }
397
This page took 0.047844 seconds and 3 git commands to generate.