From: Joshua Grams Date: Sat, 23 Apr 2005 13:32:37 +0000 (+0000) Subject: * config.h: added CONDERROR and NULLERROR macros. X-Git-Tag: 0.3~20 X-Git-Url: https://jasonwoof.com/gitweb/?p=vor.git;a=commitdiff_plain;h=46dacbe75dac20a1c6e1b61a2eb99ca25fc971ec * config.h: added CONDERROR and NULLERROR macros. * 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. --- diff --git a/Makefile b/Makefile index 3a087a0..7965c18 100644 --- 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) -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) diff --git a/config.h b/config.h index 16ea5fe..62ba253 100644 --- a/config.h +++ b/config.h @@ -46,4 +46,7 @@ #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 diff --git a/globals.h b/globals.h new file mode 100644 index 0000000..7eeefb3 --- /dev/null +++ b/globals.h @@ -0,0 +1,85 @@ +#ifndef VOR_GLOBALS_H +#define VOR_GLOBALS_H + +#include +#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 --- a/main.c +++ b/main.c @@ -25,6 +25,8 @@ #include "config.h" #include "file.h" +#include "globals.h" +#include "rocks.h" #include "score.h" #include "shape.h" #include "sound.h" @@ -40,44 +42,6 @@ #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 @@ -92,13 +56,10 @@ SDL_Surface *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; -struct rock_struct rock[MAXROCKS], *rockptr = rock; 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. -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; -int countdown = 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; @@ -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; - 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; @@ -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].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; @@ -324,9 +283,9 @@ draw_engine_dots(SDL_Surface *s) { for(i = 0; iYSIZE) { + 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; @@ -348,7 +307,7 @@ create_engine_dots(int newdots) { if(!tail_plume) return; if(state == GAMEPLAY) { - for(i = 0; iactive == 0) { theta = rnd()*M_PI*2; r = rnd(); @@ -431,24 +390,7 @@ void 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 @@ -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); - SDL_UnlockSurface(s); } - char a[MAX_PATH_LEN]; int init(int fullscreen) { @@ -545,13 +486,7 @@ init(int fullscreen) { init_engine_dots(); init_space_dots(); - // Load all our lovely rocks - for(i = 0; iw; - 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; iw; + 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: @@ -633,7 +569,7 @@ draw() { 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; @@ -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; - 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; @@ -710,42 +646,16 @@ draw() { } if(!gameover && state == GAMEPLAY) { - for(i=0; iw; - 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) { - movementrate = 0; + gamerate = 0; } else { - movementrate = GAMESPEED*ticks_since_last/50.0; + gamerate = GAMESPEED*ticks_since_last/50.0; if(state == GAMEPLAY) { score += ticks_since_last; } @@ -760,7 +670,6 @@ draw() { int gameloop() { - int i = 0; 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((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 @@ -817,104 +726,40 @@ gameloop() { 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; - for(i = 0; i 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) { - 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 - shipx += shipdx*movementrate; - shipy += shipdy*movementrate; + shipx += shipdx*gamerate; + shipy += shipdy*gamerate; // 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; - yscroll = yscroll*movementrate; + yscroll = yscroll*gamerate; 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 - shipx -= shipdx*movementrate; + shipx -= shipdx*gamerate; shipdx *= -0.99; } @@ -935,7 +780,7 @@ gameloop() { state = GAME_OVER; state_timeout = 200.0; fadetimer = 0.0; - faderate = movementrate; + faderate = gamerate; } else { state = DEAD_PAUSE; @@ -954,13 +799,7 @@ gameloop() { if(keystate[SDLK_SPACE] && (state == HIGH_SCORE_DISPLAY || state == TITLE_PAGE)) { - for(i = 0; i +#include +#include +#include + +#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= 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; iw; + 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 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 index 0000000..3468438 --- /dev/null +++ b/rocks.h @@ -0,0 +1,10 @@ +#include +#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 --- a/shape.c +++ b/shape.c @@ -13,6 +13,7 @@ get_shape(SDL_Surface *img, struct shape *s) 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); @@ -29,7 +30,7 @@ get_shape(SDL_Surface *img, struct shape *s) bit = 0; for(x=0; xw; 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; } } diff --git a/shape.h b/shape.h index a76951d..01a5708 100644 --- a/shape.h +++ b/shape.h @@ -1,3 +1,6 @@ +#ifndef VOR_SHAPE_H +#define VOR_SHAPE_H + #include #include @@ -5,7 +8,10 @@ struct shape { 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); + +#endif // VOR_SHAPE_H diff --git a/sound.c b/sound.c index e9008f1..d522955 100644 --- a/sound.c +++ b/sound.c @@ -3,9 +3,6 @@ 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 @@ -24,30 +21,30 @@ int audio_channels; 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[] = { - "music/magic.mod", - "music/getzznew.mod", - "music/4est_fulla3s.mod" + "music/magic.mod", + "music/getzznew.mod", + "music/4est_fulla3s.mod" }; 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; - } + } 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"); ) - // Preload all the tunes into memory - for (i=0; i