/// Pretty-print formatting for parsed XEX2 structures. use crate::header::Xex2Header; use crate::optional::{ format_hex_bytes, format_rating, format_timestamp, HeaderKey, OptionalHeaders, }; /// Prints the XEX2 main header in a human-readable format. pub fn display_header(header: &Xex2Header) { println!("=== XEX2 Header ==="); println!("Magic: XEX2 (0x{:08X})", header.magic); println!("Module Flags: {}", header.module_flags); println!( "Header Size: 0x{:08X} ({} bytes)", header.header_size, header.header_size ); println!("Reserved: 0x{:08X}", header.reserved); println!("Security Offset: 0x{:08X}", header.security_offset); println!("Header Count: {}", header.header_count); } /// Prints all parsed optional headers in a human-readable format. pub fn display_optional_headers(headers: &OptionalHeaders) { println!(); println!("=== Optional Headers ({} entries) ===", headers.entries.len()); // Display inline u32 values first if let Some(v) = headers.entry_point { println!(); println!("[ENTRY_POINT] 0x{v:08X}"); } if let Some(v) = headers.original_base_address { println!("[ORIGINAL_BASE_ADDRESS] 0x{v:08X}"); } if let Some(v) = headers.image_base_address { println!("[IMAGE_BASE_ADDRESS] 0x{v:08X}"); } if let Some(v) = headers.default_stack_size { println!("[DEFAULT_STACK_SIZE] 0x{v:08X} ({v} bytes)"); } if let Some(v) = headers.default_filesystem_cache_size { println!("[DEFAULT_FILESYSTEM_CACHE_SIZE] 0x{v:08X} ({v} bytes)"); } if let Some(v) = headers.default_heap_size { println!("[DEFAULT_HEAP_SIZE] 0x{v:08X} ({v} bytes)"); } if let Some(v) = headers.title_workspace_size { println!("[TITLE_WORKSPACE_SIZE] 0x{v:08X} ({v} bytes)"); } if let Some(v) = headers.additional_title_memory { println!("[ADDITIONAL_TITLE_MEMORY] 0x{v:08X} ({v} bytes)"); } if let Some(v) = headers.enabled_for_fastcap { println!("[ENABLED_FOR_FASTCAP] 0x{v:08X}"); } // System flags if let Some(ref flags) = headers.system_flags { println!("[SYSTEM_FLAGS] {flags}"); } // Execution info if let Some(ref exec) = headers.execution_info { println!(); println!("[EXECUTION_INFO]"); println!(" Media ID: 0x{:08X}", exec.media_id); println!(" Title ID: 0x{:08X}", exec.title_id); println!(" Version: {}", exec.version); println!(" Base Version: {}", exec.base_version); println!(" Platform: {}", exec.platform); println!(" Executable Type: {}", exec.executable_type); println!(" Disc: {}/{}", exec.disc_number, exec.disc_count); println!(" Savegame ID: 0x{:08X}", exec.savegame_id); } // File format info if let Some(ref fmt) = headers.file_format_info { println!(); println!("[FILE_FORMAT_INFO]"); println!(" Encryption: {}", fmt.encryption_type); println!(" Compression: {}", fmt.compression_type); } // Checksum + timestamp if let Some(ref ct) = headers.checksum_timestamp { println!(); println!("[CHECKSUM_TIMESTAMP]"); println!(" Checksum: 0x{:08X}", ct.checksum); println!( " Timestamp: 0x{:08X} ({})", ct.timestamp, format_timestamp(ct.timestamp) ); } // Original PE name if let Some(ref name) = headers.original_pe_name { println!(); println!("[ORIGINAL_PE_NAME] \"{name}\""); } // Bounding path if let Some(ref path) = headers.bounding_path { println!("[BOUNDING_PATH] \"{path}\""); } // TLS info if let Some(ref tls) = headers.tls_info { println!(); println!("[TLS_INFO]"); println!(" Slot Count: {}", tls.slot_count); println!(" Raw Data Address: 0x{:08X}", tls.raw_data_address); println!(" Data Size: {} bytes", tls.data_size); println!(" Raw Data Size: {} bytes", tls.raw_data_size); } // Static libraries if let Some(ref libs) = headers.static_libraries { println!(); println!("[STATIC_LIBRARIES] ({} libraries)", libs.len()); for lib in libs { println!(" {lib}"); } } // Import libraries if let Some(ref imports) = headers.import_libraries { println!(); println!("[IMPORT_LIBRARIES] ({} libraries)", imports.libraries.len()); for lib in &imports.libraries { println!( " {} v{} (min v{}) - {} imports", lib.name, lib.version, lib.version_min, lib.record_count ); } } // Resource info if let Some(ref resources) = headers.resource_info { println!(); println!("[RESOURCE_INFO] ({} entries)", resources.len()); for res in resources { println!( " \"{}\" @ 0x{:08X}, size: {} bytes", res.name, res.address, res.size ); } } // Game ratings if let Some(ref ratings) = headers.game_ratings { println!(); println!("[GAME_RATINGS]"); println!(" ESRB: {} | PEGI: {} | PEGI-FI: {} | PEGI-PT: {}", format_rating(ratings.esrb), format_rating(ratings.pegi), format_rating(ratings.pegi_fi), format_rating(ratings.pegi_pt)); println!(" BBFC: {} | CERO: {} | USK: {} | OFLC-AU: {}", format_rating(ratings.bbfc), format_rating(ratings.cero), format_rating(ratings.usk), format_rating(ratings.oflc_au)); println!(" OFLC-NZ: {} | KMRB: {} | Brazil: {} | FPB: {}", format_rating(ratings.oflc_nz), format_rating(ratings.kmrb), format_rating(ratings.brazil), format_rating(ratings.fpb)); } // LAN key if let Some(ref key) = headers.lan_key { println!(); println!("[LAN_KEY] {}", format_hex_bytes(key)); } // Callcap imports if let Some(ref callcap) = headers.enabled_for_callcap { println!(); println!("[ENABLED_FOR_CALLCAP]"); println!(" Start Thunk: 0x{:08X}", callcap.start_func_thunk_addr); println!(" End Thunk: 0x{:08X}", callcap.end_func_thunk_addr); } // Exports by name if let Some(ref dir) = headers.exports_by_name { println!(); println!("[EXPORTS_BY_NAME]"); println!(" Offset: 0x{:08X}", dir.offset); println!(" Size: {} bytes", dir.size); } // Xbox 360 logo if let Some(size) = headers.xbox360_logo_size { println!(); println!("[XBOX360_LOGO] {size} bytes"); } // Unknown headers for entry in &headers.entries { if let HeaderKey::Unknown(raw) = entry.key { println!(); println!( "[UNKNOWN(0x{raw:08X})] value/offset: 0x{:08X}", entry.value ); } } }