Live data from Hacker News

How to program an NES game in C

nesdoug.com

51–60 of 70 posts

Re: How to program an NES game in C

#51

IMHO a 6502 is too limited to be effectively programmed in C; even this part of the article gives all the limitations: https://nesdoug.com/2015/11/15/2-how-cc65-works/ With this important note: "clean unaltered C code will compile into very slow code that takes up too much of the limited memory space." In other words, "C" written for such a CPU will be in a vastly different style from more "normal" C, so that it migh…

> IMHO a 6502 is too limited to be effectively programmed in C; even this part of the article gives all the limitations: https://nesdoug.com/2015/11/15/2-how-cc65-works/

In my not so humble opinion, almost all of those are limitations of a compiler, not of the CPU. Then yes, on a 8-bit CPU, you'd better avoid larger words unless you really have to or it will be slow.

Re: How to program an NES game in C

#52
post #50

Earlier quoted context omitted.

C programmers used to handle banks of EMS RAM, on the PC. Ditto with program overlays. I'd assume that NES ROM banks could be handled similarly.

Actually it was mostly Assembly code being called from C and Pascal, or via language extensions like virtual registers.

I've been reading the code for Ultima Underworld for a while. A lot of that is written in C, compiled in an early Borland C++ compiler. The C lib covers a few things; it's got some functions for manipulating EMS, and supports some fancy automatic overlay handling. So certainly the functions in the C library are written in assembly, wrapping calls to int67 and such.

And admittedly, it can be hard to see where the hand-coded assembly ends and the compiled C code begins. There are occasional stylistic clues, but I'm generally spending more time figuring out what something does and why it's written than I am which language each piece was coded in. Most of the file and memory handling seems to be done through calls to the C library in that game.

Re: How to program an NES game in C

#53
post #29

How did they actually make NES games? By that I mean, what types of computers were they using for creating NES games? Other 6502-based computers? Could they run the NES games on there? Or did they have to burn to a cart to test things every time? How did they design graphics? Was it basically graph paper, which then they translated into sprites by hand?

> By that I mean, what types of computers were they using for creating NES games? Other 6502-based computers?

At the place I worked in the early '80s [1], which did some games for Mattel for a couple 6502-based systems (Atari 2600 and Commodore VIC-20), we used small PDP-11s running some DEC operating system (I don't remember which one), using in-house written 6502 cross development tools. Each developer had a PDP-11.

Same setup for developing for game systems we worked with that used processors other than the 6502, such as the GI 1610 that was used in the Mattel Intellivision and the next generation successor to the Intellivision we were designing for Mattel.

We're talking old school here--as in you started your work day by toggling in a short boot loader via the front panel switches to get your computer going.

[1] https://en.wikipedia.org/wiki/APh_Technological_Consulting

Re: How to program an NES game in C

#54
post #45
post #8

Earlier quoted context omitted.

Might be easier (but just as much fun) to whet your palate by creating a pico-8 game first: https://www.lexaloffle.com/pico-8.php

I'd beg to differ. Interpreted lua on a 4GHz pc with 4G of ram is not like compiled C on a 8bit micro. Avr dev or arduino could be arguably closer.

You should do a little more research into pico-8. Although its true that they aren't the same pico-8 has it's own set of artificial arbitrary execution cost and memory limitations that makes it a lot different than if you were using Love2D or LuaJIT embedded in an SDL2 app. Many things that should be trivial on a PC with effectively infinite resources are hard or impossible to do at frame rate on Pico 8.

The fantasy console that Pico 8 presents is still way more powerful in most ways than an NES though.

Re: How to program an NES game in C

#55

Earlier quoted context omitted.

Does c65 turn structs into parallel arrays? If you have something like struct Monster { unsigned char hitPoints; unsigned char damage; unsigned char shieldLevel; char* name; }; static Monster s_monsters[] = { { 5, 1, 0, "orc", }, { 50, 10, 5, "dragon", }, { 10, 3, 1, "goblin", }, }; that's a no-no on 6502. You generally need to store those in parallel byte arrays including the string pointer's upper and lower bytes e…

Didn't John Carmack use structures rather than parallel arrays even in Apple II assembly? Source: one of his old .plan files, reproduced verbatim in _Masters of Doom_ Edit: Found it online here: https://github.com/ESWAT/john-carmack-plan-archive/blob/mast...

I wrote a few lines about 6502 vs Z80 a couple of years ago: https://news.ycombinator.com/item?id=10766264 (parent of linked-to comment may also be of interest) - the discussion there was about relative efficiency of the two CPUs, but the addressing mode limitations that make one approach a bit inefficient on the 6502 are the same limitations that make it a bit inconvenient.

I wonder what Carmack had in mind.

---

P.S. In my comment there, I didn't mention the possibility of having the arrays interleaved. Then it looks like a struct in memory (byte 0 is X and byte is DX, say), and you add the field offset to the base of the array. It's not uncommon for assemblers to have some syntax to make it easy to specify the layout of each struct, to simplify future changes, e.g.:

    STRUCT ITEM
    X DS.B 1
    DX DS.B 1
    ENDSTRUCT

    CLC
    LDA TABLE+ITEM.X,X
    ADC TABLE+ITEM.DX,X
    STA TABLE+ITEM.X,X
    LDA #0
    STA TABLE+ITEM.DX,X
The disadvantages of this are that it reduces the number of accessible items (the X register is only 8 bits...); it makes moving from item to item more difficult (all you can do with the X register is increment or decrement it, but now you need to add arbitrary values to it); and it means there are invalid item indexes (e.g., in the example above, index 1 is not valid).

And the advantages... well, there aren't any, really, I don't think? Everything has to be done 1 byte at a time, so it makes no difference where the bytes are relative to one another... the code ends up the same anyway. (If anything, because you can do INX/DEX to get from item to item, it's actually slightly neater to have a separate table for each byte.) So you might as well do that.

Re: How to program an NES game in C

#56
post #46
post #36

> All NES assembers are command line programs. What does that mean? It has no graphic user interface. Who the hell is this written for?

I find a lot of these homebrew and ROM hacking documents are written for an enthusiast that might not necessarily have a background in software development. At first I found it a little disorienting because the technical level of the writing would fluctuate, but at the same time I can appreciate it being accessible for someone who might not know much about programming.

There's also an assumption with most HN users (who have a heavy web dev or unix background) that commandline is required in order to get any sort of development done. This isn't really the case if you have more of a game development background, where people are often using Windows and GUIs to get most work done. Someone coming to this tutorial that is used to Unity and Visual Studio could be technical, have solid programming abilities, but rarely, if ever touch the command line. I've worked with a lot of people like this, so it's not a theoretical thing.

Re: How to program an NES game in C

#57
post #46

Earlier quoted context omitted.

I find a lot of these homebrew and ROM hacking documents are written for an enthusiast that might not necessarily have a background in software development. At first I found it a little disorienting because the technical level of the writing would fluctuate, but at the same time I can appreciate it being accessible for someone who might not know much about programming.

There's also an assumption with most HN users (who have a heavy web dev or unix background) that commandline is required in order to get any sort of development done. This isn't really the case if you have more of a game development background, where people are often using Windows and GUIs to get most work done. Someone coming to this tutorial that is used to Unity and Visual Studio could be technical, have solid pro…

Agreed! Visual Studio has such a prominent place in game development, likely for its ubiquity and ease-of-debugging.

Re: How to program an NES game in C

#58

Yeah, making an NES game is on my bucket list. I'm very new at (complex) programming, but I think I might just do it in assembly. If you're going to run a marathon, why not actually do a triathlon?

I'd start with https://en.m.wikipedia.org/wiki/CHIP-8 first. It won't take too long, and you'll be much better prepared for nes.

I've built some pretty user-friendly development tools targeting Chip8:

https://github.com/JohnEarnest/Octo

Re: How to program an NES game in C

#59

Yeah, making an NES game is on my bucket list. I'm very new at (complex) programming, but I think I might just do it in assembly. If you're going to run a marathon, why not actually do a triathlon?

In reality most of the complexity lies in how "close to the metal" it is, not so much on the language or the programming techniques per se. Basically, to program for an old console with limited hardware like the NES, you have to understand how the hardware works at a relatively low level to do something with it. There's no "drawSprite" function that you call and be done with, but rather you have to understand what the video processor can do, how do your feed data to it, how you compose a sprite in a layer, etc etc.

So you learn how the different pieces of the hardware work, how do you instruct them to do things, what are their limitations and so on. And once that clicks, it's not particulary more complex than writing modern code. Like programming today, it's less about typing and more about thinking about how all the dots connect together towards doing what you want to do. You do end up with a lot more code that does a lot less, since there are no abstractions and you do everything by hand. But otherwise it's something that anyone with aptitude for programming can pick up.

Re: How to program an NES game in C

#60
A few years ago, some colleagues and I wrote a NES "demake" of Splatoon, in C, over the course of ~2 days. https://github.com/SplatooD/splatood

I definitely think our ability to do interesting things quickly (in terms of runtime) was hampered by the use of C over assembly, but it did allow us to get a functioning game done in a very short period of time.

Post reply on HN