+
+/*] Copyright (c) 2009-2011, Charles McGarvey [*****************************
+**] All rights reserved.
+*
+* Distributable under the terms and conditions of the 2-clause BSD license;
+* see the file COPYING for a complete text of the license.
+*
+*****************************************************************************/
+
+#include <cstdlib> // atexit
+#include <exception>
+#include <functional>
+#include <iostream>
+#include <sstream>
+#include <string>
+
+#include <stlplus/portability/file_system.hpp>
+#include <stlplus/portability/subprocesses.hpp>
+
+#include <moof/compression.hh>
+#include <moof/image.hh>
+#include <moof/log.hh>
+#include <moof/modal_dialog.hh>
+#include <moof/opengl.hh>
+#include <moof/resource.hh>
+#include <moof/settings.hh>
+#include <moof/string.hh>
+#include <moof/video.hh>
+
+#include "client.hh"
+
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#if PLATFORM_POSIX
+#include <termios.h>
+#else
+inline int isatty(int dummy) { return 0; }
+#endif
+
+
+Main::Main(moof::settings& settings) :
+ moof::application(settings)
+{
+ moof::dispatcher& dispatcher = moof::dispatcher::global();
+ video_reloaded_ = dispatcher.add_target("video.newcontext",
+ boost::bind(&Main::setup_opengl));
+ setup_opengl();
+
+#if ENABLE_HOTLOADING
+ hotload_timer_.init(boost::bind(&moof::resource::reload_as_needed),
+ SCALAR(0.25), moof::timer::repeat);
+#endif
+}
+
+void Main::setup_opengl()
+{
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_DEPTH_TEST);
+ //glEnable(GL_CULL_FACE);
+
+ //glEnable(GL_POINT_SMOOTH);
+ //glEnable(GL_LINE_SMOOTH);
+ //glEnable(GL_POLYGON_SMOOTH);
+ //glShadeModel(GL_SMOOTH);
+
+ //glEnable(GL_BLEND);
+ //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_ALPHA_TEST);
+ glAlphaFunc(GL_GREATER, 0.0);
+
+ glEnable(GL_MULTISAMPLE);
+
+ glClearColor(1.0, 0.0, 0.0, 1.0);
+
+ //glEnable(GL_LIGHTING);
+ //glEnable(GL_LIGHT0);
+
+ //glEnable(GL_COLOR_MATERIAL);
+ //glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
+
+ float amb[] = {0.1f, 0.1f, 0.1f, 1.0f};
+ float dif[] = {0.6f, 0.6f, 0.6f, 1.0f};
+ //glLightModelfv(GL_LIGHT_MODEL_AMBIENT, light);
+ glLightfv(GL_LIGHT0, GL_AMBIENT, amb);
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, dif);
+
+ float spec[] = {1.0f, 1.0f, 1.0f, 1.0f};
+ glLightfv(GL_LIGHT0, GL_SPECULAR, spec);
+}
+
+void Main::update(moof::scalar t, moof::scalar dt)
+{
+ yoink.update(t, dt);
+}
+
+void Main::draw(moof::scalar alpha) const
+{
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ yoink.draw(alpha);
+}
+
+void Main::handle_event(const moof::event& event)
+{
+ if (yoink.handle_event(event)) return;
+
+ switch (event.type)
+ {
+ case SDL_KEYUP:
+ if (event.key.keysym.sym == SDLK_f)
+ {
+ moof::video::current().toggle_fullscreen();
+ }
+ else if (event.key.keysym.sym == SDLK_l)
+ {
+ moof::video::current().toggle_cursor_captured();
+ moof::video::current().toggle_cursor_visible();
+ }
+ else if (event.key.keysym.sym == SDLK_ESCAPE)
+ {
+ stop();
+ }
+ break;
+
+ case SDL_VIDEORESIZE:
+ glViewport(0, 0, event.resize.w, event.resize.h);
+ break;
+
+ case SDL_QUIT:
+ stop();
+ }
+}
+
+
+static std::string search_paths()
+{
+ // Add search paths; they should be searched in this order:
+ // 1. YOINK_DATADIR (environment)
+ // 2. YOINK_DATADIR (configure)
+
+ std::string path;
+ std::string datadir = stlplus::env_vector()["YOINK_DATADIR"];
+ if (!datadir.empty())
+ {
+ path += datadir;
+ path += ":";
+ }
+ path += YOINK_DATADIR;
+ path += ":";
+ path += "data";
+
+ return path;
+}
+
+static std::string config_paths()
+{
+ // Build the list of config files to search for, in this order:
+ // 1. YOINK_DATADIR/yoinkrc
+ // 2. /etc/yoinkrc (not for Windows)
+ // 3. $HOME/.yoinkrc
+ // 4. YOINKRC (environment)
+
+ std::string path = moof::resource::find_file("yoinkrc");
+
+#if PLATFORM_POSIX
+ path += ":/etc/yoinkrc";
+#endif
+ path += ":$HOME/.yoinkrc";
+
+ std::string rc_file = stlplus::env_vector()["YOINKRC"];
+ if (!rc_file.empty())
+ {
+ path += ":";
+ path += rc_file;
+ }
+
+ return path;
+}
+
+static void print_usage()
+{
+ std::cout << "Usage: "
+ << PACKAGE" [-h|--help] [-i|--info] [OPTION=VALUE]..."
+ << std::endl
+ << "The alien-smashing action game." << std::endl
+ << std::endl
+ << "Options:" << std::endl
+ << " -h, --help" << std::endl
+ << " show this help and exit" << std::endl
+ << " -i, --info" << std::endl
+ << " show version and build information" << std::endl
+ << " detail=1|2|3" << std::endl
+ << " the level of detail of game scenes" << std::endl
+ << " fullscreen=true|false" << std::endl
+ << " if true, uses the entire display" << std::endl
+ << " framerate=num" << std::endl
+ << " number of frames to draw per second" << std::endl
+ << std::endl
+ << "See documentation for more options." << std::endl;
+}
+
+static void print_info(int argc, char* argv[])
+{
+#if INCLUDE_CONFIG_FILE
+ extern size_t data_config_gz_size;
+ extern char data_config_gz[];
+ moof::inflate(data_config_gz, data_config_gz_size, std::cout);
+#else
+ std::cout << std::endl << "No configuration available. :-("
+ << std::endl;
+#endif
+}
+
+
+static void hello()
+{
+ if (isatty(1) == 1) std::cout << "\033[94m";
+ std::cout << std::endl << PACKAGE_STRING << std::endl
+ << "Compiled " << __TIME__" "__DATE__ << std::endl
+ << "Send patches and bug reports to <"PACKAGE_BUGREPORT">."
+ << std::endl << moof::log::endl;
+}
+
+static void goodbye()
+{
+ if (isatty(1) == 1) std::cout << "\033[94m";
+ std::cout << std::endl << "Goodbye." << std::endl << moof::log::endl;
+}
+
+
+int main(int argc, char* argv[])
+{
+ if (argc > 1)
+ {
+ std::string arg(argv[1]);
+ if (arg == "-h" || arg == "--help")
+ {
+ print_usage();
+ return 0;
+ }
+ else if (arg == "-i" || arg == "--info")
+ {
+ print_info(argc, argv);
+ return 0;
+ }
+ }
+
+ hello();
+ atexit(goodbye);
+
+ moof::backend backend;
+
+ moof::resource::set_search_paths(search_paths());
+
+ moof::settings settings(argc, argv, config_paths());
+
+ enum moof::log::level logLevel = moof::log::info;
+ settings.get("loglevel", logLevel);
+ moof::log::level(logLevel);
+
+ std::cout.precision(10);
+
+ try
+ {
+ moof::image_handle icon("yoink", "png");
+ if (icon) icon->set_as_icon();
+ else moof::log_error("no icon loaded");
+ icon.unload();
+
+ class moof::video::attributes attributes(settings);
+ moof::video video(PACKAGE_STRING, attributes);
+
+ bool showfps = false;
+ settings.get("showfps", showfps);
+ video.show_fps(showfps);
+
+ Main app(settings);
+ return app.run();
+ }
+ catch (const std::exception& e)
+ {
+ moof::modal_dialog dialog(moof::modal_dialog::error,
+ PACKAGE_STRING, "unhandled exception",
+ e.what());
+ dialog.run();
+ }
+ catch (const char* e)
+ {
+ moof::modal_dialog dialog(moof::modal_dialog::error,
+ PACKAGE_STRING, "unhandled exception", e);
+ dialog.run();
+ }
+ return 1;
+}
+