<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>HunterDavis.com</title>
    <description>The personal blog of Hunter G. Davis (full-content feed)</description>
    <link>https://hunterdavis.com/</link>
    <language>en-US</language>
    <lastBuildDate>Tue, 12 May 2026 20:54:18 +0000</lastBuildDate>
    <atom:link href="https://hunterdavis.com/feed-full.xml" rel="self" type="application/rss+xml" />
    <atom:link href="https://hunterdavis.com/feed.xml" rel="alternate" type="application/rss+xml" title="Excerpt feed" />
    
      <item>
        <title>Dumber and More Dangerous than Ralph Wiggum: The Dunking Bird Method</title>
        <description>Introduction</description>
        <content:encoded><![CDATA[<h2 id="introduction">Introduction</h2>

<p>Do you remember that episode of the Simpsons where he uses a little dunking bird toy to defraud his employer? Yeah. Like that but with prompts.  Here’s the thing. Some of my coding agents, no matter how “dangerously” I like to live, still stop every 10 minutes, needing my input to continue. I know Ralph Wiggum method doesn’t have this problem, but that supposes you have planned out your project to some degree. Also I’m lazy, and it is easier ask AI to write a tool to do a ridiculous thing than to figure out another ridiculous thing.</p>

<p>If I’m really living the agentic dream, why don’t my agents work while I’m dreaming?</p>

<h2 id="what-is-dunking-bird">What is Dunking Bird?</h2>

<p>Dunking bird is my metaphor for programs which sit outside the interface of agents and act on them externally, repeatedly sending a set prompt until a completion state is reached. It’s also a sample implementation of the concept I coded up today.</p>

<h2 id="what-does-it-do">What does it do?</h2>

<ul>
  <li><strong>Feature 1</strong>: Click-to-capture a window (tested on KDE/wayland)</li>
  <li><strong>Feature 2</strong>: Prompt at a settable interval (1. ; continue; yes that’s a great idea!, etc )</li>
  <li><strong>Feature 3</strong>: test button for confidence</li>
  <li><strong>Feature 4</strong>: Insecure!</li>
</ul>

<h2 id="screenshot">Screenshot</h2>

<p>Here’s Dunking Bird in action:</p>

<p><img alt="" src="/content/images/2026/dunking-bird-screenshot.png" width="600" /></p>

<h2 id="the-story-behind-dunking-bird">The Story Behind Dunking Bird</h2>

<p>I’ve been working on a PS1 version of Johnny Castaway for about a year now.  I have agents doing static analysis and resource conversion, and it’s a pain to have to type “continue” every 10 minutes or so. To that end, I vibe-coded up a tool that’d work for my development environments.</p>

<h2 id="try-it-out">Try It Out</h2>

<p><strong>GitHub Repository</strong>: You can find the complete source code, installation instructions, and documentation on GitHub: <a href="https://github.com/huntergdavis/dunkingbird">huntergdavis/dunkingbird</a></p>

<h2 id="ai-slopportunity">AI-Slopportunity</h2>

<p>Sloppity slop slop, dropitty drop drop look at AI go</p>

<p><img alt="" src="/content/images/2026/dunking-bird-ai-art.png" width="400" /></p>

<hr />
]]></content:encoded>
        <pubDate>Sat, 21 Mar 2026 10:00:00 +0000</pubDate>
        <link>https://hunterdavis.com/2026/03/21/announcing-dunking-bird.html</link>
        <guid isPermaLink="true">https://hunterdavis.com/2026/03/21/announcing-dunking-bird.html</guid>
      </item>
    
      <item>
        <title>A big ole stack of one-off projects in 2025</title>
        <description>I actually wrote quite a bit of code in 2025! While my professional life was centered around AI enablement for my teams and getting the big launch out this year to customers, I did a fair amount of personal projects.</description>
        <content:encoded><![CDATA[<p>I actually wrote quite a bit of code in 2025!  While my professional life was centered around AI enablement for my teams and getting the big launch out this year to customers, I did a fair amount of personal projects.</p>

<p>So this is just a quick hits list for 2025 of some fun personal projects I worked on, all of which have source available, are local-first and do not require a back-end. Mostly javascript, always client-side. Many were written with signifant AI enablement, I’m finding that my AI workflow anymore is comparible to those few years I was leading R&amp;D as an IC developer, only instead of interns and graduate students working with me to refine prototypes, it’s AI. Is it good for our profession? I honestly don’t know, but I doubt it. Is it incredibly fun and rewarding? Yes, 1000% yes.</p>

<h2 id="picocalc">PicoCalc</h2>
<p><img alt="" src="/content/images/2025/picocalc.png" width="400" /></p>

<p>Back in April, I was messing with the default basic interface on my picocalc (pi pico h1), and wanted a better file browsing shell interface.  You can find that here:
<a href="https://github.com/huntergdavis/picocalc">Github Repo</a></p>

<h2 id="inboxzero">InboxZero</h2>
<p><img alt="" src="/content/images/2025/inboxzero.png" width="400" /></p>

<p>Around the same time, I took about 30 seconds to code up a button that throws confetti and plays trumpets, a more visceral inbox zero. Hardly worth mentioning, but again fun :)</p>

<p><a href="https://github.com/huntergdavis/inboxzero">Github Repo</a>
<a href="/inboxzero">Live Link</a></p>

<h2 id="streak">Streak</h2>
<p><img alt="" src="/content/images/2025/streak.png" width="400" /></p>

<p>I’ve had significant health issues this year, and this summer I was struggling with going to the gym every day. I wrote this little app ‘streak’, it bascially takes (or generates) your query parameter and sets a cookie for whenever you press the button, keeping a running log of when you did that thing. Celebratory confetti if you did it less than 1 day prior.</p>

<p><a href="https://github.com/huntergdavis/streak">Github Repo</a>
<a href="/streak">Live Link</a></p>

<h2 id="visualizer">Visualizer</h2>
<p><img alt="" src="/content/images/2025/visualizer.png" width="400" /></p>

<p>I loved winamp 25 years ago.  LOVED IT.  All my music (mp3s), customization, but most of all visualizers!!  I put a record on this summer, and realized that I didn’t have an easy way to load up winamp quickly on whatever system I was on.  So this is just a microphone-input visualizer that supports all of winamps visualization plugins via milkdrop.  Again, client-side only, all javascript.  I find myself using this one a lot actually.</p>

<p><a href="https://github.com/huntergdavis/visualizer">Github Repo</a>
<a href="/visualizer">Live Link</a></p>

<h2 id="solitaire">Solitaire</h2>
<p><img alt="" src="/content/images/2025/solitaire.png" width="400" /></p>

<p>Remember back in Covid, I designed that solitaire variant? I wrote a simulator for it to help play-test and balance, but folks wanted to actually play it.  So, that’s what this is, a webapp to play my weird solitare variant.</p>

<p><a href="https://github.com/huntergdavis/solitaire">Github Repo</a>
<a href="/solitaire">Live Link</a></p>

<h2 id="people-grid">People Grid</h2>
<p><img alt="" src="/content/images/2025/peoplegrid.png" width="400" /></p>

<p>A good amount of my job in engineering leadership is around team formation, run rate management, and organizational design.  When I want to scratch something up real quick, figma is a pretty good tool, but I don’t like to pay for simple tools with too many features, or large corporations. People grid is just a simple org design tool that I use to sketch up team formations and simple team diagrams.  A little rough around the edges, but I end up using this one all the time.</p>

<p><a href="https://github.com/huntergdavis/peoplegrid">Github Repo</a>
<a href="/peoplegrid">Live Link</a></p>

<h2 id="poke-bar-game">Poke (Bar Game)</h2>
<p><img alt="" src="/content/images/2025/poke.png" width="400" /></p>

<p>A good buddy of mine had an idea for a bar game.  It tests your reflexes, then always tells you that you’re too drunk to drive.  Cheeky right? We did it up fun with some graphics and delighters.</p>

<p><a href="https://github.com/huntergdavis/poke">Github Repo</a>
<a href="/poke">Live Link</a></p>

<h2 id="web-flight-flight-sim-concept">Web Flight (flight sim concept)</h2>
<p><img alt="" src="/content/images/2025/webflight.png" width="400" /></p>

<p>I always loved flying games, especially arcade ones.  Superflight is one of my favorite casual games ever made.  I started on a basic web flying game, but later pivoted the idea into asteroid miner. Here’s the original webflight prototype.</p>

<p><a href="https://github.com/huntergdavis/webflight">Github Repo</a>
<a href="/webflight">Live Link</a></p>

<h2 id="psyrunner-mobile-runner-game">PsyRunner (mobile runner game)</h2>
<p><img alt="" src="/content/images/2025/psyrunner.png" width="400" /></p>

<p>I miss flash games, and only feel that lately javascript development is starting to feel like what simple flash games development felt like 20 years prior. There was one, it was kind of based on the forest of endor chase, where you would avoid triangles in a straight line.  This is a modern update to that format, with joystick, mouse, and mobile touch controls so you can play on your phone. Actually pretty fun!</p>

<p><a href="https://github.com/huntergdavis/psyrunner">Github Repo</a>
<a href="/psyrunner">Live Link</a></p>

<h2 id="asteroid-miner-3d-asteroid-mining-arcade-sim">Asteroid Miner (3d Asteroid Mining Arcade Sim)</h2>
<p><img alt="" src="/content/images/2025/asteroidminer.png" width="400" /></p>

<p>I have put so, so many hours into No Man’s Sky. That’s a team that continues to impress, and I keep coming back.  Ironically, most playthroughs I start to build-up, then get distracted and go asteroid mining.  Flying through space, busting asteroids for minerals, upgrading my ship.  It’s just a fun casual game loop.  So, I’ve started to work on a game that is just that, 3d space mining.  Still some rough edges, but by far the most impressive/complex project I worked on personally in 2025. Full joystick or keyboard/mouse controls, graphics are pretty decent, and I make regular updates on Fridays.</p>

<p><a href="https://github.com/huntergdavis/asteroidminer">Github Repo</a>
<a href="/asteroidminer">Live Link</a></p>

<h2 id="2d-js-game-boilerplate-boilerplate-for-2d-javascript-webgames">2d JS Game Boilerplate (boilerplate for 2d javascript webgames)</h2>
<p><img alt="" src="/content/images/2025/2djsgameboilerplate.png" width="400" /></p>

<p>Ever have a game that really sparks your creativity?  Donkey Kong Bananaza was that game for me in 2025. I have so many 2d game concepts I’m going to try out, just based on fun little mechanics they threw in.  To start, I’ve created a simple boilerplate for 2d games client-side javascript (you know… stuff like bounding box, mini-map, joystick support and movement controls.)</p>

<p><a href="https://github.com/huntergdavis/2djsgameboilerplate">Github Repo</a>
<a href="/2djsgameboilerplate">Live Link</a></p>

<p>So, last year I committed to releasing more things that spark joy, and more little projects. I remembered to make space to work on them, but only now am I actually releasing some stuff into the wild. Hey, progress is progress :D</p>

]]></content:encoded>
        <pubDate>Sun, 05 Oct 2025 01:00:24 +0000</pubDate>
        <link>https://hunterdavis.com/2025/10/05/a-bunch-of-one-off-projects-for-2025.html</link>
        <guid isPermaLink="true">https://hunterdavis.com/2025/10/05/a-bunch-of-one-off-projects-for-2025.html</guid>
      </item>
    
      <item>
        <title>Announcing TPS</title>
        <description>Announcing TPS (Team Planning Simulator) (see, it generates TPS Reports ha!)</description>
        <content:encoded><![CDATA[<p>Announcing TPS (Team Planning Simulator) (see, it generates TPS Reports ha!)</p>

<p>Source and download here -&gt; <a href="https://github.com/huntergdavis/teamplanningsimulator/">TPS</a></p>

<p>And hey, as it’s client-side, how about a <a href="/teamplanningsimulator/">Live Version</a></p>

<p><img alt="" src="/content/images/2024/tps.png" width="400" /></p>

<p>Team Planning Simulator Reports (TPS Reports) is a quick report generator to help you plan hiring, throughput, and costs for the year, broken down by quarter and 2-week sprint. And yeah, the name is a riff on the ole T.P.S. report.</p>

<p>Current features: 
So few, so laughably few.  But hey, enough to honestly help in some situations.</p>

<ol>
  <li>Save and load to JSON for fast iteration!</li>
  <li>Add roles and event types, then apply them to your calendar</li>
  <li>See throughput metrics, efficiency, costing, etc.</li>
</ol>

<p>It falls squarely into the bucket of “can’t you just use a spreadsheet?”  Yes. Of course you can, I’ve done so for a few decades now and I’m sure folks will do so for another few hundred. The humble spreadsheet will outlive us all. All that said, this is a helpful way for me to visualize, quickly iterate with small features, and quickly generate scenarios without relying on a cloud-hosted python backend for a simulator or stacks and stacks of resource-crazy google sheets.</p>

<p>Backstory: 
I’m committing to releasing more things that spark joy, and more little projects.  Sometimes you just write a quick simulator on a Sunday night to help you clear your head and get your thoughts out, and sometimes that’s really helpful to other folks.</p>

]]></content:encoded>
        <pubDate>Sun, 29 Dec 2024 01:00:24 +0000</pubDate>
        <link>https://hunterdavis.com/2024/12/29/announcing-tps.html</link>
        <guid isPermaLink="true">https://hunterdavis.com/2024/12/29/announcing-tps.html</guid>
      </item>
    
      <item>
        <title>Announcing Labrync</title>
        <description>Announcing Labrync (like labrynth + ncurses)</description>
        <content:encoded><![CDATA[<p>Announcing Labrync (like labrynth + ncurses)</p>

<p>Source and download here -&gt; <a href="https://github.com/huntergdavis/labrync/">Labrync</a></p>

<p><img alt="" src="/content/images/2024/earlygame.png" width="400" /></p>

<p>Labrync is a passive or active little console toy. I wanted to play with a few maze exploration algorithms (you can see a bunch in the history).  The color palette is going to change as right now it’s a ‘hotdog stand’ level thing. I thought the concept from onelonecoder was really fun and inspiring and wanted to extend it in some fun ways.  Also ported to python cause why not I guess?</p>

<p>Like I said before, little things that bring me joy.  Things I might dip in and add a feature to once a year, for 30 years. That’s what my internet is all about.  Here’s another one.</p>

<p><a href="https://github.com/user-attachments/assets/89f0045f-518f-4b25-9698-34922285b47d">Early Demo Movie</a></p>

<p>Based on and extended from the command line C fps from 
onelonecoder</p>

<p><a href="https://github.com/OneLoneCoder/CommandLineFPS">One lone coder Github</a></p>

<ol>
  <li>Maps are randomly generated</li>
  <li>Maps can be auto-solved (screensaver mode, if you will) by passing -a to labrync.py</li>
  <li>Colors are… supported</li>
  <li>Player entering ‘X’ exit will regenerate the map and start fresh in top left corner</li>
  <li>Breadcrumbs (or .. reverse breadcrumbs?  Crumpled grass?) To show where you’ve been.</li>
  <li>Fog of War (or not) for additional challenge</li>
</ol>

]]></content:encoded>
        <pubDate>Sat, 16 Nov 2024 01:00:24 +0000</pubDate>
        <link>https://hunterdavis.com/2024/11/16/announcing-labrync.html</link>
        <guid isPermaLink="true">https://hunterdavis.com/2024/11/16/announcing-labrync.html</guid>
      </item>
    
      <item>
        <title>Announcing Tui000</title>
        <description>Announcing Tui000 (sounds like ‘three thousand’)</description>
        <content:encoded><![CDATA[<p>Announcing Tui000 (sounds like ‘three thousand’)</p>

<p>Source and download here -&gt; <a href="https://github.com/huntergdavis/tui000/tree/main">Tui000</a></p>

<p>Tui000 is a passive game / screensaver for your terminal.  Watch virtual avatars make life decisions, visit the graveyard to see how each life measured out. Passive, small. Now is the time for small joys, for silver linings. I feel 2025 will need as much joy as possible, and I’ve been inspired to put more little moments of joy out there for folks like I used to.</p>

<p>I had an idea one day just relaxing and thinking about Johnny Castaway. 
I had already ported Johnny to as many platforms as I was interested in.
What I really missed was that feeling of fun and writing software.</p>

<p>Some of my best work was made famous not by my original intention.
Rather, it was the creativity of others that brought purpose to “meaningless” software. 
After all these years, I keep coming back to the terminal.</p>

<p>So, in an attempt to recreate that feeling, in the terminal, here’s the start and the pitch.
You only have 3000 weekends, on average, in your adult life. The life-map assumes that each major choice you make in your life will become the focus, on average, of 12 weekends. Some a lot more, some a lot less, but on average let’s take a wild swing at 12 or so.</p>

<p>So you get 240 decisions, some many times over, with how to spend your time.  Sounds like a lot, goes by quick.  Just like life. Probably not of interest to most folks, but of great interest to me.  Useless, silly, simplistic, exactly what I had envisioned.  All future improvements are fun additions to the base concept, and I’ve got a ton in mind.</p>

<p>Design:</p>

<p>Constraints: Must target / be usable in 80x24 terminal window.</p>

<p>Launching the app spawns a character.
The character makes choices, indicated by colors which map to life categories. 
These choices add up to weave the tapestry of each life, the colorful headstone.
When the character dies, each is written out to a json file in ./graveyard/</p>

<p>Running the App:
Run with python after installing requirements.txt</p>

<p>Pass the -debug flag for more logging and 100x speed</p>

<p>Building with Docker:
sudo docker build -t tui000 .</p>

<p>Running with Docker:
docker run -it –name tui000-container tui000</p>

<p>You can find the repository below, including original design docs and screenshots.</p>

<p><a href="https://github.com/huntergdavis/tui000/tree/main">Tui000</a></p>

<p>Main Graveyard Screen -&gt; 
<img alt="" src="https://github.com/huntergdavis/tui000/raw/main/screenshots/graveyard_like_concept.png" width="400" />
<img alt="" src="https://github.com/huntergdavis/tui000/raw/main/concept_art/death_screen.jpg" width="400" /></p>
]]></content:encoded>
        <pubDate>Thu, 07 Nov 2024 01:00:24 +0000</pubDate>
        <link>https://hunterdavis.com/2024/11/07/announcing-tui000.html</link>
        <guid isPermaLink="true">https://hunterdavis.com/2024/11/07/announcing-tui000.html</guid>
      </item>
    
      <item>
        <title>Client-Side Site Search for HunterDavis.com</title>
        <description>I stumbled upon an Excellent Blog Post, from Stephan Miller detailing how to set up a local client-side search functionality for static sites.</description>
        <content:encoded><![CDATA[<p>I stumbled upon an <a href="https://www.stephanmiller.com/static-site-search/">Excellent Blog Post</a>,  from Stephan Miller detailing how to set up a local client-side search functionality for static sites.</p>

<p>So that’s exactly what I implemented today. You’ll see a search box on the right of the homepage, and you can sort the results by relevance or date. Best of all, this relies on no external search engine and respects your privacy. This works by generating a json blob with all my post data, then running a local search with lunr.js.  Much, MUCH easier to find content now, especially those old Zipit and game review articles.</p>

<p><img alt="" src="/content/images/2024/sitesearch.png" width="400" /></p>
]]></content:encoded>
        <pubDate>Sun, 25 Aug 2024 12:00:24 +0000</pubDate>
        <link>https://hunterdavis.com/2024/08/25/search.html</link>
        <guid isPermaLink="true">https://hunterdavis.com/2024/08/25/search.html</guid>
      </item>
    
      <item>
        <title>Physical Media and Markdown Table Renderer</title>
        <description>I’m a big fan of Obsidian, paying for premium and using it to store notes and lists.</description>
        <content:encoded><![CDATA[<p>I’m a big fan of <a href="https://www.obsidian.md/">Obsidian</a>, paying for premium and using it to store notes and lists.</p>

<p>I was enjoying myself rather thoroughly this weekend while browsing a thrift store in sunny Montana, a couple states away from rainy Seattle. There was a great deal of most excellent used DVDs, Blu-Rays, VHS tapes and other media formats I still find myself using day to day.</p>

<p>While I have obsidian sync for my local devices, I pondered how to keep my family apprised of what media we have and what we don’t, especially when that number is quickly approaching the thousands from the hundreds?</p>

<p>There’s a publish option, but that’s an additional 10$ per month and I already have a website and GH pages. I realized what I really needed was a way to render markdown tables as HTML client-side, then I could simply point a static page to those markdown files and I’ve got a nice little interface on the web.</p>

<p>So that’s exactly what I wrote up today. <a href="/media/">Live Link.</a> <a href="https://github.com/huntergdavis/media">Github Link.</a></p>

<p><img alt="" src="/content/images/2024/markdown.png" width="400" /></p>
]]></content:encoded>
        <pubDate>Sun, 25 Aug 2024 12:00:24 +0000</pubDate>
        <link>https://hunterdavis.com/2024/08/25/media.html</link>
        <guid isPermaLink="true">https://hunterdavis.com/2024/08/25/media.html</guid>
      </item>
    
      <item>
        <title>2024 Privacy and AI Update</title>
        <description>April Cool’s Day inspired me to do something different and share something unexpected.</description>
        <content:encoded><![CDATA[<p><a href="https://www.aprilcools.club/">April Cool’s Day</a> inspired me to do something different and share something unexpected.</p>

<p>We live in a very different world from the one that existed when this blog was created. It’s taken many different forms over the years, but throughout it all my desire to share and help others remains unchanged.</p>

<p>Where do I draw the line as to how far that help extends? When I think of my articles being helpful to a new leader or aspiring hacker, that fills me with joy. When I think of large companies using my likeness and writing style to make billions while trashing our environment, I pause. When I think of the bad actors, the scammers, the phishers, the AI-enabled stalkers (all of whom I’ve experienced over these past couple of years), I fear. I fear that they’ll continue to use the good I’ve tried to share with the world to hurt myself and others.</p>

<p>Fear can be a powerful motivator for change, but so too can the desire to help others. I want to set a better example here, when I write I want to write about leadership and coaching with a more inclusive voice and patterning better behaviors. Much as I have done in my professional life I’m going to start leveling up my game here on the blog. Today that means a couple of changes to the site, the removal of some content, and a promise to take a silver lining from this refresh.</p>

<p>Change number 1: I’m explicitly licensing all sources on this blog going forward with a NON-AI MIT license.</p>

<p>Change number 2: The removal of overly personal blog posts and content. While photos of my family and pets from 20 years ago still bring a tear to my eye, they pose a risk to their safety in this new world.</p>

<p>Change number 3: The de-identification of personal imagery and personally identifying information from all articles and site pages. Going to have some fun with this one, adjusting some prior images algorithmically. For now, I’ll start with <a href="/content/images/2024/imagechange.py">a quick thresholding and random colorization.</a> Moving forward: I’ll find a new avatar and remove EXIF data from any photos.</p>

<p>Here’s what this quick first pass looks like:
<img alt="" src="/content/images/2013/08/20130830_144712.jpg" width="400" /></p>

<p>Silver Lining: One great lesson I’ve learned in my career, imparted to me by a leader I trust: not everyone you lead will see themselves in you. The sames goes for readers of this blog! My hope is that more folks may connect with the message I’m trying to send going forward.</p>
]]></content:encoded>
        <pubDate>Mon, 01 Apr 2024 12:00:24 +0000</pubDate>
        <link>https://hunterdavis.com/2024/04/01/privacy-and-ai-update.html</link>
        <guid isPermaLink="true">https://hunterdavis.com/2024/04/01/privacy-and-ai-update.html</guid>
      </item>
    
      <item>
        <title>My Custom Guitar from MaCo Guitars Is In!</title>
        <description>This has been many years coming, and I’m so excited to finally be able to share this with y’all. Years ago, I met a brilliant engineer and guitar builder, who later started MaCo guitars. Many years before thats, my co-founder Mark and I had built a cigar-box guitar together based on the Make magazine cover article. I never forgot how much fun it was, or how much skill goes into even the most basic of guitar builds. I knew, one day I would commission a professional shop to build my dream guitar.</description>
        <content:encoded><![CDATA[<p>This has been many years coming, and I’m so excited to finally be able to share this with y’all.  Years ago, I met a brilliant engineer and guitar builder, who later started <a href="http://www.macoguitars.com/">MaCo guitars.</a> Many years before thats, my co-founder Mark and I had built a <a href="/about.html#guitar_">cigar-box guitar</a> together based on the Make magazine cover article. I never forgot how much fun it was, or how much skill goes into even the most basic of guitar builds.  I knew, one day I would commission a professional shop to build my dream guitar.</p>

<p>Well dear readers, that day has come. Below, learn all about my new guitar, and how it came together.  Please note, this is NOT a paid advertisement. I have received no compensation or discounts for writing this article, I’m just so frikkin amazed and in love with my guitar, I want everyone to know!</p>

<p>I reached out to my friend Mat at MaCo, and he walked me through the whole process. It started with a shared design session, with Mat and I going through the customizations, shape, materials, and wood types.  This was easy, and a bit like putting a computer together online, only in this case everything was custom, and changable.</p>

<p>Over the next year, I received a regular stream of updates from MaCo.  The wood selection.  The resonator build.  The composite materials and cuts.  They became the highlight of my year, and certainly some of the best and most engaging news I had in 2021.</p>

<p>Then, at the end of 2021 it was ready!  I could hardly contain my excitement!  I flew out to pick up this one of a kind guitar, and I was not ready for how emotional it would be opening the case for the first time!</p>

<p><img alt="" src="/content/images/2022/opencase.jpeg" width="400" /></p>

<p>The beauty and complete uniqueness of my guitar still amaze me all these months later. I was nearing tears as I was presented with the build certificate.</p>

<p><img alt="" src="/content/images/2022/certificate.jpeg" width="400" /></p>

<p>I had a particular set of (perhaps odd, definitely non-standard) requirements for this build.  I wanted a shortened neck, with a semi-hollow body and a player-reflecting resonator.</p>

<p><img alt="" src="/content/images/2022/guitar_body.jpg" width="400" /></p>

<p>Look at those tuning pegs!  Oooh they are pretty.</p>

<p><img alt="" src="/content/images/2022/head.jpg" width="400" /></p>

<p>My hands were literally shaking as I picked up the guitar for the first time.  Lightweight and perfectly balanced, with that custom cut MaCo is known for.</p>

<p><img alt="" src="/content/images/2022/holdingguitar.jpeg" width="400" /></p>

<p>I was giddy as I looked into the resonator and saw the build certificate and born-on date!!  That’s my name in there!</p>

<p><img alt="" src="/content/images/2022/inthebody.jpg" width="400" /></p>

<p>MaCo even took some of the leftover premium woods and created a custom set of coasters for me.  So thoughtful!</p>

<p>One last shot of my guitar.</p>

<p><img alt="" src="/content/images/2022/righthand.png" width="400" /></p>

<p>Thanks for reading all about my guitar!!  I highly recommend anyone interested in top tier professional guitar-builders to check out MaCo guitars!  It’s been a life-changing experience for me, the creation of an heirloom I’ll treasure for life!</p>
]]></content:encoded>
        <pubDate>Sun, 03 Apr 2022 12:00:24 +0000</pubDate>
        <link>https://hunterdavis.com/2022/04/03/custom-guitar-from-maco.html</link>
        <guid isPermaLink="true">https://hunterdavis.com/2022/04/03/custom-guitar-from-maco.html</guid>
      </item>
    
      <item>
        <title>Coaching Leaders During Covid</title>
        <description>It’s 2022. Strange as it is to write this, that means we’ve been living in a Covid-19 world for two years. For many of us that has meant a shift into remote work and remote leadership. Looking back on these past two years of fully remote leadership, I’ve observed that the stress of Covid-19 has only exacerbated the struggles that many new leaders go through. With that in mind, here are four struggles new leaders commonly face, and coaching lines I tend to employ for each.</description>
        <content:encoded><![CDATA[<p>It’s 2022. Strange as it is to write this, that means we’ve been living in a Covid-19 world for two years. For many of us that has meant a shift into remote work and remote leadership. Looking back on these past two years of fully remote leadership, I’ve observed that the stress of Covid-19 has only exacerbated the struggles that many new leaders go through. With that in mind, here are four struggles new leaders commonly face, and coaching lines I tend to employ for each.</p>

<p>Please note, as in all things I try to be empathetic and kind. I myself struggled greatly with these concepts as I transitioned into leadership, and I try and share personal anecdotes and my own struggles with the folks whom I support. Open your heart a little, it helps.</p>

<h1 id="scenarios">Scenarios</h1>
<ul>
  <li><a href="#badnews">Delivering Difficult News</a></li>
  <li><a href="#formerpeers">Loss of Peer Relationships</a></li>
  <li><a href="#trustjartruth">Assignment of Undesired Tasks</a></li>
  <li><a href="#opportunityleadership">Meeting Team Commitments while Growing a Team</a></li>
</ul>

<h2 id="badnews">Delivering Difficult News</h2>
<p><img alt="" src="/content/images/2022/badnews.jpeg" width="320" /></p>

<p>Here’s the scenario:</p>

<blockquote>
  <p>A leader is having difficulty delivering difficult/negative news to a team.</p>
</blockquote>

<p>Here’s the pitch:</p>

<blockquote>
  <p>By “protecting” your team from bad news, you create a culture of fear.</p>
</blockquote>

<p>Here’s the deal:</p>

<p>Early in my career, I thought that I was being a good leader by protecting my teams. I was causing them harm, but I didn’t realize it at the time. I thought I was being a good leader if I only gave a team the “good news”, the positive outlook, the cheery optimism of having the “best projects in the company.”  I thought I was giving them the proverbial “good jobs.”</p>

<p>What I was really doing was building an environment of existential fear. How?  By protecting these teams from the reality of the business and attempting to ‘smooth over’ company losses or poor results, I had eroded trust. Visibility, and real honesty drive trust within a team. In removing that, I had affected their psychological safety. They were always waiting for the other shoe to drop. Transparency, accountability, and revenue measurement are a form of kindness to a team. Trust isn’t just built on good news, as we’ll discuss in <a href="#trustjartruth">Assignment of Undesired Tasks</a> below.</p>

<h2 id="formerpeers">Loss of Peer Relationships</h2>
<p><img alt="" src="/content/images/2022/oppseverywhere.jpg" width="320" /></p>

<p>Here’s the scenario(s)  (this line of coaching is fairly universal):</p>

<blockquote>
  <ol>
    <li>A newly promoted leader is struggling with the loss of peer relationships on their team.</li>
    <li>A newly remote leader is struggling with building team culture over the internet.</li>
    <li>A leader is struggling to connect with a new team.</li>
  </ol>
</blockquote>

<p>Here’s the pitch:</p>

<blockquote>
  <p>Don’t be yourself, be the leader you want to be. Lead from your fundamentals, not your personality.</p>
</blockquote>

<p>Here’s the deal:</p>

<p>First, remind the manager that it’s their skillset that earned them this role, and it’s through that skillset and leadership experience that they can best help a team. Not personality. Not popularity.</p>

<p>I have found that a bold, clear statement of purpose helps to clear up any misconceptions. To wit, I recommend to all managers: Don’t be yourself!  Be the leader you want to be. Lead from your fundamentals, not your personality.</p>

<p>Jokes and interpersonal ribbing can ease tension, but possibly at the expense of someone’s emotional safety. There’s always an imbalance of power between a leader and those they support. Friendships are not built on power imbalances, and businesses do not run on friendships. All of the benefits of friendship in a business context flow upwards towards the business, and away from the individuals you support. “Oh, can you stay a few hours extra to help out <em>buddy?</em>”  “I know you have family commitments, <em>buuuut</em> can you come in early for a meeting just on Mondays?  To support your <em>work family</em>??”</p>

<p>Lead through your fundamentals. This is a kindness to those you support.</p>

<ol>
  <li>Build a culture of excellence and pair it with empathy.</li>
  <li>Set an expectation of mentorship and growth mindsets.</li>
  <li>Value accountability at all levels, have clear measures of success, share outcomes widely.</li>
  <li>Listen. If you find yourself interrupting folks, sip a drink during  1:1 meetings.</li>
</ol>

<h2 id="trustjartruth">Assignment of Undesired Tasks</h2>
<p><img alt="" src="/content/images/2022/trustjar.jpg" width="320" /></p>

<p>Here’s the scenario:</p>

<blockquote>
  <p>A leader is struggling with the assignment of undesirable tasks</p>
</blockquote>

<p>Here’s the pitch:</p>

<blockquote>
  <p>Trust isn’t built by throwing goodwill over a wall, it’s a relationship you build together collaboratively.</p>
</blockquote>

<p>Here’s the deal:</p>

<p>There’s this concept folks like to talk about in team leadership, that of the “trust jar”. It goes like this, every time you do something that builds trust with a team, you’re “putting a quarter into the trust jar.”  It’s a nice visual metaphor of the trust you build with a team over time.</p>

<p>The thing is, that’s only half the story. If you never have to ask for trust, if you never ask a team to suspend their disbelief and (in this case) do this undesirable task, then you’ve not built real trust. You’ve just banked goodwill. You’ve turned your trust jar into a wishing well, when it should really be more like the ‘take a penny leave a penny’ tray at the store. A shared trust, going both ways, building depth and value together. It is through this transparency and the shared shouldering of burdens that you truly build trust with your team.</p>

<h2 id="opportunityleadership">Meeting Team Commitments while Growing a Team</h2>
<p><img alt="" src="/content/images/2022/problemmountain.jpg" width="320" /></p>

<p>Here’s the scenario:</p>

<blockquote>
  <p>A leader is struggling with team growth while still meeting team commitments</p>
</blockquote>

<p>Here’s the pitch:</p>

<blockquote>
  <p>Every problem is an opportunity that someone needs, be an opportunity leader and pair them.</p>
</blockquote>

<p>Here’s the deal:</p>

<p>A business is really just a collection of problems. At all levels and at all times we’re facing challenges, prioritizing which ones to tackle and how to do so. An infinite mountain of problems, and we ski down the top slope of it every day. How then, to think about team growth when there are nothing but problems to face?</p>

<p>Remind those that you support of the mission. Of your responsibility as leaders to help others. Always tie it back to the mission, and to an empathetic outcome. Every problem that your business faces is really just an opportunity that someone in your organization needs. Maybe it’s the opportunity to learn a new skill. Maybe it’s the opportunity to help just one more person. Find that silver lining. Find the person who this challenge is also an opportunity for. As leaders we’re constantly measuring, learning, attempting to become better at what we do and in helping those we support. You should know (and if you don’t, well then get to knowing!) what areas your folks are looking to grow in. It’s a regular topic at your weekly check-ins, and you <em>never</em> want someone you support to be in the dark about their own performance and growth.  Pour yourself a nice slow-sippin drink, and get to <em>listening</em>.</p>

<p>Here’s a technique that I often employ with new leaders. I ask them if they know about the two purposes for every meeting. That usually piques their interest, and we dive in. The first purpose is obvious, it’s the stated purpose of the meeting. Every meeting has an outcome, decision or artifact that is clearly stated and obvious to all involved. If not, cancel that meeting as it’s an email in disguise.</p>

<p>The second purpose for every meeting is in opportunity leadership. Be on the lookout for problems that are really opportunities for folks you support (not just folks on your team, a good leader supports all departments.) You’d be surprised how quickly after finding out about a skill or growth area for an individual that an opportunity will present itself. Teaching this, truly embedding a growth mindset within your teams will pay off dividends for many generations of leadership. Encourage folks to talk about it plainly and transparently.</p>
]]></content:encoded>
        <pubDate>Mon, 10 Jan 2022 12:00:24 +0000</pubDate>
        <link>https://hunterdavis.com/2022/01/10/coaching-new-leaders-during-covid.html</link>
        <guid isPermaLink="true">https://hunterdavis.com/2022/01/10/coaching-new-leaders-during-covid.html</guid>
      </item>
    
      <item>
        <title>Conway&apos;s Emotional Law</title>
        <description>Conway’s Law. The idea that your organizational structure will be mirrored in your design (software) structure. Simple in concept and true to my experience, it’s a principle that drives many an organizational planning session.</description>
        <content:encoded><![CDATA[<p><a href="https://en.wikipedia.org/wiki/Conway%27s_law">Conway’s Law</a>.  The idea that your organizational structure will be mirrored in your design (software) structure.  Simple in concept and true to my experience, it’s a principle that drives many an organizational planning session.</p>

<p><a href="https://sketchplanations.com/">Sketchplanations</a> has an <a href="https://sketchplanations.com/conways-law">overview that I love</a>, embedded below.</p>

<p><img alt="" src="/content/images/2022/conwayslaw.jpg" width="640" /></p>

<p>There is however, a powerful corollary that I’ve observed.  I call it <a href="/2022/01/01/conways-emotional-law.html">“Conway’s Emotional Law”</a></p>

<blockquote>
  <p>Conway’s Emotional Law: How the members of your organization <em>treat</em> each other will be reflected in your designs (software.)</p>
</blockquote>

<p><img alt="" src="/content/images/2022/conwaysemotionallaw.svg" width="640" /></p>

<p>This is absolutely something I’ve observed over and over throughout my career.  Does your team value transparency and empathy?  Your products will stand out for their “intuitiveness” and “consistent feel.”  Conversely if your team is combative, competitive and full of lone wolves?  You’ll wonder why your features are technically brilliant but lack adoption.  Or perhaps your products sparkle with brilliance but have limited functionality, and you wonder why it takes so long to add a feature.  Look not only to how you’ve structured your teams, but to <em>how your teams treat each other</em>.</p>
]]></content:encoded>
        <pubDate>Sun, 09 Jan 2022 08:33:24 +0000</pubDate>
        <link>https://hunterdavis.com/2022/01/09/conways-emotional-law.html</link>
        <guid isPermaLink="true">https://hunterdavis.com/2022/01/09/conways-emotional-law.html</guid>
      </item>
    
      <item>
        <title>Johnny Castaway Text Edition</title>
        <description>I’ve been enjoying and porting Johnny Castaway to new systems for many years now. Today though, is the first time I’ve actually added a fundamentally new feature to Johnny.</description>
        <content:encoded><![CDATA[<p><img alt="" src="/content/images/2021/johnny_printer.jpg" width="640" />
I’ve been enjoying and porting Johnny Castaway to new systems for many years now.  Today though, is the first time I’ve actually added a fundamentally new feature to Johnny.</p>

<p>I was working on my closed captions branch, adding textual descriptions for the scenery and actions that happen while the game is playing.  It was going along just fine, but I realized that you don’t really need the original files, engine, or parsing code at all to simulate the experience textually.  I had already done the hard work to write the descriptions for every scene and item, why not script them all up together into a bash script and reduce the overhead for running Johnny <em>significantly</em>?</p>

<p>So, here you are.  The whole of Johnny Castaway, distilled down into a single bash script.  You are now free to run Johnny on devices which do not have graphics output, or on your receipt printers for example.</p>

<p>If you’d like to use the closed captions in your own ports of Johnny, you can find them in the closed_captions branch.  For the script, you can find that in the <a href="https://github.com/huntergdavis/jc_reborn/tree/bash">bash branch here</a>.</p>

<p>I also highly recommend adding Johnny to your .profile or .bashrc, such that when you log onto a shell you get an update on how Johnny’s doing today :)</p>

<p><img alt="" src="/content/images/2021/johnny_bash_startup.jpg" width="640" /></p>
]]></content:encoded>
        <pubDate>Sat, 11 Dec 2021 08:33:24 +0000</pubDate>
        <link>https://hunterdavis.com/2021/12/11/johnny-castaway-text-edition.html</link>
        <guid isPermaLink="true">https://hunterdavis.com/2021/12/11/johnny-castaway-text-edition.html</guid>
      </item>
    
      <item>
        <title>15$ for Direct HDMI Input on Oculus Go</title>
        <description>I’m going to come out and say it. The Oculus Go is my favorite VR headset of 2021, maybe ever. Yes, that Oculus go, the cheap one they don’t sell anymore. I’m currently playing through Magnesium 173 via Steam Streaming to my PC, emulating light gun games in retroarch, and playing Switch games directly through HDMI!</description>
        <content:encoded><![CDATA[<p>I’m going to come out and say it.  The Oculus Go is my favorite VR headset of 2021, maybe ever.  Yes, <a href="https://www.oculus.com/go/">that Oculus go</a>, the cheap one they don’t sell anymore.  I’m currently playing through <a href="https://store.steampowered.com/app/1157200/Magnesium_173/">Magnesium 173</a> via Steam Streaming to my PC, emulating light gun games in retroarch, and playing Switch games directly through HDMI!</p>

<p><img alt="" src="/content/images/2021/oculus_hunter.jpg" width="640" /></p>

<p>I had my eye on one since launch, but with the ties to Facebook and the Facebook login requirement, I kept my distance.  When John Carmack released a rooted/unlocked firmware for the device earlier this fall, I knew it was time to pick one up.</p>

<p>You don’t need to have a Facebook account, just submit the form to become an Oculus developer and you can create an Oculus account.  This will let you set up the device for the first time (for now… I’m sure an untethered setup hack is coming soon.)</p>

<p>I was really enjoying playing around with it, streaming Steam games from my PC and Xbox games from the cloud.  Retroarch works great, especially light gun games!  (Duck Hunt, House of the Dead, Confidential Mission)</p>

<p>It is not powerful enough to emulate the Switch.  Hell it’s not powerful enough to emulate the Gamecube at a reasonable speed.  So how then, am I going to play Metroid Dread on it?</p>

<p>OK, for sure, I could emulate it on my PC and stream it on over.  That’ll work fine.  What if I don’t want to emulate?  What if I want to use any HDMI capable device, directly on the Go, without having any wifi or internet connectivity requirements?</p>

<p>Well, as I found out today, I’m in luck.  It cost me about 15$, and no trouble at all!</p>

<p>You see, dear reader, the Oculus go is essentially a Galaxy S7 crammed into a VR headset.  Not exactly, but close enough.  Now that we have an unlocked and rooted operating system, the sky is the limit!</p>

<p>What we’ll do is use a USB OTG cable (remember those?) and a capture card to bridge out the micro-usb to a full USB-A port.</p>

<p>Take the OTG cable, and plug in the HDMI-&gt;USB capture dongle (15$ at Microcenter).  After that, any HDMI device plugs into the input (my particular capture device supports up to 1080p)</p>

<p><img alt="" src="/content/images/2021/cables_for_oculus_hdmi.jpg" width="640" /></p>

<p>Android supports this form of USB video well, but you’ll need to install a viewer application.  There’s a well supported (and ad supported) one that I’ve found works well called “USB Camera - UVC and EasyCap”.  You’ll probably want to spring for the pro version, or find one without ads.  For this proof of concept, I don’t mind if there are ads while I’m testing the hardware.</p>

<p>You’ll need to enable developer mode and sideloading, then side load in your USB capture software.</p>

<p><a href="https://developer.oculus.com/documentation/native/android/mobile-device-setup/">Here’s a guide</a> for enabling developer mode and sideloading on an Oculus Go.</p>

<p>Once we have all of our cables and software ready, plug them into the Oculus</p>

<p><img alt="" src="/content/images/2021/oculus_hdmi_in.jpg" width="640" /></p>

<p>Open the app, accept the USB camera permission, and you’re off to the races!!  Lots of cool applications for this, and the latency isn’t horrible!</p>

<p>That wraps it up for this one, keep an eye out for some fun Oculus projects coming soon on this blog!</p>

]]></content:encoded>
        <pubDate>Thu, 09 Dec 2021 08:33:24 +0000</pubDate>
        <link>https://hunterdavis.com/2021/12/09/hdmi-in-on-oculus-go.html</link>
        <guid isPermaLink="true">https://hunterdavis.com/2021/12/09/hdmi-in-on-oculus-go.html</guid>
      </item>
    
      <item>
        <title>No x86 Handheld Needed</title>
        <description>I was working on a follow-up to the previous article on my x86 handheld, when I stumbled upon a technology that totally superseded it.</description>
        <content:encoded><![CDATA[<p>I was working on a follow-up to the previous article on my x86 handheld, when I stumbled upon a technology that totally superseded it.</p>

<p>Backing up, in what little free time I’ve had these past few months, I’ve been installing and configuring linux/wine/lutris on bay trail devices.  You can pick up these tablets on eBay for under 40$ fully decked out, and it’s just this year that linux/alsa/wine all work together well without much headache on these tablets.  The only problem is that they’re used, in short supply, and they are not making any more.  So it’s not a permanent solution, but it is a nice option.</p>

<p>Then comes <a href="https://twisteros.com/about.html">TwisterOS</a> and changes the game.  Now I can hop over to the Microcenter, pick up a 35-75$ board that plugs into any TV and uses any peripheral, and they’re going to manufacture compatible units till the end of time. Nice.</p>

<p>One interesting tidbit that I did glean from my time buying intel baytrail tablets (you know, the ones that have a 32-bit bios and a 64-bit processor?) is that Fedora 35 supports all of the ones I had out of the box, fully.  I can’t even say that for windows 10.  It’s a rock solid experience and a great way to play the Simpsons Hit and Run and many other games I wrote about in the previous article, quite cheaply (like 30-40$ for a used tablet cheaply.)</p>

<p>But no, there’s no need for that now.  I read about TWISTER OS, a linux distribution for arm boards (like the raspberry pi) but tuned for running x86 software.  They’ve got box86 and wine running together, and I was quite skeptical that emulating both the CPU and the GPU would produce a playable experience on a modern arm device.</p>

<p>I was way wrong!  Check out this video of The Simpsons: Hit and Run playing full speed (1024x768 resolution) on a raspberry pi 400.  Honestly this is a game changer, and as compatibility rises you can be certain this will get more attention.</p>

<iframe width="900" height="600" src="https://www.youtube-nocookie.com/embed/mnX5fogHdoQ" title="Simpsons Hit and Run on the Pi 400" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<p>I wasn’t able to get the windows version of Psychonauts running (at least on the first try), nor Clive Barker’s Undying, but I’m going to dig in with lutris configurations and see if I can’t get them going.  SimCity 3000 worked like a champ out of the box.  So did Beyond Good and Evil!</p>

<p><img alt="" src="/content/images/2021/pi400simcity3000.jpg" width="640" /></p>

<p>Then I saw it.  That little Steam icon.  Could it really be, could I really just click Steam, install some games and rock on?</p>

<p>I clicked, Steam loaded.  I entered my information, confirmed my Steam guard code, and snap.  I was in.</p>

<p>It crashed a few times installing Portal, but I eventually got it installed.  Portal was a game I was surprised to see running at all in Linux on the bay trail chipsets, and I wanted to see how it runs on the Pi 400.</p>

<p>It’s about the same as the bay trail devices.  A bit choppy, but playable on low settings.</p>

<p><img alt="" src="/content/images/2021/pi400portal.jpg" width="640" /></p>

<p>I then proceeded to import my GOG.com games into Lutris, and install Prince of Persia.</p>

<p>It’s quite amazing how well some of these games run.  Prince of Persia: Sands of time was choppy on a bay trail processor with some amount of tweaking. It’s almost perfect on the pi 400, out of the box!  Lower end games like SteamWorld Dig ran flawlessly without any configuration at all.</p>

<p>All in all, I am so excited for what this represents.  For me, it’s bespoke game images for my raspberry pi.  This usb thumbstick boots straight up into the Simpsons Hit and Run, this one into Prince of Persia, this one into the Sims.  I know they’ll boot on any pi-4 or above, and for sure there will be a host of portable options built around the pi CM4.  A whole new generation of games just became playable on the next generation of mid-range handhelds and low-end consoles, and I’m here for it!</p>
]]></content:encoded>
        <pubDate>Sat, 09 Oct 2021 08:33:24 +0000</pubDate>
        <link>https://hunterdavis.com/2021/10/09/no-x86-handheld-needed.html</link>
        <guid isPermaLink="true">https://hunterdavis.com/2021/10/09/no-x86-handheld-needed.html</guid>
      </item>
    
      <item>
        <title>The Steamin&apos; Deck, A Low-End X86 Handheld</title>
        <description>Y’all probably know, I love games. I’m also way into handheld gaming, portable consoles, processors, embedded systems and retro gaming in a major way. I pick up every cheap chinese handheld I can find, love my switch, and am just a major portable and retro gaming enthusiast. So you can imagine my excitement when the Steam deck was announced. Of course I preordered, hell I’ve bought everything GPD has ever released.</description>
        <content:encoded><![CDATA[<p>Y’all probably know, I love games.  I’m also way into handheld gaming, portable consoles, processors, embedded systems and retro gaming in a major way.  I pick up every cheap chinese handheld I can find, love my switch, and am just a major portable and retro gaming enthusiast.  So you can imagine my excitement when the Steam deck was announced.  Of course I preordered, hell I’ve bought everything GPD has ever released.</p>

<p>However, it got me thinking.  That thinking turned to pondering, and stewing.  More than a little concerned, I realized that we, as an industry and as a culture of gamers, are missing a critical option.  We’ve taken a wrong turn at the low-end, and it’s holding us back.</p>

<p><strong>We’re missing a generation of games on the go no longer!</strong></p>

<iframe width="900" height="600" src="https://www.youtube-nocookie.com/embed/2uorZ2MeuFE" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<p><img alt="" src="/content/images/2021/portablepsychonauts.png" width="500" /></p>

<p>See, here’s the thing. For the past decade or so, if I pick up a cheap chinese handheld (think 20-60$, my sweet spot), I know what I’m getting.  A dual or quad core processor, probably right around a gigahertz, running an ARM or MIPS instruction set.  Somewhere between 128 and 1gb of ram. an SD Card for storage.  A low-resolution screen.  You’ve seen these devices, hell they are my bread and butter for fun porting projects.  These are the anerbics, the gpis, the compute module handhelds.  They are varied and sip battery power oh so slowly.  And they top out at emulating consoles from the 90s. (And some GBA, which in my mind is really a 90s console that released in the 2000s.)</p>

<p>We, as a gaming culture, have hit the ‘trough of sorrow’ when it comes to our low-end devices. There’s an entire segment missing in our market.  At the high-end, we’ve got plenty of competition.  300-1200$ devices, high-end X86 processors that are capable of running the newest (or nearly newest) games at high resolution and high speed. In the mid-range, that’s when we switch processor architectures.  Mid-range gaming portables are universally ARM devices, running a low power chipset with an ARM instruction set.  Think the GPD XD, razor android gaming handheld, etc. At the low-end, the market is saturated with cheap MIPS and low-end ARM processors.  Why is this a problem?</p>

<p>The problem is emulation overhead.  We can emulate a PS1 on these low-end chipsets.  To emulate a PS2 still requires a top of the line system.  The top of the line steam deck may still struggle to emulate some PS2 titles. It may be another 10 or 20 years before we can emulate a PS2 on a cheap 50$ handheld, if ever.  And it has been this way for over a decade.</p>

<p>It doesn’t have to be though!  A one gigahertz processor, a gig of ram, if we were running these games directly instead of emulating the original hardware, that would be more than enough!  Indeed, in the following article I show that it is, and there are a great number of PS2-era PC games I show running in full speed.  You might just be surprised how powerful 1ghz really is.  Interested?  Read on!</p>

<p><img alt="" src="/content/images/2021/simpsons.png" width="640" /></p>

<p>I set about to put together an X86 handheld.  A really shitty one, the lowest end hardware I could find.  I figured if I can show these games running on the lowest spec chip available, that’ll really prove the point.  I made some mistakes and bad assumptions along the way, while also learning a ton and even challenging some of my own assumptions.</p>

<p><img alt="" src="/content/images/2021/serioussam.png" width="640" /></p>

<p><em>The section wherein I spec the hardware.</em></p>

<p>I started by searching around (I usually start on Hackaday or github) for anyone else who has built an x86 handheld lately.  I found a couple of interesting articles:</p>

<p><a href="https://forum.level1techs.com/t/building-a-x86-handheld-gaming-pc/146654">Wherein a hacker uses a stick PC</a></p>

<p><a href="https://hackaday.com/2018/07/12/old-laptop-reborn-as-mobile-x86-game-system/">Wherein a hacker uses an old laptop</a></p>

<p>This is certainly not a new or novel idea, that’s good news!!</p>

<p>I especially liked the idea of using a stick PC.  Easily upgradeable, many were produced quite cheaply, and standard I/O (hdmi/SD card/ USB/wifi/bluetooth)</p>

<p>I stumbled upon the lowest end intel compute stick. 1gb ram, 8gb rom, intel atom x86 processor at 1.4ghz.  These can be found regularly on ebay for 30$ or so, given that the operating system they come with is fundamentally broken.  You see, the original intel compute stick 1gb/8gb came with stock ubuntu.  Stock ubuntu now requires more than 8gb of space to update, and thus these sticks run out of storage space on intitial boot-up, requiring a new OS.  That’s too much work for most users, but no touble for my needs, I’ll be installing linux fresh anyway.</p>

<p>So 30$ into this build, and I make my first truly wrong assumption.  I assumed that for this project a display would need to be 800x600.  Any LCD I use for this project, I’m going to want a 4:3 aspect ratio.  During the time period these games were made, there were really three main resolutions most everything supported.  At the top end: 1024x768.  More common in the mid-range was 800x600.  Finally there was the low-end 640x480, which to my recollection was a more common resolution a bit earlier in the 90s.  (an incorrect assumption on my part)</p>

<p>While I can easily test the compute stick on it’s own using my nexdock, it doesn’t support those 3 target resolutions.  In order to test the games, I was going to need to pick up a test monitor.  I ended up finding a 4:3 8” eyoyo security camera monitor that supported 1024x768, 800x600, and 640x480. They sell a bunch of similar models, this brand -&gt; <a href="https://eyoyomall.com/">Eyoyo</a></p>

<p>OK, so we have display and processing, what about storage?  Well, the 8gb it comes with is certainly enough to install a lightweight linux (I’ve found that Bodhi is a nice balance of small install size and full features).  I also wanted to know how games perform in other scenarios, whether playing directly from SD card, usb thumb drive, or SSD. The results were surprising!</p>

<p><em>The section wherein I talk about disk performance.</em></p>

<p>So, I set about to test PS2-era PC games on this hardware, using a variety of storage mechanisms.  Here are the results:</p>
<ul>
  <li>M2 SSD over USB 2.0 port. -&gt; Slow slow slow!  The USB port on these devices is rather limited, and I never saw over 20mb/sec transfer rate.  Random access was anecdotally abysmal.</li>
  <li>USB thumb drive over USB 2.0 port -&gt; Slow slow slow!  Again, the USB port is the limiter here.</li>
  <li>SD card via internal SD card slot -&gt; Not bad actually! System boot time is a bit slower compared to internal MMC, but game performance is equivalent.  This was unexpected!</li>
  <li>Internal MMC -&gt; About the same as the SD card slot, just a bit faster on boot.</li>
</ul>

<p>To swap or not to swap?<br />
For the above hardware scenarios, I tested out four different swap methodologies.</p>
<ol>
  <li>No swap at all</li>
  <li>Swapfile</li>
  <li>Swap partition co-located on same device as data partition</li>
  <li>Swap partition on internal MMC, data on separate device.</li>
</ol>

<p>There are scenarios where having a swap file helps, but that’s mostly because of Steam.  For example, when playing the Steam version of Saints Row 2 (or Portal) there’s not enough memory to hold both Steam, and a game like Saints row. With 1gb of ram total and 128mb of that allocated towards the GPU, we’re sitting around 881mb of usable memory.  Steam can easily use 500mb.  Saints Row 2 does as well.  Enabling swap allows the steam memory usage to get swapped out to disk, at which point you can play the game without major stuttering.</p>

<p>That said, the real solution here is quite simple.  DON’T USE STEAM.</p>

<p><img alt="" src="/content/images/2021/portalneedssteam.jpg" width="640" /></p>

<p>Don’t get me wrong, I love Steam.  LOVE IT.  I’ve been on the platform since half life 2 launch day, average about 200 purchases per year since launch, I’m invested in the platform.  Steam however, is not good for a 1gb system.  The webviews are slow, large libraries will take forever to load, and even with ‘low bandwidth’ and ‘low performance’ mode turned on, your experience will be poor. Also you won’t have enough ram leftover to run most games.</p>

<p>No, my recommendation here is quite straightforward: <a href="https://www.gog.com">GOG.com</a> and <a href="https://lutris.net/">Lutris</a></p>

<p>I’m a big fan of GOG.  They are invested in preserving classic games, and they release them DRM-free.  It’s that DRM that often makes games unplayable on modern systems or via linux/wine/proton, and most Steam games will be drm’d up to hell.  (Props to the folks at DoubleFine, the Steam linux version of Psychonauts is DRM-free!)</p>

<p>I’ve also recently found out about <a href="https://lutris.net/">Lutris</a>, a community-driven interface for installing windows games within linux via wine.  It automates most of the process, keeps a low memory profile, and the resultant installs are portable across installs (helpful if you’re re-installing different versions of linux on the daily, as I was for this article.)</p>

<p><img alt="" src="/content/images/2021/lutris.jpg" width="640" /></p>

<p>After trying a great number of combinations of linux distros and window managers, here’s how I ended up setting up my linux partitions and install.</p>
<ul>
  <li>No Swap whatsoever.</li>
  <li>50mb (yes megabyte) fat16 EFI partition, first partition of the internal 8gb MMC.  You’ll need fat16 here as the minimum fat32 partition size is 256mb</li>
  <li>7gb (remaining space) ext4 partition, second partition of the internal 8gb MMC.  Mounted as / (root directory of linux filesystem)</li>
  <li>128gb (or whatever size SD card you have) ext4 partition, first partition of the SD card inserted into the SD card slot. Mounted as /home  (I use a cheap microcenter U3 SD card ~12$)</li>
</ul>

<p>I went with <a href="https://www.bodhilinux.com/">Bhodhi Linux</a>, for the following reasons:</p>
<ul>
  <li>Supports fat12/fat16 efi boot partitioning in the installer</li>
  <li>A full 1gb less space used for root filesystem than even #!++ distro(this was a surprise!)</li>
  <li>enlightenment window manager, no screen tearing, low resource usage</li>
  <li>debian based, easy to install Lutris from PPE and steam from .deb package</li>
</ul>

<p><img alt="" src="/content/images/2021/linux.jpg" width="640" /></p>

<p>So, at this point we have our Linux base system.  You can do a few things from here.</p>
<ul>
  <li>I tend to immediately install vim (I’m spoiled, sorry vi)</li>
  <li>apt install wine and winetricks</li>
  <li>apt install steam_latest.deb (downloaded from store.steampowered.com).  If you’re like me, you’ve got a ton of Steam games, some of which are DRM-free (looking at you Tim Schafer)</li>
  <li>add the lutris PPA</li>
  <li>Adjust your screen resolution.  I’ll discuss this in more detail shortly, but 640x480 is actually a great resolution for every single game tested.  No need to scour for an 800x600 LCD.</li>
</ul>

<p>Let’s talk Games!</p>

<p>When I think about the PS2, my thoughts go back to my neighbor who had one.  He had Need for Speed:Underground 2, and he would be playing it every single time I came over.  It was a great game, and “Riders on the Storm” + Snoop Dogg became a touchpoint in our lives.  That was a long time ago now, but it was a blast to play it on the go.  Same with The Simpsons: Hit and Run, Psychonauts, the first Portal and Clive Barker’s Undying.  Games I hadn’t played in years.</p>

<p>Here’s a video of 2 of these surprise games: Portal and Need for Speed Underground 2</p>

<iframe width="900" height="600" src="https://www.youtube-nocookie.com/embed/FoPb4Hd53iU" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<p>The best part of this project has been getting to actually play all of my favorite games from the early 2000s.  Here’s the full list of games I tested, all running at 640x480</p>

<ul>
  <li>Psychonauts</li>
  <li>Need for Speed Underground 2</li>
  <li>Clive Barker’s Undying</li>
  <li>The Simpsons: Hit and Run</li>
  <li>Fallout and Fallout 2</li>
  <li>Halo: CE</li>
  <li>No One Lives Forever</li>
  <li>Portal</li>
  <li>Saints Row 2</li>
  <li>Warcraft 3</li>
  <li>XIII Classic</li>
  <li>Beyond Good and Evil</li>
  <li>Prince of Persia - The Sands of Time</li>
  <li>Rayman 3</li>
  <li>Serious Sam: The First Encounter</li>
  <li>Freddy Pharkas Fontier Pharmacist (bonus, not really a tough game to run)</li>
</ul>

<p><img alt="" src="/content/images/2021/fallout2.png" width="640" /></p>

<p>A word about Psychonauts</p>

<p><img alt="" src="/content/images/2021/psychonauts.png" width="640" /></p>

<p>You knew this was going to be top of mind this week!  I’ve been mightly impressed with Psychonauts 2, and it’s got me wanting to dive back into the original.  When I found out the Steam version was (1: linux native) and (2: DRM free), it warranted a special mention.</p>

<p><em>Notes -&gt;</em></p>
<ul>
  <li>Version: I installed the steam-linux native version, copied it out of /.local/steam/steamapps/common and into my games directory.</li>
  <li>Visual Settings: 640x480, low detail.</li>
  <li>Swap concerns: No swap needed.</li>
  <li>Input: XInput Controller supported</li>
</ul>

<p>Here’s a video I put together, using a direct HDMI capture from the compute stick, showing a few minutes of most of the games mentioned in this article.</p>

<iframe width="900" height="600" src="https://www.youtube-nocookie.com/embed/eus8CUsRFEY" title="gaming on the compute stick" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<p>OK, so I’ve shown that this chipset is capable of running games that are a generational leap over other low-end handhelds. How cheaply can we put one together ourselves?</p>

<p><img alt="" src="/content/images/2021/sandsoftime.png" width="640" /></p>

<p>Parts list:</p>
<ul>
  <li>Intel 8gb/1gb compute stick.  eBay - 30$</li>
  <li>640x480 5” LCD w/ HDMI compatible controller board and video cable.  26$</li>
  <li>32gb U3 class microsd, microcenter checkout aisle special.  5$</li>
  <li>generic wireless mini keyboard+trackpad combo, 13$</li>
  <li>2x 2000mah usb battery packs (one for display, one for CPU), 5$ at any supermarket</li>
</ul>

<p>So, retail cost using off-the-shelf components, 79$.  How would we bring this price down if we were designing our own system?</p>
<ul>
  <li>Swap out the keyboard/touchpad for a cheap microcontroller/arduino and some button switches/hats.  Could shave off 5$ here.</li>
  <li>Purchase the LCD controller+display in bulk instead of one-off, the above is sourced from a set of replacement parts for off the shelf LCD displays. Preferably a simpler controller board that eschews the AV/BNC/VGA connections.  Could shave off a few dollars here and there, but honestly the big savings would need to come in the cost of the LCD, or the SBC used to drive the device.</li>
</ul>

<p>So for now, 80$ is the low-end of the DIY ‘Steamin Deck’  I’ll be keeping my eye on the sbc market, always on the look-out for an affordable, underpowered x86 chipset.  Handheld makers hear my plea, the low-end market is ripe for upheaval!</p>

<p>With that said, I set about to put together an alpha version of the Steamin Deck using parts I had around my house, and the aforementioned test display.</p>

<p>First, how to connect a controller?  I have a few clips around, I’ll sacrifice one for this project.  A little bit of dremel work later, and we’ve got a controller clip that’ll slide right under the hdmi port.</p>

<p><img alt="" src="/content/images/2021/steaminwithcontroller.jpg" width="1000" /></p>

<p>As always, there’s quite a bit of leftovers once things are assembled.</p>

<p><img alt="" src="/content/images/2021/leftovers.jpg" width="1000" /></p>

<p>From there, I start to assemble the rest of the parts.  First, I use a u-bend hdmi connector so the compute stick is parallel to the screen.  A rubber bumper keeps it from bending too far.</p>

<p><img alt="" src="/content/images/2021/steaminback.jpg" width="1000" /></p>

<p><img alt="" src="/content/images/2021/steaminside.jpg" width="1000" /></p>

<p><img alt="" src="/content/images/2021/steaminbacktop.jpg" width="1000" /></p>

<p>This seemed precarious, and likely to snap off, so I added a metal bracket to relieve some of the pressure on the controller clip</p>

<p><img alt="" src="/content/images/2021/steaminsupportbracket.jpg" width="1000" /></p>

<p><img alt="" src="/content/images/2021/steaminbackbracket.jpg" width="1000" /></p>

<p>From here, it’s straightforward.  Boot into Linux and load some games!</p>

<p><img alt="" src="/content/images/2021/steamingrub.jpg" width="1000" /></p>

<p><img alt="" src="/content/images/2021/portablesimpsons.png" width="500" /></p>

<p>Here’s a video of Psychonauts “on the go!”</p>

<iframe width="900" height="600" src="https://www.youtube-nocookie.com/embed/Q4a1jqBOFpM" title="Psychonauts Portable" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<p>For an alpha handheld, the Steamin’ Deck meets 3 out of the 4 main criteria I have for a handheld</p>
<ol>
  <li>Portable</li>
  <li>Plays the games I want to play, right now</li>
  <li>It’s cheap</li>
  <li><del>Fits in my pocket</del></li>
</ol>

<p>I’m pretty sure I can tackle the pocketability with a few improvements for the next version</p>

<ol>
  <li>Use a telescoping game controller, bringing up the center of gravity and reducing the overall footprint. Smaller and no need for the strain-relief bolt.</li>
  <li>Find some smaller usb battery packs, the one I have at home is gigantic.</li>
  <li>Switch from an 8” screen to a 5” screen or smaller.</li>
</ol>

<p>Until then, be excellent to each other and game on!</p>
]]></content:encoded>
        <pubDate>Thu, 02 Sep 2021 08:33:24 +0000</pubDate>
        <link>https://hunterdavis.com/2021/09/02/x86-handheld.html</link>
        <guid isPermaLink="true">https://hunterdavis.com/2021/09/02/x86-handheld.html</guid>
      </item>
    
      <item>
        <title>RetroFW USB Networking and Multiplayer Duke Nukem</title>
        <description>While I was in the process of porting Johnny Castaway over to RetroFW devices, I got to know a bit more about the firmware, and these devices. I realized it would be possible to bridge the static usb debugging networks generated by each device. I show here that even a Raspberry Pi Zero is more than capable of acting as a bridge host for multiple systems.</description>
        <content:encoded><![CDATA[<p>While I was in the process of porting Johnny Castaway over to RetroFW devices, I got to know a bit more about the firmware, and these devices.  I realized it would be possible to bridge the static usb debugging networks generated by each device.  I show here that even a Raspberry Pi Zero is more than capable of acting as a bridge host for multiple systems.</p>

<p>As this is a full networking solution, this opens the door to netplay for any emulator or application which supports ip networking.  Yes, multiplayer SNES, GB/GBC/GBA link cable emulation, Doom, cross-platform networking and more are all achievable now.  You can also watch a quick co-op game of Duke Nukem between an RG300 and an LDK game system over at <a href="https://www.youtube.com/watch?v=C1WritVPKYI">my YouTube channel</a></p>

<iframe width="853" height="480" src="https://www.youtube-nocookie.com/embed/C1WritVPKYI" title="RG300 vs LDK" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>

<p>First, a little backstory. I love Johnny Castaway. For the past 33 years I’ve found a way to get it running on every system within arms reach.  Lately that’s meant porting the c version to various game consoles. Last week, that meant RetroFW devices like the LDK Game, RG3xx, and RS-97 series of handhelds and arcade machines.  I was having some trouble getting it running, and I had tried everything to capture the error logs.  I had tried graphical pop-ups, file output, nothing worked.  I was getting frustrated, and I began to go through the <a href="https://github.com/retrofw/">RetroFW Source Code</a> and <a href="https://github.com/retrofw/retrofw.github.io/wiki/Configuring-a-Toolchain">documentation</a>.</p>

<p>When I read that there was a hidden debugging network created when you plug the device into a host, I knew my troubles were over.  I could telnet straight in, execute my binary, and figure out the problem.  The problem, by the way, was that these devices don’t ship with an SDL2 library built-in.  They do for SDL1 though, and I had already backported Johnny to SDL1.2, so that wasn’t a big deal.  After that, it was smooth sailing.</p>

<p>Anyway, fast forward a week and I’ve been thinking about that debugging network all week.  Even though these devices don’t support mounting other devices in host mode, they do present a virtual USB ethernet network in client mode.  A Raspberry pi zero costs 5-10$, that’s a reasonable cost for a bridge device, barely more than  the cost of a USB cable. I set about to see if it were possible, and it turns out it’s ridiculously easy.  Read on as I detail the four files you can edit to enable USB networking (and thus, multiplayer) on any RetroFW device.</p>

<p>Here’s the gist of it.</p>
<ul>
  <li>Step 1: Edit the network settings and launch link for RetroFW Device 1</li>
  <li>Step 2: Edit the network settings and launch link for RetroFW Device 2</li>
  <li>Step 3: Enable ipv4 forwarding on your bridge device</li>
  <li>Step 4: Plug it all it, power it all on, and launch</li>
  <li>Success!</li>
</ul>

<p>First, we’ll edit the default network on the RetroFW device we want to be the ‘server’ for our Duke Nukem multiplayer lan party!</p>

<p>Mount the filesystem of your first RetroFW device, in this case an RG300, and edit ‘/etc/networking/interfaces’ You’re going to want to change the subnet address from 169.254.1.1 to 169.254.2.1.  Your interfaces file will look like</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>auto lo
iface lo inet loopback

allow-hotplug usb0
iface usb0 inet static
       address 169.254.2.1
       netmask 255.255.255.0
       network 169.254.2.0
       broadcast 169.254.2.255
       up dnsmasq
       up route add default gw 169.254.2.2
       down killall dnsmasq
</code></pre></div></div>

<p>Next, update your ‘/etc/dnsmasq.conf’ file to match, like so:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>interface=usb0
port=0
dhcp-range=169.254.2.2,169.254.2.2,255.255.255.0,12h
dhcp-option=3 
</code></pre></div></div>

<p>Next, let’s create a launch link for our duke nukem server launch. (make sure you’ve installed the RetroFW version of duke nukem 3d, most come with it installed by default.)  Here’s what my ‘/RETROFW/apps/gmenu2x/sections/games/serverduke32.default.retrofw.lnk’ looks like:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>title=Server-EDuke32
description=Duke Nukem 3D port
icon=/home/retrofw/Ports.Pack/eduke32.opk#eduke32.png
opk[icon]=eduke32.png
exec=/home/retrofw/Ports.Pack/eduke32.opk
params=eduke32.elf -server
manual=eduke32.man.txt
</code></pre></div></div>

<p>Next, we’ll edit the default network on the RetroFW device we want to be the ‘client’ joining our Duke Nukem multiplayer lan party!!</p>

<p>Mount the filesystem of your second RetroFW device, in this case my trusty LDK game, and edit ‘/etc/networking/interfaces’ You’re going to want to change the subnet address from 169.254.1.1 to 169.254.3.1.  Your interfaces file will look like</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>auto lo
iface lo inet loopback

allow-hotplug usb0
iface usb0 inet static
       address 169.254.3.1
       netmask 255.255.255.0
       network 169.254.3.0
       broadcast 169.254.3.255
       up dnsmasq
       up route add default gw 169.254.3.2
       down killall dnsmasq
</code></pre></div></div>

<p>Next, update your ‘/etc/dnsmasq.conf’ file to match, like so:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>interface=usb0
port=0
dhcp-range=169.254.3.2,169.254.3.2,255.255.255.0,12h
dhcp-option=3 
</code></pre></div></div>

<p>Next, let’s create a launch link for our duke nukem client launch.  Here’s what my ‘/RETROFW/apps/gmenu2x/sections/games/clientduke32.default.retrofw.lnk’ looks like:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>title=Client-EDuke32
description=Duke Nukem 3D port
icon=/home/retrofw/Ports.Pack/eduke32.opk#eduke32.png
opk[icon]=eduke32.png 
exec=/home/retrofw/Ports.Pack/eduke32.opk 
params=eduke32.elf -connect 169.254.2.1 
manual=eduke32.man.txt
</code></pre></div></div>

<p>Next, we’ll enable ipv4 forwarding on our bridge device.  Mount up your bridge device filesystem, in this case our RasPi Zero, and enable ipv4 forward in (at least for debian-esque systems) ‘/etc/sysctl.conf’.</p>

<p>Find the line that looks like:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#net.ipv4.ip_forward=1
</code></pre></div></div>

<p>and uncomment it to look like:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>net.ipv4.ip_forward=1
</code></pre></div></div>

<p><img alt="" src="/content/images/2021/ip_forwarding.png" width="1126" /></p>

<p>For most systems, that’s enough.  For raspbian, it doesn’t include network manager by default.  Simply run:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt install network-manager network-manager-gnome
</code></pre></div></div>

<p>and you’ll be good to plug and play as many devices into your raspberry pi as you like, with no additional configuration.</p>

<p>Here you can see all of the files you need to edit, across all 3 systems in this scenario, in one photo:</p>

<p><img alt="" src="/content/images/2021/retrofw_config_files.png" width="1126" /></p>

<p>Finally, let’s get it all running.  I use a cheap microSD card I picked up at MicroCenter, and it’s not particularly fast.  In this case it takes a full 2 minutes to boot.  Plug the Pi Zero into a power supply, in this case a cheap usb battery pack. I’ve found that even a cheap usb battery pack will keep this raspi bridge running for many, many hours. At any rate, wait a full 2 minutes before you plug in a device.</p>

<p>After your bridge device has booted, plug in your first RetroFW device to the RasPi. When the prompt to ‘mount filesystem’ comes up, hit ‘b’ for ‘charge only’, and after 5 seconds the virtual ethernet port will come up with the static IP that you set for the first device.</p>

<p>Next, plug in your second RetroFW device to the RasPi. When the prompt to ‘mount filesystem’ comes up, hit ‘b’ for ‘charge only’, and after 5 seconds the virtual ethernet port will come up with the static IP that you set for the client.</p>

<p>At this point, provided ipv4 packet forwarding is working properly on your bridge device, your RetroFW devies are fully networked.  You know what that means, it’s Duke Nukem 3D time!!</p>

<p>Launch the ‘Server-Duke3d’ link we created above first.  Select your server options and launch the game proper.</p>

<p><img alt="" src="/content/images/2021/duke_nukem_server.jpg" width="1126" /></p>

<p>After you’re in, you can launch the client link we created above on any other RetroFW devices we’re networked to.  Finally, we’ll power it all on and get to gaming!</p>

<p><img alt="" src="/content/images/2021/duke_nukem_coop.jpg" width="1126" /></p>

<p>And that’s that.  I’ve noticed that the RetroFW port of snes9x still has the netplay code compiled in, that’s a logic next target for multiplayer gaming via “link cable.”  Stay tuned!</p>
]]></content:encoded>
        <pubDate>Sun, 01 Aug 2021 08:33:24 +0000</pubDate>
        <link>https://hunterdavis.com/2021/08/01/retrofw-usb-multiplayer-networking.html</link>
        <guid isPermaLink="true">https://hunterdavis.com/2021/08/01/retrofw-usb-multiplayer-networking.html</guid>
      </item>
    
      <item>
        <title>Johnny Casaway RetroFW Released!</title>
        <description>Johnny Castaway for RetroFW devices is now released! This is the firmware that you’ll find running on all your favorite Chinese handheld devices. Things like the LDK game, RG-300, RS97, etc. It is based on my SDL 1.2 port of the engine, and generally works very well.</description>
        <content:encoded><![CDATA[<p>Johnny Castaway for RetroFW devices is now released!  This is the firmware that you’ll find running on all your favorite Chinese handheld devices.  Things  like the LDK game, RG-300, RS97, etc.  It is based on my SDL 1.2 port of the engine, and generally works very well.</p>

<p>There’s not much to the install, just download the .ipk file and install it from your RetroFW file manager.  You’ll have a launchable Johnny Castaway icon/shortcut in your applications folder. You can press any key to exit.</p>

<p>You can find the .ipk file to install <a href="https://github.com/huntergdavis/jc_reborn/blob/sdl_12_retrofw/bin/johnny.ipk">here</a></p>

<p>You can find the source code <a href="https://github.com/huntergdavis/jc_reborn/tree/sdl_12_retrofw">here</a></p>

<p>Here you can see how Johnny Castaway will look in your RetroFW library view here
<img alt="" src="/content/images/2021/johnny_menu.jpg" width="1126" /></p>

<p>And here’s an action shot
<img alt="" src="/content/images/2021/johnny_running_rg300_ldk.jpg" width="1126" /></p>

<p>If you’re interested in the source code, there are also a few half-working ports in the above repository.  Things like the original xbox, low-memory versions for various embedded systems, etc.  I’m just having a lot of fun making sure Johnny runs everywhere :)</p>

]]></content:encoded>
        <pubDate>Sun, 25 Jul 2021 16:33:24 +0000</pubDate>
        <link>https://hunterdavis.com/2021/07/25/johnny-castaway-for-retrofw-released.html</link>
        <guid isPermaLink="true">https://hunterdavis.com/2021/07/25/johnny-castaway-for-retrofw-released.html</guid>
      </item>
    
      <item>
        <title>Johnny Dreamcastaway Released!</title>
        <description>Johnny Castaway for the Dreamcast is now released! I like to call it Johnny Dreamcastaway, and it didn’t take me too long to port. It’s working splendidly! A glorious internal 640x480 screen resolution and a rock-solid 60 FPS carry you forward to your private island with “Johnny Dreamcastaway.” Read on for more info and downloads!</description>
        <content:encoded><![CDATA[<p>Johnny Castaway for the Dreamcast is now released!  I like to call it Johnny Dreamcastaway, and it didn’t take me too long to port. It’s working splendidly!  A glorious internal 640x480 screen resolution and a rock-solid 60 FPS carry you forward to your private island with “Johnny Dreamcastaway.” Read on for more info and downloads!</p>

<p>You can download a .CDI image to emulate or burn for a real Dreamcast <a href="https://github.com/huntergdavis/jc_reborn/blob/DreamSDK/johnny.cdi">here</a></p>

<p>You can download the unscrambed release .elf to emulate <a href="https://github.com/huntergdavis/jc_reborn/blob/DreamSDK/johnny_dreamcastaway.elf">here</a></p>

<p>You can view the source code <a href="https://github.com/huntergdavis/jc_reborn/tree/DreamSDK">here</a></p>

<p>Here you can see how “Johnny Dreamcastaway” will look in your REDREAM library view
<img alt="" src="/content/images/2021/johnny_emu.png" width="1126" /></p>

<p>Here’s an animated GIF of “Johnny Dreamcastaway” loading in a Dreamcast emulator
<img alt="" src="/content/images/2021/johnny_load.gif" width="640" /></p>

<p>As I wrote last week, I stumbled upon the newest code for ‘Johnny Reborn’ (https://github.com/jno6809/jc_reborn), written by the talented Jérémie GUILLAUME, and immediately wanted to port it to the Dreamcast.</p>

<p>I had originally started writing this port last week when I backported jc_reborn to SDL 1.2 and framebuffer console enabled low-end computers.  I ran into a few issues with my post-compilation build environment, and decided to put it on hold until a physical Dreamcast comes in (since writing I’ve ordered one on eBay, should be here in a week or so.)</p>

<p>Well, I couldn’t wait.  I did a bit more digging, and it turns out there’s a very nice packaged environment for the Dreamcast called DreamSDK.  This runs on Windows exclusively, so I flashed the Windows 10 image onto my GPD MicroPC and got to work!</p>

<p>DreamSDK really is quite nice as far as development environments go.  It has a nice integration with CodeBlocks (which I hadn’t used in years, and is still quite solid in 2021.)  It also has a straightforward build environment and starter project that let me quickly get down to writing and packaging up ELF binaries for the Dreamcast.</p>

<p>Once I had a starter ELF that I knew worked on emulators, I began adding in all the functionality of ‘Johnny Reborn,’ moving the assets into a ramdisk and loading them from memory.  This has the added benefit of no drive usage after boot, helpful for those looking to reduce wear and tear on their physical Dreamcast consoles.</p>

<p>And that’s that!  You can view the source updates (and a sample PR) necessary to get this compiling in my jc_reborn/DreamSDK source tree <a href="https://github.com/huntergdavis/jc_reborn/compare/SDL1.2...huntergdavis:DreamSDK?expand=1">here</a>.</p>

<p>And again, here’s your downloads:</p>

<p>You can download a .CDI image to emulate or burn for a real Dreamcast <a href="https://github.com/huntergdavis/jc_reborn/blob/DreamSDK/johnny.cdi">here</a>  This is using the audio/data selfboot method, so if that doesn’t work on your Dreamcast I’ve also included the unscrambled release elf below.</p>

<p>You can download the unscrambled release .elf to emulate <a href="https://github.com/huntergdavis/jc_reborn/blob/DreamSDK/johnny_dreamcastaway.elf">here</a></p>

<p>You can view the source code <a href="https://github.com/huntergdavis/jc_reborn/tree/DreamSDK">here</a></p>

<p>What next?  Well I’m not sure I’m happy with the boot logo, and I could add in controller or VMU support for some fun times.  Still, I’m thinking I’ll set my sights on a Nintendo Switch port next time, shouldn’t take too long either!</p>

]]></content:encoded>
        <pubDate>Sun, 21 Mar 2021 08:33:24 +0000</pubDate>
        <link>https://hunterdavis.com/2021/03/21/johnny_dreamcastaway_released.html</link>
        <guid isPermaLink="true">https://hunterdavis.com/2021/03/21/johnny_dreamcastaway_released.html</guid>
      </item>
    
      <item>
        <title>Johnny Castaway Native Live CD</title>
        <description>Once again, I am reminded of how much the past influences our future, and the choices we make. In my case, it’s a twisty tale that starts simply enough, but ends with Johnny Castaway running natively from a ramdisk on systems with as little as 64mb. Interested? Read on. Want to download it for yourself right now? Skip to the end!</description>
        <content:encoded><![CDATA[<p>Once again, I am reminded of how much the past influences our future, and the choices we make.  In my case, it’s a twisty tale that starts simply enough, but ends with Johnny Castaway running natively from a ramdisk on systems with as little as 64mb.  Interested?  Read on.  Want to download it for yourself right now?  Skip to the end!</p>

<p><img alt="" src="/content/images/2021/vbox_johnny.png" width="640" /></p>

<p><a href="/content/images/2021/64mb_ram_vm_boot.webm">And here’s a nice video from VirtualBox :)</a></p>

<p>This story starts with wonderful news, one of the talented developers working to re-implement Johnny Castaway has done so in a languge I quite enjoy (ansi c), and quite successfully.  When I stumbled upon the newest code for ‘Johnny Reborn’ (https://github.com/jno6809/jc_reborn), written by the talented Jérémie GUILLAUME, a few things stood out to me:</p>

<ol>
  <li>This is a fully baked re-implementation of Johnny Castaway</li>
  <li>It’s currently working</li>
  <li>It’s written in ansi C-99 and SDL 2</li>
  <li>The above code is quite clean, enjoyably so</li>
  <li>It is criminally under-exposed for how good it is (2 watchers, 8 stars, 1 fork (mine))</li>
</ol>

<p>There have been a few re-implementations of Johnny over the years, but I’ve always chosen to emulate Johnny using Dosbox or Wine.  Why?  These re-implementations used resource-intensive high-level languages and libraries.  They wouldn’t run particularly well on a 25 year old PC!  I know that’s not a use case most folks still have, but it’s of special interest to me :) So when I dug into this re-implementation, I knew it was something special.  Clean, straightforward code.  Runs in a few megs of ram, no noticeable memory leaks, low CPU usage even on ancient (486) class machines.  Immediately made me smile in a way I hadn’t in some time.</p>

<p>So, I did what anyone in my situation would do, I set out to cross-compile a 32-bit version of Johnny I could boot live on low-end systems (edit: tested working with as low as 64mb ram!).  [download that binary, or a live linux ISO] (https://github.com/huntergdavis/jc_reborn/ )</p>

<p>This worked well enough, but unfortunately at least one of the laptops I was booting it on doesn’t support Xvesa/Xorg.  Framebuffer was an option through, so I set about to boot to console and execute in console-FB.</p>

<p>Bummer, SDL 2.0 doesn’t support console framebuffer any longer.  I was facing a large number of hoops to try and layer in xfcb-dev onto tinycore and boot on my particular craptop, and I realized something.</p>

<p>Lightbulb moment!  Why not just re-write the graphics layer of johnny-reborn in SDL 1.2?.  That does support framebuffer backends, and it’s fairly similar to SDL 2!  So that’s just what I did, a quick SDL 2.0-&gt;1.2 backport for Johnny.  <a href="https://github.com/huntergdavis/jc_reborn/tree/SDL1.2">Source here</a></p>

<p>Second Lightbulb moment!  SDL 1.2 doesn’t just support framebuffer backends.  It’s fifteen+ years old at this point, and it supports some popular systems of that era.  One in particular caught my eye - the Sega Dreamcast.  Why?</p>

<ol>
  <li>I love the Sega Dreamcast.  So Much.</li>
  <li>It supports 640x480 natively, default resolution for JC_reborn, no need to write a scaler</li>
  <li>You can craft an ISO with the right audio track and boot on many stock Dreamcast units.</li>
  <li>Emulators are plentiful and run on all kinds of hardware (Android, game devices, etc)</li>
</ol>

<p>So, I set about my plan.</p>

<ol>
  <li>Install the kallistos libraries and cross-compile environment</li>
  <li>compile kallistos-ports (including sdl1.2)</li>
  <li>update the init and file i/o for johnny to dreamcast flavor</li>
  <li>compile elf executable, convert to bin, scramble bin, convert to 1ST_RUN.BIN</li>
  <li>assemble IP.BIN, assemble iso, convert to CDI</li>
  <li>test on emulator</li>
</ol>

<p>Out of scope for this initial release</p>
<ol>
  <li>Updating dc-specific features (i.e. VMU support)</li>
  <li>Testing on actual hardware (I’ll need to buy one that supports reading CD-R disks, pre-2000 manufacture date)</li>
</ol>

<p>How did that go?  Well, I’ve found out something that many Dreamcast developers know very well, it’s very hard to debug i/o in an emulator!  Much easier on actual hardware.  So, pending my next purchase of a Dreamcast, those preliminary commits are available for anyone looking to try. <a href="https://github.com/jno6809/jc_reborn/compare/master...huntergdavis:dreamcast?expand=1">here</a></p>

<p>Anyway, back to the live CD, I was looking to boot with a dynamically linked SDL 1.2 with console-framebuffer support (SDL 1.2 only allowed static linking if you buy a pro license, boo!).  There were still a couple of hoops to jump through though:</p>

<ol>
  <li>Mouse support!  Not likely.  Export SDL_NOMOUSE=1 (you’ll see this in /home/tc/.profile on the ISO)</li>
  <li>pass ‘‘text’ parameter to grub on boot (don’t attempt to startx)</li>
  <li>set the desired vga output for FBconsole.  This gets picked up from the vga=XXX grub boot parameter (640x480x32 is vga=786)</li>
  <li>auto-start johnny directly.  For the live CD I just add this to /home/tc/.profile and busybox will pick it up on autologin.</li>
</ol>

<p>And that’s about it!  You can download a live ISO that’ll boot to ram from any supported medium (17 megabytes or above, sorry floppy friends!)  <a href="https://github.com/huntergdavis/jc_reborn/blob/SDL1.2/johnny_dc.iso">here</a>  A giant thanks to <a href="https://github.com/jno6809">Jérémie GUILLAUME</a> for re-implementing Johnny in a clean, portable format that really made my day!!</p>

<p><a href="/content/images/2021/thinkpad_johnny_960.webm">Here’s a video of that very ISO booting from a burnt-CD (remember those!) on my beloved 2001 era Thinkpad (256mb RAM)</a></p>

]]></content:encoded>
        <pubDate>Wed, 10 Mar 2021 08:33:24 +0000</pubDate>
        <link>https://hunterdavis.com/2021/03/10/johnny_castaway_native_port_and_livcd.html</link>
        <guid isPermaLink="true">https://hunterdavis.com/2021/03/10/johnny_castaway_native_port_and_livcd.html</guid>
      </item>
    
      <item>
        <title>I bought and hacked the Atari Mini Pong Jr. So You Don&apos;t Have To!</title>
        <description>This story starts, as most of my hardware hacking stories do: a stupid impulse purchase. In this case, it’s the Atari mini pong Jr. I’m pretty sure (judging from stock levels) I’m the only one dumb enough to pick this one up. So, I set about to hack the thing. It’s almost disappointing, as this isn’t as much of a ‘hack’ as it is ‘this system is wide open.’ Here’s what I’ve been able to determine/do with zero hardware modification. (TLDR; Everything. Install and run apps, usb devices, adb shell, etc)</description>
        <content:encoded><![CDATA[<p>This story starts, as most of my hardware hacking stories do: a stupid impulse purchase.  In this case, it’s the Atari mini pong Jr.  I’m pretty sure (judging from stock levels) I’m the only one dumb enough to pick this one up.  So, I set about to hack the thing.  It’s almost disappointing, as this isn’t as much of a ‘hack’ as it is ‘this system is wide open.’  Here’s what I’ve been able to determine/do with zero hardware modification. (TLDR; Everything.  Install and run apps, usb devices, adb shell, etc)</p>

<p><img alt="" src="/content/images/2020/dec/recentfiles.jpg" width="600" /></p>

<p><img alt="" src="/content/images/2020/dec/Screenshot_1970-01-02-08-46-26.png" width="600" /></p>

<p>I started by simply connecting to my linux laptop via usb-micro.  Adb devices showed an open debug device, and adb connect worked.  From there, you can install anything, launch packages or apps, etc.  Usb peripherals work, and from the looks of it usb ethernet would also allow for internet connectivity and wireless adb.  Given the under-powered nature of the device (see geekbench below) I don’t find it’s particular worthwhile to install retroarch etc, but if you’re looking to get some more mileage out of your device it’ll be easy peasy.</p>

<p><img alt="" src="/content/images/2020/dec/Screenshot_1970-01-02-08-46-02.png" width="600" /></p>

<p>Random thoughts / info -&gt;</p>

<ol>
  <li>This is simply an android device without a touchscreen.  Wide open, with adb enabled.</li>
  <li>You can hit ctrl-t for a framecounter</li>
  <li>You can hit print-screen for a screenshot</li>
  <li>Alt-tab works.</li>
  <li>Adb shell lists the following default installed packages (plus I installed geekbench), there’s some interesting stuff in there (minipongautotest) leading me to believe this device was rushed out.</li>
  <li>There are 2 gigs free on the device.</li>
  <li>The pong app is a unity app, and it struggles to maintain a solid 60fps.</li>
  <li>Apps installed will show up on the default launcher (it’s not parsing config files etc, it’s a standard android launcher, see screenshot)</li>
  <li>Mali 400 gpu, I installed geekbench, Arm sun8i at 1.34ghz, half a gig of ram</li>
  <li>This is definitely not worth 130$, a bit of a cash grab if you ask me.</li>
  <li>The addition of an 18650 battery (pictured below) allows charging and playback from battery.</li>
</ol>

<p><img alt="" src="/content/images/2020/dec/18650.jpg" width="600" /></p>

<p>Package list -&gt;</p>

<ul>
  <li>root@astar-y3:/ # pm list packages -f</li>
  <li>package:/system/app/PrintSpooler.apk=com.android.printspooler</li>
  <li>package:/system/priv-app/DefaultContainerService.apk=com.android.defcontainer</li>
  <li>package:/system/framework/framework-res.apk=android</li>
  <li>package:/system/priv-app/Settings.apk=com.android.settings</li>
  <li>package:/system/priv-app/ContactsProvider.apk=com.android.providers.contacts</li>
  <li>package:/data/app/com.UNIS.MiniPongAutoTest-1.apk=com.UNIS.MiniPongAutoTest</li>
  <li>package:/system/priv-app/ExternalStorageProvider.apk=com.android.externalstorage</li>
  <li>package:/system/app/PartnerBookmarksProvider.apk=com.android.providers.partnerbookmarks</li>
  <li>package:/system/app/LatinIME.apk=com.android.inputmethod.latin</li>
  <li>package:/system/priv-app/TeleService.apk=com.android.phone</li>
  <li>package:/system/app/BasicDreams.apk=com.android.dreams.basic</li>
  <li>package:/system/app/WisdomTest.apk=com.wisdom.WisdomTest</li>
  <li>package:/system/priv-app/ProxyHandler.apk=com.android.proxyhandler</li>
  <li>package:/system/app/HTMLViewer.apk=com.android.htmlviewer</li>
  <li>package:/system/app/AllApp.apk=com.rk_itvui.allapp</li>
  <li>package:/system/priv-app/SystemUI.apk=com.android.systemui</li>
  <li>package:/system/app/LiveWallpapersPicker.apk=com.android.wallpaper.livepicker</li>
  <li>package:/system/app/SpeechRecorder.apk=com.android.speechrecorder</li>
  <li>package:/system/app/KeyChain.apk=com.android.keychain</li>
  <li>package:/system/priv-app/InputDevices.apk=com.android.inputdevices</li>
  <li>package:/system/app/PackageInstaller_WD.apk=com.android.packageinstaller</li>
  <li>package:/system/priv-app/hc_sy.apk=com.hc.rotation</li>
  <li>package:/system/app/TelephonyProvider.apk=com.android.providers.telephony</li>
  <li>package:/system/app/LiveWallpapers.apk=com.android.wallpaper</li>
  <li>package:/system/app/FileExplore.apk=com.softwinner.explore</li>
  <li>package:/system/priv-app/PicoTts.apk=com.svox.pico</li>
  <li>package:/system/priv-app/OneTimeInitializer.apk=com.android.onetimeinitializer</li>
  <li>package:/system/app/DownloadProviderUi.apk=com.android.providers.downloads.ui</li>
  <li>package:/system/app/UserDictionaryProvider.apk=com.android.providers.userdictionary</li>
  <li>package:/system/app/Update.apk=com.softwinner.update</li>
  <li>package:/system/app/DocumentsUI.apk=com.android.documentsui</li>
  <li>package:/system/priv-app/SharedStorageBackup.apk=com.android.sharedstoragebackup</li>
  <li>package:/system/priv-app/FusedLocation.apk=com.android.location.fused</li>
  <li>package:/system/priv-app/BackupRestoreConfirmation.apk=com.android.backupconfirm</li>
  <li>package:/system/priv-app/SettingsProvider.apk=com.android.providers.settings</li>
  <li>package:/system/priv-app/VpnDialogs.apk=com.android.vpndialogs</li>
  <li>package:/system/priv-app/Keyguard.apk=com.android.keyguard</li>
  <li>package:/system/app/Provision.apk=com.android.provision</li>
  <li>package:/data/app/com.UNIS.MiniPong-1.apk=com.UNIS.MiniPong</li>
  <li>package:/system/app/PacProcessor.apk=com.android.pacprocessor</li>
  <li>package:/system/priv-app/MediaProvider.apk=com.android.providers.media</li>
  <li>package:/system/priv-app/Shell.apk=com.android.shell</li>
  <li>package:/system/app/CertInstaller.apk=com.android.certinstaller</li>
  <li>package:/system/priv-app/DownloadProvider.apk=com.android.providers.downloads</li>
</ul>

]]></content:encoded>
        <pubDate>Sun, 20 Dec 2020 08:33:24 +0000</pubDate>
        <link>https://hunterdavis.com/2020/12/20/hacking-atari-pong-jr-mini.html</link>
        <guid isPermaLink="true">https://hunterdavis.com/2020/12/20/hacking-atari-pong-jr-mini.html</guid>
      </item>
    
  </channel>
</rss>
