-
-
Save Jimmy-Z/3aa5b83c6bc33bc6065ed5087de787be to your computer and use it in GitHub Desktop.
RetroArch input overlay for gameboy on 2160*1080 phone
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict"; | |
const writeFile = require("fs").writeFileSync | |
// from gamepads/flat | |
const image_dir = "assets" | |
const image_map = { | |
"up": "dpad-up_psx_no-mark", | |
"down": "dpad-down_psx_no-mark", | |
"left": "dpad-left_psx_no-mark", | |
"right": "dpad-right_psx_no-mark", | |
"a": "A", | |
"b": "B", | |
} | |
// vp_w/h: viewpoint size, w/h: core canvas size | |
function write_gb(name, vp_w, vp_h, w, h, la){ | |
const headers = [ | |
"overlays = 1", | |
"overlay0_full_screen = true", | |
"overlay0_normalized = true", | |
"overlay0_alpha_mod = 2.0", | |
]; | |
let n_descs = 0; | |
const descs = []; | |
// dpad | |
function addBtn(img, x, y, shape, rx, ry, key){ | |
// normalized = false is not working for me | |
// descs.push(`overlay0_desc${id} = "${key},${x},${y},${shape},${rx},${ry}"`); | |
descs.push(`overlay0_desc${n_descs} = "${key},${x/vp_w},${y/vp_h},${shape},${rx/vp_w},${ry/vp_h}"`); | |
if (img !== false){ | |
// descs.push(`overlay0_desc${n_descs}_overlay = ${images[img]}`); | |
if (img == true){ | |
img = key; | |
const mapped = image_map[img]; | |
if (mapped !== undefined){ | |
img = mapped | |
} | |
} | |
descs.push(`overlay0_desc${n_descs}_overlay = ${image_dir}/${img}.png`); | |
} | |
++n_descs; | |
} | |
// integer scale | |
const scale = Math.min(Math.floor(vp_w / w), Math.floor(vp_h / h)) | |
const scaled_w = w * scale | |
const scaled_h = h * scale | |
console.error(`scale = ${scale}`) | |
console.error(`scaled width = ${scaled_w}`) | |
console.error(`scaled height = ${scaled_h}`) | |
// assume landscape centered canvas | |
const border_w = (vp_w - scaled_w) / 2 | |
console.error(`border width = ${border_w}`) | |
// margin for image, the actual hit box covers the entire border | |
const d_pad_margin = border_w / 8 / 2 | |
// btn center distance | |
const d_pad_center_radius = border_w / 32 / 2 | |
// up/down btn image height, the left/right width | |
const d_pad_img_h = border_w / 2 - d_pad_margin - d_pad_center_radius | |
// the btn image resolution is very strange | |
const d_pad_img_w = d_pad_img_h * 74 / 86; | |
// width of up btn / width of entire d pad (AKA border width) | |
const d_pad_ratio = 1 / 3; | |
const d_pad_btn_w = border_w * d_pad_ratio | |
// height/width of the diagonal hit box, also height of compliment hit box for up/down btn | |
const d_pad_btn_h = border_w * (1 - d_pad_ratio) / 2 | |
// radial hit box with image | |
addBtn(true, border_w/2, vp_h/2-d_pad_center_radius-d_pad_img_h/2, "radial", d_pad_img_w/2, d_pad_img_h/2, "up"); | |
addBtn(true, border_w/2, vp_h/2+d_pad_center_radius+d_pad_img_h/2, "radial", d_pad_img_w/2, d_pad_img_h/2, "down"); | |
addBtn(true, border_w/2-d_pad_center_radius-d_pad_img_h/2, vp_h/2, "radial", d_pad_img_h/2, d_pad_img_w/2, "left"); | |
addBtn(true, border_w/2+d_pad_center_radius+d_pad_img_h/2, vp_h/2, "radial", d_pad_img_h/2, d_pad_img_w/2, "right"); | |
// complimentary rect hit box | |
addBtn(false, border_w/2, vp_h/2-d_pad_btn_w/2-d_pad_btn_h/2, "rect", d_pad_btn_w/2, d_pad_btn_h/2, "up"); | |
addBtn(false, border_w/2, vp_h/2+d_pad_btn_w/2+d_pad_btn_h/2, "rect", d_pad_btn_w/2, d_pad_btn_h/2, "down"); | |
addBtn(false, border_w/2-d_pad_btn_w/2-d_pad_btn_h/2, vp_h/2, "rect", d_pad_btn_h/2, d_pad_btn_w/2, "left"); | |
addBtn(false, border_w/2+d_pad_btn_w/2+d_pad_btn_h/2, vp_h/2, "rect", d_pad_btn_h/2, d_pad_btn_w/2, "right"); | |
// diagonal hit box | |
addBtn(false, d_pad_btn_h/2, vp_h/2-d_pad_btn_w/2-d_pad_btn_h/2, "rect", d_pad_btn_h/2, d_pad_btn_h/2, "left|up"); | |
addBtn(false, border_w-d_pad_btn_h/2, vp_h/2-d_pad_btn_w/2-d_pad_btn_h/2, "rect", d_pad_btn_h/2, d_pad_btn_h/2, "right|up"); | |
addBtn(false, d_pad_btn_h/2, vp_h/2+d_pad_btn_w/2+d_pad_btn_h/2, "rect", d_pad_btn_h/2, d_pad_btn_h/2, "left|down"); | |
addBtn(false, border_w-d_pad_btn_h/2, vp_h/2+d_pad_btn_w/2+d_pad_btn_h/2, "rect", d_pad_btn_h/2, d_pad_btn_h/2, "right|down"); | |
// a/b btn | |
const ab_dist_x = border_w / 2; | |
const ab_dist_y = ab_dist_x / 3; | |
const ab_radius = Math.sqrt(ab_dist_x * ab_dist_x + ab_dist_y * ab_dist_y) * 2 / 5; | |
addBtn(true, vp_w-border_w/2+ab_dist_x/2, vp_h/2-ab_dist_y/2, "radial", ab_radius, ab_radius, "a"); | |
addBtn(true, vp_w-border_w/2-ab_dist_x/2, vp_h/2+ab_dist_y/2, "radial", ab_radius, ab_radius, "b"); | |
// hit box for a+b | |
const ab_both_radius = ab_radius / 2; | |
addBtn(false, vp_w-border_w/2, vp_h/2, "radial", ab_both_radius, ab_both_radius, "a|b"); | |
// use corners of core canvas (+ up/down border) for menu/abss/select/start | |
const scr_btn_margin = vp_h / 24; | |
addBtn(false, border_w+scaled_w/6, vp_h/6, "rect", scaled_w/6-scr_btn_margin, vp_h/6-scr_btn_margin, "menu_toggle"); | |
addBtn(false, vp_w-border_w-scaled_w/6, vp_h/6, "rect", scaled_w/6-scr_btn_margin, vp_h/6-scr_btn_margin, la ? "a|b|start|select" : "toggle_fast_forward"); | |
addBtn(false, border_w+scaled_w/6, vp_h*5/6, "rect", scaled_w/6-scr_btn_margin, vp_h/6-scr_btn_margin, "select"); | |
addBtn(false, vp_w-border_w-scaled_w/6, vp_h*5/6, "rect", scaled_w/6-scr_btn_margin, vp_h/6-scr_btn_margin, "start"); | |
writeFile(`${name}.cfg`, | |
headers.join("\n") + `\noverlay0_descs = ${n_descs}\n` + descs.join("\n") + "\n", | |
{encoding: "ascii"}) | |
} | |
write_gb("gameboy-landscape-2160x1080", 2160, 1080, 160, 144, false); | |
write_gb("gameboy-landscape-la-2160x1080", 2160, 1080, 160, 144, true); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment