00001 #include <SDL/SDL.h>
00002 #include <SDL/SDL_rotozoom.h>
00003 #include <SDL/SDL_gfxPrimitives.h>
00004
00005 #include "constants.h"
00006 #include "terrain.h"
00007 #include "random.h"
00008 #include "util.h"
00009 #include "starfield.h"
00010
00011 Terrain :: Terrain( int w, int h, bool drawTop, bool drawBottom )
00012 {
00013 sWidth = w;
00014 sHeight = h;
00015 speed = 1;
00016 segSize = sWidth/(MAPSIZE-2)+1;
00017 this->drawTop = drawTop;
00018 this->drawBottom = drawBottom;
00019
00020 stars = new StarField( true );
00021
00022 SDL_Surface *tmp = SDL_CreateRGBSurface(SDL_SWSURFACE, sWidth + 20, sHeight, 32,
00023 0x000000ff,0x0000ff00, 0x00ff0000, 0xff000000);
00024 terrainSurface = SDL_DisplayFormat( tmp );
00025 SDL_FreeSurface( tmp );
00026
00027 initTerrain();
00028
00029 }
00030
00031 Terrain :: ~Terrain()
00032 {
00033 SDL_FreeSurface( terrainSurface );
00034 delete stars;
00035 }
00036
00037 void Terrain :: initTerrain()
00038 {
00039 dir = 1;
00040 offset = 0;
00041
00042 maxHeight = 50;
00043
00044 mapTop[0] = (int)(nextInt(50)) + 5;
00045 mapBottom[0] = sHeight - (maxHeight - mapTop[0]);
00046 for ( int i = 1 ; i < MAPSIZE ; ++i )
00047 setPoint( i );
00048
00049 SDL_FillRect( terrainSurface, 0, 0 );
00050
00051
00052 Sint16 px[5];
00053 Sint16 py[5];
00054
00055 for ( int i = 0 ; i < MAPSIZE ; ++i )
00056 {
00057 int left = (i*segSize);
00058 int right = ((i+1)*segSize);
00059 px[0] = left;
00060 py[0] = mapTop[i];
00061 px[1] = right;
00062 py[1] = mapTop[i+1];
00063 px[2] = right;
00064 py[2] = 0;
00065 px[3] = left;
00066 py[3] = 0;
00067
00068 if ( drawTop )
00069 {
00070
00071 filledPolygonRGBA( terrainSurface, px, py, 4, 0, 190, 0, 255 );
00072 }
00073
00074 if ( drawBottom )
00075 {
00076 py[0] = mapBottom[i];
00077 py[1] = mapBottom[i+1];
00078 py[2] = sHeight;
00079 py[3] = sHeight;
00080 filledPolygonRGBA( terrainSurface, px, py, 4, 0, 190, 0, 255 );
00081 }
00082
00083 }
00084
00085
00086 }
00087
00088 void Terrain :: moveTerrain( int amountToMove )
00089 {
00090 stars->move();
00091
00092 offset += amountToMove;
00093 speed = offset/segSize;
00094
00095 if ( offset >= segSize )
00096 {
00097 for ( int i = 0 ; i < (MAPSIZE)-speed ; ++i )
00098 {
00099 mapTop[i] = mapTop[i+speed];
00100 mapBottom[i] = mapBottom[i+speed];
00101 }
00102
00103 for ( int i = (MAPSIZE)-speed ; i < MAPSIZE ; ++i )
00104 {
00105 setPoint( i );
00106 }
00107
00108 SDL_Rect dst;
00109 dst.x = offset;
00110 dst.y = 0;
00111 dst.w = sWidth;
00112 dst.h = sHeight;
00113
00114 SDL_Rect dst2;
00115 dst2.x = 0;
00116 dst2.y = 0;
00117
00118 SDL_BlitSurface(terrainSurface, &dst, terrainSurface, &dst2 );
00119
00120 dst.x = sWidth-5;
00121 dst.y = 0;
00122 dst.w = offset;
00123 dst.h = sHeight;
00124 SDL_FillRect( terrainSurface, &dst, 0 );
00125 for ( int i = (MAPSIZE-1) - speed -1; i < MAPSIZE-1 ; ++i )
00126 {
00127 Sint16 px[4];
00128 Sint16 py[5];
00129 int left = ((i-1)*segSize);
00130 int right = ((i)*segSize);
00131
00132
00133 px[0] = left;
00134 py[0] = mapTop[i];
00135 px[1] = right;
00136 py[1] = mapTop[i+1];
00137 px[2] = right;
00138 py[2] = 0;
00139 px[3] = left;
00140 py[3] = 0;
00141
00142 if ( drawTop )
00143 {
00144
00145 filledPolygonRGBA( terrainSurface, px, py, 4, 0, 190, 0, 255 );
00146 }
00147
00148 if ( drawBottom )
00149 {
00150 py[0] = mapBottom[i];
00151 py[1] = mapBottom[i+1];
00152 py[2] = sHeight;
00153 py[3] = sHeight;
00154 filledPolygonRGBA( terrainSurface, px, py, 4, 0, 190, 0, 255 );
00155 }
00156 }
00157
00158 offset -= speed*segSize;
00159
00160 }
00161
00162 }
00163
00164 void Terrain :: setPoint( int point )
00165 {
00166 if ( nextInt( 100 ) >= 80 )
00167 dir *= -1;
00168
00169 mapTop[point] = mapTop[point-1] + (dir * nextInt( 5 ));
00170 if ( mapTop[point] < 0 )
00171 {
00172 mapTop[point] = 0;
00173 dir *= -1;
00174 }
00175 else if ( mapTop[point] >= maxHeight )
00176 {
00177 mapTop[point] = maxHeight;
00178 dir *= -1;
00179 }
00180
00181 mapBottom[point] = sHeight - (maxHeight - mapTop[point]);
00182 }
00183
00184 void Terrain :: increaseMaxHeight( int amount )
00185 {
00186 maxHeight += amount;
00187 }
00188
00189 void Terrain :: drawTerrain( SDL_Surface *screen )
00190 {
00191
00192
00193 SDL_Rect dst;
00194 dst.x = offset;
00195 dst.y = 0;
00196 dst.w = sWidth;
00197 dst.h = sHeight;
00198
00199 SDL_Rect dst2;
00200 dst2.x = 0;
00201 dst2.y = 0;
00202
00203 SDL_BlitSurface(terrainSurface, &dst, screen, &dst2 );
00204
00205 stars->draw( screen );
00206 }
00207
00208 bool Terrain :: checkCollision( int x, int y, int h )
00209 {
00210 if ( y < 0 || y > sHeight )
00211 return true;
00212
00213
00214 SDL_LockSurface( terrainSurface );
00215
00216 Uint32 c = getpixel( terrainSurface, x, y );
00217
00218 SDL_UnlockSurface( terrainSurface );
00219
00220 if ( c == 0 )
00221 return false;
00222 else
00223 return true;
00224 }
00225
00226
00227
00228 #ifdef DEBUG_TERRAIN
00229 SDL_Surface *screen;
00230 Terrain *terrain;
00231
00232 void go()
00233 {
00234
00235 if ( SDL_Init(SDL_INIT_VIDEO) < 0 )
00236 {
00237 fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
00238 exit(1);
00239 }
00240 atexit(SDL_Quit);
00241
00242 int videoflags = SDL_SWSURFACE ;
00243
00244 if ( (screen=SDL_SetVideoMode(280, 320,32,videoflags)) == NULL )
00245 {
00246 fprintf(stderr, "Couldn't set %ix%i video mode: %s\n",WIDTH,HEIGHT,SDL_GetError());
00247 exit(2);
00248 }
00249
00250 terrain = new Terrain( 240, 320 );
00251
00252 bool done = false;
00253 while ( !done )
00254 {
00255 SDL_FillRect( screen, 0, 0 );
00256 terrain->drawTerrain( screen );
00257 terrain->moveTerrain( 5 );
00258
00259 SDL_Flip( screen );
00260
00261 SDL_Delay( 5 );
00262
00263 SDL_Event event;
00264 while ( SDL_PollEvent(&event) )
00265 {
00266 switch (event.type)
00267 {
00268 case SDL_KEYDOWN:
00269
00270 if ( event.key.keysym.sym != SDLK_ESCAPE )
00271 {
00272 terrain->moveTerrain( 5 );
00273 break;
00274 }
00275 case SDL_QUIT:
00276 done = 1;
00277 break;
00278 default:
00279 break;
00280 }
00281 }
00282 }
00283 }
00284
00285
00286
00287
00288 #ifdef __cplusplus
00289 extern "C"
00290 #endif
00291 int main( int argc, char *argv[] )
00292 {
00293 go();
00294 }
00295
00296 #endif
00297