3DS: Use system font for menus

This commit is contained in:
Jeffrey Pfau 2016-07-28 00:32:00 -07:00
parent 7930c5a350
commit 376c3e715e
6 changed files with 70 additions and 51 deletions

View File

@ -24,6 +24,7 @@ Misc:
- GBA Audio: Force audio DMAs to not increment destination
- Qt: Thread startup improvements
- 3DS: Port to using citro3D
- 3DS: Use system font for menus
0.4.1: (2016-07-11)
Bugfixes:

View File

@ -30,7 +30,6 @@ set(OS_DEFINES ${OS_DEFINES} PARENT_SCOPE)
list(APPEND GUI_SRC
${CMAKE_CURRENT_BINARY_DIR}/icons.c
${CMAKE_CURRENT_BINARY_DIR}/font.c
${CMAKE_CURRENT_BINARY_DIR}/uishader_g.c
${CMAKE_CURRENT_BINARY_DIR}/uishader_g.h
${CMAKE_CURRENT_BINARY_DIR}/uishader_g.shbin.h
@ -44,7 +43,6 @@ list(APPEND GUI_SRC
set_source_files_properties(
${CMAKE_CURRENT_BINARY_DIR}/icons.c
${CMAKE_CURRENT_BINARY_DIR}/font.c
${CMAKE_CURRENT_BINARY_DIR}/uishader_g.c
${CMAKE_CURRENT_BINARY_DIR}/uishader_g.h
${CMAKE_CURRENT_BINARY_DIR}/uishader_g.shbin.h
@ -65,10 +63,6 @@ add_custom_command(OUTPUT ${BINARY_NAME}.bnr
COMMAND ${BANNERTOOL} makebanner -i ${CMAKE_CURRENT_SOURCE_DIR}/logo.png -a ${CMAKE_CURRENT_SOURCE_DIR}/bios.wav -o ${BINARY_NAME}.bnr
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/logo.png ${CMAKE_CURRENT_SOURCE_DIR}/bios.wav)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/font.c
COMMAND ${RAW2C} ${CMAKE_SOURCE_DIR}/src/platform/3ds/font.raw
DEPENDS ${CMAKE_SOURCE_DIR}/src/platform/3ds/font.raw)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/icons.c
COMMAND ${RAW2C} ${CMAKE_SOURCE_DIR}/src/platform/3ds/icons.raw
DEPENDS ${CMAKE_SOURCE_DIR}/src/platform/3ds/icons.raw)

View File

@ -27,11 +27,12 @@ struct ctrUIVertex {
u32 abgr;
};
#define MAX_NUM_QUADS 1024
#define MAX_NUM_QUADS 2048
#define VERTEX_BUFFER_SIZE MAX_NUM_QUADS * sizeof(struct ctrUIVertex)
static struct ctrUIVertex* ctrVertexBuffer = NULL;
static u16 ctrNumQuads = 0;
static int ctrNumVerts = 0;
static int ctrVertStart = 0;
static C3D_Tex* activeTexture = NULL;
@ -70,12 +71,6 @@ bool ctrInitGpu() {
return false;
}
// Set up TexEnv and other parameters
C3D_TexEnv* env = C3D_GetTexEnv(0);
C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, GPU_PRIMARY_COLOR, 0);
C3D_TexEnvOp(env, C3D_Both, 0, 0, 0);
C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE);
C3D_CullFace(GPU_CULL_NONE);
C3D_DepthTest(false, GPU_ALWAYS, GPU_WRITE_ALL);
C3D_AlphaBlend(GPU_BLEND_ADD, GPU_BLEND_ADD, GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA);
@ -88,10 +83,6 @@ bool ctrInitGpu() {
AttrInfo_AddLoader(attrInfo, 1, GPU_SHORT, 4); // in_tc0
AttrInfo_AddLoader(attrInfo, 2, GPU_UNSIGNED_BYTE, 4); // in_col
C3D_BufInfo* bufInfo = C3D_GetBufInfo();
BufInfo_Init(bufInfo);
BufInfo_Add(bufInfo, ctrVertexBuffer, sizeof(struct ctrUIVertex), 3, 0x210);
return true;
}
@ -129,9 +120,20 @@ void ctrActivateTexture(C3D_Tex* texture) {
ctrFlushBatch();
}
C3D_TexBind(0, texture);
activeTexture = texture;
C3D_TexEnv* env = C3D_GetTexEnv(0);
C3D_TexEnvOp(env, C3D_Both, 0, 0, 0);
if (texture->fmt < GPU_LA8) {
C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, GPU_PRIMARY_COLOR, 0);
C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE);
} else {
C3D_TexEnvSrc(env, C3D_RGB, GPU_PRIMARY_COLOR, 0, 0);
C3D_TexEnvSrc(env, C3D_Alpha, GPU_TEXTURE0, GPU_PRIMARY_COLOR, 0);
C3D_TexEnvFunc(env, C3D_RGB, GPU_REPLACE);
C3D_TexEnvFunc(env, C3D_Alpha, GPU_MODULATE);
}
C3D_Mtx textureMtx = {
.m = {
// Rows are in the order w z y x, because ctrulib
@ -143,11 +145,14 @@ void ctrActivateTexture(C3D_Tex* texture) {
}
void ctrAddRectScaled(u32 color, s16 x, s16 y, s16 w, s16 h, s16 u, s16 v, s16 uw, s16 vh) {
if (ctrNumQuads == MAX_NUM_QUADS) {
if (ctrNumVerts + ctrVertStart == MAX_NUM_QUADS) {
ctrFlushBatch();
C3D_Flush();
ctrNumVerts = 0;
ctrVertStart = 0;
}
struct ctrUIVertex* vtx = &ctrVertexBuffer[ctrNumQuads];
struct ctrUIVertex* vtx = &ctrVertexBuffer[ctrVertStart + ctrNumVerts];
vtx->x = x;
vtx->y = y;
vtx->w = w;
@ -158,7 +163,7 @@ void ctrAddRectScaled(u32 color, s16 x, s16 y, s16 w, s16 h, s16 u, s16 v, s16 u
vtx->vh = vh;
vtx->abgr = color;
++ctrNumQuads;
++ctrNumVerts;
}
void ctrAddRect(u32 color, s16 x, s16 y, s16 u, s16 v, s16 w, s16 h) {
@ -166,13 +171,19 @@ void ctrAddRect(u32 color, s16 x, s16 y, s16 u, s16 v, s16 w, s16 h) {
}
void ctrFlushBatch(void) {
if (ctrNumQuads == 0) {
if (ctrNumVerts == 0) {
return;
}
GSPGPU_FlushDataCache(ctrVertexBuffer, VERTEX_BUFFER_SIZE);
C3D_DrawArrays(GPU_GEOMETRY_PRIM, 0, ctrNumQuads);
C3D_Flush();
C3D_TexBind(0, activeTexture);
ctrNumQuads = 0;
C3D_BufInfo* bufInfo = C3D_GetBufInfo();
BufInfo_Init(bufInfo);
BufInfo_Add(bufInfo, &ctrVertexBuffer[ctrVertStart], sizeof(struct ctrUIVertex), 3, 0x210);
GSPGPU_FlushDataCache(ctrVertexBuffer, VERTEX_BUFFER_SIZE);
C3D_DrawArrays(GPU_GEOMETRY_PRIM, 0, ctrNumVerts);
ctrVertStart += ctrNumVerts;
ctrNumVerts = 0;
}

Binary file not shown.

View File

@ -8,36 +8,43 @@
#include "util/png-io.h"
#include "util/vfs.h"
#include "icons.h"
#include "font.h"
#include "ctr-gpu.h"
#define CELL_HEIGHT 16
#define CELL_WIDTH 16
#define GLYPH_HEIGHT 12
#define FONT_SIZE 0.52f
struct GUIFont {
C3D_Tex texture;
C3D_Tex* sheets;
C3D_Tex icons;
};
struct GUIFont* GUIFontCreate(void) {
fontEnsureMapped();
struct GUIFont* guiFont = malloc(sizeof(struct GUIFont));
if (!guiFont) {
return 0;
}
C3D_Tex* tex;
C3D_Tex* tex = &guiFont->texture;
C3D_TexInitVRAM(tex, 256, 128, GPU_RGBA5551);
TGLP_s* glyphInfo = fontGetGlyphInfo();
guiFont->sheets = malloc(sizeof(*guiFont->sheets) * glyphInfo->nSheets);
GSPGPU_FlushDataCache(font, font_size);
GX_RequestDma((u32*) font, tex->data, font_size);
gspWaitForDMA();
int i;
for (i = 0; i < glyphInfo->nSheets; ++i) {
tex = &guiFont->sheets[i];
tex->data = fontGetGlyphSheetTex(i);
tex->fmt = glyphInfo->sheetFmt;
tex->size = glyphInfo->sheetSize;
tex->width = glyphInfo->sheetWidth;
tex->height = glyphInfo->sheetHeight;
tex->param = GPU_TEXTURE_MAG_FILTER(GPU_LINEAR) | GPU_TEXTURE_MIN_FILTER(GPU_LINEAR) | GPU_TEXTURE_WRAP_S(GPU_CLAMP_TO_EDGE) | GPU_TEXTURE_WRAP_T(GPU_CLAMP_TO_EDGE);
}
tex = &guiFont->icons;
C3D_TexInitVRAM(tex, 256, 64, GPU_RGBA5551);
GSPGPU_FlushDataCache(icons, icons_size);
GX_RequestDma((u32*) icons, tex->data, icons_size);
gspWaitForDMA();
@ -46,22 +53,24 @@ struct GUIFont* GUIFontCreate(void) {
}
void GUIFontDestroy(struct GUIFont* font) {
C3D_TexDelete(&font->texture);
free(font->sheets);
C3D_TexDelete(&font->icons);
free(font);
}
unsigned GUIFontHeight(const struct GUIFont* font) {
UNUSED(font);
return GLYPH_HEIGHT;
return fontGetInfo()->lineFeed * FONT_SIZE;
}
unsigned GUIFontGlyphWidth(const struct GUIFont* font, uint32_t glyph) {
UNUSED(font);
if (glyph > 0x7F) {
glyph = 0;
int index = fontGlyphIndexFromCodePoint(glyph);
charWidthInfo_s* info = fontGetCharWidthInfo(index);
if (info) {
return info->charWidth * FONT_SIZE;
}
return defaultFontMetrics[glyph].width;
return 0;
}
void GUIFontIconMetrics(const struct GUIFont* font, enum GUIIcon icon, unsigned* w, unsigned* h) {
@ -84,19 +93,21 @@ void GUIFontIconMetrics(const struct GUIFont* font, enum GUIIcon icon, unsigned*
}
void GUIFontDrawGlyph(const struct GUIFont* font, int glyph_x, int glyph_y, uint32_t color, uint32_t glyph) {
ctrActivateTexture(&font->texture);
int index = fontGlyphIndexFromCodePoint(glyph);
fontGlyphPos_s data;
fontCalcGlyphPos(&data, index, GLYPH_POS_CALC_VTXCOORD, 1.0, 1.0);
if (glyph > 0x7F) {
glyph = '?';
}
C3D_Tex* tex = &font->sheets[data.sheetIndex];
ctrActivateTexture(tex);
struct GUIFontGlyphMetric metric = defaultFontMetrics[glyph];
u16 x = glyph_x - metric.padding.left;
u16 y = glyph_y - GLYPH_HEIGHT;
u16 u = (glyph % 16u) * CELL_WIDTH;
u16 v = (glyph / 16u) * CELL_HEIGHT;
float width = data.texcoord.right - data.texcoord.left;
float height = data.texcoord.top - data.texcoord.bottom;
u16 x = glyph_x;
u16 y = glyph_y + tex->height * height / 8;
u16 u = tex->width * data.texcoord.left;
u16 v = tex->height * data.texcoord.bottom;
ctrAddRect(color, x, y, u, v, CELL_WIDTH, CELL_HEIGHT);
ctrAddRectScaled(color, x, y, tex->width * width * FONT_SIZE, tex->height * height * -FONT_SIZE, u, v, tex->width * width, tex->height * height);
}
void GUIFontDrawIcon(const struct GUIFont* font, int x, int y, enum GUIAlignment align, enum GUIOrientation orient, uint32_t color, enum GUIIcon icon) {

View File

@ -178,6 +178,8 @@ static void _drawStart(void) {
}
static void _drawEnd(void) {
ctrFlushBatch();
C3D_Flush();
C3D_RenderBufTransfer(&topScreen, (u32*) gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL), GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGB8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8));
C3D_RenderBufTransfer(&bottomScreen, (u32*) gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL), GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGB8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8));
gfxSwapBuffersGpu();