diff options
Diffstat (limited to 'src/core/hle/service/apt/bcfnt/bcfnt.cpp')
-rw-r--r-- | src/core/hle/service/apt/bcfnt/bcfnt.cpp | 71 |
1 files changed, 71 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 |