pressing A on an option now shows more of its desc

This commit is contained in:
Shaun Inman 2023-03-04 21:46:38 -05:00
parent b52d9517d1
commit 9a35737d0e
5 changed files with 63 additions and 34 deletions

View file

@ -438,23 +438,23 @@ SDL_Surface* GFX_getBufferCopy(void) { // must be freed by caller
SDL_BlitSurface(gfx.screen, NULL, copy, NULL); SDL_BlitSurface(gfx.screen, NULL, copy, NULL);
return copy; return copy;
} }
int GFX_truncateText(TTF_Font* font, const char* in_name, char* out_name, int max_width) { int GFX_truncateText(TTF_Font* font, const char* in_name, char* out_name, int max_width, int padding) {
int text_width; int text_width;
strcpy(out_name, in_name); strcpy(out_name, in_name);
TTF_SizeUTF8(font, out_name, &text_width, NULL); TTF_SizeUTF8(font, out_name, &text_width, NULL);
text_width += SCALE1(12*2); text_width += padding;
while (text_width>max_width) { while (text_width>max_width) {
int len = strlen(out_name); int len = strlen(out_name);
strcpy(&out_name[len-4], "...\0"); strcpy(&out_name[len-4], "...\0");
TTF_SizeUTF8(font, out_name, &text_width, NULL); TTF_SizeUTF8(font, out_name, &text_width, NULL);
text_width += SCALE1(12*2); text_width += padding;
} }
return text_width; return text_width;
} }
int GFX_wrapText(TTF_Font* font, char* str, int max_width, int max_lines) { int GFX_wrapText(TTF_Font* font, char* str, int max_width, int max_lines) {
// TODO: this is kinda buggy mess // TODO: this is "kinda" a buggy mess...but possibly fixed now!
if (!str) return 0; if (!str) return 0;
@ -465,7 +465,7 @@ int GFX_wrapText(TTF_Font* font, char* str, int max_width, int max_lines) {
TTF_SizeUTF8(font, line, &line_width, NULL); TTF_SizeUTF8(font, line, &line_width, NULL);
if (line_width<=max_width) { if (line_width<=max_width) {
line_width = GFX_truncateText(font,line,buffer,max_width); line_width = GFX_truncateText(font,line,buffer,max_width,0);
strcpy(line,buffer); strcpy(line,buffer);
return line_width; return line_width;
} }
@ -478,8 +478,12 @@ int GFX_wrapText(TTF_Font* font, char* str, int max_width, int max_lines) {
tmp = strchr(tmp, ' '); tmp = strchr(tmp, ' ');
if (!tmp) { if (!tmp) {
if (prev) { if (prev) {
prev[0] = '\n'; TTF_SizeUTF8(font, line, &line_width, NULL);
line = prev + 1; if (line_width>=max_width) {
if (line_width>max_line_width) max_line_width = line_width;
prev[0] = '\n';
line = prev + 1;
}
} }
break; break;
} }
@ -504,7 +508,7 @@ int GFX_wrapText(TTF_Font* font, char* str, int max_width, int max_lines) {
i += 1; i += 1;
} }
line_width = GFX_truncateText(font,line,buffer,max_width); line_width = GFX_truncateText(font,line,buffer,max_width,0);
strcpy(line,buffer); strcpy(line,buffer);
if (line_width>max_line_width) max_line_width = line_width; if (line_width>max_line_width) max_line_width = line_width;
@ -651,7 +655,7 @@ void GFX_blitButton(char* hint, char*button, SDL_Surface* dst, SDL_Rect* dst_rec
SDL_BlitSurface(text, NULL, dst, &(SDL_Rect){ox+dst_rect->x,dst_rect->y+(SCALE1(BUTTON_SIZE)-text->h)/2,text->w,text->h}); SDL_BlitSurface(text, NULL, dst, &(SDL_Rect){ox+dst_rect->x,dst_rect->y+(SCALE1(BUTTON_SIZE)-text->h)/2,text->w,text->h});
SDL_FreeSurface(text); SDL_FreeSurface(text);
} }
void GFX_blitMessage(char* msg, SDL_Surface* dst, SDL_Rect* dst_rect) { void GFX_blitMessage(TTF_Font* font, char* msg, SDL_Surface* dst, SDL_Rect* dst_rect) {
if (dst_rect==NULL) dst_rect = &(SDL_Rect){0,0,dst->w,dst->h}; if (dst_rect==NULL) dst_rect = &(SDL_Rect){0,0,dst->w,dst->h};
SDL_Surface* text; SDL_Surface* text;
@ -686,7 +690,7 @@ void GFX_blitMessage(char* msg, SDL_Surface* dst, SDL_Rect* dst_rect) {
if (len) { if (len) {
text = TTF_RenderUTF8_Blended(font.large, line, COLOR_WHITE); text = TTF_RenderUTF8_Blended(font, line, COLOR_WHITE);
int x = dst_rect->x; int x = dst_rect->x;
x += (dst_rect->w - text->w) / 2; x += (dst_rect->w - text->w) / 2;
SDL_BlitSurface(text, NULL, dst, &(SDL_Rect){x,y}); SDL_BlitSurface(text, NULL, dst, &(SDL_Rect){x,y});
@ -1399,7 +1403,7 @@ void POW_powerOff(void) {
if (pow.can_poweroff) { if (pow.can_poweroff) {
char* msg = exists(AUTO_RESUME_PATH) ? "Quicksave created,\npowering off" : "Powering off"; char* msg = exists(AUTO_RESUME_PATH) ? "Quicksave created,\npowering off" : "Powering off";
GFX_clear(gfx.screen); GFX_clear(gfx.screen);
GFX_blitMessage(msg, gfx.screen, NULL); GFX_blitMessage(font.large, msg, gfx.screen, NULL);
GFX_flip(gfx.screen); GFX_flip(gfx.screen);
sleep(2); sleep(2);

View file

@ -117,7 +117,7 @@ int GFX_getVsync(void);
void GFX_setVsync(int vsync); void GFX_setVsync(int vsync);
SDL_Surface* GFX_getBufferCopy(void); // must be freed by caller SDL_Surface* GFX_getBufferCopy(void); // must be freed by caller
int GFX_truncateText(TTF_Font* font, const char* in_name, char* out_name, int max_width); // returns final width (including pill padding) int GFX_truncateText(TTF_Font* font, const char* in_name, char* out_name, int max_width, int padding); // returns final width
int GFX_wrapText(TTF_Font* font, char* str, int max_width, int max_lines); int GFX_wrapText(TTF_Font* font, char* str, int max_width, int max_lines);
// NOTE: all dimensions should be pre-scaled // NOTE: all dimensions should be pre-scaled
@ -127,7 +127,7 @@ void GFX_blitRect(int asset, SDL_Surface* dst, SDL_Rect* dst_rect);
void GFX_blitBattery(SDL_Surface* dst, SDL_Rect* dst_rect); void GFX_blitBattery(SDL_Surface* dst, SDL_Rect* dst_rect);
int GFX_getButtonWidth(char* hint, char* button); int GFX_getButtonWidth(char* hint, char* button);
void GFX_blitButton(char* hint, char*button, SDL_Surface* dst, SDL_Rect* dst_rect); void GFX_blitButton(char* hint, char*button, SDL_Surface* dst, SDL_Rect* dst_rect);
void GFX_blitMessage(char* msg, SDL_Surface* dst, SDL_Rect* dst_rect); void GFX_blitMessage(TTF_Font* font, char* msg, SDL_Surface* dst, SDL_Rect* dst_rect);
int GFX_blitHardwareGroup(SDL_Surface* dst, int show_setting); int GFX_blitHardwareGroup(SDL_Surface* dst, int show_setting);
int GFX_blitButtonGroup(char** hints, SDL_Surface* dst, int align_right); int GFX_blitButtonGroup(char** hints, SDL_Surface* dst, int align_right);

View file

@ -551,7 +551,8 @@ static void State_resume(void) {
typedef struct Option { typedef struct Option {
char* key; char* key;
char* name; // desc char* name; // desc
char* desc; // info char* desc; // info, truncated
char* full; // info
char* var; char* var;
int default_value; int default_value;
int value; int value;
@ -1066,9 +1067,15 @@ static void OptionList_init(const struct retro_core_option_definition *defs) {
len = strlen(def->info) + 1; len = strlen(def->info) + 1;
item->desc = calloc(len, sizeof(char)); item->desc = calloc(len, sizeof(char));
strncpy(item->desc, def->info, len); strncpy(item->desc, def->info, len);
item->desc[len-1] = '\0';
GFX_wrapText(font.tiny, item->desc, SCALE1(240), 2); // TODO magic number! (this is more about chars per line than pixel width so it's not going to be relative to the screen size, only the scale) item->full = calloc(len, sizeof(char));
strncpy(item->full, item->desc, len);
// item->desc[len-1] = '\0';
// these magic numbers are more about chars per line than pixel width
// so it's not going to be relative to the screen size, only the scale
GFX_wrapText(font.tiny, item->desc, SCALE1(240), 2); // TODO magic number!
GFX_wrapText(font.medium, item->full, SCALE1(260), 7); // TODO: magic number!
} }
for (count=0; def->values[count].value; count++); for (count=0; def->values[count].value; count++);
@ -1216,6 +1223,7 @@ static void OptionList_reset(void) {
} }
else { else {
if (item->desc) free(item->desc); if (item->desc) free(item->desc);
if (item->full) free(item->full);
for (int j=0; j<item->count; j++) { for (int j=0; j<item->count; j++) {
char* value = item->values[j]; char* value = item->values[j];
char* label = item->labels[j]; char* label = item->labels[j];
@ -1785,7 +1793,6 @@ static uint32_t sec_start = 0;
#define Weight3_2(A, B) (((((cR(B) << 1) + (cR(A) * 3)) / 5) & 0x1f) << 11 | ((((cG(B) << 1) + (cG(A) * 3)) / 5) & 0x3f) << 5 | ((((cB(B) << 1) + (cB(A) * 3)) / 5) & 0x1f)) #define Weight3_2(A, B) (((((cR(B) << 1) + (cR(A) * 3)) / 5) & 0x1f) << 11 | ((((cG(B) << 1) + (cG(A) * 3)) / 5) & 0x3f) << 5 | ((((cB(B) << 1) + (cB(A) * 3)) / 5) & 0x1f))
#define Weight1_1_1_1(A, B, C, D) ((((cR(A) + cR(B) + cR(C) + cR(D)) >> 2) & 0x1f) << 11 | (((cG(A) + cG(B) + cG(C) + cG(D)) >> 2) & 0x3f) << 5 | (((cB(A) + cB(B) + cB(C) + cB(D)) >> 2) & 0x1f)) #define Weight1_1_1_1(A, B, C, D) ((((cR(A) + cR(B) + cR(C) + cR(D)) >> 2) & 0x1f) << 11 | (((cG(A) + cG(B) + cG(C) + cG(D)) >> 2) & 0x3f) << 5 | (((cB(A) + cB(B) + cB(C) + cB(D)) >> 2) & 0x1f))
static void scaleNull(void* __restrict src, void* __restrict dst, uint32_t w, uint32_t h, uint32_t pitch, uint32_t dst_pitch) {} static void scaleNull(void* __restrict src, void* __restrict dst, uint32_t w, uint32_t h, uint32_t pitch, uint32_t dst_pitch) {}
static void scale1x(void* __restrict src, void* __restrict dst, uint32_t w, uint32_t h, uint32_t pitch, uint32_t dst_pitch) { static void scale1x(void* __restrict src, void* __restrict dst, uint32_t w, uint32_t h, uint32_t pitch, uint32_t dst_pitch) {
// pitch of src image not src buffer! // pitch of src image not src buffer!
@ -2994,10 +3001,7 @@ typedef struct MenuList {
MenuList_callback_t on_change; MenuList_callback_t on_change;
} MenuList; } MenuList;
static void Menu_detail(MenuItem* item) { static int Menu_message(char* message, char** pairs) {
// TODO: name
}
static int Menu_message(char* message) {
GFX_setMode(MODE_MAIN); GFX_setMode(MODE_MAIN);
int dirty = 1; int dirty = 1;
while (1) { while (1) {
@ -3012,8 +3016,8 @@ static int Menu_message(char* message) {
if (dirty) { if (dirty) {
if (!resized) GFX_clear(screen); // resizing clears the screen if (!resized) GFX_clear(screen); // resizing clears the screen
GFX_clear(screen); GFX_clear(screen);
GFX_blitMessage(message, screen, NULL); GFX_blitMessage(font.medium, message, screen, &(SDL_Rect){0,SCALE1(PADDING),screen->w,screen->h-SCALE1(PILL_SIZE+PADDING)});
GFX_blitButtonGroup((char*[]){ "A","OKAY", NULL }, screen, 1); GFX_blitButtonGroup(pairs, screen, 1);
GFX_flip(screen); GFX_flip(screen);
dirty = 0; dirty = 0;
} }
@ -3078,8 +3082,15 @@ static int OptionEmulator_optionChanged(MenuList* list, int i) {
); );
OptionList_setOptionRawValue(&config.core, item->key, item->value); OptionList_setOptionRawValue(&config.core, item->key, item->value);
} }
static int OptionEmulator_optionDetail(MenuList* list, int i) {
MenuItem* item = &list->items[i];
Option* option = OptionList_getOption(&config.core, item->key);
if (option->full) return Menu_message(option->full, (char*[]){ "B","BACK", NULL });
else return MENU_CALLBACK_NOP;
}
static MenuList OptionEmulator_menu = { static MenuList OptionEmulator_menu = {
.type = MENU_FIXED, .type = MENU_FIXED,
.on_confirm = OptionEmulator_optionDetail, // TODO: this needs pagination to be truly useful
.on_change = OptionEmulator_optionChanged, .on_change = OptionEmulator_optionChanged,
.items = NULL, .items = NULL,
}; };
@ -3112,7 +3123,7 @@ static int OptionEmulator_openMenu(MenuList* list, int i) {
Menu_options(&OptionEmulator_menu); Menu_options(&OptionEmulator_menu);
} }
else { else {
Menu_message("This core doesn't have any options."); Menu_message("This core doesn't have any options.", (char*[]){ "B","BACK", NULL });
} }
return MENU_CALLBACK_NOP; return MENU_CALLBACK_NOP;
@ -3286,7 +3297,7 @@ static int OptionSaveChanges_onConfirm(MenuList* list, int i) {
break; break;
} }
} }
Menu_message(message); Menu_message(message, (char*[]){ "A","OKAY", NULL });
OptionSaveChanges_updateDesc(); OptionSaveChanges_updateDesc();
return MENU_CALLBACK_EXIT; return MENU_CALLBACK_EXIT;
} }
@ -3979,7 +3990,7 @@ static void Menu_loop(void) {
int max_width = screen->w - SCALE1(PADDING * 2) - ow; int max_width = screen->w - SCALE1(PADDING * 2) - ow;
char display_name[256]; char display_name[256];
int text_width = GFX_truncateText(font.large, rom_name, display_name, max_width); int text_width = GFX_truncateText(font.large, rom_name, display_name, max_width, SCALE1(BUTTON_PADDING*2));
max_width = MIN(max_width, text_width); max_width = MIN(max_width, text_width);
SDL_Surface* text; SDL_Surface* text;
@ -4087,10 +4098,10 @@ static void Menu_loop(void) {
SDL_Rect preview_rect = {SCALE2(ox,oy),hw,hh}; SDL_Rect preview_rect = {SCALE2(ox,oy),hw,hh};
SDL_FillRect(screen, &preview_rect, 0); SDL_FillRect(screen, &preview_rect, 0);
if (save_exists) { // has save but no preview if (save_exists) { // has save but no preview
GFX_blitMessage("No Preview", screen, &preview_rect); GFX_blitMessage(font.large, "No Preview", screen, &preview_rect);
} }
else { // no save else { // no save
GFX_blitMessage("Empty Slot", screen, &preview_rect); GFX_blitMessage(font.large, "Empty Slot", screen, &preview_rect);
} }
} }
@ -4227,6 +4238,8 @@ int main(int argc , char* argv[]) {
MSG_init(); MSG_init();
InitSettings(); InitSettings();
// Overrides_init();
Core_open(core_path, tag_name); Core_open(core_path, tag_name);
Game_open(rom_path); Game_open(rom_path);
if (!game.is_open) goto finish; if (!game.is_open) goto finish;

View file

@ -1418,7 +1418,7 @@ int main (int argc, char *argv[]) {
trimSortingMeta(&entry_name); trimSortingMeta(&entry_name);
char display_name[256]; char display_name[256];
int text_width = GFX_truncateText(font.large, entry_unique ? entry_unique : entry_name, display_name, available_width); int text_width = GFX_truncateText(font.large, entry_unique ? entry_unique : entry_name, display_name, available_width, SCALE1(BUTTON_PADDING*2));
int max_width = MIN(available_width, text_width); int max_width = MIN(available_width, text_width);
if (j==selected_row) { if (j==selected_row) {
GFX_blitPill(ASSET_WHITE_PILL, screen, &(SDL_Rect){ GFX_blitPill(ASSET_WHITE_PILL, screen, &(SDL_Rect){
@ -1432,7 +1432,7 @@ int main (int argc, char *argv[]) {
else if (entry->unique) { else if (entry->unique) {
trimSortingMeta(&entry_unique); trimSortingMeta(&entry_unique);
char unique_name[256]; char unique_name[256];
GFX_truncateText(font.large, entry_unique, unique_name, available_width); GFX_truncateText(font.large, entry_unique, unique_name, available_width, SCALE1(BUTTON_PADDING*2));
SDL_Surface* text = TTF_RenderUTF8_Blended(font.large, unique_name, COLOR_DARK_TEXT); SDL_Surface* text = TTF_RenderUTF8_Blended(font.large, unique_name, COLOR_DARK_TEXT);
SDL_BlitSurface(text, &(SDL_Rect){ SDL_BlitSurface(text, &(SDL_Rect){
@ -1445,7 +1445,7 @@ int main (int argc, char *argv[]) {
SCALE1(PADDING+(j*PILL_SIZE)+4) SCALE1(PADDING+(j*PILL_SIZE)+4)
}); });
GFX_truncateText(font.large, entry_name, display_name, available_width); GFX_truncateText(font.large, entry_name, display_name, available_width, SCALE1(BUTTON_PADDING*2));
} }
SDL_Surface* text = TTF_RenderUTF8_Blended(font.large, display_name, text_color); SDL_Surface* text = TTF_RenderUTF8_Blended(font.large, display_name, text_color);
SDL_BlitSurface(text, &(SDL_Rect){ SDL_BlitSurface(text, &(SDL_Rect){
@ -1461,7 +1461,7 @@ int main (int argc, char *argv[]) {
} }
} }
else { else {
GFX_blitMessage("Empty folder", screen, NULL); GFX_blitMessage(font.large, "Empty folder", screen, NULL);
} }
// buttons // buttons

View file

@ -5,7 +5,7 @@
Please see the README.txt in the zip file for installation and update instructions. Please see the README.txt in the zip file for installation and update instructions.
**Base** **Base**
- - added press A to see entire (or at least more of) truncated option description
**Extras** **Extras**
- -
@ -14,7 +14,7 @@ Please see the README.txt in the zip file for installation and update instructio
create a clean image to flash and install over create a clean image to flash and install over
advanced users seem to be confused about how simple it is to install :sweat_smile: advanced users seem to be confused about how simple it is to install :sweat_smile:
this might be complicated by the gpio revs on newer devices this might be difficult with the gpio revs on newer devices
add most recent uImage/kernel changes add most recent uImage/kernel changes
wait till things settle wait till things settle
@ -29,11 +29,21 @@ hdmi
audio audio
minarch minarch
pressing A on an option shows the whole description?
gambatte's descriptions are so long this will require scrolling
which I have the design for but...
also my current wrapText implementation always puts the last word on a new line :sob:
it's not important enough for all this :joy:
move overrides to a text file that lives in the pak? move overrides to a text file that lives in the pak?
that way I don't have to update minarch to support new cores? that way I don't have to update minarch to support new cores?
that requires allocations...
wait, we could just use the existing cfg format
except extend that to include `-` prefix to lock/hide an option?
can I support changing discs in multi-disc pbps? can I support changing discs in multi-disc pbps?
figure out how to handle different button mappings for cores with different modes figure out how to handle different button mappings for cores with different modes
eg. GG or SMS with picodrive eg. GG or SMS with picodrive
also different defaults
some cores can only fast forward with prevent tearing off some cores can only fast forward with prevent tearing off
can this be set as an override preference? can this be set as an override preference?
@ -55,6 +65,8 @@ checkout eggs tools
I wonder if I could patch in Commander-11, BPreplayBold is too bold at that size I wonder if I could patch in Commander-11, BPreplayBold is too bold at that size
cores cores
pce
disable Alternate Turbo Hotkey (we don't have L3/R3)
vb vb
launching directly into native scaling has normal performance launching directly into native scaling has normal performance
but launching into aspect and switching to native tanks the but launching into aspect and switching to native tanks the