diff --git a/backends/3ds/include/pd-3ds.hpp b/backends/3ds/include/pd-3ds.hpp index 06eb03b..9ffd6d7 100755 --- a/backends/3ds/include/pd-3ds.hpp +++ b/backends/3ds/include/pd-3ds.hpp @@ -28,5 +28,6 @@ SOFTWARE. #include namespace PD { +PD::Li::Font::Ref LoadSystemFont(); void Init(void* data = nullptr); -} \ No newline at end of file +} // namespace PD \ No newline at end of file diff --git a/backends/3ds/source/bknd-gfx.cpp b/backends/3ds/source/bknd-gfx.cpp index 0c891bf..9205889 100755 --- a/backends/3ds/source/bknd-gfx.cpp +++ b/backends/3ds/source/bknd-gfx.cpp @@ -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& 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& 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); diff --git a/backends/3ds/source/pd-3ds.cpp b/backends/3ds/source/pd-3ds.cpp index 5a293e4..419883f 100755 --- a/backends/3ds/source/pd-3ds.cpp +++ b/backends/3ds/source/pd-3ds.cpp @@ -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 #include 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 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