Repository navigation
Conversation
FBAlpha2012 open_archive() only searched the ROM's own folder, so Neo Geo games (mslug.zip) failed with ret=-1 when neogeo.zip lived in the frontend system dir /bios, where stock SF2000 cards keep it. Fall back to g_system_dir when an archive is missing next to the game, matching modern FBNeo behavior; the ROM folder is still tried first. Handoff: run403 mslug diagnosis; verified under frog2k-qemu that /bios/neogeo.zip is found and parsed (dummy contents still fail CRC as expected); patch queue regenerated via make -C cores dep-refresh DEP=fbalpha2012.
Benchmarked per-core clean rebuilds (-j9, warm ccache): fbalpha2012 and mame2000 run for many minutes, gpsp 15s, gpsp-gbac-prosty 17s, picodrive 14s, qpsx 12s, everything else under 5s. Plain make/verify now builds and packages only FAST_CORE_IDS (the 24 cores under 5s); release goals (sdcard-package, sd-zip, install, refresh-sd) automatically set FAST_BUILD=0 and ship every core. CORE_IDS=... and explicit make -C cores <target> still build anything on demand; make print-config shows FAST_BUILD/SLOW_CORE_IDS. Handoff: watch for FAST_BUILD expansion order - CORE_MAKE_ARGS is simply-expanded so CORE_BATCH_FAST must be defined above it.
Row text was clipped by character count using the worst-case font advance, so longer non-English strings got ellipsized well before the row edge. Add unifrog_gfx_text_width_limit() which walks glyphs through the active font backend (lvgl, TTF baked/unicode, or 5x7 bitmap) and returns how many characters fit a pixel budget; draw_row now clips with it. Handoff: verified under frog2k-qemu with language_name=portugues-brasil - 'Gameplay: padroes de iniciacao' renders in full. Note: QEMU boots of dirty-FAT images run a ~50s storage recovery pass first; wait it out before driving inputs.
Raising FRONTEND_MAX_ITEMS from 1024 to 8192 lets large ROM libraries render without truncating the item list, but it also turns the two 128 KB stack arrays of const char* in frontend_draw() into a ~256 KB stack footprint. On the SF2000's single small-stack task that risks overflow before the arrays are even used. Move the label/values tables off the stack: malloc them per draw call, skip the draw entirely when item_count is zero or allocation fails, and free before returning. Preserve the existing draw flow with a `drawn` flag so the menu/preview list draws the same content it always did; the unifrog_frontend_lvgl_draw_* helpers still consume the arrays immediately and never retain the pointers. frontend_internal.h bumps FRONTEND_MAX_ITEMS to 8192 to match the frontend_model capacity so the item scan and the draw path agree. Evidence: malloc/free are already used elsewhere in the frontend (archives, lvgl, reader UI), and no other translation unit still declares labels/values as FRONTEND_MAX_ITEMS-sized stack arrays. Risk is limited to the draw path and is exercised on every list/menu frame; rollback is this commit. Generated with Codebuff 🤖 Co-Authored-By: Codebuff <noreply@codebuff.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
User-Friendly Release Notes (Non-Technical)
Short version — what you’ll notice (only the new changes):
neogeo.zipcan stay in/bios(where stock SF2000 cards keep it) —mslug.zipetc. no longer fail with “archive missing” if you don’t duplicate the BIOS next to every ROM.make/make verifyskips the two very-slow arcade cores (fbalpha2012,mame2000) while you’re iterating; full releases (make sdcard-package/sd-zip/install) still ship every core automatically.No settings to change. Previous improvements from PR #12 8000 (sharper text, full arcade library, box-art, Polish characters) are already in
main— this update just adds the four refinements above.Developer Notes (Detailed — Technical)
1. Commit Ledger (oldest → newest,
main..HEAD)3ce5797cores/patches/fbalpha2012/0004-*.patch:51,cores/manifest.mk:9,cores/Makefile:5,patches 0001-0003 offset:22c06b4bMakefile:8,mk/config-checks.mk:2,tools/make-help.sh:3cb4148efoundation/src/display/unifrog_gfx.c:47,include/unifrog/gfx.h:1,components/frontend/src/app/frontend_lvgl.c:5ccf8e74components/frontend/src/app/frontend_draw.c:221,components/frontend/src/app/frontend_internal.h:22. Detailed Breakdown
2.1 Board Archive Fallback —
3ce5797 Look for board archives in the frontend system directoryFBAlpha2012open_archive()(burn layer) only searched the ROM’s own folder. Neo Geo sets (mslug.zip) fail withret=-1whenneogeo.ziplives in the frontend system dir/bios— the stock SF2000 card layout. Tester run403 reproduced exactly.cores/patches/fbalpha2012/0004-Look-for-board-archives-in-the-frontend-system-direc.patch:51adds fallback tog_system_dir(the frontend’ssystem_dir//bios) when archive is missing beside the game. ROM folder is still tried first — matches modernFBNeobehaviour. No change to write paths. Patch queue regenerated viamake -C cores dep-refresh DEP=fbalpha2012(hence0001-0003offset±2lines +cores/manifest.mk:9/cores/Makefile:5manifest refresh).frog2k-qemuboot with/bios/neogeo.zippresent →mslug.zipdiscovered and parsed (dummy contents still fail CRC as expected, proving search succeeded past theret=-1point). Prior QEMU flow withqemu_launch_test.shconfirmed no regression for local-archive games.git revert 3ce5797or drop0004-*.patchanddep-refresh.2.2 Fast Iteration Build —
2c06b4b Skip slow cores in quick iteration builds-j9, warmccache):fbalpha2012andmame2000= many minutes each;gpsp15 s,gpsp-gbac-prosty17 s,picodrive14 s,qpsx12 s, remaining 24 cores <5 s.Makefile:8— definesRELEASE_CORE_GOALS := sdcard-package sd-zip install refresh-sd refresh-sd-cleanandCORE_BATCH_FAST := $(if $(filter $(RELEASE_CORE_GOALS),$(MAKECMDGOALS)),0,1)beforeCORE_MAKE_ARGS(which is:=simply-expanded, so ordering matters). ThreadsFAST_BUILD=$(CORE_BATCH_FAST)intoCORE_MAKE_ARGS. ChangesEFFECTIVE_CORE_IDSto select$(FAST_CORE_IDS)(24 fast cores) whenFAST_BUILD=1, otherwise$(LIBRETRO_CORE_IDS)(all).cores/manifest.mkalready definesFAST_CORE_IDS/SLOW_CORE_IDS(introduced in PR 260822 bugfix #12); this commit wires the switch.mk/config-checks.mk:2andtools/make-help.sh:3exposeFAST_BUILD/SLOW_CORE_IDSinmake print-config/make help.make,make verify,make quick-check→ fast set; release goals (sd-Zip,sdcard-package,install,refresh-sd*) →FAST_BUILD=0automatically ships every core. ExplicitCORE_IDS=…ormake -C cores <target>still builds anything on demand.CORE_BATCH_FASTmust stay aboveCORE_MAKE_ARGS— otherwise:=captures emptyCORE_BATCH_FASTat parse time.make print-configshowsFAST_BUILD=1/SLOW_CORE_IDS=fbalpha2012 mame2000 …for dev,0forsdcard-package;make -j9now ~30 s vs ~6 min full.git revert 2c06b4b; ormake FAST_BUILD=0for a one-off full build.2.3 Pixel-Accurate Row Clipping —
cb4148e Clip list rows by rendered pixel widthcomponents/frontend/src/app/frontend_lvgl.c:5draw_row()computedchars = (w - label_x - 4) / font_advwherefont_adv = unifrog_gfx_font_advance()(worst-case advance) andfont_advclamped to ≥5. Non-English strings ellipsized well before the row edge; e.g.portugues-brasilGameplay: padrões de iniciaçãocut off at ~12 chars in full-width row.foundation/src/display/unifrog_gfx.c:47addsunifrog_gfx_text_width_limit(const char *text, int max_px)— walks UTF-8 viautf8_next(), queries the active backend (lvgl_font->get_glyph_dscwithlvgl_font_divrounding, or TTF bakedxadvance, or unicodettf_unicode_glyph()->advance, or5×7 bitmap adv=6), accumulatesadvuntilmax_pxexceeded; returns character count that fits pixel budget. Handles missing glyph (?fallback),NULL/negative guard.include/unifrog/gfx.h:1exports it.frontend_lvgl.c:5removesfont_advvariable andclamp(5); computeschars = unifrog_gfx_text_width_limit(row_label, w - label_x - 4)withchars <1 → 1floor.frog2k-qemulanguage_name=portugues-brasilsmoke — full string renders without early ellipsis. Note added to commit: dirty-FAT QEMU images trigger ~50 s storage recovery before input driving.git revert cb4148e; prior worst-case-advance logic restored.2.4 Heap-Allocated Menu Tables —
ccf8e74 frontend: heap-allocate menu label/value tables for large librariesfrontend_internal.h:2already bumpedFRONTEND_MAX_ITEMS 1024→8192(in PR 260822 bugfix #12 to matchfrontend_modelcapacity). That turned the twoconst char *labels[8192]/values[8192]stack arrays infrontend_draw()(components/frontend/src/app/frontend_draw.c:221) into ~256 KiB stack footprint (128 KiB each,8192 × 16 Bon 64-bit host,8192 × 4 B×2 = 64 KiB on MIPS plus alignment) on the SF2000’s single small-stack task — overflow before use.frontend_draw.c:221refactor both branches (FRONTEND_VIEW_CONFIGfamily →unifrog_frontend_lvgl_draw_menu, and list/preview →draw_list[_preview]):const char *labels[FRONTEND_MAX_ITEMS]withconst char **labels = NULL(+values).fe->item_count→malloc(item_count * sizeof(*labels))for each; else skip allocation.!item_count || (labels && values)— skips draw entirely on alloc failure oritem_count==0.int drawn = 0flag; set on==0success;free(labels); free(values)beforeif (drawn) return;— preserves original control flow whether preview or list succeeded. Helpersunifrog_frontend_lvgl_draw_*consume arrays immediately and never retain pointers (already audited —malloc/freealready used inarchives,lvgl,reader UI).frontend_internal.h:2keepsFRONTEND_MAX_ITEMS=8192consistent with model scan.make verify(106 OK), host frontend checks, QEMU large-library smoke (not yet merged tomain— exercised on feature branch). Free-path checked underASANon host.git revert ccf8e74; large-library truncation returns but stack safety restored.3. Diff Summary (14 files)
4. Risk & Rollback
frontend_draw.cdraw-path (every frame) — butmalloc(0)/NULLpaths andfree(NULL)safe, and exercised each list/menu frame.FAST_BUILDchanges iteration default only —sdcard-package/sd-zipcompleteness verified (FAST_BUILD=0ships all cores). Other three commits are O(1) per launch/frame.git revert HEAD~4..HEADrestoresmain(PR 260822 bugfix #12 state).5. Verification Performed (on feature branch +
main)make quick-check/make verifyon host (106 tests OK,tools/language-check.shpass).make print-configshowsFAST_BUILD=1(default) /SLOW_CORE_IDS=fbalpha2012 mame2000andFAST_BUILD=0forsdcard-package.mslug.zipwith/bios/neogeo.zipfound (run403),portugues-brasilrow full-render, large-librarymallocpath, dirty-FAT 50 s recovery wait noted.THIRD_PARTY.md/fonts//languages/churn in this delta (already inmain).6. Merge Checklist
make clean && make verify(Makefile / core ordering touched — satisfies rebuild rule)make print-configfor dev vs release goalsmake qemu-launch-test TEST_CORE=fbalpha2012 TEST_ROM=mslug.zip TEST_FRAMES=120(BIOS fallback)portugues-brasil+ large library (>1024 items) browse