Page 1 of 2

New 32x demo - Ninja Fighter 2d

Posted: Sun Apr 01, 2012 12:48 am
by ammianus
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
Image

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.

Posted: Sun Apr 01, 2012 7:53 pm
by Chilly Willy
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.

Posted: Mon Apr 02, 2012 5:28 pm
by ammianus
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.
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.

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.

Posted: Mon Apr 02, 2012 11:57 pm
by Chilly Willy
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.

Posted: Tue Apr 03, 2012 8:26 pm
by sega16
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.

Posted: Tue Apr 03, 2012 10:13 pm
by Chilly Willy
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.
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.

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.

Posted: Sat Apr 07, 2012 12:43 pm
by ammianus
Chilly 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.
I'll try to do that
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.
So to make sure I understand this, you mean something this right?

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?
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 could try, I'd have to learn MD development first :D . It may not look it, but the background actually has about 83 colors.
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.
I've tried reading it before. Now that I've got some experience working with this program, maybe rereading that will be helpful.

Posted: Sat Apr 07, 2012 6:18 pm
by Chilly Willy
Proper flipping would be more like this

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
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.

Posted: Sat Apr 07, 2012 10:35 pm
by mic_
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.

Posted: Sun Apr 08, 2012 3:34 pm
by ammianus
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.

Posted: Sun Apr 08, 2012 4:03 pm
by mic_
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.
It should give you an uncompressed bitmap if you just leave out the "-pack" option.

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.

Posted: Sun Apr 08, 2012 5:49 pm
by Chilly Willy
Also, even if you don't use SuperVDP, you can take a lesson from it and reduce memory for backgrounds by drawing them as tiles instead of a complete image.

Posted: Tue Apr 10, 2012 11:46 am
by ob1
Yo.
On duty and happy to serve whenever you want.

PS : beside my other project : www.valpocl.com

Posted: Sun May 13, 2012 8:49 pm
by ammianus
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?

Posted: Sun May 13, 2012 10:14 pm
by sega16
Huge improvement compared to last version and I am always glad to see anything done with the 32x.