pd-3ds: Add sysfont loader
- add support for Alpha only textures in rendering
This commit is contained in:
@@ -28,5 +28,6 @@ SOFTWARE.
|
|||||||
#include <pd-3ds/bknd-hid.hpp>
|
#include <pd-3ds/bknd-hid.hpp>
|
||||||
|
|
||||||
namespace PD {
|
namespace PD {
|
||||||
|
PD::Li::Font::Ref LoadSystemFont();
|
||||||
void Init(void* data = nullptr);
|
void Init(void* data = nullptr);
|
||||||
}
|
} // namespace PD
|
||||||
@@ -82,6 +82,27 @@ int GetBPP(Li::Texture::Type type) {
|
|||||||
return 0; // Error
|
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() {
|
void GfxC3D::Init() {
|
||||||
VertexBuffer.resize(4 * 8192);
|
VertexBuffer.resize(4 * 8192);
|
||||||
IndexBuffer.resize(6 * 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);
|
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, pLocProjection, &proj);
|
||||||
// Mat4 proj = Mat4::Ortho(0.f, ViewPort.x, ViewPort.y, 0.f, 1.f, -1.f);
|
// 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_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;
|
size_t index = 0;
|
||||||
while (index < Commands.size()) {
|
while (index < Commands.size()) {
|
||||||
PD::Li::Texture::Ref Tex = Commands[index]->Tex;
|
PD::Li::Texture::Ref Tex = Commands[index]->Tex;
|
||||||
@@ -166,6 +182,7 @@ void GfxC3D::RenderDrawData(const std::vector<PD::Li::Command::Ref>& Commands) {
|
|||||||
} else {
|
} else {
|
||||||
C3D_SetScissor(GPU_SCISSOR_DISABLE, 0, 0, 0, 0);
|
C3D_SetScissor(GPU_SCISSOR_DISABLE, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
FragCfg(((C3D_Tex*)Tex->Address)->fmt);
|
||||||
BindTex(Tex->Address);
|
BindTex(Tex->Address);
|
||||||
auto bufInfo = C3D_GetBufInfo();
|
auto bufInfo = C3D_GetBufInfo();
|
||||||
BufInfo_Init(bufInfo);
|
BufInfo_Init(bufInfo);
|
||||||
|
|||||||
@@ -22,10 +22,106 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <3ds.h>
|
||||||
|
|
||||||
#include <palladium>
|
#include <palladium>
|
||||||
#include <pd-3ds.hpp>
|
#include <pd-3ds.hpp>
|
||||||
|
|
||||||
namespace PD {
|
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) {
|
void Init(void* data) {
|
||||||
// Dekstop Init Stage
|
// Dekstop Init Stage
|
||||||
// First use default OS Driver
|
// First use default OS Driver
|
||||||
|
|||||||
Reference in New Issue
Block a user