• Recent
  • Tags
  • Popular
  • Home
  • Docs
  • Register
  • Login
RetroPie forum home
  • Recent
  • Tags
  • Popular
  • Home
  • Docs
  • Register
  • Login
Please do not post a support request without first reading and following the advice in https://retropie.org.uk/forum/topic/3/read-this-first

[Solved] How to bind a shell command to a hotkey? (raspi2png)

Scheduled Pinned Locked Moved Help and Support
hotkeyshortcutscreenshotraspi2png
59 Posts 6 Posters 11.6k Views
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C
    Clyde
    last edited by Clyde 7 Feb 2019, 06:47

    Hi,

    this was asked some time ago, but I thought maybe someone knows another way than using xboxdrv, since I don't use it and I would prefer a way that includes keyboard shortcuts.

    I'm looking for a way to assign a hotkey that runs raspi2png to make a screenshot having to use remote access or sleep.

    It should work without needing an xserver.

    Any ideas? Thanks!

    Clyde

    edit: A step-by-step How-To for raspi2png.

    1 Reply Last reply Reply Quote 0
    • M
      mitu Global Moderator
      last edited by 7 Feb 2019, 07:18

      If you have a keyboard, you can use the 'triggerhappy' program (https://github.com/wertarbyte/triggerhappy) - I think it's already included and started up in the default Raspbian image. Should be easy to configure to have something like AltGr+Prn to run raspi2png with some parameters.

      1 Reply Last reply Reply Quote 0
      • H
        hermit
        last edited by 7 Feb 2019, 16:47

        would it be possible to pass the variable % ROM% to raspi2png to create a file with the name of the rom? thank you

        1 Reply Last reply Reply Quote 0
        • L
          Lolonois
          last edited by 15 Feb 2019, 18:47

          @hermit triggerhappy is not related to retropie. AFAIK %ROM% or $ROM is not available from the environment. However, to get the rom file name you may start with

          basename `ps a | grep RetroPie/roms | head -1 | awk '{ print $NF }'`
          

          Without a physical keyboard attached the tool jslisten may be an option.

          C 1 Reply Last reply 24 Feb 2019, 17:30 Reply Quote 1
          • H
            hermit
            last edited by 15 Feb 2019, 19:10

            This post is deleted!
            1 Reply Last reply Reply Quote 0
            • H
              hermit
              last edited by 15 Feb 2019, 19:15

              @Lolonois I'm sorry I did not understand ... can you give me an example?
              I launched the command but it does not work
              ./raspi2png basename ps a | grep RetroPie / roms | head -1 | awk '{print $ NF}'

              M 1 Reply Last reply 15 Feb 2019, 19:29 Reply Quote 0
              • M
                mitu Global Moderator @hermit
                last edited by mitu 15 Feb 2019, 19:29

                The command @Lolonois posted would get the name of the currently playing ROM, which you can then save in a variable to be used instead of %ROM%. If you're not running any game, then the command might return an empty string.

                L 1 Reply Last reply 16 Feb 2019, 00:21 Reply Quote 0
                • L
                  Lolonois @mitu
                  last edited by 16 Feb 2019, 00:21

                  @mitu Thanks for jumping in.
                  @hermit It was a brief example to extract the rom name when a rom is in use/in play.
                  You can decompose my hint into the different commands and make yourself familiar with them (same for the bash pipe | and bash backtick ` operator). Then put the commands again together with the pipe symbol one-after-another and view the results each time you added a pipe.

                  FYI in my raspi2png I have to use --pngname to give the screenshot a different name, can judge if you have a different version than me.

                  1 Reply Last reply Reply Quote 0
                  • H
                    hermit
                    last edited by hermit 16 Feb 2019, 08:56

                    @Lolonois I meant an example of the complete command
                    ./raspi2png --prgname and then what should I write?
                    launching the following command, create a file (PNG) only with the name BASENAME
                    ./raspi2png --pngname basename ps a | grep RetroPie/roms | head -1 | awk '{ print $NF }'

                    Excuse me, but I do not know these commands

                    p.s. of course a game is started (super mario world 2 snes)

                    edit:
                    if I write the command like this, it creates a file with the name B1W7RX ~ O.PNG

                    ./raspi2png --pngname basename+`ps a|grep RetroPie/roms/|head -1|awk '{ print $NF }'`+.png
                    
                    1 Reply Last reply Reply Quote 0
                    • C
                      Clyde
                      last edited by 16 Feb 2019, 11:55

                      @mitu Sorry about the late answer, I don't have much time at the moment. I'll look into triggerhappy this weekend.

                      @hermit You'll have to put @Lolonois' commands in brackets following a $ and remove the two + after basename and before .png:

                      ./raspi2png --pngname $(basename `ps a|grep RetroPie/roms/|head -1|awk '{ print $NF }'`).png
                      

                      This will creat a screenshot called gamename.ext.png, e.g. gorf.zip.png. If you want to remove the zip extension, add -s .zip as an option to basename:

                      ./raspi2png --pngname $(basename -s .zip `ps a|grep RetroPie/roms/|head -1|awk '{ print $NF }'`).png
                      
                      1 Reply Last reply Reply Quote 1
                      • H
                        hermit
                        last edited by 16 Feb 2019, 13:04

                        thank you all, but I give up
                        the only result was a file with a type name: _NCE72 ~ 2.PNG

                        C 1 Reply Last reply 16 Feb 2019, 13:36 Reply Quote 0
                        • C
                          Clyde @hermit
                          last edited by 16 Feb 2019, 13:36

                          @hermit It seems like this method has problems with spaces in the filename, because awk will treat them as field separators, and thus handing over only the part of the filename after the last space in it (I think, as I'm not very experienced in awk).

                          Could you test it with a rom filename without spaces?

                          H 1 Reply Last reply 16 Feb 2019, 13:54 Reply Quote 0
                          • H
                            hermit @Clyde
                            last edited by 16 Feb 2019, 13:54

                            @Clyde Could you test it with a rom filename without spaces?

                            yes :)
                            I have rename "Super Mario World 2 - Yoshi's Island (Europe) (En,Fr,De) (Rev 1).zip" in 000super_mario_world2.zip and the result was: 000super_mario_world2.png

                            but normally the roms have spaces ... :(

                            C 1 Reply Last reply 16 Feb 2019, 15:13 Reply Quote 0
                            • C
                              Clyde @hermit
                              last edited by Clyde 16 Feb 2019, 15:13

                              @hermit My dirty hack solution after some reading:

                              raspi2png --pngname $(basename -s .zip `ps a|grep RetroPie/roms/|head -1|sed -e 's/ /_/g'|awk '{ print $NF }'|sed 's/\\\//g'`).png
                              

                              I inserted the command sed -e 's/ /_/g' before awk to convert any whitespace to an underscore, and a sed 's/\\\//g' after awk to remove any \ which the Linux shell uses to mark special characters like whitespaces,', (, ) etc.

                              I did it this way because awk seems to have problems with whitespaces (thus sed removes them beforehand), but also needs the backslash before special characters (thus sed removes them only afterwards).

                              I sometimes can't let unsolved problems just go … although I now have to hurry cleaning up my flat before going to a party. 😌

                              edit: See @mitu's optimised version with whitespace-passthrough and multiple filename extensions support here.

                              1 Reply Last reply Reply Quote 0
                              • H
                                hermit
                                last edited by 16 Feb 2019, 15:22

                                @Clyde perfect :) tested with both snes and amiga :) Thanks a lot :)

                                thank you all :)

                                1 Reply Last reply Reply Quote 0
                                • C
                                  Clyde
                                  last edited by Clyde 23 Feb 2019, 12:33

                                  Okay, I finally got around working on this. Here's my tested solution:

                                  1. Install triggerhappy:
                                  sudo apt install triggerhappy
                                  
                                  1. Change its service configuration file using sed to run it as user pi for writing permissions in that user's $HOME directory (optional, but needed for the example below):
                                  sudo sed -i -e 's/nobody/pi/' /etc/systemd/system/multi-user.target.wants/triggerhappy.service
                                  
                                  1. Use thd to find the code of the key you want to connect a shell command to:
                                  thd --dump /dev/input/*      # exit with CTRL+C
                                  
                                  1. Put the code and the desired shell command into a fittingly named file in the directory /etc/triggerhappy/triggers.d/
                                    Example: Running the raspi2png command from above on the press of "Print Screen", using the config file /etc/triggerhappy/triggers.d/raspi2png.conf:
                                  KEY_SYSRQ 1 raspi2png --pngname "/home/pi/$(ps a | grep RetroPie/roms | awk -F "/" 'NR==1 { print $NF }' | sed 's/\.[^.]*$//g; s/\\//g')"-$(date +%Y.%m.%d-%H.%M.%S).png
                                  
                                  • KEY_SYSRQ is the code for the "Print Screen" key on most standard keyboards.
                                  • "1" = pressing the key, "2" = holding the key down, "0" = releasing the key
                                  • The rest is the command or script to run in this event. You may have to add the path to your raspi2png if it's not in your shell's search path like /home/pi/bin is for example.
                                  • Optional: Put the command in a shell script and run the script from the .conf file. See @roslofs post below. This may be advisable for multiple commands or if you change them from time to time, sparing you the reloading of the demon (see #4).
                                  1. Reload the service to apply the changes:
                                  sudo systemctl daemon-reload                 # reload the changes in triggerhappy.service
                                  sudo systemctl restart triggerhappy.service  # reload the changes in /etc/triggerhappy/triggers.d/
                                  

                                  Now, in the above example, pressing "Print Screen" should save a screenshot named after the currently running ROM file in the directory /home/pi/.

                                  Comments, test results, corrections, and enhancements are welcome. :)

                                  edit: You can check the status and any error messages of the triggerhappy daemon with the command sudo systemctl status triggerhappy.service.
                                  edit 2: Changed the raspi2png command to @mitu's optimised version.
                                  edit 3: Added @mitu's correction and @roslofs script variant.

                                  M 1 Reply Last reply 23 Feb 2019, 12:58 Reply Quote 3
                                  • C
                                    Clyde
                                    last edited by 23 Feb 2019, 12:40

                                    Credits go to @mitu, @Zigurana, @Djon, and @Headrush69 for their groundwork in https://retropie.org.uk/forum/topic/2377/control-volume-through-retroarch-with-keyboard and https://retropie.org.uk/forum/topic/18133/triggerhappy-daemon-thd-doesn-t-work-on-my-pi-running-retropie-help.

                                    1 Reply Last reply Reply Quote 0
                                    • M
                                      mitu Global Moderator @Clyde
                                      last edited by mitu 23 Feb 2019, 12:58

                                      @Clyde Hey, you got it working - great stuff !

                                      Now, the suggestions :) :

                                      • You can probably replace the long line of
                                      `ps a|grep RetroPie/roms/|head -1|sed -e 's/ /_/g'|awk '{ print $NF }'|sed 's/\\\//g'`
                                      

                                      with something like

                                      ps a | grep RetroPie/roms | head -1 | awk -F "/" '{ print $NF }'
                                      

                                      This will get you the last path segment (which can be a file or folder) from the line containing the ROM path.

                                      EDIT: this will also preserve whitespaces in the filename, so it's not a drop-in replacement for the original command.

                                      • You're assuming the ROM is a .zip, but that not might be the case. Can't think of a simple and elegant way of dealing with this but I have an idea.
                                      C 1 Reply Last reply 23 Feb 2019, 13:06 Reply Quote 2
                                      • C
                                        Clyde @mitu
                                        last edited by Clyde 23 Feb 2019, 13:06

                                        @mitu I already played around with awk -F but I got no good results.

                                        raspi2png --pngname /home/pi/$(basename -s .zip `ps a | grep RetroPie/roms/ | head -1 | awk -F "/" '{ print $NF }'`).png
                                        

                                        will save a file called 7th\, whereas my command will save 7th_Saga,_The_(USA).png.

                                        edit: I gave up on preserving the whitespaces. :)
                                        edit 2: Have to leave for the gym now. I'm curious about your idea about the rom's filename extension.

                                        1 Reply Last reply Reply Quote 0
                                        • M
                                          mitu Global Moderator
                                          last edited by mitu 23 Feb 2019, 17:00

                                          If you don't quote your argument, spaces will surely be a problem. Anyway, here it is what I got so far.

                                          raspi2png --pngname "$(ps a | grep RetroPie/roms | awk -F "/" 'NR==1 { print $NF }' | sed 's/\.[^.]*$//g')"-$(date +%Y.%m.%d-%H.%M.%S).png
                                          

                                          This should work with spaces, regardless of extension, and adds a timestamp at the end. If you'd like to keep the date format the way RetroArch does it, you can use:

                                          raspi2png --pngname "$(ps a | grep RetroPie/roms | awk -F "/" 'NR==1 { print $NF }' | sed 's/\.[^.]*$//g')"-$(date +%y%m%d-%H%M%S).png
                                          

                                          Now, the RetroArch reference got me thinking, so I checked and you can tell RA to take a screenshot with the Network control interface - https://docs.libretro.com/tech/network-control-interface/. Assuming you got RA configured to start this interface (I don't think it's enabled by default, I just have it for the power off/reset buttons), the command to take a screenshot can be just

                                          echo -n "SCREENSHOT" | nc -u -w1 127.0.0.1 55355
                                          

                                          and a screenshot would be saved in ~/.config/retroarch/screenshots (a.k.a. /opt/retropie/configs/all/retroarch/screenshots or \\retropie\configs\all\retroarch\screenshots). You'll need netcat installed to provide the nc command.

                                          C 1 Reply Last reply 23 Feb 2019, 17:18 Reply Quote 1
                                          • First post
                                            Last post

                                          Contributions to the project are always appreciated, so if you would like to support us with a donation you can do so here.

                                          Hosting provided by Mythic-Beasts. See the Hosting Information page for more information.

                                            This community forum collects and processes your personal information.
                                            consent.not_received