]> git.jsancho.org Git - lugaru.git/blobdiff - Source/main.cpp
Console: Return gracefully when loading missing level
[lugaru.git] / Source / main.cpp
index c78dc28755817be7376ad9edb5c1d5cedeb76800..79c139f8ae9a70df92d3edcb4472f092ffe0f062 100644 (file)
@@ -18,31 +18,30 @@ You should have received a copy of the GNU General Public License
 along with Lugaru.  If not, see <http://www.gnu.org/licenses/>.
 */
 
+#include "Game.hpp"
+
+#include "Audio/openal_wrapper.hpp"
+#include "Graphic/gamegl.hpp"
+#include "MacCompatibility.hpp"
+#include "User/Settings.hpp"
+
+#include <fstream>
+#include <iostream>
 #include <math.h>
+#include <set>
 #include <stdio.h>
 #include <string.h>
-#include <fstream>
-#include <iostream>
 #include <zlib.h>
-#include <set>
-#include "gamegl.h"
-#include "MacCompatibility.h"
-#include "Settings.h"
-
-#include "Game.h"
 
 using namespace Game;
 
-#include "openal_wrapper.h"
-
 #ifdef WIN32
-#include <windows.h>
 #include <shellapi.h>
-#include "win-res/resource.h"
+#include <windows.h>
+#include "win-res/resource.hpp"
 #endif
 
 extern float multiplier;
-extern float sps;
 extern float realmultiplier;
 extern int slomo;
 extern bool cellophane;
@@ -54,7 +53,8 @@ extern int mainmenu;
 
 extern float slomospeed;
 extern float slomofreq;
-extern bool visibleloading;
+
+extern int difficulty;
 
 extern SDL_Window *sdlwindow;
 
@@ -64,80 +64,11 @@ set<pair<int,int>> resolutions;
 
 // statics/globals (internal only) ------------------------------------------
 
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable: 4273)
-#endif
-
-#ifndef __MINGW32__ // FIXME: Temporary workaround for GL-8
-#define GL_FUNC(ret,fn,params,call,rt) \
-    extern "C" { \
-        static ret (GLAPIENTRY *p##fn) params = NULL; \
-        ret GLAPIENTRY fn params { rt p##fn call; } \
-    }
-#include "glstubs.h"
-#undef GL_FUNC
-#endif // __MINGW32__
-
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
-static bool lookup_glsym(const char *funcname, void **func)
-{
-    *func = SDL_GL_GetProcAddress(funcname);
-    if (*func == NULL) {
-        fprintf(stderr, "Failed to find OpenGL symbol \"%s\"\n", funcname);
-        return false;
-    }
-    return true;
-}
-
-static bool lookup_all_glsyms(void)
-{
-    bool retval = true;
-#ifndef __MINGW32__ // FIXME: Temporary workaround for GL-8
-#define GL_FUNC(ret,fn,params,call,rt) \
-        if (!lookup_glsym(#fn, (void **) &p##fn)) retval = false;
-#include "glstubs.h"
-#undef GL_FUNC
-#endif // __MINGW32__
-    return retval;
-}
-
-#ifndef __MINGW32__ // FIXME: Temporary workaround for GL-8
-static void GLAPIENTRY glDeleteTextures_doNothing(GLsizei n, const GLuint *textures)
-{
-    // no-op.
-}
-#endif // __MINGW32__
-
-#ifdef MessageBox
-#undef MessageBox
-#endif
-#define MessageBox(hwnd,text,title,flags) STUBBED("msgbox")
-
 // Menu defs
 
 int kContextWidth;
 int kContextHeight;
 
-static int _argc = 0;
-static char **_argv = NULL;
-
-bool cmdline(const char *cmd)
-{
-    for (int i = 1; i < _argc; i++) {
-        char *arg = _argv[i];
-        while (*arg == '-')
-            arg++;
-        if (strcasecmp(arg, cmd) == 0)
-            return true;
-    }
-
-    return false;
-}
-
 //-----------------------------------------------------------------------------------------------------------------------
 
 // OpenGL Drawing
@@ -235,8 +166,6 @@ SDL_bool sdlEventProc(const SDL_Event &e)
     return SDL_TRUE;
 }
 
-
-
 // --------------------------------------------------------------------------
 
 static Point gMidPoint;
@@ -261,9 +190,6 @@ bool SetUp ()
         fprintf(stderr, "Failed to load config, creating default\n");
         SaveSettings();
     }
-    if (kBitsPerPixel != 32 && kBitsPerPixel != 16) {
-        kBitsPerPixel = 16;
-    }
 
     if (SDL_GL_LoadLibrary(NULL) == -1) {
         fprintf(stderr, "SDL_GL_LoadLibrary() failed: %s\n", SDL_GetError());
@@ -291,7 +217,7 @@ bool SetUp ()
         return false;
     }
 
-    if (cmdline("showresolutions")) {
+    if (commandLineOptions[SHOWRESOLUTIONS]) {
         printf("Available resolutions:\n");
         for (auto resolution = resolutions.begin(); resolution != resolutions.end(); resolution++) {
             printf("  %d x %d\n", (int) resolution->first, (int) resolution->second);
@@ -302,12 +228,15 @@ bool SetUp ()
     SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1);
 
     Uint32 sdlflags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN;
-    if ((fullscreen || cmdline("fullscreen")) && !cmdline("windowed")) {
-        fullscreen = 1;
+    if (commandLineOptions[FULLSCREEN]) {
+        fullscreen = commandLineOptions[FULLSCREEN].last()->type();
+    }
+    if (fullscreen) {
         sdlflags |= SDL_WINDOW_FULLSCREEN;
     }
-    if (!cmdline("nomousegrab"))
+    if (!commandLineOptions[NOMOUSEGRAB].last()->type()) {
         sdlflags |= SDL_WINDOW_INPUT_GRABBED;
+    }
 
     sdlwindow = SDL_CreateWindow("Lugaru", SDL_WINDOWPOS_CENTERED_DISPLAY(0), SDL_WINDOWPOS_CENTERED_DISPLAY(0),
                                  kContextWidth, kContextHeight, sdlflags);
@@ -342,12 +271,6 @@ bool SetUp ()
 
     SDL_GL_MakeCurrent(sdlwindow, glctx);
 
-    if (!lookup_all_glsyms()) {
-        fprintf(stderr, "Missing required OpenGL functions.\n");
-        SDL_Quit();
-        return false;
-    }
-
     int dblbuf = 0;
     if ((SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &dblbuf) == -1) || (!dblbuf))
     {
@@ -360,8 +283,9 @@ bool SetUp ()
         SDL_GL_SetSwapInterval(1);
 
     SDL_ShowCursor(0);
-    if (!cmdline("nomousegrab"))
+    if (!commandLineOptions[NOMOUSEGRAB].last()->type()) {
         SDL_SetRelativeMouseMode(SDL_TRUE);
+    }
 
     initGL();
 
@@ -535,16 +459,9 @@ void CleanUp (void)
 {
     LOGFUNC;
 
-    SDL_Quit();
-#ifndef __MINGW32__ // FIXME: Temporary workaround for GL-8
-#define GL_FUNC(ret,fn,params,call,rt) p##fn = NULL;
-#include "glstubs.h"
-#undef GL_FUNC
-    // cheat here...static destructors are calling glDeleteTexture() after
-    //  the context is destroyed and libGL unloaded by SDL_Quit().
-    pglDeleteTextures = glDeleteTextures_doNothing;
-#endif // __MINGW32__
+    delete[] commandLineOptionsBuffer;
 
+    SDL_Quit();
 }
 
 // --------------------------------------------------------------------------
@@ -651,11 +568,53 @@ static inline void chdirToAppPath(const char *argv0)
 }
 #endif
 
+const option::Descriptor usage[] =
+{
+    {UNKNOWN,           0,                      "",     "",                 option::Arg::None,  "USAGE: lugaru [options]\n\n"
+                                                                                                "Options:" },
+    {HELP,              0,                      "h",    "help",             option::Arg::None,  " -h, --help        Print usage and exit." },
+    {FULLSCREEN,        1,                      "f",    "fullscreen",       option::Arg::None,  " -f, --fullscreen  Start the game in fullscreen mode." },
+    {FULLSCREEN,        0,                      "w",    "windowed",         option::Arg::None,  " -w, --windowed    Start the game in windowed mode (default)." },
+    {NOMOUSEGRAB,       1,                      "",     "nomousegrab",      option::Arg::None,  " --nomousegrab     Disable mousegrab." },
+    {NOMOUSEGRAB,       0,                      "",     "mousegrab",        option::Arg::None,  " --mousegrab       Enable mousegrab (default)." },
+    {SOUND,             1,                      "",     "nosound",          option::Arg::None,  " --nosound         Disable sound." },
+    {OPENALINFO,        0,                      "",     "openal-info",      option::Arg::None,  " --openal-info     Print info about OpenAL at launch." },
+    {SHOWRESOLUTIONS,   0,                      "",     "showresolutions",  option::Arg::None,  " --showresolutions List the resolutions found by SDL at launch." },
+    {DEVTOOLS,          0,                      "d",    "devtools",         option::Arg::None,  " -d, --devtools    Enable dev tools: console, level editor and debug info." },
+    {0,0,0,0,0,0}
+};
+
+option::Option commandLineOptions[commandLineOptionsNumber];
+option::Option* commandLineOptionsBuffer;
 
 int main(int argc, char **argv)
 {
-    _argc = argc;
-    _argv = argv;
+    argc-=(argc>0); argv+=(argc>0); // skip program name argv[0] if present
+    option::Stats  stats(true, usage, argc, argv);
+    if (commandLineOptionsNumber != stats.options_max) {
+        std::cerr << "Found incorrect command line option number" << std::endl;
+        return 1;
+    }
+    commandLineOptionsBuffer = new option::Option[stats.buffer_max];
+    option::Parser parse(true, usage, argc, argv, commandLineOptions, commandLineOptionsBuffer);
+
+    if (parse.error()) {
+        delete[] commandLineOptionsBuffer;
+        return 1;
+    }
+
+    if (commandLineOptions[HELP]) {
+        option::printUsage(std::cout, usage);
+        delete[] commandLineOptionsBuffer;
+        return 0;
+    }
+
+    if (option::Option* opt = commandLineOptions[UNKNOWN]) {
+        std::cerr << "Unknown option: " << opt->name << "\n";
+        option::printUsage(std::cerr, usage);
+        delete[] commandLineOptionsBuffer;
+        return 1;
+    }
 
     // !!! FIXME: we could use a Win32 API for this.  --ryan.
 #ifndef WIN32
@@ -664,12 +623,20 @@ int main(int argc, char **argv)
 
     LOGFUNC;
 
+#ifdef NDEBUG
     try {
+#endif
         {
             newGame();
 
-            if (!SetUp ())
+            if (!SetUp ()) {
+                delete[] commandLineOptionsBuffer;
                 return 42;
+            }
+
+            if (commandLineOptions[DEVTOOLS]) {
+                devtools = true;
+            }
 
             bool gameDone = false;
             bool gameFocused = true;
@@ -713,6 +680,7 @@ int main(int argc, char **argv)
         CleanUp ();
 
         return 0;
+#ifdef NDEBUG
     } catch (const std::exception& error) {
         CleanUp();
 
@@ -721,8 +689,9 @@ int main(int argc, char **argv)
 
         LOG(e);
 
-        MessageBox(g_windowHandle, error.what(), "ERROR", MB_OK | MB_ICONEXCLAMATION);
+        SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Exception catched", error.what(), NULL);
 
         return -1;
     }
+#endif
 }