Would it be possible to mod a NES to have that "Allow more than 8 sprites per scanline" feature from emulators?

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

User avatar
Controllerhead
Posts: 314
Joined: Tue Nov 13, 2018 4:58 am
Location: $4016
Contact:

Re: Would it be possible to mod a NES to have that "Allow more than 8 sprites per scanline" feature from emulators?

Post by Controllerhead »

tokumaru wrote: Mon Aug 31, 2020 3:50 pm You can probably write a Lua script in emulators that support that (FCEUX, Mesen) to get that information from $2002 and present it visually somehow.
Indeed you can! Here is some dodgy Lua code testing the notoriously unreliable sprite overflow flag.

I got you bro =)

Image
Attachments
testSpriteOverflow.zip
(615 Bytes) Downloaded 129 times
Image
User avatar
Quietust
Posts: 1920
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: Would it be possible to mod a NES to have that "Allow more than 8 sprites per scanline" feature from emulators?

Post by Quietust »

Controllerhead wrote: Thu Sep 03, 2020 3:55 pm Here is some dodgy Lua code testing the notoriously unreliable sprite overflow flag.

Image
Wouldn't that script also cause the VBLANK flag to get immediately cleared, or does emu.read(<addr>, 256) prevent side effects?
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
User avatar
Controllerhead
Posts: 314
Joined: Tue Nov 13, 2018 4:58 am
Location: $4016
Contact:

Re: Would it be possible to mod a NES to have that "Allow more than 8 sprites per scanline" feature from emulators?

Post by Controllerhead »

Quietust wrote: Thu Sep 03, 2020 6:51 pm does emu.read(<addr>, 256) prevent side effects?
Yes 256 is code for a "cpuDebug" read. No side effects. I am just reading the emulated value as opposed to a hardware style read.
https://www.mesen.ca/docs/apireference/ ... ml#memtype

I think the way that i am polling it after every instruction is dodgy AF. I can't think of a better way though. There is no event listener for internal register updates in the Lua API. CPU/PPU write event listeners for $2002 don't trigger it. There is also no eventType for spriteOverflow like there is for spriteZeroHit. Nothing else i fiddled with worked reliably... There could be a better way though.

At least i'm 100% sure that an instruction will happen before HBLANK is over every scanline ...it's a terrible solution :?
Image
Fiskbit
Posts: 891
Joined: Sat Nov 18, 2017 9:15 pm

Re: Would it be possible to mod a NES to have that "Allow more than 8 sprites per scanline" feature from emulators?

Post by Fiskbit »

You could probably execute 1 PPU cycle at a time and check sprite overflow after each step using emu.execute(count, type) with type ppuCycles and count 1.
User avatar
Controllerhead
Posts: 314
Joined: Tue Nov 13, 2018 4:58 am
Location: $4016
Contact:

Re: Would it be possible to mod a NES to have that "Allow more than 8 sprites per scanline" feature from emulators?

Post by Controllerhead »

Fiskbit wrote: Thu Sep 03, 2020 9:00 pm You could probably execute 1 PPU cycle at a time and check sprite overflow after each step using emu.execute(count, type) with type ppuCycles and count 1.
I could. That would be slower than what i'm doing currently... But, if you wanted exact pixel accuracy on when spriteOverflow fires instead of scanline accuracy, that would be the way to go.

Optimally it would be nice if i could just listen for a $2002 change in the API, or at the very least, sync it up to HBLANK so i could listen for spriteOverflow 240 times a frame instead of the slightly over 9000 or so instructions that probably fire. I'm sure that could be done... but it runs fine the way it is. Meh.

Anyway, i'm sure this enough of a demo to get OP moving in the right direction in his quest to discover that rendering more than 8 sprites per scanline on hardware is physically impossible. I'm happy to lend a helping hand =)
Image
Nix
Posts: 12
Joined: Wed Aug 26, 2020 12:22 pm

Re: Would it be possible to mod a NES to have that "Allow more than 8 sprites per scanline" feature from emulators?

Post by Nix »

@Controllerhead: I finally got around to testing the lua script you provided and it works nicely! Thanks for that.

It works fine in Mesen, but if I try to load it in BizHawk, I get this error:
"NLua.Exceptions.LuaScriptException: [string "main"]:14: unexpected symbol near '&'"

Could you possibly provide a version that works there?
User avatar
Controllerhead
Posts: 314
Joined: Tue Nov 13, 2018 4:58 am
Location: $4016
Contact:

Re: Would it be possible to mod a NES to have that "Allow more than 8 sprites per scanline" feature from emulators?

Post by Controllerhead »

Nix wrote: Sat Sep 12, 2020 9:00 am the lua script you provided and it works nicely! Thanks for that.
Awesome!
Nix wrote: Sat Sep 12, 2020 9:00 am Could you possibly provide a version that works (in BizHawk)?
No. Sorry =(

I am using the Mesen specific Lua API to make that script work. I have never used bizhawk. The code is only 30 lines long though; it might be possible to port? You can check to see if there are similar API functions in Bizhawk. You're on your own for that.

Next time, instead of just writing "@" just quote/tag names in your post. I didn't see this until a month later.

Good luck!
Image
Nix
Posts: 12
Joined: Wed Aug 26, 2020 12:22 pm

Re: Would it be possible to mod a NES to have that "Allow more than 8 sprites per scanline" feature from emulators?

Post by Nix »

Controllerhead wrote: Mon Oct 05, 2020 11:48 pm No. Sorry =(

I am using the Mesen specific Lua API to make that script work. I have never used bizhawk. The code is only 30 lines long though; it might be possible to port? You can check to see if there are similar API functions in Bizhawk. You're on your own for that.

Next time, instead of just writing "@" just quote/tag names in your post. I didn't see this until a month later.

Good luck!
No worries. Well, I'm not sure how I'd go about that myself as I've never coded any LUA script before, but I can try.

I have a different question now. You know, the LUA works fine and all but it detects any kind of sprite overflow, without being able to tell general overflows apart from those that are being used to achieve masking effects. Can you make another LUA (for Mesen) specifically for detecting masking effects? I mean like those used in games like Simon's Quest, Zelda 1, Gimmick and such. This would help me finding more games that make use of this particular quirk (for documentation purposes).

To give an idea on how to code this script, looking into the Mesen code below might help:
https://github.com/SourMesen/Mesen/comm ... 1ae818464c
User avatar
Controllerhead
Posts: 314
Joined: Tue Nov 13, 2018 4:58 am
Location: $4016
Contact:

Re: Would it be possible to mod a NES to have that "Allow more than 8 sprites per scanline" feature from emulators?

Post by Controllerhead »

Nix wrote: Tue Oct 06, 2020 11:41 am You know, the LUA works fine and all but it detects any kind of sprite overflow, without being able to tell general overflows apart from those that are being used to achieve masking effects.
It only detects what scanline the sprite overflow flag was set and draws it. The flag itself is prone to failure. In fact, it can trigger when there are exactly 8 sprites, and fail in other cases. The wiki describes this.
https://wiki.nesdev.com/w/index.php/PPU ... erflow_bug
Nix wrote: Tue Oct 06, 2020 11:41 am Can you make another LUA (for Mesen) specifically for detecting masking effects? I mean like those used in games like Simon's Quest, Zelda 1, Gimmick and such. This would help me finding more games that make use of this particular quirk (for documentation purposes).

To give an idea on how to code this script, looking into the Mesen code below might help:
https://github.com/SourMesen/Mesen/comm ... 1ae818464c
No, sorry =(

Thanks for the example, but, I have no idea what this code is doing. I have no idea how you would even do that.
Image
Kitty_Space_Program
Posts: 53
Joined: Mon Sep 21, 2020 12:51 am

Re: Would it be possible to mod a NES to have that "Allow more than 8 sprites per scanline" feature from emulators?

Post by Kitty_Space_Program »

tokumaru wrote: Wed Aug 26, 2020 12:48 pm Keep in mind that some games rely on sprites beyond the 8th being dropped for achieving certain visual effects.
What games use that? I’m kinda curious to see how it looks.
Bavi_H
Posts: 193
Joined: Sun Mar 03, 2013 1:52 am
Location: Texas, USA
Contact:

Re: Would it be possible to mod a NES to have that "Allow more than 8 sprites per scanline" feature from emulators?

Post by Bavi_H »

Kitty_Space_Program wrote: Wed Oct 07, 2020 7:01 am What games use that? I’m kinda curious to see how it looks.
Nesdev Wiki Sprite overflow games - Use of excess sprites for masking effects

Nix wrote: Tue Oct 06, 2020 11:41 am Can you make another LUA (for Mesen) specifically for detecting masking effects? [...]
To give an idea on how to code this script, looking into the Mesen code below might help:
https://github.com/SourMesen/Mesen/comm ... 1ae818464c
Controllerhead wrote: Tue Oct 06, 2020 12:18 pm Thanks for the example, but, I have no idea what this code is doing. I have no idea how you would even do that.
For clarity, here is the most recent version of that code: Mesen github PPU.cpp - LoadExtraSprites(). This code appears to implement Mesen's first two "Advanced Video" options:
Remove sprite limit: The NES can normally only draw up to 8 sprites per line – this limitation is indirectly responsible for some of the flickering seen in games at times. When this option is enabled, the limit is disabled, allowing up to 64 sprites to be drawn on the same line.

Automatically re-enable sprite limit as needed to prevent graphical glitches when possible: Some games rely on the sprite limit to hide objects from view. These games will have graphical glitches when the Remove sprite limit option is enabled. By enabling this option, Mesen will try to detect when games are attempting to hit the sprite limit on purpose and temporarely re-enable the limit in these specific cases. This option is not perfect and may not work in certain games, but it helps reduce the potential negative impacts of the Remove sprite limit option.

The Nesdev wiki suggests detecting intentional masking as follows (Sprite overflow games - Detecting masking effects):
Games will place 8 consecutive sprites with the same Y coordinate and same tile number. If you see this, then that is a sign that the game is using a masking effect, and the 8-sprite limit should be enforced for that area.
However, Mesen appears to not care about the tile number but does care about the X coordinate. That is, reading over the code above, Mesen appears to be detecting intentional masking as follows:
Out of the sprites that have tile boxes on this scanline, if there are 8 or more consecutive sprites with the same Y coordinate and the same X coordinate, then the masking is intentional.

Mesen has a built-in script that draws various sprite information on the screen:
Debug menu -> Script Window, then File menu -> Built-in Scripts -> SpriteBox.lua

In comparison to Controllerhead's script which looks at the sprite overflow flag, this script manually calculates overflow: any scanline where more than 8 sprites are set to appear is shown with a red line on the left margin.

Using this script as a base, I modified and simplified the code to just show lines where intentional sprite masking is detected. Lines are tinted yellow if 8 dummy sprites are detected, and tinted red if additional sprites are actually being masked. I used Mesen's detection method by default (same Y position and X position), but you can comment that line out out and un-comment the line below it to use the wiki's detection method (same Y position and tile ID).

Other helpful things I used while investigating this:

Mesen has a sprite viewer: Debug menu -> PPU Viewer, then go to the Sprite Viewer tab
Documentation about the sprite memory: Nesdev Wiki PPU OAM page
Attachments
intentional-sprite-masking.zip
(976 Bytes) Downloaded 118 times
Post Reply