From 9a35737d0efbdce647b5e5feb5f4da14836309c2 Mon Sep 17 00:00:00 2001 From: Shaun Inman Date: Sat, 4 Mar 2023 21:46:38 -0500 Subject: [PATCH] pressing A on an option now shows more of its desc --- src/common/api.c | 26 +++++++++++++++----------- src/common/api.h | 4 ++-- src/minarch/main.c | 43 ++++++++++++++++++++++++++++--------------- src/minui/main.c | 8 ++++---- todo.txt | 16 ++++++++++++++-- 5 files changed, 63 insertions(+), 34 deletions(-) diff --git a/src/common/api.c b/src/common/api.c index fb72236..c1e4702 100644 --- a/src/common/api.c +++ b/src/common/api.c @@ -438,23 +438,23 @@ SDL_Surface* GFX_getBufferCopy(void) { // must be freed by caller SDL_BlitSurface(gfx.screen, NULL, copy, NULL); 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; strcpy(out_name, in_name); TTF_SizeUTF8(font, out_name, &text_width, NULL); - text_width += SCALE1(12*2); + text_width += padding; while (text_width>max_width) { int len = strlen(out_name); strcpy(&out_name[len-4], "...\0"); TTF_SizeUTF8(font, out_name, &text_width, NULL); - text_width += SCALE1(12*2); + text_width += padding; } return text_width; } 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; @@ -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); 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); return line_width; } @@ -478,8 +478,12 @@ int GFX_wrapText(TTF_Font* font, char* str, int max_width, int max_lines) { tmp = strchr(tmp, ' '); if (!tmp) { if (prev) { - prev[0] = '\n'; - line = prev + 1; + TTF_SizeUTF8(font, line, &line_width, NULL); + if (line_width>=max_width) { + if (line_width>max_line_width) max_line_width = line_width; + prev[0] = '\n'; + line = prev + 1; + } } break; } @@ -504,7 +508,7 @@ int GFX_wrapText(TTF_Font* font, char* str, int max_width, int max_lines) { i += 1; } - line_width = GFX_truncateText(font,line,buffer,max_width); + line_width = GFX_truncateText(font,line,buffer,max_width,0); strcpy(line,buffer); 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_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}; SDL_Surface* text; @@ -686,7 +690,7 @@ void GFX_blitMessage(char* msg, SDL_Surface* dst, SDL_Rect* dst_rect) { if (len) { - text = TTF_RenderUTF8_Blended(font.large, line, COLOR_WHITE); + text = TTF_RenderUTF8_Blended(font, line, COLOR_WHITE); int x = dst_rect->x; x += (dst_rect->w - text->w) / 2; SDL_BlitSurface(text, NULL, dst, &(SDL_Rect){x,y}); @@ -1399,7 +1403,7 @@ void POW_powerOff(void) { if (pow.can_poweroff) { char* msg = exists(AUTO_RESUME_PATH) ? "Quicksave created,\npowering off" : "Powering off"; GFX_clear(gfx.screen); - GFX_blitMessage(msg, gfx.screen, NULL); + GFX_blitMessage(font.large, msg, gfx.screen, NULL); GFX_flip(gfx.screen); sleep(2); diff --git a/src/common/api.h b/src/common/api.h index df44aad..3cb629e 100644 --- a/src/common/api.h +++ b/src/common/api.h @@ -117,7 +117,7 @@ int GFX_getVsync(void); void GFX_setVsync(int vsync); 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); // 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); int GFX_getButtonWidth(char* hint, char* button); 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_blitButtonGroup(char** hints, SDL_Surface* dst, int align_right); diff --git a/src/minarch/main.c b/src/minarch/main.c index 78dc39e..82f9566 100644 --- a/src/minarch/main.c +++ b/src/minarch/main.c @@ -551,7 +551,8 @@ static void State_resume(void) { typedef struct Option { char* key; char* name; // desc - char* desc; // info + char* desc; // info, truncated + char* full; // info char* var; int default_value; int value; @@ -1066,9 +1067,15 @@ static void OptionList_init(const struct retro_core_option_definition *defs) { len = strlen(def->info) + 1; item->desc = calloc(len, sizeof(char)); 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++); @@ -1216,6 +1223,7 @@ static void OptionList_reset(void) { } else { if (item->desc) free(item->desc); + if (item->full) free(item->full); for (int j=0; jcount; j++) { char* value = item->values[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 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 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! @@ -2994,10 +3001,7 @@ typedef struct MenuList { MenuList_callback_t on_change; } MenuList; -static void Menu_detail(MenuItem* item) { - // TODO: name -} -static int Menu_message(char* message) { +static int Menu_message(char* message, char** pairs) { GFX_setMode(MODE_MAIN); int dirty = 1; while (1) { @@ -3012,8 +3016,8 @@ static int Menu_message(char* message) { if (dirty) { if (!resized) GFX_clear(screen); // resizing clears the screen GFX_clear(screen); - GFX_blitMessage(message, screen, NULL); - GFX_blitButtonGroup((char*[]){ "A","OKAY", NULL }, screen, 1); + GFX_blitMessage(font.medium, message, screen, &(SDL_Rect){0,SCALE1(PADDING),screen->w,screen->h-SCALE1(PILL_SIZE+PADDING)}); + GFX_blitButtonGroup(pairs, screen, 1); GFX_flip(screen); dirty = 0; } @@ -3078,8 +3082,15 @@ static int OptionEmulator_optionChanged(MenuList* list, int i) { ); 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 = { .type = MENU_FIXED, + .on_confirm = OptionEmulator_optionDetail, // TODO: this needs pagination to be truly useful .on_change = OptionEmulator_optionChanged, .items = NULL, }; @@ -3112,7 +3123,7 @@ static int OptionEmulator_openMenu(MenuList* list, int i) { Menu_options(&OptionEmulator_menu); } 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; @@ -3286,7 +3297,7 @@ static int OptionSaveChanges_onConfirm(MenuList* list, int i) { break; } } - Menu_message(message); + Menu_message(message, (char*[]){ "A","OKAY", NULL }); OptionSaveChanges_updateDesc(); return MENU_CALLBACK_EXIT; } @@ -3979,7 +3990,7 @@ static void Menu_loop(void) { int max_width = screen->w - SCALE1(PADDING * 2) - ow; 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); SDL_Surface* text; @@ -4087,10 +4098,10 @@ static void Menu_loop(void) { SDL_Rect preview_rect = {SCALE2(ox,oy),hw,hh}; SDL_FillRect(screen, &preview_rect, 0); 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 - 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(); InitSettings(); + // Overrides_init(); + Core_open(core_path, tag_name); Game_open(rom_path); if (!game.is_open) goto finish; diff --git a/src/minui/main.c b/src/minui/main.c index 6c07b17..f7fbdeb 100644 --- a/src/minui/main.c +++ b/src/minui/main.c @@ -1418,7 +1418,7 @@ int main (int argc, char *argv[]) { trimSortingMeta(&entry_name); 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); if (j==selected_row) { GFX_blitPill(ASSET_WHITE_PILL, screen, &(SDL_Rect){ @@ -1432,7 +1432,7 @@ int main (int argc, char *argv[]) { else if (entry->unique) { trimSortingMeta(&entry_unique); 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_BlitSurface(text, &(SDL_Rect){ @@ -1445,7 +1445,7 @@ int main (int argc, char *argv[]) { 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_BlitSurface(text, &(SDL_Rect){ @@ -1461,7 +1461,7 @@ int main (int argc, char *argv[]) { } } else { - GFX_blitMessage("Empty folder", screen, NULL); + GFX_blitMessage(font.large, "Empty folder", screen, NULL); } // buttons diff --git a/todo.txt b/todo.txt index 0119a86..53ecea9 100644 --- a/todo.txt +++ b/todo.txt @@ -5,7 +5,7 @@ Please see the README.txt in the zip file for installation and update instructions. **Base** -- +- added press A to see entire (or at least more of) truncated option description **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 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 wait till things settle @@ -29,11 +29,21 @@ hdmi audio 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? 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? figure out how to handle different button mappings for cores with different modes eg. GG or SMS with picodrive + also different defaults some cores can only fast forward with prevent tearing off 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 cores + pce + disable Alternate Turbo Hotkey (we don't have L3/R3) vb launching directly into native scaling has normal performance but launching into aspect and switching to native tanks the