how do i go about performing bg tricks with hardware writes?

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
how do i go about performing bg tricks with hardware writes?
by on (#215213)
I'd like to try and learn how to make the nes stretch out a bg image. I've seen it done vertically to an image, I've also seen a wavy bg effect, really neat. But I have no clue as to how to start trying this on my own, what addresses to mess with, etc. Could I get some pointers/suggestions? Thanks!
Re: how do i go about performing bg tricks with hardware wri
by on (#215217)
These effect usualy involve writting to PPU adresses, $2006 and $2007. Sometimes you might want to also use $2005.
In my game, FamiDepth, wavy title screen is achieved by timed writes during hblank to said registers.
Keep in mind this kind of effects tend to hog the cpu....so it isn't used during gameplay very often.
Re: how do i go about performing bg tricks with hardware wri
by on (#215228)
It's generally a combination of mid-screen scroll changes (i.e $2005 and $2006 writes) and CHR-ROM bankswitching. To simulate the movement of a flag, for example, you need wavy motion in booth axes, and the most obvious way to do this is to use bankswitching for moving graphics up and down, and scroll changes for the horizontal motion.
Re: how do i go about performing bg tricks with hardware wri
by on (#215266)
Could I get a small example of how to accomplish this? This hblank is new to me, the only kinds of splits or fancy irqs I've worked with, we're for mappers MMC3 & MMC5. So I'd like to expand my knowledge on the console's end with performing these visual tricks.

I know $2005 is the x/y. So does this trick reposition every individual scanline, by what you put as the x/y, and loop back when the next scanline is present, altering that x,y as well? Am I in the right direction?

Thanks! :-)
Re: how do i go about performing bg tricks with hardware wri
by on (#215268)
oh, Tokumaru is right, I dont know why I said $2007, haha.
When hblank starts, the ppu updates t horizontal component of scrolling.
In FamiDepth, I change x position by writing to $2005 every scanline afterwhich I wait for a scanline to pass.
During cycle burning, I read $2002 to reset the write toggle.
Re: how do i go about performing bg tricks with hardware wri
by on (#215272)
Quote:
I know $2005 is the x/y. So does this trick reposition every individual scanline, by what you put as the x/y, and loop back when the next scanline is present, altering that x,y as well? Am I in the right direction?

yes that's the gist

infidelity wrote:
Could I get a small example of how to accomplish this?


Learn how to set both xscroll and yscroll mid frame: https://wiki.nesdev.com/w/index.php/PPU ... 2FY_scroll

To align the writes to hblank, it helps to use this library: viewtopic.php?t=6589

Set the scroll once every scanline to create the effects. Each scanline is 113.666 CPU cycles long, so you'll need to count out the cycles to make sure everything is in sync. To handle the fraction just alternate between doing two 114 cycle timings then one 113 cycle timing.

Here's the source to the flag effect I made but it might be hard to read: https://github.com/pubby/F--FF/blob/master/src/flag.s
Re: how do i go about performing bg tricks with hardware wri
by on (#215274)
For long time, I wanted to revise my wave code and you finally gave me a valid reason :D
https://github.com/denine/wavyscreendemo-NES

If you are interested in playing around with it, you'll need ASM6.
If you just want to to see wavecode, it is in wavecode.asm
I've included ROM as well for preview.
You can get more smooth effects if you alter paralaxtbl table. I tried to keep it simple, for better understanding.
For this demo, I used Nesdev logo, if there is a problem with that, I'll change it.

Take this demo with grain of salt, however, I didn't test it on hardware yet.
Re: how do i go about performing bg tricks with hardware wri
by on (#215276)
The main "catch" is that mid-screen vertical scroll changes via $2005 don't work. The vertical scroll will NOT change on the second write to $2005, so you have to use a more elaborate sequence of $2006/5/5/6 writes to fully set the X and Y scroll mid-screen.
Re: how do i go about performing bg tricks with hardware wri
by on (#215286)
Thanks everyone, I'll try to sift through all the notes and comments on how to accomplish this, then see what I'm able to try. Thank you all, I'll report back. :-)
Re: how do i go about performing bg tricks with hardware wri
by on (#215291)
The first thing you have to do is analyze how some of the effects you like were done. You need a good debugging emulator, like Mesen, where you can see the pattern and name tables, advance frame by frame, and see the PPU and mapper writes that are happening as the image is drawn (check out Mesen's event viewer!).

If you don't understand how the various basic tricks are done, it'll be hard for you to come up with interesting ways to combine them and create your own thing.
Re: how do i go about performing bg tricks with hardware wri
by on (#215360)
Never heard of Mesen. I've been using the FCEUX debugger since 2005, that's how all of my games and hacks have been accomplished since then. But I'll definitely check out what you suggested, because I am going into unknown territory (for me at least). :-)
Re: how do i go about performing bg tricks with hardware wri
by on (#215362)
FCEUX is great for debugging, but its accuracy leaves much to be desired. Mesen has all the same debugging features and more, and it's more accurate.
Re: how do i go about performing bg tricks with hardware wri
by on (#215375)
Yeah you're right regarding accuracy on the FCEUX. I've had to learn the hard way, that not everything will work the same across all other emus and original hardware, just because it runs on FCEUX. I now test my work on my NES via an Everdrive, or for my MMC5 projects, on a custom made famicom mmc5 cartridge. But before I even test anything on my NES, I run my work through Nestopia & Nintendulator. And now this Mesen you speak of, I'll definitely set time aside to try it out.
Re: how do i go about performing bg tricks with hardware wri
by on (#215419)
Here's some code I use for vertical scaling, the whole loop. temp_table is in RAM, a map of the scanlines to display. vram_addr_hi and vram_addr_lo are tables of the $2006 reg values, I could share those if it helps. I built those manually by watching the VRAM address in hblank in Nintendulator.

To do horizontal and vertical changes, if it still fits in hblank, you'd add that to the second $2005 write (it's backwards from normal because the 2-write sequence toggle is shared with $2006).

The ADC #$55 trick lets you spend .666 cycles (IIRC, loopy came up with that one).

Code:
                  ldy #0
   @scanline_loop:
                  lda temp_table,y            ; 4    4
                  tax                           ; 2    6
                  lda vram_addr_hi,x            ; 4    10
                  sta $2006                     ; 4    14
                  stx $2005                     ; 4    18
                  lda #0                        ; 2    20
                  sta $2005                     ; 4    24
                  lda vram_addr_lo,x            ; 4    28
                  sta $2006                     ; 4    32
                                                ;
                  lda irrational_counter        ; 3    35
                  clc                           ; 2    37
                  adc #$55                      ; 2    39
                  sta irrational_counter        ; 3    42
                  bcc @nowhere                  ; 2/3  44.6
   @nowhere:                                    ;
                                                ;
                  ldx #11                       ; x*5 + 1
   :                                            ;
                  dex                           ;
                  bne :-                        ;

                  nop
                  nop
                  nop
                                                ;
                                                ;
                  iny         
                  cpy #33 
                  bne @scanline_loop
Re: how do i go about performing bg tricks with hardware wri
by on (#215461)
pubby wrote:
To align the writes to hblank, it helps to use this library: http://forums.nesdev.com/viewtopic.php?t=6589


This is an amazing library that opens up even more possibilities: Doing almost-perfectly aligned writes anywhere in the screen. But IIRC it only works if you have constant cycles in your NMI before you start the effect. This isn't practical for most games.

And what's more, it's just way overkill for scrolling tricks, where an IRQ or sprite#0 hit will work just fine, as long as you make sure to align your writes and keep the number of instructions down.

Memblers wrote:
Here's some code I use for vertical scaling [...]


One tiny improvement on this code: I'd move the "lda vram_addr_lo,x" before the "sta $2005", as this should give you slightly more headroom if your writes aren't perfectly aligned.
(because first two writes to $2006/$2005 only affect the temporary latches, while the next two writes to $2005/$2006 do affect rendering output)

Memblers wrote:
The ADC #$55 trick lets you spend .666 cycles (IIRC, loopy came up with that one).


Indeed Loopy thought up that trick, and my variables are still called "_666" all around my code. "irrational_counter" is quite a neat neame though. ;)

But more importantly, Loopy's the one who figured out how to set any X/Y scrolling value, which was never done by any commercial games. It sure was exciting learning this could be done back when it was first discovered, opening up the NES to neat effects we only saw in the later SNES era. I always refer to this as "loopy scrolling" to give Loopy credit for it... and because it's also such a catchy name, whereas "2006/2005/2005/2006 write sequence" sounds way too dulll and technical. :D

And yes, do check out Mesen's new event viewer. It's an amazing tool for perfecting tricks like these.
Re: how do i go about performing bg tricks with hardware wri
by on (#215464)
.