void renderDMXFlaresAndFlashes(int player) { int numColumns = gs.isDoubles || gs.isVersus ? 8 : 8; for ( int i = 0; i < numColumns; i++ ) { int frame = 15 - ((gs.player[player].laneFlareTimers[i] / (HIT_FLASH_DISPLAY_TIME / 16)) % 16); int x = getColumnOffsetX_DMX(i); if ( gs.player[player].laneFlareTimers[i] > 0 ) { int bigSmall = gs.player[player].displayCombo >= 100 ? 1 : 0; int color = (gs.player[player].displayCombo/100) % 5; // for a 'marvelous' render a flashing firework if ( gs.player[player].laneFlareColors[i] == 0 || gs.player[player].laneFlareColors[i] == 3 ) { //color = ((gs.player[player].laneFlareTimers[i] / 20) % 3) + 2; } // render an offcolor firework explosion for an O.K.! if ( gs.player[player].laneFlareColors[i] == 4 ) { bigSmall = 1; color = (color+1) % 5; // frame % 5; } // while holding a hold note, do something entirely different than a firework if ( gs.player[player].laneFlareColors[i] != 2 ) { set_add_blender(0,0,0,256); draw_trans_sprite(rm.m_backbuf, m_dmxFireworks[bigSmall][color][frame], x-46, (gs.player[player].isColumnReversed(i) ? DMX_STEP_ZONE_REV_Y-34 : DMX_STEP_ZONE_Y)-46); set_alpha_blender(); // the game assumes the graphics are left in this mode } } } }
void KaboHaze::animate(Frame *space) { STACKTRACE; // IMPORTANT: physics must not be changed, that is, NON-LOCAL variable must not // be changed in this subroutine ! // Reason: the TimeWarp engine can decide to skip animations in case of low // frame-rate, thus, leading to a desynch between computers! /* Aaaaah, lots of work to do for a simple job, namely, create a transparent overlay of the shield onto the host: - Init (see constructor): Take the host-ship picture. Create a (blurred) mask image of it. Draw the shield and Overlay the mask. - Animate: Scale and draw the masked shield, Rotate and Draw transparent onto the screen. */ if (!host) return; //if ( state == 0 ) // return; // the host can die in-between calculate and animate, therefore I use this; it's // not allowed to change state of this presence though; that's done only in // calculate(). // Create a rotated copy of the shield sprite ... but only, if such a thing // does not exist, yet ! The purpose of this is, to spread the amount of // calculations over different frames, and to limit them to when they're // needed. int wshield = shield_bmp[0]->w; int hshield = shield_bmp[0]->h; if ( !shield_bmp[shield_sprite_index] ) { shield_bmp[shield_sprite_index] = create_bitmap(wshield, hshield); // important otherwise it contains artefacts clear_to_color(shield_bmp[shield_sprite_index], 0); rotate_sprite(shield_bmp[shield_sprite_index], shield_bmp[0], 0, 0, iround((1<<24)*(host->angle + 0.5*PI)/PI2) ); // result is in sprite_bmp[sprite_index] ( nice conventions, huh !) } //sprite_index = 0; // also needed - for collision detection?? // note, I've turned the collision of, since collide_flag_anyone = 0, but // otherwise, the collision detector would use this sprite_index to access // a ship sprite that doesnt exist !! // next, animate ... // first, reserve space for the target image, but ... how big should it be? // well, as big as the ship_bmp, but then, zoomed in space: int wfinal = int(wshield * space_zoom); int hfinal = int(hshield * space_zoom); BITMAP *final_bmp; final_bmp = create_bitmap(wfinal, hfinal); // scale/draw a shield: stretch_blit(shield_bmp[shield_sprite_index], final_bmp, 0, 0, wshield, hshield, 0, 0, wfinal, hfinal ); // result is in final_bmp // I need to calculate screen coordinates (using the original bmp size). // double xhost = host->normal_pos().x; // double yhost = host->normal_pos().y; Vector2 Vcorner; Vcorner = corner(host->normal_pos(), Vector2(wshield, hshield) ); //wcorner(xhost, wshield); int xplot = iround(Vcorner.x); //hcorner(yhost, hshield); int yplot = iround(Vcorner.y); // these routines are the standard way to calculate screen coordinates ! // local double power_scaled = power / 10.0; if ( power_scaled > 1.0 ) power_scaled = 1.0; // max brightness. // change the brightness of the shield: int brightness = int(255 * power_scaled); set_add_blender(0, 0, 0, brightness); draw_trans_sprite(space->surface, final_bmp, xplot, yplot); space->add_box(xplot, yplot, wshield, hshield); // also, draw a (few) flashes, at twice the brightness: brightness = 255; for ( int i = 0; i < int(power); ++i ) { int dx, dy; dx = wshield; dy = hshield; int icheck = 0; for (;;) { ++icheck; if (icheck > 100) break; // too bad !! //graphics dy = rand() % hshield; if (edge_left[dy] == -1) continue; if ( !(rand() % 2) ) //graphics dx = edge_left[dy]; else dx = edge_right[dy]; } dx -= wshield / 2; dy -= hshield / 2; double a = host->angle + 0.5*PI; // rotated around the center int dx2 = iround(wshield/2 + dx * cos(a) - dy * sin(a)); int dy2 = iround(hshield/2 + dy * cos(a) + dx * sin(a)); dx = iround( dx2 * space_zoom); dy = iround( dy2 * space_zoom); int x = xplot + dx; int y = yplot + dy; tw_putpixel(space->surface, x, y, tw_makecol(brightness,brightness,0) ); space->add_pixel(x, y); } // release the temporary bitmap: destroy_bitmap(final_bmp); }
int main() { BITMAP *mysha = NULL, *buffer = NULL; PARTICLE *particle[NUM_PARTICLES]; int old_time = 0, old_time2 = 0; int i; int count = 0; int use_alleg = FALSE; int depth = 16; allegro_init(); install_keyboard(); install_timer(); set_config_file("examples.cfg"); depth = get_config_int("examples", "depth", 16); set_color_depth(depth); if (set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0)) { set_color_depth(16); if (set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0)) { set_color_depth(15); if (set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0)) { set_color_depth(32); if (set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0)) { allegro_message("Unable to set 640x480 screen mode!\n"); return -1; } } } } mysha = load_bitmap("mysha.pcx", NULL); if (!mysha) { set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); allegro_message("Unable to load mysha.pcx. Copy it from the allegro examples directory.\n"); return -2; } TRACE("Got here!\n"); for (i = 0; i < NUM_PARTICLES; i++) particle[i] = NULL; TRACE("Still here!\n"); for (i = 0; i < NUM_PARTICLES; i++) { int j; int r, g, b; TRACE("Going for particle: %i\n", i); particle[i] = malloc(sizeof(PARTICLE)); if (!particle[i]) { TRACE("Out of memory while creating particle!\n"); goto Error; } TRACE("Clearing particle\n"); memset(particle[i], 0, sizeof(PARTICLE)); TRACE("Creating bitmap\n"); particle[i]->bmp = create_bitmap(PARTICLE_SIZE, PARTICLE_SIZE); if (!particle[i]->bmp) { TRACE("Out of memory while creating particle bitmap!\n"); goto Error; } TRACE("Clearing bitmap\n"); clear(particle[i]->bmp); TRACE("Setting up coordinates\n"); particle[i]->x = rand() % SCREEN_W; particle[i]->y = rand() % SCREEN_H; particle[i]->vx = rand() % 10 - 5; particle[i]->vy = rand() % 10 - 5; particle[i]->a = rand() & 255; particle[i]->a_dir = 1; TRACE("Setting up colors\n"); hsv_to_rgb(rand() % 360, 1, 1, &r, &g, &b); TRACE("Drawing circles\n"); for (j = 1; j < PARTICLE_SIZE/2-1; j++) { circle(particle[i]->bmp, PARTICLE_SIZE/2-1, PARTICLE_SIZE/2, j, makecol(r*2/(j+1), g*2/(j+1), b*2/(j+1))); circle(particle[i]->bmp, PARTICLE_SIZE/2, PARTICLE_SIZE/2, j, makecol(r*2/(j+1), g*2/(j+1), b*2/(j+1))); } } LOCK_FUNCTION(the_timer); LOCK_VARIABLE(chrono); buffer = create_bitmap(SCREEN_W, SCREEN_H); if (!buffer) { TRACE("Out of memory while creating back buffer!\n"); goto Error; } clear(buffer); TRACE("Starting...\n"); install_int(the_timer, 1); old_time = chrono; text_mode(0); do { int chrono2; /* Tile mysha over the screen */ #ifndef COMPARE_WITH_ALLEGRO blit(mysha, buffer, 0, 0, 0, 0, mysha->w, mysha->h); blit(mysha, buffer, 0, 0, 320, 0, mysha->w, mysha->h); blit(mysha, buffer, 0, 0, 0, 200, mysha->w, mysha->h); blit(mysha, buffer, 0, 0, 320, 200, mysha->w, mysha->h); blit(mysha, buffer, 0, 0, 0, 400, mysha->w, mysha->h); blit(mysha, buffer, 0, 0, 320, 400, mysha->w, mysha->h); #endif if (use_alleg) { for (i = 0; i < NUM_PARTICLES; i++) { set_add_blender(0, 0, 0, particle[i]->a); draw_trans_sprite(buffer, particle[i]->bmp, particle[i]->x - particle[i]->bmp->w/2, particle[i]->y - particle[i]->bmp->h/2); } } else { for (i = 0; i < NUM_PARTICLES; i++) fblend_add(particle[i]->bmp, buffer, particle[i]->x - particle[i]->bmp->w/2, particle[i]->y - particle[i]->bmp->h/2, particle[i]->a); } if (key[KEY_SPACE]) { use_alleg = !use_alleg; key[KEY_SPACE] = 0; chrono = 0; count = 0; old_time = 0; old_time2 = 0; } count++; #ifdef COMPARE_WITH_ALLEGRO textprintf(screen, font, 0, 0, makecol(255, 255, 255), "%s %.2f fps (%.3f avg)", use_alleg ? "Using Allegro" : "Using new", (chrono - old_time2) == 0 ? 1000.0 : 1000 / ((double)chrono - old_time2), count * 1000.0 / chrono); #else textprintf(buffer, font, 0, 0, makecol(255, 255, 255), "%s %.2f fps (%.3f avg)", use_alleg ? "Using Allegro" : "Using new", (chrono - old_time2) == 0 ? 1000.0 : 1000 / ((double)chrono - old_time2), count * 1000.0 / chrono); #endif old_time2 = chrono; #ifndef COMPARE_WITH_ALLEGRO /* Draw the buffer */ blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H); #endif chrono2 = chrono / 40; for (i = old_time/40; i < chrono2; i++) { int j; for (j = 0; j < NUM_PARTICLES; j++) { particle[j]->x += particle[j]->vx; particle[j]->y += particle[j]->vy; if (particle[j]->x <= 0 || particle[j]->x >= SCREEN_W) particle[j]->vx = -particle[j]->vx; if (particle[j]->y <= 0 || particle[j]->y >= SCREEN_H) particle[j]->vy = -particle[j]->vy; if (particle[j]->a <= 0 || particle[j]->a >= 256) particle[j]->a_dir = -particle[j]->a_dir; particle[j]->a += particle[j]->a_dir; } } old_time = chrono; } while (!key[KEY_ESC]); Error: TRACE("Shutting down.\n"); if (mysha) destroy_bitmap(mysha); if (buffer) destroy_bitmap(buffer); for (i = 0; i < NUM_PARTICLES; i++) { if (particle[i]) { if (particle[i]->bmp) destroy_bitmap(particle[i]->bmp); free(particle[i]); } } set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); return 0; }