#include <os.h>
#include <SDL/SDL.h>
#include <fdlibm.h>
#define SCREEN_W 320
#define SCREEN_H 240
#define IMG_W 256
#define IMG_H 256
#define fsin(x) sin(x * M_PI / 128)
#define fcos(x) cos(x * M_PI / 128)
void setPixel(SDL_Surface *surface, int x, int y, Uint32 pixel);
Uint32 getPixel(SDL_Surface *surface, int x, int y);
int main(void)
{
SDL_Surface *screen, *bitmap, *sky;
SDL_Event event;
SDL_Rect skyRect;
skyRect.x = (skyRect.y = 0);
skyRect.w = SCREEN_W;
skyRect.h = SCREEN_H >> 2;
Uint32 color = 0;
float sinLUT[256];
float cosLUT[256];
float distance, hScale, line_dx, line_dy, space_x, space_y, scaleX = 200.0, scaleY = 200.0, space_z = 96.0,
offsetX = 870, offsetY = 1515;
int screen_x, screen_y, horizon = 0, x;
unsigned char angle = 0, speedX = 4, speedY = 4, speedAngle = 4;
SDL_Init(SDL_INIT_VIDEO);
screen = SDL_SetVideoMode(SCREEN_W, SCREEN_H, is_cx?16:8, SDL_SWSURFACE);
bitmap = SDL_LoadBMP("/documents/Examples/texture.bmp.tns"); // TODO : make the load relative
for(x = 0; x < 256; x++)
{
sinLUT[x] = fsin(x);
cosLUT[x] = fcos(x);
}
if(!bitmap)
{
SDL_Quit();
exit(1);
}
while(1)
{
SDL_PollEvent(&event);
if(isKeyPressed(KEY_NSPIRE_ESC))
{
break;
}
if(isKeyPressed(KEY_NSPIRE_DOWN))
{
offsetX -= cosLUT[angle] * speedX;
offsetY -= sinLUT[angle] * speedY;
}
if(isKeyPressed(KEY_NSPIRE_LEFT))
{
angle = (angle - speedAngle) & 0xff;
}
if(isKeyPressed(KEY_NSPIRE_RIGHT))
{
angle = (angle + speedAngle) & 0xff;
}
if(isKeyPressed(KEY_NSPIRE_UP))
{
offsetX += cosLUT[angle] * speedX;
offsetY += sinLUT[angle] * speedY;
}
for(screen_y = SCREEN_H/4; screen_y < SCREEN_H; screen_y += 2)
{
distance = space_z * scaleY / (screen_y + horizon);
hScale = distance / scaleX;
line_dx = -sinLUT[angle] * hScale;
line_dy = cosLUT[angle] * hScale;
space_x = offsetX + distance * cosLUT[angle] - SCREEN_W/4 * line_dx;
space_y = offsetY + distance * sinLUT[angle] - SCREEN_W/4 * line_dy;
for(screen_x = 0; screen_x < SCREEN_W; screen_x += 2)
{
if(SDL_LockSurface(bitmap) != 0)
{
printf("Can't access bitmap");
exit(2);
}
if(SDL_LockSurface(screen) != 0)
{
printf("Can't access screen");
exit(2);
}
color = getPixel(bitmap, (unsigned int)space_x % IMG_W, (unsigned int)space_y % IMG_H);
setPixel(screen, screen_x, screen_y, color);
setPixel(screen, screen_x + 1, screen_y, color);
setPixel(screen, screen_x, screen_y + 1, color);
setPixel(screen, screen_x + 1, screen_y + 1, color);
SDL_UnlockSurface(screen);
SDL_UnlockSurface(bitmap);
space_x += line_dx;
space_y += line_dy;
}
}
SDL_FillRect(screen, &skyRect, SDL_MapRGB(screen->format, 255, 255, 255));
SDL_Flip(screen);
}
SDL_FreeSurface(bitmap);
SDL_Quit();
return 0;
}
void setPixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
int bpp = surface->format->BytesPerPixel;
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;
}
}
Uint32 getPixel(SDL_Surface *surface, int x, int y)
{
int bpp = surface->format->BytesPerPixel;
Uint32 value;
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
switch(bpp) {
case 1:
value = *p;
break;
case 2:
value = *(Uint16 *)p;
break;
case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
value = (p[0] & 0xff) | (p[1] << 8) | (p[2] << 16);
} else {
value = (p[2] & 0xff) | (p[1] << 8) | (p[0] << 16);
}
break;
case 4:
value = *(Uint32 *)p;
break;
}
return value;
}