00001 #include <SDL/SDL.h>
00002 #include <SDL/SDL_gfxPrimitives.h>
00003
00004 #include <stdlib.h>
00005
00006 #include "starfield.h"
00007 #include "random.h"
00008 #include "util.h"
00009
00010 #define VERTICAL_VELOCITY 0
00011
00012 StarField :: StarField( bool side, int nStars, int mx, int my, int minz, int maxz )
00013 {
00014 nrStars = nStars;
00015 maxX = mx;
00016 maxY = my;
00017 minZ = minz;
00018 maxZ = maxz;
00019
00020 min_brightness = 50;
00021 top_star_speed = 6;
00022
00023 sideways = side;
00024
00025 if ( !sideways )
00026 {
00027 x = new int[nrStars];
00028 y = new int[nrStars];
00029 z = new int[nrStars];
00030
00031 star_color = 0;
00032 vel_x = 0;
00033 vel_y = 0;
00034 pos_x = 0;
00035 pos_y = 0;
00036 }
00037 else
00038 {
00039 star_color = new int[nrStars];
00040 vel_x = new int[nrStars];
00041 vel_y = new int[nrStars];
00042 pos_x = new int[nrStars];
00043 pos_y = new int[nrStars];
00044
00045 x = 0;
00046 y = 0;
00047 z = 0;
00048 }
00049
00050 init();
00051 }
00052
00053 StarField :: ~StarField()
00054 {
00055 if ( star_color )
00056 delete []star_color;
00057 if ( vel_x )
00058 delete []vel_x;
00059 if ( vel_y )
00060 delete []vel_y;
00061 if ( pos_x )
00062 delete []pos_x;
00063 if ( pos_y )
00064 delete []pos_y;
00065
00066 if ( x )
00067 delete []x;
00068 if ( y )
00069 delete []y;
00070 if ( z )
00071 delete []z;
00072 }
00073
00074 void StarField :: init()
00075 {
00076 if ( !sideways )
00077 {
00078 for ( int i = 0 ; i < nrStars ; ++i )
00079 {
00080 newStar( i );
00081 z[i] = (int)(Random() * (double)(maxZ - minZ)) + minZ ;
00082 }
00083 }
00084 else
00085 {
00086 int brightness;
00087
00088
00089 for(int i = 0; i < nrStars ; i++)
00090 {
00091
00092 vel_x[i] = -(int)floor( (Random() * top_star_speed)+1 );
00093 vel_y[i] = VERTICAL_VELOCITY;
00094
00095
00096 pos_x[i] = (int)floor((Random() * 240));
00097 pos_y[i] = (int)floor((Random() * 320));
00098
00099
00100 if (vel_x[i] != 0)
00101 {
00102 brightness = (int)(255 / fabs(vel_x[i]) );
00103 if (brightness < min_brightness)
00104 brightness = min_brightness;
00105 }
00106 else
00107 brightness = 255;
00108
00109 star_color[i] = brightness;
00110 }
00111 }
00112 }
00113
00114 void StarField :: newStar( int starNr )
00115 {
00116 if ( !sideways )
00117 {
00118 x[starNr] = (int)(Random() * (double)maxX) + 1;
00119 y[starNr] = (int)(Random() * (double)maxY) + 1;
00120 z[starNr] = maxZ;
00121
00122 int i = (int)(Random() * 4.0);
00123 if(i < 2)
00124 x[starNr] = -x[starNr];
00125 if(i == 0 || i == 2)
00126 y[starNr] = -y[starNr];
00127 }
00128 }
00129
00130 void StarField :: move( )
00131 {
00132 if ( !sideways )
00133 {
00134 int amountToMove = 16;
00135 for(int i = 0; i < nrStars; i++)
00136 {
00137
00138 z[i] = z[i] - amountToMove;
00139 if(z[i] < minZ)
00140 newStar(i);
00141 }
00142 }
00143 else
00144 {
00145 for(int i = 0; i < nrStars ; i++)
00146 {
00147
00148 if (vel_x[i] > top_star_speed)
00149 vel_x[i] = top_star_speed;
00150 else if (vel_x[i] < -top_star_speed)
00151 vel_x[i] = -top_star_speed;
00152
00153
00154 if (vel_y[i] > top_star_speed)
00155 vel_y[i] = top_star_speed;
00156 else if (vel_y[i] < -top_star_speed)
00157 vel_y[i] = -top_star_speed;
00158
00159
00160
00161
00162 pos_x[i] += vel_x[i];
00163 pos_y[i] += vel_y[i];
00164
00165 if (pos_x[i] < 0)
00166 pos_x[i] = pos_x[i] + 240;
00167
00168 if (pos_x[i] > 240)
00169 pos_x[i] = pos_x[i] - 240;
00170 if (pos_y[i] < 0)
00171 pos_y[i] = pos_y[i] + 320;
00172
00173 if (pos_y[i] > 320)
00174 pos_y[i] = pos_y[i] - 320;
00175 }
00176 }
00177 }
00178
00179 void StarField :: draw( SDL_Surface *screen, int w, int h )
00180 {
00181 if ( !sideways )
00182 {
00183 int scrW = w / 2;
00184 int scrH = h / 2;
00185 for(int i = 0; i < nrStars; i++)
00186 {
00187 int sx = (x[i] * 256) / z[i] + scrW;
00188 int sy = (y[i] * 256) / z[i] + scrH;
00189 if(sx < 0 || sx > w || sy < 0 || sy > h)
00190 {
00191 newStar(i);
00192 }
00193 else
00194 {
00195 int size = (z[i] * 3) / maxZ;
00196
00197 SDL_Rect r;
00198 r.x = sx;
00199 r.y = sy;
00200 r.w = 3 - size;
00201 r.h = 3 - size;
00202
00203 SDL_FillRect( screen, &r, SDL_MapRGB( screen->format, 255, 255, 255 ) );
00204 }
00205 }
00206 }
00207 else
00208 {
00209 SDL_LockSurface( screen );
00210 for(int i = 0; i < nrStars ; i++)
00211 {
00212
00213 Uint32 c = getpixel( screen, pos_x[i], pos_y[i] );
00214
00215
00216 if ( c == 0 )
00217 lineRGBA( screen, pos_x[i], pos_y[i], pos_x [i]+ vel_x[i], pos_y[i] + vel_y[i], star_color[i], star_color[i], star_color[i], 255 );
00218
00219
00220 }
00221 SDL_UnlockSurface( screen );
00222 }
00223 }
00224
00225
00226
00227
00228 #ifdef DEBUG_STARS
00229 SDL_Surface *screen;
00230 StarField *stars;
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(240, 320,32,videoflags)) == NULL )
00245 {
00246 fprintf(stderr, "Couldn't set %ix%i video mode: %s\n",240,320,SDL_GetError());
00247 exit(2);
00248 }
00249
00250 stars = new StarField( false, 200 );
00251
00252 bool done = false;
00253 while ( !done )
00254 {
00255 SDL_FillRect( screen, 0, 0 );
00256 stars->draw( screen );
00257 stars->move( );
00258
00259 SDL_Flip( screen );
00260
00261 SDL_Delay( 10 );
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 break;
00273 }
00274 case SDL_QUIT:
00275 done = 1;
00276 break;
00277 default:
00278 break;
00279 }
00280 }
00281 }
00282 }
00283
00284
00285
00286
00287 #ifdef __cplusplus
00288 extern "C"
00289 #endif
00290 int main( int argc, char *argv[] )
00291 {
00292 go();
00293 }
00294
00295 #endif