1
0
mirror of https://github.com/TerryCavanagh/VVVVVV.git synced 2024-06-24 13:38:29 +02:00

Migrate more prints and graphics.len calls to font::

I especially focused on graphics.len and the print calls around them,
because graphics.len calls appear a bit less often, might be overlooked
when migrating print calls (thus possibly using different fonts by
accident) and are often used for some kind of right-alignment or
centering which can be changed into PR_RIGHT or PR_CEN with a different
X anyway.

Notably, I also added a new function to generate these kinds of
sliders: ....[]............

Different languages means that the slider for analogue stick
sensitivity needs to be longer to fit possibly long words for
Low/Medium/High, and then different font sizes means that the longer
slider won't fit onscreen in a language that needs a 12-wide font. So
slider_get() can take a "target width", which dynamically changes the
number of characters depending on the width of them in the interface
font.

I kinda forgot that I could force the 8x8 font instead of adapting the
characters in the slider to the font, and other ideas (like using
different characters or a more graphical progress bar) have been
brought up on Discord, so this might all change again sooner or later.
This commit is contained in:
Dav999-v 2023-01-16 21:29:50 +01:00 committed by Misa Elizabeth Kai
parent 7c55ea7832
commit a706fb249a
8 changed files with 114 additions and 99 deletions

View File

@ -1076,9 +1076,9 @@ void editorrender(void)
if(ed.dmtileeditor>0 && t2<=30)
{
short labellen = 2 + graphics.len(loc::gettext("Tile:"));
graphics.bprint(2, 45-t2, loc::gettext("Tile:"), 196, 196, 255 - help.glow, false);
graphics.bprint(labellen+16, 45-t2, help.String(ed.dmtile), 196, 196, 255 - help.glow, false);
short labellen = 2 + font::len(0, loc::gettext("Tile:"));
font::print(PR_BOR, 2, 45-t2, loc::gettext("Tile:"), 196, 196, 255 - help.glow);
font::print(PR_BOR, labellen+16, 45-t2, help.String(ed.dmtile), 196, 196, 255 - help.glow);
graphics.fill_rect(labellen+2,44-t2,10,10, graphics.getRGB(255 - help.glow, 196, 196));
graphics.fill_rect(labellen+3,45-t2,8,8, graphics.getRGB(0,0,0));
@ -1093,11 +1093,13 @@ void editorrender(void)
}
else
{
short labellen = 2 + graphics.len(loc::gettext("Tile:"));
graphics.bprint(2, 12, loc::gettext("Tile:"), 196, 196, 255 - help.glow, false);
graphics.bprint(labellen+16, 12, help.String(ed.dmtile), 196, 196, 255 - help.glow, false);
graphics.fill_rect(labellen+2,11,10,10, graphics.getRGB(255 - help.glow, 196, 196));
graphics.fill_rect(labellen+3,12,8,8, graphics.getRGB(0,0,0));
short labellen = 2 + font::len(0, loc::gettext("Tile:"));
int y = 2 + font::height(0);
y = SDL_max(y, 12);
font::print(PR_BOR, 2, y, loc::gettext("Tile:"), 196, 196, 255 - help.glow);
font::print(PR_BOR, labellen+16, y, help.String(ed.dmtile), 196, 196, 255 - help.glow);
graphics.fill_rect(labellen+2, y-1, 10,10, graphics.getRGB(255 - help.glow, 196, 196));
graphics.fill_rect(labellen+3, y, 8,8, graphics.getRGB(0,0,0));
if(room->tileset==0)
{
@ -1459,15 +1461,18 @@ void editorrender(void)
toolname = "???";
break;
}
int toolnamelen = graphics.len(toolname);
graphics.fill_rect(0,197,toolnamelen+8,11, graphics.getRGB(32,32,32));
graphics.fill_rect(0,198,toolnamelen+7,10, graphics.getRGB(0,0,0));
graphics.bprint(2,199, toolname, 196, 196, 255 - help.glow);
graphics.fill_rect(260,197,80,11, graphics.getRGB(32,32,32));
graphics.fill_rect(261,198,80,10, graphics.getRGB(0,0,0));
font::print(PR_BOR | PR_CJK_HIGH | PR_RIGHT, 316, 199, "("+help.String(ed.levx+1)+","+help.String(ed.levy+1)+")", 196, 196, 255 - help.glow);
int bgheight = 2 + font::height(0);
int toolnamelen = font::len(0, toolname);
graphics.fill_rect(0,207-bgheight,toolnamelen+8,bgheight+1, graphics.getRGB(32,32,32));
graphics.fill_rect(0,208-bgheight,toolnamelen+7,bgheight, graphics.getRGB(0,0,0));
font::print(PR_BOR | PR_CJK_HIGH, 2,199, toolname, 196, 196, 255 - help.glow);
char coords[8];
SDL_snprintf(coords, sizeof(coords), "(%d,%d)", ed.levx+1, ed.levy+1);
int coordslen = font::len(0, coords);
graphics.fill_rect(319-coordslen-8,207-bgheight,coordslen+8,bgheight+1, graphics.getRGB(32,32,32));
graphics.fill_rect(320-coordslen-8,208-bgheight,coordslen+8,bgheight, graphics.getRGB(0,0,0));
font::print(PR_BOR | PR_CJK_HIGH | PR_RIGHT, 316, 199, coords, 196, 196, 255 - help.glow);
}
else
{
@ -1510,20 +1515,24 @@ void editorrender(void)
int menuwidth = 0;
for (size_t i = 0; i < SDL_arraysize(shiftmenuoptions); i++)
{
int len = graphics.len(shiftmenuoptions[i]);
int len = font::len(0, shiftmenuoptions[i]);
if (len > menuwidth)
menuwidth = len;
}
fillboxabs(0, 117,menuwidth+17,140,graphics.getRGB(64,64,64));
graphics.fill_rect(0,118,menuwidth+16,140, graphics.getRGB(0,0,0));
int lineheight = font::height(0);
lineheight = SDL_max(10, lineheight);
int left_y = 230-SDL_arraysize(shiftmenuoptions)*lineheight;
fillboxabs(0, left_y-3, menuwidth+17, 240,graphics.getRGB(64,64,64));
graphics.fill_rect(0,left_y-2,menuwidth+16,240, graphics.getRGB(0,0,0));
for (size_t i = 0; i < SDL_arraysize(shiftmenuoptions); i++)
graphics.Print(4, 120+i*10, shiftmenuoptions[i], 164,164,164,false);
graphics.Print(4, left_y+i*lineheight, shiftmenuoptions[i], 164,164,164,false);
fillboxabs(220, 207,100,60,graphics.getRGB(64,64,64));
graphics.fill_rect(221,208,160,60, graphics.getRGB(0,0,0));
graphics.Print(224, 210, loc::gettext("S: Save Map"),164,164,164,false);
graphics.Print(224, 220, loc::gettext("L: Load Map"),164,164,164,false);
graphics.Print(224, 210+lineheight, loc::gettext("L: Load Map"),164,164,164,false);
}
}

View File

@ -465,6 +465,7 @@ void destroy(void)
unload_font_container(&fonts_main);
}
static Font* container_get(FontContainer* container, uint8_t idx); // TODO TEMP TEMP TEMP
static bool next_wrap(
size_t* start,
@ -493,7 +494,7 @@ static bool next_wrap(
goto next;
}
linewidth += get_advance(&fonts_main.fonts[font_idx_8x8], str[idx]); // TODO get font via argument!
linewidth += get_advance(container_get(&fonts_main, loc::get_langmeta()->font_idx), str[idx]); // TODO get font via argument!
switch (str[idx])
{

View File

@ -2833,7 +2833,7 @@ void Game::updatestate(void)
"gamecomplete_n_trinkets:int",
trinkets()
);
graphics.createtextboxflipme(label, 168-graphics.len(label), 84, 0,0,0);
graphics.createtextboxflipme(label, 168-font::len(PR_FONT_INTERFACE, label), 84, 0,0,0);
graphics.textboxprintflags(PR_FONT_INTERFACE);
graphics.createtextboxflipme(buffer, 180, 84, 0, 0, 0);
graphics.textboxprintflags(PR_FONT_INTERFACE);
@ -2846,7 +2846,7 @@ void Game::updatestate(void)
const char* label = loc::gettext("Game Time:");
std::string tempstring = savetime;
graphics.createtextboxflipme(label, 168-graphics.len(label), 96, 0,0,0);
graphics.createtextboxflipme(label, 168-font::len(PR_FONT_INTERFACE, label), 96, 0,0,0);
graphics.textboxprintflags(PR_FONT_INTERFACE);
graphics.createtextboxflipme(tempstring, 180, 96, 0, 0, 0);
graphics.textboxprintflags(PR_FONT_INTERFACE);
@ -2858,7 +2858,7 @@ void Game::updatestate(void)
setstatedelay(45);
const char* label = loc::gettext("Total Flips:");
graphics.createtextboxflipme(label, 168-graphics.len(label), 123, 0,0,0);
graphics.createtextboxflipme(label, 168-font::len(PR_FONT_INTERFACE, label), 123, 0,0,0);
graphics.textboxprintflags(PR_FONT_INTERFACE);
graphics.createtextboxflipme(help.String(totalflips), 180, 123, 0, 0, 0);
graphics.textboxprintflags(PR_FONT_INTERFACE);
@ -2870,7 +2870,7 @@ void Game::updatestate(void)
setstatedelay(45+15);
const char* label = loc::gettext("Total Deaths:");
graphics.createtextboxflipme(label, 168-graphics.len(label), 135, 0,0,0);
graphics.createtextboxflipme(label, 168-font::len(PR_FONT_INTERFACE, label), 135, 0,0,0);
graphics.textboxprintflags(PR_FONT_INTERFACE);
graphics.createtextboxflipme(help.String(deathcounts), 180, 135, 0, 0, 0);
graphics.textboxprintflags(PR_FONT_INTERFACE);
@ -6888,7 +6888,7 @@ void Game::createmenu( enum Menu::MenuName t, bool samemenu/*= false*/ )
menuwidth = 0;
for (size_t i = 0; i < menuoptions.size(); i++)
{
int width = i*menuspacing + graphics.len(menuoptions[i].text);
int width = i*menuspacing + font::len(menuoptions[i].print_flags, menuoptions[i].text);
if (width > menuwidth)
menuwidth = width;
}

View File

@ -299,26 +299,33 @@ static bool max_check_string(const char* str, const char* max)
max_h = 2;
}
uint8_t font_idx = get_langmeta()->font_idx;
uint32_t print_flags = PR_FONT_IDX(font_idx) | PR_CJK_LOW;
uint8_t font_w = 8;
uint8_t font_h = 8;
font::glyph_dimensions_main(get_langmeta()->font_idx, &font_w, &font_h);
font::glyph_dimensions_main(font_idx, &font_w, &font_h);
unsigned short max_w_px = max_w * font_w;
unsigned short max_h_px = max_h * SDL_max(10, font_h);
unsigned short max_w_px = max_w * 8;
unsigned short max_h_px = max_h * 10;
bool does_overflow = false;
if (max_h == 1)
{
does_overflow = graphics.len(str) > (int) max_w_px;
max_h_px = font_h;
does_overflow = font::len(print_flags, str) > (int) max_w_px;
}
else
{
short lines;
font::string_wordwrap(str, max_w_px, &lines);
does_overflow = lines > (short) max_h;
font::string_wordwrap(str, max_w_px, &lines); // TODO: needs to be passed the font!
does_overflow = lines*SDL_max(10, font_h) > (short) max_h_px;
}
// Convert max_w and max_h from 8x8 into local
max_w = max_w_px / font_w;
max_h = max_h_px / SDL_max(10, font_h);
if (does_overflow)
{
TextOverflow overflow;
@ -329,6 +336,7 @@ static bool max_check_string(const char* str, const char* max)
overflow.max_w_px = max_w_px;
overflow.max_h_px = max_h_px;
overflow.multiline = max_h > 1;
overflow.flags = print_flags;
text_overflows.push_back(overflow);

View File

@ -50,6 +50,7 @@ struct TextOverflow
unsigned short max_w, max_h;
unsigned short max_w_px, max_h_px;
bool multiline;
uint32_t flags;
};
extern std::vector<TextOverflow> text_overflows;

View File

@ -57,48 +57,63 @@ static inline void drawslowdowntext(const int y)
}
}
static void slider_get(char* buffer, size_t buffer_len, int position, int n_positions, int target_width)
{
/* Print a slider to the buffer for target_width in pixels.
*
* <--target w-->
* []............
* ......[]......
* ............[]
* ^^^^^^ dots_per_position=6
* ^^^^^^^^^^^^^^ max_chars=14
*/
if (n_positions < 2 || position < 0 || position >= n_positions)
{
buffer[0] = '\0';
return;
}
int max_chars = ((target_width - font::len(0, "[]")) / font::len(0, ".")) + 2;
max_chars = SDL_min(max_chars, buffer_len-1);
int dots_per_position = (max_chars-2) / (n_positions-1);
max_chars = dots_per_position * (n_positions-1) + 2;
VVV_fillstring(buffer, max_chars+1, '.');
if (dots_per_position<1)
{
return;
}
int handle_idx = position*dots_per_position;
buffer[handle_idx] = '[';
buffer[handle_idx+1] = ']';
}
static void volumesliderrender(void)
{
char buffer[SCREEN_WIDTH_CHARS + 1];
char slider[20 + 1];
int slider_length;
const char symbol[] = "[]";
int symbol_length;
int offset;
int num_positions;
const int* volume_ptr;
int volume_max_position = USER_VOLUME_MAX / USER_VOLUME_STEP;
int volume;
switch (game.currentmenuoption)
{
case 0:
volume_ptr = &music.user_music_volume;
volume = music.user_music_volume;
break;
case 1:
volume_ptr = &music.user_sound_volume;
volume = music.user_sound_volume;
break;
default:
SDL_assert(0 && "Unhandled volume slider menu option!");
return;
}
VVV_fillstring(slider, sizeof(slider), '.');
slider_length = sizeof(slider) - 1;
char slider[40 + 1];
slider_get(slider, sizeof(slider), volume_max_position*volume/USER_VOLUME_MAX, volume_max_position+1, 240);
symbol_length = sizeof(symbol) - 1;
num_positions = slider_length - symbol_length + 1;
offset = num_positions * (*volume_ptr) / USER_VOLUME_MAX;
offset = SDL_clamp(offset, 0, slider_length - symbol_length);
/* SDL_strlcpy null-terminates, which would end the string in the middle of
* it, which we don't want!
*/
SDL_memcpy(&slider[offset], symbol, symbol_length);
char buffer[SCREEN_WIDTH_CHARS + 1];
if (game.slidermode == SLIDER_NONE)
{
@ -110,7 +125,7 @@ static void volumesliderrender(void)
vformat_buf(buffer, sizeof(buffer), loc::get_langmeta()->menu_select.c_str(), "label:str", slider);
}
graphics.Print(-1, 95, buffer, tr, tg, tb, true);
font::print(PR_CEN, -1, 95, buffer, tr, tg, tb);
}
static void inline drawglitchrunnertext(const int y)
@ -155,8 +170,7 @@ static void menurender(void)
graphics.draw_sprite((160 - 96) + 4 * 32, temp, 23, tr, tg, tb);
graphics.draw_sprite((160 - 96) + 5 * 32, temp, 23, tr, tg, tb);
#if defined(MAKEANDPLAY)
const char* editionlabel = loc::gettext("MAKE AND PLAY EDITION");
graphics.Print(264-graphics.len(editionlabel),temp+35,editionlabel,tr, tg, tb);
font::print(PR_RIGHT, 264, temp+35, loc::gettext("MAKE AND PLAY EDITION"), tr, tg, tb);
#endif
#ifdef INTERIM_VERSION_EXISTS
graphics.Print( 310 - (10*8), 200, COMMIT_DATE, tr/2, tg/2, tb/2);
@ -563,30 +577,15 @@ static void menurender(void)
switch (game.currentmenuoption)
{
case 0:
graphics.Print(32, 75, loc::gettext("Low"), tr, tg, tb);
graphics.Print(-1, 75, loc::gettext("Medium"), tr, tg, tb, true);
#define HIGHLABEL loc::gettext("High")
graphics.Print(288-graphics.len(HIGHLABEL), 75, HIGHLABEL, tr, tg, tb);
#undef HIGHLABEL
switch(key.sensitivity)
{
case 0:
graphics.Print( -1, 85, "[]..........................", tr, tg, tb, true);
break;
case 1:
graphics.Print( -1, 85, ".......[]...................", tr, tg, tb, true);
break;
case 2:
graphics.Print( -1, 85, ".............[].............", tr, tg, tb, true);
break;
case 3:
graphics.Print( -1, 85, "...................[].......", tr, tg, tb, true);
break;
case 4:
graphics.Print( -1, 85, "..........................[]", tr, tg, tb, true);
break;
}
{
font::print(0, 32, 75, loc::gettext("Low"), tr, tg, tb);
font::print(PR_CEN, -1, 75, loc::gettext("Medium"), tr, tg, tb);
font::print(PR_RIGHT, 288, 75, loc::gettext("High"), tr, tg, tb);
char slider[SCREEN_WIDTH_CHARS + 1];
slider_get(slider, sizeof(slider), key.sensitivity, 5, 240);
font::print(PR_CEN, -1, 85, slider, tr, tg, tb);
break;
}
case 1:
case 2:
case 3:
@ -710,14 +709,10 @@ static void menurender(void)
overflow.max_w_px, overflow.max_h_px,
overflow.lang.c_str()
);
graphics.Print(10, 10, buffer, tr/2, tg/2, tb/2);
uint8_t font_h = 8;
font::glyph_dimensions_main(loc::get_langmeta()->font_idx, NULL, &font_h);
font::print(PR_FONT_8X8, 10, 10, buffer, tr/2, tg/2, tb/2);
int box_x = SDL_min(10, (320-overflow.max_w_px)/2);
int box_h = overflow.max_h_px - SDL_max(0, 10-font_h);
graphics.fill_rect(box_x-1, 30-1, overflow.max_w_px+2, box_h+2, tr/3, tg/3, tb/3);
graphics.fill_rect(box_x-1, 30-1, overflow.max_w_px+2, overflow.max_h_px+2, tr/3, tg/3, tb/3);
int wraplimit;
if (overflow.multiline)
@ -731,7 +726,7 @@ static void menurender(void)
if (overflow.text != NULL)
{
graphics.PrintWrap(box_x, 30, overflow.text, tr, tg, tb, false, -1, wraplimit);
font::print_wrap(overflow.flags, box_x, 30, overflow.text, tr, tg, tb, -1, wraplimit);
}
}
break;
@ -1616,8 +1611,7 @@ void titlerender(void)
graphics.draw_sprite((160 - 96) + 4 * 32, temp, 23, tr, tg, tb);
graphics.draw_sprite((160 - 96) + 5 * 32, temp, 23, tr, tg, tb);
#if defined(MAKEANDPLAY)
const char* editionlabel = loc::gettext("MAKE AND PLAY EDITION");
graphics.Print(264-graphics.len(editionlabel),temp+35,editionlabel,tr, tg, tb);
font::print(PR_RIGHT, 264, temp+35, loc::gettext("MAKE AND PLAY EDITION"), tr, tg, tb);
#endif
graphics.PrintWrap(5, 175, loc::gettext("[ Press ACTION to Start ]"), tr, tg, tb, true);
@ -2018,11 +2012,11 @@ void gamerender(void)
{
std::string tempstring = help.timestring(game.swntimer);
graphics.bprint( 10, 10, loc::gettext("Current Time"), 220 - (help.glow), 220 - (help.glow), 255 - (help.glow / 2), false);
graphics.bigbprint( 25, 24, tempstring, 220 - (help.glow), 220 - (help.glow), 255 - (help.glow / 2), false, 2);
font::print(PR_2X | PR_BOR | PR_FONT_8X8, 25, 24, tempstring, 220 - (help.glow), 220 - (help.glow), 255 - (help.glow / 2));
tempstring = help.timestring(game.swnrecord);
const char* besttimelabel = loc::gettext("Best Time");
graphics.bprint( 320-graphics.len(besttimelabel)-8, 10, besttimelabel, 220 - (help.glow), 220 - (help.glow), 255 - (help.glow / 2), false);
graphics.bigbrprint( 300, 24, tempstring, 220 - (help.glow), 220 - (help.glow), 255 - (help.glow / 2), false, 2);
font::print(PR_2X | PR_BOR | PR_FONT_8X8 | PR_RIGHT, 300, 24, tempstring, 220 - (help.glow), 220 - (help.glow), 255 - (help.glow / 2));
switch(game.swnbestrank)
{

View File

@ -891,6 +891,8 @@ static void unfocused_run(void)
{
graphics.fill_rect(0, 0, 0);
#define FLIP(YPOS) graphics.flipmode ? 232 - YPOS : YPOS
/* The pause screen can also appear on the language screen, where highlighting
* a language changes the used language metadata but not the loaded strings... */
uint32_t flags = PR_CEN | PR_BOR | PR_FONT_IDX(loc::langmeta.font_idx);
font::print(flags | PR_CJK_HIGH, -1, FLIP(110), loc::gettext("Game paused"), 196 - help.glow, 255 - help.glow, 196 - help.glow);
font::print(flags | PR_CJK_LOW, -1, FLIP(120), loc::gettext("[click to resume]"), 196 - help.glow, 255 - help.glow, 196 - help.glow);

View File

@ -1,5 +1,6 @@
#include "Constants.h"
#include "Enums.h"
#include "Font.h"
#include "Game.h"
#include "Graphics.h"
#include "GraphicsUtil.h"
@ -134,8 +135,7 @@ void preloaderrender(void)
pre_fakepercent
);
int percentage_len = graphics.len(buffer);
graphics.Print(282-percentage_len, 204, buffer, 124, 112, 218, false);
font::print(PR_RIGHT | PR_CJK_HIGH, 282, 204, buffer, 124, 112, 218);
}
graphics.drawfade();