Tech demo: Real-time sprite scaling

A place where you can keep others updated about your NES-related projects through screenshots, videos or information in general.

Moderator: Moderators

Post Reply
tepples
Posts: 22162
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Tech demo: Real-time sprite scaling

Post by tepples » Sun Nov 23, 2014 1:43 pm

Sprite scaling wasn't a hardware feature of the NES or most other 2D consoles until the Super FX coprocessor and Game Boy Advance PPU. It was on the Neo Geo AES, but that's about it. But that doesn't mean there isn't a reasonably efficient way to shrink sprites in software. I got the idea from a post by psycopathicteen to look up each byte of the tile through a lookup table that shrinks a bit plane. The Sega Master System/Game Gear has to do something similar just to flip sprites; on that platform, sprite scaling would be effectively free.

Up and Down control size; Left and Right step through frames.
Attachments
scaling-wip.zip
(24.59 KiB) Downloaded 860 times

User avatar
Diskover
Posts: 213
Joined: Thu Nov 24, 2011 7:16 am
Contact:

Re: Tech demo: Real-time sprite scaling

Post by Diskover » Mon Dec 01, 2014 5:01 am

Wow :shock:

User avatar
Bregalad
Posts: 7993
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Re: Tech demo: Real-time sprite scaling

Post by Bregalad » Mon Dec 01, 2014 12:10 pm

I have no idea how you managed to make it this fast, but it's impressive. Back when I tried to roto-scale an image on the NES it was extremely hard to do and very slow.

Why do you have a fetish for legless people recently ? I find personally this is kinda ugly but this doesn't matter for the demo.

tomaitheous
Posts: 592
Joined: Thu Aug 28, 2008 1:17 am
Contact:

Re: Tech demo: Real-time sprite scaling

Post by tomaitheous » Mon Dec 01, 2014 3:39 pm

Nice work!

I did some simple scaling on the PCE for a title screen (replicating the Lunar SegaCD title screen), but I used packed pixel scaling and then converted to planar in realtime. It was slow, but fast enough for title screen stuffs.

This LUT method works out pretty decent. I ran some numbers of some quick code (more PCE geared) after seeing this, and along with a special WORD element shift table, I was able to drastically cut down the number of cycles compared to my old code.

Anyway, stuff like this would have been nice to see back in the day. Relatively easy to use and would be great for non cpu intensive parts in games; more than just demo scene stuff.

Got any ideas for rotation of planar graphics?
Last edited by tomaitheous on Mon Dec 01, 2014 5:34 pm, edited 1 time in total.
__________________________
http://pcedev.wordpress.com

tepples
Posts: 22162
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Tech demo: Real-time sprite scaling

Post by tepples » Mon Dec 01, 2014 4:54 pm

Bregalad wrote:I have no idea how you managed to make it this fast, but it's impressive. Back when I tried to roto-scale an image on the NES it was extremely hard to do and very slow.
That's because you tried rotation at the same time. Rotation is slow, but Neo Geo scaling is fast on NES. I precompute each 8x1 pixel strip scaled down to widths 7, 6, 5, and 4, and then I apply that to each bitplane. It's actually limited more by vblank time than by anything else.
tomaitheous wrote:Got any ideas for rotation of planar graphics?
Did you have a chance to look at my topic about shearing?

Discussion about the appearance of the character in the demo can go here or here.

tomaitheous
Posts: 592
Joined: Thu Aug 28, 2008 1:17 am
Contact:

Re: Tech demo: Real-time sprite scaling

Post by tomaitheous » Mon Dec 01, 2014 7:56 pm

I took a second look at this. Ok, so you avoid shifting and ORing the 8 pixel down scaled segments by using sprite positions to compensate for this (horizontally)? I thought it was a more brute force method. Also, why stop at 50% shrink?

The method I was doing required a shift table with 8 positions (split table with LSB/MSB) for ORing the WORD (shifted BYTE) with the data buffer together. The 8pixel planar value (byte) was loaded directly into X and used to access a the shift table (ldy idx ; ldx 8pixel_data,y ; ldy scale,x ; ora shift.lsb,y ; etc),. The shift table is kinda big (4k), with MSB of the table address (both tables) using the offset value from a counter for quick dirty addressing. And a little bit of self modifying code to shave a few cycles. It doesn't save a whole lot of cycles, compared to doing a 4bit (byte expanded) linear scale and then converting planar afterwards (4bit planar). But for NES 2bit planar format, it'd probably be decent enough in savings. Still not as quick as this sprite offset method you have here, but would lend itself to background rendering.
__________________________
http://pcedev.wordpress.com

tepples
Posts: 22162
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Tech demo: Real-time sprite scaling

Post by tepples » Mon Dec 01, 2014 8:06 pm

tomaitheous wrote:Ok, so you avoid shifting and ORing the 8 pixel down scaled segments by using sprite positions to compensate for this (horizontally)? I thought it was a more brute force method.
For Super NES, you'll need to use a bit more force by shifting the right half of each 16-pixel-wide unit by a power of 2 to the left. The memory-mapped multiplier should work fine for this: store the shift amount ($01, $02, $04, $08, or $10) in $4202 before starting, then store the (scaled) right half of each 16x1 sliver the sprite into $4203, scale the left half, and read the shifted right half out of $4216. For an architecture without a multiplier, you might have to use a self-modifying shiftslide for this part.
Also, why stop at 50% shrink?
Because at that point you need to drop down to the next smaller prescaled step in your mipmap so as to avoid excessive overdraw.
[My own technique was] Still not as quick as this sprite offset method you have here, but would lend itself to background rendering.
Know what else would lend itself to background rendering, at least on Super NES? Mode 7.

tomaitheous
Posts: 592
Joined: Thu Aug 28, 2008 1:17 am
Contact:

Re: Tech demo: Real-time sprite scaling

Post by tomaitheous » Mon Dec 01, 2014 11:54 pm

Meh - mode 7. It takes the fun out of everything :P
__________________________
http://pcedev.wordpress.com

User avatar
Bregalad
Posts: 7993
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Re: Tech demo: Real-time sprite scaling

Post by Bregalad » Tue Dec 02, 2014 11:49 am

Tepples I understand how you can use lookup tables for this but I see two major drawbacks :

1) This requires a lot of lookup tables, or, it can only shrink to very few scales
2) This does not work for vertical shrinking
3) There is no way you can expand sprites this way

Nevertheless it's still awesomely simple, I can't believe no game ever used this technique when it was so simple. This would also apply on SNES or any other 2d console without sprite scaling capabilities but bitplane based graphics.

This technique could/should also be used to do other effects to sprites, for example mosaic.

tomaitheous
Posts: 592
Joined: Thu Aug 28, 2008 1:17 am
Contact:

Re: Tech demo: Real-time sprite scaling

Post by tomaitheous » Tue Dec 02, 2014 4:39 pm

The SNES could easily make due with a slower routine, and just cache the frames to WRAM (128k is a nice chunk) for whatever level/area.
__________________________
http://pcedev.wordpress.com

tepples
Posts: 22162
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Tech demo: Real-time sprite scaling

Post by tepples » Tue Dec 02, 2014 5:19 pm

Bregalad wrote:I see two major drawbacks :

1) This requires a lot of lookup tables, or, it can only shrink to very few scales
You really just need tables for 8 (identity), 7, 6, 5, and 4, after which you jump down to the next size and use the 8, 7, 6, 5, 4 table on that.
2) This does not work for vertical shrinking
Of course it does. After each row I copy, I add between 0/256 and 255/256 rows to the skip variable, skipping a row when it overflows.
3) There is no way you can expand sprites this way
Or on a Neo Geo. (And that's three ;-) )

Sik
Posts: 1589
Joined: Thu Aug 12, 2010 3:43 am

Re: Tech demo: Real-time sprite scaling

Post by Sik » Sat Dec 06, 2014 7:52 pm

tepples wrote:You really just need tables for 8 (identity), 7, 6, 5, and 4, after which you jump down to the next size and use the 8, 7, 6, 5, 4 table on that.
Can't you drop the 4 as well? (since 4 in the current size would be the same as 8 in the next size)

User avatar
Dwedit
Posts: 4367
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: Tech demo: Real-time sprite scaling

Post by Dwedit » Sun Dec 07, 2014 1:35 pm

Do you really need a table for identity? It's identity, nothing is changing.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!

tepples
Posts: 22162
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Tech demo: Real-time sprite scaling

Post by tepples » Sun Dec 07, 2014 4:45 pm

Dwedit wrote:Do you really need a table for identity? It's identity, nothing is changing.
That or a second loop for not using a table at all. Also yes.

Post Reply