Jump to content
IGNORED

Two animation questions


trufun101

Recommended Posts

Ok, so I have two animation-related questions:

 

1. From everything I've seen, Raptor builds animations where the frames within the image are vertically-oriented.  Is there a way to have them horizontally-oriented?  In my case, my sprites have a greater height than width, so it would be more efficient to store the frames horizontally.

 

2. Does Raptor support multiple animations for a single sprite?  For example, if I have a character that needs separate animations for running, jumping, shooting, etc., can that be achieved with a single sprite?  I can make it work with separate sprites for each animation, but I'm curious if there's a better way.

 

Thanks!

Link to comment
Share on other sites

Hi There,

 

Your post about attempting to port Mortal Kombat actually sparked my interest in seeing what the Jag can do for 2D fighters.  It's a shame the Jag never got much in the way of top tier licensed franchises because the Jag can certainly produce visuals on-par with pretty much and 2D fighter from the 32bit generation.  The real issue is ROM storage size, not Graphics Processing ability. 

Anyway, yesterday I started playing with some things and realized that it would be necessary to support Texture Atlus, not just simple vertical sprites.  And with Texture Atlus, the sprite can animate in any direction - vertically, horizontally, even out-of-order meaning the frames do not need to be contiguous.


The Jag is certainly able to do this via Raptor / Jagstudio, but maybe not natively as it does with Vertical Sprites ( @CyranoJ please correct me if there is a native way ).  Basically, you need to track your s,t co-ordinates as well as the width + height of each frame within the texture.  From there, you can offset the graphic base address for the sprite by s * (texture bit depth multiplier) + t * gwidth. You also need to store your original gfxbase because this will now change between frames.

Example, your sprite is located at pixel (s,t) 16,16 in your texture and the texture bit depth is 16, and your texture width is 512.
sprite[i].gfxbase = originalGfxBase + (16 * 2) + (16 * 512 * 2)

I've been able to easily get Texture Atlus working on the Jag using this method after 2 hours of playing around yesterday.  The only caveat I see is that the t co-ordinate MUST be on a 16 pixel boundary, otherwise it will be rounded down to the nearest 16 pixel index.

These screens are using the full Arcade Sprite sheet for Captain America from Marvel Vs Capcom, which is using this Texture Atlus approach I am describing.
image.thumb.png.46efce0ad2a624b6ddf00d2df7f03785.png

image.thumb.png.ffda03d582ca90793d1951913cf777e5.png

Again this is only a very quick implementation for my testing, but here are some code snippets that may be of interest to you.  I am considering making a short tutorial to go through in further detail if there is any iterest
 

struct animationFrame {
    int width;
    int height;
    int x;
    int y;
};
void animateFrame(unsigned int spriteIndex, unsigned int frame, struct animationFrame animationFrame[], float mulFactor, int y, unsigned int base) {
    sprite[spriteIndex].y_ = y - animationFrame[frame].height;
    sprite[spriteIndex].width = animationFrame[frame].width;
    sprite[spriteIndex].height = animationFrame[frame].height;  
    sprite[spriteIndex].bytewid = animationFrame[frame].width * mulFactor;
    sprite[spriteIndex].framesz = animationFrame[frame].width * animationFrame[frame].height * mulFactor;
    sprite[spriteIndex].gfxbase = base + (animationFrame[frame].x * mulFactor) + (animationFrame[frame].y * sprite[spriteIndex].gwidth );
}
 
  • Like 2
Link to comment
Share on other sites

56 minutes ago, OVERRiDE said:

Anyway, yesterday I started playing with some things and realized that it would be necessary to support Texture Atlus, not just simple vertical sprites.  And with Texture Atlus, the sprite can animate in any direction - vertically, horizontally, even out-of-order meaning the frames do not need to be contiguous.


The Jag is certainly able to do this via Raptor / Jagstudio, but maybe not natively as it does with Vertical Sprites ( @CyranoJ please correct me if there is a native way ).  Basically, you need to track your s,t co-ordinates as well as the width + height of each frame within the texture.  From there, you can offset the graphic base address for the sprite by s * (texture bit depth multiplier) + t * gwidth. You also need to store your original gfxbase because this will now change between frames.

 

The easiest way to do this would be to set the sprite to a single, unanimated frame.

 

each frame you would then set its curframe property:

 

to fake the atlus sprite:

 

To go 'up' subtract the number of sprites horizontally from the current frame

To go 'down' add the number of sprites horizontally from the current frame

To go 'left' subtract #1

To go 'right' add #1

 

 

  • Like 1
Link to comment
Share on other sites

20 hours ago, OVERRiDE said:

Hi There,

 

Your post about attempting to port Mortal Kombat actually sparked my interest in seeing what the Jag can do for 2D fighters.  It's a shame the Jag never got much in the way of top tier licensed franchises because the Jag can certainly produce visuals on-par with pretty much and 2D fighter from the 32bit generation.  The real issue is ROM storage size, not Graphics Processing ability. 

Anyway, yesterday I started playing with some things and realized that it would be necessary to support Texture Atlus, not just simple vertical sprites.  And with Texture Atlus, the sprite can animate in any direction - vertically, horizontally, even out-of-order meaning the frames do not need to be contiguous.


The Jag is certainly able to do this via Raptor / Jagstudio, but maybe not natively as it does with Vertical Sprites ( @CyranoJ please correct me if there is a native way ).  Basically, you need to track your s,t co-ordinates as well as the width + height of each frame within the texture.  From there, you can offset the graphic base address for the sprite by s * (texture bit depth multiplier) + t * gwidth. You also need to store your original gfxbase because this will now change between frames.

Example, your sprite is located at pixel (s,t) 16,16 in your texture and the texture bit depth is 16, and your texture width is 512.
sprite[i].gfxbase = originalGfxBase + (16 * 2) + (16 * 512 * 2)

I've been able to easily get Texture Atlus working on the Jag using this method after 2 hours of playing around yesterday.  The only caveat I see is that the t co-ordinate MUST be on a 16 pixel boundary, otherwise it will be rounded down to the nearest 16 pixel index.

These screens are using the full Arcade Sprite sheet for Captain America from Marvel Vs Capcom, which is using this Texture Atlus approach I am describing.
image.thumb.png.46efce0ad2a624b6ddf00d2df7f03785.png

image.thumb.png.ffda03d582ca90793d1951913cf777e5.png

Again this is only a very quick implementation for my testing, but here are some code snippets that may be of interest to you.  I am considering making a short tutorial to go through in further detail if there is any iterest
 

struct animationFrame {
    int width;
    int height;
    int x;
    int y;
};
void animateFrame(unsigned int spriteIndex, unsigned int frame, struct animationFrame animationFrame[], float mulFactor, int y, unsigned int base) {
    sprite[spriteIndex].y_ = y - animationFrame[frame].height;
    sprite[spriteIndex].width = animationFrame[frame].width;
    sprite[spriteIndex].height = animationFrame[frame].height;  
    sprite[spriteIndex].bytewid = animationFrame[frame].width * mulFactor;
    sprite[spriteIndex].framesz = animationFrame[frame].width * animationFrame[frame].height * mulFactor;
    sprite[spriteIndex].gfxbase = base + (animationFrame[frame].x * mulFactor) + (animationFrame[frame].y * sprite[spriteIndex].gwidth );
}
 

Awesome, thank you for the words of encouragement and the code snippets!  I hadn't thought about it, but I actually did something pretty similar with a game I built in XNA.  I used a tool called SpriteBuddy, which allows you to build animations from a spritesheet, then it exports an XML file.  My engine would then load up animations from the XML and play them with the appropriate frames and timing.  I could do the same thing here, but just generate the code instead of parsing the XML every time.  This makes it pretty easy to play the animations in reverse as well.  (which I will need when the fighters walk forward vs. backward)

 

Thanks again!

Link to comment
Share on other sites

15 hours ago, 42bs said:

One tip: Avoid float where ever you can. Rather use fixpoint math.

Yes this is very good advice, I have alrrady realized this on one of my other projects.  Without an FPU the m68k is VERY slow at floating point operations.  GCC can make them work so it may not seem obvious at first, but if do enough flops per frame and you will immediately see the performance penalty.

 

On other systems I've worked on, multiply by 0.5 is faster  than dividing by 2... but that assumes an FPU.  For the Jag, bitshift instead is exponentially faster.

 

For the code snippet above, this function is only called twice per frame so it is not a performance concern at present 

Link to comment
Share on other sites

On 10/3/2023 at 3:19 AM, Sporadic said:

You could also precalc the relevant values and store in a lookup table.

Yes, that is one possible way.  In this case, bit shifting >> 1 achieves the multiply by 0.5 / divide by two (4-bit bitmaps) but way faster since its an integer operation - I use this heavily in my other project where there are multiple divide-by-two operations that need to occur per frame and yeah using floating point maths really slowed down the performance lol.  Again this function I posted was really just a quick implementation that was not attempting to be optimized by any means.

 

Anyway, some more screens of this little project playing around with Arcade assets on the Jag using Texture Atlas based Sprites... it really is a shame Capcom and the like never embraced the Jaguar!
 image.thumb.png.d3a42bf321a2255124a6388948501292.png
image.thumb.png.59bd719803e6db969dc2f63e6cc46cbd.png

image.thumb.png.4cd7bc3088c4e0fcd326526452748891.png

  • Like 3
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...