It is currently Tue Dec 12, 2017 11:02 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Sun Aug 13, 2017 4:32 am 
Offline
Formerly WheelInventor

Joined: Thu Apr 14, 2016 2:55 am
Posts: 1124
Location: Gothenburg, Sweden
I went a bit overboard and got greedy with using sprites for the screen filling logo experiment.

Once i've fixed a few minor mistakes (there's currently 9 sprites on 3 of the rows), it'll be at 118 to 119 sprites on screen at the same time; overtracing the 64 limit almost by a power of 2.

This means the project got a little bigger than i originally had in mind. Now i must multiplex the sprites (early gen console style), which specifically means timed animation of sprite position and tile reference during the draw of one screen.

Before i dig into it - Am i correct if
-Sprite tile animation and position updates would need to happen during hblank

And
-Is there a shorthand answer if this is even viable?

I essentially have a time buffer of 64 scanlines before the scanner hits the next set of 'virtual' / multiplexed sprites, but it can't begin until at least a row (8 scanlines) have passed so i don't move sprites prior to them being rendered. Since the total amount of sprites is less than a power of 2, there's fewer upates to be made halfway down the screen. Attaching a sprite count list.

I can of course reset sprites back to the initial setting during vblank.

Code:
Row   Spritecount
1   8
2   7
3   7
4   5
5   9 (needs a fix, cap at 8)
6   8
7   8
8   8
9   6-7 (depending on a choice)
10   6
11   9 (needs a fix, cap at 8)
12   7
13   9 (needs a fix, cap at 8)
14   8
15   7
16   4
17   3
18   2

_________________
http://www.frankengraphics.com - personal NES blog


Top
 Profile  
 
PostPosted: Sun Aug 13, 2017 4:45 am 
Online

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19335
Location: NE Indiana, USA (NTSC)
Uploading a new display list to OAM must take place while rendering is off, which means a blank bar across the screen at least five scanlines in height. I think Bigfoot does this, but not much else.


Top
 Profile  
 
PostPosted: Sun Aug 13, 2017 5:00 am 
Offline
Formerly WheelInventor

Joined: Thu Apr 14, 2016 2:55 am
Posts: 1124
Location: Gothenburg, Sweden
That's using OAMDMA, right?

I was thinking using unrolled lda/sta (even if it takes longer) to do partial/finely sliced updates. If completely unrolled, i'd also have access to deciding what bytes go where. Since i've taken care to align most sprites to an 8-pixel grid, sometimes i just need to change y position, most often also tile reference, but not always. Sometimes, there's still need for changing x position, and palette. Ideally, i'd reassign one sprite to change into the next 'virtual' sprite with the same x position and possibly (second priority) what other property that might stay the same: subpalette and/or tile number.

My aim is to do this 'clean', but this illegal opcode looks interesting (quoting this nesdev wiki article):

AXS #i ($CB ii, 2 cycles)
Sets X to {(A AND X) - #value without borrow}, and updates NZC. One might use TXA AXS #-element_size to iterate through an array of structures or other elements larger than a byte, where the 6502 architecture usually prefers a structure of arrays. For example, TXA AXS #$FC could step to the next OAM entry or to the next APU channel, saving one byte and four cycles over four INXs. Also called SBX.

_________________
http://www.frankengraphics.com - personal NES blog


Top
 Profile  
 
PostPosted: Sun Aug 13, 2017 5:26 am 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2982
Location: Tampere, Finland
It doesn't work, even with LDA/STA. PPU is constantly accessing OAM during rendering scanlines, even during hblank (it's preparing for the next scanline).

See http://wiki.nesdev.com/w/index.php/PPU_ ... evaluation.

Just as a quick test, I fed your image to NES Image Converter 2, and while the result did lose some detail, I think it came out quite nice. So I think you should be fine without extra sprites. This tool in particular uses 16x8 attribute areas and 8x16 sprite overlays. (It tries to intelligently decide how to allocate the attributes and where sprites are needed the most. Sometimes it succeeds, sometimes it doesn't.)

BTW, I really like how the image looks with NTSC filter!

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Top
 Profile  
 
PostPosted: Sun Aug 13, 2017 5:38 am 
Offline
Formerly WheelInventor

Joined: Thu Apr 14, 2016 2:55 am
Posts: 1124
Location: Gothenburg, Sweden
Hm. That's a nice idea! Using a different attribute grid (even though that 'breaks' the frame for the original experiment; running this 'vanilla' on something like UNROM) should be able to lower the need for sprites considerably without any visually noticable sacrifices. Thanks! Sprite mode is a tough one. Slicing amount of sprites vs hogging sprite per scanline bandwidth in unnecessary places...

Also thanks for the clarification on how sprite evaluation works.


Tepples, your hint on how bigfoot does it might be of use for another theme / still image. Thanks!

_________________
http://www.frankengraphics.com - personal NES blog


Top
 Profile  
 
PostPosted: Sun Aug 13, 2017 6:09 am 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2982
Location: Tampere, Finland
FrankenGraphics wrote:
(even though that 'breaks' the frame for the original experiment; running this 'vanilla' on something like UNROM)

16x8 attributes can be done on UNROM (or even NROM) with timed code by switching between two nametables (with identical tile indices, but differing attribute tables) every 8 scanlines. Of course this hogs all the CPU time.

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Top
 Profile  
 
PostPosted: Sun Aug 13, 2017 6:19 am 
Offline
Formerly WheelInventor

Joined: Thu Apr 14, 2016 2:55 am
Posts: 1124
Location: Gothenburg, Sweden
It's interesting to see how your nes converters' idea of how palette and sprite data should be organized differs from mine. I could probably learn a thing or two studying it.

It's like you said; pretty well working! I could perhaps take it from there and edit the name table /pattern table where it got a little too mangled and assume your solution for handling it in code, if you don't mind me trying.

Edit: I also wonder how your converter handles sprite generation (so that i can hand edit the output optimally). For instance, the top line used for highlights were drawn at the bottom of a sprite tile to let it not interfere with scanlines directly below it. This doesn't seem to be the case in the converter. Does it iterate solutions and select the best for minimal scanline interference/max coverage (for example testing different offsets on where to begin, like NESST does for its new nametable import), or are the priorities different?
I could probably trick it by placing a same-coloured pixel as a reference point any distance above the first sprite line.


Attachments:
File comment: Composition of sprites and bg
thefoxconverter_layercomposition.png
thefoxconverter_layercomposition.png [ 7.34 KiB | Viewed 955 times ]
File comment: just sprites
thefoxconverter_sprlayer.png
thefoxconverter_sprlayer.png [ 2.84 KiB | Viewed 957 times ]
File comment: just background
thefoxconverter_bglayer.png
thefoxconverter_bglayer.png [ 6.81 KiB | Viewed 957 times ]

_________________
http://www.frankengraphics.com - personal NES blog
Top
 Profile  
 
PostPosted: Sun Aug 13, 2017 9:48 am 
Offline
Formerly WheelInventor

Joined: Thu Apr 14, 2016 2:55 am
Posts: 1124
Location: Gothenburg, Sweden
Trying to coax the converter to do my bidding... (if that sounds demonic, well, it's DOOM) by feeding it slight changes to trig/untrig decisions being made. A few turns at it and i got pretty satisfied with the output. Just a bit of brushing up to do, and learning how to do 16x8 attributes. Your tools probably just saved me a couple of hours.


Attachments:
rathergoodspr.png
rathergoodspr.png [ 2.25 KiB | Viewed 908 times ]
rathergood_bg.png
rathergood_bg.png [ 6.79 KiB | Viewed 908 times ]
rathergood.png
rathergood.png [ 7.1 KiB | Viewed 908 times ]

_________________
http://www.frankengraphics.com - personal NES blog
Top
 Profile  
 
PostPosted: Sun Aug 13, 2017 10:13 am 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2982
Location: Tampere, Finland
FrankenGraphics wrote:
Edit: I also wonder how your converter handles sprite generation (so that i can hand edit the output optimally). For instance, the top line used for highlights were drawn at the bottom of a sprite tile to let it not interfere with scanlines directly below it. This doesn't seem to be the case in the converter. Does it iterate solutions and select the best for minimal scanline interference/max coverage (for example testing different offsets on where to begin, like NESST does for its new nametable import), or are the priorities different?
I could probably trick it by placing a same-coloured pixel as a reference point any distance above the first sprite line.

I can't remember the exact details about what it does, but yeah at least coverage was one part of it. Probably it just greedily selects the sprite that minimizes error in the output (as long as it doesn't break the 8 sprites per scanline rule), and repeats this 64 times. The sprites are always placed on an 8x16 grid (arbitrary placement is a much more difficult problem).

BTW, you can right click the toolbar in the converter to display a few debug windows. (Hover over the images in the Debug Images window to see a tooltip explaining what each one of them shows.)

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Top
 Profile  
 
PostPosted: Sun Aug 13, 2017 10:23 am 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6509
Location: Seattle
... Ok, ridiculous question. Would the timing work out such that one could disable rendering, rely on OAMADDR being 0, write 1 to 4 bytes to OAMDATA to change sprite 0, and re-enable rendering? Only being able to multiplex one sprite isn't great, but ...


Top
 Profile  
 
PostPosted: Sun Aug 13, 2017 11:02 am 
Offline
Formerly WheelInventor

Joined: Thu Apr 14, 2016 2:55 am
Posts: 1124
Location: Gothenburg, Sweden
If it works, the greatness would depend a bit on how many times you would be able to multiplex it. If it's as good as per scanline, you might be able replace more than just one sprite with sprite 0 on a per 8px-row basis, depending the density of their content not overlapping.

The bright dotted lines in the picture example posted above (rathergoodspr.png) could be rearranged to interfere as little as possible on a sliver basis, maybe realistically letting a per scanline-changing sprite 0 cover up to 3 or rarely even 4 such sprites in a single row.



Here's another question that's ridiculous:
Has anyone tried writing to PPUCTRL to switch sprite mode mid-screen? This project *does* have pattern space to waste to accomodate both modes for one screen. The gain would be less rigid placement where needed, sprite conservation otherwise.

_________________
http://www.frankengraphics.com - personal NES blog


Top
 Profile  
 
PostPosted: Sun Aug 13, 2017 12:35 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6509
Location: Seattle
I'm pretty certain that disabling rendering to upload a byte to OAM—if it works at all—would still impose a dead band of one scanline.

On the other hand, I'm about 99% confident that switching sprite height mid-render would work fine. On every scanline, OAM evaluation has to evaluate the difference of OAM[n*4] and the current scanline to establish both whether the sprite is in range and what scanline of the sprite to draw ... and switching between 16 row and 8 row is just a matter of whether the number is allowed to differ by 0-7 or 0-15.

It looks to me like the logic that determines this in Visual2C02 is specifically node 1052, because that node is grounded when both node 1036 is high and sprite_size_out is low. (Also if any of nodes 5853, 5839, 5800, 5801, 5802, 5803 are high.


Top
 Profile  
 
PostPosted: Mon Aug 14, 2017 3:04 am 
Offline
Formerly WheelInventor

Joined: Thu Apr 14, 2016 2:55 am
Posts: 1124
Location: Gothenburg, Sweden
Just before i try making something overly complex just like that, can someone remedy my confusion as to which of the two "B" cases is true?

Three examples of nine scanline intersecting 8x16 sprites.
#1 to #8 have high (H) priority and will always be shown.
#9 has low (L) priority and will always be canceled.
R is for row, C is for spriteCount.


Attachments:
8x16spritecancel.bmp
8x16spritecancel.bmp [ 30.12 KiB | Viewed 785 times ]

_________________
http://www.frankengraphics.com - personal NES blog
Top
 Profile  
 
PostPosted: Mon Aug 14, 2017 4:38 am 
Online
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10164
Location: Rio de Janeiro - Brazil
B1 is true. It all happens on a per-scanline basis, it doesn't matter where sprites start or end, every scanline the PPU scans all 64 sprites and picks the ones with the highest priorities for displaying.


Top
 Profile  
 
PostPosted: Mon Aug 14, 2017 7:27 am 
Offline
Formerly WheelInventor

Joined: Thu Apr 14, 2016 2:55 am
Posts: 1124
Location: Gothenburg, Sweden
Thanks, that's super helpful, especially in this case.

Updated the infographic, for future reference


Attachments:
8x16spritecancel.bmp
8x16spritecancel.bmp [ 30.12 KiB | Viewed 733 times ]

_________________
http://www.frankengraphics.com - personal NES blog
Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: qfwfq and 7 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group