void game_display::new_turn() { const time_of_day& tod = tod_manager_.get_time_of_day(); if( !first_turn_) { const time_of_day& old_tod = tod_manager_.get_previous_time_of_day(); if(old_tod.image_mask != tod.image_mask) { const surface old_mask(image::get_image(old_tod.image_mask,image::SCALED_TO_HEX)); const surface new_mask(image::get_image(tod.image_mask,image::SCALED_TO_HEX)); const int niterations = static_cast<int>(10/turbo_speed()); const int frame_time = 30; const int starting_ticks = SDL_GetTicks(); for(int i = 0; i != niterations; ++i) { if(old_mask != NULL) { const fixed_t proportion = ftofxp(1.0) - fxpdiv(i,niterations); tod_hex_mask1.assign(adjust_surface_alpha(old_mask,proportion)); } if(new_mask != NULL) { const fixed_t proportion = fxpdiv(i,niterations); tod_hex_mask2.assign(adjust_surface_alpha(new_mask,proportion)); } invalidate_all(); draw(); const int cur_ticks = SDL_GetTicks(); const int wanted_ticks = starting_ticks + i*frame_time; if(cur_ticks < wanted_ticks) { SDL_Delay(wanted_ticks - cur_ticks); } } } tod_hex_mask1.assign(NULL); tod_hex_mask2.assign(NULL); } first_turn_ = false; display::update_tod(); invalidate_all(); draw(); }
//TODO: proper SDL_gpu implementation void unit_drawer::draw_bar(const std::string& image, int xpos, int ypos, const map_location& loc, size_t height, double filled, const SDL_Color& col, fixed_t alpha) const { filled = std::min<double>(std::max<double>(filled,0.0),1.0); height = static_cast<size_t>(height*zoom_factor); surface surf(image::get_image(image,image::SCALED_TO_HEX)); // We use UNSCALED because scaling (and bilinear interpolation) // is bad for calculate_energy_bar. // But we will do a geometric scaling later. surface bar_surf(image::get_image(image)); if(surf == nullptr || bar_surf == nullptr) { return; } // calculate_energy_bar returns incorrect results if the surface colors // have changed (for example, due to bilinear interpolation) const SDL_Rect& unscaled_bar_loc = calculate_energy_bar(bar_surf); SDL_Rect bar_loc; if (surf->w == bar_surf->w && surf->h == bar_surf->h) bar_loc = unscaled_bar_loc; else { const fixed_t xratio = fxpdiv(surf->w,bar_surf->w); const fixed_t yratio = fxpdiv(surf->h,bar_surf->h); const SDL_Rect scaled_bar_loc = sdl::create_rect( fxptoi(unscaled_bar_loc. x * xratio) , fxptoi(unscaled_bar_loc. y * yratio + 127) , fxptoi(unscaled_bar_loc. w * xratio + 255) , fxptoi(unscaled_bar_loc. h * yratio + 255)); bar_loc = scaled_bar_loc; } if(height > static_cast<size_t>(bar_loc.h)) { height = bar_loc.h; } //if(alpha != ftofxp(1.0)) { // surf.assign(adjust_surface_alpha(surf,alpha)); // if(surf == nullptr) { // return; // } //} const size_t skip_rows = bar_loc.h - height; SDL_Rect top = sdl::create_rect(0, 0, surf->w, bar_loc.y); SDL_Rect bot = sdl::create_rect(0, bar_loc.y + skip_rows, surf->w, 0); bot.h = surf->w - bot.y; #ifdef SDL_GPU sdl::timage img(surf); img.set_clip(top); disp.drawing_buffer_add(display::LAYER_UNIT_BAR, loc, xpos, ypos, surf); img.set_clip(bot); disp.drawing_buffer_add(display::LAYER_UNIT_BAR, loc, xpos, ypos + top.h, surf); #else disp.drawing_buffer_add(display::LAYER_UNIT_BAR, loc, xpos, ypos, surf, top); disp.drawing_buffer_add(display::LAYER_UNIT_BAR, loc, xpos, ypos + top.h, surf, bot); #endif size_t unfilled = static_cast<size_t>(height * (1.0 - filled)); if(unfilled < height && alpha >= ftofxp(0.3)) { const Uint8 r_alpha = std::min<unsigned>(unsigned(fxpmult(alpha,255)),255); surface filled_surf = create_compatible_surface(bar_surf, bar_loc.w, height - unfilled); SDL_Rect filled_area = sdl::create_rect(0, 0, bar_loc.w, height-unfilled); sdl::fill_rect(filled_surf,&filled_area,SDL_MapRGBA(bar_surf->format,col.r,col.g,col.b, r_alpha)); #ifdef SDL_GPU disp.drawing_buffer_add(display::LAYER_UNIT_BAR, loc, xpos + bar_loc.x, ypos + bar_loc.y + unfilled, sdl::timage(filled_surf)); #else disp.drawing_buffer_add(display::LAYER_UNIT_BAR, loc, xpos + bar_loc.x, ypos + bar_loc.y + unfilled, filled_surf); #endif } }