commit
fc80c1c69f
440
src/ai.c
440
src/ai.c
@ -20,139 +20,139 @@
|
||||
#include "lluadef.h"
|
||||
#include "ai.h"
|
||||
|
||||
// == AI ======================================================
|
||||
//
|
||||
// -- Goal (Task) based AI with additional optimization.
|
||||
// AI uses the goal (task) based AI approach with tasks scripted
|
||||
// in lua. Additionally there is a task that is hardcoded and
|
||||
// obligatory in any AI script. The 'control' task, whose only
|
||||
// purpose is to assign tasks if there is none, and optimize
|
||||
// or change tasks if there are.
|
||||
//
|
||||
// Eg.. Pilot A is attacking Pilot B. Pilot C then comes along
|
||||
// the same system and is of the same faction as Pilot B. and
|
||||
// therefor attacks Pilot A. Pilot A would keep fighting pilot
|
||||
// B and until the control task comes in. Then the pilot could
|
||||
// run if it deems fit that Pilot C and Pilot B together are
|
||||
// both too strong for A. Or.. Attack C as it is an easy target
|
||||
// to finish.
|
||||
// Basically, there is many possibilities, and it's down to the
|
||||
// Lua fanatics to decide what to do.
|
||||
//
|
||||
// -- AI will follow basic tasks defined from Lua AI scripts.
|
||||
// -- If task is NULL, AI will run "control" task.
|
||||
// -- Task is continued every frame.
|
||||
// -- "control" task is a special task that *must* exist in
|
||||
// any given Pilot AI (missiles, and suck will use "seek".
|
||||
// -- "control" task is not permanent, but transitory.
|
||||
// -- "control" task sets another task.
|
||||
// -- "control" task is also run at a set rate (depending on
|
||||
// Lua global "control_rate") to choose optimal behaviour
|
||||
// (task).
|
||||
// ============================================================
|
||||
/* == AI ====================================================== */
|
||||
/* */
|
||||
/* -- Goal (Task) based AI with additional optimization. */
|
||||
/* AI uses the goal (task) based AI approach with tasks scripted */
|
||||
/* in lua. Additionally there is a task that is hardcoded and */
|
||||
/* obligatory in any AI script. The 'control' task, whose only */
|
||||
/* purpose is to assign tasks if there is none, and optimize */
|
||||
/* or change tasks if there are. */
|
||||
/* */
|
||||
/* Eg.. Pilot A is attacking Pilot B. Pilot C then comes along */
|
||||
/* the same system and is of the same faction as Pilot B. and */
|
||||
/* therefor attacks Pilot A. Pilot A would keep fighting pilot */
|
||||
/* B and until the control task comes in. Then the pilot could */
|
||||
/* run if it deems fit that Pilot C and Pilot B together are */
|
||||
/* both too strong for A. Or.. Attack C as it is an easy target */
|
||||
/* to finish. */
|
||||
/* Basically, there is many possibilities, and it's down to the */
|
||||
/* Lua fanatics to decide what to do. */
|
||||
/* */
|
||||
/* -- AI will follow basic tasks defined from Lua AI scripts. */
|
||||
/* -- If task is NULL, AI will run "control" task. */
|
||||
/* -- Task is continued every frame. */
|
||||
/* -- "control" task is a special task that *must* exist in */
|
||||
/* any given Pilot AI (missiles, and suck will use "seek". */
|
||||
/* -- "control" task is not permanent, but transitory. */
|
||||
/* -- "control" task sets another task. */
|
||||
/* -- "control" task is also run at a set rate (depending on */
|
||||
/* Lua global "control_rate") to choose optimal behaviour */
|
||||
/* (task). */
|
||||
/* ============================================================ */
|
||||
|
||||
// Register a number constant n to name s (syntax is just like lua_regfunc).
|
||||
/* Register a number constant n to name s (syntax is just like lua_regfunc). */
|
||||
#define lua_regnumber(l,s,n) (lua_pushnumber(l,n), lua_setglobal(l,s))
|
||||
|
||||
// Ai flags.
|
||||
/* Ai flags. */
|
||||
#define ai_setFlag(f) (pilot_flags |= f)
|
||||
#define ai_isFlag(f) (pilot_flags & f)
|
||||
// Flags.
|
||||
#define AI_PRIMARY (1<<0) // Firing primary weapon.
|
||||
#define AI_SECONDARY (1<<1) // Firing secondary weapon.
|
||||
/* Flags. */
|
||||
#define AI_PRIMARY (1<<0) /* Firing primary weapon. */
|
||||
#define AI_SECONDARY (1<<1) /* Firing secondary weapon. */
|
||||
|
||||
// file info.
|
||||
/* file info. */
|
||||
#define AI_PREFIX "../scripts/ai/"
|
||||
#define AI_SUFFIX ".lua"
|
||||
|
||||
// AI profiles.
|
||||
/* AI profiles. */
|
||||
static AI_Profile* profiles = NULL;
|
||||
static int nprofiles = 0;
|
||||
// Current AI Lua interpreter.
|
||||
/* Current AI Lua interpreter. */
|
||||
static lua_State* L = NULL;
|
||||
|
||||
// Extern pilot hacks.
|
||||
/* Extern pilot hacks. */
|
||||
extern Pilot** pilot_stack;
|
||||
extern int pilots;
|
||||
|
||||
static int ai_minbrakedist(lua_State* L); // Minimal breaking distance.
|
||||
static int ai_accel(lua_State* L); // Accelerate.
|
||||
static int ai_minbrakedist(lua_State* L); /* Minimal breaking distance. */
|
||||
static int ai_accel(lua_State* L); /* Accelerate. */
|
||||
|
||||
// Internal C routines.
|
||||
/* Internal C routines. */
|
||||
static void ai_run(const char* funcname);
|
||||
static int ai_loadProfile(char* filename);
|
||||
static void ai_freetask(Task* t);
|
||||
// External C routines.
|
||||
void ai_attacked(Pilot* attacked, const unsigned int attacker); // weapon.c
|
||||
/* External C routines. */
|
||||
void ai_attacked(Pilot* attacked, const unsigned int attacker); /* weapon.c */
|
||||
void ai_create(Pilot* pilot);
|
||||
// C routines made external.
|
||||
/* C routines made external. */
|
||||
void ai_destroy(Pilot* p);
|
||||
void ai_think(Pilot* pilot);
|
||||
|
||||
// Ai routines for Lua.
|
||||
// Tasks.
|
||||
static int ai_pushtask(lua_State* L); // pushtask(string, number/pointer, number)
|
||||
static int ai_poptask(lua_State* L); // poptask()
|
||||
static int ai_taskname(lua_State* L); // Number taskname.
|
||||
// Consult values.
|
||||
static int ai_gettarget(lua_State* L); // Pointer gettarget()
|
||||
static int ai_gettargetid(lua_State* L); // Number gettargetis()
|
||||
static int ai_getrndpilot(lua_State* L); // Number getrndpilot()
|
||||
static int ai_armour(lua_State* L); // armour()
|
||||
static int ai_shield(lua_State* L); // shield()
|
||||
static int ai_parmour(lua_State* L); // parmour()
|
||||
static int ai_pshield(lua_State* L); // pshield()
|
||||
static int ai_getdistance(lua_State* L); // Number getdist(Vec2)
|
||||
static int ai_getpos(lua_State* L); // getpos(number)
|
||||
static int ai_minbrakedist(lua_State* L); // Number minbrakedist()
|
||||
static int ai_cargofree(lua_State* L); // Number cargofree().
|
||||
// Boolean expressions.
|
||||
static int ai_exists(lua_State* L); // boolean exists
|
||||
static int ai_ismaxvel(lua_State* L); // Boolean ismaxvel()
|
||||
static int ai_isstopped(lua_State* L); // Boolean isstopped()
|
||||
static int ai_isenemy(lua_State* L); // boolean isenemy(number).
|
||||
static int ai_isally(lua_State* L); // boolean isally(number).
|
||||
static int ai_incombat(lua_State* L); // boolean incombat([number])
|
||||
// Movement.
|
||||
static int ai_accel(lua_State* L); // accel(number); nuimber <= 1.
|
||||
static int ai_turn(lua_State* L); // turn(number); abs(number) <= 1.
|
||||
static int ai_face(lua_State* L); // face(number/pointer)
|
||||
static int ai_brake(lua_State* L); // Brake()
|
||||
static int ai_getnearestplanet(lua_State* L); // pointer getnearestplanet()
|
||||
static int ai_getrndplanet(lua_State* L); // pointer getrndplanet()
|
||||
static int ai_hyperspace(lua_State* L); // [number] hyperspace()
|
||||
static int ai_stop(lua_State* L); // stop()
|
||||
// Combat.
|
||||
static int ai_combat(lua_State* L); // combat(number)
|
||||
static int ai_settarget(lua_State* L); // settarget(number)
|
||||
static int ai_secondary(lua_State* L); // string secondary()
|
||||
static int ai_hasturrets(lua_State* L); // bool hasturrets()
|
||||
static int ai_shoot(lua_State* L); // shoot(number) number = 1,2,3.
|
||||
static int ai_getenemy(lua_State* L); // number getenemy().
|
||||
static int ai_hostile(lua_State* L); // hostile(number).
|
||||
// Timers.
|
||||
static int ai_settimer(lua_State* L); // settimer(number, number)
|
||||
static int ai_timeup(lua_State* L); // boolean timeup(number)
|
||||
// Messages.
|
||||
static int ai_comm(lua_State* L); // comm(string)
|
||||
static int ai_broadcast(lua_State* L); // broadcast(string)
|
||||
// Loot.
|
||||
static int ai_credits(lua_State* L); // credits(number).
|
||||
static int ai_cargo(lua_State* L); // cargo(name, quantity).
|
||||
static int ai_shipprice(lua_State* L); // shipprice().
|
||||
/* Ai routines for Lua. */
|
||||
/* Tasks. */
|
||||
static int ai_pushtask(lua_State* L); /* pushtask(string, number/pointer, number) */
|
||||
static int ai_poptask(lua_State* L); /* poptask() */
|
||||
static int ai_taskname(lua_State* L); /* Number taskname. */
|
||||
/* Consult values. */
|
||||
static int ai_gettarget(lua_State* L); /* Pointer gettarget() */
|
||||
static int ai_gettargetid(lua_State* L); /* Number gettargetis() */
|
||||
static int ai_getrndpilot(lua_State* L); /* Number getrndpilot() */
|
||||
static int ai_armour(lua_State* L); /* armour() */
|
||||
static int ai_shield(lua_State* L); /* shield() */
|
||||
static int ai_parmour(lua_State* L); /* parmour() */
|
||||
static int ai_pshield(lua_State* L); /* pshield() */
|
||||
static int ai_getdistance(lua_State* L); /* Number getdist(Vec2) */
|
||||
static int ai_getpos(lua_State* L); /* getpos(number) */
|
||||
static int ai_minbrakedist(lua_State* L); /* Number minbrakedist() */
|
||||
static int ai_cargofree(lua_State* L); /* Number cargofree(). */
|
||||
/* Boolean expressions. */
|
||||
static int ai_exists(lua_State* L); /* boolean exists */
|
||||
static int ai_ismaxvel(lua_State* L); /* Boolean ismaxvel() */
|
||||
static int ai_isstopped(lua_State* L); /* Boolean isstopped() */
|
||||
static int ai_isenemy(lua_State* L); /* boolean isenemy(number). */
|
||||
static int ai_isally(lua_State* L); /* boolean isally(number). */
|
||||
static int ai_incombat(lua_State* L); /* boolean incombat([number]) */
|
||||
/* Movement. */
|
||||
static int ai_accel(lua_State* L); /* accel(number); nuimber <= 1. */
|
||||
static int ai_turn(lua_State* L); /* turn(number); abs(number) <= 1. */
|
||||
static int ai_face(lua_State* L); /* face(number/pointer) */
|
||||
static int ai_brake(lua_State* L); /* Brake() */
|
||||
static int ai_getnearestplanet(lua_State* L); /* pointer getnearestplanet() */
|
||||
static int ai_getrndplanet(lua_State* L); /* pointer getrndplanet() */
|
||||
static int ai_hyperspace(lua_State* L); /* [number] hyperspace() */
|
||||
static int ai_stop(lua_State* L); /* stop() */
|
||||
/* Combat. */
|
||||
static int ai_combat(lua_State* L); /* combat(number) */
|
||||
static int ai_settarget(lua_State* L); /* settarget(number) */
|
||||
static int ai_secondary(lua_State* L); /* string secondary() */
|
||||
static int ai_hasturrets(lua_State* L); /* bool hasturrets() */
|
||||
static int ai_shoot(lua_State* L); /* shoot(number) number = 1,2,3. */
|
||||
static int ai_getenemy(lua_State* L); /* number getenemy(). */
|
||||
static int ai_hostile(lua_State* L); /* hostile(number). */
|
||||
/* Timers. */
|
||||
static int ai_settimer(lua_State* L); /* settimer(number, number) */
|
||||
static int ai_timeup(lua_State* L); /* boolean timeup(number) */
|
||||
/* Messages. */
|
||||
static int ai_comm(lua_State* L); /* comm(string) */
|
||||
static int ai_broadcast(lua_State* L); /* broadcast(string) */
|
||||
/* Loot. */
|
||||
static int ai_credits(lua_State* L); /* credits(number). */
|
||||
static int ai_cargo(lua_State* L); /* cargo(name, quantity). */
|
||||
static int ai_shipprice(lua_State* L); /* shipprice(). */
|
||||
|
||||
static const luaL_Reg ai_methods[] = {
|
||||
// Tasks.
|
||||
/* Tasks. */
|
||||
{ "pushtask", ai_pushtask },
|
||||
{ "poptask", ai_poptask },
|
||||
{ "taskname", ai_taskname },
|
||||
// Sanity checks.
|
||||
/* Sanity checks. */
|
||||
{ "exists", ai_exists },
|
||||
{ "ismaxvel", ai_ismaxvel },
|
||||
{ "isstopped", ai_isstopped },
|
||||
{ "isenemy", ai_isenemy },
|
||||
{ "isally", ai_isally },
|
||||
// Get's.
|
||||
/* Get's. */
|
||||
{ "incombat", ai_incombat },
|
||||
{ "target", ai_gettarget },
|
||||
{ "targetid", ai_gettargetid },
|
||||
@ -167,14 +167,14 @@ static const luaL_Reg ai_methods[] = {
|
||||
{ "cargofree", ai_cargofree },
|
||||
{ "nearestplanet", ai_getnearestplanet },
|
||||
{ "rndplanet", ai_getrndplanet },
|
||||
// Movement.
|
||||
/* Movement. */
|
||||
{ "accel", ai_accel },
|
||||
{ "turn", ai_turn },
|
||||
{ "face", ai_face },
|
||||
{ "brake", ai_brake },
|
||||
{ "stop", ai_stop },
|
||||
{ "hyperspace", ai_hyperspace },
|
||||
// Combat.
|
||||
/* Combat. */
|
||||
{ "combat", ai_combat },
|
||||
{ "settarget", ai_settarget },
|
||||
{ "secondary", ai_secondary },
|
||||
@ -182,55 +182,55 @@ static const luaL_Reg ai_methods[] = {
|
||||
{ "shoot", ai_shoot },
|
||||
{ "getenemy", ai_getenemy },
|
||||
{ "hostile", ai_hostile },
|
||||
// Timers.
|
||||
/* Timers. */
|
||||
{ "settime", ai_settimer },
|
||||
{ "timeup", ai_timeup },
|
||||
// Messages.
|
||||
/* Messages. */
|
||||
{ "comm", ai_comm },
|
||||
{ "broadcast", ai_broadcast },
|
||||
// Loot.
|
||||
/* Loot. */
|
||||
{ "setcredits", ai_credits },
|
||||
{ "setcargo", ai_cargo },
|
||||
{ "shipprice", ai_shipprice },
|
||||
{ 0, 0 } // End.
|
||||
{ 0, 0 } /* End. */
|
||||
};
|
||||
|
||||
// Current pilot "thinking" and assorted variables.
|
||||
/* Current pilot "thinking" and assorted variables. */
|
||||
static Pilot* cur_pilot = NULL;
|
||||
static double pilot_acc = 0.;
|
||||
static double pilot_turn = 0.;
|
||||
static int pilot_flags = 0;
|
||||
static int pilot_target = 0;
|
||||
|
||||
// Ai status: 'Create' functions that can't be used elsewhere.
|
||||
/* Ai status: 'Create' functions that can't be used elsewhere. */
|
||||
#define AI_STATUS_NORMAL 1
|
||||
#define AI_STATUS_CREATE 2
|
||||
static int ai_status = AI_STATUS_NORMAL;
|
||||
|
||||
// Attempt to run a function.
|
||||
/* Attempt to run a function. */
|
||||
static void ai_run(const char* funcname) {
|
||||
lua_getglobal(L, funcname);
|
||||
if(lua_pcall(L, 0, 0, 0))
|
||||
// Errors accured.
|
||||
/* Errors accured. */
|
||||
WARN("Pilot '%s' ai -> '%s' : %s",
|
||||
cur_pilot->name, funcname, lua_tostring(L,-1));
|
||||
}
|
||||
|
||||
// Destroy the AI part of the pilot.
|
||||
/* Destroy the AI part of the pilot. */
|
||||
void ai_destroy(Pilot* p) {
|
||||
if(p->task)
|
||||
ai_freetask(p->task);
|
||||
}
|
||||
|
||||
// Init the AI stuff. Which is basically Lua.
|
||||
/* Init the AI stuff. Which is basically Lua. */
|
||||
int ai_init(void) {
|
||||
char** files;
|
||||
uint32_t nfiles, i;
|
||||
|
||||
// Get the file list.
|
||||
/* Get the file list. */
|
||||
files = pack_listfiles(data, &nfiles);
|
||||
|
||||
// Load the profiles.
|
||||
/* Load the profiles. */
|
||||
for(i = 0; i < nfiles; i++)
|
||||
if((strncmp(files[i], AI_PREFIX, strlen(AI_PREFIX))==0 &&
|
||||
strncmp(files[i] + strlen(files[i]) - strlen(AI_SUFFIX),
|
||||
@ -238,7 +238,7 @@ int ai_init(void) {
|
||||
if(ai_loadProfile(files[i]))
|
||||
WARN("Error loading AI profile '%s'", files[i]);
|
||||
|
||||
// Free the char allocated by pack.
|
||||
/* Free the char allocated by pack. */
|
||||
for(i = 0; i < nfiles; i++)
|
||||
free(files[i]);
|
||||
free(files);
|
||||
@ -248,7 +248,7 @@ int ai_init(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Init an IA_Profile and add it to the stack.
|
||||
/* Init an IA_Profile and add it to the stack. */
|
||||
static int ai_loadProfile(char* filename) {
|
||||
char* buf = NULL;
|
||||
uint32_t bufsize = 0;
|
||||
@ -272,17 +272,17 @@ static int ai_loadProfile(char* filename) {
|
||||
|
||||
L = profiles[nprofiles-1].L;
|
||||
|
||||
// Open the standard Lua libraries.
|
||||
//luaL_openlibs(L);
|
||||
/* Open the standard Lua libraries. */
|
||||
/*luaL_openlibs(L); */
|
||||
|
||||
// Constants.
|
||||
lua_regnumber(L, "player", PLAYER_ID); // Player id.
|
||||
/* Constants. */
|
||||
lua_regnumber(L, "player", PLAYER_ID); /* Player id. */
|
||||
|
||||
// Register C funstions in Lua.
|
||||
/* Register C funstions in Lua. */
|
||||
luaL_register(L, "ai", ai_methods);
|
||||
lua_loadRnd(L);
|
||||
|
||||
// Now load the file, since all the functions have been previously loaded.
|
||||
/* Now load the file, since all the functions have been previously loaded. */
|
||||
buf = pack_readfile(DATA, filename, &bufsize);
|
||||
if(luaL_dobuffer(L, buf, bufsize, filename) != 0) {
|
||||
ERR("loading AI file: %s", filename);
|
||||
@ -296,7 +296,7 @@ static int ai_loadProfile(char* filename) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get the AI_Profile with name.
|
||||
/* Get the AI_Profile with name. */
|
||||
AI_Profile* ai_getProfile(char* name) {
|
||||
if(profiles == NULL) return NULL;
|
||||
|
||||
@ -309,7 +309,7 @@ AI_Profile* ai_getProfile(char* name) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Clean up global AI
|
||||
/* Clean up global AI */
|
||||
void ai_exit(void) {
|
||||
int i;
|
||||
for(i = 0; i < nprofiles; i++) {
|
||||
@ -319,44 +319,44 @@ void ai_exit(void) {
|
||||
free(profiles);
|
||||
}
|
||||
|
||||
// Heart of hearts of the ai!! Brains of the pilot.
|
||||
/* Heart of hearts of the ai!! Brains of the pilot. */
|
||||
void ai_think(Pilot* pilot) {
|
||||
cur_pilot = pilot; // Set current pilot being processed.
|
||||
L = cur_pilot->ai->L; // Set the AI profile to the current pilot's.
|
||||
cur_pilot = pilot; /* Set current pilot being processed. */
|
||||
L = cur_pilot->ai->L; /* Set the AI profile to the current pilot's. */
|
||||
|
||||
// Clean up some variables.
|
||||
/* Clean up some variables. */
|
||||
pilot_acc = 0.;
|
||||
pilot_turn = 0.;
|
||||
pilot_flags = 0;
|
||||
pilot_target = 0;
|
||||
|
||||
// Control function if pilot is idle or tick is up.
|
||||
/* Control function if pilot is idle or tick is up. */
|
||||
if((cur_pilot->tcontrol < SDL_GetTicks()) || (cur_pilot->task == NULL)) {
|
||||
ai_run("control"); // Run control.
|
||||
ai_run("control"); /* Run control. */
|
||||
lua_getglobal(L, "control_rate");
|
||||
cur_pilot->tcontrol = SDL_GetTicks() + 1000*(int)lua_tonumber(L, -1);
|
||||
}
|
||||
if(cur_pilot->task)
|
||||
// Pilot has a currently running task.
|
||||
/* Pilot has a currently running task. */
|
||||
ai_run(cur_pilot->task->name);
|
||||
|
||||
// Make sure pilot_acc and pilot_turn are legal moves.
|
||||
if(pilot_acc > 1.) pilot_acc = 1.; // Value must be <= 1.
|
||||
if(pilot_turn > 1.) pilot_turn = 1.; // Value must be between -1 and 1.
|
||||
/* Make sure pilot_acc and pilot_turn are legal moves. */
|
||||
if(pilot_acc > 1.) pilot_acc = 1.; /* Value must be <= 1. */
|
||||
if(pilot_turn > 1.) pilot_turn = 1.; /* Value must be between -1 and 1. */
|
||||
else if(pilot_turn < -1.) pilot_turn = -1.;
|
||||
|
||||
cur_pilot->solid->dir_vel = 0.;
|
||||
if(pilot_turn) // Set the turning velocity.
|
||||
if(pilot_turn) /* Set the turning velocity. */
|
||||
cur_pilot->solid->dir_vel -= cur_pilot->turn * pilot_turn;
|
||||
vect_pset(&cur_pilot->solid->force, cur_pilot->thrust * pilot_acc,
|
||||
cur_pilot->solid->dir);
|
||||
|
||||
// Fire weapons if needs be.
|
||||
if(ai_isFlag(AI_PRIMARY)) pilot_shoot(pilot, pilot_target, 0); // Primary.
|
||||
if(ai_isFlag(AI_SECONDARY)) pilot_shoot(pilot, pilot_target, 1); // Secondary.
|
||||
/* Fire weapons if needs be. */
|
||||
if(ai_isFlag(AI_PRIMARY)) pilot_shoot(pilot, pilot_target, 0); /* Primary. */
|
||||
if(ai_isFlag(AI_SECONDARY)) pilot_shoot(pilot, pilot_target, 1); /* Secondary. */
|
||||
}
|
||||
|
||||
// Pilot is attacked.
|
||||
/* Pilot is attacked. */
|
||||
void ai_attacked(Pilot* attacked, const unsigned int attacker) {
|
||||
cur_pilot = attacked;
|
||||
L = cur_pilot->ai->L;
|
||||
@ -365,7 +365,7 @@ void ai_attacked(Pilot* attacked, const unsigned int attacker) {
|
||||
lua_pcall(L, 1, 0, 0);
|
||||
}
|
||||
|
||||
// Pilot was just created.
|
||||
/* Pilot was just created. */
|
||||
void ai_create(Pilot* pilot) {
|
||||
cur_pilot = pilot;
|
||||
L = cur_pilot->ai->L;
|
||||
@ -374,28 +374,28 @@ void ai_create(Pilot* pilot) {
|
||||
ai_status = AI_STATUS_NORMAL;
|
||||
}
|
||||
|
||||
// =====================
|
||||
// INTERNAL C FUNCTIONS.
|
||||
// =====================
|
||||
/* ===================== */
|
||||
/* INTERNAL C FUNCTIONS. */
|
||||
/* ===================== */
|
||||
|
||||
// Free the task.
|
||||
/* Free the task. */
|
||||
static void ai_freetask(Task* t) {
|
||||
if(t->next) ai_freetask(t->next); // Woot, recursive freeing!
|
||||
if(t->next) ai_freetask(t->next); /* Woot, recursive freeing! */
|
||||
|
||||
if(t->name) free(t->name);
|
||||
if(t->dtype == TYPE_PTR) free(t->dat.target);
|
||||
free(t);
|
||||
}
|
||||
|
||||
// ========================================================
|
||||
// C functions to call from Lua.
|
||||
// ========================================================
|
||||
/* ======================================================== */
|
||||
/* C functions to call from Lua. */
|
||||
/* ======================================================== */
|
||||
|
||||
// Push the current stack.
|
||||
/* Push the current stack. */
|
||||
static int ai_pushtask(lua_State* L) {
|
||||
int pos;
|
||||
if(lua_isnumber(L, 1)) pos = (int) lua_tonumber(L, 1);
|
||||
else return 0; // Invalid param.
|
||||
else return 0; /* Invalid param. */
|
||||
|
||||
Task* t = MALLOC_L(Task);
|
||||
t->name = (lua_isstring(L, 2)) ? strdup((char*) lua_tostring(L, 2)) : NULL;
|
||||
@ -408,10 +408,10 @@ static int ai_pushtask(lua_State* L) {
|
||||
t->dat.ID = (unsigned int) lua_tonumber(L, 3);
|
||||
}
|
||||
else if(lua_islightuserdata(L, 3)) {
|
||||
// Only pointer valid is Vec2* in Lua.
|
||||
/* Only pointer valid is Vec2* in Lua. */
|
||||
t->dtype = TYPE_PTR;
|
||||
t->dat.target = MALLOC_L(Vec2);
|
||||
// No idea why vectcpy doesn't work here..
|
||||
/* No idea why vectcpy doesn't work here.. */
|
||||
((Vec2*)t->dat.target)->x = ((Vec2*)lua_topointer(L,3))->x;
|
||||
((Vec2*)t->dat.target)->y = ((Vec2*)lua_topointer(L,3))->y;
|
||||
((Vec2*)t->dat.target)->mod = ((Vec2*)lua_topointer(L,3))->mod;
|
||||
@ -420,24 +420,24 @@ static int ai_pushtask(lua_State* L) {
|
||||
t->dtype = TYPE_NULL;
|
||||
}
|
||||
|
||||
if(cur_pilot->task == NULL) // No other tasks.
|
||||
if(cur_pilot->task == NULL) /* No other tasks. */
|
||||
cur_pilot->task = t;
|
||||
else if(pos == 1) {
|
||||
// Put at the end.
|
||||
/* Put at the end. */
|
||||
Task* pointer;
|
||||
for(pointer = cur_pilot->task; pointer->next; pointer = pointer->next);
|
||||
pointer->next = t;
|
||||
} else {
|
||||
// Default put at the beginning.
|
||||
/* Default put at the beginning. */
|
||||
t->next = cur_pilot->task;
|
||||
cur_pilot->task = t;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Pop the current task.
|
||||
/* Pop the current task. */
|
||||
static int ai_poptask(lua_State* L) {
|
||||
(void)L; // Just a hack to avoid -W -Wall warnings.
|
||||
(void)L; /* Just a hack to avoid -W -Wall warnings. */
|
||||
Task* t = cur_pilot->task;
|
||||
cur_pilot->task = t->next;
|
||||
t->next = NULL;
|
||||
@ -445,14 +445,14 @@ static int ai_poptask(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Grab the current tasks name.
|
||||
/* Grab the current tasks name. */
|
||||
static int ai_taskname(lua_State* L) {
|
||||
if(cur_pilot->task) lua_pushstring(L, cur_pilot->task->name);
|
||||
else lua_pushstring(L, "none");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Grab the target pointer.
|
||||
/* Grab the target pointer. */
|
||||
static int ai_gettarget(lua_State* L) {
|
||||
if(cur_pilot->task->dtype == TYPE_PTR) {
|
||||
lua_pushlightuserdata(L, cur_pilot->task->dat.target);
|
||||
@ -461,7 +461,7 @@ static int ai_gettarget(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get the ID.
|
||||
/* Get the ID. */
|
||||
static int ai_gettargetid(lua_State* L) {
|
||||
if(cur_pilot->task->dtype == TYPE_INT) {
|
||||
lua_pushnumber(L, cur_pilot->task->dat.ID);
|
||||
@ -475,7 +475,7 @@ static int ai_getrndpilot(lua_State* L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Get the pilots armour.
|
||||
/* Get the pilots armour. */
|
||||
static int ai_armour(lua_State* L) {
|
||||
double d;
|
||||
|
||||
@ -486,7 +486,7 @@ static int ai_armour(lua_State* L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Get pilots shield.
|
||||
/* Get pilots shield. */
|
||||
static int ai_shield(lua_State* L) {
|
||||
double d;
|
||||
|
||||
@ -497,7 +497,7 @@ static int ai_shield(lua_State* L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Get the pilot's armour in percentage.
|
||||
/* Get the pilot's armour in percentage. */
|
||||
static int ai_parmour(lua_State* L) {
|
||||
double d;
|
||||
Pilot* p;
|
||||
@ -512,7 +512,7 @@ static int ai_parmour(lua_State* L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Get the pilot's shield in percentage.
|
||||
/* Get the pilot's shield in percentage. */
|
||||
static int ai_pshield(lua_State* L) {
|
||||
double d;
|
||||
Pilot* p;
|
||||
@ -528,7 +528,7 @@ static int ai_pshield(lua_State* L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Get the distance from the pointer.
|
||||
/* Get the distance from the pointer. */
|
||||
static int ai_getdistance(lua_State* L) {
|
||||
Vec2* vect;
|
||||
|
||||
@ -539,31 +539,31 @@ static int ai_getdistance(lua_State* L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Get the pilots position.
|
||||
/* Get the pilots position. */
|
||||
static int ai_getpos(lua_State* L) {
|
||||
Pilot* p;
|
||||
if(lua_isnumber(L, 1)) {
|
||||
p = pilot_get((int)lua_tonumber(L,1)); // Pilot ID.
|
||||
p = pilot_get((int)lua_tonumber(L,1)); /* Pilot ID. */
|
||||
if(p == NULL) return 0;
|
||||
}
|
||||
else p = cur_pilot; // Default to ones self.
|
||||
else p = cur_pilot; /* Default to ones self. */
|
||||
|
||||
lua_pushlightuserdata(L, &p->solid->pos);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ========================================================
|
||||
// Get the minimum braking distance.
|
||||
//
|
||||
// Braking vel ==> 0 = v - a*dt
|
||||
// Add turn around time (to initial velocity) :
|
||||
// ==> 180.*360./cur_pilot->turn
|
||||
// Add it to general euler equation x = v*t + 0.5 * a * t^2
|
||||
// Have fun.
|
||||
//
|
||||
// I really hate this function. Why isn't it depricated yet?
|
||||
// ========================================================
|
||||
/* ======================================================== */
|
||||
/* Get the minimum braking distance. */
|
||||
/* */
|
||||
/* Braking vel ==> 0 = v - a*dt */
|
||||
/* Add turn around time (to initial velocity) : */
|
||||
/* ==> 180.*360./cur_pilot->turn */
|
||||
/* Add it to general euler equation x = v*t + 0.5 * a * t^2 */
|
||||
/* Have fun. */
|
||||
/* */
|
||||
/* I really hate this function. Why isn't it depricated yet? */
|
||||
/* ======================================================== */
|
||||
static int ai_minbrakedist(lua_State* L) {
|
||||
double time, dist;
|
||||
time = VMOD(cur_pilot->solid->vel) /
|
||||
@ -572,7 +572,7 @@ static int ai_minbrakedist(lua_State* L) {
|
||||
dist = VMOD(cur_pilot->solid->vel)*0.9*(time+180./cur_pilot->turn) -
|
||||
0.5 * (cur_pilot->thrust / cur_pilot->solid->mass)*time*time;
|
||||
|
||||
lua_pushnumber(L, dist); // return
|
||||
lua_pushnumber(L, dist); /* return */
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -591,19 +591,19 @@ static int ai_exists(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Are we at max velocity?
|
||||
/* Are we at max velocity? */
|
||||
static int ai_ismaxvel(lua_State* L) {
|
||||
lua_pushboolean(L,(VMOD(cur_pilot->solid->vel)>cur_pilot->speed-MIN_VEL_ERR));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Have we stopped?
|
||||
/* Have we stopped? */
|
||||
static int ai_isstopped(lua_State* L) {
|
||||
lua_pushboolean(L, VMOD(cur_pilot->solid->vel) < MIN_VEL_ERR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Check if the pilot is an enemy.
|
||||
/* Check if the pilot is an enemy. */
|
||||
static int ai_isenemy(lua_State* L) {
|
||||
if(lua_isnumber(L,1))
|
||||
lua_pushboolean(L, areEnemies(cur_pilot->faction,
|
||||
@ -611,14 +611,14 @@ static int ai_isenemy(lua_State* L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Check if the pilot is an ally.
|
||||
/* Check if the pilot is an ally. */
|
||||
static int ai_isally(lua_State* L) {
|
||||
lua_pushboolean(L, areAllies(cur_pilot->faction,
|
||||
pilot_get(lua_tonumber(L,1))->faction));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Check to see if the pilot is in combat. Defaults to self.
|
||||
/* Check to see if the pilot is in combat. Defaults to self. */
|
||||
static int ai_incombat(lua_State* L) {
|
||||
Pilot* p;
|
||||
|
||||
@ -629,7 +629,7 @@ static int ai_incombat(lua_State* L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Accelerate the pilot based on a param.
|
||||
/* Accelerate the pilot based on a param. */
|
||||
static int ai_accel(lua_State* L) {
|
||||
double n;
|
||||
|
||||
@ -647,17 +647,17 @@ static int ai_accel(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Turn the pilot based on a param.
|
||||
/* Turn the pilot based on a param. */
|
||||
static int ai_turn(lua_State* L) {
|
||||
LLUA_MIN_ARGS(1);
|
||||
pilot_turn = (lua_isnumber(L, 1)) ? (double)lua_tonumber(L, 1) : 0.;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Face the target.
|
||||
/* Face the target. */
|
||||
static int ai_face(lua_State* L) {
|
||||
LLUA_MIN_ARGS(1);
|
||||
Vec2* v, sv, tv; // Grab the position to face.
|
||||
Vec2* v, sv, tv; /* Grab the position to face. */
|
||||
Pilot* p;
|
||||
double mod, diff;
|
||||
int invert = 0;
|
||||
@ -668,7 +668,7 @@ static int ai_face(lua_State* L) {
|
||||
|
||||
if(n >= 0) {
|
||||
p = pilot_get(n);
|
||||
if(p == NULL) return 0; // Make sure pilot is valid.
|
||||
if(p == NULL) return 0; /* Make sure pilot is valid. */
|
||||
vect_cset(&tv, VX(p->solid->pos) + FACE_WVEL*VX(p->solid->vel),
|
||||
VY(p->solid->pos) + FACE_WVEL*VY(p->solid->vel));
|
||||
v = NULL;
|
||||
@ -682,12 +682,12 @@ static int ai_face(lua_State* L) {
|
||||
VY(cur_pilot->solid->pos) + FACE_WVEL*VY(cur_pilot->solid->vel));
|
||||
|
||||
if(v == NULL)
|
||||
// Target is dynamic.
|
||||
/* Target is dynamic. */
|
||||
diff = angle_diff(cur_pilot->solid->dir,
|
||||
(n==-1) ? VANGLE(sv) :
|
||||
vect_angle(&sv, &tv));
|
||||
else
|
||||
// Target is static.
|
||||
/* Target is static. */
|
||||
diff = angle_diff(cur_pilot->solid->dir,
|
||||
(n==-1) ? VANGLE(cur_pilot->solid->pos) :
|
||||
vect_angle(&cur_pilot->solid->pos, v));
|
||||
@ -699,9 +699,9 @@ static int ai_face(lua_State* L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// This is generally good for coming to a halt.
|
||||
/* This is generally good for coming to a halt. */
|
||||
static int ai_brake(lua_State* L) {
|
||||
(void)L; // Just a hack to avoid -W -Wall warnings.
|
||||
(void)L; /* Just a hack to avoid -W -Wall warnings. */
|
||||
double diff, d;
|
||||
|
||||
d = cur_pilot->solid->dir+M_PI;
|
||||
@ -715,34 +715,34 @@ static int ai_brake(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Return the nearest friendly planet's position to the pilot.
|
||||
/* Return the nearest friendly planet's position to the pilot. */
|
||||
static int ai_getnearestplanet(lua_State* L) {
|
||||
if(cur_system->nplanets == 0) return 0; // No planets.
|
||||
if(cur_system->nplanets == 0) return 0; /* No planets. */
|
||||
|
||||
double dist, d;
|
||||
int i, j;
|
||||
|
||||
// Cycle through planets.
|
||||
/* Cycle through planets. */
|
||||
for(dist = 0., j = -1, i = 0; i < cur_system->nplanets; i++) {
|
||||
d = vect_dist(&cur_system->planets[i].pos, &cur_pilot->solid->pos);
|
||||
if((!areEnemies(cur_pilot->faction, cur_system->planets[i].faction)) &&
|
||||
(d < dist)) {
|
||||
// Closer friendly planet.
|
||||
/* Closer friendly planet. */
|
||||
j = i;
|
||||
dist = d;
|
||||
}
|
||||
}
|
||||
|
||||
// No friendly planet found.
|
||||
/* No friendly planet found. */
|
||||
if(j == -1) return 0;
|
||||
|
||||
lua_pushlightuserdata(L, &cur_system->planets[j].pos);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Return a random friendly planet's position to the pilot.
|
||||
/* Return a random friendly planet's position to the pilot. */
|
||||
static int ai_getrndplanet(lua_State* L) {
|
||||
if(cur_system->nplanets == 0) return 0; // No planets.
|
||||
if(cur_system->nplanets == 0) return 0; /* No planets. */
|
||||
|
||||
Planet** planets;
|
||||
int nplanets, i;
|
||||
@ -754,13 +754,13 @@ static int ai_getrndplanet(lua_State* L) {
|
||||
!areEnemies(cur_pilot->faction, cur_system->planets[i].faction))
|
||||
planets[nplanets++] = &cur_system->planets[i];
|
||||
|
||||
// No planet to land on found.
|
||||
/* No planet to land on found. */
|
||||
if(nplanets == 0) {
|
||||
free(planets);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// We can actually get a random planet now.
|
||||
/* We can actually get a random planet now. */
|
||||
i = RNG(0,nplanets-1);
|
||||
vectcpy(&v, &planets[i]->pos);
|
||||
vect_cadd(&v, RNG(0, planets[i]->gfx_space->sw)-planets[i]->gfx_space->sw/2.,
|
||||
@ -770,7 +770,7 @@ static int ai_getrndplanet(lua_State* L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Attempt to enter the pilot hyperspace. Return the distance if too far away.
|
||||
/* Attempt to enter the pilot hyperspace. Return the distance if too far away. */
|
||||
static int ai_hyperspace(lua_State* L) {
|
||||
int dist;
|
||||
|
||||
@ -781,9 +781,9 @@ static int ai_hyperspace(lua_State* L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Completely stop the pilot if it is below minimum vel error. (No instant stops.)
|
||||
/* Completely stop the pilot if it is below minimum vel error. (No instant stops.) */
|
||||
static int ai_stop(lua_State* L) {
|
||||
(void)L; // Just avoid a gcc warning.
|
||||
(void)L; /* Just avoid a gcc warning. */
|
||||
|
||||
if(VMOD(cur_pilot->solid->vel) < MIN_VEL_ERR)
|
||||
vect_pset(&cur_pilot->solid->vel, 0., 0.);
|
||||
@ -791,7 +791,7 @@ static int ai_stop(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Toggle combat flag. Default is on.
|
||||
/* Toggle combat flag. Default is on. */
|
||||
static int ai_combat(lua_State* L) {
|
||||
int i;
|
||||
|
||||
@ -804,7 +804,7 @@ static int ai_combat(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set the pilots target.
|
||||
/* Set the pilots target. */
|
||||
static int ai_settarget(lua_State* L) {
|
||||
LLUA_MIN_ARGS(1);
|
||||
|
||||
@ -812,7 +812,7 @@ static int ai_settarget(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set the secondary weapon. Biassed towards launchers..
|
||||
/* Set the secondary weapon. Biassed towards launchers.. */
|
||||
static int ai_secondary(lua_State* L) {
|
||||
if(cur_pilot->secondary) {
|
||||
lua_pushstring(L, outfit_getTypeBroad(cur_pilot->secondary->outfit));
|
||||
@ -844,7 +844,7 @@ static int ai_hasturrets(lua_State* L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Pew pew.. Says the pilot.
|
||||
/* Pew pew.. Says the pilot. */
|
||||
static int ai_shoot(lua_State* L) {
|
||||
int n = 1;
|
||||
if(lua_isnumber(L, 1)) n = (int)lua_tonumber(L,1);
|
||||
@ -856,13 +856,13 @@ static int ai_shoot(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get the nearest enemy.
|
||||
/* Get the nearest enemy. */
|
||||
static int ai_getenemy(lua_State* L) {
|
||||
lua_pushnumber(L,pilot_getNearest(cur_pilot));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Set the enemy hostile. (Simply notifies of an impending attack).
|
||||
/* Set the enemy hostile. (Simply notifies of an impending attack). */
|
||||
static int ai_hostile(lua_State* L) {
|
||||
LLUA_MIN_ARGS(1);
|
||||
|
||||
@ -872,11 +872,11 @@ static int ai_hostile(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set the timer.
|
||||
/* Set the timer. */
|
||||
static int ai_settimer(lua_State* L) {
|
||||
LLUA_MIN_ARGS(2);
|
||||
|
||||
int n; // Get the timer.
|
||||
int n; /* Get the timer. */
|
||||
if(lua_isnumber(L, 1)) n = lua_tonumber(L,1);
|
||||
|
||||
cur_pilot->timer[n] = (lua_isnumber(L,2)) ?
|
||||
@ -884,18 +884,18 @@ static int ai_settimer(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check the timer.
|
||||
/* Check the timer. */
|
||||
static int ai_timeup(lua_State* L) {
|
||||
LLUA_MIN_ARGS(1);
|
||||
|
||||
int n; // Get the timer.
|
||||
int n; /* Get the timer. */
|
||||
if(lua_isnumber(L,1)) n = lua_tonumber(L,1);
|
||||
|
||||
lua_pushboolean(L, cur_pilot->timer[n] < SDL_GetTicks());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Have the pilot say something to player.
|
||||
/* Have the pilot say something to player. */
|
||||
static int ai_comm(lua_State* L) {
|
||||
LLUA_MIN_ARGS(2);
|
||||
|
||||
@ -905,7 +905,7 @@ static int ai_comm(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Broadcasts to the entire area.
|
||||
/* Broadcasts to the entire area. */
|
||||
static int ai_broadcast(lua_State* L) {
|
||||
LLUA_MIN_ARGS(1);
|
||||
|
||||
@ -915,7 +915,7 @@ static int ai_broadcast(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set the pilots credits.
|
||||
/* Set the pilots credits. */
|
||||
static int ai_credits(lua_State* L) {
|
||||
LLUA_MIN_ARGS(1);
|
||||
if(ai_status != AI_STATUS_CREATE) return 0;
|
||||
@ -926,7 +926,7 @@ static int ai_credits(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set the pilots cargo.
|
||||
/* Set the pilots cargo. */
|
||||
static int ai_cargo(lua_State* L) {
|
||||
LLUA_MIN_ARGS(2);
|
||||
if(ai_status != AI_STATUS_CREATE) return 0;
|
||||
@ -938,7 +938,7 @@ static int ai_cargo(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get the pilot's ship value.
|
||||
/* Get the pilot's ship value. */
|
||||
static int ai_shipprice(lua_State* L) {
|
||||
lua_pushnumber(L, cur_pilot->ship->price);
|
||||
return 1;
|
||||
|
14
src/ai.h
14
src/ai.h
@ -5,32 +5,32 @@
|
||||
#define MAX_DIR_ERR 0.5*M_PI/180.
|
||||
#define MIN_VEL_ERR 5.0
|
||||
|
||||
#define FACE_WVEL 0.1 // Weight of velocity compared to position to face.
|
||||
#define FACE_WVEL 0.1 /* Weight of velocity compared to position to face. */
|
||||
|
||||
// Max number of AI timers.
|
||||
/* Max number of AI timers. */
|
||||
#define MAX_AI_TIMERS 2
|
||||
|
||||
typedef enum TaskData_ { TYPE_NULL, TYPE_INT, TYPE_PTR } TaskData;
|
||||
|
||||
// Basic task.
|
||||
/* Basic task. */
|
||||
typedef struct Task_ {
|
||||
struct Task_* next;
|
||||
char* name;
|
||||
|
||||
TaskData dtype;
|
||||
union {
|
||||
void* target; // Vec2 etc.
|
||||
unsigned int ID; // Pilot ID etc.
|
||||
void* target; /* Vec2 etc. */
|
||||
unsigned int ID; /* Pilot ID etc. */
|
||||
} dat;
|
||||
} Task;
|
||||
|
||||
// Ai profile.
|
||||
/* Ai profile. */
|
||||
typedef struct AI_Profile_ {
|
||||
char* name;
|
||||
lua_State* L;
|
||||
} AI_Profile;
|
||||
|
||||
// Misc.
|
||||
/* Misc. */
|
||||
AI_Profile* ai_getProfile(char* name);
|
||||
|
||||
int ai_init(void);
|
||||
|
50
src/base64.c
50
src/base64.c
@ -2,9 +2,9 @@
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Encode table - base64 alphabet is defined by the rfc
|
||||
/* Encode table - base64 alphabet is defined by the rfc */
|
||||
static const char cb64[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
// Generate decode table at compile time.
|
||||
/* Generate decode table at compile time. */
|
||||
#define B64(_) \
|
||||
((_) == 'A' ? 0 \
|
||||
: (_) == 'B' ? 1 \
|
||||
@ -72,7 +72,7 @@ static const char cb64[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx
|
||||
: (_) == '/' ? 63 \
|
||||
: -1)
|
||||
|
||||
// Makes it much faster.
|
||||
/* Makes it much faster. */
|
||||
static const signed char cd64[256] = {
|
||||
B64(0), B64(1), B64(2), B64(3),
|
||||
B64(4), B64(5), B64(6), B64(7),
|
||||
@ -140,34 +140,34 @@ static const signed char cd64[256] = {
|
||||
B64(252), B64(253), B64(254), B64(255)
|
||||
};
|
||||
|
||||
// Encode src of sz length storing the new length in len.
|
||||
/* Encode src of sz length storing the new length in len. */
|
||||
char* base64_encode(size_t* len, char* src, size_t sz) {
|
||||
char* r;
|
||||
size_t i, c;
|
||||
uint32_t n;
|
||||
uint8_t ch[4], pad;
|
||||
|
||||
// Create r.
|
||||
/* Create r. */
|
||||
c = sz * 4 / 3 + sz % 3 + 2;
|
||||
c += c / 76;
|
||||
r = malloc(c * sizeof(char));
|
||||
|
||||
// Setup padding.
|
||||
/* Setup padding. */
|
||||
pad = ((sz % 3) == 0) ? 0 : 3 - sz % 3;
|
||||
|
||||
// Time to do the bulk of the work.
|
||||
/* Time to do the bulk of the work. */
|
||||
i = 0;
|
||||
for(c = 0; c < sz; c += 3) {
|
||||
// Specification wants newline after every 76 characters.
|
||||
/* Specification wants newline after every 76 characters. */
|
||||
if((c > 0) && ((c / 3 * 4) % 76 == 0))
|
||||
r[i++] = '\n';
|
||||
|
||||
// n is 24 bits.
|
||||
/* n is 24 bits. */
|
||||
n = (src[c] << 16);
|
||||
n += (c+1<sz) ? (src[c+1] << 8) : 0; // May be out of range.
|
||||
n += (c+2<sz) ? (src[c+2] << 0) : 0; // May be out of range.
|
||||
n += (c+1<sz) ? (src[c+1] << 8) : 0; /* May be out of range. */
|
||||
n += (c+2<sz) ? (src[c+2] << 0) : 0; /* May be out of range. */
|
||||
|
||||
// ch[0-3] are 6 bits each.
|
||||
/* ch[0-3] are 6 bits each. */
|
||||
ch[0] = (n >> 18) & 63;
|
||||
ch[1] = (n >> 12) & 63;
|
||||
ch[2] = (n >> 6) & 63;
|
||||
@ -181,14 +181,14 @@ char* base64_encode(size_t* len, char* src, size_t sz) {
|
||||
|
||||
for(c = 0; c < pad; c++)
|
||||
r[i-c-1] = '=';
|
||||
// It'll be a valid string.
|
||||
/* It'll be a valid string. */
|
||||
r[i] = '\0';
|
||||
(*len) = i;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
// Decode the buffer, same syntax as base64_encode.
|
||||
/* Decode the buffer, same syntax as base64_encode. */
|
||||
#define dec_valid(inp) (cd64[(int)inp] == -1) ? 0 : 1
|
||||
#define dec_ch(inp) cd64[(int)inp]
|
||||
|
||||
@ -197,43 +197,43 @@ char* base64_decode(size_t* len, char* src, size_t sz) {
|
||||
size_t c, i, j;
|
||||
uint32_t n;
|
||||
|
||||
// Allocate r.
|
||||
/* Allocate r. */
|
||||
c = sz * 3 / 4 + 2;
|
||||
r = malloc(c * sizeof(char));
|
||||
|
||||
// Create a clean version of the text.
|
||||
/* Create a clean version of the text. */
|
||||
pad = 0;
|
||||
dat = malloc(sz * sizeof(char));
|
||||
j = 0;
|
||||
for(i = 0; i < sz; i++) {
|
||||
if(src[i] == '=')
|
||||
// Control padding.
|
||||
/* Control padding. */
|
||||
pad++;
|
||||
if(dec_valid(src[i]))
|
||||
// Only allow valid characters.
|
||||
/* Only allow valid characters. */
|
||||
dat[j++] = src[i];
|
||||
}
|
||||
|
||||
// Fill r.
|
||||
/* Fill r. */
|
||||
i = 0;
|
||||
for(c = 0; c < j; c += 4) {
|
||||
// Process the input from base 64.
|
||||
n = dec_ch(dat[c+0]) << 18; // Guaranteed to be valid.
|
||||
n += (c+1<j) ? (dec_ch(dat[c+1]) << 12) : 0; // Check if in bounds.
|
||||
/* Process the input from base 64. */
|
||||
n = dec_ch(dat[c+0]) << 18; /* Guaranteed to be valid. */
|
||||
n += (c+1<j) ? (dec_ch(dat[c+1]) << 12) : 0; /* Check if in bounds. */
|
||||
n += (c+2<j) ? (dec_ch(dat[c+2]) << 6) : 0;
|
||||
n += (c+3<j) ? (dec_ch(dat[c+3]) << 0) : 0;
|
||||
|
||||
// Convert the 24 bits of encoded data into 3 8 bit chunks.
|
||||
/* Convert the 24 bits of encoded data into 3 8 bit chunks. */
|
||||
r[i++] = (n >> 16) & 255;
|
||||
r[i++] = (n >> 8) & 255;
|
||||
r[i++] = (n >> 0) & 255;
|
||||
|
||||
}
|
||||
|
||||
// Cleanup.
|
||||
/* Cleanup. */
|
||||
free(dat);
|
||||
|
||||
(*len) = i - pad; // Must decount the padding.
|
||||
(*len) = i - pad; /* Must decount the padding. */
|
||||
return r;
|
||||
}
|
||||
|
||||
|
24
src/board.c
24
src/board.c
@ -21,7 +21,7 @@ static void board_stealCargo(char* str);
|
||||
static int board_fail(void);
|
||||
static void board_update(void);
|
||||
|
||||
// Attempt to board the players target.
|
||||
/* Attempt to board the players target. */
|
||||
void player_board(void) {
|
||||
Pilot* p;
|
||||
|
||||
@ -52,11 +52,11 @@ void player_board(void) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Pilot will be boarded.
|
||||
/* Pilot will be boarded. */
|
||||
pilot_setFlag(p, PILOT_BOARDED);
|
||||
player_message("Boarding ship %s", p->name);
|
||||
|
||||
// Create the boarding window.
|
||||
/* Create the boarding window. */
|
||||
board_wid = window_create("Boarding", -1, -1, BOARDING_WIDTH, BOARDING_HEIGHT);
|
||||
|
||||
window_addText(board_wid, 20, -30, 120, 60,
|
||||
@ -91,7 +91,7 @@ static void board_stealCreds(char* str) {
|
||||
p = pilot_get(player_target);
|
||||
|
||||
if(p->credits == 0) {
|
||||
// Can't steal from the poor. ;)
|
||||
/* Can't steal from the poor. ;) */
|
||||
player_message("The ship has no SCreds.");
|
||||
return;
|
||||
}
|
||||
@ -100,7 +100,7 @@ static void board_stealCreds(char* str) {
|
||||
|
||||
player->credits += p->credits;
|
||||
p->credits = 0;
|
||||
board_update(); // Update the lack of credits.
|
||||
board_update(); /* Update the lack of credits. */
|
||||
player_message("You manage to steal the ship's Scred.");
|
||||
}
|
||||
|
||||
@ -112,7 +112,7 @@ static void board_stealCargo(char* str) {
|
||||
p = pilot_get(player_target);
|
||||
|
||||
if(p->ncommodities==0) {
|
||||
// No cargo.
|
||||
/* No cargo. */
|
||||
player_message("The ship has no cargo.");
|
||||
return;
|
||||
}
|
||||
@ -123,7 +123,7 @@ static void board_stealCargo(char* str) {
|
||||
|
||||
if(board_fail()) return;
|
||||
|
||||
// Steal as much as possible until full - TODO: Allow the player to choose.
|
||||
/* Steal as much as possible until full - TODO: Allow the player to choose. */
|
||||
q = 1;
|
||||
while((p->ncommodities > 0) && (q != 0)) {
|
||||
q = pilot_addCargo(player, p->commodities[0].commodity,
|
||||
@ -136,30 +136,30 @@ static void board_stealCargo(char* str) {
|
||||
player_message("You manage to steal the ship's cargo.");
|
||||
}
|
||||
|
||||
// Failed to board.
|
||||
/* Failed to board. */
|
||||
static int board_fail(void) {
|
||||
Pilot* p;
|
||||
|
||||
p = pilot_get(player_target);
|
||||
|
||||
// Fail chance.
|
||||
/* Fail chance. */
|
||||
if(RNG(0, 100) > (int)(50. *
|
||||
(10. + (double)p->ship->crew/10.+(double)player->ship->crew)))
|
||||
return 0;
|
||||
|
||||
if(RNG(0, 2)==0) {
|
||||
// 33% of instant death.
|
||||
/* 33% of instant death. */
|
||||
p->armour = -1;
|
||||
player_message("You have tripped the ship's self destruct mechanism!");
|
||||
} else
|
||||
// You just got locked out!!
|
||||
/* You just got locked out!! */
|
||||
player_message("The ship's security system locks you out!");
|
||||
|
||||
board_exit(NULL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Update the cargo and credit fields.
|
||||
/* Update the cargo and credit fields. */
|
||||
static void board_update(void) {
|
||||
int i;
|
||||
char str[128], buf[32];
|
||||
|
@ -2,16 +2,16 @@
|
||||
#include "log.h"
|
||||
#include "collision.h"
|
||||
|
||||
// Collide sprite at (asx, asy) int 'at' at pos 'ap' with sprite at (bsx,bsy)
|
||||
//in 'bt' at 'bp'
|
||||
// at - Texture a.
|
||||
// asx - Position of x of sprite a.
|
||||
// asy - Position of y of sprite a.
|
||||
// ap - Position in space of sprite a.
|
||||
// bt - Texture b.
|
||||
// bsx - Position of x of sprite b.
|
||||
// bsy - Position of y of sprite b.
|
||||
// bp - Position in space of sprite b.
|
||||
/* Collide sprite at (asx, asy) int 'at' at pos 'ap' with sprite at (bsx,bsy) */
|
||||
/*in 'bt' at 'bp' */
|
||||
/* at - Texture a. */
|
||||
/* asx - Position of x of sprite a. */
|
||||
/* asy - Position of y of sprite a. */
|
||||
/* ap - Position in space of sprite a. */
|
||||
/* bt - Texture b. */
|
||||
/* bsx - Position of x of sprite b. */
|
||||
/* bsy - Position of y of sprite b. */
|
||||
/* bp - Position in space of sprite b. */
|
||||
int CollideSprite(const glTexture* at, const int asx, const int asy,
|
||||
const Vec2* ap, const glTexture* bt,
|
||||
const int bsx, const int bsy, const Vec2* bp) {
|
||||
@ -23,33 +23,33 @@ int CollideSprite(const glTexture* at, const int asx, const int asy,
|
||||
int rasy, rbsy;
|
||||
int abx, aby, bbx, bby;
|
||||
|
||||
// a - cube coords.
|
||||
/* a - cube coords. */
|
||||
ax1 = (int)VX(*ap) - (int)(at->sw)/2;
|
||||
ay1 = (int)VY(*ap) - (int)(at->sh)/2;
|
||||
ax2 = ax1 + (int)(at->sw) - 1;
|
||||
ay2 = ay1 + (int)(at->sh) - 1;
|
||||
|
||||
// b - cube coords.
|
||||
/* b - cube coords. */
|
||||
bx1 = (int)VX(*bp) - (int)(bt->sw)/2;
|
||||
by1 = (int)VY(*bp) - (int)(bt->sh)/2;
|
||||
bx2 = bx1 + (int)(bt->sw) - 1;
|
||||
by2 = by1 + (int)(bt->sh) - 1;
|
||||
|
||||
// Check if bounding boxes intersect.
|
||||
/* Check if bounding boxes intersect. */
|
||||
if((bx2 < ax1) || (ax2 < bx1)) return 0;
|
||||
if((by2 < ay1) || (ay2 < by1)) return 0;
|
||||
|
||||
// Define the remaining binding box.
|
||||
/* Define the remaining binding box. */
|
||||
inter_x0 = MAX(ax1, bx1);
|
||||
inter_x1 = MIN(ax2, bx2);
|
||||
inter_y0 = MAX(ay1, by1);
|
||||
inter_y1 = MIN(ay2, by2);
|
||||
|
||||
// Real vertical sprite value (flipped).
|
||||
/* Real vertical sprite value (flipped). */
|
||||
rasy = at->sy - asy - 1;
|
||||
rbsy = bt->sy - bsy - 1;
|
||||
|
||||
// Set up the base points.
|
||||
/* Set up the base points. */
|
||||
abx = asx*(int)(at->sw) - ax1;
|
||||
aby = rasy*(int)(at->sh) - ay1;
|
||||
bbx = bsx*(int)(bt->sw) - bx1;
|
||||
@ -57,7 +57,7 @@ int CollideSprite(const glTexture* at, const int asx, const int asy,
|
||||
|
||||
for(y = inter_y0; y <= inter_y1; y++)
|
||||
for(x = inter_x0; x <= inter_x1; x++)
|
||||
// Compute offsets for surface before passing to TransparentPixel test.
|
||||
/* Compute offsets for surface before passing to TransparentPixel test. */
|
||||
if((!gl_isTrans(at, abx + x, aby + y)) &&
|
||||
(!gl_isTrans(bt, bbx + x, bby + y)))
|
||||
return 1;
|
||||
|
12
src/colour.c
12
src/colour.c
@ -1,6 +1,6 @@
|
||||
#include "colour.h"
|
||||
|
||||
// Default colors.
|
||||
/* Default colors. */
|
||||
glColour cWhite = { .r = 1.00, .g = 1.00, .b = 1.00, .a = 1. };
|
||||
glColour cGrey90 = { .r = 0.90, .g = 0.90, .b = 0.90, .a = 1. };
|
||||
glColour cGrey80 = { .r = 0.80, .g = 0.80, .b = 0.80, .a = 1. };
|
||||
@ -21,21 +21,21 @@ glColour cDarkBlue = { .r = 0.10, .g = 0.20, .b = 0.80, .a = 1. };
|
||||
glColour cBlue = { .r = 0.20, .g = 0.20, .b = 0.80, .a = 1. };
|
||||
glColour cPurple = { .r = 0.90, .g = 0.10, .b = 0.90, .a = 1. };
|
||||
|
||||
// Game specific.
|
||||
/* Game specific. */
|
||||
glColour cConsole = { .r = 0.1, .g = 0.9, .b = 0.1, .a = 1. };
|
||||
glColour cDConsole = { .r = 0.0, .g = 0.7, .b = 0.0, .a = 1. };
|
||||
// Toolkit.
|
||||
/* Toolkit. */
|
||||
glColour cHilight = { .r = 0.1, .g = 0.9, .b = 0.1, .a = 0.3 };
|
||||
// Objects
|
||||
/* Objects */
|
||||
glColour cInert = { .r = 0.6, .g = 0.6, .b = 0.6, .a = 1. };
|
||||
glColour cNeutral = { .r = 0.9, .g = 1.0, .b = 0.3, .a = 1. };
|
||||
glColour cFriend = { .r = 0.0, .g = 1.0, .b = 0.0, .a = 1. };
|
||||
glColour cHostile = { .r = 0.9, .g = 0.2, .b = 0.2, .a = 1. };
|
||||
// Radar
|
||||
/* Radar */
|
||||
glColour cRadar_player = { .r = 0.4, .g = 0.8, .b = 0.4, .a = 1. };
|
||||
glColour cRadar_targ = { .r = 0.0, .g = 0.7, .b = 1.0, .a = 1. };
|
||||
glColour cRadar_weap = { .r = 0.8, .g = 0.2, .b = 0.2, .a = 1. };
|
||||
// Bars.
|
||||
/* Bars. */
|
||||
glColour cShield = { .r = 0.2, .g = 0.2, .b = 0.8, .a = 1. };
|
||||
glColour cArmour = { .r = 0.5, .g = 0.5, .b = 0.5, .a = 1. };
|
||||
glColour cEnergy = { .r = 0.2, .g = 0.8, .b = 0.2, .a = 1. };
|
||||
|
18
src/colour.h
18
src/colour.h
@ -1,17 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
// Colours.
|
||||
/* Colours. */
|
||||
typedef struct glColour_ {
|
||||
double r, g, b, a;
|
||||
} glColour;
|
||||
|
||||
// Default colors.
|
||||
// -- Greyscale.
|
||||
/* Default colors. */
|
||||
/* -- Greyscale. */
|
||||
extern glColour cWhite;
|
||||
#define cGrey cGrey70
|
||||
extern glColour cBlack;
|
||||
|
||||
// Greys
|
||||
/* Greys */
|
||||
extern glColour cGrey90;
|
||||
extern glColour cGrey80;
|
||||
extern glColour cGrey70;
|
||||
@ -30,21 +30,21 @@ extern glColour cDarkBlue;
|
||||
extern glColour cBlue;
|
||||
extern glColour cPurple;
|
||||
|
||||
// Game specific.
|
||||
/* Game specific. */
|
||||
extern glColour cConsole;
|
||||
extern glColour cDConsole;
|
||||
// Toolkit.
|
||||
/* Toolkit. */
|
||||
extern glColour cHilight;
|
||||
// Objects.
|
||||
/* Objects. */
|
||||
extern glColour cInert;
|
||||
extern glColour cNeutral;
|
||||
extern glColour cFriend;
|
||||
extern glColour cHostile;
|
||||
// Radar.
|
||||
/* Radar. */
|
||||
extern glColour cRadar_player;
|
||||
extern glColour cRadar_targ;
|
||||
extern glColour cRadar_weap;
|
||||
// Health.
|
||||
/* Health. */
|
||||
extern glColour cShield;
|
||||
extern glColour cArmour;
|
||||
extern glColour cEnergy;
|
||||
|
64
src/conf.c
64
src/conf.c
@ -44,20 +44,20 @@
|
||||
lua_remove(L, -1); \
|
||||
}
|
||||
|
||||
// Some crap from main.
|
||||
/* 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.
|
||||
/* From player.c */
|
||||
extern const char* keybindNames[]; /* Keybindings. */
|
||||
/* input.c. */
|
||||
extern unsigned int input_afterburnSensibility;
|
||||
|
||||
static void print_usage(char** argv);
|
||||
|
||||
// Print usage.
|
||||
/* Print usage. */
|
||||
static void print_usage(char** argv) {
|
||||
LOG("USAGE: %s [OPTION]", argv[0]);
|
||||
LOG("Options are:");
|
||||
@ -75,35 +75,35 @@ static void print_usage(char** argv) {
|
||||
LOG(" -v - Print the version and exit");
|
||||
}
|
||||
|
||||
// Set the default configuration.
|
||||
/* Set the default configuration. */
|
||||
void conf_setDefaults(void) {
|
||||
// Global.
|
||||
/* Global. */
|
||||
data = DATA_DEF;
|
||||
// GL.
|
||||
/* GL. */
|
||||
gl_screen.w = 800;
|
||||
gl_screen.h = 600;
|
||||
gl_screen.flags = 0;
|
||||
// Openal.
|
||||
/* Openal. */
|
||||
nosound = 0;
|
||||
// Joystick.
|
||||
/* Joystick. */
|
||||
indjoystick = -1;
|
||||
namjoystick = NULL;
|
||||
// Input.
|
||||
/* Input. */
|
||||
input_setDefault();
|
||||
}
|
||||
|
||||
// Ok.. Parse a config file plox.
|
||||
/* Ok.. Parse a config file plox. */
|
||||
int conf_loadConfig(const char* file) {
|
||||
int i = 0;
|
||||
double d = 0.;
|
||||
|
||||
lua_State* L = luaL_newstate();
|
||||
if(luaL_dofile(L, file) == 0) {
|
||||
// Conf file exists indeed.
|
||||
// Global.
|
||||
/* Conf file exists indeed. */
|
||||
/* Global. */
|
||||
conf_loadString("data", data);
|
||||
|
||||
// OpenGL properties..
|
||||
/* OpenGL properties.. */
|
||||
conf_loadInt("width", gl_screen.w);
|
||||
conf_loadInt("height", gl_screen.h);
|
||||
conf_loadBool("fullscreen", i);
|
||||
@ -120,14 +120,14 @@ int conf_loadConfig(const char* file) {
|
||||
conf_loadBool("aa_polygon", i);
|
||||
if(i) { gl_screen.flags |= OPENGL_AA_POLYGON; i = 0; }
|
||||
|
||||
// FPS.
|
||||
/* FPS. */
|
||||
conf_loadBool("showfps", show_fps);
|
||||
conf_loadInt("maxfps", max_fps);
|
||||
|
||||
// Input.
|
||||
/* Input. */
|
||||
conf_loadInt("afterburn", input_afterburnSensibility);
|
||||
|
||||
// Sound.
|
||||
/* Sound. */
|
||||
conf_loadBool("nosound", i);
|
||||
nosound = i; i = 0;
|
||||
conf_loadFloat("sound", d);
|
||||
@ -135,7 +135,7 @@ int conf_loadConfig(const char* file) {
|
||||
conf_loadFloat("music", d);
|
||||
if(d) { music_volume(d); d = 0.; }
|
||||
|
||||
// Joystick.
|
||||
/* Joystick. */
|
||||
lua_getglobal(L, "joystick");
|
||||
if(lua_isnumber(L, -1)) {
|
||||
indjoystick = (int)lua_tonumber(L, -1);
|
||||
@ -146,7 +146,7 @@ int conf_loadConfig(const char* file) {
|
||||
lua_remove(L, -1);
|
||||
}
|
||||
|
||||
// If there are any keybindings. Grab them.
|
||||
/* If there are any keybindings. Grab them. */
|
||||
char* str;
|
||||
int type, key, reverse;
|
||||
for(i = 0; strcmp(keybindNames[i], "end"); i++) {
|
||||
@ -155,26 +155,26 @@ int conf_loadConfig(const char* file) {
|
||||
key = -1;
|
||||
reverse = 0;
|
||||
if(lua_istable(L, -1)) {
|
||||
// It's a gawd damn table!!
|
||||
/* 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);
|
||||
|
||||
// Get the key.
|
||||
/* 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 used for axis.
|
||||
/* Is it reversed? Only used for axis. */
|
||||
lua_pushstring(L, "reverse");
|
||||
lua_gettable(L, -4);
|
||||
if(lua_isnumber(L, -1))
|
||||
reverse = 1;
|
||||
|
||||
if(key != -1 && str != NULL) {
|
||||
// Then the keybind is valid. Get the type.
|
||||
/* 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;
|
||||
@ -183,12 +183,12 @@ int conf_loadConfig(const char* file) {
|
||||
WARN("Unknown keybinding of type %s", str);
|
||||
continue;
|
||||
}
|
||||
// Set the keybind.
|
||||
/* Set the keybind. */
|
||||
input_setKeybind((char*)keybindNames[i], type, key, reverse);
|
||||
} else
|
||||
WARN("Malformed keybind in %s", file);
|
||||
|
||||
// Clean up after table crap.
|
||||
/* Clean up after table crap. */
|
||||
lua_remove(L,-1);
|
||||
lua_remove(L,-1);
|
||||
lua_remove(L,-1);
|
||||
@ -196,7 +196,7 @@ int conf_loadConfig(const char* file) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Failed to load the config file..
|
||||
/* Failed to load the config file.. */
|
||||
DEBUG("Config file '%s' not found.", file);
|
||||
lua_close(L);
|
||||
return 1;
|
||||
@ -205,7 +205,7 @@ int conf_loadConfig(const char* file) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Parse some CLI options.
|
||||
/* Parse some CLI options. */
|
||||
void conf_parseCLI(int argc, char** argv) {
|
||||
static struct option long_options[] = {
|
||||
{ "fullscreen", no_argument, 0, 'f' },
|
||||
@ -262,8 +262,8 @@ void conf_parseCLI(int argc, char** argv) {
|
||||
sound_volume(atof(optarg));
|
||||
break;
|
||||
case 'v':
|
||||
// By now it has already displayed the version.
|
||||
//LOG(APPNAME": version %d.%d.%d", VMAJOR, VMINOR, VREV);
|
||||
/* 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);
|
||||
@ -272,9 +272,9 @@ void conf_parseCLI(int argc, char** argv) {
|
||||
}
|
||||
}
|
||||
|
||||
// Saves the current configuration.
|
||||
/* Saves the current configuration. */
|
||||
int conf_saveConfig(void) {
|
||||
// TODO:
|
||||
/* TODO: */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
// Loading.
|
||||
/* Loading. */
|
||||
void conf_setDefaults(void);
|
||||
int conf_loadConfig(const char* file);
|
||||
void conf_parseCLI(int argc, char** argv);
|
||||
|
||||
// Saving.
|
||||
/* Saving. */
|
||||
int conf_saveConfig(void);
|
||||
|
||||
|
@ -8,19 +8,19 @@
|
||||
#include "log.h"
|
||||
#include "economy.h"
|
||||
|
||||
#define XML_COMMODITY_ID "Commodities" // XML section identifier.
|
||||
#define XML_COMMODITY_ID "Commodities" /* XML section identifier. */
|
||||
#define XML_COMMODITY_TAG "commodity"
|
||||
#define COMMODITY_DATA "../dat/commodity.xml"
|
||||
|
||||
// Commodity stack.
|
||||
/* Commodity stack. */
|
||||
static Commodity* commodity_stack = NULL;
|
||||
static int commodity_nstack = 0;
|
||||
|
||||
static void commodity_freeOne(Commodity* com);
|
||||
static Commodity* commodity_parse(xmlNodePtr parent);
|
||||
|
||||
// Convert credits to a usable string for displaying.
|
||||
// str must have 10 characters allocated.
|
||||
/* Convert credits to a usable string for displaying. */
|
||||
/* str must have 10 characters allocated. */
|
||||
void credits2str(char* str, unsigned int credits, int decimals) {
|
||||
if(decimals < 0)
|
||||
snprintf(str, 32, "%d", credits);
|
||||
@ -33,7 +33,7 @@ void credits2str(char* str, unsigned int credits, int decimals) {
|
||||
else snprintf(str, 16, "%d", credits);
|
||||
}
|
||||
|
||||
// Get a commodity.
|
||||
/* Get a commodity. */
|
||||
Commodity* commodity_get(const char* name) {
|
||||
int i;
|
||||
for(i = 0; i < commodity_nstack; i++)
|
||||
@ -44,7 +44,7 @@ Commodity* commodity_get(const char* name) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Free a commodity.
|
||||
/* Free a commodity. */
|
||||
static void commodity_freeOne(Commodity* com) {
|
||||
if(com->name) free(com->name);
|
||||
if(com->description) free(com->description);
|
||||
@ -70,7 +70,7 @@ static Commodity* commodity_parse(xmlNodePtr parent) {
|
||||
else if(xml_isNode(node, "low"))
|
||||
tmp->low = xml_getInt(node);
|
||||
} while((node = node->next));
|
||||
#if 0 // Let's kill this for now.
|
||||
#if 0 /* Let's kill this for now. */
|
||||
#define MELEMENT(o,s)if(o)WARN("Commodity '%s' missing '"s"' element",tmp->name)
|
||||
MELEMENT(tmp->high==0, "high");
|
||||
MELEMENT(tmp->description==NULL, "description");
|
||||
@ -91,14 +91,14 @@ int commodity_load(void) {
|
||||
|
||||
Commodity* tmp = NULL;
|
||||
|
||||
node = doc->xmlChildrenNode; // Commoditys node.
|
||||
node = doc->xmlChildrenNode; /* Commoditys node. */
|
||||
if(strcmp((char*)node->name, XML_COMMODITY_ID)) {
|
||||
ERR("Malformed "COMMODITY_DATA
|
||||
" file: Missing root element '"XML_COMMODITY_ID"'");
|
||||
return -1;
|
||||
}
|
||||
|
||||
node = node->xmlChildrenNode; // First faction node.
|
||||
node = node->xmlChildrenNode; /* First faction node. */
|
||||
if(node == NULL) {
|
||||
ERR("Malformed "COMMODITY_DATA" file: does not contain elements");
|
||||
return -1;
|
||||
|
@ -3,14 +3,14 @@
|
||||
typedef struct Commodity_ {
|
||||
char* name;
|
||||
char* description;
|
||||
int low, medium, high; // Prices.
|
||||
int low, medium, high; /* Prices. */
|
||||
} Commodity;
|
||||
|
||||
// Commidity stuff.
|
||||
/* Commidity stuff. */
|
||||
Commodity* commodity_get(const char* name);
|
||||
int commodity_load(void);
|
||||
void commodity_free(void);
|
||||
|
||||
// Misc.
|
||||
/* Misc. */
|
||||
void credits2str(char* str, unsigned int credits, int decimals);
|
||||
|
||||
|
122
src/faction.c
122
src/faction.c
@ -7,7 +7,7 @@
|
||||
#include "xml.h"
|
||||
#include "faction.h"
|
||||
|
||||
#define XML_FACTION_ID "Factions" // XML section id.
|
||||
#define XML_FACTION_ID "Factions" /* XML section id. */
|
||||
#define XML_FACTION_TAG "faction"
|
||||
#define XML_ALLIANCE_ID "Alliances"
|
||||
#define XML_ALLIANCE_TAG "alliance"
|
||||
@ -16,9 +16,9 @@
|
||||
|
||||
#define FACTION_DATA "../dat/faction.xml"
|
||||
|
||||
#define PLAYER_ALLY 70 // Above this, player is considered ally.
|
||||
#define PLAYER_ALLY 70 /* Above this, player is considered ally. */
|
||||
|
||||
#define ALLIANCE_OFFSET 27182 // Special offset for alliances.
|
||||
#define ALLIANCE_OFFSET 27182 /* Special offset for alliances. */
|
||||
|
||||
typedef struct Faction_ {
|
||||
char* name;
|
||||
@ -28,33 +28,33 @@ typedef struct Faction_ {
|
||||
int* allies;
|
||||
int nallies;
|
||||
|
||||
int player; // Standing with player - from -100 to 100.
|
||||
int player; /* Standing with player - from -100 to 100. */
|
||||
} Faction;
|
||||
|
||||
static Faction* faction_stack = NULL;
|
||||
static int nfactions = 0;
|
||||
|
||||
// Save alliance.
|
||||
/* Save alliance. */
|
||||
typedef struct Alliance_ {
|
||||
char* name;
|
||||
int* factions;
|
||||
int nfactions;
|
||||
} Alliance;
|
||||
|
||||
// Stack of alliances.
|
||||
/* Stack of alliances. */
|
||||
static Alliance* alliances = NULL;
|
||||
static int nalliances = 0;
|
||||
|
||||
// Static.
|
||||
/* Static. */
|
||||
static Faction* faction_parse(xmlNodePtr parent);
|
||||
static void alliance_parse(xmlNodePtr parent);
|
||||
static void enemies_parse(xmlNodePtr parent);
|
||||
static Alliance* alliance_get(char* name);
|
||||
// Extern.
|
||||
/* Extern. */
|
||||
int pfaction_save(xmlTextWriterPtr writer);
|
||||
int pfaction_load(xmlNodePtr parent);
|
||||
|
||||
// Return the faction of name "name".
|
||||
/* Return the faction of name "name". */
|
||||
int faction_get(const char* name) {
|
||||
int i;
|
||||
for(i = 0; i < nfactions; i++)
|
||||
@ -68,7 +68,7 @@ int faction_get(const char* name) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Return the id of an alliance.
|
||||
/* Return the id of an alliance. */
|
||||
int faction_getAlliance(char* name) {
|
||||
int i;
|
||||
for(i = 0; i < nalliances; i++)
|
||||
@ -85,7 +85,7 @@ char* faction_name(int f) {
|
||||
return faction_stack[f].name;
|
||||
}
|
||||
|
||||
// Return the alliance of name 'name'.
|
||||
/* Return the alliance of name 'name'. */
|
||||
static Alliance* alliance_get(char* name) {
|
||||
int i;
|
||||
for(i = 0; i < nalliances; i++)
|
||||
@ -118,14 +118,14 @@ int faction_getPlayer(int f) {
|
||||
}
|
||||
}
|
||||
|
||||
// Return 1 if Faction a and b are enemies.
|
||||
/* Return 1 if Faction a and b are enemies. */
|
||||
int areEnemies(int a, int b) {
|
||||
Faction* fa, *fb;
|
||||
int i = 0;
|
||||
|
||||
if(a == b) return 0; // Luckily our factions aren't masochistic.
|
||||
if(a == b) return 0; /* Luckily our factions aren't masochistic. */
|
||||
|
||||
// Player handled seperately.
|
||||
/* Player handled seperately. */
|
||||
if(a == FACTION_PLAYER) {
|
||||
if(faction_isFaction(b)) {
|
||||
if(faction_stack[b].player < 0)
|
||||
@ -147,24 +147,24 @@ int areEnemies(int a, int b) {
|
||||
}
|
||||
}
|
||||
|
||||
// Handle a.
|
||||
/* Handle a. */
|
||||
if(faction_isFaction(a)) fa = &faction_stack[a];
|
||||
else {
|
||||
// a isn't valid.
|
||||
/* a isn't valid. */
|
||||
DEBUG("areEnemies: %d is an invalid faction/alliance", a);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Handle b.
|
||||
/* Handle b. */
|
||||
if(faction_isFaction(b)) fb = &faction_stack[b];
|
||||
else {
|
||||
// b isn't valid.
|
||||
/* b isn't valid. */
|
||||
DEBUG("areEnemies: %d is an invalid faction/alliance", b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(fa && fb) {
|
||||
// Both are factions.
|
||||
/* Both are factions. */
|
||||
for(i = 0; i < fa->nenemies; i++)
|
||||
if(fa->enemies[i] == b)
|
||||
return 1;
|
||||
@ -175,12 +175,12 @@ int areEnemies(int a, int b) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Return 1 if Faction a and b are allies.
|
||||
/* Return 1 if Faction a and b are allies. */
|
||||
int areAllies(int a, int b) {
|
||||
Faction* fa, *fb;
|
||||
int i;
|
||||
|
||||
// We assume player becomes allies with high rating.
|
||||
/* We assume player becomes allies with high rating. */
|
||||
if(a == FACTION_PLAYER) {
|
||||
if(faction_isFaction(b)) {
|
||||
if(faction_stack[b].player > PLAYER_ALLY) return 1;
|
||||
@ -200,22 +200,22 @@ int areAllies(int a, int b) {
|
||||
}
|
||||
}
|
||||
|
||||
// D'aww. Player has no allies.
|
||||
/* D'aww. Player has no allies. */
|
||||
if((a == FACTION_PLAYER) || (b == FACTION_PLAYER))
|
||||
return 0;
|
||||
|
||||
// Handle a.
|
||||
/* Handle a. */
|
||||
if(faction_isFaction(a)) fa = &faction_stack[a];
|
||||
else {
|
||||
// b isn't valid.
|
||||
/* b isn't valid. */
|
||||
DEBUG("%d is an invalid faction/alliance", a);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Handle b.
|
||||
/* Handle b. */
|
||||
if(faction_isFaction(b)) fb = &faction_stack[b];
|
||||
else {
|
||||
// b isn't valid.
|
||||
/* b isn't valid. */
|
||||
DEBUG("%d is an invalid faction/alliance", b);
|
||||
return 0;
|
||||
}
|
||||
@ -223,7 +223,7 @@ int areAllies(int a, int b) {
|
||||
if(a == b) return 0;
|
||||
|
||||
if(fa && fb) {
|
||||
// Both are factions.
|
||||
/* Both are factions. */
|
||||
for(i = 0; i < fa->nallies; i++)
|
||||
if(fa->allies[i] == b)
|
||||
return 1;
|
||||
@ -235,7 +235,7 @@ int areAllies(int a, int b) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Is faction f part of alliance a?
|
||||
/* Is faction f part of alliance a? */
|
||||
int faction_ofAlliance(int f, int a) {
|
||||
int i;
|
||||
Alliance* aa;
|
||||
@ -259,7 +259,7 @@ int faction_ofAlliance(int f, int a) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Return true if a s an alliance.
|
||||
/* Return true if a s an alliance. */
|
||||
int faction_isAlliance(int a) {
|
||||
if((a < ALLIANCE_OFFSET) || (a >= ALLIANCE_OFFSET + nalliances))
|
||||
return 0;
|
||||
@ -267,14 +267,14 @@ int faction_isAlliance(int a) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Return true if f is a faction.
|
||||
/* Return true if f is a faction. */
|
||||
int faction_isFaction(int f) {
|
||||
if((f < 0) || (f >= nfactions))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Parses a single faction, but does not set the allies/enemies.
|
||||
/* Parses a single faction, but does not set the allies/enemies. */
|
||||
static Faction* faction_parse(xmlNodePtr parent) {
|
||||
xmlNodePtr node;
|
||||
int player;
|
||||
@ -300,7 +300,7 @@ static Faction* faction_parse(xmlNodePtr parent) {
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// We set allies/enemies here, in the faction_stack.
|
||||
/* We set allies/enemies here, in the faction_stack. */
|
||||
static void alliance_parse(xmlNodePtr parent) {
|
||||
Alliance* a;
|
||||
int* i, j, n, m;
|
||||
@ -312,22 +312,22 @@ static void alliance_parse(xmlNodePtr parent) {
|
||||
do {
|
||||
if((node->type == XML_NODE_START) && (strcmp((char*)node->name,
|
||||
XML_ALLIANCE_TAG)==0)) {
|
||||
// Allocate a new alliance.
|
||||
/* Allocate a new alliance. */
|
||||
alliances = realloc(alliances, sizeof(Alliance)*(++nalliances));
|
||||
alliances[nalliances-1].name = (char*)xmlGetProp(node,(xmlChar*)"name");
|
||||
alliances[nalliances-1].factions = NULL;
|
||||
alliances[nalliances-1].nfactions = 0;
|
||||
|
||||
// Parse the current alliance's allies.
|
||||
/* Parse the current alliance's allies. */
|
||||
cur = node->xmlChildrenNode;
|
||||
do {
|
||||
if(strcmp((char*)cur->name, "ally")==0) {
|
||||
// Add the faction (and pointers to make things simple).
|
||||
/* Add the faction (and pointers to make things simple). */
|
||||
a = alliances + nalliances-1;
|
||||
i = &a->nfactions;
|
||||
(*i)++;
|
||||
|
||||
// Load the faction.
|
||||
/* Load the faction. */
|
||||
a->factions = realloc(a->factions, (*i)*sizeof(int));
|
||||
a->factions[(*i)-1] = faction_get((char*)cur->children->content);
|
||||
|
||||
@ -337,13 +337,13 @@ static void alliance_parse(xmlNodePtr parent) {
|
||||
}
|
||||
} while((cur = cur->next));
|
||||
|
||||
// Set the crap needed by faction_stack.
|
||||
/* Set the crap needed by faction_stack. */
|
||||
for(j = 0; j < (*i); j++) {
|
||||
ft = &faction_stack[a->factions[j]];
|
||||
ft->nallies += (*i)-1;
|
||||
ft->allies = realloc(ft->allies, (ft->nallies)*sizeof(int));
|
||||
for(n = 0, m = 0; n < (*i); n++, m++) {
|
||||
// Add as ally for all factions exept self.
|
||||
/* Add as ally for all factions exept self. */
|
||||
if(n == j) m--;
|
||||
else if(n != j)
|
||||
ft->allies[ft->nallies-(*i)+1+m] = a->factions[n];
|
||||
@ -380,7 +380,7 @@ static void enemies_parse(xmlNodePtr parent) {
|
||||
f = realloc(f, sizeof(int*)*i);
|
||||
|
||||
if(strcmp(type, "alliance")==0) {
|
||||
// Enemy thing is an alliance.
|
||||
/* Enemy thing is an alliance. */
|
||||
a = alliance_get((char*)cur->children->content);
|
||||
if(a == NULL)
|
||||
WARN("Alliance %s not found in stack",
|
||||
@ -389,7 +389,7 @@ static void enemies_parse(xmlNodePtr parent) {
|
||||
f[i-1] = a->factions;
|
||||
}
|
||||
else if(strcmp(type,"faction")==0) {
|
||||
// Enemy thing is only a faction.
|
||||
/* Enemy thing is only a faction. */
|
||||
j[i-1] = 1;
|
||||
f[i-1] = malloc(sizeof(int));
|
||||
f[i-1][0] = faction_get((char*)cur->children->content);
|
||||
@ -400,38 +400,38 @@ static void enemies_parse(xmlNodePtr parent) {
|
||||
free(type);
|
||||
}
|
||||
} while((cur = cur->next));
|
||||
// Now actually parse and load up the enemies.
|
||||
for(n = 0; n < i; n++) { // Unsinged int.
|
||||
for(m = 0; m < j[n]; m++) { // Unsigned int.
|
||||
// Faction.
|
||||
// Add all the faction enemies to nenemies and alloc.
|
||||
/* Now actually parse and load up the enemies. */
|
||||
for(n = 0; n < i; n++) { /* Unsinged int. */
|
||||
for(m = 0; m < j[n]; m++) { /* Unsigned int. */
|
||||
/* Faction. */
|
||||
/* Add all the faction enemies to nenemies and alloc. */
|
||||
for(e = 0, x = 0; x < i; x++)
|
||||
if(x != n) e += j[x]; // Store the total enemies.
|
||||
// Now allocate the memory.
|
||||
if(x != n) e += j[x]; /* Store the total enemies. */
|
||||
/* Now allocate the memory. */
|
||||
ft = &faction_stack[f[n][m]];
|
||||
ft->nenemies += e;
|
||||
ft->enemies = realloc(ft->enemies, sizeof(int)*ft->nenemies);
|
||||
|
||||
// Add the actualy enemies.
|
||||
/* Add the actualy enemies. */
|
||||
for(x = 0, z = 0; x < i; x++)
|
||||
if(x != n)
|
||||
// Make sure it's not from the same group.
|
||||
/* Make sure it's not from the same group. */
|
||||
if(x != n)
|
||||
for(y = 0; y < j[x]; y++, z++)
|
||||
ft->enemies[ft->nenemies-e+z] = f[x][y];
|
||||
}
|
||||
}
|
||||
// Free al the temp memory.
|
||||
/* Free al the temp memory. */
|
||||
for(x = 0; x < i; x++)
|
||||
if(j[x]==1) free(f[x]); // Free the single malloced factions.
|
||||
free(f); // Free the rest.
|
||||
if(j[x]==1) free(f[x]); /* Free the single malloced factions. */
|
||||
free(f); /* Free the rest. */
|
||||
free(j);
|
||||
}
|
||||
} while((node = node->next));
|
||||
}
|
||||
|
||||
|
||||
// Load all the factions.
|
||||
/* Load all the factions. */
|
||||
int factions_load(void) {
|
||||
uint32_t bufsize;
|
||||
char* buf = pack_readfile(DATA, FACTION_DATA, &bufsize);
|
||||
@ -441,19 +441,19 @@ int factions_load(void) {
|
||||
|
||||
Faction* tmp = NULL;
|
||||
|
||||
node = doc->xmlChildrenNode; // Faction node.
|
||||
node = doc->xmlChildrenNode; /* Faction node. */
|
||||
if(!xml_isNode(node, XML_FACTION_ID)) {
|
||||
ERR("Malformed "FACTION_DATA" file: missing root element '"XML_FACTION_ID"'");
|
||||
return -1;
|
||||
}
|
||||
|
||||
node = node->xmlChildrenNode; // First faction node.
|
||||
node = node->xmlChildrenNode; /* First faction node. */
|
||||
if(node == NULL) {
|
||||
ERR("Malformed "FACTION_DATA" file: does not contain elements");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Player faction is hardcoded.
|
||||
/* Player faction is hardcoded. */
|
||||
faction_stack = malloc(sizeof(Faction));
|
||||
faction_stack[0].name = strdup("Player");
|
||||
faction_stack[0].nallies = 0;
|
||||
@ -484,7 +484,7 @@ int factions_load(void) {
|
||||
|
||||
void factions_free(void) {
|
||||
int i;
|
||||
// Free alliances.
|
||||
/* Free alliances. */
|
||||
for(i = 0; i < nalliances; i++) {
|
||||
free(alliances[i].name);
|
||||
free(alliances[i].factions);
|
||||
@ -493,7 +493,7 @@ void factions_free(void) {
|
||||
alliances = NULL;
|
||||
nalliances = 0;
|
||||
|
||||
// Free factions.
|
||||
/* Free factions. */
|
||||
for(i = 0; i < nfactions; i++) {
|
||||
free(faction_stack[i].name);
|
||||
if(faction_stack[i].nallies > 0) free(faction_stack[i].allies);
|
||||
@ -509,17 +509,17 @@ int pfaction_save(xmlTextWriterPtr writer) {
|
||||
|
||||
xmlw_startElem(writer, "factions");
|
||||
|
||||
// Player is faction 0.
|
||||
/* Player is faction 0. */
|
||||
for(i = 1; i < nfactions; i++) {
|
||||
xmlw_startElem(writer, "faction");
|
||||
|
||||
xmlw_attr(writer, "name", "%s", faction_stack[i].name);
|
||||
xmlw_str(writer, "%d", faction_stack[i].player);
|
||||
|
||||
xmlw_endElem(writer); // Faction.
|
||||
xmlw_endElem(writer); /* Faction. */
|
||||
}
|
||||
|
||||
xmlw_endElem(writer); // Faction.
|
||||
xmlw_endElem(writer); /* Faction. */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2,27 +2,27 @@
|
||||
|
||||
#define FACTION_PLAYER 0
|
||||
|
||||
// Get stuff.
|
||||
/* Get stuff. */
|
||||
int faction_get(const char* name);
|
||||
int faction_getAlliance(char* name);
|
||||
char* faction_name(int f);
|
||||
|
||||
// Player stuff.
|
||||
/* Player stuff. */
|
||||
void faction_modPlayer(int f, int mod);
|
||||
int faction_getPlayer(int f);
|
||||
|
||||
// Works with only factions.
|
||||
/* Works with only factions. */
|
||||
int areEnemies(int a, int b);
|
||||
int areAllies(int a, int b);
|
||||
|
||||
// Faction + Alliance.
|
||||
/* Faction + Alliance. */
|
||||
int faction_ofAlliance(int f, int a);
|
||||
|
||||
// Check.
|
||||
/* Check. */
|
||||
int faction_isAlliance(int a);
|
||||
int faction_isFaction(int f);
|
||||
|
||||
// Load/Free.
|
||||
/* Load/Free. */
|
||||
int factions_load(void);
|
||||
void factions_free(void);
|
||||
|
||||
|
186
src/font.c
186
src/font.c
@ -10,19 +10,19 @@
|
||||
|
||||
#define FONT_DEF "../dat/font.ttf"
|
||||
|
||||
// == Font render routines.================================
|
||||
// Use a display list to store ASCII chars rendered with
|
||||
// freefont. There are several drawing methods depending
|
||||
// on whether you want to print it all, to a max width,
|
||||
// print centered or print a block of text.
|
||||
//
|
||||
// There are hardcoded size limits. 256 characters for all
|
||||
// routines exept gl_printText which has a 1024 limit.
|
||||
//
|
||||
// TODO: Check if length is too long.
|
||||
// ========================================================
|
||||
/* == Font render routines.================================ */
|
||||
/* Use a display list to store ASCII chars rendered with */
|
||||
/* freefont. There are several drawing methods depending */
|
||||
/* on whether you want to print it all, to a max width, */
|
||||
/* print centered or print a block of text. */
|
||||
/* */
|
||||
/* There are hardcoded size limits. 256 characters for all */
|
||||
/* routines exept gl_printText which has a 1024 limit. */
|
||||
/* */
|
||||
/* TODO: Check if length is too long. */
|
||||
/* ======================================================== */
|
||||
|
||||
// Default font.
|
||||
/* Default font. */
|
||||
glFont gl_defFont;
|
||||
glFont gl_smallFont;
|
||||
|
||||
@ -32,7 +32,7 @@ static void glFontMakeDList(FT_Face face, char ch,
|
||||
|
||||
static int pot(int n);
|
||||
|
||||
// Get the closest power of two.
|
||||
/* Get the closest power of two. */
|
||||
static int pot(int n) {
|
||||
int i = 1;
|
||||
while(i < n)
|
||||
@ -40,11 +40,11 @@ static int pot(int n) {
|
||||
return i;
|
||||
}
|
||||
|
||||
// Print text on screen! YES!!!! Just like printf! But different!
|
||||
// Defaults ft_font to gl_defFont if NULL.
|
||||
/* Print text on screen! YES!!!! Just like printf! But different! */
|
||||
/* Defaults ft_font to gl_defFont if NULL. */
|
||||
void gl_print(const glFont* ft_font, const double x, const double y,
|
||||
const glColour* c, const char* fmt, ...) {
|
||||
//float h = ft_font->h / .63; // Slightly increases font size.
|
||||
/*float h = ft_font->h / .63; // Slightly increases font size. */
|
||||
char txt[256];
|
||||
va_list ap;
|
||||
|
||||
@ -52,7 +52,7 @@ void gl_print(const glFont* ft_font, const double x, const double y,
|
||||
|
||||
if(fmt == NULL) return;
|
||||
else {
|
||||
// convert the symbols to text.
|
||||
/* convert the symbols to text. */
|
||||
va_start(ap, fmt);
|
||||
vsprintf(txt, fmt, ap);
|
||||
va_end(ap);
|
||||
@ -63,24 +63,24 @@ void gl_print(const glFont* ft_font, const double x, const double y,
|
||||
glListBase(ft_font->list_base);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix(); // Translation matrix.
|
||||
glPushMatrix(); /* Translation matrix. */
|
||||
glTranslated(x - (double)SCREEN_W/2., y - (double)SCREEN_H/2., 0);
|
||||
|
||||
if(c == NULL) glColor4d(1., 1., 1., 1.);
|
||||
else COLOUR(*c);
|
||||
glCallLists(strlen(txt), GL_UNSIGNED_BYTE, &txt);
|
||||
|
||||
glPopMatrix(); // Translation matrix.
|
||||
glPopMatrix(); /* Translation matrix. */
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
gl_checkErr();
|
||||
}
|
||||
|
||||
// Acts just like gl_print, but prints to a max length of max.
|
||||
// Return the amount of characters we had to suppress.
|
||||
/* Acts just like gl_print, but prints to a max length of max. */
|
||||
/* Return the amount of characters we had to suppress. */
|
||||
int gl_printMax(const glFont* ft_font, const int max,
|
||||
const double x, const double y, const glColour* c, const char* fmt, ...) {
|
||||
//float h = ft_font->h / .63; // Slightly increases font size.
|
||||
/*float h = ft_font->h / .63; // Slightly increases font size. */
|
||||
char txt[256];
|
||||
va_list ap;
|
||||
int i, n, len, ret;
|
||||
@ -89,37 +89,37 @@ int gl_printMax(const glFont* ft_font, const int max,
|
||||
|
||||
if(fmt == NULL) return -1;
|
||||
else {
|
||||
// convert the symbols to text.
|
||||
/* convert the symbols to text. */
|
||||
va_start(ap, fmt);
|
||||
vsprintf(txt, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
// Limit the size.
|
||||
/* Limit the size. */
|
||||
len = (int)strlen(txt);
|
||||
for(n = 0, i = 0; i < len; i++) {
|
||||
n += ft_font->w[(int)txt[i]];
|
||||
if(n > max) {
|
||||
ret = len - i; // Difference.
|
||||
ret = len - i; /* Difference. */
|
||||
txt[i] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Display the text.
|
||||
/* Display the text. */
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
glListBase(ft_font->list_base);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW); // Projection gets full fast using modelview.
|
||||
glPushMatrix(); // Translation matrix.
|
||||
glMatrixMode(GL_MODELVIEW); /* Projection gets full fast using modelview. */
|
||||
glPushMatrix(); /* Translation matrix. */
|
||||
glTranslated(x - (double)SCREEN_W/2., y - (double)SCREEN_H/2., 0);
|
||||
|
||||
if(c == NULL) glColor4d(1., 1., 1., 1.);
|
||||
else COLOUR(*c);
|
||||
glCallLists(i, GL_UNSIGNED_BYTE, &txt);
|
||||
|
||||
glPopMatrix(); // Translation matrix.
|
||||
glPopMatrix(); /* Translation matrix. */
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
gl_checkErr();
|
||||
@ -127,33 +127,33 @@ int gl_printMax(const glFont* ft_font, const int max,
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Acts just like gl_printMax, but centers the text in the width.
|
||||
/* Acts just like gl_printMax, but centers the text in the width. */
|
||||
int gl_printMid(const glFont* ft_font, const int width, double x, const double y,
|
||||
const glColour* c, const char* fmt, ...) {
|
||||
//float h = ft_font->h / .63; // Slightly increases font size.
|
||||
/*float h = ft_font->h / .63; // Slightly increases font size. */
|
||||
char txt[256];
|
||||
va_list ap;
|
||||
int i, n, len, ret;
|
||||
|
||||
ret = 0; // Default return value.
|
||||
ret = 0; /* Default return value. */
|
||||
|
||||
if(ft_font == NULL) ft_font = &gl_defFont;
|
||||
|
||||
if(fmt == NULL) return -1;
|
||||
else {
|
||||
// convert the symbols to text.
|
||||
/* convert the symbols to text. */
|
||||
va_start(ap, fmt);
|
||||
vsprintf(txt, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
// Limit the size.
|
||||
/* Limit the size. */
|
||||
len = (int)strlen(txt);
|
||||
for(n = 0, i = 0; i < len; i++) {
|
||||
n += ft_font->w[(int)txt[i]];
|
||||
if(n > width) {
|
||||
ret = len - i; // Difference.
|
||||
n -= ft_font->w[(int)txt[i]]; // Actual size.
|
||||
ret = len - i; /* Difference. */
|
||||
n -= ft_font->w[(int)txt[i]]; /* Actual size. */
|
||||
txt[i] = '\0';
|
||||
break;
|
||||
}
|
||||
@ -161,20 +161,20 @@ int gl_printMid(const glFont* ft_font, const int width, double x, const double y
|
||||
|
||||
x += (double)(width-n)/2.;
|
||||
|
||||
// Display the text.
|
||||
/* Display the text. */
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
glListBase(ft_font->list_base);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW); // Projection gets full fast using modelview.
|
||||
glPushMatrix(); // Translation matrix.
|
||||
glMatrixMode(GL_MODELVIEW); /* Projection gets full fast using modelview. */
|
||||
glPushMatrix(); /* Translation matrix. */
|
||||
glTranslated(x - (double)SCREEN_W/2., y - (double)SCREEN_H/2., 0);
|
||||
|
||||
if(c == NULL) glColor4d(1., 1., 1., 1.);
|
||||
else COLOUR(*c);
|
||||
glCallLists(i, GL_UNSIGNED_BYTE, &txt);
|
||||
|
||||
glPopMatrix(); // Translation matrix.
|
||||
glPopMatrix(); /* Translation matrix. */
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
gl_checkErr();
|
||||
@ -182,24 +182,24 @@ int gl_printMid(const glFont* ft_font, const int width, double x, const double y
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Print text with line breaks included to a max width and height precet.
|
||||
/* Print text with line breaks included to a max width and height precet. */
|
||||
int gl_printText(const glFont* ft_font, const int width, const int height,
|
||||
double bx, double by, glColour* c, const char* fmt, ...) {
|
||||
|
||||
//float h = ft_font->h / .63; // Slightly increase font size.
|
||||
/*float h = ft_font->h / .63; // Slightly increase font size. */
|
||||
char txt[4096];
|
||||
char buf[256];
|
||||
va_list ap;
|
||||
int p, i, j, n, m, len, ret, lastspace;
|
||||
double x, y;
|
||||
|
||||
ret = 0; // Default return value.
|
||||
ret = 0; /* Default return value. */
|
||||
|
||||
if(ft_font == NULL) ft_font = &gl_defFont;
|
||||
|
||||
if(fmt == NULL) return -1;
|
||||
else {
|
||||
// Convert the symbols to text.
|
||||
/* Convert the symbols to text. */
|
||||
va_start(ap, fmt);
|
||||
vsprintf(txt, fmt, ap);
|
||||
va_end(ap);
|
||||
@ -207,22 +207,22 @@ int gl_printText(const glFont* ft_font, const int width, const int height,
|
||||
bx -= (double)SCREEN_W/2.;
|
||||
by -= (double)SCREEN_H/2.;
|
||||
x = bx;
|
||||
y = by + height - (double)ft_font->h; // y is top left corner.
|
||||
y = by + height - (double)ft_font->h; /* y is top left corner. */
|
||||
|
||||
// Prepare opengl.
|
||||
/* Prepare opengl. */
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glListBase(ft_font->list_base);
|
||||
if(c == NULL) glColor4d(1., 1., 1., 1.);
|
||||
else COLOUR(*c);
|
||||
|
||||
len = (int)strlen(txt);
|
||||
// Limit size per line.
|
||||
lastspace = -1; // Last ' ' or \n int text.
|
||||
n = 0; // Current width.
|
||||
i = 0; // Current position.
|
||||
p = -1; // Where we last drew up to.
|
||||
/* Limit size per line. */
|
||||
lastspace = -1; /* Last ' ' or \n int text. */
|
||||
n = 0; /* Current width. */
|
||||
i = 0; /* Current position. */
|
||||
p = -1; /* Where we last drew up to. */
|
||||
while(i < len+1) {
|
||||
if(by - y > (double)height) return len-lastspace; // Past height.
|
||||
if(by - y > (double)height) return len-lastspace; /* Past height. */
|
||||
|
||||
n += ft_font->w[(int)txt[i]];
|
||||
|
||||
@ -231,7 +231,7 @@ int gl_printText(const glFont* ft_font, const int width, const int height,
|
||||
if(((n > width) && ((p != lastspace)))
|
||||
|| (txt[i] == '\n') || (txt[i] == '\0')) {
|
||||
|
||||
// Time to draw the line.
|
||||
/* Time to draw the line. */
|
||||
m = 0;
|
||||
if(lastspace == -1) lastspace = 0;
|
||||
for(j = 0; j < (lastspace-p-1); j++) {
|
||||
@ -243,20 +243,20 @@ int gl_printText(const glFont* ft_font, const int width, const int height,
|
||||
if(m > width) break;
|
||||
buf[j] = txt[p+j+1];
|
||||
}
|
||||
// No need for null termination.
|
||||
/* No need for null termination. */
|
||||
|
||||
glMatrixMode(GL_MODELVIEW); // using modelview, projection gets full fast.
|
||||
glPushMatrix(); // Translation matrix.
|
||||
glMatrixMode(GL_MODELVIEW); /* using modelview, projection gets full fast. */
|
||||
glPushMatrix(); /* Translation matrix. */
|
||||
glTranslated(x, y, 0);
|
||||
|
||||
// This is what we are displaying.
|
||||
/* This is what we are displaying. */
|
||||
glCallLists(j, GL_UNSIGNED_BYTE, &buf);
|
||||
glPopMatrix(); // Translation matrix.
|
||||
glPopMatrix(); /* Translation matrix. */
|
||||
|
||||
p = lastspace;
|
||||
n = 0;
|
||||
i = lastspace;
|
||||
y -= 1.5*(double)ft_font->h; // Move position down.
|
||||
y -= 1.5*(double)ft_font->h; /* Move position down. */
|
||||
}
|
||||
i++;
|
||||
}
|
||||
@ -267,17 +267,17 @@ int gl_printText(const glFont* ft_font, const int width, const int height,
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Get the width of the text about to be printed.
|
||||
/* Get the width of the text about to be printed. */
|
||||
int gl_printWidth(const glFont* ft_font, const char* fmt, ...) {
|
||||
int i, n;
|
||||
char txt[256]; // Holds the string.
|
||||
char txt[256]; /* Holds the string. */
|
||||
va_list ap;
|
||||
|
||||
if(ft_font == NULL) ft_font = &gl_defFont;
|
||||
|
||||
if(fmt == NULL) return 0;
|
||||
else {
|
||||
// Convert the symbols to text.
|
||||
/* Convert the symbols to text. */
|
||||
va_start(ap, fmt);
|
||||
vsprintf(txt, fmt, ap);
|
||||
va_end(ap);
|
||||
@ -292,7 +292,7 @@ int gl_printWidth(const glFont* ft_font, const char* fmt, ...) {
|
||||
int gl_printHeight(const glFont* ft_font, const int width,
|
||||
const char* fmt, ...) {
|
||||
|
||||
char txt[1024]; // Holds the string.
|
||||
char txt[1024]; /* Holds the string. */
|
||||
va_list ap;
|
||||
int p, i, n, len, lastspace;
|
||||
double x, y;
|
||||
@ -301,7 +301,7 @@ int gl_printHeight(const glFont* ft_font, const int width,
|
||||
|
||||
if(fmt == NULL) return -1;
|
||||
else {
|
||||
// Convert the symbols to text.
|
||||
/* Convert the symbols to text. */
|
||||
va_start(ap, fmt);
|
||||
vsprintf(txt, fmt, ap);
|
||||
va_end(ap);
|
||||
@ -310,11 +310,11 @@ int gl_printHeight(const glFont* ft_font, const int width,
|
||||
y = 0.;
|
||||
|
||||
len = (int) strlen(txt);
|
||||
// Limit the size per line.
|
||||
lastspace = -1; // Last ' ' or '\n' in the text.
|
||||
n = 0; // Current width.
|
||||
i = 0; // Current position.
|
||||
p = -1; // Where we last drew up to.
|
||||
/* Limit the size per line. */
|
||||
lastspace = -1; /* Last ' ' or '\n' in the text. */
|
||||
n = 0; /* Current width. */
|
||||
i = 0; /* Current position. */
|
||||
p = -1; /* Where we last drew up to. */
|
||||
|
||||
while(i < len+1) {
|
||||
n += ft_font->w[(int)txt[i]];
|
||||
@ -327,16 +327,16 @@ int gl_printHeight(const glFont* ft_font, const int width,
|
||||
p = lastspace;
|
||||
n = 0;
|
||||
i = lastspace;
|
||||
y += 1.5*(double)ft_font->h; // Move position down.
|
||||
y += 1.5*(double)ft_font->h; /* Move position down. */
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return (int)y;
|
||||
}
|
||||
|
||||
// ================
|
||||
// FONT!
|
||||
// ================
|
||||
/* ================ */
|
||||
/* FONT! */
|
||||
/* ================ */
|
||||
static void glFontMakeDList(FT_Face face, char ch, GLuint list_base,
|
||||
GLuint* tex_base, int* width_base) {
|
||||
FT_Glyph glyph;
|
||||
@ -353,18 +353,18 @@ static void glFontMakeDList(FT_Face face, char ch, GLuint list_base,
|
||||
if(FT_Get_Glyph(face->glyph, &glyph))
|
||||
WARN("FT_Ge_Glyph failed");
|
||||
|
||||
// Convert your glyph to a bitmap.
|
||||
/* Convert your glyph to a bitmap. */
|
||||
FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1);
|
||||
FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph)glyph;
|
||||
|
||||
bitmap = bitmap_glyph->bitmap; // To simplify.
|
||||
bitmap = bitmap_glyph->bitmap; /* To simplify. */
|
||||
|
||||
// Need the POT wrapping for GL.
|
||||
/* Need the POT wrapping for GL. */
|
||||
w = pot(bitmap.width);
|
||||
h = pot(bitmap.rows);
|
||||
|
||||
// Memory for textured data.
|
||||
// Bitmap is useing two channels, one for luminosity and one for alpha.
|
||||
/* Memory for textured data. */
|
||||
/* Bitmap is useing two channels, one for luminosity and one for alpha. */
|
||||
expanded_data = (GLubyte*)malloc(sizeof(GLubyte)*2*w*h + 1);
|
||||
for(j = 0; j < h; j++) {
|
||||
for(i = 0; i < w; i++) {
|
||||
@ -373,28 +373,28 @@ static void glFontMakeDList(FT_Face face, char ch, GLuint list_base,
|
||||
0 : bitmap.buffer[i + bitmap.width*j];
|
||||
}
|
||||
}
|
||||
// Create the GL texture.
|
||||
/* Create the GL texture. */
|
||||
glBindTexture(GL_TEXTURE_2D, tex_base[(int)ch]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_LUMINANCE_ALPHA,
|
||||
GL_UNSIGNED_BYTE, expanded_data);
|
||||
|
||||
free(expanded_data); // No need for this now.
|
||||
free(expanded_data); /* No need for this now. */
|
||||
|
||||
// Create the display lists.
|
||||
/* Create the display lists. */
|
||||
glNewList(list_base+ch, GL_COMPILE);
|
||||
|
||||
// Corrects a spacing flaw between letters and
|
||||
// downwards correction for letters like g or y.
|
||||
/* Corrects a spacing flaw between letters and */
|
||||
/* downwards correction for letters like g or y. */
|
||||
glPushMatrix();
|
||||
glTranslated(bitmap_glyph->left, bitmap_glyph->top-bitmap.rows, 0);
|
||||
|
||||
// Take the opengl POT wrapping into account.
|
||||
/* Take the opengl POT wrapping into account. */
|
||||
x = (double)bitmap.width/(double)w;
|
||||
y = (double)bitmap.rows/(double)h;
|
||||
|
||||
// Draw the texture mapped quad.
|
||||
/* Draw the texture mapped quad. */
|
||||
glBindTexture(GL_TEXTURE_2D, tex_base[(int)ch]);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2d(0, 0);
|
||||
@ -411,7 +411,7 @@ static void glFontMakeDList(FT_Face face, char ch, GLuint list_base,
|
||||
glTranslated(face->glyph->advance.x >> 6, 0,0);
|
||||
width_base[(int)ch] = (int)(face->glyph->advance.x >> 6);
|
||||
|
||||
// End of the display list.
|
||||
/* End of the display list. */
|
||||
glEndList();
|
||||
|
||||
FT_Done_Glyph(glyph);
|
||||
@ -427,7 +427,7 @@ void gl_fontInit(glFont* font, const char* fname, const unsigned int h) {
|
||||
|
||||
FT_Byte* buf = pack_readfile(DATA, (fname) ? fname : FONT_DEF, &bufsize);
|
||||
|
||||
// Allocatagery.
|
||||
/* Allocatagery. */
|
||||
font->textures = malloc(sizeof(GLuint)*128);
|
||||
font->w = malloc(sizeof(int)*128);
|
||||
font->h = (int)h;
|
||||
@ -436,29 +436,29 @@ void gl_fontInit(glFont* font, const char* fname, const unsigned int h) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a FreeType font library.
|
||||
/* Create a FreeType font library. */
|
||||
FT_Library library;
|
||||
if(FT_Init_FreeType(&library)) {
|
||||
WARN("FT_Init_FreeType failed");
|
||||
}
|
||||
|
||||
// Objects that freetype uses to store font info.
|
||||
/* Objects that freetype uses to store font info. */
|
||||
FT_Face face;
|
||||
if(FT_New_Memory_Face(library, buf, bufsize, 0, &face))
|
||||
WARN("FT_New_Memory_Face failed loading library from %s", fname);
|
||||
|
||||
// FreeType is pretty nice and measures using 1/64 of a pixel, therfore expand.
|
||||
/* FreeType is pretty nice and measures using 1/64 of a pixel, therfore expand. */
|
||||
FT_Set_Char_Size(face, h << 6, h << 6, 96, 96);
|
||||
|
||||
// Have OpenGL allocate space for the textures / display lists.
|
||||
/* Have OpenGL allocate space for the textures / display lists. */
|
||||
font->list_base = glGenLists(128);
|
||||
glGenTextures(128, font->textures);
|
||||
|
||||
// Create each of the font display lists.
|
||||
/* Create each of the font display lists. */
|
||||
for(i = 0; i < 128; i++)
|
||||
glFontMakeDList(face, i, font->list_base, font->textures, font->w);
|
||||
|
||||
// We can now free the face and library.
|
||||
/* We can now free the face and library. */
|
||||
FT_Done_Face(face);
|
||||
FT_Done_FreeType(library);
|
||||
free(buf);
|
||||
|
22
src/font.h
22
src/font.h
@ -1,39 +1,39 @@
|
||||
#pragma once
|
||||
#include "opengl.h"
|
||||
|
||||
// Font info.
|
||||
/* Font info. */
|
||||
typedef struct glFont_ {
|
||||
int h; // Height.
|
||||
int h; /* Height. */
|
||||
int* w;
|
||||
GLuint* textures;
|
||||
GLuint list_base;
|
||||
} glFont;
|
||||
|
||||
extern glFont gl_defFont; // Default font.
|
||||
extern glFont gl_smallFont; // Small font.
|
||||
extern glFont gl_defFont; /* Default font. */
|
||||
extern glFont gl_smallFont; /* Small font. */
|
||||
|
||||
// glFont loading/freeing.
|
||||
// If font is NULL it uses the internal default font, same with gl_print
|
||||
/* glFont loading/freeing. */
|
||||
/* If font is NULL it uses the internal default font, same with gl_print */
|
||||
void gl_fontInit(glFont* font, const char* fname, const unsigned int h);
|
||||
void gl_freeFont(glFont* font);
|
||||
|
||||
// Print text.
|
||||
/* Print text. */
|
||||
void gl_print(const glFont* ft_font, const double x, const double y,
|
||||
const glColour* c, const char* fmt, ...);
|
||||
|
||||
// Print text to a max length.
|
||||
/* Print text to a max length. */
|
||||
int gl_printMax(const glFont* ft_font, const int max,
|
||||
const double x, const double y, const glColour* c, const char* fmt, ...);
|
||||
|
||||
// Print text centered in width at x.
|
||||
/* Print text centered in width at x. */
|
||||
int gl_printMid(const glFont* ft_font, const int width,
|
||||
double x, const double y, const glColour* c, const char* fmt, ...);
|
||||
|
||||
// Respects \n -> bx, by is top left position.
|
||||
/* Respects \n -> bx, by is top left position. */
|
||||
int gl_printText(const glFont* ft_font, const int width, const int height,
|
||||
double bx, double by, glColour* c, const char* fmt, ...);
|
||||
|
||||
// Get the width of the text that you wish to print.
|
||||
/* Get the width of the text that you wish to print. */
|
||||
int gl_printWidth(const glFont* ft_font, const char* fmt, ...);
|
||||
|
||||
int gl_printHeight(const glFont* ft_font, const int width,
|
||||
|
68
src/hook.c
68
src/hook.c
@ -6,31 +6,31 @@
|
||||
#include "xml.h"
|
||||
#include "hook.h"
|
||||
|
||||
// The hook.
|
||||
/* The hook. */
|
||||
typedef struct Hook_ {
|
||||
unsigned int id; // Unique id.
|
||||
unsigned int parent; // Mission it's connected to.
|
||||
char* func; // Function returned.
|
||||
char* stack; // Stack it's a part of.
|
||||
unsigned int id; /* Unique id. */
|
||||
unsigned int parent; /* Mission it's connected to. */
|
||||
char* func; /* Function returned. */
|
||||
char* stack; /* Stack it's a part of. */
|
||||
|
||||
int delete; // Indicates it should be deleted when possible.
|
||||
int delete; /* Indicates it should be deleted when possible. */
|
||||
} Hook;
|
||||
|
||||
// The stack.
|
||||
static unsigned int hook_id = 0; // Unique hook id.
|
||||
/* The stack. */
|
||||
static unsigned int hook_id = 0; /* Unique hook id. */
|
||||
static Hook* hook_stack = NULL;
|
||||
static int hook_mstack = 0;
|
||||
static int hook_nstack = 0;
|
||||
static int hook_runningstack = 0; // Check if stack is running.
|
||||
static int hook_runningstack = 0; /* Check if stack is running. */
|
||||
|
||||
// Extern.
|
||||
/* Extern. */
|
||||
extern int misn_run(Mission* misn, char* func);
|
||||
// Intern.
|
||||
/* Intern. */
|
||||
static int hook_run(Hook* hook);
|
||||
static void hook_free(Hook* h);
|
||||
static int hook_needSave(Hook* h);
|
||||
static int hook_parse(xmlNodePtr base);
|
||||
// Extern.
|
||||
/* Extern. */
|
||||
int hook_save(xmlTextWriterPtr writer);
|
||||
int hook_load(xmlNodePtr parent);
|
||||
|
||||
@ -38,38 +38,38 @@ static int hook_run(Hook* hook) {
|
||||
int i;
|
||||
Mission* misn;
|
||||
|
||||
if(hook->delete) return 0; // Hook should be deleted not run.
|
||||
if(hook->delete) return 0; /* Hook should be deleted not run. */
|
||||
|
||||
// Locate the mission.
|
||||
/* Locate the mission. */
|
||||
for(i = 0; i < MISSION_MAX; i++)
|
||||
if(player_missions[i].id == hook->parent)
|
||||
break;
|
||||
if(i >= MISSION_MAX) {
|
||||
WARN("Trying to run hook with parent not in player mission stack: deleting");
|
||||
hook->delete = 1; // So delete it.
|
||||
hook->delete = 1; /* So delete it. */
|
||||
return -1;
|
||||
}
|
||||
misn = &player_missions[i];
|
||||
|
||||
if(misn_run(misn, hook->func) < 0)
|
||||
// Error has accured.
|
||||
/* Error has accured. */
|
||||
WARN("Hook [%s] '%d' -> '%s' failed", hook->stack,
|
||||
hook->id, hook->func);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Add/Remove hooks.
|
||||
/* Add/Remove hooks. */
|
||||
unsigned int hook_add(unsigned int parent, char* func, char* stack) {
|
||||
Hook* new_hook;
|
||||
|
||||
// If the memory must grow.
|
||||
/* If the memory must grow. */
|
||||
if(hook_nstack+1 > hook_mstack) {
|
||||
hook_mstack += 5;
|
||||
hook_stack = realloc(hook_stack, hook_mstack*sizeof(Hook));
|
||||
}
|
||||
|
||||
// Create the new hook.
|
||||
/* Create the new hook. */
|
||||
new_hook = &hook_stack[hook_nstack];
|
||||
new_hook->id = ++hook_id;
|
||||
new_hook->parent = parent;
|
||||
@ -99,14 +99,14 @@ void hook_rm(unsigned int id) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Last hook, just clip the stack.
|
||||
/* Last hook, just clip the stack. */
|
||||
if(m == (hook_nstack-1)) {
|
||||
hook_free(&hook_stack[m]);
|
||||
hook_nstack--;
|
||||
return;
|
||||
}
|
||||
|
||||
// Move it!
|
||||
/* Move it! */
|
||||
memmove(&hook_stack[m], &hook_stack[m+1], sizeof(Hook)*(hook_nstack-(m+1)));
|
||||
hook_nstack--;
|
||||
}
|
||||
@ -120,16 +120,16 @@ void hook_rmParent(unsigned int parent) {
|
||||
}
|
||||
}
|
||||
|
||||
// Run all hooks off the stack.
|
||||
/* Run all hooks off the stack. */
|
||||
int hooks_run(char* stack) {
|
||||
int i;
|
||||
|
||||
hook_runningstack = 1; // Running hooks.
|
||||
hook_runningstack = 1; /* Running hooks. */
|
||||
for(i = 0; i < hook_nstack; i++)
|
||||
if((strcmp(stack, hook_stack[i].stack)==0) && !hook_stack[i].delete) {
|
||||
hook_run(&hook_stack[i]);
|
||||
}
|
||||
hook_runningstack = 0; // Not running hooks anymore.
|
||||
hook_runningstack = 0; /* Not running hooks anymore. */
|
||||
|
||||
for(i = 0; i < hook_nstack; i++)
|
||||
if((strcmp(stack, hook_stack[i].stack)==0) && hook_stack[i].delete) {
|
||||
@ -140,7 +140,7 @@ int hooks_run(char* stack) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Run a single hook by id.
|
||||
/* Run a single hook by id. */
|
||||
void hook_runID(unsigned int id) {
|
||||
int i;
|
||||
|
||||
@ -152,13 +152,13 @@ void hook_runID(unsigned int id) {
|
||||
DEBUG("Attempting to run hook of id '%d' which is not in the stack", id);
|
||||
}
|
||||
|
||||
// Free a hook.
|
||||
/* Free a hook. */
|
||||
static void hook_free(Hook* h) {
|
||||
if(h->func != NULL) free(h->func);
|
||||
if(h->stack != NULL) free(h->stack);
|
||||
}
|
||||
|
||||
// Clean upi after ourselves.
|
||||
/* Clean upi after ourselves. */
|
||||
void hook_cleanup(void) {
|
||||
int i;
|
||||
|
||||
@ -166,12 +166,12 @@ void hook_cleanup(void) {
|
||||
hook_free(&hook_stack[i]);
|
||||
free(hook_stack);
|
||||
hook_stack = NULL;
|
||||
// Sane defaults just in case.
|
||||
/* Sane defaults just in case. */
|
||||
hook_nstack = 0;
|
||||
hook_mstack = 0;
|
||||
}
|
||||
|
||||
// Save the hooks.
|
||||
/* Save the hooks. */
|
||||
static int hook_needSave(Hook* h) {
|
||||
int i;
|
||||
char* nosave[] = { "death", "end" };
|
||||
@ -190,23 +190,23 @@ int hook_save(xmlTextWriterPtr writer) {
|
||||
for(i = 0; i < hook_nstack; i++) {
|
||||
h = &hook_stack[i];
|
||||
|
||||
if(!hook_needSave(h)) continue; // No need to save it.
|
||||
if(!hook_needSave(h)) continue; /* No need to save it. */
|
||||
|
||||
xmlw_startElem(writer, "hook");
|
||||
|
||||
//xmlw_attr(writer, "id", "%u", h->id); // I don't think it's needed.
|
||||
/*xmlw_attr(writer, "id", "%u", h->id); // I don't think it's needed. */
|
||||
xmlw_elem(writer, "parent", "%u", h->parent);
|
||||
xmlw_elem(writer, "func", "%s", h->func);
|
||||
xmlw_elem(writer, "stack", "%s", h->stack);
|
||||
|
||||
xmlw_endElem(writer); // Hook.
|
||||
xmlw_endElem(writer); /* Hook. */
|
||||
}
|
||||
xmlw_endElem(writer); // Hooks.
|
||||
xmlw_endElem(writer); /* Hooks. */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Load hooks for a player.
|
||||
/* Load hooks for a player. */
|
||||
int hook_load(xmlNodePtr parent) {
|
||||
xmlNodePtr node;
|
||||
|
||||
|
26
src/hook.h
26
src/hook.h
@ -1,25 +1,25 @@
|
||||
#pragma once
|
||||
#include "mission.h"
|
||||
|
||||
// Add/Run hooks.
|
||||
/* Add/Run hooks. */
|
||||
unsigned int hook_add(unsigned int parent, char* func, char* stack);
|
||||
void hook_rm(unsigned int id);
|
||||
void hook_rmParent(unsigned int parent);
|
||||
|
||||
// ========================================================
|
||||
// Run Hooks:
|
||||
//
|
||||
// Currently used:
|
||||
// -- "land" - When landed.
|
||||
// -- "takeoff" - When taking off.
|
||||
// -- "jump" - When changing systems.
|
||||
// -- "time" - When time is increment drastically
|
||||
// (hyperspace and taking off.
|
||||
// ========================================================
|
||||
/* ======================================================== */
|
||||
/* Run Hooks: */
|
||||
/* */
|
||||
/* Currently used: */
|
||||
/* -- "land" - When landed. */
|
||||
/* -- "takeoff" - When taking off. */
|
||||
/* -- "jump" - When changing systems. */
|
||||
/* -- "time" - When time is increment drastically */
|
||||
/* (hyperspace and taking off. */
|
||||
/* ======================================================== */
|
||||
|
||||
int hooks_run(char* stack);
|
||||
void hook_runID(unsigned int id); // Runs hook of specific id.
|
||||
void hook_runID(unsigned int id); /* Runs hook of specific id. */
|
||||
|
||||
// Destroy hook.
|
||||
/* Destroy hook. */
|
||||
void hook_cleanup(void);
|
||||
|
||||
|
152
src/input.c
152
src/input.c
@ -11,61 +11,61 @@
|
||||
#define KEY_PRESS ( 1.)
|
||||
#define KEY_RELEASE (-1.)
|
||||
|
||||
// Keybind structure.
|
||||
/* Keybind structure. */
|
||||
typedef struct Keybind_ {
|
||||
char* name; // Keybinding name, taken from keybindNames[]
|
||||
KeybindType type; // type, defined in player.h.
|
||||
unsigned int key; // Key/axis/button event number.
|
||||
double reverse; // 1. if normal, -1 if reversed, only useful for joystick axis.
|
||||
char* name; /* Keybinding name, taken from keybindNames[] */
|
||||
KeybindType type; /* type, defined in player.h. */
|
||||
unsigned int key; /* Key/axis/button event number. */
|
||||
double reverse; /* 1. if normal, -1 if reversed, only useful for joystick axis. */
|
||||
} Keybind;
|
||||
|
||||
static Keybind** input_keybinds; // Contains the players keybindings.
|
||||
static Keybind** input_keybinds; /* Contains the players keybindings. */
|
||||
|
||||
|
||||
// Name of each keybinding.
|
||||
/* Name of each keybinding. */
|
||||
const char* keybindNames[] = {
|
||||
"accel", "left", "right", "reverse", // Movement.
|
||||
"primary", "target", "target_nearest", "face", "board", // Combat.
|
||||
"secondary", "secondary_next", // Secondary weapons.
|
||||
"target_planet", "land", "thyperspace","starmap", "jump", // Navigation.
|
||||
"mapzoomin", "mapzoomout", "screenshot", "pause", "menu", "info", // Misc.
|
||||
"end" }; // Must terminate at the end.
|
||||
"accel", "left", "right", "reverse", /* Movement. */
|
||||
"primary", "target", "target_nearest", "face", "board", /* Combat. */
|
||||
"secondary", "secondary_next", /* Secondary weapons. */
|
||||
"target_planet", "land", "thyperspace","starmap", "jump", /* Navigation. */
|
||||
"mapzoomin", "mapzoomout", "screenshot", "pause", "menu", "info", /* Misc. */
|
||||
"end" }; /* Must terminate at the end. */
|
||||
|
||||
// Accel hacks.
|
||||
static unsigned int input_accelLast = 0; // Used to see if double tap.
|
||||
unsigned int input_afterburnSensibility = 500; // ms between taps to afterburn.
|
||||
/* Accel hacks. */
|
||||
static unsigned int input_accelLast = 0; /* Used to see if double tap. */
|
||||
unsigned int input_afterburnSensibility = 500; /* ms between taps to afterburn. */
|
||||
|
||||
// From player.c
|
||||
/* From player.c */
|
||||
extern double player_turn;
|
||||
extern unsigned int player_target;
|
||||
// Grabbed from main.c
|
||||
/* Grabbed from main.c */
|
||||
extern int show_fps;
|
||||
|
||||
|
||||
// Set the default input keys.
|
||||
/* Set the default input keys. */
|
||||
void input_setDefault(void) {
|
||||
// Movement.
|
||||
/* Movement. */
|
||||
input_setKeybind("accel", KEYBIND_KEYBOARD, SDLK_w, 0);
|
||||
input_setKeybind("left", KEYBIND_KEYBOARD, SDLK_a, 0);
|
||||
input_setKeybind("right", KEYBIND_KEYBOARD, SDLK_d, 0);
|
||||
input_setKeybind("reverse", KEYBIND_KEYBOARD, SDLK_s, 0);
|
||||
// Combat.
|
||||
/* Combat. */
|
||||
input_setKeybind("primary", KEYBIND_KEYBOARD, SDLK_SPACE, 0);
|
||||
input_setKeybind("target", KEYBIND_KEYBOARD, SDLK_TAB, 0);
|
||||
input_setKeybind("target_nearest", KEYBIND_KEYBOARD, SDLK_r, 0);
|
||||
input_setKeybind("face", KEYBIND_KEYBOARD, SDLK_f, 0);
|
||||
input_setKeybind("board", KEYBIND_KEYBOARD, SDLK_b, 0);
|
||||
// Secondary weapon.
|
||||
/* Secondary weapon. */
|
||||
input_setKeybind("secondary", KEYBIND_KEYBOARD, SDLK_LSHIFT, 0);
|
||||
input_setKeybind("secondary_next", KEYBIND_KEYBOARD, SDLK_e, 0);
|
||||
// Space
|
||||
/* Space */
|
||||
input_setKeybind("target_planet", KEYBIND_KEYBOARD, SDLK_p, 0);
|
||||
input_setKeybind("land", KEYBIND_KEYBOARD, SDLK_l, 0);
|
||||
input_setKeybind("thyperspace", KEYBIND_KEYBOARD, SDLK_h, 0);
|
||||
input_setKeybind("starmap", KEYBIND_KEYBOARD, SDLK_m, 0);
|
||||
input_setKeybind("jump", KEYBIND_KEYBOARD, SDLK_j, 0);
|
||||
|
||||
// Misc.
|
||||
/* Misc. */
|
||||
input_setKeybind("mapzoomin", KEYBIND_KEYBOARD, SDLK_0, 0);
|
||||
input_setKeybind("mapzoomout", KEYBIND_KEYBOARD, SDLK_9, 0);
|
||||
input_setKeybind("screenshot", KEYBIND_KEYBOARD, SDLK_F12, 0);
|
||||
@ -74,14 +74,14 @@ void input_setDefault(void) {
|
||||
input_setKeybind("info", KEYBIND_KEYBOARD, SDLK_i, 0);
|
||||
}
|
||||
|
||||
// Initialization/exit functions (does not assign keys).
|
||||
/* Initialization/exit functions (does not assign keys). */
|
||||
void input_init(void) {
|
||||
Keybind* tmp;
|
||||
int i;
|
||||
for(i = 0; strcmp(keybindNames[i], "end"); i++); // Get number of bindings.
|
||||
for(i = 0; strcmp(keybindNames[i], "end"); i++); /* Get number of bindings. */
|
||||
input_keybinds = malloc(i*sizeof(Keybind*));
|
||||
|
||||
// Create a null keybinding for each.
|
||||
/* Create a null keybinding for each. */
|
||||
for(i = 0; strcmp(keybindNames[i], "end"); i++) {
|
||||
tmp = MALLOC_L(Keybind);
|
||||
tmp->name = (char*)keybindNames[i];
|
||||
@ -99,7 +99,7 @@ void input_exit(void) {
|
||||
free(input_keybinds);
|
||||
}
|
||||
|
||||
// Binds key of type [type] to action keybind.
|
||||
/* Binds key of type [type] to action keybind. */
|
||||
void input_setKeybind(char* keybind, KeybindType type, int key, int reverse) {
|
||||
int i;
|
||||
for(i = 0; strcmp(keybindNames[i], "end"); i++)
|
||||
@ -112,7 +112,7 @@ void input_setKeybind(char* keybind, KeybindType type, int key, int reverse) {
|
||||
WARN("Unable to set keybind '%s', That command does not exist.", keybind);
|
||||
}
|
||||
|
||||
// Get the value of a keybind.
|
||||
/* Get the value of a keybind. */
|
||||
int input_getKeybind(char* keybind, KeybindType* type, int* reverse) {
|
||||
int i;
|
||||
for(i = 0; strcmp(keybindNames[i], "end"); i++)
|
||||
@ -126,14 +126,14 @@ int input_getKeybind(char* keybind, KeybindType* type, int* reverse) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// == Run input method. ================================================
|
||||
// keynum : Index of the input_keybinds keybind.
|
||||
// value : Value of keypress (defined above).
|
||||
// abs : Whether or not it's an abs value (For those pesky joysticks.
|
||||
// =====================================================================
|
||||
/* == Run input method. ================================================ */
|
||||
/* keynum : Index of the input_keybinds keybind. */
|
||||
/* value : Value of keypress (defined above). */
|
||||
/* abs : Whether or not it's an abs value (For those pesky joysticks. */
|
||||
/* ===================================================================== */
|
||||
#define KEY(s) (strcmp(input_keybinds[keynum]->name, s)==0)
|
||||
#define INGAME() (!toolkit)
|
||||
// We won't be having any more funny stuff from VLack..
|
||||
/* We won't be having any more funny stuff from VLack.. */
|
||||
#define NOHYP() \
|
||||
(player && !pilot_isFlag(player, PILOT_HYP_PREP) && \
|
||||
!pilot_isFlag(player, PILOT_HYP_BEGIN) && \
|
||||
@ -141,16 +141,16 @@ int input_getKeybind(char* keybind, KeybindType* type, int* reverse) {
|
||||
static void input_key(int keynum, double value, int abs) {
|
||||
unsigned int t;
|
||||
|
||||
// Accelerating.
|
||||
/* Accelerating. */
|
||||
if(KEY("accel")) {
|
||||
if(abs)player_accel(value);
|
||||
else {
|
||||
// Prevent it from getting stuck.
|
||||
/* Prevent it from getting stuck. */
|
||||
if(value == KEY_PRESS) player_accel(1.);
|
||||
else if(value == KEY_RELEASE) player_accelOver();
|
||||
}
|
||||
|
||||
// Double tap accel = afterburn!
|
||||
/* Double tap accel = afterburn! */
|
||||
t = SDL_GetTicks();
|
||||
if((value == KEY_PRESS) && (t-input_accelLast <= input_afterburnSensibility))
|
||||
player_afterburn();
|
||||
@ -159,80 +159,80 @@ static void input_key(int keynum, double value, int abs) {
|
||||
|
||||
if(value == KEY_PRESS) input_accelLast = t;
|
||||
}
|
||||
// Turning left.
|
||||
/* Turning left. */
|
||||
else if(KEY("left")) {
|
||||
// Set flags for facing correction.
|
||||
/* Set flags for facing correction. */
|
||||
if(value == KEY_PRESS) { player_setFlag(PLAYER_TURN_LEFT); }
|
||||
else if(value == KEY_RELEASE) { player_rmFlag(PLAYER_TURN_LEFT); }
|
||||
|
||||
if(abs) { player_turn = -value; }
|
||||
else { player_turn -= value; }
|
||||
if(player_turn < -1.) { player_turn = -1.; }// Make sure value is sane.
|
||||
if(player_turn < -1.) { player_turn = -1.; }/* Make sure value is sane. */
|
||||
}
|
||||
// Turning right.
|
||||
/* Turning right. */
|
||||
else if(KEY("right")) {
|
||||
// Set flags for facing correction.
|
||||
/* Set flags for facing correction. */
|
||||
if(value == KEY_PRESS) { player_setFlag(PLAYER_TURN_RIGHT); }
|
||||
else if(value == KEY_RELEASE) { player_rmFlag(PLAYER_TURN_RIGHT); }
|
||||
|
||||
if(abs) { player_turn = value; }
|
||||
else { player_turn += value; }
|
||||
|
||||
if(player_turn < -1.) { player_turn = -1.; } // Make sure value is sane.
|
||||
if(player_turn < -1.) { player_turn = -1.; } /* Make sure value is sane. */
|
||||
}
|
||||
// Turn around to face vel.
|
||||
/* Turn around to face vel. */
|
||||
else if(KEY("reverse")) {
|
||||
if(value == KEY_PRESS) { player_setFlag(PLAYER_REVERSE); }
|
||||
else if(value == KEY_RELEASE) {
|
||||
player_rmFlag(PLAYER_REVERSE);
|
||||
player_turn = 0; // Turning corrections.
|
||||
player_turn = 0; /* Turning corrections. */
|
||||
if(player_isFlag(PLAYER_TURN_LEFT)) { player_turn -= 1; }
|
||||
if(player_isFlag(PLAYER_TURN_RIGHT)) { player_turn += 1; }
|
||||
}
|
||||
}
|
||||
// Shoot primary weapon. BOOM BOOM.
|
||||
/* Shoot primary weapon. BOOM BOOM. */
|
||||
else if(KEY("primary")) {
|
||||
if(value == KEY_PRESS) { player_setFlag(PLAYER_PRIMARY); }
|
||||
else if(value == KEY_RELEASE) { player_rmFlag(PLAYER_PRIMARY); }
|
||||
}
|
||||
// Targetting.
|
||||
/* Targetting. */
|
||||
else if(INGAME() && KEY("target")) {
|
||||
if(value == KEY_PRESS) player_target = pilot_getNext(player_target);
|
||||
}
|
||||
else if(INGAME() && KEY("target_nearest")) {
|
||||
if(value == KEY_PRESS) player_target = pilot_getHostile();
|
||||
}
|
||||
// Face the target.
|
||||
/* Face the target. */
|
||||
else if(KEY("face")) {
|
||||
if(value == KEY_PRESS) { player_setFlag(PLAYER_FACE); }
|
||||
else if(value == KEY_RELEASE) {
|
||||
player_rmFlag(PLAYER_FACE);
|
||||
|
||||
// Turning corrections.
|
||||
/* Turning corrections. */
|
||||
player_turn = 0;
|
||||
if(player_isFlag(PLAYER_TURN_LEFT)) { player_turn -= 1; }
|
||||
if(player_isFlag(PLAYER_TURN_RIGHT)) { player_turn += 1; }
|
||||
}
|
||||
}
|
||||
// Board those ships.
|
||||
/* Board those ships. */
|
||||
else if(KEY("board") && INGAME() && NOHYP()) {
|
||||
if(value == KEY_PRESS) player_board();
|
||||
}
|
||||
// Shooting secondary weapon.
|
||||
/* Shooting secondary weapon. */
|
||||
else if(KEY("secondary") && NOHYP()) {
|
||||
if(value == KEY_PRESS) { player_setFlag(PLAYER_SECONDARY); }
|
||||
else if(value == KEY_RELEASE) { player_rmFlag(PLAYER_SECONDARY); }
|
||||
}
|
||||
// Selecting secondary weapon.
|
||||
/* Selecting secondary weapon. */
|
||||
else if(KEY("secondary_next") && INGAME()) {
|
||||
if(value == KEY_PRESS) player_secondaryNext();
|
||||
}
|
||||
// Space.
|
||||
// Target planet (cycles just like target).
|
||||
/* Space. */
|
||||
/* Target planet (cycles just like target). */
|
||||
else if(KEY("target_planet") && INGAME() && NOHYP()) {
|
||||
if(value == KEY_PRESS) player_targetPlanet();
|
||||
}
|
||||
// Target nearest planet or attempt to land.
|
||||
/* Target nearest planet or attempt to land. */
|
||||
else if(KEY("land") && INGAME() && NOHYP()) {
|
||||
if(value == KEY_PRESS) player_land();
|
||||
}
|
||||
@ -245,19 +245,19 @@ static void input_key(int keynum, double value, int abs) {
|
||||
else if(KEY("jump") && INGAME()) {
|
||||
if(value == KEY_PRESS) player_jump();
|
||||
}
|
||||
// Zoom in.
|
||||
/* Zoom in. */
|
||||
else if(KEY("mapzoomin") && INGAME()) {
|
||||
if(value == KEY_PRESS) player_setRadarRel(1);
|
||||
}
|
||||
// Zoom out.
|
||||
/* Zoom out. */
|
||||
else if(KEY("mapzoomout") && INGAME()) {
|
||||
if(value == KEY_PRESS) player_setRadarRel(-1);
|
||||
}
|
||||
// Take a screenshot.
|
||||
/* Take a screenshot. */
|
||||
else if(KEY("screenshot") && INGAME()) {
|
||||
if(value == KEY_PRESS) player_screenshot();
|
||||
}
|
||||
// Pause the game.
|
||||
/* Pause the game. */
|
||||
else if(KEY("pause") && NOHYP()) {
|
||||
if(value == KEY_PRESS) {
|
||||
if(!toolkit) {
|
||||
@ -265,18 +265,18 @@ static void input_key(int keynum, double value, int abs) {
|
||||
} else pause_game();
|
||||
}
|
||||
}
|
||||
// Opens a menu.
|
||||
/* Opens a menu. */
|
||||
else if(KEY("menu")) {
|
||||
if(value == KEY_PRESS) menu_small();
|
||||
}
|
||||
// Show pilot information.
|
||||
/* Show pilot information. */
|
||||
else if(KEY("info") && NOHYP()) {
|
||||
if(value == KEY_PRESS) menu_info();
|
||||
}
|
||||
}
|
||||
#undef KEY
|
||||
|
||||
// --Events--
|
||||
/* --Events-- */
|
||||
|
||||
static void input_joyaxis(const unsigned int axis, const int value);
|
||||
static void input_joydown(const unsigned int button);
|
||||
@ -284,9 +284,9 @@ static void input_joyup(const unsigned int button);
|
||||
static void input_keydown(SDLKey key);
|
||||
static void input_keyup(SDLKey key);
|
||||
|
||||
// Joystick.
|
||||
/* Joystick. */
|
||||
|
||||
// Axis.
|
||||
/* Axis. */
|
||||
static void input_joyaxis(const unsigned int axis, const int value) {
|
||||
int i;
|
||||
for(i = 0; strcmp(keybindNames[i], "end"); i++)
|
||||
@ -297,7 +297,7 @@ static void input_joyaxis(const unsigned int axis, const int value) {
|
||||
}
|
||||
}
|
||||
|
||||
// Joystick button down.
|
||||
/* Joystick button down. */
|
||||
static void input_joydown(const unsigned int button) {
|
||||
int i;
|
||||
for(i = 0; strcmp(keybindNames[i], "end");i++)
|
||||
@ -308,7 +308,7 @@ static void input_joydown(const unsigned int button) {
|
||||
}
|
||||
}
|
||||
|
||||
// Joystick button up.
|
||||
/* Joystick button up. */
|
||||
static void input_joyup(const unsigned int button) {
|
||||
int i;
|
||||
for(i = 0; strcmp(keybindNames[i], "end"); i++)
|
||||
@ -319,9 +319,9 @@ static void input_joyup(const unsigned int button) {
|
||||
}
|
||||
}
|
||||
|
||||
// Keyboard.
|
||||
/* Keyboard. */
|
||||
|
||||
// Key down.
|
||||
/* Key down. */
|
||||
static void input_keydown(SDLKey key) {
|
||||
int i;
|
||||
for(i = 0; strcmp(keybindNames[i], "end"); i++)
|
||||
@ -332,7 +332,7 @@ static void input_keydown(SDLKey key) {
|
||||
}
|
||||
}
|
||||
|
||||
// Key up.
|
||||
/* Key up. */
|
||||
static void input_keyup(SDLKey key) {
|
||||
int i;
|
||||
for(i = 0; strcmp(keybindNames[i], "end"); i++)
|
||||
@ -343,14 +343,14 @@ static void input_keyup(SDLKey key) {
|
||||
}
|
||||
}
|
||||
|
||||
// Global input.
|
||||
/* Global input. */
|
||||
|
||||
// Just seperates the event types.
|
||||
/* Just seperates the event types. */
|
||||
void input_handle(SDL_Event* event) {
|
||||
// Pause the game if it is unfocused.
|
||||
/* Pause the game if it is unfocused. */
|
||||
if(event->type == SDL_ACTIVEEVENT) {
|
||||
if(event->active.state != SDL_APPMOUSEFOCUS) {
|
||||
// We don't need mouse focus.
|
||||
/* We don't need mouse focus. */
|
||||
if((event->active.gain == 0) && !paused) pause_game();
|
||||
else if((event->active.gain == 1) && paused) unpause_game();
|
||||
return;
|
||||
@ -358,9 +358,9 @@ void input_handle(SDL_Event* event) {
|
||||
}
|
||||
|
||||
if(toolkit)
|
||||
// Toolkit is handled seperately.
|
||||
/* Toolkit is handled seperately. */
|
||||
if(toolkit_input(event))
|
||||
return; // We don't process it if toolkit grabs it.
|
||||
return; /* We don't process it if toolkit grabs it. */
|
||||
|
||||
switch(event->type) {
|
||||
case SDL_JOYAXISMOTION:
|
||||
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#include <SDL.h>
|
||||
|
||||
// Input types.
|
||||
/* Input types. */
|
||||
typedef enum {
|
||||
KEYBIND_NULL,
|
||||
KEYBIND_KEYBOARD,
|
||||
@ -9,15 +9,15 @@ typedef enum {
|
||||
KEYBIND_JBUTTON
|
||||
} KeybindType;
|
||||
|
||||
// Set input.
|
||||
/* Set input. */
|
||||
void input_setDefault(void);
|
||||
void input_setKeybind(char* keybind, KeybindType type, int key, int reverse);
|
||||
int input_getKeybind(char* keybind, KeybindType* type, int* reverse);
|
||||
|
||||
// Handle the events.
|
||||
/* Handle the events. */
|
||||
void input_handle(SDL_Event* event);
|
||||
|
||||
// Init/Exit.
|
||||
/* Init/Exit. */
|
||||
void input_init(void);
|
||||
void input_exit(void);
|
||||
|
||||
|
@ -24,9 +24,9 @@ int joystick_use(int indjoystick) {
|
||||
indjoystick = 0;
|
||||
}
|
||||
if(joystick)
|
||||
// Might as well close it if it is open already.
|
||||
/* Might as well close it if it is open already. */
|
||||
SDL_JoystickClose(joystick);
|
||||
// Start using the joystick.
|
||||
/* Start using the joystick. */
|
||||
LOG("Using joystick %d", indjoystick);
|
||||
joystick = SDL_JoystickOpen(indjoystick);
|
||||
if(joystick == NULL) {
|
||||
@ -44,19 +44,19 @@ int joystick_use(int indjoystick) {
|
||||
int joystick_init(void) {
|
||||
int numjoysticks, i;
|
||||
|
||||
// Init the SDL subsys.
|
||||
/* Init the SDL subsys. */
|
||||
if(SDL_InitSubSystem(SDL_INIT_JOYSTICK)) {
|
||||
WARN("Unable to init the joystick subsystem.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Figure out how many joysticks there are.
|
||||
/* Figure out how many joysticks there are. */
|
||||
numjoysticks = SDL_NumJoysticks();
|
||||
LOG("%d joystick%s detected", numjoysticks, (numjoysticks==1)?"":"s");
|
||||
for(i = 0; i < numjoysticks; i++)
|
||||
LOG("\t\t%d. %s", i, SDL_JoystickName(i));
|
||||
|
||||
// Enable joystick events.
|
||||
/* Enable joystick events. */
|
||||
SDL_JoystickEventState(SDL_ENABLE);
|
||||
|
||||
return 0;
|
||||
|
@ -1,12 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
// Get the joystick index number based on its name.
|
||||
/* Get the joystick index number based on its name. */
|
||||
int joystick_get(char* namjoystick);
|
||||
|
||||
// set the game to use the joystick of index indjoystick.
|
||||
/* set the game to use the joystick of index indjoystick. */
|
||||
int joystick_use(int indjoystick);
|
||||
|
||||
// Exit functions.
|
||||
/* Exit functions. */
|
||||
int joystick_init(void);
|
||||
void joystick_exit(void);
|
||||
|
||||
|
184
src/land.c
184
src/land.c
@ -17,37 +17,37 @@
|
||||
#include "music.h"
|
||||
#include "land.h"
|
||||
|
||||
// Global/main window.
|
||||
/* Global/main window. */
|
||||
#define LAND_WIDTH 700
|
||||
#define LAND_HEIGHT 600
|
||||
#define BUTTON_WIDTH 200
|
||||
#define BUTTON_HEIGHT 40
|
||||
|
||||
// Commodity window.
|
||||
/* Commodity window. */
|
||||
#define COMMODITY_WIDTH 400
|
||||
#define COMMODITY_HEIGHT 400
|
||||
|
||||
// Outfits.
|
||||
/* Outfits. */
|
||||
#define OUTFITS_WIDTH 700
|
||||
#define OUTFITS_HEIGHT 600
|
||||
|
||||
// Shipyard.
|
||||
/* Shipyard. */
|
||||
#define SHIPYARD_WIDTH 700
|
||||
#define SHIPYARD_HEIGHT 600
|
||||
|
||||
// News window.
|
||||
/* News window. */
|
||||
#define NEWS_WIDTH 400
|
||||
#define NEWS_HEIGHT 500
|
||||
|
||||
// Bar window.
|
||||
/* Bar window. */
|
||||
#define BAR_WIDTH 460
|
||||
#define BAR_HEIGHT 300
|
||||
|
||||
// Mission computer window.
|
||||
/* Mission computer window. */
|
||||
#define MISSION_WIDTH 700
|
||||
#define MISSION_HEIGHT 600
|
||||
|
||||
// We use visited flags to not duplicate missions generated.
|
||||
/* We use visited flags to not duplicate missions generated. */
|
||||
#define VISITED_LAND (1<<0)
|
||||
#define VISITED_COMMODITY (1<<1)
|
||||
#define VISITED_BAR (1<<2)
|
||||
@ -57,30 +57,30 @@
|
||||
#define has_visited(f) (land_visited & (f))
|
||||
static unsigned int land_visited = 0;
|
||||
|
||||
// Land variables.
|
||||
/* Land variables. */
|
||||
int landed = 0;
|
||||
Planet* land_planet = NULL;
|
||||
|
||||
// Mission computer stack.
|
||||
/* Mission computer stack. */
|
||||
static Mission* mission_computer = NULL;
|
||||
static int mission_ncomputer = 0;
|
||||
|
||||
// Player stuff.
|
||||
/* Player stuff. */
|
||||
extern int hyperspace_target;
|
||||
|
||||
// Window stuff.
|
||||
static int land_wid = 0; // Primary land window.
|
||||
// For the second opened land window
|
||||
/* Window stuff. */
|
||||
static int land_wid = 0; /* Primary land window. */
|
||||
/* For the second opened land window */
|
||||
static int secondary_wid = 0;
|
||||
static int terciary_wid = 0; // For fancy things like news, your ship etc..
|
||||
static int terciary_wid = 0; /* For fancy things like news, your ship etc.. */
|
||||
|
||||
// Commodity excahnge.
|
||||
/* Commodity excahnge. */
|
||||
static void commodity_exchange(void);
|
||||
static void commodity_exchange_close(char* str);
|
||||
static void commodity_update(char* str);
|
||||
static void commodity_buy(char* str);
|
||||
static void commodity_sell(char* str);
|
||||
// Outfits.
|
||||
/* Outfits. */
|
||||
static void outfits(void);
|
||||
static void outfits_close(char* str);
|
||||
static void outfits_update(char* str);
|
||||
@ -90,36 +90,36 @@ static int outfit_canSell(Outfit* outfit, int q, int errmsg);
|
||||
static void outfits_sell(char* str);
|
||||
static int outfits_getMod(void);
|
||||
static void outfits_renderMod(double bx, double by, double w, double h);
|
||||
// Shipyard.
|
||||
/* Shipyard. */
|
||||
static void shipyard(void);
|
||||
static void shipyard_close(char* str);
|
||||
static void shipyard_update(char* str);
|
||||
static void shipyard_info(char* str);
|
||||
static void shipyard_buy(char* str);
|
||||
// Your ship.
|
||||
/* Your ship. */
|
||||
static void shipyard_yours(char* str);
|
||||
static void shipyard_yoursClose(char* str);
|
||||
static void shipyard_yoursUpdate(char* str);
|
||||
static void shipyard_yoursChange(char* str);
|
||||
static void shipyard_yoursTransport(char* str);
|
||||
static int shipyard_yoursTransportPrice(char* shipname);
|
||||
// Spaceport bar.
|
||||
/* Spaceport bar. */
|
||||
static void spaceport_bar(void);
|
||||
static void spaceport_bar_close(char* str);
|
||||
// News.
|
||||
/* News. */
|
||||
static void news(void);
|
||||
static void news_close(char* str);
|
||||
// Mission computer.
|
||||
/* Mission computer. */
|
||||
static void misn(void);
|
||||
static void misn_close(char* str);
|
||||
static void misn_accept(char* str);
|
||||
static void misn_genList(int first);
|
||||
static void misn_update(char* str);
|
||||
// Refuel.
|
||||
/* Refuel. */
|
||||
static int refuel_price(void);
|
||||
static void spaceport_refuel(char* str);
|
||||
|
||||
// The local market.
|
||||
/* The local market. */
|
||||
static void commodity_exchange(void) {
|
||||
int i;
|
||||
char** goods;
|
||||
@ -163,7 +163,7 @@ static void commodity_exchange(void) {
|
||||
commodity_update(NULL);
|
||||
|
||||
if(!has_visited(VISITED_COMMODITY)) {
|
||||
// TODO: mission check.
|
||||
/* TODO: mission check. */
|
||||
visited(VISITED_COMMODITY);
|
||||
}
|
||||
}
|
||||
@ -241,14 +241,14 @@ static void outfits(void) {
|
||||
int noutfits;
|
||||
char buf[128];
|
||||
|
||||
// Create window.
|
||||
/* Create window. */
|
||||
snprintf(buf, 128, "%s - Outfits", land_planet->name);
|
||||
secondary_wid = window_create(buf, -1, -1,
|
||||
OUTFITS_WIDTH, OUTFITS_HEIGHT);
|
||||
// Will allow buying from keyboard.
|
||||
/* Will allow buying from keyboard. */
|
||||
window_setFptr(secondary_wid, outfits_buy);
|
||||
|
||||
// Buttons.
|
||||
/* Buttons. */
|
||||
window_addButton(secondary_wid, -20, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnCloseOutfits",
|
||||
"Close", outfits_close);
|
||||
@ -261,7 +261,7 @@ static void outfits(void) {
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnSellOutfit",
|
||||
"Sell", outfits_sell);
|
||||
|
||||
// Fancy 128x128 image.
|
||||
/* Fancy 128x128 image. */
|
||||
window_addRect(secondary_wid, -20, -50, 128, 128, "rctImage", &cBlack, 0);
|
||||
window_addImage(secondary_wid, -20-128, -50-128, "imgOutfit", NULL, 1);
|
||||
|
||||
@ -288,17 +288,17 @@ static void outfits(void) {
|
||||
OUTFITS_WIDTH-300, 200, 0, "txtDescription",
|
||||
&gl_smallFont, NULL, NULL);
|
||||
|
||||
// Set up the outfits to buy/sell.
|
||||
/* Set up the outfits to buy/sell. */
|
||||
outfits = outfit_getTech(&noutfits, land_planet->tech, PLANET_TECH_MAX);
|
||||
window_addList(secondary_wid, 20, 40,
|
||||
200, OUTFITS_HEIGHT-80, "lstOutfits",
|
||||
outfits, noutfits, 0, outfits_update);
|
||||
|
||||
// Write the outfits stuff.
|
||||
/* Write the outfits stuff. */
|
||||
outfits_update(NULL);
|
||||
|
||||
if(!has_visited(VISITED_OUTFITS)) {
|
||||
// TODO: mission check.
|
||||
/* TODO: mission check. */
|
||||
visited(VISITED_OUTFITS);
|
||||
}
|
||||
}
|
||||
@ -325,13 +325,13 @@ static void outfits_update(char* str) {
|
||||
else
|
||||
window_disableButton(secondary_wid, "btnBuyOutfit");
|
||||
|
||||
// Gray out sell button.
|
||||
/* Gray out sell button. */
|
||||
if(outfit_canSell(outfit, 1, 0) > 0)
|
||||
window_enableButton(secondary_wid, "btnSellOutfit");
|
||||
else
|
||||
window_disableButton(secondary_wid, "btnSellOutfit");
|
||||
|
||||
// New text.
|
||||
/* New text. */
|
||||
window_modifyText(secondary_wid, "txtDescription", outfit->description);
|
||||
credits2str(buf2, outfit->price, 2);
|
||||
credits2str(buf3, player->credits, 2);
|
||||
@ -359,7 +359,7 @@ static void outfits_update(char* str) {
|
||||
static int outfit_canBuy(Outfit* outfit, int q, int errmsg) {
|
||||
char buf[16];
|
||||
|
||||
// Can player actually fit the outfit?
|
||||
/* Can player actually fit the outfit? */
|
||||
if((pilot_freeSpace(player) - outfit->mass) < 0) {
|
||||
if(errmsg != 0)
|
||||
dialogue_alert("No enough free space (you need %d more slots).",
|
||||
@ -367,7 +367,7 @@ static int outfit_canBuy(Outfit* outfit, int q, int errmsg) {
|
||||
return 0;
|
||||
}
|
||||
else if(player_outfitOwned(outfit->name) >= outfit->max) {
|
||||
// Already has too many.
|
||||
/* Already has too many. */
|
||||
if(errmsg != 0)
|
||||
dialogue_alert("You can only carry %d of this outfit.", outfit->max);
|
||||
return 0;
|
||||
@ -377,14 +377,14 @@ static int outfit_canBuy(Outfit* outfit, int q, int errmsg) {
|
||||
dialogue_alert("You can only have one afterburner.");
|
||||
return 0;
|
||||
}
|
||||
// Takes away cargo space but you don't have any.
|
||||
/* Takes away cargo space but you don't have any. */
|
||||
else if(outfit_isMod(outfit) && (outfit->u.mod.cargo < 0)
|
||||
&& (pilot_cargoFree(player) < -outfit->u.mod.cargo)) {
|
||||
if(errmsg != 0)
|
||||
dialogue_alert("You need to empty your cargo first.");
|
||||
return 0;
|
||||
}
|
||||
// Not enough $$.
|
||||
/* Not enough $$. */
|
||||
else if(q*(int)outfit->price >= player->credits) {
|
||||
if(errmsg != 0) {
|
||||
credits2str(buf, q*outfit->price - player->credits, 2);
|
||||
@ -407,7 +407,7 @@ static void outfits_buy(char* str) {
|
||||
|
||||
q = outfits_getMod();
|
||||
|
||||
// Can buy the outfit?
|
||||
/* Can buy the outfit? */
|
||||
if(outfit_canBuy(outfit, q, 1) == 0) return;
|
||||
|
||||
player->credits -= outfit->price * pilot_addOutfit(player, outfit,
|
||||
@ -416,13 +416,13 @@ static void outfits_buy(char* str) {
|
||||
}
|
||||
|
||||
static int outfit_canSell(Outfit* outfit, int q, int errmsg) {
|
||||
// No outfits to sell.
|
||||
/* No outfits to sell. */
|
||||
if(player_outfitOwned(outfit->name) <= 0) {
|
||||
if(errmsg != 0)
|
||||
dialogue_alert("You can't sell something you don't have!");
|
||||
return 0;
|
||||
}
|
||||
// Can't sell when you are using it.
|
||||
/* Can't sell when you are using it. */
|
||||
else if(outfit_isMod(outfit) && (pilot_cargoFree(player) < outfit->u.mod.cargo * q)) {
|
||||
if(errmsg != 0)
|
||||
dialogue_alert("You currently have cargo in this modification.");
|
||||
@ -448,14 +448,14 @@ static void outfits_sell(char* str) {
|
||||
|
||||
q = outfits_getMod();
|
||||
|
||||
// Has no outfits to sell.
|
||||
/* Has no outfits to sell. */
|
||||
if(outfit_canSell(outfit, q, 1) == 0) return;
|
||||
|
||||
player->credits += outfit->price * pilot_rmOutfit(player, outfit, q);
|
||||
outfits_update(NULL);
|
||||
}
|
||||
|
||||
// Return the current modifier status.
|
||||
/* Return the current modifier status. */
|
||||
static int outfits_getMod(void) {
|
||||
SDLMod mods;
|
||||
int q;
|
||||
@ -531,17 +531,17 @@ static void shipyard(void) {
|
||||
SHIPYARD_WIDTH-300, 200, 0, "txtDescription",
|
||||
&gl_smallFont, NULL, NULL);
|
||||
|
||||
// Setup the ships to buy/sell.
|
||||
/* Setup the ships to buy/sell. */
|
||||
ships = ship_getTech(&nships, land_planet->tech, PLANET_TECH_MAX);
|
||||
window_addList(secondary_wid, 20, 40,
|
||||
200, SHIPYARD_HEIGHT-80, "lstShipyard",
|
||||
ships, nships, 0, shipyard_update);
|
||||
|
||||
// Write the shipyard stuff.
|
||||
/* Write the shipyard stuff. */
|
||||
shipyard_update(NULL);
|
||||
|
||||
if(!has_visited(VISITED_SHIPYARD)) {
|
||||
// TODO: mission check.
|
||||
/* TODO: mission check. */
|
||||
visited(VISITED_SHIPYARD);
|
||||
}
|
||||
}
|
||||
@ -619,7 +619,7 @@ static void shipyard_buy(char* str) {
|
||||
player_newShip(ship, player->solid->pos.x, player->solid->pos.y,
|
||||
0., 0., player->solid->dir);
|
||||
|
||||
player->credits -= ship->price; // Auch! Paying is hard!
|
||||
player->credits -= ship->price; /* Auch! Paying is hard! */
|
||||
|
||||
shipyard_update(NULL);
|
||||
}
|
||||
@ -698,7 +698,7 @@ static void shipyard_yoursUpdate(char* str) {
|
||||
|
||||
shipname = toolkit_getList(terciary_wid, "lstYourShips");
|
||||
if(strcmp(shipname, "None")==0) {
|
||||
// No ships.
|
||||
/* No ships. */
|
||||
window_disableButton(terciary_wid, "btnChangeShip");
|
||||
window_disableButton(terciary_wid, "btnTransportShip");
|
||||
return;
|
||||
@ -707,13 +707,13 @@ static void shipyard_yoursUpdate(char* str) {
|
||||
loc = player_getLoc(ship->name);
|
||||
price = shipyard_yoursTransportPrice(shipname);
|
||||
|
||||
// Update the image.
|
||||
/* Update the image. */
|
||||
window_modifyImage(terciary_wid, "imgTarget", ship->ship->gfx_target);
|
||||
|
||||
// Update text.
|
||||
credits2str(buf2, price, 2); // Transport.
|
||||
/* Update text. */
|
||||
credits2str(buf2, price, 2); /* Transport. */
|
||||
|
||||
credits2str(buf3, 0, 2); // Sell price.
|
||||
credits2str(buf3, 0, 2); /* Sell price. */
|
||||
snprintf(buf, 256,
|
||||
"%s\n"
|
||||
"%s\n"
|
||||
@ -740,9 +740,9 @@ static void shipyard_yoursUpdate(char* str) {
|
||||
window_modifyText(terciary_wid, "txtDOutfits", buf4);
|
||||
free(buf4);
|
||||
|
||||
// Button disabling.
|
||||
/* Button disabling. */
|
||||
if(strcmp(land_planet->name, loc)) {
|
||||
// Ship not here.
|
||||
/* Ship not here. */
|
||||
window_disableButton(terciary_wid, "btnChangeShip");
|
||||
if(price > player->credits)
|
||||
window_disableButton(terciary_wid, "btnTransportShip");
|
||||
@ -761,7 +761,7 @@ static void shipyard_yoursChange(char* str) {
|
||||
shipname = toolkit_getList(terciary_wid, "lstYourShips");
|
||||
newship = player_getShip(shipname);
|
||||
if(strcmp(shipname, "None")==0) {
|
||||
// No ships.
|
||||
/* No ships. */
|
||||
dialogue_alert("You need another ship to change to!");
|
||||
return;
|
||||
}
|
||||
@ -780,7 +780,7 @@ static void shipyard_yoursChange(char* str) {
|
||||
|
||||
player_swapShip(shipname);
|
||||
|
||||
// Recreate the window.
|
||||
/* Recreate the window. */
|
||||
shipyard_yoursClose(NULL);
|
||||
shipyard_yours(NULL);
|
||||
}
|
||||
@ -791,30 +791,30 @@ static void shipyard_yoursTransport(char* str) {
|
||||
char* shipname, buf[16];
|
||||
|
||||
shipname = toolkit_getList(terciary_wid, "lstYourShips");
|
||||
if(strcmp(shipname, "None")==0) { // No ships.
|
||||
if(strcmp(shipname, "None")==0) { /* No ships. */
|
||||
dialogue_alert("You can't transport nothing here!");
|
||||
return;
|
||||
}
|
||||
|
||||
price = shipyard_yoursTransportPrice(shipname);
|
||||
if(price == 0) {
|
||||
// Already here.
|
||||
/* Already here. */
|
||||
dialogue_alert("Your ship '%s' is already here.", shipname);
|
||||
return;
|
||||
}
|
||||
else if(player->credits < price) {
|
||||
// You are broke.
|
||||
/* You are broke. */
|
||||
credits2str(buf, price-player->credits, 2);
|
||||
dialogue_alert("You need %d more credits to transport '%s' here.",
|
||||
buf, shipname);
|
||||
return;
|
||||
}
|
||||
|
||||
// Success.
|
||||
/* Success. */
|
||||
player->credits -= price;
|
||||
player_setLoc(shipname, land_planet->name);
|
||||
|
||||
// Update the window to reflect the change.
|
||||
/* Update the window to reflect the change. */
|
||||
shipyard_yoursUpdate(NULL);
|
||||
}
|
||||
|
||||
@ -825,7 +825,7 @@ static int shipyard_yoursTransportPrice(char* shipname) {
|
||||
|
||||
ship = player_getShip(shipname);
|
||||
loc = player_getLoc(shipname);
|
||||
if(strcmp(loc, land_planet->name)==0) // Already here.
|
||||
if(strcmp(loc, land_planet->name)==0) /* Already here. */
|
||||
return 0;
|
||||
|
||||
price = (int)ship->solid->mass*500;
|
||||
@ -833,7 +833,7 @@ static int shipyard_yoursTransportPrice(char* shipname) {
|
||||
return price;
|
||||
}
|
||||
|
||||
// Spaceport bar.
|
||||
/* Spaceport bar. */
|
||||
static void spaceport_bar(void) {
|
||||
secondary_wid = window_create("SpacePort Bar", -1, -1, BAR_WIDTH, BAR_HEIGHT);
|
||||
|
||||
@ -861,7 +861,7 @@ static void spaceport_bar_close(char* str) {
|
||||
secondary_wid = 0;
|
||||
}
|
||||
|
||||
// Planet news reports.
|
||||
/* Planet news reports. */
|
||||
static void news(void) {
|
||||
terciary_wid = window_create("News Reports",
|
||||
-1, -1, NEWS_WIDTH, NEWS_HEIGHT);
|
||||
@ -882,12 +882,12 @@ static void news_close(char* str) {
|
||||
terciary_wid = 0;
|
||||
}
|
||||
|
||||
// Mission computer, cos' missions rule!
|
||||
/* Mission computer, cos' missions rule! */
|
||||
static void misn(void) {
|
||||
secondary_wid = window_create("Mission Computer",
|
||||
-1, -1, MISSION_WIDTH, MISSION_HEIGHT);
|
||||
|
||||
// Buttons.
|
||||
/* Buttons. */
|
||||
window_addButton(secondary_wid, -20, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnCloseMission",
|
||||
"Close", misn_close);
|
||||
@ -896,7 +896,7 @@ static void misn(void) {
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnAcceptMission",
|
||||
"Accept", misn_accept);
|
||||
|
||||
// Text.
|
||||
/* Text. */
|
||||
window_addText(secondary_wid, 300+40, -60,
|
||||
300, 40, 0, "txtSReward",
|
||||
&gl_smallFont, &cDConsole, "Reward:");
|
||||
@ -932,7 +932,7 @@ static void misn_accept(char* str) {
|
||||
pos = toolkit_getListPos(secondary_wid, "lstMission");
|
||||
misn = &mission_computer[pos];
|
||||
if(mission_accept(misn)) {
|
||||
// Success is accepting the mission.
|
||||
/* Success is accepting the mission. */
|
||||
memmove(misn, &mission_computer[pos+1],
|
||||
sizeof(Mission) * (mission_ncomputer-pos-1));
|
||||
mission_ncomputer--;
|
||||
@ -948,9 +948,9 @@ static void misn_genList(int first) {
|
||||
if(!first)
|
||||
window_destroyWidget(secondary_wid, "lstMission");
|
||||
|
||||
// List.
|
||||
/* List. */
|
||||
if(mission_ncomputer != 0) {
|
||||
// there are missions.
|
||||
/* there are missions. */
|
||||
misn_names = malloc(sizeof(char*) * mission_ncomputer);
|
||||
j = 0;
|
||||
for(i = 0; i < mission_ncomputer; i++)
|
||||
@ -958,7 +958,7 @@ static void misn_genList(int first) {
|
||||
misn_names[j++] = strdup(mission_computer[i].title);
|
||||
}
|
||||
if((mission_ncomputer == 0) || (j == 0)) {
|
||||
// No missions.
|
||||
/* No missions. */
|
||||
if(j == 0) free(misn_names);
|
||||
misn_names = malloc(sizeof(char*));
|
||||
misn_names[0] = strdup("No Missions");
|
||||
@ -992,17 +992,17 @@ static void misn_update(char* str) {
|
||||
window_enableButton(secondary_wid, "btnAcceptMission");
|
||||
}
|
||||
|
||||
// Return how much it will cost to refuel the player.
|
||||
/* Return how much it will cost to refuel the player. */
|
||||
static int refuel_price(void) {
|
||||
return (player->fuel_max - player->fuel)*3;
|
||||
}
|
||||
|
||||
// Refuel the player.
|
||||
/* Refuel the player. */
|
||||
static void spaceport_refuel(char* str) {
|
||||
(void)str;
|
||||
|
||||
if(player->credits < refuel_price()) {
|
||||
// Player is out of moniez after landing D:
|
||||
/* Player is out of moniez after landing D: */
|
||||
dialogue_alert("You seem to not have enough scred to refuel your ship.");
|
||||
return;
|
||||
}
|
||||
@ -1012,23 +1012,23 @@ static void spaceport_refuel(char* str) {
|
||||
window_destroyWidget(land_wid, "btnRefuel");
|
||||
}
|
||||
|
||||
// Land the player.
|
||||
/* Land the player. */
|
||||
void land(Planet* p) {
|
||||
char buf[32], cred[16];
|
||||
|
||||
if(landed) return;
|
||||
|
||||
// Change music.
|
||||
/* Change music. */
|
||||
music_choose("land");
|
||||
|
||||
land_planet = p;
|
||||
land_wid = window_create(p->name, -1, -1, LAND_WIDTH, LAND_HEIGHT);
|
||||
|
||||
// Pretty display.
|
||||
/* Pretty display. */
|
||||
window_addImage(land_wid, 20, -40, "imgPlanet", p->gfx_exterior, 1);
|
||||
window_addText(land_wid, 440, 80, LAND_WIDTH-460, 460, 0,
|
||||
"txtPlanetDesc", &gl_smallFont, &cBlack, p->description);
|
||||
// Buttons.
|
||||
/* Buttons. */
|
||||
window_addButton(land_wid, -20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnTakeoff", "Takeoff", (void(*)(char*))takeoff);
|
||||
|
||||
@ -1047,7 +1047,7 @@ void land(Planet* p) {
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnOutfits",
|
||||
"Outfits", (void(*)(char*))outfits);
|
||||
|
||||
// Third column.
|
||||
/* Third column. */
|
||||
if(planet_hasService(land_planet, PLANET_SERVICE_BASIC)) {
|
||||
window_addButton(land_wid, 20, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnNews",
|
||||
@ -1063,7 +1063,7 @@ void land(Planet* p) {
|
||||
window_addButton(land_wid, -20, 20+2*(BUTTON_HEIGHT+20),
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnRefuel",
|
||||
buf, spaceport_refuel);
|
||||
if(player->credits < refuel_price()) // Not enough memory.
|
||||
if(player->credits < refuel_price()) /* Not enough memory. */
|
||||
window_disableButton(land_wid, "btnRefuel");
|
||||
}
|
||||
}
|
||||
@ -1072,56 +1072,56 @@ void land(Planet* p) {
|
||||
landed = 1;
|
||||
hooks_run("land");
|
||||
|
||||
// Generate mission computer stuff.
|
||||
/* Generate mission computer stuff. */
|
||||
mission_computer = missions_computer(&mission_ncomputer,
|
||||
land_planet->faction, land_planet->name, cur_system->name);
|
||||
|
||||
if(!has_visited(VISITED_LAND)) {
|
||||
// TODO: mission check.
|
||||
/* TODO: mission check. */
|
||||
visited(VISITED_LAND);
|
||||
}
|
||||
}
|
||||
|
||||
// Takeoff from the planet.
|
||||
/* Takeoff from the planet. */
|
||||
void takeoff(void) {
|
||||
int sw, sh, i, h;
|
||||
char* lt;
|
||||
|
||||
if(!landed) return;
|
||||
|
||||
// The music.
|
||||
/* The music. */
|
||||
music_choose("takeoff");
|
||||
|
||||
sw = land_planet->gfx_space->w;
|
||||
sh = land_planet->gfx_space->h;
|
||||
|
||||
// No longer authorized to land.
|
||||
/* No longer authorized to land. */
|
||||
player_rmFlag(PLAYER_LANDACK);
|
||||
|
||||
// Set player to another position with random facing direction and no velocity.
|
||||
/* Set player to another position with random facing direction and no velocity. */
|
||||
player_warp(land_planet->pos.x + RNG(-sw/2, sw/2),
|
||||
land_planet->pos.y + RNG(-sh/2, sh/2));
|
||||
vect_pset(&player->solid->vel, 0., 0.);
|
||||
player->solid->dir = RNG(0, 359) * M_PI/180.;
|
||||
|
||||
// Heal the player.
|
||||
/* Heal the player. */
|
||||
player->armour = player->armour_max;
|
||||
player->shield = player->shield_max;
|
||||
player->energy = player->energy_max;
|
||||
|
||||
// Time goes by, triggers hook before takeoff.
|
||||
/* Time goes by, triggers hook before takeoff. */
|
||||
ltime_inc(RNG(2*LTIME_UNIT_LENGTH, 3*LTIME_UNIT_LENGTH));
|
||||
lt = ltime_pretty(0);
|
||||
player_message("taking off from %s on %s", land_planet->name, lt);
|
||||
free(lt);
|
||||
|
||||
// Initialize the new space.
|
||||
/* Initialize the new space. */
|
||||
h = hyperspace_target;
|
||||
space_init(NULL);
|
||||
hyperspace_target = h;
|
||||
|
||||
// Cleanup.
|
||||
save_all(); // Must be before cleaning up planet. Duh!
|
||||
/* Cleanup. */
|
||||
save_all(); /* Must be before cleaning up planet. Duh! */
|
||||
land_planet = NULL;
|
||||
window_destroy(land_wid);
|
||||
landed = 0;
|
||||
@ -1129,7 +1129,7 @@ void takeoff(void) {
|
||||
hooks_run("takeoff");
|
||||
hooks_run("enter");
|
||||
|
||||
// Cleanup mission computer.
|
||||
/* Cleanup mission computer. */
|
||||
for(i = 0; i < mission_ncomputer; i++)
|
||||
mission_cleanup(&mission_computer[i]);
|
||||
free(mission_computer);
|
||||
|
208
src/lephisto.c
208
src/lephisto.c
@ -41,35 +41,35 @@
|
||||
#define FONT_SIZE 12
|
||||
#define FONT_SIZE_SMALL 10
|
||||
|
||||
static int quit = 0; // Primary loop.
|
||||
unsigned int gtime = 0; // Calculate FPS and movement.
|
||||
static int quit = 0; /* Primary loop. */
|
||||
unsigned int gtime = 0; /* Calculate FPS and movement. */
|
||||
static char version[VERSION_LEN];
|
||||
|
||||
// Just some default crap.
|
||||
/* Just some default crap. */
|
||||
char* data = NULL;
|
||||
char dataname[DATA_NAME_LEN] = "";
|
||||
int nosound = 0;
|
||||
int show_fps = 1; // Default - True.
|
||||
int show_fps = 1; /* Default - True. */
|
||||
int max_fps = 0;
|
||||
int indjoystick = -1;
|
||||
char* namjoystick = NULL;
|
||||
|
||||
// Prototypes.
|
||||
/* Prototypes. */
|
||||
static void load_all(void);
|
||||
static void unload_all(void);
|
||||
void main_loop(void);
|
||||
static void display_fps(const double dt);
|
||||
static void window_caption(void);
|
||||
static void data_name(void);
|
||||
// Update.
|
||||
/* Update. */
|
||||
static void fps_control(void);
|
||||
static void update_all(void);
|
||||
static void render_all(void);
|
||||
|
||||
|
||||
// @brief The entry point of Lephisto.
|
||||
// @param[in] argc Number of arguments.
|
||||
// @param[in] argv Array of argc arguments.
|
||||
/* @brief The entry point of Lephisto. */
|
||||
/* @param[in] argc Number of arguments. */
|
||||
/* @param[in] argv Array of argc arguments. */
|
||||
#ifdef WIN32
|
||||
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine,
|
||||
int nCmdShow) {
|
||||
@ -81,42 +81,42 @@ int main(int argc, char** argv) {
|
||||
|
||||
char buf[PATH_MAX];
|
||||
|
||||
// Print the version.
|
||||
/* Print the version. */
|
||||
snprintf(version, VERSION_LEN, "%d.%d.%d", VMAJOR, VMINOR, VREV);
|
||||
LOG(" "APPNAME" v%s", version);
|
||||
|
||||
// Initialize SDL for possible warnings.
|
||||
/* Initialize SDL for possible warnings. */
|
||||
SDL_Init(0);
|
||||
|
||||
// Input must be initialized for config to work.
|
||||
/* Input must be initialized for config to work. */
|
||||
input_init();
|
||||
|
||||
// Create the home directory if needed.
|
||||
/* Create the home directory if needed. */
|
||||
if(lfile_dirMakeExist("."))
|
||||
WARN("Unable to create lephisto directory '%s'", lfile_basePath());
|
||||
|
||||
// Set the configuration.
|
||||
/* Set the configuration. */
|
||||
snprintf(buf, PATH_MAX, "%s"CONF_FILE, lfile_basePath());
|
||||
conf_setDefaults(); // Default config values.
|
||||
conf_loadConfig(buf); // Have Lua parse config.
|
||||
conf_parseCLI(argc, argv); // Parse CLI arguments.
|
||||
conf_setDefaults(); /* Default config values. */
|
||||
conf_loadConfig(buf); /* Have Lua parse config. */
|
||||
conf_parseCLI(argc, argv); /* Parse CLI arguments. */
|
||||
|
||||
// Load the data basics.
|
||||
/* Load the data basics. */
|
||||
data_name();
|
||||
LOG(" %s", dataname);
|
||||
DEBUG();
|
||||
|
||||
// Random numbers.
|
||||
/* Random numbers. */
|
||||
rng_init();
|
||||
|
||||
if(gl_init()) {
|
||||
// Initializes video output.
|
||||
/* Initializes video output. */
|
||||
ERR("Initializing video output failed, exiting...");
|
||||
SDL_Quit();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// See if the data file is valid.
|
||||
/* See if the data file is valid. */
|
||||
if(pack_check(data)) {
|
||||
ERR("Data file '%s' not found", DATA);
|
||||
WARN("You can specify what data file you want to use with '-d'");
|
||||
@ -127,7 +127,7 @@ int main(int argc, char** argv) {
|
||||
|
||||
window_caption();
|
||||
|
||||
// OpenAL sound.
|
||||
/* OpenAL sound. */
|
||||
if(nosound)
|
||||
LOG("Sound is disabled!");
|
||||
else {
|
||||
@ -135,12 +135,12 @@ int main(int argc, char** argv) {
|
||||
music_choose("load");
|
||||
}
|
||||
|
||||
// Input.
|
||||
/* Input. */
|
||||
if((indjoystick >= 0) || (namjoystick != NULL)) {
|
||||
if(joystick_init())
|
||||
WARN("Error initializing joystick input");
|
||||
if(namjoystick != NULL) {
|
||||
// Use a joystick name to find joystick.
|
||||
/* Use a joystick name to find joystick. */
|
||||
if(joystick_use(joystick_get(namjoystick))) {
|
||||
WARN("Failure to open any joystick, falling back to default keybinds");
|
||||
input_setDefault();
|
||||
@ -148,78 +148,78 @@ int main(int argc, char** argv) {
|
||||
free(namjoystick);
|
||||
}
|
||||
else if(indjoystick >= 0)
|
||||
// Must be using an id instead.
|
||||
/* Must be using an id instead. */
|
||||
if(joystick_use(indjoystick)) {
|
||||
WARN("Failure to open any joystick, falling back to default keybinds");
|
||||
input_setDefault();
|
||||
}
|
||||
}
|
||||
|
||||
// Misc.
|
||||
/* Misc. */
|
||||
if(ai_init())
|
||||
WARN("Error initializing AI");
|
||||
|
||||
// Misc openGL init stuff.
|
||||
gl_fontInit(NULL, NULL, FONT_SIZE); // Init default font size.
|
||||
gl_fontInit(&gl_smallFont, NULL, FONT_SIZE_SMALL); // Small font.
|
||||
gui_init(); // Init the GUI crap.
|
||||
toolkit_init(); // Init the toolkit.
|
||||
/* Misc openGL init stuff. */
|
||||
gl_fontInit(NULL, NULL, FONT_SIZE); /* Init default font size. */
|
||||
gl_fontInit(&gl_smallFont, NULL, FONT_SIZE_SMALL); /* Small font. */
|
||||
gui_init(); /* Init the GUI crap. */
|
||||
toolkit_init(); /* Init the toolkit. */
|
||||
|
||||
// Data loading.
|
||||
/* Data loading. */
|
||||
load_all();
|
||||
|
||||
menu_main();
|
||||
|
||||
gtime = SDL_GetTicks(); // Init the time.
|
||||
gtime = SDL_GetTicks(); /* Init the time. */
|
||||
|
||||
// Main loop.
|
||||
/* Main loop. */
|
||||
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.
|
||||
/* 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.
|
||||
/* Event loop. */
|
||||
while(SDL_PollEvent(&event)) {
|
||||
if(event.type == SDL_QUIT) quit = 1; // Handle quit.
|
||||
if(event.type == SDL_QUIT) quit = 1; /* Handle quit. */
|
||||
|
||||
input_handle(&event); // handles all the events the player keybinds.
|
||||
input_handle(&event); /* handles all the events the player keybinds. */
|
||||
}
|
||||
main_loop();
|
||||
}
|
||||
|
||||
// Clean up some stuff.
|
||||
player_cleanup(); // Cleans up the player stuff.
|
||||
gui_free(); // Free up the gui.
|
||||
weapon_exit(); // Destroy all active weapons.
|
||||
space_exit(); // Clean up the universe!!!
|
||||
pilots_free(); // Free the pilots, they where locked up D:
|
||||
space_exit(); // Cleans up the universe itself.
|
||||
/* Clean up some stuff. */
|
||||
player_cleanup(); /* Cleans up the player stuff. */
|
||||
gui_free(); /* Free up the gui. */
|
||||
weapon_exit(); /* Destroy all active weapons. */
|
||||
space_exit(); /* Clean up the universe!!! */
|
||||
pilots_free(); /* Free the pilots, they where locked up D: */
|
||||
space_exit(); /* Cleans up the universe itself. */
|
||||
|
||||
// Unload data.
|
||||
/* Unload data. */
|
||||
unload_all();
|
||||
|
||||
// Cleanup opengl fonts.
|
||||
/* Cleanup opengl fonts. */
|
||||
gl_freeFont(NULL);
|
||||
gl_freeFont(&gl_smallFont);
|
||||
|
||||
// Exit subsystems.
|
||||
toolkit_exit(); // Kill the toolkit.
|
||||
ai_exit(); // Stop the Lua AI magicness.
|
||||
joystick_exit(); // Release joystick.
|
||||
input_exit(); // Clean up keybindings.
|
||||
gl_exit(); // Kills video output.
|
||||
sound_exit(); // Kills the sound.
|
||||
SDL_Quit(); // Quits SDL.
|
||||
/* Exit subsystems. */
|
||||
toolkit_exit(); /* Kill the toolkit. */
|
||||
ai_exit(); /* Stop the Lua AI magicness. */
|
||||
joystick_exit(); /* Release joystick. */
|
||||
input_exit(); /* Clean up keybindings. */
|
||||
gl_exit(); /* Kills video output. */
|
||||
sound_exit(); /* Kills the sound. */
|
||||
SDL_Quit(); /* Quits SDL. */
|
||||
|
||||
// All is good.
|
||||
/* All is good. */
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
void load_all(void) {
|
||||
// Ordering of these is very important as they are interdependent.
|
||||
/* Ordering of these is very important as they are interdependent. */
|
||||
commodity_load();
|
||||
factions_load(); // Dep for fleet, space, missions.
|
||||
missions_load(); // No dep.
|
||||
factions_load(); /* Dep for fleet, space, missions. */
|
||||
missions_load(); /* No dep. */
|
||||
spfx_load();
|
||||
outfit_load();
|
||||
ships_load();
|
||||
@ -227,63 +227,63 @@ void load_all(void) {
|
||||
space_load();
|
||||
}
|
||||
|
||||
// @brief Unloads all data, simplifies main().
|
||||
/* @brief Unloads all data, simplifies main(). */
|
||||
void unload_all(void) {
|
||||
// Data unloading - order should not matter, but inverse load_all is good.
|
||||
/* Data unloading - order should not matter, but inverse load_all is good. */
|
||||
fleet_free();
|
||||
ships_free();
|
||||
outfit_free();
|
||||
spfx_free(); // Remove the special effects.
|
||||
spfx_free(); /* Remove the special effects. */
|
||||
missions_free();
|
||||
factions_free();
|
||||
commodity_free();
|
||||
}
|
||||
|
||||
// @brief Slip main loop from main() for secondary loop hack in toolkit.c.
|
||||
/* @brief Slip main loop from main() for secondary loop hack in toolkit.c. */
|
||||
void main_loop(void) {
|
||||
sound_update(); // Do sound stuff.
|
||||
sound_update(); /* Do sound stuff. */
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
fps_control(); // Everyone loves fps control..
|
||||
if(toolkit) toolkit_update(); // To simulate key repetition.
|
||||
fps_control(); /* Everyone loves fps control.. */
|
||||
if(toolkit) toolkit_update(); /* To simulate key repetition. */
|
||||
if(!menu_isOpen(MENU_MAIN)) {
|
||||
if(!paused) update_all(); // Update game.
|
||||
if(!paused) update_all(); /* Update game. */
|
||||
render_all();
|
||||
}
|
||||
if(toolkit) toolkit_render();
|
||||
|
||||
gl_checkErr(); // Check error every loop.
|
||||
gl_checkErr(); /* Check error every loop. */
|
||||
|
||||
SDL_GL_SwapBuffers();
|
||||
}
|
||||
|
||||
static double fps_dt = 1.;
|
||||
static double dt = 0.;
|
||||
// @brief Controls the FPS.
|
||||
/* @brief Controls the FPS. */
|
||||
static void fps_control(void) {
|
||||
unsigned int t;
|
||||
|
||||
// dt in ms/1000.
|
||||
/* dt in ms/1000. */
|
||||
t = SDL_GetTicks();
|
||||
dt = (double)(t-gtime)/1000.;
|
||||
gtime = t;
|
||||
|
||||
if(paused) SDL_Delay(10); // Drop paused FPS to be nice to the CPU.
|
||||
if(paused) SDL_Delay(10); /* Drop paused FPS to be nice to the CPU. */
|
||||
|
||||
// If the fps is limited..
|
||||
/* If the fps is limited.. */
|
||||
if((max_fps != 0) && (dt < 1./max_fps)) {
|
||||
double delay = 1./max_fps - dt;
|
||||
SDL_Delay(delay);
|
||||
fps_dt += delay; // Make sure it displays the propper FPS.
|
||||
fps_dt += delay; /* Make sure it displays the propper FPS. */
|
||||
}
|
||||
}
|
||||
|
||||
// @brief Updates the game itself (player flying around etc).
|
||||
/* @brief Updates the game itself (player flying around etc). */
|
||||
static void update_all(void) {
|
||||
#if 0
|
||||
if(dt > 1./30.) {
|
||||
// Slow timers down and re-run calculations.
|
||||
/* Slow timers down and re-run calculations. */
|
||||
pause_delay((unsigned int)dt*1000.);
|
||||
return;
|
||||
}
|
||||
@ -294,35 +294,35 @@ static void update_all(void) {
|
||||
pilots_update(dt);
|
||||
}
|
||||
|
||||
// @brief == Renders the game. ===========================
|
||||
// Blitting order. (layers)
|
||||
//
|
||||
// BG | Stars and planets.
|
||||
// | Background player stuff (planet targetting)
|
||||
// | Background particles.
|
||||
// | Back layer weapons.
|
||||
// X
|
||||
// N | NPC ships.
|
||||
// | Front layer weapons.
|
||||
// | Normal layer particles (above ships).
|
||||
// X
|
||||
// FG | Player.
|
||||
// | Foreground particles.
|
||||
// | Text and GUI.
|
||||
// ========================================================
|
||||
/* @brief == Renders the game. =========================== */
|
||||
/* Blitting order. (layers) */
|
||||
/* */
|
||||
/* BG | Stars and planets. */
|
||||
/* | Background player stuff (planet targetting) */
|
||||
/* | Background particles. */
|
||||
/* | Back layer weapons. */
|
||||
/* X */
|
||||
/* N | NPC ships. */
|
||||
/* | Front layer weapons. */
|
||||
/* | Normal layer particles (above ships). */
|
||||
/* X */
|
||||
/* FG | Player. */
|
||||
/* | Foreground particles. */
|
||||
/* | Text and GUI. */
|
||||
/* ======================================================== */
|
||||
static void render_all(void) {
|
||||
// Setup.
|
||||
/* Setup. */
|
||||
spfx_start(dt);
|
||||
// BG.
|
||||
/* BG. */
|
||||
space_render(dt);
|
||||
planets_render();
|
||||
player_renderBG();
|
||||
weapons_render(WEAPON_LAYER_BG);
|
||||
// N.
|
||||
/* N. */
|
||||
pilots_render();
|
||||
weapons_render(WEAPON_LAYER_FG);
|
||||
spfx_render(SPFX_LAYER_BACK);
|
||||
// FG.
|
||||
/* FG. */
|
||||
player_render();
|
||||
spfx_render(SPFX_LAYER_FRONT);
|
||||
display_fps(dt);
|
||||
@ -331,13 +331,13 @@ static void render_all(void) {
|
||||
|
||||
static double fps = 0.;
|
||||
static double fps_cur = 0.;
|
||||
// @brief Displays FPS on the screen.
|
||||
/* @brief Displays FPS on the screen. */
|
||||
static void display_fps(const double dt) {
|
||||
double x, y;
|
||||
fps_dt += dt;
|
||||
fps_cur += 1.;
|
||||
if(fps_dt > 1.) {
|
||||
// Recalculate every second.
|
||||
/* Recalculate every second. */
|
||||
fps = fps_cur / fps_dt;
|
||||
fps_dt = fps_cur = 0.;
|
||||
}
|
||||
@ -348,12 +348,12 @@ static void display_fps(const double dt) {
|
||||
gl_print(NULL, x, y, NULL, "%3.2f", fps);
|
||||
}
|
||||
|
||||
// @brief Set the data module's name.
|
||||
/* @brief Set the data module's name. */
|
||||
static void data_name(void) {
|
||||
uint32_t bufsize;
|
||||
char* buf;
|
||||
|
||||
// Check if data file is valid.
|
||||
/* Check if data file is valid. */
|
||||
if(pack_check(DATA)) {
|
||||
ERR("Data file '%s' not found", data);
|
||||
WARN("You should specify which data file to use with '-d'");
|
||||
@ -362,7 +362,7 @@ static void data_name(void) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Check the version.
|
||||
/* Check the version. */
|
||||
buf = pack_readfile(DATA, VERSION_FILE, &bufsize);
|
||||
|
||||
if(strncmp(buf, version, bufsize) != 0) {
|
||||
@ -372,7 +372,7 @@ static void data_name(void) {
|
||||
|
||||
free(buf);
|
||||
|
||||
// Load the datafiles name.
|
||||
/* Load the datafiles name. */
|
||||
buf = pack_readfile(DATA, START_DATA, &bufsize);
|
||||
|
||||
xmlNodePtr node;
|
||||
@ -384,7 +384,7 @@ static void data_name(void) {
|
||||
return;
|
||||
}
|
||||
|
||||
node = node->xmlChildrenNode; // First node.
|
||||
node = node->xmlChildrenNode; /* First node. */
|
||||
if(node == NULL) {
|
||||
ERR("Malformed '"START_DATA"' file: does not contain elements");
|
||||
return;
|
||||
@ -401,7 +401,7 @@ static void data_name(void) {
|
||||
xmlCleanupParser();
|
||||
}
|
||||
|
||||
// @brief Set the window caption.
|
||||
/* @brief Set the window caption. */
|
||||
static void window_caption(void) {
|
||||
char tmp[DATA_NAME_LEN+10];
|
||||
|
||||
|
@ -12,18 +12,18 @@
|
||||
|
||||
#define pow2(x) ((x)*(x))
|
||||
|
||||
#define DATA_DEF "data" // Default data packfile.
|
||||
extern char* data; // Modifiable datafile.
|
||||
#define DATA data // Data file.
|
||||
#define DATA_NAME_LEN 32 // Max length of data name.
|
||||
#define DATA_DEF "data" /* Default data packfile. */
|
||||
extern char* data; /* Modifiable datafile. */
|
||||
#define DATA data /* Data file. */
|
||||
#define DATA_NAME_LEN 32 /* Max length of data name. */
|
||||
extern char dataname[DATA_NAME_LEN];
|
||||
|
||||
// Max filename path.
|
||||
/* Max filename path. */
|
||||
#ifndef PATH_MAX
|
||||
# define PATH_MAX 128
|
||||
#endif
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846 // Pi.
|
||||
#define M_PI 3.14159265358979323846 /* Pi. */
|
||||
#endif
|
||||
|
||||
|
16
src/lfile.c
16
src/lfile.c
@ -14,7 +14,7 @@
|
||||
#include "log.h"
|
||||
#include "lfile.h"
|
||||
|
||||
// Return lephisto's base path.
|
||||
/* Return lephisto's base path. */
|
||||
static char lephisto_base[128] = "\0";
|
||||
char* lfile_basePath(void) {
|
||||
char* home;
|
||||
@ -29,8 +29,8 @@ char* lfile_basePath(void) {
|
||||
return lephisto_base;
|
||||
}
|
||||
|
||||
// Check if a directory exists, and create it if it doesn't.
|
||||
// Based on lephisto_base.
|
||||
/* Check if a directory exists, and create it if it doesn't. */
|
||||
/* Based on lephisto_base. */
|
||||
int lfile_dirMakeExist(char* path) {
|
||||
char file[PATH_MAX];
|
||||
|
||||
@ -54,7 +54,7 @@ int lfile_dirMakeExist(char* path) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check if a file exists.
|
||||
/* Check if a file exists. */
|
||||
int lfile_fileExists(char* path, ...) {
|
||||
char file[PATH_MAX], name[PATH_MAX];
|
||||
va_list ap;
|
||||
@ -62,7 +62,7 @@ int lfile_fileExists(char* path, ...) {
|
||||
|
||||
l = 0;
|
||||
if(path == NULL) return -1;
|
||||
else { // Get the message.
|
||||
else { /* Get the message. */
|
||||
va_start(ap, path);
|
||||
vsnprintf(name, PATH_MAX-l, path, ap);
|
||||
l = strlen(name);
|
||||
@ -73,13 +73,13 @@ int lfile_fileExists(char* path, ...) {
|
||||
#ifdef LINUX
|
||||
struct stat buf;
|
||||
|
||||
if(stat(file, &buf)==0) // Stat worked, file must exist.
|
||||
if(stat(file, &buf)==0) /* Stat worked, file must exist. */
|
||||
return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
// List all the files in a dir (besides . and ..).
|
||||
/* List all the files in a dir (besides . and ..). */
|
||||
char** lfile_readDir(int* lfiles, char* path) {
|
||||
char file[PATH_MAX];
|
||||
char** files;
|
||||
@ -119,7 +119,7 @@ char** lfile_readDir(int* lfiles, char* path) {
|
||||
closedir(d);
|
||||
#endif
|
||||
|
||||
// What if we find nothing?
|
||||
/* What if we find nothing? */
|
||||
if((*lfiles) == 0) {
|
||||
free(files);
|
||||
files = NULL;
|
||||
|
46
src/llua.c
46
src/llua.c
@ -10,16 +10,16 @@
|
||||
#include "lluadef.h"
|
||||
#include "llua.h"
|
||||
|
||||
// -- Libraries. --
|
||||
/* -- Libraries. -- */
|
||||
|
||||
// Lephisto.
|
||||
/* Lephisto. */
|
||||
static int lephisto_lang(lua_State* L);
|
||||
static const luaL_reg lephisto_methods[] = {
|
||||
{ "lang", lephisto_lang },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
// Space.
|
||||
/* Space. */
|
||||
static int space_getPlanet(lua_State* L);
|
||||
static int space_getSystem(lua_State* L);
|
||||
static int space_landName(lua_State* L);
|
||||
@ -34,7 +34,7 @@ static const luaL_reg space_methods[] = {
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
// Time.
|
||||
/* Time. */
|
||||
static int time_get(lua_State* L);
|
||||
static int time_str(lua_State* L);
|
||||
static int time_units(lua_State* L);
|
||||
@ -45,14 +45,14 @@ static const luaL_reg time_methods[] = {
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
// RND.
|
||||
/* RND. */
|
||||
static int rnd_int(lua_State*L);
|
||||
static const luaL_reg rnd_methods[] = {
|
||||
{ "int", rnd_int },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
// Toolkit.
|
||||
/* Toolkit. */
|
||||
static int tk_msg(lua_State* L);
|
||||
static int tk_yesno(lua_State* L);
|
||||
static int tk_input(lua_State* L);
|
||||
@ -63,7 +63,7 @@ static const luaL_reg tk_methods[] = {
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
// Individual libraries.
|
||||
/* Individual libraries. */
|
||||
int lua_loadLephisto(lua_State* L) {
|
||||
luaL_register(L, "lephisto", lephisto_methods);
|
||||
return 0;
|
||||
@ -91,14 +91,14 @@ int lua_loadTk(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// -- Lephisto. --
|
||||
/* -- Lephisto. -- */
|
||||
static int lephisto_lang(lua_State* L) {
|
||||
// TODO: multilanguage stuff.
|
||||
/* TODO: multilanguage stuff. */
|
||||
lua_pushstring(L, "en");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// -- Space. --
|
||||
/* -- Space. -- */
|
||||
static int space_getPlanet(lua_State* L) {
|
||||
int i;
|
||||
int *factions;
|
||||
@ -108,7 +108,7 @@ static int space_getPlanet(lua_State* L) {
|
||||
char* rndplanet;
|
||||
|
||||
if(lua_gettop(L) == 0) {
|
||||
// Get random planet.
|
||||
/* Get random planet. */
|
||||
lua_pushstring(L, space_getRndPlanet());
|
||||
return 1;
|
||||
}
|
||||
@ -121,7 +121,7 @@ static int space_getPlanet(lua_State* L) {
|
||||
planets = space_getFactionPlanet(&nplanets, &i, 1);
|
||||
}
|
||||
else if(lua_istable(L, -1)) {
|
||||
// Load up the table.
|
||||
/* Load up the table. */
|
||||
lua_pushnil(L);
|
||||
nfactions = (int) lua_gettop(L);
|
||||
factions = malloc(sizeof(int) * nfactions);
|
||||
@ -130,15 +130,15 @@ static int space_getPlanet(lua_State* L) {
|
||||
factions[i++] = (int) lua_tonumber(L, -1);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
// Get the planets.
|
||||
/* Get the planets. */
|
||||
planets = space_getFactionPlanet(&nplanets, factions, nfactions);
|
||||
free(factions);
|
||||
}
|
||||
else return 0; // Nothing useful.
|
||||
else return 0; /* Nothing useful. */
|
||||
|
||||
// Choose random planet.
|
||||
/* Choose random planet. */
|
||||
if(nplanets == 0) {
|
||||
// No suitable planet.
|
||||
/* No suitable planet. */
|
||||
free(planets);
|
||||
return 0;
|
||||
}
|
||||
@ -197,7 +197,7 @@ static int space_jumpDist(lua_State* L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// -- Time. --
|
||||
/* -- Time. -- */
|
||||
static int time_get(lua_State* L) {
|
||||
lua_pushnumber(L, ltime_get());
|
||||
return 1;
|
||||
@ -222,32 +222,32 @@ static int time_units(lua_State* L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// -- RND. --
|
||||
/* -- RND. -- */
|
||||
static int rnd_int(lua_State* L) {
|
||||
int o;
|
||||
|
||||
o = lua_gettop(L);
|
||||
|
||||
if(o == 0) lua_pushnumber(L, RNGF()); // Random double o <= x <= 1.
|
||||
if(o == 0) lua_pushnumber(L, RNGF()); /* Random double o <= x <= 1. */
|
||||
else if(o == 1) {
|
||||
// Random int 0 <= x <= param.
|
||||
/* Random int 0 <= x <= param. */
|
||||
if(lua_isnumber(L, -1))
|
||||
lua_pushnumber(L, RNG(0, (int)lua_tonumber(L, -1)));
|
||||
else return 0;
|
||||
}
|
||||
else if(o >= 2) {
|
||||
// Random int param 1 <= x <= param 2.
|
||||
/* Random int param 1 <= x <= param 2. */
|
||||
if(lua_isnumber(L, -1) && lua_isnumber(L, -2))
|
||||
lua_pushnumber(L, RNG((int)lua_tonumber(L, -2), (int)lua_tonumber(L, -1)));
|
||||
else return 0;
|
||||
}
|
||||
else return 0;
|
||||
|
||||
// Unless it's returned 0 already it'll always return param.
|
||||
/* Unless it's returned 0 already it'll always return param. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
// -- Toolkit. --
|
||||
/* -- Toolkit. -- */
|
||||
|
||||
static int tk_msg(lua_State* L) {
|
||||
char* title, *str;
|
||||
|
@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
#include "lua.h"
|
||||
|
||||
// Individual libraries.
|
||||
int lua_loadLephisto(lua_State* L); // Always read only.
|
||||
/* Individual libraries. */
|
||||
int lua_loadLephisto(lua_State* L); /* Always read only. */
|
||||
int lua_loadSpace(lua_State* L, int readonly);
|
||||
int lua_loadTime(lua_State* L, int readonly);
|
||||
int lua_loadRnd(lua_State* L); // Always read only.
|
||||
int lua_loadTk(lua_State* L); // Always read only.
|
||||
int lua_loadRnd(lua_State* L); /* Always read only. */
|
||||
int lua_loadTk(lua_State* L); /* Always read only. */
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
|
||||
// Debug stuff.
|
||||
/* Debug stuff. */
|
||||
#define LLUA_DEBUG(str, args...) \
|
||||
(fprintf(stdout, "Lua: "str"\n", ## args))
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
return 0; \
|
||||
}
|
||||
|
||||
// Comfortability macros.
|
||||
/* Comfortability macros. */
|
||||
#define luaL_dobuffer(L, b, n, s) \
|
||||
(luaL_loadbuffer(L, b, n, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
|
||||
|
||||
|
14
src/ltime.c
14
src/ltime.c
@ -7,12 +7,12 @@
|
||||
|
||||
static unsigned int lephisto_time = 0;
|
||||
|
||||
// Get the current time.
|
||||
/* Get the current time. */
|
||||
unsigned int ltime_get(void) {
|
||||
return lephisto_time;
|
||||
}
|
||||
|
||||
// Return the time in pretty text.
|
||||
/* Return the time in pretty text. */
|
||||
char* ltime_pretty(unsigned int t) {
|
||||
unsigned int lt;
|
||||
int maj, stu;
|
||||
@ -21,24 +21,24 @@ char* ltime_pretty(unsigned int t) {
|
||||
if(t == 0) lt = lephisto_time;
|
||||
else lt = t;
|
||||
|
||||
// UST (Universal Synchronized Time) - unit is STU (Syncronized Time Unit).
|
||||
/* UST (Universal Synchronized Time) - unit is STU (Syncronized Time Unit). */
|
||||
maj = lt / (1000*LTIME_UNIT_LENGTH);
|
||||
stu = (lt / (LTIME_UNIT_LENGTH)) % 1000;
|
||||
if(maj == 0) // Only STU.
|
||||
if(maj == 0) /* Only STU. */
|
||||
snprintf(str, 128, "%03d STU", stu);
|
||||
else // Full format.
|
||||
else /* Full format. */
|
||||
snprintf(str, 128, "UST %d.%03d", maj, stu);
|
||||
ret = strdup(str);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Set the time absolutely, does *not* generate an event, used at init.
|
||||
/* Set the time absolutely, does *not* generate an event, used at init. */
|
||||
void ltime_set(unsigned int t) {
|
||||
lephisto_time = t;
|
||||
}
|
||||
|
||||
// Set the time relatively.
|
||||
/* Set the time relatively. */
|
||||
void ltime_inc(unsigned int t) {
|
||||
lephisto_time += t;
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
// How long a 'unit' of time is.
|
||||
/* How long a 'unit' of time is. */
|
||||
#define LTIME_UNIT_LENGTH 1000
|
||||
|
||||
// Get.
|
||||
/* Get. */
|
||||
unsigned int ltime_get(void);
|
||||
char* ltime_pretty(unsigned int t);
|
||||
|
||||
// Set.
|
||||
/* Set. */
|
||||
void ltime_set(unsigned int t);
|
||||
void ltime_inc(unsigned int t);
|
||||
|
||||
|
86
src/map.c
86
src/map.c
@ -15,20 +15,20 @@
|
||||
#define BUTTON_HEIGHT 40
|
||||
|
||||
static int map_wid = 0;
|
||||
static double map_zoom = 1.; // Zoom of the map.
|
||||
static double map_xpos = 0.; // Map position.
|
||||
static double map_zoom = 1.; /* Zoom of the map. */
|
||||
static double map_xpos = 0.; /* Map position. */
|
||||
static double map_ypos = 0.;
|
||||
static int map_selected = -1;
|
||||
static StarSystem** map_path = NULL; // The path to current selected system.
|
||||
static StarSystem** map_path = NULL; /* The path to current selected system. */
|
||||
static int map_npath = 0;
|
||||
|
||||
static int map_drag = 0; // Is the user dragging the map?
|
||||
static int map_drag = 0; /* Is the user dragging the map? */
|
||||
|
||||
// Extern.
|
||||
// space.c
|
||||
/* Extern. */
|
||||
/* space.c */
|
||||
extern StarSystem* systems_stack;
|
||||
extern int systems_nstack;
|
||||
// player.c
|
||||
/* player.c */
|
||||
extern int planet_target;
|
||||
extern int hyperspace_target;
|
||||
|
||||
@ -40,14 +40,14 @@ static void map_mouse(SDL_Event* event, double mx, double my);
|
||||
static void map_buttonZoom(char* str);
|
||||
static void map_selectCur(void);
|
||||
|
||||
// Open the map window.
|
||||
/* Open the map window. */
|
||||
void map_open(void) {
|
||||
if(map_wid) {
|
||||
map_close(NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the position to focus on current system.
|
||||
/* Set the position to focus on current system. */
|
||||
map_xpos = cur_system->pos.x;
|
||||
map_ypos = cur_system->pos.y;
|
||||
|
||||
@ -99,7 +99,7 @@ static void map_update(void) {
|
||||
window_modifyText(map_wid, "txtSysname", sys->name);
|
||||
|
||||
if(sys->nplanets == 0)
|
||||
// No planets -> no factions.
|
||||
/* No planets -> no factions. */
|
||||
snprintf(buf, 100, "NA");
|
||||
else {
|
||||
f = -1;
|
||||
@ -108,13 +108,13 @@ static void map_update(void) {
|
||||
f = sys->planets[i].faction;
|
||||
else if(f != sys->planets[i].faction &&
|
||||
(sys->planets[i].faction!=0)) {
|
||||
// TODO: more verbosity.
|
||||
/* TODO: more verbosity. */
|
||||
snprintf(buf, 100, "Multiple");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i == sys->nplanets)
|
||||
// Saw them all, and all the same.
|
||||
/* Saw them all, and all the same. */
|
||||
snprintf(buf, 100, "%s", faction_name(f));
|
||||
}
|
||||
|
||||
@ -134,7 +134,7 @@ static void map_update(void) {
|
||||
window_modifyText(map_wid, "txtPlanets", buf);
|
||||
}
|
||||
|
||||
// Return 1 if sys is part of the map_path.
|
||||
/* Return 1 if sys is part of the map_path. */
|
||||
static int map_inPath(StarSystem* sys) {
|
||||
int i, f;
|
||||
|
||||
@ -148,7 +148,7 @@ static int map_inPath(StarSystem* sys) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Render the map as a custom widget.
|
||||
/* Render the map as a custom widget. */
|
||||
static void map_render(double bx, double by, double w, double h) {
|
||||
int i, j, n, m;
|
||||
double x, y, r, tx, ty;
|
||||
@ -158,7 +158,7 @@ static void map_render(double bx, double by, double w, double h) {
|
||||
r = 5.;
|
||||
x = (bx - map_xpos + w/2) * 1.;
|
||||
y = (by - map_ypos + h/2) * 1.;
|
||||
// Background
|
||||
/* Background */
|
||||
COLOUR(cBlack);
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2d(bx, by);
|
||||
@ -167,13 +167,13 @@ static void map_render(double bx, double by, double w, double h) {
|
||||
glVertex2d(bx+w, by);
|
||||
glEnd();
|
||||
|
||||
// Render the star systems.
|
||||
/* Render the star systems. */
|
||||
for(i = 0; i < systems_nstack; i++) {
|
||||
sys = &systems_stack[i];
|
||||
|
||||
// Draw the system.
|
||||
/* Draw the system. */
|
||||
if(sys == cur_system) COLOUR(cRadar_targ);
|
||||
else if(sys->nplanets==0) COLOUR(cInert); // TODO: dependant on planet type.
|
||||
else if(sys->nplanets==0) COLOUR(cInert); /* TODO: dependant on planet type. */
|
||||
else if(areEnemies(player->faction, sys->faction)) COLOUR(cRed);
|
||||
else COLOUR(cYellow);
|
||||
|
||||
@ -181,28 +181,28 @@ static void map_render(double bx, double by, double w, double h) {
|
||||
y + sys->pos.y*map_zoom,
|
||||
r, bx, by, w, h);
|
||||
|
||||
// Draw the system name.
|
||||
/* Draw the system name. */
|
||||
tx = x + 7. + sys->pos.x * map_zoom;
|
||||
ty = y - 5. + sys->pos.y * map_zoom;
|
||||
gl_print(&gl_smallFont,
|
||||
tx + SCREEN_W/2., ty + SCREEN_H/2.,
|
||||
&cWhite, sys->name);
|
||||
|
||||
// Draw the hyperspace paths.
|
||||
/* Draw the hyperspace paths. */
|
||||
glShadeModel(GL_SMOOTH);
|
||||
// Cheaply use transparency instead of actually
|
||||
// calculating from x to y the line must go. :)
|
||||
/* Cheaply use transparency instead of actually */
|
||||
/* calculating from x to y the line must go. :) */
|
||||
for(j = 0; j < sys->njumps; j++) {
|
||||
n = map_inPath(&systems_stack[sys->jumps[j]]);
|
||||
m = map_inPath(sys);
|
||||
// Set the colours, is the route the current one?
|
||||
/* Set the colours, is the route the current one? */
|
||||
if((hyperspace_target != -1) &&
|
||||
(((cur_system == sys) && (j == hyperspace_target)) ||
|
||||
((cur_system == &systems_stack[sys->jumps[j]]) &&
|
||||
(sys == &systems_stack[cur_system->jumps[hyperspace_target]]))))
|
||||
col = &cGreen;
|
||||
else if((n > 0) && (m > 0)) {
|
||||
if((n == 2) || (m == 2)) // Out of fuel.
|
||||
if((n == 2) || (m == 2)) /* Out of fuel. */
|
||||
col = &cRed;
|
||||
else
|
||||
col = &cYellow;
|
||||
@ -225,7 +225,7 @@ static void map_render(double bx, double by, double w, double h) {
|
||||
}
|
||||
glShadeModel(GL_FLAT);
|
||||
}
|
||||
// Selected planet.
|
||||
/* Selected planet. */
|
||||
if(map_selected != -1) {
|
||||
sys = &systems_stack[map_selected];
|
||||
COLOUR(cRed);
|
||||
@ -234,13 +234,13 @@ static void map_render(double bx, double by, double w, double h) {
|
||||
}
|
||||
}
|
||||
|
||||
// Map event handling.
|
||||
/* Map event handling. */
|
||||
static void map_mouse(SDL_Event* event, double mx, double my) {
|
||||
int i, j;
|
||||
double x, y, t;
|
||||
StarSystem* sys;
|
||||
|
||||
t = 13.*15.; // Threshold.
|
||||
t = 13.*15.; /* Threshold. */
|
||||
|
||||
mx -= MAP_WIDTH/2 - map_xpos;
|
||||
my -= MAP_HEIGHT/2 - map_ypos;
|
||||
@ -252,17 +252,17 @@ static void map_mouse(SDL_Event* event, double mx, double my) {
|
||||
else if(event->button.button == SDL_BUTTON_WHEELDOWN)
|
||||
map_buttonZoom("btnZoomIn");
|
||||
|
||||
// Selecting star system.
|
||||
/* Selecting star system. */
|
||||
else {
|
||||
for(i = 0; i < systems_nstack; i++) {
|
||||
sys = &systems_stack[i];
|
||||
|
||||
// Get position.
|
||||
/* Get position. */
|
||||
x = systems_stack[i].pos.x * map_zoom;
|
||||
y = systems_stack[i].pos.y * map_zoom;
|
||||
|
||||
if((pow2(mx-x)+pow2(my-y)) < t) {
|
||||
// Select the current system and make a path to it.
|
||||
/* Select the current system and make a path to it. */
|
||||
map_selected = i;
|
||||
if(map_path)
|
||||
free(map_path);
|
||||
@ -272,10 +272,10 @@ static void map_mouse(SDL_Event* event, double mx, double my) {
|
||||
if(map_npath == 0)
|
||||
hyperspace_target = -1;
|
||||
else
|
||||
// See if it a valid hyperspace target.
|
||||
/* See if it a valid hyperspace target. */
|
||||
for(j = 0; j < cur_system->njumps; j++) {
|
||||
if(map_path[0] == &systems_stack[cur_system->jumps[j]]) {
|
||||
planet_target = -1; // Override planet_target.
|
||||
planet_target = -1; /* Override planet_target. */
|
||||
hyperspace_target = j;
|
||||
break;
|
||||
}
|
||||
@ -294,7 +294,7 @@ static void map_mouse(SDL_Event* event, double mx, double my) {
|
||||
|
||||
case SDL_MOUSEMOTION:
|
||||
if(map_drag) {
|
||||
// Axis is inverted.
|
||||
/* Axis is inverted. */
|
||||
map_xpos -= event->motion.xrel;
|
||||
map_ypos += event->motion.yrel;
|
||||
}
|
||||
@ -314,7 +314,7 @@ static void map_buttonZoom(char* str) {
|
||||
}
|
||||
}
|
||||
|
||||
// Set the map to sane defaults.
|
||||
/* Set the map to sane defaults. */
|
||||
void map_clear(void) {
|
||||
map_zoom = 1.;
|
||||
if(cur_system != NULL) {
|
||||
@ -330,7 +330,7 @@ void map_clear(void) {
|
||||
map_npath = 0;
|
||||
}
|
||||
|
||||
// Default system is current system.
|
||||
/* Default system is current system. */
|
||||
map_selectCur();
|
||||
}
|
||||
|
||||
@ -344,37 +344,37 @@ static void map_selectCur(void) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Probably going to seg fault now..
|
||||
/* Probably going to seg fault now.. */
|
||||
map_selected = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Update the map after a jump.
|
||||
/* Update the map after a jump. */
|
||||
void map_jump(void) {
|
||||
int j;
|
||||
|
||||
// Set selected system to self.
|
||||
/* Set selected system to self. */
|
||||
map_selectCur();
|
||||
|
||||
map_xpos = cur_system->pos.x;
|
||||
map_ypos = cur_system->pos.y;
|
||||
|
||||
// Update path if set.
|
||||
/* Update path if set. */
|
||||
if(map_path != NULL) {
|
||||
map_npath--;
|
||||
if(map_npath == 0) {
|
||||
// Path is empty.
|
||||
/* Path is empty. */
|
||||
free(map_path);
|
||||
map_path = NULL;
|
||||
} else {
|
||||
// Get rid of bottom of the path.
|
||||
/* Get rid of bottom of the path. */
|
||||
memcpy(&map_path[0], &map_path[1], sizeof(StarSystem*) * map_npath);
|
||||
map_path = realloc(map_path, sizeof(StarSystem*) * map_npath);
|
||||
|
||||
// Set the next jump to be the next in path.
|
||||
/* Set the next jump to be the next in path. */
|
||||
for(j = 0; j < cur_system->njumps; j++) {
|
||||
if(map_path[0] == &systems_stack[cur_system->jumps[j]]) {
|
||||
planet_target = -1; // Override planet_target.
|
||||
planet_target = -1; /* Override planet_target. */
|
||||
hyperspace_target = j;
|
||||
break;
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
// Open the map window.
|
||||
/* Open the map window. */
|
||||
void map_open(void);
|
||||
|
||||
// Misc.
|
||||
/* Misc. */
|
||||
void map_clear(void);
|
||||
void map_jump(void);
|
||||
|
||||
|
58
src/menu.c
58
src/menu.c
@ -41,27 +41,27 @@
|
||||
|
||||
int menu_open = 0;
|
||||
|
||||
// Main menu.
|
||||
/* Main menu. */
|
||||
void menu_main_close(void);
|
||||
static void menu_main_load(char* str);
|
||||
static void menu_main_new(char* str);
|
||||
// Small menu.
|
||||
/* Small menu. */
|
||||
static void menu_small_close(char* str);
|
||||
static void edit_options(char* str);
|
||||
static void menu_small_exit(char* str);
|
||||
static void exit_game(void);
|
||||
// Information menu.
|
||||
/* Information menu. */
|
||||
static void menu_info_close(char* str);
|
||||
// Outfits submenu.
|
||||
/* Outfits submenu. */
|
||||
static void info_outfits_menu(char* str);
|
||||
// Mission submenu.
|
||||
/* Mission submenu. */
|
||||
static void info_missions_menu(char* str);
|
||||
static void mission_menu_abort(char* str);
|
||||
static void mission_menu_genList(int first);
|
||||
static void mission_menu_update(char* str);
|
||||
// Death menu.
|
||||
/* Death menu. */
|
||||
static void menu_death_main(char* str);
|
||||
// Generic.
|
||||
/* Generic. */
|
||||
static void menu_generic_close(char* str);
|
||||
|
||||
void menu_main(void) {
|
||||
@ -70,13 +70,13 @@ void menu_main(void) {
|
||||
|
||||
tex = pf_genFractal(SCREEN_W, SCREEN_H, 5.);
|
||||
|
||||
// Create background image window.
|
||||
/* Create background image window. */
|
||||
bwid = window_create("BG", -1, -1, SCREEN_W, SCREEN_H);
|
||||
window_addRect(bwid, 0, 0, SCREEN_W, SCREEN_H, "rctBG", &cBlack, 0);
|
||||
window_addImage(bwid, 0, 0, "imgBG", tex, 0);
|
||||
window_imgColour(bwid, "imgBG", &cPurple);
|
||||
|
||||
// Create menu window.
|
||||
/* Create menu window. */
|
||||
wid = window_create("Main Menu", -1, -1, MAIN_WIDTH, MAIN_HEIGHT);
|
||||
window_addButton(wid, 20, 20 + (BUTTON_HEIGHT+20)*3,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
@ -115,13 +115,13 @@ static void menu_main_new(char* str) {
|
||||
player_new();
|
||||
}
|
||||
|
||||
// Ze ingame menu.
|
||||
// Small ingame menu.
|
||||
/* Ze ingame menu. */
|
||||
/* Small ingame menu. */
|
||||
void menu_small(void) {
|
||||
if(menu_isOpen(MENU_MAIN) ||
|
||||
menu_isOpen(MENU_SMALL) ||
|
||||
menu_isOpen(MENU_DEATH))
|
||||
return; // It's already open..
|
||||
return; /* It's already open.. */
|
||||
|
||||
unsigned int wid;
|
||||
|
||||
@ -155,17 +155,17 @@ static void menu_small_exit(char* str) {
|
||||
menu_main();
|
||||
}
|
||||
|
||||
// Edit the options.
|
||||
/* Edit the options. */
|
||||
static void edit_options(char* str) {
|
||||
(void)str;
|
||||
// TODO
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
// Exit the game.
|
||||
/* Exit the game. */
|
||||
static void exit_game(void) {
|
||||
// If landed we must save anyways.
|
||||
/* If landed we must save anyways. */
|
||||
if(landed) {
|
||||
// Increment time to match takeoff.
|
||||
/* Increment time to match takeoff. */
|
||||
ltime_inc(RNG(2*LTIME_UNIT_LENGTH, 3*LTIME_UNIT_LENGTH));
|
||||
save_all();
|
||||
}
|
||||
@ -174,7 +174,7 @@ static void exit_game(void) {
|
||||
SDL_PushEvent(&quit);
|
||||
}
|
||||
|
||||
// Info menu.
|
||||
/* Info menu. */
|
||||
void menu_info(void) {
|
||||
if(menu_isOpen(MENU_INFO)) return;
|
||||
|
||||
@ -183,7 +183,7 @@ void menu_info(void) {
|
||||
unsigned int wid;
|
||||
wid = window_create("Info", -1, -1, INFO_WIDTH, INFO_HEIGHT);
|
||||
|
||||
// Pilot generics.
|
||||
/* Pilot generics. */
|
||||
lt = ltime_pretty(ltime_get());
|
||||
window_addText(wid, 20, 20, 120, INFO_HEIGHT-60,
|
||||
0, "txtDPilot", &gl_smallFont, &cDConsole,
|
||||
@ -211,7 +211,7 @@ void menu_info(void) {
|
||||
0, "txtPilot", &gl_smallFont, &cBlack, str);
|
||||
free(lt);
|
||||
|
||||
// Menu.
|
||||
/* Menu. */
|
||||
window_addButton(wid, -20, (20 + BUTTON_HEIGHT)*4 + 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
player->ship->name, "Ship", ship_view);
|
||||
@ -261,14 +261,14 @@ static void info_outfits_menu(char* str) {
|
||||
"closeOutfits", "Close", menu_generic_close);
|
||||
}
|
||||
|
||||
// Show the player's active missions.
|
||||
/* Show the player's active missions. */
|
||||
static void info_missions_menu(char* str) {
|
||||
(void)str;
|
||||
unsigned int wid;
|
||||
|
||||
wid = window_create("Missions", -1, -1, MISSIONS_WIDTH, MISSIONS_HEIGHT);
|
||||
|
||||
// Buttons.
|
||||
/* Buttons. */
|
||||
window_addButton(wid, -20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"closeMissions", "Back", menu_generic_close);
|
||||
|
||||
@ -276,7 +276,7 @@ static void info_missions_menu(char* str) {
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnAbortMission", "Abort",
|
||||
mission_menu_abort);
|
||||
|
||||
// Text.
|
||||
/* Text. */
|
||||
window_addText(wid, 300+40, -60,
|
||||
200, 40, 0, "txtSReward",
|
||||
&gl_smallFont, &cDConsole, "Reward:");
|
||||
@ -288,7 +288,7 @@ static void info_missions_menu(char* str) {
|
||||
200, MISSIONS_HEIGHT - BUTTON_WIDTH - 120, 0,
|
||||
"txtDesc", &gl_smallFont, &cBlack, NULL);
|
||||
|
||||
// List.
|
||||
/* List. */
|
||||
mission_menu_genList(1);
|
||||
}
|
||||
|
||||
@ -302,14 +302,14 @@ static void mission_menu_genList(int first) {
|
||||
if(!first)
|
||||
window_destroyWidget(wid, "lstMission");
|
||||
|
||||
// List.
|
||||
/* List. */
|
||||
misn_names = malloc(sizeof(char*) * MISSION_MAX);
|
||||
j = 0;
|
||||
for(i = 0; i < MISSION_MAX; i++)
|
||||
if(player_missions[i].id != 0)
|
||||
misn_names[j++] = strdup(player_missions[i].title);
|
||||
if(j == 0) {
|
||||
// No missions.
|
||||
/* No missions. */
|
||||
free(misn_names);
|
||||
misn_names = malloc(sizeof(char*));
|
||||
misn_names[0] = strdup("No Missions");
|
||||
@ -366,7 +366,7 @@ static void mission_menu_abort(char* str) {
|
||||
}
|
||||
}
|
||||
|
||||
// Pilot dead.
|
||||
/* Pilot dead. */
|
||||
void menu_death(void) {
|
||||
unsigned int wid;
|
||||
wid = window_create("Death", -1, -1, DEATH_WIDTH, DEATH_HEIGHT);
|
||||
@ -391,8 +391,8 @@ static void menu_death_main(char* str) {
|
||||
menu_main();
|
||||
}
|
||||
|
||||
// Generic close approach.
|
||||
/* Generic close approach. */
|
||||
static void menu_generic_close(char* str) {
|
||||
window_destroy(window_get(str+5)); // closeFoo -> Foo.
|
||||
window_destroy(window_get(str+5)); /* closeFoo -> Foo. */
|
||||
}
|
||||
|
||||
|
116
src/misn_lua.c
116
src/misn_lua.c
@ -22,7 +22,7 @@
|
||||
#include "xml.h"
|
||||
#include "misn_lua.h"
|
||||
|
||||
// Similar to lua vars, but with less variety.
|
||||
/* Similar to lua vars, but with less variety. */
|
||||
#define MISN_VAR_NIL 0
|
||||
#define MISN_VAR_NUM 1
|
||||
#define MISN_VAR_BOOL 2
|
||||
@ -37,27 +37,27 @@ typedef struct misn_var_ {
|
||||
} d;
|
||||
} misn_var;
|
||||
|
||||
// Variable stack.
|
||||
/* Variable stack. */
|
||||
static misn_var* var_stack = NULL;
|
||||
static int var_nstack = 0;
|
||||
static int var_mstack = 0;
|
||||
|
||||
// Current mission.
|
||||
/* Current mission. */
|
||||
static Mission* cur_mission = NULL;
|
||||
static int misn_delete = 0; // If 1 delete current mission.
|
||||
static int misn_delete = 0; /* If 1 delete current mission. */
|
||||
|
||||
// Static.
|
||||
/* Static. */
|
||||
static int var_add(misn_var* var);
|
||||
static void var_free(misn_var* var);
|
||||
static unsigned int hook_generic(lua_State* L, char* stack);
|
||||
// Extern.
|
||||
/* Extern. */
|
||||
int misn_run(Mission* misn, char* func);
|
||||
int var_save(xmlTextWriterPtr writer);
|
||||
int var_load(xmlNodePtr parent);
|
||||
|
||||
// -- Libraries. --
|
||||
/* -- Libraries. -- */
|
||||
|
||||
// Mission.
|
||||
/* Mission. */
|
||||
static int misn_setTitle(lua_State* L);
|
||||
static int misn_setDesc(lua_State* L);
|
||||
static int misn_setReward(lua_State* L);
|
||||
@ -74,7 +74,7 @@ static const luaL_reg misn_methods[] = {
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
// Var.
|
||||
/* Var. */
|
||||
static int var_peek(lua_State* L);
|
||||
static int var_pop(lua_State* L);
|
||||
static int var_push(lua_State* L);
|
||||
@ -85,13 +85,13 @@ static const luaL_reg var_methods[] = {
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
// Only conditional.
|
||||
/* Only conditional. */
|
||||
static const luaL_reg var_cond_methods[] = {
|
||||
{ "peek", var_peek },
|
||||
{0, 0 }
|
||||
};
|
||||
|
||||
// Player.
|
||||
/* Player. */
|
||||
static int player_getname(lua_State* L);
|
||||
static int player_shipname(lua_State* L);
|
||||
static int player_freeSpace(lua_State* L);
|
||||
@ -114,7 +114,7 @@ static const luaL_reg player_methods[] = {
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
// Hooks.
|
||||
/* Hooks. */
|
||||
static int hook_land(lua_State* L);
|
||||
static int hook_takeoff(lua_State* L);
|
||||
static int hook_time(lua_State* L);
|
||||
@ -129,7 +129,7 @@ static const luaL_reg hook_methods[] = {
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
// Pilots.
|
||||
/* Pilots. */
|
||||
static int pilot_addFleet(lua_State* L);
|
||||
static int pilot_rename(lua_State* L);
|
||||
static const luaL_reg pilot_methods[] = {
|
||||
@ -138,7 +138,7 @@ static const luaL_reg pilot_methods[] = {
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
// Register all the libaries.
|
||||
/* Register all the libaries. */
|
||||
int misn_loadLibs(lua_State* L) {
|
||||
lua_loadLephisto(L);
|
||||
lua_loadMisn(L);
|
||||
@ -159,7 +159,7 @@ int misn_loadCondLibs(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Individual libarary loading.
|
||||
/* Individual libarary loading. */
|
||||
int lua_loadMisn(lua_State* L) {
|
||||
luaL_register(L, "misn", misn_methods);
|
||||
return 0;
|
||||
@ -188,9 +188,9 @@ int lua_loadPilot(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Run a mission function.
|
||||
//
|
||||
// -1 on error, 1 on misn.finish() call and 0 normally.
|
||||
/* Run a mission function. */
|
||||
/* */
|
||||
/* -1 on error, 1 on misn.finish() call and 0 normally. */
|
||||
int misn_run(Mission* misn, char* func) {
|
||||
int i, ret;
|
||||
char* err;
|
||||
@ -200,7 +200,7 @@ int misn_run(Mission* misn, char* func) {
|
||||
|
||||
lua_getglobal(misn->L, func);
|
||||
if((ret = lua_pcall(misn->L, 0, 0, 0))) {
|
||||
// Did an oops.
|
||||
/* Did an oops. */
|
||||
err = (lua_isstring(misn->L, -1)) ? (char*) lua_tostring(misn->L, -1) : NULL;
|
||||
if(strcmp(err, "Mission Done"))
|
||||
WARN("Mission '%s' -> '%s' : %s",
|
||||
@ -208,7 +208,7 @@ int misn_run(Mission* misn, char* func) {
|
||||
else ret = 1;
|
||||
}
|
||||
|
||||
// Mission is finished.
|
||||
/* Mission is finished. */
|
||||
if(misn_delete) {
|
||||
mission_cleanup(cur_mission);
|
||||
for(i = 0; i < MISSION_MAX; i++)
|
||||
@ -223,7 +223,7 @@ int misn_run(Mission* misn, char* func) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Save the mission variables.
|
||||
/* Save the mission variables. */
|
||||
int var_save(xmlTextWriterPtr writer) {
|
||||
int i;
|
||||
|
||||
@ -251,14 +251,14 @@ int var_save(xmlTextWriterPtr writer) {
|
||||
xmlw_str(writer, var_stack[i].d.str);
|
||||
break;
|
||||
}
|
||||
xmlw_endElem(writer); // var.
|
||||
xmlw_endElem(writer); /* var. */
|
||||
}
|
||||
xmlw_endElem(writer); // vars.
|
||||
xmlw_endElem(writer); /* vars. */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Load the vars.
|
||||
/* Load the vars. */
|
||||
int var_load(xmlNodePtr parent) {
|
||||
char* str;
|
||||
xmlNodePtr node, cur;
|
||||
@ -290,7 +290,7 @@ int var_load(xmlNodePtr parent) {
|
||||
var.type = MISN_VAR_STR;
|
||||
var.d.str = atoi(xml_get(cur));
|
||||
} else {
|
||||
// Supeh error checking.
|
||||
/* Supeh error checking. */
|
||||
WARN("Unknown var type '%s'", str);
|
||||
free(var.name);
|
||||
continue;
|
||||
@ -305,17 +305,17 @@ int var_load(xmlNodePtr parent) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Add a var to the stack, strings will be SHARED, don't free!!!
|
||||
/* Add a var to the stack, strings will be SHARED, don't free!!! */
|
||||
static int var_add(misn_var* new_var) {
|
||||
int i;
|
||||
|
||||
if(var_nstack+1 > var_mstack) {
|
||||
// More memory.
|
||||
var_mstack += 64; // Overkill much??
|
||||
/* More memory. */
|
||||
var_mstack += 64; /* Overkill much?? */
|
||||
var_stack = realloc(var_stack, var_mstack * sizeof(misn_var));
|
||||
}
|
||||
|
||||
// Check if already exists.
|
||||
/* Check if already exists. */
|
||||
for(i = 0; i < var_nstack; i++)
|
||||
if(strcmp(new_var->name, var_stack[i].name)==0) {
|
||||
var_free(&var_stack[i]);
|
||||
@ -329,13 +329,13 @@ static int var_add(misn_var* new_var) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// -- Mission. --
|
||||
/* -- Mission. -- */
|
||||
|
||||
static int misn_setTitle(lua_State* L) {
|
||||
LLUA_MIN_ARGS(1);
|
||||
if(lua_isstring(L, -1)) {
|
||||
if(cur_mission->title)
|
||||
// Cleanup the old title.
|
||||
/* Cleanup the old title. */
|
||||
free(cur_mission->title);
|
||||
cur_mission->title = strdup((char*)lua_tostring(L, -1));
|
||||
}
|
||||
@ -346,7 +346,7 @@ static int misn_setDesc(lua_State* L) {
|
||||
LLUA_MIN_ARGS(1);
|
||||
if(lua_isstring(L, -1)) {
|
||||
if(cur_mission->desc)
|
||||
// Cleanup the old description.
|
||||
/* Cleanup the old description. */
|
||||
free(cur_mission->desc);
|
||||
cur_mission->desc = strdup((char*)lua_tostring(L, -1));
|
||||
}
|
||||
@ -357,7 +357,7 @@ static int misn_setReward(lua_State* L) {
|
||||
LLUA_MIN_ARGS(1);
|
||||
if(lua_isstring(L, -1)) {
|
||||
if(cur_mission->reward)
|
||||
// Cleanup the old reward.
|
||||
/* Cleanup the old reward. */
|
||||
free(cur_mission->reward);
|
||||
cur_mission->reward = strdup((char*)lua_tostring(L, -1));
|
||||
}
|
||||
@ -370,12 +370,12 @@ static int misn_factions(lua_State* L) {
|
||||
|
||||
dat = cur_mission->data;
|
||||
|
||||
// We'll push all the factions in table form.
|
||||
/* We'll push all the factions in table form. */
|
||||
lua_newtable(L);
|
||||
for(i = 0; i < dat->avail.nfactions; i++) {
|
||||
lua_pushnumber(L, i+1); // Index, starts with 1.
|
||||
lua_pushnumber(L, dat->avail.factions[i]); // Value.
|
||||
lua_rawset(L, -3); // Store the value in the table.
|
||||
lua_pushnumber(L, i+1); /* Index, starts with 1. */
|
||||
lua_pushnumber(L, dat->avail.factions[i]); /* Value. */
|
||||
lua_rawset(L, -3); /* Store the value in the table. */
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -385,18 +385,18 @@ static int misn_accept(lua_State* L) {
|
||||
|
||||
ret = 0;
|
||||
|
||||
// Find the last mission.
|
||||
/* Find the last mission. */
|
||||
for(i = 0; i < MISSION_MAX; i++)
|
||||
if(player_missions[i].data == NULL) break;
|
||||
|
||||
// No missions left.
|
||||
/* No missions left. */
|
||||
if(i >= MISSION_MAX) ret = 1;
|
||||
else {
|
||||
memcpy(&player_missions[i], cur_mission, sizeof(Mission));
|
||||
memset(cur_mission, 0, sizeof(Mission));
|
||||
cur_mission = &player_missions[i];
|
||||
}
|
||||
lua_pushboolean(L, !ret); // We'll convert C style return to lua.
|
||||
lua_pushboolean(L, !ret); /* We'll convert C style return to lua. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -406,7 +406,7 @@ static int misn_finish(lua_State* L) {
|
||||
if(lua_isboolean(L, -1)) b = lua_toboolean(L, -1);
|
||||
else {
|
||||
lua_pushstring(L, "Mission Done");
|
||||
lua_error(L); // THERE IS NO RETURN!
|
||||
lua_error(L); /* THERE IS NO RETURN! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -416,14 +416,14 @@ static int misn_finish(lua_State* L) {
|
||||
player_missionFinished(mission_getID(cur_mission->data->name));
|
||||
|
||||
lua_pushstring(L, "Mission Done");
|
||||
lua_error(L); // Should not return..
|
||||
lua_error(L); /* Should not return.. */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// -- Var. --
|
||||
/* -- Var. -- */
|
||||
|
||||
// Check if a variable exists.
|
||||
/* Check if a variable exists. */
|
||||
int var_checkflag(char* str) {
|
||||
int i;
|
||||
for(i = 0; i < var_nstack; i++)
|
||||
@ -500,7 +500,7 @@ static int var_push(lua_State* L) {
|
||||
|
||||
var.name = strdup(str);
|
||||
|
||||
// Store appropriate data.
|
||||
/* Store appropriate data. */
|
||||
if(lua_isnil(L, -1))
|
||||
var.type = MISN_VAR_NIL;
|
||||
else if(lua_isnumber(L, -1)) {
|
||||
@ -554,7 +554,7 @@ void var_cleanup(void) {
|
||||
var_mstack = 0;
|
||||
}
|
||||
|
||||
// -- Player. --
|
||||
/* -- Player. -- */
|
||||
|
||||
static int player_getname(lua_State* L) {
|
||||
lua_pushstring(L, player_name);
|
||||
@ -655,14 +655,14 @@ static int player_getFaction(lua_State* L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// -- HOOK --
|
||||
/* -- HOOK -- */
|
||||
static unsigned int hook_generic(lua_State* L, char* stack) {
|
||||
int i;
|
||||
char* func;
|
||||
|
||||
LLUA_MIN_ARGS(1);
|
||||
|
||||
// Make sure mission is a player mission.
|
||||
/* Make sure mission is a player mission. */
|
||||
for(i = 0; i < MISSION_MAX; i++)
|
||||
if(player_missions[i].id == cur_mission->id)
|
||||
break;
|
||||
@ -707,13 +707,13 @@ static int hook_pilotDeath(lua_State* L) {
|
||||
if(lua_isnumber(L, -2)) p = (unsigned int) lua_tonumber(L, -2);
|
||||
else LLUA_INVALID_PARAMETER();
|
||||
|
||||
h = hook_generic(L, "death"); // We won't actually call the death stack directly.
|
||||
h = hook_generic(L, "death"); /* We won't actually call the death stack directly. */
|
||||
pilot_addHook(pilot_get(p), PILOT_HOOK_DEATH, h);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// -- Pilot. --
|
||||
/* -- Pilot. -- */
|
||||
static int pilot_addFleet(lua_State* L) {
|
||||
LLUA_MIN_ARGS(1);
|
||||
Fleet* flt;
|
||||
@ -726,23 +726,23 @@ static int pilot_addFleet(lua_State* L) {
|
||||
if(lua_isstring(L, -1)) fltname = (char*) lua_tostring(L, -1);
|
||||
else LLUA_INVALID_PARAMETER();
|
||||
|
||||
// Pull the fleet.
|
||||
/* Pull the fleet. */
|
||||
flt = fleet_get(fltname);
|
||||
if(flt == NULL) {
|
||||
LLUA_DEBUG("Fleet not found!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This should probably be done better..
|
||||
/* This should probably be done better.. */
|
||||
vect_pset(&vp, RNG(MIN_HYPERSPACE_DIST, MIN_HYPERSPACE_DIST*1.5),
|
||||
RNG(0, 360)*M_PI/180.);
|
||||
vectnull(&vn);
|
||||
|
||||
// Now we start adding pilots and toss ids into the table we return.
|
||||
/* Now we start adding pilots and toss ids into the table we return. */
|
||||
j = 0;
|
||||
for(i = 0; i < flt->npilots; i++) {
|
||||
if(RNG(0, 100) <= flt->pilots[i].chance) {
|
||||
// Fleet displacement.
|
||||
/* Fleet displacement. */
|
||||
vect_cadd(&vp, RNG(75, 150) & (RNG(0, 1) ? 1: -1),
|
||||
RNG(75, 150) * (RNG(0, 1) ? 1 : -1));
|
||||
|
||||
@ -757,10 +757,10 @@ static int pilot_addFleet(lua_State* L) {
|
||||
&vv,
|
||||
0);
|
||||
|
||||
// We push each pilot created into a table and return it.
|
||||
lua_pushnumber(L, ++j); // Index start with 1.
|
||||
lua_pushnumber(L, p); // value = pilot id.
|
||||
lua_rawset(L, -3); // Store the value in the table.
|
||||
/* We push each pilot created into a table and return it. */
|
||||
lua_pushnumber(L, ++j); /* Index start with 1. */
|
||||
lua_pushnumber(L, p); /* value = pilot id. */
|
||||
lua_rawset(L, -3); /* Store the value in the table. */
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
@ -2,15 +2,15 @@
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
// Check if a flag exists on the variable stack.
|
||||
/* Check if a flag exists on the variable stack. */
|
||||
int var_checkflag(char* str);
|
||||
void var_cleanup(void);
|
||||
|
||||
// Load the libraries for a lua state.
|
||||
/* Load the libraries for a lua state. */
|
||||
int misn_loadLibs(lua_State* L);
|
||||
int misn_loadCondLibs(lua_State* L); // Safe read only stuff.
|
||||
int misn_loadCondLibs(lua_State* L); /* Safe read only stuff. */
|
||||
|
||||
// Individual library stuff.
|
||||
/* Individual library stuff. */
|
||||
int lua_loadMisn(lua_State* L);
|
||||
int lua_loadVar(lua_State* L, int readonly);
|
||||
int lua_loadPlayer(lua_State* L);
|
||||
|
142
src/mission.c
142
src/mission.c
@ -14,24 +14,24 @@
|
||||
#include "player.h"
|
||||
#include "mission.h"
|
||||
|
||||
#define XML_MISSION_ID "Missions" // XML section identifier.
|
||||
#define XML_MISSION_ID "Missions" /* XML section identifier. */
|
||||
#define XML_MISSION_TAG "mission"
|
||||
|
||||
#define MISSION_DATA "../dat/mission.xml"
|
||||
#define MISSION_LUA_PATH "../dat/missions/"
|
||||
|
||||
// Current player missions.
|
||||
/* Current player missions. */
|
||||
static unsigned int mission_id = 0;
|
||||
Mission player_missions[MISSION_MAX];
|
||||
|
||||
// Mission stack.
|
||||
static MissionData* mission_stack = NULL; // Unmuteable after creation.
|
||||
/* Mission stack. */
|
||||
static MissionData* mission_stack = NULL; /* Unmuteable after creation. */
|
||||
static int mission_nstack = 0;
|
||||
|
||||
// Extern.
|
||||
/* Extern. */
|
||||
extern int misn_run(Mission* misn, char* func);
|
||||
|
||||
// Static.
|
||||
/* Static. */
|
||||
static unsigned int mission_genID(void);
|
||||
static int mission_init(Mission* mission, MissionData* misn, int load);
|
||||
static void mission_freeData(MissionData* mission);
|
||||
@ -44,24 +44,24 @@ static MissionData* mission_parse(const xmlNodePtr parent);
|
||||
static int missions_parseActive(xmlNodePtr parent);
|
||||
static int mission_persistData(lua_State* L, xmlTextWriterPtr writer);
|
||||
static int mission_unpersistData(lua_State* L, xmlNodePtr parent);
|
||||
// Extern.
|
||||
/* Extern. */
|
||||
int missions_saveActive(xmlTextWriterPtr writer);
|
||||
int missions_loadActive(xmlNodePtr parent);
|
||||
|
||||
// Generate a new id for the mission.
|
||||
/* Generate a new id for the mission. */
|
||||
static unsigned int mission_genID(void) {
|
||||
unsigned int id;
|
||||
int i;
|
||||
id = ++mission_id; // Default id, not safe if loading.
|
||||
id = ++mission_id; /* Default id, not safe if loading. */
|
||||
|
||||
// We save mission id's, so check for collisions with players missions.
|
||||
/* We save mission id's, so check for collisions with players missions. */
|
||||
for(i = 0; i < MISSION_MAX; i++)
|
||||
if(id == player_missions[i].id) // Mission id was loaded from save.
|
||||
return mission_genID(); // Recursive try again.
|
||||
if(id == player_missions[i].id) /* Mission id was loaded from save. */
|
||||
return mission_genID(); /* Recursive try again. */
|
||||
return id;
|
||||
}
|
||||
|
||||
// Gets the ID from mission name.
|
||||
/* Gets the ID from mission name. */
|
||||
int mission_getID(char* name) {
|
||||
int i;
|
||||
for(i = 0; i < mission_nstack; i++)
|
||||
@ -72,13 +72,13 @@ int mission_getID(char* name) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Get a MissionData based on ID.
|
||||
/* Get a MissionData based on ID. */
|
||||
MissionData* mission_get(int id) {
|
||||
if((id <= 0) || (mission_nstack < id)) return NULL;
|
||||
return &mission_stack[id];
|
||||
}
|
||||
|
||||
// Initialize a mission.
|
||||
/* Initialize a mission. */
|
||||
static int mission_init(Mission* mission, MissionData* misn, int load) {
|
||||
char* buf;
|
||||
uint32_t bufsize;
|
||||
@ -90,23 +90,23 @@ static int mission_init(Mission* mission, MissionData* misn, int load) {
|
||||
|
||||
mission->data = misn;
|
||||
|
||||
// Sane defaults.
|
||||
/* Sane defaults. */
|
||||
mission->title = NULL;
|
||||
mission->desc = NULL;
|
||||
mission->reward = NULL;
|
||||
mission->cargo = NULL;
|
||||
mission->ncargo = 0;
|
||||
|
||||
// Init lua.
|
||||
/* Init lua. */
|
||||
mission->L = luaL_newstate();
|
||||
if(mission->L == NULL) {
|
||||
ERR("Unable to create a new lua state.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//luaopen_base(mission->L); // Can be useful.
|
||||
luaopen_string(mission->L); // string.format can be very useful.
|
||||
misn_loadLibs(mission->L); // Load our custom libraries.
|
||||
/*luaopen_base(mission->L); // Can be useful. */
|
||||
luaopen_string(mission->L); /* string.format can be very useful. */
|
||||
misn_loadLibs(mission->L); /* Load our custom libraries. */
|
||||
|
||||
buf = pack_readfile(DATA, misn->lua, &bufsize);
|
||||
if(luaL_dobuffer(mission->L, buf, bufsize, misn->lua) != 0) {
|
||||
@ -117,14 +117,14 @@ static int mission_init(Mission* mission, MissionData* misn, int load) {
|
||||
}
|
||||
free(buf);
|
||||
|
||||
// Run create function.
|
||||
if(load == 0) // Never run when loading.
|
||||
/* Run create function. */
|
||||
if(load == 0) /* Never run when loading. */
|
||||
misn_run(mission, "create");
|
||||
|
||||
return mission->id;
|
||||
}
|
||||
|
||||
// Small wrapper for misn_run.
|
||||
/* Small wrapper for misn_run. */
|
||||
int mission_accept(Mission* mission) {
|
||||
int ret;
|
||||
ret = misn_run(mission, "accept");
|
||||
@ -132,7 +132,7 @@ int mission_accept(Mission* mission) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check to see if mission is already running.
|
||||
/* Check to see if mission is already running. */
|
||||
static int mission_alreadyRunning(MissionData* misn) {
|
||||
int i;
|
||||
for (i = 0; i < MISSION_MAX; i++)
|
||||
@ -142,14 +142,14 @@ static int mission_alreadyRunning(MissionData* misn) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Is the lua condition for misn met?
|
||||
/* Is the lua condition for misn met? */
|
||||
static lua_State* mission_cond_L = NULL;
|
||||
static int mission_meetCond(MissionData* misn) {
|
||||
int ret;
|
||||
char buf[256];
|
||||
|
||||
if(mission_cond_L == NULL) {
|
||||
// Must create the conditional environment.
|
||||
/* Must create the conditional environment. */
|
||||
mission_cond_L = luaL_newstate();
|
||||
misn_loadCondLibs(mission_cond_L);
|
||||
}
|
||||
@ -196,31 +196,31 @@ static int mission_meetCond(MissionData* misn) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Does the mission meet the minimum requirements?
|
||||
/* Does the mission meet the minimum requirements? */
|
||||
static int mission_meetReq(int mission, int faction, char* planet, char* system) {
|
||||
MissionData* misn;
|
||||
|
||||
misn = &mission_stack[mission];
|
||||
|
||||
// Must match planet, system or faction.
|
||||
/* Must match planet, system or faction. */
|
||||
if(!(((misn->avail.planet && strcmp(misn->avail.planet, planet)==0)) ||
|
||||
(misn->avail.system && (strcmp(misn->avail.system, system)==0)) ||
|
||||
mission_matchFaction(misn, faction)))
|
||||
return 0;
|
||||
|
||||
if(mis_isFlag(misn, MISSION_UNIQUE) && // Mission done, or running.
|
||||
if(mis_isFlag(misn, MISSION_UNIQUE) && /* Mission done, or running. */
|
||||
(player_missionAlreadyDone(mission) ||
|
||||
mission_alreadyRunning(misn)))
|
||||
return 0;
|
||||
|
||||
if((misn->avail.cond != NULL) && // Mission doesn't meet the requirement.
|
||||
if((misn->avail.cond != NULL) && /* Mission doesn't meet the requirement. */
|
||||
!mission_meetCond(misn))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Runs bar missions, all lua side and one-shot.
|
||||
/* Runs bar missions, all lua side and one-shot. */
|
||||
void missions_bar(int faction, char* planet, char* system) {
|
||||
MissionData* misn;
|
||||
Mission mission;
|
||||
@ -237,20 +237,20 @@ void missions_bar(int faction, char* planet, char* system) {
|
||||
|
||||
if(RNGF() < chance) {
|
||||
mission_init(&mission, misn, 0);
|
||||
mission_cleanup(&mission); // It better clean up for itself or we do it.
|
||||
mission_cleanup(&mission); /* It better clean up for itself or we do it. */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Links cargo to the mission for posterior cleanup.
|
||||
/* Links cargo to the mission for posterior cleanup. */
|
||||
void mission_linkCargo(Mission* misn, unsigned int cargo_id) {
|
||||
misn->ncargo++;
|
||||
misn->cargo = realloc(misn->cargo, sizeof(unsigned int) * misn->ncargo);
|
||||
misn->cargo[misn->ncargo-1] = cargo_id;
|
||||
}
|
||||
|
||||
// Unlink cargo from the mission, removes it from the player.
|
||||
/* Unlink cargo from the mission, removes it from the player. */
|
||||
void mission_unlinkCargo(Mission* misn, unsigned int cargo_id) {
|
||||
int i;
|
||||
|
||||
@ -258,13 +258,13 @@ void mission_unlinkCargo(Mission* misn, unsigned int cargo_id) {
|
||||
if(misn->cargo[i] == cargo_id)
|
||||
break;
|
||||
|
||||
if(i >= misn->ncargo) { // Not found.
|
||||
if(i >= misn->ncargo) { /* Not found. */
|
||||
DEBUG("Mission '%s' attempting to unlink in existant cargo %d.",
|
||||
misn->title, cargo_id);
|
||||
return;
|
||||
}
|
||||
|
||||
// Shrink cargo size - No need to realloc.
|
||||
/* Shrink cargo size - No need to realloc. */
|
||||
memmove(&misn->cargo[i], &misn->cargo[i+1],
|
||||
sizeof(unsigned int) * (misn->ncargo-i-1));
|
||||
|
||||
@ -272,11 +272,11 @@ void mission_unlinkCargo(Mission* misn, unsigned int cargo_id) {
|
||||
player_rmMissionCargo(cargo_id);
|
||||
}
|
||||
|
||||
// Clean up a mission.
|
||||
/* Clean up a mission. */
|
||||
void mission_cleanup(Mission* misn) {
|
||||
int i;
|
||||
if(misn->id != 0) {
|
||||
hook_rmParent(misn->id); // Remove existing hooks.
|
||||
hook_rmParent(misn->id); /* Remove existing hooks. */
|
||||
misn->id = 0;
|
||||
}
|
||||
if(misn->title != NULL) {
|
||||
@ -304,7 +304,7 @@ void mission_cleanup(Mission* misn) {
|
||||
}
|
||||
}
|
||||
|
||||
// Free a mission.
|
||||
/* Free a mission. */
|
||||
static void mission_freeData(MissionData* mission) {
|
||||
if(mission->name) free(mission->name);
|
||||
if(mission->lua) free(mission->lua);
|
||||
@ -314,7 +314,7 @@ static void mission_freeData(MissionData* mission) {
|
||||
memset(mission, 0, sizeof(MissionData));
|
||||
}
|
||||
|
||||
// Does mission match faction requirement?
|
||||
/* Does mission match faction requirement? */
|
||||
static int mission_matchFaction(MissionData* misn, int faction) {
|
||||
int i;
|
||||
|
||||
@ -328,7 +328,7 @@ static int mission_matchFaction(MissionData* misn, int faction) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Generate missions for the computer - special case.
|
||||
/* Generate missions for the computer - special case. */
|
||||
Mission* missions_computer(int* n, int faction, char* planet, char* system) {
|
||||
int i, j, m;
|
||||
double chance;
|
||||
@ -348,7 +348,7 @@ Mission* missions_computer(int* n, int faction, char* planet, char* system) {
|
||||
rep = misn->avail.chance/100;
|
||||
|
||||
for(j = 0; j < rep; j++)
|
||||
// Random chance of rep appearances.
|
||||
/* Random chance of rep appearances. */
|
||||
if(RNGF() < chance) {
|
||||
tmp = realloc(tmp, sizeof(Mission) * ++m);
|
||||
mission_init(&tmp[m-1], misn, 0);
|
||||
@ -359,7 +359,7 @@ Mission* missions_computer(int* n, int faction, char* planet, char* system) {
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// Return location based on string.
|
||||
/* Return location based on string. */
|
||||
static int mission_location(char* loc) {
|
||||
if(strcmp(loc, "None")==0) return MIS_AVAIL_NONE;
|
||||
else if(strcmp(loc, "Computer")==0) return MIS_AVAIL_COMPUTER;
|
||||
@ -371,7 +371,7 @@ static int mission_location(char* loc) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Parse a node of a mission.
|
||||
/* Parse a node of a mission. */
|
||||
static MissionData* mission_parse(const xmlNodePtr parent) {
|
||||
MissionData* tmp;
|
||||
xmlNodePtr cur, node;
|
||||
@ -379,7 +379,7 @@ static MissionData* mission_parse(const xmlNodePtr parent) {
|
||||
tmp = malloc(sizeof(MissionData));
|
||||
memset(tmp, 0, sizeof(MissionData));
|
||||
|
||||
// Get the name.
|
||||
/* Get the name. */
|
||||
tmp->name = xml_nodeProp(parent, "name");
|
||||
if(tmp->name == NULL) WARN("Mission in "MISSION_DATA" has invalid or no name");
|
||||
|
||||
@ -387,21 +387,21 @@ static MissionData* mission_parse(const xmlNodePtr parent) {
|
||||
|
||||
char str[PATH_MAX] = "\0";
|
||||
|
||||
// Load all the data.
|
||||
/* Load all the data. */
|
||||
do {
|
||||
if(xml_isNode(node, "lua")) {
|
||||
snprintf(str, PATH_MAX, MISSION_LUA_PATH"%s.lua", xml_get(node));
|
||||
tmp->lua = strdup(str);
|
||||
str[0] = '\0';
|
||||
}
|
||||
else if(xml_isNode(node, "flags")) { // Set the various flags.
|
||||
else if(xml_isNode(node, "flags")) { /* Set the various flags. */
|
||||
cur = node->children;
|
||||
do {
|
||||
if(xml_isNode(cur, "unique"))
|
||||
mis_setFlag(tmp, MISSION_UNIQUE);
|
||||
} while(xml_nextNode(cur));
|
||||
}
|
||||
else if(xml_isNode(node, "avail")) { // Mission availability.
|
||||
else if(xml_isNode(node, "avail")) { /* Mission availability. */
|
||||
cur = node->children;
|
||||
do {
|
||||
if(xml_isNode(cur, "location"))
|
||||
@ -438,7 +438,7 @@ static MissionData* mission_parse(const xmlNodePtr parent) {
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// Load/Free.
|
||||
/* Load/Free. */
|
||||
int missions_load(void) {
|
||||
uint32_t bufsize;
|
||||
char* buf = pack_readfile(DATA, MISSION_DATA, &bufsize);
|
||||
@ -455,7 +455,7 @@ int missions_load(void) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
node = node->xmlChildrenNode; // First mission node.
|
||||
node = node->xmlChildrenNode; /* First mission node. */
|
||||
if(node == NULL) {
|
||||
ERR("Malformed '"MISSION_DATA"' file: does not contain elements");
|
||||
return -1;
|
||||
@ -483,7 +483,7 @@ int missions_load(void) {
|
||||
void missions_free(void) {
|
||||
int i;
|
||||
|
||||
// Free the mission data.
|
||||
/* Free the mission data. */
|
||||
for(i = 0; i < mission_nstack; i++)
|
||||
mission_freeData(&mission_stack[i]);
|
||||
free(mission_stack);
|
||||
@ -503,7 +503,7 @@ void missions_cleanup(void) {
|
||||
mission_cleanup(&player_missions[i]);
|
||||
}
|
||||
|
||||
// Persists partial lua data.
|
||||
/* Persists partial lua data. */
|
||||
static int mission_saveData(xmlTextWriterPtr writer, char* type,
|
||||
char* name, char* value) {
|
||||
|
||||
@ -513,16 +513,16 @@ static int mission_saveData(xmlTextWriterPtr writer, char* type,
|
||||
xmlw_attr(writer, "name", name);
|
||||
xmlw_str(writer, "%s", value);
|
||||
|
||||
xmlw_endElem(writer); // data.
|
||||
xmlw_endElem(writer); /* data. */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mission_persistData(lua_State* L, xmlTextWriterPtr writer) {
|
||||
lua_pushnil(L);
|
||||
// nil.
|
||||
/* nil. */
|
||||
while(lua_next(L, LUA_GLOBALSINDEX) != 0) {
|
||||
// key, value.
|
||||
/* key, value. */
|
||||
switch(lua_type(L, -1)) {
|
||||
case LUA_TNUMBER:
|
||||
mission_saveData(writer, "number",
|
||||
@ -540,12 +540,12 @@ static int mission_persistData(lua_State* L, xmlTextWriterPtr writer) {
|
||||
break;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
// Key.
|
||||
/* Key. */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Unpersist lua data.
|
||||
/* Unpersist lua data. */
|
||||
static int mission_unpersistData(lua_State* L, xmlNodePtr parent) {
|
||||
xmlNodePtr node;
|
||||
char* name, *type;
|
||||
@ -556,7 +556,7 @@ static int mission_unpersistData(lua_State* L, xmlNodePtr parent) {
|
||||
xmlr_attr(node, "name", name);
|
||||
xmlr_attr(node, "type", type);
|
||||
|
||||
// Handle data types.
|
||||
/* Handle data types. */
|
||||
if(strcmp(type, "number")==0)
|
||||
lua_pushnumber(L, xml_getFloat(node));
|
||||
else if(strcmp(type, "bool")==0)
|
||||
@ -587,7 +587,7 @@ int missions_saveActive(xmlTextWriterPtr writer) {
|
||||
if(player_missions[i].id != 0) {
|
||||
xmlw_startElem(writer, "mission");
|
||||
|
||||
// Data and id are attributes because they must be loaded first.
|
||||
/* Data and id are attributes because they must be loaded first. */
|
||||
xmlw_attr(writer, "data", player_missions[i].data->name);
|
||||
xmlw_attr(writer, "id", "%u", player_missions[i].id);
|
||||
|
||||
@ -598,20 +598,20 @@ int missions_saveActive(xmlTextWriterPtr writer) {
|
||||
xmlw_startElem(writer, "cargos");
|
||||
for(j = 0; j < player_missions[i].ncargo; j++)
|
||||
xmlw_elem(writer, "cargo", "%u", player_missions[i].cargo[j]);
|
||||
xmlw_endElem(writer); // Cargo.
|
||||
xmlw_endElem(writer); /* Cargo. */
|
||||
|
||||
// Write lua magic.
|
||||
/* Write lua magic. */
|
||||
xmlw_startElem(writer, "lua");
|
||||
|
||||
// Prepare the data.
|
||||
/* Prepare the data. */
|
||||
mission_persistData(player_missions[i].L, writer);
|
||||
|
||||
xmlw_endElem(writer); // Lua.
|
||||
xmlw_endElem(writer); /* Lua. */
|
||||
|
||||
xmlw_endElem(writer); // Mission.
|
||||
xmlw_endElem(writer); /* Mission. */
|
||||
}
|
||||
}
|
||||
xmlw_endElem(writer); // Missions.
|
||||
xmlw_endElem(writer); /* Missions. */
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -619,7 +619,7 @@ int missions_saveActive(xmlTextWriterPtr writer) {
|
||||
int missions_loadActive(xmlNodePtr parent) {
|
||||
xmlNodePtr node;
|
||||
|
||||
// Cleanup old missions.
|
||||
/* Cleanup old missions. */
|
||||
missions_cleanup();
|
||||
|
||||
node = parent->xmlChildrenNode;
|
||||
@ -638,18 +638,18 @@ static int missions_parseActive(xmlNodePtr parent) {
|
||||
|
||||
xmlNodePtr node, cur, nest;
|
||||
|
||||
m = 0; // Start with mission 0.
|
||||
m = 0; /* Start with mission 0. */
|
||||
node = parent->xmlChildrenNode;
|
||||
do {
|
||||
if(xml_isNode(node, "mission")) {
|
||||
misn = &player_missions[m];
|
||||
|
||||
// Process the attributes to create the mission.
|
||||
/* Process the attributes to create the mission. */
|
||||
xmlr_attr(node, "data", buf);
|
||||
mission_init(misn, mission_get(mission_getID(buf)), 1);
|
||||
free(buf);
|
||||
|
||||
// This will orphan an identifier.
|
||||
/* This will orphan an identifier. */
|
||||
xmlr_attr(node, "id", buf);
|
||||
misn->id = atol(buf);
|
||||
free(buf);
|
||||
@ -669,12 +669,12 @@ static int missions_parseActive(xmlNodePtr parent) {
|
||||
}
|
||||
|
||||
if(xml_isNode(cur, "lua"))
|
||||
// Start the unpersist routine.
|
||||
/* Start the unpersist routine. */
|
||||
mission_unpersistData(misn->L, cur);
|
||||
} while(xml_nextNode(cur));
|
||||
|
||||
m++;
|
||||
if(m >= MISSION_MAX) break; // Full of missions, must be an error.
|
||||
if(m >= MISSION_MAX) break; /* Full of missions, must be an error. */
|
||||
}
|
||||
} while(xml_nextNode(node));
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#include "misn_lua.h"
|
||||
|
||||
// Availability by location.
|
||||
/* Availability by location. */
|
||||
#define MIS_AVAIL_NONE 0
|
||||
#define MIS_AVAIL_COMPUTER 1
|
||||
#define MIS_AVAIL_BAR 2
|
||||
@ -9,73 +9,73 @@
|
||||
#define MIS_AVAIL_SHIPYARD 4
|
||||
#define MIS_AVAIL_LAND 5
|
||||
|
||||
// Flags.
|
||||
/* Flags. */
|
||||
#define mis_isFlag(m,f) ((m)->flags & (f))
|
||||
#define mis_setFlag(m,f) ((m)->flags |= (f))
|
||||
#define mis_rmFlag(m,f) ((m)->flags ^= (f))
|
||||
|
||||
#define MISSION_UNIQUE 1 // Unique missions can't be repeated.
|
||||
#define MISSION_UNIQUE 1 /* Unique missions can't be repeated. */
|
||||
|
||||
// Static mission data.
|
||||
/* Static mission data. */
|
||||
typedef struct MissionData_ {
|
||||
char* name; // the name of the mission.
|
||||
char* name; /* the name of the mission. */
|
||||
|
||||
// Availability.
|
||||
/* Availability. */
|
||||
struct {
|
||||
int loc; // Location.
|
||||
int chance; // Chance of it appearing.
|
||||
int loc; /* Location. */
|
||||
int chance; /* Chance of it appearing. */
|
||||
|
||||
// For specific cases.
|
||||
/* For specific cases. */
|
||||
char* planet;
|
||||
char* system;
|
||||
|
||||
// For generic cases.
|
||||
/* For generic cases. */
|
||||
int* factions;
|
||||
int nfactions;
|
||||
|
||||
char* cond; // Conditional that must be met.
|
||||
char* cond; /* Conditional that must be met. */
|
||||
} avail;
|
||||
|
||||
unsigned int flags; // Flags to store binary properties.
|
||||
unsigned int flags; /* Flags to store binary properties. */
|
||||
|
||||
char* lua;
|
||||
} MissionData;
|
||||
|
||||
// Active mission.
|
||||
/* Active mission. */
|
||||
typedef struct Mission_ {
|
||||
MissionData* data;
|
||||
// Unique mission identifier, used for keeping track of hooks.
|
||||
/* Unique mission identifier, used for keeping track of hooks. */
|
||||
unsigned int id;
|
||||
|
||||
char* title; // Not to be confused with name..
|
||||
char* desc; // Description of the mission.
|
||||
char* reward; // Rewards - in text.
|
||||
char* title; /* Not to be confused with name.. */
|
||||
char* desc; /* Description of the mission. */
|
||||
char* reward; /* Rewards - in text. */
|
||||
|
||||
// Mission cargo give to the player - Need to cleanup.
|
||||
/* Mission cargo give to the player - Need to cleanup. */
|
||||
unsigned int* cargo;
|
||||
int ncargo;
|
||||
|
||||
lua_State* L; // The state of the running lua code.
|
||||
lua_State* L; /* The state of the running lua code. */
|
||||
} Mission;
|
||||
|
||||
#define MISSION_MAX 6 // No sense in the player having unlimited missions..
|
||||
#define MISSION_MAX 6 /* No sense in the player having unlimited missions.. */
|
||||
extern Mission player_missions[MISSION_MAX];
|
||||
|
||||
// For mission computer.
|
||||
/* For mission computer. */
|
||||
Mission* missions_computer(int* n, int faction, char* planet, char* system);
|
||||
// Player accepted mission - mission computer.
|
||||
/* Player accepted mission - mission computer. */
|
||||
int mission_accept(Mission* mission);
|
||||
void missions_bar(int faction, char* planet, char* system);
|
||||
|
||||
// Misc.
|
||||
/* Misc. */
|
||||
int mission_getID(char* name);
|
||||
MissionData* mission_get(int id);
|
||||
|
||||
// Cargo stuff.
|
||||
/* Cargo stuff. */
|
||||
void mission_linkCargo(Mission* misn, unsigned int cargo_id);
|
||||
void mission_unlinkCargo(Mission* misn, unsigned int cargo_id);
|
||||
|
||||
// Load/Quit.
|
||||
/* Load/Quit. */
|
||||
int missions_load(void);
|
||||
void mission_cleanup(Mission* misn);
|
||||
void missions_free(void);
|
||||
|
132
src/music.c
132
src/music.c
@ -32,12 +32,12 @@
|
||||
|
||||
#define MUSIC_LUA_PATH "../snd/music.lua"
|
||||
|
||||
// Gobal sound mutex.
|
||||
/* Gobal sound mutex. */
|
||||
extern SDL_mutex* sound_lock;
|
||||
|
||||
// Global music lua.
|
||||
/* Global music lua. */
|
||||
static lua_State* music_lua = NULL;
|
||||
// Functions.
|
||||
/* Functions. */
|
||||
static int musicL_load(lua_State* L);
|
||||
static int musicL_play(lua_State* L);
|
||||
static int musicL_stop(lua_State* L);
|
||||
@ -50,36 +50,36 @@ static const luaL_reg music_methods[] = {
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
// Saves the music to ram in this structure.
|
||||
/* Saves the music to ram in this structure. */
|
||||
typedef struct alMusic_ {
|
||||
char name[64]; // Name.
|
||||
char name[64]; /* Name. */
|
||||
Packfile file;
|
||||
OggVorbis_File stream;
|
||||
vorbis_info* info;
|
||||
ALenum format;
|
||||
} alMusic;
|
||||
|
||||
// Song currently playing.
|
||||
/* Song currently playing. */
|
||||
static SDL_mutex* music_vorbis_lock;
|
||||
static alMusic music_vorbis;
|
||||
static ALuint music_buffer[2]; // Front and back buffer.
|
||||
static ALuint music_buffer[2]; /* Front and back buffer. */
|
||||
static ALuint music_source = 0;
|
||||
|
||||
// What is available?
|
||||
/* What is available? */
|
||||
static char** music_selection = NULL;
|
||||
static int nmusic_selection = 0;
|
||||
|
||||
// Volume
|
||||
/* Volume */
|
||||
static ALfloat mvolume = 1.;
|
||||
|
||||
// Vorbis suff.
|
||||
/* Vorbis suff. */
|
||||
static size_t ovpack_read(void* ptr, size_t size,
|
||||
size_t nmemb, void* datasource) {
|
||||
return (ssize_t) pack_read(datasource, ptr, size*nmemb);
|
||||
}
|
||||
|
||||
static int ovpack_retneg(void) { return -1; } // Must return -1.
|
||||
static int ovpack_retzero(void) { return 0; } // Must return 0.
|
||||
static int ovpack_retneg(void) { return -1; } /* Must return -1. */
|
||||
static int ovpack_retzero(void) { return 0; } /* Must return 0. */
|
||||
ov_callbacks ovcall = {
|
||||
.read_func = ovpack_read,
|
||||
.seek_func = (int(*)(void*, ogg_int64_t, int)) ovpack_retneg,
|
||||
@ -87,24 +87,24 @@ ov_callbacks ovcall = {
|
||||
.tell_func = (long(*)(void*))ovpack_retneg
|
||||
};
|
||||
|
||||
// Music stuff.
|
||||
/* Music stuff. */
|
||||
static int stream_loadBuffer(ALuint buffer);
|
||||
static int music_find(void);
|
||||
static int music_loadOGG(const char* filename);
|
||||
static void music_free(void);
|
||||
// Lua stuff.
|
||||
/* Lua stuff. */
|
||||
static int music_luaInit(void);
|
||||
static void music_luaQuit(void);
|
||||
|
||||
// The thread.
|
||||
/* The thread. */
|
||||
static unsigned int music_state = 0;
|
||||
int music_thread(void* unused) {
|
||||
(void)unused;
|
||||
|
||||
int active; // Active buffer.
|
||||
int active; /* Active buffer. */
|
||||
ALint stat;
|
||||
|
||||
// Main loop.
|
||||
/* Main loop. */
|
||||
while(!music_is(MUSIC_KILL)) {
|
||||
if(music_is(MUSIC_PLAYING)) {
|
||||
if(music_vorbis.file.end == 0)
|
||||
@ -112,18 +112,18 @@ int music_thread(void* unused) {
|
||||
else {
|
||||
music_rm(MUSIC_STOPPED);
|
||||
|
||||
musicLock(); // Lock the mutex.
|
||||
musicLock(); /* Lock the mutex. */
|
||||
soundLock();
|
||||
|
||||
// Start playing current song.
|
||||
active = 0; // Load first buffer.
|
||||
/* Start playing current song. */
|
||||
active = 0; /* Load first buffer. */
|
||||
if(stream_loadBuffer(music_buffer[active])) music_rm(MUSIC_PLAYING);
|
||||
alSourceQueueBuffers(music_source, 1, &music_buffer[active]);
|
||||
|
||||
// Start playing with buffer laoaded.
|
||||
/* Start playing with buffer laoaded. */
|
||||
alSourcePlay(music_source);
|
||||
|
||||
active = 1; // Load the second buffer.
|
||||
active = 1; /* Load the second buffer. */
|
||||
if(stream_loadBuffer(music_buffer[active])) music_rm(MUSIC_PLAYING);
|
||||
alSourceQueueBuffers(music_source, 1, &music_buffer[active]);
|
||||
|
||||
@ -136,7 +136,7 @@ int music_thread(void* unused) {
|
||||
|
||||
alGetSourcei(music_source, AL_BUFFERS_PROCESSED, &stat);
|
||||
if(stat > 0) {
|
||||
// Refill active buffer.
|
||||
/* Refill active buffer. */
|
||||
alSourceUnqueueBuffers(music_source, 1, &music_buffer[active]);
|
||||
if(stream_loadBuffer(music_buffer[active])) music_rm(MUSIC_PLAYING);
|
||||
alSourceQueueBuffers(music_source, 1, &music_buffer[active]);
|
||||
@ -156,26 +156,26 @@ int music_thread(void* unused) {
|
||||
musicUnlock();
|
||||
}
|
||||
music_set(MUSIC_STOPPED);
|
||||
SDL_Delay(0); // We must not kill resources.
|
||||
SDL_Delay(0); /* We must not kill resources. */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stream_loadBuffer(ALuint buffer) {
|
||||
int size, section, result;
|
||||
char data[BUFFER_SIZE]; // Buffer to hold the data.
|
||||
char data[BUFFER_SIZE]; /* Buffer to hold the data. */
|
||||
|
||||
size = 0;
|
||||
while(size < BUFFER_SIZE) {
|
||||
// Fill up the entire data buffer.
|
||||
/* Fill up the entire data buffer. */
|
||||
result = ov_read(
|
||||
&music_vorbis.stream, // Stream.
|
||||
data + size, // Data.
|
||||
BUFFER_SIZE - size, // Amount to read.
|
||||
0, // Big endian?.
|
||||
2, // 16 bit.
|
||||
1, // Signed.
|
||||
§ion); // Current bitstream.
|
||||
&music_vorbis.stream, /* Stream. */
|
||||
data + size, /* Data. */
|
||||
BUFFER_SIZE - size, /* Amount to read. */
|
||||
0, /* Big endian?. */
|
||||
2, /* 16 bit. */
|
||||
1, /* Signed. */
|
||||
§ion); /* Current bitstream. */
|
||||
|
||||
if(result == 0) return 1;
|
||||
else if(result == OV_HOLE) {
|
||||
@ -188,19 +188,19 @@ static int stream_loadBuffer(ALuint buffer) {
|
||||
}
|
||||
|
||||
size += result;
|
||||
if(size == BUFFER_SIZE) break; // Buffer is full.
|
||||
if(size == BUFFER_SIZE) break; /* Buffer is full. */
|
||||
}
|
||||
// Load the buffer.
|
||||
/* Load the buffer. */
|
||||
alBufferData(buffer, music_vorbis.format, data, BUFFER_SIZE,
|
||||
music_vorbis.info->rate);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Init/Exit.
|
||||
/* Init/Exit. */
|
||||
int music_init(void) {
|
||||
music_vorbis_lock = SDL_CreateMutex();
|
||||
music_vorbis.file.end = 0; // Indication that it's not loaded..
|
||||
music_vorbis.file.end = 0; /* Indication that it's not loaded.. */
|
||||
|
||||
soundLock();
|
||||
|
||||
@ -210,7 +210,7 @@ int music_init(void) {
|
||||
alSourcef(music_source, AL_ROLLOFF_FACTOR, 0.);
|
||||
alSourcei(music_source, AL_SOURCE_RELATIVE, AL_FALSE);
|
||||
|
||||
// Start the lua music stuff.
|
||||
/* Start the lua music stuff. */
|
||||
music_luaInit();
|
||||
|
||||
soundUnlock();
|
||||
@ -225,34 +225,34 @@ int music_makeList(void) {
|
||||
void music_exit(void) {
|
||||
int i;
|
||||
|
||||
// Free the music.
|
||||
/* Free the music. */
|
||||
alDeleteBuffers(2, music_buffer);
|
||||
alDeleteSources(1, &music_source);
|
||||
music_free();
|
||||
|
||||
// Free selection
|
||||
/* Free selection */
|
||||
for(i = 0; i < nmusic_selection; i++)
|
||||
free(music_selection[i]);
|
||||
free(music_selection);
|
||||
|
||||
// Bye bye Lua.
|
||||
/* Bye bye Lua. */
|
||||
music_luaQuit();
|
||||
|
||||
SDL_DestroyMutex(music_vorbis_lock);
|
||||
}
|
||||
|
||||
// Internal music loading ruitines.
|
||||
/* Internal music loading ruitines. */
|
||||
static int music_loadOGG(const char* filename) {
|
||||
// Free currently loaded ogg.
|
||||
/* Free currently loaded ogg. */
|
||||
music_free();
|
||||
|
||||
musicLock();
|
||||
|
||||
// Set the new name.
|
||||
/* Set the new name. */
|
||||
strncpy(music_vorbis.name, filename, 64);
|
||||
music_vorbis.name[64-1] = '\0';
|
||||
|
||||
// Load the new ogg.
|
||||
/* Load the new ogg. */
|
||||
pack_open(&music_vorbis.file, DATA, filename);
|
||||
ov_open_callbacks(&music_vorbis.file, &music_vorbis.stream, NULL, 0, ovcall);
|
||||
music_vorbis.info = ov_info(&music_vorbis.stream, -1);
|
||||
@ -271,26 +271,26 @@ static int music_find(void) {
|
||||
char tmp[64];
|
||||
int len;
|
||||
|
||||
// Get the file list.
|
||||
/* Get the file list. */
|
||||
files = pack_listfiles(data, &nfiles);
|
||||
|
||||
// Load the profiles.
|
||||
/* Load the profiles. */
|
||||
for(i = 0; i < nfiles; i++)
|
||||
if((strncmp(files[i], MUSIC_PREFIX, strlen(MUSIC_PREFIX))==0) &&
|
||||
(strncmp(files[i] + strlen(files[i]) - strlen(MUSIC_SUFFIX),
|
||||
MUSIC_SUFFIX, strlen(MUSIC_SUFFIX))==0)) {
|
||||
|
||||
// Grow the selection size.
|
||||
/* Grow the selection size. */
|
||||
music_selection = realloc(music_selection,++nmusic_selection*sizeof(char*));
|
||||
|
||||
// Remove the prefix and suffix.
|
||||
/* Remove the prefix and suffix. */
|
||||
len = strlen(files[i]) - strlen(MUSIC_SUFFIX MUSIC_PREFIX);
|
||||
strncpy(tmp, files[i] + strlen(MUSIC_PREFIX), len);
|
||||
tmp[MIN(len, 64-1)] = '\0';
|
||||
|
||||
music_selection[nmusic_selection-1] = strdup(tmp);
|
||||
}
|
||||
// Free the char* allocated by pack.
|
||||
/* Free the char* allocated by pack. */
|
||||
for(i = 0; i < nfiles; i++)
|
||||
free(files[i]);
|
||||
free(files);
|
||||
@ -306,7 +306,7 @@ static void music_free(void) {
|
||||
if(music_vorbis.file.end != 0) {
|
||||
ov_clear(&music_vorbis.stream);
|
||||
pack_close(&music_vorbis.file);
|
||||
music_vorbis.file.end = 0; // Somewhat ended.
|
||||
music_vorbis.file.end = 0; /* Somewhat ended. */
|
||||
}
|
||||
|
||||
musicUnlock();
|
||||
@ -315,13 +315,13 @@ static void music_free(void) {
|
||||
void music_volume(const double vol) {
|
||||
if(sound_lock == NULL) return;
|
||||
|
||||
// Sanity check!
|
||||
/* Sanity check! */
|
||||
ALfloat fvol = ABS(vol);
|
||||
if(fvol > 1.) fvol = 1.;
|
||||
|
||||
mvolume = fvol;
|
||||
|
||||
// Only needed if playing!
|
||||
/* Only needed if playing! */
|
||||
if(music_set(MUSIC_PLAYING)) {
|
||||
soundLock();
|
||||
alSourcef(music_source, AL_GAIN, fvol);
|
||||
@ -329,7 +329,7 @@ void music_volume(const double vol) {
|
||||
}
|
||||
}
|
||||
|
||||
// Music control functions.
|
||||
/* Music control functions. */
|
||||
void music_load(const char* name) {
|
||||
if(sound_lock == NULL) return;
|
||||
|
||||
@ -360,9 +360,9 @@ void music_kill(void) {
|
||||
if(!music_is(MUSIC_KILL)) music_set(MUSIC_KILL);
|
||||
}
|
||||
|
||||
// Music lua stuff.
|
||||
/* Music lua stuff. */
|
||||
|
||||
// Initialize.
|
||||
/* Initialize. */
|
||||
static int music_luaInit(void) {
|
||||
char* buf;
|
||||
uint32_t bufsize;
|
||||
@ -372,15 +372,15 @@ static int music_luaInit(void) {
|
||||
|
||||
music_lua = luaL_newstate();
|
||||
|
||||
//luaL_openlibs(music_lua);
|
||||
/*luaL_openlibs(music_lua); */
|
||||
|
||||
lua_loadSpace(music_lua, 1); // Space and time are readonly.
|
||||
lua_loadSpace(music_lua, 1); /* Space and time are readonly. */
|
||||
lua_loadTime(music_lua, 1);
|
||||
lua_loadRnd(music_lua);
|
||||
lua_loadVar(music_lua, 1); // Also read only.
|
||||
lua_loadMusic(music_lua, 0); // Write it.
|
||||
lua_loadVar(music_lua, 1); /* Also read only. */
|
||||
lua_loadMusic(music_lua, 0); /* Write it. */
|
||||
|
||||
// Load the actual lua music code.
|
||||
/* Load the actual lua music code. */
|
||||
buf = pack_readfile(DATA, MUSIC_LUA_PATH, &bufsize);
|
||||
if(luaL_dobuffer(music_lua, buf, bufsize, MUSIC_LUA_PATH) != 0) {
|
||||
ERR("Error loading music file: %s" MUSIC_LUA_PATH);
|
||||
@ -393,7 +393,7 @@ static int music_luaInit(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Destroy.
|
||||
/* Destroy. */
|
||||
static void music_luaQuit(void) {
|
||||
if(music_lua == NULL)
|
||||
return;
|
||||
@ -403,7 +403,7 @@ static void music_luaQuit(void) {
|
||||
}
|
||||
|
||||
int lua_loadMusic(lua_State* L, int read_only) {
|
||||
(void)read_only; // Future proof.
|
||||
(void)read_only; /* Future proof. */
|
||||
luaL_register(L, "music", music_methods);
|
||||
return 0;
|
||||
}
|
||||
@ -414,18 +414,18 @@ int music_choose(char* situation) {
|
||||
lua_getglobal(music_lua, "choose");
|
||||
lua_pushstring(music_lua, situation);
|
||||
if(lua_pcall(music_lua, 1, 0, 0)) {
|
||||
// Error occured.
|
||||
/* Error occured. */
|
||||
WARN("Error while choosing music: %s", (char*)lua_tostring(music_lua, -1));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// The music lua functions.
|
||||
/* The music lua functions. */
|
||||
static int musicL_load(lua_State* L) {
|
||||
char* str;
|
||||
|
||||
// Check parameters.
|
||||
/* Check parameters. */
|
||||
LLUA_MIN_ARGS(1);
|
||||
if(lua_isstring(L, 1)) str = (char*)lua_tostring(L, 1);
|
||||
else LLUA_INVALID_PARAMETER();
|
||||
|
@ -1,22 +1,22 @@
|
||||
#pragma once
|
||||
#include "lua.h"
|
||||
|
||||
// Thread.
|
||||
/* Thread. */
|
||||
int music_thread(void* unused);
|
||||
void music_kill(void);
|
||||
|
||||
// Init/Exit.
|
||||
/* Init/Exit. */
|
||||
int music_init(void);
|
||||
int music_makeList(void);
|
||||
void music_exit(void);
|
||||
|
||||
// Music control.
|
||||
/* Music control. */
|
||||
void music_volume(const double vol);
|
||||
void music_load(const char* name);
|
||||
void music_play(void);
|
||||
void music_stop(void);
|
||||
|
||||
// Lua control.
|
||||
/* Lua control. */
|
||||
int lua_loadMusic(lua_State* L, int read_only);
|
||||
int music_choose(char* situation);
|
||||
|
||||
|
256
src/opengl.c
256
src/opengl.c
@ -14,39 +14,39 @@
|
||||
#include "pack.h"
|
||||
#include "opengl.h"
|
||||
|
||||
// offsets to Adjust the pilot's place onscreen
|
||||
//to be in the middle, even with the GUI.
|
||||
/* offsets to Adjust the pilot's place onscreen */
|
||||
/*to be in the middle, even with the GUI. */
|
||||
extern double gui_xoff;
|
||||
extern double gui_yoff;
|
||||
|
||||
// The screen info, gives data of current opengl settings.
|
||||
/* The screen info, gives data of current opengl settings. */
|
||||
glInfo gl_screen;
|
||||
|
||||
// Our precious camera.
|
||||
/* Our precious camera. */
|
||||
Vec2* gl_camera;
|
||||
|
||||
// Misc.
|
||||
/* Misc. */
|
||||
static int SDL_VFlipSurface(SDL_Surface* surface);
|
||||
static int SDL_IsTrans(SDL_Surface* s, int x, int y);
|
||||
static uint8_t* SDL_MapTrans(SDL_Surface* s);
|
||||
static int pot(int n);
|
||||
// glTexture.
|
||||
/* glTexture. */
|
||||
static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh);
|
||||
static void gl_blitTexture(const glTexture* texture,
|
||||
const double x, const double y,
|
||||
const double tx, const double ty, const glColour* c);
|
||||
|
||||
// PNG.
|
||||
/* PNG. */
|
||||
int write_png(const char* file_name, png_bytep* rows, int w, int h,
|
||||
int colourtype, int bitdepth);
|
||||
// Global.
|
||||
/* Global. */
|
||||
static GLboolean gl_hasExt(char* name);
|
||||
|
||||
// ================
|
||||
// MISC!
|
||||
// ================
|
||||
/* ================ */
|
||||
/* MISC! */
|
||||
/* ================ */
|
||||
|
||||
// Get the closest power of two.
|
||||
/* Get the closest power of two. */
|
||||
static int pot(int n) {
|
||||
int i = 1;
|
||||
while(i < n)
|
||||
@ -54,9 +54,9 @@ static int pot(int n) {
|
||||
return i;
|
||||
}
|
||||
|
||||
// Flips the surface vertically. Return 0 on success.
|
||||
/* Flips the surface vertically. Return 0 on success. */
|
||||
static int SDL_VFlipSurface(SDL_Surface* surface) {
|
||||
// Flip the image.
|
||||
/* Flip the image. */
|
||||
Uint8* rowhi, *rowlo, *tmpbuf;
|
||||
int y;
|
||||
|
||||
@ -76,14 +76,14 @@ static int SDL_VFlipSurface(SDL_Surface* surface) {
|
||||
rowlo -= surface->pitch;
|
||||
}
|
||||
free(tmpbuf);
|
||||
// Might be obvious, but I'm done flipping.
|
||||
/* Might be obvious, but I'm done flipping. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Return true if position (x,y) of s is transparent.
|
||||
/* Return true if position (x,y) of s is transparent. */
|
||||
static int SDL_IsTrans(SDL_Surface* s, int x, int y) {
|
||||
int bpp = s->format->BytesPerPixel;
|
||||
// p is the address to the pixel we want to retrieve.
|
||||
/* p is the address to the pixel we want to retrieve. */
|
||||
Uint8* p = (Uint8*)s->pixels + y * s->pitch + x*bpp;
|
||||
|
||||
Uint32 pixelcolour = 0;
|
||||
@ -105,18 +105,18 @@ static int SDL_IsTrans(SDL_Surface* s, int x, int y) {
|
||||
pixelcolour = *(Uint32*)p;
|
||||
break;
|
||||
}
|
||||
// Test whetehr the pixels color is equal to color of
|
||||
//transparent pixels for that surface.
|
||||
/* Test whetehr the pixels color is equal to color of */
|
||||
/*transparent pixels for that surface. */
|
||||
return (pixelcolour == s->format->colorkey);
|
||||
}
|
||||
|
||||
// Map the surface transparancy.
|
||||
// Return 0 on success.
|
||||
/* Map the surface transparancy. */
|
||||
/* Return 0 on success. */
|
||||
static uint8_t* SDL_MapTrans(SDL_Surface* s) {
|
||||
// Allocate memory for just enough bits to hold all the data we need.
|
||||
/* Allocate memory for just enough bits to hold all the data we need. */
|
||||
int size = s->w*s->h/8 + ((s->w*s->h%8)?1:0);
|
||||
uint8_t* t = malloc(size);
|
||||
memset(t, 0, size); // *must* be set to zero.
|
||||
memset(t, 0, size); /* *must* be set to zero. */
|
||||
|
||||
if(t == NULL) {
|
||||
WARN("Out of memeory");
|
||||
@ -125,13 +125,13 @@ static uint8_t* SDL_MapTrans(SDL_Surface* s) {
|
||||
|
||||
int i, j;
|
||||
for(i = 0; i < s->h; i++)
|
||||
for(j = 0; j < s->w; j++) // Set each bit to be 1 if not transparent or 0 if it is.
|
||||
for(j = 0; j < s->w; j++) /* Set each bit to be 1 if not transparent or 0 if it is. */
|
||||
t[(i*s->w+j)/8] |= (SDL_IsTrans(s,j,i)) ? 0 : (1<<((i*s->w+j)%8));
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
// Take a screenshot.
|
||||
/* Take a screenshot. */
|
||||
void gl_screenshot(const char* filename) {
|
||||
SDL_Surface* screen = SDL_GetVideoSurface();
|
||||
unsigned rowbytes = screen->w * 3;
|
||||
@ -146,12 +146,12 @@ void gl_screenshot(const char* filename) {
|
||||
gl_checkErr();
|
||||
}
|
||||
|
||||
// ================
|
||||
// TEXTURE!
|
||||
// ================
|
||||
/* ================ */
|
||||
/* TEXTURE! */
|
||||
/* ================ */
|
||||
|
||||
// Returns the texture ID.
|
||||
// Stores real sizes in rw/rh (from POT padding).
|
||||
/* Returns the texture ID. */
|
||||
/* Stores real sizes in rw/rh (from POT padding). */
|
||||
static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh) {
|
||||
GLuint texture;
|
||||
SDL_Surface* tmp;
|
||||
@ -160,7 +160,7 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh) {
|
||||
int potw, poth;
|
||||
SDL_Rect rtemp;
|
||||
|
||||
// Make size power of two.
|
||||
/* Make size power of two. */
|
||||
potw = pot(surface->w);
|
||||
poth = pot(surface->h);
|
||||
if(rw)*rw = potw;
|
||||
@ -170,7 +170,7 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh) {
|
||||
rtemp.w = surface->w;
|
||||
rtemp.h = surface->h;
|
||||
|
||||
// Save alpha.
|
||||
/* Save alpha. */
|
||||
saved_flags = surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK);
|
||||
saved_alpha = surface->format->alpha;
|
||||
if((saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA)
|
||||
@ -178,7 +178,7 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh) {
|
||||
if((saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA)
|
||||
SDL_SetColorKey(surface, 0, surface->format->colorkey);
|
||||
|
||||
// Create the temp POT surface.
|
||||
/* Create the temp POT surface. */
|
||||
tmp = SDL_CreateRGBSurface(SDL_SRCCOLORKEY,
|
||||
potw, poth, surface->format->BytesPerPixel*8, RGBMASK);
|
||||
if(tmp == NULL) {
|
||||
@ -191,30 +191,30 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Change the surface to the new blitted one.
|
||||
/* Change the surface to the new blitted one. */
|
||||
SDL_BlitSurface(surface, &rtemp, tmp, &rtemp);
|
||||
SDL_FreeSurface(surface);
|
||||
surface = tmp;
|
||||
|
||||
// Set saved alpha.
|
||||
/* Set saved alpha. */
|
||||
if((saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA)
|
||||
SDL_SetAlpha(surface, 0, 0);
|
||||
|
||||
// Opengl texture binding.
|
||||
glGenTextures(1, &texture); // Create the texure.
|
||||
glBindTexture(GL_TEXTURE_2D, texture); // Load the texture.
|
||||
/* Opengl texture binding. */
|
||||
glGenTextures(1, &texture); /* Create the texure. */
|
||||
glBindTexture(GL_TEXTURE_2D, texture); /* Load the texture. */
|
||||
|
||||
// Filtering, LINEAR is better for scaling, nearest looks nicer, LINEAR
|
||||
// also seems to create a bit of artifacts around the edges.
|
||||
/* Filtering, LINEAR is better for scaling, nearest looks nicer, LINEAR */
|
||||
/* also seems to create a bit of artifacts around the edges. */
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
|
||||
// Now lead the texture data up.
|
||||
/* Now lead the texture data up. */
|
||||
SDL_LockSurface(surface);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, surface->format->BytesPerPixel,
|
||||
surface->w, surface->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels);
|
||||
|
||||
// Cleanup.
|
||||
/* Cleanup. */
|
||||
SDL_UnlockSurface(surface);
|
||||
SDL_FreeSurface(surface);
|
||||
|
||||
@ -223,11 +223,11 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh) {
|
||||
return texture;
|
||||
}
|
||||
|
||||
// Load the SDL_Surface to an openGL texture.
|
||||
/* Load the SDL_Surface to an openGL texture. */
|
||||
glTexture* gl_loadImage(SDL_Surface* surface) {
|
||||
int rw, rh;
|
||||
|
||||
// Set up the texture defaults.
|
||||
/* Set up the texture defaults. */
|
||||
glTexture* texture = MALLOC_L(glTexture);
|
||||
texture->w = (double)surface->w;
|
||||
texture->h = (double)surface->h;
|
||||
@ -246,7 +246,7 @@ glTexture* gl_loadImage(SDL_Surface* surface) {
|
||||
return texture;
|
||||
}
|
||||
|
||||
// Load the image directly as an opengl texture.
|
||||
/* Load the image directly as an opengl texture. */
|
||||
glTexture* gl_newImage(const char* path) {
|
||||
SDL_Surface* tmp, *surface;
|
||||
glTexture* t;
|
||||
@ -266,21 +266,21 @@ glTexture* gl_newImage(const char* path) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
surface = SDL_DisplayFormatAlpha(tmp); // Sets the surface to what we use.
|
||||
surface = SDL_DisplayFormatAlpha(tmp); /* Sets the surface to what we use. */
|
||||
if(surface == 0) {
|
||||
WARN("Error converting image to screen format: %s", SDL_GetError());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SDL_FreeSurface(tmp); // Free the temp surface.
|
||||
SDL_FreeSurface(tmp); /* Free the temp surface. */
|
||||
|
||||
// We have to flip our surfaces to match the ortho.
|
||||
/* We have to flip our surfaces to match the ortho. */
|
||||
if(SDL_VFlipSurface(surface)) {
|
||||
WARN("Error flipping surface");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Do after flipping for collision detection.
|
||||
/* Do after flipping for collision detection. */
|
||||
SDL_LockSurface(surface);
|
||||
trans = SDL_MapTrans(surface);
|
||||
SDL_UnlockSurface(surface);
|
||||
@ -290,7 +290,7 @@ glTexture* gl_newImage(const char* path) {
|
||||
return t;
|
||||
}
|
||||
|
||||
// Load the texture immediately, but also set is as a sprite.
|
||||
/* Load the texture immediately, but also set is as a sprite. */
|
||||
glTexture* gl_newSprite(const char* path, const int sx, const int sy) {
|
||||
glTexture* texture;
|
||||
if((texture = gl_newImage(path)) == NULL)
|
||||
@ -302,45 +302,45 @@ glTexture* gl_newSprite(const char* path, const int sx, const int sy) {
|
||||
return texture;
|
||||
}
|
||||
|
||||
// Free the texture.
|
||||
/* Free the texture. */
|
||||
void gl_freeTexture(glTexture* texture) {
|
||||
glDeleteTextures(1, &texture->texture);
|
||||
if(texture->trans) free(texture->trans);
|
||||
free(texture);
|
||||
}
|
||||
|
||||
// Return true if pixel at pos (x,y) is transparent.
|
||||
/* Return true if pixel at pos (x,y) is transparent. */
|
||||
int gl_isTrans(const glTexture* t, const int x, const int y) {
|
||||
return !(t->trans[(y*(int)(t->w)+x)/8] & (1<<((y*(int)(t->w)+x)%8)));
|
||||
}
|
||||
|
||||
// Set x and y to be the appropriate sprite for glTexture using dir.
|
||||
/* Set x and y to be the appropriate sprite for glTexture using dir. */
|
||||
void gl_getSpriteFromDir(int* x, int* y, const glTexture* t, const double dir) {
|
||||
int s, sx, sy;
|
||||
|
||||
double shard, rdir;
|
||||
|
||||
// What each image represents in angle.
|
||||
/* What each image represents in angle. */
|
||||
shard = 2.0*M_PI / (t->sy*t->sx);
|
||||
|
||||
rdir = dir + shard/2.;
|
||||
if(rdir < 0.) rdir = 0.;
|
||||
|
||||
// Now calculate the sprite we need.
|
||||
/* Now calculate the sprite we need. */
|
||||
s = (int)(rdir / shard);
|
||||
sx = t->sx;
|
||||
sy = t->sy;
|
||||
|
||||
// Make sure the sprite is "in range".
|
||||
/* Make sure the sprite is "in range". */
|
||||
if(s > (sy*sx-1)) s = s % (sy*sx);
|
||||
|
||||
(*x) = s % sx;
|
||||
(*y) = s / sx;
|
||||
}
|
||||
|
||||
// ================
|
||||
// BLITTING!
|
||||
// ================
|
||||
/* ================ */
|
||||
/* BLITTING! */
|
||||
/* ================ */
|
||||
|
||||
static void gl_blitTexture(const glTexture* texture,
|
||||
const double x, const double y,
|
||||
@ -348,14 +348,14 @@ static void gl_blitTexture(const glTexture* texture,
|
||||
|
||||
double tw, th;
|
||||
|
||||
// Texture dimensions.
|
||||
/* Texture dimensions. */
|
||||
tw = texture->sw / texture->rw;
|
||||
th = texture->sh / texture->rh;
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, texture->texture);
|
||||
glBegin(GL_QUADS);
|
||||
// Set colour or default if not set.
|
||||
/* Set colour or default if not set. */
|
||||
if(c == NULL) glColor4d(1., 1., 1., 1.);
|
||||
else COLOUR(*c);
|
||||
|
||||
@ -373,46 +373,46 @@ static void gl_blitTexture(const glTexture* texture,
|
||||
glEnd();
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
// Did anything fail?
|
||||
/* Did anything fail? */
|
||||
gl_checkErr();
|
||||
}
|
||||
|
||||
// Blit the sprite at given position.
|
||||
/* Blit the sprite at given position. */
|
||||
void gl_blitSprite(const glTexture* sprite, const double bx, const double by,
|
||||
const int sx, const int sy, const glColour* c) {
|
||||
|
||||
double x, y, tx, ty;
|
||||
|
||||
// Calculate position - we'll use relative coords to player.
|
||||
/* Calculate position - we'll use relative coords to player. */
|
||||
x = bx - VX(*gl_camera) - sprite->sw/2. + gui_xoff;
|
||||
y = by - VY(*gl_camera) - sprite->sh/2. + gui_yoff;
|
||||
|
||||
// Don't draw if offscreen.
|
||||
/* Don't draw if offscreen. */
|
||||
if((fabs(x) > SCREEN_W/2 + sprite->sw) ||
|
||||
(fabs(y) > SCREEN_H/2 + sprite->sh))
|
||||
return;
|
||||
|
||||
// Texture coords.
|
||||
/* Texture coords. */
|
||||
tx = sprite->sw * (double)(sx)/sprite->rw;
|
||||
ty = sprite->sh * (sprite->sy-(double)sy-1)/sprite->rh;
|
||||
|
||||
// Actual blitting.
|
||||
/* Actual blitting. */
|
||||
gl_blitTexture(sprite, x, y, tx, ty, c);
|
||||
}
|
||||
|
||||
// Like gl_blitSprite but will use the actual direction, for things that
|
||||
// can just rotate around.
|
||||
/* Like gl_blitSprite but will use the actual direction, for things that */
|
||||
/* can just rotate around. */
|
||||
void gl_blitRotate(const glTexture* texture,
|
||||
const double bx, const double by,
|
||||
const double dir, const glColour* c) {
|
||||
|
||||
double x, y;
|
||||
|
||||
// Calculate position - we'll use relative coords to player.
|
||||
/* Calculate position - we'll use relative coords to player. */
|
||||
x = bx - VX(*gl_camera) - texture->sw/2. + gui_xoff;
|
||||
y = by - VY(*gl_camera) - texture->sh/2. + gui_yoff;
|
||||
|
||||
// Don't draw if offscreen.
|
||||
/* Don't draw if offscreen. */
|
||||
if((fabs(x) > SCREEN_W/2 + texture->sw) ||
|
||||
(fabs(y) > SCREEN_H/2 + texture->sh))
|
||||
return;
|
||||
@ -421,31 +421,31 @@ void gl_blitRotate(const glTexture* texture,
|
||||
glPushMatrix();
|
||||
glRotated(dir, 0., 0., 1.);
|
||||
|
||||
// Blit.
|
||||
/* Blit. */
|
||||
gl_blitTexture(texture, x, y, 0, 0, c);
|
||||
|
||||
glPopMatrix(); // GL_PROJECTION.
|
||||
glPopMatrix(); /* GL_PROJECTION. */
|
||||
}
|
||||
|
||||
// Just straight out blit the thing at position.
|
||||
/* Just straight out blit the thing at position. */
|
||||
void gl_blitStatic(const glTexture* texture, const double bx, const double by,
|
||||
const glColour* c) {
|
||||
double x, y;
|
||||
|
||||
// Here we use absolute coords.
|
||||
/* Here we use absolute coords. */
|
||||
x = bx - (double)SCREEN_W/2.;
|
||||
y = by - (double)SCREEN_H/2.;
|
||||
|
||||
// Actual blitting..
|
||||
/* Actual blitting.. */
|
||||
gl_blitTexture(texture, x, y, 0, 0, c);
|
||||
}
|
||||
|
||||
// Bind our precious camera to a vector.
|
||||
/* Bind our precious camera to a vector. */
|
||||
void gl_bindCamera(const Vec2* pos) {
|
||||
gl_camera = (Vec2*)pos;
|
||||
}
|
||||
|
||||
// Draw circles.
|
||||
/* Draw circles. */
|
||||
void gl_drawCircle(const double cx, const double cy, const double r) {
|
||||
double x, y, p;
|
||||
|
||||
@ -492,7 +492,7 @@ void gl_drawCircle(const double cx, const double cy, const double r) {
|
||||
gl_checkErr();
|
||||
}
|
||||
|
||||
// Draw a cirlce in a rect.
|
||||
/* Draw a cirlce in a rect. */
|
||||
#define PIXEL(x,y) \
|
||||
if((x>rx) && (y>ry) && (x<rxw) && (y<ryh)) \
|
||||
glVertex2d(x,y)
|
||||
@ -505,10 +505,10 @@ void gl_drawCircleInRect(const double cx, const double cy, const double r,
|
||||
rxw = rx+rw;
|
||||
ryh = ry+rh;
|
||||
|
||||
// Are we offscreen?
|
||||
/* Are we offscreen? */
|
||||
if((cx+r < rx) || (cy+r < ry) || (cx-r > rxw) || (cy-r > ryh))
|
||||
return;
|
||||
// Can be drawn normally.
|
||||
/* Can be drawn normally. */
|
||||
else if((cx-r > rx) && (cy-r > ry) && (cx+r < rxw) && (cy+r < ryh)) {
|
||||
gl_drawCircle(cx, cy, r);
|
||||
return;
|
||||
@ -558,18 +558,18 @@ void gl_drawCircleInRect(const double cx, const double cy, const double r,
|
||||
}
|
||||
#undef PIXEL
|
||||
|
||||
// ================
|
||||
// GLOBAL.
|
||||
// ================
|
||||
/* ================ */
|
||||
/* GLOBAL. */
|
||||
/* ================ */
|
||||
|
||||
// Check for extensions.
|
||||
/* Check for extensions. */
|
||||
static GLboolean gl_hasExt(char* name) {
|
||||
// ======================================================
|
||||
// Search for name in the extensions string. Use of strstr()
|
||||
// is not sufficient because extensions names can be prefixes of
|
||||
// other extension names. Could use strtol() but the constant
|
||||
// string returned by glGetString can be in read-only memory.
|
||||
// ======================================================
|
||||
/* ====================================================== */
|
||||
/* Search for name in the extensions string. Use of strstr() */
|
||||
/* is not sufficient because extensions names can be prefixes of */
|
||||
/* other extension names. Could use strtol() but the constant */
|
||||
/* string returned by glGetString can be in read-only memory. */
|
||||
/* ====================================================== */
|
||||
|
||||
char* p, *end;
|
||||
size_t len, n;
|
||||
@ -588,8 +588,8 @@ static GLboolean gl_hasExt(char* name) {
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
// Check and report if there's been an error.
|
||||
//#ifndef gl_checkErr // I know, I know, it's a little hackish.
|
||||
/* Check and report if there's been an error. */
|
||||
/*#ifndef gl_checkErr // I know, I know, it's a little hackish. */
|
||||
void gl_checkErr(void) {
|
||||
#ifdef DEBUG
|
||||
GLenum err;
|
||||
@ -597,7 +597,7 @@ void gl_checkErr(void) {
|
||||
|
||||
err = glGetError();
|
||||
|
||||
if(err == GL_NO_ERROR) return; // No error.
|
||||
if(err == GL_NO_ERROR) return; /* No error. */
|
||||
|
||||
switch(err) {
|
||||
case GL_INVALID_ENUM:
|
||||
@ -628,9 +628,9 @@ void gl_checkErr(void) {
|
||||
WARN("OpenGL error: %s", errstr);
|
||||
#endif
|
||||
}
|
||||
//#endif
|
||||
/*#endif */
|
||||
|
||||
// Initialize SDL/OpenGL etc.
|
||||
/* Initialize SDL/OpenGL etc. */
|
||||
int gl_init(void) {
|
||||
int doublebuf, depth, i, j, off, toff, supported;
|
||||
SDL_Rect** modes;
|
||||
@ -639,16 +639,16 @@ int gl_init(void) {
|
||||
|
||||
supported = 0;
|
||||
|
||||
// Initializes video.
|
||||
/* Initializes video. */
|
||||
if(SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
|
||||
WARN("Unable to initialize SDL Video: %s", SDL_GetError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Get available fullscreen modes.
|
||||
/* Get available fullscreen modes. */
|
||||
if(gl_has(OPENGL_FULLSCREEN)) {
|
||||
modes = SDL_ListModes(NULL, SDL_OPENGL | SDL_FULLSCREEN);
|
||||
if(modes == NULL) { // Could happen, but rare.
|
||||
if(modes == NULL) { /* Could happen, but rare. */
|
||||
WARN("No fullscreen modes available");
|
||||
if(flags & SDL_FULLSCREEN) {
|
||||
WARN("Disabling fullscreen mode");
|
||||
@ -663,13 +663,13 @@ int gl_init(void) {
|
||||
DEBUG("\t%dx%d", modes[i]->w, modes[i]->h);
|
||||
if((flags & SDL_FULLSCREEN) && (modes[i]->w == SCREEN_W) &&
|
||||
(modes[i]->h == SCREEN_H))
|
||||
supported = 1; // Mode we asked for is supported.
|
||||
supported = 1; /* Mode we asked for is supported. */
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure fullscreen mode is supported.
|
||||
/* Make sure fullscreen mode is supported. */
|
||||
if((flags & SDL_FULLSCREEN) && !supported) {
|
||||
// Try to get the closest aproximation to mode we asked for.
|
||||
/* Try to get the closest aproximation to mode we asked for. */
|
||||
off = -1;
|
||||
j = 0;
|
||||
for(i = 0; modes[i]; i++) {
|
||||
@ -689,7 +689,7 @@ int gl_init(void) {
|
||||
}
|
||||
}
|
||||
|
||||
// Test the setup - aim for 32.
|
||||
/* Test the setup - aim for 32. */
|
||||
depth = SDL_VideoModeOK(SCREEN_W, SCREEN_H, gl_screen.depth, flags);
|
||||
if(depth == 0)
|
||||
WARN("Video mode %dx%d @ %d bpp not supported"
|
||||
@ -700,13 +700,13 @@ int gl_init(void) {
|
||||
|
||||
gl_screen.depth = depth;
|
||||
|
||||
// Actually creating the screen.
|
||||
/* Actually creating the screen. */
|
||||
if(SDL_SetVideoMode(SCREEN_W, SCREEN_H, gl_screen.depth, flags) == NULL) {
|
||||
ERR("Unable to create OpenGL window: %s", SDL_GetError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Grab some info.
|
||||
/* Grab some info. */
|
||||
SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &gl_screen.r);
|
||||
SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &gl_screen.g);
|
||||
SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &gl_screen.b);
|
||||
@ -715,16 +715,16 @@ int gl_init(void) {
|
||||
if(doublebuf) gl_screen.flags |= OPENGL_DOUBLEBUF;
|
||||
gl_screen.depth = gl_screen.r + gl_screen.g + gl_screen.b + gl_screen.a;
|
||||
|
||||
// Get info about some extensions.
|
||||
/* Get info about some extensions. */
|
||||
if(gl_hasExt("GL_ARB_vertex_shader")==GL_TRUE)
|
||||
gl_screen.flags |= OPENGL_VERT_SHADER;
|
||||
if(gl_hasExt("GL_ARB_fragment_shader")==GL_TRUE)
|
||||
gl_screen.flags |= OPENGL_FRAG_SHADER;
|
||||
|
||||
// Max texture size.
|
||||
/* Max texture size. */
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_screen.tex_max);
|
||||
|
||||
// Debug heaven.
|
||||
/* Debug heaven. */
|
||||
DEBUG("OpenGL Window Created: %dx%d@%dbpp %s", SCREEN_W, SCREEN_H,
|
||||
gl_screen.depth, (gl_has(OPENGL_FULLSCREEN)) ? "fullscreen" : "window");
|
||||
|
||||
@ -739,43 +739,43 @@ int gl_init(void) {
|
||||
DEBUG("No fragment shader extension detected");
|
||||
DEBUG("");
|
||||
|
||||
// Some openGL options.
|
||||
/* Some openGL options. */
|
||||
glClearColor(0., 0., 0., 1.);
|
||||
|
||||
// Enable/Disable.
|
||||
glDisable(GL_DEPTH_TEST); // Set for doing 2D shidazles.
|
||||
//glEnable(GL_TEXTURE_2D); // Don't enable globally, it will break non-texture blits.
|
||||
glDisable(GL_LIGHTING); // No lighting, it is done when rendered.
|
||||
glEnable(GL_BLEND); // Alpha blending ftw.
|
||||
/* Enable/Disable. */
|
||||
glDisable(GL_DEPTH_TEST); /* Set for doing 2D shidazles. */
|
||||
/*glEnable(GL_TEXTURE_2D); // Don't enable globally, it will break non-texture blits. */
|
||||
glDisable(GL_LIGHTING); /* No lighting, it is done when rendered. */
|
||||
glEnable(GL_BLEND); /* Alpha blending ftw. */
|
||||
|
||||
// Models.
|
||||
glShadeModel(GL_FLAT); // Default shade model. Functions should keep this when done..
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Good blend model.
|
||||
/* Models. */
|
||||
glShadeModel(GL_FLAT); /* Default shade model. Functions should keep this when done.. */
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* Good blend model. */
|
||||
|
||||
// Set up the matrix.
|
||||
/* Set up the matrix. */
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(-SCREEN_W /2, // Left edge.
|
||||
SCREEN_W /2, // Right edge.
|
||||
-SCREEN_H /2, // Bottom edge.
|
||||
SCREEN_H /2, // Top edge.
|
||||
-1., // Near.
|
||||
1.); // Far.
|
||||
glOrtho(-SCREEN_W /2, /* Left edge. */
|
||||
SCREEN_W /2, /* Right edge. */
|
||||
-SCREEN_H /2, /* Bottom edge. */
|
||||
SCREEN_H /2, /* Top edge. */
|
||||
-1., /* Near. */
|
||||
1.); /* Far. */
|
||||
|
||||
|
||||
// Finishing touches.
|
||||
glClear(GL_COLOR_BUFFER_BIT); // Must clear the buffer first.
|
||||
/* Finishing touches. */
|
||||
glClear(GL_COLOR_BUFFER_BIT); /* Must clear the buffer first. */
|
||||
gl_checkErr();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Clean up our mess.
|
||||
/* Clean up our mess. */
|
||||
void gl_exit(void) {
|
||||
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
||||
}
|
||||
|
||||
// Saves a png.
|
||||
/* Saves a png. */
|
||||
int write_png(const char* file_name, png_bytep* rows, int w, int h,
|
||||
int colourtype, int bitdepth) {
|
||||
png_structp png_ptr;
|
||||
|
60
src/opengl.h
60
src/opengl.h
@ -5,7 +5,7 @@
|
||||
#include "colour.h"
|
||||
#include "physics.h"
|
||||
|
||||
// Recommended for compatibility bullshit.
|
||||
/* Recommended for compatibility bullshit. */
|
||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||
# define RMASK 0xff000000
|
||||
# define GMASK 0x00ff0000
|
||||
@ -19,7 +19,7 @@
|
||||
#endif
|
||||
#define RGBMASK RMASK,GMASK,BMASK,AMASK
|
||||
|
||||
// Info about opengl screen.
|
||||
/* Info about opengl screen. */
|
||||
#define OPENGL_FULLSCREEN (1<<0)
|
||||
#define OPENGL_DOUBLEBUF (1<<1)
|
||||
#define OPENGL_AA_POINT (1<<2)
|
||||
@ -27,15 +27,15 @@
|
||||
#define OPENGL_AA_POLYGON (1<<4)
|
||||
#define OPENGL_FRAG_SHADER (1<<5)
|
||||
#define OPENGL_VERT_SHADER (1<<6)
|
||||
#define gl_has(f) (gl_screen.flags & (f)) // Check for the flag.
|
||||
#define gl_has(f) (gl_screen.flags & (f)) /* Check for the flag. */
|
||||
typedef struct glInfo_ {
|
||||
int w, h; // Window dimensions.
|
||||
int depth; // Depth in bpp.
|
||||
int r, g, b, a; // Framebuffer values in bits.
|
||||
int flags; // Store different properties.
|
||||
int tex_max; // Max texture size.
|
||||
int w, h; /* Window dimensions. */
|
||||
int depth; /* Depth in bpp. */
|
||||
int r, g, b, a; /* Framebuffer values in bits. */
|
||||
int flags; /* Store different properties. */
|
||||
int tex_max; /* Max texture size. */
|
||||
} glInfo;
|
||||
extern glInfo gl_screen; // Local structure set with gl_init etc.
|
||||
extern glInfo gl_screen; /* Local structure set with gl_init etc. */
|
||||
|
||||
#define SCREEN_W gl_screen.w
|
||||
#define SCREEN_H gl_screen.h
|
||||
@ -43,56 +43,56 @@ extern glInfo gl_screen; // Local structure set with gl_init etc.
|
||||
#define COLOUR(x) glColor4d((x).r, (x).g, (x).b, (x).a)
|
||||
#define ACOLOUR(x,a) glColor4d((x).r, (x).g, (x).b, a)
|
||||
|
||||
// Spritesheet info.
|
||||
/* Spritesheet info. */
|
||||
typedef struct glTexture_ {
|
||||
double w, h; // Real size of the image (excluding POT buffer.
|
||||
double rw, rh; // Size of POT surface.
|
||||
double sx, sy; // Number of sprites on x and y axes.
|
||||
double sw, sh; // Size of each sprite.
|
||||
GLuint texture; // The opengl texture itself.
|
||||
uint8_t* trans; // Maps the transparency.
|
||||
double w, h; /* Real size of the image (excluding POT buffer. */
|
||||
double rw, rh; /* Size of POT surface. */
|
||||
double sx, sy; /* Number of sprites on x and y axes. */
|
||||
double sw, sh; /* Size of each sprite. */
|
||||
GLuint texture; /* The opengl texture itself. */
|
||||
uint8_t* trans; /* Maps the transparency. */
|
||||
} glTexture;
|
||||
|
||||
// gl_texute loading/freeing.
|
||||
glTexture* gl_loadImage(SDL_Surface* surface); // Frees the surface.
|
||||
/* gl_texute loading/freeing. */
|
||||
glTexture* gl_loadImage(SDL_Surface* surface); /* Frees the surface. */
|
||||
glTexture* gl_newImage(const char* path);
|
||||
glTexture* gl_newSprite(const char* path, const int sx, const int sy);
|
||||
void gl_freeTexture(glTexture* texture);
|
||||
|
||||
// Rendering.
|
||||
// Blits a sprite, relative pos.
|
||||
/* Rendering. */
|
||||
/* Blits a sprite, relative pos. */
|
||||
void gl_blitSprite(const glTexture* sprite, const double bx, const double by,
|
||||
const int sx, const int sy, const glColour* c);
|
||||
|
||||
// Blits a texture rotated, relative pos.
|
||||
/* Blits a texture rotated, relative pos. */
|
||||
void gl_blitRotate(const glTexture* texture,
|
||||
const double bx, const double by,
|
||||
const double dir, const glColour* c);
|
||||
|
||||
// Blit the entire image, absolute pos.
|
||||
/* Blit the entire image, absolute pos. */
|
||||
void gl_blitStatic(const glTexture* texture, const double bx, const double by,
|
||||
const glColour* c);
|
||||
|
||||
// Bind the camera to a vector.
|
||||
/* Bind the camera to a vector. */
|
||||
void gl_bindCamera(const Vec2* pos);
|
||||
|
||||
// Circle drawing.
|
||||
/* Circle drawing. */
|
||||
void gl_drawCircle(const double x, const double y, const double r);
|
||||
void gl_drawCircleInRect(const double x, const double y, const double r,
|
||||
const double rc, const double ry, const double rw,
|
||||
const double rh);
|
||||
|
||||
// Initialize/cleanup.
|
||||
/* Initialize/cleanup. */
|
||||
int gl_init(void);
|
||||
void gl_exit(void);
|
||||
|
||||
// Misc.
|
||||
/* Misc. */
|
||||
int gl_isTrans(const glTexture* t, const int x, const int y);
|
||||
void gl_getSpriteFromDir(int* x, int* y, const glTexture* t, const double dir);
|
||||
void gl_screenshot(const char* filename);
|
||||
//#if DEBUG == 1
|
||||
/*#if DEBUG == 1 */
|
||||
void gl_checkErr(void);
|
||||
//#else
|
||||
//#define gl_checkErr()
|
||||
//#endif
|
||||
/*#else */
|
||||
/*#define gl_checkErr() */
|
||||
/*#endif */
|
||||
|
||||
|
78
src/outfit.c
78
src/outfit.c
@ -18,15 +18,15 @@
|
||||
#define OUTFIT_DATA "../dat/outfit.xml"
|
||||
#define OUTFIT_GFX "../gfx/outfit/"
|
||||
|
||||
extern SDL_mutex* sound_lock; // Sound.c
|
||||
extern SDL_mutex* sound_lock; /* Sound.c */
|
||||
|
||||
// The Stack.
|
||||
/* The Stack. */
|
||||
static Outfit* outfit_stack = NULL;
|
||||
static int outfits = 0;
|
||||
|
||||
// Misc.
|
||||
/* Misc. */
|
||||
static DamageType outfit_strToDamageType(char* buf);
|
||||
// Parsing.
|
||||
/* Parsing. */
|
||||
static int outfit_parseDamage(DamageType* dtype, double* dmg, xmlNodePtr node);
|
||||
static Outfit* outfit_parse(const xmlNodePtr parent);
|
||||
static void outfit_parseSWeapon(Outfit* tmp, const xmlNodePtr parent);
|
||||
@ -35,7 +35,7 @@ static void outfit_parseSAmmo(Outfit* tmp, const xmlNodePtr parent);
|
||||
static void outfit_parseSMod(Outfit* tmp, const xmlNodePtr parent);
|
||||
static void outfit_parseSAfterburner(Outfit* tmp, const xmlNodePtr parent);
|
||||
|
||||
// Return an outfit.
|
||||
/* Return an outfit. */
|
||||
Outfit* outfit_get(const char* name) {
|
||||
int i;
|
||||
for(i = 0; i < outfits; i++)
|
||||
@ -44,7 +44,7 @@ Outfit* outfit_get(const char* name) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Return all the outfits.
|
||||
/* Return all the outfits. */
|
||||
char** outfit_getTech(int* n, const int* tech, const int techmax) {
|
||||
int i, j;
|
||||
char** outfitnames = malloc(sizeof(Outfit*) * outfits);
|
||||
@ -62,7 +62,7 @@ char** outfit_getTech(int* n, const int* tech, const int techmax) {
|
||||
}
|
||||
}
|
||||
|
||||
// Actual size is bigger, but it'll just get freed ;).
|
||||
/* Actual size is bigger, but it'll just get freed ;). */
|
||||
return outfitnames;
|
||||
}
|
||||
|
||||
@ -84,12 +84,12 @@ defualt:
|
||||
}
|
||||
}
|
||||
|
||||
// Return 1 if outfit is a weapon (beam/bolt).
|
||||
/* Return 1 if outfit is a weapon (beam/bolt). */
|
||||
int outfit_isWeapon(const Outfit* o) {
|
||||
return ((o->type == OUTFIT_TYPE_BOLT) || (o->type == OUTFIT_TYPE_BEAM));
|
||||
}
|
||||
|
||||
// Return 1 if outfit is a launcher.
|
||||
/* Return 1 if outfit is a launcher. */
|
||||
int outfit_isLauncher(const Outfit* o) {
|
||||
return((o->type == OUTFIT_TYPE_MISSILE_DUMB) ||
|
||||
(o->type == OUTFIT_TYPE_MISSILE_SEEK) ||
|
||||
@ -98,7 +98,7 @@ int outfit_isLauncher(const Outfit* o) {
|
||||
(o->type == OUTFIT_TYPE_MISSILE_SWARM_SMART));
|
||||
}
|
||||
|
||||
// Return 1 if outfit is weapon ammunition.
|
||||
/* Return 1 if outfit is weapon ammunition. */
|
||||
int outfit_isAmmo(const Outfit* o) {
|
||||
return((o->type == OUTFIT_TYPE_MISSILE_DUMB_AMMO) ||
|
||||
(o->type == OUTFIT_TYPE_MISSILE_SEEK_AMMO) ||
|
||||
@ -113,17 +113,17 @@ int outfit_isTurret(const Outfit* o) {
|
||||
(o->type == OUTFIT_TYPE_TURRET_BEAM));
|
||||
}
|
||||
|
||||
// Return 1 if o is a modification.
|
||||
/* Return 1 if o is a modification. */
|
||||
int outfit_isMod(const Outfit* o) {
|
||||
return (o->type == OUTFIT_TYPE_MODIFICATION);
|
||||
}
|
||||
|
||||
// Return 1 if o is an afterburner.
|
||||
/* Return 1 if o is an afterburner. */
|
||||
int outfit_isAfterburner(const Outfit* o) {
|
||||
return (o->type == OUTFIT_TYPE_AFTERBURNER);
|
||||
}
|
||||
|
||||
// Get the outfit graphics.
|
||||
/* Get the outfit graphics. */
|
||||
glTexture* outfit_gfx(const Outfit* o) {
|
||||
if(outfit_isWeapon(o)) return o->u.blt.gfx_space;
|
||||
else if(outfit_isAmmo(o)) return o->u.amm.gfx_space;
|
||||
@ -131,7 +131,7 @@ glTexture* outfit_gfx(const Outfit* o) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get the outfit spfx if applicable.
|
||||
/* Get the outfit spfx if applicable. */
|
||||
int outfit_spfx(const Outfit* o) {
|
||||
if(outfit_isWeapon(o)) return o->u.blt.spfx;
|
||||
else if(outfit_isAmmo(o)) return o->u.amm.spfx;
|
||||
@ -191,7 +191,7 @@ const char* outfit_getType(const Outfit* o) {
|
||||
return outfit_typename[o->type];
|
||||
}
|
||||
|
||||
// Return the broad outfit type.
|
||||
/* Return the broad outfit type. */
|
||||
const char* outfit_typenamebroad[] = {
|
||||
"NULL",
|
||||
"Weapon",
|
||||
@ -214,7 +214,7 @@ const char* outfit_getTypeBroad(const Outfit* o) {
|
||||
return outfit_typenamebroad[i];
|
||||
}
|
||||
|
||||
// Return the damage type from a str.
|
||||
/* Return the damage type from a str. */
|
||||
static DamageType outfit_strToDamageType(char* buf) {
|
||||
if(strcmp(buf, "energy")==0) return DAMAGE_TYPE_ENERGY;
|
||||
else if(strcmp(buf, "kinetic")==0) return DAMAGE_TYPE_KINETIC;
|
||||
@ -241,14 +241,14 @@ static int outfit_parseDamage(DamageType* dtype, double* dmg, xmlNodePtr node) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Parses the specific area for a weapon and loads it into outfit.
|
||||
/* Parses the specific area for a weapon and loads it into outfit. */
|
||||
static void outfit_parseSWeapon(Outfit* tmp, const xmlNodePtr parent) {
|
||||
xmlNodePtr node;
|
||||
char str[PATH_MAX] = "\0";
|
||||
|
||||
node = parent->xmlChildrenNode;
|
||||
do {
|
||||
// Load all the things.
|
||||
/* Load all the things. */
|
||||
xmlr_float(node, "speed", tmp->u.blt.speed);
|
||||
xmlr_float(node, "delay", tmp->u.blt.delay);
|
||||
xmlr_float(node, "range", tmp->u.blt.range);
|
||||
@ -280,13 +280,13 @@ static void outfit_parseSWeapon(Outfit* tmp, const xmlNodePtr parent) {
|
||||
#undef MELEMENT
|
||||
}
|
||||
|
||||
// Parse the specific area for a launcher and loads it into Outfit.
|
||||
/* Parse the specific area for a launcher and loads it into Outfit. */
|
||||
static void outfit_parseSLauncher(Outfit* tmp, const xmlNodePtr parent) {
|
||||
xmlNodePtr node;
|
||||
node = parent->xmlChildrenNode;
|
||||
|
||||
do {
|
||||
// Load the dataz.
|
||||
/* Load the dataz. */
|
||||
if(xml_isNode(node, "delay")) tmp->u.lau.delay = xml_getInt(node);
|
||||
else if(xml_isNode(node, "ammo")) tmp->u.lau.ammo = strdup(xml_get(node));
|
||||
} while((node = node->next));
|
||||
@ -297,7 +297,7 @@ static void outfit_parseSLauncher(Outfit* tmp, const xmlNodePtr parent) {
|
||||
#undef MELEMENT
|
||||
}
|
||||
|
||||
// Parse the specific area for a weapon and load it into Outfit.
|
||||
/* Parse the specific area for a weapon and load it into Outfit. */
|
||||
static void outfit_parseSAmmo(Outfit* tmp, const xmlNodePtr parent) {
|
||||
xmlNodePtr node;
|
||||
node = parent->xmlChildrenNode;
|
||||
@ -341,13 +341,13 @@ static void outfit_parseSMod(Outfit* tmp, const xmlNodePtr parent) {
|
||||
xmlNodePtr node;
|
||||
node = parent->children;
|
||||
|
||||
// Load all the data.
|
||||
/* Load all the data. */
|
||||
do {
|
||||
// Movement.
|
||||
/* Movement. */
|
||||
xmlr_float(node, "thrust", tmp->u.mod.thrust);
|
||||
xmlr_float(node, "turn", tmp->u.mod.turn);
|
||||
xmlr_float(node, "speed", tmp->u.mod.speed);
|
||||
// Health.
|
||||
/* Health. */
|
||||
xmlr_float(node, "armour", tmp->u.mod.armour);
|
||||
xmlr_float(node, "shield", tmp->u.mod.shield);
|
||||
xmlr_float(node, "energy", tmp->u.mod.energy);
|
||||
@ -359,18 +359,18 @@ static void outfit_parseSMod(Outfit* tmp, const xmlNodePtr parent) {
|
||||
else if(xml_isNode(node, "energy_regen"))
|
||||
tmp->u.mod.energy_regen = xml_getFloat(node)/60.0;
|
||||
|
||||
// Misc.
|
||||
/* Misc. */
|
||||
xmlr_int(node, "cargo", tmp->u.mod.cargo);
|
||||
|
||||
} while((node = node->next));
|
||||
}
|
||||
|
||||
// Parses the afterburner tidbits of the outfit.
|
||||
/* Parses the afterburner tidbits of the outfit. */
|
||||
static void outfit_parseSAfterburner(Outfit* tmp, const xmlNodePtr parent) {
|
||||
xmlNodePtr node;
|
||||
node = parent->children;
|
||||
|
||||
// Must be >= 1.
|
||||
/* Must be >= 1. */
|
||||
tmp->u.afb.thrust_perc = 1.;
|
||||
tmp->u.afb.speed_perc = 1.;
|
||||
|
||||
@ -388,19 +388,19 @@ static void outfit_parseSAfterburner(Outfit* tmp, const xmlNodePtr parent) {
|
||||
} while((node = node->next));
|
||||
}
|
||||
|
||||
// Parse and return Outfits from parent node.
|
||||
/* Parse and return Outfits from parent node. */
|
||||
static Outfit* outfit_parse(const xmlNodePtr parent) {
|
||||
Outfit* tmp = CALLOC_L(Outfit);
|
||||
xmlNodePtr cur, node;
|
||||
char* prop;
|
||||
char str[PATH_MAX] = "\0";
|
||||
|
||||
tmp->name = xml_nodeProp(parent, "name"); // Already malloced.
|
||||
tmp->name = xml_nodeProp(parent, "name"); /* Already malloced. */
|
||||
if(tmp->name == NULL) WARN("Outfit in "OUTFIT_DATA" has invalid or no name");
|
||||
|
||||
node = parent->xmlChildrenNode;
|
||||
do {
|
||||
// Load all the things.
|
||||
/* Load all the things. */
|
||||
if(xml_isNode(node, "general")) {
|
||||
cur = node->children;
|
||||
do {
|
||||
@ -417,16 +417,16 @@ static Outfit* outfit_parse(const xmlNodePtr parent) {
|
||||
} while((cur = cur->next));
|
||||
}
|
||||
else if(xml_isNode(node, "specific")) {
|
||||
// Has to be processed seperately.
|
||||
/* Has to be processed seperately. */
|
||||
|
||||
// Get the type.
|
||||
/* Get the type. */
|
||||
prop = xml_nodeProp(node, "type");
|
||||
if(prop == NULL)
|
||||
ERR("Outfit '%s' element 'specific' missing property 'type'", tmp->name);
|
||||
tmp->type = atoi(prop);
|
||||
free(prop);
|
||||
|
||||
// Is this the secondary weapon?
|
||||
/* Is this the secondary weapon? */
|
||||
prop = xml_nodeProp(node, "secondary");
|
||||
if(prop != NULL) {
|
||||
if((int)atoi(prop)) outfit_setProp(tmp, OUTFIT_PROP_WEAP_SECONDARY);
|
||||
@ -453,7 +453,7 @@ static Outfit* outfit_parse(const xmlNodePtr parent) {
|
||||
MELEMENT(tmp->max==0, "max");
|
||||
MELEMENT(tmp->tech==0, "tech");
|
||||
MELEMENT(tmp->gfx_store==NULL, "gfx_store");
|
||||
//MELEMENT(tmp->mass==0, "mass");
|
||||
/*MELEMENT(tmp->mass==0, "mass"); */
|
||||
MELEMENT(tmp->type==0, "type");
|
||||
MELEMENT(tmp->price==0, "price");
|
||||
MELEMENT(tmp->description==NULL, "description");
|
||||
@ -462,7 +462,7 @@ static Outfit* outfit_parse(const xmlNodePtr parent) {
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// Load all the outfits into the outfit stack.
|
||||
/* Load all the outfits into the outfit stack. */
|
||||
int outfit_load(void) {
|
||||
uint32_t bufsize;
|
||||
char* buf = pack_readfile(DATA, OUTFIT_DATA, &bufsize);
|
||||
@ -478,7 +478,7 @@ int outfit_load(void) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
node = node->xmlChildrenNode; // First system node.
|
||||
node = node->xmlChildrenNode; /* First system node. */
|
||||
if(node == NULL) {
|
||||
ERR("Malformed "OUTFIT_DATA" file: does not contain elements");
|
||||
return -1;
|
||||
@ -502,15 +502,15 @@ int outfit_load(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Frees the outfit stack.
|
||||
/* Frees the outfit stack. */
|
||||
void outfit_free(void) {
|
||||
int i;
|
||||
for(i = 0; i < outfits; i++) {
|
||||
// Free graphics.
|
||||
/* Free graphics. */
|
||||
if(outfit_gfx(&outfit_stack[i]))
|
||||
gl_freeTexture(outfit_gfx(&outfit_stack[i]));
|
||||
|
||||
// Strings.
|
||||
/* Strings. */
|
||||
if(outfit_isLauncher(&outfit_stack[i]) && outfit_stack[i].u.lau.ammo)
|
||||
free(outfit_stack[i].u.lau.ammo);
|
||||
|
||||
|
102
src/outfit.h
102
src/outfit.h
@ -3,10 +3,10 @@
|
||||
#include "sound.h"
|
||||
|
||||
#define outfit_isProp(o,p) ((o)->properties & p)
|
||||
// Property flags.
|
||||
/* Property flags. */
|
||||
#define OUTFIT_PROP_WEAP_SECONDARY (1<<0)
|
||||
|
||||
// Outfit types.
|
||||
/* Outfit types. */
|
||||
typedef enum OutfitType_ {
|
||||
OUTFIT_TYPE_NULL = 0,
|
||||
OUTFIT_TYPE_BOLT = 1,
|
||||
@ -33,94 +33,94 @@ typedef enum DamageType_ {
|
||||
DAMAGE_TYPE_KINETIC = 2
|
||||
} DamageType;
|
||||
|
||||
// An outfit depends a lot on the type.
|
||||
/* An outfit depends a lot on the type. */
|
||||
typedef struct Outfit_ {
|
||||
char* name;
|
||||
|
||||
// General specs.
|
||||
/* General specs. */
|
||||
int max;
|
||||
int tech;
|
||||
int mass;
|
||||
|
||||
// Store stuff.
|
||||
/* Store stuff. */
|
||||
unsigned int price;
|
||||
char* description;
|
||||
|
||||
glTexture* gfx_store; // Store graphic.
|
||||
glTexture* gfx_store; /* Store graphic. */
|
||||
|
||||
int properties; // Properties stored bitwise.
|
||||
int properties; /* Properties stored bitwise. */
|
||||
|
||||
// Type dependant.
|
||||
/* Type dependant. */
|
||||
OutfitType type;
|
||||
union {
|
||||
struct { // Bolt.
|
||||
unsigned int delay; // Delay between shots.
|
||||
double speed; // Speed of shot. (not applicable to beam.
|
||||
struct { /* Bolt. */
|
||||
unsigned int delay; /* Delay between shots. */
|
||||
double speed; /* Speed of shot. (not applicable to beam. */
|
||||
double range;
|
||||
double accuracy; // Desviation accuracy.
|
||||
double energy; // Energy usage.
|
||||
DamageType dtype; // Damage type.
|
||||
double damage; // Damage.
|
||||
double accuracy; /* Desviation accuracy. */
|
||||
double energy; /* Energy usage. */
|
||||
DamageType dtype; /* Damage type. */
|
||||
double damage; /* Damage. */
|
||||
|
||||
glTexture* gfx_space;
|
||||
ALuint sound; // Sound to play.
|
||||
int spfx; // Special effect on hit.
|
||||
ALuint sound; /* Sound to play. */
|
||||
int spfx; /* Special effect on hit. */
|
||||
} blt;
|
||||
struct { // Beam.
|
||||
double range; // Distance it travels.
|
||||
glColour colour; // Beam colour.
|
||||
double energy; // Energy drained.
|
||||
double damage_armour, damage_shield; // Damage.
|
||||
struct { /* Beam. */
|
||||
double range; /* Distance it travels. */
|
||||
glColour colour; /* Beam colour. */
|
||||
double energy; /* Energy drained. */
|
||||
double damage_armour, damage_shield; /* Damage. */
|
||||
} bem;
|
||||
struct { // Launcher.
|
||||
unsigned int delay; // Delay between shots.
|
||||
struct { /* Launcher. */
|
||||
unsigned int delay; /* Delay between shots. */
|
||||
char* ammo;
|
||||
} lau;
|
||||
struct { // Ammo.
|
||||
unsigned int duration; // Duration.
|
||||
double speed; // Max speed.
|
||||
double turn; // Turn vel.
|
||||
double thrust; // Acceleration.
|
||||
double energy; // Energy usage.
|
||||
DamageType dtype; // Damage type.
|
||||
double damage; // Damage.
|
||||
struct { /* Ammo. */
|
||||
unsigned int duration; /* Duration. */
|
||||
double speed; /* Max speed. */
|
||||
double turn; /* Turn vel. */
|
||||
double thrust; /* Acceleration. */
|
||||
double energy; /* Energy usage. */
|
||||
DamageType dtype; /* Damage type. */
|
||||
double damage; /* Damage. */
|
||||
|
||||
glTexture* gfx_space;
|
||||
ALuint sound; // Sound to play.
|
||||
int spfx; // Special effect on hit.
|
||||
unsigned int lockon; // Time taken to lock on the target.
|
||||
ALuint sound; /* Sound to play. */
|
||||
int spfx; /* Special effect on hit. */
|
||||
unsigned int lockon; /* Time taken to lock on the target. */
|
||||
} amm;
|
||||
struct { // Modification.
|
||||
// Movement.
|
||||
struct { /* Modification. */
|
||||
/* Movement. */
|
||||
double thrust, turn, speed;
|
||||
|
||||
// Health.
|
||||
/* Health. */
|
||||
double armour, armour_regen;
|
||||
double shield, shield_regen;
|
||||
double energy, energy_regen;
|
||||
double fuel;
|
||||
|
||||
// Misc.
|
||||
int cargo; // Cargo space to add.
|
||||
/* Misc. */
|
||||
int cargo; /* Cargo space to add. */
|
||||
} mod;
|
||||
struct { // Afterburner.
|
||||
double rumble; // Percent of rumble.
|
||||
ALuint sound; // Sound of the afterburner.
|
||||
double thrust_perc, thrust_abs; // Percent and absolute thrust bonus.
|
||||
double speed_perc, speed_abs; // Percent and absolute speed bonus.
|
||||
double energy; // Energy used while active.
|
||||
struct { /* Afterburner. */
|
||||
double rumble; /* Percent of rumble. */
|
||||
ALuint sound; /* Sound of the afterburner. */
|
||||
double thrust_perc, thrust_abs; /* Percent and absolute thrust bonus. */
|
||||
double speed_perc, speed_abs; /* Percent and absolute speed bonus. */
|
||||
double energy; /* Energy used while active. */
|
||||
} afb;
|
||||
} u;
|
||||
} Outfit;
|
||||
|
||||
// Misc.
|
||||
/* Misc. */
|
||||
void outfit_calcDamage(double* dshield, double* darmour,
|
||||
DamageType dtype, double dmg);
|
||||
|
||||
// Get.
|
||||
/* Get. */
|
||||
Outfit* outfit_get(const char* name);
|
||||
char** outfit_getTech(int* n, const int* tech, const int techmax);
|
||||
// Outfit types.
|
||||
/* Outfit types. */
|
||||
int outfit_isWeapon(const Outfit* o);
|
||||
int outfit_isLauncher(const Outfit* o);
|
||||
int outfit_isAmmo(const Outfit* o);
|
||||
@ -130,7 +130,7 @@ int outfit_isAfterburner(const Outfit* o);
|
||||
const char* outfit_getType(const Outfit* o);
|
||||
const char* outfit_getTypeBroad(const Outfit* o);
|
||||
|
||||
// Get data from outfit.
|
||||
/* Get data from outfit. */
|
||||
glTexture* outfit_gfx(const Outfit* o);
|
||||
int outfit_spfx(const Outfit* o);
|
||||
double outfit_damage(const Outfit* o);
|
||||
@ -138,7 +138,7 @@ DamageType outfit_damageType(const Outfit* o);
|
||||
int outfit_delay(const Outfit* o);
|
||||
double outfit_energy(const Outfit* o);
|
||||
|
||||
// Load/free outfit stack.
|
||||
/* Load/free outfit stack. */
|
||||
int outfit_load(void);
|
||||
void outfit_free(void);
|
||||
|
||||
|
126
src/pack.c
126
src/pack.c
@ -1,5 +1,5 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h> // S_IRUSR
|
||||
#include <sys/stat.h> /* S_IRUSR */
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
@ -9,39 +9,39 @@
|
||||
#include "log.h"
|
||||
#include "md5.h"
|
||||
|
||||
// == Store data in a funky format. =======================
|
||||
// Format:
|
||||
// -- Index.
|
||||
// -- Magic number (16 bytes).
|
||||
// -- Number of files (uint32_t).
|
||||
// -- Files in format name/location.
|
||||
// -- File name (128 bytes max, ending in \0).
|
||||
// -- File location (uint32_t).
|
||||
// -- File data in format Size/Data.
|
||||
// -- File size (uint32_t).
|
||||
// -- File data (char*).
|
||||
// -- File MD5 (16 byte char*).
|
||||
// -- EOF
|
||||
//
|
||||
// -- Write magic number and number of files.
|
||||
// -- Write the index.
|
||||
// -- Pack the files.
|
||||
// ========================================================
|
||||
/* == Store data in a funky format. ======================= */
|
||||
/* Format: */
|
||||
/* -- Index. */
|
||||
/* -- Magic number (16 bytes). */
|
||||
/* -- Number of files (uint32_t). */
|
||||
/* -- Files in format name/location. */
|
||||
/* -- File name (128 bytes max, ending in \0). */
|
||||
/* -- File location (uint32_t). */
|
||||
/* -- File data in format Size/Data. */
|
||||
/* -- File size (uint32_t). */
|
||||
/* -- File data (char*). */
|
||||
/* -- File MD5 (16 byte char*). */
|
||||
/* -- EOF */
|
||||
/* */
|
||||
/* -- Write magic number and number of files. */
|
||||
/* -- Write the index. */
|
||||
/* -- Pack the files. */
|
||||
/* ======================================================== */
|
||||
|
||||
#undef DEBUG // this will be spammy.
|
||||
#undef DEBUG /* this will be spammy. */
|
||||
#define DEBUG(str, args...) do{;} while(0)
|
||||
|
||||
// The read/write block size.
|
||||
/* The read/write block size. */
|
||||
#define BLOCKSIZE 128*1024
|
||||
|
||||
// Max filename length.
|
||||
/* Max filename length. */
|
||||
#define MAX_FILENAME 100
|
||||
|
||||
#define PERMS S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH
|
||||
|
||||
const uint64_t magic = 0x25524573; // sER%
|
||||
const uint64_t magic = 0x25524573; /* sER% */
|
||||
|
||||
// Grab the filesize.
|
||||
/* Grab the filesize. */
|
||||
static off_t getfilesize(const char* filename) {
|
||||
#ifdef _POSIX_SOURCE
|
||||
struct stat file;
|
||||
@ -65,7 +65,7 @@ static off_t getfilesize(const char* filename) {
|
||||
#endif
|
||||
}
|
||||
|
||||
// Return true if filename is a Packfile.
|
||||
/* Return true if filename is a Packfile. */
|
||||
int pack_check(const char* filename) {
|
||||
int ret;
|
||||
char* buf;
|
||||
@ -108,7 +108,7 @@ int pack_check(const char* filename) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Pack nfiles, infiles into outfile.
|
||||
/* Pack nfiles, infiles into outfile. */
|
||||
#ifdef _POSIX_SOURCE
|
||||
#define WRITE(b,n) if(write(outfd, b, n)==-1) { \
|
||||
ERR("Error writing to file: %s", strerror(errno)); \
|
||||
@ -133,7 +133,7 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles)
|
||||
const uint8_t b = '\0';
|
||||
|
||||
for(namesize = 0, i = 0; i < nfiles; i++) {
|
||||
// Make sure file exists before writing.
|
||||
/* Make sure file exists before writing. */
|
||||
#ifdef _POSIX_SOURCE
|
||||
if(stat(infiles[i], &file)) {
|
||||
#else
|
||||
@ -150,12 +150,12 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles)
|
||||
namesize += strlen(infiles[i]);
|
||||
}
|
||||
|
||||
indexsize = (sizeof(magic) + 4 + // Magic number and number of files.
|
||||
namesize + // Total length of file names.
|
||||
(1+4)*nfiles); // File size and extra end of string char '\0'.
|
||||
indexsize = (sizeof(magic) + 4 + /* Magic number and number of files. */
|
||||
namesize + /* Total length of file names. */
|
||||
(1+4)*nfiles); /* File size and extra end of string char '\0'. */
|
||||
DEBUG("Index size is %d", indexsize);
|
||||
|
||||
// Create the output file.
|
||||
/* Create the output file. */
|
||||
#ifdef _POSIX_SOURCE
|
||||
outfd = creat(outfile, PERMS);
|
||||
if(outfd == -1) {
|
||||
@ -167,31 +167,31 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Index!
|
||||
/* Index! */
|
||||
buf = malloc(BLOCKSIZE);
|
||||
|
||||
// Magic number.
|
||||
/* Magic number. */
|
||||
WRITE(&magic, sizeof(magic));
|
||||
DEBUG("Wrote magic number");
|
||||
// Number of files.
|
||||
/* Number of files. */
|
||||
WRITE(&nfiles, sizeof(nfiles));
|
||||
DEBUG("Wrote number of files: %d", nfiles);
|
||||
// Create file dependent index part.
|
||||
/* Create file dependent index part. */
|
||||
pointer = indexsize;
|
||||
for(i = 0; i < nfiles; i++) {
|
||||
WRITE(infiles[i], strlen(infiles[i]));
|
||||
DEBUG("File: '%s' at %d", infiles[i], pointer);
|
||||
WRITE(&b, 1);
|
||||
WRITE(&pointer, 4);
|
||||
pointer += 4 + getfilesize(infiles[i]) + 16; // Set pointer to be next file pos.
|
||||
pointer += 4 + getfilesize(infiles[i]) + 16; /* Set pointer to be next file pos. */
|
||||
}
|
||||
|
||||
// Data!
|
||||
/* Data! */
|
||||
md5_state_t md5;
|
||||
md5_byte_t* md5val = malloc(16);
|
||||
for(i = 0; i < nfiles; i++) {
|
||||
bytes = (uint32_t)getfilesize(infiles[i]);
|
||||
WRITE(&bytes, 4); // filesize.
|
||||
WRITE(&bytes, 4); /* filesize. */
|
||||
DEBUG("About to write '%s' of %d bytes", infiles[i], bytes);
|
||||
md5_init(&md5);
|
||||
#ifdef _POSIX_SOURCE
|
||||
@ -201,7 +201,7 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles)
|
||||
inf = fopen(infiles[i], "rb");
|
||||
while((bytes = fread(buf, 1, BLOCKSIZE, inf))) {
|
||||
#endif
|
||||
WRITE(buf, bytes); // Data.
|
||||
WRITE(buf, bytes); /* Data. */
|
||||
md5_append(&md5, buf, bytes);
|
||||
}
|
||||
md5_finish(&md5, md5val);
|
||||
@ -228,7 +228,7 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles)
|
||||
}
|
||||
#undef WRITE
|
||||
|
||||
// Opens the filename in packfile for reading.
|
||||
/* Opens the filename in packfile for reading. */
|
||||
#ifdef _POSIX_SOURCE
|
||||
#define READ(b,n) if(read(file->fd, (b), (n))!=(n)) { \
|
||||
ERR("Too few bytes read. Expected more."); \
|
||||
@ -256,7 +256,7 @@ int pack_open(Packfile* file, const char* packfile, const char* filename) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
READ(buf, sizeof(magic)); // Make sure it's a packfile.
|
||||
READ(buf, sizeof(magic)); /* Make sure it's a packfile. */
|
||||
if(memcmp(buf, &magic, sizeof(magic))) {
|
||||
ERR("File %s is not a valid packfile", filename);
|
||||
return -1;
|
||||
@ -264,20 +264,20 @@ int pack_open(Packfile* file, const char* packfile, const char* filename) {
|
||||
|
||||
READ(&nfiles, 4);
|
||||
for(i = 0; i < nfiles; i++) {
|
||||
// Start to search files.
|
||||
/* Start to search files. */
|
||||
j = 0;
|
||||
READ(&buf[j], 1); // Get the name.
|
||||
READ(&buf[j], 1); /* Get the name. */
|
||||
while(buf[j++] != '\0')
|
||||
READ(&buf[j], 1);
|
||||
|
||||
if(strcmp(filename, buf) == 0) {
|
||||
// We found the file.
|
||||
/* We found the file. */
|
||||
READ(&file->start, 4);
|
||||
DEBUG("'%s' found at %d", filename, file->start);
|
||||
break;
|
||||
}
|
||||
#ifdef _POSIX_SOURCE
|
||||
lseek(file->fd, 4, SEEK_CUR); // Ignore the file location.
|
||||
lseek(file->fd, 4, SEEK_CUR); /* Ignore the file location. */
|
||||
#else
|
||||
fseek(file->fp, 4, SEEK_CUR);
|
||||
#endif
|
||||
@ -285,7 +285,7 @@ int pack_open(Packfile* file, const char* packfile, const char* filename) {
|
||||
free(buf);
|
||||
|
||||
if(file->start) {
|
||||
// Go to the beginning of the file.
|
||||
/* Go to the beginning of the file. */
|
||||
#ifdef _POSIX_SOURCE
|
||||
if((uint32_t)lseek(file->fd, file->start, SEEK_SET) != file->start) {
|
||||
#else
|
||||
@ -307,10 +307,10 @@ int pack_open(Packfile* file, const char* packfile, const char* filename) {
|
||||
}
|
||||
#undef READ
|
||||
|
||||
// Read count bytes from file and put them into buf.
|
||||
/* Read count bytes from file and put them into buf. */
|
||||
ssize_t pack_read(Packfile* file, void* buf, size_t count) {
|
||||
if(file->pos + count > file->end)
|
||||
count = file->end - file->pos; // Can't go past the end!
|
||||
count = file->end - file->pos; /* Can't go past the end! */
|
||||
if(count == 0) return 0;
|
||||
|
||||
int bytes;
|
||||
@ -328,7 +328,7 @@ ssize_t pack_read(Packfile* file, void* buf, size_t count) {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
// Seek in the packfile.
|
||||
/* Seek in the packfile. */
|
||||
off_t pack_seek(Packfile* file, off_t offset, int whence) {
|
||||
DEBUG("Attempting to seek offset: %d, whence: %d", offset, whence);
|
||||
off_t ret;
|
||||
@ -373,12 +373,12 @@ off_t pack_seek(Packfile* file, off_t offset, int whence) {
|
||||
return ret - file->start;
|
||||
}
|
||||
|
||||
// Return current pointer position.
|
||||
/* Return current pointer position. */
|
||||
long pack_tell(Packfile* file) {
|
||||
return file->pos - file->start;
|
||||
}
|
||||
|
||||
// Loads an entire file into memory and returns a pointer to it.
|
||||
/* Loads an entire file into memory and returns a pointer to it. */
|
||||
void* pack_readfile(const char* packfile, const char* filename, uint32_t* filesize) {
|
||||
Packfile* file = (Packfile*)malloc(sizeof(Packfile));
|
||||
void* buf;
|
||||
@ -393,7 +393,7 @@ void* pack_readfile(const char* packfile, const char* filename, uint32_t* filesi
|
||||
}
|
||||
DEBUG("Opened file '%s' from '%s'", filename, packfile);
|
||||
|
||||
// Read the entire file.
|
||||
/* Read the entire file. */
|
||||
size = file->end - file->start;
|
||||
buf = malloc(size+1);
|
||||
if((bytes = pack_read(file, buf, size)) != size) {
|
||||
@ -404,9 +404,9 @@ void* pack_readfile(const char* packfile, const char* filename, uint32_t* filesi
|
||||
return NULL;
|
||||
}
|
||||
DEBUG("Read %d bytes from '%s'", bytes, filename);
|
||||
memset(buf+size, 0, 1); // Append size '\0' for it to validate as a string.
|
||||
memset(buf+size, 0, 1); /* Append size '\0' for it to validate as a string. */
|
||||
|
||||
// Check the md5.
|
||||
/* Check the md5. */
|
||||
md5_state_t md5;
|
||||
md5_byte_t* md5val = malloc(16);
|
||||
md5_byte_t* md5fd = malloc(16);
|
||||
@ -424,7 +424,7 @@ void* pack_readfile(const char* packfile, const char* filename, uint32_t* filesi
|
||||
free(md5val);
|
||||
free(md5fd);
|
||||
|
||||
// Cleanup.
|
||||
/* Cleanup. */
|
||||
if(pack_close(file) == -1) {
|
||||
ERR("Closing packfile");
|
||||
free(file);
|
||||
@ -438,9 +438,9 @@ void* pack_readfile(const char* packfile, const char* filename, uint32_t* filesi
|
||||
return buf;
|
||||
}
|
||||
|
||||
// Load the filenames int the packfile to filenames.
|
||||
// filenames should be freed after use
|
||||
// On error if filenames is (char**)-1.
|
||||
/* Load the filenames int the packfile to filenames. */
|
||||
/* filenames should be freed after use */
|
||||
/* On error if filenames is (char**)-1. */
|
||||
#ifdef _POSIX_SOURCE
|
||||
#define READ(b,n) if(read(fd, (b), (n))!=(n)) { \
|
||||
ERR("Too few bytes read"); \
|
||||
@ -473,7 +473,7 @@ char** pack_listfiles(const char* packfile, uint32_t* nfiles) {
|
||||
ERR("opening %s: %s", packfile, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
READ(buf, sizeof(magic)); // Make sure it is a packfile.
|
||||
READ(buf, sizeof(magic)); /* Make sure it is a packfile. */
|
||||
if(memcmp(buf, &magic, sizeof(magic))) {
|
||||
ERR("File %s is not a valid packfile", packfile);
|
||||
return NULL;
|
||||
@ -482,13 +482,13 @@ char** pack_listfiles(const char* packfile, uint32_t* nfiles) {
|
||||
READ(nfiles, 4);
|
||||
filenames = malloc(((*nfiles)+1)*sizeof(char*));
|
||||
for(i = 0; i < *nfiles; i++) {
|
||||
// Start searching files.
|
||||
/* Start searching files. */
|
||||
j = 0;
|
||||
filenames[i] = malloc(MAX_FILENAME * sizeof(char));
|
||||
READ(&filenames[i][j], 1); // Get the name.
|
||||
READ(&filenames[i][j], 1); /* Get the name. */
|
||||
while(filenames[i][j++] != '\0')
|
||||
READ(&filenames[i][j], 1);
|
||||
READ(buf, 4); // skip the location.
|
||||
READ(buf, 4); /* skip the location. */
|
||||
}
|
||||
free(buf);
|
||||
|
||||
@ -502,7 +502,7 @@ char** pack_listfiles(const char* packfile, uint32_t* nfiles) {
|
||||
}
|
||||
#undef READ
|
||||
|
||||
// Close the packfile.
|
||||
/* Close the packfile. */
|
||||
int pack_close(Packfile* file) {
|
||||
int i;
|
||||
#ifdef _POSIX_SOURCE
|
||||
|
14
src/pack.h
14
src/pack.h
@ -1,23 +1,23 @@
|
||||
#pragma once
|
||||
#include <fcntl.h>
|
||||
#ifndef _POSIX_SOURCE // No posix.
|
||||
#ifndef _POSIX_SOURCE /* No posix. */
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct Packfile_ {
|
||||
#ifdef _POSIX_SOURCE
|
||||
int fd; // File descriptor.
|
||||
int fd; /* File descriptor. */
|
||||
#else
|
||||
FILE* fp;
|
||||
#endif
|
||||
uint32_t pos; // position.
|
||||
uint32_t start, end; // file limits.
|
||||
uint32_t pos; /* position. */
|
||||
uint32_t start, end; /* file limits. */
|
||||
} Packfile;
|
||||
|
||||
// Packfile manipulation. Automatically allocated and freed (with open and close).
|
||||
/* Packfile manipulation. Automatically allocated and freed (with open and close). */
|
||||
|
||||
// Basic.
|
||||
/* Basic. */
|
||||
int pack_check(const char* filename);
|
||||
int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles);
|
||||
int pack_open(Packfile* file, const char* packfile, const char* filename);
|
||||
@ -26,7 +26,7 @@ off_t pack_seek(Packfile* file, off_t offset, int whence);
|
||||
long pack_tell(Packfile* file);
|
||||
int pack_close(Packfile* file);
|
||||
|
||||
// Fancy stuff.
|
||||
/* Fancy stuff. */
|
||||
void* pack_readfile(const char* packfile, const char* filename, uint32_t* filesize);
|
||||
char** pack_listfiles(const char* packfile, uint32_t* nfiles);
|
||||
|
||||
|
22
src/pause.c
22
src/pause.c
@ -3,37 +3,37 @@
|
||||
#include "spfx.h"
|
||||
#include "pause.h"
|
||||
|
||||
// Main thing with pausing is to allow things based on time to
|
||||
// work properly when the toolkit opens a window.
|
||||
/* Main thing with pausing is to allow things based on time to */
|
||||
/* work properly when the toolkit opens a window. */
|
||||
|
||||
int paused = 0; // Are we paused.
|
||||
int paused = 0; /* Are we paused. */
|
||||
|
||||
// From pilot.c
|
||||
/* From pilot.c */
|
||||
extern Pilot** pilot_stack;
|
||||
extern int pilots;
|
||||
// From space.c
|
||||
/* From space.c */
|
||||
extern unsigned int spawn_timer;
|
||||
// From main.c
|
||||
/* From main.c */
|
||||
extern unsigned int gtime;
|
||||
|
||||
static void pilots_pause(void);
|
||||
static void pilots_unpause(void);
|
||||
static void pilots_delay(unsigned int delay);
|
||||
|
||||
// Pause the game.
|
||||
/* Pause the game. */
|
||||
void pause_game(void) {
|
||||
if(paused) return; // Well well.. We are paused already.
|
||||
if(paused) return; /* Well well.. We are paused already. */
|
||||
|
||||
pilots_pause();
|
||||
weapons_pause();
|
||||
spfx_pause();
|
||||
spawn_timer -= SDL_GetTicks();
|
||||
|
||||
paused = 1; // We should unpause it.
|
||||
paused = 1; /* We should unpause it. */
|
||||
}
|
||||
|
||||
void unpause_game(void) {
|
||||
if(!paused) return; // We are unpaused already.
|
||||
if(!paused) return; /* We are unpaused already. */
|
||||
|
||||
pilots_unpause();
|
||||
weapons_unpause();
|
||||
@ -43,7 +43,7 @@ void unpause_game(void) {
|
||||
paused = 0;
|
||||
}
|
||||
|
||||
// Set the timers back.
|
||||
/* Set the timers back. */
|
||||
void pause_delay(unsigned int delay) {
|
||||
pilots_delay(delay);
|
||||
weapons_delay(delay);
|
||||
|
114
src/physics.c
114
src/physics.c
@ -6,9 +6,9 @@
|
||||
#include "log.h"
|
||||
#include "physics.h"
|
||||
|
||||
// ================
|
||||
// MISC
|
||||
// ================
|
||||
/* ================ */
|
||||
/* MISC */
|
||||
/* ================ */
|
||||
double angle_diff(const double ref, double a) {
|
||||
double d;
|
||||
if(a < M_PI) a += 2*M_PI;
|
||||
@ -19,15 +19,15 @@ double angle_diff(const double ref, double a) {
|
||||
void limit_speed(Vec2* vel, const double speed, const double dt) {
|
||||
double vmod;
|
||||
vmod = VMOD(*vel);
|
||||
if(vmod > speed) // Should not go faster.
|
||||
if(vmod > speed) /* Should not go faster. */
|
||||
vect_pset(vel, (vmod-speed)*(1.-dt*3.) + speed, VANGLE(*vel));
|
||||
}
|
||||
|
||||
// ================
|
||||
// VEC2
|
||||
// ================
|
||||
/* ================ */
|
||||
/* VEC2 */
|
||||
/* ================ */
|
||||
|
||||
// Set the vector value using cartesian coords.
|
||||
/* Set the vector value using cartesian coords. */
|
||||
void vect_cset(Vec2* v, const double x, const double y) {
|
||||
v->x = x;
|
||||
v->y = y;
|
||||
@ -35,13 +35,13 @@ void vect_cset(Vec2* v, const double x, const double y) {
|
||||
v->angle = ANGLE(x, y);
|
||||
}
|
||||
|
||||
// Create a minimal vector, only valid for blitting.
|
||||
/* 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.
|
||||
/* Set the vector value using polar coords. */
|
||||
void vect_pset(Vec2* v, const double mod, const double angle) {
|
||||
v->mod = mod;
|
||||
v->angle = angle;
|
||||
@ -49,7 +49,7 @@ void vect_pset(Vec2* v, const double mod, const double angle) {
|
||||
v->y = v->mod*sin(v->angle);
|
||||
}
|
||||
|
||||
// Copy vector source to destination.
|
||||
/* Copy vector source to destination. */
|
||||
void vectcpy(Vec2* dest, const Vec2* src) {
|
||||
dest->x = src->x;
|
||||
dest->y = src->y;
|
||||
@ -57,12 +57,12 @@ void vectcpy(Vec2* dest, const Vec2* src) {
|
||||
dest->angle = src->angle;
|
||||
}
|
||||
|
||||
// Null a vector.
|
||||
/* Null a vector. */
|
||||
void vectnull(Vec2* v) {
|
||||
v->x = v->y = v->mod = v->angle = 0.;
|
||||
}
|
||||
|
||||
// Get the direction pointed to by two vectors (from ref to v).
|
||||
/* Get the direction pointed to by two vectors (from ref to v). */
|
||||
double vect_angle(const Vec2* ref, const Vec2* v) {
|
||||
return ANGLE(v->x - ref->x, v->y - ref->y);
|
||||
}
|
||||
@ -75,23 +75,23 @@ void vect_cadd(Vec2* v, const double x, const double y) {
|
||||
}
|
||||
|
||||
|
||||
// ================
|
||||
// SOLID!
|
||||
// ================
|
||||
/* ================ */
|
||||
/* SOLID! */
|
||||
/* ================ */
|
||||
|
||||
// ==Update method.========================================
|
||||
// d^2 x(t) / d t^2 = a, a = constant (acceleration)
|
||||
// x'(0) = v, x(0) = p
|
||||
//
|
||||
// d x(t) / d t = a*t + v, v = constant (initial velocity)
|
||||
// x(t) = a/2*t + v*t + p, p = constant (initial position)
|
||||
//
|
||||
// Since dt isn't actually differential this gives us an
|
||||
// error, so watch out with big values for dt.
|
||||
// ========================================================
|
||||
#if 0 // Simply commenting this out to avoid silly warnings.
|
||||
/* ==Update method.======================================== */
|
||||
/* d^2 x(t) / d t^2 = a, a = constant (acceleration) */
|
||||
/* x'(0) = v, x(0) = p */
|
||||
/* */
|
||||
/* d x(t) / d t = a*t + v, v = constant (initial velocity) */
|
||||
/* x(t) = a/2*t + v*t + p, p = constant (initial position) */
|
||||
/* */
|
||||
/* Since dt isn't actually differential this gives us an */
|
||||
/* error, so watch out with big values for dt. */
|
||||
/* ======================================================== */
|
||||
#if 0 /* Simply commenting this out to avoid silly warnings. */
|
||||
static void simple_update(Solid* obj, const double dt) {
|
||||
// Make sure angle doesn't flip.
|
||||
/* Make sure angle doesn't flip. */
|
||||
obj->dir += M_PI/360.*obj->dir_vel*dt;
|
||||
if(obj->dir > 2*M_PI) obj->dir -= 2*M_PI;
|
||||
if(obj->dir < 0.) obj->dir += 2*M_PI;
|
||||
@ -102,7 +102,7 @@ static void simple_update(Solid* obj, const double dt) {
|
||||
vx = obj->vel->x;
|
||||
vy = obj->vel->y;
|
||||
|
||||
if(obj->force.mod) { // Force applied on an object.
|
||||
if(obj->force.mod) { /* Force applied on an object. */
|
||||
double ax, ay;
|
||||
ax = obj->force->x/obj->mass;
|
||||
ay = obj->force->y/obj->mass;
|
||||
@ -124,46 +124,46 @@ static void simple_update(Solid* obj, const double dt) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// ==Runge-Kutta 4th method.===============================
|
||||
// d^2 x(t) / d t^2 = a, a = constant(acceleration)
|
||||
// x'(0) = v, x(0) = p
|
||||
// x'' = f(t, x, x') = (x', a)
|
||||
//
|
||||
// x_ {n+1} = x_n + h/6 (k1 + 2*k2 + 3*k3 + k4)
|
||||
// h = (b-a)/2
|
||||
// k1 = f(t_n, X_n), X_n = (x_n, x'_n)
|
||||
// k2 = f(t_n + h/2, X_n + h/2*k1)
|
||||
// k3 = f(t_n + h/2, X_n + h/2*k2)
|
||||
// k4 = f(t_n + h, X_n + h*k3)
|
||||
//
|
||||
// x_{n+1} = x_n + h/6x'_n + 3*h*a, 4*a)
|
||||
// ========================================================
|
||||
/* ==Runge-Kutta 4th method.=============================== */
|
||||
/* d^2 x(t) / d t^2 = a, a = constant(acceleration) */
|
||||
/* x'(0) = v, x(0) = p */
|
||||
/* x'' = f(t, x, x') = (x', a) */
|
||||
/* */
|
||||
/* x_ {n+1} = x_n + h/6 (k1 + 2*k2 + 3*k3 + k4) */
|
||||
/* h = (b-a)/2 */
|
||||
/* k1 = f(t_n, X_n), X_n = (x_n, x'_n) */
|
||||
/* k2 = f(t_n + h/2, X_n + h/2*k1) */
|
||||
/* k3 = f(t_n + h/2, X_n + h/2*k2) */
|
||||
/* k4 = f(t_n + h, X_n + h*k3) */
|
||||
/* */
|
||||
/* x_{n+1} = x_n + h/6x'_n + 3*h*a, 4*a) */
|
||||
/* ======================================================== */
|
||||
|
||||
#define RK4_MIN_H 0.01 // Minimal pass we want.
|
||||
#define RK4_MIN_H 0.01 /* Minimal pass we want. */
|
||||
static void rk4_update(Solid* obj, const double dt) {
|
||||
int i, N; // For iteration and pass calculation.
|
||||
double h, px, py, vx, vy; // Pass and position/velocity values.
|
||||
double ix, iy, tx, ty, ax, ay; // Initial and temp cartesian vector values.
|
||||
// Make sure angle doesn't flip.
|
||||
int i, N; /* For iteration and pass calculation. */
|
||||
double h, px, py, vx, vy; /* Pass and position/velocity values. */
|
||||
double ix, iy, tx, ty, ax, ay; /* Initial and temp cartesian vector values. */
|
||||
/* Make sure angle doesn't flip. */
|
||||
obj->dir += M_PI/180.*obj->dir_vel*dt;
|
||||
if(obj->dir >= 2.*M_PI) obj->dir -= 2*M_PI;
|
||||
else if(obj->dir < 0.) obj->dir += 2*M_PI;
|
||||
|
||||
N = (dt > RK4_MIN_H) ? (int)(dt/RK4_MIN_H) : 1;
|
||||
h = dt / (double)N; // Step.
|
||||
h = dt / (double)N; /* Step. */
|
||||
|
||||
px = obj->pos.x;
|
||||
py = obj->pos.y;
|
||||
vx = obj->vel.x;
|
||||
vy = obj->vel.y;
|
||||
|
||||
if(obj->force.mod) { // Force applied on object.
|
||||
// Movement quantity theorem : m*a = \sum f.
|
||||
if(obj->force.mod) { /* Force applied on object. */
|
||||
/* Movement quantity theorem : m*a = \sum f. */
|
||||
ax = obj->force.x / obj->mass;
|
||||
ay = obj->force.y / obj->mass;
|
||||
|
||||
for(i = 0; i < N; i++) {
|
||||
// X component.
|
||||
/* X component. */
|
||||
tx = ix = vx;
|
||||
tx += 2.*ix + h*tx;
|
||||
tx += 2.*ix + h*tx;
|
||||
@ -173,7 +173,7 @@ static void rk4_update(Solid* obj, const double dt) {
|
||||
px += tx;
|
||||
vx += ax*h;
|
||||
|
||||
// Y component.
|
||||
/* Y component. */
|
||||
ty = iy = vy;
|
||||
ty += 2.*(iy + h/2.*ty);
|
||||
ty += 2.*(iy + h/2.*ty);
|
||||
@ -185,14 +185,14 @@ static void rk4_update(Solid* obj, const double dt) {
|
||||
}
|
||||
vect_cset(&obj->vel, vx, vy);
|
||||
} else {
|
||||
// Euler method -> p = v*t + 0.5*a*t^2 (no accel, so no error).
|
||||
/* Euler method -> p = v*t + 0.5*a*t^2 (no accel, so no error). */
|
||||
px += dt*vx;
|
||||
py += dt*vy;
|
||||
}
|
||||
vect_cset(&obj->pos, px, py);
|
||||
}
|
||||
|
||||
// Initialize a new solid.
|
||||
/* Initialize a new solid. */
|
||||
void solid_init(Solid* dest, const double mass, const double dir,
|
||||
const Vec2* pos, const Vec2* vel) {
|
||||
dest->mass = mass;
|
||||
@ -213,7 +213,7 @@ void solid_init(Solid* dest, const double mass, const double dir,
|
||||
dest->update = rk4_update;
|
||||
}
|
||||
|
||||
// Create a new solid.
|
||||
/* Create a new solid. */
|
||||
Solid* solid_create(const double mass, const double dir,
|
||||
const Vec2* pos, const Vec2* vel) {
|
||||
Solid* dyn = MALLOC_L(Solid);
|
||||
@ -222,7 +222,7 @@ Solid* solid_create(const double mass, const double dir,
|
||||
return dyn;
|
||||
}
|
||||
|
||||
// Free an existing solid.
|
||||
/* Free an existing solid. */
|
||||
void solid_free(Solid* src) {
|
||||
free(src);
|
||||
src = NULL;
|
||||
|
@ -14,19 +14,19 @@
|
||||
#define vect_odist(v) MOD((v)->x, (v)->y)
|
||||
|
||||
|
||||
// Base of 2D vectors.
|
||||
/* Base of 2D vectors. */
|
||||
typedef struct Vec2_ {
|
||||
double x, y; // Cartesian values.
|
||||
double mod, angle; // Polar values.
|
||||
double x, y; /* Cartesian values. */
|
||||
double mod, angle; /* Polar values. */
|
||||
} Vec2;
|
||||
|
||||
// Misc
|
||||
/* Misc */
|
||||
double angle_diff(const double ref, double a);
|
||||
void limit_speed(Vec2* vel, const double speed, const double dt);
|
||||
|
||||
// Vector manupulation.
|
||||
/* Vector manupulation. */
|
||||
void vect_cset(Vec2* v, const double x, const double y);
|
||||
// Doesn't set mod nor angle.
|
||||
/* 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);
|
||||
@ -34,14 +34,14 @@ void vectnull(Vec2* v);
|
||||
double vect_angle(const Vec2* ref, const Vec2* v);
|
||||
void vect_cadd(Vec2* v, const double x, const double y);
|
||||
|
||||
// Describe any solid in 2D space.
|
||||
/* Describe any solid in 2D space. */
|
||||
typedef struct Solid_ {
|
||||
double mass, dir, dir_vel; // Properties.
|
||||
Vec2 vel, pos, force; // Position/velocity vectors.
|
||||
void(*update)(struct Solid_*, const double); // Update method.
|
||||
double mass, dir, dir_vel; /* Properties. */
|
||||
Vec2 vel, pos, force; /* Position/velocity vectors. */
|
||||
void(*update)(struct Solid_*, const double); /* Update method. */
|
||||
} Solid;
|
||||
|
||||
// Solid manipulation.
|
||||
/* Solid manipulation. */
|
||||
void solid_init(Solid* dest, const double mass, const double dir,
|
||||
const Vec2* pos, const Vec2* vel);
|
||||
Solid* solid_create(const double mass, const double dir,
|
||||
|
438
src/pilot.c
438
src/pilot.c
File diff suppressed because it is too large
Load Diff
172
src/pilot.h
172
src/pilot.h
@ -9,139 +9,139 @@
|
||||
|
||||
#define PLAYER_ID 1
|
||||
|
||||
#define HYPERSPACE_ENGINE_DELAY 3000 // Warm up the engines.
|
||||
#define HYPERSPACE_FLY_DELAY 5000 // Time taken to hyperspace.
|
||||
#define HYPERSPACE_STARS_BLUR 2000 // Time stars blur.
|
||||
#define HYPERSPACE_STARS_LENGTH 1000 // Length the stars blur to at max.
|
||||
#define HYPERSPACE_FADEOUT 1000 // Time fadeout.
|
||||
#define HYPERSPACE_FUEL 100 // Amount of fuel taken.
|
||||
#define HYPERSPACE_ENGINE_DELAY 3000 /* Warm up the engines. */
|
||||
#define HYPERSPACE_FLY_DELAY 5000 /* Time taken to hyperspace. */
|
||||
#define HYPERSPACE_STARS_BLUR 2000 /* Time stars blur. */
|
||||
#define HYPERSPACE_STARS_LENGTH 1000 /* Length the stars blur to at max. */
|
||||
#define HYPERSPACE_FADEOUT 1000 /* Time fadeout. */
|
||||
#define HYPERSPACE_FUEL 100 /* Amount of fuel taken. */
|
||||
|
||||
// Aproximation for pilot size.
|
||||
/* Aproximation for pilot size. */
|
||||
#define PILOT_SIZE_APROX 0.8
|
||||
#define PILOT_DISABLED_ARMOUR 0.3 // Based on armour percentage.
|
||||
#define PILOT_DISABLED_ARMOUR 0.3 /* Based on armour percentage. */
|
||||
|
||||
// Hooks.
|
||||
#define PILOT_HOOK_NONE 0 // No hook.
|
||||
#define PILOT_HOOK_DEATH 1 // Pilot died.
|
||||
/* Hooks. */
|
||||
#define PILOT_HOOK_NONE 0 /* No hook. */
|
||||
#define PILOT_HOOK_DEATH 1 /* Pilot died. */
|
||||
|
||||
// Flags.
|
||||
/* Flags. */
|
||||
#define pilot_isFlag(p,f) (p->flags & (f))
|
||||
#define pilot_setFlag(p,f) (p->flags |= (f))
|
||||
#define pilot_rmFlag(p,f) (p->flags ^= (f))
|
||||
// Creation.
|
||||
#define PILOT_PLAYER (1<<0) // Pilot is a player.
|
||||
#define PILOT_HASTURRET (1<<20) // Pilot has turrets.
|
||||
#define PILOT_NO_OUTFITS (1<<21) // Do not create the pilot with outfits.
|
||||
#define PILOT_EMPTY (1<<22) // Do not add pilot to stack.
|
||||
// Dynamic.
|
||||
#define PILOT_HOSTILE (1<<1) // Pilot is hostile to the player.
|
||||
#define PILOT_COMBAT (1<<2) // Pilot is engaged in combat.
|
||||
#define PILOT_AFTERBURNER (1<<3) // Pilot has her afterburner activated.
|
||||
#define PILOT_HYP_PREP (1<<5) // Pilot is getting ready for hyperspace.
|
||||
#define PILOT_HYP_BEGIN (1<<6) // Pilot is starting engines.
|
||||
#define PILOT_HYPERSPACE (1<<7) // Pilot is in hyperspace.
|
||||
#define PILOT_BOARDED (1<<8) // Pilot has been boarded already!
|
||||
#define PILOT_DISABLED (1<<9) // Pilot is disabled.
|
||||
#define PILOT_DEAD (1<<10) // Pilot is on it's death bed.
|
||||
#define PILOT_EXPLODED (1<<11) // Pilot did final death explosion.
|
||||
#define PILOT_DELETE (1<<15) // Pilot will get delete asap.
|
||||
/* Creation. */
|
||||
#define PILOT_PLAYER (1<<0) /* Pilot is a player. */
|
||||
#define PILOT_HASTURRET (1<<20) /* Pilot has turrets. */
|
||||
#define PILOT_NO_OUTFITS (1<<21) /* Do not create the pilot with outfits. */
|
||||
#define PILOT_EMPTY (1<<22) /* Do not add pilot to stack. */
|
||||
/* Dynamic. */
|
||||
#define PILOT_HOSTILE (1<<1) /* Pilot is hostile to the player. */
|
||||
#define PILOT_COMBAT (1<<2) /* Pilot is engaged in combat. */
|
||||
#define PILOT_AFTERBURNER (1<<3) /* Pilot has her afterburner activated. */
|
||||
#define PILOT_HYP_PREP (1<<5) /* Pilot is getting ready for hyperspace. */
|
||||
#define PILOT_HYP_BEGIN (1<<6) /* Pilot is starting engines. */
|
||||
#define PILOT_HYPERSPACE (1<<7) /* Pilot is in hyperspace. */
|
||||
#define PILOT_BOARDED (1<<8) /* Pilot has been boarded already! */
|
||||
#define PILOT_DISABLED (1<<9) /* Pilot is disabled. */
|
||||
#define PILOT_DEAD (1<<10) /* Pilot is on it's death bed. */
|
||||
#define PILOT_EXPLODED (1<<11) /* Pilot did final death explosion. */
|
||||
#define PILOT_DELETE (1<<15) /* Pilot will get delete asap. */
|
||||
|
||||
// Just makes life simpler.
|
||||
/* Just makes life simpler. */
|
||||
#define pilot_isPlayer(p) ((p)->flags & PILOT_PLAYER)
|
||||
#define pilot_isDisabled(p) ((p)->flags & PILOT_DISABLED)
|
||||
|
||||
typedef struct PilotOutfit_ {
|
||||
Outfit* outfit; // Associated outfit.
|
||||
int quantity; // Number of outfits of this type that the pilot has.
|
||||
unsigned int timer; // Used to store last used weapon time.
|
||||
Outfit* outfit; /* Associated outfit. */
|
||||
int quantity; /* Number of outfits of this type that the pilot has. */
|
||||
unsigned int timer; /* Used to store last used weapon time. */
|
||||
} PilotOutfit;
|
||||
|
||||
// Pilot commodity.
|
||||
/* Pilot commodity. */
|
||||
typedef struct PilotCommodity_ {
|
||||
Commodity* commodity;
|
||||
int quantity;
|
||||
unsigned int id; // Special mission id for cargo.
|
||||
unsigned int id; /* Special mission id for cargo. */
|
||||
} PilotCommodity;
|
||||
|
||||
// Primary pilot structure.
|
||||
/* Primary pilot structure. */
|
||||
typedef struct Pilot_ {
|
||||
unsigned int id; // Pilots id.
|
||||
char* name; // Pilot's name (if unique).
|
||||
char* title; // Title - Usuall indicating special properties - TODO.
|
||||
unsigned int id; /* Pilots id. */
|
||||
char* name; /* Pilot's name (if unique). */
|
||||
char* title; /* Title - Usuall indicating special properties - TODO. */
|
||||
|
||||
int faction;
|
||||
|
||||
// Object characteristics.
|
||||
Ship* ship; // Pilots ship.
|
||||
Solid* solid; // Associated solid (physics).
|
||||
int tsx, tsy; // Current sprite, calculated on update.
|
||||
/* Object characteristics. */
|
||||
Ship* ship; /* Pilots ship. */
|
||||
Solid* solid; /* Associated solid (physics). */
|
||||
int tsx, tsy; /* Current sprite, calculated on update. */
|
||||
|
||||
double thrust, turn, speed;
|
||||
|
||||
// Current health.
|
||||
/* Current health. */
|
||||
double armour, shield, energy, fuel;
|
||||
double armour_max, shield_max, energy_max, fuel_max;
|
||||
double armour_regen, shield_regen, energy_regen;
|
||||
|
||||
void (*think)(struct Pilot_*); // AI thinking for the pilot.
|
||||
void (*update)(struct Pilot_*, const double); // Update the pilot.
|
||||
void (*render)(struct Pilot_*); // Rendering the pilot.
|
||||
void (*think)(struct Pilot_*); /* AI thinking for the pilot. */
|
||||
void (*update)(struct Pilot_*, const double); /* Update the pilot. */
|
||||
void (*render)(struct Pilot_*); /* Rendering the pilot. */
|
||||
|
||||
// Outfit management.
|
||||
/* Outfit management. */
|
||||
PilotOutfit* outfits;
|
||||
int noutfits;
|
||||
PilotOutfit* secondary; // Secondary weapon.
|
||||
PilotOutfit* ammo; // Secondary ammo (if needed).
|
||||
PilotOutfit* afterburner; // Ze afterburner.
|
||||
PilotOutfit* secondary; /* Secondary weapon. */
|
||||
PilotOutfit* ammo; /* Secondary ammo (if needed). */
|
||||
PilotOutfit* afterburner; /* Ze afterburner. */
|
||||
|
||||
// Cargo.
|
||||
int credits; // Moniez the pilot has.
|
||||
PilotCommodity* commodities; // Commodity and quantity.
|
||||
/* Cargo. */
|
||||
int credits; /* Moniez the pilot has. */
|
||||
PilotCommodity* commodities; /* Commodity and quantity. */
|
||||
int ncommodities;
|
||||
int cargo_free;
|
||||
|
||||
// Misc.
|
||||
uint32_t flags; // Used for AI etc.
|
||||
unsigned int ptimer; // Generic timer for internal pilot use.
|
||||
/* Misc. */
|
||||
uint32_t flags; /* Used for AI etc. */
|
||||
unsigned int ptimer; /* Generic timer for internal pilot use. */
|
||||
|
||||
// Hook attached to the pilot.
|
||||
/* Hook attached to the pilot. */
|
||||
int hook_type;
|
||||
int hook;
|
||||
|
||||
// AI.
|
||||
AI_Profile* ai; // Ai personality profile.
|
||||
unsigned int tcontrol; // Timer for control tick.
|
||||
unsigned int timer[MAX_AI_TIMERS]; // Timers for AI.
|
||||
Task* task; // Current action.
|
||||
/* AI. */
|
||||
AI_Profile* ai; /* Ai personality profile. */
|
||||
unsigned int tcontrol; /* Timer for control tick. */
|
||||
unsigned int timer[MAX_AI_TIMERS]; /* Timers for AI. */
|
||||
Task* task; /* Current action. */
|
||||
} Pilot;
|
||||
|
||||
// Fleets.
|
||||
/* Fleets. */
|
||||
typedef struct FleetPilot_ {
|
||||
Ship* ship; // Ship that the pilot is flying.
|
||||
char* name; // For special 'unique' names.
|
||||
int chance; // Chance of this pilot appearing in the fleet.
|
||||
Ship* ship; /* Ship that the pilot is flying. */
|
||||
char* name; /* For special 'unique' names. */
|
||||
int chance; /* Chance of this pilot appearing in the fleet. */
|
||||
} FleetPilot;
|
||||
|
||||
typedef struct Fleet_ {
|
||||
char* name; // Fleet name, used as an identifier.
|
||||
int faction; // Faction of the fleet.
|
||||
char* name; /* Fleet name, used as an identifier. */
|
||||
int faction; /* Faction of the fleet. */
|
||||
|
||||
AI_Profile* ai; // A useable profile.
|
||||
AI_Profile* ai; /* A useable profile. */
|
||||
|
||||
FleetPilot* pilots; // The pilots in the fleet.
|
||||
int npilots; // Total number of pilots.
|
||||
FleetPilot* pilots; /* The pilots in the fleet. */
|
||||
int npilots; /* Total number of pilots. */
|
||||
} Fleet;
|
||||
|
||||
// Grabing pilot crap.
|
||||
extern Pilot* player; // The player.
|
||||
/* Grabing pilot crap. */
|
||||
extern Pilot* player; /* The player. */
|
||||
Pilot* pilot_get(unsigned int id);
|
||||
unsigned int pilot_getNext(const unsigned int id);
|
||||
unsigned int pilot_getNearest(const Pilot* p);
|
||||
unsigned int pilot_getHostile(void); // Only for the player.
|
||||
unsigned int pilot_getHostile(void); /* Only for the player. */
|
||||
Fleet* fleet_get(const char* name);
|
||||
int pilot_getJumps(const Pilot* p);
|
||||
|
||||
// MISC.
|
||||
/* MISC. */
|
||||
void pilot_shoot(Pilot* p, const unsigned int target, const int secondary);
|
||||
void pilot_hit(Pilot* p, const Solid* w, const unsigned int shooter,
|
||||
const DamageType dtype, const double damage);
|
||||
@ -149,23 +149,23 @@ void pilot_setSecondary(Pilot* p, const char* secondary);
|
||||
void pilot_setAmmo(Pilot* p);
|
||||
void pilot_setAfterburner(Pilot* p);
|
||||
double pilot_face(Pilot* p, const float dir);
|
||||
// Outfits.
|
||||
int pilot_freeSpace(Pilot* p); // Pilot space.
|
||||
/* Outfits. */
|
||||
int pilot_freeSpace(Pilot* p); /* Pilot space. */
|
||||
int pilot_addOutfit(Pilot* pilot, Outfit* outfit, int quantity);
|
||||
int pilot_rmOutfit(Pilot* pilot, Outfit* outfit, int quantity);
|
||||
char* pilot_getOutfits(Pilot* pilot);
|
||||
void pilot_calcStats(Pilot* pilot);
|
||||
// Normal cargo.
|
||||
int pilot_cagoUsed(Pilot* pilot); // Get amount of cargo onboard.
|
||||
int pilot_cargoFree(Pilot* p); // Cargo space.
|
||||
/* Normal cargo. */
|
||||
int pilot_cagoUsed(Pilot* pilot); /* Get amount of cargo onboard. */
|
||||
int pilot_cargoFree(Pilot* p); /* Cargo space. */
|
||||
int pilot_addCargo(Pilot* pilot, Commodity* cargo, int quantity);
|
||||
int pilot_rmCargo(Pilot* pilot, Commodity* cargo, int quantity);
|
||||
// Mission cargo - Not to be confused with normal cargo.
|
||||
/* Mission cargo - Not to be confused with normal cargo. */
|
||||
unsigned int pilot_addMissionCargo(Pilot* pilot, Commodity* cargo, int quantity);
|
||||
int pilot_rmMissionCargo(Pilot* pilot, unsigned int cargo_id);
|
||||
|
||||
|
||||
// Creation.
|
||||
/* Creation. */
|
||||
void pilot_init(Pilot* dest, Ship* ship, char* name, int faction,
|
||||
AI_Profile* ai, const double dir, const Vec2* pos,
|
||||
const Vec2* vel, const int flags);
|
||||
@ -179,16 +179,16 @@ Pilot* pilot_createEmpty(Ship* ship, char* name,
|
||||
|
||||
Pilot* pilot_copy(Pilot* src);
|
||||
|
||||
// Init/Cleanup.
|
||||
/* Init/Cleanup. */
|
||||
void pilot_destroy(Pilot* p);
|
||||
void pilots_free(void);
|
||||
void pilots_clean(void);
|
||||
void pilots_cleanAll(void);
|
||||
void pilot_free(Pilot* p);
|
||||
int fleet_load(void); // TODO
|
||||
int fleet_load(void); /* TODO */
|
||||
void fleet_free(void);
|
||||
|
||||
// Update.
|
||||
/* Update. */
|
||||
void pilots_update(double dt);
|
||||
void pilots_render(void);
|
||||
|
||||
|
@ -11,7 +11,7 @@ static void pf_divFractal(double* map, const double x, const double y,
|
||||
double rw, const double rh, double c1,
|
||||
double c2, double c3, double c4, double rug);
|
||||
|
||||
// Acutally generate the fractal and loads it up in an opengl texture.
|
||||
/* Acutally generate the fractal and loads it up in an opengl texture. */
|
||||
glTexture* pf_genFractal(const int w, const int h, double rug) {
|
||||
int i;
|
||||
double* map;
|
||||
@ -25,7 +25,7 @@ glTexture* pf_genFractal(const int w, const int h, double rug) {
|
||||
sur = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, RGBMASK);
|
||||
pix = sur->pixels;
|
||||
|
||||
// Convert from mapping to actual colours.
|
||||
/* Convert from mapping to actual colours. */
|
||||
SDL_LockSurface(sur);
|
||||
for(i = 0; i < h*w; i++) {
|
||||
c = map[i];
|
||||
@ -41,7 +41,7 @@ glTexture* pf_genFractal(const int w, const int h, double rug) {
|
||||
}
|
||||
|
||||
static double* pf_genFractalMap(const int w, const int h, double rug) {
|
||||
double* map; // We'll use it to map out the fractal before saving.
|
||||
double* map; /* We'll use it to map out the fractal before saving. */
|
||||
double cx, cy;
|
||||
|
||||
map = malloc(w*h * sizeof(double));
|
||||
@ -50,11 +50,11 @@ static double* pf_genFractalMap(const int w, const int h, double rug) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Set up initial values.
|
||||
/* Set up initial values. */
|
||||
cx = (double)w/2;
|
||||
cy = (double)h/2;
|
||||
|
||||
// Start by doing the four squares.
|
||||
/* Start by doing the four squares. */
|
||||
pf_divFractal(map, 0, 0, cx, cy, w, h, 0., 0., 1., 0., rug);
|
||||
pf_divFractal(map, cx, 0, cx, cy, w, h, 0., 0., 0., 1., rug);
|
||||
pf_divFractal(map, cx, cy, cx, cy, w, h, 1., 0., 0., 0., rug);
|
||||
@ -68,35 +68,35 @@ static void pf_divFractal(double* map, const double x, const double y,
|
||||
const double rh, double c1, double c2, double c3,
|
||||
double c4, double rug) {
|
||||
|
||||
double nw, nh; // New dimensions.
|
||||
double m, e1, e2, e3, e4; // Middle and edges.
|
||||
double nw, nh; /* New dimensions. */
|
||||
double m, e1, e2, e3, e4; /* Middle and edges. */
|
||||
|
||||
// Still need to subdivide.
|
||||
/* Still need to subdivide. */
|
||||
if((w>1.) || (h>1.)) {
|
||||
// Calculate new dimensions.
|
||||
/* Calculate new dimensions. */
|
||||
nw = w/2.;
|
||||
nh = h/2.;
|
||||
|
||||
// Edges.
|
||||
/* Edges. */
|
||||
m = (c1 + c2 + c3 + c4)/4.;
|
||||
e1 = (c1 + c2)/2.;
|
||||
e2 = (c2 + c3)/2.;
|
||||
e3 = (c3 + c4)/2.;
|
||||
e4 = (c4 + c1)/2.;
|
||||
|
||||
// Now change the middle colour.
|
||||
//DEBUG("%f + %f", m, rug*(RNGF()-0.5) * ((nw+nh)/(rw+rh)*1000));
|
||||
/* Now change the middle colour. */
|
||||
/*DEBUG("%f + %f", m, rug*(RNGF()-0.5) * ((nw+nh)/(rw+rh)*1000)); */
|
||||
m += rug*(RNGF()-0.5)*((nw+nh)/(rw+rh)*3.);
|
||||
if(m < 0.) m = 0.;
|
||||
else if(m>1.) m = 1.;
|
||||
|
||||
// Recursivation.
|
||||
/* Recursivation. */
|
||||
pf_divFractal(map, x, y, nw, nh, rw, rh, c1, e1, m, e4, rug);
|
||||
pf_divFractal(map, x+nw, y, nw, nh, rw, rh, e1, c2, e2, m, rug);
|
||||
pf_divFractal(map, x+nw, y+nh, nw, nh, rw, rh, m, e2, c3, e3, rug);
|
||||
pf_divFractal(map, x, y+nh, nw, nh, rw, rh, e4, m, e3, c4, rug);
|
||||
} else
|
||||
// Actually write the pixel.
|
||||
/* Actually write the pixel. */
|
||||
map[(int)y*(int)rw + (int)x] = (c1 + c2 + c3 + c4)/4.;
|
||||
}
|
||||
|
||||
|
532
src/player.c
532
src/player.c
File diff suppressed because it is too large
Load Diff
46
src/player.h
46
src/player.h
@ -1,58 +1,58 @@
|
||||
#pragma once
|
||||
#include "pilot.h"
|
||||
|
||||
// Flag definitions.
|
||||
#define PLAYER_TURN_LEFT (1<<0) // Player is turning left.
|
||||
#define PLAYER_TURN_RIGHT (1<<1) // Player is turning right.
|
||||
#define PLAYER_REVERSE (1<<2) // Player is facint opposite vel.
|
||||
#define PLAYER_AFTERBURNER (1<<3) // Player is burning it up.
|
||||
#define PLAYER_DESTROYED (1<<9) // Player goes BOOM!
|
||||
#define PLAYER_FACE (1<<10) // Player is facing target.
|
||||
#define PLAYER_PRIMARY (1<<11) // Player is shooting primary weapon.
|
||||
#define PLAYER_SECONDARY (1<<12) // Player is shooting secondary weapon.
|
||||
#define PLAYER_LANDACK (1<<13) // Player has permission to land.
|
||||
#define PLAYER_CREATING (1<<14) // Player is being created.
|
||||
/* Flag definitions. */
|
||||
#define PLAYER_TURN_LEFT (1<<0) /* Player is turning left. */
|
||||
#define PLAYER_TURN_RIGHT (1<<1) /* Player is turning right. */
|
||||
#define PLAYER_REVERSE (1<<2) /* Player is facint opposite vel. */
|
||||
#define PLAYER_AFTERBURNER (1<<3) /* Player is burning it up. */
|
||||
#define PLAYER_DESTROYED (1<<9) /* Player goes BOOM! */
|
||||
#define PLAYER_FACE (1<<10) /* Player is facing target. */
|
||||
#define PLAYER_PRIMARY (1<<11) /* Player is shooting primary weapon. */
|
||||
#define PLAYER_SECONDARY (1<<12) /* Player is shooting secondary weapon. */
|
||||
#define PLAYER_LANDACK (1<<13) /* Player has permission to land. */
|
||||
#define PLAYER_CREATING (1<<14) /* Player is being created. */
|
||||
|
||||
// Flag functions.
|
||||
/* Flag functions. */
|
||||
#define player_isFlag(f) (player_flags & f)
|
||||
#define player_setFlag(f) if(!player_isFlag(f)) (player_flags |= f)
|
||||
#define player_rmFlag(f) if(player_isFlag(f)) (player_flags ^= f)
|
||||
|
||||
// The player.
|
||||
/* The player. */
|
||||
extern Pilot* pilot;
|
||||
extern char* player_name;
|
||||
extern unsigned int player_flags;
|
||||
extern int combat_crating;
|
||||
|
||||
// Enums.
|
||||
/* Enums. */
|
||||
|
||||
// For render functions.
|
||||
/* For render functions. */
|
||||
typedef enum RadarShape_ { RADAR_RECT, RADAR_CIRCLE } RadarShape;
|
||||
|
||||
// Creation/Cleanup.
|
||||
/* Creation/Cleanup. */
|
||||
void player_new(void);
|
||||
void player_newShip(Ship* ship, double px, double py,
|
||||
double vx, double vy, double dir);
|
||||
void player_cleanup(void);
|
||||
int gui_load(const char* name);
|
||||
|
||||
// Render.
|
||||
/* Render. */
|
||||
int gui_init(void);
|
||||
void gui_free(void);
|
||||
void player_render(void);
|
||||
void player_renderBG(void); // Render BG layer.
|
||||
void player_renderBG(void); /* Render BG layer. */
|
||||
|
||||
// Misc.
|
||||
/* Misc. */
|
||||
void player_message(const char* fmt, ...);
|
||||
void player_clear(void);
|
||||
void player_warp(const double x, const double y);
|
||||
const char* player_rating(void);
|
||||
// Cargo.
|
||||
/* Cargo. */
|
||||
int player_outfitOwned(const char* outfitname);
|
||||
int player_cargoOwned(const char* commodityname);
|
||||
void player_rmMissionCargo(unsigned int cargo_id);
|
||||
|
||||
// Pilot ships.
|
||||
/* Pilot ships. */
|
||||
char** player_ships(int* nships);
|
||||
int player_nships(void);
|
||||
Pilot* player_getShip(char* shipname);
|
||||
@ -60,11 +60,11 @@ char* player_getLoc(char* shipname);
|
||||
void player_setLoc(char* shipname, char* loc);
|
||||
void player_swapShip(char* shipname);
|
||||
|
||||
// Player missions.
|
||||
/* Player missions. */
|
||||
void player_missionFinished(int id);
|
||||
int player_missionAlreadyDone(int id);
|
||||
|
||||
// Keybind actions.
|
||||
/* Keybind actions. */
|
||||
void player_setRadarRel(int mod);
|
||||
void player_secondaryNext(void);
|
||||
void player_targetPlanet(void);
|
||||
|
28
src/rng.c
28
src/rng.c
@ -11,13 +11,13 @@
|
||||
#include "rng.h"
|
||||
#include "log.h"
|
||||
|
||||
// Mersenne twister state.
|
||||
/* Mersenne twister state. */
|
||||
static uint32_t MT[624];
|
||||
static uint32_t mt_y;
|
||||
static int mt_pos = 0; // Current number.
|
||||
static int mt_pos = 0; /* Current number. */
|
||||
|
||||
static uint32_t rng_timeEntropy(void);
|
||||
// Mersenne twister.
|
||||
/* Mersenne twister. */
|
||||
static void mt_initArray(uint32_t seed);
|
||||
static void mt_genArray(void);
|
||||
static uint32_t mt_getInt(void);
|
||||
@ -26,10 +26,10 @@ void rng_init(void) {
|
||||
uint32_t i;
|
||||
int need_init;
|
||||
|
||||
need_init = 1; // Initialize by default.
|
||||
need_init = 1; /* Initialize by default. */
|
||||
#ifdef LINUX
|
||||
int fd;
|
||||
fd = open("/dev/urandom", O_RDONLY); // /dev/urandom is better then time seed.
|
||||
fd = open("/dev/urandom", O_RDONLY); /* /dev/urandom is better then time seed. */
|
||||
if(fd != -1) {
|
||||
i = sizeof(uint32_t)*624;
|
||||
if(read(fd, &MT, i) == (ssize_t)i)
|
||||
@ -45,11 +45,11 @@ void rng_init(void) {
|
||||
if(need_init)
|
||||
mt_initArray(i);
|
||||
for(i = 0; i < 10; i++)
|
||||
// Generate numbers to get away from poor initial values.
|
||||
/* Generate numbers to get away from poor initial values. */
|
||||
mt_genArray();
|
||||
}
|
||||
|
||||
// Use the time as source of entropy.
|
||||
/* Use the time as source of entropy. */
|
||||
static uint32_t rng_timeEntropy(void) {
|
||||
int i;
|
||||
|
||||
@ -65,7 +65,7 @@ static uint32_t rng_timeEntropy(void) {
|
||||
return i;
|
||||
}
|
||||
|
||||
// Generates the initial mersenne twister based on seed.
|
||||
/* Generates the initial mersenne twister based on seed. */
|
||||
static void mt_initArray(uint32_t seed) {
|
||||
int i;
|
||||
MT[0] = seed;
|
||||
@ -74,22 +74,22 @@ static void mt_initArray(uint32_t seed) {
|
||||
mt_pos = 0;
|
||||
}
|
||||
|
||||
// Generate an array of numbers.
|
||||
/* Generate an array of numbers. */
|
||||
static void mt_genArray(void) {
|
||||
int i;
|
||||
for(i = 0; i < 624; i++) {
|
||||
mt_y = (MT[i] & 0x80000000) + ((MT[i] % 624) & 0x7FFFFFFF);
|
||||
if(mt_y % 2)
|
||||
// Odd.
|
||||
/* Odd. */
|
||||
MT[i] = (MT[(i+397) % 624] ^ (mt_y >> 1)) ^ 2567483615;
|
||||
else
|
||||
// Even.
|
||||
/* Even. */
|
||||
MT[i] = MT[(i+397) % 624] ^ (mt_y >> 1);
|
||||
}
|
||||
mt_pos = 0;
|
||||
}
|
||||
|
||||
// Get the next int.
|
||||
/* Get the next int. */
|
||||
static uint32_t mt_getInt(void) {
|
||||
if(mt_pos >= 624) mt_genArray();
|
||||
|
||||
@ -102,12 +102,12 @@ static uint32_t mt_getInt(void) {
|
||||
return mt_y;
|
||||
}
|
||||
|
||||
// Return a random int.
|
||||
/* Return a random int. */
|
||||
unsigned int randint(void) {
|
||||
return mt_getInt();
|
||||
}
|
||||
|
||||
// Return a random double.
|
||||
/* Return a random double. */
|
||||
static double m_div = (double)(0xFFFFFFFF) + 1.;
|
||||
double randfp(void) {
|
||||
double m = (double)mt_getInt();
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#define RNG(L,H) ((int)L + (int)((double)(H-L+1) * randfp())) // L <= RNG <= H
|
||||
#define RNG(L,H) ((int)L + (int)((double)(H-L+1) * randfp())) /* L <= RNG <= H */
|
||||
#define RNGF() (randfp())
|
||||
|
||||
void rng_init(void);
|
||||
|
50
src/save.c
50
src/save.c
@ -1,5 +1,5 @@
|
||||
#ifdef _POSIX_SOURCE
|
||||
#include <unistd.h> // Unlink.
|
||||
#include <unistd.h> /* Unlink. */
|
||||
#endif
|
||||
|
||||
#include "lephisto.h"
|
||||
@ -17,28 +17,28 @@
|
||||
#define BUTTON_WIDTH 50
|
||||
#define BUTTON_HEIGHT 30
|
||||
|
||||
// Externs.
|
||||
extern int player_save(xmlTextWriterPtr writer); // A lot of stuff.
|
||||
/* Externs. */
|
||||
extern int player_save(xmlTextWriterPtr writer); /* A lot of stuff. */
|
||||
extern int player_load(xmlNodePtr parent);
|
||||
extern int missions_saveActive(xmlTextWriterPtr writer); // Active missions.
|
||||
extern int missions_saveActive(xmlTextWriterPtr writer); /* Active missions. */
|
||||
extern int missions_loadActive(xmlNodePtr parent);
|
||||
extern int var_save(xmlTextWriterPtr writer); // misn var.
|
||||
extern int var_save(xmlTextWriterPtr writer); /* misn var. */
|
||||
extern int var_load(xmlNodePtr parent);
|
||||
extern int pfaction_save(xmlTextWriterPtr writer); // Faction data.
|
||||
extern int pfaction_save(xmlTextWriterPtr writer); /* Faction data. */
|
||||
extern int pfaction_load(xmlNodePtr parent);
|
||||
extern int hook_save(xmlTextWriterPtr writer); // Hooks.
|
||||
extern int hook_save(xmlTextWriterPtr writer); /* Hooks. */
|
||||
extern int hook_load(xmlNodePtr parent);
|
||||
extern void menu_main_close(void);
|
||||
// Static.
|
||||
/* Static. */
|
||||
static int save_data(xmlTextWriterPtr writer);
|
||||
static void load_menu_close(char* str);
|
||||
static void load_menu_load(char* str);
|
||||
static void load_menu_delete(char* str);
|
||||
static int load_game(char* file);
|
||||
|
||||
// Save all the game data.
|
||||
/* Save all the game data. */
|
||||
static int save_data(xmlTextWriterPtr writer) {
|
||||
// The data itself.
|
||||
/* The data itself. */
|
||||
if(player_save(writer) < 0) return -1;
|
||||
if(missions_saveActive(writer) < 0) return -1;
|
||||
if(var_save(writer) < 0) return -1;
|
||||
@ -47,7 +47,7 @@ static int save_data(xmlTextWriterPtr writer) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Save the current game.
|
||||
/* Save the current game. */
|
||||
int save_all(void) {
|
||||
char file[PATH_MAX];
|
||||
xmlDocPtr doc;
|
||||
@ -62,11 +62,11 @@ int save_all(void) {
|
||||
xmlw_start(writer);
|
||||
xmlw_startElem(writer, "lephisto_save");
|
||||
|
||||
// Save the version or something..
|
||||
/* Save the version or something.. */
|
||||
xmlw_startElem(writer, "version");
|
||||
xmlw_elem(writer, "lephisto", "%d.%d.%d", VMAJOR, VMINOR, VREV);
|
||||
xmlw_elem(writer, "data", dataname);
|
||||
xmlw_endElem(writer); // Version.
|
||||
xmlw_endElem(writer); /* Version. */
|
||||
|
||||
if(save_data(writer) < 0) {
|
||||
ERR("Trying to save game data");
|
||||
@ -75,7 +75,7 @@ int save_all(void) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
xmlw_endElem(writer); // lephisto_save.
|
||||
xmlw_endElem(writer); /* lephisto_save. */
|
||||
xmlw_done(writer);
|
||||
|
||||
if(lfile_dirMakeExist("saves") < 0) {
|
||||
@ -93,32 +93,32 @@ int save_all(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Open the load game menu.
|
||||
/* Open the load game menu. */
|
||||
void load_game_menu(void) {
|
||||
unsigned int wid;
|
||||
char** files;
|
||||
int lfiles, i, len;
|
||||
|
||||
// Window.
|
||||
/* Window. */
|
||||
wid = window_create("Load Game", -1, -1, LOAD_WIDTH, LOAD_HEIGHT);
|
||||
|
||||
// Load the saves.
|
||||
/* Load the saves. */
|
||||
files = lfile_readDir(&lfiles, "saves");
|
||||
for(i = 0; i < lfiles; i++) {
|
||||
len = strlen(files[i]);
|
||||
|
||||
// No save extension.
|
||||
/* No save extension. */
|
||||
if((len < 6) || strcmp(&files[i][len-3], ".ls")) {
|
||||
free(files[i]);
|
||||
memmove(&files[i], &files[i+1], sizeof(char*) * (lfiles-i-1));
|
||||
lfiles--;
|
||||
i--;
|
||||
}
|
||||
else // Remove the extension.
|
||||
else /* Remove the extension. */
|
||||
files[i][len-3] = '\0';
|
||||
}
|
||||
|
||||
// Again.. What if there is no files?
|
||||
/* Again.. What if there is no files? */
|
||||
if(files == NULL) {
|
||||
files = malloc(sizeof(char*));
|
||||
files[0] = strdup("None");
|
||||
@ -129,7 +129,7 @@ void load_game_menu(void) {
|
||||
LOAD_WIDTH-BUTTON_WIDTH-50, LOAD_HEIGHT-90,
|
||||
"lstSaves", files, lfiles, 0, NULL);
|
||||
|
||||
// Buttons.
|
||||
/* Buttons. */
|
||||
window_addButton(wid, -20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnBack", "Back", load_menu_close);
|
||||
|
||||
@ -139,7 +139,7 @@ void load_game_menu(void) {
|
||||
window_addButton(wid, -20, 20+2*(10+BUTTON_HEIGHT), BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnDelete", "Del", load_menu_delete);
|
||||
|
||||
// Default action.
|
||||
/* Default action. */
|
||||
window_setFptr(wid, load_menu_load);
|
||||
}
|
||||
|
||||
@ -185,18 +185,18 @@ static void load_menu_delete(char* str) {
|
||||
snprintf(path, PATH_MAX, "%ssaves/%s.ls", lfile_basePath(), save);
|
||||
unlink(path);
|
||||
|
||||
// Need to reload the menu.
|
||||
/* Need to reload the menu. */
|
||||
load_menu_close(NULL);
|
||||
load_game_menu();
|
||||
}
|
||||
|
||||
// Load a new game.
|
||||
/* Load a new game. */
|
||||
static int load_game(char* file) {
|
||||
xmlNodePtr node;
|
||||
xmlDocPtr doc;
|
||||
|
||||
doc = xmlParseFile(file);
|
||||
node = doc->xmlChildrenNode; // Base node.
|
||||
node = doc->xmlChildrenNode; /* Base node. */
|
||||
if(node == NULL) {
|
||||
WARN("Savegame '%s' invalid!", file);
|
||||
return -1;
|
||||
|
30
src/ship.c
30
src/ship.c
@ -7,7 +7,7 @@
|
||||
#include "toolkit.h"
|
||||
#include "ship.h"
|
||||
|
||||
#define XML_ID "Ships" // XML section identifier.
|
||||
#define XML_ID "Ships" /* XML section identifier. */
|
||||
#define XML_SHIP "ship"
|
||||
|
||||
#define SHIP_DATA "../dat/ship.xml"
|
||||
@ -27,20 +27,20 @@ static int ships = 0;
|
||||
static Ship* ship_parse(xmlNodePtr parent);
|
||||
static void ship_view_close(char* btn);
|
||||
|
||||
// Get a ship based on it's name.
|
||||
/* Get a ship based on it's name. */
|
||||
Ship* ship_get(const char* name) {
|
||||
Ship* tmp = ship_stack;
|
||||
int i;
|
||||
for(i = 0; i < ships; i++)
|
||||
if(strcmp((tmp+i)->name, name)==0) break;
|
||||
|
||||
if(i == ships) // Ship doesn't exist, game will probably crash now.
|
||||
if(i == ships) /* Ship doesn't exist, game will probably crash now. */
|
||||
WARN("Ship %s does not exist", name);
|
||||
|
||||
return tmp+i;
|
||||
}
|
||||
|
||||
// Get the ship's classname.
|
||||
/* Get the ship's classname. */
|
||||
static char* ship_classes[] = {
|
||||
"NULL",
|
||||
"Civialian Light", "Civilian Medium", "Civilian Heavy"
|
||||
@ -50,7 +50,7 @@ static char* ship_classes[] = {
|
||||
|
||||
};
|
||||
|
||||
// Return all the ships in text form.
|
||||
/* Return all the ships in text form. */
|
||||
char** ship_getTech(int* n, const int* tech, const int techmax) {
|
||||
int i, j;
|
||||
char** shipnames;
|
||||
@ -91,13 +91,13 @@ static Ship* ship_parse(xmlNodePtr parent) {
|
||||
node = parent->xmlChildrenNode;
|
||||
|
||||
do {
|
||||
// Load all the data.
|
||||
/* Load all the data. */
|
||||
if(xml_isNode(node,"GFX")) {
|
||||
snprintf(str, strlen(xml_get(node)) +
|
||||
sizeof(SHIP_GFX) + sizeof(SHIP_EXT),
|
||||
SHIP_GFX"%s"SHIP_EXT, xml_get(node));
|
||||
tmp->gfx_space = gl_newSprite(str, 6, 6);
|
||||
// Target.
|
||||
/* Target. */
|
||||
snprintf(str, strlen(xml_get(node)) +
|
||||
sizeof(SHIP_GFX)+sizeof(SHIP_TARGET)+sizeof(SHIP_EXT),
|
||||
SHIP_GFX"%s"SHIP_TARGET SHIP_EXT, xml_get(node));
|
||||
@ -168,7 +168,7 @@ static Ship* ship_parse(xmlNodePtr parent) {
|
||||
}
|
||||
} while(xml_nextNode(node));
|
||||
|
||||
tmp->thrust *= tmp->mass; // Helps keep number sane.
|
||||
tmp->thrust *= tmp->mass; /* Helps keep number sane. */
|
||||
|
||||
#define MELEMENT(o,s) if(o) WARN("Ship '%s' missing '"s"' element", tmp->name)
|
||||
MELEMENT(tmp->name == NULL, "name");
|
||||
@ -207,13 +207,13 @@ int ships_load(void) {
|
||||
|
||||
Ship* tmp = NULL;
|
||||
|
||||
node = doc->xmlChildrenNode; // Ships node.
|
||||
node = doc->xmlChildrenNode; /* Ships node. */
|
||||
if(strcmp((char*)node->name, XML_ID)) {
|
||||
ERR("Malformed "SHIP_DATA" file: missing root element '"XML_ID"'");
|
||||
return -1;
|
||||
}
|
||||
|
||||
node = node->xmlChildrenNode; // First ship node.
|
||||
node = node->xmlChildrenNode; /* First ship node. */
|
||||
if(node == NULL) {
|
||||
ERR("Malformed "SHIP_DATA" file: Does not contain elements");
|
||||
return -1;
|
||||
@ -241,14 +241,14 @@ void ships_free(void) {
|
||||
ShipOutfit* so, *sot;
|
||||
int i;
|
||||
for(i = 0; i < ships; i++) {
|
||||
// Free stored strings.
|
||||
/* Free stored strings. */
|
||||
if((ship_stack+i)->name) free(ship_stack[i].name);
|
||||
if((ship_stack+i)->description) free(ship_stack[i].description);
|
||||
if((ship_stack+i)->gui) free(ship_stack[i].gui);
|
||||
if((ship_stack+i)->fabricator) free(ship_stack[i].fabricator);
|
||||
|
||||
so = (ship_stack+i)->outfit;
|
||||
while(so) { // free the ship outfit.
|
||||
while(so) { /* free the ship outfit. */
|
||||
sot = so;
|
||||
so = so->next;
|
||||
free(sot);
|
||||
@ -260,7 +260,7 @@ void ships_free(void) {
|
||||
ship_stack = NULL;
|
||||
}
|
||||
|
||||
// Used to visualize the ships status.
|
||||
/* Used to visualize the ships status. */
|
||||
void ship_view(char* shipname) {
|
||||
Ship* s;
|
||||
char buf[1024];
|
||||
@ -317,7 +317,7 @@ void ship_view(char* shipname) {
|
||||
window_addText(wid, 120, -40, VIEW_WIDTH-140, h,
|
||||
0, "txtProperties", &gl_smallFont, &cBlack, buf);
|
||||
|
||||
// Close the button.
|
||||
/* Close the button. */
|
||||
snprintf(buf, 37, "close%s", shipname);
|
||||
window_addButton(wid, -20, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
@ -325,6 +325,6 @@ void ship_view(char* shipname) {
|
||||
}
|
||||
|
||||
static void ship_view_close(char* btn) {
|
||||
window_destroy(window_get(btn+5)); // "closefoo -> Foo"
|
||||
window_destroy(window_get(btn+5)); /* "closefoo -> Foo" */
|
||||
}
|
||||
|
||||
|
46
src/ship.h
46
src/ship.h
@ -3,7 +3,7 @@
|
||||
#include "outfit.h"
|
||||
#include "sound.h"
|
||||
|
||||
// Target gfx dimensions.
|
||||
/* Target gfx dimensions. */
|
||||
#define SHIP_TARGET_W 128
|
||||
#define SHIP_TARGET_H 96
|
||||
|
||||
@ -23,63 +23,63 @@ typedef enum ShipClass_ {
|
||||
SHIP_CLASS_HYB_HEAVY = 12
|
||||
} ShipClass;
|
||||
|
||||
// Small wrapper for the outfits.
|
||||
/* Small wrapper for the outfits. */
|
||||
typedef struct ShipOutfit_ {
|
||||
struct ShipOutfit_* next; // Linked list.
|
||||
Outfit* data; // Data itself.
|
||||
struct ShipOutfit_* next; /* Linked list. */
|
||||
Outfit* data; /* Data itself. */
|
||||
int quantity;
|
||||
} ShipOutfit;
|
||||
|
||||
|
||||
// Ship structure.
|
||||
/* Ship structure. */
|
||||
typedef struct Ship_ {
|
||||
char* name; // Ship name.
|
||||
ShipClass class; // Ship class.
|
||||
char* name; /* Ship name. */
|
||||
ShipClass class; /* Ship class. */
|
||||
|
||||
// Store stuff.
|
||||
int price; // Price!
|
||||
/* Store stuff. */
|
||||
int price; /* Price! */
|
||||
int tech;
|
||||
char* fabricator; // Manufacturer.
|
||||
char* description; // Sales pitch.
|
||||
char* fabricator; /* Manufacturer. */
|
||||
char* description; /* Sales pitch. */
|
||||
|
||||
// Movement.
|
||||
/* Movement. */
|
||||
double thrust, turn, speed;
|
||||
|
||||
// Graphics.
|
||||
/* Graphics. */
|
||||
glTexture* gfx_space, *gfx_target;
|
||||
|
||||
// GUI interface.
|
||||
/* GUI interface. */
|
||||
char* gui;
|
||||
|
||||
// Sound.
|
||||
/* Sound. */
|
||||
ALuint sound;
|
||||
|
||||
// Characteristics.
|
||||
/* Characteristics. */
|
||||
int crew;
|
||||
int mass;
|
||||
int fuel; // How many jumps by default.
|
||||
int fuel; /* How many jumps by default. */
|
||||
|
||||
// Health.
|
||||
/* Health. */
|
||||
double armour, armour_regen;
|
||||
double shield, shield_regen;
|
||||
double energy, energy_regen;
|
||||
|
||||
// Capacity.
|
||||
/* Capacity. */
|
||||
int cap_cargo, cap_weapon;
|
||||
|
||||
// Outfits
|
||||
/* Outfits */
|
||||
ShipOutfit* outfit;
|
||||
} Ship;
|
||||
|
||||
// Get.
|
||||
/* Get. */
|
||||
Ship* ship_get(const char* name);
|
||||
char** ship_getTech(int* n, const int* tech, const int techmax);
|
||||
char* ship_class(Ship* p);
|
||||
|
||||
// Load/quit.
|
||||
/* Load/quit. */
|
||||
int ships_load(void);
|
||||
void ships_free(void);
|
||||
|
||||
// Toolkit.
|
||||
/* Toolkit. */
|
||||
void ship_view(char* shipname);
|
||||
|
||||
|
308
src/sound.c
308
src/sound.c
@ -10,41 +10,41 @@
|
||||
#include "music.h"
|
||||
#include "sound.h"
|
||||
|
||||
// ==============================================
|
||||
// sound.c controls the routines for using a
|
||||
// virtual voice wrapper system around the openal
|
||||
// library to get 3D sound.
|
||||
//
|
||||
// We only use position sound and no doppler effect
|
||||
// right now.
|
||||
// ==============================================
|
||||
/* ============================================== */
|
||||
/* sound.c controls the routines for using a */
|
||||
/* virtual voice wrapper system around the openal */
|
||||
/* library to get 3D sound. */
|
||||
/* */
|
||||
/* We only use position sound and no doppler effect */
|
||||
/* right now. */
|
||||
/* ============================================== */
|
||||
|
||||
// ==============================================
|
||||
// Sound Overview:
|
||||
// ---------------
|
||||
//
|
||||
// We use a priority virtual voice system with
|
||||
// pre-allocated buffers.
|
||||
//
|
||||
// Nameing:
|
||||
// -- buffer - Sound sample.
|
||||
// -- source - openal object that plays sound.
|
||||
// -- voice - Virtual object that wants to play sound.
|
||||
//
|
||||
// First we allocate all the buffers based on what
|
||||
// we find inside the datafile.
|
||||
// Then we allocate all the possible sources (giving
|
||||
// the music system what it needs).
|
||||
// Now we allow the user to dynamically create
|
||||
// voices, these voices will always try to grab
|
||||
// a source from the source pool. If they can't,
|
||||
// they will pretend to play the buffer.
|
||||
// Every so often we'll check to see if the important
|
||||
// voices are being played and take away the sources
|
||||
// from the lesser ones.
|
||||
// ==============================================
|
||||
/* ============================================== */
|
||||
/* Sound Overview: */
|
||||
/* --------------- */
|
||||
/* */
|
||||
/* We use a priority virtual voice system with */
|
||||
/* pre-allocated buffers. */
|
||||
/* */
|
||||
/* Nameing: */
|
||||
/* -- buffer - Sound sample. */
|
||||
/* -- source - openal object that plays sound. */
|
||||
/* -- voice - Virtual object that wants to play sound. */
|
||||
/* */
|
||||
/* First we allocate all the buffers based on what */
|
||||
/* we find inside the datafile. */
|
||||
/* Then we allocate all the possible sources (giving */
|
||||
/* the music system what it needs). */
|
||||
/* Now we allow the user to dynamically create */
|
||||
/* voices, these voices will always try to grab */
|
||||
/* a source from the source pool. If they can't, */
|
||||
/* they will pretend to play the buffer. */
|
||||
/* Every so often we'll check to see if the important */
|
||||
/* voices are being played and take away the sources */
|
||||
/* from the lesser ones. */
|
||||
/* ============================================== */
|
||||
|
||||
// Sound parameters - TODO: make it variable per source.
|
||||
/* Sound parameters - TODO: make it variable per source. */
|
||||
#define SOUND_ROLLOFF_FACTOR 1.
|
||||
#define SOUND_REFERENCE_DIST 500.
|
||||
#define SOUND_MAX_DIST 1000.
|
||||
@ -56,57 +56,57 @@
|
||||
#define soundLock() SDL_mutexP(sound_lock)
|
||||
#define soundUnlock() SDL_mutexV(sound_lock)
|
||||
|
||||
// Give the buffers a name.
|
||||
/* Give the buffers a name. */
|
||||
typedef struct alSound_ {
|
||||
char* name; // Buffers name.
|
||||
ALuint buffer; // Associated OpenAL buffer.
|
||||
char* name; /* Buffers name. */
|
||||
ALuint buffer; /* Associated OpenAL buffer. */
|
||||
} alSound;
|
||||
|
||||
// Voice private flags (public in sound.h).
|
||||
#define VOICE_PLAYING (1<<0) // Voice is playing.
|
||||
#define VOICE_DONE (1<<1) // Voice is done - must remove.
|
||||
/* Voice private flags (public in sound.h). */
|
||||
#define VOICE_PLAYING (1<<0) /* Voice is playing. */
|
||||
#define VOICE_DONE (1<<1) /* Voice is done - must remove. */
|
||||
#define voice_set(v,f) ((v)->flags |= f)
|
||||
#define voice_is(v,f) ((v)->flags & f)
|
||||
|
||||
// Global sound lock.
|
||||
/* Global sound lock. */
|
||||
SDL_mutex* sound_lock = NULL;
|
||||
|
||||
// Gobal device and context.
|
||||
/* Gobal device and context. */
|
||||
static ALCcontext* al_context = NULL;
|
||||
static ALCdevice* al_device = NULL;
|
||||
|
||||
// Threads.
|
||||
/* Threads. */
|
||||
static SDL_Thread* music_player = NULL;
|
||||
|
||||
// List of sounds available (All preloaded into a buffer).
|
||||
/* List of sounds available (All preloaded into a buffer). */
|
||||
static alSound* sound_list = NULL;
|
||||
static int nsound_list = 0;
|
||||
|
||||
// Struct to hold all the sources and currently attached voice.
|
||||
static ALuint* source_stack = NULL; // And it's stack.
|
||||
/* Struct to hold all the sources and currently attached voice. */
|
||||
static ALuint* source_stack = NULL; /* And it's stack. */
|
||||
static int source_nstack = 0;
|
||||
|
||||
// Virtual voice.
|
||||
/* Virtual voice. */
|
||||
struct alVoice {
|
||||
alVoice* next; // Yes it's a linked list.
|
||||
alVoice* next; /* Yes it's a linked list. */
|
||||
|
||||
//ALuint id; // Unique id for the voice.
|
||||
/*ALuint id; // Unique id for the voice. */
|
||||
|
||||
ALuint source; // Source itself, 0 if not set.
|
||||
ALuint buffer; // Buffer.
|
||||
ALuint source; /* Source itself, 0 if not set. */
|
||||
ALuint buffer; /* Buffer. */
|
||||
|
||||
int priority; // Base priority.
|
||||
int priority; /* Base priority. */
|
||||
|
||||
double px, py; // Position.
|
||||
//double vx, vy; // Velocity.
|
||||
double px, py; /* Position. */
|
||||
/*double vx, vy; // Velocity. */
|
||||
|
||||
unsigned int start; // time started in ms.
|
||||
unsigned int flags; // Flags to set properties.
|
||||
unsigned int start; /* time started in ms. */
|
||||
unsigned int flags; /* Flags to set properties. */
|
||||
};
|
||||
static alVoice* voice_start = NULL;
|
||||
static alVoice* voice_end = NULL;
|
||||
|
||||
// Volume.
|
||||
/* Volume. */
|
||||
static ALfloat svolume = 0.3;
|
||||
|
||||
static int sound_makeList(void);
|
||||
@ -124,15 +124,15 @@ int sound_init(void) {
|
||||
|
||||
ret = 0;
|
||||
|
||||
// We'll need a mutex.
|
||||
/* We'll need a mutex. */
|
||||
sound_lock = SDL_CreateMutex();
|
||||
soundLock();
|
||||
|
||||
// Initialize alut - I think it's worth it.
|
||||
/* Initialize alut - I think it's worth it. */
|
||||
alutInitWithoutContext(NULL, NULL);
|
||||
|
||||
const ALchar* device = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
|
||||
// Open the default device.
|
||||
/* Open the default device. */
|
||||
al_device = alcOpenDevice(NULL);
|
||||
if(al_device == NULL) {
|
||||
WARN("Unable to open default sound device");
|
||||
@ -140,7 +140,7 @@ int sound_init(void) {
|
||||
goto snderr_dev;
|
||||
}
|
||||
|
||||
// Create the OpenAL context.
|
||||
/* Create the OpenAL context. */
|
||||
al_context = alcCreateContext(al_device, NULL);
|
||||
if(sound_lock == NULL) {
|
||||
WARN("Unable to create OpenAL context");
|
||||
@ -148,34 +148,34 @@ int sound_init(void) {
|
||||
goto snderr_ctx;
|
||||
}
|
||||
|
||||
// Clear the errors.
|
||||
/* Clear the errors. */
|
||||
alGetError();
|
||||
|
||||
// Set active context.
|
||||
/* Set active context. */
|
||||
if(alcMakeContextCurrent(al_context)==AL_FALSE) {
|
||||
WARN("Failure to set default context");
|
||||
ret = -4;
|
||||
goto snderr_act;
|
||||
}
|
||||
|
||||
// Set the master gain.
|
||||
/* Set the master gain. */
|
||||
alListenerf(AL_GAIN, .1);
|
||||
|
||||
// Set the distance model.
|
||||
/* Set the distance model. */
|
||||
alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
|
||||
|
||||
// We can unlock now.
|
||||
/* We can unlock now. */
|
||||
soundUnlock();
|
||||
|
||||
// Start the music server.
|
||||
/* Start the music server. */
|
||||
music_init();
|
||||
|
||||
// Start allocating the sources - music has already taken this.
|
||||
alGetError(); // Another error clear.
|
||||
/* Start allocating the sources - music has already taken this. */
|
||||
alGetError(); /* Another error clear. */
|
||||
mem = 0;
|
||||
while(((err = alGetError()) == AL_NO_ERROR) && (source_nstack < 128)) {
|
||||
if(mem < source_nstack+1) {
|
||||
// Allocate more memory.
|
||||
/* Allocate more memory. */
|
||||
mem += 32;
|
||||
source_stack = realloc(source_stack, sizeof(ALuint) * mem);
|
||||
}
|
||||
@ -183,20 +183,20 @@ int sound_init(void) {
|
||||
source_nstack++;
|
||||
}
|
||||
|
||||
// Use minimal ram.
|
||||
/* Use minimal ram. */
|
||||
source_stack = realloc(source_stack, sizeof(ALuint) * source_nstack);
|
||||
|
||||
// Debug magic.
|
||||
/* Debug magic. */
|
||||
DEBUG("OpenAL: %s", device);
|
||||
DEBUG("Sources: %d", source_nstack);
|
||||
DEBUG("Renderer: %s", alGetString(AL_RENDERER));
|
||||
DEBUG("Version: %s", alGetString(AL_VERSION));
|
||||
|
||||
// Load up all the sounds.
|
||||
/* Load up all the sounds. */
|
||||
sound_makeList();
|
||||
music_makeList(); // And music.
|
||||
music_makeList(); /* And music. */
|
||||
|
||||
// Now start the music thread.
|
||||
/* Now start the music thread. */
|
||||
music_player = SDL_CreateThread(music_thread, NULL);
|
||||
|
||||
return 0;
|
||||
@ -216,18 +216,18 @@ snderr_dev:
|
||||
}
|
||||
|
||||
|
||||
// Clean up after the sound system.
|
||||
/* Clean up after the sound system. */
|
||||
void sound_exit(void) {
|
||||
int i;
|
||||
// Free the sounds.
|
||||
/* Free the sounds. */
|
||||
for(i = 0; i < nsound_list; i++)
|
||||
sound_free(&sound_list[i]);
|
||||
free(sound_list);
|
||||
sound_list = NULL;
|
||||
nsound_list = 0;
|
||||
|
||||
// Must stop the music before killing it,
|
||||
// then thread should commit suicide.
|
||||
/* Must stop the music before killing it, */
|
||||
/* then thread should commit suicide. */
|
||||
if(music_player) {
|
||||
music_stop();
|
||||
music_kill();
|
||||
@ -235,11 +235,11 @@ void sound_exit(void) {
|
||||
music_exit();
|
||||
}
|
||||
|
||||
// Clean up the voices.
|
||||
/* Clean up the voices. */
|
||||
while(voice_start != NULL)
|
||||
voice_rm(NULL, voice_start);
|
||||
|
||||
// Clean up the sources.
|
||||
/* Clean up the sources. */
|
||||
if(source_stack)
|
||||
alDeleteSources(source_nstack, source_stack);
|
||||
|
||||
@ -255,11 +255,11 @@ void sound_exit(void) {
|
||||
soundUnlock();
|
||||
SDL_DestroyMutex(sound_lock);
|
||||
}
|
||||
// Cya alut!
|
||||
/* Cya alut! */
|
||||
alutExit();
|
||||
}
|
||||
|
||||
// Get the buffer to sound of [name].
|
||||
/* Get the buffer to sound of [name]. */
|
||||
ALuint sound_get(char* name) {
|
||||
if(sound_lock == NULL) return 0;
|
||||
|
||||
@ -271,7 +271,7 @@ ALuint sound_get(char* name) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Make list of available sounds.
|
||||
/* Make list of available sounds. */
|
||||
static int sound_makeList(void) {
|
||||
if(sound_lock == NULL) return 0;
|
||||
|
||||
@ -281,38 +281,38 @@ static int sound_makeList(void) {
|
||||
int len;
|
||||
int mem;
|
||||
|
||||
// Get the file list.
|
||||
/* Get the file list. */
|
||||
files = pack_listfiles(data, &nfiles);
|
||||
|
||||
// Load the profiles.
|
||||
/* Load the profiles. */
|
||||
mem = 0;
|
||||
for(i = 0; i < nfiles; i++)
|
||||
if((strncmp(files[i], SOUND_PREFIX, strlen(SOUND_PREFIX))==0) &&
|
||||
(strncmp(files[i] + strlen(files[i]) - strlen(SOUND_SUFFIX),
|
||||
SOUND_SUFFIX, strlen(SOUND_SUFFIX))==0)) {
|
||||
|
||||
// Expand the selection size.
|
||||
/* Expand the selection size. */
|
||||
nsound_list++;
|
||||
if(nsound_list > mem) {
|
||||
// We must grow.
|
||||
mem += 32; // We'll overallocate most likely.
|
||||
/* We must grow. */
|
||||
mem += 32; /* We'll overallocate most likely. */
|
||||
sound_list = realloc(sound_list, mem*sizeof(alSound));
|
||||
}
|
||||
|
||||
// Remove the prefix and suffix.
|
||||
/* Remove the prefix and suffix. */
|
||||
len = strlen(files[i]) - strlen(SOUND_SUFFIX SOUND_PREFIX);
|
||||
strncpy(tmp, files[i] + strlen(SOUND_PREFIX), len);
|
||||
tmp[len] = '\0';
|
||||
|
||||
// give it the new name.
|
||||
/* give it the new name. */
|
||||
sound_list[nsound_list-1].name = strdup(tmp);
|
||||
sound_load(&sound_list[nsound_list-1].buffer, files[i]);
|
||||
}
|
||||
|
||||
// Shrink to minimum ram usage.
|
||||
/* Shrink to minimum ram usage. */
|
||||
sound_list = realloc(sound_list, nsound_list*sizeof(alSound));
|
||||
|
||||
// Free the char* allocated by pack.
|
||||
/* Free the char* allocated by pack. */
|
||||
for(i = 0; i < nfiles; i++)
|
||||
free(files[i]);
|
||||
free(files);
|
||||
@ -322,7 +322,7 @@ static int sound_makeList(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Loads a sound into the sound_list.
|
||||
/* Loads a sound into the sound_list. */
|
||||
static int sound_load(ALuint* buffer, char* filename) {
|
||||
if(sound_lock == NULL) return 0;
|
||||
|
||||
@ -330,18 +330,18 @@ static int sound_load(ALuint* buffer, char* filename) {
|
||||
unsigned int size;
|
||||
ALenum err;
|
||||
|
||||
// Get the file data buffer from the packfile.
|
||||
/* Get the file data buffer from the packfile. */
|
||||
wavdata = pack_readfile(DATA, filename, &size);
|
||||
|
||||
soundLock();
|
||||
|
||||
// Bind to OpenAL buffer.
|
||||
/* Bind to OpenAL buffer. */
|
||||
(*buffer) = alutCreateBufferFromFileImage(wavdata, size);
|
||||
if((*buffer) == AL_NONE) WARN("FAILURE: %s", alutGetErrorString(alutGetError()));
|
||||
//alGenBuffers(1, buffer);
|
||||
//alBufferData(*buffer, AL_FORMAT_MONO16, wavdata, size, 22050);
|
||||
/*alGenBuffers(1, buffer); */
|
||||
/*alBufferData(*buffer, AL_FORMAT_MONO16, wavdata, size, 22050); */
|
||||
|
||||
// Errors?
|
||||
/* Errors? */
|
||||
if((err = alGetError()) != AL_NO_ERROR) {
|
||||
WARN("OpenAL erro '%d' loading sound '%s'.", err, filename);
|
||||
return 0;
|
||||
@ -349,7 +349,7 @@ static int sound_load(ALuint* buffer, char* filename) {
|
||||
|
||||
soundUnlock();
|
||||
|
||||
// Finish up.
|
||||
/* Finish up. */
|
||||
free(wavdata);
|
||||
return 0;
|
||||
}
|
||||
@ -359,39 +359,39 @@ static void sound_free(alSound* snd) {
|
||||
|
||||
soundLock();
|
||||
|
||||
// Free the stuff.
|
||||
/* Free the stuff. */
|
||||
if(snd->name) free(snd->name);
|
||||
alDeleteBuffers(1, &snd->buffer);
|
||||
|
||||
soundUnlock();
|
||||
}
|
||||
|
||||
// Update the sounds and prioritize them.
|
||||
/* Update the sounds and prioritize them. */
|
||||
void sound_update(void) {
|
||||
ALint stat;
|
||||
alVoice* voice, *prev, *next;
|
||||
|
||||
if(sound_lock == NULL) return; // Sound system is off.
|
||||
if(voice_start == NULL) return; // No voices.
|
||||
if(sound_lock == NULL) return; /* Sound system is off. */
|
||||
if(voice_start == NULL) return; /* No voices. */
|
||||
|
||||
soundLock();
|
||||
|
||||
// Update sound.
|
||||
/* Update sound. */
|
||||
prev = NULL;
|
||||
voice = voice_start;
|
||||
do {
|
||||
next = voice->next;
|
||||
|
||||
// Get status.
|
||||
/* Get status. */
|
||||
stat = -1;
|
||||
if(voice->source != 0)
|
||||
alGetSourcei(voice->source, AL_SOURCE_STATE, &stat);
|
||||
|
||||
if(!voice_is(voice, VOICE_DONE)) { // Still working.
|
||||
// Voice has a source.
|
||||
if(!voice_is(voice, VOICE_DONE)) { /* Still working. */
|
||||
/* Voice has a source. */
|
||||
if(voice->source != 0) {
|
||||
|
||||
// Update position.
|
||||
/* Update position. */
|
||||
alSource3f(voice->source, AL_POSITION,
|
||||
voice->px, voice->py, 0.);
|
||||
/*alSource3f(voice->source, AL_VELOCITY,
|
||||
@ -400,9 +400,9 @@ void sound_update(void) {
|
||||
|
||||
prev = voice;
|
||||
}else {
|
||||
// Delete them.
|
||||
/* Delete them. */
|
||||
if(stat != AL_PLAYING)
|
||||
voice_rm(prev, voice); // Do not set prev to voice.
|
||||
voice_rm(prev, voice); /* Do not set prev to voice. */
|
||||
else
|
||||
prev = voice;
|
||||
}
|
||||
@ -412,53 +412,53 @@ void sound_update(void) {
|
||||
soundUnlock();
|
||||
}
|
||||
|
||||
// Remove a voice.
|
||||
/* Remove a voice. */
|
||||
static void voice_rm(alVoice* prev, alVoice* voice) {
|
||||
ALint stat;
|
||||
|
||||
if(voice->source != 0) { // Source must exist.
|
||||
// Stop it if playing.
|
||||
if(voice->source != 0) { /* Source must exist. */
|
||||
/* Stop it if playing. */
|
||||
alGetSourcei(voice->source, AL_SOURCE_STATE, &stat);
|
||||
if(stat == AL_PLAYING) alSourceStop(voice->source);
|
||||
|
||||
// Clear it and get rid of it.
|
||||
source_stack[source_nstack++] = voice->source; // Throw it back.
|
||||
/* Clear it and get rid of it. */
|
||||
source_stack[source_nstack++] = voice->source; /* Throw it back. */
|
||||
}
|
||||
|
||||
// Delete from linked list.
|
||||
if(prev == NULL) // Was the first member.
|
||||
/* Delete from linked list. */
|
||||
if(prev == NULL) /* Was the first member. */
|
||||
voice_start = voice->next;
|
||||
else // Not first memmber.
|
||||
else /* Not first memmber. */
|
||||
prev->next = voice->next;
|
||||
if(voice_end == voice) // Last voice in linked list.
|
||||
if(voice_end == voice) /* Last voice in linked list. */
|
||||
voice_end = prev;
|
||||
free(voice);
|
||||
}
|
||||
|
||||
// Set all the sounds volume to vol.
|
||||
/* Set all the sounds volume to vol. */
|
||||
void sound_volume(const double vol) {
|
||||
if(sound_lock == NULL) return;
|
||||
|
||||
svolume = (ALfloat) vol;
|
||||
}
|
||||
|
||||
// Attempt to alloc a source for a voice.
|
||||
/* Attempt to alloc a source for a voice. */
|
||||
static int voice_getSource(alVoice* voc) {
|
||||
int ret;
|
||||
|
||||
// Sound system isn't on.
|
||||
/* Sound system isn't on. */
|
||||
if(sound_lock == NULL) return -1;
|
||||
|
||||
ret = 0; // Default return.
|
||||
ret = 0; /* Default return. */
|
||||
|
||||
soundLock();
|
||||
|
||||
// Try and grab a source.
|
||||
if(source_nstack > 0) { // We have the source.
|
||||
// We must pull it from the free source vector.
|
||||
/* Try and grab a source. */
|
||||
if(source_nstack > 0) { /* We have the source. */
|
||||
/* We must pull it from the free source vector. */
|
||||
voc->source = source_stack[--source_nstack];
|
||||
|
||||
// Initialize and play.
|
||||
/* Initialize and play. */
|
||||
voice_init(voc);
|
||||
ret = voice_play(voc);
|
||||
} else
|
||||
@ -469,23 +469,23 @@ static int voice_getSource(alVoice* voc) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Must lock becore calling.
|
||||
/* Must lock becore calling. */
|
||||
static void voice_init(alVoice* voice) {
|
||||
// Distance model.
|
||||
/* Distance model. */
|
||||
alSourcef(voice->source, AL_ROLLOFF_FACTOR, SOUND_ROLLOFF_FACTOR);
|
||||
alSourcef(voice->source, AL_MAX_DISTANCE, SOUND_MAX_DIST);
|
||||
alSourcef(voice->source, AL_REFERENCE_DISTANCE, SOUND_REFERENCE_DIST);
|
||||
|
||||
alSourcef(voice->source, AL_GAIN, svolume);
|
||||
alSource3f(voice->source, AL_POSITION, voice->px, voice->py, 0.);
|
||||
//alSource3f(voice->source, AL_VELOCITY, voice->vx, voice->vy, 0.);
|
||||
/*alSource3f(voice->source, AL_VELOCITY, voice->vx, voice->vy, 0.); */
|
||||
if(voice_is(voice, VOICE_LOOPING))
|
||||
alSourcei(voice->source, AL_LOOPING, AL_TRUE);
|
||||
else
|
||||
alSourcei(voice->source, AL_LOOPING, AL_FALSE);
|
||||
}
|
||||
|
||||
// Create a dynamic moving piece.
|
||||
/* Create a dynamic moving piece. */
|
||||
alVoice* sound_addVoice(int priority, double px, double py,
|
||||
double vx, double vy, const ALuint buffer, const unsigned int flags) {
|
||||
|
||||
@ -495,25 +495,25 @@ alVoice* sound_addVoice(int priority, double px, double py,
|
||||
|
||||
if(sound_lock == NULL) return NULL;
|
||||
|
||||
// Allocate the voice.
|
||||
/* Allocate the voice. */
|
||||
voc = malloc(sizeof(alVoice));
|
||||
|
||||
// Set the data.
|
||||
/* Set the data. */
|
||||
voc->next = NULL;
|
||||
voc->priority = priority;
|
||||
voc->start = SDL_GetTicks();
|
||||
voc->buffer = buffer;
|
||||
|
||||
// Handle positions.
|
||||
/* Handle positions. */
|
||||
voc->px = px;
|
||||
voc->py = py;
|
||||
//voc->vx = vx;
|
||||
//voc->vy = vy;
|
||||
/*voc->vx = vx; */
|
||||
/*voc->vy = vy; */
|
||||
|
||||
// Handle the flags.
|
||||
/* Handle the flags. */
|
||||
voice_parseFlags(voc, flags);
|
||||
|
||||
// Get the source.
|
||||
/* Get the source. */
|
||||
voice_getSource(voc);
|
||||
|
||||
if(voice_start == NULL) {
|
||||
@ -528,14 +528,14 @@ alVoice* sound_addVoice(int priority, double px, double py,
|
||||
return voc;
|
||||
}
|
||||
|
||||
// Delete the voice.
|
||||
/* Delete the voice. */
|
||||
void sound_delVoice(alVoice* voice) {
|
||||
if(sound_lock == NULL) return;
|
||||
|
||||
voice_set(voice, VOICE_DONE);
|
||||
}
|
||||
|
||||
// Update voice position, should be run once per frame.
|
||||
/* Update voice position, should be run once per frame. */
|
||||
void voice_update(alVoice* voice, double px, double py, double vx, double vy) {
|
||||
(void) vx;
|
||||
(void) vy;
|
||||
@ -544,24 +544,24 @@ void voice_update(alVoice* voice, double px, double py, double vx, double vy) {
|
||||
|
||||
voice->px = px;
|
||||
voice->py = py;
|
||||
//voice->vx = vx;
|
||||
//voice->vy = vy;
|
||||
/*voice->vx = vx; */
|
||||
/*voice->vy = vy; */
|
||||
}
|
||||
|
||||
// Changes the voice's buffer.
|
||||
/* Changes the voice's buffer. */
|
||||
void voice_buffer(alVoice* voice, const ALuint buffer, const unsigned int flags) {
|
||||
if(voice == NULL) return;
|
||||
|
||||
voice->buffer = buffer;
|
||||
voice_parseFlags(voice, flags);
|
||||
|
||||
// Start playing.
|
||||
/* Start playing. */
|
||||
soundLock();
|
||||
voice_play(voice);
|
||||
soundUnlock();
|
||||
}
|
||||
|
||||
// Stop playing sound.
|
||||
/* Stop playing sound. */
|
||||
void voice_stop(alVoice* voice) {
|
||||
if(voice == NULL) return;
|
||||
|
||||
@ -571,11 +571,11 @@ void voice_stop(alVoice* voice) {
|
||||
soundUnlock();
|
||||
}
|
||||
|
||||
// Handle flags.
|
||||
/* Handle flags. */
|
||||
static void voice_parseFlags(alVoice* voice, const unsigned int flags) {
|
||||
voice->flags = 0; // Defaults.
|
||||
voice->flags = 0; /* Defaults. */
|
||||
|
||||
// Looping.
|
||||
/* Looping. */
|
||||
if(flags & VOICE_LOOPING)
|
||||
voice_set(voice, VOICE_LOOPING);
|
||||
|
||||
@ -585,20 +585,20 @@ static void voice_parseFlags(alVoice* voice, const unsigned int flags) {
|
||||
alSourcei(voice->source, AL_SOURCE_RELATIVE, AL_FALSE);
|
||||
}
|
||||
|
||||
// Make a voice play. Must lock before calling.
|
||||
/* Make a voice play. Must lock before calling. */
|
||||
static int voice_play(alVoice* voice) {
|
||||
ALenum err;
|
||||
ALint stat;
|
||||
|
||||
// Must have buffer.
|
||||
/* Must have buffer. */
|
||||
if(voice->buffer != 0) {
|
||||
alGetSourcei(voice->source, AL_SOURCE_STATE, &stat);
|
||||
if(stat == AL_PLAYING)
|
||||
alSourceStop(voice->source);
|
||||
// Set buffer.
|
||||
/* Set buffer. */
|
||||
alSourcei(voice->source, AL_BUFFER, voice->buffer);
|
||||
|
||||
// Try to play the source.
|
||||
/* Try to play the source. */
|
||||
alSourcePlay(voice->source);
|
||||
err = alGetError();
|
||||
if(err == AL_NO_ERROR) voice_set(voice, VOICE_PLAYING);
|
||||
@ -616,13 +616,13 @@ void sound_listener(double dir, double px, double py, double vx, double vy) {
|
||||
|
||||
soundLock();
|
||||
|
||||
// Set orientation.
|
||||
/* Set orientation. */
|
||||
ALfloat ori[] = { 0., 0., 0., 0., 0., 1. };
|
||||
ori[0] = cos(dir);
|
||||
ori[1] = sin(dir);
|
||||
alListenerfv(AL_ORIENTATION, ori);
|
||||
alListener3f(AL_POSITION, px, py, 1.);
|
||||
//alListener3f(AL_VELOCITY, vx, vy, 0.);
|
||||
/*alListener3f(AL_VELOCITY, vx, vy, 0.); */
|
||||
|
||||
soundUnlock();
|
||||
}
|
||||
|
14
src/sound.h
14
src/sound.h
@ -2,31 +2,31 @@
|
||||
#include <AL/al.h>
|
||||
#include "physics.h"
|
||||
|
||||
#define VOICE_LOOPING (1<<10) // Voice loops.
|
||||
#define VOICE_STATIC (1<<11) // Voice isn't relative.
|
||||
#define VOICE_LOOPING (1<<10) /* Voice loops. */
|
||||
#define VOICE_STATIC (1<<11) /* Voice isn't relative. */
|
||||
|
||||
struct alVoice;
|
||||
typedef struct alVoice alVoice;
|
||||
|
||||
// Sound subsystem.
|
||||
/* Sound subsystem. */
|
||||
int sound_init(void);
|
||||
void sound_exit(void);
|
||||
void sound_update(void);
|
||||
|
||||
// Sound manupulation functions.
|
||||
/* Sound manupulation functions. */
|
||||
ALuint sound_get(char* name);
|
||||
void sound_volume(const double vol);
|
||||
|
||||
// Voice manipulation function.
|
||||
/* Voice manipulation function. */
|
||||
alVoice* sound_addVoice(int priority, double px, double py,
|
||||
double vx, double vy, const ALuint buffer, const unsigned int flags);
|
||||
|
||||
void sound_delVoice(alVoice* voice); // Delete voice.
|
||||
void sound_delVoice(alVoice* voice); /* Delete voice. */
|
||||
|
||||
void voice_update(alVoice* voice, double px, double py, double vx, double vy);
|
||||
void voice_buffer(alVoice* voice, const ALuint buffer, const unsigned int flags);
|
||||
void voice_stop(alVoice* voice);
|
||||
|
||||
// Listener manipulation.
|
||||
/* Listener manipulation. */
|
||||
void sound_listener(double dir, double px, double py, double vx, double vy);
|
||||
|
||||
|
260
src/space.c
260
src/space.c
@ -34,7 +34,7 @@
|
||||
#define PLANET_GFX_EXTERIOR_W 400
|
||||
#define PLANET_GFX_EXTERIOR_H 400
|
||||
|
||||
// Overcome warning due to zero value.
|
||||
/* Overcome warning due to zero value. */
|
||||
|
||||
#define FLAG_XSET (1<<0)
|
||||
#define FLAG_YSET (1<<1)
|
||||
@ -44,45 +44,45 @@
|
||||
#define FLAG_TECHSET (1<<5)
|
||||
#define FLAG_FACTIONSET (1<<6)
|
||||
|
||||
// Planet <-> system name stack.
|
||||
/* Planet <-> system name stack. */
|
||||
static char** planetname_stack = NULL;
|
||||
static char** systemname_stack = NULL;
|
||||
static int spacename_nstack = 0;
|
||||
|
||||
// Star system stack and co.
|
||||
StarSystem* systems_stack = NULL; // Star system stack.
|
||||
int systems_nstack = 0; // Number of star systems.
|
||||
static int nplanets = 0; // Total number of loaded planets - A little silly.
|
||||
StarSystem* cur_system = NULL; // Current star system.
|
||||
/* Star system stack and co. */
|
||||
StarSystem* systems_stack = NULL; /* Star system stack. */
|
||||
int systems_nstack = 0; /* Number of star systems. */
|
||||
static int nplanets = 0; /* Total number of loaded planets - A little silly. */
|
||||
StarSystem* cur_system = NULL; /* Current star system. */
|
||||
|
||||
// Fleet spawn rate.
|
||||
unsigned int spawn_timer = 0; // Controls spawn rate.
|
||||
/* Fleet spawn rate. */
|
||||
unsigned int spawn_timer = 0; /* Controls spawn rate. */
|
||||
|
||||
// Star stack and co.
|
||||
#define STAR_BUF 100 // Area to leave around screen, more = less repitition.
|
||||
/* Star stack and co. */
|
||||
#define STAR_BUF 100 /* Area to leave around screen, more = less repitition. */
|
||||
typedef struct Star_ {
|
||||
double x, y; // Position. It is simpler ligher to use two doubles than the physics.
|
||||
double x, y; /* Position. It is simpler ligher to use two doubles than the physics. */
|
||||
double brightness;
|
||||
} Star;
|
||||
|
||||
static Star* stars = NULL; // Star array.
|
||||
static int nstars = 0; // Total stars.
|
||||
static int mstars = 0; // Memory stars are taking.
|
||||
static Star* stars = NULL; /* Star array. */
|
||||
static int nstars = 0; /* Total stars. */
|
||||
static int mstars = 0; /* Memory stars are taking. */
|
||||
|
||||
// Intern.
|
||||
/* Intern. */
|
||||
static StarSystem* system_get(const char* sysname);
|
||||
static Planet* planet_pull(const char* name);
|
||||
static void space_addFleet(Fleet* fleet);
|
||||
static StarSystem* system_parse(const xmlNodePtr parent);
|
||||
static void system_parseJumps(const xmlNodePtr parent);
|
||||
static PlanetClass planetclass_get(const char a);
|
||||
// Extern.
|
||||
/* Extern. */
|
||||
extern void player_message(const char* fmt, ...);
|
||||
void planets_minimap(const double res, const double w,
|
||||
const double h, const RadarShape shape);
|
||||
|
||||
// Draw the planet. Used in planet.c
|
||||
// Matrix mode is already displaced to center of the minimap.
|
||||
/* Draw the planet. Used in planet.c */
|
||||
/* Matrix mode is already displaced to center of the minimap. */
|
||||
#define PIXEL(x,y) if((shape == RADAR_RECT && ABS(x)<w/2. && ABS(y)<h/2.) || \
|
||||
(shape == RADAR_CIRCLE && (((x)*(x)+(y)*(y)) < rc))) glVertex2i((x),(y))
|
||||
void planets_minimap(const double res, const double w,
|
||||
@ -146,20 +146,20 @@ void planets_minimap(const double res, const double w,
|
||||
}
|
||||
#undef PIXEL
|
||||
|
||||
// A* Algorithm fo shortest path finding.
|
||||
/* A* Algorithm fo shortest path finding. */
|
||||
|
||||
// The node struct.
|
||||
/* The node struct. */
|
||||
typedef struct SysNode_ {
|
||||
struct SysNode_* next, *gnext;
|
||||
|
||||
struct SysNode_* parent;
|
||||
StarSystem* sys;
|
||||
double r; // Ranking.
|
||||
int g; // Step.
|
||||
double r; /* Ranking. */
|
||||
int g; /* Step. */
|
||||
} SysNode;
|
||||
|
||||
static SysNode* A_gc;
|
||||
// Prototypes.
|
||||
/* Prototypes. */
|
||||
static SysNode* A_newNode(StarSystem* sys, SysNode* parent);
|
||||
static double A_h(StarSystem* n, StarSystem* g);
|
||||
static double A_g(SysNode* n);
|
||||
@ -169,7 +169,7 @@ static SysNode* A_in(SysNode* first, StarSystem* cur);
|
||||
static SysNode* A_lowest(SysNode* first);
|
||||
static void A_freeList(SysNode* first);
|
||||
|
||||
// Creates a new node link to star system.
|
||||
/* Creates a new node link to star system. */
|
||||
static SysNode* A_newNode(StarSystem* sys, SysNode* parent) {
|
||||
SysNode* n;
|
||||
|
||||
@ -190,17 +190,17 @@ static SysNode* A_newNode(StarSystem* sys, SysNode* parent) {
|
||||
static double A_h(StarSystem* n, StarSystem* g) {
|
||||
(void)n;
|
||||
(void)g;
|
||||
// Euclidean distance.
|
||||
//return sqrt(pow2(n->pos.x - g->pos.x) + pow2(n->pos.y - g->pos.y))/100.;
|
||||
/* Euclidean distance. */
|
||||
/*return sqrt(pow2(n->pos.x - g->pos.x) + pow2(n->pos.y - g->pos.y))/100.; */
|
||||
return 0.;
|
||||
}
|
||||
|
||||
// Get the g from a node.
|
||||
/* Get the g from a node. */
|
||||
static double A_g(SysNode* n) {
|
||||
return n->g;
|
||||
}
|
||||
|
||||
// Add a node to the linkes list.
|
||||
/* Add a node to the linkes list. */
|
||||
static SysNode* A_add(SysNode* first, SysNode* cur) {
|
||||
SysNode* n;
|
||||
|
||||
@ -215,7 +215,7 @@ static SysNode* A_add(SysNode* first, SysNode* cur) {
|
||||
return first;
|
||||
}
|
||||
|
||||
// Remove a node from a linked list.
|
||||
/* Remove a node from a linked list. */
|
||||
static SysNode* A_rm(SysNode* first, StarSystem* cur) {
|
||||
SysNode* n, *p;
|
||||
|
||||
@ -238,7 +238,7 @@ static SysNode* A_rm(SysNode* first, StarSystem* cur) {
|
||||
return first;
|
||||
}
|
||||
|
||||
// Check if node is in linked list.
|
||||
/* Check if node is in linked list. */
|
||||
static SysNode* A_in(SysNode* first, StarSystem* cur) {
|
||||
SysNode* n;
|
||||
|
||||
@ -253,7 +253,7 @@ static SysNode* A_in(SysNode* first, StarSystem* cur) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Return the lowest ranking node from a linked list of nodes.
|
||||
/* Return the lowest ranking node from a linked list of nodes. */
|
||||
static SysNode* A_lowest(SysNode* first) {
|
||||
SysNode* lowest, *n;
|
||||
|
||||
@ -270,7 +270,7 @@ static SysNode* A_lowest(SysNode* first) {
|
||||
return lowest;
|
||||
}
|
||||
|
||||
// Free a linked list.
|
||||
/* Free a linked list. */
|
||||
static void A_freeList(SysNode* first) {
|
||||
SysNode* p, *n;
|
||||
|
||||
@ -299,17 +299,17 @@ StarSystem** system_getJumpPath(int* njumps, char* sysstart, char* sysend) {
|
||||
|
||||
A_gc = NULL;
|
||||
|
||||
// Initial and target systems.
|
||||
ssys = system_get(sysstart); // Start.
|
||||
esys = system_get(sysend); // End.
|
||||
/* Initial and target systems. */
|
||||
ssys = system_get(sysstart); /* Start. */
|
||||
esys = system_get(sysend); /* End. */
|
||||
|
||||
// Start the linked lists.
|
||||
/* Start the linked lists. */
|
||||
open = closed = NULL;
|
||||
cur = A_newNode(ssys, NULL);
|
||||
open = A_add(open, cur); // Initial open node is the start system.
|
||||
open = A_add(open, cur); /* Initial open node is the start system. */
|
||||
|
||||
while((cur = A_lowest(open))->sys != esys) {
|
||||
// Get best from open and toss to closed.
|
||||
/* Get best from open and toss to closed. */
|
||||
open = A_rm(open, cur->sys);
|
||||
closed = A_add(closed, cur);
|
||||
cost = A_g(cur) + 1;
|
||||
@ -320,12 +320,12 @@ StarSystem** system_getJumpPath(int* njumps, char* sysstart, char* sysend) {
|
||||
|
||||
ocost = A_in(open, sys);
|
||||
if((ocost != NULL) && (cost < ocost->g)) {
|
||||
open = A_rm(open, sys); // New path is better.
|
||||
open = A_rm(open, sys); /* New path is better. */
|
||||
}
|
||||
|
||||
ccost = A_in(closed, sys);
|
||||
if(ccost != NULL) {
|
||||
closed = A_rm(closed, sys); // Shouldn't happen.
|
||||
closed = A_rm(closed, sys); /* Shouldn't happen. */
|
||||
}
|
||||
|
||||
if((ocost == NULL) && (ccost == NULL)) {
|
||||
@ -336,7 +336,7 @@ StarSystem** system_getJumpPath(int* njumps, char* sysstart, char* sysend) {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Build the path backwards.
|
||||
/* Build the path backwards. */
|
||||
(*njumps) = A_g(cur);
|
||||
res = malloc(sizeof(StarSystem*) * (*njumps));
|
||||
for(i = 0; i < (*njumps); i++) {
|
||||
@ -344,14 +344,14 @@ StarSystem** system_getJumpPath(int* njumps, char* sysstart, char* sysend) {
|
||||
cur = cur->parent;
|
||||
}
|
||||
|
||||
// Free the linked list.
|
||||
/* Free the linked list. */
|
||||
A_freeList(A_gc);
|
||||
return res;
|
||||
}
|
||||
|
||||
static PlanetClass planetclass_get(const char a) {
|
||||
switch(a) {
|
||||
// Planets use letters.
|
||||
/* Planets use letters. */
|
||||
case 'A': return PLANET_CLASS_A;
|
||||
case 'B': return PLANET_CLASS_B;
|
||||
case 'C': return PLANET_CLASS_C;
|
||||
@ -376,7 +376,7 @@ static PlanetClass planetclass_get(const char a) {
|
||||
case 'Y': return PLANET_CLASS_Y;
|
||||
case 'Z': return PLANET_CLASS_Z;
|
||||
|
||||
// Stations use numbers as there isn't as many.
|
||||
/* Stations use numbers as there isn't as many. */
|
||||
case '0' : return STATION_CLASS_A;
|
||||
case '1' : return STATION_CLASS_B;
|
||||
case '2' : return STATION_CLASS_C;
|
||||
@ -386,7 +386,7 @@ static PlanetClass planetclass_get(const char a) {
|
||||
};
|
||||
}
|
||||
|
||||
// Check distance to ensure we can go into hyperspace.
|
||||
/* Check distance to ensure we can go into hyperspace. */
|
||||
int space_canHyperspace(Pilot* p) {
|
||||
int i;
|
||||
double d;
|
||||
@ -400,18 +400,18 @@ int space_canHyperspace(Pilot* p) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Hyperspace, returns 0 if entering hyperspace, or the distance if not.
|
||||
/* Hyperspace, returns 0 if entering hyperspace, or the distance if not. */
|
||||
int space_hyperspace(Pilot* p) {
|
||||
if(p->fuel < HYPERSPACE_FUEL) return -3;
|
||||
if(!space_canHyperspace(p)) return -1;
|
||||
|
||||
// Pilot is now going to get automatically ready for hyperspace.
|
||||
/* Pilot is now going to get automatically ready for hyperspace. */
|
||||
pilot_setFlag(p, PILOT_HYP_PREP);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Return the name of all the planets that belong to factions.
|
||||
/* Return the name of all the planets that belong to factions. */
|
||||
char** space_getFactionPlanet(int* nplanets, int* factions, int nfactions) {
|
||||
int i, j, k;
|
||||
Planet* planet;
|
||||
@ -437,14 +437,14 @@ char** space_getFactionPlanet(int* nplanets, int* factions, int nfactions) {
|
||||
tmp = realloc(tmp, sizeof(char*) * mtmp);
|
||||
}
|
||||
tmp[ntmp-1] = planet->name;
|
||||
break; // No need to check all factions.
|
||||
break; /* No need to check all factions. */
|
||||
}
|
||||
}
|
||||
(*nplanets) = ntmp;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// Return the name of a random planet.
|
||||
/* Return the name of a random planet. */
|
||||
char* space_getRndPlanet(void) {
|
||||
int i, j;
|
||||
char** tmp;
|
||||
@ -472,7 +472,7 @@ char* space_getRndPlanet(void) {
|
||||
return res;
|
||||
}
|
||||
|
||||
// Get the system from it's name.
|
||||
/* Get the system from it's name. */
|
||||
static StarSystem* system_get(const char* sysname) {
|
||||
int i;
|
||||
|
||||
@ -484,7 +484,7 @@ static StarSystem* system_get(const char* sysname) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get the name of a system from a planetname.
|
||||
/* Get the name of a system from a planetname. */
|
||||
char* planet_getSystem(char* planetname) {
|
||||
int i;
|
||||
for(i = 0; i < spacename_nstack; i++)
|
||||
@ -495,7 +495,7 @@ char* planet_getSystem(char* planetname) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get a planet based on it's name.
|
||||
/* Get a planet based on it's name. */
|
||||
Planet* planet_get(char* planetname) {
|
||||
int i;
|
||||
char* sys;
|
||||
@ -511,31 +511,31 @@ Planet* planet_get(char* planetname) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Basically used for spawning fleets.
|
||||
/* Basically used for spawning fleets. */
|
||||
void space_update(const double dt) {
|
||||
unsigned int t;
|
||||
int i, j, f;
|
||||
|
||||
(void)dt; // Don't need it right now.
|
||||
(void)dt; /* Don't need it right now. */
|
||||
|
||||
if(cur_system == NULL) return; // Can't update a null system.
|
||||
if(cur_system == NULL) return; /* Can't update a null system. */
|
||||
|
||||
t = SDL_GetTicks();
|
||||
|
||||
if(cur_system->nfleets == 0)
|
||||
// Please stop checking that there are no fleets.
|
||||
/* Please stop checking that there are no fleets. */
|
||||
spawn_timer = t + 300000;
|
||||
|
||||
if(spawn_timer < t) {
|
||||
// Time to possibly spawn.
|
||||
/* Time to possibly spawn. */
|
||||
|
||||
// Spawn chance is based on overall percentage.
|
||||
/* Spawn chance is based on overall percentage. */
|
||||
f = RNG(0, 100*cur_system->nfleets);
|
||||
j = 0;
|
||||
for(i = 0; i < cur_system->nfleets; i++) {
|
||||
j += cur_system->fleets[i].chance;
|
||||
if(f < j) {
|
||||
// Add one fleet.
|
||||
/* Add one fleet. */
|
||||
space_addFleet(cur_system->fleets[i].fleet);
|
||||
break;
|
||||
}
|
||||
@ -544,13 +544,13 @@ void space_update(const double dt) {
|
||||
}
|
||||
}
|
||||
|
||||
// Crate a fleet.
|
||||
/* Crate a fleet. */
|
||||
static void space_addFleet(Fleet* fleet) {
|
||||
int i;
|
||||
double a;
|
||||
Vec2 vv, vp, vn;
|
||||
|
||||
// Simulate them coming from hyperspace.
|
||||
/* Simulate them coming from hyperspace. */
|
||||
vect_pset(&vp, RNG(MIN_HYPERSPACE_DIST, MIN_HYPERSPACE_DIST*1.5),
|
||||
RNG(0, 360)*M_PI/180.);
|
||||
vectnull(&vn);
|
||||
@ -574,16 +574,16 @@ static void space_addFleet(Fleet* fleet) {
|
||||
}
|
||||
}
|
||||
|
||||
// Init the system.
|
||||
/* Init the system. */
|
||||
void space_init(const char* sysname) {
|
||||
char* lt;
|
||||
int i;
|
||||
|
||||
// Cleanup some stuff.
|
||||
player_clear(); // Clears targets.
|
||||
pilots_clean(); // Destroy all the current pilots, exept player.
|
||||
weapon_clear(); // Get rid of all the weapons.
|
||||
spfx_clear(); // Remove of explosions.
|
||||
/* Cleanup some stuff. */
|
||||
player_clear(); /* Clears targets. */
|
||||
pilots_clean(); /* Destroy all the current pilots, exept player. */
|
||||
weapon_clear(); /* Get rid of all the weapons. */
|
||||
spfx_clear(); /* Remove of explosions. */
|
||||
|
||||
if((sysname == NULL) && (cur_system == NULL))
|
||||
ERR("Cannot reinit system if there is no system previously loaded");
|
||||
@ -598,26 +598,26 @@ void space_init(const char* sysname) {
|
||||
player_message("Entering System %s on %s", sysname, lt);
|
||||
free(lt);
|
||||
|
||||
// Set up stars.
|
||||
/* Set up stars. */
|
||||
nstars = (cur_system->stars*SCREEN_W*SCREEN_H+STAR_BUF*STAR_BUF)/(800*640);
|
||||
if(mstars < nstars)
|
||||
stars = realloc(stars, sizeof(Star)*nstars); // should realloc not malloc.
|
||||
stars = realloc(stars, sizeof(Star)*nstars); /* should realloc not malloc. */
|
||||
for(i = 0; i < nstars; i++) {
|
||||
stars[i].brightness = (double)RNG(50, 200)/256.;
|
||||
stars[i].x = (double)RNG(-STAR_BUF, SCREEN_W + STAR_BUF);
|
||||
stars[i].y = (double)RNG(-STAR_BUF, SCREEN_H + STAR_BUF);
|
||||
}
|
||||
}
|
||||
// Set up fleets -> pilots.
|
||||
/* Set up fleets -> pilots. */
|
||||
for(i = 0; i < cur_system->nfleets; i++)
|
||||
if(RNG(0,100) <= (cur_system->fleets[i].chance/2)) // Fleet check (50% chance).
|
||||
if(RNG(0,100) <= (cur_system->fleets[i].chance/2)) /* Fleet check (50% chance). */
|
||||
space_addFleet(cur_system->fleets[i].fleet);
|
||||
|
||||
// Start the spawn timer.
|
||||
/* Start the spawn timer. */
|
||||
spawn_timer = SDL_GetTicks() + 120000./(float)(cur_system->nfleets+1);
|
||||
}
|
||||
|
||||
// Load the planets of name 'name'.
|
||||
/* Load the planets of name 'name'. */
|
||||
static Planet* planet_pull(const char* name) {
|
||||
int i;
|
||||
|
||||
@ -640,7 +640,7 @@ static Planet* planet_pull(const char* name) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
node = node->xmlChildrenNode; // First system node.
|
||||
node = node->xmlChildrenNode; /* First system node. */
|
||||
if(node == NULL) {
|
||||
ERR("Malformed "PLANET_DATA" file: does not contain elements");
|
||||
return NULL;
|
||||
@ -649,7 +649,7 @@ static Planet* planet_pull(const char* name) {
|
||||
do {
|
||||
if(xml_isNode(node, XML_PLANET_TAG)) {
|
||||
tstr = xml_nodeProp(node, "name");
|
||||
if(strcmp(tstr, name)==0) { // Found.
|
||||
if(strcmp(tstr, name)==0) { /* Found. */
|
||||
tmp = CALLOC_L(Planet);
|
||||
tmp->name = tstr;
|
||||
|
||||
@ -660,13 +660,13 @@ static Planet* planet_pull(const char* name) {
|
||||
cur = node->children;
|
||||
do {
|
||||
if(xml_isNode(cur, "space")) {
|
||||
// Load space gfx.
|
||||
/* Load space gfx. */
|
||||
snprintf(str, strlen(xml_get(cur))+sizeof(PLANET_GFX_SPACE),
|
||||
PLANET_GFX_SPACE"%s", xml_get(cur));
|
||||
tmp->gfx_space = gl_newImage(str);
|
||||
}
|
||||
else if(xml_isNode(cur, "exterior")) {
|
||||
// Load land gfx.
|
||||
/* Load land gfx. */
|
||||
snprintf(str, strlen(xml_get(cur))+sizeof(PLANET_GFX_EXTERIOR),
|
||||
PLANET_GFX_EXTERIOR"%s", xml_get(cur));
|
||||
tmp->gfx_exterior = gl_newImage(str);
|
||||
@ -738,7 +738,7 @@ static Planet* planet_pull(const char* name) {
|
||||
} while(xml_nextNode(node));
|
||||
break;
|
||||
} else
|
||||
free(tstr); // xmlGetProp mallocs the string.
|
||||
free(tstr); /* xmlGetProp mallocs the string. */
|
||||
}
|
||||
} while(xml_nextNode(node));
|
||||
|
||||
@ -746,7 +746,7 @@ static Planet* planet_pull(const char* name) {
|
||||
free(buf);
|
||||
xmlCleanupParser();
|
||||
|
||||
// Check elements.
|
||||
/* Check elements. */
|
||||
if(tmp) {
|
||||
#define MELEMENT(o,s) if(o) WARN("Planet '%s' missing '"s"' element", tmp->name)
|
||||
MELEMENT(tmp->gfx_space==NULL, "GFX_space");
|
||||
@ -775,8 +775,8 @@ static Planet* planet_pull(const char* name) {
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// Parse node 'parent' which should be the node of a system.
|
||||
// Return the StarSystem fully loaded.
|
||||
/* Parse node 'parent' which should be the node of a system. */
|
||||
/* Return the StarSystem fully loaded. */
|
||||
static StarSystem* system_parse(const xmlNodePtr parent) {
|
||||
Planet* planet = NULL;
|
||||
SystemFleet* fleet = NULL;
|
||||
@ -786,12 +786,12 @@ static StarSystem* system_parse(const xmlNodePtr parent) {
|
||||
|
||||
uint32_t flags;
|
||||
|
||||
tmp->name = xml_nodeProp(parent, "name"); // Already mallocs.
|
||||
tmp->name = xml_nodeProp(parent, "name"); /* Already mallocs. */
|
||||
|
||||
node = parent->xmlChildrenNode;
|
||||
|
||||
do {
|
||||
// Load all the things!
|
||||
/* Load all the things! */
|
||||
if(xml_isNode(node, "pos")) {
|
||||
cur = node->children;
|
||||
do {
|
||||
@ -808,7 +808,7 @@ static StarSystem* system_parse(const xmlNodePtr parent) {
|
||||
else if(xml_isNode(node, "general")) {
|
||||
cur = node->children;
|
||||
do {
|
||||
if(xml_isNode(cur, "stars")) // Non-zero.
|
||||
if(xml_isNode(cur, "stars")) /* Non-zero. */
|
||||
tmp->stars = xml_getInt(cur);
|
||||
else if(xml_isNode(cur, "asteroids")) {
|
||||
flags |= FLAG_ASTEROIDSSET;
|
||||
@ -820,18 +820,18 @@ static StarSystem* system_parse(const xmlNodePtr parent) {
|
||||
}
|
||||
}while(xml_nextNode(cur));
|
||||
}
|
||||
// Load all the planets.
|
||||
/* Load all the planets. */
|
||||
else if(xml_isNode(node, "planets")) {
|
||||
cur = node->children;
|
||||
do {
|
||||
if(cur && xml_isNode(cur, "planet")) {
|
||||
// Add planet to system.
|
||||
nplanets++; // Increase planet counter.
|
||||
/* Add planet to system. */
|
||||
nplanets++; /* Increase planet counter. */
|
||||
planet = planet_pull(xml_get(cur));
|
||||
tmp->planets = realloc(tmp->planets, sizeof(Planet)*(++tmp->nplanets));
|
||||
memcpy(tmp->planets+(tmp->nplanets-1), planet, sizeof(Planet));
|
||||
|
||||
// Add planet <-> star system to name stack.
|
||||
/* Add planet <-> star system to name stack. */
|
||||
spacename_nstack++;
|
||||
planetname_stack = realloc(planetname_stack,
|
||||
sizeof(char*)*spacename_nstack);
|
||||
@ -843,7 +843,7 @@ static StarSystem* system_parse(const xmlNodePtr parent) {
|
||||
}
|
||||
} while(xml_nextNode(cur));
|
||||
}
|
||||
// Load all the fleets.
|
||||
/* Load all the fleets. */
|
||||
else if(xml_isNode(node, "fleets")) {
|
||||
cur = node->children;
|
||||
do {
|
||||
@ -853,12 +853,12 @@ static StarSystem* system_parse(const xmlNodePtr parent) {
|
||||
if(fleet->fleet == NULL)
|
||||
WARN("Fleet %s for Star System %s not found", xml_get(cur), tmp->name);
|
||||
|
||||
ptrc = xml_nodeProp(cur, "chance"); // Malloc ptrc.
|
||||
ptrc = xml_nodeProp(cur, "chance"); /* Malloc ptrc. */
|
||||
fleet->chance = atoi(ptrc);
|
||||
if(fleet->chance == 0)
|
||||
WARN("Fleet %s for Star System %s has 0%% chance to appear",
|
||||
fleet->fleet->name, tmp->name);
|
||||
if(ptrc) free(ptrc); // Free the ptrc.
|
||||
if(ptrc) free(ptrc); /* Free the ptrc. */
|
||||
|
||||
tmp->fleets = realloc(tmp->fleets, sizeof(SystemFleet)*(++tmp->nfleets));
|
||||
memcpy(tmp->fleets+(tmp->nfleets-1), fleet, sizeof(SystemFleet));
|
||||
@ -868,30 +868,30 @@ static StarSystem* system_parse(const xmlNodePtr parent) {
|
||||
}
|
||||
} while(xml_nextNode(node));
|
||||
|
||||
// Check elements.
|
||||
/* Check elements. */
|
||||
#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(flags&FLAG_ASTEROIDSSET, "asteroids"); // Can be 0.
|
||||
MELEMENT(flags&FLAG_ASTEROIDSSET, "asteroids"); /* Can be 0. */
|
||||
MELEMENT(flags&FLAG_INTEFERENCESET, "inteference");
|
||||
#undef MELEMENT
|
||||
|
||||
// Post processing.
|
||||
/* Post processing. */
|
||||
if(tmp->nplanets > 0)
|
||||
// TODO: Make dependant on overall planet faction.
|
||||
/* TODO: Make dependant on overall planet faction. */
|
||||
tmp->faction = tmp->planets[0].faction;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// Load the jumps into a system.
|
||||
/* Load the jumps into a system. */
|
||||
static void system_parseJumps(const xmlNodePtr parent) {
|
||||
int i;
|
||||
StarSystem* system;
|
||||
char* name;
|
||||
xmlNodePtr cur, node;
|
||||
|
||||
name = xml_nodeProp(parent, "name"); // Already mallocs.
|
||||
name = xml_nodeProp(parent, "name"); /* Already mallocs. */
|
||||
for(i = 0; i < systems_nstack; i++)
|
||||
if(strcmp(systems_stack[i].name, name)==0) {
|
||||
system = &systems_stack[i];
|
||||
@ -899,12 +899,12 @@ static void system_parseJumps(const xmlNodePtr parent) {
|
||||
}
|
||||
if(i == systems_nstack)
|
||||
WARN("System '%s' was not found in the stack for some reason", name);
|
||||
free(name); // No need for it now.
|
||||
free(name); /* No need for it now. */
|
||||
|
||||
node = parent->xmlChildrenNode;
|
||||
|
||||
do {
|
||||
// Load the data.
|
||||
/* Load the data. */
|
||||
if(xml_isNode(node, "jumps")) {
|
||||
cur = node->children;
|
||||
do {
|
||||
@ -924,8 +924,8 @@ static void system_parseJumps(const xmlNodePtr parent) {
|
||||
} while(xml_nextNode(node));
|
||||
}
|
||||
|
||||
// Load the ENTIRE universe into RAM. -- WOAH!
|
||||
// -- Used a two system pass to first load the star systems_stack and then set jump routes.
|
||||
/* Load the ENTIRE universe into RAM. -- WOAH! */
|
||||
/* -- Used a two system pass to first load the star systems_stack and then set jump routes. */
|
||||
int space_load(void) {
|
||||
uint32_t bufsize;
|
||||
char* buf = pack_readfile(DATA, SYSTEM_DATA, &bufsize);
|
||||
@ -940,12 +940,12 @@ int space_load(void) {
|
||||
ERR("Malformed "SYSTEM_DATA" file: missing root element '"XML_SYSTEM_ID"'");
|
||||
return -1;
|
||||
}
|
||||
node = node->xmlChildrenNode; // First system node.
|
||||
node = node->xmlChildrenNode; /* First system node. */
|
||||
if(node == NULL) {
|
||||
ERR("Malformed "SYSTEM_DATA" file: does not contain elements");
|
||||
return -1;
|
||||
}
|
||||
// Fist pass - Load all the star systems_stack.
|
||||
/* Fist pass - Load all the star systems_stack. */
|
||||
do {
|
||||
if(xml_isNode(node, XML_SYSTEM_TAG)) {
|
||||
tmp = system_parse(node);
|
||||
@ -955,14 +955,14 @@ int space_load(void) {
|
||||
}
|
||||
} while(xml_nextNode(node));
|
||||
|
||||
// Second pass - Load all the jump routes.
|
||||
/* Second pass - Load all the jump routes. */
|
||||
node = doc->xmlChildrenNode->xmlChildrenNode;
|
||||
do {
|
||||
if(xml_isNode(node, XML_SYSTEM_TAG))
|
||||
system_parseJumps(node); // Automatically load the jumps into the system.
|
||||
system_parseJumps(node); /* Automatically load the jumps into the system. */
|
||||
} while(xml_nextNode(node));
|
||||
|
||||
// Cleanup.
|
||||
/* Cleanup. */
|
||||
xmlFreeDoc(doc);
|
||||
free(buf);
|
||||
xmlCleanupParser();
|
||||
@ -974,29 +974,29 @@ int space_load(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Render the system. -- Just playing god now.
|
||||
/* Render the system. -- Just playing god now. */
|
||||
void space_render(double dt) {
|
||||
int i;
|
||||
unsigned int t, timer;
|
||||
double x, y, m, b;
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix(); // Translation matrix.
|
||||
glPushMatrix(); /* Translation matrix. */
|
||||
glTranslated(-(double)SCREEN_W/2., -(double)SCREEN_H/2., 0);
|
||||
|
||||
t = SDL_GetTicks();
|
||||
if(!player_isFlag(PLAYER_DESTROYED) && !player_isFlag(PLAYER_CREATING) &&
|
||||
pilot_isFlag(player, PILOT_HYPERSPACE) && // Hyperspace fancy effect.
|
||||
pilot_isFlag(player, PILOT_HYPERSPACE) && /* Hyperspace fancy effect. */
|
||||
!paused && (player->ptimer-HYPERSPACE_STARS_BLUR < t)) {
|
||||
|
||||
timer = player->ptimer - HYPERSPACE_STARS_BLUR;
|
||||
|
||||
// Fancy hyperspace effects.
|
||||
/* Fancy hyperspace effects. */
|
||||
glShadeModel(GL_SMOOTH);
|
||||
|
||||
glBegin(GL_LINES);
|
||||
|
||||
// Lines will be based on velocity.
|
||||
/* Lines will be based on velocity. */
|
||||
m = HYPERSPACE_STARS_LENGTH * (double)(t-timer) / (HYPERSPACE_STARS_BLUR);
|
||||
x = m*cos(VANGLE(player->solid->vel)+M_PI);
|
||||
y = m*sin(VANGLE(player->solid->vel)+M_PI);
|
||||
@ -1012,28 +1012,28 @@ void space_render(double dt) {
|
||||
glShadeModel(GL_FLAT);
|
||||
|
||||
} else {
|
||||
glBegin(GL_POINTS); // Normal rendering.
|
||||
glBegin(GL_POINTS); /* Normal rendering. */
|
||||
if(!paused && !player_isFlag(PLAYER_DESTROYED) &&
|
||||
!player_isFlag(PLAYER_CREATING)) { // Update position.
|
||||
!player_isFlag(PLAYER_CREATING)) { /* Update position. */
|
||||
for(i = 0; i < nstars; i++) {
|
||||
b = 13.-10.*stars[i].brightness;
|
||||
stars[i].x -= player->solid->vel.x/b*dt;
|
||||
stars[i].y -= player->solid->vel.y/b*dt;
|
||||
|
||||
// Check for boundaries.
|
||||
/* Check for boundaries. */
|
||||
if(stars[i].x > SCREEN_W + STAR_BUF) stars[i].x = -STAR_BUF;
|
||||
else if(stars[i].x < -STAR_BUF) stars[i].x = SCREEN_W + STAR_BUF;
|
||||
if(stars[i].y > SCREEN_H + STAR_BUF) stars[i].y = -STAR_BUF;
|
||||
else if(stars[i].y < -STAR_BUF) stars[i].y = SCREEN_H + STAR_BUF;
|
||||
|
||||
// Render.
|
||||
/* Render. */
|
||||
if((stars[i].x < SCREEN_W) && (stars[i].x > 0) &&
|
||||
(stars[i].y < SCREEN_H) && (stars[i].y > 0)) {
|
||||
glColor4d(1., 1., 1., stars[i].brightness);
|
||||
glVertex2d(stars[i].x, stars[i].y);
|
||||
}
|
||||
}
|
||||
} else { // Just render.
|
||||
} else { /* Just render. */
|
||||
for(i = 0; i < nstars; i++) {
|
||||
if((stars[i].x < SCREEN_W) && (stars[i].x > 0) &&
|
||||
(stars[i].y < SCREEN_H) && (stars[i].y > 0)) {
|
||||
@ -1042,12 +1042,12 @@ void space_render(double dt) {
|
||||
}
|
||||
}
|
||||
}
|
||||
glEnd(); // GL_POINTS
|
||||
glEnd(); /* GL_POINTS */
|
||||
}
|
||||
glPopMatrix(); // Translation matrix.
|
||||
glPopMatrix(); /* Translation matrix. */
|
||||
}
|
||||
|
||||
// Render the planets.
|
||||
/* Render the planets. */
|
||||
void planets_render(void) {
|
||||
if(cur_system == NULL) return;
|
||||
|
||||
@ -1057,13 +1057,13 @@ void planets_render(void) {
|
||||
cur_system->planets[i].pos.x, cur_system->planets[i].pos.y, 0, 0, NULL);
|
||||
}
|
||||
|
||||
// Clean up the system.
|
||||
/* Clean up the system. */
|
||||
void space_exit(void) {
|
||||
int i,j;
|
||||
|
||||
// Free the names.
|
||||
//if(planetname_stack) free(planetname_stack);
|
||||
//if(systemname_stack) free(systemname_stack);
|
||||
/* Free the names. */
|
||||
/*if(planetname_stack) free(planetname_stack); */
|
||||
/*if(systemname_stack) free(systemname_stack); */
|
||||
if(planetname_stack) {
|
||||
free(planetname_stack);
|
||||
planetname_stack = NULL;
|
||||
@ -1074,7 +1074,7 @@ void space_exit(void) {
|
||||
}
|
||||
spacename_nstack = 0;
|
||||
|
||||
// Free the systems.
|
||||
/* Free the systems. */
|
||||
for(i = 0; i < systems_nstack; i++) {
|
||||
free(systems_stack[i].name);
|
||||
if(systems_stack[i].fleets)
|
||||
@ -1082,7 +1082,7 @@ void space_exit(void) {
|
||||
if(systems_stack[i].jumps)
|
||||
free(systems_stack[i].jumps);
|
||||
|
||||
// Free some planets.
|
||||
/* Free some planets. */
|
||||
for(j = 0; j < systems_stack[i].nplanets; j++) {
|
||||
free(systems_stack[i].planets[j].name);
|
||||
if(systems_stack[i].planets[j].description)
|
||||
@ -1090,13 +1090,13 @@ void space_exit(void) {
|
||||
if(systems_stack[i].planets[j].bar_description)
|
||||
free(systems_stack[i].planets[j].bar_description);
|
||||
|
||||
// Graphics.
|
||||
/* Graphics. */
|
||||
if(systems_stack[i].planets[j].gfx_space)
|
||||
gl_freeTexture(systems_stack[i].planets[j].gfx_space);
|
||||
if(systems_stack[i].planets[j].gfx_exterior)
|
||||
gl_freeTexture(systems_stack[i].planets[j].gfx_exterior);
|
||||
|
||||
// Commodities.
|
||||
/* Commodities. */
|
||||
free(systems_stack[i].planets[j].commodities);
|
||||
}
|
||||
free(systems_stack[i].planets);
|
||||
@ -1105,7 +1105,7 @@ void space_exit(void) {
|
||||
systems_stack = NULL;
|
||||
systems_nstack = 0;
|
||||
|
||||
// Stars must be set free too.
|
||||
/* Stars must be set free too. */
|
||||
if(stars) free(stars);
|
||||
stars = NULL;
|
||||
nstars = 0;
|
||||
|
128
src/space.h
128
src/space.h
@ -9,110 +9,110 @@
|
||||
|
||||
#define PLANET_TECH_MAX 8
|
||||
|
||||
// Planet types. I didn't take them from Star Trek, I promise.
|
||||
/* Planet types. I didn't take them from Star Trek, I promise. */
|
||||
typedef enum PlanetClass_ {
|
||||
PLANET_CLASS_NULL = 0,
|
||||
PLANET_CLASS_A, // Geothermal.
|
||||
PLANET_CLASS_B, // Geomorteus.
|
||||
PLANET_CLASS_C, // Geoinactive.
|
||||
PLANET_CLASS_D, // Asteroid/Moon.
|
||||
PLANET_CLASS_E, // Geoplastic.
|
||||
PLANET_CLASS_F, // Geometallic.
|
||||
PLANET_CLASS_G, // GroCrystaline.
|
||||
PLANET_CLASS_H, // Desert.
|
||||
PLANET_CLASS_I, // Gas Supergiant.
|
||||
PLANET_CLASS_J, // Gas Giant.
|
||||
PLANET_CLASS_K, // Adaptable.
|
||||
PLANET_CLASS_L, // Marginal.
|
||||
PLANET_CLASS_M, // Terrestrial.
|
||||
PLANET_CLASS_N, // Reducing.
|
||||
PLANET_CLASS_O, // Pelagic.
|
||||
PLANET_CLASS_P, // Glaciated.
|
||||
PLANET_CLASS_Q, // Variable.
|
||||
PLANET_CLASS_R, // Rogue.
|
||||
PLANET_CLASS_S, // Ultragiant.
|
||||
PLANET_CLASS_T, // Ultragiant.
|
||||
PLANET_CLASS_X, // Demon.
|
||||
PLANET_CLASS_Y, // Demon.
|
||||
PLANET_CLASS_Z, // Demon.
|
||||
STATION_CLASS_A, // Civilian station.
|
||||
STATION_CLASS_B, // Military station.
|
||||
STATION_CLASS_C, // Interfactional station.
|
||||
STATION_CLASS_D, // Robotoc station.
|
||||
PLANET_CLASS_A, /* Geothermal. */
|
||||
PLANET_CLASS_B, /* Geomorteus. */
|
||||
PLANET_CLASS_C, /* Geoinactive. */
|
||||
PLANET_CLASS_D, /* Asteroid/Moon. */
|
||||
PLANET_CLASS_E, /* Geoplastic. */
|
||||
PLANET_CLASS_F, /* Geometallic. */
|
||||
PLANET_CLASS_G, /* GroCrystaline. */
|
||||
PLANET_CLASS_H, /* Desert. */
|
||||
PLANET_CLASS_I, /* Gas Supergiant. */
|
||||
PLANET_CLASS_J, /* Gas Giant. */
|
||||
PLANET_CLASS_K, /* Adaptable. */
|
||||
PLANET_CLASS_L, /* Marginal. */
|
||||
PLANET_CLASS_M, /* Terrestrial. */
|
||||
PLANET_CLASS_N, /* Reducing. */
|
||||
PLANET_CLASS_O, /* Pelagic. */
|
||||
PLANET_CLASS_P, /* Glaciated. */
|
||||
PLANET_CLASS_Q, /* Variable. */
|
||||
PLANET_CLASS_R, /* Rogue. */
|
||||
PLANET_CLASS_S, /* Ultragiant. */
|
||||
PLANET_CLASS_T, /* Ultragiant. */
|
||||
PLANET_CLASS_X, /* Demon. */
|
||||
PLANET_CLASS_Y, /* Demon. */
|
||||
PLANET_CLASS_Z, /* Demon. */
|
||||
STATION_CLASS_A, /* Civilian station. */
|
||||
STATION_CLASS_B, /* Military station. */
|
||||
STATION_CLASS_C, /* Interfactional station. */
|
||||
STATION_CLASS_D, /* Robotoc station. */
|
||||
} PlanetClass;
|
||||
|
||||
// Planet services.
|
||||
#define PLANET_SERVICE_LAND (1<<0) // Can we land?
|
||||
#define PLANET_SERVICE_BASIC (1<<1) // Refueling, spaceport bar, new.
|
||||
/* Planet services. */
|
||||
#define PLANET_SERVICE_LAND (1<<0) /* Can we land? */
|
||||
#define PLANET_SERVICE_BASIC (1<<1) /* Refueling, spaceport bar, new. */
|
||||
#define PLANET_SERVICE_COMMODITY (1<<2)
|
||||
#define PLANET_SERVICE_OUTFITS (1<<3)
|
||||
#define PLANET_SERVICE_SHIPYARD (1<<4)
|
||||
#define planet_hasService(p,s) ((p)->services & s)
|
||||
|
||||
typedef struct Planet_ {
|
||||
char* name; // Planet name
|
||||
Vec2 pos; // Position in star system.
|
||||
char* name; /* Planet name */
|
||||
Vec2 pos; /* Position in star system. */
|
||||
|
||||
PlanetClass class; // Planet type.
|
||||
int faction; // Planet faction.
|
||||
PlanetClass class; /* Planet type. */
|
||||
int faction; /* Planet faction. */
|
||||
|
||||
char* description; // Planet description.
|
||||
char* bar_description; // Spaceport bar description.
|
||||
unsigned int services; // Offered services.
|
||||
Commodity** commodities; // Commodities sold.
|
||||
int ncommodities; // Amount in stock.
|
||||
char* description; /* Planet description. */
|
||||
char* bar_description; /* Spaceport bar description. */
|
||||
unsigned int services; /* Offered services. */
|
||||
Commodity** commodities; /* Commodities sold. */
|
||||
int ncommodities; /* Amount in stock. */
|
||||
|
||||
// tech[0] stores global tech level (everything that and below) while
|
||||
// tech[1-PLANET_TECH_MAX] stores the unique tech levels.
|
||||
/* tech[0] stores global tech level (everything that and below) while */
|
||||
/* tech[1-PLANET_TECH_MAX] stores the unique tech levels. */
|
||||
int tech[PLANET_TECH_MAX];
|
||||
|
||||
glTexture* gfx_space; // Graphics in space.
|
||||
glTexture* gfx_exterior; // Graphics in the exterior.
|
||||
glTexture* gfx_space; /* Graphics in space. */
|
||||
glTexture* gfx_exterior; /* Graphics in the exterior. */
|
||||
} Planet;
|
||||
|
||||
// Star systems.
|
||||
/* Star systems. */
|
||||
typedef struct SystemFleet_ {
|
||||
Fleet* fleet; // Fleet to appear.
|
||||
int chance; // Chance of fleet appearing in the system.
|
||||
Fleet* fleet; /* Fleet to appear. */
|
||||
int chance; /* Chance of fleet appearing in the system. */
|
||||
} SystemFleet;
|
||||
|
||||
typedef struct StarSystem_ {
|
||||
char* name; // Star system identifier.
|
||||
Vec2 pos; // Position.
|
||||
int stars, asteroids; // Un numero!
|
||||
double interference; // Un uh.. Percentage.
|
||||
char* name; /* Star system identifier. */
|
||||
Vec2 pos; /* Position. */
|
||||
int stars, asteroids; /* Un numero! */
|
||||
double interference; /* Un uh.. Percentage. */
|
||||
|
||||
int faction; // Overall faction.
|
||||
int faction; /* Overall faction. */
|
||||
|
||||
Planet* planets; // Planets.
|
||||
int nplanets; // Total number of planets.
|
||||
Planet* planets; /* Planets. */
|
||||
int nplanets; /* Total number of planets. */
|
||||
|
||||
SystemFleet* fleets; // Fleets that can appear in the current system.
|
||||
int nfleets; // Total number of fleets.
|
||||
SystemFleet* fleets; /* Fleets that can appear in the current system. */
|
||||
int nfleets; /* Total number of fleets. */
|
||||
|
||||
int* jumps; // Adjacent star system index number.
|
||||
int njumps; // Number of adjacent jumps.
|
||||
int* jumps; /* Adjacent star system index number. */
|
||||
int njumps; /* Number of adjacent jumps. */
|
||||
} StarSystem;
|
||||
|
||||
extern StarSystem* cur_system; // Current star system.
|
||||
extern StarSystem* cur_system; /* Current star system. */
|
||||
|
||||
// Load/Exit.
|
||||
/* Load/Exit. */
|
||||
void space_init(const char* sysname);
|
||||
int space_load(void);
|
||||
void space_exit(void);
|
||||
|
||||
// Planet stuff.
|
||||
/* Planet stuff. */
|
||||
char* planet_getSystem(char* planetname);
|
||||
Planet* planet_get(char* planetname);
|
||||
|
||||
// Render.
|
||||
/* Render. */
|
||||
void space_render(double dt);
|
||||
void planets_render(void);
|
||||
|
||||
// Update.
|
||||
/* Update. */
|
||||
void space_update(const double dt);
|
||||
|
||||
// Misc.
|
||||
/* Misc. */
|
||||
StarSystem** system_getJumpPath(int* njumps, char* sysstart, char* sysend);
|
||||
int space_canHyperspace(Pilot* p);
|
||||
int space_hyperspace(Pilot* p);
|
||||
|
62
src/spfx.c
62
src/spfx.c
@ -9,38 +9,38 @@
|
||||
#include "rng.h"
|
||||
#include "spfx.h"
|
||||
|
||||
#define SPFX_GFX "../gfx/spfx/" // Graphics location.
|
||||
#define SPFX_CHUNK 32 // Chunk to allocate when needed.
|
||||
#define SPFX_GFX "../gfx/spfx/" /* Graphics location. */
|
||||
#define SPFX_CHUNK 32 /* Chunk to allocate when needed. */
|
||||
|
||||
// Special hardcoded effects..
|
||||
/* Special hardcoded effects.. */
|
||||
|
||||
// Shake, AKA RUMBLE!
|
||||
/* Shake, AKA RUMBLE! */
|
||||
static double shake_rad = 0.;
|
||||
static Vec2 shake_pos = { .x = 0., .y = 0. };
|
||||
static Vec2 shake_vel = { .x = 0., .y = 0. };
|
||||
static int shake_off = 1;
|
||||
|
||||
// Generic SPFX template.
|
||||
/* Generic SPFX template. */
|
||||
typedef struct SPFX_Base_ {
|
||||
char* name;
|
||||
|
||||
int anim; // Total duration in ms.
|
||||
glTexture* gfx; // Will use each sprite as a frame.
|
||||
int anim; /* Total duration in ms. */
|
||||
glTexture* gfx; /* Will use each sprite as a frame. */
|
||||
} SPFX_Base;
|
||||
|
||||
static SPFX_Base* spfx_effects = NULL;
|
||||
static int spfx_neffects = 0;
|
||||
|
||||
typedef struct SPFX_ {
|
||||
Vec2 pos, vel; // They don't accelerate.
|
||||
Vec2 pos, vel; /* They don't accelerate. */
|
||||
|
||||
int lastframe; // Need when pausing.
|
||||
int effect; // Actual effect.
|
||||
unsigned int t; // Start.
|
||||
int lastframe; /* Need when pausing. */
|
||||
int effect; /* Actual effect. */
|
||||
unsigned int t; /* Start. */
|
||||
} SPFX;
|
||||
|
||||
// Front stack is for effects on player.
|
||||
// Back is for everything else.
|
||||
/* Front stack is for effects on player. */
|
||||
/* Back is for everything else. */
|
||||
static SPFX* spfx_stack_front = NULL;
|
||||
static int spfx_nstack_front = 0;
|
||||
static int spfx_mstack_front = 0;
|
||||
@ -56,7 +56,7 @@ static void spfx_pause_layer(SPFX* layer, int nlayer);
|
||||
static void spfx_unpause_layer(SPFX* layer, int nlayer);
|
||||
static void spfx_delay_layer(SPFX* layer, int nlayer, unsigned int delay);
|
||||
|
||||
// Load the SPFX_Base.
|
||||
/* Load the SPFX_Base. */
|
||||
static int spfx_base_load(char* name, int anim, char* gfx, int sx, int sy) {
|
||||
SPFX_Base* cur;
|
||||
char buf[PATH_MAX];
|
||||
@ -86,7 +86,7 @@ int spfx_get(char* name) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Load/Unload.
|
||||
/* Load/Unload. */
|
||||
int spfx_load(void) {
|
||||
spfx_base_load("ExpS", 400, "exps.png", 6, 5);
|
||||
spfx_base_load("ExpM", 450, "expm.png", 6, 5);
|
||||
@ -97,7 +97,7 @@ int spfx_load(void) {
|
||||
void spfx_free(void) {
|
||||
int i;
|
||||
|
||||
// Get rid of all the particles and free the stacks.
|
||||
/* Get rid of all the particles and free the stacks. */
|
||||
spfx_clear();
|
||||
if(spfx_stack_front) free(spfx_stack_front);
|
||||
spfx_stack_front = NULL;
|
||||
@ -120,9 +120,9 @@ void spfx_add(int effect,
|
||||
SPFX* cur_spfx;
|
||||
|
||||
if(layer == SPFX_LAYER_FRONT) {
|
||||
// Front layer.
|
||||
/* Front layer. */
|
||||
if(spfx_mstack_front < spfx_nstack_front+1) {
|
||||
// We need more memory.
|
||||
/* We need more memory. */
|
||||
spfx_mstack_front += SPFX_CHUNK;
|
||||
spfx_stack_front = realloc(spfx_stack_front, spfx_mstack_front*sizeof(SPFX));
|
||||
}
|
||||
@ -130,9 +130,9 @@ void spfx_add(int effect,
|
||||
spfx_nstack_front++;
|
||||
}
|
||||
else if(layer == SPFX_LAYER_BACK) {
|
||||
// Back layer.
|
||||
/* Back layer. */
|
||||
if(spfx_mstack_back < spfx_nstack_back+1) {
|
||||
// Need more memory.
|
||||
/* Need more memory. */
|
||||
spfx_mstack_back += SPFX_CHUNK;
|
||||
spfx_stack_back = realloc(spfx_stack_back, spfx_mstack_back*sizeof(SPFX));
|
||||
}
|
||||
@ -170,35 +170,35 @@ static void spfx_update_layer(SPFX* layer, int* nlayer, const double dt) {
|
||||
unsigned int t = SDL_GetTicks();
|
||||
|
||||
for(i = 0; i < *nlayer; i++) {
|
||||
// Time to die!!!
|
||||
/* Time to die!!! */
|
||||
if(t > (layer[i].t + spfx_effects[layer[i].effect].anim)) {
|
||||
spfx_destroy(layer, nlayer, i);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
// Mkay. Update it now.
|
||||
/* Mkay. Update it now. */
|
||||
vect_cadd(&layer[i].pos, dt*VX(layer[i].vel), dt*VY(layer[i].vel));
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare the rendering for special affects.
|
||||
/* Prepare the rendering for special affects. */
|
||||
void spfx_start(double dt) {
|
||||
GLdouble bx, by, x, y;
|
||||
double inc;
|
||||
|
||||
if(shake_off == 1) return; // Save the cycles.
|
||||
if(shake_off == 1) return; /* Save the cycles. */
|
||||
bx = SCREEN_W / 2;
|
||||
by = SCREEN_H / 2;
|
||||
|
||||
if(!paused) {
|
||||
inc = dt*100000.;
|
||||
|
||||
// Calculate new position.
|
||||
/* Calculate new position. */
|
||||
if(shake_rad > 0.01) {
|
||||
vect_cadd(&shake_pos, shake_vel.x * inc, shake_vel.y * inc);
|
||||
|
||||
if(VMOD(shake_pos) > shake_rad) {
|
||||
// Change direction.
|
||||
/* Change direction. */
|
||||
vect_pset(&shake_pos, shake_rad, VANGLE(shake_pos));
|
||||
vect_pset(&shake_vel, shake_rad,
|
||||
-VANGLE(shake_pos) + (RNGF()-0.5) * M_PI);
|
||||
@ -220,7 +220,7 @@ void spfx_start(double dt) {
|
||||
glOrtho(-bx+x, bx+x, -by+y, by+y, -1., 1.);
|
||||
}
|
||||
|
||||
// Add ruuumble!!
|
||||
/* Add ruuumble!! */
|
||||
void spfx_shake(double mod) {
|
||||
shake_rad += mod;
|
||||
if(shake_rad > SHAKE_MAX) shake_rad = SHAKE_MAX;
|
||||
@ -231,7 +231,7 @@ void spfx_shake(double mod) {
|
||||
|
||||
void spfx_cinematic(void) {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix(); // Translation matrix.
|
||||
glPushMatrix(); /* Translation matrix. */
|
||||
glTranslated(-(double)SCREEN_W/2., -(double)SCREEN_H/2., 0);
|
||||
|
||||
COLOUR(cBlack);
|
||||
@ -246,7 +246,7 @@ void spfx_cinematic(void) {
|
||||
glVertex2d(0., SCREEN_H*0.8);
|
||||
glEnd();
|
||||
|
||||
glPopMatrix(); // Translation matrix.
|
||||
glPopMatrix(); /* Translation matrix. */
|
||||
}
|
||||
|
||||
void spfx_render(const int layer) {
|
||||
@ -256,7 +256,7 @@ void spfx_render(const int layer) {
|
||||
int sx, sy;
|
||||
unsigned int t = SDL_GetTicks();
|
||||
|
||||
// Get the appropriate layer.
|
||||
/* Get the appropriate layer. */
|
||||
switch(layer) {
|
||||
case SPFX_LAYER_FRONT:
|
||||
spfx_stack = spfx_stack_front;
|
||||
@ -273,7 +273,7 @@ void spfx_render(const int layer) {
|
||||
sx = (int)effect->gfx->sx;
|
||||
sy = (int)effect->gfx->sy;
|
||||
|
||||
if(!paused) // Don't calculate frame if paused.
|
||||
if(!paused) /* Don't calculate frame if paused. */
|
||||
spfx_stack[i].lastframe = sx * sy
|
||||
* MIN(((double)(t - spfx_stack[i].t)/(double)effect->anim), 1.);
|
||||
|
||||
|
16
src/spfx.h
16
src/spfx.h
@ -5,33 +5,33 @@
|
||||
#define SPFX_LAYER_FRONT 0
|
||||
#define SPFX_LAYER_BACK 1
|
||||
|
||||
#define SHAKE_DECAY 50. // Decay parameter.
|
||||
#define SHAKE_MAX 50.*SCREEN_W*SCREEN_H/1024./768. // Max parameter.
|
||||
#define SHAKE_DECAY 50. /* Decay parameter. */
|
||||
#define SHAKE_MAX 50.*SCREEN_W*SCREEN_H/1024./768. /* Max parameter. */
|
||||
|
||||
// Stack manipulation.
|
||||
/* Stack manipulation. */
|
||||
int spfx_get(char* name);
|
||||
void spfx_add(const int effect,
|
||||
const double px, const double py,
|
||||
const double vx, const double vy,
|
||||
const int layer);
|
||||
|
||||
// Stack mass manipulation functions.
|
||||
/* Stack mass manipulation functions. */
|
||||
void spfx_update(const double dt);
|
||||
void spfx_render(const int layer);
|
||||
void spfx_clear(void);
|
||||
|
||||
// Get ready to rumble!
|
||||
/* Get ready to rumble! */
|
||||
void spfx_start(double dt);
|
||||
void spfx_shake(double mod);
|
||||
|
||||
// Other effects.
|
||||
/* Other effects. */
|
||||
void spfx_cinematic(void);
|
||||
|
||||
// Load/free.
|
||||
/* Load/free. */
|
||||
int spfx_load(void);
|
||||
void spfx_free(void);
|
||||
|
||||
// Pause/Unpause routines.
|
||||
/* Pause/Unpause routines. */
|
||||
void spfx_pause(void);
|
||||
void spfx_unpause(void);
|
||||
void spfx_delay(unsigned int delay);
|
||||
|
450
src/toolkit.c
450
src/toolkit.c
File diff suppressed because it is too large
Load Diff
@ -5,7 +5,7 @@
|
||||
|
||||
extern int toolkit;
|
||||
|
||||
// Creation.
|
||||
/* Creation. */
|
||||
unsigned int window_create(char* name, const int x, const int y,
|
||||
const int w, const int h);
|
||||
|
||||
@ -21,19 +21,19 @@ void window_addImage(const unsigned int wid, const int x, const int y,
|
||||
char* name, glTexture* image, int border);
|
||||
|
||||
void window_addList(const unsigned int wid,
|
||||
const int x, const int y, // Position.
|
||||
const int w, const int h, // Size.
|
||||
const int x, const int y, /* Position. */
|
||||
const int w, const int h, /* Size. */
|
||||
char* name, char** items, int nitems, int defitem,
|
||||
void(*call)(char*));
|
||||
|
||||
void window_addRect(const unsigned int wid,
|
||||
const int x, const int y, // Position.
|
||||
const int w, const int h, // size.
|
||||
char* name, glColour* colour, int border); // Properties.
|
||||
const int x, const int y, /* Position. */
|
||||
const int w, const int h, /* size. */
|
||||
char* name, glColour* colour, int border); /* Properties. */
|
||||
|
||||
void window_addCust(const unsigned int wid,
|
||||
const int x, const int y, // Position.
|
||||
const int w, const int h, // Size.
|
||||
const int x, const int y, /* Position. */
|
||||
const int w, const int h, /* Size. */
|
||||
char* name, const int border,
|
||||
void(*render) (double x, double y, double w, double h),
|
||||
void(*mouse) (SDL_Event* event, double x, double y));
|
||||
@ -43,27 +43,27 @@ void window_addInput(const unsigned int wid,
|
||||
const int w, const int h,
|
||||
char* name, const int max, const int oneline);
|
||||
|
||||
// Popups and alerts.
|
||||
/* Popups and alerts. */
|
||||
|
||||
// Does not pause execution.
|
||||
/* Does not pause execution. */
|
||||
void dialogue_alert(const char* fmt, ...);
|
||||
void dialogue_msg(char* caption, const char* fmt, ...);
|
||||
// Yes = 1, No = 0.
|
||||
/* Yes = 1, No = 0. */
|
||||
int dialogue_YesNo(char* caption, const char* fmt, ...);
|
||||
char* dialogue_input(char* title, int min, int max, const char* fmt, ...);
|
||||
|
||||
// Modification.
|
||||
/* Modification. */
|
||||
void window_setFptr(const unsigned int wid, void(*fptr)(char*));
|
||||
// Text.
|
||||
/* Text. */
|
||||
void window_modifyText(const unsigned int wid, char* name, char* newstring);
|
||||
// Button.
|
||||
/* Button. */
|
||||
void window_disableButton(const unsigned int wid, char* name);
|
||||
void window_enableButton(const unsigned int wid, char* name);
|
||||
// Image.
|
||||
/* Image. */
|
||||
void window_modifyImage(const unsigned int wid, char* name, glTexture* image);
|
||||
void window_imgColour(const unsigned int wid, char* name, glColour* colour);
|
||||
|
||||
// Get the window by name.
|
||||
/* Get the window by name. */
|
||||
int window_exists(const char* wdwname);
|
||||
unsigned int window_get(const char* wdwname);
|
||||
char* toolkit_getList(const unsigned int wid, char* name);
|
||||
@ -71,18 +71,18 @@ int toolkit_getListPos(const unsigned int wid, char* name);
|
||||
glTexture* window_getImage(const unsigned int wid, char* name);
|
||||
char* window_getInput(const unsigned int wid, char* name);
|
||||
|
||||
// Destroy window.
|
||||
/* Destroy window. */
|
||||
void window_destroy(const unsigned int wid);
|
||||
void window_destroyWidget(unsigned wid, const char* wgtname);
|
||||
|
||||
// Render.
|
||||
/* Render. */
|
||||
void toolkit_render(void);
|
||||
|
||||
// Input.
|
||||
/* Input. */
|
||||
int toolkit_input(SDL_Event* event);
|
||||
void toolkit_update(void);
|
||||
|
||||
// Init/Exit.
|
||||
/* Init/Exit. */
|
||||
int toolkit_init(void);
|
||||
void toolkit_exit(void);
|
||||
|
||||
|
142
src/weapon.c
142
src/weapon.c
@ -15,50 +15,50 @@
|
||||
|
||||
#define weapon_isSmart(w) (w->think)
|
||||
|
||||
#define VOICE_PRIORITY_BOLT 10 // Default.
|
||||
#define VOICE_PRIORITY_AMMO 8 // Higher.
|
||||
#define VOICE_PRIORITY_BEAM 6 // Even higher.
|
||||
#define VOICE_PRIORITY_BOLT 10 /* Default. */
|
||||
#define VOICE_PRIORITY_AMMO 8 /* Higher. */
|
||||
#define VOICE_PRIORITY_BEAM 6 /* Even higher. */
|
||||
|
||||
#define WEAPON_CHUNK 32
|
||||
|
||||
// Some stuff from pilot.
|
||||
/* Some stuff from pilot. */
|
||||
extern Pilot** pilot_stack;
|
||||
extern int pilots;
|
||||
|
||||
// Player stuff.
|
||||
/* Player stuff. */
|
||||
extern unsigned int player_target;
|
||||
|
||||
// Ai stuff.
|
||||
/* Ai stuff. */
|
||||
extern void ai_attacked(Pilot* attacked, const unsigned int attacker);
|
||||
|
||||
typedef struct Weapon_ {
|
||||
Solid* solid; // Actually has its own solid. :D
|
||||
Solid* solid; /* Actually has its own solid. :D */
|
||||
|
||||
unsigned int parent; // The pilot that just shot at you!
|
||||
unsigned int target; // Target to hit. Only used by seeking stuff.
|
||||
const Outfit* outfit; // Related outfit that fired.
|
||||
unsigned int timer; // Mainly used to see when the weapon was fired.
|
||||
unsigned int parent; /* The pilot that just shot at you! */
|
||||
unsigned int target; /* Target to hit. Only used by seeking stuff. */
|
||||
const Outfit* outfit; /* Related outfit that fired. */
|
||||
unsigned int timer; /* Mainly used to see when the weapon was fired. */
|
||||
|
||||
alVoice* voice; // Virtual voise.
|
||||
alVoice* voice; /* Virtual voise. */
|
||||
|
||||
// Update position and render.
|
||||
void(*update)(struct Weapon_*, const double, WeaponLayer); // Position update and render.
|
||||
void(*think)(struct Weapon_*, const double); // Some missiles need to be inteligent.a
|
||||
/* Update position and render. */
|
||||
void(*update)(struct Weapon_*, const double, WeaponLayer); /* Position update and render. */
|
||||
void(*think)(struct Weapon_*, const double); /* Some missiles need to be inteligent.a */
|
||||
|
||||
double pid_last;
|
||||
double pid_int;
|
||||
} Weapon;
|
||||
|
||||
// Behind Pilot layer.
|
||||
static Weapon** wbackLayer = NULL; // Behind pilots.
|
||||
static int nwbackLayer = 0; // Number of elements.
|
||||
static int mwbackLayer = 0; // Allocated memory size.
|
||||
// Behind player layer.
|
||||
static Weapon** wfrontLayer = NULL; // Behind pilots.
|
||||
static int nwfrontLayer = 0; // Number of elements.
|
||||
static int mwfrontLayer = 0; // Allocated memory size.
|
||||
/* Behind Pilot layer. */
|
||||
static Weapon** wbackLayer = NULL; /* Behind pilots. */
|
||||
static int nwbackLayer = 0; /* Number of elements. */
|
||||
static int mwbackLayer = 0; /* Allocated memory size. */
|
||||
/* Behind player layer. */
|
||||
static Weapon** wfrontLayer = NULL; /* Behind pilots. */
|
||||
static int nwfrontLayer = 0; /* Number of elements. */
|
||||
static int mwfrontLayer = 0; /* Allocated memory size. */
|
||||
|
||||
// Static.
|
||||
/* Static. */
|
||||
static Weapon* weapon_create(const Outfit* outfit, const double dir,
|
||||
const Vec2* pos, const Vec2* vel,
|
||||
const unsigned int parent,
|
||||
@ -70,14 +70,14 @@ static void weapon_update(Weapon* w, const double dt, WeaponLayer layer);
|
||||
static void weapon_hit(Weapon* w, Pilot* p, WeaponLayer layer);
|
||||
static void weapon_destroy(Weapon* w, WeaponLayer layer);
|
||||
static void weapon_free(Weapon* w);
|
||||
// Think.
|
||||
/* Think. */
|
||||
static void think_seeker(Weapon* w, const double dt);
|
||||
static void think_smart(Weapon* w, const double dt);
|
||||
// Extern.
|
||||
/* Extern. */
|
||||
void weapon_minimap(const double res, const double w,
|
||||
const double h, const RadarShape shape);
|
||||
|
||||
// Draw the minimap weapons (player.c).
|
||||
/* Draw the minimap weapons (player.c). */
|
||||
#define PIXEL(x,y) if((shape == RADAR_RECT && ABS(x) < w/2. && ABS(y)<h/2.) || \
|
||||
(shape == RADAR_CIRCLE && (((x)*(x)+(y)*(y))<rc))) glVertex2i((x),(y))
|
||||
void weapon_minimap(const double res, const double w,
|
||||
@ -101,7 +101,7 @@ void weapon_minimap(const double res, const double w,
|
||||
}
|
||||
#undef PIXEL
|
||||
|
||||
// Pause/Unpause the weapon system.
|
||||
/* Pause/Unpause the weapon system. */
|
||||
void weapons_pause(void) {
|
||||
int i;
|
||||
unsigned int t = SDL_GetTicks();
|
||||
@ -129,10 +129,10 @@ void weapons_delay(unsigned int delay) {
|
||||
wfrontLayer[i]->timer += delay;
|
||||
}
|
||||
|
||||
// Seeker brain, You get what you pay for. :)
|
||||
/* Seeker brain, You get what you pay for. :) */
|
||||
static void think_seeker(Weapon* w, const double dt) {
|
||||
double diff;
|
||||
if(w->target == w->parent) return; // HEY! Self harm is not allowed.
|
||||
if(w->target == w->parent) return; /* HEY! Self harm is not allowed. */
|
||||
|
||||
Pilot* p = pilot_get(w->target);
|
||||
if(p == NULL) {
|
||||
@ -140,11 +140,11 @@ static void think_seeker(Weapon* w, const double dt) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ammo isn't locked on yet..
|
||||
/* Ammo isn't locked on yet.. */
|
||||
if(SDL_GetTicks() > (w->timer + w->outfit->u.amm.lockon)) {
|
||||
diff = angle_diff(w->solid->dir, vect_angle(&w->solid->pos, &p->solid->pos));
|
||||
w->solid->dir_vel = 10 * diff * w->outfit->u.amm.turn;
|
||||
// Face the target.
|
||||
/* Face the target. */
|
||||
if(w->solid->dir_vel > w->outfit->u.amm.turn)
|
||||
w->solid->dir_vel = w->outfit->u.amm.turn;
|
||||
else if(w->solid->dir_vel < -w->outfit->u.amm.turn)
|
||||
@ -156,16 +156,16 @@ static void think_seeker(Weapon* w, const double dt) {
|
||||
limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt);
|
||||
}
|
||||
|
||||
// ========================================================
|
||||
// Smart seeker brain. Much better at homing.
|
||||
// ========================================================
|
||||
/* ======================================================== */
|
||||
/* Smart seeker brain. Much better at homing. */
|
||||
/* ======================================================== */
|
||||
static void think_smart(Weapon* w, const double dt) {
|
||||
Vec2 sv, tv;
|
||||
double t;
|
||||
|
||||
if(w->target == w->parent) return; // No self shooting here.
|
||||
if(w->target == w->parent) return; /* No self shooting here. */
|
||||
|
||||
Pilot* p = pilot_get(w->target); // No null pilots..
|
||||
Pilot* p = pilot_get(w->target); /* No null pilots.. */
|
||||
|
||||
if(p == NULL) {
|
||||
limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt);
|
||||
@ -181,7 +181,7 @@ static void think_smart(Weapon* w, const double dt) {
|
||||
|
||||
t = -angle_diff(w->solid->dir, vect_angle(&tv, &sv));
|
||||
|
||||
w->solid->dir_vel = t * w->outfit->u.amm.turn; // Face the target.
|
||||
w->solid->dir_vel = t * w->outfit->u.amm.turn; /* Face the target. */
|
||||
|
||||
if(w->solid->dir_vel > w->outfit->u.amm.turn)
|
||||
w->solid->dir_vel = w->outfit->u.amm.turn;
|
||||
@ -195,13 +195,13 @@ static void think_smart(Weapon* w, const double dt) {
|
||||
|
||||
}
|
||||
|
||||
// Update all the weapon layers.
|
||||
/* Update all the weapon layers. */
|
||||
void weapons_update(const double dt) {
|
||||
weapons_updateLayer(dt, WEAPON_LAYER_BG);
|
||||
weapons_updateLayer(dt, WEAPON_LAYER_FG);
|
||||
}
|
||||
|
||||
// Update all weapons in the layer.
|
||||
/* Update all weapons in the layer. */
|
||||
static void weapons_updateLayer(const double dt, const WeaponLayer layer) {
|
||||
Weapon** wlayer;
|
||||
int* nlayer;
|
||||
@ -221,7 +221,7 @@ static void weapons_updateLayer(const double dt, const WeaponLayer layer) {
|
||||
for(i = 0; i < (*nlayer); i++) {
|
||||
w = wlayer[i];
|
||||
switch(wlayer[i]->outfit->type) {
|
||||
// Most missiles behave the same.
|
||||
/* Most missiles behave the same. */
|
||||
case OUTFIT_TYPE_MISSILE_SEEK_AMMO:
|
||||
case OUTFIT_TYPE_MISSILE_SEEK_SMART_AMMO:
|
||||
case OUTFIT_TYPE_MISSILE_SWARM_AMMO:
|
||||
@ -233,7 +233,7 @@ static void weapons_updateLayer(const double dt, const WeaponLayer layer) {
|
||||
}
|
||||
break;
|
||||
case OUTFIT_TYPE_BOLT:
|
||||
// Check see if it exceeds distance.
|
||||
/* Check see if it exceeds distance. */
|
||||
case OUTFIT_TYPE_TURRET_BOLT:
|
||||
if(SDL_GetTicks() > wlayer[i]->timer) {
|
||||
weapon_destroy(wlayer[i],layer);
|
||||
@ -244,12 +244,12 @@ static void weapons_updateLayer(const double dt, const WeaponLayer layer) {
|
||||
break;
|
||||
}
|
||||
weapon_update(wlayer[i], dt, layer);
|
||||
// If the weapon has been deleted we are going to have to hold back one.
|
||||
/* If the weapon has been deleted we are going to have to hold back one. */
|
||||
if(w != wlayer[i]) i--;
|
||||
}
|
||||
}
|
||||
|
||||
// Render all the weapons.
|
||||
/* Render all the weapons. */
|
||||
void weapons_render(const WeaponLayer layer) {
|
||||
Weapon** wlayer;
|
||||
int* nlayer;
|
||||
@ -269,20 +269,20 @@ void weapons_render(const WeaponLayer layer) {
|
||||
weapon_render(wlayer[i]);
|
||||
}
|
||||
|
||||
// Render the weapons.
|
||||
/* Render the weapons. */
|
||||
static void weapon_render(const Weapon* w) {
|
||||
int sx, sy;
|
||||
glTexture* gfx;
|
||||
|
||||
gfx = outfit_gfx(w->outfit);
|
||||
|
||||
// Get the sprite corresponding to the direction facing.
|
||||
/* Get the sprite corresponding to the direction facing. */
|
||||
gl_getSpriteFromDir(&sx, &sy, gfx, w->solid->dir);
|
||||
|
||||
gl_blitSprite(gfx, w->solid->pos.x, w->solid->pos.y, sx, sy, NULL);
|
||||
}
|
||||
|
||||
// Update the weapon.
|
||||
/* Update the weapon. */
|
||||
static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) {
|
||||
int i, wsx, wsy, psx, psy;
|
||||
glTexture* gfx;
|
||||
@ -295,7 +295,7 @@ static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) {
|
||||
psx = pilot_stack[i]->tsx;
|
||||
psy = pilot_stack[i]->tsy;
|
||||
|
||||
if(w->parent == pilot_stack[i]->id) continue; // Hey! That's you.
|
||||
if(w->parent == pilot_stack[i]->id) continue; /* Hey! That's you. */
|
||||
|
||||
if((weapon_isSmart(w)) && (pilot_stack[i]->id == w->target) &&
|
||||
CollideSprite(gfx, wsx, wsy, &w->solid->pos,
|
||||
@ -316,20 +316,20 @@ static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) {
|
||||
|
||||
(*w->solid->update)(w->solid, dt);
|
||||
|
||||
// Update the sound.
|
||||
/* Update the sound. */
|
||||
if(w->voice)
|
||||
voice_update(w->voice, w->solid->pos.x, w->solid->pos.y,
|
||||
w->solid->vel.x, w->solid->vel.y);
|
||||
}
|
||||
|
||||
// Good shot.
|
||||
/* Good shot. */
|
||||
static void weapon_hit(Weapon* w, Pilot* p, WeaponLayer layer) {
|
||||
// Someone should let the ai know it's been attacked.
|
||||
/* Someone should let the ai know it's been attacked. */
|
||||
if(!pilot_isPlayer(p)) {
|
||||
if((player_target == p->id) || (RNG(0,2) == 0)) {
|
||||
if((w->parent == PLAYER_ID) &&
|
||||
(!pilot_isFlag(p, PILOT_HOSTILE) || (RNG(0, 2) == 0))) {
|
||||
faction_modPlayer(p->faction, -1); // Slowly lower faction.
|
||||
faction_modPlayer(p->faction, -1); /* Slowly lower faction. */
|
||||
pilot_setFlag(p, PILOT_HOSTILE);
|
||||
}
|
||||
ai_attacked(p, w->parent);
|
||||
@ -342,29 +342,29 @@ static void weapon_hit(Weapon* w, Pilot* p, WeaponLayer layer) {
|
||||
VX(w->solid->pos), VY(w->solid->pos),
|
||||
VX(p->solid->vel), VY(p->solid->vel), SPFX_LAYER_FRONT);
|
||||
|
||||
// Let the ship know that is should take some kind of damage.
|
||||
/* Let the ship know that is should take some kind of damage. */
|
||||
pilot_hit(p, w->solid, w->parent,
|
||||
outfit_damageType(w->outfit), outfit_damage(w->outfit));
|
||||
// We don't need the weapon particle any longer.
|
||||
/* We don't need the weapon particle any longer. */
|
||||
weapon_destroy(w, layer);
|
||||
}
|
||||
|
||||
static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2* pos,
|
||||
const Vec2* vel, unsigned int parent, const unsigned int target) {
|
||||
Vec2 v;
|
||||
double mass = 1; // Presumer lasers have a mass of 1.
|
||||
double rdir = dir; // Real direction (accuracy).
|
||||
double mass = 1; /* Presumer lasers have a mass of 1. */
|
||||
double rdir = dir; /* Real direction (accuracy). */
|
||||
Weapon* w = MALLOC_L(Weapon);
|
||||
w->parent = parent; // Non-Changeable.
|
||||
w->target = target; // Non-Changeable.
|
||||
w->outfit = outfit; // Non-Changeable.
|
||||
w->parent = parent; /* Non-Changeable. */
|
||||
w->target = target; /* Non-Changeable. */
|
||||
w->outfit = outfit; /* Non-Changeable. */
|
||||
w->update = weapon_update;
|
||||
w->timer = SDL_GetTicks();
|
||||
w->think = NULL;
|
||||
|
||||
switch(outfit->type) {
|
||||
case OUTFIT_TYPE_BOLT:
|
||||
// Need accuracy and speed based on player. -- Another contribution from VLack.
|
||||
/* Need accuracy and speed based on player. -- Another contribution from VLack. */
|
||||
rdir += RNG(-outfit->u.blt.accuracy/2., outfit->u.blt.accuracy/2.)/180.*M_PI;
|
||||
if((rdir > 2.*M_PI) || (rdir < 0.)) rdir = fmod(rdir, 2.*M_PI);
|
||||
vectcpy(&v, vel);
|
||||
@ -378,7 +378,7 @@ static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2*
|
||||
case OUTFIT_TYPE_MISSILE_SEEK_AMMO:
|
||||
mass = w->outfit->mass;
|
||||
w->solid = solid_create(mass, dir, pos, vel);
|
||||
w->think = think_seeker; // Eeek!!!
|
||||
w->think = think_seeker; /* Eeek!!! */
|
||||
w->voice = sound_addVoice(VOICE_PRIORITY_AMMO,
|
||||
w->solid->pos.x, w->solid->pos.y,
|
||||
w->solid->vel.x, w->solid->vel.y, w->outfit->u.amm.sound, 0);
|
||||
@ -386,7 +386,7 @@ static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2*
|
||||
case OUTFIT_TYPE_MISSILE_SEEK_SMART_AMMO:
|
||||
mass = w->outfit->mass;
|
||||
w->solid = solid_create(mass, dir, pos, vel);
|
||||
w->think = think_smart; // Smartass.
|
||||
w->think = think_smart; /* Smartass. */
|
||||
w->voice = sound_addVoice(VOICE_PRIORITY_AMMO,
|
||||
w->solid->pos.x, w->solid->pos.y,
|
||||
w->solid->vel.x, w->solid->vel.y, w->outfit->u.amm.sound, 0);
|
||||
@ -406,7 +406,7 @@ static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2*
|
||||
w->solid->vel.x, w->solid->vel.y, w->outfit->u.blt.sound, 0);
|
||||
break;
|
||||
default:
|
||||
// Just dump it where the player is.
|
||||
/* Just dump it where the player is. */
|
||||
w->voice = NULL;
|
||||
w->solid = solid_create(mass, dir, pos, vel);
|
||||
break;
|
||||
@ -414,7 +414,7 @@ static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2*
|
||||
return w;
|
||||
}
|
||||
|
||||
// Add a new weapon.
|
||||
/* Add a new weapon. */
|
||||
void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos,
|
||||
const Vec2* vel, unsigned int parent, unsigned int target) {
|
||||
|
||||
@ -427,7 +427,7 @@ void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos,
|
||||
WeaponLayer layer = (parent == PLAYER_ID) ? WEAPON_LAYER_FG : WEAPON_LAYER_BG;
|
||||
Weapon* w = weapon_create(outfit, dir, pos, vel, parent, target);
|
||||
|
||||
// Set the propper layer.
|
||||
/* Set the propper layer. */
|
||||
Weapon** curLayer = NULL;
|
||||
int* mLayer = NULL;
|
||||
int* nLayer = NULL;
|
||||
@ -446,9 +446,9 @@ void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos,
|
||||
ERR("Invalid WEAPON_LAYER specified.");
|
||||
return;
|
||||
}
|
||||
if(*mLayer > *nLayer) // More memory allocated than what we need.
|
||||
if(*mLayer > *nLayer) /* More memory allocated than what we need. */
|
||||
curLayer[(*nLayer)++] = w;
|
||||
else { // Need to allocate more memory.
|
||||
else { /* Need to allocate more memory. */
|
||||
switch(layer) {
|
||||
case WEAPON_LAYER_BG:
|
||||
(*mLayer) += WEAPON_CHUNK;
|
||||
@ -463,7 +463,7 @@ void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos,
|
||||
}
|
||||
}
|
||||
|
||||
// Destroy the weapon.
|
||||
/* Destroy the weapon. */
|
||||
static void weapon_destroy(Weapon* w, WeaponLayer layer) {
|
||||
int i;
|
||||
Weapon** wlayer;
|
||||
@ -478,7 +478,7 @@ static void weapon_destroy(Weapon* w, WeaponLayer layer) {
|
||||
nlayer = &nwfrontLayer;
|
||||
break;
|
||||
}
|
||||
for(i = 0; wlayer[i] != w; i++); // Get us to the current posision.
|
||||
for(i = 0; wlayer[i] != w; i++); /* Get us to the current posision. */
|
||||
weapon_free(wlayer[i]);
|
||||
wlayer[i] = NULL;
|
||||
(*nlayer)--;
|
||||
@ -487,14 +487,14 @@ static void weapon_destroy(Weapon* w, WeaponLayer layer) {
|
||||
wlayer[i] = wlayer[i+1];
|
||||
}
|
||||
|
||||
// Clear the weapon.
|
||||
/* Clear the weapon. */
|
||||
static void weapon_free(Weapon* w) {
|
||||
sound_delVoice(w->voice);
|
||||
solid_free(w->solid);
|
||||
free(w);
|
||||
}
|
||||
|
||||
// Clear all the weapons, do not free the layers.
|
||||
/* Clear all the weapons, do not free the layers. */
|
||||
void weapon_clear(void) {
|
||||
int i;
|
||||
for(i = 0; i < nwbackLayer; i++)
|
||||
|
@ -8,16 +8,16 @@ void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos,
|
||||
const Vec2* vel, unsigned int parent,
|
||||
const unsigned int target);
|
||||
|
||||
// Pausing.
|
||||
/* Pausing. */
|
||||
void weapons_pause(void);
|
||||
void weapons_unpause(void);
|
||||
void weapons_delay(unsigned int delay);
|
||||
|
||||
// Update.
|
||||
/* Update. */
|
||||
void weapons_update(const double dt);
|
||||
void weapons_render(const WeaponLayer layer);
|
||||
|
||||
// Clean.
|
||||
/* Clean. */
|
||||
void weapon_clear(void);
|
||||
void weapon_exit(void);
|
||||
|
||||
|
18
src/xml.h
18
src/xml.h
@ -8,24 +8,24 @@
|
||||
#define XML_NODE_START 1
|
||||
#define XML_NODE_TEXT 3
|
||||
|
||||
// Check if node n is of name s.
|
||||
/* Check if node n is of name s. */
|
||||
#define xml_isNode(n,s) (((n)->type == XML_NODE_START) && \
|
||||
(strcmp((char*)(n)->name, s)==0))
|
||||
|
||||
// Get the next node.
|
||||
/* Get the next node. */
|
||||
#define xml_nextNode(n) \
|
||||
((n!=NULL) && ((n = n->next) != NULL))
|
||||
|
||||
// Get the property s of node n. This mallocs.
|
||||
/* Get the property s of node n. This mallocs. */
|
||||
#define xml_nodeProp(n,s) (char*)xmlGetProp(n, (xmlChar*)s)
|
||||
|
||||
// Get data different ways.
|
||||
/* Get data different ways. */
|
||||
#define xml_get(n) ((char*)(n)->children->content)
|
||||
#define xml_getInt(n) (atoi((char*)(n)->children->content))
|
||||
#define xml_getLong(n) (atoi((char*)(n)->children->content))
|
||||
#define xml_getFloat(n) (atof((char*)(n)->children->content))
|
||||
|
||||
// Reader crap.
|
||||
/* Reader crap. */
|
||||
#define xmlr_int(n,s,i) \
|
||||
if(xml_isNode(n,s)) { i = xml_getInt(n); continue; }
|
||||
#define xmlr_long(n,s,l) \
|
||||
@ -39,9 +39,9 @@
|
||||
#define xmlr_attr(n,s,a) \
|
||||
a = xml_nodeProp(n,s)
|
||||
|
||||
// Writer crap.
|
||||
/* Writer crap. */
|
||||
|
||||
// Encompassing element.
|
||||
/* Encompassing element. */
|
||||
#define xmlw_startElem(w, str) \
|
||||
if(xmlTextWriterStartElement(w, (xmlChar*)str) < 0) { \
|
||||
ERR("xmlw: Unable to create start element"); return -1; }
|
||||
@ -50,7 +50,7 @@
|
||||
if(xmlTextWriterEndElement(w) < 0) { \
|
||||
ERR("xmlw: Unable to create end element"); return -1; }
|
||||
|
||||
// Other stuff.
|
||||
/* Other stuff. */
|
||||
#define xmlw_elem(w, n, str, args...) \
|
||||
if(xmlTextWriterWriteFormatElement(w, (xmlChar*)n, str, ## args) < 0) { \
|
||||
ERR("xmlw: Unable to write format element"); return -1; }
|
||||
@ -67,7 +67,7 @@
|
||||
if(xmlTextWriterWriteFormatString(w, str, ## val) < 0) { \
|
||||
ERR("xmlw: Unable to write element data"); return -1; }
|
||||
|
||||
// Document level.
|
||||
/* Document level. */
|
||||
#define xmlw_start(w) \
|
||||
if(xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL) < 0) { \
|
||||
ERR("xmlw: Unable to start document"); return -1; }
|
||||
|
@ -18,7 +18,7 @@
|
||||
#endif
|
||||
#define RGBAMASK RMASK, GMASK, BMASK, AMASK
|
||||
|
||||
// Logging macros.
|
||||
/* Logging macros. */
|
||||
#define LOG(str, args...)(fprintf(stdout, str"\n", ## args))
|
||||
#define WARN(str, args...)(fprintf(stderr, "Warning: "str"\n", ## args))
|
||||
#define ERR(str, args...) { fprintf(stderr, "ERROR %s:%d: "str"\n", \
|
||||
@ -37,7 +37,7 @@ int main(int argc, char* argv[]) {
|
||||
SDL_Surface* final, *tmp, **load;
|
||||
SDL_Rect r;
|
||||
|
||||
// Init variables.
|
||||
/* Init variables. */
|
||||
r.w = r.h = 0;
|
||||
|
||||
if(argc == 2) {
|
||||
@ -55,22 +55,22 @@ int main(int argc, char* argv[]) {
|
||||
tmp = NULL;
|
||||
final = NULL;
|
||||
|
||||
// Init SDL.
|
||||
/* Init SDL. */
|
||||
if(SDL_Init(SDL_INIT_VIDEO)) ERR("Initializing SDL: %s", SDL_GetError());
|
||||
// Create the window.
|
||||
/* Create the window. */
|
||||
tmp = SDL_SetVideoMode(320, 240, 0, SDL_NOFRAME);
|
||||
if(tmp == NULL) ERR("Initializing video surface: %s", SDL_GetError());
|
||||
|
||||
// Open RAM for the images.
|
||||
/* Open RAM for the images. */
|
||||
load = malloc(sizeof(SDL_Surface*)*(ws*hs));
|
||||
if(load == NULL) ERR("Out of RAM");
|
||||
|
||||
// Load all the images to RAM.
|
||||
/* Load all the images to RAM. */
|
||||
for(i = 0; i < (ws*hs); i++) {
|
||||
// Filenames will be in the sequence of: 000.png, 001.png, ..., 045.png, etc.
|
||||
/* Filenames will be in the sequence of: 000.png, 001.png, ..., 045.png, etc. */
|
||||
sprintf(file, "%d%d%d.png", i/100, (i%100)/10, i%10);
|
||||
|
||||
// Load the image properly.
|
||||
/* Load the image properly. */
|
||||
tmp = IMG_Load(file);
|
||||
if(tmp == NULL) ERR("Problem loading file '%s': %s", file, IMG_GetError());
|
||||
sflags = tmp->flags & (SDL_SRCALPHA | SDL_SRCCOLORKEY);
|
||||
@ -82,7 +82,7 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
load[i] = tmp;
|
||||
|
||||
// Check if size has changed.
|
||||
/* Check if size has changed. */
|
||||
if(r.w == 0 && r.h == 0) {
|
||||
r.w = load[i]->w;
|
||||
r.h = load[i]->h;
|
||||
@ -90,21 +90,21 @@ int main(int argc, char* argv[]) {
|
||||
else if((r.w != load[i]->w) || (r.h != load[i]->h))
|
||||
ERR("File '%s' is not of the same dimensions as the files before!", file);
|
||||
|
||||
// Create the suface if it hasn't been created already.
|
||||
/* Create the suface if it hasn't been created already. */
|
||||
if(!final) {
|
||||
final = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, ws*r.w, hs*r.h,
|
||||
load[i]->format->BitsPerPixel, RGBAMASK);
|
||||
if(!final) ERR("Problem creating RGB Surface: %s", SDL_GetError());
|
||||
tmp = final;
|
||||
}
|
||||
// New position.
|
||||
/* New position. */
|
||||
r.y = r.h * (i/ws);
|
||||
r.x = r.w * (i%ws);
|
||||
if(SDL_BlitSurface(load[i], NULL, final, &r))
|
||||
ERR("Problem blitting surface '%s' to final surface: %s", file, SDL_GetError());
|
||||
SDL_FreeSurface(load[i]);
|
||||
}
|
||||
// Draw the result and cleanup.
|
||||
/* Draw the result and cleanup. */
|
||||
save_png(final, "sprite.png");
|
||||
SDL_FreeSurface(final);
|
||||
free(load);
|
||||
|
@ -23,7 +23,7 @@ int main(int argc, char** argv) {
|
||||
argv += 2;
|
||||
|
||||
if(nfiles == 0) {
|
||||
// No files, list what it has.
|
||||
/* No files, list what it has. */
|
||||
list = pack_listfiles(packfile, &nlist);
|
||||
fprintf(stdout, "Packfile '%s' contains:\n", packfile);
|
||||
for(i = 0; i < nlist; i++) {
|
||||
@ -31,7 +31,7 @@ int main(int argc, char** argv) {
|
||||
free(list[i]);
|
||||
}
|
||||
free(list);
|
||||
} else { // Create a packfile.
|
||||
} else { /* Create a packfile. */
|
||||
pack_files(packfile, (const char**)argv, nfiles);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user