Diffstat (limited to 'noncore/games/sfcave-sdl/terrain.cpp') (more/less context) (show whitespace changes)
-rw-r--r-- | noncore/games/sfcave-sdl/terrain.cpp | 313 |
1 files changed, 313 insertions, 0 deletions
diff --git a/noncore/games/sfcave-sdl/terrain.cpp b/noncore/games/sfcave-sdl/terrain.cpp new file mode 100644 index 0000000..c001a56 --- a/dev/null +++ b/noncore/games/sfcave-sdl/terrain.cpp @@ -0,0 +1,313 @@ +#include "SDL.h" +#include "SDL_rotozoom.h" +#include "SDL_gfxPrimitives.h" + +#include "constants.h" +#include "terrain.h" +#include "random.h" +#include "util.h" +#include "starfield.h" + +Terrain :: Terrain( int w, int h, bool drawTop, bool drawBottom ) +{ + sWidth = w; + sHeight = h; + speed = 1; + segSize = sWidth/(MAPSIZE-2)+1; + this->drawTop = drawTop; + this->drawBottom = drawBottom; + + stars = new StarField( true ); + + SDL_Surface *tmp = SDL_CreateRGBSurface(SDL_SWSURFACE, sWidth + 20, sHeight, 32, + 0x000000ff,0x0000ff00, 0x00ff0000, 0xff000000); + terrainSurface = SDL_DisplayFormat( tmp ); + SDL_FreeSurface( tmp ); + + initTerrain(); + +} + +Terrain :: ~Terrain() +{ + SDL_FreeSurface( terrainSurface ); + delete stars; +} + +void Terrain :: initTerrain() +{ + dir = 1; + offset = 0; + + maxHeight = 50; + + mapTop[0] = (int)(nextInt(50)) + 5; + mapBottom[0] = sHeight - (maxHeight - mapTop[0]); + for ( int i = 1 ; i < MAPSIZE ; ++i ) + setPoint( i ); + + SDL_FillRect( terrainSurface, 0, 0 ); + // Draw Terrain into surface + Sint16 px[5]; + Sint16 py[5]; + + for ( int i = 0 ; i < MAPSIZE ; ++i ) + { + int left = (i*segSize); + int right = ((i+1)*segSize); + px[0] = left; + py[0] = mapTop[i]; + px[1] = right; + py[1] = mapTop[i+1]; + px[2] = right; + py[2] = 0; + px[3] = left; + py[3] = 0; + + if ( drawTop ) + { + // Only display top landscape if not running FLY_GAME + filledPolygonRGBA( terrainSurface, px, py, 4, 0, 190, 0, 255 ); + } + + if ( drawBottom ) + { + py[0] = mapBottom[i]; + py[1] = mapBottom[i+1]; + py[2] = sHeight; + py[3] = sHeight; + filledPolygonRGBA( terrainSurface, px, py, 4, 0, 190, 0, 255 ); + } + + } + + +} + +void Terrain :: moveTerrain( int amountToMove ) +{ + stars->move(); + + offset += amountToMove; + speed = offset/segSize; + +// printf( "offset - %d, speed - %d\n", offset, speed ); + if ( offset >= segSize ) + { + for ( int i = 0 ; i < (MAPSIZE)-speed ; ++i ) + { + mapTop[i] = mapTop[i+speed]; + mapBottom[i] = mapBottom[i+speed]; + } + + for ( int i = (MAPSIZE)-speed ; i < MAPSIZE ; ++i ) + { + setPoint( i ); + } + + SDL_Rect dst; + dst.x = offset; + dst.y = 0; + dst.w = sWidth; + dst.h = sHeight; + + SDL_Rect dst2; + dst2.x = 0; + dst2.y = 0; + + SDL_BlitSurface(terrainSurface, &dst, terrainSurface, &dst2 ); + + dst.x = sWidth-5; + dst.y = 0; + dst.w = offset; + dst.h = sHeight; + SDL_FillRect( terrainSurface, &dst, 0 ); + for ( int i = (MAPSIZE-1) - speed -1; i < MAPSIZE-1 ; ++i ) + { + Sint16 px[4]; + Sint16 py[5]; + int left = ((i-1)*segSize); + int right = ((i)*segSize); + // printf( "left = %d, right = %d\n", left, right ); + + px[0] = left; + py[0] = mapTop[i]; + px[1] = right; + py[1] = mapTop[i+1]; + px[2] = right; + py[2] = 0; + px[3] = left; + py[3] = 0; + + if ( drawTop ) + { + // Only display top landscape if not running FLY_GAME + filledPolygonRGBA( terrainSurface, px, py, 4, 0, 190, 0, 255 ); + } + + if ( drawBottom ) + { + py[0] = mapBottom[i]; + py[1] = mapBottom[i+1]; + py[2] = sHeight; + py[3] = sHeight; + filledPolygonRGBA( terrainSurface, px, py, 4, 0, 190, 0, 255 ); + } + } + + offset -= speed*segSize; + + } + +} + +void Terrain :: setPoint( int point ) +{ + if ( nextInt( 100 ) >= 80 ) + dir *= -1; + + mapTop[point] = mapTop[point-1] + (dir * nextInt( 5 )); + if ( mapTop[point] < 0 ) + { + mapTop[point] = 0; + dir *= -1; + } + else if ( mapTop[point] >= maxHeight ) + { + mapTop[point] = maxHeight; + dir *= -1; + } + + mapBottom[point] = sHeight - (maxHeight - mapTop[point]); +} + +void Terrain :: increaseMaxHeight( int amount ) +{ + maxHeight += amount; +} + +void Terrain :: drawTerrain( SDL_Surface *screen ) +{ + // Blit terrain surface onto screen + + SDL_Rect dst; + dst.x = offset; + dst.y = 0; + dst.w = sWidth; + dst.h = sHeight; +// dst.h = maxHeight; + + SDL_Rect dst2; + dst2.x = 0; + dst2.y = 0; + + SDL_BlitSurface(terrainSurface, &dst, screen, &dst2 ); + + stars->draw( screen ); + +// dst.y = sHeight - maxHeight; +// dst2.y = sHeight - maxHeight; +// SDL_BlitSurface(terrainSurface, &dst, screen, &dst2 ); + +/* + for ( int i = 0 ; i < MAPSIZE ; ++i ) + { + int x1 = (i*segSize) - (offset*speed); + int x2 = ((i+1)*segSize)-(offset*speed); + if ( x2 >= sWidth ) + x2 = sWidth-1; + aalineRGBA( screen, x1, mapTop[i], x2, mapTop[i+1], 0, 220, 0, 255 ); + aalineRGBA( screen, x1, mapBottom[i], x2, mapBottom[i+1], 0, 220, 0, 255 ); + } +*/ +} + +bool Terrain :: checkCollision( int x, int y, int h ) +{ + if ( y < 0 || y > sHeight ) + return true; + // First get segment that matches x + SDL_LockSurface( terrainSurface ); + + Uint32 c = getpixel( terrainSurface, x, y ); + + SDL_UnlockSurface( terrainSurface ); + + if ( c == 0 ) + return false; + else + return true; +} + + +// Test +#ifdef DEBUG_TERRAIN +SDL_Surface *screen; +Terrain *terrain; + +void go() +{ + /* Initialize SDL */ + if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) + { + fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError()); + exit(1); + } + atexit(SDL_Quit); + + int videoflags = SDL_SWSURFACE ; + + if ( (screen=SDL_SetVideoMode(280, 320,32,videoflags)) == NULL ) + { + fprintf(stderr, "Couldn't set %ix%i video mode: %s\n",WIDTH,HEIGHT,SDL_GetError()); + exit(2); + } + + terrain = new Terrain( 240, 320 ); + + bool done = false; + while ( !done ) + { + SDL_FillRect( screen, 0, 0 ); + terrain->drawTerrain( screen ); + terrain->moveTerrain( 5 ); + + SDL_Flip( screen ); + + SDL_Delay( 5 ); + + SDL_Event event; + while ( SDL_PollEvent(&event) ) + { + switch (event.type) + { + case SDL_KEYDOWN: + // Escape keypress quits the app + if ( event.key.keysym.sym != SDLK_ESCAPE ) + { + terrain->moveTerrain( 5 ); + break; + } + case SDL_QUIT: + done = 1; + break; + default: + break; + } + } + } + } + + + + +#ifdef __cplusplus +extern "C" +#endif +int main( int argc, char *argv[] ) +{ + go(); +} + +#endif + |