Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
585c0ac
feat: Grid layout for game and system lists
Xisrith Nov 5, 2026
82cad52
Merge pull request #1 from Xisrith/xisrith/grid-layout
Xisrith Nov 5, 2026
9788d1e
feat: All games view
Xisrith Nov 5, 2026
6ea05d4
Merge pull request #2 from Xisrith/xisrith/all-games-view
Xisrith Nov 5, 2026
e82b198
feat: Screen margin setting and grid title spacing
Xisrith Nov 5, 2026
0633555
Merge pull request #3 from Xisrith/xisrith/screen-margin
Xisrith Nov 5, 2026
fb09acb
feat: Name the selected Quick Menu item
Xisrith Nov 5, 2026
9aa2b7b
Merge pull request #4 from Xisrith/xisrith/quick-menu-labels
Xisrith Nov 5, 2026
6b2f3ce
feat: Wrap grid Up/Down into neighbouring columns
Xisrith Nov 5, 2026
e47613f
Merge pull request #5 from Xisrith/xisrith/grid-updown-column-wrap
Xisrith Nov 5, 2026
f239e0c
feat: Setting to show or hide the Quick Menu title
Xisrith Nov 5, 2026
e245c6e
Merge pull request #6 from Xisrith/xisrith/quick-menu-title-setting
Xisrith Nov 5, 2026
78aeb70
feat: Resume with A setting
Xisrith Nov 5, 2026
f3c33f9
feat: Save & Quit in the in-game menu
Xisrith Nov 5, 2026
09a759e
Merge pull request #7 from Xisrith/xisrith/resume-with-a
Xisrith Nov 5, 2026
970420a
Merge pull request #8 from Xisrith/xisrith/save-quit-menu
Xisrith Nov 5, 2026
2756509
feat: Rename setting to "Allow Save & Quit from menu"
Xisrith Nov 6, 2026
fbe3637
Merge pull request #9 from Xisrith/xisrith/allow-save-quit-from-menu
Xisrith Nov 6, 2026
8c0c979
feat: Tools in all games view, with an icon on grid tiles
Xisrith Nov 6, 2026
f7f73ba
Merge remote-tracking branch 'origin/main' into xisrith/quick-menu-ti…
Xisrith Nov 6, 2026
1165842
Merge pull request #10 from Xisrith/xisrith/tools-in-all-games-view
Xisrith Nov 6, 2026
ab7f3fb
feat: Show or hide Recents, Games and Tools in the Quick Menu
Xisrith Nov 6, 2026
94545cb
Merge pull request #11 from Xisrith/xisrith/quick-menu-item-toggles
Xisrith Nov 6, 2026
90f4793
Update README to include details of how this fork differs from origin
Xisrith Nov 6, 2026
19ce680
Clean up some wording in the README and add a redirect to the LoveRet…
Xisrith Nov 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,42 @@
A fork of NextUI to improve usability for myself and make the OS easier to use for my parents.

**This repo is a hobby project, it is not actively maintained.**

If you want to use NextUI for your own handheld, get it from [Love Retro](https://github.com/LoveRetro/NextUI).

## AI Disclaimer

In the interest of full transparency: this fork was developed using AI tooling, specifically Claude Code.

I've been a professional software developer since 2020 and AI agents are just part of my workflow. I have never developed C or C++ professionally (though I do like to use C for hobby projects) so while I've reviewed every code change, I am limited by my lack of experience, esp for C-specific things like safe memory management. (If you care, my primary languages are C# for backend/desktop and TypeScript for frontend.)

I have done my best to keep PRs and commits small for reviewability should anyone want to cherry pick features out of this fork.

## Context

I got my parents an ANBERNIC RG 40XXH for Christmas so they could play their childhood games, but I knew immediately I was not going to be using the stock OS. After trying a few options I landed on using NextUI because it was focused and booted in and out of games extremely fast. It still felt open and breakable though, so I started this personal fork to lock it down and remove some footguns that I shot myself with in the past using NextUI on my own ANBERNIC RG SP.

## Changes

Everything was developed as atomic features that could be toggled via the settings. I did my best to develop the features in one PR per feature-setting to make cherry-picking easier if other folks want to take some of these. Every PR is tagged with what feature it touched for easier navigation.

In order of smallest to largest:

| Feature | Setting | Description | Reason | Limitations |
|-|-|-|-|-|
| Screen margin | Appearance / Screen margin | Adjusts the margin between the edge of the screen and widgets like the battery and input prompts. | Reclaims space on low resolution devices | Overrides both low res and high res / external displays with the same value when by default they are different. |
| Quick menu title | Appearance / Show Quick Menu title | Shows a title for each quick setting button in the top left of the screen. | Remove ambiguity in what the icon-only buttons do in the quick menu. | |
| Quick menu tiles | Appearch / Show X in Quick Menu | A series of options to disable the tiles that appear in the quick menu, specifically recents, games, and tools. | Recents and games as options don't make sense for my needs and at that point it was just tools so I cut it too for a cleaner look. | |
| All games list | Appearance / All games view | Skips the system menu and just shows all games in a single alphabatized list. | With a small games library (10-12 games) the system menu was more a burden than anything. | Recently played doesn't have anywhere to live so only exists in the quick menu. |
| Resume with A | System / Resume with A | Swaps the A/X behavior so resume is mapped to A and open is mapped to X | A is the default way someone would try to launch a game so this effectively lets someone make resuming their default action. | |
| Save & Quit | System / Allow Save & Quit from menu | Adds the Save & Quit option to the in-game menu if the game is targeting a save slot already. | Remembering a hotkey is more annoying than using the menu. | |
| Grid view | Appearance / Content layout + Appearance / Grid rows | Show the list in a horizontal grid of icon buttons, rendering the game title in the top left corner. | A horizontal grid is more familiar to people trained on smartphones. | Entries that don't have an icon defined use their first letter as their icon and those icons have to be provided manually. |

## Testing

All testing has been done on device with the H700 powered ANBERNIC RG 40XXH. I don't have any devices running other NextUI supported architectures to test on them.


<div align="center">

<img width=128px src="github/logo_outline.png">
Expand Down
37 changes: 29 additions & 8 deletions workspace/all/common/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -362,12 +362,25 @@ FALLBACK_IMPLEMENTATION void PLAT_getGPUUsage()
perf.gpu_usage = 0.0;
}

static char system_font_path[MAX_PATH] = "";

const char *GFX_getSystemFontPath(void)
{
return system_font_path;
}

int GFX_loadSystemFont(const char *fontPath)
{
// Load/Reload fonts
if (!TTF_WasInit())
TTF_Init();

if (fontPath && fontPath != system_font_path)
{
strncpy(system_font_path, fontPath, sizeof(system_font_path) - 1);
system_font_path[sizeof(system_font_path) - 1] = '\0';
}

TTF_CloseFont(font.large);
TTF_CloseFont(font.medium);
TTF_CloseFont(font.small);
Expand Down Expand Up @@ -2356,18 +2369,25 @@ SDL_Surface* GFX_createScreenFormatSurface(int width, int height)
);
}

int GFX_getScreenMargin(void)
{
int margin = CFG_getScreenMargin();
return SCALE1(margin < 0 ? PADDING : margin);
}

int GFX_blitHardwareGroup(SDL_Surface *dst, int show_setting)
{
int ox;
int oy;
int ow = 0;
int margin = GFX_getScreenMargin();

if (show_setting && !GetHDMI())
{
// Use the helper function to render the indicator at the standard position
ow = SCALE1(PILL_SIZE + SETTINGS_WIDTH + 10 + 4);
ox = dst->w - SCALE1(PADDING) - ow;
oy = SCALE1(PADDING);
ox = dst->w - margin - ow;
oy = margin;
GFX_blitHardwareIndicator(dst, ox, oy, (IndicatorType)show_setting);
}
else
Expand All @@ -2384,8 +2404,8 @@ int GFX_blitHardwareGroup(SDL_Surface *dst, int show_setting)
if (!show_bt && !show_wifi && !show_clock)
{
ow = SCALE1(PILL_SIZE);
ox = dst->w - SCALE1(PADDING) - ow;
oy = SCALE1(PADDING);
ox = dst->w - margin - ow;
oy = margin;

GFX_blitPillColor(ASSET_WHITE_PILL, dst, &(SDL_Rect){ox, oy, ow, SCALE1(PILL_SIZE)}, THEME_COLOR2, RGB_WHITE);

Expand Down Expand Up @@ -2435,8 +2455,8 @@ int GFX_blitHardwareGroup(SDL_Surface *dst, int show_setting)
ow += clock_width + SCALE1(BUTTON_MARGIN);
}

ox = dst->w - SCALE1(PADDING) - ow;
oy = SCALE1(PADDING);
ox = dst->w - margin - ow;
oy = margin;
GFX_blitPillColor(ASSET_WHITE_PILL, dst, &(SDL_Rect){ox, oy, ow, SCALE1(PILL_SIZE)}, THEME_COLOR2, RGB_WHITE);

ox += SCALE1(BUTTON_MARGIN);
Expand Down Expand Up @@ -2523,8 +2543,9 @@ int GFX_blitButtonGroup(char **pairs, int primary, SDL_Surface *dst, int align_r
int w = 0; // individual button dimension
int h = 0; // hints index
ow = 0; // full pill width
ox = align_right ? dst->w - SCALE1(PADDING) : SCALE1(PADDING);
oy = dst->h - SCALE1(PADDING + PILL_SIZE);
int margin = GFX_getScreenMargin();
ox = align_right ? dst->w - margin : margin;
oy = dst->h - margin - SCALE1(PILL_SIZE);

for (int i = 0; i < 2; i++)
{
Expand Down
7 changes: 6 additions & 1 deletion workspace/all/common/api.h
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,10 @@ int GFX_getButtonWidth(char* hint, char* button);
void GFX_blitButton(char* hint, char*button, 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); // returns the status pill's width
// Scaled distance between the screen edges and edge-anchored UI (status pill,
// button hints, list title): the "Screen margin" setting, PADDING by default.
int GFX_getScreenMargin(void);
void GFX_blitHardwareHints(SDL_Surface* dst, int show_setting);
void GFX_blitTopCurtain(SDL_Surface* dst);
void GFX_blitBottomCurtain(SDL_Surface* dst);
Expand Down Expand Up @@ -449,6 +452,8 @@ void GFX_ApplyRoundedCorners16(SDL_Surface* surface, SDL_Rect* rect, int radius)
void GFX_ApplyRoundedCorners_4444(SDL_Surface* surface, SDL_Rect* rect, int radius);
// for both ARGB8888 and RGBA8888
void GFX_ApplyRoundedCorners_8888(SDL_Surface* surface, SDL_Rect* rect, int radius);
// Path of the currently loaded UI font file ("" before GFX_init), for opening it at other sizes
const char* GFX_getSystemFontPath(void);
///////////////////////////////

typedef struct SND_Frame {
Expand Down
Loading