07 11


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 Tip: The dwTimeStamp member of this structure indicates when the input event actually occurred. The time stamps from subsequent events could potentially be used to determine if the user double-clicked on some item. The dwSequence number, on the other hand, indicates the chronological sequence in which input events where obtained. This is useful for determining the order of input from two separate devices, as DirectInput never assigns the same sequence number for events from different devices, even if they have the same time stamp. This might come in handy if developing a multiplayer game where two people can play from the same machine. All of this new functionality has been added to our baseline application so we can easily create DirectX applications with mouse support. While we are not going to cover it here, this new baseline application contains some additional code for drawing the mouse cursor on the primary surface from the secondary input thread. This solves the problem we noted earlier about the mouse cursor dependency on the animation frame rate. The following listing illustrates using the event notification and buffered data retrieval methods for obtaining mouse input data. Listing 7-10: Retrieving buffered mouse input data interface type . . . {this class is used to track click events} TMouseData = class public XPos, YPos: Integer; Button: TMouseButton; constructor Create(X, Y: Integer; MButton: TMouseButton); end; var CurX, CurY, OldX, OldY: Integer; // the mouse position variables MouseClickList: TList; // the list of click events FCritSec: TCriticalSection; // syncronization object FMouseEvents: TWOHandleArray; // events array const {we’re using a 32 X 32 pixel mouse cursor image} CURSORWIDTH = 32; CURSORHEIGHT = 32; {our animated mouse cursor has 8 frames} NUMFRAMES = 8; implementation constructor TMouseData.Create(X, Y: Integer; MButton: TMouseButton); begin {create and initialize the mouse data object for a click event} XPos := X; YPos := Y; Button := MButton; end; procedure TMouseThread.Execute; var EventNum: Integer; NumElements: DWORD; DeviceData: TDIDeviceObjectData; DataResult: HRESULT; SourceRect, DirtyRect: TRect; begin {continuously perform this code until terminated} while not Terminated do begin {wait until one of the events becomes signaled} EventNum := WaitForMultipleObjects(2, @FMouseEvents, FALSE, INFINITE); {was the quit event signaled? if so, terminate} if EventNum-WAIT_OBJECT_0 = QUITEVENT then begin Terminate; Break; end; {we are about to use global variables, so enter the critical section} FCritSec.Enter; {store the current mouse cursor coordinates} OldX := CurX; OldY := CurY; {begin retrieving buffered data} while TRUE do begin {we only want to retrieve one element at a time} NumElements := 1; {retrieve the buffered data} DataResult := FMouseDevice.GetDeviceData(SizeOf(TDIDeviceObjectData), @DeviceData, NumElements, 0); {if we retrieved data, update global variables} if (DataResult = DI_OK) and (NumElements = 1) then begin case DeviceData.dwOfs of {update mouse cursor positions} DIMOFS_X : CurX := CurX + DeviceData.dwData; DIMOFS_Y : CurY := CurY + DeviceData.dwData; {update our list of click events} DIMOFS_BUTTON0 : MouseClickList.Add(TMouseData.Create(CurX, CurY, mbLeft)); DIMOFS_BUTTON1 : MouseClickList.Add(TMouseData.Create(CurX, CurY, mbRight)); end; end else {if there were no move input events to retrieve, continue} Break; end; {clip the global mouse cursor positions to the extents of our screen resolution} if CurX < 0 then CurX := 0; if CurX > DXWIDTH-CURSORWIDTH then CurX := DXWIDTH-CURSORWIDTH-1; if CurY < 0 then CurY := 0; if CurY > DXHEIGHT-CURSORHEIGHT then CurY := DXHEIGHT-CURSORHEIGHT-1; {if the mouse position has changed...} if not ((CurX = OldX) and (CurY = OldY)) then begin {draw the mouse cursor if the old and new positions do not overlap...} if (ABS(CurX - OldX)>= CURSORWIDTH) or (ABS(CurY - OldY)>= CURSORHEIGHT) then begin {erase the old cursor} SourceRect := Rect(NUMFRAMES*CURSORWIDTH, 0, NUMFRAMES*CURSORWIDTH+ CURSORWIDTH, CURSORHEIGHT); FPrimarySurface.BltFast(OldX, OldY, FMouseCursors, SourceRect, DDBLTFAST_NOCOLORKEY or DDBLTFAST_WAIT); {save area under new cursor location} SourceRect := Rect(CurX, CurY, CurX+CURSORWIDTH, CurY+CURSORHEIGHT); FMouseCursors.BltFast(NUMFRAMES*CURSORWIDTH, 0, FPrimarySurface, SourceRect, DDBLTFAST_NOCOLORKEY or DDBLTFAST_WAIT); {draw new cursor} SourceRect := Rect(FCursorFrame*CURSORWIDTH, 0, (FCursorFrame* CURSORWIDTH)+CURSORWIDTH, CURSORHEIGHT); FPrimarySurface.BltFast(CurX, CurY, FMouseCursors, SourceRect, DDBLTFAST_NOCOLORKEY or DDBLTFAST_WAIT); end else {...or draw the mouse cursor if the old and new positions do overlap} begin {copy the dirty rectangle to the scratch buffer} UnionRect(DirtyRect, Rect(OldX, OldY, OldX+CURSORWIDTH, OldY+CURSORHEIGHT), Rect(CurX, CurY, CurX+CURSORWIDTH, CurY+CURSORHEIGHT)); FMouseScratch.BltFast(0, 0, FPrimarySurface, DirtyRect, DDBLTFAST_NOCOLORKEY or DDBLTFAST_WAIT); {erase the old cursor from the scratch buffer} SourceRect := Rect(NUMFRAMES*CURSORWIDTH, 0, NUMFRAMES*CURSORWIDTH+ CURSORWIDTH, CURSORHEIGHT); FMouseScratch.BltFast(OldX-DirtyRect.Left, OldY-DirtyRect.Top, FMouseCursors, SourceRect, DDBLTFAST_NOCOLORKEY or DDBLTFAST_WAIT); {save the area under the new cursor} SourceRect := Rect(CurX-DirtyRect.Left, CurY-DirtyRect.Top, (CurX- DirtyRect.Left)+CURSORWIDTH, (CurY- DirtyRect.Top)+CURSORHEIGHT); FMouseCursors.BltFast(NUMFRAMES*CURSORWIDTH, 0, FMouseScratch, SourceRect, DDBLTFAST_NOCOLORKEY or DDBLTFAST_WAIT); {draw new cursor into scratch buffer} SourceRect := Rect(FCursorFrame*CURSORWIDTH, 0, (FCursorFrame* CURSORWIDTH)+CURSORWIDTH, CURSORHEIGHT); FMouseScratch.BltFast(CurX-DirtyRect.Left, CurY-DirtyRect.Top, FMouseCursors, SourceRect, DDBLTFAST_NOCOLORKEY or DDBLTFAST_WAIT); {draw scratch buffer back to primary buffer} SourceRect := Rect(0, 0, DirtyRect.Right-DirtyRect.Left, DirtyRect.Bottom-DirtyRect.Top); FPrimarySurface.BltFast(DirtyRect.Left, DirtyRect.Top, FMouseScratch, SourceRect, DDBLTFAST_NOCOLORKEY or DDBLTFAST_WAIT); end; end; {we are finished using global variables, so we can now leave the critical section} FCritSec.Leave; end; end; 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:
143 07 (11)
07 11
Historia sztuki nowoczesnej polskiej malarstwo 07 11
Efektywnosc2010 07 11

więcej podobnych podstron