X-Git-Url: https://jasonwoof.com/gitweb/?p=vor.git;a=blobdiff_plain;f=main.c;h=f69b5dc9d4c8a2163293d7146f6bca2ddd42eeab;hp=72f3cfd9dbc82b85547e7641b640e9fa87a2089d;hb=1f56b653a3e8284f1d9164758d54b93e611af954;hpb=eb0732dc23646473853da1e37311f93052b8251b diff --git a/main.c b/main.c index 72f3cfd..f69b5dc 100644 --- a/main.c +++ b/main.c @@ -34,6 +34,7 @@ #include "config.h" #include "dust.h" #include "file.h" +#include "float.h" #include "globals.h" #include "mt.h" #include "rocks.h" @@ -57,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]; @@ -131,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; ipixels; - for(y=0; yh; y++) { - for(x = 0; xw; 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= (XSIZE - 0.000001) || bdot[i].y < 0 || bdot[i].y >= (YSIZE - 0.000001)) { - 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; iactive = 1; + dotptr->decay = 3; // dot was created at a random time during the time span time = frnd() * time_span; // this is how long ago @@ -277,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 @@ -295,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; ipixels; + 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 || 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; + if(SDL_MUSTLOCK(img)) { SDL_LockSurface(img); } + + for(i=0; ipixels; + for(y=0; yh; y++) { + for(x = 0; xw; 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; ipitch/sizeof(uint16_t); + + pixels = (uint16_t *) s->pixels; + + for(i=0; ipitch/sizeof(uint16_t); - int heatindex; + + pixels = (uint16_t *) s->pixels; for(i = 0; i3*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)]; } } @@ -721,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