pyskool icon indicating copy to clipboard operation
pyskool copied to clipboard

Controller... control?

Open HoraceAndTheSpider opened this issue 5 years ago • 7 comments

Hi

I was wondering if there were any plans to add controller support to Pyskool?

I have been thinking about trying it myself but I confess I have struggled a bit with how “pythonic” the code is! I am not a natural to this kind of structure (I prefer basic variants)

My attempt is basically to read in pygame controller inputs, and with both analogue stick and hats acting as directions, use possible button combinations to “emulate” the key presses.

This would be developed perhaps to have a controller.ini which could specify button numbers according to the pad used.

Button 1 on some pads might be X for example, so could be preferable for catapult fire.

It may be acceptable however to have “catch mouse” as a combination - e.g holding a shoulder button and pressing “circle” , so this might be buttons 7+3 on some controllers.

If this were done, it would not be a difficult task to have a separate python script “translate” say a RetroArch control map into a PySkool format, making the game easily playable on say retropie.

Thoughts welcome!

HoraceAndTheSpider avatar Jan 16 '20 23:01 HoraceAndTheSpider

No, I don't have any plans to add controller support to Pyskool. Thing is, I don't own a joystick, so even if I did add support it would be hard for me to test it!

Anyway, if I were to add support, I'd start with your approach of converting joystick input into keypresses. In the event retrieval loop in Keyboard.pump() (see input.py), for each joystick event that comes in, I'd add an appropriate keyboard event to self.key_down_events. And having a controller.ini file that specifies how to map joystick events to keyboard events is a good idea. I don't think it should be any more complicated than that, but famous last words etc.

If you plan to go ahead with this, good luck!

skoolkid avatar Jan 21 '20 20:01 skoolkid

update: 'emulating' keyboard presses isnt really a go-er due to the fact it will differ heavily on every platform.

However, i have now managed to create a 'controller_as_keyboard' class, intialise the controller, and start running checks in input.py get_joystick() to fill Keyboard.joy_action (not the prettiest solution i admit).

Combining this with conditional OR checks in eric.py has allowed me to get him wandering around the school from either AXIS or HAT controls :)

HoraceAndTheSpider avatar Jan 30 '20 20:01 HoraceAndTheSpider

Congrats!

Not sure what you mean by emulating keyboard presses not being a go-er, though. Can't you just translate a 'joystick right' event into a Pygame K_p keyboard event? Then there should be no need to modify eric.py or any other part of the game code. Only Keyboard (in input.py) should care where input is actually coming from; as far as the rest of the code is concerned, there are only keypresses to handle (genuine or emulated, it doesn't matter).

skoolkid avatar Jan 30 '20 21:01 skoolkid

I am away from the code as I write this but iirc self.key_down_events gets filled with keyboard events for your processing in input.py , so this is the problem really, in “emulating” those.

I can make my controller routine easily output one of the keyboard equivalents you nicely set up inkeys.py but to turn those into the events threw up problems.

When I looked into it, the issue appears to be win/OS X etc all handling keyboards differently, although reading more now maybe I can create a custom/fake keypress event if I declare it differently

I would be glad not to need to edit Eric.py but I am probably going to have do something special to handle auto-writing combinations onto the blackboard for example, so it may be unavoidable

HoraceAndTheSpider avatar Jan 30 '20 23:01 HoraceAndTheSpider

Revisited and solved the above issues. i had to make so pretty ugly code to solve a 'holding down a button' issue, and in doing so i notice that Pyskool limits (for example) a single keypress for Sitting down to one action, whereas i belive you can press and hold this on the original?

I will do some cleaning up of that (i dont expect it to be great still though), and add an INI file for the control buttons as you suggested.

The biggest problem i have is that i can no longer load/save - i get errors with pickling, such as TypeError: can't pickle Joystick objects and TypeError: can't pickle Event objects and i'm not sure why this would be, as I havent touch anything other than the input.py now

HoraceAndTheSpider avatar Feb 04 '20 17:02 HoraceAndTheSpider

That's odd. Sounds as if when you're trying to save, there are unprocessed keypress events left in the queue (somehow). Are you saving any events to the queue that you don't later check for?

A possible fix for this is to make sure that Keyboard's key_down_events list is cleared before pickling. Try adding this line to the Game._save() method in game.py before the pickle.dump() call:

self.keyboard.key_down_events.clear()

skoolkid avatar Feb 04 '20 19:02 skoolkid

right, that did help thank you :)

There shouldnt be any events which are not loaded in, as they are 'dumped' into the queue adjacent to the 'real' keyboard events...

I had to also close down my joystick object, so i am using:

        if self.keyboard.moved_joystick != None:
            self.keyboard.moved_joystick.quit
            self.keyboard.moved_joystick = None
        self.keyboard.key_down_events.clear()

I also had to improve my joystick initialisation code for afterwards, but so far looking good.

HoraceAndTheSpider avatar Feb 04 '20 20:02 HoraceAndTheSpider