281 lines
7.1 KiB
C
281 lines
7.1 KiB
C
#include <SDL.h>
|
|
#include <lua.h>
|
|
#include <lauxlib.h>
|
|
#include <lualib.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
|
|
#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);
|
|
}
|
|
|