summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service/apt/bcfnt/bcfnt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/service/apt/bcfnt/bcfnt.cpp')
-rw-r--r--src/core/hle/service/apt/bcfnt/bcfnt.cpp71
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