···11+/*
22+ This is a little hacky, but it works.
33+44+ ContentSurround expects you use an icon, but we're not and we're using
55+ an image instead.
66+ */
77+.link-da-flute-boi-img {
88+ background: url('/images/link-da-flute-boi.png') no-repeat;
99+ background-color: initial;
1010+ background-size: contain;
1111+ width: 100px;
1212+ height: 156px;
1313+ mask-image: none;
1414+ -webkit-mask-image: none;
1515+1616+ &:where(.i-lucide\:arrow-left) {
1717+ transform: scaleX(-1);
1818+ }
1919+}
···1818### MG-Zero and gm112 combine their half-braincells together to form one braincell
19192020During a conversation with Steve, we had talked about Ocarina of Time 2D and how
2121-nice it would have been to do a panel on it. That discussion evolved into a
2222-project that went down a rabbit hole of learning how to make a game on the
2323-Game Boy. The idea was to make an Ocarina of Time 2D demo that would
2424-play into the hopelessness of Demo 4 (I will write an article about this later).
2121+nice it would have been to do a panel on it. To give a spotlight to the community
2222+of where OoT2D was born. That discussion evolved into a project that went down
2323+a rabbit hole of learning how to make a game on the Game Boy. The idea was to
2424+make an Ocarina of Time 2D demo that would play into the hopelessness
2525+of Demo 4 (I will write an article about this later).
2626+2727+Thankfully, I had already had been helping another friend of mine, Aaron,
2828+with theirown Game Boy project, Dearborn, which has a similar playstyle to
2929+2D Zeldas.
25302626-Thankfully, I had already had been helping another friend of mine with their
2727-own Game Boy project, Dearborn, which has a similar playstyle to 2D Zeldas.
2831Aaron had been working on Dearborn, and then reached out to me to help with
2932developing the game. Since we were in pre-production, we experimented with
3033a couple of different ideas. One was a turned based combat system demo, which
···59626063### Figuring out the audio situation
61646262-For streaming the audio, originally I had written a simple bash script that
6363-converted the WAV files into a C array. And then, I wrote a function that
6464-DMA'd the array into the APU's Channel 3 effectively. The first atttempts
6565-at this did not work, due to timing issues, logic that was too dumb, and
6666-honestly I had no idea what I was doing. Ultimately, I decided to try
6767-using GBVM's sound fx functions, seeing that it had a 3 second limitation.
6868-It seemed if you timed it right, you could queue up multiple samples of
6969-sounds and chain together a complete song! At this point, there was
7070-no optimization, so the CPU was spent entirely on sending these commands.
7171-Luckily, most of that time was spent idling, so it was simple enough to
7272-move the commands into a GBVM script that ran on a separate "thread" that
7373-instead no-ops. At this point, it was possible for the player to interact
7474-with the game while they were being rick rolled. \:D
6565+[GB Studio](https://www.gbstudio.dev/docs/assets/sound-effects/) noted
6666+that audio had to be formatted a certain way. Using [yt-dlp](https://github.com/yt-dlp/yt-dlp){target="\_blank"}
6767+and [ffmpeg](https://www.ffmpeg.org/){target="\_blank"} from the
6868+AUR and started with a script to generate the WAV files.
75697676-TOOD: Rework this section, and talk about setting up the audio.
7070+::code-collapse
77717878-<details class="bg-info p-4">
7979- <summary>Click to see code! \:D</summary>
7272+::code-group{name="Click to see code! :D"}
7373+7474+```bash [convert.sh]
7575+#!/usr/bin/env bash
7676+set -e
80778181-```asm
7878+INPUT="$1"
7979+OUTDIR="$2"
8080+8181+if [[ -z "$INPUT" || -z "$OUTDIR" ]]; then
8282+ echo "Usage: $0 input.webm output_dir"
8383+ exit 1
8484+fi
8585+8686+mkdir -p "$OUTDIR"
8787+8888+ffmpeg -i "$INPUT" \
8989+ -filter_complex "\
9090+[0:a]\
9191+dcshift=0,\
9292+pan=mono|c0=0.5*c0+0.5*c1,\
9393+highpass=60,\
9494+lowpass=3300,\
9595+equalizer=f=400:t=q:w=1:g=-1.5,\
9696+equalizer=f=1200:t=q:w=1:g=1.2,\
9797+equalizer=f=1800:t=q:w=1:g=1.8,\
9898+equalizer=f=2500:t=q:w=1:g=-3.2,\
9999+volume=3.0\
100100+[aud]; \
101101+anoisesrc=color=white:amplitude=0.0007 \
102102+[noise]; \
103103+[aud][noise]amix=inputs=2:weights=1 0.15:duration=shortest,\
104104+alimiter=limit=0.86\
105105+[out]" \
106106+ -map "[out]" \
107107+ -ac 1 \
108108+ -ar 8000 \
109109+ -c:a pcm_u8 \
110110+ -f segment \
111111+ -segment_time 3 \
112112+ -reset_timestamps 1 \
113113+ "$OUTDIR/never-gonna-give-you-up-%03d.wav"
114114+```
115115+116116+```bash [output.log]
117117+ls -1 | wc -l
118118+119119+# 72
120120+```
121121+122122+::
123123+124124+::
125125+126126+With around 72 output files, I removed 3 of them and replaced the last
127127+one with a silence file. The next step was to see if we could playback the wave
128128+files. My first attempt involved queuing up two GBVM `VM_SFX_PLAY` commands,
129129+which didn't work on its own. Then I tried using a C-style array, and manually
130130+using a DMA transfer to the APU's Channel 3. This worked, but my implementation
131131+stole the CPU.
132132+133133+Going back to the drawing board, I felt the `VM_SFX_PLAY` approach could work.
134134+Being the simpleton I am, I remembered that for the demo, I implemented a
135135+function that played back a sound effect on the noise channel on a separate
136136+script thread for a sword swing sound.
137137+138138+If that worked, then surely I could do the same thing, except with many WAV files!
139139+140140+::code-collapse
141141+142142+```asm [rick-roll.asm]
82143.macro PLAY_WAIT bank, snd, mask
83144 VM_SFX_PLAY bank, snd, mask, .SFX_PRIORITY_NORMAL
84145 VM_SET_CONST 0, 174
···95156VM_RET_FAR
96157```
971589898-</details>
159159+::
99160100161This bone headed bit of code was stuffed into a GBVM Script in the project file,
101162and thankfully it was good enough to handle playback. Shoutouts to the GBVM and
102163GB Studio developers for making this possible! Psst. See if you can find the
103164hidden easter egg in the ROM or code!
165165+166166+At this point I began testing in other emulators.
167167+168168+### Emulator Accuracy
169169+170170+This has to be called out, but upon realizing that I might have a problem with
171171+audio playback on hardware, I resorted to testing the ROM on multiple emulators.
172172+Up until this point, I had used [SkyEmu](https://skyemu.app/){target="\_blank"}
173173+for testing. But, it seems every other emulator I tried, had issues with audio
174174+playback. Audio pops, no playback, etc, it felt like maybe I was walking into a
175175+brick wall once I tried this on a real Game Boy. Many hours and nights were
176176+spent trying to figure out what was going on.
177177+178178+At this point my shipment of flashcarts had arrived, and I was able to test the
179179+ROM on real hardware, and all seemed well! At this point, I wrote off the audio
180180+issues in other emulators as something that's just out of scope to deal with,
181181+especially given the simple approach to playing back Rick Astley's "Never Gonna
182182+Give You Up". ;p
104183105184### Departing
106185···158237things, and also the people who were rooming with us at the hotel! Everyone was
159238chill.
160239161161-TODO: Finish this section.
240240+We made it to the hotel room, and I plopped on the bed and busted
241241+out the goods. >: )
162242163243### Flashing Game Boy Carts
244244+245245+Because of missing some of the object data, I decided
246246+to scrap Kikori Forest, the Great Deku Tree, and just make a simple
247247+single room for the rick roll. After fiddling with the scene script,
248248+a ROM flashing extravaganza happened! haha
164249165250{
166251fit="cover"
···172257loading="lazy"
173258}
174259175175-We made it to the hotel room, and I plopped on the bed and busted
176176-out the goods. >: ) Because of missing some of the object data, I decided
177177-to scrap Kikori Forest, the Great Deku Tree, and just make a simple
178178-single room for the rick roll.
179179-180180-TODO: Finish this section
181181-182260## Unleashing Rick Astley onto MAGFest
183183-184184-## The Rick Roll
185261186262To describe the rick roll, essentially just imagine a legitimate
187263startup sequence that hits you with an 8-bit rendering of the raw