[Change] Optimized ai API some.
[Fix] Few mem leaks.
This commit is contained in:
parent
f90a2a273c
commit
6a2f07b5b7
@ -64,7 +64,7 @@ face(number/Vec2 target, number invert)
|
||||
-- Turn to face the current target.
|
||||
-- target pilot ID or Vec2 to face.
|
||||
-- invert face away if 1
|
||||
-- return nil
|
||||
-- return number offset from target in grad
|
||||
|
||||
// ================
|
||||
// MISC!
|
||||
|
@ -1,6 +1,10 @@
|
||||
function follow()
|
||||
face(1,1)
|
||||
accel(1)
|
||||
target = 1
|
||||
dir = face(target)
|
||||
dist = getdist(getpos(target))
|
||||
if dir < 10 and dist > 100 then
|
||||
accel()
|
||||
end
|
||||
end
|
||||
|
||||
function goto()
|
||||
|
21
src/ai.c
21
src/ai.c
@ -62,6 +62,12 @@ static Pilot* cur_pilot = NULL;
|
||||
static double pilot_acc = 0.;
|
||||
static double pilot_turn = 0.;
|
||||
|
||||
// Destroy the AI part of the pilot.
|
||||
void ai_destroy(Pilot* p) {
|
||||
ai_freetask(p->task);
|
||||
}
|
||||
|
||||
// Init the AI stuff. Which is basically Lua.
|
||||
int ai_init(void) {
|
||||
L = luaL_newstate();
|
||||
if(L == NULL)
|
||||
@ -76,7 +82,7 @@ int ai_init(void) {
|
||||
lua_register(L, "taskname", ai_taskname);
|
||||
lua_register(L, "gettarget", ai_gettarget);
|
||||
lua_register(L, "gettargetid", ai_gettargetid);
|
||||
lua_register(L, "getdistance", ai_getdistance);
|
||||
lua_register(L, "getdist", ai_getdistance);
|
||||
lua_register(L, "getpos", ai_getpos);
|
||||
lua_register(L, "minbrakedist", ai_minbrakedist);
|
||||
lua_register(L, "accel", ai_accel);
|
||||
@ -96,6 +102,7 @@ int ai_init(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Clean up global AI
|
||||
void ai_exit(void) {
|
||||
lua_close(L);
|
||||
}
|
||||
@ -148,6 +155,7 @@ static int ai_pushtask(lua_State* L) {
|
||||
Task* t = MALLOC_L(Task);
|
||||
t->name = (lua_isstring(L, 2)) ? strdup((char*) lua_tostring(L, 2)) : NULL;
|
||||
t->next = NULL;
|
||||
t->target = NULL;
|
||||
|
||||
if(lua_gettop(L) > 2) {
|
||||
if(lua_isnumber(L, 3))
|
||||
@ -241,8 +249,7 @@ static int ai_minbrakedist(lua_State* L) {
|
||||
|
||||
// Accelerate the pilot based on a param.
|
||||
static int ai_accel(lua_State* L) {
|
||||
MIN_ARGS(1);
|
||||
pilot_acc = (lua_isnumber(L, 1)) ? ABS((double)lua_tonumber(L, 1)) : 1.;
|
||||
pilot_acc = (lua_gettop(L) > 1 && lua_isnumber(L, 1)) ? ABS((double)lua_tonumber(L, 1)) : 1.;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -263,13 +270,17 @@ static int ai_face(lua_State* L) {
|
||||
double mod = 10;
|
||||
if(lua_gettop(L) > 1 && lua_isnumber(L,2))
|
||||
switch((int)lua_tonumber(L,2)) {
|
||||
case 0: break;
|
||||
case 1: mod *= -1; break;
|
||||
case 2: break;
|
||||
}
|
||||
double diff = angle_diff(cur_pilot->solid->dir, vect_angle(&cur_pilot->solid->pos, v));
|
||||
|
||||
pilot_turn = mod * angle_diff(cur_pilot->solid->dir, vect_angle(&cur_pilot->solid->pos, v));
|
||||
pilot_turn = mod*diff;
|
||||
|
||||
return 0;
|
||||
lua_pushnumber(L, ABS(diff*180./M_PI));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Create a vector.
|
||||
|
26
src/main.c
26
src/main.c
@ -28,6 +28,8 @@ extern const char* keybindNames[]; // Keybindings.
|
||||
static int quit = 0; // Primary loop.
|
||||
static unsigned int time = 0; // Calculate FPS and movement.
|
||||
|
||||
static int show_fps = 1; // Default - True.
|
||||
|
||||
// Prototypes.
|
||||
|
||||
static void print_usage(char** argv);
|
||||
@ -82,6 +84,10 @@ int main(int argc, char** argv) {
|
||||
if((int)lua_tonumber(L, -1) == 1)
|
||||
gl_screen.fullscreen = 1;
|
||||
|
||||
lua_getglobal(L, "fps");
|
||||
if(lua_isnumber(L, -1))
|
||||
show_fps = (int)lua_tonumber(L, -1);
|
||||
|
||||
// Joystick.
|
||||
lua_getglobal(L, "joystick");
|
||||
if(lua_isnumber(L, -1))
|
||||
@ -137,19 +143,23 @@ int main(int argc, char** argv) {
|
||||
// Parse arguments.
|
||||
static struct option long_options[] = {
|
||||
{ "fullscreen", no_argument, 0, 'f' },
|
||||
{ "fps", optional_argument, 0, 'F' },
|
||||
{ "joystick", required_argument, 0, 'j' },
|
||||
{ "joystick", required_argument, 0, 'J' },
|
||||
{ "help", no_argument, 0, 'h' },
|
||||
{ "version", no_argument, 0, 'v' },
|
||||
{ 0, 0, 0, 0 }
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
int option_index = 0;
|
||||
int c = 0;
|
||||
while((c = getopt_long(argc, argv, "fJ:j:hv", long_options, &option_index)) != -1) {
|
||||
while((c = getopt_long(argc, argv, "fFJ:j:hv", long_options, &option_index)) != -1) {
|
||||
switch(c) {
|
||||
case 'f':
|
||||
gl_screen.fullscreen = 1;
|
||||
break;
|
||||
case 'F':
|
||||
if(optarg != NULL) show_fps = atoi(optarg);
|
||||
break;
|
||||
case 'j':
|
||||
indjoystick = atoi(optarg);
|
||||
break;
|
||||
@ -256,7 +266,7 @@ static void update_all(void) {
|
||||
|
||||
if(dt > MINIMUM_FPS) {
|
||||
Vec2 pos;
|
||||
vect_cset(&pos, 10., (double)(gl_screen.h-40));
|
||||
vect_csetmin(&pos, 10., (double)(gl_screen.h-40));
|
||||
gl_print(NULL, &pos, "FPS is really low! Skipping frames.");
|
||||
SDL_GL_SwapBuffers();
|
||||
return;
|
||||
@ -264,10 +274,15 @@ static void update_all(void) {
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// BG.
|
||||
space_render(dt);
|
||||
planets_render();
|
||||
|
||||
// N
|
||||
pilots_update(dt);
|
||||
|
||||
// FG.
|
||||
player_renderGUI();
|
||||
|
||||
display_fps(dt);
|
||||
|
||||
@ -287,7 +302,8 @@ static void display_fps(const double dt) {
|
||||
fps_dt = fps_cur = 0.;
|
||||
}
|
||||
Vec2 pos;
|
||||
vect_cset(&pos, 10., (double)(gl_screen.h-20));
|
||||
gl_print(NULL, &pos, "%3.2f", fps);
|
||||
vect_csetmin(&pos, 10., (double)(gl_screen.h-20));
|
||||
if(show_fps)
|
||||
gl_print(NULL, &pos, "%3.2f", fps);
|
||||
}
|
||||
|
||||
|
@ -420,6 +420,8 @@ static void gl_fontMakeDList(FT_Face face, char ch, GLuint list_base, GLuint* te
|
||||
|
||||
// End of the display list.
|
||||
glEndList();
|
||||
|
||||
FT_Done_Glyph(glyph);
|
||||
}
|
||||
|
||||
void gl_fontInit(gl_font* font, const char* fname, unsigned int h) {
|
||||
|
@ -25,6 +25,12 @@ void vect_cset(Vec2* v, const double x, const double y) {
|
||||
v->angle = ANGLE(x, y);
|
||||
}
|
||||
|
||||
// Create a minimal vector, only valid for blitting.
|
||||
void vect_csetmin(Vec2* v, const double x, const double y) {
|
||||
v->x = x;
|
||||
v->y = y;
|
||||
}
|
||||
|
||||
// Set the vector value using polar coords.
|
||||
void vect_pset(Vec2* v, const double mod, const double angle) {
|
||||
v->mod = mod;
|
||||
|
@ -20,6 +20,8 @@ typedef struct {
|
||||
|
||||
// Vector manupulation.
|
||||
void vect_cset(Vec2* v, const double x, const double y);
|
||||
// Doesn't set mod nor angle.
|
||||
void vect_csetmin(Vec2* v, const double x, const double y);
|
||||
void vect_pset(Vec2* v, const double mod, const double angle);
|
||||
void vectcpy(Vec2* dest, const Vec2* src);
|
||||
void vectnull(Vec2* v);
|
||||
|
21
src/pilot.c
21
src/pilot.c
@ -14,8 +14,11 @@ static unsigned int pilot_id = 0;
|
||||
static Pilot** pilot_stack;
|
||||
static int pilots = 0;
|
||||
|
||||
// External.
|
||||
extern void ai_destroy(Pilot* p); // Ai.
|
||||
extern void player_think(Pilot* pilot, const double dt); // Player.c
|
||||
extern void ai_think(Pilot* pilot); // Ai.c
|
||||
// Internal.
|
||||
static void pilot_update(Pilot* pilot, const double dt);
|
||||
static void pilot_render(Pilot* pilot);
|
||||
|
||||
@ -110,6 +113,24 @@ unsigned int pilot_create(Ship* ship, char* name, const Vec2* vel, const Vec2* p
|
||||
return dyn->id;
|
||||
}
|
||||
|
||||
// Frees and cleans up a pilot.
|
||||
void pilot_destroy(Pilot* p) {
|
||||
int i;
|
||||
|
||||
solid_free(p->solid);
|
||||
free(p->name);
|
||||
ai_destroy(p);
|
||||
|
||||
for(i = 0; i < pilots; i++)
|
||||
if(pilot_stack[i] == p)
|
||||
break;
|
||||
while(i < pilots) {
|
||||
pilot_stack[i] = pilot_stack[i+1];
|
||||
i++;
|
||||
}
|
||||
free(p);
|
||||
}
|
||||
|
||||
// Free the prisoned pilot!
|
||||
void pilots_free(void) {
|
||||
int i;
|
||||
|
@ -39,6 +39,7 @@ unsigned int pilot_create(Ship* ship, char* name, const Vec2* vel,
|
||||
const Vec2* pos, const int flags);
|
||||
|
||||
// Cleanup.
|
||||
void pilot_destroy(Pilot* p);
|
||||
void pilots_free(void);
|
||||
|
||||
// Update.
|
||||
|
12
src/player.c
12
src/player.c
@ -32,6 +32,17 @@ void player_think(Pilot* player, const double dt) {
|
||||
vect_pset(&player->solid->force, player->ship->thrust * player_acc, player->solid->dir);
|
||||
}
|
||||
|
||||
// ================
|
||||
// GUI!
|
||||
// ================
|
||||
void player_renderGUI(void) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
// ================
|
||||
// INPUT!
|
||||
// ================
|
||||
// Initialization/exit functions (does not assign keys).
|
||||
void input_init(void) {
|
||||
Keybind* tmp;
|
||||
@ -178,6 +189,7 @@ void input_handle(SDL_Event* event) {
|
||||
break;
|
||||
case SDL_JOYBUTTONUP:
|
||||
input_joyup(event->jbutton.button);
|
||||
break;
|
||||
case SDL_KEYDOWN:
|
||||
input_keydown(event->key.keysym.sym);
|
||||
break;
|
||||
|
@ -3,6 +3,9 @@
|
||||
|
||||
typedef enum { KEYBIND_NULL, KEYBIND_KEYBOARD, KEYBIND_JAXIS, KEYBIND_JBUTTON } KeybindType;
|
||||
|
||||
// GUI.
|
||||
void player_renderGUI(void);
|
||||
|
||||
int player_isFlag(unsigned int flag);
|
||||
void player_setFlag(unsigned int flag);
|
||||
void player_rmFlag(unsigned int flag);
|
||||
|
85
src/space.c
85
src/space.c
@ -26,6 +26,13 @@
|
||||
|
||||
#define PLANET_GFX "../gfx/planet/"
|
||||
|
||||
// Overcome warning due to zero value.
|
||||
|
||||
#define FLAG_XSET (1<<0)
|
||||
#define FLAG_YSET (1<<1)
|
||||
#define FLAG_ASTEROIDSSET (1<<2)
|
||||
#define FLAG_INTEFERENCESET (1<<3)
|
||||
|
||||
// Planet types. I didn't take them from Star Trek, I promise.
|
||||
typedef enum {
|
||||
PLANET_CLASS_A, // Geothermal.
|
||||
@ -55,14 +62,14 @@ typedef enum {
|
||||
|
||||
typedef struct {
|
||||
char* name;
|
||||
double x, y; // Position in star system.
|
||||
Vec2 pos; // Position in star system.
|
||||
PlanetClass class;
|
||||
gl_texture* gfx_space; // Graphics in space.
|
||||
} Planet;
|
||||
|
||||
typedef struct {
|
||||
char* name;
|
||||
double x, y; // Position.
|
||||
Vec2 pos; // Position.
|
||||
int stars, asteroids; // Un numero!
|
||||
double interference; // Un uh.. Percentage.
|
||||
|
||||
@ -112,6 +119,9 @@ static Planet* planet_get(const char* name) {
|
||||
Planet* tmp = NULL;
|
||||
|
||||
char str[MAX_PATH_NAME] = "\0";
|
||||
char* tstr;
|
||||
|
||||
uint32_t flags = 0;
|
||||
|
||||
uint32_t bufsize;
|
||||
char* buf = pack_readfile(DATA, PLANET_DATA, &bufsize);
|
||||
@ -133,9 +143,10 @@ static Planet* planet_get(const char* name) {
|
||||
|
||||
do {
|
||||
if(node->type == XML_NODE_START && strcmp((char*)node->name, XML_PLANET_TAG)==0) {
|
||||
if(strcmp((char*)xmlGetProp(node, (xmlChar*)"name"), name)==0) { // Found.
|
||||
tstr = (char*)xmlGetProp(node, (xmlChar*)"name");
|
||||
if(strcmp(tstr, name)==0) { // Found.
|
||||
tmp = CALLOC_L(Planet);
|
||||
tmp->name = strdup(name);
|
||||
tmp->name = tstr;
|
||||
|
||||
node = node->xmlChildrenNode;
|
||||
|
||||
@ -151,10 +162,14 @@ static Planet* planet_get(const char* name) {
|
||||
else if(strcmp((char*)node->name, "pos")==0) {
|
||||
cur = node->children;
|
||||
while((cur = cur->next)) {
|
||||
if(strcmp((char*)cur->name, "x")==0)
|
||||
tmp->x = atof((char*)cur->children->content);
|
||||
else if(strcmp((char*)cur->name, "y")==0)
|
||||
tmp->y = atof((char*)cur->children->content);
|
||||
if(strcmp((char*)cur->name, "x")==0) {
|
||||
flags |= FLAG_XSET;
|
||||
tmp->pos.x = atof((char*)cur->children->content);
|
||||
}
|
||||
else if(strcmp((char*)cur->name, "y")==0) {
|
||||
flags |= FLAG_YSET;
|
||||
tmp->pos.y = atof((char*)cur->children->content);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(strcmp((char*)node->name, "general")==0) {
|
||||
@ -166,7 +181,8 @@ static Planet* planet_get(const char* name) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else
|
||||
free(tstr); // xmlGetProp mallocs the string.
|
||||
}
|
||||
} while((node = node->next));
|
||||
|
||||
@ -176,9 +192,9 @@ static Planet* planet_get(const char* name) {
|
||||
|
||||
// Check elements.
|
||||
if(tmp) {
|
||||
#define MELEMENT(o,s) if(o == 0) WARN("Planet '%s' missing '"s"' element", tmp->name)
|
||||
MELEMENT(tmp->x, "x");
|
||||
MELEMENT(tmp->x, "y");
|
||||
#define MELEMENT(o,s) if((o) == 0) WARN("Planet '%s' missing '"s"' element", tmp->name)
|
||||
MELEMENT(flags&FLAG_XSET, "x");
|
||||
MELEMENT(flags&FLAG_YSET, "y");
|
||||
MELEMENT(tmp->class, "class");
|
||||
#undef MELEMENT
|
||||
} else
|
||||
@ -194,8 +210,10 @@ static StarSystem* system_parse(const xmlNodePtr parent) {
|
||||
StarSystem* tmp = CALLOC_L(StarSystem);
|
||||
xmlNodePtr cur, node;
|
||||
|
||||
tmp->name = strdup((char*) xmlGetProp(parent, (xmlChar*)"name"));
|
||||
|
||||
uint32_t flags;
|
||||
|
||||
tmp->name = (char*)xmlGetProp(parent, (xmlChar*)"name"); // Already mallocs.
|
||||
|
||||
node = parent->xmlChildrenNode;
|
||||
|
||||
while((node = node->next)) {
|
||||
@ -203,21 +221,29 @@ static StarSystem* system_parse(const xmlNodePtr parent) {
|
||||
if(strcmp((char*)node->name, "pos")==0) {
|
||||
cur = node->children;
|
||||
while((cur = cur->next)) {
|
||||
if(strcmp((char*)cur->name, "x")==0)
|
||||
tmp->x = atof((char*)cur->children->content);
|
||||
if(strcmp((char*)cur->name, "y")==0)
|
||||
tmp->y = atof((char*)cur->children->content);
|
||||
if(strcmp((char*)cur->name, "x")==0) {
|
||||
flags |= FLAG_XSET;
|
||||
tmp->pos.x = atof((char*)cur->children->content);
|
||||
}
|
||||
if(strcmp((char*)cur->name, "y")==0) {
|
||||
flags |= FLAG_YSET;
|
||||
tmp->pos.y = atof((char*)cur->children->content);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(strcmp((char*)node->name, "general")==0) {
|
||||
cur = node->children;
|
||||
while((cur = cur->next)) {
|
||||
if(strcmp((char*)cur->name, "stars")==0)
|
||||
if(strcmp((char*)cur->name, "stars")==0) // Non-zero.
|
||||
tmp->stars = atoi((char*)cur->children->content);
|
||||
else if(strcmp((char*)cur->name, "asteroids")==0)
|
||||
else if(strcmp((char*)cur->name, "asteroids")==0) {
|
||||
flags |= FLAG_ASTEROIDSSET;
|
||||
tmp->asteroids = atoi((char*)cur->children->content);
|
||||
else if(strcmp((char*)cur->name, "interference")==0)
|
||||
}
|
||||
else if(strcmp((char*)cur->name, "interference")==0) {
|
||||
flags |= FLAG_INTEFERENCESET;
|
||||
tmp->interference = atof((char*)cur->children->content);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(strcmp((char*)node->name, "planets")==0) {
|
||||
@ -233,12 +259,12 @@ static StarSystem* system_parse(const xmlNodePtr parent) {
|
||||
}
|
||||
}
|
||||
// Check elements.
|
||||
#define MELEMENT(o,s) if(o == 0) WARN("Star System '%s' missing '"s"' element", tmp->name)
|
||||
MELEMENT(tmp->x, "x");
|
||||
MELEMENT(tmp->x, "y");
|
||||
#define MELEMENT(o,s) if((o) == 0) WARN("Star System '%s' missing '"s"' element", tmp->name)
|
||||
MELEMENT(flags&FLAG_XSET, "x");
|
||||
MELEMENT(flags&FLAG_YSET, "y");
|
||||
MELEMENT(tmp->stars, "stars");
|
||||
/*MELEMENT(tmp->asteroids, "asteroids"); // Can be 0.
|
||||
MELEMENT(tmp->interference, "interference");*/
|
||||
MELEMENT(flags&FLAG_ASTEROIDSSET, "asteroids"); // Can be 0.
|
||||
MELEMENT(flags&FLAG_INTEFERENCESET, "inteference");
|
||||
#undef MELEMENT
|
||||
DEBUG("Loaded Star System '%s' with %d Planets%s", tmp->name, tmp->nplanets, (tmp->nplanets > 1) ? "s" : "");
|
||||
|
||||
@ -314,11 +340,8 @@ void space_render(double dt) {
|
||||
void planets_render(void) {
|
||||
int i;
|
||||
Vec2 v;
|
||||
for(i = 0; i < cur_system->nplanets; i++) {
|
||||
v.x = cur_system->planets[i].x;
|
||||
v.y = cur_system->planets[i].y;
|
||||
gl_blitSprite(cur_system->planets[i].gfx_space, &v, 0, 0);
|
||||
}
|
||||
for(i = 0; i < cur_system->nplanets; i++)
|
||||
gl_blitSprite(cur_system->planets[i].gfx_space, &cur_system->planets[i].pos, 0, 0);
|
||||
}
|
||||
|
||||
// Clean up the system.
|
||||
|
Loading…
Reference in New Issue
Block a user