tykkiman's N64 homebrew site

Recent developments in N64 homebrew tech

There are so many interesting projects and experiments going on in N64brew’s Discord that most people have never heard of. Until today! In this blog post I will expose the most exciting new developments on the Nintendo 64 homebrew development front.

Let’s start with some games.

N64brew Game Jam 2022

This years Game Jam concluded with eight entries total. Being a graphics programmer by trade, I was of course very interested in graphics of these games :) And I wasn’t disappointed, for example check out Spirit Harvest:

And the sounds – so atmospheric. You can view rest of the YouTube playlist of this years entries to see what the games were like. Pre-built ROMs and source code are also available.

Thanks to the organizers and participants for making this happen!

Portal 64

James Lambert has been hard at work on an inspiring Portal demake for the N64. Enjoy this hilarious N64 ON trailer below.

He shares his progress also on GitHub in addition to his explainer videos. They are a great way to learn computer graphics in general :)

Lightmapping with a simulated second UV map

On Discord, user Arthur has been demonstrating a beautiful baked lightmap technique.

A lightmapping demo by Arthur that shows a beautiful manor corridor with sun shining throuh window panes on the left.

It’s not vertex lighting, it’s a second texture. What makes this tricky is that each triangle can have only one set of per-vertex texture coordinates. Here a second texture coordinate channel is simulated with some trickery using the RDP’s “tiling” feature, if I understood correctly.

I’m sure I’m not alone saying I can’t wait to see where this will be going in the future.

Real time bump mapping technique

Also, user Илюха has been sharing sneak peeks and test ROMs for really impressive looking shading tech:

Bump Mapping!

bumps bumps

It’s based on clever RDP color combiner programming and runs in a single pass. I have to admit I didn’t fully grasp how exactly the math works out but will definitely read up on it.

Interestingly, a similar technique was demonstrated by WadeMalone already in 2020 but it wasn’t a good fit for complex geometry. Here’s a still of their 2020 video:

WadeMalone’s bump map demo from 2020.

It’s lovely to see people “maxing out” the console by taking advantage of pretty much every RDP feature simultaneously :) Now we can move to some programming environment and library news.

Ares emulator accuracy improvements

My understanding is that the ares multi-system emulator is the most accurate N64 emu you can get right now. It doesn’t have high-level emulation hacks for commercial games but has become indispensable for homebrew development due to its reliability.

Recently Rasky has been improving its floating point emulation and added some video related fixes as well. Its already so good you could declare the following maxim:

If it runs on your ares it will run your Nintendo!

New libdragon features

The 100% open source libdragon toolchain is finally emerging as a strong competitor to the leaked official libultra SDK and its modern revamp by CrashOveride.

I know the rest of this chapter sounds a bit like an advertisement but I can’t help myself. It’s just fun to see hobbyists doing such excellent work on their free time.

OpenGL support

For the longest time libdragon was 2D-only. Now it is changing thanks to Rasky, snacchus, and anacierdem who have been writing an OpenGL 1.1 implementation from scratch!

gldemo

The gldemo example running in ares.

See gldemo.c example code with your own eyes to verify that, yes, it’s standard OpenGL with none of the leaked libultra weirdness homebrew developers have been forced to deal with before.

It’s still early days for the OpenGL implementation but you can test it in opengl branch of the libdragon repository. It’s not fully RSP accelerated yet but triangle setup, the tricky part, is already running on the RSP.

rspq task queue

Programming the N64’s “Reality Signal Processor” (RSP) has been seen as a dark art impenetrable to mere mortal homebrew devs. Its programs have been called “microcode” or “ucode” you might have heard before, even though they are just 32-bit MIPS R4000 machine code with some instructions added and others removed.

Anyway, rspq, the RSP task queue, allows programmers to run multiple RSP programs concurrently using co-operative multitasking. Yes, the programs, called “overlays”, still need to be written in assembly language but now it’s much easier to schedule, synchronize and interleave their execution. Each overlay can handle multiple commands that are supposed to execute real quick. A scheduler can switch overlay programs between commands so to the programmer it seems that they all execute concurrently.

This new abstraction is used both by the OpenGL implementation and the XM module player mentioned below.

rdpq

In addition to rspq there’s also a new abstraction for the RDP chip: rdpq. Instead of trying to explain it, I’ll just directly quote rdpq.h:

Architecture and rationale

Normally, RDP commands are generated by both the CPU and the RSP. The normal split is that CPU is in charge of render mode changes (eg: loading textures, defining the alpha blending behavior, etc.), while the RSP executes a full T&L pipeline which terminates with the generation of RDP triangle primitives.

This library allows the CPU to enqueue RDP commands. It covers the full RDP command set, including triangles. Even if for RDP commands generated by CPU, the RSP is involved: in fact, this library is a rspq overlay (see rspq.h). All RDP commands are enqueued in the main RSP command queue, and they are sent to the RDP by the RSP.

There are two main reasons for this design (rather than letting the CPU directly send the commands to the RDP):

  • Given that CPU and RSP usually work in parallel (with as few as possible syncing points), it is necessary to make sure that the CPU is able to schedule RDP commands that will be executed in the right order with respect to commands generated by RSP. This is easy to do if CPU-generated RDP commands always go through RSP in main command queue.

  • Most of the commands are sent unchanged to the RDP (we call them “passthrough”). Some commands, instead, are manipulated by the RSP and changed before they hit the RDP (we call these “fixups”). This is done to achieve a saner semantic for the programmer, hiding a few dark corners of the RDP hardware.

RDP validator

The RDP is difficult to program because it has so many possible command and parameter combinations but only a small minority of them make sense and actually work. There are also some clear design oversights, such as inconsistent handling of rectangle bounds as inclusive or exclusive depending on command.

Thanks to Rasky’s new validator in libdragon, many kind of bugs now throw an error to the programmer so that the issue can be fixed directly. Validator can also be ran offline as a separate tool.

This is a big deal and something the 90s game developers, our heroes, could only dream of.

XM module playback with RSP mixing

XM player screenshot

The classic FastTracker 2 module format is apparently a surprisingly good fit for the N64. Libdragon includes support for them with only a small CPU impact because the tracks are mixed on the RSP. It uses some libxm library to read the files and exposes an easy to use API to the programmer.

Where to start

If this got you interested I invite you to visit the N64brew wiki and Discord server. You can also eyeball How to make a N64 game with LibDragon (2022) to get an idea how things work.