gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > Best way to handle space between screens?

#157830 - Polaris - Fri May 30, 2008 4:55 am

I want my sprites to make the transition in a way that they appear where they should if they followed a straight line through the space between the screens.

I hope that was clear enough.

Anyway, the first thing I thought was pretty simple. Instead of placing my sprite right on the Y border of the screen it should "jump" to, I placed it roughly 90 pixels before. This way if the sprite keeps the same trajectory, it eventually appears in the position the player would expect. The problem with this is that the sprite actually has to go the distance unseen.

My second and better approach was to use some simple trigonometry. I would calculate the X position on the new screen using the entrance angle and having as a constant the space between screens. If I'm not mistaken that would be something like this:
Code:
float Xpos = 90/tan(angle);

I'm pretty sure that should work, so I think my problem is doing it with fixed point. This is what I got
Code:
int Xpos = 90<<8/TAN[angle&0x01FF]>>4;

Is the math in there alright? I'm aiming for a 8.8 fixed point result, but I'm not to clear as to what extra shift I have to do in order to get a proper result from a fixed point division.

#157856 - Sweater Fish Deluxe - Fri May 30, 2008 9:25 pm

I don't know if your math is right or not, but personally I don't think this method of handling the gap will really feel more natural. It depends on how your sprites are moving obviously, but if they approach the gap at anything less than a 60 degree angle, I think it would be pretty disorienting to have them suddenly appear on the other screen, at a totally different X coordinate. I also find that the speed the sprite is moving is significant in how noticeable the gap is. But by all means try this out and let us know how it feels. It might be fine in your particular game.

One other thing I could suggest is to just pretend the gap smaller than it really is. It's actually 96pixels on a Lite, but coding it as 48 seems to still feel okay, but again that would depend on how the sprites move in a particular game.

One thing I've considered is using triangles or arrows that appear on both screens whenever a sprite is hidden in the gap. One where it went off screen and another where it will appear on the second screen, both pointing to the sprite off screen and maybe getting larger or changing color as the sprite gets closer to them. It's kind of complicated, so I don't know if it would really be effective in a gameplay setting, but it's something I've considered.

Ultimately, I don't think there's any good way to handle the gap between the screens. It's just a flaw in the DS design, I think (not that it could have been avoided, but still a flaw). I would love it if the DS could bring back all those great vertical screen orientation arcade gameplay concepts form the '80s, but sadly it just can't.


...word is bondage...

#157858 - Polaris - Fri May 30, 2008 11:39 pm

I already did solve this little problem, and it turned out as usual.

When dealing with simple trigonometry avoid the tangent, the sine+cosine combo gets better results every time. I always forget about it, but it probably has to do with the tangent generating asintotes.

As for the felling the player might get from how the invisible space is handled, I'll have to test it. Personally I found really annoying in games like Contra 4 that you can die because things are still happening in the hinge, even if you can't see them. But in Metroid Prime Pinball for instance, it feels really natural.

It is true that having the sprites making an instant jump from one display to the other is a bit too fast. Probably the best approach is a mixture of both. Having the sprite move unseen, but not the whole distance, so the player can adjust to the display swapping, without waiting that much.

I guess the kind of game is also really important when deciding what to do with this.

#157859 - Cydrak - Fri May 30, 2008 11:46 pm

Sweater Fish Deluxe wrote:
I don't know if your math is right or not, but personally I don't think this method of handling the gap will really feel more natural.

The trig seems okay. However, here all axis angles will be undefined (use a graph/calculator to see). Also, units: tan() wants radians, and TAN[] uses a circle of 0x200 "degrees".

A bigger concern is that it introduces rather strange physics. If one has a point on the edge of the screen, where is it supposed to be? It will "connect" at different spots depending on the angle... to the game it's not a smooth, consistent space. This ignores if it's gone left, right or not moving at all. I have no idea how you'd handle collision or scrolling.

#157861 - Polaris - Sat May 31, 2008 12:00 am

Damn, I was about to leave.

I read somewhere on this forum that if I wanted to make a game that uses both screens as one, the best thing is to have my program reflect that purpose. I thought about it for a minute and came up with the following, which I haven't tried yet, but would be nice to have some input before hand.

Suppose I have each display using a 64x64 background layer with the same Tile and Map bases assigned to them. And then I use the BGnY registers of each background to place them so that each screen shows what the other can't.

Would that be a good way to simulate the "single tall screen" effect, from the programs perspective that is.

#157863 - Cydrak - Sat May 31, 2008 12:27 am

Yes, you can of course twiddle the BGs so they line up. However, you can't just share the data. VRAM is always assigned to a specific part of the graphics system, and the two graphics cores are completely separate.

So, there are two basic ways to span screens:
- Duplicate the sprites/tilemap, like you said. (Easy if you separated your physics and drawing code. It's probably also more compatible with emulators, and loses less VRAM/framerate... but you can't do 3D this way.)
- Reserve banks C and D as framebuffers. Then alternate rendering the top and bottom, just using the main graphics core. (Not too hard, and it supports 3D--but requires a good understanding of the hardware, and I don't know any real tutorials...)