[Fix] Moving from tab to space messed all the indents up. I thing that got them all now.

This commit is contained in:
Allanis 2013-03-21 19:34:35 +00:00
parent 0f6ff44a93
commit 6a7c051851
46 changed files with 3989 additions and 3986 deletions

View File

@ -29,7 +29,7 @@
// B and until the control task comes in. Then the pilot could // B and until the control task comes in. Then the pilot could
// run if it deems fit that Pilot C and Pilot B together are // run if it deems fit that Pilot C and Pilot B together are
// both too strong for A. Or.. Attack C as it is an easy target // both too strong for A. Or.. Attack C as it is an easy target
// to finish. // to finish.
// Basically, there is many possibilities, and it's down to the // Basically, there is many possibilities, and it's down to the
// Lua fanatics to decide what to do. // Lua fanatics to decide what to do.
// //
@ -55,7 +55,7 @@
#define lua_regfunc(l,s,f) (lua_pushcfunction(l,f), lua_setglobal(L,s)) #define lua_regfunc(l,s,f) (lua_pushcfunction(l,f), lua_setglobal(L,s))
// L state, void* buf, int n size, char* s identifier. // L state, void* buf, int n size, char* s identifier.
#define luaL_dobuffer(L,b,n,s) \ #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. // Don't run the function if (n) params aren't passed.
#define MIN_ARGS(n) if(lua_gettop(L) < n) return 0 #define MIN_ARGS(n) if(lua_gettop(L) < n) return 0
@ -220,7 +220,7 @@ static void ai_run(const char* funcname) {
if(lua_pcall(L, 0, 0, 0)) if(lua_pcall(L, 0, 0, 0))
// Errors accured. // Errors accured.
WARN("Pilot '%s' ai -> '%s' : %s", WARN("Pilot '%s' ai -> '%s' : %s",
cur_pilot->name, funcname, lua_tostring(L,-1)); cur_pilot->name, funcname, lua_tostring(L,-1));
} }
// Destroy the AI part of the pilot. // Destroy the AI part of the pilot.
@ -240,8 +240,8 @@ int ai_init(void) {
// Load the profiles. // Load the profiles.
for(i = 0; i < nfiles; i++) for(i = 0; i < nfiles; i++)
if((strncmp(files[i], AI_PREFIX, strlen(AI_PREFIX))==0 && if((strncmp(files[i], AI_PREFIX, strlen(AI_PREFIX))==0 &&
strncmp(files[i] + strlen(files[i]) - strlen(AI_SUFFIX), strncmp(files[i] + strlen(files[i]) - strlen(AI_SUFFIX),
AI_SUFFIX, strlen(AI_SUFFIX))==0)) AI_SUFFIX, strlen(AI_SUFFIX))==0))
if(ai_loadProfile(files[i])) if(ai_loadProfile(files[i]))
WARN("Error loading AI profile '%s'", files[i]); WARN("Error loading AI profile '%s'", files[i]);
@ -263,12 +263,12 @@ static int ai_loadProfile(char* filename) {
profiles = realloc(profiles, sizeof(AI_Profile)*(++nprofiles)); profiles = realloc(profiles, sizeof(AI_Profile)*(++nprofiles));
profiles[nprofiles-1].name = profiles[nprofiles-1].name =
malloc(sizeof(char)* malloc(sizeof(char)*
(strlen(filename)-strlen(AI_PREFIX)-strlen(AI_SUFFIX))+1); (strlen(filename)-strlen(AI_PREFIX)-strlen(AI_SUFFIX))+1);
snprintf(profiles[nprofiles-1].name, snprintf(profiles[nprofiles-1].name,
strlen(filename)-strlen(AI_PREFIX)-strlen(AI_SUFFIX)+1, strlen(filename)-strlen(AI_PREFIX)-strlen(AI_SUFFIX)+1,
"%s", filename+strlen(AI_PREFIX)); "%s", filename+strlen(AI_PREFIX));
profiles[nprofiles-1].L = luaL_newstate(); profiles[nprofiles-1].L = luaL_newstate();
@ -305,7 +305,7 @@ static int ai_loadProfile(char* filename) {
// Get the AI_Profile with name. // Get the AI_Profile with name.
AI_Profile* ai_getProfile(char* name) { AI_Profile* ai_getProfile(char* name) {
if(profiles == NULL) return NULL; if(profiles == NULL) return NULL;
int i; int i;
for(i = 0; i < nprofiles; i++) for(i = 0; i < nprofiles; i++)
if(strcmp(name, profiles[i].name)==0) if(strcmp(name, profiles[i].name)==0)
@ -329,7 +329,7 @@ void ai_exit(void) {
void ai_think(Pilot* pilot) { void ai_think(Pilot* pilot) {
cur_pilot = pilot; // Set current pilot being processed. cur_pilot = pilot; // Set current pilot being processed.
L = cur_pilot->ai->L; // Set the AI profile to the current pilot's. L = cur_pilot->ai->L; // Set the AI profile to the current pilot's.
// Clean up some variables. // Clean up some variables.
pilot_acc = pilot_turn = 0.; pilot_acc = pilot_turn = 0.;
pilot_flags = 0; pilot_flags = 0;
@ -354,8 +354,8 @@ void ai_think(Pilot* pilot) {
if(pilot_turn) // Set the turning velocity. if(pilot_turn) // Set the turning velocity.
cur_pilot->solid->dir_vel -= cur_pilot->turn * pilot_turn; cur_pilot->solid->dir_vel -= cur_pilot->turn * pilot_turn;
vect_pset(&cur_pilot->solid->force, cur_pilot->thrust * pilot_acc, vect_pset(&cur_pilot->solid->force, cur_pilot->thrust * pilot_acc,
cur_pilot->solid->dir); cur_pilot->solid->dir);
// Fire weapons if needs be. // Fire weapons if needs be.
if(ai_isFlag(AI_PRIMARY)) pilot_shoot(pilot, pilot_target, 0); // Primary. if(ai_isFlag(AI_PRIMARY)) pilot_shoot(pilot, pilot_target, 0); // Primary.
if(ai_isFlag(AI_SECONDARY)) pilot_shoot(pilot, pilot_target, 1); // Secondary. if(ai_isFlag(AI_SECONDARY)) pilot_shoot(pilot, pilot_target, 1); // Secondary.
@ -497,7 +497,7 @@ static int ai_shield(lua_State* L) {
if(lua_isnumber(L,1)) d = pilot_get((unsigned int)lua_tonumber(L,1))->shield; if(lua_isnumber(L,1)) d = pilot_get((unsigned int)lua_tonumber(L,1))->shield;
else d = cur_pilot->shield; else d = cur_pilot->shield;
lua_pushnumber(L, d); lua_pushnumber(L, d);
return 1; return 1;
} }
@ -506,7 +506,7 @@ static int ai_shield(lua_State* L) {
static int ai_parmour(lua_State* L) { static int ai_parmour(lua_State* L) {
double d; double d;
Pilot* p; Pilot* p;
if(lua_isnumber(L,1)) { if(lua_isnumber(L,1)) {
p = pilot_get((unsigned int)lua_tonumber(L,1)); p = pilot_get((unsigned int)lua_tonumber(L,1));
d = p->armour / p->armour_max * 100.; d = p->armour / p->armour_max * 100.;
@ -521,7 +521,7 @@ static int ai_parmour(lua_State* L) {
static int ai_pshield(lua_State* L) { static int ai_pshield(lua_State* L) {
double d; double d;
Pilot* p; Pilot* p;
if(lua_isnumber(L,1)) { if(lua_isnumber(L,1)) {
p = pilot_get((unsigned int)lua_tonumber(L,1)); p = pilot_get((unsigned int)lua_tonumber(L,1));
d = p->shield / p->shield_max * 100.; d = p->shield / p->shield_max * 100.;
@ -557,22 +557,22 @@ static int ai_getpos(lua_State* L) {
// ======================================================== // ========================================================
// Get the minimum braking distance. // Get the minimum braking distance.
// //
// Braking vel ==> 0 = v - a*dt // Braking vel ==> 0 = v - a*dt
// Add turn around time (to initial velocity) : // Add turn around time (to initial velocity) :
// ==> 180.*360./cur_pilot->turn // ==> 180.*360./cur_pilot->turn
// Add it to general euler equation x = v*t + 0.5 * a * t^2 // Add it to general euler equation x = v*t + 0.5 * a * t^2
// Have fun. // Have fun.
// //
// I really hate this function. Why isn't it depricated yet? // I really hate this function. Why isn't it depricated yet?
// ======================================================== // ========================================================
static int ai_minbrakedist(lua_State* L) { static int ai_minbrakedist(lua_State* L) {
double time, dist; double time, dist;
time = VMOD(cur_pilot->solid->vel) / time = VMOD(cur_pilot->solid->vel) /
(cur_pilot->thrust / cur_pilot->solid->mass); (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; 0.5 * (cur_pilot->thrust / cur_pilot->solid->mass)*time*time;
lua_pushnumber(L, dist); // return lua_pushnumber(L, dist); // return
return 1; return 1;
@ -585,7 +585,7 @@ static int ai_cargofree(lua_State* L) {
static int ai_exists(lua_State* L) { static int ai_exists(lua_State* L) {
MIN_ARGS(1); MIN_ARGS(1);
if(lua_isnumber(L,1)) { if(lua_isnumber(L,1)) {
lua_pushboolean(L, (pilot_get((unsigned int)lua_tonumber(L,1)) != NULL)?1:0); lua_pushboolean(L, (pilot_get((unsigned int)lua_tonumber(L,1)) != NULL)?1:0);
return 1; return 1;
@ -609,14 +609,14 @@ static int ai_isstopped(lua_State* L) {
static int ai_isenemy(lua_State* L) { static int ai_isenemy(lua_State* L) {
if(lua_isnumber(L,1)) if(lua_isnumber(L,1))
lua_pushboolean(L, areEnemies(cur_pilot->faction, lua_pushboolean(L, areEnemies(cur_pilot->faction,
pilot_get(lua_tonumber(L,1))->faction)); pilot_get(lua_tonumber(L,1))->faction));
return 1; return 1;
} }
// Check if the pilot is an ally. // Check if the pilot is an ally.
static int ai_isally(lua_State* L) { static int ai_isally(lua_State* L) {
lua_pushboolean(L, areAllies(cur_pilot->faction, lua_pushboolean(L, areAllies(cur_pilot->faction,
pilot_get(lua_tonumber(L,1))->faction)); pilot_get(lua_tonumber(L,1))->faction));
return 1; return 1;
} }
@ -653,15 +653,15 @@ static int ai_face(lua_State* L) {
double mod, diff; double mod, diff;
int invert = 0; int invert = 0;
int n = -2; int n = -2;
if(lua_isnumber(L, 1)) if(lua_isnumber(L, 1))
n = (int)lua_tonumber(L, 1); n = (int)lua_tonumber(L, 1);
if(n >= 0) { if(n >= 0) {
p = pilot_get(n); p = pilot_get(n);
if(p == NULL) return 0; // Make sure pilot is valid. if(p == NULL) return 0; // Make sure pilot is valid.
vect_cset(&tv, VX(p->solid->pos) + FACE_WVEL*VX(p->solid->vel), vect_cset(&tv, VX(p->solid->pos) + FACE_WVEL*VX(p->solid->vel),
VY(p->solid->pos) + FACE_WVEL*VY(p->solid->vel)); VY(p->solid->pos) + FACE_WVEL*VY(p->solid->vel));
v = NULL; v = NULL;
} }
else if(lua_islightuserdata(L,1)) v = (Vec2*)lua_topointer(L,1); else if(lua_islightuserdata(L,1)) v = (Vec2*)lua_topointer(L,1);
@ -670,19 +670,19 @@ static int ai_face(lua_State* L) {
if(lua_gettop(L) > 1 && lua_isnumber(L,2)) invert = (int)lua_tonumber(L,2); if(lua_gettop(L) > 1 && lua_isnumber(L,2)) invert = (int)lua_tonumber(L,2);
if(invert) mod *= -1; if(invert) mod *= -1;
vect_cset(&sv, VX(cur_pilot->solid->pos) + FACE_WVEL*VX(cur_pilot->solid->vel), 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)); VY(cur_pilot->solid->pos) + FACE_WVEL*VY(cur_pilot->solid->vel));
if(v != NULL) if(v != NULL)
// Target is static. // Target is static.
diff = angle_diff(cur_pilot->solid->dir, diff = angle_diff(cur_pilot->solid->dir,
(n==-1) ? VANGLE(cur_pilot->solid->pos) : (n==-1) ? VANGLE(cur_pilot->solid->pos) :
vect_angle(&cur_pilot->solid->pos, v)); vect_angle(&cur_pilot->solid->pos, v));
else else
// Target is dynamic. // Target is dynamic.
diff = angle_diff(cur_pilot->solid->dir, diff = angle_diff(cur_pilot->solid->dir,
(n==-1) ? VANGLE(sv) : (n==-1) ? VANGLE(sv) :
vect_angle(&sv, &tv)); vect_angle(&sv, &tv));
pilot_turn = mod*diff; pilot_turn = mod*diff;
lua_pushnumber(L, ABS(diff*180./M_PI)); lua_pushnumber(L, ABS(diff*180./M_PI));
@ -712,12 +712,12 @@ static int ai_getnearestplanet(lua_State* L) {
double dist, d; double dist, d;
int i, j; int i, j;
// Cycle through planets. // Cycle through planets.
for(dist = 0., j = -1, i = 0; i < cur_system->nplanets; i++) { for(dist = 0., j = -1, i = 0; i < cur_system->nplanets; i++) {
d = vect_dist(&cur_system->planets[i].pos, &cur_pilot->solid->pos); d = vect_dist(&cur_system->planets[i].pos, &cur_pilot->solid->pos);
if((!areEnemies(cur_pilot->faction, cur_system->planets[i].faction)) && if((!areEnemies(cur_pilot->faction, cur_system->planets[i].faction)) &&
(d < dist)) { (d < dist)) {
// Closer friendly planet. // Closer friendly planet.
j = i; j = i;
dist = d; dist = d;
@ -742,7 +742,7 @@ static int ai_getrndplanet(lua_State* L) {
for(nplanets = 0, i = 0; i < cur_system->nplanets; i++) for(nplanets = 0, i = 0; i < cur_system->nplanets; i++)
if(planet_hasService(&cur_system->planets[i], PLANET_SERVICE_BASIC) && 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]; planets[nplanets++] = &cur_system->planets[i];
// No planet to land on found. // No planet to land on found.
@ -755,7 +755,7 @@ static int ai_getrndplanet(lua_State* L) {
i = RNG(0,nplanets-1); i = RNG(0,nplanets-1);
vectcpy(&v, &planets[i]->pos); vectcpy(&v, &planets[i]->pos);
vect_cadd(&v, RNG(0, planets[i]->gfx_space->sw)-planets[i]->gfx_space->sw/2., 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.); RNG(0, planets[i]->gfx_space->sh)-planets[i]->gfx_space->sh/2.);
lua_pushlightuserdata(L, &v); lua_pushlightuserdata(L, &v);
free(planets); free(planets);
return 1; return 1;
@ -778,7 +778,7 @@ static int ai_stop(lua_State* L) {
if(VMOD(cur_pilot->solid->vel) < MIN_VEL_ERR) if(VMOD(cur_pilot->solid->vel) < MIN_VEL_ERR)
vect_pset(&cur_pilot->solid->vel, 0., 0.); vect_pset(&cur_pilot->solid->vel, 0., 0.);
return 0; return 0;
} }
@ -814,10 +814,10 @@ static int ai_secondary(lua_State* L) {
int i; int i;
for(i = 0; i < cur_pilot->noutfits; i++) { for(i = 0; i < cur_pilot->noutfits; i++) {
if((po == NULL) && (outfit_isWeapon(cur_pilot->outfits[i].outfit) || if((po == NULL) && (outfit_isWeapon(cur_pilot->outfits[i].outfit) ||
outfit_isLauncher(cur_pilot->outfits[i].outfit))) outfit_isLauncher(cur_pilot->outfits[i].outfit)))
po = &cur_pilot->outfits[i]; po = &cur_pilot->outfits[i];
else if((po != NULL) && outfit_isWeapon(po->outfit) && else if((po != NULL) && outfit_isWeapon(po->outfit) &&
outfit_isLauncher(cur_pilot->outfits[i].outfit)) outfit_isLauncher(cur_pilot->outfits[i].outfit))
po = &cur_pilot->outfits[i]; po = &cur_pilot->outfits[i];
} }
if(po) { if(po) {
@ -889,7 +889,7 @@ static int ai_timeup(lua_State* L) {
// Have the pilot say something to player. // Have the pilot say something to player.
static int ai_comm(lua_State* L) { static int ai_comm(lua_State* L) {
MIN_ARGS(2); MIN_ARGS(2);
if(lua_isnumber(L,1) && (lua_tonumber(L,1)==PLAYER_ID) && lua_isstring(L,2)) if(lua_isnumber(L,1) && (lua_tonumber(L,1)==PLAYER_ID) && lua_isstring(L,2))
player_message("Comm: %s> \"%s\"", cur_pilot->name, lua_tostring(L,2)); player_message("Comm: %s> \"%s\"", cur_pilot->name, lua_tostring(L,2));
@ -913,7 +913,7 @@ static int ai_credits(lua_State* L) {
if(lua_isnumber(L,1)) if(lua_isnumber(L,1))
cur_pilot->credits = (int)lua_tonumber(L,1); cur_pilot->credits = (int)lua_tonumber(L,1);
return 0; return 0;
} }
@ -924,7 +924,7 @@ static int ai_cargo(lua_State* L) {
if(lua_isstring(L,1) && lua_isnumber(L,2)) if(lua_isstring(L,1) && lua_isnumber(L,2))
pilot_addCargo(cur_pilot, commodity_get(lua_tostring(L,1)), pilot_addCargo(cur_pilot, commodity_get(lua_tostring(L,1)),
(int)lua_tonumber(L,2)); (int)lua_tonumber(L,2));
return 0; return 0;
} }

View File

@ -16,7 +16,7 @@ typedef enum TaskData_ { TYPE_NULL, TYPE_INT, TYPE_PTR } TaskData;
typedef struct Task_ { typedef struct Task_ {
struct Task_* next; struct Task_* next;
char* name; char* name;
TaskData dtype; TaskData dtype;
union { union {
void* target; // Vec2 etc. void* target; // Vec2 etc.

View File

@ -23,166 +23,166 @@ static void board_update(void);
// Attempt to board the players target. // Attempt to board the players target.
void player_board(void) { void player_board(void) {
Pilot* p; Pilot* p;
if(player_target == PLAYER_ID) { if(player_target == PLAYER_ID) {
player_message("You need a target to board first!"); player_message("You need a target to board first!");
return; return;
} }
p = pilot_get(player_target); p = pilot_get(player_target);
if(!pilot_isDisabled(p)) { if(!pilot_isDisabled(p)) {
player_message("You cannot board a ship that is not disabled!"); player_message("You cannot board a ship that is not disabled!");
return; return;
} }
else if(vect_dist(&player->solid->pos, &p->solid->pos) > else if(vect_dist(&player->solid->pos, &p->solid->pos) >
p->ship->gfx_space->sw * PILOT_SIZE_APROX) { p->ship->gfx_space->sw * PILOT_SIZE_APROX) {
player_message("You are too far away to board your target"); player_message("You are too far away to board your target");
return; return;
} }
else if((pow2(VX(player->solid->vel)-VX(p->solid->vel)) + else if((pow2(VX(player->solid->vel)-VX(p->solid->vel)) +
pow2(VY(player->solid->vel)-VY(p->solid->vel))) > pow2(VY(player->solid->vel)-VY(p->solid->vel))) >
(double)pow2(MAX_HYPERSPACE_VEL)) { (double)pow2(MAX_HYPERSPACE_VEL)) {
player_message("You are going too fast to board the ship"); player_message("You are going too fast to board the ship");
return; return;
} }
else if(pilot_isFlag(p, PILOT_BOARDED)) { else if(pilot_isFlag(p, PILOT_BOARDED)) {
player_message("Your target cannot be boarded again"); player_message("Your target cannot be boarded again");
return; return;
} }
// Pilot will be boarded.
pilot_setFlag(p, PILOT_BOARDED);
player_message("Boarding ship %s", p->name);
// Create the boarding window. // Pilot will be boarded.
board_wid = window_create("Boarding", -1, -1, BOARDING_WIDTH, BOARDING_HEIGHT); pilot_setFlag(p, PILOT_BOARDED);
player_message("Boarding ship %s", p->name);
window_addText(board_wid, 20, -30, 120, 60, // Create the boarding window.
0, "txtCargo", &gl_smallFont, &cDConsole, board_wid = window_create("Boarding", -1, -1, BOARDING_WIDTH, BOARDING_HEIGHT);
"SCreds:\n"
"Cargo:\n");
window_addText(board_wid, 80, -30, 120, 60, 0, "txtData",
&gl_smallFont, &cBlack, NULL);
window_addButton(board_wid, 20, 20, 50, 30, "btnStealCredits", window_addText(board_wid, 20, -30, 120, 60,
"Credits", board_stealCreds); 0, "txtCargo", &gl_smallFont, &cDConsole,
"SCreds:\n"
"Cargo:\n");
window_addButton(board_wid, 90, 20, 50, 30, "btnStealCargo", window_addText(board_wid, 80, -30, 120, 60, 0, "txtData",
"Cargo", board_stealCargo); &gl_smallFont, &cBlack, NULL);
window_addButton(board_wid, -20, 20, 50, 30, "btnBoardingClose", window_addButton(board_wid, 20, 20, 50, 30, "btnStealCredits",
"Leave", board_exit); "Credits", board_stealCreds);
board_update(); window_addButton(board_wid, 90, 20, 50, 30, "btnStealCargo",
"Cargo", board_stealCargo);
window_addButton(board_wid, -20, 20, 50, 30, "btnBoardingClose",
"Leave", board_exit);
board_update();
} }
static void board_exit(char* str) { static void board_exit(char* str) {
(void)str; (void)str;
window_destroy(window_get("Boarding")); window_destroy(window_get("Boarding"));
} }
static void board_stealCreds(char* str) { static void board_stealCreds(char* str) {
(void)str; (void)str;
Pilot* p; Pilot* p;
p = pilot_get(player_target); p = pilot_get(player_target);
if(p->credits == 0) { if(p->credits == 0) {
// Can't steal from the poor. ;) // Can't steal from the poor. ;)
player_message("The ship has no SCreds."); player_message("The ship has no SCreds.");
return; return;
} }
if(board_fail()) return; if(board_fail()) return;
player_credits += p->credits; player_credits += p->credits;
p->credits = 0; p->credits = 0;
board_update(); // Update the lack of credits. board_update(); // Update the lack of credits.
player_message("You manage to steal the ship's Scred."); player_message("You manage to steal the ship's Scred.");
} }
static void board_stealCargo(char* str) { static void board_stealCargo(char* str) {
(void)str; (void)str;
int q; int q;
Pilot* p; Pilot* p;
p = pilot_get(player_target); p = pilot_get(player_target);
if(p->ncommodities==0) { if(p->ncommodities==0) {
// No cargo. // No cargo.
player_message("The ship has no cargo."); player_message("The ship has no cargo.");
return; return;
} }
else if(player->cargo_free <= 0) { else if(player->cargo_free <= 0) {
player_message("You have no room for cargo."); player_message("You have no room for cargo.");
return; return;
} }
if(board_fail()) return; if(board_fail()) return;
// Steal as much as possible until full - TODO: Allow the player to choose. // Steal as much as possible until full - TODO: Allow the player to choose.
q = 1; q = 1;
while((p->ncommodities > 0) && (q != 0)) { while((p->ncommodities > 0) && (q != 0)) {
q = pilot_addCargo(player, p->commodities[0].commodity, q = pilot_addCargo(player, p->commodities[0].commodity,
p->commodities[0].quantity); p->commodities[0].quantity);
pilot_rmCargo(p, p->commodities[0].commodity, q); pilot_rmCargo(p, p->commodities[0].commodity, q);
} }
board_update(); board_update();
player_message("You manage to steal the ship's cargo."); player_message("You manage to steal the ship's cargo.");
} }
// Failed to board. // Failed to board.
static int board_fail(void) { static int board_fail(void) {
Pilot* p; Pilot* p;
p = pilot_get(player_target); p = pilot_get(player_target);
// Fail chance. // Fail chance.
if(RNG(0, 100) > (int)(50. * if(RNG(0, 100) > (int)(50. *
(10. + (double)p->ship->crew/10.+(double)player->ship->crew))) (10. + (double)p->ship->crew/10.+(double)player->ship->crew)))
return 0; return 0;
if(RNG(0, 2)==0) { if(RNG(0, 2)==0) {
// 33% of instant death. // 33% of instant death.
p->armour = -1; p->armour = -1;
player_message("You have tripped the ship's self destruct mechanism!"); player_message("You have tripped the ship's self destruct mechanism!");
} else } else
// You just got locked out!! // You just got locked out!!
player_message("The ship's security system locks you out!"); player_message("The ship's security system locks you out!");
board_exit(NULL); board_exit(NULL);
return 1; return 1;
} }
// Update the cargo and credit fields. // Update the cargo and credit fields.
static void board_update(void) { static void board_update(void) {
int i; int i;
char str[128], buf[32]; char str[128], buf[32];
char cred[10]; char cred[10];
Pilot* p; 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, snprintf(str, 11,
"%s\n", cred); "%s\n", cred);
if(p->ncommodities == 0) if(p->ncommodities == 0)
strncat(str, "none", 10); strncat(str, "none", 10);
else { else {
for(i = 0; i < p->ncommodities; i++) { for(i = 0; i < p->ncommodities; i++) {
snprintf(buf, 32, snprintf(buf, 32,
"%d %s\n", "%d %s\n",
p->commodities[i].quantity, p->commodities[i].commodity->name); p->commodities[i].quantity, p->commodities[i].commodity->name);
strncat(str, buf, 32); 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. // bsy - Position of y of sprite b.
// bp - Position in space of sprite b. // bp - Position in space of sprite b.
int CollideSprite(const glTexture* at, const int asx, const int asy, int CollideSprite(const glTexture* at, const int asx, const int asy,
const Vec2* ap, const glTexture* bt, const Vec2* ap, const glTexture* bt,
const int bsx, const int bsy, const Vec2* bp) { const int bsx, const int bsy, const Vec2* bp) {
int x,y; int x,y;
int ax1, ax2, ay1, ay2; int ax1, ax2, ay1, ay2;
int bx1, bx2, by1, by2; int bx1, bx2, by1, by2;
int inter_x0, inter_x1, inter_y0, inter_y1; int inter_x0, inter_x1, inter_y0, inter_y1;
int rasy, rbsy; int rasy, rbsy;
int abx, aby, bbx, bby; int abx, aby, bbx, bby;
// a - cube coords. // a - cube coords.
ax1 = (int)VX(*ap) - (int)(at->sw)/2; ax1 = (int)VX(*ap) - (int)(at->sw)/2;
@ -34,7 +34,7 @@ int CollideSprite(const glTexture* at, const int asx, const int asy,
by1 = (int)VY(*bp) - (int)(bt->sh)/2; by1 = (int)VY(*bp) - (int)(bt->sh)/2;
bx2 = bx1 + (int)(bt->sw) - 1; bx2 = bx1 + (int)(bt->sw) - 1;
by2 = by1 + (int)(bt->sh) - 1; by2 = by1 + (int)(bt->sh) - 1;
// Check if bounding boxes intersect. // Check if bounding boxes intersect.
if((bx2 < ax1) || (ax2 < bx1)) return 0; if((bx2 < ax1) || (ax2 < bx1)) return 0;
if((by2 < ay1) || (ay2 < by1)) return 0; if((by2 < ay1) || (ay2 < by1)) return 0;
@ -44,7 +44,7 @@ int CollideSprite(const glTexture* at, const int asx, const int asy,
inter_x1 = MIN(ax2, bx2); inter_x1 = MIN(ax2, bx2);
inter_y0 = MAX(ay1, by1); inter_y0 = MAX(ay1, by1);
inter_y1 = MIN(ay2, by2); inter_y1 = MIN(ay2, by2);
// Real vertical sprite value (flipped). // Real vertical sprite value (flipped).
rasy = at->sy - asy - 1; rasy = at->sy - asy - 1;
rbsy = bt->sy - bsy - 1; rbsy = bt->sy - bsy - 1;
@ -59,7 +59,7 @@ int CollideSprite(const glTexture* at, const int asx, const int asy,
for(x = inter_x0; x <= inter_x1; x++) for(x = inter_x0; x <= inter_x1; x++)
// Compute offsets for surface before passing to TransparentPixel test. // Compute offsets for surface before passing to TransparentPixel test.
if((!gl_isTrans(at, abx + x, aby + y)) && if((!gl_isTrans(at, abx + x, aby + y)) &&
(!gl_isTrans(bt, bbx + x, bby + y))) (!gl_isTrans(bt, bbx + x, bby + y)))
return 1; return 1;
return 0; return 0;

View File

@ -3,6 +3,6 @@
#include "physics.h" #include "physics.h"
int CollideSprite(const glTexture* at, const int asx, const int asy, int CollideSprite(const glTexture* at, const int asx, const int asy,
const Vec2* ap, const glTexture* bt, const Vec2* ap, const glTexture* bt,
const int bsx, const int bsy, const Vec2* bp); const int bsx, const int bsy, const Vec2* bp);

View File

@ -15,33 +15,33 @@
#include "conf.h" #include "conf.h"
#define conf_loadInt(n,i) \ #define conf_loadInt(n,i) \
lua_getglobal(L,n); \ lua_getglobal(L,n); \
if(lua_isnumber(L, -1)) { \ if(lua_isnumber(L, -1)) { \
i = (int)lua_tonumber(L, -1); \ i = (int)lua_tonumber(L, -1); \
lua_remove(L, -1); \ lua_remove(L, -1); \
} }
#define conf_loadFloat(n,f) \ #define conf_loadFloat(n,f) \
lua_getglobal(L,n); \ lua_getglobal(L,n); \
if(lua_isnumber(L, -1)) { \ if(lua_isnumber(L, -1)) { \
f = (double)lua_tonumber(L, -1); \ f = (double)lua_tonumber(L, -1); \
lua_remove(L,-1);\ lua_remove(L,-1);\
} }
#define conf_loadBool(n,b) \ #define conf_loadBool(n,b) \
lua_getglobal(L,n); \ lua_getglobal(L,n); \
if(lua_isnumber(L, -1)) \ if(lua_isnumber(L, -1)) \
if((int)lua_tonumber(L, -1) == 1) { \ if((int)lua_tonumber(L, -1) == 1) { \
b = 1; \ b = 1; \
lua_remove(L, -1); \ lua_remove(L, -1); \
} \ } \
#define conf_loadString(n,s) \ #define conf_loadString(n,s) \
lua_getglobal(L,n); \ lua_getglobal(L,n); \
if(lua_isstring(L, -1)) { \ if(lua_isstring(L, -1)) { \
s = strdup((char*)lua_tostring(L, -1)); \ s = strdup((char*)lua_tostring(L, -1)); \
lua_remove(L, -1); \ lua_remove(L, -1); \
} }
// Some crap from main. // Some crap from main.
extern int nosound; extern int nosound;
@ -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-d s, --data s - Set the data file to be s");
LOG("\t-j n, --joystick n - Use joystick (n)"); LOG("\t-j n, --joystick n - Use joystick (n)");
LOG("\t-J s, --joystick s - Use joystick whose name contains (s)"); 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-m f, --music f - Set the music volume to f");
LOG("\t-s f, --sound f - Set the sound 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-h --help - Display this message and exit.");
LOG("\t-v - Print the version and exit"); LOG("\t-v - Print the version and exit");
} }
@ -89,7 +89,7 @@ void conf_setDefaults(void) {
// Ok.. Parse a config file plox. // Ok.. Parse a config file plox.
int conf_loadConfig(const char* file) { int conf_loadConfig(const char* file) {
int i = 0; int i = 0;
double d = 0.; double d = 0.;
lua_State* L = luaL_newstate(); lua_State* L = luaL_newstate();
if(luaL_dofile(L, file) == 0) { if(luaL_dofile(L, file) == 0) {
@ -104,28 +104,28 @@ int conf_loadConfig(const char* file) {
if(i) { gl_screen.flags |= OPENGL_FULLSCREEN; i = 0; } if(i) { gl_screen.flags |= OPENGL_FULLSCREEN; i = 0; }
conf_loadBool("aa", i); conf_loadBool("aa", i);
if(i) { if(i) {
gl_screen.flags |= OPENGL_AA_POINT | OPENGL_AA_LINE || OPENGL_AA_POLYGON; gl_screen.flags |= OPENGL_AA_POINT | OPENGL_AA_LINE || OPENGL_AA_POLYGON;
i = 0; i = 0;
} }
conf_loadBool("aa_point", i); conf_loadBool("aa_point", i);
if(i) { gl_screen.flags |= OPENGL_AA_POINT; i = 0; } if(i) { gl_screen.flags |= OPENGL_AA_POINT; i = 0; }
conf_loadBool("aa_line", i) conf_loadBool("aa_line", i)
if(i) { gl_screen.flags |= OPENGL_AA_LINE; i = 0; } if(i) { gl_screen.flags |= OPENGL_AA_LINE; i = 0; }
conf_loadBool("aa_polygon", i); conf_loadBool("aa_polygon", i);
if(i) { gl_screen.flags |= OPENGL_AA_POLYGON; i = 0; } if(i) { gl_screen.flags |= OPENGL_AA_POLYGON; i = 0; }
// FPS. // FPS.
conf_loadBool("showfps", show_fps); conf_loadBool("showfps", show_fps);
conf_loadInt("maxfps", max_fps); conf_loadInt("maxfps", max_fps);
// Input. // Input.
conf_loadInt("afterburn", input_afterburnSensibility); conf_loadInt("afterburn", input_afterburnSensibility);
// Sound. // Sound.
conf_loadFloat("sound", d); conf_loadFloat("sound", d);
if(d) { sound_volume(d); d = 0.; } if(d) { sound_volume(d); d = 0.; }
conf_loadFloat("music", d); conf_loadFloat("music", d);
if(d) { music_volume(d); d = 0.; } if(d) { music_volume(d); d = 0.; }
// Joystick. // Joystick.
lua_getglobal(L, "joystick"); lua_getglobal(L, "joystick");
@ -205,8 +205,8 @@ void conf_parseCLI(int argc, char** argv) {
{ "data", required_argument, 0, 'd' }, { "data", required_argument, 0, 'd' },
{ "joystick", required_argument, 0, 'j' }, { "joystick", required_argument, 0, 'j' },
{ "Joystick", required_argument, 0, 'J' }, { "Joystick", required_argument, 0, 'J' },
{ "music", required_argument, 0, 'm' }, { "music", required_argument, 0, 'm' },
{ "sound", required_argument, 0, 's' }, { "sound", required_argument, 0, 's' },
{ "help", no_argument, 0, 'h' }, { "help", no_argument, 0, 'h' },
{ "version", no_argument, 0, 'v' }, { "version", no_argument, 0, 'v' },
{ NULL, 0, 0, 0 } { NULL, 0, 0, 0 }
@ -215,34 +215,34 @@ void conf_parseCLI(int argc, char** argv) {
int c = 0; int c = 0;
while((c = getopt_long(argc, argv, "fF:d:J:j:s:m:V:hv", 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) { switch(c) {
case 'f': case 'f':
gl_screen.flags |= OPENGL_FULLSCREEN; gl_screen.flags |= OPENGL_FULLSCREEN;
break; break;
case 'F': case 'F':
max_fps = atoi(optarg); max_fps = atoi(optarg);
break; break;
case 'd': case 'd':
data = strdup(optarg); data = strdup(optarg);
break; break;
case 'j': case 'j':
indjoystick = atoi(optarg); indjoystick = atoi(optarg);
break; break;
case 'J': case 'J':
namjoystick = strdup(optarg); namjoystick = strdup(optarg);
break; break;
case 'm': case 'm':
music_volume(atof(optarg)); music_volume(atof(optarg));
break; break;
case 's': case 's':
sound_volume(atof(optarg)); sound_volume(atof(optarg));
break; break;
case 'v': case 'v':
LOG(APPNAME": version %d.%d.%d", VMAJOR, VMINOR, VREV); LOG(APPNAME": version %d.%d.%d", VMAJOR, VMINOR, VREV);
case 'h': case 'h':
print_usage(argv); print_usage(argv);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
} }
} }

View File

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

View File

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

View File

@ -41,7 +41,7 @@ Faction* faction_get(const char* name) {
for(i = 0; i < nfactions; i++) for(i = 0; i < nfactions; i++)
if(strcmp(faction_stack[i].name, name)==0) if(strcmp(faction_stack[i].name, name)==0)
break; break;
if(i != nfactions) if(i != nfactions)
return faction_stack+i; return faction_stack+i;
@ -64,9 +64,9 @@ static Alliance* alliance_get(char* name) {
// Return 1 if Faction a and b are enemies. // Return 1 if Faction a and b are enemies.
int areEnemies(Faction* a, Faction* b) { int areEnemies(Faction* a, Faction* b) {
int i = 0; int i = 0;
if(a == b) return 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++) for(i = 0; i < a->nenemies; i++)
if(a->enemies[i] == b) if(a->enemies[i] == b)
@ -83,7 +83,7 @@ int areAllies(Faction* a, Faction* b) {
int i = 0; int i = 0;
if(a == b) return 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++) for(i = 0; i < a->nallies; i++)
if(a->allies[i] == b) if(a->allies[i] == b)
@ -115,13 +115,13 @@ static void alliance_parse(xmlNodePtr parent) {
do { do {
if((node->type == XML_NODE_START) && (strcmp((char*)node->name, if((node->type == XML_NODE_START) && (strcmp((char*)node->name,
XML_ALLIANCE_TAG)==0)) { XML_ALLIANCE_TAG)==0)) {
// Allocate a new alliance. // Allocate a new alliance.
alliances = realloc(alliances, sizeof(Alliance)*(++nalliances)); alliances = realloc(alliances, sizeof(Alliance)*(++nalliances));
alliances[nalliances-1].name = (char*)xmlGetProp(node,(xmlChar*)"name"); alliances[nalliances-1].name = (char*)xmlGetProp(node,(xmlChar*)"name");
alliances[nalliances-1].factions = NULL; alliances[nalliances-1].factions = NULL;
alliances[nalliances-1].nfactions = 0; alliances[nalliances-1].nfactions = 0;
// Parse the current alliance's allies. // Parse the current alliance's allies.
cur = node->xmlChildrenNode; cur = node->xmlChildrenNode;
do { do {
@ -137,24 +137,24 @@ static void alliance_parse(xmlNodePtr parent) {
if(a->factions[(*i)-1] == NULL) if(a->factions[(*i)-1] == NULL)
WARN("Faction %s in alliance %s does not exist in "FACTION_DATA, WARN("Faction %s in alliance %s does not exist in "FACTION_DATA,
(char*)cur->children->content, a->name); (char*)cur->children->content, a->name);
} }
} while((cur = cur->next)); } while((cur = cur->next));
// Set the crap needed by faction_stack. // Set the crap needed by faction_stack.
for(j = 0; j < (*i); j++) { for(j = 0; j < (*i); j++) {
a->factions[j]->nallies += (*i)-1; a->factions[j]->nallies += (*i)-1;
a->factions[j]->allies = realloc(a->factions[j]->allies, a->factions[j]->allies = realloc(a->factions[j]->allies,
a->factions[j]->nallies*sizeof(Faction*)); a->factions[j]->nallies*sizeof(Faction*));
for(n = 0, m = 0; n < (*i); n++, m++) { for(n = 0, m = 0; n < (*i); n++, m++) {
// Add as ally for all factions exept self. // Add as ally for all factions exept self.
if(n == j) m--; if(n == j) m--;
else if(n != j) else if(n != j)
a->factions[j]->allies[a->factions[j]->nallies-(*i)+1+m] = a->factions[j]->allies[a->factions[j]->nallies-(*i)+1+m] =
a->factions[n]; a->factions[n];
}
} }
} }
}
} while((node = node->next)); } while((node = node->next));
} }
@ -164,12 +164,12 @@ static void enemies_parse(xmlNodePtr parent) {
Alliance* a; Alliance* a;
int i, *j, n, m, x, y, z, e; int i, *j, n, m, x, y, z, e;
char* type; char* type;
node = parent->xmlChildrenNode; node = parent->xmlChildrenNode;
do { do {
if((node->type == XML_NODE_START) if((node->type == XML_NODE_START)
&& (strcmp((char*)node->name, XML_ENEMIES_TAG)==0)) { && (strcmp((char*)node->name, XML_ENEMIES_TAG)==0)) {
i = 0; i = 0;
f = NULL; f = NULL;
j = NULL; j = NULL;
@ -188,7 +188,7 @@ static void enemies_parse(xmlNodePtr parent) {
a = alliance_get((char*)cur->children->content); a = alliance_get((char*)cur->children->content);
if(a == NULL) if(a == NULL)
WARN("Alliance %s not found in stack", WARN("Alliance %s not found in stack",
(char*)cur->children->content); (char*)cur->children->content);
j[i-1] = a->nfactions; j[i-1] = a->nfactions;
f[i-1] = a->factions; f[i-1] = a->factions;
} }
@ -199,35 +199,35 @@ static void enemies_parse(xmlNodePtr parent) {
f[i-1][0] = faction_get((char*)cur->children->content); f[i-1][0] = faction_get((char*)cur->children->content);
if(f[i-1][0] == NULL) if(f[i-1][0] == NULL)
WARN("Faction %s not found in stack", WARN("Faction %s not found in stack",
(char*)cur->children->content); (char*)cur->children->content);
} }
free(type); free(type);
} }
} while((cur = cur->next)); } while((cur = cur->next));
// Now actually parse and load up the enemies. // Now actually parse and load up the enemies.
for(n = 0; n < i; n++) { for(n = 0; n < i; n++) {
for(m = 0; m < j[n]; m++) { for(m = 0; m < j[n]; m++) {
// Faction. // Faction.
// Add all the faction enemies to nenemies and alloc. // Add all the faction enemies to nenemies and alloc.
for(e = 0, x = 0; x < i; x++) for(e = 0, x = 0; x < i; x++)
if(x != n) e += j[x]; // Store the total enemies. if(x != n) e += j[x]; // Store the total enemies.
// Now allocate the memory. // Now allocate the memory.
f[n][m]->nenemies += e; f[n][m]->nenemies += e;
f[n][m]->enemies = realloc(f[n][m]->enemies, 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. // Add the actualy enemies.
for(x = 0, z = 0; x < i; x++) for(x = 0, z = 0; x < i; x++)
if(x != n)
// Make sure it's not from the same group.
if(x != n) if(x != n)
// Make sure it's not from the same group. for(y = 0; y < j[x]; y++, z++)
if(x != n) f[n][m]->enemies[f[n][m]->nenemies-e+z]=f[x][y];
for(y = 0; y < j[x]; y++, z++)
f[n][m]->enemies[f[n][m]->nenemies-e+z]=f[x][y];
}
} }
// Free al the temp memory. }
for(x = 0; x < i; x++) // Free al the temp memory.
if(j[x]==1) free(f[x]); // Free the single malloced factions. for(x = 0; x < i; x++)
if(j[x]==1) free(f[x]); // Free the single malloced factions.
free(f); // Free the rest. free(f); // Free the rest.
free(j); free(j);
} }

View File

@ -11,7 +11,7 @@
#define FONT_DEF "../dat/font.ttf" #define FONT_DEF "../dat/font.ttf"
// == Font render routines.================================ // == Font render routines.================================
// Use a display list to store ASCII chars rendered with // Use a display list to store ASCII chars rendered with
// freefont. There are several drawing methods depending // freefont. There are several drawing methods depending
// on whether you want to print it all, to a max width, // on whether you want to print it all, to a max width,
// print centered or print a block of text. // print centered or print a block of text.
@ -27,7 +27,8 @@ glFont gl_defFont;
glFont gl_smallFont; glFont gl_smallFont;
static void glFontMakeDList(FT_Face face, char ch, static void glFontMakeDList(FT_Face face, char ch,
GLuint list_base, GLuint* tex_base, int* width_base); GLuint list_base, GLuint* tex_base,
int* width_base);
static int pot(int n); static int pot(int n);
@ -42,7 +43,7 @@ static int pot(int n) {
// Print text on screen! YES!!!! Just like printf! But different! // Print text on screen! YES!!!! Just like printf! But different!
// Defaults ft_font to gl_defFont if NULL. // Defaults ft_font to gl_defFont if NULL.
void gl_print(const glFont* ft_font, const double x, const double y, void gl_print(const glFont* ft_font, const double x, const double y,
const glColour* c, const char* fmt, ...) { const glColour* c, const char* fmt, ...) {
//float h = ft_font->h / .63; // Slightly increases font size. //float h = ft_font->h / .63; // Slightly increases font size.
char txt[256]; char txt[256];
va_list ap; va_list ap;
@ -75,8 +76,8 @@ 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. // Acts just like gl_print, but prints to a max length of max.
// Return the amount of characters we had to suppress. // Return the amount of characters we had to suppress.
int gl_printMax(const glFont* ft_font, const int max, 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. //float h = ft_font->h / .63; // Slightly increases font size.
char txt[256]; char txt[256];
va_list ap; va_list ap;
@ -91,7 +92,7 @@ int gl_printMax(const glFont* ft_font, const int max,
vsprintf(txt, fmt, ap); vsprintf(txt, fmt, ap);
va_end(ap); va_end(ap);
} }
// Limit the size. // Limit the size.
len = (int)strlen(txt); len = (int)strlen(txt);
for(n = 0, i = 0; i < len; i++) { for(n = 0, i = 0; i < len; i++) {
@ -124,12 +125,12 @@ int gl_printMax(const glFont* ft_font, const int max,
// Acts just like gl_printMax, but centers the text in the width. // Acts just like gl_printMax, but centers the text in the width.
int gl_printMid(const glFont* ft_font, const int width, double x, const double y, int gl_printMid(const glFont* ft_font, const int width, double x, const double y,
const glColour* c, const char* fmt, ...) { const glColour* c, const char* fmt, ...) {
//float h = ft_font->h / .63; // Slightly increases font size. //float h = ft_font->h / .63; // Slightly increases font size.
char txt[256]; char txt[256];
va_list ap; va_list ap;
int i, n, len, ret; int i, n, len, ret;
ret = 0; // Default return value. ret = 0; // Default return value.
if(ft_font == NULL) ft_font = &gl_defFont; if(ft_font == NULL) ft_font = &gl_defFont;
@ -141,7 +142,7 @@ int gl_printMid(const glFont* ft_font, const int width, double x, const double y
vsprintf(txt, fmt, ap); vsprintf(txt, fmt, ap);
va_end(ap); va_end(ap);
} }
// Limit the size. // Limit the size.
len = (int)strlen(txt); len = (int)strlen(txt);
for(n = 0, i = 0; i < len; i++) { for(n = 0, i = 0; i < len; i++) {
@ -177,7 +178,7 @@ int gl_printMid(const glFont* ft_font, const int width, double x, const double y
// Print text with line breaks included to a max width and height precet. // Print text with line breaks included to a max width and height precet.
int gl_printText(const glFont* ft_font, const int width, const int height, int gl_printText(const glFont* ft_font, const int width, const int height,
double bx, double by, glColour* c, const char* fmt, ...) { double bx, double by, glColour* c, const char* fmt, ...) {
//float h = ft_font->h / .63; // Slightly increase font size. //float h = ft_font->h / .63; // Slightly increase font size.
char txt[1024]; char txt[1024];
@ -185,7 +186,7 @@ int gl_printText(const glFont* ft_font, const int width, const int height,
va_list ap; va_list ap;
int p, i, j, n, len, ret, lastspace; int p, i, j, n, len, ret, lastspace;
double x, y; double x, y;
ret = 0; // Default return value. ret = 0; // Default return value.
if(ft_font == NULL) ft_font = &gl_defFont; if(ft_font == NULL) ft_font = &gl_defFont;
@ -230,7 +231,7 @@ int gl_printText(const glFont* ft_font, const int width, const int height,
glMatrixMode(GL_MODELVIEW); // using modelview, projection gets full fast. glMatrixMode(GL_MODELVIEW); // using modelview, projection gets full fast.
glPushMatrix(); // Translation matrix. glPushMatrix(); // Translation matrix.
glTranslated(x, y, 0); glTranslated(x, y, 0);
// This is what we are displaying. // This is what we are displaying.
glCallLists(lastspace-p-1, GL_UNSIGNED_BYTE, &buf); glCallLists(lastspace-p-1, GL_UNSIGNED_BYTE, &buf);
glPopMatrix(); // Translation matrix. glPopMatrix(); // Translation matrix.
@ -272,8 +273,8 @@ int gl_printWidth(const glFont* ft_font, const char* fmt, ...) {
// ================ // ================
// FONT! // FONT!
// ================ // ================
static void glFontMakeDList(FT_Face face, char ch, GLuint list_base, 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_Glyph glyph;
FT_Bitmap bitmap; FT_Bitmap bitmap;
GLubyte* expanded_data; GLubyte* expanded_data;
@ -303,16 +304,16 @@ static void glFontMakeDList(FT_Face face, char ch, GLuint list_base,
for(j = 0; j < h; j++) { for(j = 0; j < h; j++) {
for(i = 0; i < w; i++) { for(i = 0; i < w; i++) {
expanded_data[2*(i+j*w)] = expanded_data[2*(i+j*w)+1] = expanded_data[2*(i+j*w)] = expanded_data[2*(i+j*w)+1] =
(i >= bitmap.width || j >= bitmap.rows) ? (i >= bitmap.width || j >= bitmap.rows) ?
0 : bitmap.buffer[i + bitmap.width*j]; 0 : bitmap.buffer[i + bitmap.width*j];
} }
} }
// Create the GL texture. // Create the GL texture.
glBindTexture(GL_TEXTURE_2D, tex_base[(int)ch]); glBindTexture(GL_TEXTURE_2D, tex_base[(int)ch]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_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, 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. free(expanded_data); // No need for this now.
@ -331,14 +332,14 @@ static void glFontMakeDList(FT_Face face, char ch, GLuint list_base,
// Draw the texture mapped quad. // Draw the texture mapped quad.
glBindTexture(GL_TEXTURE_2D, tex_base[(int)ch]); glBindTexture(GL_TEXTURE_2D, tex_base[(int)ch]);
glBegin(GL_QUADS); glBegin(GL_QUADS);
glTexCoord2d(0, 0); glTexCoord2d(0, 0);
glVertex2d(0, bitmap.rows); glVertex2d(0, bitmap.rows);
glTexCoord2d(x, 0); glTexCoord2d(x, 0);
glVertex2d(bitmap.width, bitmap.rows); glVertex2d(bitmap.width, bitmap.rows);
glTexCoord2d(x, y); glTexCoord2d(x, y);
glVertex2d(bitmap.width, 0); glVertex2d(bitmap.width, 0);
glTexCoord2d(0, y); glTexCoord2d(0, y);
glVertex2d(0, 0); glVertex2d(0, 0);
glEnd(); glEnd();
glPopMatrix(); glPopMatrix();
@ -353,7 +354,7 @@ static void glFontMakeDList(FT_Face face, char ch, GLuint list_base,
void gl_fontInit(glFont* font, const char* fname, const unsigned int h) { void gl_fontInit(glFont* font, const char* fname, const unsigned int h) {
if(font == NULL) font = &gl_defFont; if(font == NULL) font = &gl_defFont;
uint32_t bufsize; uint32_t bufsize;
FT_Byte* buf = pack_readfile(DATA, (fname) ? fname : FONT_DEF, &bufsize); FT_Byte* buf = pack_readfile(DATA, (fname) ? fname : FONT_DEF, &bufsize);

View File

@ -19,19 +19,19 @@ void gl_freeFont(glFont* font);
// Print text. // Print text.
void gl_print(const glFont* ft_font, const double x, const double y, void gl_print(const glFont* ft_font, const double x, const double y,
const glColour* c, const char* fmt, ...); const glColour* c, const char* fmt, ...);
// Print text to a max length. // Print text to a max length.
int gl_printMax(const glFont* ft_font, const int max, 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. // Print text centered in width at x.
int gl_printMid(const glFont* ft_font, const int width, 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. // Respects \n -> bx, by is top left position.
int gl_printText(const glFont* ft_font, const int width, const int height, int gl_printText(const glFont* ft_font, const int width, const int height,
double bx, double by, glColour* c, const char* fmt, ...); double bx, double by, glColour* c, const char* fmt, ...);
// Get the width of the text that you wish to print. // Get the width of the text that you wish to print.
int gl_printWidth(const glFont* ft_font, const char* fmt, ...); int gl_printWidth(const glFont* ft_font, const char* fmt, ...);

View File

@ -24,12 +24,12 @@ static Keybind** input_keybinds; // Contains the players keybindings.
// Name of each keybinding. // Name of each keybinding.
const char* keybindNames[] = { const char* keybindNames[] = {
"accel", "left", "right", "reverse", // Movement. "accel", "left", "right", "reverse", // Movement.
"primary", "target", "target_nearest", "face", "board", // Combat. "primary", "target", "target_nearest", "face", "board", // Combat.
"secondary", "secondary_next", // Secondary weapons. "secondary", "secondary_next", // Secondary weapons.
"target_planet", "land", "thyperspace","starmap", "jump", // Navigation. "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. "end" }; // Must terminate at the end.
// Accel hacks. // Accel hacks.
static unsigned int input_accelLast = 0; // Used to see if double tap. static unsigned int input_accelLast = 0; // Used to see if double tap.
@ -57,22 +57,22 @@ void input_setDefault(void) {
input_setKeybind("face", KEYBIND_KEYBOARD, SDLK_f, 0); input_setKeybind("face", KEYBIND_KEYBOARD, SDLK_f, 0);
input_setKeybind("board", KEYBIND_KEYBOARD, SDLK_b, 0); input_setKeybind("board", KEYBIND_KEYBOARD, SDLK_b, 0);
// Secondary weapon. // 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); input_setKeybind("secondary_next", KEYBIND_KEYBOARD, SDLK_e, 0);
// Space // Space
input_setKeybind("target_planet", KEYBIND_KEYBOARD, SDLK_p, 0); input_setKeybind("target_planet", KEYBIND_KEYBOARD, SDLK_p, 0);
input_setKeybind("land", KEYBIND_KEYBOARD, SDLK_l, 0); input_setKeybind("land", KEYBIND_KEYBOARD, SDLK_l, 0);
input_setKeybind("thyperspace", KEYBIND_KEYBOARD, SDLK_h, 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); input_setKeybind("jump", KEYBIND_KEYBOARD, SDLK_j, 0);
// Misc. // Misc.
input_setKeybind("mapzoomin", KEYBIND_KEYBOARD, SDLK_0, 0); input_setKeybind("mapzoomin", KEYBIND_KEYBOARD, SDLK_0, 0);
input_setKeybind("mapzoomout", KEYBIND_KEYBOARD, SDLK_9, 0); input_setKeybind("mapzoomout", KEYBIND_KEYBOARD, SDLK_9, 0);
input_setKeybind("screenshot", KEYBIND_KEYBOARD, SDLK_F12, 0); input_setKeybind("screenshot", KEYBIND_KEYBOARD, SDLK_F12, 0);
input_setKeybind("pause", KEYBIND_KEYBOARD, SDLK_F1, 0); input_setKeybind("pause", KEYBIND_KEYBOARD, SDLK_F1, 0);
input_setKeybind("menu", KEYBIND_KEYBOARD, SDLK_ESCAPE, 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). // Initialization/exit functions (does not assign keys).
@ -122,27 +122,27 @@ void input_setKeybind(char* keybind, KeybindType type, int key, int reverse) {
#define INGAME() (!toolkit) #define INGAME() (!toolkit)
// We won't be having any more funny stuff from VLack.. // We won't be having any more funny stuff from VLack..
#define NOHYP() \ #define NOHYP() \
(!pilot_isFlag(player, PILOT_HYP_PREP) && \ (!pilot_isFlag(player, PILOT_HYP_PREP) && \
!pilot_isFlag(player, PILOT_HYP_BEGIN) && \ !pilot_isFlag(player, PILOT_HYP_BEGIN) && \
!pilot_isFlag(player, PILOT_HYPERSPACE)) !pilot_isFlag(player, PILOT_HYPERSPACE))
static void input_key(int keynum, double value, int abs) { static void input_key(int keynum, double value, int abs) {
unsigned int t; unsigned int t;
// Accelerating. // Accelerating.
if(KEY("accel")) { if(KEY("accel")) {
if(abs)player_acc = value; if(abs)player_acc = value;
else player_acc += value; else player_acc += value;
// Double tap accel = afterburn! // Double tap accel = afterburn!
t = SDL_GetTicks(); t = SDL_GetTicks();
if((value == KEY_PRESS) && (t-input_accelLast <= input_afterburnSensibility)) { if((value == KEY_PRESS) && (t-input_accelLast <= input_afterburnSensibility)) {
player_afterburn(); player_afterburn();
} }
else if((value == KEY_RELEASE) && player_isFlag(PLAYER_AFTERBURNER)) else if((value == KEY_RELEASE) && player_isFlag(PLAYER_AFTERBURNER))
player_afterburnOver(); player_afterburnOver();
else else
player_acc = ABS(player_acc); // Make sure value is sane. 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. // Turning left.
else if(KEY("left")) { else if(KEY("left")) {
@ -159,10 +159,10 @@ static void input_key(int keynum, double value, int abs) {
// Set flags for facing correction. // Set flags for facing correction.
if(value == KEY_PRESS) { player_setFlag(PLAYER_TURN_RIGHT); } if(value == KEY_PRESS) { player_setFlag(PLAYER_TURN_RIGHT); }
else if(value == KEY_RELEASE) { player_rmFlag(PLAYER_TURN_RIGHT); } else if(value == KEY_RELEASE) { player_rmFlag(PLAYER_TURN_RIGHT); }
if(abs) { player_turn = value; } if(abs) { player_turn = value; }
else { player_turn += value; } else { player_turn += value; }
if(player_turn < -1.) { player_turn = -1.; } // Make sure value is sane. if(player_turn < -1.) { player_turn = -1.; } // Make sure value is sane.
} }
// Turn around to face vel. // Turn around to face vel.
@ -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_LEFT)) { player_turn -= 1; }
if(player_isFlag(PLAYER_TURN_RIGHT)) { player_turn += 1; } if(player_isFlag(PLAYER_TURN_RIGHT)) { player_turn += 1; }
} }
} }
// Shoot primary weapon. BOOM BOOM. // Shoot primary weapon. BOOM BOOM.
else if(KEY("primary")) { else if(KEY("primary")) {
if(value == KEY_PRESS) { player_setFlag(PLAYER_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()) { else if(KEY("thyperspace") && INGAME() && NOHYP()) {
if(value == KEY_PRESS) player_targetHyperspace(); if(value == KEY_PRESS) player_targetHyperspace();
} }
else if(KEY("starmap") && NOHYP()) { else if(KEY("starmap") && NOHYP()) {
if(value == KEY_PRESS) map_open(); if(value == KEY_PRESS) map_open();
} }
else if(KEY("jump") && INGAME()) { else if(KEY("jump") && INGAME()) {
if(value == KEY_PRESS) player_jump(); if(value == KEY_PRESS) player_jump();
} }
@ -254,10 +254,10 @@ static void input_key(int keynum, double value, int abs) {
else if(KEY("menu")) { else if(KEY("menu")) {
if(value == KEY_PRESS) menu_small(); if(value == KEY_PRESS) menu_small();
} }
// Show pilot information. // Show pilot information.
else if(KEY("info") && NOHYP()) { else if(KEY("info") && NOHYP()) {
if(value == KEY_PRESS) menu_info(); if(value == KEY_PRESS) menu_info();
} }
} }
#undef KEY #undef KEY
@ -276,7 +276,7 @@ static void input_joyaxis(const unsigned int axis, const int value) {
int i; int i;
for(i = 0; strcmp(keybindNames[i], "end"); i++) for(i = 0; strcmp(keybindNames[i], "end"); i++)
if(input_keybinds[i]->type == KEYBIND_JAXIS && 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); input_key(i, -(input_keybinds[i]->reverse) * (double)value / 32767., 1);
return; return;
} }
@ -287,7 +287,7 @@ static void input_joydown(const unsigned int button) {
int i; int i;
for(i = 0; strcmp(keybindNames[i], "end");i++) for(i = 0; strcmp(keybindNames[i], "end");i++)
if(input_keybinds[i]->type == KEYBIND_JBUTTON && if(input_keybinds[i]->type == KEYBIND_JBUTTON &&
input_keybinds[i]->key == button) { input_keybinds[i]->key == button) {
input_key(i, KEY_RELEASE, 0); input_key(i, KEY_RELEASE, 0);
return; return;
} }
@ -298,7 +298,7 @@ static void input_joyup(const unsigned int button) {
int i; int i;
for(i = 0; strcmp(keybindNames[i], "end"); i++) for(i = 0; strcmp(keybindNames[i], "end"); i++)
if(input_keybinds[i]->type == KEYBIND_JBUTTON && if(input_keybinds[i]->type == KEYBIND_JBUTTON &&
input_keybinds[i]->key == button) { input_keybinds[i]->key == button) {
input_key(i, KEY_RELEASE, 0); input_key(i, KEY_RELEASE, 0);
return; return;
} }
@ -311,7 +311,7 @@ static void input_keydown(SDLKey key) {
int i; int i;
for(i = 0; strcmp(keybindNames[i], "end"); i++) for(i = 0; strcmp(keybindNames[i], "end"); i++)
if(input_keybinds[i]->type == KEYBIND_KEYBOARD && if(input_keybinds[i]->type == KEYBIND_KEYBOARD &&
input_keybinds[i]->key == key) { input_keybinds[i]->key == key) {
input_key(i, KEY_PRESS, 0); input_key(i, KEY_PRESS, 0);
return; return;
} }
@ -322,7 +322,7 @@ static void input_keyup(SDLKey key) {
int i; int i;
for(i = 0; strcmp(keybindNames[i], "end"); i++) for(i = 0; strcmp(keybindNames[i], "end"); i++)
if(input_keybinds[i]->type == KEYBIND_KEYBOARD && if(input_keybinds[i]->type == KEYBIND_KEYBOARD &&
input_keybinds[i]->key == key) { input_keybinds[i]->key == key) {
input_key(i, KEY_RELEASE, 0); input_key(i, KEY_RELEASE, 0);
return; return;
} }
@ -332,27 +332,27 @@ static void input_keyup(SDLKey key) {
// Just seperates the event types. // Just seperates the event types.
void input_handle(SDL_Event* event) { void input_handle(SDL_Event* event) {
if(toolkit) if(toolkit)
// Toolkit is handled seperately. // Toolkit is handled seperately.
if(toolkit_input(event)) if(toolkit_input(event))
return; // We don't process it if toolkit grabs it. return; // We don't process it if toolkit grabs it.
switch(event->type) { switch(event->type) {
case SDL_JOYAXISMOTION: case SDL_JOYAXISMOTION:
input_joyaxis(event->jaxis.axis, event->jaxis.value); input_joyaxis(event->jaxis.axis, event->jaxis.value);
break; break;
case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONDOWN:
input_joydown(event->jbutton.button); input_joydown(event->jbutton.button);
break; break;
case SDL_JOYBUTTONUP: case SDL_JOYBUTTONUP:
input_joyup(event->jbutton.button); input_joyup(event->jbutton.button);
break; break;
case SDL_KEYDOWN: case SDL_KEYDOWN:
input_keydown(event->key.keysym.sym); input_keydown(event->key.keysym.sym);
break; break;
case SDL_KEYUP: case SDL_KEYUP:
input_keyup(event->key.keysym.sym); input_keyup(event->key.keysym.sym);
break; break;
} }
} }

View File

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

View File

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

View File

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

View File

@ -65,7 +65,7 @@ static void render_space(void);
#ifdef WIN32 #ifdef WIN32
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine,
int nCmdShow) { int nCmdShow) {
int argc = 0; int argc = 0;
char *argv[] = { NULL }; char *argv[] = { NULL };
#else #else
@ -78,7 +78,7 @@ int main(int argc, char** argv) {
// Initialize SDL for possible warnings. // Initialize SDL for possible warnings.
SDL_Init(0); SDL_Init(0);
// Input must be initialized for config to work. // Input must be initialized for config to work.
input_init(); input_init();
@ -91,7 +91,7 @@ int main(int argc, char** argv) {
data_name(); data_name();
LOG(" %s", dataname); LOG(" %s", dataname);
DEBUG(); DEBUG();
// Random numbers. // Random numbers.
rng_init(); rng_init();
@ -113,14 +113,14 @@ int main(int argc, char** argv) {
window_caption(); window_caption();
// OpenAL sound. // OpenAL sound.
if(nosound) if(nosound)
LOG("Sound is disabled!"); LOG("Sound is disabled!");
else { else {
if(sound_init()) WARN("Problem setting up sound!"); if(sound_init()) WARN("Problem setting up sound!");
music_load("Machina"); music_load("Machina");
music_play(); music_play();
} }
// Input. // Input.
if((indjoystick >= 0) || (namjoystick != NULL)) { if((indjoystick >= 0) || (namjoystick != NULL)) {
@ -153,15 +153,15 @@ int main(int argc, char** argv) {
toolkit_init(); // Init the toolkit. toolkit_init(); // Init the toolkit.
// Data loading. // Data loading.
commodity_load(); commodity_load();
factions_load(); factions_load();
spfx_load(); spfx_load();
outfit_load(); outfit_load();
ships_load(); ships_load();
fleet_load(); fleet_load();
space_load(); space_load();
menu_main(); menu_main();
gtime = SDL_GetTicks(); // Init the time. 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. 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); glClear(GL_COLOR_BUFFER_BIT);
fps_control(); // Who doesn't love FPS control?
toolkit_update(); // Simulate key repetition.
if(!menu_isOpen(MENU_MAIN)) { fps_control(); // Who doesn't love FPS control?
if(!paused && !toolkit) update_space(); // Update the game. toolkit_update(); // Simulate key repetition.
render_space();
} if(!menu_isOpen(MENU_MAIN)) {
if(!paused && !toolkit) update_space(); // Update the game.
render_space();
}
if(toolkit) toolkit_render(); if(toolkit) toolkit_render();
@ -212,11 +212,11 @@ int main(int argc, char** argv) {
fleet_free(); fleet_free();
ships_free(); ships_free();
outfit_free(); outfit_free();
spfx_free(); // Remove the special effects. spfx_free(); // Remove the special effects.
factions_free(); factions_free();
commodity_free(); commodity_free();
gl_freeFont(NULL); gl_freeFont(NULL);
gl_freeFont(&gl_smallFont); gl_freeFont(&gl_smallFont);
// Exit subsystems. // Exit subsystems.
toolkit_exit(); // Kill the toolkit. toolkit_exit(); // Kill the toolkit.
@ -224,9 +224,9 @@ int main(int argc, char** argv) {
joystick_exit(); // Release joystick. joystick_exit(); // Release joystick.
input_exit(); // Clean up keybindings. input_exit(); // Clean up keybindings.
gl_exit(); // Kills video output. gl_exit(); // Kills video output.
sound_exit(); // Kills the sound. sound_exit(); // Kills the sound.
SDL_Quit(); // Quits SDL. SDL_Quit(); // Quits SDL.
// All is good. // All is good.
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
@ -240,7 +240,7 @@ static void fps_control(void) {
gtime = SDL_GetTicks(); gtime = SDL_GetTicks();
if(paused) SDL_Delay(10); // Drop paused FPS to be nice to the CPU. if(paused) SDL_Delay(10); // Drop paused FPS to be nice to the CPU.
// If the fps is limited.. // If the fps is limited..
if((max_fps != 0) && (dt < 1./max_fps)) { if((max_fps != 0) && (dt < 1./max_fps)) {
double delay = 1./max_fps - dt; double delay = 1./max_fps - dt;
@ -251,14 +251,14 @@ static void fps_control(void) {
// Update the game. // Update the game.
static void update_space(void) { static void update_space(void) {
if(dt > 1./30.) { if(dt > 1./30.) {
// Slow timers down and re-run calculations. // Slow timers down and re-run calculations.
pause_delay((unsigned int)dt*1000.); pause_delay((unsigned int)dt*1000.);
return; return;
} }
space_update(dt); space_update(dt);
weapons_update(dt); weapons_update(dt);
spfx_update(dt); spfx_update(dt);
pilots_update(dt); pilots_update(dt);
} }
@ -287,10 +287,10 @@ static void render_space(void) {
// N. // N.
pilots_render(); pilots_render();
weapons_render(WEAPON_LAYER_FG); weapons_render(WEAPON_LAYER_FG);
spfx_render(SPFX_LAYER_BACK); spfx_render(SPFX_LAYER_BACK);
// FG. // FG.
player_render(); player_render();
spfx_render(SPFX_LAYER_FRONT); spfx_render(SPFX_LAYER_FRONT);
display_fps(dt); display_fps(dt);
} }
@ -317,7 +317,7 @@ static void display_fps(const double dt) {
static void data_name(void) { static void data_name(void) {
uint32_t bufsize; uint32_t bufsize;
char* buf; char* buf;
// Check if data file is valid. // Check if data file is valid.
if(pack_check(DATA)) { if(pack_check(DATA)) {
ERR("Data file '%s' not found", data); ERR("Data file '%s' not found", data);

View File

@ -4,7 +4,7 @@
#define LOG(str, args...)(fprintf(stdout, str"\n", ## args)) #define LOG(str, args...)(fprintf(stdout, str"\n", ## args))
#define WARN(str, args...)(fprintf(stderr, "Warning: "str"\n", ## args)) #define WARN(str, args...)(fprintf(stderr, "Warning: "str"\n", ## args))
#define ERR(str, args...) (fprintf(stderr, "ERROR %s:%d: "str"\n", \ #define ERR(str, args...) (fprintf(stderr, "ERROR %s:%d: "str"\n", \
__FILE__, __LINE__, ## args)) __FILE__, __LINE__, ## args))
#ifdef DEBUG #ifdef DEBUG
# undef DEBUG # undef DEBUG

340
src/map.c
View File

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

View File

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

View File

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

View File

@ -16,7 +16,7 @@
#define SCREEN_W gl_screen.w #define SCREEN_W gl_screen.w
#define SCREEN_H gl_screen.h #define SCREEN_H gl_screen.h
// offsets to Adjust the pilot's place onscreen // offsets to Adjust the pilot's place onscreen
//to be in the middle, even with the GUI. //to be in the middle, even with the GUI.
extern double gui_xoff; extern double gui_xoff;
extern double gui_yoff; extern double gui_yoff;
@ -37,7 +37,7 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh);
// PNG. // PNG.
int write_png(const char* file_name, png_bytep* rows, int w, int h, int write_png(const char* file_name, png_bytep* rows, int w, int h,
int colourtype, int bitdepth); int colourtype, int bitdepth);
// ================ // ================
// MISC! // MISC!
@ -86,23 +86,23 @@ static int SDL_IsTrans(SDL_Surface* s, int x, int y) {
Uint32 pixelcolour = 0; Uint32 pixelcolour = 0;
switch(bpp) { switch(bpp) {
case 1: case 1:
pixelcolour = *p; pixelcolour = *p;
break; break;
case 2: case 2:
pixelcolour = *(Uint16*)p; pixelcolour = *(Uint16*)p;
break; break;
case 3: case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
pixelcolour = p[0] << 16 | p[1] << 8 | p[2]; pixelcolour = p[0] << 16 | p[1] << 8 | p[2];
else else
pixelcolour = p[0] | p[1] << 8 | p[2] << 16; pixelcolour = p[0] | p[1] << 8 | p[2] << 16;
break; break;
case 4: case 4:
pixelcolour = *(Uint32*)p; pixelcolour = *(Uint32*)p;
break; break;
} }
// Test whetehr the pixels color is equal to color of // Test whetehr the pixels color is equal to color of
//transparent pixels for that surface. //transparent pixels for that surface.
return (pixelcolour == s->format->colorkey); return (pixelcolour == s->format->colorkey);
} }
@ -153,7 +153,7 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh) {
Uint32 saved_flags; Uint32 saved_flags;
Uint8 saved_alpha; Uint8 saved_alpha;
int potw, poth; int potw, poth;
// Make size power of two. // Make size power of two.
potw = pot(surface->w); potw = pot(surface->w);
poth = pot(surface->h); poth = pot(surface->h);
@ -175,13 +175,13 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh) {
// Create the temp POT surface. // Create the temp POT surface.
tmp = SDL_CreateRGBSurface(SDL_SRCCOLORKEY, tmp = SDL_CreateRGBSurface(SDL_SRCCOLORKEY,
potw, poth, surface->format->BytesPerPixel*8, RGBMASK); potw, poth, surface->format->BytesPerPixel*8, RGBMASK);
if(tmp == NULL) { if(tmp == NULL) {
WARN("Unable to create POT surface %s", SDL_GetError()); WARN("Unable to create POT surface %s", SDL_GetError());
return 0; return 0;
} }
if(SDL_FillRect(tmp, NULL, SDL_MapRGBA(surface->format, 0, 0, 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()); WARN("Unable to fill rect: %s", SDL_GetError());
return 0; return 0;
} }
@ -197,13 +197,13 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh) {
// Create the temp POT surface. // Create the temp POT surface.
tmp = SDL_CreateRGBSurface(SDL_SRCCOLORKEY, tmp = SDL_CreateRGBSurface(SDL_SRCCOLORKEY,
potw, poth, surface->format->BytesPerPixel*8, RGBMASK); potw, poth, surface->format->BytesPerPixel*8, RGBMASK);
if(tmp == NULL) { if(tmp == NULL) {
WARN("Unable to create POT surface %s", SDL_GetError()); WARN("Unable to create POT surface %s", SDL_GetError());
return 0; return 0;
} }
if(SDL_FillRect(tmp, NULL, SDL_MapRGBA(surface->format, 0, 0, 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()); WARN("Unable to fill rect: %s", SDL_GetError());
return 0; return 0;
} }
@ -212,7 +212,7 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh) {
SDL_FreeSurface(surface); SDL_FreeSurface(surface);
surface = tmp; surface = tmp;
// Set saved alpha. // Set saved alpha.
if((saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA) if((saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA)
SDL_SetAlpha(surface, saved_flags, saved_alpha); SDL_SetAlpha(surface, saved_flags, saved_alpha);
@ -228,7 +228,7 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh) {
SDL_LockSurface(surface); SDL_LockSurface(surface);
glTexImage2D(GL_TEXTURE_2D, 0, surface->format->BytesPerPixel, glTexImage2D(GL_TEXTURE_2D, 0, surface->format->BytesPerPixel,
surface->w, surface->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels); surface->w, surface->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels);
SDL_UnlockSurface(surface); SDL_UnlockSurface(surface);
SDL_FreeSurface(surface); SDL_FreeSurface(surface);
@ -253,7 +253,7 @@ glTexture* gl_loadImage(SDL_Surface* surface) {
texture->rh = (double)rh; texture->rh = (double)rh;
texture->sw = texture->w; texture->sw = texture->w;
texture->sh = texture->h; texture->sh = texture->h;
texture->trans = NULL; texture->trans = NULL;
return texture; return texture;
@ -292,7 +292,7 @@ glTexture* gl_newImage(const char* path) {
WARN("Error flipping surface"); WARN("Error flipping surface");
return NULL; return NULL;
} }
// Do after flipping for collision detection. // Do after flipping for collision detection.
SDL_LockSurface(surface); SDL_LockSurface(surface);
trans = SDL_MapTrans(surface); trans = SDL_MapTrans(surface);
@ -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. // 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) { 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))); s = (int)(dir / (2.0*M_PI / (t->sy*t->sx)));
sx = t->sx; sx = t->sx;
sy = t->sy; sy = t->sy;
// Make sure the sprite is "in range". // Make sure the sprite is "in range".
if(s > (sy*sx-1)) s = s % (sy*sx); if(s > (sy*sx-1)) s = s % (sy*sx);
*x = s % sx; *x = s % sx;
*y = s / sx; *y = s / sx;
@ -348,10 +348,10 @@ void gl_getSpriteFromDir(int* x, int* y, const glTexture* t, const double dir) {
// Blit the sprite at given position. // Blit the sprite at given position.
void gl_blitSprite(const glTexture* sprite, const double bx, const double by, void gl_blitSprite(const glTexture* sprite, const double bx, const double by,
const int sx, const int sy, const glColour* c) { const int sx, const int sy, const glColour* c) {
// Don't bother drawing if offscreen -- waste of cycles. // Don't bother drawing if offscreen -- waste of cycles.
if(fabs(bx-VX(*gl_camera)+gui_xoff) > gl_screen.w / 2 + sprite->sw / 2 || if(fabs(bx-VX(*gl_camera)+gui_xoff) > gl_screen.w / 2 + sprite->sw / 2 ||
fabs(by-VY(*gl_camera)+gui_yoff) > gl_screen.h / 2 + sprite->sh / 2) fabs(by-VY(*gl_camera)+gui_yoff) > gl_screen.h / 2 + sprite->sh / 2)
return; return;
double x, y, tx, ty; double x, y, tx, ty;
@ -367,20 +367,20 @@ void gl_blitSprite(const glTexture* sprite, const double bx, const double by,
// Actual blitting.... // Actual blitting....
glBindTexture(GL_TEXTURE_2D, sprite->texture); glBindTexture(GL_TEXTURE_2D, sprite->texture);
glBegin(GL_QUADS); glBegin(GL_QUADS);
if(c == NULL) glColor4d(1., 1., 1., 1.); if(c == NULL) glColor4d(1., 1., 1., 1.);
else COLOUR(*c); else COLOUR(*c);
glTexCoord2d(tx, ty); glTexCoord2d(tx, ty);
glVertex2d(x, y); glVertex2d(x, y);
glTexCoord2d(tx + sprite->sw/sprite->rw, ty); glTexCoord2d(tx + sprite->sw/sprite->rw, ty);
glVertex2d(x + sprite->sw, y); glVertex2d(x + sprite->sw, y);
glTexCoord2d(tx + sprite->sw/sprite->rw, ty + sprite->sh/sprite->rh); glTexCoord2d(tx + sprite->sw/sprite->rw, ty + sprite->sh/sprite->rh);
glVertex2d(x + sprite->sw, y + sprite->sh); glVertex2d(x + sprite->sw, y + sprite->sh);
glTexCoord2d(tx, ty + sprite->sh/sprite->rh); glTexCoord2d(tx, ty + sprite->sh/sprite->rh);
glVertex2d(x, y + sprite->sh); glVertex2d(x, y + sprite->sh);
glEnd(); glEnd();
@ -389,30 +389,30 @@ void gl_blitSprite(const glTexture* sprite, const double bx, const double by,
// Just straight out blit the thing at position. // Just straight out blit the thing at position.
void gl_blitStatic(const glTexture* texture, const double bx, const double by, void gl_blitStatic(const glTexture* texture, const double bx, const double by,
const glColour* c) { const glColour* c) {
double x, y; double x, y;
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
x = bx - (double)gl_screen.w/2.; x = bx - (double)gl_screen.w/2.;
y = by - (double)gl_screen.h/2.; y = by - (double)gl_screen.h/2.;
// Actual blitting.. // Actual blitting..
glBindTexture(GL_TEXTURE_2D, texture->texture); glBindTexture(GL_TEXTURE_2D, texture->texture);
glBegin(GL_QUADS); glBegin(GL_QUADS);
if(c == NULL) glColor4d(1., 1., 1., 1.); if(c == NULL) glColor4d(1., 1., 1., 1.);
else COLOUR(*c); else COLOUR(*c);
glTexCoord2d(0., 0.);
glVertex2d(x, y);
glTexCoord2d(texture->sw/texture->rw, 0.); glTexCoord2d(0., 0.);
glVertex2d(x + texture->sw, y); glVertex2d(x, y);
glTexCoord2d(texture->sw/texture->rw, texture->sh/texture->rh); glTexCoord2d(texture->sw/texture->rw, 0.);
glVertex2d(x + texture->sw, y + texture->sh); glVertex2d(x + texture->sw, y);
glTexCoord2d(0., texture->sh/texture->rh); glTexCoord2d(texture->sw/texture->rw, texture->sh/texture->rh);
glVertex2d(x, y + texture->sh); glVertex2d(x + texture->sw, y + texture->sh);
glTexCoord2d(0., texture->sh/texture->rh);
glVertex2d(x, y + texture->sh);
glEnd(); glEnd();
@ -426,110 +426,110 @@ void gl_bindCamera(const Vec2* pos) {
// Draw circles. // Draw circles.
void gl_drawCircle(const double cx, const double cy, const double r) { void gl_drawCircle(const double cx, const double cy, const double r) {
double x, y, p; double x, y, p;
x = 0; x = 0;
y = r; y = r;
p = (5. - (r*4.)) / 4.; p = (5. - (r*4.)) / 4.;
glBegin(GL_POINTS); glBegin(GL_POINTS);
glVertex2d(cx, cy+y); glVertex2d(cx, cy+y);
glVertex2d(cx, cy-y); glVertex2d(cx, cy-y);
glVertex2d(cx+y, cy); glVertex2d(cx+y, cy);
glVertex2d(cx-y, cy); glVertex2d(cx-y, cy);
while(x < y) { while(x < y) {
x++; x++;
if(p < 0) p += 2*(double)(x)+1; if(p < 0) p += 2*(double)(x)+1;
else p += 2*(double)(x-(--y))+1; else p += 2*(double)(x-(--y))+1;
if(x == 0) { if(x == 0) {
glVertex2d(cx, cy+y); glVertex2d(cx, cy+y);
glVertex2d(cx, cy-y); glVertex2d(cx, cy-y);
glVertex2d(cx+y, cy); glVertex2d(cx+y, cy);
glVertex2d(cx-y, cy); glVertex2d(cx-y, cy);
} }
else if(x == 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+x, cy-y); glVertex2d(cx+x, cy-y);
glVertex2d(cx-x, cy-y); glVertex2d(cx-x, cy-y);
} }
else if(x < 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+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);
glVertex2d(cx+y, cy-x); glVertex2d(cx+y, cy-x);
glVertex2d(cx-y, cy-x); glVertex2d(cx-y, cy-x);
} }
} }
glEnd(); glEnd();
} }
// Draw a cirlce in a rect. // Draw a cirlce in a rect.
#define PIXEL(x,y) \ #define PIXEL(x,y) \
if((x>rx) && (y>ry) && (x<rxw) && (y<ryh)) \ 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, 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; rxw = rx+rw;
ryh = ry+rh; 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;
}
x = 0; // Are we offscreen?
y = r; if((cx+r < rx) || (cy+r < ry) || (cx-r > rxw) || (cy-r > ryh))
p = (5. - (r*4.)) / 4.; 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;
}
glBegin(GL_POINTS); x = 0;
y = r;
p = (5. - (r*4.)) / 4.;
glBegin(GL_POINTS);
PIXEL(cx, cy+y); PIXEL(cx, cy+y);
PIXEL(cx, cy-y); PIXEL(cx, cy-y);
PIXEL(cx+y, cy); PIXEL(cx+y, cy);
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;
if(x == 0) { while(x < y) {
PIXEL(cx, cy+y); x++;
PIXEL(cx, cy-y); if(p < 0) p += 2*(double)(x)+1;
PIXEL(cx+y, cy); else p += 2*(double)(x-(--y))+1;
PIXEL(cx-y, cy);
} if(x == 0) {
else if(x == y) { PIXEL(cx, cy+y);
PIXEL(cx+x, cy+y); PIXEL(cx, cy-y);
PIXEL(cx-x, cy+y); PIXEL(cx+y, cy);
PIXEL(cx+x, cy-y); PIXEL(cx-y, cy);
PIXEL(cx-x, cy-y); }
} else if(x == 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+x, cy-y);
PIXEL(cx+x, cy-y); PIXEL(cx-x, cy-y);
PIXEL(cx-x, cy-y); }
PIXEL(cx+y, cy+x); else if(x < y) {
PIXEL(cx-y, cy+x); PIXEL(cx+x, cy+y);
PIXEL(cx+y, cy-x); PIXEL(cx-x, cy+y);
PIXEL(cx-y, cy-x); 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(); glEnd();
} }
// ================ // ================
@ -566,7 +566,7 @@ int gl_init(void) {
for(i = 0; modes[i]; i++) { for(i = 0; modes[i]; i++) {
DEBUG("\t%dx%d", modes[i]->w, modes[i]->h); DEBUG("\t%dx%d", modes[i]->w, modes[i]->h);
if((flags & SDL_FULLSCREEN) && (modes[i]->w == gl_screen.w) && 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. supported = 1; // Mode we asked for is supported.
} }
} }
@ -584,8 +584,8 @@ int gl_init(void) {
} }
} }
WARN("Fullscreen mode %dx%d is not supported by your setup\n" WARN("Fullscreen mode %dx%d is not supported by your setup\n"
" Switching to %dx%d", gl_screen.w, gl_screen.h, " Switching to %dx%d", gl_screen.w, gl_screen.h,
modes[j]->w, modes[j]->h); modes[j]->w, modes[j]->h);
gl_screen.w = modes[j]->w; gl_screen.w = modes[j]->w;
gl_screen.h = modes[j]->h; gl_screen.h = modes[j]->h;
@ -621,10 +621,10 @@ int gl_init(void) {
// Debug heaven. // Debug heaven.
DEBUG("OpenGL Window Created: %dx%d@%dbpp %s", gl_screen.w, gl_screen.h, 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", 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"); (gl_has(OPENGL_DOUBLEBUF)) ? "yes" : "no");
DEBUG("Renderer: %s", glGetString(GL_RENDERER)); DEBUG("Renderer: %s", glGetString(GL_RENDERER));
@ -645,7 +645,7 @@ int gl_init(void) {
SCREEN_H /2, // Top edge. SCREEN_H /2, // Top edge.
-1., // Near. -1., // Near.
1.); // Far. 1.); // Far.
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
return 0; return 0;
@ -658,7 +658,7 @@ void gl_exit(void) {
// Saves a png. // Saves a png.
int write_png(const char* file_name, png_bytep* rows, int w, int h, 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_structp png_ptr;
png_infop info_ptr; png_infop info_ptr;
FILE* fp = NULL; 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"; doing = "Create png write struct";
if(!(png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 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"; doing = "Create png info struct";
if(!(info_ptr = png_create_info_struct(png_ptr))) goto fail; if(!(info_ptr = png_create_info_struct(png_ptr))) goto fail;
@ -677,8 +677,8 @@ int write_png(const char* file_name, png_bytep* rows, int w, int h,
doing = "Init IO"; doing = "Init IO";
png_init_io(png_ptr, fp); png_init_io(png_ptr, fp);
png_set_IHDR(png_ptr, info_ptr, w, h, bitdepth, colourtype, PNG_INTERLACE_NONE, png_set_IHDR(png_ptr, info_ptr, w, h, bitdepth, colourtype, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
doing = "Write info"; doing = "Write info";
png_write_info(png_ptr, info_ptr); png_write_info(png_ptr, info_ptr);

View File

@ -54,12 +54,12 @@ void gl_freeTexture(glTexture* texture);
// Rendering. // Rendering.
// Blits a sprite. // Blits a sprite.
void gl_blitSprite(const glTexture* sprite, const double bx, const double by, void gl_blitSprite(const glTexture* sprite, const double bx, const double by,
const int sx, const int sy, const glColour* c); const int sx, const int sy, const glColour* c);
// Blit the entire image. // Blit the entire image.
void gl_blitStatic(const glTexture* texture, const double bx, const double by, void gl_blitStatic(const glTexture* texture, const double bx, const double by,
const glColour* c); const glColour* c);
// Bind the camera to a vector. // Bind the camera to a vector.
void gl_bindCamera(const Vec2* pos); void gl_bindCamera(const Vec2* pos);
@ -67,7 +67,7 @@ void gl_bindCamera(const Vec2* pos);
// Circle drawing. // Circle drawing.
void gl_drawCircle(const double x, const double y, const double r); void gl_drawCircle(const double x, const double y, const double r);
void gl_drawCircleInRect(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. // Initialize/cleanup.
int gl_init(void); int gl_init(void);

View File

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

View File

@ -21,10 +21,10 @@ typedef enum OutfitType_ {
OUTFIT_TYPE_MISSILE_SWARM_AMMO = 10, OUTFIT_TYPE_MISSILE_SWARM_AMMO = 10,
OUTFIT_TYPE_MISSILE_SWARM_SMART = 11, OUTFIT_TYPE_MISSILE_SWARM_SMART = 11,
OUTFIT_TYPE_MISSILE_SWARM_SMART_AMMO = 12, OUTFIT_TYPE_MISSILE_SWARM_SMART_AMMO = 12,
OUTFIT_TYPE_TURRET_BOLT = 13, OUTFIT_TYPE_TURRET_BOLT = 13,
OUTFIT_TYPE_TURRET_BEAM = 14, OUTFIT_TYPE_TURRET_BEAM = 14,
OUTFIT_TYPE_MODIFICATION = 15, OUTFIT_TYPE_MODIFICATION = 15,
OUTFIT_TYPE_AFTERBURNER = 16 OUTFIT_TYPE_AFTERBURNER = 16
} OutfitType; } OutfitType;
// An outfit depends a lot on the type. // An outfit depends a lot on the type.
@ -36,14 +36,14 @@ typedef struct Outfit_ {
int tech; int tech;
int mass; int mass;
// Store stuff. // Store stuff.
unsigned int price; unsigned int price;
char* description; char* description;
glTexture* gfx_store; // Store graphic. glTexture* gfx_store; // Store graphic.
int properties; // Properties stored bitwise. int properties; // Properties stored bitwise.
// Type dependant. // Type dependant.
OutfitType type; OutfitType type;
union { union {
@ -52,50 +52,50 @@ typedef struct Outfit_ {
double speed; // Speed of shot. (not applicable to beam. double speed; // Speed of shot. (not applicable to beam.
double range; double range;
double accuracy; // Desviation accuracy. double accuracy; // Desviation accuracy.
double energy; // Energy usage. double energy; // Energy usage.
double damage_armour, damage_shield; // Damage. double damage_armour, damage_shield; // Damage.
glTexture* gfx_space; glTexture* gfx_space;
ALuint sound; // Sound to play. ALuint sound; // Sound to play.
int spfx; // Special effect on hit. int spfx; // Special effect on hit.
} blt; } blt;
struct { // Beam. struct { // Beam.
double range; // Distance it travels. double range; // Distance it travels.
glColour colour; // Beam colour. glColour colour; // Beam colour.
double energy; // Energy drained. double energy; // Energy drained.
double damage_armour, damage_shield; // Damage. double damage_armour, damage_shield; // Damage.
} bem; } bem;
struct { // Launcher. struct { // Launcher.
unsigned int delay; // Delay between shots. unsigned int delay; // Delay between shots.
char* ammo; char* ammo;
} lau; } lau;
struct { // Ammo. struct { // Ammo.
unsigned int duration; // Duration. unsigned int duration; // Duration.
double speed; // Max speed. double speed; // Max speed.
double turn; // Turn vel. double turn; // Turn vel.
double thrust; // Acceleration. double thrust; // Acceleration.
double energy; // Energy usage. double energy; // Energy usage.
double damage_armour, damage_shield; // Damage. double damage_armour, damage_shield; // Damage.
glTexture* gfx_space; glTexture* gfx_space;
ALuint sound; // Sound to play. ALuint sound; // Sound to play.
int spfx; // Special effect on hit. int spfx; // Special effect on hit.
unsigned int lockon; // Time taken to lock on the target. unsigned int lockon; // Time taken to lock on the target.
} amm; } amm;
struct { // Modification. struct { // Modification.
// Movement. // Movement.
double thrust, turn, speed; double thrust, turn, speed;
// Health. // Health.
double armour, armour_regen; double armour, armour_regen;
double shield, shield_regen; double shield, shield_regen;
double energy, energy_regen; double energy, energy_regen;
} mod; } mod;
struct { // Afterburner. struct { // Afterburner.
double thrust_perc, thrust_abs; // Percent and absolute thrust bonus. double thrust_perc, thrust_abs; // Percent and absolute thrust bonus.
double speed_perc, speed_abs; // Percent and absolute speed bonus. double speed_perc, speed_abs; // Percent and absolute speed bonus.
double energy; // Energy used while active. double energy; // Energy used while active.
} afb; } afb;
} u; } u;
} Outfit; } Outfit;

View File

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

View File

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

View File

@ -26,8 +26,8 @@ void pause(void) {
pilots_pause(); pilots_pause();
weapons_pause(); weapons_pause();
spfx_pause(); spfx_pause();
spawn_timer -= SDL_GetTicks(); spawn_timer -= SDL_GetTicks();
paused = 1; // We should unpause it. paused = 1; // We should unpause it.
} }
@ -37,17 +37,17 @@ void unpause(void) {
pilots_unpause(); pilots_unpause();
weapons_unpause(); weapons_unpause();
spfx_unpause(); spfx_unpause();
spawn_timer += SDL_GetTicks(); spawn_timer += SDL_GetTicks();
paused = 0; paused = 0;
} }
// Set the timers back. // Set the timers back.
void pause_delay(unsigned int delay) { void pause_delay(unsigned int delay) {
pilots_delay(delay); pilots_delay(delay);
weapons_delay(delay); weapons_delay(delay);
spfx_delay(delay); spfx_delay(delay);
} }
static void pilots_pause(void) { static void pilots_pause(void) {
@ -75,13 +75,13 @@ static void pilots_unpause(void) {
} }
static void pilots_delay(unsigned int delay) { static void pilots_delay(unsigned int delay) {
int i, j; int i, j;
for(i = 0; i < pilots; i++) { for(i = 0; i < pilots; i++) {
pilot_stack[i]->ptimer += delay; pilot_stack[i]->ptimer += delay;
pilot_stack[i]->tcontrol += delay; pilot_stack[i]->tcontrol += delay;
for(j = 0; j < MAX_AI_TIMERS; j++) for(j = 0; j < MAX_AI_TIMERS; j++)
pilot_stack[i]->timer[j] += delay; 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) { void limit_speed(Vec2* vel, const double speed, const double dt) {
double vmod = VMOD(*vel); double vmod = VMOD(*vel);
if(vmod > speed) // Should not go faster. if(vmod > speed) // Should not go faster.
vect_pset(vel, (vmod-speed)*(1.-dt*3.) + speed, VANGLE(*vel)); vect_pset(vel, (vmod-speed)*(1.-dt*3.) + speed, VANGLE(*vel));
} }
// ================ // ================
@ -92,7 +92,7 @@ static void simple_update(Solid* obj, const double dt) {
obj->dir += M_PI/360.*obj->dir_vel*dt; obj->dir += M_PI/360.*obj->dir_vel*dt;
if(obj->dir > 2*M_PI) obj->dir -= 2*M_PI; if(obj->dir > 2*M_PI) obj->dir -= 2*M_PI;
if(obj->dir < 0.) obj->dir += 2*M_PI; if(obj->dir < 0.) obj->dir += 2*M_PI;
double px, py, vx, vy; double px, py, vx, vy;
px = VX(obj->pos); px = VX(obj->pos);
py = VY(obj->pos); py = VY(obj->pos);
@ -190,7 +190,7 @@ static void rk4_update(Solid* obj, const double dt) {
// Initialize a new solid. // Initialize a new solid.
void solid_init(Solid* dest, const double mass, const double dir, 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->mass = mass;
dest->dir_vel = 0.; dest->dir_vel = 0.;
@ -202,7 +202,7 @@ void solid_init(Solid* dest, const double mass, const double dir,
if(vel == NULL) vectnull(&dest->vel); if(vel == NULL) vectnull(&dest->vel);
else vectcpy(&dest->vel, vel); else vectcpy(&dest->vel, vel);
if(pos == NULL) vectnull(&dest->pos); if(pos == NULL) vectnull(&dest->pos);
else vectcpy(&dest->pos, pos); else vectcpy(&dest->pos, pos);
@ -211,7 +211,7 @@ void solid_init(Solid* dest, const double mass, const double dir,
// Create a new solid. // Create a new solid.
Solid* solid_create(const double mass, const double dir, 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); Solid* dyn = MALLOC_L(Solid);
if(dyn == NULL) ERR("Out of memory"); if(dyn == NULL) ERR("Out of memory");
solid_init(dyn, mass, dir, pos, vel); solid_init(dyn, mass, dir, pos, vel);

View File

@ -42,9 +42,9 @@ typedef struct Solid_ {
} Solid; } Solid;
// Solid manipulation. // Solid manipulation.
void solid_init(Solid* dest, const double mass, const double dir, void solid_init(Solid* dest, const double mass, const double dir,
const Vec2* pos, const Vec2* vel); const Vec2* pos, const Vec2* vel);
Solid* solid_create(const double mass, const double dir, Solid* solid_create(const double mass, const double dir,
const Vec2* pos, const Vec2* vel); const Vec2* pos, const Vec2* vel);
void solid_free(Solid* src); void solid_free(Solid* src);

View File

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

View File

@ -10,11 +10,11 @@
#define PLAYER_ID 1 #define PLAYER_ID 1
#define HYPERSPACE_ENGINE_DELAY 3000 // Warm up the engines. #define HYPERSPACE_ENGINE_DELAY 3000 // Warm up the engines.
#define HYPERSPACE_FLY_DELAY 5000 // Time taken to hyperspace. #define HYPERSPACE_FLY_DELAY 5000 // Time taken to hyperspace.
#define HYPERSPACE_STARS_BLUR 2000 // Time stars blur. #define HYPERSPACE_STARS_BLUR 2000 // Time stars blur.
#define HYPERSPACE_STARS_LENGTH 1000 // Length the stars blur to at max. #define HYPERSPACE_STARS_LENGTH 1000 // Length the stars blur to at max.
#define HYPERSPACE_FADEOUT 1000 // Time fadeout. #define HYPERSPACE_FADEOUT 1000 // Time fadeout.
// Aproximation for pilot size. // Aproximation for pilot size.
#define PILOT_SIZE_APROX 0.8 #define PILOT_SIZE_APROX 0.8
@ -26,18 +26,18 @@
#define pilot_rmFlag(p,f) (p->flags ^= (f)) #define pilot_rmFlag(p,f) (p->flags ^= (f))
// Creation. // Creation.
#define PILOT_PLAYER (1<<0) // Pilot is a player. #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. // Dynamic.
#define PILOT_HOSTILE (1<<1) // Pilot is hostile to the player. #define PILOT_HOSTILE (1<<1) // Pilot is hostile to the player.
#define PILOT_COMBAT (1<<2) // Pilot is engaged in combat. #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_PREP (1<<5) // Pilot is getting ready for hyperspace.
#define PILOT_HYP_BEGIN (1<<6) // Pilot is starting engines. #define PILOT_HYP_BEGIN (1<<6) // Pilot is starting engines.
#define PILOT_HYPERSPACE (1<<7) // Pilot is in hyperspace. #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_DISABLED (1<<9) // Pilot is disabled.
#define PILOT_DEAD (1<<10) // Pilot is on it's death bed. #define PILOT_DEAD (1<<10) // Pilot is on it's death bed.
#define PILOT_EXPLODED (1<<11) // Pilot did final death explosion. #define PILOT_EXPLODED (1<<11) // Pilot did final death explosion.
#define PILOT_DELETE (1<<15) // Pilot will get delete asap. #define PILOT_DELETE (1<<15) // Pilot will get delete asap.
// Just makes life simpler. // Just makes life simpler.
@ -45,14 +45,14 @@
#define pilot_isDisabled(p) ((p)->flags & PILOT_DISABLED) #define pilot_isDisabled(p) ((p)->flags & PILOT_DISABLED)
typedef struct PilotOutfit_ { typedef struct PilotOutfit_ {
Outfit* outfit; // Associated outfit. Outfit* outfit; // Associated outfit.
int quantity; // Number of outfits of this type that the pilot has. int quantity; // Number of outfits of this type that the pilot has.
unsigned int timer; // Used to store last used weapon time. unsigned int timer; // Used to store last used weapon time.
} PilotOutfit; } PilotOutfit;
typedef struct PilotCommodity_ { typedef struct PilotCommodity_ {
Commodity* commodity; Commodity* commodity;
int quantity; int quantity;
} PilotCommodity; } PilotCommodity;
// Primary pilot structure. // Primary pilot structure.
@ -65,14 +65,14 @@ typedef struct Pilot_ {
// Object characteristics. // Object characteristics.
Ship* ship; // Pilots ship. Ship* ship; // Pilots ship.
Solid* solid; // Associated solid (physics). 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. // Current health.
double armour, shield, energy; double armour, shield, energy;
double armour_max, shield_max, energy_max; 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. double fuel; // Used only for jumps. TODO: make it do something.
void (*think)(struct Pilot_*); // AI thinking for the pilot. void (*think)(struct Pilot_*); // AI thinking for the pilot.
@ -84,16 +84,16 @@ typedef struct Pilot_ {
int noutfits; int noutfits;
PilotOutfit* secondary; // Secondary weapon. PilotOutfit* secondary; // Secondary weapon.
PilotOutfit* ammo; // Secondary ammo (if needed). PilotOutfit* ammo; // Secondary ammo (if needed).
PilotOutfit* afterburner; // Ze afterburner. PilotOutfit* afterburner; // Ze afterburner.
// Cargo. // Cargo.
int credits; // Moniez the pilot has. int credits; // Moniez the pilot has.
PilotCommodity* commodities; // Commodity and quantity. PilotCommodity* commodities; // Commodity and quantity.
int ncommodities; int ncommodities;
int cargo_free; int cargo_free;
// Misc. // Misc.
uint32_t flags; // Used for AI etc. uint32_t flags; // Used for AI etc.
unsigned int ptimer; // Generic timer for internal pilot use. unsigned int ptimer; // Generic timer for internal pilot use.
// AI. // AI.
@ -113,7 +113,7 @@ typedef struct FleetPilot_ {
typedef struct Fleet_ { typedef struct Fleet_ {
char* name; // Fleet name, used as an identifier. char* name; // Fleet name, used as an identifier.
Faction* faction; // Faction of the fleet. Faction* faction; // Faction of the fleet.
AI_Profile* ai; // A useable profile. AI_Profile* ai; // A useable profile.
FleetPilot* pilots; // The pilots in the fleet. FleetPilot* pilots; // The pilots in the fleet.
@ -131,7 +131,7 @@ Fleet* fleet_get(const char* name);
// MISC. // MISC.
void pilot_shoot(Pilot* p, const unsigned int target, const int secondary); void pilot_shoot(Pilot* p, const unsigned int target, const int secondary);
void pilot_hit(Pilot* p, const Solid* w, const unsigned int shooter, 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_setSecondary(Pilot* p, const char* secondary);
void pilot_setAmmo(Pilot* p); void pilot_setAmmo(Pilot* p);
double pilot_face(Pilot* p, const float dir); double pilot_face(Pilot* p, const float dir);
@ -142,12 +142,12 @@ int pilot_rmCargo(Pilot* pilot, Commodity* cargo, int quantity);
// Creation. // Creation.
void pilot_init(Pilot* dest, Ship* ship, char* name, Faction* faction, void pilot_init(Pilot* dest, Ship* ship, char* name, Faction* faction,
AI_Profile* ai, const double dir, const Vec2* pos, AI_Profile* ai, const double dir, const Vec2* pos,
const Vec2* vel, const int flags); const Vec2* vel, const int flags);
unsigned int pilot_create(Ship* ship, char* name, Faction* faction, unsigned int pilot_create(Ship* ship, char* name, Faction* faction,
AI_Profile* ai, const double dir, const Vec2* pos, AI_Profile* ai, const double dir, const Vec2* pos,
const Vec2* vel, const int flags); const Vec2* vel, const int flags);
// Init/Cleanup. // Init/Cleanup.
void pilot_destroy(Pilot* p); void pilot_destroy(Pilot* p);

View File

@ -90,9 +90,9 @@ typedef struct GUI_ {
} GUI; } GUI;
GUI gui = { GUI gui = {
.gfx_frame = NULL, .gfx_frame = NULL,
.gfx_targetPilot = NULL, .gfx_targetPilot = NULL,
.gfx_targetPlanet = NULL .gfx_targetPlanet = NULL
}; };
double gui_xoff = 0.; double gui_xoff = 0.;
@ -111,12 +111,12 @@ static Msg* msg_stack;
// External. // External.
extern void pilot_render(const Pilot* pilot); // Extern is in Pilot.* extern void pilot_render(const Pilot* pilot); // Extern is in Pilot.*
extern void weapon_minimap(const double res, 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, 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. // Internal.
static void rect_parse(const xmlNodePtr parent, 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 int gui_parse(const xmlNodePtr parent, const char* name);
static void gui_renderPilot(const Pilot* p); static void gui_renderPilot(const Pilot* p);
static void gui_renderBar(const glColour* c, const Rect* r, const double w); 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); else if(xml_isNode(tmp, "y")) y = xml_getFloat(tmp);
} while((tmp = tmp->next)); } while((tmp = tmp->next));
} }
else if(xml_isNode(cur, "combat_crating")) else if(xml_isNode(cur, "combat_crating"))
combat_crating = xml_getInt(cur); combat_crating = xml_getInt(cur);
} while((cur = cur->next)); } while((cur = cur->next));
} }
}while((node = node->next)); }while((node = node->next));
@ -181,8 +181,8 @@ void player_new(void) {
free(buf); free(buf);
xmlCleanupParser(); xmlCleanupParser();
// In case we are respawning. // In case we are respawning.
player_rmFlag(PLAYER_DESTROYED); player_rmFlag(PLAYER_DESTROYED);
// Money. // Money.
player_credits = RNG(l, h); player_credits = RNG(l, h);
@ -191,24 +191,24 @@ void player_new(void) {
player_message("Welcome to "APPNAME"!"); player_message("Welcome to "APPNAME"!");
player_message("v%d.%d.%d", VMAJOR, VMINOR, VREV); player_message("v%d.%d.%d", VMAJOR, VMINOR, VREV);
// Create the player and start the game. // Create the player and start the game.
player_newShip(ship); player_newShip(ship);
space_init(system); space_init(system);
// Position and direction. // Position and direction.
player_warp(x, y); player_warp(x, y);
player->solid->dir = RNG(0, 359) / 180.*M_PI; player->solid->dir = RNG(0, 359) / 180.*M_PI;
} }
// Change the players ship. // Change the players ship.
void player_newShip(Ship* ship) { void player_newShip(Ship* ship) {
if(player) if(player)
pilot_destroy(player); pilot_destroy(player);
pilot_create(ship, "Player", faction_get("Player"), NULL, pilot_create(ship, "Player", faction_get("Player"), NULL,
0., NULL, NULL, PILOT_PLAYER); 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, ...) { void player_message(const char* fmt, ...) {
@ -223,12 +223,12 @@ void player_message(const char* fmt, ...) {
strcpy(msg_stack[msg_max-i].str, msg_stack[msg_max-i-1].str); strcpy(msg_stack[msg_max-i].str, msg_stack[msg_max-i-1].str);
msg_stack[msg_max-i].t = msg_stack[msg_max-i-1].t; msg_stack[msg_max-i].t = msg_stack[msg_max-i-1].t;
} }
// Add the new one. // Add the new one.
va_start(ap, fmt); va_start(ap, fmt);
vsprintf(msg_stack[0].str, fmt, ap); vsprintf(msg_stack[0].str, fmt, ap);
va_end(ap); va_end(ap);
msg_stack[0].t = SDL_GetTicks() + msg_timeout; msg_stack[0].t = SDL_GetTicks() + msg_timeout;
} }
void player_warp(const double x, const double y) { void player_warp(const double x, const double y) {
@ -243,56 +243,56 @@ void player_clear(void) {
} }
static char* player_ratings[] = { static char* player_ratings[] = {
"None", "None",
"Smallfry", "Smallfry",
"Minor", "Minor",
"Average", "Average",
"Major", "Major",
"Fearsome", "Fearsome",
"Godlike" "Godlike"
}; };
const char* player_rating(void) { const char* player_rating(void) {
if(combat_crating == 0) return player_ratings[0]; if(combat_crating == 0) return player_ratings[0];
else if(combat_crating < 50) return player_ratings[1]; else if(combat_crating < 50) return player_ratings[1];
else if(combat_crating < 200) return player_ratings[2]; else if(combat_crating < 200) return player_ratings[2];
else if(combat_crating < 500) return player_ratings[3]; else if(combat_crating < 500) return player_ratings[3];
else if(combat_crating < 1000) return player_ratings[4]; else if(combat_crating < 1000) return player_ratings[4];
else if(combat_crating < 2500) return player_ratings[5]; else if(combat_crating < 2500) return player_ratings[5];
else if(combat_crating < 10000) return player_ratings[6]; else if(combat_crating < 10000) return player_ratings[6];
else return player_ratings[7]; else return player_ratings[7];
} }
// Return how much weapon. space the player has remaining. // Return how much weapon. space the player has remaining.
int player_freeSpace(void) { int player_freeSpace(void) {
int i, s; int i, s;
s = player->ship->cap_weapon; s = player->ship->cap_weapon;
for(i = 0; i < player->noutfits; i++) for(i = 0; i < player->noutfits; i++)
s -= player->outfits[i].quantity * player->outfits[i].outfit->mass; s -= player->outfits[i].quantity * player->outfits[i].outfit->mass;
return s; return s;
} }
// Return amount of outfits the player owns. // Return amount of outfits the player owns.
int player_outfitOwned(const char* outfitname) { int player_outfitOwned(const char* outfitname) {
int i; int i;
for(i = 0; i < player->noutfits; i++) for(i = 0; i < player->noutfits; i++)
if(strcmp(outfitname, player->outfits[i].outfit->name)==0) if(strcmp(outfitname, player->outfits[i].outfit->name)==0)
return player->outfits[i].quantity; return player->outfits[i].quantity;
return 0; return 0;
} }
// Return how many of the commodity the player has. // Return how many of the commodity the player has.
int player_cargoOwned(const char* commodityname) { int player_cargoOwned(const char* commodityname) {
int i; int i;
for(i = 0; i < player->ncommodities; i++) for(i = 0; i < player->ncommodities; i++)
if(strcmp(commodityname, player->commodities[i].commodity->name)==0) if(strcmp(commodityname, player->commodities[i].commodity->name)==0)
return player->commodities[i].quantity; return player->commodities[i].quantity;
return 0; return 0;
} }
// Render the background player stuff, namely planet target // Render the background player stuff, namely planet target
@ -301,8 +301,8 @@ void player_renderBG(void) {
glColour* c; glColour* c;
Planet* planet; Planet* planet;
if(player_isFlag(PLAYER_DESTROYED) || if(player_isFlag(PLAYER_DESTROYED) ||
pilot_isFlag(player, PILOT_DEAD)) return; pilot_isFlag(player, PILOT_DEAD)) return;
if(planet_target >= 0) { if(planet_target >= 0) {
planet = &cur_system->planets[planet_target]; planet = &cur_system->planets[planet_target];
@ -334,45 +334,45 @@ void player_render(void) {
glColour* c; glColour* c;
glFont* f; glFont* f;
if(player_isFlag(PLAYER_DESTROYED) || pilot_isFlag(player, PILOT_DEAD)) { if(player_isFlag(PLAYER_DESTROYED) || pilot_isFlag(player, PILOT_DEAD)) {
if(player_isFlag(PLAYER_DESTROYED)) { if(player_isFlag(PLAYER_DESTROYED)) {
if(!toolkit && (SDL_GetTicks() > player_timer)) if(!toolkit && (SDL_GetTicks() > player_timer))
menu_death(); menu_death();
} else } else
pilot_render(player); 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);
COLOUR(cBlack); // Fancy cinematic scene borders.
glBegin(GL_QUADS); glMatrixMode(GL_MODELVIEW);
glVertex2d(0., 0.); glPushMatrix(); // Translation matrix.
glVertex2d(0., gl_screen.h*0.2); glTranslated(x-(double)gl_screen.w/2., y-(double)gl_screen.h/2., 0);
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. 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();
return; glPopMatrix(); // Translation matrix.
}
return;
}
// Render the player target graphics. // Render the player target graphics.
if(player_target != PLAYER_ID) p = pilot_get(player_target); if(player_target != PLAYER_ID) p = pilot_get(player_target);
else p = NULL; else p = NULL;
if((p == NULL) || pilot_isFlag(p, PILOT_DEAD)) if((p == NULL) || pilot_isFlag(p, PILOT_DEAD))
player_target = PLAYER_ID; // No more pilot target. player_target = PLAYER_ID; // No more pilot target.
else { else {
// There is still a pilot target. // There is still a pilot target.
if(pilot_isDisabled(p)) c = &cInert; if(pilot_isDisabled(p)) c = &cInert;
else if(pilot_isFlag(p, PILOT_HOSTILE)) c = &cHostile; else if(pilot_isFlag(p, PILOT_HOSTILE)) c = &cHostile;
else c = &cNeutral; else c = &cNeutral;
x = p->solid->pos.x - p->ship->gfx_space->sw * PILOT_SIZE_APROX/2.; x = p->solid->pos.x - p->ship->gfx_space->sw * PILOT_SIZE_APROX/2.;
y = p->solid->pos.y + p->ship->gfx_space->sh * PILOT_SIZE_APROX/2.; y = p->solid->pos.y + p->ship->gfx_space->sh * PILOT_SIZE_APROX/2.;
gl_blitSprite(gui.gfx_targetPilot, x, y, 0, 0, c); // Top left. gl_blitSprite(gui.gfx_targetPilot, x, y, 0, 0, c); // Top left.
@ -397,18 +397,18 @@ void player_render(void) {
glPushMatrix(); glPushMatrix();
if(gui.radar.shape == RADAR_RECT) if(gui.radar.shape == RADAR_RECT)
glTranslated(gui.radar.x - gl_screen.w/2. + gui.radar.w/2., glTranslated(gui.radar.x - gl_screen.w/2. + gui.radar.w/2.,
gui.radar.y - gl_screen.h/2. - gui.radar.h/2., 0.); gui.radar.y - gl_screen.h/2. - gui.radar.h/2., 0.);
else if(gui.radar.shape == RADAR_CIRCLE) else if(gui.radar.shape == RADAR_CIRCLE)
glTranslated(gui.radar.x - gl_screen.w/2., glTranslated(gui.radar.x - gl_screen.w/2.,
gui.radar.y - gl_screen.h/2., 0.); gui.radar.y - gl_screen.h/2., 0.);
// Planets. // Planets.
planets_minimap(gui.radar.res, gui.radar.w, gui.radar.h, gui.radar.shape); planets_minimap(gui.radar.res, gui.radar.w, gui.radar.h, gui.radar.shape);
// Weapons. // Weapons.
glBegin(GL_POINTS); glBegin(GL_POINTS);
COLOUR(cRadar_weap); COLOUR(cRadar_weap);
weapon_minimap(gui.radar.res, gui.radar.w, gui.radar.h, gui.radar.shape); weapon_minimap(gui.radar.res, gui.radar.w, gui.radar.h, gui.radar.shape);
glEnd(); glEnd();
// Render the pilots. // Render the pilots.
@ -442,44 +442,44 @@ void player_render(void) {
if(planet_target >= 0) { if(planet_target >= 0) {
// Planet landing target. // Planet landing target.
gl_printMid(NULL, (int)gui.nav.w, 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, gl_printMid(&gl_smallFont, (int)gui.nav.w, gui.nav.x,
gui.nav.y - 10 - gl_smallFont.h, NULL, "%s", gui.nav.y - 10 - gl_smallFont.h, NULL, "%s",
cur_system->planets[planet_target].name); cur_system->planets[planet_target].name);
} }
else if(hyperspace_target >= 0) { else if(hyperspace_target >= 0) {
// Hyperspace target. // Hyperspace target.
c = space_canHyperspace(player) ? &cConsole : NULL; c = space_canHyperspace(player) ? &cConsole : NULL;
gl_printMid(NULL, (int)gui.nav.w, gui.nav.x, gui.nav.y - 5, gl_printMid(NULL, (int)gui.nav.w, gui.nav.x, gui.nav.y - 5,
c, "Hyperspace"); c, "Hyperspace");
gl_printMid(&gl_smallFont, (int)gui.nav.w, gui.nav.x, gl_printMid(&gl_smallFont, (int)gui.nav.w, gui.nav.x,
gui.nav.y - 10 - gl_smallFont.h, NULL, "%s", gui.nav.y - 10 - gl_smallFont.h, NULL, "%s",
systems_stack[cur_system->jumps[hyperspace_target]].name); systems_stack[cur_system->jumps[hyperspace_target]].name);
} }
else { else {
// No NAV target. // No NAV target.
gl_printMid(NULL, (int)gui.nav.w, gui.nav.x, gl_printMid(NULL, (int)gui.nav.w, gui.nav.x,
gui.nav.y - 5, &cConsole, "Navigation"); gui.nav.y - 5, &cConsole, "Navigation");
gl_printMid(&gl_smallFont, (int)gui.nav.w, gui.nav.x, gl_printMid(&gl_smallFont, (int)gui.nav.w, gui.nav.x,
gui.nav.y - 10 - gl_smallFont.h, &cGrey, "Off"); gui.nav.y - 10 - gl_smallFont.h, &cGrey, "Off");
} }
// Health // Health
gui_renderBar(&cShield, &gui.shield, player->shield / player->shield_max); gui_renderBar(&cShield, &gui.shield, player->shield / player->shield_max);
gui_renderBar(&cArmour, &gui.armour, player->armour / player->armour_max); gui_renderBar(&cArmour, &gui.armour, player->armour / player->armour_max);
gui_renderBar(&cEnergy, &gui.energy, player->energy / player->energy_max); gui_renderBar(&cEnergy, &gui.energy, player->energy / player->energy_max);
// Weapon. // Weapon.
if(player->secondary == NULL) { if(player->secondary == NULL) {
gl_printMid(NULL, (int)gui.weapon.w, gui.weapon.x, gl_printMid(NULL, (int)gui.weapon.w, gui.weapon.x,
gui.weapon.y - 5, &cConsole, "Secondary"); gui.weapon.y - 5, &cConsole, "Secondary");
gl_printMid(&gl_smallFont, (int)gui.weapon.w, gui.weapon.x, gl_printMid(&gl_smallFont, (int)gui.weapon.w, gui.weapon.x,
gui.weapon.y - 10 - gl_defFont.h, &cGrey, "None"); gui.weapon.y - 10 - gl_defFont.h, &cGrey, "None");
} else { } else {
f = &gl_defFont; f = &gl_defFont;
if(outfit_isLauncher(player->secondary->outfit)) { if(outfit_isLauncher(player->secondary->outfit)) {
// Use the ammunitions name. // Use the ammunitions name.
i = gl_printWidth(f, "%s", player->secondary->outfit->u.lau.ammo); i = gl_printWidth(f, "%s", player->secondary->outfit->u.lau.ammo);
if(i > gui.weapon.w) if(i > gui.weapon.w)
@ -487,23 +487,23 @@ void player_render(void) {
f = &gl_smallFont; f = &gl_smallFont;
gl_printMid(f, (int)gui.weapon.w, gui.weapon.x, gl_printMid(f, (int)gui.weapon.w, gui.weapon.x,
gui.weapon.y - 5, gui.weapon.y - 5,
&cConsole, "%s", player->secondary->outfit->u.lau.ammo); &cConsole, "%s", player->secondary->outfit->u.lau.ammo);
// Print ammo underneath to the left. // Print ammo underneath to the left.
gl_printMid(&gl_smallFont, (int)gui.weapon.w, gui.weapon.x, gl_printMid(&gl_smallFont, (int)gui.weapon.w, gui.weapon.x,
gui.weapon.y - 10 - gl_defFont.h, gui.weapon.y - 10 - gl_defFont.h,
NULL, "%d", (player->ammo) ? player->ammo->quantity : 0); NULL, "%d", (player->ammo) ? player->ammo->quantity : 0);
} else { } else {
// Just print the item name. // Just print the item name.
i = gl_printWidth(f, "%s", player->secondary->outfit->name); i = gl_printWidth(f, "%s", player->secondary->outfit->name);
if(i > (int)gui.weapon.w) if(i > (int)gui.weapon.w)
// Font is too big. // Font is too big.
f = &gl_smallFont; f = &gl_smallFont;
gl_printMid(f, (int)gui.weapon.w, gl_printMid(f, (int)gui.weapon.w,
gui.weapon.x, gui.weapon.y - (gui.weapon.h - f->h)/2., gui.weapon.x, gui.weapon.y - (gui.weapon.h - f->h)/2.,
&cConsole, "%s", player->secondary->outfit->name); &cConsole, "%s", player->secondary->outfit->name);
} }
} }
// Target. // Target.
@ -511,67 +511,67 @@ void player_render(void) {
p = pilot_get(player_target); p = pilot_get(player_target);
gl_blitStatic(p->ship->gfx_target, gui.target.x, gui.target.y, NULL); gl_blitStatic(p->ship->gfx_target, gui.target.x, gui.target.y, NULL);
// Target name. // Target name.
gl_print(NULL, gui.target_name.x, gui.target_name.y, gl_print(NULL, gui.target_name.x, gui.target_name.y,
NULL, "%s", p->name); NULL, "%s", p->name);
gl_print(&gl_smallFont, gui.target_faction.x, gui.target_faction.y, gl_print(&gl_smallFont, gui.target_faction.x, gui.target_faction.y,
NULL, "%s", p->faction->name); NULL, "%s", p->faction->name);
// Target status. // Target status.
if(pilot_isDisabled(p)) if(pilot_isDisabled(p))
// Disable the pilot. // Disable the pilot.
gl_print(&gl_smallFont, gui.target_health.x, gui.target_health.y, gl_print(&gl_smallFont, gui.target_health.x, gui.target_health.y,
NULL, "Disabled"); NULL, "Disabled");
else if(p->shield > p->shield_max / 100.) else if(p->shield > p->shield_max / 100.)
// On shields. // On shields.
gl_print(&gl_smallFont, gui.target_health.x, gui.target_health.y, gl_print(&gl_smallFont, gui.target_health.x, gui.target_health.y,
NULL, "%s: %.0f%%", "Shield", p->shield/p->shield_max*100.); NULL, "%s: %.0f%%", "Shield", p->shield/p->shield_max*100.);
else else
// On armour. // On armour.
gl_print(&gl_smallFont, gui.target_health.x, gui.target_health.y, gl_print(&gl_smallFont, gui.target_health.x, gui.target_health.y,
NULL, "%s: %.0f%%", "Armor", p->armour/p->armour_max*100.); NULL, "%s: %.0f%%", "Armor", p->armour/p->armour_max*100.);
} else { } else {
// No target. // No target.
gl_printMid(NULL, SHIP_TARGET_W, gui.target.x, gl_printMid(NULL, SHIP_TARGET_W, gui.target.x,
gui.target.y + (SHIP_TARGET_H - gl_defFont.h)/2., gui.target.y + (SHIP_TARGET_H - gl_defFont.h)/2.,
&cGrey80, "No Target"); &cGrey80, "No Target");
} }
// Misc. // 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, gl_print(NULL, gui.misc.x + 8, j,
&cConsole, "SCreds:"); &cConsole, "SCreds:");
credits2str(str, player_credits, 2); credits2str(str, player_credits, 2);
i = gl_printWidth(&gl_smallFont, str); i = gl_printWidth(&gl_smallFont, str);
gl_print(&gl_smallFont, gui.misc.x + gui.misc.w - 8 - i, j, gl_print(&gl_smallFont, gui.misc.x + gui.misc.w - 8 - i, j,
NULL, str); NULL, str);
// Cargo and co. // Cargo and co.
if(player->ncommodities > 0) { 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);
}
}
j -= gl_smallFont.h + 5; j -= gl_smallFont.h + 5;
gl_print(&gl_smallFont, gl_print(&gl_smallFont,
gui.misc.x + 8, j, &cConsole, "Cargo"); gui.misc.x + 8, j, &cConsole, "Free:");
for(i = 0; i < MIN(player->ncommodities,3); i++) { i = gl_printWidth(&gl_smallFont, "%d", player->ship->cap_cargo);
j -= gl_smallFont.h + 3; gl_print(&gl_smallFont,
gl_print(&gl_smallFont, gui.misc.x + gui.misc.w - 8 - i, j,
gui.misc.x + 13, j, NULL, "%d", player->cargo_free);
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:");
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. // Messages.
x = gui.msg.x; x = gui.msg.x;
@ -586,18 +586,18 @@ void player_render(void) {
} }
// Hyperspace FLASH BANG!!! // Hyperspace FLASH BANG!!!
if(pilot_isFlag(player, PILOT_HYPERSPACE) && !paused) { if(pilot_isFlag(player, PILOT_HYPERSPACE) && !paused) {
i = (int)player->ptimer - HYPERSPACE_FADEOUT; i = (int)player->ptimer - HYPERSPACE_FADEOUT;
j = (int)SDL_GetTicks(); j = (int)SDL_GetTicks();
if(i < j) { if(i < j) {
x = (double)(j-i) / HYPERSPACE_FADEOUT; x = (double)(j-i) / HYPERSPACE_FADEOUT;
glColor4d(1.,1.,1., x); // We'll | I'll, make this more effiecent later. glColor4d(1.,1.,1., x); // We'll | I'll, make this more effiecent later.
glBegin(GL_QUADS); 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.);
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(); glEnd();
} }
} }
} }
@ -614,8 +614,8 @@ static void gui_renderPilot(const Pilot* p) {
if(sy < 1.) sy = 1.; if(sy < 1.) sy = 1.;
if(((gui.radar.shape == RADAR_RECT) && ((ABS(x) > gui.radar.w/2.+sx) if(((gui.radar.shape == RADAR_RECT) && ((ABS(x) > gui.radar.w/2.+sx)
|| (ABS(y) > gui.radar.h/2.+sy))) || ((gui.radar.shape == RADAR_CIRCLE) && || (ABS(y) > gui.radar.h/2.+sy))) || ((gui.radar.shape == RADAR_CIRCLE) &&
((x*x + y*y) > (int)(gui.radar.w*gui.radar.w)))) ((x*x + y*y) > (int)(gui.radar.w*gui.radar.w))))
return; // Pilot isn't in range. return; // Pilot isn't in range.
if(gui.radar.shape == RADAR_RECT) { if(gui.radar.shape == RADAR_RECT) {
@ -628,17 +628,17 @@ static void gui_renderPilot(const Pilot* p) {
} }
glBegin(GL_QUADS); glBegin(GL_QUADS);
// Colours. // Colours.
if(p->id == player_target) COLOUR(cRadar_targ); if(p->id == player_target) COLOUR(cRadar_targ);
else if(pilot_isDisabled(p)) COLOUR(cInert); else if(pilot_isDisabled(p)) COLOUR(cInert);
else if(pilot_isFlag(p, PILOT_HOSTILE)) COLOUR(cHostile); else if(pilot_isFlag(p, PILOT_HOSTILE)) COLOUR(cHostile);
else COLOUR(cNeutral); else COLOUR(cNeutral);
// Image. // Image.
glVertex2d(MAX(x-sx, -w), MIN(y+sy, h)); // Top left. glVertex2d(MAX(x-sx, -w), MIN(y+sy, h)); // Top left.
glVertex2d(MIN(x+sx, w), MIN(y+sy, h)); // Top right. glVertex2d(MIN(x+sx, w), MIN(y+sy, h)); // Top right.
glVertex2d(MIN(x+sx, w), MAX(y-sy, -h)); // Bottom right. glVertex2d(MIN(x+sx, w), MAX(y-sy, -h)); // Bottom right.
glVertex2d(MAX(x-sx, -w), MAX(y-sy, -h)); // Bottom left. glVertex2d(MAX(x-sx, -w), MAX(y-sy, -h)); // Bottom left.
glEnd(); glEnd();
} }
@ -647,15 +647,15 @@ static void gui_renderBar(const glColour* c, const Rect* r, const double w) {
int x, y, sx, sy; int x, y, sx, sy;
glBegin(GL_QUADS); glBegin(GL_QUADS);
COLOUR(*c); COLOUR(*c);
x = r->x - gl_screen.w/2.; x = r->x - gl_screen.w/2.;
y = r->y - gl_screen.h/2.; y = r->y - gl_screen.h/2.;
sx = w * r->w; sx = w * r->w;
sy = r->h; sy = r->h;
glVertex2d(x, y); glVertex2d(x, y);
glVertex2d(x+sx, y); glVertex2d(x+sx, y);
glVertex2d(x+sx, y-sy); glVertex2d(x+sx, y-sy);
glVertex2d(x, y-sy); glVertex2d(x, y-sy);
glEnd(); glEnd();
} }
@ -727,14 +727,14 @@ int gui_load(const char* name) {
} }
static void rect_parse(const xmlNodePtr parent, double* x, double* y, static void rect_parse(const xmlNodePtr parent, double* x, double* y,
double* w, double* h) { double* w, double* h) {
xmlNodePtr cur; xmlNodePtr cur;
int param; int param;
param = 0; param = 0;
cur = parent->children; cur = parent->children;
do { do {
if(xml_isNode(cur, "x")) { if(xml_isNode(cur, "x")) {
if(x != NULL) { if(x != NULL) {
@ -779,7 +779,7 @@ static void rect_parse(const xmlNodePtr parent, double* x, double* y,
// Parse a gui node. // Parse a gui node.
#define RELATIVIZE(a) \ #define RELATIVIZE(a) \
{ (a).x += VX(gui.frame); (a).y = VY(gui.frame) + gui.gfx_frame->h-(a).y; } { (a).x += VX(gui.frame); (a).y = VY(gui.frame) + gui.gfx_frame->h-(a).y; }
static int gui_parse(const xmlNodePtr parent, const char* name) { static int gui_parse(const xmlNodePtr parent, const char* name) {
xmlNodePtr cur, node; xmlNodePtr cur, node;
char* tmp, *tmp2; char* tmp, *tmp2;
@ -810,8 +810,8 @@ static int gui_parse(const xmlNodePtr parent, const char* name) {
// Frame (based on gfx). // Frame (based on gfx).
vect_csetmin(&gui.frame, vect_csetmin(&gui.frame,
gl_screen.w - gui.gfx_frame->w, // x. gl_screen.w - gui.gfx_frame->w, // x.
gl_screen.h - gui.gfx_frame->h); // h. gl_screen.h - gui.gfx_frame->h); // h.
// Let's parse the data now. // Let's parse the data now.
node = parent->children; node = parent->children;
@ -850,19 +850,19 @@ static int gui_parse(const xmlNodePtr parent, const char* name) {
do { do {
if(xml_isNode(cur, "shield")) { if(xml_isNode(cur, "shield")) {
rect_parse(cur, &gui.shield.x, &gui.shield.y, rect_parse(cur, &gui.shield.x, &gui.shield.y,
&gui.shield.w, &gui.shield.h); &gui.shield.w, &gui.shield.h);
RELATIVIZE(gui.shield); RELATIVIZE(gui.shield);
} }
if(xml_isNode(cur, "armour")) { if(xml_isNode(cur, "armour")) {
rect_parse(cur, &gui.armour.x, &gui.armour.y, rect_parse(cur, &gui.armour.x, &gui.armour.y,
&gui.armour.w, &gui.armour.h); &gui.armour.w, &gui.armour.h);
RELATIVIZE(gui.armour); RELATIVIZE(gui.armour);
} }
if(xml_isNode(cur, "energy")) { if(xml_isNode(cur, "energy")) {
rect_parse(cur, &gui.energy.x, &gui.energy.y, rect_parse(cur, &gui.energy.x, &gui.energy.y,
&gui.energy.w, &gui.energy.h); &gui.energy.w, &gui.energy.h);
RELATIVIZE(gui.energy); RELATIVIZE(gui.energy);
} }
} while((cur = cur->next)); } while((cur = cur->next));
@ -870,7 +870,7 @@ static int gui_parse(const xmlNodePtr parent, const char* name) {
// Secondary weapon. // Secondary weapon.
else if(xml_isNode(node, "weapon")) { else if(xml_isNode(node, "weapon")) {
rect_parse(node, &gui.weapon.x, &gui.weapon.y, rect_parse(node, &gui.weapon.x, &gui.weapon.y,
&gui.weapon.w, &gui.weapon.h); &gui.weapon.w, &gui.weapon.h);
RELATIVIZE(gui.weapon); RELATIVIZE(gui.weapon);
gui.weapon.y -= gl_defFont.h; gui.weapon.y -= gl_defFont.h;
} }
@ -883,23 +883,23 @@ static int gui_parse(const xmlNodePtr parent, const char* name) {
RELATIVIZE(gui.target); RELATIVIZE(gui.target);
gui.target.y -= SHIP_TARGET_H; gui.target.y -= SHIP_TARGET_H;
} }
if(xml_isNode(cur, "name")) { if(xml_isNode(cur, "name")) {
rect_parse(cur, &gui.target_name.x, &gui.target_name.y, NULL, NULL); rect_parse(cur, &gui.target_name.x, &gui.target_name.y, NULL, NULL);
RELATIVIZE(gui.target_name); RELATIVIZE(gui.target_name);
gui.target_name.y -= gl_defFont.h; gui.target_name.y -= gl_defFont.h;
} }
if(xml_isNode(cur, "faction")) { if(xml_isNode(cur, "faction")) {
rect_parse(cur, &gui.target_faction.x, &gui.target_faction.y, rect_parse(cur, &gui.target_faction.x, &gui.target_faction.y,
NULL, NULL); NULL, NULL);
RELATIVIZE(gui.target_faction); RELATIVIZE(gui.target_faction);
gui.target_faction.y -= gl_smallFont.h; gui.target_faction.y -= gl_smallFont.h;
} }
if(xml_isNode(cur, "health")) { if(xml_isNode(cur, "health")) {
rect_parse(cur, &gui.target_health.x, &gui.target_health.y, rect_parse(cur, &gui.target_health.x, &gui.target_health.y,
NULL, NULL); NULL, NULL);
RELATIVIZE(gui.target_health); RELATIVIZE(gui.target_health);
gui.target_health.y -= gl_smallFont.h; gui.target_health.y -= gl_smallFont.h;
} }
@ -926,25 +926,25 @@ void gui_free(void) {
// Used in pilot.c // Used in pilot.c
// Basically uses keyboard input instead of AI input. // Basically uses keyboard input instead of AI input.
void player_think(Pilot* player) { void player_think(Pilot* player) {
// Last I checked, the dead didn't think.. // Last I checked, the dead didn't think..
if(pilot_isFlag(player, PILOT_DEAD)) return; if(pilot_isFlag(player, PILOT_DEAD)) return;
// PLAYER_FACE will take over navigation. // PLAYER_FACE will take over navigation.
if(player_isFlag(PLAYER_FACE)) { if(player_isFlag(PLAYER_FACE)) {
if(player_target != PLAYER_ID) if(player_target != PLAYER_ID)
pilot_face(player, pilot_face(player,
vect_angle(&player->solid->pos, vect_angle(&player->solid->pos,
&pilot_get(player_target)->solid->pos)); &pilot_get(player_target)->solid->pos));
else if(planet_target != -1) else if(planet_target != -1)
pilot_face(player, pilot_face(player,
vect_angle(&player->solid->pos, vect_angle(&player->solid->pos,
&cur_system->planets[planet_target].pos)); &cur_system->planets[planet_target].pos));
} }
// PLAYER_REVERSE will take over navigation. // PLAYER_REVERSE will take over navigation.
else if(player_isFlag(PLAYER_REVERSE) && (VMOD(player->solid->vel) > 0.)) else if(player_isFlag(PLAYER_REVERSE) && (VMOD(player->solid->vel) > 0.))
pilot_face(player, VANGLE(player->solid->vel) + M_PI); pilot_face(player, VANGLE(player->solid->vel) + M_PI);
// Normal navigation sheme. // Normal navigation sheme.
else { else {
player->solid->dir_vel = 0.; player->solid->dir_vel = 0.;
@ -956,25 +956,25 @@ void player_think(Pilot* player) {
if(player_isFlag(PLAYER_SECONDARY)) // Needs a target. if(player_isFlag(PLAYER_SECONDARY)) // Needs a target.
pilot_shoot(player, player_target, 1); pilot_shoot(player, player_target, 1);
if(player_isFlag(PLAYER_AFTERBURNER)) if(player_isFlag(PLAYER_AFTERBURNER))
vect_pset(&player->solid->force, vect_pset(&player->solid->force,
player->thrust * player->afterburner->outfit->u.afb.thrust_perc + player->thrust * player->afterburner->outfit->u.afb.thrust_perc +
player->afterburner->outfit->u.afb.thrust_abs, player->solid->dir); player->afterburner->outfit->u.afb.thrust_abs, player->solid->dir);
else else
vect_pset(&player->solid->force, player->thrust * player_acc, vect_pset(&player->solid->force, player->thrust * player_acc,
player->solid->dir); player->solid->dir);
// Set the listener stuff. // Set the listener stuff.
sound_listener(player->solid->dir, sound_listener(player->solid->dir,
player->solid->pos.x, player->solid->pos.y, player->solid->pos.x, player->solid->pos.y,
player->solid->vel.x, player->solid->vel.y); player->solid->vel.x, player->solid->vel.y);
} }
// Modify the radar resolution. // Modify the radar resolution.
void player_setRadarRel(int mod) { void player_setRadarRel(int mod) {
gui.radar.res += mod * RADAR_RES_INTERVAL; gui.radar.res += mod * RADAR_RES_INTERVAL;
if(gui.radar.res > RADAR_RES_MAX) gui.radar.res = RADAR_RES_MAX; 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; 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);
} }
@ -1007,7 +1007,7 @@ void player_secondaryNext(void) {
// Cycle through planet targets. // Cycle through planet targets.
void player_targetPlanet(void) { void player_targetPlanet(void) {
hyperspace_target = -1; hyperspace_target = -1;
player_rmFlag(PLAYER_LANDACK); player_rmFlag(PLAYER_LANDACK);
if((planet_target == -1) && (cur_system->nplanets > 0)) { if((planet_target == -1) && (cur_system->nplanets > 0)) {
// No target. // No target.
@ -1031,26 +1031,26 @@ void player_land(void) {
} }
Planet* planet = &cur_system->planets[planet_target]; Planet* planet = &cur_system->planets[planet_target];
if(planet_target >= 0) { if(planet_target >= 0) {
if(!planet_hasService(planet, PLANET_SERVICE_LAND)) { if(!planet_hasService(planet, PLANET_SERVICE_LAND)) {
player_message("You can't land here."); player_message("You can't land here.");
return; return;
} }
else if(!player_isFlag(PLAYER_LANDACK)) { else if(!player_isFlag(PLAYER_LANDACK)) {
// No landing authorization. // No landing authorization.
if(!areEnemies(player->faction, planet->faction)) { if(!areEnemies(player->faction, planet->faction)) {
player_message("%s> Permission to land cleared.", planet->name); player_message("%s> Permission to land cleared.", planet->name);
player_setFlag(PLAYER_LANDACK); player_setFlag(PLAYER_LANDACK);
} else { } else {
player_message("%s> Land request denied.", planet->name); player_message("%s> Land request denied.", planet->name);
} }
return; return;
} }
else if(vect_dist(&player->solid->pos, &planet->pos) > planet->gfx_space->sw) { 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); player_message("You are too far away to land on %s", planet->name);
return; return;
} }
else if((pow2(VX(player->solid->vel)) + pow2(VY(player->solid->vel))) > 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); player_message("You are going too fast to land on %s", planet->name);
return; return;
} }
@ -1060,26 +1060,26 @@ void player_land(void) {
int i; int i;
int tp; int tp;
double td, d; double td, d;
td = -1; // Temp distance. td = -1; // Temp distance.
tp = -1; // Temp planet. tp = -1; // Temp planet.
for(i = 0; i < cur_system->nplanets; i++) { for(i = 0; i < cur_system->nplanets; i++) {
d = vect_dist(&player->solid->pos, &cur_system->planets[i].pos); d = vect_dist(&player->solid->pos, &cur_system->planets[i].pos);
if(planet_hasService(&cur_system->planets[i], PLANET_SERVICE_LAND) && if(planet_hasService(&cur_system->planets[i], PLANET_SERVICE_LAND) &&
((tp == -1) || ((td == -1) || (td > d)))) { ((tp == -1) || ((td == -1) || (td > d)))) {
tp = i; tp = i;
td = d; td = d;
} }
} }
planet_target = tp; planet_target = tp;
player_rmFlag(PLAYER_LANDACK); player_rmFlag(PLAYER_LANDACK);
player_land(); // Re-run land protocol. player_land(); // Re-run land protocol.
} }
} }
void player_targetHyperspace(void) { void player_targetHyperspace(void) {
planet_target = -1; // Remove planet target. 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++; hyperspace_target++;
if(hyperspace_target >= cur_system->njumps) if(hyperspace_target >= cur_system->njumps)
@ -1089,10 +1089,10 @@ void player_targetHyperspace(void) {
// Actually attempt to jump into hyperspace. // Actually attempt to jump into hyperspace.
void player_jump(void) { void player_jump(void) {
if((hyperspace_target == -1) || if((hyperspace_target == -1) ||
pilot_isFlag(player, PILOT_HYP_PREP) || pilot_isFlag(player, PILOT_HYP_PREP) ||
pilot_isFlag(player, PILOT_HYP_BEGIN) || pilot_isFlag(player, PILOT_HYP_BEGIN) ||
pilot_isFlag(player, PILOT_HYPERSPACE)) pilot_isFlag(player, PILOT_HYPERSPACE))
return; return;
int i = space_hyperspace(player); int i = space_hyperspace(player);
@ -1111,7 +1111,7 @@ void player_brokeHyperspace(void) {
// Set position, pilot_update will handle the lowering of velocity. // Set position, pilot_update will handle the lowering of velocity.
player_warp(-cos(player->solid->dir) * MIN_HYPERSPACE_DIST * 2.5, player_warp(-cos(player->solid->dir) * MIN_HYPERSPACE_DIST * 2.5,
-sin(player->solid->dir) * MIN_HYPERSPACE_DIST * 2.5); -sin(player->solid->dir) * MIN_HYPERSPACE_DIST * 2.5);
// Stop hyperspace. // Stop hyperspace.
pilot_rmFlag(player, PILOT_HYPERSPACE | PILOT_HYP_BEGIN | PILOT_HYP_PREP); pilot_rmFlag(player, PILOT_HYPERSPACE | PILOT_HYP_BEGIN | PILOT_HYP_PREP);
@ -1121,29 +1121,29 @@ void player_brokeHyperspace(void) {
// Make the player face her hyperspace target. // Make the player face her hyperspace target.
double player_faceHyperspace(void) { double player_faceHyperspace(void) {
double a; double a;
a = ANGLE(systems_stack[cur_system->jumps[hyperspace_target]].pos.x - a = ANGLE(systems_stack[cur_system->jumps[hyperspace_target]].pos.x -
cur_system->pos.x, cur_system->pos.x,
systems_stack[cur_system->jumps[hyperspace_target]].pos.y - systems_stack[cur_system->jumps[hyperspace_target]].pos.y -
cur_system->pos.y); cur_system->pos.y);
return pilot_face(player, a); return pilot_face(player, a);
} }
// Activate afterburner. // Activate afterburner.
void player_afterburn(void) { void player_afterburn(void) {
// TODO: Fancy effects. // TODO: Fancy effects.
if(player->afterburner != NULL) { if(player->afterburner != NULL) {
player_setFlag(PLAYER_AFTERBURNER); player_setFlag(PLAYER_AFTERBURNER);
pilot_setFlag(player, PILOT_AFTERBURNER); pilot_setFlag(player, PILOT_AFTERBURNER);
} }
} }
void player_afterburnOver(void) { void player_afterburnOver(void) {
if(player->afterburner != NULL) { if(player->afterburner != NULL) {
player_rmFlag(PLAYER_AFTERBURNER); player_rmFlag(PLAYER_AFTERBURNER);
pilot_rmFlag(player, PILOT_AFTERBURNER); pilot_rmFlag(player, PILOT_AFTERBURNER);
} }
} }
// Take a screenshot. // Take a screenshot.
@ -1162,7 +1162,7 @@ void player_screenshot(void) {
return; return;
} }
snprintf(filename, PATH_MAX, "../screenshots/screenshot%03d.png", 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. fp = fopen(filename, "r"); // Myeah, I know it's a horrible way to check.
if(fp == NULL) done = 1; if(fp == NULL) done = 1;
else { else {
@ -1180,15 +1180,15 @@ void player_screenshot(void) {
// Player go pwned. // Player go pwned.
void player_dead(void) { void player_dead(void) {
gui_xoff = 0.; gui_xoff = 0.;
gui_yoff = 0.; gui_yoff = 0.;
} }
// Player blew up in a nice fireball. // Player blew up in a nice fireball.
void player_destroyed(void) { void player_destroyed(void) {
vectcpy(&player_cam, &player->solid->pos); vectcpy(&player_cam, &player->solid->pos);
gl_bindCamera(&player_cam); gl_bindCamera(&player_cam);
player_setFlag(PLAYER_DESTROYED); player_setFlag(PLAYER_DESTROYED);
player_timer = SDL_GetTicks() + 5000; player_timer = SDL_GetTicks() + 5000;
} }

View File

@ -2,15 +2,15 @@
#include "pilot.h" #include "pilot.h"
// Flag definitions. // Flag definitions.
#define PLAYER_TURN_LEFT (1<<0) // Player is turning left. #define PLAYER_TURN_LEFT (1<<0) // Player is turning left.
#define PLAYER_TURN_RIGHT (1<<1) // Player is turning right. #define PLAYER_TURN_RIGHT (1<<1) // Player is turning right.
#define PLAYER_REVERSE (1<<2) // Player is facint opposite vel. #define PLAYER_REVERSE (1<<2) // Player is facint opposite vel.
#define PLAYER_AFTERBURNER (1<<3) // Player is burning it up. #define PLAYER_AFTERBURNER (1<<3) // Player is burning it up.
#define PLAYER_DESTROYED (1<<9) // Player goes BOOM! #define PLAYER_DESTROYED (1<<9) // Player goes BOOM!
#define PLAYER_FACE (1<<10) // Player is facing target. #define PLAYER_FACE (1<<10) // Player is facing target.
#define PLAYER_PRIMARY (1<<11) // Player is shooting primary weapon. #define PLAYER_PRIMARY (1<<11) // Player is shooting primary weapon.
#define PLAYER_SECONDARY (1<<12) // Player is shooting secondary weapon. #define PLAYER_SECONDARY (1<<12) // Player is shooting secondary weapon.
#define PLAYER_LANDACK (1<<13) // Player has permission to land. #define PLAYER_LANDACK (1<<13) // Player has permission to land.
// Flag functions. // Flag functions.
#define player_isFlag(f) (player_flags & f) #define player_isFlag(f) (player_flags & f)

View File

@ -33,7 +33,7 @@ Ship* ship_get(const char* name) {
int i; int i;
for(i = 0; i < ships; i++) for(i = 0; i < ships; i++)
if(strcmp((tmp+i)->name, name)==0) break; if(strcmp((tmp+i)->name, name)==0) break;
if(i == ships) // Ship doesn't exist, game will probably crash now. if(i == ships) // Ship doesn't exist, game will probably crash now.
WARN("Ship %s does not exist", name); WARN("Ship %s does not exist", name);
@ -42,37 +42,37 @@ Ship* ship_get(const char* name) {
// Get the ship's classname. // Get the ship's classname.
static char* ship_classes[] = { static char* ship_classes[] = {
"NULL", "NULL",
"Civialian Light", "Civilian Medium", "Civilian Heavy" "Civialian Light", "Civilian Medium", "Civilian Heavy"
"Military Light", "Military Medium", "Military Heavy" "Military Light", "Military Medium", "Military Heavy"
"Robotic Light", "Robotic Medium", "Robotic Heavy" "Robotic Light", "Robotic Medium", "Robotic Heavy"
"Hybrid Light", "Hybrid Medium", "Hybrid Heavy" "Hybrid Light", "Hybrid Medium", "Hybrid Heavy"
}; };
// Return all the ships in text form. // Return all the ships in text form.
char** ship_getTech(int* n, const int* tech, const int techmax) { char** ship_getTech(int* n, const int* tech, const int techmax) {
int i, j; int i, j;
char** shipnames = malloc(sizeof(Ship*) * ships); char** shipnames = malloc(sizeof(Ship*) * ships);
*n = 0; *n = 0;
for(i = 0; i < ships; i++) for(i = 0; i < ships; i++)
if(ship_stack[i].tech <= tech[0]) { if(ship_stack[i].tech <= tech[0]) {
shipnames[*n] = strdup(ship_stack[i].name); shipnames[*n] = strdup(ship_stack[i].name);
(*n)++; (*n)++;
} else { } else {
for(j = 0; j < techmax; j++) for(j = 0; j < techmax; j++)
if(tech[j] == ship_stack[i].tech) { if(tech[j] == ship_stack[i].tech) {
shipnames[*n] = strdup(ship_stack[i].name); shipnames[*n] = strdup(ship_stack[i].name);
(*n)++; (*n)++;
}
} }
}
return shipnames;
return shipnames;
} }
char* ship_class(Ship* s) { char* ship_class(Ship* s) {
return ship_classes[s->class]; return ship_classes[s->class];
} }
static Ship* ship_parse(xmlNodePtr parent) { static Ship* ship_parse(xmlNodePtr parent) {
@ -81,7 +81,7 @@ static Ship* ship_parse(xmlNodePtr parent) {
ShipOutfit* otmp, *ocur; ShipOutfit* otmp, *ocur;
char str[PATH_MAX] = "\0"; char str[PATH_MAX] = "\0";
char* stmp; char* stmp;
tmp->name = xml_nodeProp(parent, "name"); tmp->name = xml_nodeProp(parent, "name");
if(tmp->name == NULL) WARN("Ship in "SHIP_DATA" has invalid or no 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 { do {
// Load all the data. // Load all the data.
if(xml_isNode(node,"GFX")) { if(xml_isNode(node,"GFX")) {
snprintf(str, strlen(xml_get(node)) + snprintf(str, strlen(xml_get(node)) +
sizeof(SHIP_GFX) + sizeof(SHIP_EXT), sizeof(SHIP_GFX) + sizeof(SHIP_EXT),
SHIP_GFX"%s"SHIP_EXT, xml_get(node)); SHIP_GFX"%s"SHIP_EXT, xml_get(node));
tmp->gfx_space = gl_newSprite(str, 6, 6); tmp->gfx_space = gl_newSprite(str, 6, 6);
// Target. // Target.
snprintf(str, strlen(xml_get(node)) + 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)); SHIP_GFX"%s"SHIP_TARGET SHIP_EXT, xml_get(node));
tmp->gfx_target = gl_newImage(str); tmp->gfx_target = gl_newImage(str);
} }
else if(xml_isNode(node, "GUI")) else if(xml_isNode(node, "GUI"))
tmp->gui = strdup(xml_get(node)); tmp->gui = strdup(xml_get(node));
else if(xml_isNode(node, "sound")) else if(xml_isNode(node, "sound"))
tmp->sound = sound_get(xml_get(node)); tmp->sound = sound_get(xml_get(node));
else if(xml_isNode(node, "class")) else if(xml_isNode(node, "class"))
tmp->class = xml_getInt(node); tmp->class = xml_getInt(node);
else if(xml_isNode(node, "price")) else if(xml_isNode(node, "price"))
tmp->price = xml_getInt(node); tmp->price = xml_getInt(node);
else if(xml_isNode(node, "tech")) else if(xml_isNode(node, "tech"))
tmp->tech = xml_getInt(node); tmp->tech = xml_getInt(node);
else if(xml_isNode(node, "fabricator")) else if(xml_isNode(node, "fabricator"))
tmp->fabricator = strdup(xml_get(node)); tmp->fabricator = strdup(xml_get(node));
else if(xml_isNode(node, "description")) else if(xml_isNode(node, "description"))
tmp->description = strdup(xml_get(node)); tmp->description = strdup(xml_get(node));
else if(xml_isNode(node, "movement")) { else if(xml_isNode(node, "movement")) {
cur = node->children; cur = node->children;
do { do {
@ -142,19 +142,19 @@ static Ship* ship_parse(xmlNodePtr parent) {
tmp->shield_regen = (double)(xml_getInt(cur))/60.0; tmp->shield_regen = (double)(xml_getInt(cur))/60.0;
else if(xml_isNode(cur, "energy_regen")) else if(xml_isNode(cur, "energy_regen"))
tmp->energy_regen = (double)(xml_getInt(cur))/60.0; tmp->energy_regen = (double)(xml_getInt(cur))/60.0;
} while((cur = cur->next)); } while((cur = cur->next));
} }
else if(xml_isNode(node, "characteristics")) { else if(xml_isNode(node, "characteristics")) {
cur = node->children; cur = node->children;
do { do {
if(xml_isNode(cur, "crew")) if(xml_isNode(cur, "crew"))
tmp->crew = xml_getInt(cur); tmp->crew = xml_getInt(cur);
else if(xml_isNode(cur, "mass")) else if(xml_isNode(cur, "mass"))
tmp->mass = (double)xml_getInt(cur); tmp->mass = (double)xml_getInt(cur);
else if(xml_isNode(cur, "cap_weapon")) else if(xml_isNode(cur, "cap_weapon"))
tmp->cap_weapon = xml_getInt(cur); tmp->cap_weapon = xml_getInt(cur);
else if(xml_isNode(cur, "cap_cargo")) else if(xml_isNode(cur, "cap_cargo"))
tmp->cap_cargo = xml_getInt(cur); tmp->cap_cargo = xml_getInt(cur);
} while((cur = cur->next)); } while((cur = cur->next));
} }
else if(xml_isNode(node, "outfits")) { else if(xml_isNode(node, "outfits")) {
@ -166,7 +166,7 @@ static Ship* ship_parse(xmlNodePtr parent) {
stmp = xml_nodeProp(cur, "quantity"); stmp = xml_nodeProp(cur, "quantity");
if(!stmp) if(!stmp)
WARN("Ship '%s' is missing tag 'quantity for outfit '%s'", WARN("Ship '%s' is missing tag 'quantity for outfit '%s'",
tmp->name, otmp->data->name); tmp->name, otmp->data->name);
otmp->quantity = atoi(stmp); otmp->quantity = atoi(stmp);
free(stmp); free(stmp);
otmp->next = NULL; otmp->next = NULL;
@ -180,31 +180,31 @@ static Ship* ship_parse(xmlNodePtr parent) {
} while((cur = cur->next)); } while((cur = cur->next));
} }
} while((node = node->next)); } while((node = node->next));
tmp->thrust *= tmp->mass; // Helps keep number sane. tmp->thrust *= tmp->mass; // Helps keep number sane.
#define MELEMENT(o,s) if(o) WARN("Ship '%s' missing '"s"' element", tmp->name) #define MELEMENT(o,s) if(o) WARN("Ship '%s' missing '"s"' element", tmp->name)
MELEMENT(tmp->name == NULL, "name"); MELEMENT(tmp->name == NULL, "name");
MELEMENT(tmp->gfx_space == NULL, "GFX"); MELEMENT(tmp->gfx_space == NULL, "GFX");
MELEMENT(tmp->gui == NULL, "GUI"); MELEMENT(tmp->gui == NULL, "GUI");
MELEMENT(tmp->class==0, "class"); MELEMENT(tmp->class==0, "class");
MELEMENT(tmp->price==0, "price"); MELEMENT(tmp->price==0, "price");
MELEMENT(tmp->tech==0, "tech"); MELEMENT(tmp->tech==0, "tech");
MELEMENT(tmp->fabricator==0, "fabricator"); MELEMENT(tmp->fabricator==0, "fabricator");
MELEMENT(tmp->description==0, "description"); MELEMENT(tmp->description==0, "description");
MELEMENT(tmp->thrust==0, "thrust"); MELEMENT(tmp->thrust==0, "thrust");
MELEMENT(tmp->turn==0, "turn"); MELEMENT(tmp->turn==0, "turn");
MELEMENT(tmp->speed==0, "speed"); MELEMENT(tmp->speed==0, "speed");
MELEMENT(tmp->armour==0, "armour"); MELEMENT(tmp->armour==0, "armour");
MELEMENT(tmp->armour_regen==0, "armour_regen"); MELEMENT(tmp->armour_regen==0, "armour_regen");
MELEMENT(tmp->shield==0, "shield"); MELEMENT(tmp->shield==0, "shield");
MELEMENT(tmp->shield_regen==0, "shield_regen"); MELEMENT(tmp->shield_regen==0, "shield_regen");
MELEMENT(tmp->energy==0, "energy"); MELEMENT(tmp->energy==0, "energy");
MELEMENT(tmp->energy_regen==0, "energt_regen"); MELEMENT(tmp->energy_regen==0, "energt_regen");
MELEMENT(tmp->crew==0, "crew"); MELEMENT(tmp->crew==0, "crew");
MELEMENT(tmp->mass==0, "mass"); MELEMENT(tmp->mass==0, "mass");
MELEMENT(tmp->cap_cargo==0, "cap_cargo"); MELEMENT(tmp->cap_cargo==0, "cap_cargo");
MELEMENT(tmp->cap_weapon==0, "cap_weapon"); MELEMENT(tmp->cap_weapon==0, "cap_weapon");
#undef MELEMENT #undef MELEMENT
return tmp; return tmp;
@ -216,7 +216,7 @@ int ships_load(void) {
xmlNodePtr node; xmlNodePtr node;
xmlDocPtr doc = xmlParseMemory(buf, bufsize); xmlDocPtr doc = xmlParseMemory(buf, bufsize);
Ship* tmp = NULL; Ship* tmp = NULL;
node = doc->xmlChildrenNode; // Ships node. node = doc->xmlChildrenNode; // Ships node.
@ -230,7 +230,7 @@ int ships_load(void) {
ERR("Malformed "SHIP_DATA" file: Does not contain elements"); ERR("Malformed "SHIP_DATA" file: Does not contain elements");
return -1; return -1;
} }
do { do {
if(node->type == XML_NODE_START && strcmp((char*)node->name, XML_SHIP)==0) { if(node->type == XML_NODE_START && strcmp((char*)node->name, XML_SHIP)==0) {
tmp = ship_parse(node); tmp = ship_parse(node);
@ -244,7 +244,7 @@ int ships_load(void) {
free(buf); free(buf);
xmlCleanupParser(); xmlCleanupParser();
DEBUG("Loaded %d ship%s", ships, (ships==1) ? "" : "s"); DEBUG("Loaded %d ship%s", ships, (ships==1) ? "" : "s");
return 0; return 0;
} }
@ -255,7 +255,7 @@ void ships_free(void) {
for(i = 0; i < ships; i++) { for(i = 0; i < ships; i++) {
// Free stored strings. // Free stored strings.
if((ship_stack+i)->name) free(ship_stack[i].name); if((ship_stack+i)->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); if((ship_stack+i)->gui) free(ship_stack[i].gui);
so = (ship_stack+i)->outfit; so = (ship_stack+i)->outfit;
while(so) { // free the ship outfit. while(so) { // free the ship outfit.
@ -272,62 +272,62 @@ void ships_free(void) {
// Used to visualize the ships status. // Used to visualize the ships status.
void ship_view(char* shipname) { void ship_view(char* shipname) {
Ship* s; Ship* s;
char buf[1024]; char buf[1024];
unsigned int wid; unsigned int wid;
wid = window_create(shipname, -1, -1, VIEW_WIDTH, VIEW_HEIGHT); wid = window_create(shipname, -1, -1, VIEW_WIDTH, VIEW_HEIGHT);
s = ship_get(shipname); s = ship_get(shipname);
window_addText(wid, 20, 0, 100, VIEW_HEIGHT-40, window_addText(wid, 20, 0, 100, VIEW_HEIGHT-40,
0, "txtLabel", &gl_smallFont, &cDConsole, 0, "txtLabel", &gl_smallFont, &cDConsole,
"Name:\n" "Name:\n"
"Class:\n" "Class:\n"
"Crew:\n" "Crew:\n"
"Mass:\n" "Mass:\n"
"\n" "\n"
"Thrust:\n" "Thrust:\n"
"Max Speed:\n" "Max Speed:\n"
"Turn:\n" "Turn:\n"
"\n" "\n"
"Shield:\n" "Shield:\n"
"Armour:\n" "Armour:\n"
"Energy:\n" "Energy:\n"
"\n" "\n"
"Weapon Space:\n" "Weapon Space:\n"
"Cargo Space:\n"); "Cargo Space:\n");
snprintf(buf, 1024, snprintf(buf, 1024,
"%s\n" "%s\n"
"%s\n" "%s\n"
"%d\n" "%d\n"
"%d Tons\n" "%d Tons\n"
"\n" "\n"
"%.2f MN\n" "%.2f MN\n"
"%.2f M/s\n" "%.2f M/s\n"
"%.2f Grad/s\n" "%.2f Grad/s\n"
"\n" "\n"
"%.2f MJ (%.2f MJ/s)\n)" "%.2f MJ (%.2f MJ/s)\n)"
"%.2f MJ (%.2f MJ/s)\n)" "%.2f MJ (%.2f MJ/s)\n)"
"%.2f MJ (%.2f MJ/s)\n)" "%.2f MJ (%.2f MJ/s)\n)"
"\n" "\n"
"%d Tons\n" "%d Tons\n"
"%d Tons\n", "%d Tons\n",
s->name, ship_class(s), s->crew, s->mass, s->name, ship_class(s), s->crew, s->mass,
s->thrust/s->mass, s->speed, s->turn, s->thrust/s->mass, s->speed, s->turn,
s->shield, s->shield_regen, s->armour, s->armour_regen, s->shield, s->shield_regen, s->armour, s->armour_regen,
s->energy, s->energy_regen, s->cap_weapon, s->cap_cargo); s->energy, s->energy_regen, s->cap_weapon, s->cap_cargo);
window_addText(wid, 120, 0, VIEW_WIDTH-140, VIEW_HEIGHT-40, window_addText(wid, 120, 0, VIEW_WIDTH-140, VIEW_HEIGHT-40,
0, "txtProperties", &gl_smallFont, &cBlack, buf); 0, "txtProperties", &gl_smallFont, &cBlack, buf);
// Close the button. // Close the button.
snprintf(buf, 37, "close%s", shipname); snprintf(buf, 37, "close%s", shipname);
window_addButton(wid, -20, 20, window_addButton(wid, -20, 20,
BUTTON_WIDTH, BUTTON_HEIGHT, BUTTON_WIDTH, BUTTON_HEIGHT,
buf, "Close", ship_view_close); buf, "Close", ship_view_close);
} }
static void ship_view_close(char* btn) { 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

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

View File

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

View File

@ -7,16 +7,16 @@
// Virtual voice. // Virtual voice.
typedef struct alVoice_ { typedef struct alVoice_ {
ALuint source; // Source itself, 0 if not set. ALuint source; // Source itself, 0 if not set.
ALuint buffer; // Buffer. ALuint buffer; // Buffer.
int priority; // Base priority. int priority; // Base priority.
double px, py; // Position. double px, py; // Position.
double vx, vy; // Velocity. double vx, vy; // Velocity.
unsigned int start; // Time started in ms. unsigned int start; // Time started in ms.
unsigned int flags; // Flags to set properties. unsigned int flags; // Flags to set properties.
} alVoice; } alVoice;
// Sound subsystem. // Sound subsystem.
@ -30,7 +30,7 @@ void sound_volume(const double vol);
// Voice manipulation function. // Voice manipulation function.
alVoice* sound_addVoice(int priority, double px, double py, double vx, double vy, 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 sound_delVoice(alVoice* voice);
void voice_update(alVoice* voice, double px, double py, double vx, double vy); void voice_update(alVoice* voice, double px, double py, double vx, double vy);

View File

@ -35,8 +35,8 @@
#define FLAG_YSET (1<<1) #define FLAG_YSET (1<<1)
#define FLAG_ASTEROIDSSET (1<<2) #define FLAG_ASTEROIDSSET (1<<2)
#define FLAG_INTEFERENCESET (1<<3) #define FLAG_INTEFERENCESET (1<<3)
#define FLAG_SERVICESET (1<<4) #define FLAG_SERVICESET (1<<4)
#define FLAG_TECHSET (1<<5) #define FLAG_TECHSET (1<<5)
// Star system stack and co. // Star system stack and co.
StarSystem* systems_stack = NULL; // Star system stack. StarSystem* systems_stack = NULL; // Star system stack.
@ -74,9 +74,9 @@ extern void player_message(const char* fmt, ...);
// Draw the planet. Used in planet.c // Draw the planet. Used in planet.c
// Matrix mode is already displaced to center of the minimap. // Matrix mode is already displaced to center of the minimap.
#define PIXEL(x,y) if((shape == RADAR_RECT && ABS(x)<w/2. && ABS(y)<h/2.) || \ #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)) (shape == RADAR_CIRCLE && (((x)*(x)+(y)*(y)) < rc))) glVertex2i((x),(y))
void planets_minimap(const double res, 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 i;
int cx, cy, x, y, r, rc; int cx, cy, x, y, r, rc;
double p; double p;
@ -84,42 +84,42 @@ void planets_minimap(const double res,
if(shape == RADAR_CIRCLE) rc = (int)(w*w); if(shape == RADAR_CIRCLE) rc = (int)(w*w);
glBegin(GL_POINTS); glBegin(GL_POINTS);
for(i = 0; i < cur_system->nplanets; i++) { for(i = 0; i < cur_system->nplanets; i++) {
if(areEnemies(player->faction, cur_system->planets[i].faction)) if(areEnemies(player->faction, cur_system->planets[i].faction))
COLOUR(cHostile); COLOUR(cHostile);
else if(areAllies(player->faction, cur_system->planets[i].faction)) else if(areAllies(player->faction, cur_system->planets[i].faction))
COLOUR(cFriend); COLOUR(cFriend);
else COLOUR(cNeutral); else COLOUR(cNeutral);
r = (int)(cur_system->planets[i].gfx_space->sw / res); r = (int)(cur_system->planets[i].gfx_space->sw / res);
cx = (int)((cur_system->planets[i].pos.x - player->solid->pos.x) / 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); cy = (int)((cur_system->planets[i].pos.y - player->solid->pos.y) / res);
x = 0; x = 0;
y = r; y = r;
p = (5. - (double)(r*3)) / 4.; p = (5. - (double)(r*3)) / 4.;
PIXEL(cx, cy+y); PIXEL(cx, cy+y);
PIXEL(cx, cy-y); PIXEL(cx, cy-y);
PIXEL(cx+y, cy); PIXEL(cx+y, cy);
PIXEL(cx-y, cy); PIXEL(cx-y, cy);
while(x < y) { while(x < y) {
x++; x++;
if(p < 0) p += 2*(double)(x)+1; if(p < 0) p += 2*(double)(x)+1;
else p += 2*(double)(x-(--y))+1; else p += 2*(double)(x-(--y))+1;
if(x == 0) { if(x == 0) {
PIXEL(cx, cy+y); PIXEL(cx, cy+y);
PIXEL(cx, cy-y); PIXEL(cx, cy-y);
PIXEL(cx+y, cy); PIXEL(cx+y, cy);
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 } 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) { if(x < y) {
PIXEL(cx+x, cy+y); PIXEL(cx+x, cy+y);
PIXEL(cx-x, cy+y); PIXEL(cx-x, cy+y);
@ -130,8 +130,8 @@ void planets_minimap(const double res,
PIXEL(cx+y, cy-x); PIXEL(cx+y, cy-x);
PIXEL(cx-y, cy-x); PIXEL(cx-y, cy-x);
} }
}
} }
}
glEnd(); glEnd();
} }
#undef PIXEL #undef PIXEL
@ -139,34 +139,34 @@ void planets_minimap(const double res,
static PlanetClass planetclass_get(const char a) { static PlanetClass planetclass_get(const char a) {
switch(a) { switch(a) {
// Planets use letters. // Planets use letters.
case 'A': return PLANET_CLASS_A; case 'A': return PLANET_CLASS_A;
case 'B': return PLANET_CLASS_B; case 'B': return PLANET_CLASS_B;
case 'C': return PLANET_CLASS_C; case 'C': return PLANET_CLASS_C;
case 'D': return PLANET_CLASS_D; case 'D': return PLANET_CLASS_D;
case 'E': return PLANET_CLASS_E; case 'E': return PLANET_CLASS_E;
case 'F': return PLANET_CLASS_F; case 'F': return PLANET_CLASS_F;
case 'G': return PLANET_CLASS_G; case 'G': return PLANET_CLASS_G;
case 'H': return PLANET_CLASS_H; case 'H': return PLANET_CLASS_H;
case 'I': return PLANET_CLASS_I; case 'I': return PLANET_CLASS_I;
case 'J': return PLANET_CLASS_J; case 'J': return PLANET_CLASS_J;
case 'K': return PLANET_CLASS_K; case 'K': return PLANET_CLASS_K;
case 'L': return PLANET_CLASS_L; case 'L': return PLANET_CLASS_L;
case 'M': return PLANET_CLASS_M; case 'M': return PLANET_CLASS_M;
case 'N': return PLANET_CLASS_N; case 'N': return PLANET_CLASS_N;
case 'O': return PLANET_CLASS_O; case 'O': return PLANET_CLASS_O;
case 'P': return PLANET_CLASS_P; case 'P': return PLANET_CLASS_P;
case 'Q': return PLANET_CLASS_Q; case 'Q': return PLANET_CLASS_Q;
case 'R': return PLANET_CLASS_R; case 'R': return PLANET_CLASS_R;
case 'S': return PLANET_CLASS_S; case 'S': return PLANET_CLASS_S;
case 'T': return PLANET_CLASS_T; case 'T': return PLANET_CLASS_T;
case 'X': return PLANET_CLASS_X; case 'X': return PLANET_CLASS_X;
case 'Y': return PLANET_CLASS_Y; case 'Y': return PLANET_CLASS_Y;
case 'Z': return PLANET_CLASS_Z; case 'Z': return PLANET_CLASS_Z;
// Stations use numbers as there isn't as many. // Stations use numbers as there isn't as many.
case '0' : return STATION_CLASS_A; case '0' : return STATION_CLASS_A;
default: return PLANET_CLASS_NULL; default: return PLANET_CLASS_NULL;
}; };
} }
@ -194,74 +194,74 @@ int space_hyperspace(Pilot* p) {
// Basically used for spawning fleets. // Basically used for spawning fleets.
void space_update(const double dt) { void space_update(const double dt) {
unsigned int t; unsigned int t;
int i, j, f; 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) if(cur_system->nfleets == 0)
// Please stop checking that there are no fleets. // Please stop checking that there are no fleets.
spawn_timer = t + 300000; spawn_timer = t + 300000;
if(spawn_timer < t) { if(spawn_timer < t) {
// Time to possibly spawn. // Time to possibly spawn.
// Spawn chance is based on overall percentage. // Spawn chance is based on overall percentage.
f = RNG(0, 100*cur_system->nfleets); f = RNG(0, 100*cur_system->nfleets);
j = 0; j = 0;
for(i = 0; i < cur_system->nfleets; i++) { for(i = 0; i < cur_system->nfleets; i++) {
j += cur_system->fleets[i].chance; j += cur_system->fleets[i].chance;
if(f < j) { if(f < j) {
// Add one fleet. // Add one fleet.
space_addFleet(cur_system->fleets[i].fleet); space_addFleet(cur_system->fleets[i].fleet);
break; break;
} }
}
spawn_timer = t + 60000./(float)cur_system->nfleets;
} }
spawn_timer = t + 60000./(float)cur_system->nfleets;
}
} }
// Crate a fleet. // Crate a fleet.
static void space_addFleet(Fleet* fleet) { static void space_addFleet(Fleet* fleet) {
int i; int i;
double a; double a;
Vec2 vv, vp, vn; Vec2 vv, vp, vn;
// Simulate them coming from hyperspace. // Simulate them coming from hyperspace.
vect_pset(&vp, RNG(MIN_HYPERSPACE_DIST, MIN_HYPERSPACE_DIST*1.5), vect_pset(&vp, RNG(MIN_HYPERSPACE_DIST, MIN_HYPERSPACE_DIST*1.5),
RNG(0, 360)*M_PI/180.); RNG(0, 360)*M_PI/180.);
vectnull(&vn); vectnull(&vn);
for(i = 0; i < fleet->npilots; i++) for(i = 0; i < fleet->npilots; i++)
if(RNG(0, 100) <= fleet->pilots[i].chance) { if(RNG(0, 100) <= fleet->pilots[i].chance) {
vect_cadd(&vp, RNG(75, 150) * (RNG(0,1) ? 1 : -1), vect_cadd(&vp, RNG(75, 150) * (RNG(0,1) ? 1 : -1),
RNG(75, 150) * (RNG(0,1) ? 1 : -1)); RNG(75, 150) * (RNG(0,1) ? 1 : -1));
a = vect_angle(&vp, &vn); a = vect_angle(&vp, &vn);
vectnull(&vv); vectnull(&vv);
pilot_create(fleet->pilots[i].ship, pilot_create(fleet->pilots[i].ship,
fleet->pilots[i].name, fleet->pilots[i].name,
fleet->faction, fleet->faction,
fleet->ai, fleet->ai,
a, a,
&vp, &vp,
&vv, &vv,
0); 0);
} }
} }
// Init the system. // Init the system.
void space_init(const char* sysname) { void space_init(const char* sysname) {
int i; int i;
// Cleanup some stuff. // Cleanup some stuff.
player_clear(); // Clears targets. player_clear(); // Clears targets.
pilots_clean(); // Destroy all the current pilots, exept player. pilots_clean(); // Destroy all the current pilots, exept player.
weapon_clear(); // Get rid of all the weapons. weapon_clear(); // Get rid of all the weapons.
spfx_clear(); // Remove of explosions. spfx_clear(); // Remove of explosions.
if((sysname == NULL) && (cur_system == NULL)) if((sysname == NULL) && (cur_system == NULL))
ERR("Cannot reinit system if there is no system previously loaded"); 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. // Set up fleets -> pilots.
for(i = 0; i < cur_system->nfleets; i++) for(i = 0; i < cur_system->nfleets; i++)
if(RNG(0,100) <= (cur_system->fleets[i].chance/2)) // Fleet check (50% chance). if(RNG(0,100) <= (cur_system->fleets[i].chance/2)) // Fleet check (50% chance).
space_addFleet(cur_system->fleets[i].fleet); space_addFleet(cur_system->fleets[i].fleet);
// Start the spawn timer. // Start the spawn timer.
spawn_timer = SDL_GetTicks() + 120000./(float)(cur_system->nfleets+1); spawn_timer = SDL_GetTicks() + 120000./(float)(cur_system->nfleets+1);
} }
// Load the planets of name 'name'. // Load the planets of name 'name'.
static Planet* planet_get(const char* name) { static Planet* planet_get(const char* name) {
int i; int i;
Planet* tmp = NULL; Planet* tmp = NULL;
@ -338,13 +338,13 @@ static Planet* planet_get(const char* name) {
if(xml_isNode(cur, "space")) { if(xml_isNode(cur, "space")) {
// Load space gfx. // Load space gfx.
snprintf(str, strlen(xml_get(cur))+sizeof(PLANET_GFX_SPACE), snprintf(str, strlen(xml_get(cur))+sizeof(PLANET_GFX_SPACE),
PLANET_GFX_SPACE"%s", xml_get(cur)); PLANET_GFX_SPACE"%s", xml_get(cur));
tmp->gfx_space = gl_newImage(str); tmp->gfx_space = gl_newImage(str);
} }
else if(xml_isNode(cur, "exterior")) { else if(xml_isNode(cur, "exterior")) {
// Load land gfx. // Load land gfx.
snprintf(str, strlen(xml_get(cur))+sizeof(PLANET_GFX_EXTERIOR), snprintf(str, strlen(xml_get(cur))+sizeof(PLANET_GFX_EXTERIOR),
PLANET_GFX_EXTERIOR"%s", xml_get(cur)); PLANET_GFX_EXTERIOR"%s", xml_get(cur));
tmp->gfx_exterior = gl_newImage(str); tmp->gfx_exterior = gl_newImage(str);
} }
} while((cur = cur->next)); } while((cur = cur->next));
@ -374,39 +374,39 @@ static Planet* planet_get(const char* name) {
else if(xml_isNode(cur, "bar")) else if(xml_isNode(cur, "bar"))
tmp->bar_description = strdup(xml_get(cur)); tmp->bar_description = strdup(xml_get(cur));
else if(xml_isNode(cur, "services")) { else if(xml_isNode(cur, "services")) {
flags |= FLAG_SERVICESET; flags |= FLAG_SERVICESET;
tmp->services = xml_getInt(cur); tmp->services = xml_getInt(cur);
} }
else if(xml_isNode(cur, "tech")) { else if(xml_isNode(cur, "tech")) {
ccur = cur->children; ccur = cur->children;
do { do {
if(xml_isNode(ccur, "main")) { if(xml_isNode(ccur, "main")) {
flags |= FLAG_TECHSET; flags |= FLAG_TECHSET;
tmp->tech[0] = xml_getInt(ccur); tmp->tech[0] = xml_getInt(ccur);
} }
else if(xml_isNode(ccur, "special")) { else if(xml_isNode(ccur, "special")) {
for(i = 1; i < PLANET_TECH_MAX; i++) for(i = 1; i < PLANET_TECH_MAX; i++)
if(tmp->tech[i]==0) { if(tmp->tech[i]==0) {
tmp->tech[i] = xml_getInt(ccur); tmp->tech[i] = xml_getInt(ccur);
break; break;
} }
if(i == PLANET_TECH_MAX) WARN("Planet '%s' has tooo many" if(i == PLANET_TECH_MAX) WARN("Planet '%s' has tooo many"
"'special tech' entries", tmp->name); "'special tech' entries", tmp->name);
} }
} while((ccur = ccur->next)); } while((ccur = ccur->next));
} }
else if(xml_isNode(cur, "commodities")) { else if(xml_isNode(cur, "commodities")) {
ccur = cur->children; ccur = cur->children;
do { do {
if(xml_isNode(ccur, "commodity")) { if(xml_isNode(ccur, "commodity")) {
tmp->commodities = realloc(tmp->commodities, tmp->commodities = realloc(tmp->commodities,
(tmp->ncommodities+1) * sizeof(Commodity*)); (tmp->ncommodities+1) * sizeof(Commodity*));
tmp->commodities[tmp->ncommodities] = tmp->commodities[tmp->ncommodities] =
commodity_get(xml_get(ccur)); commodity_get(xml_get(ccur));
tmp->ncommodities++; tmp->ncommodities++;
} }
} while((ccur = ccur->next)); } while((ccur = ccur->next));
} }
} while((cur = cur->next)); } while((cur = cur->next));
} }
} while((node = node->next)); } while((node = node->next));
@ -424,24 +424,24 @@ static Planet* planet_get(const char* name) {
if(tmp) { if(tmp) {
#define MELEMENT(o,s) if(o) WARN("Planet '%s' missing '"s"' element", tmp->name) #define MELEMENT(o,s) if(o) WARN("Planet '%s' missing '"s"' element", tmp->name)
MELEMENT(tmp->gfx_space==NULL, "GFX_space"); MELEMENT(tmp->gfx_space==NULL, "GFX_space");
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_LAND) && MELEMENT(planet_hasService(tmp, PLANET_SERVICE_LAND) &&
tmp->gfx_exterior==NULL, "GFX exterior"); tmp->gfx_exterior==NULL, "GFX exterior");
MELEMENT((flags&FLAG_XSET)==0, "x"); MELEMENT((flags&FLAG_XSET)==0, "x");
MELEMENT((flags&FLAG_YSET)==0, "y"); MELEMENT((flags&FLAG_YSET)==0, "y");
MELEMENT(tmp->class==PLANET_CLASS_NULL, "class"); MELEMENT(tmp->class==PLANET_CLASS_NULL, "class");
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_LAND) && MELEMENT(planet_hasService(tmp, PLANET_SERVICE_LAND) &&
tmp->description==NULL, "description"); tmp->description==NULL, "description");
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_BASIC) && MELEMENT(planet_hasService(tmp, PLANET_SERVICE_BASIC) &&
tmp->bar_description==NULL, "bar"); tmp->bar_description==NULL, "bar");
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_BASIC) && MELEMENT(planet_hasService(tmp, PLANET_SERVICE_BASIC) &&
tmp->faction==NULL, "faction"); tmp->faction==NULL, "faction");
MELEMENT((flags&FLAG_SERVICESET)==0, "services"); MELEMENT((flags&FLAG_SERVICESET)==0, "services");
MELEMENT((planet_hasService(tmp, PLANET_SERVICE_OUTFITS) || MELEMENT((planet_hasService(tmp, PLANET_SERVICE_OUTFITS) ||
planet_hasService(tmp, PLANET_SERVICE_SHIPYARD)) && planet_hasService(tmp, PLANET_SERVICE_SHIPYARD)) &&
(flags&FLAG_TECHSET)==0, "tech"); (flags&FLAG_TECHSET)==0, "tech");
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_COMMODITY) && MELEMENT(planet_hasService(tmp, PLANET_SERVICE_COMMODITY) &&
(tmp->ncommodities==0), "commodity"); (tmp->ncommodities==0), "commodity");
#undef MELEMENT #undef MELEMENT
} else } else
WARN("No planet found matching name '%s'", name); WARN("No planet found matching name '%s'", name);
@ -499,7 +499,7 @@ static StarSystem* system_parse(const xmlNodePtr parent) {
cur = node->children; cur = node->children;
do { do {
if(xml_isNode(cur, "planet")) { if(xml_isNode(cur, "planet")) {
nplanets++; // Increase planet counter. nplanets++; // Increase planet counter.
planet = planet_get(xml_get(cur)); planet = planet_get(xml_get(cur));
planet = planet_get((const char*)cur->children->content); planet = planet_get((const char*)cur->children->content);
tmp->planets = realloc(tmp->planets, sizeof(Planet)*(++tmp->nplanets)); tmp->planets = realloc(tmp->planets, sizeof(Planet)*(++tmp->nplanets));
@ -522,7 +522,7 @@ static StarSystem* system_parse(const xmlNodePtr parent) {
fleet->chance = atoi(ptrc); fleet->chance = atoi(ptrc);
if(fleet->chance == 0) if(fleet->chance == 0)
WARN("Fleet %s for Star System %s has 0%% chance to appear", WARN("Fleet %s for Star System %s has 0%% chance to appear",
fleet->fleet->name, tmp->name); fleet->fleet->name, tmp->name);
if(ptrc) free(ptrc); // Free the ptrc. if(ptrc) free(ptrc); // Free the ptrc.
tmp->fleets = realloc(tmp->fleets, sizeof(SystemFleet)*(++tmp->nfleets)); tmp->fleets = realloc(tmp->fleets, sizeof(SystemFleet)*(++tmp->nfleets));
@ -540,11 +540,11 @@ static StarSystem* system_parse(const xmlNodePtr parent) {
MELEMENT(flags&FLAG_ASTEROIDSSET, "asteroids"); // Can be 0. MELEMENT(flags&FLAG_ASTEROIDSSET, "asteroids"); // Can be 0.
MELEMENT(flags&FLAG_INTEFERENCESET, "inteference"); MELEMENT(flags&FLAG_INTEFERENCESET, "inteference");
#undef MELEMENT #undef MELEMENT
// Post processing. // Post processing.
if(tmp->nplanets > 0) if(tmp->nplanets > 0)
// TODO: Make dependant on overall planet faction. // TODO: Make dependant on overall planet faction.
tmp->faction = tmp->planets[0].faction; tmp->faction = tmp->planets[0].faction;
return tmp; return tmp;
} }
@ -561,31 +561,31 @@ static void system_parseJumps(const xmlNodePtr parent) {
system = &systems_stack[i]; system = &systems_stack[i];
break; break;
} }
if(i == systems_nstack) 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. free(name); // No need for it now.
node = parent->xmlChildrenNode; node = parent->xmlChildrenNode;
do { do {
// Load the data. // Load the data.
if(xml_isNode(node, "jumps")) { if(xml_isNode(node, "jumps")) {
cur = node->children; cur = node->children;
do { do {
if(xml_isNode(cur, "jump")) { if(xml_isNode(cur, "jump")) {
for(i = 0; i < systems_nstack; i++) for(i = 0; i < systems_nstack; i++)
if(strcmp(systems_stack[i].name, xml_get(cur))==0) { if(strcmp(systems_stack[i].name, xml_get(cur))==0) {
system->njumps++; system->njumps++;
system->jumps = realloc(system->jumps, system->njumps*sizeof(int)); system->jumps = realloc(system->jumps, system->njumps*sizeof(int));
system->jumps[system->njumps-1] = i; system->jumps[system->njumps-1] = i;
break; break;
} }
if(i == systems_nstack) if(i == systems_nstack)
WARN("System '%s' not found for jump linking", xml_get(cur)); WARN("System '%s' not found for jump linking", xml_get(cur));
} }
} while((cur = cur->next)); } while((cur = cur->next));
} }
} while((node = node->next)); } while((node = node->next));
} }
// Load the ENTIRE universe into RAM. -- WOAH! // Load the ENTIRE universe into RAM. -- WOAH!
@ -631,9 +631,9 @@ int space_load(void) {
free(buf); free(buf);
xmlCleanupParser(); xmlCleanupParser();
DEBUG("Loaded %d star system%s with %d planet%s", DEBUG("Loaded %d star system%s with %d planet%s",
systems_nstack, (systems_nstack==1) ? "" : "s", systems_nstack, (systems_nstack==1) ? "" : "s",
nplanets, (nplanets==1) ? "" : "s"); nplanets, (nplanets==1) ? "" : "s");
return 0; return 0;
} }
@ -641,63 +641,63 @@ int space_load(void) {
// Render the system. -- Just playing god now. // Render the system. -- Just playing god now.
void space_render(double dt) { void space_render(double dt) {
int i; int i;
unsigned int t, timer; unsigned int t, timer;
double x, y, m; double x, y, m;
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glPushMatrix(); // Translation matrix. glPushMatrix(); // Translation matrix.
glTranslated(-(double)gl_screen.w/2., -(double)gl_screen.h/2., 0); glTranslated(-(double)gl_screen.w/2., -(double)gl_screen.h/2., 0);
t = SDL_GetTicks(); t = SDL_GetTicks();
if(!player_isFlag(PLAYER_DESTROYED) && if(!player_isFlag(PLAYER_DESTROYED) &&
pilot_isFlag(player, PILOT_HYPERSPACE) && // Hyperspace fancy effect. pilot_isFlag(player, PILOT_HYPERSPACE) && // Hyperspace fancy effect.
!paused && (player->ptimer-HYPERSPACE_STARS_BLUR < t)) { !paused && (player->ptimer-HYPERSPACE_STARS_BLUR < t)) {
timer = player->ptimer - HYPERSPACE_STARS_BLUR; timer = player->ptimer - HYPERSPACE_STARS_BLUR;
// Fancy hyperspace effects. // Fancy hyperspace effects.
glShadeModel(GL_SMOOTH); glShadeModel(GL_SMOOTH);
glBegin(GL_LINES); glBegin(GL_LINES);
// Lines will be based on velocity. // Lines will be based on velocity.
m = HYPERSPACE_STARS_LENGTH * (double)(t-timer) / (HYPERSPACE_STARS_BLUR); m = HYPERSPACE_STARS_LENGTH * (double)(t-timer) / (HYPERSPACE_STARS_BLUR);
x = m*cos(VANGLE(player->solid->vel)+M_PI); x = m*cos(VANGLE(player->solid->vel)+M_PI);
y = m*sin(VANGLE(player->solid->vel)+M_PI); y = m*sin(VANGLE(player->solid->vel)+M_PI);
for(i = 0; i < nstars; i++) { for(i = 0; i < nstars; i++) {
glColor4d(1., 1., 1., stars[i].brightness); glColor4d(1., 1., 1., stars[i].brightness);
glVertex2d(stars[i].x, stars[i].y); glVertex2d(stars[i].x, stars[i].y);
glColor4d(1., 1., 1., 0.); glColor4d(1., 1., 1., 0.);
glVertex2d(stars[i].x+x*stars[i].brightness,stars[i].y+y*stars[i].brightness); glVertex2d(stars[i].x+x*stars[i].brightness,stars[i].y+y*stars[i].brightness);
}
glEnd();
glShadeModel(GL_FLAT);
} 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! glEnd();
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; glShadeModel(GL_FLAT);
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; } else {
} glBegin(GL_POINTS);
// Render.
glColor4d(1., 1., 1., stars[i].brightness); for(i = 0; i < nstars; i++) {
glVertex2d(stars[i].x, stars[i].y); 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();
} }
glEnd(); glPopMatrix(); // Translation matrix.
}
glPopMatrix(); // Translation matrix.
} }
// Render the planets. // Render the planets.
@ -705,7 +705,7 @@ void planets_render(void) {
int i; int i;
for(i = 0; i < cur_system->nplanets; i++) for(i = 0; i < cur_system->nplanets; i++)
gl_blitSprite(cur_system->planets[i].gfx_space, gl_blitSprite(cur_system->planets[i].gfx_space,
cur_system->planets[i].pos.x, cur_system->planets[i].pos.y, 0, 0, NULL); cur_system->planets[i].pos.x, cur_system->planets[i].pos.y, 0, 0, NULL);
} }
// Clean up the system. // Clean up the system.

View File

@ -35,7 +35,7 @@ typedef enum PlanetClass_ {
PLANET_CLASS_X, // Demon. PLANET_CLASS_X, // Demon.
PLANET_CLASS_Y, // Demon. PLANET_CLASS_Y, // Demon.
PLANET_CLASS_Z, // Demon. PLANET_CLASS_Z, // Demon.
STATION_CLASS_A // TODO. STATION_CLASS_A // TODO.
} PlanetClass; } PlanetClass;
// Planet services. // Planet services.
@ -56,12 +56,12 @@ typedef struct Planet_ {
char* description; // Planet description. char* description; // Planet description.
char* bar_description; // Spaceport bar description. char* bar_description; // Spaceport bar description.
unsigned int services; // Offered services. unsigned int services; // Offered services.
Commodity** commodities; // Commodities sold. Commodity** commodities; // Commodities sold.
int ncommodities; // Amount in stock. int ncommodities; // Amount in stock.
// tech[0] stores global tech level (everything that and below) while // tech[0] stores global tech level (everything that and below) while
// tech[1-PLANET_TECH_MAX] stores the unique tech levels. // tech[1-PLANET_TECH_MAX] stores the unique tech levels.
int tech[PLANET_TECH_MAX]; int tech[PLANET_TECH_MAX];
glTexture* gfx_space; // Graphics in space. glTexture* gfx_space; // Graphics in space.
glTexture* gfx_exterior; // Graphics in the exterior. glTexture* gfx_exterior; // Graphics in the exterior.
@ -79,7 +79,7 @@ typedef struct StarSystem_ {
int stars, asteroids; // Un numero! 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. Planet* planets; // Planets.
int nplanets; // Total number of planets. int nplanets; // Total number of planets.

View File

@ -12,21 +12,21 @@
#define SPFX_CHUNK 10 // Chunk to allocate when needed. #define SPFX_CHUNK 10 // Chunk to allocate when needed.
typedef struct SPFX_Base_ { typedef struct SPFX_Base_ {
char* name; char* name;
int anim; // Total duration in ms. int anim; // Total duration in ms.
glTexture* gfx; // Will use each sprite as a frame. glTexture* gfx; // Will use each sprite as a frame.
} SPFX_Base; } SPFX_Base;
static SPFX_Base* spfx_effects = NULL; static SPFX_Base* spfx_effects = NULL;
static int spfx_neffects = 0; static int spfx_neffects = 0;
typedef struct SPFX_ { typedef struct SPFX_ {
Vec2 pos, vel; // They don't accelerate. Vec2 pos, vel; // They don't accelerate.
int lastframe; // Need when pausing. int lastframe; // Need when pausing.
int effect; // Actual effect. int effect; // Actual effect.
unsigned int t; // Start. unsigned int t; // Start.
} SPFX; } SPFX;
// Front stack is for effects on player. // Front stack is for effects on player.
@ -48,198 +48,198 @@ static void spfx_delay_layer(SPFX* layer, int nlayer, unsigned int delay);
// Load the SPFX_Base. // Load the SPFX_Base.
static int spfx_base_load(char* name, int anim, char* gfx, int sx, int sy) { static int spfx_base_load(char* name, int anim, char* gfx, int sx, int sy) {
SPFX_Base* cur; SPFX_Base* cur;
char buf[PATH_MAX]; char buf[PATH_MAX];
spfx_effects = realloc(spfx_effects, ++spfx_neffects*sizeof(SPFX_Base)); spfx_effects = realloc(spfx_effects, ++spfx_neffects*sizeof(SPFX_Base));
cur = &spfx_effects[spfx_neffects-1]; cur = &spfx_effects[spfx_neffects-1];
cur->name = strdup(name); cur->name = strdup(name);
cur->anim = anim; cur->anim = anim;
sprintf(buf, SPFX_GFX"%s", gfx); sprintf(buf, SPFX_GFX"%s", gfx);
cur->gfx = gl_newSprite(buf, sx, sy); cur->gfx = gl_newSprite(buf, sx, sy);
return 0; return 0;
} }
static void spfx_base_free(SPFX_Base* effect) { static void spfx_base_free(SPFX_Base* effect) {
if(effect->name) free(effect->name); if(effect->name) free(effect->name);
if(effect->gfx) gl_freeTexture(effect->gfx); if(effect->gfx) gl_freeTexture(effect->gfx);
} }
int spfx_get(char* name) { int spfx_get(char* name) {
int i; int i;
for(i = 0; i < spfx_neffects; i++) for(i = 0; i < spfx_neffects; i++)
if(strcmp(spfx_effects[i].name, name)==0) if(strcmp(spfx_effects[i].name, name)==0)
return i; return i;
WARN("SPFX '%s' not found!", name); WARN("SPFX '%s' not found!", name);
return 0; return 0;
} }
// Load/Unload. // Load/Unload.
int spfx_load(void) { int spfx_load(void) {
spfx_base_load("ExpS", 400, "exps.png", 6, 5); spfx_base_load("ExpS", 400, "exps.png", 6, 5);
spfx_base_load("ExpM", 450, "expm.png", 6, 5); spfx_base_load("ExpM", 450, "expm.png", 6, 5);
spfx_base_load("ExpL", 500, "expl.png", 6, 5); spfx_base_load("ExpL", 500, "expl.png", 6, 5);
return 0; return 0;
} }
void spfx_free(void) { void spfx_free(void) {
int i; int i;
// Get rid of all the particles and free the stacks. // Get rid of all the particles and free the stacks.
spfx_clear(); spfx_clear();
if(spfx_stack_front) free(spfx_stack_front); if(spfx_stack_front) free(spfx_stack_front);
spfx_stack_front = NULL; spfx_stack_front = NULL;
spfx_mstack_front = 0; spfx_mstack_front = 0;
if(spfx_stack_back) free(spfx_stack_back); if(spfx_stack_back) free(spfx_stack_back);
spfx_stack_back = NULL; spfx_stack_back = NULL;
spfx_mstack_back = 0; spfx_mstack_back = 0;
for(i = 0; i < spfx_neffects; i++) for(i = 0; i < spfx_neffects; i++)
spfx_base_free(&spfx_effects[i]); spfx_base_free(&spfx_effects[i]);
free(spfx_effects); free(spfx_effects);
spfx_effects = NULL; spfx_effects = NULL;
spfx_neffects = 0; spfx_neffects = 0;
} }
void spfx_add(int effect, void spfx_add(int effect,
const double px, const double py, const double px, const double py,
const double vx, const double vy, const double vx, const double vy,
const int layer) { const int layer) {
SPFX* cur_spfx; SPFX* cur_spfx;
if(layer == SPFX_LAYER_FRONT) { if(layer == SPFX_LAYER_FRONT) {
// Front layer. // Front layer.
if(spfx_mstack_front < spfx_nstack_front+1) { if(spfx_mstack_front < spfx_nstack_front+1) {
// We need more memory. // We need more memory.
spfx_mstack_front += SPFX_CHUNK; spfx_mstack_front += SPFX_CHUNK;
spfx_stack_front = realloc(spfx_stack_front, spfx_mstack_front*sizeof(SPFX)); spfx_stack_front = realloc(spfx_stack_front, spfx_mstack_front*sizeof(SPFX));
}
cur_spfx = &spfx_stack_front[spfx_nstack_front];
spfx_nstack_front++;
} }
cur_spfx = &spfx_stack_front[spfx_nstack_front]; else if(layer == SPFX_LAYER_BACK) {
spfx_nstack_front++; // Back layer.
} if(spfx_mstack_back < spfx_nstack_back+1) {
else if(layer == SPFX_LAYER_BACK) { // Need more memory.
// Back layer. spfx_mstack_back += SPFX_CHUNK;
if(spfx_mstack_back < spfx_nstack_back+1) { spfx_stack_back = realloc(spfx_stack_back, spfx_mstack_back*sizeof(SPFX));
// Need more memory. }
spfx_mstack_back += SPFX_CHUNK; cur_spfx = &spfx_stack_back[spfx_nstack_back];
spfx_stack_back = realloc(spfx_stack_back, spfx_mstack_back*sizeof(SPFX)); spfx_nstack_back++;
} }
cur_spfx = &spfx_stack_back[spfx_nstack_back];
spfx_nstack_back++;
}
cur_spfx->effect = effect; cur_spfx->effect = effect;
vect_csetmin(&cur_spfx->pos, px, py); vect_csetmin(&cur_spfx->pos, px, py);
vect_csetmin(&cur_spfx->vel, vx, vy); vect_csetmin(&cur_spfx->vel, vx, vy);
cur_spfx->t = SDL_GetTicks(); cur_spfx->t = SDL_GetTicks();
} }
void spfx_clear(void) { void spfx_clear(void) {
int i; int i;
for(i = spfx_nstack_front-1; i >= 0; i--) for(i = spfx_nstack_front-1; i >= 0; i--)
spfx_destroy(spfx_stack_front, &spfx_nstack_front, i); spfx_destroy(spfx_stack_front, &spfx_nstack_front, i);
for(i = spfx_nstack_back-1; i >= 0; i--) for(i = spfx_nstack_back-1; i >= 0; i--)
spfx_destroy(spfx_stack_back, &spfx_nstack_back, i); spfx_destroy(spfx_stack_back, &spfx_nstack_back, i);
} }
static void spfx_destroy(SPFX* layer, int* nlayer, int spfx) { static void spfx_destroy(SPFX* layer, int* nlayer, int spfx) {
(*nlayer)--; (*nlayer)--;
memmove(&layer[spfx], &layer[spfx+1], (*nlayer-spfx)*sizeof(SPFX)); memmove(&layer[spfx], &layer[spfx+1], (*nlayer-spfx)*sizeof(SPFX));
} }
void spfx_update(const double dt) { void spfx_update(const double dt) {
spfx_update_layer(spfx_stack_front, &spfx_nstack_front, 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_back, &spfx_nstack_back, dt);
} }
static void spfx_update_layer(SPFX* layer, int* nlayer, const double dt) { static void spfx_update_layer(SPFX* layer, int* nlayer, const double dt) {
int i; int i;
unsigned int t = SDL_GetTicks(); unsigned int t = SDL_GetTicks();
for(i = 0; i < *nlayer; i++) { for(i = 0; i < *nlayer; i++) {
// Time to die!!! // Time to die!!!
if(t > (layer[i].t + spfx_effects[layer[i].effect].anim)) { if(t > (layer[i].t + spfx_effects[layer[i].effect].anim)) {
spfx_destroy(layer, nlayer, i); spfx_destroy(layer, nlayer, i);
i--; i--;
continue; continue;
}
// Mkay. Update it now.
vect_cadd(&layer[i].pos, dt*VX(layer[i].vel), dt*VY(layer[i].vel));
} }
// 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) { void spfx_render(const int layer) {
SPFX* spfx_stack; SPFX* spfx_stack;
int i, spfx_nstack; int i, spfx_nstack;
SPFX_Base* effect; SPFX_Base* effect;
int sx, sy; int sx, sy;
unsigned int t = SDL_GetTicks(); unsigned int t = SDL_GetTicks();
// Get the appropriate layer. // Get the appropriate layer.
switch(layer) { switch(layer) {
case SPFX_LAYER_FRONT: case SPFX_LAYER_FRONT:
spfx_stack = spfx_stack_front; spfx_stack = spfx_stack_front;
spfx_nstack = spfx_nstack_front; spfx_nstack = spfx_nstack_front;
break; break;
case SPFX_LAYER_BACK: case SPFX_LAYER_BACK:
spfx_stack = spfx_stack_back; spfx_stack = spfx_stack_back;
spfx_nstack = spfx_nstack_back; spfx_nstack = spfx_nstack_back;
break; break;
} }
for(i = 0; i < spfx_nstack; i++) { for(i = 0; i < spfx_nstack; i++) {
effect = &spfx_effects[spfx_stack[i].effect]; effect = &spfx_effects[spfx_stack[i].effect];
sx = (int)effect->gfx->sx; sx = (int)effect->gfx->sx;
sy = (int)effect->gfx->sy; sy = (int)effect->gfx->sy;
if(!paused) // Don't calculate frame if paused. if(!paused) // Don't calculate frame if paused.
spfx_stack[i].lastframe = sx * sy spfx_stack[i].lastframe = sx * sy
* MIN(((double)(t - spfx_stack[i].t)/(double)effect->anim), 1.); * MIN(((double)(t - spfx_stack[i].t)/(double)effect->anim), 1.);
gl_blitSprite(effect->gfx, gl_blitSprite(effect->gfx,
VX(spfx_stack[i].pos), VY(spfx_stack[i].pos), VX(spfx_stack[i].pos), VY(spfx_stack[i].pos),
spfx_stack[i].lastframe % sx, spfx_stack[i].lastframe % sx,
spfx_stack[i].lastframe / sx, spfx_stack[i].lastframe / sx,
NULL); NULL);
} }
} }
void spfx_pause(void) { void spfx_pause(void) {
spfx_pause_layer(spfx_stack_front, spfx_nstack_front); spfx_pause_layer(spfx_stack_front, spfx_nstack_front);
spfx_pause_layer(spfx_stack_back, spfx_nstack_back); spfx_pause_layer(spfx_stack_back, spfx_nstack_back);
} }
static void spfx_pause_layer(SPFX* layer, int nlayer) { static void spfx_pause_layer(SPFX* layer, int nlayer) {
int i; int i;
unsigned int t = SDL_GetTicks(); unsigned int t = SDL_GetTicks();
for(i = 0; i < nlayer; i++) for(i = 0; i < nlayer; i++)
layer[i].t -= t; layer[i].t -= t;
} }
void spfx_unpause(void) { void spfx_unpause(void) {
spfx_unpause_layer(spfx_stack_front, spfx_nstack_front); spfx_unpause_layer(spfx_stack_front, spfx_nstack_front);
spfx_unpause_layer(spfx_stack_back, spfx_nstack_back); spfx_unpause_layer(spfx_stack_back, spfx_nstack_back);
} }
static void spfx_unpause_layer(SPFX* layer, int nlayer) { static void spfx_unpause_layer(SPFX* layer, int nlayer) {
int i; int i;
unsigned int t = SDL_GetTicks(); unsigned int t = SDL_GetTicks();
for(i = 0; i < nlayer; i++) for(i = 0; i < nlayer; i++)
layer[i].t += t; layer[i].t += t;
} }
void spfx_delay(unsigned int delay) { void spfx_delay(unsigned int delay) {
spfx_delay_layer(spfx_stack_front, spfx_nstack_front, 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_back, spfx_nstack_back, delay);
} }
static void spfx_delay_layer(SPFX* layer, int nlayer, unsigned int delay) { static void spfx_delay_layer(SPFX* layer, int nlayer, unsigned int delay) {
int i; int i;
for(i = 0; i < nlayer; i++) for(i = 0; i < nlayer; i++)
layer[i].t += delay; layer[i].t += delay;
} }

View File

@ -7,9 +7,9 @@
// Stack manipulation. // Stack manipulation.
int spfx_get(char* name); int spfx_get(char* name);
void spfx_add(const int effect, void spfx_add(const int effect,
const double px, const double py, const double px, const double py,
const double vx, const double vy, const double vx, const double vy,
const int layer); const int layer);
// Stack mass manipulation functions. // Stack mass manipulation functions.
void spfx_update(const double dt); void spfx_update(const double dt);

File diff suppressed because it is too large Load Diff

View File

@ -7,36 +7,36 @@ extern int toolkit;
// Creation. // Creation.
unsigned int window_create(char* name, const int x, const int y, 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, void window_addButton(const unsigned int wid, const int x, const int y,
const int w, const int h, char* name, char* display, const int w, const int h, char* name, char* display,
void(*call)(char*)); void(*call)(char*));
void window_addText(const unsigned int wid, const int x, const int y, void window_addText(const unsigned int wid, const int x, const int y,
const int w, const int h, const int centered, char* name, const int w, const int h, const int centered, char* name,
glFont* font, glColour* colour, char* string); glFont* font, glColour* colour, char* string);
void window_addImage(const unsigned int wid, const int x, const int y, void window_addImage(const unsigned int wid, const int x, const int y,
char* name, glTexture* image); char* name, glTexture* image);
void window_addList(const unsigned int wid, void window_addList(const unsigned int wid,
const int x, const int y, // Position. const int x, const int y, // Position.
const int w, const int h, // Size. const int w, const int h, // Size.
char* name, char** items, int nitems, int defitem, char* name, char** items, int nitems, int defitem,
void(*call)(char*)); void(*call)(char*));
void window_addRect(const unsigned int wid, void window_addRect(const unsigned int wid,
const int x, const int y, // Position. const int x, const int y, // Position.
const int w, const int h, // size. const int w, const int h, // size.
char* name, glColour* colour, int border); // Properties. char* name, glColour* colour, int border); // Properties.
void window_addCust(const unsigned int wid, void window_addCust(const unsigned int wid,
const int x, const int y, // Position. const int x, const int y, // Position.
const int w, const int h, // Size. const int w, const int h, // Size.
char* name, const int border, char* name, const int border,
void(*render) (double x, double y, double w, double h), void(*render) (double x, double y, double w, double h),
void(*mouse) (SDL_Event* event, double x, double y)); void(*mouse) (SDL_Event* event, double x, double y));
// Popups and alerts. // Popups and alerts.
void toolkit_alert(const char* fmt, ...); void toolkit_alert(const char* fmt, ...);

View File

@ -33,9 +33,9 @@ typedef struct Weapon_ {
const Outfit* outfit; // Related outfit that fired. const Outfit* outfit; // Related outfit that fired.
unsigned int timer; // Mainly used to see when the weapon was 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(*update)(struct Weapon_*, const double, WeaponLayer); // Position update and render.
void(*think)(struct Weapon_*, const double); // Some missiles need to be inteligent. void(*think)(struct Weapon_*, const double); // Some missiles need to be inteligent.
} Weapon; } Weapon;
@ -50,8 +50,9 @@ static int nwfrontLayer = 0; // Number of elements.
static int mwfrontLayer = 0; // Allocated memory size. static int mwfrontLayer = 0; // Allocated memory size.
static Weapon* weapon_create(const Outfit* outfit, const double dir, static Weapon* weapon_create(const Outfit* outfit, const double dir,
const Vec2* pos, const Vec2* vel, const unsigned int parent, const Vec2* pos, const Vec2* vel,
const unsigned int target); const unsigned int parent,
const unsigned int target);
static void weapon_render(const Weapon* w); static void weapon_render(const Weapon* w);
static void weapons_updateLayer(const double dt, const WeaponLayer layer); static void weapons_updateLayer(const double dt, const WeaponLayer layer);
@ -65,9 +66,9 @@ static void think_smart(Weapon* w, const double dt);
// Draw the minimap weapons (player.c). // Draw the minimap weapons (player.c).
#define PIXEL(x,y) if((shape == RADAR_RECT && ABS(x) < w/2. && ABS(y)<h/2.) || \ #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)) (shape == RADAR_CIRCLE && (((x)*(x)+(y)*(y))<rc))) glVertex2i((x),(y))
void weapon_minimap(const double res, 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; int i, rc;
double x, y; double x, y;
@ -78,7 +79,7 @@ void weapon_minimap(const double res,
y = (wbackLayer[i]->solid->pos.y - player->solid->pos.y) / res; y = (wbackLayer[i]->solid->pos.y - player->solid->pos.y) / res;
PIXEL(x,y); PIXEL(x,y);
} }
for(i = 0; i < nwfrontLayer; i++) { for(i = 0; i < nwfrontLayer; i++) {
x = (wfrontLayer[i]->solid->pos.x - player->solid->pos.x) / res; x = (wfrontLayer[i]->solid->pos.x - player->solid->pos.x) / res;
y = (wfrontLayer[i]->solid->pos.y - player->solid->pos.y) / res; y = (wfrontLayer[i]->solid->pos.y - player->solid->pos.y) / res;
@ -108,70 +109,70 @@ void weapons_unpause(void) {
} }
void weapons_delay(unsigned int delay) { void weapons_delay(unsigned int delay) {
int i; int i;
for(i = 0; i < nwbackLayer; i++) for(i = 0; i < nwbackLayer; i++)
wbackLayer[i]->timer += delay; wbackLayer[i]->timer += delay;
for(i = 0; i < nwfrontLayer; i++) for(i = 0; i < nwfrontLayer; i++)
wfrontLayer[i]->timer += delay; wfrontLayer[i]->timer += delay;
} }
// Seeker brain, You get what you pay for. :) // Seeker brain, You get what you pay for. :)
static void think_seeker(Weapon* w, const double dt) { 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. if(w->target == w->parent) return; // HEY! Self harm is not allowed.
Pilot* p = pilot_get(w->target); Pilot* p = pilot_get(w->target);
if(p == NULL) { if(p == NULL) {
limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt); limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt);
return; return;
} }
// Ammo isn't locked on yet.. // Ammo isn't locked on yet..
if(SDL_GetTicks() > (w->timer + w->outfit->u.amm.lockon)) { if(SDL_GetTicks() > (w->timer + w->outfit->u.amm.lockon)) {
diff = angle_diff(w->solid->dir, vect_angle(&w->solid->pos, &p->solid->pos)); 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; w->solid->dir_vel = 10 * diff * w->outfit->u.amm.turn;
// Face the target. // Face the target.
if(w->solid->dir_vel > w->outfit->u.amm.turn) if(w->solid->dir_vel > w->outfit->u.amm.turn)
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) else if(w->solid->dir_vel < -w->outfit->u.amm.turn)
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);
} }
// Smart seeker brain. Much better at homing. // Smart seeker brain. Much better at homing.
static void think_smart(Weapon* w, const double dt) { static void think_smart(Weapon* w, const double dt) {
double diff; double diff;
Vec2 tv, sv; 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(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);
if(p == NULL) {
limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt); 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;
}
vect_pset(&w->solid->force, w->outfit->u.amm.thrust, w->solid->dir);
limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt);
} }
@ -187,41 +188,41 @@ static void weapons_updateLayer(const double dt, const WeaponLayer layer) {
int* nlayer; int* nlayer;
switch(layer) { switch(layer) {
case WEAPON_LAYER_BG: case WEAPON_LAYER_BG:
wlayer = wbackLayer; wlayer = wbackLayer;
nlayer = &nwbackLayer; nlayer = &nwbackLayer;
break; break;
case WEAPON_LAYER_FG: case WEAPON_LAYER_FG:
wlayer = wfrontLayer; wlayer = wfrontLayer;
nlayer = &nwfrontLayer; nlayer = &nwfrontLayer;
break; break;
} }
int i; int i;
Weapon* w; Weapon* w;
for(i = 0; i < (*nlayer); i++) { for(i = 0; i < (*nlayer); i++) {
w = wlayer[i]; w = wlayer[i];
switch(wlayer[i]->outfit->type) { 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_AMMO:
case OUTFIT_TYPE_MISSILE_SEEK_SMART_AMMO: case OUTFIT_TYPE_MISSILE_SEEK_SMART_AMMO:
case OUTFIT_TYPE_MISSILE_SWARM_AMMO: case OUTFIT_TYPE_MISSILE_SWARM_AMMO:
case OUTFIT_TYPE_MISSILE_SWARM_SMART_AMMO: case OUTFIT_TYPE_MISSILE_SWARM_SMART_AMMO:
if(SDL_GetTicks() > 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); weapon_destroy(wlayer[i], layer);
continue; continue;
} }
break; break;
case OUTFIT_TYPE_BOLT: case OUTFIT_TYPE_BOLT:
// Check see if it exceeds distance. // Check see if it exceeds distance.
case OUTFIT_TYPE_TURRET_BOLT: case OUTFIT_TYPE_TURRET_BOLT:
if(SDL_GetTicks() > wlayer[i]->timer) { if(SDL_GetTicks() > wlayer[i]->timer) {
weapon_destroy(wlayer[i],layer); weapon_destroy(wlayer[i],layer);
continue; continue;
} }
break; break;
default: default:
break; break;
} }
weapon_update(wlayer[i], dt, layer); weapon_update(wlayer[i], dt, layer);
// If the weapon has been deleted we are going to have to hold back one. // If the weapon has been deleted we are going to have to hold back one.
@ -236,14 +237,14 @@ void weapons_render(const WeaponLayer layer) {
int i; int i;
switch(layer) { switch(layer) {
case WEAPON_LAYER_BG: case WEAPON_LAYER_BG:
wlayer = wbackLayer; wlayer = wbackLayer;
nlayer = &nwbackLayer; nlayer = &nwbackLayer;
break; break;
case WEAPON_LAYER_FG: case WEAPON_LAYER_FG:
wlayer = wfrontLayer; wlayer = wfrontLayer;
nlayer = &nwfrontLayer; nlayer = &nwfrontLayer;
break; break;
} }
for(i = 0; i < (*nlayer); i++) for(i = 0; i < (*nlayer); i++)
weapon_render(wlayer[i]); weapon_render(wlayer[i]);
@ -252,9 +253,9 @@ void weapons_render(const WeaponLayer layer) {
// Render the weapons. // Render the weapons.
static void weapon_render(const Weapon* w) { static void weapon_render(const Weapon* w) {
int sx, sy; 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. // Get the sprite corresponding to the direction facing.
gl_getSpriteFromDir(&sx, &sy, gfx, w->solid->dir); gl_getSpriteFromDir(&sx, &sy, gfx, w->solid->dir);
@ -265,41 +266,41 @@ static void weapon_render(const Weapon* w) {
// Update the weapon. // Update the weapon.
static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) { static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) {
int i, wsx, wsy, psx, psy; 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); gl_getSpriteFromDir(&wsx, &wsy, gfx, w->solid->dir);
for(i = 0; i < pilots; i++) { for(i = 0; i < pilots; i++) {
psx = pilot_stack[i]->tsx; psx = pilot_stack[i]->tsx;
psy = pilot_stack[i]->tsy; psy = pilot_stack[i]->tsy;
if(w->parent == pilot_stack[i]->id) continue; // Hey! That's you. if(w->parent == pilot_stack[i]->id) continue; // Hey! That's you.
if((weapon_isSmart(w)) && (pilot_stack[i]->id == w->target) && if((weapon_isSmart(w)) && (pilot_stack[i]->id == w->target) &&
CollideSprite(gfx, wsx, wsy, &w->solid->pos, CollideSprite(gfx, wsx, wsy, &w->solid->pos,
pilot_stack[i]->ship->gfx_space, psx, psy, &pilot_stack[i]->solid->pos)) { pilot_stack[i]->ship->gfx_space, psx, psy, &pilot_stack[i]->solid->pos)) {
weapon_hit(w, pilot_stack[i], layer); weapon_hit(w, pilot_stack[i], layer);
return; return;
} }
else if(!weapon_isSmart(w) && else if(!weapon_isSmart(w) &&
!areAllies(pilot_get(w->parent)->faction, pilot_stack[i]->faction) && !areAllies(pilot_get(w->parent)->faction, pilot_stack[i]->faction) &&
CollideSprite(gfx, wsx, wsy, &w->solid->pos, CollideSprite(gfx, wsx, wsy, &w->solid->pos,
pilot_stack[i]->ship->gfx_space, psx, psy, &pilot_stack[i]->solid->pos)) { pilot_stack[i]->ship->gfx_space, psx, psy, &pilot_stack[i]->solid->pos)) {
weapon_hit(w, pilot_stack[i], layer); weapon_hit(w, pilot_stack[i], layer);
return; return;
} }
} }
if(weapon_isSmart(w)) (*w->think)(w,dt); if(weapon_isSmart(w)) (*w->think)(w,dt);
(*w->solid->update)(w->solid, dt); (*w->solid->update)(w->solid, dt);
// Update the sound. // Update the sound.
if(w->voice) if(w->voice)
voice_update(w->voice, w->solid->pos.x, w->solid->pos.y, voice_update(w->voice, w->solid->pos.x, w->solid->pos.y,
w->solid->vel.x, w->solid->vel.y); w->solid->vel.x, w->solid->vel.y);
} }
// Good shot. // Good shot.
@ -307,13 +308,13 @@ static void weapon_hit(Weapon* w, Pilot* p, WeaponLayer layer) {
// Someone should let the ai know it's been attacked. // Someone should let the ai know it's been attacked.
if(!pilot_isPlayer(p)) { if(!pilot_isPlayer(p)) {
ai_attacked(p, w->parent); ai_attacked(p, w->parent);
spfx_add(outfit_spfx(w->outfit), spfx_add(outfit_spfx(w->outfit),
VX(w->solid->pos), VY(w->solid->pos), VX(w->solid->pos), VY(w->solid->pos),
VX(p->solid->vel), VY(p->solid->vel), SPFX_LAYER_BACK); VX(p->solid->vel), VY(p->solid->vel), SPFX_LAYER_BACK);
} else } else
spfx_add(outfit_spfx(w->outfit), spfx_add(outfit_spfx(w->outfit),
VX(w->solid->pos), VY(w->solid->pos), VX(w->solid->pos), VY(w->solid->pos),
VX(p->solid->vel), VY(p->solid->vel), SPFX_LAYER_FRONT); VX(p->solid->vel), VY(p->solid->vel), SPFX_LAYER_FRONT);
if(w->parent == PLAYER_ID) if(w->parent == PLAYER_ID)
// Make hostile to player. // Make hostile to player.
@ -326,7 +327,7 @@ static void weapon_hit(Weapon* w, Pilot* p, WeaponLayer layer) {
} }
static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2* pos, static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2* pos,
const Vec2* vel, unsigned int parent, const unsigned int target) { const Vec2* vel, unsigned int parent, const unsigned int target) {
Vec2 v; Vec2 v;
double mass = 1; // Presumer lasers have a mass of 1. double mass = 1; // Presumer lasers have a mass of 1.
double rdir = dir; // Real direction (accuracy). double rdir = dir; // Real direction (accuracy).
@ -339,63 +340,63 @@ static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2*
w->think = NULL; w->think = NULL;
switch(outfit->type) { switch(outfit->type) {
case OUTFIT_TYPE_BOLT: case OUTFIT_TYPE_BOLT:
// Need accuracy and speed based on player. -- Another contribution from VLack. // Need accuracy and speed based on player. -- Another contribution from VLack.
rdir += RNG(-outfit->u.blt.accuracy/2., outfit->u.blt.accuracy/2.)/180.*M_PI; 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); if((rdir > 2.*M_PI) || (rdir < 0.)) rdir = fmod(rdir, 2.*M_PI);
vectcpy(&v, vel); vectcpy(&v, vel);
vect_cadd(&v, outfit->u.blt.speed*cos(rdir), outfit->u.blt.speed*sin(rdir)); 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->solid = solid_create(mass, rdir, pos, &v);
w->voice = sound_addVoice(VOICE_PRIORITY_BOLT, w->voice = sound_addVoice(VOICE_PRIORITY_BOLT,
w->solid->pos.x, w->solid->pos.y, w->solid->pos.x, w->solid->pos.y,
w->solid->vel.x, w->solid->vel.y, w->outfit->u.blt.sound, 0); w->solid->vel.x, w->solid->vel.y, w->outfit->u.blt.sound, 0);
break; break;
case OUTFIT_TYPE_MISSILE_SEEK_AMMO: case OUTFIT_TYPE_MISSILE_SEEK_AMMO:
mass = w->outfit->mass; mass = w->outfit->mass;
w->solid = solid_create(mass, dir, pos, vel); w->solid = solid_create(mass, dir, pos, vel);
w->think = think_seeker; // Eeek!!! w->think = think_seeker; // Eeek!!!
w->voice = sound_addVoice(VOICE_PRIORITY_AMMO, w->voice = sound_addVoice(VOICE_PRIORITY_AMMO,
w->solid->pos.x, w->solid->pos.y, w->solid->pos.x, w->solid->pos.y,
w->solid->vel.x, w->solid->vel.y, w->outfit->u.amm.sound, 0); w->solid->vel.x, w->solid->vel.y, w->outfit->u.amm.sound, 0);
break; break;
case OUTFIT_TYPE_MISSILE_SEEK_SMART_AMMO: case OUTFIT_TYPE_MISSILE_SEEK_SMART_AMMO:
mass = w->outfit->mass; mass = w->outfit->mass;
w->solid = solid_create(mass, dir, pos, vel); w->solid = solid_create(mass, dir, pos, vel);
w->think = think_smart; // Smartass. w->think = think_smart; // Smartass.
w->voice = sound_addVoice(VOICE_PRIORITY_AMMO, w->voice = sound_addVoice(VOICE_PRIORITY_AMMO,
w->solid->pos.x, w->solid->pos.y, w->solid->pos.x, w->solid->pos.y,
w->solid->vel.x, w->solid->vel.y, w->outfit->u.amm.sound, 0); w->solid->vel.x, w->solid->vel.y, w->outfit->u.amm.sound, 0);
break; break;
case OUTFIT_TYPE_TURRET_BOLT: case OUTFIT_TYPE_TURRET_BOLT:
if(w->parent != w->target) if(w->parent != w->target)
rdir = vect_angle(pos, &pilot_get(w->target)->solid->pos); rdir = vect_angle(pos, &pilot_get(w->target)->solid->pos);
rdir += RNG(-outfit->u.blt.accuracy/2., rdir += RNG(-outfit->u.blt.accuracy/2.,
outfit->u.blt.accuracy/2.)/180.*M_PI; outfit->u.blt.accuracy/2.)/180.*M_PI;
if((rdir > 2.*M_PI) || (rdir < 0.)) rdir = fmod(rdir, 2.*M_PI); if((rdir > 2.*M_PI) || (rdir < 0.)) rdir = fmod(rdir, 2.*M_PI);
vectcpy(&v, vel); vectcpy(&v, vel);
vect_cadd(&v, outfit->u.blt.speed*cos(rdir), outfit->u.blt.speed*sin(rdir)); 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->solid = solid_create(mass, rdir, pos, &v);
w->voice = sound_addVoice(VOICE_PRIORITY_BOLT, w->voice = sound_addVoice(VOICE_PRIORITY_BOLT,
w->solid->pos.x, w->solid->pos.y, w->solid->pos.x, w->solid->pos.y,
w->solid->vel.x, w->solid->vel.y, w->outfit->u.blt.sound, 0); w->solid->vel.x, w->solid->vel.y, w->outfit->u.blt.sound, 0);
break; break;
default: default:
// Just dump it where the player is. // Just dump it where the player is.
w->voice = NULL; w->voice = NULL;
w->solid = solid_create(mass, dir, pos, vel); w->solid = solid_create(mass, dir, pos, vel);
break; break;
} }
return w; return w;
} }
// Add a new weapon. // Add a new weapon.
void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos, void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos,
const Vec2* vel, unsigned int parent, unsigned int target) { const Vec2* vel, unsigned int parent, unsigned int target) {
if(!outfit_isWeapon(outfit) && 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"); ERR("Trying to create a weapon from a non-Weapon type Outfit");
return; return;
} }
@ -408,30 +409,30 @@ void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos,
int* mLayer = NULL; int* mLayer = NULL;
int* nLayer = NULL; int* nLayer = NULL;
switch(layer) { switch(layer) {
case WEAPON_LAYER_BG: case WEAPON_LAYER_BG:
curLayer = wbackLayer; curLayer = wbackLayer;
nLayer = &nwbackLayer; nLayer = &nwbackLayer;
mLayer = &mwbackLayer; mLayer = &mwbackLayer;
break; break;
case WEAPON_LAYER_FG: case WEAPON_LAYER_FG:
curLayer = wfrontLayer; curLayer = wfrontLayer;
nLayer = &nwfrontLayer; nLayer = &nwfrontLayer;
mLayer = &mwfrontLayer; mLayer = &mwfrontLayer;
break; break;
default: default:
ERR("Invalid WEAPON_LAYER specified."); ERR("Invalid WEAPON_LAYER specified.");
return; return;
} }
if(*mLayer > *nLayer) // More memory allocated than what we need. if(*mLayer > *nLayer) // More memory allocated than what we need.
curLayer[(*nLayer)++] = w; curLayer[(*nLayer)++] = w;
else { // Need to allocate more memory. else { // Need to allocate more memory.
switch(layer) { switch(layer) {
case WEAPON_LAYER_BG: case WEAPON_LAYER_BG:
curLayer = wbackLayer = realloc(curLayer, (++(*mLayer))*sizeof(Weapon*)); curLayer = wbackLayer = realloc(curLayer, (++(*mLayer))*sizeof(Weapon*));
break; break;
case WEAPON_LAYER_FG: case WEAPON_LAYER_FG:
curLayer = wfrontLayer = realloc(curLayer, (++(*mLayer))*sizeof(Weapon*)); curLayer = wfrontLayer = realloc(curLayer, (++(*mLayer))*sizeof(Weapon*));
break; break;
} }
curLayer[(*nLayer)++] = w; curLayer[(*nLayer)++] = w;
} }
@ -443,27 +444,27 @@ static void weapon_destroy(Weapon* w, WeaponLayer layer) {
Weapon** wlayer; Weapon** wlayer;
int* nlayer; int* nlayer;
switch(layer) { switch(layer) {
case WEAPON_LAYER_BG: case WEAPON_LAYER_BG:
wlayer = wbackLayer; wlayer = wbackLayer;
nlayer = &nwbackLayer; nlayer = &nwbackLayer;
break; break;
case WEAPON_LAYER_FG: case WEAPON_LAYER_FG:
wlayer = wfrontLayer; wlayer = wfrontLayer;
nlayer = &nwfrontLayer; nlayer = &nwfrontLayer;
break; break;
} }
for(i = 0; wlayer[i] != w; i++); // Get us to the current posision. for(i = 0; wlayer[i] != w; i++); // Get us to the current posision.
weapon_free(wlayer[i]); weapon_free(wlayer[i]);
wlayer[i] = NULL; wlayer[i] = NULL;
(*nlayer)--; (*nlayer)--;
for(; i < (*nlayer); i++) for(; i < (*nlayer); i++)
wlayer[i] = wlayer[i+1]; wlayer[i] = wlayer[i+1];
} }
// Clear the weapon. // Clear the weapon.
static void weapon_free(Weapon* w) { static void weapon_free(Weapon* w) {
sound_delVoice(w->voice); sound_delVoice(w->voice);
solid_free(w->solid); solid_free(w->solid);
free(w); free(w);
} }

View File

@ -4,8 +4,9 @@
typedef enum { WEAPON_LAYER_BG, WEAPON_LAYER_FG } WeaponLayer; typedef enum { WEAPON_LAYER_BG, WEAPON_LAYER_FG } WeaponLayer;
void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos, void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos,
const Vec2* vel, unsigned int parent, const unsigned int target); const Vec2* vel, unsigned int parent,
const unsigned int target);
// Pausing. // Pausing.
void weapons_pause(void); void weapons_pause(void);

View File

@ -7,7 +7,7 @@
// Check if node n is of name s. // Check if node n is of name s.
#define xml_isNode(n,s) (((n)->type == XML_NODE_START) && \ #define xml_isNode(n,s) (((n)->type == XML_NODE_START) && \
(strcmp((char*)(n)->name, s)==0)) (strcmp((char*)(n)->name, s)==0))
// Get the property s of node n. This mallocs. // Get the property s of node n. This mallocs.
#define xml_nodeProp(n,s) (char*)xmlGetProp(n, (xmlChar*)s) #define xml_nodeProp(n,s) (char*)xmlGetProp(n, (xmlChar*)s)