[Add] Rudimentary screenshots.

This commit is contained in:
Allanis 2013-02-14 19:29:26 +00:00
parent 7dbe3d2598
commit 70c9585302
7 changed files with 177 additions and 16 deletions

2
.gitignore vendored
View File

@ -28,5 +28,5 @@
*bin/data *bin/data
*pack *pack
*core *core
*screenshot.png

View File

@ -1,4 +1,5 @@
<Start> <Start>
<name>Dark Tides</name>
<player> <player>
<ship>Lancer</ship> <ship>Lancer</ship>
<credits> <credits>

View File

@ -21,8 +21,12 @@
#include "pack.h" #include "pack.h"
#include "weapon.h" #include "weapon.h"
#include "faction.h" #include "faction.h"
#include "xml.h"
#include "pilot.h" #include "pilot.h"
#define XML_START_ID "Start"
#define START_DATA "../dat/start.xml"
#define CONF_FILE "conf" #define CONF_FILE "conf"
#define MINIMUM_FPS 0.5 #define MINIMUM_FPS 0.5
@ -34,8 +38,10 @@ static int quit = 0; // Primary loop.
static unsigned int time = 0; // Calculate FPS and movement. static unsigned int time = 0; // Calculate FPS and movement.
// Just some default crap. // Just some default crap.
#define DATA_DEF "data" #define DATA_DEF "data" // Default data pack file.
#define DATA_NAME_LEN 25 // Max length of data name.
char* data = NULL; char* data = NULL;
char dataname[DATA_NAME_LEN];
static int show_fps = 1; // Default - True. static int show_fps = 1; // Default - True.
static int max_fps = 0; static int max_fps = 0;
@ -43,6 +49,8 @@ static int max_fps = 0;
static void print_usage(char** argv); static void print_usage(char** argv);
static void display_fps(const double dt); static void display_fps(const double dt);
static void window_caption(void);
static void data_name(void);
// Update. // Update.
static void update_all(void); static void update_all(void);
@ -188,13 +196,26 @@ int main(int argc, char** argv) {
namjoystick = strdup(optarg); namjoystick = strdup(optarg);
break; break;
case 'v': case 'v':
LOG("Lephisto: version %d.%d.%d\n", VMAJOR, VMINOR, VREV); LOG(APPNAME": version %d.%d.%d", VMAJOR, VMINOR, VREV);
case 'h': case 'h':
print_usage(argv); print_usage(argv);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
} }
// Check if the data file is valid.
if(pack_check(data)) {
ERR("Data file '%s'not found", data);
WARN("You should specify which data file to use with '-d'");
WARN("See -h or --help for more information.");
SDL_Quit();
exit(EXIT_FAILURE);
}
data_name(); // Loads the data's name and friends.
LOG(" %s", dataname);
DEBUG();
// Random numbers. // Random numbers.
rng_init(); rng_init();
@ -214,11 +235,10 @@ int main(int argc, char** argv) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// Window. window_caption();
SDL_WM_SetCaption(APPNAME, NULL);
// Input. // Input.
if(indjoystick >= 0 || namjoystick != NULL) { if((indjoystick >= 0) || (namjoystick != NULL)) {
if(joystick_init()) if(joystick_init())
WARN("Error initializing joystick input"); WARN("Error initializing joystick input");
if(namjoystick != NULL) { if(namjoystick != NULL) {
@ -307,7 +327,7 @@ int main(int argc, char** argv) {
// ======================================================== // ========================================================
static double fps_dt = 1.; static double fps_dt = 1.;
static void update_all(void) { static void update_all(void) {
// dt in us. // dt in ms/1000.
double dt = (double)(SDL_GetTicks() - time) / 1000.; double dt = (double)(SDL_GetTicks() - time) / 1000.;
time = SDL_GetTicks(); time = SDL_GetTicks();
@ -319,7 +339,7 @@ static void update_all(void) {
return; return;
} }
// If FPS is limited. // If FPS is limited.
else if(max_fps != 0 && dt < 1./max_fps) { else if((max_fps != 0) && (dt < 1./max_fps)) {
double delay = 1./max_fps - dt; double delay = 1./max_fps - dt;
SDL_Delay(delay); SDL_Delay(delay);
fps_dt += delay; // Make sure it displays the propper FPS. fps_dt += delay; // Make sure it displays the propper FPS.
@ -351,6 +371,7 @@ static void display_fps(const double dt) {
fps_dt += dt; fps_dt += dt;
fps_cur += 1.; fps_cur += 1.;
if(fps_dt > 1.) { if(fps_dt > 1.) {
// Recalculate every second.
fps = fps_cur / fps_dt; fps = fps_cur / fps_dt;
fps_dt = fps_cur = 0.; fps_dt = fps_cur = 0.;
} }
@ -360,3 +381,38 @@ static void display_fps(const double dt) {
gl_print(NULL, &pos, NULL, "%3.2f", fps); gl_print(NULL, &pos, NULL, "%3.2f", fps);
} }
static void data_name(void) {
uint32_t bufsize;
char* buf = pack_readfile(DATA, START_DATA, &bufsize);
xmlNodePtr node;
xmlDocPtr doc = xmlParseMemory(buf, bufsize);
node = doc->xmlChildrenNode;
if(!xml_isNode(node, XML_START_ID)) {
ERR("Maformed '"START_DATA"' file: missing root element '"XML_START_ID"'");
return;
}
node = node->xmlChildrenNode; // First node.
if(node == NULL) {
ERR("Malformed '"START_DATA"' file: does not contain elements");
return;
}
do {
if(xml_isNode(node, "name"))
strncpy(dataname, xml_get(node), DATA_NAME_LEN);
} while((node = node->next));
xmlFreeDoc(doc);
free(buf);
xmlCleanupParser();
}
static void window_caption(void) {
char tmp[DATA_NAME_LEN+10];
snprintf(tmp, DATA_NAME_LEN+10, APPNAME" - %s", dataname);
SDL_WM_SetCaption(tmp, NULL);
}

View File

@ -1,5 +1,6 @@
#include <SDL.h> #include <SDL.h>
#include <SDL_image.h> #include <SDL_image.h>
#include <png.h>
#include <ft2build.h> #include <ft2build.h>
#include <freetype/freetype.h> #include <freetype/freetype.h>
#include <freetype/ftglyph.h> #include <freetype/ftglyph.h>
@ -43,6 +44,8 @@ static int pot(int n);
static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh); static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh);
// Gl font. // Gl font.
static void gl_fontMakeDList(FT_Face face, char ch, GLuint list_base, GLuint* tex_base, int* width_base); static void gl_fontMakeDList(FT_Face face, char ch, GLuint list_base, GLuint* tex_base, int* width_base);
// PNG.
int write_png(const char* file_name, png_bytep* rows, int w, int h, int colortype, int bitdepth);
// ================ // ================
// MISC! // MISC!
@ -133,6 +136,19 @@ static uint8_t* SDL_MapTrans(SDL_Surface* s) {
return t; return t;
} }
// Take a screenshot.
void gl_screenshot(const char* filename) {
SDL_Surface* screen = SDL_GetVideoSurface();
unsigned rowbytes = screen->w * 4;
unsigned char screenbuf[screen->h][rowbytes], *rows[screen->h];
int i;
glReadPixels(0, 0, screen->w, screen->h, GL_RGBA, GL_UNSIGNED_BYTE, screenbuf);
for(i = 0; i < screen->h; i++) rows[i] = screenbuf[screen->h - i - 1];
write_png(filename, rows, screen->w, screen->h, PNG_COLOR_TYPE_RGBA, 8);
}
// ================ // ================
// TEXTURE! // TEXTURE!
// ================ // ================
@ -708,3 +724,43 @@ void gl_exit(void) {
SDL_Quit(); SDL_Quit();
} }
// Saves a png.
int write_png(const char* file_name, png_bytep* rows, int w, int h, int colortype, int bitdepth) {
png_structp png_ptr;
png_infop info_ptr;
FILE* fp = NULL;
char* doing = "Open for writing";
if(!(fp = fopen(file_name, "wb"))) goto fail;
doing = "Create png write struct";
if(!(png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL))) goto fail;
doing = "Create png info struct";
if(!(info_ptr = png_create_info_struct(png_ptr))) goto fail;
if(setjmp(png_jmpbuf(png_ptr))) goto fail;
doing = "Init IO";
png_init_io(png_ptr, fp);
png_set_IHDR(png_ptr, info_ptr, w, h, bitdepth, colortype, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
doing = "Write info";
png_write_info(png_ptr, info_ptr);
doing = "Write image";
png_write_image(png_ptr, rows);
doing = "Write end";
png_write_end(png_ptr, NULL);
doing = "Closing file";
if(0 != fclose(fp)) goto fail;
return 0;
fail:
WARN("write_png: Could not %s", doing);
return -1;
}

View File

@ -83,4 +83,5 @@ void gl_exit(void);
// Misc. // Misc.
int gl_isTrans(const gl_texture* t, const int x, const int y); int gl_isTrans(const gl_texture* t, const int x, const int y);
void gl_getSpriteFromDir(int* x, int* y, const gl_texture* t, const double dir); void gl_getSpriteFromDir(int* x, int* y, const gl_texture* t, const double dir);
void gl_screenshot(const char* filename);

View File

@ -20,7 +20,7 @@
#define START_DATA "../dat/start.xml" #define START_DATA "../dat/start.xml"
#define POW2(x) ((x)*(x)) #define pow2(x) ((x)*(x))
#define GFX_GUI_FRAME "../gfx/gui/frame.png" #define GFX_GUI_FRAME "../gfx/gui/frame.png"
#define GFX_GUI_TARG_PILOT "../gfx/gui/pilot.png" #define GFX_GUI_TARG_PILOT "../gfx/gui/pilot.png"
@ -38,8 +38,9 @@ typedef struct {
} Keybind; } Keybind;
static Keybind** player_input; // Contains the players keybindings. static Keybind** player_input; // Contains the players keybindings.
// Name of each keybinding. // Name of each keybinding.
const char* keybindNames[] = { "accel", "left", "right", "primary", "target", const char* keybindNames[] = { "accel", "left", "right", // Movement.
"target_nearest", "mapzoomin", "mapzoomout", "end" }; // Need to terminate in "end". "primary", "target", "target_nearest", "board", // Combat.
"mapzoomin", "mapzoomout", "screenshot", "end" }; // Misc.
// Player stuff. // Player stuff.
Pilot* player = NULL; // extern in pilot.h Pilot* player = NULL; // extern in pilot.h
@ -138,6 +139,9 @@ static int gui_parse(const xmlNodePtr parent, const char* name);
static void gui_renderPilot(const Pilot* p); static void gui_renderPilot(const Pilot* p);
static void gui_renderBar(const glColor* c, const Vec2* p, const Rect* r, const double w); static void gui_renderBar(const glColor* c, const Vec2* p, const Rect* r, const double w);
static void player_board(void);
static void player_screenshot(void);
// Create a new player. // Create a new player.
void player_new(void) { void player_new(void) {
Ship* ship; Ship* ship;
@ -529,28 +533,28 @@ static void rect_parse(const xmlNodePtr parent, double* x, double* y, double* w,
do { do {
if(xml_isNode(cur, "x")) { if(xml_isNode(cur, "x")) {
if(x != NULL) { if(x != NULL) {
*x = (double)atoi((char*)cur->children->content); *x = xml_getFloat(cur);
param |= (1<<0); param |= (1<<0);
} else } else
WARN("Extra parameter 'x' found for GUI node '%s'", parent->name); WARN("Extra parameter 'x' found for GUI node '%s'", parent->name);
} }
else if(xml_isNode(cur, "y")) { else if(xml_isNode(cur, "y")) {
if(y != NULL) { if(y != NULL) {
*y = (double)atoi((char*)cur->children->content); *y = xml_getFloat(cur);
param |= (1<<1); param |= (1<<1);
} else } else
WARN("Extra parameter 'y' found for GUI node '%s'", parent->name); WARN("Extra parameter 'y' found for GUI node '%s'", parent->name);
} }
else if(xml_isNode(cur, "w")) { else if(xml_isNode(cur, "w")) {
if(w != NULL) { if(w != NULL) {
*w = (double)atoi((char*)cur->children->content); *w = xml_getFloat(cur);
param |= (1<<2); param |= (1<<2);
} else } else
WARN("Extra parameter 'w' found for GUI node '%s'", parent->name); WARN("Extra parameter 'w' found for GUI node '%s'", parent->name);
} }
else if(xml_isNode(cur, "h")) { else if(xml_isNode(cur, "h")) {
if(h != NULL) { if(h != NULL) {
*h = (double)atoi((char*)cur->children->content); *h = xml_getFloat(cur);
param |= (1<<3); param |= (1<<3);
} else } else
WARN("Extra parameter 'h' found for GUI node '%s'", parent->name); WARN("Extra parameter 'h' found for GUI node '%s'", parent->name);
@ -736,6 +740,40 @@ void player_think(Pilot* player) {
vect_pset(&player->solid->force, player->ship->thrust * player_acc, player->solid->dir); vect_pset(&player->solid->force, player->ship->thrust * player_acc, player->solid->dir);
} }
void player_board(void) {
Pilot* p;
if(player_target == PLAYER_ID) {
player_message("You need a target to board first!");
return;
}
p = pilot_get(player_target);
if(!pilot_isFlag(p, PILOT_DISABLED)) {
player_message("You cannot board a ship that isn't disabled!");
return;
}
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;
}
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 fact to board the ship");
return;
}
player_message("Ship boarding isn't implemented yet! HAHA");
}
// Take a screenshot.
static void player_screenshot(void) {
char filename[20];
// TODO not overwirte old screenshots.
strncpy(filename, "screenshot.png", 20);
gl_screenshot(filename);
}
// ================ // ================
// INPUT! // INPUT!
// ================ // ================
@ -748,8 +786,10 @@ void input_setDefault(void) {
input_setKeybind("primary", KEYBIND_KEYBOARD, SDLK_SPACE, 0); input_setKeybind("primary", KEYBIND_KEYBOARD, SDLK_SPACE, 0);
input_setKeybind("target", KEYBIND_KEYBOARD, SDLK_TAB, 0); input_setKeybind("target", KEYBIND_KEYBOARD, SDLK_TAB, 0);
input_setKeybind("target_nearest", KEYBIND_KEYBOARD, SDLK_r, 0); input_setKeybind("target_nearest", KEYBIND_KEYBOARD, SDLK_r, 0);
input_setKeybind("board", KEYBIND_KEYBOARD, SDLK_b, 0);
input_setKeybind("mapzoomin", KEYBIND_KEYBOARD, SDLK_UP, 0); input_setKeybind("mapzoomin", KEYBIND_KEYBOARD, SDLK_UP, 0);
input_setKeybind("mapzoomout", KEYBIND_KEYBOARD, SDLK_DOWN, 0); input_setKeybind("mapzoomout", KEYBIND_KEYBOARD, SDLK_DOWN, 0);
input_setKeybind("screenshot", KEYBIND_KEYBOARD, SDLK_F12, 0);
} }
// Initialization/exit functions (does not assign keys). // Initialization/exit functions (does not assign keys).
@ -820,6 +860,10 @@ static void input_key(int keynum, double value, int abs) {
else if(strcmp(player_input[keynum]->name, "target_nearest")==0) { else if(strcmp(player_input[keynum]->name, "target_nearest")==0) {
if(value == KEY_PRESS) player_target = pilot_getHostile(); if(value == KEY_PRESS) player_target = pilot_getHostile();
} }
// Board those ships.
else if(strcmp(player_input[keynum]->name, "board")==0) {
if(value == KEY_PRESS) player_board();
}
// Zoom in. // Zoom in.
else if(strcmp(player_input[keynum]->name, "mapzoomin")==0) { else if(strcmp(player_input[keynum]->name, "mapzoomin")==0) {
if(value == KEY_PRESS && gui.radar.res < RADAR_RES_MAX) if(value == KEY_PRESS && gui.radar.res < RADAR_RES_MAX)
@ -830,6 +874,9 @@ static void input_key(int keynum, double value, int abs) {
if(value == KEY_PRESS && gui.radar.res > RADAR_RES_MIN) if(value == KEY_PRESS && gui.radar.res > RADAR_RES_MIN)
gui.radar.res -= RADAR_RES_INTERVAL; gui.radar.res -= RADAR_RES_INTERVAL;
} }
else if(strcmp(player_input[keynum]->name, "screenshot")==0) {
if(value == KEY_PRESS) player_screenshot();
}
//Make sure values are sane. //Make sure values are sane.
player_acc = ABS(player_acc); player_acc = ABS(player_acc);

View File

@ -4,7 +4,7 @@
#include "pilot.h" #include "pilot.h"
#define MIN_HYPERSPACE_DIST 1500 #define MIN_HYPERSPACE_DIST 1500
#define MAX_HYPERSPACE_VEL 3 #define MAX_HYPERSPACE_VEL 10
// Planet types. I didn't take them from Star Trek, I promise. // Planet types. I didn't take them from Star Trek, I promise.
typedef enum { typedef enum {