Mapping a "save_delete" action to a gamepad button? (Solved!)

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
User avatar
tim640
Regular
Posts: 47
Joined: Wed May 23, 2018 4:47 pm
Contact:

Mapping a "save_delete" action to a gamepad button? (Solved!)

#1 Post by tim640 »

Good evening ya'll!
So as the thread name says. Honestly, i've been sitting on such a small (as i thought lol) thing for a couple of hours by now and read the whole documentation through, but simply can't seem to make it work. Basically what i want to do it whenever i use the gamepad (i use the Xbox Windows one) and in the load section, when the slot with the save is selected, by pressing "X" button it'd trigger the "save_delete" function. Using the mouse\keyboard it works no problem with the

key "save_delete" action FileDelete(slot)

part, yet i can't figure out how to bind a gamepad button to this function no matter how i try. If anyone has ideas, please do share and thank you in advance!
Last edited by tim640 on Sat May 26, 2018 5:23 am, edited 1 time in total.

kivik
Miko-Class Veteran
Posts: 786
Joined: Fri Jun 24, 2016 5:58 pm
Contact:

Re: Mapping a "save_delete" action to a gamepad button?

#2 Post by kivik »

Try pad_x_press?

I can't find a full list of gamepad keymaps but this page makes me think it'd be that.

https://www.renpy.org/doc/html/keymap.html

User avatar
tim640
Regular
Posts: 47
Joined: Wed May 23, 2018 4:47 pm
Contact:

Re: Mapping a "save_delete" action to a gamepad button?

#3 Post by tim640 »

Yep, that is exactly what i did at first.

key "pad_x_press" action FileDelete(slot)

doesn't work; reading the manual also kinda says that gamepad buttons are binding to events, not to functions; also, in the "default" settings of controls "pad_x_press" doesn't even exist.
So at first i tried to map the "save_delete" to "pad_y_press", it didn't work. Then i read more and tried to map in with

init:
$ config.keymap['save_delete'].append('pad_x_press')

placed in "options.rpy", also in "gui.rpy" just in case for some reason that'll do the trick
And well
It didn't :<

User avatar
tim640
Regular
Posts: 47
Joined: Wed May 23, 2018 4:47 pm
Contact:

Re: Mapping a "save_delete" action to a gamepad button?

#4 Post by tim640 »

UPD:

yeeeah so i am a bit stupid bc i should've done

init:
$ config.pad_bindings["pad_x_press"].append("save_delete")

instead of "keymap" because i am trying to configure the gamepad after all lol
Now with that function in options it gives me an exception

KeyError: u'pad_x_press'

Changing the "x" to "y" seems to fix the exception, yet pressing "y" on the save slot does nothing. (this of course with me editing the
key "pad_x_press" action FileDelete(slot)
function in the "screens.rpy" all along of course, i didn't forget)

Soooooo yeah the question stays

User avatar
Remix
Eileen-Class Veteran
Posts: 1628
Joined: Tue May 30, 2017 6:10 am
Completed: None... yet (as I'm still looking for an artist)
Projects: An un-named anime based trainer game
Contact:

Re: Mapping a "save_delete" action to a gamepad button?

#5 Post by Remix »

Maybe:

Code: Select all

init python:
    if not 'pad_x_press' in config.pad_bindings:
        config.pad_bindings['pad_x_press'] = []
    config.pad_bindings['pad_x_press'].append( "save_delete" )
This does of course presume that the gamecontrollerdb.txt setup for the gamepad in question includes an 'x' button...

It also presumes that new button events can just be added... might also need:

renpy.display.controller.make_event( "pad_x_press" ) or somesuch
Frameworks & Scriptlets:

User avatar
tim640
Regular
Posts: 47
Joined: Wed May 23, 2018 4:47 pm
Contact:

Re: Mapping a "save_delete" action to a gamepad button?

#6 Post by tim640 »

Checked gamecontrollerdb.txt just in case, every button is present there! Now as to the code, seems extremely logical, yet it doesn't work, i am at a loss haha
It at least doesn't cause an exception, at least the big piece of the code you wrote. Unlike the

renpy.display.controller.make_event( "pad_x_press" )

though, when i add this, it cause an exception saying

File "game/options.rpy", line 204, in <module>
renpy.display.controller.make_event("pad_x_press")
AttributeError: 'NoneType' object has no attribute 'keyboard_focused'

Maybe i am placing it at the wrong place?.. I am kinda new to python, basically just getting into it. I try my best to keep the syntax and everything, thankfully, it's all very logical, but still eh



Even though this concrete detail doesn't affect the gameplay in critical ways, i want to get it to see what's the problem here to understand it now haha

User avatar
tim640
Regular
Posts: 47
Joined: Wed May 23, 2018 4:47 pm
Contact:

Re: Mapping a "save_delete" action to a gamepad button?

#7 Post by tim640 »

P.S: found an interesting part of the code in "controller.py":

# Should we ignore events?
ignore = False

def make_event(name):
"""
Creates an EVENTNAME event with `name`, and returns it.
"""

if not renpy.display.interface.keyboard_focused:
return None

if ignore:
return None

names = [ name ]

if renpy.config.map_pad_event:
names.extend(renpy.config.map_pad_event(name))
else:
names.extend(renpy.config.pad_bindings.get(name, ()))

return pygame_sdl2.event.Event(
renpy.display.core.EVENTNAME,
{ "eventnames" : names, "controller" : name, "up" : False })



Could this help somehow? Tried to write a "make_event" code myself based on this but i am afraid i am too unexperienced yet for it to work
Last edited by tim640 on Wed May 23, 2018 8:32 pm, edited 1 time in total.

User avatar
Remix
Eileen-Class Veteran
Posts: 1628
Joined: Tue May 30, 2017 6:10 am
Completed: None... yet (as I'm still looking for an artist)
Projects: An un-named anime based trainer game
Contact:

Re: Mapping a "save_delete" action to a gamepad button?

#8 Post by Remix »

Yeah, ignore that, seems Ren'py uses it during the actual event action to create an object that it can use to handle the user action.

Maybe remove the "key "pad_x_press" action FileDelete(slot)" bit entirely, then test:

Have you configured and tested your controller? Is renpy.game.preferences.pad_enabled set to True? Does your game support a controller config menu?
Do other buttons work? Does controller 'y' hide windows for example?
Does the standard Delete Key delete saves correctly?
If so, maybe just try appending "save_delete" to the working button of the controller and testing.
Frameworks & Scriptlets:

User avatar
tim640
Regular
Posts: 47
Joined: Wed May 23, 2018 4:47 pm
Contact:

Re: Mapping a "save_delete" action to a gamepad button?

#9 Post by tim640 »

Removed the "key "pad_x_press" action FileDelete(slot)" , but also didn't changed a thing :<

Also, all of the things you asked are positive. All other functions works perfectly fine

It's really weird. Like, i have a "Press Start to continue" screen instead of the main menu, basically it's just a bg with some transformed text, on which i set parameters

key "game_menu" action ShowMenu("load"):
activate_sound "music/optionsclick.mp3"
key "K_SPACE" action ShowMenu("load"):
activate_sound "music/optionsclick.mp3"
key "K_RETURN" action ShowMenu("load"):
activate_sound "music/optionsclick.mp3"
key "pad_a_press" action ShowMenu("load"):
activate_sound "music/optionsclick.mp3"
key "mousedown_1" action ShowMenu("load"):
activate_sound "music/optionsclick.mp3"

- basically it makes this opening screen progress to the "Load" screen after any of these buttons are presses. And it all works perfect. I am confused af :<

Also, a while ago i changed the "x" button in the code to "y" (and tried other ones, too), and it also doesn't react Dx

User avatar
Remix
Eileen-Class Veteran
Posts: 1628
Joined: Tue May 30, 2017 6:10 am
Completed: None... yet (as I'm still looking for an artist)
Projects: An un-named anime based trainer game
Contact:

Re: Mapping a "save_delete" action to a gamepad button?

#10 Post by Remix »

So, do all those buttons still do what you want after that press_start_screen is hidden?

I'm thinking that, because "save_delete" can only work while in the load/save menu, that screen is likely hidden so those mappings might not run...

Maybe better to try testing the controller in a game screen with a button rather than in the sub menu...

Code: Select all


screen test_controller():

    fixed:
    
        for i,v in enumerate( [ 'a', 'b', 'x', 'y' ] ):

            textbutton "Press [v] button":
                keysym "pad_{}_press".format(v) 
                action Function( renpy.notify, "Pressed {}".format(v) )
                pos (100, i*50)
            
            textbutton "Release [v] button":
                keysym "pad_{}_release".format(v)
                action Function( renpy.notify, "Released {}".format(v) )
                pos (300, i*50)



label start:

    show screen test_controller
    "..."
If you get notifications for a, b, y and not x we would know x isn't supported...
Frameworks & Scriptlets:

User avatar
tim640
Regular
Posts: 47
Joined: Wed May 23, 2018 4:47 pm
Contact:

Re: Mapping a "save_delete" action to a gamepad button?

#11 Post by tim640 »

All the buttons in every other occasion with the current settings work as i need it! ;_; On every screen.

Oh, well. Actually, i've been thinking: is it's such a pain to map the button to the gamepad, i can just add additional textbutton to delete a save right under the slot, right? It would be more intuitive also, which is great, and easy to access.
But it seems to be also not that easy U_U Weh
My code with the slots haven't changed, its:

Code: Select all

    ## The grid of file slots.
            grid gui.file_slot_cols gui.file_slot_rows:
                style_prefix "slot"

                xalign 0.5
                yalign 0.5

                spacing gui.slot_spacing

                for i in range(gui.file_slot_cols * gui.file_slot_rows):

                    $ slot = i + 1

                    button:
                        action FileAction(slot)
                        activate_sound "music/optionsclick.mp3"
                        hover_sound "music/hover.mp3"

                        has vbox

                        add FileScreenshot(slot) xalign 0.5

                        text FileTime(slot, format=_("{size=+15}{#file_time}%A, %B %d %Y, %H:%M{/size}"), empty=_("{size=+15}empty slot{/size}")):
                            style "slot_time_text"

                        text FileSaveName(slot):
                            style "slot_name_text"





                        key "save_delete" action FileDelete(slot)


So i thought of adding a textbutton "DELETE" right under the slot name/time, like that:

Code: Select all

 ## The grid of file slots.
            grid gui.file_slot_cols gui.file_slot_rows:
                style_prefix "slot"

                xalign 0.5
                yalign 0.5

                spacing gui.slot_spacing

                for i in range(gui.file_slot_cols * gui.file_slot_rows):

                    $ slot = i + 1

                    button:
                        action FileAction(slot)
                        activate_sound "music/optionsclick.mp3"
                        hover_sound "music/hover.mp3"

                        has vbox

                        add FileScreenshot(slot) xalign 0.5

                        text FileTime(slot, format=_("{size=+15}{#file_time}%A, %B %d %Y, %H:%M{/size}"), empty=_("{size=+15}empty slot{/size}")):
                            style "slot_time_text"

                        text FileSaveName(slot):
                            style "slot_name_text"

                    textbutton ("DELETE") action FileDelete(slot)




                        key "save_delete" action FileDelete(slot)


But when i do so, i get the "Grid overfull" exception. My grid in the gui.rpy is

Code: Select all

define gui.file_slot_cols = 3
define gui.file_slot_rows = 2
How do i fix this?.. Will that even work? It would be perfect to do such a button because it would also allow to delete a save from a mobile device. And thank you again for the responses!!

User avatar
Remix
Eileen-Class Veteran
Posts: 1628
Joined: Tue May 30, 2017 6:10 am
Completed: None... yet (as I'm still looking for an artist)
Projects: An un-named anime based trainer game
Contact:

Re: Mapping a "save_delete" action to a gamepad button?

#12 Post by Remix »

just put them both in a fixed or other container, e.g.

Code: Select all

    vbox:
        button: # etc
        textbutton _("Delete") # etc
Might be worth just trying
keysym "pad_x_release" in that button... might work
Frameworks & Scriptlets:

User avatar
tim640
Regular
Posts: 47
Joined: Wed May 23, 2018 4:47 pm
Contact:

Re: Mapping a "save_delete" action to a gamepad button?

#13 Post by tim640 »

Okay, so first of all: i tested the "keysym" parameter on the save slot itself first, and it DOES work with the "FileAction" function, so seeing that i am positive it will work on the textbutton properly! This is incredibly awesome, finally!! I kinda gave up tbh, will remember "keysym" thing for the future as i take it i can map keypad buttons like that to any action if needed, even though individually in each case. Awesomeeeee

...although uh
So okay, here's my full code after editing in one more "vbox" and a textbutton:

Code: Select all

    use game_menu(title):

        fixed:

            ## This ensures the input will get the enter event before any of the
            ## buttons do.
            order_reverse True

            ## The page name, which can be edited by clicking on a button.
            button:
                style "page_label"

                key_events True
                xalign 0.5
                action page_name_value.Toggle()

                input:
                    style "page_label_text"
                    value page_name_value

            ## The grid of file slots.
            grid gui.file_slot_cols gui.file_slot_rows:
                style_prefix "slot"

                xalign 0.5
                yalign 0.5

                spacing gui.slot_spacing

                for i in range(gui.file_slot_cols * gui.file_slot_rows):

                    $ slot = i + 1
                    vbox:
                        button:
                            action FileAction(slot)
                            activate_sound "music/optionsclick.mp3"
                            hover_sound "music/hover.mp3"

                            has vbox

                            add FileScreenshot(slot) xalign 0.5

                            text FileTime(slot, format=_("{size=+15}{#file_time}%A, %B %d %Y, %H:%M{/size}"), empty=_("{size=+15}empty slot{/size}")):
                                style "slot_time_text"

                            text FileSaveName(slot):
                                style "slot_name_text"





                            key "save_delete" action FileDelete(slot)
                           textbutton ("DELETE"):
                                 action FileDelete(slot)
                                 keysym "pad_x_press"



It doesn't cause an exception, however it does kinda crush the whole structure lol
Last edited by tim640 on Tue May 29, 2018 8:16 am, edited 1 time in total.

User avatar
Remix
Eileen-Class Veteran
Posts: 1628
Joined: Tue May 30, 2017 6:10 am
Completed: None... yet (as I'm still looking for an artist)
Projects: An un-named anime based trainer game
Contact:

Re: Mapping a "save_delete" action to a gamepad button?

#14 Post by Remix »

Oops, missed that normal already has a vbox, so maybe:

Option 1:
Remove the extra code bits and use the alternate action...

Code: Select all

                       button:
                            action FileAction(slot)
                            activate_sound "music/optionsclick.mp3"
                            hover_sound "music/hover.mp3"

                            alternate FileDelete(slot)
                            alternate_keysym "pad_x_press"
Which would delete on right-click/android long press/gamepad x or delete key

Option 2:
Try to smuggle in the extra button using normal screen language without messing up the display... likely need a fixed holding the normal parts with an extra mini button [x] for delete hidden in one corner
Frameworks & Scriptlets:

User avatar
tim640
Regular
Posts: 47
Joined: Wed May 23, 2018 4:47 pm
Contact:

Re: Mapping a "save_delete" action to a gamepad button?

#15 Post by tim640 »

The alternate button WORKS. I'll just put this bit into the "controls info" section to clarify it exists and it's going to be enough now. I can't thank you enough, but sending all the hugs all the way from Russia lol
Also, as to a small delete button, also an idea for the future. I guess i can just add it overlay so it'd be ON the file slot over the screenshot of the save, then the grid wouldn't be interrupted i take it, but for now i'll settle down with the "alternate button. As i will finish the main interface, i'll experiment with this and if i'll make it work, i'll post the code here for the ones that might need to realize something like that, too :>

You helped a ton!! Funny thing is now that i read more about the actions in the RenPy documentation, it all seems obvious
I guess i really should've done a better job on reading through these parts. Thank you again!!

Post Reply

Who is online

Users browsing this forum: Bing [Bot]