Homemade Pokie Machine

Disclaimer: This project contains zero pokie/slot machine parts, the machine doesn’t have a coin mech or note acceptor – it can’t accept money and doesn’t payout money. No software is hosted, linked to or shared on this page. This is just a project for personal use, this was simply to see if this was even possible to work. The information here is for educational purposes only.

Contents

Parts

The Cabinet

I found a nice looking flat pack bar top arcade cabinet on eBay. The price was super reasonable, it included a 19″ LCD monitor that had the bezel already removed and the seller wasn’t too far away so I thought, what the hell? A global pandemic has just started and I might as well keep busy…

Once the cabinet arrived and I put it together I thought wow, this would be a cool little MAME box and I understand it was made with the intentions of it being a MAME box, but I had some other plans for it.

The Control Panel

Designing the Buttons

After playing around with the emulator, I knew I was going to have a problem with determining a physical button layout. Not all games have the same button layout, there are different bets, different number of lines and buttons randomly swapping.

I ran every single ROM and took a screenshot of the buttons and compiled it into the largest “iCloud Notes” note ever, in fact it actually ended up alerting me with an error saying I’ve added the maximum number of image attachments and I had to save the last couple to another note…

Because I’m an idiot, I printed all the buttons, cut them out and grouped them to find similarities. The ‘Gamble’ and ‘Take Win’ buttons seemed to always be in the same spot but the ‘Rules’, ‘Spin’ and ‘Collect’ buttons move around a bit.

My final solution was to have a mix of a 5 Dragons and Miss Kitty layout as I personally like both those games. I can always change the inserts later if I want to and nothing changes on the software side of things either way.

I designed a rough version with paper, then changed some things up like adding the suit symbols, adding some colour variations and printing it on a clear sheet.

Mounting the Buttons

I placed the buttons on the panel in the same layout as the emulators buttons – I think this looks nice and is practical. I thought about moving the collect button to the monitors bezel but there wasn’t much space and it would have been off centre (and that would have annoyed me).

I went and purchased a 25mm hole saw (thanks Bunnings), measured it up, marked it out and went to town. I put in all the button inserts (I only had paper copies at this stage) and mounted the buttons in the panel. It was looking good so far!

Wiring the Button Switches

Cabinet Side (PCB Side)

Now I wanted to get some real buttons working. For projects I’ve done in the past, I’ve normally just used an Ultimarc product, but I thought I’d try something different this time. As the Aristocrat emulator already has predefined controls, I just thought it would be easier to assign buttons to them physically. This board is called a “Keyboard Coding Board” by SJ@JX, which I found on Amazon.

Now that I had it in my hands, the first problem arose – they were kind enough to send me pre-made cables that connect the microswitches to the small connectors on the board… But not enough for how many buttons this project required. An easy solution to this problem was to pull the plastic connector off the board leaving the pins exposed. I soldered wires to each of the required pins then used heat shrink so nothing shorts and to keep the connections strong.

The second issue that came about was that there isn’t a common + or – on this board, which means every button requires 2 wires… This was turning into a chunky harness and I hadn’t even wired any of the LED’s yet.

Control Panel Side (Buttons Side)

Following the same colours as the wires soldered to the keyboard emulator, I made the harness that is on the control panel side, with molex connectors for easy removal of the panel (this is also a requirement because of the soldered wires to the board). As Ben Heck always says, “never build something you can’t pull apart” – wise words.

I tried my best to keep everything neat by cutting everything to length, using cable ties and plastic cable tidy. On the board side I kept the harness on the long side so in the event of removing the control panel, there is enough slack on the harness to get it out easily. This also keeps the harness rigid which makes removal and installation of the harness easy (I’m going to have to remove it when I vinyl wrap it though).

The wires hanging out the bottom are for other buttons on the cabinet which are not located on the control panel like the credit button, internal menu buttons and exit. I’ll deal with these later.

Wiring the LED’s

The LED’s that came with the buttons are 12v and the Ultimarc PacDrive LED Driver can only output 5v. Luckily it’s safe to use external 12v with this board as long as you only connect the ground wires and leave the + terminals disconnected.

I ran a common 12v to all LED’s and all the grounds terminate at the PacDrive board. Just like the switch harness, I added Molex connectors for easy removal. I tried to keep is as neat as possible but it still turned into looking like chaos!

Ultimarc PacDrive LED Driver.

As the Dell is a small form factor PC with a 19v power supply “brick” I wasn’t going to power everything of it. So, I used a framed 12vdc power supply as it is more than enough to power all the button LEDs, the speaker amp board and the header LED strip. Because the LEDs in the buttons have a 12v source from the external power supply and it’s ground is from the PacDrive you need to join grounds between the power supply and the computer. My simple solution was to terminate the wire with the screw of the WiFi antenna.

Ground connection between the 12v power supply and the computer.

Software

Maximus Arcade

I found this post on AussieArcade.com from 2015, it explains how to load the ROMs into the Maximus Arcade front end and people also posted their theme designs.

I’d never used Maximus Arcade, I’d only ever used LaunchBox, Attract-Mode, EmulationStation and HyperSpin as front end software on dedicated hardware.

The software didn’t look like it was being actively worked on, but it looked so simple to setup and those other front ends would be overkill for this setup.

Setting Up Maximus Arcade as the Front End

Now this was super time consuming… Did I mention the global pandemic?

Anywho, I started up my Windows 7 VM and installed Maximus Arcade. By default, as you can guess by it’s title, Maximus Arcade is a Front End designed for arcade games. To make this look like it’s a finished product (and I know how to use photoshop so why not?), I needed to give the software a pokie theme with previews of the games so that I knew what each of them looked like. But with little to no information online about these games, I had to do it the DIY way…

My solution – I opened every single ROM, removed the credits, waited until it went into attract mode and took a screenshot of the artwork. Whilst I was there I also took a screenshot of the reels and recorded a short video of the reels in action – now I had enough art to make Maximus Arcade look awesome!

Having never used Maximus Arcade before, I spent a bit of time playing around with the theme editor. I slowly learnt how it worked by editing the default theme until I was completely happy with it.

AutoHotkey

Making The Game Start Fullscreen

Firstly, I don’t use Windows much. All my other computers are Mac’s, Hackintosh’s and Linux boxes – but I have to say, wow AutoHotKey is awesome.

Originally I wrote a simple AutoHotkey script called ‘background.exe’ that launched from Maximus Arcade at the time of loading a ROM. It looks for the active window titled Roms       Screen 1 and when found hit ALT-ENTER which is the shortcut for fullscreen.

This worked fine and I played it like this for a while but it would also hide the on-screen buttons. I knew I needed the on-screen buttons to be visible so AutoHotKey could see them and turn the LED’s on and off – I had to think outside the box.

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
WinWaitActive, Roms       Screen 1  ; Look for active game window.
Send !{Enter}  ; Press ALT-ENTER to enable fullscreen.

AutoHotKey script to make the game appear fullscreen while moving the on-screen buttons to a second monitor

What I ended up doing was writing another AutoHotKey script called ‘move.exe’ – similar to the previous script, it’s launched when loading a ROM, looks for the game window, but this time removes the titlebar and frame, then maximises the window (this looks fullscreen). Once it sees the on-screen buttons window, it moves it to my second monitor (in the exact same location every time).

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
WinWaitActive, Roms       Screen 1  ; Look for active game window.
WinSet, Style,  -0xC40000 , A  ; Remove the window border and titlebar.
WinMaximize  ; Maximise window.
WinWait, MK6 Emulator  ; Look for buttons window.
WinMove, 1571, 475  ; Move window to the second screen.

AutoHotKey script to control LED’s by the colour of the pixels on the on-screen button panel

This script was my ha-ha moment! I found a script here that allowed me to utilise the PacDrive64.dll file and control the PacDrive from AutoHotKeys. In the original script it would turn on the LED as the button is pressed, so I removed the parts referencing button presses and replaced it with code I found here which I modified to look at a single pixel on every onscreen button: if it’s yellow it tells the assigned buttons LED to turn on, if it’s any other colour (black background from emulator not running yet or grey) it will turn the LED off. I’m no AutoHotKeys expert, I just found things online and adapted them for what I needed. This actually worked surprisingly well.

#SingleInstance Force 
#Persistent 
#NoEnv 
SetWorkingDir, %A_ScriptDir%

; Uses of the PacDrive64.dll
; First, Load the Library with DllCall("LoadLibrary", "str", "PacDrive64.dll")
; Then Initialize the PacDrive with DllCall("PacDrive64.dll\PacInitialize")
; To set the LEDs as a whole use DllCall("PacDrive64.dll\PacSetLEDStates",Int,0,UShort,0) - Note (integer, pacdrive ID, short integer, decimal value for LEDs)
; To set induvidual LEDs, use DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,0,Int,1) - Note (integer, pacdrive ID, integer, pin0, integer, 1 means ON)
;
; This program, loads the PacDrive64.dll (which should be in the same folder as the AHK file you ran) and initializes it.
; Then it will refresh the LED output status for all 16 outputs (ie the LED ports on the PacDrive) after reading what the status of the virtual buttons on screen are.
;
; For this program, I used a Ultimarc PacDrive to light up 12v LEDs inside buttons.
; 
; Every 100ms the ChangeLED routine is called from the settimer command and it reads a pixel colour, checks to see if it's 0xFFFF00 (RGB Yellow) and if so, sets the LED port pin 
; to (1) ON. If it is not RGB yellow, then it sets the LED port to (0) OFF.
;
; Original code by Gwarble - THANKYOU!!!
;
; Modified for basic Gamepad/Joypad/Joystick indication by Ramjet - Later to be upgraded to Arcade/RaceSim cockpit
;
; Modified for Aristocrat MK6 Emulator by Shaun Jay.

If DllCall("LoadLibrary", "str", "PacDrive64.dll") 
If DllCall("PacDrive64.dll\PacInitialize") 
DllCall("PacDrive64.dll\PacSetLEDStates",Int,0,UShort,0) "`n`nError: " ErrorLevel
Else 
   ExitApp 
SetTimer, ChangeLED, 100
Return

ChangeLED:
   
   CoordMode, Pixel, Screen
   Pixelgetcolor, Color0, 1582, 504, RGB ;Reserve Gamble Button
   if Color0 = 0xFFFF00
   {
      DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,0,Int,1)
   }else  {DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,0,Int,0) 
   }
   
   CoordMode, Pixel, Screen
   Pixelgetcolor, Color1, 1661, 504, RGB ;Bet x1 Button
   if Color1 = 0xFFFF00
   {
      DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,1,Int,1)
   }else  {DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,1,Int,0) 
   }
   
   CoordMode, Pixel, Screen
   Pixelgetcolor, Color2, 1737, 504, RGB ;Bet x2 Button
   if Color2 = 0xFFFF00
   {
      DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,2,Int,1)
   }else  {
      DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,2,Int,0)
   }
   
   CoordMode, Pixel, Screen
   Pixelgetcolor, Color3, 1819, 504, RGB ;Bet x5 Button
   if Color3 = 0xFFFF00
   {
      DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,3,Int,1)
   }else  {DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,3,Int,0) 
   }
   
   CoordMode, Pixel, Screen
   Pixelgetcolor, Color4, 1893, 504, RGB ;Bet x10 Button
   if Color4 = 0xFFFF00
   {
      DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,4,Int,1)
   }else  {DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,4,Int,0) 
   }
   
   CoordMode, Pixel, Screen
   Pixelgetcolor, Color5, 1971, 504, RGB ;Bet x20 Button
   if Color5 = 0xFFFF00
   {
      DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,5,Int,1)
   }else  {DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,5,Int,0) 
   }
   
   CoordMode, Pixel, Screen
   Pixelgetcolor, Color6, 2065, 504, RGB ;Rules Button
   if Color6 = 0xFFFF00
   {
      DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,6,Int,1)
   }else  {DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,6,Int,0) 
   }
   
   CoordMode, Pixel, Screen
   Pixelgetcolor, Color7, 2144, 504, RGB ;Collect Button
   if Color7 = 0xFFFF00
   {
      DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,7,Int,1)
   }else  {DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,7,Int,0) 
   }
   
   CoordMode, Pixel, Screen
   Pixelgetcolor, Color8, 1580, 568, RGB ;Take Win Button
   if Color8 = 0xFFFF00
   {
      DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,8,Int,1)
   }else  {DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,8,Int,0) 
   }
   
   CoordMode, Pixel, Screen
   Pixelgetcolor, Color9, 1657, 568, RGB ;2 Lines Button
   if Color9 = 0xFFFF00
   {
      DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,9,Int,1)
   }else  {DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,9,Int,0) 
   }
   
   CoordMode, Pixel, Screen
   Pixelgetcolor, Color10, 1735, 568, RGB ;10 Lines Button
   if Color10 = 0xFFFF00
   {
      DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,10,Int,1)
   }else  {DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,10,Int,0) 
   }
   
   CoordMode, Pixel, Screen
   Pixelgetcolor, Color11, 1813, 568, RGB ;20 Lines Button
   if Color11 = 0xFFFF00
   {
      DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,11,Int,1)
   }else  {DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,11,Int,0) 
   }
   
   CoordMode, Pixel, Screen
   Pixelgetcolor, Color12, 1893, 568, RGB ;30 Lines Button
   if Color12 = 0xFFFF00
   {
      DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,12,Int,1)
   }else  {DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,12,Int,0) 
   }
   
   CoordMode, Pixel, Screen
   Pixelgetcolor, Color13, 1970, 568, RGB ;50 Lines Button
   if Color13 = 0xFFFF00
   {
      DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,13,Int,1)
   }else  {DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,13,Int,0) 
   }
   
   CoordMode, Pixel, Screen
   Pixelgetcolor, Color14, 2065, 568, RGB ;Feature Button
   if Color14 = 0xFFFF00
   {
      DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,14,Int,1)
   }else  {DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,14,Int,0) 
   }
   
   CoordMode, Pixel, Screen
   Pixelgetcolor, Color15, 2145, 568, RGB ;Rules Spin Button
   if Color15 = 0xFFFF00
   {
      DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,15,Int,1)
   }else  {DllCall("PacDrive64.dll\PacSetLEDState",Int,0,Int,15,Int,0) 
   }
return

VGA Dummy Plug

Since the AutoHotKey script moves the on-screen buttons to the second monitor I was considering getting a small LCD panel that I could hide in the back of the cabinet. This didn’t seem like the best solution as it adds extra costs, heat and power consumption. I searched online for a software fix, but nothing I found seemed like a permanent solution.

I finally stumbled upon this “VGA hack” that tricks the computer into thinking there is a monitor plugged in. All you have to do is connect 75Ω resistors from the RGB channels to ground. Quick trip to JayCar, got all the things I needed, put it together and it worked! Because it’s a dongle I can always remove it and plug in a real monitor for troubleshooting reasons. Such a cheap and simple solution.

To be continued… (Project is 100% complete now, will add a follow up here).

  1. Yeah that was part of it, and moving states it put it all on the back burner.
    You’ve definitely sparked my motivation again to dive back into it in the coming months!
    All the parts are still in a box in the shed.
    I’ll just have to collect some of the older style plastic notes for the bill acceptor as I won’t be able to program the new ones without shipping it back to GBA Tech.

  2. Getting the lights to work was my favorite part of the entire project 🙂
    Always happy to help where I can, if you get stuck or need help with the LED stuff, don’t hesitate to contact me!

  3. I gave you a follow and message on your linked instagram too. I sent some photos of my decade old project cabinet that I scrapped.

  4. Yeah that’s what I thought.
    I managed to find a download for the newer emulator, but yeah seems a bit hit and miss.
    I have scrapped my old cabinet, it was just a rough mdf mock-up, but I’m looking at buying a counter top flat pack.
    And hopefully I can get your code going for the button lights. Really adds that real touch to it.
    I’m not that good with code, but you solution to the credit input seems like a good workaround.
    Really love your work it’s gave me the motivation to start looking into finally getting a finished product!
    Hopefully I can pick your brain in the future if I need any help with the LED stuff!

  5. Thanks for the kind words 🙂

    I believe the “new” emulator is the same as the one that leaked with the 4 ROMs originally. It also has issues not crediting on every pulse (button press). I’m currently using a credit button and I just bash it or hold it and the credits accumulate. I thought about adding a coin mech or note acceptor to the cabinet to give it a more realistic feel but as you said, it’s a bit of a hit and miss.

    The only other way I thought is by using AutoHotKey to run a script once the credit button is pressed, monitor the memory and look for the string that displays credits, and keep auto hitting the credit button until the number advances then stop. This would ensure that with every button press or pulse on the credit line it would credit the emulator. I never went down this path as I ran out of physical room in the cabinet anyway. But it’s honestly the only way I could think of doing this.

    Do you have any pictures of your cabinet?

  6. Awesome dude. I started making one in 2008 when the initial 4 pack romset come out. I used a keywiz ps/2 keyboard emulator board. I had a bill acceptor too.
    But the aristocrat emulator was hit and miss with adding credits.
    I might revisit this and update with the flashing leds on the buttons.
    Do you find you have to press the add credit button a few times for it to work? Or is the new emulator/Roms pack more responsive?

Your email address will not be published.