[Fix] Moving from tab to space messed all the indents up. I thing that got them all now.
This commit is contained in:
parent
0f6ff44a93
commit
6a7c051851
88
src/ai.c
88
src/ai.c
@ -29,7 +29,7 @@
|
||||
// B and until the control task comes in. Then the pilot could
|
||||
// run if it deems fit that Pilot C and Pilot B together are
|
||||
// both too strong for A. Or.. Attack C as it is an easy target
|
||||
// to finish.
|
||||
// to finish.
|
||||
// Basically, there is many possibilities, and it's down to the
|
||||
// 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))
|
||||
// L state, void* buf, int n size, char* s identifier.
|
||||
#define luaL_dobuffer(L,b,n,s) \
|
||||
(luaL_loadbuffer(L,b,n,s) || lua_pcall(L, 0, LUA_MULTRET, 0))
|
||||
(luaL_loadbuffer(L,b,n,s) || lua_pcall(L, 0, LUA_MULTRET, 0))
|
||||
|
||||
// Don't run the function if (n) params aren't passed.
|
||||
#define MIN_ARGS(n) if(lua_gettop(L) < n) return 0
|
||||
@ -220,7 +220,7 @@ static void ai_run(const char* funcname) {
|
||||
if(lua_pcall(L, 0, 0, 0))
|
||||
// Errors accured.
|
||||
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.
|
||||
@ -240,8 +240,8 @@ int ai_init(void) {
|
||||
// Load the profiles.
|
||||
for(i = 0; i < nfiles; i++)
|
||||
if((strncmp(files[i], AI_PREFIX, strlen(AI_PREFIX))==0 &&
|
||||
strncmp(files[i] + strlen(files[i]) - strlen(AI_SUFFIX),
|
||||
AI_SUFFIX, strlen(AI_SUFFIX))==0))
|
||||
strncmp(files[i] + strlen(files[i]) - strlen(AI_SUFFIX),
|
||||
AI_SUFFIX, strlen(AI_SUFFIX))==0))
|
||||
if(ai_loadProfile(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[nprofiles-1].name =
|
||||
malloc(sizeof(char)*
|
||||
(strlen(filename)-strlen(AI_PREFIX)-strlen(AI_SUFFIX))+1);
|
||||
malloc(sizeof(char)*
|
||||
(strlen(filename)-strlen(AI_PREFIX)-strlen(AI_SUFFIX))+1);
|
||||
|
||||
snprintf(profiles[nprofiles-1].name,
|
||||
strlen(filename)-strlen(AI_PREFIX)-strlen(AI_SUFFIX)+1,
|
||||
"%s", filename+strlen(AI_PREFIX));
|
||||
strlen(filename)-strlen(AI_PREFIX)-strlen(AI_SUFFIX)+1,
|
||||
"%s", filename+strlen(AI_PREFIX));
|
||||
|
||||
profiles[nprofiles-1].L = luaL_newstate();
|
||||
|
||||
@ -305,7 +305,7 @@ static int ai_loadProfile(char* filename) {
|
||||
// Get the AI_Profile with name.
|
||||
AI_Profile* ai_getProfile(char* name) {
|
||||
if(profiles == NULL) return NULL;
|
||||
|
||||
|
||||
int i;
|
||||
for(i = 0; i < nprofiles; i++)
|
||||
if(strcmp(name, profiles[i].name)==0)
|
||||
@ -329,7 +329,7 @@ void ai_exit(void) {
|
||||
void ai_think(Pilot* pilot) {
|
||||
cur_pilot = pilot; // Set current pilot being processed.
|
||||
L = cur_pilot->ai->L; // Set the AI profile to the current pilot's.
|
||||
|
||||
|
||||
// Clean up some variables.
|
||||
pilot_acc = pilot_turn = 0.;
|
||||
pilot_flags = 0;
|
||||
@ -354,8 +354,8 @@ void ai_think(Pilot* pilot) {
|
||||
if(pilot_turn) // Set the turning velocity.
|
||||
cur_pilot->solid->dir_vel -= cur_pilot->turn * pilot_turn;
|
||||
vect_pset(&cur_pilot->solid->force, cur_pilot->thrust * pilot_acc,
|
||||
cur_pilot->solid->dir);
|
||||
|
||||
cur_pilot->solid->dir);
|
||||
|
||||
// Fire weapons if needs be.
|
||||
if(ai_isFlag(AI_PRIMARY)) pilot_shoot(pilot, pilot_target, 0); // Primary.
|
||||
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;
|
||||
else d = cur_pilot->shield;
|
||||
|
||||
|
||||
lua_pushnumber(L, d);
|
||||
return 1;
|
||||
}
|
||||
@ -506,7 +506,7 @@ static int ai_shield(lua_State* L) {
|
||||
static int ai_parmour(lua_State* L) {
|
||||
double d;
|
||||
Pilot* p;
|
||||
|
||||
|
||||
if(lua_isnumber(L,1)) {
|
||||
p = pilot_get((unsigned int)lua_tonumber(L,1));
|
||||
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) {
|
||||
double d;
|
||||
Pilot* p;
|
||||
|
||||
|
||||
if(lua_isnumber(L,1)) {
|
||||
p = pilot_get((unsigned int)lua_tonumber(L,1));
|
||||
d = p->shield / p->shield_max * 100.;
|
||||
@ -557,22 +557,22 @@ static int ai_getpos(lua_State* L) {
|
||||
|
||||
// ========================================================
|
||||
// Get the minimum braking distance.
|
||||
//
|
||||
//
|
||||
// Braking vel ==> 0 = v - a*dt
|
||||
// Add turn around time (to initial velocity) :
|
||||
// ==> 180.*360./cur_pilot->turn
|
||||
// Add it to general euler equation x = v*t + 0.5 * a * t^2
|
||||
// Have fun.
|
||||
//
|
||||
//
|
||||
// I really hate this function. Why isn't it depricated yet?
|
||||
// ========================================================
|
||||
static int ai_minbrakedist(lua_State* L) {
|
||||
double time, dist;
|
||||
time = VMOD(cur_pilot->solid->vel) /
|
||||
(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) -
|
||||
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
|
||||
return 1;
|
||||
@ -585,7 +585,7 @@ static int ai_cargofree(lua_State* L) {
|
||||
|
||||
static int ai_exists(lua_State* L) {
|
||||
MIN_ARGS(1);
|
||||
|
||||
|
||||
if(lua_isnumber(L,1)) {
|
||||
lua_pushboolean(L, (pilot_get((unsigned int)lua_tonumber(L,1)) != NULL)?1:0);
|
||||
return 1;
|
||||
@ -609,14 +609,14 @@ static int ai_isstopped(lua_State* L) {
|
||||
static int ai_isenemy(lua_State* L) {
|
||||
if(lua_isnumber(L,1))
|
||||
lua_pushboolean(L, areEnemies(cur_pilot->faction,
|
||||
pilot_get(lua_tonumber(L,1))->faction));
|
||||
pilot_get(lua_tonumber(L,1))->faction));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Check if the pilot is an ally.
|
||||
static int ai_isally(lua_State* L) {
|
||||
lua_pushboolean(L, areAllies(cur_pilot->faction,
|
||||
pilot_get(lua_tonumber(L,1))->faction));
|
||||
pilot_get(lua_tonumber(L,1))->faction));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -653,15 +653,15 @@ static int ai_face(lua_State* L) {
|
||||
double mod, diff;
|
||||
int invert = 0;
|
||||
int n = -2;
|
||||
|
||||
|
||||
if(lua_isnumber(L, 1))
|
||||
n = (int)lua_tonumber(L, 1);
|
||||
|
||||
|
||||
if(n >= 0) {
|
||||
p = pilot_get(n);
|
||||
if(p == NULL) return 0; // Make sure pilot is valid.
|
||||
vect_cset(&tv, VX(p->solid->pos) + FACE_WVEL*VX(p->solid->vel),
|
||||
VY(p->solid->pos) + FACE_WVEL*VY(p->solid->vel));
|
||||
VY(p->solid->pos) + FACE_WVEL*VY(p->solid->vel));
|
||||
v = NULL;
|
||||
}
|
||||
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(invert) mod *= -1;
|
||||
vect_cset(&sv, VX(cur_pilot->solid->pos) + FACE_WVEL*VX(cur_pilot->solid->vel),
|
||||
VY(cur_pilot->solid->pos) + FACE_WVEL*VY(cur_pilot->solid->vel));
|
||||
|
||||
VY(cur_pilot->solid->pos) + FACE_WVEL*VY(cur_pilot->solid->vel));
|
||||
|
||||
if(v != NULL)
|
||||
// Target is static.
|
||||
diff = angle_diff(cur_pilot->solid->dir,
|
||||
(n==-1) ? VANGLE(cur_pilot->solid->pos) :
|
||||
vect_angle(&cur_pilot->solid->pos, v));
|
||||
(n==-1) ? VANGLE(cur_pilot->solid->pos) :
|
||||
vect_angle(&cur_pilot->solid->pos, v));
|
||||
else
|
||||
// Target is dynamic.
|
||||
diff = angle_diff(cur_pilot->solid->dir,
|
||||
(n==-1) ? VANGLE(sv) :
|
||||
vect_angle(&sv, &tv));
|
||||
|
||||
(n==-1) ? VANGLE(sv) :
|
||||
vect_angle(&sv, &tv));
|
||||
|
||||
pilot_turn = mod*diff;
|
||||
|
||||
lua_pushnumber(L, ABS(diff*180./M_PI));
|
||||
@ -712,12 +712,12 @@ static int ai_getnearestplanet(lua_State* L) {
|
||||
|
||||
double dist, d;
|
||||
int i, j;
|
||||
|
||||
|
||||
// Cycle through planets.
|
||||
for(dist = 0., j = -1, i = 0; i < cur_system->nplanets; i++) {
|
||||
d = vect_dist(&cur_system->planets[i].pos, &cur_pilot->solid->pos);
|
||||
if((!areEnemies(cur_pilot->faction, cur_system->planets[i].faction)) &&
|
||||
(d < dist)) {
|
||||
(d < dist)) {
|
||||
// Closer friendly planet.
|
||||
j = i;
|
||||
dist = d;
|
||||
@ -742,7 +742,7 @@ static int ai_getrndplanet(lua_State* L) {
|
||||
|
||||
for(nplanets = 0, i = 0; i < cur_system->nplanets; i++)
|
||||
if(planet_hasService(&cur_system->planets[i], PLANET_SERVICE_BASIC) &&
|
||||
!areEnemies(cur_pilot->faction, cur_system->planets[i].faction))
|
||||
!areEnemies(cur_pilot->faction, cur_system->planets[i].faction))
|
||||
planets[nplanets++] = &cur_system->planets[i];
|
||||
|
||||
// No planet to land on found.
|
||||
@ -755,7 +755,7 @@ static int ai_getrndplanet(lua_State* L) {
|
||||
i = RNG(0,nplanets-1);
|
||||
vectcpy(&v, &planets[i]->pos);
|
||||
vect_cadd(&v, RNG(0, planets[i]->gfx_space->sw)-planets[i]->gfx_space->sw/2.,
|
||||
RNG(0, planets[i]->gfx_space->sh)-planets[i]->gfx_space->sh/2.);
|
||||
RNG(0, planets[i]->gfx_space->sh)-planets[i]->gfx_space->sh/2.);
|
||||
lua_pushlightuserdata(L, &v);
|
||||
free(planets);
|
||||
return 1;
|
||||
@ -778,7 +778,7 @@ static int ai_stop(lua_State* L) {
|
||||
|
||||
if(VMOD(cur_pilot->solid->vel) < MIN_VEL_ERR)
|
||||
vect_pset(&cur_pilot->solid->vel, 0., 0.);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -814,10 +814,10 @@ static int ai_secondary(lua_State* L) {
|
||||
int i;
|
||||
for(i = 0; i < cur_pilot->noutfits; i++) {
|
||||
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];
|
||||
else if((po != NULL) && outfit_isWeapon(po->outfit) &&
|
||||
outfit_isLauncher(cur_pilot->outfits[i].outfit))
|
||||
else if((po != NULL) && outfit_isWeapon(po->outfit) &&
|
||||
outfit_isLauncher(cur_pilot->outfits[i].outfit))
|
||||
po = &cur_pilot->outfits[i];
|
||||
}
|
||||
if(po) {
|
||||
@ -889,7 +889,7 @@ static int ai_timeup(lua_State* L) {
|
||||
// Have the pilot say something to player.
|
||||
static int ai_comm(lua_State* L) {
|
||||
MIN_ARGS(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));
|
||||
|
||||
@ -913,7 +913,7 @@ static int ai_credits(lua_State* L) {
|
||||
|
||||
if(lua_isnumber(L,1))
|
||||
cur_pilot->credits = (int)lua_tonumber(L,1);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -924,7 +924,7 @@ static int ai_cargo(lua_State* L) {
|
||||
|
||||
if(lua_isstring(L,1) && lua_isnumber(L,2))
|
||||
pilot_addCargo(cur_pilot, commodity_get(lua_tostring(L,1)),
|
||||
(int)lua_tonumber(L,2));
|
||||
(int)lua_tonumber(L,2));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
2
src/ai.h
2
src/ai.h
@ -16,7 +16,7 @@ typedef enum TaskData_ { TYPE_NULL, TYPE_INT, TYPE_PTR } TaskData;
|
||||
typedef struct Task_ {
|
||||
struct Task_* next;
|
||||
char* name;
|
||||
|
||||
|
||||
TaskData dtype;
|
||||
union {
|
||||
void* target; // Vec2 etc.
|
||||
|
234
src/board.c
234
src/board.c
@ -23,166 +23,166 @@ static void board_update(void);
|
||||
|
||||
// Attempt to board the players target.
|
||||
void player_board(void) {
|
||||
Pilot* p;
|
||||
Pilot* p;
|
||||
|
||||
if(player_target == PLAYER_ID) {
|
||||
player_message("You need a target to board first!");
|
||||
return;
|
||||
}
|
||||
if(player_target == PLAYER_ID) {
|
||||
player_message("You need a target to board first!");
|
||||
return;
|
||||
}
|
||||
|
||||
p = pilot_get(player_target);
|
||||
p = pilot_get(player_target);
|
||||
|
||||
if(!pilot_isDisabled(p)) {
|
||||
player_message("You cannot board a ship that is not disabled!");
|
||||
return;
|
||||
}
|
||||
else if(vect_dist(&player->solid->pos, &p->solid->pos) >
|
||||
p->ship->gfx_space->sw * PILOT_SIZE_APROX) {
|
||||
player_message("You are too far away to board your target");
|
||||
return;
|
||||
}
|
||||
else if((pow2(VX(player->solid->vel)-VX(p->solid->vel)) +
|
||||
pow2(VY(player->solid->vel)-VY(p->solid->vel))) >
|
||||
(double)pow2(MAX_HYPERSPACE_VEL)) {
|
||||
player_message("You are going too fast to board the ship");
|
||||
return;
|
||||
}
|
||||
else if(pilot_isFlag(p, PILOT_BOARDED)) {
|
||||
player_message("Your target cannot be boarded again");
|
||||
return;
|
||||
}
|
||||
|
||||
// Pilot will be boarded.
|
||||
pilot_setFlag(p, PILOT_BOARDED);
|
||||
player_message("Boarding ship %s", p->name);
|
||||
if(!pilot_isDisabled(p)) {
|
||||
player_message("You cannot board a ship that is not disabled!");
|
||||
return;
|
||||
}
|
||||
else if(vect_dist(&player->solid->pos, &p->solid->pos) >
|
||||
p->ship->gfx_space->sw * PILOT_SIZE_APROX) {
|
||||
player_message("You are too far away to board your target");
|
||||
return;
|
||||
}
|
||||
else if((pow2(VX(player->solid->vel)-VX(p->solid->vel)) +
|
||||
pow2(VY(player->solid->vel)-VY(p->solid->vel))) >
|
||||
(double)pow2(MAX_HYPERSPACE_VEL)) {
|
||||
player_message("You are going too fast to board the ship");
|
||||
return;
|
||||
}
|
||||
else if(pilot_isFlag(p, PILOT_BOARDED)) {
|
||||
player_message("Your target cannot be boarded again");
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the boarding window.
|
||||
board_wid = window_create("Boarding", -1, -1, BOARDING_WIDTH, BOARDING_HEIGHT);
|
||||
// Pilot will be boarded.
|
||||
pilot_setFlag(p, PILOT_BOARDED);
|
||||
player_message("Boarding ship %s", p->name);
|
||||
|
||||
window_addText(board_wid, 20, -30, 120, 60,
|
||||
0, "txtCargo", &gl_smallFont, &cDConsole,
|
||||
"SCreds:\n"
|
||||
"Cargo:\n");
|
||||
|
||||
window_addText(board_wid, 80, -30, 120, 60, 0, "txtData",
|
||||
&gl_smallFont, &cBlack, NULL);
|
||||
// Create the boarding window.
|
||||
board_wid = window_create("Boarding", -1, -1, BOARDING_WIDTH, BOARDING_HEIGHT);
|
||||
|
||||
window_addButton(board_wid, 20, 20, 50, 30, "btnStealCredits",
|
||||
"Credits", board_stealCreds);
|
||||
window_addText(board_wid, 20, -30, 120, 60,
|
||||
0, "txtCargo", &gl_smallFont, &cDConsole,
|
||||
"SCreds:\n"
|
||||
"Cargo:\n");
|
||||
|
||||
window_addButton(board_wid, 90, 20, 50, 30, "btnStealCargo",
|
||||
"Cargo", board_stealCargo);
|
||||
window_addText(board_wid, 80, -30, 120, 60, 0, "txtData",
|
||||
&gl_smallFont, &cBlack, NULL);
|
||||
|
||||
window_addButton(board_wid, -20, 20, 50, 30, "btnBoardingClose",
|
||||
"Leave", board_exit);
|
||||
window_addButton(board_wid, 20, 20, 50, 30, "btnStealCredits",
|
||||
"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) {
|
||||
(void)str;
|
||||
window_destroy(window_get("Boarding"));
|
||||
(void)str;
|
||||
window_destroy(window_get("Boarding"));
|
||||
}
|
||||
|
||||
static void board_stealCreds(char* str) {
|
||||
(void)str;
|
||||
Pilot* p;
|
||||
(void)str;
|
||||
Pilot* p;
|
||||
|
||||
p = pilot_get(player_target);
|
||||
p = pilot_get(player_target);
|
||||
|
||||
if(p->credits == 0) {
|
||||
// Can't steal from the poor. ;)
|
||||
player_message("The ship has no SCreds.");
|
||||
return;
|
||||
}
|
||||
if(p->credits == 0) {
|
||||
// Can't steal from the poor. ;)
|
||||
player_message("The ship has no SCreds.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(board_fail()) return;
|
||||
if(board_fail()) return;
|
||||
|
||||
player_credits += p->credits;
|
||||
p->credits = 0;
|
||||
board_update(); // Update the lack of credits.
|
||||
player_message("You manage to steal the ship's Scred.");
|
||||
player_credits += p->credits;
|
||||
p->credits = 0;
|
||||
board_update(); // Update the lack of credits.
|
||||
player_message("You manage to steal the ship's Scred.");
|
||||
}
|
||||
|
||||
static void board_stealCargo(char* str) {
|
||||
(void)str;
|
||||
int q;
|
||||
Pilot* p;
|
||||
(void)str;
|
||||
int q;
|
||||
Pilot* p;
|
||||
|
||||
p = pilot_get(player_target);
|
||||
p = pilot_get(player_target);
|
||||
|
||||
if(p->ncommodities==0) {
|
||||
// No cargo.
|
||||
player_message("The ship has no cargo.");
|
||||
return;
|
||||
}
|
||||
else if(player->cargo_free <= 0) {
|
||||
player_message("You have no room for cargo.");
|
||||
return;
|
||||
}
|
||||
if(p->ncommodities==0) {
|
||||
// No cargo.
|
||||
player_message("The ship has no cargo.");
|
||||
return;
|
||||
}
|
||||
else if(player->cargo_free <= 0) {
|
||||
player_message("You have no room for cargo.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(board_fail()) return;
|
||||
if(board_fail()) return;
|
||||
|
||||
// Steal as much as possible until full - TODO: Allow the player to choose.
|
||||
q = 1;
|
||||
while((p->ncommodities > 0) && (q != 0)) {
|
||||
q = pilot_addCargo(player, p->commodities[0].commodity,
|
||||
p->commodities[0].quantity);
|
||||
// Steal as much as possible until full - TODO: Allow the player to choose.
|
||||
q = 1;
|
||||
while((p->ncommodities > 0) && (q != 0)) {
|
||||
q = pilot_addCargo(player, p->commodities[0].commodity,
|
||||
p->commodities[0].quantity);
|
||||
|
||||
pilot_rmCargo(p, p->commodities[0].commodity, q);
|
||||
}
|
||||
pilot_rmCargo(p, p->commodities[0].commodity, q);
|
||||
}
|
||||
|
||||
board_update();
|
||||
player_message("You manage to steal the ship's cargo.");
|
||||
board_update();
|
||||
player_message("You manage to steal the ship's cargo.");
|
||||
}
|
||||
|
||||
// Failed to board.
|
||||
static int board_fail(void) {
|
||||
Pilot* p;
|
||||
Pilot* p;
|
||||
|
||||
p = pilot_get(player_target);
|
||||
p = pilot_get(player_target);
|
||||
|
||||
// Fail chance.
|
||||
if(RNG(0, 100) > (int)(50. *
|
||||
(10. + (double)p->ship->crew/10.+(double)player->ship->crew)))
|
||||
return 0;
|
||||
// Fail chance.
|
||||
if(RNG(0, 100) > (int)(50. *
|
||||
(10. + (double)p->ship->crew/10.+(double)player->ship->crew)))
|
||||
return 0;
|
||||
|
||||
if(RNG(0, 2)==0) {
|
||||
// 33% of instant death.
|
||||
p->armour = -1;
|
||||
player_message("You have tripped the ship's self destruct mechanism!");
|
||||
} else
|
||||
// You just got locked out!!
|
||||
player_message("The ship's security system locks you out!");
|
||||
|
||||
board_exit(NULL);
|
||||
return 1;
|
||||
if(RNG(0, 2)==0) {
|
||||
// 33% of instant death.
|
||||
p->armour = -1;
|
||||
player_message("You have tripped the ship's self destruct mechanism!");
|
||||
} else
|
||||
// You just got locked out!!
|
||||
player_message("The ship's security system locks you out!");
|
||||
|
||||
board_exit(NULL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Update the cargo and credit fields.
|
||||
static void board_update(void) {
|
||||
int i;
|
||||
char str[128], buf[32];
|
||||
char cred[10];
|
||||
Pilot* p;
|
||||
int i;
|
||||
char str[128], buf[32];
|
||||
char cred[10];
|
||||
Pilot* p;
|
||||
|
||||
p = pilot_get(player_target);
|
||||
p = pilot_get(player_target);
|
||||
|
||||
credits2str(cred, p->credits, 2);
|
||||
credits2str(cred, p->credits, 2);
|
||||
|
||||
snprintf(str, 11,
|
||||
"%s\n", cred);
|
||||
if(p->ncommodities == 0)
|
||||
strncat(str, "none", 10);
|
||||
else {
|
||||
for(i = 0; i < p->ncommodities; i++) {
|
||||
snprintf(buf, 32,
|
||||
"%d %s\n",
|
||||
p->commodities[i].quantity, p->commodities[i].commodity->name);
|
||||
strncat(str, buf, 32);
|
||||
}
|
||||
snprintf(str, 11,
|
||||
"%s\n", cred);
|
||||
if(p->ncommodities == 0)
|
||||
strncat(str, "none", 10);
|
||||
else {
|
||||
for(i = 0; i < p->ncommodities; i++) {
|
||||
snprintf(buf, 32,
|
||||
"%d %s\n",
|
||||
p->commodities[i].quantity, p->commodities[i].commodity->name);
|
||||
strncat(str, buf, 32);
|
||||
}
|
||||
}
|
||||
|
||||
window_modifyText(board_wid, "txtData", str);
|
||||
window_modifyText(board_wid, "txtData", str);
|
||||
}
|
||||
|
||||
|
@ -13,15 +13,15 @@
|
||||
// bsy - Position of y of sprite b.
|
||||
// bp - Position in space of sprite b.
|
||||
int CollideSprite(const glTexture* at, const int asx, const int asy,
|
||||
const Vec2* ap, const glTexture* bt,
|
||||
const int bsx, const int bsy, const Vec2* bp) {
|
||||
|
||||
const Vec2* ap, const glTexture* bt,
|
||||
const int bsx, const int bsy, const Vec2* bp) {
|
||||
|
||||
int x,y;
|
||||
int ax1, ax2, ay1, ay2;
|
||||
int bx1, bx2, by1, by2;
|
||||
int inter_x0, inter_x1, inter_y0, inter_y1;
|
||||
int rasy, rbsy;
|
||||
int abx, aby, bbx, bby;
|
||||
int ax1, ax2, ay1, ay2;
|
||||
int bx1, bx2, by1, by2;
|
||||
int inter_x0, inter_x1, inter_y0, inter_y1;
|
||||
int rasy, rbsy;
|
||||
int abx, aby, bbx, bby;
|
||||
|
||||
// a - cube coords.
|
||||
ax1 = (int)VX(*ap) - (int)(at->sw)/2;
|
||||
@ -34,7 +34,7 @@ int CollideSprite(const glTexture* at, const int asx, const int asy,
|
||||
by1 = (int)VY(*bp) - (int)(bt->sh)/2;
|
||||
bx2 = bx1 + (int)(bt->sw) - 1;
|
||||
by2 = by1 + (int)(bt->sh) - 1;
|
||||
|
||||
|
||||
// Check if bounding boxes intersect.
|
||||
if((bx2 < ax1) || (ax2 < bx1)) 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_y0 = MAX(ay1, by1);
|
||||
inter_y1 = MIN(ay2, by2);
|
||||
|
||||
|
||||
// Real vertical sprite value (flipped).
|
||||
rasy = at->sy - asy - 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++)
|
||||
// Compute offsets for surface before passing to TransparentPixel test.
|
||||
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 0;
|
||||
|
@ -3,6 +3,6 @@
|
||||
#include "physics.h"
|
||||
|
||||
int CollideSprite(const glTexture* at, const int asx, const int asy,
|
||||
const Vec2* ap, const glTexture* bt,
|
||||
const int bsx, const int bsy, const Vec2* bp);
|
||||
const Vec2* ap, const glTexture* bt,
|
||||
const int bsx, const int bsy, const Vec2* bp);
|
||||
|
||||
|
120
src/conf.c
120
src/conf.c
@ -15,33 +15,33 @@
|
||||
#include "conf.h"
|
||||
|
||||
#define conf_loadInt(n,i) \
|
||||
lua_getglobal(L,n); \
|
||||
if(lua_isnumber(L, -1)) { \
|
||||
lua_getglobal(L,n); \
|
||||
if(lua_isnumber(L, -1)) { \
|
||||
i = (int)lua_tonumber(L, -1); \
|
||||
lua_remove(L, -1); \
|
||||
}
|
||||
}
|
||||
|
||||
#define conf_loadFloat(n,f) \
|
||||
lua_getglobal(L,n); \
|
||||
if(lua_isnumber(L, -1)) { \
|
||||
f = (double)lua_tonumber(L, -1); \
|
||||
lua_remove(L,-1);\
|
||||
}
|
||||
lua_getglobal(L,n); \
|
||||
if(lua_isnumber(L, -1)) { \
|
||||
f = (double)lua_tonumber(L, -1); \
|
||||
lua_remove(L,-1);\
|
||||
}
|
||||
|
||||
#define conf_loadBool(n,b) \
|
||||
lua_getglobal(L,n); \
|
||||
if(lua_isnumber(L, -1)) \
|
||||
lua_getglobal(L,n); \
|
||||
if(lua_isnumber(L, -1)) \
|
||||
if((int)lua_tonumber(L, -1) == 1) { \
|
||||
b = 1; \
|
||||
lua_remove(L, -1); \
|
||||
b = 1; \
|
||||
lua_remove(L, -1); \
|
||||
} \
|
||||
|
||||
#define conf_loadString(n,s) \
|
||||
lua_getglobal(L,n); \
|
||||
if(lua_isstring(L, -1)) { \
|
||||
lua_getglobal(L,n); \
|
||||
if(lua_isstring(L, -1)) { \
|
||||
s = strdup((char*)lua_tostring(L, -1)); \
|
||||
lua_remove(L, -1); \
|
||||
}
|
||||
}
|
||||
|
||||
// Some crap from main.
|
||||
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-j n, --joystick n - Use joystick (n)");
|
||||
LOG("\t-J s, --joystick s - Use joystick whose name contains (s)");
|
||||
LOG("\t-m f, --music f - Set the music volume to f");
|
||||
LOG("\t-s f, --sound f - Set the sound volume to f");
|
||||
LOG("\t-m f, --music f - Set the music volume to f");
|
||||
LOG("\t-s f, --sound f - Set the sound volume to f");
|
||||
LOG("\t-h --help - Display this message and exit.");
|
||||
LOG("\t-v - Print the version and exit");
|
||||
}
|
||||
@ -89,7 +89,7 @@ void conf_setDefaults(void) {
|
||||
// Ok.. Parse a config file plox.
|
||||
int conf_loadConfig(const char* file) {
|
||||
int i = 0;
|
||||
double d = 0.;
|
||||
double d = 0.;
|
||||
|
||||
lua_State* L = luaL_newstate();
|
||||
if(luaL_dofile(L, file) == 0) {
|
||||
@ -104,28 +104,28 @@ int conf_loadConfig(const char* file) {
|
||||
if(i) { gl_screen.flags |= OPENGL_FULLSCREEN; i = 0; }
|
||||
conf_loadBool("aa", i);
|
||||
if(i) {
|
||||
gl_screen.flags |= OPENGL_AA_POINT | OPENGL_AA_LINE || OPENGL_AA_POLYGON;
|
||||
i = 0;
|
||||
}
|
||||
gl_screen.flags |= OPENGL_AA_POINT | OPENGL_AA_LINE || OPENGL_AA_POLYGON;
|
||||
i = 0;
|
||||
}
|
||||
conf_loadBool("aa_point", i);
|
||||
if(i) { gl_screen.flags |= OPENGL_AA_POINT; i = 0; }
|
||||
conf_loadBool("aa_line", i)
|
||||
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);
|
||||
if(i) { gl_screen.flags |= OPENGL_AA_POLYGON; i = 0; }
|
||||
|
||||
// FPS.
|
||||
conf_loadBool("showfps", show_fps);
|
||||
// FPS.
|
||||
conf_loadBool("showfps", show_fps);
|
||||
conf_loadInt("maxfps", max_fps);
|
||||
|
||||
// Input.
|
||||
conf_loadInt("afterburn", input_afterburnSensibility);
|
||||
// Input.
|
||||
conf_loadInt("afterburn", input_afterburnSensibility);
|
||||
|
||||
// Sound.
|
||||
conf_loadFloat("sound", d);
|
||||
if(d) { sound_volume(d); d = 0.; }
|
||||
conf_loadFloat("music", d);
|
||||
if(d) { music_volume(d); d = 0.; }
|
||||
// Sound.
|
||||
conf_loadFloat("sound", d);
|
||||
if(d) { sound_volume(d); d = 0.; }
|
||||
conf_loadFloat("music", d);
|
||||
if(d) { music_volume(d); d = 0.; }
|
||||
|
||||
// Joystick.
|
||||
lua_getglobal(L, "joystick");
|
||||
@ -205,8 +205,8 @@ void conf_parseCLI(int argc, char** argv) {
|
||||
{ "data", required_argument, 0, 'd' },
|
||||
{ "joystick", required_argument, 0, 'j' },
|
||||
{ "Joystick", required_argument, 0, 'J' },
|
||||
{ "music", required_argument, 0, 'm' },
|
||||
{ "sound", required_argument, 0, 's' },
|
||||
{ "music", required_argument, 0, 'm' },
|
||||
{ "sound", required_argument, 0, 's' },
|
||||
{ "help", no_argument, 0, 'h' },
|
||||
{ "version", no_argument, 0, 'v' },
|
||||
{ NULL, 0, 0, 0 }
|
||||
@ -215,34 +215,34 @@ void conf_parseCLI(int argc, char** argv) {
|
||||
int c = 0;
|
||||
|
||||
while((c = getopt_long(argc, argv, "fF:d:J:j:s:m:V:hv",
|
||||
long_options, &option_index)) != -1) {
|
||||
long_options, &option_index)) != -1) {
|
||||
switch(c) {
|
||||
case 'f':
|
||||
gl_screen.flags |= OPENGL_FULLSCREEN;
|
||||
break;
|
||||
case 'F':
|
||||
max_fps = atoi(optarg);
|
||||
break;
|
||||
case 'd':
|
||||
data = strdup(optarg);
|
||||
break;
|
||||
case 'j':
|
||||
indjoystick = atoi(optarg);
|
||||
break;
|
||||
case 'J':
|
||||
namjoystick = strdup(optarg);
|
||||
break;
|
||||
case 'm':
|
||||
music_volume(atof(optarg));
|
||||
break;
|
||||
case 's':
|
||||
sound_volume(atof(optarg));
|
||||
break;
|
||||
case 'v':
|
||||
LOG(APPNAME": version %d.%d.%d", VMAJOR, VMINOR, VREV);
|
||||
case 'h':
|
||||
print_usage(argv);
|
||||
exit(EXIT_SUCCESS);
|
||||
case 'f':
|
||||
gl_screen.flags |= OPENGL_FULLSCREEN;
|
||||
break;
|
||||
case 'F':
|
||||
max_fps = atoi(optarg);
|
||||
break;
|
||||
case 'd':
|
||||
data = strdup(optarg);
|
||||
break;
|
||||
case 'j':
|
||||
indjoystick = atoi(optarg);
|
||||
break;
|
||||
case 'J':
|
||||
namjoystick = strdup(optarg);
|
||||
break;
|
||||
case 'm':
|
||||
music_volume(atof(optarg));
|
||||
break;
|
||||
case 's':
|
||||
sound_volume(atof(optarg));
|
||||
break;
|
||||
case 'v':
|
||||
LOG(APPNAME": version %d.%d.%d", VMAJOR, VMINOR, VREV);
|
||||
case 'h':
|
||||
print_usage(argv);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
160
src/economy.c
160
src/economy.c
@ -22,115 +22,115 @@ static Commodity* commodity_parse(xmlNodePtr parent);
|
||||
// Convert credits to a usable string for displaying.
|
||||
// str must have 10 characters allocated.
|
||||
void credits2str(char* str, unsigned int credits, int decimals) {
|
||||
if(decimals < 0)
|
||||
snprintf(str, 32, "%d", credits);
|
||||
else if(credits >= 1000000000)
|
||||
snprintf(str, 16, "%.*fB", decimals, (double)credits / 1000000000.);
|
||||
else if(credits >= 1000000)
|
||||
snprintf(str, 16, "%*fM", decimals, (double)credits / 1000000.);
|
||||
else if(credits >= 1000)
|
||||
snprintf(str, 16, "%.*fK", decimals, (double)credits / 1000.);
|
||||
else snprintf(str, 16, "%d", credits);
|
||||
if(decimals < 0)
|
||||
snprintf(str, 32, "%d", credits);
|
||||
else if(credits >= 1000000000)
|
||||
snprintf(str, 16, "%.*fB", decimals, (double)credits / 1000000000.);
|
||||
else if(credits >= 1000000)
|
||||
snprintf(str, 16, "%*fM", decimals, (double)credits / 1000000.);
|
||||
else if(credits >= 1000)
|
||||
snprintf(str, 16, "%.*fK", decimals, (double)credits / 1000.);
|
||||
else snprintf(str, 16, "%d", credits);
|
||||
}
|
||||
|
||||
// Get a commodity.
|
||||
Commodity* commodity_get(const char* name) {
|
||||
int i;
|
||||
for(i = 0; i < commodity_nstack; i++)
|
||||
if(strcmp(commodity_stack[i].name, name)==0)
|
||||
return &commodity_stack[i];
|
||||
|
||||
WARN("Commodity '%s' not found in stack", name);
|
||||
return NULL;
|
||||
int i;
|
||||
for(i = 0; i < commodity_nstack; i++)
|
||||
if(strcmp(commodity_stack[i].name, name)==0)
|
||||
return &commodity_stack[i];
|
||||
|
||||
WARN("Commodity '%s' not found in stack", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Free a commodity.
|
||||
static void commodity_freeOne(Commodity* com) {
|
||||
if(com->name) free(com->name);
|
||||
if(com->description) free(com->description);
|
||||
if(com->name) free(com->name);
|
||||
if(com->description) free(com->description);
|
||||
}
|
||||
|
||||
static Commodity* commodity_parse(xmlNodePtr parent) {
|
||||
xmlNodePtr node;
|
||||
Commodity* tmp = CALLOC_L(Commodity);
|
||||
xmlNodePtr node;
|
||||
Commodity* tmp = CALLOC_L(Commodity);
|
||||
|
||||
tmp->name = (char*)xmlGetProp(parent, (xmlChar*)"name");
|
||||
if(tmp->name == NULL)
|
||||
WARN("Commodity from "COMMODITY_DATA" has invalid or noname");
|
||||
|
||||
node = parent->xmlChildrenNode;
|
||||
tmp->name = (char*)xmlGetProp(parent, (xmlChar*)"name");
|
||||
if(tmp->name == NULL)
|
||||
WARN("Commodity from "COMMODITY_DATA" has invalid or noname");
|
||||
|
||||
do {
|
||||
if(xml_isNode(node, "description"))
|
||||
tmp->description = strdup(xml_get(node));
|
||||
else if(xml_isNode(node, "high"))
|
||||
tmp->high = xml_getInt(node);
|
||||
else if(xml_isNode(node, "medium"))
|
||||
tmp->medium = xml_getInt(node);
|
||||
else if(xml_isNode(node, "low"))
|
||||
tmp->low = xml_getInt(node);
|
||||
} while((node = node->next));
|
||||
node = parent->xmlChildrenNode;
|
||||
|
||||
do {
|
||||
if(xml_isNode(node, "description"))
|
||||
tmp->description = strdup(xml_get(node));
|
||||
else if(xml_isNode(node, "high"))
|
||||
tmp->high = xml_getInt(node);
|
||||
else if(xml_isNode(node, "medium"))
|
||||
tmp->medium = xml_getInt(node);
|
||||
else if(xml_isNode(node, "low"))
|
||||
tmp->low = xml_getInt(node);
|
||||
} while((node = node->next));
|
||||
|
||||
#define MELEMENT(o,s)if(o)WARN("Commodity '%s' missing '"s"' element",tmp->name)
|
||||
MELEMENT(tmp->high==0, "high");
|
||||
MELEMENT(tmp->description==NULL, "description");
|
||||
MELEMENT(tmp->medium==0, "medium");
|
||||
MELEMENT(tmp->low==0, "low");
|
||||
MELEMENT(tmp->high==0, "high");
|
||||
MELEMENT(tmp->description==NULL, "description");
|
||||
MELEMENT(tmp->medium==0, "medium");
|
||||
MELEMENT(tmp->low==0, "low");
|
||||
#undef MELEMENT
|
||||
|
||||
return tmp;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
int commodity_load(void) {
|
||||
uint32_t bufsize;
|
||||
char* buf = pack_readfile(DATA, COMMODITY_DATA, &bufsize);
|
||||
uint32_t bufsize;
|
||||
char* buf = pack_readfile(DATA, COMMODITY_DATA, &bufsize);
|
||||
|
||||
xmlNodePtr node;
|
||||
xmlDocPtr doc = xmlParseMemory(buf, bufsize);
|
||||
xmlNodePtr node;
|
||||
xmlDocPtr doc = xmlParseMemory(buf, bufsize);
|
||||
|
||||
Commodity* tmp = NULL;
|
||||
Commodity* tmp = NULL;
|
||||
|
||||
node = doc->xmlChildrenNode; // Commoditys node.
|
||||
if(strcmp((char*)node->name, XML_COMMODITY_ID)) {
|
||||
ERR("Malformed "COMMODITY_DATA
|
||||
" file: Missing root element '"XML_COMMODITY_ID"'");
|
||||
return -1;
|
||||
}
|
||||
|
||||
node = 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);
|
||||
}
|
||||
node = doc->xmlChildrenNode; // Commoditys node.
|
||||
if(strcmp((char*)node->name, XML_COMMODITY_ID)) {
|
||||
ERR("Malformed "COMMODITY_DATA
|
||||
" file: Missing root element '"XML_COMMODITY_ID"'");
|
||||
return -1;
|
||||
}
|
||||
} while((node = node->next));
|
||||
|
||||
xmlFreeDoc(doc);
|
||||
free(buf);
|
||||
xmlCleanupParser();
|
||||
node = node->xmlChildrenNode; // First faction node.
|
||||
if(node == NULL) {
|
||||
ERR("Malformed "COMMODITY_DATA" file: does not contain elements");
|
||||
return -1;
|
||||
}
|
||||
|
||||
DEBUG("Loaded %d commodit%s",
|
||||
commodity_nstack, (commodity_nstack==1) ? "y" : "ies");
|
||||
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));
|
||||
|
||||
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) {
|
||||
int i;
|
||||
for(i = 0; i < commodity_nstack; i++)
|
||||
commodity_freeOne(&commodity_stack[i]);
|
||||
free(commodity_stack);
|
||||
commodity_stack = NULL;
|
||||
commodity_nstack = 0;
|
||||
int i;
|
||||
for(i = 0; i < commodity_nstack; i++)
|
||||
commodity_freeOne(&commodity_stack[i]);
|
||||
free(commodity_stack);
|
||||
commodity_stack = NULL;
|
||||
commodity_nstack = 0;
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
typedef struct Commodity_ {
|
||||
char* name;
|
||||
char* description;
|
||||
int low, medium, high; // Prices.
|
||||
char* name;
|
||||
char* description;
|
||||
int low, medium, high; // Prices.
|
||||
} Commodity;
|
||||
|
||||
// Commidity stuff.
|
||||
|
@ -41,7 +41,7 @@ Faction* faction_get(const char* name) {
|
||||
for(i = 0; i < nfactions; i++)
|
||||
if(strcmp(faction_stack[i].name, name)==0)
|
||||
break;
|
||||
|
||||
|
||||
if(i != nfactions)
|
||||
return faction_stack+i;
|
||||
|
||||
@ -64,9 +64,9 @@ static Alliance* alliance_get(char* name) {
|
||||
// Return 1 if Faction a and b are enemies.
|
||||
int areEnemies(Faction* a, Faction* b) {
|
||||
int i = 0;
|
||||
|
||||
|
||||
if(a == b) return 0;
|
||||
else if((a == NULL) || (b == NULL)) return 0;
|
||||
else if((a == NULL) || (b == NULL)) return 0;
|
||||
|
||||
for(i = 0; i < a->nenemies; i++)
|
||||
if(a->enemies[i] == b)
|
||||
@ -83,7 +83,7 @@ int areAllies(Faction* a, Faction* b) {
|
||||
int i = 0;
|
||||
|
||||
if(a == b) return 0;
|
||||
else if((a == NULL) || (b == NULL)) return 0;
|
||||
else if((a == NULL) || (b == NULL)) return 0;
|
||||
|
||||
for(i = 0; i < a->nallies; i++)
|
||||
if(a->allies[i] == b)
|
||||
@ -115,13 +115,13 @@ static void alliance_parse(xmlNodePtr parent) {
|
||||
|
||||
do {
|
||||
if((node->type == XML_NODE_START) && (strcmp((char*)node->name,
|
||||
XML_ALLIANCE_TAG)==0)) {
|
||||
XML_ALLIANCE_TAG)==0)) {
|
||||
// Allocate a new alliance.
|
||||
alliances = realloc(alliances, sizeof(Alliance)*(++nalliances));
|
||||
alliances[nalliances-1].name = (char*)xmlGetProp(node,(xmlChar*)"name");
|
||||
alliances[nalliances-1].factions = NULL;
|
||||
alliances[nalliances-1].nfactions = 0;
|
||||
|
||||
|
||||
// Parse the current alliance's allies.
|
||||
cur = node->xmlChildrenNode;
|
||||
do {
|
||||
@ -137,24 +137,24 @@ static void alliance_parse(xmlNodePtr parent) {
|
||||
|
||||
if(a->factions[(*i)-1] == NULL)
|
||||
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));
|
||||
|
||||
// Set the crap needed by faction_stack.
|
||||
for(j = 0; j < (*i); j++) {
|
||||
a->factions[j]->nallies += (*i)-1;
|
||||
a->factions[j]->allies = realloc(a->factions[j]->allies,
|
||||
a->factions[j]->nallies*sizeof(Faction*));
|
||||
for(n = 0, m = 0; n < (*i); n++, m++) {
|
||||
// Add as ally for all factions exept self.
|
||||
if(n == j) m--;
|
||||
else if(n != j)
|
||||
a->factions[j]->allies[a->factions[j]->nallies-(*i)+1+m] =
|
||||
a->factions[n];
|
||||
}
|
||||
// Set the crap needed by faction_stack.
|
||||
for(j = 0; j < (*i); j++) {
|
||||
a->factions[j]->nallies += (*i)-1;
|
||||
a->factions[j]->allies = realloc(a->factions[j]->allies,
|
||||
a->factions[j]->nallies*sizeof(Faction*));
|
||||
for(n = 0, m = 0; n < (*i); n++, m++) {
|
||||
// Add as ally for all factions exept self.
|
||||
if(n == j) m--;
|
||||
else if(n != j)
|
||||
a->factions[j]->allies[a->factions[j]->nallies-(*i)+1+m] =
|
||||
a->factions[n];
|
||||
}
|
||||
}
|
||||
}
|
||||
} while((node = node->next));
|
||||
}
|
||||
|
||||
@ -164,12 +164,12 @@ static void enemies_parse(xmlNodePtr parent) {
|
||||
Alliance* a;
|
||||
int i, *j, n, m, x, y, z, e;
|
||||
char* type;
|
||||
|
||||
|
||||
node = parent->xmlChildrenNode;
|
||||
|
||||
do {
|
||||
if((node->type == XML_NODE_START)
|
||||
&& (strcmp((char*)node->name, XML_ENEMIES_TAG)==0)) {
|
||||
if((node->type == XML_NODE_START)
|
||||
&& (strcmp((char*)node->name, XML_ENEMIES_TAG)==0)) {
|
||||
i = 0;
|
||||
f = NULL;
|
||||
j = NULL;
|
||||
@ -188,7 +188,7 @@ static void enemies_parse(xmlNodePtr parent) {
|
||||
a = alliance_get((char*)cur->children->content);
|
||||
if(a == NULL)
|
||||
WARN("Alliance %s not found in stack",
|
||||
(char*)cur->children->content);
|
||||
(char*)cur->children->content);
|
||||
j[i-1] = a->nfactions;
|
||||
f[i-1] = a->factions;
|
||||
}
|
||||
@ -199,35 +199,35 @@ static void enemies_parse(xmlNodePtr parent) {
|
||||
f[i-1][0] = faction_get((char*)cur->children->content);
|
||||
if(f[i-1][0] == NULL)
|
||||
WARN("Faction %s not found in stack",
|
||||
(char*)cur->children->content);
|
||||
(char*)cur->children->content);
|
||||
}
|
||||
free(type);
|
||||
}
|
||||
} while((cur = cur->next));
|
||||
// Now actually parse and load up the enemies.
|
||||
for(n = 0; n < i; n++) {
|
||||
for(m = 0; m < j[n]; m++) {
|
||||
// Faction.
|
||||
// Add all the faction enemies to nenemies and alloc.
|
||||
for(e = 0, x = 0; x < i; x++)
|
||||
if(x != n) e += j[x]; // Store the total enemies.
|
||||
// Now allocate the memory.
|
||||
f[n][m]->nenemies += e;
|
||||
f[n][m]->enemies = realloc(f[n][m]->enemies,
|
||||
sizeof(Faction*)*f[n][m]->nenemies);
|
||||
|
||||
// Add the actualy enemies.
|
||||
for(x = 0, z = 0; x < i; x++)
|
||||
// Now actually parse and load up the enemies.
|
||||
for(n = 0; n < i; n++) {
|
||||
for(m = 0; m < j[n]; m++) {
|
||||
// Faction.
|
||||
// Add all the faction enemies to nenemies and alloc.
|
||||
for(e = 0, x = 0; x < i; x++)
|
||||
if(x != n) e += j[x]; // Store the total enemies.
|
||||
// Now allocate the memory.
|
||||
f[n][m]->nenemies += e;
|
||||
f[n][m]->enemies = realloc(f[n][m]->enemies,
|
||||
sizeof(Faction*)*f[n][m]->nenemies);
|
||||
|
||||
// Add the actualy enemies.
|
||||
for(x = 0, z = 0; x < i; x++)
|
||||
if(x != n)
|
||||
// Make sure it's not from the same group.
|
||||
if(x != n)
|
||||
// Make sure it's not from the same group.
|
||||
if(x != n)
|
||||
for(y = 0; y < j[x]; y++, z++)
|
||||
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++)
|
||||
if(j[x]==1) free(f[x]); // Free the single malloced factions.
|
||||
}
|
||||
// Free al the temp memory.
|
||||
for(x = 0; x < i; x++)
|
||||
if(j[x]==1) free(f[x]); // Free the single malloced factions.
|
||||
free(f); // Free the rest.
|
||||
free(j);
|
||||
}
|
||||
|
55
src/font.c
55
src/font.c
@ -11,7 +11,7 @@
|
||||
#define FONT_DEF "../dat/font.ttf"
|
||||
|
||||
// == 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
|
||||
// on whether you want to print it all, to a max width,
|
||||
// print centered or print a block of text.
|
||||
@ -27,7 +27,8 @@ glFont gl_defFont;
|
||||
glFont gl_smallFont;
|
||||
|
||||
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);
|
||||
|
||||
@ -42,7 +43,7 @@ static int pot(int n) {
|
||||
// Print text on screen! YES!!!! Just like printf! But different!
|
||||
// Defaults ft_font to gl_defFont if NULL.
|
||||
void gl_print(const glFont* ft_font, const double x, const double y,
|
||||
const glColour* c, const char* fmt, ...) {
|
||||
const glColour* c, const char* fmt, ...) {
|
||||
//float h = ft_font->h / .63; // Slightly increases font size.
|
||||
char txt[256];
|
||||
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.
|
||||
// Return the amount of characters we had to suppress.
|
||||
int gl_printMax(const glFont* ft_font, const int max,
|
||||
const double x, const double y, const glColour* c, const char* fmt, ...) {
|
||||
int gl_printMax(const glFont* ft_font, const int max,
|
||||
const double x, const double y, const glColour* c, const char* fmt, ...) {
|
||||
//float h = ft_font->h / .63; // Slightly increases font size.
|
||||
char txt[256];
|
||||
va_list ap;
|
||||
@ -91,7 +92,7 @@ int gl_printMax(const glFont* ft_font, const int max,
|
||||
vsprintf(txt, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
|
||||
// Limit the size.
|
||||
len = (int)strlen(txt);
|
||||
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.
|
||||
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.
|
||||
char txt[256];
|
||||
va_list ap;
|
||||
int i, n, len, ret;
|
||||
|
||||
|
||||
ret = 0; // Default return value.
|
||||
|
||||
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);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
|
||||
// Limit the size.
|
||||
len = (int)strlen(txt);
|
||||
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.
|
||||
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.
|
||||
char txt[1024];
|
||||
@ -185,7 +186,7 @@ int gl_printText(const glFont* ft_font, const int width, const int height,
|
||||
va_list ap;
|
||||
int p, i, j, n, len, ret, lastspace;
|
||||
double x, y;
|
||||
|
||||
|
||||
ret = 0; // Default return value.
|
||||
|
||||
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.
|
||||
glPushMatrix(); // Translation matrix.
|
||||
glTranslated(x, y, 0);
|
||||
|
||||
|
||||
// This is what we are displaying.
|
||||
glCallLists(lastspace-p-1, GL_UNSIGNED_BYTE, &buf);
|
||||
glPopMatrix(); // Translation matrix.
|
||||
@ -272,8 +273,8 @@ int gl_printWidth(const glFont* ft_font, const char* fmt, ...) {
|
||||
// ================
|
||||
// FONT!
|
||||
// ================
|
||||
static void glFontMakeDList(FT_Face face, char ch, GLuint list_base,
|
||||
GLuint* tex_base, int* width_base) {
|
||||
static void glFontMakeDList(FT_Face face, char ch, GLuint list_base,
|
||||
GLuint* tex_base, int* width_base) {
|
||||
FT_Glyph glyph;
|
||||
FT_Bitmap bitmap;
|
||||
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(i = 0; i < w; i++) {
|
||||
expanded_data[2*(i+j*w)] = expanded_data[2*(i+j*w)+1] =
|
||||
(i >= bitmap.width || j >= bitmap.rows) ?
|
||||
0 : bitmap.buffer[i + bitmap.width*j];
|
||||
(i >= bitmap.width || j >= bitmap.rows) ?
|
||||
0 : bitmap.buffer[i + bitmap.width*j];
|
||||
}
|
||||
}
|
||||
// Create the GL texture.
|
||||
glBindTexture(GL_TEXTURE_2D, tex_base[(int)ch]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_LUMINANCE_ALPHA,
|
||||
GL_UNSIGNED_BYTE, expanded_data);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_LUMINANCE_ALPHA,
|
||||
GL_UNSIGNED_BYTE, expanded_data);
|
||||
|
||||
free(expanded_data); // No need for this now.
|
||||
|
||||
@ -331,14 +332,14 @@ static void glFontMakeDList(FT_Face face, char ch, GLuint list_base,
|
||||
// Draw the texture mapped quad.
|
||||
glBindTexture(GL_TEXTURE_2D, tex_base[(int)ch]);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2d(0, 0);
|
||||
glVertex2d(0, bitmap.rows);
|
||||
glTexCoord2d(x, 0);
|
||||
glVertex2d(bitmap.width, bitmap.rows);
|
||||
glTexCoord2d(x, y);
|
||||
glVertex2d(bitmap.width, 0);
|
||||
glTexCoord2d(0, y);
|
||||
glVertex2d(0, 0);
|
||||
glTexCoord2d(0, 0);
|
||||
glVertex2d(0, bitmap.rows);
|
||||
glTexCoord2d(x, 0);
|
||||
glVertex2d(bitmap.width, bitmap.rows);
|
||||
glTexCoord2d(x, y);
|
||||
glVertex2d(bitmap.width, 0);
|
||||
glTexCoord2d(0, y);
|
||||
glVertex2d(0, 0);
|
||||
glEnd();
|
||||
|
||||
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) {
|
||||
if(font == NULL) font = &gl_defFont;
|
||||
|
||||
|
||||
uint32_t bufsize;
|
||||
FT_Byte* buf = pack_readfile(DATA, (fname) ? fname : FONT_DEF, &bufsize);
|
||||
|
||||
|
@ -19,19 +19,19 @@ void gl_freeFont(glFont* font);
|
||||
|
||||
// Print text.
|
||||
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.
|
||||
int gl_printMax(const glFont* ft_font, const int max,
|
||||
const double x, const double y, const glColour* c, const char* fmt, ...);
|
||||
const double x, const double y, const glColour* c, const char* fmt, ...);
|
||||
|
||||
// Print text centered in width at x.
|
||||
int gl_printMid(const glFont* ft_font, const int width,
|
||||
double x, const double y, const glColour* c, const char* fmt, ...);
|
||||
double x, const double y, const glColour* c, const char* fmt, ...);
|
||||
|
||||
// Respects \n -> bx, by is top left position.
|
||||
int gl_printText(const glFont* ft_font, const int width, const int height,
|
||||
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.
|
||||
int gl_printWidth(const glFont* ft_font, const char* fmt, ...);
|
||||
|
116
src/input.c
116
src/input.c
@ -24,12 +24,12 @@ static Keybind** input_keybinds; // Contains the players keybindings.
|
||||
|
||||
// Name of each keybinding.
|
||||
const char* keybindNames[] = {
|
||||
"accel", "left", "right", "reverse", // Movement.
|
||||
"primary", "target", "target_nearest", "face", "board", // Combat.
|
||||
"secondary", "secondary_next", // Secondary weapons.
|
||||
"target_planet", "land", "thyperspace","starmap", "jump", // Navigation.
|
||||
"mapzoomin", "mapzoomout", "screenshot", "pause", "menu", "info", // Misc.
|
||||
"end" }; // Must terminate at the end.
|
||||
"accel", "left", "right", "reverse", // Movement.
|
||||
"primary", "target", "target_nearest", "face", "board", // Combat.
|
||||
"secondary", "secondary_next", // Secondary weapons.
|
||||
"target_planet", "land", "thyperspace","starmap", "jump", // Navigation.
|
||||
"mapzoomin", "mapzoomout", "screenshot", "pause", "menu", "info", // Misc.
|
||||
"end" }; // Must terminate at the end.
|
||||
|
||||
// Accel hacks.
|
||||
static unsigned int input_accelLast = 0; // Used to see if double tap.
|
||||
@ -57,22 +57,22 @@ void input_setDefault(void) {
|
||||
input_setKeybind("face", KEYBIND_KEYBOARD, SDLK_f, 0);
|
||||
input_setKeybind("board", KEYBIND_KEYBOARD, SDLK_b, 0);
|
||||
// Secondary weapon.
|
||||
input_setKeybind("secondary", KEYBIND_KEYBOARD, SDLK_LSHIFT, 0);
|
||||
input_setKeybind("secondary", KEYBIND_KEYBOARD, SDLK_LSHIFT, 0);
|
||||
input_setKeybind("secondary_next", KEYBIND_KEYBOARD, SDLK_e, 0);
|
||||
// Space
|
||||
input_setKeybind("target_planet", KEYBIND_KEYBOARD, SDLK_p, 0);
|
||||
input_setKeybind("land", KEYBIND_KEYBOARD, SDLK_l, 0);
|
||||
input_setKeybind("thyperspace", KEYBIND_KEYBOARD, SDLK_h, 0);
|
||||
input_setKeybind("starmap", KEYBIND_KEYBOARD, SDLK_m, 0);
|
||||
input_setKeybind("starmap", KEYBIND_KEYBOARD, SDLK_m, 0);
|
||||
input_setKeybind("jump", KEYBIND_KEYBOARD, SDLK_j, 0);
|
||||
|
||||
// Misc.
|
||||
input_setKeybind("mapzoomin", KEYBIND_KEYBOARD, SDLK_0, 0);
|
||||
input_setKeybind("mapzoomout", KEYBIND_KEYBOARD, SDLK_9, 0);
|
||||
input_setKeybind("mapzoomout", KEYBIND_KEYBOARD, SDLK_9, 0);
|
||||
input_setKeybind("screenshot", KEYBIND_KEYBOARD, SDLK_F12, 0);
|
||||
input_setKeybind("pause", KEYBIND_KEYBOARD, SDLK_F1, 0);
|
||||
input_setKeybind("menu", KEYBIND_KEYBOARD, SDLK_ESCAPE, 0);
|
||||
input_setKeybind("info", KEYBIND_KEYBOARD, SDLK_i, 0);
|
||||
input_setKeybind("info", KEYBIND_KEYBOARD, SDLK_i, 0);
|
||||
}
|
||||
|
||||
// Initialization/exit functions (does not assign keys).
|
||||
@ -122,27 +122,27 @@ void input_setKeybind(char* keybind, KeybindType type, int key, int reverse) {
|
||||
#define INGAME() (!toolkit)
|
||||
// We won't be having any more funny stuff from VLack..
|
||||
#define NOHYP() \
|
||||
(!pilot_isFlag(player, PILOT_HYP_PREP) && \
|
||||
!pilot_isFlag(player, PILOT_HYP_BEGIN) && \
|
||||
!pilot_isFlag(player, PILOT_HYPERSPACE))
|
||||
(!pilot_isFlag(player, PILOT_HYP_PREP) && \
|
||||
!pilot_isFlag(player, PILOT_HYP_BEGIN) && \
|
||||
!pilot_isFlag(player, PILOT_HYPERSPACE))
|
||||
static void input_key(int keynum, double value, int abs) {
|
||||
unsigned int t;
|
||||
unsigned int t;
|
||||
|
||||
// Accelerating.
|
||||
if(KEY("accel")) {
|
||||
if(abs)player_acc = value;
|
||||
else player_acc += value;
|
||||
// Double tap accel = afterburn!
|
||||
t = SDL_GetTicks();
|
||||
if((value == KEY_PRESS) && (t-input_accelLast <= input_afterburnSensibility)) {
|
||||
player_afterburn();
|
||||
}
|
||||
else if((value == KEY_RELEASE) && player_isFlag(PLAYER_AFTERBURNER))
|
||||
player_afterburnOver();
|
||||
else
|
||||
player_acc = ABS(player_acc); // Make sure value is sane.
|
||||
// Double tap accel = afterburn!
|
||||
t = SDL_GetTicks();
|
||||
if((value == KEY_PRESS) && (t-input_accelLast <= input_afterburnSensibility)) {
|
||||
player_afterburn();
|
||||
}
|
||||
else if((value == KEY_RELEASE) && player_isFlag(PLAYER_AFTERBURNER))
|
||||
player_afterburnOver();
|
||||
else
|
||||
player_acc = ABS(player_acc); // Make sure value is sane.
|
||||
|
||||
if(value == KEY_PRESS) input_accelLast = t;
|
||||
if(value == KEY_PRESS) input_accelLast = t;
|
||||
}
|
||||
// Turning left.
|
||||
else if(KEY("left")) {
|
||||
@ -159,10 +159,10 @@ static void input_key(int keynum, double value, int abs) {
|
||||
// Set flags for facing correction.
|
||||
if(value == KEY_PRESS) { player_setFlag(PLAYER_TURN_RIGHT); }
|
||||
else if(value == KEY_RELEASE) { player_rmFlag(PLAYER_TURN_RIGHT); }
|
||||
|
||||
|
||||
if(abs) { player_turn = value; }
|
||||
else { player_turn += value; }
|
||||
|
||||
|
||||
if(player_turn < -1.) { player_turn = -1.; } // Make sure value is sane.
|
||||
}
|
||||
// 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_RIGHT)) { player_turn += 1; }
|
||||
}
|
||||
}
|
||||
}
|
||||
// Shoot primary weapon. BOOM BOOM.
|
||||
else if(KEY("primary")) {
|
||||
if(value == KEY_PRESS) { player_setFlag(PLAYER_PRIMARY); }
|
||||
@ -224,9 +224,9 @@ static void input_key(int keynum, double value, int abs) {
|
||||
else if(KEY("thyperspace") && INGAME() && NOHYP()) {
|
||||
if(value == KEY_PRESS) player_targetHyperspace();
|
||||
}
|
||||
else if(KEY("starmap") && NOHYP()) {
|
||||
if(value == KEY_PRESS) map_open();
|
||||
}
|
||||
else if(KEY("starmap") && NOHYP()) {
|
||||
if(value == KEY_PRESS) map_open();
|
||||
}
|
||||
else if(KEY("jump") && INGAME()) {
|
||||
if(value == KEY_PRESS) player_jump();
|
||||
}
|
||||
@ -254,10 +254,10 @@ static void input_key(int keynum, double value, int abs) {
|
||||
else if(KEY("menu")) {
|
||||
if(value == KEY_PRESS) menu_small();
|
||||
}
|
||||
// Show pilot information.
|
||||
else if(KEY("info") && NOHYP()) {
|
||||
if(value == KEY_PRESS) menu_info();
|
||||
}
|
||||
// Show pilot information.
|
||||
else if(KEY("info") && NOHYP()) {
|
||||
if(value == KEY_PRESS) menu_info();
|
||||
}
|
||||
}
|
||||
#undef KEY
|
||||
|
||||
@ -276,7 +276,7 @@ static void input_joyaxis(const unsigned int axis, const int value) {
|
||||
int i;
|
||||
for(i = 0; strcmp(keybindNames[i], "end"); i++)
|
||||
if(input_keybinds[i]->type == KEYBIND_JAXIS &&
|
||||
input_keybinds[i]->key == axis) {
|
||||
input_keybinds[i]->key == axis) {
|
||||
input_key(i, -(input_keybinds[i]->reverse) * (double)value / 32767., 1);
|
||||
return;
|
||||
}
|
||||
@ -287,7 +287,7 @@ static void input_joydown(const unsigned int button) {
|
||||
int i;
|
||||
for(i = 0; strcmp(keybindNames[i], "end");i++)
|
||||
if(input_keybinds[i]->type == KEYBIND_JBUTTON &&
|
||||
input_keybinds[i]->key == button) {
|
||||
input_keybinds[i]->key == button) {
|
||||
input_key(i, KEY_RELEASE, 0);
|
||||
return;
|
||||
}
|
||||
@ -298,7 +298,7 @@ static void input_joyup(const unsigned int button) {
|
||||
int i;
|
||||
for(i = 0; strcmp(keybindNames[i], "end"); i++)
|
||||
if(input_keybinds[i]->type == KEYBIND_JBUTTON &&
|
||||
input_keybinds[i]->key == button) {
|
||||
input_keybinds[i]->key == button) {
|
||||
input_key(i, KEY_RELEASE, 0);
|
||||
return;
|
||||
}
|
||||
@ -311,7 +311,7 @@ static void input_keydown(SDLKey key) {
|
||||
int i;
|
||||
for(i = 0; strcmp(keybindNames[i], "end"); i++)
|
||||
if(input_keybinds[i]->type == KEYBIND_KEYBOARD &&
|
||||
input_keybinds[i]->key == key) {
|
||||
input_keybinds[i]->key == key) {
|
||||
input_key(i, KEY_PRESS, 0);
|
||||
return;
|
||||
}
|
||||
@ -322,7 +322,7 @@ static void input_keyup(SDLKey key) {
|
||||
int i;
|
||||
for(i = 0; strcmp(keybindNames[i], "end"); i++)
|
||||
if(input_keybinds[i]->type == KEYBIND_KEYBOARD &&
|
||||
input_keybinds[i]->key == key) {
|
||||
input_keybinds[i]->key == key) {
|
||||
input_key(i, KEY_RELEASE, 0);
|
||||
return;
|
||||
}
|
||||
@ -332,27 +332,27 @@ static void input_keyup(SDLKey key) {
|
||||
|
||||
// Just seperates the event types.
|
||||
void input_handle(SDL_Event* event) {
|
||||
if(toolkit)
|
||||
// Toolkit is handled seperately.
|
||||
if(toolkit_input(event))
|
||||
return; // We don't process it if toolkit grabs it.
|
||||
if(toolkit)
|
||||
// Toolkit is handled seperately.
|
||||
if(toolkit_input(event))
|
||||
return; // We don't process it if toolkit grabs it.
|
||||
|
||||
switch(event->type) {
|
||||
case SDL_JOYAXISMOTION:
|
||||
input_joyaxis(event->jaxis.axis, event->jaxis.value);
|
||||
break;
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
input_joydown(event->jbutton.button);
|
||||
break;
|
||||
case SDL_JOYBUTTONUP:
|
||||
input_joyup(event->jbutton.button);
|
||||
break;
|
||||
case SDL_KEYDOWN:
|
||||
input_keydown(event->key.keysym.sym);
|
||||
break;
|
||||
case SDL_KEYUP:
|
||||
input_keyup(event->key.keysym.sym);
|
||||
break;
|
||||
case SDL_JOYAXISMOTION:
|
||||
input_joyaxis(event->jaxis.axis, event->jaxis.value);
|
||||
break;
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
input_joydown(event->jbutton.button);
|
||||
break;
|
||||
case SDL_JOYBUTTONUP:
|
||||
input_joyup(event->jbutton.button);
|
||||
break;
|
||||
case SDL_KEYDOWN:
|
||||
input_keydown(event->key.keysym.sym);
|
||||
break;
|
||||
case SDL_KEYUP:
|
||||
input_keyup(event->key.keysym.sym);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,10 +3,10 @@
|
||||
|
||||
// Input types.
|
||||
typedef enum {
|
||||
KEYBIND_NULL,
|
||||
KEYBIND_KEYBOARD,
|
||||
KEYBIND_JAXIS,
|
||||
KEYBIND_JBUTTON
|
||||
KEYBIND_NULL,
|
||||
KEYBIND_KEYBOARD,
|
||||
KEYBIND_JAXIS,
|
||||
KEYBIND_JBUTTON
|
||||
} KeybindType;
|
||||
|
||||
// Set input.
|
||||
|
@ -13,14 +13,14 @@ int joystick_get(char* namjoystick) {
|
||||
return i;
|
||||
|
||||
WARN("Joystick '%s' not found, using default joystick '%s'",
|
||||
namjoystick, SDL_JoystickName(0));
|
||||
namjoystick, SDL_JoystickName(0));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int joystick_use(int indjoystick) {
|
||||
if(indjoystick < 0 || indjoystick >= SDL_NumJoysticks()) {
|
||||
WARN("Joystick of index number %d does not exist. Switching to default (0)",
|
||||
indjoystick);
|
||||
indjoystick);
|
||||
indjoystick = 0;
|
||||
}
|
||||
if(joystick)
|
||||
@ -31,7 +31,7 @@ int joystick_use(int indjoystick) {
|
||||
joystick = SDL_JoystickOpen(indjoystick);
|
||||
if(joystick == NULL) {
|
||||
WARN("Error opening joystick %d [%s]",
|
||||
indjoystick, SDL_JoystickName(indjoystick));
|
||||
indjoystick, SDL_JoystickName(indjoystick));
|
||||
return -1;
|
||||
}
|
||||
DEBUG("\t\tWith %d axes, %d buttons, %d balls, and %d hats",
|
||||
|
658
src/land.c
658
src/land.c
@ -72,43 +72,43 @@ static void news_close(char* str);
|
||||
|
||||
// The local market.
|
||||
static void commodity_exchange(void) {
|
||||
int i;
|
||||
char** goods;
|
||||
int i;
|
||||
char** goods;
|
||||
secondary_wid = window_create("Commodity Exchange", -1, -1,
|
||||
COMMODITY_WIDTH, COMMODITY_HEIGHT);
|
||||
COMMODITY_WIDTH, COMMODITY_HEIGHT);
|
||||
|
||||
window_addButton(secondary_wid, -20, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnCommodityClose",
|
||||
"Close", commodity_exchange_close);
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnCommodityClose",
|
||||
"Close", commodity_exchange_close);
|
||||
|
||||
window_addButton(secondary_wid, -40-((BUTTON_WIDTH-20)/2), 20*2+BUTTON_HEIGHT,
|
||||
(BUTTON_WIDTH-20)/2, BUTTON_HEIGHT, "btnCommodityBuy",
|
||||
"Buy", commodity_buy);
|
||||
|
||||
window_addButton(secondary_wid, -20, 20*2+BUTTON_HEIGHT,
|
||||
(BUTTON_WIDTH-20)/2, BUTTON_HEIGHT, "btnCommoditySell",
|
||||
"Sell", commodity_sell);
|
||||
window_addButton(secondary_wid, -40-((BUTTON_WIDTH-20)/2), 20*2+BUTTON_HEIGHT,
|
||||
(BUTTON_WIDTH-20)/2, BUTTON_HEIGHT, "btnCommodityBuy",
|
||||
"Buy", commodity_buy);
|
||||
|
||||
window_addText(secondary_wid, -20, -40, BUTTON_WIDTH, 20, 0,
|
||||
"txtSInfo", &gl_smallFont, &cDConsole,
|
||||
"You have:\n"
|
||||
"Market price:\n");
|
||||
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/2, 20, 0,
|
||||
"txtDInfo", &gl_smallFont, &cBlack, NULL);
|
||||
window_addText(secondary_wid, -20, -40, BUTTON_WIDTH, 20, 0,
|
||||
"txtSInfo", &gl_smallFont, &cDConsole,
|
||||
"You have:\n"
|
||||
"Market price:\n");
|
||||
|
||||
window_addText(secondary_wid, -40, -80, BUTTON_WIDTH-20,
|
||||
BUTTON_WIDTH, 0, "txtDesc", &gl_smallFont, &cBlack, NULL);
|
||||
window_addText(secondary_wid, -20, -40, BUTTON_WIDTH/2, 20, 0,
|
||||
"txtDInfo", &gl_smallFont, &cBlack, 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);
|
||||
window_addText(secondary_wid, -40, -80, BUTTON_WIDTH-20,
|
||||
BUTTON_WIDTH, 0, "txtDesc", &gl_smallFont, &cBlack, NULL);
|
||||
|
||||
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) {
|
||||
@ -117,356 +117,356 @@ static void commodity_exchange_close(char* str) {
|
||||
}
|
||||
|
||||
static void commodity_update(char* str) {
|
||||
(void)str;
|
||||
char buf[128];
|
||||
char* comname;
|
||||
Commodity* com;
|
||||
(void)str;
|
||||
char buf[128];
|
||||
char* comname;
|
||||
Commodity* com;
|
||||
|
||||
comname = toolkit_getList(secondary_wid, "lstGoods");
|
||||
com = commodity_get(comname);
|
||||
comname = toolkit_getList(secondary_wid, "lstGoods");
|
||||
com = commodity_get(comname);
|
||||
|
||||
snprintf(buf, 128,
|
||||
"%d\n"
|
||||
"%d Screds/ton\n",
|
||||
player_cargoOwned(comname),
|
||||
com->medium);
|
||||
snprintf(buf, 128,
|
||||
"%d\n"
|
||||
"%d Screds/ton\n",
|
||||
player_cargoOwned(comname),
|
||||
com->medium);
|
||||
|
||||
window_modifyText(secondary_wid, "txtDInfo", buf);
|
||||
window_modifyText(secondary_wid, "txtDesc", com->description);
|
||||
window_modifyText(secondary_wid, "txtDInfo", buf);
|
||||
window_modifyText(secondary_wid, "txtDesc", com->description);
|
||||
}
|
||||
|
||||
static void commodity_buy(char* str) {
|
||||
(void)str;
|
||||
char* comname;
|
||||
Commodity* com;
|
||||
int q;
|
||||
(void)str;
|
||||
char* comname;
|
||||
Commodity* com;
|
||||
int q;
|
||||
|
||||
q = 10;
|
||||
q = 10;
|
||||
|
||||
comname = toolkit_getList(secondary_wid, "lstGoods");
|
||||
com = commodity_get(comname);
|
||||
comname = toolkit_getList(secondary_wid, "lstGoods");
|
||||
com = commodity_get(comname);
|
||||
|
||||
if(player_credits <= q * com->medium) {
|
||||
toolkit_alert("Not enough Scred!");
|
||||
return;
|
||||
}
|
||||
else if(player->cargo_free <= 0) {
|
||||
toolkit_alert("not enough free space!");
|
||||
return;
|
||||
}
|
||||
if(player_credits <= q * com->medium) {
|
||||
toolkit_alert("Not enough Scred!");
|
||||
return;
|
||||
}
|
||||
else if(player->cargo_free <= 0) {
|
||||
toolkit_alert("not enough free space!");
|
||||
return;
|
||||
}
|
||||
|
||||
q = pilot_addCargo(player, com, q);
|
||||
player_credits -= q * com->medium;
|
||||
commodity_update(NULL);
|
||||
q = pilot_addCargo(player, com, q);
|
||||
player_credits -= q * com->medium;
|
||||
commodity_update(NULL);
|
||||
}
|
||||
|
||||
static void commodity_sell(char* str) {
|
||||
(void)str;
|
||||
char* comname;
|
||||
Commodity* com;
|
||||
int q;
|
||||
(void)str;
|
||||
char* comname;
|
||||
Commodity* com;
|
||||
int q;
|
||||
|
||||
q = 10;
|
||||
comname = toolkit_getList(secondary_wid, "lstGoods");
|
||||
com = commodity_get(comname);
|
||||
q = 10;
|
||||
comname = toolkit_getList(secondary_wid, "lstGoods");
|
||||
com = commodity_get(comname);
|
||||
|
||||
q = pilot_rmCargo(player, com, q);
|
||||
player_credits += q * com->medium;
|
||||
commodity_update(NULL);
|
||||
q = pilot_rmCargo(player, com, q);
|
||||
player_credits += q * com->medium;
|
||||
commodity_update(NULL);
|
||||
}
|
||||
|
||||
static void outfits(void) {
|
||||
char** outfits;
|
||||
int noutfits;
|
||||
char buf[128];
|
||||
char** outfits;
|
||||
int noutfits;
|
||||
char buf[128];
|
||||
|
||||
snprintf(buf, 128, "%s - Outfits", planet->name);
|
||||
secondary_wid = window_create(buf, -1, -1,
|
||||
OUTFITS_WIDTH, OUTFITS_HEIGHT);
|
||||
|
||||
window_addButton(secondary_wid, -20, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnCloseOutfits",
|
||||
"Close", outfits_close);
|
||||
snprintf(buf, 128, "%s - Outfits", planet->name);
|
||||
secondary_wid = window_create(buf, -1, -1,
|
||||
OUTFITS_WIDTH, OUTFITS_HEIGHT);
|
||||
|
||||
window_addButton(secondary_wid, -40-BUTTON_WIDTH, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnBuyOutfits",
|
||||
"Buy", outfits_buy);
|
||||
window_addButton(secondary_wid, -20, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnCloseOutfits",
|
||||
"Close", outfits_close);
|
||||
|
||||
window_addButton(secondary_wid, -40-BUTTON_WIDTH, 40+BUTTON_HEIGHT,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnSellOutfit",
|
||||
"Sell", outfits_sell);
|
||||
window_addButton(secondary_wid, -40-BUTTON_WIDTH, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnBuyOutfits",
|
||||
"Buy", outfits_buy);
|
||||
|
||||
// Fancy 128x128 image.
|
||||
window_addRect(secondary_wid, -20, -50, 128, 128, "rctImage", &cBlack, 0);
|
||||
window_addImage(secondary_wid, -20-128, -50-128, "imgOutfit", NULL);
|
||||
window_addButton(secondary_wid, -40-BUTTON_WIDTH, 40+BUTTON_HEIGHT,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnSellOutfit",
|
||||
"Sell", outfits_sell);
|
||||
|
||||
window_addCust(secondary_wid, -40-BUTTON_WIDTH, 60+2*BUTTON_HEIGHT,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "cstMod", 0, outfits_renderMod, NULL);
|
||||
// Fancy 128x128 image.
|
||||
window_addRect(secondary_wid, -20, -50, 128, 128, "rctImage", &cBlack, 0);
|
||||
window_addImage(secondary_wid, -20-128, -50-128, "imgOutfit", NULL);
|
||||
|
||||
window_addText(secondary_wid, 40+200+20, -60,
|
||||
80, 96, 0, "txtSDesc", &gl_smallFont, &cDConsole,
|
||||
"Name:\n"
|
||||
"Type:\n"
|
||||
"Owned:\n"
|
||||
"\n"
|
||||
"Space taken:\n"
|
||||
"Free Space:\n"
|
||||
"\n"
|
||||
"Price:\n"
|
||||
"Money:\n");
|
||||
|
||||
window_addText(secondary_wid, 40+200+40+60, -60,
|
||||
250, 96, 0, "txtDDesc", &gl_smallFont, &cBlack, NULL);
|
||||
window_addCust(secondary_wid, -40-BUTTON_WIDTH, 60+2*BUTTON_HEIGHT,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "cstMod", 0, outfits_renderMod, 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);
|
||||
window_addText(secondary_wid, 40+200+20, -60,
|
||||
80, 96, 0, "txtSDesc", &gl_smallFont, &cDConsole,
|
||||
"Name:\n"
|
||||
"Type:\n"
|
||||
"Owned:\n"
|
||||
"\n"
|
||||
"Space taken:\n"
|
||||
"Free Space:\n"
|
||||
"\n"
|
||||
"Price:\n"
|
||||
"Money:\n");
|
||||
|
||||
// Write the outfits stuff.
|
||||
outfits_update(NULL);
|
||||
window_addText(secondary_wid, 40+200+40+60, -60,
|
||||
250, 96, 0, "txtDDesc", &gl_smallFont, &cBlack, NULL);
|
||||
|
||||
window_addText(secondary_wid, 20+200+40, -200,
|
||||
OUTFITS_WIDTH-300, 200, 0, "txtDescription",
|
||||
&gl_smallFont, NULL, NULL);
|
||||
|
||||
// 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) {
|
||||
if(strcmp(str, "btnCloseOutfits")==0)
|
||||
window_destroy(secondary_wid);
|
||||
if(strcmp(str, "btnCloseOutfits")==0)
|
||||
window_destroy(secondary_wid);
|
||||
}
|
||||
|
||||
static void outfits_update(char* str) {
|
||||
(void)str;
|
||||
char* outfitname;
|
||||
Outfit* outfit;
|
||||
char buf[80], buf2[16], buf3[16];
|
||||
(void)str;
|
||||
char* outfitname;
|
||||
Outfit* outfit;
|
||||
char buf[80], buf2[16], buf3[16];
|
||||
|
||||
outfitname = toolkit_getList(secondary_wid, "lstOutfits");
|
||||
outfit = outfit_get(outfitname);
|
||||
outfitname = toolkit_getList(secondary_wid, "lstOutfits");
|
||||
outfit = outfit_get(outfitname);
|
||||
|
||||
window_modifyImage(secondary_wid, "imgOutfit", outfit->gfx_store);
|
||||
window_modifyImage(secondary_wid, "imgOutfit", outfit->gfx_store);
|
||||
|
||||
window_modifyText(secondary_wid, "txtDescription", outfit->description);
|
||||
credits2str(buf2, outfit->price, 2);
|
||||
credits2str(buf3, player_credits, 2);
|
||||
snprintf(buf, 80,
|
||||
"%s\n"
|
||||
"%s\n"
|
||||
"%d\n"
|
||||
"\n"
|
||||
"%d\n"
|
||||
"%d\n"
|
||||
"\n"
|
||||
"%s SCred\n"
|
||||
"%s SCred\n",
|
||||
outfit->name,
|
||||
outfit_getType(outfit),
|
||||
player_outfitOwned(outfitname),
|
||||
outfit->mass,
|
||||
player_freeSpace(),
|
||||
buf2,
|
||||
buf3);
|
||||
window_modifyText(secondary_wid, "txtDescription", outfit->description);
|
||||
credits2str(buf2, outfit->price, 2);
|
||||
credits2str(buf3, player_credits, 2);
|
||||
snprintf(buf, 80,
|
||||
"%s\n"
|
||||
"%s\n"
|
||||
"%d\n"
|
||||
"\n"
|
||||
"%d\n"
|
||||
"%d\n"
|
||||
"\n"
|
||||
"%s SCred\n"
|
||||
"%s SCred\n",
|
||||
outfit->name,
|
||||
outfit_getType(outfit),
|
||||
player_outfitOwned(outfitname),
|
||||
outfit->mass,
|
||||
player_freeSpace(),
|
||||
buf2,
|
||||
buf3);
|
||||
|
||||
window_modifyText(secondary_wid, "txtDDesc", buf);
|
||||
window_modifyText(secondary_wid, "txtDDesc", buf);
|
||||
}
|
||||
|
||||
static void outfits_buy(char* str) {
|
||||
(void)str;
|
||||
char* outfitname;
|
||||
Outfit* outfit;
|
||||
int q;
|
||||
char buf[16];
|
||||
(void)str;
|
||||
char* outfitname;
|
||||
Outfit* outfit;
|
||||
int q;
|
||||
char buf[16];
|
||||
|
||||
outfitname = toolkit_getList(secondary_wid, "lstOutfits");
|
||||
outfit = outfit_get(outfitname);
|
||||
outfitname = toolkit_getList(secondary_wid, "lstOutfits");
|
||||
outfit = outfit_get(outfitname);
|
||||
|
||||
q = outfits_getMod();
|
||||
q = outfits_getMod();
|
||||
|
||||
// Can player actually fit the outfit?
|
||||
if((player_freeSpace() - outfit->mass) < 0) {
|
||||
toolkit_alert("No enough free space (you need %d more slots).",
|
||||
outfit->mass - player_freeSpace());
|
||||
return;
|
||||
}
|
||||
else if(player_outfitOwned(outfitname) >= outfit->max) {
|
||||
// Already has too many.
|
||||
toolkit_alert("You can only carry %d of this outfit.", outfit->max);
|
||||
return;
|
||||
}
|
||||
else if(outfit_isAfterburner(outfit) && (player->afterburner != NULL)) {
|
||||
toolkit_alert("You can only have one afterburner.");
|
||||
return;
|
||||
}
|
||||
// Not enough $$.
|
||||
else if(q*(int)outfit->price >= player_credits) {
|
||||
credits2str(buf, q*outfit->price - player_credits, 2);
|
||||
toolkit_alert("You need %s more SCred.", buf);
|
||||
return;
|
||||
}
|
||||
// Can player actually fit the outfit?
|
||||
if((player_freeSpace() - outfit->mass) < 0) {
|
||||
toolkit_alert("No enough free space (you need %d more slots).",
|
||||
outfit->mass - player_freeSpace());
|
||||
return;
|
||||
}
|
||||
else if(player_outfitOwned(outfitname) >= outfit->max) {
|
||||
// Already has too many.
|
||||
toolkit_alert("You can only carry %d of this outfit.", outfit->max);
|
||||
return;
|
||||
}
|
||||
else if(outfit_isAfterburner(outfit) && (player->afterburner != NULL)) {
|
||||
toolkit_alert("You can only have one afterburner.");
|
||||
return;
|
||||
}
|
||||
// Not enough $$.
|
||||
else if(q*(int)outfit->price >= player_credits) {
|
||||
credits2str(buf, q*outfit->price - player_credits, 2);
|
||||
toolkit_alert("You need %s more SCred.", buf);
|
||||
return;
|
||||
}
|
||||
|
||||
player_credits -= outfit->price * pilot_addOutfit(player, outfit,
|
||||
MIN(q, outfit->max));
|
||||
outfits_update(NULL);
|
||||
player_credits -= outfit->price * pilot_addOutfit(player, outfit,
|
||||
MIN(q, outfit->max));
|
||||
outfits_update(NULL);
|
||||
}
|
||||
|
||||
static void outfits_sell(char* str) {
|
||||
(void)str;
|
||||
char* outfitname;
|
||||
Outfit* outfit;
|
||||
int q;
|
||||
(void)str;
|
||||
char* outfitname;
|
||||
Outfit* outfit;
|
||||
int q;
|
||||
|
||||
outfitname = toolkit_getList(secondary_wid, "lstOutfits");
|
||||
outfit = outfit_get(outfitname);
|
||||
outfitname = toolkit_getList(secondary_wid, "lstOutfits");
|
||||
outfit = outfit_get(outfitname);
|
||||
|
||||
q = outfits_getMod();
|
||||
q = outfits_getMod();
|
||||
|
||||
if(player_outfitOwned(outfitname) <= 0) {
|
||||
// No outfits to sell.
|
||||
toolkit_alert("You can't sell something you don't have!");
|
||||
return;
|
||||
}
|
||||
if(player_outfitOwned(outfitname) <= 0) {
|
||||
// No outfits to sell.
|
||||
toolkit_alert("You can't sell something you don't have!");
|
||||
return;
|
||||
}
|
||||
|
||||
player_credits += outfit->price * pilot_rmOutfit(player, outfit, q);
|
||||
outfits_update(NULL);
|
||||
player_credits += outfit->price * pilot_rmOutfit(player, outfit, q);
|
||||
outfits_update(NULL);
|
||||
}
|
||||
|
||||
// Return the current modifier status.
|
||||
static int outfits_getMod(void) {
|
||||
SDLMod mods;
|
||||
int q;
|
||||
SDLMod mods;
|
||||
int q;
|
||||
|
||||
mods = SDL_GetModState();
|
||||
q = 1;
|
||||
if(mods & (KMOD_LCTRL | KMOD_RCTRL)) q *= 5;
|
||||
if(mods & (KMOD_LSHIFT | KMOD_RSHIFT)) q *= 10;
|
||||
mods = SDL_GetModState();
|
||||
q = 1;
|
||||
if(mods & (KMOD_LCTRL | KMOD_RCTRL)) q *= 5;
|
||||
if(mods & (KMOD_LSHIFT | KMOD_RSHIFT)) q *= 10;
|
||||
|
||||
return q;
|
||||
return q;
|
||||
}
|
||||
|
||||
static void outfits_renderMod(double bx, double by, double w, double h) {
|
||||
(void) h;
|
||||
int q;
|
||||
char buf[8];
|
||||
(void) h;
|
||||
int q;
|
||||
char buf[8];
|
||||
|
||||
q = outfits_getMod();
|
||||
if(q == 1) return;
|
||||
q = outfits_getMod();
|
||||
if(q == 1) return;
|
||||
|
||||
snprintf(buf, 8, "%dx", q);
|
||||
gl_printMid(&gl_smallFont, w,
|
||||
bx + (double)gl_screen.w/2.,
|
||||
by + (double)gl_screen.h/2.,
|
||||
&cBlack, buf);
|
||||
snprintf(buf, 8, "%dx", q);
|
||||
gl_printMid(&gl_smallFont, w,
|
||||
bx + (double)gl_screen.w/2.,
|
||||
by + (double)gl_screen.h/2.,
|
||||
&cBlack, buf);
|
||||
}
|
||||
|
||||
static void shipyard(void) {
|
||||
char** ships;
|
||||
int nships;
|
||||
char buf[128];
|
||||
char** ships;
|
||||
int nships;
|
||||
char buf[128];
|
||||
|
||||
snprintf(buf, 128, "%s - Shipyard", planet->name);
|
||||
secondary_wid = window_create(buf,
|
||||
-1, -1, SHIPYARD_WIDTH, SHIPYARD_HEIGHT);
|
||||
|
||||
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);
|
||||
snprintf(buf, 128, "%s - Shipyard", planet->name);
|
||||
secondary_wid = window_create(buf,
|
||||
-1, -1, SHIPYARD_WIDTH, SHIPYARD_HEIGHT);
|
||||
|
||||
window_addButton(secondary_wid, -40-BUTTON_WIDTH, 40+BUTTON_HEIGHT,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnInfoShip",
|
||||
"Info", shipyard_info);
|
||||
|
||||
window_addRect(secondary_wid, -40, -50,
|
||||
128, 96, "rctTarget", &cBlack, 0);
|
||||
|
||||
window_addImage(secondary_wid, -40-128, -50-96,
|
||||
"imgTarget", NULL);
|
||||
window_addButton(secondary_wid, -20, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnCloseShipyard",
|
||||
"Close", shipyard_close);
|
||||
|
||||
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_addButton(secondary_wid, -40-BUTTON_WIDTH, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnBuyShip",
|
||||
"Buy", shipyard_buy);
|
||||
|
||||
|
||||
window_addText(secondary_wid, 20+200+40, -160,
|
||||
SHIPYARD_WIDTH-300, 200, 0, "txtDescription",
|
||||
&gl_smallFont, NULL, NULL);
|
||||
window_addButton(secondary_wid, -40-BUTTON_WIDTH, 40+BUTTON_HEIGHT,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnInfoShip",
|
||||
"Info", shipyard_info);
|
||||
|
||||
// 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);
|
||||
window_addRect(secondary_wid, -40, -50,
|
||||
128, 96, "rctTarget", &cBlack, 0);
|
||||
|
||||
// Write the shipyard stuff.
|
||||
shipyard_update(NULL);
|
||||
window_addImage(secondary_wid, -40-128, -50-96,
|
||||
"imgTarget", NULL);
|
||||
|
||||
window_addText(secondary_wid, 40+200+40, -55,
|
||||
80, 96, 0, "txtSDesc", &gl_smallFont, &cDConsole,
|
||||
"Name:\n"
|
||||
"Class:\n"
|
||||
"Fabricator:\n"
|
||||
"\n"
|
||||
"Price:\n"
|
||||
"Money:\n");
|
||||
|
||||
window_addText(secondary_wid, 40+200+40+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) {
|
||||
if(strcmp(str, "btnCloseShipyard")==0)
|
||||
window_destroy(secondary_wid);
|
||||
if(strcmp(str, "btnCloseShipyard")==0)
|
||||
window_destroy(secondary_wid);
|
||||
}
|
||||
|
||||
static void shipyard_update(char* str) {
|
||||
(void)str;
|
||||
char* shipname;
|
||||
Ship* ship;
|
||||
char buf[80], buf2[16], buf3[16];
|
||||
(void)str;
|
||||
char* shipname;
|
||||
Ship* ship;
|
||||
char buf[80], buf2[16], buf3[16];
|
||||
|
||||
shipname = toolkit_getList(secondary_wid, "lstShipyard");
|
||||
ship = ship_get(shipname);
|
||||
shipname = toolkit_getList(secondary_wid, "lstShipyard");
|
||||
ship = ship_get(shipname);
|
||||
|
||||
window_modifyText(secondary_wid, "txtDescription", ship->description);
|
||||
window_modifyImage(secondary_wid, "imgTarget", ship->gfx_target);
|
||||
window_modifyText(secondary_wid, "txtDescription", ship->description);
|
||||
window_modifyImage(secondary_wid, "imgTarget", ship->gfx_target);
|
||||
|
||||
credits2str(buf2, ship->price, 2);
|
||||
credits2str(buf3, player_credits, 2);
|
||||
snprintf(buf, 80,
|
||||
"%s\n"
|
||||
"%s\n"
|
||||
"%s\n"
|
||||
"\n"
|
||||
"%s SCred\n"
|
||||
"%s SCred\n",
|
||||
ship->name,
|
||||
ship_class(ship),
|
||||
ship->fabricator,
|
||||
buf2,
|
||||
buf3);
|
||||
credits2str(buf2, ship->price, 2);
|
||||
credits2str(buf3, player_credits, 2);
|
||||
snprintf(buf, 80,
|
||||
"%s\n"
|
||||
"%s\n"
|
||||
"%s\n"
|
||||
"\n"
|
||||
"%s SCred\n"
|
||||
"%s SCred\n",
|
||||
ship->name,
|
||||
ship_class(ship),
|
||||
ship->fabricator,
|
||||
buf2,
|
||||
buf3);
|
||||
|
||||
window_modifyText(secondary_wid, "txtDDesc", buf);
|
||||
window_modifyText(secondary_wid, "txtDDesc", buf);
|
||||
|
||||
}
|
||||
|
||||
static void shipyard_info(char* str) {
|
||||
(void)str;
|
||||
char* shipname;
|
||||
(void)str;
|
||||
char* shipname;
|
||||
|
||||
shipname = toolkit_getList(secondary_wid, "lstShipyard");
|
||||
ship_view(shipname);
|
||||
shipname = toolkit_getList(secondary_wid, "lstShipyard");
|
||||
ship_view(shipname);
|
||||
}
|
||||
|
||||
static void shipyard_buy(char* str) {
|
||||
(void)str;
|
||||
char* shipname;
|
||||
Ship* ship;
|
||||
(void)str;
|
||||
char* shipname;
|
||||
Ship* ship;
|
||||
|
||||
shipname = toolkit_getList(secondary_wid, "lstShipyard");
|
||||
ship = ship_get(shipname);
|
||||
|
||||
player_newShip(ship);
|
||||
shipname = toolkit_getList(secondary_wid, "lstShipyard");
|
||||
ship = ship_get(shipname);
|
||||
|
||||
player_newShip(ship);
|
||||
}
|
||||
|
||||
// Spaceport bar.
|
||||
@ -474,16 +474,16 @@ static void spaceport_bar(void) {
|
||||
secondary_wid = window_create("SpacePort Bar", -1, -1, BAR_WIDTH, BAR_HEIGHT);
|
||||
|
||||
window_addText(secondary_wid, 20, -30,
|
||||
BAR_WIDTH-40, BAR_HEIGHT - 40 - BUTTON_HEIGHT, 0,
|
||||
"txtDescription", &gl_smallFont, &cBlack, planet->bar_description);
|
||||
BAR_WIDTH-40, BAR_HEIGHT - 40 - BUTTON_HEIGHT, 0,
|
||||
"txtDescription", &gl_smallFont, &cBlack, planet->bar_description);
|
||||
|
||||
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) {
|
||||
if(strcmp(str, "btnCloseBar")==0)
|
||||
@ -492,18 +492,18 @@ static void spaceport_bar_close(char* str) {
|
||||
|
||||
// Planet news reports.
|
||||
static void news(void) {
|
||||
unsigned int news_wid;
|
||||
news_wid = window_create("News Reports",
|
||||
-1, -1, NEWS_WIDTH, NEWS_HEIGHT);
|
||||
unsigned int news_wid;
|
||||
news_wid = window_create("News Reports",
|
||||
-1, -1, NEWS_WIDTH, NEWS_HEIGHT);
|
||||
|
||||
window_addText(news_wid, 20, 20 + BUTTON_HEIGHT + 20,
|
||||
NEWS_WIDTH-40, NEWS_HEIGHT - 20 - BUTTON_HEIGHT - 20 - 20 -20,
|
||||
0, "txtNews", &gl_smallFont, &cBlack,
|
||||
"News reporters report that they are on strike right now! D:");
|
||||
NEWS_WIDTH-40, NEWS_HEIGHT - 20 - BUTTON_HEIGHT - 20 - 20 -20,
|
||||
0, "txtNews", &gl_smallFont, &cBlack,
|
||||
"News reporters report that they are on strike right now! D:");
|
||||
|
||||
window_addButton(news_wid, -20, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnCloseNews", "Close", news_close);
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnCloseNews", "Close", news_close);
|
||||
}
|
||||
|
||||
static void news_close(char* str) {
|
||||
@ -515,9 +515,9 @@ static void news_close(char* str) {
|
||||
void land(Planet* p) {
|
||||
if(landed) return;
|
||||
|
||||
// Change music.
|
||||
music_load(MUSIC_LAND);
|
||||
music_play();
|
||||
// Change music.
|
||||
music_load(MUSIC_LAND);
|
||||
music_play();
|
||||
|
||||
planet = p;
|
||||
land_wid = window_create(p->name, -1, -1, LAND_WIDTH, LAND_HEIGHT);
|
||||
@ -525,34 +525,34 @@ void land(Planet* p) {
|
||||
// Pretty display.
|
||||
window_addImage(land_wid, 20, -40, "imgPlanet", p->gfx_exterior);
|
||||
window_addText(land_wid, 440, 80, LAND_WIDTH-460, 460, 0,
|
||||
"txtPlanetDesc", &gl_smallFont, &cBlack, p->description);
|
||||
"txtPlanetDesc", &gl_smallFont, &cBlack, p->description);
|
||||
// Buttons.
|
||||
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))
|
||||
window_addButton(land_wid, -20, 20 + BUTTON_HEIGHT + 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnCommodity",
|
||||
"Commodity Exchange", (void(*)(char*))commodity_exchange);
|
||||
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnCommodity",
|
||||
"Commodity Exchange", (void(*)(char*))commodity_exchange);
|
||||
|
||||
if(planet_hasService(planet, PLANET_SERVICE_SHIPYARD))
|
||||
window_addButton(land_wid, -20 - BUTTON_WIDTH - 20, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnShipyard",
|
||||
"Shipyard", (void(*)(char*))shipyard);
|
||||
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnShipyard",
|
||||
"Shipyard", (void(*)(char*))shipyard);
|
||||
|
||||
if(planet_hasService(planet, PLANET_SERVICE_OUTFITS))
|
||||
window_addButton(land_wid, -20 - BUTTON_WIDTH - 20, 20 + BUTTON_HEIGHT + 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnOutfits",
|
||||
"Outfits", (void(*)(char*))outfits);
|
||||
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnOutfits",
|
||||
"Outfits", (void(*)(char*))outfits);
|
||||
|
||||
if(planet_hasService(planet, PLANET_SERVICE_BASIC)) {
|
||||
window_addButton(land_wid, 20, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnNews",
|
||||
"Mission Terminal", NULL);
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnNews",
|
||||
"Mission Terminal", NULL);
|
||||
window_addButton(land_wid, 20, 20 + BUTTON_HEIGHT + 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnBar",
|
||||
"Spaceport Bar", (void(*)(char*))spaceport_bar);
|
||||
}
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnBar",
|
||||
"Spaceport Bar", (void(*)(char*))spaceport_bar);
|
||||
}
|
||||
|
||||
|
||||
landed = 1;
|
||||
@ -562,15 +562,15 @@ void land(Planet* p) {
|
||||
void takeoff(void) {
|
||||
if(!landed) return;
|
||||
|
||||
music_load(MUSIC_TAKEOFF);
|
||||
music_play();
|
||||
music_load(MUSIC_TAKEOFF);
|
||||
music_play();
|
||||
|
||||
int sw, sh;
|
||||
sw = planet->gfx_space->w;
|
||||
sh = planet->gfx_space->h;
|
||||
|
||||
// No longer authorized to land.
|
||||
player_rmFlag(PLAYER_LANDACK);
|
||||
// No longer authorized to land.
|
||||
player_rmFlag(PLAYER_LANDACK);
|
||||
|
||||
// Set player to another position with random facing direction and no velocity.
|
||||
player_warp(planet->pos.x + RNG(-sw/2, sw/2), planet->pos.y + RNG(-sh/2, sh/2));
|
||||
@ -580,7 +580,7 @@ void takeoff(void) {
|
||||
// Heal the player.
|
||||
player->armour = player->armour_max;
|
||||
player->shield = player->shield_max;
|
||||
player->energy = player->energy_max;
|
||||
player->energy = player->energy_max;
|
||||
|
||||
space_init(NULL);
|
||||
|
||||
|
@ -65,7 +65,7 @@ static void render_space(void);
|
||||
|
||||
#ifdef WIN32
|
||||
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine,
|
||||
int nCmdShow) {
|
||||
int nCmdShow) {
|
||||
int argc = 0;
|
||||
char *argv[] = { NULL };
|
||||
#else
|
||||
@ -78,7 +78,7 @@ int main(int argc, char** argv) {
|
||||
|
||||
// Initialize SDL for possible warnings.
|
||||
SDL_Init(0);
|
||||
|
||||
|
||||
// Input must be initialized for config to work.
|
||||
input_init();
|
||||
|
||||
@ -91,7 +91,7 @@ int main(int argc, char** argv) {
|
||||
data_name();
|
||||
LOG(" %s", dataname);
|
||||
DEBUG();
|
||||
|
||||
|
||||
// Random numbers.
|
||||
rng_init();
|
||||
|
||||
@ -113,14 +113,14 @@ int main(int argc, char** argv) {
|
||||
|
||||
window_caption();
|
||||
|
||||
// OpenAL sound.
|
||||
if(nosound)
|
||||
LOG("Sound is disabled!");
|
||||
else {
|
||||
if(sound_init()) WARN("Problem setting up sound!");
|
||||
music_load("Machina");
|
||||
music_play();
|
||||
}
|
||||
// OpenAL sound.
|
||||
if(nosound)
|
||||
LOG("Sound is disabled!");
|
||||
else {
|
||||
if(sound_init()) WARN("Problem setting up sound!");
|
||||
music_load("Machina");
|
||||
music_play();
|
||||
}
|
||||
|
||||
// Input.
|
||||
if((indjoystick >= 0) || (namjoystick != NULL)) {
|
||||
@ -153,15 +153,15 @@ int main(int argc, char** argv) {
|
||||
toolkit_init(); // Init the toolkit.
|
||||
|
||||
// Data loading.
|
||||
commodity_load();
|
||||
commodity_load();
|
||||
factions_load();
|
||||
spfx_load();
|
||||
spfx_load();
|
||||
outfit_load();
|
||||
ships_load();
|
||||
fleet_load();
|
||||
space_load();
|
||||
|
||||
menu_main();
|
||||
menu_main();
|
||||
|
||||
gtime = SDL_GetTicks(); // Init the time.
|
||||
|
||||
@ -187,17 +187,17 @@ int main(int argc, char** argv) {
|
||||
input_handle(&event); // handles all the events the player keybinds.
|
||||
}
|
||||
|
||||
sound_update(); // Do the sound stuff.
|
||||
sound_update(); // Do the sound stuff.
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
fps_control(); // Who doesn't love FPS control?
|
||||
toolkit_update(); // Simulate key repetition.
|
||||
|
||||
if(!menu_isOpen(MENU_MAIN)) {
|
||||
if(!paused && !toolkit) update_space(); // Update the game.
|
||||
render_space();
|
||||
}
|
||||
fps_control(); // Who doesn't love FPS control?
|
||||
toolkit_update(); // Simulate key repetition.
|
||||
|
||||
if(!menu_isOpen(MENU_MAIN)) {
|
||||
if(!paused && !toolkit) update_space(); // Update the game.
|
||||
render_space();
|
||||
}
|
||||
|
||||
if(toolkit) toolkit_render();
|
||||
|
||||
@ -212,11 +212,11 @@ int main(int argc, char** argv) {
|
||||
fleet_free();
|
||||
ships_free();
|
||||
outfit_free();
|
||||
spfx_free(); // Remove the special effects.
|
||||
spfx_free(); // Remove the special effects.
|
||||
factions_free();
|
||||
commodity_free();
|
||||
commodity_free();
|
||||
gl_freeFont(NULL);
|
||||
gl_freeFont(&gl_smallFont);
|
||||
gl_freeFont(&gl_smallFont);
|
||||
|
||||
// Exit subsystems.
|
||||
toolkit_exit(); // Kill the toolkit.
|
||||
@ -224,9 +224,9 @@ int main(int argc, char** argv) {
|
||||
joystick_exit(); // Release joystick.
|
||||
input_exit(); // Clean up keybindings.
|
||||
gl_exit(); // Kills video output.
|
||||
sound_exit(); // Kills the sound.
|
||||
SDL_Quit(); // Quits SDL.
|
||||
|
||||
sound_exit(); // Kills the sound.
|
||||
SDL_Quit(); // Quits SDL.
|
||||
|
||||
// All is good.
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
@ -240,7 +240,7 @@ static void fps_control(void) {
|
||||
gtime = SDL_GetTicks();
|
||||
|
||||
if(paused) SDL_Delay(10); // Drop paused FPS to be nice to the CPU.
|
||||
|
||||
|
||||
// If the fps is limited..
|
||||
if((max_fps != 0) && (dt < 1./max_fps)) {
|
||||
double delay = 1./max_fps - dt;
|
||||
@ -251,14 +251,14 @@ static void fps_control(void) {
|
||||
|
||||
// Update the game.
|
||||
static void update_space(void) {
|
||||
if(dt > 1./30.) {
|
||||
// Slow timers down and re-run calculations.
|
||||
pause_delay((unsigned int)dt*1000.);
|
||||
return;
|
||||
}
|
||||
space_update(dt);
|
||||
if(dt > 1./30.) {
|
||||
// Slow timers down and re-run calculations.
|
||||
pause_delay((unsigned int)dt*1000.);
|
||||
return;
|
||||
}
|
||||
space_update(dt);
|
||||
weapons_update(dt);
|
||||
spfx_update(dt);
|
||||
spfx_update(dt);
|
||||
pilots_update(dt);
|
||||
}
|
||||
|
||||
@ -287,10 +287,10 @@ static void render_space(void) {
|
||||
// N.
|
||||
pilots_render();
|
||||
weapons_render(WEAPON_LAYER_FG);
|
||||
spfx_render(SPFX_LAYER_BACK);
|
||||
// FG.
|
||||
spfx_render(SPFX_LAYER_BACK);
|
||||
// FG.
|
||||
player_render();
|
||||
spfx_render(SPFX_LAYER_FRONT);
|
||||
spfx_render(SPFX_LAYER_FRONT);
|
||||
display_fps(dt);
|
||||
}
|
||||
|
||||
@ -317,7 +317,7 @@ static void display_fps(const double dt) {
|
||||
static void data_name(void) {
|
||||
uint32_t bufsize;
|
||||
char* buf;
|
||||
|
||||
|
||||
// Check if data file is valid.
|
||||
if(pack_check(DATA)) {
|
||||
ERR("Data file '%s' not found", data);
|
||||
|
@ -4,7 +4,7 @@
|
||||
#define LOG(str, args...)(fprintf(stdout, str"\n", ## args))
|
||||
#define WARN(str, args...)(fprintf(stderr, "Warning: "str"\n", ## args))
|
||||
#define ERR(str, args...) (fprintf(stderr, "ERROR %s:%d: "str"\n", \
|
||||
__FILE__, __LINE__, ## args))
|
||||
__FILE__, __LINE__, ## args))
|
||||
|
||||
#ifdef DEBUG
|
||||
# undef DEBUG
|
||||
|
340
src/map.c
340
src/map.c
@ -38,231 +38,231 @@ static void map_buttonZoom(char* str);
|
||||
|
||||
// Open the map window.
|
||||
void map_open(void) {
|
||||
if(map_wid) {
|
||||
map_close(NULL);
|
||||
return;
|
||||
}
|
||||
if(map_wid) {
|
||||
map_close(NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the position to focus on current system.
|
||||
map_xpos = cur_system->pos.x;
|
||||
map_ypos = cur_system->pos.y;
|
||||
// Set the position to focus on current system.
|
||||
map_xpos = cur_system->pos.x;
|
||||
map_ypos = cur_system->pos.y;
|
||||
|
||||
map_wid = window_create("Star Map", -1, -1, WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||
|
||||
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:");
|
||||
map_wid = window_create("Star Map", -1, -1, WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||
|
||||
window_addText(map_wid, -20, -60-gl_smallFont.h-5, 80, 100, 0, "txtFaction",
|
||||
&gl_smallFont, &cBlack, NULL);
|
||||
window_addText(map_wid, -20, -20, 100, 20, 1, "txtSysname",
|
||||
&gl_defFont, &cDConsole, systems_stack[map_selected].name);
|
||||
|
||||
window_addText(map_wid, -20, -110, 90, 20, 0, "txtSPlanets",
|
||||
&gl_smallFont, &cDConsole, "Planets:");
|
||||
|
||||
window_addText(map_wid, -20, -110-gl_smallFont.h-5, 80, 100, 0, "txtPlanets",
|
||||
&gl_smallFont, &cBlack, NULL);
|
||||
window_addText(map_wid, -20, -60, 90, 20, 0, "txtSFaction",
|
||||
&gl_smallFont, &cDConsole, "Faction:");
|
||||
|
||||
window_addCust(map_wid, 20, -40, MAP_WIDTH, MAP_HEIGHT,
|
||||
"cstMap", 1, map_render, map_mouse);
|
||||
window_addText(map_wid, -20, -60-gl_smallFont.h-5, 80, 100, 0, "txtFaction",
|
||||
&gl_smallFont, &cBlack, NULL);
|
||||
|
||||
window_addButton(map_wid, -20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnClose", "Close", map_close);
|
||||
window_addText(map_wid, -20, -110, 90, 20, 0, "txtSPlanets",
|
||||
&gl_smallFont, &cDConsole, "Planets:");
|
||||
|
||||
window_addButton(map_wid, 40, 20, 30, 30, "btnZoomIn", "+", map_buttonZoom);
|
||||
window_addButton(map_wid, 80, 20, 30, 30, "btnZoomOut", "-", map_buttonZoom);
|
||||
window_addText(map_wid, -20, -110-gl_smallFont.h-5, 80, 100, 0, "txtPlanets",
|
||||
&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) {
|
||||
(void)str;
|
||||
if(map_wid) {
|
||||
window_destroy(map_wid);
|
||||
map_wid = 0;
|
||||
}
|
||||
(void)str;
|
||||
if(map_wid) {
|
||||
window_destroy(map_wid);
|
||||
map_wid = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void map_update(void) {
|
||||
int i;
|
||||
StarSystem* sys;
|
||||
Faction* f;
|
||||
char buf[100];
|
||||
int i;
|
||||
StarSystem* sys;
|
||||
Faction* f;
|
||||
char buf[100];
|
||||
|
||||
sys = &systems_stack[map_selected];
|
||||
sys = &systems_stack[map_selected];
|
||||
|
||||
window_modifyText(map_wid, "txtSysname", sys->name);
|
||||
window_modifyText(map_wid, "txtSysname", sys->name);
|
||||
|
||||
if(sys->nplanets == 0)
|
||||
// No planets -> no factions.
|
||||
snprintf(buf, 100, "NA");
|
||||
else {
|
||||
f = NULL;
|
||||
for(i = 0; i < sys->nplanets; i++) {
|
||||
if(f == NULL)
|
||||
f = sys->planets[i].faction;
|
||||
else if(f != sys->planets[i].faction) {
|
||||
// TODO: more verbosity.
|
||||
snprintf(buf, 100, "Multiple");
|
||||
break;
|
||||
}
|
||||
if(sys->nplanets == 0)
|
||||
// No planets -> no factions.
|
||||
snprintf(buf, 100, "NA");
|
||||
else {
|
||||
f = NULL;
|
||||
for(i = 0; i < sys->nplanets; i++) {
|
||||
if(f == NULL)
|
||||
f = sys->planets[i].faction;
|
||||
else if(f != sys->planets[i].faction) {
|
||||
// TODO: more verbosity.
|
||||
snprintf(buf, 100, "Multiple");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i == sys->nplanets)
|
||||
// Saw them all, and all the same.
|
||||
snprintf(buf, 100, "%s", f->name);
|
||||
}
|
||||
if(i == sys->nplanets)
|
||||
// Saw them all, and all the same.
|
||||
snprintf(buf, 100, "%s", f->name);
|
||||
}
|
||||
|
||||
window_modifyText(map_wid, "txtFaction", buf);
|
||||
window_modifyText(map_wid, "txtFaction", buf);
|
||||
|
||||
buf[0] = '\0';
|
||||
if(sys->nplanets == 0)
|
||||
snprintf(buf, 100, "None");
|
||||
else {
|
||||
for(i = 0; i < sys->nplanets; i++) {
|
||||
strcat(buf, sys->planets[i].name);
|
||||
strcat(buf, "\n");
|
||||
buf[0] = '\0';
|
||||
if(sys->nplanets == 0)
|
||||
snprintf(buf, 100, "None");
|
||||
else {
|
||||
for(i = 0; i < sys->nplanets; i++) {
|
||||
strcat(buf, sys->planets[i].name);
|
||||
strcat(buf, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
window_modifyText(map_wid, "txtPlanets", buf);
|
||||
window_modifyText(map_wid, "txtPlanets", buf);
|
||||
}
|
||||
|
||||
// Render the map as a custom widget.
|
||||
static void map_render(double bx, double by, double w, double h) {
|
||||
int i, j;
|
||||
double x, y, r, tx, ty;
|
||||
StarSystem* sys;
|
||||
glColour* col;
|
||||
int i, j;
|
||||
double x, y, r, tx, ty;
|
||||
StarSystem* sys;
|
||||
glColour* col;
|
||||
|
||||
r = 5.;
|
||||
x = (bx - map_xpos + w/2) * 1.; // Map zoom.
|
||||
y = (by - map_ypos + h/2) * 1.; // Map zoom.
|
||||
// Background
|
||||
COLOUR(cBlack);
|
||||
glBegin(GL_QUADS);
|
||||
r = 5.;
|
||||
x = (bx - map_xpos + w/2) * 1.; // Map zoom.
|
||||
y = (by - map_ypos + h/2) * 1.; // Map zoom.
|
||||
// Background
|
||||
COLOUR(cBlack);
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2d(bx, by);
|
||||
glVertex2d(bx, by+h);
|
||||
glVertex2d(bx+w, by+h);
|
||||
glVertex2d(bx+w, by);
|
||||
glEnd();
|
||||
glEnd();
|
||||
|
||||
// Render the star systems.
|
||||
for(i = 0; i < systems_nstack; i++) {
|
||||
sys = &systems_stack[i];
|
||||
// Render the star systems.
|
||||
for(i = 0; i < systems_nstack; i++) {
|
||||
sys = &systems_stack[i];
|
||||
|
||||
// Draw the system.
|
||||
if(sys == cur_system) COLOUR(cRadar_targ);
|
||||
else if(sys->nplanets==0) COLOUR(cInert); // TODO: dependant on planet type.
|
||||
else if(areEnemies(player->faction, sys->faction)) COLOUR(cRed);
|
||||
else COLOUR(cYellow);
|
||||
|
||||
gl_drawCircleInRect(x + sys->pos.x*map_zoom,
|
||||
y + sys->pos.y*map_zoom,
|
||||
r, bx, by, w, h);
|
||||
// Draw the system.
|
||||
if(sys == cur_system) COLOUR(cRadar_targ);
|
||||
else if(sys->nplanets==0) COLOUR(cInert); // TODO: dependant on planet type.
|
||||
else if(areEnemies(player->faction, sys->faction)) COLOUR(cRed);
|
||||
else COLOUR(cYellow);
|
||||
|
||||
// Draw the system name.
|
||||
tx = x + 7. + sys->pos.x * map_zoom;
|
||||
ty = y - 5. + sys->pos.y * map_zoom;
|
||||
if((map_zoom >= 1.) && // Can't be tiny.
|
||||
((tx > bx) && (ty > by) && (ty < by+h-6.))) // Width checking.
|
||||
gl_printMax(&gl_smallFont, (bx+w)-(tx),
|
||||
tx + gl_screen.w/2., ty + gl_screen.h/2.,
|
||||
&cWhite, sys->name);
|
||||
gl_drawCircleInRect(x + sys->pos.x*map_zoom,
|
||||
y + sys->pos.y*map_zoom,
|
||||
r, bx, by, w, h);
|
||||
|
||||
// Draw the hyperspace paths.
|
||||
glShadeModel(GL_SMOOTH);
|
||||
// Cheaply use transparency instead of actually
|
||||
// calculating from x to y the line must go. :)
|
||||
for(j = 0; j < sys->njumps; j++) {
|
||||
// Set the colours, is the route the current one?
|
||||
if(((cur_system == sys) && (j == hyperspace_target)) ||
|
||||
((cur_system == &systems_stack[sys->jumps[j]]) &&
|
||||
(sys = &systems_stack[cur_system->jumps[hyperspace_target]])))
|
||||
col = &cRed;
|
||||
else col = &cDarkBlue;
|
||||
glBegin(GL_LINE_STRIP);
|
||||
ACOLOUR(*col, 0.);
|
||||
tx = x + sys->pos.x * map_zoom;
|
||||
ty = y + sys->pos.y * map_zoom;
|
||||
if(!((tx < bx) || (tx > bx + w) || (ty < by) || (ty > by+h)))
|
||||
glVertex2d(tx, ty);
|
||||
COLOUR(*col);
|
||||
tx += (systems_stack[sys->jumps[j]].pos.x - sys->pos.x)/2. * map_zoom;
|
||||
ty += (systems_stack[sys->jumps[j]].pos.y - sys->pos.y)/2. * map_zoom;
|
||||
if(!((tx < bx) || (tx > bx+w) || (ty < by) || (ty > by+h)))
|
||||
glVertex2d(tx, ty);
|
||||
ACOLOUR(*col, 0.);
|
||||
tx = x + systems_stack[sys->jumps[j]].pos.x * map_zoom;
|
||||
ty = y + systems_stack[sys->jumps[j]].pos.y * map_zoom;
|
||||
if(!((tx < bx) || (tx > bx+w) || (ty < by) || (ty > by+h)))
|
||||
glVertex2d(tx, ty);
|
||||
glEnd();
|
||||
// Draw the system name.
|
||||
tx = x + 7. + sys->pos.x * map_zoom;
|
||||
ty = y - 5. + sys->pos.y * map_zoom;
|
||||
if((map_zoom >= 1.) && // Can't be tiny.
|
||||
((tx > bx) && (ty > by) && (ty < by+h-6.))) // Width checking.
|
||||
gl_printMax(&gl_smallFont, (bx+w)-(tx),
|
||||
tx + gl_screen.w/2., ty + gl_screen.h/2.,
|
||||
&cWhite, sys->name);
|
||||
|
||||
// Draw the hyperspace paths.
|
||||
glShadeModel(GL_SMOOTH);
|
||||
// Cheaply use transparency instead of actually
|
||||
// calculating from x to y the line must go. :)
|
||||
for(j = 0; j < sys->njumps; j++) {
|
||||
// Set the colours, is the route the current one?
|
||||
if(((cur_system == sys) && (j == hyperspace_target)) ||
|
||||
((cur_system == &systems_stack[sys->jumps[j]]) &&
|
||||
(sys = &systems_stack[cur_system->jumps[hyperspace_target]])))
|
||||
col = &cRed;
|
||||
else col = &cDarkBlue;
|
||||
glBegin(GL_LINE_STRIP);
|
||||
ACOLOUR(*col, 0.);
|
||||
tx = x + sys->pos.x * map_zoom;
|
||||
ty = y + sys->pos.y * map_zoom;
|
||||
if(!((tx < bx) || (tx > bx + w) || (ty < by) || (ty > by+h)))
|
||||
glVertex2d(tx, ty);
|
||||
COLOUR(*col);
|
||||
tx += (systems_stack[sys->jumps[j]].pos.x - sys->pos.x)/2. * map_zoom;
|
||||
ty += (systems_stack[sys->jumps[j]].pos.y - sys->pos.y)/2. * map_zoom;
|
||||
if(!((tx < bx) || (tx > bx+w) || (ty < by) || (ty > by+h)))
|
||||
glVertex2d(tx, ty);
|
||||
ACOLOUR(*col, 0.);
|
||||
tx = x + systems_stack[sys->jumps[j]].pos.x * map_zoom;
|
||||
ty = y + systems_stack[sys->jumps[j]].pos.y * map_zoom;
|
||||
if(!((tx < bx) || (tx > bx+w) || (ty < by) || (ty > by+h)))
|
||||
glVertex2d(tx, ty);
|
||||
glEnd();
|
||||
}
|
||||
glShadeModel(GL_FLAT);
|
||||
}
|
||||
glShadeModel(GL_FLAT);
|
||||
}
|
||||
// Selected planet.
|
||||
sys = &systems_stack[map_selected];
|
||||
COLOUR(cRed);
|
||||
gl_drawCircleInRect(x + sys->pos.x*map_zoom, y + sys->pos.y*map_zoom,
|
||||
r+3., bx, by, w, h);
|
||||
// Selected planet.
|
||||
sys = &systems_stack[map_selected];
|
||||
COLOUR(cRed);
|
||||
gl_drawCircleInRect(x + sys->pos.x*map_zoom, y + sys->pos.y*map_zoom,
|
||||
r+3., bx, by, w, h);
|
||||
}
|
||||
|
||||
// Map event handling.
|
||||
static void map_mouse(SDL_Event* event, double mx, double my) {
|
||||
int i, j;
|
||||
double x, y, t;
|
||||
int i, j;
|
||||
double x, y, t;
|
||||
|
||||
t = 13.*15.; // Threshold.
|
||||
t = 13.*15.; // Threshold.
|
||||
|
||||
mx -= MAP_WIDTH/2 - map_xpos;
|
||||
my -= MAP_HEIGHT/2 - map_ypos;
|
||||
mx -= MAP_WIDTH/2 - map_xpos;
|
||||
my -= MAP_HEIGHT/2 - map_ypos;
|
||||
|
||||
switch(event->type) {
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
// Selecting star system.
|
||||
for(i = 0; i < systems_nstack; i++) {
|
||||
x = systems_stack[i].pos.x * map_zoom;
|
||||
y = systems_stack[i].pos.y * map_zoom;
|
||||
switch(event->type) {
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
// Selecting star system.
|
||||
for(i = 0; i < systems_nstack; i++) {
|
||||
x = systems_stack[i].pos.x * map_zoom;
|
||||
y = systems_stack[i].pos.y * map_zoom;
|
||||
|
||||
if((pow2(mx-x)+pow2(my-y)) < t) {
|
||||
map_selected = i;
|
||||
for(j = 0; j < cur_system->njumps; j++) {
|
||||
if(i == cur_system->jumps[j]) {
|
||||
planet_target = -1; // Override planet_target.
|
||||
hyperspace_target = j;
|
||||
break;
|
||||
if((pow2(mx-x)+pow2(my-y)) < t) {
|
||||
map_selected = i;
|
||||
for(j = 0; j < cur_system->njumps; j++) {
|
||||
if(i == cur_system->jumps[j]) {
|
||||
planet_target = -1; // Override planet_target.
|
||||
hyperspace_target = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
map_update();
|
||||
break;
|
||||
}
|
||||
map_update();
|
||||
break;
|
||||
}
|
||||
}
|
||||
map_drag = 1;
|
||||
break;
|
||||
map_drag = 1;
|
||||
break;
|
||||
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
if(map_drag) map_drag = 0;
|
||||
break;
|
||||
|
||||
case SDL_MOUSEMOTION:
|
||||
if(map_drag) {
|
||||
// Axis is inverted.
|
||||
map_xpos -= event->motion.xrel;
|
||||
map_ypos += event->motion.yrel;
|
||||
case SDL_MOUSEMOTION:
|
||||
if(map_drag) {
|
||||
// Axis is inverted.
|
||||
map_xpos -= event->motion.xrel;
|
||||
map_ypos += event->motion.yrel;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void map_buttonZoom(char* str) {
|
||||
if(strcmp(str, "btnZoomIn")==0) {
|
||||
map_zoom += (map_zoom >= 1.) ? 0.5 : 0.25;
|
||||
map_zoom = MIN(2.5, map_zoom);
|
||||
}
|
||||
if(strcmp(str, "btnZoomIn")==0) {
|
||||
map_zoom += (map_zoom >= 1.) ? 0.5 : 0.25;
|
||||
map_zoom = MIN(2.5, map_zoom);
|
||||
}
|
||||
|
||||
else if(strcmp(str, "btnZoomOut")==0) {
|
||||
map_zoom -= (map_zoom > 1.) ? 0.5 : 0.25;
|
||||
map_zoom = MAX(0.5, map_zoom);
|
||||
}
|
||||
else if(strcmp(str, "btnZoomOut")==0) {
|
||||
map_zoom -= (map_zoom > 1.) ? 0.5 : 0.25;
|
||||
map_zoom = MAX(0.5, map_zoom);
|
||||
}
|
||||
}
|
||||
|
||||
|
242
src/menu.c
242
src/menu.c
@ -44,68 +44,68 @@ static void info_outfits_menu_close(char* str);
|
||||
static void menu_death_main(char* str);
|
||||
|
||||
void menu_main(void) {
|
||||
unsigned int bwid, wid;
|
||||
unsigned int bwid, wid;
|
||||
|
||||
// Create background image window.
|
||||
bwid = window_create("BG", -1, -1, gl_screen.w, gl_screen.h);
|
||||
window_addRect(bwid, 0, 0, gl_screen.w, gl_screen.h, "rctBG", &cBlack, 0);
|
||||
// Create background image window.
|
||||
bwid = window_create("BG", -1, -1, gl_screen.w, gl_screen.h);
|
||||
window_addRect(bwid, 0, 0, gl_screen.w, gl_screen.h, "rctBG", &cBlack, 0);
|
||||
|
||||
// Create menu window.
|
||||
wid = window_create("Main Menu", -1, -1, MAIN_WIDTH, MAIN_HEIGHT);
|
||||
window_addButton(wid, 20, 20 + (BUTTON_HEIGHT+20)*3,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnLoad", "Load Game", NULL);
|
||||
window_addButton(wid, 20, 20 + (BUTTON_HEIGHT+20)*2,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnNew", "New Game", menu_main_new);
|
||||
window_addButton(wid, 20, 20 + (BUTTON_HEIGHT+20),
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnOptions", "Options", (void(*)(char*)) edit_options);
|
||||
window_addButton(wid, 20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnExit", "Exit", (void(*)(char*)) exit_game);
|
||||
// Create menu window.
|
||||
wid = window_create("Main Menu", -1, -1, MAIN_WIDTH, MAIN_HEIGHT);
|
||||
window_addButton(wid, 20, 20 + (BUTTON_HEIGHT+20)*3,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnLoad", "Load Game", NULL);
|
||||
window_addButton(wid, 20, 20 + (BUTTON_HEIGHT+20)*2,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnNew", "New Game", menu_main_new);
|
||||
window_addButton(wid, 20, 20 + (BUTTON_HEIGHT+20),
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnOptions", "Options", (void(*)(char*)) edit_options);
|
||||
window_addButton(wid, 20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnExit", "Exit", (void(*)(char*)) exit_game);
|
||||
|
||||
menu_Open(MENU_MAIN);
|
||||
menu_Open(MENU_MAIN);
|
||||
}
|
||||
|
||||
static void menu_main_close(void) {
|
||||
window_destroy(window_get("Main Menu"));
|
||||
window_destroy(window_get("BG"));
|
||||
window_destroy(window_get("Main Menu"));
|
||||
window_destroy(window_get("BG"));
|
||||
|
||||
menu_Close(MENU_MAIN);
|
||||
menu_Close(MENU_MAIN);
|
||||
}
|
||||
|
||||
static void menu_main_new(char* str) {
|
||||
(void)str;
|
||||
(void)str;
|
||||
|
||||
menu_main_close();
|
||||
player_new();
|
||||
menu_main_close();
|
||||
player_new();
|
||||
}
|
||||
|
||||
// Ze ingame menu.
|
||||
// Small ingame menu.
|
||||
void menu_small(void) {
|
||||
if(menu_isOpen(MENU_MAIN) ||
|
||||
menu_isOpen(MENU_SMALL) ||
|
||||
menu_isOpen(MENU_DEATH))
|
||||
return; // It's already open..
|
||||
pause();
|
||||
menu_isOpen(MENU_SMALL) ||
|
||||
menu_isOpen(MENU_DEATH))
|
||||
return; // It's already open..
|
||||
pause();
|
||||
|
||||
unsigned int wid;
|
||||
|
||||
wid = window_create("Menu", -1, -1, MENU_WIDTH, MENU_HEIGHT);
|
||||
|
||||
window_addButton(wid, 20, 20 + BUTTON_HEIGHT*2 + 20*2,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnResume", "Resume", menu_small_close);
|
||||
|
||||
window_addButton(wid, 20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnExit", "Exit", (void(*)(char*))exit_game);
|
||||
|
||||
window_addButton(wid, 20, 20 + BUTTON_HEIGHT + 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnOptions", "Options", (void(*)(char*))edit_options);
|
||||
|
||||
menu_Open(MENU_SMALL);
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnResume", "Resume", menu_small_close);
|
||||
|
||||
window_addButton(wid, 20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnExit", "Exit", (void(*)(char*))exit_game);
|
||||
|
||||
window_addButton(wid, 20, 20 + BUTTON_HEIGHT + 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnOptions", "Options", (void(*)(char*))edit_options);
|
||||
|
||||
menu_Open(MENU_SMALL);
|
||||
}
|
||||
|
||||
static void menu_small_close(char* str) {
|
||||
@ -113,7 +113,7 @@ static void menu_small_close(char* str) {
|
||||
window_destroy(window_get("Menu"));
|
||||
|
||||
unpause();
|
||||
menu_Close(MENU_SMALL);
|
||||
menu_Close(MENU_SMALL);
|
||||
}
|
||||
|
||||
// Edit the options.
|
||||
@ -130,114 +130,114 @@ static void exit_game(void) {
|
||||
|
||||
// Info menu.
|
||||
void menu_info(void) {
|
||||
if(menu_isOpen(MENU_INFO)) return;
|
||||
pause();
|
||||
if(menu_isOpen(MENU_INFO)) return;
|
||||
pause();
|
||||
|
||||
char str[128];;
|
||||
unsigned int wid;
|
||||
wid = window_create("Info", -1, -1, INFO_WIDTH, INFO_HEIGHT);
|
||||
char str[128];;
|
||||
unsigned int wid;
|
||||
wid = window_create("Info", -1, -1, INFO_WIDTH, INFO_HEIGHT);
|
||||
|
||||
// Pilot generics.
|
||||
window_addText(wid, 20, 20, 120, INFO_HEIGHT-60,
|
||||
0, "txtDPilot", &gl_smallFont, &cDConsole,
|
||||
"Pilot:\n"
|
||||
"Combat Rating:\n");
|
||||
|
||||
snprintf(str, 128,
|
||||
"%s\n"
|
||||
"%s\n",
|
||||
player_name, player_rating());
|
||||
// Pilot generics.
|
||||
window_addText(wid, 20, 20, 120, INFO_HEIGHT-60,
|
||||
0, "txtDPilot", &gl_smallFont, &cDConsole,
|
||||
"Pilot:\n"
|
||||
"Combat Rating:\n");
|
||||
|
||||
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);
|
||||
|
||||
snprintf(str, 128,
|
||||
"%s\n"
|
||||
"%s\n",
|
||||
player_name, player_rating());
|
||||
|
||||
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) {
|
||||
if(strcmp(str, "btnClose")==0)
|
||||
window_destroy(window_get("Info"));
|
||||
|
||||
menu_Close(MENU_INFO);
|
||||
unpause();
|
||||
if(strcmp(str, "btnClose")==0)
|
||||
window_destroy(window_get("Info"));
|
||||
|
||||
menu_Close(MENU_INFO);
|
||||
unpause();
|
||||
}
|
||||
|
||||
static void info_outfits_menu(char* str) {
|
||||
(void) str;
|
||||
int i;
|
||||
char buf[1024], buf2[64];
|
||||
unsigned int wid;
|
||||
wid = window_create("Outfits", -1, -1, OUTFITS_WIDTH, OUTFITS_HEIGHT);
|
||||
(void) str;
|
||||
int i;
|
||||
char buf[1024], buf2[64];
|
||||
unsigned int wid;
|
||||
wid = window_create("Outfits", -1, -1, OUTFITS_WIDTH, OUTFITS_HEIGHT);
|
||||
|
||||
window_addText(wid, 20, -40, 100, OUTFITS_HEIGHT-40,
|
||||
0, "txtLabel", &gl_smallFont, &cDConsole,
|
||||
"Ship Outfits:");
|
||||
window_addText(wid, 20, -40, 100, OUTFITS_HEIGHT-40,
|
||||
0, "txtLabel", &gl_smallFont, &cDConsole,
|
||||
"Ship Outfits:");
|
||||
|
||||
buf[0] = '\0';
|
||||
if(player->noutfits > 0)
|
||||
snprintf(buf, 1024, "%dx %s",
|
||||
player->outfits[0].quantity, player->outfits[0].outfit->name);
|
||||
|
||||
for(i = 1; i < player->noutfits; i++) {
|
||||
snprintf(buf2, 64, ", %dx %s",
|
||||
player->outfits[i].quantity, player->outfits[i].outfit->name);
|
||||
strcat(buf, buf2);
|
||||
}
|
||||
buf[0] = '\0';
|
||||
if(player->noutfits > 0)
|
||||
snprintf(buf, 1024, "%dx %s",
|
||||
player->outfits[0].quantity, player->outfits[0].outfit->name);
|
||||
|
||||
window_addText(wid, 20, -45-gl_smallFont.h,
|
||||
OUTFITS_WIDTH-40, OUTFITS_HEIGHT-60,
|
||||
0, "txtOutfits", &gl_smallFont, &cBlack, buf);
|
||||
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_addButton(wid, -20, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"closeOutfits", "Close", info_outfits_menu_close);
|
||||
window_addText(wid, 20, -45-gl_smallFont.h,
|
||||
OUTFITS_WIDTH-40, OUTFITS_HEIGHT-60,
|
||||
0, "txtOutfits", &gl_smallFont, &cBlack, buf);
|
||||
|
||||
window_addButton(wid, -20, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"closeOutfits", "Close", info_outfits_menu_close);
|
||||
}
|
||||
|
||||
static void info_outfits_menu_close(char* str) {
|
||||
window_destroy(window_get(str+5)); // closeFoo -> Foo.
|
||||
window_destroy(window_get(str+5)); // closeFoo -> Foo.
|
||||
}
|
||||
|
||||
// Pilot dead.
|
||||
void menu_death(void) {
|
||||
unsigned int wid;
|
||||
wid = window_create("Death", -1, -1, DEATH_WIDTH, DEATH_HEIGHT);
|
||||
unsigned int wid;
|
||||
wid = window_create("Death", -1, -1, DEATH_WIDTH, DEATH_HEIGHT);
|
||||
|
||||
window_addButton(wid, 20, 20 + (BUTTON_HEIGHT + 20),
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnMain", "MainMenu", menu_death_main);
|
||||
window_addButton(wid, 20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnExit", "Exit", (void(*)(char*)) exit_game);
|
||||
window_addButton(wid, 20, 20 + (BUTTON_HEIGHT + 20),
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnMain", "MainMenu", menu_death_main);
|
||||
window_addButton(wid, 20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnExit", "Exit", (void(*)(char*)) exit_game);
|
||||
|
||||
menu_Open(MENU_DEATH);
|
||||
menu_Open(MENU_DEATH);
|
||||
}
|
||||
|
||||
static void menu_death_main(char* str) {
|
||||
(void)str;
|
||||
unsigned int wid;
|
||||
(void)str;
|
||||
unsigned int wid;
|
||||
|
||||
wid = window_get("Death");
|
||||
window_destroy(wid);
|
||||
menu_Close(MENU_DEATH);
|
||||
wid = window_get("Death");
|
||||
window_destroy(wid);
|
||||
menu_Close(MENU_DEATH);
|
||||
|
||||
menu_main();
|
||||
menu_main();
|
||||
}
|
||||
|
||||
|
360
src/music.c
360
src/music.c
@ -25,11 +25,11 @@ extern SDL_mutex* sound_lock;
|
||||
|
||||
// Saves the music to ram in this structure.
|
||||
typedef struct alMusic_ {
|
||||
char name[32]; // Name.
|
||||
Packfile file;
|
||||
OggVorbis_File stream;
|
||||
vorbis_info* info;
|
||||
ALenum format;
|
||||
char name[32]; // Name.
|
||||
Packfile file;
|
||||
OggVorbis_File stream;
|
||||
vorbis_info* info;
|
||||
ALenum format;
|
||||
} alMusic;
|
||||
|
||||
// Song currently playing.
|
||||
@ -47,17 +47,17 @@ static ALfloat mvolume = 1.;
|
||||
|
||||
// Vorbis suff.
|
||||
static size_t ovpack_read(void* ptr, size_t size,
|
||||
size_t nmemb, void* datasource) {
|
||||
return (ssize_t) pack_read(datasource, ptr, size*nmemb);
|
||||
size_t nmemb, void* datasource) {
|
||||
return (ssize_t) pack_read(datasource, ptr, size*nmemb);
|
||||
}
|
||||
|
||||
static int ovpack_retneg(void) { return -1; } // Must return -1.
|
||||
static int ovpack_retzero(void) { return 0; } // Must return 0.
|
||||
ov_callbacks ovcall = {
|
||||
.read_func = ovpack_read,
|
||||
.seek_func = (int(*)(void*, ogg_int64_t, int)) ovpack_retneg,
|
||||
.close_func = (int(*)(void*))ovpack_retzero,
|
||||
.tell_func = (long(*)(void*))ovpack_retneg
|
||||
.read_func = ovpack_read,
|
||||
.seek_func = (int(*)(void*, ogg_int64_t, int)) ovpack_retneg,
|
||||
.close_func = (int(*)(void*))ovpack_retzero,
|
||||
.tell_func = (long(*)(void*))ovpack_retneg
|
||||
};
|
||||
|
||||
static int stream_loadBuffer(ALuint buffer);
|
||||
@ -68,250 +68,250 @@ static void music_free(void);
|
||||
// The thread.
|
||||
static unsigned int music_state = 0;
|
||||
int music_thread(void* unused) {
|
||||
(void)unused;
|
||||
(void)unused;
|
||||
|
||||
int active; // Active buffer.
|
||||
ALint stat;
|
||||
int active; // Active buffer.
|
||||
ALint stat;
|
||||
|
||||
// Main loop.
|
||||
while(!music_is(MUSIC_KILL)) {
|
||||
if(music_is(MUSIC_PLAYING)) {
|
||||
if(music_vorbis.file.end == 0)
|
||||
music_rm(MUSIC_PLAYING);
|
||||
else {
|
||||
music_rm(MUSIC_STOPPED);
|
||||
// Main loop.
|
||||
while(!music_is(MUSIC_KILL)) {
|
||||
if(music_is(MUSIC_PLAYING)) {
|
||||
if(music_vorbis.file.end == 0)
|
||||
music_rm(MUSIC_PLAYING);
|
||||
else {
|
||||
music_rm(MUSIC_STOPPED);
|
||||
|
||||
SDL_mutexP(music_vorbis_lock); // Lock the mutex.
|
||||
SDL_mutexP(sound_lock);
|
||||
SDL_mutexP(music_vorbis_lock); // Lock the mutex.
|
||||
SDL_mutexP(sound_lock);
|
||||
|
||||
// Start playing current song.
|
||||
active = 0; // Load first buffer.
|
||||
if(stream_loadBuffer(music_buffer[active])) music_rm(MUSIC_PLAYING);
|
||||
alSourceQueueBuffers(music_source, 1, &music_buffer[active]);
|
||||
// Start playing current song.
|
||||
active = 0; // Load first buffer.
|
||||
if(stream_loadBuffer(music_buffer[active])) music_rm(MUSIC_PLAYING);
|
||||
alSourceQueueBuffers(music_source, 1, &music_buffer[active]);
|
||||
|
||||
// Start playing with buffer laoaded.
|
||||
alSourcePlay(music_source);
|
||||
// Start playing with buffer laoaded.
|
||||
alSourcePlay(music_source);
|
||||
|
||||
active = 1; // Load the second buffer.
|
||||
if(stream_loadBuffer(music_buffer[active])) music_rm(MUSIC_PLAYING);
|
||||
alSourceQueueBuffers(music_source, 1, &music_buffer[active]);
|
||||
active = 1; // Load the second buffer.
|
||||
if(stream_loadBuffer(music_buffer[active])) music_rm(MUSIC_PLAYING);
|
||||
alSourceQueueBuffers(music_source, 1, &music_buffer[active]);
|
||||
|
||||
SDL_mutexV(sound_lock);
|
||||
SDL_mutexV(sound_lock);
|
||||
|
||||
active = 0;
|
||||
}
|
||||
while(music_is(MUSIC_PLAYING)) {
|
||||
SDL_mutexP(sound_lock);
|
||||
active = 0;
|
||||
}
|
||||
while(music_is(MUSIC_PLAYING)) {
|
||||
SDL_mutexP(sound_lock);
|
||||
|
||||
alGetSourcei(music_source, AL_BUFFERS_PROCESSED, &stat);
|
||||
if(stat > 0) {
|
||||
// Refill active buffer.
|
||||
alSourceUnqueueBuffers(music_source, 1, &music_buffer[active]);
|
||||
if(stream_loadBuffer(music_buffer[active])) music_rm(MUSIC_PLAYING);
|
||||
alSourceQueueBuffers(music_source, 1, &music_buffer[active]);
|
||||
alGetSourcei(music_source, AL_BUFFERS_PROCESSED, &stat);
|
||||
if(stat > 0) {
|
||||
// Refill active buffer.
|
||||
alSourceUnqueueBuffers(music_source, 1, &music_buffer[active]);
|
||||
if(stream_loadBuffer(music_buffer[active])) music_rm(MUSIC_PLAYING);
|
||||
alSourceQueueBuffers(music_source, 1, &music_buffer[active]);
|
||||
|
||||
active = 1 - active;
|
||||
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);
|
||||
|
||||
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);
|
||||
SDL_Delay(0); // We must not kill resources.
|
||||
}
|
||||
music_set(MUSIC_STOPPED);
|
||||
SDL_Delay(0); // We must not kill resources.
|
||||
}
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stream_loadBuffer(ALuint buffer) {
|
||||
int size, section, result;
|
||||
char data[BUFFER_SIZE]; // Buffer to hold the data.
|
||||
int size, section, result;
|
||||
char data[BUFFER_SIZE]; // Buffer to hold the data.
|
||||
|
||||
size = 0;
|
||||
while(size < BUFFER_SIZE) {
|
||||
// Fill up the entire data buffer.
|
||||
result = ov_read(
|
||||
&music_vorbis.stream, // Stream.
|
||||
data + size, // Data.
|
||||
BUFFER_SIZE - size, // Amount to read.
|
||||
0, // Big endian?.
|
||||
2, // 16 bit.
|
||||
1, // Signed.
|
||||
§ion); // Current bitstream.
|
||||
|
||||
if(result == 0) return 1;
|
||||
else if(result == OV_HOLE) {
|
||||
WARN("OGG: Vorbis hole detected in music!");
|
||||
return 0;
|
||||
}
|
||||
else if(result == OV_EBADLINK) {
|
||||
WARN("OGG: Invalid stream section or corrupt link in music!");
|
||||
return -1;
|
||||
size = 0;
|
||||
while(size < BUFFER_SIZE) {
|
||||
// Fill up the entire data buffer.
|
||||
result = ov_read(
|
||||
&music_vorbis.stream, // Stream.
|
||||
data + size, // Data.
|
||||
BUFFER_SIZE - size, // Amount to read.
|
||||
0, // Big endian?.
|
||||
2, // 16 bit.
|
||||
1, // Signed.
|
||||
§ion); // Current bitstream.
|
||||
|
||||
if(result == 0) return 1;
|
||||
else if(result == OV_HOLE) {
|
||||
WARN("OGG: Vorbis hole detected in music!");
|
||||
return 0;
|
||||
}
|
||||
else if(result == OV_EBADLINK) {
|
||||
WARN("OGG: Invalid stream section or corrupt link in music!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
size += result;
|
||||
if(size == BUFFER_SIZE) break; // Buffer is full.
|
||||
}
|
||||
// Load the buffer.
|
||||
alBufferData(buffer, music_vorbis.format, data, BUFFER_SIZE,
|
||||
music_vorbis.info->rate);
|
||||
|
||||
size += result;
|
||||
if(size == BUFFER_SIZE) break; // Buffer is full.
|
||||
}
|
||||
// Load the buffer.
|
||||
alBufferData(buffer, music_vorbis.format, data, BUFFER_SIZE,
|
||||
music_vorbis.info->rate);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Init/Exit.
|
||||
int music_init(void) {
|
||||
music_vorbis_lock = SDL_CreateMutex();
|
||||
music_find();
|
||||
music_vorbis.file.end = 0; // Indication that it's not loaded..
|
||||
music_vorbis_lock = SDL_CreateMutex();
|
||||
music_find();
|
||||
music_vorbis.file.end = 0; // Indication that it's not loaded..
|
||||
|
||||
SDL_mutexP(sound_lock);
|
||||
SDL_mutexP(sound_lock);
|
||||
|
||||
alGenBuffers(2, music_buffer);
|
||||
alGenSources(1, &music_source);
|
||||
alSourcef(music_source, AL_GAIN, mvolume);
|
||||
alSourcef(music_source, AL_ROLLOFF_FACTOR, 0.);
|
||||
alSourcei(music_source, AL_SOURCE_RELATIVE, AL_TRUE);
|
||||
alGenBuffers(2, music_buffer);
|
||||
alGenSources(1, &music_source);
|
||||
alSourcef(music_source, AL_GAIN, mvolume);
|
||||
alSourcef(music_source, AL_ROLLOFF_FACTOR, 0.);
|
||||
alSourcei(music_source, AL_SOURCE_RELATIVE, AL_TRUE);
|
||||
|
||||
SDL_mutexV(sound_lock);
|
||||
SDL_mutexV(sound_lock);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void music_exit(void) {
|
||||
int i;
|
||||
int i;
|
||||
|
||||
// Free the music.
|
||||
alDeleteBuffers(2, music_buffer);
|
||||
alDeleteSources(1, &music_source);
|
||||
music_free();
|
||||
// Free the music.
|
||||
alDeleteBuffers(2, music_buffer);
|
||||
alDeleteSources(1, &music_source);
|
||||
music_free();
|
||||
|
||||
// Free selection
|
||||
for(i = 0; i < nmusic_selection; i++)
|
||||
free(music_selection[i]);
|
||||
free(music_selection);
|
||||
// Free selection
|
||||
for(i = 0; i < nmusic_selection; i++)
|
||||
free(music_selection[i]);
|
||||
free(music_selection);
|
||||
|
||||
SDL_DestroyMutex(music_vorbis_lock);
|
||||
SDL_DestroyMutex(music_vorbis_lock);
|
||||
}
|
||||
|
||||
// Internal music loading ruitines.
|
||||
static int music_loadOGG(const char* filename) {
|
||||
// Free currently loaded ogg.
|
||||
music_free();
|
||||
// Free currently loaded ogg.
|
||||
music_free();
|
||||
|
||||
SDL_mutexP(music_vorbis_lock);
|
||||
SDL_mutexP(music_vorbis_lock);
|
||||
|
||||
// Load the new ogg.
|
||||
pack_open(&music_vorbis.file, DATA, filename);
|
||||
ov_open_callbacks(&music_vorbis.file, &music_vorbis.stream, NULL, 0, ovcall);
|
||||
music_vorbis.info = ov_info(&music_vorbis.stream, -1);
|
||||
// Load the new ogg.
|
||||
pack_open(&music_vorbis.file, DATA, filename);
|
||||
ov_open_callbacks(&music_vorbis.file, &music_vorbis.stream, NULL, 0, ovcall);
|
||||
music_vorbis.info = ov_info(&music_vorbis.stream, -1);
|
||||
|
||||
if(music_vorbis.info->channels == 1) music_vorbis.format = AL_FORMAT_MONO16;
|
||||
else music_vorbis.format = AL_FORMAT_STEREO16;
|
||||
if(music_vorbis.info->channels == 1) music_vorbis.format = AL_FORMAT_MONO16;
|
||||
else music_vorbis.format = AL_FORMAT_STEREO16;
|
||||
|
||||
SDL_mutexV(music_vorbis_lock);
|
||||
return 0;
|
||||
SDL_mutexV(music_vorbis_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int music_find(void) {
|
||||
char** files;
|
||||
uint32_t nfiles, i;
|
||||
char tmp[64];
|
||||
int len;
|
||||
char** files;
|
||||
uint32_t nfiles, i;
|
||||
char tmp[64];
|
||||
int len;
|
||||
|
||||
// Get the file list.
|
||||
files = pack_listfiles(data, &nfiles);
|
||||
// Get the file list.
|
||||
files = pack_listfiles(data, &nfiles);
|
||||
|
||||
// Load the profiles.
|
||||
for(i = 0; i < nfiles; i++)
|
||||
if((strncmp(files[i], MUSIC_PREFIX, strlen(MUSIC_PREFIX))==0) &&
|
||||
(strncmp(files[i] + strlen(files[i]) - strlen(MUSIC_SUFFIX),
|
||||
MUSIC_SUFFIX, strlen(MUSIC_SUFFIX))==0)) {
|
||||
|
||||
// Grow the selection size.
|
||||
music_selection = realloc(music_selection,++nmusic_selection*sizeof(char*));
|
||||
// Load the profiles.
|
||||
for(i = 0; i < nfiles; i++)
|
||||
if((strncmp(files[i], MUSIC_PREFIX, strlen(MUSIC_PREFIX))==0) &&
|
||||
(strncmp(files[i] + strlen(files[i]) - strlen(MUSIC_SUFFIX),
|
||||
MUSIC_SUFFIX, strlen(MUSIC_SUFFIX))==0)) {
|
||||
|
||||
// Remove the prefix and suffix.
|
||||
len = strlen(files[i]) - strlen(MUSIC_SUFFIX MUSIC_PREFIX);
|
||||
strncpy(tmp, files[i] + strlen(MUSIC_PREFIX), len);
|
||||
tmp[len] = '\0';
|
||||
// Grow the selection size.
|
||||
music_selection = realloc(music_selection,++nmusic_selection*sizeof(char*));
|
||||
|
||||
music_selection[nmusic_selection-1] = strdup(tmp);
|
||||
}
|
||||
// Free the char* allocated by pack.
|
||||
for(i = 0; i < nfiles; i++)
|
||||
free(files[i]);
|
||||
free(files);
|
||||
// Remove the prefix and suffix.
|
||||
len = strlen(files[i]) - strlen(MUSIC_SUFFIX MUSIC_PREFIX);
|
||||
strncpy(tmp, files[i] + strlen(MUSIC_PREFIX), len);
|
||||
tmp[len] = '\0';
|
||||
|
||||
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) {
|
||||
SDL_mutexP(music_vorbis_lock);
|
||||
SDL_mutexP(music_vorbis_lock);
|
||||
|
||||
if(music_vorbis.file.end != 0) {
|
||||
ov_clear(&music_vorbis.stream);
|
||||
pack_close(&music_vorbis.file);
|
||||
music_vorbis.file.end = 0; // Somewhat ended.
|
||||
}
|
||||
if(music_vorbis.file.end != 0) {
|
||||
ov_clear(&music_vorbis.stream);
|
||||
pack_close(&music_vorbis.file);
|
||||
music_vorbis.file.end = 0; // Somewhat ended.
|
||||
}
|
||||
|
||||
SDL_mutexV(music_vorbis_lock);
|
||||
SDL_mutexV(music_vorbis_lock);
|
||||
}
|
||||
|
||||
void music_volume(const double vol) {
|
||||
if(sound_lock == NULL) return;
|
||||
if(sound_lock == NULL) return;
|
||||
|
||||
// Sanity check!
|
||||
ALfloat fvol = ABS(vol);
|
||||
if(fvol > 1.) fvol = 1.;
|
||||
// Sanity check!
|
||||
ALfloat fvol = ABS(vol);
|
||||
if(fvol > 1.) fvol = 1.;
|
||||
|
||||
mvolume = fvol;
|
||||
mvolume = fvol;
|
||||
|
||||
// Only needed if playing!
|
||||
if(music_set(MUSIC_PLAYING)) {
|
||||
SDL_mutexP(sound_lock);
|
||||
alSourcef(music_source, AL_GAIN, fvol);
|
||||
SDL_mutexV(sound_lock);
|
||||
}
|
||||
// Only needed if playing!
|
||||
if(music_set(MUSIC_PLAYING)) {
|
||||
SDL_mutexP(sound_lock);
|
||||
alSourcef(music_source, AL_GAIN, fvol);
|
||||
SDL_mutexV(sound_lock);
|
||||
}
|
||||
}
|
||||
|
||||
// Music control functions.
|
||||
void music_load(const char* name) {
|
||||
if(sound_lock == NULL) return;
|
||||
if(sound_lock == NULL) return;
|
||||
|
||||
int i;
|
||||
char tmp[64];
|
||||
int i;
|
||||
char tmp[64];
|
||||
|
||||
music_stop();
|
||||
while(!music_is(MUSIC_STOPPED)) SDL_Delay(0);
|
||||
music_stop();
|
||||
while(!music_is(MUSIC_STOPPED)) SDL_Delay(0);
|
||||
|
||||
for(i = 0; i < nmusic_selection; i++)
|
||||
if(strcmp(music_selection[i], name)==0) {
|
||||
snprintf(tmp, 64, MUSIC_PREFIX"%s"MUSIC_SUFFIX, name);
|
||||
music_loadOGG(tmp);
|
||||
return;
|
||||
}
|
||||
WARN("Requested load song '%s' but it can't be found in the music stack",name);
|
||||
for(i = 0; i < nmusic_selection; i++)
|
||||
if(strcmp(music_selection[i], name)==0) {
|
||||
snprintf(tmp, 64, MUSIC_PREFIX"%s"MUSIC_SUFFIX, name);
|
||||
music_loadOGG(tmp);
|
||||
return;
|
||||
}
|
||||
WARN("Requested load song '%s' but it can't be found in the music stack",name);
|
||||
}
|
||||
|
||||
void music_play(void) {
|
||||
if(!music_is(MUSIC_PLAYING)) music_set(MUSIC_PLAYING);
|
||||
if(!music_is(MUSIC_PLAYING)) music_set(MUSIC_PLAYING);
|
||||
}
|
||||
|
||||
void music_stop(void) {
|
||||
if(music_is(MUSIC_PLAYING)) music_rm(MUSIC_PLAYING);
|
||||
if(music_is(MUSIC_PLAYING)) music_rm(MUSIC_PLAYING);
|
||||
}
|
||||
|
||||
void music_kill(void) {
|
||||
if(!music_is(MUSIC_KILL)) music_set(MUSIC_KILL);
|
||||
if(!music_is(MUSIC_KILL)) music_set(MUSIC_KILL);
|
||||
}
|
||||
|
||||
|
288
src/opengl.c
288
src/opengl.c
@ -16,7 +16,7 @@
|
||||
#define SCREEN_W gl_screen.w
|
||||
#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.
|
||||
extern double gui_xoff;
|
||||
extern double gui_yoff;
|
||||
@ -37,7 +37,7 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh);
|
||||
|
||||
// PNG.
|
||||
int write_png(const char* file_name, png_bytep* rows, int w, int h,
|
||||
int colourtype, int bitdepth);
|
||||
int colourtype, int bitdepth);
|
||||
|
||||
// ================
|
||||
// MISC!
|
||||
@ -86,23 +86,23 @@ static int SDL_IsTrans(SDL_Surface* s, int x, int y) {
|
||||
Uint32 pixelcolour = 0;
|
||||
|
||||
switch(bpp) {
|
||||
case 1:
|
||||
pixelcolour = *p;
|
||||
break;
|
||||
case 2:
|
||||
pixelcolour = *(Uint16*)p;
|
||||
break;
|
||||
case 3:
|
||||
if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
|
||||
pixelcolour = p[0] << 16 | p[1] << 8 | p[2];
|
||||
else
|
||||
pixelcolour = p[0] | p[1] << 8 | p[2] << 16;
|
||||
break;
|
||||
case 4:
|
||||
pixelcolour = *(Uint32*)p;
|
||||
break;
|
||||
case 1:
|
||||
pixelcolour = *p;
|
||||
break;
|
||||
case 2:
|
||||
pixelcolour = *(Uint16*)p;
|
||||
break;
|
||||
case 3:
|
||||
if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
|
||||
pixelcolour = p[0] << 16 | p[1] << 8 | p[2];
|
||||
else
|
||||
pixelcolour = p[0] | p[1] << 8 | p[2] << 16;
|
||||
break;
|
||||
case 4:
|
||||
pixelcolour = *(Uint32*)p;
|
||||
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.
|
||||
return (pixelcolour == s->format->colorkey);
|
||||
}
|
||||
@ -153,7 +153,7 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh) {
|
||||
Uint32 saved_flags;
|
||||
Uint8 saved_alpha;
|
||||
int potw, poth;
|
||||
|
||||
|
||||
// Make size power of two.
|
||||
potw = pot(surface->w);
|
||||
poth = pot(surface->h);
|
||||
@ -175,13 +175,13 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh) {
|
||||
|
||||
// Create the temp POT surface.
|
||||
tmp = SDL_CreateRGBSurface(SDL_SRCCOLORKEY,
|
||||
potw, poth, surface->format->BytesPerPixel*8, RGBMASK);
|
||||
potw, poth, surface->format->BytesPerPixel*8, RGBMASK);
|
||||
if(tmp == NULL) {
|
||||
WARN("Unable to create POT surface %s", SDL_GetError());
|
||||
return 0;
|
||||
}
|
||||
if(SDL_FillRect(tmp, NULL, SDL_MapRGBA(surface->format, 0, 0, 0,
|
||||
SDL_ALPHA_TRANSPARENT))) {
|
||||
SDL_ALPHA_TRANSPARENT))) {
|
||||
WARN("Unable to fill rect: %s", SDL_GetError());
|
||||
return 0;
|
||||
}
|
||||
@ -197,13 +197,13 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh) {
|
||||
|
||||
// Create the temp POT surface.
|
||||
tmp = SDL_CreateRGBSurface(SDL_SRCCOLORKEY,
|
||||
potw, poth, surface->format->BytesPerPixel*8, RGBMASK);
|
||||
potw, poth, surface->format->BytesPerPixel*8, RGBMASK);
|
||||
if(tmp == NULL) {
|
||||
WARN("Unable to create POT surface %s", SDL_GetError());
|
||||
return 0;
|
||||
}
|
||||
if(SDL_FillRect(tmp, NULL, SDL_MapRGBA(surface->format, 0, 0, 0,
|
||||
SDL_ALPHA_TRANSPARENT))) {
|
||||
SDL_ALPHA_TRANSPARENT))) {
|
||||
WARN("Unable to fill rect: %s", SDL_GetError());
|
||||
return 0;
|
||||
}
|
||||
@ -212,7 +212,7 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh) {
|
||||
SDL_FreeSurface(surface);
|
||||
|
||||
surface = tmp;
|
||||
|
||||
|
||||
// Set saved alpha.
|
||||
if((saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA)
|
||||
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);
|
||||
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_FreeSurface(surface);
|
||||
@ -253,7 +253,7 @@ glTexture* gl_loadImage(SDL_Surface* surface) {
|
||||
texture->rh = (double)rh;
|
||||
texture->sw = texture->w;
|
||||
texture->sh = texture->h;
|
||||
|
||||
|
||||
texture->trans = NULL;
|
||||
|
||||
return texture;
|
||||
@ -292,7 +292,7 @@ glTexture* gl_newImage(const char* path) {
|
||||
WARN("Error flipping surface");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// Do after flipping for collision detection.
|
||||
SDL_LockSurface(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.
|
||||
void gl_getSpriteFromDir(int* x, int* y, const glTexture* t, const double dir) {
|
||||
int s, sx, sy;
|
||||
int s, sx, sy;
|
||||
|
||||
s = (int)(dir / (2.0*M_PI / (t->sy*t->sx)));
|
||||
sx = t->sx;
|
||||
sy = t->sy;
|
||||
sx = t->sx;
|
||||
sy = t->sy;
|
||||
|
||||
// Make sure the sprite is "in range".
|
||||
if(s > (sy*sx-1)) s = s % (sy*sx);
|
||||
if(s > (sy*sx-1)) s = s % (sy*sx);
|
||||
|
||||
*x = s % sx;
|
||||
*y = s / sx;
|
||||
@ -348,10 +348,10 @@ void gl_getSpriteFromDir(int* x, int* y, const glTexture* t, const double dir) {
|
||||
|
||||
// Blit the sprite at given position.
|
||||
void gl_blitSprite(const glTexture* sprite, const double bx, const double by,
|
||||
const int sx, const int sy, const glColour* c) {
|
||||
const int sx, const int sy, const glColour* c) {
|
||||
// Don't bother drawing if offscreen -- waste of cycles.
|
||||
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;
|
||||
|
||||
double x, y, tx, ty;
|
||||
@ -367,20 +367,20 @@ void gl_blitSprite(const glTexture* sprite, const double bx, const double by,
|
||||
// Actual blitting....
|
||||
glBindTexture(GL_TEXTURE_2D, sprite->texture);
|
||||
glBegin(GL_QUADS);
|
||||
if(c == NULL) glColor4d(1., 1., 1., 1.);
|
||||
else COLOUR(*c);
|
||||
if(c == NULL) glColor4d(1., 1., 1., 1.);
|
||||
else COLOUR(*c);
|
||||
|
||||
glTexCoord2d(tx, ty);
|
||||
glVertex2d(x, y);
|
||||
glTexCoord2d(tx, ty);
|
||||
glVertex2d(x, y);
|
||||
|
||||
glTexCoord2d(tx + sprite->sw/sprite->rw, ty);
|
||||
glVertex2d(x + sprite->sw, y);
|
||||
glTexCoord2d(tx + sprite->sw/sprite->rw, ty);
|
||||
glVertex2d(x + sprite->sw, y);
|
||||
|
||||
glTexCoord2d(tx + sprite->sw/sprite->rw, ty + sprite->sh/sprite->rh);
|
||||
glVertex2d(x + sprite->sw, y + sprite->sh);
|
||||
glTexCoord2d(tx + sprite->sw/sprite->rw, ty + sprite->sh/sprite->rh);
|
||||
glVertex2d(x + sprite->sw, y + sprite->sh);
|
||||
|
||||
glTexCoord2d(tx, ty + sprite->sh/sprite->rh);
|
||||
glVertex2d(x, y + sprite->sh);
|
||||
glTexCoord2d(tx, ty + sprite->sh/sprite->rh);
|
||||
glVertex2d(x, y + sprite->sh);
|
||||
|
||||
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.
|
||||
void gl_blitStatic(const glTexture* texture, const double bx, const double by,
|
||||
const glColour* c) {
|
||||
const glColour* c) {
|
||||
double x, y;
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
|
||||
x = bx - (double)gl_screen.w/2.;
|
||||
y = by - (double)gl_screen.h/2.;
|
||||
|
||||
// Actual blitting..
|
||||
glBindTexture(GL_TEXTURE_2D, texture->texture);
|
||||
glBegin(GL_QUADS);
|
||||
if(c == NULL) glColor4d(1., 1., 1., 1.);
|
||||
else COLOUR(*c);
|
||||
|
||||
glTexCoord2d(0., 0.);
|
||||
glVertex2d(x, y);
|
||||
if(c == NULL) glColor4d(1., 1., 1., 1.);
|
||||
else COLOUR(*c);
|
||||
|
||||
glTexCoord2d(texture->sw/texture->rw, 0.);
|
||||
glVertex2d(x + texture->sw, y);
|
||||
glTexCoord2d(0., 0.);
|
||||
glVertex2d(x, y);
|
||||
|
||||
glTexCoord2d(texture->sw/texture->rw, texture->sh/texture->rh);
|
||||
glVertex2d(x + texture->sw, y + texture->sh);
|
||||
glTexCoord2d(texture->sw/texture->rw, 0.);
|
||||
glVertex2d(x + texture->sw, y);
|
||||
|
||||
glTexCoord2d(0., texture->sh/texture->rh);
|
||||
glVertex2d(x, y + texture->sh);
|
||||
glTexCoord2d(texture->sw/texture->rw, texture->sh/texture->rh);
|
||||
glVertex2d(x + texture->sw, y + texture->sh);
|
||||
|
||||
glTexCoord2d(0., texture->sh/texture->rh);
|
||||
glVertex2d(x, y + texture->sh);
|
||||
|
||||
glEnd();
|
||||
|
||||
@ -426,110 +426,110 @@ void gl_bindCamera(const Vec2* pos) {
|
||||
|
||||
// Draw circles.
|
||||
void gl_drawCircle(const double cx, const double cy, const double r) {
|
||||
double x, y, p;
|
||||
double x, y, p;
|
||||
|
||||
x = 0;
|
||||
y = r;
|
||||
p = (5. - (r*4.)) / 4.;
|
||||
x = 0;
|
||||
y = r;
|
||||
p = (5. - (r*4.)) / 4.;
|
||||
|
||||
glBegin(GL_POINTS);
|
||||
glBegin(GL_POINTS);
|
||||
glVertex2d(cx, cy+y);
|
||||
glVertex2d(cx, cy-y);
|
||||
glVertex2d(cx+y, cy);
|
||||
glVertex2d(cx-y, cy);
|
||||
|
||||
while(x < y) {
|
||||
x++;
|
||||
if(p < 0) p += 2*(double)(x)+1;
|
||||
else p += 2*(double)(x-(--y))+1;
|
||||
x++;
|
||||
if(p < 0) p += 2*(double)(x)+1;
|
||||
else p += 2*(double)(x-(--y))+1;
|
||||
|
||||
if(x == 0) {
|
||||
glVertex2d(cx, cy+y);
|
||||
glVertex2d(cx, cy-y);
|
||||
glVertex2d(cx+y, cy);
|
||||
glVertex2d(cx-y, cy);
|
||||
}
|
||||
else if(x == y) {
|
||||
glVertex2d(cx+x, cy+y);
|
||||
glVertex2d(cx-x, cy+y);
|
||||
glVertex2d(cx+x, cy-y);
|
||||
glVertex2d(cx-x, cy-y);
|
||||
}
|
||||
else if(x < y) {
|
||||
glVertex2d(cx+x, cy+y);
|
||||
glVertex2d(cx-x, cy+y);
|
||||
glVertex2d(cx+x, cy-y);
|
||||
glVertex2d(cx-x, cy-y);
|
||||
glVertex2d(cx+y, cy+x);
|
||||
glVertex2d(cx-y, cy+x);
|
||||
glVertex2d(cx+y, cy-x);
|
||||
glVertex2d(cx-y, cy-x);
|
||||
}
|
||||
if(x == 0) {
|
||||
glVertex2d(cx, cy+y);
|
||||
glVertex2d(cx, cy-y);
|
||||
glVertex2d(cx+y, cy);
|
||||
glVertex2d(cx-y, cy);
|
||||
}
|
||||
else if(x == y) {
|
||||
glVertex2d(cx+x, cy+y);
|
||||
glVertex2d(cx-x, cy+y);
|
||||
glVertex2d(cx+x, cy-y);
|
||||
glVertex2d(cx-x, cy-y);
|
||||
}
|
||||
else if(x < y) {
|
||||
glVertex2d(cx+x, cy+y);
|
||||
glVertex2d(cx-x, cy+y);
|
||||
glVertex2d(cx+x, cy-y);
|
||||
glVertex2d(cx-x, cy-y);
|
||||
glVertex2d(cx+y, cy+x);
|
||||
glVertex2d(cx-y, cy+x);
|
||||
glVertex2d(cx+y, cy-x);
|
||||
glVertex2d(cx-y, cy-x);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
glEnd();
|
||||
}
|
||||
|
||||
// Draw a cirlce in a rect.
|
||||
#define PIXEL(x,y) \
|
||||
if((x>rx) && (y>ry) && (x<rxw) && (y<ryh)) \
|
||||
glVertex2d(x,y)
|
||||
if((x>rx) && (y>ry) && (x<rxw) && (y<ryh)) \
|
||||
glVertex2d(x,y)
|
||||
|
||||
void gl_drawCircleInRect(const double cx, const double cy, const double r,
|
||||
const double rx, const double ry, const double rw, const double rh) {
|
||||
const double rx, const double ry, const double rw, const double rh) {
|
||||
|
||||
double rxw, ryh, x, y, p;
|
||||
double rxw, ryh, x, y, p;
|
||||
|
||||
rxw = rx+rw;
|
||||
ryh = ry+rh;
|
||||
|
||||
// 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;
|
||||
}
|
||||
rxw = rx+rw;
|
||||
ryh = ry+rh;
|
||||
|
||||
x = 0;
|
||||
y = r;
|
||||
p = (5. - (r*4.)) / 4.;
|
||||
// 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;
|
||||
}
|
||||
|
||||
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+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) {
|
||||
PIXEL(cx, cy+y);
|
||||
PIXEL(cx, cy-y);
|
||||
PIXEL(cx+y, cy);
|
||||
PIXEL(cx-y, cy);
|
||||
}
|
||||
else if(x == y) {
|
||||
PIXEL(cx+x, cy+y);
|
||||
PIXEL(cx-x, cy+y);
|
||||
PIXEL(cx+x, cy-y);
|
||||
PIXEL(cx-x, cy-y);
|
||||
}
|
||||
else if(x < y) {
|
||||
PIXEL(cx+x, cy+y);
|
||||
PIXEL(cx-x, cy+y);
|
||||
PIXEL(cx+x, cy-y);
|
||||
PIXEL(cx-x, cy-y);
|
||||
PIXEL(cx+y, cy+x);
|
||||
PIXEL(cx-y, cy+x);
|
||||
PIXEL(cx+y, cy-x);
|
||||
PIXEL(cx-y, cy-x);
|
||||
}
|
||||
while(x < y) {
|
||||
x++;
|
||||
if(p < 0) p += 2*(double)(x)+1;
|
||||
else p += 2*(double)(x-(--y))+1;
|
||||
|
||||
if(x == 0) {
|
||||
PIXEL(cx, cy+y);
|
||||
PIXEL(cx, cy-y);
|
||||
PIXEL(cx+y, cy);
|
||||
PIXEL(cx-y, cy);
|
||||
}
|
||||
else if(x == y) {
|
||||
PIXEL(cx+x, cy+y);
|
||||
PIXEL(cx-x, cy+y);
|
||||
PIXEL(cx+x, cy-y);
|
||||
PIXEL(cx-x, cy-y);
|
||||
}
|
||||
else if(x < y) {
|
||||
PIXEL(cx+x, cy+y);
|
||||
PIXEL(cx-x, cy+y);
|
||||
PIXEL(cx+x, cy-y);
|
||||
PIXEL(cx-x, cy-y);
|
||||
PIXEL(cx+y, cy+x);
|
||||
PIXEL(cx-y, cy+x);
|
||||
PIXEL(cx+y, cy-x);
|
||||
PIXEL(cx-y, cy-x);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
glEnd();
|
||||
}
|
||||
|
||||
// ================
|
||||
@ -566,7 +566,7 @@ int gl_init(void) {
|
||||
for(i = 0; modes[i]; i++) {
|
||||
DEBUG("\t%dx%d", modes[i]->w, modes[i]->h);
|
||||
if((flags & SDL_FULLSCREEN) && (modes[i]->w == gl_screen.w) &&
|
||||
(modes[i]->h == gl_screen.h))
|
||||
(modes[i]->h == gl_screen.h))
|
||||
supported = 1; // Mode we asked for is supported.
|
||||
}
|
||||
}
|
||||
@ -584,8 +584,8 @@ int gl_init(void) {
|
||||
}
|
||||
}
|
||||
WARN("Fullscreen mode %dx%d is not supported by your setup\n"
|
||||
" Switching to %dx%d", gl_screen.w, gl_screen.h,
|
||||
modes[j]->w, modes[j]->h);
|
||||
" Switching to %dx%d", gl_screen.w, gl_screen.h,
|
||||
modes[j]->w, modes[j]->h);
|
||||
|
||||
gl_screen.w = modes[j]->w;
|
||||
gl_screen.h = modes[j]->h;
|
||||
@ -621,10 +621,10 @@ int gl_init(void) {
|
||||
|
||||
// Debug heaven.
|
||||
DEBUG("OpenGL Window Created: %dx%d@%dbpp %s", gl_screen.w, gl_screen.h,
|
||||
gl_screen.depth, (gl_has(OPENGL_FULLSCREEN)) ? "fullscreen" : "window");
|
||||
gl_screen.depth, (gl_has(OPENGL_FULLSCREEN)) ? "fullscreen" : "window");
|
||||
|
||||
DEBUG("r: %d, g: %d, b: %d, a: %d, doublebuffer: %s",
|
||||
gl_screen.r, gl_screen.g, gl_screen.b, gl_screen.a,
|
||||
gl_screen.r, gl_screen.g, gl_screen.b, gl_screen.a,
|
||||
(gl_has(OPENGL_DOUBLEBUF)) ? "yes" : "no");
|
||||
|
||||
DEBUG("Renderer: %s", glGetString(GL_RENDERER));
|
||||
@ -645,7 +645,7 @@ int gl_init(void) {
|
||||
SCREEN_H /2, // Top edge.
|
||||
-1., // Near.
|
||||
1.); // Far.
|
||||
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
return 0;
|
||||
@ -658,7 +658,7 @@ void gl_exit(void) {
|
||||
|
||||
// Saves a png.
|
||||
int write_png(const char* file_name, png_bytep* rows, int w, int h,
|
||||
int colourtype, int bitdepth) {
|
||||
int colourtype, int bitdepth) {
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
FILE* fp = NULL;
|
||||
@ -668,7 +668,7 @@ int write_png(const char* file_name, png_bytep* rows, int w, int h,
|
||||
|
||||
doing = "Create png write struct";
|
||||
if(!(png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
|
||||
NULL, NULL, NULL))) goto fail;
|
||||
NULL, NULL, NULL))) goto fail;
|
||||
|
||||
doing = "Create png info struct";
|
||||
if(!(info_ptr = png_create_info_struct(png_ptr))) goto fail;
|
||||
@ -677,8 +677,8 @@ int write_png(const char* file_name, png_bytep* rows, int w, int h,
|
||||
doing = "Init IO";
|
||||
png_init_io(png_ptr, fp);
|
||||
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";
|
||||
png_write_info(png_ptr, info_ptr);
|
||||
|
||||
|
@ -54,12 +54,12 @@ void gl_freeTexture(glTexture* texture);
|
||||
|
||||
// Rendering.
|
||||
// Blits a sprite.
|
||||
void gl_blitSprite(const glTexture* sprite, const double bx, const double by,
|
||||
const int sx, const int sy, const glColour* c);
|
||||
void gl_blitSprite(const glTexture* sprite, const double bx, const double by,
|
||||
const int sx, const int sy, const glColour* c);
|
||||
|
||||
// Blit the entire image.
|
||||
void gl_blitStatic(const glTexture* texture, const double bx, const double by,
|
||||
const glColour* c);
|
||||
const glColour* c);
|
||||
|
||||
// Bind the camera to a vector.
|
||||
void gl_bindCamera(const Vec2* pos);
|
||||
@ -67,7 +67,7 @@ void gl_bindCamera(const Vec2* pos);
|
||||
// Circle drawing.
|
||||
void gl_drawCircle(const double x, const double y, const double r);
|
||||
void gl_drawCircleInRect(const double x, const double y, const double r,
|
||||
const double rc, const double ry, const double rw, const double rh);
|
||||
const double rc, const double ry, const double rw, const double rh);
|
||||
|
||||
// Initialize/cleanup.
|
||||
int gl_init(void);
|
||||
|
320
src/outfit.c
320
src/outfit.c
@ -42,24 +42,24 @@ Outfit* outfit_get(const char* name) {
|
||||
|
||||
// Return all the outfits.
|
||||
char** outfit_getTech(int* n, const int* tech, const int techmax) {
|
||||
int i, j;
|
||||
char** outfitnames = malloc(sizeof(Outfit*) * outfits);
|
||||
|
||||
*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)++;
|
||||
}
|
||||
}
|
||||
int i, j;
|
||||
char** outfitnames = malloc(sizeof(Outfit*) * outfits);
|
||||
|
||||
// Actual size is bigger, but it'll just get freed ;).
|
||||
return outfitnames;
|
||||
*n = 0;
|
||||
for(i = 0; i < outfits; i++)
|
||||
if(outfit_stack[i].tech <= tech[0]) {
|
||||
outfitnames[*n] = strdup(outfit_stack[i].name);
|
||||
(*n)++;
|
||||
} else {
|
||||
for(j = 0; j < techmax; j++)
|
||||
if(tech[j] == outfit_stack[i].tech) {
|
||||
outfitnames[*n] = strdup(outfit_stack[i].name);
|
||||
(*n)++;
|
||||
}
|
||||
}
|
||||
|
||||
// Actual size is bigger, but it'll just get freed ;).
|
||||
return outfitnames;
|
||||
}
|
||||
|
||||
// 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.
|
||||
int outfit_isLauncher(const Outfit* o) {
|
||||
return((o->type == OUTFIT_TYPE_MISSILE_DUMB) ||
|
||||
(o->type == OUTFIT_TYPE_MISSILE_SEEK) ||
|
||||
(o->type == OUTFIT_TYPE_MISSILE_SEEK_SMART) ||
|
||||
(o->type == OUTFIT_TYPE_MISSILE_SWARM) ||
|
||||
(o->type == OUTFIT_TYPE_MISSILE_SWARM_SMART));
|
||||
(o->type == OUTFIT_TYPE_MISSILE_SEEK) ||
|
||||
(o->type == OUTFIT_TYPE_MISSILE_SEEK_SMART) ||
|
||||
(o->type == OUTFIT_TYPE_MISSILE_SWARM) ||
|
||||
(o->type == OUTFIT_TYPE_MISSILE_SWARM_SMART));
|
||||
}
|
||||
|
||||
// Return 1 if outfit is weapon ammunition.
|
||||
int outfit_isAmmo(const Outfit* o) {
|
||||
return((o->type == OUTFIT_TYPE_MISSILE_DUMB_AMMO) ||
|
||||
(o->type == OUTFIT_TYPE_MISSILE_SEEK_AMMO) ||
|
||||
(o->type == OUTFIT_TYPE_MISSILE_SEEK_SMART_AMMO) ||
|
||||
(o->type == OUTFIT_TYPE_MISSILE_SWARM_AMMO) ||
|
||||
(o->type == OUTFIT_TYPE_MISSILE_SWARM_SMART_AMMO));
|
||||
(o->type == OUTFIT_TYPE_MISSILE_SEEK_AMMO) ||
|
||||
(o->type == OUTFIT_TYPE_MISSILE_SEEK_SMART_AMMO) ||
|
||||
(o->type == OUTFIT_TYPE_MISSILE_SWARM_AMMO) ||
|
||||
(o->type == OUTFIT_TYPE_MISSILE_SWARM_SMART_AMMO));
|
||||
|
||||
}
|
||||
|
||||
int outfit_isTurret(const Outfit* o) {
|
||||
return ((o->type == OUTFIT_TYPE_TURRET_BOLT) ||
|
||||
(o->type == OUTFIT_TYPE_TURRET_BEAM));
|
||||
return ((o->type == OUTFIT_TYPE_TURRET_BOLT) ||
|
||||
(o->type == OUTFIT_TYPE_TURRET_BEAM));
|
||||
}
|
||||
|
||||
// Return 1 if o is a modification.
|
||||
int outfit_isMod(const Outfit* o) {
|
||||
return (o->type == OUTFIT_TYPE_MODIFICATION);
|
||||
return (o->type == OUTFIT_TYPE_MODIFICATION);
|
||||
}
|
||||
|
||||
// Return 1 if o is an afterburner.
|
||||
int outfit_isAfterburner(const Outfit* o) {
|
||||
return (o->type == OUTFIT_TYPE_AFTERBURNER);
|
||||
return (o->type == OUTFIT_TYPE_AFTERBURNER);
|
||||
}
|
||||
|
||||
// Get the outfit graphics.
|
||||
glTexture* outfit_gfx(const Outfit* o) {
|
||||
if(outfit_isWeapon(o)) return o->u.blt.gfx_space;
|
||||
else if(outfit_isAmmo(o)) return o->u.amm.gfx_space;
|
||||
else if(outfit_isTurret(o)) return o->u.blt.gfx_space;
|
||||
return NULL;
|
||||
if(outfit_isWeapon(o)) return o->u.blt.gfx_space;
|
||||
else if(outfit_isAmmo(o)) return o->u.amm.gfx_space;
|
||||
else if(outfit_isTurret(o)) return o->u.blt.gfx_space;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get the outfit spfx if applicable.
|
||||
int outfit_spfx(const Outfit* o) {
|
||||
if(outfit_isWeapon(o)) return o->u.blt.spfx;
|
||||
else if(outfit_isAmmo(o)) return o->u.amm.spfx;
|
||||
else if(outfit_isTurret(o)) return o->u.blt.spfx;
|
||||
return -1;
|
||||
if(outfit_isWeapon(o)) return o->u.blt.spfx;
|
||||
else if(outfit_isAmmo(o)) return o->u.amm.spfx;
|
||||
else if(outfit_isTurret(o)) return o->u.blt.spfx;
|
||||
return -1;
|
||||
}
|
||||
|
||||
double outfit_dmgShield(const Outfit* o) {
|
||||
if(outfit_isWeapon(o)) return o->u.blt.damage_armour;
|
||||
else if(outfit_isAmmo(o)) return o->u.amm.damage_armour;
|
||||
else if(outfit_isTurret(o)) return o->u.blt.damage_armour;
|
||||
return -1;
|
||||
if(outfit_isWeapon(o)) return o->u.blt.damage_armour;
|
||||
else if(outfit_isAmmo(o)) return o->u.amm.damage_armour;
|
||||
else if(outfit_isTurret(o)) return o->u.blt.damage_armour;
|
||||
return -1;
|
||||
}
|
||||
|
||||
double outfit_dmgArmour(const Outfit* o) {
|
||||
if(outfit_isWeapon(o)) return o->u.blt.damage_shield;
|
||||
else if(outfit_isAmmo(o)) return o->u.amm.damage_shield;
|
||||
else if(outfit_isTurret(o)) return o->u.blt.damage_shield;
|
||||
return -1;
|
||||
if(outfit_isWeapon(o)) return o->u.blt.damage_shield;
|
||||
else if(outfit_isAmmo(o)) return o->u.amm.damage_shield;
|
||||
else if(outfit_isTurret(o)) return o->u.blt.damage_shield;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int outfit_delay(const Outfit* o) {
|
||||
if(outfit_isWeapon(o)) return o->u.blt.delay;
|
||||
else if(outfit_isLauncher(o)) return o->u.lau.delay;
|
||||
else if(outfit_isTurret(o)) return o->u.blt.delay;
|
||||
return -1;
|
||||
if(outfit_isWeapon(o)) return o->u.blt.delay;
|
||||
else if(outfit_isLauncher(o)) return o->u.lau.delay;
|
||||
else if(outfit_isTurret(o)) return o->u.blt.delay;
|
||||
return -1;
|
||||
}
|
||||
|
||||
double outfit_energy(const Outfit* o) {
|
||||
if(outfit_isWeapon(o)) return o->u.blt.energy;
|
||||
else if(outfit_isAmmo(o)) return o->u.amm.energy;
|
||||
else if(outfit_isTurret(o)) return o->u.blt.energy;
|
||||
return -1.;
|
||||
if(outfit_isWeapon(o)) return o->u.blt.energy;
|
||||
else if(outfit_isAmmo(o)) return o->u.amm.energy;
|
||||
else if(outfit_isTurret(o)) return o->u.blt.energy;
|
||||
return -1.;
|
||||
}
|
||||
|
||||
const char* outfit_typename[] = {
|
||||
@ -159,10 +159,10 @@ const char* outfit_typename[] = {
|
||||
"Swarm Missile Ammunition Pack",
|
||||
"Smart Swarm Missile",
|
||||
"Smart Swarm Missile Ammunition Pack",
|
||||
"Bolt Turret",
|
||||
"Beam Turret",
|
||||
"Ship Modification",
|
||||
"Afterburner"
|
||||
"Bolt Turret",
|
||||
"Beam Turret",
|
||||
"Ship Modification",
|
||||
"Afterburner"
|
||||
};
|
||||
|
||||
const char* outfit_getType(const Outfit* o) {
|
||||
@ -170,14 +170,14 @@ const char* outfit_getType(const Outfit* o) {
|
||||
}
|
||||
|
||||
// Return the broad outfit type.
|
||||
const char* outfit_typenamebroad[] = {
|
||||
"NULL",
|
||||
"Weapon",
|
||||
"Launcher",
|
||||
"Ammo",
|
||||
"Turret",
|
||||
"Modification",
|
||||
"Afterburner"
|
||||
const char* outfit_typenamebroad[] = {
|
||||
"NULL",
|
||||
"Weapon",
|
||||
"Launcher",
|
||||
"Ammo",
|
||||
"Turret",
|
||||
"Modification",
|
||||
"Afterburner"
|
||||
};
|
||||
|
||||
const char* outfit_getTypeBroad(const Outfit* o) {
|
||||
@ -185,9 +185,9 @@ const char* outfit_getTypeBroad(const Outfit* o) {
|
||||
if(outfit_isWeapon(o)) i = 1;
|
||||
else if(outfit_isLauncher(o)) i = 2;
|
||||
else if(outfit_isAmmo(o)) i = 3;
|
||||
else if(outfit_isTurret(o)) i = 4;
|
||||
else if(outfit_isMod(o)) i = 5;
|
||||
else if(outfit_isAfterburner(o)) i = 6;
|
||||
else if(outfit_isTurret(o)) i = 4;
|
||||
else if(outfit_isMod(o)) i = 5;
|
||||
else if(outfit_isAfterburner(o)) i = 6;
|
||||
|
||||
return outfit_typenamebroad[i];
|
||||
}
|
||||
@ -205,31 +205,31 @@ static void outfit_parseSWeapon(Outfit* tmp, const xmlNodePtr parent) {
|
||||
else if(xml_isNode(node, "delay")) tmp->u.blt.delay = xml_getInt(node);
|
||||
else if(xml_isNode(node, "range")) tmp->u.blt.range = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "accuracy")) tmp->u.blt.accuracy = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "energy")) tmp->u.blt.energy = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "energy")) tmp->u.blt.energy = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "gfx")) {
|
||||
snprintf(str, strlen(xml_get(node))+sizeof(OUTFIT_GFX)+10,
|
||||
OUTFIT_GFX"space/%s.png", xml_get(node));
|
||||
snprintf(str, strlen(xml_get(node))+sizeof(OUTFIT_GFX)+10,
|
||||
OUTFIT_GFX"space/%s.png", xml_get(node));
|
||||
tmp->u.blt.gfx_space = gl_newSprite(str, 6, 6);
|
||||
}
|
||||
else if(xml_isNode(node, "spfx"))
|
||||
tmp->u.blt.spfx = spfx_get(xml_get(node));
|
||||
else if(xml_isNode(node, "sound"))
|
||||
tmp->u.blt.sound = sound_get(xml_get(node));
|
||||
else if(xml_isNode(node, "spfx"))
|
||||
tmp->u.blt.spfx = spfx_get(xml_get(node));
|
||||
else if(xml_isNode(node, "sound"))
|
||||
tmp->u.blt.sound = sound_get(xml_get(node));
|
||||
else if(xml_isNode(node, "damage")) {
|
||||
cur = node->children;
|
||||
do {
|
||||
if(xml_isNode(cur, "armour"))
|
||||
tmp->u.blt.damage_armour = xml_getFloat(cur);
|
||||
tmp->u.blt.damage_armour = xml_getFloat(cur);
|
||||
else if(xml_isNode(cur, "shield"))
|
||||
tmp->u.blt.damage_shield = xml_getFloat(cur);
|
||||
tmp->u.blt.damage_shield = xml_getFloat(cur);
|
||||
} while((cur = cur->next));
|
||||
}
|
||||
} while((node = node->next));
|
||||
#define MELEMENT(o,s) if((o) == 0) \
|
||||
WARN("Outfit '%s' missing '"s"' element", tmp->name)
|
||||
WARN("Outfit '%s' missing '"s"' element", tmp->name)
|
||||
if(tmp->u.blt.gfx_space == NULL)
|
||||
WARN("Outfit '%s' missing 'gfx' element", tmp->name);
|
||||
MELEMENT(tmp->u.blt.sound, "sound");
|
||||
MELEMENT(tmp->u.blt.sound, "sound");
|
||||
MELEMENT(tmp->u.blt.delay, "delay");
|
||||
MELEMENT(tmp->u.blt.speed, "speed");
|
||||
MELEMENT(tmp->u.blt.range, "range");
|
||||
@ -267,20 +267,20 @@ static void outfit_parseSAmmo(Outfit* tmp, const xmlNodePtr parent) {
|
||||
if(xml_isNode(node, "thrust")) tmp->u.amm.thrust = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "turn")) tmp->u.amm.turn = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "speed")) tmp->u.amm.speed = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "energy")) tmp->u.amm.energy = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "energy")) tmp->u.amm.energy = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "duration"))
|
||||
tmp->u.amm.duration = (unsigned int)1000.*xml_getFloat(node);
|
||||
else if(xml_isNode(node, "lockon"))
|
||||
tmp->u.amm.lockon = (unsigned int)1000.*xml_getFloat(node);
|
||||
tmp->u.amm.duration = (unsigned int)1000.*xml_getFloat(node);
|
||||
else if(xml_isNode(node, "lockon"))
|
||||
tmp->u.amm.lockon = (unsigned int)1000.*xml_getFloat(node);
|
||||
else if(xml_isNode(node, "gfx")) {
|
||||
snprintf(str, strlen(xml_get(node))+sizeof(OUTFIT_GFX)+10,
|
||||
OUTFIT_GFX"space/%s.png", xml_get(node));
|
||||
OUTFIT_GFX"space/%s.png", xml_get(node));
|
||||
tmp->u.amm.gfx_space = gl_newSprite(str, 6, 6);
|
||||
}
|
||||
else if(xml_isNode(node, "spfx"))
|
||||
tmp->u.amm.spfx = spfx_get(xml_get(node));
|
||||
else if(xml_isNode(node, "sound"))
|
||||
tmp->u.amm.sound = sound_get(xml_get(node));
|
||||
else if(xml_isNode(node, "spfx"))
|
||||
tmp->u.amm.spfx = spfx_get(xml_get(node));
|
||||
else if(xml_isNode(node, "sound"))
|
||||
tmp->u.amm.sound = sound_get(xml_get(node));
|
||||
else if(xml_isNode(node, "damage")) {
|
||||
cur = node->children;
|
||||
do {
|
||||
@ -291,69 +291,69 @@ static void outfit_parseSAmmo(Outfit* tmp, const xmlNodePtr parent) {
|
||||
} while((node = node->next));
|
||||
#define MELEMENT(o,s) if(o) WARN("Outfit '%s' missing '"s"' element", tmp->name)
|
||||
MELEMENT(tmp->u.amm.gfx_space == NULL, "gfx");
|
||||
MELEMENT((sound_lock != NULL) && (tmp->u.amm.sound == 0), "sound");
|
||||
MELEMENT((sound_lock != NULL) && (tmp->u.amm.sound == 0), "sound");
|
||||
MELEMENT(tmp->u.amm.thrust==0, "thrust");
|
||||
MELEMENT(tmp->u.amm.turn==0, "turn");
|
||||
MELEMENT(tmp->u.amm.speed==0, "speed");
|
||||
MELEMENT(tmp->u.amm.duration==0, "duration");
|
||||
MELEMENT(tmp->u.amm.lockon==0, "lockon");
|
||||
MELEMENT(tmp->u.amm.lockon==0, "lockon");
|
||||
MELEMENT(tmp->u.amm.damage_armour==0, "armour' from element 'damage");
|
||||
MELEMENT(tmp->u.amm.damage_shield==0, "shield' from element 'damage");
|
||||
#undef MELEMENT
|
||||
}
|
||||
|
||||
static void outfit_parseSMod(Outfit* tmp, const xmlNodePtr parent) {
|
||||
xmlNodePtr node;
|
||||
node = parent->children;
|
||||
xmlNodePtr node;
|
||||
node = parent->children;
|
||||
|
||||
// Load all the data.
|
||||
do {
|
||||
// Movement.
|
||||
if(xml_isNode(node, "thrust"))
|
||||
tmp->u.mod.thrust = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "turn"))
|
||||
tmp->u.mod.turn = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "speed"))
|
||||
tmp->u.mod.speed = xml_getFloat(node);
|
||||
// Load all the data.
|
||||
do {
|
||||
// Movement.
|
||||
if(xml_isNode(node, "thrust"))
|
||||
tmp->u.mod.thrust = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "turn"))
|
||||
tmp->u.mod.turn = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "speed"))
|
||||
tmp->u.mod.speed = xml_getFloat(node);
|
||||
|
||||
// Health.
|
||||
if(xml_isNode(node, "armour"))
|
||||
tmp->u.mod.armour = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "shield"))
|
||||
tmp->u.mod.shield = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "energy"))
|
||||
tmp->u.mod.energy = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "armour_regen"))
|
||||
tmp->u.mod.armour_regen = xml_getFloat(node)/60.0;
|
||||
else if(xml_isNode(node, "shield_regen"))
|
||||
tmp->u.mod.shield_regen = xml_getFloat(node)/60.0;
|
||||
else if(xml_isNode(node, "energy_regen"))
|
||||
tmp->u.mod.energy_regen = xml_getFloat(node)/60.0;
|
||||
// Health.
|
||||
if(xml_isNode(node, "armour"))
|
||||
tmp->u.mod.armour = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "shield"))
|
||||
tmp->u.mod.shield = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "energy"))
|
||||
tmp->u.mod.energy = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "armour_regen"))
|
||||
tmp->u.mod.armour_regen = xml_getFloat(node)/60.0;
|
||||
else if(xml_isNode(node, "shield_regen"))
|
||||
tmp->u.mod.shield_regen = xml_getFloat(node)/60.0;
|
||||
else if(xml_isNode(node, "energy_regen"))
|
||||
tmp->u.mod.energy_regen = xml_getFloat(node)/60.0;
|
||||
|
||||
} while((node = node->next));
|
||||
} while((node = node->next));
|
||||
}
|
||||
|
||||
// Parses the afterburner tidbits of the outfit.
|
||||
static void outfit_parseSAfterburner(Outfit* tmp, const xmlNodePtr parent) {
|
||||
xmlNodePtr node;
|
||||
node = parent->children;
|
||||
xmlNodePtr node;
|
||||
node = parent->children;
|
||||
|
||||
// Must be >= 1.
|
||||
tmp->u.afb.thrust_perc = 1.;
|
||||
tmp->u.afb.speed_perc = 1.;
|
||||
// Must be >= 1.
|
||||
tmp->u.afb.thrust_perc = 1.;
|
||||
tmp->u.afb.speed_perc = 1.;
|
||||
|
||||
do {
|
||||
if(xml_isNode(node, "thrust_perc"))
|
||||
tmp->u.afb.thrust_perc = 1. + xml_getFloat(node)/100.;
|
||||
else if(xml_isNode(node, "thrust_abs"))
|
||||
tmp->u.afb.thrust_abs = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "speed_perc"))
|
||||
tmp->u.afb.speed_perc = 1. + xml_getFloat(node)/100.;
|
||||
else if(xml_isNode(node, "speed_abs"))
|
||||
tmp->u.afb.speed_abs = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "energy"))
|
||||
tmp->u.afb.energy = xml_getFloat(node);
|
||||
} while((node = node->next));
|
||||
do {
|
||||
if(xml_isNode(node, "thrust_perc"))
|
||||
tmp->u.afb.thrust_perc = 1. + xml_getFloat(node)/100.;
|
||||
else if(xml_isNode(node, "thrust_abs"))
|
||||
tmp->u.afb.thrust_abs = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "speed_perc"))
|
||||
tmp->u.afb.speed_perc = 1. + xml_getFloat(node)/100.;
|
||||
else if(xml_isNode(node, "speed_abs"))
|
||||
tmp->u.afb.speed_abs = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "energy"))
|
||||
tmp->u.afb.energy = xml_getFloat(node);
|
||||
} while((node = node->next));
|
||||
}
|
||||
|
||||
// Parse and return Outfits from parent node.
|
||||
@ -361,7 +361,7 @@ static Outfit* outfit_parse(const xmlNodePtr parent) {
|
||||
Outfit* tmp = CALLOC_L(Outfit);
|
||||
xmlNodePtr cur, node;
|
||||
char* prop;
|
||||
char str[PATH_MAX] = "\0";
|
||||
char str[PATH_MAX] = "\0";
|
||||
|
||||
tmp->name = xml_nodeProp(parent, "name"); // Already malloced.
|
||||
if(tmp->name == NULL) WARN("Outfit in "OUTFIT_DATA" has invalid or no name");
|
||||
@ -375,14 +375,14 @@ static Outfit* outfit_parse(const xmlNodePtr parent) {
|
||||
if(xml_isNode(cur, "max")) tmp->max = xml_getInt(cur);
|
||||
else if(xml_isNode(cur, "tech")) tmp->tech = xml_getInt(cur);
|
||||
else if(xml_isNode(cur, "mass")) tmp->mass = xml_getInt(cur);
|
||||
else if(xml_isNode(cur, "price")) tmp->price = xml_getInt(cur);
|
||||
else if(xml_isNode(cur, "description"))
|
||||
tmp->description = strdup(xml_get(cur));
|
||||
else if(xml_isNode(cur, "gfx_store")) {
|
||||
snprintf(str, strlen(xml_get(cur))+sizeof(OUTFIT_GFX)+10,
|
||||
OUTFIT_GFX"store/%s.png", xml_get(cur));
|
||||
tmp->gfx_store = gl_newImage(str);
|
||||
}
|
||||
else if(xml_isNode(cur, "price")) tmp->price = xml_getInt(cur);
|
||||
else if(xml_isNode(cur, "description"))
|
||||
tmp->description = strdup(xml_get(cur));
|
||||
else if(xml_isNode(cur, "gfx_store")) {
|
||||
snprintf(str, strlen(xml_get(cur))+sizeof(OUTFIT_GFX)+10,
|
||||
OUTFIT_GFX"store/%s.png", xml_get(cur));
|
||||
tmp->gfx_store = gl_newImage(str);
|
||||
}
|
||||
} while((cur = cur->next));
|
||||
}
|
||||
else if(xml_isNode(node, "specific")) {
|
||||
@ -409,23 +409,23 @@ static Outfit* outfit_parse(const xmlNodePtr parent) {
|
||||
outfit_parseSLauncher(tmp, node);
|
||||
else if(outfit_isAmmo(tmp))
|
||||
outfit_parseSAmmo(tmp, node);
|
||||
else if(outfit_isTurret(tmp))
|
||||
outfit_parseSWeapon(tmp, node);
|
||||
else if(outfit_isMod(tmp))
|
||||
outfit_parseSMod(tmp, node);
|
||||
else if(outfit_isAfterburner(tmp))
|
||||
outfit_parseSAfterburner(tmp, node);
|
||||
else if(outfit_isTurret(tmp))
|
||||
outfit_parseSWeapon(tmp, node);
|
||||
else if(outfit_isMod(tmp))
|
||||
outfit_parseSMod(tmp, node);
|
||||
else if(outfit_isAfterburner(tmp))
|
||||
outfit_parseSAfterburner(tmp, node);
|
||||
}
|
||||
} while((node = node->next));
|
||||
#define MELEMENT(o,s) if(o) WARN("Outfit '%s' missing '"s"' element", tmp->name)
|
||||
MELEMENT(tmp->name==NULL, "name");
|
||||
MELEMENT(tmp->name==NULL, "name");
|
||||
MELEMENT(tmp->max==0, "max");
|
||||
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->type==0, "type");
|
||||
MELEMENT(tmp->price==0, "price");
|
||||
MELEMENT(tmp->description==NULL, "description");
|
||||
MELEMENT(tmp->price==0, "price");
|
||||
MELEMENT(tmp->description==NULL, "description");
|
||||
#undef MELEMENT
|
||||
|
||||
return tmp;
|
||||
@ -465,8 +465,8 @@ int outfit_load(void) {
|
||||
xmlFreeDoc(doc);
|
||||
free(buf);
|
||||
xmlCleanupParser();
|
||||
|
||||
DEBUG("Loaded %d outfit%s", outfits, (outfits==1) ? "" : "s");
|
||||
|
||||
DEBUG("Loaded %d outfit%s", outfits, (outfits==1) ? "" : "s");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -476,18 +476,18 @@ void outfit_free(void) {
|
||||
int i;
|
||||
for(i = 0; i < outfits; i++) {
|
||||
// Free graphics.
|
||||
if(outfit_gfx(&outfit_stack[i]))
|
||||
gl_freeTexture(outfit_gfx(&outfit_stack[i]));
|
||||
if(outfit_gfx(&outfit_stack[i]))
|
||||
gl_freeTexture(outfit_gfx(&outfit_stack[i]));
|
||||
|
||||
// Strings.
|
||||
// Strings.
|
||||
if(outfit_isLauncher(&outfit_stack[i]) && outfit_stack[i].u.lau.ammo)
|
||||
free(outfit_stack[i].u.lau.ammo);
|
||||
|
||||
if(outfit_stack[i].description)
|
||||
free(outfit_stack[i].description);
|
||||
if(outfit_stack[i].description)
|
||||
free(outfit_stack[i].description);
|
||||
|
||||
if(outfit_stack[i].gfx_store)
|
||||
gl_freeTexture(outfit_stack[i].gfx_store);
|
||||
if(outfit_stack[i].gfx_store)
|
||||
gl_freeTexture(outfit_stack[i].gfx_store);
|
||||
|
||||
free(outfit_stack[i].name);
|
||||
}
|
||||
|
72
src/outfit.h
72
src/outfit.h
@ -21,10 +21,10 @@ typedef enum OutfitType_ {
|
||||
OUTFIT_TYPE_MISSILE_SWARM_AMMO = 10,
|
||||
OUTFIT_TYPE_MISSILE_SWARM_SMART = 11,
|
||||
OUTFIT_TYPE_MISSILE_SWARM_SMART_AMMO = 12,
|
||||
OUTFIT_TYPE_TURRET_BOLT = 13,
|
||||
OUTFIT_TYPE_TURRET_BEAM = 14,
|
||||
OUTFIT_TYPE_MODIFICATION = 15,
|
||||
OUTFIT_TYPE_AFTERBURNER = 16
|
||||
OUTFIT_TYPE_TURRET_BOLT = 13,
|
||||
OUTFIT_TYPE_TURRET_BEAM = 14,
|
||||
OUTFIT_TYPE_MODIFICATION = 15,
|
||||
OUTFIT_TYPE_AFTERBURNER = 16
|
||||
} OutfitType;
|
||||
|
||||
// An outfit depends a lot on the type.
|
||||
@ -36,14 +36,14 @@ typedef struct Outfit_ {
|
||||
int tech;
|
||||
int mass;
|
||||
|
||||
// Store stuff.
|
||||
unsigned int price;
|
||||
char* description;
|
||||
// Store stuff.
|
||||
unsigned int price;
|
||||
char* description;
|
||||
|
||||
glTexture* gfx_store; // Store graphic.
|
||||
|
||||
int properties; // Properties stored bitwise.
|
||||
|
||||
|
||||
// Type dependant.
|
||||
OutfitType type;
|
||||
union {
|
||||
@ -52,50 +52,50 @@ typedef struct Outfit_ {
|
||||
double speed; // Speed of shot. (not applicable to beam.
|
||||
double range;
|
||||
double accuracy; // Desviation accuracy.
|
||||
double energy; // Energy usage.
|
||||
double energy; // Energy usage.
|
||||
double damage_armour, damage_shield; // Damage.
|
||||
|
||||
glTexture* gfx_space;
|
||||
ALuint sound; // Sound to play.
|
||||
int spfx; // Special effect on hit.
|
||||
ALuint sound; // Sound to play.
|
||||
int spfx; // Special effect on hit.
|
||||
} blt;
|
||||
struct { // Beam.
|
||||
double range; // Distance it travels.
|
||||
glColour colour; // Beam colour.
|
||||
double energy; // Energy drained.
|
||||
double damage_armour, damage_shield; // Damage.
|
||||
} bem;
|
||||
struct { // Beam.
|
||||
double range; // Distance it travels.
|
||||
glColour colour; // Beam colour.
|
||||
double energy; // Energy drained.
|
||||
double damage_armour, damage_shield; // Damage.
|
||||
} bem;
|
||||
struct { // Launcher.
|
||||
unsigned int delay; // Delay between shots.
|
||||
char* ammo;
|
||||
} lau;
|
||||
struct { // Ammo.
|
||||
unsigned int duration; // Duration.
|
||||
double speed; // Max speed.
|
||||
double speed; // Max speed.
|
||||
double turn; // Turn vel.
|
||||
double thrust; // Acceleration.
|
||||
double energy; // Energy usage.
|
||||
double energy; // Energy usage.
|
||||
double damage_armour, damage_shield; // Damage.
|
||||
|
||||
glTexture* gfx_space;
|
||||
ALuint sound; // Sound to play.
|
||||
int spfx; // Special effect on hit.
|
||||
unsigned int lockon; // Time taken to lock on the target.
|
||||
glTexture* gfx_space;
|
||||
ALuint sound; // Sound to play.
|
||||
int spfx; // Special effect on hit.
|
||||
unsigned int lockon; // Time taken to lock on the target.
|
||||
} amm;
|
||||
struct { // Modification.
|
||||
// Movement.
|
||||
double thrust, turn, speed;
|
||||
struct { // Modification.
|
||||
// Movement.
|
||||
double thrust, turn, speed;
|
||||
|
||||
// Health.
|
||||
double armour, armour_regen;
|
||||
double shield, shield_regen;
|
||||
double energy, energy_regen;
|
||||
} mod;
|
||||
struct { // Afterburner.
|
||||
double thrust_perc, thrust_abs; // Percent and absolute thrust bonus.
|
||||
double speed_perc, speed_abs; // Percent and absolute speed bonus.
|
||||
double energy; // Energy used while active.
|
||||
} afb;
|
||||
// Health.
|
||||
double armour, armour_regen;
|
||||
double shield, shield_regen;
|
||||
double energy, energy_regen;
|
||||
} mod;
|
||||
struct { // Afterburner.
|
||||
double thrust_perc, thrust_abs; // Percent and absolute thrust bonus.
|
||||
double speed_perc, speed_abs; // Percent and absolute speed bonus.
|
||||
double energy; // Energy used while active.
|
||||
} afb;
|
||||
} u;
|
||||
} Outfit;
|
||||
|
||||
|
198
src/pack.c
198
src/pack.c
@ -52,25 +52,25 @@ static off_t getfilesize(const char* filename) {
|
||||
ERR("Unable to get filesize of %s", filename);
|
||||
return 0;
|
||||
#else
|
||||
long size;
|
||||
FILE* fp = fopen(filename, "rb");
|
||||
if(fp == NULL) return 0;
|
||||
long size;
|
||||
FILE* fp = fopen(filename, "rb");
|
||||
if(fp == NULL) return 0;
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
size = ftell(fp);
|
||||
fseek(fp, 0, SEEK_END);
|
||||
size = ftell(fp);
|
||||
|
||||
fclose(fp);
|
||||
fclose(fp);
|
||||
|
||||
return size;
|
||||
return size;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Return true if filename is a Packfile.
|
||||
int pack_check(const char* filename) {
|
||||
int ret;
|
||||
char* buf;
|
||||
int ret;
|
||||
char* buf;
|
||||
|
||||
buf = malloc(sizeof(magic));
|
||||
buf = malloc(sizeof(magic));
|
||||
|
||||
#ifdef _POSIX_SOURCE
|
||||
int fd = open(filename, O_RDONLY);
|
||||
@ -84,24 +84,24 @@ int pack_check(const char* filename) {
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
ret = (memcmp(buf, &magic, sizeof(magic))==0) ? 0 : 1;
|
||||
close(fd);
|
||||
ret = (memcmp(buf, &magic, sizeof(magic))==0) ? 0 : 1;
|
||||
close(fd);
|
||||
#else
|
||||
FILE* file = fopen(filename, "rb");
|
||||
if(file == NULL) {
|
||||
ERR("Error opening '%s': %s", filename, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
FILE* file = fopen(filename, "rb");
|
||||
if(file == NULL) {
|
||||
ERR("Error opening '%s': %s", filename, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf = malloc(sizeof(magic));
|
||||
if(fread(buf, 1, sizeof(magic), file) != sizeof(magic)) {
|
||||
ERR("Error reading magic number: %s", strerror(errno));
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
buf = malloc(sizeof(magic));
|
||||
if(fread(buf, 1, sizeof(magic), file) != sizeof(magic)) {
|
||||
ERR("Error reading magic number: %s", strerror(errno));
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = (memcmp(buf, &magic, sizeof(magic))==0) ? 0 : 1;
|
||||
fclose(file);
|
||||
ret = (memcmp(buf, &magic, sizeof(magic))==0) ? 0 : 1;
|
||||
fclose(file);
|
||||
#endif
|
||||
|
||||
free(buf);
|
||||
@ -111,8 +111,8 @@ int pack_check(const char* filename) {
|
||||
// Pack nfiles, infiles into outfile.
|
||||
#ifdef _POSIX_SOURCE
|
||||
#define WRITE(b,n) if(write(outfd, b, n)==-1) { \
|
||||
ERR("Error writing to file: %s", strerror(errno)); \
|
||||
free(buf); return -1; }
|
||||
ERR("Error writing to file: %s", strerror(errno)); \
|
||||
free(buf); return -1; }
|
||||
#else
|
||||
#define WRITE(b,n) if(fwrite(b, 1, n, outf)==0) { \
|
||||
ERR("Error writing to file: %s", strerror(errno)); \
|
||||
@ -122,9 +122,9 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles)
|
||||
void* buf;
|
||||
#ifdef _POSIX_SOURCE
|
||||
struct stat file;
|
||||
int outfd, infd;
|
||||
int outfd, infd;
|
||||
#else
|
||||
FILE* outf, *inf;
|
||||
FILE* outf, *inf;
|
||||
#endif
|
||||
uint32_t i;
|
||||
int namesize;
|
||||
@ -137,22 +137,22 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles)
|
||||
#ifdef _POSIX_SOURCE
|
||||
if(stat(infiles[i], &file)) {
|
||||
#else
|
||||
if(getfilesize(infiles[i]) == 0) {
|
||||
if(getfilesize(infiles[i]) == 0) {
|
||||
#endif
|
||||
ERR("File %s does not exist", infiles[i]);
|
||||
return -1;
|
||||
}
|
||||
if(strlen(infiles[i]) > MAX_FILENAME) {
|
||||
ERR("filename '%s' is too long, should be only %d characters", infiles[i],
|
||||
MAX_FILENAME);
|
||||
MAX_FILENAME);
|
||||
return -1;
|
||||
}
|
||||
namesize += strlen(infiles[i]);
|
||||
}
|
||||
|
||||
indexsize = (sizeof(magic) + 4 + // Magic number and number of files.
|
||||
namesize + // Total length of file names.
|
||||
(1+4)*nfiles); // File size and extra end of string char '\0'.
|
||||
namesize + // Total length of file names.
|
||||
(1+4)*nfiles); // File size and extra end of string char '\0'.
|
||||
DEBUG("Index size is %d", indexsize);
|
||||
|
||||
// Create the output file.
|
||||
@ -160,8 +160,8 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles)
|
||||
outfd = creat(outfile, PERMS);
|
||||
if(outfd == -1) {
|
||||
#else
|
||||
outf = fopen(outfile, "wb");
|
||||
if(outf == NULL) {
|
||||
outf = fopen(outfile, "wb");
|
||||
if(outf == NULL) {
|
||||
#endif
|
||||
ERR("Unable to open %s for writing", outfile);
|
||||
return -1;
|
||||
@ -169,7 +169,7 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles)
|
||||
|
||||
// Index!
|
||||
buf = malloc(BLOCKSIZE);
|
||||
|
||||
|
||||
// Magic number.
|
||||
WRITE(&magic, sizeof(magic));
|
||||
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);
|
||||
md5_init(&md5);
|
||||
#ifdef _POSIX_SOURCE
|
||||
infd = open(infiles[i], O_RDONLY);
|
||||
infd = open(infiles[i], O_RDONLY);
|
||||
while((bytes = read(infd, buf, BLOCKSIZE))) {
|
||||
#else
|
||||
inf = fopen(infiles[i], "rb");
|
||||
while((bytes = fread(buf, 1, BLOCKSIZE, inf))) {
|
||||
inf = fopen(infiles[i], "rb");
|
||||
while((bytes = fread(buf, 1, BLOCKSIZE, inf))) {
|
||||
#endif
|
||||
WRITE(buf, bytes); // Data.
|
||||
WRITE(buf, bytes); // Data.
|
||||
md5_append(&md5, buf, bytes);
|
||||
}
|
||||
md5_finish(&md5, md5val);
|
||||
@ -209,7 +209,7 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles)
|
||||
#ifdef _POSIX_SOURCE
|
||||
close(infd);
|
||||
#else
|
||||
fclose(inf);
|
||||
fclose(inf);
|
||||
#endif
|
||||
DEBUG("Wrote file '%s'", infiles[i]);
|
||||
}
|
||||
@ -218,12 +218,12 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles)
|
||||
#ifdef _POSIX_SOURCE
|
||||
close(outfd);
|
||||
#else
|
||||
fclose(outf);
|
||||
fclose(outf);
|
||||
#endif
|
||||
free(buf);
|
||||
|
||||
DEBUG("Packfile success\n\t%d files\n\t%d bytes",
|
||||
nfiles, (int)getfilesize(outfile));
|
||||
nfiles, (int)getfilesize(outfile));
|
||||
return 0;
|
||||
}
|
||||
#undef WRITE
|
||||
@ -235,8 +235,8 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles)
|
||||
free(buf); return -1; }
|
||||
#else
|
||||
#define READ(b,n) if(fread((b), 1, (n), file->fp)!=(n)) { \
|
||||
ERR("Fewer bytes read then expected"); \
|
||||
free(buf); return -1; }
|
||||
ERR("Fewer bytes read then expected"); \
|
||||
free(buf); return -1; }
|
||||
#endif
|
||||
int pack_open(Packfile* file, const char* packfile, const char* filename) {
|
||||
int j;
|
||||
@ -249,8 +249,8 @@ int pack_open(Packfile* file, const char* packfile, const char* filename) {
|
||||
file->fd = open(packfile, O_RDONLY);
|
||||
if(file->fd == -1) {
|
||||
#else
|
||||
file->fp = fopen(packfile, "rb");
|
||||
if(file->fp == NULL) {
|
||||
file->fp = fopen(packfile, "rb");
|
||||
if(file->fp == NULL) {
|
||||
#endif
|
||||
ERR("Error opening %s: %s", filename, strerror(errno));
|
||||
return -1;
|
||||
@ -279,23 +279,23 @@ int pack_open(Packfile* file, const char* packfile, const char* filename) {
|
||||
#ifdef _POSIX_SOURCE
|
||||
lseek(file->fd, 4, SEEK_CUR); // Ignore the file location.
|
||||
#else
|
||||
fseek(file->fp, 4, SEEK_CUR);
|
||||
fseek(file->fp, 4, SEEK_CUR);
|
||||
#endif
|
||||
}
|
||||
free(buf);
|
||||
|
||||
|
||||
if(file->start) {
|
||||
// Go to the beginning of the file.
|
||||
#ifdef _POSIX_SOURCE
|
||||
if((uint32_t)lseek(file->fd, file->start, SEEK_SET) != file->start) {
|
||||
#else
|
||||
fseek(file->fp, file->start, SEEK_SET);
|
||||
if(errno) {
|
||||
fseek(file->fp, file->start, SEEK_SET);
|
||||
if(errno) {
|
||||
#endif
|
||||
ERR("Failure to seek to file start: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
READ(&file->end, 4);
|
||||
READ(&file->end, 4);
|
||||
DEBUG("\t%d bytes", file->end);
|
||||
file->pos = file->start;
|
||||
file->end += file->start;
|
||||
@ -310,7 +310,7 @@ int pack_open(Packfile* file, const char* packfile, const char* filename) {
|
||||
// Read count bytes from file and put them into buf.
|
||||
ssize_t pack_read(Packfile* file, void* buf, size_t count) {
|
||||
if(file->pos + count > file->end)
|
||||
count = file->end - file->pos; // Can't go past the end!
|
||||
count = file->end - file->pos; // Can't go past the end!
|
||||
if(count == 0) return 0;
|
||||
|
||||
int bytes;
|
||||
@ -318,7 +318,7 @@ ssize_t pack_read(Packfile* file, void* buf, size_t count) {
|
||||
#ifdef _POSIX_SOURCE
|
||||
if((bytes = read(file->fd, buf, count)) == -1) {
|
||||
#else
|
||||
if((bytes = fread(buf, 1, count, file->fp)) == -1) {
|
||||
if((bytes = fread(buf, 1, count, file->fp)) == -1) {
|
||||
#endif
|
||||
ERR("Error while reading file: %s", strerror(errno));
|
||||
return -1;
|
||||
@ -330,52 +330,52 @@ ssize_t pack_read(Packfile* file, void* buf, size_t count) {
|
||||
|
||||
// Seek in the packfile.
|
||||
off_t pack_seek(Packfile* file, off_t offset, int whence) {
|
||||
DEBUG("Attempting to seek offset: %d, whence: %d", offset, whence);
|
||||
off_t ret;
|
||||
switch(whence) {
|
||||
DEBUG("Attempting to seek offset: %d, whence: %d", offset, whence);
|
||||
off_t ret;
|
||||
switch(whence) {
|
||||
#ifdef _POSIX_SOURCE
|
||||
case SEEK_SET:
|
||||
if((file->start + offset) > file->end) return -1;
|
||||
ret = lseek(file->fd, file->start + offset, SEEK_SET);
|
||||
if(ret != ((off_t)file->start + offset)) return -1;
|
||||
break;
|
||||
if((file->start + offset) > file->end) return -1;
|
||||
ret = lseek(file->fd, file->start + offset, SEEK_SET);
|
||||
if(ret != ((off_t)file->start + offset)) return -1;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
if((file->start + offset) > file->end) return -1;
|
||||
ret = lseek(file->fd, file->pos + offset, SEEK_SET);
|
||||
if(ret != ((off_t)file->pos + offset)) return -1;
|
||||
break;
|
||||
if((file->start + offset) > file->end) return -1;
|
||||
ret = lseek(file->fd, file->pos + offset, SEEK_SET);
|
||||
if(ret != ((off_t)file->pos + offset)) return -1;
|
||||
break;
|
||||
case SEEK_END:
|
||||
if((file->end - offset) < file->start) return -1;
|
||||
ret = lseek(file->fd, file->end - offset - 1, SEEK_SET);
|
||||
if(ret != ((off_t)file->end - offset)) return -1;
|
||||
break;
|
||||
if((file->end - offset) < file->start) return -1;
|
||||
ret = lseek(file->fd, file->end - offset - 1, SEEK_SET);
|
||||
if(ret != ((off_t)file->end - offset)) return -1;
|
||||
break;
|
||||
#else
|
||||
case SEEK_SET:
|
||||
if((file->start + offset) > file->end) return -1;
|
||||
ret = fseek(file->fd, file->start + offset, SEEK_SET);
|
||||
if(ret != (file->start + offset)) return -1;
|
||||
break;
|
||||
if((file->start + offset) > file->end) return -1;
|
||||
ret = fseek(file->fd, file->start + offset, SEEK_SET);
|
||||
if(ret != (file->start + offset)) return -1;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
if((file->start + offset) > file->end) return -1;
|
||||
ret = flseek(file->fd, file->pos + offset, SEEK_SET);
|
||||
if(ret != (file->pos + offset)) return -1;
|
||||
break;
|
||||
if((file->start + offset) > file->end) return -1;
|
||||
ret = flseek(file->fd, file->pos + offset, SEEK_SET);
|
||||
if(ret != (file->pos + offset)) return -1;
|
||||
break;
|
||||
case SEEK_END:
|
||||
if((file->end - offset) < file->start) return -1;
|
||||
ret = flseek(file->fd, file->end - offset - 1, SEEK_SET);
|
||||
if(ret != (file->end - offset)) return -1;
|
||||
break;
|
||||
if((file->end - offset) < file->start) return -1;
|
||||
ret = flseek(file->fd, file->end - offset - 1, SEEK_SET);
|
||||
if(ret != (file->end - offset)) return -1;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ERR("Whence is not one of SEEK_SET, SEEK_CUR or SEEK_END");
|
||||
return -1;
|
||||
}
|
||||
return ret - file->start;
|
||||
ERR("Whence is not one of SEEK_SET, SEEK_CUR or SEEK_END");
|
||||
return -1;
|
||||
}
|
||||
return ret - file->start;
|
||||
}
|
||||
|
||||
// Return current pointer position.
|
||||
long pack_tell(Packfile* file) {
|
||||
return file->pos - file->start;
|
||||
return file->pos - file->start;
|
||||
}
|
||||
|
||||
// Loads an entire file into memory and returns a pointer to it.
|
||||
@ -398,7 +398,7 @@ void* pack_readfile(const char* packfile, const char* filename, uint32_t* filesi
|
||||
buf = malloc(size+1);
|
||||
if((bytes = pack_read(file, buf, size)) != size) {
|
||||
ERR("Reading '%s' from packfile '%s'. Expected %d bytes got %d bytes",
|
||||
filename, packfile, size, bytes);
|
||||
filename, packfile, size, bytes);
|
||||
free(buf);
|
||||
free(file);
|
||||
return NULL;
|
||||
@ -416,7 +416,7 @@ void* pack_readfile(const char* packfile, const char* filename, uint32_t* filesi
|
||||
#ifdef _POSIX_SOURCE
|
||||
if((bytes = read(file->fd, md5fd, 16)) == -1)
|
||||
#else
|
||||
if((bytes = fread(md5fd, 1, 16, file->fp)) == -1)
|
||||
if((bytes = fread(md5fd, 1, 16, file->fp)) == -1)
|
||||
#endif
|
||||
WARN("Failure to read MD5, continuing anyway..");
|
||||
else if(memcmp(md5val, md5fd, 16))
|
||||
@ -443,18 +443,18 @@ void* pack_readfile(const char* packfile, const char* filename, uint32_t* filesi
|
||||
// On error if filenames is (char**)-1.
|
||||
#ifdef _POSIX_SOURCE
|
||||
#define READ(b,n) if(read(fd, (b), (n))!=(n)) { \
|
||||
ERR("Too few bytes read"); \
|
||||
return NULL; }
|
||||
ERR("Too few bytes read"); \
|
||||
return NULL; }
|
||||
#else
|
||||
#define READ(b,n) if(fread((b), 1, (n), fp) != (n)) { \
|
||||
ERR("Too few bytes read"); \
|
||||
return NULL; }
|
||||
ERR("Too few bytes read"); \
|
||||
return NULL; }
|
||||
#endif
|
||||
char** pack_listfiles(const char* packfile, uint32_t* nfiles) {
|
||||
#ifdef _POSIX_SOURCE
|
||||
int fd;
|
||||
int fd;
|
||||
#else
|
||||
FILE* fp;
|
||||
FILE* fp;
|
||||
#endif
|
||||
int j;
|
||||
uint32_t i;
|
||||
@ -467,8 +467,8 @@ char** pack_listfiles(const char* packfile, uint32_t* nfiles) {
|
||||
fd = open(packfile, O_RDONLY);
|
||||
if(fd == -1) {
|
||||
#else
|
||||
fp = fopen(packfile, "rb");
|
||||
if(fp == NULL) {
|
||||
fp = fopen(packfile, "rb");
|
||||
if(fp == NULL) {
|
||||
#endif
|
||||
ERR("opening %s: %s", packfile, strerror(errno));
|
||||
return NULL;
|
||||
@ -495,7 +495,7 @@ char** pack_listfiles(const char* packfile, uint32_t* nfiles) {
|
||||
#ifdef _POSIX_SOURCE
|
||||
close(fd);
|
||||
#else
|
||||
fclose(fp);
|
||||
fclose(fp);
|
||||
#endif
|
||||
|
||||
return filenames;
|
||||
@ -504,11 +504,11 @@ char** pack_listfiles(const char* packfile, uint32_t* nfiles) {
|
||||
|
||||
// Close the packfile.
|
||||
int pack_close(Packfile* file) {
|
||||
int i;
|
||||
int i;
|
||||
#ifdef _POSIX_SOURCE
|
||||
i = close(file->fd);
|
||||
#else
|
||||
i = fclose(file->fp);
|
||||
i = fclose(file->fp);
|
||||
#endif
|
||||
return (i) ? -1 : 0;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ typedef struct Packfile_ {
|
||||
#ifdef _POSIX_SOURCE
|
||||
int fd; // File descriptor.
|
||||
#else
|
||||
FILE* fp;
|
||||
FILE* fp;
|
||||
#endif
|
||||
uint32_t pos; // position.
|
||||
uint32_t start, end; // file limits.
|
||||
|
28
src/pause.c
28
src/pause.c
@ -26,8 +26,8 @@ void pause(void) {
|
||||
|
||||
pilots_pause();
|
||||
weapons_pause();
|
||||
spfx_pause();
|
||||
spawn_timer -= SDL_GetTicks();
|
||||
spfx_pause();
|
||||
spawn_timer -= SDL_GetTicks();
|
||||
|
||||
paused = 1; // We should unpause it.
|
||||
}
|
||||
@ -37,17 +37,17 @@ void unpause(void) {
|
||||
|
||||
pilots_unpause();
|
||||
weapons_unpause();
|
||||
spfx_unpause();
|
||||
spawn_timer += SDL_GetTicks();
|
||||
spfx_unpause();
|
||||
spawn_timer += SDL_GetTicks();
|
||||
|
||||
paused = 0;
|
||||
}
|
||||
|
||||
// Set the timers back.
|
||||
void pause_delay(unsigned int delay) {
|
||||
pilots_delay(delay);
|
||||
weapons_delay(delay);
|
||||
spfx_delay(delay);
|
||||
pilots_delay(delay);
|
||||
weapons_delay(delay);
|
||||
spfx_delay(delay);
|
||||
}
|
||||
|
||||
static void pilots_pause(void) {
|
||||
@ -75,13 +75,13 @@ static void pilots_unpause(void) {
|
||||
}
|
||||
|
||||
static void pilots_delay(unsigned int delay) {
|
||||
int i, j;
|
||||
for(i = 0; i < pilots; i++) {
|
||||
pilot_stack[i]->ptimer += delay;
|
||||
int i, j;
|
||||
for(i = 0; i < pilots; i++) {
|
||||
pilot_stack[i]->ptimer += delay;
|
||||
|
||||
pilot_stack[i]->tcontrol += delay;
|
||||
for(j = 0; j < MAX_AI_TIMERS; j++)
|
||||
pilot_stack[i]->timer[j] += delay;
|
||||
}
|
||||
pilot_stack[i]->tcontrol += delay;
|
||||
for(j = 0; j < MAX_AI_TIMERS; j++)
|
||||
pilot_stack[i]->timer[j] += delay;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,9 +15,9 @@ double angle_diff(const double ref, double a) {
|
||||
}
|
||||
|
||||
void limit_speed(Vec2* vel, const double speed, const double dt) {
|
||||
double vmod = VMOD(*vel);
|
||||
if(vmod > speed) // Should not go faster.
|
||||
vect_pset(vel, (vmod-speed)*(1.-dt*3.) + speed, VANGLE(*vel));
|
||||
double vmod = VMOD(*vel);
|
||||
if(vmod > speed) // Should not go faster.
|
||||
vect_pset(vel, (vmod-speed)*(1.-dt*3.) + speed, VANGLE(*vel));
|
||||
}
|
||||
|
||||
// ================
|
||||
@ -92,7 +92,7 @@ static void simple_update(Solid* obj, const double dt) {
|
||||
obj->dir += M_PI/360.*obj->dir_vel*dt;
|
||||
if(obj->dir > 2*M_PI) obj->dir -= 2*M_PI;
|
||||
if(obj->dir < 0.) obj->dir += 2*M_PI;
|
||||
|
||||
|
||||
double px, py, vx, vy;
|
||||
px = VX(obj->pos);
|
||||
py = VY(obj->pos);
|
||||
@ -190,7 +190,7 @@ static void rk4_update(Solid* obj, const double dt) {
|
||||
|
||||
// Initialize a new solid.
|
||||
void solid_init(Solid* dest, const double mass, const double dir,
|
||||
const Vec2* pos, const Vec2* vel) {
|
||||
const Vec2* pos, const Vec2* vel) {
|
||||
dest->mass = mass;
|
||||
|
||||
dest->dir_vel = 0.;
|
||||
@ -202,7 +202,7 @@ void solid_init(Solid* dest, const double mass, const double dir,
|
||||
|
||||
if(vel == NULL) vectnull(&dest->vel);
|
||||
else vectcpy(&dest->vel, vel);
|
||||
|
||||
|
||||
if(pos == NULL) vectnull(&dest->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.
|
||||
Solid* solid_create(const double mass, const double dir,
|
||||
const Vec2* pos, const Vec2* vel) {
|
||||
const Vec2* pos, const Vec2* vel) {
|
||||
Solid* dyn = MALLOC_L(Solid);
|
||||
if(dyn == NULL) ERR("Out of memory");
|
||||
solid_init(dyn, mass, dir, pos, vel);
|
||||
|
@ -42,9 +42,9 @@ typedef struct Solid_ {
|
||||
} Solid;
|
||||
|
||||
// Solid manipulation.
|
||||
void solid_init(Solid* dest, const double mass, const double dir,
|
||||
const Vec2* pos, const Vec2* vel);
|
||||
Solid* solid_create(const double mass, const double dir,
|
||||
const Vec2* pos, const Vec2* vel);
|
||||
void solid_init(Solid* dest, const double mass, const double dir,
|
||||
const Vec2* pos, const Vec2* vel);
|
||||
Solid* solid_create(const double mass, const double dir,
|
||||
const Vec2* pos, const Vec2* vel);
|
||||
void solid_free(Solid* src);
|
||||
|
||||
|
656
src/pilot.c
656
src/pilot.c
@ -140,14 +140,14 @@ double pilot_face(Pilot* p, const float dir) {
|
||||
|
||||
// Return quantity of a pilot outfit.
|
||||
static int pilot_oquantity(Pilot* p, PilotOutfit* w) {
|
||||
return (outfit_isAmmo(w->outfit) && p->secondary) ?
|
||||
p->secondary->quantity : w->quantity;
|
||||
return (outfit_isAmmo(w->outfit) && p->secondary) ?
|
||||
p->secondary->quantity : w->quantity;
|
||||
}
|
||||
|
||||
// Mkay, this is how we shoot. Listen up.
|
||||
void pilot_shoot(Pilot* p, const unsigned int target, const int secondary) {
|
||||
int i;
|
||||
|
||||
|
||||
if(!p->outfits) return; // No outfits.
|
||||
|
||||
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) {
|
||||
int quantity, delay;
|
||||
int quantity, delay;
|
||||
// WElll... Trying to shoot when you have no ammo?? FUUU
|
||||
quantity = pilot_oquantity(p,w);
|
||||
delay = outfit_delay(w->outfit);
|
||||
quantity = pilot_oquantity(p,w);
|
||||
delay = outfit_delay(w->outfit);
|
||||
|
||||
// Check to see if weapon is ready.
|
||||
if((SDL_GetTicks() - w->timer) < (unsigned int)(delay/quantity)) return;
|
||||
@ -174,32 +174,32 @@ static void pilot_shootWeapon(Pilot* p, PilotOutfit* w, const unsigned int t) {
|
||||
if(outfit_isWeapon(w->outfit) || (outfit_isTurret(w->outfit))) {
|
||||
// Different weapons.
|
||||
switch(w->outfit->type) {
|
||||
case OUTFIT_TYPE_TURRET_BOLT:
|
||||
case OUTFIT_TYPE_BOLT:
|
||||
// Enough energy?
|
||||
if(outfit_energy(w->outfit) > p->energy) return;
|
||||
case OUTFIT_TYPE_TURRET_BOLT:
|
||||
case OUTFIT_TYPE_BOLT:
|
||||
// Enough energy?
|
||||
if(outfit_energy(w->outfit) > p->energy) return;
|
||||
|
||||
p->energy -= outfit_energy(w->outfit);
|
||||
weapon_add(w->outfit, p->solid->dir, &p->solid->pos,
|
||||
&p->solid->vel, p->id, t);
|
||||
p->energy -= outfit_energy(w->outfit);
|
||||
weapon_add(w->outfit, p->solid->dir, &p->solid->pos,
|
||||
&p->solid->vel, p->id, t);
|
||||
|
||||
// Can't shoot for a while.
|
||||
w->timer = SDL_GetTicks();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
// Can't shoot for a while.
|
||||
w->timer = SDL_GetTicks();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Missile launchers.
|
||||
// Must be secondary weapon, Shooter can't be the target.
|
||||
else if(outfit_isLauncher(w->outfit) && (w == p->secondary) && (p->id != t)) {
|
||||
if(p->ammo && (p->ammo->quantity > 0)) {
|
||||
// Enough energy?
|
||||
if(outfit_energy(w->outfit) > p->energy) return;
|
||||
// Enough energy?
|
||||
if(outfit_energy(w->outfit) > p->energy) return;
|
||||
|
||||
p->energy -= outfit_energy(w->outfit);
|
||||
p->energy -= outfit_energy(w->outfit);
|
||||
weapon_add(p->ammo->outfit, p->solid->dir, &p->solid->pos,
|
||||
&p->solid->vel, p->id, t);
|
||||
&p->solid->vel, p->id, t);
|
||||
|
||||
w->timer = SDL_GetTicks(); // Can't shoot for a while.
|
||||
p->ammo->quantity -= 1; // There's no getting this one back.
|
||||
@ -209,72 +209,72 @@ static void pilot_shootWeapon(Pilot* p, PilotOutfit* w, const unsigned int t) {
|
||||
|
||||
// Damage the pilot.
|
||||
void pilot_hit(Pilot* p, const Solid* w, const unsigned int shooter,
|
||||
const double damage_shield, const double damage_armour) {
|
||||
const double damage_shield, const double damage_armour) {
|
||||
|
||||
double dam_mod;
|
||||
double dam_mod;
|
||||
|
||||
if(p->shield - damage_shield > 0.) {
|
||||
p->shield -= damage_shield;
|
||||
dam_mod = damage_shield/p->shield_max;
|
||||
}
|
||||
dam_mod = damage_shield/p->shield_max;
|
||||
}
|
||||
else if(p->shield > 0.) {
|
||||
// Shields can take part of the blow.
|
||||
p->armour -= p->shield/damage_shield*damage_armour;
|
||||
p->shield = 0.;
|
||||
dam_mod = (damage_shield+damage_armour) / (p->shield_max + p->armour_max);
|
||||
dam_mod = (damage_shield+damage_armour) / (p->shield_max + p->armour_max);
|
||||
}
|
||||
else if(p->armour-damage_armour > 0.) {
|
||||
p->armour -= damage_armour;
|
||||
dam_mod = damage_armour/p->armour_max;
|
||||
}
|
||||
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);
|
||||
dam_mod = damage_armour/p->armour_max;
|
||||
}
|
||||
}
|
||||
|
||||
// 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.));
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// Knock back effect is dependent on both damage and mass of the weapon.
|
||||
// should probably turn it into a partial conservative collision..
|
||||
vect_cadd(&p->solid->vel,
|
||||
w->vel.x * (dam_mod/6. + w->mass/p->solid->mass/6.),
|
||||
w->vel.y * (dam_mod/6. + w->mass/p->solid->mass/6.));
|
||||
}
|
||||
|
||||
void pilot_dead(Pilot* p) {
|
||||
// Basically just set the timers..
|
||||
if(p->id == PLAYER_ID) player_dead();
|
||||
p->timer[0] = SDL_GetTicks(); // No need for AI anymore.
|
||||
p->ptimer = p->timer[0] + 1000 + (unsigned int)sqrt(10*p->armour_max*p->shield_max);
|
||||
p->timer[1] = p->timer[0]; // Explosion timer.
|
||||
pilot_setFlag(p, PILOT_DEAD);
|
||||
// Basically just set the timers..
|
||||
if(p->id == PLAYER_ID) player_dead();
|
||||
p->timer[0] = SDL_GetTicks(); // No need for AI anymore.
|
||||
p->ptimer = p->timer[0] + 1000 + (unsigned int)sqrt(10*p->armour_max*p->shield_max);
|
||||
p->timer[1] = p->timer[0]; // Explosion timer.
|
||||
pilot_setFlag(p, PILOT_DEAD);
|
||||
}
|
||||
|
||||
void pilot_setSecondary(Pilot* p, const char* secondary) {
|
||||
int i;
|
||||
int i;
|
||||
|
||||
if(secondary == NULL) {
|
||||
if(secondary == NULL) {
|
||||
p->secondary = NULL;
|
||||
p->ammo = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
for(i = 0; i < p->noutfits; i++) {
|
||||
if(strcmp(secondary, p->outfits[i].outfit->name)==0) {
|
||||
p->secondary = &p->outfits[i];;
|
||||
pilot_setAmmo(p);
|
||||
return;
|
||||
}
|
||||
}
|
||||
WARN("Attempted to set pilot '%s' secondary weapon to non-existing '%s'",
|
||||
p->name, secondary);
|
||||
p->secondary = NULL;
|
||||
p->ammo = NULL;
|
||||
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.
|
||||
@ -301,102 +301,102 @@ void pilot_setAmmo(Pilot* p) {
|
||||
// Render the pilot.
|
||||
void pilot_render(Pilot* p) {
|
||||
gl_blitSprite(p->ship->gfx_space,
|
||||
p->solid->pos.x, p->solid->pos.y,
|
||||
p->tsx, p->tsy, NULL);
|
||||
p->solid->pos.x, p->solid->pos.y,
|
||||
p->tsx, p->tsy, NULL);
|
||||
}
|
||||
|
||||
// Update the pilot.
|
||||
static void pilot_update(Pilot* pilot, const double dt) {
|
||||
unsigned int t, l;
|
||||
double a, px, py, vx, vy;
|
||||
unsigned int t, l;
|
||||
double a, px, py, vx, vy;
|
||||
|
||||
if(pilot_isFlag(pilot, PILOT_DEAD)) {
|
||||
t = SDL_GetTicks();
|
||||
if(pilot_isFlag(pilot, PILOT_DEAD)) {
|
||||
t = SDL_GetTicks();
|
||||
|
||||
if(t > pilot->ptimer) {
|
||||
if(pilot->id == PLAYER_ID)
|
||||
player_destroyed();
|
||||
pilot_setFlag(pilot, PILOT_DELETE); // It'll get deleted next frame.
|
||||
return;
|
||||
if(t > pilot->ptimer) {
|
||||
if(pilot->id == PLAYER_ID)
|
||||
player_destroyed();
|
||||
pilot_setFlag(pilot, PILOT_DELETE); // It'll get deleted next frame.
|
||||
return;
|
||||
}
|
||||
|
||||
if(!pilot_isFlag(pilot, PILOT_EXPLODED) && (t > pilot->ptimer - 200)) {
|
||||
spfx_add(spfx_get("ExpL"),
|
||||
VX(pilot->solid->pos), VY(pilot->solid->pos),
|
||||
VX(pilot->solid->vel), VY(pilot->solid->vel), SPFX_LAYER_BACK);
|
||||
pilot_setFlag(pilot, PILOT_EXPLODED);
|
||||
}
|
||||
else if(t > pilot->timer[1]) {
|
||||
pilot->timer[1] = t +
|
||||
(unsigned int)(100*(double)(pilot->ptimer - pilot->timer[1]) /
|
||||
(double)(pilot->ptimer - pilot->timer[0]));
|
||||
|
||||
// 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)) {
|
||||
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);
|
||||
|
||||
// Pupose fallthrough to get the movement similar to disabled.
|
||||
if(pilot != player && pilot->armour < PILOT_DISABLED_ARMOUR * pilot->armour_max) {
|
||||
// Pupose fallthrough to get the movement similar to disabled.
|
||||
if(pilot != player && pilot->armour < PILOT_DISABLED_ARMOUR * pilot->armour_max) {
|
||||
// We are disabled.
|
||||
pilot_setFlag(pilot, PILOT_DISABLED);
|
||||
// Come to a halt slowly.
|
||||
vect_pset(&pilot->solid->vel,
|
||||
VMOD(pilot->solid->vel) * (1. - dt*0.10), VANGLE(pilot->solid->vel));
|
||||
vect_pset(&pilot->solid->vel,
|
||||
VMOD(pilot->solid->vel) * (1. - dt*0.10), VANGLE(pilot->solid->vel));
|
||||
vectnull(&pilot->solid->force);
|
||||
pilot->solid->dir_vel = 0.; // Stop it from turning.
|
||||
|
||||
// Update the solid.
|
||||
pilot->solid->update(pilot->solid, dt);
|
||||
gl_getSpriteFromDir(&pilot->tsx, &pilot->tsy,
|
||||
pilot->ship->gfx_space, pilot->solid->dir);
|
||||
gl_getSpriteFromDir(&pilot->tsx, &pilot->tsy,
|
||||
pilot->ship->gfx_space, pilot->solid->dir);
|
||||
return;
|
||||
}
|
||||
// We are still alive.
|
||||
else if(pilot->armour < pilot->armour_max) {
|
||||
pilot->armour += pilot->armour_regen*dt;
|
||||
pilot->energy += pilot->energy_regen*dt;
|
||||
} else {
|
||||
pilot->energy += pilot->energy_regen*dt;
|
||||
} else {
|
||||
pilot->shield += pilot->shield_regen*dt;
|
||||
pilot->energy += pilot->energy_regen*dt;
|
||||
}
|
||||
pilot->energy += pilot->energy_regen*dt;
|
||||
}
|
||||
|
||||
if(pilot->armour > pilot->armour_max) pilot->armour = pilot->armour_max;
|
||||
if(pilot->shield > pilot->shield_max) pilot->shield = pilot->shield_max;
|
||||
if(pilot->energy > pilot->energy_max) pilot->energy = pilot->energy_max;
|
||||
if(pilot->energy > pilot->energy_max) pilot->energy = pilot->energy_max;
|
||||
|
||||
// Update the solid.
|
||||
(*pilot->solid->update)(pilot->solid, dt);
|
||||
gl_getSpriteFromDir(&pilot->tsx, &pilot->tsy,
|
||||
pilot->ship->gfx_space, pilot->solid->dir);
|
||||
|
||||
if(!pilot_isFlag(pilot, PILOT_HYPERSPACE)) { // Limit the speed.
|
||||
if(pilot_isFlag(pilot, PILOT_AFTERBURNER) && // Must have enough energy.
|
||||
(player->energy > pilot->afterburner->outfit->u.afb.energy * dt)) {
|
||||
limit_speed(&pilot->solid->vel,
|
||||
pilot->speed * pilot->afterburner->outfit->u.afb.speed_perc +
|
||||
pilot->afterburner->outfit->u.afb.speed_abs, dt);
|
||||
pilot->energy -= pilot->afterburner->outfit->u.afb.energy * dt;
|
||||
} else
|
||||
limit_speed(&pilot->solid->vel, pilot->speed, dt);
|
||||
}
|
||||
gl_getSpriteFromDir(&pilot->tsx, &pilot->tsy,
|
||||
pilot->ship->gfx_space, pilot->solid->dir);
|
||||
|
||||
if(!pilot_isFlag(pilot, PILOT_HYPERSPACE)) { // Limit the speed.
|
||||
if(pilot_isFlag(pilot, PILOT_AFTERBURNER) && // Must have enough energy.
|
||||
(player->energy > pilot->afterburner->outfit->u.afb.energy * dt)) {
|
||||
limit_speed(&pilot->solid->vel,
|
||||
pilot->speed * pilot->afterburner->outfit->u.afb.speed_perc +
|
||||
pilot->afterburner->outfit->u.afb.speed_abs, dt);
|
||||
pilot->energy -= pilot->afterburner->outfit->u.afb.energy * dt;
|
||||
} else
|
||||
limit_speed(&pilot->solid->vel, pilot->speed, dt);
|
||||
}
|
||||
}
|
||||
|
||||
// Pilot is getting ready or is in, hyperspace.
|
||||
static void pilot_hyperspace(Pilot* p) {
|
||||
double diff;
|
||||
double diff;
|
||||
|
||||
if(pilot_isFlag(p, PILOT_HYPERSPACE)) {
|
||||
// Pilot is actually in hyperspace.
|
||||
@ -417,18 +417,18 @@ static void pilot_hyperspace(Pilot* p) {
|
||||
}
|
||||
} else {
|
||||
// Pilot is getting ready for hyperspace.
|
||||
|
||||
|
||||
if(VMOD(p->solid->vel) > MIN_VEL_ERR) {
|
||||
diff = pilot_face(p, VANGLE(p->solid->vel) + M_PI);
|
||||
|
||||
if(ABS(diff) < MAX_DIR_ERR) // Brake.
|
||||
vect_pset(&p->solid->force, p->thrust, p->solid->dir);
|
||||
|
||||
if(ABS(diff) < MAX_DIR_ERR) // Brake.
|
||||
vect_pset(&p->solid->force, p->thrust, p->solid->dir);
|
||||
} else {
|
||||
vectnull(&p->solid->force); // Stop accelerating.
|
||||
|
||||
// Player should actually face the system she's headed to.
|
||||
if(p == player) diff = player_faceHyperspace();
|
||||
else diff = pilot_face(p, VANGLE(p->solid->pos));
|
||||
|
||||
// Player should actually face the system she's headed to.
|
||||
if(p == player) diff = player_faceHyperspace();
|
||||
else diff = pilot_face(p, VANGLE(p->solid->pos));
|
||||
|
||||
if(ABS(diff) < MAX_DIR_ERR) {
|
||||
// We should prepare for the jump now.
|
||||
@ -441,188 +441,188 @@ static void pilot_hyperspace(Pilot* p) {
|
||||
}
|
||||
|
||||
int pilot_addOutfit(Pilot* pilot, Outfit* outfit, int quantity) {
|
||||
int i, q;
|
||||
char* s;
|
||||
int i, q;
|
||||
char* s;
|
||||
|
||||
q = quantity;
|
||||
q = quantity;
|
||||
|
||||
for(i = 0; i < pilot->noutfits; i++)
|
||||
if(strcmp(outfit->name, pilot->outfits[i].outfit->name)==0) {
|
||||
pilot->outfits[i].quantity += quantity;
|
||||
// Can't be over max.
|
||||
if(pilot->outfits[i].quantity > outfit->max) {
|
||||
q -= pilot->outfits[i].quantity - outfit->max;
|
||||
for(i = 0; i < pilot->noutfits; i++)
|
||||
if(strcmp(outfit->name, pilot->outfits[i].outfit->name)==0) {
|
||||
pilot->outfits[i].quantity += quantity;
|
||||
// Can't be over max.
|
||||
if(pilot->outfits[i].quantity > outfit->max) {
|
||||
q -= pilot->outfits[i].quantity - outfit->max;
|
||||
pilot->outfits[i].quantity = outfit->max;
|
||||
}
|
||||
pilot_calcStats(pilot);
|
||||
return q;
|
||||
}
|
||||
|
||||
s = (pilot->secondary) ? pilot->secondary->outfit->name : NULL;
|
||||
pilot->outfits = realloc(pilot->outfits, (pilot->noutfits+1)*sizeof(PilotOutfit));
|
||||
pilot->outfits[pilot->noutfits].outfit = outfit;
|
||||
pilot->outfits[pilot->noutfits].quantity = quantity;
|
||||
// Can't be over max.
|
||||
if(pilot->outfits[pilot->noutfits].quantity > outfit->max) {
|
||||
q -= pilot->outfits[pilot->noutfits].quantity - outfit->max;
|
||||
pilot->outfits[i].quantity = outfit->max;
|
||||
}
|
||||
pilot_calcStats(pilot);
|
||||
return q;
|
||||
}
|
||||
|
||||
s = (pilot->secondary) ? pilot->secondary->outfit->name : NULL;
|
||||
pilot->outfits = realloc(pilot->outfits, (pilot->noutfits+1)*sizeof(PilotOutfit));
|
||||
pilot->outfits[pilot->noutfits].outfit = outfit;
|
||||
pilot->outfits[pilot->noutfits].quantity = quantity;
|
||||
// Can't be over max.
|
||||
if(pilot->outfits[pilot->noutfits].quantity > outfit->max) {
|
||||
q -= pilot->outfits[pilot->noutfits].quantity - outfit->max;
|
||||
pilot->outfits[i].quantity = outfit->max;
|
||||
}
|
||||
pilot->outfits[pilot->noutfits].timer = 0;
|
||||
(pilot->noutfits)++;
|
||||
pilot->outfits[pilot->noutfits].timer = 0;
|
||||
(pilot->noutfits)++;
|
||||
|
||||
if(outfit_isTurret(outfit))
|
||||
// Used to speed up AI.
|
||||
pilot_setFlag(pilot, PILOT_HASTURRET);
|
||||
|
||||
// Hack due to realloc possibility.
|
||||
pilot_setSecondary(pilot, s);
|
||||
if(outfit_isTurret(outfit))
|
||||
// Used to speed up AI.
|
||||
pilot_setFlag(pilot, PILOT_HASTURRET);
|
||||
|
||||
pilot_calcStats(pilot);
|
||||
return q;
|
||||
// Hack due to realloc possibility.
|
||||
pilot_setSecondary(pilot, s);
|
||||
|
||||
pilot_calcStats(pilot);
|
||||
return q;
|
||||
}
|
||||
|
||||
// Remove an outfit from the pilot.
|
||||
int pilot_rmOutfit(Pilot* pilot, Outfit* outfit, int quantity) {
|
||||
int i, q;
|
||||
char* s;
|
||||
int i, q;
|
||||
char* s;
|
||||
|
||||
q = quantity;
|
||||
q = quantity;
|
||||
|
||||
for(i = 0; i < pilot->noutfits; i++)
|
||||
if(strcmp(outfit->name, pilot->outfits[i].outfit->name)==0) {
|
||||
pilot->outfits[i].quantity -= quantity;
|
||||
if(pilot->outfits[i].quantity <= 0) {
|
||||
// We didn't actually remove the full amount.
|
||||
q += pilot->outfits[i].quantity;
|
||||
// Hack in case it reallocs - Can happen even when shrinking.
|
||||
s = (pilot->secondary) ? pilot->secondary->outfit->name : NULL;
|
||||
// Clear it if it's the afterburner.
|
||||
if(&pilot->outfits[i] == pilot->afterburner)
|
||||
pilot->afterburner = NULL;
|
||||
for(i = 0; i < pilot->noutfits; i++)
|
||||
if(strcmp(outfit->name, pilot->outfits[i].outfit->name)==0) {
|
||||
pilot->outfits[i].quantity -= quantity;
|
||||
if(pilot->outfits[i].quantity <= 0) {
|
||||
// We didn't actually remove the full amount.
|
||||
q += pilot->outfits[i].quantity;
|
||||
// Hack in case it reallocs - Can happen even when shrinking.
|
||||
s = (pilot->secondary) ? pilot->secondary->outfit->name : NULL;
|
||||
// Clear it if it's the afterburner.
|
||||
if(&pilot->outfits[i] == pilot->afterburner)
|
||||
pilot->afterburner = NULL;
|
||||
|
||||
// Remove the outfit.
|
||||
memmove(pilot->outfits+i, pilot->outfits+i+1,
|
||||
sizeof(PilotOutfit)*(pilot->noutfits-i));
|
||||
pilot->noutfits--;
|
||||
pilot->outfits = realloc(pilot->outfits,
|
||||
sizeof(PilotOutfit)*(pilot->noutfits));
|
||||
// Remove the outfit.
|
||||
memmove(pilot->outfits+i, pilot->outfits+i+1,
|
||||
sizeof(PilotOutfit)*(pilot->noutfits-i));
|
||||
pilot->noutfits--;
|
||||
pilot->outfits = realloc(pilot->outfits,
|
||||
sizeof(PilotOutfit)*(pilot->noutfits));
|
||||
|
||||
pilot_setSecondary(pilot, s);
|
||||
}
|
||||
return q;
|
||||
}
|
||||
WARN("Failure attempting to remove %d '%s' from pilot '%s'",
|
||||
quantity, outfit->name, pilot->name);
|
||||
|
||||
return 0;
|
||||
pilot_setSecondary(pilot, s);
|
||||
}
|
||||
return q;
|
||||
}
|
||||
WARN("Failure attempting to remove %d '%s' from pilot '%s'",
|
||||
quantity, outfit->name, pilot->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Recalculate the pilot's stats based on her outfits.
|
||||
static void pilot_calcStats(Pilot* pilot) {
|
||||
int i;
|
||||
double q;
|
||||
Outfit* o;
|
||||
double ac, sc, ec; // Temp health coeficients to set.
|
||||
int i;
|
||||
double q;
|
||||
Outfit* o;
|
||||
double ac, sc, ec; // Temp health coeficients to set.
|
||||
|
||||
// -- Set up the basic stuff.
|
||||
// Movement.
|
||||
pilot->thrust = pilot->ship->thrust;
|
||||
pilot->turn = pilot->ship->turn;
|
||||
pilot->speed = pilot->ship->speed;
|
||||
// Health.
|
||||
ac = pilot->armour / pilot->armour_max;
|
||||
sc = pilot->shield / pilot->shield_max;
|
||||
ec = pilot->energy / pilot->energy_max;
|
||||
pilot->armour_max = pilot->ship->armour;
|
||||
pilot->shield_max = pilot->ship->shield;
|
||||
pilot->energy_max = pilot->ship->energy;
|
||||
pilot->armour_regen = pilot->ship->armour_regen;
|
||||
pilot->shield_regen = pilot->ship->shield_regen;
|
||||
pilot->energy_regen = pilot->ship->energy_regen;
|
||||
// -- Set up the basic stuff.
|
||||
// Movement.
|
||||
pilot->thrust = pilot->ship->thrust;
|
||||
pilot->turn = pilot->ship->turn;
|
||||
pilot->speed = pilot->ship->speed;
|
||||
// Health.
|
||||
ac = pilot->armour / pilot->armour_max;
|
||||
sc = pilot->shield / pilot->shield_max;
|
||||
ec = pilot->energy / pilot->energy_max;
|
||||
pilot->armour_max = pilot->ship->armour;
|
||||
pilot->shield_max = pilot->ship->shield;
|
||||
pilot->energy_max = pilot->ship->energy;
|
||||
pilot->armour_regen = pilot->ship->armour_regen;
|
||||
pilot->shield_regen = pilot->ship->shield_regen;
|
||||
pilot->energy_regen = pilot->ship->energy_regen;
|
||||
|
||||
// Now add outfit changes.
|
||||
for(i = 0; i < pilot->noutfits; i++) {
|
||||
if(outfit_isMod(pilot->outfits[i].outfit)) {
|
||||
q = (double) pilot->outfits[i].quantity;
|
||||
o = pilot->outfits[i].outfit;
|
||||
// Now add outfit changes.
|
||||
for(i = 0; i < pilot->noutfits; i++) {
|
||||
if(outfit_isMod(pilot->outfits[i].outfit)) {
|
||||
q = (double) pilot->outfits[i].quantity;
|
||||
o = pilot->outfits[i].outfit;
|
||||
|
||||
// Movement.
|
||||
pilot->thrust += o->u.mod.thrust * q;
|
||||
pilot->turn += o->u.mod.turn * q;
|
||||
pilot->speed += o->u.mod.speed * q;
|
||||
// Health.
|
||||
pilot->armour_max += o->u.mod.armour * q;
|
||||
pilot->armour_regen += o->u.mod.armour_regen * q;
|
||||
pilot->shield_max += o->u.mod.shield * q;
|
||||
pilot->shield_regen += o->u.mod.shield_regen * q;
|
||||
pilot->energy_max += o->u.mod.energy * q;
|
||||
pilot->energy_regen += o->u.mod.energy_regen * q;
|
||||
// Movement.
|
||||
pilot->thrust += o->u.mod.thrust * q;
|
||||
pilot->turn += o->u.mod.turn * q;
|
||||
pilot->speed += o->u.mod.speed * q;
|
||||
// Health.
|
||||
pilot->armour_max += o->u.mod.armour * q;
|
||||
pilot->armour_regen += o->u.mod.armour_regen * q;
|
||||
pilot->shield_max += o->u.mod.shield * q;
|
||||
pilot->shield_regen += o->u.mod.shield_regen * q;
|
||||
pilot->energy_max += o->u.mod.energy * q;
|
||||
pilot->energy_regen += o->u.mod.energy_regen * q;
|
||||
|
||||
}
|
||||
else if(outfit_isAfterburner(pilot->outfits[i].outfit)) {
|
||||
// Set the afterburner.
|
||||
pilot->afterburner = &pilot->outfits[i];
|
||||
}
|
||||
}
|
||||
else if(outfit_isAfterburner(pilot->outfits[i].outfit)) {
|
||||
// Set the afterburner.
|
||||
pilot->afterburner = &pilot->outfits[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Give the pilot her health proportion back.
|
||||
pilot->armour = ac * pilot->armour_max;
|
||||
pilot->shield = sc * pilot->shield_max;
|
||||
pilot->energy = ec * pilot->energy_max;
|
||||
// Give the pilot her health proportion back.
|
||||
pilot->armour = ac * pilot->armour_max;
|
||||
pilot->shield = sc * pilot->shield_max;
|
||||
pilot->energy = ec * pilot->energy_max;
|
||||
}
|
||||
|
||||
// Try to add quantity of cargo to pilot, return quantity actually added.
|
||||
int pilot_addCargo(Pilot* pilot, Commodity* cargo, int quantity) {
|
||||
int i, q;
|
||||
|
||||
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++;
|
||||
int i, q;
|
||||
|
||||
return q;
|
||||
q = quantity;
|
||||
for(i = 0; i < pilot->ncommodities; i++)
|
||||
if(pilot->commodities[i].commodity == cargo) {
|
||||
if(pilot->cargo_free < quantity)
|
||||
q = pilot->cargo_free;
|
||||
pilot->commodities[i].quantity += q;
|
||||
pilot->cargo_free -= q;
|
||||
return q;
|
||||
}
|
||||
|
||||
// Must add another one.
|
||||
pilot->commodities = realloc(pilot->commodities,
|
||||
sizeof(PilotCommodity) * (pilot->ncommodities+1));
|
||||
pilot->commodities[pilot->ncommodities].commodity = cargo;
|
||||
if(pilot->cargo_free < quantity)
|
||||
q = pilot->cargo_free;
|
||||
pilot->commodities[pilot->ncommodities].quantity = q;
|
||||
pilot->cargo_free -= q;
|
||||
pilot->ncommodities++;
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
// Try to get rid of quantity cargo from pilot,
|
||||
// return quantity actually removed.
|
||||
int pilot_rmCargo(Pilot* pilot, Commodity* cargo, int quantity) {
|
||||
int i, q;
|
||||
|
||||
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;
|
||||
int i, q;
|
||||
|
||||
pilot->cargo_free += q;
|
||||
return q;
|
||||
}
|
||||
|
||||
return 0;
|
||||
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;
|
||||
return q;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ==Init pilot.===========================================
|
||||
@ -634,15 +634,15 @@ int pilot_rmCargo(Pilot* pilot, Commodity* cargo, int quantity) {
|
||||
// flags : Tweaking the pilot.
|
||||
// ========================================================
|
||||
void pilot_init(Pilot* pilot, Ship* ship, char* name, Faction* faction,
|
||||
AI_Profile* ai, const double dir, const Vec2* pos,
|
||||
const Vec2* vel, const int flags) {
|
||||
AI_Profile* ai, const double dir, const Vec2* pos,
|
||||
const Vec2* vel, const int flags) {
|
||||
|
||||
if(flags & PILOT_PLAYER) // Player is ID 0
|
||||
pilot->id = PLAYER_ID;
|
||||
else
|
||||
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);
|
||||
|
||||
// Faction.
|
||||
@ -663,7 +663,7 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, Faction* faction,
|
||||
pilot->outfits = NULL;
|
||||
pilot->secondary = NULL;
|
||||
pilot->ammo = NULL;
|
||||
pilot->afterburner = NULL;
|
||||
pilot->afterburner = NULL;
|
||||
ShipOutfit* so;
|
||||
if(ship->outfit) {
|
||||
pilot->noutfits = 0;
|
||||
@ -673,25 +673,25 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, Faction* faction,
|
||||
pilot->outfits[pilot->noutfits].quantity = so->quantity;
|
||||
pilot->outfits[pilot->noutfits].timer = 0;
|
||||
(pilot->noutfits)++;
|
||||
if(outfit_isTurret(so->data)) // Used to speed up AI a bit.
|
||||
pilot_setFlag(pilot, PILOT_HASTURRET);
|
||||
if(outfit_isTurret(so->data)) // Used to speed up AI a bit.
|
||||
pilot_setFlag(pilot, PILOT_HASTURRET);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the pilot stats based on her ship and outfits.
|
||||
// Hack to have full armour/shield/energy.
|
||||
pilot->armour = pilot->armour_max = 1.;
|
||||
pilot->shield = pilot->shield_max = 1.;
|
||||
pilot->energy = pilot->energy_max = 1.;
|
||||
pilot_calcStats(pilot);
|
||||
// Set the pilot stats based on her ship and outfits.
|
||||
// Hack to have full armour/shield/energy.
|
||||
pilot->armour = pilot->armour_max = 1.;
|
||||
pilot->shield = pilot->shield_max = 1.;
|
||||
pilot->energy = pilot->energy_max = 1.;
|
||||
pilot_calcStats(pilot);
|
||||
|
||||
// Cargo.
|
||||
pilot->credits = 0;
|
||||
pilot->commodities = NULL;
|
||||
pilot->ncommodities = 0;
|
||||
pilot->cargo_free = pilot->ship->cap_cargo;
|
||||
// Cargo.
|
||||
pilot->credits = 0;
|
||||
pilot->commodities = NULL;
|
||||
pilot->ncommodities = 0;
|
||||
pilot->cargo_free = pilot->ship->cap_cargo;
|
||||
|
||||
// Set flags and functions.
|
||||
// Set flags and functions.
|
||||
if(flags & PILOT_PLAYER) {
|
||||
pilot->think = player_think; // Players don't need to thing! :P
|
||||
pilot->render = NULL; // Render will be called from player_think
|
||||
@ -701,20 +701,20 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, Faction* faction,
|
||||
} else {
|
||||
pilot->think = ai_think;
|
||||
pilot->render = pilot_render;
|
||||
ai_create(pilot); // Will run the create function in ai.
|
||||
ai_create(pilot); // Will run the create function in ai.
|
||||
}
|
||||
// All update the same way.
|
||||
// All update the same way.
|
||||
pilot->update = pilot_update;
|
||||
}
|
||||
|
||||
// Create a new pilot - Params are same as pilot_init. Return pilot's id.
|
||||
unsigned int pilot_create(Ship* ship, char* name, Faction* faction,
|
||||
AI_Profile* ai, const double dir, const Vec2* pos,
|
||||
const Vec2* vel, const int flags) {
|
||||
AI_Profile* ai, const double dir, const Vec2* pos,
|
||||
const Vec2* vel, const int flags) {
|
||||
|
||||
Pilot** tp, *dyn;
|
||||
Pilot** tp, *dyn;
|
||||
|
||||
dyn = MALLOC_L(Pilot);
|
||||
dyn = MALLOC_L(Pilot);
|
||||
if(dyn == NULL) {
|
||||
WARN("Unable to allocate memory.");
|
||||
return 0;
|
||||
@ -732,16 +732,16 @@ unsigned int pilot_create(Ship* ship, char* name, Faction* faction,
|
||||
} else {
|
||||
// Add to the stack.
|
||||
pilots++; // There is a new pilot.
|
||||
|
||||
if(pilots >= mpilots) {
|
||||
// Need to grow. About 20 at a time.
|
||||
mpilots += 20;
|
||||
tp = pilot_stack;
|
||||
pilot_stack = realloc(pilot_stack, mpilots*sizeof(Pilot*));
|
||||
if((pilot_stack != tp) && player)
|
||||
// Take into account possible mem move.
|
||||
player = pilot_stack[0];
|
||||
}
|
||||
|
||||
if(pilots >= mpilots) {
|
||||
// Need to grow. About 20 at a time.
|
||||
mpilots += 20;
|
||||
tp = pilot_stack;
|
||||
pilot_stack = realloc(pilot_stack, mpilots*sizeof(Pilot*));
|
||||
if((pilot_stack != tp) && player)
|
||||
// Take into account possible mem move.
|
||||
player = pilot_stack[0];
|
||||
}
|
||||
|
||||
pilot_stack[pilots-1] = dyn;
|
||||
}
|
||||
@ -750,11 +750,11 @@ unsigned int pilot_create(Ship* ship, char* name, Faction* faction,
|
||||
|
||||
// Frees and cleans up a pilot.
|
||||
static void pilot_free(Pilot* p) {
|
||||
if(player == p) player = NULL;
|
||||
if(player == p) player = NULL;
|
||||
solid_free(p->solid);
|
||||
if(p->outfits) free(p->outfits);
|
||||
free(p->name);
|
||||
if(p->commodities) free(p->commodities);
|
||||
if(p->commodities) free(p->commodities);
|
||||
ai_destroy(p);
|
||||
free(p);
|
||||
}
|
||||
@ -765,8 +765,8 @@ void pilot_destroy(Pilot* p) {
|
||||
for(i = 0; i < pilots; i++)
|
||||
if(pilot_stack[i] == p)
|
||||
break;
|
||||
|
||||
pilots--;
|
||||
|
||||
pilots--;
|
||||
|
||||
while(i < pilots) {
|
||||
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.
|
||||
if(tmp->name == NULL) WARN("Fleet in "FLEET_DATA" has invalid or no name");
|
||||
|
||||
|
||||
do {
|
||||
// Load all the data.
|
||||
if(strcmp((char*)node->name, "faction")==0)
|
||||
@ -869,7 +869,7 @@ static Fleet* fleet_parse(const xmlNodePtr parent) {
|
||||
pilot->chance = atoi(c);
|
||||
if(pilot->chance == 0)
|
||||
WARN("Pilot %s in Fleet %s has 0%% chance of appearing",
|
||||
pilot->name, tmp->name);
|
||||
pilot->name, tmp->name);
|
||||
if(c) free(c); // Free the external malloc.
|
||||
|
||||
tmp->pilots = realloc(tmp->pilots, sizeof(FleetPilot)*tmp->npilots);
|
||||
@ -883,7 +883,7 @@ static Fleet* fleet_parse(const xmlNodePtr parent) {
|
||||
MELEMENT(tmp->ai==NULL, "ai");
|
||||
MELEMENT(tmp->faction==NULL, "faction");
|
||||
MELEMENT(tmp->pilots==NULL, "pilots");
|
||||
#undef MELEMENT
|
||||
#undef MELEMENT
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
62
src/pilot.h
62
src/pilot.h
@ -10,11 +10,11 @@
|
||||
|
||||
#define PLAYER_ID 1
|
||||
|
||||
#define HYPERSPACE_ENGINE_DELAY 3000 // Warm up the engines.
|
||||
#define HYPERSPACE_FLY_DELAY 5000 // Time taken to hyperspace.
|
||||
#define HYPERSPACE_STARS_BLUR 2000 // Time stars blur.
|
||||
#define HYPERSPACE_STARS_LENGTH 1000 // Length the stars blur to at max.
|
||||
#define HYPERSPACE_FADEOUT 1000 // Time fadeout.
|
||||
#define HYPERSPACE_ENGINE_DELAY 3000 // Warm up the engines.
|
||||
#define HYPERSPACE_FLY_DELAY 5000 // Time taken to hyperspace.
|
||||
#define HYPERSPACE_STARS_BLUR 2000 // Time stars blur.
|
||||
#define HYPERSPACE_STARS_LENGTH 1000 // Length the stars blur to at max.
|
||||
#define HYPERSPACE_FADEOUT 1000 // Time fadeout.
|
||||
|
||||
// Aproximation for pilot size.
|
||||
#define PILOT_SIZE_APROX 0.8
|
||||
@ -26,18 +26,18 @@
|
||||
#define pilot_rmFlag(p,f) (p->flags ^= (f))
|
||||
// Creation.
|
||||
#define PILOT_PLAYER (1<<0) // Pilot is a player.
|
||||
#define PILOT_HASTURRET (1<<20) // Pilit has turrets.
|
||||
#define PILOT_HASTURRET (1<<20) // Pilit has turrets.
|
||||
// Dynamic.
|
||||
#define PILOT_HOSTILE (1<<1) // Pilot is hostile to the player.
|
||||
#define PILOT_COMBAT (1<<2) // Pilot is engaged in combat.
|
||||
#define PILOT_AFTERBURNER (1<<3) // Pilot has her afterburner activated.
|
||||
#define PILOT_AFTERBURNER (1<<3) // Pilot has her afterburner activated.
|
||||
#define PILOT_HYP_PREP (1<<5) // Pilot is getting ready for hyperspace.
|
||||
#define PILOT_HYP_BEGIN (1<<6) // Pilot is starting engines.
|
||||
#define PILOT_HYPERSPACE (1<<7) // Pilot is in hyperspace.
|
||||
#define PILOT_BOARDED (1<<8) // Pilot has been boarded already!
|
||||
#define PILOT_BOARDED (1<<8) // Pilot has been boarded already!
|
||||
#define PILOT_DISABLED (1<<9) // Pilot is disabled.
|
||||
#define PILOT_DEAD (1<<10) // Pilot is on it's death bed.
|
||||
#define PILOT_EXPLODED (1<<11) // Pilot did final death explosion.
|
||||
#define PILOT_DEAD (1<<10) // Pilot is on it's death bed.
|
||||
#define PILOT_EXPLODED (1<<11) // Pilot did final death explosion.
|
||||
#define PILOT_DELETE (1<<15) // Pilot will get delete asap.
|
||||
|
||||
// Just makes life simpler.
|
||||
@ -45,14 +45,14 @@
|
||||
#define pilot_isDisabled(p) ((p)->flags & PILOT_DISABLED)
|
||||
|
||||
typedef struct PilotOutfit_ {
|
||||
Outfit* outfit; // Associated outfit.
|
||||
int quantity; // Number of outfits of this type that the pilot has.
|
||||
Outfit* outfit; // Associated outfit.
|
||||
int quantity; // Number of outfits of this type that the pilot has.
|
||||
unsigned int timer; // Used to store last used weapon time.
|
||||
} PilotOutfit;
|
||||
|
||||
typedef struct PilotCommodity_ {
|
||||
Commodity* commodity;
|
||||
int quantity;
|
||||
Commodity* commodity;
|
||||
int quantity;
|
||||
} PilotCommodity;
|
||||
|
||||
// Primary pilot structure.
|
||||
@ -65,14 +65,14 @@ typedef struct Pilot_ {
|
||||
// Object characteristics.
|
||||
Ship* ship; // Pilots ship.
|
||||
Solid* solid; // Associated solid (physics).
|
||||
int tsx, tsy; // Current sprite, calculated on update.
|
||||
int tsx, tsy; // Current sprite, calculated on update.
|
||||
|
||||
double thrust, turn, speed;
|
||||
double thrust, turn, speed;
|
||||
|
||||
// Current health.
|
||||
double armour, shield, energy;
|
||||
double armour_max, shield_max, energy_max;
|
||||
double armour_regen, shield_regen, energy_regen;
|
||||
double armour_regen, shield_regen, energy_regen;
|
||||
double fuel; // Used only for jumps. TODO: make it do something.
|
||||
|
||||
void (*think)(struct Pilot_*); // AI thinking for the pilot.
|
||||
@ -84,16 +84,16 @@ typedef struct Pilot_ {
|
||||
int noutfits;
|
||||
PilotOutfit* secondary; // Secondary weapon.
|
||||
PilotOutfit* ammo; // Secondary ammo (if needed).
|
||||
PilotOutfit* afterburner; // Ze afterburner.
|
||||
PilotOutfit* afterburner; // Ze afterburner.
|
||||
|
||||
// Cargo.
|
||||
int credits; // Moniez the pilot has.
|
||||
PilotCommodity* commodities; // Commodity and quantity.
|
||||
int ncommodities;
|
||||
int cargo_free;
|
||||
// Cargo.
|
||||
int credits; // Moniez the pilot has.
|
||||
PilotCommodity* commodities; // Commodity and quantity.
|
||||
int ncommodities;
|
||||
int cargo_free;
|
||||
|
||||
// Misc.
|
||||
uint32_t flags; // Used for AI etc.
|
||||
// Misc.
|
||||
uint32_t flags; // Used for AI etc.
|
||||
unsigned int ptimer; // Generic timer for internal pilot use.
|
||||
|
||||
// AI.
|
||||
@ -113,7 +113,7 @@ typedef struct FleetPilot_ {
|
||||
typedef struct Fleet_ {
|
||||
char* name; // Fleet name, used as an identifier.
|
||||
Faction* faction; // Faction of the fleet.
|
||||
|
||||
|
||||
AI_Profile* ai; // A useable profile.
|
||||
|
||||
FleetPilot* pilots; // The pilots in the fleet.
|
||||
@ -131,7 +131,7 @@ Fleet* fleet_get(const char* name);
|
||||
// MISC.
|
||||
void pilot_shoot(Pilot* p, const unsigned int target, const int secondary);
|
||||
void pilot_hit(Pilot* p, const Solid* w, const unsigned int shooter,
|
||||
const double damage_shield, const double damage_armour);
|
||||
const double damage_shield, const double damage_armour);
|
||||
void pilot_setSecondary(Pilot* p, const char* secondary);
|
||||
void pilot_setAmmo(Pilot* p);
|
||||
double pilot_face(Pilot* p, const float dir);
|
||||
@ -142,12 +142,12 @@ int pilot_rmCargo(Pilot* pilot, Commodity* cargo, int quantity);
|
||||
|
||||
// Creation.
|
||||
void pilot_init(Pilot* dest, Ship* ship, char* name, Faction* faction,
|
||||
AI_Profile* ai, const double dir, const Vec2* pos,
|
||||
const Vec2* vel, const int flags);
|
||||
AI_Profile* ai, const double dir, const Vec2* pos,
|
||||
const Vec2* vel, const int flags);
|
||||
|
||||
unsigned int pilot_create(Ship* ship, char* name, Faction* faction,
|
||||
AI_Profile* ai, const double dir, const Vec2* pos,
|
||||
const Vec2* vel, const int flags);
|
||||
AI_Profile* ai, const double dir, const Vec2* pos,
|
||||
const Vec2* vel, const int flags);
|
||||
|
||||
// Init/Cleanup.
|
||||
void pilot_destroy(Pilot* p);
|
||||
|
562
src/player.c
562
src/player.c
@ -90,9 +90,9 @@ typedef struct GUI_ {
|
||||
} GUI;
|
||||
|
||||
GUI gui = {
|
||||
.gfx_frame = NULL,
|
||||
.gfx_targetPilot = NULL,
|
||||
.gfx_targetPlanet = NULL
|
||||
.gfx_frame = NULL,
|
||||
.gfx_targetPilot = NULL,
|
||||
.gfx_targetPlanet = NULL
|
||||
};
|
||||
|
||||
double gui_xoff = 0.;
|
||||
@ -111,12 +111,12 @@ static Msg* msg_stack;
|
||||
// External.
|
||||
extern void pilot_render(const Pilot* pilot); // Extern is in Pilot.*
|
||||
extern void weapon_minimap(const double res,
|
||||
const double w, const double h, const RadarShape shape); // weapon.c
|
||||
const double w, const double h, const RadarShape shape); // weapon.c
|
||||
extern void planets_minimap(const double res,
|
||||
const double w, const double h, const RadarShape shape); // space.c
|
||||
const double w, const double h, const RadarShape shape); // space.c
|
||||
// Internal.
|
||||
static void rect_parse(const xmlNodePtr parent,
|
||||
double* x, double* y, double* w, double* h);
|
||||
double* x, double* y, double* w, double* h);
|
||||
static int gui_parse(const xmlNodePtr parent, const char* name);
|
||||
static void gui_renderPilot(const Pilot* p);
|
||||
static void gui_renderBar(const glColour* c, const Rect* r, const double w);
|
||||
@ -171,8 +171,8 @@ void player_new(void) {
|
||||
else if(xml_isNode(tmp, "y")) y = xml_getFloat(tmp);
|
||||
} while((tmp = tmp->next));
|
||||
}
|
||||
else if(xml_isNode(cur, "combat_crating"))
|
||||
combat_crating = xml_getInt(cur);
|
||||
else if(xml_isNode(cur, "combat_crating"))
|
||||
combat_crating = xml_getInt(cur);
|
||||
} while((cur = cur->next));
|
||||
}
|
||||
}while((node = node->next));
|
||||
@ -181,8 +181,8 @@ void player_new(void) {
|
||||
free(buf);
|
||||
xmlCleanupParser();
|
||||
|
||||
// In case we are respawning.
|
||||
player_rmFlag(PLAYER_DESTROYED);
|
||||
// In case we are respawning.
|
||||
player_rmFlag(PLAYER_DESTROYED);
|
||||
|
||||
// Money.
|
||||
player_credits = RNG(l, h);
|
||||
@ -191,24 +191,24 @@ void player_new(void) {
|
||||
player_message("Welcome to "APPNAME"!");
|
||||
player_message("v%d.%d.%d", VMAJOR, VMINOR, VREV);
|
||||
|
||||
// Create the player and start the game.
|
||||
player_newShip(ship);
|
||||
// Create the player and start the game.
|
||||
player_newShip(ship);
|
||||
space_init(system);
|
||||
|
||||
// Position and direction.
|
||||
player_warp(x, y);
|
||||
player->solid->dir = RNG(0, 359) / 180.*M_PI;
|
||||
// Position and direction.
|
||||
player_warp(x, y);
|
||||
player->solid->dir = RNG(0, 359) / 180.*M_PI;
|
||||
}
|
||||
|
||||
// Change the players ship.
|
||||
void player_newShip(Ship* ship) {
|
||||
if(player)
|
||||
pilot_destroy(player);
|
||||
|
||||
pilot_create(ship, "Player", faction_get("Player"), NULL,
|
||||
0., NULL, NULL, PILOT_PLAYER);
|
||||
|
||||
gl_bindCamera(&player->solid->pos); // Set opengl camera.
|
||||
if(player)
|
||||
pilot_destroy(player);
|
||||
|
||||
pilot_create(ship, "Player", faction_get("Player"), NULL,
|
||||
0., NULL, NULL, PILOT_PLAYER);
|
||||
|
||||
gl_bindCamera(&player->solid->pos); // Set opengl camera.
|
||||
}
|
||||
|
||||
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);
|
||||
msg_stack[msg_max-i].t = msg_stack[msg_max-i-1].t;
|
||||
}
|
||||
// Add the new one.
|
||||
va_start(ap, fmt);
|
||||
vsprintf(msg_stack[0].str, fmt, ap);
|
||||
va_end(ap);
|
||||
// Add the new one.
|
||||
va_start(ap, fmt);
|
||||
vsprintf(msg_stack[0].str, fmt, 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) {
|
||||
@ -243,56 +243,56 @@ void player_clear(void) {
|
||||
}
|
||||
|
||||
static char* player_ratings[] = {
|
||||
"None",
|
||||
"Smallfry",
|
||||
"Minor",
|
||||
"Average",
|
||||
"Major",
|
||||
"Fearsome",
|
||||
"Godlike"
|
||||
"None",
|
||||
"Smallfry",
|
||||
"Minor",
|
||||
"Average",
|
||||
"Major",
|
||||
"Fearsome",
|
||||
"Godlike"
|
||||
};
|
||||
|
||||
const char* player_rating(void) {
|
||||
if(combat_crating == 0) return player_ratings[0];
|
||||
else if(combat_crating < 50) return player_ratings[1];
|
||||
else if(combat_crating < 200) return player_ratings[2];
|
||||
else if(combat_crating < 500) return player_ratings[3];
|
||||
else if(combat_crating < 1000) return player_ratings[4];
|
||||
else if(combat_crating < 2500) return player_ratings[5];
|
||||
else if(combat_crating < 10000) return player_ratings[6];
|
||||
else return player_ratings[7];
|
||||
if(combat_crating == 0) return player_ratings[0];
|
||||
else if(combat_crating < 50) return player_ratings[1];
|
||||
else if(combat_crating < 200) return player_ratings[2];
|
||||
else if(combat_crating < 500) return player_ratings[3];
|
||||
else if(combat_crating < 1000) return player_ratings[4];
|
||||
else if(combat_crating < 2500) return player_ratings[5];
|
||||
else if(combat_crating < 10000) return player_ratings[6];
|
||||
else return player_ratings[7];
|
||||
}
|
||||
|
||||
// Return how much weapon. space the player has remaining.
|
||||
int player_freeSpace(void) {
|
||||
int i, s;
|
||||
s = player->ship->cap_weapon;
|
||||
for(i = 0; i < player->noutfits; i++)
|
||||
s -= player->outfits[i].quantity * player->outfits[i].outfit->mass;
|
||||
|
||||
return s;
|
||||
int i, s;
|
||||
s = player->ship->cap_weapon;
|
||||
for(i = 0; i < player->noutfits; i++)
|
||||
s -= player->outfits[i].quantity * player->outfits[i].outfit->mass;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
// Return amount of outfits the player owns.
|
||||
int player_outfitOwned(const char* outfitname) {
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < player->noutfits; i++)
|
||||
if(strcmp(outfitname, player->outfits[i].outfit->name)==0)
|
||||
return player->outfits[i].quantity;
|
||||
|
||||
return 0;
|
||||
for(i = 0; i < player->noutfits; i++)
|
||||
if(strcmp(outfitname, player->outfits[i].outfit->name)==0)
|
||||
return player->outfits[i].quantity;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Return how many of the commodity the player has.
|
||||
int player_cargoOwned(const char* commodityname) {
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < player->ncommodities; i++)
|
||||
if(strcmp(commodityname, player->commodities[i].commodity->name)==0)
|
||||
return player->commodities[i].quantity;
|
||||
for(i = 0; i < player->ncommodities; i++)
|
||||
if(strcmp(commodityname, player->commodities[i].commodity->name)==0)
|
||||
return player->commodities[i].quantity;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Render the background player stuff, namely planet target
|
||||
@ -301,8 +301,8 @@ void player_renderBG(void) {
|
||||
glColour* c;
|
||||
Planet* planet;
|
||||
|
||||
if(player_isFlag(PLAYER_DESTROYED) ||
|
||||
pilot_isFlag(player, PILOT_DEAD)) return;
|
||||
if(player_isFlag(PLAYER_DESTROYED) ||
|
||||
pilot_isFlag(player, PILOT_DEAD)) return;
|
||||
|
||||
if(planet_target >= 0) {
|
||||
planet = &cur_system->planets[planet_target];
|
||||
@ -334,45 +334,45 @@ void player_render(void) {
|
||||
glColour* c;
|
||||
glFont* f;
|
||||
|
||||
if(player_isFlag(PLAYER_DESTROYED) || pilot_isFlag(player, PILOT_DEAD)) {
|
||||
if(player_isFlag(PLAYER_DESTROYED)) {
|
||||
if(!toolkit && (SDL_GetTicks() > player_timer))
|
||||
menu_death();
|
||||
} else
|
||||
pilot_render(player);
|
||||
|
||||
// Fancy cinematic scene borders.
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix(); // Translation matrix.
|
||||
glTranslated(x-(double)gl_screen.w/2., y-(double)gl_screen.h/2., 0);
|
||||
if(player_isFlag(PLAYER_DESTROYED) || pilot_isFlag(player, PILOT_DEAD)) {
|
||||
if(player_isFlag(PLAYER_DESTROYED)) {
|
||||
if(!toolkit && (SDL_GetTicks() > player_timer))
|
||||
menu_death();
|
||||
} else
|
||||
pilot_render(player);
|
||||
|
||||
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();
|
||||
// Fancy cinematic scene borders.
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix(); // Translation matrix.
|
||||
glTranslated(x-(double)gl_screen.w/2., y-(double)gl_screen.h/2., 0);
|
||||
|
||||
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.
|
||||
if(player_target != PLAYER_ID) p = pilot_get(player_target);
|
||||
else p = NULL;
|
||||
if((p == NULL) || pilot_isFlag(p, PILOT_DEAD))
|
||||
player_target = PLAYER_ID; // No more pilot target.
|
||||
else {
|
||||
// There is still a pilot target.
|
||||
else p = NULL;
|
||||
if((p == NULL) || pilot_isFlag(p, PILOT_DEAD))
|
||||
player_target = PLAYER_ID; // No more pilot target.
|
||||
else {
|
||||
// There is still a pilot target.
|
||||
if(pilot_isDisabled(p)) c = &cInert;
|
||||
else if(pilot_isFlag(p, PILOT_HOSTILE)) c = &cHostile;
|
||||
else c = &cNeutral;
|
||||
|
||||
|
||||
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.;
|
||||
gl_blitSprite(gui.gfx_targetPilot, x, y, 0, 0, c); // Top left.
|
||||
@ -397,18 +397,18 @@ void player_render(void) {
|
||||
glPushMatrix();
|
||||
if(gui.radar.shape == RADAR_RECT)
|
||||
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)
|
||||
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_minimap(gui.radar.res, gui.radar.w, gui.radar.h, gui.radar.shape);
|
||||
|
||||
// Weapons.
|
||||
glBegin(GL_POINTS);
|
||||
COLOUR(cRadar_weap);
|
||||
weapon_minimap(gui.radar.res, gui.radar.w, gui.radar.h, gui.radar.shape);
|
||||
COLOUR(cRadar_weap);
|
||||
weapon_minimap(gui.radar.res, gui.radar.w, gui.radar.h, gui.radar.shape);
|
||||
glEnd();
|
||||
|
||||
// Render the pilots.
|
||||
@ -442,44 +442,44 @@ void player_render(void) {
|
||||
if(planet_target >= 0) {
|
||||
// Planet landing target.
|
||||
gl_printMid(NULL, (int)gui.nav.w,
|
||||
gui.nav.x, gui.nav.y - 5, &cConsole, "Land");
|
||||
gui.nav.x, gui.nav.y - 5, &cConsole, "Land");
|
||||
|
||||
gl_printMid(&gl_smallFont, (int)gui.nav.w, gui.nav.x,
|
||||
gui.nav.y - 10 - gl_smallFont.h, NULL, "%s",
|
||||
cur_system->planets[planet_target].name);
|
||||
gui.nav.y - 10 - gl_smallFont.h, NULL, "%s",
|
||||
cur_system->planets[planet_target].name);
|
||||
}
|
||||
else if(hyperspace_target >= 0) {
|
||||
// Hyperspace target.
|
||||
c = space_canHyperspace(player) ? &cConsole : NULL;
|
||||
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,
|
||||
gui.nav.y - 10 - gl_smallFont.h, NULL, "%s",
|
||||
systems_stack[cur_system->jumps[hyperspace_target]].name);
|
||||
gui.nav.y - 10 - gl_smallFont.h, NULL, "%s",
|
||||
systems_stack[cur_system->jumps[hyperspace_target]].name);
|
||||
}
|
||||
else {
|
||||
// No NAV target.
|
||||
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,
|
||||
gui.nav.y - 10 - gl_smallFont.h, &cGrey, "Off");
|
||||
gui.nav.y - 10 - gl_smallFont.h, &cGrey, "Off");
|
||||
}
|
||||
|
||||
// Health
|
||||
gui_renderBar(&cShield, &gui.shield, player->shield / player->shield_max);
|
||||
gui_renderBar(&cArmour, &gui.armour, player->armour / player->armour_max);
|
||||
gui_renderBar(&cEnergy, &gui.energy, player->energy / player->energy_max);
|
||||
|
||||
|
||||
// Weapon.
|
||||
if(player->secondary == NULL) {
|
||||
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,
|
||||
gui.weapon.y - 10 - gl_defFont.h, &cGrey, "None");
|
||||
gui.weapon.y - 10 - gl_defFont.h, &cGrey, "None");
|
||||
} else {
|
||||
f = &gl_defFont;
|
||||
if(outfit_isLauncher(player->secondary->outfit)) {
|
||||
if(outfit_isLauncher(player->secondary->outfit)) {
|
||||
// Use the ammunitions name.
|
||||
i = gl_printWidth(f, "%s", player->secondary->outfit->u.lau.ammo);
|
||||
if(i > gui.weapon.w)
|
||||
@ -487,23 +487,23 @@ void player_render(void) {
|
||||
f = &gl_smallFont;
|
||||
|
||||
gl_printMid(f, (int)gui.weapon.w, gui.weapon.x,
|
||||
gui.weapon.y - 5,
|
||||
&cConsole, "%s", player->secondary->outfit->u.lau.ammo);
|
||||
gui.weapon.y - 5,
|
||||
&cConsole, "%s", player->secondary->outfit->u.lau.ammo);
|
||||
|
||||
// Print ammo underneath to the left.
|
||||
gl_printMid(&gl_smallFont, (int)gui.weapon.w, gui.weapon.x,
|
||||
gui.weapon.y - 10 - gl_defFont.h,
|
||||
NULL, "%d", (player->ammo) ? player->ammo->quantity : 0);
|
||||
gui.weapon.y - 10 - gl_defFont.h,
|
||||
NULL, "%d", (player->ammo) ? player->ammo->quantity : 0);
|
||||
} else {
|
||||
// Just print the item name.
|
||||
i = gl_printWidth(f, "%s", player->secondary->outfit->name);
|
||||
if(i > (int)gui.weapon.w)
|
||||
// Font is too big.
|
||||
f = &gl_smallFont;
|
||||
gl_printMid(f, (int)gui.weapon.w,
|
||||
gui.weapon.x, gui.weapon.y - (gui.weapon.h - f->h)/2.,
|
||||
&cConsole, "%s", player->secondary->outfit->name);
|
||||
}
|
||||
// Just print the item name.
|
||||
i = gl_printWidth(f, "%s", player->secondary->outfit->name);
|
||||
if(i > (int)gui.weapon.w)
|
||||
// Font is too big.
|
||||
f = &gl_smallFont;
|
||||
gl_printMid(f, (int)gui.weapon.w,
|
||||
gui.weapon.x, gui.weapon.y - (gui.weapon.h - f->h)/2.,
|
||||
&cConsole, "%s", player->secondary->outfit->name);
|
||||
}
|
||||
}
|
||||
|
||||
// Target.
|
||||
@ -511,67 +511,67 @@ void player_render(void) {
|
||||
p = pilot_get(player_target);
|
||||
|
||||
gl_blitStatic(p->ship->gfx_target, gui.target.x, gui.target.y, NULL);
|
||||
|
||||
|
||||
// Target name.
|
||||
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,
|
||||
NULL, "%s", p->faction->name);
|
||||
NULL, "%s", p->faction->name);
|
||||
|
||||
// Target status.
|
||||
if(pilot_isDisabled(p))
|
||||
// Disable the pilot.
|
||||
gl_print(&gl_smallFont, gui.target_health.x, gui.target_health.y,
|
||||
NULL, "Disabled");
|
||||
NULL, "Disabled");
|
||||
else if(p->shield > p->shield_max / 100.)
|
||||
// On shields.
|
||||
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
|
||||
// On armour.
|
||||
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 {
|
||||
// No target.
|
||||
gl_printMid(NULL, SHIP_TARGET_W, gui.target.x,
|
||||
gui.target.y + (SHIP_TARGET_H - gl_defFont.h)/2.,
|
||||
&cGrey80, "No Target");
|
||||
gui.target.y + (SHIP_TARGET_H - gl_defFont.h)/2.,
|
||||
&cGrey80, "No Target");
|
||||
}
|
||||
|
||||
// Misc.
|
||||
j = gui.misc.y - 8 - gl_smallFont.h;
|
||||
j = gui.misc.y - 8 - gl_smallFont.h;
|
||||
gl_print(NULL, gui.misc.x + 8, j,
|
||||
&cConsole, "SCreds:");
|
||||
|
||||
credits2str(str, player_credits, 2);
|
||||
&cConsole, "SCreds:");
|
||||
|
||||
credits2str(str, player_credits, 2);
|
||||
|
||||
i = gl_printWidth(&gl_smallFont, str);
|
||||
gl_print(&gl_smallFont, gui.misc.x + gui.misc.w - 8 - i, j,
|
||||
NULL, str);
|
||||
|
||||
// Cargo and co.
|
||||
if(player->ncommodities > 0) {
|
||||
NULL, str);
|
||||
|
||||
// Cargo and co.
|
||||
if(player->ncommodities > 0) {
|
||||
j -= gl_smallFont.h + 5;
|
||||
gl_print(&gl_smallFont,
|
||||
gui.misc.x + 8, j, &cConsole, "Cargo");
|
||||
|
||||
for(i = 0; i < MIN(player->ncommodities,3); i++) {
|
||||
j -= gl_smallFont.h + 3;
|
||||
gl_print(&gl_smallFont,
|
||||
gui.misc.x + 13, j,
|
||||
NULL, "%d %s", player->commodities[i].quantity,
|
||||
player->commodities[i].commodity->name);
|
||||
}
|
||||
}
|
||||
|
||||
j -= gl_smallFont.h + 5;
|
||||
gl_print(&gl_smallFont,
|
||||
gui.misc.x + 8, j, &cConsole, "Cargo");
|
||||
gui.misc.x + 8, j, &cConsole, "Free:");
|
||||
|
||||
for(i = 0; i < MIN(player->ncommodities,3); i++) {
|
||||
j -= gl_smallFont.h + 3;
|
||||
gl_print(&gl_smallFont,
|
||||
gui.misc.x + 13, j,
|
||||
NULL, "%d %s", player->commodities[i].quantity,
|
||||
player->commodities[i].commodity->name);
|
||||
}
|
||||
}
|
||||
|
||||
j -= gl_smallFont.h + 5;
|
||||
gl_print(&gl_smallFont,
|
||||
gui.misc.x + 8, j, &cConsole, "Free:");
|
||||
|
||||
i = gl_printWidth(&gl_smallFont, "%d", player->ship->cap_cargo);
|
||||
gl_print(&gl_smallFont,
|
||||
gui.misc.x + gui.misc.w - 8 - i, j,
|
||||
NULL, "%d", player->cargo_free);
|
||||
i = gl_printWidth(&gl_smallFont, "%d", player->ship->cap_cargo);
|
||||
gl_print(&gl_smallFont,
|
||||
gui.misc.x + gui.misc.w - 8 - i, j,
|
||||
NULL, "%d", player->cargo_free);
|
||||
|
||||
// Messages.
|
||||
x = gui.msg.x;
|
||||
@ -586,18 +586,18 @@ void player_render(void) {
|
||||
}
|
||||
// Hyperspace FLASH BANG!!!
|
||||
if(pilot_isFlag(player, PILOT_HYPERSPACE) && !paused) {
|
||||
i = (int)player->ptimer - HYPERSPACE_FADEOUT;
|
||||
j = (int)SDL_GetTicks();
|
||||
if(i < j) {
|
||||
x = (double)(j-i) / HYPERSPACE_FADEOUT;
|
||||
glColor4d(1.,1.,1., x); // We'll | I'll, make this more effiecent later.
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2d(-gl_screen.w/2., -gl_screen.h/2.);
|
||||
glVertex2d(-gl_screen.w/2., gl_screen.h/2.);
|
||||
glVertex2d( gl_screen.w/2., gl_screen.h/2.);
|
||||
glVertex2d( gl_screen.w/2., -gl_screen.h/2.);
|
||||
glEnd();
|
||||
}
|
||||
i = (int)player->ptimer - HYPERSPACE_FADEOUT;
|
||||
j = (int)SDL_GetTicks();
|
||||
if(i < j) {
|
||||
x = (double)(j-i) / HYPERSPACE_FADEOUT;
|
||||
glColor4d(1.,1.,1., x); // We'll | I'll, make this more effiecent later.
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2d(-gl_screen.w/2., -gl_screen.h/2.);
|
||||
glVertex2d(-gl_screen.w/2., gl_screen.h/2.);
|
||||
glVertex2d( gl_screen.w/2., gl_screen.h/2.);
|
||||
glVertex2d( gl_screen.w/2., -gl_screen.h/2.);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -614,8 +614,8 @@ static void gui_renderPilot(const Pilot* p) {
|
||||
if(sy < 1.) sy = 1.;
|
||||
|
||||
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) &&
|
||||
((x*x + y*y) > (int)(gui.radar.w*gui.radar.w))))
|
||||
|| (ABS(y) > gui.radar.h/2.+sy))) || ((gui.radar.shape == RADAR_CIRCLE) &&
|
||||
((x*x + y*y) > (int)(gui.radar.w*gui.radar.w))))
|
||||
return; // Pilot isn't in range.
|
||||
|
||||
if(gui.radar.shape == RADAR_RECT) {
|
||||
@ -628,17 +628,17 @@ static void gui_renderPilot(const Pilot* p) {
|
||||
}
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
// Colours.
|
||||
if(p->id == player_target) COLOUR(cRadar_targ);
|
||||
else if(pilot_isDisabled(p)) COLOUR(cInert);
|
||||
else if(pilot_isFlag(p, PILOT_HOSTILE)) COLOUR(cHostile);
|
||||
else COLOUR(cNeutral);
|
||||
// Colours.
|
||||
if(p->id == player_target) COLOUR(cRadar_targ);
|
||||
else if(pilot_isDisabled(p)) COLOUR(cInert);
|
||||
else if(pilot_isFlag(p, PILOT_HOSTILE)) COLOUR(cHostile);
|
||||
else COLOUR(cNeutral);
|
||||
|
||||
// Image.
|
||||
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), MAX(y-sy, -h)); // Bottom right.
|
||||
glVertex2d(MAX(x-sx, -w), MAX(y-sy, -h)); // Bottom left.
|
||||
// Image.
|
||||
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), MAX(y-sy, -h)); // Bottom right.
|
||||
glVertex2d(MAX(x-sx, -w), MAX(y-sy, -h)); // Bottom left.
|
||||
glEnd();
|
||||
}
|
||||
|
||||
@ -647,15 +647,15 @@ static void gui_renderBar(const glColour* c, const Rect* r, const double w) {
|
||||
int x, y, sx, sy;
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
COLOUR(*c);
|
||||
x = r->x - gl_screen.w/2.;
|
||||
y = r->y - gl_screen.h/2.;
|
||||
sx = w * r->w;
|
||||
sy = r->h;
|
||||
glVertex2d(x, y);
|
||||
glVertex2d(x+sx, y);
|
||||
glVertex2d(x+sx, y-sy);
|
||||
glVertex2d(x, y-sy);
|
||||
COLOUR(*c);
|
||||
x = r->x - gl_screen.w/2.;
|
||||
y = r->y - gl_screen.h/2.;
|
||||
sx = w * r->w;
|
||||
sy = r->h;
|
||||
glVertex2d(x, y);
|
||||
glVertex2d(x+sx, y);
|
||||
glVertex2d(x+sx, y-sy);
|
||||
glVertex2d(x, y-sy);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
@ -727,14 +727,14 @@ int gui_load(const char* name) {
|
||||
}
|
||||
|
||||
static void rect_parse(const xmlNodePtr parent, double* x, double* y,
|
||||
double* w, double* h) {
|
||||
double* w, double* h) {
|
||||
xmlNodePtr cur;
|
||||
int param;
|
||||
|
||||
param = 0;
|
||||
|
||||
cur = parent->children;
|
||||
|
||||
|
||||
do {
|
||||
if(xml_isNode(cur, "x")) {
|
||||
if(x != NULL) {
|
||||
@ -779,7 +779,7 @@ static void rect_parse(const xmlNodePtr parent, double* x, double* y,
|
||||
|
||||
// Parse a gui node.
|
||||
#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) {
|
||||
xmlNodePtr cur, node;
|
||||
char* tmp, *tmp2;
|
||||
@ -810,8 +810,8 @@ static int gui_parse(const xmlNodePtr parent, const char* name) {
|
||||
|
||||
// Frame (based on gfx).
|
||||
vect_csetmin(&gui.frame,
|
||||
gl_screen.w - gui.gfx_frame->w, // x.
|
||||
gl_screen.h - gui.gfx_frame->h); // h.
|
||||
gl_screen.w - gui.gfx_frame->w, // x.
|
||||
gl_screen.h - gui.gfx_frame->h); // h.
|
||||
|
||||
// Let's parse the data now.
|
||||
node = parent->children;
|
||||
@ -850,19 +850,19 @@ static int gui_parse(const xmlNodePtr parent, const char* name) {
|
||||
do {
|
||||
if(xml_isNode(cur, "shield")) {
|
||||
rect_parse(cur, &gui.shield.x, &gui.shield.y,
|
||||
&gui.shield.w, &gui.shield.h);
|
||||
&gui.shield.w, &gui.shield.h);
|
||||
RELATIVIZE(gui.shield);
|
||||
}
|
||||
|
||||
|
||||
if(xml_isNode(cur, "armour")) {
|
||||
rect_parse(cur, &gui.armour.x, &gui.armour.y,
|
||||
&gui.armour.w, &gui.armour.h);
|
||||
&gui.armour.w, &gui.armour.h);
|
||||
RELATIVIZE(gui.armour);
|
||||
}
|
||||
|
||||
|
||||
if(xml_isNode(cur, "energy")) {
|
||||
rect_parse(cur, &gui.energy.x, &gui.energy.y,
|
||||
&gui.energy.w, &gui.energy.h);
|
||||
&gui.energy.w, &gui.energy.h);
|
||||
RELATIVIZE(gui.energy);
|
||||
}
|
||||
} while((cur = cur->next));
|
||||
@ -870,7 +870,7 @@ static int gui_parse(const xmlNodePtr parent, const char* name) {
|
||||
// Secondary weapon.
|
||||
else if(xml_isNode(node, "weapon")) {
|
||||
rect_parse(node, &gui.weapon.x, &gui.weapon.y,
|
||||
&gui.weapon.w, &gui.weapon.h);
|
||||
&gui.weapon.w, &gui.weapon.h);
|
||||
RELATIVIZE(gui.weapon);
|
||||
gui.weapon.y -= gl_defFont.h;
|
||||
}
|
||||
@ -883,23 +883,23 @@ static int gui_parse(const xmlNodePtr parent, const char* name) {
|
||||
RELATIVIZE(gui.target);
|
||||
gui.target.y -= SHIP_TARGET_H;
|
||||
}
|
||||
|
||||
|
||||
if(xml_isNode(cur, "name")) {
|
||||
rect_parse(cur, &gui.target_name.x, &gui.target_name.y, NULL, NULL);
|
||||
RELATIVIZE(gui.target_name);
|
||||
gui.target_name.y -= gl_defFont.h;
|
||||
}
|
||||
|
||||
|
||||
if(xml_isNode(cur, "faction")) {
|
||||
rect_parse(cur, &gui.target_faction.x, &gui.target_faction.y,
|
||||
NULL, NULL);
|
||||
NULL, NULL);
|
||||
RELATIVIZE(gui.target_faction);
|
||||
gui.target_faction.y -= gl_smallFont.h;
|
||||
}
|
||||
|
||||
if(xml_isNode(cur, "health")) {
|
||||
rect_parse(cur, &gui.target_health.x, &gui.target_health.y,
|
||||
NULL, NULL);
|
||||
NULL, NULL);
|
||||
RELATIVIZE(gui.target_health);
|
||||
gui.target_health.y -= gl_smallFont.h;
|
||||
}
|
||||
@ -926,25 +926,25 @@ void gui_free(void) {
|
||||
// Used in pilot.c
|
||||
// Basically uses keyboard input instead of AI input.
|
||||
void player_think(Pilot* player) {
|
||||
// Last I checked, the dead didn't think..
|
||||
if(pilot_isFlag(player, PILOT_DEAD)) return;
|
||||
// Last I checked, the dead didn't think..
|
||||
if(pilot_isFlag(player, PILOT_DEAD)) return;
|
||||
|
||||
// PLAYER_FACE will take over navigation.
|
||||
if(player_isFlag(PLAYER_FACE)) {
|
||||
if(player_target != PLAYER_ID)
|
||||
pilot_face(player,
|
||||
vect_angle(&player->solid->pos,
|
||||
&pilot_get(player_target)->solid->pos));
|
||||
else if(planet_target != -1)
|
||||
pilot_face(player,
|
||||
vect_angle(&player->solid->pos,
|
||||
&cur_system->planets[planet_target].pos));
|
||||
}
|
||||
if(player_isFlag(PLAYER_FACE)) {
|
||||
if(player_target != PLAYER_ID)
|
||||
pilot_face(player,
|
||||
vect_angle(&player->solid->pos,
|
||||
&pilot_get(player_target)->solid->pos));
|
||||
else if(planet_target != -1)
|
||||
pilot_face(player,
|
||||
vect_angle(&player->solid->pos,
|
||||
&cur_system->planets[planet_target].pos));
|
||||
}
|
||||
|
||||
// PLAYER_REVERSE will take over navigation.
|
||||
else if(player_isFlag(PLAYER_REVERSE) && (VMOD(player->solid->vel) > 0.))
|
||||
pilot_face(player, VANGLE(player->solid->vel) + M_PI);
|
||||
|
||||
|
||||
// Normal navigation sheme.
|
||||
else {
|
||||
player->solid->dir_vel = 0.;
|
||||
@ -956,25 +956,25 @@ void player_think(Pilot* player) {
|
||||
if(player_isFlag(PLAYER_SECONDARY)) // Needs a target.
|
||||
pilot_shoot(player, player_target, 1);
|
||||
|
||||
if(player_isFlag(PLAYER_AFTERBURNER))
|
||||
vect_pset(&player->solid->force,
|
||||
player->thrust * player->afterburner->outfit->u.afb.thrust_perc +
|
||||
player->afterburner->outfit->u.afb.thrust_abs, player->solid->dir);
|
||||
else
|
||||
vect_pset(&player->solid->force, player->thrust * player_acc,
|
||||
player->solid->dir);
|
||||
if(player_isFlag(PLAYER_AFTERBURNER))
|
||||
vect_pset(&player->solid->force,
|
||||
player->thrust * player->afterburner->outfit->u.afb.thrust_perc +
|
||||
player->afterburner->outfit->u.afb.thrust_abs, player->solid->dir);
|
||||
else
|
||||
vect_pset(&player->solid->force, player->thrust * player_acc,
|
||||
player->solid->dir);
|
||||
|
||||
// Set the listener stuff.
|
||||
sound_listener(player->solid->dir,
|
||||
player->solid->pos.x, player->solid->pos.y,
|
||||
player->solid->vel.x, player->solid->vel.y);
|
||||
}
|
||||
// Set the listener stuff.
|
||||
sound_listener(player->solid->dir,
|
||||
player->solid->pos.x, player->solid->pos.y,
|
||||
player->solid->vel.x, player->solid->vel.y);
|
||||
}
|
||||
|
||||
// Modify the radar resolution.
|
||||
void player_setRadarRel(int mod) {
|
||||
gui.radar.res += mod * RADAR_RES_INTERVAL;
|
||||
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;
|
||||
gui.radar.res += mod * RADAR_RES_INTERVAL;
|
||||
if(gui.radar.res > RADAR_RES_MAX) gui.radar.res = RADAR_RES_MAX;
|
||||
else if(gui.radar.res < RADAR_RES_MIN) gui.radar.res = RADAR_RES_MIN;
|
||||
|
||||
player_message("Radar set to %dx", (int)gui.radar.res);
|
||||
}
|
||||
@ -1007,7 +1007,7 @@ void player_secondaryNext(void) {
|
||||
// Cycle through planet targets.
|
||||
void player_targetPlanet(void) {
|
||||
hyperspace_target = -1;
|
||||
player_rmFlag(PLAYER_LANDACK);
|
||||
player_rmFlag(PLAYER_LANDACK);
|
||||
|
||||
if((planet_target == -1) && (cur_system->nplanets > 0)) {
|
||||
// No target.
|
||||
@ -1031,26 +1031,26 @@ void player_land(void) {
|
||||
}
|
||||
Planet* planet = &cur_system->planets[planet_target];
|
||||
if(planet_target >= 0) {
|
||||
if(!planet_hasService(planet, PLANET_SERVICE_LAND)) {
|
||||
player_message("You can't land here.");
|
||||
return;
|
||||
}
|
||||
else if(!player_isFlag(PLAYER_LANDACK)) {
|
||||
// No landing authorization.
|
||||
if(!areEnemies(player->faction, planet->faction)) {
|
||||
player_message("%s> Permission to land cleared.", planet->name);
|
||||
player_setFlag(PLAYER_LANDACK);
|
||||
} else {
|
||||
player_message("%s> Land request denied.", planet->name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(!planet_hasService(planet, PLANET_SERVICE_LAND)) {
|
||||
player_message("You can't land here.");
|
||||
return;
|
||||
}
|
||||
else if(!player_isFlag(PLAYER_LANDACK)) {
|
||||
// No landing authorization.
|
||||
if(!areEnemies(player->faction, planet->faction)) {
|
||||
player_message("%s> Permission to land cleared.", planet->name);
|
||||
player_setFlag(PLAYER_LANDACK);
|
||||
} else {
|
||||
player_message("%s> Land request denied.", planet->name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if(vect_dist(&player->solid->pos, &planet->pos) > planet->gfx_space->sw) {
|
||||
player_message("You are too far away to land on %s", planet->name);
|
||||
return;
|
||||
}
|
||||
else if((pow2(VX(player->solid->vel)) + pow2(VY(player->solid->vel))) >
|
||||
(double)pow2(MAX_HYPERSPACE_VEL)) {
|
||||
else if((pow2(VX(player->solid->vel)) + pow2(VY(player->solid->vel))) >
|
||||
(double)pow2(MAX_HYPERSPACE_VEL)) {
|
||||
player_message("You are going too fast to land on %s", planet->name);
|
||||
return;
|
||||
}
|
||||
@ -1060,26 +1060,26 @@ void player_land(void) {
|
||||
int i;
|
||||
int tp;
|
||||
double td, d;
|
||||
|
||||
|
||||
td = -1; // Temp distance.
|
||||
tp = -1; // Temp planet.
|
||||
for(i = 0; i < cur_system->nplanets; i++) {
|
||||
d = vect_dist(&player->solid->pos, &cur_system->planets[i].pos);
|
||||
if(planet_hasService(&cur_system->planets[i], PLANET_SERVICE_LAND) &&
|
||||
((tp == -1) || ((td == -1) || (td > d)))) {
|
||||
((tp == -1) || ((td == -1) || (td > d)))) {
|
||||
tp = i;
|
||||
td = d;
|
||||
}
|
||||
}
|
||||
planet_target = tp;
|
||||
player_rmFlag(PLAYER_LANDACK);
|
||||
player_land(); // Re-run land protocol.
|
||||
player_rmFlag(PLAYER_LANDACK);
|
||||
player_land(); // Re-run land protocol.
|
||||
}
|
||||
}
|
||||
|
||||
void player_targetHyperspace(void) {
|
||||
planet_target = -1; // Remove planet target.
|
||||
player_rmFlag(PLAYER_LANDACK); // Get rid of landing permission.
|
||||
player_rmFlag(PLAYER_LANDACK); // Get rid of landing permission.
|
||||
hyperspace_target++;
|
||||
|
||||
if(hyperspace_target >= cur_system->njumps)
|
||||
@ -1089,10 +1089,10 @@ void player_targetHyperspace(void) {
|
||||
// Actually attempt to jump into hyperspace.
|
||||
void player_jump(void) {
|
||||
if((hyperspace_target == -1) ||
|
||||
pilot_isFlag(player, PILOT_HYP_PREP) ||
|
||||
pilot_isFlag(player, PILOT_HYP_BEGIN) ||
|
||||
pilot_isFlag(player, PILOT_HYPERSPACE))
|
||||
return;
|
||||
pilot_isFlag(player, PILOT_HYP_PREP) ||
|
||||
pilot_isFlag(player, PILOT_HYP_BEGIN) ||
|
||||
pilot_isFlag(player, PILOT_HYPERSPACE))
|
||||
return;
|
||||
|
||||
int i = space_hyperspace(player);
|
||||
|
||||
@ -1111,7 +1111,7 @@ void player_brokeHyperspace(void) {
|
||||
|
||||
// Set position, pilot_update will handle the lowering of velocity.
|
||||
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.
|
||||
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.
|
||||
double player_faceHyperspace(void) {
|
||||
double a;
|
||||
a = ANGLE(systems_stack[cur_system->jumps[hyperspace_target]].pos.x -
|
||||
cur_system->pos.x,
|
||||
systems_stack[cur_system->jumps[hyperspace_target]].pos.y -
|
||||
cur_system->pos.y);
|
||||
|
||||
return pilot_face(player, a);
|
||||
double a;
|
||||
a = ANGLE(systems_stack[cur_system->jumps[hyperspace_target]].pos.x -
|
||||
cur_system->pos.x,
|
||||
systems_stack[cur_system->jumps[hyperspace_target]].pos.y -
|
||||
cur_system->pos.y);
|
||||
|
||||
return pilot_face(player, a);
|
||||
}
|
||||
|
||||
// Activate afterburner.
|
||||
void player_afterburn(void) {
|
||||
// TODO: Fancy effects.
|
||||
if(player->afterburner != NULL) {
|
||||
player_setFlag(PLAYER_AFTERBURNER);
|
||||
pilot_setFlag(player, PILOT_AFTERBURNER);
|
||||
}
|
||||
// TODO: Fancy effects.
|
||||
if(player->afterburner != NULL) {
|
||||
player_setFlag(PLAYER_AFTERBURNER);
|
||||
pilot_setFlag(player, PILOT_AFTERBURNER);
|
||||
}
|
||||
}
|
||||
|
||||
void player_afterburnOver(void) {
|
||||
if(player->afterburner != NULL) {
|
||||
player_rmFlag(PLAYER_AFTERBURNER);
|
||||
pilot_rmFlag(player, PILOT_AFTERBURNER);
|
||||
}
|
||||
if(player->afterburner != NULL) {
|
||||
player_rmFlag(PLAYER_AFTERBURNER);
|
||||
pilot_rmFlag(player, PILOT_AFTERBURNER);
|
||||
}
|
||||
}
|
||||
|
||||
// Take a screenshot.
|
||||
@ -1162,7 +1162,7 @@ void player_screenshot(void) {
|
||||
return;
|
||||
}
|
||||
snprintf(filename, PATH_MAX, "../screenshots/screenshot%03d.png",
|
||||
screenshot_cur);
|
||||
screenshot_cur);
|
||||
fp = fopen(filename, "r"); // Myeah, I know it's a horrible way to check.
|
||||
if(fp == NULL) done = 1;
|
||||
else {
|
||||
@ -1180,15 +1180,15 @@ void player_screenshot(void) {
|
||||
|
||||
// Player go pwned.
|
||||
void player_dead(void) {
|
||||
gui_xoff = 0.;
|
||||
gui_yoff = 0.;
|
||||
gui_xoff = 0.;
|
||||
gui_yoff = 0.;
|
||||
}
|
||||
|
||||
// Player blew up in a nice fireball.
|
||||
void player_destroyed(void) {
|
||||
vectcpy(&player_cam, &player->solid->pos);
|
||||
gl_bindCamera(&player_cam);
|
||||
player_setFlag(PLAYER_DESTROYED);
|
||||
player_timer = SDL_GetTicks() + 5000;
|
||||
vectcpy(&player_cam, &player->solid->pos);
|
||||
gl_bindCamera(&player_cam);
|
||||
player_setFlag(PLAYER_DESTROYED);
|
||||
player_timer = SDL_GetTicks() + 5000;
|
||||
}
|
||||
|
||||
|
18
src/player.h
18
src/player.h
@ -2,15 +2,15 @@
|
||||
#include "pilot.h"
|
||||
|
||||
// Flag definitions.
|
||||
#define PLAYER_TURN_LEFT (1<<0) // Player is turning left.
|
||||
#define PLAYER_TURN_RIGHT (1<<1) // Player is turning right.
|
||||
#define PLAYER_REVERSE (1<<2) // Player is facint opposite vel.
|
||||
#define PLAYER_AFTERBURNER (1<<3) // Player is burning it up.
|
||||
#define PLAYER_DESTROYED (1<<9) // Player goes BOOM!
|
||||
#define PLAYER_FACE (1<<10) // Player is facing target.
|
||||
#define PLAYER_PRIMARY (1<<11) // Player is shooting primary weapon.
|
||||
#define PLAYER_SECONDARY (1<<12) // Player is shooting secondary weapon.
|
||||
#define PLAYER_LANDACK (1<<13) // Player has permission to land.
|
||||
#define PLAYER_TURN_LEFT (1<<0) // Player is turning left.
|
||||
#define PLAYER_TURN_RIGHT (1<<1) // Player is turning right.
|
||||
#define PLAYER_REVERSE (1<<2) // Player is facint opposite vel.
|
||||
#define PLAYER_AFTERBURNER (1<<3) // Player is burning it up.
|
||||
#define PLAYER_DESTROYED (1<<9) // Player goes BOOM!
|
||||
#define PLAYER_FACE (1<<10) // Player is facing target.
|
||||
#define PLAYER_PRIMARY (1<<11) // Player is shooting primary weapon.
|
||||
#define PLAYER_SECONDARY (1<<12) // Player is shooting secondary weapon.
|
||||
#define PLAYER_LANDACK (1<<13) // Player has permission to land.
|
||||
|
||||
// Flag functions.
|
||||
#define player_isFlag(f) (player_flags & f)
|
||||
|
258
src/ship.c
258
src/ship.c
@ -33,7 +33,7 @@ Ship* ship_get(const char* name) {
|
||||
int i;
|
||||
for(i = 0; i < ships; i++)
|
||||
if(strcmp((tmp+i)->name, name)==0) break;
|
||||
|
||||
|
||||
if(i == ships) // Ship doesn't exist, game will probably crash now.
|
||||
WARN("Ship %s does not exist", name);
|
||||
|
||||
@ -42,37 +42,37 @@ Ship* ship_get(const char* name) {
|
||||
|
||||
// Get the ship's classname.
|
||||
static char* ship_classes[] = {
|
||||
"NULL",
|
||||
"Civialian Light", "Civilian Medium", "Civilian Heavy"
|
||||
"Military Light", "Military Medium", "Military Heavy"
|
||||
"Robotic Light", "Robotic Medium", "Robotic Heavy"
|
||||
"Hybrid Light", "Hybrid Medium", "Hybrid Heavy"
|
||||
"NULL",
|
||||
"Civialian Light", "Civilian Medium", "Civilian Heavy"
|
||||
"Military Light", "Military Medium", "Military Heavy"
|
||||
"Robotic Light", "Robotic Medium", "Robotic Heavy"
|
||||
"Hybrid Light", "Hybrid Medium", "Hybrid Heavy"
|
||||
|
||||
};
|
||||
|
||||
// Return all the ships in text form.
|
||||
char** ship_getTech(int* n, const int* tech, const int techmax) {
|
||||
int i, j;
|
||||
char** shipnames = malloc(sizeof(Ship*) * ships);
|
||||
int i, j;
|
||||
char** shipnames = malloc(sizeof(Ship*) * ships);
|
||||
|
||||
*n = 0;
|
||||
for(i = 0; i < ships; i++)
|
||||
if(ship_stack[i].tech <= tech[0]) {
|
||||
shipnames[*n] = strdup(ship_stack[i].name);
|
||||
(*n)++;
|
||||
} else {
|
||||
for(j = 0; j < techmax; j++)
|
||||
if(tech[j] == ship_stack[i].tech) {
|
||||
shipnames[*n] = strdup(ship_stack[i].name);
|
||||
(*n)++;
|
||||
*n = 0;
|
||||
for(i = 0; i < ships; i++)
|
||||
if(ship_stack[i].tech <= tech[0]) {
|
||||
shipnames[*n] = strdup(ship_stack[i].name);
|
||||
(*n)++;
|
||||
} else {
|
||||
for(j = 0; j < techmax; j++)
|
||||
if(tech[j] == ship_stack[i].tech) {
|
||||
shipnames[*n] = strdup(ship_stack[i].name);
|
||||
(*n)++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return shipnames;
|
||||
|
||||
return shipnames;
|
||||
}
|
||||
|
||||
char* ship_class(Ship* s) {
|
||||
return ship_classes[s->class];
|
||||
return ship_classes[s->class];
|
||||
}
|
||||
|
||||
static Ship* ship_parse(xmlNodePtr parent) {
|
||||
@ -81,7 +81,7 @@ static Ship* ship_parse(xmlNodePtr parent) {
|
||||
ShipOutfit* otmp, *ocur;
|
||||
|
||||
char str[PATH_MAX] = "\0";
|
||||
char* stmp;
|
||||
char* stmp;
|
||||
|
||||
tmp->name = xml_nodeProp(parent, "name");
|
||||
if(tmp->name == NULL) WARN("Ship in "SHIP_DATA" has invalid or no name");
|
||||
@ -91,31 +91,31 @@ static Ship* ship_parse(xmlNodePtr parent) {
|
||||
do {
|
||||
// Load all the data.
|
||||
if(xml_isNode(node,"GFX")) {
|
||||
snprintf(str, strlen(xml_get(node)) +
|
||||
sizeof(SHIP_GFX) + sizeof(SHIP_EXT),
|
||||
SHIP_GFX"%s"SHIP_EXT, xml_get(node));
|
||||
snprintf(str, strlen(xml_get(node)) +
|
||||
sizeof(SHIP_GFX) + sizeof(SHIP_EXT),
|
||||
SHIP_GFX"%s"SHIP_EXT, xml_get(node));
|
||||
tmp->gfx_space = gl_newSprite(str, 6, 6);
|
||||
// Target.
|
||||
snprintf(str, strlen(xml_get(node)) +
|
||||
sizeof(SHIP_GFX)+sizeof(SHIP_TARGET)+sizeof(SHIP_EXT),
|
||||
SHIP_GFX"%s"SHIP_TARGET SHIP_EXT, xml_get(node));
|
||||
sizeof(SHIP_GFX)+sizeof(SHIP_TARGET)+sizeof(SHIP_EXT),
|
||||
SHIP_GFX"%s"SHIP_TARGET SHIP_EXT, xml_get(node));
|
||||
tmp->gfx_target = gl_newImage(str);
|
||||
|
||||
}
|
||||
else if(xml_isNode(node, "GUI"))
|
||||
tmp->gui = strdup(xml_get(node));
|
||||
else if(xml_isNode(node, "sound"))
|
||||
tmp->sound = sound_get(xml_get(node));
|
||||
else if(xml_isNode(node, "sound"))
|
||||
tmp->sound = sound_get(xml_get(node));
|
||||
else if(xml_isNode(node, "class"))
|
||||
tmp->class = xml_getInt(node);
|
||||
else if(xml_isNode(node, "price"))
|
||||
tmp->price = xml_getInt(node);
|
||||
else if(xml_isNode(node, "tech"))
|
||||
tmp->tech = xml_getInt(node);
|
||||
else if(xml_isNode(node, "fabricator"))
|
||||
tmp->fabricator = strdup(xml_get(node));
|
||||
else if(xml_isNode(node, "description"))
|
||||
tmp->description = strdup(xml_get(node));
|
||||
else if(xml_isNode(node, "price"))
|
||||
tmp->price = xml_getInt(node);
|
||||
else if(xml_isNode(node, "tech"))
|
||||
tmp->tech = xml_getInt(node);
|
||||
else if(xml_isNode(node, "fabricator"))
|
||||
tmp->fabricator = strdup(xml_get(node));
|
||||
else if(xml_isNode(node, "description"))
|
||||
tmp->description = strdup(xml_get(node));
|
||||
else if(xml_isNode(node, "movement")) {
|
||||
cur = node->children;
|
||||
do {
|
||||
@ -142,19 +142,19 @@ static Ship* ship_parse(xmlNodePtr parent) {
|
||||
tmp->shield_regen = (double)(xml_getInt(cur))/60.0;
|
||||
else if(xml_isNode(cur, "energy_regen"))
|
||||
tmp->energy_regen = (double)(xml_getInt(cur))/60.0;
|
||||
} while((cur = cur->next));
|
||||
}
|
||||
else if(xml_isNode(node, "characteristics")) {
|
||||
cur = node->children;
|
||||
do {
|
||||
if(xml_isNode(cur, "crew"))
|
||||
tmp->crew = xml_getInt(cur);
|
||||
else if(xml_isNode(cur, "mass"))
|
||||
tmp->mass = (double)xml_getInt(cur);
|
||||
else if(xml_isNode(cur, "cap_weapon"))
|
||||
tmp->cap_weapon = xml_getInt(cur);
|
||||
else if(xml_isNode(cur, "cap_cargo"))
|
||||
tmp->cap_cargo = xml_getInt(cur);
|
||||
} while((cur = cur->next));
|
||||
}
|
||||
else if(xml_isNode(node, "characteristics")) {
|
||||
cur = node->children;
|
||||
do {
|
||||
if(xml_isNode(cur, "crew"))
|
||||
tmp->crew = xml_getInt(cur);
|
||||
else if(xml_isNode(cur, "mass"))
|
||||
tmp->mass = (double)xml_getInt(cur);
|
||||
else if(xml_isNode(cur, "cap_weapon"))
|
||||
tmp->cap_weapon = xml_getInt(cur);
|
||||
else if(xml_isNode(cur, "cap_cargo"))
|
||||
tmp->cap_cargo = xml_getInt(cur);
|
||||
} while((cur = cur->next));
|
||||
}
|
||||
else if(xml_isNode(node, "outfits")) {
|
||||
@ -166,7 +166,7 @@ static Ship* ship_parse(xmlNodePtr parent) {
|
||||
stmp = xml_nodeProp(cur, "quantity");
|
||||
if(!stmp)
|
||||
WARN("Ship '%s' is missing tag 'quantity for outfit '%s'",
|
||||
tmp->name, otmp->data->name);
|
||||
tmp->name, otmp->data->name);
|
||||
otmp->quantity = atoi(stmp);
|
||||
free(stmp);
|
||||
otmp->next = NULL;
|
||||
@ -180,31 +180,31 @@ static Ship* ship_parse(xmlNodePtr parent) {
|
||||
} while((cur = cur->next));
|
||||
}
|
||||
} while((node = node->next));
|
||||
|
||||
|
||||
tmp->thrust *= tmp->mass; // Helps keep number sane.
|
||||
|
||||
#define MELEMENT(o,s) if(o) WARN("Ship '%s' missing '"s"' element", tmp->name)
|
||||
MELEMENT(tmp->name == NULL, "name");
|
||||
MELEMENT(tmp->gfx_space == NULL, "GFX");
|
||||
MELEMENT(tmp->gui == NULL, "GUI");
|
||||
MELEMENT(tmp->class==0, "class");
|
||||
MELEMENT(tmp->price==0, "price");
|
||||
MELEMENT(tmp->tech==0, "tech");
|
||||
MELEMENT(tmp->fabricator==0, "fabricator");
|
||||
MELEMENT(tmp->description==0, "description");
|
||||
MELEMENT(tmp->thrust==0, "thrust");
|
||||
MELEMENT(tmp->turn==0, "turn");
|
||||
MELEMENT(tmp->speed==0, "speed");
|
||||
MELEMENT(tmp->armour==0, "armour");
|
||||
MELEMENT(tmp->armour_regen==0, "armour_regen");
|
||||
MELEMENT(tmp->shield==0, "shield");
|
||||
MELEMENT(tmp->shield_regen==0, "shield_regen");
|
||||
MELEMENT(tmp->energy==0, "energy");
|
||||
MELEMENT(tmp->energy_regen==0, "energt_regen");
|
||||
MELEMENT(tmp->crew==0, "crew");
|
||||
MELEMENT(tmp->mass==0, "mass");
|
||||
MELEMENT(tmp->cap_cargo==0, "cap_cargo");
|
||||
MELEMENT(tmp->cap_weapon==0, "cap_weapon");
|
||||
MELEMENT(tmp->gui == NULL, "GUI");
|
||||
MELEMENT(tmp->class==0, "class");
|
||||
MELEMENT(tmp->price==0, "price");
|
||||
MELEMENT(tmp->tech==0, "tech");
|
||||
MELEMENT(tmp->fabricator==0, "fabricator");
|
||||
MELEMENT(tmp->description==0, "description");
|
||||
MELEMENT(tmp->thrust==0, "thrust");
|
||||
MELEMENT(tmp->turn==0, "turn");
|
||||
MELEMENT(tmp->speed==0, "speed");
|
||||
MELEMENT(tmp->armour==0, "armour");
|
||||
MELEMENT(tmp->armour_regen==0, "armour_regen");
|
||||
MELEMENT(tmp->shield==0, "shield");
|
||||
MELEMENT(tmp->shield_regen==0, "shield_regen");
|
||||
MELEMENT(tmp->energy==0, "energy");
|
||||
MELEMENT(tmp->energy_regen==0, "energt_regen");
|
||||
MELEMENT(tmp->crew==0, "crew");
|
||||
MELEMENT(tmp->mass==0, "mass");
|
||||
MELEMENT(tmp->cap_cargo==0, "cap_cargo");
|
||||
MELEMENT(tmp->cap_weapon==0, "cap_weapon");
|
||||
#undef MELEMENT
|
||||
|
||||
return tmp;
|
||||
@ -216,7 +216,7 @@ int ships_load(void) {
|
||||
|
||||
xmlNodePtr node;
|
||||
xmlDocPtr doc = xmlParseMemory(buf, bufsize);
|
||||
|
||||
|
||||
Ship* tmp = NULL;
|
||||
|
||||
node = doc->xmlChildrenNode; // Ships node.
|
||||
@ -230,7 +230,7 @@ int ships_load(void) {
|
||||
ERR("Malformed "SHIP_DATA" file: Does not contain elements");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
do {
|
||||
if(node->type == XML_NODE_START && strcmp((char*)node->name, XML_SHIP)==0) {
|
||||
tmp = ship_parse(node);
|
||||
@ -244,7 +244,7 @@ int ships_load(void) {
|
||||
free(buf);
|
||||
xmlCleanupParser();
|
||||
|
||||
DEBUG("Loaded %d ship%s", ships, (ships==1) ? "" : "s");
|
||||
DEBUG("Loaded %d ship%s", ships, (ships==1) ? "" : "s");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -255,7 +255,7 @@ void ships_free(void) {
|
||||
for(i = 0; i < ships; i++) {
|
||||
// Free stored strings.
|
||||
if((ship_stack+i)->name) free(ship_stack[i].name);
|
||||
if((ship_stack+i)->description) free(ship_stack[i].description);
|
||||
if((ship_stack+i)->description) free(ship_stack[i].description);
|
||||
if((ship_stack+i)->gui) free(ship_stack[i].gui);
|
||||
so = (ship_stack+i)->outfit;
|
||||
while(so) { // free the ship outfit.
|
||||
@ -272,62 +272,62 @@ void ships_free(void) {
|
||||
|
||||
// Used to visualize the ships status.
|
||||
void ship_view(char* shipname) {
|
||||
Ship* s;
|
||||
char buf[1024];
|
||||
unsigned int wid;
|
||||
wid = window_create(shipname, -1, -1, VIEW_WIDTH, VIEW_HEIGHT);
|
||||
s = ship_get(shipname);
|
||||
Ship* s;
|
||||
char buf[1024];
|
||||
unsigned int wid;
|
||||
wid = window_create(shipname, -1, -1, VIEW_WIDTH, VIEW_HEIGHT);
|
||||
s = ship_get(shipname);
|
||||
|
||||
window_addText(wid, 20, 0, 100, VIEW_HEIGHT-40,
|
||||
0, "txtLabel", &gl_smallFont, &cDConsole,
|
||||
"Name:\n"
|
||||
"Class:\n"
|
||||
"Crew:\n"
|
||||
"Mass:\n"
|
||||
"\n"
|
||||
"Thrust:\n"
|
||||
"Max Speed:\n"
|
||||
"Turn:\n"
|
||||
"\n"
|
||||
"Shield:\n"
|
||||
"Armour:\n"
|
||||
"Energy:\n"
|
||||
"\n"
|
||||
"Weapon Space:\n"
|
||||
"Cargo Space:\n");
|
||||
|
||||
snprintf(buf, 1024,
|
||||
"%s\n"
|
||||
"%s\n"
|
||||
"%d\n"
|
||||
"%d Tons\n"
|
||||
"\n"
|
||||
"%.2f MN\n"
|
||||
"%.2f M/s\n"
|
||||
"%.2f Grad/s\n"
|
||||
"\n"
|
||||
"%.2f MJ (%.2f MJ/s)\n)"
|
||||
"%.2f MJ (%.2f MJ/s)\n)"
|
||||
"%.2f MJ (%.2f MJ/s)\n)"
|
||||
"\n"
|
||||
"%d Tons\n"
|
||||
"%d Tons\n",
|
||||
s->name, ship_class(s), s->crew, s->mass,
|
||||
s->thrust/s->mass, s->speed, s->turn,
|
||||
s->shield, s->shield_regen, s->armour, s->armour_regen,
|
||||
s->energy, s->energy_regen, s->cap_weapon, s->cap_cargo);
|
||||
|
||||
window_addText(wid, 120, 0, VIEW_WIDTH-140, VIEW_HEIGHT-40,
|
||||
0, "txtProperties", &gl_smallFont, &cBlack, buf);
|
||||
|
||||
// Close the button.
|
||||
snprintf(buf, 37, "close%s", shipname);
|
||||
window_addButton(wid, -20, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
buf, "Close", ship_view_close);
|
||||
window_addText(wid, 20, 0, 100, VIEW_HEIGHT-40,
|
||||
0, "txtLabel", &gl_smallFont, &cDConsole,
|
||||
"Name:\n"
|
||||
"Class:\n"
|
||||
"Crew:\n"
|
||||
"Mass:\n"
|
||||
"\n"
|
||||
"Thrust:\n"
|
||||
"Max Speed:\n"
|
||||
"Turn:\n"
|
||||
"\n"
|
||||
"Shield:\n"
|
||||
"Armour:\n"
|
||||
"Energy:\n"
|
||||
"\n"
|
||||
"Weapon Space:\n"
|
||||
"Cargo Space:\n");
|
||||
|
||||
snprintf(buf, 1024,
|
||||
"%s\n"
|
||||
"%s\n"
|
||||
"%d\n"
|
||||
"%d Tons\n"
|
||||
"\n"
|
||||
"%.2f MN\n"
|
||||
"%.2f M/s\n"
|
||||
"%.2f Grad/s\n"
|
||||
"\n"
|
||||
"%.2f MJ (%.2f MJ/s)\n)"
|
||||
"%.2f MJ (%.2f MJ/s)\n)"
|
||||
"%.2f MJ (%.2f MJ/s)\n)"
|
||||
"\n"
|
||||
"%d Tons\n"
|
||||
"%d Tons\n",
|
||||
s->name, ship_class(s), s->crew, s->mass,
|
||||
s->thrust/s->mass, s->speed, s->turn,
|
||||
s->shield, s->shield_regen, s->armour, s->armour_regen,
|
||||
s->energy, s->energy_regen, s->cap_weapon, s->cap_cargo);
|
||||
|
||||
window_addText(wid, 120, 0, VIEW_WIDTH-140, VIEW_HEIGHT-40,
|
||||
0, "txtProperties", &gl_smallFont, &cBlack, buf);
|
||||
|
||||
// Close the button.
|
||||
snprintf(buf, 37, "close%s", shipname);
|
||||
window_addButton(wid, -20, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
buf, "Close", ship_view_close);
|
||||
}
|
||||
|
||||
static void ship_view_close(char* btn) {
|
||||
window_destroy(window_get(btn+5)); // "closefoo -> Foo"
|
||||
window_destroy(window_get(btn+5)); // "closefoo -> Foo"
|
||||
}
|
||||
|
||||
|
38
src/ship.h
38
src/ship.h
@ -7,20 +7,20 @@
|
||||
#define SHIP_TARGET_W 128
|
||||
#define SHIP_TARGET_H 96
|
||||
|
||||
typedef enum ShipClass_ {
|
||||
typedef enum ShipClass_ {
|
||||
SHIP_CLASS_NULL = 0,
|
||||
SHIP_CLASS_CIV_LIGHT = 1,
|
||||
SHIP_CLASS_CIV_MEDIUM = 2,
|
||||
SHIP_CLASS_CIV_HEAVY = 3,
|
||||
SHIP_CLASS_MIL_LIGHT = 4,
|
||||
SHIP_CLASS_MIL_MEDIUM = 5,
|
||||
SHIP_CLASS_MIL_HEAVY = 6,
|
||||
SHIP_CLASS_ROB_LIGHT = 7,
|
||||
SHIP_CLASS_ROB_MEDIUM = 8,
|
||||
SHIP_CLASS_ROB_HEAVY = 9,
|
||||
SHIP_CLASS_HYB_LIGHT = 10,
|
||||
SHIP_CLASS_HYB_MEDIUM = 11,
|
||||
SHIP_CLASS_HYB_HEAVY = 12
|
||||
SHIP_CLASS_MIL_LIGHT = 4,
|
||||
SHIP_CLASS_MIL_MEDIUM = 5,
|
||||
SHIP_CLASS_MIL_HEAVY = 6,
|
||||
SHIP_CLASS_ROB_LIGHT = 7,
|
||||
SHIP_CLASS_ROB_MEDIUM = 8,
|
||||
SHIP_CLASS_ROB_HEAVY = 9,
|
||||
SHIP_CLASS_HYB_LIGHT = 10,
|
||||
SHIP_CLASS_HYB_MEDIUM = 11,
|
||||
SHIP_CLASS_HYB_HEAVY = 12
|
||||
} ShipClass;
|
||||
|
||||
// Small wrapper for the outfits.
|
||||
@ -36,11 +36,11 @@ typedef struct Ship_ {
|
||||
char* name; // Ship name.
|
||||
ShipClass class; // Ship class.
|
||||
|
||||
// Store stuff.
|
||||
int price; // Price!
|
||||
int tech;
|
||||
char* fabricator; // Manufacturer.
|
||||
char* description; // Sales pitch.
|
||||
// Store stuff.
|
||||
int price; // Price!
|
||||
int tech;
|
||||
char* fabricator; // Manufacturer.
|
||||
char* description; // Sales pitch.
|
||||
|
||||
// Movement.
|
||||
double thrust, turn, speed;
|
||||
@ -51,9 +51,9 @@ typedef struct Ship_ {
|
||||
// GUI interface.
|
||||
char* gui;
|
||||
|
||||
// Sound.
|
||||
ALuint sound;
|
||||
|
||||
// Sound.
|
||||
ALuint sound;
|
||||
|
||||
// Characteristics.
|
||||
int crew;
|
||||
int mass;
|
||||
@ -65,7 +65,7 @@ typedef struct Ship_ {
|
||||
|
||||
// Capacity.
|
||||
int cap_cargo, cap_weapon;
|
||||
|
||||
|
||||
// Outfits
|
||||
ShipOutfit* outfit;
|
||||
} Ship;
|
||||
|
518
src/sound.c
518
src/sound.c
@ -23,8 +23,8 @@
|
||||
|
||||
// Give the buffers a name.
|
||||
typedef struct alSound_ {
|
||||
char* name; // Buffers name.
|
||||
ALuint buffer; // Associated OpenAL buffer.
|
||||
char* name; // Buffers name.
|
||||
ALuint buffer; // Associated OpenAL buffer.
|
||||
} alSound;
|
||||
|
||||
#define VOICE_PLAYING (1<<0) // Voice is playing.
|
||||
@ -60,371 +60,371 @@ static void sound_free(alSound* snd);
|
||||
static int voice_getSource(alVoice* voc);
|
||||
|
||||
int sound_init(void) {
|
||||
int ret = 0;
|
||||
int ret = 0;
|
||||
|
||||
sound_lock = SDL_CreateMutex();
|
||||
sound_lock = SDL_CreateMutex();
|
||||
|
||||
SDL_mutexP(sound_lock);
|
||||
const ALchar* device = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
|
||||
DEBUG("OpenAL using device '%s'", device);
|
||||
// Open the default device.
|
||||
al_device = alcOpenDevice(NULL);
|
||||
if(al_device == NULL) {
|
||||
WARN("Unable to open default sound device");
|
||||
ret = -1;
|
||||
goto snderr_dev;
|
||||
}
|
||||
SDL_mutexP(sound_lock);
|
||||
const ALchar* device = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
|
||||
DEBUG("OpenAL using device '%s'", device);
|
||||
// Open the default device.
|
||||
al_device = alcOpenDevice(NULL);
|
||||
if(al_device == NULL) {
|
||||
WARN("Unable to open default sound device");
|
||||
ret = -1;
|
||||
goto snderr_dev;
|
||||
}
|
||||
|
||||
// Create the OpenAL context.
|
||||
al_context = alcCreateContext(al_device, NULL);
|
||||
if(sound_lock == NULL) {
|
||||
WARN("Unable to create OpenAL context");
|
||||
ret = -2;
|
||||
goto snderr_ctx;
|
||||
}
|
||||
// Create the OpenAL context.
|
||||
al_context = alcCreateContext(al_device, NULL);
|
||||
if(sound_lock == NULL) {
|
||||
WARN("Unable to create OpenAL context");
|
||||
ret = -2;
|
||||
goto snderr_ctx;
|
||||
}
|
||||
|
||||
// Clear the errors.
|
||||
alGetError();
|
||||
// Clear the errors.
|
||||
alGetError();
|
||||
|
||||
// Set active context.
|
||||
if(alcMakeContextCurrent(al_context)==AL_FALSE) {
|
||||
WARN("Failure to set default context");
|
||||
ret = -4;
|
||||
goto snderr_act;
|
||||
}
|
||||
// Set active context.
|
||||
if(alcMakeContextCurrent(al_context)==AL_FALSE) {
|
||||
WARN("Failure to set default context");
|
||||
ret = -4;
|
||||
goto snderr_act;
|
||||
}
|
||||
|
||||
// Set the master gain.
|
||||
alListenerf(AL_GAIN, .1);
|
||||
// Set the master gain.
|
||||
alListenerf(AL_GAIN, .1);
|
||||
|
||||
// Set the distance model.
|
||||
alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
|
||||
// Set the distance model.
|
||||
alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
|
||||
|
||||
SDL_mutexV(sound_lock);
|
||||
SDL_mutexV(sound_lock);
|
||||
|
||||
// Load up all the sounds.
|
||||
sound_makeList();
|
||||
// Load up all the sounds.
|
||||
sound_makeList();
|
||||
|
||||
// Start the music server.
|
||||
music_init();
|
||||
music_player = SDL_CreateThread(music_thread, NULL);
|
||||
// Start the music server.
|
||||
music_init();
|
||||
music_player = SDL_CreateThread(music_thread, NULL);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
snderr_act:
|
||||
alcDestroyContext(al_context);
|
||||
alcDestroyContext(al_context);
|
||||
snderr_ctx:
|
||||
al_context = NULL;
|
||||
alcCloseDevice(al_device);
|
||||
al_context = NULL;
|
||||
alcCloseDevice(al_device);
|
||||
snderr_dev:
|
||||
al_device = NULL;
|
||||
SDL_mutexV(sound_lock);
|
||||
SDL_DestroyMutex(sound_lock);
|
||||
sound_lock = NULL;
|
||||
return ret;
|
||||
al_device = NULL;
|
||||
SDL_mutexV(sound_lock);
|
||||
SDL_DestroyMutex(sound_lock);
|
||||
sound_lock = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// Clean up after the sound system.
|
||||
void sound_exit(void) {
|
||||
int i;
|
||||
// Free the sounds.
|
||||
for(i = 0; i < nsound_list; i++)
|
||||
sound_free(&sound_list[i]);
|
||||
free(sound_list);
|
||||
sound_list = NULL;
|
||||
nsound_list = 0;
|
||||
int i;
|
||||
// Free the sounds.
|
||||
for(i = 0; i < nsound_list; i++)
|
||||
sound_free(&sound_list[i]);
|
||||
free(sound_list);
|
||||
sound_list = NULL;
|
||||
nsound_list = 0;
|
||||
|
||||
// Must stop the music before killing it,
|
||||
// then thread should commit suicide.
|
||||
if(music_player) {
|
||||
music_stop();
|
||||
music_kill();
|
||||
SDL_WaitThread(music_player, NULL);
|
||||
music_exit();
|
||||
}
|
||||
|
||||
if(sound_lock) {
|
||||
SDL_mutexP(sound_lock);
|
||||
|
||||
if(al_context) {
|
||||
alcMakeContextCurrent(NULL);
|
||||
alcDestroyContext(al_context);
|
||||
// Must stop the music before killing it,
|
||||
// then thread should commit suicide.
|
||||
if(music_player) {
|
||||
music_stop();
|
||||
music_kill();
|
||||
SDL_WaitThread(music_player, NULL);
|
||||
music_exit();
|
||||
}
|
||||
if(al_device) alcCloseDevice(al_device);
|
||||
|
||||
SDL_mutexV(sound_lock);
|
||||
SDL_DestroyMutex(sound_lock);
|
||||
}
|
||||
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);
|
||||
SDL_DestroyMutex(sound_lock);
|
||||
}
|
||||
}
|
||||
|
||||
// Get the buffer to sound of [name].
|
||||
ALuint sound_get(char* name) {
|
||||
if(sound_lock == NULL) return 0;
|
||||
if(sound_lock == NULL) return 0;
|
||||
|
||||
int i;
|
||||
for(i = 0; i < nsound_list; i++)
|
||||
if(strcmp(name, sound_list[i].name)==0)
|
||||
return sound_list[i].buffer;
|
||||
WARN("Sound '%s' not found in sound list", name);
|
||||
return 0;
|
||||
int i;
|
||||
for(i = 0; i < nsound_list; i++)
|
||||
if(strcmp(name, sound_list[i].name)==0)
|
||||
return sound_list[i].buffer;
|
||||
WARN("Sound '%s' not found in sound list", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Make list of available sounds.
|
||||
static int sound_makeList(void) {
|
||||
if(sound_lock == NULL) return 0;
|
||||
if(sound_lock == NULL) return 0;
|
||||
|
||||
char** files;
|
||||
uint32_t nfiles, i;
|
||||
char tmp[64];
|
||||
int len;
|
||||
char** files;
|
||||
uint32_t nfiles, i;
|
||||
char tmp[64];
|
||||
int len;
|
||||
|
||||
// Get the file list.
|
||||
files = pack_listfiles(data, &nfiles);
|
||||
// Get the file list.
|
||||
files = pack_listfiles(data, &nfiles);
|
||||
|
||||
// Load the profiles.
|
||||
for(i = 0; i < nfiles; i++)
|
||||
if((strncmp(files[i], SOUND_PREFIX, strlen(SOUND_PREFIX))==0) &&
|
||||
(strncmp(files[i] + strlen(files[i]) - strlen(SOUND_SUFFIX),
|
||||
SOUND_SUFFIX, strlen(SOUND_SUFFIX))==0)) {
|
||||
|
||||
// Expand the selection size.
|
||||
sound_list = realloc(sound_list, ++nsound_list * sizeof(alSound));
|
||||
// Load the profiles.
|
||||
for(i = 0; i < nfiles; i++)
|
||||
if((strncmp(files[i], SOUND_PREFIX, strlen(SOUND_PREFIX))==0) &&
|
||||
(strncmp(files[i] + strlen(files[i]) - strlen(SOUND_SUFFIX),
|
||||
SOUND_SUFFIX, strlen(SOUND_SUFFIX))==0)) {
|
||||
|
||||
// Remove the prefix and suffix.
|
||||
len = strlen(files[i]) - strlen(SOUND_SUFFIX SOUND_PREFIX);
|
||||
strncpy(tmp, files[i] + strlen(SOUND_PREFIX), len);
|
||||
tmp[len] = '\0';
|
||||
// Expand the selection size.
|
||||
sound_list = realloc(sound_list, ++nsound_list * sizeof(alSound));
|
||||
|
||||
// give it the new name.
|
||||
sound_list[nsound_list-1].name = strdup(tmp);
|
||||
sound_load(&sound_list[nsound_list-1].buffer, files[i]);
|
||||
}
|
||||
|
||||
// Free the char* allocated by pack.
|
||||
for(i = 0; i < nfiles; i++)
|
||||
free(files[i]);
|
||||
free(files);
|
||||
// Remove the prefix and suffix.
|
||||
len = strlen(files[i]) - strlen(SOUND_SUFFIX SOUND_PREFIX);
|
||||
strncpy(tmp, files[i] + strlen(SOUND_PREFIX), len);
|
||||
tmp[len] = '\0';
|
||||
|
||||
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.
|
||||
static int sound_load(ALuint* buffer, char* filename) {
|
||||
if(sound_lock == NULL) return 0;
|
||||
if(sound_lock == NULL) return 0;
|
||||
|
||||
void* wavdata;
|
||||
unsigned int size;
|
||||
ALenum err;
|
||||
void* wavdata;
|
||||
unsigned int size;
|
||||
ALenum err;
|
||||
|
||||
// Get the file data buffer from the packfile.
|
||||
wavdata = pack_readfile(DATA, filename, &size);
|
||||
// Get the file data buffer from the packfile.
|
||||
wavdata = pack_readfile(DATA, filename, &size);
|
||||
|
||||
SDL_mutexP(sound_lock);
|
||||
SDL_mutexP(sound_lock);
|
||||
|
||||
// Bind to OpenAL buffer.
|
||||
alGenBuffers(1, buffer);
|
||||
alBufferData(*buffer, AL_FORMAT_MONO16, wavdata, size, 22050);
|
||||
// Bind to OpenAL buffer.
|
||||
alGenBuffers(1, buffer);
|
||||
alBufferData(*buffer, AL_FORMAT_MONO16, wavdata, size, 22050);
|
||||
|
||||
// Errors?
|
||||
if((err = alGetError()) != AL_NO_ERROR) {
|
||||
WARN("OpenAL erro '%d' loading sound '%s'.", err, filename);
|
||||
// Errors?
|
||||
if((err = alGetError()) != AL_NO_ERROR) {
|
||||
WARN("OpenAL erro '%d' loading sound '%s'.", err, filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDL_mutexV(sound_lock);
|
||||
|
||||
// Finish up.
|
||||
free(wavdata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDL_mutexV(sound_lock);
|
||||
|
||||
// Finish up.
|
||||
free(wavdata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sound_free(alSound* snd) {
|
||||
if(sound_lock) return;
|
||||
if(sound_lock) return;
|
||||
|
||||
SDL_mutexP(sound_lock);
|
||||
SDL_mutexP(sound_lock);
|
||||
|
||||
if(snd->name) free(snd->name);
|
||||
alDeleteBuffers(1, &snd->buffer);
|
||||
if(snd->name) free(snd->name);
|
||||
alDeleteBuffers(1, &snd->buffer);
|
||||
|
||||
SDL_mutexV(sound_lock);
|
||||
SDL_mutexV(sound_lock);
|
||||
}
|
||||
|
||||
// Update the sounds and prioritize them.
|
||||
void sound_update(void) {
|
||||
if(sound_lock == NULL) return;
|
||||
int i;
|
||||
|
||||
// TODO: Prioritize the things.
|
||||
if(sound_lock == NULL) return;
|
||||
int i;
|
||||
|
||||
SDL_mutexP(sound_lock);
|
||||
// TODO: Prioritize the things.
|
||||
|
||||
for(i = 0; i < nvoice_stack; i++) {
|
||||
if(voice_is(voice_stack[i], VOICE_PLAYING)) {
|
||||
// Update position.
|
||||
alSource3f(voice_stack[i]->source, AL_POSITION,
|
||||
voice_stack[i]->px, voice_stack[i]->py, 0.);
|
||||
//alSource3f(voice_stack[i]->source, AL_VELOCITY,
|
||||
SDL_mutexP(sound_lock);
|
||||
|
||||
for(i = 0; i < nvoice_stack; i++) {
|
||||
if(voice_is(voice_stack[i], VOICE_PLAYING)) {
|
||||
// Update position.
|
||||
alSource3f(voice_stack[i]->source, AL_POSITION,
|
||||
voice_stack[i]->px, voice_stack[i]->py, 0.);
|
||||
//alSource3f(voice_stack[i]->source, AL_VELOCITY,
|
||||
//voice_stack[i]->vx, voice_stack[i]->vy, 0.);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
SDL_mutexV(sound_lock);
|
||||
SDL_mutexV(sound_lock);
|
||||
}
|
||||
|
||||
// Set all the sounds volume to vol.
|
||||
void sound_volume(const double vol) {
|
||||
if(sound_lock == NULL) return;
|
||||
if(sound_lock == NULL) return;
|
||||
|
||||
int i;
|
||||
int i;
|
||||
|
||||
svolume = (ALfloat) vol;
|
||||
svolume = (ALfloat) vol;
|
||||
|
||||
SDL_mutexP(sound_lock);
|
||||
for(i = 0; i < nvoice_stack; i++)
|
||||
if(voice_set(voice_stack[i], VOICE_PLAYING))
|
||||
alSourcef(voice_stack[i]->source, AL_GAIN, svolume);
|
||||
SDL_mutexV(sound_lock);
|
||||
SDL_mutexP(sound_lock);
|
||||
for(i = 0; i < nvoice_stack; i++)
|
||||
if(voice_set(voice_stack[i], VOICE_PLAYING))
|
||||
alSourcef(voice_stack[i]->source, AL_GAIN, svolume);
|
||||
SDL_mutexV(sound_lock);
|
||||
}
|
||||
|
||||
// Attempt to alloc a source for a voice.
|
||||
static int voice_getSource(alVoice* voc) {
|
||||
if(sound_lock == NULL) return -1;
|
||||
int ret;
|
||||
ALenum err;
|
||||
if(sound_lock == NULL) return -1;
|
||||
int ret;
|
||||
ALenum err;
|
||||
|
||||
ret = 0; // Default return.
|
||||
ret = 0; // Default return.
|
||||
|
||||
SDL_mutexP(sound_lock);
|
||||
SDL_mutexP(sound_lock);
|
||||
|
||||
// Try and grab a source.
|
||||
voc->source = 0;
|
||||
alGenSources(1, &voc->source);
|
||||
err = alGetError();
|
||||
|
||||
if(err != AL_NO_ERROR) {
|
||||
// Try and grab a source.
|
||||
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);
|
||||
alGenSources(1, &voc->source);
|
||||
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,
|
||||
const ALuint buffer, const int looping) {
|
||||
|
||||
(void)vx;
|
||||
(void)vy;
|
||||
const ALuint buffer, const int looping) {
|
||||
|
||||
if(sound_lock == NULL) return NULL;
|
||||
(void)vx;
|
||||
(void)vy;
|
||||
|
||||
alVoice* voc;
|
||||
if(sound_lock == NULL) return NULL;
|
||||
|
||||
nvoice_stack++;
|
||||
if(nvoice_stack > mvoice_stack)
|
||||
voice_stack = realloc(voice_stack, ++mvoice_stack*sizeof(alVoice*));
|
||||
|
||||
voc = malloc(sizeof(alVoice));
|
||||
voice_stack[nvoice_stack-1] = voc;
|
||||
alVoice* 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;
|
||||
nvoice_stack++;
|
||||
if(nvoice_stack > mvoice_stack)
|
||||
voice_stack = realloc(voice_stack, ++mvoice_stack*sizeof(alVoice*));
|
||||
|
||||
voice_getSource(voc);
|
||||
|
||||
return voc;
|
||||
voc = malloc(sizeof(alVoice));
|
||||
voice_stack[nvoice_stack-1] = voc;
|
||||
|
||||
// Set the data.
|
||||
voc->priority = priority;
|
||||
voc->start = SDL_GetTicks();
|
||||
voc->buffer = buffer;
|
||||
if(looping) voice_set(voc, VOICE_LOOPING);
|
||||
voc->px = px;
|
||||
voc->py = py;
|
||||
//voc->vx = vx;
|
||||
//voc->vy = vy;
|
||||
|
||||
voice_getSource(voc);
|
||||
|
||||
return voc;
|
||||
}
|
||||
|
||||
void sound_delVoice(alVoice* voice) {
|
||||
if(sound_lock == NULL) return;
|
||||
ALint stat;
|
||||
int i;
|
||||
if(sound_lock == NULL) return;
|
||||
ALint stat;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < nvoice_stack; i++)
|
||||
if(voice == voice_stack[i])
|
||||
break;
|
||||
for(i = 0; i < nvoice_stack; i++)
|
||||
if(voice == voice_stack[i])
|
||||
break;
|
||||
|
||||
// No match found.
|
||||
if(i >= nvoice_stack) {
|
||||
WARN("Unable to find voice to free from stack");
|
||||
return;
|
||||
}
|
||||
// No match found.
|
||||
if(i >= nvoice_stack) {
|
||||
WARN("Unable to find voice to free from stack");
|
||||
return;
|
||||
}
|
||||
|
||||
if(voice->source) {
|
||||
SDL_mutexP(sound_lock);
|
||||
if(voice->source) {
|
||||
SDL_mutexP(sound_lock);
|
||||
|
||||
alGetSourcei(voice->source, AL_SOURCE_STATE, &stat);
|
||||
if(stat == AL_PLAYING) alSourceStop(voice->source);
|
||||
alDeleteSources(1, &voice->source);
|
||||
voice->source = 0;
|
||||
alGetSourcei(voice->source, AL_SOURCE_STATE, &stat);
|
||||
if(stat == AL_PLAYING) alSourceStop(voice->source);
|
||||
alDeleteSources(1, &voice->source);
|
||||
voice->source = 0;
|
||||
|
||||
SDL_mutexV(sound_lock);
|
||||
}
|
||||
SDL_mutexV(sound_lock);
|
||||
}
|
||||
|
||||
free(voice_stack[i]);
|
||||
nvoice_stack--;
|
||||
for(; i < nvoice_stack; i++)
|
||||
voice_stack[i] = voice_stack[i+1];
|
||||
free(voice_stack[i]);
|
||||
nvoice_stack--;
|
||||
for(; i < nvoice_stack; i++)
|
||||
voice_stack[i] = voice_stack[i+1];
|
||||
}
|
||||
|
||||
void voice_update(alVoice* voice, double px, double py, double vx, double vy) {
|
||||
(void) vx;
|
||||
(void) vy;
|
||||
(void) vx;
|
||||
(void) vy;
|
||||
|
||||
if(sound_lock == NULL) return;
|
||||
|
||||
voice->px = px;
|
||||
voice->py = py;
|
||||
//voice->vx = vx;
|
||||
//voice->vy = vy;
|
||||
if(sound_lock == NULL) return;
|
||||
|
||||
voice->px = px;
|
||||
voice->py = py;
|
||||
//voice->vx = vx;
|
||||
//voice->vy = vy;
|
||||
}
|
||||
|
||||
void sound_listener(double dir, double px, double py, double vx, double vy) {
|
||||
(void)vx;
|
||||
(void)vy;
|
||||
(void)vx;
|
||||
(void)vy;
|
||||
|
||||
if(sound_lock == NULL) return;
|
||||
if(sound_lock == NULL) return;
|
||||
|
||||
SDL_mutexP(sound_lock);
|
||||
SDL_mutexP(sound_lock);
|
||||
|
||||
ALfloat ori[] = { 0., 0., 0., 0., 0., 1. };
|
||||
ori[0] = cos(dir);
|
||||
ori[1] = sin(dir);
|
||||
alListenerfv(AL_ORIENTATION, ori);
|
||||
alListener3f(AL_POSITION, px, py, 0.);
|
||||
//alListener3f(AL_VELOCITY, vx, vy, 0.);
|
||||
ALfloat ori[] = { 0., 0., 0., 0., 0., 1. };
|
||||
ori[0] = cos(dir);
|
||||
ori[1] = sin(dir);
|
||||
alListenerfv(AL_ORIENTATION, ori);
|
||||
alListener3f(AL_POSITION, px, py, 0.);
|
||||
//alListener3f(AL_VELOCITY, vx, vy, 0.);
|
||||
|
||||
SDL_mutexV(sound_lock);
|
||||
SDL_mutexV(sound_lock);
|
||||
}
|
||||
|
||||
|
16
src/sound.h
16
src/sound.h
@ -7,16 +7,16 @@
|
||||
|
||||
// Virtual voice.
|
||||
typedef struct alVoice_ {
|
||||
ALuint source; // Source itself, 0 if not set.
|
||||
ALuint buffer; // Buffer.
|
||||
ALuint source; // Source itself, 0 if not set.
|
||||
ALuint buffer; // Buffer.
|
||||
|
||||
int priority; // Base priority.
|
||||
int priority; // Base priority.
|
||||
|
||||
double px, py; // Position.
|
||||
double vx, vy; // Velocity.
|
||||
double px, py; // Position.
|
||||
double vx, vy; // Velocity.
|
||||
|
||||
unsigned int start; // Time started in ms.
|
||||
unsigned int flags; // Flags to set properties.
|
||||
unsigned int start; // Time started in ms.
|
||||
unsigned int flags; // Flags to set properties.
|
||||
} alVoice;
|
||||
|
||||
// Sound subsystem.
|
||||
@ -30,7 +30,7 @@ void sound_volume(const double vol);
|
||||
|
||||
// Voice manipulation function.
|
||||
alVoice* sound_addVoice(int priority, double px, double py, double vx, double vy,
|
||||
const ALuint buffer, const int looping);
|
||||
const ALuint buffer, const int looping);
|
||||
|
||||
void sound_delVoice(alVoice* voice);
|
||||
void voice_update(alVoice* voice, double px, double py, double vx, double vy);
|
||||
|
484
src/space.c
484
src/space.c
@ -35,8 +35,8 @@
|
||||
#define FLAG_YSET (1<<1)
|
||||
#define FLAG_ASTEROIDSSET (1<<2)
|
||||
#define FLAG_INTEFERENCESET (1<<3)
|
||||
#define FLAG_SERVICESET (1<<4)
|
||||
#define FLAG_TECHSET (1<<5)
|
||||
#define FLAG_SERVICESET (1<<4)
|
||||
#define FLAG_TECHSET (1<<5)
|
||||
|
||||
// Star system stack and co.
|
||||
StarSystem* systems_stack = NULL; // Star system stack.
|
||||
@ -74,9 +74,9 @@ extern void player_message(const char* fmt, ...);
|
||||
// Draw the planet. Used in planet.c
|
||||
// Matrix mode is already displaced to center of the minimap.
|
||||
#define PIXEL(x,y) if((shape == RADAR_RECT && ABS(x)<w/2. && ABS(y)<h/2.) || \
|
||||
(shape == RADAR_CIRCLE && (((x)*(x)+(y)*(y)) < rc))) glVertex2i((x),(y))
|
||||
(shape == RADAR_CIRCLE && (((x)*(x)+(y)*(y)) < rc))) glVertex2i((x),(y))
|
||||
void planets_minimap(const double res,
|
||||
const double w, const double h, const RadarShape shape) {
|
||||
const double w, const double h, const RadarShape shape) {
|
||||
int i;
|
||||
int cx, cy, x, y, r, rc;
|
||||
double p;
|
||||
@ -84,42 +84,42 @@ void planets_minimap(const double res,
|
||||
if(shape == RADAR_CIRCLE) rc = (int)(w*w);
|
||||
|
||||
glBegin(GL_POINTS);
|
||||
for(i = 0; i < cur_system->nplanets; i++) {
|
||||
if(areEnemies(player->faction, cur_system->planets[i].faction))
|
||||
COLOUR(cHostile);
|
||||
else if(areAllies(player->faction, cur_system->planets[i].faction))
|
||||
COLOUR(cFriend);
|
||||
else COLOUR(cNeutral);
|
||||
r = (int)(cur_system->planets[i].gfx_space->sw / res);
|
||||
cx = (int)((cur_system->planets[i].pos.x - player->solid->pos.x) / res);
|
||||
cy = (int)((cur_system->planets[i].pos.y - player->solid->pos.y) / res);
|
||||
for(i = 0; i < cur_system->nplanets; i++) {
|
||||
if(areEnemies(player->faction, cur_system->planets[i].faction))
|
||||
COLOUR(cHostile);
|
||||
else if(areAllies(player->faction, cur_system->planets[i].faction))
|
||||
COLOUR(cFriend);
|
||||
else COLOUR(cNeutral);
|
||||
r = (int)(cur_system->planets[i].gfx_space->sw / res);
|
||||
cx = (int)((cur_system->planets[i].pos.x - player->solid->pos.x) / res);
|
||||
cy = (int)((cur_system->planets[i].pos.y - player->solid->pos.y) / res);
|
||||
|
||||
x = 0;
|
||||
y = r;
|
||||
p = (5. - (double)(r*3)) / 4.;
|
||||
x = 0;
|
||||
y = r;
|
||||
p = (5. - (double)(r*3)) / 4.;
|
||||
|
||||
PIXEL(cx, cy+y);
|
||||
PIXEL(cx, cy-y);
|
||||
PIXEL(cx+y, cy);
|
||||
PIXEL(cx-y, cy);
|
||||
PIXEL(cx, cy+y);
|
||||
PIXEL(cx, cy-y);
|
||||
PIXEL(cx+y, cy);
|
||||
PIXEL(cx-y, cy);
|
||||
|
||||
while(x < y) {
|
||||
x++;
|
||||
if(p < 0) p += 2*(double)(x)+1;
|
||||
else p += 2*(double)(x-(--y))+1;
|
||||
while(x < y) {
|
||||
x++;
|
||||
if(p < 0) p += 2*(double)(x)+1;
|
||||
else p += 2*(double)(x-(--y))+1;
|
||||
|
||||
if(x == 0) {
|
||||
PIXEL(cx, cy+y);
|
||||
PIXEL(cx, cy-y);
|
||||
PIXEL(cx+y, cy);
|
||||
PIXEL(cx-y, cy);
|
||||
if(x == 0) {
|
||||
PIXEL(cx, cy+y);
|
||||
PIXEL(cx, cy-y);
|
||||
PIXEL(cx+y, cy);
|
||||
PIXEL(cx-y, cy);
|
||||
} else
|
||||
if(x == y) {
|
||||
PIXEL(cx+x, cy+y);
|
||||
PIXEL(cx-x, cy+y);
|
||||
PIXEL(cx+x, cy-y);
|
||||
PIXEL(cx-x, cy-y);
|
||||
} else
|
||||
if(x == y) {
|
||||
PIXEL(cx+x, cy+y);
|
||||
PIXEL(cx-x, cy+y);
|
||||
PIXEL(cx+x, cy-y);
|
||||
PIXEL(cx-x, cy-y);
|
||||
} else
|
||||
if(x < 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
#undef PIXEL
|
||||
@ -139,34 +139,34 @@ void planets_minimap(const double res,
|
||||
static PlanetClass planetclass_get(const char a) {
|
||||
switch(a) {
|
||||
// Planets use letters.
|
||||
case 'A': return PLANET_CLASS_A;
|
||||
case 'B': return PLANET_CLASS_B;
|
||||
case 'C': return PLANET_CLASS_C;
|
||||
case 'D': return PLANET_CLASS_D;
|
||||
case 'E': return PLANET_CLASS_E;
|
||||
case 'F': return PLANET_CLASS_F;
|
||||
case 'G': return PLANET_CLASS_G;
|
||||
case 'H': return PLANET_CLASS_H;
|
||||
case 'I': return PLANET_CLASS_I;
|
||||
case 'J': return PLANET_CLASS_J;
|
||||
case 'K': return PLANET_CLASS_K;
|
||||
case 'L': return PLANET_CLASS_L;
|
||||
case 'M': return PLANET_CLASS_M;
|
||||
case 'N': return PLANET_CLASS_N;
|
||||
case 'O': return PLANET_CLASS_O;
|
||||
case 'P': return PLANET_CLASS_P;
|
||||
case 'Q': return PLANET_CLASS_Q;
|
||||
case 'R': return PLANET_CLASS_R;
|
||||
case 'S': return PLANET_CLASS_S;
|
||||
case 'T': return PLANET_CLASS_T;
|
||||
case 'X': return PLANET_CLASS_X;
|
||||
case 'Y': return PLANET_CLASS_Y;
|
||||
case 'Z': return PLANET_CLASS_Z;
|
||||
case 'A': return PLANET_CLASS_A;
|
||||
case 'B': return PLANET_CLASS_B;
|
||||
case 'C': return PLANET_CLASS_C;
|
||||
case 'D': return PLANET_CLASS_D;
|
||||
case 'E': return PLANET_CLASS_E;
|
||||
case 'F': return PLANET_CLASS_F;
|
||||
case 'G': return PLANET_CLASS_G;
|
||||
case 'H': return PLANET_CLASS_H;
|
||||
case 'I': return PLANET_CLASS_I;
|
||||
case 'J': return PLANET_CLASS_J;
|
||||
case 'K': return PLANET_CLASS_K;
|
||||
case 'L': return PLANET_CLASS_L;
|
||||
case 'M': return PLANET_CLASS_M;
|
||||
case 'N': return PLANET_CLASS_N;
|
||||
case 'O': return PLANET_CLASS_O;
|
||||
case 'P': return PLANET_CLASS_P;
|
||||
case 'Q': return PLANET_CLASS_Q;
|
||||
case 'R': return PLANET_CLASS_R;
|
||||
case 'S': return PLANET_CLASS_S;
|
||||
case 'T': return PLANET_CLASS_T;
|
||||
case 'X': return PLANET_CLASS_X;
|
||||
case 'Y': return PLANET_CLASS_Y;
|
||||
case 'Z': return PLANET_CLASS_Z;
|
||||
|
||||
// Stations use numbers as there isn't as many.
|
||||
// Stations use numbers as there isn't as many.
|
||||
case '0' : return STATION_CLASS_A;
|
||||
|
||||
default: return PLANET_CLASS_NULL;
|
||||
default: return PLANET_CLASS_NULL;
|
||||
};
|
||||
}
|
||||
|
||||
@ -194,74 +194,74 @@ int space_hyperspace(Pilot* p) {
|
||||
|
||||
// Basically used for spawning fleets.
|
||||
void space_update(const double dt) {
|
||||
unsigned int t;
|
||||
int i, j, f;
|
||||
unsigned int t;
|
||||
int i, j, f;
|
||||
|
||||
(void)dt; // Don't need it right now.
|
||||
(void)dt; // Don't need it right now.
|
||||
|
||||
t = SDL_GetTicks();
|
||||
t = SDL_GetTicks();
|
||||
|
||||
if(cur_system->nfleets == 0)
|
||||
// Please stop checking that there are no fleets.
|
||||
spawn_timer = t + 300000;
|
||||
if(cur_system->nfleets == 0)
|
||||
// Please stop checking that there are no fleets.
|
||||
spawn_timer = t + 300000;
|
||||
|
||||
if(spawn_timer < t) {
|
||||
// Time to possibly spawn.
|
||||
if(spawn_timer < t) {
|
||||
// Time to possibly spawn.
|
||||
|
||||
// Spawn chance is based on overall percentage.
|
||||
f = RNG(0, 100*cur_system->nfleets);
|
||||
j = 0;
|
||||
for(i = 0; i < cur_system->nfleets; i++) {
|
||||
j += cur_system->fleets[i].chance;
|
||||
if(f < j) {
|
||||
// Add one fleet.
|
||||
space_addFleet(cur_system->fleets[i].fleet);
|
||||
break;
|
||||
}
|
||||
// Spawn chance is based on overall percentage.
|
||||
f = RNG(0, 100*cur_system->nfleets);
|
||||
j = 0;
|
||||
for(i = 0; i < cur_system->nfleets; i++) {
|
||||
j += cur_system->fleets[i].chance;
|
||||
if(f < j) {
|
||||
// Add one fleet.
|
||||
space_addFleet(cur_system->fleets[i].fleet);
|
||||
break;
|
||||
}
|
||||
}
|
||||
spawn_timer = t + 60000./(float)cur_system->nfleets;
|
||||
}
|
||||
spawn_timer = t + 60000./(float)cur_system->nfleets;
|
||||
}
|
||||
}
|
||||
|
||||
// Crate a fleet.
|
||||
static void space_addFleet(Fleet* fleet) {
|
||||
int i;
|
||||
double a;
|
||||
Vec2 vv, vp, vn;
|
||||
int i;
|
||||
double a;
|
||||
Vec2 vv, vp, vn;
|
||||
|
||||
// Simulate them coming from hyperspace.
|
||||
vect_pset(&vp, RNG(MIN_HYPERSPACE_DIST, MIN_HYPERSPACE_DIST*1.5),
|
||||
RNG(0, 360)*M_PI/180.);
|
||||
vectnull(&vn);
|
||||
// Simulate them coming from hyperspace.
|
||||
vect_pset(&vp, RNG(MIN_HYPERSPACE_DIST, MIN_HYPERSPACE_DIST*1.5),
|
||||
RNG(0, 360)*M_PI/180.);
|
||||
vectnull(&vn);
|
||||
|
||||
for(i = 0; i < fleet->npilots; i++)
|
||||
if(RNG(0, 100) <= fleet->pilots[i].chance) {
|
||||
vect_cadd(&vp, RNG(75, 150) * (RNG(0,1) ? 1 : -1),
|
||||
RNG(75, 150) * (RNG(0,1) ? 1 : -1));
|
||||
for(i = 0; i < fleet->npilots; i++)
|
||||
if(RNG(0, 100) <= fleet->pilots[i].chance) {
|
||||
vect_cadd(&vp, RNG(75, 150) * (RNG(0,1) ? 1 : -1),
|
||||
RNG(75, 150) * (RNG(0,1) ? 1 : -1));
|
||||
|
||||
a = vect_angle(&vp, &vn);
|
||||
vectnull(&vv);
|
||||
a = vect_angle(&vp, &vn);
|
||||
vectnull(&vv);
|
||||
|
||||
pilot_create(fleet->pilots[i].ship,
|
||||
fleet->pilots[i].name,
|
||||
fleet->faction,
|
||||
fleet->ai,
|
||||
a,
|
||||
&vp,
|
||||
&vv,
|
||||
0);
|
||||
}
|
||||
pilot_create(fleet->pilots[i].ship,
|
||||
fleet->pilots[i].name,
|
||||
fleet->faction,
|
||||
fleet->ai,
|
||||
a,
|
||||
&vp,
|
||||
&vv,
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
// Init the system.
|
||||
void space_init(const char* sysname) {
|
||||
int i;
|
||||
|
||||
|
||||
// Cleanup some stuff.
|
||||
player_clear(); // Clears targets.
|
||||
pilots_clean(); // Destroy all the current pilots, exept player.
|
||||
weapon_clear(); // Get rid of all the weapons.
|
||||
spfx_clear(); // Remove of explosions.
|
||||
spfx_clear(); // Remove of explosions.
|
||||
|
||||
if((sysname == NULL) && (cur_system == NULL))
|
||||
ERR("Cannot reinit system if there is no system previously loaded");
|
||||
@ -286,16 +286,16 @@ void space_init(const char* sysname) {
|
||||
}
|
||||
// Set up fleets -> pilots.
|
||||
for(i = 0; i < cur_system->nfleets; i++)
|
||||
if(RNG(0,100) <= (cur_system->fleets[i].chance/2)) // Fleet check (50% chance).
|
||||
space_addFleet(cur_system->fleets[i].fleet);
|
||||
|
||||
// Start the spawn timer.
|
||||
spawn_timer = SDL_GetTicks() + 120000./(float)(cur_system->nfleets+1);
|
||||
if(RNG(0,100) <= (cur_system->fleets[i].chance/2)) // Fleet check (50% chance).
|
||||
space_addFleet(cur_system->fleets[i].fleet);
|
||||
|
||||
// Start the spawn timer.
|
||||
spawn_timer = SDL_GetTicks() + 120000./(float)(cur_system->nfleets+1);
|
||||
}
|
||||
|
||||
// Load the planets of name 'name'.
|
||||
static Planet* planet_get(const char* name) {
|
||||
int i;
|
||||
int i;
|
||||
|
||||
Planet* tmp = NULL;
|
||||
|
||||
@ -338,13 +338,13 @@ static Planet* planet_get(const char* name) {
|
||||
if(xml_isNode(cur, "space")) {
|
||||
// Load space gfx.
|
||||
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);
|
||||
}
|
||||
else if(xml_isNode(cur, "exterior")) {
|
||||
// Load land gfx.
|
||||
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);
|
||||
}
|
||||
} while((cur = cur->next));
|
||||
@ -374,39 +374,39 @@ static Planet* planet_get(const char* name) {
|
||||
else if(xml_isNode(cur, "bar"))
|
||||
tmp->bar_description = strdup(xml_get(cur));
|
||||
else if(xml_isNode(cur, "services")) {
|
||||
flags |= FLAG_SERVICESET;
|
||||
flags |= FLAG_SERVICESET;
|
||||
tmp->services = xml_getInt(cur);
|
||||
}
|
||||
else if(xml_isNode(cur, "tech")) {
|
||||
ccur = cur->children;
|
||||
do {
|
||||
if(xml_isNode(ccur, "main")) {
|
||||
flags |= FLAG_TECHSET;
|
||||
tmp->tech[0] = xml_getInt(ccur);
|
||||
}
|
||||
else if(xml_isNode(ccur, "special")) {
|
||||
for(i = 1; i < PLANET_TECH_MAX; i++)
|
||||
if(tmp->tech[i]==0) {
|
||||
tmp->tech[i] = xml_getInt(ccur);
|
||||
break;
|
||||
}
|
||||
if(i == PLANET_TECH_MAX) WARN("Planet '%s' has tooo many"
|
||||
"'special tech' entries", tmp->name);
|
||||
}
|
||||
} while((ccur = ccur->next));
|
||||
}
|
||||
else if(xml_isNode(cur, "commodities")) {
|
||||
ccur = cur->children;
|
||||
do {
|
||||
if(xml_isNode(ccur, "commodity")) {
|
||||
tmp->commodities = realloc(tmp->commodities,
|
||||
(tmp->ncommodities+1) * sizeof(Commodity*));
|
||||
tmp->commodities[tmp->ncommodities] =
|
||||
commodity_get(xml_get(ccur));
|
||||
tmp->ncommodities++;
|
||||
}
|
||||
} while((ccur = ccur->next));
|
||||
}
|
||||
}
|
||||
else if(xml_isNode(cur, "tech")) {
|
||||
ccur = cur->children;
|
||||
do {
|
||||
if(xml_isNode(ccur, "main")) {
|
||||
flags |= FLAG_TECHSET;
|
||||
tmp->tech[0] = xml_getInt(ccur);
|
||||
}
|
||||
else if(xml_isNode(ccur, "special")) {
|
||||
for(i = 1; i < PLANET_TECH_MAX; i++)
|
||||
if(tmp->tech[i]==0) {
|
||||
tmp->tech[i] = xml_getInt(ccur);
|
||||
break;
|
||||
}
|
||||
if(i == PLANET_TECH_MAX) WARN("Planet '%s' has tooo many"
|
||||
"'special tech' entries", tmp->name);
|
||||
}
|
||||
} while((ccur = ccur->next));
|
||||
}
|
||||
else if(xml_isNode(cur, "commodities")) {
|
||||
ccur = cur->children;
|
||||
do {
|
||||
if(xml_isNode(ccur, "commodity")) {
|
||||
tmp->commodities = realloc(tmp->commodities,
|
||||
(tmp->ncommodities+1) * sizeof(Commodity*));
|
||||
tmp->commodities[tmp->ncommodities] =
|
||||
commodity_get(xml_get(ccur));
|
||||
tmp->ncommodities++;
|
||||
}
|
||||
} while((ccur = ccur->next));
|
||||
}
|
||||
} while((cur = cur->next));
|
||||
}
|
||||
} while((node = node->next));
|
||||
@ -424,24 +424,24 @@ static Planet* planet_get(const char* name) {
|
||||
if(tmp) {
|
||||
#define MELEMENT(o,s) if(o) WARN("Planet '%s' missing '"s"' element", tmp->name)
|
||||
MELEMENT(tmp->gfx_space==NULL, "GFX_space");
|
||||
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_LAND) &&
|
||||
tmp->gfx_exterior==NULL, "GFX exterior");
|
||||
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_LAND) &&
|
||||
tmp->gfx_exterior==NULL, "GFX exterior");
|
||||
MELEMENT((flags&FLAG_XSET)==0, "x");
|
||||
MELEMENT((flags&FLAG_YSET)==0, "y");
|
||||
MELEMENT(tmp->class==PLANET_CLASS_NULL, "class");
|
||||
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_LAND) &&
|
||||
tmp->description==NULL, "description");
|
||||
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_BASIC) &&
|
||||
tmp->bar_description==NULL, "bar");
|
||||
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_BASIC) &&
|
||||
tmp->faction==NULL, "faction");
|
||||
MELEMENT((flags&FLAG_SERVICESET)==0, "services");
|
||||
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_LAND) &&
|
||||
tmp->description==NULL, "description");
|
||||
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_BASIC) &&
|
||||
tmp->bar_description==NULL, "bar");
|
||||
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_BASIC) &&
|
||||
tmp->faction==NULL, "faction");
|
||||
MELEMENT((flags&FLAG_SERVICESET)==0, "services");
|
||||
|
||||
MELEMENT((planet_hasService(tmp, PLANET_SERVICE_OUTFITS) ||
|
||||
planet_hasService(tmp, PLANET_SERVICE_SHIPYARD)) &&
|
||||
(flags&FLAG_TECHSET)==0, "tech");
|
||||
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_COMMODITY) &&
|
||||
(tmp->ncommodities==0), "commodity");
|
||||
MELEMENT((planet_hasService(tmp, PLANET_SERVICE_OUTFITS) ||
|
||||
planet_hasService(tmp, PLANET_SERVICE_SHIPYARD)) &&
|
||||
(flags&FLAG_TECHSET)==0, "tech");
|
||||
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_COMMODITY) &&
|
||||
(tmp->ncommodities==0), "commodity");
|
||||
#undef MELEMENT
|
||||
} else
|
||||
WARN("No planet found matching name '%s'", name);
|
||||
@ -499,7 +499,7 @@ static StarSystem* system_parse(const xmlNodePtr parent) {
|
||||
cur = node->children;
|
||||
do {
|
||||
if(xml_isNode(cur, "planet")) {
|
||||
nplanets++; // Increase planet counter.
|
||||
nplanets++; // Increase planet counter.
|
||||
planet = planet_get(xml_get(cur));
|
||||
planet = planet_get((const char*)cur->children->content);
|
||||
tmp->planets = realloc(tmp->planets, sizeof(Planet)*(++tmp->nplanets));
|
||||
@ -522,7 +522,7 @@ static StarSystem* system_parse(const xmlNodePtr parent) {
|
||||
fleet->chance = atoi(ptrc);
|
||||
if(fleet->chance == 0)
|
||||
WARN("Fleet %s for Star System %s has 0%% chance to appear",
|
||||
fleet->fleet->name, tmp->name);
|
||||
fleet->fleet->name, tmp->name);
|
||||
if(ptrc) free(ptrc); // Free the ptrc.
|
||||
|
||||
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_INTEFERENCESET, "inteference");
|
||||
#undef MELEMENT
|
||||
|
||||
// Post processing.
|
||||
if(tmp->nplanets > 0)
|
||||
// TODO: Make dependant on overall planet faction.
|
||||
tmp->faction = tmp->planets[0].faction;
|
||||
|
||||
// Post processing.
|
||||
if(tmp->nplanets > 0)
|
||||
// TODO: Make dependant on overall planet faction.
|
||||
tmp->faction = tmp->planets[0].faction;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@ -561,31 +561,31 @@ static void system_parseJumps(const xmlNodePtr parent) {
|
||||
system = &systems_stack[i];
|
||||
break;
|
||||
}
|
||||
if(i == systems_nstack)
|
||||
WARN("System '%s' was not found in the stack for some reason", name);
|
||||
free(name); // No need for it now.
|
||||
if(i == systems_nstack)
|
||||
WARN("System '%s' was not found in the stack for some reason", name);
|
||||
free(name); // No need for it now.
|
||||
|
||||
node = parent->xmlChildrenNode;
|
||||
node = parent->xmlChildrenNode;
|
||||
|
||||
do {
|
||||
// Load the data.
|
||||
if(xml_isNode(node, "jumps")) {
|
||||
cur = node->children;
|
||||
do {
|
||||
if(xml_isNode(cur, "jump")) {
|
||||
for(i = 0; i < systems_nstack; i++)
|
||||
if(strcmp(systems_stack[i].name, xml_get(cur))==0) {
|
||||
system->njumps++;
|
||||
system->jumps = realloc(system->jumps, system->njumps*sizeof(int));
|
||||
system->jumps[system->njumps-1] = i;
|
||||
break;
|
||||
}
|
||||
if(i == systems_nstack)
|
||||
WARN("System '%s' not found for jump linking", xml_get(cur));
|
||||
}
|
||||
} while((cur = cur->next));
|
||||
}
|
||||
} while((node = node->next));
|
||||
do {
|
||||
// Load the data.
|
||||
if(xml_isNode(node, "jumps")) {
|
||||
cur = node->children;
|
||||
do {
|
||||
if(xml_isNode(cur, "jump")) {
|
||||
for(i = 0; i < systems_nstack; i++)
|
||||
if(strcmp(systems_stack[i].name, xml_get(cur))==0) {
|
||||
system->njumps++;
|
||||
system->jumps = realloc(system->jumps, system->njumps*sizeof(int));
|
||||
system->jumps[system->njumps-1] = i;
|
||||
break;
|
||||
}
|
||||
if(i == systems_nstack)
|
||||
WARN("System '%s' not found for jump linking", xml_get(cur));
|
||||
}
|
||||
} while((cur = cur->next));
|
||||
}
|
||||
} while((node = node->next));
|
||||
}
|
||||
|
||||
// Load the ENTIRE universe into RAM. -- WOAH!
|
||||
@ -631,9 +631,9 @@ int space_load(void) {
|
||||
free(buf);
|
||||
xmlCleanupParser();
|
||||
|
||||
DEBUG("Loaded %d star system%s with %d planet%s",
|
||||
systems_nstack, (systems_nstack==1) ? "" : "s",
|
||||
nplanets, (nplanets==1) ? "" : "s");
|
||||
DEBUG("Loaded %d star system%s with %d planet%s",
|
||||
systems_nstack, (systems_nstack==1) ? "" : "s",
|
||||
nplanets, (nplanets==1) ? "" : "s");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -641,63 +641,63 @@ int space_load(void) {
|
||||
// Render the system. -- Just playing god now.
|
||||
void space_render(double dt) {
|
||||
int i;
|
||||
unsigned int t, timer;
|
||||
double x, y, m;
|
||||
unsigned int t, timer;
|
||||
double x, y, m;
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix(); // Translation matrix.
|
||||
glTranslated(-(double)gl_screen.w/2., -(double)gl_screen.h/2., 0);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix(); // Translation matrix.
|
||||
glTranslated(-(double)gl_screen.w/2., -(double)gl_screen.h/2., 0);
|
||||
|
||||
t = SDL_GetTicks();
|
||||
if(!player_isFlag(PLAYER_DESTROYED) &&
|
||||
pilot_isFlag(player, PILOT_HYPERSPACE) && // Hyperspace fancy effect.
|
||||
!paused && (player->ptimer-HYPERSPACE_STARS_BLUR < t)) {
|
||||
t = SDL_GetTicks();
|
||||
if(!player_isFlag(PLAYER_DESTROYED) &&
|
||||
pilot_isFlag(player, PILOT_HYPERSPACE) && // Hyperspace fancy effect.
|
||||
!paused && (player->ptimer-HYPERSPACE_STARS_BLUR < t)) {
|
||||
|
||||
timer = player->ptimer - HYPERSPACE_STARS_BLUR;
|
||||
timer = player->ptimer - HYPERSPACE_STARS_BLUR;
|
||||
|
||||
// Fancy hyperspace effects.
|
||||
glShadeModel(GL_SMOOTH);
|
||||
// Fancy hyperspace effects.
|
||||
glShadeModel(GL_SMOOTH);
|
||||
|
||||
glBegin(GL_LINES);
|
||||
glBegin(GL_LINES);
|
||||
|
||||
// Lines will be based on velocity.
|
||||
m = HYPERSPACE_STARS_LENGTH * (double)(t-timer) / (HYPERSPACE_STARS_BLUR);
|
||||
x = m*cos(VANGLE(player->solid->vel)+M_PI);
|
||||
y = m*sin(VANGLE(player->solid->vel)+M_PI);
|
||||
// Lines will be based on velocity.
|
||||
m = HYPERSPACE_STARS_LENGTH * (double)(t-timer) / (HYPERSPACE_STARS_BLUR);
|
||||
x = m*cos(VANGLE(player->solid->vel)+M_PI);
|
||||
y = m*sin(VANGLE(player->solid->vel)+M_PI);
|
||||
|
||||
for(i = 0; i < nstars; i++) {
|
||||
glColor4d(1., 1., 1., stars[i].brightness);
|
||||
glVertex2d(stars[i].x, stars[i].y);
|
||||
glColor4d(1., 1., 1., 0.);
|
||||
glVertex2d(stars[i].x+x*stars[i].brightness,stars[i].y+y*stars[i].brightness);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
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;
|
||||
for(i = 0; i < nstars; i++) {
|
||||
glColor4d(1., 1., 1., stars[i].brightness);
|
||||
glVertex2d(stars[i].x, stars[i].y);
|
||||
glColor4d(1., 1., 1., 0.);
|
||||
glVertex2d(stars[i].x+x*stars[i].brightness,stars[i].y+y*stars[i].brightness);
|
||||
}
|
||||
// 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();
|
||||
|
||||
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!
|
||||
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.
|
||||
@ -705,7 +705,7 @@ void planets_render(void) {
|
||||
int i;
|
||||
for(i = 0; i < cur_system->nplanets; i++)
|
||||
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.
|
||||
|
14
src/space.h
14
src/space.h
@ -35,7 +35,7 @@ typedef enum PlanetClass_ {
|
||||
PLANET_CLASS_X, // Demon.
|
||||
PLANET_CLASS_Y, // Demon.
|
||||
PLANET_CLASS_Z, // Demon.
|
||||
STATION_CLASS_A // TODO.
|
||||
STATION_CLASS_A // TODO.
|
||||
} PlanetClass;
|
||||
|
||||
// Planet services.
|
||||
@ -56,12 +56,12 @@ typedef struct Planet_ {
|
||||
char* description; // Planet description.
|
||||
char* bar_description; // Spaceport bar description.
|
||||
unsigned int services; // Offered services.
|
||||
Commodity** commodities; // Commodities sold.
|
||||
int ncommodities; // Amount in stock.
|
||||
Commodity** commodities; // Commodities sold.
|
||||
int ncommodities; // Amount in stock.
|
||||
|
||||
// tech[0] stores global tech level (everything that and below) while
|
||||
// tech[1-PLANET_TECH_MAX] stores the unique tech levels.
|
||||
int tech[PLANET_TECH_MAX];
|
||||
// tech[0] stores global tech level (everything that and below) while
|
||||
// tech[1-PLANET_TECH_MAX] stores the unique tech levels.
|
||||
int tech[PLANET_TECH_MAX];
|
||||
|
||||
glTexture* gfx_space; // Graphics in space.
|
||||
glTexture* gfx_exterior; // Graphics in the exterior.
|
||||
@ -79,7 +79,7 @@ typedef struct StarSystem_ {
|
||||
int stars, asteroids; // Un numero!
|
||||
double interference; // Un uh.. Percentage.
|
||||
|
||||
Faction* faction; // Overall faction.
|
||||
Faction* faction; // Overall faction.
|
||||
|
||||
Planet* planets; // Planets.
|
||||
int nplanets; // Total number of planets.
|
||||
|
268
src/spfx.c
268
src/spfx.c
@ -12,21 +12,21 @@
|
||||
#define SPFX_CHUNK 10 // Chunk to allocate when needed.
|
||||
|
||||
typedef struct SPFX_Base_ {
|
||||
char* name;
|
||||
char* name;
|
||||
|
||||
int anim; // Total duration in ms.
|
||||
glTexture* gfx; // Will use each sprite as a frame.
|
||||
int anim; // Total duration in ms.
|
||||
glTexture* gfx; // Will use each sprite as a frame.
|
||||
} SPFX_Base;
|
||||
|
||||
static SPFX_Base* spfx_effects = NULL;
|
||||
static int spfx_neffects = 0;
|
||||
|
||||
typedef struct SPFX_ {
|
||||
Vec2 pos, vel; // They don't accelerate.
|
||||
Vec2 pos, vel; // They don't accelerate.
|
||||
|
||||
int lastframe; // Need when pausing.
|
||||
int effect; // Actual effect.
|
||||
unsigned int t; // Start.
|
||||
int lastframe; // Need when pausing.
|
||||
int effect; // Actual effect.
|
||||
unsigned int t; // Start.
|
||||
} SPFX;
|
||||
|
||||
// Front stack is for effects on player.
|
||||
@ -48,198 +48,198 @@ static void spfx_delay_layer(SPFX* layer, int nlayer, unsigned int delay);
|
||||
|
||||
// Load the SPFX_Base.
|
||||
static int spfx_base_load(char* name, int anim, char* gfx, int sx, int sy) {
|
||||
SPFX_Base* cur;
|
||||
char buf[PATH_MAX];
|
||||
SPFX_Base* cur;
|
||||
char buf[PATH_MAX];
|
||||
|
||||
spfx_effects = realloc(spfx_effects, ++spfx_neffects*sizeof(SPFX_Base));
|
||||
cur = &spfx_effects[spfx_neffects-1];
|
||||
spfx_effects = realloc(spfx_effects, ++spfx_neffects*sizeof(SPFX_Base));
|
||||
cur = &spfx_effects[spfx_neffects-1];
|
||||
|
||||
cur->name = strdup(name);
|
||||
cur->anim = anim;
|
||||
sprintf(buf, SPFX_GFX"%s", gfx);
|
||||
cur->gfx = gl_newSprite(buf, sx, sy);
|
||||
cur->name = strdup(name);
|
||||
cur->anim = anim;
|
||||
sprintf(buf, SPFX_GFX"%s", gfx);
|
||||
cur->gfx = gl_newSprite(buf, sx, sy);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void spfx_base_free(SPFX_Base* effect) {
|
||||
if(effect->name) free(effect->name);
|
||||
if(effect->gfx) gl_freeTexture(effect->gfx);
|
||||
if(effect->name) free(effect->name);
|
||||
if(effect->gfx) gl_freeTexture(effect->gfx);
|
||||
}
|
||||
|
||||
int spfx_get(char* name) {
|
||||
int i;
|
||||
for(i = 0; i < spfx_neffects; i++)
|
||||
if(strcmp(spfx_effects[i].name, name)==0)
|
||||
return i;
|
||||
WARN("SPFX '%s' not found!", name);
|
||||
return 0;
|
||||
int i;
|
||||
for(i = 0; i < spfx_neffects; i++)
|
||||
if(strcmp(spfx_effects[i].name, name)==0)
|
||||
return i;
|
||||
WARN("SPFX '%s' not found!", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Load/Unload.
|
||||
int spfx_load(void) {
|
||||
spfx_base_load("ExpS", 400, "exps.png", 6, 5);
|
||||
spfx_base_load("ExpM", 450, "expm.png", 6, 5);
|
||||
spfx_base_load("ExpL", 500, "expl.png", 6, 5);
|
||||
return 0;
|
||||
spfx_base_load("ExpS", 400, "exps.png", 6, 5);
|
||||
spfx_base_load("ExpM", 450, "expm.png", 6, 5);
|
||||
spfx_base_load("ExpL", 500, "expl.png", 6, 5);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void spfx_free(void) {
|
||||
int i;
|
||||
int i;
|
||||
|
||||
// Get rid of all the particles and free the stacks.
|
||||
spfx_clear();
|
||||
if(spfx_stack_front) free(spfx_stack_front);
|
||||
spfx_stack_front = NULL;
|
||||
spfx_mstack_front = 0;
|
||||
if(spfx_stack_back) free(spfx_stack_back);
|
||||
spfx_stack_back = NULL;
|
||||
spfx_mstack_back = 0;
|
||||
// Get rid of all the particles and free the stacks.
|
||||
spfx_clear();
|
||||
if(spfx_stack_front) free(spfx_stack_front);
|
||||
spfx_stack_front = NULL;
|
||||
spfx_mstack_front = 0;
|
||||
if(spfx_stack_back) free(spfx_stack_back);
|
||||
spfx_stack_back = NULL;
|
||||
spfx_mstack_back = 0;
|
||||
|
||||
for(i = 0; i < spfx_neffects; i++)
|
||||
spfx_base_free(&spfx_effects[i]);
|
||||
free(spfx_effects);
|
||||
spfx_effects = NULL;
|
||||
spfx_neffects = 0;
|
||||
for(i = 0; i < spfx_neffects; i++)
|
||||
spfx_base_free(&spfx_effects[i]);
|
||||
free(spfx_effects);
|
||||
spfx_effects = NULL;
|
||||
spfx_neffects = 0;
|
||||
}
|
||||
|
||||
void spfx_add(int effect,
|
||||
const double px, const double py,
|
||||
const double vx, const double vy,
|
||||
const int layer) {
|
||||
SPFX* cur_spfx;
|
||||
const double px, const double py,
|
||||
const double vx, const double vy,
|
||||
const int layer) {
|
||||
SPFX* cur_spfx;
|
||||
|
||||
if(layer == SPFX_LAYER_FRONT) {
|
||||
// Front layer.
|
||||
if(spfx_mstack_front < spfx_nstack_front+1) {
|
||||
// We need more memory.
|
||||
spfx_mstack_front += SPFX_CHUNK;
|
||||
spfx_stack_front = realloc(spfx_stack_front, spfx_mstack_front*sizeof(SPFX));
|
||||
if(layer == SPFX_LAYER_FRONT) {
|
||||
// Front layer.
|
||||
if(spfx_mstack_front < spfx_nstack_front+1) {
|
||||
// We need more memory.
|
||||
spfx_mstack_front += SPFX_CHUNK;
|
||||
spfx_stack_front = realloc(spfx_stack_front, spfx_mstack_front*sizeof(SPFX));
|
||||
}
|
||||
cur_spfx = &spfx_stack_front[spfx_nstack_front];
|
||||
spfx_nstack_front++;
|
||||
}
|
||||
cur_spfx = &spfx_stack_front[spfx_nstack_front];
|
||||
spfx_nstack_front++;
|
||||
}
|
||||
else if(layer == SPFX_LAYER_BACK) {
|
||||
// Back layer.
|
||||
if(spfx_mstack_back < spfx_nstack_back+1) {
|
||||
// Need more memory.
|
||||
spfx_mstack_back += SPFX_CHUNK;
|
||||
spfx_stack_back = realloc(spfx_stack_back, spfx_mstack_back*sizeof(SPFX));
|
||||
else if(layer == SPFX_LAYER_BACK) {
|
||||
// Back layer.
|
||||
if(spfx_mstack_back < spfx_nstack_back+1) {
|
||||
// Need more memory.
|
||||
spfx_mstack_back += SPFX_CHUNK;
|
||||
spfx_stack_back = realloc(spfx_stack_back, spfx_mstack_back*sizeof(SPFX));
|
||||
}
|
||||
cur_spfx = &spfx_stack_back[spfx_nstack_back];
|
||||
spfx_nstack_back++;
|
||||
}
|
||||
cur_spfx = &spfx_stack_back[spfx_nstack_back];
|
||||
spfx_nstack_back++;
|
||||
}
|
||||
|
||||
cur_spfx->effect = effect;
|
||||
vect_csetmin(&cur_spfx->pos, px, py);
|
||||
vect_csetmin(&cur_spfx->vel, vx, vy);
|
||||
cur_spfx->t = SDL_GetTicks();
|
||||
cur_spfx->effect = effect;
|
||||
vect_csetmin(&cur_spfx->pos, px, py);
|
||||
vect_csetmin(&cur_spfx->vel, vx, vy);
|
||||
cur_spfx->t = SDL_GetTicks();
|
||||
}
|
||||
|
||||
void spfx_clear(void) {
|
||||
int i;
|
||||
for(i = spfx_nstack_front-1; i >= 0; i--)
|
||||
spfx_destroy(spfx_stack_front, &spfx_nstack_front, i);
|
||||
|
||||
for(i = spfx_nstack_back-1; i >= 0; i--)
|
||||
spfx_destroy(spfx_stack_back, &spfx_nstack_back, i);
|
||||
int i;
|
||||
for(i = spfx_nstack_front-1; i >= 0; i--)
|
||||
spfx_destroy(spfx_stack_front, &spfx_nstack_front, i);
|
||||
|
||||
for(i = spfx_nstack_back-1; i >= 0; i--)
|
||||
spfx_destroy(spfx_stack_back, &spfx_nstack_back, i);
|
||||
}
|
||||
|
||||
static void spfx_destroy(SPFX* layer, int* nlayer, int spfx) {
|
||||
(*nlayer)--;
|
||||
memmove(&layer[spfx], &layer[spfx+1], (*nlayer-spfx)*sizeof(SPFX));
|
||||
(*nlayer)--;
|
||||
memmove(&layer[spfx], &layer[spfx+1], (*nlayer-spfx)*sizeof(SPFX));
|
||||
}
|
||||
|
||||
void spfx_update(const double dt) {
|
||||
spfx_update_layer(spfx_stack_front, &spfx_nstack_front, dt);
|
||||
spfx_update_layer(spfx_stack_back, &spfx_nstack_back, dt);
|
||||
spfx_update_layer(spfx_stack_front, &spfx_nstack_front, dt);
|
||||
spfx_update_layer(spfx_stack_back, &spfx_nstack_back, dt);
|
||||
}
|
||||
|
||||
static void spfx_update_layer(SPFX* layer, int* nlayer, const double dt) {
|
||||
int i;
|
||||
unsigned int t = SDL_GetTicks();
|
||||
int i;
|
||||
unsigned int t = SDL_GetTicks();
|
||||
|
||||
for(i = 0; i < *nlayer; i++) {
|
||||
// Time to die!!!
|
||||
if(t > (layer[i].t + spfx_effects[layer[i].effect].anim)) {
|
||||
spfx_destroy(layer, nlayer, i);
|
||||
i--;
|
||||
continue;
|
||||
for(i = 0; i < *nlayer; i++) {
|
||||
// Time to die!!!
|
||||
if(t > (layer[i].t + spfx_effects[layer[i].effect].anim)) {
|
||||
spfx_destroy(layer, nlayer, i);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
// Mkay. Update it now.
|
||||
vect_cadd(&layer[i].pos, dt*VX(layer[i].vel), dt*VY(layer[i].vel));
|
||||
}
|
||||
// Mkay. Update it now.
|
||||
vect_cadd(&layer[i].pos, dt*VX(layer[i].vel), dt*VY(layer[i].vel));
|
||||
}
|
||||
}
|
||||
|
||||
void spfx_render(const int layer) {
|
||||
SPFX* spfx_stack;
|
||||
int i, spfx_nstack;
|
||||
SPFX_Base* effect;
|
||||
int sx, sy;
|
||||
unsigned int t = SDL_GetTicks();
|
||||
SPFX* spfx_stack;
|
||||
int i, spfx_nstack;
|
||||
SPFX_Base* effect;
|
||||
int sx, sy;
|
||||
unsigned int t = SDL_GetTicks();
|
||||
|
||||
// Get the appropriate layer.
|
||||
switch(layer) {
|
||||
// Get the appropriate layer.
|
||||
switch(layer) {
|
||||
case SPFX_LAYER_FRONT:
|
||||
spfx_stack = spfx_stack_front;
|
||||
spfx_nstack = spfx_nstack_front;
|
||||
break;
|
||||
spfx_stack = spfx_stack_front;
|
||||
spfx_nstack = spfx_nstack_front;
|
||||
break;
|
||||
case SPFX_LAYER_BACK:
|
||||
spfx_stack = spfx_stack_back;
|
||||
spfx_nstack = spfx_nstack_back;
|
||||
break;
|
||||
}
|
||||
for(i = 0; i < spfx_nstack; i++) {
|
||||
effect = &spfx_effects[spfx_stack[i].effect];
|
||||
spfx_stack = spfx_stack_back;
|
||||
spfx_nstack = spfx_nstack_back;
|
||||
break;
|
||||
}
|
||||
for(i = 0; i < spfx_nstack; i++) {
|
||||
effect = &spfx_effects[spfx_stack[i].effect];
|
||||
|
||||
sx = (int)effect->gfx->sx;
|
||||
sy = (int)effect->gfx->sy;
|
||||
sx = (int)effect->gfx->sx;
|
||||
sy = (int)effect->gfx->sy;
|
||||
|
||||
if(!paused) // Don't calculate frame if paused.
|
||||
spfx_stack[i].lastframe = sx * sy
|
||||
* MIN(((double)(t - spfx_stack[i].t)/(double)effect->anim), 1.);
|
||||
|
||||
gl_blitSprite(effect->gfx,
|
||||
VX(spfx_stack[i].pos), VY(spfx_stack[i].pos),
|
||||
spfx_stack[i].lastframe % sx,
|
||||
spfx_stack[i].lastframe / sx,
|
||||
NULL);
|
||||
}
|
||||
if(!paused) // Don't calculate frame if paused.
|
||||
spfx_stack[i].lastframe = sx * sy
|
||||
* MIN(((double)(t - spfx_stack[i].t)/(double)effect->anim), 1.);
|
||||
|
||||
gl_blitSprite(effect->gfx,
|
||||
VX(spfx_stack[i].pos), VY(spfx_stack[i].pos),
|
||||
spfx_stack[i].lastframe % sx,
|
||||
spfx_stack[i].lastframe / sx,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void spfx_pause(void) {
|
||||
spfx_pause_layer(spfx_stack_front, spfx_nstack_front);
|
||||
spfx_pause_layer(spfx_stack_back, spfx_nstack_back);
|
||||
spfx_pause_layer(spfx_stack_front, spfx_nstack_front);
|
||||
spfx_pause_layer(spfx_stack_back, spfx_nstack_back);
|
||||
|
||||
}
|
||||
|
||||
static void spfx_pause_layer(SPFX* layer, int nlayer) {
|
||||
int i;
|
||||
unsigned int t = SDL_GetTicks();
|
||||
for(i = 0; i < nlayer; i++)
|
||||
layer[i].t -= t;
|
||||
int i;
|
||||
unsigned int t = SDL_GetTicks();
|
||||
for(i = 0; i < nlayer; i++)
|
||||
layer[i].t -= t;
|
||||
}
|
||||
|
||||
void spfx_unpause(void) {
|
||||
spfx_unpause_layer(spfx_stack_front, spfx_nstack_front);
|
||||
spfx_unpause_layer(spfx_stack_back, spfx_nstack_back);
|
||||
spfx_unpause_layer(spfx_stack_front, spfx_nstack_front);
|
||||
spfx_unpause_layer(spfx_stack_back, spfx_nstack_back);
|
||||
}
|
||||
|
||||
static void spfx_unpause_layer(SPFX* layer, int nlayer) {
|
||||
int i;
|
||||
unsigned int t = SDL_GetTicks();
|
||||
for(i = 0; i < nlayer; i++)
|
||||
layer[i].t += t;
|
||||
int i;
|
||||
unsigned int t = SDL_GetTicks();
|
||||
for(i = 0; i < nlayer; i++)
|
||||
layer[i].t += t;
|
||||
}
|
||||
|
||||
void spfx_delay(unsigned int delay) {
|
||||
spfx_delay_layer(spfx_stack_front, spfx_nstack_front, delay);
|
||||
spfx_delay_layer(spfx_stack_back, spfx_nstack_back, delay);
|
||||
spfx_delay_layer(spfx_stack_front, spfx_nstack_front, delay);
|
||||
spfx_delay_layer(spfx_stack_back, spfx_nstack_back, delay);
|
||||
}
|
||||
|
||||
static void spfx_delay_layer(SPFX* layer, int nlayer, unsigned int delay) {
|
||||
int i;
|
||||
for(i = 0; i < nlayer; i++)
|
||||
layer[i].t += delay;
|
||||
int i;
|
||||
for(i = 0; i < nlayer; i++)
|
||||
layer[i].t += delay;
|
||||
}
|
||||
|
||||
|
@ -7,9 +7,9 @@
|
||||
// Stack manipulation.
|
||||
int spfx_get(char* name);
|
||||
void spfx_add(const int effect,
|
||||
const double px, const double py,
|
||||
const double vx, const double vy,
|
||||
const int layer);
|
||||
const double px, const double py,
|
||||
const double vx, const double vy,
|
||||
const int layer);
|
||||
|
||||
// Stack mass manipulation functions.
|
||||
void spfx_update(const double dt);
|
||||
|
1104
src/toolkit.c
1104
src/toolkit.c
File diff suppressed because it is too large
Load Diff
@ -7,36 +7,36 @@ extern int toolkit;
|
||||
|
||||
// Creation.
|
||||
unsigned int window_create(char* name, const int x, const int y,
|
||||
const int w, const int h);
|
||||
const int w, const int h);
|
||||
|
||||
void window_addButton(const unsigned int wid, const int x, const int y,
|
||||
const int w, const int h, char* name, char* display,
|
||||
void(*call)(char*));
|
||||
const int w, const int h, char* name, char* display,
|
||||
void(*call)(char*));
|
||||
|
||||
void window_addText(const unsigned int wid, const int x, const int y,
|
||||
const int w, const int h, const int centered, char* name,
|
||||
glFont* font, glColour* colour, char* string);
|
||||
const int w, const int h, const int centered, char* name,
|
||||
glFont* font, glColour* colour, char* string);
|
||||
|
||||
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,
|
||||
const int x, const int y, // Position.
|
||||
const int w, const int h, // Size.
|
||||
char* name, char** items, int nitems, int defitem,
|
||||
void(*call)(char*));
|
||||
const int x, const int y, // Position.
|
||||
const int w, const int h, // Size.
|
||||
char* name, char** items, int nitems, int defitem,
|
||||
void(*call)(char*));
|
||||
|
||||
void window_addRect(const unsigned int wid,
|
||||
const int x, const int y, // Position.
|
||||
const int w, const int h, // size.
|
||||
char* name, glColour* colour, int border); // Properties.
|
||||
const int x, const int y, // Position.
|
||||
const int w, const int h, // size.
|
||||
char* name, glColour* colour, int border); // Properties.
|
||||
|
||||
void window_addCust(const unsigned int wid,
|
||||
const int x, const int y, // Position.
|
||||
const int w, const int h, // Size.
|
||||
char* name, const int border,
|
||||
void(*render) (double x, double y, double w, double h),
|
||||
void(*mouse) (SDL_Event* event, double x, double y));
|
||||
const int x, const int y, // Position.
|
||||
const int w, const int h, // Size.
|
||||
char* name, const int border,
|
||||
void(*render) (double x, double y, double w, double h),
|
||||
void(*mouse) (SDL_Event* event, double x, double y));
|
||||
|
||||
// Popups and alerts.
|
||||
void toolkit_alert(const char* fmt, ...);
|
||||
|
387
src/weapon.c
387
src/weapon.c
@ -33,9 +33,9 @@ typedef struct Weapon_ {
|
||||
const Outfit* outfit; // Related outfit that fired.
|
||||
unsigned int timer; // Mainly used to see when the weapon was fired.
|
||||
|
||||
alVoice* voice; // Virtual voise.
|
||||
|
||||
// Update position and render.
|
||||
alVoice* voice; // Virtual voise.
|
||||
|
||||
// Update position and render.
|
||||
void(*update)(struct Weapon_*, const double, WeaponLayer); // Position update and render.
|
||||
void(*think)(struct Weapon_*, const double); // Some missiles need to be inteligent.
|
||||
} Weapon;
|
||||
@ -50,8 +50,9 @@ static int nwfrontLayer = 0; // Number of elements.
|
||||
static int mwfrontLayer = 0; // Allocated memory size.
|
||||
|
||||
static Weapon* weapon_create(const Outfit* outfit, const double dir,
|
||||
const Vec2* pos, const Vec2* vel, const unsigned int parent,
|
||||
const unsigned int target);
|
||||
const Vec2* pos, const Vec2* vel,
|
||||
const unsigned int parent,
|
||||
const unsigned int target);
|
||||
|
||||
static void weapon_render(const Weapon* w);
|
||||
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).
|
||||
#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,
|
||||
const double w, const double h, const RadarShape shape) {
|
||||
const double w, const double h, const RadarShape shape) {
|
||||
int i, rc;
|
||||
double x, y;
|
||||
|
||||
@ -78,7 +79,7 @@ void weapon_minimap(const double res,
|
||||
y = (wbackLayer[i]->solid->pos.y - player->solid->pos.y) / res;
|
||||
PIXEL(x,y);
|
||||
}
|
||||
|
||||
|
||||
for(i = 0; i < nwfrontLayer; i++) {
|
||||
x = (wfrontLayer[i]->solid->pos.x - player->solid->pos.x) / 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) {
|
||||
int i;
|
||||
for(i = 0; i < nwbackLayer; i++)
|
||||
wbackLayer[i]->timer += delay;
|
||||
for(i = 0; i < nwfrontLayer; i++)
|
||||
wfrontLayer[i]->timer += delay;
|
||||
int i;
|
||||
for(i = 0; i < nwbackLayer; i++)
|
||||
wbackLayer[i]->timer += delay;
|
||||
for(i = 0; i < nwfrontLayer; i++)
|
||||
wfrontLayer[i]->timer += delay;
|
||||
}
|
||||
|
||||
// Seeker brain, You get what you pay for. :)
|
||||
static void think_seeker(Weapon* w, const double dt) {
|
||||
double diff;
|
||||
double diff;
|
||||
if(w->target == w->parent) return; // HEY! Self harm is not allowed.
|
||||
|
||||
Pilot* p = pilot_get(w->target);
|
||||
if(p == NULL) {
|
||||
limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt);
|
||||
return;
|
||||
}
|
||||
limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt);
|
||||
return;
|
||||
}
|
||||
|
||||
// Ammo isn't locked on yet..
|
||||
if(SDL_GetTicks() > (w->timer + w->outfit->u.amm.lockon)) {
|
||||
diff = angle_diff(w->solid->dir, vect_angle(&w->solid->pos, &p->solid->pos));
|
||||
w->solid->dir_vel = 10 * diff * w->outfit->u.amm.turn;
|
||||
// Face the target.
|
||||
if(w->solid->dir_vel > w->outfit->u.amm.turn)
|
||||
w->solid->dir_vel = w->outfit->u.amm.turn;
|
||||
else if(w->solid->dir_vel < -w->outfit->u.amm.turn)
|
||||
w->solid->dir_vel = -w->outfit->u.amm.turn;
|
||||
}
|
||||
if(SDL_GetTicks() > (w->timer + w->outfit->u.amm.lockon)) {
|
||||
diff = angle_diff(w->solid->dir, vect_angle(&w->solid->pos, &p->solid->pos));
|
||||
w->solid->dir_vel = 10 * diff * w->outfit->u.amm.turn;
|
||||
// Face the target.
|
||||
if(w->solid->dir_vel > w->outfit->u.amm.turn)
|
||||
w->solid->dir_vel = w->outfit->u.amm.turn;
|
||||
else if(w->solid->dir_vel < -w->outfit->u.amm.turn)
|
||||
w->solid->dir_vel = -w->outfit->u.amm.turn;
|
||||
}
|
||||
|
||||
vect_pset(&w->solid->force, w->outfit->u.amm.thrust, w->solid->dir);
|
||||
|
||||
limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt);
|
||||
|
||||
limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt);
|
||||
}
|
||||
|
||||
// Smart seeker brain. Much better at homing.
|
||||
static void think_smart(Weapon* w, const double dt) {
|
||||
double diff;
|
||||
Vec2 tv, sv;
|
||||
double diff;
|
||||
Vec2 tv, sv;
|
||||
|
||||
if(w->target == w->parent) return; // No self shooting here.
|
||||
if(w->target == w->parent) return; // No self shooting here.
|
||||
|
||||
Pilot* p = pilot_get(w->target); // No null pilots..
|
||||
Pilot* p = pilot_get(w->target); // No null pilots..
|
||||
|
||||
if(p == NULL) {
|
||||
limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt);
|
||||
return;
|
||||
}
|
||||
|
||||
if(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);
|
||||
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;
|
||||
|
||||
switch(layer) {
|
||||
case WEAPON_LAYER_BG:
|
||||
wlayer = wbackLayer;
|
||||
nlayer = &nwbackLayer;
|
||||
break;
|
||||
case WEAPON_LAYER_FG:
|
||||
wlayer = wfrontLayer;
|
||||
nlayer = &nwfrontLayer;
|
||||
break;
|
||||
case WEAPON_LAYER_BG:
|
||||
wlayer = wbackLayer;
|
||||
nlayer = &nwbackLayer;
|
||||
break;
|
||||
case WEAPON_LAYER_FG:
|
||||
wlayer = wfrontLayer;
|
||||
nlayer = &nwfrontLayer;
|
||||
break;
|
||||
}
|
||||
int i;
|
||||
Weapon* w;
|
||||
for(i = 0; i < (*nlayer); i++) {
|
||||
w = wlayer[i];
|
||||
switch(wlayer[i]->outfit->type) {
|
||||
// Most missiles behave the same.
|
||||
case OUTFIT_TYPE_MISSILE_SEEK_AMMO:
|
||||
case OUTFIT_TYPE_MISSILE_SEEK_SMART_AMMO:
|
||||
case OUTFIT_TYPE_MISSILE_SWARM_AMMO:
|
||||
case OUTFIT_TYPE_MISSILE_SWARM_SMART_AMMO:
|
||||
if(SDL_GetTicks() >
|
||||
(wlayer[i]->timer + wlayer[i]->outfit->u.amm.duration)) {
|
||||
weapon_destroy(wlayer[i], layer);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case OUTFIT_TYPE_BOLT:
|
||||
// Check see if it exceeds distance.
|
||||
case OUTFIT_TYPE_TURRET_BOLT:
|
||||
if(SDL_GetTicks() > wlayer[i]->timer) {
|
||||
weapon_destroy(wlayer[i],layer);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
// Most missiles behave the same.
|
||||
case OUTFIT_TYPE_MISSILE_SEEK_AMMO:
|
||||
case OUTFIT_TYPE_MISSILE_SEEK_SMART_AMMO:
|
||||
case OUTFIT_TYPE_MISSILE_SWARM_AMMO:
|
||||
case OUTFIT_TYPE_MISSILE_SWARM_SMART_AMMO:
|
||||
if(SDL_GetTicks() >
|
||||
(wlayer[i]->timer + wlayer[i]->outfit->u.amm.duration)) {
|
||||
weapon_destroy(wlayer[i], layer);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case OUTFIT_TYPE_BOLT:
|
||||
// Check see if it exceeds distance.
|
||||
case OUTFIT_TYPE_TURRET_BOLT:
|
||||
if(SDL_GetTicks() > wlayer[i]->timer) {
|
||||
weapon_destroy(wlayer[i],layer);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
weapon_update(wlayer[i], dt, layer);
|
||||
// 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;
|
||||
|
||||
switch(layer) {
|
||||
case WEAPON_LAYER_BG:
|
||||
wlayer = wbackLayer;
|
||||
nlayer = &nwbackLayer;
|
||||
break;
|
||||
case WEAPON_LAYER_FG:
|
||||
wlayer = wfrontLayer;
|
||||
nlayer = &nwfrontLayer;
|
||||
break;
|
||||
case WEAPON_LAYER_BG:
|
||||
wlayer = wbackLayer;
|
||||
nlayer = &nwbackLayer;
|
||||
break;
|
||||
case WEAPON_LAYER_FG:
|
||||
wlayer = wfrontLayer;
|
||||
nlayer = &nwfrontLayer;
|
||||
break;
|
||||
}
|
||||
for(i = 0; i < (*nlayer); i++)
|
||||
weapon_render(wlayer[i]);
|
||||
@ -252,9 +253,9 @@ void weapons_render(const WeaponLayer layer) {
|
||||
// Render the weapons.
|
||||
static void weapon_render(const Weapon* w) {
|
||||
int sx, sy;
|
||||
glTexture* gfx;
|
||||
glTexture* gfx;
|
||||
|
||||
gfx = outfit_gfx(w->outfit);
|
||||
gfx = outfit_gfx(w->outfit);
|
||||
|
||||
// Get the sprite corresponding to the direction facing.
|
||||
gl_getSpriteFromDir(&sx, &sy, gfx, w->solid->dir);
|
||||
@ -265,41 +266,41 @@ static void weapon_render(const Weapon* w) {
|
||||
// Update the weapon.
|
||||
static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) {
|
||||
int i, wsx, wsy, psx, psy;
|
||||
glTexture* gfx;
|
||||
glTexture* gfx;
|
||||
|
||||
gfx = outfit_gfx(w->outfit);
|
||||
gfx = outfit_gfx(w->outfit);
|
||||
|
||||
gl_getSpriteFromDir(&wsx, &wsy, gfx, w->solid->dir);
|
||||
|
||||
for(i = 0; i < pilots; i++) {
|
||||
psx = pilot_stack[i]->tsx;
|
||||
psy = pilot_stack[i]->tsy;
|
||||
psx = pilot_stack[i]->tsx;
|
||||
psy = pilot_stack[i]->tsy;
|
||||
|
||||
if(w->parent == pilot_stack[i]->id) continue; // Hey! That's you.
|
||||
|
||||
if((weapon_isSmart(w)) && (pilot_stack[i]->id == w->target) &&
|
||||
CollideSprite(gfx, wsx, wsy, &w->solid->pos,
|
||||
pilot_stack[i]->ship->gfx_space, psx, psy, &pilot_stack[i]->solid->pos)) {
|
||||
CollideSprite(gfx, wsx, wsy, &w->solid->pos,
|
||||
pilot_stack[i]->ship->gfx_space, psx, psy, &pilot_stack[i]->solid->pos)) {
|
||||
weapon_hit(w, pilot_stack[i], layer);
|
||||
return;
|
||||
}
|
||||
else if(!weapon_isSmart(w) &&
|
||||
!areAllies(pilot_get(w->parent)->faction, pilot_stack[i]->faction) &&
|
||||
CollideSprite(gfx, wsx, wsy, &w->solid->pos,
|
||||
pilot_stack[i]->ship->gfx_space, psx, psy, &pilot_stack[i]->solid->pos)) {
|
||||
!areAllies(pilot_get(w->parent)->faction, pilot_stack[i]->faction) &&
|
||||
CollideSprite(gfx, wsx, wsy, &w->solid->pos,
|
||||
pilot_stack[i]->ship->gfx_space, psx, psy, &pilot_stack[i]->solid->pos)) {
|
||||
weapon_hit(w, pilot_stack[i], layer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(weapon_isSmart(w)) (*w->think)(w,dt);
|
||||
|
||||
|
||||
if(weapon_isSmart(w)) (*w->think)(w,dt);
|
||||
|
||||
(*w->solid->update)(w->solid, dt);
|
||||
|
||||
// Update the sound.
|
||||
if(w->voice)
|
||||
voice_update(w->voice, w->solid->pos.x, w->solid->pos.y,
|
||||
w->solid->vel.x, w->solid->vel.y);
|
||||
// Update the sound.
|
||||
if(w->voice)
|
||||
voice_update(w->voice, w->solid->pos.x, w->solid->pos.y,
|
||||
w->solid->vel.x, w->solid->vel.y);
|
||||
}
|
||||
|
||||
// Good shot.
|
||||
@ -307,13 +308,13 @@ static void weapon_hit(Weapon* w, Pilot* p, WeaponLayer layer) {
|
||||
// Someone should let the ai know it's been attacked.
|
||||
if(!pilot_isPlayer(p)) {
|
||||
ai_attacked(p, w->parent);
|
||||
spfx_add(outfit_spfx(w->outfit),
|
||||
VX(w->solid->pos), VY(w->solid->pos),
|
||||
VX(p->solid->vel), VY(p->solid->vel), SPFX_LAYER_BACK);
|
||||
} else
|
||||
spfx_add(outfit_spfx(w->outfit),
|
||||
VX(w->solid->pos), VY(w->solid->pos),
|
||||
VX(p->solid->vel), VY(p->solid->vel), SPFX_LAYER_FRONT);
|
||||
spfx_add(outfit_spfx(w->outfit),
|
||||
VX(w->solid->pos), VY(w->solid->pos),
|
||||
VX(p->solid->vel), VY(p->solid->vel), SPFX_LAYER_BACK);
|
||||
} else
|
||||
spfx_add(outfit_spfx(w->outfit),
|
||||
VX(w->solid->pos), VY(w->solid->pos),
|
||||
VX(p->solid->vel), VY(p->solid->vel), SPFX_LAYER_FRONT);
|
||||
|
||||
if(w->parent == PLAYER_ID)
|
||||
// Make hostile to player.
|
||||
@ -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,
|
||||
const Vec2* vel, unsigned int parent, const unsigned int target) {
|
||||
const Vec2* vel, unsigned int parent, const unsigned int target) {
|
||||
Vec2 v;
|
||||
double mass = 1; // Presumer lasers have a mass of 1.
|
||||
double rdir = dir; // Real direction (accuracy).
|
||||
@ -339,63 +340,63 @@ static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2*
|
||||
w->think = NULL;
|
||||
|
||||
switch(outfit->type) {
|
||||
case OUTFIT_TYPE_BOLT:
|
||||
// Need accuracy and speed based on player. -- Another contribution from VLack.
|
||||
rdir += RNG(-outfit->u.blt.accuracy/2., outfit->u.blt.accuracy/2.)/180.*M_PI;
|
||||
if((rdir > 2.*M_PI) || (rdir < 0.)) rdir = fmod(rdir, 2.*M_PI);
|
||||
vectcpy(&v, vel);
|
||||
vect_cadd(&v, outfit->u.blt.speed*cos(rdir), outfit->u.blt.speed*sin(rdir));
|
||||
w->timer += 1000*(unsigned int)outfit->u.blt.range/outfit->u.blt.speed;
|
||||
w->solid = solid_create(mass, rdir, pos, &v);
|
||||
w->voice = sound_addVoice(VOICE_PRIORITY_BOLT,
|
||||
w->solid->pos.x, w->solid->pos.y,
|
||||
w->solid->vel.x, w->solid->vel.y, w->outfit->u.blt.sound, 0);
|
||||
break;
|
||||
case OUTFIT_TYPE_MISSILE_SEEK_AMMO:
|
||||
mass = w->outfit->mass;
|
||||
w->solid = solid_create(mass, dir, pos, vel);
|
||||
w->think = think_seeker; // Eeek!!!
|
||||
w->voice = sound_addVoice(VOICE_PRIORITY_AMMO,
|
||||
w->solid->pos.x, w->solid->pos.y,
|
||||
w->solid->vel.x, w->solid->vel.y, w->outfit->u.amm.sound, 0);
|
||||
break;
|
||||
case OUTFIT_TYPE_BOLT:
|
||||
// Need accuracy and speed based on player. -- Another contribution from VLack.
|
||||
rdir += RNG(-outfit->u.blt.accuracy/2., outfit->u.blt.accuracy/2.)/180.*M_PI;
|
||||
if((rdir > 2.*M_PI) || (rdir < 0.)) rdir = fmod(rdir, 2.*M_PI);
|
||||
vectcpy(&v, vel);
|
||||
vect_cadd(&v, outfit->u.blt.speed*cos(rdir), outfit->u.blt.speed*sin(rdir));
|
||||
w->timer += 1000*(unsigned int)outfit->u.blt.range/outfit->u.blt.speed;
|
||||
w->solid = solid_create(mass, rdir, pos, &v);
|
||||
w->voice = sound_addVoice(VOICE_PRIORITY_BOLT,
|
||||
w->solid->pos.x, w->solid->pos.y,
|
||||
w->solid->vel.x, w->solid->vel.y, w->outfit->u.blt.sound, 0);
|
||||
break;
|
||||
case OUTFIT_TYPE_MISSILE_SEEK_AMMO:
|
||||
mass = w->outfit->mass;
|
||||
w->solid = solid_create(mass, dir, pos, vel);
|
||||
w->think = think_seeker; // Eeek!!!
|
||||
w->voice = sound_addVoice(VOICE_PRIORITY_AMMO,
|
||||
w->solid->pos.x, w->solid->pos.y,
|
||||
w->solid->vel.x, w->solid->vel.y, w->outfit->u.amm.sound, 0);
|
||||
break;
|
||||
case OUTFIT_TYPE_MISSILE_SEEK_SMART_AMMO:
|
||||
mass = w->outfit->mass;
|
||||
w->solid = solid_create(mass, dir, pos, vel);
|
||||
w->think = think_smart; // Smartass.
|
||||
w->voice = sound_addVoice(VOICE_PRIORITY_AMMO,
|
||||
w->solid->pos.x, w->solid->pos.y,
|
||||
w->solid->vel.x, w->solid->vel.y, w->outfit->u.amm.sound, 0);
|
||||
break;
|
||||
mass = w->outfit->mass;
|
||||
w->solid = solid_create(mass, dir, pos, vel);
|
||||
w->think = think_smart; // Smartass.
|
||||
w->voice = sound_addVoice(VOICE_PRIORITY_AMMO,
|
||||
w->solid->pos.x, w->solid->pos.y,
|
||||
w->solid->vel.x, w->solid->vel.y, w->outfit->u.amm.sound, 0);
|
||||
break;
|
||||
case OUTFIT_TYPE_TURRET_BOLT:
|
||||
if(w->parent != w->target)
|
||||
rdir = vect_angle(pos, &pilot_get(w->target)->solid->pos);
|
||||
rdir += RNG(-outfit->u.blt.accuracy/2.,
|
||||
outfit->u.blt.accuracy/2.)/180.*M_PI;
|
||||
if((rdir > 2.*M_PI) || (rdir < 0.)) rdir = fmod(rdir, 2.*M_PI);
|
||||
vectcpy(&v, vel);
|
||||
vect_cadd(&v, outfit->u.blt.speed*cos(rdir), outfit->u.blt.speed*sin(rdir));
|
||||
w->timer += 1000*(unsigned int)outfit->u.blt.range / outfit->u.blt.speed;
|
||||
w->solid = solid_create(mass, rdir, pos, &v);
|
||||
w->voice = sound_addVoice(VOICE_PRIORITY_BOLT,
|
||||
w->solid->pos.x, w->solid->pos.y,
|
||||
w->solid->vel.x, w->solid->vel.y, w->outfit->u.blt.sound, 0);
|
||||
break;
|
||||
default:
|
||||
// Just dump it where the player is.
|
||||
w->voice = NULL;
|
||||
w->solid = solid_create(mass, dir, pos, vel);
|
||||
break;
|
||||
if(w->parent != w->target)
|
||||
rdir = vect_angle(pos, &pilot_get(w->target)->solid->pos);
|
||||
rdir += RNG(-outfit->u.blt.accuracy/2.,
|
||||
outfit->u.blt.accuracy/2.)/180.*M_PI;
|
||||
if((rdir > 2.*M_PI) || (rdir < 0.)) rdir = fmod(rdir, 2.*M_PI);
|
||||
vectcpy(&v, vel);
|
||||
vect_cadd(&v, outfit->u.blt.speed*cos(rdir), outfit->u.blt.speed*sin(rdir));
|
||||
w->timer += 1000*(unsigned int)outfit->u.blt.range / outfit->u.blt.speed;
|
||||
w->solid = solid_create(mass, rdir, pos, &v);
|
||||
w->voice = sound_addVoice(VOICE_PRIORITY_BOLT,
|
||||
w->solid->pos.x, w->solid->pos.y,
|
||||
w->solid->vel.x, w->solid->vel.y, w->outfit->u.blt.sound, 0);
|
||||
break;
|
||||
default:
|
||||
// Just dump it where the player is.
|
||||
w->voice = NULL;
|
||||
w->solid = solid_create(mass, dir, pos, vel);
|
||||
break;
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
// Add a new weapon.
|
||||
void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos,
|
||||
const Vec2* vel, unsigned int parent, unsigned int target) {
|
||||
|
||||
if(!outfit_isWeapon(outfit) &&
|
||||
!outfit_isAmmo(outfit) && !outfit_isTurret(outfit)) {
|
||||
const Vec2* vel, unsigned int parent, unsigned int target) {
|
||||
|
||||
if(!outfit_isWeapon(outfit) &&
|
||||
!outfit_isAmmo(outfit) && !outfit_isTurret(outfit)) {
|
||||
ERR("Trying to create a weapon from a non-Weapon type Outfit");
|
||||
return;
|
||||
}
|
||||
@ -408,30 +409,30 @@ void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos,
|
||||
int* mLayer = NULL;
|
||||
int* nLayer = NULL;
|
||||
switch(layer) {
|
||||
case WEAPON_LAYER_BG:
|
||||
curLayer = wbackLayer;
|
||||
nLayer = &nwbackLayer;
|
||||
mLayer = &mwbackLayer;
|
||||
break;
|
||||
case WEAPON_LAYER_FG:
|
||||
curLayer = wfrontLayer;
|
||||
nLayer = &nwfrontLayer;
|
||||
mLayer = &mwfrontLayer;
|
||||
break;
|
||||
default:
|
||||
ERR("Invalid WEAPON_LAYER specified.");
|
||||
return;
|
||||
case WEAPON_LAYER_BG:
|
||||
curLayer = wbackLayer;
|
||||
nLayer = &nwbackLayer;
|
||||
mLayer = &mwbackLayer;
|
||||
break;
|
||||
case WEAPON_LAYER_FG:
|
||||
curLayer = wfrontLayer;
|
||||
nLayer = &nwfrontLayer;
|
||||
mLayer = &mwfrontLayer;
|
||||
break;
|
||||
default:
|
||||
ERR("Invalid WEAPON_LAYER specified.");
|
||||
return;
|
||||
}
|
||||
if(*mLayer > *nLayer) // More memory allocated than what we need.
|
||||
curLayer[(*nLayer)++] = w;
|
||||
else { // Need to allocate more memory.
|
||||
switch(layer) {
|
||||
case WEAPON_LAYER_BG:
|
||||
curLayer = wbackLayer = realloc(curLayer, (++(*mLayer))*sizeof(Weapon*));
|
||||
break;
|
||||
case WEAPON_LAYER_FG:
|
||||
curLayer = wfrontLayer = realloc(curLayer, (++(*mLayer))*sizeof(Weapon*));
|
||||
break;
|
||||
case WEAPON_LAYER_BG:
|
||||
curLayer = wbackLayer = realloc(curLayer, (++(*mLayer))*sizeof(Weapon*));
|
||||
break;
|
||||
case WEAPON_LAYER_FG:
|
||||
curLayer = wfrontLayer = realloc(curLayer, (++(*mLayer))*sizeof(Weapon*));
|
||||
break;
|
||||
}
|
||||
curLayer[(*nLayer)++] = w;
|
||||
}
|
||||
@ -443,27 +444,27 @@ static void weapon_destroy(Weapon* w, WeaponLayer layer) {
|
||||
Weapon** wlayer;
|
||||
int* nlayer;
|
||||
switch(layer) {
|
||||
case WEAPON_LAYER_BG:
|
||||
wlayer = wbackLayer;
|
||||
nlayer = &nwbackLayer;
|
||||
break;
|
||||
case WEAPON_LAYER_FG:
|
||||
wlayer = wfrontLayer;
|
||||
nlayer = &nwfrontLayer;
|
||||
break;
|
||||
case WEAPON_LAYER_BG:
|
||||
wlayer = wbackLayer;
|
||||
nlayer = &nwbackLayer;
|
||||
break;
|
||||
case WEAPON_LAYER_FG:
|
||||
wlayer = wfrontLayer;
|
||||
nlayer = &nwfrontLayer;
|
||||
break;
|
||||
}
|
||||
for(i = 0; wlayer[i] != w; i++); // Get us to the current posision.
|
||||
weapon_free(wlayer[i]);
|
||||
wlayer[i] = NULL;
|
||||
(*nlayer)--;
|
||||
|
||||
|
||||
for(; i < (*nlayer); i++)
|
||||
wlayer[i] = wlayer[i+1];
|
||||
}
|
||||
|
||||
// Clear the weapon.
|
||||
static void weapon_free(Weapon* w) {
|
||||
sound_delVoice(w->voice);
|
||||
sound_delVoice(w->voice);
|
||||
solid_free(w->solid);
|
||||
free(w);
|
||||
}
|
||||
|
@ -4,8 +4,9 @@
|
||||
|
||||
typedef enum { WEAPON_LAYER_BG, WEAPON_LAYER_FG } WeaponLayer;
|
||||
|
||||
void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos,
|
||||
const Vec2* vel, unsigned int parent, const unsigned int target);
|
||||
void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos,
|
||||
const Vec2* vel, unsigned int parent,
|
||||
const unsigned int target);
|
||||
|
||||
// Pausing.
|
||||
void weapons_pause(void);
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
// Check if node n is of name s.
|
||||
#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.
|
||||
#define xml_nodeProp(n,s) (char*)xmlGetProp(n, (xmlChar*)s)
|
||||
|
Loading…
Reference in New Issue
Block a user