Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

DirectX in HLA

38 views
Skip to first unread message

NoDot

unread,
Apr 27, 2004, 9:23:21 PM4/27/04
to
I've posted this elsewhere, but I've finally decided to post it here.

Does anyone know an example of using DirectX in HLA. I'll even settle
for an example of OpenXX material. (Just make sure it's a turtorial
on it.)

Please, help me here.

Betov

unread,
Apr 28, 2004, 2:18:21 AM4/28/04
to
no_...@msn.com (NoDot) écrivait news:dfed44a6.0404271706.21a0e899
@posting.google.com:

No, sorry, no example, but you have _many_ for all
Assemblers.


Betov.

< http://betov.free.fr/RosAsm.html >

Nathan C. Baker

unread,
Apr 28, 2004, 2:18:24 AM4/28/04
to

"NoDot" <no_...@msn.com> wrote in message
news:dfed44a6.04042...@posting.google.com...

Just download the DirectX and OpenGL examples written for other assemblers
and convert them to the HLA sytax. This means flipping the SRC/DEST
operands and a bunch of extra typing -- "(", ")", and ";" for each line --
and greatly increases your chances for syntax errors but it shouldn't be too
hard of a task.


Charles Banas

unread,
Apr 28, 2004, 4:07:59 AM4/28/04
to
NoDot wrote:

i don't know of any HLA examples of anything, to be honest.

but NeHe's OpenGL tutorials have example code in assembly suitable for
MASM and (i think) NASM. might help guide you in the right direction:
http://nehe.gamedev.net/

http://nexe.gamedev.net/ used to be NeHe's DirectX alter-ego
so-to-speak, but its format has since changed. i don't know of anything
else with DirectX in assembly, though i don't doubt it's possible.
(although, it would probably be easier to write a wrapper library in C
and use those functions from assembly than to code all of the object
code that DirectX seems to mandate.)

NoDot

unread,
Apr 28, 2004, 7:52:16 PM4/28/04
to
"Nathan C. Baker" <nbake...@charter.net> wrote in message news:<108ugmm...@corp.supernews.com>...

The examples I've seen usually use MASM and use the OOP library for
MASM. Drives me crazy. I just thought of something, so I'll go and
have a look.

NoDot

unread,
Apr 30, 2004, 11:34:22 PM4/30/04
to
> http://nexe.gamedev.net/ used to be NeHe's DirectX alter-ego
> so-to-speak, but its format has since changed. i don't know of anything
> else with DirectX in assembly, though i don't doubt it's possible.
> (although, it would probably be easier to write a wrapper library in C
> and use those functions from assembly than to code all of the object
> code that DirectX seems to mandate.)

The reason I'm using HLA is because my Borland C++ compiler (OK the
problem is the linker) can't handle the DirectX SDK libraries. If it
could handle them them I wouldn't be here right now asking for this
information.

Charles Banas

unread,
May 1, 2004, 4:33:21 AM5/1/04
to
well, for the linker to suport DirectX, it needs the linkable libraries
to be in a format it can recognize. IIRC, Borland uses the OMF format,
as does Intel. Microsoft uses a bastardized COFF format called "PE".
GCC generally supports everything except OMF, i think.

there are libraries for GCC that support DirectX 7, and maybe 8.

but as far as HLA goes (or any non-C++ language, for that matter), you
need a pre-written library, or to write one yourself, that can load and
call all of the functions that DirectX uses.

i don't know how much time you have on your hands, but if you want to
implement an object-based library that exports DirectX calls in a usable
calling convention, then you, sir, are very talented.

(someone correct me if i'm wrong here somewhere. but i do recall
reading that the vtables format Microsoft uses in DirectX kept GCC from
supporting it for a very long time.)

Randall Hyde

unread,
May 1, 2004, 1:25:36 PM5/1/04
to

"Charles Banas" <u...@ftc.gov> wrote in message
news:1096leq...@news.supernews.com...

>>
> but as far as HLA goes (or any non-C++ language, for that matter), you
> need a pre-written library, or to write one yourself, that can load and
> call all of the functions that DirectX uses.

Hmmm... Last time I checked, the C++ language definition didn't include
DirectX as part of the language :-).

For *every* language, HLA, MASM, C++, whatever, you need the
"pre-written" library, it's call "Direct-X".

What the OP needs is a header file with the proper definitions for the
DirectX
calls, which is true, again, for nearly every language that interfaces to
external
functions. As has been pointed out, these external definitions are very
simple
to create (in HLA, as in MASM, etc.), so the best advice to the OP is to
study the Direct-X tutorials for MASM and create the appropriate external
declarations for HLA.


>
> i don't know how much time you have on your hands, but if you want to
> implement an object-based library that exports DirectX calls in a usable
> calling convention, then you, sir, are very talented.

OTOH, he might also be using HLA, which allows the creation of
object-oriented modules in assembly a breeze. :-)


>
> (someone correct me if i'm wrong here somewhere. but i do recall
> reading that the vtables format Microsoft uses in DirectX kept GCC from
> supporting it for a very long time.)

That's the beauty of assembly language.
You can interface with just about anything.
Cheers,
Randy Hyde

NoDot

unread,
May 1, 2004, 4:48:47 PM5/1/04
to
> (someone correct me if i'm wrong here somewhere. but i do recall
> reading that the vtables format Microsoft uses in DirectX kept GCC from
> supporting it for a very long time.)

The problem I seem to be having in HLA, it seems, is getting the
vtable information. I might be accessing it incorrectly. What is
their vtable format?

Charles Banas

unread,
May 1, 2004, 4:48:51 PM5/1/04
to
Randall Hyde wrote:
>
> Hmmm... Last time I checked, the C++ language definition didn't include
> DirectX as part of the language :-).
>
Thank God.

> For *every* language, HLA, MASM, C++, whatever, you need the
> "pre-written" library, it's call "Direct-X".
>

very true.

> What the OP needs is a header file with the proper definitions for the
> DirectX
> calls, which is true, again, for nearly every language that interfaces to
> external
> functions. As has been pointed out, these external definitions are very
> simple
> to create (in HLA, as in MASM, etc.), so the best advice to the OP is to
> study the Direct-X tutorials for MASM and create the appropriate external
> declarations for HLA.
>

which i submit is a difficult task given that DirectX makes copious use
of C++ classes with just about every feature known to man:
multiple-inheritance, virtual functions, etc.

wrtiting support for all of that in a language is no easy task, i'm
sure, and creates quite a bit of difficulty in calling any DirectX code.

IMHO, the solution to the issue is to create a wrapper library (written
in C++) that exports (in a C or Pascal-like calling convention) all of
the functions that one might need to write DirectX code. AFAIK, other
than OpenGL/DirectX wrappers, no such wrapper exists.

>
>
>>i don't know how much time you have on your hands, but if you want to
>>implement an object-based library that exports DirectX calls in a usable
>>calling convention, then you, sir, are very talented.
>
>
> OTOH, he might also be using HLA, which allows the creation of
> object-oriented modules in assembly a breeze. :-)
>

which, honestly, still seems like quite a feat with all fo the features
and code bloat that DirectX takes advantage of.

>
>
>>(someone correct me if i'm wrong here somewhere. but i do recall
>>reading that the vtables format Microsoft uses in DirectX kept GCC from
>>supporting it for a very long time.)
>
>
> That's the beauty of assembly language.
> You can interface with just about anything.

including Microsoft's COM code bloat?

the comp.lang.C++ FAQ outlines some of the problems in section [32.8,
9]. http://www.parashift.com/c++-faq-lite/

i don't deny it's possible to se DirectX from HLA. but is it worth all
of the work involved in *CREATING* the header files and libraries you need?

Charles Banas

unread,
May 1, 2004, 5:58:43 PM5/1/04
to
since i'm neither a compiler programmer, nor intimately familiar with
Microsoft bastardizations, i haven't a clue.

i'm merely passing on information.

(and suggesting this may be a waste of your time.)

Betov

unread,
May 2, 2004, 1:15:49 PM5/2/04
to
no_...@msn.com (NoDot) écrivait
news:dfed44a6.04050...@posting.google.com:

These are nothing but simple Tables of Pointers to
Fuctions, that you can very easily access with any
Assembler, with a quite simple Table of Displacements
Equates and with a quite simple Macro. Example with
RosAsm, for an inferface call:

; Displacements Equates:

[QueryInterface 0
AddRef 4
Release 8
Compact 12
CreateClipper 16
CreatePalette 20
CreateSurface 24
DuplicateSurface 28
EnumDisplayModes 32
EnumSurfaces 36
FlipToGDISurface 40
GetCaps 44
GetDisplayMode 48
GetFourCCCodes 52
GetGDISurface 56
GetMonitorFrequency 60
GetScanLine 64
GetVerticalBlankStatus 68
Initialize 72
RestoreDisplayMode 76
SetCooperativeLevel 80
SetDisplayMode 84
WaitForVerticalBlank 88]

; Caling Macro:

[iCall | mov eax #2 | mov eax D$eax | call D$eax+#1 #2 #3>L]

; Using:

iCall Release D$Primary


As simple as this. Of course, with HLA added confusion
this might be a bit less simple, but i am quite sure
that, when you will have understood the simplicity
of these calls you will not miss to contribute to, in
turn, misslead other beginners, with no base propaganda,
for the damage of Assembly and for the personal glory
of Master Self-Esteemed Randall Hyde.


Betov.

< http://betov.free.fr/RosAsm.html >

NoDot

unread,
May 2, 2004, 1:15:58 PM5/2/04
to
> > i don't know how much time you have on your hands, but if you want to
> > implement an object-based library that exports DirectX calls in a usable
> > calling convention, then you, sir, are very talented.

I'll try and create one.

> OTOH, he might also be using HLA, which allows the creation of
> object-oriented modules in assembly a breeze. :-)

HLA passes the this pointer in esi. C++ passes the this pointer on
the stack. Problem.

NoDot

unread,
May 2, 2004, 1:16:16 PM5/2/04
to
> (and suggesting this may be a waste of your time.)

How? If I make this library, then other HLA users can benifit from my
work and we can have more apps written in HLA.

Randall Hyde

unread,
May 2, 2004, 2:45:07 PM5/2/04
to

"NoDot" <no_...@msn.com> wrote in message
news:dfed44a6.04050...@posting.google.com...

>
> HLA passes the this pointer in esi. C++ passes the this pointer on
> the stack. Problem.

If you're using HLA *classes* and the high-level HLA class invocation
mechanism, it uses ESI. However, don't forget that you can easily pass
the object pointer on the stack yourself (this is assembly language, after
all, you don't *always* have to use the high-level features in assembly
:-)).
If you like clean, HLL-like syntax for the calls, you can easily create a
macro
that does the work for you.
Cheers,
Randy Hyde


Randall Hyde

unread,
May 2, 2004, 2:45:46 PM5/2/04
to

"NoDot" <no_...@msn.com> wrote in message
news:dfed44a6.04050...@posting.google.com...

Personally, I've never worked with Direct-X, so I can't offer
any more insights into this issue. However, you might ask
Beth Stone, who has played around with Direct-X in assembly
a bit.
Cheers,
Randy Hyde

Charles Banas

unread,
May 2, 2004, 8:35:51 PM5/2/04
to
i don't disagree with that. in fact, i completely agree.

it just seems to me to be more work than it may be worth.

Beth

unread,
May 8, 2004, 4:43:04 AM5/8/04
to
Betov wrote:

> NoDot wrote:
> >> (someone correct me if i'm wrong here somewhere. but i do recall
> >> reading that the vtables format Microsoft uses in DirectX kept
GCC
> from
> >> supporting it for a very long time.)
> >
> > The problem I seem to be having in HLA, it seems, is getting the
> > vtable information. I might be accessing it incorrectly. What is
> > their vtable format?
>
> These are nothing but simple Tables of Pointers to
> Fuctions, that you can very easily access with any
> Assembler, with a quite simple Table of Displacements
> Equates and with a quite simple Macro.

Yup; We're in complete agreement here...it's complicated by the
jargonistic nonsense Microsoft spout about "aggregating inherited
IUnknown pointers on an interface"...

Indeed...

> Of course, with HLA added confusion
> this might be a bit less simple, but i am quite sure
> that, when you will have understood the simplicity
> of these calls

Well, no...HLA can do it in exactly the same way...there is some
_optional_ "added confusion" of letting HLA do all that "counting up
in fours" for you using a structure, which adds all the "complex
confusion" of making it even simpler again...

[ And, for those that want it, you can add on "parameter checking" by
adding on the parameters...but if you don't add them on, HLA just
doesn't "parameter check" because there's no parameters...which
doesn't seem all that particularly confusing, really: add on
parameters, HLA checks parameters...don't add on parameters, HLA
doesn't check parameters because there are no parameters given to be
checked...kind of logical, that, really :) ]

> you will not miss to contribute to, in
> turn, misslead other beginners, with no base propaganda,
> for the damage of Assembly and for the personal glory
> of Master Self-Esteemed Randall Hyde.

As to this, it would seem that you're the one with "no base
propoganda" because HLA can _entirely duplicate_ the RosAsm method
you've just shown...it can also do a lot more besides, mind you...but,
whatever, HLA can use exactly the same method you've shown...create
some constants that "add up in fours" and a macro to automate the COM
call from those constants...using structures - as you've noted
yourself on occasion - is merely a case of getting the assembler to do
all that "counting in fours" for you to create the "offset constants"
automatically...and then you can use a macro to do it...

Hence, if HLA copying the RosAsm method is "no base propoganda for the
damage of Assembly" then so is RosAsm for using it too...

Beth :)

Beth

unread,
May 8, 2004, 4:43:17 AM5/8/04
to
Charles Banas wrote:
> NoDot wrote:
> >>(someone correct me if i'm wrong here somewhere. but i do recall
> >>reading that the vtables format Microsoft uses in DirectX kept GCC
from
> >>supporting it for a very long time.)
> >
> > The problem I seem to be having in HLA, it seems, is getting the
> > vtable information. I might be accessing it incorrectly. What is
> > their vtable format?
>
> since i'm neither a compiler programmer, nor intimately familiar
with
> Microsoft bastardizations, i haven't a clue.

Because you are neither, you are actually presenting it as far more
complicated than it really actually is...

A COM-object is a record that contains pointers to procedures...and
that's all...

You can concern yourself with all the object-orientated stuff but, as
has been contended, it's an awful lot of work for no particular reason
or benefit...considering it from a non-OOP point of view vastly
simplifies the problem without losing a sole "feature" from OOP...

For example, here's the HLA for "IUnknown" without parameter checking:

--------------- 8< ----------------

IUnknown: record

QueryInterface: procedure;
AddRef: procedure;
Release: procedure;

endrecord;

--------------- >8 ----------------

If you insist on some parameter checking, as you'd have under C++,
then merely "decorate" your procedure calls:

--------------- 8< ----------------

IUnknown: record

QueryInterface: procedure( ThisPtr: DWORD;
iid: REFIID;
ppvObject: LPLPVOID);
@stdcall; @returns("(type HRESULT eax)");

AddRef: procedure( ThisPtr: DWORD);
@stdcall; @returns("(type ULONG eax)");

Release: procedure( ThisPtr: DWORD);
@stdcall; @returns("(type ULONG eax)");

endrecord;

--------------- >8 ----------------

Note the simple addition of "ThisPtr" as the first parameter (I've
simplified the type to "DWORD" but it would actually be a
self-referential "pointer to IUnknown" if you insisted on _strict_
data typing...actually, if I recall, when I tried this myself, I had a
problem with "self-referencing" data types under HLA...something I was
going to talk to Randy about but completely plain forgot...it's
problematic so deserved a little "bug report", I thought...must have
another look at it, though, to remind myself what the exact problem
was so I can, this time, _remember_ to address it to Randy
specifically ;)...

That's really the only "OOPism" of any significance that you need
worry about: Just add "ThisPtr: DWORD" as the first parameter to any
procedure in the record (not listed in your DirectX C++-based
procedure prototypes because the OOP stuff in C++ adds it
automatically...just a case, though, of adding it manually ;)...note,
doesn't have to be called "ThisPtr"...that's just any old name I came
up with that just avoids any "clashes" with HLA's "this" keyword for
its OOP support...perhaps, for a touch of "comedy value", you could
just call it "that" instead of "this"? Or even "What-not-over-there",
if you really want to be silly about things ;)...

Also, the above assumes that the usual Windows data types are defined
("REFIID", "HRESULT", etc. ;)...but, if you don't care about your data
typing being that particularly strict, then just do the old
"everything's a DWORD" method:

--------------- 8< ----------------

IUnknown: record

QueryInterface: procedure( ThisPtr: DWORD;
iid: DWORD;
ppvObject: DWORD);
@stdcall; @returns("eax");

AddRef: procedure( ThisPtr: DWORD);
@stdcall; @returns("eax");

Release: procedure( ThisPtr: DWORD);
@stdcall; @returns("eax");


endrecord;

--------------- >8 ----------------

Works just as well, just HLA will now only be checking the size and
number of parameters, won't be checking their "formal data types" or
anything...for most ASM coders, this is good enough...

But, why not? Let's get the HLA plug in: The ability to be _more_
strict about data typing than even something like C...down to
"actually, only care that the number of parameters and sizes are
right"...all the way down to a completely undecorated "procedure"
only...is a somewhat unique HLA feature..._YOU_ decide just how much
"data typing" (including _NONE_ ;) that you want to use...

And, basically, every COM object will have its first three members as
above (that is, all COM objects are "inherited" from "IUnknown"
;)..."inheritance" can simply be tackled by either expanding it out
(really, "inheritance" in these HLLs is only just a "shorthand
macro"...an "intelligent automatic cut and paste" ;)...or,
alernatively, sticking one record inside another...

To explain, all that happens during "inheritance" is that one record
is "merged" with another...if there are no common members in both
records, this is literally a simple aggregation (in other words, you
put one after the other...yup, as simple as that ;)...the thing that
makes "inheritance" a touch different to just putting records inside
records is that any _common members_ are only listed _once_...the two
records are "merged" together...

But, with DirectX, you actually _don't need to know this_...as,
simply, all DirectX "COM interfaces" thus far have no common members
inside them at all (and this will probably always be the case...it's
"COM based" but only marginally so, in that Microsoft don't actually
use any of the wider COM / OLE "features" in actual practice at all
;)...hence, what you actually get in reality once you expand all these
"COM inheritance OOP macro" nonsense stuff out into what it really is,
is that every DirectX interface starts with those same three
"IUnknown" procedures and then you just list all the other ones for
that particular interface after it...DirectX does NOT make use of COM
"aggregation" features (you can note this in the "CreateXXX" methods
in the documentation which state "this functionality is not supported
as yet, supply NULL" for all that "lpOuter" nonsense ;)...

So, in practical terms, this means that you should just pop in the
three "QueryInterface", "AddRef" and "Release" procedures at the start
of every DirectX interface...these three are always at the start of
_ANY_ COM object because they are all to do with "COM Object
control"...for instance, you call "Release" when you finally want to
release the COM object, as you're not using it any more...you call
"AddRef" to bump up the "reference count", if you're duplicating the
pointers and need the object "held open" for both pointers...you call
"QueryInterface" in order to ask for different "interfaces" - by their
unique GUID (just a big number that's guaranteed to be unique so that
every COM interface is guaranteed to have a different GUID...and,
therefore, you can create your COM objects without fear of
"clashes"...Microsoft simply introduced this because COM objects can
be created with "CoCreateInstance" from _anywhere_ in the system, so
they needed a "naming system" which wouldn't introduce any "clashes"
or "conflicts"...for example, if they'd used ASCII names, then two
companies might both create a "IStringTable" object and - bang! - you
ask for "IStringTable" and get the _wrong_ interface...that would not
be a Good Thing at all...so, Microsoft simply use GUIDs - really big
numbers generated using a formula designed to ensure "uniqueness" (no,
no idea what that formula actually is...but, as usual, the "GUID" is
NOT a Microsoft invention so you can look around UNIX-y resources and
probably find the answer to that elsewhere) - to guarantee that if you
refer to interfaces by "GUID" then you'll always get the interface you
want because GUIDs are "guaranteed unique" so every interface -
whoever makes them - has a completely unique GUID number ;) - for this
particular object...

Other than an older DirectDraw interface where you "QueryInterface" to
get the Direct3D interface (this method, though, is now
_OBSELETE_...use a later version of DirectX, if you want Direct3D and,
again, you don't really need to know about this ;)..."AddRef" is
almost never used...that, in actual practice, the sole thing you need
care about here is calling "Release" to release your COM object when
done...the rest is "adminstration" nonsense that, in fact, you'll find
you never really have any instance to call in your DirectX code at
all...it's more there for the more complicated "OLE" stuff built on
top of COM...DirectX's COM interface just _don't_ go that far or get
that complicated...

So, basically, you don't need to know much of anything, really, in
actual practice...just pick your "interface" that you want then create
a "record" for each of the procedures with "QueryInterface", "AddRef"
and "Release" put as the first three procedures because all COM
objects start with these three "object control" procedures (if you
like, simply copy and paste the perferred one of the alternatives I
supplied above for "IUnknown" ;)...

For example, you want "IDirect3D9"? Okay...the first three procedures
in the record are going to be "QueryInterface", "AddRef" and "Release"
in that order...

Then you follow these with the "IDirect3D9" procedures...the order of
the "IDirect3D9" procedures might not be as listed in the
documentation, though...so, the easiest way? Grab the C / C++ header
file with the C / C++ definition in it (I would suggest using GREP and
then simply looking for "IDirect3D9" using GREP amongst your header
file directory...and just let GREP do all the hard work of actually
finding it for you ;)...

So, this is what we see in the C / C++ header file:

--------------- 8< ----------------

DECLARE_INTERFACE_(IDirect3D9, IUnknown)
{
/*** IUnknown methods ***/
STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE;
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
STDMETHOD_(ULONG,Release)(THIS) PURE;

/*** IDirect3D9 methods ***/
STDMETHOD(RegisterSoftwareDevice)(THIS_ void* pInitializeFunction)
PURE;
STDMETHOD_(UINT, GetAdapterCount)(THIS) PURE;
STDMETHOD(GetAdapterIdentifier)(THIS_ UINT Adapter,DWORD
Flags,D3DADAPTER_IDENTIFIER9* pIdentifier) PURE;
STDMETHOD_(UINT, GetAdapterModeCount)(THIS_ UINT Adapter,D3DFORMAT
Format) PURE;
STDMETHOD(EnumAdapterModes)(THIS_ UINT Adapter,D3DFORMAT
Format,UINT Mode,D3DDISPLAYMODE* pMode) PURE;
STDMETHOD(GetAdapterDisplayMode)(THIS_ UINT
Adapter,D3DDISPLAYMODE* pMode) PURE;
STDMETHOD(CheckDeviceType)(THIS_ UINT iAdapter,D3DDEVTYPE
DevType,D3DFORMAT DisplayFormat,D3DFORMAT BackBufferFormat,BOOL
bWindowed) PURE;
STDMETHOD(CheckDeviceFormat)(THIS_ UINT Adapter,D3DDEVTYPE
DeviceType,D3DFORMAT AdapterFormat,DWORD Usage,D3DRESOURCETYPE
RType,D3DFORMAT CheckFormat) PURE;
STDMETHOD(CheckDeviceMultiSampleType)(THIS_ UINT
Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SurfaceFormat,BOOL
Windowed,D3DMULTISAMPLE_TYPE MultiSampleType,DWORD* pQualityLevels)
PURE;
STDMETHOD(CheckDepthStencilMatch)(THIS_ UINT Adapter,D3DDEVTYPE
DeviceType,D3DFORMAT AdapterFormat,D3DFORMAT
RenderTargetFormat,D3DFORMAT DepthStencilFormat) PURE;
STDMETHOD(CheckDeviceFormatConversion)(THIS_ UINT
Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SourceFormat,D3DFORMAT
TargetFormat) PURE;
STDMETHOD(GetDeviceCaps)(THIS_ UINT Adapter,D3DDEVTYPE
DeviceType,D3DCAPS9* pCaps) PURE;
STDMETHOD_(HMONITOR, GetAdapterMonitor)(THIS_ UINT Adapter) PURE;
STDMETHOD(CreateDevice)(THIS_ UINT Adapter,D3DDEVTYPE
DeviceType,HWND hFocusWindow,DWORD
BehaviorFlags,D3DPRESENT_PARAMETERS*
pPresentationParameters,IDirect3DDevice9** ppReturnedDeviceInterface)
PURE;
};

--------------- >8 ----------------

Most of this is "compatibility" nonsense so that both C and C++
compilers can read the header files without blowing up (C++ has OOP
but C does not...hence, Microsoft have created a bunch of simple
macros that expand one way for C++ and another way for C that fits in
with their OOP / non-OOP syntaxii...in fact, what I'm demonstrating
with the HLA stuff? More or less a _duplication_ of what the C version
of the macros expand into ;)...

Right, it looks a total mess but that's Microsoft trying to be
"compatible" using special "macros" everywhere...so let me try to
clear away the "junk" here for you...

The "DECLARE_INTERFACE_" expands into a "typedef struct"...note,
interestingly, that even under C++, Microsoft still use _struct_ and
not "class"...the reason? "structs" and "classes" under C++ are
identical, in fact, except for the "default access rights"...this is
"private" for "class" and "public" for "struct"...due to the
definition of COM object interfaces, they _only_ contain a series of
"public:" procedures...hence, using "struct" automatically adds a
"public:" to the whole structure and saves trying to work out some
"macro" to expand this into the definition...so, even under C++,
there's nothing dubious about my "it's all just a record" assertion
because even C++ uses "struct" here, NOT "class"...it's that OOP
jargon nonsense confusing people again...note how complex it is
explaining this stuff in OOP terms but just how clean and clear it is
to do exactly the same thing _without_ the OOP jargon and manually
using non-OOP devices...I tell you, it's a conspiracy of jargon
_designed_ so no-one can understand what's actually very easy, so that
everyone rushes out to buy "OOP" books and go on "OOP" courses to give
all these people jobs and a source of income...it really isn't that
complex "under the hood"...it's, in fact, pathetically simple stuff
that you'll probably be just as annoyed as me that all that jargon
even exists at all...

[ The only reason for using a "macro" rather than just a literal
"typedef struct IDirect3D9" - which would apply to both languages, C
and C++ - is that (for, actually, no particularly useful reason in
actual practice ;) Microsoft want to do it "properly" so as
"IDirect3D9" is technically inherited from "IUnknown", the C++ expands
to: "typedef struct IDirect3D9 : IUnknown"...seeing, though, as all
the members are actually listed out in their entireity thereafter in
the actual correct order, this actually serves no useful purpose (all
the C++ compiler does when seeing such an "inheritance" device is use
it to work out the _order_ of inherited procedures...that
"QueryInterface", "AddRef" and "Release" must be in the _same offset
positions_ as they are in "IUnknown"...this is, in fact, quite
pointless in practice because Microsoft spits out the interface
definitions in the correct order, anyway...I suppose it's useful for
_them_ to have the compiler double-check things...but this serves
_us_ - using it - absolutely no good purpose whatsoever ;)... ]

Anyway, in our HLA conversion, simply using "Name: record" will do the
trick, basically...ignore the "inheritance" nonsense, we'll just make
sure that our procedures are listed out in the correct order (which
solely means "QueryInterface", "AddRef" and "Release" come _first_, as
the first three procedures, in all COM objects and everything else
just follows it...this won't be hard to do because the C / C++ header
files you're working from, _already_ have it in the correct order,
anyway...so, literally cut and paste..."inheritance" is, as I say,
only really a "shorthand intelligent cut and paste" device in OOPLs,
anyway ;)...then, just list each of the procedures afterwards in the
same order as you see in the header file...

In fact, one simple way to do it? Cut and paste whatever's between the
opening bracket after "DECLARE_INTERFACE" and it's matching closing
bracket over to your HLA source file between your "IDirect3D9: record"
and "endrecord;" statements...avoids the chance of you making a
mistake with the ordering if you just cut and paste it directly...

So, it looks something like:

--------------- >8 ----------------

IDirect3D9: record

/*** IUnknown methods ***/
STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE;
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
STDMETHOD_(ULONG,Release)(THIS) PURE;

/*** IDirect3D9 methods ***/
STDMETHOD(RegisterSoftwareDevice)(THIS_ void* pInitializeFunction)
PURE;
STDMETHOD_(UINT, GetAdapterCount)(THIS) PURE;
STDMETHOD(GetAdapterIdentifier)(THIS_ UINT Adapter,DWORD
Flags,D3DADAPTER_IDENTIFIER9* pIdentifier) PURE;
STDMETHOD_(UINT, GetAdapterModeCount)(THIS_ UINT Adapter,D3DFORMAT
Format) PURE;
STDMETHOD(EnumAdapterModes)(THIS_ UINT Adapter,D3DFORMAT
Format,UINT Mode,D3DDISPLAYMODE* pMode) PURE;
STDMETHOD(GetAdapterDisplayMode)(THIS_ UINT
Adapter,D3DDISPLAYMODE* pMode) PURE;
STDMETHOD(CheckDeviceType)(THIS_ UINT iAdapter,D3DDEVTYPE
DevType,D3DFORMAT DisplayFormat,D3DFORMAT BackBufferFormat,BOOL
bWindowed) PURE;
STDMETHOD(CheckDeviceFormat)(THIS_ UINT Adapter,D3DDEVTYPE
DeviceType,D3DFORMAT AdapterFormat,DWORD Usage,D3DRESOURCETYPE
RType,D3DFORMAT CheckFormat) PURE;
STDMETHOD(CheckDeviceMultiSampleType)(THIS_ UINT
Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SurfaceFormat,BOOL
Windowed,D3DMULTISAMPLE_TYPE MultiSampleType,DWORD* pQualityLevels)
PURE;
STDMETHOD(CheckDepthStencilMatch)(THIS_ UINT Adapter,D3DDEVTYPE
DeviceType,D3DFORMAT AdapterFormat,D3DFORMAT
RenderTargetFormat,D3DFORMAT DepthStencilFormat) PURE;
STDMETHOD(CheckDeviceFormatConversion)(THIS_ UINT
Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SourceFormat,D3DFORMAT
TargetFormat) PURE;
STDMETHOD(GetDeviceCaps)(THIS_ UINT Adapter,D3DDEVTYPE
DeviceType,D3DCAPS9* pCaps) PURE;
STDMETHOD_(HMONITOR, GetAdapterMonitor)(THIS_ UINT Adapter) PURE;
STDMETHOD(CreateDevice)(THIS_ UINT Adapter,D3DDEVTYPE
DeviceType,HWND hFocusWindow,DWORD
BehaviorFlags,D3DPRESENT_PARAMETERS*
pPresentationParameters,IDirect3DDevice9** ppReturnedDeviceInterface)
PURE;

endrecord;

--------------- 8< ----------------

Right, if you care nothing for "parameter checking", then literally
just clear away all the nonsense except the procedure's name and add a
":procedure" after each line...like this:

--------------- 8< ----------------

IDirect3D9: record

/*** IUnknown methods ***/
QueryInterface: procedure;
AddRef: procedure;
Release: procedure;

/*** IDirect3D9 methods ***/
RegisterSoftwareDevice: procedure;
GetAdapterCount: procedure;
GetAdapterIdentifier: procedure;
GetAdapterModeCount: procedure;
EnumAdapterModes: procedure;
GetAdapterDisplayMode: procedure;
CheckDeviceType: procedure;
CheckDeviceFormat: procedure;
CheckDeviceMultiSampleType: procedure;
CheckDepthStencilMatch: procedure;
CheckDeviceFormatConversion: procedure;
GetDeviceCaps: procedure;
GetAdapterMonitor: procedure;
CreateDevice: procedure;

endrecord;

--------------- >8 ----------------

If you _do_ care about the parameters, then...well...you've got your
DirectX documentation with the C / C++ prototypes, yes? Just
"decorate" the raw "procedure" stuff with the required parameters...

Something like:

--------------- 8< ----------------

IDirect3D9: record

/*** IUnknown methods ***/
QueryInterface: procedure( ThisPtr: DWORD;
iid: DWORD;
ppvObject: DWORD);
@stdcall; @returns("eax");

AddRef: procedure( ThisPtr: DWORD);
@stdcall; @returns("eax");

Release: procedure( ThisPtr: DWORD);
@stdcall; @returns("eax");

/*** IDirect3D9 methods ***/
RegisterSoftwareDevice: procedure(ThisPtr: DWORD;
pInitializeFunction:
DWORD);
@stdcall; @returns("eax");

GetAdapterCount: procedure(ThisPtr: DWORD);
@stdcall; @returns("eax");

GetAdapterIdentifier: procedure(ThisPtr: DWORD;
Adapter: DWORD;
Flags: DWORD;
pIdentifier: pointer to D3DADAPTER_INDENTIFIER9;
@stdcall; @returns("eax");

// ...
//
// Rest of IDirect3D9 procedures go here
// (I'm just too lazy to convert it all ;)

endrecord;

--------------- >8 ----------------

Note that the above points something else out...you'll also need to
define other records used by DirectX like "D3DADAPTER_IDENTIFIER9", if
you want to properly "type" your procedures...mind you, to a degree,
you _will_ need to define at least some of these other records which
provide parameter information to the procedures, just because DirectX
often passing around records of parameters to some of its
procedures...

Well, it's the same situation as I mentioned before, really...HLA is
happy with just "procedure" but it'll also accept you putting in
parameters and "@stdcall" and "@returns" and stuff, if you want to
"decorate" your procedure prototypes here to allow HLA to do some
"parameter checking"...also, due to the fact that HLA has strict data
typing but also the "typeless" DWORD too, you can even choose just how
"fussy" you want to be checking the "types" of your parameters...if
you don't care, then, usually under Win32, you can literally just
change it to "DWORD" because all the different types usually just
resolve into being a 32-bit DWORD...if you do care - and, with HLA, a
unique feature is you can be as _selective_ in how rigorous and strict
you want the "data typing" to be...from absolutely none at all, right
up to making C++ look like it has "loose data typing" - then simply
add in all the extra junk about parameters and calling conventions and
so forth...the "@returns" thingy allows you to write stuff like "if
(CreateDevice(parameters)==D3D_OK)" with the "HLLisms"...drop that if
you never use "IF" or "WHILE" or anything or just don't want that kind
of support from HLA...again, the uniqueness of HLA's methodology here
is that _YOU_ decide just how much stuff HLA does...it's _capable_ of
very strict data typing and "HLLisms"...but that capability is not
enforced...you can completely ignore it or only use it "partially" or
whatever...perhaps the only tool - and my support for HLA might begin
to be explained to those who don't understand - where the _CHOICE IS
IN THE PROGRAMMER'S HANDS_...every other tool has some "enforced"
scheme of "no data typing" / "strict data typing" and you have to fall
in line...HLA instead _provides the facilities_ for these things but
they are _only used_ when specifically requested...don't supply
parameters and HLA will simply not parameter check...if you do supply
them, then it will parameter check if you use the "HLLism" version of
"CALL"...if you do supply them and push parameters manually and use
"CALL" directly, it does NOT check...so, in fact, you could, say,
create a bunch of header file _with_ the parameters and everything in
place but, even then, HLA allows a programmer to _choose_ not to have
parameter checking by doing it all manually...hence, the assertion
that HLA "enforces" anything is the least applicable accusation there
is...HLA is perhaps the _only tool_ which does NOT do such a thing, be
that HLLs or ASM or whatever...the only tool to take the kind of
approach I support: "here's the facilities so if you want it, you can
have it...but, if you don't want, then don't use"...Randy is not
"copping out" when he says these things at all...he's pointing out one
of HLA's unique features that you'd be hard-pressed to find _any_ tool
providing, be that script language, HLL or ASM ;)...

And, basically, repeat for all the "COM objects" you're interesting in
using...it's _tedious_ work, rather than "difficult" work...you can,
as I've suggested, literally copy and paste the stuff out of the C++
file, trim off the macro nonsense and add ":procedure;" after each
line (which itself is always the same so write it once and then "copy
and paste" it after each line ;)...

Also, note, that there's no compulsion to use "records"...this just is
a sensible approach...but someone like Rene might insist that this is
"not assembly"...well, fair enough...you can copy the RosAsm approach
to this by converting the above structure into a list of offset
constants and use those instead...such as:

--------------- 8< ----------------

const

IDirect3D9_QueryInterface := $00000000;
IDirect3D9_AddRef := $00000004;
IDirect3D9_Release := $00000008;

IDirect3D9_RegisterSoftwareDevice := $0000000C;
IDirect3D9_GetAdapterCount := $00000010;
IDirect3D9_GetAdapterIdentifier := $00000014;

// ...
//
// Rest of IDirect3D9 procedures go here
// (I'm just too lazy to convert it all ;)

endconst;

--------------- >8 ----------------

The advantages of the "record" approach, which Rene deems
"anti-assembly", is that you can do "@size(IDirect3D9)" and get HLA to
work out the size of the entire interface rather than count it up
yourself...and that you don't need to become an expert in counting up
in fours in hexadecimal...

[ Yes, I don't really understand Rene's argument here either...how
does counting up in fours in hexadecimal make you a "real assembly
programmer", while letting the tool do it automatically some "evil
anti-assembly propoganda to aid Monsanto Nazis force Third Farmers to
kill everyone with McDonald's cheeseburgers"? Well, Rene, seems the
connection is so "clearly defined" and obvious that it only takes an
"assembly genius" of your calibre to understand the connection between
"evil camp" rule of the universe and counting up in fours in
hexadecimal...you'll have to forgive the rest of us for kind of
thinking that you're talking completely crap...but, hey, it's so
surreal - like some sketch from Monty Python - I can't help but find
it absolutely hilarious...so, keep it up, as we can all do with a
smile from time to time ;)... ]

Oh, the reason for inserting the "IDirect3D9_" stuff in front of each
constant? Well, Rene would find "scope" to be very
"anti-assembly"...hence, to avoid any "name clashes", we can throw
this in front of each constant to get much the same as "scoping"
without violating Rene's rule that it's "anti-assembly" to, ummm, let
an assembler do any of the work...I suppose it's also "anti-builders"
to let builders build things too...looks like we'll all have to build
our own houses "manually" brick-by-brick and not hire Rene to build
them, as we'd be an "evil affront" to the building trade by actually
wanting to give the experts some work to be doing...

When calling any of the procedures, of course, you must remember that
we've added that first parameter - "this" - to each procedure...so,
push the address of your interface record onto the stack as the first
parameter before making the "CALL"...this can be simplified into some
"COMCall" macro that automatically pushes the address as well as
calling the procedure offset from the same address for convenience
because it's always the same thing for any COM procedure call (that's
really the thing that the C++ compiler does "behind your back"...it
automatically adds on the "this" as the first parameter and
automatically push the "this" address on the stack as the first
parameter when you call...because this is always the same thing every
time, the C++ compiler can "automate" the process and simply hide it
from view...do I agree with this "hiding"? No, not at all...BUT
_that's what happens_, my own views aside for the moment :)...

COM objects can be simplified greatly when addressed without the
confusing OOP jargon...a "COM interface" is: a record of pointers to
procedures, where every pointer takes the address of that record as
its first parameter...the first three procedures are "QueryInterface",
"AddRef" and "Release" in that order (these are to "control" the
"lifetime" of the object...in practice, you'll just use "Release" to
close down the object when you're finished...you _might_, perhaps,
need "AddRef" if you're copying the pointer around a multi-threaded
application or something...but probably not..."QueryInterface" tends
to be useless for DirectX because, instead, you grab your first
"interface pointer" by using an ordinary API function like
"Direct3DCreate9" and then all the other COM objects tend to be
"connected" (e.g. you can create a "Direct3DDevice9" by calling the
"CreateDevice" procedure in the "IDirect3D9" you're provided...from
that interface, you can call procedures to create textures and so
forth...there also tends to be a "backlink" procedure with every
interface too, anyway...that is, the "IDirect3DDevice9::GetDirect3D"
procedure returns the "IDirect3D9" pointer that the "device" was
created from, anyhow...DirectX keeps track so you can always ask if
you "get lost" but then you're never going to "get lost" keeping track
of your pointers, anyway, are you? If you know what's going on,
there's actually very little use for these "backlink"
procedures...added, no doubt, just to support some similar API call
for VB programmers in the VB interfaces to DirectX because they tend
to have no idea what they are doing that such redundency is
"useful"...but like plotting your own graphics, there's actually often
never any legitimate need to read from the screen itself (a slow
operation)...rather read from your data and _know_ what's on the
screen instead ;)...

COM isn't overly complicated and DirectX doesn't even use all of its
feature, anyway, that using it for DirectX is even more
simplified...and there's nothing particularly "HLA specific" in the
methods mentioned here (well, other than the extra support HLA
provides for parameter checking on all the procedures...which is
optional, if you don't like or don't care :)...you can use a
"structure" in some other assembler like MASM or NASM (HLA just likes
to call this "record" instead ;)...using the constants method will
work in assemblers that find structures to be "anti-assembly"...

I Hope this begins to clarify things...there's more I could write and
I did start a bunch of HLA header files for DirectX before (well, I
know what to do so I could put together a bunch of them with all the
parameters and so forth then hand them over to Randy to put in HLA "as
standard" :)...but it's very tedious stuff to do it for _all_ of
DirectX (and I was putting in support for _all_ the versions
too...well, again, more of the same...not more "difficult", just "more
tedious" ;)...and then I got distracted doing other things and it
really is exceedingly boring to do that I couldn't get motivated
enough to be bothered to go back to it...I may eventually get around
to finishing that off so that then HLA has it "as standard"...it's not
that, magically, HLA can't do it but RosAsm can...it's a case of
RosAsm having the tireless Guga putting together all the "equates" for
Rene (a massive and tedious piece of work to do...hats off and respect
to Guga for the support...without that work being contributed to him,
Rene would not be able to smile as widely as he does ;)...where
"equates file" is just RosAsm's version of the same kind of "header
file" thing I mentioned here for HLA...Randy's a productive little
worker, indeed, but there are limits to what one person can do (and
writing all those books and articles and just getting HLA functional,
as well as work on HLA v2.0...well, he's already doing enough to make
everyone else look a touch lazy ;)...well, stuff like this - as well
as needing similar "header files" for LuxAsm - that prompted the
"okay, this is getting silly...isn't there an easier way to do this
with some automated tool rather than slogging through it all line by
line?"...a great idea but still no real response to the ConvInc
project I set up on SourceForge...I guess I should accept no-one's
interested - or won't get interested until some "version 1" has been
written - and that I should just plough on ahead by myself on
that...this is fine but, well, didn't want to march on ahead and then
have people show up all confused and disagreeing with what I've done
and that kind of thing...but, hey, if there's no "team", in fact, then
there's no need for me to consider "being a team player" or "the need
for teamwork" and that kind of thing...I'll just plough on ahead and
see if anyone becomes interested later once I've got something basic
working or whatever...

Beth :)

Beth

unread,
May 8, 2004, 4:59:28 AM5/8/04
to
Randy wrote:
> Personally, I've never worked with Direct-X, so I can't offer
> any more insights into this issue. However, you might ask
> Beth Stone, who has played around with Direct-X in assembly
> a bit.

Indeed; I've posted up my assistance now...sorry about the massive
delay...too many other threads in the newsgroup going on and kind of
missed this one until now (just quickly looking over things)...Hope
I'm not so exceedingly late in reply that I've missed the original
poster completely...oops! ;)...

Beth :)

Kain

unread,
May 8, 2004, 2:10:29 PM5/8/04
to
"Beth" <BethS...@hotmail.NOSPICEDHAM.com> wrote in message news:<qR0nc.19$Gz...@newsfe5-gui.server.ntli.net>...

>
> You can concern yourself with all the object-orientated stuff but, as
> has been contended, it's an awful lot of work for no particular reason
> or benefit...considering it from a non-OOP point of view vastly
> simplifies the problem without losing a sole "feature" from OOP...

Thanks Beth. This has been a very useful article in helping me
understand some of those pesky C++ header files.

Beth

unread,
May 9, 2004, 5:41:47 AM5/9/04
to
Kain wrote:

> Beth wrote:
> > You can concern yourself with all the object-orientated stuff but,
as
> > has been contended, it's an awful lot of work for no particular
reason
> > or benefit...considering it from a non-OOP point of view vastly
> > simplifies the problem without losing a sole "feature" from OOP...
>
> Thanks Beth. This has been a very useful article in helping me
> understand some of those pesky C++ header files.

Pleasure...

Beth :)

Beth

unread,
May 9, 2004, 8:09:32 AM5/9/04
to
Randy wrote:

> NoDot wrote:
> > HLA passes the this pointer in esi. C++ passes the this pointer
on
> > the stack. Problem.
>
> If you're using HLA *classes* and the high-level HLA class
invocation
> mechanism, it uses ESI. However, don't forget that you can easily
pass
> the object pointer on the stack yourself (this is assembly language,
after
> all, you don't *always* have to use the high-level features in
assembly
> :-)).
> If you like clean, HLL-like syntax for the calls, you can easily
create a
> macro that does the work for you.

True; But as COM "objects" don't carry any data - only a "table of
pointers" - and you're already giving up on the "class invocation
mechanism" then it begins to become a case of: "Why use _any_ of the
HLA class stuff at all for COM?"...

The "record" stuff works admirably (and, in actual fact, is what C
uses, of course...because C++ has OOP but C doesn't...Microsoft use
special "macros" in their header files that expand different ways to
support the two simultaneously...mind you, incredibly messy that I'm
wondering if it wouldn't have been simpler to make separate C and C++
headers for those particular bits and then perhaps an "#ifdef", just
to select whether to include the ".h" or the ".hpp" ;)...mind you, so
does Rene using his "offset constants" stuff too...

Beth :)


Beth

unread,
May 9, 2004, 8:09:46 AM5/9/04
to
Charles Banas wrote:

> Randy wrote:
> > What the OP needs is a header file with the proper definitions for
the
> > DirectX
> > calls, which is true, again, for nearly every language that
interfaces to
> > external
> > functions. As has been pointed out, these external definitions are
very
> > simple
> > to create (in HLA, as in MASM, etc.), so the best advice to the OP
is to
> > study the Direct-X tutorials for MASM and create the appropriate
external
> > declarations for HLA.
>
> which i submit is a difficult task given that DirectX makes copious
use
> of C++ classes with just about every feature known to man:
> multiple-inheritance, virtual functions, etc.

To which I submit you're displaying a misunderstanding of COM itself
here...

"COM" - the "component object model" - is a _language-independent_
binary standard for object-orientation...in other words, COM is
_DESIGNED_ to have no "bias" whatsoever to any language...it's a
_binary standard_ below language considerations exactly so that OOP
can be offered by the OS to _ANY_ programming language...a COM
"interface" only consists of public procedures and no data whatsoever,
as procedures are "universal" (the target of a "CALL" instruction ;)
and have "conventions" defined across languages, whereas data and data
types vary significantly from language to language...

The header files that Microsoft produce in order to use C++ to
_interface_ with DirectX may make use of C++ classes (which is
actually somewhat inaccurate and standardised and simplified by COM's
structure, anyway)...but "DirectX" doesn't...it uses COM which is a
binary standard for object-orientation that is actually _simplified_
by this...

The jargon of "multiple inheritance" (actually, where does this happen
in DirectX specifically? All the "interfaces" I've looked at inherit
from "IUnknown" and only "IUnknown"...yes, this kind of thing happens
in the more complicated "OLE" stuff that's built atop of COM...but not
in the underlying COM binary standard itself...DirectX is COM - and a
simplistic use of it at that - not OLE) and "virtual functions"
unnecessarily complicates the matter...I really wish this jargon would
either be properly explained or just disappear...

A COM object is just a structure (or "record") of procedures, where
they take a pointer to that structure's address as their first
parameter ("this")...when a procedure has a "this" pointer to the
structure that contains it, it gets renamed a "method" just to
distinguish this property..."inheritance" is basically the practice of
_merging_ two structures together (that is, putting both members into
one structure BUT, where there are common members, these are "merged"
and listed just _once_)...a "class" is the _definition_ (the "typedef
struct" ;) of that structure, an "instance" is a variable instance of
that structure...

In the case of DirectX and COM, the "virtual functions" thing is a red
herring that complicates things...as COM is separate from the
programming language (which may or may not have OOP features in it :),
this is actually a consequence of trying to view a simple use of
structures from the viewpoint of the OOP jargon...what's actually
happening is quite simple...

A COM "interface" is a structure / record of procedures...when you get
an "interface on a pointer" (that's what Microsoft call it to confuse
the matter...this simply means "when you get a pointer to one of these
'interface' structures" :) handed to you by some API like
"Direct3DCreate9" (which is just an ordinary DLL function)...the
structure that it points to is _filled out with the actual addresses_
of the various procedures you can call...but when you're defining
these structures in your source code, you are just "reserving space"
for each procedure...you're not actually filling these out with the
actual addresses of procedures because, at this point, you don't know
what those addresses are going to be, as it's the DirectX DLLs which
supply them...

Now, ordinarily, when using C++, you define your "structure" with the
"class" keyword and then write the procedures that will be stored in
that structure...the C++ compiler automatically creates a table of the
addresses and loads this into the structure when you create an object
of that type...this is perfectly possible because you're defining the
"class" structure _and_ the procedures that will go into it at the
same time...

But this doesn't make sense when the objects are _EXTERNAL_ to the
program...their addresses must be supplied by that external DLL file
or whatever...hence, you are only making use of declaring these
procedures as "virtual methods" in order that you are only "reserving
space" for where the procedure address will go, not actually attaching
any address to it yourself (when you get a COM object structure from
the OS, the addresses will be provided then)...

To try to clarify even more obviously, this is your "interface"
definition...using MASM syntax because this syntax makes it abundently
clear what the "virtual" stuff is actually for:

----------------- 8< ---------------------

ISomeObject struct

QueryInterface dword ?
AddRef dword ?
Release dword ?

MethodOne dword ?
MethodTwo dword ?

ISomeObject ends

----------------- >8 ---------------------

The "virtual" really means the same as the "?" here...that you're only
_defining_ the structure of the interface, you're NOT yet assigning it
any actual addresses...when you get an "interface" passed to you by
DirectX, each of the "dword" entries here will actually contain an
_actual address_ for the method call...but, in your code, you define
only the _structure_ and it's DirectX that supplies the actual
addresses (that "fills out" your structure with useful data :)...

The need in C++ to put "virtual" on this is because, ordinarily, the
classes you define are your own classes defined _internally_...that
is, I'd also be including the source code for
"ISomeObject::MethodOne", "ISomeObject::MethodTwo" elsewhere in my
source code...when the compiler compiles this "class", it creates the
above structure...but it also creates a VMT ("virtual method table")
where it will create a table of procedure addresses to the "methods"
defined by this class in the correct order...in other words, this
"table" is the empty structure _filled out_ with the correct
addresses...as part of creating an object (using "new" ;), the C++
compiler inserts some code ("hidden" code ;) which copies the "VMT"
data with the actual addresses into a newly allocated structure of the
type "ISomeObject"...

Well, in the case of an object that's _external_, then we don't
actually know what those addresses are going to be yet...hence, you
declare them "virtual", which means they aren't to be alloted any
specific addresses (the use of "?" in MASM there to define the
structure without specifying it should have any initialisers
;)...those addresses will be provided when DirectX hands you an
"instance" of the structure that's properly filled out...

This is another case of the jargon and OOPL stuff actually
_complicating_ what is actually a simple matter:

DirectX hands you a table of procedure addresses (where according to
its definition, the first procedure address in the table is for
"QueryInterface" for this object, the second procedure address in the
table is for "AddRef" for this object, the third procedure in the
table is for "Release" for this object...presuming my example above,
the fourth procedure in the table is for "MethodOne" for this object,
the fifth procedure address in the table is for "MethodTwo" for this
object...and so on and so forth)...

There's only one remarkable thing about these procedures: Their first
parameter is always a pointer to the start address of this table
itself...the so-called "this" pointer...

What does the "this" pointer do? Well, you can create many instances
of this object structure (for example, you may have a "texture" object
under DirectX...well, your 3D scene requires more than one "texture"
and, thus, has one of these structures for each texture :)...on the
other hand, the procedures inside the structure are likely to all be
the same for each instance of that object so those address filled out
are likely to be exactly the same address for each procedure...hence,
all that the "this" pointer does is provide those procedures with the
address of the instance's structure so that it knows to work on the
right object...it acts as a "handle to an object", which just so
happens to be the address of its structure (being an address, it's
automatically guaranteed to be "unique" for each object because you
can't put more than one thing in the same memory at the same time ;)
so that the procedure can not only identify the object, it can jump
directly into its contents...

If you've used the C standard library, then you might have noticed
that the standard file I/O functions return you a "file handle"...but
the "type" of this "file handle" is "FILE *"...or, in fact, a "pointer
to a FILE"...what's the "FILE" data type? A structure containing all
the data that relates to a "file" for the procedures to use in
manipulating it..."fopen", "fread", "fwrite", "fclose" all take a
"FILE *" file handle as one of their parameters...to initialise the
contents of the structure with valid information, you must call
"fopen" first to open the file and this procedure fills out the
internal details into the structure..."fread", "fwrite" and "fclose"
read the contents of the "FILE" structure in order to get data from
the structure about the current file...also, the actual layout of the
"FILE" structure is implementation-dependent...you shouldn't really
need to ever look inside it or know what it's definition is
("information hiding")...

Yup, a file with these stanard library functions is really an
"object"...but just implemented without OOP...you'll note that files
are not unique in having an "open" function which returns some kind of
"handle", which you then pass onto other related functions which
manipulate the "object" in some way before handing it to some "close"
function...this layout is, in fact, so common, they invented OOP to
standardise the mechanisms...invented languages where you could use a
bunch of OOP "keywords" which would automatically layout code in this
thing "encapsulated" form...automate lots of the "hard work" and
repetitive bits of implementing something like this...

While they were at it, they also decided that if they put the
addresses of the functions like "fread", "fwrite" and "fclose" into
that "FILE" structure too then you could do some other clever stuff
like actually change the address of one of these procedures at
run-time...because another common thing was to notice that you'd often
get "common" stuff in your objects...wouldn't it be kind of cool to
NOT copy this _common code_ into both objects but to, well, change
that address in the structure instead? That is, we could create two
"FILE" structures but then change the "fread" and "fwrite" on one of
these "FILE" structures to use a different procedure instead...but all
the other procedures are the same...so, this changed structure kind of
"inherits" the stuff from the standard "FILE" structure but changes
things and adds new bits on...yup, "inheritance"...and, yup, putting
the addresses of the functions into the structure? "virtual
methods"...

OOP is NOT "voodoo black magic"...it _doesn't_ need all the fancy
jargon (which, to be honest, almost universally _confuses_ people more
than it clarifies things for them ;)...it was an idea based on
_practice_...programmers were noticing a common pattern of having a
bunch of data (usually in a structure, just to keep it altogether :)
that you'd allocate and then call some "Initialise" function on, which
initialised the data in the structure to initial / default
values...then there'd be a bunch of procedures that you'd call,
supplying the address of the structure of data, which would do things
and manipulate the values of that data...then, after use, they'd be
some "Uninitialise" function which closed things down and de-allocated
memory and that kind of thing...and all these things related to some
kind of "object", like "a file", "a printer", "a texture" or
whatever...some, in fact - though not Soustroupe, who reckons the
"multi-paradigm" (that you can use it OOP or non-OOP at the same time
;) stuff in C++ is one of its strong points - were even going so far
as wondering if you couldn't simply make _everything_ an "object" and
always follow this layout...

OOP was just the attempt to add on keywords and support to programming
languages to be able to automate all the bits that were always the
same when following this "object" kind of way of structuring your
program...and it is, in fact, somewhat a _betrayal_ to the initial
_PRACTICAL_ (and even slightly "hackerish") origins of OOP that it has
now been covered in impenetrable jargon and is the "academic's
darling", full of "theories" and an awful lot of that academic
bullshitting about how it's some "new philosophy for living!", "it's
the Second Coming!!" and so forth...

Nope, it's just about laying out your code in an organised and ordered
fashion, based around using "structures" (just a group of contiguous
data variables...put next to each other for convenience of doing
things like copying it all in one go ;)...I've said here before but I
would rename what "OOP" stands for: "Ordered and organised
programming"...that's all it is really about...standardising a method
of programming in an ordered and organised fashion (that all other OOP
practitioners are also following)...

> wrtiting support for all of that in a language is no easy task, i'm
> sure, and creates quite a bit of difficulty in calling any DirectX
code.

Ummm, Rene manages the support in RosAsm with a bunch of constants and
an indirect CALL!! Which is fair enough, as all "structure support"
is, is a thing for, well, automatically generating "offset constants"
(and, though TASM doesn't agree, handling "scope" and stuff ;)...

One of the main design criteria of COM was that it should be
"unbiased" and could be used in _any_ programming language...the sole
criteria that you absolutely need is to be able to "CALL" a procedure
via a "pointer variable" (an "indirect" function call ;)...if you can
do that in your language, you can use COM...it was _DESIGNED_ that
way:

"The only language requirement for COM is that code is generated in a
language that can create structures of pointers and, either explicitly
or implicitly, call functions through pointers. Object-oriented
languages such as C++ and Smalltalk provide programming mechanisms
that simplify the implementation of COM objects, but languages such as
C, Pascal, Ada, Java, and even BASIC programming environments can
create and use COM objects."

[ From Microsoft's COM documentation...actually, the _third paragraph_
in the COM documentation that you don't have to read too far into it
to find it...does _ANYONE_ "RTFM" anymore? ;) ]

Note, for the "structure of pointers", I'm disagreeing with Microsoft
that is a strict "requirement" because Rene gets by with "offset
constants" as a replacement for "structure support"...and you could
also - as all COM interfaces include _only_ procedure addresses, only
"pointers" - also consider a COM object as "an array of DWORDs" (well,
"array of pointers", which just happens to be DWORDs on an x86
machine, to be more precise to avoid the pedants ;) because all the
elements in a COM object "structure" are actually all the same
size...and it's only a logical thing between a "structure of equally
sized elements" and an "array"...

If you _IGNORE_ the C++ and OOP jargon and the other "Jackson
Pollocks" found in most documentation to confuse you, then it's
actually almost _offensive_ the degree to which they make it sound
like complex neuro-surgery with the OOP jargon, when it's quite the
opposite and, actually, exceedingly _easy_ to use and understand...

DirectX passes you an "array of procedure pointers"...each entry in
this "table" is a different procedure (the order can be determined by
looking at some DirectX header files, like the C / C++ ones Microsoft
provide...it's quite "poor show" that the DirectX documentation
doesn't _explicitly_ state the order of the entries in the
table...but, as we've seen, they don't seem interested in actually
explaining any of it in a _useful_ manner ;)...they all take the
address of the table itself as the first parameter (so the procedure
can "work out" which one of many possible similar structures it
actually is working on this time ;)...that's it in terms of the
physicality...

In terms of use, you call an ordinary API function like
"DirectSoundCreate" or whatever to get your first "table of
pointers"...after that, these tables tend to point to one another
(that is, "IDirect3D9" has a "CreateDevice" to get a
"IDirect3DDevice"...or "IDirectSound" has a "CreateBuffer" to get a
"IDirectSoundBuffer"...and so on and so forth...once you've got one of
these structures, they tend to be designed that you just use the
procedures in the structures themselves to do everything...you just
need the DLL API function to "start you off" with the first table /
record / array / structure to get yourself _into_ this "maze of
pointers" ;)...

Each "object" is responsible for its own "lifetime"...which is
actually maintained by just keeping a "reference count"...when you
create an object, the reference count goes to one...when you call
"Release" to say "there, finished.", the reference count is
decremented by one ("AddRef" does the reverse and adds one onto the
count...you can use this to "hold open" objects or when you copy
pointers around a program...you can add one onto the count - increase
it to two - to say "okay, two 'clients' are holding pointers to it at
the same time, expect two 'Release' calls before closing from each of
them" ;)...when the count is zero, the object actually de-allocates
itself..."QueryInterface"? Mostly pointless...the idea is that some
objects may have more than one type of "structure" that applies to
them, so you can use "QueryInterface" to get the other type of
structures for this object...used by OLE, not by DirectX (the idea
being that you could create an "interface" like "IStorage" which
contains "Load" and "Save" procedures inside it...well, you could
"re-use" that kind of "interface" on a whole bunch of objects...it's
like some "code re-use" stuff that is more effort than it's worth that
DirectX doesn't bother, OLE uses it a bit but, well, you can tell that
not even Microsoft are particularly impressed with "QueryInterface"
and don't bother using it much either ;)...

As for the rest of the procedures in the "interface"? Well, that all
depends on what object it is...read the DirectX documentation for that
stuff about how to do flashy 3D graphics and stuff with the
"interfaces" ;)...

> IMHO, the solution to the issue is to create a wrapper library
(written
> in C++) that exports (in a C or Pascal-like calling convention) all
of
> the functions that one might need to write DirectX code. AFAIK,
other
> than OpenGL/DirectX wrappers, no such wrapper exists.

For ASM use? Doesn't seem worth the bother...it really isn't that
complex...what you're suffering under is the stream of OOP jargonising
confusion and really badly written documentation about how it
works...DirectX hands you a "table of pointers"...you indirectly call
the right entry in the table, passing the address of the table itself
as the first parameter (also, of course, push the other parameters -
if it has any - too ;)...and...and...that's it...

The real problem is all the tons and tons of "interfaces" and
constants and flags and structures and all that...real tedious to
create your own sets of header files for these things...but, well, for
HLA, no-one has appeared to have done it yet (I was working on it but
it really is _immensely boring_ that I got bored...if I can manage to
keep my eyes open, then I might finish these and pass them onto
Randy...then, at least, only _one_ person has to go through all the
really tediously boring stuff of creating records here and records
there ;)...

There's also somewhat limited support on all the assemblers for
this...it's pretty cool to find, usually, a full set of Win32 API
header files...DirectX tends to be not there or it's just the earlier
DirectX 3 only or something like that...RosAsm seems to have some of
the furthest work in getting DirectX supported (well, it's "specific"
so stands to reason ;)...but even Rene has to admit to it not being
fully supported, just "mostly supported" (better than most everyone
else, though...so no "insult" intended at all there ;)...

> >>i don't know how much time you have on your hands, but if you want
to
> >>implement an object-based library that exports DirectX calls in a
usable
> >>calling convention, then you, sir, are very talented.
> >
> > OTOH, he might also be using HLA, which allows the creation of
> > object-oriented modules in assembly a breeze. :-)
>
> which, honestly, still seems like quite a feat with all fo the
features
> and code bloat that DirectX takes advantage of.

Ah, DirectX itself might be bloated (though, it is one of Microsoft's
"finer" bits of code...basically because it does as little as
possible...just really a kind of "filter" sitting on top of the device
drivers, which actually do all the impressive work ;)...but the
interface to it isn't...

Mind you - addressing Randy now - the creation of _COM_
"object-orientated modules" ain't quite such a breeze...it _would_ be
if "this" could also be passed via the first parameter on the stack as
well as ESI, somehow...that's why, in my examples, Randy, I'm using
"record" and not "class"...it's _good_ that you've put "this" into a
register for HLA for OOP code generated in HLA itself...but, well, the
C++ / COM stuff isn't so concern for "optimised" solutions, as you
might imagine...so they stuff it onto the stack like all other HLL
function parameters...if you could allow a touch of "customisation" to
the OOP support to specify where "this" is passed?

A "compatibility" thing, really...ESI is a good place to pass it for
HLA classes...but, well, to fit in with C++ / COM classes, then you've
got to do it the same way as them to be "compatible", whether that's a
good idea generally or not...much like passing parameters in registers
is much better for lots of ASM code but you've got to put them onto
that stack when it's "STDCALL" or "CDECL" and so forth...

> >>(someone correct me if i'm wrong here somewhere. but i do recall
> >>reading that the vtables format Microsoft uses in DirectX kept GCC
from
> >>supporting it for a very long time.)
> >
> > That's the beauty of assembly language.
> > You can interface with just about anything.
>
> including Microsoft's COM code bloat?

Yes; In fact, drop the "just about"..._THAT_ is the beauty of assembly
language, you can interface with _ANYTHING_...absolutely no
"qualifier" attached at all...in assembly language, you can generate
_any_ sequence of "zeroes and ones" that you like...so - other than
some bizarre "non-binary computer" - you can interface to
_ANYTHING_...

Now, ah, whether it's "easy" to do that is another matter...I won't
make any guarantees about it being "easy"...quite the opposite...some
things would be stupidly complex to interface to...but, luckily for
you if you want to use DirectX, COM actually _isn't_ one of those
things...

> the comp.lang.C++ FAQ outlines some of the problems in section
[32.8,
> 9]. http://www.parashift.com/c++-faq-lite/

Actually, many of the "complexities" you're looking are actually about
the _reverse_...the ASM is _simple_ but the C++ - having twisted
itself up in knots with a very _particular_ method of structuring its
OOP support - has to "jump through hoops" to effectively "undo" its
own complexity...

Oh, yeah...I know...everyone tells you "ASM is complex, ASM is
difficult, ASM is impossible" and so forth...so how could ASM actually
be the one where things are _easy_ but C++ is where it is
unnecessarily complicated?

Welcome to the wonderful world of the misrepresentative "myths" about
ASM coding that are spread as gossip out there...working at the most
elemental and low-level possible can actually _SIMPLIFY_ some tasks...

> i don't deny it's possible to se DirectX from HLA. but is it worth
all
> of the work involved in *CREATING* the header files and libraries
you need?

It's not that much work...although, admittedly, I feel asleep in the
middle of trying...but that's because it's _tedious_ (grab a structure
from the C files, change the syntax, grab another, change the syntax,
grab another...and so on for far, far too many structures for one
small mind like mine to cope with ;)...it's not "difficult",
though...I gave a rough "cut and paste" method to get basic support in
one of my other posts...literally, "copy and paste", strip off macro
crap, add ":procedure;" to each line...then repeat for every
structure...in fact, using that way I might have got through it
without falling asleep but thought that "if you're going to do it, do
it properly" and added in all the parameters and stuff too...

Oh - note to Randy - there's a method in one of the Direct3D
interfaces called "Begin" and another one called "End"...keyword
clash!!! Still trying to work out what it would be best to rename them
to...but perhaps you get why I was talking about keeping "namespaces"
as "unpolluted" as possible...mind you, Microsoft's naming strategy
just isn't good for ASM, anyway...such as all that "cx" stuff (great
"role model" example of a "descriptive meaningful label name" there,
eh? How many out there, not knowing Microsoft's conventions, could
work this out as meaning "width"? Another good thing about
X-Windows...it calls the width parameter "width" (and height is
"height" ;), as you'd kind of expect, naturally enough...Microsoft
thinks "cx" says "width" to people...just exactly what planet - or
should that be solar system - are they living in? ;)...

Beth ;)

NoDot

unread,
May 9, 2004, 1:40:23 PM5/9/04
to
"Beth" <BethS...@hotmail.NOSPICEDHAM.com> wrote in message news:<d21nc.20$6V3.5@newsfe1-win>...

Beth, if your correct, then I've been right all along about the VTable
format.

That being the case, I must have another bug in the system. This is
what I've created for a micro-test:

-------------------------------------------------------------------
Program DXTest;

#asm;
includelib \masm32\directX\all-libs-except-d3dx8\d3d8.lib
#endasm;

Procedure D3DCreate;
@external("__imp__Direct3DCreate8@4");

Const
IDirect3D_Release := 8;

Begin DXTest;
pushd(31);
call(D3DCreate); // Create the Object
push(eax);
mov([eax], eax); // Load VTable
call([eax+IDirect3D_Release]);
add(8, esp); // Clean the Stack
End DXTest;
-------------------------------------------------------------------

The program ends with a terminating message in the form, "This program
has preformed an illeagal operation." blah. I'm using DirectX 8. Can
you tell me what's going on?

The Half a Wanna bee

unread,
May 9, 2004, 6:18:43 PM5/9/04
to
> pushd(31); ------------------------------This should be 120d/78hex

> call(D3DCreate); // Create the Object
> push(eax);
> mov([eax], eax); // Load VTable
> call([eax+IDirect3D_Release]);
> add(8, esp); // Clean the Stack <------------------- Is this needed ?

Betov

unread,
May 10, 2004, 2:47:00 PM5/10/04
to
The Half a Wanna bee <shaka...@hotmail.com> icrivait
news:409e9f0f$1...@news.broadpark.no:


:)) An empty answer is a bit surprising, at first look,
but after thinking of it, it seems to me the most
appropriated answer... :))


Betov.

< http://betov.free.fr/RosAsm.html >


Frank Kotler

unread,
May 10, 2004, 4:05:52 PM5/10/04
to
NoDot wrote:

> Program DXTest;
>
> #asm;
> includelib \masm32\directX\all-libs-except-d3dx8\d3d8.lib
> #endasm;
>
> Procedure D3DCreate;
> @external("__imp__Direct3DCreate8@4");
>
> Const
> IDirect3D_Release := 8;
>
> Begin DXTest;
> pushd(31);
> call(D3DCreate); // Create the Object
> push(eax);
> mov([eax], eax); // Load VTable
> call([eax+IDirect3D_Release]);
> add(8, esp); // Clean the Stack
> End DXTest;
> -------------------------------------------------------------------
>
> The program ends with a terminating message in the form, "This program
> has preformed an illeagal operation." blah. I'm using DirectX 8. Can
> you tell me what's going on?

You've performed an illegal operation. :)

Just as a wild-asmed guess - I'm not familiar with DirectX - is this
stuff stdcall like the usual API? If so, you don't want to clean the
stack. If it's C calling convention, you do. You know that, I'm sure...
best I can do...

Best,
Frank

NoDot

unread,
May 11, 2004, 12:05:35 AM5/11/04
to
Frank Kotler <fbko...@comcast.net> wrote in message news:<409FDE13...@comcast.net>...

> Just as a wild-asmed guess - I'm not familiar with DirectX - is this
> stuff stdcall like the usual API? If so, you don't want to clean the
> stack. If it's C calling convention, you do. You know that, I'm sure...
> best I can do...
>
> Best,
> Frank


Reduced the ADD to four... same problem.
Commented out the ADD... same problem.
:-(
HELP! PLEASE!

Betov

unread,
May 11, 2004, 2:54:49 PM5/11/04
to
no_...@msn.com (NoDot) icrivait
news:dfed44a6.0405...@posting.google.com:

> Reduced the ADD to four... same problem.
> Commented out the ADD... same problem.
> :-(
> HELP! PLEASE!


Well, OK, we are far too crual with you. Sorry. ;)
So, i am going to help you: Download any Assembler.
The ones of interrest are:

NASM: < http://sourceforge.net/projects/nasm >

RosAsm: < http://betov.free.fr/RosAsm.html >

FASM: < http://flatassembler.net/ >

GoAsm: < http://www.godevtool.com/index.html >

For most -if not all-, you will find out several good
examples about how to do DX. This is very simple, and,
with an Assembler, simple things are simple to do. ;)

For RosAsm (SpAsm, more exactely), for example, you will
find a pretty good Page (dedicated to SpAsm), with quite
impressive examples, at:

< http://www.chez.com/asmgges/index.htm >

... and/or several good demos at RosAsm Users Demos Page:

< http://betov.free.fr/UsersDemos.html >


This should help a lot. Courage, Betov.

< http://betov.free.fr/RosAsm.html >

Beth

unread,
May 13, 2004, 7:38:08 PM5/13/04
to
NoDot wrote:

> Beth wrote:
> > Randy wrote:
> > > Personally, I've never worked with Direct-X, so I can't offer
> > > any more insights into this issue. However, you might ask
> > > Beth Stone, who has played around with Direct-X in assembly
> > > a bit.
> >
> > Indeed; I've posted up my assistance now...sorry about the massive
> > delay...too many other threads in the newsgroup going on and kind
of
> > missed this one until now (just quickly looking over
things)...Hope
> > I'm not so exceedingly late in reply that I've missed the original
> > poster completely...oops! ;)...
>
> Beth, if your correct, then I've been right all along about the
VTable
> format.
>
> That being the case, I must have another bug in the system. This is
> what I've created for a micro-test:
>
> -------------------------------------------------------------------
> Program DXTest;
>
> #asm;
> includelib \masm32\directX\all-libs-except-d3dx8\d3d8.lib
> #endasm;
>
> Procedure D3DCreate;
> @external("__imp__Direct3DCreate8@4");
>
> Const
> IDirect3D_Release := 8;
>
> Begin DXTest;
> pushd(31);

Right, this number "D3D_SDK_VERSION" is used as a kind of "ID number"
for the version of the SDK header files you're compiling against
(yeah, Microsoft for you...no consideration that someone won't be
compiling against the C headers ;)...the number apparently has no
meaning other than that Microsoft _CHANGE_ it every time they make a
significant change to the header files...I suppose a kind of
"subversion" number, really...

Anyway, "D3D_SDK_VERSION" is "31" - like you've written here - in the
_DirectX 9_ header files (d3d9.h) but NOT in the DirectX 8 header
files (d3d8.h)...you're using the wrong number...

Yes, this number isn't a "constant" in the usual sense...it's a
"header file ID number", basically...so, grab the value out of the
_correct_ header file for the version of DirectX you're using...

Looking into my own DX8 header files (of which I actually have
two...an older one and what should be the latest one ;) then the older
one has "120" but the newer one has "220"...I'd go with the "220" but,
if that fails, try "120" (or update your DirectX versions ;)...

> call(D3DCreate); // Create the Object
> push(eax);

Seeing as you've been passing what looks like the _wrong_
"D3D_SDK_VERSION" then the "D3DCreate" call might have failed and
returned NULL to say "no Direct3D object created"...

Regardless of this, you're steaming on ahead because you've not
checked the error return...oops!! ;)...

> mov([eax], eax); // Load VTable
> call([eax+IDirect3D_Release]);

If the return was NULL because it couldn't create the Direct3D object
(because you've supplied the "D3D_SDK_VERSION" for DirectX9, not
DirectX8 ;) then you're now doing: "mov ([NULL], eax); call([ eax +
IDirect3D_Release]);"...goodness knows what kind of sheer madness
you've just instructed Windows to perform!!!

> add(8, esp); // Clean the Stack

Frank was right, by the way; DirectX calls are all STDCALL and, thus,
they clean the stack up themselves automatically...you should remove
this instruction...and you don't need to do this with any DirectX
calls, just as you don't for any Win32 API calls...

> End DXTest;
> -------------------------------------------------------------------
>
> The program ends with a terminating message in the form, "This
program
> has preformed an illeagal operation." blah. I'm using DirectX 8.
Can
> you tell me what's going on?

Actually, you just said it: "I'm using DirectX 8"...but you've gotten
that "31" value for "D3D_SDK_VERSION" from the "d3d9.h" header file,
haven't you? Look into the "d3d8.h" header file and you'll see it's
defined as a different number ("220")...

>From Microsoft's DirectX documentation (the "remarks" for
"Direct3DCreate8" ;)...

"The D3D_SDK_VERSION identifier is passed to Direct3DCreate8 in order
to ensure that an application was built against the correct header
files. This value is incremented whenever a header or other change
would require applications to be rebuilt. If the version does not
match, Direct3DCreate8 will fail."

As you're using the DirectX9 header file's version number rather than
the DirectX8 value, the function is _FAILING_ as the documentation
specifies(!!)...when this function fails, it returns a NULL
value...you're not looking for this failure and are happily carrying
on using the returned NULL in eax, as if it was a valid pointer...

Unsurprisingly, proceeding with "NULL" ends up causing a nasty GP
fault...and up pops the "This program has performed an illegal
operation" box...

Simply, check for a "NULL" return and if it is NULL, then the object
couldn't be created so don't proceed...that is, a "cmp (eax, NULL); je
TerminateProgram;" kind of thing...I mean, you should always be
checking those return values!!

But the real problem that's _causing_ the function to fail to give you
that NULL, which is blowing up your program, is you're just using the
wrong "D3D_SDK_VERSION" for DirectX 8...this number _CHANGES_ every
time the header files change, you see...it's kind of like a
"subversion number", so to speak...the Direct3D DLL file knows all the
valid values for all the applicable header files and only creates an
object when the value is valid...in this case, the value isn't
valid...the function fails....your program starts using NULL pointers
as if they were valid pointers...and BANG! "This program has performed
an illegal operation"...

By the way, on a different note, do Microsoft realise just how
_worrying_ that particular terminology is? Along comes a "Clueless
Newbie", clicks on a program and then - BANG! - "This program has
performed an illegal operation"...

"Illegal?!? It's broken the law!! What's it done that's illegal? Has
the program just electronically robbed a bank behind my back? Is it
running some big drug smuggling operation without telling me? No, it's
probably just tried to hack into the CIA's databases! Awww, crap...the
cyber-cops will be after me now!!"...

The "Clueless Newbie" runs to the bedroom and throws all their clothes
and stuff into a suitcase...they'll have to go "on the run" and "keep
a low profile" from any cops: "bloody computers! I knew I should never
have bought the thing...they're going to lock me up and throw away the
key...and I didn't even do anything but double-click on an icon!!"...

Might I suggest that though us geeks refer to it as an "illegal"
operation, the dialogue box chooses a more "diplomatic" piece of
language like: "This program has performed an invalid operation" or
"an erroneous operation" or something like that? Because, of course,
you're average Joe or Joanna is going to associate the law of the land
with the terms "legal / illegal" quite naturally...

Beth ;)

Beth

unread,
May 13, 2004, 7:38:42 PM5/13/04
to
Betov wrote:
> For most -if not all-, you will find out several good
> examples about how to do DX. This is very simple, and,
> with an Assembler, simple things are simple to do. ;)

Actually, the only real problem with his code example was that he
copied the wrong value - "31" rather than "220" - for the
"Direct3DCreate8" API...that's all...probably did something like GREP
for it and find the symbol in "d3d9.h", not realising that it's also
defined in "d3d8.h" to a completely different value (because the value
changes with each header file...it's actually a kind of "header file
ID number", so to speak ;)...

So, if simple things are simple to do with an assembler, Rene, then
his HLA code here was exactly right, in fact...what was actually wrong
was to do with DirectX's API parameters...nothing to do with HLA...

And, by the way, he's using your "offset constants" method so the code
is, basically, exactly the same as your RosAsm DirectX examples, other
than syntax...but, hey, if you want to call this code dumb and condemn
how you yourself use DirectX in RosAsm, then, please, feel free to do
so...

Beth :)

NoDot

unread,
May 13, 2004, 7:41:50 PM5/13/04
to
Betov <be...@free.fr> wrote in message news:<XnF94E67AD2AA...@212.27.42.65>...


I'm actually willing to take advice from you. I must be getting
desperate.

I already have FASM, NAMS, and GoAsm, but the problem lies in the fact
that I always find them using a ComCall macro, or similar. :( I have
yet to find an example that doesn't use it.

Thanks for the help. It proves you aren't always a complete jerk.

I'll see what I can do.

Betov

unread,
May 14, 2004, 5:04:24 AM5/14/04
to
"Beth" <BethS...@hotmail.NOSPICEDHAM.com> écrivait news:cpUoc.662
$KZ4...@newsfe2-gui.server.ntli.net:

> Actually, the only real problem with his code example was that he
> copied the wrong value - "31" rather than "220"

Then replace, recompile and... try again... :)) :)) :))

A much better way would be that you write a complete DX
Demo by yourself. This would enable master Self-Esteemed
Randall Hyde with a new stupidity to sell on young heads,
and this would save all of these young heads from having
to learn and to understand anything at DX calls. Or,
even better, write a Library, so that, like in any HLL,
they would not even to have to know of it, at all...

When will you LAND???!!!...


Betov.

< http://betov.free.fr/RosAsm.html >


Beth

unread,
May 14, 2004, 12:11:16 PM5/14/04
to
Betov wrote:

> Beth wrote:
> > Actually, the only real problem with his code example was that he
> > copied the wrong value - "31" rather than "220"
>
> Then replace, recompile and... try again... :)) :)) :))

As Ned Flanders might say, indeedee-doodoo...

> A much better way would be that you write a complete DX
> Demo by yourself. This would enable master Self-Esteemed
> Randall Hyde with a new stupidity to sell on young heads,
> and this would save all of these young heads from having
> to learn and to understand anything at DX calls.

Now, wait a minute...let's get this straight...it would be a
"stupidity" for someone other than the author of the tool to create a
DirectX demo to give to the author of that tool to "sell" the tool to
"young heads"? Isn't that _exactly_ what's happened with RosAsm, as
you didn't write those DX examples...

And, as for "save all of these young heads from having to learn and to
understand anything at DX calls", you've got to question why - if
you're so the expert on DX calls - _someone else_ wrote all your
DirectX examples...and you thought that there was actually something
wrong with NoDot's code when, in fact, there was nothing wrong with it
except that he'd supplied the wrong parameter to the API...the _very
first_ API you need to call to access DirectX Graphics in DirectX
8...the _very first_ thing that you should have seen and understood in
all these many DX examples you yourself have written (as opposed to
sitting around and letting others write those examples for you: Which
you've just claimed is a "stupidity")...how come you didn't see what
was a very simple little mistake of just supplying the wrong number as
a parameter? Either that "stupidity" of other's handing you DX
examples means you don't know it as well as you make out...or, despite
a display of concern about NoDot's problem, you didn't even really
look at his problem properly, did you?

> Or, even better, write a Library, so that, like in any HLL,
> they would not even to have to know of it, at all...

Write a library? Why would I need to write a library?

DIRECTX _IS_ A LIBRARY(!!) that means the user doesn't have to know
about how to send I/O bytes to an nVidia card or where the ATI Rage
maps its linear framebuffer...or hadn't you noticed that yet, oh great
assembly master?

_WINDOWS ITSELF IS A HLL_!!!

> When will you LAND???!!!...

"Land"?

Hmmm, now, there's a thought...

Beth :)

Betov

unread,
May 14, 2004, 2:18:57 PM5/14/04
to
no_...@msn.com (NoDot) icrivait
news:dfed44a6.04051...@posting.google.com:


You will probably never see "an example that doesn't use"
a Macro for DX calls, because there is no reason for not
using a so simple Macro, for doing this...


Betov.

< http://betov.free.fr

Betov

unread,
May 14, 2004, 7:29:09 PM5/14/04
to
"Beth" <BethS...@hotmail.NOSPICEDHAM.com> icrivait news:XP6pc.643
$Ce4...@newsfe2-gui.server.ntli.net:

> Betov wrote:
>> Beth wrote:
>> [...]


>
>> A much better way would be that you write a complete DX
>> Demo by yourself. This would enable master Self-Esteemed
>> Randall Hyde with a new stupidity to sell on young heads,
>> and this would save all of these young heads from having
>> to learn and to understand anything at DX calls.
>
> Now, wait a minute...let's get this straight...it would be a
> "stupidity" for someone other than the author of the tool to create a
> DirectX demo to give to the author of that tool to "sell" the tool to
> "young heads"? Isn't that _exactly_ what's happened with RosAsm, as
> you didn't write those DX examples...

Mind you long before any user had written a DX game with
RosAsm, i had written, with the help of Ron Thomas, a DX
Demo with all the Basic stuff, at the same time we both
wrote the very first full featured "Screen Saver" Demo
ever written in Win32 Assembly,... years ago... So said,
this remark is _completely_ out of thread: The stupidity
i am talking about is in no way about the fact that master
Pdf _nerver_ contributed to _anything_ in the Assembly
Rebirth. This was about enabling this swindler with one
more "component" for helping him damaging Assembly.

For your other bullshits, please do not simulate of never
having heard of any "Standard Library" and of all of the
stupidities coming with it.


Betov.

< http://betov.free.fr/RosAsm.html >

Bryan Parkoff

unread,
May 15, 2004, 1:19:10 PM5/15/04
to
It is interesting. It would be much easier to write simple DirectX3D in
assembler language like using MASM. Is it true that OOP is much easier than
non-OOP? After C/C++ source code is compiled, OOP is ALWAYS converted back
to non-OOP into assembler language.
Do you think that there is a possibility that DirectX3D is written in
C/C++ source code may only improve 70% performance while DirectX3D is
written in assembler source code may only improve 90% performance? Which is
faster? The answer would be DirectX3D that is written in assembler
language.
The fact is that C style rather than C++ style is identical to assembler
language however C++ must be converted back to C before it is compiled into
assembler language. Please correct me if I am wrong.
If there is no data struct, it must be done inside function to push and
pop data in order to balance the stack. How is it possible that stack can
handle more than two data structs. For example, first data struct has an
address 0x0012aa00 and second data struct has an address 0x0012bb00. Is it
the way that first data struct can be pushed into stack before it is used,
and then it is popped out of stack. Second data struct can be pushed into
stack to use.
Is it the way how DirectX3D work?

--
Bryan Parkoff


"Beth" <BethS...@hotmail.NOSPICEDHAM.com> wrote in message

news:agUoc.661$KZ4...@newsfe2-gui.server.ntli.net...

NoDot

unread,
May 15, 2004, 5:58:28 PM5/15/04
to
Betov <be...@free.fr> wrote in message news:<XnF94E96F7899...@212.27.42.69>...

> "Beth" <BethS...@hotmail.NOSPICEDHAM.com> écrivait news:cpUoc.662
> $KZ4...@newsfe2-gui.server.ntli.net:
>
> > Actually, the only real problem with his code example was that he
> > copied the wrong value - "31" rather than "220"
>
> Then replace, recompile and... try again... :)) :)) :))

Fixed the problem, thanks to Beth's post.

> A much better way would be that you write a complete DX
> Demo by yourself.

What do you think I was trying to do. I just got stumped and asked
for help.

> This would enable master Self-Esteemed
> Randall Hyde with a new stupidity to sell on young heads,
> and this would save all of these young heads from having
> to learn and to understand anything at DX calls.

If they were to understand the program, they would have to learn about
DirectX. I don't get it.

> Or,
> even better, write a Library, so that, like in any HLL,
> they would not even to have to know of it, at all...

If I were to make a library, I would document its internat operation
and write an article about how it came to be.

Where is there a library that uses DirectX? I don't know of one.
Neither assembly nor HLL.

Alex McDonald

unread,
May 15, 2004, 6:01:22 PM5/15/04
to
"Bryan Parkoff" <bryan.nosp...@nospam.com> wrote in message
news:Ldspc.113060$hR1....@fe2.texas.rr.com...

> It is interesting. It would be much easier to write simple DirectX3D
in
> assembler language like using MASM. Is it true that OOP is much easier
than
> non-OOP?

It depends on the problem you're trying to solve.

> After C/C++ source code is compiled, OOP is ALWAYS converted back
> to non-OOP into assembler language.

No; languages, OOP and non-OOP, are always translated into machine code,
eventually. Some compilers (like gcc) use an assembler as an intermediate
step; some (like vcc) don't. OOP is a high level construct for the
programmer's use.

> Do you think that there is a possibility that DirectX3D is written in
> C/C++ source code may only improve 70% performance while DirectX3D is
> written in assembler source code may only improve 90% performance? Which
is
> faster? The answer would be DirectX3D that is written in assembler
> language.

Not necessarily true. For large projects, all assembler is an overhead; it's
mainly loops that require high speed or unusual algorithms/processor
instructions that get written in assembler. The rest will perform pretty
much the same regardless of the source language.

> The fact is that C style rather than C++ style is identical to
assembler
> language however C++ must be converted back to C before it is compiled
into
> assembler language. Please correct me if I am wrong.

Nowadays, C++ is compiled, not converted to C first. Style? Not quite sure
what you mean by that. If you mean there's a closer one-to-one relationship
between C and the code executed by the processor, as opposed to C++, then it
depends on the processor. For instance, Intel/AMDs have a stack, but the C
language doesn't have such a concept; C has strings and string functions,
but Intel/AMD processors don't. And then there are processors (like the
Intel) with jump-type instructions that very efficently support vtables (a
common technique for C++ and OOP).

> If there is no data struct, it must be done inside function to push
and
> pop data in order to balance the stack. How is it possible that stack can
> handle more than two data structs. For example, first data struct has an
> address 0x0012aa00 and second data struct has an address 0x0012bb00. Is
it
> the way that first data struct can be pushed into stack before it is used,
> and then it is popped out of stack. Second data struct can be pushed into
> stack to use.
> Is it the way how DirectX3D work?

Sorry, don't understand this.

--
Regards
Alex McDonald


Beth

unread,
May 17, 2004, 11:06:26 AM5/17/04
to
Bryan Parkoff wrote:
> It is interesting. It would be much easier to write
simple DirectX3D in
> assembler language like using MASM.

Well, the COM calling mechanisms I believe are simplified for
understanding by looking at them in assembly language...

This doesn't automatically mean using MASM is necessarily
simpler because, of course, there's more to, say, a 3D space
shoot-'em-up game than only calling DirectX (e.g. the rest of
the code spinning matrices, calculating shadows, moving all the
sprites, synchronising the soundtrack with the action on screen,
etc., etc. ;)...and, with a C++ compiler, though _HOW_ it
interfaces is made much more complex to understand, you are
supplied a set of header files that already deal with the issues
and define the necessary constructs that you don't really need
to understand it but can just use the constructs in the header
file...

It's a HLL: _Understanding_ what's happening often isn't a
requirement (what code is inside "printf"? Yeah, exactly...they
don't care to tell you, you're just supposed to _use_ it and,
well, keep quiet about things after that ;)...the supplied
DirectX header files supply the "structures" and C++ actually
automatically knows how to make COM calls because it's the same
rough way C++ makes its own OOP calls (for C, Microsoft supply a
whole bunch of "convenience macros" that hide it away too :)...

Trying to _understand_ the specifics of the COM "binary
standard" calling mechanism is made more complicated because you
kind of have to not only understand what COM is doing but also
what your C++ compiler is doing too...for example, like the
"virtual methods" jargon had confused the poster but what it
actually represents, really, is a means to "undo" the OOP so
that the structure is an ordinary uninitialised structure...that
the compiler won't create a VMT with all the addresses filled
out because, well, it can't actually do that, as the object is
_external_ to the program in the DirectX DLLs...in fact, you
_don't_ use "new" and "delete" to create the objects either
because the C++ mechanisms are more or less designed for
_internal_ objects where it has access to all the code inside
the program and controls the entire process...DirectX isn't like
that because the "objects" are actually implemented inside
external DLL files and are "shared" between the program and
DirectX...this is, in fact, also why all the COM "objects" have
a "reference count" and a "Release" method because it's the
_object itself_ which has to become responsible for its own
deallocation...the ordinary C++ mechanisms of things like an
implied "delete" for objects created on the stack and so forth
would not work and would play havoc with these COM objects...

So, in fact, as I say, most of the COM stuff actually relates to
_switching off_ C++'s OOP, to an extent...you make them "virtual
methods" so that it's just an ordinary structure and C++ keeps
out of things with creating VMTs and so forth (one still employs
OOP, though, basically so that C++ automatically generates the
"indirection" needed...the C++ OOP mechanisms know to
automatically push "this" for any "virtual method" held inside a
structure...so it's used this way just to get that "convenience"
of having "this" pushed automatically without having to do it
manually :)...you don't use "new" and "delete" because their
semantics are designed for _internal_ objects and would likely
mess up how COM objects would work...blah-blah-blah...

Hence, as I was saying, the irony here is that the C++
descriptions are highly complicated _because_, in fact, you have
to play a lot of "tricks" to "undo" much of what C++ does
automatically because it's no longer useful or applicable to COM
objects...you put "virtual" in front and "= 0;" at the end of
every method in the structure to tell it to _butt out_, in fact,
and NOT create VMTs or anything like that (as they are "pure
virtual methods" = "pointer to a particular function
(prototyped) but no actual address yet given to where this
function is" :)...to treat it as an ordinary unintialised
structure that just happens to be full of OOP ("this" parameter
implied) methods...

> Is it true that OOP is much easier than non-OOP?

They are _different_...it's not a question of "easier / harder"
but a question of "applicable / non-applicable"...OOP _can_ be
easier in situations that fit with OOP well but it can also be
adding on a whole lot of complication to a program for no
particular benefit that complicates it unnecessarily...

Also, though it sounds cliched these days, OOP is a
_paradigm_...a way of looking at things...a way of doing
things...hence, for example, a lot of things which might not
seem "OOP" initially actually really are in terms of the
"attitude" and "philosophy"...such as the typical example of
file I/O in C with "FILE *" handles and passing the "file
handle" to "fread", "fwrite" and closing it with "fclose" and so
on...it's a simplistic kind of OOP but essentially it's fitting
into the "OOP" pattern and the way OOP looks at things and
implements things...

OOP, though, can often bring a lot of extra "fluff" (especially
when used without really knowing what your compiler is doing
"under the hood" :)...this is why lots who don't like OOP talk
about it being "inefficient"...this isn't strictly true as OOP
can, in the correct circumstances, be very efficient...but,
yeah, many people using OOP just use it for everything whether
usual or not and just throw things at the compiler without
thinking what they'll generate in the final output code...and,
though, in fact, it's NOT really _OOP_ that's at fault
here...it's actually the fault of the _misuse_ of OOP...same
arguments, really, as I make about "portability"...the thing is
not inherently "right" or "wrong" in itself...it's all to do
with _USING IT CORRECTLY_ in the right places...

Adding OOP for a program that doesn't really need it (that, in
fact, is only bloated by OOP and you gain _NO_ benefit for using
it at all)? Adding "portability" to a program that never uses
it? Well, when you _MISUSE_ things like this, then, yeah, all
they are good for is complicating things, slowing it all down
(both development and run-time performance), bloating,
mismanaging resources, etc., etc....

Another way to look at it is that OOP (and "portability" and
other similar devices :) are _TOOLS_...and it would be silly,
indeed, to say: "Right, I will _ALWAYS_ use a hammer for every
single job that I do regardless"...yup, a nail in the wall?
Hammer! (good)...need to strip paint? Hammer! (very bad)...need
to sand down some wood? Hammer! (terrible choice)...need to
demolish some big piece of wooden furniture? Hammer! (well, not
the best tool but it'll do the job...just smash it to pieces!
;)...

Kind of getting the basic point? A hammer is only appropriate
for certain jobs...when used for those jobs, a hammer is "good"
and "easy"...when used for jobs that it's no use for (like
sanding down or precisely cutting wood, for example), then the
hammer is "bad" (if not "absolutely terrible choice" ;) and
"hard" (if not "impossible" ;)...imagine trying to put up
wallpaper or paint a wall using just a hammer!! ;)...

OOP groups up related data and procedures into separate,
encapsulated "groups"...lots of programs are automatically
naturally formatted in that way and OOP is the right hammer for
this kind of job...when any kind of program gets "big and
complex" with lots of different parts to it in all directions,
then OOP is often a useful way to "order and organise"
things...put your program into "modules" and then divide things
up into "groups" and so forth...keep your program code all nice
and tidy, a bit like putting books on a bookshelf into
alphabetical order to also keep it all nice and tidy that when
you want to find a book later, it's very easy to find...you
know, the thing mothers always fail in teaching their sons:
"Keep your room tidy!"...when you just pile everything in a big
heap in the middle of the floor, finding things again is made
more complex than if you tidied up and put everything in its
place...see? It wasn't only about appearances, it serves a
_practical_ purpose to keep your room tidy too! ;)...

> After C/C++ source code is compiled, OOP is ALWAYS converted
back
> to non-OOP into assembler language.

Well, yes, all code from any language ultimately is compiled to
_machine code_ ("zeroes and ones", so to speak ;)...

But there seems a little confusion here...if I use structures,
pointers, tables of pointers to procedures, etc. under C which
is NOT an "OOPL" (object-orientated programming language), then
it still _IS_ OOP (object-orientated programming)...as I was
saying, the _C_ file I/O stuff with "FILE *" and "fwrite",
"fread", "fclose" really _IS_ OOP...but, yes, C _ISN'T_ an
"OOPL"...

What C++ does is basically add on some extra keywords here and
there which automate doing things in an "OOP" way...but, you'll
note that C++ is otherwise more or less exactly the same as C
but for these additional "keywords"...C++ is, therefore, an
"OOPL" (object-orientated programming language...although, to be
strict, C++ is "multi-paradigm" because it can be used in
_either_ way...many programmers - me included from time to
time - often simply use C++ as just "enhanced C" and don't
bother with the OOP stuff...which is totally okay by the guy who
invented C++ because he always says that C++ being
"multi-paradigm" - that you can do OOP _and_ non-OOP, as you
feel like - is actually its _strongest_ point, in his
opinion...but we'll call it an "OOPL" because it has OOP support
built-in and can be used to do OOP all the way, if the
programmer uses it that way...but we should make the distinction
as some languages really are _ONLY_ OOP and there's no choice at
all but to use it everywhere...C++ is more "OOP-enabled C", so
to speak...as the name makes as a pun: "C plus one"...no,
clearly Microsoft never understood the joke at all because what
the hell does "C#" mean? "C with an empty preprocessor
directive"?!?! Microsoft are so clueless sometimes ;)...

So, OOP code is not really compiled to non-OOP code...not in
that sense...it's still OOP code in the machine code because
"OOP" is defined as a _way of doing things_, not as some special
"OOP" instructions in the CPU's instruction set or whatever...

You have to make a distinction between "OOP" (object-orientated
progamming) and "OOPL" (object-orientated programming
language)...OOP just means, as the name actually states,
programming in a way "orientated" to using "objects"...you are
formatting out your code into "objects"...that's all "OOP" is
and you _CAN_ do OOP in _ANY_ language, whether it is an "OOPL"
or not...and what an "OOPL" - like C++ or SmallTalk or
whatever - are, are just programming languages where the
programming style of "orientating" things around creating
"objects" is _BUILT INTO_ how that programming language works...

Unfortunately, yes, there was an awful lot of "it's something
brand new!!!" hype going around to sell C++ compilers...and then
there's some programmers who delibrately or accidentally confuse
the two things up (delibrately when they are trying to insult
it: "OOP is crap and bloated and useless"...then, often, they,
of course, go and put all their variables in a structure and
then use procedures to manipulate it that takes a pointer to
that structure and so on and so forth...they are, in fact,
programming OOP...whether they realise it or not! ;)...

But OOP isn't some kind of "magic"...there aren't any "special
instructions" in the CPU to do OOP...it really is just an
"extension" of "programming practice" ideas like creating
procedures, systematic naming, grouping related things together
in a "module", etc....OOP is those ideas pushed a little further
again...despite what same people say about OOP being
"revolutionary", it really is NOT...it is clearly
_evolutionary_...an "object" is actually a "module",
really...being able to merge structures as well as simply
aggregate them together was a clear _evolutionary_ thing to add
support for (but call it "inheritance" and suddenly, thanks to
all the hype, people think it's "magic!" ;)...

It's not really "converted" from OOP to non-OOP...both OOP and
so-called "non-OOP" are both completely expressable in machine
code...the instructions aren't different...it's the way they are
_USED_ that makes it "OOP"...

Perhaps I was misleading earlier...when I said "non-OOP", I
simply meant "not using OOP jargon or OOP keywords" rather than
that uses structures and calling through pointers directly isn't
OOP...what I'm explaining _IS_ OOP...but what I meant with
"non-OOP" was "explaining it _WITHOUT_ using OOP jargon or
special OOP keywords"...the code itself _IS_ OOP because that is
defined _solely_ by _what it does_ (and, yes, the dividing line
_isn't_ always clear and can be "fuzzy", exactly because it's
about how a program works rather than what instructions or tools
a program uses to do it...but you can get an appreciation with
enough exposure to be able to look at something and say "yeah,
that's definitely OOP!" ;)...

> Do you think that there is a possibility that DirectX3D is
written in
> C/C++ source code may only improve 70% performance while
DirectX3D is
> written in assembler source code may only improve 90%
performance? Which is
> faster? The answer would be DirectX3D that is written in
assembler
> language.

Right, it's not totally clear what you mean here, sorry...

But if you mean using C/C++ or ASM source code to _access_
Direct3D from your program then, actually, there's likely to be
_NO DIFFERENCE WHATSOEVER_...what you'd be doing in the ASM is
only what the C++ automates for you (C is NOT an OOPL so, in
fact, would have to do things "manually", exactly like ASM does
and we shouldn't really say "C / C++" in this context anymore
because this is where C and C++ go their separate ways ;)...you
can't get it any smaller than pushing the parameters, pushing
"this" and then making an indirect "CALL" instruction via the
"table of pointers" (the "VMT" in the OOP JargonSpeak
;)...that's what you'd code in ASM and that's what a C++ would
almost certainly compile it down too...

There is, actually, _NO REAL ADVANTAGE_, generally, to using ASM
than C when it comes to _making calls to libraries_ (e.g. Win32
API, DirectX, etc. ;)...this isn't where you make any real gains
over HLLs...the reason basically being: Win32 and DirectX and
OpenGL and all these other libraries use _HLL conventions_...and
when you're using ASM to access them then you actually _must_
follow the "HLL conventions" for calling into the
libraries...and when you follow the "HLL conventions", you are,
of course, simply _copying_ what the HLL does exactly...because
of this, ASM has no great advantage over HLLs for calling into
libraries with "HLL conventions" on their procedures...these
libraries, really, are _HLL libraries_...it's just because ASM
is capable of interfacing to _anything_ that you can "fake up"
or "emulate" or "copy" the same calling sequence _manually_ that
the HLL compiler would do automatically so that the HLL library
is none the wiser that it's ASM code rather than HLL code
calling it...

ASM loses its advantage when calling into libraries with HLL
calling conventions because it has to temporarily "stop being
ASM", so to speak, and start acting like a HLL - "pretending" to
be HLL code by copying exactly what the HLL compiler would
produce - to work with the library, before it can return to
being ASM once more...well, in a manner of speaking, anyway...

There is one place where ASM can win over HLLs in calling
sequences but it's not all that common to be of great
advantage...for example (pay attention, also, those people who
use "invoke" all the time and think there's no difference or
advantage to not using "invoke" than to using it...you might be
"missing a trick" here ;)...

Rather than (as a HLL compiler or someone using "invoke" would
tend to produce)...

---------------------------------------

.code

invoke GetModuleHandleA, NULL
mov edx, eax

invoke GetCommandLineA

invoke WinMain, edx, NULL, eax, SW_SHOWDEFAULT

invoke ExitProcess, eax

end _start

---------------------------------------

(...which would expand into...)

---------------------------------------

.code

push NULL
call GetModuleHandleA
mov edx, eax

call GetCommandLineA

push SW_SHOWDEFAULT
push eax
push NULL
push edx
call WinMain

push eax
call ExitProcess

end _start

---------------------------------------

...ASM can do one thing that HLLs tend not to do (and that
"invoke" gets in the way of ;) of "interweaving" API calls where
the return of one API call feeds directly as a parameter in
another call...like the following little change:

---------------------------------------

.code

_start: push SW_SHOWDEFAULT

call GetCommandLineA
push eax

push NULL

push NULL
call GetModuleHandleA
push eax

call WinMain

push eax
call ExitProcess

end _start

---------------------------------------

Which is slightly - not a great deal - better...smaller, doesn't
use any registers (so those could be used to store things for
other purposes...registers are precious to look after ;) and
some slight improvements here and there...

Though, unlike the above, one has to be more careful to ensure
the stack is balanced, which is trickier when the stacks for the
parameters are all being "interweaved" like this...

BUT, generally speaking, when calling _HLL libraries_ (which
things like DirectX are because they use the HLL "STDCALL"
conventions and stuff :), ASM gains you little advantage over
HLLs like C / C++...ASM makes all its gains _elsewhere_ but,
unfortunately, can't do anything about Microsoft's crap HLL
designs, that insist you have to do things in a "HLL way",
whether using a HLL or not, whether you care about "portability"
or not...indeed, this is why I moan elsewhere that an OS
shouldn't really do that...it should present an _ASM_ interface
to things and then C++ compilers can have "wrappers" to make
things "HLL friendly" (this would, in fact, be a _good_ solution
for HLLs too because rather than saying "STDCALL" for all HLLs,
be they C or Pascal or whatever, then the "wrappers" can be
custom-built and tailored to the language being used...C
"wrappers" using C conventions, Pascal "wrappers" using Pascal
wrappers...it wouldn't just be good for the ASM people but
better for the HLL people too...this is why I say this method
makes the most sense for an OS _whatever language you're
using_...an OS should always be designed in that way, in my
opinion ;)...and, thus, coding ASM? Don't need to put up with
"portability" nonsense _that you don't use_...note, even many C
or Pascal coders or something could do the same too - to improve
their performance too - by creating some "inline ASM macros"
that by-pass the need for "wrappers" ("inline ASM" is, indeed,
"compiler specific" but most C / Pascal compilers and stuff can
actually do it...losing "portability" is okay because if you're
by-passing the "wrappers" to go straight to the registers then
that's "non-portable", anyway...every CPU has different
registers, after all...that's the point here, you see: "those
who want portability can get it, no problem - use the wrappers -
but those who would benefit from dispensing with 'portability'
to get better performance - games, multimedia, etc. - can
'by-pass' it at their discretion" ;)...and if a HLL uses one of
these "wrappers" then its performance only really drops to _what
it is already now_...in a sense, _everyone_ is forced, under
Windows, to use some "generic wrappers"...well, I would say that
they should be separated out so that the programmer _CHOOSES_
whether they want the "wrapper" or not...but, anyway, all
pointless talk because Microsoft do it the wrong way and will
almost certainly never change from that now they've made their
choice to be "HLL" all the way about everything...

And if you meant that DirectX _itself_ would be improved by
writing it in ASM rather than C / C++ then, yeah, probably it
could be speeded up...but I'd wager, in fact, _NOT BY THAT
MUCH_...because DirectX actually just sits on the device drivers
as a kind of "filter" for the device drivers..._ALL THE HARD
WORK_ of DirectX happens inside the video display driver, inside
the soundcard device driver, inside the mouse and keyboard
device drivers, etc....

In truth, "DirectX" is a "correction" of a basic design flaw in
the original Windows...of course, this doesn't very clever or
good that you'll never hear Microsoft phrase it that
way...basically, the original Windows (not actually too
dissimilar to other GUIs...most GUIs, in my opinion, are
_wrongly structured_ because they copied Xerox's original
design...and what's Xerox's strong point? _Specific embedded
designs_ tend to be what they mostly do inside their
photocopiers and stuff...specific purposes devices their
speciality...and I would say that those writing _general
purpose_ GUIs for _general purpose_ PCs perhaps should NOT have
taken Xerox's designs so _literally_...but rather as a
"guide"...but what is done is done, eh? ;)...the original
Windows could only access the display through the built-in
GDI...and GDI was NOT designed to be "real-time" drawing tons of
textured polygons...in fact, GDI is NOT even really
well-designed for simple "pixel plotting"...GDI was designed as
a "friendly library" for, well, programmers who "aren't very
good with graphics" to write spreadsheet programs...GDI, for
example, works just as well with printers as it does with video
screens and in being "generic" for both types of quite different
design, it had to _compromise_ certain useful video
functionality...yup, GDI makes "WYSIWYG" ("what you see is what
you get" ;) functionality that what is on the screen prints out
to the printer exactly the same, totally easy and
"built-in"...so, great, makes spreadsheets and wordprocessors
easier to write, then...but this design _compromises_ out the
possibility of flicker-free 60fps textured polygon computer
games...they just didn't think of it and didn't work it into the
design...

In fact, what games programmers (and demo programmers and those
with need for high-performance multi-media of any kind ;)
actually wanted, really, was to just be able to load up the
device drivers and talk to them directly...some kind of, for
example, "GetVideoDriver" API which provides a "handle" to the
driver handling the video display and then you could use some
"SendMessage" API to send commands directly to the driver to do
things like change video modes or load a texture into video
memory or draw a polygon or whatever...of course, same idea with
the soundcard...a "GetAudioDriver" API and then you communicate
with the driver directly...

Note that this is a perfectly valid possibility because device
drivers are already "portable" in the interface that they show
to the OS (that's how the OS themselves can use the hardware in
a "portable" way ;)...and, under this design, GDI would,
instead, simply be a "user code library" that provides a
"high-level" API like it does now and inside the library, all it
would be doing is handling all the device driver communication
on your behalf...to be a "wrapper" for talking to the device
drivers directly with a "friendly" interface of "DrawBox",
"DrawLine", "ChangePen" and that kind of GDI vector graphics
stuff...indeed, easy enough too, that this "wrapper" could be
clever enough that it could provide the same "API" to both a
video display and a printer...so, indeed, I'm NOT talking about
getting rid of GDI at all...but it should have been strictly a
_library_ on top of the _device drivers_...

Unfortunately - and Windows is far from the only GUI OS to, in
my opinion, make this "mistake" - Windows was designed with GDI
at the front...the device driver interface was designed without
any idea of making it "friendly" for application programs to
use...no, instead, device drivers were only for the OS to deal
with...applications must talk to the OS who passes it onto the
device drivers...

BUT, of course, game designers didn't like this at all...and, in
fact, games _STILL_ kept being made for DOS, well after Windows
had become the main OS on PCs for people to do word-processing,
spreadsheets, play Solitare (the only undemanding game that
could happily live with using GDI only ;) and that kind of
thing...Microsoft realised that they had to do _something_ to
fix this problem...

Hence, "DirectX" was stuck onto Windows as an "extension" where
you pass it more "direct" and "specific" commands that it will
"by-pass" the usual API nonsense and take more directly to the
device drivers...it's just a "filter" to get around a bad design
in the first place...

And anyone who disputes that the original design was not a bad
design (_IF_ there is anyone)? Proof of the pudding is in the
eating...they _HAD TO_ create DirectX to cater for this or
Windows would have remained "shunned" as a gaming and
multi-media platform...

And, now, in hindsight, anyone creating their own OS from
scratch should consider learning from MS's mistakes rather than
repeat them themselves...put your "DirectX" equivalent at the
_core_ of the OS...in fact, design it so that it's a reasonable
thing for an application to get a "handle" to a device driver
and talk to the device driver directly (still need device
drivers more generally because of the need to _regulate_ in a
multi-tasking environment - can't have everyone attack the
screen at the same time! - and to also provide "portability", as
PC video and sound cards and stuff are all completely different
that it's a _practical_ problem that you need something like
this...unless you use VGA mode 13h - not good enough a standard
for today, unfortunately - for everything, anyway ;)...you can
provide "GDI" and "OpenGL" and all that kind of thing as "user
code wrapper libraries"...they don't have to be lost, you see,
just that they should be the "extensions" rather than the core
of the OS with using the device drivers more directly as the
"extension"...it's simple logic: build it up bit by bit, one
component using the lower-level component...don't just jump from
"sending command on I/O ports" to GDI in one big leap...it's NOT
as clever an idea as it might first appear to do that...the
other OS have learnt this big-time having to "replace" their
main, crappy graphical interface with better "extensions" bolted
onto the side...

> The fact is that C style rather than C++ style is
identical to assembler
> language however C++ must be converted back to C before it is
compiled into
> assembler language. Please correct me if I am wrong.

Ummm, not completely sure what you're saying that I can't
correct you or otherwise, until I'm sure I know exactly what
you're trying to say...

Right, "C style [...] is identical to assembler language"...yes,
C has no "OOP" constructs built into, so the approach with C
(not C++) is actually very, very much like ASM...that is, you
just create a "structure" and then _manually_ pass along the
"this" as the first parameter and all the same things as in
ASM...

C++ is just different because it recognises and understands what
"methods" are and, thus, knows to automatically push "this" as
the first parameter (it does this "behind the scenes" :)...so
you don't need to put "this" into the parameter list and when
you use something like "pDirect3D -> CreateDevice()", then C++
automatically knows that "this" (pDirect3D itself, in fact ;)
should be automatically pushed as the "hidden" first
parameter...if you like, the C++ is "OOP-aware C"...it realises
that this is an "OOP thing" and knows that OOP needs the "this"
pointer as one of the parameters...so it does this all
automatically so that it's "hidden" and you don't need to know
about it...

Although, in this case, that's _all_ C++ does that's
advantageous for the programmer...and, to get it to work right
with _external_ COM objects, you wonder if this is worth the
price when you have to put "virtual" in front of everything and
"= 0;" after it and then list the "inheritance" at the top and
so on and so forth...in this case - for COM objects - C++
probably requires more "tweaking" to work properly with COM than
you actually gain from having "this" hidden from you (that's all
you're doing all that stuff for...to have C++ do the "this"
stuff automatically...and, I'd say - but then I'm an ASM
programmer and "biased" so I probably would say this - that
there's no great point in "hiding this", anyway...what's so hard
about having a pointer as the first parameter of a procedure and
remembering to push it? It's not like it's a difficult value to
obtain...you're already using it to find the "method table" to
make the OOP call, anyway...that is, in "pDirect3D ->
CreateDevice()", you've already got your "this"...it's the
"pDirect3D" value itself! You go through all this effort,
really, to stop yourself having to type out "pDirect3D"
twice...and that's about it in reality...so, as I say, it might
actually be _easier_ and _better_ not to use an OOPL for this
kind of thing because it demands lots of "tweaking" to do
something with "hiding this" that's hardly worth all the
effort...certainly true for low-level programmers - the _MOST
LIKELY_ people use DirectX, if you stop and think about t for a
second because it's used for _high performance_ games and
multimedia applications (so, if you're not particularly good
with "low-level" things and don't really understand it too well
then, ummm, I wouldn't totally say "what are you doing
programming DirectX?" as it can benefit even VisualBASIC
programmers - after all, their HLL code ain't the best so they
need every bit of help on the "speed" front they can get - but
it called into question what the designers of these things are
often thinking...you know, "yes, we expect them to understand
matrix mathematics completely...but, no, they do need 'help' in
learning how to use their mouse and which button on their PC is
the 'power button'"...I mean, either these people know what they
are doing and are able to learn to know what they are doing...or
you treat them like complete morons...what we actually get,
though, is some really bizarre "in-between" where you're
expected to be an expert in highly complex game algorithms but,
at the same time, you're also considered a "blithering idiot"
that, ooh, pushing "this" makes your brain explode with
"Overload! Overload! Pushing a pointer too complicated! Pushing
a pointer too complicated!"...yet, by the way, you're fully
expected to understand how to use and manipulate pointers in
other places without any problems...it's a confused design from
very confused people at Microsoft, who aren't sure if this is
for "Clueless Newbies" or "Advanced Coders" or whatever, so
weirdly try to make it all those things at the same time in
different places with no consistency at all! Indeed, it's almost
a catchphrase now but: "Bloody Microsoft!" ;)...

"however C++ must be converted back to C before it is compiled

into assembler language"?

Ummm, no...as mentioned by Alex, modern C++ compilers compile to
object code directly...no in-between "C" phase...the very first
C++ compilers did do it "via C" but that was more just a way to
get the language working at first until a full C++ compiler was
written (HLA is really doing the same thing in converting HLA to
MASM or FASM and then using them to assemble the code...it's
just a "quick and nasty" way to get a new language up and
running without writing the full compiler...Randy did it this
way so that he could spend most of his time on the _design_ of
the HLA language to get it right - to "prototype" it - before
actually diving in to code it up properly...but HLA v2.0 will no
longer need an "intermediate" assembler to help out...it's just
a way to test out designs with a simple "prototype" until you're
sure you've got the language properly sorted..._then_ you can
write it up properly as it's own compiler, safe in the knowledge
that you've got the language designed exactly the way you wanted
it to be :)...

And assemblers and compilers compile to _machine
code_...assembly language is the "human-readable" form of
machine code and, in many contexts, it doesn't which word you
use...but, strictly, in this context, we're compiling to
_machine code_ (inside "object code" files most usually
;)...and, no, most C++ compilers go straight to that machine
code without converting to C or anything...

Now, if you mean "C _style_" rather than literally C...that is,
"converting" C++ OOP into C non-OOP before outputting the
machine code...that's not true either..."OOP" is perfectly
expressible directly in machine code...it just goes straight
from OOP to machine code...again, "OOP" is the _STYLE_ that the
code follows...you can do "OOP" in C just as well as C++...the
difference with C++ is that it _understands_ OOP automatically
and has special "OOP keywords" to make OOP programming
easier...it's an "OOPL"...

> If there is no data struct, it must be done inside
function to push and
> pop data in order to balance the stack.

Again, not totally sure what exactly you mean here...what does
"no data struct" refer to here? Sorry...I think you're getting
the ideas about the programming stuff right here but your
English is a little hard to read in places...be patient and
tolerant with me in trying to understand: I'm too stupid and
stuck with native English thinking that I'll need some more of
your help to understand completely...

But, anyway, the "balance the stack" stuff is, of course,
correct in that pushes and pops must be "balanced" by a
procedure...

Let me think...do you mean - as C++ allows - for an "object" to
be put onto the stack rather than in the "heap" memory or data
section? Is that what you mean by "no data struct"?

If so, then I see what you mean...and what happens is that the
function doesn't really "push" and "pop" the parameters on the
other end...instead, it uses the "this" pointer - which will
have the address of the "struct", whether that is on the stack
or in the data section or whatever - to access the data...this
is actually part of the reason _why_ you must the "this" pointer
as the first parameter to allow the function to be able to
access the "struct" _wherever_ in memory it is...because by
passing the pointer to the struct - the "this" pointer - then
you pass it the _address_ of the struct, whether it's on the
stack or in a data section or dynamically allocated "heap"
memory or wherever it is...and it doesn't actually touch the
stack with "pop" inside the function to allow this to
happen...what it does is use "esp" - the stack pointer - to
access the parameters and the "this" pointer - the first
"pointer to struct" pointer - to access the struct...because
these are just "addresses" then they could be anywhere in
memory...

> How is it possible that stack can handle more than two data
structs.
> For example, first data struct has an address 0x0012aa00 and
second
> data struct has an address 0x0012bb00. Is it the way that
first data
> struct can be pushed into stack before it is used, and then it
is
> popped out of stack. Second data struct can be pushed into
stack to use.

Well, it's able to handle having the "structs" anywhere in
memory because, of course, we're _passing the address_ of the
"struct" as the first parameter ("this")...so, wherever the
"struct" is in memory, the "this" pointer is what the function
uses to find it...in other words, the function itself doesn't
"work out" where the structs are...we _TELL IT_ where they are
with "this"...that is basically _WHY_ we pass "this" as the
first parameter and why "this" is simply the _address_ of the
start of the struct...because, yeah, how could the function work
this kind of thing out? It couldn't really...so, instead, as a
programmer, we _TELL_ it where the "structs" are by passing the
address of the structs as part of the function call
itself...and, yes, if you were to pass the wrong address then
this scheme wouldn't work and you might blow up the program (in
truth, _that_ is the reason _why_ C++ tries to "hide" the first
"this" parameter from the programmer...so that it deals with it
and makes sure the addresses are always right...to eliminate the
possibility of the programmer making a terrible "bug" of passing
the wrong pointer to the function - which actually doesn't know
where the "structs" are at all and totally _trusts_ the pointer
you provide as being always correct - and crashing the program
;)...

When there are two structs on the stack then, by definition, the
struct pushed first will be "alive" while the second struct is
on the stack...because to get back "down" the stack to the
struct pushed first means popping off all the stuff above it on
the stack and, hence, the second struct has to be popped off
first from the stack to get to the first struct (in that
description, I've said "up" and "above" in the contexts of
real-world stacks - like stacks of plates - inside the computer,
though, stacks are actually upside-down...yeah, as if it wasn't
complicated enough, they go and put our stacks upside-down to
confuse us! No, there is a good reason for that, actually, but
it's another post in itself to start to explain how weird stacks
are ;)...

In practice, though, a program would not normally be putting its
COM "structs" onto the stack...you _CAN_ do that, of
course...just make enough room on the stack for the "table of
pointers" and then pass the stack pointer as the address...and
then the addresses would be filled into the stack
space...indeed, C++ completely supports objects on the stack and
whenever you declare an object as a local variable, then this is
actually what it does...

But, generally, in OOP, the memory for the "structs" is usually
dynamically allocated "heap" memory (allocated with
"VirtualAlloc" or "malloc" :) because part of OOP is to allow a
programmer to make lots and lots of the same "object" (like,
say, loads of "texture" objects in Direct3D for drawing textures
on all of your polygons...one "texture object" for every texture
you want to draw in the "scene" on the screen :)...and you often
have _no idea_ in advance how many objects you want to allocate
while running the program...it's a "variable-length" thing
usually...and, thus, allocating "heap" memory tends to be the
usual way to store the "struct" memory because you can allocate
as many structs from this memory as you have spare available
RAM...must remember to deallocate that memory when you're
finished, though...

The stack - as "local variables" - would be more common but, as
you seem to be talking about - you have to make sure that your
"object" doesn't just "vanish" because, oops, it gets popped off
the stack before you've finished using it (a nasty bug because
you've probably NOT called "Release" on the object as you're
supposed to do when you finish and objects are responsible for
deallocating themselves in COM...in other words, you would need
to be a little careful not to make a bug here and cause a
"memory leak" that you have an "object" sitting around in memory
that you've lost the pointer to - so you can't deallocate it
anymore when you've lost its address (oops! ;) - and that won't
disappear until it is told to do so with a "Release" call...it's
not so bad in that Windows should really clean this stuff up
when the process ends...but, while your program is running, then
it could have a nasty "memory leak" in it...yes, when using
"pointers" and "dynamically allocated memory" then you always
need to be wary and keep an eye for any "memory leaks" and be
careful about that stuff :)...

Static memory - memory in your data section - is usually used
for some objects...for example, you only need to have _one_
"IDirect3D" object - this is the "object" that just represents
"Direct3D" itself (hmmm, Microsoft haven't read the OOP
textbooks about not creating "super objects", have they? Why am
I not surprised at anything Microsoft do? Sorry, ignore this
comment, it isn't relevent...I just spotted yet another stupid
thing Microsoft have done...again! ;) - and, therefore, you'll
only ever need one "struct" for this "IDirect3D" object...so,
might as well just create a static struct in your data section
for that (well, unless you're _really fussy_ about "file size"
;)...in fact, if your program always uses a fixed number of
"objects" then you can, indeed, do it all with static memory -
the ASM DirectX demos I've seen only usually consider doing this
way and don't use the stack or dynamic "heap" memory or
anything - from start to finish...but a big, complex DirectX
program would likely need to do things in a "flexible" way and
use dynamic memory (or, indeed, the stack...which is actually
also "dynamic memory" but a "special" kind that works in a
certain way...and also keeps track of "return addresses" from
procedures that you've, indeed, always got to be careful to
"balance" the stack or it'll pop off the wrong address and then
jump into the middle of nowhere in memory and, almost
certainly - bang! - crash badly :)...

But, in practice, this usually isn't a problem because the
program logic means that you normally wouldn't run into problems
unless you were doing it in a really weird way...you know, a bit
like how you never have to worry about the stack popping off
procedure "return addresses" in the right order normally because
of the way most programs "CALL and RET" in a strict sequence
that the stack is quite naturally always "balanced"...

And, seeing as we're talking about "DirectX in HLA" (well,
according to the subject line we are ;)...then it's worth
looking over the chapter about the stacks...but also the stuff
about "displays"...this is a stack mechanism that's not used in
C / C++ at all, so it might be new to many coders who've only
done C / C++...HLA (as well as Intel's "ENTER" and "LEAVE"
instructions before Rene launches into an "anti-assembly"
rant...sorry, supported in the CPU directly with its own
instructions so quite "assembly", in fact...just because C / C++
doesn't do something is automatic that it's not possible or
useful or "anti-assembly" or whatever ;) can create "displays"
for procedures so that procedures can actually access the "local
variables" of other procedures (access the other procedure's
"stack frame" without pushing or popping or anything :)...those
chapters contain a lot about "stacks" that's useful to read up
about...in fact, as noted, C / C++ doesn't support "displays"
that, actually, HLA and the AoA chapters about this stuff is
something that many other textbooks don't talk about at all
because their authors only really know C / C++ and haven't heard
of "displays" to write about them...

> Is it the way how DirectX3D work?

Well, I'm not 100% sure that I completely understand your
question, so maybe I've given you the wrong answers here
(indeed, as you said to me: "correct me if I'm wrong" ;)...but
it's more the way C++ works _when using Direct3D_ than the way
Direct3D itself works...Direct3D doesn't really care _where_ you
have your "structs" because you have to provide a _pointer_ - a
memory address - to it and Direct3D just uses the memory pointed
to by that address...it doesn't care nor does it even know
whether that memory is on the stack, in the data section or
"heap" memory or whatever...it's one of the reasons _why_ OOP
works the way it does with "this" pointers being passed as a
parameter all the time to make sure that it can work with _any_
kind of memory...

Beth :)

Bryan Parkoff

unread,
May 17, 2004, 5:23:40 PM5/17/04
to
Beth,

Wow!! You provided a TON of information in this newsgroups. It helps
me to understand. I guess that you have a great knowledge of DirectX
writer. I suspect that you sound like Microsoft programmer to write and
develop DirectX library with DirectX programmers in this team. Didn't you?

--
Bryan Parkoff
"Beth" <BethS...@hotmail.NOSPICEDHAM.com> wrote in message

news:vD4qc.120$uu2...@newsfe2-gui.server.ntli.net...

Woody

unread,
May 18, 2004, 2:27:03 PM5/18/04
to
On Mon, 17 May 2004 21:23:40 +0000 (UTC), "Bryan Parkoff"
<bryan.nosp...@nospam.com> wrote:

> Wow!! You provided a TON of information in this newsgroups. It helps
>me to understand. I guess that you have a great knowledge of DirectX
>writer. I suspect that you sound like Microsoft programmer to write and
>develop DirectX library with DirectX programmers in this team. Didn't you?

[snip over 800 lines of quoted text!]

http://www.netmeister.org/news/learn2quote2.html :-)

0 new messages