mirror of
https://github.com/switchbrew/switch-tools.git
synced 2025-08-07 01:09:22 +02:00
Append custom data to the end of NRO for storing assets.
This commit is contained in:
parent
2bfd935f4a
commit
3d8238e1d5
100
src/elf2nro.c
100
src/elf2nro.c
@ -34,6 +34,19 @@ typedef struct {
|
|||||||
u8 Padding[0x20];
|
u8 Padding[0x20];
|
||||||
} NroHeader;
|
} NroHeader;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u64 offset;
|
||||||
|
u64 size;
|
||||||
|
} AssetSection;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u8 magic[4];
|
||||||
|
u32 version;
|
||||||
|
AssetSection icon;
|
||||||
|
AssetSection nacp;
|
||||||
|
AssetSection romfs;
|
||||||
|
} AssetHeader;
|
||||||
|
|
||||||
uint8_t* ReadEntireFile(const char* fn, size_t* len_out) {
|
uint8_t* ReadEntireFile(const char* fn, size_t* len_out) {
|
||||||
FILE* fd = fopen(fn, "rb");
|
FILE* fd = fopen(fn, "rb");
|
||||||
if (fd == NULL)
|
if (fd == NULL)
|
||||||
@ -61,8 +74,12 @@ uint8_t* ReadEntireFile(const char* fn, size_t* len_out) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
if (argc != 3) {
|
if (argc < 3) {
|
||||||
fprintf(stderr, "%s <elf-file> <nro-file>\n", argv[0]);
|
fprintf(stderr, "%s <elf-file> <nro-file> [options]\n\n", argv[0]);
|
||||||
|
fprintf(stderr, "Options:\n");
|
||||||
|
fprintf(stderr, "--icon=<iconpath> Embeds icon into the output file.\n");
|
||||||
|
fprintf(stderr, "--nacp=<control.nacp> Embeds control.nacp into the output file.\n");
|
||||||
|
fprintf(stderr, "--romfs=<image> Embeds RomFS into the output file.\n");//TODO: Use directory for input instead.
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,6 +102,14 @@ int main(int argc, char* argv[]) {
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int argi;
|
||||||
|
char* icon_path = NULL, *nacp_path = NULL, *romfs_path = NULL;
|
||||||
|
for (argi=3; argi<argc; argi++) {
|
||||||
|
if (strncmp(argv[argi], "--icon=", 7)==0) icon_path = &argv[argi][7];
|
||||||
|
if (strncmp(argv[argi], "--nacp=", 7)==0) nacp_path = &argv[argi][7];
|
||||||
|
if (strncmp(argv[argi], "--romfs=", 8)==0) romfs_path = &argv[argi][8];
|
||||||
|
}
|
||||||
|
|
||||||
if (elf_len < sizeof(Elf64_Ehdr)) {
|
if (elf_len < sizeof(Elf64_Ehdr)) {
|
||||||
fprintf(stderr, "Input file doesn't fit ELF header!\n");
|
fprintf(stderr, "Input file doesn't fit ELF header!\n");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
@ -167,5 +192,76 @@ int main(int argc, char* argv[]) {
|
|||||||
fseek(out, sizeof(nro_start), SEEK_SET);
|
fseek(out, sizeof(nro_start), SEEK_SET);
|
||||||
fwrite(&nro_hdr, sizeof(nro_hdr), 1, out);
|
fwrite(&nro_hdr, sizeof(nro_hdr), 1, out);
|
||||||
|
|
||||||
|
if (icon_path==NULL && nacp_path==NULL && romfs_path==NULL) {
|
||||||
|
fclose(out);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetHeader asset_hdr;
|
||||||
|
memset(&asset_hdr, 0, sizeof(asset_hdr));
|
||||||
|
memcpy(asset_hdr.magic, "ASET", 4);
|
||||||
|
asset_hdr.version = 0;
|
||||||
|
|
||||||
|
fseek(out, file_off, SEEK_SET);
|
||||||
|
|
||||||
|
uint8_t* icon = NULL, *nacp = NULL, *romfs = NULL;
|
||||||
|
size_t icon_len = 0, nacp_len = 0, romfs_len = 0;
|
||||||
|
size_t tmp_off = sizeof(asset_hdr);
|
||||||
|
|
||||||
|
if (icon_path) {
|
||||||
|
icon = ReadEntireFile(icon_path, &icon_len);
|
||||||
|
if (icon == NULL) {
|
||||||
|
fprintf(stderr, "Failed to open input icon!\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
asset_hdr.icon.offset = tmp_off;
|
||||||
|
asset_hdr.icon.size = icon_len;
|
||||||
|
tmp_off+= icon_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nacp_path) {
|
||||||
|
nacp = ReadEntireFile(nacp_path, &nacp_len);
|
||||||
|
if (nacp == NULL) {
|
||||||
|
fprintf(stderr, "Failed to open input nacp!\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
asset_hdr.nacp.offset = tmp_off;
|
||||||
|
asset_hdr.nacp.size = nacp_len;
|
||||||
|
tmp_off+= nacp_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (romfs_path) {
|
||||||
|
romfs = ReadEntireFile(romfs_path, &romfs_len);
|
||||||
|
if (romfs == NULL) {
|
||||||
|
fprintf(stderr, "Failed to open input romfs!\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
asset_hdr.romfs.offset = tmp_off;
|
||||||
|
asset_hdr.romfs.size = romfs_len;
|
||||||
|
tmp_off+= romfs_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
fwrite(&asset_hdr, sizeof(asset_hdr), 1, out);
|
||||||
|
|
||||||
|
if (icon_path) {
|
||||||
|
fseek(out, file_off + asset_hdr.icon.offset, SEEK_SET);
|
||||||
|
fwrite(icon, icon_len, 1, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nacp_path) {
|
||||||
|
fseek(out, file_off + asset_hdr.nacp.offset, SEEK_SET);
|
||||||
|
fwrite(nacp, nacp_len, 1, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (romfs_path) {
|
||||||
|
fseek(out, file_off + asset_hdr.romfs.offset, SEEK_SET);
|
||||||
|
fwrite(romfs, romfs_len, 1, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(out);
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user