NESmaker update

A place where you can keep others updated about your NES-related projects through screenshots, videos or information in general.

Moderator: Moderators

JoeGtake2
Posts: 333
Joined: Tue Jul 01, 2014 4:02 pm

NESmaker update

Post by JoeGtake2 »

Not sure the best place to put this - moderators feel free to move. I just wanted to provide a link to the latest NESmaker update, which shows how we handle input management, and open to custom ASM routines.

If you're interested or curious, check it out here: https://youtu.be/3NMbWhGs-ck

Especially for all of you who have been constantly in the trenches, would love to know your thoughts on if and how this might speed up rapid prototyping for you, even if you're only using it for proof of concepts and whatnot. :-)

You guys rock.
Last edited by JoeGtake2 on Fri Feb 23, 2018 10:47 am, edited 1 time in total.
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: NESmaer update

Post by dougeff »

Thanks Joe. I didn't know you worked on Sydney Hunter.

BTW. You can edit the title of a thread by clicking on the EDIT button of the first post of that thread.
nesdoug.com -- blog/tutorial on programming for the NES
JoeGtake2
Posts: 333
Joined: Tue Jul 01, 2014 4:02 pm

Re: NESmaker update

Post by JoeGtake2 »

Hey friend - didn't work myself on Sydney Hunter at all. Just friends with the Collectorvision guys, and since they just released the SNES Sydney Hunter, and I was doing this video anyway, I asked if they would like the plug as I demonstrated our input manager. :-)
Bananmos
Posts: 552
Joined: Wed Mar 09, 2005 9:08 am
Contact:

Re: NESmaker update

Post by Bananmos »

The amount of configurability for input looks impressive, seems like this project is headed the right way!

One thing I found curious though is that the video seems to indicate that a full byte is used for the actor direction. This seems a bit wasteful with the tiny 2kB of RAM the NES has. A common technique is to use a "flags" byte which stores the horizontal direction in the MSB, and use other bits for palette selection and background priority. Perhaps worth considering?

And then, I've also thought about the configurability of NESmaker, and as an advanced user I'd really appreciate if the NMI (and ideally also IRQ) address was configurable. i.e., a common programming pattern is to store the address of the handler in 2 bytes of zeropage RAM, and have the ROM address do an indirect jump with this address.

While you spend 2 bytes and a few cycles of RAM with this method, it allows you to easier change game state completely. So if I were to say have a very specific cut-scene which needs perfect NMI/IRQ timing, I wouldn't have to figure out how to best shoehorn my code into the NESmaker code (which may change between versions). I'd just set my own handlers, and restore them when done (together with other game state pushed on the stack).

And yes, I know I could always do this by hacking the existing NESmaker code. But having to patch the main engine is a bit of a hurdle when collaborating, so it'd be way better if this use-case was natively supported.

A tangential request to the above one would also be to have a clear deifinition of permanent vs temporary game state. For my imagined awesome-scrollery-trick cutscene, I will undoubtly need to use some RAM, and will have to consider what RAM used by NESmaker is the permanent gameplay state I must preserve, and what is data that could be restored by re-initialisation. Examples of the latter would be the spritepage, screen and attribute shadows, music data and so on. Having this clearly defined would be helpful for extending NESmaker.
JoeGtake2
Posts: 333
Joined: Tue Jul 01, 2014 4:02 pm

Re: NESmaker update

Post by JoeGtake2 »

Bananmos - thanks for the feedback!

We are still working with definable byte structures, effectively making *classes* of objects, so during the main-game cycle, during applicable parts, updates are happening for the bytes being affected for that class. For instance, an enemy projectile - type - class of object doesn't need nearly the object info that a player object does. We're working on making a class system so you might be able to determine bytes - used - by- class based on an individual particular game needs. It's a super complicated beast from a CONCEPTUALLY standpoint, let alone getting good cross talk between the tool and engine. Small things at a time. But sometimes, that's why it's harder to be more efficient with bytes, that may or may not be present. A power up may not need directionality, for instance, but might need the other bits in that byte. You can see the conundrum.

Right now, we have to do a lot of weighting ease against flexibility against conformity. Our animation engine, for instance, is super inefficient compared to what it could be, but it also is super regimented and user friendly and intuitive. So...that's a trade off. Our main demographic here are people who have zero ASM experience (and only limited coding experience), while hopefully providing enough back doors to more easily hack the engine for the needs of those who are much more confident. Essentially, we want to use this tool to take a complete newcomer through that grueling period of self doubt to give them the confidence to WANT to jettison our tool and build from scratch! :-)

Also, generally speaking, we have it broken out into GameState and subGameState, which could allow you to utilize the subGameState to still carry on common game state needs (Drawing whatever, for instance), but also allow you particulars between sub-game-states. That's how Mystic Searches handles it, so we're just sort of porting that concept over. In most things, we're using the experience we gleaned from working with COMPLETELY green folks sitting at the tool, and my years of experience teaching GameMaker and Unity to people who had never seen programming languages before, to make something that's as intuitive as it can be for NES development, even though it may not be the most efficient or best optimized way to do any one particular thing. Does that make sense?

Even still, even if current devs just use this for rapid prototyping or for the level editor or music editor or pixel editor...that's awesome. But yeah, feedback like this is awesome for sure. Any time you see something like that, feel free to point it out in case it's something we haven't thought of (but know that there was probably some trade off reason we did a thing in a particular way). You rock! :-)
Bananmos
Posts: 552
Joined: Wed Mar 09, 2005 9:08 am
Contact:

Re: NESmaker update

Post by Bananmos »

Does that make sense?
Well, to be honest: Not really... :P

I asked 3 questions and you only answered the least interesting one of them, while leaving the two more important ones out. OTOH, I readily admit it was a very chatty post from my side, so I'll try again and be more focused in what I'm asking about:

Question1) Would you consider optimising the object direction to occupy just 1 bit.
- You've already answered this by saying it's not much of a priority, and that your pseudo-OOP allocation of gameobject RAM might make it a special case only some objects anyway. And that's perfectly fine as micro-optimisations may not be necessary - just keep that option in mind if RAM usage does become an issue.

Question2) Could we please have the NMI in NESmaker consist of a "JMP (NMIaddr)" instruction, so that we can more easily inject our own? (and same for IRQ)

Question3) Will we have some documentation on the RAM usage of NESmaker, so we know what RAM contains crucial gameplay state and what we can trash for our own use?

Oh, and I forgot to throw in another question that I'm curious about:

Question4) Which assembler is NESmaker? Is it CA65, or some other one?
Erockbrox
Posts: 397
Joined: Sun Nov 23, 2014 12:16 pm

Re: NESmaker update

Post by Erockbrox »

I can tell that there are probably some NES ASM programmers who will take NESmaker and then rewrite certain parts of the code to personalize it in their own specific way.

I could see an expert ASM coder look at the code in NESmaker and say "why did they do this" or "this is not optimized" because different coders have their own style of doing things.

For me, I don't even know how to put graphics or anything up on the screen so I would be adapting to the style of programming that NESmaker offers, but to a master ASM coder NESmaker might be harder to adapt to.
JoeGtake2
Posts: 333
Joined: Tue Jul 01, 2014 4:02 pm

Re: NESmaker update

Post by JoeGtake2 »

Question2) Could we please have the NMI in NESmaker consist of a "JMP (NMIaddr)" instruction, so that we can more easily inject our own? (and same for IRQ)
Hm - I mean...if anyone knows what they're looking at to this degree, it's not like this would be hard to customize. I'm not sure we'll set it up that way...but I guess I can look at it? There is no IRQ, using Mapper 30. Again though - if someone is to that degree of proficiency, I'm not sure this would be too difficult a problem on the code side even if we don't implement it...I wonder how many things would be truly integral, though, if someone were to write their own NMI. I guess it would depend on what you're really using to tool for. Again, that sort of goes back to our main demographic for use, being people who would never make use of this functionality.

Question3) Will we have some documentation on the RAM usage of NESmaker, so we know what RAM contains crucial gameplay state and what we can trash for our own use?
Sure, and it's relatively easy to track, too. The addresses for various things are pretty clearly lain out as constants at the top of the code (though subject to change). I'll obviously make things as documented as possible, but with all of the variability, I'll likely be more documenting conceptual things, as they may be different from genre module to genre module...advanced coders such as yourself would be able to recognize what they're looking at upon knowing where to look...drag and drop level users would have no use for this info, because they wouldn't even know what to do with it if they found it.

Question4) Which assembler is NESmaker? Is it CA65, or some other one?
ASM6

Thanks for the feedback :-)
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: NESmaker update

Post by tepples »

JoeGtake2 wrote:Question2) Could we please have the NMI in NESmaker consist of a "JMP (NMIaddr)" instruction, so that we can more easily inject our own? (and same for IRQ)
[...] There is no IRQ, using Mapper 30.
A raster split (ab)using the DMC is possible. See DPCM Letterbox.
Bananmos
Posts: 552
Joined: Wed Mar 09, 2005 9:08 am
Contact:

Re: NESmaker update

Post by Bananmos »

if someone is to that degree of proficiency, I'm not sure this would be too difficult a problem on the code side even if we don't implement it...
Yes, but as I said earlier in this thread the reasons why I'd prefer native support are:
...I wouldn't have to figure out how to best shoehorn my code into the NESmaker code (which may change between versions).
[...]
And yes, I know I could always do this by hacking the existing NESmaker code. But having to patch the main engine is a bit of a hurdle when collaborating, so it'd be way better if this use-case was natively supported.
So if I am collaborating with someone less technical that uses NESmaker, then without a settable IRQ-address I would have to first find some free zeropage bytes (which in worst case may not even be available), and then I would either need to:
1) Ask my fellow NESmaker user to manually modify their output code according to my instructions - tedious and error-prone.
2) Write a program that tries to do the patching of the output code automatically - likely to break with NESmaker version changes.

None of those options seem very appealing TBH.

In contrast, if there was native support for a configurable NMI/IRQ address, I'd just ask the NESmaker user to INCBIN my precompiled 16kB binary in one of the PRG banks, then do a JSR $8000 to give control to my code for doing the cool screen transition/cutscene I've provided for them.
(and perhaps even adding the INCBIN/JSR $8000 wouldn't be necessary, if NESmaker would allow a feature for inserting "plugin code" like this)
There is no IRQ, using Mapper 30
Tepples's DMC IRQ was indeed what I was having in mind. The forum thread linked to is quite long though, so I think the wiki about the DMC summarizes it better if you're short on time.

An even simpler variant of this that I've used successfully is to combine a coarse DMC IRQ which waits for a sprite#0 hit. That way you make sure the DMC will interrupt code that takes a variables amount of cycles, while still relying on the sprite#0 hit to get the finer timing needed for PPU register writes.

Both methods are obviously a lot more cumbersome than a proper scanline IRQ like the MMC3 has, but do enable screen-effects that would otherwise be very difficult to do on mapper's that have no IRQ support.

There's also other neat uses of the DMC IRQ, such as http://www.slack.net/~ant/misc/nes-saw/
Our main demographic here are people who have zero ASM experience (and only limited coding experience), while hopefully providing enough back doors to more easily hack the engine for the needs of those who are much more confident.
Yeah, that's fair enough. But my hope was that this tool would also allow easy collaboration between people with less programming knowledge (who can use the NESmaker tool without touching the asm output) and those with more programming knowledge (who'd like to add more bells&whistles to the NESmaker-made game, but would prefer using their own tools/assembler). And having to do loads of error-prone patching to glue these things together sounds like not a lot of fun. And seems unnecessary, as it can be avoided with just a little bit of foresight... :)
User avatar
NovaSquirrel
Posts: 483
Joined: Fri Feb 27, 2009 2:35 pm
Location: Fort Wayne, Indiana
Contact:

Re: NESmaker update

Post by NovaSquirrel »

I don't see why interrupt pointers need to be in zeropage? JMP indirect always takes a 16-bit address, so all you're doing is saving like two cycles when updating the address at the cost of precious zeropage memory.
Bananmos
Posts: 552
Joined: Wed Mar 09, 2005 9:08 am
Contact:

Re: NESmaker update

Post by Bananmos »

Post subject: Re: NESmaker update Reply with quote
I don't see why interrupt pointers need to be in zeropage? JMP indirect always takes a 16-bit address, so all you're doing is saving like two cycles when updating the address at the cost of precious zeropage memory.
Heh, that just shows I'm getting old and don't know my 6502 instructions as well as I used to! ;)

That means it's even less of a cost then, as you wouldn't be wasting zeropage RAM. So yeah, 2*2 = 4 bytes of RAM to make NESmaker a lot easier to extend with 16kB "plugins".
JoeGtake2
Posts: 333
Joined: Tue Jul 01, 2014 4:02 pm

Re: NESmaker update

Post by JoeGtake2 »

Forgive me for being dense on this point...I admit, I completely am not sure the benefit, still.

If there is an

Code: Select all

.include "Routines\NMIroutines\NMIcode.asm"
, and that NMIcode.asm is exposed in the tool...what functional benefit would be gained from determining its address or making that address changeable again? If the question is about including custom NMI code...you could just put that in that code, no? I'm not sure variable NMI address makes that any easier.

Maybe I'm completely missing the use here. Sorry for being dense on this point! haha
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: NESmaker update

Post by dougeff »

If you had a game that had minigames, it might make sense to have multiple NMI routines, to handle the different PPU update needs of each mini-game.

Or perhaps if had designed a Title screen (or Ninja Gaiden style cutscene) that involved a highly optimized PPU loading system...for fast changing animations...it might have different NMI needs than the in-game one.

But, for a general purpose game maker, I wouldn't. Options will just confuse newer / less skilled users.
nesdoug.com -- blog/tutorial on programming for the NES
JoeGtake2
Posts: 333
Joined: Tue Jul 01, 2014 4:02 pm

Re: NESmaker update

Post by JoeGtake2 »

Interesting. Yeah, I can see that.

I mean, you'd lose a few NMI cycles, but you could likely do a quick table read in custom NMI code to achieve the same results, no? Rather than variable NMIs, variable places to jump within an NMI?
Post Reply