mirror of
https://github.com/mauiaaron/apple2.git
synced 2024-12-26 15:29:19 +00:00
Refactor HUD model to allow scaling font glyphs
- Should be less pixelation of touch keyboard on large tablet screens
This commit is contained in:
parent
a54a69efcc
commit
f5bbda4c6e
@ -12,6 +12,106 @@
|
|||||||
#include "glhudmodel.h"
|
#include "glhudmodel.h"
|
||||||
#include "glvideo.h"
|
#include "glvideo.h"
|
||||||
|
|
||||||
|
// . . .
|
||||||
|
// . x .
|
||||||
|
// . . .
|
||||||
|
typedef struct EightPatchArgs_s {
|
||||||
|
GLModel *parent;
|
||||||
|
unsigned int pixelSize;
|
||||||
|
unsigned int glyphScale;
|
||||||
|
unsigned int fb_h;
|
||||||
|
unsigned int fb_w;
|
||||||
|
unsigned int srcIdx;
|
||||||
|
unsigned int dstIdx;
|
||||||
|
} EightPatchArgs_s;
|
||||||
|
|
||||||
|
// Generates a semi-opaque halo effect around each glyph
|
||||||
|
static void _eightpatch_opaquePixelHaloFilter(const EightPatchArgs_s args) {
|
||||||
|
|
||||||
|
#if USE_RGBA4444
|
||||||
|
# define SEMI_OPAQUE (0x0C << SHIFT_A)
|
||||||
|
#else
|
||||||
|
# define SEMI_OPAQUE (0xC0 << SHIFT_A)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const unsigned int pixelSize = args.pixelSize;
|
||||||
|
const unsigned int glyphScale = args.glyphScale;
|
||||||
|
const unsigned int fb_w = args.fb_w;
|
||||||
|
const unsigned int fb_h = args.fb_h;
|
||||||
|
const unsigned int srcIdx = args.srcIdx;
|
||||||
|
const unsigned int srcCol = (srcIdx % fb_w);
|
||||||
|
const unsigned int lastCol = (fb_w-1);
|
||||||
|
const unsigned int dstPointStride = pixelSize * glyphScale;
|
||||||
|
const unsigned int dstRowStride = fb_w * dstPointStride;
|
||||||
|
const unsigned int texRowStride = ((fb_w * glyphScale) * (glyphScale/*1 row*/ * glyphScale) * pixelSize);
|
||||||
|
const unsigned int lastPoint = ((fb_w * glyphScale) * (fb_h * glyphScale) * pixelSize);
|
||||||
|
|
||||||
|
uint8_t *texPixels = args.parent->texPixels;
|
||||||
|
const int dstIdx0 = (int)args.dstIdx;
|
||||||
|
const int dstPre0 = dstIdx0 - texRowStride; // negative is okay
|
||||||
|
const int dstPost0 = dstIdx0 + texRowStride;
|
||||||
|
|
||||||
|
// scale glyph data 1x, 2x, ...
|
||||||
|
|
||||||
|
// north pixels
|
||||||
|
if (dstPre0 >= 0) {
|
||||||
|
int dstPre = dstPre0;
|
||||||
|
for (unsigned int k=0; k<glyphScale; k++, dstPre+=dstRowStride) {
|
||||||
|
for (unsigned int l=0; l<glyphScale; l++, dstPre+=pixelSize) {
|
||||||
|
if (srcCol != 0) {
|
||||||
|
*((PIXEL_TYPE*)(texPixels + dstPre - dstPointStride)) |= SEMI_OPAQUE;
|
||||||
|
}
|
||||||
|
*((PIXEL_TYPE*)(texPixels + dstPre)) |= SEMI_OPAQUE;
|
||||||
|
if (srcCol < lastCol) {
|
||||||
|
*((PIXEL_TYPE*)(texPixels + dstPre + dstPointStride)) |= SEMI_OPAQUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dstPre -= dstPointStride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// west pixel
|
||||||
|
if (srcCol != 0) {
|
||||||
|
int dstIdx = dstIdx0;
|
||||||
|
for (unsigned int k=0; k<glyphScale; k++, dstIdx+=dstRowStride) {
|
||||||
|
for (unsigned int l=0; l<glyphScale; l++, dstIdx+=pixelSize) {
|
||||||
|
*((PIXEL_TYPE*)(texPixels + dstIdx - dstPointStride)) |= SEMI_OPAQUE;
|
||||||
|
}
|
||||||
|
dstIdx -= dstPointStride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// east pixel
|
||||||
|
if (srcCol < lastCol) {
|
||||||
|
int dstIdx = dstIdx0;
|
||||||
|
for (unsigned int k=0; k<glyphScale; k++, dstIdx+=dstRowStride) {
|
||||||
|
for (unsigned int l=0; l<glyphScale; l++, dstIdx+=pixelSize) {
|
||||||
|
*((PIXEL_TYPE*)(texPixels + dstIdx + dstPointStride)) |= SEMI_OPAQUE;
|
||||||
|
}
|
||||||
|
dstIdx -= dstPointStride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// south pixels
|
||||||
|
if (dstPost0 < lastPoint) {
|
||||||
|
int dstPost = dstPost0;
|
||||||
|
for (unsigned int k=0; k<glyphScale; k++, dstPost+=dstRowStride) {
|
||||||
|
for (unsigned int l=0; l<glyphScale; l++, dstPost+=pixelSize) {
|
||||||
|
if (srcCol != 0) {
|
||||||
|
*((PIXEL_TYPE*)(texPixels + dstPost - dstPointStride)) |= SEMI_OPAQUE;
|
||||||
|
}
|
||||||
|
*((PIXEL_TYPE*)(texPixels + dstPost)) |= SEMI_OPAQUE;
|
||||||
|
if (srcCol < lastCol) {
|
||||||
|
*((PIXEL_TYPE*)(texPixels + dstPost + dstPointStride)) |= SEMI_OPAQUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dstPost -= dstPointStride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
void *glhud_createDefault(void) {
|
void *glhud_createDefault(void) {
|
||||||
return glhud_createCustom(sizeof(GLModelHUDElement));
|
return glhud_createCustom(sizeof(GLModelHUDElement));
|
||||||
}
|
}
|
||||||
@ -20,6 +120,7 @@ void *glhud_createCustom(unsigned int sizeofModel) {
|
|||||||
assert(sizeof(GLModelHUDElement) <= sizeofModel);
|
assert(sizeof(GLModelHUDElement) <= sizeofModel);
|
||||||
GLModelHUDElement *hudElement = (GLModelHUDElement *)CALLOC(sizeofModel, 1);
|
GLModelHUDElement *hudElement = (GLModelHUDElement *)CALLOC(sizeofModel, 1);
|
||||||
if (hudElement) {
|
if (hudElement) {
|
||||||
|
hudElement->glyphMultiplier = 1;
|
||||||
hudElement->colorScheme = RED_ON_BLACK;
|
hudElement->colorScheme = RED_ON_BLACK;
|
||||||
}
|
}
|
||||||
return hudElement;
|
return hudElement;
|
||||||
@ -28,6 +129,8 @@ void *glhud_createCustom(unsigned int sizeofModel) {
|
|||||||
void glhud_setupDefault(GLModel *parent) {
|
void glhud_setupDefault(GLModel *parent) {
|
||||||
|
|
||||||
GLModelHUDElement *hudElement = (GLModelHUDElement *)parent->custom;
|
GLModelHUDElement *hudElement = (GLModelHUDElement *)parent->custom;
|
||||||
|
assert(hudElement->glyphMultiplier > 0);
|
||||||
|
|
||||||
char *submenu = (char *)(hudElement->tpl);
|
char *submenu = (char *)(hudElement->tpl);
|
||||||
const unsigned int cols = hudElement->tplWidth;
|
const unsigned int cols = hudElement->tplWidth;
|
||||||
const unsigned int rows = hudElement->tplHeight;
|
const unsigned int rows = hudElement->tplHeight;
|
||||||
@ -36,71 +139,68 @@ void glhud_setupDefault(GLModel *parent) {
|
|||||||
// render template into indexed fb
|
// render template into indexed fb
|
||||||
interface_plotMessage(fb, hudElement->colorScheme, submenu, cols, rows);
|
interface_plotMessage(fb, hudElement->colorScheme, submenu, cols, rows);
|
||||||
|
|
||||||
// Generate OpenGL color from indexed color
|
// generate OpenGL texture/color from indexed color
|
||||||
const unsigned int fb_w = hudElement->pixWidth;
|
const unsigned int fb_w = hudElement->pixWidth;
|
||||||
const unsigned int fb_h = hudElement->pixHeight;
|
const unsigned int fb_h = hudElement->pixHeight;
|
||||||
const unsigned int count = fb_w * fb_h;
|
const unsigned int pixelSize = sizeof(PIXEL_TYPE);
|
||||||
const unsigned int countOut = count * sizeof(PIXEL_TYPE);
|
const unsigned int glyphScale = hudElement->glyphMultiplier;
|
||||||
for (unsigned int srcIdx=0, dstIdx=0; srcIdx<count; srcIdx++, dstIdx+=sizeof(PIXEL_TYPE)) {
|
const unsigned int dstPointStride = pixelSize * glyphScale;
|
||||||
uint8_t index = *(fb + srcIdx);
|
const unsigned int dstRowStride = fb_w * dstPointStride;
|
||||||
PIXEL_TYPE rgb = (((PIXEL_TYPE)(colormap[index].red) << SHIFT_R) |
|
const unsigned int texSubRowStride = dstRowStride * (glyphScale-1);
|
||||||
((PIXEL_TYPE)(colormap[index].green) << SHIFT_G) |
|
|
||||||
((PIXEL_TYPE)(colormap[index].blue) << SHIFT_B));
|
LOG("fb_h:%u, fb_w:%u -- texH:%u texW:%u", fb_h, fb_w, parent->texHeight, parent->texWidth);
|
||||||
if (rgb == 0 && hudElement->blackIsTransparent) {
|
|
||||||
// make black transparent
|
do {
|
||||||
} else {
|
unsigned int srcIdx = 0;
|
||||||
rgb |= ((PIXEL_TYPE)MAX_SATURATION << SHIFT_A);
|
unsigned int texIdx = 0;
|
||||||
|
for (unsigned int i=0; i<fb_h; i++, texIdx+=texSubRowStride) {
|
||||||
|
for (unsigned int j=0; j<fb_w; j++, srcIdx++, texIdx+=dstPointStride) {
|
||||||
|
uint8_t value = *(fb + srcIdx);
|
||||||
|
PIXEL_TYPE rgba = (((PIXEL_TYPE)(colormap[value].red) << SHIFT_R) |
|
||||||
|
((PIXEL_TYPE)(colormap[value].green) << SHIFT_G) |
|
||||||
|
((PIXEL_TYPE)(colormap[value].blue) << SHIFT_B));
|
||||||
|
if (rgba == 0 && hudElement->blackIsTransparent) {
|
||||||
|
// black remains transparent
|
||||||
|
} else {
|
||||||
|
rgba |= ((PIXEL_TYPE)MAX_SATURATION << SHIFT_A);
|
||||||
|
}
|
||||||
|
|
||||||
|
// scale glyph data 1x, 2x, ...
|
||||||
|
unsigned int dstIdx = texIdx;
|
||||||
|
for (unsigned int k=0; k<glyphScale; k++, dstIdx+=dstRowStride) {
|
||||||
|
for (unsigned int l=0; l<glyphScale; l++, dstIdx+=pixelSize) {
|
||||||
|
*( (PIXEL_TYPE *)(parent->texPixels + dstIdx) ) = rgba;
|
||||||
|
}
|
||||||
|
dstIdx -= dstPointStride;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*( (PIXEL_TYPE*)(parent->texPixels + dstIdx) ) = rgb;
|
} while (0);
|
||||||
}
|
|
||||||
|
|
||||||
// Second pass to generate a semi-opaque halo effect around each glyph
|
|
||||||
if (hudElement->opaquePixelHalo) {
|
if (hudElement->opaquePixelHalo) {
|
||||||
for (int // -negative index values allowed here ...
|
unsigned int srcIdx = 0;
|
||||||
srcIdx=0, dstPre=-((fb_w+1)*sizeof(PIXEL_TYPE)), dstIdx=0, dstPost=((fb_w-1)*sizeof(PIXEL_TYPE));
|
unsigned int texIdx = 0;
|
||||||
srcIdx<count;
|
for (unsigned int i=0; i<fb_h; i++, texIdx+=texSubRowStride) {
|
||||||
srcIdx++, dstPre+=sizeof(PIXEL_TYPE), dstIdx+=sizeof(PIXEL_TYPE), dstPost+=sizeof(PIXEL_TYPE))
|
for (unsigned int j=0; j<fb_w; j++, srcIdx++, texIdx+=dstPointStride) {
|
||||||
{
|
uint8_t value = *(fb + srcIdx);
|
||||||
uint8_t index = *(fb + srcIdx);
|
PIXEL_TYPE rgb = (((PIXEL_TYPE)(colormap[value].red) << SHIFT_R) |
|
||||||
PIXEL_TYPE rgb = (((PIXEL_TYPE)(colormap[index].red) << SHIFT_R) |
|
((PIXEL_TYPE)(colormap[value].green) << SHIFT_G) |
|
||||||
((PIXEL_TYPE)(colormap[index].green) << SHIFT_G) |
|
((PIXEL_TYPE)(colormap[value].blue) << SHIFT_B));
|
||||||
((PIXEL_TYPE)(colormap[index].blue) << SHIFT_B));
|
|
||||||
if (!rgb) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if USE_RGBA4444
|
unsigned int dstIdx = texIdx;
|
||||||
#define SEMI_OPAQUE (0x0C << SHIFT_A)
|
|
||||||
#else
|
|
||||||
#define SEMI_OPAQUE (0xC0 << SHIFT_A)
|
|
||||||
#endif
|
|
||||||
const unsigned int col = (srcIdx % fb_w);
|
|
||||||
|
|
||||||
if (dstPre >= 0) { // north pixels
|
// perform "eight patch" on adjacent pixels
|
||||||
if (col != 0) {
|
if (rgb) {
|
||||||
*((PIXEL_TYPE*)(parent->texPixels + dstPre)) |= SEMI_OPAQUE;
|
EightPatchArgs_s args = {
|
||||||
}
|
.parent = parent,
|
||||||
*((PIXEL_TYPE*)(parent->texPixels + dstPre + sizeof(PIXEL_TYPE) )) |= SEMI_OPAQUE;
|
.pixelSize = pixelSize,
|
||||||
if (col < fb_w-1) {
|
.glyphScale = glyphScale,
|
||||||
*((PIXEL_TYPE*)(parent->texPixels + dstPre + (2*sizeof(PIXEL_TYPE)) )) |= SEMI_OPAQUE;
|
.fb_h = fb_h,
|
||||||
}
|
.fb_w = fb_w,
|
||||||
}
|
.srcIdx = srcIdx,
|
||||||
|
.dstIdx = dstIdx,
|
||||||
if (col != 0) { // west pixel
|
};
|
||||||
*((PIXEL_TYPE*)(parent->texPixels + dstIdx - sizeof(PIXEL_TYPE) )) |= SEMI_OPAQUE;
|
_eightpatch_opaquePixelHaloFilter(args);
|
||||||
}
|
|
||||||
|
|
||||||
if (col < fb_w-1) { // east pixel
|
|
||||||
*((PIXEL_TYPE*)(parent->texPixels + dstIdx + sizeof(PIXEL_TYPE) )) |= SEMI_OPAQUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dstPost < countOut) { // south pixels
|
|
||||||
if (col != 0) {
|
|
||||||
*((PIXEL_TYPE*)(parent->texPixels + dstPost)) |= SEMI_OPAQUE;
|
|
||||||
}
|
|
||||||
*((PIXEL_TYPE*)(parent->texPixels + dstPost + sizeof(PIXEL_TYPE) )) |= SEMI_OPAQUE;
|
|
||||||
if (col < fb_w-1) {
|
|
||||||
*((PIXEL_TYPE*)(parent->texPixels + dstPost + (2*sizeof(PIXEL_TYPE)) )) |= SEMI_OPAQUE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,8 +24,9 @@
|
|||||||
unsigned int tplHeight; /* template height */ \
|
unsigned int tplHeight; /* template height */ \
|
||||||
\
|
\
|
||||||
uint8_t *pixels; /* raw indexed data */ \
|
uint8_t *pixels; /* raw indexed data */ \
|
||||||
unsigned int pixWidth; /* FB width -- FIXME TODO : this is really the same as GLModel.texWidth */ \
|
unsigned int pixWidth; /* FB width -- this is the same as GLModel.texWidth if glyphMultiplier is 1 */ \
|
||||||
unsigned int pixHeight; /* FB height -- FIXME TODO : this is really the same as GLModel.texHeight */ \
|
unsigned int pixHeight; /* FB height -- this is the same as GLModel.texHeight if glyphMultiplier is 1 */ \
|
||||||
|
unsigned int glyphMultiplier; \
|
||||||
\
|
\
|
||||||
interface_colorscheme_t colorScheme; \
|
interface_colorscheme_t colorScheme; \
|
||||||
bool blackIsTransparent; \
|
bool blackIsTransparent; \
|
||||||
|
@ -37,8 +37,8 @@
|
|||||||
#define MAINROW 4 // main keyboard row offset
|
#define MAINROW 4 // main keyboard row offset
|
||||||
#define SWITCHCOL 0
|
#define SWITCHCOL 0
|
||||||
|
|
||||||
#define KBD_FB_WIDTH (KBD_TEMPLATE_COLS * FONT80_WIDTH_PIXELS)
|
#define KBD_FB_WIDTH (KBD_TEMPLATE_COLS * FONT80_WIDTH_PIXELS) // 10 * 7 == 70
|
||||||
#define KBD_FB_HEIGHT (KBD_TEMPLATE_ROWS * FONT_HEIGHT_PIXELS)
|
#define KBD_FB_HEIGHT (KBD_TEMPLATE_ROWS * FONT_HEIGHT_PIXELS) // 8 * 16 == 128
|
||||||
|
|
||||||
#define KBD_OBJ_W 2.0
|
#define KBD_OBJ_W 2.0
|
||||||
#define KBD_OBJ_H 2.0
|
#define KBD_OBJ_H 2.0
|
||||||
@ -129,27 +129,34 @@ static struct {
|
|||||||
|
|
||||||
bool ctrlPressed;
|
bool ctrlPressed;
|
||||||
|
|
||||||
|
unsigned int glyphMultiplier;
|
||||||
|
|
||||||
struct timespec timingBegin;
|
struct timespec timingBegin;
|
||||||
} kbd = { 0 };
|
} kbd = { 0 };
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Misc internal methods
|
// Misc internal methods
|
||||||
|
|
||||||
|
#warning FIXME TODO ... make this a generic GLModelHUDElement function
|
||||||
static void _rerender_character(int col, int row) {
|
static void _rerender_character(int col, int row) {
|
||||||
GLModelHUDKeyboard *hudKeyboard = (GLModelHUDKeyboard *)(kbd.model->custom);
|
GLModelHUDKeyboard *hudKeyboard = (GLModelHUDKeyboard *)(kbd.model->custom);
|
||||||
|
|
||||||
// re-generate texture from indexed color
|
// In English, this changes one glyph within the keyboard texture data to be the (un)selected color. It handles
|
||||||
const unsigned int colCount = 1;
|
// scaling from indexed color to RGBA8888 (4x) and then possibly scaling to 2x or greater.
|
||||||
const unsigned int pixCharsWidth = FONT80_WIDTH_PIXELS*colCount;
|
|
||||||
const unsigned int rowStride = hudKeyboard->pixWidth - pixCharsWidth;
|
|
||||||
unsigned int srcIdx = (row * hudKeyboard->pixWidth * FONT_HEIGHT_PIXELS) + (col * FONT80_WIDTH_PIXELS);
|
|
||||||
unsigned int dstIdx = srcIdx * sizeof(PIXEL_TYPE);
|
|
||||||
|
|
||||||
for (unsigned int i=0; i<FONT_HEIGHT_PIXELS; i++) {
|
const unsigned int fb_w = hudKeyboard->pixWidth;
|
||||||
for (unsigned int j=0; j<pixCharsWidth; j++) {
|
const unsigned int pixelSize = sizeof(PIXEL_TYPE);
|
||||||
|
const unsigned int glyphScale = hudKeyboard->glyphMultiplier;
|
||||||
|
const unsigned int dstPointStride = pixelSize * glyphScale;
|
||||||
|
const unsigned int dstRowStride = fb_w * dstPointStride;
|
||||||
|
const unsigned int texSubRowStride = dstRowStride + (dstRowStride * (glyphScale-1));
|
||||||
|
const unsigned int indexedIdx = (row * fb_w * FONT_HEIGHT_PIXELS) + (col * FONT80_WIDTH_PIXELS);
|
||||||
|
unsigned int texIdx = ((row * fb_w * FONT_HEIGHT_PIXELS * /*1 row:*/glyphScale) + (col * FONT80_WIDTH_PIXELS)) * dstPointStride;
|
||||||
|
|
||||||
// HACK : red <-> green swap
|
for (unsigned int i=0; i<FONT_HEIGHT_PIXELS; i++, texIdx+=texSubRowStride) {
|
||||||
PIXEL_TYPE rgba = *((PIXEL_TYPE *)(kbd.model->texPixels + dstIdx));
|
for (unsigned int j=0; j<FONT80_WIDTH_PIXELS; j++, texIdx+=dstPointStride) {
|
||||||
|
// HACK : red <-> green swap of texture data
|
||||||
|
PIXEL_TYPE rgba = *((PIXEL_TYPE *)(kbd.model->texPixels + texIdx));
|
||||||
PIXEL_TYPE r = (rgba >> SHIFT_R) & MAX_SATURATION;
|
PIXEL_TYPE r = (rgba >> SHIFT_R) & MAX_SATURATION;
|
||||||
PIXEL_TYPE g = (rgba >> SHIFT_G) & MAX_SATURATION;
|
PIXEL_TYPE g = (rgba >> SHIFT_G) & MAX_SATURATION;
|
||||||
#if USE_RGBA4444
|
#if USE_RGBA4444
|
||||||
@ -157,13 +164,16 @@ static void _rerender_character(int col, int row) {
|
|||||||
#else
|
#else
|
||||||
rgba = ( ((rgba>>SHIFT_B)<<SHIFT_B) | (r << SHIFT_G) | (g << SHIFT_R) );
|
rgba = ( ((rgba>>SHIFT_B)<<SHIFT_B) | (r << SHIFT_G) | (g << SHIFT_R) );
|
||||||
#endif
|
#endif
|
||||||
*( (PIXEL_TYPE *)(kbd.model->texPixels + dstIdx) ) = rgba;
|
// scale texture data 1x, 2x, ...
|
||||||
|
unsigned int dstIdx = texIdx;
|
||||||
srcIdx += 1;
|
for (unsigned int k=0; k<glyphScale; k++, dstIdx+=dstRowStride) {
|
||||||
dstIdx += sizeof(PIXEL_TYPE);
|
for (unsigned int l=0; l<glyphScale; l++, dstIdx+=pixelSize) {
|
||||||
|
*( (PIXEL_TYPE *)(kbd.model->texPixels + dstIdx) ) = rgba;
|
||||||
|
}
|
||||||
|
dstIdx -= dstPointStride;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
srcIdx += rowStride;
|
texIdx -= (FONT80_WIDTH_PIXELS * dstPointStride);
|
||||||
dstIdx = srcIdx * sizeof(PIXEL_TYPE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
kbd.model->texDirty = true;
|
kbd.model->texDirty = true;
|
||||||
@ -464,6 +474,7 @@ static void *_create_touchkbd_hud(void) {
|
|||||||
if (hudKeyboard) {
|
if (hudKeyboard) {
|
||||||
hudKeyboard->blackIsTransparent = true;
|
hudKeyboard->blackIsTransparent = true;
|
||||||
hudKeyboard->opaquePixelHalo = true;
|
hudKeyboard->opaquePixelHalo = true;
|
||||||
|
hudKeyboard->glyphMultiplier = kbd.glyphMultiplier;
|
||||||
}
|
}
|
||||||
return hudKeyboard;
|
return hudKeyboard;
|
||||||
}
|
}
|
||||||
@ -498,7 +509,9 @@ static void gltouchkbd_setup(void) {
|
|||||||
|
|
||||||
gltouchkbd_shutdown();
|
gltouchkbd_shutdown();
|
||||||
|
|
||||||
kbd.model = mdlCreateQuad(-1.0, -1.0, KBD_OBJ_W, KBD_OBJ_H, MODEL_DEPTH, KBD_FB_WIDTH, KBD_FB_HEIGHT, (GLCustom){
|
GLsizei texW = KBD_FB_WIDTH * kbd.glyphMultiplier;
|
||||||
|
GLsizei texH = KBD_FB_HEIGHT * kbd.glyphMultiplier;
|
||||||
|
kbd.model = mdlCreateQuad(-1.0, -1.0, KBD_OBJ_W, KBD_OBJ_H, MODEL_DEPTH, texW, texH, (GLCustom){
|
||||||
.create = &_create_touchkbd_hud,
|
.create = &_create_touchkbd_hud,
|
||||||
.setup = &_setup_touchkbd_hud,
|
.setup = &_setup_touchkbd_hud,
|
||||||
.destroy = &_destroy_touchkbd_hud,
|
.destroy = &_destroy_touchkbd_hud,
|
||||||
@ -974,6 +987,8 @@ static void _init_gltouchkbd(void) {
|
|||||||
kbd.ctrlCol = DEFAULT_CTRL_COL;
|
kbd.ctrlCol = DEFAULT_CTRL_COL;
|
||||||
kbd.ctrlRow = CTRLROW;
|
kbd.ctrlRow = CTRLROW;
|
||||||
|
|
||||||
|
kbd.glyphMultiplier = 1;
|
||||||
|
|
||||||
glnode_registerNode(RENDER_LOW, (GLNode){
|
glnode_registerNode(RENDER_LOW, (GLNode){
|
||||||
.setup = &gltouchkbd_setup,
|
.setup = &gltouchkbd_setup,
|
||||||
.shutdown = &gltouchkbd_shutdown,
|
.shutdown = &gltouchkbd_shutdown,
|
||||||
|
@ -71,6 +71,7 @@ static struct {
|
|||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
GLModel *model;
|
GLModel *model;
|
||||||
|
unsigned int glyphMultiplier;
|
||||||
bool topLeftShowing;
|
bool topLeftShowing;
|
||||||
bool topRightShowing;
|
bool topRightShowing;
|
||||||
} menu = { 0 };
|
} menu = { 0 };
|
||||||
@ -356,6 +357,7 @@ static void *_create_touchmenu(void) {
|
|||||||
if (hudMenu) {
|
if (hudMenu) {
|
||||||
hudMenu->blackIsTransparent = true;
|
hudMenu->blackIsTransparent = true;
|
||||||
hudMenu->opaquePixelHalo = true;
|
hudMenu->opaquePixelHalo = true;
|
||||||
|
hudMenu->glyphMultiplier = menu.glyphMultiplier;
|
||||||
}
|
}
|
||||||
return hudMenu;
|
return hudMenu;
|
||||||
}
|
}
|
||||||
@ -376,7 +378,10 @@ static void gltouchmenu_setup(void) {
|
|||||||
LOG("gltouchmenu_setup ...");
|
LOG("gltouchmenu_setup ...");
|
||||||
|
|
||||||
mdlDestroyModel(&menu.model);
|
mdlDestroyModel(&menu.model);
|
||||||
menu.model = mdlCreateQuad(-1.0, 1.0-MENU_OBJ_H, MENU_OBJ_W, MENU_OBJ_H, MODEL_DEPTH, MENU_FB_WIDTH, MENU_FB_HEIGHT, (GLCustom){
|
|
||||||
|
GLsizei texW = MENU_FB_WIDTH * menu.glyphMultiplier;
|
||||||
|
GLsizei texH = MENU_FB_HEIGHT * menu.glyphMultiplier;
|
||||||
|
menu.model = mdlCreateQuad(-1.0, 1.0-MENU_OBJ_H, MENU_OBJ_W, MENU_OBJ_H, MODEL_DEPTH, texW, texH, (GLCustom){
|
||||||
.create = &_create_touchmenu,
|
.create = &_create_touchmenu,
|
||||||
.setup = &_setup_touchmenu,
|
.setup = &_setup_touchmenu,
|
||||||
.destroy = &_destroy_touchmenu,
|
.destroy = &_destroy_touchmenu,
|
||||||
@ -552,6 +557,8 @@ static void _init_gltouchmenu(void) {
|
|||||||
interface_setTouchMenuEnabled = &gltouchmenu_setTouchMenuEnabled;
|
interface_setTouchMenuEnabled = &gltouchmenu_setTouchMenuEnabled;
|
||||||
interface_setTouchMenuVisibility = &gltouchmenu_setTouchMenuVisibility;
|
interface_setTouchMenuVisibility = &gltouchmenu_setTouchMenuVisibility;
|
||||||
|
|
||||||
|
menu.glyphMultiplier = 1;
|
||||||
|
|
||||||
glnode_registerNode(RENDER_TOP, (GLNode){
|
glnode_registerNode(RENDER_TOP, (GLNode){
|
||||||
.setup = &gltouchmenu_setup,
|
.setup = &gltouchmenu_setup,
|
||||||
.shutdown = &gltouchmenu_shutdown,
|
.shutdown = &gltouchmenu_shutdown,
|
||||||
|
Loading…
Reference in New Issue
Block a user