Lephisto/src/conf.c

392 lines
11 KiB
C

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <getopt.h>
#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;
}