Rotating BIG sprites

Discussion of hardware and software development for Super NES and Super Famicom. See the SNESdev wiki for more information.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
psycopathicteen
Posts: 3140
Joined: Wed May 19, 2010 6:12 pm

Rotating BIG sprites

Post by psycopathicteen »

My current sprite rotation engine fills up the RAM with rotation steps. Obviously this limits the size of the rotating sprites, so I'm thinking of an alternative for larger sprites.

My idea is to pre-rotate the sprite to only 16 angles (which doubles to 32 angles when flipped) and smoothing the rotation by doing something similar to offset-per-tile mode, only being applied to sprites, and being done through software. First it will shift columns of 8x8 cells vertically, then it will shift lines of pixels horizontally.
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Rotating BIG sprites

Post by tepples »

psycopathicteen wrote:My idea is to pre-rotate the sprite to only 16 angles (which doubles to 32 angles when flipped) and smoothing the rotation by doing something similar to offset-per-tile mode, only being applied to sprites, and being done through software. First it will shift columns of 8x8 cells vertically, then it will shift lines of pixels horizontally.
So something like this sprite shearing technique?
psycopathicteen
Posts: 3140
Joined: Wed May 19, 2010 6:12 pm

Re: Rotating BIG sprites

Post by psycopathicteen »

tepples wrote:
psycopathicteen wrote:My idea is to pre-rotate the sprite to only 16 angles (which doubles to 32 angles when flipped) and smoothing the rotation by doing something similar to offset-per-tile mode, only being applied to sprites, and being done through software. First it will shift columns of 8x8 cells vertically, then it will shift lines of pixels horizontally.
So something like this sprite shearing technique?
Pretty much, except the shearing would be done through software.

One thing I'd need to change about my engine is something I think Khan mentioned in a thread about animation. He once mentioned about using a bit to signal when an animation needs to be updated, as opposed to comparing numbers. Instead of having to compare 2 metasprite data address registers, 2 graphics address registers, and now a flag to mark if the graphics at that particular address happened to change, it makes sense to just have a flag that declares if the metasprite was changed in general.
psycopathicteen
Posts: 3140
Joined: Wed May 19, 2010 6:12 pm

Re: Rotating BIG sprites

Post by psycopathicteen »

I think I'll arrange the "unshifted" version of the sprites in a slightly different format. All 4 planar bytes would be stored together, and the 8x1 slivers would be stored from left to right, top to bottom. The sprites would be padded 4 lines of pixels on top and bottom with blank pixels in order to not have boundary crossing problems. So here is some code to copy a column of pixels.

Code: Select all

-;
lda $0000,x
sta $0000,y
lda $0002,x
sta $0010,y

lda $0020,x
sta $0002,y
lda $0022,x
sta $0012,y

lda $0040,x
sta $0004,y
lda $0042,x
sta $0014,y

lda $0060,x
sta $0006,y
lda $0062,x
sta $0016,y

lda $0080,x
sta $0008,y
lda $0082,x
sta $0018,y

lda $00a0,x
sta $000a,y
lda $00a2,x
sta $001a,y

lda $00c0,x
sta $000c,y
lda $00c2,x
sta $001c,y

lda $00e0,x
sta $000e,y
lda $00e2,x
sta $001e,y

txa
clc
adc #$0100
tax
tya
clc
adc #$0100
tay
dec {temp}
bne -
psycopathicteen
Posts: 3140
Joined: Wed May 19, 2010 6:12 pm

Re: Rotating BIG sprites

Post by psycopathicteen »

Okay, now I have working code for tilting a 64x64 sprite.

Code: Select all

big_sprite_rotation:
phb
lda #$7e7e
pha
plb
plb

ldy #$0000
sty {temp4}
sty {temp3}

lda #$0008
clc
adc {shift_factor}	//shift factor is between -8 and 7
asl #2
sta {temp2}


-;
and #$0038
asl #2
clc
adc {temp3}
tax
jsr copy_collumn
lda {temp4}
clc
adc #$0020
sta {temp4}
tay
lda {temp3}
clc
adc #$0004
sta {temp3}
cmp #$0020
beq +

lda {temp2}
sec
sbc {shift_factor}
sta {temp2}
bra -
+;



ldx #$0000
lda {shift_factor}
asl #5
sta {temp}
-;
lda {temp}
lsr #6
sep #$20
cmp #$00
beq ++
bpl +
jsr shift_pixels_left
bra ++
+;
jsr shift_pixels_right
+;
rep #$20
lda {temp}
sec
sbc {shift_factor}
sta {temp}
inx
inx
txa
and #$001f
cmp #$0010
bne -
txa
clc
adc #$00f0
tax
cpx #$0800
beq +
jmp -
+;

plb
rts







copy_collumn:
lda #$0008
sta {temp}
-;
lda {rotating_sprite}+$0000,x
sta {rotating_sprite_buffer}+$0000,y
lda {rotating_sprite}+$0002,x
sta {rotating_sprite_buffer}+$0010,y

lda {rotating_sprite}+$0020,x
sta {rotating_sprite_buffer}+$0002,y
lda {rotating_sprite}+$0022,x
sta {rotating_sprite_buffer}+$0012,y

lda {rotating_sprite}+$0040,x
sta {rotating_sprite_buffer}+$0004,y
lda {rotating_sprite}+$0042,x
sta {rotating_sprite_buffer}+$0014,y

lda {rotating_sprite}+$0060,x
sta {rotating_sprite_buffer}+$0006,y
lda {rotating_sprite}+$0062,x
sta {rotating_sprite_buffer}+$0016,y

lda {rotating_sprite}+$0080,x
sta {rotating_sprite_buffer}+$0008,y
lda {rotating_sprite}+$0082,x
sta {rotating_sprite_buffer}+$0018,y

lda {rotating_sprite}+$00a0,x
sta {rotating_sprite_buffer}+$000a,y
lda {rotating_sprite}+$00a2,x
sta {rotating_sprite_buffer}+$001a,y

lda {rotating_sprite}+$00c0,x
sta {rotating_sprite_buffer}+$000c,y
lda {rotating_sprite}+$00c2,x
sta {rotating_sprite_buffer}+$001c,y

lda {rotating_sprite}+$00e0,x
sta {rotating_sprite_buffer}+$000e,y
lda {rotating_sprite}+$00e2,x
sta {rotating_sprite_buffer}+$001e,y

txa
clc
adc #$0100
tax
tya
clc
adc #$0100
tay
dec {temp}
beq +
jmp -
+;
rts


shift_pixels_right:
-;
pha
lsr {rotating_sprite_buffer}+$0000,x
ror {rotating_sprite_buffer}+$0020,x
ror {rotating_sprite_buffer}+$0040,x
ror {rotating_sprite_buffer}+$0060,x
ror {rotating_sprite_buffer}+$0080,x
ror {rotating_sprite_buffer}+$00a0,x
ror {rotating_sprite_buffer}+$00c0,x
ror {rotating_sprite_buffer}+$00e0,x

lsr {rotating_sprite_buffer}+$0001,x
ror {rotating_sprite_buffer}+$0021,x
ror {rotating_sprite_buffer}+$0041,x
ror {rotating_sprite_buffer}+$0061,x
ror {rotating_sprite_buffer}+$0081,x
ror {rotating_sprite_buffer}+$00a1,x
ror {rotating_sprite_buffer}+$00c1,x
ror {rotating_sprite_buffer}+$00e1,x

lsr {rotating_sprite_buffer}+$0010,x
ror {rotating_sprite_buffer}+$0030,x
ror {rotating_sprite_buffer}+$0050,x
ror {rotating_sprite_buffer}+$0070,x
ror {rotating_sprite_buffer}+$0090,x
ror {rotating_sprite_buffer}+$00b0,x
ror {rotating_sprite_buffer}+$00d0,x
ror {rotating_sprite_buffer}+$00f0,x

lsr {rotating_sprite_buffer}+$0011,x
ror {rotating_sprite_buffer}+$0031,x
ror {rotating_sprite_buffer}+$0051,x
ror {rotating_sprite_buffer}+$0071,x
ror {rotating_sprite_buffer}+$0091,x
ror {rotating_sprite_buffer}+$00b1,x
ror {rotating_sprite_buffer}+$00d1,x
ror {rotating_sprite_buffer}+$00f1,x
pla
dec
beq +
jmp -
+;

rts


shift_pixels_left:
-;
pha

asl {rotating_sprite_buffer}+$00e0,x
rol {rotating_sprite_buffer}+$00c0,x
rol {rotating_sprite_buffer}+$00a0,x
rol {rotating_sprite_buffer}+$0080,x
rol {rotating_sprite_buffer}+$0060,x
rol {rotating_sprite_buffer}+$0040,x
rol {rotating_sprite_buffer}+$0020,x
rol {rotating_sprite_buffer}+$0000,x

asl {rotating_sprite_buffer}+$00e1,x
rol {rotating_sprite_buffer}+$00c1,x
rol {rotating_sprite_buffer}+$00a1,x
rol {rotating_sprite_buffer}+$0081,x
rol {rotating_sprite_buffer}+$0061,x
rol {rotating_sprite_buffer}+$0041,x
rol {rotating_sprite_buffer}+$0021,x
rol {rotating_sprite_buffer}+$0001,x

asl {rotating_sprite_buffer}+$00f0,x
rol {rotating_sprite_buffer}+$00d0,x
rol {rotating_sprite_buffer}+$00b0,x
rol {rotating_sprite_buffer}+$0090,x
rol {rotating_sprite_buffer}+$0070,x
rol {rotating_sprite_buffer}+$0050,x
rol {rotating_sprite_buffer}+$0030,x
rol {rotating_sprite_buffer}+$0010,x

asl {rotating_sprite_buffer}+$00f1,x
rol {rotating_sprite_buffer}+$00d1,x
rol {rotating_sprite_buffer}+$00b1,x
rol {rotating_sprite_buffer}+$0091,x
rol {rotating_sprite_buffer}+$0071,x
rol {rotating_sprite_buffer}+$0051,x
rol {rotating_sprite_buffer}+$0031,x
rol {rotating_sprite_buffer}+$0011,x

pla
inc
beq +
jmp -
+;

rts
lint
Posts: 25
Joined: Thu May 15, 2008 4:05 am

Re: Rotating BIG sprites

Post by lint »

Can you post a rom ? I'm curious about the result ... and the perfs ...
https://twitter.com/Lint_
http://snesdev.antihero.org/ [depecated blog, new one coming one of these days]
psycopathicteen
Posts: 3140
Joined: Wed May 19, 2010 6:12 pm

Re: Rotating BIG sprites

Post by psycopathicteen »

At 60fps it causes slowdown, but I can fix it by having it run outside the main routine. It's okay if it runs 30fps or 20fps, because even the non-realtime rotation sprites have variable framerates because of DMA limitations.
Attachments
real time rotation.zip
(82.95 KiB) Downloaded 282 times
Stef
Posts: 263
Joined: Mon Jul 01, 2013 11:25 am

Re: Rotating BIG sprites

Post by Stef »

Really impressive psycopathicteen :)
psycopathicteen
Posts: 3140
Joined: Wed May 19, 2010 6:12 pm

Re: Rotating BIG sprites

Post by psycopathicteen »

I've been thinking today about this and I realized that if I scroll every 5 pixels instead of 8, I would only need 8 distinct rotation frames (16 including x/y flip) to make a full circle because arctan(1/5) = ~11.25 degrees.
psycopathicteen
Posts: 3140
Joined: Wed May 19, 2010 6:12 pm

Re: Rotating BIG sprites

Post by psycopathicteen »

I got a 64x64 sprite rotating 360 degrees, but it looks kind've crappy because I was in a rush.
Attachments
Alisha's Adventure.zip
(121.56 KiB) Downloaded 201 times
UnDisbeliever
Posts: 123
Joined: Mon Mar 02, 2015 1:11 am
Location: Australia (PAL)
Contact:

Re: Rotating BIG sprites

Post by UnDisbeliever »

Looking good.

EDIT: The rotations look a lot nicer on my CRT TV then on a SNES emulator. I can barely see the tearing on my PAL SNES+CRT TV.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Rotating BIG sprites

Post by tokumaru »

UnDisbeliever wrote:The rotations look a lot nicer on my CRT TV then on a SNES emulator.
EVERYTHING looks better on a CRT television than on an emulator. :wink:
psycopathicteen
Posts: 3140
Joined: Wed May 19, 2010 6:12 pm

Re: Rotating BIG sprites

Post by psycopathicteen »

I didn't think about this, but it would look better on a PAL TV set than an NTSC TV set, because you have 20% more CPU time.

Here is an improved version, that would look good even on NTSC.
Attachments
Alisha's Adventure.zip
(112.69 KiB) Downloaded 210 times
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: Rotating BIG sprites

Post by Drew Sebastino »

UnDisbeliever wrote:I can barely see the tearing on my PAL SNES+CRT TV.
"It looks a lot better after it's been blurred out." :lol:
ccovell
Posts: 1045
Joined: Sun Mar 19, 2006 9:44 pm
Location: Japan
Contact:

Re: Rotating BIG sprites

Post by ccovell »

It looks quite good, and I really like the green pumpkin spider. Very Wolfteam-like.

Music is strident, but slowly getting less abrasive....
Post Reply