|
Joined: Aug 2008
Posts: 24
Member
|
Member
Joined: Aug 2008
Posts: 24 |
I somehow integrate this to work with my 2 screen setup (1 is for the marquees).
I have to ask though, could there be a way to make this work with other systems? Gameboy, game gear, master system, megadrive, ...?
I'm sure there's no one size fits all but I'd like to see this as a feature, if at all possible, at some point because it's really cool.
Anyway, thanks and thanks to the whole team as well.
|
|
|
|
Joined: Feb 2014
Posts: 1,124 Likes: 193
Very Senior Member
|
Very Senior Member
Joined: Feb 2014
Posts: 1,124 Likes: 193 |
It should be possible to do this for any system because the input system works in the same way.
so for instance, looking at genesis, to get the list of ports:
function printt(t) for i,j in pairs(t) do print (i,j) end end printt(manager.machine.ioport.ports)
:RESET sol.ioport_port*: 0x564f7ec6e7d8 :ctrl1:mdpad:PAD sol.ioport_port*: 0x564f7ec202c8 :ctrl2:mdpad:PAD sol.ioport_port*: 0x564f7ecfc988
then get the fields:
printt(manager.machine.ioport.ports[":ctrl1:mdpad:PAD"].fields) P1 B sol.ioport_field*: 0x564f7ec3fff8 %p B sol.ioport_field*: 0x564f7ec46198 %p A sol.ioport_field*: 0x564f7ec56848 P1 Right sol.ioport_field*: 0x564f7ec2b2b8 P1 Up sol.ioport_field*: 0x564f7ecfc988 P1 A sol.ioport_field*: 0x564f7ec202c8 P1 Start sol.ioport_field*: 0x564f7ec41338 %p C sol.ioport_field*: 0x564f7ec567f8 P1 C sol.ioport_field*: 0x564f7ec5a1d8 P1 Down sol.ioport_field*: 0x564f7f703e88 P1 Left sol.ioport_field*: 0x564f7ec60e08
and then look at the mask:
for i,j in pairs(manager.machine.ioport.ports[":ctrl1:mdpad:PAD"].fields) do print(i, j.mask) end P1 Down 2 P1 C 32 P1 Left 4 P1 Up 1 P1 B 16 %p A 64 %p C 32 %p B 16 P1 Start 128 P1 Right 8 P1 A 64
Last edited by Golden Child; 11/01/23 06:41 PM.
|
|
|
|
Joined: Aug 2008
Posts: 24
Member
|
Member
Joined: Aug 2008
Posts: 24 |
EDIT: Corrected 1 problem, got another Turns out it was a misplaced /n No more errors but I can't see the text on the buttons, still. /edit I'm probably doing something stupid as it is my 1st time looking at LUA but I have trouble making this work for the genesis. I can see the layout but the boxes are not filled with the text. They change to red in the correct positions when I press the buttons too, so I'm assuming the pad is detected correctly. The error is in line 13 on this .lua script The error is: "attempt to index a nil value (field ':screen')" and line 13 would be "manager.machine.screens[":screen"]:draw_box(buttonpos[i][1],buttonpos[i][2],buttonpos[i][1]+20,buttonpos[i][2]+20," For the sake of debug I removed the " manager.machine.screens[":screen"]" and then the error moves to draw_boxfunction iifnot0(a,b,c) if a~=0 then return b else return c end end
displayoverlay=true originx,originy=50,170 alphavalue=0.5
function drawoverlay() dpadx,dpady = 50,originy padx,pady = 30,30 cposx,cposy = 120,originy rposx,rposy = 190,originy buttons = {up = 1, down = 2, left = 4, right = 8, b = 16, c = 32, a = 64, start = 128} buttonpos = {up = {dpadx, dpady-pady}, down = {dpadx,dpady+pady}, right = {dpadx+padx, dpady}, left={dpadx-padx, dpady}, c={cposx, cposy}, start={cposx+padx, cposy}, b={rposx,rposy}, a={rposx+padx, rposy}} if displayoverlay==true then for i,j in pairs(buttons) do manager.machine.screens[":screen"]:draw_box(buttonpos[i][1],buttonpos[i][2],buttonpos[i][1]+20,buttonpos[i][2]+20, 0x00ffffff | math.floor(alphavalue*255)<<24, iifnot0(manager.machine.ioport.ports[":ctrl1:mdpad:PAD"]:read() & buttons[i], 0x00ff0000 | math.floor(alphavalue*255)<<24, 0x00000000 | math.floor(alphavalue*255)<<24)) manager.machine.screens[":screen"]:draw_text(buttonpos[i][1]+2, buttonpos[i][2]+4, i, 0xffffff | math.floor(alphavalue*255)<<24) end end input=manager.machine.input if input:code_pressed(input:code_from_token("KEYCODE_OPENBRACE")) then displayoverlay = false end if input:code_pressed(input:code_from_token("KEYCODE_CLOSEBRACE")) then displayoverlay = true end if input:code_pressed(input:code_from_token("KEYCODE_8PAD")) then originy = originy - 1 end if input:code_pressed(input:code_from_token("KEYCODE_2PAD")) then originy = originy + 1 end if input:code_pressed(input:code_from_token("KEYCODE_4PAD")) then alphavalue = alphavalue-0.01 if alphavalue<0 then alphavalue=0 end end if input:code_pressed(input:code_from_token("KEYCODE_6PAD")) then alphavalue = alphavalue+0.01 if alphavalue>1.0 then alphavalue=1.0 end end end
emu.register_frame_done(drawoverlay) So, if this is something quick and you have a spare 5m I'll like your help on this. Thanks in advance.
Last edited by RomKnight; 11/02/23 01:35 PM.
|
|
|
|
Joined: Feb 2014
Posts: 1,124 Likes: 193
Very Senior Member
|
Very Senior Member
Joined: Feb 2014
Posts: 1,124 Likes: 193 |
Each driver is free to name its screens differently, so in this case the screen is named ":megadriv" Run a search and replace from ":screen" to ":megadriv" and it should work function printt(t) for i,j in pairs(t) do print (i,j) end end printt(manager.machine.screens) :megadriv sol.screen_device*: 0x557f97832d78
function iifnot0(a,b,c) if a~=0 then return b else return c end end
displayoverlay=true
originx,originy=50,170
alphavalue=0.5
function calcalpha() return math.floor(alphavalue*255)<<24 end
function pressed(token) input=manager.machine.input return input:code_pressed(input:code_from_token(token)) end
function drawoverlay()
dpadx,dpady = 50,originy padx,pady = 30,30 cposx,cposy = 120,originy rposx,rposy = 190,originy
buttons = {up = 1, down = 2, left = 4, right = 8, b = 16, c = 32, a = 64, start = 128}
buttonpos = {up = {dpadx, dpady-pady}, down = {dpadx,dpady+pady}, right = {dpadx+padx, dpady}, left={dpadx-padx, dpady}, c={cposx, cposy}, start={cposx+padx, cposy}, b={rposx,rposy}, a={rposx+padx, rposy}}
if displayoverlay==true then
screenname = ":screen"
screenname = ":megadriv"
screen = manager.machine.screens[screenname]
for i,j in pairs(buttons) do
screen:draw_box(buttonpos[i][1],buttonpos[i][2],buttonpos[i][1]+20,buttonpos[i][2]+20,
0x00ffffff | calcalpha(),
iifnot0(manager.machine.ioport.ports[":ctrl1:mdpad:PAD"]:read() & buttons[i],
0x00ff0000 | calcalpha(),
0x00000000 | calcalpha()))
screen:draw_text(buttonpos[i][1]+2, buttonpos[i][2]+4, i, 0xffffff | calcalpha())
end
end
if pressed("KEYCODE_OPENBRACE") then displayoverlay = false end
if pressed("KEYCODE_CLOSEBRACE") then displayoverlay = true end
if pressed("KEYCODE_8PAD") then originy = originy - 1 end
if pressed("KEYCODE_2PAD") then originy = originy + 1 end
if pressed("KEYCODE_4PAD") then alphavalue = alphavalue-0.01 if alphavalue<0 then alphavalue=0 end end
if pressed("KEYCODE_6PAD") then alphavalue = alphavalue+0.01 if alphavalue>1.0 then alphavalue=1.0 end end
end
emu.register_frame_done(drawoverlay)
Last edited by Golden Child; 11/02/23 04:02 PM.
|
|
|
|
Joined: Aug 2008
Posts: 24
Member
|
Member
Joined: Aug 2008
Posts: 24 |
Perfect. Thanks for the time explaining it.
|
|
|
|
Joined: Feb 2014
Posts: 1,124 Likes: 193
Very Senior Member
|
Very Senior Member
Joined: Feb 2014
Posts: 1,124 Likes: 193 |
For fun, I wanted to see if I could get lua to generate some xml. So this makes a list of elements from drawing boxes and text, then prints some xml.
elementlist = {}
function iifnot0(a,b,c) if a~=0 then return b else return c end end
function mydrawbox(x,y,x1,y1,portname,mask,bordercolor,inside1,inside0)
manager.machine.screens[":screen"]:draw_box(x,y,x1,y1,bordercolor, iifnot0(manager.machine.ioport.ports[portname]:read() & mask, inside1, inside0))
table.insert(elementlist, {type="box",x=x,y=y,x1=x1,y1=y1,portname=portname,mask=mask,bordercolor=bordercolor,inside1=inside1,inside0=inside0})
end
function mydrawtext(x,y,text,col)
manager.machine.screens[":screen"]:draw_text(x,y,text,col)
table.insert(elementlist, {type="text",x=x,y=y,text=text,col=col})
end
function otag(t,attrs,inside) attrs=attrs or "" return "<"..t.." "..attrs..">\n" end -- open tag
function ctag(t) return "</"..t..">\n" end -- close tag
function tag(t,attrs,inside) attrs=attrs or "" inside = inside or "" return "<"..t.." "..attrs..">\n"..inside.."</"..t..">\n" end -- complete tag
function stag(t,attrs) attrs=attrs or "" return "<"..t.." "..attrs.."/>\n"end -- singleton tag
function attr(a,v) return a.."=\""..v.."\"".." " end -- attribute
function makelayout()
print(otag("mamelayout",attr("version",2)))
print(tag("element",attr("name","button"),
tag("rect","",stag("color",attr("red",1.0)..attr("green",1.0)..attr("blue",1.0)))..
tag("rect",attr("state",1),stag("color",attr("red",1.0)..attr("green",0.0)..attr("blue",0.0))..
stag("bounds",attr("x",0.05)..attr("y",0.05)..attr("width",0.90)..attr("height",0.90)))..
tag("rect",attr("state",0),stag("color",attr("red",0.0)..attr("green",0.0)..attr("blue",0.0))..
stag("bounds",attr("x",0.05)..attr("y",0.05)..attr("width",0.90)..attr("height",0.90))) ))
for i,j in pairs(elementlist) do
if j.type=="text" then print(tag("element",attr("name","text"..j.text),stag("text",attr("string",j.text)))) end
end
print(otag("view",attr("name","Overlay")))
print([[<screen index="0">
<bounds x="0" y="0" width="256" height="240" />
</screen>]])
for i,j in pairs(elementlist) do
if j.type=="text" then print(tag("element",attr("ref","text"..j.text),stag("bounds",attr("top",j.y)..attr("left",j.x)..attr("bottom",j.y+10)..attr("right",j.x+4*j.text:len())))) end
if j.type=="box" then print(tag("element",attr("ref","button")..attr("inputtag",j.portname)..attr("inputmask",j.mask),stag("bounds",attr("top",j.y)..attr("left",j.x)..attr("bottom",j.y1)..attr("right",j.x1)))) end
end
print(ctag("view"))
print(ctag("mamelayout"))
end
function drawoverlay()
elementlist = {}
dpadx,dpady = 50, 170 padx,pady = 30, 30 cposx,cposy = 120, 170 rposx, rposy = 190,170
buttons = {up = 16, down = 32, left = 64, right = 128, a=1, b=2, select=4, start=8}
buttonpos = {up = {dpadx, dpady-pady}, down = {dpadx,dpady + pady}, right = {dpadx+padx, dpady}, left={dpadx-padx, dpady}, select={cposx, cposy}, start={cposx+padx,cposy}, b={rposx,rposy},a={rposx+padx,rposy}}
for i,j in pairs(buttons) do
mydrawbox(buttonpos[i][1],buttonpos[i][2],buttonpos[i][1]+20,buttonpos[i][2]+20,
":ctrl1:joypad:JOYPAD",buttons[i], 0x88ffffff, 0x88ff0000, 0x88000000)
mydrawtext(buttonpos[i][1]+2,buttonpos[i][2]+4,i,0x88ffffff)
end
end
emu.register_frame_done(drawoverlay)
makelayout()
and the xml it generates:
<mamelayout version="2" >
<element name="button" >
<rect >
<color red="1.0" green="1.0" blue="1.0" />
</rect>
<rect state="1" >
<color red="1.0" green="0.0" blue="0.0" />
<bounds x="0.05" y="0.05" width="0.9" height="0.9" />
</rect>
<rect state="0" >
<color red="0.0" green="0.0" blue="0.0" />
<bounds x="0.05" y="0.05" width="0.9" height="0.9" />
</rect>
</element>
<element name="textright" >
<text string="right" />
</element>
<element name="textup" >
<text string="up" />
</element>
<element name="texta" >
<text string="a" />
</element>
<element name="textdown" >
<text string="down" />
</element>
<element name="textleft" >
<text string="left" />
</element>
<element name="textb" >
<text string="b" />
</element>
<element name="textstart" >
<text string="start" />
</element>
<element name="textselect" >
<text string="select" />
</element>
<view name="Overlay" >
<screen index="0">
<bounds x="0" y="0" width="256" height="240" />
</screen>
<element ref="button" inputtag=":ctrl1:joypad:JOYPAD" inputmask="128" >
<bounds top="170" left="80" bottom="190" right="100" />
</element>
<element ref="textright" >
<bounds top="174" left="82" bottom="184" right="102" />
</element>
<element ref="button" inputtag=":ctrl1:joypad:JOYPAD" inputmask="16" >
<bounds top="140" left="50" bottom="160" right="70" />
</element>
<element ref="textup" >
<bounds top="144" left="52" bottom="154" right="60" />
</element>
<element ref="button" inputtag=":ctrl1:joypad:JOYPAD" inputmask="1" >
<bounds top="170" left="220" bottom="190" right="240" />
</element>
<element ref="texta" >
<bounds top="174" left="222" bottom="184" right="226" />
</element>
<element ref="button" inputtag=":ctrl1:joypad:JOYPAD" inputmask="32" >
<bounds top="200" left="50" bottom="220" right="70" />
</element>
<element ref="textdown" >
<bounds top="204" left="52" bottom="214" right="68" />
</element>
<element ref="button" inputtag=":ctrl1:joypad:JOYPAD" inputmask="64" >
<bounds top="170" left="20" bottom="190" right="40" />
</element>
<element ref="textleft" >
<bounds top="174" left="22" bottom="184" right="38" />
</element>
<element ref="button" inputtag=":ctrl1:joypad:JOYPAD" inputmask="2" >
<bounds top="170" left="190" bottom="190" right="210" />
</element>
<element ref="textb" >
<bounds top="174" left="192" bottom="184" right="196" />
</element>
<element ref="button" inputtag=":ctrl1:joypad:JOYPAD" inputmask="8" >
<bounds top="170" left="150" bottom="190" right="170" />
</element>
<element ref="textstart" >
<bounds top="174" left="152" bottom="184" right="172" />
</element>
<element ref="button" inputtag=":ctrl1:joypad:JOYPAD" inputmask="4" >
<bounds top="170" left="120" bottom="190" right="140" />
</element>
<element ref="textselect" >
<bounds top="174" left="122" bottom="184" right="146" />
</element>
</view>
</mamelayout>
|
2 members like this:
u-man, robcfg |
|
|
|
Joined: Aug 2008
Posts: 24
Member
|
Member
Joined: Aug 2008
Posts: 24 |
This is cool and useful. thanks.
|
|
|
|
Joined: Feb 2014
Posts: 1,124 Likes: 193
Very Senior Member
|
Very Senior Member
Joined: Feb 2014
Posts: 1,124 Likes: 193 |
I had an idea of having a set of "macro buttons" that you could click on to help you control a system. For example, on the apple II you could have a button that would do "CTRL+RESET" or would type a system command like "CATALOG" or "CALL -151". This would be useful for helping navigate unfamiliar systems or to type unusual commands. For proof of concept, I wanted to make clickable buttons on a layout, which means adding an input port. So taking the apple2e driver, I added a dummy input port "keyb_dummy"
static INPUT_PORTS_START( apple2e_common )
PORT_START("keyb_dummy")
PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("DUMMY0")
PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("DUMMY1")
PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("DUMMY2")
PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("DUMMY3")
PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("DUMMY4")
PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("DUMMY5")
PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("DUMMY6")
PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("DUMMY7")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("DUMMY8")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("DUMMY9")
...
m_kbspecial(*this, "keyb_special"),
m_kbdummy(*this, "keyb_dummy"),
m_sysconfig(*this, "a2_config"),
...
required_ioport m_kbspecial;
required_ioport m_kbdummy;
optional_ioport m_sysconfig;
...
so now I've got some dummy buttons I can hook up to a layout. So now I can make a layout file: Taking my layout file from the nes and hacking up on it:
<mamelayout version="2" >
<element name="button" >
<rect >
<color red="1.0" green="1.0" blue="1.0" />
</rect>
<rect state="1" >
<color red="1.0" green="0.0" blue="0.0" />
<bounds x="0.05" y="0.05" width="0.9" height="0.9" />
</rect>
<rect state="0" >
<color red="0.0" green="0.0" blue="0.0" />
<bounds x="0.05" y="0.05" width="0.9" height="0.9" />
</rect>
</element>
<element name="textreset" >
<text string="Reset" />
</element>
<element name="textctrl" >
<text string="Control" />
</element>
<element name="textctrlreset" >
<text string="Control-Reset" />
</element>
<element name="textctrlcenter" >
<text string="^C + CR" />
</element>
<element name="textcall151" >
<text string="CALL -151" />
</element>
<group name="buttons">
<element ref="button" inputtag=":keyb_special" inputmask="8" >
<bounds top="170" left="20" bottom="190" right="40" />
</element>
<element ref="textctrl" >
<bounds top="174" left="22" bottom="184" right="38" />
</element>
<element ref="button" inputtag=":keyb_dummy" inputmask="2" >
<bounds top="170" left="160" bottom="190" right="190" />
</element>
<element ref="textctrlcenter" >
<bounds top="174" left="162" bottom="184" right="182" />
</element>
<element ref="button" inputtag=":keyb_dummy" inputmask="4" >
<bounds top="170" left="120" bottom="190" right="150" />
</element>
<element ref="textctrlreset" >
<bounds top="174" left="122" bottom="184" right="146" />
</element>
<element ref="button" inputtag=":keyb_dummy" inputmask="8" >
<bounds top="170" left="210" bottom="190" right="240" />
</element>
<element ref="textcall151" >
<bounds top="174" left="212" bottom="184" right="236" />
</element>
<element ref="button" inputtag=":keyb_special" inputmask="128" >
<bounds top="170" left="80" bottom="190" right="100" />
</element>
<element ref="textreset" >
<bounds top="174" left="82" bottom="184" right="102" />
</element>
</group>
<view name="Helper" >
<screen index="0">
<bounds x="0" y="0" width="280" height="240" />
</screen>
<group ref="buttons">
<bounds left="-160" right="0" top="0" bottom="20"/>
</group>
</view>
</mamelayout>
and a lua script (executed with dofile) that simply watches the dummy port and executes a command based on the port being pressed.
function press(port,field)
manager.machine.ioport.ports[port].fields[field]:set_value(1)
end
function release(port,field)
manager.machine.ioport.ports[port].fields[field]:clear_value()
end
function do_reset()
press(":keyb_special","Control")
press(":keyb_special","RESET")
emu.wait(2/60)
release(":keyb_special","RESET")
release(":keyb_special","Control")
emu.wait(1/60)
end
function do_ctrlc()
press(":keyb_special","Control")
press(":X3","C c") -- was aborting because it was looking for "c"
emu.wait(2/60)
release(":X3","C c")
emu.wait(1/60)
release(":keyb_special","Control")
emu.wait(1/60)
press(":X6","Return") -- not in X5 it's in X6!!!
emu.wait(1/60)
release(":X6","Return")
emu.wait(1/60)
end
function check_dummy()
if lastdummyread == nil then lastdummyread=0 end
dummyread = manager.machine.ioport.ports[":keyb_dummy"]:read()
if dummyread ~= 0 and lastdummyread==0 then
if dummyread & 4 ~= 0 then
co1=coroutine.create(do_reset) coroutine.resume(co1)
end
if dummyread & 2 ~= 0 then
co1=coroutine.create(do_ctrlc) coroutine.resume(co1)
end
end
lastdummyread = dummyread
end
emu.register_frame_done(check_dummy)
It's kind of primitive, but it works.
|
|
|
|
Joined: May 1999
Posts: 616 Likes: 1
Senior Member
|
Senior Member
Joined: May 1999
Posts: 616 Likes: 1 |
Interesting, Golden Child, but for this to work I have to modify the source code, if I understand it correctly, right?
|
|
|
|
Joined: Mar 2001
Posts: 17,228 Likes: 251
Very Senior Member
|
Very Senior Member
Joined: Mar 2001
Posts: 17,228 Likes: 251 |
Right, that's a source mod. The Franklin clones have F1-F12 keys that are programmable macros but the emulation isn't 100% correct.
|
|
|
1 members (anoid),
221
guests, and
1
robot. |
Key:
Admin,
Global Mod,
Mod
|
|
Forums9
Topics9,325
Posts122,087
Members5,074
|
Most Online1,283 Dec 21st, 2022
|
|
These forums are sponsored by Superior Solitaire, an ad-free card game collection for macOS and iOS. Download it today!
|
|
|
|