
Vorteile gegenüber 3DSprites:
- Die Größe des Sprites ist egal (Keine Einschränkungen wie 16x16,32x32...)
- Kann in kombination mit UseBuffer() verwendet werden
- Unterstützt Clipping (mit ClipSprite())
- zum zeichnen ist kein 3D Beschleuniger notwendig
Code: Alles auswählen
#DDBLT_WAIT=16777216
#DDBLT_KEYSRC=32768
Structure PB_Sprite
Sprite.l
Width.w
Height.w
Depth.w
Mode.w
FileName.l
RealWidth.w
RealHeight.w
ClipX.w
ClipY.w
EndStructure
Structure DDBLTFX
dwSize.l
dwDDFX.l
dwROP.l
dwDDROP.l
dwRotationAngle.l
dwZBufferOpCode.l
dwZBufferLow.l
dwZBufferHigh.l
dwZBufferBaseDest.l
dwZDestConstBitDepth.l
dwZDestConst.l
dwZSrcConstBitDepth.l
dwZSrcConst.l
dwAlphaEdgeBlendBitDepth.l
dwAlphaEdgeBlend.l
dwReserved.l
dwAlphaDestConstBitDepth.l
dwAlphaDestConst.l
dwAlphaSrcConstBitDepth.l
dwAlphaSrcConst.l
dwFillColor.l
dwColorSpaceLowValue.l
dwColorSpaceHighValue.l
dwColorSpaceLowValue2.l
dwColorSpaceHighValue2.l
EndStructure
Structure RGN
dwSize.l
iType.l
nCount.l
nRgnSize.l
rcBoundLeft.l
rcBoundTop.l
rcBoundRight.l
rcBoundBottom.l
rc1Left.l
rc1Top.l
rc1Right.l
rc1Bottom.l
rc2Left.l
rc2Top.l
rc2Right.l
rc2Bottom.l
EndStructure
!extrn _PB_Screen_Width
!extrn _PB_Screen_Height
!extrn _PB_Sprite_CurrentBitmap
!extrn _PB_DDrawBase
ProcedureDLL.l GetScreenWidth() ; returns the width of the current buffer selected with UseBuffer()
!MOV Eax,[_PB_Screen_Width]
ProcedureReturn
EndProcedure
ProcedureDLL.l GetScreenHeight() ; returns the height of the current buffer selected with UseBuffer()
!MOV Eax,[_PB_Screen_Height]
ProcedureReturn
EndProcedure
ProcedureDLL.l GetCurrentDDS() ; returns the current used (select with UseBuffer()) directdrawsurface
!MOV Eax,[_PB_Sprite_CurrentBitmap]
ProcedureReturn
EndProcedure
ProcedureDLL.l GetDDrawBase() ; returns the directdraw interface
!MOV Eax,[_PB_DDrawBase]
ProcedureReturn
EndProcedure
Procedure DisplaySpriteEx(Sprite,x.l,y.l,Width.l,Height.l,transparent.l)
Protected *Sprite.PB_Sprite,rgn.RGN,*DD.IDirectDraw7,*Clipper.IDirectDrawClipper,SrcRe.Rect,DstRe.Rect,*DDS.IDirectDrawSurface7,fx.DDBLTFX,Result.l
*DDS=GetCurrentDDS()
*Sprite=IsSprite(Sprite)
If *DDS=0 Or *Sprite=0 Or Width<1 Or Height<1
ProcedureReturn #False
EndIf
DstRe.Rect
DstRe\left=x
DstRe\top=y
DstRe\right=x+Width
DstRe\bottom=y+Height
SrcRe\left=*Sprite\ClipX
SrcRe\right=*Sprite\ClipX+*Sprite\Width
SrcRe\top=*Sprite\ClipY
SrcRe\bottom=*Sprite\ClipY+*Sprite\Height
DestWidth=GetScreenWidth()
DestHeight=GetScreenHeight()
fx\dwSize=SizeOf(DDBLTFX)
If x<0 Or y<0 Or DstRe\right=>DestWidth Or DstRe\bottom=>DestHeight ; use only a clipper, if we need it
rgn\dwSize=SizeOf(RGNDATAHEADER)
rgn\iType=#RDH_RECTANGLES
rgn\nCount=1
rgn\nRgnSize=16
rgn\rcBoundLeft=0
rgn\rcBoundTop=0
rgn\rcBoundRight=DestWidth
rgn\rcBoundBottom=DestHeight
rgn\rc1Left=0
rgn\rc1Top=0
rgn\rc1Right=DestWidth
rgn\rc1Bottom=DestHeight
*DD=GetDDrawBase()
If *DD=0:ProcedureReturn #False:EndIf
*DD\CreateClipper(0,@*Clipper,0)
If *Clipper=0:ProcedureReturn #False:EndIf
If *Clipper\SetClipList(rgn,0)<>#S_OK
*Clipper\Release()
ProcedureReturn #False
EndIf
If *DDS\SetClipper(*Clipper)<>#S_OK
*Clipper\Release()
ProcedureReturn #False
EndIf
If transparent
Result=*DDS\Blt(DstRe,*Sprite\Sprite,SrcRe,#DDBLT_KEYSRC|#DDBLT_WAIT,fx)
Else
Result=*DDS\Blt(DstRe,*Sprite\Sprite,SrcRe,#DDBLT_WAIT,fx)
EndIf
*DDS\SetClipper(0)
*Clipper\Release()
Else
If transparent
Result=*DDS\Blt(DstRe,*Sprite\Sprite,SrcRe,#DDBLT_KEYSRC|#DDBLT_WAIT,fx)
Else
Result=*DDS\Blt(DstRe,*Sprite\Sprite,SrcRe,#DDBLT_WAIT,fx)
EndIf
EndIf
If Result=#S_OK
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndProcedure
InitSprite()
OpenWindow(1,0,0,640,480,"DisplaySpriteEx() example")
OpenWindowedScreen(WindowID(1),0,0,640,480,0,0,0)
CreateSprite(1,100,100)
TransparentSpriteColor(1,#Magenta)
StartDrawing(SpriteOutput(1))
Box(0,0,100,100,#Magenta)
For n=50 To 1 Step -1
Circle(45+Random(10),45+Random(10),n,RGB(255-n,255-n*4,0))
Next
StopDrawing()
Repeat
ClearScreen(#Blue)
For T=0 To 20
k.f+0.001
DisplaySpriteEx(1,Sin(k+T/10)*260+260,Cos(k+T/5)*180+180,Cos(k+T/5)*30+50,Cos(k+T/5)*30+50,#True)
Next
FlipBuffers()
Until WindowEvent()=#PB_Event_CloseWindow