Parallax Examples?

User avatar
Kasumi
Posts: 261
Joined: Fri Mar 09, 2018 11:13 pm

Re: Parallax Examples?

Post by Kasumi » Thu Aug 22, 2019 6:36 pm

For a couple more notes. It's actually not terribly hard to change NES Maker from Mapper 30 to MMC3 (which does have a scanline counter). (For anyone not using mapper 30 features it doesn't support. Which is primarily CHR RAM bank switching, or saves larger than 8KB, neither of which NES Maker uses without you adding them yourself anyway, at this point in time.) That is my own "Maybe I'll write a guide".

Finally, you can use an audio IRQ as a makeshift scanline counter: http://wiki.nesdev.com/w/index.php/APU_DMC#Usage_of_DMC_for_syncing_to_video

But I believe it's easier to switch to MMC3 than do that (with the main caveat that your game can no longer be flashed to a mapper 30 cart). MMC3 does have CHR ROM bank switching, but modifying the engine to use that instead would likely be involved.

But switching to MMC3 alone does nothing. You'd still have to write the code to use its scanline counter.
User avatar
Mugi
Posts: 697
Joined: Thu Dec 27, 2018 8:30 pm

Re: Parallax Examples?

Post by Mugi » Thu Aug 22, 2019 6:40 pm

well, speaking from experience, i can say that implementing a makeshitft scanline counter out of DMC irq is indeed doable (im using it) but it comes with a lot of work that has to be put
into the engine, as in it's vanilla state you have zero chance to use it for anything, the engine is just too slow, and having it intentionally slow down to synchronize the CPU in order to actually do accurate splits
requires a relatively ridiculous amount of rewriting of things.

that said, if you peek in to the Dimension Shift WIP thread, you can see it can actually be done.

on the matter of other things, if you do make a writeup about setting up MMC3 for nesmaker, that'd be an interesting read.
"what are you up to?" "Oh, not much... just... Parallaxing"
- Raftronaut
User avatar
Kasumi
Posts: 261
Joined: Fri Mar 09, 2018 11:13 pm

Re: Parallax Examples?

Post by Kasumi » Thu Aug 22, 2019 7:03 pm

I know you have done it, I had you in mind as I wrote the post. ("for anyone not using mapper 30 features it doesn't support") You are, the CHR RAM bank switching.

I wrote out how to do it in the discord, the only real "issues" are
1. That a mapper 30 bank switch is 16KB, and an MMC3 bank switch is 8KB. So the NMI gets slightly more complicated to "interrupt" in the middle of the two writes safely.
2. Only $E000-$FFFF are guaranteed to consistent on startup (again, because the banks are 8KB), and NES Maker's engine has reset at $C000. This is only lightly annoying, the first issue is larger.

Beyond that, it's just change the header/bank switch routine and you're done. I'll add quotes from discord here:
Itemized changes (plain English)
1. Change mapper number to 4 from 30.
2. Change the name of the RESET label
3. Add a snippet before the vector includes called RESET that jmps to the new name of the old RESET
4. Add three bytes somewhere in RAM (nmisafeprg0, nmisafeprg1, and nmibanktoset)
5. Replace BankSwitch.asm with the 616 byte one below.
6. After the php left for context in the NMI, add the snippet from below.
7. Before the plp left for conext in the NMI, add the snippet from below.
8. Maybe initialize CHR banks too, I don't know if it's required. I only have an MMC3 CHR ROM cart.
Header.asm change (accomplishes 1):

Code: Select all

	.db "NES",$1a       ;iNES identifier

	.db $20         ;number of PRG-ROM blocks
	;;32 prg rom blocks
	.db $00         ;number of CHR-ROM blocks
	;;0 chr rom blocks, using chr ram
	.db %01000011 
	;;   ||||
	    ;MAP 3 2 1 0
	
	.db %00000000    ;ROM control bytes: Horizontal mirroring, no SRAM or trainer, Mapper #0
	;;   ||||
	   ; MAP - 7 6 5 4
	
	.db $00,$00,$00,$00,$00,$00,$00,$00   ;filler
Reset Changes: (Accomplishes 2 and 3)
you could change RESET: in reset.ASM to RESETPOSTMAPPER: then add this directly below the include for the vectors in MainASM.asm:

Code: Select all

;The below routine is 21 bytes.
;Vectors.ASM .orgs to $FFF0
.org $FFF0-21;So put this code 21 bytes before it
RESET:
    sei;Disable IRQs
    ldx #$00
    stx $E000;Disable mapper IRQs
    stx $A000;Set up mirroring
    
    stx $2000; Disable NMI
    stx $2001; Disable Rendering    
    stx $8000;Ensures $8000-$BFFF is swappable

    JMP RESETPOSTMAPPER
Accomplishes 5:
BankSwitch.asm.zip
(433 Bytes) Downloaded 6 times
Accomplishes 6:

Code: Select all

NMI:
    ;first push whatever is in the accumulator to the stack
    
    PHA
    LDA doNMI
    BEQ dontSkipNMI
    JMP skipWholeNMI
dontSkipNMI:

    LDA #$01
    STA doNMI
    TXA
    PHA
    TYA
    PHA
    PHP;This line and above are unchanged, here for context

    lda nmibanktoset;Pushing nmibanktoset to the stack just to preserve it since we're still using
    pha;the generic bank switch routines which change it
    lda nmisafeprg0
    pha
    lda nmisafeprg1
    pha
    
    LDA temp;this line and below are unchanged, here for context
    PHA ;STA NMItemp
    LDA temp1
Accomplishes 7:

Code: Select all

LDA #$00
    STA doNMI;This line and above are unchanged, here for context

    lda #7
    sta $8000

    pla
    sta nmisafeprg1
    sta $8001

    lda #6
    sta $8000
   
    pla
    sta nmisafeprg0
    sta $8001

    pla
    sta nmibanktoset
    sta $8000
    
    PLP;This line and below are unchanged, here for context
    PLA
    TAY
    PLA
    TAX
skipWholeNMI:    
    PLA

    
    RTI   
There's a better way to do most of that, because NES Maker doesn't ever swap 8KB banks (it can't, and Indivisible does), but I leave it as an exercise to the reader if they really want the byte(s) of RAM

It's definitely possible to do 4, 5, 6, and 7 with fewer changes (because NES Maker will always swap two 8KB banks), but paradoxically I'd have to think harder about them. I know what Indivisible does works. 2 and 3 (and 8?) are lightly annoying, if only mappers initialized to a more known state they wouldn't be needed at all.
I'll add the caveat from discord as well:
Not super tested, but I'd anticipate problems would not be hard to fix
Edit: Hang on, reset is slightly wrong, I'll fix.
Edit4: Okay. Should be good. The previous version "worked" by accident. (Was using sta, but ldx which set not-the-mirroring-Indivisible-uses (0), assuming an emulator started A at 0.) I had wondered about why mirroring worked whenever I first did this, since NES Maker doesn't want its mirroring.
Edit2: The bank switch isn't the NMI safe one too >_> I guess I grabbed the wrong version from discord.
Edit3: Bank Switch fixed.

All issues should now be fixed, if they're not, yell at me.
Last edited by Kasumi on Thu Aug 22, 2019 7:41 pm, edited 2 times in total.
User avatar
Mugi
Posts: 697
Joined: Thu Dec 27, 2018 8:30 pm

Re: Parallax Examples?

Post by Mugi » Thu Aug 22, 2019 7:14 pm

that's pretty throughout for a "quick writeup", but then again, i suppose you do know what you're doing afterall, unlike i do :P
i already decided that dimension shift will be version locked to nesmaker 4.1.4 and mapper 30 as so much work has gone into the engine that simply flipping all that over at this point would
just be complete nonsense, but this is extremely interesting regarding any future endeavors i might do after DS.
scanline counter was one of my biggest butthurts with nesmaker's decision of going for mapper 30 (i love parallax THAT much!) but since that has now been rectified too in a relatively functional manner (work load aside lol)
i'll just keep that for future adventures :P

no wonder i missed it i guess, since i got (unjustly) banned from the NM discord :P
"what are you up to?" "Oh, not much... just... Parallaxing"
- Raftronaut
User avatar
Kasumi
Posts: 261
Joined: Fri Mar 09, 2018 11:13 pm

Re: Parallax Examples?

Post by Kasumi » Thu Aug 22, 2019 7:34 pm

The thoroughness is to be as safe as possible, but by changing only the bank switch subroutine/header I had a NES Maker game working on MMC3 in two minutes. Edit: (That said, it wasn't safe yet!) The writeups take much longer to read/write than actually doing it.

It's very few actual changes, at the end of the day. But still, anyone feel free to yell at me if this doesn't work for some reason. Edit2: Just realize if you DO do it, your game will only work exactly the same as it did before. This gives you the option to use MMC3 features, it doesn't provide anything that actually uses them.
User avatar
Mugi
Posts: 697
Joined: Thu Dec 27, 2018 8:30 pm

Re: Parallax Examples?

Post by Mugi » Thu Aug 22, 2019 7:48 pm

well yeah obviously, the bigger workload here is to actually code something to make use of the provided things.
i was originally interested of chr rom as opposed to chr ram simply because that's what shatterhand uses, and my initial desire was just to make a shatterhand 2.
i eventually ditched that idea mostly due to copyright reasons but bleh..
chr ram is fun and all though, especially now since the way DS allocates it's chr's has been completely overhauled and void of all the nesmaker restrictions (i load full 128x128 chr's, with 16 metatiles of animations, no more huds and paths and screentiles.)
"what are you up to?" "Oh, not much... just... Parallaxing"
- Raftronaut
User avatar
Kasumi
Posts: 261
Joined: Fri Mar 09, 2018 11:13 pm

Re: Parallax Examples?

Post by Kasumi » Thu Aug 22, 2019 9:39 pm

I think my issues with writing all manner of NES Maker specific guides are time spent to write accounting for prerequisite knowledge, breaking the UI, and unfamiliarity with the engine.

It (probably) takes less time to set up an MMC3 IRQ than it does to do the changes outlined to change to MMC3 in the first place. You cli someplace safe, you remove the old waits for sprite 0, you move the code that actually changes the scroll into an IRQ (pushing A to/pulling A from the stack), then write how many scanlines to wait to three registers in order at the start of the NMI (if I remember correctly) and retime the code that's now in the IRQ slightly (this particular part would be annoying, if not for Mesen's Event viewer). This is actually a change you could make without really breaking the UI (the sprite zero position is exported, which you can use for how many lines to wait). It wouldn't work exactly the same (since a hit could occur of any of the 64 pixels within the sprite rather than the one exported position, depending on how the user sets it up), but that's mostly fine.

Maybe I could do it in 5 minutes! Certainly faster than it took to even write the above short version >_>. But if the discord MMC3 guide is any indication, it's gonna take a couple of hours to specifically write about how to do it/test it. And after I have done all that, there's no (real) benefit to anyone. (Well, maybe to people who want their HUD on the bottom.) Now you're on MMC3, and you're using a scanline split, but your game plays exactly the same as before you started. :lol: And then writing about multiple splits from there stops being about NES Maker, doesn't allow the UI to help etc.

I dunno, most things people ask about to me make me just want teach fundamentals in the first place. It usually stops being NES Maker specific by step 2, and then continuing in a NES Maker context makes the guide take more time to write for the reasons outlined above. (This post isn't really directed at anyone, just kind of a thought dump. I realize no one asked about then using scanline splits with MMC3, but like... it does end up being the next step. And the above explains why I end up not just covering that "obvious" next step.)

Edit: I guess one example people might understand is GGSound vs NES Maker's use of GGSound. (Order 09 limitations from earlier versions, things like that.) If I could teach how to use GGSound/IRQ Scanlines/Saving/whatever, and fundamentals could be used to apply them to NES Maker, I feel like more people could be helped. Otherwise, I'm bandaiding things, I feel. One could follow those MMC3 steps, and get a result, but with fundamentals you could switch to FME-7 or whatever. Someday, I'll write fundamental guides, but at this point I'm just ranting. <crawls back into hole>
User avatar
Mugi
Posts: 697
Joined: Thu Dec 27, 2018 8:30 pm

Re: Parallax Examples?

Post by Mugi » Thu Aug 22, 2019 10:28 pm

i certainly feel you with that.
there's a reason why i didnt dump the code for CHR RAM to the forum or why i dont have a tutorial up for setting up a 4-directional scroll into nesmaker,
simply because the way those are done in my game are so out of nesmaker now that even if i did manage to fight my way through 10 hours of writing instructions and copypaste-ready code,
its still not manageable in any shape or form from nesmaker itself, it's just assembly code that nesmaker doesnt really know exists outside of the fact that it compiles it because it's included in a bank**.asm file.

someone even flipped a table at me that i lied when i said that my game doesnt really work with nesmaker anymore because i had it open on a video where i demonstrated something, and i just think people really misunderstand
the whole function of the tool. it doesnt have to be "if or else" scenario really.
for instance, the only things i actually use nesmaker for anymore are 1) drawing screens (i do assets and chr's outside of the tool, i literally just paint screens) 2) i manage objects with it 3) i use it to organize my assembly files.
i dont have hud things (clicking that on my project crashes nesmaker) i dont have UI options for managing variables, etc etc... there's so many things that are just stripped off or modified to the point that nothing really works the way it should.
"what are you up to?" "Oh, not much... just... Parallaxing"
- Raftronaut
Post Reply