Skip to main content
Spacebruce dot netlify dot app

Using Oscar64 for NES game development

Oscar64 is a C/C++ compiler for 6502-based systems. Designed for the Commodore 64 and it's variants, it is compatible with other 6502 computers and consoles such as the Nintendo NES/Famicom. Encouraged by how performant the resulting programs appear to be for C64 applications, I'm interested in using this myself sometime in the future 👀.

I didn't find any documentation specifically covering using it with the NES, so I did some light digging and made these notes, I hope they're useful to others!

The commands here should work on Linux or Windows as long as Oscar64 is installed correctly.

# Basic setup

Create a project file called game.c and copy this in, remove comments for taste;

#include <oscar.h>      // Compiler/Runtime details
#include <nes/nes.h>    // NES constants
#include <nes/neslib.h> // NES functions
#include "stdint.h"     // Useful types

void nes_game() // This is the user program entry point, called from the real "int main" which lives inside inside neslib.h
{
    ppu_on_all();   // Init the PPU 
    uint16_t i = 0;
    while(1)
    {
        pal_col(0, (i >> 4) % 54); // Cycle the BG to prove the system is running
        ++i;
        ppu_wait_frame();   // Wait for next frame
    }
}

Run the compiler like so, and you should receive a game.nes output file, which you can test in an emulator or on a real console;

oscar64 -tm=nes game.c

testrun.png

You may wish to write that command to a file later for ease of use, on windows write it down in a .bat file and on linux a .sh (with permissions set to +x).

$ echo oscar64 -tm=nes game.c > build.sh
$ chmod +x build.sh 
$ ./build.sh 

# Extending the project

Oscar64 diverges from typical C convention and permits you to specify inline which files get compiled, using the compile pragma, like so;

#pragma compile("foo.c")

Putting this into practice, the current project structure can be exploded into multiple files like this;
utils.h

#pragma once
void doBG();
#pragma compile("utils.c")

utils.c

#include "utils.h"
#include "stdint.h"

void doBG()
{
    uint16_t i = 0;
    while(1)
    {
        pal_col(0, (i >> 4) % 54);
        ++i;
        ppu_wait_frame();
    }
}

game.c

#include <oscar.h>
#include <nes/nes.h>
#include <nes/neslib.h>
#include "utils.h"

void nes_game()
{
    ppu_on_all(); 
    doBG();
}

# Download

The ROM file for this segment can be downloaded from ... here

# Graphics

Soon...