#include #include #include #include #include "llua.h" #include "lauxlib.h" #include "lephisto.h" #include "log.h" #include "player.h" #include "opengl.h" #include "input.h" #include "music.h" #include "nebulae.h" #include "ldata.h" #include "lfile.h" #include "conf.h" #define conf_loadInt(n,i) \ lua_getglobal(L,n); \ if(lua_isnumber(L, -1)) { \ i = (int)lua_tonumber(L, -1); \ } \ lua_pop(L, 1); \ #define conf_loadFloat(n,f) \ lua_getglobal(L,n); \ if(lua_isnumber(L, -1)) { \ f = (double)lua_tonumber(L, -1); \ } \ lua_pop(L,1);\ #define conf_loadBool(n,b) \ lua_getglobal(L,n); \ if(lua_isnumber(L, -1)) { \ if((int)lua_tonumber(L, -1) == 1) \ b = 1; \ } \ else if(lua_isboolean(L, -1)) \ b = lua_toboolean(L, -1); \ lua_pop(L, 1); \ #define conf_loadString(n,s) \ lua_getglobal(L,n); \ if(lua_isstring(L, -1)) { \ s = strdup((char*)lua_tostring(L, -1)); \ } \ lua_pop(L, 1); \ /* Some crap from main. */ extern int nosound; extern int show_fps; extern int max_fps; extern int indjoystick; extern char* namjoystick; /* From player.c */ extern const char* keybindNames[]; /* Keybindings. */ /* input.c. */ extern unsigned int input_afterburnSensibility; static void print_usage(char** argv); /* Print usage. */ static void print_usage(char** argv) { LOG("USAGE: %s [OPTIONS]", argv[0]); LOG("Options are:"); LOG(" -f, --fullscreen - Activate fullscreen"); LOG(" -F, --fps - Limit frames per second to n"); LOG(" -V, --vsync - Enable vsync"); LOG(" -d s, --data s - Set the data file to be s"); LOG(" -W n - Set width to n"); LOG(" -H n - Set height to n"); LOG(" -j n, --joystick n - Use joystick (n)"); LOG(" -J s, --joystick s - Use joystick whose name contains (s)"); LOG(" -S, --Sound - Forces sound."); LOG(" -m f --mvol f - Set the music volume to f"); LOG(" -s f --svol f - Set the sound volume to f"); LOG(" -G - Regenerates the nebulae (slow)"); LOG(" -h --help - Display this message and exit."); LOG(" -v - Print the version and exit"); } /** * @brief Set the default configuration. */ void conf_setDefaults(void) { /* GL. */ gl_screen.w = 800; gl_screen.h = 600; gl_screen.flags = 0; gl_screen.fsaa = 4; /* Only used if activated. */ /* Openal. */ nosound = 0; /* Joystick. */ indjoystick = -1; namjoystick = NULL; /* Input. */ input_setDefault(); } /* Ok.. Parse a config file plox. */ int conf_loadConfig(const char* file) { int i; double d; char* str, *mod; SDLKey key; int type, reverse; int w, h, fsaa; SDLMod m; i = 0; d = 0.; lua_State* L = llua_newState(); if(luaL_dofile(L, file) == 0) { /* Conf file exists indeed. */ /* Global. */ lua_getglobal(L, "data"); if(lua_isstring(L, -1)) ldata_setPath((char*)lua_tostring(L, -1)); lua_pop(L, 1); /* OpenGL properties.. */ /* Dimensions. */ w = h = 0; conf_loadInt("width", w); conf_loadInt("height", h); if(w != 0) { gl_screen.flags |= OPENGL_DIM_DEF; gl_screen.w = w; } if(h != 0) { gl_screen.flags |= OPENGL_DIM_DEF; gl_screen.h = h; } /* FSAA */ fsaa = 0; conf_loadInt("fsaa", fsaa); if(fsaa > 0) { gl_screen.flags |= OPENGL_FSAA; gl_screen.fsaa = fsaa; } /* Fullscreen. */ conf_loadBool("fullscreen", i); if(i) { gl_screen.flags |= OPENGL_FULLSCREEN; i = 0; } /* Anti Aliasing. */ conf_loadBool("aa", i); if(i) { gl_screen.flags |= OPENGL_AA_POINT | OPENGL_AA_LINE || OPENGL_AA_POLYGON; i = 0; } conf_loadBool("aa_point", i); if(i) { gl_screen.flags |= OPENGL_AA_POINT; i = 0; } conf_loadBool("aa_line", i) if(i) { gl_screen.flags |= OPENGL_AA_LINE; i = 0; } conf_loadBool("aa_polygon", i); if(i) { gl_screen.flags |= OPENGL_AA_POLYGON; i = 0; } /* vsync. */ conf_loadBool("vsync", i); if(i) { gl_screen.flags |= OPENGL_VSYNC; i = 0; } /* FPS. */ conf_loadBool("showfps", show_fps); conf_loadInt("maxfps", max_fps); /* Input. */ conf_loadInt("afterburn", input_afterburnSensibility); /* Sound. */ conf_loadBool("nosound", i); nosound = i; i = 0; conf_loadFloat("sound", d); if(d) { sound_defVolume = MAX(MIN(d, 1.), 0.); if(d == 0.) sound_disabled = 1; d = 0.; } conf_loadFloat("music", d); if(d) { music_defVolume = MAX(MIN(d, 1.), 0.); if(d == 0.) music_disabled = 1; d = 0.; } /* Joystick. */ lua_getglobal(L, "joystick"); if(lua_isnumber(L, -1)) indjoystick = (int)lua_tonumber(L, -1); else if(lua_isstring(L, -1)) namjoystick = strdup((char*)lua_tostring(L, -1)); lua_pop(L, 1); /* Keybindings. */ for(i = 0; strcmp(keybindNames[i], "end"); i++) { lua_getglobal(L, keybindNames[i]); if(lua_istable(L, -1)) { /* It's a gawd damn table!! */ lua_pushstring(L, "type"); lua_gettable(L, -2); if(lua_isstring(L, -1)) str = (char*)lua_tostring(L, -1); else if(lua_isnil(L, -1)) { WARN("Found keybind with no type field!"); str = "null"; } else { WARN("Found keybind with invalid type field!"); str = "null"; } lua_pop(L, 1); /* Get the key. */ lua_pushstring(L, "key"); lua_gettable(L, -2); if(lua_isnumber(L, -1)) key = (int)lua_tonumber(L, -1); else if(lua_isstring(L, -1)) key = input_keyConv((char*)lua_tostring(L, -1)); else if(lua_isnil(L, -1)) { WARN("Found keybind with no key field!"); key = SDLK_UNKNOWN; } else { WARN("Found keybind with invalid key field!"); key = SDLK_UNKNOWN; } lua_pop(L, 1); /* Is it reversed? Only used for axis. */ lua_pushstring(L, "reverse"); lua_gettable(L, -2); if(lua_isnumber(L, -1)) reverse = !!(int)lua_tonumber(L, -1); else if(lua_isboolean(L, -1)) reverse = lua_toboolean(L, -1); else reverse = 0; lua_pop(L, 1); /* Get the modifier. */ lua_pushstring(L, "mod"); lua_gettable(L, -2); if(lua_isstring(L, -1)) mod = (char*)lua_tostring(L, -1); else mod = NULL; lua_pop(L, 1); if(str != NULL) { /* Then the keybind is valid. Get the type. */ if(strcmp(str, "null") ==0) type = KEYBIND_NULL; else if(strcmp(str, "keyboard") ==0) type = KEYBIND_KEYBOARD; else if(strcmp(str, "jaxis") ==0) type = KEYBIND_JAXIS; else if(strcmp(str, "jbutton") ==0) type = KEYBIND_JBUTTON; else { WARN("Unknown keybinding of type %s", str); continue; } /* Set modifier, probably should be able to handle two at a time. */ if(mod != NULL) { if(strcmp(mod, "lctrl") ==0) m = KMOD_LCTRL; else if(strcmp(mod, "rctrl") ==0) m = KMOD_RCTRL; else if(strcmp(mod, "lshift") ==0) m = KMOD_LSHIFT; else if(strcmp(mod, "rshift") ==0) m = KMOD_RSHIFT; else if(strcmp(mod, "lalt") ==0) m = KMOD_LALT; else if(strcmp(mod, "ralt") ==0) m = KMOD_RALT; else if(strcmp(mod, "lmeta") ==0) m = KMOD_LMETA; else if(strcmp(mod, "rmeta") ==0) m = KMOD_RMETA; else if(strcmp(mod, "any") ==0) m = KMOD_ALL; else { WARN("Unkown keybinding mod of type %s", mod); m = KMOD_NONE; } } else m = KMOD_NONE; /* Set the keybind. */ input_setKeybind((char*)keybindNames[i], type, key, m, reverse); } else { WARN("Malformed keybind for %s in '%s'", keybindNames[i], file); } } /* Clean up after table crap. */ lua_pop(L,1); } } else { /* Failed to load the config file.. */ lua_close(L); DEBUG("Config file '%s' not found.", file); lfile_touch(file); return 1; } lua_close(L); return 0; } /* Parse some CLI options. */ void conf_parseCLI(int argc, char** argv) { static struct option long_options[] = { { "fullscreen", no_argument, 0, 'f' }, { "fps", required_argument, 0, 'F' }, { "vysnc", no_argument, 0, 'V' }, { "data", required_argument, 0, 'd' }, { "joystick", required_argument, 0, 'j' }, { "Joystick", required_argument, 0, 'J' }, { "width", required_argument, 0, 'W' }, { "width", required_argument, 0, 'H' }, { "sound", no_argument, 0, 'S' }, { "mvol", required_argument, 0, 'm' }, { "svol", required_argument, 0, 's' }, { "help", no_argument, 0, 'h' }, { "version", no_argument, 0, 'v' }, { NULL, 0, 0, 0 } }; int option_index = 0; int c = 0; double d; while((c = getopt_long(argc, argv, "fF:Vd:j:J:W:H:MSm:s:Ghv", long_options, &option_index)) != -1) { switch(c) { case 'f': gl_screen.flags |= OPENGL_FULLSCREEN; break; case 'F': max_fps = atoi(optarg); break; case 'V': gl_screen.flags |= OPENGL_VSYNC; break; case 'd': ldata_setPath(optarg); break; case 'j': indjoystick = atoi(optarg); break; case 'J': namjoystick = strdup(optarg); break; case 'W': gl_screen.w = atoi(optarg); gl_screen.flags |= OPENGL_DIM_DEF; break; case 'H': gl_screen.h = atoi(optarg); gl_screen.flags |= OPENGL_DIM_DEF; break; case 'M': nosound = 1; break; case 'S': nosound = 0; break; case 'm': d = atof(optarg); music_defVolume = MAX(MIN(d, 1.), 0.); if(d == 0.) music_disabled = 1; break; case 's': d = atof(optarg); sound_defVolume = MAX(MIN(d, 1.), 0.); if(d == 0.) sound_disabled = 1; break; case 'G': nebu_forceGenerate(); break; case 'v': /* By now it has already displayed the version. */ /*LOG(APPNAME": version %d.%d.%d", VMAJOR, VMINOR, VREV); */ exit(EXIT_SUCCESS); case 'h': print_usage(argv); exit(EXIT_SUCCESS); } } } /* Saves the current configuration. */ int conf_saveConfig(void) { /** @todo save conf. */ return 0; }