]> fortfriendship.online Git - gnargle.github.io.git/blob - projects/pipboy.html
09bc715e8ebd28a2bd60ed6615391b8783d69e00
[gnargle.github.io.git] / projects / pipboy.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="UTF-8" />
5 <title>Pipboy Prop Custom Apps</title>
6 <meta property="og:title" content="Pipboy Prop Custom Apps" />
7 <meta name="twitter:title" content="Pipboy Prop Custom Apps" />
8 <meta
9 name="description"
10 content="There's an official Fallout TV show prop. It's hackable."
11 />
12 <meta
13 property="og:description"
14 content="There's an official Fallout TV show prop. It's hackable."
15 />
16 <meta
17 name="twitter:description"
18 content="There's an official Fallout TV show prop. It's hackable."
19 />
20 <meta
21 property="article:published_time"
22 content="2025-03-19T00:00:00+00:00"
23 />
24 <meta
25 property="og:image"
26 content="https://athene.gay/img/projects/pipboy/pipboy2.jpg"
27 />
28 <meta
29 name="twitter:image"
30 content="https://athene.gay/img/projects/pipboy/pipboy2.jpg"
31 />
32 <link rel="stylesheet" href="../main.css" />
33 </head>
34 <body class="whole-site">
35 <div>
36 <iframe class="embed-title" src="../shared/title.html"> </iframe>
37 <div class="main-container">
38 <div class="main">
39 <div class="entry">
40 <a href="../index.html">Home</a>
41 <div class="title-block">
42 <a
43 class="blog-title"
44 target="_blank"
45 href="https://github.com/gnargle/pipboy-apps"
46 >
47 <h3>Pipboy Prop Custom Apps</h3>
48 </a>
49 <h3 class="datestamp">2025</h3>
50 </div>
51 <div class="content">
52 <p>There's an official Fallout TV show prop. It's hackable.</p>
53 <p>
54 OK, we're doing something a little different with this one. But
55 first the preamble.
56 </p>
57 <div class="title-block">
58 <h3 class="blog-title">The Preamble</h3>
59 <h3 class="datestamp">19/03/2025</h3>
60 </div>
61 <p>
62 So I haven't cosplayed properly in a while. I did it prettyu
63 regularly in 2023, but 2024 was a nadir for me menty h and
64 cosplay, with its ill-fitting, itchy fabrics that are not
65 designed with trans people in mind, was not gonna help that. I
66 didn't go to many cons, those I did I avoided being in cosplay,
67 yadda yadda.
68 </p>
69 <p>
70 Thing is, is I do actually really like cosplay, when I'm of the
71 frame of mind to do it. I like prop work. I like wearing the
72 clothes Cat has designed for me. It's fun when it's not autistic
73 agony.
74 </p>
75 <p>
76 You may have noticed I've got mad into Fallout of late. See the
77 previous entry on this blog. I've loved Fallout for a long time
78 but never really considered cosplay for it, not really sure why.
79 </p>
80 <p>
81 But this dive back into the series coincided well with me
82 wanting to get back into cosplay proper. And because I want to
83 do it properly, I've gone a bit all out.
84 </p>
85 <p>
86 I've ordered a reaaaalllly nice vault 33 suit, with backpack.
87 I'm gonna dye my hair instead of wearing a wig, which is the
88 worst thing sensory-wise for me in cosplay.
89 </p>
90 <p>And, I made a Pip-Boy! Look at it here, it's pretty great!</p>
91 <a href="../img/projects/pipboy/pipboy-homemade.jpg">
92 <img
93 class="blog-img-lrg"
94 src="../img/projects/pipboy/pipboy-homemade.jpg"
95 alt="A photo of the home-made pip-boy in question. It looks pretty accurate but it is very very large."
96 />
97 </a>
98 <p>It's also <i>absolutely fucking massive.</i></p>
99 <p>
100 Wearing it is deeply uncomfortable and my arms get tired after
101 mere minutes, let alone the hours of continuous wear a con would
102 require. It's impractical.
103 </p>
104 <p>
105 There is, however, a solution. Bethesda and 'The Wand Company'
106 produce a screen-accurate version of the tv series hero prop,
107 which normally wouldn't particularly interest me, as often
108 screen-accurate props are just display pieces and are
109 non-functional.
110 </p>
111 <p>
112 Props I use for cosplay need to have flare. I use LEDs to make
113 them nicer, or in the case of my own homebrew pipboy, I was
114 using a phone with an android app that mimics the Fallout 3
115 pip-boy interface, fully interactable. That's cool! And it's a
116 showcase!
117 </p>
118 <p>
119 But luckily this prop also actually works. It features a lot of
120 animations from the tv show, but more to the point, all the
121 dials on it function and are used to interact with it. It's
122 really excellent.
123 </p>
124 <p>
125 It's expensive, though, and that alone wouldn't have been enough
126 to sway me. That is, until I did a little bit of digging and
127 discovered that
128 <a
129 href="https://log.robco-industries.org/documentation/pipboy-3000/"
130 >the firmware is customisable, supporting custom applications
131 out of the box.</a
132 >
133 </p>
134 <p>
135 That's basically a red rag to a bull for me. I
136 <i>love</i> writing software for esoteric things. I mean. Look
137 at the projects on this website. Two of them use a midi device
138 and one of them is a plugin for a videogame. I've also written
139 plenty of software for and interfacing with embedded hardware.
140 This is simply made for me!
141 </p>
142 <p>
143 But if you click through the link at the top there, you'll
144 notice that there's basically nothing in the repository right
145 now. That's because, dear reader, we're gonna be exploring this
146 hardware TOGETHER. IN REAL TIME.
147 </p>
148 <p>
149 There's a sequence at the start of the social network where zuck
150 liveblogs him making facesmash. A lot of what he writes is
151 despicable, and the concept of facesmash is awful, but I dfo
152 love the idea of liveblogging a project. It's not something I
153 have really done before. So we're gonna do it with this one.
154 </p>
155 <p>
156 It's a good candidate. There's some documentation at the above
157 link, but not a lot, and there's lots left to explore in terms
158 of how the system works. The author of the above linked article
159 makes an assumption, for example - that the graphics context
160 should be one bit per pixel - but I don't think that's actually
161 the case. There are different tones in the monochrome screen,
162 and it doesn't look like they're made using dithering. So how
163 are they done? That's jsut one of many questions we will explore
164 together.
165 </p>
166 <p>
167 My ultimate aim here is to put something like the in-game stats
168 screen together. When I was setting up my homemade pip-boy, I
169 put some funny and personaly jokes into what stats and perks I
170 picked - being able to replicate them here would be really nice.
171 </p>
172 <p>
173 There's a long walk between here and there, though, so strap in.
174 </p>
175 <p>
176 However, let's get one thing straight here - I'm not a teenager
177 in a university dorm running on monster energy and rage. I'm a
178 31 year old woman with a full-time job and a bedtime.
179 </p>
180 <p>
181 So the 'liveblog' will not be me hacking away at this until 4AM,
182 oh no no. I will be working on this off and on over the next few
183 weeks most likely, and keeping this post updated as I go.
184 </p>
185 <p>
186 I am sure you will agree that this is a much healthier choice.
187 </p>
188 <div class="title-block">
189 <h3 class="blog-title">Beginnings</h3>
190 <h3 class="datestamp">19/03/2025</h3>
191 </div>
192 <p>
193 OK, so, the device itself. This is a boutique prop with
194 functionality that, while not an afterthought, is certainly not
195 economically worthy of any kind of custom silicon. This is a
196 collector's item, there's only a few thousand of them made, best
197 to use something off the shelf.
198 </p>
199 <p>
200 And, indeed, it does! An STM32 to be exact, an absolute
201 <i>classic</i> bit of IC hardware. The STM32 series are ARM
202 microcontrollers, architecturally similar to the hardware in
203 your common or garden smartphone. ARM is wonderful because it's
204 somehow managed to succeed in all 3 corners of the 'you can only
205 have two' triangle: it's [relatively] quick, it's cheap, and
206 it's Good. It also sips power relative to bigger, more
207 traditional chips, but that's true of any microcontroller,
208 really, so shouldn't really be counted as a strength here.
209 </p>
210 <p>
211 I was a smidge surprised to see an ARM chip in this - if this
212 were a homebrew project you'd expect probably an arduino, an
213 RP2040 or maybe a teensy - but this thing does have some
214 relatively complex graphics to drive.
215 </p>
216 <p>
217 I imagine the main reason this was chosen, however, was hardware
218 video decoding capability. Most (maybe all?) of the show-derived
219 animations are video files on-disk that are just decoded and
220 straight to the graphics context. You can argue this is cheating
221 if you want but to me it reeks of sensible design. Instead of
222 requiring the programmers to design and animate elegantly in a
223 very inelegant context (we'll get to that, believe me), you get
224 the raw files made for the show, re-encode them, and plonk them
225 on. Easy!
226 </p>
227 <p>
228 Additionally, the raw power the STM32 chip here has allows for a
229 less conventional (but friendlier-ish) development context. This
230 chip uses
231 <a href="https://www.espruino.com/">Espruino</a>.
232 </p>
233 <p>
234 Espruino is javascript for microcontrollers. Some of you may
235 have just hissed, and you'd be right to. Javascript is, pretty
236 infamously, horrible. It's heavy and unwieldy, it's untyped,
237 it's messy, it's functional-but-not-quite. If you want an
238 example of how not to design a programming language, you need
239 look no further than javascript. Yet because it runs in-browser,
240 it is the most common language in the world. Go figure.
241 </p>
242 <p>
243 Some of the words in that paragraph may have you convinced that
244 javascript is a bad fit for the lean, high-performance world of
245 microcontrollers, and really, you'd be right. But that hasn't
246 stopped the most insane people alive, javascript monodevelopers,
247 from crowbarring it into them anyway. And so: Espruino.
248 </p>
249 <p>
250 Cards on table, I've never used Espruino before today. I've
251 touched basically every other microcontroller going, and
252 everything else uses C++. I'm not a great C++ programmer, but I
253 can get by.
254 </p>
255 <p>
256 Comparative to my javascript, I might as well be the Bach of
257 C++. I do not like promises, I think throwing all your code to
258 'some indeterminate point in the future' is a horrendous choice,
259 but it's what we have to work with here, so we go with it.
260 </p>
261 <p>
262 The thing is though, in this case, this is actually a fairly
263 massive strength. Because Espruino is a JS interpreter, it will
264 run any valid JS you throw at it. This means you can actually
265 program it interactively from a serial connection, which is
266 pretty snazzy. Here's me throwing some debug code at it purely
267 from the terminal and seeing it display the results in real
268 time.
269 </p>
270 <a href="../img/projects/pipboy/pipboy2.jpg">
271 <img
272 class="blog-img-lrg"
273 src="../img/projects/pipboy/pipboy2.jpg"
274 alt="A photo of the prop pip-boy displaying the word 'TEST' on its screen."
275 />
276 </a>
277 <p>
278 It <i>also</i> means we can dump the firmware with one line from
279 the terminal and, instead of being binary and unreadable, it's
280 in regular-ass javascript. Holy shit!
281 </p>
282 <a href="../img/projects/pipboy/pipboyfirmwarescreenshot.png">
283 <img
284 class="blog-img"
285 src="../img/projects/pipboy/pipboyfirmwarescreenshot.png"
286 alt="A screenshot of some of the pip-boy firmware's built in function names."
287 />
288 </a>
289 <p>
290 As mentioned, the guy in the link above has already done this to
291 some extent, but I want to dig through a bit further and
292 understand a bit more what's going on. There's some very
293 interesting functions here that I wanna figure out.
294 </p>
295 <p>
296 For legal reasons, I can't share this firmware wholesale in the
297 repo, so you won't be able to see precisely what I'm talking
298 about. As we go, however, I'll screenshot various parts of the
299 code so you, reader, have context. Like the above!
300 </p>
301 <p>
302 Anyway, I think that's where I'm leaving it for tonight. It's
303 11pm, after all. More tomorrow.
304 </p>
305 <div class="title-block">
306 <h3 class="blog-title">Let's get some images displayed</h3>
307 <h3 class="datestamp">20/03/2025</h3>
308 </div>
309 <p>
310 OK, it's 6pm, there's 3 hours until the Apprentice is on, let's
311 get hacking. The first thing I need to do is, uh... take the
312 thing apart.
313 </p>
314 <a href="../img/projects/pipboy/pipboyopen.jpg">
315 <img
316 class="blog-img-lrg"
317 src="../img/projects/pipboy/pipboyopen.jpg"
318 alt="A photo of the pipboy's arse with a ribbon cable hanging out of it."
319 />
320 </a>
321 <p>
322 That's an micro-sd extender cable stringing out of it, there.
323 Nearly everything that makes up the pip-boy is stored on an sd
324 card which is, conveniently, not bolted into the board.
325 </p>
326 <p>
327 You can open up the thing and take it out, you can copy all of
328 its files over to a folder and, most usefully for us, you can
329 copy those same files over to another, bigger sd card (the one
330 installed is only 250MB) and it works, as long as the card is
331 fat32 formatted.
332 </p>
333 <p>
334 I've put a 32GB one in there, which is overkill, but I had it
335 lying around. It also means I can put the entirety of the
336 FO3/4/NV soundtracks on there, if I want. Which, maybe, I do in
337 future! Who knows.
338 </p>
339 <p>
340 More importantly, however, that SD card has a USER/ folder where
341 we can drop our own custom javascript files and it'll display
342 them in a nice 'APPS' menu in the INV menu.
343 </p>
344 <p>
345 We're gonna start with the the helloWorld and graphicsTest files
346 that are currently in the repo. Some file wiggling and inserting
347 and removal of SD cards and bang, there they are!
348 </p>
349 <a href="../img/projects/pipboy/pipboyapps.jpg">
350 <img
351 class="blog-img-lrg"
352 src="../img/projects/pipboy/pipboyapps.jpg"
353 alt="A photo of the pipboy's arse with a ribbon cable hanging out of it."
354 />
355 </a>
356 <p>
357 So we want tio draw something to screen that isn't just text,
358 next. So I need to dive into some docs. More updates in a bit...
359 </p>
360 <b>Code Updated. Check the github link to keep up.</b>
361 <p>
362 OK, first thing I want to do is draw a square. Which means we
363 need to understand how the graphics buffer is working. See,
364 right here, in the dump of the buffer of the main portion of the
365 screen, is some interesting evidence.
366 </p>
367 <a href="../img/projects/pipboy/firmwarebCbuffer.png">
368 <img
369 class="blog-img"
370 src="../img/projects/pipboy/firmwarebCbuffer.png"
371 alt="A screenshot of an the graphics context in the pip boy firmware."
372 />
373 </a>
374 <p>
375 The interesting thing here is 'UInt8.' This is an array of 8bit
376 integers. This could mean the pixels are rendered as 3-byte RGB
377 values, with the r and b just ignored, or it could mean each bit
378 in the byte is a pixel, and the different tones is achieved
379 using dithering. Right now, I'm not sure!
380 </p>
381 <p>So, to find out, we're gonna draw three squares.</p>
382 <a href="../img/projects/pipboy/squares.jpg">
383 <img
384 class="blog-img-lrg"
385 src="../img/projects/pipboy/squares.jpg"
386 alt="A photo of the pipboy screen showing 3 16x16 squares. One is slightly dimmer than the other two."
387 />
388 </a>
389 <p>
390 And there we have it! Three squares. Now if we look at the code
391 I've written, and note that the middle square is the dimmest of
392 the three, we can deduce...
393 </p>
394 <a href="../img/projects/pipboy/squarecode.png">
395 <img
396 class="blog-img"
397 src="../img/projects/pipboy/squarecode.png"
398 alt="A screenshot of the code to make the three squares. The three are commented 'full byte pp', 'dithered square', and 'fullbright square'"
399 />
400 </a>
401 <p>
402 That I was completely wrong and the screen is compeltely
403 monochrome, and any dimming is done by dithering. I'm so glad
404 I'm liveblogging this so everyone can see how stupid I am.
405 </p>
406 <p>
407 That's ok though! We're here to learn, and this actually makes
408 things relatively nice and easy. I'm sure there are monochrome
409 image -> uint arrays somewhere out there one the web already,
410 thisn is a very common format on embedded platforms, so I just
411 need to find one and run the icons for various perks etc through
412 them, and we can get one displaying.
413 </p>
414 <p>In fact, maybe that's what we do next. BRB...</p>
415 <b>Code Updated. Check the github link to keep up.</b>
416 <p>
417 Excellent, here's one, first hit on google.
418 <a href="https://javl.github.io/image2cpp/">image2cpp</a>
419 Let's run the Cherchez La Femme image through it and upload it
420 to the machine aaaand...
421 </p>
422 <a href="../img/projects/pipboy/errorlowmem.png">
423 <img
424 class="blog-img"
425 src="../img/projects/pipboy/errorlowmem.png"
426 alt="A screenshot of the espruino terminal reading 'New interpreter error: LOW_MEMORY,MEMORY'"
427 />
428 </a>
429 <p>
430 So, that's not good. In fairness, I am loading a 167x167 bitmap
431 into memory here, I suppose it makes sense that that wouldn't
432 exactly work. But it is going to make this more difficult.
433 </p>
434 <p>
435 Next question then. What is a reasonable maximum array size we
436 can use here? Time to experiment. We'll start with half the
437 resolution, 83x83.
438 </p>
439 <a href="../img/projects/pipboy/chercheztake1.jpg">
440 <img
441 class="blog-img-lrg"
442 src="../img/projects/pipboy/chercheztake1.jpg"
443 alt="A photo of the pipboy screen showing garbage in a square."
444 />
445 </a>
446 <p>
447 OK, it's displaying, but that's clearly not right. Here's what
448 it's supposed to look like:
449 </p>
450 <a href="../img/projects/pipboy/CherchezLaFemme.png">
451 <img
452 class="blog-img"
453 src="../img/projects/pipboy/CherchezLaFemme.png"
454 alt="The Cherchez La Femme perk icon from New Vegas"
455 />
456 </a>
457 <p>
458 That's ok though, there's options on the converter for just this
459 predicament. This was the default (Horizontal - 1bpp), and
460 Vertical - 1bpp landed similar results, so let's move on from
461 that converter and use the one hosted on
462 <a href="https://www.espruino.com/Image+Converter"
463 >Espruino's website</a
464 >
465 instead. Man I'm really proving myself soooo smart today.
466 </p>
467 <p>
468 Using the right tool for the job gives us this! And it's even
469 full resolution! Huzzah!
470 </p>
471 <a href="../img/projects/pipboy/cherchezsuccess.jpg">
472 <img
473 class="blog-img-lrg"
474 src="../img/projects/pipboy/cherchezsuccess.jpg"
475 alt="A photo of the pipboy screen showing the Cherchez La Femme icon."
476 />
477 </a>
478 <p>
479 OK, that's real, genuine progress. We can encode images and
480 display them, which we need for the perks screen. They are
481 pretty big though, so I think next order of business is going to
482 be keeping those strings in text files and loading them in when
483 we need to. Back to the docs... Although I might leave it there
484 tonight, my back hurts. No wonder Zuck had to be 19 to do this
485 live.
486 </p>
487 </div>
488 </div>
489 </div>
490 </div>
491 <iframe class="embed-links" src="../shared/links.html"> </iframe>
492 <iframe class="embed-footer" src="../shared/footer.html"> </iframe>
493 </div>
494 </body>
495 </html>