trufun101 Posted September 28, 2023 Share Posted September 28, 2023 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! Quote Link to comment Share on other sites More sharing options...
OVERRiDE Posted September 30, 2023 Share Posted September 30, 2023 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. 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 ); } 2 Quote Link to comment Share on other sites More sharing options...
+CyranoJ Posted September 30, 2023 Share Posted September 30, 2023 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 1 Quote Link to comment Share on other sites More sharing options...
LordKraken Posted September 30, 2023 Share Posted September 30, 2023 Not sure how good your compiler is at optimization but you might want to consider passing a pointer on your animation frame instead of the frame index and the array of animationFrame (same with spriteIndex actually). 1 Quote Link to comment Share on other sites More sharing options...
trufun101 Posted September 30, 2023 Author Share Posted September 30, 2023 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. 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! Quote Link to comment Share on other sites More sharing options...
42bs Posted October 2, 2023 Share Posted October 2, 2023 One tip: Avoid float where ever you can. Rather use fixpoint math. Quote Link to comment Share on other sites More sharing options...
OVERRiDE Posted October 3, 2023 Share Posted October 3, 2023 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 Quote Link to comment Share on other sites More sharing options...
42bs Posted October 3, 2023 Share Posted October 3, 2023 Avoiding float starts on the small things. 1 Quote Link to comment Share on other sites More sharing options...
Sporadic Posted October 3, 2023 Share Posted October 3, 2023 You could also precalc the relevant values and store in a lookup table. 1 Quote Link to comment Share on other sites More sharing options...
OVERRiDE Posted October 6, 2023 Share Posted October 6, 2023 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! 3 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.