does anybody have a good rspr(n, x, y, w, h, r, ox, oy, flipx, flipy) function to draw rotated sprites?
I need this to make my 4 player spaceship battle game.

P#54942 2018-08-10 21:40 ( Edited 2018-08-11 01:40)

See these previous discussions:

And maybe useful:

P#54944 2018-08-10 22:49 ( Edited 2018-08-11 02:49)

See the ‘Gyrus’ demo cart in this thread:
https://www.lexaloffle.com/bbs/?tid=3593

You’ll find a rspr function that is fast and pixel perfect :)

P#54945 2018-08-11 03:25 ( Edited 2018-08-11 07:39)

@dddaaannn
the first one u linked doesn't seem to be in a function and I can't read it well enough to put it in one to try it out

the second one you linked doesn't fit what I need and when I tried to fix it it doesn't draw right

@freds72 u mean this one?

Cart #54948 | 2018-08-11 | Code ▽ | No License
Cart #54949 | 2018-08-11 | Code ▽ | No License

this uses weird arguments as it doesn't let me specify a height

 ```function rspr(sx,sy,x,y,a,w) local ca,sa=cos(a),sin(a) local srcx,srcy,addr,pixel_pair local ddx0,ddy0=ca,sa local mask=shl(0xfff8,(w-1)) w*=4 ca*=w-0.5 sa*=w-0.5 local dx0,dy0=sa-ca+w,-ca-sa+w w=2*w-1 for ix=0,w do srcx,srcy=dx0,dy0 for iy=0,w do if band(bor(srcx,srcy),mask)==0 then local c=sget(sx+srcx,sy+srcy) sset(x+ix,y+iy,c) else sset(x+ix,y+iy,rspr_clear_col) end srcx-=ddy0 srcy+=ddx0 end dx0+=ddx0 dy0+=ddy0 end end ```

also if you mean the first one then it doesn't work properly for example putting in 32 for argument s should be tile 0,2 but its not.

EDIT: something like sprr(s,x,y,w,h,r) should work

P#54950 2018-08-11 11:07 ( Edited 2018-08-11 16:12)

You can’t put height because I only ever needed to rotate square sprites!
Adding a height should be easy.

Note that this version actually writes to the sprite sheet, replace sset by pset to draw on screen.

As for:
«
EDIT: something like sprr(s,x,y,w,h,r) should work
«
Sorry, that’s Pico-8, either you roll put tour own sprr function or work with what other did.
Don’t expect someone else to do your own code!

P#54960 2018-08-11 13:49 ( Edited 2018-08-11 19:27)

ok sorry so I took a try at it from the top of my head and got this...

 ```function sprr(s,x,y,w,h,r) local xr=sin(r/360) local yr=cos(r/360) local sx=flr(s%16) * 8 local sy=flr(s/16) * 8 for yy=sy,sy+h*8-1 do for xx=sx,sx+w*8-1 do local dc=sget(xx,yy) -- this should get the rotated loop position local dx=x+(xx-sx) * xr local dy=y+(yy-sy) * yr pset(x+xx,y+yy, dc) end end end ```

however dx and dy is not correct do you know what could be wrong?

P#54973 2018-08-11 17:30 ( Edited 2018-08-11 21:30)

To have a clean rotated sprie with no holes, you must go through the target region (eg square ir rectangle) and get the rotated pixel that should be at position. Suggest to read the Dr Dobbs article I took the code from (linked in the post I mention)

P#54977 2018-08-11 17:59 ( Edited 2018-08-11 21:59)

I thought thats what I am doing.
I am offsetting the current pixel position by a angle and length.

I did take a look at that dr dobbs page you posted in the other topic though, I really didn't understand it.

P#54980 2018-08-11 20:00 ( Edited 2018-08-12 00:01)

@freds72 can you tell me what I am doing wrong with dx and dy?

so here is another attempt to create it..

 ```function sprr(s,x,y,w,h,r) local rx=cos(r/360) local ry=sin(r/360) local sx=flr(s%16) * 8 local sy=flr(s/16) * 8 local ex=sy+h*8-1 local ey=sx+w*8-1 local rr=ry*ry+rx*rx for yy=sy,ey do for xx=sx,ex do local dx=( ry*yy+rx*xx)/rr+w local dy=(-ry*xx+rx*yy)/rr+h local dc=sget(dx,dy) pset(x+xx,y+yy, dc) end end end ```

based it on this.. https://www.lexaloffle.com/bbs/?tid=2189

P#55010 2018-08-12 15:34 ( Edited 2018-08-12 22:21)

@freds72 so this time I tried my best to follow the dr dobbs tutorial and reference it to yours and I got this..

 ```function sprr(s,x,y,w,h,r) local sx=flr(s % 16) * 8 local sy=flr(s / 16) * 8 local sw=w*8 local sh=h*8 local dx=x local dy=y local dw=w*8 local dh=h*8 local colx = sin(r/360) local coly = cos(r/360) local rowx = coly; local rowy =-colx; local srtu = sx - (dx * coly + dy * colx); local srtv = sy - (dx * rowy + dy * rowx); local rowu = srtu; local rowv = srtv; for y=0, dh do local u = rowu local v = rowv for x=0, dw do local su = ((u < 0.0 and -u or u) + sw) % sw local sv = ((v < 0.0 and -v or v) + sh) % sh pset(dx+x, dy+y, pget(su, sv)) u += rowx v += rowy end rowu += rowx rowv += rowy end end ```

can you please take a look at it and tell me whats wrong?

P#55091 2018-08-13 18:02 ( Edited 2018-08-13 22:02)

Looks like a plain typo:
pset(..,..,pget(..))
pset(..,..,sget(..))
(that is read from spritesheet, write on screen)

edit: you are not iterating over the right direction:
u+=rowx
v+=rowy
must be:
u+=colx
v+=coly

Otherwise, looks ok (it’s fine to start with a very verbose version and optimize after)

P#55119 2018-08-14 04:05 ( Edited 2018-08-14 08:07)

is there any optimizations I could make besides ingnoring color 0?

also I see your version has a mask so it doesn't draw outside of the source tiles, but I had a hard time understanding it can you explain how to do that in mine?

P#55146 2018-08-14 15:30 ( Edited 2018-08-14 19:30)

The fully optimized version is mine ;)
You’re version as a lot of useless variables and intermediate variables that you can rid of.

The mask indicates if the value is above the width/height of the sprite (expressed as a power of 2).

P#55148 2018-08-14 15:43 ( Edited 2018-08-14 19:43)

@freds72 I was messing around and I came up with a compact version.
the only problem is that it seems to rotate the src pixels and slows down at certain angles

 ```function sprrt1(s,x,y,w,h,r) local spx=flr(s%16)*8 local spy=flr(s/16)*8 w*=8 h*=8 r=r/360 for iy=0,h do for ix=0,w do local sx=spx+ cos(-r)*ix+sin(-r)*iy local sy=spy+-sin(-r)*ix+cos(-r)*iy local sc=sget(sx,sy) //local bnd=sxspx+w or sy>spy+h //if sc>0 and not bnd then pset(x+ix,y+iy,sc) end end end ```

https://gph.is/2OCbFTu

edit: i wanted it to rotate around center

P#55154 2018-08-14 16:23 ( Edited 2018-08-14 20:36)

Sorry @Shadowblitz but I gave the source code for a fast and correct sprite rotating function.
I am not going to redo the same work again for your version.

Hint: do not calculate 4 sin/cos for every single pixel...

P#55163 2018-08-14 17:58 ( Edited 2018-08-14 21:58)

can you at least fix your version then so it takes in a height parameter?
this is basically your code but with h implemented and mask taken out because I don't know how to do the mask with h included.
it also has a bug where it rotating the src rectangle.

 ```function sprr(s,x,y,w,h,r) local rx=cos(r/360) local rx=cos(r/360) local ry=sin(r/360) local sx=flr(s % 16) * 8 local sy=flr(s / 16) * 8 local ddx0=rx local ddy0=ry w*=4 h*=4 rx*=w-0.5 ry*=h-0.5 local dx0= ry-rx+w local dy0=-rx-ry+h w=2*w-1 h=2*h-1 for iy=0,h do local srcx = dx0 local srcy = dy0 for ix=0,w do local c=sget(sx+srcx,sy+srcy) pset(x+ix,y+iy,c) srcx -= ddy0 srcy += ddx0 end dx0 += ddx0 dy0 += ddy0 end end ```

if your not going to help people adapt your code for something that should have been implemented to begin with, then why did you even post a link to your code in the first place?

P#55164 2018-08-14 18:36 ( Edited 2018-08-14 23:31)

@freds72
so what do I do with this function to add a height paramater?

 ``` local mask=shl(0xfff8,(w-1)) ```
P#65760 2019-07-11 06:30

you cannot unless you have 2 masks (which defeats the point).
So just check if source pixel is outside boundaries (0,0,w,h) and you should be good.

P#65761 2019-07-11 08:35

oh thanks

P#65768 2019-07-11 18:07

@freds72

how would I add a rotation offset to the function?

 ```function rspr(n,x,y,w,h,a,ax,ay) print(a,64,64,7) ax=ax or 0 ay=ay or 0 a = flr(a/22.5)*22.5 local sx,sy=flr(n%16)*8,flr(n/16)*8 local ca,sa=cos(a/360),sin(a/360) local srcx,srcy,addr,pixel_pair local ddx0,ddy0=ca,sa local mask=shl(0xfff8,(w-1)) w*=4 h*=4 ca*=w-0.5 sa*=h-0.5 local dx0,dy0=sa-ca+w,-ca-sa+h w=2*w-1 h=2*h-1 for ix=0,w do srcx,srcy=dx0,dy0 for iy=0,h do if contains(srcx,srcy,0,0,w,h) then local c=sget(sx+srcx,sy+srcy) pset(x+ix,y+iy,c) else pset(x+ix,y+iy,rspr_clear_col) end srcx-=ddy0 srcy+=ddx0 end dx0+=ddx0 dy0+=ddy0 end end ```
P#65780 2019-07-11 22:17

what is a ‘rotation offset’??

P#65787 2019-07-12 05:34

it's a rotation x and y offset from the center

P#65800 2019-07-13 02:48

This is done outside of the function - you need to decompose as:

• rotation around center
• translation to rotated position
P#65809 2019-07-13 07:18