Hey everyone, I'm back. I haven't been on the forums in a while because I've been busy. Since I've been doing some programming recently I decided to share some include files I cooked up which were so long and tiresome to type that I decided to save others from the same struggle.
I decided recently to start looking into DirectX programming and I hit a stumbling block with the include files provided by MASM. While they are good, I don't particularly find them read-friendly. They are quite cryptic because of the vast amount of data in them.
I decided to just write my own include files for DirectSound and Direct3D. I did not bother trying to make every previous version of DirectX work since I think DirectX is by nature quite easy to upgrade since it is online and free to download. Thus, these include files are strictly conforming to
DirectX9 standards but that really shouldn't ever be an obstacle unless you are trying to recompile an old DirectX6 project or something weird like that.
I'm not an expert in DirectX, I'm a beginner. Based on what I've learned so far, I like it. At first glance I was overwhelmed, but now I'm catching on, and it's not that complicated. The COM part is by far the biggest obstacle if you've never been exposed to it.
If you're new to DirectX and/or COM, I recommend looking into it. All of my include file information is based on MSDN and I give full credit for my learning of DirectX to http://www.directtutorial.com/ which I completely based my first example program on.
I don't understand the way DirectX10 is headed so I'm not prepared to do anything with it until it matures.
Anyway, I'd put the whole package in a zip file but you can just get them from my website. (http://home.columbus.rr.com/notfed/. They let me have infite amount of bandwidth, but they give me a limited amount of storage space :boohoo:)
There are four include files, 2 for the interfaces and 2 for the constants and enums and such. In theory some of these should really have been combined into one file but I felt the need to separate them since they are so enormous.
The include files are located at http://home.columbus.rr.com/notfed/library/
Here's a working program I made using my include files: http://home.columbus.rr.com/notfed/programs/direct3d.html
(http://home.columbus.rr.com/notfed/images/programs/BlankD3D.png)
Other links -
MSDN - Direct3D9 - http://msdn.microsoft.com/archive/en-us/directx9_c_Feb_2006/directx_sdk_graphics.asp )
MSDN - DirectSound9 - http://msdn.microsoft.com/archive/en-us/directx9_c_Feb_2006/directx_sdk_audio.asp
DirectTutorial (I recommend) - http://www.directtutorial.com
My only problem so far is the fact that
invoke does not support immediate floats/doubles. The best workarounds on the forum seem to be unperfect, unfortunately, so I am becoming doubtful of getting very far with DirectX unless floats are somehow supported better in a future version of MASM ( wink wink hutch wink wink ....... ok fine, then PLEASE I BEG OF YOU!! :'( )
Either that or someone makes a MACRO which converts a float to it's hex equivalent. If no one does I might find myself doing it and if this is the case I will most likely suffer a brain aneurysm for obvious reasons.
The floats-problem has already been solved, fnCall was the macro-name iirc, used to call with real4, string and so on parameters - you can base a coinvoke-clone on it. Maybe OA32 supports it, and it already has perfect support for DX9 with many tutorials. ATC also supports DX9, for quite some time already - I'm actively using D3D9 for my GUI stuff, basing my engine on the work I've published :)
supporting floats in instructions like "mov" is easily added... by making a movf macro, for instance:
movf macro dest,value
mov dest,12345678h
org $-4
real4 value
endm
; movf eax,3.18
(same approach wherever you need it)
ufcomp macro var1,var2 ; compares the two vars, then do je, jne, jg, jl, jge, jle ...
mov eax,var1
mov ebx,var2
mov ecx,eax
and ecx,ebx
sar ecx,31
xor eax,ecx
xor ebx,ecx
cmp eax,ebx
endm
But still... there aren't enough people interested in DX/OGL :/ Homer is actively uploading tutorials on the other forum, but the active responses are few.
btw, what asm can do with d3d: ^^
(http://img77.imageshack.us/img77/3735/sadsadzj3.jpg)
Ultrano - good point, but still... it hasn't really been solved since it's still a pain to have to make a macro for each scenario in paticular. I wish MASM would come out with a new version supporting this.
Another problem is doubles. That's even more of a pain.
Why not redirect that effort into making the macro-base for DX games, for PoAsm ? It supports these things to boot, it's only that its macros are a bit different. The only thing that I didn't like in PoAsm, last time I checked, was that it was missing argument-number checking on "invoke", or so it seemed.
Game-development is a fresh start, so it's good to take the better path from the start :)
I suppose I'm so accustomed to MASM that I almost have a slight fear of trying different assemblers, it's almost as if I am defying my religion. I view it more as my own lack of ability for creating macros if I must rely on another assembler's built in advantages.
I really don't like the idea of workarounds for each instruction just to make them float-compatible. I think there should be a global solution which works for all cases. Maybe I'm just stubborn?
All right, I decided to try out my own form of coinvoke and I wanted to keep type safety.
Believe it or not, I got a working (but obviously extremely prone to bugginess) result! :dance:
Instead of reinventing invoke, I used invoke and then had the macro go back and reinsert the floating point values. This relies heavily on the sizes of opcodes, and things like ADDR are not accounted for yet in which case it will just explode. Also there are obviously going to be issues with things like using another macro as a parameter. Though I made it work for at least integer results from macros.
;---------------------------------------
; <isfloat>
; Tells whether the argument is an
; immediate floating point value
;---------------------------------------
; e.g.
; $isfloat(1.0) ; returns 1
;---------------------------------------
$isfloat MACRO num
OPVAL TEXTEQU %OPATTR (num) ; "Op type"
DECPT TEXTEQU %@InStr(1, num, <.>) ; "Decimal Point"
IF OPVAL AND 00010000y ; Register
exitm <0>
ELSEIF OPVAL AND 00000100y ; Immediate
exitm <0>
ELSEIF OPVAL AND 00000010y ; Memory reference
exitm <0>
ELSEIF DECPT NE 0 ; Float
exitm <1>
ELSE ; Unknown
exitm <0>
ENDIF
ENDM
;---------------------------------------
; <_coinvoke>
; An incomplete version of coinvoke which
; allows immediate floating point
; numbers as parameters.
;---------------------------------------
_coinvoke MACRO pInterface:REQ, Interface:REQ, Function:REQ, args:VARARG
LOCAL istatement, arg, argc, oldorg, numval
;---------------------------------------
; Do edx check
;---------------------------------------
FOR arg, <args>
IFIDNI <&arg>, <edx>
.ERR <edx is not allowed as a coinvoke parameter>
ENDIF
ENDM
IFIDNI <&pInterface>, <edx>
.ERR <edx is not allowed as a coinvoke parameter>
ENDIF
;---------------------------------------
; Begin istatement
;---------------------------------------
istatement CATSTR <invoke (Interface PTR[edx]).&Interface>,<_>,<&Function, pInterface>
;---------------------------------------
; Concat each arg
;---------------------------------------
FOR arg, <args>
IF $isfloat(arg)
istatement CATSTR istatement, <, >, <077777777h>
ELSE
istatement CATSTR istatement, <, >, <&arg>
ENDIF
ENDM
;---------------------------------------
; Type it all in
;---------------------------------------
mov edx, pInterface
mov edx, [edx]
istatement
;---------------------------------------
; Preserve ORG
;---------------------------------------
oldorg = $
;---------------------------------------
; Overwrite floats
;---------------------------------------
argc = 12 ; 6 for call 6 for push pInterface
FOR arg, <args>
;---------------------------------------
; Go back X bytes
;---------------------------------------
ORG $-argc
;---------------------------------------
; Set number of bytes to next push
;---------------------------------------
OPVAL TEXTEQU %OPATTR (arg) ; "Op type"
DECPT TEXTEQU %@InStr(1, arg, <.>) ; "Decimal Point"
IF OPVAL AND 00010000y ; Register (1/2 byte)
argc = 1 ;; todo: extend to 2byte operands
ELSEIF OPVAL AND 00000100y ; Immediate (2/2/5 bytes)
numval = arg
IF numval EQ 0FFFFFFFFh
argc = 2
ELSEIF numval LT 255
argc = 2
ELSE
argc = 5
ENDIF
ELSEIF OPVAL AND 00000100y ; Direct Memory reference (6 bytes)
argc = 6
ELSEIF OPVAL AND 00000010y ; Complex Memory reference
argc = 6
ELSEIF DECPT NE 0 ; Float (5 bytes)
argc = 5
ORG $-4
REAL4 arg
ELSE ; Unknown
.err <Argument &arg& is an unknown type.>
ENDIF
ENDM
;---------------------------------------
; Recall ORG
;---------------------------------------
ORG oldorg
ENDM
I used the following test and it works perfectly.
;-----------------------------------------------------------------
; IDirect3DDevice9::Clear
;-----------------------------------------------------------------
_coinvoke pIDirect3DDevice9, IDirect3DDevice9, Clear, \
0,\
0,\
D3DCLEAR_TARGET,\
$D3DCOLOR_XRGB(0, 40, 100),\
1.0,\
0
Hi,
http://www.japheth.de/Download/win32inc.zip does also supply DirectX 9 include files. Just to inform you of your "competitors" :).