Lephisto/src/space.c
2013-02-02 06:15:51 +00:00

157 lines
3.8 KiB
C

#include "log.h"
#include "physics.h"
#include "opengl.h"
#include "rng.h"
#include "pilot.h"
#include "space.h"
#define STAR_LAYERS 3
static gl_texture* starBG[STAR_LAYERS];
static Vec2 starPos[STAR_LAYERS];
static gl_texture* starBG_create(const int density);
static void put_pixel(SDL_Surface* surface, const int x, const int y,
const Uint8 R, const Uint8 G, const Uint8 B, const Uint8 A);
// Modify the pixel at (x,y) of the surface to be of color RGB.
static void put_pixel(SDL_Surface* surface, const int x, const int y,
const Uint8 R, const Uint8 G, const Uint8 B, const Uint8 A) {
Uint32 pixel = SDL_MapRGBA(surface->format, R, G, B, A);
int bpp = surface->format->BytesPerPixel;
// p is the address to the pixel we want to set.
Uint8* p = (Uint8*)surface->pixels + y * surface->pitch + x * bpp;
switch(bpp) {
case 1:
*p = pixel;
break;
case 2:
*(Uint16*)p = pixel;
break;
case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
p[0] = (pixel >> 16) & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = pixel & 0xff;
} else {
p[0] = pixel & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff;
}
break;
case 4:
*(Uint32*)p = pixel;
break;
}
}
// Create a background of stars to use.
// Background consists of four tiles together.
static gl_texture* starBG_create(const int density) {
SDL_Surface* surface;
int w, h;
int i, d;
w = (int)((float)gl_screen.w * 1.5);
if((w & (w-1)) != 0) {
w = 1;
while(w < (int)((float)gl_screen.w*1.5))
w <<= 1;
}
h = (int)((float)gl_screen.h * 1.5);
if((h & (h-1)) != 0) {
h = 1;
while(h < (int)((float)gl_screen.h * 1.5))
h <<= 1;
}
surface = SDL_CreateRGBSurface(SDL_SRCCOLORKEY, w, h,
SDL_GetVideoSurface()->format->BytesPerPixel*8, RGBMASK);
if(surface == NULL) {
WARN("Unable to create RGB surface");
return NULL;
}
SDL_LockSurface(surface);
d = (int)((FP)(density)*(FP)(gl_screen.w)*(FP)(gl_screen.h)/1000./1000.);
for(i = 0; i < d; i++)
put_pixel(surface, RNG(0,w-1), RNG(0,h-1), 255, 255, 255, RNG(50, 255));
SDL_UnlockSurface(surface);
return gl_loadImage(surface);
}
void space_init(void) {
int i;
for(i = 0; i < STAR_LAYERS; i++) {
starBG[i] = starBG_create(1000);
starPos[i].x = 0.;
starPos[i].y = 0.;
}
}
void space_render(FP dt) {
int i;
Vec2 tmp;
FP f;
for(i = 0; i < STAR_LAYERS; i++) {
// Movement.
starPos[i].x -= player->solid->vel.x / (FP)(2*i+10)*dt;
starPos[i].y -= player->solid->vel.y / (FP)(2*i+104)*dt;
// Displaces x if reaches edge.
if(starPos[i].x > 0)
starPos[i].x -= starBG[i]->w;
else if(starPos[i].x < -starBG[i]->w)
starPos[i].x += starBG[i]->w;
// Displaces y if reaches edge.
if(starPos[i].y > 0)
starPos[i].y -= starBG[i]->h;
else if(starPos[i].y < -starBG[i]->h)
starPos[i].y += starBG[i]->h;
// Primary blit.
gl_blitStatic(starBG[i], &starPos[i]);
tmp.x = starPos[i].x;
tmp.y = starPos[i].y;
// More blits if part of the screen is blank.
if(starPos[i].x < starBG[i]->w/4.)
tmp.x += starBG[i]->w;
else if(starPos[i].x < starBG[i]->w*3./4.)
tmp.y -= starBG[i]->w;
if(starPos[i].y < starBG[i]->h/4.)
tmp.y += starBG[i]->h;
else if(starPos[i].y < starBG[i]->h*3./4.)
tmp.y -= starBG[i]->h;
if(tmp.x != starPos[i].x && tmp.y != starPos[i].y) {
gl_blitStatic(starBG[i], &tmp);
f = tmp.x;
tmp.x = starPos[i].x;
gl_blitStatic(starBG[i], &tmp);
tmp.x = f;
tmp.y = starPos[i].y;
gl_blitStatic(starBG[i], &tmp);
}
else if(tmp.x != starPos[i].x || tmp.y != starPos[i].y)
gl_blitStatic(starBG[i], &tmp);
}
}
void space_exit(void) {
int i;
for(i = 0; i < STAR_LAYERS; i++)
gl_freeTexture(starBG[i]);
}