Hi Fred!
It seems we (me and polux) have problems in our games on some configs with keyboard, when a lot of sprites are rendered. It is terribly slow. It happens on one of bgames members (cederavic), so we can test.
Maybe it's our way to use keyboard that's not good. Maybe we should use hooks, events, do a delay somewhere, organise our code in some order, put our keys routine in a thread?
I've also read in this article http://www.falloutsoftware.com/tutorials/di/di2.htm that maybe setcooperativelevel could be the problem, but I'm not sure...
If you have a tip (the best method for a game), it would be greatly appreciated! Thank you...
Keyboard - directinput
I've tried to use SetWindowCallback, but I haven't the window number to use it with openscreen. I've tried with ScreenID, but it doesn't work.
Code: Select all
Procedure WindowCB(WindowID.l, Message.l, wParam.l, lParam.l)
; This is where the processing of your callback procedure would be performed
Result = #PB_ProcessPureBasicEvents
Select Message
Case #WM_CLOSE ; #WM_CLOSE = #PB_Event_CloseWindow
MessageRequester("","Closing")
End
; Case #WM_CHAR
; MessageRequester("#WM_CHAR","Character typed : Code "+ Str(wParam)+"="+Chr(wParam)+" ; Code 2 :"+Hex(lParam))
Case #WM_KEYDOWN
MessageRequester("#WM_KEYDOWN","Character typed : Code "+ Str(wParam)+"="+Chr(wParam)+" ; Code 2 :"+Hex(lParam))
Case #WM_KEYUP
MessageRequester("#WM_KEYUP","Character typed : Code "+ Str(wParam)+"="+Chr(wParam)+" ; Code 2 :"+Hex(lParam))
If wParam=27
End
EndIf
Default
ProcedureReturn Result
EndSelect
EndProcedure
InitSprite()
InitKeyboard()
ExamineDesktops()
;OpenScreen(DesktopWidth(0),DesktopHeight(0),DesktopDepth(0),"")
OpenWindow(0, 0, 0, 220, 160, "A screen in a window...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, 160, 160, 0, 0, 0)
; A special callback for the Windows OS allowing you to process window events
SetWindowCallback( @WindowCB())
;SetWindowCallback( @WindowCB(), ScreenID()) ;doesn't work
CreateSprite(1,100,100)
StartDrawing(SpriteOutput(1))
Box( 0, 0,100,100,RGB(250,20,20))
Box(10,10, 80, 80,RGB(50,20,220))
Circle(50,50,30,RGB(200,200,50))
StopDrawing()
; Create a copy of the 1st sprite
CopySprite(1,2)
Repeat
Repeat
Event = WindowEvent()
If Event = #PB_Event_CloseWindow
End
EndIf
Until Event = 0
ExamineKeyboard()
DisplaySprite(1,20,20)
DisplaySprite(2,150,150)
FlipBuffers()
Until KeyboardPushed(#PB_Key_F1)
End
I've tried that, but it doesn't work in fullscreen mode with debugger activated... I imagine this is not strange, as this is a hack. However, could you valid this code?
Code: Select all
Global *pb_callback
Procedure WindowCB(WindowID.l, Message.l, wParam.l, lParam.l)
; This is where the processing of your callback procedure would be performed
Result = #PB_ProcessPureBasicEvents
Select Message
Case #WM_CLOSE ; #WM_CLOSE = #PB_Event_CloseWindow
;MessageRequester("","Closing")
End
; Case #WM_CHAR
; MessageRequester("#WM_CHAR","Character typed : Code "+ Str(wParam)+"="+Chr(wParam)+" ; Code 2 :"+Hex(lParam))
Case #WM_KEYDOWN
;MessageRequester("#WM_KEYDOWN","Character typed : Code "+ Str(wParam)+"="+Chr(wParam)+" ; Code 2 :"+Hex(lParam))
Case #WM_KEYUP
;MessageRequester("#WM_KEYUP","Character typed : Code "+ Str(wParam)+"="+Chr(wParam)+" ; Code 2 :"+Hex(lParam))
If wParam=27
End
EndIf
Default
EndSelect
CallWindowProc_(*pb_callback, WindowID.l, Message.l, wParam.l, lParam.l)
; ProcedureReturn Result
EndProcedure
InitSprite()
InitKeyboard()
ExamineDesktops()
OpenScreen(DesktopWidth(0),DesktopHeight(0),DesktopDepth(0),"")
;OpenWindow(0, 0, 0, 220, 160, "A screen in a window...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
;OpenWindowedScreen(WindowID(0), 0, 0, 160, 160, 0, 0, 0)
; A special callback for the Windows OS allowing you to process window events
;SetWindowCallback_( @WindowCB())
*pb_callback=GetWindowLong_(ScreenID(), #GWL_WNDPROC)
SetWindowLong_(ScreenID(), #GWL_WNDPROC, @WindowCB())
CreateSprite(1,100,100)
StartDrawing(SpriteOutput(1))
Box( 0, 0,100,100,RGB(250,20,20))
Box(10,10, 80, 80,RGB(50,20,220))
Circle(50,50,30,RGB(200,200,50))
StopDrawing()
; Create a copy of the 1st sprite
CopySprite(1,2)
Repeat
Repeat
Event = WindowEvent()
If Event = #PB_Event_CloseWindow
End
EndIf
Until Event = 0
ExamineKeyboard()
DisplaySprite(1,20,20)
DisplaySprite(2,150,150)
FlipBuffers()
Until KeyboardPushed(#PB_Key_F1)
End
- netmaestro
- PureBasic Bullfrog
- Posts: 8425
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
See if this is doing more or less what you want:
Code: Select all
Global oldproc, msgout$
Procedure WindowCB(WindowID.l, Message.l, wParam.l, lParam.l)
If wParam=27
End
EndIf
Select Message
Case #WM_CHAR
msgout$ = "#WM_CHAR, Character typed : Code "+ Str(wParam)+"="+Chr(wParam)+" ; Code 2 :"+Hex(lParam)
Case #WM_KEYDOWN
msgout$ = "#WM_KEYDOWN, Character typed : Code "+ Str(wParam)+"="+Chr(wParam)+" ; Code 2 :"+Hex(lParam)
Case #WM_KEYUP
msgout$ = "#WM_KEYUP, Character typed : Code "+ Str(wParam)+"="+Chr(wParam)+" ; Code 2 :"+Hex(lParam)
Default
ProcedureReturn CallWindowProc_(oldproc, WindowID, message, wparam, lparam)
EndSelect
EndProcedure
InitSprite()
InitKeyboard()
ExamineDesktops()
OpenScreen(DesktopWidth(0),DesktopHeight(0),DesktopDepth(0),"")
oldproc = SetWindowLong_(ScreenID(), #GWL_WNDPROC, @WindowCB())
CreateSprite(1,100,100)
StartDrawing(SpriteOutput(1))
Box( 0, 0,100,100,RGB(250,20,20))
Box(10,10, 80, 80,RGB(50,20,220))
Circle(50,50,30,RGB(200,200,50))
StopDrawing()
; Create a copy of the 1st sprite
CopySprite(1,2)
Repeat
ExamineKeyboard()
ClearScreen(0)
DisplaySprite(1,20,20)
DisplaySprite(2,150,150)
StartDrawing(ScreenOutput())
DrawText(0,DesktopHeight(0)-20,Space(DesktopWidth(0)),0,0)
DrawText(0,DesktopHeight(0)-20,msgout$, #Yellow,#Black)
StopDrawing()
FlipBuffers()
Delay(1)
Until KeyboardPushed(#PB_Key_F1)
End
BERESHEIT
Thank you In windows, fred told us that we can use a callback. Of course, messagerequester doesn't work. Here a little code that I've just done for us.
Code: Select all
;*****************************************************************************************
;*
;* myKeyboardKeys
;*
;* Windows callback routine to get keyboard state with openscreen when
;* standard pb KeyboardReleased and KeyboardPressed don't work
;*
;* djes (djes@free.fr)
;* http://www.bgames.org
;*
;* 09/30/2007 : first version
;*
;*****************************************************************************************
Global Dim myKeyboardKeys.l(255)
Global *myKeyboard_pb_callback
;*****************************************************************************************
Procedure myKeyboardCB(WindowID.l, Message.l, wParam.l, lParam.l)
Select Message
; Case #WM_CHAR
; MessageRequester("#WM_CHAR","Character typed : Code "+ Str(wParam)+"="+Chr(wParam)+" ; Code 2 :"+Hex(lParam))
Case #WM_KEYDOWN
; wParam
; Specifies the virtual-key code of the nonsystem key.
; lParam
; Specifies the Repeat count, scan code, extended-key flag, context code, previous key-state flag, And transition-state flag, As shown in the following table.
; 0-15
; Specifies the Repeat count For the current message. The value is the number of times the keystroke is autorepeated As a result of the user holding down the key. If the keystroke is held long enough, multiple messages are sent. However, the Repeat count is Not cumulative.
; 16-23
; Specifies the scan code. The value depends on the OEM.
; 24
; Specifies whether the key is an extended key, such As the right-hand ALT And CTRL keys that appear on an enhanced 101- Or 102-key keyboard. The value is 1 If it is an extended key; otherwise, it is 0.
; 25-28
; Reserved; do not use.
; 29
; Specifies the context code. The value is always 0 For a WM_KEYDOWN message.
; 30
; Specifies the previous key state. The value is 1 If the key is down before the message is sent, Or it is zero If the key is up.
; 31
; Specifies the transition state. The value is always zero For a WM_KEYDOWN message.
; MessageRequester("#WM_KEYDOWN","Character typed : Code "+ Str(wParam)+"="+Chr(wParam)+" ; Code 2 :"+Hex(lParam))
myKeyboardKeys(wParam)=1
Case #WM_KEYUP
; wParam
; Specifies the virtual-key code of the nonsystem key.
; lParam
; Specifies the Repeat count, scan code, extended-key flag, context code, previous key-state flag, And transition-state flag, As shown in the following table.
; 0-15
; Specifies the Repeat count For the current message. The value is the number of times the keystroke is autorepeated As a result of the user holding down the key. The Repeat count is always one For a WM_KEYUP message.
; 16-23
; Specifies the scan code. The value depends on the OEM.
; 24
; Specifies whether the key is an extended key, such As the right-hand ALT And CTRL keys that appear on an enhanced 101- Or 102-key keyboard. The value is 1 If it is an extended key; otherwise, it is 0.
; 25-28
; Reserved; do not use.
; 29
; Specifies the context code. The value is always 0 For a WM_KEYUP message.
; 30
; Specifies the previous key state. The value is always 1 For a WM_KEYUP message.
; 31
; Specifies the transition state. The value is always 1 For a WM_KEYUP message.
; MessageRequester("#WM_KEYUP","Character typed : Code "+ Str(wParam)+"="+Chr(wParam)+" ; Code 2 :"+Hex(lParam))
myKeyboardKeys(wParam)=2
Default
EndSelect
CallWindowProc_(*myKeyboard_pb_callback, WindowID.l, Message.l, wParam.l, lParam.l)
EndProcedure
;*****************************************************************************************
Procedure myKeyboardReleased(code.l)
If mykeyboardkeys(code)=2
mykeyboardkeys(code)=0
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndProcedure
;*****************************************************************************************
Procedure myKeyboardPressed(code.l)
If mykeyboardkeys(code)=1
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndProcedure
;*****************************************************************************************
;* Need to be called after openscreen
Procedure myKeyboardInit()
If ScreenID()=0
MessageRequester("myKeyboardInit","Screen not opened")
End
EndIf
;Our callback working with openscreen
*myKeyboard_pb_callback=GetWindowLong_(ScreenID(), #GWL_WNDPROC)
If SetWindowLong_(ScreenID(), #GWL_WNDPROC, @myKeyboardCB())=0
MessageRequester("myKeyboardInit","Can't intercept keys")
End
EndIf
EndProcedure
;*****************************************************************************************
InitSprite()
;OpenWindow(0, 0, 0, 220, 160, "A screen in a window...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
;OpenWindowedScreen(WindowID(0), 0, 0, 160, 160, 0, 0, 0)
;Usual PB callback for the Windows OS allowing you to process window events
;SetWindowCallback_( @WindowCB())
ExamineDesktops()
OpenScreen(DesktopWidth(0),DesktopHeight(0),DesktopDepth(0),"")
myKeyboardInit()
CreateSprite(1,100,100)
StartDrawing(SpriteOutput(1))
Box( 0, 0,100,100,RGB(250,20,20))
Box(10,10, 80, 80,RGB(50,20,220))
Circle(50,50,30,RGB(200,200,50))
StopDrawing()
x=DesktopWidth(0)/2-SpriteWidth(1)/2
y=DesktopHeight(0)/2-SpriteHeight(1)/2
;*****************************************************************************************
Repeat
;Repeat
; Event = WindowEvent()
; If Event = #PB_Event_CloseWindow
; End
; EndIf
;Until Event = 0
If myKeyboardPressed(#PB_Shortcut_Up)
y-1
EndIf
If myKeyboardReleased(#PB_Shortcut_Down)
y+1
EndIf
ClearScreen(0)
DisplaySprite(1,x,y)
StartDrawing(ScreenOutput())
text.s="myKeyboardKeys test"
DrawText(DesktopWidth(0)/2-TextWidth(text)/2,50,text,RGB($FF,$FF,$FF),0)
text.s="Up Arrow to move up, press and release Down Arrow to move down"
DrawText(DesktopWidth(0)/2-TextWidth(text)/2,DesktopHeight(0)/2-TextHeight(text)/2,text,RGB($FF,$FF,$FF),0)
StopDrawing()
FlipBuffers()
Until myKeyboardReleased(#PB_Shortcut_Escape)
End