I usually see retro-gaming projects using tiny screens with a fair number of pixels (64×64) but what I really like is the look of making every pixel count. With this in mind I built 1-Pixel Pac-Man, the classic coin-op experience but with characters that consist of just one pixel. Playing a throw-back like this wouldn’t be the same without some vintage controls so I picked up an Atari joystick, patched it into a microcontroller, and started coding. Check it out:
This piece of hardware made the project build really easy: the Smartmatrix. [Louis Beaudioin] developed the Smartmatrix and it’s been in the Hackaday Store for a while now. The display module itself is a commodity item that is used in LED billboards. There are shrouded headers on the back of the panels, to the left and right sides, which allow them to be daisy chained. The Smartmatrix PCB plugs into one of these shields, provides a soldering footprint for the Teensy 3.1 which drives the display, and gives you the wiring to connect screw terminals from the PCB to the power terminals on the module. Why the need for beefy power jumpers? At full white the thing can draw about 3.5A — don’t worry there’s a power supply included in the bundle.
Also integral to making this look good is the diffuser panel which is frosted acrylic. The Smartmatrix is designed to be housed in a shadowbox frame; it even includes a frame backer board with a cut-out for the Teensy 3.1 so it can be programmed without opening the thing up. I like looking at the guts so I’m leaving my free floating until I come up with an interesting way to mount everything as one unit.
Programming Pac-Man from the Ground Up
If you haven’t looked into it before, the ghost AI and gameplay details for Pac-Man are absolutely brilliant. [Toru Iwatani] did a masterful job with the original, and you should take a look at all of the analysis that has been done over the years. The best collection I could find was the Pac-Man Dossier and I based most of my code on the rules described there.
Basically the ghosts have two modes, chase and scatter. The modes set the enemy targets differently; to points at the four corners of the board in scatter, and to points relative to the player in chase. The relative part is key; only the red enemy actually chases you. Another one of them looks at the red enemy’s distance and angle, and targets the reflection of that vector. Really easy, really clever, and results in enemy behavior that’s believable. It isn’t just the enemy movement, little touches like a speed penalty (1/60 of a second) for each dot the player gobbles up means the enemies can catch up if you continuously eat, but you can escape by taking the path already-eaten.
Library, DMA, and Extra Hardware
The hardware and software running the Smartmatrix made the display portions of the project really simple. First off, the Teensy 3.1 is fast, running at 96MHz in this case. Second, it has Direct Memory Access (DMA) which [Louis] used in the Smartmatrix library. This means that driving the display takes almost no CPU time at all, leaving the rest for your own use. This example of a game is under-utilizing this power… it’s totally capable of full-motion video and calculating amazing visualizations on the fly.
The PCB hosting the Teensy 3.1 breaks out several pins to one side. I’m not sure what I’ll add in the future so I actually used the extra surface-mount IO pins on the bottom of the Teensy to connect the Atari joystick (which is simply a set of switches). The are enough pads for two joysticks so I used pin sockets to interface the Teensy to the PCB so that I can get to it again later.
The kit also includes an IR receiver and remote, and also a microSD card to loading animations (there’s an SD socket on the PCB). The bundle in the Hackaday Store is a kit you solder yourself, but [Louis’] company, Pixelmatix, has a Kickstarter running for fully-assembled versions that come with a black remote and sound-visualization hardware.
The game is fully working, but there are a few key things that I really want to add. The Teensy 3.1 has a single DAC pin available. I’m fairly certain the original coin-op game had mono audio. It should be possible to reproduce the sound quite accurately with this board. That would really make the project pop.
There are also a bunch of touch-ups that need to happen. I’d like to add an animation when the player is eaten by an enemy, and a countdown before the level restarts. The score, shown in binary on the right column, should be scrolled out in decimal when the game ends, and what’s a coin-op recreation without a high-score screen?
37 thoughts on “1-Pixel Pacman”
Great idea Mike!
Do you mind if I make a iPad copy of this game? ;)
Be my guest… But write about it on Hackaday.io?
As Mike mentions, the 1-Pixel Pac-Man game doesn’t show off all the graphical capabilities of SmartMatrix. The driver in the SmartMatrix Library refreshes the panels at 120Hz with 36-bit color so graphics look really good especially subtle changes like fading to black. There’s plenty of CPU cycles left over after refreshing, so you can use FastLED to draw patterns on the fly, or decode Animated GIFs from an SD card. This project on Hackaday.io really shows off what you can do with SmartMatrix:
I’ve been thinking about writing an article on how I used DMA to automate the time-sensitive updates for SmartMatrix and get 36-bit color using the Teensy 3.1 when normally these panels require an FPGA driver. If this is something you’d like to read on Hackaday, please reply to this comment so I know there’s some interest.
There is interest.
I was thinking of doing something similar with an ARM core DMA. So save me on reinventing the wheel?
Which ARM? The Library is open source, so you can take a look at the code and use it if you like. I’m not sure how dependent it is on the Kinetis K20 DMA controller. I know it can’t be ported as is to a Kinetis Cortex-M0 (Teensy LC) which has a simpler DMA controller.
Most of the DMA code is in here:
I hope an M4 would work for cheapness. For more details on the project, I’d use a 7″ TFT LCD with lots of pixels, so I’d need possibly more processing. But it only does some basic image displaying, like an LCD photo frame. I figured I’d store some data on microSD and use SDIO + DMA to get at it quickly.
I have a hackaday.io project on it. It’s the 7″ Nametag.
I think this Teensy 3.1 TFT library is a better place to start than SmartMatrix:
I’m not sure if that library is using DMA, but it’s really fast regardless! This article and looking at the source code for the OctoWS2811 library is what got me started with DMA, then read the DMA section of the K20 reference manual to figure out the rest.
Gorgeous piece of retro. 1-bit MAME, anyone?
As well as using simple, slow, easier-to-emulate 8-bit processors, and very little RAM, old arcade games generally had a tile-mapped background (if they had a background) and hardware sprites. This means simply reading the tile RAM and the sprites gives you the location of objects in a very easily broken-down way. IE read Pac-Man’s tile RAM, for each tile that’s background, use a black LED. For each maze tile, use a blue one. Read the ghosts’ and Pac-Man’s screen locations, divide for by the resolution of the screen / number of LED pixels, and put them as coloured dots appropriately. The bitmaps for the tiles themselves, you ignore. My point being simple tile-mapped displays like this make the job of using an LED grid like this a lot easier!
Not sure if an AVR chip could emulate a 6502 / Z80 fast enough. It probably could, at 96MHz. The Teensy’s 64K RAM is enough to hold the emulated system’s RAM, plus the few variables you’d need for emulating. Or just use an ARM, plenty of power there.
With the right custom code for each display model, and the simple matter of choosing a colour of LED for each tile, you could probably emulate a ton of early 1980s arcade games, and more importantly, have an actually playable display just on an LED grid. MAME, on an LED grid, with a choice of games, running the original code, would be excellent!
You could even do sound, there was a 74 series tone generator a lot of early machines used, just a few square-wave tone generators.
Then there’s the 1970s games, though they were often fixed-logic, monochrome, and pretty boring.
Oh, Teensy IS an ARM. Well then.
There’s a new movie coming soon, named Pixels and the trailer features giant Pac Man. Coincidence?
Oh, there bloody would be. “DIRT! The next movie from Pixar, starring clumps of dirt! Starring Eddie Murphy basically just playing himself, or some fat asshole from a sitcom doing exactly the same thing. Or, heaven help us, Jack Black. In 4D! At cinemas!”
Really nice! And this LED panel with the diffuser look very good.
Thanks! The diffuser material is called Acrylite Satinice, and I show where to get it in the first step of this Instructable:
It’s really great for LED projects as it transmits nearly 90% of light but does a good job diffusing as well.
Nicely done video, and although the HaD store sells that (or extremely similar) display and it’s sort of an ad it’s a honest ad since it’s just showing the truth and features of the display..
In fact I don’t even think the HaD store is mentioned. Which is sort of amusing.
Mind you it is rather pricey for a coarse LED display in the HaD store IMO, but that’s just how it sometimes is with these things, and money has got to roll to keep the economy going.
“In fact I don’t even think the HaD store is mentioned”
You missed the direct link to the HaD store in the second para.?
I was referring to the video of course.
But good point, the text does mention it as you say. And I sort of stand corrected in that sense.
I think I’ll port the SDL version to the TI-Nspire!
Why don’t you give it some Lua love? :P
Because it’s already written in C and uses SDL, so porting is trivial, just need to backport it to SDL 2.1 and other misc. changes.
Exactly, trivial. Not as much fun ;P
I’m working on mine with the Raspberry Pi.
Did you simulate the glitch with the Pinky ghost AI? Or did you correct that? And don’t forget about the kill screen.
I think the glitch you’re asking about is the array index overflow, and yes I implemented that.
I don’t have a kill screen yet. Only about 90% of the ghost AI is implemented. I need to make ghosts that have been eaten jump to 100% speed when going back home, I also need to add Cruise Elroy logic. The bones are there for it, just need to find the time and I’d rather add some death animations, pauses between restart, and high score stuff first.
Oh, HaD original content. I like it and I actually get it – the series by Elliot Williams and starting one with Bill Herd are great ones – and I really appreciate it. Keep going, please.
Thanks! We all love doing the original content. It’s just a matter of making the time but that’s true for all hackers, right?
Fully agree. Super story, Mike! Thank you.
I love those panels. I mentor an FRC team, and helped the kids build a snake game for a 3×3 display and a portable one.
We used the LEDScape library which uses a Beaglebone Black, and can drive up to 32 panels.
Wearable snake game – that’s awesome!
Are you using a USB portable charger pack for power on the portable display, or something else? What’s powering the portable display, also a Beaglebone Black?
Yes, there’s a 5000mAh usb charger powering the portable display. It lasts between 4-8 hours, depending on how bright the display is being driven.
Also a Beaglebone Black. Our team ended up with 2 last year, but hadn’t found a use for them until playing with LEDScape. All of the programs running on it were written in PyGame, so moving to a Teensy wouldn’t have been simple.
What’s the counter-looking thing in the lower right corner for?
I believe that’s the score in binary.
He should ditch the joystick and control the game with tilt sensors!
That’s awesome! I hope you’ll put it in a tabletop/countertop enclosure that resembles the upper part of a vintage Pac-Man arcade cabinet. :)
Definitely one of my favourite uses of those panels….
Please be kind and respectful to help make the comments section excellent. (Comment Policy)