← BackJan 6, 2026

Recreating the Game Boy Color Boot Animation as an 88×31 Web Button with ImageMagick

This article walks through extracting the 175‑frame boot animation from the Game Boy Color ROM, converting it into a web‑friendly 88×31 button, and seamlessly integrating a custom grey background while preserving the original fade transition. Using the SameBoy emulator, a detailed breakpoint strategy, and a full ImageMagick command pipeline—including colour remapping—authors can reproduce a polished GIF button suitable for modern personal sites.

## Background The Game Boy Color’s boot animation is a classic example of tight, frame‑accurate sprite work. Over the past few years the retro web‑button style has resurfaced, and a 88×31 button featuring the classic "+Game Boy+" logo is a popular choice for personal sites. Rather than design the logo from scratch, the goal here is to extract the original animation from the boot ROM, scale it accurately, and wrap it in the standard grey‑border button frame that matches the ubiquitous 88×31 design. ## Extracting the Raw Frames The boot animation is embedded in the official Nintendo boot ROM, a 32 kB binary. The easiest way to capture each frame is to run the ROM in an emulator that supports break‑points on the Game Boy Color. SameBoy is a lightweight, well‑documented option. ### Identifying the VBlank Loop The animation is paced by the hardware VBlank interrupt. The disassembly of the ROM (e.g. the community‑dumped, labelled source) shows a routine called `Wait_for_next_VBLANK` (address $0211). By setting a breakpoint here and stepping through, each return to the routine corresponds to the completion of one frame. ### Capturing Screenshots SameBoy exposes an `⌘S` hot‑key that outputs the current LCD framebuffer to disk as a PNG at the native 160×144 resolution, independent of the host display. > **Scripted workflow** > 1. Reset and set a breakpoint on `sub_0291` (the routine that calls `Wait_for_next_VBLANK`). > 2. Continue execution until the breakpoint. > 3. Capture a screenshot. > 4. Repeat until the animation restarts. > This produces 175 single‑frame PNGs. ImageMagick can then be used to assemble these into a GIF: ```bash magick -delay 1.6742706299 -loop 0 *.png animation.gif ``` The delay value is derived from the hardware clock (≈0.0167 s per frame). ## Resizing & Framing the Logo The raw animation contains the full 127 × 22 pixel “Game Boy” text logo at coordinates (16, 48). To reuse it in a standard 88×31 button we need to: 1. **Crop** the logo out of the full 160×144 frames. 2. **Scale** it to fit the 88×31 area while preserving the aspect ratio. 3. **Embed** it in a grey border and pad the remainder of the frame. 4. **Replace** any white background with the chosen grey color. Each step is performed in a single ImageMagick pipeline: ```bash magick animation.gif \ -crop 127x22+16+48 +repage \ -fill #C0C0C0 -opaque #FFFFFF \ -resize 82x \ -gravity center \ -background #C0C0C0 \ -extent 88x31 \ -coalesce null:frame.png \ -layers composite \ button.gif ``` Explanation: - `-crop` isolates the logo. - The `-opaque` replace removes the white background. - `-resize 82x` respects the aspect ratio (82×14). - `-gravity center` and `-extent` pad the image within an 88×31 canvas. - `-coalesce null:frame.png` applies the classic 2‑pixel grey border. ## Handling Fade‑to‑White Artefacts (“Ghosting”) The original boot animation fades the logo from deep blue to pure white. When the background is replaced with grey (#C0C0C0), the transition produces a faint ghost‑like halo. ### Extracting Transition Colours A histogram of the final frames reveals a tidy list of 26 colours that form the blue‑to‑white gradient: ```text #006BFF 
 #FAFBFF, #FFFFFF ``` The fade can be remapped to transition from the same blue start to grey end. A Python helper converts each hex colour into an equivalent in the new range: ```python from math import lerp # Example mapping for one colour start_old = (0x00, 0x6B, 0xFF) end_old = (0xFF, 0xFF, 0xFF) start_new = (0x00, 0x6B, 0xFF) end_new = (0xC0, 0xC0, 0xC0) def remap(c): r,g,b = c t = (r - start_old[0]) / (end_old[0] - start_old[0]) return tuple(int(lerp(a,b,t)) for a,b in zip(start_new,end_new)) ``` The script outputs a sequence of `-fill/-opaque` pairs that replace each original colour with its new counterpart. ### One‑Shot ImageMagick Replacement Inserting those pairs into the earlier pipeline achieves the remapped fade in a single command: ```bash magick animation.gif \ -crop 127x22+16+48 +repage \ -fill #006BFF -opaque #006BFF \ -fill #056DFE -opaque #066CFF \ ... \ -fill #C0C0C0 -opaque #FFFFFF \ -resize 82x \ -gravity center \ -background #C0C0C0 \ -extent 88x31 \ -coalesce null:frame.png \ -layers composite \ button.gif ``` (The `...` represents the full list of 26 colour pairs.) ## Result & Integration The final `button.gif` is an 88×31 animated GIF with a classic 2‑pixel grey border, the Game Boy logo rendered in its original style, and a clean grey background that eliminates ghosting. Embedding is straightforward: ```html Game Boy Color ``` Feel free to host the GIF locally or integrate it into your preferred static site generator. ## Takeaways * **Extracting ROM assets** can be done reliably with an emulator and a small debugging workflow. * **ImageMagick’s pipeline** handles cropping, scaling, colour remapping, padding, and framing in a single command chain, showcasing its power for complex web‑graphics transformations. * **Colour remapping** is critical when adjusting legacy hardware‑specific visuals for modern color palettes: a handful of RGB conversions can eliminate visual artefacts. This process illustrates how classic retro graphics can be harvested, sanitized, and repurposed for contemporary web design, while staying true to the original artwork.