void floating_label::draw(surface screen) { if(!visible_) { buf_.assign(nullptr); return; } if(screen == nullptr) { return; } create_surface(); if(surf_ == nullptr) { return; } if(buf_ == nullptr) { buf_.assign(create_compatible_surface(screen, surf_->w, surf_->h)); if(buf_ == nullptr) { return; } } SDL_Rect rect = sdl::create_rect(xpos(surf_->w), ypos_, surf_->w, surf_->h); const clip_rect_setter clip_setter(screen, &clip_rect_); sdl_copy_portion(screen,&rect,buf_,nullptr); sdl_blit(surf_,nullptr,screen,&rect); }
bool halo_impl::effect::render() { if(disp == nullptr) { return false; } if(loc_.x != -1 && loc_.y != -1) { if(disp->shrouded(loc_)) { return false; } else { // The location of a halo is an x,y value and not a map location. // This means when a map is zoomed, the halo's won't move, // This glitch is most visible on [item] haloes. // This workaround always recalculates the location of the halo // (item haloes have a location parameter to hide them under the shroud) // and reapplies that location. // It might be optimized by storing and comparing the zoom value. set_location( disp->get_location_x(loc_) + disp->hex_size() / 2, disp->get_location_y(loc_) + disp->hex_size() / 2); } } images_.update_last_draw_time(); surf_.assign(image::get_image(current_image(),image::SCALED_TO_ZOOM)); if(surf_ == nullptr) { return false; } if(orientation_ == HREVERSE || orientation_ == HVREVERSE) { surf_.assign(image::reverse_image(surf_)); } if(orientation_ == VREVERSE || orientation_ == HVREVERSE) { surf_.assign(flop_surface(surf_)); } const int screenx = disp->get_location_x(map_location::ZERO()); const int screeny = disp->get_location_y(map_location::ZERO()); const int xpos = x_ + screenx - surf_->w/2; const int ypos = y_ + screeny - surf_->h/2; SDL_Rect rect = sdl::create_rect(xpos, ypos, surf_->w, surf_->h); rect_ = rect; SDL_Rect clip_rect = disp->map_outside_area(); // If rendered the first time, need to determine the area affected. // If a halo changes size, it is not updated. if(location_not_known()) { display::rect_of_hexes hexes = disp->hexes_under_rect(rect); display::rect_of_hexes::iterator i = hexes.begin(), end = hexes.end(); for (;i != end; ++i) { overlayed_hexes_.push_back(*i); } } if(sdl::rects_overlap(rect,clip_rect) == false) { buffer_.assign(nullptr); return false; } surface& screen = disp->get_screen_surface(); const clip_rect_setter clip_setter(screen, &clip_rect); if(buffer_ == nullptr || buffer_->w != rect.w || buffer_->h != rect.h) { SDL_Rect rect = rect_; buffer_.assign(get_surface_portion(screen,rect)); } else { SDL_Rect rect = rect_; sdl_copy_portion(screen,&rect,buffer_,nullptr); } sdl_blit(surf_,nullptr,screen,&rect); update_rect(rect_); return true; }
void draw(surface screen) { if(use_color_cursors() == false) { return; } if(current_cursor == NUM_CURSORS) { current_cursor = NORMAL; } if(have_focus == false) { cursor_buf = NULL; return; } if (!color_ready) { // Display start to draw cursor // so it can now display color cursor color_ready = true; // Reset the cursor to be sure that we hide the b&w set(); } /** @todo FIXME: don't parse the file path every time */ const surface surf(image::get_image("cursors/" + color_images[current_cursor])); if(surf == NULL) { // Fall back to b&w cursors std::cerr << "could not load color cursors. Falling back to hardware cursors\n"; preferences::set_color_cursors(false); return; } if(cursor_buf != NULL && (cursor_buf->w != surf->w || cursor_buf->h != surf->h)) { cursor_buf = NULL; } if(cursor_buf == NULL) { cursor_buf = create_compatible_surface(surf); if(cursor_buf == NULL) { std::cerr << "Could not allocate surface for mouse cursor\n"; return; } } int new_cursor_x, new_cursor_y; SDL_GetMouseState(&new_cursor_x,&new_cursor_y); const bool must_update = new_cursor_x != cursor_x || new_cursor_y != cursor_y; cursor_x = new_cursor_x; cursor_y = new_cursor_y; // Save the screen area where the cursor is being drawn onto the back buffer SDL_Rect area = sdl::create_rect(cursor_x - shift_x[current_cursor] , cursor_y - shift_y[current_cursor] , surf->w , surf->h); sdl_copy_portion(screen,&area,cursor_buf,NULL); // Blit the surface sdl_blit(surf,NULL,screen,&area); if(must_update) { update_rect(area); } }