[Add] Information and ship spec widows with keybins 'i'
[Change] Cleaned up some MELEMENT sanity checks.
This commit is contained in:
parent
7d04d86146
commit
efe9970854
@ -21,7 +21,7 @@ CFLAGS = $(CLUA) $(CSDL) $(CXML) $(CTTF) $(CGL) $(CAL) $(CVORBIS) $(VERSION)
|
||||
ifdef DEBUG
|
||||
CFLAGS += -W -Wall -g3 -DDEBUG -DLUA_USE_APICHECK
|
||||
else
|
||||
CFLAGS += -O2 -funroll-loops
|
||||
CFLAGS += -O2 -funroll-loops -pipe
|
||||
endif
|
||||
|
||||
LDLUA = ../lib/lua/liblua.a
|
||||
|
@ -19,6 +19,7 @@ glColour cRed = { .r = 0.80, .g = 0.20, .b = 0.20, .a = 1 };
|
||||
|
||||
// Game specific.
|
||||
glColour cConsole = { .r = 0.1, .g = 0.9, .b = 0.1, .a = 1. };
|
||||
glColour cDConsole = { .r = 0.0, .g = 0.7, .b = 0.0, .a = 1. };
|
||||
// Objects
|
||||
glColour cInert = { .r = 0.6, .g = 0.6, .b = 0.6, .a = 1. };
|
||||
glColour cNeutral = { .r = 0.9, .g = 1.0, .b = 0.3, .a = 1. };
|
||||
|
@ -28,6 +28,7 @@ extern glColour cRed;
|
||||
|
||||
// Game specific.
|
||||
extern glColour cConsole;
|
||||
extern glColour cDConsole;
|
||||
// Objects.
|
||||
extern glColour cInert;
|
||||
extern glColour cNeutral;
|
||||
|
12
src/input.c
12
src/input.c
@ -25,7 +25,8 @@ const char* keybindNames[] = { "accel", "left", "right", "reverse", // Movement.
|
||||
"primary", "target", "target_nearest", "face", "board", // Combat.
|
||||
"secondary", "secondary_next", // Secondary weapons.
|
||||
"target_planet", "land", "thyperspace", "jump", // Navigation.
|
||||
"mapzoomin", "mapzoomout", "screenshot", "pause", "menu", // Misc.
|
||||
"mapzoomin", "mapzoomout", "screenshot", "pause", "menu",
|
||||
"info", // Misc.
|
||||
"end" }; // Must terminate at the end.
|
||||
// From player.c
|
||||
extern double player_turn;
|
||||
@ -64,7 +65,7 @@ void input_setDefault(void) {
|
||||
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);
|
||||
}
|
||||
|
||||
// Initialization/exit functions (does not assign keys).
|
||||
@ -223,8 +224,11 @@ static void input_key(int keynum, double value, int abs) {
|
||||
}
|
||||
// Opens a menu.
|
||||
else if(KEY("menu")) {
|
||||
if(value == KEY_PRESS)
|
||||
menu_small();
|
||||
if(value == KEY_PRESS) menu_small();
|
||||
}
|
||||
// Show pilot information.
|
||||
else if(KEY("info")) {
|
||||
if(value == KEY_PRESS) info_menu();
|
||||
}
|
||||
}
|
||||
|
||||
|
71
src/menu.c
71
src/menu.c
@ -5,23 +5,36 @@
|
||||
#include "log.h"
|
||||
#include "lephisto.h"
|
||||
#include "pause.h"
|
||||
#include "pilot.h"
|
||||
#include "space.h"
|
||||
#include "menu.h"
|
||||
|
||||
#define MENU_WIDTH 120
|
||||
#define MENU_HEIGHT 200
|
||||
|
||||
#define INFO_WIDTH 320
|
||||
#define INFO_HEIGHT 280
|
||||
|
||||
#define BUTTON_WIDTH 80
|
||||
#define BUTTON_HEIGHT 30
|
||||
|
||||
#define MENU_SMALL (1<<0)
|
||||
#define MENU_INFO (1<<1)
|
||||
#define menu_isOpen(f) (menu_open & (f))
|
||||
#define menu_Open(f) (menu_open |= (f))
|
||||
#define menu_Close(f) (menu_open ^= (f))
|
||||
|
||||
static int menu_open = 0;
|
||||
|
||||
static void menu_small_close(char* str);
|
||||
static void edit_options(void);
|
||||
static void exit_game(void);
|
||||
static void info_menu_close(char* str);
|
||||
|
||||
// Ze ingame menu.
|
||||
// Small ingame menu.
|
||||
void menu_small(void) {
|
||||
if(menu_open) return; // It's already open..
|
||||
if(menu_isOpen(MENU_SMALL)) return; // It's already open..
|
||||
|
||||
unsigned int wid;
|
||||
|
||||
@ -37,15 +50,15 @@ void menu_small(void) {
|
||||
"btnResume", "Resume", menu_small_close);
|
||||
|
||||
pause();
|
||||
menu_open = 1;
|
||||
menu_Open(MENU_SMALL);
|
||||
}
|
||||
|
||||
void menu_small_close(char* str) {
|
||||
static void menu_small_close(char* str) {
|
||||
if(strcmp(str, "btnResume")==0)
|
||||
window_destroy(window_get("Menu"));
|
||||
|
||||
unpause();
|
||||
menu_open = 0;
|
||||
menu_Close(MENU_SMALL);
|
||||
}
|
||||
|
||||
// Edit the options.
|
||||
@ -60,3 +73,53 @@ static void exit_game(void) {
|
||||
SDL_PushEvent(&quit);
|
||||
}
|
||||
|
||||
// Info menu.
|
||||
void info_menu(void) {
|
||||
if(menu_isOpen(MENU_INFO)) return;
|
||||
|
||||
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,
|
||||
"Foobar\n"
|
||||
"Luser\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", ship_view);
|
||||
window_addButton(wid, -20, (20 + BUTTON_HEIGHT)*2 + 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnCargo", "Cargo", ship_view);
|
||||
window_addButton(wid, -20, 20 + BUTTON_HEIGHT + 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnMissions", "Missions", ship_view);
|
||||
window_addButton(wid, -20, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnClose", "Close", info_menu_close);
|
||||
|
||||
|
||||
menu_Open(MENU_INFO);
|
||||
}
|
||||
|
||||
static void info_menu_close(char* str) {
|
||||
if(strcmp(str, "btnClose")==0)
|
||||
window_destroy(window_get("Info"));
|
||||
|
||||
menu_Close(MENU_INFO);
|
||||
}
|
||||
|
||||
|
@ -2,3 +2,5 @@
|
||||
|
||||
void menu_small(void);
|
||||
|
||||
void info_menu(void);
|
||||
|
||||
|
36
src/outfit.c
36
src/outfit.c
@ -139,9 +139,9 @@ static void outfit_parseSLauncher(Outfit* tmp, const xmlNodePtr parent) {
|
||||
else if(xml_isNode(node, "ammo")) tmp->ammo = strdup(xml_get(node));
|
||||
} while((node = node->next));
|
||||
|
||||
#define MELEMENT(o,s) if((o) == 0) WARN("Outfit '%s' missing '"s"' element", tmp->name)
|
||||
if(tmp->ammo == NULL) WARN("Outfit '%s' missing 'ammo' element", tmp->name);
|
||||
MELEMENT(tmp->delay, "delay");
|
||||
#define MELEMENT(o,s) if(o) WARN("Outfit '%s' missing '"s"' element", tmp->name)
|
||||
MELEMENT(tmp->ammo == NULL, "ammo");
|
||||
MELEMENT(tmp->delay==0, "delay");
|
||||
#undef MELEMENT
|
||||
}
|
||||
|
||||
@ -172,16 +172,15 @@ static void outfit_parseSAmmo(Outfit* tmp, const xmlNodePtr parent) {
|
||||
} while((cur = cur->next));
|
||||
}
|
||||
} while((node = node->next));
|
||||
#define MELEMENT(o,s) if((o) == 0) WARN("Outfit '%s' missing '"s"' element", tmp->name)
|
||||
if(tmp->gfx_space == NULL)
|
||||
WARN("Outfit '%s' missing 'gfx' element", tmp->name);
|
||||
MELEMENT(tmp->sound, "sound");
|
||||
MELEMENT(tmp->thrust, "thrust");
|
||||
MELEMENT(tmp->turn, "turn");
|
||||
MELEMENT(tmp->speed, "speed");
|
||||
MELEMENT(tmp->range, "duration");
|
||||
MELEMENT(tmp->damage_armour, "armour' from element 'damage");
|
||||
MELEMENT(tmp->damage_shield, "shield' from element 'damage");
|
||||
#define MELEMENT(o,s) if(o) WARN("Outfit '%s' missing '"s"' element", tmp->name)
|
||||
MELEMENT(tmp->gfx_space == NULL, "gfx");
|
||||
MELEMENT(tmp->sound==0, "sound");
|
||||
MELEMENT(tmp->thrust==0, "thrust");
|
||||
MELEMENT(tmp->turn==0, "turn");
|
||||
MELEMENT(tmp->speed==0, "speed");
|
||||
MELEMENT(tmp->range==0, "duration");
|
||||
MELEMENT(tmp->damage_armour==0, "armour' from element 'damage");
|
||||
MELEMENT(tmp->damage_shield==0, "shield' from element 'damage");
|
||||
#undef MELEMENT
|
||||
}
|
||||
|
||||
@ -231,11 +230,12 @@ static Outfit* outfit_parse(const xmlNodePtr parent) {
|
||||
outfit_parseSAmmo(tmp, node);
|
||||
}
|
||||
} while((node = node->next));
|
||||
#define MELEMENT(o,s) if((o) == 0) WARN("Outfit '%s' missing '"s"' element", tmp->name)
|
||||
MELEMENT(tmp->max, "max");
|
||||
MELEMENT(tmp->tech, "tech");
|
||||
MELEMENT(tmp->mass, "mass");
|
||||
MELEMENT(tmp->type, "type");
|
||||
#define MELEMENT(o,s) if(o) WARN("Outfit '%s' missing '"s"' element", tmp->name)
|
||||
MELEMENT(tmp->name==NULL, "name");
|
||||
MELEMENT(tmp->max==0, "max");
|
||||
MELEMENT(tmp->tech==0, "tech");
|
||||
MELEMENT(tmp->mass==0, "mass");
|
||||
MELEMENT(tmp->type==0, "type");
|
||||
#undef MELEMENT
|
||||
|
||||
DEBUG("Loaded outfit '%s' of type '%s'", tmp->name, outfit_getType(tmp));
|
||||
|
112
src/ship.c
112
src/ship.c
@ -4,6 +4,7 @@
|
||||
#include "log.h"
|
||||
#include "pack.h"
|
||||
#include "xml.h"
|
||||
#include "toolkit.h"
|
||||
#include "ship.h"
|
||||
|
||||
#define XML_ID "Ships" // XML section identifier.
|
||||
@ -14,10 +15,18 @@
|
||||
#define SHIP_EXT ".png"
|
||||
#define SHIP_TARGET "_target"
|
||||
|
||||
#define VIEW_WIDTH 300
|
||||
#define VIEW_HEIGHT 300
|
||||
|
||||
#define BUTTON_WIDTH 80
|
||||
#define BUTTON_HEIGHT 30
|
||||
|
||||
static Ship* ship_stack = NULL;
|
||||
static int ships = 0;
|
||||
|
||||
static char* ship_class(Ship* s);
|
||||
static Ship* ship_parse(xmlNodePtr parent);
|
||||
static void ship_view_close(char* btn);
|
||||
|
||||
// Get a ship based on it's name.
|
||||
Ship* ship_get(const char* name) {
|
||||
@ -32,6 +41,15 @@ Ship* ship_get(const char* name) {
|
||||
return tmp+i;
|
||||
}
|
||||
|
||||
// Get the ship's classname.
|
||||
static char* ship_classes[] = {
|
||||
"NULL", "Civialian Light", "Civilian Medium", "Civilian Heavy"
|
||||
};
|
||||
|
||||
static char* ship_class(Ship* s) {
|
||||
return ship_classes[s->class];
|
||||
}
|
||||
|
||||
static Ship* ship_parse(xmlNodePtr parent) {
|
||||
xmlNodePtr cur, node;
|
||||
Ship* tmp = CALLOC_L(Ship);
|
||||
@ -129,23 +147,23 @@ static Ship* ship_parse(xmlNodePtr parent) {
|
||||
|
||||
tmp->thrust *= tmp->mass; // Helps keep number sane.
|
||||
|
||||
#define MELEMENT(o,s) if(o == 0) WARN("Ship '%s' missing '"s"' element", tmp->name)
|
||||
if(tmp->name == NULL) WARN("Ship '%s' missing 'name' tag", tmp->name);
|
||||
if(tmp->gfx_space == NULL) WARN("Ship '%s' missing 'GFX' element", tmp->name);
|
||||
if(tmp->gui == NULL) WARN("Ship '%s' missing 'GUI' element", tmp->name);
|
||||
MELEMENT(tmp->thrust, "thrust");
|
||||
MELEMENT(tmp->turn, "turn");
|
||||
MELEMENT(tmp->speed, "speed");
|
||||
MELEMENT(tmp->armour, "armour");
|
||||
MELEMENT(tmp->armour_regen, "armour_regen");
|
||||
MELEMENT(tmp->shield, "shield");
|
||||
MELEMENT(tmp->shield_regen, "shield_regen");
|
||||
MELEMENT(tmp->energy, "energy");
|
||||
MELEMENT(tmp->energy_regen, "energt_regen");
|
||||
MELEMENT(tmp->crew, "crew");
|
||||
MELEMENT(tmp->mass, "mass");
|
||||
MELEMENT(tmp->cap_cargo, "cap_cargo");
|
||||
MELEMENT(tmp->cap_weapon, "cap_weapon");
|
||||
#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->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
|
||||
|
||||
DEBUG("Loaded ship '%s'", tmp->name);
|
||||
@ -210,3 +228,63 @@ void ships_free(void) {
|
||||
ship_stack = NULL;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
window_addText(wid, 20, 0, 100, VIEW_HEIGHT-30,
|
||||
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"
|
||||
}
|
||||
|
||||
|
14
src/ship.h
14
src/ship.h
@ -7,13 +7,12 @@
|
||||
#define SHIP_TARGET_W 128
|
||||
#define SHIP_TARGET_H 96
|
||||
|
||||
enum ship_class {
|
||||
typedef enum {
|
||||
SHIP_CLASS_NULL = 0,
|
||||
SHIP_CLASS_CIV_LIGHT = 1,
|
||||
SHIP_CLASS_CIV_MEDIUM = 2,
|
||||
SHIP_CLASS_CIV_HEAVY = 3
|
||||
};
|
||||
typedef enum ship_class ship_class;
|
||||
} ShipClass;
|
||||
|
||||
// Small wrapper for the outfits.
|
||||
typedef struct ShipOutfit {
|
||||
@ -26,7 +25,7 @@ typedef struct ShipOutfit {
|
||||
// Ship structure.
|
||||
typedef struct {
|
||||
char* name; // Ship name.
|
||||
ship_class class; // Ship class.
|
||||
ShipClass class; // Ship class.
|
||||
|
||||
// Movement.
|
||||
double thrust, turn, speed;
|
||||
@ -56,8 +55,13 @@ typedef struct {
|
||||
ShipOutfit* outfit;
|
||||
} Ship;
|
||||
|
||||
// Get.
|
||||
Ship* ship_get(const char* name);
|
||||
|
||||
// Load/quit.
|
||||
int ships_load(void);
|
||||
void ships_free(void);
|
||||
|
||||
Ship* ship_get(const char* name);
|
||||
// Toolkit.
|
||||
void ship_view(char* shipname);
|
||||
|
||||
|
@ -190,6 +190,16 @@ static Window* window_wget(const unsigned int wid) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Check if a window exists.
|
||||
int window_exists(const char* wdwname) {
|
||||
int i;
|
||||
for(i = 0; i < nwindows; i++)
|
||||
if(strcmp(windows[i].name, wdwname)==0)
|
||||
return 1; // Exists.
|
||||
|
||||
return 0; // Does not exits!
|
||||
}
|
||||
|
||||
// Return the id of a window.
|
||||
unsigned int window_get(const char* wdwname) {
|
||||
int i;
|
||||
|
@ -20,6 +20,7 @@ void window_addImage(const unsigned int wid, const int x, const int y,
|
||||
char* name, glTexture* image);
|
||||
|
||||
// Get the window by name.
|
||||
int window_exists(const char* wdwname);
|
||||
unsigned int window_get(const char* wdwname);
|
||||
|
||||
// Destroy window.
|
||||
|
Loading…
Reference in New Issue
Block a user