mirror of https://github.com/mgba-emu/mgba.git
GUI: Add icons and scrolling enhancements
This commit is contained in:
parent
90eca20ab2
commit
0511d0a69e
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
|
@ -203,7 +203,7 @@ void GBAGUIRun(struct GBAGUIRunner* runner, const char* path) {
|
|||
if (runner->params.guiPrepare) {
|
||||
runner->params.guiPrepare();
|
||||
}
|
||||
GUIFontPrint(runner->params.font, runner->params.width / 2, (GUIFontHeight(runner->params.font) + runner->params.height) / 2, GUI_TEXT_CENTER, 0xFFFFFFFF, "Loading...");
|
||||
GUIFontPrint(runner->params.font, runner->params.width / 2, (GUIFontHeight(runner->params.font) + runner->params.height) / 2, GUI_ALIGN_HCENTER, 0xFFFFFFFF, "Loading...");
|
||||
if (runner->params.guiFinish) {
|
||||
runner->params.guiFinish();
|
||||
}
|
||||
|
@ -216,7 +216,7 @@ void GBAGUIRun(struct GBAGUIRunner* runner, const char* path) {
|
|||
if (runner->params.guiPrepare) {
|
||||
runner->params.guiPrepare();
|
||||
}
|
||||
GUIFontPrint(runner->params.font, runner->params.width / 2, (GUIFontHeight(runner->params.font) + runner->params.height) / 2, GUI_TEXT_CENTER, 0xFFFFFFFF, "Load failed!");
|
||||
GUIFontPrint(runner->params.font, runner->params.width / 2, (GUIFontHeight(runner->params.font) + runner->params.height) / 2, GUI_ALIGN_HCENTER, 0xFFFFFFFF, "Load failed!");
|
||||
if (runner->params.guiFinish) {
|
||||
runner->params.guiFinish();
|
||||
}
|
||||
|
@ -270,7 +270,7 @@ void GBAGUIRun(struct GBAGUIRunner* runner, const char* path) {
|
|||
if (runner->params.guiPrepare) {
|
||||
runner->params.guiPrepare();
|
||||
}
|
||||
GUIFontPrintf(runner->params.font, 0, GUIFontHeight(runner->params.font), GUI_TEXT_LEFT, 0x7FFFFFFF, "%.2f fps", runner->fps);
|
||||
GUIFontPrintf(runner->params.font, 0, GUIFontHeight(runner->params.font), GUI_ALIGN_LEFT, 0x7FFFFFFF, "%.2f fps", runner->fps);
|
||||
if (runner->params.guiFinish) {
|
||||
runner->params.guiFinish();
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ set(CORE_VFS_SRC ${CORE_VFS_SRC} PARENT_SCOPE)
|
|||
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.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/uishader.h
|
||||
|
@ -38,6 +39,7 @@ list(APPEND GUI_SRC
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/ctr-gpu.h)
|
||||
|
||||
set_source_files_properties(
|
||||
${CMAKE_CURRENT_BINARY_DIR}/icons.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/font.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/uishader.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/uishader.h
|
||||
|
@ -59,6 +61,10 @@ 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)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/uishader.shbin ${CMAKE_CURRENT_BINARY_DIR}/uishader.shbin.h
|
||||
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/uishader.vsh
|
||||
|
|
|
@ -7,8 +7,9 @@
|
|||
#include "util/gui/font-metrics.h"
|
||||
#include "util/png-io.h"
|
||||
#include "util/vfs.h"
|
||||
#include "platform/3ds/ctr-gpu.h"
|
||||
#include "icons.h"
|
||||
#include "font.h"
|
||||
#include "ctr-gpu.h"
|
||||
|
||||
#define CELL_HEIGHT 16
|
||||
#define CELL_WIDTH 16
|
||||
|
@ -16,6 +17,7 @@
|
|||
|
||||
struct GUIFont {
|
||||
struct ctrTexture texture;
|
||||
struct ctrTexture icons;
|
||||
};
|
||||
|
||||
struct GUIFont* GUIFontCreate(void) {
|
||||
|
@ -35,11 +37,23 @@ struct GUIFont* GUIFontCreate(void) {
|
|||
GX_RequestDma((u32*) font, tex->data, font_size);
|
||||
gspWaitForDMA();
|
||||
|
||||
tex = &guiFont->icons;
|
||||
ctrTexture_Init(tex);
|
||||
tex->data = vramAlloc(256 * 64 * 2);
|
||||
tex->format = GPU_RGBA5551;
|
||||
tex->width = 256;
|
||||
tex->height = 64;
|
||||
|
||||
GSPGPU_FlushDataCache(icons, icons_size);
|
||||
GX_RequestDma((u32*) icons, tex->data, icons_size);
|
||||
gspWaitForDMA();
|
||||
|
||||
return guiFont;
|
||||
}
|
||||
|
||||
void GUIFontDestroy(struct GUIFont* font) {
|
||||
vramFree(font->texture.data);
|
||||
vramFree(font->icons.data);
|
||||
free(font);
|
||||
}
|
||||
|
||||
|
@ -71,3 +85,42 @@ void GUIFontDrawGlyph(const struct GUIFont* font, int glyph_x, int glyph_y, uint
|
|||
|
||||
ctrAddRect(color, x, y, u, v, CELL_WIDTH, CELL_HEIGHT);
|
||||
}
|
||||
|
||||
void GUIFontDrawIcon(const struct GUIFont* font, int x, int y, enum GUIAlignment align, enum GUIOrientation orient, uint32_t color, enum GUIIcon icon) {
|
||||
ctrActivateTexture(&font->icons);
|
||||
|
||||
if (icon >= GUI_ICON_MAX) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct GUIIconMetric metric = defaultIconMetrics[icon];
|
||||
switch (align & GUI_ALIGN_HCENTER) {
|
||||
case GUI_ALIGN_HCENTER:
|
||||
x -= metric.width / 2;
|
||||
break;
|
||||
case GUI_ALIGN_RIGHT:
|
||||
x -= metric.width;
|
||||
break;
|
||||
}
|
||||
switch (align & GUI_ALIGN_VCENTER) {
|
||||
case GUI_ALIGN_VCENTER:
|
||||
y -= metric.height / 2;
|
||||
break;
|
||||
case GUI_ALIGN_BOTTOM:
|
||||
y -= metric.height;
|
||||
break;
|
||||
}
|
||||
switch (orient) {
|
||||
case GUI_ORIENT_HMIRROR:
|
||||
ctrAddRectScaled(color, x + metric.width, y, -metric.width, metric.height, metric.x, metric.y, metric.width, metric.height);
|
||||
break;
|
||||
case GUI_ORIENT_VMIRROR:
|
||||
ctrAddRectScaled(color, x, y + metric.height, metric.width, -metric.height, metric.x, metric.y, metric.width, metric.height);
|
||||
break;
|
||||
case GUI_ORIENT_0:
|
||||
default:
|
||||
// TODO: Rotation
|
||||
ctrAddRect(color, x, y, metric.x, metric.y, metric.width, metric.height);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -410,7 +410,7 @@ static uint32_t _pollInput(void) {
|
|||
return keys;
|
||||
}
|
||||
|
||||
static enum GUICursorState _pollCursor(int* x, int* y) {
|
||||
static enum GUICursorState _pollCursor(unsigned* x, unsigned* y) {
|
||||
hidScanInput();
|
||||
if (!(hidKeysHeld() & KEY_TOUCH)) {
|
||||
return GUI_CURSOR_NOT_PRESENT;
|
||||
|
|
|
@ -19,8 +19,14 @@ set(OBJCOPY_CMD ${OBJCOPY} -I binary -O elf32-littlearm -B arm)
|
|||
|
||||
list(APPEND GUI_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gui-font.c)
|
||||
|
||||
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/font.o ${CMAKE_CURRENT_BINARY_DIR}/backdrop.o PROPERTIES GENERATED ON)
|
||||
add_executable(${BINARY_NAME}.elf ${PLATFORM_SRC} ${GUI_SRC} ${CMAKE_CURRENT_BINARY_DIR}/font.o ${CMAKE_CURRENT_BINARY_DIR}/backdrop.o main.c)
|
||||
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/icons.o
|
||||
${CMAKE_CURRENT_BINARY_DIR}/font.o
|
||||
${CMAKE_CURRENT_BINARY_DIR}/backdrop.o
|
||||
PROPERTIES GENERATED ON)
|
||||
add_executable(${BINARY_NAME}.elf ${PLATFORM_SRC} ${GUI_SRC} main.c
|
||||
${CMAKE_CURRENT_BINARY_DIR}/icons.o
|
||||
${CMAKE_CURRENT_BINARY_DIR}/font.o
|
||||
${CMAKE_CURRENT_BINARY_DIR}/backdrop.o)
|
||||
set_target_properties(${BINARY_NAME}.elf PROPERTIES COMPILE_DEFINITIONS "${OS_DEFINES};${FEATURE_DEFINES};${FUNCTION_DEFINES}")
|
||||
target_link_libraries(${BINARY_NAME}.elf ${BINARY_NAME} ${OS_LIB})
|
||||
|
||||
|
@ -28,6 +34,10 @@ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/font.o
|
|||
COMMAND ${OBJCOPY_CMD} font2x.png ${CMAKE_CURRENT_BINARY_DIR}/font.o
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/res)
|
||||
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/icons.o
|
||||
COMMAND ${OBJCOPY_CMD} icons2x.png ${CMAKE_CURRENT_BINARY_DIR}/icons.o
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/res)
|
||||
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/backdrop.o
|
||||
COMMAND ${OBJCOPY_CMD} backdrop.png ${CMAKE_CURRENT_BINARY_DIR}/backdrop.o
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
|
|
@ -13,9 +13,11 @@
|
|||
#define GLYPH_HEIGHT 24
|
||||
|
||||
extern const uint8_t _binary_font2x_png_start[];
|
||||
extern const uint8_t _binary_icons2x_png_start[];
|
||||
|
||||
struct GUIFont {
|
||||
vita2d_texture* tex;
|
||||
vita2d_texture* icons;
|
||||
};
|
||||
|
||||
struct GUIFont* GUIFontCreate(void) {
|
||||
|
@ -24,11 +26,13 @@ struct GUIFont* GUIFontCreate(void) {
|
|||
return 0;
|
||||
}
|
||||
font->tex = vita2d_load_PNG_buffer(_binary_font2x_png_start);
|
||||
font->icons = vita2d_load_PNG_buffer(_binary_icons2x_png_start);
|
||||
return font;
|
||||
}
|
||||
|
||||
void GUIFontDestroy(struct GUIFont* font) {
|
||||
vita2d_free_texture(font->tex);
|
||||
vita2d_free_texture(font->icons);
|
||||
free(font);
|
||||
}
|
||||
|
||||
|
@ -57,3 +61,49 @@ void GUIFontDrawGlyph(const struct GUIFont* font, int x, int y, uint32_t color,
|
|||
CELL_HEIGHT - (metric.padding.top + metric.padding.bottom) * 2,
|
||||
1, 1, color);
|
||||
}
|
||||
|
||||
void GUIFontDrawIcon(const struct GUIFont* font, int x, int y, enum GUIAlignment align, enum GUIOrientation orient, uint32_t color, enum GUIIcon icon) {
|
||||
if (icon >= GUI_ICON_MAX) {
|
||||
return;
|
||||
}
|
||||
struct GUIIconMetric metric = defaultIconMetrics[icon];
|
||||
switch (align & GUI_ALIGN_HCENTER) {
|
||||
case GUI_ALIGN_HCENTER:
|
||||
x -= metric.width;
|
||||
break;
|
||||
case GUI_ALIGN_RIGHT:
|
||||
x -= metric.width * 2;
|
||||
break;
|
||||
}
|
||||
switch (align & GUI_ALIGN_VCENTER) {
|
||||
case GUI_ALIGN_VCENTER:
|
||||
y -= metric.height;
|
||||
break;
|
||||
case GUI_ALIGN_BOTTOM:
|
||||
y -= metric.height * 2;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (orient) {
|
||||
case GUI_ORIENT_HMIRROR:
|
||||
vita2d_draw_texture_tint_part_scale(font->icons, x, y,
|
||||
metric.x * 2, metric.y * 2,
|
||||
metric.width * 2, metric.height * 2,
|
||||
-1, 1, color);
|
||||
return;
|
||||
case GUI_ORIENT_VMIRROR:
|
||||
vita2d_draw_texture_tint_part_scale(font->icons, x, y,
|
||||
metric.x * 2, metric.y * 2,
|
||||
metric.width * 2, metric.height * 2,
|
||||
1, -1, color);
|
||||
return;
|
||||
case GUI_ORIENT_0:
|
||||
default:
|
||||
// TOOD: Rotate
|
||||
vita2d_draw_texture_tint_part(font->icons, x, y,
|
||||
metric.x * 2, metric.y * 2,
|
||||
metric.width * 2, metric.height * 2,
|
||||
color);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ static uint32_t _pollInput(void) {
|
|||
return input;
|
||||
}
|
||||
|
||||
static enum GUICursorState _pollCursor(int* x, int* y) {
|
||||
static enum GUICursorState _pollCursor(unsigned* x, unsigned* y) {
|
||||
SceTouchData touch;
|
||||
sceTouchPeek(0, &touch, 1);
|
||||
if (touch.reportNum < 1) {
|
||||
|
|
|
@ -15,7 +15,7 @@ source_group("Wii-specific code" FILES ${OS_SRC})
|
|||
set(CORE_VFS_SRC ${CORE_VFS_SRC} PARENT_SCOPE)
|
||||
set(OS_DEFINES ${OS_DEFINES} PARENT_SCOPE)
|
||||
|
||||
list(APPEND GUI_SRC ${CMAKE_CURRENT_BINARY_DIR}/font.c ${CMAKE_CURRENT_SOURCE_DIR}/gui-font.c)
|
||||
list(APPEND GUI_SRC ${CMAKE_CURRENT_BINARY_DIR}/font.c ${CMAKE_CURRENT_BINARY_DIR}/icons.c ${CMAKE_CURRENT_SOURCE_DIR}/gui-font.c)
|
||||
|
||||
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/font.c PROPERTIES GENERATED ON)
|
||||
add_executable(${BINARY_NAME}.elf ${GUI_SRC} main.c)
|
||||
|
@ -24,7 +24,12 @@ target_link_libraries(${BINARY_NAME}.elf ${BINARY_NAME} ${OS_LIB})
|
|||
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/font.c
|
||||
COMMAND ${RAW2C} ${CMAKE_SOURCE_DIR}/src/platform/wii/font.tpl
|
||||
MAIN_DEPENDENCY ${CMAKE_SOURCE_DIR}/src/platform/wii/font.tpl
|
||||
MAIN_DEPENDENCY ${CMAKE_SOURCE_DIR}/src/platform/wii/font.tpl
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/icons.c
|
||||
COMMAND ${RAW2C} ${CMAKE_SOURCE_DIR}/src/platform/wii/icons.tpl
|
||||
MAIN_DEPENDENCY ${CMAKE_SOURCE_DIR}/src/platform/wii/icons.tpl
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
add_custom_target(${BINARY_NAME}.dol ALL
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include "util/gui/font.h"
|
||||
#include "util/gui/font-metrics.h"
|
||||
#include "icons.h"
|
||||
#include "font.h"
|
||||
|
||||
#include <malloc.h>
|
||||
|
@ -16,6 +17,7 @@
|
|||
|
||||
struct GUIFont {
|
||||
TPLFile tdf;
|
||||
TPLFile iconsTdf;
|
||||
};
|
||||
|
||||
struct GUIFont* GUIFontCreate(void) {
|
||||
|
@ -32,11 +34,21 @@ struct GUIFont* GUIFontCreate(void) {
|
|||
}
|
||||
memcpy(fontTpl, font, font_size);
|
||||
TPL_OpenTPLFromMemory(&guiFont->tdf, fontTpl, font_size);
|
||||
|
||||
void* iconsTpl = memalign(32, icons_size);
|
||||
if (!iconsTpl) {
|
||||
TPL_CloseTPLFile(&guiFont->tdf);
|
||||
free(guiFont);
|
||||
return 0;
|
||||
}
|
||||
memcpy(iconsTpl, icons, icons_size);
|
||||
TPL_OpenTPLFromMemory(&guiFont->iconsTdf, iconsTpl, icons_size);
|
||||
return guiFont;
|
||||
}
|
||||
|
||||
void GUIFontDestroy(struct GUIFont* font) {
|
||||
TPL_CloseTPLFile(&font->tdf);
|
||||
TPL_CloseTPLFile(&font->iconsTdf);
|
||||
free(font);
|
||||
}
|
||||
|
||||
|
@ -89,3 +101,82 @@ void GUIFontDrawGlyph(const struct GUIFont* font, int x, int y, uint32_t color,
|
|||
GX_TexCoord2f32(tx / 512.f, (ty + CELL_HEIGHT - (metric.padding.top + metric.padding.bottom) * 2) / 256.f);
|
||||
GX_End();
|
||||
}
|
||||
|
||||
void GUIFontDrawIcon(const struct GUIFont* font, int x, int y, enum GUIAlignment align, enum GUIOrientation orient, uint32_t color, enum GUIIcon icon) {
|
||||
if (icon >= GUI_ICON_MAX) {
|
||||
return;
|
||||
}
|
||||
|
||||
color = (color >> 24) | (color << 8);
|
||||
GXTexObj tex;
|
||||
|
||||
struct GUIFont* ncfont = font;
|
||||
TPL_GetTexture(&ncfont->iconsTdf, 0, &tex);
|
||||
GX_LoadTexObj(&tex, GX_TEXMAP0);
|
||||
|
||||
GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_NOOP);
|
||||
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
|
||||
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
|
||||
|
||||
struct GUIIconMetric metric = defaultIconMetrics[icon];
|
||||
switch (align & GUI_ALIGN_HCENTER) {
|
||||
case GUI_ALIGN_HCENTER:
|
||||
x -= metric.width;
|
||||
break;
|
||||
case GUI_ALIGN_RIGHT:
|
||||
x -= metric.width * 2;
|
||||
break;
|
||||
}
|
||||
switch (align & GUI_ALIGN_VCENTER) {
|
||||
case GUI_ALIGN_VCENTER:
|
||||
y -= metric.height;
|
||||
break;
|
||||
case GUI_ALIGN_BOTTOM:
|
||||
y -= metric.height * 2;
|
||||
break;
|
||||
}
|
||||
|
||||
float u[4];
|
||||
float v[4];
|
||||
|
||||
switch (orient) {
|
||||
case GUI_ORIENT_0:
|
||||
default:
|
||||
// TODO: Rotations
|
||||
u[0] = u[3] = metric.x / 256.f;
|
||||
u[1] = u[2] = (metric.x + metric.width) / 256.f;
|
||||
v[0] = v[1] = (metric.y + metric.height) / 64.f;
|
||||
v[2] = v[3] = metric.y / 64.f;
|
||||
break;
|
||||
case GUI_ORIENT_HMIRROR:
|
||||
u[0] = u[3] = (metric.x + metric.width) / 256.f;
|
||||
u[1] = u[2] = metric.x / 256.f;
|
||||
v[0] = v[1] = (metric.y + metric.height) / 64.f;
|
||||
v[2] = v[3] = metric.y / 64.f;
|
||||
break;
|
||||
case GUI_ORIENT_VMIRROR:
|
||||
u[0] = u[3] = metric.x / 256.f;
|
||||
u[1] = u[2] = (metric.x + metric.width) / 256.f;
|
||||
v[0] = v[1] = metric.y / 64.f;
|
||||
v[2] = v[3] = (metric.y + metric.height) / 64.f;
|
||||
break;
|
||||
}
|
||||
|
||||
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
|
||||
GX_Position2s16(x, y + metric.height * 2);
|
||||
GX_Color1u32(color);
|
||||
GX_TexCoord2f32(u[0], v[0]);
|
||||
|
||||
GX_Position2s16(x + metric.width * 2, y + metric.height * 2);
|
||||
GX_Color1u32(color);
|
||||
GX_TexCoord2f32(u[1], v[1]);
|
||||
|
||||
GX_Position2s16(x + metric.width * 2, y);
|
||||
GX_Color1u32(color);
|
||||
GX_TexCoord2f32(u[2], v[2]);
|
||||
|
||||
GX_Position2s16(x, y);
|
||||
GX_Color1u32(color);
|
||||
GX_TexCoord2f32(u[3], v[3]);
|
||||
GX_End();
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ static int32_t _readGyroZ(struct GBARotationSource* source);
|
|||
static void _drawStart(void);
|
||||
static void _drawEnd(void);
|
||||
static uint32_t _pollInput(void);
|
||||
static enum GUICursorState _pollCursor(int* x, int* y);
|
||||
static enum GUICursorState _pollCursor(unsigned* x, unsigned* y);
|
||||
static void _guiPrepare(void);
|
||||
static void _guiFinish(void);
|
||||
|
||||
|
@ -467,7 +467,7 @@ static uint32_t _pollInput(void) {
|
|||
return keys;
|
||||
}
|
||||
|
||||
static enum GUICursorState _pollCursor(int* x, int* y) {
|
||||
static enum GUICursorState _pollCursor(unsigned* x, unsigned* y) {
|
||||
ir_t ir;
|
||||
WPAD_IR(0, &ir);
|
||||
if (!ir.smooth_valid) {
|
||||
|
|
|
@ -59,7 +59,7 @@ struct GUIParams {
|
|||
void (*drawStart)(void);
|
||||
void (*drawEnd)(void);
|
||||
uint32_t (*pollInput)(void);
|
||||
enum GUICursorState (*pollCursor)(int* x, int* y);
|
||||
enum GUICursorState (*pollCursor)(unsigned* x, unsigned* y);
|
||||
int (*batteryState)(void);
|
||||
void (*guiPrepare)(void);
|
||||
void (*guiFinish)(void);
|
||||
|
@ -78,7 +78,7 @@ struct GUIParams {
|
|||
|
||||
void GUIInit(struct GUIParams* params);
|
||||
void GUIPollInput(struct GUIParams* params, uint32_t* newInput, uint32_t* heldInput);
|
||||
enum GUICursorState GUIPollCursor(struct GUIParams* params, int* x, int* y);
|
||||
enum GUICursorState GUIPollCursor(struct GUIParams* params, unsigned* x, unsigned* y);
|
||||
void GUIInvalidateKeys(struct GUIParams* params);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -71,8 +71,8 @@ static bool _refreshDirectory(struct GUIParams* params, const char* currentPath,
|
|||
if (params->guiPrepare) {
|
||||
params->guiPrepare();
|
||||
}
|
||||
GUIFontPrintf(params->font, 0, GUIFontHeight(params->font), GUI_TEXT_LEFT, 0xFFFFFFFF, "(scanning for items: %zu)", i);
|
||||
GUIFontPrintf(params->font, 0, GUIFontHeight(params->font) * 2, GUI_TEXT_LEFT, 0xFFFFFFFF, "%s", currentPath);
|
||||
GUIFontPrintf(params->font, 0, GUIFontHeight(params->font), GUI_ALIGN_LEFT, 0xFFFFFFFF, "(scanning for items: %zu)", i);
|
||||
GUIFontPrintf(params->font, 0, GUIFontHeight(params->font) * 2, GUI_ALIGN_LEFT, 0xFFFFFFFF, "%s", currentPath);
|
||||
if (params->guiFinish) {
|
||||
params->guiFinish();
|
||||
}
|
||||
|
@ -109,8 +109,8 @@ static bool _refreshDirectory(struct GUIParams* params, const char* currentPath,
|
|||
if (params->guiPrepare) {
|
||||
params->guiPrepare();
|
||||
}
|
||||
GUIFontPrintf(params->font, 0, GUIFontHeight(params->font), GUI_TEXT_LEFT, 0xFFFFFFFF, "(scanning item %zu of %zu)", i, items);
|
||||
GUIFontPrintf(params->font, 0, GUIFontHeight(params->font) * 2, GUI_TEXT_LEFT, 0xFFFFFFFF, "%s", currentPath);
|
||||
GUIFontPrintf(params->font, 0, GUIFontHeight(params->font), GUI_ALIGN_LEFT, 0xFFFFFFFF, "(scanning item %zu of %zu)", i, items);
|
||||
GUIFontPrintf(params->font, 0, GUIFontHeight(params->font) * 2, GUI_ALIGN_LEFT, 0xFFFFFFFF, "%s", currentPath);
|
||||
if (params->guiFinish) {
|
||||
params->guiFinish();
|
||||
}
|
||||
|
|
|
@ -135,3 +135,21 @@ struct GUIFontGlyphMetric defaultFontMetrics[128] = {
|
|||
{ 10, 5, { 5, 3, 6, 3 }}, // 0x7E "}"
|
||||
{ 0, 0, { 0, 0, 0, 0 }}, // 0x7F
|
||||
};
|
||||
|
||||
struct GUIIconMetric defaultIconMetrics[] = {
|
||||
[GUI_ICON_BATTERY_FULL] = { 0, 0, 32, 16 },
|
||||
[GUI_ICON_BATTERY_HIGH] = { 32, 0, 32, 16 },
|
||||
[GUI_ICON_BATTERY_HALF] = { 64, 0, 32, 16 },
|
||||
[GUI_ICON_BATTERY_LOW] = { 96, 0, 32, 16 },
|
||||
[GUI_ICON_BATTERY_EMPTY] = { 128, 0, 32, 16 },
|
||||
[GUI_ICON_SCROLLBAR_BUTTON] = { 6, 16, 4, 5 },
|
||||
[GUI_ICON_SCROLLBAR_TRACK] = { 23, 16, 2, 16 },
|
||||
[GUI_ICON_SCROLLBAR_THUMB] = { 38, 16, 4, 16 },
|
||||
[GUI_ICON_CURSOR] = { 48, 16, 16, 16 },
|
||||
[GUI_ICON_POINTER] = { 68, 20, 8, 8 },
|
||||
[GUI_ICON_BUTTON_CIRCLE] = { 2, 34, 12, 11 },
|
||||
[GUI_ICON_BUTTON_CROSS] = { 18, 34, 12, 11 },
|
||||
[GUI_ICON_BUTTON_TRIANGLE] = { 34, 34, 12, 11 },
|
||||
[GUI_ICON_BUTTON_SQUARE] = { 50, 34, 12, 11 },
|
||||
[GUI_ICON_BUTTON_HOME] = { 66, 34, 16, 16 },
|
||||
};
|
||||
|
|
|
@ -9,5 +9,6 @@
|
|||
#include "util/gui/font.h"
|
||||
|
||||
extern struct GUIFontGlyphMetric defaultFontMetrics[];
|
||||
extern struct GUIIconMetric defaultIconMetrics[];
|
||||
|
||||
#endif
|
||||
|
|
|
@ -15,12 +15,12 @@ unsigned GUIFontSpanWidth(const struct GUIFont* font, const char* text) {
|
|||
return width;
|
||||
}
|
||||
|
||||
void GUIFontPrint(const struct GUIFont* font, int x, int y, enum GUITextAlignment align, uint32_t color, const char* text) {
|
||||
switch (align) {
|
||||
case GUI_TEXT_CENTER:
|
||||
void GUIFontPrint(const struct GUIFont* font, int x, int y, enum GUIAlignment align, uint32_t color, const char* text) {
|
||||
switch (align & GUI_ALIGN_HCENTER) {
|
||||
case GUI_ALIGN_HCENTER:
|
||||
x -= GUIFontSpanWidth(font, text) / 2;
|
||||
break;
|
||||
case GUI_TEXT_RIGHT:
|
||||
case GUI_ALIGN_RIGHT:
|
||||
x -= GUIFontSpanWidth(font, text);
|
||||
break;
|
||||
default:
|
||||
|
@ -34,7 +34,7 @@ void GUIFontPrint(const struct GUIFont* font, int x, int y, enum GUITextAlignmen
|
|||
}
|
||||
}
|
||||
|
||||
void GUIFontPrintf(const struct GUIFont* font, int x, int y, enum GUITextAlignment align, uint32_t color, const char* text, ...) {
|
||||
void GUIFontPrintf(const struct GUIFont* font, int x, int y, enum GUIAlignment align, uint32_t color, const char* text, ...) {
|
||||
char buffer[256];
|
||||
va_list args;
|
||||
va_start(args, text);
|
||||
|
|
|
@ -12,10 +12,46 @@ struct GUIFont;
|
|||
struct GUIFont* GUIFontCreate(void);
|
||||
void GUIFontDestroy(struct GUIFont*);
|
||||
|
||||
enum GUITextAlignment {
|
||||
GUI_TEXT_LEFT = 0,
|
||||
GUI_TEXT_CENTER,
|
||||
GUI_TEXT_RIGHT
|
||||
enum GUIAlignment {
|
||||
GUI_ALIGN_LEFT = 1,
|
||||
GUI_ALIGN_HCENTER = 3,
|
||||
GUI_ALIGN_RIGHT = 2,
|
||||
|
||||
GUI_ALIGN_TOP = 4,
|
||||
GUI_ALIGN_VCENTER = 12,
|
||||
GUI_ALIGN_BOTTOM = 8,
|
||||
};
|
||||
|
||||
enum GUIOrientation {
|
||||
GUI_ORIENT_0,
|
||||
GUI_ORIENT_90_CCW,
|
||||
GUI_ORIENT_180,
|
||||
GUI_ORIENT_270_CCW,
|
||||
|
||||
GUI_ORIENT_VMIRROR,
|
||||
GUI_ORIENT_HMIRROR,
|
||||
|
||||
GUI_ORIENT_90_CW = GUI_ORIENT_270_CCW,
|
||||
GUI_ORIENT_270_CW = GUI_ORIENT_90_CCW
|
||||
};
|
||||
|
||||
enum GUIIcon {
|
||||
GUI_ICON_BATTERY_FULL,
|
||||
GUI_ICON_BATTERY_HIGH,
|
||||
GUI_ICON_BATTERY_HALF,
|
||||
GUI_ICON_BATTERY_LOW,
|
||||
GUI_ICON_BATTERY_EMPTY,
|
||||
GUI_ICON_SCROLLBAR_THUMB,
|
||||
GUI_ICON_SCROLLBAR_TRACK,
|
||||
GUI_ICON_SCROLLBAR_BUTTON,
|
||||
GUI_ICON_CURSOR,
|
||||
GUI_ICON_POINTER,
|
||||
GUI_ICON_BUTTON_CIRCLE,
|
||||
GUI_ICON_BUTTON_CROSS,
|
||||
GUI_ICON_BUTTON_TRIANGLE,
|
||||
GUI_ICON_BUTTON_SQUARE,
|
||||
GUI_ICON_BUTTON_HOME,
|
||||
GUI_ICON_MAX,
|
||||
};
|
||||
|
||||
struct GUIFontGlyphMetric {
|
||||
|
@ -29,13 +65,21 @@ struct GUIFontGlyphMetric {
|
|||
} padding;
|
||||
};
|
||||
|
||||
struct GUIIconMetric {
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
unsigned GUIFontHeight(const struct GUIFont*);
|
||||
unsigned GUIFontGlyphWidth(const struct GUIFont*, uint32_t glyph);
|
||||
unsigned GUIFontSpanWidth(const struct GUIFont*, const char* text);
|
||||
|
||||
ATTRIBUTE_FORMAT(printf, 6, 7)
|
||||
void GUIFontPrintf(const struct GUIFont*, int x, int y, enum GUITextAlignment, uint32_t color, const char* text, ...);
|
||||
void GUIFontPrint(const struct GUIFont*, int x, int y, enum GUITextAlignment, uint32_t color, const char* text);
|
||||
void GUIFontPrintf(const struct GUIFont*, int x, int y, enum GUIAlignment, uint32_t color, const char* text, ...);
|
||||
void GUIFontPrint(const struct GUIFont*, int x, int y, enum GUIAlignment, uint32_t color, const char* text);
|
||||
void GUIFontDrawGlyph(const struct GUIFont*, int x, int y, uint32_t color, uint32_t glyph);
|
||||
void GUIFontDrawIcon(const struct GUIFont*, int x, int y, enum GUIAlignment, enum GUIOrientation, uint32_t color, enum GUIIcon);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,7 +25,7 @@ enum GUIMenuExitReason GUIShowMenu(struct GUIParams* params, struct GUIMenu* men
|
|||
while (true) {
|
||||
uint32_t newInput = 0;
|
||||
GUIPollInput(params, &newInput, 0);
|
||||
int cx, cy;
|
||||
unsigned cx, cy;
|
||||
enum GUICursorState cursor = GUIPollCursor(params, &cx, &cy);
|
||||
|
||||
if (newInput & (1 << GUI_INPUT_UP) && menu->index > 0) {
|
||||
|
@ -71,14 +71,26 @@ enum GUIMenuExitReason GUIShowMenu(struct GUIParams* params, struct GUIMenu* men
|
|||
}
|
||||
}
|
||||
if (cursor != GUI_CURSOR_NOT_PRESENT) {
|
||||
int index = (cy / lineHeight) - 2;
|
||||
if (index >= 0 && index + start < GUIMenuItemListSize(&menu->items)) {
|
||||
if (menu->index != index + start || !cursorOverItem) {
|
||||
cursorOverItem = 1;
|
||||
if (cx < params->width - 16) {
|
||||
int index = (cy / lineHeight) - 2;
|
||||
if (index >= 0 && index + start < GUIMenuItemListSize(&menu->items)) {
|
||||
if (menu->index != index + start || !cursorOverItem) {
|
||||
cursorOverItem = 1;
|
||||
}
|
||||
menu->index = index + start;
|
||||
} else {
|
||||
cursorOverItem = 0;
|
||||
}
|
||||
} else if (cursor == GUI_CURSOR_DOWN || cursor == GUI_CURSOR_DRAGGING) {
|
||||
if (cy <= 2 * lineHeight && cy > lineHeight && menu->index > 0) {
|
||||
--menu->index;
|
||||
} else if (cy <= params->height && cy > params->height - lineHeight && menu->index < GUIMenuItemListSize(&menu->items) - 1) {
|
||||
++menu->index;
|
||||
} else if (cy <= params->height - lineHeight && cy > 2 * lineHeight) {
|
||||
size_t location = cy - 2 * lineHeight;
|
||||
location *= GUIMenuItemListSize(&menu->items);
|
||||
menu->index = location / (params->height - 3 * lineHeight);
|
||||
}
|
||||
menu->index = index + start;
|
||||
} else {
|
||||
cursorOverItem = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,23 +129,23 @@ enum GUIMenuExitReason GUIShowMenu(struct GUIParams* params, struct GUIMenu* men
|
|||
params->guiPrepare();
|
||||
}
|
||||
unsigned y = lineHeight;
|
||||
GUIFontPrint(params->font, 0, y, GUI_TEXT_LEFT, 0xFFFFFFFF, menu->title);
|
||||
GUIFontPrint(params->font, 0, y, GUI_ALIGN_LEFT, 0xFFFFFFFF, menu->title);
|
||||
if (menu->subtitle) {
|
||||
GUIFontPrint(params->font, 0, y * 2, GUI_TEXT_LEFT, 0xFFFFFFFF, menu->subtitle);
|
||||
GUIFontPrint(params->font, 0, y * 2, GUI_ALIGN_LEFT, 0xFFFFFFFF, menu->subtitle);
|
||||
}
|
||||
y += 2 * lineHeight;
|
||||
size_t itemsPerScreen = (params->height - y) / lineHeight;
|
||||
size_t i;
|
||||
for (i = start; i < GUIMenuItemListSize(&menu->items); ++i) {
|
||||
int color = 0xE0A0A0A0;
|
||||
char bullet = ' ';
|
||||
if (i == menu->index) {
|
||||
color = 0xFFFFFFFF;
|
||||
bullet = '>';
|
||||
GUIFontDrawIcon(params->font, 2, y, GUI_ALIGN_BOTTOM | GUI_ALIGN_LEFT, GUI_ORIENT_0, 0xFFFFFFFF, GUI_ICON_POINTER);
|
||||
}
|
||||
struct GUIMenuItem* item = GUIMenuItemListGetPointer(&menu->items, i);
|
||||
GUIFontPrintf(params->font, 0, y, GUI_TEXT_LEFT, color, "%c %s", bullet, item->title);
|
||||
GUIFontPrintf(params->font, 0, y, GUI_ALIGN_LEFT, color, " %s", item->title);
|
||||
if (item->validStates && item->validStates[item->state]) {
|
||||
GUIFontPrintf(params->font, params->width, y, GUI_TEXT_RIGHT, color, "%s ", item->validStates[item->state]);
|
||||
GUIFontPrintf(params->font, params->width, y, GUI_ALIGN_RIGHT, color, "%s ", item->validStates[item->state]);
|
||||
}
|
||||
y += lineHeight;
|
||||
if (y + lineHeight > params->height) {
|
||||
|
@ -141,9 +153,26 @@ enum GUIMenuExitReason GUIShowMenu(struct GUIParams* params, struct GUIMenu* men
|
|||
}
|
||||
}
|
||||
|
||||
if (itemsPerScreen < GUIMenuItemListSize(&menu->items)) {
|
||||
y = 2 * lineHeight;
|
||||
GUIFontDrawIcon(params->font, params->width - 8, y, GUI_ALIGN_HCENTER | GUI_ALIGN_BOTTOM, GUI_ORIENT_VMIRROR, 0xFFFFFFFF, GUI_ICON_SCROLLBAR_BUTTON);
|
||||
for (; y < params->height - 16; y += 16) {
|
||||
GUIFontDrawIcon(params->font, params->width - 8, y, GUI_ALIGN_HCENTER | GUI_ALIGN_TOP, GUI_ORIENT_0, 0xFFFFFFFF, GUI_ICON_SCROLLBAR_TRACK);
|
||||
}
|
||||
GUIFontDrawIcon(params->font, params->width - 8, y, GUI_ALIGN_HCENTER | GUI_ALIGN_TOP, GUI_ORIENT_0, 0xFFFFFFFF, GUI_ICON_SCROLLBAR_BUTTON);
|
||||
|
||||
size_t top = 2 * lineHeight;
|
||||
y = menu->index * (y - top - 16) / GUIMenuItemListSize(&menu->items);
|
||||
GUIFontDrawIcon(params->font, params->width - 8, top + y, GUI_ALIGN_HCENTER | GUI_ALIGN_TOP, GUI_ORIENT_0, 0xFFFFFFFF, GUI_ICON_SCROLLBAR_THUMB);
|
||||
}
|
||||
|
||||
GUIDrawBattery(params);
|
||||
GUIDrawClock(params);
|
||||
|
||||
if (cursor != GUI_CURSOR_NOT_PRESENT) {
|
||||
GUIFontDrawIcon(params->font, cx, cy, GUI_ALIGN_HCENTER | GUI_ALIGN_TOP, GUI_ORIENT_0, 0xFFFFFFFF, GUI_ICON_CURSOR);
|
||||
}
|
||||
|
||||
if (params->guiFinish) {
|
||||
params->guiFinish();
|
||||
}
|
||||
|
@ -152,7 +181,7 @@ enum GUIMenuExitReason GUIShowMenu(struct GUIParams* params, struct GUIMenu* men
|
|||
return GUI_MENU_EXIT_CANCEL;
|
||||
}
|
||||
|
||||
enum GUICursorState GUIPollCursor(struct GUIParams* params, int* x, int* y) {
|
||||
enum GUICursorState GUIPollCursor(struct GUIParams* params, unsigned* x, unsigned* y) {
|
||||
if (!params->pollCursor) {
|
||||
return GUI_CURSOR_NOT_PRESENT;
|
||||
}
|
||||
|
@ -207,29 +236,29 @@ void GUIDrawBattery(struct GUIParams* params) {
|
|||
color |= 0x3030FF;
|
||||
}
|
||||
|
||||
const char* batteryText;
|
||||
enum GUIIcon batteryIcon;
|
||||
switch (state & ~BATTERY_CHARGING) {
|
||||
case BATTERY_EMPTY:
|
||||
batteryText = "[ ]";
|
||||
batteryIcon = GUI_ICON_BATTERY_EMPTY;
|
||||
break;
|
||||
case BATTERY_LOW:
|
||||
batteryText = "[I ]";
|
||||
batteryIcon = GUI_ICON_BATTERY_LOW;
|
||||
break;
|
||||
case BATTERY_HALF:
|
||||
batteryText = "[II ]";
|
||||
batteryIcon = GUI_ICON_BATTERY_HALF;
|
||||
break;
|
||||
case BATTERY_HIGH:
|
||||
batteryText = "[III ]";
|
||||
batteryIcon = GUI_ICON_BATTERY_HIGH;
|
||||
break;
|
||||
case BATTERY_FULL:
|
||||
batteryText = "[IIII]";
|
||||
batteryIcon = GUI_ICON_BATTERY_FULL;
|
||||
break;
|
||||
default:
|
||||
batteryText = "[????]";
|
||||
batteryIcon = GUI_ICON_BATTERY_EMPTY;
|
||||
break;
|
||||
}
|
||||
|
||||
GUIFontPrint(params->font, params->width, GUIFontHeight(params->font), GUI_TEXT_RIGHT, color, batteryText);
|
||||
GUIFontDrawIcon(params->font, params->width, 0, GUI_ALIGN_RIGHT, GUI_ORIENT_0, color, batteryIcon);
|
||||
}
|
||||
|
||||
void GUIDrawClock(struct GUIParams* params) {
|
||||
|
@ -238,5 +267,5 @@ void GUIDrawClock(struct GUIParams* params) {
|
|||
struct tm tm;
|
||||
localtime_r(&t, &tm);
|
||||
strftime(buffer, sizeof(buffer), "%H:%M:%S", &tm);
|
||||
GUIFontPrint(params->font, params->width / 2, GUIFontHeight(params->font), GUI_TEXT_CENTER, 0xFFFFFFFF, buffer);
|
||||
GUIFontPrint(params->font, params->width / 2, GUIFontHeight(params->font), GUI_ALIGN_HCENTER, 0xFFFFFFFF, buffer);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue