Delphi Graphics and Game Programming Exposed! with DirectX For versions 5.0-7.0:Input Techniques
Search Tips
Advanced Search
Title
Author
Publisher
ISBN
Please Select
-----------
Artificial Intel
Business & Mgmt
Components
Content Mgmt
Certification
Databases
Enterprise Mgmt
Fun/Games
Groupware
Hardware
IBM Redbooks
Intranet Dev
Middleware
Multimedia
Networks
OS
Productivity Apps
Programming Langs
Security
Soft Engineering
UI
Web Services
Webmaster
Y2K
-----------
New Arrivals
Delphi Graphics and Game Programming Exposed with DirectX 7.0
by John Ayres
Wordware Publishing, Inc.
ISBN: 1556226373 Pub Date: 12/01/99
Search this book:
Previous
Table of Contents
Next
This structure carries information that describes a devices data format. The first member should be set to the size of the TDIDataFormat structure. The second member is set to the size of a TDIObjectDataFormat structure. The third member is a series of flags that describe certain attributes of the data format. For our purposes, we can set this member to DIDF_ABSAXIS to indicate that axes measurements are absolute. The fourth member indicates the size of the data packet returned from the driver. This value must be a multiple of 4, and must exceed the largest offset value for an objects data in the packet. For our purposes, well set this to the size of the TDIJoyState2 structure. The fifth member indicates the number of objects that are in the sixth member, which is a pointer to an array of TDIObjectDataFormat structures. The TDIObjectDataFormat structure is defined as:
TDIObjectDataFormat = packed record
pguid: ^TGUID; // object GUID
dwOfs: DWORD; // object offset
dwType: DWORD; // object type
dwFlags: DWORD; // attribute flags
end;
The TDIObjectDataFormat structure contains information about a specific object on the input device, such as an individual axis or button. The first member is the objects unique identifying GUID. The second member is the objects offset within the data packet. This is also the object identifier that we have used in other methods. The third member indicates the object type (such as a button or axis), and the final member contains attribute flags for the object.
After we initialize the first four members of the TDIDataFormat structure, we must begin building the array of TDIObjectDataFormat structures for each object on the device. To do this, we must employ the EnumObjects method. EnumObjects works the same as all other enumeration functions in that it calls a callback function once for each object on the input device. The EnumObjects method is defined as:
function EnumObjects(
lpCallback: TDIEnumDeviceObjectsCallbackA; // the callback function
pvRef: Pointer; // application-defined value
dwFlags: DWORD // enumeration flags
): HResult; // returns a DirectX error code
The first parameter is a pointer to the callback function, the second parameter is a pointer to an application-defined value, and the final parameter is a series of flags that control the scope of enumeration. For our purposes, well set this final parameter to DIDFT_ALL to indicate we wish to enumerate all devices. The callback function itself must be defined as:
function TDIEnumDeviceObjectsCallbackA(
var lpddoi: TDIDeviceObjectInstance; // a TDIDeviceObjectInstance structure
pvRef: Pointer // the application-defined data
): BOOL; stdcall; // returns TRUE or FALSE
The first parameter is an initialized TDIDeviceObjectInstance structure containing all the information we need about this specific object. The only other parameter is a pointer to the application-defined value. This callback function should return TRUE to continue enumeration or FALSE otherwise.
As we are enumerating, for each object, we can save the GUID, offset, and type as reported from the TDIDeviceObjectInstance structure into our array of TDIObjectDataFormat structures. We also must keep a count of the number of objects found.
When enumeration completes, we will have a correctly initialized TDIDataFormat structure, complete with an array of correctly initialized TDIObjectDataFormat structures. This entire data structure is then sent to the SetDataFormat method to finally set the correct data format for the game controller. This is illustrated in the following example.
Listing 7-13: Setting the data format
procedure SetDataFormat;
function DIEnumDeviceObjectsProc(const peff: TDIDeviceObjectInstance;
pvRef: Pointer): HRESULT; stdcall;
begin
{if the offset is not beyond the indicated data size... (useful if
we were to use the TDIJoyState data structure instead) }
if peff.dwOfs<FDataFormat.dwDataSize then
begin
{save the type GUID for this object}
FDataFormatGUIDs[FDataFormat.dwNumObjs] := peff.guidType;
{add the object information to our custom made data format}
with FDataFormatObjects[FDataFormat.dwNumObjs] do
begin
pguid := @FDataFormatGUIDs[FDataFormat.dwNumObjs];
dwOfs := peff.dwOfs;
dwType := peff.dwType;
dwFlags := 0;
end;
{if this object is an axis, store it in our axis list}
if (peff.dwType and DIDFT_AXIS) > 0 then
begin
FAxisList[NumAxes] := peff.dwOfs;
Inc(NumAxes);
end;
{increment the number of objects found}
Inc(FDataFormat.dwNumObjs);
end;
{continue enumeration}
Result := DIENUM_CONTINUE;
end;
begin
{enumerate all objects on this input device. this will build our custom data
structure programmatically with the correct information for each object}
FDirectInputDevice.EnumObjects(@DIEnumDeviceObjectsProc, nil, DIDFT_ALL);
{set the data format for the input device}
DXCheck( FDirectInputDevice.SetDataFormat(FDataFormat) );
end;
procedure TfrmJoyTestBed.FormActivate(Sender: TObject);
var
.
.
.
begin
.
.
.
{initialize our axis tracking variable}
NumAxes := 0;
{now we need to begin creating the data format structure and setting the
data format, so we must initialize the overall data format structure}
with FDataFormat do
begin
dwFlags := DIDF_ABSAXIS;
dwDataSize := SizeOf(TDIJoyState2);
dwSize := SizeOf(FDataFormat);
dwObjSize := SizeOf(TDIObjectDataFormat);
dwNumObjs := 0;
rgodf := @FDataFormatObjects;
end;
{create and set a data format specifically made for this device}
SetDataFormat;
.
.
.
end;
Setting Axis Properties With the data format set, we are now ready to start setting various properties for all of the axes.
As discussed above, we must set the range, deadzone, and saturation for each axis. To accomplish this task, well need variables of type TDIPropRange for the range and TDIPropDWord for the deadzone and saturation. As we illustrated in the mouse example, we must initialize the various size members of this structure. Unlike the mouse example, however, we will set the dwObj members of both structures to the object identifier for each individual axis. We could set this to DIPH_DEVICE, setting the properties for all axes on the device, but we may want to set different ranges, deadzones, and saturations for each device. For the TDIPropRange structure, well set the lMin and lMax members to 1,000 and 1,000, respectively. For the TDIPropDWord structure, well set the dwData member to 1,000 for deadzone properties (indicating 10 percent deadzone), and 9,000 for saturation properties (indicating that the last 10 percent is saturation). We can then call the SetProperty method once for each axis and each property. Once this is complete, we can finally set our cooperative level and acquire the device so we can start retrieving input. This is illustrated in the following listing.
Previous
Table of Contents
Next
Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.
Wyszukiwarka
Podobne podstrony:
07 (15)konsultant obslugi projektow finansowanych z programu kapital ludzki 07 15,861000 złotych 15 07 1947MIKROBIOLOGIAwyk 07 10 15R 15 07 (2)US Billboard Top 100 Single Charts 07 02 15 (2015) Tracklista100 złotych 15 07 1947kodeks karny skarbowy 15 07 2016więcej podobnych podstron