The Best Kind Of Handheld Gaming Is Homemade

[CNCDan] previously dabbled with Raspberry Pi CM4-powered gaming handhelds but was itching for something more powerful. Starting in May 2023, he embarked on building an Intel NUC7i5BNK-powered handheld dubbed NucDeck.

As he goes over the feature list, it sounds like a commercially available console. A 1024 x 600 screen provides a good balance of fidelity and performance. Stereo-chambered speakers provide good front-facing sound. Two thumbsticks with gyro aim assist, two hall effect triggers, and many buttons round out the input. Depending on the mode, the Raspberry Pi Pico provides input as it can emulate a mouse and keyboard or a more traditional gamepad. A small OLED screen shows battery status, input mode, and other options. This all fits on four custom PCBs, communicating over I2C. 6000 mAh of battery allows for a decent three hours of run time for simpler emulators and closer to an hour for more modern games.

The whole design is geared around easily obtainable parts, and the files are open-source and on GitHub with PDFs and detailed build instructions. We see plenty of gorgeous builds here on Hackaday, but everything from the gorgeous translucent case to the build instructions screams how much time and love has been put into this. Of course, we’ve seen some exciting hacks with the steam deck (such as this one emulating a printer), so we can only imagine what sort of things you can do once you add any new hardware features you’d like.

Continue reading “The Best Kind Of Handheld Gaming Is Homemade”

Custom Aluminum Monitor Stand For The Home Office

Monitor stands vary wildly in price, from a few cents for a pile of books from a thrift store to hundreds of dollars. One trendy style, as [Steven Bennett] puts it, is the “General Grievous,” with adjustable arms splayed around a central pole. While effective, it is not particularly aesthetically pleasing. [Steven] set out to make his monitor stand out of extruded aluminum.

[Steven] started with a cantilever design with a VESA adapter and a c-clamp. With some 3D-printed adapter brackets, he could attach them directly to the tracks in the aluminum. Of course, the 3D printed parts, while great for prototyping, might not be the best choice for the loads he was planning on. He sent it off to a fab to get some powder-coated steel parts. After using it for a few months, he revisited the drawing board. Moving away from the cantilever with an offset center post, he switched to a single 1×4 piece of aluminum. This allowed him to create 3D-printed attachments to hold his headphones, flash drives, and cables. A build guide is available online, as well as printable add-ons.

While it doesn’t have a built-in computer like this glorious wooden stand, we can’t deny the utility or the aesthetic of the aluminum version.

Video after the break.

Continue reading “Custom Aluminum Monitor Stand For The Home Office”

Ordering Pizza While Racing

As [Matt Stele] prepared to bike a local 300-mile (~480km) race in addition to training, he had to prepare for food. A full day of riding was ahead on gravel trails, and one of the best options for him was Casey’s General Store pizza. However, as it was a race, other riders were much faster than him. So, all the hot slices were gone when he arrived. With the help of a serverless GPS tracker, some cloud lambdas, and some good old-fashioned web scraping, [Matt] had a system that could order him a fresh pizza at the precise moment he needed. Continue reading “Ordering Pizza While Racing”

WiFi, PWM Backlight, And Graphics On Updated Chumby Kernel

For some, the Chumby was a peek at what could have been. That vision never died for [Doug Brown], and he has been working tirelessly on bringing mainline Linux kernel support to the customizable smart display. He has posted several updates but recently got graphics and the PWM backlight working.

Of course, we covered when [Doug] first started working on the new kernel, so it’s high time we revisited the progress. The WiFi hardware uses a Marvell 88W8686 chipset, which talks over the SDIO bus, so it’s a matter of convincing the libertas driver to talk to it. With a USB to Ethernet adapter, [Doug] could boot new kernels over NFS, so he didn’t have to walk over to swap the SD card. After dealing with an unhandled fault when trying to read the SDHCI_HOST_VERSION register, [Doug] had access points showing up in NetworkManager but could not connect. As a nasty hack, he temporarily removed the interrupts and switched to polling in the driver. While that worked, it would never get upstreamed. A critical interrupt was being dropped, and commands went out of sequence. A second, perhaps ugly hack, read a register after acknowledging an SDIO interrupt, which seemed to work. But it was still a hack, and [Doug] wanted something cleaner. In a blind stroke of luck, he found the errata online and noticed that it mentioned that an interrupt could be missed when a signal was asserted. After following the workaround with a lot of head-scratching and deep diving, he had a fully working WiFi driver.

Graphics were a more straightforward endeavor compared to WiFi. He enabled the simpledrm driver (similar to simplefb) but using Direct Rendering Manager. He had a working panel that could run Qt apps by adding the frame buffer to the device tree with the correct compatible string, registers, and data. However, there was a Vivante GC300 graphics accelerator onboard that he wanted to use. A driver for Vivante GPUs already exists in the kernel, but after enabling it, the driver detects the GC300 and then starts complaining. He discovered that older revisions of the GC300 (like the ones found in Chumbys) mapped registered at different addresses and didn’t set some bits in their idle registers. Of course, just loading a GPU driver isn’t quite enough. He modified an x11 server that supported Vivante accelerators to support the GC300.

For hacking purposes, [Doug] set the backlight GPIO high. While easy to see, perhaps not the best for a device meant to blend in. The PAX166 comes with PWM hardware, though confusingly, it has two PWM modes for pin 84. PWM1 and PWM2 share some common clock and reset bits in a decidedly undocumented way. PWM2 doesn’t work until you configure and then turn off PWM1. However, the backlight turned off once out of UBoot and into Linux. Linux re-initialized the hardware too quickly, causing the device to freak out. This was solved using the abrupt shutdown register.

It’s a journey through debugging, Linux internals, and device tree hackery. Perhaps the most incredible thing is that these changes are submitted for upstreaming to the Linux kernel, with many landing in Linux 6.2. While it’s a shame¬†new Chumbys aren’t being made, making your own smart display has never been easier.

Accurate Cycle Counting On RP2040 MicroPython

The RP2040 is a gorgeous little chip with a well-defined datasheet and a fantastic price tag. Two SDKs are even offered: one based on C and the other MicroPython. More experienced MCU wranglers will likely reach for the C variant, but Python does bring a certain speed when banging out a quick project or proof of concept. Perhaps that’s why [Jeremy Bentham] ported his RP2040-based vehicle speedometer to MicroPython.

The two things that make that difficult are that MicroPython tries to be pretty generic, which means some hackery is needed to talk to the low-level hardware, and that MicroPython doesn’t have a reputation for accurate cycle counting. In this case, the low-level hardware is the PWM peripheral. He details the underlying mechanism in more detail in the C version. On the RP2040, the PWM module can count pulse edges on an input. However, you must start and stop it accurately to calculate the amount of time captured. From there, it’s just edges divided by time. For this, the DMA system is pulled in. A DMA request can be triggered once the PWM counter rolls over. The other PWM channel acts as a timer, and when the timer expires, the DMA request turns off the counter. This works great for fast signals but is inaccurate for slow signals (below 1kHz). So, a reciprocal or time-interval system is included, where the time between edges is captured instead of counting the number of edges in a period,

What’s interesting here is how the hardware details are wrapped neatly into pico_devices.py. The uctypes module from MicroPython allows access to MMIO devices such as DMA and PWM.¬†The code is available on GitHub. Of course, [Jeremy] is no stranger to hacking around on the RP2040, as he has previously rolled his own WiFi driver for the Pico W.

Decompiling Sonic Runners

Usually, when you hear about games being decompiled and rebuilt, the games are often decades-old relics, loving and saved from the ravages of time. [MattKC] recently set out to decompile the 2015 game Sonic Runners.

The game was a 2D endless runner released on mobile platforms. Despite getting praise for the gameplay, it received mixed reviews for the pop-up ads and pay-to-play elements. A little over a year later, the game was discontinued. However, the game required a constant online connection, so once the servers were offline, it rendered the over five million downloads unplayable.

A team of developers worked to reverse engineer the server, and with a little bit of binary hacking, the client could be patched to connect to a community-hosted server instead. However, as phones with notched displays came out and suggestions for improvements stacked up, the community realized a new client would bring immense benefits. Compared to many decompilation projects, Sonic Runners was pretty easy as it uses Unity, which means most of the code is in C#. Unfortunately, the build of Unity used by the game is from 2012, meaning many of the tools designed for much later versions of Unity were inoperable.

However, one native code library called UnmanagedProcess was designed to confuse reverse engineering efforts. The library handled AES encryption and communication with the server. Luckily, the library was a later addition, and earlier versions of its functions still lingered in the C# code. Since an open source server already existed, it was trivial to validate the changes. Additionally, all the shaders were in OpenGL Shading Language (GLSL), which meant rewriting them in High-Level Shading Language (HLSL) and checking that they matched the original GLSL when building for Android.

Now the client has new game modes, no ads, and a proper offline mode. The community continues adding new features and refining the game, which is very satisfying. If you’re curious about reverse engineering, [Matthew Alt] can help you get started.

Continue reading “Decompiling Sonic Runners

Where Did Your PCB Go Wrong? KiRI Knows

When working on a PCB design in KiCad, it’s helpful that the files are all text and can easily be checked into Git or other source control. However, stepping back through the revisions to determine where precisely a trace got routed wrong can be tricky. [Leandro] started with a simple script that exported the KiCad project to an image for inspection — over time it grew into a full-blown visual diff tool named KiCad Revision Inspector (KiRI).

The primary mechanism exports the revisions of a KiCad 5, 6, or 7 project to SVG, which can then be compared via a handy onion skin view. As this is a tool written for those using KiCad, shortcuts are a huge part of the experience. A command line interface generates artifacts to view the diff in any web browser. As these outputs have the KiRI tooling baked in, it is relatively easy to archive the output as a build artifact and allow easy access to review design changes.

For the long-time reader, you might remember back in 2018 talked about another diffing tool called plotgitsch (which this KiRI uses for KiCad 5 projects). KiCad has grown significantly in the last five years. It might be time to update our tips to utilize Git better for your PCB designs.

Continue reading “Where Did Your PCB Go Wrong? KiRI Knows”