PDA

View Full Version : Problems using SDLInput.pas :(



paul_nicholls
10-07-2009, 05:16 AM
Hi all,
I am trying to use SDLInput.pas for my PGDAnnual2009 entry and am having some issues...

I am using a TSDLInputManager class that I have already created like so:

InputManager := TSDLInputManager.Create([itJoystick , itKeyBoard, itMouse]);

Issue #1 I have tried enabling all three input types (joystick, keyboard and mouse) using this code:

InputManager.Enable([itJoystick,itKeyBoard,itMouse]);

but it crashes and gives me an error dialog box:


Project DayOfDestruction.exe raised exception class EListError with message 'List index out of bounds (0)'. Process stopped. Use Step or Run to continue.

Would this be because I don't have a joystick attached to my system?

I would have thought that the code would have done some error checking behind the scenes...

it seems I can fix it using this code instead as a workaround:

If InputManager.JoyStick.NumOfJoySticks > 0 Then
InputManager.Enable([itJoystick,itKeyBoard,itMouse])
Else
InputManager.Enable([itKeyBoard,itMouse]);

But I don't think I should have to do this myself :(

Issue #2 I am trying to detect keypresses using the keyboard input manager like so:

InputManager.KeyBoard.OnKeyUp := OnKeyUp;

Where the OnKeyUp method is this:

Procedure TGame.OnKeyUp(var Key: TSDLKey; Shift: TSDLMod; unicode : UInt16);
Begin
If Key = SDLK_ESCAPE Then ExitApplication;
End;

but it is never being called for some reason...

As you can see from the code below the update method of the InputManager is being called ok in my main SDL loop:

Procedure TSDLApplication.Run(Const AWidth,AHeight,ADepth : Uint32;
Const AFullScreen : Boolean);
Const
cLockFPS = 60;
cMinTimeSlice = Round(1/cLockFPS);
cMaxTimeSlice = 1;
Var
event : TSDL_Event;
TimeSlice : Single;
FPS : Single;
Begin
FWidth := AWidth;
FHeight := AHeight;
FDepth := ADepth;
FFullScreen := AFullScreen;
Try
If Not Initialize Then Exit;
FTimer.Init;

TimeSlice := cMinTimeSlice;
FFinished := False;
While Not FFinished Do
Begin
FInputManager.UpdateInputs(event);
If SDL_MustLock(FVideoBuffer) Then
SDL_LockSurface(FVideoBuffer);

FPS := FTimer.GetFPS;
ProcessFrame(TimeSlice,FPS,FFinished);

If SDL_MustLock(FVideoBuffer) Then
SDL_UnlockSurface(FVideoBuffer);

Case FOpenGLEnabled Of
False : SDL_Flip(FVideoBuffer);
True : SDL_GL_SwapBuffers;
End;

TimeSlice := FTimer.GetElapsedSeconds;
FTimer.LockFPS(cLockFPS);
End;
Finally
Cleanup;
End;
End;

Any ideas?

cheers,
Paul

paul_nicholls
10-07-2009, 05:40 AM
Nevermind...I figured it out :-[

I somehow deleted the SDL_PollEvent() call out of the code so no events were being read from SDL!! D'OH!

While SDL_PollEvent(@event) = 1 Do FInputManager.UpdateInputs(event);

It is now working...

cheers,
Paul

paul_nicholls
10-07-2009, 01:49 PM
I'm still wondering about issue#1 though - the crash if no joystick is available...

Not sure why it was programmed that way...

cheers,
Paul

paul_nicholls
12-07-2009, 10:31 PM
bump? :)

noeska
13-07-2009, 07:26 AM
In some way it makes sense to only enable things that actualy are available ...

chronozphere
13-07-2009, 10:49 AM
I don't like these kind of things either. It's better to just return an error code than a crash.

The actual error looks very "Delphi-ish" and seems to be generated by the TSDLInputManager wrapper class. If you have the source, you could debug that yourself Just temporarly add the unit that contains TSDLInputManager to your project and step through the code using the debugger. It's probably just a matter of adding/tweaking an IF statement. :D

If you don't have the source, you can ask the people who are maintaining JEDI-SDL. :)

jdarling
14-07-2009, 12:02 AM
You should be able to do the following:



if (SDL_Init(SDL_INIT_JOYSTICK) < 0) then
InputManager := TSDLInputManager.Create([itJoystick , itKeyBoard, itMouse])
else
InputManager := TSDLInputManager.Create([itKeyBoard, itMouse]);


The problem is that that TSDLInputManager will throw an error if you try to init something that doesn't exist. It's an oddity of the pascal wrappers (and one that I personally don't like). To avoid things like this, try using the SDL interface directly instead of using the wrapper objects.

paul_nicholls
14-07-2009, 01:31 AM
Thanks all for the hints/tips :)

I may just stick with the code I have now:

If InputManager.JoyStick.NumOfJoySticks > 0 Then
InputManager.Enable([itJoystick,itKeyBoard,itMouse])
Else
InputManager.Enable([itKeyBoard,itMouse]);

cheers,
Paul