MFME extraction, etc #2
Replies: 34 comments 80 replies
-
|
Thanks for this, and apologies @cuavas, @james-wallace-ghub - I was thinking we need something for general MAME fruit machine discussion, this is perfect :) As an update - I am fully committed to the 'flakey but already working' approach on my MFME layout/config extractor again now (to much risk/work/complexity in the FML decoding approach). I spent last night doing the majority of the remaining Lamp component base info (thus far I've been just extracting enough to drive the Arcade Sim 'DX' machines, as it was all still in the experimental phase). Plan is:
I'll post the odd update as I pass key milestones, now we have a forum for this :) |
Beta Was this translation helpful? Give feedback.
-
|
As you’ve probably noticed, I’ve been slowly converting layouts to use loops to generate and place the numeric lamp/button labels in the debug views. It saves thousands of lines in the layout files, and makes a checked out source tree a bit smaller. I have about 200 left to do for my current round. It’s fairly automated with vim scripting, but I still check the changes, so it’s boring work. As you guys are already no doubt aware, the reel components in layouts (inherited from AGEMAME) have been deprecated. They were problematic in multiple ways. They performed incredibly poorly (you could see the slowdown when the reels do their initial spin on start), they generate insane numbers of textures, and you’re limited to using fixed-size bitmap tiles. Being able to show a window on any element is more flexible (it can cater to things other than reels), and it performs a whole lot better. I migrated a couple of layouts to eliminate deprecated reel elements, but it’s going to be quite a while before they’re all done. There are some other people interested in helping out with it, but I’ve been putting off describing the process because I wanted to get the rest of the debug view cleanup done first. |
Beta Was this translation helpful? Give feedback.
-
|
The Here’s an example of a new, relatively simple layout using scroll windows to implement reels: https://github.com/mamedev/mame/blob/445293464e4aa99320493f1a93d8caeff72a1a68/src/mame/layout/j_lc.lay This commit converts reel components for one layout: mamedev/mame@24a5f43 Essentially:
With the
|
Beta Was this translation helpful? Give feedback.
-
|
@johnparker007 I saw you mentioned about your doing screen scraping/remote control of MFME. Just FYI that you do not need to do this with MAME (any more), @npwoods (Bletch) has a good example of how to remote control a MAME interface with Lua over at https://github.com/npwoods/bletchmame . Most (all?) MAME frontends have yet to catch up. |
Beta Was this translation helpful? Give feedback.
-
|
@davidhaywood just to let you know I've finally got some free time again, so I've now finished up the first stage of scraping the components (used in the test MPU4 Adders & Ladders MFME layout). This gives me graphical assets along with a large human-readable json file containing a dump of all the extracted data: CLASSICClassicAddersAndLadders(Barcrest).zip So now I'll move onto implementing a new version of the MAME .lay xml builder. I might be able to salvage some stuff from the old one written in C, but I may just start from scratch, and do it cleaner... Once I've got it generating something I'll post another update with a MAME screenshot :) I may be doing some improvements, I'm considering putting a white border around clickable buttons, something like this mockup on the £1 button, so they are visually different to lamps: |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
Extending the built-in components is the road to hell. It’s better to keep them simple. We’re not going to complicate them.
It’s one setting to change to turn on a plugin – you can get there from the main menu pretty easily. You’d be shocked how many “typical users” turn on the high score, autofire and input macro plugins straight away. I really don’t want to pander to users who can’t flip a setting in a menu.
Why are people so obsessed with using transforms to rotate things by 45° when the SVG code would be more readable using plain paths? I really don’t understand this.
You‘re not understanding what a group element actually does or how scrolling words.
But I think you’re trying to jam too much stuff into the internal layouts. Consider that in an external layout, you can supply SVG, PNG, JPEG or BMP files for reel graphics. If you want to de-duplicate the symbols in an external layout, you can just draw the same images in multiple elements (remember an element can contain multiple components). For internal layouts it‘s probably better to just use text for the reel symbols so people know what they are. |
Beta Was this translation helpful? Give feedback.
-
|
@davidhaywood @james-wallace-ghub Hey guys :) I've been following the conversation you were having on mamedev/mame#10015 ... re: "the layout now specifies if the 7seg is inverted. I guess this makes sense, if they used different component types which inverted the signal or something. kinda feels like we're missing a level of abstraction somewhere, but as it's mostly guesswork based on behavior, it should be ok for now." I'm sure you already know, but just in case - in MFME, the emulator appears to be able to detect/model this without any additional game-specific configuration (i.e. within layout, as that also has a lot of per-game hardware settings, much like MAME's per-game drivers). Here's a screenshot showing the layout properties page for an LED on Andy's Big Time, plus the overall hardware config page... no option anywhere to manually invert 7 seg displays: Apologies if this is superfluous information :) It does suggest though that it's (somehow) possible to have these work at the emulation level, without a per game manual adjustment. Easier said than done of course :) But it does appear to be derivable. I have been continuing to work on the layout builder, another (very rough) WIP screenshot: |
Beta Was this translation helpful? Give feedback.
-
|
fwiw, looking at the layouts we already have the one for 'Alphabet' is mostly correct, but it looks like that game doesn't use a standard '3 lamps per reel' setup. I'm guessing the layout generator assumed reel lamps were always a standard mapping? |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
|
@davidhaywood I'm moving to a new layout with different reel symbols, so I can develop something for parsing reel symbols from text files/earlier versions of the .lay files. This was always going to be an issue - so was just wondering; how did you go about unscrambling the lamps themselves to make your test Classic Adders & Ladders MPU4 layout work correctly (once you'd given it the correct 8x lamp column Chr values)? Was it just a case of careful trial and error per lamp, or did you figure out any kind of magic way to determine the old lamp number -> new lamp number mappings? MPU4 Graffiti layout, showing incorrect lamps: 0x00, 0x60, 0x40, 0x60, 0x20, 0x40, 0x40, 0x20 (MAME driver correct lamp chr values) I'm guessing it was just working each lamp out manually, but thought I'd best check! :) - in which case, I guess I'd initially just generate them with these wrong lamps where they occur, perhaps someone can be tempted into working them all out in the source MFME layouts, so I can then rebuild them for MAME. |
Beta Was this translation helpful? Give feedback.
-
|
well for Classic Adders and Ladders, yes, I went over the layout and manually fixed the lamp values. Basically each scramble value acts as a 'xor' on each row. I knew what the old layout expected, and was previously being provided, and I knew the difference in the values in my lamp values compared to the old ones. From there I created a table of what the 'old' lamp number in the layout was, vs. what it should be. I search+replaced each of the lamp values that would need changing, so "lamp64" was renamed "lampxxxx68" for example. After doing all the renames I then removed the 'xxxx' part. basically if you want to hand-fix the layouts to work you need to know the (incorrect) CHR lamp table values MFME used and the (correct) CHR lamp table MAME uses. I guess it would be cleaner if this could be built into the conversion process, but for Classic AL it was done by hand. |
Beta Was this translation helpful? Give feedback.
-
|
Just checking in with another update :) The work is going slowly due to lack of time (the noisy neighbours on both sides of my terraced house have got the better of me, so now I'm balancing full time job + building false interior walls both sides of house to block the noise, so FME dev is getting a smaller slice of time than is ideal), but still progressing... Been doing work on more reel symbol layers, and also got JPM input/reel alignment working, here's a couple more test layouts: MPU4 Graffiti with fruit symbols/overlays: MPU4 Sunset Boulevard with boxed symbols: JPM Impact Big Bucks - some symbols have a red background stripe layer, buttons/coins/reels working (minor issue with hold 2/3 lamps to figure out): |
Beta Was this translation helpful? Give feedback.
-
|
glad to see you're still chipping away, my progress has kinda stalled until the branch gets merged in, but I'm sure we'll get there in the end |
Beta Was this translation helpful? Give feedback.
-
|
I took the liberty of asking about Bell Fruit Flat Chassis at the Mecca someone posted a pic of one of the boards https://www.fruitemu.co.uk/ib/topic/25725-bell-fruit-flat-chassis/#comment-374855 |
Beta Was this translation helpful? Give feedback.
-
|
Hey @james-wallace-ghub and @mamehaze :) I'd been ill so away from the scene for a while. I have been back to slowly plugging away on some FME-related stuff though :) It's not ready yet, but I thought a preview would be good. So the new project is a suite of programs (Oasis suite) to allow others to work on this stuff that I was doing all manually/with coding before. So there is a split out tool in progress, that takes care of extracting layouts from MFME to an open JSON structure with accompanying BMP images: ...in conjunction with that I'm working on a Layout Editor: ...and this will have the MAME .lay builder ported/upgraded into it. So the layout is firstly Extracted from MFME, then Imported into Layout Editor, and then can be Exported to MAME .lay format. The Layout Editor will also allow for creating layouts from scratch, so will be generally useful for MAME internal layouts outside of just fruit machine layouts. It also runs MAME as a child process and can render the emulation/send input to MAME (via Lua), so this will be helpful if creating new layouts to test lamps/buttons etc: All a work in progress for now, but thought it was worth an update :) Sorry I abandoned the last big attempt at this - but lots of that work is finding its way into this new work, so not a complete write off! And this way, it won't actually need specifically me, others will be able to help, with labelling reel text symbols etc (some people have indicated they'll be down to help with that sort of stuff from over on Dif forum. The repo is here, and I'll update again once we're at the stage of outputting MAME .lay files, as I'm prioritising that over all the 3d stuff it will do later. |
Beta Was this translation helpful? Give feedback.
-
|
It does feel to me that the lay creation is the stumbling block here, so something cleaner than the existing setup is a good move. I think trying to find a good route to do this is something that has been beyond me, so I'm keen to see where this goes. |
Beta Was this translation helpful? Give feedback.
-
|
I've looked at the MFME .fml files and they're compressed using a Delphi library called "EasyCompression" program mfme_decoder;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, EasyCompression;
const
levelValue: array [0 .. 3] of TECLCompressionLevel = (eclNone, zlibFastest,
zlibNormal, zlibMax);
var
fs: TECLFileStream;
s: string;
begin
try
fs := TECLFileStream.Create(ParamStr(1), fmOpenReadWrite, '00908434');
s := ParamStr(1) + '.dec';
fs.SaveToFile(s);
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;Sadly they are still not really readable, it's a binary format I haven't understood yet. |
Beta Was this translation helpful? Give feedback.
-
|
That's great work. If I can find a Delphi compiler I might have a play with this, unless you've a precompiled version available ? Thanks |
Beta Was this translation helpful? Give feedback.
-
|
Thanks for that. |
Beta Was this translation helpful? Give feedback.
-
|
The key seems to be calculated dynamically, I suppose more research is needed.
I did not that the cleartext .gam file was in memory the entire time, the key is probably calculated from that somehow |
Beta Was this translation helpful? Give feedback.
-
|
MFME will load a fml file without having a gam file so that can't be used for the password. |
Beta Was this translation helpful? Give feedback.
-
|
A renamed fml still loads ok, so it's not the name.
…On Sun, 30 Nov 2025 at 19:16, stonedDiscord ***@***.***> wrote:
No, there doesn't seem to be one, there is only the AACS header from the
library. Can you test loading a fml file that has been renamed?
—
Reply to this email directly, view it on GitHub
<#2 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AXSXQJ3KTMVZ2ALXHZZPKIT37M7BZAVCNFSM6AAAAACNRXSSWGVHI2DSMVQWIX3LMV43URDJONRXK43TNFXW4Q3PNVWWK3TUHMYTKMJRHAYTSMI>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
|
Adding a few zeroes to the end does nothing, adding a bunch of them prevents the layout from loading - pretty sure it's in the size. |
Beta Was this translation helpful? Give feedback.
-
|
It doesn't look like its the size. |
Beta Was this translation helpful? Give feedback.
-
|
I think this time I figured it out for some of the files: program mfme_decoder;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, System.Classes, EasyCompression;
const
levelValue: array [0 .. 9] of TECLCompressionLevel = (eclNone, zlibFastest,
zlibNormal, zlibMax, bzipFastest, bzipNormal, bzipMax, ppmFastest,
ppmNormal, ppmMax);
var
fs: TECLFileStream;
inputFile, outputFile: string;
last4Bytes: Cardinal;
passwordInt: Integer;
const
XOR_CONST = $00C59A00;
{$R-}
{$Q-}
function mixer(a1, a2: Integer): Integer;
var
i: Integer;
x, v4: Cardinal;
addr: Cardinal;
begin
Result := a2;
addr := Cardinal(a1);
for i := 0 to 99 do
begin
x := addr xor Cardinal(Result);
v4 := (x shr 24) or (x shl 24) or (x and $00FFFF00);
Result := (v4 shl 3) or (v4 shr 29);
end;
end;
begin
try
if ParamCount < 1 then
begin
Writeln('Usage: mfme_decoder <inputfile>');
Exit;
end;
inputFile := ParamStr(1);
outputFile := ChangeFileExt(inputFile, '_decoded.dat');
var
fsIn := TFileStream.Create(inputFile, fmOpenRead or fmShareDenyNone);
try
fsIn.Seek(-4, soFromEnd);
fsIn.ReadBuffer(last4Bytes, 4);
finally
fsIn.Free;
end;
Writeln('Bytes: ', last4Bytes);
passwordInt := mixer(XOR_CONST, Integer(last4Bytes));
var
passwordStr := LowerCase(IntToHex(passwordInt));
Writeln('Password: ', passwordStr);
try
fs := TECLFileStream.Create(inputFile, fmOpenRead, passwordStr);
fs.SaveToFile(outputFile);
Writeln('File decoded to: ', outputFile);
finally
fs.Free;
end;
except
on E: Exception do
begin
Writeln(E.ClassName, ': ', E.Message);
Writeln('Trying alt password');
fs := TECLFileStream.Create(inputFile, fmOpenRead, 'b67de657');
fs.SaveToFile(outputFile);
Writeln('File decoded to: ', outputFile);
end;
end;
end.The last 4 bytes are the password but run through a XOR mixer 100 times. |
Beta Was this translation helpful? Give feedback.
-
|
I created my own fml file and it seemed fairly structured and semi-meaningful but other fmls looked completely different but I eventually found some similarities. The images are stored as bitmap files with a control header before them. Easiest way to find them is look for the font name, "Tahoma" was used on the fml I looked at. Sometimes you get some extra 'tags' between the images, no idea what they do. Somewhere in all that is the number of "on" images as you can have images which aren't allocated to a lamp so aren't in the 12*4 table. That's all I've got |
Beta Was this translation helpful? Give feedback.
-
|
For now I'm most interested in the element positions, this alone would make manual layout creation much easier. So parsing the fml to get parameters 01-04 is what I'm going for right now. |
Beta Was this translation helpful? Give feedback.

















Uh oh!
There was an error while loading. Please reload this page.
-
A continuation of mamedev/mame#9632 (comment) , so we don't pollute the PR system any more.
Beta Was this translation helpful? Give feedback.
All reactions