mirror of https://github.com/mgba-emu/mgba.git
3DS: Use system font for menus
This commit is contained in:
parent
7930c5a350
commit
376c3e715e
1
CHANGES
1
CHANGES
|
@ -24,6 +24,7 @@ Misc:
|
||||||
- GBA Audio: Force audio DMAs to not increment destination
|
- GBA Audio: Force audio DMAs to not increment destination
|
||||||
- Qt: Thread startup improvements
|
- Qt: Thread startup improvements
|
||||||
- 3DS: Port to using citro3D
|
- 3DS: Port to using citro3D
|
||||||
|
- 3DS: Use system font for menus
|
||||||
|
|
||||||
0.4.1: (2016-07-11)
|
0.4.1: (2016-07-11)
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
|
|
|
@ -30,7 +30,6 @@ set(OS_DEFINES ${OS_DEFINES} PARENT_SCOPE)
|
||||||
|
|
||||||
list(APPEND GUI_SRC
|
list(APPEND GUI_SRC
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/icons.c
|
${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.c
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/uishader_g.h
|
${CMAKE_CURRENT_BINARY_DIR}/uishader_g.h
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/uishader_g.shbin.h
|
${CMAKE_CURRENT_BINARY_DIR}/uishader_g.shbin.h
|
||||||
|
@ -44,7 +43,6 @@ list(APPEND GUI_SRC
|
||||||
|
|
||||||
set_source_files_properties(
|
set_source_files_properties(
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/icons.c
|
${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.c
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/uishader_g.h
|
${CMAKE_CURRENT_BINARY_DIR}/uishader_g.h
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/uishader_g.shbin.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
|
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)
|
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
|
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/icons.c
|
||||||
COMMAND ${RAW2C} ${CMAKE_SOURCE_DIR}/src/platform/3ds/icons.raw
|
COMMAND ${RAW2C} ${CMAKE_SOURCE_DIR}/src/platform/3ds/icons.raw
|
||||||
DEPENDS ${CMAKE_SOURCE_DIR}/src/platform/3ds/icons.raw)
|
DEPENDS ${CMAKE_SOURCE_DIR}/src/platform/3ds/icons.raw)
|
||||||
|
|
|
@ -27,11 +27,12 @@ struct ctrUIVertex {
|
||||||
u32 abgr;
|
u32 abgr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_NUM_QUADS 1024
|
#define MAX_NUM_QUADS 2048
|
||||||
#define VERTEX_BUFFER_SIZE MAX_NUM_QUADS * sizeof(struct ctrUIVertex)
|
#define VERTEX_BUFFER_SIZE MAX_NUM_QUADS * sizeof(struct ctrUIVertex)
|
||||||
|
|
||||||
static struct ctrUIVertex* ctrVertexBuffer = NULL;
|
static struct ctrUIVertex* ctrVertexBuffer = NULL;
|
||||||
static u16 ctrNumQuads = 0;
|
static int ctrNumVerts = 0;
|
||||||
|
static int ctrVertStart = 0;
|
||||||
|
|
||||||
static C3D_Tex* activeTexture = NULL;
|
static C3D_Tex* activeTexture = NULL;
|
||||||
|
|
||||||
|
@ -70,12 +71,6 @@ bool ctrInitGpu() {
|
||||||
return false;
|
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_CullFace(GPU_CULL_NONE);
|
||||||
C3D_DepthTest(false, GPU_ALWAYS, GPU_WRITE_ALL);
|
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);
|
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, 1, GPU_SHORT, 4); // in_tc0
|
||||||
AttrInfo_AddLoader(attrInfo, 2, GPU_UNSIGNED_BYTE, 4); // in_col
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,9 +120,20 @@ void ctrActivateTexture(C3D_Tex* texture) {
|
||||||
ctrFlushBatch();
|
ctrFlushBatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
C3D_TexBind(0, texture);
|
|
||||||
activeTexture = 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 = {
|
C3D_Mtx textureMtx = {
|
||||||
.m = {
|
.m = {
|
||||||
// Rows are in the order w z y x, because ctrulib
|
// 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) {
|
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();
|
ctrFlushBatch();
|
||||||
|
C3D_Flush();
|
||||||
|
ctrNumVerts = 0;
|
||||||
|
ctrVertStart = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ctrUIVertex* vtx = &ctrVertexBuffer[ctrNumQuads];
|
struct ctrUIVertex* vtx = &ctrVertexBuffer[ctrVertStart + ctrNumVerts];
|
||||||
vtx->x = x;
|
vtx->x = x;
|
||||||
vtx->y = y;
|
vtx->y = y;
|
||||||
vtx->w = w;
|
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->vh = vh;
|
||||||
vtx->abgr = color;
|
vtx->abgr = color;
|
||||||
|
|
||||||
++ctrNumQuads;
|
++ctrNumVerts;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ctrAddRect(u32 color, s16 x, s16 y, s16 u, s16 v, s16 w, s16 h) {
|
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) {
|
void ctrFlushBatch(void) {
|
||||||
if (ctrNumQuads == 0) {
|
if (ctrNumVerts == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GSPGPU_FlushDataCache(ctrVertexBuffer, VERTEX_BUFFER_SIZE);
|
C3D_TexBind(0, activeTexture);
|
||||||
C3D_DrawArrays(GPU_GEOMETRY_PRIM, 0, ctrNumQuads);
|
|
||||||
C3D_Flush();
|
|
||||||
|
|
||||||
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.
|
@ -8,36 +8,43 @@
|
||||||
#include "util/png-io.h"
|
#include "util/png-io.h"
|
||||||
#include "util/vfs.h"
|
#include "util/vfs.h"
|
||||||
#include "icons.h"
|
#include "icons.h"
|
||||||
#include "font.h"
|
|
||||||
|
|
||||||
#include "ctr-gpu.h"
|
#include "ctr-gpu.h"
|
||||||
|
|
||||||
#define CELL_HEIGHT 16
|
#define CELL_HEIGHT 16
|
||||||
#define CELL_WIDTH 16
|
#define CELL_WIDTH 16
|
||||||
#define GLYPH_HEIGHT 12
|
#define FONT_SIZE 0.52f
|
||||||
|
|
||||||
struct GUIFont {
|
struct GUIFont {
|
||||||
C3D_Tex texture;
|
C3D_Tex* sheets;
|
||||||
C3D_Tex icons;
|
C3D_Tex icons;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GUIFont* GUIFontCreate(void) {
|
struct GUIFont* GUIFontCreate(void) {
|
||||||
|
fontEnsureMapped();
|
||||||
struct GUIFont* guiFont = malloc(sizeof(struct GUIFont));
|
struct GUIFont* guiFont = malloc(sizeof(struct GUIFont));
|
||||||
if (!guiFont) {
|
if (!guiFont) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
C3D_Tex* tex;
|
||||||
|
|
||||||
C3D_Tex* tex = &guiFont->texture;
|
TGLP_s* glyphInfo = fontGetGlyphInfo();
|
||||||
C3D_TexInitVRAM(tex, 256, 128, GPU_RGBA5551);
|
guiFont->sheets = malloc(sizeof(*guiFont->sheets) * glyphInfo->nSheets);
|
||||||
|
|
||||||
GSPGPU_FlushDataCache(font, font_size);
|
int i;
|
||||||
GX_RequestDma((u32*) font, tex->data, font_size);
|
for (i = 0; i < glyphInfo->nSheets; ++i) {
|
||||||
gspWaitForDMA();
|
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;
|
tex = &guiFont->icons;
|
||||||
C3D_TexInitVRAM(tex, 256, 64, GPU_RGBA5551);
|
C3D_TexInitVRAM(tex, 256, 64, GPU_RGBA5551);
|
||||||
|
|
||||||
|
|
||||||
GSPGPU_FlushDataCache(icons, icons_size);
|
GSPGPU_FlushDataCache(icons, icons_size);
|
||||||
GX_RequestDma((u32*) icons, tex->data, icons_size);
|
GX_RequestDma((u32*) icons, tex->data, icons_size);
|
||||||
gspWaitForDMA();
|
gspWaitForDMA();
|
||||||
|
@ -46,22 +53,24 @@ struct GUIFont* GUIFontCreate(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUIFontDestroy(struct GUIFont* font) {
|
void GUIFontDestroy(struct GUIFont* font) {
|
||||||
C3D_TexDelete(&font->texture);
|
free(font->sheets);
|
||||||
C3D_TexDelete(&font->icons);
|
C3D_TexDelete(&font->icons);
|
||||||
free(font);
|
free(font);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned GUIFontHeight(const struct GUIFont* font) {
|
unsigned GUIFontHeight(const struct GUIFont* font) {
|
||||||
UNUSED(font);
|
UNUSED(font);
|
||||||
return GLYPH_HEIGHT;
|
return fontGetInfo()->lineFeed * FONT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned GUIFontGlyphWidth(const struct GUIFont* font, uint32_t glyph) {
|
unsigned GUIFontGlyphWidth(const struct GUIFont* font, uint32_t glyph) {
|
||||||
UNUSED(font);
|
UNUSED(font);
|
||||||
if (glyph > 0x7F) {
|
int index = fontGlyphIndexFromCodePoint(glyph);
|
||||||
glyph = 0;
|
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) {
|
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) {
|
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) {
|
C3D_Tex* tex = &font->sheets[data.sheetIndex];
|
||||||
glyph = '?';
|
ctrActivateTexture(tex);
|
||||||
}
|
|
||||||
|
|
||||||
struct GUIFontGlyphMetric metric = defaultFontMetrics[glyph];
|
float width = data.texcoord.right - data.texcoord.left;
|
||||||
u16 x = glyph_x - metric.padding.left;
|
float height = data.texcoord.top - data.texcoord.bottom;
|
||||||
u16 y = glyph_y - GLYPH_HEIGHT;
|
u16 x = glyph_x;
|
||||||
u16 u = (glyph % 16u) * CELL_WIDTH;
|
u16 y = glyph_y + tex->height * height / 8;
|
||||||
u16 v = (glyph / 16u) * CELL_HEIGHT;
|
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) {
|
void GUIFontDrawIcon(const struct GUIFont* font, int x, int y, enum GUIAlignment align, enum GUIOrientation orient, uint32_t color, enum GUIIcon icon) {
|
||||||
|
|
|
@ -178,6 +178,8 @@ static void _drawStart(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _drawEnd(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(&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));
|
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();
|
gfxSwapBuffersGpu();
|
||||||
|
|
Loading…
Reference in New Issue