diff --git a/src/menu.c b/src/menu.c index 6f4a386..e6747fc 100644 --- a/src/menu.c +++ b/src/menu.c @@ -69,7 +69,7 @@ void menu_main(void) { /* Create background image window. */ bwid = window_create("BG", -1, -1, SCREEN_W, SCREEN_H); - /*window_addRect(bwid, 0, 0, SCREEN_W, SCREEN_H, "rctBG", &cBlack, 0);*/ + window_addRect(bwid, 0, 0, SCREEN_W, SCREEN_H, "rctBG", &cBlack, 0); window_addCust(bwid, 0, 0, SCREEN_W, SCREEN_H, "cstBG", 0, (void(*)(double, double, double, double))nebu_render, NULL); diff --git a/src/nebulae.c b/src/nebulae.c index a00533f..a1b40d6 100644 --- a/src/nebulae.c +++ b/src/nebulae.c @@ -1,11 +1,7 @@ #include #include "nebulae.h" -#ifdef _POSIX_SOURCE -#include -#include -#include -#endif +#include "SDL_image.h" #include "lephisto.h" #include "log.h" @@ -22,7 +18,7 @@ #define NEBU_VERSION "1" /* Will be used for version checking. */ #define NEBULAE_Z 32 /* Z plane. */ -#define NEBULAE_PATH "gen/nebu_%02d.nebu" +#define NEBULAE_PATH "gen/nebu_%02d.png" /* The nebulae textures. */ static GLuint nebu_textures[NEBULAE_Z]; @@ -31,15 +27,13 @@ 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); +static SDL_Surface* loadNebulae(const char* file); /* Initialize the nebulae. */ void nebu_init(void) { - int i, y; + int i; char nebu_file[PATH_MAX]; - unsigned char* nebu_padded; - int w, h; - unsigned char* nebu_data; + SDL_Surface* nebu_sur; /* Set expected sizes. */ nebu_w = SCREEN_W; @@ -48,7 +42,6 @@ void nebu_init(void) { 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); @@ -57,34 +50,35 @@ void nebu_init(void) { 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); - for(y = 0; y < nebu_h; y++) { /* Copy lines over. */ - /* nebu_padded = [ nebu_data 0000000000000 ] */ - memmove(&nebu_padded[y*nebu_pw], &nebu_data[y*nebu_w], nebu_w); - memset(&nebu_padded[y*nebu_pw+nebu_w], 0, nebu_pw-nebu_w); /* Pad the end. */ - } - /* End it with 0's. */ - memset(&nebu_padded[nebu_h*nebu_pw+nebu_w], 0, - nebu_ph*nebu_w - nebu_h*nebu_pw); + nebu_sur = loadNebulae(nebu_file); + if((nebu_sur->w != nebu_w) || (nebu_sur->h != nebu_h)) + WARN("Nebulae raw size doesn't match expected! (%dx%d instead of %dx%d)", + nebu_sur->w, nebu_sur->h, nebu_pw, nebu_ph); + + nebu_sur = gl_prepareSurface(nebu_sur); + if((nebu_sur->w != nebu_pw) || (nebu_sur->h != nebu_ph)) + WARN("Nebulae size doesn't match expected! (%dx%d instead of %dx%d)", + nebu_sur->w, nebu_sur->h, nebu_pw, nebu_ph); /* 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(); + + SDL_LockSurface(nebu_sur); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, nebu_sur->w, nebu_sur->h, + 0, GL_RGBA, GL_UNSIGNED_BYTE, nebu_sur->pixels); + SDL_UnlockSurface(nebu_sur); - free(nebu_data); /* No longer need the data. */ + SDL_FreeSurface(nebu_sur); + gl_checkErr(); } - free(nebu_padded); DEBUG("Loaded %d Nebulae Layers", NEBULAE_Z); } @@ -97,29 +91,38 @@ void nebu_exit(void) { /* Render the nebulae. */ void nebu_render(void) { int n; - double tw, th; + double x, y, w, h, tx, ty, tw, th; n = 0; + x = -SCREEN_W/2.; + y = -SCREEN_H/2.; + + w = SCREEN_W; + h = SCREEN_H; + + tx = 0.; + ty = 0.; + tw = nebu_w / nebu_pw; th = nebu_h / nebu_ph; glEnable(GL_TEXTURE_2D); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + /*glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);*/ glBindTexture(GL_TEXTURE_2D, nebu_textures[n]); - glColor4d(1., 1., 1., 1.); + COLOUR(cPurple); glBegin(GL_QUADS); - glTexCoord2d(0., 0.); - glVertex2d(-SCREEN_W/2., -SCREEN_H/2.); + glTexCoord2d(tx, ty); + glVertex2d(x, y); - glTexCoord2d(tw, th); - glVertex2d(SCREEN_W/2., -SCREEN_H/2.); + glTexCoord2d(tx+tw, ty); + glVertex2d(x+w, y); - glTexCoord2d(tw, th); - glVertex2d(SCREEN_W/2., SCREEN_H/2.); + glTexCoord2d(tx+tw, ty+th); + glVertex2d(x+w, y+h); - glTexCoord2d(0., th); - glVertex2d(-SCREEN_W/2., SCREEN_H/2.); + glTexCoord2d(tx, ty+th); + glVertex2d(x, y+h); glEnd(); glDisable(GL_TEXTURE_2D); @@ -158,90 +161,31 @@ static int nebu_checkCompat(const char* file) { 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]; + SDL_Surface* sur; - 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); - cur += 4; - memcpy(&buf[cur], &h, 4); - cur += 4; - - /* 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. */ + sur = noise_surfaceFromNebulaeMap(map, w, h); + 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 + SDL_savePNG(sur, file_path); + + SDL_FreeSurface(sur); } /* 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; +static SDL_Surface* loadNebulae(const char* file) { char file_path[PATH_MAX]; + SDL_Surface* sur; -#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; - int cur; snprintf(file_path, PATH_MAX, "%s%s", lfile_basePath(), file); - fd = open(file_path, O_RDONLY); - if(fd < 0) { - ERR("Unable to open file %s: %s", file_path, strerror(errno)); + + sur = IMG_Load(file_path); + if(sur == NULL) { + ERR("Unable to load Nebulae image: %s", file); return NULL; } - READ(header, 16); - READ(&tw, 4); - READ(&th, 4); - buf = malloc(tw*th); - cur = 0; - while((len = read(fd, &buf[cur], tw*th - cur)) != 0) - cur += len; -#else -#error "Needs implementation." -#endif - (*w) = (int)tw; - (*h) = (int)th; - return buf; + return sur; } diff --git a/src/opengl.c b/src/opengl.c index e7e9e1d..b39df7f 100644 --- a/src/opengl.c +++ b/src/opengl.c @@ -233,14 +233,16 @@ int SDL_savePNG(SDL_Surface* surface, const char* file) { return r; } -/* ================ */ -/* TEXTURE! */ -/* ================ */ +/* + * ================ + * TEXTURE! + * ================ + */ -/* Returns the texture ID. */ -/* Stores real sizes in rw/rh (from POT padding). */ -static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh) { - GLuint texture; +/* Returns the texture ID. + * Stores real sizes in rw/rh (from POT padding). + */ +SDL_Surface* gl_prepareSurface(SDL_Surface* surface) { SDL_Surface* tmp; Uint32 saved_flags; Uint8 saved_alpha; @@ -250,8 +252,6 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh) { /* Make size power of two. */ potw = gl_pot(surface->w); poth = gl_pot(surface->h); - if(rw)*rw = potw; - if(rh)*rh = poth; rtemp.x = rtemp.y = 0; rtemp.w = surface->w; @@ -287,6 +287,20 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh) { if((saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA) SDL_SetAlpha(surface, 0, 0); + return surface; +} + +/* + * Return the texture id. + * Stores real sizes in rw/rh (from POT padding). + */ +static GLuint gl_loadSurface(SDL_Surface* surface, int *rw, int* rh) { + GLuint texture; + + surface = gl_prepareSurface(surface); + if(rw != NULL) (*rw) = surface->w; + if(rh != NULL) (*rh) = surface->h; + /* Opengl texture binding. */ glGenTextures(1, &texture); /* Create the texure. */ glBindTexture(GL_TEXTURE_2D, texture); /* Load the texture. */ diff --git a/src/opengl.h b/src/opengl.h index 200bb4a..2314080 100644 --- a/src/opengl.h +++ b/src/opengl.h @@ -63,7 +63,8 @@ typedef struct glTexture_ { uint8_t flags; /**< Flags used for texture properties. */ } glTexture; -/* gl_texute loading/freeing. */ +/* glTextyre loading/freeing. */ +SDL_Surface* gl_prepareSurface(SDL_Surface* surface); /* Only preps it. */ glTexture* gl_loadImage(SDL_Surface* surface); /* Frees the surface. */ glTexture* gl_newImage(const char* path); glTexture* gl_newSprite(const char* path, const int sx, const int sy); diff --git a/src/perlin.c b/src/perlin.c index 7b7c89d..ba199fe 100644 --- a/src/perlin.c +++ b/src/perlin.c @@ -248,17 +248,3 @@ SDL_Surface* noise_surfaceFromNebulaeMap(float* map, const int w, const int h) { return sur; } -glTexture* noise_genCloud(const int w, const int h, double rug) { - float* map; - SDL_Surface* sur; - glTexture* tex; - - map = noise_genNebulaeMap(w, h, 1, rug); - sur = noise_surfaceFromNebulaeMap(map, w, h); - free(map); - - tex = gl_loadImage(sur); - - return tex; -} - diff --git a/src/perlin.h b/src/perlin.h index af976ec..57c57b4 100644 --- a/src/perlin.h +++ b/src/perlin.h @@ -5,5 +5,3 @@ float* noise_genNebulaeMap(const int w, const int h, const int n, float rug); SDL_Surface* noise_surfaceFromNebulaeMap(float* map, const int w, const int h); -glTexture* noise_genCloud(const int w, const int h, double rug); -