1#![allow(non_snake_case)]
2use binrw::*;
3
4#[binrw]
5#[derive(Clone)]
6pub struct NRO {
7 pub start: NROStart,
8 pub header: NROHeader,
9 #[br(count(header.size - 0x80))]
10 pub data: Vec<u8>,
11 #[br(try)]
12 pub assets: Option<Assets>
13}
14
15#[binrw]
16#[derive(Clone, Copy)]
17pub struct NROStart {
18 pub unused: u32,
19 pub MOD0Offset: u32,
20 pub padding: [u8; 0x8],
21}
22
23#[binrw]
24#[br(magic=b"NRO0")]
25#[derive(Clone, Copy)]
26pub struct NROHeader {
27 pub version: u32, pub size: u32, pub flags: u32, pub textSegmentHeader: SegmentHeader,
31 pub roSegmentHeader: SegmentHeader,
32 pub dataSegmentHeader: SegmentHeader,
33 pub BssSize: u32,
34 pub reserved: [u8; 0x4],
35 pub ModuleID: [u8; 0x20],
36 pub DsoHandleOffset: u32, pub reserved_2: [u8; 0x4],
38 pub apiInfoSegmentHeader: SegmentHeader,
39 pub dynstrSegmentHeader: SegmentHeader,
40 pub dynsymSegmentHeader: SegmentHeader
41}
42
43#[binrw]
44#[derive(Clone, Copy)]
45pub struct SegmentHeader {
46 pub MemoryOffset: u32,
47 pub size: u32
48}
49
50#[binrw]
51#[derive(Clone)]
52pub struct Assets { pub assetHeader: AssetHeader,
54
55 #[br(offset = assetHeader.iconAssetSection.offset)]
56 #[br(if(assetHeader.iconAssetSection.size != 0))]
57 #[br(count(assetHeader.iconAssetSection.size))]
58 pub icon: Option<Vec<u8>>,
59
60 #[br(offset = assetHeader.nacpAssetSection.offset)]
61 #[br(if(assetHeader.nacpAssetSection.size != 0))]
62 #[br(count(assetHeader.nacpAssetSection.size))]
63 pub nacp: Option<Vec<u8>>,
64
65 #[br(offset = assetHeader.romfsAssetSection.offset)]
66 #[br(if(assetHeader.romfsAssetSection.size != 0))]
67 #[br(count(assetHeader.romfsAssetSection.size))]
68 pub romfs: Option<Vec<u8>>
69}
70
71#[binrw]
72#[br(magic=b"ASET")]
73#[derive(Clone, Copy)]
74pub struct AssetHeader {
75 pub version: u32,
76 pub iconAssetSection: AssetSection,
77 pub nacpAssetSection: AssetSection,
78 pub romfsAssetSection: AssetSection
79}
80
81#[binrw]
82#[derive(Clone, Copy)]
83pub struct AssetSection {
84 pub offset: u64,
85 pub size: u64
86}