/* ddraw_do_stretch_blit: * Accelerated stretch_blit, stretch_sprite, stretch_masked_blit */ static void ddraw_do_stretch_blit(struct BITMAP *source, struct BITMAP *dest, int source_x, int source_y, int source_width, int source_height, int dest_x, int dest_y, int dest_width, int dest_height, int masked) { RECT dest_rect, source_rect; DDCOLORKEY src_key; HRESULT hr; BITMAP *dest_parent; BITMAP *source_parent; dest_rect.left = dest_x + dest->x_ofs; dest_rect.top = dest_y + dest->y_ofs; dest_rect.right = dest_x + dest->x_ofs + dest_width; dest_rect.bottom = dest_y + dest->y_ofs + dest_height; source_rect.left = source_x + source->x_ofs; source_rect.top = source_y + source->y_ofs; source_rect.right = source_x + source->x_ofs + source_width; source_rect.bottom = source_y + source->y_ofs + source_height; src_key.dwColorSpaceLowValue = source->vtable->mask_color; src_key.dwColorSpaceHighValue = source->vtable->mask_color; if ( ( (masked && (gfx_capabilities & GFX_HW_VRAM_STRETCH_BLIT_MASKED)) || (!masked && (gfx_capabilities & GFX_HW_VRAM_STRETCH_BLIT)) ) && ( is_video_bitmap(source) || is_system_bitmap(source) ) ) { /* find parents */ dest_parent = dest; while (dest_parent->id & BMP_ID_SUB) dest_parent = (BITMAP *)dest_parent->extra; source_parent = source; while (source_parent->id & BMP_ID_SUB) source_parent = (BITMAP *)source_parent->extra; _enter_gfx_critical(); gfx_directx_release_lock(dest); gfx_directx_release_lock(source); IDirectDrawSurface2_SetColorKey(DDRAW_SURFACE_OF(source_parent)->id, DDCKEY_SRCBLT, &src_key); hr = IDirectDrawSurface2_Blt(DDRAW_SURFACE_OF(dest_parent)->id, &dest_rect, DDRAW_SURFACE_OF(source_parent)->id, &source_rect, (masked ? DDBLT_KEYSRC : 0) | DDBLT_WAIT, NULL); _exit_gfx_critical(); if (FAILED(hr)) _TRACE(PREFIX_E "Blt failed (%x)\n", hr); /* only for windowed mode */ if ((gfx_driver->id == GFX_DIRECTX_WIN) && (dest_parent == gfx_directx_forefront_bitmap)) win_gfx_driver->paint(&dest_rect); } else { /* have to use the original software version */ _orig_stretch_blit(source, dest, source_x, source_y, source_width, source_height, dest_x, dest_y, dest_width, dest_height, masked); } }
/* ddraw_draw_sprite: * Accelerated sprite drawing routine. */ static void ddraw_draw_sprite(BITMAP * bmp, BITMAP * sprite, int x, int y) { int sx, sy, w, h; if (is_video_bitmap(sprite) || is_system_bitmap(sprite)) { sx = 0; /* sprite->x_ofs & sprite->y_ofs will be accounted for in ddraw_masked_blit */ sy = 0; w = sprite->w; h = sprite->h; if (bmp->clip) { if (x < bmp->cl) { sx += bmp->cl - x; w -= bmp->cl - x; x = bmp->cl; } if (y < bmp->ct) { sy += bmp->ct - y; h -= bmp->ct - y; y = bmp->ct; } if (x + w > bmp->cr) w = bmp->cr - x; if (w <= 0) return; if (y + h > bmp->cb) h = bmp->cb - y; if (h <= 0) return; } ddraw_masked_blit(sprite, bmp, sx, sy, x, y, w, h); } else { /* have to use the original software version */ _orig_draw_sprite(bmp, sprite, x, y); } }
/* destroy_bitmap: * Destroys a memory bitmap. */ void destroy_bitmap(BITMAP *bitmap) { VRAM_BITMAP *prev, *pos; if (bitmap) { if (is_video_bitmap(bitmap)) { /* special case for getting rid of video memory bitmaps */ ASSERT(!_dispsw_status); prev = NULL; pos = vram_bitmap_list; while (pos) { if (pos->bmp == bitmap) { if (prev) prev->next_y = pos->next_y; else vram_bitmap_list = pos->next_y; if (pos->x < 0) { /* the driver is in charge of this object */ gfx_driver->destroy_video_bitmap(bitmap); _AL_FREE(pos); return; } /* Update cached bitmap size using worst case scenario: * the bitmap lies between two holes whose size is the cached * size on each axis respectively. */ failed_bitmap_w = failed_bitmap_w * 2 + ((bitmap->w + 15) & ~15); if (failed_bitmap_w > BMP_MAX_SIZE) failed_bitmap_w = BMP_MAX_SIZE; failed_bitmap_h = failed_bitmap_h * 2 + bitmap->h; if (failed_bitmap_h > BMP_MAX_SIZE) failed_bitmap_h = BMP_MAX_SIZE; _AL_FREE(pos); break; } prev = pos; pos = pos->next_y; } _unregister_switch_bitmap(bitmap); } else if (is_system_bitmap(bitmap)) { /* special case for getting rid of system memory bitmaps */ ASSERT(gfx_driver != NULL); if (gfx_driver->destroy_system_bitmap) { gfx_driver->destroy_system_bitmap(bitmap); return; } } /* normal memory or sub-bitmap destruction */ if (system_driver->destroy_bitmap) { if (system_driver->destroy_bitmap(bitmap)) return; } if (bitmap->dat) _AL_FREE(bitmap->dat); _AL_FREE(bitmap); } }