Main Restorations Software Audio/Jukebox/MP3 Everything Else Buy/Sell/Trade
Project Announcements Monitor/Video GroovyMAME Merit/JVL Touchscreen Meet Up Retail Vendors
Driving & Racing Woodworking Software Support Forums Consoles Project Arcade Reviews
Automated Projects Artwork Frontend Support Forums Pinball Forum Discussion Old Boards
Raspberry Pi & Dev Board controls.dat Linux Miscellaneous Arcade Wiki Discussion Old Archives
Lightguns Arcade1Up Try the site in https mode Site News

Unread posts | New Replies | Recent posts | Rules | Chatroom | Wiki | File Repository | RSS | Submit news

  

Author Topic: Question for MAME programming gurus (maybe Retroarch too)  (Read 3628 times)

0 Members and 1 Guest are viewing this topic.

KNagle04

  • Trade Count: (0)
  • Jr. Member
  • **
  • Offline Offline
  • Posts: 1
  • Last login:June 28, 2023, 03:51:42 am
  • I want to build my own arcade controls!
Question for MAME programming gurus (maybe Retroarch too)
« on: August 03, 2021, 07:20:51 pm »
Hello everyone, I'm working on an idea I have for a Track 'N Field arcade cabinet I'm building and hope maybe I can get some insight on whether you guys think this is possible.

In a nutshell, my idea is to have setup that penalizes you whenever you FOUL in the game. At this point it may range anywhere from a squirt gun shooting you with a blast of water, to a little miniature popping out and wacking your fingers with a little mallet. Basically I need an output trigger from the game whenever a player fouls.

I initially started looking into Mame hooker thinking I may be able to make that work, but then I found it's more for triggering outputs on games that actually had these physical outputs on the original machine. It worked for things like lights and sirens on games that actually had them, or the "knocker" on a Q-Bert machine, but not so much for things that originally were never an actual output.

My question is: Is this something that sounds like it might be do-able? Possibly with the RetroAchievement system? Can a memory value being written as a foul be used as a trigger that can make it outside Retroarch itself? In my head, an acheivement something along the lines of "Foul x amount of times in a row" doesn't seem out of the realm of possibility, so neither should triggering an output off that first foul.

I'm sure there will be more steps along the way to get the signal to the actuators themselves, but I feel like getting the signal from the game is the first step. The RetroAchievement system seems to me like a good way to possibly make this happen, but I also don't really know anything about the programming behind how it works.

Am I even close to making any sense here? Any thoughts you guys might have would be greatly appreciated. Thanks again.

PL1

  • Global Moderator
  • Trade Count: (+1)
  • Full Member
  • *****
  • Offline Offline
  • Posts: 9402
  • Last login:Yesterday at 09:46:22 pm
  • Designated spam hunter
Re: Question for MAME programming gurus (maybe Retroarch too)
« Reply #1 on: August 03, 2021, 09:48:56 pm »
I don't think the squirt gun or mallet are good ideas for penalties . . .   :scared
. . . but I'll throw my 2 cents in on two possible generic ways to trigger an external event when a foul occurs.

Watching some game footage reveals that the one consistent thing with fouls in the different events is the "FOUL" sound file.

One way to trigger an output is to watch for the emulator to access the sound ROM memory address where the file is stored.

The other way would be to feed the audio into a voice recognition program that only sends an output when it hears "FOUL."


Scott

bobbyb13

  • Trade Count: (+2)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 1899
  • Last login:Today at 02:59:55 am
  • I believe I may need an intervention
Re: Question for MAME programming gurus (maybe Retroarch too)
« Reply #2 on: August 04, 2021, 02:52:06 am »
This all reminds me of the air blasts in The Irritating Maze.
Relax, all right? My old man is a television repairman, he's got this ultimate set of tools! I can fix it.

Vocalitus

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 400
  • Last login:October 25, 2021, 06:16:58 pm
  • I want to build my own arcade controls!
Re: Question for MAME programming gurus (maybe Retroarch too)
« Reply #3 on: August 04, 2021, 03:05:23 am »
Hello everyone, I'm working on an idea I have for a Track 'N Field arcade cabinet I'm building and hope maybe I can get some insight on whether you guys think this is possible.

In a nutshell, my idea is to have setup that penalizes you whenever you FOUL in the game. At this point it may range anywhere from a squirt gun shooting you with a blast of water, to a little miniature popping out and wacking your fingers with a little mallet. Basically I need an output trigger from the game whenever a player fouls.

I initially started looking into Mame hooker thinking I may be able to make that work, but then I found it's more for triggering outputs on games that actually had these physical outputs on the original machine. It worked for things like lights and sirens on games that actually had them, or the "knocker" on a Q-Bert machine, but not so much for things that originally were never an actual output.

My question is: Is this something that sounds like it might be do-able? Possibly with the RetroAchievement system? Can a memory value being written as a foul be used as a trigger that can make it outside Retroarch itself? In my head, an acheivement something along the lines of "Foul x amount of times in a row" doesn't seem out of the realm of possibility, so neither should triggering an output off that first foul.

I'm sure there will be more steps along the way to get the signal to the actuators themselves, but I feel like getting the signal from the game is the first step. The RetroAchievement system seems to me like a good way to possibly make this happen, but I also don't really know anything about the programming behind how it works.

Am I even close to making any sense here? Any thoughts you guys might have would be greatly appreciated. Thanks again.

Remember going to Disneyland in the Penny Arcade on Main Street?

They had the high voltage endurance machines for 25c that your muscles contracted and you could not let go of the handles?



Hook something like that to your Track N Field and you will never want to Foul again.  The joy of zapping yourself will add a new dimension to your gaming experience.

Just make sure you are not standing in a pool of liquid before hand.

Unless you are into fouling yourself more extremely, then I would recommend hairy legs, duct tape and a strong arm.


10yard

  • Trade Count: (0)
  • Full Member
  • ***
  • Online Online
  • Posts: 138
  • Last login:Today at 04:17:58 am
  • L BREAK into program
    • DKAFE Frontend
Re: Question for MAME programming gurus (maybe Retroarch too)
« Reply #4 on: August 05, 2021, 12:58:46 pm »
Hi,

This is definitely do-able.  I have it partially working so you can decide if you would like to take my approach.

There's a scripting engine in MAME that can query the memory of a machine as it is running.  You just need to know where in memory to look and what to look for.  It can be tricky but there is a process we can follow. 

Looking at the long jump stage,  I can see that the word "FOUL" appears on the board behind the athlete after the foul is given.



The word "FOUL" is made up of 4 sprites from the sprite bank of the rom.  There are rom hacking tools (such as TuracoCL) that allow you to extract the sprite banks from a rom to an image file.  I was able to pull this image from sprite bank 1 of trackfld.zip.



From this we can work out the offsets for each of the characters F, O, U and L.  That's the position of those characters within the sprite bank.
Counting from the top left (offset 0) and working across,  the character "F" appears at offset position 22.  This is 16 in hexadecimal.  Repeat for the others and we get.

F = 16
O = 1F
U = 25
L = 1C


The sprite offsets will be referenced in the video ram of the game as the screen is drawn so we need to figure out where abouts in memory is the video ram.
Thankfully,  the guys at MAME have documented their driver.

Code: [Select]
/***************************************************************************

Konami games memory map (preliminary)

Based on drivers from Juno First emulator by Chris Hardy (chrish@kcbbs.gen.nz)

Track'n'Field

MAIN BOARD:
0000-17ff RAM
1800-183f Sprite RAM Pt 1
1C00-1C3f Sprite RAM Pt 2
3800-3bff Color RAM
3000-33ff Video RAM
6000-ffff ROM
1200-12ff IO

***************************************************************************
/

So "Video RAM" starts from memory address 3000. 
To see the video ram,  we can run launch the rom in MAME with -debug parameter,  then open a memory window in the debugger,  and type 3000 into the address box.  To see a better textual representation of the video ram we can increase the number of bytes per line to 32 (from the default 16).  There looks to be 32 sprites drawn on each row.

Watching the memory window closely,  we can see the video data changing as the word FOUL is drawn to the screen.  Fortunately,  not much else is happening on screen at this time so it was easy to spot.  The data highlighted in red below was changed from 10, 10, 10, 10 to 16, 1F, 25, 1C. 
16, 1F, 25, 1C gives us "FOUL".  Yay!



Now we know how to check for a long jump foul so we can write a script to react to it.

I made the following script and saved it to the plugins folder under MAME as foul.lua

Code: [Select]
mem = manager.machine.devices.maincpu.spaces["program"]

function check(offset, value)
return mem:read_i8(offset) == value
end   

emu.register_frame(function()
-- Check for FOUL
if check(0xc34E5, 0x16) and check(0xc34E6, 0x1f) and check(0xc34E7, 0x25) and check(0xc34E8, 0x1c) then
if foul == nil then
-- React to the FOUL
os.execute("start c:\\emus\\mame_0234\\plugins\\foul.bat")
foul = 1
end
else
foul = nil
end
end)

If the script detects the foul then it reacts by launching the "foul.bat" batch file.  This file is also saved into the plugins folder of MAME.

Here is the result of my test.



You can test this out my extracting files from the attached zip into your MAME plugins folder.  Then run MAME with the following arguments (changing the path to your foul.lua).

Code: [Select]
mame trackfld -script c:\emus\mame_0234\plugins\foul.lua -window
I'm running MAME in a window so that you can see my popup message.  Obviously,  you can trigger any other action that you want either from the LUA script or from the batch file.

Jon
Check out my Donkey Kong Arcade Frontend at https://github.com/10yard/dkafe#readme


PL1

  • Global Moderator
  • Trade Count: (+1)
  • Full Member
  • *****
  • Offline Offline
  • Posts: 9402
  • Last login:Yesterday at 09:46:22 pm
  • Designated spam hunter
Re: Question for MAME programming gurus (maybe Retroarch too)
« Reply #5 on: August 05, 2021, 02:35:23 pm »
Impressive work, Jon.   :notworthy:

That approach works great for long jump, hammer throw and javelin where you see and hear "foul", but not for high jump, hurdles, and 100 meter dash.

Can you use a similar approach to determine when sounds are played?

When when you foul on the high jump, you hear "foul" and see a red dot next to "fault", but the word foul doesn't appear on the screen. (6:25)



If you start too early in the hurdles or 100 meter dash, you see the message "flying start" and hear "flying". (13:45)



Based on these observations, it's probably better to look for the "foul" and "flying" sound triggers so all six events are covered.


Scott
« Last Edit: August 05, 2021, 03:31:42 pm by PL1 »

MartyKong

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 168
  • Last login:April 01, 2024, 05:09:52 pm
  • I want to build my own arcade controls!
Re: Question for MAME programming gurus (maybe Retroarch too)
« Reply #6 on: August 05, 2021, 04:24:34 pm »
Wow 10yard,
Learned a lot from your post! When I get freed up looking forward to giving Dkafe a whirl.

Vocalitus

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 400
  • Last login:October 25, 2021, 06:16:58 pm
  • I want to build my own arcade controls!
Re: Question for MAME programming gurus (maybe Retroarch too)
« Reply #7 on: August 05, 2021, 05:21:30 pm »
Great work!

I now know how to correct all my high scores. : )


Now all we have to do if find the correct battery to attach to the electrodes.

10yard

  • Trade Count: (0)
  • Full Member
  • ***
  • Online Online
  • Posts: 138
  • Last login:Today at 04:17:58 am
  • L BREAK into program
    • DKAFE Frontend
Re: Question for MAME programming gurus (maybe Retroarch too)
« Reply #8 on: August 05, 2021, 07:06:40 pm »
Impressive work, Jon.   :notworthy:

That approach works great for long jump, hammer throw and javelin where you see and hear "foul", but not for high jump, hurdles, and 100 meter dash.

Can you use a similar approach to determine when sounds are played?

When when you foul on the high jump, you hear "foul" and see a red dot next to "fault", but the word foul doesn't appear on the screen. (6:25)



If you start too early in the hurdles or 100 meter dash, you see the message "flying start" and hear "flying". (13:45)



Based on these observations, it's probably better to look for the "foul" and "flying" sound triggers so all six events are covered.


Scott

Thanks Scott.  It's a good suggestion to look at sounds.

I had a quick look at the MAME driver and can see that there is a sound latch which handles how the sounds are queued to the audio cpu.  It looks like there is a single memory address that contains sounds at the point they are requested by the game.  It retains the last requested sound/sample. 

Extract from MAME driver source:
Code: [Select]
map(0x6000, 0x6000).mirror(0x1fff).r("soundlatch", FUNC(generic_latch_8_device::read));

If I watch the value at memory address 0x6000 on the audio cpu.  I can see it changing with new sounds/samples.  I don't have a reference to the sounds,  like I did for the sprites but I can roll my own.  I made a start.  It's 1 byte so values range 0 to 255.


0 and 255 - No sound
1 - Running sound
2 - Coin inserted
21 Jumping sound
40 - Start Whistle
45 - Game over
128 - On your marks
129 - Get set
130 - Foul
179 - Flying


So this is doable too.

Here's a simple script which echoes the sample ID as the game is played.  When I get time I will update the list.  It's a good excuse to play more track and field  :cheers:

Code: [Select]
mem = manager.machine.devices.audiocpu.spaces["program"]

emu.register_frame(function()
sample = mem:read_u8(0x6000)
if sample > 0 and sample < 255 then
print(sample)
end
end)


 

« Last Edit: August 05, 2021, 07:10:59 pm by 10yard »
Check out my Donkey Kong Arcade Frontend at https://github.com/10yard/dkafe#readme


10yard

  • Trade Count: (0)
  • Full Member
  • ***
  • Online Online
  • Posts: 138
  • Last login:Today at 04:17:58 am
  • L BREAK into program
    • DKAFE Frontend
Re: Question for MAME programming gurus (maybe Retroarch too)
« Reply #9 on: August 05, 2021, 07:17:20 pm »
Wow 10yard,
Learned a lot from your post! When I get freed up looking forward to giving Dkafe a whirl.

Hey,  thanks.  Yeh,  please give DKAFE a whirl.  I have another update going out in the next few days.  Hopefully I'll get round to making videos to show it off.   
Check out my Donkey Kong Arcade Frontend at https://github.com/10yard/dkafe#readme


PL1

  • Global Moderator
  • Trade Count: (+1)
  • Full Member
  • *****
  • Offline Offline
  • Posts: 9402
  • Last login:Yesterday at 09:46:22 pm
  • Designated spam hunter
Re: Question for MAME programming gurus (maybe Retroarch too)
« Reply #10 on: August 05, 2021, 08:37:53 pm »
I had a quick look at the MAME driver and can see that there is a sound latch which handles how the sounds are queued to the audio cpu.  It looks like there is a single memory address that contains sounds at the point they are requested by the game.  It retains the last requested sound/sample. 

Extract from MAME driver source:
Code: [Select]
map(0x6000, 0x6000).mirror(0x1fff).r("soundlatch", FUNC(generic_latch_8_device::read));

If I watch the value at memory address 0x6000 on the audio cpu.  I can see it changing with new sounds/samples.  I don't have a reference to the sounds,  like I did for the sprites but I can roll my own.  I made a start.  It's 1 byte so values range 0 to 255.


0 and 255 - No sound
1 - Running sound
2 - Coin inserted
21 Jumping sound
40 - Start Whistle
45 - Game over
128 - On your marks
129 - Get set
130 - Foul
179 - Flying

Would it be possible to map all of the sounds by injecting different values between 1 and 254 into the sound latch address?

I'm picturing a script that uses 3 buttons -- ideally ones like "[", "]", and "=" that are usually not used by MAME.
- One button "]" to increase the value by one and display the new value like your earlier "YOU SUCK" example.   :lol
- One button "[" to decrease the value by one and display the new value.
- One button "=" to inject the current value into the sound latch address (plays the sound), display "playing sound [value]", add a short delay (if needed), then inject 0 or 255. (resets the latch to "no sound" to keep it from looping, if needed)



If you turn the attract mode sounds off, you can map the sounds without interruptions from the game.
- Set the "Demo Sounds" dipswitch to off then reboot with F3.


Scott
« Last Edit: August 05, 2021, 08:43:49 pm by PL1 »

10yard

  • Trade Count: (0)
  • Full Member
  • ***
  • Online Online
  • Posts: 138
  • Last login:Today at 04:17:58 am
  • L BREAK into program
    • DKAFE Frontend
Re: Question for MAME programming gurus (maybe Retroarch too)
« Reply #11 on: August 06, 2021, 08:36:05 am »
Quote
Would it be possible to map all of the sounds by injecting different values between 1 and 254 into the sound latch address?
The audio cpu wasn't happy with me injecting values so this approach came to a dead end Scott.  It was worth a try though.

Instead,  I adapted my previous discovery script to look up the description of the current sample if it was known to me and to echo the description to the console. If an unknown sample was played then ? would be shown e.g.

Code: [Select]
162: The
132: ?
150: 6
133: Point
145: 1
146: 2
134: ?

I would pause the game after my attempt and then update my discovery script with the missing descriptions based on what was announced in the game i.e.
Code: [Select]
132: Distance
134: Metres 

Here's the output from a game I had just now.  You can see the progression through the game based on the sounds that are echoed.

Code: [Select]
52:No Sound
4:Coin entry
3:Coin entry
2:Coin entry
24:Before name registration
64:Name registration music
23:Move cursor in name registration
27:Enter character in name registration
23:Move cursor in name registration
27:Enter character in name registration
23:Move cursor in name registration
27:Enter character in name registration
44:Stage begins/introduction music
128:On your marks
129:Get set
13:Starter pistol
12:Starter pistol
11:Starter pistol
1:Running/clock ticking
162:The
135:Time
155:11
133:Point
148:4
146:2
136:Seconds
65:Cheering
44:Stage begins/introduction music
40:Start Whistle
1:Running/clock ticking
5:Take off
20:Airborne
21:Airborne
9:Landing
37:Measuring
162:The
132:Distance
150:6
133:Point
147:3
153:9
134:Metres
65:Cheering
40:Start Whistle
1:Running/clock ticking
130:Foul
40:Start Whistle
1:Running/clock ticking
5:Take off
20:Airborne
21:Airborne
9:Landing
37:Measuring
162:The
132:Distance
150:6
133:Point
145:1
146:2
134:Metres
65:Cheering
44:Stage begins/introduction music
40:Start Whistle
1:Running/clock ticking
14:Start throw
20:Airborne
21:Airborne
15:End throw
130:Foul
40:Start Whistle
1:Running/clock ticking
14:Start throw
20:Airborne
21:Airborne
15:End throw
162:The
132:Distance
189:60
149:5
133:Point
152:8
146:2
134:Metres
51:A great score was registered!
40:Start Whistle
1:Running/clock ticking
14:Start throw
20:Airborne
21:Airborne
15:End throw
162:The
132:Distance
191:70
146:2
133:Point
145:1
160:6
134:Metres
51:A great score was registered!
44:Stage begins/introduction music
128:On your marks
129:Get set
13:Starter pistol
12:Starter pistol
11:Starter pistol
1:Running/clock ticking
6:Hurdling
7:Hurdling
6:Hurdling
7:Hurdling
1:Running/clock ticking
6:Hurdling
7:Hurdling
1:Running/clock ticking
6:Hurdling
7:Hurdling
1:Running/clock ticking
6:Hurdling
7:Hurdling
1:Running/clock ticking
6:Hurdling
7:Hurdling
1:Running/clock ticking
6:Hurdling
7:Hurdling
1:Running/clock ticking
6:Hurdling
7:Hurdling
1:Running/clock ticking
6:Hurdling
7:Hurdling
6:Hurdling
7:Hurdling
1:Running/clock ticking
6:Hurdling
7:Hurdling
6:Hurdling
7:Hurdling
1:Running/clock ticking
6:Hurdling
7:Hurdling
1:Running/clock ticking
6:Hurdling
7:Hurdling
1:Running/clock ticking
6:Hurdling
7:Hurdling
6:Hurdling
7:Hurdling
1:Running/clock ticking
6:Hurdling
7:Hurdling
6:Hurdling
7:Hurdling
10:Hit hurdle
1:Running/clock ticking
6:Hurdling
7:Hurdling
6:Hurdling
7:Hurdling
1:Running/clock ticking
162:The
135:Time
182:14
133:Point
149:5
146:2
136:Seconds
45:Game over music
31:Chariots of Fire music

and this is my discovery script so far.

Code: [Select]
mem = manager.machine.devices.audiocpu.spaces["program"]

t = {}
t[0] = "No sound"
t[1] = "Running/clock ticking"
t[2] = "Coin entry"
t[3] = "Coin entry"
t[4] = "Coin entry"
t[5] = "Take off"
t[6] = "Hurdling"
t[7] = "Hurdling"
t[8] = "Bad hammer throw"
t[9] = "Landing"
t[10] = "Hit hurdle"
t[11] = "Starter pistol"
t[12] = "Starter pistol"
t[13] = "Starter pistol"
t[14] = "Start throw"
t[15] = "End throw"
t[16] = "Bar hits ground"
t[18] = "Hammer swing"
t[19] = "Hit the bar"
t[20] = "Airborne"
t[21] = "Airborne"
t[23] = "Move cursor in name registration"
t[24] = "Before name registration"
t[27] = "Enter character in name registration"
t[31] = "Chariots of Fire music"
t[37] = "Measuring"
t[40] = "Start Whistle"
t[44] = "Stage begins/introduction music"
t[45] = "Game over music"
t[46] = "Fail music"
t[51] = "A great score was registered!"
t[52] = "No Sound"
t[64] = "Name registration music"
t[65] = "Cheering"
t[128] = "On your marks"
t[129] = "Get set"
t[130] = "Foul"
t[132] = "Distance"
t[133] = "Point"
t[134] = "Metres"
t[135] = "Time"
t[136] = "Seconds"
t[144] = "Zero"
t[145] = "1"
t[146] = "2"
t[147] = "3"
t[148] = "4"
t[149] = "5"
t[150] = "6"
t[151] = "7"
t[152] = "8"
t[153] = "9"
t[154] = "10"
t[155] = "11"
t[156] = "12"
t[157] = "13"
t[158] = "17"
t[159] = "30"
t[160] = "6"
t[162] = "The"
t[179] = "Flying"
t[182] = "14"
t[183] = "15"
t[184] = "16"
t[185] = "18"
t[186] = "19"
t[187] = "40"
t[188] = "50"
t[189] = "60"
t[190] = "20"
t[191] = "70"
t[255] = "No sound"


emu.register_frame(function()
sample = mem:read_u8(0x6000)
if sample ~= last_sample and sample > 0 and sample < 255 then
if t[sample] ~= nil then
print(sample..":"..t[sample])
else
print(sample..": ? ")
end
last_sample = sample
end
end)

My current script has most of the important samples mapped.  It just a case of playing it some more to cover some of the gaps...or maybe grab an .inp recording of a high scoring game from Twin Galaxies and play it back with the script running.

Reacting to events happening in the game will be super easy.  Just check 0x6000 addresss matches a number in our list.





« Last Edit: August 06, 2021, 08:38:32 am by 10yard »
Check out my Donkey Kong Arcade Frontend at https://github.com/10yard/dkafe#readme


10yard

  • Trade Count: (0)
  • Full Member
  • ***
  • Online Online
  • Posts: 138
  • Last login:Today at 04:17:58 am
  • L BREAK into program
    • DKAFE Frontend
Re: Question for MAME programming gurus (maybe Retroarch too)
« Reply #12 on: August 06, 2021, 09:47:24 am »
So KNagle04,  you can use the attached script to react to foul and flying starts.  Extract it from the ZIP and place it into your MAME plugins folder.

You will then need to run MAME with -script argument like below (changing your path to foul.lua) to test it.

mame trackfld -window -script c:\emus\mame_0234\plugins\foul.lua

Hope it is useful to you.
Jon



Check out my Donkey Kong Arcade Frontend at https://github.com/10yard/dkafe#readme


PL1

  • Global Moderator
  • Trade Count: (+1)
  • Full Member
  • *****
  • Offline Offline
  • Posts: 9402
  • Last login:Yesterday at 09:46:22 pm
  • Designated spam hunter
Re: Question for MAME programming gurus (maybe Retroarch too)
« Reply #13 on: August 06, 2021, 10:07:59 am »
:applaud:


Scott