Creating a swaying background

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Creating a swaying background
by on (#139266)
You know how Recca has these swaying background effects? I was thinking of creating a code that easily lets you create those effects. Because I want to have it in general use for everyone, it'd be good to have more than one people to create (and later optimize) the code. This will be for MMC3 mapper, but can be later modified to be used with other mappers with scanline IRQ.

My current plan is to use only one IRQ routine and NMI to set up the IRQ request if a flag is set for that. The IRQ routine checks bunch of variables like:

    - first split scanline
    - split increment
    - amount of splits to create
    - offset in the swaying table
    - address where the swaying table is located
    - swaying table length
    - swaying mode

Using these variables the IRQ routine knows how to handle the swaying. One other function would be that you can choose what to do when you reach the end of the swaying table. Possible options would be either loop, stop or load new swaying table. This would allow start and end swaying to make the transition between non-swaying and swaying background look smoother.

Here is a pseudo code of the current plan:

Code:
; in game code
Setup variables and enable swaying

; in NMI
Reload IRQ with the $C000, $C001, $E000 and $E001 if swaying is enables

; in IRQ
Acknowledge IRQ
Read swaying table offset and move scroll after split to that position
Decrement split count
If split count == 0 -> RTI
Compare swaying table offset with table length
If equal -> check swaying mode for next action
If not equal set up next IRQ and exit


Any additional ideas and things to consider would be appreciated. Currently the other splits will "trace" the previous split's position, but I still need to figure out how to do that.
Re: Creating a swaying background
by on (#139294)
Don't forget Time as a variable.
Re: Creating a swaying background
by on (#139326)
Myask wrote:
Don't forget Time as a variable.


You mean a "update every x frames" type of time variable?
Re: Creating a swaying background
by on (#139490)
Yeah. Though, with wave-type you can just add time (divided by something) to the slice number to offset You seem to have done this. If you allow separate pointers you can do other effects, like 6-2 in Castlevania: Bloodlines, or a "cut up the screen" transition between scenes. Or the matching-slices-of-powerups roulette from SMB3.
Re: Creating a swaying background
by on (#139531)
There are two demos on the wiki which might be useful.

http://wiki.nesdev.com/w/index.php/Proj ... ris_Covell

Both are by Chris Covell,

http://nesdev.com/cmcwavy.zip

This one some some nice horizontal waving.

http://nesdev.com/Stretch.zip

This one does cool vertical stretching.

Hope this helps!
Re: Creating a swaying background
by on (#140167)
Update


I got the swaying working now. All I need to do is add a simple way for people to edit the swaying settings. I also need to optimize the code a little bit, because this alone is enough to give lag frames. Recca doesn't get any when the game is paused (the swaying keeps going while paused). It is still playing it's DCM heavy music and stuff so...

But anyway here is a picture :P
Re: Creating a swaying background
by on (#140168)
I think the 1-line 8-pixel-off artifacts are because the coarse scroll (X bits 8-3) needs to go in earlier than the fine scroll (X bits 2-0). So you're seeing one scanline's coarse scroll with another line's fine scroll.
Re: Creating a swaying background
by on (#140177)
Awesome job! I am going to try and code a project like this in the next few weeks.
Re: Creating a swaying background
by on (#140221)
tepples wrote:
I think the 1-line 8-pixel-off artifacts are because the coarse scroll (X bits 8-3) needs to go in earlier than the fine scroll (X bits 2-0). So you're seeing one scanline's coarse scroll with another line's fine scroll.


If with the coarse and fine scrolling are referring to the $2005 $2006 $2006 $2005 scrolling thing, All I need to say it that I didn't use the $2006 register at all. It may look a bit off because of how the graphic looks like (see attachment).
Re: Creating a swaying background
by on (#142343)
Update 2


I think that the code is now ready to be posted here. The code has multiple lookup tables with different "swaying intensity". You can change the table by changing the number in LDA SwayTable02, x (00 - 04) under SwayCopy label. Currently the table is copied to RAM to let you modify it in Main Loop if you want to. NTSwap is used to swap between the two nametables (vertical mirroring) when the swaying position in the SwayTable either under- or overflows. I'd be interested in seeing what people can do with this after modifying it. Currently the code does not work 100% correctly under PAL emulation. The attached file should have all you need.

Before Main Loop:
Code:
 LDA #$04
 STA sway_pointer
 STA sway_pointer_new
 LDX #$1F
SwayCopy:
 LDA SwayTable02, x
 STA sway_table, x
 DEX
 BNE SwayCopy

 LDA #$00
 STA Mirroring
 STA irq_offset
 LDA #$1F
 STA sway_length
 LDA #$03
 STA irq_scanline
 STA IRQLatch
 STA IRQEnable
 STA IRQReload


IRQ:
Code:
IRQ:
 PHA
 TXA
 PHA
 TYA
 PHA
 LDX #$00
 STX IRQDisable
 STX IRQEnable
 LDA irq_scanline
 STA IRQLatch
 LDA frame_roll
 CLC
 ADC irq_offset
 AND sway_length
 TAY
 LDA sway_table, y
 STA scroll_x
 STA PPUScroll
 STX scroll_y
 STX PPUScroll
 LDA NTSwap, y
 STA PPUCtrl
 INC irq_offset
 PLA
 TAY
 PLA
 TAX
 PLA
 RTI


In NMI routine:
Code:
 LDA #$00
 STA sleeping
 STA irq_offset
 INC frame_roll
 LDA irq_scanline
 STA IRQLatch
 STA IRQReload