diff options
Diffstat (limited to 'src/core/hle/service/apt/bcfnt')
-rw-r--r-- | src/core/hle/service/apt/bcfnt/bcfnt.cpp | 71 | ||||
-rw-r--r-- | src/core/hle/service/apt/bcfnt/bcfnt.h | 87 |
2 files changed, 158 insertions, 0 deletions
diff --git a/src/core/hle/service/apt/bcfnt/bcfnt.cpp b/src/core/hle/service/apt/bcfnt/bcfnt.cpp new file mode 100644 index 000000000..b0d39d4a5 --- /dev/null +++ b/src/core/hle/service/apt/bcfnt/bcfnt.cpp @@ -0,0 +1,71 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/apt/bcfnt/bcfnt.h" +#include "core/hle/service/service.h" + +namespace Service { +namespace APT { +namespace BCFNT { + +void RelocateSharedFont(Kernel::SharedPtr<Kernel::SharedMemory> shared_font, VAddr previous_address, VAddr new_address) { + static const u32 SharedFontStartOffset = 0x80; + u8* data = shared_font->GetPointer(SharedFontStartOffset); + + CFNT cfnt; + memcpy(&cfnt, data, sizeof(cfnt)); + + // Advance past the header + data = shared_font->GetPointer(SharedFontStartOffset + cfnt.header_size); + + for (unsigned block = 0; block < cfnt.num_blocks; ++block) { + + u32 section_size = 0; + if (memcmp(data, "FINF", 4) == 0) { + BCFNT::FINF finf; + memcpy(&finf, data, sizeof(finf)); + section_size = finf.section_size; + + // Relocate the offsets in the FINF section + finf.cmap_offset += new_address - previous_address; + finf.cwdh_offset += new_address - previous_address; + finf.tglp_offset += new_address - previous_address; + + memcpy(data, &finf, sizeof(finf)); + } else if (memcmp(data, "CMAP", 4) == 0) { + BCFNT::CMAP cmap; + memcpy(&cmap, data, sizeof(cmap)); + section_size = cmap.section_size; + + // Relocate the offsets in the CMAP section + cmap.next_cmap_offset += new_address - previous_address; + + memcpy(data, &cmap, sizeof(cmap)); + } else if (memcmp(data, "CWDH", 4) == 0) { + BCFNT::CWDH cwdh; + memcpy(&cwdh, data, sizeof(cwdh)); + section_size = cwdh.section_size; + + // Relocate the offsets in the CWDH section + cwdh.next_cwdh_offset += new_address - previous_address; + + memcpy(data, &cwdh, sizeof(cwdh)); + } else if (memcmp(data, "TGLP", 4) == 0) { + BCFNT::TGLP tglp; + memcpy(&tglp, data, sizeof(tglp)); + section_size = tglp.section_size; + + // Relocate the offsets in the TGLP section + tglp.sheet_data_offset += new_address - previous_address; + + memcpy(data, &tglp, sizeof(tglp)); + } + + data += section_size; + } +} + +} // namespace BCFNT +} // namespace APT +} // namespace Service
\ No newline at end of file diff --git a/src/core/hle/service/apt/bcfnt/bcfnt.h b/src/core/hle/service/apt/bcfnt/bcfnt.h new file mode 100644 index 000000000..388c6bea0 --- /dev/null +++ b/src/core/hle/service/apt/bcfnt/bcfnt.h @@ -0,0 +1,87 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "common/swap.h" + +#include "core/hle/kernel/shared_memory.h" +#include "core/hle/service/service.h" + +namespace Service { +namespace APT { +namespace BCFNT { ///< BCFNT Shared Font file structures + +struct CFNT { + u8 magic[4]; + u16_le endianness; + u16_le header_size; + u32_le version; + u32_le file_size; + u32_le num_blocks; +}; + +struct FINF { + u8 magic[4]; + u32_le section_size; + u8 font_type; + u8 line_feed; + u16_le alter_char_index; + u8 default_width[3]; + u8 encoding; + u32_le tglp_offset; + u32_le cwdh_offset; + u32_le cmap_offset; + u8 height; + u8 width; + u8 ascent; + u8 reserved; +}; + +struct TGLP { + u8 magic[4]; + u32_le section_size; + u8 cell_width; + u8 cell_height; + u8 baseline_position; + u8 max_character_width; + u32_le sheet_size; + u16_le num_sheets; + u16_le sheet_image_format; + u16_le num_columns; + u16_le num_rows; + u16_le sheet_width; + u16_le sheet_height; + u32_le sheet_data_offset; +}; + +struct CMAP { + u8 magic[4]; + u32_le section_size; + u16_le code_begin; + u16_le code_end; + u16_le mapping_method; + u16_le reserved; + u32_le next_cmap_offset; +}; + +struct CWDH { + u8 magic[4]; + u32_le section_size; + u16_le start_index; + u16_le end_index; + u32_le next_cwdh_offset; +}; + +/** + * Relocates the internal addresses of the BCFNT Shared Font to the new base. + * @param shared_font SharedMemory object that contains the Shared Font + * @param previous_address Previous address at which the offsets in the structure were based. + * @param new_address New base for the offsets in the structure. + */ +void RelocateSharedFont(Kernel::SharedPtr<Kernel::SharedMemory> shared_font, VAddr previous_address, VAddr new_address); + +} // namespace BCFNT +} // namespace APT +} // namespace Service |