X-Git-Url: https://jasonwoof.com/gitweb/?p=vor.git;a=blobdiff_plain;f=main.c;h=ccaf3504d59c5bc55ba7d6fd497e67240fc49b2f;hp=7c046ddb5bf12dedcbcf8d86a64874af2fa1930c;hb=47d10ee91e99f21602ce674ad140fc99b8986633;hpb=0fa601afde57877514c939ca84b35e9b0134ebe9 diff --git a/main.c b/main.c index 7c046dd..ccaf350 100644 --- a/main.c +++ b/main.c @@ -27,7 +27,7 @@ #include #include -#include "SFont.h" +#include "font.h" #include "args.h" #include "common.h" @@ -59,7 +59,7 @@ SDL_Surface *surf_font_big; // The big font -SFont_Font *g_font; +font *g_font; // Structure global variables struct enginedots edot[MAXENGINEDOTS], *dotptr = edot; @@ -75,6 +75,7 @@ float screendx = SCREENDXMIN, screendy = 0.0; float back_dist; // all movement is based on t_frame. +unsigned long frames, start, end; 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) @@ -144,12 +145,12 @@ new_bang_dots(int xbang, int ybang, int dx, int dy, SDL_Surface *s) int row_inc; double theta, r; - n = 24.0 * t_frame; + n = 20; pixel = s->pixels; row_inc = s->pitch/sizeof(uint16_t) - s->w; colorkey = s->format->colorkey; - SDL_LockSurface(s); + if(SDL_MUSTLOCK(s)) { SDL_LockSurface(s); } for(i=0; ipixels; @@ -164,8 +165,8 @@ new_bang_dots(int xbang, int ybang, int dx, int dy, SDL_Surface *s) bdot[bd2].dy = 45*r*sin(theta) + dy; bdot[bd2].x = x + xbang; bdot[bd2].y = y + ybang; - bdot[bd2].c = (i < n-3) ? 0 : c; - bdot[bd2].life = 100; + //bdot[bd2].c = (i < n-3) ? 0 : c; + bdot[bd2].life = frnd() * 99; bdot[bd2].decay = frnd()*3 + 1; bdot[bd2].active = 1; @@ -176,7 +177,7 @@ new_bang_dots(int xbang, int ybang, int dx, int dy, SDL_Surface *s) } } - SDL_UnlockSurface(s); + if(SDL_MUSTLOCK(s)) { SDL_UnlockSurface(s); } } void @@ -189,13 +190,13 @@ move_bang_dots(float ticks) if(!bdot[i].active) continue; // decrement life and maybe kill - bdot[i].life -= bdot[i].decay; + 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(bdot[i].x < 0 || bdot[i].x >= XSIZE || bdot[i].y < 0 || bdot[i].y >= YSIZE) { + if(bdot[i].x < 0 || bdot[i].x >= (XSIZE - 0.000001) || bdot[i].y < 0 || bdot[i].y >= (YSIZE - 0.000001)) { bdot[i].active = 0; continue; } @@ -233,8 +234,8 @@ draw_bang_dots(SDL_Surface *s) void -new_engine_dots(float time_span, int dir) { - int i; +new_engine_dots(float time_span) { + int dir, i; int n = time_span * ENGINE_DOTS_PER_TIC; float a, r; // angle, random length float dx, dy; @@ -246,50 +247,54 @@ new_engine_dots(float time_span, int dir) { hx = ship.image->w / 2; hy = ship.image->h / 2; - for(i = 0; iactive == 0) { - a = frnd()*M_PI + (dir-1)*M_PI_2; - r = sin(frnd()*M_PI); - dx = r * cos(a); - dy = r * -sin(a); // screen y is "backwards". - - dotptr->active = 1; - - // 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 smooth acceleration). 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 = past_ship_dx + 2*dx; - dotptr->dy = past_ship_dy + 20*dy; - dotptr->life = 60 * fabs(dy); - } else { - dotptr->dx = past_ship_dx + 20*dx; - dotptr->dy = past_ship_dy + 2*dy; - dotptr->life = 60 * fabs(dx); - } + for(dir=0; dir<4; dir++) { + if(!(ship.jets & 1<active == 0) { + a = frnd()*M_PI + (dir-1)*M_PI_2; + r = sin(frnd()*M_PI); + dx = r * cos(a); + dy = r * -sin(a); // screen y is "backwards". + + dotptr->active = 1; + + // 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 smooth acceleration). 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 = past_ship_dx + 2*dx; + dotptr->dy = past_ship_dy + 20*dy; + dotptr->life = 60 * fabs(dy); + } else { + 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; + // 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; + if(dotptr - edot < MAXENGINEDOTS-1) dotptr++; + else dotptr = edot; + } } } } @@ -305,8 +310,9 @@ move_engine_dots(float ticks) { 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 || edot[i].x<0 || edot[i].x >= XSIZE || edot[i].y < 0 || edot[i].y >= YSIZE) { + if(edot[i].life < 0 || edot[i].x<0 || edot[i].x >= (XSIZE - 0.000001) || edot[i].y < 0 || edot[i].y >= (YSIZE - 0.000001)) { edot[i].active = 0; + continue; } // check collisions @@ -340,20 +346,11 @@ draw_engine_dots(SDL_Surface *s) { void draw_dots(SDL_Surface *s) { - int m; - - // Create engine dots - for(m = 0; m<4; m++) { - if(ship.jets & 1<w)/2; dest.y = (YSIZE-surf_b_game->h)/2-40; - SDL_SetAlpha(surf_b_game, SDL_SRCALPHA, (int)(a_game*(200 + 55*cos(fadetimer)))); + //SDL_SetAlpha(surf_b_game, SDL_SRCALPHA, (int)(a_game*(200 + 55*cos(fadetimer)))); SDL_BlitSurface(surf_b_game,NULL,surf_screen,&dest); dest.x = (XSIZE-surf_b_over->w)/2; dest.y = (YSIZE-surf_b_over->h)/2 + 40; - SDL_SetAlpha(surf_b_over, SDL_SRCALPHA, (int)(a_over*(200 + 55*sin(fadetimer)))); + //SDL_SetAlpha(surf_b_over, SDL_SRCALPHA, (int)(a_over*(200 + 55*sin(fadetimer)))); SDL_BlitSurface(surf_b_over,NULL,surf_screen,&dest); if(new_high_score(score)) { @@ -504,11 +507,11 @@ draw_game_over(void) text1 = msgs[g_easy][1]; } - x = (XSIZE-SFont_TextWidth(g_font,text0))/2 + cos(fadetimer/9)*10; - SFont_Write(surf_screen,g_font,x,YSIZE-100 + cos(fadetimer/6)*5,text0); + x = (XSIZE-font_width(text0))/2 + cos(fadetimer/9)*10; + font_write(x,YSIZE-100 + cos(fadetimer/6)*5,text0); - x = (XSIZE-SFont_TextWidth(g_font,text1))/2 + sin(fadetimer/9)*10; - SFont_Write(surf_screen,g_font,x,YSIZE-50 + sin(fadetimer/4)*5,text1); + x = (XSIZE-font_width(text1))/2 + sin(fadetimer/9)*10; + font_write(x,YSIZE-50 + sin(fadetimer/4)*5,text1); } void @@ -522,26 +525,26 @@ draw_title_page(void) dest.x = (XSIZE-surf_b_variations->w)/2 + cos(fadetimer/6.5)*10; dest.y = (YSIZE/2-surf_b_variations->h)/2 + sin(fadetimer/5.0)*10; - SDL_SetAlpha(surf_b_variations, SDL_SRCALPHA, (int)(200 + 55*sin(fadetimer))); + //SDL_SetAlpha(surf_b_variations, SDL_SRCALPHA, (int)(200 + 55*sin(fadetimer))); SDL_BlitSurface(surf_b_variations,NULL,surf_screen,&dest); dest.x = (XSIZE-surf_b_on->w)/2 + cos((fadetimer + 1.0)/6.5)*10; dest.y = (YSIZE/2-surf_b_on->h)/2 + surf_b_variations->h + 20 + sin((fadetimer + 1.0)/5.0)*10; - SDL_SetAlpha(surf_b_on, SDL_SRCALPHA, (int)(200 + 55*sin(fadetimer-1.0))); + //SDL_SetAlpha(surf_b_on, SDL_SRCALPHA, (int)(200 + 55*sin(fadetimer-1.0))); SDL_BlitSurface(surf_b_on,NULL,surf_screen,&dest); dest.x = (XSIZE-surf_b_rockdodger->w)/2 + cos((fadetimer + 2.0)/6.5)*10; dest.y = (YSIZE/2-surf_b_rockdodger->h)/2 + surf_b_variations->h + surf_b_on->h + 40 + sin((fadetimer + 2.0)/5)*10; - SDL_SetAlpha(surf_b_rockdodger, SDL_SRCALPHA, (int)(200 + 55*sin(fadetimer-2.0))); + //SDL_SetAlpha(surf_b_rockdodger, SDL_SRCALPHA, (int)(200 + 55*sin(fadetimer-2.0))); SDL_BlitSurface(surf_b_rockdodger,NULL,surf_screen,&dest); text = msgs[g_easy][(int)(fadetimer/35)%NSEQUENCE]; - x = (XSIZE-SFont_TextWidth(g_font,text))/2 + cos(fadetimer/4.5)*10; - SFont_Write(surf_screen,g_font,x,YSIZE-100 + cos(fadetimer/3)*5,text); + x = (XSIZE-font_width(text))/2 + cos(fadetimer/4.5)*10; + font_write(x,YSIZE-100 + cos(fadetimer/3)*5,text); text = "Version " VERSION; - x = (XSIZE-SFont_TextWidth(g_font,text))/2 + sin(fadetimer/4.5)*10; - SFont_Write(surf_screen,g_font,x,YSIZE-50 + sin(fadetimer/2)*5,text); + x = (XSIZE-font_width(text))/2 + sin(fadetimer/4.5)*10; + font_write(x,YSIZE-50 + sin(fadetimer/2)*5,text); } void @@ -575,11 +578,6 @@ draw(void) { collisions(); - ms_frame = SDL_GetTicks() - ms_end; - ms_end += ms_frame; - t_frame = opt_gamespeed * ms_frame / 50; - if(state == GAMEPLAY) score += ms_frame; - // Update the surface SDL_Flip(surf_screen); } @@ -611,24 +609,63 @@ init_score_entry(void) insert_score(score); } +// Count down the state timer, and change state when it gets to zero or less; +void +update_state(float ticks) +{ + state_timeout -= ticks*3; + if(state_timeout > 0) return; + + switch(state) { + case DEAD_PAUSE: + // Restore the ship and continue playing + ship.flags = DRAW|MOVE|COLLIDE; + state = GAMEPLAY; + play_tune(TUNE_GAMEPLAY); + break; + case GAME_OVER: + if(new_high_score(score)) init_score_entry(); + else { + state = HIGH_SCORE_DISPLAY; + state_timeout = 400; + } + break; + case HIGH_SCORE_DISPLAY: + state = TITLE_PAGE; + state_timeout = 600.0; + fadetimer = 0.0; + break; + case HIGH_SCORE_ENTRY: + break; + case TITLE_PAGE: + state = HIGH_SCORE_DISPLAY; + state_timeout = 200.0; + break; + case GAMEPLAY: + ; // no action necessary + } +} + void gameloop() { SDL_Event e; Uint8 *keystate; float tmp; - for(;;) { + ms_frame = SDL_GetTicks() - ms_end; + ms_end += ms_frame; + if(ms_frame > 1000) { + ms_frame = 1000; + } + t_frame = opt_gamespeed * ms_frame / 50; + frames++; + 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(state == HIGH_SCORE_ENTRY) { if(!process_score_input(&e.key.keysym)) { // Write the high score table to the file write_high_score_table(); @@ -637,53 +674,49 @@ gameloop() { state_timeout = 200; play_tune(TUNE_TITLE_PAGE); } + } else if(e.key.keysym.sym == SDLK_q) { + return; + } + + if(e.key.keysym.sym == SDLK_ESCAPE) { + return; + } break; } } keystate = SDL_GetKeyState(NULL); - if(!paused) { - // Count down the game loop timer, and change state when it gets to zero or less; - - if((state_timeout -= t_frame*3) < 0) { - switch(state) { - case DEAD_PAUSE: - // Restore the ship and continue playing - ship.flags = DRAW|MOVE|COLLIDE; - state = GAMEPLAY; - play_tune(TUNE_GAMEPLAY); - break; - case GAME_OVER: - if(new_high_score(score)) init_score_entry(); - else { - state = HIGH_SCORE_DISPLAY; - state_timeout = 400; - } - break; - case HIGH_SCORE_DISPLAY: - state = TITLE_PAGE; - state_timeout = 600.0; - fadetimer = 0.0; - break; - case HIGH_SCORE_ENTRY: - break; - case TITLE_PAGE: - state = HIGH_SCORE_DISPLAY; - state_timeout = 200.0; - break; - case GAMEPLAY: - ; // no action necessary + if(state == GAMEPLAY) { + if(!paused) { + score += ms_frame; + + 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"); } + } + + if(keystate[SDLK_p] | keystate[SDLK_s]) { + if(!pausedown) { + paused = !paused; + pausedown = 1; + if(!paused) ms_end = SDL_GetTicks(); } } else { - if(state == DEAD_PAUSE) { - if(bangx < 60) bangx = 60; - } + pausedown = 0; } + } + + if(!paused) { + update_state(t_frame); + + if(state == DEAD_PAUSE && bangx < 60) bangx = 60; // SCROLLING - tmp = (ship.y+ship.dy*t_frame-YSCROLLTO)/25 + (ship.dy-screendy); + tmp = (ship.y+ship.h/2+ship.dy*t_frame-YSCROLLTO)/25 + (ship.dy-screendy); screendy += tmp * t_frame/12; - tmp = (ship.x+ship.dx*t_frame-XSCROLLTO)/25 + (ship.dx-screendx); + tmp = (ship.x+ship.w/2+ship.dx*t_frame-XSCROLLTO)/25 + (ship.dx-screendx); screendx += tmp * t_frame/12; // taper off so we don't hit the barrier abruptly. // (if we would hit in < 2 seconds, adjust to 2 seconds). @@ -714,6 +747,7 @@ gameloop() { } new_rocks(t_frame); + new_engine_dots(t_frame); draw(); @@ -763,7 +797,7 @@ gameloop() { reset_rocks(); screendx = SCREENDXMIN; screendy = 0; - ship.x = XSIZE/2.2; ship.y = YSIZE/2; + ship.x = XSIZE/2.2; ship.y = YSIZE/2 - ship.w/2; ship.dx = screendx; ship.dy = screendy; ship.lives = 4; ship.flags = MOVE|DRAW|COLLIDE; @@ -779,27 +813,6 @@ gameloop() { ship.jets = 0; } - if(state == GAMEPLAY) { - if(!paused) { - // 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"); } - } - - if(keystate[SDLK_p] | keystate[SDLK_s]) { - if(!pausedown) { - paused = !paused; - pausedown = 1; - if(!paused) ms_end = SDL_GetTicks(); - } - } else { - pausedown = 0; - } - } - if(state == TITLE_PAGE && keystate[SDLK_h]) { state = HIGH_SCORE_DISPLAY; state_timeout = 400; @@ -812,11 +825,15 @@ main(int argc, char **argv) { if(!parse_opts(argc, argv)) return 1; if(init()) { - printf ("ta: '%s'\n",initerror); + printf ("vor: SDL error: '%s'\n",initerror); return 1; } + start = SDL_GetTicks(); + frames = 0; gameloop(); + end = SDL_GetTicks(); + // printf("%ld frames in %ld ms, %.2f fps.\n", frames, end-start, frames * 1000.0 / (end-start)); return 0; }