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

felipe

Ok, after quitting the idea of using directx 9 for the lack of the include files necessary for the job for one side and because of the complexity to get them working for the other, my mind started to think in the possibility of make a mix of c and asm. The idea was to use c functions called from asm code just to invoke all the stuff in the directx 9 libraries. The problem with this idea, as aw27 mentioned in somewhere, is that that will mean that the 80% or maybe 90% will have to be written in c, because in the games made with directx 9 (AFAIK) you only need windows and messages to set up the basic stuff and then you ignore all the other messages. That's why i have created this simple demo of how mix the asm code (main program) which creates the window for the game and handles the winproc. And from this main program we call 3 c functions: to initialize direcxt 9 objects, to use them (the game action) and to clean all the obects when finishing the game. But that's all. I don't want to program in c... :lol: But you can check out this, maybe as help, maybe as curiosity, maybe to see the game loop (this particular implementation)... :idea:

Attached is the .exe, the c code (ignore the .cpp extension) and  the .obj files. The assembly code is here:

.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

Game_Init proto c :dword               ; The c functions that deals with directx9 calls.
Game_Run proto c :dword
Game_End proto c :dword
 
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

.data?
align 4
hinstance   dword       ?
hwindow     dword       ?
bye     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 hwindow
    call Game_Init     ; Initialize direct3d objects.

    add esp,4

    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 hwindow
            call        Game_Run                                            ; All the action of the game.

    add esp,4

    push VK_ESCAPE
    call GetAsyncKeyState     ; 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

    push hwindow
    call Game_End             ; Clean the direct3d objects.

    add esp,4

            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


Btw i'm 100% agreed if you want to RE all the .exes that i upload. This is because if you want to be sure (paranoid? not necessarily, is good to be sure) than the .exe is what the code is. And also specially in this mix scenario where we can see how the directx 9 are called  :icon14:.

I haven't do to much research about com and directx in general, but it seems that you need to call methods from objects. Is it possible to do this usign the functions loadlibrary and getproc address (i think)? If so, will this need special (directx include) files too? Any help here will be appreciated  :icon14:.

Some details of the process of creation of this simple demo (just a painted window in fullscreen  :redface:): Was created with visual studio 2010  :dazzled:  :P. Using ml 10 from there. That facilitated the linking process. And the compile of the c module.

Aside note: Siekmanski is talking about quantum physics out there in this forum, so i will not comment there to avoid embarrassing... :icon_redface:  :lol:  :greenclp:

felipe

Btw, to exit the program (the full screen window painted green) press the esc key...

Siekmanski

Why would you mix asm and c++ for DirectX?
You can use 1 of those languages to make it work.
Creative coders use backward thinking techniques as a strategy.

Lonewolff

Quote from: Siekmanski on April 17, 2018, 07:27:24 AM
Why would you mix asm and c++ for DirectX?
You can use 1 of those languages to make it work.

Agreed. He took the easy way out.

Felipe, you and I both started our DirectX journey in ASM at about the same time. Should have stuck with it dude. You'd have been better off for it.

I have learned much valuable information from Siekmanski that I can now apply to any COM interface.

felipe

Quote from: Lonewolff on April 17, 2018, 07:35:01 AM
Agreed. He took the easy way out.
:biggrin:

This sounds very interesting. Good luck with game development.  :t

aw27

It is legitimate to mix C, or any high-level language, with ASM, actually it is the almost the only way ASM is used in the real World these days.
Of course, we can also make standalone DirectX ASM applications. However, things are difficult without using a set of macros to help with indirection and location of methods inside interfaces. People that fabricated those macros learned a lot in the process, but users tend to use a finished product like a black box. Sure, a few will dig inside the macros, but most will not.

Lonewolff

Quote from: aw27 on April 17, 2018, 01:51:06 PM
It is legitimate to mix C, or any high-level language, with ASM, actually it is the almost the only way ASM is used in the real World these days.
Of course, we can also make standalone DirectX ASM applications. However, things are difficult without using a set of macros to help with indirection and location of methods inside interfaces. People that fabricated those macros learned a lot in the process, but users tend to use a finished product like a black box. Sure, a few will dig inside the macros, but most will not.

Depends on what Felipe wants to do.

If he wants to ship a game in a timely fashion then maybe GameMaker would be more suitable.

If he wants to learn ASM, then mixing up languages to 'Frankenstein' something together because he doesn't want to understand one of the steps, doesn't seem like the way to go to me.

But, each to their own. We all do things for our own purposes.  :t

aw27

Felipe is learning ASM at a fast pace because he choose not to go through the easy fast lane. I am not seeing him pose basic questions, like "others" do.  :t

Lonewolff

Quote from: aw27 on April 17, 2018, 02:20:47 PM
Felipe is learning ASM at a fast pace because he choose not to go through the easy fast lane. I am not seeing him pose basic questions, like "others" do.  :t

"others" being me you mean?

I started ASM 10 days ago and have already ported DirectX 11  :t

Sure, 99% of ASM is still new to me, that's why I ask basic questions. Is that not what this forum is for? Learning in a supposed 'friendly' environment?

aw27

You have very firm opinions about how things should be for someone that has no definite idea of  the whole picture.

Quote
I started ASM 10 days ago and have already ported DirectX 11
I meet genius of that sort everyday.


aw27

#11
You should not use unusual abbreviations like OP because most people here is neither yankee nor frequent online chats all the time.
And I have nothing else to add.  :biggrin:

PS: You changed the post to a mere OK, to make it appear that OP is a typo. I can confirm once again that you are a genius.

felipe

Is this some kind of joke? c0der is you again?   :badgrin:


jj2007

Quote from: Lonewolff on April 17, 2018, 02:11:12 PMIf he wants to learn ASM, then mixing up languages to 'Frankenstein' something together because he doesn't want to understand one of the steps, doesn't seem like the way to go to me.
This is an old conflict between "fans of the bare metal" and "macro freaks" that pops up every n months. The purists insist that a 100 lines hand-made proc ending with a push push call WriteLine is much better than a print "hello world". Then the macro freaks invite the purists not to use a dirty WinAPI call to WriteLine but rather to code a direct pure way to shift bits into the video card ;)

Lonewolff

Quote from: jj2007 on April 17, 2018, 04:45:17 PM
This is an old conflict between "fans of the bare metal" and "macro freaks" that pops up every n months. The purists insist that a 100 lines hand-made proc ending with a push push call WriteLine is much better than a print "hello world". Then the macro freaks invite the purists not to use a dirty WinAPI call to WriteLine but rather to code a direct pure way to shift bits into the video card ;)

It's not that at all.

To make something usable, he will need to do a hell of a lot of 'wrapping' of function calls in C/C++. And even then the function will always be limited to his implementation.

What if he decides he wants to enable vSnyc?
Triple buffering to avoid tearing?
FSAA?
Change the FVF formats.
Fixed function or pure?
Lights (spot, directional, ambient).
The list (and wrapping) is literally endless.

This will require rewrites of the external library or additional functions written. That's the danger of relying on writing wrapper libraries rather than using a native implementation.

DirectX is massive (granted 9.0c less so - but it is still huge). You will never cover all bases trying to make a wrapper for it.

What would I know though. I'm just the noob here.  :biggrin: