Homebrew Any way to include resources inside 3ds, 3dsx or CIA files?

cebolleto

Well-Known Member
OP
Member
Joined
Mar 5, 2010
Messages
203
Trophies
1
Age
43
XP
2,517
Country
So right now the only way I've seen on the 3ds to include the resources inside a binary is to turn then into arrays (using bin2cpp or similars). This has several problems like taking a lot of memory and being hard to maintain as the project grows

The current solution seems to be placing the files into a folder on the SD and then read from there. That's better and seems to work perfect for .3dsx (because the 3dsx must be placed in a specific directory for the homebrew launcher to list it). But for .3ds and .cias it is very annoying having to copy some files to the SD and the install the game from the microSD (on the gateway)

Isn't there anything like nitrofs for the DS?

Or just the address to place the resource file system will be enought (we could use zlib for example to read from a zip file)
 

Cyan

GBATemp's lurking knight
Former Staff
Joined
Oct 27, 2002
Messages
23,749
Trophies
4
Age
45
Location
Engine room, learning
XP
15,648
Country
France
I've read there's a way to append data at the end of the .3ds file.
You pack all your resources in zip and append it to the executable.

I just don't know how you access them from the sources.
You should ask in the main/stickied 3DS Homebrew development thread.
 
  • Like
Reactions: Margen67

The Real Jdbye

*is birb*
Member
Joined
Mar 17, 2010
Messages
23,254
Trophies
4
Location
Space
XP
13,809
Country
Norway
What do you do with the zeroes file?

Someone here appends a zip file at the end of the 3ds
http://4dsdev.org/thread.php?pid=79
problem is, how do I get the address of the zip file... and isn't that loaded into memory?
The easy way is to append the zip file, then append the size of the zip file. That way you can simply seek to the end, read the int containing the size, then seek back that number of bytes + 4 for the int.
No it obviously doesn't load the entire ROM into memory :P ROMs are normally much larger than the RAM of the 3DS can hold.
The best solution would be using RomFS, they can be generated but I don't know if there's anything in ctrulib to read them.
 
  • Like
Reactions: Cyan

Technicmaster0

Well-Known Member
Member
Joined
Oct 22, 2011
Messages
4,406
Trophies
2
Website
www.flashkarten.tk
XP
3,496
Country
Gambia, The
The easy way is to append the zip file, then append the size of the zip file. That way you can simply seek to the end, read the int containing the size, then seek back that number of bytes + 4 for the int.
No it obviously doesn't load the entire ROM into memory :P ROMs are normally much larger than the RAM of the 3DS can hold.
The best solution would be using RomFS, they can be generated but I don't know if there's anything in ctrulib to read them.
I think that the problem is that makerom doesn't handle ROMFS properly.
 

cebolleto

Well-Known Member
OP
Member
Joined
Mar 5, 2010
Messages
203
Trophies
1
Age
43
XP
2,517
Country
The easy way is to append the zip file, then append the size of the zip file. That way you can simply seek to the end, read the int containing the size, then seek back that number of bytes + 4 for the int.

The problem is that the 3ds is placed inside the micro SD on the Flashcard. I don't know if there is a way to access it so I can search for the .3ds that has been loaded and then locate the .zip inside.
But the approach you are suggesting is interesting.
 

The Real Jdbye

*is birb*
Member
Joined
Mar 17, 2010
Messages
23,254
Trophies
4
Location
Space
XP
13,809
Country
Norway
The problem is that the 3ds is placed inside the micro SD on the Flashcard. I don't know if there is a way to access it so I can search for the .3ds that has been loaded and then locate the .zip inside.
But the approach you are suggesting is interesting.
Yeah, you're right, that might be a problem. I didn't think of that.

There's definitely a way, since the 3DS loads the game as normal, not sure if it can be read like a regular cartridge though but it's worth a try.
Edit: SaveDataFiler seems able to read the cart like normal (apart from saves) so I think that should work.
 

cebolleto

Well-Known Member
OP
Member
Joined
Mar 5, 2010
Messages
203
Trophies
1
Age
43
XP
2,517
Country
So, after reading the documentation here http://3dbrew.org/wiki/FS:OpenFile I found that actually the functions for accessing the romfs are already implemented on libctru (services/fs.h)
I have created a very simple romfs with 3 files just to see if I can get access to it ( I have tried using -romfs with makerom and also using the field HostRoot inside the .rsf)
The code is very simple:

Code:
void romfsTest()
{
    FS_archive romfsArchive    = { ARCH_ROMFS, { PATH_EMPTY, 1, (u8*)"" } };
 
    Result rc = 0;
    rc = FSUSER_OpenArchive(NULL, &romfsArchive);
    if(rc == 0) {
        Handle fd;
        FS_path fs_path = { PATH_BINARY, 20, (u8*)"00000000000000000000" };
        rc = FSUSER_OpenFileDirectly(NULL, &fd, romfsArchive, fs_path, FS_OPEN_READ, FS_ATTRIBUTE_READONLY);
        if(rc == 0) {
            char data[1024];
            u32 bytesRead;
            rc = FSFILE_Read(fd, &bytesRead, 0, (u32*)data, (u32)1024);
            if(rc == 0) {
                printf("Data read:\n");
                printf("%s\n", data);
            } else {
                printf("FSFILE_Read failed(%x)\n", (int)rc);
            }
        } else {
            printf("FSUSER_OpenFile failed(%x)\n", (int)rc);
        }
    } else {
        printf("FSUSER_OpenArchive failed(%x)\n", (int)rc);
    }
}


But no matter what I try I am always getting 0xE0E046BE (EINVAL) when FSUSER_OpenFileDirectly is called
Could anyone give me a hand here? If we can make this work we could even implement a devoptab for romfs and access it using stdio functions
 

elhobbs

Well-Known Member
Member
Joined
Jul 28, 2008
Messages
1,044
Trophies
1
XP
3,030
Country
United States
So, after reading the documentation here http://3dbrew.org/wiki/FS:OpenFile I found that actually the functions for accessing the romfs are already implemented on libctru (services/fs.h)
I have created a very simple romfs with 3 files just to see if I can get access to it ( I have tried using -romfs with makerom and also using the field HostRoot inside the .rsf)
The code is very simple:

Code:
void romfsTest()
{
    FS_archive romfsArchive    = { ARCH_ROMFS, { PATH_EMPTY, 1, (u8*)"" } };
 
    Result rc = 0;
    rc = FSUSER_OpenArchive(NULL, &romfsArchive);
    if(rc == 0) {
        Handle fd;
        FS_path fs_path = { PATH_BINARY, 20, (u8*)"00000000000000000000" };
        rc = FSUSER_OpenFileDirectly(NULL, &fd, romfsArchive, fs_path, FS_OPEN_READ, FS_ATTRIBUTE_READONLY);
        if(rc == 0) {
            char data[1024];
            u32 bytesRead;
            rc = FSFILE_Read(fd, &bytesRead, 0, (u32*)data, (u32)1024);
            if(rc == 0) {
                printf("Data read:\n");
                printf("%s\n", data);
            } else {
                printf("FSFILE_Read failed(%x)\n", (int)rc);
            }
        } else {
            printf("FSUSER_OpenFile failed(%x)\n", (int)rc);
        }
    } else {
        printf("FSUSER_OpenArchive failed(%x)\n", (int)rc);
    }
}

But no matter what I try I am always getting 0xE0E046BE (EINVAL) when FSUSER_OpenFileDirectly is called
Could anyone give me a hand here? If we can make this work we could even implement a devoptab for romfs and access it using stdio functions
PATH_BINARY looks wrong. Shouldn't it be PATH_CHAR with a length of 21?
 

cebolleto

Well-Known Member
OP
Member
Joined
Mar 5, 2010
Messages
203
Trophies
1
Age
43
XP
2,517
Country
What is the difference?
Code:
u8        file_binary_lowpath[20]  = {};
    FS_path    romfs_path              = { PATH_BINARY, 20, file_binary_lowpath };
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
    SylverReZ @ SylverReZ: Sup