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
Listing 7-6: Initializing DirectInput for mouse data retrieval
{create the DirectInput object}
DirectInputCreate(hInstance, DIRECTINPUT_VERSION, FDirectInput, nil);
{create the DirectInputDevice object for the primary mouse}
FDirectInput.CreateDevice(@GUID_SysMouse, FMouseDevice, nil);
{set the data format for mouse data}
FMouseDevice.SetDataFormat(c_dfDIMouse);
{set the appropriate cooperative level}
FMouseDevice.SetCooperativeLevel(Handle,DISCL_FOREGROUND or DISCL_EXCLUSIVE);
With this accomplished, we should now set the size of the buffer that will hold our mouse input data. This property takes only a simple DWORD of information, so we can use a TDIPropDWord structure in our call to SetProperty. After initializing the appropriate size members, we should set the diph.dwObj member to zero and the diph.dwHow member to DIPH_DEVICE, indicating that this property affects the entire device. Setting the dwData member to 64 indicates we want to set the buffer size to hold 64 data packets (this number is arbitrary, and can be higher or lower as dictated by the application requirements). Thus, our buffer will be capable of holding 64 individual instances of mouse input, be that axis movement, button presses, etc. If we do not retrieve and flush this buffer before this limit is reached, any subsequent input data will be lost. This process is illustrated below.
Listing 7-7: Setting the size of the buffer
procedure TfrmDXAppMain.FormActivate(Sender: TObject);
var
.
.
.
{the mouse property structure}
MouseProp: TDIPropDWord;
begin
.
.
.
{initialize our property structure}
MouseProp.diph.dwSize := SizeOf(TDIPropDWord);
MouseProp.diph.dwHeaderSize := SizeOf(TDIPropHeader);
MouseProp.diph.dwObj := 0;
MouseProp.diph.dwHow := DIPH_DEVICE;
MouseProp.dwData := 64; // we want 64 data packets
{set the size of the buffer property}
DXCheck( FMouseDevice.SetProperty(DIPROP_BUFFERSIZE, MouseProp.diph) );
Event Notification As weve previously discussed, DirectInput has a method known as event notification where it can signal the application that an input event has occurred on some device. This releases the application from the requirement of polling the device through every iteration of the game loop, but it introduces some serious implications.
This technique works by using a Windows event object. Basically, an event is little more than a flag that exists in a signaled or non-signaled state, and is used for thread synchronization. Using the IDirectInputDevices SetEventNotification method you can pass the device an event, which will be set to a signaled state when new input is available.
The only way this is useful is in a call to one of the Win32 API wait functions. These functions halt execution of a thread until the event object passed into the function becomes signaled. This is useless in a single-threaded application, as it would halt the execution of the primary thread unless the mouse is moving, making for a boring game indeed. This is why we must use this technique in a multithreaded application. Well see one of these wait functions in action below.
We will actually want to create two events, one which is passed to DirectInput to signal the availability of new mouse input and one to signal the thread to terminate. We can create these events using the Win32 API function CreateEvent, which is defined as:
function CreateEvent(
lpEventAttributes: PSecurityAttributes; // pointer to security attributes
bManualReset: BOOL; // flag for manual reset event
bInitialState: BOOL; // flag for initial state
lpName: PChar // name of the event object
): THandle; // returns a handle of the event object
For our purposes, we can set the first parameter to nil, and the second and third parameters to FALSE. We can set the final parameter to an appropriate name for the event, but it is unimportant to our application. These events will be stored in an array for easy management. We will also create a TCriticalSection object, which we will use to synchronize the main thread and our secondary input thread. Using the critical section object will be covered below when we read the mouse data from the buffer.
Now that weve created our events, we need to tell DirectInput which event to signal when mouse input becomes available. This is accomplished by calling the IDirectInputDevices SetEventNotification method, defined as:
function SetEventNotification(
hEvent: THandle // a handle to the event to be signaled
): HResult; // returns a DirectX error code
The only parameter to this method is the handle of the event to be signaled, which we just created above. The following example demonstrates the setup required for initializing event notification.
Listing 7-8: Initializing event notification
{create our events, one for indicating new mouse input data, one for
indicating that the application is terminating}
FMouseEvents[MOUSEEVENT] := CreateEvent(nil, FALSE, FALSE, MouseEvent);
FMouseEvents[QUITEVENT] := CreateEvent(nil, FALSE, FALSE, QuitEvent);
{create our critical section synchronization object}
FCritSec := TCriticalSection.Create;
{set the event notification}
DXCheck( FMouseDevice.SetEventNotification(FMouseEvents[MOUSEEVENT]) );
Secondary Thread Creation Now that the critical section and events have been set up, we need to create our secondary thread. This second thread is where we will perform all input data retrieval. We used the File | New menu to create a new TThread object, using the Execute method as the location for our code that retrieves mouse input. Well examine the details of this code below when we cover reading input data. To actually create the thread, we call our TThread objects Create method, passing its only parameter a value of TRUE to indicate we want the thread to be suspended upon creation. The thread should be suspended as we have not yet acquired the mouse. We then set its Priority property to tpTimeCritical, indicating we want it to be immediately responsive, and its FreeOnTerminate property to TRUE, indicating it should free itself when it is terminated. These steps are illustrated in the following listing.
Listing 7-9: Creating the secondary input thread
{create our secondary input thread}
FMouseThread := TMouseThread.Create(TRUE);
{we want it to be supremely responsive}
FMouseThread.Priority := tpTimeCritical;
{indicate it should free itself when it terminates}
FMouseThread.FreeOnTerminate := TRUE;
Device Acquisition Now that the events have been created and set up and the secondary input thread has been initialized, we can acquire the device by calling the Acquire method. As a final step, we must begin executing the input thread by calling the threads Resume method. We are now finally ready to start retrieving buffered, event-driven mouse input data.
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:
od 02 07 09 do 10 07 09TI 99 07 09 B pl(1)Mechanika budowli I egzamin (03 07 09)(2)Wędrówka przez Biblię twr 26 07 09Shell zainwestuje miliardy w Iraku (07 09 2008)plyty?lextherm 08 07 092010 07 09 Kalendarz Histmag orgustawa o wojewodzie i administracji rządowej w województwie 07,09,2015Atachment 13 09 23 07 18 38Plan studiow PK NST nabor2008 09 07 01TI 99 09 07 T B pl(1)ANT SPCC (09 07 27 18 28)więcej podobnych podstron