Clipping in DirectDraw 7
By: Peter Kuchnio

This is a tutorial about clipping, or displaying only the part of the sprite that is visible onscreen and "clipping" the invisible part that is supposed to be offscreen. Without this technique sprites would simply disappear when they reach the edges of the screen. There are actually 2 ways to do this, both pretty easy.

Clipping with the DirectDraw Clipper object

This is used to clip the screen in windowed mode. The DirectDraw clipper cannot be used in fullscreen exclusive mode. This method is very simple. 

Dim DDClipper as DirectDrawClipper

Set DDClipper = Dd.CreateClipper(0)
DDClipper.SetHwnd Form1.Hwnd
ddsFront.SetClipper DDClipper

Here we attach a clipper to the primary surface. First we create the clipper, then we pass it the handle to the form and finally we attach it to our surface. We can expand this further by using Clip Lists, in which case we specify the RECTS of the different rectangles we want clipped. This is very easy to do. You just make a RECT array, then make a clip list:

DDClipper.SetClipList 1, Rects()

Rects() is the rect array and the number is how many entries there are in the array. You do this before you attach the clipper to the surface. Note, you can't use BltFast with Clipper, you have to use Blt.
 

Clipping in Fullscreen Exclusive mode

Since Clipper can't be used in fullscreen exclusive mode, you have to write your own clipping routines. This is easiest to do in a subroutine.

Public Sub DDBltFast (Surface as DirectDrawSurface7, RECTvar as RECT, X as Integer, Y as Integer)

'CLIPPING
    
    'Set up screen rect for clipping
    Dim ScreenRECT As RECT
    ScreenRECT.Top = Y
    ScreenRECT.Left = X
    ScreenRECT.Bottom = Y + RECTvar.Bottom
    ScreenRECT.Right = X + RECTvar.Right
    
    'Temporary rect
    Dim RectTEMP As RECT
    RectTEMP = RECTvar
    
    'Clip surface
    With ScreenRECT
        If .Bottom > 600 Then
            RectTEMP.Bottom = RectTEMP.Bottom - (.Bottom - 600)
            .Bottom = 600
        End If
        If .Left < 0 Then
            RectTEMP.Left = RectTEMP.Left - .Left
            .Left = 0
        End If
        If .Right > 800 Then
            RectTEMP.Right = RectTEMP.Right - (.Right - 800)
            .Right = 800
        End If
        If .Top < 0 Then
            RectTEMP.Top = RectTEMP.Top - .Top
            .Top = 0
        End If
    End With
    
    Call ddsBack.BltFast (X, Y, surface, RectTEMP, DDBLTFAST_WAIT or DDBLTFAST_SRCCOLORKEY)
End Sub

This will nicely clip your sprites and you can even use BltFast. We use RectTEMP so that any other sprites using the same RECT variable aren't clipped with the surface offscreen. This is of course for an 800x600 resolution. For different resolutions just change the two numbers.

Peter