New 32x demo - Ninja Fighter 2d
Moderator: Mask of Destiny
-
- Very interested
- Posts: 124
- Joined: Sun Jan 29, 2012 2:10 pm
- Location: North America
- Contact:
New 32x demo - Ninja Fighter 2d
For those who saw me posting questions in the Super 32X forums. Here is what I've been working on this whole time!
Ninja Fighter 2d - version 0
Edits
Gameplay video:
v3 - http://youtu.be/ChiOXwBn_kk
Rom:
v3 -http://50.17.234.100/ammianus/32x/demo- ... r2d_v3.32x
I know it's not much. Basically I am drawing a background and a few sprites to the 32X VDP in 256 color mode. The player controls the ninja character, who can either move left or right or kick (b-button). The other character is "ai" controlled and will follow you around. I haven't added any moves for him. Kicking the opponent will send him flying. Really basic logic. And yes there are some sprite glitches I haven't fixed yet. I have not tried this in real hardware (don't have access yet) . It plays in Fusion 3.64 and Gens-gs-r7-win32-pkg1.
Nothing fancy going on here. I did write some functions for drawing arbitrary sized image data at any location in the FB, and it can be drawn "flipped" depending which way the sprite is facing. I haven't found anyone has shared any low level C library with basic functions for this, but if someone had it that would have saved me time
I used Chilly Willy's 32x gcc tool chain for this, most of the code is written in C. I also borrowed heavily from the examples he provided like TicTacToe.
I used mic_'s lzss_decode and a modified version of his sixpack tool to compress all the graphics to lzss and decode them to draw.
Sprites I (shamelessly) took from various sites on the web, the ninja is from Samurai Showdown I think and the other guy is Sesshomaru from Inuyasha (I think he was in some Mugen game).
Thanks for everyone's help with my newbie questions. This is not really the game I want to make, so I hope to continue working on this, learning how to make better, more fun games.
Ninja Fighter 2d - version 0
Edits
Gameplay video:
v3 - http://youtu.be/ChiOXwBn_kk
Rom:
v3 -http://50.17.234.100/ammianus/32x/demo- ... r2d_v3.32x
I know it's not much. Basically I am drawing a background and a few sprites to the 32X VDP in 256 color mode. The player controls the ninja character, who can either move left or right or kick (b-button). The other character is "ai" controlled and will follow you around. I haven't added any moves for him. Kicking the opponent will send him flying. Really basic logic. And yes there are some sprite glitches I haven't fixed yet. I have not tried this in real hardware (don't have access yet) . It plays in Fusion 3.64 and Gens-gs-r7-win32-pkg1.
Nothing fancy going on here. I did write some functions for drawing arbitrary sized image data at any location in the FB, and it can be drawn "flipped" depending which way the sprite is facing. I haven't found anyone has shared any low level C library with basic functions for this, but if someone had it that would have saved me time
I used Chilly Willy's 32x gcc tool chain for this, most of the code is written in C. I also borrowed heavily from the examples he provided like TicTacToe.
I used mic_'s lzss_decode and a modified version of his sixpack tool to compress all the graphics to lzss and decode them to draw.
Sprites I (shamelessly) took from various sites on the web, the ninja is from Samurai Showdown I think and the other guy is Sesshomaru from Inuyasha (I think he was in some Mugen game).
Thanks for everyone's help with my newbie questions. This is not really the game I want to make, so I hope to continue working on this, learning how to make better, more fun games.
Last edited by ammianus on Sun Sep 02, 2012 7:35 pm, edited 3 times in total.
-
- Very interested
- Posts: 2984
- Joined: Fri Aug 17, 2007 9:33 pm
It's a good start. I'm sure it can be sped up. You probably do something that kills the speed without realizing it. Maybe on the screen flip, you're wasting a vertical blank, making it half the speed it could be. Maybe your background draw routine is slower than it should be. Maybe you're redrawing the entire background every time when it's not needed.
-
- Very interested
- Posts: 124
- Joined: Sun Jan 29, 2012 2:10 pm
- Location: North America
- Contact:
I am redrawing the background the entire time. If I remove that it basically speeds up the movement of the characters. Although it leaves some other side effects such as the past sprite draws are still there. I'll have to do that more efficiently.Chilly Willy wrote:It's a good start. I'm sure it can be sped up. You probably do something that kills the speed without realizing it. Maybe on the screen flip, you're wasting a vertical blank, making it half the speed it could be. Maybe your background draw routine is slower than it should be. Maybe you're redrawing the entire background every time when it's not needed.
That background image is about 70 KB uncompressed so I was trying to read it using the lzss_decode method which directly writes to the FB. But I'll have to rethink that or scrap the large background for this and go to something smaller.
I am not doing any optimization on screen flip, so probably wasting that vertical blank as you say.
-
- Very interested
- Posts: 2984
- Joined: Fri Aug 17, 2007 9:33 pm
Well, lzss is meant for decompressing when loading a level, not for every time you redraw. It would be quicker to save the background under the sprites to erase them rather than lzss the whole background each time.
As to screen flipping, what you want to do is run the game logic, then check if the screen has finished flipping. Once it finishes, draw the next frame, flip the screen and loop. Don't wait for the screen after flipping as that is a prime time to do the game logic. Only wait for the flip after the game logic is done.
As to screen flipping, what you want to do is run the game logic, then check if the screen has finished flipping. Once it finishes, draw the next frame, flip the screen and loop. Don't wait for the screen after flipping as that is a prime time to do the game logic. Only wait for the flip after the game logic is done.
-
- Very interested
- Posts: 2984
- Joined: Fri Aug 17, 2007 9:33 pm
That's the way a lot of the early 32X games work. It's simple and fast. If your background doesn't need a lot of colors, that's also a good way to handle it. You get the most out of all the hardware.sega16 wrote:You could put the background on the genesis plane b and make the sprites on the 32x framebuffer the background appears not the have many colors anyway.
This demo is closer to what the SuperVDP thread was doing. The OP should probably read that thread - it may do him a lot of good for his project.
-
- Very interested
- Posts: 124
- Joined: Sun Jan 29, 2012 2:10 pm
- Location: North America
- Contact:
I'll try to do thatChilly Willy wrote:Well, lzss is meant for decompressing when loading a level, not for every time you redraw. It would be quicker to save the background under the sprites to erase them rather than lzss the whole background each time.
So to make sure I understand this, you mean something this right?As to screen flipping, what you want to do is run the game logic, then check if the screen has finished flipping. Once it finishes, draw the next frame, flip the screen and loop. Don't wait for the screen after flipping as that is a prime time to do the game logic. Only wait for the flip after the game logic is done.
Code: Select all
// Process controller inputs
// AI logic
// Update character positions, animation frames
//flip the FB, wait for vBlank??
MARS_VDP_FBCTL = currentFB ^ 1;
while ((MARS_VDP_FBCTL & MARS_VDP_FS) == currentFB) {}
currentFB ^= 1;
// draw character sprites to FB?
I could try, I'd have to learn MD development first . It may not look it, but the background actually has about 83 colors.sega16 wrote:You could put the background on the genesis plane b and make the sprites on the 32x framebuffer the background appears not the have many colors anyway.
I've tried reading it before. Now that I've got some experience working with this program, maybe rereading that will be helpful.This demo is closer to what the SuperVDP thread was doing. The OP should probably read that thread - it may do him a lot of good for his project.
-
- Very interested
- Posts: 2984
- Joined: Fri Aug 17, 2007 9:33 pm
Proper flipping would be more like this
Initializing the currentFB variable to the hardware means that the first wait for flip will go through without hanging. If you're ever in doubt about the frame buffer setting, wait for the next vblank, then fetch the current value currentFB = MARS_VDP_FBCTL & MARS_VDP_FS;
Think about the loop reordered like this:
1 - we draw the frame
2 - we start the frame flipping - note that the frame does not flip immediately, it flips on the next vblank.
3 - while the frame is waiting on the vblank to flip, we do all the game logic. sometime in this period, the vblank may or may not occur depending on how long game logic takes.
4 - wait on the flip to finish. If a vblank has occurred during the game logic phase, this will go through instantly, otherwise it will hold until the next vblank where the flip actually occurs.
5 - loop to 1
That is the same as how I redid your outline above, but started at a different point to make it more clear where the overlap with the flip comes in.
Code: Select all
// start with currentFB = MARS_VDP_FBCTL & MARS_VDP_FS;
// init
// menu, start game
game-loop:
// Process controller inputs
// AI logic
// Update character positions, animation frames
// wait on flip to finish
while ((MARS_VDP_FBCTL & MARS_VDP_FS) != currentFB) {}
// draw to FB
//flip the FB, without waiting on flip
currentFB ^= 1;
MARS_VDP_FBCTL = currentFB;
// go to game-loop
Think about the loop reordered like this:
1 - we draw the frame
2 - we start the frame flipping - note that the frame does not flip immediately, it flips on the next vblank.
3 - while the frame is waiting on the vblank to flip, we do all the game logic. sometime in this period, the vblank may or may not occur depending on how long game logic takes.
4 - wait on the flip to finish. If a vblank has occurred during the game logic phase, this will go through instantly, otherwise it will hold until the next vblank where the flip actually occurs.
5 - loop to 1
That is the same as how I redid your outline above, but started at a different point to make it more clear where the overlap with the flip comes in.
LZSS-decoding of large graphics every frame is going to be slooooow. It mainly intended for decompressing stuff during startup.
I've never measured the speed of my implementation, but I would guesstimate it to at least a few dozen cycles/pixels, especially since it's optimized for size and not for speed. So we're talking maybe 3 million CPU cycles to decompress a fullscreen image.
I'd suggest using an uncompressed background image, and either draw it with the Genesis VDP as others have suggested (you can get up to 64 colors by using both BG layers), or implement some sort of "dirty rectangles" system so that you only redraw the parts of the BG that need to be redrawn if you use the SH2s for it.
I've never measured the speed of my implementation, but I would guesstimate it to at least a few dozen cycles/pixels, especially since it's optimized for size and not for speed. So we're talking maybe 3 million CPU cycles to decompress a fullscreen image.
I'd suggest using an uncompressed background image, and either draw it with the Genesis VDP as others have suggested (you can get up to 64 colors by using both BG layers), or implement some sort of "dirty rectangles" system so that you only redraw the parts of the BG that need to be redrawn if you use the SH2s for it.
-
- Very interested
- Posts: 124
- Joined: Sun Jan 29, 2012 2:10 pm
- Location: North America
- Contact:
Thanks, I wasn't sure what the best way to go is, since there is limited memory available in 32x overall, I didn't want to take it all up with the bg and a few sprite animations, but lesson learned there.
One of my stumbling blocks initially which led me down the path of your lzss in the first place was how to just get the bitmap graphics compiled into my binary, I must not be aware of the tools that I can use to do that. So it seemed easier to use all the generated output from sixpack to that purpose. Does sixpack have a non-compressed mode that is compatible with 32X 256 color mode? (I feel like I tried early on, and it didn't work, but that was probably my first attempts) I may revisit that.
I was thinking about what others are saying, and I might take a stab at the generic dirty rectangles approach.
One of my stumbling blocks initially which led me down the path of your lzss in the first place was how to just get the bitmap graphics compiled into my binary, I must not be aware of the tools that I can use to do that. So it seemed easier to use all the generated output from sixpack to that purpose. Does sixpack have a non-compressed mode that is compatible with 32X 256 color mode? (I feel like I tried early on, and it didn't work, but that was probably my first attempts) I may revisit that.
I was thinking about what others are saying, and I might take a stab at the generic dirty rectangles approach.
It should give you an uncompressed bitmap if you just leave out the "-pack" option.Does sixpack have a non-compressed mode that is compatible with 32X 256 color mode? (I feel like I tried early on, and it didn't work, but that was probably my first attempts) I may revisit that.
Something like sixpack -image -target 32x -q 256 -format l8 -v -o out.bin background.png
It might not generate a line table for you then, but that's trivial to generate yourself for an uncompressed image.
-
- Very interested
- Posts: 2984
- Joined: Fri Aug 17, 2007 9:33 pm
-
- Very interested
- Posts: 124
- Joined: Sun Jan 29, 2012 2:10 pm
- Location: North America
- Contact:
Thanks so far for the assistance.
I've refactored the game loop as you've suggested, that had a modest improvement. The big one came when I got rid of the lzss decompression for every sprite. I only load all the animations and background image once and store it in memory.
That made a huge improvement: http://youtu.be/8Wcmzjvjqf8
I would still like to explore the "SuperVDP" concept, since I do want to get some scrolling of the background in the future.
Is there any tool you guys recommend for creating tiles from one larger image? Also how do you represent the tile locations in your code? Is it a good practice to externalize it into some file format that you read in to make it easier to build levels?
I've refactored the game loop as you've suggested, that had a modest improvement. The big one came when I got rid of the lzss decompression for every sprite. I only load all the animations and background image once and store it in memory.
That made a huge improvement: http://youtu.be/8Wcmzjvjqf8
I would still like to explore the "SuperVDP" concept, since I do want to get some scrolling of the background in the future.
Is there any tool you guys recommend for creating tiles from one larger image? Also how do you represent the tile locations in your code? Is it a good practice to externalize it into some file format that you read in to make it easier to build levels?