[Change] Optimized ai API some.

[Fix] Few mem leaks.
This commit is contained in:
Allanis 2013-02-04 11:00:32 +00:00
parent f90a2a273c
commit 6a2f07b5b7
12 changed files with 145 additions and 44 deletions

View File

@ -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!

View File

@ -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()

View File

@ -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.

View File

@ -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);
}

View File

@ -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) {

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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.

View File

@ -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;

View File

@ -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);

View File

@ -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.