JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
* main.c (enginedots, bangdots): combined into a single dot type.
authorJoshua Grams <josh@qualdan.com>
Mon, 5 Mar 2007 13:01:26 +0000 (13:01 +0000)
committerJoshua Grams <josh@qualdan.com>
Mon, 5 Mar 2007 13:01:26 +0000 (13:01 +0000)
config.h
globals.h
main.c

index 77b453c..dc5e983 100644 (file)
--- a/config.h
+++ b/config.h
@@ -45,7 +45,7 @@
 #define M 255
 
 // determines how hard they push the rocks. Set to 0 to disable pushing rocks
-#define ENGINE_DOT_WEIGHT 0.07
+#define DOT_MASS_UNIT 0.07
 
 // radius^2 (pixels) which will be cleared of rocks when you die
 #define BLAST_RADIUS 300
index 7f47314..c98f1f8 100644 (file)
--- a/globals.h
+++ b/globals.h
@@ -5,25 +5,6 @@
 #include <inttypes.h>
 #include "font.h"
 
-struct bangdots {
-       // Bang dots have the same colour as shield dots.
-       // Bang dots get darker as they age.
-       // Some are coloured the same as the ex-ship.
-       float x,y,dx,dy;
-       Uint16 c; // when zero, use heatcolor[bangdotlife]
-       float life;     // When reduced to 0, set active = 0
-       int active;
-       float decay;// Amount by which to reduce life each time dot is drawn
-};
-struct enginedots {
-       // Engine dots stream out the back of the ship, getting darker as they go.
-       int active;
-       float x,y,dx,dy;
-       // The life of an engine dot 
-       // is a number starting at between 0 and 50 and counting backward.
-       float life;     // When reduced to 0, set active = 0
-};
-
 // ************************************* VARS
 // SDL_Surface global variables
 extern SDL_Surface 
@@ -40,10 +21,6 @@ extern SDL_Surface
 
 extern font *g_font;
 
-// Structure global variables
-extern struct enginedots edot[MAXENGINEDOTS], *dotptr;
-extern struct bangdots bdot[MAXBANGDOTS], *bdotptr;
-
 // Other global variables
 extern char topline[1024];
 extern char *initerror;
diff --git a/main.c b/main.c
index 88d207a..f69b5dc 100644 (file)
--- a/main.c
+++ b/main.c
@@ -58,9 +58,16 @@ SDL_Surface
 
 font *g_font;
 
-// Structure global variables
-struct enginedots edot[MAXENGINEDOTS], *dotptr = edot;
-struct bangdots bdot[MAXBANGDOTS], *bdotptr = bdot;
+struct dot {
+       int active;
+       float x, y;
+       float dx, dy;
+       float mass;   // in DOT_MASS_UNITs
+       float decay;  // rate at which to reduce mass.
+};
+
+struct dot edot[MAXENGINEDOTS], *dotptr = edot;
+struct dot bdot[MAXBANGDOTS];
 
 // Other global variables
 char topline[1024];
@@ -132,103 +139,6 @@ init_engine_dots() {
        }
 }
 
-void
-new_bang_dots(struct sprite *s)
-{
-       int i, n, x, y;
-       uint16_t *pixel, c;
-       uint32_t colorkey;
-       int row_inc;
-       double theta, r;
-       SDL_Surface *img = s->image;
-
-       n = 20;
-       pixel = img->pixels;
-       row_inc = img->pitch/sizeof(uint16_t) - img->w;
-       colorkey = img->format->colorkey;
-
-       if(SDL_MUSTLOCK(img)) { SDL_LockSurface(img); }
-
-       for(i=0; i<n; i++) {
-               pixel = img->pixels;
-               for(y=0; y<img->h; y++) {
-                       for(x = 0; x<img->w; x++) {
-                               c = *pixel++;
-                               if(c && c != colorkey) {
-                                       theta = frnd()*M_PI*2;
-                                       r = frnd(); r = 1 - r*r;
-
-                                       bdot[bd2].dx = 45*r*cos(theta) + s->dx;
-                                       bdot[bd2].dy = 45*r*sin(theta) + s->dy;
-                                       bdot[bd2].x = x + s->x;
-                                       bdot[bd2].y = y + s->y;
-                                       //bdot[bd2].c = (i < n-3) ? 0 : c;
-                                       bdot[bd2].life = frnd() * 99;
-                                       bdot[bd2].decay = frnd()*3 + 1;
-                                       bdot[bd2].active = 1;
-
-                                       bd2 = (bd2+1) % MAXBANGDOTS;
-                               }
-                               pixel += row_inc;
-                       }
-               }
-       }
-
-       if(SDL_MUSTLOCK(img)) { SDL_UnlockSurface(img); }
-}
-
-void
-move_bang_dots(float ticks)
-{
-       int i;
-       Sprite *hit;
-
-       for(i=0; i<MAXBANGDOTS; i++) {
-               if(!bdot[i].active) continue;
-
-               // decrement life and maybe kill
-               bdot[i].life -= bdot[i].decay * ticks/2.0;
-               if(bdot[i].life < 0) { bdot[i].active = 0; continue; }
-               
-               // move and clip
-               bdot[i].x += (bdot[i].dx - screendx)*ticks;
-               bdot[i].y += (bdot[i].dy - screendy)*ticks;
-               if(fclip(bdot[i].x, XSIZE) || fclip(bdot[i].y, YSIZE)) {
-                       bdot[i].active = 0;
-                       continue;
-               }
-
-               // check collisions
-               if((hit = pixel_collides(bdot[i].x, bdot[i].y))) {
-                       if(hit->type != SHIP) { // they shouldn't hit the ship, but they do
-                               bdot[i].active = 0;
-                               hit->dx += ENGINE_DOT_WEIGHT * bdot[i].life * bdot[i].dx / sprite_mass(hit);
-                               hit->dy += ENGINE_DOT_WEIGHT * bdot[i].life * bdot[i].dy / sprite_mass(hit);
-                               continue;
-                       }
-               }
-       }
-}
-
-
-void
-draw_bang_dots(SDL_Surface *s)
-{
-       int i;
-       uint16_t *pixels, *pixel, c;
-       int row_inc = s->pitch/sizeof(uint16_t);
-
-       pixels = (uint16_t *) s->pixels;
-
-       for(i=0; i<MAXBANGDOTS; i++) {
-               if(!bdot[i].active) continue;
-
-               pixel = pixels + row_inc*(int)(bdot[i].y) + (int)(bdot[i].x);
-               if(bdot[i].c) c = bdot[i].c; else c = heatcolor[(int)(bdot[i].life)*3];
-               *pixel = c;
-       }
-}
-
 
 void
 new_engine_dots(float time_span) {
@@ -255,6 +165,7 @@ new_engine_dots(float time_span) {
                                dy = r * -sin(a);  // screen y is "backwards".
 
                                dotptr->active = 1;
+                               dotptr->decay = 3;
 
                                // dot was created at a random time during the time span
                                time = frnd() * time_span; // this is how long ago
@@ -278,11 +189,11 @@ new_engine_dots(float time_span) {
                                if(dir&1) {
                                        dotptr->dx = past_ship_dx + 2*dx;
                                        dotptr->dy = past_ship_dy + 20*dy;
-                                       dotptr->life = 60 * fabs(dy);
+                                       dotptr->mass = 60 * fabs(dy);
                                } else {
                                        dotptr->dx = past_ship_dx + 20*dx;
                                        dotptr->dy = past_ship_dy + 2*dy;
-                                       dotptr->life = 60 * fabs(dx);
+                                       dotptr->mass = 60 * fabs(dx);
                                }
 
                                // move the dot as though it were created in the past
@@ -296,48 +207,115 @@ new_engine_dots(float time_span) {
        }
 }
 
+
 void
-move_engine_dots(float ticks) {
-       int i;
-       Sprite *hit;
+new_bang_dots(struct sprite *s)
+{
+       int i, n, x, y;
+       uint16_t *pixel, c;
+       uint32_t colorkey;
+       int row_inc;
+       double theta, r;
+       SDL_Surface *img = s->image;
 
-       for(i = 0; i<MAXENGINEDOTS; i++) {
-               if(!edot[i].active) continue;
+       n = 20;
+       pixel = img->pixels;
+       row_inc = img->pitch/sizeof(uint16_t) - img->w;
+       colorkey = img->format->colorkey;
 
-               edot[i].x += (edot[i].dx - screendx)*ticks;
-               edot[i].y += (edot[i].dy - screendy)*ticks;
-               edot[i].life -= t_frame*3;
-               if(edot[i].life < 0 || fclip(edot[i].x, XSIZE) || fclip(edot[i].y, YSIZE)) {
-                       edot[i].active = 0;
-                       continue;
+       if(SDL_MUSTLOCK(img)) { SDL_LockSurface(img); }
+
+       for(i=0; i<n; i++) {
+               pixel = img->pixels;
+               for(y=0; y<img->h; y++) {
+                       for(x = 0; x<img->w; x++) {
+                               c = *pixel++;
+                               if(c && c != colorkey) {
+                                       theta = frnd()*M_PI*2;
+                                       r = frnd(); r = 1 - r*r;
+
+                                       bdot[bd2].dx = 45*r*cos(theta) + s->dx;
+                                       bdot[bd2].dy = 45*r*sin(theta) + s->dy;
+                                       bdot[bd2].x = x + s->x;
+                                       bdot[bd2].y = y + s->y;
+                                       bdot[bd2].mass = frnd() * 99;
+                                       bdot[bd2].decay = frnd()*1.5 + 0.5;
+                                       bdot[bd2].active = 1;
+
+                                       bd2 = (bd2+1) % MAXBANGDOTS;
+                               }
+                               pixel += row_inc;
+                       }
                }
+       }
+
+       if(SDL_MUSTLOCK(img)) { SDL_UnlockSurface(img); }
+}
+
 
-               // check collisions
-               if((hit = pixel_collides(edot[i].x, edot[i].y))) {
-                       if(hit->type != SHIP) { // they shouldn't hit the ship, but they do
-                               edot[i].active = 0;
-                               hit->dx += ENGINE_DOT_WEIGHT * edot[i].life * edot[i].dx / sprite_mass(hit);
-                               hit->dy += ENGINE_DOT_WEIGHT * edot[i].life * edot[i].dy / sprite_mass(hit);
-                               continue;
+void
+move_dot(struct dot *d, float ticks)
+{
+       Sprite *hit;
+       float mass;
+
+       if(d->active) {
+               d->x += (d->dx - screendx) * ticks;
+               d->y += (d->dy - screendy) * ticks;
+               d->mass -= ticks * d->decay;
+               if(d->mass < 0 || fclip(d->x, XSIZE) || fclip(d->y, YSIZE))
+                       d->active = 0; 
+               else {
+                       hit = pixel_collides(d->x, d->y);
+                       if(hit && hit->type != SHIP) {
+                               d->active = 0;
+                               mass = sprite_mass(hit);
+                               hit->dx += DOT_MASS_UNIT * d->mass * d->dx / mass;
+                               hit->dy += DOT_MASS_UNIT * d->mass * d->dy / mass;
                        }
                }
        }
 }
 
 void
-draw_engine_dots(SDL_Surface *s) {
+move_dots(float ticks)
+{
        int i;
-       uint16_t c;
-       uint16_t *pixels = (uint16_t *) s->pixels;
+
+       for(i=0; i<MAXBANGDOTS; i++) move_dot(&bdot[i], ticks);
+       for(i=0; i<MAXENGINEDOTS; i++) move_dot(&edot[i], ticks);
+}
+
+
+void
+draw_bang_dots(SDL_Surface *s)
+{
+       int i;
+       uint16_t *pixels, *pixel;
+       int row_inc = s->pitch/sizeof(uint16_t);
+
+       pixels = (uint16_t *) s->pixels;
+
+       for(i=0; i<MAXBANGDOTS; i++) {
+               if(!bdot[i].active) continue;
+               pixel = pixels + row_inc*(int)(bdot[i].y) + (int)(bdot[i].x);
+               *pixel = heatcolor[(int)(bdot[i].mass)*3];
+       }
+}
+
+void
+draw_engine_dots(SDL_Surface *s)
+{
+       int i;
+       uint16_t *pixels, *pixel;
        int row_inc = s->pitch/sizeof(uint16_t);
-       int heatindex;
+
+       pixels = (uint16_t *) s->pixels;
 
        for(i = 0; i<MAXENGINEDOTS; i++) {
                if(!edot[i].active) continue;
-
-               heatindex = edot[i].life * 6;
-               c = heatindex>3*W ? heatcolor[3*W-1] : heatcolor[heatindex];
-               pixels[row_inc*(int)(edot[i].y) + (int)(edot[i].x)] = c;
+               pixel = pixels + row_inc*(int)(edot[i].y) + (int)(edot[i].x);
+               *pixel = heatcolor[min(3*W-1, (int)(edot[i].mass)*6)];
        }
 }
 
@@ -722,11 +700,13 @@ gameloop() {
                        dist_ahead += (screendx - BARRIER_SPEED)*t_frame;
                        if(MAX_DIST_AHEAD >= 0) dist_ahead = min(dist_ahead, MAX_DIST_AHEAD);
 
-                       move_sprites(t_frame);  new_rocks(t_frame);
-                       move_engine_dots(t_frame); new_engine_dots(t_frame);
-                       move_bang_dots(t_frame);
+                       move_sprites(t_frame);
+                       move_dots(t_frame);
                        move_dust(t_frame);
 
+                       new_rocks(t_frame);
+                       new_engine_dots(t_frame);
+
                        collisions();
 
                        // BOUNCE off left or right edge of screen