Nintendo 64 programming characteristics
# Nintendo 64 programming characteristics

The Nintendo 64's programming characteristics describe the elements of writing software for the Nintendo 64 (N64) gaming system.

## History

The Nintendo 64 was released in 1996. At the time, The Economist described the system as "horrendously complex". The difficulties were said to be a combination of oversight on the part of the hardware designers, limitations on 3D graphics, technology limits of that time, and manufacturing issues.

As the Nintendo 64 reached the end of its lifecycle, hardware development chief Genyo Takeda referred to its programming challenges using the word hansei (Japanese: 反省 "reflective regret"). Takeda said, "When we made Nintendo 64, we thought it was logical that if you want to make advanced games, it becomes technically more difficult. We were wrong. We now understand it's the cruising speed that matters, not the momentary flash of peak power."

## Memory

The console uses high-bandwidth but high-latency Rambus DRAM. It is hosted from the Reality Coprocessor (RCP) having an internal interconnect across the Reality Signal Processor, Reality Display Processor, and the IO (including microprocessor) interfaces.

There is a physical address space into which the majority of resources are mapped, including the Game Pak, the RSP instruction and data local storage, but neither the RDP texture local storage nor any CPU cache. The RSP, RDP, and IO interfaces each have their own DMA engine, programmable by registers that are exposed through the physical address space. The RSP can address only its local storage, and can program its DMA engine. The RDP DMA engine handles command buffers (so-called display lists); the RDP has a further memory front end for accessing video buffers and data, able to directly fetch from the RSP data local storage through a separate data path.

The R4300 CPU is connected to the RCP through the microprocessor interface, and can perform programmed IO through its cache and memory frontend.

## Reality Display Processor

The Reality Display Processor is a fixed-pipeline rasterizer and shader, with Z-buffering, outputting a framebuffer for the video interface to scan out to the display.

### Texture cache

The texture cache was 4 KB in size. Its small size led developers to stretch small textures over a comparatively larger space. The console's bilinear filtering only blurs them. When mipmapping is used, texture width requirements and the extra storage for the mipmap levels limit the largest mipmap level to 2 KB. Toward the end of the Nintendo 64's market cycle, some developers precomputed their textures using multi-layered texturing and small texture pieces that were heavily clamped, to simulate larger textures. Examples of this workaround are found in Rare's Perfect Dark, Banjo-Tooie, Conker's Bad Fur Day, and in Factor 5's Indiana Jones and the Infernal Machine. Some games with non-realistic aesthetics use plain colored Gouraud shading instead of texturing on certain surfaces (e.g., Super Mario 64).

   The big strength was the N64 cartridge. We use the cartridge almost like normal RAM and are streaming all level data, textures, animations, music, sound and even program code while the game is running. With the final size of the levels and the amount of textures, the RAM of the N64 never would have been even remotely enough to fit any individual level. So the cartridge technology really saved the day.

### Fill rate

Many Nintendo 64 games are fill-rate limited, not geometry limited. For example, Z-buffering when enabled is a significant share of memory access, otherwise needed for textures and the frame-buffer. Optimization is possible by pushing this function onto the RSP and CPU using a custom microcode. Significant performance Optimization can be found by using a microcode appropriate for each game. The Nintendo 64's polygon per second rating is about 160,000 with hardware features enabled. Some of the more polygon-intense Nintendo 64 games include World Driver Championship, Turok 2: Seeds of Evil, and Indiana Jones and the Infernal Machine.

## Reality Signal Processor

The Reality Signal Processor (RSP) accepts microcode, through which, a developer can access different operations, create new effects, and optimize for speed or quality. The RSP is a RISC processor, less capable than the CPU, but with an 8-way 16-bit vector engine. The efficacious use of this engine is governed by the microcode, which defines a small instruction sequence for each complex instruction. While promoting the feature of custom microcodes, Nintendo initially refused to share information on how to use the related microcode tools. This was due to the fear that it would be copied by their competitors. However during the console's last few years, Nintendo shared the microcode information with a few developers. Nintendo's official code tools are basic, with no debugger and poor documentation.

SGI's default microcode for Nintendo 64 is called "Fast3D", which some developers claimed was poorly profiled for use in games. Although it generates more than 100,000 high accuracy polygons per second, this microcode is optimized more for accuracy than for speed, and performance suffered. Nintendo's "Turbo3D" microcode allows 500,000–600,000 normal accuracy polygons per second. However, due to the graphical degradation, Nintendo officially discouraged its use. Companies such as Factor 5, Boss Game Studios, and Rare were able to write custom microcode that reportedly runs their game engines better than SGI's standard microcode.

One of the best examples of custom microcode is Factor 5's N64 port of the Indiana Jones and the Infernal Machine PC game. The Factor 5 team aimed for the high resolution mode of 640×480 because of its visual crispness. The machine was said to be operating at its limits while running at 640×480. The Z-buffer could not be used because it alone consumed the already constrained texture fill rate. To work around the 4 KB texture cache, programmers came up with custom texture formats and tools. Each texture was analyzed and fitted to best texture format for performance and quality. They took advantage of the cartridge as a texture streaming source to squeeze as much detail as possible into each environment and work around RAM limitations. They wrote microcode for real-time lighting, because the supplied microcode from SGI was not optimized for this task, and because they wanted to have more lighting than the PC version. Factor 5's microcode allows almost unlimited realtime lighting and significantly boosts the polygon count. In the end, the N64 version is said to be more feature-rich than the PC version, and is considered to be one of the unit's most advanced games.

Factor 5 again used custom microcode with games such as Star Wars: Rogue Squadron and Star Wars: Episode I: Battle for Naboo. In Star Wars: Rogue Squadron, the team tweaked the microcode for a landscape engine to create the alien worlds. For Star Wars: Battle for Naboo, they used what they learned from Rogue Squadron and made the game run at 640×480, also implementing enhancements for particles and the landscape engine. Battle for Naboo has a long draw distance and large amounts of snow and rain, even in high resolution mode.

In reality, N64 games with high resolution (480i) modes rarely ran at 640x480, in Factor 5 games case, the high resolution was instead set to 400x440, Turok 2, Turok 3 and Turok Rage Wars used 480x360 while Perfect Dark used 640x222 in NTSC, 448x268 in PAL.

