pd-3ds: Add sysfont loader

- add support for Alpha only textures in rendering
This commit is contained in:
2025-12-19 21:07:57 +01:00
parent 1e35dbd743
commit 4ad00cd2be
3 changed files with 120 additions and 6 deletions

View File

@@ -28,5 +28,6 @@ SOFTWARE.
#include <pd-3ds/bknd-hid.hpp>
namespace PD {
PD::Li::Font::Ref LoadSystemFont();
void Init(void* data = nullptr);
}
} // namespace PD

View File

@@ -82,6 +82,27 @@ int GetBPP(Li::Texture::Type type) {
return 0; // Error
}
void FragCfg(GPU_TEXCOLOR clr) {
C3D_DepthTest(false, GPU_GREATER, GPU_WRITE_ALL);
C3D_TexEnv* env = C3D_GetTexEnv(0);
C3D_TexEnvInit(env);
switch (clr) {
case GPU_A4:
case GPU_A8:
case GPU_L4:
case GPU_L8:
C3D_TexEnvSrc(env, C3D_Alpha, GPU_TEXTURE0);
C3D_TexEnvFunc(env, C3D_RGB, GPU_REPLACE);
C3D_TexEnvFunc(env, C3D_Alpha, GPU_MODULATE);
break;
default:
C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0);
C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE);
break;
}
}
void GfxC3D::Init() {
VertexBuffer.resize(4 * 8192);
IndexBuffer.resize(6 * 8192);
@@ -129,11 +150,6 @@ void GfxC3D::RenderDrawData(const std::vector<PD::Li::Command::Ref>& Commands) {
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, pLocProjection, &proj);
// Mat4 proj = Mat4::Ortho(0.f, ViewPort.x, ViewPort.y, 0.f, 1.f, -1.f);
// C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, pLocProjection, (C3D_Mtx*)&proj);
C3D_DepthTest(false, GPU_GREATER, GPU_WRITE_ALL);
C3D_TexEnv* env = C3D_GetTexEnv(0);
C3D_TexEnvInit(env);
C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0);
C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE);
size_t index = 0;
while (index < Commands.size()) {
PD::Li::Texture::Ref Tex = Commands[index]->Tex;
@@ -166,6 +182,7 @@ void GfxC3D::RenderDrawData(const std::vector<PD::Li::Command::Ref>& Commands) {
} else {
C3D_SetScissor(GPU_SCISSOR_DISABLE, 0, 0, 0, 0);
}
FragCfg(((C3D_Tex*)Tex->Address)->fmt);
BindTex(Tex->Address);
auto bufInfo = C3D_GetBufInfo();
BufInfo_Init(bufInfo);

View File

@@ -22,10 +22,106 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include <3ds.h>
#include <palladium>
#include <pd-3ds.hpp>
namespace PD {
PD::Li::Font::Ref LoadSystemFont() {
TT::Scope st("LI_SystemFont"); // Trace loading time
Li::Font::Ref ret = Li::Font::New();
fontEnsureMapped(); // Call this to be sure the font is mapped
// Get some const references for system font loading
const auto fnt = fontGetSystemFont();
const auto fnt_info = fontGetInfo(fnt);
const auto glyph_info = fontGetGlyphInfo(fnt);
// Resize the Texture list by the num of sysfont textures
ret->Textures.resize(glyph_info->nSheets + 1);
/// Modify the Pixel Height by 1.1f to fit the
/// Size og ttf font Rendering
ret->PixelHeight = glyph_info->cellHeight;
// Load the Textures and make sure they don't auto unload
for (size_t i = 0; i < glyph_info->nSheets; i++) {
auto stex = Li::Texture::New();
auto tx = new C3D_Tex;
tx->data = fontGetGlyphSheetTex(fnt, i);
tx->fmt = (GPU_TEXCOLOR)glyph_info->sheetFmt;
tx->size = glyph_info->sheetSize;
tx->width = glyph_info->sheetWidth;
tx->height = glyph_info->sheetHeight;
tx->param = GPU_TEXTURE_MAG_FILTER(GPU_LINEAR) |
GPU_TEXTURE_MIN_FILTER(GPU_LINEAR) |
GPU_TEXTURE_WRAP_S(GPU_REPEAT) | GPU_TEXTURE_WRAP_T(GPU_REPEAT);
tx->border = 0xffffffff;
tx->lodParam = 0;
stex->Address = (Li::TexAddress)tx;
stex->Size = fvec2(tx->width, tx->height);
stex->UV = fvec4(0, 1, 1, 0);
ret->Textures[i] = stex;
}
std::vector<unsigned int> charSet;
// Write the Charset into a vector
for (auto cmap = fnt_info->cmap; cmap; cmap = cmap->next) {
if (cmap->mappingMethod == CMAP_TYPE_DIRECT) {
if (cmap->codeEnd >= cmap->codeBegin) {
charSet.reserve(charSet.size() + cmap->codeEnd - cmap->codeBegin + 1);
for (auto i = cmap->codeBegin; i <= cmap->codeEnd; ++i) {
if (cmap->indexOffset + (i - cmap->codeBegin) == 0xFFFF) break;
charSet.emplace_back(i);
}
}
} else if (cmap->mappingMethod == CMAP_TYPE_TABLE) {
if (cmap->codeEnd >= cmap->codeBegin) {
charSet.reserve(charSet.size() + cmap->codeEnd - cmap->codeBegin + 1);
for (auto i = cmap->codeBegin; i <= cmap->codeEnd; ++i) {
if (cmap->indexTable[i - cmap->codeBegin] == 0xFFFF) continue;
charSet.emplace_back(i);
}
}
} else if (cmap->mappingMethod == CMAP_TYPE_SCAN) {
charSet.reserve(charSet.size() + cmap->nScanEntries);
for (unsigned i = 0; i < cmap->nScanEntries; ++i) {
if (cmap->scanEntries[i].code >= cmap->codeBegin &&
cmap->scanEntries[i].code <= cmap->codeEnd) {
if (cmap->scanEntries[i].glyphIndex != 0xFFFF) {
charSet.emplace_back(cmap->scanEntries[i].code);
}
}
}
} else {
continue;
}
}
// Sort the charset and make sure all values are unique
std::sort(charSet.begin(), charSet.end());
charSet.erase(std::unique(charSet.begin(), charSet.end()));
// Setup the Codepoint map by the charset
for (auto cp : charSet) {
int gidx = fontGlyphIndexFromCodePoint(fnt, cp);
if (gidx >= 0xFFFF) continue;
Li::Font::Codepoint codepoint;
fontGlyphPos_s dat;
fontCalcGlyphPos(&dat, fnt, gidx, GLYPH_POS_CALC_VTXCOORD, 1.f, 1.f);
codepoint.pCodepoint = cp;
codepoint.SimpleUV = fvec4(dat.texcoord.left, dat.texcoord.top,
dat.texcoord.right, dat.texcoord.bottom);
if (dat.sheetIndex < (int)ret->Textures.size()) {
codepoint.Tex = ret->Textures[dat.sheetIndex];
} else {
codepoint.pInvalid = true;
}
codepoint.Size = fvec2(dat.vtxcoord.right, dat.vtxcoord.bottom);
codepoint.Offset = 0;
ret->CodeMap[cp] = codepoint;
}
return ret;
}
void Init(void* data) {
// Dekstop Init Stage
// First use default OS Driver