284 строки
7.6 KiB
TypeScript
284 строки
7.6 KiB
TypeScript
function rpiConfig() {
|
|
// update this string with your arcade cfg if needed
|
|
const arcadeCfg = `
|
|
BTN_RESET=4
|
|
BTN_EXIT=3
|
|
BTN_MENU=2
|
|
BTN_A=26
|
|
BTN_B=19
|
|
BTN_LEFT=13
|
|
BTN_UP=6
|
|
BTN_RIGHT=5
|
|
BTN_DOWN=0
|
|
BTN_A2=11
|
|
BTN_B2=9
|
|
BTN_LEFT2=10
|
|
BTN_UP2=22
|
|
BTN_RIGHT2=27
|
|
BTN_DOWN2=17
|
|
BTN_A3=21
|
|
BTN_B3=20
|
|
BTN_LEFT3=16
|
|
BTN_UP3=12
|
|
BTN_RIGHT3=1
|
|
BTN_DOWN3=7
|
|
BTN_A4=8
|
|
BTN_B4=25
|
|
BTN_LEFT4=24
|
|
BTN_UP4=23
|
|
BTN_RIGHT4=18
|
|
BTN_DOWN4=15
|
|
`;
|
|
|
|
const pCols = [13, 3, 7, 9]
|
|
const bkg = image.create(160, 120);
|
|
bkg.fillRect(0, 10, 160, 66, 7)
|
|
for (let i = 0; i < 4; ++i) {
|
|
bkg.print((2 * i + 1).toString(), 154 - 8 * i, 44, 1);
|
|
bkg.print((2 * i + 2).toString(), 154 - 8 * i, 68, 1);
|
|
}
|
|
for (let i = 0; i < pCols.length; ++i) {
|
|
bkg.print("P" + (i + 1), 80 + i * (image.font8.charWidth * 3), 80, pCols[i]);
|
|
}
|
|
|
|
scene.setBackgroundImage(bkg)
|
|
|
|
const pinImg = img`
|
|
b b b b b b b b
|
|
b c c c c c c b
|
|
b c c c c c c b
|
|
b c c c c c c b
|
|
b c c c c c c b
|
|
b c c c c c c b
|
|
b c c c c c c b
|
|
b b b b b b b b
|
|
`
|
|
const bcmImg = img`
|
|
9 9 9 9 9 9 9 9
|
|
9 c c c c c c 9
|
|
9 c c c c c c 9
|
|
9 c c c c c c 9
|
|
9 c c c c c c 9
|
|
9 c c c c c c 9
|
|
9 c c c c c c 9
|
|
9 9 9 9 9 9 9 9
|
|
`
|
|
const pinSelectedImg = img`
|
|
1 1 1 1 1 1 1 1
|
|
1 5 5 5 5 5 5 1
|
|
1 5 5 5 5 5 5 1
|
|
1 5 5 5 5 5 5 1
|
|
1 5 5 5 5 5 5 1
|
|
1 5 5 5 5 5 5 1
|
|
1 5 5 5 5 5 5 1
|
|
1 1 1 1 1 1 1 1
|
|
`
|
|
const gndPinImg = img`
|
|
d d d d d d d d
|
|
d 1 1 f 1 1 1 d
|
|
d f f f f f 1 d
|
|
d 1 1 1 1 1 1 d
|
|
d 1 f f f 1 1 d
|
|
d 1 1 1 1 1 1 d
|
|
d 1 1 f 1 1 1 d
|
|
d d d d d d d d
|
|
`
|
|
const srcPinImg = img`
|
|
e e e e e e e e
|
|
e 2 2 2 2 2 2 e
|
|
e 2 2 2 f 2 2 e
|
|
e 2 2 2 f 2 2 e
|
|
e 2 f f f f f e
|
|
e 2 2 2 f 2 2 e
|
|
e 2 2 2 f 2 2 e
|
|
e e e e e e e e
|
|
`
|
|
|
|
bkg.drawImage(gndPinImg, 80, 90)
|
|
bkg.print("GND", 90, 90)
|
|
bkg.drawImage(srcPinImg, 80, 100)
|
|
bkg.print("+3.3/5V", 90, 100)
|
|
|
|
// BCM -> pin index
|
|
const bcmToPins: any = {
|
|
2: 3,
|
|
3: 5,
|
|
4: 7,
|
|
17: 11,
|
|
27: 13,
|
|
22: 15,
|
|
10: 19,
|
|
9: 21,
|
|
11: 23,
|
|
0: 27,
|
|
5: 29,
|
|
6: 31,
|
|
13: 33,
|
|
19: 35,
|
|
26: 37,
|
|
14: 8,
|
|
15: 10,
|
|
18: 12,
|
|
23: 16,
|
|
24: 18,
|
|
25: 22,
|
|
8: 24,
|
|
7: 26,
|
|
1: 28,
|
|
12: 32,
|
|
16: 36,
|
|
20: 38,
|
|
21: 40,
|
|
}
|
|
// ground pin indixes
|
|
const gnds = [6, 9, 14, 20, 25, 30, 34, 39];
|
|
const srcs = [1, 17, 2, 4]
|
|
|
|
|
|
let pinout: Sprite[] = []
|
|
for (let i = 0; i < 40; i++) {
|
|
const pin = sprites.create(pinImg.clone(), 0)
|
|
pin.data = {};
|
|
pinout.push(pin)
|
|
pin.left = 160 - ((i >> 1) + 1) * 8
|
|
if (i % 2 == 0) {
|
|
pin.y = 56
|
|
} else {
|
|
pin.y = 64
|
|
}
|
|
|
|
if (gnds.indexOf(pinout.length) > -1)
|
|
pin.setImage(gndPinImg);
|
|
if (srcs.indexOf(pinout.length) > -1)
|
|
pin.setImage(srcPinImg);
|
|
}
|
|
|
|
// parse arcade.cfg, store name in sprites
|
|
for (let line of arcadeCfg.split('\n')) {
|
|
if (line.indexOf("BTN_") != 0) continue;
|
|
const parts = line.substr(4).split('=');
|
|
const name = parts[0];
|
|
const bcm = parseInt(parts[1]);
|
|
const index = bcmToPins[bcm] as number;
|
|
const sprite = pinout[index - 1];
|
|
sprite.data["name"] = name;
|
|
sprite.setImage(bcmImg.clone());
|
|
if (name == "RESET") {
|
|
bkg.print(`RESET ${index}`, 10, 80, 10)
|
|
sprite.setImage(pinImg)
|
|
sprite.setImage(sprite.image.clone())
|
|
sprite.image.replace(0xc, 10);
|
|
}
|
|
else if (name == "EXIT") {
|
|
bkg.print(`EXIT ${index}`, 10, 90, 3)
|
|
sprite.setImage(pinImg)
|
|
sprite.setImage(sprite.image.clone())
|
|
sprite.image.replace(0xc, 3);
|
|
}
|
|
else if (name == "MENU") {
|
|
bkg.print(`MENU ${index}`, 10, 100, 4)
|
|
sprite.setImage(pinImg)
|
|
sprite.setImage(sprite.image.clone())
|
|
sprite.image.replace(0xc, 4);
|
|
} else {
|
|
const i = (parseInt(name[name.length - 1]) || 1) - 1;
|
|
sprite.image.print(name[0], 2, 2, pCols[i], image.font5)
|
|
}
|
|
}
|
|
|
|
// setup menu, reset, select
|
|
|
|
// text sprites
|
|
let buttonName = sprites.create(img`
|
|
. . . . . . . . . . . . . . . .
|
|
. . . . . . . . . . . . . . . .
|
|
. . . . . . . . . b 5 5 b . . .
|
|
. . . . . . b b b b b b . . . .
|
|
. . . . . b b 5 5 5 5 5 b . . .
|
|
. b b b b b 5 5 5 5 5 5 5 b . .
|
|
. b d 5 b 5 5 5 5 5 5 5 5 b . .
|
|
. . b 5 5 b 5 d 1 f 5 d 4 f . .
|
|
. . b d 5 5 b 1 f f 5 4 4 c . .
|
|
b b d b 5 5 5 d f b 4 4 4 4 b .
|
|
b d d c d 5 5 b 5 4 4 4 4 4 4 b
|
|
c d d d c c b 5 5 5 5 5 5 5 b .
|
|
c b d d d d d 5 5 5 5 5 5 5 b .
|
|
. c d d d d d d 5 5 5 5 5 d b .
|
|
. . c b d d d d d 5 5 5 b b . .
|
|
. . . c c c c c c c c b b . . .
|
|
`)
|
|
buttonName.x = 80
|
|
buttonName.y = 36
|
|
buttonName.say("Press buttons for pin INDEX")
|
|
|
|
let lastPress = 0
|
|
let lastKey = ""
|
|
let comboLen = 0
|
|
|
|
const select = (name: string) => {
|
|
const sprite = pinout.filter(pin => pin.data["name"] == name)[0];
|
|
const index = pinout.indexOf(sprite) + 1;
|
|
sprite.image.replace(0xc, 5)
|
|
buttonName.say(`${name} ${index}`, 0);
|
|
lastPress = control.millis()
|
|
if (name == "A") {
|
|
if (lastKey == "B") comboLen++
|
|
else comboLen = 1
|
|
} else if (name == "B") {
|
|
if (lastKey == "A") comboLen++
|
|
else comboLen = 0
|
|
} else {
|
|
comboLen = 0
|
|
}
|
|
if (comboLen >= 6) {
|
|
settings.writeNumber("config-ok", 1)
|
|
control.reset()
|
|
}
|
|
lastKey = name
|
|
}
|
|
const unselect = (name: string) => {
|
|
const sprite = pinout.filter(pin => pin.data["name"] == name)[0];
|
|
sprite.image.replace(5, 0xc)
|
|
buttonName.say("", 0);
|
|
lastPress = control.millis()
|
|
}
|
|
function setup(btn: controller.Button, name: string) {
|
|
btn.onEvent(ControllerButtonEvent.Pressed, function () { select(name) })
|
|
btn.onEvent(ControllerButtonEvent.Released, function () { unselect(name) });
|
|
}
|
|
|
|
game.onUpdateInterval(500, function () {
|
|
if (lastPress && control.millis() - lastPress > 5000) {
|
|
buttonName.say("Press A B A B A B when you're done!", 0);
|
|
lastPress = 0
|
|
}
|
|
})
|
|
|
|
// wire all events
|
|
setup(controller.A, "A");
|
|
setup(controller.B, "B");
|
|
setup(controller.up, "UP");
|
|
setup(controller.down, "DOWN");
|
|
setup(controller.left, "LEFT");
|
|
setup(controller.right, "RIGHT");
|
|
setup(controller.player2.A, "A2");
|
|
setup(controller.player2.B, "B2");
|
|
setup(controller.player2.up, "UP2");
|
|
setup(controller.player2.down, "DOWN2");
|
|
setup(controller.player2.left, "LEFT2");
|
|
setup(controller.player2.right, "RIGHT2");
|
|
setup(controller.player3.A, "A3");
|
|
setup(controller.player3.B, "B3");
|
|
setup(controller.player3.up, "UP3");
|
|
setup(controller.player3.down, "DOWN3");
|
|
setup(controller.player3.left, "LEFT3");
|
|
setup(controller.player3.right, "RIGHT3");
|
|
setup(controller.player4.A, "A4");
|
|
setup(controller.player4.B, "B4");
|
|
setup(controller.player4.up, "UP4");
|
|
setup(controller.player4.down, "DOWN4");
|
|
setup(controller.player4.left, "LEFT4");
|
|
setup(controller.player4.right, "RIGHT4");
|
|
|
|
}
|