[Change] All tabs back to spaces.

This commit is contained in:
Allanis 2013-03-21 00:27:05 +00:00
parent b286205f56
commit 4ea444b9ae
50 changed files with 3734 additions and 3734 deletions

288
src/ai.c
View File

@ -48,14 +48,14 @@
// FUCK LUA!!!
#define luaL_register(L,n,l) (luaL_openlib(L, (n),(l), 0))
// Creates a new lua table.
#define newtable(L) (lua_newtable(L), lua_gettop(L))
#define newtable(L) (lua_newtable(L), lua_gettop(L))
// 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))
// Registers a C function.
#define lua_regfunc(l,s,f) (lua_pushcfunction(l,f), lua_setglobal(L,s))
// L state, void* buf, int n size, char* s identifier.
#define luaL_dobuffer(L,b,n,s) \
(luaL_loadbuffer(L,b,n,s) || lua_pcall(L, 0, LUA_MULTRET, 0))
(luaL_loadbuffer(L,b,n,s) || lua_pcall(L, 0, LUA_MULTRET, 0))
// Don't run the function if (n) params aren't passed.
#define MIN_ARGS(n) if(lua_gettop(L) < n) return 0
@ -94,13 +94,13 @@ void ai_create(Pilot* pilot);
// Ai routines for Lua.
// Tasks.
static int ai_pushtask(lua_State* L); // pushtask(string, number/pointer, number)
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_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()
@ -108,7 +108,7 @@ 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().
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()
@ -124,12 +124,12 @@ 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()
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_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).
@ -140,66 +140,66 @@ static int ai_timeup(lua_State* L); // boolean timeup(number)
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 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().
// Random.
static int ai_rng(lua_State* L); // rng(number, number)
static const luaL_Reg ai_methods[] = {
// Tasks.
{ "pushtask", ai_pushtask },
{ "poptask", ai_poptask },
{ "taskname", ai_taskname },
// Sanity checks.
{ "exists", ai_exists },
{ "ismaxvel", ai_ismaxvel },
{ "isstopped", ai_isstopped },
{ "isenemy", ai_isenemy },
{ "isally", ai_isally },
// Get's.
{ "incombat", ai_incombat },
{ "target", ai_gettarget },
{ "targetid", ai_gettargetid },
{ "rndpilot", ai_getrndpilot },
{ "armour", ai_armour },
{ "shield", ai_shield },
{ "parmour", ai_parmour },
{ "pshield", ai_pshield },
{ "dist", ai_getdistance },
{ "pos", ai_getpos },
{ "minbrakedist", ai_minbrakedist },
{ "cargofree", ai_cargofree },
{ "nearestplanet", ai_getnearestplanet },
{ "rndplanet", ai_getrndplanet },
// Movement.
{ "accel", ai_accel },
{ "turn", ai_turn },
{ "face", ai_face },
{ "brake", ai_brake },
{ "stop", ai_stop },
{ "hyperspace", ai_hyperspace },
// Combat.
{ "combat", ai_combat },
{ "settarget", ai_settarget },
{ "secondary", ai_secondary },
{ "hasturrets", ai_hasturrets },
{ "shoot", ai_shoot },
{ "getenemy", ai_getenemy },
{ "hostile", ai_hostile },
// Timers.
{ "settime", ai_settimer },
{ "timeup", ai_timeup },
// Messages.
{ "comm", ai_comm },
{ "broadcast", ai_broadcast },
// Loot.
{ "setcredits", ai_credits },
{ "setcargo", ai_cargo },
{ "shipprice", ai_shipprice },
// Random.
{ "rnd", ai_rng },
{ 0, 0 } // End.
// Tasks.
{ "pushtask", ai_pushtask },
{ "poptask", ai_poptask },
{ "taskname", ai_taskname },
// Sanity checks.
{ "exists", ai_exists },
{ "ismaxvel", ai_ismaxvel },
{ "isstopped", ai_isstopped },
{ "isenemy", ai_isenemy },
{ "isally", ai_isally },
// Get's.
{ "incombat", ai_incombat },
{ "target", ai_gettarget },
{ "targetid", ai_gettargetid },
{ "rndpilot", ai_getrndpilot },
{ "armour", ai_armour },
{ "shield", ai_shield },
{ "parmour", ai_parmour },
{ "pshield", ai_pshield },
{ "dist", ai_getdistance },
{ "pos", ai_getpos },
{ "minbrakedist", ai_minbrakedist },
{ "cargofree", ai_cargofree },
{ "nearestplanet", ai_getnearestplanet },
{ "rndplanet", ai_getrndplanet },
// Movement.
{ "accel", ai_accel },
{ "turn", ai_turn },
{ "face", ai_face },
{ "brake", ai_brake },
{ "stop", ai_stop },
{ "hyperspace", ai_hyperspace },
// Combat.
{ "combat", ai_combat },
{ "settarget", ai_settarget },
{ "secondary", ai_secondary },
{ "hasturrets", ai_hasturrets },
{ "shoot", ai_shoot },
{ "getenemy", ai_getenemy },
{ "hostile", ai_hostile },
// Timers.
{ "settime", ai_settimer },
{ "timeup", ai_timeup },
// Messages.
{ "comm", ai_comm },
{ "broadcast", ai_broadcast },
// Loot.
{ "setcredits", ai_credits },
{ "setcargo", ai_cargo },
{ "shipprice", ai_shipprice },
// Random.
{ "rnd", ai_rng },
{ 0, 0 } // End.
};
// Current pilot "thinking" and assorted variables.
@ -210,17 +210,17 @@ static int pilot_flags = 0;
static int pilot_target = 0;
// Ai status: 'Create' functions that can't be used elsewhere.
#define AI_STATUS_NORMAL 1
#define AI_STATUS_CREATE 2
#define AI_STATUS_NORMAL 1
#define AI_STATUS_CREATE 2
static int ai_status = AI_STATUS_NORMAL;
// 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.
WARN("Pilot '%s' ai -> '%s' : %s",
cur_pilot->name, funcname, lua_tostring(L,-1));
lua_getglobal(L, funcname);
if(lua_pcall(L, 0, 0, 0))
// Errors accured.
WARN("Pilot '%s' ai -> '%s' : %s",
cur_pilot->name, funcname, lua_tostring(L,-1));
}
// Destroy the AI part of the pilot.
@ -263,12 +263,12 @@ static int ai_loadProfile(char* filename) {
profiles = realloc(profiles, sizeof(AI_Profile)*(++nprofiles));
profiles[nprofiles-1].name =
malloc(sizeof(char)*
(strlen(filename)-strlen(AI_PREFIX)-strlen(AI_SUFFIX))+1);
malloc(sizeof(char)*
(strlen(filename)-strlen(AI_PREFIX)-strlen(AI_SUFFIX))+1);
snprintf(profiles[nprofiles-1].name,
strlen(filename)-strlen(AI_PREFIX)-strlen(AI_SUFFIX)+1,
"%s", filename+strlen(AI_PREFIX));
snprintf(profiles[nprofiles-1].name,
strlen(filename)-strlen(AI_PREFIX)-strlen(AI_SUFFIX)+1,
"%s", filename+strlen(AI_PREFIX));
profiles[nprofiles-1].L = luaL_newstate();
@ -286,7 +286,7 @@ static int ai_loadProfile(char* filename) {
lua_regnumber(L, "player", PLAYER_ID); // Player id.
// Register C funstions in Lua.
luaL_register(L, "ai", ai_methods);
luaL_register(L, "ai", ai_methods);
// Now load the file, since all the functions have been previously loaded.
buf = pack_readfile(DATA, filename, &bufsize);
@ -354,7 +354,7 @@ void ai_think(Pilot* pilot) {
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);
cur_pilot->solid->dir);
// Fire weapons if needs be.
if(ai_isFlag(AI_PRIMARY)) pilot_shoot(pilot, pilot_target, 0); // Primary.
@ -372,11 +372,11 @@ void ai_attacked(Pilot* attacked, const unsigned int attacker) {
// Pilot was just created.
void ai_create(Pilot* pilot) {
cur_pilot = pilot;
L = cur_pilot->ai->L;
ai_status = AI_STATUS_CREATE;
ai_run("create");
ai_status = AI_STATUS_NORMAL;
cur_pilot = pilot;
L = cur_pilot->ai->L;
ai_status = AI_STATUS_CREATE;
ai_run("create");
ai_status = AI_STATUS_NORMAL;
}
// =====================
@ -416,11 +416,11 @@ static int ai_pushtask(lua_State* L) {
// 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..
((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;
((Vec2*)t->dat.target)->angle = ((Vec2*)lua_topointer(L,3))->angle;
// 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;
((Vec2*)t->dat.target)->angle = ((Vec2*)lua_topointer(L,3))->angle;
} else
t->dtype = TYPE_NULL;
}
@ -476,8 +476,8 @@ static int ai_gettargetid(lua_State* L) {
}
static int ai_getrndpilot(lua_State* L) {
lua_pushnumber(L, pilot_stack[RNG(0, pilots-1)]->id);
return 1;
lua_pushnumber(L, pilot_stack[RNG(0, pilots-1)]->id);
return 1;
}
// Get the pilots armour.
@ -568,10 +568,10 @@ static int ai_getpos(lua_State* L) {
// ========================================================
static int ai_minbrakedist(lua_State* L) {
double time, dist;
time = VMOD(cur_pilot->solid->vel) /
time = VMOD(cur_pilot->solid->vel) /
(cur_pilot->thrust / cur_pilot->solid->mass);
dist = VMOD(cur_pilot->solid->vel)*0.9*(time+180./cur_pilot->turn) -
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
@ -579,8 +579,8 @@ static int ai_minbrakedist(lua_State* L) {
}
static int ai_cargofree(lua_State* L) {
lua_pushnumber(L, cur_pilot->cargo_free);
return 1;
lua_pushnumber(L, cur_pilot->cargo_free);
return 1;
}
static int ai_exists(lua_State* L) {
@ -609,14 +609,14 @@ static int ai_isstopped(lua_State* L) {
static int ai_isenemy(lua_State* L) {
if(lua_isnumber(L,1))
lua_pushboolean(L, areEnemies(cur_pilot->faction,
pilot_get(lua_tonumber(L,1))->faction));
pilot_get(lua_tonumber(L,1))->faction));
return 1;
}
// 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));
pilot_get(lua_tonumber(L,1))->faction));
return 1;
}
@ -634,7 +634,7 @@ static int ai_incombat(lua_State* L) {
// Accelerate the pilot based on a param.
static int ai_accel(lua_State* L) {
pilot_acc = (lua_gettop(L) > 1 && lua_isnumber(L, 1)) ?
ABS((double)lua_tonumber(L, 1)) : 1.;
ABS((double)lua_tonumber(L, 1)) : 1.;
return 0;
}
@ -651,37 +651,37 @@ static int ai_face(lua_State* L) {
Vec2* v, sv, tv; // Grab the position to face.
Pilot* p;
double mod, diff;
int invert = 0;
int n = -2;
int invert = 0;
int n = -2;
if(lua_isnumber(L, 1))
n = (int)lua_tonumber(L, 1);
if(lua_isnumber(L, 1))
n = (int)lua_tonumber(L, 1);
if(n >= 0) {
p = pilot_get(n);
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;
if(n >= 0) {
p = pilot_get(n);
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;
}
else if(lua_islightuserdata(L,1)) v = (Vec2*)lua_topointer(L,1);
mod = -10;
if(lua_gettop(L) > 1 && lua_isnumber(L,2)) invert = (int)lua_tonumber(L,2);
if(invert) mod *= -1;
vect_cset(&sv, VX(cur_pilot->solid->pos) + FACE_WVEL*VX(cur_pilot->solid->vel),
VY(cur_pilot->solid->pos) + FACE_WVEL*VY(cur_pilot->solid->vel));
if(invert) mod *= -1;
vect_cset(&sv, VX(cur_pilot->solid->pos) + FACE_WVEL*VX(cur_pilot->solid->vel),
VY(cur_pilot->solid->pos) + FACE_WVEL*VY(cur_pilot->solid->vel));
if(v != NULL)
// Target is static.
diff = angle_diff(cur_pilot->solid->dir,
(n==-1) ? VANGLE(cur_pilot->solid->pos) :
vect_angle(&cur_pilot->solid->pos, v));
else
// Target is dynamic.
diff = angle_diff(cur_pilot->solid->dir,
(n==-1) ? VANGLE(sv) :
vect_angle(&sv, &tv));
if(v != NULL)
// Target is static.
diff = angle_diff(cur_pilot->solid->dir,
(n==-1) ? VANGLE(cur_pilot->solid->pos) :
vect_angle(&cur_pilot->solid->pos, v));
else
// Target is dynamic.
diff = angle_diff(cur_pilot->solid->dir,
(n==-1) ? VANGLE(sv) :
vect_angle(&sv, &tv));
pilot_turn = mod*diff;
@ -737,12 +737,12 @@ static int ai_getrndplanet(lua_State* L) {
Planet** planets;
int nplanets, i;
Vec2 v;
Vec2 v;
planets = malloc(sizeof(Planet*) * cur_system->nplanets);
for(nplanets = 0, i = 0; i < cur_system->nplanets; i++)
if(planet_hasService(&cur_system->planets[i], PLANET_SERVICE_BASIC) &&
!areEnemies(cur_pilot->faction, cur_system->planets[i].faction))
!areEnemies(cur_pilot->faction, cur_system->planets[i].faction))
planets[nplanets++] = &cur_system->planets[i];
// No planet to land on found.
@ -753,9 +753,9 @@ static int ai_getrndplanet(lua_State* L) {
// 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.,
RNG(0, planets[i]->gfx_space->sh)-planets[i]->gfx_space->sh/2.);
vectcpy(&v, &planets[i]->pos);
vect_cadd(&v, RNG(0, planets[i]->gfx_space->sw)-planets[i]->gfx_space->sw/2.,
RNG(0, planets[i]->gfx_space->sh)-planets[i]->gfx_space->sh/2.);
lua_pushlightuserdata(L, &v);
free(planets);
return 1;
@ -774,12 +774,12 @@ static int ai_hyperspace(lua_State* L) {
// 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.);
if(VMOD(cur_pilot->solid->vel) < MIN_VEL_ERR)
vect_pset(&cur_pilot->solid->vel, 0., 0.);
return 0;
return 0;
}
// Toggle combat flag. Default is on.
@ -831,8 +831,8 @@ static int ai_secondary(lua_State* L) {
}
static int ai_hasturrets(lua_State* L) {
lua_pushboolean(L, pilot_isFlag(cur_pilot, PILOT_HASTURRET));
return 1;
lua_pushboolean(L, pilot_isFlag(cur_pilot, PILOT_HASTURRET));
return 1;
}
// Pew pew.. Says the pilot.
@ -871,7 +871,7 @@ static int ai_settimer(lua_State* L) {
if(lua_isnumber(L, 1)) n = lua_tonumber(L,1);
cur_pilot->timer[n] = (lua_isnumber(L,2)) ?
lua_tonumber(L,2) + SDL_GetTicks() : 0;
lua_tonumber(L,2) + SDL_GetTicks() : 0;
return 0;
}
@ -908,31 +908,31 @@ static int ai_broadcast(lua_State* L) {
// Set the pilots credits.
static int ai_credits(lua_State* L) {
MIN_ARGS(1);
if(ai_status != AI_STATUS_CREATE) return 0;
MIN_ARGS(1);
if(ai_status != AI_STATUS_CREATE) return 0;
if(lua_isnumber(L,1))
cur_pilot->credits = (int)lua_tonumber(L,1);
if(lua_isnumber(L,1))
cur_pilot->credits = (int)lua_tonumber(L,1);
return 0;
return 0;
}
// Set the pilots cargo.
static int ai_cargo(lua_State* L) {
MIN_ARGS(2);
if(ai_status != AI_STATUS_CREATE) return 0;
MIN_ARGS(2);
if(ai_status != AI_STATUS_CREATE) return 0;
if(lua_isstring(L,1) && lua_isnumber(L,2))
pilot_addCargo(cur_pilot, commodity_get(lua_tostring(L,1)),
(int)lua_tonumber(L,2));
if(lua_isstring(L,1) && lua_isnumber(L,2))
pilot_addCargo(cur_pilot, commodity_get(lua_tostring(L,1)),
(int)lua_tonumber(L,2));
return 0;
return 0;
}
// Get the pilot's ship value.
static int ai_shipprice(lua_State* L) {
lua_pushnumber(L, cur_pilot->ship->price);
return 1;
lua_pushnumber(L, cur_pilot->ship->price);
return 1;
}
// Return a number between low and high.

View File

@ -5,7 +5,7 @@
#define MAX_DIR_ERR 0.1*M_PI/180.
#define MIN_VEL_ERR 1.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.
#define MAX_AI_TIMERS 2

View File

@ -8,8 +8,8 @@
#include "economy.h"
#include "board.h"
#define BOARDING_WIDTH 300
#define BOARDING_HEIGHT 200
#define BOARDING_WIDTH 300
#define BOARDING_HEIGHT 200
extern unsigned int player_target;
@ -23,166 +23,166 @@ static void board_update(void);
// Attempt to board the players target.
void player_board(void) {
Pilot* p;
Pilot* p;
if(player_target == PLAYER_ID) {
player_message("You need a target to board first!");
return;
}
if(player_target == PLAYER_ID) {
player_message("You need a target to board first!");
return;
}
p = pilot_get(player_target);
p = pilot_get(player_target);
if(!pilot_isDisabled(p)) {
player_message("You cannot board a ship that is not disabled!");
return;
}
else if(vect_dist(&player->solid->pos, &p->solid->pos) >
p->ship->gfx_space->sw * PILOT_SIZE_APROX) {
player_message("You are too far away to board your target");
return;
}
else if((pow2(VX(player->solid->vel)-VX(p->solid->vel)) +
pow2(VY(player->solid->vel)-VY(p->solid->vel))) >
(double)pow2(MAX_HYPERSPACE_VEL)) {
player_message("You are going too fast to board the ship");
return;
}
else if(pilot_isFlag(p, PILOT_BOARDED)) {
player_message("Your target cannot be boarded again");
return;
}
if(!pilot_isDisabled(p)) {
player_message("You cannot board a ship that is not disabled!");
return;
}
else if(vect_dist(&player->solid->pos, &p->solid->pos) >
p->ship->gfx_space->sw * PILOT_SIZE_APROX) {
player_message("You are too far away to board your target");
return;
}
else if((pow2(VX(player->solid->vel)-VX(p->solid->vel)) +
pow2(VY(player->solid->vel)-VY(p->solid->vel))) >
(double)pow2(MAX_HYPERSPACE_VEL)) {
player_message("You are going too fast to board the ship");
return;
}
else if(pilot_isFlag(p, PILOT_BOARDED)) {
player_message("Your target cannot be boarded again");
return;
}
// Pilot will be boarded.
pilot_setFlag(p, PILOT_BOARDED);
player_message("Boarding ship %s", p->name);
// Pilot will be boarded.
pilot_setFlag(p, PILOT_BOARDED);
player_message("Boarding ship %s", p->name);
// Create the boarding window.
board_wid = window_create("Boarding", -1, -1, BOARDING_WIDTH, BOARDING_HEIGHT);
// Create the boarding window.
board_wid = window_create("Boarding", -1, -1, BOARDING_WIDTH, BOARDING_HEIGHT);
window_addText(board_wid, 20, -30, 120, 60,
0, "txtCargo", &gl_smallFont, &cDConsole,
"SCreds:\n"
"Cargo:\n");
window_addText(board_wid, 20, -30, 120, 60,
0, "txtCargo", &gl_smallFont, &cDConsole,
"SCreds:\n"
"Cargo:\n");
window_addText(board_wid, 80, -30, 120, 60, 0, "txtData",
&gl_smallFont, &cBlack, NULL);
window_addText(board_wid, 80, -30, 120, 60, 0, "txtData",
&gl_smallFont, &cBlack, NULL);
window_addButton(board_wid, 20, 20, 50, 30, "btnStealCredits",
"Credits", board_stealCreds);
window_addButton(board_wid, 20, 20, 50, 30, "btnStealCredits",
"Credits", board_stealCreds);
window_addButton(board_wid, 90, 20, 50, 30, "btnStealCargo",
"Cargo", board_stealCargo);
window_addButton(board_wid, 90, 20, 50, 30, "btnStealCargo",
"Cargo", board_stealCargo);
window_addButton(board_wid, -20, 20, 50, 30, "btnBoardingClose",
"Leave", board_exit);
window_addButton(board_wid, -20, 20, 50, 30, "btnBoardingClose",
"Leave", board_exit);
board_update();
board_update();
}
static void board_exit(char* str) {
(void)str;
window_destroy(window_get("Boarding"));
(void)str;
window_destroy(window_get("Boarding"));
}
static void board_stealCreds(char* str) {
(void)str;
Pilot* p;
(void)str;
Pilot* p;
p = pilot_get(player_target);
p = pilot_get(player_target);
if(p->credits == 0) {
// Can't steal from the poor. ;)
player_message("The ship has no SCreds.");
return;
}
if(p->credits == 0) {
// Can't steal from the poor. ;)
player_message("The ship has no SCreds.");
return;
}
if(board_fail()) return;
if(board_fail()) return;
player_credits += p->credits;
p->credits = 0;
board_update(); // Update the lack of credits.
player_message("You manage to steal the ship's Scred.");
player_credits += p->credits;
p->credits = 0;
board_update(); // Update the lack of credits.
player_message("You manage to steal the ship's Scred.");
}
static void board_stealCargo(char* str) {
(void)str;
int q;
Pilot* p;
(void)str;
int q;
Pilot* p;
p = pilot_get(player_target);
p = pilot_get(player_target);
if(p->ncommodities==0) {
// No cargo.
player_message("The ship has no cargo.");
return;
}
else if(player->cargo_free <= 0) {
player_message("You have no room for cargo.");
return;
}
if(p->ncommodities==0) {
// No cargo.
player_message("The ship has no cargo.");
return;
}
else if(player->cargo_free <= 0) {
player_message("You have no room for cargo.");
return;
}
if(board_fail()) return;
if(board_fail()) return;
// 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,
p->commodities[0].quantity);
// 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,
p->commodities[0].quantity);
pilot_rmCargo(p, p->commodities[0].commodity, q);
}
pilot_rmCargo(p, p->commodities[0].commodity, q);
}
board_update();
player_message("You manage to steal the ship's cargo.");
board_update();
player_message("You manage to steal the ship's cargo.");
}
// Failed to board.
static int board_fail(void) {
Pilot* p;
Pilot* p;
p = pilot_get(player_target);
p = pilot_get(player_target);
// Fail chance.
if(RNG(0, 100) > (int)(50. *
(10. + (double)p->ship->crew/10.+(double)player->ship->crew)))
return 0;
// 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.
p->armour = -1;
player_message("You have tripped the ship's self destruct mechanism!");
} else
// You just got locked out!!
player_message("The ship's security system locks you out!");
if(RNG(0, 2)==0) {
// 33% of instant death.
p->armour = -1;
player_message("You have tripped the ship's self destruct mechanism!");
} else
// You just got locked out!!
player_message("The ship's security system locks you out!");
board_exit(NULL);
return 1;
board_exit(NULL);
return 1;
}
// Update the cargo and credit fields.
static void board_update(void) {
int i;
char str[128], buf[32];
char cred[10];
Pilot* p;
int i;
char str[128], buf[32];
char cred[10];
Pilot* p;
p = pilot_get(player_target);
p = pilot_get(player_target);
credits2str(cred, p->credits, 2);
credits2str(cred, p->credits, 2);
snprintf(str, 11,
"%s\n", cred);
if(p->ncommodities == 0)
strncat(str, "none", 10);
else {
for(i = 0; i < p->ncommodities; i++) {
snprintf(buf, 32,
"%d %s\n",
p->commodities[i].quantity, p->commodities[i].commodity->name);
strncat(str, buf, 32);
}
}
snprintf(str, 11,
"%s\n", cred);
if(p->ncommodities == 0)
strncat(str, "none", 10);
else {
for(i = 0; i < p->ncommodities; i++) {
snprintf(buf, 32,
"%d %s\n",
p->commodities[i].quantity, p->commodities[i].commodity->name);
strncat(str, buf, 32);
}
}
window_modifyText(board_wid, "txtData", str);
window_modifyText(board_wid, "txtData", str);
}

View File

@ -13,15 +13,15 @@
// 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) {
const Vec2* ap, const glTexture* bt,
const int bsx, const int bsy, const Vec2* bp) {
int x,y;
int ax1, ax2, ay1, ay2;
int bx1, bx2, by1, by2;
int inter_x0, inter_x1, inter_y0, inter_y1;
int rasy, rbsy;
int abx, aby, bbx, bby;
int ax1, ax2, ay1, ay2;
int bx1, bx2, by1, by2;
int inter_x0, inter_x1, inter_y0, inter_y1;
int rasy, rbsy;
int abx, aby, bbx, bby;
// a - cube coords.
ax1 = (int)VX(*ap) - (int)(at->sw)/2;

View File

@ -3,6 +3,6 @@
#include "physics.h"
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);
const Vec2* ap, const glTexture* bt,
const int bsx, const int bsy, const Vec2* bp);

View File

@ -16,26 +16,26 @@ glColour cBlack = { .r = 0.00, .g = 0.00, .b = 0.00, .a = 1. };
glColour cGreen = { .r = 0.20, .g = 0.80, .b = 0.20, .a = 1. };
glColour cDarkRed = { .r = 0.60, .g = 0.10, .b = 0.10, .a = 1. };
glColour cRed = { .r = 0.80, .g = 0.20, .b = 0.20, .a = 1. };
glColour cYellow = { .r = 0.80, .g = 0.80, .b = 0.00, .a = 1. };
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 cYellow = { .r = 0.80, .g = 0.80, .b = 0.00, .a = 1. };
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. };
// 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. };
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.
glColour cHilight = { .r = 0.1, .g = 0.9, .b = 0.1, .a = 0.3 };
glColour cHilight = { .r = 0.1, .g = 0.9, .b = 0.1, .a = 0.3 };
// 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. };
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
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. };
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.
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. };
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. };

View File

@ -31,7 +31,7 @@ extern glColour cBlue;
// Game specific.
extern glColour cConsole;
extern glColour cDConsole;
extern glColour cDConsole;
// Toolkit.
extern glColour cHilight;
// Objects.

View File

@ -24,8 +24,8 @@ if(lua_isnumber(L, -1)) { \
#define conf_loadFloat(n,f) \
lua_getglobal(L,n); \
if(lua_isnumber(L, -1)) { \
f = (double)lua_tonumber(L, -1); \
lua_remove(L,-1);\
f = (double)lua_tonumber(L, -1); \
lua_remove(L,-1);\
}
#define conf_loadBool(n,b) \
@ -65,8 +65,8 @@ static void print_usage(char** argv) {
LOG("\t-d s, --data s - Set the data file to be s");
LOG("\t-j n, --joystick n - Use joystick (n)");
LOG("\t-J s, --joystick s - Use joystick whose name contains (s)");
LOG("\t-m f, --music f - Set the music volume to f");
LOG("\t-s f, --sound f - Set the sound volume to f");
LOG("\t-m f, --music f - Set the music volume to f");
LOG("\t-s f, --sound f - Set the sound volume to f");
LOG("\t-h --help - Display this message and exit.");
LOG("\t-v - Print the version and exit");
}
@ -89,7 +89,7 @@ void conf_setDefaults(void) {
// Ok.. Parse a config file plox.
int conf_loadConfig(const char* file) {
int i = 0;
double d = 0.;
double d = 0.;
lua_State* L = luaL_newstate();
if(luaL_dofile(L, file) == 0) {
@ -104,9 +104,9 @@ int conf_loadConfig(const char* file) {
if(i) { gl_screen.flags |= OPENGL_FULLSCREEN; i = 0; }
conf_loadBool("aa", i);
if(i) {
gl_screen.flags |= OPENGL_AA_POINT | OPENGL_AA_LINE || OPENGL_AA_POLYGON;
i = 0;
}
gl_screen.flags |= OPENGL_AA_POINT | OPENGL_AA_LINE || OPENGL_AA_POLYGON;
i = 0;
}
conf_loadBool("aa_point", i);
if(i) { gl_screen.flags |= OPENGL_AA_POINT; i = 0; }
conf_loadBool("aa_line", i)
@ -114,18 +114,18 @@ int conf_loadConfig(const char* file) {
conf_loadBool("aa_polygon", i);
if(i) { gl_screen.flags |= OPENGL_AA_POLYGON; i = 0; }
// FPS.
conf_loadBool("showfps", show_fps);
// FPS.
conf_loadBool("showfps", show_fps);
conf_loadInt("maxfps", max_fps);
// Input.
conf_loadInt("afterburn", input_afterburnSensibility);
// Input.
conf_loadInt("afterburn", input_afterburnSensibility);
// Sound.
conf_loadFloat("sound", d);
if(d) { sound_volume(d); d = 0.; }
conf_loadFloat("music", d);
if(d) { music_volume(d); d = 0.; }
// Sound.
conf_loadFloat("sound", d);
if(d) { sound_volume(d); d = 0.; }
conf_loadFloat("music", d);
if(d) { music_volume(d); d = 0.; }
// Joystick.
lua_getglobal(L, "joystick");
@ -200,22 +200,22 @@ int conf_loadConfig(const char* file) {
// Parse some CLI options.
void conf_parseCLI(int argc, char** argv) {
static struct option long_options[] = {
{ "fullscreen", no_argument, 0, 'f' },
{ "fps", required_argument, 0, 'F' },
{ "data", required_argument, 0, 'd' },
{ "joystick", required_argument, 0, 'j' },
{ "Joystick", required_argument, 0, 'J' },
{ "music", required_argument, 0, 'm' },
{ "sound", required_argument, 0, 's' },
{ "help", no_argument, 0, 'h' },
{ "version", no_argument, 0, 'v' },
{ "fullscreen", no_argument, 0, 'f' },
{ "fps", required_argument, 0, 'F' },
{ "data", required_argument, 0, 'd' },
{ "joystick", required_argument, 0, 'j' },
{ "Joystick", required_argument, 0, 'J' },
{ "music", required_argument, 0, 'm' },
{ "sound", required_argument, 0, 's' },
{ "help", no_argument, 0, 'h' },
{ "version", no_argument, 0, 'v' },
{ NULL, 0, 0, 0 }
};
int option_index = 0;
int c = 0;
while((c = getopt_long(argc, argv, "fF:d:J:j:s:m:V:hv",
long_options, &option_index)) != -1) {
long_options, &option_index)) != -1) {
switch(c) {
case 'f':
gl_screen.flags |= OPENGL_FULLSCREEN;
@ -232,12 +232,12 @@ void conf_parseCLI(int argc, char** argv) {
case 'J':
namjoystick = strdup(optarg);
break;
case 'm':
music_volume(atof(optarg));
break;
case 's':
sound_volume(atof(optarg));
break;
case 'm':
music_volume(atof(optarg));
break;
case 's':
sound_volume(atof(optarg));
break;
case 'v':
LOG(APPNAME": version %d.%d.%d", VMAJOR, VMINOR, VREV);
case 'h':

View File

@ -8,9 +8,9 @@
#include "log.h"
#include "economy.h"
#define XML_COMMODITY_ID "Commodities" // XML section identifier.
#define XML_COMMODITY_TAG "commodity"
#define COMMODITY_DATA "../dat/commodity.xml"
#define XML_COMMODITY_ID "Commodities" // XML section identifier.
#define XML_COMMODITY_TAG "commodity"
#define COMMODITY_DATA "../dat/commodity.xml"
// Commodity stack.
static Commodity* commodity_stack = NULL;
@ -22,115 +22,115 @@ static Commodity* commodity_parse(xmlNodePtr parent);
// 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);
else if(credits >= 1000000000)
snprintf(str, 16, "%.*fB", decimals, (double)credits / 1000000000.);
else if(credits >= 1000000)
snprintf(str, 16, "%*fM", decimals, (double)credits / 1000000.);
else if(credits >= 1000)
snprintf(str, 16, "%.*fK", decimals, (double)credits / 1000.);
else snprintf(str, 16, "%d", credits);
if(decimals < 0)
snprintf(str, 32, "%d", credits);
else if(credits >= 1000000000)
snprintf(str, 16, "%.*fB", decimals, (double)credits / 1000000000.);
else if(credits >= 1000000)
snprintf(str, 16, "%*fM", decimals, (double)credits / 1000000.);
else if(credits >= 1000)
snprintf(str, 16, "%.*fK", decimals, (double)credits / 1000.);
else snprintf(str, 16, "%d", credits);
}
// Get a commodity.
Commodity* commodity_get(const char* name) {
int i;
for(i = 0; i < commodity_nstack; i++)
if(strcmp(commodity_stack[i].name, name)==0)
return &commodity_stack[i];
int i;
for(i = 0; i < commodity_nstack; i++)
if(strcmp(commodity_stack[i].name, name)==0)
return &commodity_stack[i];
WARN("Commodity '%s' not found in stack", name);
return NULL;
WARN("Commodity '%s' not found in stack", name);
return NULL;
}
// Free a commodity.
static void commodity_freeOne(Commodity* com) {
if(com->name) free(com->name);
if(com->description) free(com->description);
if(com->name) free(com->name);
if(com->description) free(com->description);
}
static Commodity* commodity_parse(xmlNodePtr parent) {
xmlNodePtr node;
Commodity* tmp = CALLOC_L(Commodity);
xmlNodePtr node;
Commodity* tmp = CALLOC_L(Commodity);
tmp->name = (char*)xmlGetProp(parent, (xmlChar*)"name");
if(tmp->name == NULL)
WARN("Commodity from "COMMODITY_DATA" has invalid or noname");
tmp->name = (char*)xmlGetProp(parent, (xmlChar*)"name");
if(tmp->name == NULL)
WARN("Commodity from "COMMODITY_DATA" has invalid or noname");
node = parent->xmlChildrenNode;
node = parent->xmlChildrenNode;
do {
if(xml_isNode(node, "description"))
tmp->description = strdup(xml_get(node));
else if(xml_isNode(node, "high"))
tmp->high = xml_getInt(node);
else if(xml_isNode(node, "medium"))
tmp->medium = xml_getInt(node);
else if(xml_isNode(node, "low"))
tmp->low = xml_getInt(node);
} while((node = node->next));
do {
if(xml_isNode(node, "description"))
tmp->description = strdup(xml_get(node));
else if(xml_isNode(node, "high"))
tmp->high = xml_getInt(node);
else if(xml_isNode(node, "medium"))
tmp->medium = xml_getInt(node);
else if(xml_isNode(node, "low"))
tmp->low = xml_getInt(node);
} while((node = node->next));
#define MELEMENT(o,s)if(o)WARN("Commodity '%s' missing '"s"' element",tmp->name)
MELEMENT(tmp->high==0, "high");
MELEMENT(tmp->description==NULL, "description");
MELEMENT(tmp->medium==0, "medium");
MELEMENT(tmp->low==0, "low");
MELEMENT(tmp->high==0, "high");
MELEMENT(tmp->description==NULL, "description");
MELEMENT(tmp->medium==0, "medium");
MELEMENT(tmp->low==0, "low");
#undef MELEMENT
return tmp;
return tmp;
}
int commodity_load(void) {
uint32_t bufsize;
char* buf = pack_readfile(DATA, COMMODITY_DATA, &bufsize);
uint32_t bufsize;
char* buf = pack_readfile(DATA, COMMODITY_DATA, &bufsize);
xmlNodePtr node;
xmlDocPtr doc = xmlParseMemory(buf, bufsize);
xmlNodePtr node;
xmlDocPtr doc = xmlParseMemory(buf, bufsize);
Commodity* tmp = NULL;
Commodity* tmp = NULL;
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 = 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.
if(node == NULL) {
ERR("Malformed "COMMODITY_DATA" file: does not contain elements");
return -1;
}
node = node->xmlChildrenNode; // First faction node.
if(node == NULL) {
ERR("Malformed "COMMODITY_DATA" file: does not contain elements");
return -1;
}
do {
if(node->type == XML_NODE_START) {
if(strcmp((char*)node->name, XML_COMMODITY_TAG)==0) {
tmp = commodity_parse(node);
commodity_stack = realloc(commodity_stack,
sizeof(Commodity)*(++commodity_nstack));
memcpy(commodity_stack+commodity_nstack-1, tmp, sizeof(Commodity));
free(tmp);
}
}
} while((node = node->next));
do {
if(node->type == XML_NODE_START) {
if(strcmp((char*)node->name, XML_COMMODITY_TAG)==0) {
tmp = commodity_parse(node);
commodity_stack = realloc(commodity_stack,
sizeof(Commodity)*(++commodity_nstack));
memcpy(commodity_stack+commodity_nstack-1, tmp, sizeof(Commodity));
free(tmp);
}
}
} while((node = node->next));
xmlFreeDoc(doc);
free(buf);
xmlCleanupParser();
xmlFreeDoc(doc);
free(buf);
xmlCleanupParser();
DEBUG("Loaded %d commodit%s",
commodity_nstack, (commodity_nstack==1) ? "y" : "ies");
DEBUG("Loaded %d commodit%s",
commodity_nstack, (commodity_nstack==1) ? "y" : "ies");
return 0;
return 0;
}
void commodity_free(void) {
int i;
for(i = 0; i < commodity_nstack; i++)
commodity_freeOne(&commodity_stack[i]);
free(commodity_stack);
commodity_stack = NULL;
commodity_nstack = 0;
int i;
for(i = 0; i < commodity_nstack; i++)
commodity_freeOne(&commodity_stack[i]);
free(commodity_stack);
commodity_stack = NULL;
commodity_nstack = 0;
}

View File

@ -1,9 +1,9 @@
#pragma once
typedef struct Commodity_ {
char* name;
char* description;
int low, medium, high; // Prices.
char* name;
char* description;
int low, medium, high; // Prices.
} Commodity;
// Commidity stuff.

View File

@ -66,7 +66,7 @@ int areEnemies(Faction* a, Faction* b) {
int i = 0;
if(a == b) return 0;
else if((a == NULL) || (b == NULL)) return 0;
else if((a == NULL) || (b == NULL)) return 0;
for(i = 0; i < a->nenemies; i++)
if(a->enemies[i] == b)
@ -83,7 +83,7 @@ int areAllies(Faction* a, Faction* b) {
int i = 0;
if(a == b) return 0;
else if((a == NULL) || (b == NULL)) return 0;
else if((a == NULL) || (b == NULL)) return 0;
for(i = 0; i < a->nallies; i++)
if(a->allies[i] == b)
@ -101,7 +101,7 @@ static Faction* faction_parse(xmlNodePtr parent) {
Faction* tmp = CALLOC_L(Faction);
tmp->name = (char*)xmlGetProp(parent, (xmlChar*)"name");
if(tmp->name == NULL)
WARN("Faction from "FACTION_DATA" has invalid or no name");
WARN("Faction from "FACTION_DATA" has invalid or no name");
return tmp;
}
@ -115,7 +115,7 @@ static void alliance_parse(xmlNodePtr parent) {
do {
if((node->type == XML_NODE_START) && (strcmp((char*)node->name,
XML_ALLIANCE_TAG)==0)) {
XML_ALLIANCE_TAG)==0)) {
// Allocate a new alliance.
alliances = realloc(alliances, sizeof(Alliance)*(++nalliances));
alliances[nalliances-1].name = (char*)xmlGetProp(node,(xmlChar*)"name");
@ -144,14 +144,14 @@ static void alliance_parse(xmlNodePtr parent) {
// Set the crap needed by faction_stack.
for(j = 0; j < (*i); j++) {
a->factions[j]->nallies += (*i)-1;
a->factions[j]->allies = realloc(a->factions[j]->allies,
a->factions[j]->nallies*sizeof(Faction*));
a->factions[j]->allies = realloc(a->factions[j]->allies,
a->factions[j]->nallies*sizeof(Faction*));
for(n = 0, m = 0; n < (*i); n++, m++) {
// Add as ally for all factions exept self.
if(n == j) m--;
else if(n != j)
a->factions[j]->allies[a->factions[j]->nallies-(*i)+1+m] =
a->factions[n];
a->factions[n];
}
}
}
@ -169,7 +169,7 @@ static void enemies_parse(xmlNodePtr parent) {
do {
if((node->type == XML_NODE_START)
&& (strcmp((char*)node->name, XML_ENEMIES_TAG)==0)) {
&& (strcmp((char*)node->name, XML_ENEMIES_TAG)==0)) {
i = 0;
f = NULL;
j = NULL;
@ -188,7 +188,7 @@ static void enemies_parse(xmlNodePtr parent) {
a = alliance_get((char*)cur->children->content);
if(a == NULL)
WARN("Alliance %s not found in stack",
(char*)cur->children->content);
(char*)cur->children->content);
j[i-1] = a->nfactions;
f[i-1] = a->factions;
}
@ -199,7 +199,7 @@ static void enemies_parse(xmlNodePtr parent) {
f[i-1][0] = faction_get((char*)cur->children->content);
if(f[i-1][0] == NULL)
WARN("Faction %s not found in stack",
(char*)cur->children->content);
(char*)cur->children->content);
}
free(type);
}
@ -214,7 +214,7 @@ static void enemies_parse(xmlNodePtr parent) {
// Now allocate the memory.
f[n][m]->nenemies += e;
f[n][m]->enemies = realloc(f[n][m]->enemies,
sizeof(Faction*)*f[n][m]->nenemies);
sizeof(Faction*)*f[n][m]->nenemies);
// Add the actualy enemies.
for(x = 0, z = 0; x < i; x++)

View File

@ -76,7 +76,7 @@ void gl_print(const glFont* ft_font, const double x, const double y,
// 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, ...) {
const double x, const double y, const glColour* c, const char* fmt, ...) {
//float h = ft_font->h / .63; // Slightly increases font size.
char txt[256];
va_list ap;
@ -231,7 +231,7 @@ int gl_printText(const glFont* ft_font, const int width, const int height,
glPushMatrix(); // Translation matrix.
glTranslated(x, y, 0);
// This is what we are displaying.
// This is what we are displaying.
glCallLists(lastspace-p-1, GL_UNSIGNED_BYTE, &buf);
glPopMatrix(); // Translation matrix.
@ -273,13 +273,13 @@ int gl_printWidth(const glFont* ft_font, const char* fmt, ...) {
// FONT!
// ================
static void glFontMakeDList(FT_Face face, char ch, GLuint list_base,
GLuint* tex_base, int* width_base) {
GLuint* tex_base, int* width_base) {
FT_Glyph glyph;
FT_Bitmap bitmap;
GLubyte* expanded_data;
int w, h;
int i, j;
double x, y;
double x, y;
if(FT_Load_Glyph(face, FT_Get_Char_Index(face, ch), FT_LOAD_FORCE_AUTOHINT))
WARN("FT_Load_Glyph failed");
@ -304,7 +304,7 @@ static void glFontMakeDList(FT_Face face, char ch, GLuint list_base,
for(i = 0; i < w; i++) {
expanded_data[2*(i+j*w)] = expanded_data[2*(i+j*w)+1] =
(i >= bitmap.width || j >= bitmap.rows) ?
0 : bitmap.buffer[i + bitmap.width*j];
0 : bitmap.buffer[i + bitmap.width*j];
}
}
// Create the GL texture.
@ -312,7 +312,7 @@ static void glFontMakeDList(FT_Face face, char ch, GLuint list_base,
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);
GL_UNSIGNED_BYTE, expanded_data);
free(expanded_data); // No need for this now.
@ -343,7 +343,7 @@ static void glFontMakeDList(FT_Face face, char ch, GLuint list_base,
glPopMatrix();
glTranslated(face->glyph->advance.x >> 6, 0,0);
width_base[(int)ch] = (int)(face->glyph->advance.x >> 6);
width_base[(int)ch] = (int)(face->glyph->advance.x >> 6);
// End of the display list.
glEndList();

View File

@ -23,11 +23,11 @@ void gl_print(const glFont* ft_font, const double x, const double y,
// 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, ...);
const double x, const double y, const glColour* c, const char* fmt, ...);
// 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, ...);
double x, const double y, const glColour* c, const char* fmt, ...);
// Respects \n -> bx, by is top left position.
int gl_printText(const glFont* ft_font, const int width, const int height,

View File

@ -24,16 +24,16 @@ static Keybind** input_keybinds; // Contains the players keybindings.
// Name of each keybinding.
const char* keybindNames[] = {
"accel", "left", "right", "reverse", // Movement.
"primary", "target", "target_nearest", "face", "board", // Combat.
"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.
"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.
int input_afterburnSensibility = 500; // ms between taps to afterburn.
static unsigned int input_accelLast = 0; // Used to see if double tap.
int input_afterburnSensibility = 500; // ms between taps to afterburn.
// From player.c
extern double player_turn;
@ -57,22 +57,22 @@ void input_setDefault(void) {
input_setKeybind("face", KEYBIND_KEYBOARD, SDLK_f, 0);
input_setKeybind("board", KEYBIND_KEYBOARD, SDLK_b, 0);
// Secondary weapon.
input_setKeybind("secondary", KEYBIND_KEYBOARD, SDLK_LSHIFT, 0);
input_setKeybind("secondary", KEYBIND_KEYBOARD, SDLK_LSHIFT, 0);
input_setKeybind("secondary_next", KEYBIND_KEYBOARD, SDLK_e, 0);
// 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("starmap", KEYBIND_KEYBOARD, SDLK_m, 0);
input_setKeybind("jump", KEYBIND_KEYBOARD, SDLK_j, 0);
// Misc.
input_setKeybind("mapzoomin", KEYBIND_KEYBOARD, SDLK_0, 0);
input_setKeybind("mapzoomout", KEYBIND_KEYBOARD, SDLK_9, 0);
input_setKeybind("mapzoomin", KEYBIND_KEYBOARD, SDLK_0, 0);
input_setKeybind("mapzoomout", KEYBIND_KEYBOARD, SDLK_9, 0);
input_setKeybind("screenshot", KEYBIND_KEYBOARD, SDLK_F12, 0);
input_setKeybind("pause", KEYBIND_KEYBOARD, SDLK_F1, 0);
input_setKeybind("menu", KEYBIND_KEYBOARD, SDLK_ESCAPE, 0);
input_setKeybind("info", KEYBIND_KEYBOARD, SDLK_i, 0);
input_setKeybind("info", KEYBIND_KEYBOARD, SDLK_i, 0);
}
// Initialization/exit functions (does not assign keys).
@ -118,31 +118,31 @@ void input_setKeybind(char* keybind, KeybindType type, int key, int reverse) {
// 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)
#define KEY(s) (strcmp(input_keybinds[keynum]->name, s)==0)
#define INGAME() (!toolkit)
// We won't be having any more funny stuff from VLack..
#define NOHYP() \
(!pilot_isFlag(player, PILOT_HYP_PREP) && \
!pilot_isFlag(player, PILOT_HYP_BEGIN) && \
!pilot_isFlag(player, PILOT_HYPERSPACE))
(!pilot_isFlag(player, PILOT_HYP_PREP) && \
!pilot_isFlag(player, PILOT_HYP_BEGIN) && \
!pilot_isFlag(player, PILOT_HYPERSPACE))
static void input_key(int keynum, double value, int abs) {
unsigned int t;
unsigned int t;
// Accelerating.
if(KEY("accel")) {
if(abs)player_acc = value;
else player_acc += value;
// Double tap accel = afterburn!
t = SDL_GetTicks();
if((value == KEY_PRESS) && (t-input_accelLast <= input_afterburnSensibility)) {
player_afterburn();
}
else if((value == KEY_RELEASE) && player_isFlag(PLAYER_AFTERBURNER))
player_afterburnOver();
else
player_acc = ABS(player_acc); // Make sure value is sane.
// Double tap accel = afterburn!
t = SDL_GetTicks();
if((value == KEY_PRESS) && (t-input_accelLast <= input_afterburnSensibility)) {
player_afterburn();
}
else if((value == KEY_RELEASE) && player_isFlag(PLAYER_AFTERBURNER))
player_afterburnOver();
else
player_acc = ABS(player_acc); // Make sure value is sane.
if(value == KEY_PRESS) input_accelLast = t;
if(value == KEY_PRESS) input_accelLast = t;
}
// Turning left.
else if(KEY("left")) {
@ -174,7 +174,7 @@ static void input_key(int keynum, double value, int abs) {
if(player_isFlag(PLAYER_TURN_LEFT)) { player_turn -= 1; }
if(player_isFlag(PLAYER_TURN_RIGHT)) { player_turn += 1; }
}
}
}
// Shoot primary weapon. BOOM BOOM.
else if(KEY("primary")) {
if(value == KEY_PRESS) { player_setFlag(PLAYER_PRIMARY); }
@ -224,9 +224,9 @@ static void input_key(int keynum, double value, int abs) {
else if(KEY("thyperspace") && INGAME() && NOHYP()) {
if(value == KEY_PRESS) player_targetHyperspace();
}
else if(KEY("starmap") && NOHYP()) {
if(value == KEY_PRESS) map_open();
}
else if(KEY("starmap") && NOHYP()) {
if(value == KEY_PRESS) map_open();
}
else if(KEY("jump") && INGAME()) {
if(value == KEY_PRESS) player_jump();
}
@ -254,10 +254,10 @@ static void input_key(int keynum, double value, int abs) {
else if(KEY("menu")) {
if(value == KEY_PRESS) menu_small();
}
// Show pilot information.
else if(KEY("info") && NOHYP()) {
if(value == KEY_PRESS) menu_info();
}
// Show pilot information.
else if(KEY("info") && NOHYP()) {
if(value == KEY_PRESS) menu_info();
}
}
#undef KEY
@ -276,7 +276,7 @@ static void input_joyaxis(const unsigned int axis, const int value) {
int i;
for(i = 0; strcmp(keybindNames[i], "end"); i++)
if(input_keybinds[i]->type == KEYBIND_JAXIS &&
input_keybinds[i]->key == axis) {
input_keybinds[i]->key == axis) {
input_key(i, -(input_keybinds[i]->reverse) * (double)value / 32767., 1);
return;
}
@ -287,7 +287,7 @@ static void input_joydown(const unsigned int button) {
int i;
for(i = 0; strcmp(keybindNames[i], "end");i++)
if(input_keybinds[i]->type == KEYBIND_JBUTTON &&
input_keybinds[i]->key == button) {
input_keybinds[i]->key == button) {
input_key(i, KEY_RELEASE, 0);
return;
}
@ -298,7 +298,7 @@ static void input_joyup(const unsigned int button) {
int i;
for(i = 0; strcmp(keybindNames[i], "end"); i++)
if(input_keybinds[i]->type == KEYBIND_JBUTTON &&
input_keybinds[i]->key == button) {
input_keybinds[i]->key == button) {
input_key(i, KEY_RELEASE, 0);
return;
}
@ -311,7 +311,7 @@ static void input_keydown(SDLKey key) {
int i;
for(i = 0; strcmp(keybindNames[i], "end"); i++)
if(input_keybinds[i]->type == KEYBIND_KEYBOARD &&
input_keybinds[i]->key == key) {
input_keybinds[i]->key == key) {
input_key(i, KEY_PRESS, 0);
return;
}
@ -322,7 +322,7 @@ static void input_keyup(SDLKey key) {
int i;
for(i = 0; strcmp(keybindNames[i], "end"); i++)
if(input_keybinds[i]->type == KEYBIND_KEYBOARD &&
input_keybinds[i]->key == key) {
input_keybinds[i]->key == key) {
input_key(i, KEY_RELEASE, 0);
return;
}
@ -332,10 +332,10 @@ static void input_keyup(SDLKey key) {
// Just seperates the event types.
void input_handle(SDL_Event* event) {
if(toolkit)
// Toolkit is handled seperately.
if(toolkit_input(event))
return; // We don't process it if toolkit grabs it.
if(toolkit)
// Toolkit is handled seperately.
if(toolkit_input(event))
return; // We don't process it if toolkit grabs it.
switch(event->type) {
case SDL_JOYAXISMOTION:

View File

@ -3,10 +3,10 @@
// Input types.
typedef enum {
KEYBIND_NULL,
KEYBIND_KEYBOARD,
KEYBIND_JAXIS,
KEYBIND_JBUTTON
KEYBIND_NULL,
KEYBIND_KEYBOARD,
KEYBIND_JAXIS,
KEYBIND_JBUTTON
} KeybindType;
// Set input.

View File

@ -20,7 +20,7 @@ int joystick_get(char* namjoystick) {
int joystick_use(int indjoystick) {
if(indjoystick < 0 || indjoystick >= SDL_NumJoysticks()) {
WARN("Joystick of index number %d does not exist. Switching to default (0)",
indjoystick);
indjoystick);
indjoystick = 0;
}
if(joystick)
@ -31,7 +31,7 @@ int joystick_use(int indjoystick) {
joystick = SDL_JoystickOpen(indjoystick);
if(joystick == NULL) {
WARN("Error opening joystick %d [%s]",
indjoystick, SDL_JoystickName(indjoystick));
indjoystick, SDL_JoystickName(indjoystick));
return -1;
}
DEBUG("\t\tWith %d axes, %d buttons, %d balls, and %d hats",

View File

@ -18,12 +18,12 @@
#define COMMODITY_HEIGHT 400
// Outfits.
#define OUTFITS_WIDTH 700
#define OUTFITS_HEIGHT 600
#define OUTFITS_WIDTH 700
#define OUTFITS_HEIGHT 600
// Shipyard.
#define SHIPYARD_WIDTH 700
#define SHIPYARD_HEIGHT 600
#define SHIPYARD_WIDTH 700
#define SHIPYARD_HEIGHT 600
// News window.
#define NEWS_WIDTH 400
@ -33,8 +33,8 @@
#define BAR_WIDTH 460
#define BAR_HEIGHT 300
#define MUSIC_TAKEOFF "liftoff"
#define MUSIC_LAND "agriculture"
#define MUSIC_TAKEOFF "liftoff"
#define MUSIC_LAND "agriculture"
int landed = 0;
@ -55,7 +55,7 @@ static void outfits_close(char* str);
static void outfits_update(char* str);
static void outfits_buy(char* str);
static void outfits_sell(char* str);
static int outfits_getMod(void);
static int outfits_getMod(void);
static void outfits_renderMod(double bx, double by, double w, double h);
// Shipyard.
static void shipyard(void);
@ -72,43 +72,43 @@ static void news_close(char* str);
// The local market.
static void commodity_exchange(void) {
int i;
char** goods;
int i;
char** goods;
secondary_wid = window_create("Commodity Exchange", -1, -1,
COMMODITY_WIDTH, COMMODITY_HEIGHT);
COMMODITY_WIDTH, COMMODITY_HEIGHT);
window_addButton(secondary_wid, -20, 20,
BUTTON_WIDTH, BUTTON_HEIGHT, "btnCommodityClose",
"Close", commodity_exchange_close);
window_addButton(secondary_wid, -40-((BUTTON_WIDTH-20)/2), 20*2+BUTTON_HEIGHT,
(BUTTON_WIDTH-20)/2, BUTTON_HEIGHT, "btnCommodityBuy",
"Buy", commodity_buy);
window_addButton(secondary_wid, -40-((BUTTON_WIDTH-20)/2), 20*2+BUTTON_HEIGHT,
(BUTTON_WIDTH-20)/2, BUTTON_HEIGHT, "btnCommodityBuy",
"Buy", commodity_buy);
window_addButton(secondary_wid, -20, 20*2+BUTTON_HEIGHT,
(BUTTON_WIDTH-20)/2, BUTTON_HEIGHT, "btnCommoditySell",
"Sell", commodity_sell);
window_addButton(secondary_wid, -20, 20*2+BUTTON_HEIGHT,
(BUTTON_WIDTH-20)/2, BUTTON_HEIGHT, "btnCommoditySell",
"Sell", commodity_sell);
window_addText(secondary_wid, -20, -40, BUTTON_WIDTH, 20, 0,
"txtSInfo", &gl_smallFont, &cDConsole,
"You have:\n"
"Market price:\n");
window_addText(secondary_wid, -20, -40, BUTTON_WIDTH, 20, 0,
"txtSInfo", &gl_smallFont, &cDConsole,
"You have:\n"
"Market price:\n");
window_addText(secondary_wid, -20, -40, BUTTON_WIDTH/2, 20, 0,
"txtDInfo", &gl_smallFont, &cBlack, NULL);
window_addText(secondary_wid, -20, -40, BUTTON_WIDTH/2, 20, 0,
"txtDInfo", &gl_smallFont, &cBlack, NULL);
window_addText(secondary_wid, -40, -80, BUTTON_WIDTH-20,
BUTTON_WIDTH, 0, "txtDesc", &gl_smallFont, &cBlack, NULL);
window_addText(secondary_wid, -40, -80, BUTTON_WIDTH-20,
BUTTON_WIDTH, 0, "txtDesc", &gl_smallFont, &cBlack, NULL);
goods = malloc(sizeof(char*)*planet->ncommodities);
for(i = 0; i < planet->ncommodities; i++)
goods[i] = strdup(planet->commodities[i]->name);
goods = malloc(sizeof(char*)*planet->ncommodities);
for(i = 0; i < planet->ncommodities; i++)
goods[i] = strdup(planet->commodities[i]->name);
window_addList(secondary_wid, 20, -40,
COMMODITY_WIDTH-BUTTON_WIDTH-60, COMMODITY_HEIGHT-80-BUTTON_HEIGHT,
"lstGoods", goods, planet->ncommodities, 0, commodity_update);
window_addList(secondary_wid, 20, -40,
COMMODITY_WIDTH-BUTTON_WIDTH-60, COMMODITY_HEIGHT-80-BUTTON_HEIGHT,
"lstGoods", goods, planet->ncommodities, 0, commodity_update);
commodity_update(NULL);
commodity_update(NULL);
}
static void commodity_exchange_close(char* str) {
@ -117,356 +117,356 @@ static void commodity_exchange_close(char* str) {
}
static void commodity_update(char* str) {
(void)str;
char buf[128];
char* comname;
Commodity* com;
(void)str;
char buf[128];
char* comname;
Commodity* com;
comname = toolkit_getList(secondary_wid, "lstGoods");
com = commodity_get(comname);
comname = toolkit_getList(secondary_wid, "lstGoods");
com = commodity_get(comname);
snprintf(buf, 128,
"%d\n"
"%d Screds/ton\n",
player_cargoOwned(comname),
com->medium);
snprintf(buf, 128,
"%d\n"
"%d Screds/ton\n",
player_cargoOwned(comname),
com->medium);
window_modifyText(secondary_wid, "txtDInfo", buf);
window_modifyText(secondary_wid, "txtDesc", com->description);
window_modifyText(secondary_wid, "txtDInfo", buf);
window_modifyText(secondary_wid, "txtDesc", com->description);
}
static void commodity_buy(char* str) {
(void)str;
char* comname;
Commodity* com;
int q;
(void)str;
char* comname;
Commodity* com;
int q;
q = 10;
q = 10;
comname = toolkit_getList(secondary_wid, "lstGoods");
com = commodity_get(comname);
comname = toolkit_getList(secondary_wid, "lstGoods");
com = commodity_get(comname);
if(player_credits <= q * com->medium) {
toolkit_alert("Not enough Scred!");
return;
}
else if(player->cargo_free <= 0) {
toolkit_alert("not enough free space!");
return;
}
if(player_credits <= q * com->medium) {
toolkit_alert("Not enough Scred!");
return;
}
else if(player->cargo_free <= 0) {
toolkit_alert("not enough free space!");
return;
}
q = pilot_addCargo(player, com, q);
player_credits -= q * com->medium;
commodity_update(NULL);
q = pilot_addCargo(player, com, q);
player_credits -= q * com->medium;
commodity_update(NULL);
}
static void commodity_sell(char* str) {
(void)str;
char* comname;
Commodity* com;
int q;
(void)str;
char* comname;
Commodity* com;
int q;
q = 10;
comname = toolkit_getList(secondary_wid, "lstGoods");
com = commodity_get(comname);
q = 10;
comname = toolkit_getList(secondary_wid, "lstGoods");
com = commodity_get(comname);
q = pilot_rmCargo(player, com, q);
player_credits += q * com->medium;
commodity_update(NULL);
q = pilot_rmCargo(player, com, q);
player_credits += q * com->medium;
commodity_update(NULL);
}
static void outfits(void) {
char** outfits;
int noutfits;
char buf[128];
char** outfits;
int noutfits;
char buf[128];
snprintf(buf, 128, "%s - Outfits", planet->name);
secondary_wid = window_create(buf, -1, -1,
OUTFITS_WIDTH, OUTFITS_HEIGHT);
snprintf(buf, 128, "%s - Outfits", planet->name);
secondary_wid = window_create(buf, -1, -1,
OUTFITS_WIDTH, OUTFITS_HEIGHT);
window_addButton(secondary_wid, -20, 20,
BUTTON_WIDTH, BUTTON_HEIGHT, "btnCloseOutfits",
"Close", outfits_close);
window_addButton(secondary_wid, -20, 20,
BUTTON_WIDTH, BUTTON_HEIGHT, "btnCloseOutfits",
"Close", outfits_close);
window_addButton(secondary_wid, -40-BUTTON_WIDTH, 20,
BUTTON_WIDTH, BUTTON_HEIGHT, "btnBuyOutfits",
"Buy", outfits_buy);
window_addButton(secondary_wid, -40-BUTTON_WIDTH, 20,
BUTTON_WIDTH, BUTTON_HEIGHT, "btnBuyOutfits",
"Buy", outfits_buy);
window_addButton(secondary_wid, -40-BUTTON_WIDTH, 40+BUTTON_HEIGHT,
BUTTON_WIDTH, BUTTON_HEIGHT, "btnSellOutfit",
"Sell", outfits_sell);
window_addButton(secondary_wid, -40-BUTTON_WIDTH, 40+BUTTON_HEIGHT,
BUTTON_WIDTH, BUTTON_HEIGHT, "btnSellOutfit",
"Sell", outfits_sell);
// Fancy 128x128 image.
window_addRect(secondary_wid, -20, -50, 128, 128, "rctImage", &cBlack, 0);
window_addImage(secondary_wid, -20-128, -50-128, "imgOutfit", NULL);
// Fancy 128x128 image.
window_addRect(secondary_wid, -20, -50, 128, 128, "rctImage", &cBlack, 0);
window_addImage(secondary_wid, -20-128, -50-128, "imgOutfit", NULL);
window_addCust(secondary_wid, -40-BUTTON_WIDTH, 60+2*BUTTON_HEIGHT,
BUTTON_WIDTH, BUTTON_HEIGHT, "cstMod", 0, outfits_renderMod, NULL);
window_addCust(secondary_wid, -40-BUTTON_WIDTH, 60+2*BUTTON_HEIGHT,
BUTTON_WIDTH, BUTTON_HEIGHT, "cstMod", 0, outfits_renderMod, NULL);
window_addText(secondary_wid, 40+200+20, -60,
80, 96, 0, "txtSDesc", &gl_smallFont, &cDConsole,
"Name:\n"
"Type:\n"
"Owned:\n"
"\n"
"Space taken:\n"
"Free Space:\n"
"\n"
"Price:\n"
"Money:\n");
window_addText(secondary_wid, 40+200+20, -60,
80, 96, 0, "txtSDesc", &gl_smallFont, &cDConsole,
"Name:\n"
"Type:\n"
"Owned:\n"
"\n"
"Space taken:\n"
"Free Space:\n"
"\n"
"Price:\n"
"Money:\n");
window_addText(secondary_wid, 40+200+40+60, -60,
250, 96, 0, "txtDDesc", &gl_smallFont, &cBlack, NULL);
window_addText(secondary_wid, 40+200+40+60, -60,
250, 96, 0, "txtDDesc", &gl_smallFont, &cBlack, NULL);
window_addText(secondary_wid, 20+200+40, -200,
OUTFITS_WIDTH-300, 200, 0, "txtDescription",
&gl_smallFont, NULL, NULL);
window_addText(secondary_wid, 20+200+40, -200,
OUTFITS_WIDTH-300, 200, 0, "txtDescription",
&gl_smallFont, NULL, NULL);
// Set up the outfits to buy/sell.
outfits = outfit_getTech(&noutfits, planet->tech, PLANET_TECH_MAX);
window_addList(secondary_wid, 20, 40,
200, OUTFITS_HEIGHT-80, "lstOutfits",
outfits, noutfits, 0, outfits_update);
// Set up the outfits to buy/sell.
outfits = outfit_getTech(&noutfits, 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.
outfits_update(NULL);
// Write the outfits stuff.
outfits_update(NULL);
}
static void outfits_close(char* str) {
if(strcmp(str, "btnCloseOutfits")==0)
window_destroy(secondary_wid);
if(strcmp(str, "btnCloseOutfits")==0)
window_destroy(secondary_wid);
}
static void outfits_update(char* str) {
(void)str;
char* outfitname;
Outfit* outfit;
char buf[80], buf2[16], buf3[16];
(void)str;
char* outfitname;
Outfit* outfit;
char buf[80], buf2[16], buf3[16];
outfitname = toolkit_getList(secondary_wid, "lstOutfits");
outfit = outfit_get(outfitname);
outfitname = toolkit_getList(secondary_wid, "lstOutfits");
outfit = outfit_get(outfitname);
window_modifyImage(secondary_wid, "imgOutfit", outfit->gfx_store);
window_modifyImage(secondary_wid, "imgOutfit", outfit->gfx_store);
window_modifyText(secondary_wid, "txtDescription", outfit->description);
credits2str(buf2, outfit->price, 2);
credits2str(buf3, player_credits, 2);
snprintf(buf, 80,
"%s\n"
"%s\n"
"%d\n"
"\n"
"%d\n"
"%d\n"
"\n"
"%s SCred\n"
"%s SCred\n",
outfit->name,
outfit_getType(outfit),
player_outfitOwned(outfitname),
outfit->mass,
player_freeSpace(),
buf2,
buf3);
window_modifyText(secondary_wid, "txtDescription", outfit->description);
credits2str(buf2, outfit->price, 2);
credits2str(buf3, player_credits, 2);
snprintf(buf, 80,
"%s\n"
"%s\n"
"%d\n"
"\n"
"%d\n"
"%d\n"
"\n"
"%s SCred\n"
"%s SCred\n",
outfit->name,
outfit_getType(outfit),
player_outfitOwned(outfitname),
outfit->mass,
player_freeSpace(),
buf2,
buf3);
window_modifyText(secondary_wid, "txtDDesc", buf);
window_modifyText(secondary_wid, "txtDDesc", buf);
}
static void outfits_buy(char* str) {
(void)str;
char* outfitname;
Outfit* outfit;
int q;
char buf[16];
(void)str;
char* outfitname;
Outfit* outfit;
int q;
char buf[16];
outfitname = toolkit_getList(secondary_wid, "lstOutfits");
outfit = outfit_get(outfitname);
outfitname = toolkit_getList(secondary_wid, "lstOutfits");
outfit = outfit_get(outfitname);
q = outfits_getMod();
q = outfits_getMod();
// Can player actually fit the outfit?
if((player_freeSpace() - outfit->mass) < 0) {
toolkit_alert("No enough free space (you need %d more slots).",
outfit->mass - player_freeSpace());
return;
}
else if(player_outfitOwned(outfitname) >= outfit->max) {
// Already has too many.
toolkit_alert("You can only carry %d of this outfit.", outfit->max);
return;
}
else if(outfit_isAfterburner(outfit) && (player->afterburner != NULL)) {
toolkit_alert("You can only have one afterburner.");
return;
}
// Not enough $$.
else if(q*(int)outfit->price >= player_credits) {
credits2str(buf, q*outfit->price - player_credits, 2);
toolkit_alert("You need %s more SCred.", buf);
return;
}
// Can player actually fit the outfit?
if((player_freeSpace() - outfit->mass) < 0) {
toolkit_alert("No enough free space (you need %d more slots).",
outfit->mass - player_freeSpace());
return;
}
else if(player_outfitOwned(outfitname) >= outfit->max) {
// Already has too many.
toolkit_alert("You can only carry %d of this outfit.", outfit->max);
return;
}
else if(outfit_isAfterburner(outfit) && (player->afterburner != NULL)) {
toolkit_alert("You can only have one afterburner.");
return;
}
// Not enough $$.
else if(q*(int)outfit->price >= player_credits) {
credits2str(buf, q*outfit->price - player_credits, 2);
toolkit_alert("You need %s more SCred.", buf);
return;
}
player_credits -= outfit->price * pilot_addOutfit(player, outfit,
MIN(q, outfit->max));
outfits_update(NULL);
player_credits -= outfit->price * pilot_addOutfit(player, outfit,
MIN(q, outfit->max));
outfits_update(NULL);
}
static void outfits_sell(char* str) {
(void)str;
char* outfitname;
Outfit* outfit;
int q;
(void)str;
char* outfitname;
Outfit* outfit;
int q;
outfitname = toolkit_getList(secondary_wid, "lstOutfits");
outfit = outfit_get(outfitname);
outfitname = toolkit_getList(secondary_wid, "lstOutfits");
outfit = outfit_get(outfitname);
q = outfits_getMod();
q = outfits_getMod();
if(player_outfitOwned(outfitname) <= 0) {
// No outfits to sell.
toolkit_alert("You can't sell something you don't have!");
return;
}
if(player_outfitOwned(outfitname) <= 0) {
// No outfits to sell.
toolkit_alert("You can't sell something you don't have!");
return;
}
player_credits += outfit->price * pilot_rmOutfit(player, outfit, q);
outfits_update(NULL);
player_credits += outfit->price * pilot_rmOutfit(player, outfit, q);
outfits_update(NULL);
}
// Return the current modifier status.
static int outfits_getMod(void) {
SDLMod mods;
int q;
SDLMod mods;
int q;
mods = SDL_GetModState();
q = 1;
if(mods & (KMOD_LCTRL | KMOD_RCTRL)) q *= 5;
if(mods & (KMOD_LSHIFT | KMOD_RSHIFT)) q *= 10;
mods = SDL_GetModState();
q = 1;
if(mods & (KMOD_LCTRL | KMOD_RCTRL)) q *= 5;
if(mods & (KMOD_LSHIFT | KMOD_RSHIFT)) q *= 10;
return q;
return q;
}
static void outfits_renderMod(double bx, double by, double w, double h) {
(void) h;
int q;
char buf[8];
(void) h;
int q;
char buf[8];
q = outfits_getMod();
if(q == 1) return;
q = outfits_getMod();
if(q == 1) return;
snprintf(buf, 8, "%dx", q);
gl_printMid(&gl_smallFont, w,
bx + (double)gl_screen.w/2.,
by + (double)gl_screen.h/2.,
&cBlack, buf);
snprintf(buf, 8, "%dx", q);
gl_printMid(&gl_smallFont, w,
bx + (double)gl_screen.w/2.,
by + (double)gl_screen.h/2.,
&cBlack, buf);
}
static void shipyard(void) {
char** ships;
int nships;
char buf[128];
char** ships;
int nships;
char buf[128];
snprintf(buf, 128, "%s - Shipyard", planet->name);
secondary_wid = window_create(buf,
-1, -1, SHIPYARD_WIDTH, SHIPYARD_HEIGHT);
snprintf(buf, 128, "%s - Shipyard", planet->name);
secondary_wid = window_create(buf,
-1, -1, SHIPYARD_WIDTH, SHIPYARD_HEIGHT);
window_addButton(secondary_wid, -20, 20,
BUTTON_WIDTH, BUTTON_HEIGHT, "btnCloseShipyard",
"Close", shipyard_close);
window_addButton(secondary_wid, -20, 20,
BUTTON_WIDTH, BUTTON_HEIGHT, "btnCloseShipyard",
"Close", shipyard_close);
window_addButton(secondary_wid, -40-BUTTON_WIDTH, 20,
BUTTON_WIDTH, BUTTON_HEIGHT, "btnBuyShip",
"Buy", shipyard_buy);
window_addButton(secondary_wid, -40-BUTTON_WIDTH, 20,
BUTTON_WIDTH, BUTTON_HEIGHT, "btnBuyShip",
"Buy", shipyard_buy);
window_addButton(secondary_wid, -40-BUTTON_WIDTH, 40+BUTTON_HEIGHT,
BUTTON_WIDTH, BUTTON_HEIGHT, "btnInfoShip",
"Info", shipyard_info);
window_addButton(secondary_wid, -40-BUTTON_WIDTH, 40+BUTTON_HEIGHT,
BUTTON_WIDTH, BUTTON_HEIGHT, "btnInfoShip",
"Info", shipyard_info);
window_addRect(secondary_wid, -40, -50,
128, 96, "rctTarget", &cBlack, 0);
window_addRect(secondary_wid, -40, -50,
128, 96, "rctTarget", &cBlack, 0);
window_addImage(secondary_wid, -40-128, -50-96,
"imgTarget", NULL);
window_addImage(secondary_wid, -40-128, -50-96,
"imgTarget", NULL);
window_addText(secondary_wid, 40+200+40, -55,
80, 96, 0, "txtSDesc", &gl_smallFont, &cDConsole,
"Name:\n"
"Class:\n"
"Fabricator:\n"
"\n"
"Price:\n"
"Money:\n");
window_addText(secondary_wid, 40+200+40, -55,
80, 96, 0, "txtSDesc", &gl_smallFont, &cDConsole,
"Name:\n"
"Class:\n"
"Fabricator:\n"
"\n"
"Price:\n"
"Money:\n");
window_addText(secondary_wid, 40+200+40+80, -55,
130, 96, 0, "txtDDesc", &gl_smallFont, &cBlack, NULL);
window_addText(secondary_wid, 40+200+40+80, -55,
130, 96, 0, "txtDDesc", &gl_smallFont, &cBlack, NULL);
window_addText(secondary_wid, 20+200+40, -160,
SHIPYARD_WIDTH-300, 200, 0, "txtDescription",
&gl_smallFont, NULL, NULL);
window_addText(secondary_wid, 20+200+40, -160,
SHIPYARD_WIDTH-300, 200, 0, "txtDescription",
&gl_smallFont, NULL, NULL);
// Setup the ships to buy/sell.
ships = ship_getTech(&nships, planet->tech, PLANET_TECH_MAX);
window_addList(secondary_wid, 20, 40,
200, SHIPYARD_HEIGHT-80, "lstShipyard",
ships, nships, 0, shipyard_update);
// Setup the ships to buy/sell.
ships = ship_getTech(&nships, 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.
shipyard_update(NULL);
// Write the shipyard stuff.
shipyard_update(NULL);
}
static void shipyard_close(char* str) {
if(strcmp(str, "btnCloseShipyard")==0)
window_destroy(secondary_wid);
if(strcmp(str, "btnCloseShipyard")==0)
window_destroy(secondary_wid);
}
static void shipyard_update(char* str) {
(void)str;
char* shipname;
Ship* ship;
char buf[80], buf2[16], buf3[16];
(void)str;
char* shipname;
Ship* ship;
char buf[80], buf2[16], buf3[16];
shipname = toolkit_getList(secondary_wid, "lstShipyard");
ship = ship_get(shipname);
shipname = toolkit_getList(secondary_wid, "lstShipyard");
ship = ship_get(shipname);
window_modifyText(secondary_wid, "txtDescription", ship->description);
window_modifyImage(secondary_wid, "imgTarget", ship->gfx_target);
window_modifyText(secondary_wid, "txtDescription", ship->description);
window_modifyImage(secondary_wid, "imgTarget", ship->gfx_target);
credits2str(buf2, ship->price, 2);
credits2str(buf3, player_credits, 2);
snprintf(buf, 80,
"%s\n"
"%s\n"
"%s\n"
"\n"
"%s SCred\n"
"%s SCred\n",
ship->name,
ship_class(ship),
ship->fabricator,
buf2,
buf3);
credits2str(buf2, ship->price, 2);
credits2str(buf3, player_credits, 2);
snprintf(buf, 80,
"%s\n"
"%s\n"
"%s\n"
"\n"
"%s SCred\n"
"%s SCred\n",
ship->name,
ship_class(ship),
ship->fabricator,
buf2,
buf3);
window_modifyText(secondary_wid, "txtDDesc", buf);
window_modifyText(secondary_wid, "txtDDesc", buf);
}
static void shipyard_info(char* str) {
(void)str;
char* shipname;
(void)str;
char* shipname;
shipname = toolkit_getList(secondary_wid, "lstShipyard");
ship_view(shipname);
shipname = toolkit_getList(secondary_wid, "lstShipyard");
ship_view(shipname);
}
static void shipyard_buy(char* str) {
(void)str;
char* shipname;
Ship* ship;
(void)str;
char* shipname;
Ship* ship;
shipname = toolkit_getList(secondary_wid, "lstShipyard");
ship = ship_get(shipname);
shipname = toolkit_getList(secondary_wid, "lstShipyard");
ship = ship_get(shipname);
player_newShip(ship);
player_newShip(ship);
}
// Spaceport bar.
@ -480,9 +480,9 @@ static void spaceport_bar(void) {
window_addButton(secondary_wid, -20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
"btnCloseBar", "Close", spaceport_bar_close);
window_addButton(secondary_wid, 20, 20,
BUTTON_WIDTH, BUTTON_HEIGHT, "btnNews",
"News", (void(*)(char*))news);
window_addButton(secondary_wid, 20, 20,
BUTTON_WIDTH, BUTTON_HEIGHT, "btnNews",
"News", (void(*)(char*))news);
}
static void spaceport_bar_close(char* str) {
@ -492,9 +492,9 @@ static void spaceport_bar_close(char* str) {
// Planet news reports.
static void news(void) {
unsigned int news_wid;
news_wid = window_create("News Reports",
-1, -1, NEWS_WIDTH, NEWS_HEIGHT);
unsigned int news_wid;
news_wid = window_create("News Reports",
-1, -1, NEWS_WIDTH, NEWS_HEIGHT);
window_addText(news_wid, 20, 20 + BUTTON_HEIGHT + 20,
NEWS_WIDTH-40, NEWS_HEIGHT - 20 - BUTTON_HEIGHT - 20 - 20 -20,
@ -502,7 +502,7 @@ static void news(void) {
"News reporters report that they are on strike right now! D:");
window_addButton(news_wid, -20, 20,
BUTTON_WIDTH, BUTTON_HEIGHT,
BUTTON_WIDTH, BUTTON_HEIGHT,
"btnCloseNews", "Close", news_close);
}
@ -515,9 +515,9 @@ static void news_close(char* str) {
void land(Planet* p) {
if(landed) return;
// Change music.
music_load(MUSIC_LAND);
music_play();
// Change music.
music_load(MUSIC_LAND);
music_play();
planet = p;
land_wid = window_create(p->name, -1, -1, LAND_WIDTH, LAND_HEIGHT);
@ -552,7 +552,7 @@ void land(Planet* p) {
window_addButton(land_wid, 20, 20 + BUTTON_HEIGHT + 20,
BUTTON_WIDTH, BUTTON_HEIGHT, "btnBar",
"Spaceport Bar", (void(*)(char*))spaceport_bar);
}
}
landed = 1;
@ -562,15 +562,15 @@ void land(Planet* p) {
void takeoff(void) {
if(!landed) return;
music_load(MUSIC_TAKEOFF);
music_play();
music_load(MUSIC_TAKEOFF);
music_play();
int sw, sh;
sw = planet->gfx_space->w;
sh = planet->gfx_space->h;
// No longer authorized to land.
player_rmFlag(PLAYER_LANDACK);
// No longer authorized to land.
player_rmFlag(PLAYER_LANDACK);
// Set player to another position with random facing direction and no velocity.
player_warp(planet->pos.x + RNG(-sw/2, sw/2), planet->pos.y + RNG(-sh/2, sh/2));
@ -580,7 +580,7 @@ void takeoff(void) {
// Heal the player.
player->armour = player->armour_max;
player->shield = player->shield_max;
player->energy = player->energy_max;
player->energy = player->energy_max;
space_init(NULL);

View File

@ -65,7 +65,7 @@ static void render_space(void);
#ifdef WIN32
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine,
int nCmdShow) {
int nCmdShow) {
int argc = 0;
char *argv[] = { NULL };
#else
@ -113,14 +113,14 @@ int main(int argc, char** argv) {
window_caption();
// OpenAL sound.
if(nosound)
LOG("Sound is disabled!");
else {
if(sound_init()) WARN("Problem setting up sound!");
music_load("Machina");
music_play();
}
// OpenAL sound.
if(nosound)
LOG("Sound is disabled!");
else {
if(sound_init()) WARN("Problem setting up sound!");
music_load("Machina");
music_play();
}
// Input.
if((indjoystick >= 0) || (namjoystick != NULL)) {
@ -153,15 +153,15 @@ int main(int argc, char** argv) {
toolkit_init(); // Init the toolkit.
// Data loading.
commodity_load();
commodity_load();
factions_load();
spfx_load();
spfx_load();
outfit_load();
ships_load();
fleet_load();
space_load();
menu_main();
menu_main();
gtime = SDL_GetTicks(); // Init the time.
@ -187,17 +187,17 @@ int main(int argc, char** argv) {
input_handle(&event); // handles all the events the player keybinds.
}
sound_update(); // Do the sound stuff.
sound_update(); // Do the sound stuff.
glClear(GL_COLOR_BUFFER_BIT);
fps_control(); // Who doesn't love FPS control?
toolkit_update(); // Simulate key repetition.
toolkit_update(); // Simulate key repetition.
if(!menu_isOpen(MENU_MAIN)) {
if(!paused && !toolkit) update_space(); // Update the game.
render_space();
}
if(!menu_isOpen(MENU_MAIN)) {
if(!paused && !toolkit) update_space(); // Update the game.
render_space();
}
if(toolkit) toolkit_render();
@ -212,11 +212,11 @@ int main(int argc, char** argv) {
fleet_free();
ships_free();
outfit_free();
spfx_free(); // Remove the special effects.
spfx_free(); // Remove the special effects.
factions_free();
commodity_free();
commodity_free();
gl_freeFont(NULL);
gl_freeFont(&gl_smallFont);
gl_freeFont(&gl_smallFont);
// Exit subsystems.
toolkit_exit(); // Kill the toolkit.
@ -224,8 +224,8 @@ int main(int argc, char** argv) {
joystick_exit(); // Release joystick.
input_exit(); // Clean up keybindings.
gl_exit(); // Kills video output.
sound_exit(); // Kills the sound.
SDL_Quit(); // Quits SDL.
sound_exit(); // Kills the sound.
SDL_Quit(); // Quits SDL.
// All is good.
exit(EXIT_SUCCESS);
@ -251,14 +251,14 @@ static void fps_control(void) {
// Update the game.
static void update_space(void) {
if(dt > 1./30.) {
// Slow timers down and re-run calculations.
pause_delay((unsigned int)dt*1000.);
return;
}
space_update(dt);
if(dt > 1./30.) {
// Slow timers down and re-run calculations.
pause_delay((unsigned int)dt*1000.);
return;
}
space_update(dt);
weapons_update(dt);
spfx_update(dt);
spfx_update(dt);
pilots_update(dt);
}
@ -287,10 +287,10 @@ static void render_space(void) {
// N.
pilots_render();
weapons_render(WEAPON_LAYER_FG);
spfx_render(SPFX_LAYER_BACK);
spfx_render(SPFX_LAYER_BACK);
// FG.
player_render();
spfx_render(SPFX_LAYER_FRONT);
spfx_render(SPFX_LAYER_FRONT);
display_fps(dt);
}

View File

@ -5,12 +5,12 @@
#define MALLOC_L(type)(malloc(sizeof(type)))
#define CALLOC_L(type)(calloc(1, sizeof(type)))
#define ABS(x) (((x)<0)?-(x):(x))
#define ABS(x) (((x)<0)?-(x):(x))
#define MAX(x,y) (((x)>(y))?(x):(y))
#define MIN(x,y) (((x)>(y))?(y):(x))
#define pow2(x) ((x)*(x))
#define pow2(x) ((x)*(x))
#define DATA_DEF "data" // Default data packfile.
extern char* data; // Modifiable datafile.

View File

@ -4,7 +4,7 @@
#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", \
__FILE__, __LINE__, ## args))
__FILE__, __LINE__, ## args))
#ifdef DEBUG
# undef DEBUG

388
src/map.c
View File

@ -5,19 +5,19 @@
#include "opengl.h"
#include "map.h"
#define WINDOW_WIDTH 550
#define WINDOW_HEIGHT 440
#define WINDOW_WIDTH 550
#define WINDOW_HEIGHT 440
#define MAP_WIDTH (WINDOW_WIDTH-150)
#define MAP_HEIGHT (WINDOW_HEIGHT-100)
#define MAP_WIDTH (WINDOW_WIDTH-150)
#define MAP_HEIGHT (WINDOW_HEIGHT-100)
#define BUTTON_WIDTH 60
#define BUTTON_HEIGHT 40
#define BUTTON_WIDTH 60
#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_ypos = 0.;
static int map_wid = 0;
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 = 0;
static int map_drag = 0; // Is the user dragging the map?
@ -38,235 +38,235 @@ static void map_buttonZoom(char* str);
// Open the map window.
void map_open(void) {
if(map_wid) {
map_close(NULL);
return;
}
if(map_wid) {
map_close(NULL);
return;
}
// Set the position to focus on current system.
map_xpos = cur_system->pos.x;
map_ypos = cur_system->pos.y;
// Set the position to focus on current system.
map_xpos = cur_system->pos.x;
map_ypos = cur_system->pos.y;
map_wid = window_create("Star Map", -1, -1, WINDOW_WIDTH, WINDOW_HEIGHT);
map_wid = window_create("Star Map", -1, -1, WINDOW_WIDTH, WINDOW_HEIGHT);
window_addText(map_wid, -20, -20, 100, 20, 1, "txtSysname",
&gl_defFont, &cDConsole, systems_stack[map_selected].name);
window_addText(map_wid, -20, -20, 100, 20, 1, "txtSysname",
&gl_defFont, &cDConsole, systems_stack[map_selected].name);
window_addText(map_wid, -20, -60, 90, 20, 0, "txtSFaction",
&gl_smallFont, &cDConsole, "Faction:");
window_addText(map_wid, -20, -60, 90, 20, 0, "txtSFaction",
&gl_smallFont, &cDConsole, "Faction:");
window_addText(map_wid, -20, -60-gl_smallFont.h-5, 80, 100, 0, "txtFaction",
&gl_smallFont, &cBlack, NULL);
window_addText(map_wid, -20, -60-gl_smallFont.h-5, 80, 100, 0, "txtFaction",
&gl_smallFont, &cBlack, NULL);
window_addText(map_wid, -20, -110, 90, 20, 0, "txtSPlanets",
&gl_smallFont, &cDConsole, "Planets:");
window_addText(map_wid, -20, -110, 90, 20, 0, "txtSPlanets",
&gl_smallFont, &cDConsole, "Planets:");
window_addText(map_wid, -20, -110-gl_smallFont.h-5, 80, 100, 0, "txtPlanets",
&gl_smallFont, &cBlack, NULL);
window_addText(map_wid, -20, -110-gl_smallFont.h-5, 80, 100, 0, "txtPlanets",
&gl_smallFont, &cBlack, NULL);
window_addCust(map_wid, 20, -40, MAP_WIDTH, MAP_HEIGHT,
"cstMap", 1, map_render, map_mouse);
window_addCust(map_wid, 20, -40, MAP_WIDTH, MAP_HEIGHT,
"cstMap", 1, map_render, map_mouse);
window_addButton(map_wid, -20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
"btnClose", "Close", map_close);
window_addButton(map_wid, -20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
"btnClose", "Close", map_close);
window_addButton(map_wid, 40, 20, 30, 30, "btnZoomIn", "+", map_buttonZoom);
window_addButton(map_wid, 80, 20, 30, 30, "btnZoomOut", "-", map_buttonZoom);
window_addButton(map_wid, 40, 20, 30, 30, "btnZoomIn", "+", map_buttonZoom);
window_addButton(map_wid, 80, 20, 30, 30, "btnZoomOut", "-", map_buttonZoom);
map_update();
map_update();
}
static void map_close(char* str) {
(void)str;
if(map_wid) {
window_destroy(map_wid);
map_wid = 0;
}
(void)str;
if(map_wid) {
window_destroy(map_wid);
map_wid = 0;
}
}
static void map_update(void) {
int i;
StarSystem* sys;
Faction* f;
char buf[100];
int i;
StarSystem* sys;
Faction* f;
char buf[100];
sys = &systems_stack[map_selected];
sys = &systems_stack[map_selected];
window_modifyText(map_wid, "txtSysname", sys->name);
window_modifyText(map_wid, "txtSysname", sys->name);
if(sys->nplanets == 0)
// No planets -> no factions.
snprintf(buf, 100, "NA");
else {
f = NULL;
for(i = 0; i < sys->nplanets; i++) {
if(f == NULL)
f = sys->planets[i].faction;
else if(f != sys->planets[i].faction) {
// TODO: more verbosity.
snprintf(buf, 100, "Multiple");
break;
}
}
if(i == sys->nplanets)
// Saw them all, and all the same.
snprintf(buf, 100, "%s", f->name);
}
if(sys->nplanets == 0)
// No planets -> no factions.
snprintf(buf, 100, "NA");
else {
f = NULL;
for(i = 0; i < sys->nplanets; i++) {
if(f == NULL)
f = sys->planets[i].faction;
else if(f != sys->planets[i].faction) {
// TODO: more verbosity.
snprintf(buf, 100, "Multiple");
break;
}
}
if(i == sys->nplanets)
// Saw them all, and all the same.
snprintf(buf, 100, "%s", f->name);
}
window_modifyText(map_wid, "txtFaction", buf);
window_modifyText(map_wid, "txtFaction", buf);
buf[0] = '\0';
if(sys->nplanets == 0)
snprintf(buf, 100, "None");
else {
for(i = 0; i < sys->nplanets; i++) {
strcat(buf, sys->planets[i].name);
strcat(buf, "\n");
}
}
window_modifyText(map_wid, "txtPlanets", buf);
buf[0] = '\0';
if(sys->nplanets == 0)
snprintf(buf, 100, "None");
else {
for(i = 0; i < sys->nplanets; i++) {
strcat(buf, sys->planets[i].name);
strcat(buf, "\n");
}
}
window_modifyText(map_wid, "txtPlanets", buf);
}
// Render the map as a custom widget.
static void map_render(double bx, double by, double w, double h) {
int i, j;
double x, y, r, tx, ty;
StarSystem* sys;
glColour* col;
int i, j;
double x, y, r, tx, ty;
StarSystem* sys;
glColour* col;
r = 5.;
x = (bx - map_xpos + w/2) * 1.; // Map zoom.
y = (by - map_ypos + h/2) * 1.; // Map zoom.
// Background
COLOUR(cBlack);
glBegin(GL_QUADS);
glVertex2d(bx, by);
glVertex2d(bx, by+h);
glVertex2d(bx+w, by+h);
glVertex2d(bx+w, by);
glEnd();
r = 5.;
x = (bx - map_xpos + w/2) * 1.; // Map zoom.
y = (by - map_ypos + h/2) * 1.; // Map zoom.
// Background
COLOUR(cBlack);
glBegin(GL_QUADS);
glVertex2d(bx, by);
glVertex2d(bx, by+h);
glVertex2d(bx+w, by+h);
glVertex2d(bx+w, by);
glEnd();
// Render the star systems.
for(i = 0; i < systems_nstack; i++) {
sys = &systems_stack[i];
// Render the star systems.
for(i = 0; i < systems_nstack; i++) {
sys = &systems_stack[i];
// Draw the system.
if(sys == cur_system) COLOUR(cRadar_targ);
else if(sys->nplanets==0) COLOUR(cInert); // TODO: dependant on planet type.
else if(areEnemies(player->faction, sys->faction)) COLOUR(cRed);
else COLOUR(cYellow);
// Draw the system.
if(sys == cur_system) COLOUR(cRadar_targ);
else if(sys->nplanets==0) COLOUR(cInert); // TODO: dependant on planet type.
else if(areEnemies(player->faction, sys->faction)) COLOUR(cRed);
else COLOUR(cYellow);
gl_drawCircleInRect(x + sys->pos.x*map_zoom,
y + sys->pos.y*map_zoom,
r, bx, by, w, h);
gl_drawCircleInRect(x + sys->pos.x*map_zoom,
y + sys->pos.y*map_zoom,
r, bx, by, w, h);
// Draw the system name.
tx = x + 7. + sys->pos.x * map_zoom;
ty = y - 5. + sys->pos.y * map_zoom;
if((map_zoom >= 1.) && // Can't be tiny.
((tx > bx) && (ty > by) && (ty < by+h-6.))) // Width checking.
gl_printMax(&gl_smallFont, (bx+w)-(tx),
tx + gl_screen.w/2., ty + gl_screen.h/2.,
&cWhite, sys->name);
// Draw the system name.
tx = x + 7. + sys->pos.x * map_zoom;
ty = y - 5. + sys->pos.y * map_zoom;
if((map_zoom >= 1.) && // Can't be tiny.
((tx > bx) && (ty > by) && (ty < by+h-6.))) // Width checking.
gl_printMax(&gl_smallFont, (bx+w)-(tx),
tx + gl_screen.w/2., ty + gl_screen.h/2.,
&cWhite, sys->name);
// Draw the hyperspace paths.
glShadeModel(GL_SMOOTH);
// Cheaply use transparency instead of actually
// calculating from x to y the line must go. :)
for(j = 0; j < sys->njumps; j++) {
// Set the colours, is the route the current one?
if(((cur_system == sys) && (j == hyperspace_target)) ||
((cur_system == &systems_stack[sys->jumps[j]]) &&
(sys = &systems_stack[cur_system->jumps[hyperspace_target]])))
col = &cRed;
else col = &cDarkBlue;
glBegin(GL_LINE_STRIP);
ACOLOUR(*col, 0.);
tx = x + sys->pos.x * map_zoom;
ty = y + sys->pos.y * map_zoom;
if(!((tx < bx) || (tx > bx + w) || (ty < by) || (ty > by+h)))
glVertex2d(tx, ty);
COLOUR(*col);
tx += (systems_stack[sys->jumps[j]].pos.x - sys->pos.x)/2. * map_zoom;
ty += (systems_stack[sys->jumps[j]].pos.y - sys->pos.y)/2. * map_zoom;
if(!((tx < bx) || (tx > bx+w) || (ty < by) || (ty > by+h)))
glVertex2d(tx, ty);
ACOLOUR(*col, 0.);
tx = x + systems_stack[sys->jumps[j]].pos.x * map_zoom;
ty = y + systems_stack[sys->jumps[j]].pos.y * map_zoom;
if(!((tx < bx) || (tx > bx+w) || (ty < by) || (ty > by+h)))
glVertex2d(tx, ty);
glEnd();
}
glShadeModel(GL_FLAT);
}
// Selected planet.
sys = &systems_stack[map_selected];
COLOUR(cRed);
gl_drawCircleInRect(x + sys->pos.x*map_zoom, y + sys->pos.y*map_zoom,
r+3., bx, by, w, h);
// Draw the hyperspace paths.
glShadeModel(GL_SMOOTH);
// Cheaply use transparency instead of actually
// calculating from x to y the line must go. :)
for(j = 0; j < sys->njumps; j++) {
// Set the colours, is the route the current one?
if(((cur_system == sys) && (j == hyperspace_target)) ||
((cur_system == &systems_stack[sys->jumps[j]]) &&
(sys = &systems_stack[cur_system->jumps[hyperspace_target]])))
col = &cRed;
else col = &cDarkBlue;
glBegin(GL_LINE_STRIP);
ACOLOUR(*col, 0.);
tx = x + sys->pos.x * map_zoom;
ty = y + sys->pos.y * map_zoom;
if(!((tx < bx) || (tx > bx + w) || (ty < by) || (ty > by+h)))
glVertex2d(tx, ty);
COLOUR(*col);
tx += (systems_stack[sys->jumps[j]].pos.x - sys->pos.x)/2. * map_zoom;
ty += (systems_stack[sys->jumps[j]].pos.y - sys->pos.y)/2. * map_zoom;
if(!((tx < bx) || (tx > bx+w) || (ty < by) || (ty > by+h)))
glVertex2d(tx, ty);
ACOLOUR(*col, 0.);
tx = x + systems_stack[sys->jumps[j]].pos.x * map_zoom;
ty = y + systems_stack[sys->jumps[j]].pos.y * map_zoom;
if(!((tx < bx) || (tx > bx+w) || (ty < by) || (ty > by+h)))
glVertex2d(tx, ty);
glEnd();
}
glShadeModel(GL_FLAT);
}
// Selected planet.
sys = &systems_stack[map_selected];
COLOUR(cRed);
gl_drawCircleInRect(x + sys->pos.x*map_zoom, y + sys->pos.y*map_zoom,
r+3., bx, by, w, h);
}
// Map event handling.
static void map_mouse(SDL_Event* event, double mx, double my) {
int i, j;
double x, y, t;
int i, j;
double x, y, t;
t = 13.*15.; // Threshold.
t = 13.*15.; // Threshold.
mx -= MAP_WIDTH/2 - map_xpos;
my -= MAP_HEIGHT/2 - map_ypos;
mx -= MAP_WIDTH/2 - map_xpos;
my -= MAP_HEIGHT/2 - map_ypos;
switch(event->type) {
case SDL_MOUSEBUTTONDOWN:
// Selecting star system.
if(event->button.button == SDL_BUTTON_LEFT) {
for(i = 0; i < systems_nstack; i++) {
x = systems_stack[i].pos.x * map_zoom;
y = systems_stack[i].pos.y * map_zoom;
switch(event->type) {
case SDL_MOUSEBUTTONDOWN:
// Selecting star system.
if(event->button.button == SDL_BUTTON_LEFT) {
for(i = 0; i < systems_nstack; i++) {
x = systems_stack[i].pos.x * map_zoom;
y = systems_stack[i].pos.y * map_zoom;
if((pow2(mx-x)+pow2(my-y)) < t) {
map_selected = i;
for(j = 0; j < cur_system->njumps; j++)
if(i == cur_system->jumps[j]) {
planet_target = -1; // Override planet target.
hyperspace_target = j;
break;
}
map_update();
break;
}
}
}
// Start dragging.
else if(event->button.button == SDL_BUTTON_RIGHT)
map_drag = 1;
break;
if((pow2(mx-x)+pow2(my-y)) < t) {
map_selected = i;
for(j = 0; j < cur_system->njumps; j++)
if(i == cur_system->jumps[j]) {
planet_target = -1; // Override planet target.
hyperspace_target = j;
break;
}
map_update();
break;
}
}
}
// Start dragging.
else if(event->button.button == SDL_BUTTON_RIGHT)
map_drag = 1;
break;
case SDL_MOUSEBUTTONUP:
if((event->button.button == SDL_BUTTON_RIGHT) && map_drag)
map_drag = 0;
break;
case SDL_MOUSEBUTTONUP:
if((event->button.button == SDL_BUTTON_RIGHT) && map_drag)
map_drag = 0;
break;
case SDL_MOUSEMOTION:
if(map_drag) {
// Axis is inverted.
map_xpos -= event->motion.xrel;
map_ypos += event->motion.yrel;
}
break;
}
case SDL_MOUSEMOTION:
if(map_drag) {
// Axis is inverted.
map_xpos -= event->motion.xrel;
map_ypos += event->motion.yrel;
}
break;
}
}
static void map_buttonZoom(char* str) {
if(strcmp(str, "btnZoomIn")==0) {
map_zoom += (map_zoom >= 1.) ? 0.5 : 0.25;
map_zoom = MIN(2.5, map_zoom);
}
if(strcmp(str, "btnZoomIn")==0) {
map_zoom += (map_zoom >= 1.) ? 0.5 : 0.25;
map_zoom = MIN(2.5, map_zoom);
}
else if(strcmp(str, "btnZoomOut")==0) {
map_zoom -= (map_zoom > 1.) ? 0.5 : 0.25;
map_zoom = MAX(0.5, map_zoom);
}
else if(strcmp(str, "btnZoomOut")==0) {
map_zoom -= (map_zoom > 1.) ? 0.5 : 0.25;
map_zoom = MAX(0.5, map_zoom);
}
}

124
src/md5.c
View File

@ -27,7 +27,7 @@
This code implements the MD5 Algorithm defined in RFC 1321, whose
text is available at
http://www.ietf.org/rfc/rfc1321.txt
http://www.ietf.org/rfc/rfc1321.txt
The code is derived from the text of the RFC, including the test suite
(section A.5) but excluding the rest of Appendix A. It does not include
any code or documentation that is identified in the RFC as being
@ -38,14 +38,14 @@
that follows (in reverse chronological order):
2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
either statically or dynamically; added missing #include <string.h>
in library.
either statically or dynamically; added missing #include <string.h>
in library.
2002-03-11 lpd Corrected argument list for main(), and added int return
type, in test program and T value program.
type, in test program and T value program.
2002-02-21 lpd Added missing #include <stdio.h> in test program.
2000-07-03 lpd Patched to eliminate warnings about "constant is
unsigned in ANSI C, signed in traditional"; made test program
self-checking.
unsigned in ANSI C, signed in traditional"; made test program
self-checking.
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
1999-05-03 lpd Original version.
@ -54,7 +54,7 @@
#include "md5.h"
#include <string.h>
#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
#ifdef ARCH_IS_BIG_ENDIAN
# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
#else
@ -132,8 +132,8 @@ static void
md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
{
md5_word_t
a = pms->abcd[0], b = pms->abcd[1],
c = pms->abcd[2], d = pms->abcd[3];
a = pms->abcd[0], b = pms->abcd[1],
c = pms->abcd[2], d = pms->abcd[3];
md5_word_t t;
#if BYTE_ORDER > 0
/* Define storage only for big-endian CPUs. */
@ -146,51 +146,51 @@ md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
{
#if BYTE_ORDER == 0
/*
* Determine dynamically whether this is a big-endian or
* little-endian machine, since we can use a more efficient
* algorithm on the latter.
*/
static const int w = 1;
/*
* Determine dynamically whether this is a big-endian or
* little-endian machine, since we can use a more efficient
* algorithm on the latter.
*/
static const int w = 1;
if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
#endif
#if BYTE_ORDER <= 0 /* little-endian */
{
/*
* On little-endian machines, we can process properly aligned
* data without copying it.
*/
if (!((data - (const md5_byte_t *)0) & 3)) {
/* data are properly aligned */
X = (const md5_word_t *)data;
} else {
/* not aligned */
memcpy(xbuf, data, 64);
X = xbuf;
}
}
#if BYTE_ORDER <= 0 /* little-endian */
{
/*
* On little-endian machines, we can process properly aligned
* data without copying it.
*/
if (!((data - (const md5_byte_t *)0) & 3)) {
/* data are properly aligned */
X = (const md5_word_t *)data;
} else {
/* not aligned */
memcpy(xbuf, data, 64);
X = xbuf;
}
}
#endif
#if BYTE_ORDER == 0
else /* dynamic big-endian */
else /* dynamic big-endian */
#endif
#if BYTE_ORDER >= 0 /* big-endian */
{
/*
* On big-endian machines, we must arrange the bytes in the
* right order.
*/
const md5_byte_t *xp = data;
int i;
#if BYTE_ORDER >= 0 /* big-endian */
{
/*
* On big-endian machines, we must arrange the bytes in the
* right order.
*/
const md5_byte_t *xp = data;
int i;
# if BYTE_ORDER == 0
X = xbuf; /* (dynamic only) */
X = xbuf; /* (dynamic only) */
# else
# define xbuf X /* (static only) */
# define xbuf X /* (static only) */
# endif
for (i = 0; i < 16; ++i, xp += 4)
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
}
for (i = 0; i < 16; ++i, xp += 4)
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
}
#endif
}
@ -328,54 +328,54 @@ md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
md5_word_t nbits = (md5_word_t)(nbytes << 3);
if (nbytes <= 0)
return;
return;
/* Update the message length. */
pms->count[1] += nbytes >> 29;
pms->count[0] += nbits;
if (pms->count[0] < nbits)
pms->count[1]++;
pms->count[1]++;
/* Process an initial partial block. */
if (offset) {
int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
memcpy(pms->buf + offset, p, copy);
if (offset + copy < 64)
return;
p += copy;
left -= copy;
md5_process(pms, pms->buf);
memcpy(pms->buf + offset, p, copy);
if (offset + copy < 64)
return;
p += copy;
left -= copy;
md5_process(pms, pms->buf);
}
/* Process full blocks. */
for (; left >= 64; p += 64, left -= 64)
md5_process(pms, p);
md5_process(pms, p);
/* Process a final partial block. */
if (left)
memcpy(pms->buf, p, left);
memcpy(pms->buf, p, left);
}
void
md5_finish(md5_state_t *pms, md5_byte_t digest[16])
{
static const md5_byte_t pad[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
md5_byte_t data[8];
int i;
/* Save the length before padding. */
for (i = 0; i < 8; ++i)
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
/* Pad to 56 bytes mod 64. */
md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
/* Append the length. */
md5_append(pms, data, 8);
for (i = 0; i < 16; ++i)
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
}

View File

@ -27,7 +27,7 @@
This code implements the MD5 Algorithm defined in RFC 1321, whose
text is available at
http://www.ietf.org/rfc/rfc1321.txt
http://www.ietf.org/rfc/rfc1321.txt
The code is derived from the text of the RFC, including the test suite
(section A.5) but excluding the rest of Appendix A. It does not include
any code or documentation that is identified in the RFC as being
@ -40,12 +40,12 @@
2007-04-15 bobbens using uint8_t and uint32_t for compatibility.
removed C++ conditionalization.
2002-04-13 lpd Removed support for non-ANSI compilers; removed
references to Ghostscript; clarified derivation from RFC 1321;
now handles byte order either statically or dynamically.
references to Ghostscript; clarified derivation from RFC 1321;
now handles byte order either statically or dynamically.
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
added conditionalization for C++ compilation from Martin
Purschke <purschke@bnl.gov>.
added conditionalization for C++ compilation from Martin
Purschke <purschke@bnl.gov>.
1999-05-03 lpd Original version.
*/
@ -69,9 +69,9 @@ typedef uint32_t md5_word_t; /* 32-bit word */
/* Define the state of the MD5 Algorithm. */
typedef struct md5_state_s {
md5_word_t count[2]; /* message length in bits, lsw first */
md5_word_t abcd[4]; /* digest buffer */
md5_byte_t buf[64]; /* accumulate block */
md5_word_t count[2]; /* message length in bits, lsw first */
md5_word_t abcd[4]; /* digest buffer */
md5_byte_t buf[64]; /* accumulate block */
} md5_state_t;

View File

@ -10,26 +10,26 @@
#include "player.h"
#include "menu.h"
#define MAIN_WIDTH 130
#define MAIN_HEIGHT 250
#define MAIN_WIDTH 130
#define MAIN_HEIGHT 250
#define MENU_WIDTH 130
#define MENU_HEIGHT 200
#define MENU_WIDTH 130
#define MENU_HEIGHT 200
#define INFO_WIDTH 320
#define INFO_HEIGHT 280
#define INFO_WIDTH 320
#define INFO_HEIGHT 280
#define OUTFITS_WIDTH 400
#define OUTFITS_HEIGHT 200
#define OUTFITS_WIDTH 400
#define OUTFITS_HEIGHT 200
#define DEATH_WIDTH 130
#define DEATH_HEIGHT 150
#define DEATH_WIDTH 130
#define DEATH_HEIGHT 150
#define BUTTON_WIDTH 90
#define BUTTON_HEIGHT 30
#define BUTTON_WIDTH 90
#define BUTTON_HEIGHT 30
#define menu_Open(f) (menu_open |= (f))
#define menu_Close(f) (menu_open ^= (f))
#define menu_Open(f) (menu_open |= (f))
#define menu_Close(f) (menu_open ^= (f))
int menu_open = 0;
@ -44,51 +44,51 @@ static void info_outfits_menu_close(char* str);
static void menu_death_main(char* str);
void menu_main(void) {
unsigned int bwid, wid;
unsigned int bwid, wid;
// Create background image window.
bwid = window_create("BG", -1, -1, gl_screen.w, gl_screen.h);
window_addRect(bwid, 0, 0, gl_screen.w, gl_screen.h, "rctBG", &cBlack, 0);
// Create background image window.
bwid = window_create("BG", -1, -1, gl_screen.w, gl_screen.h);
window_addRect(bwid, 0, 0, gl_screen.w, gl_screen.h, "rctBG", &cBlack, 0);
// 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,
"btnLoad", "Load Game", NULL);
window_addButton(wid, 20, 20 + (BUTTON_HEIGHT+20)*2,
BUTTON_WIDTH, BUTTON_HEIGHT,
"btnNew", "New Game", menu_main_new);
window_addButton(wid, 20, 20 + (BUTTON_HEIGHT+20),
BUTTON_WIDTH, BUTTON_HEIGHT,
"btnOptions", "Options", (void(*)(char*)) edit_options);
window_addButton(wid, 20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
"btnExit", "Exit", (void(*)(char*)) exit_game);
// 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,
"btnLoad", "Load Game", NULL);
window_addButton(wid, 20, 20 + (BUTTON_HEIGHT+20)*2,
BUTTON_WIDTH, BUTTON_HEIGHT,
"btnNew", "New Game", menu_main_new);
window_addButton(wid, 20, 20 + (BUTTON_HEIGHT+20),
BUTTON_WIDTH, BUTTON_HEIGHT,
"btnOptions", "Options", (void(*)(char*)) edit_options);
window_addButton(wid, 20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
"btnExit", "Exit", (void(*)(char*)) exit_game);
menu_Open(MENU_MAIN);
menu_Open(MENU_MAIN);
}
static void menu_main_close(void) {
window_destroy(window_get("Main Menu"));
window_destroy(window_get("BG"));
window_destroy(window_get("Main Menu"));
window_destroy(window_get("BG"));
menu_Close(MENU_MAIN);
menu_Close(MENU_MAIN);
}
static void menu_main_new(char* str) {
(void)str;
(void)str;
menu_main_close();
player_new();
menu_main_close();
player_new();
}
// 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..
pause();
menu_isOpen(MENU_SMALL) ||
menu_isOpen(MENU_DEATH))
return; // It's already open..
pause();
unsigned int wid;
@ -98,14 +98,14 @@ void menu_small(void) {
BUTTON_WIDTH, BUTTON_HEIGHT,
"btnResume", "Resume", menu_small_close);
window_addButton(wid, 20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
window_addButton(wid, 20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
"btnExit", "Exit", (void(*)(char*))exit_game);
window_addButton(wid, 20, 20 + BUTTON_HEIGHT + 20,
window_addButton(wid, 20, 20 + BUTTON_HEIGHT + 20,
BUTTON_WIDTH, BUTTON_HEIGHT,
"btnOptions", "Options", (void(*)(char*))edit_options);
menu_Open(MENU_SMALL);
menu_Open(MENU_SMALL);
}
static void menu_small_close(char* str) {
@ -113,7 +113,7 @@ static void menu_small_close(char* str) {
window_destroy(window_get("Menu"));
unpause();
menu_Close(MENU_SMALL);
menu_Close(MENU_SMALL);
}
// Edit the options.
@ -130,114 +130,114 @@ static void exit_game(void) {
// Info menu.
void menu_info(void) {
if(menu_isOpen(MENU_INFO)) return;
pause();
if(menu_isOpen(MENU_INFO)) return;
pause();
char str[128];;
unsigned int wid;
wid = window_create("Info", -1, -1, INFO_WIDTH, INFO_HEIGHT);
char str[128];;
unsigned int wid;
wid = window_create("Info", -1, -1, INFO_WIDTH, INFO_HEIGHT);
// Pilot generics.
window_addText(wid, 20, 20, 120, INFO_HEIGHT-60,
0, "txtDPilot", &gl_smallFont, &cDConsole,
"Pilot:\n"
"Combat Rating:\n");
// Pilot generics.
window_addText(wid, 20, 20, 120, INFO_HEIGHT-60,
0, "txtDPilot", &gl_smallFont, &cDConsole,
"Pilot:\n"
"Combat Rating:\n");
snprintf(str, 128,
"%s\n"
"%s\n",
player_name, player_rating());
snprintf(str, 128,
"%s\n"
"%s\n",
player_name, player_rating());
window_addText(wid, 120, 20,
INFO_WIDTH-120-BUTTON_WIDTH, INFO_HEIGHT-60,
0, "txtPilot", &gl_smallFont, &cBlack, str);
window_addText(wid, 120, 20,
INFO_WIDTH-120-BUTTON_WIDTH, INFO_HEIGHT-60,
0, "txtPilot", &gl_smallFont, &cBlack, str);
// Menu.
window_addButton(wid, -20, (20 + BUTTON_HEIGHT)*4 + 20,
BUTTON_WIDTH, BUTTON_HEIGHT,
player->ship->name, "Ship", ship_view);
window_addButton(wid, -20, (20 + BUTTON_HEIGHT)*3 + 20,
BUTTON_WIDTH, BUTTON_HEIGHT,
"btnOutfits", "Outfits", info_outfits_menu);
window_addButton(wid, -20, (20 + BUTTON_HEIGHT)*2 + 20,
BUTTON_WIDTH, BUTTON_HEIGHT,
"btnCargo", "Cargo", NULL);
window_addButton(wid, -20, 20 + BUTTON_HEIGHT + 20,
BUTTON_WIDTH, BUTTON_HEIGHT,
"btnMissions", "Missions", NULL);
window_addButton(wid, -20, 20,
BUTTON_WIDTH, BUTTON_HEIGHT,
"btnClose", "Close", menu_info_close);
// Menu.
window_addButton(wid, -20, (20 + BUTTON_HEIGHT)*4 + 20,
BUTTON_WIDTH, BUTTON_HEIGHT,
player->ship->name, "Ship", ship_view);
window_addButton(wid, -20, (20 + BUTTON_HEIGHT)*3 + 20,
BUTTON_WIDTH, BUTTON_HEIGHT,
"btnOutfits", "Outfits", info_outfits_menu);
window_addButton(wid, -20, (20 + BUTTON_HEIGHT)*2 + 20,
BUTTON_WIDTH, BUTTON_HEIGHT,
"btnCargo", "Cargo", NULL);
window_addButton(wid, -20, 20 + BUTTON_HEIGHT + 20,
BUTTON_WIDTH, BUTTON_HEIGHT,
"btnMissions", "Missions", NULL);
window_addButton(wid, -20, 20,
BUTTON_WIDTH, BUTTON_HEIGHT,
"btnClose", "Close", menu_info_close);
menu_Open(MENU_INFO);
menu_Open(MENU_INFO);
}
static void menu_info_close(char* str) {
if(strcmp(str, "btnClose")==0)
window_destroy(window_get("Info"));
if(strcmp(str, "btnClose")==0)
window_destroy(window_get("Info"));
menu_Close(MENU_INFO);
unpause();
menu_Close(MENU_INFO);
unpause();
}
static void info_outfits_menu(char* str) {
(void) str;
int i;
char buf[1024], buf2[64];
unsigned int wid;
wid = window_create("Outfits", -1, -1, OUTFITS_WIDTH, OUTFITS_HEIGHT);
(void) str;
int i;
char buf[1024], buf2[64];
unsigned int wid;
wid = window_create("Outfits", -1, -1, OUTFITS_WIDTH, OUTFITS_HEIGHT);
window_addText(wid, 20, -40, 100, OUTFITS_HEIGHT-40,
0, "txtLabel", &gl_smallFont, &cDConsole,
"Ship Outfits:");
window_addText(wid, 20, -40, 100, OUTFITS_HEIGHT-40,
0, "txtLabel", &gl_smallFont, &cDConsole,
"Ship Outfits:");
buf[0] = '\0';
if(player->noutfits > 0)
snprintf(buf, 1024, "%dx %s",
player->outfits[0].quantity, player->outfits[0].outfit->name);
buf[0] = '\0';
if(player->noutfits > 0)
snprintf(buf, 1024, "%dx %s",
player->outfits[0].quantity, player->outfits[0].outfit->name);
for(i = 1; i < player->noutfits; i++) {
snprintf(buf2, 64, ", %dx %s",
player->outfits[i].quantity, player->outfits[i].outfit->name);
strcat(buf, buf2);
}
for(i = 1; i < player->noutfits; i++) {
snprintf(buf2, 64, ", %dx %s",
player->outfits[i].quantity, player->outfits[i].outfit->name);
strcat(buf, buf2);
}
window_addText(wid, 20, -45-gl_smallFont.h,
OUTFITS_WIDTH-40, OUTFITS_HEIGHT-60,
0, "txtOutfits", &gl_smallFont, &cBlack, buf);
window_addText(wid, 20, -45-gl_smallFont.h,
OUTFITS_WIDTH-40, OUTFITS_HEIGHT-60,
0, "txtOutfits", &gl_smallFont, &cBlack, buf);
window_addButton(wid, -20, 20,
BUTTON_WIDTH, BUTTON_HEIGHT,
"closeOutfits", "Close", info_outfits_menu_close);
window_addButton(wid, -20, 20,
BUTTON_WIDTH, BUTTON_HEIGHT,
"closeOutfits", "Close", info_outfits_menu_close);
}
static void info_outfits_menu_close(char* str) {
window_destroy(window_get(str+5)); // closeFoo -> Foo.
window_destroy(window_get(str+5)); // closeFoo -> Foo.
}
// Pilot dead.
void menu_death(void) {
unsigned int wid;
wid = window_create("Death", -1, -1, DEATH_WIDTH, DEATH_HEIGHT);
unsigned int wid;
wid = window_create("Death", -1, -1, DEATH_WIDTH, DEATH_HEIGHT);
window_addButton(wid, 20, 20 + (BUTTON_HEIGHT + 20),
BUTTON_WIDTH, BUTTON_HEIGHT,
"btnMain", "MainMenu", menu_death_main);
window_addButton(wid, 20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
"btnExit", "Exit", (void(*)(char*)) exit_game);
window_addButton(wid, 20, 20 + (BUTTON_HEIGHT + 20),
BUTTON_WIDTH, BUTTON_HEIGHT,
"btnMain", "MainMenu", menu_death_main);
window_addButton(wid, 20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
"btnExit", "Exit", (void(*)(char*)) exit_game);
menu_Open(MENU_DEATH);
menu_Open(MENU_DEATH);
}
static void menu_death_main(char* str) {
(void)str;
unsigned int wid;
(void)str;
unsigned int wid;
wid = window_get("Death");
window_destroy(wid);
menu_Close(MENU_DEATH);
wid = window_get("Death");
window_destroy(wid);
menu_Close(MENU_DEATH);
menu_main();
menu_main();
}

View File

@ -1,10 +1,10 @@
#pragma once
#define MENU_MAIN (1<<0)
#define MENU_SMALL (1<<1)
#define MENU_INFO (1<<2)
#define MENU_DEATH (1<<3)
#define menu_isOpen(f) (menu_open & (f))
#define MENU_MAIN (1<<0)
#define MENU_SMALL (1<<1)
#define MENU_INFO (1<<2)
#define MENU_DEATH (1<<3)
#define menu_isOpen(f) (menu_open & (f))
extern int menu_open;
void menu_main(void);

View File

@ -8,34 +8,34 @@
#include "pack.h"
#include "music.h"
#define MUSIC_STOPPED (1<<1)
#define MUSIC_PLAYING (1<<2)
#define MUSIC_KILL (1<<9)
#define music_is(f) (music_state & f)
#define music_set(f) (music_state |= f)
#define music_rm(f) (music_state ^= f)
#define MUSIC_STOPPED (1<<1)
#define MUSIC_PLAYING (1<<2)
#define MUSIC_KILL (1<<9)
#define music_is(f) (music_state & f)
#define music_set(f) (music_state |= f)
#define music_rm(f) (music_state ^= f)
#define MUSIC_PREFIX "../snd/music/"
#define MUSIC_SUFFIX ".ogg"
#define MUSIC_PREFIX "../snd/music/"
#define MUSIC_SUFFIX ".ogg"
#define BUFFER_SIZE (4096 * 8)
#define BUFFER_SIZE (4096 * 8)
// Gobal sound mutex.
extern SDL_mutex* sound_lock;
// Saves the music to ram in this structure.
typedef struct alMusic_ {
char name[32]; // Name.
Packfile file;
OggVorbis_File stream;
vorbis_info* info;
ALenum format;
char name[32]; // Name.
Packfile file;
OggVorbis_File stream;
vorbis_info* info;
ALenum format;
} alMusic;
// 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?
@ -47,17 +47,17 @@ static ALfloat mvolume = 1.;
// 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);
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.
ov_callbacks ovcall = {
.read_func = ovpack_read,
.seek_func = (int(*)(void*, ogg_int64_t, int)) ovpack_retneg,
.close_func = (int(*)(void*))ovpack_retzero,
.tell_func = (long(*)(void*))ovpack_retneg
.read_func = ovpack_read,
.seek_func = (int(*)(void*, ogg_int64_t, int)) ovpack_retneg,
.close_func = (int(*)(void*))ovpack_retzero,
.tell_func = (long(*)(void*))ovpack_retneg
};
static int stream_loadBuffer(ALuint buffer);
@ -68,250 +68,250 @@ static void music_free(void);
// The thread.
static unsigned int music_state = 0;
int music_thread(void* unused) {
(void)unused;
(void)unused;
int active; // Active buffer.
ALint stat;
int active; // Active buffer.
ALint stat;
// Main loop.
while(!music_is(MUSIC_KILL)) {
if(music_is(MUSIC_PLAYING)) {
if(music_vorbis.file.end == 0)
music_rm(MUSIC_PLAYING);
else {
music_rm(MUSIC_STOPPED);
// Main loop.
while(!music_is(MUSIC_KILL)) {
if(music_is(MUSIC_PLAYING)) {
if(music_vorbis.file.end == 0)
music_rm(MUSIC_PLAYING);
else {
music_rm(MUSIC_STOPPED);
SDL_mutexP(music_vorbis_lock); // Lock the mutex.
SDL_mutexP(sound_lock);
SDL_mutexP(music_vorbis_lock); // Lock the mutex.
SDL_mutexP(sound_lock);
// 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 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.
alSourcePlay(music_source);
// Start playing with buffer laoaded.
alSourcePlay(music_source);
active = 1; // Load the second buffer.
if(stream_loadBuffer(music_buffer[active])) music_rm(MUSIC_PLAYING);
alSourceQueueBuffers(music_source, 1, &music_buffer[active]);
active = 1; // Load the second buffer.
if(stream_loadBuffer(music_buffer[active])) music_rm(MUSIC_PLAYING);
alSourceQueueBuffers(music_source, 1, &music_buffer[active]);
SDL_mutexV(sound_lock);
SDL_mutexV(sound_lock);
active = 0;
}
while(music_is(MUSIC_PLAYING)) {
SDL_mutexP(sound_lock);
active = 0;
}
while(music_is(MUSIC_PLAYING)) {
SDL_mutexP(sound_lock);
alGetSourcei(music_source, AL_BUFFERS_PROCESSED, &stat);
if(stat > 0) {
// 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]);
alGetSourcei(music_source, AL_BUFFERS_PROCESSED, &stat);
if(stat > 0) {
// 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]);
active = 1 - active;
}
SDL_mutexV(sound_lock);
active = 1 - active;
}
SDL_mutexV(sound_lock);
SDL_Delay(0);
}
SDL_mutexP(sound_lock);
SDL_Delay(0);
}
SDL_mutexP(sound_lock);
alSourceStop(music_source);
alSourceUnqueueBuffers(music_source, 2, music_buffer);
alSourceStop(music_source);
alSourceUnqueueBuffers(music_source, 2, music_buffer);
SDL_mutexV(sound_lock);
SDL_mutexV(music_vorbis_lock);
}
music_set(MUSIC_STOPPED);
SDL_Delay(0); // We must not kill resources.
}
return 0;
SDL_mutexV(sound_lock);
SDL_mutexV(music_vorbis_lock);
}
music_set(MUSIC_STOPPED);
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.
int size, section, result;
char data[BUFFER_SIZE]; // Buffer to hold the data.
size = 0;
while(size < BUFFER_SIZE) {
// 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.
&section); // Current bitstream.
size = 0;
while(size < BUFFER_SIZE) {
// 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.
&section); // Current bitstream.
if(result == 0) return 1;
else if(result == OV_HOLE) {
WARN("OGG: Vorbis hole detected in music!");
return 0;
}
else if(result == OV_EBADLINK) {
WARN("OGG: Invalid stream section or corrupt link in music!");
return -1;
}
if(result == 0) return 1;
else if(result == OV_HOLE) {
WARN("OGG: Vorbis hole detected in music!");
return 0;
}
else if(result == OV_EBADLINK) {
WARN("OGG: Invalid stream section or corrupt link in music!");
return -1;
}
size += result;
if(size == BUFFER_SIZE) break; // Buffer is full.
}
// Load the buffer.
alBufferData(buffer, music_vorbis.format, data, BUFFER_SIZE,
music_vorbis.info->rate);
size += result;
if(size == BUFFER_SIZE) break; // Buffer is full.
}
// Load the buffer.
alBufferData(buffer, music_vorbis.format, data, BUFFER_SIZE,
music_vorbis.info->rate);
return 0;
return 0;
}
// Init/Exit.
int music_init(void) {
music_vorbis_lock = SDL_CreateMutex();
music_find();
music_vorbis.file.end = 0; // Indication that it's not loaded..
music_vorbis_lock = SDL_CreateMutex();
music_find();
music_vorbis.file.end = 0; // Indication that it's not loaded..
SDL_mutexP(sound_lock);
SDL_mutexP(sound_lock);
alGenBuffers(2, music_buffer);
alGenSources(1, &music_source);
alSourcef(music_source, AL_GAIN, mvolume);
alSourcef(music_source, AL_ROLLOFF_FACTOR, 0.);
alSourcei(music_source, AL_SOURCE_RELATIVE, AL_TRUE);
alGenBuffers(2, music_buffer);
alGenSources(1, &music_source);
alSourcef(music_source, AL_GAIN, mvolume);
alSourcef(music_source, AL_ROLLOFF_FACTOR, 0.);
alSourcei(music_source, AL_SOURCE_RELATIVE, AL_TRUE);
SDL_mutexV(sound_lock);
SDL_mutexV(sound_lock);
return 0;
return 0;
}
void music_exit(void) {
int i;
int i;
// Free the music.
alDeleteBuffers(2, music_buffer);
alDeleteSources(1, &music_source);
music_free();
// Free the music.
alDeleteBuffers(2, music_buffer);
alDeleteSources(1, &music_source);
music_free();
// Free selection
for(i = 0; i < nmusic_selection; i++)
free(music_selection[i]);
free(music_selection);
// Free selection
for(i = 0; i < nmusic_selection; i++)
free(music_selection[i]);
free(music_selection);
SDL_DestroyMutex(music_vorbis_lock);
SDL_DestroyMutex(music_vorbis_lock);
}
// Internal music loading ruitines.
static int music_loadOGG(const char* filename) {
// Free currently loaded ogg.
music_free();
// Free currently loaded ogg.
music_free();
SDL_mutexP(music_vorbis_lock);
SDL_mutexP(music_vorbis_lock);
// 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);
// 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);
if(music_vorbis.info->channels == 1) music_vorbis.format = AL_FORMAT_MONO16;
else music_vorbis.format = AL_FORMAT_STEREO16;
if(music_vorbis.info->channels == 1) music_vorbis.format = AL_FORMAT_MONO16;
else music_vorbis.format = AL_FORMAT_STEREO16;
SDL_mutexV(music_vorbis_lock);
return 0;
SDL_mutexV(music_vorbis_lock);
return 0;
}
static int music_find(void) {
char** files;
uint32_t nfiles, i;
char tmp[64];
int len;
char** files;
uint32_t nfiles, i;
char tmp[64];
int len;
// Get the file list.
files = pack_listfiles(data, &nfiles);
// Get the file list.
files = pack_listfiles(data, &nfiles);
// 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)) {
// 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.
music_selection = realloc(music_selection,++nmusic_selection*sizeof(char*));
// Grow the selection size.
music_selection = realloc(music_selection,++nmusic_selection*sizeof(char*));
// Remove the prefix and suffix.
len = strlen(files[i]) - strlen(MUSIC_SUFFIX MUSIC_PREFIX);
strncpy(tmp, files[i] + strlen(MUSIC_PREFIX), len);
tmp[len] = '\0';
// Remove the prefix and suffix.
len = strlen(files[i]) - strlen(MUSIC_SUFFIX MUSIC_PREFIX);
strncpy(tmp, files[i] + strlen(MUSIC_PREFIX), len);
tmp[len] = '\0';
music_selection[nmusic_selection-1] = strdup(tmp);
}
// Free the char* allocated by pack.
for(i = 0; i < nfiles; i++)
free(files[i]);
free(files);
music_selection[nmusic_selection-1] = strdup(tmp);
}
// Free the char* allocated by pack.
for(i = 0; i < nfiles; i++)
free(files[i]);
free(files);
DEBUG("Loaded %d song%c", nmusic_selection, (nmusic_selection==1)?' ':'s');
DEBUG("Loaded %d song%c", nmusic_selection, (nmusic_selection==1)?' ':'s');
return 0;
return 0;
}
static void music_free(void) {
SDL_mutexP(music_vorbis_lock);
SDL_mutexP(music_vorbis_lock);
if(music_vorbis.file.end != 0) {
ov_clear(&music_vorbis.stream);
pack_close(&music_vorbis.file);
music_vorbis.file.end = 0; // Somewhat ended.
}
if(music_vorbis.file.end != 0) {
ov_clear(&music_vorbis.stream);
pack_close(&music_vorbis.file);
music_vorbis.file.end = 0; // Somewhat ended.
}
SDL_mutexV(music_vorbis_lock);
SDL_mutexV(music_vorbis_lock);
}
void music_volume(const double vol) {
if(sound_lock == NULL) return;
if(sound_lock == NULL) return;
// Sanity check!
ALfloat fvol = ABS(vol);
if(fvol > 1.) fvol = 1.;
// Sanity check!
ALfloat fvol = ABS(vol);
if(fvol > 1.) fvol = 1.;
mvolume = fvol;
mvolume = fvol;
// Only needed if playing!
if(music_set(MUSIC_PLAYING)) {
SDL_mutexP(sound_lock);
alSourcef(music_source, AL_GAIN, fvol);
SDL_mutexV(sound_lock);
}
// Only needed if playing!
if(music_set(MUSIC_PLAYING)) {
SDL_mutexP(sound_lock);
alSourcef(music_source, AL_GAIN, fvol);
SDL_mutexV(sound_lock);
}
}
// Music control functions.
void music_load(const char* name) {
if(sound_lock == NULL) return;
if(sound_lock == NULL) return;
int i;
char tmp[64];
int i;
char tmp[64];
music_stop();
while(!music_is(MUSIC_STOPPED)) SDL_Delay(0);
music_stop();
while(!music_is(MUSIC_STOPPED)) SDL_Delay(0);
for(i = 0; i < nmusic_selection; i++)
if(strcmp(music_selection[i], name)==0) {
snprintf(tmp, 64, MUSIC_PREFIX"%s"MUSIC_SUFFIX, name);
music_loadOGG(tmp);
return;
}
WARN("Requested load song '%s' but it can't be found in the music stack",name);
for(i = 0; i < nmusic_selection; i++)
if(strcmp(music_selection[i], name)==0) {
snprintf(tmp, 64, MUSIC_PREFIX"%s"MUSIC_SUFFIX, name);
music_loadOGG(tmp);
return;
}
WARN("Requested load song '%s' but it can't be found in the music stack",name);
}
void music_play(void) {
if(!music_is(MUSIC_PLAYING)) music_set(MUSIC_PLAYING);
if(!music_is(MUSIC_PLAYING)) music_set(MUSIC_PLAYING);
}
void music_stop(void) {
if(music_is(MUSIC_PLAYING)) music_rm(MUSIC_PLAYING);
if(music_is(MUSIC_PLAYING)) music_rm(MUSIC_PLAYING);
}
void music_kill(void) {
if(!music_is(MUSIC_KILL)) music_set(MUSIC_KILL);
if(!music_is(MUSIC_KILL)) music_set(MUSIC_KILL);
}

View File

@ -37,7 +37,7 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh);
// PNG.
int write_png(const char* file_name, png_bytep* rows, int w, int h,
int colourtype, int bitdepth);
int colourtype, int bitdepth);
// ================
// MISC!
@ -181,7 +181,7 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh) {
return 0;
}
if(SDL_FillRect(tmp, NULL, SDL_MapRGBA(surface->format, 0, 0, 0,
SDL_ALPHA_TRANSPARENT))) {
SDL_ALPHA_TRANSPARENT))) {
WARN("Unable to fill rect: %s", SDL_GetError());
return 0;
}
@ -203,7 +203,7 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh) {
return 0;
}
if(SDL_FillRect(tmp, NULL, SDL_MapRGBA(surface->format, 0, 0, 0,
SDL_ALPHA_TRANSPARENT))) {
SDL_ALPHA_TRANSPARENT))) {
WARN("Unable to fill rect: %s", SDL_GetError());
return 0;
}
@ -329,14 +329,14 @@ int gl_isTrans(const glTexture* t, const int x, const int y) {
// 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;
int s, sx, sy;
s = (int)(dir / (2.0*M_PI / (t->sy*t->sx)));
sx = t->sx;
sy = t->sy;
sx = t->sx;
sy = t->sy;
// Make sure the sprite is "in range".
if(s > (sy*sx-1)) s = s % (sy*sx);
if(s > (sy*sx-1)) s = s % (sy*sx);
*x = s % sx;
*y = s / sx;
@ -389,7 +389,7 @@ void gl_blitSprite(const glTexture* sprite, const double bx, const double by,
// Just straight out blit the thing at position.
void gl_blitStatic(const glTexture* texture, const double bx, const double by,
const glColour* c) {
const glColour* c) {
double x, y;
glEnable(GL_TEXTURE_2D);
@ -426,110 +426,110 @@ void gl_bindCamera(const Vec2* pos) {
// Draw circles.
void gl_drawCircle(const double cx, const double cy, const double r) {
double x, y, p;
double x, y, p;
x = 0;
y = r;
p = (5. - (r*4.)) / 4.;
x = 0;
y = r;
p = (5. - (r*4.)) / 4.;
glBegin(GL_POINTS);
glVertex2d(cx, cy+y);
glVertex2d(cx, cy-y);
glVertex2d(cx+y, cy);
glVertex2d(cx-y, cy);
glBegin(GL_POINTS);
glVertex2d(cx, cy+y);
glVertex2d(cx, cy-y);
glVertex2d(cx+y, cy);
glVertex2d(cx-y, cy);
while(x < y) {
x++;
if(p < 0) p += 2*(double)(x)+1;
else p += 2*(double)(x-(--y))+1;
while(x < y) {
x++;
if(p < 0) p += 2*(double)(x)+1;
else p += 2*(double)(x-(--y))+1;
if(x == 0) {
glVertex2d(cx, cy+y);
glVertex2d(cx, cy-y);
glVertex2d(cx+y, cy);
glVertex2d(cx-y, cy);
}
else if(x == y) {
glVertex2d(cx+x, cy+y);
glVertex2d(cx-x, cy+y);
glVertex2d(cx+x, cy-y);
glVertex2d(cx-x, cy-y);
}
else if(x < y) {
glVertex2d(cx+x, cy+y);
glVertex2d(cx-x, cy+y);
glVertex2d(cx+x, cy-y);
glVertex2d(cx-x, cy-y);
glVertex2d(cx+y, cy+x);
glVertex2d(cx-y, cy+x);
glVertex2d(cx+y, cy-x);
glVertex2d(cx-y, cy-x);
}
}
glEnd();
if(x == 0) {
glVertex2d(cx, cy+y);
glVertex2d(cx, cy-y);
glVertex2d(cx+y, cy);
glVertex2d(cx-y, cy);
}
else if(x == y) {
glVertex2d(cx+x, cy+y);
glVertex2d(cx-x, cy+y);
glVertex2d(cx+x, cy-y);
glVertex2d(cx-x, cy-y);
}
else if(x < y) {
glVertex2d(cx+x, cy+y);
glVertex2d(cx-x, cy+y);
glVertex2d(cx+x, cy-y);
glVertex2d(cx-x, cy-y);
glVertex2d(cx+y, cy+x);
glVertex2d(cx-y, cy+x);
glVertex2d(cx+y, cy-x);
glVertex2d(cx-y, cy-x);
}
}
glEnd();
}
// Draw a cirlce in a rect.
#define PIXEL(x,y) \
if((x>rx) && (y>ry) && (x<rxw) && (y<ryh)) \
glVertex2d(x,y)
glVertex2d(x,y)
void gl_drawCircleInRect(const double cx, const double cy, const double r,
const double rx, const double ry, const double rw, const double rh) {
const double rx, const double ry, const double rw, const double rh) {
double rxw, ryh, x, y, p;
double rxw, ryh, x, y, p;
rxw = rx+rw;
ryh = ry+rh;
rxw = rx+rw;
ryh = ry+rh;
// Are we offscreen?
if((cx+r < rx) || (cy+r < ry) || (cx-r > rxw) || (cy-r > ryh))
return;
// Can be drawn normally.
else if((cx-r > rx) && (cy-r > ry) && (cx+r < rxw) && (cy+r < ryh)) {
gl_drawCircle(cx, cy, r);
return;
}
// Are we offscreen?
if((cx+r < rx) || (cy+r < ry) || (cx-r > rxw) || (cy-r > ryh))
return;
// Can be drawn normally.
else if((cx-r > rx) && (cy-r > ry) && (cx+r < rxw) && (cy+r < ryh)) {
gl_drawCircle(cx, cy, r);
return;
}
x = 0;
y = r;
p = (5. - (r*4.)) / 4.;
x = 0;
y = r;
p = (5. - (r*4.)) / 4.;
glBegin(GL_POINTS);
PIXEL(cx, cy+y);
PIXEL(cx, cy-y);
PIXEL(cx+y, cy);
PIXEL(cx-y, cy);
glBegin(GL_POINTS);
PIXEL(cx, cy+y);
PIXEL(cx, cy-y);
PIXEL(cx+y, cy);
PIXEL(cx-y, cy);
while(x < y) {
x++;
if(p < 0) p += 2*(double)(x)+1;
else p += 2*(double)(x-(--y))+1;
while(x < y) {
x++;
if(p < 0) p += 2*(double)(x)+1;
else p += 2*(double)(x-(--y))+1;
if(x == 0) {
PIXEL(cx, cy+y);
PIXEL(cx, cy-y);
PIXEL(cx+y, cy);
PIXEL(cx-y, cy);
}
else if(x == y) {
PIXEL(cx+x, cy+y);
PIXEL(cx-x, cy+y);
PIXEL(cx+x, cy-y);
PIXEL(cx-x, cy-y);
}
else if(x < y) {
PIXEL(cx+x, cy+y);
PIXEL(cx-x, cy+y);
PIXEL(cx+x, cy-y);
PIXEL(cx-x, cy-y);
PIXEL(cx+y, cy+x);
PIXEL(cx-y, cy+x);
PIXEL(cx+y, cy-x);
PIXEL(cx-y, cy-x);
}
}
glEnd();
if(x == 0) {
PIXEL(cx, cy+y);
PIXEL(cx, cy-y);
PIXEL(cx+y, cy);
PIXEL(cx-y, cy);
}
else if(x == y) {
PIXEL(cx+x, cy+y);
PIXEL(cx-x, cy+y);
PIXEL(cx+x, cy-y);
PIXEL(cx-x, cy-y);
}
else if(x < y) {
PIXEL(cx+x, cy+y);
PIXEL(cx-x, cy+y);
PIXEL(cx+x, cy-y);
PIXEL(cx-x, cy-y);
PIXEL(cx+y, cy+x);
PIXEL(cx-y, cy+x);
PIXEL(cx+y, cy-x);
PIXEL(cx-y, cy-x);
}
}
glEnd();
}
// ================
@ -566,7 +566,7 @@ int gl_init(void) {
for(i = 0; modes[i]; i++) {
DEBUG("\t%dx%d", modes[i]->w, modes[i]->h);
if((flags & SDL_FULLSCREEN) && (modes[i]->w == gl_screen.w) &&
(modes[i]->h == gl_screen.h))
(modes[i]->h == gl_screen.h))
supported = 1; // Mode we asked for is supported.
}
}
@ -621,10 +621,10 @@ int gl_init(void) {
// Debug heaven.
DEBUG("OpenGL Window Created: %dx%d@%dbpp %s", gl_screen.w, gl_screen.h,
gl_screen.depth, (gl_has(OPENGL_FULLSCREEN)) ? "fullscreen" : "window");
gl_screen.depth, (gl_has(OPENGL_FULLSCREEN)) ? "fullscreen" : "window");
DEBUG("r: %d, g: %d, b: %d, a: %d, doublebuffer: %s",
gl_screen.r, gl_screen.g, gl_screen.b, gl_screen.a,
gl_screen.r, gl_screen.g, gl_screen.b, gl_screen.a,
(gl_has(OPENGL_DOUBLEBUF)) ? "yes" : "no");
DEBUG("Renderer: %s", glGetString(GL_RENDERER));
@ -658,7 +658,7 @@ void gl_exit(void) {
// Saves a png.
int write_png(const char* file_name, png_bytep* rows, int w, int h,
int colourtype, int bitdepth) {
int colourtype, int bitdepth) {
png_structp png_ptr;
png_infop info_ptr;
FILE* fp = NULL;
@ -668,7 +668,7 @@ int write_png(const char* file_name, png_bytep* rows, int w, int h,
doing = "Create png write struct";
if(!(png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
NULL, NULL, NULL))) goto fail;
NULL, NULL, NULL))) goto fail;
doing = "Create png info struct";
if(!(info_ptr = png_create_info_struct(png_ptr))) goto fail;

View File

@ -33,8 +33,8 @@ typedef struct glInfo_ {
} glInfo;
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)
#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.
typedef struct glTexture_ {
@ -67,7 +67,7 @@ void gl_bindCamera(const Vec2* pos);
// 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);
const double rc, const double ry, const double rw, const double rh);
// Initialize/cleanup.
int gl_init(void);

View File

@ -42,24 +42,24 @@ Outfit* outfit_get(const char* name) {
// Return all the outfits.
char** outfit_getTech(int* n, const int* tech, const int techmax) {
int i, j;
char** outfitnames = malloc(sizeof(Outfit*) * outfits);
int i, j;
char** outfitnames = malloc(sizeof(Outfit*) * outfits);
*n = 0;
for(i = 0; i < outfits; i++)
if(outfit_stack[i].tech <= tech[0]) {
outfitnames[*n] = strdup(outfit_stack[i].name);
(*n)++;
} else {
for(j = 0; j < techmax; j++)
if(tech[j] == outfit_stack[i].tech) {
outfitnames[*n] = strdup(outfit_stack[i].name);
(*n)++;
}
}
*n = 0;
for(i = 0; i < outfits; i++)
if(outfit_stack[i].tech <= tech[0]) {
outfitnames[*n] = strdup(outfit_stack[i].name);
(*n)++;
} else {
for(j = 0; j < techmax; j++)
if(tech[j] == outfit_stack[i].tech) {
outfitnames[*n] = strdup(outfit_stack[i].name);
(*n)++;
}
}
// Actual size is bigger, but it'll just get freed ;).
return outfitnames;
// Actual size is bigger, but it'll just get freed ;).
return outfitnames;
}
// Return 1 if outfit is a weapon (beam/bolt).
@ -87,62 +87,62 @@ int outfit_isAmmo(const Outfit* o) {
}
int outfit_isTurret(const Outfit* o) {
return ((o->type == OUTFIT_TYPE_TURRET_BOLT) ||
(o->type == OUTFIT_TYPE_TURRET_BEAM));
return ((o->type == OUTFIT_TYPE_TURRET_BOLT) ||
(o->type == OUTFIT_TYPE_TURRET_BEAM));
}
// Return 1 if o is a modification.
int outfit_isMod(const Outfit* o) {
return (o->type == OUTFIT_TYPE_MODIFICATION);
return (o->type == OUTFIT_TYPE_MODIFICATION);
}
// Return 1 if o is an afterburner.
int outfit_isAfterburner(const Outfit* o) {
return (o->type == OUTFIT_TYPE_AFTERBURNER);
return (o->type == OUTFIT_TYPE_AFTERBURNER);
}
// 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;
else if(outfit_isTurret(o)) return o->u.blt.gfx_space;
return NULL;
if(outfit_isWeapon(o)) return o->u.blt.gfx_space;
else if(outfit_isAmmo(o)) return o->u.amm.gfx_space;
else if(outfit_isTurret(o)) return o->u.blt.gfx_space;
return NULL;
}
// 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;
else if(outfit_isTurret(o)) return o->u.blt.spfx;
return -1;
if(outfit_isWeapon(o)) return o->u.blt.spfx;
else if(outfit_isAmmo(o)) return o->u.amm.spfx;
else if(outfit_isTurret(o)) return o->u.blt.spfx;
return -1;
}
double outfit_dmgShield(const Outfit* o) {
if(outfit_isWeapon(o)) return o->u.blt.damage_armour;
else if(outfit_isAmmo(o)) return o->u.amm.damage_armour;
else if(outfit_isTurret(o)) return o->u.blt.damage_armour;
return -1;
if(outfit_isWeapon(o)) return o->u.blt.damage_armour;
else if(outfit_isAmmo(o)) return o->u.amm.damage_armour;
else if(outfit_isTurret(o)) return o->u.blt.damage_armour;
return -1;
}
double outfit_dmgArmour(const Outfit* o) {
if(outfit_isWeapon(o)) return o->u.blt.damage_shield;
else if(outfit_isAmmo(o)) return o->u.amm.damage_shield;
else if(outfit_isTurret(o)) return o->u.blt.damage_shield;
return -1;
if(outfit_isWeapon(o)) return o->u.blt.damage_shield;
else if(outfit_isAmmo(o)) return o->u.amm.damage_shield;
else if(outfit_isTurret(o)) return o->u.blt.damage_shield;
return -1;
}
int outfit_delay(const Outfit* o) {
if(outfit_isWeapon(o)) return o->u.blt.delay;
else if(outfit_isLauncher(o)) return o->u.lau.delay;
else if(outfit_isTurret(o)) return o->u.blt.delay;
return -1;
if(outfit_isWeapon(o)) return o->u.blt.delay;
else if(outfit_isLauncher(o)) return o->u.lau.delay;
else if(outfit_isTurret(o)) return o->u.blt.delay;
return -1;
}
double outfit_energy(const Outfit* o) {
if(outfit_isWeapon(o)) return o->u.blt.energy;
else if(outfit_isAmmo(o)) return o->u.amm.energy;
else if(outfit_isTurret(o)) return o->u.blt.energy;
return -1.;
if(outfit_isWeapon(o)) return o->u.blt.energy;
else if(outfit_isAmmo(o)) return o->u.amm.energy;
else if(outfit_isTurret(o)) return o->u.blt.energy;
return -1.;
}
const char* outfit_typename[] = {
@ -159,10 +159,10 @@ const char* outfit_typename[] = {
"Swarm Missile Ammunition Pack",
"Smart Swarm Missile",
"Smart Swarm Missile Ammunition Pack",
"Bolt Turret",
"Beam Turret",
"Ship Modification",
"Afterburner"
"Bolt Turret",
"Beam Turret",
"Ship Modification",
"Afterburner"
};
const char* outfit_getType(const Outfit* o) {
@ -171,23 +171,23 @@ const char* outfit_getType(const Outfit* o) {
// Return the broad outfit type.
const char* outfit_typenamebroad[] = {
"NULL",
"Weapon",
"Launcher",
"Ammo",
"Turret",
"Modification",
"Afterburner"
"NULL",
"Weapon",
"Launcher",
"Ammo",
"Turret",
"Modification",
"Afterburner"
};
const char* outfit_getTypeBroad(const Outfit* o) {
int i = 0;
if(outfit_isWeapon(o)) i = 1;
else if(outfit_isLauncher(o)) i = 2;
else if(outfit_isAmmo(o)) i = 3;
else if(outfit_isTurret(o)) i = 4;
else if(outfit_isMod(o)) i = 5;
else if(outfit_isAfterburner(o)) i = 6;
if(outfit_isWeapon(o)) i = 1;
else if(outfit_isLauncher(o)) i = 2;
else if(outfit_isAmmo(o)) i = 3;
else if(outfit_isTurret(o)) i = 4;
else if(outfit_isMod(o)) i = 5;
else if(outfit_isAfterburner(o)) i = 6;
return outfit_typenamebroad[i];
}
@ -205,31 +205,31 @@ static void outfit_parseSWeapon(Outfit* tmp, const xmlNodePtr parent) {
else if(xml_isNode(node, "delay")) tmp->u.blt.delay = xml_getInt(node);
else if(xml_isNode(node, "range")) tmp->u.blt.range = xml_getFloat(node);
else if(xml_isNode(node, "accuracy")) tmp->u.blt.accuracy = xml_getFloat(node);
else if(xml_isNode(node, "energy")) tmp->u.blt.energy = xml_getFloat(node);
else if(xml_isNode(node, "energy")) tmp->u.blt.energy = xml_getFloat(node);
else if(xml_isNode(node, "gfx")) {
snprintf(str, strlen(xml_get(node))+sizeof(OUTFIT_GFX)+10,
OUTFIT_GFX"space/%s.png", xml_get(node));
OUTFIT_GFX"space/%s.png", xml_get(node));
tmp->u.blt.gfx_space = gl_newSprite(str, 6, 6);
}
else if(xml_isNode(node, "spfx"))
tmp->u.blt.spfx = spfx_get(xml_get(node));
else if(xml_isNode(node, "sound"))
tmp->u.blt.sound = sound_get(xml_get(node));
else if(xml_isNode(node, "spfx"))
tmp->u.blt.spfx = spfx_get(xml_get(node));
else if(xml_isNode(node, "sound"))
tmp->u.blt.sound = sound_get(xml_get(node));
else if(xml_isNode(node, "damage")) {
cur = node->children;
do {
if(xml_isNode(cur, "armour"))
tmp->u.blt.damage_armour = xml_getFloat(cur);
tmp->u.blt.damage_armour = xml_getFloat(cur);
else if(xml_isNode(cur, "shield"))
tmp->u.blt.damage_shield = xml_getFloat(cur);
tmp->u.blt.damage_shield = xml_getFloat(cur);
} while((cur = cur->next));
}
} while((node = node->next));
#define MELEMENT(o,s) if((o) == 0) \
WARN("Outfit '%s' missing '"s"' element", tmp->name)
WARN("Outfit '%s' missing '"s"' element", tmp->name)
if(tmp->u.blt.gfx_space == NULL)
WARN("Outfit '%s' missing 'gfx' element", tmp->name);
MELEMENT(tmp->u.blt.sound, "sound");
MELEMENT(tmp->u.blt.sound, "sound");
MELEMENT(tmp->u.blt.delay, "delay");
MELEMENT(tmp->u.blt.speed, "speed");
MELEMENT(tmp->u.blt.range, "range");
@ -251,8 +251,8 @@ static void outfit_parseSLauncher(Outfit* tmp, const xmlNodePtr parent) {
} while((node = node->next));
#define MELEMENT(o,s) if(o) WARN("Outfit '%s' missing '"s"' element", tmp->name)
MELEMENT(tmp->u.lau.ammo == NULL, "ammo");
MELEMENT(tmp->u.lau.delay==0, "delay");
MELEMENT(tmp->u.lau.ammo == NULL, "ammo");
MELEMENT(tmp->u.lau.delay==0, "delay");
#undef MELEMENT
}
@ -267,20 +267,20 @@ static void outfit_parseSAmmo(Outfit* tmp, const xmlNodePtr parent) {
if(xml_isNode(node, "thrust")) tmp->u.amm.thrust = xml_getFloat(node);
else if(xml_isNode(node, "turn")) tmp->u.amm.turn = xml_getFloat(node);
else if(xml_isNode(node, "speed")) tmp->u.amm.speed = xml_getFloat(node);
else if(xml_isNode(node, "energy")) tmp->u.amm.energy = xml_getFloat(node);
else if(xml_isNode(node, "energy")) tmp->u.amm.energy = xml_getFloat(node);
else if(xml_isNode(node, "duration"))
tmp->u.amm.duration = (unsigned int)1000.*xml_getFloat(node);
else if(xml_isNode(node, "lockon"))
tmp->u.amm.lockon = (unsigned int)1000.*xml_getFloat(node);
tmp->u.amm.duration = (unsigned int)1000.*xml_getFloat(node);
else if(xml_isNode(node, "lockon"))
tmp->u.amm.lockon = (unsigned int)1000.*xml_getFloat(node);
else if(xml_isNode(node, "gfx")) {
snprintf(str, strlen(xml_get(node))+sizeof(OUTFIT_GFX)+10,
OUTFIT_GFX"space/%s.png", xml_get(node));
tmp->u.amm.gfx_space = gl_newSprite(str, 6, 6);
}
else if(xml_isNode(node, "spfx"))
tmp->u.amm.spfx = spfx_get(xml_get(node));
else if(xml_isNode(node, "sound"))
tmp->u.amm.sound = sound_get(xml_get(node));
else if(xml_isNode(node, "spfx"))
tmp->u.amm.spfx = spfx_get(xml_get(node));
else if(xml_isNode(node, "sound"))
tmp->u.amm.sound = sound_get(xml_get(node));
else if(xml_isNode(node, "damage")) {
cur = node->children;
do {
@ -290,70 +290,70 @@ static void outfit_parseSAmmo(Outfit* tmp, const xmlNodePtr parent) {
}
} while((node = node->next));
#define MELEMENT(o,s) if(o) WARN("Outfit '%s' missing '"s"' element", tmp->name)
MELEMENT(tmp->u.amm.gfx_space == NULL, "gfx");
MELEMENT((sound_lock != NULL) && (tmp->u.amm.sound == 0), "sound");
MELEMENT(tmp->u.amm.thrust==0, "thrust");
MELEMENT(tmp->u.amm.turn==0, "turn");
MELEMENT(tmp->u.amm.speed==0, "speed");
MELEMENT(tmp->u.amm.duration==0, "duration");
MELEMENT(tmp->u.amm.lockon==0, "lockon");
MELEMENT(tmp->u.amm.damage_armour==0, "armour' from element 'damage");
MELEMENT(tmp->u.amm.damage_shield==0, "shield' from element 'damage");
MELEMENT(tmp->u.amm.gfx_space == NULL, "gfx");
MELEMENT((sound_lock != NULL) && (tmp->u.amm.sound == 0), "sound");
MELEMENT(tmp->u.amm.thrust==0, "thrust");
MELEMENT(tmp->u.amm.turn==0, "turn");
MELEMENT(tmp->u.amm.speed==0, "speed");
MELEMENT(tmp->u.amm.duration==0, "duration");
MELEMENT(tmp->u.amm.lockon==0, "lockon");
MELEMENT(tmp->u.amm.damage_armour==0, "armour' from element 'damage");
MELEMENT(tmp->u.amm.damage_shield==0, "shield' from element 'damage");
#undef MELEMENT
}
static void outfit_parseSMod(Outfit* tmp, const xmlNodePtr parent) {
xmlNodePtr node;
node = parent->children;
xmlNodePtr node;
node = parent->children;
// Load all the data.
do {
// Movement.
if(xml_isNode(node, "thrust"))
tmp->u.mod.thrust = xml_getFloat(node);
else if(xml_isNode(node, "turn"))
tmp->u.mod.turn = xml_getFloat(node);
else if(xml_isNode(node, "speed"))
tmp->u.mod.speed = xml_getFloat(node);
// Load all the data.
do {
// Movement.
if(xml_isNode(node, "thrust"))
tmp->u.mod.thrust = xml_getFloat(node);
else if(xml_isNode(node, "turn"))
tmp->u.mod.turn = xml_getFloat(node);
else if(xml_isNode(node, "speed"))
tmp->u.mod.speed = xml_getFloat(node);
// Health.
if(xml_isNode(node, "armour"))
tmp->u.mod.armour = xml_getFloat(node);
else if(xml_isNode(node, "shield"))
tmp->u.mod.shield = xml_getFloat(node);
else if(xml_isNode(node, "energy"))
tmp->u.mod.energy = xml_getFloat(node);
else if(xml_isNode(node, "armour_regen"))
tmp->u.mod.armour_regen = xml_getFloat(node)/60.0;
else if(xml_isNode(node, "shield_regen"))
tmp->u.mod.shield_regen = xml_getFloat(node)/60.0;
else if(xml_isNode(node, "energy_regen"))
tmp->u.mod.energy_regen = xml_getFloat(node)/60.0;
// Health.
if(xml_isNode(node, "armour"))
tmp->u.mod.armour = xml_getFloat(node);
else if(xml_isNode(node, "shield"))
tmp->u.mod.shield = xml_getFloat(node);
else if(xml_isNode(node, "energy"))
tmp->u.mod.energy = xml_getFloat(node);
else if(xml_isNode(node, "armour_regen"))
tmp->u.mod.armour_regen = xml_getFloat(node)/60.0;
else if(xml_isNode(node, "shield_regen"))
tmp->u.mod.shield_regen = xml_getFloat(node)/60.0;
else if(xml_isNode(node, "energy_regen"))
tmp->u.mod.energy_regen = xml_getFloat(node)/60.0;
} while((node = node->next));
} while((node = node->next));
}
// Parses the afterburner tidbits of the outfit.
static void outfit_parseSAfterburner(Outfit* tmp, const xmlNodePtr parent) {
xmlNodePtr node;
node = parent->children;
xmlNodePtr node;
node = parent->children;
// Must be >= 1.
tmp->u.afb.thrust_perc = 1.;
tmp->u.afb.speed_perc = 1.;
// Must be >= 1.
tmp->u.afb.thrust_perc = 1.;
tmp->u.afb.speed_perc = 1.;
do {
if(xml_isNode(node, "thrust_perc"))
tmp->u.afb.thrust_perc = 1. + xml_getFloat(node)/100.;
else if(xml_isNode(node, "thrust_abs"))
tmp->u.afb.thrust_abs = xml_getFloat(node);
else if(xml_isNode(node, "speed_perc"))
tmp->u.afb.speed_perc = 1. + xml_getFloat(node)/100.;
else if(xml_isNode(node, "speed_abs"))
tmp->u.afb.speed_abs = xml_getFloat(node);
else if(xml_isNode(node, "energy"))
tmp->u.afb.energy = xml_getFloat(node);
} while((node = node->next));
do {
if(xml_isNode(node, "thrust_perc"))
tmp->u.afb.thrust_perc = 1. + xml_getFloat(node)/100.;
else if(xml_isNode(node, "thrust_abs"))
tmp->u.afb.thrust_abs = xml_getFloat(node);
else if(xml_isNode(node, "speed_perc"))
tmp->u.afb.speed_perc = 1. + xml_getFloat(node)/100.;
else if(xml_isNode(node, "speed_abs"))
tmp->u.afb.speed_abs = xml_getFloat(node);
else if(xml_isNode(node, "energy"))
tmp->u.afb.energy = xml_getFloat(node);
} while((node = node->next));
}
// Parse and return Outfits from parent node.
@ -361,7 +361,7 @@ static Outfit* outfit_parse(const xmlNodePtr parent) {
Outfit* tmp = CALLOC_L(Outfit);
xmlNodePtr cur, node;
char* prop;
char str[PATH_MAX] = "\0";
char str[PATH_MAX] = "\0";
tmp->name = xml_nodeProp(parent, "name"); // Already malloced.
if(tmp->name == NULL) WARN("Outfit in "OUTFIT_DATA" has invalid or no name");
@ -373,16 +373,16 @@ static Outfit* outfit_parse(const xmlNodePtr parent) {
cur = node->children;
do {
if(xml_isNode(cur, "max")) tmp->max = xml_getInt(cur);
else if(xml_isNode(cur, "tech")) tmp->tech = xml_getInt(cur);
else if(xml_isNode(cur, "mass")) tmp->mass = xml_getInt(cur);
else if(xml_isNode(cur, "price")) tmp->price = xml_getInt(cur);
else if(xml_isNode(cur, "description"))
tmp->description = strdup(xml_get(cur));
else if(xml_isNode(cur, "gfx_store")) {
snprintf(str, strlen(xml_get(cur))+sizeof(OUTFIT_GFX)+10,
OUTFIT_GFX"store/%s.png", xml_get(cur));
tmp->gfx_store = gl_newImage(str);
}
else if(xml_isNode(cur, "tech")) tmp->tech = xml_getInt(cur);
else if(xml_isNode(cur, "mass")) tmp->mass = xml_getInt(cur);
else if(xml_isNode(cur, "price")) tmp->price = xml_getInt(cur);
else if(xml_isNode(cur, "description"))
tmp->description = strdup(xml_get(cur));
else if(xml_isNode(cur, "gfx_store")) {
snprintf(str, strlen(xml_get(cur))+sizeof(OUTFIT_GFX)+10,
OUTFIT_GFX"store/%s.png", xml_get(cur));
tmp->gfx_store = gl_newImage(str);
}
} while((cur = cur->next));
}
else if(xml_isNode(node, "specific")) {
@ -409,23 +409,23 @@ static Outfit* outfit_parse(const xmlNodePtr parent) {
outfit_parseSLauncher(tmp, node);
else if(outfit_isAmmo(tmp))
outfit_parseSAmmo(tmp, node);
else if(outfit_isTurret(tmp))
outfit_parseSWeapon(tmp, node);
else if(outfit_isMod(tmp))
outfit_parseSMod(tmp, node);
else if(outfit_isAfterburner(tmp))
outfit_parseSAfterburner(tmp, node);
else if(outfit_isTurret(tmp))
outfit_parseSWeapon(tmp, node);
else if(outfit_isMod(tmp))
outfit_parseSMod(tmp, node);
else if(outfit_isAfterburner(tmp))
outfit_parseSAfterburner(tmp, node);
}
} while((node = node->next));
#define MELEMENT(o,s) if(o) WARN("Outfit '%s' missing '"s"' element", tmp->name)
MELEMENT(tmp->name==NULL, "name");
MELEMENT(tmp->max==0, "max");
MELEMENT(tmp->tech==0, "tech");
MELEMENT(tmp->gfx_store==NULL, "gfx_store");
//MELEMENT(tmp->mass==0, "mass");
MELEMENT(tmp->type==0, "type");
MELEMENT(tmp->price==0, "price");
MELEMENT(tmp->description==NULL, "description");
MELEMENT(tmp->name==NULL, "name");
MELEMENT(tmp->max==0, "max");
MELEMENT(tmp->tech==0, "tech");
MELEMENT(tmp->gfx_store==NULL, "gfx_store");
//MELEMENT(tmp->mass==0, "mass");
MELEMENT(tmp->type==0, "type");
MELEMENT(tmp->price==0, "price");
MELEMENT(tmp->description==NULL, "description");
#undef MELEMENT
return tmp;
@ -466,7 +466,7 @@ int outfit_load(void) {
free(buf);
xmlCleanupParser();
DEBUG("Loaded %d outfit%s", outfits, (outfits==1) ? "" : "s");
DEBUG("Loaded %d outfit%s", outfits, (outfits==1) ? "" : "s");
return 0;
}
@ -476,18 +476,18 @@ void outfit_free(void) {
int i;
for(i = 0; i < outfits; i++) {
// Free graphics.
if(outfit_gfx(&outfit_stack[i]))
gl_freeTexture(outfit_gfx(&outfit_stack[i]));
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);
if(outfit_stack[i].description)
free(outfit_stack[i].description);
if(outfit_stack[i].description)
free(outfit_stack[i].description);
if(outfit_stack[i].gfx_store)
gl_freeTexture(outfit_stack[i].gfx_store);
if(outfit_stack[i].gfx_store)
gl_freeTexture(outfit_stack[i].gfx_store);
free(outfit_stack[i].name);
}

View File

@ -21,10 +21,10 @@ typedef enum OutfitType_ {
OUTFIT_TYPE_MISSILE_SWARM_AMMO = 10,
OUTFIT_TYPE_MISSILE_SWARM_SMART = 11,
OUTFIT_TYPE_MISSILE_SWARM_SMART_AMMO = 12,
OUTFIT_TYPE_TURRET_BOLT = 13,
OUTFIT_TYPE_TURRET_BEAM = 14,
OUTFIT_TYPE_MODIFICATION = 15,
OUTFIT_TYPE_AFTERBURNER = 16
OUTFIT_TYPE_TURRET_BOLT = 13,
OUTFIT_TYPE_TURRET_BEAM = 14,
OUTFIT_TYPE_MODIFICATION = 15,
OUTFIT_TYPE_AFTERBURNER = 16
} OutfitType;
// An outfit depends a lot on the type.
@ -36,9 +36,9 @@ typedef struct Outfit_ {
int tech;
int mass;
// Store stuff.
unsigned int price;
char* description;
// Store stuff.
unsigned int price;
char* description;
glTexture* gfx_store; // Store graphic.
@ -49,53 +49,53 @@ typedef struct Outfit_ {
union {
struct { // Bolt.
unsigned int delay; // Delay between shots.
double speed; // Speed of shot. (not applicable to beam.
double speed; // Speed of shot. (not applicable to beam.
double range;
double accuracy; // Desviation accuracy.
double energy; // Energy usage.
double accuracy; // Desviation accuracy.
double energy; // Energy usage.
double damage_armour, damage_shield; // 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.
} bem;
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.
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.
double speed; // Max speed.
double turn; // Turn vel.
double thrust; // Acceleration.
double energy; // Energy usage.
double damage_armour, damage_shield; // 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.
glTexture* gfx_space;
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.
double thrust, turn, speed;
struct { // Modification.
// Movement.
double thrust, turn, speed;
// Health.
double armour, armour_regen;
double shield, shield_regen;
double energy, energy_regen;
} mod;
struct { // 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;
// Health.
double armour, armour_regen;
double shield, shield_regen;
double energy, energy_regen;
} mod;
struct { // 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;

View File

@ -52,25 +52,25 @@ static off_t getfilesize(const char* filename) {
ERR("Unable to get filesize of %s", filename);
return 0;
#else
long size;
FILE* fp = fopen(filename, "rb");
if(fp == NULL) return 0;
long size;
FILE* fp = fopen(filename, "rb");
if(fp == NULL) return 0;
fseek(fp, 0, SEEK_END);
size = ftell(fp);
fseek(fp, 0, SEEK_END);
size = ftell(fp);
fclose(fp);
fclose(fp);
return size;
return size;
#endif
}
// Return true if filename is a Packfile.
int pack_check(const char* filename) {
int ret;
char* buf;
int ret;
char* buf;
buf = malloc(sizeof(magic));
buf = malloc(sizeof(magic));
#ifdef _POSIX_SOURCE
int fd = open(filename, O_RDONLY);
@ -84,24 +84,24 @@ int pack_check(const char* filename) {
free(buf);
return -1;
}
ret = (memcmp(buf, &magic, sizeof(magic))==0) ? 0 : 1;
close(fd);
ret = (memcmp(buf, &magic, sizeof(magic))==0) ? 0 : 1;
close(fd);
#else
FILE* file = fopen(filename, "rb");
if(file == NULL) {
ERR("Error opening '%s': %s", filename, strerror(errno));
return -1;
}
FILE* file = fopen(filename, "rb");
if(file == NULL) {
ERR("Error opening '%s': %s", filename, strerror(errno));
return -1;
}
buf = malloc(sizeof(magic));
if(fread(buf, 1, sizeof(magic), file) != sizeof(magic)) {
ERR("Error reading magic number: %s", strerror(errno));
free(buf);
return -1;
}
buf = malloc(sizeof(magic));
if(fread(buf, 1, sizeof(magic), file) != sizeof(magic)) {
ERR("Error reading magic number: %s", strerror(errno));
free(buf);
return -1;
}
ret = (memcmp(buf, &magic, sizeof(magic))==0) ? 0 : 1;
fclose(file);
ret = (memcmp(buf, &magic, sizeof(magic))==0) ? 0 : 1;
fclose(file);
#endif
free(buf);
@ -110,9 +110,9 @@ int pack_check(const char* filename) {
// 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)); \
free(buf); return -1; }
#define WRITE(b,n) if(write(outfd, b, n)==-1) { \
ERR("Error writing to file: %s", strerror(errno)); \
free(buf); return -1; }
#else
#define WRITE(b,n) if(fwrite(b, 1, n, outf)==0) { \
ERR("Error writing to file: %s", strerror(errno)); \
@ -122,9 +122,9 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles)
void* buf;
#ifdef _POSIX_SOURCE
struct stat file;
int outfd, infd;
int outfd, infd;
#else
FILE* outf, *inf;
FILE* outf, *inf;
#endif
uint32_t i;
int namesize;
@ -137,14 +137,14 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles)
#ifdef _POSIX_SOURCE
if(stat(infiles[i], &file)) {
#else
if(getfilesize(infiles[i]) == 0) {
if(getfilesize(infiles[i]) == 0) {
#endif
ERR("File %s does not exist", infiles[i]);
return -1;
}
if(strlen(infiles[i]) > MAX_FILENAME) {
ERR("filename '%s' is too long, should be only %d characters", infiles[i],
MAX_FILENAME);
MAX_FILENAME);
return -1;
}
namesize += strlen(infiles[i]);
@ -160,8 +160,8 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles)
outfd = creat(outfile, PERMS);
if(outfd == -1) {
#else
outf = fopen(outfile, "wb");
if(outf == NULL) {
outf = fopen(outfile, "wb");
if(outf == NULL) {
#endif
ERR("Unable to open %s for writing", outfile);
return -1;
@ -195,13 +195,13 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles)
DEBUG("About to write '%s' of %d bytes", infiles[i], bytes);
md5_init(&md5);
#ifdef _POSIX_SOURCE
infd = open(infiles[i], O_RDONLY);
infd = open(infiles[i], O_RDONLY);
while((bytes = read(infd, buf, BLOCKSIZE))) {
#else
inf = fopen(infiles[i], "rb");
while((bytes = fread(buf, 1, BLOCKSIZE, inf))) {
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);
@ -209,7 +209,7 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles)
#ifdef _POSIX_SOURCE
close(infd);
#else
fclose(inf);
fclose(inf);
#endif
DEBUG("Wrote file '%s'", infiles[i]);
}
@ -218,25 +218,25 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles)
#ifdef _POSIX_SOURCE
close(outfd);
#else
fclose(outf);
fclose(outf);
#endif
free(buf);
DEBUG("Packfile success\n\t%d files\n\t%d bytes",
nfiles, (int)getfilesize(outfile));
nfiles, (int)getfilesize(outfile));
return 0;
}
#undef WRITE
// Opens the filename in packfile for reading.
#ifdef _POSIX_SOURCE
#define READ(b,n) if(read(file->fd, (b), (n))!=(n)) { \
#define READ(b,n) if(read(file->fd, (b), (n))!=(n)) { \
ERR("Too few bytes read. Expected more."); \
free(buf); return -1; }
#else
#define READ(b,n) if(fread((b), 1, (n), file->fp)!=(n)) { \
ERR("Fewer bytes read then expected"); \
free(buf); return -1; }
#define READ(b,n) if(fread((b), 1, (n), file->fp)!=(n)) { \
ERR("Fewer bytes read then expected"); \
free(buf); return -1; }
#endif
int pack_open(Packfile* file, const char* packfile, const char* filename) {
int j;
@ -249,8 +249,8 @@ int pack_open(Packfile* file, const char* packfile, const char* filename) {
file->fd = open(packfile, O_RDONLY);
if(file->fd == -1) {
#else
file->fp = fopen(packfile, "rb");
if(file->fp == NULL) {
file->fp = fopen(packfile, "rb");
if(file->fp == NULL) {
#endif
ERR("Error opening %s: %s", filename, strerror(errno));
return -1;
@ -279,7 +279,7 @@ int pack_open(Packfile* file, const char* packfile, const char* filename) {
#ifdef _POSIX_SOURCE
lseek(file->fd, 4, SEEK_CUR); // Ignore the file location.
#else
fseek(file->fp, 4, SEEK_CUR);
fseek(file->fp, 4, SEEK_CUR);
#endif
}
free(buf);
@ -289,13 +289,13 @@ int pack_open(Packfile* file, const char* packfile, const char* filename) {
#ifdef _POSIX_SOURCE
if((uint32_t)lseek(file->fd, file->start, SEEK_SET) != file->start) {
#else
fseek(file->fp, file->start, SEEK_SET);
if(errno) {
fseek(file->fp, file->start, SEEK_SET);
if(errno) {
#endif
ERR("Failure to seek to file start: %s", strerror(errno));
return -1;
}
READ(&file->end, 4);
READ(&file->end, 4);
DEBUG("\t%d bytes", file->end);
file->pos = file->start;
file->end += file->start;
@ -310,7 +310,7 @@ int pack_open(Packfile* file, const char* packfile, const char* filename) {
// 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;
@ -318,7 +318,7 @@ ssize_t pack_read(Packfile* file, void* buf, size_t count) {
#ifdef _POSIX_SOURCE
if((bytes = read(file->fd, buf, count)) == -1) {
#else
if((bytes = fread(buf, 1, count, file->fp)) == -1) {
if((bytes = fread(buf, 1, count, file->fp)) == -1) {
#endif
ERR("Error while reading file: %s", strerror(errno));
return -1;
@ -330,52 +330,52 @@ ssize_t pack_read(Packfile* file, void* buf, size_t count) {
// 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;
switch(whence) {
DEBUG("Attempting to seek offset: %d, whence: %d", offset, whence);
off_t ret;
switch(whence) {
#ifdef _POSIX_SOURCE
case SEEK_SET:
if((file->start + offset) > file->end) return -1;
ret = lseek(file->fd, file->start + offset, SEEK_SET);
if(ret != ((off_t)file->start + offset)) return -1;
break;
case SEEK_CUR:
if((file->start + offset) > file->end) return -1;
ret = lseek(file->fd, file->pos + offset, SEEK_SET);
if(ret != ((off_t)file->pos + offset)) return -1;
break;
case SEEK_END:
if((file->end - offset) < file->start) return -1;
ret = lseek(file->fd, file->end - offset - 1, SEEK_SET);
if(ret != ((off_t)file->end - offset)) return -1;
break;
case SEEK_SET:
if((file->start + offset) > file->end) return -1;
ret = lseek(file->fd, file->start + offset, SEEK_SET);
if(ret != ((off_t)file->start + offset)) return -1;
break;
case SEEK_CUR:
if((file->start + offset) > file->end) return -1;
ret = lseek(file->fd, file->pos + offset, SEEK_SET);
if(ret != ((off_t)file->pos + offset)) return -1;
break;
case SEEK_END:
if((file->end - offset) < file->start) return -1;
ret = lseek(file->fd, file->end - offset - 1, SEEK_SET);
if(ret != ((off_t)file->end - offset)) return -1;
break;
#else
case SEEK_SET:
if((file->start + offset) > file->end) return -1;
ret = fseek(file->fd, file->start + offset, SEEK_SET);
if(ret != (file->start + offset)) return -1;
break;
case SEEK_CUR:
if((file->start + offset) > file->end) return -1;
ret = flseek(file->fd, file->pos + offset, SEEK_SET);
if(ret != (file->pos + offset)) return -1;
break;
case SEEK_END:
if((file->end - offset) < file->start) return -1;
ret = flseek(file->fd, file->end - offset - 1, SEEK_SET);
if(ret != (file->end - offset)) return -1;
break;
case SEEK_SET:
if((file->start + offset) > file->end) return -1;
ret = fseek(file->fd, file->start + offset, SEEK_SET);
if(ret != (file->start + offset)) return -1;
break;
case SEEK_CUR:
if((file->start + offset) > file->end) return -1;
ret = flseek(file->fd, file->pos + offset, SEEK_SET);
if(ret != (file->pos + offset)) return -1;
break;
case SEEK_END:
if((file->end - offset) < file->start) return -1;
ret = flseek(file->fd, file->end - offset - 1, SEEK_SET);
if(ret != (file->end - offset)) return -1;
break;
#endif
default:
ERR("Whence is not one of SEEK_SET, SEEK_CUR or SEEK_END");
return -1;
}
return ret - file->start;
default:
ERR("Whence is not one of SEEK_SET, SEEK_CUR or SEEK_END");
return -1;
}
return ret - file->start;
}
// Return current pointer position.
long pack_tell(Packfile* file) {
return file->pos - file->start;
return file->pos - file->start;
}
// Loads an entire file into memory and returns a pointer to it.
@ -398,7 +398,7 @@ void* pack_readfile(const char* packfile, const char* filename, uint32_t* filesi
buf = malloc(size+1);
if((bytes = pack_read(file, buf, size)) != size) {
ERR("Reading '%s' from packfile '%s'. Expected %d bytes got %d bytes",
filename, packfile, size, bytes);
filename, packfile, size, bytes);
free(buf);
free(file);
return NULL;
@ -416,7 +416,7 @@ void* pack_readfile(const char* packfile, const char* filename, uint32_t* filesi
#ifdef _POSIX_SOURCE
if((bytes = read(file->fd, md5fd, 16)) == -1)
#else
if((bytes = fread(md5fd, 1, 16, file->fp)) == -1)
if((bytes = fread(md5fd, 1, 16, file->fp)) == -1)
#endif
WARN("Failure to read MD5, continuing anyway..");
else if(memcmp(md5val, md5fd, 16))
@ -442,19 +442,19 @@ void* pack_readfile(const char* packfile, const char* filename, uint32_t* filesi
// 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"); \
return NULL; }
#define READ(b,n) if(read(fd, (b), (n))!=(n)) { \
ERR("Too few bytes read"); \
return NULL; }
#else
#define READ(b,n) if(fread((b), 1, (n), fp) != (n)) { \
ERR("Too few bytes read"); \
return NULL; }
#define READ(b,n) if(fread((b), 1, (n), fp) != (n)) { \
ERR("Too few bytes read"); \
return NULL; }
#endif
char** pack_listfiles(const char* packfile, uint32_t* nfiles) {
#ifdef _POSIX_SOURCE
int fd;
int fd;
#else
FILE* fp;
FILE* fp;
#endif
int j;
uint32_t i;
@ -467,8 +467,8 @@ char** pack_listfiles(const char* packfile, uint32_t* nfiles) {
fd = open(packfile, O_RDONLY);
if(fd == -1) {
#else
fp = fopen(packfile, "rb");
if(fp == NULL) {
fp = fopen(packfile, "rb");
if(fp == NULL) {
#endif
ERR("opening %s: %s", packfile, strerror(errno));
return NULL;
@ -495,7 +495,7 @@ char** pack_listfiles(const char* packfile, uint32_t* nfiles) {
#ifdef _POSIX_SOURCE
close(fd);
#else
fclose(fp);
fclose(fp);
#endif
return filenames;
@ -504,11 +504,11 @@ char** pack_listfiles(const char* packfile, uint32_t* nfiles) {
// Close the packfile.
int pack_close(Packfile* file) {
int i;
int i;
#ifdef _POSIX_SOURCE
i = close(file->fd);
#else
i = fclose(file->fp);
i = fclose(file->fp);
#endif
return (i) ? -1 : 0;
}

View File

@ -9,7 +9,7 @@ typedef struct Packfile_ {
#ifdef _POSIX_SOURCE
int fd; // File descriptor.
#else
FILE* fp;
FILE* fp;
#endif
uint32_t pos; // position.
uint32_t start, end; // file limits.

View File

@ -26,8 +26,8 @@ void pause(void) {
pilots_pause();
weapons_pause();
spfx_pause();
spawn_timer -= SDL_GetTicks();
spfx_pause();
spawn_timer -= SDL_GetTicks();
paused = 1; // We should unpause it.
}
@ -37,17 +37,17 @@ void unpause(void) {
pilots_unpause();
weapons_unpause();
spfx_unpause();
spawn_timer += SDL_GetTicks();
spfx_unpause();
spawn_timer += SDL_GetTicks();
paused = 0;
}
// Set the timers back.
void pause_delay(unsigned int delay) {
pilots_delay(delay);
weapons_delay(delay);
spfx_delay(delay);
pilots_delay(delay);
weapons_delay(delay);
spfx_delay(delay);
}
static void pilots_pause(void) {
@ -75,13 +75,13 @@ static void pilots_unpause(void) {
}
static void pilots_delay(unsigned int delay) {
int i, j;
for(i = 0; i < pilots; i++) {
pilot_stack[i]->ptimer += delay;
int i, j;
for(i = 0; i < pilots; i++) {
pilot_stack[i]->ptimer += delay;
pilot_stack[i]->tcontrol += delay;
for(j = 0; j < MAX_AI_TIMERS; j++)
pilot_stack[i]->timer[j] += delay;
}
pilot_stack[i]->tcontrol += delay;
for(j = 0; j < MAX_AI_TIMERS; j++)
pilot_stack[i]->timer[j] += delay;
}
}

View File

@ -15,9 +15,9 @@ double angle_diff(const double ref, double a) {
}
void limit_speed(Vec2* vel, const double speed, const double dt) {
double vmod = VMOD(*vel);
if(vmod > speed) // Should not go faster.
vect_pset(vel, (vmod-speed)*(1.-dt*3.) + speed, VANGLE(*vel));
double vmod = VMOD(*vel);
if(vmod > speed) // Should not go faster.
vect_pset(vel, (vmod-speed)*(1.-dt*3.) + speed, VANGLE(*vel));
}
// ================
@ -190,7 +190,7 @@ static void rk4_update(Solid* obj, const double dt) {
// Initialize a new solid.
void solid_init(Solid* dest, const double mass, const double dir,
const Vec2* pos, const Vec2* vel) {
const Vec2* pos, const Vec2* vel) {
dest->mass = mass;
dest->dir_vel = 0.;
@ -211,7 +211,7 @@ void solid_init(Solid* dest, const double mass, const double dir,
// Create a new solid.
Solid* solid_create(const double mass, const double dir,
const Vec2* pos, const Vec2* vel) {
const Vec2* pos, const Vec2* vel) {
Solid* dyn = MALLOC_L(Solid);
if(dyn == NULL) ERR("Out of memory");
solid_init(dyn, mass, dir, pos, vel);

View File

@ -140,8 +140,8 @@ double pilot_face(Pilot* p, const float dir) {
// Return quantity of a pilot outfit.
static int pilot_oquantity(Pilot* p, PilotOutfit* w) {
return (outfit_isAmmo(w->outfit) && p->secondary) ?
p->secondary->quantity : w->quantity;
return (outfit_isAmmo(w->outfit) && p->secondary) ?
p->secondary->quantity : w->quantity;
}
// Mkay, this is how we shoot. Listen up.
@ -163,10 +163,10 @@ void pilot_shoot(Pilot* p, const unsigned int target, const int secondary) {
}
static void pilot_shootWeapon(Pilot* p, PilotOutfit* w, const unsigned int t) {
int quantity, delay;
int quantity, delay;
// WElll... Trying to shoot when you have no ammo?? FUUU
quantity = pilot_oquantity(p,w);
delay = outfit_delay(w->outfit);
quantity = pilot_oquantity(p,w);
delay = outfit_delay(w->outfit);
// Check to see if weapon is ready.
if((SDL_GetTicks() - w->timer) < (unsigned int)(delay/quantity)) return;
@ -174,14 +174,14 @@ static void pilot_shootWeapon(Pilot* p, PilotOutfit* w, const unsigned int t) {
if(outfit_isWeapon(w->outfit) || (outfit_isTurret(w->outfit))) {
// Different weapons.
switch(w->outfit->type) {
case OUTFIT_TYPE_TURRET_BOLT:
case OUTFIT_TYPE_TURRET_BOLT:
case OUTFIT_TYPE_BOLT:
// Enough energy?
if(outfit_energy(w->outfit) > p->energy) return;
// Enough energy?
if(outfit_energy(w->outfit) > p->energy) return;
p->energy -= outfit_energy(w->outfit);
p->energy -= outfit_energy(w->outfit);
weapon_add(w->outfit, p->solid->dir, &p->solid->pos,
&p->solid->vel, p->id, t);
&p->solid->vel, p->id, t);
// Can't shoot for a while.
w->timer = SDL_GetTicks();
@ -194,12 +194,12 @@ static void pilot_shootWeapon(Pilot* p, PilotOutfit* w, const unsigned int t) {
// Must be secondary weapon, Shooter can't be the target.
else if(outfit_isLauncher(w->outfit) && (w == p->secondary) && (p->id != t)) {
if(p->ammo && (p->ammo->quantity > 0)) {
// Enough energy?
if(outfit_energy(w->outfit) > p->energy) return;
// Enough energy?
if(outfit_energy(w->outfit) > p->energy) return;
p->energy -= outfit_energy(w->outfit);
p->energy -= outfit_energy(w->outfit);
weapon_add(p->ammo->outfit, p->solid->dir, &p->solid->pos,
&p->solid->vel, p->id, t);
&p->solid->vel, p->id, t);
w->timer = SDL_GetTicks(); // Can't shoot for a while.
p->ammo->quantity -= 1; // There's no getting this one back.
@ -209,72 +209,72 @@ static void pilot_shootWeapon(Pilot* p, PilotOutfit* w, const unsigned int t) {
// Damage the pilot.
void pilot_hit(Pilot* p, const Solid* w, const unsigned int shooter,
const double damage_shield, const double damage_armour) {
const double damage_shield, const double damage_armour) {
double dam_mod;
double dam_mod;
if(p->shield - damage_shield > 0.) {
p->shield -= damage_shield;
dam_mod = damage_shield/p->shield_max;
}
dam_mod = damage_shield/p->shield_max;
}
else if(p->shield > 0.) {
// Shields can take part of the blow.
p->armour -= p->shield/damage_shield*damage_armour;
p->shield = 0.;
dam_mod = (damage_shield+damage_armour) / (p->shield_max + p->armour_max);
dam_mod = (damage_shield+damage_armour) / (p->shield_max + p->armour_max);
}
else if(p->armour-damage_armour > 0.) {
p->armour -= damage_armour;
dam_mod = damage_armour/p->armour_max;
}
dam_mod = damage_armour/p->armour_max;
}
else {
// We are officially dead.
// We are officially dead.
p->armour = 0.;
dam_mod = 0.;
dam_mod = 0.;
if(!pilot_isFlag(p, PILOT_DEAD)) {
pilot_dead(p);
// Adjust the combat rating based on pilot mass.
if(shooter == PLAYER_ID) combat_crating += MAX(1, p->ship->mass/50);
}
}
if(!pilot_isFlag(p, PILOT_DEAD)) {
pilot_dead(p);
// Adjust the combat rating based on pilot mass.
if(shooter == PLAYER_ID) combat_crating += MAX(1, p->ship->mass/50);
}
}
// Knock back effect is dependent on both damage and mass of the weapon.
// should probably turn it into a partial conservative collision..
vect_cadd(&p->solid->vel,
w->vel.x * (dam_mod/6. + w->mass/p->solid->mass/6.),
w->vel.y * (dam_mod/6. + w->mass/p->solid->mass/6.));
// Knock back effect is dependent on both damage and mass of the weapon.
// should probably turn it into a partial conservative collision..
vect_cadd(&p->solid->vel,
w->vel.x * (dam_mod/6. + w->mass/p->solid->mass/6.),
w->vel.y * (dam_mod/6. + w->mass/p->solid->mass/6.));
}
void pilot_dead(Pilot* p) {
// Basically just set the timers..
if(p->id == PLAYER_ID) player_dead();
p->timer[0] = SDL_GetTicks(); // No need for AI anymore.
p->ptimer = p->timer[0] + 1000 + (unsigned int)sqrt(10*p->armour_max*p->shield_max);
p->timer[1] = p->timer[0]; // Explosion timer.
pilot_setFlag(p, PILOT_DEAD);
// Basically just set the timers..
if(p->id == PLAYER_ID) player_dead();
p->timer[0] = SDL_GetTicks(); // No need for AI anymore.
p->ptimer = p->timer[0] + 1000 + (unsigned int)sqrt(10*p->armour_max*p->shield_max);
p->timer[1] = p->timer[0]; // Explosion timer.
pilot_setFlag(p, PILOT_DEAD);
}
void pilot_setSecondary(Pilot* p, const char* secondary) {
int i;
int i;
if(secondary == NULL) {
p->secondary = NULL;
p->ammo = NULL;
return;
}
if(secondary == NULL) {
p->secondary = NULL;
p->ammo = NULL;
return;
}
for(i = 0; i < p->noutfits; i++) {
if(strcmp(secondary, p->outfits[i].outfit->name)==0) {
p->secondary = &p->outfits[i];;
pilot_setAmmo(p);
return;
}
}
WARN("Attempted to set pilot '%s' secondary weapon to non-existing '%s'",
p->name, secondary);
p->secondary = NULL;
p->ammo = NULL;
for(i = 0; i < p->noutfits; i++) {
if(strcmp(secondary, p->outfits[i].outfit->name)==0) {
p->secondary = &p->outfits[i];;
pilot_setAmmo(p);
return;
}
}
WARN("Attempted to set pilot '%s' secondary weapon to non-existing '%s'",
p->name, secondary);
p->secondary = NULL;
p->ammo = NULL;
}
// Set the pilot's ammo based on their secondary weapon.
@ -301,102 +301,102 @@ void pilot_setAmmo(Pilot* p) {
// Render the pilot.
void pilot_render(Pilot* p) {
gl_blitSprite(p->ship->gfx_space,
p->solid->pos.x, p->solid->pos.y,
p->tsx, p->tsy, NULL);
p->solid->pos.x, p->solid->pos.y,
p->tsx, p->tsy, NULL);
}
// Update the pilot.
static void pilot_update(Pilot* pilot, const double dt) {
unsigned int t, l;
double a, px, py, vx, vy;
unsigned int t, l;
double a, px, py, vx, vy;
if(pilot_isFlag(pilot, PILOT_DEAD)) {
t = SDL_GetTicks();
if(pilot_isFlag(pilot, PILOT_DEAD)) {
t = SDL_GetTicks();
if(t > pilot->ptimer) {
if(pilot->id == PLAYER_ID)
player_destroyed();
pilot_setFlag(pilot, PILOT_DELETE); // It'll get deleted next frame.
return;
}
if(t > pilot->ptimer) {
if(pilot->id == PLAYER_ID)
player_destroyed();
pilot_setFlag(pilot, PILOT_DELETE); // It'll get deleted next frame.
return;
}
if(!pilot_isFlag(pilot, PILOT_EXPLODED) && (t > pilot->ptimer - 200)) {
spfx_add(spfx_get("ExpL"),
VX(pilot->solid->pos), VY(pilot->solid->pos),
VX(pilot->solid->vel), VY(pilot->solid->vel), SPFX_LAYER_BACK);
pilot_setFlag(pilot, PILOT_EXPLODED);
}
else if(t > pilot->timer[1]) {
pilot->timer[1] = t +
(unsigned int)(100*(double)(pilot->ptimer - pilot->timer[1]) /
(double)(pilot->ptimer - pilot->timer[0]));
if(!pilot_isFlag(pilot, PILOT_EXPLODED) && (t > pilot->ptimer - 200)) {
spfx_add(spfx_get("ExpL"),
VX(pilot->solid->pos), VY(pilot->solid->pos),
VX(pilot->solid->vel), VY(pilot->solid->vel), SPFX_LAYER_BACK);
pilot_setFlag(pilot, PILOT_EXPLODED);
}
else if(t > pilot->timer[1]) {
pilot->timer[1] = t +
(unsigned int)(100*(double)(pilot->ptimer - pilot->timer[1]) /
(double)(pilot->ptimer - pilot->timer[0]));
// Random position on ship.
a = RNGF()*2.*M_PI;
px = VX(pilot->solid->pos) + cos(a)*RNGF()*pilot->ship->gfx_space->sw/2.;
py = VY(pilot->solid->pos) + sin(a)*RNGF()*pilot->ship->gfx_space->sh/2.;
// Random position on ship.
a = RNGF()*2.*M_PI;
px = VX(pilot->solid->pos) + cos(a)*RNGF()*pilot->ship->gfx_space->sw/2.;
py = VY(pilot->solid->pos) + sin(a)*RNGF()*pilot->ship->gfx_space->sh/2.;
vx = VX(pilot->solid->vel);
vy = VY(pilot->solid->vel);
vx = VX(pilot->solid->vel);
vy = VY(pilot->solid->vel);
// Set explosions.
l = (pilot->id == PLAYER_ID) ? SPFX_LAYER_FRONT : SPFX_LAYER_BACK;
if(RNGF() > 0.8) spfx_add(spfx_get("ExpM"), px, py, vx, vy, l);
else spfx_add(spfx_get("ExpS"), px, py, vx, vy, l);
}
}
else if(pilot->armour <= 0.) // PWNED!
pilot_dead(pilot);
// Set explosions.
l = (pilot->id == PLAYER_ID) ? SPFX_LAYER_FRONT : SPFX_LAYER_BACK;
if(RNGF() > 0.8) spfx_add(spfx_get("ExpM"), px, py, vx, vy, l);
else spfx_add(spfx_get("ExpS"), px, py, vx, vy, l);
}
}
else if(pilot->armour <= 0.) // PWNED!
pilot_dead(pilot);
// Pupose fallthrough to get the movement similar to disabled.
// Pupose fallthrough to get the movement similar to disabled.
if(pilot != player && pilot->armour < PILOT_DISABLED_ARMOUR * pilot->armour_max) {
// We are disabled.
pilot_setFlag(pilot, PILOT_DISABLED);
// Come to a halt slowly.
vect_pset(&pilot->solid->vel,
VMOD(pilot->solid->vel) * (1. - dt*0.10), VANGLE(pilot->solid->vel));
VMOD(pilot->solid->vel) * (1. - dt*0.10), VANGLE(pilot->solid->vel));
vectnull(&pilot->solid->force);
pilot->solid->dir_vel = 0.; // Stop it from turning.
// Update the solid.
pilot->solid->update(pilot->solid, dt);
gl_getSpriteFromDir(&pilot->tsx, &pilot->tsy,
pilot->ship->gfx_space, pilot->solid->dir);
gl_getSpriteFromDir(&pilot->tsx, &pilot->tsy,
pilot->ship->gfx_space, pilot->solid->dir);
return;
}
// We are still alive.
else if(pilot->armour < pilot->armour_max) {
pilot->armour += pilot->armour_regen*dt;
pilot->energy += pilot->energy_regen*dt;
} else {
pilot->energy += pilot->energy_regen*dt;
} else {
pilot->shield += pilot->shield_regen*dt;
pilot->energy += pilot->energy_regen*dt;
}
pilot->energy += pilot->energy_regen*dt;
}
if(pilot->armour > pilot->armour_max) pilot->armour = pilot->armour_max;
if(pilot->shield > pilot->shield_max) pilot->shield = pilot->shield_max;
if(pilot->energy > pilot->energy_max) pilot->energy = pilot->energy_max;
if(pilot->energy > pilot->energy_max) pilot->energy = pilot->energy_max;
// Update the solid.
(*pilot->solid->update)(pilot->solid, dt);
gl_getSpriteFromDir(&pilot->tsx, &pilot->tsy,
pilot->ship->gfx_space, pilot->solid->dir);
gl_getSpriteFromDir(&pilot->tsx, &pilot->tsy,
pilot->ship->gfx_space, pilot->solid->dir);
if(!pilot_isFlag(pilot, PILOT_HYPERSPACE)) { // Limit the speed.
if(pilot_isFlag(pilot, PILOT_AFTERBURNER) && // Must have enough energy.
(player->energy > pilot->afterburner->outfit->u.afb.energy * dt)) {
limit_speed(&pilot->solid->vel,
pilot->speed * pilot->afterburner->outfit->u.afb.speed_perc +
pilot->afterburner->outfit->u.afb.speed_abs, dt);
pilot->energy -= pilot->afterburner->outfit->u.afb.energy * dt;
} else
limit_speed(&pilot->solid->vel, pilot->speed, dt);
}
if(!pilot_isFlag(pilot, PILOT_HYPERSPACE)) { // Limit the speed.
if(pilot_isFlag(pilot, PILOT_AFTERBURNER) && // Must have enough energy.
(player->energy > pilot->afterburner->outfit->u.afb.energy * dt)) {
limit_speed(&pilot->solid->vel,
pilot->speed * pilot->afterburner->outfit->u.afb.speed_perc +
pilot->afterburner->outfit->u.afb.speed_abs, dt);
pilot->energy -= pilot->afterburner->outfit->u.afb.energy * dt;
} else
limit_speed(&pilot->solid->vel, pilot->speed, dt);
}
}
// Pilot is getting ready or is in, hyperspace.
static void pilot_hyperspace(Pilot* p) {
double diff;
double diff;
if(pilot_isFlag(p, PILOT_HYPERSPACE)) {
// Pilot is actually in hyperspace.
@ -421,14 +421,14 @@ static void pilot_hyperspace(Pilot* p) {
if(VMOD(p->solid->vel) > MIN_VEL_ERR) {
diff = pilot_face(p, VANGLE(p->solid->vel) + M_PI);
if(ABS(diff) < MAX_DIR_ERR) // Brake.
vect_pset(&p->solid->force, p->thrust, p->solid->dir);
if(ABS(diff) < MAX_DIR_ERR) // Brake.
vect_pset(&p->solid->force, p->thrust, p->solid->dir);
} else {
vectnull(&p->solid->force); // Stop accelerating.
// Player should actually face the system she's headed to.
if(p == player) diff = player_faceHyperspace();
else diff = pilot_face(p, VANGLE(p->solid->pos));
// Player should actually face the system she's headed to.
if(p == player) diff = player_faceHyperspace();
else diff = pilot_face(p, VANGLE(p->solid->pos));
if(ABS(diff) < MAX_DIR_ERR) {
// We should prepare for the jump now.
@ -441,188 +441,188 @@ static void pilot_hyperspace(Pilot* p) {
}
int pilot_addOutfit(Pilot* pilot, Outfit* outfit, int quantity) {
int i, q;
char* s;
int i, q;
char* s;
q = quantity;
q = quantity;
for(i = 0; i < pilot->noutfits; i++)
if(strcmp(outfit->name, pilot->outfits[i].outfit->name)==0) {
pilot->outfits[i].quantity += quantity;
// Can't be over max.
if(pilot->outfits[i].quantity > outfit->max) {
q -= pilot->outfits[i].quantity - outfit->max;
pilot->outfits[i].quantity = outfit->max;
}
pilot_calcStats(pilot);
return q;
}
for(i = 0; i < pilot->noutfits; i++)
if(strcmp(outfit->name, pilot->outfits[i].outfit->name)==0) {
pilot->outfits[i].quantity += quantity;
// Can't be over max.
if(pilot->outfits[i].quantity > outfit->max) {
q -= pilot->outfits[i].quantity - outfit->max;
pilot->outfits[i].quantity = outfit->max;
}
pilot_calcStats(pilot);
return q;
}
s = (pilot->secondary) ? pilot->secondary->outfit->name : NULL;
pilot->outfits = realloc(pilot->outfits, (pilot->noutfits+1)*sizeof(PilotOutfit));
pilot->outfits[pilot->noutfits].outfit = outfit;
pilot->outfits[pilot->noutfits].quantity = quantity;
// Can't be over max.
if(pilot->outfits[pilot->noutfits].quantity > outfit->max) {
q -= pilot->outfits[pilot->noutfits].quantity - outfit->max;
pilot->outfits[i].quantity = outfit->max;
}
pilot->outfits[pilot->noutfits].timer = 0;
(pilot->noutfits)++;
s = (pilot->secondary) ? pilot->secondary->outfit->name : NULL;
pilot->outfits = realloc(pilot->outfits, (pilot->noutfits+1)*sizeof(PilotOutfit));
pilot->outfits[pilot->noutfits].outfit = outfit;
pilot->outfits[pilot->noutfits].quantity = quantity;
// Can't be over max.
if(pilot->outfits[pilot->noutfits].quantity > outfit->max) {
q -= pilot->outfits[pilot->noutfits].quantity - outfit->max;
pilot->outfits[i].quantity = outfit->max;
}
pilot->outfits[pilot->noutfits].timer = 0;
(pilot->noutfits)++;
if(outfit_isTurret(outfit))
// Used to speed up AI.
pilot_setFlag(pilot, PILOT_HASTURRET);
if(outfit_isTurret(outfit))
// Used to speed up AI.
pilot_setFlag(pilot, PILOT_HASTURRET);
// Hack due to realloc possibility.
pilot_setSecondary(pilot, s);
// Hack due to realloc possibility.
pilot_setSecondary(pilot, s);
pilot_calcStats(pilot);
return q;
pilot_calcStats(pilot);
return q;
}
// Remove an outfit from the pilot.
int pilot_rmOutfit(Pilot* pilot, Outfit* outfit, int quantity) {
int i, q;
char* s;
int i, q;
char* s;
q = quantity;
q = quantity;
for(i = 0; i < pilot->noutfits; i++)
if(strcmp(outfit->name, pilot->outfits[i].outfit->name)==0) {
pilot->outfits[i].quantity -= quantity;
if(pilot->outfits[i].quantity <= 0) {
// We didn't actually remove the full amount.
q += pilot->outfits[i].quantity;
// Hack in case it reallocs - Can happen even when shrinking.
s = (pilot->secondary) ? pilot->secondary->outfit->name : NULL;
// Clear it if it's the afterburner.
if(&pilot->outfits[i] == pilot->afterburner)
pilot->afterburner = NULL;
for(i = 0; i < pilot->noutfits; i++)
if(strcmp(outfit->name, pilot->outfits[i].outfit->name)==0) {
pilot->outfits[i].quantity -= quantity;
if(pilot->outfits[i].quantity <= 0) {
// We didn't actually remove the full amount.
q += pilot->outfits[i].quantity;
// Hack in case it reallocs - Can happen even when shrinking.
s = (pilot->secondary) ? pilot->secondary->outfit->name : NULL;
// Clear it if it's the afterburner.
if(&pilot->outfits[i] == pilot->afterburner)
pilot->afterburner = NULL;
// Remove the outfit.
memmove(pilot->outfits+i, pilot->outfits+i+1,
sizeof(PilotOutfit)*(pilot->noutfits-i));
pilot->noutfits--;
pilot->outfits = realloc(pilot->outfits,
sizeof(PilotOutfit)*(pilot->noutfits));
// Remove the outfit.
memmove(pilot->outfits+i, pilot->outfits+i+1,
sizeof(PilotOutfit)*(pilot->noutfits-i));
pilot->noutfits--;
pilot->outfits = realloc(pilot->outfits,
sizeof(PilotOutfit)*(pilot->noutfits));
pilot_setSecondary(pilot, s);
}
return q;
}
WARN("Failure attempting to remove %d '%s' from pilot '%s'",
quantity, outfit->name, pilot->name);
pilot_setSecondary(pilot, s);
}
return q;
}
WARN("Failure attempting to remove %d '%s' from pilot '%s'",
quantity, outfit->name, pilot->name);
return 0;
return 0;
}
// Recalculate the pilot's stats based on her outfits.
static void pilot_calcStats(Pilot* pilot) {
int i;
double q;
Outfit* o;
double ac, sc, ec; // Temp health coeficients to set.
int i;
double q;
Outfit* o;
double ac, sc, ec; // Temp health coeficients to set.
// -- Set up the basic stuff.
// Movement.
pilot->thrust = pilot->ship->thrust;
pilot->turn = pilot->ship->turn;
pilot->speed = pilot->ship->speed;
// Health.
ac = pilot->armour / pilot->armour_max;
sc = pilot->shield / pilot->shield_max;
ec = pilot->energy / pilot->energy_max;
pilot->armour_max = pilot->ship->armour;
pilot->shield_max = pilot->ship->shield;
pilot->energy_max = pilot->ship->energy;
pilot->armour_regen = pilot->ship->armour_regen;
pilot->shield_regen = pilot->ship->shield_regen;
pilot->energy_regen = pilot->ship->energy_regen;
// -- Set up the basic stuff.
// Movement.
pilot->thrust = pilot->ship->thrust;
pilot->turn = pilot->ship->turn;
pilot->speed = pilot->ship->speed;
// Health.
ac = pilot->armour / pilot->armour_max;
sc = pilot->shield / pilot->shield_max;
ec = pilot->energy / pilot->energy_max;
pilot->armour_max = pilot->ship->armour;
pilot->shield_max = pilot->ship->shield;
pilot->energy_max = pilot->ship->energy;
pilot->armour_regen = pilot->ship->armour_regen;
pilot->shield_regen = pilot->ship->shield_regen;
pilot->energy_regen = pilot->ship->energy_regen;
// Now add outfit changes.
for(i = 0; i < pilot->noutfits; i++) {
if(outfit_isMod(pilot->outfits[i].outfit)) {
q = (double) pilot->outfits[i].quantity;
o = pilot->outfits[i].outfit;
// Now add outfit changes.
for(i = 0; i < pilot->noutfits; i++) {
if(outfit_isMod(pilot->outfits[i].outfit)) {
q = (double) pilot->outfits[i].quantity;
o = pilot->outfits[i].outfit;
// Movement.
pilot->thrust += o->u.mod.thrust * q;
pilot->turn += o->u.mod.turn * q;
pilot->speed += o->u.mod.speed * q;
// Health.
pilot->armour_max += o->u.mod.armour * q;
pilot->armour_regen += o->u.mod.armour_regen * q;
pilot->shield_max += o->u.mod.shield * q;
pilot->shield_regen += o->u.mod.shield_regen * q;
pilot->energy_max += o->u.mod.energy * q;
pilot->energy_regen += o->u.mod.energy_regen * q;
// Movement.
pilot->thrust += o->u.mod.thrust * q;
pilot->turn += o->u.mod.turn * q;
pilot->speed += o->u.mod.speed * q;
// Health.
pilot->armour_max += o->u.mod.armour * q;
pilot->armour_regen += o->u.mod.armour_regen * q;
pilot->shield_max += o->u.mod.shield * q;
pilot->shield_regen += o->u.mod.shield_regen * q;
pilot->energy_max += o->u.mod.energy * q;
pilot->energy_regen += o->u.mod.energy_regen * q;
}
else if(outfit_isAfterburner(pilot->outfits[i].outfit)) {
// Set the afterburner.
pilot->afterburner = &pilot->outfits[i];
}
}
}
else if(outfit_isAfterburner(pilot->outfits[i].outfit)) {
// Set the afterburner.
pilot->afterburner = &pilot->outfits[i];
}
}
// Give the pilot her health proportion back.
pilot->armour = ac * pilot->armour_max;
pilot->shield = sc * pilot->shield_max;
pilot->energy = ec * pilot->energy_max;
// Give the pilot her health proportion back.
pilot->armour = ac * pilot->armour_max;
pilot->shield = sc * pilot->shield_max;
pilot->energy = ec * pilot->energy_max;
}
// Try to add quantity of cargo to pilot, return quantity actually added.
int pilot_addCargo(Pilot* pilot, Commodity* cargo, int quantity) {
int i, q;
int i, q;
q = quantity;
for(i = 0; i < pilot->ncommodities; i++)
if(pilot->commodities[i].commodity == cargo) {
if(pilot->cargo_free < quantity)
q = pilot->cargo_free;
pilot->commodities[i].quantity += q;
pilot->cargo_free -= q;
return q;
}
q = quantity;
for(i = 0; i < pilot->ncommodities; i++)
if(pilot->commodities[i].commodity == cargo) {
if(pilot->cargo_free < quantity)
q = pilot->cargo_free;
pilot->commodities[i].quantity += q;
pilot->cargo_free -= q;
return q;
}
// Must add another one.
pilot->commodities = realloc(pilot->commodities,
sizeof(PilotCommodity) * (pilot->ncommodities+1));
pilot->commodities[pilot->ncommodities].commodity = cargo;
if(pilot->cargo_free < quantity)
q = pilot->cargo_free;
pilot->commodities[pilot->ncommodities].quantity = q;
pilot->cargo_free -= q;
pilot->ncommodities++;
// Must add another one.
pilot->commodities = realloc(pilot->commodities,
sizeof(PilotCommodity) * (pilot->ncommodities+1));
pilot->commodities[pilot->ncommodities].commodity = cargo;
if(pilot->cargo_free < quantity)
q = pilot->cargo_free;
pilot->commodities[pilot->ncommodities].quantity = q;
pilot->cargo_free -= q;
pilot->ncommodities++;
return q;
return q;
}
// Try to get rid of quantity cargo from pilot,
// return quantity actually removed.
int pilot_rmCargo(Pilot* pilot, Commodity* cargo, int quantity) {
int i, q;
int i, q;
q = quantity;
for(i = 0; i < pilot->ncommodities; i++)
if(pilot->commodities[i].commodity == cargo) {
if(quantity >= pilot->commodities[i].quantity) {
q = pilot->commodities[i].quantity;
q = quantity;
for(i = 0; i < pilot->ncommodities; i++)
if(pilot->commodities[i].commodity == cargo) {
if(quantity >= pilot->commodities[i].quantity) {
q = pilot->commodities[i].quantity;
// Remove cargo.
memmove(pilot->commodities+i, pilot->commodities+i+1,
sizeof(PilotCommodity)*(pilot->ncommodities-i));
pilot->ncommodities--;
pilot->commodities = realloc(pilot->commodities,
sizeof(PilotCommodity)*pilot->ncommodities);
} else
pilot->commodities[i].quantity -= q;
// Remove cargo.
memmove(pilot->commodities+i, pilot->commodities+i+1,
sizeof(PilotCommodity)*(pilot->ncommodities-i));
pilot->ncommodities--;
pilot->commodities = realloc(pilot->commodities,
sizeof(PilotCommodity)*pilot->ncommodities);
} else
pilot->commodities[i].quantity -= q;
pilot->cargo_free += q;
return q;
}
pilot->cargo_free += q;
return q;
}
return 0;
return 0;
}
// ==Init pilot.===========================================
@ -634,8 +634,8 @@ int pilot_rmCargo(Pilot* pilot, Commodity* cargo, int quantity) {
// flags : Tweaking the pilot.
// ========================================================
void pilot_init(Pilot* pilot, Ship* ship, char* name, Faction* faction,
AI_Profile* ai, const double dir, const Vec2* pos,
const Vec2* vel, const int flags) {
AI_Profile* ai, const double dir, const Vec2* pos,
const Vec2* vel, const int flags) {
if(flags & PILOT_PLAYER) // Player is ID 0
pilot->id = PLAYER_ID;
@ -663,7 +663,7 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, Faction* faction,
pilot->outfits = NULL;
pilot->secondary = NULL;
pilot->ammo = NULL;
pilot->afterburner = NULL;
pilot->afterburner = NULL;
ShipOutfit* so;
if(ship->outfit) {
pilot->noutfits = 0;
@ -673,25 +673,25 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, Faction* faction,
pilot->outfits[pilot->noutfits].quantity = so->quantity;
pilot->outfits[pilot->noutfits].timer = 0;
(pilot->noutfits)++;
if(outfit_isTurret(so->data)) // Used to speed up AI a bit.
pilot_setFlag(pilot, PILOT_HASTURRET);
if(outfit_isTurret(so->data)) // Used to speed up AI a bit.
pilot_setFlag(pilot, PILOT_HASTURRET);
}
}
// Set the pilot stats based on her ship and outfits.
// Hack to have full armour/shield/energy.
pilot->armour = pilot->armour_max = 1.;
pilot->shield = pilot->shield_max = 1.;
pilot->energy = pilot->energy_max = 1.;
pilot_calcStats(pilot);
// Set the pilot stats based on her ship and outfits.
// Hack to have full armour/shield/energy.
pilot->armour = pilot->armour_max = 1.;
pilot->shield = pilot->shield_max = 1.;
pilot->energy = pilot->energy_max = 1.;
pilot_calcStats(pilot);
// Cargo.
pilot->credits = 0;
pilot->commodities = NULL;
pilot->ncommodities = 0;
pilot->cargo_free = pilot->ship->cap_cargo;
// Cargo.
pilot->credits = 0;
pilot->commodities = NULL;
pilot->ncommodities = 0;
pilot->cargo_free = pilot->ship->cap_cargo;
// Set flags and functions.
// Set flags and functions.
if(flags & PILOT_PLAYER) {
pilot->think = player_think; // Players don't need to thing! :P
pilot->render = NULL; // Render will be called from player_think
@ -701,20 +701,20 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, Faction* faction,
} else {
pilot->think = ai_think;
pilot->render = pilot_render;
ai_create(pilot); // Will run the create function in ai.
ai_create(pilot); // Will run the create function in ai.
}
// All update the same way.
// All update the same way.
pilot->update = pilot_update;
}
// Create a new pilot - Params are same as pilot_init. Return pilot's id.
unsigned int pilot_create(Ship* ship, char* name, Faction* faction,
AI_Profile* ai, const double dir, const Vec2* pos,
const Vec2* vel, const int flags) {
AI_Profile* ai, const double dir, const Vec2* pos,
const Vec2* vel, const int flags) {
Pilot** tp, *dyn;
Pilot** tp, *dyn;
dyn = MALLOC_L(Pilot);
dyn = MALLOC_L(Pilot);
if(dyn == NULL) {
WARN("Unable to allocate memory.");
return 0;
@ -733,15 +733,15 @@ unsigned int pilot_create(Ship* ship, char* name, Faction* faction,
// Add to the stack.
pilots++; // There is a new pilot.
if(pilots >= mpilots) {
// Need to grow. About 20 at a time.
mpilots += 20;
tp = pilot_stack;
pilot_stack = realloc(pilot_stack, mpilots*sizeof(Pilot*));
if((pilot_stack != tp) && player)
// Take into account possible mem move.
player = pilot_stack[0];
}
if(pilots >= mpilots) {
// Need to grow. About 20 at a time.
mpilots += 20;
tp = pilot_stack;
pilot_stack = realloc(pilot_stack, mpilots*sizeof(Pilot*));
if((pilot_stack != tp) && player)
// Take into account possible mem move.
player = pilot_stack[0];
}
pilot_stack[pilots-1] = dyn;
}
@ -750,11 +750,11 @@ unsigned int pilot_create(Ship* ship, char* name, Faction* faction,
// Frees and cleans up a pilot.
static void pilot_free(Pilot* p) {
if(player == p) player = NULL;
if(player == p) player = NULL;
solid_free(p->solid);
if(p->outfits) free(p->outfits);
free(p->name);
if(p->commodities) free(p->commodities);
if(p->commodities) free(p->commodities);
ai_destroy(p);
free(p);
}
@ -766,7 +766,7 @@ void pilot_destroy(Pilot* p) {
if(pilot_stack[i] == p)
break;
pilots--;
pilots--;
while(i < pilots) {
pilot_stack[i] = pilot_stack[i+1];
@ -869,7 +869,7 @@ static Fleet* fleet_parse(const xmlNodePtr parent) {
pilot->chance = atoi(c);
if(pilot->chance == 0)
WARN("Pilot %s in Fleet %s has 0%% chance of appearing",
pilot->name, tmp->name);
pilot->name, tmp->name);
if(c) free(c); // Free the external malloc.
tmp->pilots = realloc(tmp->pilots, sizeof(FleetPilot)*tmp->npilots);

View File

@ -10,11 +10,11 @@
#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_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.
// Aproximation for pilot size.
#define PILOT_SIZE_APROX 0.8
@ -26,18 +26,18 @@
#define pilot_rmFlag(p,f) (p->flags ^= (f))
// Creation.
#define PILOT_PLAYER (1<<0) // Pilot is a player.
#define PILOT_HASTURRET (1<<20) // Pilit has turrets.
#define PILOT_HASTURRET (1<<20) // Pilit has turrets.
// 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_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_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_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.
@ -45,14 +45,14 @@
#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.
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;
typedef struct PilotCommodity_ {
Commodity* commodity;
int quantity;
Commodity* commodity;
int quantity;
} PilotCommodity;
// Primary pilot structure.
@ -65,14 +65,14 @@ typedef struct Pilot_ {
// Object characteristics.
Ship* ship; // Pilots ship.
Solid* solid; // Associated solid (physics).
int tsx, tsy; // Current sprite, calculated on update.
int tsx, tsy; // Current sprite, calculated on update.
double thrust, turn, speed;
double thrust, turn, speed;
// Current health.
double armour, shield, energy;
double armour_max, shield_max, energy_max;
double armour_regen, shield_regen, energy_regen;
double armour_regen, shield_regen, energy_regen;
double fuel; // Used only for jumps. TODO: make it do something.
void (*think)(struct Pilot_*); // AI thinking for the pilot.
@ -82,18 +82,18 @@ typedef struct Pilot_ {
// 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.
int ncommodities;
int cargo_free;
// 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.
// Misc.
uint32_t flags; // Used for AI etc.
unsigned int ptimer; // Generic timer for internal pilot use.
// AI.
@ -131,7 +131,7 @@ Fleet* fleet_get(const char* name);
// 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 double damage_shield, const double damage_armour);
const double damage_shield, const double damage_armour);
void pilot_setSecondary(Pilot* p, const char* secondary);
void pilot_setAmmo(Pilot* p);
double pilot_face(Pilot* p, const float dir);
@ -142,12 +142,12 @@ int pilot_rmCargo(Pilot* pilot, Commodity* cargo, int quantity);
// Creation.
void pilot_init(Pilot* dest, Ship* ship, char* name, Faction* faction,
AI_Profile* ai, const double dir, const Vec2* pos,
const Vec2* vel, const int flags);
AI_Profile* ai, const double dir, const Vec2* pos,
const Vec2* vel, const int flags);
unsigned int pilot_create(Ship* ship, char* name, Faction* faction,
AI_Profile* ai, const double dir, const Vec2* pos,
const Vec2* vel, const int flags);
AI_Profile* ai, const double dir, const Vec2* pos,
const Vec2* vel, const int flags);
// Init/Cleanup.
void pilot_destroy(Pilot* p);

View File

@ -30,16 +30,16 @@
// Player stuff.
Pilot* player = NULL; // extern in pilot.h
// Player global properties.
char* player_name = NULL; // Player name.
int player_credits = 0; // Ze monies.
int combat_crating = 0; // Ze rating.
unsigned int player_flags = 0; // Player flags.
char* player_name = NULL; // Player name.
int player_credits = 0; // Ze monies.
int combat_crating = 0; // Ze rating.
unsigned int player_flags = 0; // Player flags.
// Input.c
double player_turn = 0.; // Turn velocity from input.
double player_acc = 0.; // Accel velocity from input.
double player_turn = 0.; // Turn velocity from input.
double player_acc = 0.; // Accel velocity from input.
unsigned int player_target = PLAYER_ID; // Targetted pilot.
// Internal
int planet_target = -1; // Targetted planet.
int planet_target = -1; // Targetted planet.
int hyperspace_target = -1; // Target hyperspace route.
// For death etc.
static unsigned int player_timer = 0;
@ -90,9 +90,9 @@ typedef struct GUI_ {
} GUI;
GUI gui = {
.gfx_frame = NULL,
.gfx_targetPilot = NULL,
.gfx_targetPlanet = NULL
.gfx_frame = NULL,
.gfx_targetPilot = NULL,
.gfx_targetPlanet = NULL
};
double gui_xoff = 0.;
@ -111,12 +111,12 @@ static Msg* msg_stack;
// External.
extern void pilot_render(const Pilot* pilot); // Extern is in Pilot.*
extern void weapon_minimap(const double res,
const double w, const double h, const RadarShape shape); // weapon.c
const double w, const double h, const RadarShape shape); // weapon.c
extern void planets_minimap(const double res,
const double w, const double h, const RadarShape shape); // space.c
const double w, const double h, const RadarShape shape); // space.c
// Internal.
static void rect_parse(const xmlNodePtr parent,
double* x, double* y, double* w, double* h);
double* x, double* y, double* w, double* h);
static int gui_parse(const xmlNodePtr parent, const char* name);
static void gui_renderPilot(const Pilot* p);
static void gui_renderBar(const glColour* c, const Rect* r, const double w);
@ -171,8 +171,8 @@ void player_new(void) {
else if(xml_isNode(tmp, "y")) y = xml_getFloat(tmp);
} while((tmp = tmp->next));
}
else if(xml_isNode(cur, "combat_crating"))
combat_crating = xml_getInt(cur);
else if(xml_isNode(cur, "combat_crating"))
combat_crating = xml_getInt(cur);
} while((cur = cur->next));
}
}while((node = node->next));
@ -181,8 +181,8 @@ void player_new(void) {
free(buf);
xmlCleanupParser();
// In case we are respawning.
player_rmFlag(PLAYER_DESTROYED);
// In case we are respawning.
player_rmFlag(PLAYER_DESTROYED);
// Money.
player_credits = RNG(l, h);
@ -191,24 +191,24 @@ void player_new(void) {
player_message("Welcome to "APPNAME"!");
player_message("v%d.%d.%d", VMAJOR, VMINOR, VREV);
// Create the player and start the game.
player_newShip(ship);
// Create the player and start the game.
player_newShip(ship);
space_init(system);
// Position and direction.
player_warp(x, y);
player->solid->dir = RNG(0, 359) / 180.*M_PI;
// Position and direction.
player_warp(x, y);
player->solid->dir = RNG(0, 359) / 180.*M_PI;
}
// Change the players ship.
void player_newShip(Ship* ship) {
if(player)
pilot_destroy(player);
if(player)
pilot_destroy(player);
pilot_create(ship, "Player", faction_get("Player"), NULL,
0., NULL, NULL, PILOT_PLAYER);
pilot_create(ship, "Player", faction_get("Player"), NULL,
0., NULL, NULL, PILOT_PLAYER);
gl_bindCamera(&player->solid->pos); // Set opengl camera.
gl_bindCamera(&player->solid->pos); // Set opengl camera.
}
void player_message(const char* fmt, ...) {
@ -243,56 +243,56 @@ void player_clear(void) {
}
static char* player_ratings[] = {
"None",
"Smallfry",
"Minor",
"Average",
"Major",
"Fearsome",
"Godlike"
"None",
"Smallfry",
"Minor",
"Average",
"Major",
"Fearsome",
"Godlike"
};
const char* player_rating(void) {
if(combat_crating == 0) return player_ratings[0];
else if(combat_crating < 50) return player_ratings[1];
else if(combat_crating < 200) return player_ratings[2];
else if(combat_crating < 500) return player_ratings[3];
else if(combat_crating < 1000) return player_ratings[4];
else if(combat_crating < 2500) return player_ratings[5];
else if(combat_crating < 10000) return player_ratings[6];
else return player_ratings[7];
if(combat_crating == 0) return player_ratings[0];
else if(combat_crating < 50) return player_ratings[1];
else if(combat_crating < 200) return player_ratings[2];
else if(combat_crating < 500) return player_ratings[3];
else if(combat_crating < 1000) return player_ratings[4];
else if(combat_crating < 2500) return player_ratings[5];
else if(combat_crating < 10000) return player_ratings[6];
else return player_ratings[7];
}
// Return how much weapon. space the player has remaining.
int player_freeSpace(void) {
int i, s;
s = player->ship->cap_weapon;
for(i = 0; i < player->noutfits; i++)
s -= player->outfits[i].quantity * player->outfits[i].outfit->mass;
int i, s;
s = player->ship->cap_weapon;
for(i = 0; i < player->noutfits; i++)
s -= player->outfits[i].quantity * player->outfits[i].outfit->mass;
return s;
return s;
}
// Return amount of outfits the player owns.
int player_outfitOwned(const char* outfitname) {
int i;
int i;
for(i = 0; i < player->noutfits; i++)
if(strcmp(outfitname, player->outfits[i].outfit->name)==0)
return player->outfits[i].quantity;
for(i = 0; i < player->noutfits; i++)
if(strcmp(outfitname, player->outfits[i].outfit->name)==0)
return player->outfits[i].quantity;
return 0;
return 0;
}
// Return how many of the commodity the player has.
int player_cargoOwned(const char* commodityname) {
int i;
int i;
for(i = 0; i < player->ncommodities; i++)
if(strcmp(commodityname, player->commodities[i].commodity->name)==0)
return player->commodities[i].quantity;
for(i = 0; i < player->ncommodities; i++)
if(strcmp(commodityname, player->commodities[i].commodity->name)==0)
return player->commodities[i].quantity;
return 0;
return 0;
}
// Render the background player stuff, namely planet target
@ -301,8 +301,8 @@ void player_renderBG(void) {
glColour* c;
Planet* planet;
if(player_isFlag(PLAYER_DESTROYED) ||
pilot_isFlag(player, PILOT_DEAD)) return;
if(player_isFlag(PLAYER_DESTROYED) ||
pilot_isFlag(player, PILOT_DEAD)) return;
if(planet_target >= 0) {
planet = &cur_system->planets[planet_target];
@ -334,41 +334,41 @@ void player_render(void) {
glColour* c;
glFont* f;
if(player_isFlag(PLAYER_DESTROYED) || pilot_isFlag(player, PILOT_DEAD)) {
if(player_isFlag(PLAYER_DESTROYED)) {
if(!toolkit && (SDL_GetTicks() > player_timer))
menu_death();
} else
pilot_render(player);
if(player_isFlag(PLAYER_DESTROYED) || pilot_isFlag(player, PILOT_DEAD)) {
if(player_isFlag(PLAYER_DESTROYED)) {
if(!toolkit && (SDL_GetTicks() > player_timer))
menu_death();
} else
pilot_render(player);
// Fancy cinematic scene borders.
glMatrixMode(GL_MODELVIEW);
glPushMatrix(); // Translation matrix.
glTranslated(x-(double)gl_screen.w/2., y-(double)gl_screen.h/2., 0);
// Fancy cinematic scene borders.
glMatrixMode(GL_MODELVIEW);
glPushMatrix(); // Translation matrix.
glTranslated(x-(double)gl_screen.w/2., y-(double)gl_screen.h/2., 0);
COLOUR(cBlack);
glBegin(GL_QUADS);
glVertex2d(0., 0.);
glVertex2d(0., gl_screen.h*0.2);
glVertex2d(gl_screen.w, gl_screen.h*0.2);
glVertex2d(gl_screen.w, 0.);
glVertex2d(0., gl_screen.h);
glVertex2d(gl_screen.w, gl_screen.h);
glVertex2d(0., gl_screen.h*0.8);
glEnd();
COLOUR(cBlack);
glBegin(GL_QUADS);
glVertex2d(0., 0.);
glVertex2d(0., gl_screen.h*0.2);
glVertex2d(gl_screen.w, gl_screen.h*0.2);
glVertex2d(gl_screen.w, 0.);
glVertex2d(0., gl_screen.h);
glVertex2d(gl_screen.w, gl_screen.h);
glVertex2d(0., gl_screen.h*0.8);
glEnd();
glPopMatrix(); // Translation matrix.
glPopMatrix(); // Translation matrix.
return;
}
return;
}
// Render the player target graphics.
if(player_target != PLAYER_ID) p = pilot_get(player_target);
else p = NULL;
if((p == NULL) || pilot_isFlag(p, PILOT_DEAD))
player_target = PLAYER_ID; // No more pilot target.
else {
// There is still a pilot target.
else p = NULL;
if((p == NULL) || pilot_isFlag(p, PILOT_DEAD))
player_target = PLAYER_ID; // No more pilot target.
else {
// There is still a pilot target.
if(pilot_isDisabled(p)) c = &cInert;
else if(pilot_isFlag(p, PILOT_HOSTILE)) c = &cHostile;
else c = &cNeutral;
@ -442,11 +442,11 @@ void player_render(void) {
if(planet_target >= 0) {
// Planet landing target.
gl_printMid(NULL, (int)gui.nav.w,
gui.nav.x, gui.nav.y - 5, &cConsole, "Land");
gui.nav.x, gui.nav.y - 5, &cConsole, "Land");
gl_printMid(&gl_smallFont, (int)gui.nav.w, gui.nav.x,
gui.nav.y - 10 - gl_smallFont.h, NULL, "%s",
cur_system->planets[planet_target].name);
gui.nav.y - 10 - gl_smallFont.h, NULL, "%s",
cur_system->planets[planet_target].name);
}
else if(hyperspace_target >= 0) {
// Hyperspace target.
@ -455,8 +455,8 @@ void player_render(void) {
c, "Hyperspace");
gl_printMid(&gl_smallFont, (int)gui.nav.w, gui.nav.x,
gui.nav.y - 10 - gl_smallFont.h, NULL, "%s",
systems_stack[cur_system->jumps[hyperspace_target]].name);
gui.nav.y - 10 - gl_smallFont.h, NULL, "%s",
systems_stack[cur_system->jumps[hyperspace_target]].name);
}
else {
// No NAV target.
@ -479,7 +479,7 @@ void player_render(void) {
gui.weapon.y - 10 - gl_defFont.h, &cGrey, "None");
} else {
f = &gl_defFont;
if(outfit_isLauncher(player->secondary->outfit)) {
if(outfit_isLauncher(player->secondary->outfit)) {
// Use the ammunitions name.
i = gl_printWidth(f, "%s", player->secondary->outfit->u.lau.ammo);
if(i > gui.weapon.w)
@ -495,15 +495,15 @@ void player_render(void) {
gui.weapon.y - 10 - gl_defFont.h,
NULL, "%d", (player->ammo) ? player->ammo->quantity : 0);
} else {
// Just print the item name.
i = gl_printWidth(f, "%s", player->secondary->outfit->name);
if(i > (int)gui.weapon.w)
// Font is too big.
f = &gl_smallFont;
gl_printMid(f, (int)gui.weapon.w,
gui.weapon.x, gui.weapon.y - (gui.weapon.h - f->h)/2.,
&cConsole, "%s", player->secondary->outfit->name);
}
// Just print the item name.
i = gl_printWidth(f, "%s", player->secondary->outfit->name);
if(i > (int)gui.weapon.w)
// Font is too big.
f = &gl_smallFont;
gl_printMid(f, (int)gui.weapon.w,
gui.weapon.x, gui.weapon.y - (gui.weapon.h - f->h)/2.,
&cConsole, "%s", player->secondary->outfit->name);
}
}
// Target.
@ -539,39 +539,39 @@ void player_render(void) {
}
// Misc.
j = gui.misc.y - 8 - gl_smallFont.h;
j = gui.misc.y - 8 - gl_smallFont.h;
gl_print(NULL, gui.misc.x + 8, j,
&cConsole, "SCreds:");
credits2str(str, player_credits, 2);
credits2str(str, player_credits, 2);
i = gl_printWidth(&gl_smallFont, str);
gl_print(&gl_smallFont, gui.misc.x + gui.misc.w - 8 - i, j,
NULL, str);
NULL, str);
// Cargo and co.
if(player->ncommodities > 0) {
j -= gl_smallFont.h + 5;
gl_print(&gl_smallFont,
gui.misc.x + 8, j, &cConsole, "Cargo");
// Cargo and co.
if(player->ncommodities > 0) {
j -= gl_smallFont.h + 5;
gl_print(&gl_smallFont,
gui.misc.x + 8, j, &cConsole, "Cargo");
for(i = 0; i < MIN(player->ncommodities,3); i++) {
j -= gl_smallFont.h + 3;
gl_print(&gl_smallFont,
gui.misc.x + 13, j,
NULL, "%d %s", player->commodities[i].quantity,
player->commodities[i].commodity->name);
}
}
for(i = 0; i < MIN(player->ncommodities,3); i++) {
j -= gl_smallFont.h + 3;
gl_print(&gl_smallFont,
gui.misc.x + 13, j,
NULL, "%d %s", player->commodities[i].quantity,
player->commodities[i].commodity->name);
}
}
j -= gl_smallFont.h + 5;
gl_print(&gl_smallFont,
gui.misc.x + 8, j, &cConsole, "Free:");
j -= gl_smallFont.h + 5;
gl_print(&gl_smallFont,
gui.misc.x + 8, j, &cConsole, "Free:");
i = gl_printWidth(&gl_smallFont, "%d", player->ship->cap_cargo);
gl_print(&gl_smallFont,
gui.misc.x + gui.misc.w - 8 - i, j,
NULL, "%d", player->cargo_free);
i = gl_printWidth(&gl_smallFont, "%d", player->ship->cap_cargo);
gl_print(&gl_smallFont,
gui.misc.x + gui.misc.w - 8 - i, j,
NULL, "%d", player->cargo_free);
// Messages.
x = gui.msg.x;
@ -586,18 +586,18 @@ void player_render(void) {
}
// Hyperspace FLASH BANG!!!
if(pilot_isFlag(player, PILOT_HYPERSPACE) && !paused) {
i = (int)player->ptimer - HYPERSPACE_FADEOUT;
j = (int)SDL_GetTicks();
if(i < j) {
x = (double)(j-i) / HYPERSPACE_FADEOUT;
glColor4d(1.,1.,1., x); // We'll | I'll, make this more effiecent later.
glBegin(GL_QUADS);
glVertex2d(-gl_screen.w/2., -gl_screen.h/2.);
glVertex2d(-gl_screen.w/2., gl_screen.h/2.);
glVertex2d( gl_screen.w/2., gl_screen.h/2.);
glVertex2d( gl_screen.w/2., -gl_screen.h/2.);
glEnd();
}
i = (int)player->ptimer - HYPERSPACE_FADEOUT;
j = (int)SDL_GetTicks();
if(i < j) {
x = (double)(j-i) / HYPERSPACE_FADEOUT;
glColor4d(1.,1.,1., x); // We'll | I'll, make this more effiecent later.
glBegin(GL_QUADS);
glVertex2d(-gl_screen.w/2., -gl_screen.h/2.);
glVertex2d(-gl_screen.w/2., gl_screen.h/2.);
glVertex2d( gl_screen.w/2., gl_screen.h/2.);
glVertex2d( gl_screen.w/2., -gl_screen.h/2.);
glEnd();
}
}
}
@ -727,7 +727,7 @@ int gui_load(const char* name) {
}
static void rect_parse(const xmlNodePtr parent, double* x, double* y,
double* w, double* h) {
double* w, double* h) {
xmlNodePtr cur;
int param;
@ -850,19 +850,19 @@ static int gui_parse(const xmlNodePtr parent, const char* name) {
do {
if(xml_isNode(cur, "shield")) {
rect_parse(cur, &gui.shield.x, &gui.shield.y,
&gui.shield.w, &gui.shield.h);
&gui.shield.w, &gui.shield.h);
RELATIVIZE(gui.shield);
}
if(xml_isNode(cur, "armour")) {
rect_parse(cur, &gui.armour.x, &gui.armour.y,
&gui.armour.w, &gui.armour.h);
&gui.armour.w, &gui.armour.h);
RELATIVIZE(gui.armour);
}
if(xml_isNode(cur, "energy")) {
rect_parse(cur, &gui.energy.x, &gui.energy.y,
&gui.energy.w, &gui.energy.h);
&gui.energy.w, &gui.energy.h);
RELATIVIZE(gui.energy);
}
} while((cur = cur->next));
@ -870,7 +870,7 @@ static int gui_parse(const xmlNodePtr parent, const char* name) {
// Secondary weapon.
else if(xml_isNode(node, "weapon")) {
rect_parse(node, &gui.weapon.x, &gui.weapon.y,
&gui.weapon.w, &gui.weapon.h);
&gui.weapon.w, &gui.weapon.h);
RELATIVIZE(gui.weapon);
gui.weapon.y -= gl_defFont.h;
}
@ -892,14 +892,14 @@ static int gui_parse(const xmlNodePtr parent, const char* name) {
if(xml_isNode(cur, "faction")) {
rect_parse(cur, &gui.target_faction.x, &gui.target_faction.y,
NULL, NULL);
NULL, NULL);
RELATIVIZE(gui.target_faction);
gui.target_faction.y -= gl_smallFont.h;
}
if(xml_isNode(cur, "health")) {
rect_parse(cur, &gui.target_health.x, &gui.target_health.y,
NULL, NULL);
NULL, NULL);
RELATIVIZE(gui.target_health);
gui.target_health.y -= gl_smallFont.h;
}
@ -916,9 +916,9 @@ static int gui_parse(const xmlNodePtr parent, const char* name) {
// Free the GUI.
void gui_free(void) {
if(gui.gfx_frame) gl_freeTexture(gui.gfx_frame);
if(gui.gfx_targetPilot) gl_freeTexture(gui.gfx_targetPilot);
if(gui.gfx_targetPlanet) gl_freeTexture(gui.gfx_targetPlanet);
if(gui.gfx_frame) gl_freeTexture(gui.gfx_frame);
if(gui.gfx_targetPilot) gl_freeTexture(gui.gfx_targetPilot);
if(gui.gfx_targetPlanet) gl_freeTexture(gui.gfx_targetPlanet);
free(msg_stack);
}
@ -926,20 +926,20 @@ void gui_free(void) {
// Used in pilot.c
// Basically uses keyboard input instead of AI input.
void player_think(Pilot* player) {
// Last I checked, the dead didn't think..
if(pilot_isFlag(player, PILOT_DEAD)) return;
// Last I checked, the dead didn't think..
if(pilot_isFlag(player, PILOT_DEAD)) return;
// PLAYER_FACE will take over navigation.
if(player_isFlag(PLAYER_FACE)) {
if(player_target != PLAYER_ID)
pilot_face(player,
vect_angle(&player->solid->pos,
&pilot_get(player_target)->solid->pos));
else if(planet_target != -1)
pilot_face(player,
vect_angle(&player->solid->pos,
&cur_system->planets[planet_target].pos));
}
if(player_isFlag(PLAYER_FACE)) {
if(player_target != PLAYER_ID)
pilot_face(player,
vect_angle(&player->solid->pos,
&pilot_get(player_target)->solid->pos));
else if(planet_target != -1)
pilot_face(player,
vect_angle(&player->solid->pos,
&cur_system->planets[planet_target].pos));
}
// PLAYER_REVERSE will take over navigation.
else if(player_isFlag(PLAYER_REVERSE) && (VMOD(player->solid->vel) > 0.))
@ -956,18 +956,18 @@ void player_think(Pilot* player) {
if(player_isFlag(PLAYER_SECONDARY)) // Needs a target.
pilot_shoot(player, player_target, 1);
if(player_isFlag(PLAYER_AFTERBURNER))
vect_pset(&player->solid->force,
player->thrust * player->afterburner->outfit->u.afb.thrust_perc +
player->afterburner->outfit->u.afb.thrust_abs, player->solid->dir);
else
vect_pset(&player->solid->force, player->thrust * player_acc,
player->solid->dir);
if(player_isFlag(PLAYER_AFTERBURNER))
vect_pset(&player->solid->force,
player->thrust * player->afterburner->outfit->u.afb.thrust_perc +
player->afterburner->outfit->u.afb.thrust_abs, player->solid->dir);
else
vect_pset(&player->solid->force, player->thrust * player_acc,
player->solid->dir);
// Set the listener stuff.
sound_listener(player->solid->dir,
player->solid->pos.x, player->solid->pos.y,
player->solid->vel.x, player->solid->vel.y);
// Set the listener stuff.
sound_listener(player->solid->dir,
player->solid->pos.x, player->solid->pos.y,
player->solid->vel.x, player->solid->vel.y);
}
// Modify the radar resolution.
@ -976,7 +976,7 @@ void player_setRadarRel(int mod) {
if(gui.radar.res > RADAR_RES_MAX) gui.radar.res = RADAR_RES_MAX;
else if(gui.radar.res < RADAR_RES_MIN) gui.radar.res = RADAR_RES_MIN;
player_message("Radar set to %dx", (int)gui.radar.res);
player_message("Radar set to %dx", (int)gui.radar.res);
}
// Get the next secondary weapon.
@ -1007,7 +1007,7 @@ void player_secondaryNext(void) {
// Cycle through planet targets.
void player_targetPlanet(void) {
hyperspace_target = -1;
player_rmFlag(PLAYER_LANDACK);
player_rmFlag(PLAYER_LANDACK);
if((planet_target == -1) && (cur_system->nplanets > 0)) {
// No target.
@ -1031,26 +1031,26 @@ void player_land(void) {
}
Planet* planet = &cur_system->planets[planet_target];
if(planet_target >= 0) {
if(!planet_hasService(planet, PLANET_SERVICE_LAND)) {
player_message("You can't land here.");
return;
}
else if(!player_isFlag(PLAYER_LANDACK)) {
// No landing authorization.
if(!areEnemies(player->faction, planet->faction)) {
player_message("%s> Permission to land cleared.", planet->name);
player_setFlag(PLAYER_LANDACK);
} else {
player_message("%s> Land request denied.", planet->name);
}
return;
}
if(!planet_hasService(planet, PLANET_SERVICE_LAND)) {
player_message("You can't land here.");
return;
}
else if(!player_isFlag(PLAYER_LANDACK)) {
// No landing authorization.
if(!areEnemies(player->faction, planet->faction)) {
player_message("%s> Permission to land cleared.", planet->name);
player_setFlag(PLAYER_LANDACK);
} else {
player_message("%s> Land request denied.", planet->name);
}
return;
}
else if(vect_dist(&player->solid->pos, &planet->pos) > planet->gfx_space->sw) {
player_message("You are too far away to land on %s", planet->name);
return;
}
else if((pow2(VX(player->solid->vel)) + pow2(VY(player->solid->vel))) >
(double)pow2(MAX_HYPERSPACE_VEL)) {
(double)pow2(MAX_HYPERSPACE_VEL)) {
player_message("You are going too fast to land on %s", planet->name);
return;
}
@ -1066,20 +1066,20 @@ void player_land(void) {
for(i = 0; i < cur_system->nplanets; i++) {
d = vect_dist(&player->solid->pos, &cur_system->planets[i].pos);
if(planet_hasService(&cur_system->planets[i], PLANET_SERVICE_LAND) &&
((tp == -1) || ((td == -1) || (td > d)))) {
((tp == -1) || ((td == -1) || (td > d)))) {
tp = i;
td = d;
}
}
planet_target = tp;
player_rmFlag(PLAYER_LANDACK);
player_land(); // Re-run land protocol.
player_rmFlag(PLAYER_LANDACK);
player_land(); // Re-run land protocol.
}
}
void player_targetHyperspace(void) {
planet_target = -1; // Remove planet target.
player_rmFlag(PLAYER_LANDACK); // Get rid of landing permission.
player_rmFlag(PLAYER_LANDACK); // Get rid of landing permission.
hyperspace_target++;
if(hyperspace_target >= cur_system->njumps)
@ -1089,10 +1089,10 @@ void player_targetHyperspace(void) {
// Actually attempt to jump into hyperspace.
void player_jump(void) {
if((hyperspace_target == -1) ||
pilot_isFlag(player, PILOT_HYP_PREP) ||
pilot_isFlag(player, PILOT_HYP_BEGIN) ||
pilot_isFlag(player, PILOT_HYPERSPACE))
return;
pilot_isFlag(player, PILOT_HYP_PREP) ||
pilot_isFlag(player, PILOT_HYP_BEGIN) ||
pilot_isFlag(player, PILOT_HYPERSPACE))
return;
int i = space_hyperspace(player);
@ -1121,29 +1121,29 @@ void player_brokeHyperspace(void) {
// Make the player face her hyperspace target.
double player_faceHyperspace(void) {
double a;
a = ANGLE(systems_stack[cur_system->jumps[hyperspace_target]].pos.x -
cur_system->pos.x,
systems_stack[cur_system->jumps[hyperspace_target]].pos.y -
cur_system->pos.y);
double a;
a = ANGLE(systems_stack[cur_system->jumps[hyperspace_target]].pos.x -
cur_system->pos.x,
systems_stack[cur_system->jumps[hyperspace_target]].pos.y -
cur_system->pos.y);
return pilot_face(player, a);
return pilot_face(player, a);
}
// Activate afterburner.
void player_afterburn(void) {
// TODO: Fancy effects.
if(player->afterburner != NULL) {
player_setFlag(PLAYER_AFTERBURNER);
pilot_setFlag(player, PILOT_AFTERBURNER);
}
// TODO: Fancy effects.
if(player->afterburner != NULL) {
player_setFlag(PLAYER_AFTERBURNER);
pilot_setFlag(player, PILOT_AFTERBURNER);
}
}
void player_afterburnOver(void) {
if(player->afterburner != NULL) {
player_rmFlag(PLAYER_AFTERBURNER);
pilot_rmFlag(player, PILOT_AFTERBURNER);
}
if(player->afterburner != NULL) {
player_rmFlag(PLAYER_AFTERBURNER);
pilot_rmFlag(player, PILOT_AFTERBURNER);
}
}
// Take a screenshot.
@ -1162,7 +1162,7 @@ void player_screenshot(void) {
return;
}
snprintf(filename, PATH_MAX, "../screenshots/screenshot%03d.png",
screenshot_cur);
screenshot_cur);
fp = fopen(filename, "r"); // Myeah, I know it's a horrible way to check.
if(fp == NULL) done = 1;
else {
@ -1180,15 +1180,15 @@ void player_screenshot(void) {
// Player go pwned.
void player_dead(void) {
gui_xoff = 0.;
gui_yoff = 0.;
gui_xoff = 0.;
gui_yoff = 0.;
}
// Player blew up in a nice fireball.
void player_destroyed(void) {
vectcpy(&player_cam, &player->solid->pos);
gl_bindCamera(&player_cam);
player_setFlag(PLAYER_DESTROYED);
player_timer = SDL_GetTicks() + 5000;
vectcpy(&player_cam, &player->solid->pos);
gl_bindCamera(&player_cam);
player_setFlag(PLAYER_DESTROYED);
player_timer = SDL_GetTicks() + 5000;
}

View File

@ -2,20 +2,20 @@
#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_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.
// 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)
#define player_rmFlag(f) if(player_isFlag(f)) (player_flags ^= f)
// The player.
extern Pilot* pilot;

View File

@ -1,8 +1,8 @@
#pragma once
#include <stdlib.h>
#define RNG(L,H) ((int)L + (int)((double)(H-L+1) * (rand()/(RAND_MAX+1.))))
#define RNGF() (rand()/(RAND_MAX+1.))
#define RNG(L,H) ((int)L + (int)((double)(H-L+1) * (rand()/(RAND_MAX+1.))))
#define RNGF() (rand()/(RAND_MAX+1.))
void rng_init(void);

View File

@ -15,11 +15,11 @@
#define SHIP_EXT ".png"
#define SHIP_TARGET "_target"
#define VIEW_WIDTH 300
#define VIEW_HEIGHT 300
#define VIEW_WIDTH 300
#define VIEW_HEIGHT 300
#define BUTTON_WIDTH 80
#define BUTTON_HEIGHT 30
#define BUTTON_WIDTH 80
#define BUTTON_HEIGHT 30
static Ship* ship_stack = NULL;
static int ships = 0;
@ -42,37 +42,37 @@ Ship* ship_get(const char* name) {
// Get the ship's classname.
static char* ship_classes[] = {
"NULL",
"Civialian Light", "Civilian Medium", "Civilian Heavy"
"Military Light", "Military Medium", "Military Heavy"
"Robotic Light", "Robotic Medium", "Robotic Heavy"
"Hybrid Light", "Hybrid Medium", "Hybrid Heavy"
"NULL",
"Civialian Light", "Civilian Medium", "Civilian Heavy"
"Military Light", "Military Medium", "Military Heavy"
"Robotic Light", "Robotic Medium", "Robotic Heavy"
"Hybrid Light", "Hybrid Medium", "Hybrid Heavy"
};
// Return all the ships in text form.
char** ship_getTech(int* n, const int* tech, const int techmax) {
int i, j;
char** shipnames = malloc(sizeof(Ship*) * ships);
int i, j;
char** shipnames = malloc(sizeof(Ship*) * ships);
*n = 0;
for(i = 0; i < ships; i++)
if(ship_stack[i].tech <= tech[0]) {
shipnames[*n] = strdup(ship_stack[i].name);
(*n)++;
} else {
for(j = 0; j < techmax; j++)
if(tech[j] == ship_stack[i].tech) {
shipnames[*n] = strdup(ship_stack[i].name);
(*n)++;
}
}
*n = 0;
for(i = 0; i < ships; i++)
if(ship_stack[i].tech <= tech[0]) {
shipnames[*n] = strdup(ship_stack[i].name);
(*n)++;
} else {
for(j = 0; j < techmax; j++)
if(tech[j] == ship_stack[i].tech) {
shipnames[*n] = strdup(ship_stack[i].name);
(*n)++;
}
}
return shipnames;
return shipnames;
}
char* ship_class(Ship* s) {
return ship_classes[s->class];
return ship_classes[s->class];
}
static Ship* ship_parse(xmlNodePtr parent) {
@ -81,7 +81,7 @@ static Ship* ship_parse(xmlNodePtr parent) {
ShipOutfit* otmp, *ocur;
char str[PATH_MAX] = "\0";
char* stmp;
char* stmp;
tmp->name = xml_nodeProp(parent, "name");
if(tmp->name == NULL) WARN("Ship in "SHIP_DATA" has invalid or no name");
@ -91,31 +91,31 @@ static Ship* ship_parse(xmlNodePtr parent) {
do {
// 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));
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.
snprintf(str, strlen(xml_get(node)) +
sizeof(SHIP_GFX)+sizeof(SHIP_TARGET)+sizeof(SHIP_EXT),
sizeof(SHIP_GFX)+sizeof(SHIP_TARGET)+sizeof(SHIP_EXT),
SHIP_GFX"%s"SHIP_TARGET SHIP_EXT, xml_get(node));
tmp->gfx_target = gl_newImage(str);
}
else if(xml_isNode(node, "GUI"))
tmp->gui = strdup(xml_get(node));
else if(xml_isNode(node, "sound"))
tmp->sound = sound_get(xml_get(node));
else if(xml_isNode(node, "sound"))
tmp->sound = sound_get(xml_get(node));
else if(xml_isNode(node, "class"))
tmp->class = xml_getInt(node);
else if(xml_isNode(node, "price"))
tmp->price = xml_getInt(node);
else if(xml_isNode(node, "tech"))
tmp->tech = xml_getInt(node);
else if(xml_isNode(node, "fabricator"))
tmp->fabricator = strdup(xml_get(node));
else if(xml_isNode(node, "description"))
tmp->description = strdup(xml_get(node));
else if(xml_isNode(node, "price"))
tmp->price = xml_getInt(node);
else if(xml_isNode(node, "tech"))
tmp->tech = xml_getInt(node);
else if(xml_isNode(node, "fabricator"))
tmp->fabricator = strdup(xml_get(node));
else if(xml_isNode(node, "description"))
tmp->description = strdup(xml_get(node));
else if(xml_isNode(node, "movement")) {
cur = node->children;
do {
@ -166,7 +166,7 @@ static Ship* ship_parse(xmlNodePtr parent) {
stmp = xml_nodeProp(cur, "quantity");
if(!stmp)
WARN("Ship '%s' is missing tag 'quantity for outfit '%s'",
tmp->name, otmp->data->name);
tmp->name, otmp->data->name);
otmp->quantity = atoi(stmp);
free(stmp);
otmp->next = NULL;
@ -185,26 +185,26 @@ static Ship* ship_parse(xmlNodePtr parent) {
#define MELEMENT(o,s) if(o) WARN("Ship '%s' missing '"s"' element", tmp->name)
MELEMENT(tmp->name == NULL, "name");
MELEMENT(tmp->gfx_space == NULL, "GFX");
MELEMENT(tmp->gui == NULL, "GUI");
MELEMENT(tmp->class==0, "class");
MELEMENT(tmp->price==0, "price");
MELEMENT(tmp->tech==0, "tech");
MELEMENT(tmp->fabricator==0, "fabricator");
MELEMENT(tmp->description==0, "description");
MELEMENT(tmp->thrust==0, "thrust");
MELEMENT(tmp->turn==0, "turn");
MELEMENT(tmp->speed==0, "speed");
MELEMENT(tmp->armour==0, "armour");
MELEMENT(tmp->armour_regen==0, "armour_regen");
MELEMENT(tmp->shield==0, "shield");
MELEMENT(tmp->shield_regen==0, "shield_regen");
MELEMENT(tmp->energy==0, "energy");
MELEMENT(tmp->energy_regen==0, "energt_regen");
MELEMENT(tmp->crew==0, "crew");
MELEMENT(tmp->mass==0, "mass");
MELEMENT(tmp->cap_cargo==0, "cap_cargo");
MELEMENT(tmp->cap_weapon==0, "cap_weapon");
MELEMENT(tmp->gfx_space == NULL, "GFX");
MELEMENT(tmp->gui == NULL, "GUI");
MELEMENT(tmp->class==0, "class");
MELEMENT(tmp->price==0, "price");
MELEMENT(tmp->tech==0, "tech");
MELEMENT(tmp->fabricator==0, "fabricator");
MELEMENT(tmp->description==0, "description");
MELEMENT(tmp->thrust==0, "thrust");
MELEMENT(tmp->turn==0, "turn");
MELEMENT(tmp->speed==0, "speed");
MELEMENT(tmp->armour==0, "armour");
MELEMENT(tmp->armour_regen==0, "armour_regen");
MELEMENT(tmp->shield==0, "shield");
MELEMENT(tmp->shield_regen==0, "shield_regen");
MELEMENT(tmp->energy==0, "energy");
MELEMENT(tmp->energy_regen==0, "energt_regen");
MELEMENT(tmp->crew==0, "crew");
MELEMENT(tmp->mass==0, "mass");
MELEMENT(tmp->cap_cargo==0, "cap_cargo");
MELEMENT(tmp->cap_weapon==0, "cap_weapon");
#undef MELEMENT
return tmp;
@ -244,7 +244,7 @@ int ships_load(void) {
free(buf);
xmlCleanupParser();
DEBUG("Loaded %d ship%s", ships, (ships==1) ? "" : "s");
DEBUG("Loaded %d ship%s", ships, (ships==1) ? "" : "s");
return 0;
}
@ -255,7 +255,7 @@ void ships_free(void) {
for(i = 0; i < ships; i++) {
// 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)->description) free(ship_stack[i].description);
if((ship_stack+i)->gui) free(ship_stack[i].gui);
so = (ship_stack+i)->outfit;
while(so) { // free the ship outfit.
@ -272,62 +272,62 @@ void ships_free(void) {
// Used to visualize the ships status.
void ship_view(char* shipname) {
Ship* s;
char buf[1024];
unsigned int wid;
wid = window_create(shipname, -1, -1, VIEW_WIDTH, VIEW_HEIGHT);
s = ship_get(shipname);
Ship* s;
char buf[1024];
unsigned int wid;
wid = window_create(shipname, -1, -1, VIEW_WIDTH, VIEW_HEIGHT);
s = ship_get(shipname);
window_addText(wid, 20, 0, 100, VIEW_HEIGHT-40,
0, "txtLabel", &gl_smallFont, &cDConsole,
"Name:\n"
"Class:\n"
"Crew:\n"
"Mass:\n"
"\n"
"Thrust:\n"
"Max Speed:\n"
"Turn:\n"
"\n"
"Shield:\n"
"Armour:\n"
"Energy:\n"
"\n"
"Weapon Space:\n"
"Cargo Space:\n");
window_addText(wid, 20, 0, 100, VIEW_HEIGHT-40,
0, "txtLabel", &gl_smallFont, &cDConsole,
"Name:\n"
"Class:\n"
"Crew:\n"
"Mass:\n"
"\n"
"Thrust:\n"
"Max Speed:\n"
"Turn:\n"
"\n"
"Shield:\n"
"Armour:\n"
"Energy:\n"
"\n"
"Weapon Space:\n"
"Cargo Space:\n");
snprintf(buf, 1024,
"%s\n"
"%s\n"
"%d\n"
"%d Tons\n"
"\n"
"%.2f MN\n"
"%.2f M/s\n"
"%.2f Grad/s\n"
"\n"
"%.2f MJ (%.2f MJ/s)\n)"
"%.2f MJ (%.2f MJ/s)\n)"
"%.2f MJ (%.2f MJ/s)\n)"
"\n"
"%d Tons\n"
"%d Tons\n",
s->name, ship_class(s), s->crew, s->mass,
s->thrust/s->mass, s->speed, s->turn,
s->shield, s->shield_regen, s->armour, s->armour_regen,
s->energy, s->energy_regen, s->cap_weapon, s->cap_cargo);
snprintf(buf, 1024,
"%s\n"
"%s\n"
"%d\n"
"%d Tons\n"
"\n"
"%.2f MN\n"
"%.2f M/s\n"
"%.2f Grad/s\n"
"\n"
"%.2f MJ (%.2f MJ/s)\n)"
"%.2f MJ (%.2f MJ/s)\n)"
"%.2f MJ (%.2f MJ/s)\n)"
"\n"
"%d Tons\n"
"%d Tons\n",
s->name, ship_class(s), s->crew, s->mass,
s->thrust/s->mass, s->speed, s->turn,
s->shield, s->shield_regen, s->armour, s->armour_regen,
s->energy, s->energy_regen, s->cap_weapon, s->cap_cargo);
window_addText(wid, 120, 0, VIEW_WIDTH-140, VIEW_HEIGHT-40,
0, "txtProperties", &gl_smallFont, &cBlack, buf);
window_addText(wid, 120, 0, VIEW_WIDTH-140, VIEW_HEIGHT-40,
0, "txtProperties", &gl_smallFont, &cBlack, buf);
// Close the button.
snprintf(buf, 37, "close%s", shipname);
window_addButton(wid, -20, 20,
BUTTON_WIDTH, BUTTON_HEIGHT,
buf, "Close", ship_view_close);
// Close the button.
snprintf(buf, 37, "close%s", shipname);
window_addButton(wid, -20, 20,
BUTTON_WIDTH, BUTTON_HEIGHT,
buf, "Close", ship_view_close);
}
static void ship_view_close(char* btn) {
window_destroy(window_get(btn+5)); // "closefoo -> Foo"
window_destroy(window_get(btn+5)); // "closefoo -> Foo"
}

View File

@ -12,15 +12,15 @@ typedef enum ShipClass_ {
SHIP_CLASS_CIV_LIGHT = 1,
SHIP_CLASS_CIV_MEDIUM = 2,
SHIP_CLASS_CIV_HEAVY = 3,
SHIP_CLASS_MIL_LIGHT = 4,
SHIP_CLASS_MIL_MEDIUM = 5,
SHIP_CLASS_MIL_HEAVY = 6,
SHIP_CLASS_ROB_LIGHT = 7,
SHIP_CLASS_ROB_MEDIUM = 8,
SHIP_CLASS_ROB_HEAVY = 9,
SHIP_CLASS_HYB_LIGHT = 10,
SHIP_CLASS_HYB_MEDIUM = 11,
SHIP_CLASS_HYB_HEAVY = 12
SHIP_CLASS_MIL_LIGHT = 4,
SHIP_CLASS_MIL_MEDIUM = 5,
SHIP_CLASS_MIL_HEAVY = 6,
SHIP_CLASS_ROB_LIGHT = 7,
SHIP_CLASS_ROB_MEDIUM = 8,
SHIP_CLASS_ROB_HEAVY = 9,
SHIP_CLASS_HYB_LIGHT = 10,
SHIP_CLASS_HYB_MEDIUM = 11,
SHIP_CLASS_HYB_HEAVY = 12
} ShipClass;
// Small wrapper for the outfits.
@ -36,11 +36,11 @@ typedef struct Ship_ {
char* name; // Ship name.
ShipClass class; // Ship class.
// Store stuff.
int price; // Price!
int tech;
char* fabricator; // Manufacturer.
char* description; // Sales pitch.
// Store stuff.
int price; // Price!
int tech;
char* fabricator; // Manufacturer.
char* description; // Sales pitch.
// Movement.
double thrust, turn, speed;
@ -51,8 +51,8 @@ typedef struct Ship_ {
// GUI interface.
char* gui;
// Sound.
ALuint sound;
// Sound.
ALuint sound;
// Characteristics.
int crew;

View File

@ -18,19 +18,19 @@
// right now.
// ==============================================
#define SOUND_PREFIX "../snd/sounds/"
#define SOUND_SUFFIX ".wav"
#define SOUND_PREFIX "../snd/sounds/"
#define SOUND_SUFFIX ".wav"
// 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;
#define VOICE_PLAYING (1<<0) // Voice is playing.
#define VOICE_LOOPING (1<<1) // Voice is looping.
#define voice_set(v,f) ((v)->flags |= f)
#define voice_is(v,f) ((v)->flags & f)
#define VOICE_PLAYING (1<<0) // Voice is playing.
#define VOICE_LOOPING (1<<1) // Voice is looping.
#define voice_set(v,f) ((v)->flags |= f)
#define voice_is(v,f) ((v)->flags & f)
// Global sound lock.
SDL_mutex* sound_lock = NULL;
@ -60,371 +60,371 @@ static void sound_free(alSound* snd);
static int voice_getSource(alVoice* voc);
int sound_init(void) {
int ret = 0;
int ret = 0;
sound_lock = SDL_CreateMutex();
sound_lock = SDL_CreateMutex();
SDL_mutexP(sound_lock);
const ALchar* device = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
DEBUG("OpenAL using device '%s'", device);
// Open the default device.
al_device = alcOpenDevice(NULL);
if(al_device == NULL) {
WARN("Unable to open default sound device");
ret = -1;
goto snderr_dev;
}
SDL_mutexP(sound_lock);
const ALchar* device = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
DEBUG("OpenAL using device '%s'", device);
// Open the default device.
al_device = alcOpenDevice(NULL);
if(al_device == NULL) {
WARN("Unable to open default sound device");
ret = -1;
goto snderr_dev;
}
// Create the OpenAL context.
al_context = alcCreateContext(al_device, NULL);
if(sound_lock == NULL) {
WARN("Unable to create OpenAL context");
ret = -2;
goto snderr_ctx;
}
// Create the OpenAL context.
al_context = alcCreateContext(al_device, NULL);
if(sound_lock == NULL) {
WARN("Unable to create OpenAL context");
ret = -2;
goto snderr_ctx;
}
// Clear the errors.
alGetError();
// Clear the errors.
alGetError();
// Set active context.
if(alcMakeContextCurrent(al_context)==AL_FALSE) {
WARN("Failure to set default context");
ret = -4;
goto snderr_act;
}
// Set active context.
if(alcMakeContextCurrent(al_context)==AL_FALSE) {
WARN("Failure to set default context");
ret = -4;
goto snderr_act;
}
// Set the master gain.
alListenerf(AL_GAIN, .1);
// Set the master gain.
alListenerf(AL_GAIN, .1);
// Set the distance model.
alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
// Set the distance model.
alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
SDL_mutexV(sound_lock);
SDL_mutexV(sound_lock);
// Load up all the sounds.
sound_makeList();
// Load up all the sounds.
sound_makeList();
// Start the music server.
music_init();
music_player = SDL_CreateThread(music_thread, NULL);
// Start the music server.
music_init();
music_player = SDL_CreateThread(music_thread, NULL);
return 0;
return 0;
snderr_act:
alcDestroyContext(al_context);
alcDestroyContext(al_context);
snderr_ctx:
al_context = NULL;
alcCloseDevice(al_device);
al_context = NULL;
alcCloseDevice(al_device);
snderr_dev:
al_device = NULL;
SDL_mutexV(sound_lock);
SDL_DestroyMutex(sound_lock);
sound_lock = NULL;
return ret;
al_device = NULL;
SDL_mutexV(sound_lock);
SDL_DestroyMutex(sound_lock);
sound_lock = NULL;
return ret;
}
// Clean up after the sound system.
void sound_exit(void) {
int i;
// Free the sounds.
for(i = 0; i < nsound_list; i++)
sound_free(&sound_list[i]);
free(sound_list);
sound_list = NULL;
nsound_list = 0;
int i;
// 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.
if(music_player) {
music_stop();
music_kill();
SDL_WaitThread(music_player, NULL);
music_exit();
}
// Must stop the music before killing it,
// then thread should commit suicide.
if(music_player) {
music_stop();
music_kill();
SDL_WaitThread(music_player, NULL);
music_exit();
}
if(sound_lock) {
SDL_mutexP(sound_lock);
if(sound_lock) {
SDL_mutexP(sound_lock);
if(al_context) {
alcMakeContextCurrent(NULL);
alcDestroyContext(al_context);
}
if(al_device) alcCloseDevice(al_device);
if(al_context) {
alcMakeContextCurrent(NULL);
alcDestroyContext(al_context);
}
if(al_device) alcCloseDevice(al_device);
SDL_mutexV(sound_lock);
SDL_DestroyMutex(sound_lock);
}
SDL_mutexV(sound_lock);
SDL_DestroyMutex(sound_lock);
}
}
// Get the buffer to sound of [name].
ALuint sound_get(char* name) {
if(sound_lock == NULL) return 0;
if(sound_lock == NULL) return 0;
int i;
for(i = 0; i < nsound_list; i++)
if(strcmp(name, sound_list[i].name)==0)
return sound_list[i].buffer;
WARN("Sound '%s' not found in sound list", name);
return 0;
int i;
for(i = 0; i < nsound_list; i++)
if(strcmp(name, sound_list[i].name)==0)
return sound_list[i].buffer;
WARN("Sound '%s' not found in sound list", name);
return 0;
}
// Make list of available sounds.
static int sound_makeList(void) {
if(sound_lock == NULL) return 0;
if(sound_lock == NULL) return 0;
char** files;
uint32_t nfiles, i;
char tmp[64];
int len;
char** files;
uint32_t nfiles, i;
char tmp[64];
int len;
// Get the file list.
files = pack_listfiles(data, &nfiles);
// Get the file list.
files = pack_listfiles(data, &nfiles);
// Load the profiles.
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)) {
// Load the profiles.
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.
sound_list = realloc(sound_list, ++nsound_list * sizeof(alSound));
// Expand the selection size.
sound_list = realloc(sound_list, ++nsound_list * sizeof(alSound));
// 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';
// 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.
sound_list[nsound_list-1].name = strdup(tmp);
sound_load(&sound_list[nsound_list-1].buffer, files[i]);
}
// give it the new name.
sound_list[nsound_list-1].name = strdup(tmp);
sound_load(&sound_list[nsound_list-1].buffer, files[i]);
}
// Free the char* allocated by pack.
for(i = 0; i < nfiles; i++)
free(files[i]);
free(files);
// Free the char* allocated by pack.
for(i = 0; i < nfiles; i++)
free(files[i]);
free(files);
DEBUG("Loaded %d sound%c", nsound_list, (nsound_list==1)?' ':'s');
DEBUG("Loaded %d sound%c", nsound_list, (nsound_list==1)?' ':'s');
return 0;
return 0;
}
// Loads a sound into the sound_list.
static int sound_load(ALuint* buffer, char* filename) {
if(sound_lock == NULL) return 0;
if(sound_lock == NULL) return 0;
void* wavdata;
unsigned int size;
ALenum err;
void* wavdata;
unsigned int size;
ALenum err;
// Get the file data buffer from the packfile.
wavdata = pack_readfile(DATA, filename, &size);
// Get the file data buffer from the packfile.
wavdata = pack_readfile(DATA, filename, &size);
SDL_mutexP(sound_lock);
SDL_mutexP(sound_lock);
// Bind to OpenAL buffer.
alGenBuffers(1, buffer);
alBufferData(*buffer, AL_FORMAT_MONO16, wavdata, size, 22050);
// Bind to OpenAL buffer.
alGenBuffers(1, buffer);
alBufferData(*buffer, AL_FORMAT_MONO16, wavdata, size, 22050);
// Errors?
if((err = alGetError()) != AL_NO_ERROR) {
WARN("OpenAL erro '%d' loading sound '%s'.", err, filename);
return 0;
}
// Errors?
if((err = alGetError()) != AL_NO_ERROR) {
WARN("OpenAL erro '%d' loading sound '%s'.", err, filename);
return 0;
}
SDL_mutexV(sound_lock);
SDL_mutexV(sound_lock);
// Finish up.
free(wavdata);
return 0;
// Finish up.
free(wavdata);
return 0;
}
static void sound_free(alSound* snd) {
if(sound_lock) return;
if(sound_lock) return;
SDL_mutexP(sound_lock);
SDL_mutexP(sound_lock);
if(snd->name) free(snd->name);
alDeleteBuffers(1, &snd->buffer);
if(snd->name) free(snd->name);
alDeleteBuffers(1, &snd->buffer);
SDL_mutexV(sound_lock);
SDL_mutexV(sound_lock);
}
// Update the sounds and prioritize them.
void sound_update(void) {
if(sound_lock == NULL) return;
int i;
if(sound_lock == NULL) return;
int i;
// TODO: Prioritize the things.
// TODO: Prioritize the things.
SDL_mutexP(sound_lock);
SDL_mutexP(sound_lock);
for(i = 0; i < nvoice_stack; i++) {
if(voice_is(voice_stack[i], VOICE_PLAYING)) {
// Update position.
alSource3f(voice_stack[i]->source, AL_POSITION,
voice_stack[i]->px, voice_stack[i]->py, 0.);
//alSource3f(voice_stack[i]->source, AL_VELOCITY,
//voice_stack[i]->vx, voice_stack[i]->vy, 0.);
for(i = 0; i < nvoice_stack; i++) {
if(voice_is(voice_stack[i], VOICE_PLAYING)) {
// Update position.
alSource3f(voice_stack[i]->source, AL_POSITION,
voice_stack[i]->px, voice_stack[i]->py, 0.);
//alSource3f(voice_stack[i]->source, AL_VELOCITY,
//voice_stack[i]->vx, voice_stack[i]->vy, 0.);
}
}
SDL_mutexV(sound_lock);
}
}
SDL_mutexV(sound_lock);
}
// Set all the sounds volume to vol.
void sound_volume(const double vol) {
if(sound_lock == NULL) return;
if(sound_lock == NULL) return;
int i;
int i;
svolume = (ALfloat) vol;
svolume = (ALfloat) vol;
SDL_mutexP(sound_lock);
for(i = 0; i < nvoice_stack; i++)
if(voice_set(voice_stack[i], VOICE_PLAYING))
alSourcef(voice_stack[i]->source, AL_GAIN, svolume);
SDL_mutexV(sound_lock);
SDL_mutexP(sound_lock);
for(i = 0; i < nvoice_stack; i++)
if(voice_set(voice_stack[i], VOICE_PLAYING))
alSourcef(voice_stack[i]->source, AL_GAIN, svolume);
SDL_mutexV(sound_lock);
}
// Attempt to alloc a source for a voice.
static int voice_getSource(alVoice* voc) {
if(sound_lock == NULL) return -1;
int ret;
ALenum err;
if(sound_lock == NULL) return -1;
int ret;
ALenum err;
ret = 0; // Default return.
ret = 0; // Default return.
SDL_mutexP(sound_lock);
SDL_mutexP(sound_lock);
// Try and grab a source.
voc->source = 0;
alGenSources(1, &voc->source);
err = alGetError();
// Try and grab a source.
voc->source = 0;
alGenSources(1, &voc->source);
err = alGetError();
if(err != AL_NO_ERROR) {
voc->source = 0;
ret = 1;
} else {
// Set the properties.
alSourcei(voc->source, AL_BUFFER, voc->buffer);
if(err != AL_NO_ERROR) {
voc->source = 0;
ret = 1;
} else {
// Set the properties.
alSourcei(voc->source, AL_BUFFER, voc->buffer);
// Distance model.
alSourcef(voc->source, AL_MAX_DISTANCE, 200.);
alSourcef(voc->source, AL_REFERENCE_DISTANCE, 50.);
// Distance model.
alSourcef(voc->source, AL_MAX_DISTANCE, 200.);
alSourcef(voc->source, AL_REFERENCE_DISTANCE, 50.);
alSourcei(voc->source, AL_SOURCE_RELATIVE, AL_FALSE);
alSourcef(voc->source, AL_GAIN, svolume);
alSource3f(voc->source, AL_POSITION, voc->px, voc->py, 0.);
//alSource3f(voc->source, AL_VELOCITY, voc->vx, voc->vy, 0.);
if(voice_is(voc, VOICE_LOOPING))
alSourcei(voc->source, AL_LOOPING, AL_TRUE);
else
alSourcei(voc->source, AL_LOOPING, AL_FALSE);
alSourcei(voc->source, AL_SOURCE_RELATIVE, AL_FALSE);
alSourcef(voc->source, AL_GAIN, svolume);
alSource3f(voc->source, AL_POSITION, voc->px, voc->py, 0.);
//alSource3f(voc->source, AL_VELOCITY, voc->vx, voc->vy, 0.);
if(voice_is(voc, VOICE_LOOPING))
alSourcei(voc->source, AL_LOOPING, AL_TRUE);
else
alSourcei(voc->source, AL_LOOPING, AL_FALSE);
// Try to play the source.
alSourcePlay(voc->source);
err = alGetError();
if(err == AL_NO_ERROR) voice_set(voc, VOICE_PLAYING);
else ret = 2;
}
SDL_mutexV(sound_lock);
// Try to play the source.
alSourcePlay(voc->source);
err = alGetError();
if(err == AL_NO_ERROR) voice_set(voc, VOICE_PLAYING);
else ret = 2;
}
SDL_mutexV(sound_lock);
return ret;
return ret;
}
alVoice* sound_addVoice(int priority, double px, double py, double vx, double vy,
const ALuint buffer, const int looping) {
const ALuint buffer, const int looping) {
(void)vx;
(void)vy;
(void)vx;
(void)vy;
if(sound_lock == NULL) return NULL;
if(sound_lock == NULL) return NULL;
alVoice* voc;
alVoice* voc;
nvoice_stack++;
if(nvoice_stack > mvoice_stack)
voice_stack = realloc(voice_stack, ++mvoice_stack*sizeof(alVoice*));
nvoice_stack++;
if(nvoice_stack > mvoice_stack)
voice_stack = realloc(voice_stack, ++mvoice_stack*sizeof(alVoice*));
voc = malloc(sizeof(alVoice));
voice_stack[nvoice_stack-1] = voc;
voc = malloc(sizeof(alVoice));
voice_stack[nvoice_stack-1] = voc;
// Set the data.
voc->priority = priority;
voc->start = SDL_GetTicks();
voc->buffer = buffer;
if(looping) voice_set(voc, VOICE_LOOPING);
voc->px = px;
voc->py = py;
//voc->vx = vx;
//voc->vy = vy;
// Set the data.
voc->priority = priority;
voc->start = SDL_GetTicks();
voc->buffer = buffer;
if(looping) voice_set(voc, VOICE_LOOPING);
voc->px = px;
voc->py = py;
//voc->vx = vx;
//voc->vy = vy;
voice_getSource(voc);
voice_getSource(voc);
return voc;
return voc;
}
void sound_delVoice(alVoice* voice) {
if(sound_lock == NULL) return;
ALint stat;
int i;
if(sound_lock == NULL) return;
ALint stat;
int i;
for(i = 0; i < nvoice_stack; i++)
if(voice == voice_stack[i])
break;
for(i = 0; i < nvoice_stack; i++)
if(voice == voice_stack[i])
break;
// No match found.
if(i >= nvoice_stack) {
WARN("Unable to find voice to free from stack");
return;
}
// No match found.
if(i >= nvoice_stack) {
WARN("Unable to find voice to free from stack");
return;
}
if(voice->source) {
SDL_mutexP(sound_lock);
if(voice->source) {
SDL_mutexP(sound_lock);
alGetSourcei(voice->source, AL_SOURCE_STATE, &stat);
if(stat == AL_PLAYING) alSourceStop(voice->source);
alDeleteSources(1, &voice->source);
voice->source = 0;
alGetSourcei(voice->source, AL_SOURCE_STATE, &stat);
if(stat == AL_PLAYING) alSourceStop(voice->source);
alDeleteSources(1, &voice->source);
voice->source = 0;
SDL_mutexV(sound_lock);
}
SDL_mutexV(sound_lock);
}
free(voice_stack[i]);
nvoice_stack--;
for(; i < nvoice_stack; i++)
voice_stack[i] = voice_stack[i+1];
free(voice_stack[i]);
nvoice_stack--;
for(; i < nvoice_stack; i++)
voice_stack[i] = voice_stack[i+1];
}
void voice_update(alVoice* voice, double px, double py, double vx, double vy) {
(void) vx;
(void) vy;
(void) vx;
(void) vy;
if(sound_lock == NULL) return;
if(sound_lock == NULL) return;
voice->px = px;
voice->py = py;
//voice->vx = vx;
//voice->vy = vy;
voice->px = px;
voice->py = py;
//voice->vx = vx;
//voice->vy = vy;
}
void sound_listener(double dir, double px, double py, double vx, double vy) {
(void)vx;
(void)vy;
(void)vx;
(void)vy;
if(sound_lock == NULL) return;
if(sound_lock == NULL) return;
SDL_mutexP(sound_lock);
SDL_mutexP(sound_lock);
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, 0.);
//alListener3f(AL_VELOCITY, vx, vy, 0.);
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, 0.);
//alListener3f(AL_VELOCITY, vx, vy, 0.);
SDL_mutexV(sound_lock);
SDL_mutexV(sound_lock);
}

View File

@ -2,21 +2,21 @@
#include <AL/al.h>
#include "physics.h"
#define SOUND_REFERENCE_DIST 500.
#define SOUND_MAX_DIST 1000.
#define SOUND_REFERENCE_DIST 500.
#define SOUND_MAX_DIST 1000.
// Virtual voice.
typedef struct alVoice_ {
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.
} alVoice;
// Sound subsystem.
@ -30,7 +30,7 @@ void sound_volume(const double vol);
// Voice manipulation function.
alVoice* sound_addVoice(int priority, double px, double py, double vx, double vy,
const ALuint buffer, const int looping);
const ALuint buffer, const int looping);
void sound_delVoice(alVoice* voice);
void voice_update(alVoice* voice, double px, double py, double vx, double vy);

View File

@ -35,14 +35,14 @@
#define FLAG_YSET (1<<1)
#define FLAG_ASTEROIDSSET (1<<2)
#define FLAG_INTEFERENCESET (1<<3)
#define FLAG_SERVICESET (1<<4)
#define FLAG_TECHSET (1<<5)
#define FLAG_SERVICESET (1<<4)
#define FLAG_TECHSET (1<<5)
// 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.
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.
// Current stardate in nice format.
char* stardate = "Stardate";
@ -58,9 +58,9 @@ typedef struct Star_ {
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
static Planet* planet_get(const char* name);
@ -76,7 +76,7 @@ extern void player_message(const char* fmt, ...);
#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, const double h, const RadarShape shape) {
const double w, const double h, const RadarShape shape) {
int i;
int cx, cy, x, y, r, rc;
double p;
@ -85,11 +85,11 @@ void planets_minimap(const double res,
glBegin(GL_POINTS);
for(i = 0; i < cur_system->nplanets; i++) {
if(areEnemies(player->faction, cur_system->planets[i].faction))
COLOUR(cHostile);
else if(areAllies(player->faction, cur_system->planets[i].faction))
COLOUR(cFriend);
else COLOUR(cNeutral);
if(areEnemies(player->faction, cur_system->planets[i].faction))
COLOUR(cHostile);
else if(areAllies(player->faction, cur_system->planets[i].faction))
COLOUR(cFriend);
else COLOUR(cNeutral);
r = (int)(cur_system->planets[i].gfx_space->sw / res);
cx = (int)((cur_system->planets[i].pos.x - player->solid->pos.x) / res);
cy = (int)((cur_system->planets[i].pos.y - player->solid->pos.y) / res);
@ -138,7 +138,7 @@ void planets_minimap(const double 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;
@ -163,8 +163,8 @@ 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.
case '0' : return STATION_CLASS_A;
// Stations use numbers as there isn't as many.
case '0' : return STATION_CLASS_A;
default: return PLANET_CLASS_NULL;
};
@ -194,63 +194,63 @@ int space_hyperspace(Pilot* p) {
// Basically used for spawning fleets.
void space_update(const double dt) {
unsigned int t;
int i, j, f;
unsigned int t;
int i, j, f;
(void)dt; // Don't need it right now.
(void)dt; // Don't need it right now.
t = SDL_GetTicks();
t = SDL_GetTicks();
if(cur_system->nfleets == 0)
// Please stop checking that there are no fleets.
spawn_timer = t + 300000;
if(cur_system->nfleets == 0)
// Please stop checking that there are no fleets.
spawn_timer = t + 300000;
if(spawn_timer < t) {
// Time to possibly spawn.
if(spawn_timer < t) {
// Time to possibly spawn.
// 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.
space_addFleet(cur_system->fleets[i].fleet);
break;
}
}
spawn_timer = t + 60000./(float)cur_system->nfleets;
}
// 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.
space_addFleet(cur_system->fleets[i].fleet);
break;
}
}
spawn_timer = t + 60000./(float)cur_system->nfleets;
}
}
// Crate a fleet.
static void space_addFleet(Fleet* fleet) {
int i;
double a;
Vec2 vv, vp, vn;
int i;
double a;
Vec2 vv, vp, vn;
// 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);
// 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);
for(i = 0; i < fleet->npilots; i++)
if(RNG(0, 100) <= fleet->pilots[i].chance) {
vect_cadd(&vp, RNG(75, 150) * (RNG(0,1) ? 1 : -1),
RNG(75, 150) * (RNG(0,1) ? 1 : -1));
for(i = 0; i < fleet->npilots; i++)
if(RNG(0, 100) <= fleet->pilots[i].chance) {
vect_cadd(&vp, RNG(75, 150) * (RNG(0,1) ? 1 : -1),
RNG(75, 150) * (RNG(0,1) ? 1 : -1));
a = vect_angle(&vp, &vn);
vectnull(&vv);
a = vect_angle(&vp, &vn);
vectnull(&vv);
pilot_create(fleet->pilots[i].ship,
fleet->pilots[i].name,
fleet->faction,
fleet->ai,
a,
&vp,
&vv,
0);
}
pilot_create(fleet->pilots[i].ship,
fleet->pilots[i].name,
fleet->faction,
fleet->ai,
a,
&vp,
&vv,
0);
}
}
// Init the system.
@ -261,7 +261,7 @@ void space_init(const char* sysname) {
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.
spfx_clear(); // Remove of explosions.
if((sysname == NULL) && (cur_system == NULL))
ERR("Cannot reinit system if there is no system previously loaded");
@ -286,16 +286,16 @@ void space_init(const char* sysname) {
}
// 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).
space_addFleet(cur_system->fleets[i].fleet);
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.
spawn_timer = SDL_GetTicks() + 120000./(float)(cur_system->nfleets+1);
// Start the spawn timer.
spawn_timer = SDL_GetTicks() + 120000./(float)(cur_system->nfleets+1);
}
// Load the planets of name 'name'.
static Planet* planet_get(const char* name) {
int i;
int i;
Planet* tmp = NULL;
@ -374,39 +374,39 @@ static Planet* planet_get(const char* name) {
else if(xml_isNode(cur, "bar"))
tmp->bar_description = strdup(xml_get(cur));
else if(xml_isNode(cur, "services")) {
flags |= FLAG_SERVICESET;
flags |= FLAG_SERVICESET;
tmp->services = xml_getInt(cur);
}
else if(xml_isNode(cur, "tech")) {
ccur = cur->children;
do {
if(xml_isNode(ccur, "main")) {
flags |= FLAG_TECHSET;
tmp->tech[0] = xml_getInt(ccur);
}
else if(xml_isNode(ccur, "special")) {
for(i = 1; i < PLANET_TECH_MAX; i++)
if(tmp->tech[i]==0) {
tmp->tech[i] = xml_getInt(ccur);
break;
}
if(i == PLANET_TECH_MAX) WARN("Planet '%s' has tooo many"
"'special tech' entries", tmp->name);
}
} while((ccur = ccur->next));
}
else if(xml_isNode(cur, "commodities")) {
ccur = cur->children;
do {
if(xml_isNode(ccur, "commodity")) {
tmp->commodities = realloc(tmp->commodities,
(tmp->ncommodities+1) * sizeof(Commodity*));
tmp->commodities[tmp->ncommodities] =
commodity_get(xml_get(ccur));
tmp->ncommodities++;
}
} while((ccur = ccur->next));
}
}
else if(xml_isNode(cur, "tech")) {
ccur = cur->children;
do {
if(xml_isNode(ccur, "main")) {
flags |= FLAG_TECHSET;
tmp->tech[0] = xml_getInt(ccur);
}
else if(xml_isNode(ccur, "special")) {
for(i = 1; i < PLANET_TECH_MAX; i++)
if(tmp->tech[i]==0) {
tmp->tech[i] = xml_getInt(ccur);
break;
}
if(i == PLANET_TECH_MAX) WARN("Planet '%s' has tooo many"
"'special tech' entries", tmp->name);
}
} while((ccur = ccur->next));
}
else if(xml_isNode(cur, "commodities")) {
ccur = cur->children;
do {
if(xml_isNode(ccur, "commodity")) {
tmp->commodities = realloc(tmp->commodities,
(tmp->ncommodities+1) * sizeof(Commodity*));
tmp->commodities[tmp->ncommodities] =
commodity_get(xml_get(ccur));
tmp->ncommodities++;
}
} while((ccur = ccur->next));
}
} while((cur = cur->next));
}
} while((node = node->next));
@ -423,25 +423,25 @@ static Planet* planet_get(const char* name) {
// 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");
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_LAND) &&
tmp->gfx_exterior==NULL, "GFX exterior");
MELEMENT((flags&FLAG_XSET)==0, "x");
MELEMENT((flags&FLAG_YSET)==0, "y");
MELEMENT(tmp->gfx_space==NULL, "GFX_space");
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_LAND) &&
tmp->gfx_exterior==NULL, "GFX exterior");
MELEMENT((flags&FLAG_XSET)==0, "x");
MELEMENT((flags&FLAG_YSET)==0, "y");
MELEMENT(tmp->class==PLANET_CLASS_NULL, "class");
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_LAND) &&
tmp->description==NULL, "description");
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_BASIC) &&
tmp->bar_description==NULL, "bar");
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_BASIC) &&
tmp->faction==NULL, "faction");
MELEMENT((flags&FLAG_SERVICESET)==0, "services");
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_LAND) &&
tmp->description==NULL, "description");
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_BASIC) &&
tmp->bar_description==NULL, "bar");
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_BASIC) &&
tmp->faction==NULL, "faction");
MELEMENT((flags&FLAG_SERVICESET)==0, "services");
MELEMENT((planet_hasService(tmp, PLANET_SERVICE_OUTFITS) ||
planet_hasService(tmp, PLANET_SERVICE_SHIPYARD)) &&
(flags&FLAG_TECHSET)==0, "tech");
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_COMMODITY) &&
(tmp->ncommodities==0), "commodity");
MELEMENT((planet_hasService(tmp, PLANET_SERVICE_OUTFITS) ||
planet_hasService(tmp, PLANET_SERVICE_SHIPYARD)) &&
(flags&FLAG_TECHSET)==0, "tech");
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_COMMODITY) &&
(tmp->ncommodities==0), "commodity");
#undef MELEMENT
} else
WARN("No planet found matching name '%s'", name);
@ -499,7 +499,7 @@ static StarSystem* system_parse(const xmlNodePtr parent) {
cur = node->children;
do {
if(xml_isNode(cur, "planet")) {
nplanets++; // Increase planet counter.
nplanets++; // Increase planet counter.
planet = planet_get(xml_get(cur));
planet = planet_get((const char*)cur->children->content);
tmp->planets = realloc(tmp->planets, sizeof(Planet)*(++tmp->nplanets));
@ -541,10 +541,10 @@ static StarSystem* system_parse(const xmlNodePtr parent) {
MELEMENT(flags&FLAG_INTEFERENCESET, "inteference");
#undef MELEMENT
// Post processing.
if(tmp->nplanets > 0)
// TODO: Make dependant on overall planet faction.
tmp->faction = tmp->planets[0].faction;
// Post processing.
if(tmp->nplanets > 0)
// TODO: Make dependant on overall planet faction.
tmp->faction = tmp->planets[0].faction;
return tmp;
}
@ -562,7 +562,7 @@ static void system_parseJumps(const xmlNodePtr parent) {
break;
}
if(i == systems_nstack)
WARN("System '%s' was not found in the stack for some reason", name);
WARN("System '%s' was not found in the stack for some reason", name);
free(name); // No need for it now.
node = parent->xmlChildrenNode;
@ -631,9 +631,9 @@ int space_load(void) {
free(buf);
xmlCleanupParser();
DEBUG("Loaded %d star system%s with %d planet%s",
systems_nstack, (systems_nstack==1) ? "" : "s",
nplanets, (nplanets==1) ? "" : "s");
DEBUG("Loaded %d star system%s with %d planet%s",
systems_nstack, (systems_nstack==1) ? "" : "s",
nplanets, (nplanets==1) ? "" : "s");
return 0;
}
@ -641,63 +641,63 @@ int space_load(void) {
// Render the system. -- Just playing god now.
void space_render(double dt) {
int i;
unsigned int t, timer;
double x, y, m;
unsigned int t, timer;
double x, y, m;
glMatrixMode(GL_MODELVIEW);
glPushMatrix(); // Translation matrix.
glTranslated(-(double)gl_screen.w/2., -(double)gl_screen.h/2., 0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix(); // Translation matrix.
glTranslated(-(double)gl_screen.w/2., -(double)gl_screen.h/2., 0);
t = SDL_GetTicks();
if(!player_isFlag(PLAYER_DESTROYED) &&
pilot_isFlag(player, PILOT_HYPERSPACE) && // Hyperspace fancy effect.
!paused && (player->ptimer-HYPERSPACE_STARS_BLUR < t)) {
t = SDL_GetTicks();
if(!player_isFlag(PLAYER_DESTROYED) &&
pilot_isFlag(player, PILOT_HYPERSPACE) && // Hyperspace fancy effect.
!paused && (player->ptimer-HYPERSPACE_STARS_BLUR < t)) {
timer = player->ptimer - HYPERSPACE_STARS_BLUR;
timer = player->ptimer - HYPERSPACE_STARS_BLUR;
// Fancy hyperspace effects.
glShadeModel(GL_SMOOTH);
// Fancy hyperspace effects.
glShadeModel(GL_SMOOTH);
glBegin(GL_LINES);
glBegin(GL_LINES);
// 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);
// 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);
for(i = 0; i < nstars; i++) {
glColor4d(1., 1., 1., stars[i].brightness);
glVertex2d(stars[i].x, stars[i].y);
glColor4d(1., 1., 1., 0.);
glVertex2d(stars[i].x+x*stars[i].brightness,stars[i].y+y*stars[i].brightness);
}
glEnd();
for(i = 0; i < nstars; i++) {
glColor4d(1., 1., 1., stars[i].brightness);
glVertex2d(stars[i].x, stars[i].y);
glColor4d(1., 1., 1., 0.);
glVertex2d(stars[i].x+x*stars[i].brightness,stars[i].y+y*stars[i].brightness);
}
glEnd();
glShadeModel(GL_FLAT);
glShadeModel(GL_FLAT);
} else {
glBegin(GL_POINTS);
} else {
glBegin(GL_POINTS);
for(i = 0; i < nstars; i++) {
if(!paused && !toolkit) {
// Update position.
if(!player_isFlag(PLAYER_DESTROYED)) {
stars[i].x -= VX(player->solid->vel)/(13.-10.*stars[i].brightness)*dt;
stars[i].y -= VY(player->solid->vel)/(13.-10.*stars[i].brightness)*dt;
}
// Scroll those stars bitch!
if(stars[i].x > gl_screen.w + STAR_BUF) stars[i].x = -STAR_BUF;
else if(stars[i].x < -STAR_BUF) stars[i].x = gl_screen.w + STAR_BUF;
if(stars[i].y > gl_screen.h + STAR_BUF) stars[i].y = -STAR_BUF;
else if(stars[i].y < -STAR_BUF) stars[i].y = gl_screen.h + STAR_BUF;
}
// Render.
glColor4d(1., 1., 1., stars[i].brightness);
glVertex2d(stars[i].x, stars[i].y);
}
glEnd();
}
glPopMatrix(); // Translation matrix.
for(i = 0; i < nstars; i++) {
if(!paused && !toolkit) {
// Update position.
if(!player_isFlag(PLAYER_DESTROYED)) {
stars[i].x -= VX(player->solid->vel)/(13.-10.*stars[i].brightness)*dt;
stars[i].y -= VY(player->solid->vel)/(13.-10.*stars[i].brightness)*dt;
}
// Scroll those stars bitch!
if(stars[i].x > gl_screen.w + STAR_BUF) stars[i].x = -STAR_BUF;
else if(stars[i].x < -STAR_BUF) stars[i].x = gl_screen.w + STAR_BUF;
if(stars[i].y > gl_screen.h + STAR_BUF) stars[i].y = -STAR_BUF;
else if(stars[i].y < -STAR_BUF) stars[i].y = gl_screen.h + STAR_BUF;
}
// Render.
glColor4d(1., 1., 1., stars[i].brightness);
glVertex2d(stars[i].x, stars[i].y);
}
glEnd();
}
glPopMatrix(); // Translation matrix.
}
// Render the planets.

View File

@ -7,7 +7,7 @@
#define MIN_HYPERSPACE_DIST 1500
#define MAX_HYPERSPACE_VEL 25
#define PLANET_TECH_MAX 8
#define PLANET_TECH_MAX 8
// Planet types. I didn't take them from Star Trek, I promise.
typedef enum PlanetClass_ {
@ -35,11 +35,11 @@ typedef enum PlanetClass_ {
PLANET_CLASS_X, // Demon.
PLANET_CLASS_Y, // Demon.
PLANET_CLASS_Z, // Demon.
STATION_CLASS_A // TODO.
STATION_CLASS_A // TODO.
} PlanetClass;
// Planet services.
#define PLANET_SERVICE_LAND (1<<0) // Can we land?
#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)
@ -48,44 +48,44 @@ typedef enum PlanetClass_ {
typedef struct Planet_ {
char* name; // Planet name
Vec2 pos; // Position in star system.
Vec2 pos; // Position in star system.
PlanetClass class; // Planet type.
Faction* faction; // Planet faction.
PlanetClass class; // Planet type.
Faction* 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.
int tech[PLANET_TECH_MAX];
// 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.
typedef struct SystemFleet_ {
Fleet* fleet; // Fleet to appear.
int chance; // Chance of fleet appearing in the system.
int chance; // Chance of fleet appearing in the system.
} SystemFleet;
typedef struct StarSystem_ {
char* name; // Star system identifier.
Vec2 pos; // Position.
Vec2 pos; // Position.
int stars, asteroids; // Un numero!
double interference; // Un uh.. Percentage.
double interference; // Un uh.. Percentage.
Faction* faction; // Overall faction.
Faction* 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.

View File

@ -8,35 +8,35 @@
#include "pause.h"
#include "spfx.h"
#define SPFX_GFX "../gfx/spfx/" // Graphics location.
#define SPFX_GFX "../gfx/spfx/" // Graphics location.
#define SPFX_CHUNK 10 // Chunk to allocate when needed.
typedef struct SPFX_Base_ {
char* name;
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.
static SPFX* spfx_stack_front = NULL;
static int spfx_nstack_front = 0;
static int spfx_mstack_front = 0;
static SPFX* spfx_stack_back = NULL;
static int spfx_nstack_back = 0;
static int spfx_mstack_back = 0;
static SPFX* spfx_stack_front = NULL;
static int spfx_nstack_front = 0;
static int spfx_mstack_front = 0;
static SPFX* spfx_stack_back = NULL;
static int spfx_nstack_back = 0;
static int spfx_mstack_back = 0;
static int spfx_base_load(char* name, int anim, char* gfx, int sx, int sy);
static void spfx_base_free(SPFX_Base* effect);
@ -48,198 +48,198 @@ static void spfx_delay_layer(SPFX* layer, int nlayer, unsigned int delay);
// 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];
SPFX_Base* cur;
char buf[PATH_MAX];
spfx_effects = realloc(spfx_effects, ++spfx_neffects*sizeof(SPFX_Base));
cur = &spfx_effects[spfx_neffects-1];
spfx_effects = realloc(spfx_effects, ++spfx_neffects*sizeof(SPFX_Base));
cur = &spfx_effects[spfx_neffects-1];
cur->name = strdup(name);
cur->anim = anim;
sprintf(buf, SPFX_GFX"%s", gfx);
cur->gfx = gl_newSprite(buf, sx, sy);
cur->name = strdup(name);
cur->anim = anim;
sprintf(buf, SPFX_GFX"%s", gfx);
cur->gfx = gl_newSprite(buf, sx, sy);
return 0;
return 0;
}
static void spfx_base_free(SPFX_Base* effect) {
if(effect->name) free(effect->name);
if(effect->gfx) gl_freeTexture(effect->gfx);
if(effect->name) free(effect->name);
if(effect->gfx) gl_freeTexture(effect->gfx);
}
int spfx_get(char* name) {
int i;
for(i = 0; i < spfx_neffects; i++)
if(strcmp(spfx_effects[i].name, name)==0)
return i;
WARN("SPFX '%s' not found!", name);
return 0;
int i;
for(i = 0; i < spfx_neffects; i++)
if(strcmp(spfx_effects[i].name, name)==0)
return i;
WARN("SPFX '%s' not found!", name);
return 0;
}
// Load/Unload.
int spfx_load(void) {
spfx_base_load("ExpS", 400, "exps.png", 6, 5);
spfx_base_load("ExpM", 450, "expm.png", 6, 5);
spfx_base_load("ExpL", 500, "expl.png", 6, 5);
return 0;
spfx_base_load("ExpS", 400, "exps.png", 6, 5);
spfx_base_load("ExpM", 450, "expm.png", 6, 5);
spfx_base_load("ExpL", 500, "expl.png", 6, 5);
return 0;
}
void spfx_free(void) {
int i;
int i;
// Get rid of all the particles and free the stacks.
spfx_clear();
if(spfx_stack_front) free(spfx_stack_front);
spfx_stack_front = NULL;
spfx_mstack_front = 0;
if(spfx_stack_back) free(spfx_stack_back);
spfx_stack_back = NULL;
spfx_mstack_back = 0;
// Get rid of all the particles and free the stacks.
spfx_clear();
if(spfx_stack_front) free(spfx_stack_front);
spfx_stack_front = NULL;
spfx_mstack_front = 0;
if(spfx_stack_back) free(spfx_stack_back);
spfx_stack_back = NULL;
spfx_mstack_back = 0;
for(i = 0; i < spfx_neffects; i++)
spfx_base_free(&spfx_effects[i]);
free(spfx_effects);
spfx_effects = NULL;
spfx_neffects = 0;
for(i = 0; i < spfx_neffects; i++)
spfx_base_free(&spfx_effects[i]);
free(spfx_effects);
spfx_effects = NULL;
spfx_neffects = 0;
}
void spfx_add(int effect,
const double px, const double py,
const double vx, const double vy,
const int layer) {
SPFX* cur_spfx;
const double px, const double py,
const double vx, const double vy,
const int layer) {
SPFX* cur_spfx;
if(layer == SPFX_LAYER_FRONT) {
// Front layer.
if(spfx_mstack_front < spfx_nstack_front+1) {
// We need more memory.
spfx_mstack_front += SPFX_CHUNK;
spfx_stack_front = realloc(spfx_stack_front, spfx_mstack_front*sizeof(SPFX));
}
cur_spfx = &spfx_stack_front[spfx_nstack_front];
spfx_nstack_front++;
}
else if(layer == SPFX_LAYER_BACK) {
// Back layer.
if(spfx_mstack_back < spfx_nstack_back+1) {
// Need more memory.
spfx_mstack_back += SPFX_CHUNK;
spfx_stack_back = realloc(spfx_stack_back, spfx_mstack_back*sizeof(SPFX));
}
cur_spfx = &spfx_stack_back[spfx_nstack_back];
spfx_nstack_back++;
}
if(layer == SPFX_LAYER_FRONT) {
// Front layer.
if(spfx_mstack_front < spfx_nstack_front+1) {
// We need more memory.
spfx_mstack_front += SPFX_CHUNK;
spfx_stack_front = realloc(spfx_stack_front, spfx_mstack_front*sizeof(SPFX));
}
cur_spfx = &spfx_stack_front[spfx_nstack_front];
spfx_nstack_front++;
}
else if(layer == SPFX_LAYER_BACK) {
// Back layer.
if(spfx_mstack_back < spfx_nstack_back+1) {
// Need more memory.
spfx_mstack_back += SPFX_CHUNK;
spfx_stack_back = realloc(spfx_stack_back, spfx_mstack_back*sizeof(SPFX));
}
cur_spfx = &spfx_stack_back[spfx_nstack_back];
spfx_nstack_back++;
}
cur_spfx->effect = effect;
vect_csetmin(&cur_spfx->pos, px, py);
vect_csetmin(&cur_spfx->vel, vx, vy);
cur_spfx->t = SDL_GetTicks();
cur_spfx->effect = effect;
vect_csetmin(&cur_spfx->pos, px, py);
vect_csetmin(&cur_spfx->vel, vx, vy);
cur_spfx->t = SDL_GetTicks();
}
void spfx_clear(void) {
int i;
for(i = spfx_nstack_front-1; i >= 0; i--)
spfx_destroy(spfx_stack_front, &spfx_nstack_front, i);
int i;
for(i = spfx_nstack_front-1; i >= 0; i--)
spfx_destroy(spfx_stack_front, &spfx_nstack_front, i);
for(i = spfx_nstack_back-1; i >= 0; i--)
spfx_destroy(spfx_stack_back, &spfx_nstack_back, i);
for(i = spfx_nstack_back-1; i >= 0; i--)
spfx_destroy(spfx_stack_back, &spfx_nstack_back, i);
}
static void spfx_destroy(SPFX* layer, int* nlayer, int spfx) {
(*nlayer)--;
memmove(&layer[spfx], &layer[spfx+1], (*nlayer-spfx)*sizeof(SPFX));
(*nlayer)--;
memmove(&layer[spfx], &layer[spfx+1], (*nlayer-spfx)*sizeof(SPFX));
}
void spfx_update(const double dt) {
spfx_update_layer(spfx_stack_front, &spfx_nstack_front, dt);
spfx_update_layer(spfx_stack_back, &spfx_nstack_back, dt);
spfx_update_layer(spfx_stack_front, &spfx_nstack_front, dt);
spfx_update_layer(spfx_stack_back, &spfx_nstack_back, dt);
}
static void spfx_update_layer(SPFX* layer, int* nlayer, const double dt) {
int i;
unsigned int t = SDL_GetTicks();
int i;
unsigned int t = SDL_GetTicks();
for(i = 0; i < *nlayer; i++) {
// 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.
vect_cadd(&layer[i].pos, dt*VX(layer[i].vel), dt*VY(layer[i].vel));
}
for(i = 0; i < *nlayer; i++) {
// 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.
vect_cadd(&layer[i].pos, dt*VX(layer[i].vel), dt*VY(layer[i].vel));
}
}
void spfx_render(const int layer) {
SPFX* spfx_stack;
int i, spfx_nstack;
SPFX_Base* effect;
int sx, sy;
unsigned int t = SDL_GetTicks();
SPFX* spfx_stack;
int i, spfx_nstack;
SPFX_Base* effect;
int sx, sy;
unsigned int t = SDL_GetTicks();
// Get the appropriate layer.
switch(layer) {
case SPFX_LAYER_FRONT:
spfx_stack = spfx_stack_front;
spfx_nstack = spfx_nstack_front;
break;
case SPFX_LAYER_BACK:
spfx_stack = spfx_stack_back;
spfx_nstack = spfx_nstack_back;
break;
}
for(i = 0; i < spfx_nstack; i++) {
effect = &spfx_effects[spfx_stack[i].effect];
// Get the appropriate layer.
switch(layer) {
case SPFX_LAYER_FRONT:
spfx_stack = spfx_stack_front;
spfx_nstack = spfx_nstack_front;
break;
case SPFX_LAYER_BACK:
spfx_stack = spfx_stack_back;
spfx_nstack = spfx_nstack_back;
break;
}
for(i = 0; i < spfx_nstack; i++) {
effect = &spfx_effects[spfx_stack[i].effect];
sx = (int)effect->gfx->sx;
sy = (int)effect->gfx->sy;
sx = (int)effect->gfx->sx;
sy = (int)effect->gfx->sy;
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.);
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.);
gl_blitSprite(effect->gfx,
VX(spfx_stack[i].pos), VY(spfx_stack[i].pos),
spfx_stack[i].lastframe % sx,
spfx_stack[i].lastframe / sx,
NULL);
}
gl_blitSprite(effect->gfx,
VX(spfx_stack[i].pos), VY(spfx_stack[i].pos),
spfx_stack[i].lastframe % sx,
spfx_stack[i].lastframe / sx,
NULL);
}
}
void spfx_pause(void) {
spfx_pause_layer(spfx_stack_front, spfx_nstack_front);
spfx_pause_layer(spfx_stack_back, spfx_nstack_back);
spfx_pause_layer(spfx_stack_front, spfx_nstack_front);
spfx_pause_layer(spfx_stack_back, spfx_nstack_back);
}
static void spfx_pause_layer(SPFX* layer, int nlayer) {
int i;
unsigned int t = SDL_GetTicks();
for(i = 0; i < nlayer; i++)
layer[i].t -= t;
int i;
unsigned int t = SDL_GetTicks();
for(i = 0; i < nlayer; i++)
layer[i].t -= t;
}
void spfx_unpause(void) {
spfx_unpause_layer(spfx_stack_front, spfx_nstack_front);
spfx_unpause_layer(spfx_stack_back, spfx_nstack_back);
spfx_unpause_layer(spfx_stack_front, spfx_nstack_front);
spfx_unpause_layer(spfx_stack_back, spfx_nstack_back);
}
static void spfx_unpause_layer(SPFX* layer, int nlayer) {
int i;
unsigned int t = SDL_GetTicks();
for(i = 0; i < nlayer; i++)
layer[i].t += t;
int i;
unsigned int t = SDL_GetTicks();
for(i = 0; i < nlayer; i++)
layer[i].t += t;
}
void spfx_delay(unsigned int delay) {
spfx_delay_layer(spfx_stack_front, spfx_nstack_front, delay);
spfx_delay_layer(spfx_stack_back, spfx_nstack_back, delay);
spfx_delay_layer(spfx_stack_front, spfx_nstack_front, delay);
spfx_delay_layer(spfx_stack_back, spfx_nstack_back, delay);
}
static void spfx_delay_layer(SPFX* layer, int nlayer, unsigned int delay) {
int i;
for(i = 0; i < nlayer; i++)
layer[i].t += delay;
int i;
for(i = 0; i < nlayer; i++)
layer[i].t += delay;
}

View File

@ -1,15 +1,15 @@
#pragma once
#include "physics.h"
#define SPFX_LAYER_FRONT 0
#define SPFX_LAYER_BACK 1
#define SPFX_LAYER_FRONT 0
#define SPFX_LAYER_BACK 1
// 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);
const double px, const double py,
const double vx, const double vy,
const int layer);
// Stack mass manipulation functions.
void spfx_update(const double dt);

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@ extern int toolkit;
// Creation.
unsigned int window_create(char* name, const int x, const int y,
const int w, const int h);
const int w, const int h);
void window_addButton(const unsigned int wid, const int x, const int y,
const int w, const int h, char* name, char* display,
@ -21,22 +21,22 @@ void window_addImage(const unsigned int wid, const int x, const int y,
char* name, glTexture* image);
void window_addList(const unsigned int wid,
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*));
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.
char* name, const int border,
void(*render) (double x, double y, double w, double h),
void(*mouse) (SDL_Event* event, double x, double y));
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));
// Popups and alerts.
void toolkit_alert(const char* fmt, ...);

View File

@ -15,8 +15,8 @@
#define weapon_isSmart(w) (w->think)
#define VOICE_PRIORITY_BOLT 10 // Default.
#define VOICE_PRIORITY_AMMO 8 // Higher.
#define VOICE_PRIORITY_BOLT 10 // Default.
#define VOICE_PRIORITY_AMMO 8 // Higher.
// Some stuff from pilot.
extern Pilot** pilot_stack;
@ -33,9 +33,9 @@ typedef struct Weapon_ {
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.
// 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.
} Weapon;
@ -67,7 +67,7 @@ static void think_smart(Weapon* w, const double dt);
#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, const double h, const RadarShape shape) {
const double w, const double h, const RadarShape shape) {
int i, rc;
double x, y;
@ -108,70 +108,70 @@ void weapons_unpause(void) {
}
void weapons_delay(unsigned int delay) {
int i;
for(i = 0; i < nwbackLayer; i++)
wbackLayer[i]->timer += delay;
for(i = 0; i < nwfrontLayer; i++)
wfrontLayer[i]->timer += delay;
int i;
for(i = 0; i < nwbackLayer; i++)
wbackLayer[i]->timer += delay;
for(i = 0; i < nwfrontLayer; i++)
wfrontLayer[i]->timer += delay;
}
// Seeker brain, You get what you pay for. :)
static void think_seeker(Weapon* w, const double dt) {
double diff;
double diff;
if(w->target == w->parent) return; // HEY! Self harm is not allowed.
Pilot* p = pilot_get(w->target);
if(p == NULL) {
limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt);
return;
}
limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt);
return;
}
// 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.
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)
w->solid->dir_vel = -w->outfit->u.amm.turn;
}
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.
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)
w->solid->dir_vel = -w->outfit->u.amm.turn;
}
vect_pset(&w->solid->force, w->outfit->u.amm.thrust, w->solid->dir);
limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt);
limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt);
}
// Smart seeker brain. Much better at homing.
static void think_smart(Weapon* w, const double dt) {
double diff;
Vec2 tv, sv;
double diff;
Vec2 tv, sv;
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);
return;
}
if(p == NULL) {
limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt);
return;
}
if(SDL_GetTicks() > (w->timer + w->outfit->u.amm.lockon)) {
vect_cset(&tv, VX(p->solid->pos) + VX(p->solid->vel),
VY(p->solid->pos) + VY(p->solid->vel));
vect_cset(&sv, VX(w->solid->pos) + VX(w->solid->vel),
VY(w->solid->pos) + VY(w->solid->vel));
diff = angle_diff(w->solid->dir, vect_angle(&tv, &sv));
w->solid->dir_vel = 10*diff*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;
else if(w->solid->dir_vel < -w->outfit->u.amm.turn)
w->solid->dir_vel = -w->outfit->u.amm.turn;
}
if(SDL_GetTicks() > (w->timer + w->outfit->u.amm.lockon)) {
vect_cset(&tv, VX(p->solid->pos) + VX(p->solid->vel),
VY(p->solid->pos) + VY(p->solid->vel));
vect_cset(&sv, VX(w->solid->pos) + VX(w->solid->vel),
VY(w->solid->pos) + VY(w->solid->vel));
diff = angle_diff(w->solid->dir, vect_angle(&tv, &sv));
w->solid->dir_vel = 10*diff*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;
else if(w->solid->dir_vel < -w->outfit->u.amm.turn)
w->solid->dir_vel = -w->outfit->u.amm.turn;
}
vect_pset(&w->solid->force, w->outfit->u.amm.thrust, w->solid->dir);
vect_pset(&w->solid->force, w->outfit->u.amm.thrust, w->solid->dir);
limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt);
limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt);
}
@ -201,27 +201,27 @@ 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:
case OUTFIT_TYPE_MISSILE_SWARM_SMART_AMMO:
case OUTFIT_TYPE_MISSILE_SEEK_SMART_AMMO:
case OUTFIT_TYPE_MISSILE_SWARM_AMMO:
case OUTFIT_TYPE_MISSILE_SWARM_SMART_AMMO:
if(SDL_GetTicks() >
(wlayer[i]->timer + wlayer[i]->outfit->u.amm.duration)) {
(wlayer[i]->timer + wlayer[i]->outfit->u.amm.duration)) {
weapon_destroy(wlayer[i], layer);
continue;
}
break;
case OUTFIT_TYPE_BOLT:
// Check see if it exceeds distance.
case OUTFIT_TYPE_TURRET_BOLT:
if(SDL_GetTicks() > wlayer[i]->timer) {
case OUTFIT_TYPE_TURRET_BOLT:
if(SDL_GetTicks() > wlayer[i]->timer) {
weapon_destroy(wlayer[i],layer);
continue;
}
break;
default:
break;
default:
break;
}
weapon_update(wlayer[i], dt, layer);
// If the weapon has been deleted we are going to have to hold back one.
@ -252,9 +252,9 @@ void weapons_render(const WeaponLayer layer) {
// Render the weapons.
static void weapon_render(const Weapon* w) {
int sx, sy;
glTexture* gfx;
glTexture* gfx;
gfx = outfit_gfx(w->outfit);
gfx = outfit_gfx(w->outfit);
// Get the sprite corresponding to the direction facing.
gl_getSpriteFromDir(&sx, &sy, gfx, w->solid->dir);
@ -265,15 +265,15 @@ static void weapon_render(const Weapon* w) {
// Update the weapon.
static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) {
int i, wsx, wsy, psx, psy;
glTexture* gfx;
glTexture* gfx;
gfx = outfit_gfx(w->outfit);
gfx = outfit_gfx(w->outfit);
gl_getSpriteFromDir(&wsx, &wsy, gfx, w->solid->dir);
for(i = 0; i < pilots; i++) {
psx = pilot_stack[i]->tsx;
psy = pilot_stack[i]->tsy;
psx = pilot_stack[i]->tsx;
psy = pilot_stack[i]->tsy;
if(w->parent == pilot_stack[i]->id) continue; // Hey! That's you.
@ -292,14 +292,14 @@ static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) {
}
}
if(weapon_isSmart(w)) (*w->think)(w,dt);
if(weapon_isSmart(w)) (*w->think)(w,dt);
(*w->solid->update)(w->solid, dt);
// 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);
// 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.
@ -307,13 +307,13 @@ static void weapon_hit(Weapon* w, Pilot* p, WeaponLayer layer) {
// Someone should let the ai know it's been attacked.
if(!pilot_isPlayer(p)) {
ai_attacked(p, w->parent);
spfx_add(outfit_spfx(w->outfit),
VX(w->solid->pos), VY(w->solid->pos),
VX(p->solid->vel), VY(p->solid->vel), SPFX_LAYER_BACK);
} else
spfx_add(outfit_spfx(w->outfit),
VX(w->solid->pos), VY(w->solid->pos),
VX(p->solid->vel), VY(p->solid->vel), SPFX_LAYER_FRONT);
spfx_add(outfit_spfx(w->outfit),
VX(w->solid->pos), VY(w->solid->pos),
VX(p->solid->vel), VY(p->solid->vel), SPFX_LAYER_BACK);
} else
spfx_add(outfit_spfx(w->outfit),
VX(w->solid->pos), VY(w->solid->pos),
VX(p->solid->vel), VY(p->solid->vel), SPFX_LAYER_FRONT);
if(w->parent == PLAYER_ID)
// Make hostile to player.
@ -345,45 +345,45 @@ static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2*
if((rdir > 2.*M_PI) || (rdir < 0.)) rdir = fmod(rdir, 2.*M_PI);
vectcpy(&v, vel);
vect_cadd(&v, outfit->u.blt.speed*cos(rdir), outfit->u.blt.speed*sin(rdir));
w->timer += 1000*(unsigned int)outfit->u.blt.range/outfit->u.blt.speed;
w->timer += 1000*(unsigned int)outfit->u.blt.range/outfit->u.blt.speed;
w->solid = solid_create(mass, rdir, pos, &v);
w->voice = sound_addVoice(VOICE_PRIORITY_BOLT,
w->solid->pos.x, w->solid->pos.y,
w->solid->vel.x, w->solid->vel.y, w->outfit->u.blt.sound, 0);
w->voice = sound_addVoice(VOICE_PRIORITY_BOLT,
w->solid->pos.x, w->solid->pos.y,
w->solid->vel.x, w->solid->vel.y, w->outfit->u.blt.sound, 0);
break;
case OUTFIT_TYPE_MISSILE_SEEK_AMMO:
mass = w->outfit->mass;
w->solid = solid_create(mass, dir, pos, vel);
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);
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);
break;
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->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);
break;
case OUTFIT_TYPE_TURRET_BOLT:
if(w->parent != w->target)
rdir = vect_angle(pos, &pilot_get(w->target)->solid->pos);
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);
vect_cadd(&v, outfit->u.blt.speed*cos(rdir), outfit->u.blt.speed*sin(rdir));
w->timer += 1000*(unsigned int)outfit->u.blt.range / outfit->u.blt.speed;
w->solid = solid_create(mass, rdir, pos, &v);
w->voice = sound_addVoice(VOICE_PRIORITY_BOLT,
w->solid->pos.x, w->solid->pos.y,
w->solid->vel.x, w->solid->vel.y, w->outfit->u.blt.sound, 0);
break;
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->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);
break;
case OUTFIT_TYPE_TURRET_BOLT:
if(w->parent != w->target)
rdir = vect_angle(pos, &pilot_get(w->target)->solid->pos);
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);
vect_cadd(&v, outfit->u.blt.speed*cos(rdir), outfit->u.blt.speed*sin(rdir));
w->timer += 1000*(unsigned int)outfit->u.blt.range / outfit->u.blt.speed;
w->solid = solid_create(mass, rdir, pos, &v);
w->voice = sound_addVoice(VOICE_PRIORITY_BOLT,
w->solid->pos.x, w->solid->pos.y,
w->solid->vel.x, w->solid->vel.y, w->outfit->u.blt.sound, 0);
break;
default:
// Just dump it where the player is.
w->voice = NULL;
w->voice = NULL;
w->solid = solid_create(mass, dir, pos, vel);
break;
}
@ -391,11 +391,11 @@ static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2*
}
// 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) {
void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos,
const Vec2* vel, unsigned int parent, unsigned int target) {
if(!outfit_isWeapon(outfit) &&
!outfit_isAmmo(outfit) && !outfit_isTurret(outfit)) {
!outfit_isAmmo(outfit) && !outfit_isTurret(outfit)) {
ERR("Trying to create a weapon from a non-Weapon type Outfit");
return;
}
@ -463,7 +463,7 @@ static void weapon_destroy(Weapon* w, WeaponLayer layer) {
// Clear the weapon.
static void weapon_free(Weapon* w) {
sound_delVoice(w->voice);
sound_delVoice(w->voice);
solid_free(w->solid);
free(w);
}