lysiwyg

Bringing The Predators To Life In MAME

I rarely get to write about a passion of mine, and even less frequently do I get to take action on it, but the Christmas period of 2025 presented me with an opportunity I simply could not pass up.

0001.png

Since sometime around the turn of the century, I have been following the MAME project, Multiple Arcade Machine Emulator, for anyone who may be unfamiliar with the subject. MAME is the work of an Open Source Foundation dedicated to making arcade games playable on PC and smartphones and in a world where everything is considered disposable, the collective effort on display to prevent arcade media from being lost is rare and commendable. In the past, I have even contributed toward donation drives to purchase rare titles, but I stopped when delivery promises were broken notably Taito’s Vertexer. I do not recall whether I put money forward for that one or not but I love my space games.

MAME is a supermassive work, and contained within are many games that don't work or aren't even correctly recognized. I happened across a "pull request" to identify one of those arcade games while browsing the project pages earlier in December.

The subject was a four-player game that was said to resemble Sinistar, it was a forgotten piece of history from Williams that I had previously read about [reference 1]. The game was known as The Predators, and based on the dialogue, it had been added to the MAME code as an unidentified gambling game earlier this year by a developer named Mark Beckford (Osso13) [reference 2].

0012.png

A C language (source code) file for MAME was posted alongside the remarks [reference 3] claiming to be an extremely ancient “driver” for the game that had previously been worked on by Angelo Salese, David Haywood, and Philip Bennett. A driver is the uncompiled source code that powers the emulation of a game in MAME.

I had a Christmas break coming up, time off work, and I wanted to see how working on MAME compared to the daily grind of enterprise coding. I also wanted to see this long-lost game running on my computer and possibly share it with the world. Some of the other comments were rather odd and hard to understand, including one without context saying “stop chasing it” but compared to monetary contributions with no return on investment it made more sense to try my hand at coding.

Getting MAME to Build

The comments alongside the given source code suggested that it was for a MAME version from ten to fifteen years ago, raising the question of just why this has been languishing underground for as the Playstation 4 has been in our homes, but also providing a hint if I wanted to try my hand at getting it to play--- I would have to put together a version of MAME from that time period.

Doing so would prove easier said than done.

0003.png

MAME’s official support channels only provide support for the most recent version of the program; if you inquire about running or building older versions, you will simply receive a harsh reprimand for not utilizing the most recent release. Unprofessional behavior, but it is what it is.

In order to encompass the 15-year age estimate of the code, I had chosen MAME 0.140 from 2010, but lacking official support to guide me, and despite my repeated prompts, ChatGPT was unable to steer me toward a workable build environment. It is insufficient to simply state that previous versions are not supported, they are aggressively not supported but I was not to be deterred.

0005.png

I'd bet that some of you who are reading this have guessed where I turned next. Intuitively named MAME2010, the admirable people at Libretro have their own version of MAME from 2010. Because of their excellent support, I was able to construct a MAME2010 “core” for Retroarch in a matter of hours after attempting to compile MAME 0.140 for a whole day without success.

However, that didn't resolve my issue. A page-long list of build failures appeared when the C file was inserted into the MAME2010 code. A 2010 version of MAME, or at least this version of MAME, was not compatible with the C source code file. The structure of MAME didn’t match.

Since 15 years was at the higher end of an estimate, I switched to Libretro's 2016 core, which was likewise easy to compile. However, adding the driver proved to be unsuccessful once more, the structure of MAME's code did not match here either. My Libretro experience came to an end here, although their support for compiling these outdated cores is better than most industry software, they don't offer any documentation on how to develop with them, nor are MAME debugging features available, so I couldn't confidently edit the code I had to function using those versions.

My simple options had been exhausted, so it was time to do things the right way. By right, I mean porting the C source I had to the most recent version of MAME as attempting to find an older version to get it operating was wasting time.

0006.png

To their credit, the instructions on mamedev.org for compiling the current version of MAME [reference 4] are foolproof. The most time consuming part was compiling the binary because there is simply a lot more MAME now than there was in 2010, but that's not a complaint. There are examples of how to do anything you can think of, and I would need as many references as possible if I was going to be able to update this old code.

The build environment still was the source of my next issue. No sane person would want to use command line debugging and a non-integrated development environment to work on a project the size of MAME. After updating my reliable Visual Studio 2019, I tried the choices the MAME makefile offered for building Visual Studio 2022 solutions, but all were unsuccessful.

ChatGPT was more helpful for this problem, directing me at a wiki page containing instructions on how to build MAME with Visual Studio 2022 [reference 5] and with minor adjustments that worked. Build environment sorted.

Updating the Old C Code

The OOP (object-oriented programming) model is the most notable distinction between the code in the current iterations of MAME and the legacy C source code file that was supplied. In contrast to more recent MAME releases, which have nearly entirely switched to a C++ base, the version of MAME our code originated from was primarily based in C which was de-facto standard when MAME started out in 1997 and persisted until very recently because it offers greater performance.

To put it briefly, everything had changed outside of the ROM loading mechanism, which appears to be a relic alongside the C++ in the current MAME code. To port this I would have to deal with those changes by updating everything in the file using the old model to the new model.

0032.png

If you've spent enough time studying you'll see that there are two primary categories of code forming the structure of a MAME driver--- Glue that keeps everything together and bits of special code that describe the emulated platform's unique behavior. The first step was to divide the old C file into these. The bulk of the C file was glue logic, for this platform the unique code was minimal.

I was fortunate because MAME is filled with examples of modern implementations of glue logic, which made up the majority of the older file. Only the video handling, the way the game draws to the screens was truly custom; I’ll end up coming back to that later.

Taking the code from the current version, I wanted to reduce the non-functional “skeleton” falconun.cpp driver (the one coded by Mark and assigned the task of emulating this hardware) to its bare fundamentals by building with only the ROM loading modifications from the older code before continuing.

I successfully compiled MAME after removing everything and configuring the driver to load the ROM data in the way shown by the older code. A couple of ROMs were different, there was mention of this in the prior discussion and assurance that it wouldn’t matter.

One of the different ROMs was a "pal" and was not mentioned anywhere else in the file, so I REM’d it out. The other was the ROM for an 8035, which was more concerning because it was referenced and could cause issues in the future if the newer ROM was badly read, but for the time being I replaced the file I didn’t have with the ROM from the falconun.cpp driver found in the newer code.

0024.png

The next problem was prioritizing tasks, which required knowing what was necessary to get this game up and running at all. By reviewing the previous code, I discovered that sound communication was one-way, and my first target was getting a video display, so I didn't have to worry about it for the time being. That was eight emulated CPUs and support chips that I didn't need to worry about just now.

The 8035 mentioned in the code was also not connected by glue logic to anything else, so unless this was in a less playable state than advertised, I wouldn't have to worry about it for the time being either. This was a relief because that was the ROM that differed from the previous file. Could it be that the older ROM referenced was a bad read, explaining why it was never connected to anything?

The only parts I had to concentrate on in order to get anything on the screen were the core 68000 Central Processing Unit, an MC6840 Programmable Timer Unit, and the custom video logic drawing to four screens.

Since the MC6840 and 68000 are ubiquitous components, it was easy to locate examples of how to include them into a new styler MAME driver. Likewise, learning how to add more than one screen was easy because MAME has a lot of multiscreen games. I had assumed I would need to create a “layout” file because the old code made reference to one and it hadn’t been supplied, but without further change I was able to build MAME in this configuration and it displayed 4 screens side-by-side, without any graphics being drawn to them for now.

0000.png

The way that MAME handled the vertical blanking callback had changed between the code that was provided and what I could see in the new versions. The new codebase required a callback for every screen, whereas the old code was tied to the MC68000. All of that made sense, but the old method didn't, and once again, there were enough examples of how to adjust to the new method to be able to create stub functions.

By now, I had used more recent examples to reconstruct all the glue logic in the old code, leaving only the system-specific visual logic to transfer. I knew that if I had done everything right, I should be able to see the game running after the next step.

The next section was the simplest of all because, aside from the modifications to how everything glues together, not much has changed in MAME, and I was able to transition over the outdated video processing with a few small adjustments. I didn’t fully understand the code here, and I could see why the code's creator referred to it as "funky" in some of the associated comments. I wanted to understand the code rather than just moving it across, so I took some time out to study it.

Drawing pixel based sprite graphics from vector line definitions to a screen buffer was something I had never seen before when looking through the MAME source but is what the code I was studying was trying to do. Everything drawn to the screen was made of lines, specifying a start position, a length and an angle. For 20th century arcade hardware this was obtuse, I’ve done homebrew for a number of legacy platforms and never encountered anything like this.

Additionally, all of the line definitions are hardcoded in ROMs, so this esoteric design would not even have been suitable for 3D wireframe games or games that requires scaling because the individual points cannot be moved by the software, only the entire sprite or model.

0013.png

I also noted a comment in the existing code saying the implementation was incorrect, and looking at it, the usage of arithmetic divisions rather than shifts seemed excessive. I have worked for platforms from the 80s, and that was simply unheard of. I wouldn’t know how incorrect the implementation was until I had it building again though, and was hoping it wasn’t too far off.

It would not be long until I knew, it took me less than an hour to port the logic, and now that I had a display, I could see the game operating in the MAME build I was putting together. The game was running, this was a big deal, even though there was no sound and no inputs because those sections of the code had not yet been moved across.

I made a mistake when I stated before that the ROM loading mechanism was the only part that was compatible across the old and new MAME sources. The input port structure could likewise be relocated straight over without the compiler even flinching, I’d just overlooked it at the time. To handle how MAME reads the input ports, a few adjustments were required, but once again, there were so many examples of how to accomplish this in the code that it was simple.

I could now gain a sense of the game by coining in any one of the four players and guiding the spacecraft around.

What I had in front of me was a four-player, four-monitor arena battle with full eight-way scrolling and AI drones for players not present, this would have been revolutionary in 1986. There were a few visual flaws catching my eye, likely caused by that "not accurate" statement in the line drawing code I’d observed earlier, minor though.

0000.png

The elephant in the room now was the sound, or rather lack of sound.

In terms of how MAME was implementing OOP code, sound support was the most complicated aspect of the original file. A "device" was declared in the file and instantiated eight times, giving each player two sound output channels. An MC6808 CPU, a 6821 PIA, an HC-55516 for sampled speech, and an 8-bit DAC for general-purpose noises were required for each of those instances. That's more hardware than the rest of the game, and depending on if the hardware engineers intended to find a method to reduce it later, it seems either over-engineered or under-engineered. This was a prototype, but that isn’t rational design.

A clinical investigation into the MAME sources showed that the Williams sound system was a close match for what could be found on The Predators. Even so, those games only used a single instance of the hardware and wouldn't help me figure out how to port this device structure in a way that would allow eight instances of the same specification. Casting a wider net I was able to locate examples of how to construct devices in the newer code allowing me to mimic what was in the older source.

The newer falconun.cpp found in MAME also assisted here. Original author Mark had incorrectly identified the sound processor as the main processor, but also showed how to connect an “input merger” device, which was absent in the older code. Using the knowledge gained from both these studies I was able to port the sound handling across.

0023.png

In summary, I was able to recreate the code using what I could discover in the newer MAME and comparing it to the older sources. After a few crashes, where I was able to figure out what I had done incorrectly by using Visual Studio's debugger and breakpoints, I had the game running with sound, but it sounded awful. I double checked my work and was confident in it, so I believe these issues were present in the code provided.

Improving the Emulation

The HC-55516s were producing silence, prototype or not, I didn't think that was intentional. The spot effects were functioning, but there was no speech. It took some time to figure out how to fix this.

I’d replicated the existing Williams sound solution for the HC-55516 connections, and my work appeared to be functionally identical to the previously supplied C code. Resolution was simple enough, the clock and data lines coming from the PIA had been flipped, although this took a long time to figure out using the MAME debugging and logging features. I was now sure this could not have worked in the source that had been provided. Speech now played through the HC-55516.

The speech still sounded awful though. Every announcement was chopping out early.

0015.png

I had noticed previously that the game timer was running quickly rather than counting in seconds and although I didn't give it much thought prior to sound being added, I had a suspicion it might be connected.

The MC6840, which is literally a dedicated timer chip, is what drives game timing. MAME had it set to 1Mhz, and reducing it did improve the quality of the sound, and the in-game timer. Another dive into the MAME code revealed drivers operating the chip at the main system clock divided by 10, in this case 8Mhz divided by 10, or 800Khz.

Keying in 800Khz not only caused the timer to count seconds correctly, but it also stopped the speech samples from ending prematurely. This furthers my believe the source I’d been provided with didn’t have working speech at all, because this was such an obvious and simple fix.

I had now developed working emulation for a game with functional visuals and audio that could be played by up to four players. Good enough, but I wanted a greater challenge.

Even though I was certain that my creation was superior to that offered for the older MAME version, it wasn't flawless. There were still the small visual issues, and all of the players' audio channels were coming from the same set of stereo speakers rather than a speaker for each player.

0024.png

I had a USB soundbox in storage with support for 7.1 output, and MAME just added the capability to route sound channels to more than two speakers [reference 6].

Doing the math, with the USB card I had 8 output channels I could use from the development laptop, and I was working with a game featuring 8 audio channels. My target was therefore to output each of those audio channels to its own speaker. I had to proceed cautiously however since, if I've learned anything from exploring MAME over the years, it's that new features seldom first function as intended and this was a recent feature.

This proved to be no issue at all however. Recent work in MAME had added multi-speaker output to the 3D NeoGeo “hng64” emulation and using that I was able to see how it should be done.

I lacked information on the original cabinets to determine whether the game was intended to send audio to four stereo pairs or if those pairs were mixed down to four mono speakers, but after listening to what was sent to each channel, I decided to go with mixing down to four even though it was possible to output to eight individual speakers. I’ve left the option to build with both configurations in the code, but there doesn’t appear to be logical stereo separation with eight.

Once again working with MAME had proven unexpectedly easy. The greatest challenge was still to come though, improving the graphics.

I'll be honest with you: I tried to improve the graphics, but I didn't succeed. I eliminated the unrealistic division in the line drawing code, however this simply made the image worse. By adjusting some of the other code, I was able to make it closer to what was previously shown, but it was still incorrect because there were still single pixel gaps, albeit in different locations. I tried many more solutions but every time all that happened was the gaps appeared in different places.

I foolishly believed that fixing this would be easy: simply go through each sprite definition, identify the lines that are drawn incorrectly, identify a pattern, and make the necessary corrections. I couldn't have been more mistaken. Tens of lines at various angles with an absurd amount of overdraw are needed to construct every sprite definition used by the game. I'm not sure if these were created by a computer or if the graphic artists simply added additional lines haphazardly until the sections they desired to fill were completely covered. I’d never considered before how many different ways there are to rasterize a line from a vector.

0013.png

After analyzing this for a few hours, I now consider myself fortunate that I wasn't the one decoding it in the first place, and that I could rely on the provided code for a somewhat accurate approximation. I've never seen anything so contrived in my life. My family call me as a cyberwitch, but this was an insane level of silcon dark magic for which I was unprepared.

Good Enough for now.

Playing The Game!!

Since The Predators isn't meant to be played by one person, I invited some friends over for Christmas, hooked my laptop to the guest room's 55-inch 4K TV, plugged in the external soundbox, four speakers, and four Xbox pads. It was time to start playing.

It must have been the first time four people had played this game head-to-head in forty years, and gathered around the table was me (Lysi), Wizard, Dan, and Ant as Eagle, Falcon, Condor, and Hawk respectively in a galactic battle to determine who would reign supreme as the apex predator.

And even though none of us had ever played The Predators before, the nostalgia hit didn't let us down. It was the memories of first playing something new while gathered around a TV with friends.

The game plays at 15 frames per second, which recalled our initial experience with GoldenEye on the Nintendo 64. 15 frames per second means the screens will redraw every four frames, you can see this if you single-step, and while that might sound awful by modern standards we adjusted to it back then and could adjust to it now without it souring the experience.

The magical feeling of nostalgia was true for the adults at least, the kids present in the household observed in bewilderment as we occupied the gaming TV for a few hours. They’re of the age and belief that Fortnite has poor graphics so couldn't comprehend how we were enjoying a game with such lo-fi visuals and sound, the latter which they compared to a malfunctioning security alarm. I can see where they’re coming from with that, working an arcade in the 80s must have been torture for the ears, but it remains nostalgic.

At least by the rules we had established, Wizz emerged from our tournament victorious.

In The Predators, you buy time with your coins, but you can extend that by doing well, with a time bonus for moving up the ranks thus allowing a seasoned player to continue playing and taking on new challengers. Wizz consistently survived for the longest time, and got the highest scores.

0009.png

All four ships operate in the same manner, nobody has an advantage, Wizz was just better at the game than the rest of us.

The game is unusual because it’s ongoing, a new player can join at any time at the lowest level and be dropped straight into the battle arena.

Running out of time throws you out of the game and replaces that craft with an AI drone once more, but you can add more coins at any point to extend your time, we chose not to, opting to all start with 10 minutes. Anybody who dropped out was allowed to rejoin with zero score and the lowest rank.

I'll accept a fair defeat because Wizz is the one who originally introduced me to MAME and plays retro games more frequently than the rest of us. He’s just a better, more observant player and was the first to notice that each player's health is represented by the size of the circle inside the ship, so was able to easily pick off of the weaker players following our own skirmishes during the first period of play.

As a social experience had it been released in 1986, this would have been the grandfather to games like Fortnight; a multiplayer PvP battle arena where each player was supposed to have their own dedicated set of controls and display. There isn't much to the game compared to modern offerings, just one arena and a few set-play moments “increased leech activity” requiring you to concentrate on something other than the players you’re fighting, but you can see the DNA of so many modern online games.

I regret not connecting this to four monitors. The documentation provided with MAME states that MAME supports it, but the laptop I was using did not. Hiding behind clouds for a stealthy attack is one of the gameplay elements, and it is less effective when you can see your opponent's screen. For the most part, we were courteous enough not to look, so it wasn’t a deal-breaker.

The Predators isn’t a perfect game, but we found enjoyment in it and with a little more refinement it could have been a pivotal game. In the last month MAME emulated a game called Jammin from Atari, also from the middle of the 1980s [reference 7], which also failed to release.

0010.png

Williams’ game represents something similar, an idea too ahead of its time while also appearing dated in its presentation. It can’t have helped that Sinistar was the most direct visual comparison, but that was a fluid 60 frames per second with stronger visuals and audio despite coming out 4 years earlier. The game design here was pushing boundaries, but the execution wasn’t quite there yet and in the superficial world of arcades presentation often mattered more than ideas.

Finishing Up

I worked on improving the code for the remainder of the day. The singularity when it comes to code quality is pride, and if I was to release what I had to the public, which was my goal, I would need to tidy it up and bring more of it to the standard expected by MAME.

What I had created was a translation of an old MAME source into one compatible with newer versions. Functionally that was fine, but still present a lot of outdated design patterns.

The bulk of the code could be tidied and reduced thanks to device finders, device arrays, templates, and eliminating runtime lookups. Although C++ is less performant than plain C, it is cleaner and easier to work with so most of the tidy up work was pushing more C++ patterns over C ones. I wanted to ensure a good user experience, so gave everything the player would see friendly names too; routing sound channels and screens is easier when they’re named after the player cabinets. NVRAM support was absent too so was added, player scores and settings get saved as they should.

0006.png

When I compare this work to regular coding, I am impressed by the brilliance of folks who figure out how these gaming boards operate. The glue side of things was simple to understand at a code level, but I couldn't have done this without the pre-existing functions to handle the drawing, nor would I have known how to deduce the connections between components without the many demonstrations in MAME and the code provided.

0005.png

While porting provided me with a well-defined objective, creating something from nothing would have been a completely different experience. I can't emphasize how much credit folks who figure out how to perform hardware reversing work from breadcrumbs deserve. A large portion of my work life has been in banking and finance and while that pays well a chimpanzee could do it. MAME requires a different level of thinking, you’re not coding to a specification, you have to figure out what to code, not just write the code. Credit to Angelo, David, Mark, and Philip here because without you this would not have been possible.

I wish I had more time to devote to MAME. The code is simple to comprehend and fun to work with after you get past the initial annoyances and abrasive management team, but outside of seasonal holidays there isn't enough time between being a housewife and working in a field where every day is part of the crunch. I had the opportunity to push myself over the Christmas holiday, and I would advise others to do the same given the chance. Nothing compares to reviving a 40-year-old game and knowing that others will also be able to benefit from what you’re doing.

Could there be more old unpublished files that just need upgrading to the latest code? Is that the fate Vertexer met? Updating old code isn't an excessive challenge as I discovered so if old support is languishing somewhere for that too I would look at it.

0000.png

The Goods

After all of that, the downloads are located here at the bottom of the page. The executable is built on top of the most recent MAME version, 0.284. To retain compatibility with a current MAME set, the anticipated ROM has been left as falconun. Double-click the program after placing falconun.zip from an existing MAME set in the roms folder, and just start playing. A secondary source file has been provided with the set renamed.

I'm confident that MAME will take the code from here and incorporate it into the 0.285 release if you don't trust the files I'm providing.

Downloads

binary

source code

References

[ref 1] http://www.retrokade.com/cabs/predators.htm

[ref 2] https://github.com/mamedev/mame/commit/1f6fc6b7eb239dc83545d05525c87fcfd97a9209

[ref 3] https://github.com/mamedev/mame/pull/14659

[ref 4] https://docs.mamedev.org/initialsetup/compilingmame.html

[ref 5] https://github.com/ScottTunstall/BuildMameWithVS2022/blob/main/README.md

[ref 6] https://www.mamedev.org/?p=552

[ref 7] https://www.timeextension.com/news/2025/12/ataris-lost-80s-precursor-to-beatmania-has-been-recovered

Merry Festive Season and New Year to all!

  • Lysi (Lizzy)