agnes - single C header NES emulation library
Moderator: Moderators
agnes - single C header NES emulation library
Hi all!
I want to present you agnes. Agnes is a NES emulation library available as a single C header. It's very easy to use and should be trivially embeddable. Also, it could be useful as a reference for other people writing NES emulators.
Current status: it supports 4 mappers (NROM, UxROM, MMC1 and MMC3), but it's possible that some games might not work correctly (as always). Also, there is no sound due to lack of APU emulation. And performance could be better (there's a lot of space for performance optimizations in PPU rendering).
You can find it here: https://github.com/kgabis/agnes
I'd like to thank all people on this forum and NesDev wiki, it would be impossible to write a NES emulator without all the knowledge found here.
I want to present you agnes. Agnes is a NES emulation library available as a single C header. It's very easy to use and should be trivially embeddable. Also, it could be useful as a reference for other people writing NES emulators.
Current status: it supports 4 mappers (NROM, UxROM, MMC1 and MMC3), but it's possible that some games might not work correctly (as always). Also, there is no sound due to lack of APU emulation. And performance could be better (there's a lot of space for performance optimizations in PPU rendering).
You can find it here: https://github.com/kgabis/agnes
I'd like to thank all people on this forum and NesDev wiki, it would be impossible to write a NES emulator without all the knowledge found here.
- rainwarrior
- Posts: 8719
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: agnes - single C header NES emulation library
Hah! Nice. I'm tempted to incorporate this into one of my random hobby projects just... because.
Re: agnes - single C header NES emulation library
Would you prefer that I make feature requests in this topic, in GitHub Issues, or somewhere else?
Re: agnes - single C header NES emulation library
I think that github issues is the best place for ittepples wrote:Would you prefer that I make feature requests in this topic, in GitHub Issues, or somewhere else?
Re: agnes - single C header NES emulation library
This is slick! I implemented it in no time and no trouble. I may include it in my NES graphics tool until such time as I get crazy enough to attempt my own emulator.
The only thing I see that's "wrong" is no output for emphasis bits, but it's not a large complaint or anything.
The only thing I see that's "wrong" is no output for emphasis bits, but it's not a large complaint or anything.
Re: agnes - single C header NES emulation library
Recently I've been working on exposing nametables and sprites through the API. You can see it in action here: https://twitter.com/KrzysztofGabis/stat ... 1925894146
Re: agnes - single C header NES emulation library
More work on emulator debugging:
* Showing visible area on per-scanline basis
* Displaying contents of RAM (bottom)
* Displaying contents of PPU memory (right)
I hoped that writing a "speculative" emulator that draws whole screen and then redraws portions of it when scroll/banks change would be much easier but at this point I'm leaning towards ignoring optimizations (for now) and concentrating on APU emulation. It's the last bit that's really missing from making my emulator complete (by my definition of complete
).
Anyway, here's a short video:
https://twitter.com/KrzysztofGabis/stat ... 9092816896
* Showing visible area on per-scanline basis
* Displaying contents of RAM (bottom)
* Displaying contents of PPU memory (right)
I hoped that writing a "speculative" emulator that draws whole screen and then redraws portions of it when scroll/banks change would be much easier but at this point I'm leaning towards ignoring optimizations (for now) and concentrating on APU emulation. It's the last bit that's really missing from making my emulator complete (by my definition of complete
Anyway, here's a short video:
https://twitter.com/KrzysztofGabis/stat ... 9092816896
Re: agnes - single C header NES emulation library
One word: awesome.
Re: agnes - single C header NES emulation library
Not sure if anyone will find it interesting, but I haven't heard of any emulator doing this. Recently I've been playing with frame interpolation to make NES games play more smoothly on high refresh rate displays (120, 240hz). The idea is to emulate 2 frames at once and then interpolate scroll and sprite positions in between. The downside is that you need to render screen and sprites separately and it's quite hard to do in a non-glitchy way (especially with games changing bank mid-screen). So far interpolating scroll positions has been quite successful but interpolating sprite positions is quite tricky and I'm not sure it can be achieved because the same "game object" can end up being two different sprites on two consecutive frames. Anyway, I've tested it with SMB at 120hz and it plays noticeably smoother. You can see the results running at 50% speed here (interpolated frames are on the right):
https://www.youtube.com/watch?v=bH4RBxaj9QY
Not sure if I'll spend more time on this, but seeing that more and more people have high refresh rate screens I think this might be an interesting direction.
https://www.youtube.com/watch?v=bH4RBxaj9QY
Not sure if I'll spend more time on this, but seeing that more and more people have high refresh rate screens I think this might be an interesting direction.
Re: agnes - single C header NES emulation library
If raster effects are causing problems, you need a different way to think about whole-screen rendering.
After a frame runs, you can collect information for each scanline: (possibly sample this information at the middle of each scanline)
* X Scroll
* Y Scroll
* PPU Control
* PPU Mask
* 8 selected CHR banks
(you don't necessarily need to store every scanline separately, just indicating when it changes is enough)
From there, you can do a not-pixel-accurate, but somewhat accurate reconstruction of the whole screen. It would be good enough for most games other than Marble Madness or Punch Out.
Then divide the screen into scrolling regions. For example, detect the status bar, and the main game screen separately. Then you can have much better results for motion interpolation.
After a frame runs, you can collect information for each scanline: (possibly sample this information at the middle of each scanline)
* X Scroll
* Y Scroll
* PPU Control
* PPU Mask
* 8 selected CHR banks
(you don't necessarily need to store every scanline separately, just indicating when it changes is enough)
From there, you can do a not-pixel-accurate, but somewhat accurate reconstruction of the whole screen. It would be good enough for most games other than Marble Madness or Punch Out.
Then divide the screen into scrolling regions. For example, detect the status bar, and the main game screen separately. Then you can have much better results for motion interpolation.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
Re: agnes - single C header NES emulation library
That's what I'm doing with scroll positions right now, I'm storing them per scanline. Otherwise the status bar in SMB wouldn't work correctly.
Re: agnes - single C header NES emulation library
Not really, it proved quite hard to implement in a non-glitchy way because of the issues I've mentioned 