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

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

View File

@ -29,7 +29,7 @@
// B and until the control task comes in. Then the pilot could
// 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;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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",

View File

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

View File

@ -65,7 +65,7 @@ static void render_space(void);
#ifdef WIN32
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine,
int nCmdShow) {
int nCmdShow) {
int argc = 0;
char *argv[] = { NULL };
#else
@ -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);

View File

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

340
src/map.c
View File

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

View File

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

View File

@ -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.
&section); // Current bitstream.
if(result == 0) return 1;
else if(result == OV_HOLE) {
WARN("OGG: Vorbis hole detected in music!");
return 0;
}
else if(result == OV_EBADLINK) {
WARN("OGG: Invalid stream section or corrupt link in music!");
return -1;
size = 0;
while(size < BUFFER_SIZE) {
// Fill up the entire data buffer.
result = ov_read(
&music_vorbis.stream, // Stream.
data + size, // Data.
BUFFER_SIZE - size, // Amount to read.
0, // Big endian?.
2, // 16 bit.
1, // Signed.
&section); // Current bitstream.
if(result == 0) return 1;
else if(result == OV_HOLE) {
WARN("OGG: Vorbis hole detected in music!");
return 0;
}
else if(result == OV_EBADLINK) {
WARN("OGG: Invalid stream section or corrupt link in music!");
return -1;
}
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);
}

View File

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

View File

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

View File

@ -42,24 +42,24 @@ Outfit* outfit_get(const char* name) {
// Return all the outfits.
char** outfit_getTech(int* n, const int* tech, const int techmax) {
int i, j;
char** outfitnames = malloc(sizeof(Outfit*) * outfits);
*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);
}

View File

@ -21,10 +21,10 @@ typedef enum OutfitType_ {
OUTFIT_TYPE_MISSILE_SWARM_AMMO = 10,
OUTFIT_TYPE_MISSILE_SWARM_SMART = 11,
OUTFIT_TYPE_MISSILE_SWARM_SMART_AMMO = 12,
OUTFIT_TYPE_TURRET_BOLT = 13,
OUTFIT_TYPE_TURRET_BEAM = 14,
OUTFIT_TYPE_MODIFICATION = 15,
OUTFIT_TYPE_AFTERBURNER = 16
OUTFIT_TYPE_TURRET_BOLT = 13,
OUTFIT_TYPE_TURRET_BEAM = 14,
OUTFIT_TYPE_MODIFICATION = 15,
OUTFIT_TYPE_AFTERBURNER = 16
} OutfitType;
// An outfit depends a lot on the type.
@ -36,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;

View File

@ -52,25 +52,25 @@ static off_t getfilesize(const char* filename) {
ERR("Unable to get filesize of %s", filename);
return 0;
#else
long size;
FILE* fp = fopen(filename, "rb");
if(fp == NULL) return 0;
long size;
FILE* fp = fopen(filename, "rb");
if(fp == NULL) return 0;
fseek(fp, 0, SEEK_END);
size = ftell(fp);
fseek(fp, 0, SEEK_END);
size = ftell(fp);
fclose(fp);
fclose(fp);
return size;
return size;
#endif
}
// Return true if filename is a Packfile.
int pack_check(const char* filename) {
int ret;
char* buf;
int ret;
char* buf;
buf = malloc(sizeof(magic));
buf = malloc(sizeof(magic));
#ifdef _POSIX_SOURCE
int fd = open(filename, O_RDONLY);
@ -84,24 +84,24 @@ int pack_check(const char* filename) {
free(buf);
return -1;
}
ret = (memcmp(buf, &magic, sizeof(magic))==0) ? 0 : 1;
close(fd);
ret = (memcmp(buf, &magic, sizeof(magic))==0) ? 0 : 1;
close(fd);
#else
FILE* file = fopen(filename, "rb");
if(file == NULL) {
ERR("Error opening '%s': %s", filename, strerror(errno));
return -1;
}
FILE* file = fopen(filename, "rb");
if(file == NULL) {
ERR("Error opening '%s': %s", filename, strerror(errno));
return -1;
}
buf = malloc(sizeof(magic));
if(fread(buf, 1, sizeof(magic), file) != sizeof(magic)) {
ERR("Error reading magic number: %s", strerror(errno));
free(buf);
return -1;
}
buf = malloc(sizeof(magic));
if(fread(buf, 1, sizeof(magic), file) != sizeof(magic)) {
ERR("Error reading magic number: %s", strerror(errno));
free(buf);
return -1;
}
ret = (memcmp(buf, &magic, sizeof(magic))==0) ? 0 : 1;
fclose(file);
ret = (memcmp(buf, &magic, sizeof(magic))==0) ? 0 : 1;
fclose(file);
#endif
free(buf);
@ -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;
}

View File

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

View File

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

View File

@ -15,9 +15,9 @@ double angle_diff(const double ref, double a) {
}
void limit_speed(Vec2* vel, const double speed, const double dt) {
double vmod = VMOD(*vel);
if(vmod > speed) // Should not go faster.
vect_pset(vel, (vmod-speed)*(1.-dt*3.) + speed, VANGLE(*vel));
double vmod = VMOD(*vel);
if(vmod > speed) // Should not go faster.
vect_pset(vel, (vmod-speed)*(1.-dt*3.) + speed, VANGLE(*vel));
}
// ================
@ -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);

View File

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

View File

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

View File

@ -10,11 +10,11 @@
#define PLAYER_ID 1
#define HYPERSPACE_ENGINE_DELAY 3000 // Warm up the engines.
#define HYPERSPACE_FLY_DELAY 5000 // Time taken to hyperspace.
#define HYPERSPACE_STARS_BLUR 2000 // Time stars blur.
#define HYPERSPACE_STARS_LENGTH 1000 // Length the stars blur to at max.
#define HYPERSPACE_FADEOUT 1000 // Time fadeout.
#define HYPERSPACE_ENGINE_DELAY 3000 // Warm up the engines.
#define HYPERSPACE_FLY_DELAY 5000 // Time taken to hyperspace.
#define HYPERSPACE_STARS_BLUR 2000 // Time stars blur.
#define HYPERSPACE_STARS_LENGTH 1000 // Length the stars blur to at max.
#define HYPERSPACE_FADEOUT 1000 // Time fadeout.
// Aproximation for pilot size.
#define PILOT_SIZE_APROX 0.8
@ -26,18 +26,18 @@
#define pilot_rmFlag(p,f) (p->flags ^= (f))
// Creation.
#define PILOT_PLAYER (1<<0) // Pilot is a player.
#define PILOT_HASTURRET (1<<20) // Pilit has turrets.
#define PILOT_HASTURRET (1<<20) // Pilit has turrets.
// Dynamic.
#define PILOT_HOSTILE (1<<1) // Pilot is hostile to the player.
#define PILOT_COMBAT (1<<2) // Pilot is engaged in combat.
#define PILOT_AFTERBURNER (1<<3) // Pilot has her afterburner activated.
#define PILOT_AFTERBURNER (1<<3) // Pilot has her afterburner activated.
#define PILOT_HYP_PREP (1<<5) // Pilot is getting ready for hyperspace.
#define PILOT_HYP_BEGIN (1<<6) // Pilot is starting engines.
#define PILOT_HYPERSPACE (1<<7) // Pilot is in hyperspace.
#define PILOT_BOARDED (1<<8) // Pilot has been boarded already!
#define PILOT_BOARDED (1<<8) // Pilot has been boarded already!
#define PILOT_DISABLED (1<<9) // Pilot is disabled.
#define PILOT_DEAD (1<<10) // Pilot is on it's death bed.
#define PILOT_EXPLODED (1<<11) // Pilot did final death explosion.
#define PILOT_DEAD (1<<10) // Pilot is on it's death bed.
#define PILOT_EXPLODED (1<<11) // Pilot did final death explosion.
#define PILOT_DELETE (1<<15) // Pilot will get delete asap.
// Just makes life simpler.
@ -45,14 +45,14 @@
#define pilot_isDisabled(p) ((p)->flags & PILOT_DISABLED)
typedef struct PilotOutfit_ {
Outfit* outfit; // Associated outfit.
int quantity; // Number of outfits of this type that the pilot has.
Outfit* outfit; // Associated outfit.
int quantity; // Number of outfits of this type that the pilot has.
unsigned int timer; // Used to store last used weapon time.
} PilotOutfit;
typedef struct PilotCommodity_ {
Commodity* commodity;
int quantity;
Commodity* commodity;
int quantity;
} PilotCommodity;
// Primary pilot structure.
@ -65,14 +65,14 @@ typedef struct Pilot_ {
// Object characteristics.
Ship* ship; // Pilots ship.
Solid* solid; // Associated solid (physics).
int tsx, tsy; // Current sprite, calculated on update.
int tsx, tsy; // Current sprite, calculated on update.
double thrust, turn, speed;
double thrust, turn, speed;
// Current health.
double armour, shield, energy;
double armour_max, shield_max, energy_max;
double armour_regen, shield_regen, energy_regen;
double armour_regen, shield_regen, energy_regen;
double fuel; // Used only for jumps. TODO: make it do something.
void (*think)(struct Pilot_*); // AI thinking for the pilot.
@ -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);

View File

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

View File

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

View File

@ -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"
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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