JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
* config.h: added CONDERROR and NULLERROR macros.
authorJoshua Grams <josh@qualdan.com>
Sat, 23 Apr 2005 13:32:37 +0000 (13:32 +0000)
committerJoshua Grams <josh@qualdan.com>
Sat, 23 Apr 2005 13:32:37 +0000 (13:32 +0000)
* globals.h: structure definitions and declarations of global variables.
* main.c: removed rock code to rocks.c & rocks.h.
* rocks.c rocks.h: crudely factored-out rock code.
* shape.h shape.c: added area (in pixels).
* sound.c: replaced spaces with tabs.

Makefile
config.h
globals.h [new file with mode: 0644]
main.c
rocks.c [new file with mode: 0644]
rocks.h [new file with mode: 0644]
shape.c
shape.h
sound.c

index 3a087a0..7965c18 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -19,7 +19,7 @@ debug := $(if $(DEBUG),1,0)
 ldflags := $(shell sdl-config --libs) -lSDL_image -lSDL_mixer
 cflags := $(shell sdl-config --cflags) -Wall -DDEBUG=$(debug)
 
 ldflags := $(shell sdl-config --libs) -lSDL_image -lSDL_mixer
 cflags := $(shell sdl-config --cflags) -Wall -DDEBUG=$(debug)
 
-my_objects := file.o score.o shape.o sound.o main.o $(if $(DEBUG),debug.o)
+my_objects := file.o rocks.o score.o shape.o sound.o main.o $(if $(DEBUG),debug.o)
 libs := SFont.o
 objects := $(libs) $(my_objects)
 
 libs := SFont.o
 objects := $(libs) $(my_objects)
 
index 16ea5fe..62ba253 100644 (file)
--- a/config.h
+++ b/config.h
@@ -46,4 +46,7 @@
 #define NULL 0
 #endif
 
 #define NULL 0
 #endif
 
+#define CONDERROR(a) if((a)) {initerror = strdup(SDL_GetError());return 1;}
+#define NULLERROR(a) CONDERROR((a) == NULL)
+
 #endif // VOR_CONFIG_H
 #endif // VOR_CONFIG_H
diff --git a/globals.h b/globals.h
new file mode 100644 (file)
index 0000000..7eeefb3
--- /dev/null
+++ b/globals.h
@@ -0,0 +1,85 @@
+#ifndef VOR_GLOBALS_H
+#define VOR_GLOBALS_H
+
+#include <SDL.h>
+#include "shape.h"
+#include "SFont.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
+};
+struct spacedot {
+       // Space dots are harmless background items
+       // All are active. When one falls off the edge, another is created at the start.
+       float x,y,dx;
+       Uint16 color;
+};
+
+// ************************************* VARS
+// SDL_Surface global variables
+extern SDL_Surface 
+       *surf_screen,   // Screen
+       *surf_b_variations, // "variations" banner
+       *surf_b_on, // "on" banner
+       *surf_b_rockdodger, // "rockdodger" banner
+       *surf_b_game,   // Title element "game"
+       *surf_b_over,   // Title element "over"
+       *surf_ship,             // Spaceship element
+       *surf_life,     // Indicator of number of ships remaining
+       *surf_rock[NROCKS],     // THE ROCKS
+       *surf_font_big; // The big font
+
+extern SFont_Font *g_font;
+
+extern uint32_t area;
+
+// Structure global variables
+extern struct enginedots edot[MAXENGINEDOTS], *dotptr;
+extern struct bangdots bdot[MAXBANGDOTS], *bdotptr;
+extern struct spacedot sdot[MAXSPACEDOTS];
+
+// Other global variables
+extern char topline[1024];
+extern char *initerror;
+
+extern struct shape shipshape;
+extern float shipx,shipy;      // X position, 0..XSIZE
+extern float shipdx,shipdy;    // Change in X position per tick.
+extern float gamerate;  // this controls the speed of everything that moves.
+extern float yscroll;
+extern float scrollvel;
+
+extern int nships,score,initticks,ticks_since_last, last_ticks;
+extern int gameover;
+extern int maneuver;
+extern int sound_flag, music_flag;
+extern int tail_plume; // display big engine at the back?
+extern int friction;   // should there be friction?
+extern float fadetimer, faderate;
+
+extern int pausedown, paused;
+
+// bangdot start (bd1) and end (bd2) position:
+extern int bd1, bd2;
+
+extern int bangdotlife, nbangdots;
+extern Uint16 heatcolor[W*3];
+
+extern char *data_dir;
+
+#endif // VOR_GLOBALS_H
diff --git a/main.c b/main.c
index 5341e28..0486c7e 100644 (file)
--- a/main.c
+++ b/main.c
@@ -25,6 +25,8 @@
 
 #include "config.h"
 #include "file.h"
 
 #include "config.h"
 #include "file.h"
+#include "globals.h"
+#include "rocks.h"
 #include "score.h"
 #include "shape.h"
 #include "sound.h"
 #include "score.h"
 #include "shape.h"
 #include "sound.h"
 
 #include "SFont.h"
 
 
 #include "SFont.h"
 
-#define CONDERROR(a) if((a)) {initerror = strdup(SDL_GetError());return 1;}
-#define NULLERROR(a) CONDERROR((a) == NULL)
-
-// ************************************* STRUCTS
-struct rock_struct {
-       float x,y,dx,dy;
-       int active;
-       int dead;  // has been blown out of the way
-                  // to make room for a new ship appearing.
-       SDL_Surface *image;
-       struct shape *shape;
-       int type_number;
-}; 
-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
-};
-struct spacedot {
-       // Space dots are harmless background items
-       // All are active. When one falls off the edge, another is created at the start.
-       float x,y,dx;
-       Uint16 color;
-};
-
 // ************************************* VARS
 // SDL_Surface global variables
 SDL_Surface 
 // ************************************* VARS
 // SDL_Surface global variables
 SDL_Surface 
@@ -92,13 +56,10 @@ SDL_Surface
        *surf_rock[NROCKS],     // THE ROCKS
        *surf_font_big; // The big font
 
        *surf_rock[NROCKS],     // THE ROCKS
        *surf_font_big; // The big font
 
-struct shape rock_shapes[NROCKS];
-
 SFont_Font *g_font;
 
 // Structure global variables
 struct enginedots edot[MAXENGINEDOTS], *dotptr = edot;
 SFont_Font *g_font;
 
 // Structure global variables
 struct enginedots edot[MAXENGINEDOTS], *dotptr = edot;
-struct rock_struct rock[MAXROCKS], *rockptr = rock;
 struct bangdots bdot[MAXBANGDOTS], *bdotptr = bdot;
 struct spacedot sdot[MAXSPACEDOTS];
 
 struct bangdots bdot[MAXBANGDOTS], *bdotptr = bdot;
 struct spacedot sdot[MAXSPACEDOTS];
 
@@ -109,18 +70,16 @@ char *initerror = "";
 struct shape shipshape;
 float shipx,shipy = 240.0;     // X position, 0..XSIZE
 float shipdx,shipdy;   // Change in X position per tick.
 struct shape shipshape;
 float shipx,shipy = 240.0;     // X position, 0..XSIZE
 float shipdx,shipdy;   // Change in X position per tick.
-float rockrate,rockspeed;
-float movementrate;  // this controls the speed of everything that moves.
+float gamerate;  // this controls the speed of everything that moves.
 float yscroll;
 float scrollvel;
 
 int nships,score,initticks,ticks_since_last, last_ticks;
 int gameover;
 float yscroll;
 float scrollvel;
 
 int nships,score,initticks,ticks_since_last, last_ticks;
 int gameover;
-int countdown = 0;
 int maneuver = 0;
 int maneuver = 0;
-int sound_flag = 1, music_flag = 0;
-int tail_plume = 0; // display big engine at the back?
-int friction = 0;      // should there be friction?
+int sound_flag, music_flag;
+int tail_plume; // display big engine at the back?
+int friction;  // should there be friction?
 float fadetimer = 0, faderate;
 
 int pausedown = 0, paused = 0;
 float fadetimer = 0, faderate;
 
 int pausedown = 0, paused = 0;
@@ -272,8 +231,8 @@ draw_bang_dots(SDL_Surface *s) {
                        //last_i = i + 1;
                        rawpixel[(int)(s->pitch/2*(int)(bdot[i].y)) + (int)(bdot[i].x)] = bdot[i].c ? bdot[i].c : heatcolor[(int)(bdot[i].life*3)];
                        bdot[i].life -= bdot[i].decay;
                        //last_i = i + 1;
                        rawpixel[(int)(s->pitch/2*(int)(bdot[i].y)) + (int)(bdot[i].x)] = bdot[i].c ? bdot[i].c : heatcolor[(int)(bdot[i].life*3)];
                        bdot[i].life -= bdot[i].decay;
-                       bdot[i].x += bdot[i].dx*movementrate;
-                       bdot[i].y += bdot[i].dy*movementrate + yscroll;
+                       bdot[i].x += bdot[i].dx*gamerate;
+                       bdot[i].y += bdot[i].dy*gamerate + yscroll;
 
                        if(bdot[i].life<0)
                        bdot[i].active = 0;
 
                        if(bdot[i].life<0)
                        bdot[i].active = 0;
@@ -303,7 +262,7 @@ draw_space_dots(SDL_Surface *s) {
                        sdot[i].y = 0;
                }
                rawpixel[(int)(s->pitch/2*(int)sdot[i].y) + (int)(sdot[i].x)] = sdot[i].color;
                        sdot[i].y = 0;
                }
                rawpixel[(int)(s->pitch/2*(int)sdot[i].y) + (int)(sdot[i].x)] = sdot[i].color;
-               sdot[i].x += sdot[i].dx*movementrate;
+               sdot[i].x += sdot[i].dx*gamerate;
                sdot[i].y += yscroll;
                if(sdot[i].y > YSIZE) {
                        sdot[i].y -= YSIZE;
                sdot[i].y += yscroll;
                if(sdot[i].y > YSIZE) {
                        sdot[i].y -= YSIZE;
@@ -324,9 +283,9 @@ draw_engine_dots(SDL_Surface *s) {
 
        for(i = 0; i<MAXENGINEDOTS; i++) {
                if(edot[i].active) {
 
        for(i = 0; i<MAXENGINEDOTS; i++) {
                if(edot[i].active) {
-                       edot[i].x += edot[i].dx*movementrate;
-                       edot[i].y += edot[i].dy*movementrate + yscroll;
-                       if((edot[i].life -= movementrate*3)<0 || edot[i].y<0 || edot[i].y>YSIZE) {
+                       edot[i].x += edot[i].dx*gamerate;
+                       edot[i].y += edot[i].dy*gamerate + yscroll;
+                       if((edot[i].life -= gamerate*3)<0 || edot[i].y<0 || edot[i].y>YSIZE) {
                                edot[i].active = 0;
                        } else if(edot[i].x<0 || edot[i].x>XSIZE) {
                                edot[i].active = 0;
                                edot[i].active = 0;
                        } else if(edot[i].x<0 || edot[i].x>XSIZE) {
                                edot[i].active = 0;
@@ -348,7 +307,7 @@ create_engine_dots(int newdots) {
        if(!tail_plume) return;
 
        if(state == GAMEPLAY) {
        if(!tail_plume) return;
 
        if(state == GAMEPLAY) {
-               for(i = 0; i<newdots*movementrate; i++) {
+               for(i = 0; i<newdots*gamerate; i++) {
                        if(dotptr->active == 0) {
                                theta = rnd()*M_PI*2;
                                r = rnd();
                        if(dotptr->active == 0) {
                                theta = rnd()*M_PI*2;
                                r = rnd();
@@ -431,24 +390,7 @@ void
 drawdots(SDL_Surface *s) {
        int m;
 
 drawdots(SDL_Surface *s) {
        int m;
 
-       SDL_LockSurface(s);
-       // Draw the background stars aka space dots
-       draw_space_dots(s);
-
-       // Draw the score when playing the game or whn the game is freshly over
-       if(1 || state == GAMEPLAY || state == DEAD_PAUSE || state == GAME_OVER ) {
-               SDL_UnlockSurface(s);
-
-               snprintscore_line(topline, 50, score);
-               SFont_Write(s,g_font,XSIZE-250,0,topline);
-
-               SDL_LockSurface(s);
-       }
-
-       // Draw all the engine dots
-       draw_engine_dots(s);
-
-       // Create more engine dots comin out da back
+       // Create more engine dots comin' out da back
        if(!gameover) create_engine_dots(200);
 
        // Create engine dots out the side we're moving from
        if(!gameover) create_engine_dots(200);
 
        // Create engine dots out the side we're moving from
@@ -458,14 +400,13 @@ drawdots(SDL_Surface *s) {
                }
        }
 
                }
        }
 
-       // Draw all outstanding bang dots
-       //if(bangdotlife-- > 0) 
+       SDL_LockSurface(s);
+       draw_space_dots(s);
+       draw_engine_dots(s);
        draw_bang_dots(s);
        draw_bang_dots(s);
-
        SDL_UnlockSurface(s);
 }
 
        SDL_UnlockSurface(s);
 }
 
-               char a[MAX_PATH_LEN];
 int
 init(int fullscreen) {
 
 int
 init(int fullscreen) {
 
@@ -545,13 +486,7 @@ init(int fullscreen) {
        init_engine_dots();
        init_space_dots();
 
        init_engine_dots();
        init_space_dots();
 
-       // Load all our lovely rocks
-       for(i = 0; i<NROCKS; i++) {
-               snprintf(a,MAX_PATH_LEN,add_path("sprites/rock%02d.png"),i);
-               NULLERROR(temp = IMG_Load(a));
-               NULLERROR(surf_rock[i] = SDL_DisplayFormat(temp));
-               get_shape(surf_rock[i], &rock_shapes[i]);
-       }
+       init_rocks();
 
        // Remove the mouse cursor
 #ifdef SDL_DISABLE
 
        // Remove the mouse cursor
 #ifdef SDL_DISABLE
@@ -593,23 +528,24 @@ draw() {
                SDL_BlitSurface(surf_ship,&src,surf_screen,&dest);
        }
 
                SDL_BlitSurface(surf_ship,&src,surf_screen,&dest);
        }
 
-       // Draw all the rocks, in all states
-       for(i = 0; i<MAXROCKS; i++) {
-               if(rock[i].active) {
-
-                       src.w = rock[i].image->w;
-                       src.h = rock[i].image->h;
-                       dest.w = src.w;
-                       dest.h = src.h;
-                       dest.x = (int) rock[i].x;
-                       dest.y = (int) rock[i].y;
-
-                       // Draw the rock
-                       SDL_BlitSurface(rock[i].image,&src,surf_screen,&dest);
+       draw_rocks();
 
 
-               }
+       // Draw the life indicators.
+       if(state == GAMEPLAY || state == DEAD_PAUSE || state == GAME_OVER)
+       for(i = 0; i<nships-1; i++) {
+               src.w = surf_life->w;
+               src.h = surf_life->h;
+               dest.w = src.w;
+               dest.h = src.h;
+               dest.x = (i + 1)*(src.w + 10);
+               dest.y = 20;
+               SDL_BlitSurface(surf_life, &src, surf_screen, &dest);
        }
 
        }
 
+       // Draw the score
+       snprintscore_line(topline, 50, score);
+       SFont_Write(surf_screen, g_font, XSIZE-250, 0, topline);
+
        // If it's game over, show the game over graphic in the dead centre
        switch (state) {
                case GAME_OVER:
        // If it's game over, show the game over graphic in the dead centre
        switch (state) {
                case GAME_OVER:
@@ -633,7 +569,7 @@ draw() {
                        dest.h = src.h;
                        dest.x = (XSIZE-src.w)/2;
                        dest.y = (YSIZE-src.h)/2-40;
                        dest.h = src.h;
                        dest.x = (XSIZE-src.w)/2;
                        dest.y = (YSIZE-src.h)/2-40;
-                       SDL_SetAlpha(surf_b_game, SDL_SRCALPHA, (int)(fadegame*(200 + 55*cos(fadetimer += movementrate/1.0))));
+                       SDL_SetAlpha(surf_b_game, SDL_SRCALPHA, (int)(fadegame*(200 + 55*cos(fadetimer += gamerate/1.0))));
                        SDL_BlitSurface(surf_b_game,&src,surf_screen,&dest);
 
                        src.w = surf_b_over->w;
                        SDL_BlitSurface(surf_b_game,&src,surf_screen,&dest);
 
                        src.w = surf_b_over->w;
@@ -654,7 +590,7 @@ draw() {
                        dest.h = src.h;
                        dest.x = (XSIZE-src.w)/2 + cos(fadetimer/6.5)*10;
                        dest.y = (YSIZE/2-src.h)/2 + sin(fadetimer/5.0)*10;
                        dest.h = src.h;
                        dest.x = (XSIZE-src.w)/2 + cos(fadetimer/6.5)*10;
                        dest.y = (YSIZE/2-src.h)/2 + sin(fadetimer/5.0)*10;
-                       SDL_SetAlpha(surf_b_variations, SDL_SRCALPHA, (int)(200 + 55*sin(fadetimer += movementrate/2.0)));
+                       SDL_SetAlpha(surf_b_variations, SDL_SRCALPHA, (int)(200 + 55*sin(fadetimer += gamerate/2.0)));
                        SDL_BlitSurface(surf_b_variations,&src,surf_screen,&dest);
 
                        src.w = surf_b_on->w;
                        SDL_BlitSurface(surf_b_variations,&src,surf_screen,&dest);
 
                        src.w = surf_b_on->w;
@@ -710,42 +646,16 @@ draw() {
        }
 
        if(!gameover && state == GAMEPLAY) {
        }
 
        if(!gameover && state == GAMEPLAY) {
-               for(i=0; i<MAXROCKS; i++) {
-                       if(rock[i].active) {
-                               if(collide(shipx-rock[i].x, shipy-rock[i].y, rock[i].shape, &shipshape)) 
-                                       bang = 1;
-                       }
-               }
+               bang = hit_rocks(shipx, shipy, &shipshape);
        }
 
        }
 
-       // Draw all the little ships
-       if(state == GAMEPLAY || state == DEAD_PAUSE || state == GAME_OVER)
-       for(i = 0; i<nships-1; i++) {
-               src.w = surf_life->w;
-               src.h = surf_life->h;
-               dest.w = src.w;
-               dest.h = src.h;
-               dest.x = (i + 1)*(src.w + 10);
-               dest.y = 20;
-               SDL_BlitSurface(surf_life,&src,surf_screen,&dest);
-       }
-
-
-       // Update the score
-       /*
-       n = SDL_GetTicks()-initticks;
-       if(score)
-       ticks_since_last = n-score;
-       score = n;
-       */
-
        ticks_since_last = SDL_GetTicks()-last_ticks;
        last_ticks = SDL_GetTicks();
        if(ticks_since_last>200 || ticks_since_last<0) {
        ticks_since_last = SDL_GetTicks()-last_ticks;
        last_ticks = SDL_GetTicks();
        if(ticks_since_last>200 || ticks_since_last<0) {
-               movementrate = 0;
+               gamerate = 0;
        }
        else {
        }
        else {
-               movementrate = GAMESPEED*ticks_since_last/50.0;
+               gamerate = GAMESPEED*ticks_since_last/50.0;
                if(state == GAMEPLAY) {
                        score += ticks_since_last;
                }
                if(state == GAMEPLAY) {
                        score += ticks_since_last;
                }
@@ -760,7 +670,6 @@ draw() {
 
 int
 gameloop() {
 
 int
 gameloop() {
-       int i = 0;
        Uint8 *keystate;
 
 
        Uint8 *keystate;
 
 
@@ -768,7 +677,7 @@ gameloop() {
                if(!paused) {
                        // Count down the game loop timer, and change state when it gets to zero or less;
 
                if(!paused) {
                        // Count down the game loop timer, and change state when it gets to zero or less;
 
-                       if((state_timeout -= movementrate*3) < 0) {
+                       if((state_timeout -= gamerate*3) < 0) {
                                switch(state) {
                                        case DEAD_PAUSE:
                                                // Create a new ship and start all over again
                                switch(state) {
                                        case DEAD_PAUSE:
                                                // Create a new ship and start all over again
@@ -817,104 +726,40 @@ gameloop() {
                                                blast_radius = BLAST_RADIUS * (DEAD_PAUSE_LENGTH - state_timeout) / 20.0;
                                                fixonly = 0;
                                        }
                                                blast_radius = BLAST_RADIUS * (DEAD_PAUSE_LENGTH - state_timeout) / 20.0;
                                                fixonly = 0;
                                        }
+                                       blast_rocks(shipx, shipy, blast_radius, fixonly);
 
                                        if(shipx < 60) shipx = 60;
 
                                        if(shipx < 60) shipx = 60;
-                                       for(i = 0; i<MAXROCKS; i++ ) {
-                                               float dx, dy, n;
-                                               if(rock[i].x <= 0) continue;
-
-                                               // This makes it so your explosion from dying magically doesn't leave
-                                               // any rocks that aren't moving much on the x axis. After the first
-                                               // 20 tics, only rocks that are barely moving will be pushed.
-                                               if(fixonly && (!rock[i].dead || rock[i].dx < -4 || rock[i].dx > 3)) {
-                                                       continue;
-                                               }
-
-                                               dx = rock[i].x - shipx;
-                                               dy = rock[i].y - shipy;
-
-                                               n = sqrt(dx*dx + dy*dy);
-                                               if(n < blast_radius) {
-                                                       n *= 20;
-                                                       rock[i].dx += rockrate*(dx+30)/n;
-                                                       rock[i].dy += rockrate*dy/n;
-                                                       rock[i].dead = 1;
-                                               }
-                                       }
                                }
                        }
 
                                }
                        }
 
-                       if(--countdown <= 0 && (rnd()*100.0<(rockrate += 0.025))) {
-                               // Create a rock
-                               rockptr++;
-                               if(rockptr-rock >= MAXROCKS) {
-                                       rockptr = rock;
-                               }
-                               if(!rockptr->active) {
-                                       rockptr->x = (float)XSIZE;
-                                       rockptr->dx = -(rockspeed)*(1 + rnd());
-                                       rockptr->dy = rnd()-0.5;
-                                       rockptr->type_number = random() % NROCKS;
-                                       rockptr->image = surf_rock[rockptr->type_number];// [random()%NROCKS];
-                                       rockptr->shape = &rock_shapes[rockptr->type_number];
-                                       rockptr->active = 1;
-                                       rockptr->y = rnd()*(YSIZE + rockptr->image->h);
-                               }
-                               if(movementrate>0.1) {
-                                       countdown = (int)(ROCKRATE/movementrate);
-                               } else {
-                                       countdown = 0;
-                               }
-                       }
+                       new_rocks();
 
                        // FRICTION?
                        if(friction) {
 
                        // FRICTION?
                        if(friction) {
-                               shipdx *= pow((double)0.9,(double)movementrate);
-                               shipdy *= pow((double)0.9,(double)movementrate);
-                               // if(abs(shipdx)<0.00001) shipdx = 0;
-                               // if(abs(shipdy)<0.00001) shipdy = 0;
+                               shipdx *= pow((double)0.9,(double)gamerate);
+                               shipdy *= pow((double)0.9,(double)gamerate);
                        }
 
                        // INERTIA
                        }
 
                        // INERTIA
-                       shipx += shipdx*movementrate;
-                       shipy += shipdy*movementrate;
+                       shipx += shipdx*gamerate;
+                       shipy += shipdy*gamerate;
 
                        // SCROLLING
                        yscroll = shipy - (YSIZE / 2);
                        yscroll += shipdy * 25;
                        yscroll /= -25;
 
                        // SCROLLING
                        yscroll = shipy - (YSIZE / 2);
                        yscroll += shipdy * 25;
                        yscroll /= -25;
-                       yscroll = ((scrollvel * (12 - movementrate)) + (yscroll * movementrate)) / 12;
+                       yscroll = ((scrollvel * (12 - gamerate)) + (yscroll * gamerate)) / 12;
                        scrollvel = yscroll;
                        scrollvel = yscroll;
-                       yscroll = yscroll*movementrate;
+                       yscroll = yscroll*gamerate;
                        shipy += yscroll;
                        
                        shipy += yscroll;
                        
-                       // Move all the rocks
-                       for(i = 0; i < MAXROCKS; i++) {
-                               if(rock[i].active) {
-                                       rock[i].x += rock[i].dx*movementrate;
-                                       rock[i].y += rock[i].dy*movementrate + yscroll;
-                                       if(rock[i].y > YSIZE || rock[i].y < -rock[i].image->h) {
-                                               if(rock[i].dead) {
-                                                       rock[i].dead = 0;
-                                                       rock[i].active = 0;
-                                               } else {
-                                                       // wrap
-                                                       rock[i].y = (YSIZE - rock[i].image->h) - rock[i].y;
-                                                       rock[i].y += (rock[i].dy*movementrate + yscroll) * 1.01;
-                                               }
-                                       }
-                                       if(rock[i].x < -rock[i].image->w || rock[i].x > XSIZE) {
-                                               rock[i].active = 0;
-                                               rock[i].dead = 0;
-                                       }
-                               }
-                       }
+                       move_rocks();
 
 
                        // BOUNCE X
                        if(shipx<0 || shipx>XSIZE-surf_ship->w) {
                                // BOUNCE from left and right wall
 
 
                        // BOUNCE X
                        if(shipx<0 || shipx>XSIZE-surf_ship->w) {
                                // BOUNCE from left and right wall
-                               shipx -= shipdx*movementrate;
+                               shipx -= shipdx*gamerate;
                                shipdx *= -0.99;
                        }
 
                                shipdx *= -0.99;
                        }
 
@@ -935,7 +780,7 @@ gameloop() {
                                        state = GAME_OVER;
                                        state_timeout = 200.0;
                                        fadetimer = 0.0;
                                        state = GAME_OVER;
                                        state_timeout = 200.0;
                                        fadetimer = 0.0;
-                                       faderate = movementrate;
+                                       faderate = gamerate;
                                }
                                else {
                                        state = DEAD_PAUSE;
                                }
                                else {
                                        state = DEAD_PAUSE;
@@ -954,13 +799,7 @@ gameloop() {
 
                        if(keystate[SDLK_SPACE] && (state == HIGH_SCORE_DISPLAY || state == TITLE_PAGE)) {
 
 
                        if(keystate[SDLK_SPACE] && (state == HIGH_SCORE_DISPLAY || state == TITLE_PAGE)) {
 
-                               for(i = 0; i<MAXROCKS; i++ ) {
-                                       rock[i].active = 0;
-                                       rock[i].dead = 0;
-                               }
-
-                               rockrate = 54.0;
-                               rockspeed = 5.0;
+                               reset_rocks();
 
                                nships = 4;
                                score = 0;
 
                                nships = 4;
                                score = 0;
@@ -985,10 +824,10 @@ gameloop() {
                        if(!gameover) {
 
                                if(!paused) {
                        if(!gameover) {
 
                                if(!paused) {
-                                       if(keystate[SDLK_UP] | keystate[SDLK_c])                { shipdy -= 1.5*movementrate; maneuver |= 1<<3;}
-                                       if(keystate[SDLK_DOWN] | keystate[SDLK_t])              { shipdy += 1.5*movementrate; maneuver |= 1<<1;}
-                                       if(keystate[SDLK_LEFT] | keystate[SDLK_h])              { shipdx -= 1.5*movementrate; maneuver |= 1<<2;}
-                                       if(keystate[SDLK_RIGHT] | keystate[SDLK_n])             { shipdx += 1.5*movementrate; maneuver |= 1;}
+                                       if(keystate[SDLK_UP] | keystate[SDLK_c])                { shipdy -= 1.5*gamerate; maneuver |= 1<<3;}
+                                       if(keystate[SDLK_DOWN] | keystate[SDLK_t])              { shipdy += 1.5*gamerate; maneuver |= 1<<1;}
+                                       if(keystate[SDLK_LEFT] | keystate[SDLK_h])              { shipdx -= 1.5*gamerate; maneuver |= 1<<2;}
+                                       if(keystate[SDLK_RIGHT] | keystate[SDLK_n])             { shipdx += 1.5*gamerate; maneuver |= 1;}
                                        if(keystate[SDLK_3])            { SDL_SaveBMP(surf_screen, "snapshot.bmp"); }
                                }
 
                                        if(keystate[SDLK_3])            { SDL_SaveBMP(surf_screen, "snapshot.bmp"); }
                                }
 
@@ -1016,7 +855,7 @@ gameloop() {
 
 int
 main(int argc, char **argv) {
 
 int
 main(int argc, char **argv) {
-       int i, x, fullscreen;
+       int x, fullscreen;
 
        fullscreen = 0;
        tail_plume = 0;
 
        fullscreen = 0;
        tail_plume = 0;
@@ -1059,12 +898,7 @@ main(int argc, char **argv) {
                return 1;
        }
 
                return 1;
        }
 
-       for(i = 0; i<MAXROCKS; i++) {
-               rock[i].active = 0;
-               rock[i].dead = 0;
-       }
-       rockrate = 54.0;
-       rockspeed = 5.0;
+       reset_rocks();
        initticks = SDL_GetTicks();
        gameloop();
 
        initticks = SDL_GetTicks();
        gameloop();
 
diff --git a/rocks.c b/rocks.c
new file mode 100644 (file)
index 0000000..fe66c4c
--- /dev/null
+++ b/rocks.c
@@ -0,0 +1,191 @@
+#include <SDL_image.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "config.h"
+#include "file.h"
+#include "globals.h"
+#include "rocks.h"
+#include "shape.h"
+
+struct rock_struct {
+       float x,y,dx,dy;
+       int active;
+       int dead;  // has been blown out of the way
+                  // to make room for a new ship appearing.
+       SDL_Surface *image;
+       struct shape *shape;
+       int type_number;
+}; 
+
+struct rock_struct rock[MAXROCKS], *rockptr = rock;
+
+float rockrate,rockspeed;
+
+SDL_Surface *surf_rock[NROCKS];
+struct shape rock_shapes[NROCKS];
+
+int countdown = 0;
+
+float rnd(void);
+
+uint32_t area;
+
+int
+init_rocks(void)
+{
+       int i;
+       char a[MAX_PATH_LEN];
+       SDL_Surface *temp;
+
+       area = 0;
+
+       for(i = 0; i<NROCKS; i++) {
+               snprintf(a,MAX_PATH_LEN,add_path("sprites/rock%02d.png"),i);
+               NULLERROR(temp = IMG_Load(a));
+               NULLERROR(surf_rock[i] = SDL_DisplayFormat(temp));
+               get_shape(surf_rock[i], &rock_shapes[i]);
+       }
+       return 0;
+}
+
+void
+new_rocks(void)
+{
+       if(--countdown <= 0 && (rnd()*100.0<(rockrate += 0.025))) {
+               // Possibly create a rock
+               rockptr++;
+               if(rockptr-rock >= MAXROCKS) {
+                       rockptr = rock;
+               }
+               if(!rockptr->active) {
+                       rockptr->dx = -(rockspeed)*(1 + rnd());
+                       rockptr->dy = rnd()-0.5;
+                       rockptr->type_number = random() % NROCKS;
+                       rockptr->image = surf_rock[rockptr->type_number];
+                       rockptr->shape = &rock_shapes[rockptr->type_number];
+                       rockptr->x = (float)XSIZE;
+                       rockptr->y = rnd()*(YSIZE + rockptr->image->h);
+                       rockptr->active = 1;
+                       area += rockptr->shape->area;
+               }
+               if(gamerate>0.1) {
+                       countdown = (int)(ROCKRATE/gamerate);
+               } else {
+                       countdown = 0;
+               }
+       }
+}
+
+void
+move_rocks(void)
+{
+       int i;
+
+       // Move all the rocks
+       for(i = 0; i < MAXROCKS; i++) {
+               if(rock[i].active) {
+                       rock[i].x += rock[i].dx*gamerate;
+                       rock[i].y += rock[i].dy*gamerate + yscroll;
+                       if(rock[i].y > YSIZE || rock[i].y < -rock[i].image->h) {
+                               if(rock[i].dead) {
+                                       area -= rock[i].shape->area;
+                                       rock[i].dead = 0;
+                                       rock[i].active = 0;
+                               } else {
+                                       // wrap
+                                       rock[i].y = (YSIZE - rock[i].image->h) - rock[i].y;
+                                       rock[i].y += (rock[i].dy*gamerate + yscroll) * 1.01;
+                               }
+                       }
+                       if(rock[i].x < -rock[i].image->w || rock[i].x > XSIZE) {
+                               area -= rock[i].shape->area;
+                               rock[i].active = 0;
+                               rock[i].dead = 0;
+                       }
+               }
+       }
+}
+
+void
+reset_rocks(void)
+{
+       int i;
+
+       area = 0;
+       for(i = 0; i<MAXROCKS; i++ ) {
+               rock[i].active = 0;
+               rock[i].dead = 0;
+       }
+
+       rockrate = 54.0;
+       rockspeed = 5.0;
+}
+
+void
+draw_rocks(void)
+{
+       int i;
+       SDL_Rect src, dest;
+
+       src.x = 0; src.y = 0;
+
+       for(i = 0; i<MAXROCKS; i++) {
+               if(rock[i].active) {
+                       src.w = rock[i].image->w;
+                       src.h = rock[i].image->h;
+
+                       dest.w = src.w;
+                       dest.h = src.h;
+                       dest.x = (int) rock[i].x;
+                       dest.y = (int) rock[i].y;
+
+                       SDL_BlitSurface(rock[i].image,&src,surf_screen,&dest);
+
+               }
+       }
+}
+
+int
+hit_rocks(float x, float y, struct shape *shape)
+{
+       int i;
+
+       for(i=0; i<MAXROCKS; i++) {
+               if(rock[i].active) {
+                       if(collide(x-rock[i].x, y-rock[i].y, rock[i].shape, shape)) 
+                               return 1;
+               }
+       }
+       return 0;
+}
+
+void
+blast_rocks(float x, float y, float radius, int onlyslow)
+{
+       int i;
+       float dx, dy, n;
+
+       for(i = 0; i<MAXROCKS; i++ ) {
+               if(rock[i].x <= 0) continue;
+
+               // This makes it so your explosion from dying magically doesn't leave
+               // any rocks that aren't moving much on the x axis. If onlyslow is set,
+               // only rocks that are barely moving will be pushed.
+               if(onlyslow && (!rock[i].dead || rock[i].dx < -4 || rock[i].dx > 3)) {
+                       continue;
+               }
+
+               dx = rock[i].x - x;
+               dy = rock[i].y - y;
+
+               n = sqrt(dx*dx + dy*dy);
+               if(n < radius) {
+                       n *= 20;
+                       rock[i].dx += rockrate*(dx+30)/n;
+                       rock[i].dy += rockrate*dy/n;
+                       rock[i].dead = 1;
+               }
+       }
+}
diff --git a/rocks.h b/rocks.h
new file mode 100644 (file)
index 0000000..3468438
--- /dev/null
+++ b/rocks.h
@@ -0,0 +1,10 @@
+#include <SDL.h>
+#include "shape.h"
+
+int init_rocks(void);
+void new_rocks(void);
+void reset_rocks(void);
+void move_rocks(void);
+void draw_rocks(void);
+int hit_rocks(float x, float y, struct shape *shape);
+void blast_rocks(float x, float y, float radius, int onlyslow);
diff --git a/shape.c b/shape.c
index 867610e..9e03f19 100644 (file)
--- a/shape.c
+++ b/shape.c
@@ -13,6 +13,7 @@ get_shape(SDL_Surface *img, struct shape *s)
                exit(1);
        }
 
                exit(1);
        }
 
+       s->area = 0;
        s->w = img->w; s->h = img->h;
        s->mw = ((img->w+31)>>5);
        s->mask = malloc(4*s->mw*s->h);
        s->w = img->w; s->h = img->h;
        s->mw = ((img->w+31)>>5);
        s->mask = malloc(4*s->mw*s->h);
@@ -29,7 +30,7 @@ get_shape(SDL_Surface *img, struct shape *s)
                bit = 0;
                for(x=0; x<img->w; x++) {
                        if(!bit) { bits = 0; bit = 0x80000000; }
                bit = 0;
                for(x=0; x<img->w; x++) {
                        if(!bit) { bits = 0; bit = 0x80000000; }
-                       if(*px++ != transp) bits |= bit;
+                       if(*px++ != transp) { bits |= bit; s->area++; }
                        bit >>= 1;
                        if(!bit || x == img->w - 1) { *(p++) = bits; }
                }
                        bit >>= 1;
                        if(!bit || x == img->w - 1) { *(p++) = bits; }
                }
diff --git a/shape.h b/shape.h
index a76951d..01a5708 100644 (file)
--- a/shape.h
+++ b/shape.h
@@ -1,3 +1,6 @@
+#ifndef VOR_SHAPE_H
+#define VOR_SHAPE_H
+
 #include <SDL/SDL.h>
 #include <stdint.h>
 
 #include <SDL/SDL.h>
 #include <stdint.h>
 
@@ -5,7 +8,10 @@ struct shape {
        int w, h;
        int mw;
        uint32_t *mask;
        int w, h;
        int mw;
        uint32_t *mask;
+       uint32_t area;
 };
 
 void get_shape(SDL_Surface *img, struct shape *s);
 int collide(int xdiff, int ydiff, struct shape *r, struct shape *s);
 };
 
 void get_shape(SDL_Surface *img, struct shape *s);
 int collide(int xdiff, int ydiff, struct shape *r, struct shape *s);
+
+#endif // VOR_SHAPE_H
diff --git a/sound.c b/sound.c
index e9008f1..d522955 100644 (file)
--- a/sound.c
+++ b/sound.c
@@ -3,9 +3,6 @@
 
 extern int sound_flag, music_flag;
 
 
 extern int sound_flag, music_flag;
 
-#define CONDERROR(a) if ((a)) {fprintf(stderr,"Error: %s\n",SDL_GetError());exit(1);}
-#define NULLERROR(a) CONDERROR((a)==NULL)
-
 #define TUNE_TITLE_PAGE                0
 #define TUNE_GAMEPLAY          1
 #define TUNE_HIGH_SCORE_ENTRY  2
 #define TUNE_TITLE_PAGE                0
 #define TUNE_GAMEPLAY          1
 #define TUNE_HIGH_SCORE_ENTRY  2
@@ -24,30 +21,30 @@ int audio_channels;
 
 char *add_path(char *);
 char *wav_file[] = {
 
 char *add_path(char *);
 char *wav_file[] = {
-    "sounds/booom.wav",
+       "sounds/booom.wav",
        "sounds/cboom.wav",
        "sounds/boom.wav",
        "sounds/bzboom.wav"
 };
 
 char *tune_file[] = {
        "sounds/cboom.wav",
        "sounds/boom.wav",
        "sounds/bzboom.wav"
 };
 
 char *tune_file[] = {
-    "music/magic.mod",
-    "music/getzznew.mod",
-    "music/4est_fulla3s.mod"
+       "music/magic.mod",
+       "music/getzznew.mod",
+       "music/4est_fulla3s.mod"
 };
 
 int
 init_sound() {
 };
 
 int
 init_sound() {
-    // Return 1 if the sound is ready to roll, and 0 if not.
+       // Return 1 if the sound is ready to roll, and 0 if not.
 
 
-    int i;
-    debug(printf ("Initialise sound\n"));
+       int i;
+       debug(printf ("Initialise sound\n"));
 
 
-    // Initialise output with SDL_mixer
-    if (Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, AUDIO_S16, MIX_DEFAULT_CHANNELS, 4096) < 0) {
+       // Initialise output with SDL_mixer
+       if (Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, AUDIO_S16, MIX_DEFAULT_CHANNELS, 4096) < 0) {
        fprintf(stderr, "Couldn't open SDL_mixer audio: %s\n", SDL_GetError());
        return 0;
        fprintf(stderr, "Couldn't open SDL_mixer audio: %s\n", SDL_GetError());
        return 0;
-    }
+       }
 
        debug(
                        // What kind of sound did we get?  Ah who cares. As long as it can play
 
        debug(
                        // What kind of sound did we get?  Ah who cares. As long as it can play
@@ -58,26 +55,26 @@ init_sound() {
                                (audio_channels > 1) ? "stereo" : "mono");
                        ) 
 
                                (audio_channels > 1) ? "stereo" : "mono");
                        ) 
 
-    // Preload all the tunes into memory
-    for (i=0; i<NUM_TUNES; i++) {
-       if (!(music[i] = Mix_LoadMUS(add_path(tune_file[i])))) {
-           printf ("Failed to load %s\n",add_path(tune_file[i]));
+       // Preload all the tunes into memory
+       for (i=0; i<NUM_TUNES; i++) {
+               if (!(music[i] = Mix_LoadMUS(add_path(tune_file[i])))) {
+                       printf ("Failed to load %s\n",add_path(tune_file[i]));
+               }
        }
        }
-    }
 
 
-    // Preload all the wav files into memory
-    for (i=0; i<NUM_SOUNDS; i++) {
-       wav[i] = Mix_LoadWAV(add_path(wav_file[i]));
-    }
+       // Preload all the wav files into memory
+       for (i=0; i<NUM_SOUNDS; i++) {
+               wav[i] = Mix_LoadWAV(add_path(wav_file[i]));
+       }
 
 
-    return 1;
+       return 1;
 }
 
 void
 play_sound(int i)  {
        if(!sound_flag) return;
 }
 
 void
 play_sound(int i)  {
        if(!sound_flag) return;
-    debug(printf ("play sound %d on first free channel\n",i));
-    Mix_PlayChannel(-1, wav[i], 0);
+       debug(printf ("play sound %d on first free channel\n",i));
+       Mix_PlayChannel(-1, wav[i], 0);
 }/*}}}*/
 
 int playing=-1;
 }/*}}}*/
 
 int playing=-1;
@@ -85,21 +82,21 @@ int playing=-1;
 
 void
 play_tune(int i) {/*{{{*/
 
 void
 play_tune(int i) {/*{{{*/
-       if(!sound_flag || !music_flag) return;
-    if (playing==i)
+       if(!music_flag) return;
+       if (playing==i)
        return;
        return;
-    if (playing) {
-       Mix_FadeOutMusic(1500);
-       debug(printf("Stop playing %d\n",playing));
-    }
+       if (playing) {
+               Mix_FadeOutMusic(1500);
+               debug(printf("Stop playing %d\n",playing));
+       }
        debug(
                        printf ("Play music %d\n",i);
                        printf ("volume %d\n",music_volume[i]);
                        )
        debug(
                        printf ("Play music %d\n",i);
                        printf ("volume %d\n",music_volume[i]);
                        )
-    Mix_FadeInMusic(music[i],-1,2000);
-    Mix_VolumeMusic(music_volume[i]);
+       Mix_FadeInMusic(music[i],-1,2000);
+       Mix_VolumeMusic(music_volume[i]);
 
 
-    playing = i;
+       playing = i;
 }
 
 /*
 }
 
 /*