BitmapRef Sprite::Refresh(Rect& rect) { if (zoom_x_effect != 1.0 && zoom_y_effect != 1.0 && angle_effect != 0.0 && waver_effect_depth != 0) { // TODO: Out of bounds check adjustments for zoom, angle and waver // but even without this will catch most of the cases if (Rect(x - ox, y - oy, GetWidth(), GetHeight()).IsOutOfBounds(Rect(0, 0, SCREEN_TARGET_WIDTH, SCREEN_TARGET_HEIGHT))) { return BitmapRef(); }; } rect.Adjust(bitmap->GetWidth(), bitmap->GetHeight()); bool no_tone = tone_effect == Tone(); bool no_flash = flash_effect.alpha == 0; bool no_flip = !flipx_effect && !flipy_effect; bool no_effects = no_tone && no_flash && no_flip; bool effects_changed = tone_effect != current_tone || flash_effect != current_flash || flipx_effect != current_flip_x || flipy_effect != current_flip_y; bool effects_rect_changed = rect != bitmap_effects_src_rect; if (effects_changed || effects_rect_changed || bitmap_changed) { bitmap_effects_valid = false; } if (no_effects) return bitmap; if (bitmap_effects && bitmap_effects_valid) return bitmap_effects; BitmapRef src_bitmap; if (no_effects) src_bitmap = bitmap; else if (bitmap_effects_valid) src_bitmap = bitmap_effects; else { current_tone = tone_effect; current_flash = flash_effect; current_flip_x = flipx_effect; current_flip_y = flipy_effect; if (bitmap_effects && bitmap_effects->GetWidth() < rect.x + rect.width && bitmap_effects->GetHeight() < rect.y + rect.height) { bitmap_effects.reset(); } if (!bitmap_effects) bitmap_effects = Bitmap::Create(bitmap->GetWidth(), bitmap->GetHeight(), true); bitmap_effects->Clear(); if (no_tone && no_flash) bitmap_effects->FlipBlit(rect.x, rect.y, *bitmap, rect, flipx_effect, flipy_effect, Opacity::opaque); else if (no_flip && no_flash) bitmap_effects->ToneBlit(rect.x, rect.y, *bitmap, rect, tone_effect, Opacity::opaque); else if (no_flip && no_tone) bitmap_effects->BlendBlit(rect.x, rect.y, *bitmap, rect, flash_effect, Opacity::opaque); else if (no_flash) { bitmap_effects->ToneBlit(rect.x, rect.y, *bitmap, rect, tone_effect, Opacity::opaque); bitmap_effects->Flip(rect, flipx_effect, flipy_effect); } else if (no_tone) { bitmap_effects->BlendBlit(rect.x, rect.y, *bitmap, rect, flash_effect, Opacity::opaque); bitmap_effects->Flip(rect, flipx_effect, flipy_effect); } else if (no_flip) { bitmap_effects->ToneBlit(rect.x, rect.y, *bitmap, rect, tone_effect, Opacity::opaque); bitmap_effects->BlendBlit(rect.x, rect.y, *bitmap_effects, rect, flash_effect, Opacity::opaque); } else { bitmap_effects->ToneBlit(rect.x, rect.y, *bitmap, rect, tone_effect, Opacity::opaque); bitmap_effects->BlendBlit(rect.x, rect.y, *bitmap_effects, rect, flash_effect, Opacity::opaque); bitmap_effects->Flip(rect, flipx_effect, flipy_effect); } bitmap_effects_src_rect = rect; bitmap_effects_valid = true; src_bitmap = bitmap_effects; } return src_bitmap; }
BitmapScreenRef BitmapScreen::Create() { return Create(BitmapRef()); }
BitmapRef BitmapScreen::Refresh(Rect& rect, bool& need_scale, int& bush_y) { need_scale = false; rect.Adjust(bitmap->GetWidth(), bitmap->GetHeight()); if (rect.IsOutOfBounds(bitmap->GetWidth(), bitmap->GetHeight())) return BitmapRef(); bool no_tone = tone_effect == Tone(); bool no_flash = flash_effect.alpha == 0; bool no_flip = !flipx_effect && !flipy_effect; bool no_effects = no_tone && no_flash && no_flip; bool no_zoom = zoom_x_effect == 1.0 && zoom_y_effect == 1.0; bool effects_changed = tone_effect != current_tone || flash_effect != current_flash || flipx_effect != current_flip_x || flipy_effect != current_flip_y; bool effects_rect_changed = rect != bitmap_effects_src_rect; if (effects_changed || effects_rect_changed || bitmap_changed) { bitmap_effects_valid = false; bitmap_scale_valid = false; } if (no_effects && no_zoom) return bitmap; if (bitmap_effects != NULL && bitmap_effects_valid && no_zoom) return bitmap_effects; BitmapRef src_bitmap; if (no_effects) src_bitmap = bitmap; else if (bitmap_effects_valid) src_bitmap = bitmap_effects; else { current_tone = tone_effect; current_flash = flash_effect; current_flip_x = flipx_effect; current_flip_y = flipy_effect; if (bitmap_effects != NULL && bitmap_effects->GetWidth() < rect.x + rect.width && bitmap_effects->GetHeight() < rect.y + rect.height) { bitmap_effects.reset(); } if (!bitmap_effects) bitmap_effects = Bitmap::Create(bitmap->GetWidth(), bitmap->GetHeight(), true); bitmap_effects->Clear(); if (no_tone && no_flash) bitmap_effects->FlipBlit(rect.x, rect.y, *bitmap, rect, flipx_effect, flipy_effect); else if (no_flip && no_flash) bitmap_effects->ToneBlit(rect.x, rect.y, *bitmap, rect, tone_effect); else if (no_flip && no_tone) bitmap_effects->BlendBlit(rect.x, rect.y, *bitmap, rect, flash_effect); else if (no_flash) { bitmap_effects->ToneBlit(rect.x, rect.y, *bitmap, rect, tone_effect); bitmap_effects->Flip(rect, flipx_effect, flipy_effect); } else if (no_tone) { bitmap_effects->BlendBlit(rect.x, rect.y, *bitmap, rect, flash_effect); bitmap_effects->Flip(rect, flipx_effect, flipy_effect); } else if (no_flip) { bitmap_effects->BlendBlit(rect.x, rect.y, *bitmap, rect, flash_effect); bitmap_effects->ToneBlit(rect.x, rect.y, *bitmap_effects, rect, tone_effect); } else { bitmap_effects->BlendBlit(rect.x, rect.y, *bitmap, rect, flash_effect); bitmap_effects->ToneBlit(rect.x, rect.y, *bitmap_effects, rect, tone_effect); bitmap_effects->Flip(rect, flipx_effect, flipy_effect); } bitmap_effects_src_rect = rect; bitmap_effects_valid = true; src_bitmap = bitmap_effects; } if (no_zoom || angle_effect != 0.0) return src_bitmap; int zoomed_width = (int)(rect.width * zoom_x_effect); int zoomed_height = (int)(rect.height * zoom_y_effect); if (zoomed_width > 640 || zoomed_height > 640) { need_scale = true; return src_bitmap; } bool zoom_changed = zoom_x_effect != current_zoom_x || zoom_y_effect != current_zoom_y; bool scale_rect_changed = rect != bitmap_scale_src_rect; if (zoom_changed || scale_rect_changed) bitmap_scale_valid = false; if (bitmap_scale != NULL && bitmap_scale_valid) { bush_y = bush_y * bitmap_scale->GetHeight() / rect.height; rect = bitmap_scale->GetRect(); return bitmap_scale; } current_zoom_x = zoom_x_effect; current_zoom_y = zoom_y_effect; bitmap_scale.reset(); bitmap_scale = src_bitmap->Resample(zoomed_width, zoomed_height, rect); bitmap_scale_src_rect = rect; bitmap_scale_valid = true; bush_y = bush_y * bitmap_scale->GetHeight() / rect.height; rect = bitmap_scale->GetRect(); return bitmap_scale; }
void Window::RefreshFrame() { frame_needs_refresh = false; BitmapRef up_bitmap = Bitmap::Create(width, 8); BitmapRef down_bitmap = Bitmap::Create(width, 8); up_bitmap->SetTransparentColor(windowskin->GetTransparentColor()); down_bitmap->SetTransparentColor(windowskin->GetTransparentColor()); up_bitmap->Clear(); down_bitmap->Clear(); Rect src_rect, dst_rect; // Border Up src_rect.Set(32 + 8, 0, 16, 8); dst_rect.Set(8, 0, max(width - 16, 1), 8); up_bitmap->TiledBlit(8, 0, src_rect, *windowskin, dst_rect, 255); // Border Down src_rect.Set(32 + 8, 32 - 8, 16, 8); dst_rect.Set(8, 0, max(width - 16, 1), 8); down_bitmap->TiledBlit(8, 0, src_rect, *windowskin, dst_rect, 255); // Upper left corner up_bitmap->Blit(0, 0, *windowskin, Rect(32, 0, 8, 8), 255); // Upper right corner up_bitmap->Blit(width - 8, 0, *windowskin, Rect(64 - 8, 0, 8, 8), 255); // Lower left corner down_bitmap->Blit(0, 0, *windowskin, Rect(32, 32 - 8, 8, 8), 255); // Lower right corner down_bitmap->Blit(width - 8, 0, *windowskin, Rect(64 - 8, 32 - 8, 8, 8), 255); frame_up->SetBitmap(up_bitmap); frame_down->SetBitmap(down_bitmap); if (height > 16) { BitmapRef left_bitmap = Bitmap::Create(8, height - 16); BitmapRef right_bitmap = Bitmap::Create(8, height - 16); left_bitmap->SetTransparentColor(windowskin->GetTransparentColor()); right_bitmap->SetTransparentColor(windowskin->GetTransparentColor()); left_bitmap->Clear(); right_bitmap->Clear(); // Border Left src_rect.Set(32, 8, 8, 16); dst_rect.Set(0, 0, 8, height - 16); left_bitmap->TiledBlit(0, 8, src_rect, *windowskin, dst_rect, 255); // Border Right src_rect.Set(64 - 8, 8, 8, 16); dst_rect.Set(0, 0, 8, height - 16); right_bitmap->TiledBlit(0, 8, src_rect, *windowskin, dst_rect, 255); frame_left->SetBitmap(left_bitmap); frame_right->SetBitmap(right_bitmap); } else { frame_left->SetBitmap(BitmapRef()); frame_right->SetBitmap(BitmapRef()); } }