-
-
Notifications
You must be signed in to change notification settings - Fork 66
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
238d84b
commit 8c80099
Showing
8 changed files
with
204 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
// Copyright 2016 Citra Emulator Project | ||
// Licensed under GPLv2 or any later version | ||
// Refer to the license.txt file included. | ||
|
||
// Adapted from https://github.com/PabloMK7/citra/blob/master/src/core/hle/service/apt/bcfnt/bcfnt.h | ||
|
||
#pragma once | ||
|
||
#include <memory> | ||
|
||
#include "helpers.hpp" | ||
#include "swap.hpp" | ||
|
||
namespace HLE::Fonts { | ||
struct CFNT { | ||
u8 magic[4]; | ||
u16_le endianness; | ||
u16_le headerSize; | ||
u32_le version; | ||
u32_le fileSize; | ||
u32_le numBlocks; | ||
}; | ||
|
||
struct SectionHeader { | ||
u8 magic[4]; | ||
u32_le sectionSize; | ||
}; | ||
|
||
struct FINF { | ||
u8 magic[4]; | ||
u32_le sectionSize; | ||
u8 fontType; | ||
u8 lineFeed; | ||
u16_le alterCharIndex; | ||
u8 default_width[3]; | ||
u8 encoding; | ||
u32_le tglpOffset; | ||
u32_le cwdhOffset; | ||
u32_le cmapOffset; | ||
u8 height; | ||
u8 width; | ||
u8 ascent; | ||
u8 reserved; | ||
}; | ||
|
||
struct TGLP { | ||
u8 magic[4]; | ||
u32_le sectionSize; | ||
u8 cellWidth; | ||
u8 cellHeight; | ||
u8 baselinePosition; | ||
u8 maxCharacterWidth; | ||
u32_le sheetSize; | ||
u16_le numSheets; | ||
u16_le sheetImageFormat; | ||
u16_le numColumns; | ||
u16_le numRows; | ||
u16_le sheetWidth; | ||
u16_le sheetHeight; | ||
u32_le sheetDataOffset; | ||
}; | ||
|
||
struct CMAP { | ||
u8 magic[4]; | ||
u32_le sectionSize; | ||
u16_le codeBegin; | ||
u16_le codeEnd; | ||
u16_le mappingMethod; | ||
u16_le reserved; | ||
u32_le nextCmapOffset; | ||
}; | ||
|
||
struct CWDH { | ||
u8 magic[4]; | ||
u32_le sectionSize; | ||
u16_le startIndex; | ||
u16_le endIndex; | ||
u32_le nextCwdhOffset; | ||
}; | ||
|
||
// Relocates the internal addresses of the BCFNT Shared Font to the new base. The current base will | ||
// be auto-detected based on the file headers. | ||
void relocateSharedFont(u8* sharedFont, u32 newAddress); | ||
} // namespace HLE::Fonts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
// Copyright 2016 Citra Emulator Project | ||
// Licensed under GPLv2 or any later version | ||
// Refer to the license.txt file included. | ||
|
||
// Adapted from https://github.com/PabloMK7/citra/blob/master/src/core/hle/service/apt/bcfnt/bcfnt.cpp | ||
|
||
#include "services/fonts.hpp" | ||
|
||
namespace HLE::Fonts { | ||
void relocateSharedFont(u8* sharedFont, u32 newAddress) { | ||
constexpr u32 sharedFontStartOffset = 0x80; | ||
const u8* cfntData = &sharedFont[sharedFontStartOffset]; | ||
|
||
CFNT cfnt; | ||
std::memcpy(&cfnt, cfntData, sizeof(cfnt)); | ||
|
||
u32 assumedCmapOffset = 0; | ||
u32 assumedCwdhOffset = 0; | ||
u32 assumedTglpOffset = 0; | ||
u32 firstCmapOffset = 0; | ||
u32 firstCwdhOffset = 0; | ||
u32 firstTglpOffset = 0; | ||
|
||
// First discover the location of sections so that the rebase offset can be auto-detected | ||
u32 currentOffset = sharedFontStartOffset + cfnt.headerSize; | ||
for (uint block = 0; block < cfnt.numBlocks; ++block) { | ||
const u8* data = &sharedFont[currentOffset]; | ||
|
||
SectionHeader sectionHeader; | ||
std::memcpy(§ionHeader, data, sizeof(sectionHeader)); | ||
|
||
if (firstCmapOffset == 0 && std::memcmp(sectionHeader.magic, "CMAP", 4) == 0) { | ||
firstCmapOffset = currentOffset; | ||
} else if (firstCwdhOffset == 0 && std::memcmp(sectionHeader.magic, "CWDH", 4) == 0) { | ||
firstCwdhOffset = currentOffset; | ||
} else if (firstTglpOffset == 0 && std::memcmp(sectionHeader.magic, "TGLP", 4) == 0) { | ||
firstTglpOffset = currentOffset; | ||
} else if (std::memcmp(sectionHeader.magic, "FINF", 4) == 0) { | ||
Fonts::FINF finf; | ||
std::memcpy(&finf, data, sizeof(finf)); | ||
|
||
assumedCmapOffset = finf.cmapOffset - sizeof(SectionHeader); | ||
assumedCwdhOffset = finf.cwdhOffset - sizeof(SectionHeader); | ||
assumedTglpOffset = finf.tglpOffset - sizeof(SectionHeader); | ||
} | ||
|
||
currentOffset += sectionHeader.sectionSize; | ||
} | ||
|
||
u32 previousBase = assumedCmapOffset - firstCmapOffset; | ||
if ((previousBase != assumedCwdhOffset - firstCwdhOffset) || (previousBase != assumedTglpOffset - firstTglpOffset)) { | ||
Helpers::warn("You shouldn't be seeing this. Shared Font file offsets might be borked?"); | ||
} | ||
|
||
u32 offset = newAddress - previousBase; | ||
|
||
// Reset pointer back to start of sections and do the actual rebase | ||
currentOffset = sharedFontStartOffset + cfnt.headerSize; | ||
for (uint block = 0; block < cfnt.numBlocks; ++block) { | ||
u8* data = &sharedFont[currentOffset]; | ||
|
||
SectionHeader sectionHeader; | ||
std::memcpy(§ionHeader, data, sizeof(sectionHeader)); | ||
|
||
if (std::memcmp(sectionHeader.magic, "FINF", 4) == 0) { | ||
Fonts::FINF finf; | ||
std::memcpy(&finf, data, sizeof(finf)); | ||
|
||
// Relocate the offsets in the FINF section | ||
finf.cmapOffset += offset; | ||
finf.cwdhOffset += offset; | ||
finf.tglpOffset += offset; | ||
|
||
std::memcpy(data, &finf, sizeof(finf)); | ||
} else if (std::memcmp(sectionHeader.magic, "CMAP", 4) == 0) { | ||
Fonts::CMAP cmap; | ||
std::memcpy(&cmap, data, sizeof(cmap)); | ||
|
||
// Relocate the offsets in the CMAP section | ||
if (cmap.nextCmapOffset != 0) { | ||
cmap.nextCmapOffset += offset; | ||
} | ||
|
||
std::memcpy(data, &cmap, sizeof(cmap)); | ||
} else if (std::memcmp(sectionHeader.magic, "CWDH", 4) == 0) { | ||
Fonts::CWDH cwdh; | ||
std::memcpy(&cwdh, data, sizeof(cwdh)); | ||
|
||
// Relocate the offsets in the CWDH section | ||
if (cwdh.nextCwdhOffset != 0) { | ||
cwdh.nextCwdhOffset += offset; | ||
} | ||
|
||
std::memcpy(data, &cwdh, sizeof(cwdh)); | ||
} else if (std::memcmp(sectionHeader.magic, "TGLP", 4) == 0) { | ||
Fonts::TGLP tglp; | ||
std::memcpy(&tglp, data, sizeof(tglp)); | ||
|
||
// Relocate the offsets in the TGLP section | ||
tglp.sheetDataOffset += offset; | ||
std::memcpy(data, &tglp, sizeof(tglp)); | ||
} | ||
|
||
currentOffset += sectionHeader.sectionSize; | ||
} | ||
} | ||
} // namespace HLE::Fonts |
File renamed without changes.