N64:N64blur

agizmo

Many Nintendo 64 games use software to add a blurring effect, presumably to smooth out the jagged, low-resolution 3D graphics. This seemed to do a great job back in 1996 when almost everyone played on a CRT with composite video. This blurring effect sometimes doesn't scale well to modern TVs, and people figured out ways to turn it off on most games if desired.

This page is a culmination of work done by many different people in the retro gaming community; The picture below is a result of their work and the improvements that can be made in these games (click the picture for a full-sized view). Also, see the video from My Life In Gaming that does an excellent job explaining everything!



https://www.youtube.com/embed/QDiHgKil8AQ

Introduction:
As explained in the My Life in Gaming video above, there are two different smoothing processing occurring to the video output of the Nintendo 64. First, anti-aliasing, dither filtering, and other adjustments are applied to the image by the RCP (Reality Co-Processor) based on the value set in the VI_CONTROL_REG register. . Finally, the Nintendo 64 interpolates the image's horizontal axis from 320 to 640. This effectively applies a smoothing filter to the image.

Remove Horizontal Blur
At this time, there is no known way to disable the Nintendo 64 horizontal image interpolation through software or hardware mods. Products like Retroactive's UltraHDMI, Pixel FX's N64Digital, and Tim Worthington's N64RGB have "deblur" features that adjust their horizontal sampling to compensate for the interpolation. The OSSC can be configured with optimal timings to generate similar results.

Remove Reality Co-Processor Effects
Removing effects applied by the RCP, such as anti-aliasing and dither filtering, is more complicated. People knew games like Quake 64 had options in the video menu to disable anti-aliasing, but it wasn't until 2016 when users at the ASSEMblergames.org forums figured out how the setting was applied and how to control it. The technical details are beyond the scope of this guide. The important thing to know is the Nintendo 64 has a register called VI_STATUS_REG/VI_CONTROL_REG (address 0x04400000). This register controls dither filtering, anti-aliasing, gamma boost, gamma filtering, and color depth. What's more, the value of the register is set by the developers in the game's code, and that information can be manipulated using ROM patches or GameShark codes. Below is an example diagram explaining what each bit of the register does based on its value set in Mario Kart 64.



Using the diagram as an example, here is an explanation of each bit from the right to left:
 * Bit 0-1 = 16-bit color
 * Bit 2 = Enable gamma dither. (has no effect because gamma is disabled)
 * Bit 3 = Disable gamma boost.
 * Bit 4 = Enable DIVOT.
 * Bit 5 = Disable VBUS clock. (always disabled)
 * Bit 6 = Disable serrate.
 * Bit 7 = Disable test mode.
 * Bit 8-9 = Enable anti-aliasing and always resample.
 * Bit 10= Undefined.
 * Bit 11= Disable kill_we.
 * Bit 12-15 = Always 0011 for optimal operation.
 * Bits 16 = Enable dither filter.
 * Bit 17-31: Undefined.

How to Find the Current Register Value
The question is how to find the VI_STATUS_REG/VI_CONTROL_REG register's current value and set it. All of the information below was sourced from information provided by xdaniel on the ASSEMblergames.org forum archive.

Option 1: Emulators
The easiest way to find the register's value is to use an emulator. The example below uses Nemu64 v0.8. The next step is to find the location in memory that sets the value of the register. These addresses are unique to every game and every game revision. The memory addresses will be used later in this guide.
 * 1) Launch Nemu64 and start the desired game.
 * 2) Go into the "Plugins" menu and select "Debugger: Memory..." to open the Memory window.
 * 3) Click on the "Predefined" button and choose VI_STATUS. That should move the memory viewer to address A4400000.
 * 4) Take note of the 4-byte/32-bit value there. In Mario Kart 64's case, it's 00013016.
 * 1) Click the "Search..." button, and put the VI_STATUS value into the "Search value" textbox. Make sure "Hex" is checked and "32 bits (aligned)" selected to the right of it. Click "Search".
 * 2) You should find the register's value in two possible memory locations, both exactly 0x30 hexadecimal (48 decimal) bytes apart. Make a note of both addresses. For MK64, the two results are 000EB3DC and 000EB40C.

Option 2: GameShark and PC
Another way to find the register value is more involved, as it requires some hardware. You need a Nintendo 64, a GameShark Pro with a functioning parallel port on the back, a PC with a parallel port (USB adapters for connecting printers may not work), the game you want to find codes for, and (if the game requires a GS keycode to boot) another game like Super Mario 64, Mario Kart 64 and most others to boot the system, to select the correct key code, then turn the system off again, swap in the cart that needs the keycode, and then turning everything back on. This whole procedure can be pretty unstable regardless of the setup. The best PC may be one using a Windows 98 and the "Game Software Code Creator" tool, GSCC for short. See the Kodewerx EnHacklopedia for more details about the PC connection. The next step is to find the location in memory that sets the value of the register. These addresses are unique to every game and every game revision. The memory addresses will be used later in this guide.
 * 1) With the N64 booted up and on the GameShark's main menu screen, have the GSCC software on the PC detect the proper settings for communication in its configuration screen
 * 2) Start the game on the N64 with the Code Generator turned ON.
 * 3) Once somewhere in-game, go to GSCC's RAM editor via the menu "Ram Edit", then "Open Window".
 * 4) Once there, click the "Goto Address" button, then enter "0xA4400000" as the address and click "Goto".
 * 5) The main editor window will now show the memory starting at address A4400000.
 * 6) Take note of the 4-byte/32-bit value there. In Mario Kart 64's case, it's 00013016.
 * 1) Press the "Find Memory" button next to Goto Address, put the register's value into the "Find What" textbox, make sure "Hex" is selected for "Value", and press "Find Now". The search will freeze the game until the value has been found in memory, so don't be alarmed. Once the value has been found, the game resumes, and the RAM editor jumps to the value's location.
 * 2) You should find the register's value in two possible memory locations, both exactly 0x30 hexadecimal (48 decimal) bytes apart. Make a note of both addresses. For MK64, the two results are 000EB3DC and 000EB40C.

Option 1: GameShark Codes
Now that we know what each bit in the VI_STATUS_REG/VI_CONTROL_REG register does, what a game set's it two, and where the register gets its value from the game code running in memory, it is possible to manipulate the register's value to get the desired result. For example, to disable anti-aliasing in Mario Kart 64, bits 8 and 9 in the register are changed from 00 to 10. Changing the bits results in a different hex value for the register. 00013016 becomes 00013216 (note: completely disabling anti-aliasing and resampling using value 11 may cause visual artifacts). The dither filter can also be disabled by modifying bit 16 from 1 to 0 (note: some games suffer from heavy dithering and may look better with the filter set to enabled). Using the two memory addresses found above and determining the desired value for the VI_STATUS_REG/VI_CONTROL_REG register, GameShark codes can be created to change the register's value. This is accomplished by turning the 32-bit register value into two 16-bit writes. 810EB3DC 0000 810EB3DE 3216 810EB40C 0000 810EB40E 3216
 * 1) Take the register's desired value and split it to create two hex numbers. 00003126 become 0000 and 3216.
 * 2) 16-bit write operation codes in the GameShark are written as  . For the example with Mario Kart 64, the first address found earlier (000EB3DC) becomes 810EB3DC. The code for the second half of the memory is 810EB3DD (this is offset by 16-bits).
 * 3) In total, four codes are needed to write the desired register value to memory (two memory locations found times two 16-bit write operations). To change the VI_STATUS_REG/VI_CONTROL_REG register from 00013016 to 00003216 using memory addresses 000EB3DC & 000EB40C, the following GameShark codes are used:

Option 2: Patch ROM files
santurnu created an application to modify ROM files with the desired VI_STATUS_REG/VI_CONTROL_REG register value. The attached zip file contains the last version of the autopatcher plus uCON64 to convert ROM files to z64 format (if needed) and Real N64 CRC Tool to recalculate the ROM's checksum, so game booting works. A "patch.bat" file has preconfigured commands to automate the process of patching ROM files by simply dragging and dropping them onto the batch file. Source code for santurnu's application is available at GitHub.



Example command:

Option 3: Patch Files
Poregon has created patches for most of the NTSC-U ROM set. The original website is no longer exists, but a copy is available at the Internet Archive.

Lunar IPS can be used to apply patches to ROM files. Some ROM carts contain features that can toggle patches on or off before starting a game.

Gameshark Codes
The following GameShark codes are provided by the ASSEMblergames.org forums community.