I'm looking to rewrite the source code on my website using a "vanilla" neslib.
I have most of the things figured out, I will have to write a co-library to do what I want... but scrolling would seem to be the main problem. (dynamically writing a multiscreen game as you scroll)
The nmi code is too slow for my needs (fast and dynamic scrolling). I thought about options...
1. have an "escape nmi early" flag, check it at the top of nmi, and the main code can handle the writing to the PPU (faster)...I guess that flag could be called "the fast write buffer is filled" flag
or
2. write an entirely new nmi routine just for scrolling, making it incompatible with other neslib code examples
or
3. try to force using vanilla neslib, using an elaborate step by step approach of building metatiles a few block per frame.
I'm not sure which would be the best approach.
How much of the return stack does your C program use? If not more than 64 bytes or so ($01C0-$01FF), you could add
Popslide to the project. Writing a set of fastcall-convention wrappers around Popslide would sacrifice "just uses vanilla neslib" without sacrificing the ability to write straightforward C code that fills a buffer at $0108-$01AF.
Code:
#define popslide_buf *(unsigned char *)0x0108
Then your NMI would use the "is there anything in the Popslide buffer?" flag that Popslide already maintains to determine which updater to call.
The NMI is the first thing that went out of the window when I tested my code with neslib. I think that any game that will require decoding of metatile on every frame will require some special code for buffering and a custom NMI.
In my case, instead of having only 1 NMI, I have "dynamic" ones. What it means is NMI jump to an address that will jump to a new address which contain my real NMI. This means I need to put by hand the jmp opcode and the address of my NMI I want a the location the NMI vector jump.
This is something that I learned from nesdev thread a long time ago and if necessary I can write a quick example if required. I my case I even set it from the C code but doing so is maybe a little bit advanced for tutorial and is prone to error.
I usually add or replace a jsr to my own fast data writing function right before the jsr flush_vram_nmi or whatever it was called. The general design of Shiru's NMI is good, so if you need faster writes than what the buffer scheme gets you, you can do so without changing everything.
It sounds like most people would modify the NMI code.
I guess I will rename the neslib file, in that case.
I usually add a "copy this fast, linearly" buffer + code to neslib when required. It's quite usual, I think.
or keep neslib function "as-is", extract the nmi and put it in another file. If you use cc65 you will need to export a few variables from it but it's not a big deal. This way, you can have all the neslib function and update the nmi per project/tutorial when necessary.
The first tutorials will uses the same NMI file (basic palette, OAM, counter) and advanced case will have a custom one. I think that's a good compromise.
Quote:
The first tutorials will uses the same NMI file (basic palette, OAM, counter) and advanced case will have a custom one.
Sounds good.
You could put a default NMI handler in its own object in the library so it only gets linked in on request. Then maybe give the user a DEFAULT_NMI macro or something that imports it and links it to the NMI handler symbol used in the vector table?
That would allow it to be replaced by a custom one without having to rebuild the library.
neslib's existing packet w/direction update NMI handler seems fine to me, though to make it easier you could high the packet data structure from the user with convenient API functions that set it up for them (these could also go in the same module). I think that's good enough for many purposes. Someone who really needs extra efficiency for pumping 100+ bytes through their NMI is probably going to need to write a custom handler anyway.
Quote:
extra efficiency for pumping 100+ bytes
neslib can only push 97 tiles sequentially, or 40 bytes non sequentially...per frame.
and actually less, if the palette has been changed.
It's the 40 bytes non sequentially that bothers me.
dougeff wrote:
neslib can only push 97 tiles sequentially, or 40 bytes non sequentially...per frame.
and actually less, if the palette has been changed.
That sounds like an extremely reasonable amount to me.