IDriverDependantBitmap* prepare_screen_for_transition_in() { if (saved_viewport_bitmap == NULL) quit("Crossfade: buffer is null attempting transition"); saved_viewport_bitmap = ReplaceBitmapWithSupportedFormat(saved_viewport_bitmap); const Rect &viewport = play.GetMainViewport(); if (saved_viewport_bitmap->GetHeight() < viewport.GetHeight()) { Bitmap *enlargedBuffer = BitmapHelper::CreateBitmap(saved_viewport_bitmap->GetWidth(), viewport.GetHeight(), saved_viewport_bitmap->GetColorDepth()); enlargedBuffer->Blit(saved_viewport_bitmap, 0, 0, 0, (viewport.GetHeight() - saved_viewport_bitmap->GetHeight()) / 2, saved_viewport_bitmap->GetWidth(), saved_viewport_bitmap->GetHeight()); delete saved_viewport_bitmap; saved_viewport_bitmap = enlargedBuffer; } else if (saved_viewport_bitmap->GetHeight() > viewport.GetHeight()) { Bitmap *clippedBuffer = BitmapHelper::CreateBitmap(saved_viewport_bitmap->GetWidth(), viewport.GetHeight(), saved_viewport_bitmap->GetColorDepth()); clippedBuffer->Blit(saved_viewport_bitmap, 0, (saved_viewport_bitmap->GetHeight() - viewport.GetHeight()) / 2, 0, 0, saved_viewport_bitmap->GetWidth(), saved_viewport_bitmap->GetHeight()); delete saved_viewport_bitmap; saved_viewport_bitmap = clippedBuffer; } saved_viewport_bitmap->Acquire(); IDriverDependantBitmap *ddb = gfxDriver->CreateDDBFromBitmap(saved_viewport_bitmap, false); return ddb; }
// a simple function that applies a blur effect on a bitmap // - Bitmap &bmp: the input bitmap // - int radius: blur radius void MAS::Cursor::Blur(Bitmap &bmp, int radius) { int x, y; int i, j; int r,g,b; int div = (2*radius+1)*(2*radius+1); Bitmap tmp2(bmp.w(), bmp.h(), Bitmap::MEMORY); tmp2.Clear(Color::transparent); bmp.Blit(tmp2, 0, 0, 0, 0, bmp.w(), bmp.h()); Bitmap tmp(Size(bmp.w() + 2*radius, bmp.h() + 2*radius), Bitmap::MEMORY); tmp.Clear(Color::black); bmp.Blit(tmp, Point(0,0), Point(radius, radius), bmp.size()); for (y=radius; y<tmp.h()-radius; y++) { for (x=radius; x<tmp.w()-radius; x++) { r = g = b = 0; for (j=-radius; j<=radius; j++) { for (i=-radius; i<=radius; i++) { Color col = tmp.Getpixel(Point(x+i, y+j)); r += col.r(); g += col.g(); b += col.b(); } } tmp2.Putpixel(Point(x-radius, y-radius), Color(r/div, g/div, b/div)); } } bmp.Clear(); tmp2.Blit(bmp, 0, 0, 0, 0, bmp.w(), bmp.h()); }
void show_preload () { // ** Do the preload graphic if available color temppal[256]; Bitmap *splashsc = BitmapHelper::CreateRawObjectOwner( load_pcx("preload.pcx",temppal) ); if (splashsc != NULL) { if (splashsc->GetColorDepth() == 8) wsetpalette(0,255,temppal); Bitmap *screen_bmp = BitmapHelper::GetScreenBitmap(); Bitmap *tsc = BitmapHelper::CreateBitmap(splashsc->GetWidth(),splashsc->GetHeight(),screen_bmp->GetColorDepth()); tsc->Blit(splashsc,0,0,0,0,tsc->GetWidth(),tsc->GetHeight()); screen_bmp->Clear(); screen_bmp->StretchBlt(tsc, RectWH(0, 0, scrnwid,scrnhit), Common::kBitmap_Transparency); gfxDriver->ClearDrawList(); if (!gfxDriver->UsesMemoryBackBuffer()) { IDriverDependantBitmap *ddb = gfxDriver->CreateDDBFromBitmap(screen_bmp, false, true); gfxDriver->DrawSprite(0, 0, ddb); render_to_screen(screen_bmp, 0, 0); gfxDriver->DestroyDDB(ddb); } else render_to_screen(screen_bmp, 0, 0); delete splashsc; delete tsc; platform->Delay(500); } }
void DrawingSurface_DrawSurface(ScriptDrawingSurface* target, ScriptDrawingSurface* source, int translev) { if ((translev < 0) || (translev > 99)) quit("!DrawingSurface.DrawSurface: invalid parameter (transparency must be 0-99)"); Bitmap *ds = target->StartDrawing(); Bitmap *surfaceToDraw = source->GetBitmapSurface(); if (surfaceToDraw == target->GetBitmapSurface()) quit("!DrawingSurface.DrawSurface: cannot draw surface onto itself"); if (translev == 0) { // just draw it over the top, no transparency ds->Blit(surfaceToDraw, 0, 0, 0, 0, surfaceToDraw->GetWidth(), surfaceToDraw->GetHeight()); target->FinishedDrawing(); return; } if (surfaceToDraw->GetColorDepth() <= 8) quit("!DrawingSurface.DrawSurface: 256-colour surfaces cannot be drawn transparently"); // Draw it transparently GfxUtil::DrawSpriteWithTransparency(ds, surfaceToDraw, 0, 0, GfxDef::Trans100ToAlpha255(translev)); target->FinishedDrawing(); }
ScriptDynamicSprite* DynamicSprite_CreateFromDrawingSurface(ScriptDrawingSurface *sds, int x, int y, int width, int height) { int gotSlot = spriteset.findFreeSlot(); if (gotSlot <= 0) return NULL; // use DrawingSurface resolution sds->MultiplyCoordinates(&x, &y); sds->MultiplyCoordinates(&width, &height); Bitmap *ds = sds->StartDrawing(); if ((x < 0) || (y < 0) || (x + width > ds->GetWidth()) || (y + height > ds->GetHeight())) quit("!DynamicSprite.CreateFromDrawingSurface: requested area is outside the surface"); int colDepth = ds->GetColorDepth(); Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, colDepth); if (newPic == NULL) return NULL; newPic->Blit(ds, x, y, 0, 0, width, height); sds->FinishedDrawingReadOnly(); add_dynamic_sprite(gotSlot, newPic, (sds->hasAlphaChannel != 0)); ScriptDynamicSprite *new_spr = new ScriptDynamicSprite(gotSlot); return new_spr; }
// RawRestoreScreen: copy backup bitmap back to screen; we // deliberately don't free the Bitmap *cos they can multiple restore // and it gets freed on room exit anyway void RawRestoreScreen() { if (raw_saved_screen == NULL) { debug_log("RawRestoreScreen: unable to restore, since the screen hasn't been saved previously."); return; } Bitmap *deston = thisroom.ebscene[play.bg_frame]; deston->Blit(raw_saved_screen, 0, 0, 0, 0, deston->GetWidth(), deston->GetHeight()); invalidate_screen(); mark_current_background_dirty(); }
void polygonLoop( Bitmap& pointer ) { LineStrip polygon; Line line( 0,0,0,0 ); global_pressed = false; global_released = false; bool drawing = false; while( !keypressed()) { Canvas::Fill( Rgba::BLACK ); polygon.Draw( Rgba::WHITE ); if( drawing ) { line.end = Vec2D( mouse_x, mouse_y ); line.Draw( Rgba::WHITE ); } pointer.Blit( mouse_x, mouse_y ); Canvas::Refresh(); if( global_pressed ) { if( !polygon.GetNumOfVertices()) polygon.AddToEnd( Vec2D( mouse_x, mouse_y )); line.start = polygon.GetVertex( polygon.GetNumOfVertices() - 1 ); global_pressed = false; drawing = true; } if( global_released ) { polygon.AddToEnd( Vec2D( mouse_x, mouse_y )); global_released = false; drawing = false; } rest(1); } }
IDriverDependantBitmap* prepare_screen_for_transition_in() { if (temp_virtual == NULL) quit("Crossfade: buffer is null attempting transition"); temp_virtual = gfxDriver->ConvertBitmapToSupportedColourDepth(temp_virtual); if (temp_virtual->GetHeight() < scrnhit) { Bitmap *enlargedBuffer = BitmapHelper::CreateBitmap(temp_virtual->GetWidth(), scrnhit, temp_virtual->GetColorDepth()); enlargedBuffer->Blit(temp_virtual, 0, 0, 0, (scrnhit - temp_virtual->GetHeight()) / 2, temp_virtual->GetWidth(), temp_virtual->GetHeight()); delete temp_virtual; temp_virtual = enlargedBuffer; } else if (temp_virtual->GetHeight() > scrnhit) { Bitmap *clippedBuffer = BitmapHelper::CreateBitmap(temp_virtual->GetWidth(), scrnhit, temp_virtual->GetColorDepth()); clippedBuffer->Blit(temp_virtual, 0, (temp_virtual->GetHeight() - scrnhit) / 2, 0, 0, temp_virtual->GetWidth(), temp_virtual->GetHeight()); delete temp_virtual; temp_virtual = clippedBuffer; } temp_virtual->Acquire(); IDriverDependantBitmap *ddb = gfxDriver->CreateDDBFromBitmap(temp_virtual, false); return ddb; }
IDriverDependantBitmap* prepare_screen_for_transition_in() { if (temp_virtual == NULL) quit("Crossfade: buffer is null attempting transition"); temp_virtual = ReplaceBitmapWithSupportedFormat(temp_virtual); if (temp_virtual->GetHeight() < play.viewport.GetHeight()) { Bitmap *enlargedBuffer = BitmapHelper::CreateBitmap(temp_virtual->GetWidth(), play.viewport.GetHeight(), temp_virtual->GetColorDepth()); enlargedBuffer->Blit(temp_virtual, 0, 0, 0, (play.viewport.GetHeight() - temp_virtual->GetHeight()) / 2, temp_virtual->GetWidth(), temp_virtual->GetHeight()); delete temp_virtual; temp_virtual = enlargedBuffer; } else if (temp_virtual->GetHeight() > play.viewport.GetHeight()) { Bitmap *clippedBuffer = BitmapHelper::CreateBitmap(temp_virtual->GetWidth(), play.viewport.GetHeight(), temp_virtual->GetColorDepth()); clippedBuffer->Blit(temp_virtual, 0, (temp_virtual->GetHeight() - play.viewport.GetHeight()) / 2, 0, 0, temp_virtual->GetWidth(), temp_virtual->GetHeight()); delete temp_virtual; temp_virtual = clippedBuffer; } temp_virtual->Acquire(); IDriverDependantBitmap *ddb = gfxDriver->CreateDDBFromBitmap(temp_virtual, false); return ddb; }
// creates a cursor shadow from a cursor bitmap void MAS::Cursor::MakeShadow() { int x, y, i; Point pOffset(PADDING, PADDING); Point pOrigin(0,0); for (i=0; i<frameCount; i++) { Bitmap bmp; if (MAS::Settings::mouseShadow) { bmp.Create(Size(sprite[i]->w() + 2*PADDING, sprite[i]->h() + 2*PADDING), Bitmap::MEMORY); // create the alpha channel for the shadow by masking the cursor and bluring the results Bitmap alpha(bmp.size(), Bitmap::MEMORY); alpha.Clear(Color::transparent); sprite[i]->Blit(alpha, pOrigin, pOffset, sprite[i]->size()); for (y=0; y<bmp.h(); y++) { for (x=0; x<bmp.w(); x++) { Point p(x,y); if (alpha.Getpixel(p) == Color::transparent) alpha.Putpixel(p, Color::black); else alpha.Putpixel(p, Color::white); } } Blur(alpha, PADDING); // write the alpha channel to the shadow bitmap for (y=0; y<bmp.h(); y++) { for (x=0; x<bmp.w(); x++) { Point p(x,y); bmp.Putpixel(p, Color(shadowColor.r(), shadowColor.g(), shadowColor.b(), alpha.Getpixel(p).r())); } } alpha.Destroy(); } else { bmp.Create(1, 1); bmp.Putpixel(0, 0, Color::transparent); } Bitmap *result = new Bitmap(bmp.w(), bmp.h()); bmp.Blit(*result, 0, 0, 0, 0, bmp.w(), bmp.h()); shadow.push_back(result); } }
void DynamicSprite_ChangeCanvasSize(ScriptDynamicSprite *sds, int width, int height, int x, int y) { if (sds->slot == 0) quit("!DynamicSprite.ChangeCanvasSize: sprite has been deleted"); if ((width < 1) || (height < 1)) quit("!DynamicSprite.ChangeCanvasSize: new size is too small"); multiply_up_coordinates(&x, &y); multiply_up_coordinates(&width, &height); Bitmap *newPic = BitmapHelper::CreateTransparentBitmap(width, height, spriteset[sds->slot]->GetColorDepth()); // blit it into the enlarged image newPic->Blit(spriteset[sds->slot], 0, 0, x, y, spritewidth[sds->slot], spriteheight[sds->slot]); delete spriteset[sds->slot]; // replace the bitmap in the sprite set add_dynamic_sprite(sds->slot, newPic, (game.spriteflags[sds->slot] & SPF_ALPHACHANNEL) != 0); }
Bitmap *wnewblock(Common::Bitmap *src, int x1, int y1, int x2, int y2) { Bitmap *tempbitm; int twid = (x2 - x1) + 1, thit = (y2 - y1) + 1; if (twid < 1) twid = 1; if (thit < 1) thit = 1; tempbitm = BitmapHelper::CreateBitmap(twid, thit); if (tempbitm == NULL) return NULL; tempbitm->Blit(src, x1, y1, 0, 0, tempbitm->GetWidth(), tempbitm->GetHeight()); return tempbitm; }
void DynamicSprite_Crop(ScriptDynamicSprite *sds, int x1, int y1, int width, int height) { if ((width < 1) || (height < 1)) quit("!DynamicSprite.Crop: co-ordinates do not make sense"); if (sds->slot == 0) quit("!DynamicSprite.Crop: sprite has been deleted"); multiply_up_coordinates(&x1, &y1); multiply_up_coordinates(&width, &height); if ((width > spritewidth[sds->slot]) || (height > spriteheight[sds->slot])) quit("!DynamicSprite.Crop: requested to crop an area larger than the source"); Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, spriteset[sds->slot]->GetColorDepth()); // blit it cropped newPic->Blit(spriteset[sds->slot], x1, y1, 0, 0, newPic->GetWidth(), newPic->GetHeight()); delete spriteset[sds->slot]; // replace the bitmap in the sprite set add_dynamic_sprite(sds->slot, newPic, (game.spriteflags[sds->slot] & SPF_ALPHACHANNEL) != 0); }
ScriptDynamicSprite* DynamicSprite_CreateFromBackground(int frame, int x1, int y1, int width, int height) { if (frame == SCR_NO_VALUE) { frame = play.bg_frame; } else if ((frame < 0) || (frame >= thisroom.num_bscenes)) quit("!DynamicSprite.CreateFromBackground: invalid frame specified"); if (x1 == SCR_NO_VALUE) { x1 = 0; y1 = 0; width = play.room_width; height = play.room_height; } else if ((x1 < 0) || (y1 < 0) || (width < 1) || (height < 1) || (x1 + width > play.room_width) || (y1 + height > play.room_height)) quit("!DynamicSprite.CreateFromBackground: invalid co-ordinates specified"); multiply_up_coordinates(&x1, &y1); multiply_up_coordinates(&width, &height); int gotSlot = spriteset.findFreeSlot(); if (gotSlot <= 0) return NULL; // create a new sprite as a copy of the existing one Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, thisroom.ebscene[frame]->GetColorDepth()); if (newPic == NULL) return NULL; newPic->Blit(thisroom.ebscene[frame], x1, y1, 0, 0, width, height); // replace the bitmap in the sprite set add_dynamic_sprite(gotSlot, newPic); ScriptDynamicSprite *new_spr = new ScriptDynamicSprite(gotSlot); GlobalReturnValue.SetDynamicObject(new_spr, new_spr); return new_spr; }
void draw_text_window_and_bar(Bitmap **text_window_ds, bool should_free_ds, int*xins,int*yins,int*xx,int*yy,int*wii,color_t *set_text_color,int ovrheight, int ifnum) { draw_text_window(text_window_ds, should_free_ds, xins, yins, xx, yy, wii, set_text_color, ovrheight, ifnum); if ((topBar.wantIt) && (text_window_ds && *text_window_ds)) { // top bar on the dialog window with character's name // create an enlarged window, then free the old one Bitmap *ds = *text_window_ds; Bitmap *newScreenop = BitmapHelper::CreateBitmap(ds->GetWidth(), ds->GetHeight() + topBar.height, game.GetColorDepth()); newScreenop->Blit(ds, 0, 0, 0, topBar.height, ds->GetWidth(), ds->GetHeight()); delete *text_window_ds; *text_window_ds = newScreenop; ds = *text_window_ds; // draw the top bar color_t draw_color = ds->GetCompatibleColor(play.top_bar_backcolor); ds->FillRect(Rect(0, 0, ds->GetWidth() - 1, topBar.height - 1), draw_color); if (play.top_bar_backcolor != play.top_bar_bordercolor) { // draw the border draw_color = ds->GetCompatibleColor(play.top_bar_bordercolor); for (int j = 0; j < play.top_bar_borderwidth; j++) ds->DrawRect(Rect(j, j, ds->GetWidth() - (j + 1), topBar.height - (j + 1)), draw_color); } // draw the text int textx = (ds->GetWidth() / 2) - wgettextwidth_compensate(topBar.text, topBar.font) / 2; color_t text_color = ds->GetCompatibleColor(play.top_bar_textcolor); wouttext_outline(ds, textx, play.top_bar_borderwidth + 1, topBar.font, text_color, topBar.text); // don't draw it next time topBar.wantIt = 0; // adjust the text Y position yins[0] += topBar.height; } else if (topBar.wantIt) topBar.wantIt = 0; }
ScriptDynamicSprite* DynamicSprite_CreateFromExistingSprite(int slot, int preserveAlphaChannel) { int gotSlot = spriteset.findFreeSlot(); if (gotSlot <= 0) return NULL; if (!spriteset.doesSpriteExist(slot)) quitprintf("DynamicSprite.CreateFromExistingSprite: sprite %d does not exist", slot); // create a new sprite as a copy of the existing one Bitmap *newPic = BitmapHelper::CreateBitmap(spritewidth[slot], spriteheight[slot], spriteset[slot]->GetColorDepth()); if (newPic == NULL) return NULL; newPic->Blit(spriteset[slot], 0, 0, 0, 0, spritewidth[slot], spriteheight[slot]); bool hasAlpha = (preserveAlphaChannel) && ((game.spriteflags[slot] & SPF_ALPHACHANNEL) != 0); // replace the bitmap in the sprite set add_dynamic_sprite(gotSlot, newPic, hasAlpha); ScriptDynamicSprite *new_spr = new ScriptDynamicSprite(gotSlot); GlobalReturnValue.SetDynamicObject(new_spr, new_spr); return new_spr; }
void Text::Draw(Bitmap& dest, int x, int y, int color, std::string const& text, Text::Alignment align) { if (text.length() == 0) return; FontRef font = dest.GetFont(); Rect dst_rect = Font::Default()->GetSize(text); switch (align) { case Text::AlignCenter: dst_rect.x = x - dst_rect.width / 2; break; case Text::AlignRight: dst_rect.x = x - dst_rect.width; break; case Text::AlignLeft: dst_rect.x = x; break; default: assert(false); } dst_rect.y = y; dst_rect.width += 1; dst_rect.height += 1; // Need place for shadow if (dst_rect.IsOutOfBounds(dest.GetWidth(), dest.GetHeight())) return; BitmapRef text_surface; // Complete text will be on this surface text_surface = Bitmap::Create(dst_rect.width, dst_rect.height, true); text_surface->SetTransparentColor(dest.GetTransparentColor()); text_surface->Clear(); // Load the system file for the shadow and text color BitmapRef system = Cache::System(Data::system.system_name); // Load the exfont-file BitmapRef exfont = Cache::Exfont(); // Get the Shadow color Color shadow_color(Cache::system_info.sh_color); // If shadow is pure black, increase blue channel // so it doesn't become transparent if ((shadow_color.red == 0) && (shadow_color.green == 0) && (shadow_color.blue == 0) ) { if (text_surface->bytes() >= 3) { shadow_color.blue++; } else { shadow_color.blue += 8; } } // Where to draw the next glyph (x pos) int next_glyph_pos = 0; // The current char is an exfont bool is_exfont = false; // This loops always renders a single char, color blends it and then puts // it onto the text_surface (including the drop shadow) for (boost::u8_to_u32_iterator<std::string::const_iterator> c(text.begin(), text.begin(), text.end()), end(text.end(), text.begin(), text.end()); c != end; ++c) { Rect next_glyph_rect(next_glyph_pos, 0, 0, 0); boost::u8_to_u32_iterator<std::string::const_iterator> next_c_it = boost::next(c); uint32_t const next_c = std::distance(c, end) > 1? *next_c_it : 0; // ExFont-Detection: Check for A-Z or a-z behind the $ if (*c == '$' && std::isalpha(next_c)) { int exfont_value = -1; // Calculate which exfont shall be rendered if (islower(next_c)) { exfont_value = 26 + next_c - 'a'; } else if (isupper(next_c)) { exfont_value = next_c - 'A'; } else { assert(false); } is_exfont = true; BitmapRef mask = Bitmap::Create(12, 12, true); // Get exfont from graphic Rect const rect_exfont((exfont_value % 13) * 12, (exfont_value / 13) * 12, 12, 12); // Create a mask mask->Clear(); mask->Blit(0, 0, *exfont, rect_exfont, 255); // Get color region from system graphic Rect clip_system(8+16*(color%10), 4+48+16*(color/10), 6, 12); BitmapRef char_surface = Bitmap::Create(mask->GetWidth(), mask->GetHeight(), true); char_surface->SetTransparentColor(dest.GetTransparentColor()); char_surface->Clear(); // Blit gradient color background (twice because of full glyph) char_surface->Blit(0, 0, *system, clip_system, 255); char_surface->Blit(6, 0, *system, clip_system, 255); // Blit mask onto background char_surface->MaskBlit(0, 0, *mask, mask->GetRect()); BitmapRef char_shadow = Bitmap::Create(mask->GetWidth(), mask->GetHeight(), true); char_shadow->SetTransparentColor(dest.GetTransparentColor()); char_shadow->Clear(); // Blit solid color background char_shadow->Fill(shadow_color); // Blit mask onto background char_shadow->MaskBlit(0, 0, *mask, mask->GetRect()); // Blit first shadow and then text text_surface->Blit(next_glyph_rect.x + 1, next_glyph_rect.y + 1, *char_shadow, char_shadow->GetRect(), 255); text_surface->Blit(next_glyph_rect.x, next_glyph_rect.y, *char_surface, char_surface->GetRect(), 255); } else { // Not ExFont, draw normal text font->Render(*text_surface, next_glyph_rect.x, next_glyph_rect.y, *system, color, *c); } // If it's a full size glyph, add the size of a half-size glypth twice if (is_exfont) { is_exfont = false; next_glyph_pos += 12; // Skip the next character ++c; } else { std::string const glyph(c.base(), next_c_it.base()); next_glyph_pos += Font::Default()->GetSize(glyph).width; } } BitmapRef text_bmp = Bitmap::Create(*text_surface, text_surface->GetRect()); Rect src_rect(0, 0, dst_rect.width, dst_rect.height); int iy = dst_rect.y; if (dst_rect.height > text_bmp->GetHeight()) { iy += ((dst_rect.height - text_bmp->GetHeight()) / 2); } int ix = dst_rect.x; dest.Blit(ix, iy, *text_bmp, src_rect, 255); }