void part_ui::render_background() { #if SDL_VERSION_ATLEAST(2,0,0) sdl::twindow *wnd = CVideo::get_window(); wnd->fill(0, 0, 0); for (size_t i = 0; i<background_images_.size(); i++) { const int x = background_positions_[i].first; const int y = background_positions_[i].second; wnd->draw(background_images_[i], x, y); } #else #ifdef SDL_GPU GPU_Target *target = get_render_target(); GPU_Clear(target); for (size_t i = 0; i<background_images_.size(); i++) { const int x = background_positions_[i].first; const int y = background_positions_[i].second; background_images_[i].draw(*target, x, y); } #else sdl::draw_solid_tinted_rectangle( 0, 0, video_.getx(), video_.gety(), 0, 0, 0, 1.0, video_.getSurface() ); sdl_blit(background_, NULL, video_.getSurface(), NULL); #endif #endif }
void loadscreen::clear_screen() { #ifdef SDL_GPU GPU_Clear(get_render_target()); #else int scrx = screen_.getx(); // Screen width. int scry = screen_.gety(); // Screen height. SDL_Rect area = sdl::create_rect(0, 0, scrx, scry); // Screen area. surface disp(screen_.getSurface()); // Screen surface. // Make everything black. sdl::fill_rect(disp,&area,SDL_MapRGB(disp->format,0,0,0)); update_whole_screen(); screen_.flip(); #endif }
void part_ui::render_story_box() { #ifdef SDL_GPU LOG_NG << "ENTER part_ui()::render_story_box()\n"; GPU_Target *target = get_render_target(); const std::string& storytxt = p_.text(); if(storytxt.empty()) { video_.flip(); wait_for_input(); return; } const part::BLOCK_LOCATION tbl = p_.story_text_location(); const int max_width = buttons_x_ - storybox_padding - text_x_; const int max_height = screen_area().h - storybox_padding; skip_ = false; last_key_ = true; font::ttext t; if(!t.set_text(p_.text(), true)) { ERR_NG << "Text: Invalid markup in '" << p_.text() << "' rendered as is.\n"; t.set_text(p_.text(), false); } t.set_font_style(font::ttext::STYLE_NORMAL) .set_font_size(storybox_font_size) .set_foreground_color(storybox_font_color) .set_maximum_width(max_width) .set_maximum_height(max_height, true); sdl::timage txttxt = t.render_as_texture(); if(txttxt.null()) { ERR_NG << "storyscreen text area rendering resulted in a null texture" << std::endl; return; } int fix_text_y = text_y_; if(fix_text_y + 2*(storybox_padding+1) + txttxt.height() > screen_area().h && tbl != part::BLOCK_TOP) { fix_text_y = (screen_area().h > txttxt.height() + 1) ? (std::max(0, screen_area().h - txttxt.height() - 2*(storybox_padding+1))) : (0); } int fix_text_h; switch(tbl) { case part::BLOCK_TOP: fix_text_h = std::max(txttxt.height() + 2*storybox_padding, screen_area().h/4); break; case part::BLOCK_MIDDLE: fix_text_h = std::max(txttxt.height() + 2*storybox_padding, screen_area().h/3); break; default: fix_text_h = screen_area().h - fix_text_y; break; } SDL_Rect update_area = sdl::create_rect(0 , fix_text_y , screen_area().w , fix_text_h); /* do */ { // this should kill the tiniest flickering caused // by the buttons being hidden and unhidden in this scope. update_locker locker(video_); next_button_.hide(); back_button_.hide(); play_button_.hide(); //TODO: blurring const SDL_Rect box = sdl::create_rect(0, fix_text_y, screen_area().w, fix_text_h); sdl::fill_rect(*target, box, storyshadow_r, storyshadow_g, storyshadow_b, storyshadow_a); render_story_box_borders(update_area); // no-op if LOW_MEM is defined next_button_.hide(false); back_button_.hide(false); play_button_.hide(false); } // Time to do some f*****g visual effect. const int scan_height = 1, scan_width = txttxt.width(); SDL_Rect scan = sdl::create_rect(0, 0, scan_width, scan_height); SDL_Rect dstrect = sdl::create_rect(text_x_, 0, scan_width, scan_height); bool scan_finished = false; while(true) { scan_finished = scan.y >= txttxt.base_height(); if (!scan_finished) { dstrect.y = fix_text_y + scan.y + storybox_padding; txttxt.set_clip(scan); video_.draw_texture(txttxt, dstrect.x, dstrect.y); video_.flip(); ++scan.y; } else skip_ = true; if (handle_interface()) break; if (!skip_ || scan_finished) { disp_.delay(20); } } const SDL_Rect rect = sdl::create_rect(0, 0, video_.getx(), video_.gety()); sdl::fill_rect(*target, rect, 0, 0, 0, 255); #else LOG_NG << "ENTER part_ui()::render_story_box()\n"; const std::string& storytxt = p_.text(); if(storytxt.empty()) { update_whole_screen(); wait_for_input(); return; } const part::BLOCK_LOCATION tbl = p_.story_text_location(); const int max_width = buttons_x_ - storybox_padding - text_x_; const int max_height = screen_area().h - storybox_padding; skip_ = false; last_key_ = true; font::ttext t; if(!t.set_text(p_.text(), true)) { ERR_NG << "Text: Invalid markup in '" << p_.text() << "' rendered as is.\n"; t.set_text(p_.text(), false); } t.set_font_style(font::ttext::STYLE_NORMAL) .set_font_size(storybox_font_size) .set_foreground_color(storybox_font_color) .set_maximum_width(max_width) .set_maximum_height(max_height, true); surface txtsurf = t.render(); if(txtsurf.null()) { ERR_NG << "storyscreen text area rendering resulted in a null surface" << std::endl; return; } int fix_text_y = text_y_; if(fix_text_y + 2*(storybox_padding+1) + txtsurf->h > screen_area().h && tbl != part::BLOCK_TOP) { fix_text_y = (screen_area().h > txtsurf->h + 1) ? (std::max(0, screen_area().h - txtsurf->h - 2*(storybox_padding+1))) : (0); } int fix_text_h; switch(tbl) { case part::BLOCK_TOP: fix_text_h = std::max(txtsurf->h + 2*storybox_padding, screen_area().h/4); break; case part::BLOCK_MIDDLE: fix_text_h = std::max(txtsurf->h + 2*storybox_padding, screen_area().h/3); break; default: fix_text_h = screen_area().h - fix_text_y; break; } SDL_Rect update_area = sdl::create_rect(0 , fix_text_y , screen_area().w , fix_text_h); /* do */ { // this should kill the tiniest flickering caused // by the buttons being hidden and unhidden in this scope. update_locker locker(video_); next_button_.hide(); back_button_.hide(); play_button_.hide(); #ifndef LOW_MEM blur_area(video_, fix_text_y, fix_text_h); #endif sdl::draw_solid_tinted_rectangle( 0, fix_text_y, screen_area().w, fix_text_h, storyshadow_r, storyshadow_g, storyshadow_b, storyshadow_opacity, video_.getSurface() ); render_story_box_borders(update_area); // no-op if LOW_MEM is defined next_button_.hide(false); back_button_.hide(false); play_button_.hide(false); } if(imgs_.empty()) { update_whole_screen(); } else if(update_area.h > 0) { update_rect(update_area); } // Time to do some f*****g visual effect. const int scan_height = 1, scan_width = txtsurf->w; SDL_Rect scan = sdl::create_rect(0, 0, scan_width, scan_height); SDL_Rect dstrect = sdl::create_rect(text_x_, 0, scan_width, scan_height); surface scan_dst = video_.getSurface(); bool scan_finished = false; while(true) { scan_finished = scan.y >= txtsurf->h; if (!scan_finished) { //dstrect.x = text_x_; dstrect.y = fix_text_y + scan.y + storybox_padding; // NOTE: ::blit_surface() screws up with antialiasing and hinting when // on backgroundless (e.g. black) screens; ttext::draw() // uses it nonetheless, no idea why... // Here we'll use CVideo::blit_surface() instead. video_.blit_surface(dstrect.x, dstrect.y, txtsurf, &scan); update_rect(dstrect); ++scan.y; } else skip_ = true; if (handle_interface()) break; if (!skip_ || scan_finished) { disp_.delay(20); } } sdl::draw_solid_tinted_rectangle( 0, 0, video_.getx(), video_.gety(), 0, 0, 0, 1.0, video_.getSurface() ); #endif }
void part_ui::render_title_box() { #ifdef SDL_GPU const std::string& titletxt = p_.title(); if(titletxt.empty()) { return; } GPU_Target *target = get_render_target(); int titlebox_x, titlebox_y, titlebox_max_w, titlebox_max_h; // We later correct these according to the storytext box location. // The text box is always aligned according to the base_rect_ // (effective background area) at the end. titlebox_x = titlebox_padding; titlebox_max_w = base_rect_.w - 2*titlebox_padding; titlebox_y = titlebox_padding; titlebox_max_h = base_rect_.h - 2*titlebox_padding; font::ttext t; if(!t.set_text(titletxt, true)) { ERR_NG << "Text: Invalid markup in '" << titletxt << "' rendered as is.\n"; t.set_text(titletxt, false); } t.set_font_style(font::ttext::STYLE_NORMAL) .set_font_size(titlebox_font_size) .set_foreground_color(titlebox_font_color) .set_maximum_width(titlebox_max_w) .set_maximum_height(titlebox_max_h, true); sdl::timage txttxt = t.render_as_texture(); if(txttxt.null()) { ERR_NG << "storyscreen titlebox rendering resulted in a null surface" << std::endl; return; } const int titlebox_w = txttxt.width(); const int titlebox_h = txttxt.height(); switch(p_.title_text_alignment()) { case part::TEXT_CENTERED: titlebox_x = base_rect_.w / 2 - titlebox_w / 2 - titlebox_padding; break; case part::TEXT_RIGHT: titlebox_x = base_rect_.w - titlebox_padding - titlebox_w; break; default: break; // already set before } // Translate to absolute position. titlebox_x += base_rect_.x; titlebox_y += base_rect_.y; const SDL_Rect box = sdl::create_rect( titlebox_x - titleshadow_padding, titlebox_y - titleshadow_padding, titlebox_w + 2*titleshadow_padding, titlebox_h + 2*titleshadow_padding ); sdl::fill_rect(*target, box, titleshadow_r, titleshadow_g, titleshadow_b, titleshadow_a); video_.draw_texture(txttxt, titlebox_x, titlebox_y); #else const std::string& titletxt = p_.title(); if(titletxt.empty()) { return; } int titlebox_x, titlebox_y, titlebox_max_w, titlebox_max_h; // We later correct these according to the storytext box location. // The text box is always aligned according to the base_rect_ // (effective background area) at the end. titlebox_x = titlebox_padding; titlebox_max_w = base_rect_.w - 2*titlebox_padding; titlebox_y = titlebox_padding; titlebox_max_h = base_rect_.h - 2*titlebox_padding; font::ttext t; if(!t.set_text(titletxt, true)) { ERR_NG << "Text: Invalid markup in '" << titletxt << "' rendered as is.\n"; t.set_text(titletxt, false); } t.set_font_style(font::ttext::STYLE_NORMAL) .set_font_size(titlebox_font_size) .set_foreground_color(titlebox_font_color) .set_maximum_width(titlebox_max_w) .set_maximum_height(titlebox_max_h, true); surface txtsurf = t.render(); if(txtsurf.null()) { ERR_NG << "storyscreen titlebox rendering resulted in a null surface" << std::endl; return; } const int titlebox_w = txtsurf->w; const int titlebox_h = txtsurf->h; switch(p_.title_text_alignment()) { case part::TEXT_CENTERED: titlebox_x = base_rect_.w / 2 - titlebox_w / 2 - titlebox_padding; break; case part::TEXT_RIGHT: titlebox_x = base_rect_.w - titlebox_padding - titlebox_w; break; default: break; // already set before } sdl::draw_solid_tinted_rectangle( base_rect_.x + titlebox_x - titleshadow_padding, base_rect_.y + titlebox_y - titleshadow_padding, titlebox_w + 2*titleshadow_padding, titlebox_h + 2*titleshadow_padding, titleshadow_r, titleshadow_g, titleshadow_b, titleshadow_opacity, video_.getSurface() ); video_.blit_surface(base_rect_.x + titlebox_x, base_rect_.y + titlebox_y, txtsurf); update_rect( static_cast<size_t>(std::max(0, base_rect_.x + titlebox_x)), static_cast<size_t>(std::max(0, base_rect_.y + titlebox_y)), static_cast<size_t>(std::max(0, titlebox_w)), static_cast<size_t>(std::max(0, titlebox_h)) ); #endif }
bool part_ui::render_floating_images() { #ifdef SDL_GPU GPU_Target *target = get_render_target(); skip_ = false; last_key_ = true; size_t fi_n = 0; BOOST_FOREACH(floating_image::render_input& ri, imgs_) { const floating_image& fi = p_.get_floating_images()[fi_n]; if(!ri.image.null()) { ri.image.draw(*target, ri.rect.x, ri.rect.y); video_.flip(); } if (!skip_) { int delay = fi.display_delay(), delay_step = 20; for (int i = 0; i != (delay + delay_step - 1) / delay_step; ++i) { if (handle_interface()) return false; if (skip_) break; disp_.delay(std::min<int>(delay_step, delay - i * delay_step)); } } ++fi_n; } return true; #else events::raise_draw_event(); update_whole_screen(); skip_ = false; last_key_ = true; size_t fi_n = 0; BOOST_FOREACH(floating_image::render_input& ri, imgs_) { const floating_image& fi = p_.get_floating_images()[fi_n]; if(!ri.image.null()) { sdl_blit(ri.image, NULL, video_.getSurface(), &ri.rect); update_rect(ri.rect); } if (!skip_) { int delay = fi.display_delay(), delay_step = 20; for (int i = 0; i != (delay + delay_step - 1) / delay_step; ++i) { if (handle_interface()) return false; if (skip_) break; disp_.delay(std::min<int>(delay_step, delay - i * delay_step)); } } ++fi_n; } return true; #endif }