At one point it was thought that  DirectX under RapidQ might be improved by custom programming. However, because of the inability to RapidQ to properly handle function pointers, this is not recommended. The easier way to do write DirectX code in FreeBasic and make it into a DLL. With that said, here is the Quick but Lame Tutorial on COM interface and RapidQ

 

First make sure you know the abbreviations:

API – application programming interface. How you talk with the operating system to get it to do what you program asks.

 

DLL - Dynamic Link Library an EXTERNAL file that contains machine code. Your program can use DLL to run Windows API. DLLs load in the same process space (memory area) as your program. You cannot compile a DLL into your program.

 

 

GUID - Globally Unique identifier. A 16-bye code that identifies a specific COM object. That is DirectDraw (one little piece of DirectX) has a GUID that is for a DirectDraw version. That way all new versions are known from old ones and other pieces of DirectX. You might remember the QOLEOBJECT example in which

Microsoft Word has a GUID "{000209FE-0000-0000-C000-000000000046}" that thing has 16 bytes of hexadecimal codes.

 

POINTER – a variable that holds the memory address (location in computer memory) of a variable, User defined TYPE, a SUB, Func, etc. etc. RapidQ does not give you all pointers (see below)

DIM a AS INTEGER
DIM lp AS LONG
A = 5
Lp = VARPTR(a)        lp is now the pointer, it does not = 5!!! But a memory address.
lp =@a                      'the @ symbol also says get the address of the variable

COM - Component Object Model. You never get a straight answer from M$. Basically, this is an advanced way to improve a DLL. Once a COM is made it is standard and new versions will work with older programs. They are suited for C++ coding. It kind of turns DLLs into object oriented programming.

Instead of using API functions like this:

A = GetWidth (myObject)

B = GetHeight (myObject)

You would have a DLL with an object oriented programming interface:

A = NewObject.Width (myObject)

A = NewObject.Height (myObject)

It’s just cleaner coding but it is a hassle to get it working in RapidQ.

 

 

The BASICs of DirectX

___________________

DirectX uses the COM interface. It is not the same as “OLE automation”, which also uses a COM interface but with a different format.

 

Instead of calling one or many individual SUB/Func like this:

Declare Function GetForegroundWindow Lib "user32" Alias "GetForegroundWindow" () As Long

Declare Function GetDC Lib "user32" Alias "GetDC" (hwnd As Long) As Long

….. on and on

 You are going to have one a (or few) simple calls Here is the only call you need to start DirectDraw:

 

Declare Function DirectDrawCreate Lib "ddraw.dll" ALIAS "DirectDrawCreate" (ByVal lpGUID As Long, ByVal lplpDD As Long, ByVal pUnkOuter As Long) As Long

 

Wow, that was easy! Wrong….

What happens is this Function returns a POINTER TO A STRUCTURE, that can be used to IMPLEMENT the INTERFACE. This is explained later. Here is how you run it:

 

$DEFINE LPDIRECTDRAW                         LONG              variables of “LPxxxx” are pointers

$DEFINE LPDIRECTDRAWSURFACE        LONG             ‘use LONG for 32-bit windows

$DEFINE IDirectDraw                                    LPDIRECTDRAW

$DEFINE HRESULT                                      LONG             ‘handle for a return value

$DEFINE DD_OK                                          0                      ‘this checks if it ran OK

 

‘The API to create our DirectDraw “OBJECT”

Declare Function DirectDrawCreate Lib "ddraw.dll" ALIAS "DirectDrawCreate"_

(ByVal lpGUID As Long, ByVal lplpDD As Long, ByVal pUnkOuter As Long) As Long

 

DIM result        AS HRESULT

DIM lpDD       AS LPDIRECTDRAW            ‘our pointer

lpDD = 0          ‘null it out

result = DirectDrawCreate(0, @lpDD,0)  ‘get the pointer to the interface

 

first parameter is 0, which is the default active display, second parm passes the Pointer of lpDD using the ‘@’ symbol to the FUNCTION

last parameter must be 0 for ‘future expansion’ by windows

 

IF result <> DD_OK THEN

 ShowMessage "Create direct draw Failed"

ELSE

  ShowMessage STR$(lpDD)

END IF

end of program…………………………

 

This program actually runs and returns a large number in lpDD. This is the starting address of the INTERFACE. IF you run it, you cannot close down the directDraw interface because you are supposed to RELEASE it, so windows can use the memory

Here is the c code:

lpDD ->Release();

You can’t do it in RapidQ, yet. So if you run the program you just used up some memory…

 

 

With the line

result = DirectDrawCreate(0, @lpDD,0)

We now have a pointer to a pointer that points to a structure, the pointer is lpDD !! But how do we start calling the DirectDraw functions? You need to declare the structure and then use that pointer to the stucture. You know what a structure is (use TYPE or STRUCT)

   TYPE MyType

        A AS LONG

        B AS INTEGER

    END TYPE

 

Then what does the DirectDraw structure look like?

The code for a SUB or FUNCTION sits in some memory address space in the computer. The program knows where that code is by a pointer. Pointers are only numbers, and for Windows 32-bit, the pointer is of a LONG type. The pointer holds the memory address of the starting location of the code. So if you know the value of the pointer, you can "jump" that memory location and run the code in that "process space." Before you can run that code, the program must know how  many, and what type of parameters there are to run the code

 

SUB Add(a as integer, b as integer)

CODEPTR(Add)-- will be the memory where start code of Add SUBroutine. Now you need to call the sub so the computer knows there are two parameters (a and b), which are both integers

 

In RapidQ, you must first BIND the SUB/Func to a LONG

DIM fptr AS LONG

BIND fptr TO Add

*** in C you don't do this

 

now you can run the code so the computer knows the right number and type of parameters

 

CALLFUNC(fptr(a,b))

 

NOW FOR DIRECTX, DIRECT3D, DIRECT Play, etc--

 

When you start DirectX, it GIVES YOU the memory address of its code in a pointer!! That is you have no idea where the CODEPTR is!! So if

CALLFUNC(CreateDirect3D, my3Ddisplay, etc., etc) you know that "CreateDirect3D" is the starting memory address and "my3Ddisplay, etc., etc..." are the parameters to pass to that SUB/FUNC. How does the program know the correct number and type of parameters for DirectX? From those HUGE, HUGE, C header files!

 

Since CALLFUNC uses some internal table for memory addresses (in the sample program it returns "1", NOT a real memory address) then I can't see how to develop DirectX, DirectPlay, DirectMusic in RapidQ .
The bottom line, you will need a C-like programming language such as BCX or FreeBasic to program in DirectX