--- oldsrc\win\wddaccel.c Thu Oct 27 23:23:40 2005 +++ src\win\wddaccel.c Sat Jan 28 13:27:32 2006 @@ -15,6 +15,7 @@ * Bugfixes by Isaac Cruz. * * Accelerated rectfill() and hline() added by Shawn Hargreaves. + * Accelerated draw_sprite_*_flip() added by Jens-Michael Kuhn. * * See readme.txt for copyright information. */ @@ -34,6 +35,9 @@ static void (*_orig_rectfill) (BITMAP * bmp, int x1, int y1, int x2, int y2, int color); static void (*_orig_draw_sprite) (BITMAP * bmp, BITMAP * sprite, int x, int y); static void (*_orig_masked_blit) (BITMAP * source, BITMAP * dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height); +static void (*_orig_draw_sprite_v_flip) (BITMAP * bmp, BITMAP * sprite, int x, int y); +static void (*_orig_draw_sprite_h_flip) (BITMAP * bmp, BITMAP * sprite, int x, int y); +static void (*_orig_draw_sprite_vh_flip) (BITMAP * bmp, BITMAP * sprite, int x, int y); @@ -193,6 +197,297 @@ +/* ddraw_draw_sprite_v_flip +* Accelerated sprite vertical flip routine +*/ +static void ddraw_draw_sprite_v_flip(BITMAP *bmp, BITMAP *sprite, int x, int y) +{ + int sx, sy, w, h; + RECT dest_rect, source_rect; + DDBLTFX blt_fx; + DDCOLORKEY src_key; + HRESULT hr; + BITMAP *dest_parent; + BITMAP *source_parent; + + if (is_video_bitmap(sprite) || is_system_bitmap(sprite)) { + sx = sprite->x_ofs; + sy = sprite->y_ofs; + 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) { + 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) { + sy += y + h - bmp->cb; + h -= y + h - bmp->cb; + } + + if (h <= 0) + return; + } + + dest_rect.left = x + bmp->x_ofs; + dest_rect.top = y + bmp->y_ofs; + dest_rect.right = x + bmp->x_ofs + w; + dest_rect.bottom = y + bmp->y_ofs + h; + + source_rect.left = sx + sprite->x_ofs; + source_rect.top = sy + sprite->y_ofs; + source_rect.right = sx + sprite->x_ofs + w; + source_rect.bottom = sy + sprite->y_ofs + h; + + src_key.dwColorSpaceLowValue = sprite->vtable->mask_color; + src_key.dwColorSpaceHighValue = sprite->vtable->mask_color; + + dest_parent = bmp; + while (dest_parent->id & BMP_ID_SUB) + dest_parent = (BITMAP *)dest_parent->extra; + source_parent = sprite; + while (source_parent->id & BMP_ID_SUB) + source_parent = (BITMAP *)source_parent->extra; + + /* set vertical flip */ + blt_fx.dwSize = sizeof(blt_fx); + blt_fx.dwDDFX = DDBLTFX_MIRRORUPDOWN; + + _enter_gfx_critical(); + gfx_directx_release_lock(bmp); + gfx_directx_release_lock(sprite); + + 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, + DDBLT_KEYSRC | DDBLT_DDFX | DDBLT_WAIT, &blt_fx); + _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_draw_sprite_v_flip(bmp, sprite, x, y); + } +} + + + +/* ddraw_draw_sprite_h_flip +* Accelerated sprite horizontal flip routine +*/ +static void ddraw_draw_sprite_h_flip(BITMAP *bmp, BITMAP *sprite, int x, int y) +{ + int sx, sy, w, h; + RECT dest_rect, source_rect; + DDBLTFX blt_fx; + DDCOLORKEY src_key; + HRESULT hr; + BITMAP *dest_parent; + BITMAP *source_parent; + + if (is_video_bitmap(sprite) || is_system_bitmap(sprite)) { + sx = sprite->x_ofs; + sy = sprite->y_ofs; + w = sprite->w; + h = sprite->h; + if (bmp->clip) { + if (x < bmp->cl) { + 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) { + sx += x + w - bmp->cr; + w -= x + w - bmp->cr; + } + + if (w <= 0) + return; + + if (y + h > bmp->cb) + h = bmp->cb - y; + + if (h <= 0) + return; + } + + dest_rect.left = x + bmp->x_ofs; + dest_rect.top = y + bmp->y_ofs; + dest_rect.right = x + bmp->x_ofs + w; + dest_rect.bottom = y + bmp->y_ofs + h; + + source_rect.left = sx + sprite->x_ofs; + source_rect.top = sy + sprite->y_ofs; + source_rect.right = sx + sprite->x_ofs + w; + source_rect.bottom = sy + sprite->y_ofs + h; + + src_key.dwColorSpaceLowValue = sprite->vtable->mask_color; + src_key.dwColorSpaceHighValue = sprite->vtable->mask_color; + + dest_parent = bmp; + while (dest_parent->id & BMP_ID_SUB) + dest_parent = (BITMAP *)dest_parent->extra; + source_parent = sprite; + while (source_parent->id & BMP_ID_SUB) + source_parent = (BITMAP *)source_parent->extra; + + /* set horizontal flip */ + blt_fx.dwSize = sizeof(blt_fx); + blt_fx.dwDDFX = DDBLTFX_MIRRORLEFTRIGHT; + + _enter_gfx_critical(); + gfx_directx_release_lock(bmp); + gfx_directx_release_lock(sprite); + + 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, + DDBLT_KEYSRC | DDBLT_DDFX | DDBLT_WAIT, &blt_fx); + _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_draw_sprite_h_flip(bmp, sprite, x, y); + } +} + + + +/* ddraw_draw_sprite_vh_flip +* Accelerated sprite vertical + horizontal flip routine +*/ +static void ddraw_draw_sprite_vh_flip(BITMAP *bmp, BITMAP *sprite, int x, int y) +{ + int sx, sy, w, h; + RECT dest_rect, source_rect; + DDBLTFX blt_fx; + DDCOLORKEY src_key; + HRESULT hr; + BITMAP *dest_parent; + BITMAP *source_parent; + + if (is_video_bitmap(sprite) || is_system_bitmap(sprite)) { + sx = sprite->x_ofs; + sy = sprite->y_ofs; + w = sprite->w; + h = sprite->h; + + if (bmp->clip) { + if (x < bmp->cl) { + w -= bmp->cl - x; + x = bmp->cl; + } + + if (y < bmp->ct) { + h -= bmp->ct - y; + y = bmp->ct; + } + + if (x + w > bmp->cr) { + sx += x + w - bmp->cr; + w -= x + w - bmp->cr; + } + + if (w <= 0) + return; + + if (y + h > bmp->cb) { + sy += y + h - bmp->cb; + h -= y + h - bmp->cb; + } + + if (h <= 0) + return; + } + + dest_rect.left = x + bmp->x_ofs; + dest_rect.top = y + bmp->y_ofs; + dest_rect.right = x + bmp->x_ofs + w; + dest_rect.bottom = y + bmp->y_ofs + h; + + source_rect.left = sx + sprite->x_ofs; + source_rect.top = sy + sprite->y_ofs; + source_rect.right = sx + sprite->x_ofs + w; + source_rect.bottom = sy + sprite->y_ofs + h; + + src_key.dwColorSpaceLowValue = sprite->vtable->mask_color; + src_key.dwColorSpaceHighValue = sprite->vtable->mask_color; + + dest_parent = bmp; + while (dest_parent->id & BMP_ID_SUB) + dest_parent = (BITMAP *)dest_parent->extra; + source_parent = sprite; + while (source_parent->id & BMP_ID_SUB) + source_parent = (BITMAP *)source_parent->extra; + + /* set vertical + horizontal flip */ + blt_fx.dwSize = sizeof(blt_fx); + blt_fx.dwDDFX = (DDBLTFX_MIRRORLEFTRIGHT | DDBLTFX_MIRRORUPDOWN); + + _enter_gfx_critical(); + gfx_directx_release_lock(bmp); + gfx_directx_release_lock(sprite); + + 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, + DDBLT_KEYSRC | DDBLT_DDFX | DDBLT_WAIT, &blt_fx); + _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_draw_sprite_vh_flip(bmp, sprite, x, y); + } +} + + + /* ddraw_clear_to_color: * Accelerated screen clear routine. */ @@ -458,6 +753,9 @@ _orig_rectfill = _screen_vtable.rectfill; _orig_draw_sprite = _screen_vtable.draw_sprite; _orig_masked_blit = _screen_vtable.masked_blit; + _orig_draw_sprite_v_flip = _screen_vtable.draw_sprite_v_flip; + _orig_draw_sprite_h_flip = _screen_vtable.draw_sprite_h_flip; + _orig_draw_sprite_vh_flip = _screen_vtable.draw_sprite_vh_flip; /* accelerated video to video blits? */ if (ddcaps.dwCaps & DDCAPS_BLT) { @@ -488,6 +786,14 @@ if (_screen_vtable.color_depth == 8) _screen_vtable.draw_256_sprite = ddraw_draw_sprite; + + /* accelerated flipped sprites? */ + if ((ddcaps.dwFXCaps & DDFXCAPS_BLTMIRRORUPDOWN) && (ddcaps.dwFXCaps & DDFXCAPS_BLTMIRRORLEFTRIGHT)) { + _screen_vtable.draw_sprite_v_flip = ddraw_draw_sprite_v_flip; + _screen_vtable.draw_sprite_h_flip = ddraw_draw_sprite_h_flip; + _screen_vtable.draw_sprite_vh_flip = ddraw_draw_sprite_vh_flip; + /* no gfx_capabilities are defined */ + } gfx_capabilities |= (GFX_HW_VRAM_BLIT_MASKED | GFX_HW_SYS_TO_VRAM_BLIT_MASKED); }