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 > My new game - and problems with same.

#123022 - 3D_geek - Sat Mar 24, 2007 6:06 pm

Well, after a week of dinking around with the DS - using:

* Games N'Music cartridge (which works AMAZINGLY well BTW)
* Linux for development.
* devkitARM r20
* libnds - the latest as of a week ago.

I have something reasonably nice running - which you are welcome to download and play with:

http://www.sjbaker.org/tmp/hardball.nds

Instructions: {UPDATED 3/25}[UDATED AGAIN 3/31] are now displayed on the bottom screen.

The back-story is that this is a mining colony on Mars - the arena is an ancient Martian city that's been turned into a place for the miners to live - with a glass canopy enclosing the atmosphere. Since it's a low gravity world, miners can get around on a variety of human-powered flying machines - bicycle-powered helicopters, giant mutant eagles, jet-packs, etc. For fun, they play a game that's a bit like 3D football - flying around the arena - grabbing the ball using force-field "grabbers"...using huge ore buckets on cranes as goals...you get the idea.

The entire game works 100% correctly on a Linux PC - but not yet 100% on the DS.

The actual game functions *would* also work - but because I've exceeded the 2048 polygon budget, I've had to turn a bunch of stuff off to get it to run at all - so I have more work to do before this is a playable game...but you *can* just fly around and admire the scenery - and that's fun for about 5 minutes!

...but I have LOTS of problems still:

1) I don't understand why I don't get any sounds or activity on the buttons that are handled on the ARM7. I've pretty much concluded that there is a problem somewhere in the current version of devkitARM and/or libnds because programs that I build don't produce sound or respond to the X/Y buttons - but programs I get ready-built from elsewhere work fine until I recompile them. Because the things that don't work are ARM7 functions, I presume there is something amiss with the ARM7 executable that devkit is (presumably) tacking on to my ARM9 program. Help!?!

2) I'm surprised that the DS seems to simply lock up/freeze if I draw one too many polygons. (Jeez - 2048 is a horribly low limit!) Is that intended behavior?

3) Could someone explain how texture storage works? When I overflow ~128k, I just get white textures - OK, fair enough - I guess I need more VRAM banks. So I added stuff like:

vramSetBankA(VRAM_A_TEXTURE);
vramSetBankB(VRAM_B_TEXTURE);
vramSetBankC(VRAM_C_TEXTURE);
vramSetBankD(VRAM_D_TEXTURE);

...but some of those commands seem to shut off the bottom screen - others result in very corrupted textures...like maybe they are sharing RAM with program storage or something. Which banks can I use and which ones are used for something else?

4) When my program links (using g++), I get a bunch of spurious linker errors. The same set of sources, compiled for Linux/x86 hardware link just fine. The errors appear to be something to do with ARM arithmetic emulation.

I can shut them up and get a working binary using "-Wl,-zmuldefs" ...but that can't be a good thing!

/home/nds/devkitARM_r20/bin/../lib/gcc/arm-eabi/4.1.1/thumb/libgcc.a(_udivsi3.o): In function `__aeabi_uidiv':
(.text+0x0): multiple definition of `__udivsi3'
/u/nds/devkitARM_r20/libnds/lib/libnds9.a(division.o):/home/nds/devkitARM_r20/libnds/source/common/division.s:(.text+0x4): first defined here
/home/nds/devkitARM_r20/bin/../lib/gcc/arm-eabi/4.1.1/thumb/libgcc.a(_udivsi3.o): In function `__aeabi_uidiv':
(.text+0x0): multiple definition of `__aeabi_uidiv'
/u/nds/devkitARM_r20/libnds/lib/libnds9.a(division.o):/home/nds/devkitARM_r20/libnds/source/common/division.s:(.text+0x4): first defined here
collect2: ld returned 1 exit status

Any clues?


Last edited by 3D_geek on Sat Mar 31, 2007 9:04 am; edited 2 times in total

#123026 - Diddl - Sat Mar 24, 2007 6:22 pm

no clues (from me) ...

but it is cool, a nice 3d landscape!

#123037 - 3D_geek - Sat Mar 24, 2007 7:55 pm

Diddl wrote:
no clues (from me) ...

but it is cool, a nice 3d landscape!


Thanks!

The railroad tracks should have mine karts rolling back and forth along them - there is a bug someplace in my fixed point matrix math that's making one of them fly across the middle of the arena at enormous speed - and the others be miles outside the arena. There should be two massive cranes with excavator scoops dangling benath them to make the two 'goals' - then the player is this kinda punk-looking guy riding a man-powered helicopter...other players are riding giant eagles and jetpacks and such...

But the arena and mine karts eats about 1000 triangles - each of the players eats around 700 - so I blow the triangle limit alarmingly quickly. I've got to put the whole scene on a severe polygon diet...argh!

#123056 - tepples - Sat Mar 24, 2007 9:55 pm

Shutting off the subscreen can be solved: move the console to a sub-bank (E through I). The corrupted textures may be the console's map and/or its 8x8 pixel font.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#123060 - HyperHacker - Sat Mar 24, 2007 10:22 pm

Your mine carts are 1000 polygons? You need to scale this game waaaaay down. I'd think ~9 quads and some textures could make a decent mine cart, especially if texture transparency is used for the wheels.
3D_geek wrote:
Start == Reset the game,
Select == Toggle Pause
Why do people keep using this control scheme? Every game ever has used Start to pause. It really sucks when you don't know the game you're playing has it assigned to Reset instead, or instinctively reach for Start anyway.
_________________
I'm a PSP hacker now, but I still <3 DS.

#123086 - 3D_geek - Sun Mar 25, 2007 12:41 am

HyperHacker wrote:
Your mine carts are 1000 polygons? You need to scale this game waaaaay down. I'd think ~9 quads and some textures could make a decent mine cart, especially if texture transparency is used for the wheels.


No! You misunderstand - the entire ARENA (all of the buildings, gantries, the floor, the walls and the roof and sky above the roof - PLUS THE MINEKARTS (of which there are half a dozen) comes to under 1000 polygons. The mine karts are indeed cuboids - with no top and two polygons dangling underneath with wheel textures!

The worst problem is the characters in the game - which are quite detailed because the camera is right up next to them much of the time. I've got to use a level-of-detail mechanism to drop those to much fewer polygons at longer ranges - but the worst-case situation is still bad...probably one has to play with the AI to ensure that characters don't congregate together too close to the camera...tricky stuff.

Quote:
3D_geek wrote:
Start == Reset the game,
Select == Toggle Pause
Why do people keep using this control scheme? Every game ever has used Start to pause. It really sucks when you don't know the game you're playing has it assigned to Reset instead, or instinctively reach for Start anyway.


It's utterly trivial to change. 'Start' says 'Reset' to me...but that's one line of code...I have a ton of other control issues to fix yet. Aside from anything else, I can't get the X/Y buttons to work - so I'm short of two buttons as it is.

#123087 - 3D_geek - Sun Mar 25, 2007 12:44 am

tepples wrote:
Shutting off the subscreen can be solved: move the console to a sub-bank (E through I). The corrupted textures may be the console's map and/or its 8x8 pixel font.

I'm not entirely sure how to do that - what banks are there - and what are the recommended distribution of textures/screens/whatever? I'm using 16 bit textures - so no color map is needed.

#123125 - 0xtob - Sun Mar 25, 2007 10:45 am

Hey, really nice game so far!

Quote:
1) I don't understand why I don't get any sounds or activity on the buttons that are handled on the ARM7. I've pretty much concluded that there is a problem somewhere in the current version of devkitARM and/or libnds because programs that I build don't produce sound or respond to the X/Y buttons - but programs I get ready-built from elsewhere work fine until I recompile them. Because the things that don't work are ARM7 functions, I presume there is something amiss with the ARM7 executable that devkit is (presumably) tacking on to my ARM9 program. Help!?!

This looks like the arm7 part is not running, which is usually the case because the wrong entry point is set (the entry point was changed with devkitPro r20). Check for the ndstool call in your top-level Makefile. If there are parameters like -e7 ... and -r7 ..., remove them. Also make sure you're using the latest ndstool (i.e. the one that comes with DKP r20).
_________________
http://blog.dev-scene.com/0xtob | http://nitrotracker.tobw.net | http://dsmi.tobw.net

#123142 - zzo38computer - Sun Mar 25, 2007 5:01 pm

Make START+SELECT if pushed simultaneously reset the game, and START by itself to pause.
_________________
Important: Please send messages about FWNITRO to the public forum, not privately to me.

#123170 - 3D_geek - Sun Mar 25, 2007 8:44 pm

0xtob wrote:
This looks like the arm7 part is not running, which is usually the case because the wrong entry point is set (the entry point was changed with devkitPro r20). Check for the ndstool call in your top-level Makefile. If there are parameters like -e7 ... and -r7 ..., remove them. Also make sure you're using the latest ndstool (i.e. the one that comes with DKP r20).


Right - I kinda suspected an ARM7 problem. I'm not able to use the standard set of Makefiles that were in the 'examples' package because this project runs under Windows and Linux PC as well as the NDS - but the script I use to convert an 'elf' binary into a '.nds' file is:

echo "Converting " $1 "(ELF)" to $2 "(NDS)..."
${DEVKITARM}/bin/arm-eabi-objcopy -O binary $1 $1.arm9
${DEVKITARM}/bin/ndstool -c $2 -9 $1.arm9

But that can't be it - none of the 'examples' programs produce sound or respond to the X/Y buttons either.

My setup has

/home/nds/devkitARM
/home/nds/devkitARM/libnds

...so I presume ndstool is finding whatever it needs OK (I don't see any error messages from it). My libnds came from downloading libnds-src-20070317.tar.bz2 and building it in the usual way by typing 'make' then 'make install'. Again, no errors were reported.

What exactly does ndstool actually do? Is there something I could search for in the '.nds' binary file that would verify whether the 'ARM7' code is present and at the correct version? Where is that code stored in libnds?

#123175 - 3D_geek - Sun Mar 25, 2007 9:48 pm

zzo38computer wrote:
Make START+SELECT if pushed simultaneously reset the game, and START by itself to pause.


Your wish is my command!

http://www.sjbaker.org/tmp/hardball.nds

START - toggle pause.
SELECT - cycle through camera positions
START+SELECT - reset
A - Accellerate
B - Brake
L/R - (Temporarily because I'm debugging something) Zoom In/Zoom Out
+ - Joystick.

#123434 - gabebear - Wed Mar 28, 2007 4:49 am

You can only do 2048 triangles per render pass, but you can combine multiple render passes into a single image with the DS's display capture. On the second pass you will lose the depth buffer, so you have to separate the foreground from the background(a.k.a. whatever you draw on the second pass will be on top of the first pass). Each pass takes a fixed time of 1/60th of a sec. I guess there should be a libnds example that demonstrates display capture. I'll put that on my to-do list; the example would need to be really well commented.

Using display capture to boost polygon count isn't trivial, you probably want to get more familiar with the DS hardware before playing with it.


Last edited by gabebear on Wed Mar 28, 2007 7:20 am; edited 2 times in total

#123440 - ikaris - Wed Mar 28, 2007 5:57 am

Nice job 3D_geek,

what did you use to export the 3D data ?

Are you using display lists or immediate mode ?

#123522 - 3D_geek - Wed Mar 28, 2007 8:44 pm

ikaris wrote:
what did you use to export the 3D data ?


The models were made in a mix of blender and AC3D (both under Linux) - I used my 'PLIB' library (http://plib.sf.net) to import the models (PLIB imports and exports a bunch of different formats) into a tool I wrote that writes the models out as a big heap of pre-initialised arrays and classes in C++ source code. The result is a 'scene graph' that you can compile into your sources and render just by calling the 'draw' method on any object in the scene. I have another tool I wrote to take images in '.rgb' or '.png' and chucks them out as preinitialised C++ structures. This allows all of the models and textures to be compiled into the code.

The constructor functions for objects in the scene graph and texture maps causes them to be 'registered' into a repository as the program starts up - then the game can 'fetch' objects by querying the repository with a text string.

The program runs under Linux/PC also - so I can debug more conveniently.

Quote:
Are you using display lists or immediate mode ?


It's in immediate mode - I should probably look into display lists - but right now it's running plenty fast enough so I'll attack other problems first. The biggest concerns right now are getting the ARM7 problem under control and figuring out what I'm going to do about the 2048 triangle limit.

The multipass solution to pushing up the polygon limit is tempting - but I like the smoothness of running at a solid 60Hz. For 'flying' games, 60Hz does a lot to improve the fluidity of the experience. If I can get my brain around texture memory bank allocation - I may do what MarioKart does and pre-render the players as sprites (at least at longer ranges). I'll figure something out.

#123570 - gabebear - Thu Mar 29, 2007 4:23 am

if you want to get more polys without limiting your frame-rate you need to look into using quads.

General run down on DS polygon limit:
~2000 triangles (strips or singles)
~1500 quads as singles
~1700 quads as strips

so drawing quads as quads instead of two triangles is 50% or more efficient.

Quads will not render correctly unless they are flat or reallllllly close to flat(like any other 3D card). I made a simple PLY to packed display list converter that works well with Blender http://ghearing.com/mtutorial/ . The converter doesn't make sure that quads are flat, so you have to make sure quads are actually flat in Blender, and it doesn't make strips. Strips would only increase efficiency by 13% at most (probably like 8% on average).

I noticed that the converter doesn't export normals correctly unless you export vertex colors as well, but I haven't fixed it yet.

#123571 - tepples - Thu Mar 29, 2007 4:27 am

But isn't the use of strips patented where a lot of us live?
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#123589 - kusma - Thu Mar 29, 2007 10:06 am

tepples wrote:
But isn't the use of strips patented where a lot of us live?


That patent can pretty much be considered useless. It was filed two years after the release of OpenGL 1.0, which already incorporated the concept. I'm sure there's other prior art out there.

#123592 - memoni - Thu Mar 29, 2007 12:02 pm

I cannot unfortunately test your game currently so I don't know exactly how your level is laid out, but one thing to fight against the polygon limit is to add some sort of space partitioning.

It can be as simple as dividing the world on a grid of cubes, then checking if some polygons touch a cube and then expanding the cube to be AABB of all the touched polygons. The polys are only added to one "cube". Continue until no polys left. Then at render time check if the AABB of the chunk if visible and only render the visible chunks.

Additionally you could make the game logic so that it tries to keep the number of carts within the poly limits but still keep the illusion of a lot of carts.

#123662 - 3D_geek - Fri Mar 30, 2007 1:00 am

kusma wrote:
tepples wrote:
But isn't the use of strips patented where a lot of us live?


That patent can pretty much be considered useless. It was filed two years after the release of OpenGL 1.0, which already incorporated the concept. I'm sure there's other prior art out there.


Yeah - there sure is. OpenGL is the successor to IrisGL - which was around since the start of SGI's graphics workstation line - which was around in 1982 or so. IrisGL has an API call 'bgntmesh' and 'bgnqstrip' that to tristrips and quadstrips respectively. I suspect there were strip-based systems around long before that - but it's harder to prove.

That patent is ignored by absolutely everyone - there is a ton of 'prior' art which renders it completely invalid.

#123666 - 3D_geek - Fri Mar 30, 2007 1:31 am

memoni wrote:
I cannot unfortunately test your game currently so I don't know exactly how your level is laid out, but one thing to fight against the polygon limit is to add some sort of space partitioning.

It can be as simple as dividing the world on a grid of cubes, then checking if some polygons touch a cube and then expanding the cube to be AABB of all the touched polygons. The polys are only added to one "cube". Continue until no polys left. Then at render time check if the AABB of the chunk if visible and only render the visible chunks.

Additionally you could make the game logic so that it tries to keep the number of carts within the poly limits but still keep the illusion of a lot of carts.


Yes - I'm very familiar with the issues involving field of view culling (I used to design flight simulator graphics for a living and I've twice designed and built my own 3D hardware with custom/semicustom silicon!) - but in this particular application, there is no way to prevent the eyepoint getting into a position in one corner of the play arena where every single object in the entire game world is in view at once. Since we have an utter hard limit on polygon count - one has to engineer for the worst case. In a normal graphics system, the worst that would happen would be that you'd drop frame rate occasionally...here, something much more drastic has to happen.

That means that there isn't a whole lot of point in doing field of view culling - which only improves the best case - unless you have some other mechanism to get rid of things that are far from the eye (you can't easily be close to everything at once - so that's one kind of "worst case" that can't ever happen. But that too is essentially out of the question because the game is set in a very confined arena and things never get very far from your eye (intentionally - because with the ultra-low screen resolution, you lose sight of things if they get too far away. I'll have to use a level of detail mechanism to drop the polygon counts of objects at longer ranges - along with a mechanism to render smaller objects in near-to-far order, simply dropping out the ones that push the polygon count over the magic limit. I may also have to consider hacking my AI to have enemy players stay away from the camera when the polygon counts start to climb too high.

Intelligent use of quadstrips is definitely something I need to look into - but even so, the gains are likely to be disappointing because only a fairly small proportion of my scene content is quad-strippable - and fifty percent of a small amount isn't worth a whole lot of implementation hassle (especially because a bunch of my models are going to be animated with skin/bones techniques so things that were planar quads when I modelled them may well bend into non-planar things at runtime.

Taking smaller and more distant objects and rendering them as 2D sprites is clearly a good idea (we know that's what Nintendo do in several of their games - but the limited amount of texture memory is going to make that painful too. Fortunately, the tiny display resolution works for us in that regard - nearly everything is 'small' on such a tiny screen.

#123724 - memoni - Fri Mar 30, 2007 5:47 pm

3D_Geek, that "everthing can be visible" was the bit I feared when I answered without seeing the game. I have only Mac at home currently and the cart I have has windows drivers only.

If you want to go for 2 pass rendering that kind of partitioning might help you to divide the two passes (front and back).

Btw, does someone know if backfacing polygons are culled before they are added to the vertex buffer? If not and you have some cycles to spare you might try to do a backface culling before drawing.

p.s. Do you happen to have any screenshots of your game?

#123738 - tepples - Fri Mar 30, 2007 7:44 pm

memoni wrote:
Btw, does someone know if backfacing polygons are culled before they are added to the vertex buffer?

They are. One of the 3D demos included with libnds examples shows how much RAM is being used, and the value changes based on the number of polygons that are facing forward.

Quote:
If not and you have some cycles to spare you might try to do a backface culling before drawing.

Software culling isn't so easy if you're using quad strips to save geometry RAM. For example, a deltoidal icosatetrahedron (a 24-quad Catalan approximation to the sphere) is six such strips, and a software backface culler would have to split strips to fit everything in.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#123753 - crossraleigh - Fri Mar 30, 2007 9:03 pm

Quote:
[...] unless you have some other mechanism to get rid of things that are far from the eye [...]

There is a hardware register that allows you to automatically cull distant polygons. GBATEK calls it DISP_1DOT_DEPTH, but it may be called something different in libnds.

Quote:
[...] a bunch of my models are going to be animated with skin/bones techniques so things that were planar quads when I modelled them may well bend into non-planar things at runtime.

You could just ignore polygons on a joint when finding quads on an animated model.

#123803 - 3D_geek - Sat Mar 31, 2007 7:15 am

Finding the problem with glTexImage2D solved a lot of my issues. By loading large textures first and then the smaller ones I'm able to avoid the texture wastage in libnds and because I now only use banks A and B, I seem to be somehow avoiding the problems I had previously with killing the ARM7 and corrupting the bottom screen.

So now I have three characters working - with on-screen help and such - and both helicopter and eagle are animated, mine karts are trundling around correctly....the eagle is flapping it's wings when it's working hard - and steering with it's tail feathers too. Press 'Y' to toggle between flying the 'pedalcopter guy' and the 'giant eagle gal'.

The guy with the jet pack is on the other team so you can't fly as him.

It's beginning to look cool!

http://www.sjbaker.org/tmp/hardball.nds


Last edited by 3D_geek on Sat Mar 31, 2007 9:19 am; edited 1 time in total

#123807 - 3D_geek - Sat Mar 31, 2007 9:15 am

memoni wrote:
p.s. Do you happen to have any screenshots of your game?


I have two shots of the PC version running at DS screen resolution (approximately):

http://www.sjbaker.org/tmp/screenshot.gif
http://www.sjbaker.org/tmp/screenshot2.gif