示例#1
0
	void dialog::handle_draw(const rect& r, float rotation, float scale) const
	{
		for(auto& tex : bg_) {
			ASSERT_LOG(tex.is_valid(), "Texture isn't valid.");
		}
		// XXX move all the rect calculations to recalc_dimensions() and store rects.
		// like in the texture.
		
		auto& tl = bg_[static_cast<int>(BackgroundSections::CORNER_TL)];
		tl.blit_ex(rect(r.x(), r.y(), tl.width(), tl.height()) * scale, rotation, r.mid() * scale, graphics::FlipFlags::NONE);
		auto& tr = bg_[static_cast<int>(BackgroundSections::CORNER_TR)];
		tr.blit_ex(rect(r.x2() - tr.width(), r.y(), tr.width(), tr.height()) * scale, rotation, r.mid() * scale, graphics::FlipFlags::NONE);
		auto& bl = bg_[static_cast<int>(BackgroundSections::CORNER_BL)];
		bl.blit_ex(rect(r.x(), r.y2() - bl.height(), bl.width(), bl.height()) * scale, rotation, r.mid() * scale, graphics::FlipFlags::NONE);
		auto& br = bg_[static_cast<int>(BackgroundSections::CORNER_BR)];
		br.blit_ex(rect(r.x2() - br.width(), r.y2() - br.height(), br.width(), br.height()) * scale, rotation, r.mid() * scale, graphics::FlipFlags::NONE);
		auto& cc = bg_[static_cast<int>(BackgroundSections::CENTER)];
		cc.blit_ex(rect(r.x()+tl.width(), r.y()+tl.height(), r.w() - br.width() - tl.width(), r.h() - br.height() - tl.height()) * scale, rotation, r.mid() * scale, graphics::FlipFlags::NONE);
		auto& sl = bg_[static_cast<int>(BackgroundSections::SIDE_LEFT)];
		sl.blit_ex(rect(r.x(), r.y()+tl.height(), tl.width(), r.h()-bl.height()-tl.height()) * scale, rotation, r.mid() * scale, graphics::FlipFlags::NONE);
		auto& sr = bg_[static_cast<int>(BackgroundSections::SIDE_RIGHT)];
		sr.blit_ex(rect(r.x2() - sr.width(), r.y() + tr.height(), sr.width(), r.h()-tr.height()-br.height()) * scale, rotation, r.mid() * scale, graphics::FlipFlags::NONE);
		auto& st = bg_[static_cast<int>(BackgroundSections::SIDE_TOP)];
		st.blit_ex(rect(r.x() + tl.width(), r.y(), r.w() - tl.width() - tr.width(), st.height()) * scale, rotation, r.mid() * scale, graphics::FlipFlags::NONE);
		auto& sb = bg_[static_cast<int>(BackgroundSections::SIDE_BOTTOM)];
		sb.blit_ex(rect(r.x() + br.width(), r.y2() - sb.height(), r.w() - bl.width() - br.width(), sb.height()) * scale, rotation, r.mid() * scale, graphics::FlipFlags::NONE);

		for(auto& w : children_) {
			w->draw(r, rotation, scale);
		}
	}
示例#2
0
void queue_draw_from_tilesheet(graphics::blit_queue& q, const graphics::texture& t, const rect& area, int tile_num, int x, int y, bool reverse)
{
	if(tile_num < 0 || area.w() <= 0 || area.h() <= 0 || area.x() < 0 || area.y() < 0) {
		return;
	}

	q.set_texture(t.get_id());

	const int width = std::max<int>(t.width(), t.height());
	const int xpos = 16*(tile_num%(width/16)) + area.x();
	const int ypos = 16*(tile_num/(width/16)) + area.y();

	//a value we subtract from the width and height of tiles when calculating
	//UV co-ordinates. This is to prevent floating point rounding errors
	//from causing us to draw slightly outside the tile. This is pretty
	//nasty stuff though, and I'm not sure of a better way to do it. :(
	const GLfloat TileEpsilon = 0.01;
	GLfloat x1 = t.translate_coord_x(GLfloat(xpos)/GLfloat(t.width()));
	GLfloat x2 = t.translate_coord_x(GLfloat(xpos+area.w() - TileEpsilon)/GLfloat(t.width()));
	const GLfloat y1 = t.translate_coord_y(GLfloat(ypos)/GLfloat(t.height()));
	const GLfloat y2 = t.translate_coord_y(GLfloat(ypos+area.h() - TileEpsilon)/GLfloat(t.height()));

	int area_x = area.x()*2;
	if(reverse) {
		std::swap(x1, x2);
		area_x = 32 - area.x()*2 - area.w()*2;
	}

	x += area_x;
	y += area.y()*2;
	q.add(x, y, x1, y1);
	q.add(x, y + area.h()*2, x1, y2);
	q.add(x + area.w()*2, y, x2, y1);
	q.add(x + area.w()*2, y + area.h()*2, x2, y2);
}
示例#3
0
	void DisplayDeviceOpenGL::setViewPort(const rect& vp)
	{
		if(get_current_viewport() != vp && vp.w() != 0 && vp.h() != 0) {
			get_current_viewport() = vp;
			// N.B. glViewPort has the origin in the bottom-left corner. 
			glViewport(vp.x(), vp.y(), vp.w(), vp.h());
		}
	}
示例#4
0
int get_tile_corners(tile_corner* result, const graphics::texture& t, const rect& area, int tile_num, int x, int y, bool reverse)
{
	if(tile_num < 0 || area.w() <= 0 || area.h() <= 0 || area.x() < 0 || area.y() < 0) {
		return 0;
	}

	const int width = std::max<int>(t.width(), t.height());
	if (width == 0) return 0;
	
	const int xpos = 16*(tile_num%(width/16)) + area.x();
	const int ypos = 16*(tile_num/(width/16)) + area.y();

	//a value we subtract from the width and height of tiles when calculating
	//UV co-ordinates. This is to prevent floating point rounding errors
	//from causing us to draw slightly outside the tile. This is pretty
	//nasty stuff though, and I'm not sure of a better way to do it. :(
	const GLfloat TileEpsilon = 0.1;
	GLfloat x1 = t.translate_coord_x(GLfloat(xpos + TileEpsilon)/GLfloat(t.width()));
	GLfloat x2 = t.translate_coord_x(GLfloat(xpos+area.w() - TileEpsilon)/GLfloat(t.width()));
	const GLfloat y1 = t.translate_coord_y(GLfloat(ypos + TileEpsilon)/GLfloat(t.height()));
	const GLfloat y2 = t.translate_coord_y(GLfloat(ypos+area.h() - TileEpsilon)/GLfloat(t.height()));

	int area_x = area.x()*2;
	if(reverse) {
		std::swap(x1, x2);
		area_x = 32 - area.x()*2 - area.w()*2;
	}

	x += area_x;
	y += area.y()*2;

	result->vertex[0] = x;
	result->vertex[1] = y;
	result->uv[0] = x1;
	result->uv[1] = y1;
	++result;

	result->vertex[0] = x;
	result->vertex[1] = y + area.h()*2;
	result->uv[0] = x1;
	result->uv[1] = y2;
	++result;

	result->vertex[0] = x + area.w()*2;
	result->vertex[1] = y;
	result->uv[0] = x2;
	result->uv[1] = y1;
	++result;

	result->vertex[0] = x + area.w()*2;
	result->vertex[1] = y + area.h()*2;
	result->uv[0] = x2;
	result->uv[1] = y2;
	++result;

	return 4;
}
示例#5
0
void rotate_rect(const rect& r, GLfloat angle, GLshort* output){
	
	point offset;
	offset.x = r.x() + r.w()/2;
	offset.y = r.y() + r.h()/2;

	point p;

	p = rotate_point_around_origin_with_offset( r.x(), r.y(), angle, offset.x, offset.y );
	output[0] = p.x;
	output[1] = p.y;

	p = rotate_point_around_origin_with_offset( r.x2(), r.y(), angle, offset.x, offset.y );
	output[2] = p.x;
	output[3] = p.y;

	p = rotate_point_around_origin_with_offset( r.x2(), r.y2(), angle, offset.x, offset.y );
	output[4] = p.x;
	output[5] = p.y;

	p = rotate_point_around_origin_with_offset( r.x(), r.y2(), angle, offset.x, offset.y );
	output[6] = p.x;
	output[7] = p.y;

}
示例#6
0
bool rects_intersect(const rect& a, const rect& b)
{
	if(a.x2() <= b.x() || b.x2() <= a.x()) {
		return false;
	}

	if(a.y2() <= b.y() || b.y2() <= a.y()) {
		return false;
	}

	if(a.w() == 0 || a.h() == 0 || b.w() == 0 || b.h() == 0) {
		return false;
	}
	
	return true;
}
示例#7
0
message_dialog::message_dialog(const std::string& text, const rect& pos,
                               const std::vector<std::string>* options)
  : text_(text), pos_(pos), line_height_(0),
    cur_row_(0), cur_char_(0), cur_wait_(0),
	selected_option_(0)
{
	line_height_ = font::char_height(FontSize);
	viewable_lines_ = pos.h()/line_height_;
	if(viewable_lines_ < 1) {
		viewable_lines_ = 1;
	}

	const int max_chars_on_line = std::max<int>(1, pos.w()/font::char_width(FontSize));
	std::string::const_iterator i1 = text.begin();
	std::string::const_iterator i2 = i1;
	while(i2 != text.end()) {
		i2 = get_line(i2, text.end(), max_chars_on_line);
		if(i2 == i1) {
			break;
		}

		while(i1 != i2 && util::isspace(*i1)) {
			++i1;
		}

		lines_.push_back(font::render_text(std::string(i1, i2), graphics::color_black(), FontSize));
		i1 = i2;
	}

	if(options != NULL) {
		foreach(const std::string& option, *options) {
			options_.push_back(font::render_text(option, graphics::color_black(), FontSize));
		}
	}
示例#8
0
code_editor_dialog::code_editor_dialog(const rect& r)
  : dialog(r.x(), r.y(), r.w(), r.h()), invalidated_(0), has_error_(false),
    modified_(false), file_contents_set_(true), suggestions_prefix_(-1),
	have_close_buttons_(false)
{
	init();
}
示例#9
0
rect rect_union(const rect& a, const rect& b)
{
	if(a.w() == 0 || a.h() == 0) {
		return b;
	}

	if(b.w() == 0 || b.h() == 0) {
		return a;
	}

	const int x = std::min<int>(a.x(), b.x());
	const int y = std::min<int>(a.y(), b.y());
	const int x2 = std::max<int>(a.x2(), b.x2());
	const int y2 = std::max<int>(a.y2(), b.y2());

	return rect(x, y, x2 - x, y2 - y);
}
示例#10
0
	void draw_rect(const rect& r, const graphics::color& color)
	{
		glDisable(GL_TEXTURE_2D);
		glDisableClientState(GL_TEXTURE_COORD_ARRAY);
		glColor4ub(color.r(),color.g(),color.b(),color.a());
		GLfloat varray[] = {
			r.x(), r.y(),
			r.x()+r.w(), r.y(),
			r.x(), r.y()+r.h(),
			r.x()+r.w(), r.y()+r.h()
		};
		glVertexPointer(2, GL_FLOAT, 0, varray);
		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
		//glRecti(r.x(),r.y(),r.x()+r.w(),r.y()+r.h());
		glColor4ub(255, 255, 255, 255);
		glEnableClientState(GL_TEXTURE_COORD_ARRAY);
		glEnable(GL_TEXTURE_2D);
	}
示例#11
0
point entity::midpoint() const
{
	if(solid()) {
		const rect r = solid_rect();
		return point(r.x() + r.w()/2, r.y() + r.h()/2);
	}

	const frame& f = current_frame();
	return point(x() + f.width()/2, y() + f.height()/2);
}
示例#12
0
graphics::texture render_fbo(const rect& area, const std::vector<entity_ptr> objects)
{
	const controls::control_backup_scope ctrl_backup;

	const int tex_width = graphics::texture::allows_npot() ? area.w() : graphics::texture::next_power_of_2(area.w());
	const int tex_height = graphics::texture::allows_npot() ? area.h() : graphics::texture::next_power_of_2(area.h());
	GLint video_framebuffer_id = 0;
	glGetIntegerv(EXT_MACRO(GL_FRAMEBUFFER_BINDING), &video_framebuffer_id);

	GLuint texture_id = 0;
	glGenTextures(1, &texture_id);
	glBindTexture(GL_TEXTURE_2D, texture_id);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_width, tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glBindTexture(GL_TEXTURE_2D, 0);

	GLuint framebuffer_id = 0;
	EXT_CALL(glGenFramebuffers)(1, &framebuffer_id);
	EXT_CALL(glBindFramebuffer)(EXT_MACRO(GL_FRAMEBUFFER), framebuffer_id);

	// attach the texture to FBO color attachment point
	EXT_CALL(glFramebufferTexture2D)(EXT_MACRO(GL_FRAMEBUFFER), EXT_MACRO(GL_COLOR_ATTACHMENT0),
                          GL_TEXTURE_2D, texture_id, 0);

	// check FBO status
	GLenum status = EXT_CALL(glCheckFramebufferStatus)(EXT_MACRO(GL_FRAMEBUFFER));
	ASSERT_NE(status, EXT_MACRO(GL_FRAMEBUFFER_UNSUPPORTED));
	ASSERT_EQ(status, EXT_MACRO(GL_FRAMEBUFFER_COMPLETE));

	glViewport(0, 0, area.w(), area.h());

	level_ptr lvl(new level("empty.cfg"));
	foreach(const entity_ptr& e, objects) {
		lvl->add_character(e);
		lvl->add_draw_character(e);
	}
示例#13
0
int rect_difference(const rect& a, const rect& b, rect* output)
{
	if (rects_intersect(a,b) == false){  //return empty if there's no intersection
		return -1;
	}
		
	/* returning 4 rectangles in this orientation:
	 _________
	 | |___| |
	 | |   | |
	 | |___| |
	 |_|___|_|  */

	const rect* begin_output = output;

	if(a.x() < b.x()) {
		//get the left section of the source rectangle
		*output++ = rect(a.x(), a.y(), b.x() - a.x(), a.h());
	}

	if(a.x() + a.w() > b.x() + b.w()) {
		*output++ = rect(b.x() + b.w(), a.y(), (a.x() + a.w()) - (b.x() + b.w()), a.h());
	}

	if(a.y() < b.y()) {
		const int x1 = std::max(a.x(), b.x());
		const int x2 = std::min(a.x() + a.w(), b.x() + b.w());
		*output++ = rect(x1, a.y(), x2 - x1, b.y() - a.y());
	}

	if(a.y() + a.h() > b.y() + b.h()) {
		const int x1 = std::max(a.x(), b.x());
		const int x2 = std::min(a.x() + a.w(), b.x() + b.w());
		*output++ = rect(x1, b.y() + b.h(), x2 - x1, (a.y() + a.h()) - (b.y() + b.h()));
	}
	
	return output - begin_output;
}
示例#14
0
	bool SurfaceSDL::setClipRect(const rect& r)
	{
		ASSERT_LOG(surface_ != nullptr, "surface_ is null");
		SDL_Rect sr = {r.x(), r.y(), r.w(), r.h()};
		return SDL_SetClipRect(surface_, &sr) == SDL_TRUE;
	}
void animation_preview_widget::handle_draw() const
{
	graphics::draw_rect(rect(x(),y(),width(),height()), graphics::color(0,0,0,196));
	rect image_area(x(), y(), (width()*3)/4, height() - 30);
	const graphics::texture image_texture(graphics::texture::get(obj_["image"].as_string()));
	if(image_texture.valid()) {
		const graphics::clip_scope clipping_scope(image_area.sdl_rect());

		const rect focus_area(frame_->area().x(), frame_->area().y(),
		      (frame_->area().w() + frame_->pad())*frame_->num_frames_per_row(),
			  (frame_->area().h() + frame_->pad())*(frame_->num_frames()/frame_->num_frames_per_row() + (frame_->num_frames()%frame_->num_frames_per_row() ? 1 : 0)));

		GLfloat scale = 2.0;
		for(int n = 0; n != abs(scale_); ++n) {
			scale *= (scale_ < 0 ? 0.5 : 2.0);
		}

		while(image_area.w()*scale*2.0 < image_area.w() &&
		      image_area.h()*scale*2.0 < image_area.h()) {
			scale *= 2.0;
			scale_++;
			update_zoom_label();
		}
		
		while(focus_area.w()*scale > image_area.w() ||
		      focus_area.h()*scale > image_area.h()) {
			scale *= 0.5;
			scale_--;
			update_zoom_label();
		}

		const int show_width = image_area.w()/scale;
		const int show_height = image_area.h()/scale;

		int x1 = focus_area.x() + (focus_area.w() - show_width)/2;
		int y1 = focus_area.y() + (focus_area.h() - show_height)/2;
		int x2 = x1 + show_width;
		int y2 = y1 + show_height;

		int xpos = image_area.x();
		int ypos = image_area.y();

		src_rect_ = rect(x1, y1, x2 - x1, y2 - y1);
		dst_rect_ = rect(xpos, ypos, (x2-x1)*scale, (y2-y1)*scale);

		graphics::blit_texture(image_texture, xpos, ypos,
		                       (x2-x1)*scale, (y2-y1)*scale, 0.0,
							   GLfloat(x1)/image_texture.width(),
							   GLfloat(y1)/image_texture.height(),
							   GLfloat(x2)/image_texture.width(),
							   GLfloat(y2)/image_texture.height());

		for(int n = 0; n != frame_->num_frames(); ++n) {
			const int row = n/frame_->num_frames_per_row();
			const int col = n%frame_->num_frames_per_row();
			const int x = xpos - x1*scale + (frame_->area().x() + col*(frame_->area().w()+frame_->pad()))*scale;
			const int y = ypos - y1*scale + (frame_->area().y() + row*(frame_->area().h()+frame_->pad()))*scale;
			const rect box(x, y, frame_->area().w()*scale, frame_->area().h()*scale);
			graphics::draw_hollow_rect(box.sdl_rect(), n == 0 ? graphics::color_yellow() : graphics::color_white(), frame_->frame_number(cycle_) == n ? 0xFF : 0x88);
		}

		int mousex, mousey;
		if(anchor_x_ != -1 && SDL_GetMouseState(&mousex, &mousey) &&
		   point_in_rect(point(mousex, mousey), dst_rect_)) {
			const point p1 = mouse_point_to_image_loc(point(mousex, mousey));
			const point p2 = mouse_point_to_image_loc(point(anchor_x_, anchor_y_));

			int xpos1 = xpos - x1*scale + p1.x*scale;
			int xpos2 = xpos - x1*scale + p2.x*scale;
			int ypos1 = ypos - y1*scale + p1.y*scale;
			int ypos2 = ypos - y1*scale + p2.y*scale;
			
			if(xpos2 < xpos1) {
				std::swap(xpos1, xpos2);
			}

			if(ypos2 < ypos1) {
				std::swap(ypos1, ypos2);
			}
			
			rect area(xpos1, ypos1, xpos2 - xpos1, ypos2 - ypos1);
			graphics::draw_hollow_rect(area.sdl_rect(), graphics::color_white());
		}
	}

	rect preview_area(x() + (width()*3)/4, y(), width()/4, height());
	GLfloat scale = 1.0;
	while(false && (frame_->width()*scale > preview_area.w() || frame_->height()*scale > preview_area.h())) {
		scale *= 0.5;
	}

	frame_->draw(
	  preview_area.x() + (preview_area.w() - frame_->width()*scale)/2,
	  preview_area.y() + (preview_area.h() - frame_->height()*scale)/2,
	  true, false, cycle_, 0, scale);
	if(++cycle_ >= frame_->duration()) {
		cycle_ = 0;
	}

	foreach(const_widget_ptr w, widgets_) {
		w->draw();
	}
}
示例#16
0
inline bool operator==(const rect& a, const rect& b) {
	return a.x() == b.x() && a.y() == b.y() && a.w() == b.w() && a.h() == b.h();
}
示例#17
0
code_editor_dialog::code_editor_dialog(const rect& r)
  : dialog(r.x(), r.y(), r.w(), r.h()), invalidated_(0), modified_(false),
    suggestions_prefix_(-1)
{
	init();
}
示例#18
0
code_editor_dialog::code_editor_dialog(const rect& r)
    : dialog(r.x(), r.y(), r.w(), r.h()), invalidated_(0), modified_(false)
{
    init();
}
示例#19
0
void speech_dialog::draw() const
{
	static const const_gui_section_ptr top_corner = gui_section::get("speech_dialog_top_corner");
	static const const_gui_section_ptr bottom_corner = gui_section::get("speech_dialog_bottom_corner");
	static const const_gui_section_ptr top_edge = gui_section::get("speech_dialog_top_edge");
	static const const_gui_section_ptr bottom_edge = gui_section::get("speech_dialog_bottom_edge");
	static const const_gui_section_ptr side_edge = gui_section::get("speech_dialog_side_edge");
	static const const_gui_section_ptr arrow = gui_section::get("speech_dialog_arrow");

	const_graphical_font_ptr font = graphical_font::get("default");

	const int TextAreaHeight = 80;

	const int TextBorder = 10;

	int speaker_xpos = INT_MAX;
	int speaker_ypos = INT_MAX;

	const_entity_ptr speaker = left_side_speaking_ ? left_ : right_;
	if(speaker) {
		const screen_position& pos = last_draw_position();
		const int screen_x = pos.x/100 + (graphics::screen_width()/2)*(-1.0/pos.zoom + 1.0);
		const int screen_y = pos.y/100 + (graphics::screen_height()/2)*(-1.0/pos.zoom + 1.0);

		speaker_xpos = (speaker->feet_x() - screen_x)*pos.zoom - 36;
		speaker_ypos = (speaker->feet_y() - screen_y)*pos.zoom - 10;
	}

	if(pane_area_.w() == 0) {
		pane_area_ = rect(
		  top_corner->width(),
		  preferences::virtual_screen_height() - TextAreaHeight + TextBorder,
		  preferences::virtual_screen_width() - top_corner->width()*2,
		  TextAreaHeight - bottom_corner->height());
		if(speaker_ypos < 100) {
			pane_area_ = rect(pane_area_.x(), top_corner->height() + 50, pane_area_.w(), pane_area_.h());
		}
	}

	const rect text_area(pane_area_.x()-30, pane_area_.y()-30, pane_area_.w()+60, pane_area_.h()+60);

	graphics::draw_rect(pane_area_, graphics::color(85, 53, 53, 255));
	top_corner->blit(pane_area_.x() - top_corner->width(), pane_area_.y() - top_corner->height());
	top_corner->blit(pane_area_.x2()-1, pane_area_.y() - top_corner->height(), -top_corner->width(), top_corner->height());

	top_edge->blit(pane_area_.x(), pane_area_.y() - top_edge->height(), pane_area_.w(), top_edge->height());

	bottom_corner->blit(pane_area_.x() - bottom_corner->width(), pane_area_.y2());
	bottom_corner->blit(pane_area_.x2()-1, pane_area_.y2(), -bottom_corner->width(), bottom_corner->height());

	bottom_edge->blit(pane_area_.x(), pane_area_.y2(), pane_area_.w(), bottom_edge->height());

	side_edge->blit(pane_area_.x() - side_edge->width(), pane_area_.y(), side_edge->width(), pane_area_.h());
	side_edge->blit(pane_area_.x2()-1, pane_area_.y(), -side_edge->width(), pane_area_.h());

	if(speaker) {

		//if the arrow to the speaker is within reasonable limits, then
		//blit it.
		if(speaker_xpos > top_corner->width() && speaker_xpos < graphics::screen_width() - top_corner->width() - arrow->width()) {
			arrow->blit(speaker_xpos, pane_area_.y() - arrow->height() - 32);
		}
	}


	//we center our text. Create a vector of the left edge of the text.
	std::vector<int> text_left_align;

	int total_height = 0;
	for(int n = 0; n < text_.size(); ++n) {
		rect area = font->dimensions(text_[n]);

		if(n < 2) {
			total_height += area.h();
		}

		const int width = area.w();
		const int left = text_area.x() + text_area.w()/2 - width/2;
		text_left_align.push_back(left);
	}

	int ypos = text_area.y() + (text_area.h() - total_height)/2;
	int nchars = text_char_;
	for(int n = 0; n < 2 && n < text_.size() && nchars > 0; ++n) {
		std::string str(text_[n].begin(), text_[n].begin() +
		                  std::min<int>(nchars, text_[n].size()));
		//move the first line slightly up so that accents don't mess up centering
		rect area = font->dimensions(str);
		area = rect(text_left_align[n], ypos - 2, area.w(), area.h());

		//draw the font by chunks of markup.
		int xadj = 0;
		const std::vector<TextMarkup>& markup = markup_[n];
		for(int m = 0; m != markup.size(); ++m) {
			const int begin_index = markup[m].begin;
			const int end_index = std::min<int>(str.size(), m+1 == markup.size() ? str.size() : markup[m+1].begin);
			if(begin_index >= end_index) {
				continue;
			}

			if(markup[m].color) {
				markup[m].color->set_as_current_color();
			} else {
				//default color of fonts.
				glColor4ub(255, 187, 10, 255);
			}

			const rect r = font->draw(text_left_align[n] + xadj, ypos - 2, std::string(str.begin() + begin_index, str.begin() + end_index));
			xadj += r.w();
		}

		glColor4f(1.0, 1.0, 1.0, 1.0);
		//add some space between the lines
		ypos = area.y2() + 4;
		nchars -= text_[n].size();
	}

	if(text_.size() > 2 && text_char_ == num_chars() && (cycle_&16)) {
		const_gui_section_ptr down_arrow = gui_section::get("speech_text_down_arrow");
		down_arrow->blit(text_area.x2() - down_arrow->width() - 10, text_area.y2() - down_arrow->height() - 10);
		
	}

	if(text_char_ == num_chars() && options_.empty() == false) {
		//const_gui_section_ptr options_panel = gui_section::get("speech_portrait_pane");
		const_framed_gui_element_ptr options_panel = framed_gui_element::get("regular_window");
		int xpos = graphics::screen_width() - OptionsX - option_width_ - OptionsBorder*2;
		int ypos = graphics::screen_height() - OptionsY - OptionHeight*options_.size() - OptionsBorder*2;
		options_panel->blit(xpos, ypos, OptionsBorder*2 + option_width_, OptionsBorder*2 + OptionHeight*options_.size(), true);

		xpos += OptionsBorder + OptionXPad;
		ypos += OptionsBorder;

		glColor4ub(255, 187, 10, 255);
		int index = 0;
		foreach(const std::string& option, options_) {
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
			if(index == option_selected_) {
				graphics::draw_rect(rect(xpos-OptionXPad, ypos, option_width_, OptionHeight), graphics::color(0xC74545FF));
				glColor4ub(255, 187, 10, 255); //reset color to what it was, since draw_rect changes it
			}
#endif
			rect area = font->dimensions(option);
			area = font->draw(xpos, ypos+(OptionHeight/3-area.h()/4), option);

#if !TARGET_IPHONE_SIMULATOR && !TARGET_OS_IPHONE
			if(index == option_selected_) {
				const_gui_section_ptr cursor = gui_section::get("cursor");
				cursor->blit(area.x2(), area.y());
			}
#endif

			ypos += OptionHeight;
			++index;
		}
		glColor4f(1.0, 1.0, 1.0, 1.0);
	}
示例#20
0
	void SurfaceSDL::fillRect(const rect& dst_rect, const Color& color)
	{
		SDL_Rect r = {dst_rect.x(), dst_rect.y(), dst_rect.w(), dst_rect.h() };
		SDL_FillRect(surface_, &r, color.asARGB());
	}