News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Directx 9 last shot (at least for now)

Started by felipe, April 17, 2018, 04:50:01 AM

Previous topic - Next topic

Lonewolff

'Toddler's Corner' is down the bottom  :t

Siekmanski

Hi Felipe,

No worries, I will put something together tomorrow.
Loading "d3d9.dll" via LoadLibrary and get the function "Direct3DCreate9" via GetProcAddress.
And calling the COM interfaces without MACROS .  :t
Creative coders use backward thinking techniques as a strategy.

felipe

Ok siekmanski, thanks a lot. I f you can do that probably you are a genius.  :greenclp:

felipe

Quote from: Lonewolff on April 18, 2018, 09:30:13 AM
'Toddler's Corner' is down the bottom  :t

You are really a lonewolff, right?   :badgrin:

jj2007

Quote from: felipe on April 18, 2018, 09:25:28 AM:biggrin: This is lovely lonewolff but i already have a girlfriend... :badgrin:

Maybe you should dedicate more time to her. Or to coding 8)

To give you a starting point: Forum search yields almost 100 threads for loadlibrary getprocaddress. If that is not enough, there are almost 200 threads at the old forum. The term coinvoke is less popular, 36 threads in the new forum, less than 100 in the old one, but still, there is enough learning material for you. And certainly, if you post code, many people here will be willing to help you.

felipe

Quote from: jj2007 on April 18, 2018, 11:10:47 AM
Maybe you should dedicate more time to her. Or to coding 8)

jj2007: Is that an inclusive OR? Because if not, from what you have typed can be inferred that there are too many resources to learn, even more than there is time to code. Which in fact may be true. So in what do you think i waste my time? If you mean fighting i agree. But i'm really not the kind of guy who likes to fight. I just do what i have to do to remain free, as possible, and hopefully, happy  :idea:.

Btw, thanks for the tips  :icon14:.

LordAdef


Siekmanski

Another approach to get DirectX 9 running without using static libs and without the coinvoke MACRO.
And for Felipe also a com call code procedure without using a ComCall MACRO.
Of course I made a new "DX9call" MACRO for myself and everybody else who wants to use it.
Had to rewrite all d3d9 com interface code in the include files.
d3d9.inc, d3d9caps.inc and d3d9types are translated and ready to use.
The other include files for the d3d9x wrapper lib are not translated yet.
I'll leave that job for Felipe.

How to load and scan the computer for 1 of the many d3d9x wrapper libs, have a look at my PixelShader compiler code.
http://masm32.com/board/index.php?topic=6904.0

Cheers, Siekmanski

; Hi Felipe, because you didn't want to use the coinvoke MACRO to call the COM Interfaces,
; all COM Interfaces like the one below have to be rewritten like "IDirect3D9 Interface methods".

; coinvoke version:
;_vtIDirect3D9 MACRO CastName:REQ
;    _vtIUnknown CastName
;    &CastName&_RegisterSoftwareDevice       comethod2 ?
;    &CastName&_GetAdapterCount              comethod1 ?
;    &CastName&_GetAdapterIdentifier         comethod4 ?
;    &CastName&_GetAdapterModeCount          comethod3 ?
;    &CastName&_EnumAdapterModes             comethod5 ?
;    &CastName&_GetAdapterDisplayMode        comethod3 ?
;    &CastName&_CheckDeviceType              comethod6 ?
;    &CastName&_CheckDeviceFormat            comethod7 ?
;    &CastName&_CheckDeviceMultiSampleType   comethod7 ?
;    &CastName&_CheckDepthStencilMatch       comethod6 ?
;    &CastName&_CheckDeviceFormatConversion  comethod5 ?
;    &CastName&_GetDeviceCaps                comethod4 ?
;    &CastName&_GetAdapterMonitor            comethod2 ?
;    &CastName&_CreateDevice                 comethod7 ?
;ENDM
;
;IDirect3D9 struct
;   _vtIDirect3D9 IDirect3D9
;IDirect3D9 ends
;
;   LPDIRECT3D9 typedef PTR IDirect3D9
;   PDIRECT3D9  typedef PTR IDirect3D9

; Interfaces are now addressed in this manner:
; Keep the interface methods as in the original SDK order!( see the DX9 SDK *.h includes for the right order )
; Don't place the interface methods in alphabetical order as in the "DirectX9_c.chm"
; Start with address offset 12 and add 4 for the next method.

; IDirect3D9 Interface methods
IDirect3D9_RegisterSoftwareDevice               equ 12
IDirect3D9_GetAdapterCount                      equ 16
IDirect3D9_GetAdapterIdentifier                 equ 20
IDirect3D9_GetAdapterModeCount                  equ 24
IDirect3D9_EnumAdapterModes                     equ 28
IDirect3D9_GetAdapterDisplayMode                equ 32
IDirect3D9_CheckDeviceType                      equ 36
IDirect3D9_CheckDeviceFormat                    equ 40
IDirect3D9_CheckDeviceMultiSampleType           equ 44
IDirect3D9_CheckDepthStencilMatch               equ 48
IDirect3D9_CheckDeviceFormatConversion          equ 52
IDirect3D9_GetDeviceCaps                        equ 56
IDirect3D9_GetAdapterMonitor                    equ 60
IDirect3D9_CreateDevice                         equ 64

LPDIRECT3D9                     typedef PTR DWORD
PDIRECT3D9                      typedef PTR DWORD


The COM call code:

    push    0                   ; push the parameters
    push    FLT4(1.0)
    push    BackgroundColor
    push    D3DCLEAR_TARGET
    push    NULL
    push    0
    mov     eax,g_pD3DDevice    ; load the com interface
    push    eax                 ; push it
    mov     eax,[eax]           ; get the pointer from the interface pointer
    call    dword ptr[eax+IDirect3DDevice9_Clear] ; call the com interface method

    ;DX9call    g_pD3DDevice,IDirect3DDevice9_Clear,0,NULL,D3DCLEAR_TARGET,BackgroundColor,FLT4(1.0),0
;   The "DX9call" MACRO produces the same code as the manual code above

Creative coders use backward thinking techniques as a strategy.

felipe

Siekmanski you are a genius! Thanks a lot! This time all worked correctly, i was able of run the program and to assemble and link the code (i first deleted the .exe) and all worked without problems. This is a great learning resource for me. I really appreciate it. I will use and work with all this and will create all the includes that remains (and of course i will post everything too).  :greenclp:

:greenclp:

Siekmanski

Creative coders use backward thinking techniques as a strategy.

jj2007


Siekmanski

 :biggrin: I'm not.
He can now start with DirectX9 in his own favorite coding style, I can understand that very well.
Afterall, we all have our own coding styles, I like mine the most.  :bgrin:
I'm waiting till he discovers all the macros for the color conversions etc.
It is almost impossible not to use macros to keep it a bit maintainable.

And another thing, my DX9call macro is now faster then the coinvoke macro. ( one less memory read )
Without Felipe I never had spotted that one + I can use edx again in the parameters.

Creative coders use backward thinking techniques as a strategy.

aw27

Nice job!
A couple of years ago I was studying a way to use the Desktop Duplication API to transfer changed screen rectangles to a remote computer. It requires DirectX 11/DXGI 1.2. I have also made an article about that. Although I know how to save rectangles to bitmaps and send them across the network, of course, I ended up not pursuing the project because my current implementation is already very fast and at the time I could not figure out a good way to handle it on the receiver side.

felipe

Quote from: jj2007 on April 19, 2018, 10:19:21 AM
Quote from: Siekmanski on April 19, 2018, 06:38:34 AM
    push    FLT4(1.0)

Remember felipe is allergic against macros :eusa_naughty:

:biggrin: This macro code actually helped me to see that i can't move directly a float to a register, i mean like an immediate operand. I didn't knew that. Seems like we need to initialize all of them.

Siekmanski thanks again very much, this has been actually, i think, a great contribution to the masm32 sdk. I have to go to sleep now  (i was too excited to wait until tomorrow to try to code with this great help). From tomorrow i will start to learn more about directx9. Here is the same "idea" that i posted here (the first reply) but without c code:

.686
.model      flat,stdcall
option      casemap:none
include     \masm32\include\windows.inc
include     \masm32\include\kernel32.inc
include     \masm32\include\user32.inc
include     \masm32\include\gdi32.inc
includelib  \masm32\lib\kernel32.lib
includelib  \masm32\lib\user32.lib
includelib  \masm32\lib\gdi32.lib

include     \masm32\include\DX9Includes\d3d9.inc

 
SCREEN_WIDTH    equ 1024                     ; Kind of old standard
SCREEN_HEIGHT   equ 768                             ;   resolution.

.data
align 1
class_name      byte        "main window class",0
wnd_name        byte        "DIRECTX9 TEST",0
d3d9_lib        byte        "d3d9.dll",0
dx9func0        byte        "Direct3DCreate9",0

align 4
float4          dword       1.0

.data?
align 4
hinstance       dword       ?
hwindow         dword       ?
bye           dword     ?
hdll            dword       ?
proc_add        dword       ?
inter_add       dword       ?
d3dpp           D3DPRESENT_PARAMETERS <?>
d3ddev          dword       ?





.code
align 4
start:
            push        ebp
            mov         ebp,esp

            push        NULL                                                ; Get a handle for the program instance.
            call        GetModuleHandle
           
            mov         hinstance,eax
           
            sub         esp,76                                              ; WNDCLASSEX and MSG.
                                           
            mov         dword ptr[ebp-48],48                                ; The size of the structure.
            mov         dword ptr[ebp-44],CS_HREDRAW or CS_VREDRAW          ; The style of the class.
            mov         [ebp-40],wndproc
            mov         dword ptr[ebp-36],0                                 ; No extra
            mov         dword ptr[ebp-32],0                                 ;   bytes.
            mov         eax,hinstance
            mov         [ebp-28],eax

            mov         dword ptr[ebp-24],NULL                              ; No icon.

            push        IDC_ARROW                                           ; The system cursor.
            push        NULL                                             
            call        LoadCursor

            mov         [ebp-20],eax                                        ; hCursor.

            push        WHITE_BRUSH                                         ; Typical background color for a window.
            call        GetStockObject                                      ; Get the handle of the brush.

            mov         [ebp-16],eax                                        ; hBrush.
            mov         dword ptr[ebp-12],NULL                              ; No menu.
            mov         [ebp-8],offset class_name
            mov         dword ptr[ebp-4],NULL                               ; Use the same app icon for the small one.

            lea         eax,[ebp-48]                                        ; WNDCLASSEX.

            push        eax
            call        RegisterClassEx

            push        NULL                                                ; No value passed to the window.
            push        hinstance
            push        NULL                                                ; No menu.
            push        NULL                                                ; No parent of the window.
            push        SCREEN_HEIGHT                                       ; Old standar
            push        SCREEN_WIDTH                                        ;   resolution.
            push        CW_USEDEFAULT                                       ; Default position
            push        CW_USEDEFAULT                                       ;  of the window.
            push        WS_EX_TOPMOST or WS_VISIBLE or WS_POPUP             ; Game window style.
            push        offset wnd_name                                     ; Name of the game window.   
            push        offset class_name
            push        WS_EX_TOPMOST     ; Some extension of the style.
            call CreateWindowEx

            mov         hwindow,eax

            push        SW_SHOWNORMAL                                       ; Displaying the window for the first time.
            push        eax
            call        ShowWindow                                         

            push        hwindow
            call        UpdateWindow                                        ; Update the client area.

            push        offset d3d9_lib
            call        LoadLibrary                                         ; Load d3d9.dll to the address space of this program.

            mov         hdll,eax                                            ; Handle to the module loaded.

            push        offset dx9func0                                     ; Direct3DCreate9.
            push        eax                                                 ; hdll.
            call        GetProcAddress                                      ; Get the address of the dx9 function.

            mov         proc_add,eax                                        ; Save the address of the funtion Direct3DCreate9.

            push        D3D_SDK_VERSION
            call        eax                                                 ; Call the function Direct3DCreate9.
           
            mov         inter_add,eax                                       ; Safe the com interface address.                                 

            mov         esi,offset d3dpp
            mov         ecx,14                                              ; There are 14 dword members in this structure.

align 4
fill_struc:
            mov        dword ptr[esi],0
            add        esi,4                                                ; Next field.
            loop       fill_struc                                           ; Fill the structure with 0.

            mov        esi,offset d3dpp
   
    mov        dword ptr[esi+0],SCREEN_WIDTH                        ; Backbuffer width.
    mov        dword ptr[esi+4],SCREEN_HEIGHT                       ; Backbuffer height.
            mov        dword ptr[esi+8],D3DFMT_X8R8G8B8                     ; Backbuffer format.
            mov        dword ptr[esi+12],1                                  ; Backbuffer count.
            mov        dword ptr[esi+24],D3DSWAPEFFECT_DISCARD              ; Swap effect.
            mov        eax,hwindow
            mov        dword ptr[esi+28],eax                                ; device window.
            mov        dword ptr[esi+32],FALSE                              ; Not windowe, we want fullscreen.
     
            push        offset d3ddev
            push        offset d3dpp
            push        D3DCREATE_SOFTWARE_VERTEXPROCESSING
            push        eax                                                 ; hwindow
            push        D3DDEVTYPE_HAL
            push        D3DADAPTER_DEFAULT

            mov         eax,inter_add                                       ; Com interface address.
            push        eax
            mov         eax,[eax]                                           
            call        dword ptr[eax+IDirect3D9_CreateDevice]              ; Call com interface method CreateDevice.       

    lea         esi,[ebp-76]             ; MSG.
    mov bye,0     ; Flag to stop the game loop.

                   
align 4
msgloop:           
    push        PM_REMOVE                                           ; Pull out messages.
            push        0                                                   ; Retrieve all
            push        0                                                   ;  available messages.
            push        NULL                                                ; Messages of any window of this thread.
            push        esi                     ; MSG.
            call        PeekMessage       

    cmp eax,0
    je no_msg     ; No messages yet. Give the game the resources.

    push        esi
            call        TranslateMessage                                    ; Translate keyboard to messages.

            push        esi
            call        DispatchMessage                                     ; Dispatch messages to wndproc.

            cmp         bye,1
    je end_program             ; Check if the game is over.

align 4
no_msg:
            push        0
            push        float4
            push        00ff0000h                                           ; Color.
            push        D3DCLEAR_TARGET
            push        NULL
            push        0

            mov         eax,d3ddev                                          ; Com interface address.
            push        eax
            mov         eax,[eax]
            call        dword ptr[eax+IDirect3DDevice9_Clear]               ; Call the com interface method.
           
            mov         eax,d3ddev
            push        eax
            mov         eax,[eax]
            call        dword ptr[eax+IDirect3DDevice9_BeginScene]

            mov         eax,d3ddev
            push        eax
            mov         eax,[eax]
            call        dword ptr[eax+IDirect3DDevice9_EndScene]

            push        NULL               
            push        NULL
            push        NULL
            push        NULL
            mov         eax,d3ddev
            push        eax               
            mov         eax,[eax]         
            call        dword ptr[eax+IDirect3DDevice9_Present]     

    push VK_ESCAPE
    call GetAsyncKeySt            ; The esc key turns off the game.

     test eax,80000000h
     jz keep_rolling                 ; If is not pressed keep playing.

     push 0
     push 0
     push WM_DESTROY
     push hwindow
     call PostMessage            ; If pressed let start to shutdown the game.

align 4
keep_rolling:
    jmp msgloop                                    ; All again.


align 4
end_program:
            mov         eax,[ebp-68]                                        ; wParam (exit code).

            mov         esp,ebp
            pop         ebp
 
            push        eax                                 
            call        ExitProcess                                         ; End the program.


; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

align 4
wndproc:                                                                    ; The window procedure for the main window class.
            push        ebp
            mov         ebp,esp

            cmp         dword ptr[ebp+12],WM_DESTROY            ; Game over.
            jne do_the_default


            cmp         d3ddev,NULL
            je          skip_cleaning
           
            mov         eax,d3ddev
            push        eax               
            mov         eax,[eax]         
            call        dword ptr[eax+IUnknown_Release]

            cmp         inter_add,NULL
            je          skip_cleaning

            mov         eax,inter_add
            push        eax               
            mov         eax,[eax]         
            call        dword ptr[eax+IUnknown_Release]


align 4
skip_cleaning:
            push        0                                                   ; Exit code (wParam in WM_QUIT).
            call        PostQuitMessage                                     ; Notify to windows that is the end of the application.   

            mov bye,1     ; To stop the game loop.


            xor         eax,eax
           
            mov         esp,ebp
            pop         ebp
           
            ret         16



align 4
do_the_default:
    push        dword ptr[ebp+20]                                   ; lParam.
            push        dword ptr[ebp+16]                                   ; wParam.
            push        dword ptr[ebp+12]                                   ; The message.
            push        dword ptr[ebp+8]                                    ; Handle of the window.
            call        DefWindowProc                                       ; Default processing for all the other messages.

            mov         esp,ebp
            pop         ebp

            ret         16
           
            end         start


The .exe is attached. Remember to escape the fullscreen with the esc key.

:icon_mrgreen: I'm very happy.

Quote from: Siekmanski on April 19, 2018, 10:23:36 AM
Afterall, we all have our own coding styles, I like mine the most.  :bgrin:

Is true. Your coding style is very clear. I'm trying to improve mine. But in the code above i didn't do too much effort to refine it because i was very hurry trying to probe it. I have a lot to learn. What i couldn't understand yet is why we need to push the address of the com interface always, before we get the value of the first method (i think?). Well tomorrow more research now to the bed... :icon_mrgreen:
:greenclp:  :icon14:

aw27

Quote
What i couldn't understand yet is why we need to push the address of the com interface always
Since you are not using macros you might be able to save a few bytes and cycles across repeated calls, namely here:
mov     eax,g_pD3DDevice    ; load the com interface
and  here:
mov     eax,[eax]           ; get the pointer from the interface pointer

However, people that like macros trades that for its convenient automatism.