Ich arbeite zur Zeit an einem DX9 Subsystem, das irgendwann mal alle Sprite-,Sprite3D-,Sound-,Keyboard-... Befehle unterstützen soll.
Das Subsystem wird erst mal in PureBasic geschrieben.
Hier mal die Befehle, die ich bis jetzt geschrieben habe:
Code: Alles auswählen
IncludeFile "DXH_SubSystemDX9.pbi"
Structure PB_Sprite
Sprite.l ; DirectDrawSurface7 pointer
Width.w ; Current width of the sprite (could change if ClipSprite() is used)
Height.w ; Current height of the sprite (could change if ClipSprite() is used)
Depth.w ; depth of shade of the file. (in bits)
Mode.w ; Sprite mode, as described in LoadSprite()
FileName.l ; Pointer on the filename, if any
RealWidth.w ; Original width of the sprite when it was loaded
RealHeight.w ; Original height of the sprite when it was loaded
ClipX.w ; X offset if ClipSprite()
ClipY.w ; Y offset if ClipSprite()
EndStructure
Structure PB_ScreenMode
ScreenModeWidth.w ; Width of the Screen (in pixel)
ScreenModeHeight.w ; Height of the Screen (in pixel)
ScreenModeDepth.w ; Depth of the Screen (in bits per pixel)
ScreenModeRefreshRate.w ; Refresh rate of the Screen (in Hz)
EndStructure
Structure DrawingInfoStruct
Type.l ; Type of the DC
Window.l ; Window associated to the DC (if any)
DC.l ; DC (Display Device Context)
ReleaseProcedure.l ; Address to a procedure to release the DC when StopDrawing() is called
PixelBuffer.l ; Address of the memory pixel buffer (DirectX)
Pitch.l ; Bytes per line (DirectX)
Width.l
Height.l
Depth.l
EndStructure
Global *D3D.IDirect3D9
Global *D3DDevice9.IDirect3DDevice9
Global *BackBuffer.IDirect3DSurface9
Global d3dpp.D3DPRESENT_PARAMETERS
Global d3dcaps.D3DCAPS9
Global WindowedScreen_AutoStretch
Global WindowedScreen_X
Global WindowedScreen_Y
Global WindowedScreen_RightOffset
Global WindowedScreen_BottomOffset
Global Screen_RefreshRate
Global Screen_FrameRate
Global Screen_Format
Global Screen_Width
Global Screen_Height
Global IsScreenActive
Global ScreenOutput.DrawingInfoStruct
Global *ScreenModes.PB_ScreenMode
Global NumScreenModes
Global ScreenModeIndex
Global ScreenModeWidth
Global ScreenModeHeight
Global ScreenModeRefreshRate
Global ScreenModeDepth
;D3DDevice9 States
Global AlphaBlendState,SrcBlendMode,DestBlendMode
Global CurrentFVF;,CurrentVB,CurrentIB
Procedure _InitSprite()
*D3D.IDirect3D9=Direct3DCreate9(#D3D_SDK_VERSION)
If *D3D=0:ProcedureReturn 0:EndIf
;Examine screen modes
Num15BitModes=*D3D\GetAdapterModeCount(#D3DADAPTER_DEFAULT,#D3DFMT_X1R5G5B5)
Num16BitModes=*D3D\GetAdapterModeCount(#D3DADAPTER_DEFAULT,#D3DFMT_R5G6B5)
Num32BitModes=*D3D\GetAdapterModeCount(#D3DADAPTER_DEFAULT,#D3DFMT_X8R8G8B8)
NumScreenModes=Num32BitModes
If Num15BitModes>0
NumScreenModes+Num15BitModes
Else
NumScreenModes+Num16BitModes
EndIf
If NumScreenModes=0:ProcedureReturn 0:EndIf
*ScreenModes=AllocateMemory(NumScreenModes*SizeOf(PB_ScreenMode))
If *ScreenModes=0:ProcedureReturn 0:EndIf
*ScreenModesPtr.PB_ScreenMode=*ScreenModes
If Num15BitModes>0
For Mode=0 To Num15BitModes-1
*D3D\EnumAdapterModes(#D3DADAPTER_DEFAULT,#D3DFMT_X1R5G5B5,Mode,d3ddm.D3DDISPLAYMODE)
*ScreenModesPtr\ScreenModeWidth=d3ddm\Width
*ScreenModesPtr\ScreenModeHeight=d3ddm\Height
*ScreenModesPtr\ScreenModeRefreshRate=d3ddm\RefreshRate
*ScreenModesPtr\ScreenModeDepth=H_D3DFormatToBPP(d3ddm\Format)
*ScreenModesPtr+SizeOf(PB_ScreenMode)
Next
Else
*ScreenModesPtr.PB_ScreenMode=*ScreenModes
For Mode=0 To Num16BitModes-1
*D3D\EnumAdapterModes(#D3DADAPTER_DEFAULT,#D3DFMT_R5G6B5,Mode,d3ddm.D3DDISPLAYMODE)
*ScreenModesPtr\ScreenModeWidth=d3ddm\Width
*ScreenModesPtr\ScreenModeHeight=d3ddm\Height
*ScreenModesPtr\ScreenModeRefreshRate=d3ddm\RefreshRate
*ScreenModesPtr\ScreenModeDepth=H_D3DFormatToBPP(d3ddm\Format)
*ScreenModesPtr+SizeOf(PB_ScreenMode)
Next
EndIf
For Mode=0 To Num32BitModes-1
*D3D\EnumAdapterModes(#D3DADAPTER_DEFAULT,#D3DFMT_X8R8G8B8,Mode,d3ddm.D3DDISPLAYMODE)
*ScreenModesPtr\ScreenModeWidth=d3ddm\Width
*ScreenModesPtr\ScreenModeHeight=d3ddm\Height
*ScreenModesPtr\ScreenModeRefreshRate=d3ddm\RefreshRate
*ScreenModesPtr\ScreenModeDepth=H_D3DFormatToBPP(d3ddm\Format)
*ScreenModesPtr+SizeOf(PB_ScreenMode)
Next
ScreenModeIndex=0
ProcedureReturn *D3D
EndProcedure
Procedure _AvailableScreenMemory()
If *D3DDevice9=0:ProcedureReturn 0:EndIf
ProcedureReturn *D3DDevice9\GetAvailableTextureMem()
EndProcedure
Procedure _ExamineScreenModes()
ScreenModeIndex=0
ProcedureReturn NumScreenModes
EndProcedure
Procedure _NextScreenMode()
If ScreenModeIndex>=NumScreenModes
ScreenModeWidth=0
ScreenModeHeight=0
ScreenModeRefreshRate=0
ScreenModeDepth=0
ProcedureReturn 0
EndIf
*ScreenModesPtr.PB_ScreenMode=*ScreenModes+SizeOf(PB_ScreenMode)*ScreenModeIndex
ScreenModeWidth=*ScreenModesPtr\ScreenModeWidth
ScreenModeHeight=*ScreenModesPtr\ScreenModeHeight
ScreenModeRefreshRate=*ScreenModesPtr\ScreenModeRefreshRate
ScreenModeDepth=*ScreenModesPtr\ScreenModeDepth
ScreenModeIndex+1
ProcedureReturn 1
EndProcedure
Procedure _ScreenModeWidth()
ProcedureReturn ScreenModeWidth
EndProcedure
Procedure _ScreenModeHeight()
ProcedureReturn ScreenModeHeight
EndProcedure
Procedure _ScreenModeRefreshRate()
ProcedureReturn ScreenModeRefreshRate
EndProcedure
Procedure _ScreenModeDepth()
ProcedureReturn ScreenModeDepth
EndProcedure
Procedure _OpenWindowedScreen(WindowID,x,y,Width,Height,AutoStretch,RightOffset,BottomOffset)
Result=H_Fill_D3DPRESENT_PARAMETERS(d3dpp,*D3D,WindowID,Width,Height,1,0,#H_DEVICE_LOCKABLE|#H_DEVICE_DISABLEVSYNC)
If Result:ProcedureReturn 0:EndIf
Result=*D3D\GetDeviceCaps(#D3DADAPTER_DEFAULT,#D3DDEVTYPE_HAL,d3dcaps)
If Result:ProcedureReturn 0:EndIf
BehaviorFlags=#D3DCREATE_SOFTWARE_VERTEXPROCESSING
If d3dcaps\DevCaps&#D3DDEVCAPS_HWTRANSFORMANDLIGHT
BehaviorFlags=#D3DCREATE_HARDWARE_VERTEXPROCESSING
If d3dcaps\DevCaps&#D3DDEVCAPS_PUREDEVICE
BehaviorFlags=#D3DCREATE_HARDWARE_VERTEXPROCESSING|#D3DCREATE_PUREDEVICE
EndIf
EndIf
Result=*D3D\CreateDevice(#D3DADAPTER_DEFAULT,#D3DDEVTYPE_HAL,WindowID,BehaviorFlags,d3dpp,@*D3DDevice9)
If Result:ProcedureReturn 0:EndIf
*D3D\GetAdapterDisplayMode(#D3DADAPTER_DEFAULT,ScreenInfo.D3DDISPLAYMODE)
Screen_RefreshRate=ScreenInfo\RefreshRate
If Screen_RefreshRate=0:Screen_RefreshRate=60:EndIf
Screen_Width=Width
Screen_Height=Height
WindowedScreen_X=x
WindowedScreen_Y=y
WindowedScreen_AutoStretch=AutoStretch
WindowedScreen_RightOffset=RightOffset
WindowedScreen_BottomOffset=BottomOffset
*D3DDevice9\GetBackBuffer(0,0,#D3DBACKBUFFER_TYPE_MONO,@*BackBuffer)
*D3DDevice9\BeginScene()
ProcedureReturn *D3DDevice9
EndProcedure
Procedure _ClearScreen(Color)
If *D3DDevice9=0 Or IsScreenActive=0:ProcedureReturn 0:EndIf
If *D3DDevice9\Clear(0,0,#D3DCLEAR_TARGET,Color>>16+(Color&$FF00)+(Color&$FF)<<16,0,0)=#D3D_OK
ProcedureReturn 1
EndIf
EndProcedure
Procedure _ScreenID()
ProcedureReturn d3dpp\hDeviceWindow=hWnd
EndProcedure
Procedure _IsScreenActive()
If *D3DDevice9=0 Or IsScreenActive=0:ProcedureReturn 0:EndIf
If IsWindow_(d3dpp\hDeviceWindow)=0:ProcedureReturn 0:EndIf
If IsIconic_(d3dpp\hDeviceWindow):ProcedureReturn 0:EndIf
If d3dpp\Windowed=0
If GetForegroundWindow_()<>d3dpp\hDeviceWindow:ProcedureReturn 0:EndIf
Else
DC=GetWindowDC_(d3dpp\hDeviceWindow)
If DC=0:ProcedureReturn 0:EndIf
GetWindowRect_(d3dpp\hDeviceWindow,re.rect)
re\right=re\right-re\left
re\left=0
re\bottom=re\bottom-re\Top
re\Top=0
Visible=RectVisible_(DC,re)
ReleaseDC_(d3dpp\hDeviceWindow,DC)
If Visible=0:ProcedureReturn 0:EndIf
EndIf
If *D3DDevice9\TestCooperativeLevel():ProcedureReturn 0:EndIf
ProcedureReturn 1
EndProcedure
Procedure _FlipBuffers(Mode)
If *D3DDevice9=0:IsScreenActive=0:ProcedureReturn 0:EndIf
If IsWindow_(d3dpp\hDeviceWindow)=0:IsScreenActive=0:ProcedureReturn 0:EndIf
If d3dpp\Windowed=0 ; only for fullscreen mode (in windowed mode WindowEvent() must be used)
PeekMessage_(msg.MSG,hWnd,0,0,#PM_REMOVE)
TranslateMessage_(msg)
DispatchMessage_(msg)
EndIf
Result=*D3DDevice9\TestCooperativeLevel()
If Result=#D3DERR_DRIVERINTERNALERROR:IsScreenActive=0:ProcedureReturn 0:EndIf
If Result=#D3DERR_DEVICELOST
Repeat
Sleep_(1)
Result=*D3DDevice9\TestCooperativeLevel()
If Result=#D3DERR_DRIVERINTERNALERROR:IsScreenActive=0:ProcedureReturn 0:EndIf
Until Result=#D3DERR_DEVICENOTRESET
EndIf
If Result=#D3DERR_DEVICENOTRESET ;Restore Device
;----> Free all Default Pool ressources <----
If *D3DDevice9\Reset(d3dpp):IsScreenActive=0:ProcedureReturn 0:EndIf
;----> Recreate Default Pool ressources <----
EndIf
*D3DDevice9\EndScene()
Select Mode
Case 0
H_Wait(*D3DDevice9,0,Screen_FrameRate,0) ; Speed optimized / Wait for Framerate
Case 2
H_Wait(*D3DDevice9,Screen_RefreshRate,Screen_FrameRate,1) ; CPU usage Optimized / Wait for VBlank / Wait for FrameRate
Default
H_Wait(*D3DDevice9,Screen_RefreshRate,Screen_FrameRate,0) ; Speed optimized / Wait for VBlank / Wait for FrameRate
EndSelect
If d3dpp\Windowed=0
Result=*D3DDevice9\Present(0,0,0,0)
Else
re.rect\left=WindowedScreen_X
re\top=WindowedScreen_Y
GetClientRect_(d3dpp\hDeviceWindow,cre.rect)
re\right=cre\right-WindowedScreen_RightOffset
re\bottom=cre\bottom-WindowedScreen_BottomOffset
;should be:
;re\right=cre\right
;re\bottom=cre\bottom
If re\right-re\left>Screen_Width:re\right=re\left+Screen_Width:EndIf
If re\bottom-re\top>Screen_Height:re\bottom=re\top+Screen_Height:EndIf
If WindowedScreen_AutoStretch=0
sre.rect\left=0
sre\top=0
sre\right=re\right-re\left
sre\bottom=re\bottom-re\top
Else
sre\left=0
sre\top=0
sre\right=Screen_Width
sre\bottom=Screen_Height
EndIf
Result=*D3DDevice9\Present(sre,re,0,0)
EndIf
If Result=#D3D_OK
If *D3DDevice9\BeginScene()=#D3D_OK
IsScreenActive=1
ProcedureReturn 1
EndIf
EndIf
IsScreenActive=0
EndProcedure
Procedure _SetFrameRate(FrameRate)
Screen_FrameRate=FrameRate
EndProcedure
Procedure ___ReleaseScreenOutput()
*BackBuffer\ReleaseDC(ScreenOutput\DC)
EndProcedure
Procedure _ScreenOutput()
ScreenOutput\Type=2
*BackBuffer\GetDC(@ScreenOutput\DC)
ScreenOutput\ReleaseProcedure=@___ReleaseScreenOutput()
ProcedureReturn ScreenOutput
EndProcedure
Structure RGBFilter
x1.f
y1.f
z1.f
rhw1.f
Color1.l
x2.f
y2.f
z2.f
rhw2.f
Color2.l
x3.f
y3.f
z3.f
rhw3.f
Color3.l
x4.f
y4.f
z4.f
rhw4.f
Color4.l
EndStructure
Procedure _DisplayRGBFilter(x,y,Width,Height,R,G,B)
If AlphaBlendState=0:AlphaBlendState=1:*D3DDevice9\SetRenderState(#D3DRS_ALPHABLENDENABLE,1):EndIf
If SrcBlendMode<>#D3DBLEND_ONE:SrcBlendMode=#D3DBLEND_ONE:*D3DDevice9\SetRenderState(#D3DRS_SRCBLEND,#D3DBLEND_ONE):EndIf
If DestBlendMode<>#D3DBLEND_DESTCOLOR:DestBlendMode=#D3DBLEND_DESTCOLOR:*D3DDevice9\SetRenderState(#D3DRS_DESTBLEND,#D3DBLEND_DESTCOLOR):EndIf
If CurrentFVF<>#D3DFVF_DIFFUSE|#D3DFVF_XYZRHW:CurrentFVF=#D3DFVF_DIFFUSE|#D3DFVF_XYZRHW:*D3DDevice9\SetFVF(#D3DFVF_DIFFUSE|#D3DFVF_XYZRHW):EndIf
v.RGBFilter
v\x1=x
v\y1=y
v\rhw1=1.0
v\Color1=RGB(B,G,R)
v\x2=x+Width
v\y2=y
v\rhw2=1.0
v\Color2=RGB(B,G,R)
v\x3=x
v\y3=y+Height
v\rhw3=1.0
v\Color3=RGB(B,G,R)
v\x4=x+Width
v\y4=y+Height
v\rhw4=1.0
v\Color4=RGB(B,G,R)
ProcedureReturn *D3DDevice9\DrawPrimitiveUP(#D3DPT_TRIANGLESTRIP,2,v,SizeOf(RGBFilter)/4)
EndProcedure
_InitSprite()
OpenWindow(1,0,0,320,240,"DX9Subsystem",#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
_OpenWindowedScreen(WindowID(1),50,50,320,240,1,10,10)
_SetFrameRate(60)
Repeat
_ClearScreen(#Red)
StartDrawing(_ScreenOutput())
DrawText(0,0,"PB DX9Subsystem")
StopDrawing()
_DisplayRGBFilter(5,5,100,100,0,255,128)
_FlipBuffers(2)
Until WindowEvent()=#PB_Event_CloseWindow
Vorraussetzungen sind natürlich:
- Zeit
- wissen über DirectX9/WindowsAPI/interne Funktionsweise der PB-Befehle
- Die Fähigkeit meinen Code lesen zu können

Gruß
Stefan