[Add] Now we will initialize the nebulae.
This commit is contained in:
parent
40df85b5ab
commit
897fb9918d
@ -24,12 +24,15 @@
|
||||
#include "toolkit.h"
|
||||
#include "pilot.h"
|
||||
#include "sound.h"
|
||||
#include "music.h"
|
||||
#include "spfx.h"
|
||||
#include "economy.h"
|
||||
#include "menu.h"
|
||||
#include "mission.h"
|
||||
#include "misn_lua.h"
|
||||
#include "lfile.h"
|
||||
#include "music.h"
|
||||
#include "nebulae.h"
|
||||
|
||||
|
||||
#define XML_START_ID "Start"
|
||||
#define START_DATA "../dat/start.xml"
|
||||
@ -128,8 +131,17 @@ int main(int argc, char** argv) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* OpenGL */
|
||||
if(gl_init()) { /* Init video output. */
|
||||
ERR("Initializing video output failed, exiting...");
|
||||
SDL_Quit();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
window_caption();
|
||||
|
||||
/* Time to try to load the nebulae. */
|
||||
nebu_init();
|
||||
|
||||
/* OpenAL sound. */
|
||||
if(nosound)
|
||||
LOG("Sound is disabled!");
|
||||
@ -210,6 +222,7 @@ int main(int argc, char** argv) {
|
||||
ai_exit(); /* Stop the Lua AI magicness. */
|
||||
joystick_exit(); /* Release joystick. */
|
||||
input_exit(); /* Clean up keybindings. */
|
||||
nebu_exit(); /* Destroys the nebulae. */
|
||||
gl_exit(); /* Kills video output. */
|
||||
sound_exit(); /* Kills the sound. */
|
||||
SDL_Quit(); /* Quits SDL. */
|
||||
|
@ -33,7 +33,7 @@ char* lfile_basePath(void) {
|
||||
|
||||
/* Check if a directory exists, and create it if it doesn't. */
|
||||
/* Based on lephisto_base. */
|
||||
int lfile_dirMakeExist(char* path) {
|
||||
int lfile_dirMakeExist(const char* path) {
|
||||
char file[PATH_MAX];
|
||||
|
||||
#ifdef LINUX
|
||||
@ -59,7 +59,7 @@ int lfile_dirMakeExist(char* path) {
|
||||
}
|
||||
|
||||
/* Check if a file exists. */
|
||||
int lfile_fileExists(char* path, ...) {
|
||||
int lfile_fileExists(const char* path, ...) {
|
||||
char file[PATH_MAX], name[PATH_MAX];
|
||||
va_list ap;
|
||||
size_t l;
|
||||
@ -86,7 +86,7 @@ int lfile_fileExists(char* path, ...) {
|
||||
}
|
||||
|
||||
/* List all the files in a dir (besides . and ..). */
|
||||
char** lfile_readDir(int* lfiles, char* path) {
|
||||
char** lfile_readDir(int* lfiles, const char* path) {
|
||||
char file[PATH_MAX];
|
||||
char** files;
|
||||
|
||||
|
11
src/lfile.h
11
src/lfile.h
@ -1,7 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
char* lfile_basePath(void);
|
||||
int lfile_dirMakeExist(char* path);
|
||||
int lfile_fileExists(char* path, ...);
|
||||
char** lfile_readDir(int* lfiles, char* path);
|
||||
|
||||
/* Create if doesn't exist, 0 success. */
|
||||
int lfile_dirMakeExist(const char* path);
|
||||
|
||||
/* Return 1 on exit. */
|
||||
int lfile_fileExists(const char* path, ...);
|
||||
|
||||
char** lfile_readDir(int* lfiles, const char* path);
|
||||
|
||||
|
200
src/nebulae.c
Normal file
200
src/nebulae.c
Normal file
@ -0,0 +1,200 @@
|
||||
#include <errno.h>
|
||||
#include "nebulae.h"
|
||||
|
||||
#ifdef _POSIX_SOURCE
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include "lephisto.h"
|
||||
#include "log.h"
|
||||
#include "lfile.h"
|
||||
#include "perlin.h"
|
||||
|
||||
/* -- CUSTOM NEBULAE FORMAT. --
|
||||
* Header (16 byte string).
|
||||
* Dimesnions (4 byte w and 4 byte h).
|
||||
* Body (1 byte per pixel).
|
||||
*/
|
||||
|
||||
#define NEBU_FORMAT_HEADER 16 /* Size of header. */
|
||||
#define NEBU_VERSION "1" /* Will be used for version checking. */
|
||||
|
||||
#define NEBULAE_Z 32 /* Z plane. */
|
||||
#define NEBULAE_PATH "gen/nebu_%02d.nebu"
|
||||
|
||||
/* The nebulae textures. */
|
||||
static GLuint nebu_textures[NEBULAE_Z];
|
||||
static int nebu_w, nebu_h, nebu_pw, nebu_ph;
|
||||
|
||||
static int nebu_checkCompat(const char* file);
|
||||
static void saveNebulae(float* map, const uint32_t w, const uint32_t h,
|
||||
const char* file);
|
||||
static unsigned char* loadNebulae(const char* file, int* w, int* h);
|
||||
|
||||
void nebu_init(void) {
|
||||
int i;
|
||||
char nebu_file[PATH_MAX];
|
||||
unsigned char* nebu_padded;
|
||||
int w, h;
|
||||
unsigned char* nebu_data;
|
||||
|
||||
/* Set expected sizes. */
|
||||
nebu_w = SCREEN_W;
|
||||
nebu_h = SCREEN_H;
|
||||
nebu_pw = gl_pot(nebu_w);
|
||||
nebu_ph = gl_pot(nebu_h);
|
||||
|
||||
/* Load each, checking for compatibility and padding. */
|
||||
nebu_padded = malloc(nebu_pw * nebu_ph);
|
||||
glGenTextures(NEBULAE_Z, nebu_textures);
|
||||
for(i = 0; i < NEBULAE_Z; i++) {
|
||||
snprintf(nebu_file, PATH_MAX, NEBULAE_PATH, i);
|
||||
|
||||
if(nebu_checkCompat(nebu_file)) { /* Incompatable. */
|
||||
LOG("No nebulae found, generating (this may take a while).");
|
||||
|
||||
/* So we generate and reload. */
|
||||
free(nebu_padded);
|
||||
nebu_generate(nebu_w, nebu_h);
|
||||
nebu_init();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Load the file. */
|
||||
nebu_data = loadNebulae(nebu_file, &w, &h);
|
||||
memcpy(nebu_padded, nebu_data, w*h);
|
||||
|
||||
/* Load the textures. */
|
||||
glBindTexture(GL_TEXTURE_2D, nebu_textures[i]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA8, nebu_pw, nebu_ph,
|
||||
0, GL_ALPHA, GL_UNSIGNED_BYTE, nebu_padded);
|
||||
gl_checkErr();
|
||||
|
||||
free(nebu_data); /* No longer need the data. */
|
||||
}
|
||||
free(nebu_padded);
|
||||
}
|
||||
|
||||
/* Clean up the nebu subsystem. */
|
||||
void nebu_exit(void) {
|
||||
glDeleteTextures(NEBULAE_Z, nebu_textures);
|
||||
}
|
||||
|
||||
/* Force generation of new nebulae. */
|
||||
void nebu_generate(const int w, const int h) {
|
||||
int i;
|
||||
float* nebu;
|
||||
char nebu_file[PATH_MAX];
|
||||
|
||||
/* Generate all the nebulae. */
|
||||
nebu = noise_genNebulaeMap(w, h, NEBULAE_Z, 15.);
|
||||
lfile_dirMakeExist("gen");
|
||||
|
||||
/* Save each nebulae as an image. */
|
||||
for(i = 0; i < NEBULAE_Z; i++) {
|
||||
snprintf(nebu_file, PATH_MAX, NEBULAE_PATH, i);
|
||||
saveNebulae(&nebu[i*w*h], w, h, nebu_file);
|
||||
}
|
||||
|
||||
/* Cleanup. */
|
||||
free(nebu);
|
||||
}
|
||||
|
||||
/* Check the validity of a nebulae. 0 on success. */
|
||||
static int nebu_checkCompat(const char* file) {
|
||||
if(lfile_fileExists(file) == 0) /* First check to see if file exists. */
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Save a nebulae. */
|
||||
static void saveNebulae(float* map, const uint32_t w, const uint32_t h,
|
||||
const char* file) {
|
||||
|
||||
int x, y;
|
||||
char* buf;
|
||||
unsigned char c;
|
||||
int cur;
|
||||
ssize_t size;
|
||||
char file_path[PATH_MAX];
|
||||
|
||||
size = w*h + 16 + 4;
|
||||
buf = malloc(size);
|
||||
|
||||
/* Write the header. */
|
||||
memset(buf, '0', 16);
|
||||
snprintf(buf, NEBU_FORMAT_HEADER, "LEPHISTO NEBU v" NEBU_VERSION);
|
||||
cur = 16;
|
||||
memcpy(&buf[cur], &w, 4);
|
||||
memcpy(&buf[cur], &h, 4);
|
||||
cur += 8;
|
||||
|
||||
/* The Body. */
|
||||
for(y = 0; y < (int)h; y++)
|
||||
for(x = 0; x < (int)w; x++) {
|
||||
c = (unsigned char) 255.*map[y*w + x];
|
||||
memcpy(&buf[cur++], &c, 1);
|
||||
}
|
||||
|
||||
/* Write to a file. */
|
||||
snprintf(file_path, PATH_MAX, "%s%s", lfile_basePath(), file);
|
||||
#ifdef _POSIX_SOURCE
|
||||
int fd;
|
||||
fd = open(file_path, O_WRONLY | O_CREAT | O_TRUNC,
|
||||
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
|
||||
if(fd < 0) {
|
||||
ERR("Unable to open file %s: %s", file, strerror(errno));
|
||||
return;
|
||||
}
|
||||
if(write(fd, buf, size) != size) {
|
||||
ERR("Error writing nebulae to %s: %s", file, strerror(errno));
|
||||
return;
|
||||
}
|
||||
close(fd);
|
||||
#else
|
||||
#error "Needs implementation."
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Load the nebulae from file. */
|
||||
static unsigned char* loadNebulae(const char* file, int* w, int* h) {
|
||||
unsigned char* buf;
|
||||
char header[16];
|
||||
uint32_t tw, th;
|
||||
ssize_t len;
|
||||
char file_path[PATH_MAX];
|
||||
|
||||
#ifdef _POSIX_SOURCE
|
||||
#define READ(b, l) \
|
||||
len = read(fd, b, l); \
|
||||
if(len < l) {\
|
||||
WARN("Read too few bytes from %s: %s", file, strerror(errno)); \
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
int fd;
|
||||
snprintf(file_path, PATH_MAX, "%s%s", lfile_basePath(), file);
|
||||
fd = open(file, O_RDONLY);
|
||||
if(fd < 0) {
|
||||
ERR("Unable to open file %s: %s", file_path, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
READ(header, 16);
|
||||
READ(&tw, 4);
|
||||
READ(&th, 4);
|
||||
buf = malloc(tw*th);
|
||||
READ(buf, tw*th);
|
||||
#else
|
||||
#error "Needs implementation."
|
||||
#endif
|
||||
(*w) = (int)tw;
|
||||
(*h) = (int)th;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
10
src/nebulae.h
Normal file
10
src/nebulae.h
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include "opengl.h"
|
||||
|
||||
/* Try to find nebulae to load, or generate if there isn't any. */
|
||||
void nebu_init(void);
|
||||
|
||||
void nebu_exit(void);
|
||||
|
||||
void nebu_generate(const int w, const int h);
|
||||
|
@ -39,7 +39,6 @@ static glTexList* texture_list = NULL;
|
||||
static int SDL_VFlipSurface(SDL_Surface* surface);
|
||||
static int SDL_IsTrans(SDL_Surface* s, int x, int y);
|
||||
static uint8_t* SDL_MapTrans(SDL_Surface* s);
|
||||
static int pot(int n);
|
||||
/* glTexture. */
|
||||
static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh);
|
||||
static glTexture* gl_loadNewImage(const char* path);
|
||||
@ -58,7 +57,7 @@ static GLboolean gl_hasExt(char* name);
|
||||
*/
|
||||
|
||||
/* Get the closest power of two. */
|
||||
static int pot(int n) {
|
||||
int gl_pot(int n) {
|
||||
int i = 1;
|
||||
while(i < n)
|
||||
i<<=1;
|
||||
@ -249,8 +248,8 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh) {
|
||||
SDL_Rect rtemp;
|
||||
|
||||
/* Make size power of two. */
|
||||
potw = pot(surface->w);
|
||||
poth = pot(surface->h);
|
||||
potw = gl_pot(surface->w);
|
||||
poth = gl_pot(surface->h);
|
||||
if(rw)*rw = potw;
|
||||
if(rh)*rh = poth;
|
||||
|
||||
|
@ -102,6 +102,7 @@ int gl_init(void);
|
||||
void gl_exit(void);
|
||||
|
||||
/* Misc. */
|
||||
int gl_pot(int n);
|
||||
int gl_isTrans(const glTexture* t, const int x, const int y);
|
||||
void gl_getSpriteFromDir(int* x, int* y, const glTexture* t, const double dir);
|
||||
void gl_screenshot(const char* filename);
|
||||
|
Loading…
Reference in New Issue
Block a user