#include #include #include #include #include #include #include "def.h" #include "log.h" #include "physics.h" #include "opengl.h" #include "ship.h" #include "pilot.h" #include "player.h" #include "joystick.h" #include "space.h" #include "rng.h" #include "ai.h" #include "pilot.h" #define WINDOW_CAPTION "Lephisto" #define CONF_FILE "conf" #define MINIMUM_FPS 0.5 extern const char* keybindNames[]; // Keybindings. static int quit = 0; // Primary loop. static unsigned int time = 0; // Calculate FPS and movement. // Prototypes. static void print_usage(char** argv); static void display_fps(const double dt); // Update. static void update_all(void); // Usage. static void print_usage(char** argv) { LOG("USAGE: %s [-f] [-j n | -J s] [-hv]", argv[0]); LOG("Options are:"); LOG("\t-f - Fullscreen"); LOG("\t-w n - Set width to (n)"); LOG("\t-h n - Set height to (n)"); LOG("\t-j n - Use joystick (n)"); LOG("\t-J s - Use joystick whose name contains (s)"); LOG("\t-h - Display this message and exit."); LOG("\t-v - Print the version and exit"); } int main(int argc, char** argv) { int i; // Initialize SDL for possible warnings. SDL_Init(0); // Default values.. gl_screen.w = 800; gl_screen.h = 640; gl_screen.fullscreen = 0; // Joystick. int indjoystick = -1; char* namjoystick = NULL; // input. input_init(); input_setKeybind("accel", KEYBIND_KEYBOARD, SDLK_w, 0); input_setKeybind("left", KEYBIND_KEYBOARD, SDLK_a, 0); input_setKeybind("right", KEYBIND_KEYBOARD, SDLK_d, 0); // Use Lua to parse configuration file. lua_State* L = luaL_newstate(); if(luaL_dofile(L, CONF_FILE) == 0) { // Conf file exists. // OpenGL properties. lua_getglobal(L, "width"); if(lua_isnumber(L, -1)) gl_screen.w = (int)lua_tonumber(L, -1); lua_getglobal(L, "height"); if(lua_isnumber(L, -1)) gl_screen.h = (int)lua_tonumber(L, -1); lua_getglobal(L, "fullscreen"); if(lua_isnumber(L, -1)) if((int)lua_tonumber(L, -1) == 1) gl_screen.fullscreen = 1; // 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)); // Grab the keybindings if there are any. char* str; int type, key, reverse; for(i = 0; keybindNames[i]; i++) { lua_getglobal(L, keybindNames[i]); str = NULL; key = -1; reverse = 0; if(lua_istable(L, -1)) { // It's a table alright. // Get the event type. lua_pushstring(L, "type"); lua_gettable(L, -2); if(lua_isstring(L, -1)) str = (char*)lua_tostring(L, -1); // Get the key. lua_pushstring(L, "key"); lua_gettable(L, -3); if(lua_isnumber(L, -1)) key = (int)lua_tonumber(L, -1); // Is it reversed? Only useful for axis. lua_pushstring(L, "reverse"); lua_gettable(L, -4); if(lua_isnumber(L, -1)) reverse = 1; if(key != -1 && str != NULL) { // 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 the keybind. input_setKeybind((char*)keybindNames[i], type, key, reverse); } else WARN("Malformed keybind in %s", CONF_FILE); } } } lua_close(L); // Parse arguments. int c = 0; while((c = getopt(argc, argv, "fJ:j:hv")) != -1) { switch(c) { case 'f': gl_screen.fullscreen = 1; break; case 'j': indjoystick = atoi(optarg); break; case 'J': namjoystick = strdup(optarg); break; case 'v': LOG("Lephisto: version %d.%d.%d\n", VMAJOR, VMINOR, VREV); case 'h': print_usage(argv); exit(EXIT_SUCCESS); } } // Random numbers. rng_init(); if(gl_init()) { // Initializes video output. WARN("Error initializing video output, exiting..."); exit(EXIT_FAILURE); } // Window. SDL_WM_SetCaption(WINDOW_CAPTION, NULL); // Input. if(indjoystick >= 0 || namjoystick != NULL) { if(joystick_init()) WARN("Error initializing joystick input"); if(namjoystick != NULL) { joystick_use(joystick_get(namjoystick)); free(namjoystick); } else if(indjoystick >= 0) joystick_use(indjoystick); } // Misc. if(ai_init()) WARN("Error initializing AI"); gl_fontInit(NULL, "../gfx/fonts/FreeSans.ttf", 16); // Data loading. ships_load(); // Testing. pilot_create(get_ship("Ship"), "Player", NULL, NULL, PILOT_PLAYER); gl_bindCamera(&player->solid->pos); space_init(); pilot_create(get_ship("Miss. Test"), NULL, NULL, NULL, 0); time = SDL_GetTicks(); // Main looops. SDL_Event event; // flushes the event loop, since I notices that when the joystick is loaded, it // creates button events that results in the player starting out accelerating. while(SDL_PollEvent(&event)); while(!quit) { // Event loop. while(SDL_PollEvent(&event)) { if(event.type == SDL_QUIT) quit = 1; // Handle quit. input_handle(&event); // handles all the events the player keybinds. } update_all(); } // Unload data. space_exit(); // Clean up the universe!!! pilots_free(); // Free the pilots, they where locked up D: ships_free(); gl_freeFont(NULL); // Exit subsystems. ai_exit(); // Stop the Lua AI magicness. joystick_exit(); // Release joystick. input_exit(); // Clean up keybindings. gl_exit(); // Kills video output. exit(EXIT_SUCCESS); } // == Update everything. ================================== // Blitting order. (layers) // // BG | Stars and planets. // | Background particles. // X // N | NPC ships. // | Normal layer particles (above ships). // X // FG | Player. // | Foreground particles. // | Text and GUI. // ======================================================== static void update_all(void) { // dt in us. double dt = (double)(SDL_GetTicks() - time) / 1000.; time = SDL_GetTicks(); if(dt > MINIMUM_FPS) { Vec2 pos; vect_cset(&pos, 10., (double)(gl_screen.h-40)); gl_print(NULL, &pos, "FPS is really low! Skipping frames."); SDL_GL_SwapBuffers(); return; } glClear(GL_COLOR_BUFFER_BIT); space_render(dt); pilots_update(dt); display_fps(dt); SDL_GL_SwapBuffers(); } // Spit this out on display. static double fps = 0.; static double fps_cur = 0.; static double fps_dt = 1.; static void display_fps(const double dt) { fps_dt += dt; fps_cur += 1.; if(fps_dt > 1.) { fps = fps_cur / fps_dt; fps_dt = fps_cur = 0.; } Vec2 pos; vect_cset(&pos, 10., (double)(gl_screen.h-20)); gl_print(NULL, &pos, "%3.2f", fps); }