Example #1
0
part_ui::RESULT part_ui::show()
{
	if(p_.music().empty() != true) {
		sound::play_music_repeatedly(p_.music());
	}

	if(p_.sound().empty() != true) {
		sound::play_sound(p_.sound());
	}

	render_background();

	if(p_.show_title()) {
		render_title_box();
	}

	if(!imgs_.empty()) {
		if(!render_floating_images()) {
			return ret_;
		}
	}

	try {
		render_story_box();
	}
	catch(utf8::invalid_utf8_exception const&) {
		ERR_NG << "invalid UTF-8 sequence in story text, skipping part..." << std::endl;
	}

	return ret_;
}
Example #2
0
void part_ui::render_story_box()
{
#ifdef SDL_GPU
	LOG_NG << "ENTER part_ui()::render_story_box()\n";

	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(video_, 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) {
			CVideo::delay(20);
		}
	}

	const SDL_Rect rect = sdl::create_rect(0, 0, video_.getx(), video_.gety());
	sdl::fill_rect(video_, rect, 0, 0, 0, SDL_ALPHA_OPAQUE);
#else

	LOG_NG<< "ENTER part_ui()::render_story_box()\n";
	bool first = true;

	render_background();

	if(p_.show_title()) {
		render_title_box();
	}

	if(!imgs_.empty()) {
		if(!render_floating_images()) {
			return;
		}
	}


	const std::string& storytxt = p_.text();
	if(storytxt.empty()) {
		wait_for_input();
		return;
	}

	skip_ = false;
	last_key_ = true;
	font::ttext t;
	bool scan_finished = false;
	SDL_Rect scan;
	SDL_Rect dstrect;


	while(true) {

		if (dirty_) {

			render_background();

			if(p_.show_title()) {
				render_title_box();
			}

			if(!imgs_.empty()) {
				if(!render_floating_images()) {
					return;
				}
			}
		}

		part::BLOCK_LOCATION tbl = p_.story_text_location();
		int max_width = buttons_x_ - storybox_padding - text_x_;
		int max_height = screen_area().h - storybox_padding;

		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
			if (dirty_ || first) {
				blur_area(video_, fix_text_y, fix_text_h);
			}
#endif
			if (dirty_ || first) {
				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 (dirty_ || first) {
			if(!imgs_.empty() && update_area.h > 0) {
				update_rect(update_area);
			}
		}

		// Time to do some visual effecta.
		if (dirty_ || first) {
			const int scan_height = 1, scan_width = txtsurf->w;
			scan = sdl::create_rect(0, 0, scan_width, scan_height);
			dstrect = sdl::create_rect(text_x_, 0, scan_width, scan_height);
		}

		/* This needs to happen before poll for events */
		dirty_ = false;
		first = false;

		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) {
			CVideo::delay(20);
		}

	}

	sdl::draw_solid_tinted_rectangle(
			0, 0, video_.getx(), video_.gety(), 0, 0, 0,
			1.0, video_.getSurface()
	);
#endif
}