From 27f2441772d8c4ccdb2f9d56a8ac09ffcdafdf4d Mon Sep 17 00:00:00 2001 From: Hominem te esse Date: Sat, 5 Mar 2011 19:11:31 +0100 Subject: [PATCH] * caching of last attribute value (for AttributeText/Image element), to not search the config file every frame * drawing text (font) do not use rmSetupQuad anymore, wasn't needed anyway (Also reduced branching for Pixmap/quad) * Image element have a new "scaled" option to define if the drawing of the Image should respect the screen scaling policy (for 4:3, or 16:9 adaptation). Background element use "scaled=0" by default to take the full screen width and height. * drawing text can used two mode for limiting the text size. When an element have a "width" or "height" defined, by default we use "clipping" (everything larger than width or height will not be drawn). With the "wrap=1" option for text element, you can change this default behavior to wrap the text instead. Finally if you don't define width/height, the full text wil be drawn, without any check. * Element width and height definition can use the string "DIM_INF" to mean "maximum/infinite" (bound to the max screenwidth/screenheight). This is to be used instead of putting the real max screen width/height (as "heigth=512"), as they may change depending of the use of NTSC/PAL. Example of conf_theme.cfg. To define a background, and then a "decorative frame" layer: main0: type=Background main1: type=StaticImage default=main_frames aligned=0 scaled=0 width=DIM_INF height=DIM_INF ... To define a Text element using wraping: ... info7: type=AttributeText attribute=Description display=2 aligned=0 wrap=1 x=65 y=180 width=300 ... And finally, for this last specicif question you have, the answer is "Don't ask" ;) --- include/fntsys.h | 2 +- include/renderman.h | 17 +-- include/themes.h | 17 ++- src/dia.c | 62 +++++------ src/fntsys.c | 103 ++++++------------ src/gui.c | 18 ++-- src/renderman.c | 158 ++++++++++++---------------- src/themes.c | 297 ++++++++++++++++++++++++++++++++-------------------- 8 files changed, 347 insertions(+), 327 deletions(-) diff --git a/include/fntsys.h b/include/fntsys.h index 6fab535..ded91d7 100644 --- a/include/fntsys.h +++ b/include/fntsys.h @@ -40,7 +40,7 @@ void fntRelease(int id); void fntSetAspectRatio(float aw, float ah); /** Renders a string -* @return Width of the string rendered */ +* @return the new x position after drawing */ int fntRenderString(int font, int x, int y, short aligned, const unsigned char* string, u64 colour); /** Renders a text with specified window dimensions */ diff --git a/include/renderman.h b/include/renderman.h index 4f8bb9e..1934525 100644 --- a/include/renderman.h +++ b/include/renderman.h @@ -3,12 +3,13 @@ #include -#define DIM_INF -1 -#define DIM_UNDEF -2 +#define DIM_UNDEF -1 #define ALIGN_NONE 0 #define ALIGN_CENTER 1 +#define SCALING_NONE 0 +#define SCALING_RATIO 1 /// GSKit CLUT base struct. This should've been in gsKit from the start :) typedef struct { @@ -72,16 +73,16 @@ void rmDispatch(void); void rmDrawQuad(rm_quad_t* q); -void rmSetupQuad(GSTEXTURE* txt, int x, int y, short aligned, int w, int h, u64 color, rm_quad_t* q); +void rmSetupQuad(GSTEXTURE* txt, int x, int y, short aligned, int w, int h, short scaled, u64 color, rm_quad_t* q); /** Queues a specified pixmap (tinted with colour) to be rendered on specified position */ -void rmDrawPixmap(GSTEXTURE* txt, int x, int y, short aligned, int w, int h, u64 color); +void rmDrawPixmap(GSTEXTURE* txt, int x, int y, short aligned, int w, int h, short scaled, u64 color); -void rmDrawOverlayPixmap(GSTEXTURE* overlay, int x, int y, short aligned, int w, int h, u64 color, +void rmDrawOverlayPixmap(GSTEXTURE* overlay, int x, int y, short aligned, int w, int h, short scaled, u64 color, GSTEXTURE* inlay, int ulx, int uly, int urx, int ury, int blx, int bly, int brx, int bry); /** Queues a opaque rectangle to be rendered */ -void rmDrawRect(int x, int y, short aligned, int w, int h, u64 color); +void rmDrawRect(int x, int y, int w, int h, u64 color); /** Queues a single color line to be rendered */ void rmDrawLine(int x, int y, int x1, int y1, u64 color); @@ -108,10 +109,14 @@ void rmResetAspectRatio(); /** gets the current aspect ratio */ void rmGetAspectRatio(float *w, float *h); +void rmApplyAspectRatio(int* w, int* h); + void rmSetShiftRatio(float height); void rmResetShiftRatio(); +void rmApplyShiftRatio(int* y); + /** sets the transposition coordiantes (all content is transposed with these values) */ void rmSetTransposition(float x, float y); diff --git a/include/themes.h b/include/themes.h index b160fed..2e9a5c5 100644 --- a/include/themes.h +++ b/include/themes.h @@ -27,7 +27,8 @@ typedef struct { typedef struct { // Attributes for: AttributeImage int currentUid; - char currentName[32]; + int currentItemId; + char* currentValue; // Attributes for: AttributeImage & GameImage image_cache_t* cache; @@ -42,10 +43,17 @@ typedef struct { } mutable_image_t; typedef struct { - int displayMode; - char* attribute; + // Attributes for: AttributeText & StaticText + char* value; + int sizingMode; + + // Attributes for: AttributeText char* alias; -} attribute_text_t; + int displayMode; + + int currentItemId; + char* currentValue; +} mutable_text_t; typedef struct { int displayedItems; @@ -61,6 +69,7 @@ typedef struct theme_element { short aligned; int width; int height; + short scaled; u64 color; int font; diff --git a/src/dia.c b/src/dia.c index dd8175c..68d2cf6 100644 --- a/src/dia.c +++ b/src/dia.c @@ -38,20 +38,14 @@ static int screenHeight; #define KEYB_ITEMS (KEYB_WIDTH * KEYB_HEIGHT) static void diaDrawBoundingBox(int x, int y, int w, int h, int focus) { - float aw, ah; - rmGetAspectRatio(&aw, &ah); - rmResetAspectRatio(); - if (focus) - rmDrawRect(x - 5, y, ALIGN_NONE, w + 10, h + 10, gTheme->selTextColor & gColFocus); + rmDrawRect(x - 5, y, w + 10, h + 10, gTheme->selTextColor & gColFocus); else - rmDrawRect(x - 5, y, ALIGN_NONE, w + 10, h + 10, gTheme->textColor & gColFocus); - - rmSetAspectRatio(aw, ah); + rmDrawRect(x - 5, y, w + 10, h + 10, gTheme->textColor & gColFocus); } int diaShowKeyb(char* text, int maxLen) { - int i, j, len = strlen(text), selkeyb = 0, w; + int i, j, len = strlen(text), selkeyb = 0, x, w; int selchar = 0, selcommand = -1; char c[2] = "\0\0"; char keyb0[KEYB_ITEMS] = { @@ -79,7 +73,7 @@ int diaShowKeyb(char* text, int maxLen) { rmStartFrame(); guiDrawBGPlasma(); - rmDrawRect(0, 0, ALIGN_NONE, DIM_INF, DIM_INF, gColDarker); + rmDrawRect(0, 0, screenWidth, screenHeight, gColDarker); //Text fntRenderString(FNT_DEFAULT, 50, 120, ALIGN_NONE, text, gTheme->textColor); @@ -92,20 +86,22 @@ int diaShowKeyb(char* text, int maxLen) { for (i = 0; i < KEYB_WIDTH; i++) { c[0] = keyb[i + j * KEYB_WIDTH]; - w = fntRenderString(FNT_DEFAULT, 50 + i*32, 170 + 3 * UI_SPACING_H * j, ALIGN_NONE, c, gTheme->uiTextColor); + x = 50 + i * 32; + w = fntRenderString(FNT_DEFAULT, x, 170 + 3 * UI_SPACING_H * j, ALIGN_NONE, c, gTheme->uiTextColor) - x; if ((i + j * KEYB_WIDTH) == selchar) - diaDrawBoundingBox(50 + i*32, 170 + 3 * UI_SPACING_H * j, w, UI_SPACING_H, 0); + diaDrawBoundingBox(x, 170 + 3 * UI_SPACING_H * j, w, UI_SPACING_H, 0); } } // Commands for (i = 0; i < KEYB_HEIGHT; i++) { if (cmdicons[i]) - rmDrawPixmap(cmdicons[i], 448, 170 + 3 * UI_SPACING_H * i, ALIGN_NONE, DIM_UNDEF, DIM_UNDEF, gDefaultCol); + rmDrawPixmap(cmdicons[i], 448, 170 + 3 * UI_SPACING_H * i, ALIGN_NONE, cmdicons[i]->Width, cmdicons[i]->Height, SCALING_RATIO, gDefaultCol); - w = fntRenderString(FNT_DEFAULT, 489, 170 + 3 * UI_SPACING_H * i, ALIGN_NONE, commands[i], gTheme->uiTextColor); + x = 489; + w = fntRenderString(FNT_DEFAULT, x, 170 + 3 * UI_SPACING_H * i, ALIGN_NONE, commands[i], gTheme->uiTextColor) - x; if (i == selcommand) - diaDrawBoundingBox(489, 170 + 3 * UI_SPACING_H * i, w, UI_SPACING_H, 0); + diaDrawBoundingBox(x, 170 + 3 * UI_SPACING_H * i, w, UI_SPACING_H, 0); } rmEndFrame(); @@ -215,7 +211,7 @@ static int diaShowColSel(unsigned char *r, unsigned char *g, unsigned char *b) { rmStartFrame(); guiDrawBGPlasma(); - rmDrawRect(0, 0, ALIGN_NONE, DIM_INF, DIM_INF, gColDarker); + rmDrawRect(0, 0, screenWidth, screenHeight, gColDarker); // "Color selection" fntRenderString(FNT_DEFAULT, 50, 50, ALIGN_NONE, "Colour selection", GS_SETREG_RGBA(0x060, 0x060, 0x060, 0x060)); @@ -234,11 +230,11 @@ static int diaShowColSel(unsigned char *r, unsigned char *g, unsigned char *b) { u64 dcol = GS_SETREG_RGBA(cc[0], cc[1], cc[2], 0x80); if (selc == co) - rmDrawRect(x, y, ALIGN_NONE, 200, 20, GS_SETREG_RGBA(0x060, 0x060, 0x060, 0x60)); + rmDrawRect(x, y, 200, 20, GS_SETREG_RGBA(0x060, 0x060, 0x060, 0x60)); else - rmDrawRect(x, y, ALIGN_NONE, 200, 20, GS_SETREG_RGBA(0x020, 0x020, 0x020, 0x60)); + rmDrawRect(x, y, 200, 20, GS_SETREG_RGBA(0x020, 0x020, 0x020, 0x60)); - rmDrawRect(x + 2, y + 2, ALIGN_NONE, 190.0f*(cc[co]*100/255)/100, 16, dcol); + rmDrawRect(x + 2, y + 2, 190.0f*(cc[co]*100/255)/100, 16, dcol); } // target color itself @@ -247,8 +243,8 @@ static int diaShowColSel(unsigned char *r, unsigned char *g, unsigned char *b) { x = 300; y = 75; - rmDrawRect(x, y, ALIGN_NONE, 70, 70, GS_SETREG_RGBA(0x060, 0x060, 0x060, 0x60)); - rmDrawRect(x+5, y+5, ALIGN_NONE, 60, 60, dcol); + rmDrawRect(x, y, 70, 70, GS_SETREG_RGBA(0x060, 0x060, 0x060, 0x60)); + rmDrawRect(x + 5, y + 5, 60, 60, dcol); rmEndFrame(); @@ -316,7 +312,7 @@ static void diaDrawHint(int text_id) { y = gTheme->usedHeight - 40; // render hint on the lower side of the screen. - rmDrawRect(x, y, ALIGN_NONE, DIM_INF, MENU_ITEM_HEIGHT + 10, gColDarker); + rmDrawRect(x, y, screenWidth - x, MENU_ITEM_HEIGHT + 10, gColDarker); fntRenderString(FNT_DEFAULT, x + 5, y + 5, ALIGN_NONE, text, gTheme->textColor); } @@ -343,9 +339,9 @@ static void diaRenderItem(int x, int y, struct UIItem *item, int selected, int h // width is text length in pixels... const char *txt = diaGetLocalisedText(item->label.text, item->label.stringId); if(txt && strlen(txt)) - *w = fntRenderString(FNT_DEFAULT, x, y, ALIGN_NONE, txt, txtcol); + *w = fntRenderString(FNT_DEFAULT, x, y, ALIGN_NONE, txt, txtcol) - x; else - *w = fntRenderString(FNT_DEFAULT, x, y, ALIGN_NONE, _l(_STR_NOT_SET), txtcol); + *w = fntRenderString(FNT_DEFAULT, x, y, ALIGN_NONE, _l(_STR_NOT_SET), txtcol) - x; break; } @@ -383,7 +379,7 @@ static void diaRenderItem(int x, int y, struct UIItem *item, int selected, int h case UI_OK: { const char *txt = _l(_STR_OK); - *w = fntRenderString(FNT_DEFAULT, x, y, ALIGN_NONE, txt, txtcol); + *w = fntRenderString(FNT_DEFAULT, x, y, ALIGN_NONE, txt, txtcol) - x; break; } @@ -391,15 +387,15 @@ static void diaRenderItem(int x, int y, struct UIItem *item, int selected, int h char tmp[10]; snprintf(tmp, 10, "%d", item->intvalue.current); - *w = fntRenderString(FNT_DEFAULT, x, y, ALIGN_NONE, tmp, txtcol); + *w = fntRenderString(FNT_DEFAULT, x, y, ALIGN_NONE, tmp, txtcol) - x; break; } case UI_STRING: { if(strlen(item->stringvalue.text)) - *w = fntRenderString(FNT_DEFAULT, x, y, ALIGN_NONE, item->stringvalue.text, txtcol); + *w = fntRenderString(FNT_DEFAULT, x, y, ALIGN_NONE, item->stringvalue.text, txtcol) - x; else - *w = fntRenderString(FNT_DEFAULT, x, y, ALIGN_NONE, _l(_STR_NOT_SET), txtcol); + *w = fntRenderString(FNT_DEFAULT, x, y, ALIGN_NONE, _l(_STR_NOT_SET), txtcol) - x; break; } @@ -412,13 +408,13 @@ static void diaRenderItem(int x, int y, struct UIItem *item, int selected, int h stars[i] = '*'; stars[i] = '\0'; - *w = fntRenderString(FNT_DEFAULT, x, y, ALIGN_NONE, stars, txtcol); + *w = fntRenderString(FNT_DEFAULT, x, y, ALIGN_NONE, stars, txtcol) - x; break; } case UI_BOOL: { const char *txtval = _l((item->intvalue.current) ? _STR_ON : _STR_OFF); - *w = fntRenderString(FNT_DEFAULT, x, y, ALIGN_NONE, txtval, txtcol); + *w = fntRenderString(FNT_DEFAULT, x, y, ALIGN_NONE, txtval, txtcol) - x; break; } @@ -428,14 +424,14 @@ static void diaRenderItem(int x, int y, struct UIItem *item, int selected, int h if (!tv) tv = _l(_STR_NO_ITEMS); - *w = fntRenderString(FNT_DEFAULT, x, y, ALIGN_NONE, tv, txtcol); + *w = fntRenderString(FNT_DEFAULT, x, y, ALIGN_NONE, tv, txtcol) - x; break; } case UI_COLOUR: { - rmDrawRect(x, y + 3, ALIGN_NONE, 25, 17, txtcol); + rmDrawRect(x, y + 3, 25, 17, txtcol); u64 dcol = GS_SETREG_RGBA(item->colourvalue.r, item->colourvalue.g, item->colourvalue.b, 0x80); - rmDrawRect(x + 2, y + 5, ALIGN_NONE, 21, 13, dcol); + rmDrawRect(x + 2, y + 5, 21, 13, dcol); *w = 25; *h = 17; diff --git a/src/fntsys.c b/src/fntsys.c index b53e3fa..0999088 100644 --- a/src/fntsys.c +++ b/src/fntsys.c @@ -473,23 +473,17 @@ int fntRenderString(int font, int x, int y, short aligned, const unsigned char* y -= MENU_ITEM_HEIGHT >> 1; } - // backup the aspect ratio, restore 1:1 to have the font rendering clean - float aw, ah; - rmGetAspectRatio(&aw, &ah); - rmResetAspectRatio(); + rmApplyShiftRatio(&y); uint32_t codepoint; uint32_t state = 0; - int w = 0, d; FT_Bool use_kerning = FT_HAS_KERNING(fnt->face); FT_UInt glyph_index, previous = 0; FT_Vector delta; // cache glyphs and render as we go for (; *string; ++string) { - unsigned char c = *string; - - if (utf8Decode(&state, &codepoint, c)) // accumulate the codepoint value + if (utf8Decode(&state, &codepoint, *string)) // accumulate the codepoint value continue; fnt_glyph_cache_entry_t* glyph = fntCacheGlyph(fnt, codepoint); @@ -502,13 +496,10 @@ int fntRenderString(int font, int x, int y, short aligned, const unsigned char* glyph_index = FT_Get_Char_Index(fnt->face, codepoint); if (glyph_index) { FT_Get_Kerning(fnt->face, previous, glyph_index, FT_KERNING_DEFAULT, &delta); - d = delta.x >> 6; - x += d; - w += d; + x += delta.x >> 6; } previous = glyph_index; } - // only if glyph has atlas placement if (glyph->allocation) { @@ -521,39 +512,33 @@ int fntRenderString(int font, int x, int y, short aligned, const unsigned char* * - this method would handle the preparetion of the quads and GS upload itself, * without the use of prim_quad_texture and rmSetupQuad... * - * 3. rmSetupQuad is cool for a few quads a frame, but glyphs are too many in numbers - * - seriously, all that branching for every letter is a bit much + * (3. rmSetupQuad is cool for a few quads a frame, but glyphs are too many in numbers + * - seriously, all that branching for every letter is a bit much) * * 4. We should use clut to keep the memory allocations sane - we're linear in the 32bit buffers * anyway, no reason to waste like we do! */ - rmSetupQuad(NULL, x, y, ALIGN_NONE, glyph->width, glyph->height, colour, &quad); - quad.ul.x += glyph->ox; - quad.br.x += glyph->ox; - quad.ul.y += glyph->oy; - quad.br.y += glyph->oy; + quad.color = colour; + quad.ul.x = x + glyph->ox; + quad.br.x = quad.ul.x + glyph->width; + quad.ul.y = y + glyph->oy; + quad.br.y = quad.ul.y + glyph->height; // UV is our own, custom thing here quad.txt = &glyph->atlas->surface; quad.ul.u = glyph->allocation->x; + quad.br.u = quad.ul.u + glyph->width; quad.ul.v = glyph->allocation->y; - - quad.br.u = glyph->allocation->x + glyph->width; - quad.br.v = glyph->allocation->y + glyph->height; + quad.br.v = quad.ul.v + glyph->height; rmDrawQuad(&quad); } - int ofs = glyph->shx >> 6; - w += ofs; - x += ofs; + x += glyph->shx >> 6; y += glyph->shy >> 6; } - // return to the prev. aspect ratio - rmSetAspectRatio(aw, ah); - - return w; + return x; } void fntRenderText(int font, int sx, int sy, size_t width, size_t height, const unsigned char* string, u64 colour) { @@ -562,25 +547,19 @@ void fntRenderText(int font, int sx, int sy, size_t width, size_t height, const font_t *fnt = &fonts[font]; SignalSema(gFontSemaId); + rmApplyShiftRatio(&sy); + int x = sx; int y = sy; int xm = sx + width; int ym = sy + height; - // backup the aspect ratio, restore 1:1 to have the font rendering clean - float aw, ah; - rmGetAspectRatio(&aw, &ah); - rmResetAspectRatio(); - uint32_t codepoint; uint32_t state = 0; - int w = 0, d; FT_Bool use_kerning = FT_HAS_KERNING(fnt->face); FT_UInt glyph_index, previous = 0; FT_Vector delta; - int hmax = 0; - // Note: We need to change this so that we'll accumulate whole word before doing a layout with it // for now this method breaks on any character - which is a bit ugly @@ -590,9 +569,7 @@ void fntRenderText(int font, int sx, int sy, size_t width, size_t height, const // cache glyphs and render as we go for (; *string; ++string) { - unsigned char c = *string; - - if (utf8Decode(&state, &codepoint, c)) // accumulate the codepoint value + if (utf8Decode(&state, &codepoint, *string)) // accumulate the codepoint value continue; fnt_glyph_cache_entry_t* glyph = fntCacheGlyph(fnt, codepoint); @@ -604,57 +581,41 @@ void fntRenderText(int font, int sx, int sy, size_t width, size_t height, const glyph_index = FT_Get_Char_Index(fnt->face, codepoint); if (glyph_index) { FT_Get_Kerning(fnt->face, previous, glyph_index, FT_KERNING_DEFAULT, &delta); - d = delta.x >> 6; - x += d; - w += d; + x += delta.x >> 6; } previous = glyph_index; } - // do we fit to xmax? - if ((x + glyph->width > xm) || (codepoint == '\n')) { + if (codepoint == '\n') { x = sx; - // y += hmax + 5; y += MENU_ITEM_HEIGHT; // hmax is too tight and unordered, generally - hmax = 0; - - if (codepoint == '\n') - continue; - - if (y > ym) // stepped over ymax - break; + continue; } - if (glyph->height > hmax) - hmax = glyph->height; - + if ((x + glyph->width > xm) || (y > ym)) // stepped over the max + break; + // only if glyph has atlas placement if (glyph->allocation) { - rmSetupQuad(NULL, x, y, ALIGN_NONE, glyph->width, glyph->height, colour, &quad); - quad.ul.x += glyph->ox; - quad.br.x += glyph->ox; - quad.ul.y += glyph->oy; - quad.br.y += glyph->oy; + quad.color = colour; + quad.ul.x = x + glyph->ox; + quad.br.x = quad.ul.x + glyph->width; + quad.ul.y = y + glyph->oy; + quad.br.y = quad.ul.y + glyph->height; // UV is our own, custom thing here quad.txt = &glyph->atlas->surface; quad.ul.u = glyph->allocation->x; + quad.br.u = quad.ul.u + glyph->width; quad.ul.v = glyph->allocation->y; - - quad.br.u = glyph->allocation->x + glyph->width; - quad.br.v = glyph->allocation->y + glyph->height; - + quad.br.v = quad.ul.v + glyph->height; + rmDrawQuad(&quad); } - int ofs = glyph->shx >> 6; - w += ofs; - x += ofs; + x += glyph->shx >> 6; y += glyph->shy >> 6; } - - // return to the prev. aspect ratio - rmSetAspectRatio(aw, ah); } void fntFitString(int font, unsigned char *string, size_t width) { diff --git a/src/gui.c b/src/gui.c index 1bce2a4..3dc1b80 100644 --- a/src/gui.c +++ b/src/gui.c @@ -792,7 +792,7 @@ static void guiDrawBusy() { GSTEXTURE* texture = thmGetTexture(LOAD0_ICON + guiFrameId % gTheme->loadingIconCount); if (texture && texture->Mem) { u64 mycolor = GS_SETREG_RGBA(0x080, 0x080, 0x080, bfadeout); - rmDrawPixmap(texture, gTheme->loadingIcon->posX, gTheme->loadingIcon->posY, gTheme->loadingIcon->aligned, gTheme->loadingIcon->width, gTheme->loadingIcon->height, mycolor); + rmDrawPixmap(texture, gTheme->loadingIcon->posX, gTheme->loadingIcon->posY, gTheme->loadingIcon->aligned, gTheme->loadingIcon->width, gTheme->loadingIcon->height, gTheme->loadingIcon->scaled, mycolor); } } } @@ -801,7 +801,7 @@ static int wfadeout = 0x0150; static void guiRenderGreeting() { int fade = wfadeout > 0xFF ? 0xFF : wfadeout; u64 mycolor = GS_SETREG_RGBA(0x10, 0x10, 0x10, fade >> 1); - rmDrawRect(0, 0, ALIGN_NONE, DIM_INF, DIM_INF, mycolor); + rmDrawRect(0, 0, screenWidth, screenHeight, mycolor); /* char introtxt[255]; snprintf(introtxt, 255, _l(_STR_OUL_VER), USBLD_VERSION); fntRenderString(screenWidth >> 1, gTheme->usedHeight >> 1, ALIGN_CENTER, introtxt, GS_SETREG_RGBA(0x060, 0x060, 0x060, wfadeout)); @@ -810,7 +810,7 @@ static void guiRenderGreeting() { GSTEXTURE* logo = thmGetTexture(LOGO_PICTURE); if (logo) { mycolor = GS_SETREG_RGBA(0x080, 0x080, 0x080, fade >> 1); - rmDrawPixmap(logo, screenWidth >> 1, gTheme->usedHeight >> 1, ALIGN_CENTER, DIM_UNDEF, DIM_UNDEF, mycolor); + rmDrawPixmap(logo, screenWidth >> 1, gTheme->usedHeight >> 1, ALIGN_CENTER, logo->Width, logo->Height, SCALING_RATIO, mycolor); } return; @@ -999,17 +999,17 @@ void guiDrawBGPlasma() { } pery = ymax; - rmDrawPixmap(&gBackgroundTex, 0, 0, ALIGN_NONE, DIM_INF, DIM_INF, gDefaultCol); + rmDrawPixmap(&gBackgroundTex, 0, 0, ALIGN_NONE, screenWidth, screenHeight, SCALING_NONE, gDefaultCol); } int guiDrawIconAndText(int iconId, int textId, int font, int x, int y, u64 color) { GSTEXTURE* iconTex = thmGetTexture(iconId); if (iconTex && iconTex->Mem) { - rmDrawPixmap(iconTex, x, y, ALIGN_NONE, DIM_UNDEF, DIM_UNDEF, gDefaultCol); + rmDrawPixmap(iconTex, x, y, ALIGN_NONE, iconTex->Width, iconTex->Height, SCALING_RATIO, gDefaultCol); x += iconTex->Width + 2; } - x += fntRenderString(font, x, y, ALIGN_NONE, _l(textId), color); + x = fntRenderString(font, x, y, ALIGN_NONE, _l(textId), color); return x; } @@ -1196,7 +1196,7 @@ int guiMsgBox(const char* text, int addAccept, struct UIItem *ui) { else guiShow(); - rmDrawRect(0, 0, ALIGN_NONE, DIM_INF, DIM_INF, gColDarker); + rmDrawRect(0, 0, screenWidth, screenHeight, gColDarker); rmDrawLine(50, 75, screenWidth - 50, 75, gColWhite); rmDrawLine(50, 410, screenWidth - 50, 410, gColWhite); @@ -1222,7 +1222,7 @@ void guiHandleDefferedIO(int *ptr, const unsigned char* message, int type, void guiShow(); - rmDrawRect(0, 0, ALIGN_NONE, DIM_INF, DIM_INF, gColDarker); + rmDrawRect(0, 0, screenWidth, screenHeight, gColDarker); fntRenderString(FNT_DEFAULT, screenWidth >> 1, gTheme->usedHeight >> 1, ALIGN_CENTER, message, gTheme->textColor); @@ -1238,7 +1238,7 @@ void guiRenderTextScreen(const unsigned char* message) { guiShow(); - rmDrawRect(0, 0, ALIGN_NONE, DIM_INF, DIM_INF, gColDarker); + rmDrawRect(0, 0, screenWidth, screenHeight, gColDarker); fntRenderString(FNT_DEFAULT, screenWidth >> 1, gTheme->usedHeight >> 1, ALIGN_CENTER, message, gTheme->textColor); diff --git a/src/renderman.c b/src/renderman.c index fb7d65c..e94c4c9 100644 --- a/src/renderman.c +++ b/src/renderman.c @@ -440,67 +440,47 @@ void rmEnd(void) { rmFlush(); } -void rmDrawQuad(rm_quad_t* q) { - if (!rmClipQuad(q)) - return; - - if (!rmPrepareTexture(q->txt)) // won't render if not ready! - return; - - if ((q->txt->PSM == GS_PSM_CT32) || - (q->txt->Clut && q->txt->ClutPSM == GS_PSM_CT32)) - { - gsKit_set_primalpha(gsGlobal, gDefaultAlpha, 0); - } - - gsKit_prim_sprite_texture(gsGlobal, q->txt, q->ul.x + transX, q->ul.y + transY, q->ul.u, - q->ul.v, q->br.x + transX, q->br.y + transY, q->br.u, q->br.v, order, q->color); - order++; - - gsKit_set_primalpha(gsGlobal, GS_BLEND_BACK2FRONT, 0); -} - -/** If txt is null, don't use DIM_UNDEF size ! */ -void rmSetupQuad(GSTEXTURE* txt, int x, int y, short aligned, int w, int h, u64 color, rm_quad_t* q) { - float drawX, drawY; - float drawW, drawH; - +/** If txt is null, don't use DIM_ADAPT size */ +void rmSetupQuad(GSTEXTURE* txt, int x, int y, short aligned, int w, int h, short scaled, u64 color, rm_quad_t* q) { if (aligned) { - if (w != DIM_UNDEF) - drawW = aspectWidth * w; + float dim; + if (w == DIM_UNDEF) + w = txt->Width; + if (h == DIM_UNDEF) + h = txt->Height; + + if (scaled) + dim = aspectWidth * (w >> 1); else - drawW = aspectWidth * txt->Width; - drawX = x - drawW / 2; + dim = w >> 1; + q->ul.x = x - dim; + q->br.x = x + dim; - if (h != DIM_UNDEF) - drawH = aspectHeight * h; + if (scaled) + dim = aspectHeight * (h >> 1); else - drawH = aspectHeight * txt->Height; - drawY = shiftY(y) - drawH / 2; - } - else { + dim = h >> 1; + q->ul.y = shiftY(y) - dim; + q->br.y = shiftY(y) + dim; + } else { if (w == DIM_UNDEF) - drawW = aspectWidth * txt->Width; - else if (w == DIM_INF) - drawW = gsGlobal->Width - x; + w = txt->Width; + if (h == DIM_UNDEF) + h = txt->Height; + + q->ul.x = x; + if (scaled) + q->br.x = x + aspectWidth * w; else - drawW = aspectWidth * w; - drawX = x; + q->br.x = x + w; - if (h == DIM_UNDEF) - drawH = aspectHeight * txt->Height; - else if (h == DIM_INF) - drawH = gsGlobal->Height - y; + q->ul.y = shiftY(y); + if (scaled) + q->br.y = shiftY(y) + aspectHeight * h; else - drawH = aspectHeight * h; - drawY = shiftY(y); + q->br.y = shiftY(y) + h; } - q->ul.x = drawX; - q->ul.y = drawY; - q->br.x = drawX + drawW; - q->br.y = drawY + drawH; - q->color = color; if (txt) { @@ -512,17 +492,39 @@ void rmSetupQuad(GSTEXTURE* txt, int x, int y, short aligned, int w, int h, u64 } } -void rmDrawPixmap(GSTEXTURE* txt, int x, int y, short aligned, int w, int h, u64 color) { +void rmDrawQuad(rm_quad_t* q) { // NO scaling, NO shift, NO alignment + if (!rmClipQuad(q)) + return; + + if (!rmPrepareTexture(q->txt)) // won't render if not ready! + return; + + if ((q->txt->PSM == GS_PSM_CT32) || (q->txt->Clut && q->txt->ClutPSM == GS_PSM_CT32)) + { + gsKit_set_primalpha(gsGlobal, gDefaultAlpha, 0); + } + + gsKit_prim_sprite_texture(gsGlobal, q->txt, + q->ul.x + transX, q->ul.y + transY, + q->ul.u, q->ul.v, + q->br.x + transX, q->br.y + transY, + q->br.u, q->br.v, order, q->color); + order++; + + gsKit_set_primalpha(gsGlobal, GS_BLEND_BACK2FRONT, 0); +} + +void rmDrawPixmap(GSTEXTURE* txt, int x, int y, short aligned, int w, int h, short scaled, u64 color) { rm_quad_t quad; - rmSetupQuad(txt, x, y, aligned, w, h, color, &quad); + rmSetupQuad(txt, x, y, aligned, w, h, scaled, color, &quad); rmDrawQuad(&quad); } -void rmDrawOverlayPixmap(GSTEXTURE* overlay, int x, int y, short aligned, int w, int h, u64 color, +void rmDrawOverlayPixmap(GSTEXTURE* overlay, int x, int y, short aligned, int w, int h, short scaled, u64 color, GSTEXTURE* inlay, int ulx, int uly, int urx, int ury, int blx, int bly, int brx, int bry) { rm_quad_t quad; - rmSetupQuad(overlay, x, y, aligned, w, h, color, &quad); + rmSetupQuad(overlay, x, y, aligned, w, h, scaled, color, &quad); if (!rmPrepareTexture(inlay)) return; @@ -540,45 +542,14 @@ void rmDrawOverlayPixmap(GSTEXTURE* overlay, int x, int y, short aligned, int w, rmDrawQuad(&quad); } -void rmDrawRect(int x, int y, short aligned, int w, int h, u64 color) { - // primitive clipping TODO: repair clipping ... - /*float x1 = x + w; - float y1 = y + h; - - if (clipRect.used) { - if (x > clipRect.x1) - return; - if (y > clipRect.y1) - return; - if (x1 < clipRect.x) - return; - if (y1 < clipRect.y) - return; - - if (x < clipRect.x) - x = clipRect.x; - - if (x1 > clipRect.x1) - x1 = clipRect.x1; - - if (y < clipRect.y) - y = clipRect.y; - - if (y1 > clipRect.y1) - y1 = clipRect.y1; - }*/ - - rm_quad_t quad; - rmSetupQuad(NULL, x, y, aligned, w, h, color, &quad); - +void rmDrawRect(int x, int y, int w, int h, u64 color) { gsKit_set_primalpha(gsGlobal, GS_SETREG_ALPHA(0,1,0,1,0), 0); - gsKit_prim_quad(gsGlobal, quad.ul.x + transX, quad.ul.y + transY, quad.br.x + transX, quad.ul.y + transY, quad.ul.x + transX, quad.br.y + transY, quad.br.x + transX, quad.br.y + transY, order, quad.color); + gsKit_prim_quad(gsGlobal, x + transX, shiftY(y) + transY, x + w + transX, shiftY(y) + transY, x + transX, shiftY(y) + h + transY, x + w + transX, shiftY(y) + h + transY, order, color); order++; gsKit_set_primalpha(gsGlobal, GS_BLEND_BACK2FRONT, 0); } void rmDrawLine(int x, int y, int x1, int y1, u64 color) { - // TODO: clipping. It is more complicated in this case gsKit_prim_line(gsGlobal, x + transX, shiftY(y) + transY, x1 + transX, shiftY(y1) + transY, order, color); } @@ -594,7 +565,7 @@ void rmClip(int x, int y, int w, int h) { clipRect.y1 = gsGlobal->Height; else clipRect.y1 = y + h; - clipRect.used = 0; // TODO: 1; + clipRect.used = 0; } /** Sets cipping to none */ @@ -617,6 +588,11 @@ void rmGetAspectRatio(float *w, float *h) { *h = aspectHeight; } +void rmApplyAspectRatio(int* w, int* h) { + *w = *w * aspectWidth; + *h = *h * aspectHeight; +} + void rmSetShiftRatio(float shiftYRatio) { shiftYVal = shiftYRatio; shiftY = &shiftYFunc; @@ -626,6 +602,10 @@ void rmResetShiftRatio() { shiftY = &identityFunc; } +void rmApplyShiftRatio(int* y) { + *y = shiftY(*y); +} + void rmSetTransposition(float x, float y) { transX = x; transY = y; diff --git a/src/themes.c b/src/themes.c index b5ede75..f3857ae 100644 --- a/src/themes.c +++ b/src/themes.c @@ -41,6 +41,10 @@ static char **guiThemesNames = NULL; #define DISPLAY_DEFINED 1 #define DISPLAY_NEVER 2 +#define SIZING_NONE -1 +#define SIZING_CLIP 0 +#define SIZING_WRAP 1 + static char *elementsType[] = { "AttributeText", "StaticText", @@ -58,10 +62,91 @@ static char *elementsType[] = { "LoadingIcon", }; +// Common functions for Text //////////////////////////////////////////////////////////////////////////////////////////////// + +static void endMutableText(theme_element_t* elem) { + mutable_text_t* mutableText = (mutable_text_t*) elem->extended; + if (mutableText) { + if (mutableText->value) + free(mutableText->value); + + if (mutableText->alias) + free(mutableText->alias); + + free(mutableText); + } + + free(elem); +} + +static mutable_text_t* initMutableText(char* themePath, config_set_t* themeConfig, theme_t* theme, char* name, int type, struct theme_element* elem, + char* value, char* alias, int displayMode, int sizingMode) { + + mutable_text_t* mutableText = (mutable_text_t*) malloc(sizeof(mutable_text_t)); + mutableText->currentItemId = -1; + mutableText->currentValue = NULL; + mutableText->alias = NULL; + + char elemProp[64]; + + snprintf(elemProp, 64, "%s_display", name); + configGetInt(themeConfig, elemProp, &displayMode); + mutableText->displayMode = displayMode; + + int length = strlen(value) + 1; + mutableText->value = (char*) malloc(length * sizeof(char)); + memcpy(mutableText->value, value, length); + + snprintf(elemProp, 64, "%s_wrap", name); + if (configGetInt(themeConfig, elemProp, &sizingMode)) { + if (sizingMode > 0) + mutableText->sizingMode = SIZING_WRAP; + } + + if ((elem->width != DIM_UNDEF) || (elem->height != DIM_UNDEF)) { + if (sizingMode == SIZING_NONE) + sizingMode = SIZING_CLIP; + + if (elem->width == DIM_UNDEF) + elem->width = screenWidth; + + if (elem->height == DIM_UNDEF) + elem->height = screenHeight; + } else + sizingMode = SIZING_NONE; + mutableText->sizingMode = sizingMode; + + if (type == TYPE_ATTRIBUTE_TEXT) { + snprintf(elemProp, 64, "%s_title", name); + configGetStr(themeConfig, elemProp, &alias); + if (!alias) { + if (value[0] == '#') + alias = &value[1]; + else + alias = value; + } + length = strlen(alias) + 1 + 3; + mutableText->alias = (char*) malloc(length * sizeof(char)); + if (mutableText->sizingMode == SIZING_WRAP) + snprintf(mutableText->alias, length, "%s :\n", alias); + else + snprintf(mutableText->alias, length, "%s : ", alias); + } else { + if (mutableText->sizingMode == SIZING_WRAP) + fntFitString(elem->font, mutableText->value, elem->width); + } + + return mutableText; +} + // StaticText /////////////////////////////////////////////////////////////////////////////////////////////////////////////// static void drawStaticText(struct menu_list* menu, struct submenu_list* item, config_set_t* config, struct theme_element* elem) { - fntRenderString(elem->font, elem->posX, elem->posY, elem->aligned, (char *) elem->extended, elem->color); + mutable_text_t* mutableText = (mutable_text_t*) elem->extended; + if (mutableText->sizingMode == SIZING_NONE) + fntRenderString(elem->font, elem->posX, elem->posY, elem->aligned, mutableText->value, elem->color); + else + fntRenderText(elem->font, elem->posX, elem->posY, elem->width, elem->height, mutableText->value, elem->color); } static void initStaticText(char* themePath, config_set_t* themeConfig, theme_t* theme, theme_element_t* elem, char* name, @@ -72,11 +157,8 @@ static void initStaticText(char* themePath, config_set_t* themeConfig, theme_t* snprintf(elemProp, 64, "%s_value", name); configGetStr(themeConfig, elemProp, &value); if (value) { - int length = strlen(value) + 1; - elem->extended = (char*) malloc(length * sizeof(char)); - memcpy(elem->extended, value, length); - // elem->endElem = &endBasic; does the job - + elem->extended = initMutableText(themePath, themeConfig, theme, name, TYPE_STATIC_TEXT, elem, value, NULL, DISPLAY_ALWAYS, SIZING_NONE); + elem->endElem = &endMutableText; elem->drawElem = &drawStaticText; } else LOG("elemStaticText %s: NO value, elem disabled !!\n", name); @@ -86,66 +168,45 @@ static void initStaticText(char* themePath, config_set_t* themeConfig, theme_t* static void drawAttributeText(struct menu_list* menu, struct submenu_list* item, config_set_t* config, struct theme_element* elem) { if (config) { - attribute_text_t* attributeText = (attribute_text_t*) elem->extended; - char *temp; - char result[300]; - - if (configGetStr(config, attributeText->attribute, &temp)) { - if (attributeText->displayMode == DISPLAY_NEVER) - fntRenderString(elem->font, elem->posX, elem->posY, elem->aligned, temp, elem->color); - else { - snprintf(result, 300, "%s : %s", attributeText->alias, temp); - fntRenderString(elem->font, elem->posX, elem->posY, elem->aligned, result, elem->color); + mutable_text_t* mutableText = (mutable_text_t*) elem->extended; + if (mutableText->currentItemId != item->item.id) { + // force refresh + mutableText->currentItemId = item->item.id; + mutableText->currentValue = NULL; + if (configGetStr(config, mutableText->value, &mutableText->currentValue)) { + if (mutableText->sizingMode == SIZING_WRAP) + fntFitString(elem->font, mutableText->currentValue, elem->width); } } - else if (attributeText->displayMode == DISPLAY_ALWAYS) { - snprintf(result, 300, "%s :", attributeText->alias); - fntRenderString(elem->font, elem->posX, elem->posY, elem->aligned, result, elem->color); - } + if (mutableText->currentValue) { + if (mutableText->displayMode == DISPLAY_NEVER) + if (mutableText->sizingMode == SIZING_NONE) + fntRenderString(elem->font, elem->posX, elem->posY, elem->aligned, mutableText->currentValue, elem->color); + else + fntRenderText(elem->font, elem->posX, elem->posY, elem->width, elem->height, mutableText->currentValue, elem->color); + else { + char result[300]; + snprintf(result, 300, "%s%s", mutableText->alias, mutableText->currentValue); + if (mutableText->sizingMode == SIZING_NONE) + fntRenderString(elem->font, elem->posX, elem->posY, elem->aligned, result, elem->color); + else + fntRenderText(elem->font, elem->posX, elem->posY, elem->width, elem->height, result, elem->color); + } + } else if (mutableText->displayMode == DISPLAY_ALWAYS) + fntRenderString(elem->font, elem->posX, elem->posY, elem->aligned, mutableText->alias, elem->color); } } -static void endAttributeText(theme_element_t* elem) { - attribute_text_t* attributeText = (attribute_text_t*) elem->extended; - free(attributeText->attribute); - free(attributeText->alias); - - free(elem); -} - static void initAttributeText(char* themePath, config_set_t* themeConfig, theme_t* theme, theme_element_t* elem, char* name, - char* attribute, char* alias, int displayMode) { + char* attribute) { char elemProp[64]; snprintf(elemProp, 64, "%s_attribute", name); configGetStr(themeConfig, elemProp, &attribute); if (attribute) { - attribute_text_t* attributeText = (attribute_text_t*) malloc(sizeof(attribute_text_t)); - - snprintf(elemProp, 64, "%s_display", name); - configGetInt(themeConfig, elemProp, &displayMode); - attributeText->displayMode = displayMode; - - snprintf(elemProp, 64, "%s_title", name); - configGetStr(themeConfig, elemProp, &alias); - if (!alias) { - if (attribute[0] == '#') - alias = &attribute[1]; - else - alias = attribute; - } - int length = strlen(alias) + 1; - attributeText->alias = (char*) malloc(length * sizeof(char)); - memcpy(attributeText->alias, alias, length); - - length = strlen(attribute) + 1; - attributeText->attribute = (char*) malloc(length * sizeof(char)); - memcpy(attributeText->attribute, attribute, length); - - elem->extended = attributeText; - elem->endElem = &endAttributeText; - + elem->extended = initMutableText(themePath, themeConfig, theme, name, TYPE_ATTRIBUTE_TEXT, elem, attribute, NULL, DISPLAY_ALWAYS, SIZING_NONE); + elem->endElem = &endMutableText; elem->drawElem = &drawAttributeText; } else LOG("elemAttributeText %s: NO attribute, elem disabled !!\n", name); @@ -241,7 +302,8 @@ static image_texture_t* initImageTexture(char* themePath, config_set_t* themeCon return texture; } -static void freeMutableImage(mutable_image_t* mutableImage) { +static void endMutableImage(struct theme_element* elem) { + mutable_image_t* mutableImage = (mutable_image_t*) elem->extended; if (mutableImage) { if (mutableImage->cache && !mutableImage->cacheLinked) cacheDestroyCache(mutableImage->cache); @@ -254,10 +316,6 @@ static void freeMutableImage(mutable_image_t* mutableImage) { free(mutableImage); } -} - -static void endMutableImage(struct theme_element* elem) { - freeMutableImage((mutable_image_t*) elem->extended); free(elem); } @@ -267,7 +325,8 @@ static mutable_image_t* initMutableImage(char* themePath, config_set_t* themeCon mutable_image_t* mutableImage = (mutable_image_t*) malloc(sizeof(mutable_image_t)); mutableImage->currentUid = -1; - mutableImage->currentName[0] = '\0'; + mutableImage->currentItemId = -1; + mutableImage->currentValue = NULL; mutableImage->cache = NULL; mutableImage->cacheLinked = 0; mutableImage->defaultTexture = NULL; @@ -321,11 +380,11 @@ static mutable_image_t* initMutableImage(char* themePath, config_set_t* themeCon static void drawStaticImage(struct menu_list* menu, struct submenu_list* item, config_set_t* config, struct theme_element* elem) { mutable_image_t* staticImage = (mutable_image_t*) elem->extended; if (staticImage->overlayTexture) { - rmDrawOverlayPixmap(&staticImage->overlayTexture->source, elem->posX, elem->posY, elem->aligned, elem->width, elem->height, gDefaultCol, + rmDrawOverlayPixmap(&staticImage->overlayTexture->source, elem->posX, elem->posY, elem->aligned, elem->width, elem->height, elem->scaled, gDefaultCol, &staticImage->defaultTexture->source, staticImage->overlayTexture->upperLeft_x, staticImage->overlayTexture->upperLeft_y, staticImage->overlayTexture->upperRight_x, staticImage->overlayTexture->upperRight_y, staticImage->overlayTexture->lowerLeft_x, staticImage->overlayTexture->lowerLeft_y, staticImage->overlayTexture->lowerRight_x, staticImage->overlayTexture->lowerRight_y); } else - rmDrawPixmap(&staticImage->defaultTexture->source, elem->posX, elem->posY, elem->aligned, elem->width, elem->height, gDefaultCol); + rmDrawPixmap(&staticImage->defaultTexture->source, elem->posX, elem->posY, elem->aligned, elem->width, elem->height, elem->scaled, gDefaultCol); } static void initStaticImage(char* themePath, config_set_t* themeConfig, theme_t* theme, theme_element_t* elem, char* name, @@ -369,15 +428,15 @@ static void drawGameImage(struct menu_list* menu, struct submenu_list* item, con } if (gameImage->overlayTexture) { - rmDrawOverlayPixmap(&gameImage->overlayTexture->source, elem->posX, elem->posY, elem->aligned, elem->width, elem->height, gDefaultCol, + rmDrawOverlayPixmap(&gameImage->overlayTexture->source, elem->posX, elem->posY, elem->aligned, elem->width, elem->height, elem->scaled, gDefaultCol, texture, gameImage->overlayTexture->upperLeft_x, gameImage->overlayTexture->upperLeft_y, gameImage->overlayTexture->upperRight_x, gameImage->overlayTexture->upperRight_y, gameImage->overlayTexture->lowerLeft_x, gameImage->overlayTexture->lowerLeft_y, gameImage->overlayTexture->lowerRight_x, gameImage->overlayTexture->lowerRight_y); } else - rmDrawPixmap(texture, elem->posX, elem->posY, elem->aligned, elem->width, elem->height, gDefaultCol); + rmDrawPixmap(texture, elem->posX, elem->posY, elem->aligned, elem->width, elem->height, elem->scaled, gDefaultCol); } else if (elem->type == TYPE_BACKGROUND) { if (gameImage->defaultTexture) - rmDrawPixmap(&gameImage->defaultTexture->source, elem->posX, elem->posY, elem->aligned, elem->width, elem->height, gDefaultCol); + rmDrawPixmap(&gameImage->defaultTexture->source, elem->posX, elem->posY, elem->aligned, elem->width, elem->height, elem->scaled, gDefaultCol); else guiDrawBGPlasma(); } @@ -401,29 +460,30 @@ static void initGameImage(char* themePath, config_set_t* themeConfig, theme_t* t static void drawAttributeImage(struct menu_list* menu, struct submenu_list* item, config_set_t* config, struct theme_element* elem) { if (config) { mutable_image_t* attributeImage = (mutable_image_t*) elem->extended; - char *value; - if (configGetStr(config, attributeImage->cache->suffix, &value)) { - if (strcmp(value, attributeImage->currentName)) { - // force refresh - attributeImage->currentUid = -1; - strcpy(attributeImage->currentName, value); - } + if (attributeImage->currentItemId != item->item.id) { + // force refresh + attributeImage->currentUid = -1; + attributeImage->currentItemId = item->item.id; + attributeImage->currentValue = NULL; + configGetStr(config, attributeImage->cache->suffix, &attributeImage->currentValue); + } + if (attributeImage->currentValue) { int posZ = 0; - GSTEXTURE* texture = cacheGetTexture(attributeImage->cache, menu->item->userdata, &posZ, &attributeImage->currentUid, value); + GSTEXTURE* texture = cacheGetTexture(attributeImage->cache, menu->item->userdata, &posZ, &attributeImage->currentUid, attributeImage->currentValue); if (texture && texture->Mem) { if (attributeImage->overlayTexture) { - rmDrawOverlayPixmap(&attributeImage->overlayTexture->source, elem->posX, elem->posY, elem->aligned, elem->width, elem->height, gDefaultCol, + rmDrawOverlayPixmap(&attributeImage->overlayTexture->source, elem->posX, elem->posY, elem->aligned, elem->width, elem->height, elem->scaled, gDefaultCol, texture, attributeImage->overlayTexture->upperLeft_x, attributeImage->overlayTexture->upperLeft_y, attributeImage->overlayTexture->upperRight_x, attributeImage->overlayTexture->upperRight_y, attributeImage->overlayTexture->lowerLeft_x, attributeImage->overlayTexture->lowerLeft_y, attributeImage->overlayTexture->lowerRight_x, attributeImage->overlayTexture->lowerRight_y); } else - rmDrawPixmap(texture, elem->posX, elem->posY, elem->aligned, elem->width, elem->height, gDefaultCol); - } + rmDrawPixmap(texture, elem->posX, elem->posY, elem->aligned, elem->width, elem->height, elem->scaled, gDefaultCol); - return; + return; + } } if (attributeImage->defaultTexture) - rmDrawPixmap(&attributeImage->defaultTexture->source, elem->posX, elem->posY, elem->aligned, elem->width, elem->height, gDefaultCol); + rmDrawPixmap(&attributeImage->defaultTexture->source, elem->posX, elem->posY, elem->aligned, elem->width, elem->height, elem->scaled, gDefaultCol); } } @@ -448,7 +508,7 @@ static void endBasic(theme_element_t* elem) { } static theme_element_t* initBasic(char* themePath, config_set_t* themeConfig, theme_t* theme, int screenWidth, int screenHeight, - char* name, int type, int x, int y, short aligned, int w, int h, u64 color, int font) { + char* name, int type, int x, int y, short aligned, int w, int h, short scaled, u64 color, int font) { int intValue; unsigned char charColor[3]; @@ -488,15 +548,21 @@ static theme_element_t* initBasic(char* themePath, config_set_t* themeConfig, th elem->posY = y; snprintf(elemProp, 64, "%s_width", name); - if (configGetInt(themeConfig, elemProp, &intValue)) - elem->width = intValue; - else + if (configGetStr(themeConfig, elemProp, &temp)) { + if (!strncmp(temp, "DIM_INF", 7)) + elem->width = screenWidth; + else + elem->width = atoi(temp); + } else elem->width = w; snprintf(elemProp, 64, "%s_height", name); - if (configGetInt(themeConfig, elemProp, &intValue)) - elem->height = intValue; - else + if (configGetStr(themeConfig, elemProp, &temp)) { + if (!strncmp(temp, "DIM_INF", 7)) + elem->height = screenHeight; + else + elem->height = atoi(temp); + } else elem->height = h; snprintf(elemProp, 64, "%s_aligned", name); @@ -504,10 +570,12 @@ static theme_element_t* initBasic(char* themePath, config_set_t* themeConfig, th elem->aligned = intValue; else elem->aligned = aligned; - if (elem->aligned) { // DIM_INF and aligned are incompatible - if ((elem->width == DIM_INF) || (elem->height == DIM_INF)) - elem->aligned = ALIGN_NONE; - } + + snprintf(elemProp, 64, "%s_scaled", name); + if (configGetInt(themeConfig, elemProp, &intValue)) + elem->scaled = intValue; + else + elem->scaled = scaled; snprintf(elemProp, 64, "%s_color", name); if (configGetColor(themeConfig, elemProp, charColor)) @@ -550,7 +618,7 @@ static void initBackground(char* themePath, config_set_t* themeConfig, theme_t* static void drawMenuIcon(struct menu_list* menu, struct submenu_list* item, config_set_t* config, struct theme_element* elem) { GSTEXTURE* menuIconTex = thmGetTexture(menu->item->icon_id); if (menuIconTex && menuIconTex->Mem) - rmDrawPixmap(menuIconTex, elem->posX, elem->posY, elem->aligned, elem->width, elem->height, gDefaultCol); + rmDrawPixmap(menuIconTex, elem->posX, elem->posY, elem->aligned, elem->width, elem->height, elem->scaled, gDefaultCol); } static void drawMenuText(struct menu_list* menu, struct submenu_list* item, config_set_t* config, struct theme_element* elem) { @@ -563,15 +631,15 @@ static void drawMenuText(struct menu_list* menu, struct submenu_list* item, conf if (elem->aligned) { int offset = elem->width >> 1; if (leftIconTex && leftIconTex->Mem) - rmDrawPixmap(leftIconTex, elem->posX - offset, elem->posY, elem->aligned, DIM_UNDEF, DIM_UNDEF, gDefaultCol); + rmDrawPixmap(leftIconTex, elem->posX - offset, elem->posY, elem->aligned, leftIconTex->Width, leftIconTex->Height, elem->scaled, gDefaultCol); if (rightIconTex && rightIconTex->Mem) - rmDrawPixmap(rightIconTex, elem->posX + offset, elem->posY, elem->aligned, DIM_UNDEF, DIM_UNDEF, gDefaultCol); + rmDrawPixmap(rightIconTex, elem->posX + offset, elem->posY, elem->aligned, rightIconTex->Width, rightIconTex->Height, elem->scaled, gDefaultCol); } else { if (leftIconTex && leftIconTex->Mem) - rmDrawPixmap(leftIconTex, elem->posX - leftIconTex->Width, elem->posY, elem->aligned, DIM_UNDEF, DIM_UNDEF, gDefaultCol); + rmDrawPixmap(leftIconTex, elem->posX - leftIconTex->Width, elem->posY, elem->aligned, leftIconTex->Width, leftIconTex->Height, elem->scaled, gDefaultCol); if (rightIconTex && rightIconTex->Mem) - rmDrawPixmap(rightIconTex, elem->posX + elem->width, elem->posY, elem->aligned, DIM_UNDEF, DIM_UNDEF, gDefaultCol); + rmDrawPixmap(rightIconTex, elem->posX + elem->width, elem->posY, elem->aligned, rightIconTex->Width, rightIconTex->Height, elem->scaled, gDefaultCol); } fntRenderString(elem->font, elem->posX, elem->posY, elem->aligned, menuItemGetText(menu->item), elem->color); } @@ -608,13 +676,14 @@ static void drawItemsList(struct menu_list* menu, struct submenu_list* item, con else color = elem->color; + // TODO use sizingMode if (itemsList->decoratorImage) { GSTEXTURE* itemIconTex = getGameImageTexture(itemsList->decoratorImage->cache, menu->item->userdata, &ps->item); if (itemIconTex && itemIconTex->Mem) - rmDrawPixmap(itemIconTex, elem->posX, curpos + others * MENU_ITEM_HEIGHT, ALIGN_NONE, DECORATOR_SIZE, DECORATOR_SIZE, gDefaultCol); + rmDrawPixmap(itemIconTex, elem->posX, curpos + others * MENU_ITEM_HEIGHT, ALIGN_NONE, DECORATOR_SIZE, DECORATOR_SIZE, elem->scaled, gDefaultCol); else { if (itemsList->decoratorImage->defaultTexture) - rmDrawPixmap(&itemsList->decoratorImage->defaultTexture->source, elem->posX, curpos + others * MENU_ITEM_HEIGHT, ALIGN_NONE, DECORATOR_SIZE, DECORATOR_SIZE, gDefaultCol); + rmDrawPixmap(&itemsList->decoratorImage->defaultTexture->source, elem->posX, curpos + others * MENU_ITEM_HEIGHT, ALIGN_NONE, DECORATOR_SIZE, DECORATOR_SIZE, elem->scaled, gDefaultCol); } fntRenderString(elem->font, elem->posX + DECORATOR_SIZE, curpos + others * MENU_ITEM_HEIGHT, ALIGN_NONE, submenuItemGetText(&ps->item), color); } else @@ -682,7 +751,7 @@ static void validateGUIElems(char* themePath, config_set_t* themeConfig, theme_t // 1. check we have a valid Background elements if ( !theme->mainElems.first || (theme->mainElems.first->type != TYPE_BACKGROUND) ) { LOG("No valid background found for main, add default BG_ART\n"); - theme_element_t* backgroundElem = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, "bg", TYPE_BACKGROUND, 0, 0, ALIGN_NONE, DIM_INF, DIM_INF, gDefaultCol, FNT_DEFAULT); + theme_element_t* backgroundElem = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, "bg", TYPE_BACKGROUND, 0, 0, ALIGN_NONE, screenWidth, screenHeight, SCALING_NONE, gDefaultCol, FNT_DEFAULT); if (themePath) initBackground(themePath, themeConfig, theme, backgroundElem, "bg", "BG", 1, "background"); else @@ -694,7 +763,7 @@ static void validateGUIElems(char* themePath, config_set_t* themeConfig, theme_t if (theme->infoElems.first) { if (theme->infoElems.first->type != TYPE_BACKGROUND) { LOG("No valid background found for info, add default BG_ART\n"); - theme_element_t* backgroundElem = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, "bg", TYPE_BACKGROUND, 0, 0, ALIGN_NONE, DIM_INF, DIM_INF, gDefaultCol, FNT_DEFAULT); + theme_element_t* backgroundElem = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, "bg", TYPE_BACKGROUND, 0, 0, ALIGN_NONE, screenWidth, screenHeight, SCALING_NONE, gDefaultCol, FNT_DEFAULT); if (themePath) initBackground(themePath, themeConfig, theme, backgroundElem, "bg", "BG", 1, "background"); else @@ -727,7 +796,7 @@ static void validateGUIElems(char* themePath, config_set_t* themeConfig, theme_t } } else { LOG("No itemsList found, adding a default one\n"); - theme->itemsList = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, "il", TYPE_ITEMS_LIST, 150, MENU_POS_V, ALIGN_NONE, DIM_INF, 0, theme->textColor, FNT_DEFAULT); + theme->itemsList = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, "il", TYPE_ITEMS_LIST, 150, MENU_POS_V, ALIGN_NONE, screenWidth, screenHeight, SCALING_RATIO, theme->textColor, FNT_DEFAULT); initItemsList(themePath, themeConfig, theme, theme->itemsList, "il", (theme->usedHeight - (MENU_POS_V + HINT_HEIGHT)) / MENU_ITEM_HEIGHT, NULL); theme->itemsList->next = theme->mainElems.first->next; // Position the itemsList as second element (right after the Background) theme->mainElems.first->next = theme->itemsList; @@ -749,52 +818,52 @@ static int addGUIElem(char* themePath, config_set_t* themeConfig, theme_t* theme configGetStr(themeConfig, elemProp, &type); if (type) { if (!strcmp(elementsType[TYPE_ATTRIBUTE_TEXT], type)) { - elem = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, name, TYPE_ATTRIBUTE_TEXT, 0, 0, ALIGN_CENTER, DIM_UNDEF, DIM_UNDEF, theme->textColor, FNT_DEFAULT); - initAttributeText(themePath, themeConfig, theme, elem, name, NULL, NULL, DISPLAY_ALWAYS); + elem = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, name, TYPE_ATTRIBUTE_TEXT, 0, 0, ALIGN_CENTER, DIM_UNDEF, DIM_UNDEF, SCALING_RATIO, theme->textColor, FNT_DEFAULT); + initAttributeText(themePath, themeConfig, theme, elem, name, NULL); } else if (!strcmp(elementsType[TYPE_STATIC_TEXT], type)) { - elem = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, name, TYPE_STATIC_TEXT, 0, 0, ALIGN_CENTER, DIM_UNDEF, DIM_UNDEF, theme->textColor, FNT_DEFAULT); + elem = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, name, TYPE_STATIC_TEXT, 0, 0, ALIGN_CENTER, DIM_UNDEF, DIM_UNDEF, SCALING_RATIO, theme->textColor, FNT_DEFAULT); initStaticText(themePath, themeConfig, theme, elem, name, NULL); } else if (!strcmp(elementsType[TYPE_ATTRIBUTE_IMAGE], type)) { - elem = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, name, TYPE_ATTRIBUTE_IMAGE, 0, 0, ALIGN_CENTER, DIM_UNDEF, DIM_UNDEF, gDefaultCol, FNT_DEFAULT); + elem = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, name, TYPE_ATTRIBUTE_IMAGE, 0, 0, ALIGN_CENTER, DIM_UNDEF, DIM_UNDEF, SCALING_RATIO, gDefaultCol, FNT_DEFAULT); initAttributeImage(themePath, themeConfig, theme, elem, name); } else if (!strcmp(elementsType[TYPE_GAME_IMAGE], type)) { - elem = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, name, TYPE_GAME_IMAGE, 0, 0, ALIGN_CENTER, DIM_UNDEF, DIM_UNDEF, gDefaultCol, FNT_DEFAULT); + elem = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, name, TYPE_GAME_IMAGE, 0, 0, ALIGN_CENTER, DIM_UNDEF, DIM_UNDEF, SCALING_RATIO, gDefaultCol, FNT_DEFAULT); initGameImage(themePath, themeConfig, theme, elem, name, NULL, 1, NULL, NULL); } else if (!strcmp(elementsType[TYPE_STATIC_IMAGE], type)) { - elem = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, name, TYPE_STATIC_IMAGE, 0, 0, ALIGN_CENTER, DIM_UNDEF, DIM_UNDEF, gDefaultCol, FNT_DEFAULT); + elem = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, name, TYPE_STATIC_IMAGE, 0, 0, ALIGN_CENTER, DIM_UNDEF, DIM_UNDEF, SCALING_RATIO, gDefaultCol, FNT_DEFAULT); initStaticImage(themePath, themeConfig, theme, elem, name, NULL); } else if (!strcmp(elementsType[TYPE_BACKGROUND], type)) { if (!elems->first) { // Background elem can only be the first one - elem = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, name, TYPE_BACKGROUND, 0, 0, ALIGN_NONE, DIM_INF, DIM_INF, gDefaultCol, FNT_DEFAULT); + elem = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, name, TYPE_BACKGROUND, 0, 0, ALIGN_NONE, screenWidth, screenHeight, SCALING_NONE, gDefaultCol, FNT_DEFAULT); initBackground(themePath, themeConfig, theme, elem, name, NULL, 1, NULL); } } else if (!strcmp(elementsType[TYPE_MENU_ICON], type)) { - elem = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, name, TYPE_MENU_ICON, 40, 40, ALIGN_CENTER, DIM_UNDEF, DIM_UNDEF, gDefaultCol, FNT_DEFAULT); + elem = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, name, TYPE_MENU_ICON, 40, 40, ALIGN_CENTER, DIM_UNDEF, DIM_UNDEF, SCALING_RATIO, gDefaultCol, FNT_DEFAULT); elem->drawElem = &drawMenuIcon; } else if (!strcmp(elementsType[TYPE_MENU_TEXT], type)) { - elem = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, name, TYPE_MENU_TEXT, screenWidth >> 1, 20, ALIGN_CENTER, 200, 20, theme->textColor, FNT_DEFAULT); + elem = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, name, TYPE_MENU_TEXT, screenWidth >> 1, 20, ALIGN_CENTER, 200, 20, SCALING_RATIO, theme->textColor, FNT_DEFAULT); elem->drawElem = &drawMenuText; } else if (!strcmp(elementsType[TYPE_ITEMS_LIST], type)) { if (!theme->itemsList) { - elem = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, name, TYPE_ITEMS_LIST, 150, MENU_POS_V, ALIGN_NONE, DIM_INF, 0, theme->textColor, FNT_DEFAULT); + elem = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, name, TYPE_ITEMS_LIST, 150, MENU_POS_V, ALIGN_NONE, screenWidth, screenHeight, SCALING_RATIO, theme->textColor, FNT_DEFAULT); initItemsList(themePath, themeConfig, theme, elem, name, (theme->usedHeight - (MENU_POS_V + HINT_HEIGHT)) / MENU_ITEM_HEIGHT, NULL); theme->itemsList = elem; } } else if (!strcmp(elementsType[TYPE_ITEM_ICON], type)) { - elem = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, name, TYPE_GAME_IMAGE, 80, theme->usedHeight >> 1, ALIGN_CENTER, DIM_UNDEF, DIM_UNDEF, gDefaultCol, FNT_DEFAULT); + elem = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, name, TYPE_GAME_IMAGE, 80, theme->usedHeight >> 1, ALIGN_CENTER, DIM_UNDEF, DIM_UNDEF, SCALING_RATIO, gDefaultCol, FNT_DEFAULT); initGameImage(themePath, themeConfig, theme, elem, name, "ICO", 20, NULL, NULL); } else if (!strcmp(elementsType[TYPE_ITEM_COVER], type)) { - elem = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, name, TYPE_GAME_IMAGE, 520, theme->usedHeight >> 1, ALIGN_CENTER, DIM_UNDEF, DIM_UNDEF, gDefaultCol, FNT_DEFAULT); + elem = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, name, TYPE_GAME_IMAGE, 520, theme->usedHeight >> 1, ALIGN_CENTER, DIM_UNDEF, DIM_UNDEF, SCALING_RATIO, gDefaultCol, FNT_DEFAULT); initGameImage(themePath, themeConfig, theme, elem, name, "COV", 10, NULL, NULL); } else if (!strcmp(elementsType[TYPE_ITEM_TEXT], type)) { - elem = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, name, TYPE_ITEM_TEXT, 520, 370, ALIGN_CENTER, DIM_UNDEF, 20, theme->textColor, FNT_DEFAULT); + elem = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, name, TYPE_ITEM_TEXT, 520, 370, ALIGN_CENTER, DIM_UNDEF, DIM_UNDEF, SCALING_RATIO, theme->textColor, FNT_DEFAULT); elem->drawElem = &drawItemText; } else if (!strcmp(elementsType[TYPE_HINT_TEXT], type)) { - elem = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, name, TYPE_HINT_TEXT, 16, -HINT_HEIGHT, ALIGN_NONE, DIM_INF, HINT_HEIGHT, theme->textColor, FNT_DEFAULT); + elem = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, name, TYPE_HINT_TEXT, 16, -HINT_HEIGHT, ALIGN_NONE, DIM_UNDEF, DIM_UNDEF, SCALING_RATIO, theme->textColor, FNT_DEFAULT); elem->drawElem = &drawHintText; } else if (!strcmp(elementsType[TYPE_LOADING_ICON], type)) { if (!theme->loadingIcon) - theme->loadingIcon = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, name, TYPE_LOADING_ICON, -50, -50, ALIGN_CENTER, DIM_UNDEF, DIM_UNDEF, gDefaultCol, FNT_DEFAULT); + theme->loadingIcon = initBasic(themePath, themeConfig, theme, screenWidth, screenHeight, name, TYPE_LOADING_ICON, -50, -50, ALIGN_CENTER, DIM_UNDEF, DIM_UNDEF, SCALING_RATIO, gDefaultCol, FNT_DEFAULT); } if (elem) { -- 2.11.4.GIT