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); } }
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; }
rect intersection_rect(const rect& a, const rect& b) { const int x = std::max(a.x(), b.x()); const int y = std::max(a.y(), b.y()); const int w = std::max(0, std::min(a.x2(), b.x2()) - x); const int h = std::max(0, std::min(a.y2(), b.y2()) - y); return rect(x, y, w, h); }
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; }
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); }
void Surface::fillRect(const rect& dst_rect, const Color& color) { // XXX do we need to consider ARGB/RGBA ordering issues here. ASSERT_LOG(dst_rect.x1() >= 0 && dst_rect.x1() <= width(), "destination co-ordinates out of bounds: " << dst_rect.x1() << " : (0," << width() << ")"); ASSERT_LOG(dst_rect.x2() >= 0 && dst_rect.x2() <= width(), "destination co-ordinates out of bounds: " << dst_rect.x2() << " : (0," << width() << ")"); ASSERT_LOG(dst_rect.y1() >= 0 && dst_rect.y1() <= height(), "destination co-ordinates out of bounds: " << dst_rect.y1() << " : (0," << height() << ")"); ASSERT_LOG(dst_rect.y2() >= 0 && dst_rect.y2() <= height(), "destination co-ordinates out of bounds: " << dst_rect.y2() << " : (0," << height() << ")"); unsigned char* pix = reinterpret_cast<unsigned char*>(pixelsWriteable()); const int bpp = pf_->bytesPerPixel(); for(int y = dst_rect.x1(); y < dst_rect.x2(); ++y) { for(int x = dst_rect.y1(); x < dst_rect.y2(); ++x) { unsigned char* p = &pix[(y * width() + x) * bpp]; // XXX FIXME //uint32_t pixels; //pf_->encodeRGBA(&pixels, color.r(), color.g(), color.b(), color.a()); switch(bpp) { case 1: p[0] = color.r_int(); break; case 2: p[0] = color.r_int(); p[1] = color.g_int(); break; case 3: p[0] = color.r_int(); p[1] = color.g_int(); p[2] = color.b_int(); break; case 4: p[0] = color.r_int(); p[1] = color.g_int(); p[2] = color.b_int(); p[3] = color.a_int(); break; } } } }
bool entity_collides_with_entity(const entity& e, const entity& other, collision_info* info) { if((e.solid_dimensions()&other.weak_solid_dimensions()) == 0 && (e.weak_solid_dimensions()&other.solid_dimensions()) == 0) { return false; } const rect& our_rect = e.solid_rect(); const rect& other_rect = other.solid_rect(); if(!rects_intersect(our_rect, other_rect)) { return false; } if(other.destroyed()) { return false; } const rect area = intersection_rect(our_rect, other_rect); const solid_info* our_solid = e.solid(); const solid_info* other_solid = other.solid(); assert(our_solid && other_solid); const frame& our_frame = e.current_frame(); const frame& other_frame = other.current_frame(); for(int y = area.y(); y <= area.y2(); ++y) { for(int x = area.x(); x < area.x2(); ++x) { const int our_x = e.face_right() ? x - e.x() : (e.x() + our_frame.width()-1) - x; const int our_y = y - e.y(); if(our_solid->solid_at(our_x, our_y, info ? &info->area_id : NULL)) { const int other_x = other.face_right() ? x - other.x() : (other.x() + other_frame.width()-1) - x; const int other_y = y - other.y(); if(other_solid->solid_at(other_x, other_y, info ? &info->collide_with_area_id : NULL)) { return true; } } } } return false; }
explicit SimpleRenderable(const rect& r, const KRE::Color& color) : KRE::SceneObject("simple_renderable") { init(); setColor(color); const float vx1 = static_cast<float>(r.x1()); const float vy1 = static_cast<float>(r.y1()); const float vx2 = static_cast<float>(r.x2()); const float vy2 = static_cast<float>(r.y2()); std::vector<glm::vec2> vc; vc.emplace_back(vx1, vy2); vc.emplace_back(vx1, vy1); vc.emplace_back(vx2, vy1); vc.emplace_back(vx2, vy1); vc.emplace_back(vx2, vy2); vc.emplace_back(vx1, vy2); attribs_->update(&vc); }
void window::submit_delayed_expose( const rect &r ) { /// \todo { Need to fix the local vs screen coordinates } RECT rect = { LONG( std::floor( r.x1() ) ), LONG( std::floor( r.y1() ) ), LONG( std::ceil( r.x2() ) ), LONG( std::ceil( r.y2() ) ) }; if ( rect.left == rect.top && rect.left == rect.right && rect.left == rect.bottom ) RedrawWindow( _hwnd, NULL, NULL, RDW_INTERNALPAINT|RDW_UPDATENOW ); else RedrawWindow( _hwnd, &rect, NULL, RDW_INVALIDATE|RDW_UPDATENOW ); }
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); }
bool point_in_rect(const point& p, const rect& r) { return p.x >= r.x() && p.y >= r.y() && p.x < r.x2() && p.y < r.y2(); }