X-Git-Url: https://jasonwoof.com/gitweb/?p=vor.git;a=blobdiff_plain;f=main.c;h=e3a0f8351da7158bb9e2fa5a7ae400a4288f6144;hp=94c8e9ab4df5fe834862616c16ac930903657e5e;hb=a726e74233c877dab3aca50e5b31e7652035ae30;hpb=038a8a4aaa54b7b60e7fbb6a0f988dd852fb8970 diff --git a/main.c b/main.c index 94c8e9a..e3a0f83 100644 --- a/main.c +++ b/main.c @@ -19,7 +19,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include #include #include #include @@ -42,6 +41,10 @@ #include "sprite.h" #include "sound.h" +#ifdef WIN32 +#define SDL_SetAlpha(surf, flag, alpha) +#endif + // ************************************* VARS // SDL_Surface global variables SDL_Surface @@ -72,7 +75,7 @@ float screendx = SCREENDXMIN, screendy = 0.0; float back_dist; // all movement is based on t_frame. -float t_frame; // length of this frame (in ticks = 1/20th second) +float t_frame; // length of this frame (in ticks = 1/20th second) adjusted for gamespeed int ms_frame; // length of this frame (milliseconds) int ms_end; // end of this frame (milliseconds) @@ -100,10 +103,17 @@ enum states state = TITLE_PAGE; float state_timeout = 600.0; #define NSEQUENCE 3 -char *sequence[] = { - "Press SPACE for normal game", - "Or 'e' for easy game", - "http://jasonwoof.org/vor" +char *msgs[2][3] = { + { + "Press SPACE for normal game", + "Press '1' for easy game", + "http://jasonwoof.org/vor" + }, + { + "Press SPACE for easy game", + "Press '2' for normal game", + "http://jasonwoof.org/vor" + } }; int bangdotlife, nbangdots; @@ -128,22 +138,20 @@ init_engine_dots() { void new_bang_dots(int xbang, int ybang, int dx, int dy, SDL_Surface *s) { - int x,y,endcount; - uint16_t *pixel,c; + int i, n, x, y; + uint16_t *pixel, c; uint32_t colorkey; int row_inc; - double theta,r; - int begin_generate; + double theta, r; - begin_generate = SDL_GetTicks(); + n = 24.0 * t_frame; pixel = s->pixels; row_inc = s->pitch/sizeof(uint16_t) - s->w; colorkey = s->format->colorkey; SDL_LockSurface(s); - endcount = 0; - while (endcount<3) { + for(i=0; ipixels; for(y=0; yh; y++) { for(x = 0; xw; x++) { @@ -151,26 +159,21 @@ new_bang_dots(int xbang, int ybang, int dx, int dy, SDL_Surface *s) if(c && c != colorkey) { theta = frnd()*M_PI*2; r = frnd(); r = 1 - r*r; - // r = 1 - frnd()*frnd(); bdot[bd2].dx = 45*r*cos(theta) + dx; bdot[bd2].dy = 45*r*sin(theta) + dy; bdot[bd2].x = x + xbang; bdot[bd2].y = y + ybang; - bdot[bd2].c = 0; + bdot[bd2].c = (i < n-3) ? 0 : c; bdot[bd2].life = 100; bdot[bd2].decay = frnd()*3 + 1; bdot[bd2].active = 1; - // Replace the last few bang dots with the pixels from the exploding object - if(endcount>0) bdot[bd2].c = c; - bd2 = (bd2+1) % MAXBANGDOTS; } pixel += row_inc; } } - if(SDL_GetTicks() - begin_generate > 7) endcount++; } SDL_UnlockSurface(s); @@ -183,6 +186,7 @@ draw_bang_dots(SDL_Surface *s) int first_i, last_i; uint16_t *pixels, *pixel, c; int row_inc = s->pitch/sizeof(uint16_t); + Sprite *hit; pixels = (uint16_t *) s->pixels; first_i = -1; @@ -204,7 +208,14 @@ draw_bang_dots(SDL_Surface *s) } // check collisions - if(pixel_collides(bdot[i].x, bdot[i].y)) { bdot[i].active = 0; continue; } + 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; + } + } 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]; @@ -214,12 +225,15 @@ draw_bang_dots(SDL_Surface *s) void -new_engine_dots(int n, int dir) { +new_engine_dots(float time_span, int dir) { int i; + int n = time_span * ENGINE_DOTS_PER_TIC; float a, r; // angle, random length float dx, dy; float hx, hy; // half ship width/height. static const int s[4] = { 2, 1, 0, 1 }; + float time; + float accelh, accelv, past_ship_dx, past_ship_dy; hx = ship.image->w / 2; hy = ship.image->h / 2; @@ -232,18 +246,40 @@ new_engine_dots(int n, int dir) { dy = r * -sin(a); // screen y is "backwards". dotptr->active = 1; - dotptr->x = ship.x + s[dir]*hx + (frnd()-0.5)*3; - dotptr->y = ship.y + s[(dir+1)&3]*hy + (frnd()-0.5)*3; + + // dot was created at a random time during the time span + time = frnd() * time_span; // this is how long ago + + // calculate how fast the ship was going when this engine dot was + // created (as if it had a smoothe accelleration). This is used in + // determining the velocity of the dots, but not their starting + // location. + accelh = ((ship.jets >> 2) & 1) - (ship.jets & 1); + accelh *= THRUSTER_STRENGTH * time; + past_ship_dx = ship.dx - accelh; + accelv = ((ship.jets >> 1) & 1) - ((ship.jets >> 3) & 1); + accelv *= THRUSTER_STRENGTH * time; + past_ship_dy = ship.dy - accelv; + + // the starting position (not speed) of the dot is calculated as + // though the ship were traveling at a constant speed for this + // time_span. + dotptr->x = (ship.x - (ship.dx - screendx) * time) + s[dir]*hx; + dotptr->y = (ship.y - (ship.dy - screendy) * time) + s[(dir+1)&3]*hy; if(dir&1) { - dotptr->dx = ship.dx + 2*dx; - dotptr->dy = ship.dy + 20*dy; + dotptr->dx = past_ship_dx + 2*dx; + dotptr->dy = past_ship_dy + 20*dy; dotptr->life = 60 * fabs(dy); } else { - dotptr->dx = ship.dx + 20*dx; - dotptr->dy = ship.dy + 2*dy; + dotptr->dx = past_ship_dx + 20*dx; + dotptr->dy = past_ship_dy + 2*dy; dotptr->life = 60 * fabs(dx); } + // move the dot as though it were created in the past + dotptr->x += (dotptr->dx - screendx) * time; + dotptr->y += (dotptr->dy - screendy) * time; + if(dotptr - edot < MAXENGINEDOTS-1) dotptr++; else dotptr = edot; } @@ -251,6 +287,22 @@ new_engine_dots(int n, int dir) { } void +move_engine_dots() { + int i; + for(i = 0; i= XSIZE || edot[i].y < 0 || edot[i].y >= YSIZE) { + edot[i].active = 0; + } + } +} + +void draw_engine_dots(SDL_Surface *s) { int i; uint16_t c; @@ -260,14 +312,7 @@ draw_engine_dots(SDL_Surface *s) { Sprite *hit; for(i = 0; i= XSIZE - || edot[i].y<0 || edot[i].y >= YSIZE) { - edot[i].active = 0; + if(!edot[i].active) { continue; } // check collisions @@ -289,10 +334,12 @@ void drawdots(SDL_Surface *s) { int m; - // Create engine dots out the side we're moving from + move_engine_dots(); + + // Create engine dots for(m = 0; m<4; m++) { if(ship.jets & 1<flags = MOVE; - // ship->flags = MOVE|DRAW; // FADE SHIP - // SDL_SetAlpha(ship->image, SDL_SRCALPHA, 0); // FADE SHIP bang = true; } @@ -573,16 +604,38 @@ init_score_entry(void) SDL_EnableUNICODE(1); while(SDL_PollEvent(&e)) ; + insert_score(score); } void gameloop() { - Uint8 *keystate = SDL_GetKeyState(NULL); + SDL_Event e; + Uint8 *keystate; float tmp; for(;;) { - SDL_PumpEvents(); + while(SDL_PollEvent(&e)) { + switch(e.type) { + case SDL_QUIT: return; + case SDL_KEYUP: + if(e.key.keysym.sym == SDLK_ESCAPE + || e.key.keysym.sym == SDLK_q) + return; + break; + case SDL_KEYDOWN: + if(state == HIGH_SCORE_ENTRY) + if(!process_score_input(&e.key.keysym)) { + // Write the high score table to the file + write_high_score_table(); + // continue to display the scores briefly + state = HIGH_SCORE_DISPLAY; + state_timeout = 200; + play_tune(TUNE_TITLE_PAGE); + } + break; + } + } keystate = SDL_GetKeyState(NULL); if(!paused) { @@ -605,7 +658,8 @@ gameloop() { break; case HIGH_SCORE_DISPLAY: state = TITLE_PAGE; - state_timeout = 500.0; + state_timeout = 600.0; + fadetimer = 0.0; break; case HIGH_SCORE_ENTRY: break; @@ -618,18 +672,7 @@ gameloop() { } } else { if(state == DEAD_PAUSE) { - float blast_radius; - // float alpha; // FADE SHIP - if(state_timeout >= DEAD_PAUSE_LENGTH - 20.0) { - blast_radius = BLAST_RADIUS * (DEAD_PAUSE_LENGTH - state_timeout) / 20.0; - blast_rocks(bangx, bangy, blast_radius); - } - if(bangx < 60) bangx = 60; - - // FADE SHIP - // alpha = 255.0 * (DEAD_PAUSE_LENGTH - state_timeout) / DEAD_PAUSE_LENGTH; - // SDL_SetAlpha(ship.image, SDL_SRCALPHA, (uint8_t)alpha); } } @@ -691,19 +734,21 @@ gameloop() { } // new game - if((keystate[SDLK_SPACE] || keystate[SDLK_e] || keystate[SDLK_n]) + if((keystate[SDLK_SPACE] || keystate[SDLK_1] || keystate[SDLK_2]) && (state == HIGH_SCORE_DISPLAY || state == TITLE_PAGE || state == GAME_OVER)) { if(state == GAME_OVER && new_high_score(score)) init_score_entry(); else { - if(keystate[SDLK_n] || (keystate[SDLK_SPACE] && !initial_rocks)) { + if((keystate[SDLK_SPACE] && !initial_rocks) || keystate[SDLK_2]) { + g_easy = 0; initial_rocks = NORMAL_I_ROCKS; final_rocks = NORMAL_F_ROCKS; if(opt_gamespeed == EASY_GAMESPEED) opt_gamespeed = NORMAL_GAMESPEED; - } else if(keystate[SDLK_e]) { + } else if(keystate[SDLK_1]) { + g_easy = 1; initial_rocks = EASY_I_ROCKS; final_rocks = EASY_F_ROCKS; opt_gamespeed = EASY_GAMESPEED; @@ -716,7 +761,6 @@ gameloop() { ship.dx = screendx; ship.dy = screendy; ship.lives = 4; ship.flags = MOVE|DRAW|COLLIDE; - // SDL_SetAlpha(ship.image, SDL_SRCALPHA, SDL_ALPHA_OPAQUE); // FADE SHIP add_sprite(SPRITE(&ship)); score = 0; @@ -731,10 +775,11 @@ gameloop() { if(state == GAMEPLAY) { if(!paused) { - if(keystate[SDLK_LEFT] | keystate[SDLK_h]) { ship.dx -= 1.5*t_frame; ship.jets |= 1<<0;} - if(keystate[SDLK_DOWN] | keystate[SDLK_t]) { ship.dy += 1.5*t_frame; ship.jets |= 1<<1;} - if(keystate[SDLK_RIGHT] | keystate[SDLK_n]) { ship.dx += 1.5*t_frame; ship.jets |= 1<<2;} - if(keystate[SDLK_UP] | keystate[SDLK_c]) { ship.dy -= 1.5*t_frame; ship.jets |= 1<<3;} + // FIXME why is this at the bottom? Shouldn't it be up before the ship movement? + if(keystate[SDLK_LEFT] || keystate[SDLK_h]) { ship.dx -= THRUSTER_STRENGTH*t_frame; ship.jets |= 1<<0;} + if(keystate[SDLK_DOWN] || keystate[SDLK_t]) { ship.dy += THRUSTER_STRENGTH*t_frame; ship.jets |= 1<<1;} + if(keystate[SDLK_RIGHT] || keystate[SDLK_n]) { ship.dx += THRUSTER_STRENGTH*t_frame; ship.jets |= 1<<2;} + if(keystate[SDLK_UP] || keystate[SDLK_c]) { ship.dy -= THRUSTER_STRENGTH*t_frame; ship.jets |= 1<<3;} if(keystate[SDLK_3]) { SDL_SaveBMP(surf_screen, "snapshot.bmp"); } } @@ -749,16 +794,16 @@ gameloop() { } } - if(state != HIGH_SCORE_ENTRY && (keystate[SDLK_q] || keystate[SDLK_ESCAPE])) - return; - + if(state == TITLE_PAGE && keystate[SDLK_h]) { + state = HIGH_SCORE_DISPLAY; + state_timeout = 400; + } } } int main(int argc, char **argv) { - init_opts(); - argp_parse(&argp, argc, argv, 0, 0, 0); + if(!parse_opts(argc, argv)) return 1; if(init()) { printf ("ta: '%s'\n",initerror);