RetroPad Editor - create and edit onscreen gamepads

RetroPad Editor

Online tool to create and edit onscreen gamepads for RetroArch.


  1. Import suitable .cfg file (or use default config).

  2. Delete unused overlays.

  3. Add/remove buttons.

  4. Change picture/position.

  5. Save config.

… test, make fixes, test again …

N. Play!


  • Create, move, resize buttons of virtual gamepad.
  • Multiple layers; auto switch orientation for portrait overlays.
  • Generate overlay name (it’s NOT obvious that autorotation works only if overlay names contain ‘landscape’ or ‘portrait’ keyword)
  • Fix overlay aspect ratio (use aspect_ratio parameter).
  • Import image resources in addition to ‘flat’ image set.
  • Scale viewport for comfortable editing on small screens.
  • Display sensitivity range for analog sticks.
  • Duplicate overlay.
  • Raw editor for additional overlay parameters.
  • Support old format (auto normalize integer overlays. does anybody need it?).
  • Support non-fullscreen overlays and ovelayX_rect parameter (also useless things).

Some small help and tips

Bottom sliders for adjusting position and size look a bit awkward but work well. So I decided do not switch to touch-and-drag editing mode as it is not accurate.

“Import-Export” dialog allows to load existing config, additional images (multiple selection available), screenshot sample, and save your work.

“Set screen size” - set display parameters of target device and game viewport size. Actual size in pixels does not matters, only aspect ratio does. Notice that “Rescale to fit editor window” option designed to fit whole editor interface, not just gamepad view.

Config file may contain multiple overlays.

“Create/edit overlay” dialog combines both these functions (do not overload main screen with UI elements)

“Fix aspect ratio” by default shifts buttons to sides (same as RetroArch Auto-Scale Overlay option). And also writes aspect_ratio config parameter, so RetroArch can use it.

"Edit button" dialog

Command, Image, Shape - pretty obvious things but not so simple… Values can be entered manually or selected from list.

Command - contains comprehensive list of commands except keyboard keys (retrok_shift, retrok_q…) and digital-to-right-analog buttons (r_x_minus, r_x_plus, r_y_minus, r_y_plus). Commands can be combined like up|left.

Image - image filename. Additional images can be loaded via Import-Export dialog.

Shape - hitbox shape. Does not affects image. Analog sticks can not have rectangular shape.

Every some_param section is shorthand for overlayX_descY_some_param

next_target - overlay that be selected with overlay_next command. Does nothing with other commands.

range_mod - button hitbox size change on press. This will override same overlay parameter.

alpha_mod - button opacity change on press.

saturate_pct - analog sensitivity. Notice blue circle on screenshot - touch outside it (but inside hitbox) cause 100% tilt of analog. Smaller value - more sharp input.

movable - button can be dragged with finger slide. Applicable only to analog sticks. Regular buttons can not be movable.

Aaaand with some patience you can get an interesting results

Skeuomorphic design. I have no skills in this (assets from Retroarch builtin gamepads).

Weird thing. This is one of few rhythm games playable on touchscreen.

This is not a game. but still…

P.S.: This is just a sligthly edited repost. Only one small fix added to program.

Hope this will be useful


I needed this so much! just finished with one with lots of buttons + 8 layers, dealing with the overlay editor + editing manually on notepad + the windows screen magnifier, is such a mess… your tool is very helpful!

There is any chance to make this offline in case i dont have internet access?

Using this in future overlays, with propper credits to you, thanks so much!

Hi. For offline work you can download repository from github.

Click “code” button then “download zip”. Unpack archive then open index.html in your browser.


Thank you !!!

It’s there a way to make a config where RA automatically changes to a portrait layout when the phone is flipped to portrait?

Where you name the overlays, if they have “landscape” or “portrait” in the name, they should switch to them automatically.

1 Like

It doesn’t work for me at all. They are named “landscape” and “portrait”. The problem is when my phone auto rotates to portrait it just shows the landscape layout scaled smaller, but in portrait.

Does the default neo-retropad overlay rotate properly for you?

Yes it works properly.

This is the config file that I get. I can’t see anything that would make it not work so idk where the problem is.

overlays = 4
overlay0_name = "landscape"
overlay0_full_screen = true
overlay0_normalized = true
overlay0_range_mod = 1.5
overlay0_alpha_mod = 2.0
overlay0_aspect_ratio = 2.2222222
overlay0_descs = 21
overlay0_desc0 = "up,0.11846,0.49581,rect,0.03285,0.073"
overlay0_desc0_overlay = SKLC-Dpad-Up.png
overlay0_desc1 = "down,0.11846,0.74139,rect,0.03285,0.073"
overlay0_desc1_overlay = SKLC-Dpad-Down.png
overlay0_desc2 = "left,0.06359,0.61829,rect,0.03285,0.073"
overlay0_desc2_overlay = SKLC-Dpad-Left.png
overlay0_desc3 = "right,0.17287,0.61829,rect,0.03285,0.073"
overlay0_desc3_overlay = SKLC-Dpad-Right.png
overlay0_desc4 = "a,0.93606,0.61829,radial,0.03285,0.073"
overlay0_desc4_overlay = SKLC-Circle.png
overlay0_desc5 = "b,0.88209,0.74139,radial,0.03285,0.073"
overlay0_desc5_overlay = SKLC-Cross.png
overlay0_desc6 = "x,0.88209,0.49581,radial,0.03285,0.073"
overlay0_desc6_overlay = SKLC-Triangle.png
overlay0_desc7 = "y,0.82684,0.61829,radial,0.03285,0.073"
overlay0_desc7_overlay = SKLC-Square.png
overlay0_desc8 = "start,0.82684,0.3489,radial,0.03195,0.071"
overlay0_desc8_overlay = SKLC-Start.png
overlay0_desc9 = "select,0.17287,0.3489,radial,0.03195,0.071"
overlay0_desc9_overlay = SKLC-Select.png
overlay0_desc10 = "l,0.06359,0.3489,radial,0.03195,0.071"
overlay0_desc10_overlay = SKLC-L1.png
overlay0_desc11 = "l2,0.11846,0.2548,radial,0.03195,0.071"
overlay0_desc11_overlay = SKLC-L2.png
overlay0_desc12 = "r,0.93606,0.3489,radial,0.03195,0.071"
overlay0_desc12_overlay = SKLC-R1.png
overlay0_desc13 = "r2,0.88209,0.2548,radial,0.03195,0.071"
overlay0_desc13_overlay = SKLC-R2.png
overlay0_desc14 = "menu_toggle,0.93606,0.89867,radial,0.03195,0.071"
overlay0_desc14_overlay = SKLC-Menu.png
overlay0_desc15 = "toggle_fast_forward,0.06359,0.89867,radial,0.03195,0.071"
overlay0_desc15_overlay = SKLC-Speed.png
overlay0_desc16 = "left|up,0.05854,0.48449,rect,0.02516,0.05592"
overlay0_desc17 = "left|down,0.05824,0.75306,rect,0.02516,0.05592"
overlay0_desc18 = "right|up,0.17844,0.48449,rect,0.02516,0.05592"
overlay0_desc19 = "right|down,0.17943,0.75292,rect,0.02516,0.05592"
overlay0_desc20 = "overlay_next,0.82684,0.89867,radial,0.03195,0.071"
overlay0_desc20_overlay = SKLC-AnalogToggle.png
overlay0_desc20_next_target = "landscape-analog"
overlay1_name = "portrait"
overlay1_full_screen = true
overlay1_normalized = true
overlay1_range_mod = 1.5
overlay1_alpha_mod = 2.0
overlay1_aspect_ratio = 0.45
overlay1_descs = 21
overlay1_desc0 = "left,0.11373,0.78565,rect,0.073,0.03285"
overlay1_desc0_overlay = SKLC-Dpad-Left.png
overlay1_desc1 = "right,0.35942,0.78565,rect,0.073,0.03285"
overlay1_desc1_overlay = SKLC-Dpad-Right.png
overlay1_desc2 = "up,0.23709,0.73124,rect,0.073,0.03285"
overlay1_desc2_overlay = SKLC-Dpad-Up.png
overlay1_desc3 = "down,0.23709,0.84136,rect,0.073,0.03285"
overlay1_desc3_overlay = SKLC-Dpad-Down.png
overlay1_desc4 = "left|up,0.10107,0.7252,rect,0.0537,0.02416"
overlay1_desc5 = "right|up,0.37286,0.7252,rect,0.0537,0.02416"
overlay1_desc6 = "left|down,0.10107,0.84536,rect,0.0537,0.02416"
overlay1_desc7 = "right|down,0.37286,0.84536,rect,0.05370,0.02416"
overlay1_desc8 = "a,0.87829,0.78565,radial,0.073,0.03285"
overlay1_desc8_overlay = SKLC-Circle.png
overlay1_desc9 = "b,0.75668,0.84136,radial,0.073,0.03285"
overlay1_desc9_overlay = SKLC-Cross.png
overlay1_desc10 = "x,0.75668,0.73124,radial,0.073,0.03285"
overlay1_desc10_overlay = SKLC-Triangle.png
overlay1_desc11 = "y,0.63416,0.78565,radial,0.073,0.03285"
overlay1_desc11_overlay = SKLC-Square.png
overlay1_desc12 = "start,0.63416,0.65742,radial,0.071,0.03195"
overlay1_desc12_overlay = SKLC-Start.png
overlay1_desc13 = "select,0.35942,0.65742,radial,0.071,0.03195"
overlay1_desc13_overlay = SKLC-Select.png
overlay1_desc14 = "l,0.11373,0.65742,radial,0.071,0.03195"
overlay1_desc14_overlay = SKLC-L1.png
overlay1_desc15 = "l2,0.23709,0.61401,radial,0.071,0.03195"
overlay1_desc15_overlay = SKLC-L2.png
overlay1_desc16 = "r2,0.75292,0.61401,radial,0.071,0.03195"
overlay1_desc16_overlay = SKLC-R2.png
overlay1_desc17 = "r,0.87829,0.65742,radial,0.071,0.03195"
overlay1_desc17_overlay = SKLC-R1.png
overlay1_desc18 = "menu_toggle,0.87829,0.9119,radial,0.05787,0.02604"
overlay1_desc18_overlay = SKLC-Menu.png
overlay1_desc19 = "toggle_fast_forward,0.11373,0.9119,radial,0.05787,0.02604"
overlay1_desc19_overlay = SKLC-Speed.png
overlay1_desc20 = "overlay_next,0.63416,0.9119,radial,0.05787,0.02604"
overlay1_desc20_overlay = SKLC-AnalogToggle.png
overlay1_desc20_next_target = "portrait-analog"
overlay2_name = "landscape-analog"
overlay2_full_screen = true
overlay2_normalized = true
overlay2_range_mod = 1.5
overlay2_alpha_mod = 2.0
overlay2_aspect_ratio = 2.2222222
overlay2_descs = 15
overlay2_desc0 = "a,0.93606,0.61829,radial,0.03285,0.073"
overlay2_desc0_overlay = SKLC-Circle.png
overlay2_desc1 = "b,0.88209,0.74139,radial,0.03285,0.073"
overlay2_desc1_overlay = SKLC-Cross.png
overlay2_desc2 = "x,0.88209,0.49581,radial,0.03285,0.073"
overlay2_desc2_overlay = SKLC-Triangle.png
overlay2_desc3 = "y,0.82684,0.61829,radial,0.03285,0.073"
overlay2_desc3_overlay = SKLC-Square.png
overlay2_desc4 = "start,0.82684,0.3489,radial,0.03195,0.071"
overlay2_desc4_overlay = SKLC-Start.png
overlay2_desc5 = "select,0.17287,0.3489,radial,0.03195,0.071"
overlay2_desc5_overlay = SKLC-Select.png
overlay2_desc6 = "l,0.06359,0.3489,radial,0.03195,0.071"
overlay2_desc6_overlay = SKLC-L1.png
overlay2_desc7 = "l2,0.11846,0.2548,radial,0.03195,0.071"
overlay2_desc7_overlay = SKLC-L2.png
overlay2_desc8 = "r,0.93606,0.3489,radial,0.03195,0.071"
overlay2_desc8_overlay = SKLC-R1.png
overlay2_desc9 = "r2,0.88209,0.2548,radial,0.03195,0.071"
overlay2_desc9_overlay = SKLC-R2.png
overlay2_desc10 = "menu_toggle,0.93606,0.89867,radial,0.03195,0.071"
overlay2_desc10_overlay = SKLC-Menu.png
overlay2_desc11 = "toggle_fast_forward,0.06359,0.89867,radial,0.03195,0.071"
overlay2_desc11_overlay = SKLC-Speed.png
overlay2_desc12 = "overlay_next,0.82684,0.89867,radial,0.03195,0.071"
overlay2_desc12_overlay = SKLC-AnalogToggleOn.png
overlay2_desc12_next_target = "landscape"
overlay2_desc13 = "null,0.11804,0.62076,radial,0.07435,0.16522"
overlay2_desc13_overlay = SKLC-AnalogBorder.png
overlay2_desc14 = "analog_left,0.11732,0.62076,radial,0.05560,0.12356"
overlay2_desc14_overlay = SKLC-Analog.png
overlay2_desc14_range_mod = 2.0
overlay2_desc14_saturate_pct = 0.8
overlay2_desc14_movable = true
overlay3_name = "portrait-analog"
overlay3_full_screen = true
overlay3_normalized = true
overlay3_range_mod = 1.5
overlay3_alpha_mod = 2.0
overlay3_aspect_ratio = 0.45
overlay3_descs = 15
overlay3_desc0 = "a,0.87829,0.78565,radial,0.073,0.03285"
overlay3_desc0_overlay = SKLC-Circle.png
overlay3_desc1 = "b,0.75668,0.84136,radial,0.073,0.03285"
overlay3_desc1_overlay = SKLC-Cross.png
overlay3_desc2 = "x,0.75668,0.73124,radial,0.073,0.03285"
overlay3_desc2_overlay = SKLC-Triangle.png
overlay3_desc3 = "y,0.63416,0.78565,radial,0.073,0.03285"
overlay3_desc3_overlay = SKLC-Square.png
overlay3_desc4 = "start,0.63416,0.65742,radial,0.071,0.03195"
overlay3_desc4_overlay = SKLC-Start.png
overlay3_desc5 = "select,0.35942,0.65742,radial,0.071,0.03195"
overlay3_desc5_overlay = SKLC-Select.png
overlay3_desc6 = "l,0.11373,0.65742,radial,0.071,0.03195"
overlay3_desc6_overlay = SKLC-L1.png
overlay3_desc7 = "l2,0.23709,0.61401,radial,0.071,0.03195"
overlay3_desc7_overlay = SKLC-L2.png
overlay3_desc8 = "r2,0.75292,0.61401,radial,0.071,0.03195"
overlay3_desc8_overlay = SKLC-R2.png
overlay3_desc9 = "r,0.87829,0.65742,radial,0.071,0.03195"
overlay3_desc9_overlay = SKLC-R1.png
overlay3_desc10 = "menu_toggle,0.87829,0.9119,radial,0.05787,0.02604"
overlay3_desc10_overlay = SKLC-Menu.png
overlay3_desc11 = "toggle_fast_forward,0.11373,0.9119,radial,0.05787,0.02604"
overlay3_desc11_overlay = SKLC-Speed.png
overlay3_desc12 = "overlay_next,0.63416,0.9119,radial,0.05787,0.02604"
overlay3_desc12_overlay = SKLC-AnalogToggleOn.png
overlay3_desc12_next_target = "portrait"
overlay3_desc13 = "null,0.23709,0.78565,radial,0.16522,0.07435"
overlay3_desc13_overlay = SKLC-AnalogBorder.png
overlay3_desc14 = "analog_left,0.23709,0.78565,radial,0.12356,0.0556"
overlay3_desc14_overlay = SKLC-Analog.png
overlay3_desc14_range_mod = 2.0
overlay3_desc14_saturate_pct = 0.8
overlay3_desc14_movable = true

Ah, that’s your issue, then: there’s no portrait version in that cfg, just the landscape one.

Hm but how?

What about this part though?

overlay1_name = "portrait"
overlay1_full_screen = true
overlay1_normalized = true
overlay1_range_mod = 1.5
overlay1_alpha_mod = 2.0
overlay1_aspect_ratio = 0.45

oh whoops, it wasn’t scrolling when I looked at it before lol! my mistake!

ok, so it looks like you’re missing the one other necessary bit for autorotation: you need a button to go to the rotated overlay. It doesn’t have to be big (it can be as small as 1 pixel or even off-screen, I think), it just has to exist.

So, just like you have overlay0_desc20, just make a desc21 that points to the “portrait” overlay and tuck it away somewhere where you won’t hit it accidentally, and then do the same for portrait -> landscape.


Ok, that finally worked! Tyvm!

1 Like

w00t, yeah, I had forgotten about that part. That’s the problem with this kind of automagic stuff…

1 Like

can negative values be used for x/y positioning to place this marker off-screen?

I believe so. I haven’t tested that myself, but I think it should work, yeah. If that doesn’t work, you can probably just go the other way. That is, >1.

1 Like

placing it @ 0,0 worked just great!

1 Like

Negative values are supported in RetroArch. Some builtin overlays using this to hide switch-buttons. Tick “Show offscreen” checkbox to reveal those buttons (sometimes requires small screen size).

Slider range is 0…1 in editor but values can also be entered manually in corresponding fields.


Thank you! I’m gonna use that.

BTW Do you happen to know what does these commands/inputs do ? (Found it on one of the default portrait overlays)

overlay0_block_y_separation = true
overlay0_block_x_separation = false