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 > RAM and executable size

#62563 - Vich - Fri Dec 02, 2005 10:55 am

Since the NDS has only got 4MB of RAM: does it always try to load the full executable or does it stream/buffer the parts of it that it needs?

And if so: Can you convert your game assets to a C++ header file and just attach them to your executable? (which might make the executable very large).

#62583 - tepples - Fri Dec 02, 2005 6:22 pm

Vich wrote:
Since the NDS has only got 4MB of RAM: does it always try to load the full executable or does it stream/buffer the parts of it that it needs?

For WMB demos, the former. For games that need a DS card, the latter. For multiplayer games, either. When you boot a game from a DS card, or when you WMB a game's multiplayer client program, a .nds file is loaded into RAM. This .nds file can load other code or data into RAM by copying it from the DS card or by requesting it from the multiplayer server.

Quote:
And if so: Can you convert your game assets to a C++ header file

You probably meant "convert your game assets to source code". Don't put data in header files, and don't put code in header files unless it's a static inline function or an inline method.

Quote:
and just attach them to your executable? (which might make the executable very large).

Yes. You can use bin2s (which comes with devkitARM) to convert assets to assembly language files, which you can import into your program's ARM9 section. You can convert each asset separately, or you can toss them all into a GBFS file and convert them in one step.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#62626 - Vich - Sat Dec 03, 2005 3:29 am

I think I didn't formulate my question correct:
I know when or when you can stream game assets, but what I don't know is if you can actually stream the executable code from a game cartridge.

About bin2s:
Isn't it better to create 1 asset with it, that contains an archive like a ZIP-file? I've seen the GBFS members and the functionality seems really crappy.
What does "s" in "bin2s" stand for? That it is stored in SRAM if it would be a regular commercial DS cartridge?

#62630 - tepples - Sat Dec 03, 2005 5:24 am

Vich wrote:
I think I didn't formulate my question correct:
I know when or when you can stream game assets, but what I don't know is if you can actually stream the executable code from a game cartridge.

Executable code is just data. If you load another .nds file from the DS Game Card or the CF/SD card, then you can load executable code.

Quote:
About bin2s:
Isn't it better to create 1 asset with it, that contains an archive like a ZIP-file?

That's what GBFS is: an archive.

Quote:
I've seen the GBFS members and the functionality seems really crappy.

I don't really get what you're saying. What do you mean by "GBFS members" and what is "crappy" about them?

Quote:
What does "s" in "bin2s" stand for? That it is stored in SRAM if it would be a regular commercial DS cartridge?

s == .s, the file name suffix for assembly language source code
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#62635 - mymateo - Sat Dec 03, 2005 7:21 am

tepples wrote:
Don't put data in header files, and don't put code in header files unless it's a static inline function or an inline method.


I understand that it's bad form to put that stuff in header files, but I've never really understood why. Does it slow down the process of retrieving the information, make the resulting ROM larger, or what? (Forgive my ignorance, everything I know about C/C++ I learned from others' source mostly)

#62637 - DekuTree64 - Sat Dec 03, 2005 8:11 am

mymateo wrote:
I understand that it's bad form to put that stuff in header files, but I've never really understood why.

If your data is defined in the header, then every time you include that header in another file, it makes another copy of the data. If you put the data in a .c file, and only declare it as extern in the header, then you have a single copy that any file can reference.

Compiling large amounts of data as arrays is also insanely slow. I usually use .s files for their speed and simplicity (either straight numbers, or using .incbin to include raw data files), but GBFS is good too.

For small demos and things using .c arrays is fine though.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku

#62640 - mymateo - Sat Dec 03, 2005 8:47 am

Thanks, Deku. I never thought of that, but it makes so much sense now. You deserve a cookie. Or a beer, if that's more to your liking. :)

#62691 - Vich - Sun Dec 04, 2005 1:22 pm

tepples wrote:
Executable code is just data. If you load another .nds file from the DS Game Card or the CF/SD card, then you can load executable code.

True, but that means that 1 big executable of - let's say - 20MB doesn't get streamed automatically when you run it?

Quote:
About bin2s:
That's what GBFS is: an archive.
[...]
I don't really get what you're saying. What do you mean by "GBFS members" and what is "crappy" about them?

I know it's something like an archive, but the way that it's build is not really user-friendly. If you would use something like a zip-archive, there is immediately a lot of functionality available to the programmer to handle the data that it contains.
With GBFS members, I meant the functions like:
Code:

void gbfs_search_range(   u32 gbfs_1st_limit,
                  u32 gbfs_2nd_start, u32 gbfs_2nd_limit,
                  u32 gbfs_stride );

const GBFS_FILE * find_first_gbfs_file(const void *start);
const void *skip_gbfs_file(const GBFS_FILE * file);
const void *gbfs_get_obj(const GBFS_FILE *file,
                         const char *name,
                         u32 *len);
const void *gbfs_get_nth_obj(GBFS_FILE const * file,
                             size_t n,
                             char *name,
                             u32 *len);
void *gbfs_copy_obj(void *dst,
                    const GBFS_FILE *file,
                    const char *name);
size_t gbfs_count_objs(const GBFS_FILE *file);


With "crappy", I meant that it seems very low-level to use. And thus not user(coder)-friendly.

#62723 - agentq - Mon Dec 05, 2005 12:46 am

We're programming directly to the hardware, and so nothing happens 'automatically'. Memory is just one big block of RAM. If you want to stream an executable you need to write the code to do that.

You may be able to use virtual memory to load only part of an executable under an OS like Windows. But then PCs have hardware memory management and OS support which doesn't exist on the DS.

Gbfs works nicely as a simple way of getting some data into your program. What sort of simpler API would you have liked to see?

#62737 - tepples - Mon Dec 05, 2005 5:21 am

Vich wrote:
tepples wrote:
That's what GBFS is: an archive.
[...]
I don't really get what you're saying. What do you mean by "GBFS members" and what is "crappy" about them?

I know it's something like an archive, but the way that it's build is not really user-friendly.

Using Info-ZIP Zip:
zip file.zip foo.bin bar.chr baz.txt
vs. using GBFS:
gbfs file.gbfs foo.bin bar.chr baz.txt

Quote:
If you would use something like a zip-archive, there is immediately a lot of functionality available to the programmer to handle the data that it contains.

Thing about .zip is that it uses compression, which would require a lot more memory and a lot more time to load assets (especially on the GBA, which was RAM constrained), and it wouldn't work so well for a zipfile that's included into a program that is loaded into RAM (.mb or .nds) because you have to compress things anyway.

Quote:

With GBFS members, I meant the functions like:
Code:

void gbfs_search_range(   u32 gbfs_1st_limit,
                  u32 gbfs_2nd_start, u32 gbfs_2nd_limit,
                  u32 gbfs_stride );

const GBFS_FILE * find_first_gbfs_file(const void *start);
const void *skip_gbfs_file(const GBFS_FILE * file);

Those are for appended GBFS, which is valid only in .mb, .gba, or ds.gba programs.

Quote:
Code:
const void *gbfs_get_obj(const GBFS_FILE *file,
                         const char *name,
                         u32 *len);
const void *gbfs_get_nth_obj(GBFS_FILE const * file,
                             size_t n,
                             char *name,
                             u32 *len);
void *gbfs_copy_obj(void *dst,
                    const GBFS_FILE *file,
                    const char *name);
size_t gbfs_count_objs(const GBFS_FILE *file);


With "crappy", I meant that it seems very low-level to use. And thus not user(coder)-friendly.

I don't know much about DS mode (hence the "GB" in GBFS), but loading a mode 3 image in GBA mode is as easy as this, once you've found the GBFS file:
Code:
gbfs_copy_obj(VRAM, data, "title.mo3");

As agentq said, what higher level APIs would you like to see built on these? If they're feasible, I might add them to a future version of GBFS.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#62741 - Vich - Mon Dec 05, 2005 9:52 am

tepples:
What I'd like to see is that you could just use the iostream or FILE objects in respectively C and C++. As I understood folders wouldn't work, but that's not an issue. Then again, because of your info, I understand the API a bit better, thanks :)

#62788 - sajiimori - Mon Dec 05, 2005 7:18 pm

It wouldn't be very hard to make an istream that reads from GBFS. Why not try it out, Vich?

#62789 - GPFerror - Mon Dec 05, 2005 7:19 pm

iv just released a romdiskfs for the ds which has some stdio similair functions.

http://forum.gbadev.org/viewtopic.php?t=7695

Troy(GPF)

#62839 - Vich - Tue Dec 06, 2005 9:43 am

sajiimori wrote:
It wouldn't be very hard to make an istream that reads from GBFS. Why not try it out, Vich?


Hmmm good idea, but I'll probably go implement it in my streaming system, so it works with everything that uses my core library.

GPFerror wrote:
iv just released a romdiskfs for the ds which has some stdio similair functions.

http://forum.gbadev.org/viewtopic.php?t=7695

Troy(GPF)


Thanks :)