Jump to content
IGNORED

Feature Request - Sprite scale origin variables


Sporadic

Recommended Posts

Hey, thanks for taking the time to do this! This will surely end up in rb+ one way or another (with your permission of course). I just want to take some time to optimise the code a bit (from briefly looking at it I think that all floating point instructions can be replaced with fixed point and the division(s) replaced by inverse multiplication). Anyway, I don't think I should attempt this tonight :).

  • Like 2
Link to comment
Share on other sites

Also, please note that I added 1 to the width and height after retrieving from rgetobj near the beginning. This is so it worked out correctly and the sprite stayed more central.

 

I can understand having to add 1 to the height because of the known issue but i'm not sure why adding 1 to the width helped it look better. Might just be rounding errors in the horrible math I used ;)

Edited by Sporadic
  • Like 1
Link to comment
Share on other sites

  • 1 month later...

Was just looking at scaled stuff and wanted to position an object centrally as a few different things throw values at the scale factor every frame. I remembered this thread but thought I'd muck about anyway.

 

I found that, to position my spite centrally in x, if I did this:

 

bingo=32-scale_factor ' normalise scale factor to 0 (probably the wrong term, a long time since I needed to know these things), 32 being 1:1

x_pos=x_offset+(bingo*2)

 

...that seems to place it where I want it and was working for scale values of 8 to 128.

 

If anyone wants to give that a go and see if it works OK for their needs, that would be nice, and if not there's probably something close we can figure out that will.

 

The actual code from my game is this:

 

bingo=32-x_scale
RSETOBJ(web,R_sprite_x,(x_off+(bingo*2))<<16)
Edited by sh3-rg
  • Like 1
Link to comment
Share on other sites

That looks similar to what I started with. Does that work for other sprite sizes?

 

EDIT: Also, how is xoffset defined in your code? Its not shown in your post.

 

Funny you should post this as I was looking at this code/thread today too!

Edited by Sporadic
Link to comment
Share on other sites

Well, the hardware manual states:

 

This eight bit field contains a three bit integer part and a five bit fractional

part. The number determines how many pixels are written into the line

buffer for each source pixel.

Unless I'm grossly mistaken, if your width (or height) is "a" and your scale factor is "b" (from 0 to 255) then you can calculate the scaled size like this: a*b/(1<<5)=a*b/32. So, half the scaled size in order to find the centre would be a*b/64 (or (a*b)>>6). Add that to the corner coordinate and you have your centre coordinate.

 

If you keep your coordinates in a longword variable (since raptor has 16 bits integer and 16 fraction) and perform the above calculation you'll end up with the fractions shifted to the proper bits. Problem is, the 68000 can't perform a 32bitsx16bits multiplication internally so gcc calls a helper function for this which consumes a few more cycles. So my advice would be if possible to perform these calculations offline, store them in a table of longs and then load them as needed.

Link to comment
Share on other sites

Well, the hardware manual states:

 

 

Unless I'm grossly mistaken, if your width (or height) is "a" and your scale factor is "b" (from 0 to 255) then you can calculate the scaled size like this: a*b/(1<<5)=a*b/32. So, half the scaled size in order to find the centre would be a*b/64 (or (a*b)>>6). Add that to the corner coordinate and you have your centre coordinate.

 

If you keep your coordinates in a longword variable (since raptor has 16 bits integer and 16 fraction) and perform the above calculation you'll end up with the fractions shifted to the proper bits. Problem is, the 68000 can't perform a 32bitsx16bits multiplication internally so gcc calls a helper function for this which consumes a few more cycles. So my advice would be if possible to perform these calculations offline, store them in a table of longs and then load them as needed.

 

havin-a-giggle.gif

 

Why do you need to know the centre? That's probably the bit I'm not 100% on... maybe in some circumstances it's good to know the centre, I thought the issue was keeping a sprite centered as it scales.

Edited by sh3-rg
Link to comment
Share on other sites

x_off is just the x position, sorry for that wording, it makes sense in my game but not typed out here.

 

The stuff I posted doesn't take account of sprite width, it's only concerned with the scale factor vs the coordinate. If you wanted to position an object centrally on a given x coordinate, you'd offset what I did by half the sprite width... so e.g. with a 64-wide sprite you'd subtract 64/2 from your x position.

Edited by sh3-rg
Link to comment
Share on other sites

Why do you need to know the centre? That's probably the bit I'm not 100% on...

Sometimes it definitely helps if the origin is the middle of the sprite rather than in the corner.

I thought sporadic asked for this? Also, if you know the centre coordinates of a sprite it's easier to move it around, especially if you're scaling up and down all the time.

Link to comment
Share on other sites

I thought sporadic asked for this? Also, if you know the centre coordinates of a sprite it's easier to move it around, especially if you're scaling up and down all the time.

 

OK, so if you want to place a scaled sprite centred at x=160:

 

bingo=32-x_scale
RSETOBJ(web,R_sprite_x,(160-(sprite_width/2)+(bingo*2))<<16)
something like that?
Link to comment
Share on other sites

 

bingo=32-scale_factor ' normalise scale factor to 0 (probably the wrong term, a long time since I needed to know these things), 32 being 1:1

x_pos=x_offset+(bingo*2)

 

...that seems to place it where I want it and was working for scale values of 8 to 128.

 

If anyone wants to give that a go and see if it works OK for their needs, that would be nice, and if not there's probably something close we can figure out that will.

 

 

Sorry, but this doesn't work for all sprite sizes.

 

Please see attached scaler project that has a 64px sprite and a 128px sprite.

The 128px scales in place correctly but the 64px sprite gets smaller from the left. Run it to see.

DPad left/right to change scale sizes.

 

This is why in my original scaler project, it took account of the scaled half sprite width, because it has to adjust the xpos accordingly to stop the sprite from moving left or right and scale it "in place".

 

I think it works with the 128px sprite because that just "fits in" with the formula you posted.

 

Yes, I was after a scale operation that scales the sprite centrally (so it gets bigger to the left and right), I wasn't after something to find the middle or to position the sprite based on the middle.

 

Certainly if your sprite is about 128px then the above formula will be the quickest method as it just works for that size :)

scaler_new.zip

  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...