From 2954abebbc4d5be26043bd2cd4071e9ffc8e0951 Mon Sep 17 00:00:00 2001 From: frysee Date: Fri, 3 Jul 2026 23:07:17 +0200 Subject: [PATCH 01/77] Feat: Alpha channel for theme colors and better pill sprite handling (#762) * feat: full alpha transparency support for theme colors, 3-slicing for pill sprites * feat: option for a half-transparent top/bottom curtain on game switcher (helps when using transparent pills) --- workspace/all/battery/battery.c | 6 +- workspace/all/common/api.c | 200 ++++++++++++++++++--- workspace/all/common/api.h | 9 +- workspace/all/common/config.c | 136 ++++++++++---- workspace/all/common/config.h | 21 ++- workspace/all/nextui/nextui.c | 5 + workspace/all/settings/colorpickermenu.cpp | 123 +++++++++---- workspace/all/settings/colorpickermenu.hpp | 2 +- workspace/all/settings/menu.cpp | 17 +- workspace/all/settings/settings.cpp | 14 +- 10 files changed, 409 insertions(+), 124 deletions(-) diff --git a/workspace/all/battery/battery.c b/workspace/all/battery/battery.c index 68fae04d5..990d63ac7 100644 --- a/workspace/all/battery/battery.c +++ b/workspace/all/battery/battery.c @@ -487,9 +487,9 @@ void renderPage() // monochrome is more MinUI, but some colours are nice const bool ilikeitcolourful = true; if(ilikeitcolourful) { - white_pixel_color = SDL_MapRGB(screen->format, 255, 255, 255); - red_pixel_color = SDL_MapRGB(screen->format, 255, 170, 170); - blue_pixel_color = SDL_MapRGB(screen->format, 89, 167, 255); + white_pixel_color = SDL_MapRGBA(screen->format, 255, 255, 255, 255); + red_pixel_color = SDL_MapRGBA(screen->format, 255, 170, 170, 255); + blue_pixel_color = SDL_MapRGBA(screen->format, 89, 167, 255, 255); pixel_color = white_pixel_color; } diff --git a/workspace/all/common/api.c b/workspace/all/common/api.c index 25b4998e9..3084abc4a 100644 --- a/workspace/all/common/api.c +++ b/workspace/all/common/api.c @@ -110,47 +110,57 @@ SDL_Color ALT_BUTTON_TEXT_COLOR; // Function to convert hex color code to RGB and set the values static inline uint32_t HexToUint(const char *hexColor) { - int r, g, b; - sscanf(hexColor, "%02x%02x%02x", &r, &g, &b); - return SDL_MapRGB(gfx.screen->format, r, g, b); + int r, g, b, a = 255; // Default alpha value to 255 (fully opaque) + // hex color code may or may not have alpha channel, so we need to handle both cases + if (strlen(hexColor) == 8) // If the hex color code has alpha channel + { + sscanf(hexColor, "%02x%02x%02x%02x", &r, &g, &b, &a); + } + else // If the hex color code does not have alpha channel + { + sscanf(hexColor, "%02x%02x%02x", &r, &g, &b); + } + return SDL_MapRGBA(gfx.screen->format, r, g, b, a); } static inline uint32_t HexToUint32_unmapped(const char *hexColor) { - // Convert the hex string to an unsigned long - uint32_t value = (uint32_t)strtoul(hexColor, NULL, 16); - return value; + // Convert the hex string to an unsigned long + uint32_t value = (uint32_t)strtoul(hexColor, NULL, 16); + return value; } -static inline void rgb_unpack(uint32_t col, int *r, int *g, int *b) +static inline void rgba_unpack(uint32_t col, int *r, int *g, int *b, int *a) { - *r = (col >> 16) & 0xff; - *g = (col >> 8) & 0xff; - *b = col & 0xff; + *r = (col >> 24) & 0xff; + *g = (col >> 16) & 0xff; + *b = (col >> 8) & 0xff; + *a = col & 0xff; } -static inline uint32_t rgb_pack(int r, int g, int b) +static inline uint32_t rgba_pack(int r, int g, int b, int a) { - return (r << 16) + (g << 8) + b; + return (r << 24) + (g << 16) + (b << 8) + a; } static inline uint32_t mapUint(uint32_t col) { - int r, g, b; - rgb_unpack(col, &r, &g, &b); - return SDL_MapRGB(gfx.screen->format, r, g, b); + int r, g, b, a; + rgba_unpack(col, &r, &g, &b, &a); + return SDL_MapRGBA(gfx.screen->format, r, g, b, a); } -static inline uint32_t UintMult(uint32_t color, uint32_t modulate_rgb) +static inline uint32_t UintMult(uint32_t color, uint32_t modulate_rgba) { SDL_Color dest = uintToColour(color); - SDL_Color modulate = uintToColour(modulate_rgb); + SDL_Color modulate = uintToColour(modulate_rgba); dest.r = (int)dest.r * modulate.r / 255; dest.g = (int)dest.g * modulate.g / 255; dest.b = (int)dest.b * modulate.b / 255; + dest.a = (int)dest.a * modulate.a / 255; - return (dest.r << 16) | (dest.g << 8) | dest.b; + return (dest.r << 24) | (dest.g << 16) | (dest.b << 8) | dest.a; } /////////////////////////////// @@ -370,10 +380,15 @@ SDL_Surface *GFX_init(int mode) RGB_DARK_GRAY = SDL_MapRGB(gfx.screen->format, TRIAD_DARK_GRAY); asset_rgbs[ASSET_WHITE_PILL] = RGB_WHITE; + asset_rgbs[ASSET_WHITE_RECT] = RGB_WHITE; asset_rgbs[ASSET_BLACK_PILL] = RGB_BLACK; + asset_rgbs[ASSET_BLACK_RECT] = RGB_BLACK; asset_rgbs[ASSET_DARK_GRAY_PILL] = RGB_DARK_GRAY; + asset_rgbs[ASSET_DARK_GRAY_RECT] = RGB_DARK_GRAY; asset_rgbs[ASSET_OPTION] = RGB_DARK_GRAY; + asset_rgbs[ASSET_OPTION_RECT] = RGB_DARK_GRAY; asset_rgbs[ASSET_BUTTON] = RGB_WHITE; + asset_rgbs[ASSET_BUTTON_RECT] = RGB_WHITE; asset_rgbs[ASSET_PAGE_BG] = RGB_WHITE; asset_rgbs[ASSET_STATE_BG] = RGB_WHITE; asset_rgbs[ASSET_PAGE] = RGB_BLACK; @@ -387,8 +402,13 @@ SDL_Surface *GFX_init(int mode) asset_rects[ASSET_WHITE_PILL] = (SDL_Rect){SCALE4(1, 1, 30, 30)}; asset_rects[ASSET_BLACK_PILL] = (SDL_Rect){SCALE4(33, 1, 30, 30)}; asset_rects[ASSET_DARK_GRAY_PILL] = (SDL_Rect){SCALE4(65, 1, 30, 30)}; + asset_rects[ASSET_WHITE_RECT] = (SDL_Rect){SCALE4(1+14, 1, 2, 30)}; // two pixels wide, middle of the asset + asset_rects[ASSET_BLACK_RECT] = (SDL_Rect){SCALE4(33+14, 1, 2, 30)}; // two pixels wide, middle of the asset + asset_rects[ASSET_DARK_GRAY_RECT] = (SDL_Rect){SCALE4(65+14, 1, 2, 30)}; // two pixels wide, middle of the asset asset_rects[ASSET_OPTION] = (SDL_Rect){SCALE4(97, 1, 20, 20)}; + asset_rects[ASSET_OPTION_RECT] = (SDL_Rect){SCALE4(97+9, 1, 2, 20)}; // two pixels wide, middle of the asset asset_rects[ASSET_BUTTON] = (SDL_Rect){SCALE4(1, 33, 20, 20)}; + asset_rects[ASSET_BUTTON_RECT] = (SDL_Rect){SCALE4(1+9, 33, 2, 20)}; // two pixels wide, middle of the asset asset_rects[ASSET_PAGE_BG] = (SDL_Rect){SCALE4(64, 33, 15, 15)}; asset_rects[ASSET_STATE_BG] = (SDL_Rect){SCALE4(23, 54, 8, 8)}; asset_rects[ASSET_PAGE] = (SDL_Rect){SCALE4(39, 54, 6, 6)}; @@ -1347,13 +1367,13 @@ void GFX_freeAAScaler(void) /////////////////////////////// -SDL_Color /*GFX_*/ uintToColour(uint32_t colour) +SDL_Color /*GFX_*/ uintToColour(uint32_t rgba) { SDL_Color tempcol; - tempcol.a = 255; - tempcol.r = (colour >> 16) & 0xFF; - tempcol.g = (colour >> 8) & 0xFF; - tempcol.b = colour & 0xFF; + tempcol.r = (rgba >> 24) & 0xFF; + tempcol.g = (rgba >> 16) & 0xFF; + tempcol.b = (rgba >> 8) & 0xFF; + tempcol.a = rgba & 0xFF; return tempcol; } @@ -1646,14 +1666,22 @@ void GFX_blitSurfaceColor(SDL_Surface *src, SDL_Rect *src_rect, SDL_Surface *dst else if (asset_color == THEME_COLOR7) asset_color = THEME_COLOR7_255; + SDL_Color tint = uintToColour(asset_color); + SDL_Color restore; + Uint8 restore_a; + SDL_BlendMode restore_blend; SDL_GetSurfaceColorMod(src, &restore.r, &restore.g, &restore.b); - SDL_SetSurfaceColorMod(src, - (asset_color >> 16) & 0xFF, - (asset_color >> 8) & 0xFF, - asset_color & 0xFF); + SDL_GetSurfaceAlphaMod(src, &restore_a); + SDL_GetSurfaceBlendMode(src, &restore_blend); + + SDL_SetSurfaceColorMod(src, tint.r, tint.g, tint.b); + SDL_SetSurfaceAlphaMod(src, tint.a); + SDL_SetSurfaceBlendMode(src, SDL_BLENDMODE_BLEND); SDL_BlitSurface(src, src_rect, dst, dst_rect); SDL_SetSurfaceColorMod(src, restore.r, restore.g, restore.b); + SDL_SetSurfaceAlphaMod(src, restore_a); + SDL_SetSurfaceBlendMode(src, restore_blend); } else { @@ -1661,6 +1689,48 @@ void GFX_blitSurfaceColor(SDL_Surface *src, SDL_Rect *src_rect, SDL_Surface *dst } } +static void GFX_blitSurfaceColorScaled(SDL_Surface *src, SDL_Rect *src_rect, SDL_Surface *dst, SDL_Rect *dst_rect, uint32_t asset_color) +{ + if (asset_color != RGB_WHITE) + { + if (asset_color == THEME_COLOR1) + asset_color = THEME_COLOR1_255; + else if (asset_color == THEME_COLOR2) + asset_color = THEME_COLOR2_255; + else if (asset_color == THEME_COLOR3) + asset_color = THEME_COLOR3_255; + else if (asset_color == THEME_COLOR4) + asset_color = THEME_COLOR4_255; + else if (asset_color == THEME_COLOR5) + asset_color = THEME_COLOR5_255; + else if (asset_color == THEME_COLOR6) + asset_color = THEME_COLOR6_255; + else if (asset_color == THEME_COLOR7) + asset_color = THEME_COLOR7_255; + + SDL_Color tint = uintToColour(asset_color); + + SDL_Color restore; + Uint8 restore_a; + SDL_BlendMode restore_blend; + SDL_GetSurfaceColorMod(src, &restore.r, &restore.g, &restore.b); + SDL_GetSurfaceAlphaMod(src, &restore_a); + SDL_GetSurfaceBlendMode(src, &restore_blend); + + SDL_SetSurfaceColorMod(src, tint.r, tint.g, tint.b); + SDL_SetSurfaceAlphaMod(src, tint.a); + SDL_SetSurfaceBlendMode(src, SDL_BLENDMODE_BLEND); + SDL_BlitScaled(src, src_rect, dst, dst_rect); + SDL_SetSurfaceColorMod(src, restore.r, restore.g, restore.b); + SDL_SetSurfaceAlphaMod(src, restore_a); + SDL_SetSurfaceBlendMode(src, restore_blend); + } + else + { + SDL_BlitScaled(src, src_rect, dst, dst_rect); + } +} + void GFX_blitAssetColor(int asset, SDL_Rect *src_rect, SDL_Surface *dst, SDL_Rect *dst_rect, uint32_t asset_color) { @@ -1685,6 +1755,47 @@ void GFX_blitAsset(int asset, SDL_Rect *src_rect, SDL_Surface *dst, SDL_Rect *ds { GFX_blitAssetColor(asset, src_rect, dst, dst_rect, RGB_WHITE); } + +static void GFX_fillRectBlend(SDL_Surface *dst, const SDL_Rect *rect, uint32_t mapped_color) +{ + if (!dst || !rect || rect->w <= 0 || rect->h <= 0) + return; + + Uint8 r, g, b, a; + SDL_GetRGBA(mapped_color, dst->format, &r, &g, &b, &a); + + SDL_Surface *tmp = SDL_CreateRGBSurfaceWithFormat(0, rect->w, rect->h, + 32, SDL_PIXELFORMAT_ARGB8888); + if (!tmp) + return; + + SDL_SetSurfaceBlendMode(tmp, SDL_BLENDMODE_BLEND); + SDL_FillRect(tmp, NULL, SDL_MapRGBA(tmp->format, r, g, b, a)); + + SDL_Rect dst_rect = *rect; + SDL_BlitSurface(tmp, NULL, dst, &dst_rect); + SDL_FreeSurface(tmp); +} + +static int GFX_pillRectAsset(int asset) +{ + switch (asset) + { + case ASSET_WHITE_PILL: + return ASSET_WHITE_RECT; + case ASSET_BLACK_PILL: + return ASSET_BLACK_RECT; + case ASSET_DARK_GRAY_PILL: + return ASSET_DARK_GRAY_RECT; + case ASSET_BUTTON: + return ASSET_BUTTON_RECT; + case ASSET_OPTION: + return ASSET_OPTION_RECT; + default: + return -1; + } +} + void GFX_blitPillColor(int asset, SDL_Surface *dst, SDL_Rect *dst_rect, uint32_t asset_color, uint32_t fill_color) { int x = dst_rect->x; @@ -1704,8 +1815,19 @@ void GFX_blitPillColor(int asset, SDL_Surface *dst, SDL_Rect *dst_rect, uint32_t x += r; if (w > 0) { - // SDL_FillRect(dst, &(SDL_Rect){x,y,w,h}, UintMult(fill_color, asset_color)); - SDL_FillRect(dst, &(SDL_Rect){x, y, w, h}, asset_color); + int rect_asset = GFX_pillRectAsset(asset); + if (rect_asset >= 0) + { + uint32_t center_color = (fill_color != RGB_WHITE) ? fill_color : asset_color; + SDL_Rect src_rect = asset_rects[rect_asset]; + SDL_Rect center_dst = {x, y, w, h}; + GFX_blitSurfaceColorScaled(gfx.assets, &src_rect, dst, ¢er_dst, center_color); + } + else + { + // Fallback for non-pill assets that still use this helper. + GFX_fillRectBlend(dst, &(SDL_Rect){x, y, w, h}, asset_color); + } x += w; } GFX_blitAssetColor(asset, &(SDL_Rect){r, 0, r, h}, dst, &(SDL_Rect){x, y}, asset_color); @@ -2216,6 +2338,26 @@ int GFX_blitButtonGroup(char **pairs, int primary, SDL_Surface *dst, int align_r return ow; } +void GFX_blitTopCurtain(SDL_Surface* dst) +{ + // blit a top curtain to the screen, which is a semi-transparent black rectangle at the top of the screen + int opacity = CFG_getGameSwitcherCurtain() * 255 / 100; // convert percentage to 0-255 range + if(opacity <= 0) + return; // no need to draw if fully transparent + SDL_Rect rect = {0, 0, dst->w, SCALE1(PADDING+PILL_SIZE+PADDING)}; + GFX_fillRectBlend(dst, &rect, SDL_MapRGBA(dst->format, 0, 0, 0, opacity)); +} + +void GFX_blitBottomCurtain(SDL_Surface* dst) +{ + // blit a bottom curtain to the screen, which is a semi-transparent black rectangle at the bottom of the screen + int opacity = CFG_getGameSwitcherCurtain() * 255 / 100; // convert percentage to 0-255 range + if(opacity <= 0) + return; // no need to draw if fully transparent + SDL_Rect rect = {0, dst->h - SCALE1(PADDING+PILL_SIZE+PADDING), dst->w, SCALE1(PADDING+PILL_SIZE+PADDING)}; + GFX_fillRectBlend(dst, &rect, SDL_MapRGBA(dst->format, 0, 0, 0, opacity)); +} + #define MAX_TEXT_LINES 16 void GFX_sizeText(TTF_Font *font, const char *str, int leading, int *w, int *h) { diff --git a/workspace/all/common/api.h b/workspace/all/common/api.h index da8e14534..9488c09ca 100644 --- a/workspace/all/common/api.h +++ b/workspace/all/common/api.h @@ -117,8 +117,13 @@ enum { ASSET_WHITE_PILL, ASSET_BLACK_PILL, ASSET_DARK_GRAY_PILL, + ASSET_WHITE_RECT, + ASSET_BLACK_RECT, + ASSET_DARK_GRAY_RECT, ASSET_OPTION, + ASSET_OPTION_RECT, ASSET_BUTTON, + ASSET_BUTTON_RECT, ASSET_PAGE_BG, ASSET_STATE_BG, ASSET_PAGE, @@ -281,7 +286,7 @@ SDL_Surface* GFX_init(int mode); void GFX_setMode(int mode); int GFX_hdmiChanged(void); -SDL_Color /*GFX_*/ uintToColour(uint32_t colour); +SDL_Color /*GFX_*/ uintToColour(uint32_t rgba); #define GFX_clear PLAT_clearVideo // (SDL_Surface* screen) #define GFX_clearAll PLAT_clearAll // (void) @@ -352,6 +357,8 @@ void GFX_blitMessage(TTF_Font* font, char* msg, SDL_Surface* dst, SDL_Rect* dst_ int GFX_blitHardwareGroup(SDL_Surface* dst, int show_setting); void GFX_blitHardwareHints(SDL_Surface* dst, int show_setting); +void GFX_blitTopCurtain(SDL_Surface* dst); +void GFX_blitBottomCurtain(SDL_Surface* dst); typedef enum { INDICATOR_BRIGHTNESS = 1, diff --git a/workspace/all/common/config.c b/workspace/all/common/config.c index ff5af1a62..03dbd303a 100644 --- a/workspace/all/common/config.c +++ b/workspace/all/common/config.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include "defines.h" #include "utils.h" @@ -55,6 +56,7 @@ void CFG_defaults(NextUISettings *cfg) .gameSwitcherScaling = CFG_DEFAULT_GAMESWITCHERSCALING, .defaultView = CFG_DEFAULT_VIEW, .showQuickSwitcherUi = CFG_DEFAULT_SHOWQUICKWITCHERUI, + .gameSwitcherCurtain = CFG_DEFAULT_GAMESWITCHER_CURTAIN, .muteLeds = CFG_DEFAULT_MUTELEDS, @@ -93,12 +95,34 @@ void CFG_defaults(NextUISettings *cfg) .raNotificationDuration = CFG_DEFAULT_RA_NOTIFICATION_DURATION, .raProgressNotificationDuration = CFG_DEFAULT_RA_PROGRESS_NOTIFICATION_DURATION, .raAchievementSortOrder = CFG_DEFAULT_RA_ACHIEVEMENT_SORT_ORDER, - -}; + }; *cfg = defaults; } +static inline uint32_t parseHexColor(const char *hexColor) { + // Accept both legacy RGB (RRGGBB) and RGBA (RRGGBBAA) text formats. + // Decide by input hex digit count, not numeric value. + uint32_t value = HexToUint32_unmapped(hexColor); + + const char *p = hexColor; + while (*p == ' ' || *p == '\t') p++; + if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) + p += 2; + + size_t digits = 0; + while (isxdigit((unsigned char)p[digits])) + digits++; + + if (digits <= 6) { + // Legacy RGB -> packed RGBA with opaque alpha. + return (value << 8) | 0xFF; + } + + // 8+ hex digits are treated as explicit packed RGBA. + return value; +} + void CFG_init(FontLoad_callback_t cb, ColorSet_callback_t ccb) { CFG_defaults(&settings); @@ -134,41 +158,53 @@ void CFG_init(FontLoad_callback_t cb, ColorSet_callback_t ccb) fontLoaded = true; continue; } - if (sscanf(line, "color1=%x", &temp_color) == 1) + if(strncmp(line, "color1=", 7) == 0) { - char hexColor[7]; - snprintf(hexColor, sizeof(hexColor), "%06x", temp_color); - CFG_setColor(1, HexToUint32_unmapped(hexColor)); + char *value = line + 7; + value[strcspn(value, "\n")] = 0; + CFG_setColor(1, parseHexColor(value)); continue; } - if (sscanf(line, "color2=%x", &temp_color) == 1) + if (strncmp(line, "color2=", 7) == 0) { - CFG_setColor(2, temp_color); + char *value = line + 7; + value[strcspn(value, "\n")] = 0; + CFG_setColor(2, parseHexColor(value)); continue; } - if (sscanf(line, "color3=%x", &temp_color) == 1) + if (strncmp(line, "color3=", 7) == 0) { - CFG_setColor(3, temp_color); + char *value = line + 7; + value[strcspn(value, "\n")] = 0; + CFG_setColor(3, parseHexColor(value)); continue; } - if (sscanf(line, "color4=%x", &temp_color) == 1) + if (strncmp(line, "color4=", 7) == 0) { - CFG_setColor(4, temp_color); + char *value = line + 7; + value[strcspn(value, "\n")] = 0; + CFG_setColor(4, parseHexColor(value)); continue; } - if (sscanf(line, "color5=%x", &temp_color) == 1) + if (strncmp(line, "color5=", 7) == 0) { - CFG_setColor(5, temp_color); + char *value = line + 7; + value[strcspn(value, "\n")] = 0; + CFG_setColor(5, parseHexColor(value)); continue; } - if (sscanf(line, "color6=%x", &temp_color) == 1) + if (strncmp(line, "color6=", 7) == 0) { - CFG_setColor(6, temp_color); + char *value = line + 7; + value[strcspn(value, "\n")] = 0; + CFG_setColor(6, parseHexColor(value)); continue; } - if (sscanf(line, "color7=%x", &temp_color) == 1) + if (strncmp(line, "color7=", 7) == 0) { - CFG_setColor(7, temp_color); + char *value = line + 7; + value[strcspn(value, "\n")] = 0; + CFG_setColor(7, parseHexColor(value)); continue; } if (sscanf(line, "radius=%i", &temp_value) == 1) @@ -420,6 +456,11 @@ void CFG_init(FontLoad_callback_t cb, ColorSet_callback_t ccb) CFG_setFontStyle(temp_value); continue; } + if (sscanf(line, "gameSwitcherCurtain=%i", &temp_value) == 1) + { + CFG_setGameSwitcherCurtain(temp_value); + continue; + } } fclose(file); } @@ -1105,6 +1146,17 @@ void CFG_setFontStyle(int style) CFG_setFontFile(CFG_getFontFile()); } +int CFG_getGameSwitcherCurtain(void) +{ + return settings.gameSwitcherCurtain; +} + +void CFG_setGameSwitcherCurtain(int opacity) +{ + settings.gameSwitcherCurtain = clamp(opacity, 0, 100); + CFG_sync(); +} + void CFG_get(const char *key, char *value) { if (strcmp(key, "font") == 0) @@ -1118,31 +1170,31 @@ void CFG_get(const char *key, char *value) } else if (strcmp(key, "color1") == 0) { - sprintf(value, "\"0x%06X\"", CFG_getColor(COLOR_MAIN)); + sprintf(value, "\"0x%08X\"", CFG_getColor(COLOR_MAIN)); } else if (strcmp(key, "color2") == 0) { - sprintf(value, "\"0x%06X\"", CFG_getColor(COLOR_ACCENT)); + sprintf(value, "\"0x%08X\"", CFG_getColor(COLOR_ACCENT)); } else if (strcmp(key, "color3") == 0) { - sprintf(value, "\"0x%06X\"", CFG_getColor(COLOR_ACCENT2)); + sprintf(value, "\"0x%08X\"", CFG_getColor(COLOR_ACCENT2)); } else if (strcmp(key, "color4") == 0) { - sprintf(value, "\"0x%06X\"", CFG_getColor(COLOR_LIST_TEXT)); + sprintf(value, "\"0x%08X\"", CFG_getColor(COLOR_LIST_TEXT)); } else if (strcmp(key, "color5") == 0) { - sprintf(value, "\"0x%06X\"", CFG_getColor(COLOR_LIST_TEXT_SELECTED)); + sprintf(value, "\"0x%08X\"", CFG_getColor(COLOR_LIST_TEXT_SELECTED)); } else if (strcmp(key, "color6") == 0) { - sprintf(value, "\"0x%06X\"", CFG_getColor(COLOR_HINT)); + sprintf(value, "\"0x%08X\"", CFG_getColor(COLOR_HINT)); } else if (strcmp(key, "color7") == 0) { - sprintf(value, "\"0x%06X\"", CFG_getColor(COLOR_BACKGROUND)); + sprintf(value, "\"0x%08X\"", CFG_getColor(COLOR_BACKGROUND)); } else if (strcmp(key, "radius") == 0) { @@ -1328,6 +1380,10 @@ void CFG_get(const char *key, char *value) { sprintf(value, "%i", CFG_getFontStyle()); } + else if (strcmp(key, "gameSwitcherCurtain") == 0) + { + sprintf(value, "%i", CFG_getGameSwitcherCurtain()); + } // meta, not a real setting else if (strcmp(key, "fontpath") == 0) @@ -1367,13 +1423,13 @@ void CFG_sync(void) fprintf(file, "font=0\n"); else fprintf(file, "font=%s\n", settings.fontFile); - fprintf(file, "color1=0x%06X\n", settings.color1_255); - fprintf(file, "color2=0x%06X\n", settings.color2_255); - fprintf(file, "color3=0x%06X\n", settings.color3_255); - fprintf(file, "color4=0x%06X\n", settings.color4_255); - fprintf(file, "color5=0x%06X\n", settings.color5_255); - fprintf(file, "color6=0x%06X\n", settings.color6_255); - fprintf(file, "color7=0x%06X\n", settings.color7_255); + fprintf(file, "color1=0x%08X\n", settings.color1_255); + fprintf(file, "color2=0x%08X\n", settings.color2_255); + fprintf(file, "color3=0x%08X\n", settings.color3_255); + fprintf(file, "color4=0x%08X\n", settings.color4_255); + fprintf(file, "color5=0x%08X\n", settings.color5_255); + fprintf(file, "color6=0x%08X\n", settings.color6_255); + fprintf(file, "color7=0x%08X\n", settings.color7_255); fprintf(file, "radius=%i\n", settings.thumbRadius); fprintf(file, "showclock=%i\n", settings.showClock); fprintf(file, "clock24h=%i\n", settings.clock24h); @@ -1422,6 +1478,7 @@ void CFG_sync(void) fprintf(file, "raProgressNotificationDuration=%i\n", settings.raProgressNotificationDuration); fprintf(file, "raAchievementSortOrder=%i\n", settings.raAchievementSortOrder); fprintf(file, "fontStyle=%i\n", settings.fontStyle); + fprintf(file, "gameSwitcherCurtain=%i\n", settings.gameSwitcherCurtain); fclose(file); } @@ -1434,13 +1491,13 @@ void CFG_print(void) printf("\t\"font\": 0,\n"); else printf("\t\"font\": 1,\n"); - printf("\t\"color1\": \"0x%06X\",\n", settings.color1_255); - printf("\t\"color2\": \"0x%06X\",\n", settings.color2_255); - printf("\t\"color3\": \"0x%06X\",\n", settings.color3_255); - printf("\t\"color4\": \"0x%06X\",\n", settings.color4_255); - printf("\t\"color5\": \"0x%06X\",\n", settings.color5_255); - printf("\t\"color6\": \"0x%06X\",\n", settings.color6_255); - printf("\t\"color7\": \"0x%06X\",\n", settings.color7_255); + printf("\t\"color1\": \"0x%08X\",\n", settings.color1_255); + printf("\t\"color2\": \"0x%08X\",\n", settings.color2_255); + printf("\t\"color3\": \"0x%08X\",\n", settings.color3_255); + printf("\t\"color4\": \"0x%08X\",\n", settings.color4_255); + printf("\t\"color5\": \"0x%08X\",\n", settings.color5_255); + printf("\t\"color6\": \"0x%08X\",\n", settings.color6_255); + printf("\t\"color7\": \"0x%08X\",\n", settings.color7_255); printf("\t\"radius\": %i,\n", settings.thumbRadius); printf("\t\"showclock\": %i,\n", settings.showClock); printf("\t\"clock24h\": %i,\n", settings.clock24h); @@ -1488,6 +1545,7 @@ void CFG_print(void) printf("\t\"raProgressNotificationDuration\": %i,\n", settings.raProgressNotificationDuration); printf("\t\"raAchievementSortOrder\": %i,\n", settings.raAchievementSortOrder); printf("\t\"fontStyle\": %i,\n", settings.fontStyle); + printf("\t\"gameSwitcherCurtain\": %i,\n", settings.gameSwitcherCurtain); // meta, not a real setting printf("\t\"fontpath\": \"%s/%s\"\n", RES_PATH, CFG_getFontFile()); diff --git a/workspace/all/common/config.h b/workspace/all/common/config.h index d2c56b94b..24708756d 100644 --- a/workspace/all/common/config.h +++ b/workspace/all/common/config.h @@ -96,6 +96,7 @@ typedef struct uint32_t color7_255; // not screen mapped int thumbRadius; int gameSwitcherScaling; // enum + int gameSwitcherCurtain; double gameArtWidth; // [0,1] -> 0-100% of screen width // font loading/unloading callback @@ -173,13 +174,13 @@ typedef struct #define CFG_DEFAULT_FONT_FILE "font1.ttf" // Next #define CFG_DEFAULT_FONT_STYLE 0x01 // TTF_STYLE_BOLD (MinUI default) -#define CFG_DEFAULT_COLOR1 0xffffffU -#define CFG_DEFAULT_COLOR2 0x9b2257U -#define CFG_DEFAULT_COLOR3 0x1e2329U -#define CFG_DEFAULT_COLOR4 0xffffffU -#define CFG_DEFAULT_COLOR5 0x000000U -#define CFG_DEFAULT_COLOR6 0xffffffU -#define CFG_DEFAULT_COLOR7 0x000000U +#define CFG_DEFAULT_COLOR1 0xffffffffU +#define CFG_DEFAULT_COLOR2 0x9b2257ffU +#define CFG_DEFAULT_COLOR3 0x1e2329ffU +#define CFG_DEFAULT_COLOR4 0xffffffffU +#define CFG_DEFAULT_COLOR5 0x000000ffU +#define CFG_DEFAULT_COLOR6 0xffffffffU +#define CFG_DEFAULT_COLOR7 0x000000ffU #define CFG_DEFAULT_COLOR_MAIN CFG_DEFAULT_COLOR1 #define CFG_DEFAULT_COLOR_ACCENT CFG_DEFAULT_COLOR2 #define CFG_DEFAULT_COLOR_ACCENT2 CFG_DEFAULT_COLOR3 @@ -218,6 +219,7 @@ typedef struct #define CFG_DEFAULT_BLUETOOTH_MAXRATE 48000 #define CFG_DEFAULT_NTP false #define CFG_DEFAULT_TIMEZONE 320 // Europe/Berlin +#define CFG_DEFAULT_GAMESWITCHER_CURTAIN 0 // Notification defaults #define CFG_DEFAULT_NOTIFY_MANUAL_SAVE true @@ -257,7 +259,7 @@ void CFG_setFontFile(const char* filename); // The font style to use for the UI font. int CFG_getFontStyle(void); void CFG_setFontStyle(int style); -// The colors to use for the UI. These are 0xRRGGBB values. +// The colors to use for the UI. These are packed 0xRRGGBBAA values. // 0 - Color1 (primary hint/asset colour) // 1 - Color2 (accent colour) // 2 - Color3 (secondary accent colour @@ -362,6 +364,9 @@ void CFG_setNTP(bool on); // Current timezone index in tz database int CFG_getCurrentTimezone(void); void CFG_setCurrentTimezone(int index); +// Show/hide curtain on the game switcher screen (0-100% opacity) +int CFG_getGameSwitcherCurtain(void); +void CFG_setGameSwitcherCurtain(int opacity); // Notification settings bool CFG_getNotifyManualSave(void); diff --git a/workspace/all/nextui/nextui.c b/workspace/all/nextui/nextui.c index 69b66ba9b..23d9e7323 100644 --- a/workspace/all/nextui/nextui.c +++ b/workspace/all/nextui/nextui.c @@ -2616,6 +2616,11 @@ int main (int argc, char *argv[]) { } GFX_clear(screen); + if(CFG_getGameSwitcherCurtain() > 0 && currentScreen == SCREEN_GAMESWITCHER) { + GFX_blitTopCurtain(screen); + GFX_blitBottomCurtain(screen); + } + int ow = GFX_blitHardwareGroup(screen, show_setting); if (currentScreen == SCREEN_QUICKMENU) { if(lastScreen != SCREEN_QUICKMENU) { diff --git a/workspace/all/settings/colorpickermenu.cpp b/workspace/all/settings/colorpickermenu.cpp index 8d5e7f1ec..33646a79f 100644 --- a/workspace/all/settings/colorpickermenu.cpp +++ b/workspace/all/settings/colorpickermenu.cpp @@ -2,13 +2,15 @@ #include -static constexpr int NUM_SLIDERS = 3; +static constexpr int NUM_SLIDERS = 4; -static void decodeColor(uint32_t c, int &r, int &g, int &b) +static void decodeColor(uint32_t c, int &r, int &g, int &b, int &a) { - r = (c >> 16) & 0xFF; - g = (c >> 8) & 0xFF; - b = c & 0xFF; + auto col = uintToColour(c); + a = col.a; + r = col.r; + g = col.g; + b = col.b; } /////////////////////////////////////////////////////////// @@ -20,12 +22,12 @@ ColorPickerMenu::ColorPickerMenu(uint32_t initialColor, ValueSetCallback on_set, presets(std::move(presets)), label_(std::move(label)), originalColor_(initialColor), selected(0) { - decodeColor(initialColor, r, g, b); + decodeColor(initialColor, r, g, b, a); } void ColorPickerMenu::reset(uint32_t color, std::vector newPresets, std::string label) { - decodeColor(color, r, g, b); + decodeColor(color, r, g, b, a); originalColor_ = color; selected = 0; presets = std::move(newPresets); @@ -34,7 +36,8 @@ void ColorPickerMenu::reset(uint32_t color, std::vector newPresets, uint32_t ColorPickerMenu::currentColor() const { - return ((uint32_t)r << 16) | ((uint32_t)g << 8) | (uint32_t)b; + // in rgba format + return ((r & 0xFF) << 24) | ((g & 0xFF) << 16) | ((b & 0xFF) << 8) | (a & 0xFF); } void ColorPickerMenu::applyColor() @@ -67,7 +70,7 @@ InputReactionHint ColorPickerMenu::handleInput(int &dirty, int &quit) } else if (PAD_justPressed(BTN_B)) { - decodeColor(originalColor_, r, g, b); + decodeColor(originalColor_, r, g, b, a); applyColor(); dirty = 1; quit = 1; @@ -83,7 +86,7 @@ InputReactionHint ColorPickerMenu::handleInput(int &dirty, int &quit) if (selected < NUM_SLIDERS) { - int *channels[] = {&r, &g, &b}; + int *channels[] = {&r, &g, &b, &a}; int *channel = channels[selected]; if (PAD_justRepeated(BTN_LEFT)) { @@ -120,7 +123,7 @@ InputReactionHint ColorPickerMenu::handleInput(int &dirty, int &quit) if (PAD_justPressed(BTN_X) && presetIdx < (int)presets.size()) { const auto &preset = presets[presetIdx]; - decodeColor(preset.color, r, g, b); + decodeColor(preset.color, r, g, b, a); applyColor(); selected = 0; dirty = 1; @@ -167,19 +170,64 @@ static void drawRoundedRect(SDL_Surface *surface, const SDL_Rect &rect, int radi } } +static void drawRoundedAlphaRect(SDL_Surface *surface, const SDL_Rect &rect, int radius, + uint32_t outer, uint32_t middle, uint32_t fill) +{ + if (rect.w <= 0 || rect.h <= 0) return; + + SDL_Surface *tmp = SDL_CreateRGBSurfaceWithFormat(0, rect.w, rect.h, + 32, SDL_PIXELFORMAT_ARGB8888); + if (!tmp) return; + + SDL_SetSurfaceBlendMode(tmp, SDL_BLENDMODE_BLEND); + SDL_FillRect(tmp, nullptr, SDL_MapRGBA(tmp->format, 0, 0, 0, 0)); + + auto remap = [&](uint32_t c) -> uint32_t { + uint8_t rr, gg, bb, aa; + SDL_GetRGBA(c, surface->format, &rr, &gg, &bb, &aa); + return SDL_MapRGBA(tmp->format, rr, gg, bb, aa); + }; + + SDL_Rect r0 = {0, 0, rect.w, rect.h}; + drawSolidRoundedRect(tmp, r0, radius, remap(outer)); + if (rect.w > 2 && rect.h > 2) + { + SDL_Rect r1 = {1, 1, rect.w - 2, rect.h - 2}; + drawSolidRoundedRect(tmp, r1, std::max(0, radius - 1), remap(middle)); + } + if (rect.w > 4 && rect.h > 4) + { + SDL_Rect r2 = {2, 2, rect.w - 4, rect.h - 4}; + drawSolidRoundedRect(tmp, r2, std::max(0, radius - 2), remap(fill)); + } + + SDL_Rect dst = rect; + SDL_BlitSurface(tmp, nullptr, surface, &dst); + SDL_FreeSurface(tmp); +} + static void drawGradientCapsule(SDL_Surface *surface, const SDL_Rect &bar, - int r, int g, int b, int channel) + int r, int g, int b, int a, int channel) { if (bar.w <= 0 || bar.h <= 0) return; const int R = bar.h / 2; + // SDL_FillRect does not alpha blend into destination surfaces. Build the + // gradient into an ARGB temp surface, then alpha-blit it onto destination. + SDL_Surface *grad = SDL_CreateRGBSurfaceWithFormat(0, bar.w, bar.h, + 32, SDL_PIXELFORMAT_ARGB8888); + if (!grad) return; + SDL_SetSurfaceBlendMode(grad, SDL_BLENDMODE_BLEND); + SDL_FillRect(grad, nullptr, SDL_MapRGBA(grad->format, 0, 0, 0, 0)); + for (int x = 0; x < bar.w; x++) { int ch_val = (bar.w > 1) ? (int)((float)x / (bar.w - 1) * 255.0f) : 128; uint8_t cr = (channel == 0) ? (uint8_t)ch_val : (uint8_t)r; uint8_t cg = (channel == 1) ? (uint8_t)ch_val : (uint8_t)g; uint8_t cb = (channel == 2) ? (uint8_t)ch_val : (uint8_t)b; - uint32_t col = SDL_MapRGB(surface->format, cr, cg, cb); + uint8_t ca = (channel == 3) ? (uint8_t)ch_val : (uint8_t)a; + uint32_t col = SDL_MapRGBA(grad->format, cr, cg, cb, ca); int y_inset = 0; if (R > 0) { @@ -197,9 +245,13 @@ static void drawGradientCapsule(SDL_Surface *surface, const SDL_Rect &bar, int col_h = bar.h - 2 * y_inset; if (col_h <= 0) continue; - SDL_Rect col_rect = {bar.x + x, bar.y + y_inset, 1, col_h}; - SDL_FillRect(surface, &col_rect, col); + SDL_Rect col_rect = {x, y_inset, 1, col_h}; + SDL_FillRect(grad, &col_rect, col); } + + SDL_Rect dst = bar; + SDL_BlitSurface(grad, nullptr, surface, &dst); + SDL_FreeSurface(grad); } void ColorPickerMenu::drawSlider(SDL_Surface *surface, const SDL_Rect &row, @@ -213,16 +265,17 @@ void ColorPickerMenu::drawSlider(SDL_Surface *surface, const SDL_Rect &row, // Fixed-width slots so all sliders align regardless of rendered glyph widths int label_fixed_w; { - int wr, wg, wb; + int wr, wg, wb, wa; TTF_SizeUTF8(font.small, "R", &wr, nullptr); TTF_SizeUTF8(font.small, "G", &wg, nullptr); TTF_SizeUTF8(font.small, "B", &wb, nullptr); - label_fixed_w = std::max({wr, wg, wb}); + TTF_SizeUTF8(font.small, "A", &wa, nullptr); + label_fixed_w = std::max({wr, wg, wb, wa}); } int hex_fixed_w; TTF_SizeUTF8(font.tiny, "00", &hex_fixed_w, nullptr); - // Channel label ("R", "G", "B") — centered in fixed-width slot + // Channel label ("R", "G", "B", "A") — centered in fixed-width slot SDL_Surface *label_surf = TTF_RenderUTF8_Blended(font.small, label, text_color); int label_x = row.x + SCALE1(OPTION_PADDING) + (label_fixed_w - label_surf->w) / 2; SDL_BlitSurfaceCPP(label_surf, {}, surface, @@ -230,7 +283,7 @@ void ColorPickerMenu::drawSlider(SDL_Surface *surface, const SDL_Rect &row, SDL_FreeSurface(label_surf); // Hex value right-aligned in fixed-width slot - char hex_str[3]; + char hex_str[4]; snprintf(hex_str, sizeof(hex_str), "%02X", value); SDL_Surface *hex_surf = TTF_RenderUTF8_Blended(font.tiny, hex_str, text_color); int hex_slot_x = row.x + row.w - SCALE1(OPTION_PADDING) - hex_fixed_w; @@ -247,17 +300,21 @@ void ColorPickerMenu::drawSlider(SDL_Surface *surface, const SDL_Rect &row, if (bar_w > 0) { - uint32_t white = SDL_MapRGB(surface->format, 255, 255, 255); - uint32_t black = SDL_MapRGB(surface->format, 0, 0, 0); + uint32_t white = SDL_MapRGBA(surface->format, 255, 255, 255, 255); + uint32_t black = SDL_MapRGBA(surface->format, 0, 0, 0, 255); // Ring inset within bar bounds: 1px black outer, 1px white inner, gradient fill drawSolidRoundedRect(surface, {bar_x, bar_y, bar_w, bar_h}, bar_h / 2, black); if (bar_w > 2 && bar_h > 2) drawSolidRoundedRect(surface, {bar_x + 1, bar_y + 1, bar_w - 2, bar_h - 2}, (bar_h - 2) / 2, white); - if (bar_w > 4 && bar_h > 4) + if (bar_w > 4 && bar_h > 4) { + // inner section is filled with background color, so we can blend + drawSolidRoundedRect(surface, {bar_x + 2, bar_y + 2, bar_w - 4, bar_h - 4}, + (bar_h - 4) / 2, THEME_COLOR7); drawGradientCapsule(surface, {bar_x + 2, bar_y + 2, bar_w - 4, bar_h - 4}, - this->r, this->g, this->b, channel); + this->r, this->g, this->b, this->a, channel); + } // Circle thumb indicator const int circ_d = bar_h + SCALE1(2); @@ -305,9 +362,9 @@ void ColorPickerMenu::drawPreset(SDL_Surface *surface, const SDL_Rect &row, SDL_Color text_color = is_selected ? uintToColour(THEME_COLOR5_255) : uintToColour(THEME_COLOR4_255); - // Hex value "#RRGGBB" - char hex_str[8]; - snprintf(hex_str, sizeof(hex_str), "#%06X", preset.color); + // Hex value "#RRGGBBAA" + char hex_str[9]; + snprintf(hex_str, sizeof(hex_str), "#%08X", preset.color); SDL_Surface *hex_surf = TTF_RenderUTF8_Blended(font.tiny, hex_str, text_color); int hex_x = sq_rect.x + sq + SCALE1(OPTION_PADDING / 2 + 2); SDL_BlitSurfaceCPP(hex_surf, {}, surface, @@ -359,13 +416,13 @@ void ColorPickerMenu::drawCustom(SDL_Surface *surface, const SDL_Rect &dst, cons const int SLIDER_AREA_W = dst.w - PREVIEW_SIZE - SCALE1(PADDING); const int PREVIEW_RADIUS = SCALE1(4); - uint32_t white = SDL_MapRGB(surface->format, 255, 255, 255); - uint32_t black = SDL_MapRGB(surface->format, 0, 0, 0); - uint32_t col_mapped = SDL_MapRGB(surface->format, r, g, b); + uint32_t white = SDL_MapRGBA(surface->format, 255, 255, 255, 255); + uint32_t black = SDL_MapRGBA(surface->format, 0, 0, 0, 255); + uint32_t col_mapped = SDL_MapRGBA(surface->format, r, g, b, a); // R, G, B slider rows - const char *channel_labels[] = {"R", "G", "B"}; - int channel_values[] = {r, g, b}; + const char *channel_labels[] = {"R", "G", "B", "A"}; + int channel_values[] = {r, g, b, a}; for (int i = 0; i < NUM_SLIDERS; i++) { SDL_Rect row = {dst.x, dst.y + TOP_OFFSET + SCALE1(i * BUTTON_SIZE), SLIDER_AREA_W, SCALE1(BUTTON_SIZE)}; @@ -379,7 +436,7 @@ void ColorPickerMenu::drawCustom(SDL_Surface *surface, const SDL_Rect &dst, cons PREVIEW_SIZE, PREVIEW_SIZE }; - drawRoundedRect(surface, preview, PREVIEW_RADIUS, black, white, col_mapped); + drawRoundedAlphaRect(surface, preview, PREVIEW_RADIUS, black, white, col_mapped); // Preset rows below the sliders for (int i = 0; i < (int)presets.size(); i++) @@ -390,6 +447,8 @@ void ColorPickerMenu::drawCustom(SDL_Surface *surface, const SDL_Rect &dst, cons dst.w, SCALE1(BUTTON_SIZE) }; + if(row.y + row.h > dst.y + dst.h - SCALE1(BUTTON_SIZE)) + break; // don't draw outside the menu area drawPreset(surface, row, presets[i], selected == NUM_SLIDERS + i); } } diff --git a/workspace/all/settings/colorpickermenu.hpp b/workspace/all/settings/colorpickermenu.hpp index e11d388ca..5e183cd11 100644 --- a/workspace/all/settings/colorpickermenu.hpp +++ b/workspace/all/settings/colorpickermenu.hpp @@ -9,7 +9,7 @@ struct ColorPreset { class ColorPickerMenu : public MenuList { - int r, g, b; + int r, g, b, a; int selected; ValueSetCallback on_set; std::vector presets; diff --git a/workspace/all/settings/menu.cpp b/workspace/all/settings/menu.cpp index ab5915b03..b17a0cabb 100644 --- a/workspace/all/settings/menu.cpp +++ b/workspace/all/settings/menu.cpp @@ -684,18 +684,19 @@ void MenuList::drawFixed(SDL_Surface *surface, const SDL_Rect &dst, const SDL_Re // TODO: expose API functions that do the same namespace { - static inline void rgb_unpack(uint32_t col, int *r, int *g, int *b) + static inline void rgba_unpack(uint32_t col, int *r, int *g, int *b, int *a) { - *r = (col >> 16) & 0xff; - *g = (col >> 8) & 0xff; - *b = col & 0xff; + *r = (col >> 24) & 0xff; + *g = (col >> 16) & 0xff; + *b = (col >> 8) & 0xff; + *a = col & 0xff; } static inline uint32_t mapUint(SDL_Surface *surface, uint32_t col) { - int r, g, b; - rgb_unpack(col, &r, &g, &b); - return SDL_MapRGB(surface->format, r, g, b); + int r, g, b, a; + rgba_unpack(col, &r, &g, &b, &a); + return SDL_MapRGBA(surface->format, r, g, b, a); } } @@ -740,7 +741,7 @@ void MenuList::drawFixedItem(SDL_Surface *surface, const SDL_Rect &dst, const Ab // Rerender the label from the live hex value SDL_FreeSurface(text); char hexLabel[12]; - snprintf(hexLabel, sizeof(hexLabel), "0x%06X", rawColor); + snprintf(hexLabel, sizeof(hexLabel), "0x%08X", rawColor); text = TTF_RenderUTF8_Blended(font.tiny, hexLabel, text_color_value); SDL_BlitSurfaceCPP(text, {}, surface, {dst.x + mw - text->w - SCALE1(OPTION_PADDING + COLOR_PADDING + FONT_TINY), dst.y + ((dst.h - text->h) / 2)}); } diff --git a/workspace/all/settings/settings.cpp b/workspace/all/settings/settings.cpp index f40153e1c..c443e5c0c 100644 --- a/workspace/all/settings/settings.cpp +++ b/workspace/all/settings/settings.cpp @@ -150,6 +150,10 @@ static const std::vector progress_duration_labels = {"Off", "1s", " static const std::vector transition_mode_values = {(int)TRANSITION_OFF, (int)TRANSITION_SNAPPY, (int)TRANSITION_COMFY}; static const std::vector transition_mode_labels = {"Off", "Snappy", "Comfy"}; +// Game switcher curtain opacity options (0-100) +static const std::vector curtain_opacity_values = {0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100}; +static const std::vector curtain_opacity_labels = {"Off", "10%", "20%", "30%", "40%", "50%", "60%", "70%", "80%", "90%", "100%"}; + // RetroAchievements sort order options static const std::vector ra_sort_values = { (int)RA_SORT_UNLOCKED_FIRST, @@ -181,7 +185,7 @@ static const std::vector ra_sort_labels = { namespace { struct ColorDef { int id; const char *name; const char *desc; uint32_t defaultColor; }; static const ColorDef g_colorDefs[] = { - {1, "Main Color", "The color used to render main UI elements.", CFG_DEFAULT_COLOR1}, + {1, "Main Color", "The color used to render main UI elements.", CFG_DEFAULT_COLOR1}, {2, "Primary Accent Color", "The color used to highlight important things in the user interface.", CFG_DEFAULT_COLOR2}, {3, "Secondary Accent Color", "A secondary highlight color.", CFG_DEFAULT_COLOR3}, {6, "Hint info Color", "Color for button hints and info", CFG_DEFAULT_COLOR6}, @@ -375,7 +379,7 @@ int main(int argc, char *argv[]) return [id, defaultColor]() { CFG_setColor(id, defaultColor); }; }; - // Pre-create one RGB picker per color setting (reused across opens) + // Pre-create one RGBA picker per color setting (reused across opens) std::vector> pickers; pickers.reserve(std::size(g_colorDefs)); for (const auto &def : g_colorDefs) @@ -460,6 +464,10 @@ int main(int argc, char *argv[]) []() -> std::any{ return CFG_getShowQuickswitcherUI(); }, [](const std::any &value){ CFG_setShowQuickswitcherUI(std::any_cast(value)); }, []() { CFG_setShowQuickswitcherUI(CFG_DEFAULT_SHOWQUICKWITCHERUI);}}); + appearanceItems.push_back(new MenuItem{ListItemType::Generic, "Game switcher curtain opacity", "Show/hide curtain overlay. Helps UI elements to \nstand out when using transparent backgrounds.", curtain_opacity_values, curtain_opacity_labels, + []() -> std::any{ return CFG_getGameSwitcherCurtain(); }, + [](const std::any &value){ CFG_setGameSwitcherCurtain(std::any_cast(value)); }, + []() { CFG_setGameSwitcherCurtain(CFG_DEFAULT_GAMESWITCHER_CURTAIN);}}); // not needed anymore // new MenuItem{ListItemType::Generic, "Game switcher scaling", "The scaling algorithm used to display the savegame image.", scaling, scaling_strings, []() -> std::any // { return CFG_getGameSwitcherScaling(); }, @@ -1092,7 +1100,7 @@ int main(int argc, char *argv[]) SDL_BlitSurface(bgbmp, NULL, ctx.screen, &image_rect); } else { uint32_t bgc = CFG_getColor(COLOR_BACKGROUND); - SDL_FillRect(ctx.screen, NULL, SDL_MapRGB(ctx.screen->format, (bgc >> 16) & 0xFF, (bgc >> 8) & 0xFF, bgc & 0xFF)); + SDL_FillRect(ctx.screen, NULL, SDL_MapRGBA(ctx.screen->format, (bgc >> 24) & 0xFF, (bgc >> 16) & 0xFF, (bgc >> 8) & 0xFF, bgc & 0xFF)); } int ow = 0; From efaf2fb6dea7756cf5b0c1b901745b30de64cb33 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Wed, 1 Jul 2026 10:12:14 +0200 Subject: [PATCH 02/77] build: link the core stuff through g++ so we can start adding C++ Reworked the nextui and minarch makefiles to build objects per-file and link with g++, which is what lets us mix C and C++ from here on. C files stay on gnu99, C++ files get gnu++20, and settings moves up to gnu++20 too. No behavior change yet - this just clears the way to convert files to C++ one at a time. --- workspace/all/minarch/makefile | 52 ++++++++++++++++++++++++++------- workspace/all/nextui/makefile | 45 +++++++++++++++++++++++----- workspace/all/settings/makefile | 2 +- 3 files changed, 79 insertions(+), 20 deletions(-) diff --git a/workspace/all/minarch/makefile b/workspace/all/minarch/makefile index ae10f2529..206c10b2e 100644 --- a/workspace/all/minarch/makefile +++ b/workspace/all/minarch/makefile @@ -22,20 +22,30 @@ SDL?=SDL TARGET = minarch PRODUCT= build/$(PLATFORM)/$(TARGET).elf INCDIR = -I. -I./libretro-common/include/ -I../common/ -I../../$(PLATFORM)/platform/ -SOURCE = $(TARGET).c ma_cheats.c ma_rewind.c ma_audio.c ma_input.c \ + +# C and C++ translation units are listed separately. C files compile as C; +# C++ files compile as C++; everything links through g++ so the two can mix +# as modules are migrated to C++ incrementally. +CSOURCE = $(TARGET).c ma_cheats.c ma_rewind.c ma_audio.c ma_input.c \ ma_options.c ma_frontend_opts.c ma_saves.c ma_video.c ma_core.c ma_game.c ma_environment.c ma_config.c ma_menu.c ma_runframe.c \ ../common/scaler.c ../common/utils.c ../common/config.c ../common/api.c \ ../common/notification.c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = # RA support ifneq (,$(filter $(PLATFORM),tg5040 tg5050 my355 desktop)) # RA source files -SOURCE += ../common/http.c ../common/ra_badges.c ../common/ra_offline.c ../common/ra_sync.c ../common/ra_event_queue.c ra_integration.c chd_reader.c +CSOURCE += ../common/http.c ../common/ra_badges.c ../common/ra_offline.c ../common/ra_sync.c ../common/ra_event_queue.c ra_integration.c chd_reader.c endif -CC = $(CROSS_COMPILE)gcc +CC = $(CROSS_COMPILE)gcc +CXX = $(CROSS_COMPILE)g++ CFLAGS += $(OPT) -CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" -std=gnu99 +CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" +# CXXFLAGS inherits the platform CFLAGS (SDL/GL/PREFIX include paths) before the +# C-only -std is appended, so C++ TUs get the same include/define environment. +CXXFLAGS += $(CFLAGS) -std=gnu++20 +CFLAGS += -std=gnu99 LDFLAGS += -lmsettings -lsamplerate ifeq ($(PROFILE), 1) @@ -94,14 +104,23 @@ BUILD_DATE!=date +%Y.%m.%d BUILD_HASH!=cat ../../hash.txt CFLAGS += -DBUILD_DATE=\"${BUILD_DATE}\" -DBUILD_HASH=\"${BUILD_HASH}\" +OBJ_DIR = build/$(PLATFORM) +OBJS = $(addprefix $(OBJ_DIR)/,$(notdir $(CSOURCE:.c=.o))) \ + $(addprefix $(OBJ_DIR)/,$(notdir $(CXXSOURCE:.cpp=.o))) + +# Locate sources across their directories so single pattern rules suffice. +vpath %.c . ../common ../../$(PLATFORM)/platform +vpath %.cpp . ../common ../../$(PLATFORM)/platform + ifeq ($(PLATFORM), desktop) -all: clean libretro-common rcheevos libchdr $(PREFIX_LOCAL)/include/msettings.h - mkdir -p build/$(PLATFORM) - $(CC) $(SOURCE) -o $(PRODUCT) $(CFLAGS) $(LDFLAGS) +all: clean libretro-common rcheevos libchdr $(PREFIX_LOCAL)/include/msettings.h $(PRODUCT) else ifneq (,$(filter $(PLATFORM),tg5040 tg5050 my355)) # Platforms with RA support -all: clean libretro-common libsrm.a rcheevos libchdr $(PREFIX_LOCAL)/include/msettings.h - mkdir -p build/$(PLATFORM) +all: clean libretro-common libsrm.a rcheevos libchdr $(PREFIX_LOCAL)/include/msettings.h copylibs $(PRODUCT) +endif + +# Runtime shared libraries copied next to the binary on handheld platforms. +copylibs: | $(OBJ_DIR) cp -L $(PREFIX)/lib/libsamplerate.so.* build/$(PLATFORM) cp -L $(PREFIX)/lib/libcrypto.so.* build/$(PLATFORM) chmod a+r build/$(PLATFORM)/libcrypto.so.* @@ -117,8 +136,18 @@ endif cp -L $(PREFIX)/lib/libzstd.so.1 build/$(PLATFORM) cp -L $(PREFIX)/lib/liblz4.so.1 build/$(PLATFORM) cp -L libchdr/build/$(PLATFORM)/libchdr.so.0 build/$(PLATFORM) - $(CC) $(SOURCE) -o $(PRODUCT) $(CFLAGS) $(LDFLAGS) -endif + +$(PRODUCT): $(OBJS) + $(CXX) $(OBJS) -o $(PRODUCT) $(LDFLAGS) -lstdc++ + +$(OBJ_DIR)/%.o: %.c | $(OBJ_DIR) + $(CC) $(CFLAGS) -c $< -o $@ + +$(OBJ_DIR)/%.o: %.cpp | $(OBJ_DIR) + $(CXX) $(CXXFLAGS) -c $< -o $@ + +$(OBJ_DIR): + mkdir -p $(OBJ_DIR) libretro-common: git clone https://github.com/libretro/libretro-common @@ -157,4 +186,5 @@ libsrm.a: $(OBJECTS) clean: rm -f $(PRODUCT) + rm -f $(OBJS) rm -f $(OBJECTS) $(LIBRARY) \ No newline at end of file diff --git a/workspace/all/nextui/makefile b/workspace/all/nextui/makefile index a1f2365ed..b00843fcf 100644 --- a/workspace/all/nextui/makefile +++ b/workspace/all/nextui/makefile @@ -21,20 +21,49 @@ SDL?=SDL TARGET = nextui INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ -SOURCE = $(TARGET).c ../common/scaler.c ../common/utils.c ../common/config.c ../common/api.c ../../$(PLATFORM)/platform/platform.c -CC = $(CROSS_COMPILE)gcc -CFLAGS += $(OPT) -CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" -std=gnu99 +# C and C++ translation units are listed separately. C files compile as C; +# C++ files compile as C++; everything links through g++ so the two can mix +# as modules are migrated to C++ incrementally. +CSOURCE = $(TARGET).c ../common/scaler.c ../common/utils.c ../common/config.c ../common/api.c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = + +CC = $(CROSS_COMPILE)gcc +CXX = $(CROSS_COMPILE)g++ +CFLAGS += $(OPT) +CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" +# CXXFLAGS inherits the platform CFLAGS (SDL/GL/PREFIX include paths) before the +# C-only -std is appended, so C++ TUs get the same include/define environment. +CXXFLAGS += $(CFLAGS) -std=gnu++20 +CFLAGS += -std=gnu99 LDFLAGS += -lmsettings +OBJ_DIR = build/$(PLATFORM) +OBJS = $(addprefix $(OBJ_DIR)/,$(notdir $(CSOURCE:.c=.o))) \ + $(addprefix $(OBJ_DIR)/,$(notdir $(CXXSOURCE:.cpp=.o))) + PRODUCT= build/$(PLATFORM)/$(TARGET).elf -all: $(PREFIX_LOCAL)/include/msettings.h - mkdir -p build/$(PLATFORM) - $(CC) $(SOURCE) -o $(PRODUCT) $(CFLAGS) $(LDFLAGS) +# Locate sources across their directories so a single pattern rule suffices. +vpath %.c . ../common ../../$(PLATFORM)/platform +vpath %.cpp . ../common ../../$(PLATFORM)/platform + +all: $(PREFIX_LOCAL)/include/msettings.h $(PRODUCT) + +$(PRODUCT): $(OBJS) + $(CXX) $(OBJS) -o $(PRODUCT) $(LDFLAGS) -lstdc++ + +$(OBJ_DIR)/%.o: %.c | $(OBJ_DIR) + $(CC) $(CFLAGS) -c $< -o $@ + +$(OBJ_DIR)/%.o: %.cpp | $(OBJ_DIR) + $(CXX) $(CXXFLAGS) -c $< -o $@ + +$(OBJ_DIR): + mkdir -p $(OBJ_DIR) + clean: - rm -f $(PRODUCT) + rm -f $(PRODUCT) $(OBJS) $(PREFIX_LOCAL)/include/msettings.h: cd ../../$(PLATFORM)/libmsettings && make diff --git a/workspace/all/settings/makefile b/workspace/all/settings/makefile index da1aae07b..06c851012 100644 --- a/workspace/all/settings/makefile +++ b/workspace/all/settings/makefile @@ -29,7 +29,7 @@ CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ CFLAGS += $(OPT) CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" -CXXFLAGS += $(CFLAGS) -std=c++17 +CXXFLAGS += $(CFLAGS) -std=gnu++20 CFLAGS += -fpermissive LDFLAGS += -lmsettings -lcrypto ifeq ($(PLATFORM), tg5040) From de70401e796a77bd729d825b6b8a65bce5ae39af Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Wed, 1 Jul 2026 10:29:01 +0200 Subject: [PATCH 03/77] refactor(nextui): move nextui to C++ and swap the hash for std::unordered_map Renamed nextui.c to nextui.cpp and got it building as C++20. The main change: the little Hash helper - a lightweight two-arrays-plus-linear-scan map that did the job fine at the sizes it was used for - is now a std::unordered_map, which we get for free now that this is a C++ TU. The rest was just making the existing C compile cleanly as C++: static_casts on the void* array reads, casts on malloc/Array_pop, const-correct label arrays, and named SDL_Rect temps instead of taking the address of a compound literal. Builds clean on desktop and behaves exactly like main - same behavior headless too, including a pre-existing font-under-dummy-driver crash that predates this change. --- workspace/all/nextui/makefile | 4 +- workspace/all/nextui/{nextui.c => nextui.cpp} | 195 +++++++++--------- 2 files changed, 95 insertions(+), 104 deletions(-) rename workspace/all/nextui/{nextui.c => nextui.cpp} (94%) diff --git a/workspace/all/nextui/makefile b/workspace/all/nextui/makefile index b00843fcf..8c1505b1c 100644 --- a/workspace/all/nextui/makefile +++ b/workspace/all/nextui/makefile @@ -25,8 +25,8 @@ INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # C and C++ translation units are listed separately. C files compile as C; # C++ files compile as C++; everything links through g++ so the two can mix # as modules are migrated to C++ incrementally. -CSOURCE = $(TARGET).c ../common/scaler.c ../common/utils.c ../common/config.c ../common/api.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = +CSOURCE = ../common/scaler.c ../common/utils.c ../common/config.c ../common/api.c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ diff --git a/workspace/all/nextui/nextui.c b/workspace/all/nextui/nextui.cpp similarity index 94% rename from workspace/all/nextui/nextui.c rename to workspace/all/nextui/nextui.cpp index 4754bed78..8a9687db8 100644 --- a/workspace/all/nextui/nextui.c +++ b/workspace/all/nextui/nextui.cpp @@ -1,21 +1,28 @@ #include #include -#include #include #include #include #include #include #include // For dirname() -#include "defines.h" -#include "api.h" -#include "utils.h" -#include "config.h" #include #include #include #include +#include +#include +#include + +extern "C" { +#include +#include "defines.h" +#include "api.h" +#include "utils.h" +#include "config.h" +} + /////////////////////////////////////// typedef struct Array { @@ -25,16 +32,16 @@ typedef struct Array { } Array; static Array* Array_new(void) { - Array* self = malloc(sizeof(Array)); + Array* self = (Array*)(malloc(sizeof(Array))); self->count = 0; self->capacity = 8; - self->items = malloc(sizeof(void*) * self->capacity); + self->items = (void**)(malloc(sizeof(void*) * self->capacity)); return self; } static void Array_push(Array* self, void* item) { if (self->count>=self->capacity) { self->capacity *= 2; - self->items = realloc(self->items, sizeof(void*) * self->capacity); + self->items = (void**)(realloc(self->items, sizeof(void*) * self->capacity)); } self->items[self->count++] = item; } @@ -81,7 +88,7 @@ static void Array_yoink(Array* self, Array* other) { static int StringArray_indexOf(Array* self, char* str) { for (int i=0; icount; i++) { - if (exactMatch(self->items[i], str)) return i; + if (exactMatch(static_cast(self->items[i]), str)) return i; } return -1; } @@ -95,29 +102,22 @@ static void StringArray_free(Array* self) { /////////////////////////////////////// typedef struct Hash { - Array* keys; - Array* values; -} Hash; // not really a hash + std::unordered_map map; +} Hash; static Hash* Hash_new(void) { - Hash* self = malloc(sizeof(Hash)); - self->keys = Array_new(); - self->values = Array_new(); - return self; + return new Hash(); } static void Hash_free(Hash* self) { - StringArray_free(self->keys); - StringArray_free(self->values); - free(self); + delete self; } -static void Hash_set(Hash* self, char* key, char* value) { - Array_push(self->keys, strdup(key)); - Array_push(self->values, strdup(value)); +static void Hash_set(Hash* self, const char* key, const char* value) { + self->map[key] = value; } -static char* Hash_get(Hash* self, char* key) { - int i = StringArray_indexOf(self->keys, key); - if (i==-1) return NULL; - return self->values->items[i]; +static const char* Hash_get(Hash* self, const char* key) { + auto it = self->map.find(key); + if (it==self->map.end()) return NULL; + return it->second.c_str(); } /////////////////////////////////////// @@ -139,7 +139,7 @@ typedef struct Entry { static Entry* Entry_new(char* path, int type) { char display_name[256]; getDisplayName(path, display_name); - Entry* self = malloc(sizeof(Entry)); + Entry* self = (Entry*)(malloc(sizeof(Entry))); self->path = strdup(path); self->name = strdup(display_name); self->unique = NULL; @@ -163,7 +163,7 @@ static void Entry_free(Entry* self) { static int EntryArray_indexOf(Array* self, char* path) { for (int i=0; icount; i++) { - Entry* entry = self->items[i]; + Entry* entry = static_cast(self->items[i]); if (exactMatch(entry->path, path)) return i; } return -1; @@ -179,7 +179,7 @@ static void EntryArray_sort(Array* self) { static void EntryArray_free(Array* self) { for (int i=0; icount; i++) { - Entry_free(self->items[i]); + Entry_free(static_cast(self->items[i])); } Array_free(self); } @@ -192,7 +192,7 @@ typedef struct IntArray { int items[INT_ARRAY_MAX]; } IntArray; static IntArray* IntArray_new(void) { - IntArray* self = malloc(sizeof(IntArray)); + IntArray* self = (IntArray*)(malloc(sizeof(IntArray))); self->count = 0; memset(self->items, 0, sizeof(int) * INT_ARRAY_MAX); return self; @@ -270,9 +270,9 @@ static void Directory_index(Directory* self) { int resort = 0; int filter = 0; for (int i = 0; i < self->entries->count; i++) { - Entry* entry = self->entries->items[i]; + Entry* entry = static_cast(self->entries->items[i]); char* filename = strrchr(entry->path, '/') + 1; - char* alias = Hash_get(map, filename); + const char* alias = Hash_get(map, filename); if (alias) { free(entry->name); // Free before overwriting entry->name = strdup(alias); @@ -284,7 +284,7 @@ static void Directory_index(Directory* self) { if (filter) { Array* entries = Array_new(); for (int i = 0; i < self->entries->count; i++) { - Entry* entry = self->entries->items[i]; + Entry* entry = static_cast(self->entries->items[i]); if (hide(entry->name)) { Entry_free(entry); // Ensure Entry_free handles all memory cleanup } else { @@ -302,10 +302,10 @@ static void Directory_index(Directory* self) { int alpha = -1; int index = 0; for (int i = 0; i < self->entries->count; i++) { - Entry* entry = self->entries->items[i]; + Entry* entry = static_cast(self->entries->items[i]); if (map) { char* filename = strrchr(entry->path, '/') + 1; - char* alias = Hash_get(map, filename); + const char* alias = Hash_get(map, filename); if (alias) { free(entry->name); // Free before overwriting entry->name = strdup(alias); @@ -361,7 +361,7 @@ static Directory* Directory_new(char* path, int selected) { char display_name[256]; getDisplayName(path, display_name); - Directory* self = malloc(sizeof(Directory)); + Directory* self = (Directory*)(malloc(sizeof(Directory))); self->path = strdup(path); self->name = strdup(display_name); if (exactMatch(path, SDCARD_PATH)) { @@ -396,11 +396,11 @@ static void Directory_free(Directory* self) { } static void DirectoryArray_pop(Array* self) { - Directory_free(Array_pop(self)); + Directory_free(static_cast(Array_pop(self))); } static void DirectoryArray_free(Array* self) { for (int i=0; icount; i++) { - Directory_free(self->items[i]); + Directory_free(static_cast(self->items[i])); } Array_free(self); } @@ -417,7 +417,7 @@ static char* recent_alias = NULL; static int hasEmu(char* emu_name); static Recent* Recent_new(char* path, char* alias) { - Recent* self = malloc(sizeof(Recent)); + Recent* self = (Recent*)(malloc(sizeof(Recent))); char sd_path[256]; // only need to get emu name sprintf(sd_path, "%s%s", SDCARD_PATH, path); @@ -438,14 +438,14 @@ static void Recent_free(Recent* self) { static int RecentArray_indexOf(Array* self, char* str) { for (int i=0; icount; i++) { - Recent* item = self->items[i]; + Recent* item = static_cast(self->items[i]); if (exactMatch(item->path, str)) return i; } return -1; } static void RecentArray_free(Array* self) { for (int i=0; icount; i++) { - Recent_free(self->items[i]); + Recent_free(static_cast(self->items[i])); } Array_free(self); } @@ -481,7 +481,7 @@ static void saveRecents(void) { FILE* file = fopen(RECENT_PATH, "w"); if (file) { for (int i=0; icount; i++) { - Recent* recent = recents->items[i]; + Recent* recent = static_cast(recents->items[i]); fputs(recent->path, file); if (recent->alias) { fputs("\t", file); @@ -497,7 +497,7 @@ static void addRecent(char* path, char* alias) { int id = RecentArray_indexOf(recents, path); if (id==-1) { // add while (recents->count>=MAX_RECENTS) { - Recent_free(Array_pop(recents)); + Recent_free(static_cast(Array_pop(recents))); } Array_unshift(recents, Recent_new(path, alias)); } @@ -632,7 +632,7 @@ static int hasRecents(void) { int found = 0; for (int i=0; icount; i++) { - char* path = parent_paths->items[i]; + char* path = static_cast(parent_paths->items[i]); if (prefixMatch(path, parent_path)) { found = 1; break; @@ -728,7 +728,7 @@ static Array* getRoms() EntryArray_sort(emus); Entry* prev_entry = NULL; for (int i = 0; i < emus->count; i++) { - Entry* entry = emus->items[i]; + Entry* entry = static_cast(emus->items[i]); if (prev_entry && exactMatch(prev_entry->name, entry->name)) { Entry_free(entry); continue; @@ -765,9 +765,9 @@ static Array* getRoms() int resort = 0; for (int i = 0; i < entries->count; i++) { - Entry* entry = entries->items[i]; + Entry* entry = static_cast(entries->items[i]); char* filename = strrchr(entry->path, '/') + 1; - char* alias = Hash_get(map, filename); + const char* alias = Hash_get(map, filename); if (alias) { free(entry->name); // Free before overwriting entry->name = strdup(alias); @@ -901,7 +901,7 @@ static Entry* entryFromRecent(Recent* recent) static Array* getRecents(void) { Array* entries = Array_new(); for (int i=0; icount; i++) { - Recent *recent = recents->items[i]; + Recent* recent = static_cast(recents->items[i]); Entry *entry = entryFromRecent(recent); if(entry) Array_push(entries, entry); @@ -1459,7 +1459,7 @@ static void openDirectory(char* path, int auto_launch) { DirectoryArray_free(stack); stack = pathToStack(temp_path); - top = stack->items[stack->count - 1]; + top = static_cast(stack->items[stack->count - 1]); } } @@ -1469,7 +1469,7 @@ static void closeDirectory(void) { restore_end = top->end; DirectoryArray_pop(stack); restore_depth = stack->count; - top = stack->items[stack->count-1]; + top = static_cast(stack->items[stack->count-1]); restore_relative = top->selected; } @@ -1564,7 +1564,7 @@ static void loadLast(void) { // call after loading root directory } while (last->count>0) { - char* path = Array_pop(last); + char* path = static_cast(Array_pop(last)); if (!exactMatch(path, ROMS_PATH)) { // romsDir is effectively root as far as restoring state after a game char collated_path[256]; collated_path[0] = '\0'; @@ -1575,7 +1575,7 @@ static void loadLast(void) { // call after loading root directory } for (int i=0; ientries->count; i++) { - Entry* entry = top->entries->items[i]; + Entry* entry = static_cast(top->entries->items[i]); // NOTE: strlen() is required for collated_path, '\0' wasn't reading as NULL for some reason if (exactMatch(entry->path, path) || (strlen(collated_path) && prefixMatch(collated_path, entry->path)) || (prefixMatch(COLLECTIONS_PATH, full_path) && suffixMatch(filename, entry->path))) { @@ -1603,7 +1603,7 @@ static void loadLast(void) { // call after loading root directory StringArray_free(last); if (top->selected >= 0 && top->selected < top->entries->count) { - Entry *selected_entry = top->entries->items[top->selected]; + Entry* selected_entry = static_cast(top->entries->items[top->selected]); readyResume(selected_entry); } } @@ -1931,7 +1931,7 @@ int ThumbLoadWorker(void* unused) { } void startLoadFolderBackground(const char* imagePath, BackgroundLoadedCallback callback, void* userData) { - LoadBackgroundTask* task = malloc(sizeof(LoadBackgroundTask)); + LoadBackgroundTask* task = (LoadBackgroundTask*)(malloc(sizeof(LoadBackgroundTask))); if (!task) return; snprintf(task->imagePath, sizeof(task->imagePath), "%s", imagePath); @@ -1955,7 +1955,7 @@ void onBackgroundLoaded(SDL_Surface* surface) { } void startLoadThumb(const char* thumbpath, BackgroundLoadedCallback callback, void* userData) { - LoadBackgroundTask* task = malloc(sizeof(LoadBackgroundTask)); + LoadBackgroundTask* task = (LoadBackgroundTask*)(malloc(sizeof(LoadBackgroundTask))); if (!task) return; snprintf(task->imagePath, sizeof(task->imagePath), "%s", thumbpath); @@ -1988,9 +1988,10 @@ void onThumbLoaded(SDL_Surface* surface) { new_w = (int)(new_h / aspect_ratio); } + SDL_Rect _corner_rect = {0, 0, thumbbmp->w, thumbbmp->h}; GFX_ApplyRoundedCorners_8888( thumbbmp, - &(SDL_Rect){0, 0, thumbbmp->w, thumbbmp->h}, + &_corner_rect, SCALE1((float)CFG_getThumbnailRadius() * ((float)img_w / (float)new_w)) ); setNeedDraw(1); @@ -2326,7 +2327,7 @@ int main (int argc, char *argv[]) { dirty = 1; } else if (PAD_justReleased(BTN_A)) { - Entry *selected = qm_row == 0 ? quick->items[qm_col] : quickActions->items[qm_col]; + Entry* selected = static_cast(qm_row == 0 ? quick->items[qm_col] : quickActions->items[qm_col]); if(selected->type != ENTRY_DIP) { currentScreen = SCREEN_GAMELIST; total = top->entries->count; @@ -2417,7 +2418,7 @@ int main (int argc, char *argv[]) { // this will drop us back into game switcher after leaving the game putFile(GAME_SWITCHER_PERSIST_PATH, "unused"); startgame = 1; - Entry *selectedEntry = entryFromRecent(recents->items[switcher_selected]); + Entry *selectedEntry = entryFromRecent(static_cast(recents->items[switcher_selected])); should_resume = can_resume; Entry_open(selectedEntry); dirty = 1; @@ -2425,7 +2426,7 @@ int main (int argc, char *argv[]) { } else if (recents->count > 0 && PAD_justReleased(BTN_Y)) { // remove - Recent* recentEntry = recents->items[switcher_selected--]; + Recent* recentEntry = static_cast(recents->items[switcher_selected--]); Array_remove(recents, recentEntry); Recent_free(recentEntry); saveRecents(); @@ -2530,7 +2531,7 @@ int main (int argc, char *argv[]) { } if (PAD_justRepeated(BTN_L1) && !PAD_isPressed(BTN_R1) && !PWR_ignoreSettingInput(BTN_L1, show_setting)) { // previous alpha - Entry* entry = top->entries->items[selected]; + Entry* entry = static_cast(top->entries->items[selected]); int i = entry->alpha-1; if (i>=0) { selected = top->alphas->items[i]; @@ -2543,7 +2544,7 @@ int main (int argc, char *argv[]) { } } else if (PAD_justRepeated(BTN_R1) && !PAD_isPressed(BTN_L1) && !PWR_ignoreSettingInput(BTN_R1, show_setting)) { // next alpha - Entry* entry = top->entries->items[selected]; + Entry* entry = static_cast(top->entries->items[selected]); int i = entry->alpha+1; if (ialphas->count) { selected = top->alphas->items[i]; @@ -2561,7 +2562,7 @@ int main (int argc, char *argv[]) { dirty = 1; } - Entry* entry = top->entries->items[top->selected]; + Entry* entry = static_cast(top->entries->items[top->selected]); if (dirty && total>0) readyResume(entry); @@ -2580,7 +2581,7 @@ int main (int argc, char *argv[]) { } dirty = 1; - if (total>0) readyResume(top->entries->items[top->selected]); + if (total>0) readyResume(static_cast(top->entries->items[top->selected])); } else if (PAD_justPressed(BTN_B) && stack->count>1) { closeDirectory(); @@ -2588,7 +2589,7 @@ int main (int argc, char *argv[]) { total = top->entries->count; dirty = 1; - if (total>0) readyResume(top->entries->items[top->selected]); + if (total>0) readyResume(static_cast(top->entries->items[top->selected])); } } @@ -2622,7 +2623,7 @@ int main (int argc, char *argv[]) { GFX_clearLayers(LAYER_THUMBNAIL); } - Entry *current = qm_row == 0 ? quick->items[qm_col] : quickActions->items[qm_col]; + Entry* current = static_cast(qm_row == 0 ? quick->items[qm_col] : quickActions->items[qm_col]); char newBgPath[MAX_PATH]; char fallbackBgPath[MAX_PATH]; @@ -2642,9 +2643,9 @@ int main (int argc, char *argv[]) { // buttons (duped and trimmed from below) if (show_setting && !GetHDMI()) GFX_blitHardwareHints(screen, show_setting); - else GFX_blitButtonGroup((char*[]){ BTN_SLEEP==BTN_POWER?"POWER":"MENU","SLEEP", NULL }, 0, screen, 0); + else GFX_blitButtonGroup((char**)(const char*[]){ BTN_SLEEP==BTN_POWER?"POWER":"MENU","SLEEP", NULL }, 0, screen, 0); - GFX_blitButtonGroup((char*[]){ "B","BACK", "A","OPEN", NULL }, 1, screen, 1); + GFX_blitButtonGroup((char**)(const char*[]){ "B","BACK", "A","OPEN", NULL }, 1, screen, 1); if(CFG_getShowQuickswitcherUI()) { #define MENU_ITEM_SIZE 72 // item size, top line @@ -2678,7 +2679,7 @@ int main (int argc, char *argv[]) { for (int c = 0; c < quick->count; c++) { SDL_Rect item_rect = {ox, oy, item_size, item_size}; - Entry *item = quick->items[c]; + Entry* item = static_cast(quick->items[c]); SDL_Color text_color = uintToColour(THEME_COLOR4_255); uint32_t item_color = THEME_COLOR3; @@ -2726,7 +2727,7 @@ int main (int argc, char *argv[]) { oy = SCALE1(PADDING + PILL_SIZE + BUTTON_MARGIN + MENU_MARGIN_Y + MENU_LINE_MARGIN) + item_size + item_extra_y / 2; for (int c = 0; c < quickActions->count; c++) { SDL_Rect item_rect = {ox, oy, SCALE1(PILL_SIZE), SCALE1(PILL_SIZE)}; - Entry *item = quickActions->items[c]; + Entry* item = static_cast(quickActions->items[c]); SDL_Color text_color = uintToColour(THEME_COLOR4_255); uint32_t item_color = THEME_COLOR3; @@ -2763,7 +2764,7 @@ int main (int argc, char *argv[]) { x += (SCALE1(PILL_SIZE) - rect.w) / 2; y += (SCALE1(PILL_SIZE) - rect.h) / 2; - GFX_blitAssetColor(asset, NULL, screen, &(SDL_Rect){x,y}, icon_color); + { SDL_Rect _r = {x,y}; GFX_blitAssetColor(asset, NULL, screen, &_r, icon_color); } ox += item_rect.w + SCALE1(MENU_TOGGLE_MARGIN); } @@ -2785,7 +2786,7 @@ int main (int argc, char *argv[]) { // For all recents with resumable state (i.e. has savegame), show game switcher carousel if(recents->count > 0) { - Entry *selectedEntry = entryFromRecent(recents->items[switcher_selected]); + Entry *selectedEntry = entryFromRecent(static_cast(recents->items[switcher_selected])); readyResume(selectedEntry); // title pill { @@ -2801,28 +2802,18 @@ int main (int argc, char *argv[]) { text = TTF_RenderUTF8_Blended(font.large, display_name, textColor); SDL_UnlockMutex(fontMutex); const int text_offset_y = (SCALE1(PILL_SIZE) - text->h + 1) >> 1; - GFX_blitPillLight(ASSET_WHITE_PILL, screen, &(SDL_Rect){ - SCALE1(PADDING), - SCALE1(PADDING), - max_width, - SCALE1(PILL_SIZE) - }); - SDL_BlitSurface(text, &(SDL_Rect){ - 0, - 0, - max_width-SCALE1(BUTTON_PADDING*2), - text->h - }, screen, &(SDL_Rect){ - SCALE1(PADDING+BUTTON_PADDING), - SCALE1(PADDING) + text_offset_y, - }); + SDL_Rect _pill_rect = { SCALE1(PADDING), SCALE1(PADDING), max_width, SCALE1(PILL_SIZE) }; + GFX_blitPillLight(ASSET_WHITE_PILL, screen, &_pill_rect); + SDL_Rect _text_src = { 0, 0, max_width-SCALE1(BUTTON_PADDING*2), text->h }; + SDL_Rect _text_dst = { SCALE1(PADDING+BUTTON_PADDING), SCALE1(PADDING) + text_offset_y }; + SDL_BlitSurface(text, &_text_src, screen, &_text_dst); SDL_FreeSurface(text); } - if(can_resume) GFX_blitButtonGroup((char*[]){ "B","BACK", NULL }, 0, screen, 0); - else GFX_blitButtonGroup((char*[]){ BTN_SLEEP==BTN_POWER?"POWER":"MENU","SLEEP", NULL }, 0, screen, 0); + if(can_resume) GFX_blitButtonGroup((char**)(const char*[]){ "B","BACK", NULL }, 0, screen, 0); + else GFX_blitButtonGroup((char**)(const char*[]){ BTN_SLEEP==BTN_POWER?"POWER":"MENU","SLEEP", NULL }, 0, screen, 0); - GFX_blitButtonGroup((char*[]){ "Y", "REMOVE", "A","RESUME", NULL }, 1, screen, 1); + GFX_blitButtonGroup((char**)(const char*[]){ "Y", "REMOVE", "A","RESUME", NULL }, 1, screen, 1); if(has_preview) { // lotta memory churn here @@ -2909,7 +2900,7 @@ int main (int argc, char *argv[]) { SDL_Rect preview_rect = {ox,oy,screen->w,screen->h}; SDL_FillRect(screen, &preview_rect, 0); GFX_blitMessage(font.large, "No Recents", screen, &preview_rect); - GFX_blitButtonGroup((char*[]){ "B","BACK", NULL }, 1, screen, 1); + GFX_blitButtonGroup((char**)(const char*[]){ "B","BACK", NULL }, 1, screen, 1); } GFX_flipHidden(); @@ -2920,7 +2911,7 @@ int main (int argc, char *argv[]) { } else { // if currentscreen == SCREEN_GAMELIST // background and game art file path stuff - Entry* entry = top->entries->items[top->selected]; + Entry* entry = static_cast(top->entries->items[top->selected]); assert(entry); char tmp_path[MAX_PATH]; strncpy(tmp_path, entry->path, sizeof(tmp_path) - 1); @@ -2999,23 +2990,23 @@ int main (int argc, char *argv[]) { // buttons if (show_setting && !GetHDMI()) GFX_blitHardwareHints(screen, show_setting); - else if (can_resume) GFX_blitButtonGroup((char*[]){ "X","RESUME", NULL }, 0, screen, 0); - else GFX_blitButtonGroup((char*[]){ + else if (can_resume) GFX_blitButtonGroup((char**)(const char*[]){ "X","RESUME", NULL }, 0, screen, 0); + else GFX_blitButtonGroup((char**)(const char*[]){ BTN_SLEEP==BTN_POWER?"POWER":"MENU", BTN_SLEEP==BTN_POWER||simple_mode?"SLEEP":"INFO", NULL }, 0, screen, 0); if (total==0) { if (stack->count>1) { - GFX_blitButtonGroup((char*[]){ "B","BACK", NULL }, 0, screen, 1); + GFX_blitButtonGroup((char**)(const char*[]){ "B","BACK", NULL }, 0, screen, 1); } } else { if (stack->count>1) { - GFX_blitButtonGroup((char*[]){ "B","BACK", "A","OPEN", NULL }, 1, screen, 1); + GFX_blitButtonGroup((char**)(const char*[]){ "B","BACK", "A","OPEN", NULL }, 1, screen, 1); } else { - GFX_blitButtonGroup((char*[]){ "A","OPEN", NULL }, 0, screen, 1); + GFX_blitButtonGroup((char**)(const char*[]){ "A","OPEN", NULL }, 0, screen, 1); } } @@ -3026,7 +3017,7 @@ int main (int argc, char *argv[]) { targetY = selected_row * PILL_SIZE; SDL_Color text_color = uintToColour(THEME_COLOR4_255); // list text color for (int i = top->start, j = 0; i < top->end; i++, j++) { - Entry* entry = top->entries->items[i]; + Entry* entry = static_cast(top->entries->items[i]); char* entry_name = entry->name; char* entry_unique = entry->unique; int available_width = MAX(0,(had_thumb ? ox + SCALE1(BUTTON_MARGIN) : screen->w - SCALE1(BUTTON_MARGIN)) - SCALE1(PADDING * 2)); @@ -3069,11 +3060,11 @@ int main (int argc, char *argv[]) { globalpill=NULL; } globalpill = SDL_CreateRGBSurfaceWithFormat(SDL_SWSURFACE, max_width, SCALE1(PILL_SIZE), FIXED_DEPTH, screen->format->format); - GFX_blitPillDark(ASSET_WHITE_PILL, globalpill, &(SDL_Rect){0,0, max_width, SCALE1(PILL_SIZE)}); + { SDL_Rect _r = {0,0, max_width, SCALE1(PILL_SIZE)}; GFX_blitPillDark(ASSET_WHITE_PILL, globalpill, &_r); } globallpillW = max_width; SDL_UnlockMutex(animMutex); updatePillTextSurface(entry_name, max_width, uintToColour(THEME_COLOR5_255)); - AnimTask* task = malloc(sizeof(AnimTask)); + AnimTask* task = (AnimTask*)(malloc(sizeof(AnimTask))); task->startX = SCALE1(BUTTON_MARGIN); task->startY = SCALE1(previousY+PADDING); task->targetX = SCALE1(BUTTON_MARGIN); @@ -3116,7 +3107,7 @@ int main (int argc, char *argv[]) { } else { // TODO: for some reason screen's dimensions end up being 0x0 in GFX_blitMessage... - GFX_blitMessage(font.large, "Empty folder", screen, &(SDL_Rect){0,0,screen->w,screen->h}); //, NULL); + { SDL_Rect _r = {0,0,screen->w,screen->h}; GFX_blitMessage(font.large, "Empty folder", screen, &_r); } //, NULL); } lastScreen = SCREEN_GAMELIST; @@ -3279,7 +3270,7 @@ int main (int argc, char *argv[]) { if (currentScreen != SCREEN_GAMESWITCHER && currentScreen != SCREEN_QUICKMENU) { if(is_scrolling && pillanimdone && currentAnimQueueSize < 1) { int ow = GFX_blitHardwareGroup(screen, show_setting); - Entry* entry = top->entries->items[top->selected]; + Entry* entry = static_cast(top->entries->items[top->selected]); trimSortingMeta(&entry->name); char* entry_text = entry->name; if (entry->unique) { @@ -3359,7 +3350,7 @@ int main (int argc, char *argv[]) { if (has_hdmi!=had_hdmi) { had_hdmi = has_hdmi; - Entry* entry = top->entries->items[top->selected]; + Entry* entry = static_cast(top->entries->items[top->selected]); LOG_info("restarting after HDMI change... (%s)\n", entry->path); saveLast(entry->path); // NOTE: doesn't work in Recents (by design) sleep(4); From 6ed5f63f3729f5d004b689851bd06965560ccfbf Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Wed, 1 Jul 2026 13:05:45 +0200 Subject: [PATCH 04/77] build: auto-pick the best C++ std the toolchain supports The tg5040 cross-compiler is still gcc 8.3, which knows -std=gnu++2a but not the newer -std=gnu++20 spelling, so hardcoding gnu++20 broke the device build. Probe the compiler at make time and use gnu++20 when it's available (desktop gcc, and the gcc 13/14 toolchain once we get there) or fall back to gnu++2a otherwise. Same language either way for what we use. Builds clean on desktop and cross-compiles for tg5040. --- workspace/all/minarch/makefile | 5 ++++- workspace/all/nextui/makefile | 5 ++++- workspace/all/settings/makefile | 5 ++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/workspace/all/minarch/makefile b/workspace/all/minarch/makefile index 206c10b2e..0c6c3b2b0 100644 --- a/workspace/all/minarch/makefile +++ b/workspace/all/minarch/makefile @@ -40,11 +40,14 @@ endif CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ +# Prefer real C++20; fall back to gnu++2a on older toolchains (e.g. the current +# gcc 8.3 tg5040 cross-compiler, which predates the -std=gnu++20 spelling). +CXXSTD := $(shell printf 'int main(){return 0;}' | $(CXX) -std=gnu++20 -x c++ - -o /dev/null >/dev/null 2>&1 && echo gnu++20 || echo gnu++2a) CFLAGS += $(OPT) CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" # CXXFLAGS inherits the platform CFLAGS (SDL/GL/PREFIX include paths) before the # C-only -std is appended, so C++ TUs get the same include/define environment. -CXXFLAGS += $(CFLAGS) -std=gnu++20 +CXXFLAGS += $(CFLAGS) -std=$(CXXSTD) CFLAGS += -std=gnu99 LDFLAGS += -lmsettings -lsamplerate diff --git a/workspace/all/nextui/makefile b/workspace/all/nextui/makefile index 8c1505b1c..4f94d5e9f 100644 --- a/workspace/all/nextui/makefile +++ b/workspace/all/nextui/makefile @@ -30,11 +30,14 @@ CXXSOURCE = $(TARGET).cpp CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ +# Prefer real C++20; fall back to gnu++2a on older toolchains (e.g. the current +# gcc 8.3 tg5040 cross-compiler, which predates the -std=gnu++20 spelling). +CXXSTD := $(shell printf 'int main(){return 0;}' | $(CXX) -std=gnu++20 -x c++ - -o /dev/null >/dev/null 2>&1 && echo gnu++20 || echo gnu++2a) CFLAGS += $(OPT) CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" # CXXFLAGS inherits the platform CFLAGS (SDL/GL/PREFIX include paths) before the # C-only -std is appended, so C++ TUs get the same include/define environment. -CXXFLAGS += $(CFLAGS) -std=gnu++20 +CXXFLAGS += $(CFLAGS) -std=$(CXXSTD) CFLAGS += -std=gnu99 LDFLAGS += -lmsettings diff --git a/workspace/all/settings/makefile b/workspace/all/settings/makefile index 06c851012..a25e3585b 100644 --- a/workspace/all/settings/makefile +++ b/workspace/all/settings/makefile @@ -27,9 +27,12 @@ CXXSOURCE += build/$(PLATFORM)/utils.o build/$(PLATFORM)/api.o build/$(PLATFORM) CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ +# Prefer real C++20; fall back to gnu++2a on older toolchains (e.g. the current +# gcc 8.3 tg5040 cross-compiler, which predates the -std=gnu++20 spelling). +CXXSTD := $(shell printf 'int main(){return 0;}' | $(CXX) -std=gnu++20 -x c++ - -o /dev/null >/dev/null 2>&1 && echo gnu++20 || echo gnu++2a) CFLAGS += $(OPT) CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" -CXXFLAGS += $(CFLAGS) -std=gnu++20 +CXXFLAGS += $(CFLAGS) -std=$(CXXSTD) CFLAGS += -fpermissive LDFLAGS += -lmsettings -lcrypto ifeq ($(PLATFORM), tg5040) From 89b68f6d9914a86456ae36396e8b1e1da9b70396 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Wed, 1 Jul 2026 16:21:47 +0200 Subject: [PATCH 05/77] poc(nextui): disable worker-thread subsystems so the C++ build runs The background/thumbnail image loaders and the pill-animation worker use a hand-rolled multithreaded task queue with a latent memory-corruption bug: a stray write that smashes the stack (and even the dynamic linker's loaded-lib list). It was benign under the old C build but turns fatal once the file is compiled as C++ - the different codegen/layout shifts the write onto something that matters. It crashes a worker thread on game launch/exit; ASan masks it (timing/layout), which is how we cornered it. For the C++ port POC, gate those subsystems off behind NEXTUI_POC_NO_WORKERS: don't spawn the three worker threads, no-op the image loaders (folderbg/thumb surfaces stay NULL and the existing draw guards fall through to a clear), and set the selection pill's final position directly instead of queueing it for the animation worker. No thumbnails, box art, backgrounds or pill animation for now. Confirmed on-device (tg5040/Brick): boots, browses, launches and quits games cleanly - the crash is gone. These subsystems get reintroduced later with a proper thread-safe implementation. --- workspace/all/nextui/nextui.cpp | 55 +++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/workspace/all/nextui/nextui.cpp b/workspace/all/nextui/nextui.cpp index 8a9687db8..5516214b1 100644 --- a/workspace/all/nextui/nextui.cpp +++ b/workspace/all/nextui/nextui.cpp @@ -23,6 +23,19 @@ extern "C" { #include "config.h" } +// --------------------------------------------------------------------------- +// POC SCAFFOLDING (temporary) +// +// The background/thumbnail image loaders and the pill-animation worker use a +// hand-rolled multi-threaded task queue that has latent memory-corruption bugs +// (a stray write that smashes the stack / dynamic-linker state; benign under the +// old C build, fatal once compiled as C++). For the C++ port POC we disable +// those worker threads and run the launcher without async image loading, +// thumbnails, backgrounds and the pill animation. These are to be reintroduced +// later with a correct, thread-safe implementation. Grep NEXTUI_POC_NO_WORKERS. +// --------------------------------------------------------------------------- +#define NEXTUI_POC_NO_WORKERS 1 + /////////////////////////////////////// typedef struct Array { @@ -1931,6 +1944,12 @@ int ThumbLoadWorker(void* unused) { } void startLoadFolderBackground(const char* imagePath, BackgroundLoadedCallback callback, void* userData) { +#if NEXTUI_POC_NO_WORKERS + // POC: async background loading disabled. folderbgbmp stays NULL; every + // background draw is NULL-guarded and falls through to GFX_clearLayers. + (void)imagePath; (void)callback; (void)userData; + return; +#else LoadBackgroundTask* task = (LoadBackgroundTask*)(malloc(sizeof(LoadBackgroundTask))); if (!task) return; @@ -1938,6 +1957,7 @@ void startLoadFolderBackground(const char* imagePath, BackgroundLoadedCallback c task->callback = callback; task->userData = userData; enqueueBGTask(task); +#endif } void onBackgroundLoaded(SDL_Surface* surface) { @@ -1955,6 +1975,12 @@ void onBackgroundLoaded(SDL_Surface* surface) { } void startLoadThumb(const char* thumbpath, BackgroundLoadedCallback callback, void* userData) { +#if NEXTUI_POC_NO_WORKERS + // POC: async thumbnail loading disabled. thumbbmp stays NULL; the thumbnail + // draw is guarded by `if(thumbbmp && thumbchanged)` and falls through to clear. + (void)thumbpath; (void)callback; (void)userData; + return; +#else LoadBackgroundTask* task = (LoadBackgroundTask*)(malloc(sizeof(LoadBackgroundTask))); if (!task) return; @@ -1962,6 +1988,7 @@ void startLoadThumb(const char* thumbpath, BackgroundLoadedCallback callback, vo task->callback = callback; task->userData = userData; enqueueThumbTask(task); +#endif } void onThumbLoaded(SDL_Surface* surface) { SDL_LockMutex(thumbMutex); @@ -2114,8 +2141,28 @@ void enqueueanmimtask(AnimTask* task) { } void animPill(AnimTask *task) { +#if NEXTUI_POC_NO_WORKERS + // POC: the worker-thread pill animation is disabled. Apply the final pill + // position directly (instant, no tween) instead of queueing it for animWorker. + // This is what animcallback would have set on the last frame. + SDL_LockMutex(animMutex); + pillRect.x = task->targetX; + pillRect.y = task->targetY; + pillRect.w = task->move_w; + pillRect.h = task->move_h; + pilltargetY = task->targetY; + pilltargetTextY = task->targetTextY; + pillanimdone = true; + SDL_UnlockMutex(animMutex); + setNeedDraw(1); + setAnimationDraw(1); + // The caller malloc'd the task and does not use it after this call. + if (task->entry_name) free(task->entry_name); + free(task); +#else task->callback = animcallback; enqueueanmimtask(task); +#endif } void initImageLoaderPool() { @@ -2137,9 +2184,17 @@ void initImageLoaderPool() { fontMutex = SDL_CreateMutex(); flipCond = SDL_CreateCond(); +#if NEXTUI_POC_NO_WORKERS + // POC: do not spawn the image-loader / pill-animation worker threads. The + // thread handles stay NULL so cleanupImageLoaderPool's join guards skip them. + bgLoadThread = NULL; + thumbLoadThread = NULL; + animWorkerThread = NULL; +#else bgLoadThread = SDL_CreateThread(BGLoadWorker, "BGLoadWorker", NULL); thumbLoadThread = SDL_CreateThread(ThumbLoadWorker, "ThumbLoadWorker", NULL); animWorkerThread = SDL_CreateThread(animWorker, "animWorker", NULL); +#endif } void cleanupImageLoaderPool() { From 8a6dd00e35a2709a38c504aec668a8dc9ea3b53f Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Wed, 1 Jul 2026 17:29:42 +0200 Subject: [PATCH 06/77] nextui: swap IntArray for std::vector The old IntArray was a fixed int[27] with an unchecked push - fine in practice since it only ever holds the A-Z+# alpha buckets, but a silent overflow waiting to happen if that assumption ever changed. std::vector drops the cap and the hand-rolled new/push/free. alphas stays a heap pointer for now so we don't have to touch how Directory is allocated. --- workspace/all/nextui/nextui.cpp | 36 ++++++++------------------------- 1 file changed, 8 insertions(+), 28 deletions(-) diff --git a/workspace/all/nextui/nextui.cpp b/workspace/all/nextui/nextui.cpp index 5516214b1..4bf8b96b6 100644 --- a/workspace/all/nextui/nextui.cpp +++ b/workspace/all/nextui/nextui.cpp @@ -199,31 +199,11 @@ static void EntryArray_free(Array* self) { /////////////////////////////////////// -#define INT_ARRAY_MAX 27 -typedef struct IntArray { - int count; - int items[INT_ARRAY_MAX]; -} IntArray; -static IntArray* IntArray_new(void) { - IntArray* self = (IntArray*)(malloc(sizeof(IntArray))); - self->count = 0; - memset(self->items, 0, sizeof(int) * INT_ARRAY_MAX); - return self; -} -static void IntArray_push(IntArray* self, int i) { - self->items[self->count++] = i; -} -static void IntArray_free(IntArray* self) { - free(self); -} - -/////////////////////////////////////// - typedef struct Directory { char* path; char* name; Array* entries; - IntArray* alphas; + std::vector* alphas; // rendering int selected; int start; @@ -350,8 +330,8 @@ static void Directory_index(Directory* self) { if (!skip_index) { int a = getIndexChar(entry->name); if (a != alpha) { - index = self->alphas->count; - IntArray_push(self->alphas, i); + index = (int)self->alphas->size(); + self->alphas->push_back(i); alpha = a; } entry->alpha = index; @@ -395,7 +375,7 @@ static Directory* Directory_new(char* path, int selected) { else { self->entries = getEntries(path); } - self->alphas = IntArray_new(); + self->alphas = new std::vector(); self->selected = selected; Directory_index(self); return self; @@ -404,7 +384,7 @@ static void Directory_free(Directory* self) { free(self->path); free(self->name); EntryArray_free(self->entries); - IntArray_free(self->alphas); + delete self->alphas; free(self); } @@ -2589,7 +2569,7 @@ int main (int argc, char *argv[]) { Entry* entry = static_cast(top->entries->items[selected]); int i = entry->alpha-1; if (i>=0) { - selected = top->alphas->items[i]; + selected = (*top->alphas)[i]; if (total>MAIN_ROW_COUNT) { top->start = selected; top->end = top->start + MAIN_ROW_COUNT; @@ -2601,8 +2581,8 @@ int main (int argc, char *argv[]) { else if (PAD_justRepeated(BTN_R1) && !PAD_isPressed(BTN_L1) && !PWR_ignoreSettingInput(BTN_R1, show_setting)) { // next alpha Entry* entry = static_cast(top->entries->items[selected]); int i = entry->alpha+1; - if (ialphas->count) { - selected = top->alphas->items[i]; + if (i<(int)top->alphas->size()) { + selected = (*top->alphas)[i]; if (total>MAIN_ROW_COUNT) { top->start = selected; top->end = top->start + MAIN_ROW_COUNT; From 477d08ccb633d840933de1ae92a01144f061193f Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Wed, 1 Jul 2026 17:37:49 +0200 Subject: [PATCH 07/77] nextui: back Array with std::vector Replaces the hand-rolled grow-by-doubling void** array with a std::vector under the hood. The public Array_* API and the typed wrappers (EntryArray/StringArray/DirectoryArray/RecentArray) stay exactly the same, so call sites only change ->items[i] to ->v[i] and ->count to ->count(). Semantics preserved on purpose: - Array_free stays container-only; the typed *Array_free wrappers keep freeing their elements first (mixing those up is a leak or a double free, so they're deliberately left untouched). - Array_yoink still moves the pointers over and frees only the source container. - Array_remove now no-ops on a missing item instead of walking off the end like the old while-loop did - strictly safer, same happy path. - EntryArray_sort keeps the same case-insensitive, not-stable ordering, now via std::sort instead of qsort. --- workspace/all/nextui/nextui.cpp | 261 +++++++++++++++----------------- 1 file changed, 119 insertions(+), 142 deletions(-) diff --git a/workspace/all/nextui/nextui.cpp b/workspace/all/nextui/nextui.cpp index 4bf8b96b6..cd56e0960 100644 --- a/workspace/all/nextui/nextui.cpp +++ b/workspace/all/nextui/nextui.cpp @@ -14,6 +14,7 @@ #include #include #include +#include extern "C" { #include @@ -39,75 +40,53 @@ extern "C" { /////////////////////////////////////// typedef struct Array { - int count; - int capacity; - void** items; + std::vector v; + int count() const { return (int)v.size(); } } Array; static Array* Array_new(void) { - Array* self = (Array*)(malloc(sizeof(Array))); - self->count = 0; - self->capacity = 8; - self->items = (void**)(malloc(sizeof(void*) * self->capacity)); - return self; + return new Array(); } static void Array_push(Array* self, void* item) { - if (self->count>=self->capacity) { - self->capacity *= 2; - self->items = (void**)(realloc(self->items, sizeof(void*) * self->capacity)); - } - self->items[self->count++] = item; + self->v.push_back(item); } static void Array_unshift(Array* self, void* item) { - if (self->count==0) return Array_push(self, item); - Array_push(self, NULL); // ensures we have enough capacity - for (int i=self->count-2; i>=0; i--) { - self->items[i+1] = self->items[i]; - } - self->items[0] = item; + self->v.insert(self->v.begin(), item); } static void* Array_pop(Array* self) { - if (self->count==0) return NULL; - return self->items[--self->count]; + if (self->v.empty()) return NULL; + void* item = self->v.back(); + self->v.pop_back(); + return item; } static void Array_remove(Array* self, void* item) { - if (self->count==0 || item == NULL) - return; - int i = 0; - while (self->items[i] != item) i++; - for (int j = i; j < self->count-1; j++) - self->items[j] = self->items[j+1]; - self->count--; + if (item == NULL) return; + auto it = std::find(self->v.begin(), self->v.end(), item); + if (it != self->v.end()) self->v.erase(it); } static void Array_reverse(Array* self) { - int end = self->count-1; - int mid = self->count/2; - for (int i=0; iitems[i]; - self->items[i] = self->items[end-i]; - self->items[end-i] = item; - } + std::reverse(self->v.begin(), self->v.end()); } static void Array_free(Array* self) { - free(self->items); - free(self); + // container only; the elements are owned elsewhere. The typed + // *Array_free wrappers below free their elements before calling us. + delete self; } static void Array_yoink(Array* self, Array* other) { - // append entries to self and take ownership - for (int i = 0; i < other->count; i++) - Array_push(self, other->items[i]); - Array_free(other); // `self` now owns the entries + // append other's entries to self and take ownership of them + self->v.insert(self->v.end(), other->v.begin(), other->v.end()); + Array_free(other); // container only; `self` now owns the entries } static int StringArray_indexOf(Array* self, char* str) { - for (int i=0; icount; i++) { - if (exactMatch(static_cast(self->items[i]), str)) return i; + for (int i=0; icount(); i++) { + if (exactMatch(static_cast(self->v[i]), str)) return i; } return -1; } static void StringArray_free(Array* self) { - for (int i=0; icount; i++) { - free(self->items[i]); + for (int i=0; icount(); i++) { + free(self->v[i]); } Array_free(self); } @@ -175,24 +154,22 @@ static void Entry_free(Entry* self) { } static int EntryArray_indexOf(Array* self, char* path) { - for (int i=0; icount; i++) { - Entry* entry = static_cast(self->items[i]); + for (int i=0; icount(); i++) { + Entry* entry = static_cast(self->v[i]); if (exactMatch(entry->path, path)) return i; } return -1; } -static int EntryArray_sortEntry(const void* a, const void* b) { - Entry* item1 = *(Entry**)a; - Entry* item2 = *(Entry**)b; - return strcasecmp(item1->name, item2->name); -} static void EntryArray_sort(Array* self) { - qsort(self->items, self->count, sizeof(void*), EntryArray_sortEntry); + // same not-stable, case-insensitive name ordering the old qsort gave us + std::sort(self->v.begin(), self->v.end(), [](void* a, void* b) { + return strcasecmp(static_cast(a)->name, static_cast(b)->name) < 0; + }); } static void EntryArray_free(Array* self) { - for (int i=0; icount; i++) { - Entry_free(static_cast(self->items[i])); + for (int i=0; icount(); i++) { + Entry_free(static_cast(self->v[i])); } Array_free(self); } @@ -262,8 +239,8 @@ static void Directory_index(Directory* self) { int resort = 0; int filter = 0; - for (int i = 0; i < self->entries->count; i++) { - Entry* entry = static_cast(self->entries->items[i]); + for (int i = 0; i < self->entries->count(); i++) { + Entry* entry = static_cast(self->entries->v[i]); char* filename = strrchr(entry->path, '/') + 1; const char* alias = Hash_get(map, filename); if (alias) { @@ -276,8 +253,8 @@ static void Directory_index(Directory* self) { if (filter) { Array* entries = Array_new(); - for (int i = 0; i < self->entries->count; i++) { - Entry* entry = static_cast(self->entries->items[i]); + for (int i = 0; i < self->entries->count(); i++) { + Entry* entry = static_cast(self->entries->v[i]); if (hide(entry->name)) { Entry_free(entry); // Ensure Entry_free handles all memory cleanup } else { @@ -294,8 +271,8 @@ static void Directory_index(Directory* self) { Entry* prior = NULL; int alpha = -1; int index = 0; - for (int i = 0; i < self->entries->count; i++) { - Entry* entry = static_cast(self->entries->items[i]); + for (int i = 0; i < self->entries->count(); i++) { + Entry* entry = static_cast(self->entries->v[i]); if (map) { char* filename = strrchr(entry->path, '/') + 1; const char* alias = Hash_get(map, filename); @@ -392,8 +369,8 @@ static void DirectoryArray_pop(Array* self) { Directory_free(static_cast(Array_pop(self))); } static void DirectoryArray_free(Array* self) { - for (int i=0; icount; i++) { - Directory_free(static_cast(self->items[i])); + for (int i=0; icount(); i++) { + Directory_free(static_cast(self->v[i])); } Array_free(self); } @@ -430,15 +407,15 @@ static void Recent_free(Recent* self) { } static int RecentArray_indexOf(Array* self, char* str) { - for (int i=0; icount; i++) { - Recent* item = static_cast(self->items[i]); + for (int i=0; icount(); i++) { + Recent* item = static_cast(self->v[i]); if (exactMatch(item->path, str)) return i; } return -1; } static void RecentArray_free(Array* self) { - for (int i=0; icount; i++) { - Recent_free(static_cast(self->items[i])); + for (int i=0; icount(); i++) { + Recent_free(static_cast(self->v[i])); } Array_free(self); } @@ -473,8 +450,8 @@ static int startgame = 0; static void saveRecents(void) { FILE* file = fopen(RECENT_PATH, "w"); if (file) { - for (int i=0; icount; i++) { - Recent* recent = static_cast(recents->items[i]); + for (int i=0; icount(); i++) { + Recent* recent = static_cast(recents->v[i]); fputs(recent->path, file); if (recent->alias) { fputs("\t", file); @@ -489,16 +466,16 @@ static void addRecent(char* path, char* alias) { path += strlen(SDCARD_PATH); // makes paths platform agnostic int id = RecentArray_indexOf(recents, path); if (id==-1) { // add - while (recents->count>=MAX_RECENTS) { + while (recents->count()>=MAX_RECENTS) { Recent_free(static_cast(Array_pop(recents))); } Array_unshift(recents, Recent_new(path, alias)); } else if (id>0) { // bump to top for (int i=id; i>0; i--) { - void* tmp = recents->items[i-1]; - recents->items[i-1] = recents->items[i]; - recents->items[i] = tmp; + void* tmp = recents->v[i-1]; + recents->v[i-1] = recents->v[i]; + recents->v[i] = tmp; } } saveRecents(); @@ -614,7 +591,7 @@ static int hasRecents(void) { char sd_path[256]; sprintf(sd_path, "%s%s", SDCARD_PATH, path); if (exists(sd_path)) { - if (recents->countcount()count; i++) { - char* path = static_cast(parent_paths->items[i]); + for (int i=0; icount(); i++) { + char* path = static_cast(parent_paths->v[i]); if (prefixMatch(path, parent_path)) { found = 1; break; @@ -720,8 +697,8 @@ static Array* getRoms() EntryArray_sort(emus); Entry* prev_entry = NULL; - for (int i = 0; i < emus->count; i++) { - Entry* entry = static_cast(emus->items[i]); + for (int i = 0; i < emus->count(); i++) { + Entry* entry = static_cast(emus->v[i]); if (prev_entry && exactMatch(prev_entry->name, entry->name)) { Entry_free(entry); continue; @@ -735,7 +712,7 @@ static Array* getRoms() // Handle mapping logic char map_path[256]; snprintf(map_path, sizeof(map_path), "%s/map.txt", ROMS_PATH); - if (entries->count > 0 && exists(map_path)) { + if (entries->count() > 0 && exists(map_path)) { FILE* file = fopen(map_path, "r"); if (file) { Hash* map = Hash_new(); @@ -757,8 +734,8 @@ static Array* getRoms() fclose(file); int resort = 0; - for (int i = 0; i < entries->count; i++) { - Entry* entry = static_cast(entries->items[i]); + for (int i = 0; i < entries->count(); i++) { + Entry* entry = static_cast(entries->v[i]); char* filename = strrchr(entry->path, '/') + 1; const char* alias = Hash_get(map, filename); if (alias) { @@ -801,7 +778,7 @@ static Array* getQuickEntries(void) { Array* entries = Array_new(); // We assume Menu_init was already called and populated this - if (recents && recents->count) + if (recents && recents->count()) Array_push(entries, Entry_newNamed(FAUX_RECENT_PATH, ENTRY_DIR, "Recents")); if (hasCollections()) @@ -854,7 +831,7 @@ static Array* getRoot(void) { // Handle collections if (hasCollections() && CFG_getShowCollections()) { - if (entries->count) { + if (entries->count()) { Array_push(root, Entry_new(COLLECTIONS_PATH, ENTRY_DIR)); } else { // No visible systems, promote collections to root Array *collections = getCollections(); @@ -893,8 +870,8 @@ static Entry* entryFromRecent(Recent* recent) static Array* getRecents(void) { Array* entries = Array_new(); - for (int i=0; icount; i++) { - Recent* recent = static_cast(recents->items[i]); + for (int i=0; icount(); i++) { + Recent* recent = static_cast(recents->v[i]); Entry *entry = entryFromRecent(recent); if(entry) Array_push(entries, entry); @@ -1338,7 +1315,7 @@ Array* pathToStack(const char* path) { // Always include root directory Directory* root_dir = Directory_new(SDCARD_PATH, 0); root_dir->start = 0; - root_dir->end = (root_dir->entries->count < MAIN_ROW_COUNT) ? root_dir->entries->count : MAIN_ROW_COUNT; + root_dir->end = (root_dir->entries->count() < MAIN_ROW_COUNT) ? root_dir->entries->count() : MAIN_ROW_COUNT; Array_push(array, root_dir); if (exactMatch(path, SDCARD_PATH)) return array; @@ -1373,22 +1350,22 @@ Array* pathToStack(const char* path) { if (strcmp(segment, PLATFORM) == 0) { // Merge with previous directory - if (array->count > 0) { + if (array->count() > 0) { // Remove the previous directory - Directory* last = (Directory*)array->items[array->count - 1]; + Directory* last = (Directory*)array->v[array->count() - 1]; Array_pop(array); Directory_free(last); // assuming you have a Directory_free // Replace with updated one using combined path Directory* merged = Directory_new(temp_path, 0); merged->start = 0; - merged->end = (merged->entries->count < MAIN_ROW_COUNT) ? merged->entries->count : MAIN_ROW_COUNT; + merged->end = (merged->entries->count() < MAIN_ROW_COUNT) ? merged->entries->count() : MAIN_ROW_COUNT; Array_push(array, merged); } } else { Directory* dir = Directory_new(temp_path, 0); dir->start = 0; - dir->end = (dir->entries->count < MAIN_ROW_COUNT) ? dir->entries->count : MAIN_ROW_COUNT; + dir->end = (dir->entries->count() < MAIN_ROW_COUNT) ? dir->entries->count() : MAIN_ROW_COUNT; Array_push(array, dir); } @@ -1429,8 +1406,8 @@ static void openDirectory(char* path, int auto_launch) { int selected = 0; int start = 0; int end = 0; - if (top && top->entries->count>0) { - if (restore_depth==stack->count && top->selected==restore_relative) { + if (top && top->entries->count()>0) { + if (restore_depth==stack->count() && top->selected==restore_relative) { selected = restore_selected; start = restore_start; end = restore_end; @@ -1439,7 +1416,7 @@ static void openDirectory(char* path, int auto_launch) { top = Directory_new(path, selected); top->start = start; - top->end = end ? end : ((top->entries->countentries->count : MAIN_ROW_COUNT); + top->end = end ? end : ((top->entries->count()entries->count() : MAIN_ROW_COUNT); Array_push(stack, top); } @@ -1452,7 +1429,7 @@ static void openDirectory(char* path, int auto_launch) { DirectoryArray_free(stack); stack = pathToStack(temp_path); - top = static_cast(stack->items[stack->count - 1]); + top = static_cast(stack->v[stack->count() - 1]); } } @@ -1461,8 +1438,8 @@ static void closeDirectory(void) { restore_start = top->start; restore_end = top->end; DirectoryArray_pop(stack); - restore_depth = stack->count; - top = static_cast(stack->items[stack->count-1]); + restore_depth = stack->count(); + top = static_cast(stack->v[stack->count()-1]); restore_relative = top->selected; } @@ -1556,7 +1533,7 @@ static void loadLast(void) { // call after loading root directory last_path[(slash-last_path)] = '\0'; } - while (last->count>0) { + while (last->count()>0) { char* path = static_cast(Array_pop(last)); if (!exactMatch(path, ROMS_PATH)) { // romsDir is effectively root as far as restoring state after a game char collated_path[256]; @@ -1567,8 +1544,8 @@ static void loadLast(void) { // call after loading root directory if (tmp) tmp[1] = '\0'; // 1 because we want to keep the opening parenthesis to avoid collating "Game Boy Color" and "Game Boy Advance" into "Game Boy" } - for (int i=0; ientries->count; i++) { - Entry* entry = static_cast(top->entries->items[i]); + for (int i=0; ientries->count(); i++) { + Entry* entry = static_cast(top->entries->v[i]); // NOTE: strlen() is required for collated_path, '\0' wasn't reading as NULL for some reason if (exactMatch(entry->path, path) || (strlen(collated_path) && prefixMatch(collated_path, entry->path)) || (prefixMatch(COLLECTIONS_PATH, full_path) && suffixMatch(filename, entry->path))) { @@ -1576,12 +1553,12 @@ static void loadLast(void) { // call after loading root directory if (i>=top->end) { top->start = i; top->end = top->start + MAIN_ROW_COUNT; - if (top->end>top->entries->count) { - top->end = top->entries->count; + if (top->end>top->entries->count()) { + top->end = top->entries->count(); top->start = top->end - MAIN_ROW_COUNT; } } - if (last->count==0 && !exactMatch(entry->path, FAUX_RECENT_PATH) && !(!exactMatch(entry->path, COLLECTIONS_PATH) && prefixMatch(COLLECTIONS_PATH, entry->path))) break; // don't show contents of auto-launch dirs + if (last->count()==0 && !exactMatch(entry->path, FAUX_RECENT_PATH) && !(!exactMatch(entry->path, COLLECTIONS_PATH) && prefixMatch(COLLECTIONS_PATH, entry->path))) break; // don't show contents of auto-launch dirs if (entry->type==ENTRY_DIR) { openDirectory(entry->path, 0); @@ -1595,8 +1572,8 @@ static void loadLast(void) { // call after loading root directory StringArray_free(last); - if (top->selected >= 0 && top->selected < top->entries->count) { - Entry* selected_entry = static_cast(top->entries->items[top->selected]); + if (top->selected >= 0 && top->selected < top->entries->count()) { + Entry* selected_entry = static_cast(top->entries->v[top->selected]); readyResume(selected_entry); } } @@ -2275,7 +2252,7 @@ int main (int argc, char *argv[]) { int qm_col = 0; int qm_slot = 0; int qm_shift = 0; - int qm_slots = QUICK_SWITCHER_COUNT > quick->count ? quick->count : QUICK_SWITCHER_COUNT; + int qm_slots = QUICK_SWITCHER_COUNT > quick->count() ? quick->count() : QUICK_SWITCHER_COUNT; // LOG_info("- menu init: %lu\n", SDL_GetTicks() - main_begin); int lastScreen = SCREEN_OFF; @@ -2332,7 +2309,7 @@ int main (int argc, char *argv[]) { PAD_poll(); int selected = top->selected; - int total = top->entries->count; + int total = top->entries->count(); PWR_update(&dirty, &show_setting, NULL, NULL); @@ -2354,7 +2331,7 @@ int main (int argc, char *argv[]) { int gsanimdir = ANIM_NONE; if (currentScreen == SCREEN_QUICKMENU) { - int qm_total = qm_row == 0 ? quick->count : quickActions->count; + int qm_total = qm_row == 0 ? quick->count() : quickActions->count(); if (PAD_justPressed(BTN_B) || PAD_tappedMenu(now)) { currentScreen = SCREEN_GAMELIST; @@ -2362,10 +2339,10 @@ int main (int argc, char *argv[]) { dirty = 1; } else if (PAD_justReleased(BTN_A)) { - Entry* selected = static_cast(qm_row == 0 ? quick->items[qm_col] : quickActions->items[qm_col]); + Entry* selected = static_cast(qm_row == 0 ? quick->v[qm_col] : quickActions->v[qm_col]); if(selected->type != ENTRY_DIP) { currentScreen = SCREEN_GAMELIST; - total = top->entries->count; + total = top->entries->count(); // prevent restoring list state, game list screen currently isnt our nav origin top->selected = 0; top->start = 0; @@ -2449,29 +2426,29 @@ int main (int argc, char *argv[]) { dirty = 1; folderbgchanged = 1; // The background painting code is a clusterfuck, just force a repaint here } - else if (recents->count > 0 && PAD_justReleased(BTN_A)) { + else if (recents->count() > 0 && PAD_justReleased(BTN_A)) { // this will drop us back into game switcher after leaving the game putFile(GAME_SWITCHER_PERSIST_PATH, "unused"); startgame = 1; - Entry *selectedEntry = entryFromRecent(static_cast(recents->items[switcher_selected])); + Entry *selectedEntry = entryFromRecent(static_cast(recents->v[switcher_selected])); should_resume = can_resume; Entry_open(selectedEntry); dirty = 1; Entry_free(selectedEntry); } - else if (recents->count > 0 && PAD_justReleased(BTN_Y)) { + else if (recents->count() > 0 && PAD_justReleased(BTN_Y)) { // remove - Recent* recentEntry = static_cast(recents->items[switcher_selected--]); + Recent* recentEntry = static_cast(recents->v[switcher_selected--]); Array_remove(recents, recentEntry); Recent_free(recentEntry); saveRecents(); if(switcher_selected < 0) - switcher_selected = recents->count - 1; // wrap + switcher_selected = recents->count() - 1; // wrap dirty = 1; } else if (PAD_justPressed(BTN_RIGHT)) { switcher_selected++; - if(switcher_selected == recents->count) + if(switcher_selected == recents->count()) switcher_selected = 0; // wrap dirty = 1; gsanimdir = SLIDE_LEFT; @@ -2479,7 +2456,7 @@ int main (int argc, char *argv[]) { else if (PAD_justPressed(BTN_LEFT)) { switcher_selected--; if(switcher_selected < 0) - switcher_selected = recents->count - 1; // wrap + switcher_selected = recents->count() - 1; // wrap dirty = 1; gsanimdir = SLIDE_RIGHT; } @@ -2566,7 +2543,7 @@ int main (int argc, char *argv[]) { } if (PAD_justRepeated(BTN_L1) && !PAD_isPressed(BTN_R1) && !PWR_ignoreSettingInput(BTN_L1, show_setting)) { // previous alpha - Entry* entry = static_cast(top->entries->items[selected]); + Entry* entry = static_cast(top->entries->v[selected]); int i = entry->alpha-1; if (i>=0) { selected = (*top->alphas)[i]; @@ -2579,7 +2556,7 @@ int main (int argc, char *argv[]) { } } else if (PAD_justRepeated(BTN_R1) && !PAD_isPressed(BTN_L1) && !PWR_ignoreSettingInput(BTN_R1, show_setting)) { // next alpha - Entry* entry = static_cast(top->entries->items[selected]); + Entry* entry = static_cast(top->entries->v[selected]); int i = entry->alpha+1; if (i<(int)top->alphas->size()) { selected = (*top->alphas)[i]; @@ -2597,7 +2574,7 @@ int main (int argc, char *argv[]) { dirty = 1; } - Entry* entry = static_cast(top->entries->items[top->selected]); + Entry* entry = static_cast(top->entries->v[top->selected]); if (dirty && total>0) readyResume(entry); @@ -2612,19 +2589,19 @@ int main (int argc, char *argv[]) { Entry_open(entry); if(entry->type == ENTRY_DIR) { animationdirection = SLIDE_LEFT; - total = top->entries->count; + total = top->entries->count(); } dirty = 1; - if (total>0) readyResume(static_cast(top->entries->items[top->selected])); + if (total>0) readyResume(static_cast(top->entries->v[top->selected])); } - else if (PAD_justPressed(BTN_B) && stack->count>1) { + else if (PAD_justPressed(BTN_B) && stack->count()>1) { closeDirectory(); animationdirection = SLIDE_RIGHT; - total = top->entries->count; + total = top->entries->count(); dirty = 1; - if (total>0) readyResume(static_cast(top->entries->items[top->selected])); + if (total>0) readyResume(static_cast(top->entries->v[top->selected])); } } @@ -2658,7 +2635,7 @@ int main (int argc, char *argv[]) { GFX_clearLayers(LAYER_THUMBNAIL); } - Entry* current = static_cast(qm_row == 0 ? quick->items[qm_col] : quickActions->items[qm_col]); + Entry* current = static_cast(qm_row == 0 ? quick->v[qm_col] : quickActions->v[qm_col]); char newBgPath[MAX_PATH]; char fallbackBgPath[MAX_PATH]; @@ -2711,10 +2688,10 @@ int main (int argc, char *argv[]) { // just to keep selection visible. // every display should be able to fit three items, we shift horizontally to accomodate. ox -= qm_shift * (item_size + SCALE1(MENU_ITEM_MARGIN)); - for (int c = 0; c < quick->count; c++) + for (int c = 0; c < quick->count(); c++) { SDL_Rect item_rect = {ox, oy, item_size, item_size}; - Entry* item = static_cast(quick->items[c]); + Entry* item = static_cast(quick->v[c]); SDL_Color text_color = uintToColour(THEME_COLOR4_255); uint32_t item_color = THEME_COLOR3; @@ -2758,11 +2735,11 @@ int main (int argc, char *argv[]) { // secondary ox = SCALE1(PADDING + MENU_MARGIN_X); - ox += (screen->w - SCALE1(PADDING + MENU_MARGIN_X + MENU_MARGIN_X + PADDING) - SCALE1(quickActions->count * PILL_SIZE) - SCALE1((quickActions->count - 1) * MENU_TOGGLE_MARGIN))/2; + ox += (screen->w - SCALE1(PADDING + MENU_MARGIN_X + MENU_MARGIN_X + PADDING) - SCALE1(quickActions->count() * PILL_SIZE) - SCALE1((quickActions->count() - 1) * MENU_TOGGLE_MARGIN))/2; oy = SCALE1(PADDING + PILL_SIZE + BUTTON_MARGIN + MENU_MARGIN_Y + MENU_LINE_MARGIN) + item_size + item_extra_y / 2; - for (int c = 0; c < quickActions->count; c++) { + for (int c = 0; c < quickActions->count(); c++) { SDL_Rect item_rect = {ox, oy, SCALE1(PILL_SIZE), SCALE1(PILL_SIZE)}; - Entry* item = static_cast(quickActions->items[c]); + Entry* item = static_cast(quickActions->v[c]); SDL_Color text_color = uintToColour(THEME_COLOR4_255); uint32_t item_color = THEME_COLOR3; @@ -2820,8 +2797,8 @@ int main (int argc, char *argv[]) { oy = 0; // For all recents with resumable state (i.e. has savegame), show game switcher carousel - if(recents->count > 0) { - Entry *selectedEntry = entryFromRecent(static_cast(recents->items[switcher_selected])); + if(recents->count() > 0) { + Entry *selectedEntry = entryFromRecent(static_cast(recents->v[switcher_selected])); readyResume(selectedEntry); // title pill { @@ -2946,7 +2923,7 @@ int main (int argc, char *argv[]) { } else { // if currentscreen == SCREEN_GAMELIST // background and game art file path stuff - Entry* entry = static_cast(top->entries->items[top->selected]); + Entry* entry = static_cast(top->entries->v[top->selected]); assert(entry); char tmp_path[MAX_PATH]; strncpy(tmp_path, entry->path, sizeof(tmp_path) - 1); @@ -2971,7 +2948,7 @@ int main (int argc, char *argv[]) { static int lastType = -1; // this is only a choice on the root folder - list_show_entry_names = stack->count > 1 || CFG_getShowFolderNamesAtRoot(); + list_show_entry_names = stack->count() > 1 || CFG_getShowFolderNamesAtRoot(); // load folder background char defaultBgPath[512]; @@ -3032,12 +3009,12 @@ int main (int argc, char *argv[]) { NULL }, 0, screen, 0); if (total==0) { - if (stack->count>1) { + if (stack->count()>1) { GFX_blitButtonGroup((char**)(const char*[]){ "B","BACK", NULL }, 0, screen, 1); } } else { - if (stack->count>1) { + if (stack->count()>1) { GFX_blitButtonGroup((char**)(const char*[]){ "B","BACK", "A","OPEN", NULL }, 1, screen, 1); } else { @@ -3052,13 +3029,13 @@ int main (int argc, char *argv[]) { targetY = selected_row * PILL_SIZE; SDL_Color text_color = uintToColour(THEME_COLOR4_255); // list text color for (int i = top->start, j = 0; i < top->end; i++, j++) { - Entry* entry = static_cast(top->entries->items[i]); + Entry* entry = static_cast(top->entries->v[i]); char* entry_name = entry->name; char* entry_unique = entry->unique; int available_width = MAX(0,(had_thumb ? ox + SCALE1(BUTTON_MARGIN) : screen->w - SCALE1(BUTTON_MARGIN)) - SCALE1(PADDING * 2)); bool row_is_selected = (j == selected_row); bool row_is_top = (i == top->start); - bool row_has_moved = (previous_row != selected_row || previous_depth != stack->count); + bool row_has_moved = (previous_row != selected_row || previous_depth != stack->count()); if (row_is_top && !(had_thumb)) available_width -= ow; @@ -3088,7 +3065,7 @@ int main (int argc, char *argv[]) { if (row_is_selected) { is_scrolling = list_show_entry_names && GFX_textShouldScroll(font.large,display_name, max_width - SCALE1(BUTTON_PADDING*2), fontMutex); GFX_resetScrollText(); - bool should_animate = previous_depth == stack->count; + bool should_animate = previous_depth == stack->count(); SDL_LockMutex(animMutex); if(globalpill) { SDL_FreeSurface(globalpill); @@ -3138,7 +3115,7 @@ int main (int argc, char *argv[]) { } previous_row = selected_row; - previous_depth = stack->count; + previous_depth = stack->count(); } else { // TODO: for some reason screen's dimensions end up being 0x0 in GFX_blitMessage... @@ -3305,7 +3282,7 @@ int main (int argc, char *argv[]) { if (currentScreen != SCREEN_GAMESWITCHER && currentScreen != SCREEN_QUICKMENU) { if(is_scrolling && pillanimdone && currentAnimQueueSize < 1) { int ow = GFX_blitHardwareGroup(screen, show_setting); - Entry* entry = static_cast(top->entries->items[top->selected]); + Entry* entry = static_cast(top->entries->v[top->selected]); trimSortingMeta(&entry->name); char* entry_text = entry->name; if (entry->unique) { @@ -3385,7 +3362,7 @@ int main (int argc, char *argv[]) { if (has_hdmi!=had_hdmi) { had_hdmi = has_hdmi; - Entry* entry = static_cast(top->entries->items[top->selected]); + Entry* entry = static_cast(top->entries->v[top->selected]); LOG_info("restarting after HDMI change... (%s)\n", entry->path); saveLast(entry->path); // NOTE: doesn't work in Recents (by design) sleep(4); From ec398cc69068dd60c5c810b715025d17d29878cd Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Wed, 1 Jul 2026 17:51:59 +0200 Subject: [PATCH 08/77] nextui: drop leaked strdup in Hash_set callers Hash_set copies its value into a std::string now (since the Hash became an unordered_map), so the strdup() the two callers passed in was never freed - a small leak on every config/map line parsed. The strdup was a leftover from the old Hash that stored the raw pointer. Just pass the value straight through. --- workspace/all/nextui/nextui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/workspace/all/nextui/nextui.cpp b/workspace/all/nextui/nextui.cpp index cd56e0960..14d84575d 100644 --- a/workspace/all/nextui/nextui.cpp +++ b/workspace/all/nextui/nextui.cpp @@ -232,7 +232,7 @@ static void Directory_index(Directory* self) { tmp[0] = '\0'; char* key = line; char* value = tmp + 1; - Hash_set(map, key, strdup(value)); // Ensure strdup to store value properly + Hash_set(map, key, value); // Hash_set copies into a std::string; no strdup needed } } fclose(file); @@ -728,7 +728,7 @@ static Array* getRoms() *tmp = '\0'; char* key = line; char* value = tmp + 1; - Hash_set(map, key, strdup(value)); // Ensure strdup + Hash_set(map, key, value); // Hash_set copies into a std::string; no strdup needed } } fclose(file); From a0be0f686b7d911f18f9d9daf9092c281748ea58 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Wed, 1 Jul 2026 17:56:39 +0200 Subject: [PATCH 09/77] nextui: bound the string writes with a fixed-array target Swaps sprintf/strcpy for snprintf on every target that's a stack char array, so a long ROM name or path from the SD card truncates instead of smashing the 256-byte buffer. sizeof(buf) is provably right here since these targets are only ever declared as arrays. Also rewrote getUniqueName - it built ' ()' with a four-step strcpy-via-moving-pointer dance and computed a filename it never used. That's just one snprintf now. Left alone for a careful follow-up: the writes that target a pointer or a function param (cue_path, the tmp cursor, cmd, etc.) - sizeof would be the pointer size there, so those need their real buffer size worked out per caller. --- workspace/all/nextui/nextui.cpp | 86 +++++++++++++++------------------ 1 file changed, 39 insertions(+), 47 deletions(-) diff --git a/workspace/all/nextui/nextui.cpp b/workspace/all/nextui/nextui.cpp index 14d84575d..f4969f2fa 100644 --- a/workspace/all/nextui/nextui.cpp +++ b/workspace/all/nextui/nextui.cpp @@ -195,18 +195,10 @@ static int getIndexChar(char* str) { } static void getUniqueName(Entry* entry, char* out_name) { - char* filename = strrchr(entry->path, '/')+1; + // out_name is a char[256] at every caller char emu_tag[256]; getEmuName(entry->path, emu_tag); - - char *tmp; - strcpy(out_name, entry->name); - tmp = out_name + strlen(out_name); - strcpy(tmp, " ("); - tmp = out_name + strlen(out_name); - strcpy(tmp, emu_tag); - tmp = out_name + strlen(out_name); - strcpy(tmp, ")"); + snprintf(out_name, 256, "%s (%s)", entry->name, emu_tag); } static void Directory_index(Directory* self) { @@ -215,7 +207,7 @@ static void Directory_index(Directory* self) { Hash* map = NULL; char map_path[256]; - sprintf(map_path, "%s/map.txt", is_collection ? COLLECTIONS_PATH : self->path); + snprintf(map_path, sizeof(map_path), "%s/map.txt", is_collection ? COLLECTIONS_PATH : self->path); if (exists(map_path)) { FILE* file = fopen(map_path, "r"); @@ -390,7 +382,7 @@ static Recent* Recent_new(char* path, char* alias) { Recent* self = (Recent*)(malloc(sizeof(Recent))); char sd_path[256]; // only need to get emu name - sprintf(sd_path, "%s%s", SDCARD_PATH, path); + snprintf(sd_path, sizeof(sd_path), "%s%s", SDCARD_PATH, path); char emu_name[256]; getEmuName(sd_path, emu_name); @@ -485,17 +477,17 @@ static Entry* entryFromPakName(char* pak_name) { char pak_path[256]; // Check in Tools - sprintf(pak_path, "%s/Tools/%s/%s.pak", SDCARD_PATH, PLATFORM, pak_name); + snprintf(pak_path, sizeof(pak_path), "%s/Tools/%s/%s.pak", SDCARD_PATH, PLATFORM, pak_name); if(exists(pak_path)) return Entry_newNamed(pak_path, ENTRY_PAK, pak_name); // Check in Emus - sprintf(pak_path, "%s/Emus/%s.pak", PAKS_PATH, pak_name); + snprintf(pak_path, sizeof(pak_path), "%s/Emus/%s.pak", PAKS_PATH, pak_name); if(exists(pak_path)) return Entry_newNamed(pak_path, ENTRY_PAK, pak_name); // Check in platform Emus - sprintf(pak_path, "%s/Emus/%s/%s.pak", SDCARD_PATH, PLATFORM, pak_name); + snprintf(pak_path, sizeof(pak_path), "%s/Emus/%s/%s.pak", SDCARD_PATH, PLATFORM, pak_name); if(exists(pak_path)) return Entry_newNamed(pak_path, ENTRY_PAK, pak_name); @@ -504,10 +496,10 @@ static Entry* entryFromPakName(char* pak_name) static int hasEmu(char* emu_name) { char pak_path[256]; - sprintf(pak_path, "%s/Emus/%s.pak/launch.sh", PAKS_PATH, emu_name); + snprintf(pak_path, sizeof(pak_path), "%s/Emus/%s.pak/launch.sh", PAKS_PATH, emu_name); if (exists(pak_path)) return 1; - sprintf(pak_path, "%s/Emus/%s/%s.pak/launch.sh", SDCARD_PATH, PLATFORM, emu_name); + snprintf(pak_path, sizeof(pak_path), "%s/Emus/%s/%s.pak/launch.sh", SDCARD_PATH, PLATFORM, emu_name); return exists(pak_path); } static int hasCue(char* dir_path, char* cue_path) { // NOTE: dir_path not rom_path @@ -524,7 +516,7 @@ static int hasM3u(char* rom_path, char* m3u_path) { // NOTE: rom_path not dir_pa // path to parent directory char base_path[256]; - strcpy(base_path, m3u_path); + snprintf(base_path, sizeof(base_path), "%s", m3u_path); tmp = strrchr(m3u_path, '/'); tmp[0] = '\0'; @@ -589,7 +581,7 @@ static int hasRecents(void) { } char sd_path[256]; - sprintf(sd_path, "%s%s", SDCARD_PATH, path); + snprintf(sd_path, sizeof(sd_path), "%s%s", SDCARD_PATH, path); if (exists(sd_path)) { if (recents->count()path); + snprintf(sd_path, sizeof(sd_path), "%s%s", SDCARD_PATH, recent->path); int type = suffixMatch(".pak", sd_path) ? ENTRY_PAK : ENTRY_ROM; // ??? Entry* entry = Entry_new(sd_path, type); if (recent->alias) { @@ -890,7 +882,7 @@ static Array* getCollection(char* path) { if (strlen(line)==0) continue; // skip empty lines char sd_path[256]; - sprintf(sd_path, "%s%s", SDCARD_PATH, line); + snprintf(sd_path, sizeof(sd_path), "%s%s", SDCARD_PATH, line); if (exists(sd_path)) { int type = suffixMatch(".pak", sd_path) ? ENTRY_PAK : ENTRY_ROM; // ??? Array_push(entries, Entry_new(sd_path, type)); @@ -913,7 +905,7 @@ static Array* getDiscs(char* path){ Array* entries = Array_new(); char base_path[256]; - strcpy(base_path, path); + snprintf(base_path, sizeof(base_path), "%s", path); char* tmp = strrchr(base_path, '/') + 1; tmp[0] = '\0'; @@ -948,7 +940,7 @@ static int getFirstDisc(char* m3u_path, char* disc_path) { // based on getDiscs( int found = 0; char base_path[256]; - strcpy(base_path, m3u_path); + snprintf(base_path, sizeof(base_path), "%s", m3u_path); char* tmp = strrchr(base_path, '/') + 1; tmp[0] = '\0'; @@ -976,7 +968,7 @@ static void addEntries(Array* entries, char* path) { struct dirent *dp; char* tmp; char full_path[256]; - sprintf(full_path, "%s/", path); + snprintf(full_path, sizeof(full_path), "%s/", path); tmp = full_path + strlen(full_path); while((dp = readdir(dh)) != NULL) { if (hide(dp->d_name)) continue; @@ -1009,7 +1001,7 @@ static void addEntries(Array* entries, char* path) { static int isConsoleDir(char* path) { char* tmp; char parent_dir[256]; - strcpy(parent_dir, path); + snprintf(parent_dir, sizeof(parent_dir), "%s", path); tmp = strrchr(parent_dir, '/'); tmp[0] = '\0'; @@ -1021,7 +1013,7 @@ static Array* getEntries(char* path){ if (isConsoleDir(path)) { // top-level console folder, might collate char collated_path[256]; - strcpy(collated_path, path); + snprintf(collated_path, sizeof(collated_path), "%s", path); char* tmp = strrchr(collated_path, '('); // 1 because we want to keep the opening parenthesis to avoid collating "Game Boy Color" and "Game Boy Advance" into "Game Boy" // but conditional so we can continue to support a bare tag name as a folder name @@ -1031,7 +1023,7 @@ static Array* getEntries(char* path){ if (dh!=NULL) { struct dirent *dp; char full_path[256]; - sprintf(full_path, "%s/", ROMS_PATH); + snprintf(full_path, sizeof(full_path), "%s/", ROMS_PATH); tmp = full_path + strlen(full_path); // while loop so we can collate paths, see above while((dp = readdir(dh)) != NULL) { @@ -1128,9 +1120,9 @@ static void readyResumePath(char* rom_path, int type) { char rom_file[256]; tmp = strrchr(path, '/') + 1; - strcpy(rom_file, tmp); + snprintf(rom_file, sizeof(rom_file), "%s", tmp); - sprintf(slot_path, "%s/.minui/%s/%s.txt", SHARED_USERDATA_PATH, emu_name, rom_file); // /.userdata/.minui//.ext.txt + snprintf(slot_path, sizeof(slot_path), "%s/.minui/%s/%s.txt", SHARED_USERDATA_PATH, emu_name, rom_file); // /.userdata/.minui//.ext.txt can_resume = exists(slot_path); // slot_path contains a single integer representing the last used slot @@ -1138,7 +1130,7 @@ static void readyResumePath(char* rom_path, int type) { char slot[16]; getFile(slot_path, slot, 16); int s = atoi(slot); - sprintf(preview_path, "%s/.minui/%s/%s.%0d.bmp", SHARED_USERDATA_PATH, emu_name, rom_file, s); // /.userdata/.minui//.ext..bmp + snprintf(preview_path, sizeof(preview_path), "%s/.minui/%s/%s.%0d.bmp", SHARED_USERDATA_PATH, emu_name, rom_file, s); // /.userdata/.minui//.ext..bmp has_preview = exists(preview_path); } } @@ -1161,7 +1153,7 @@ static int autoResume(void) { // make sure rom still exists char sd_path[256]; - sprintf(sd_path, "%s%s", SDCARD_PATH, path); + snprintf(sd_path, sizeof(sd_path), "%s%s", SDCARD_PATH, path); if (!exists(sd_path)) return 0; // make sure emu still exists @@ -1176,7 +1168,7 @@ static int autoResume(void) { // putFile(LAST_PATH, FAUX_RECENT_PATH); // saveLast() will crash here because top is NULL char act[256]; - sprintf(act, "gametimectl.elf start '%s'", escapeSingleQuotes(sd_path)); + snprintf(act, sizeof(act), "gametimectl.elf start '%s'", escapeSingleQuotes(sd_path)); system(act); char cmd[256]; @@ -1203,13 +1195,13 @@ static void openRom(char* path, char* last) { LOG_info("openRom(%s,%s)\n", path, last); char sd_path[256]; - strcpy(sd_path, path); + snprintf(sd_path, sizeof(sd_path), "%s", path); char m3u_path[256]; int has_m3u = hasM3u(sd_path, m3u_path); char recent_path[256]; - strcpy(recent_path, has_m3u ? m3u_path : sd_path); + snprintf(recent_path, sizeof(recent_path), "%s", has_m3u ? m3u_path : sd_path); if (has_m3u && suffixMatch(".m3u", sd_path)) { getFirstDisc(m3u_path, sd_path); @@ -1226,19 +1218,19 @@ static void openRom(char* path, char* last) { if (has_m3u) { char rom_file[256]; - strcpy(rom_file, strrchr(m3u_path, '/') + 1); + snprintf(rom_file, sizeof(rom_file), "%s", strrchr(m3u_path, '/') + 1); // get disc for state char disc_path_path[256]; - sprintf(disc_path_path, "%s/.minui/%s/%s.%s.txt", SHARED_USERDATA_PATH, emu_name, rom_file, slot); // /.userdata/arm-480/.minui//.ext.0.txt + snprintf(disc_path_path, sizeof(disc_path_path), "%s/.minui/%s/%s.%s.txt", SHARED_USERDATA_PATH, emu_name, rom_file, slot); // /.userdata/arm-480/.minui//.ext.0.txt if (exists(disc_path_path)) { // switch to disc path char disc_path[256]; getFile(disc_path_path, disc_path, 256); - if (disc_path[0]=='/') strcpy(sd_path, disc_path); // absolute + if (disc_path[0]=='/') snprintf(sd_path, sizeof(sd_path), "%s", disc_path); // absolute else { // relative - strcpy(sd_path, m3u_path); + snprintf(sd_path, sizeof(sd_path), "%s", m3u_path); char* tmp = strrchr(sd_path, '/') + 1; strcpy(tmp, disc_path); } @@ -1255,7 +1247,7 @@ static void openRom(char* path, char* last) { addRecent(recent_path, recent_alias); // yiiikes saveLast(last==NULL ? sd_path : last); char act[256]; - sprintf(act, "gametimectl.elf start '%s'", escapeSingleQuotes(sd_path)); + snprintf(act, sizeof(act), "gametimectl.elf start '%s'", escapeSingleQuotes(sd_path)); system(act); char cmd[256]; // dont escape sd_path again because it was already escaped for gametimectl and function modifies input str aswell @@ -1321,7 +1313,7 @@ Array* pathToStack(const char* path) { if (exactMatch(path, SDCARD_PATH)) return array; char temp_path[PATH_MAX]; - strcpy(temp_path, SDCARD_PATH); + snprintf(temp_path, sizeof(temp_path), "%s", SDCARD_PATH); size_t current_len = strlen(SDCARD_PATH); const char* cursor = path + current_len; @@ -1423,7 +1415,7 @@ static void openDirectory(char* path, int auto_launch) { else { // keep a copy of path, which might be a reference into stack which is about to be freed char temp_path[256]; - strcpy(temp_path, path); + snprintf(temp_path, sizeof(temp_path), "%s", path); // construct a fresh stack by walking upwards until SDCARD_ROOT DirectoryArray_free(stack); @@ -1482,7 +1474,7 @@ static void Entry_open(Entry* self) { if (tmp) strcpy(filename, tmp+1); char last_path[256]; - sprintf(last_path, "%s/%s", top->path, filename); + snprintf(last_path, sizeof(last_path), "%s/%s", top->path, filename); last = last_path; } openRom(self->path, last); @@ -1518,7 +1510,7 @@ static void loadLast(void) { // call after loading root directory getFile(LAST_PATH, last_path, 256); char full_path[256]; - strcpy(full_path, last_path); + snprintf(full_path, sizeof(full_path), "%s", last_path); char* tmp; char filename[256]; @@ -1539,7 +1531,7 @@ static void loadLast(void) { // call after loading root directory char collated_path[256]; collated_path[0] = '\0'; if (suffixMatch(")", path) && isConsoleDir(path)) { - strcpy(collated_path, path); + snprintf(collated_path, sizeof(collated_path), "%s", path); tmp = strrchr(collated_path, '('); if (tmp) tmp[1] = '\0'; // 1 because we want to keep the opening parenthesis to avoid collating "Game Boy Color" and "Game Boy Advance" into "Game Boy" } @@ -2639,10 +2631,10 @@ int main (int argc, char *argv[]) { char newBgPath[MAX_PATH]; char fallbackBgPath[MAX_PATH]; - sprintf(newBgPath, SDCARD_PATH "/.media/quick_%s%s.png", current->name, + snprintf(newBgPath, sizeof(newBgPath), SDCARD_PATH "/.media/quick_%s%s.png", current->name, !strcmp(current->name,"Wifi") && !CFG_getWifi() || // wifi or wifi_off, based on state !strcmp(current->name,"Bluetooth") && !CFG_getBluetooth() ? "_off" : ""); // bluetooth or bluetooth_off, based on state - sprintf(fallbackBgPath, SDCARD_PATH "/.media/quick.png"); + snprintf(fallbackBgPath, sizeof(fallbackBgPath), SDCARD_PATH "/.media/quick.png"); // background if(!exists(newBgPath)) @@ -2706,7 +2698,7 @@ int main (int argc, char *argv[]) { GFX_blitRectColor(ASSET_STATE_BG, screen, &item_rect, item_color); char icon_path[MAX_PATH]; - sprintf(icon_path, SDCARD_PATH "/.system/res/%s@%ix.png", item->name, FIXED_SCALE); + snprintf(icon_path, sizeof(icon_path), SDCARD_PATH "/.system/res/%s@%ix.png", item->name, FIXED_SCALE); SDL_Surface* bmp = IMG_Load(icon_path); if(bmp) { SDL_Surface* converted = SDL_ConvertSurfaceFormat(bmp, screen->format->format, 0); From d014ff8946eb5b3bbd85a39f788b9266e475ba4d Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Wed, 1 Jul 2026 18:11:07 +0200 Subject: [PATCH 10/77] nextui: bound the remaining pointer and cursor string writes Finishes the string-safety pass - nextui.cpp now has zero raw sprintf/strcpy/strcat. These were the trickier ones sizeof can't handle: - Function params (cue_path, m3u_path, disc_path): every caller passes a char[256], so they're bounded to 256 with a comment noting why. - The tmp write-cursor pattern (build a path prefix, then strcpy a readdir name or an extension onto the tail): bounded to the space actually left in the parent buffer, i.e. SIZE - (tmp - parent). The readdir-name appends were the real overflow risk - a long filename could run past the 256-byte path buffer. All behaviour-preserving for normal-length paths; a too-long path now truncates instead of corrupting the stack. --- workspace/all/nextui/nextui.cpp | 56 ++++++++++++++++----------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/workspace/all/nextui/nextui.cpp b/workspace/all/nextui/nextui.cpp index f4969f2fa..d25059af1 100644 --- a/workspace/all/nextui/nextui.cpp +++ b/workspace/all/nextui/nextui.cpp @@ -504,13 +504,13 @@ static int hasEmu(char* emu_name) { } static int hasCue(char* dir_path, char* cue_path) { // NOTE: dir_path not rom_path char* tmp = strrchr(dir_path, '/') + 1; // folder name - sprintf(cue_path, "%s/%s.cue", dir_path, tmp); + snprintf(cue_path, 256, "%s/%s.cue", dir_path, tmp); // cue_path is a char[256] at both callers return exists(cue_path); } static int hasM3u(char* rom_path, char* m3u_path) { // NOTE: rom_path not dir_path char* tmp; - strcpy(m3u_path, rom_path); + snprintf(m3u_path, 256, "%s", rom_path); // m3u_path is a char[256] at both callers tmp = strrchr(m3u_path, '/') + 1; tmp[0] = '\0'; @@ -524,15 +524,15 @@ static int hasM3u(char* rom_path, char* m3u_path) { // NOTE: rom_path not dir_pa // get parent directory name char dir_name[256]; tmp = strrchr(m3u_path, '/'); - strcpy(dir_name, tmp); + snprintf(dir_name, sizeof(dir_name), "%s", tmp); // dir_name is also our m3u file name tmp = m3u_path + strlen(m3u_path); - strcpy(tmp, dir_name); + snprintf(tmp, 256 - (tmp - m3u_path), "%s", dir_name); // add extension tmp = m3u_path + strlen(m3u_path); - strcpy(tmp, ".m3u"); + snprintf(tmp, 256 - (tmp - m3u_path), "%s", ".m3u"); return exists(m3u_path); } @@ -554,7 +554,7 @@ static int hasRecents(void) { Array_push(recents, recent); char parent_path[256]; - strcpy(parent_path, disc_path); + snprintf(parent_path, sizeof(parent_path), "%s", disc_path); char* tmp = strrchr(parent_path, '/') + 1; tmp[0] = '\0'; Array_push(parent_paths, strdup(parent_path)); @@ -588,7 +588,7 @@ static int hasRecents(void) { char m3u_path[256]; if (hasM3u(sd_path, m3u_path)) { // TODO: this might tank launch speed char parent_path[256]; - strcpy(parent_path, path); + snprintf(parent_path, sizeof(parent_path), "%s", path); char* tmp = strrchr(parent_path, '/') + 1; tmp[0] = '\0'; @@ -646,7 +646,7 @@ static int hasRoms(char* dir_name) { if (!hasEmu(emu_name)) return has; // check for at least one non-hidden file (we're going to assume it's a rom) - sprintf(rom_path, "%s/%s/", ROMS_PATH, dir_name); + snprintf(rom_path, sizeof(rom_path), "%s/%s/", ROMS_PATH, dir_name); DIR *dh = opendir(rom_path); if (dh!=NULL) { struct dirent *dp; @@ -681,7 +681,7 @@ static Array* getRoms() while ((dp = readdir(dh)) != NULL) { if (hide(dp->d_name)) continue; if (hasRoms(dp->d_name)) { - strcpy(tmp, dp->d_name); + snprintf(tmp, sizeof(full_path) - (tmp - full_path), "%s", dp->d_name); Array_push(emus, Entry_new(full_path, ENTRY_DIR)); } } @@ -756,7 +756,7 @@ static Array* getCollections(void) Array* collections = Array_new(); while ((dp = readdir(dh)) != NULL) { if (hide(dp->d_name)) continue; - strcpy(tmp, dp->d_name); + snprintf(tmp, sizeof(full_path) - (tmp - full_path), "%s", dp->d_name); Array_push(collections, Entry_new(full_path, ENTRY_DIR)); // Collections are fake directories } closedir(dh); // Close immediately after use @@ -920,14 +920,14 @@ static Array* getDiscs(char* path){ if (strlen(line)==0) continue; // skip empty lines char disc_path[256]; - sprintf(disc_path, "%s%s", base_path, line); + snprintf(disc_path, sizeof(disc_path), "%s%s", base_path, line); if (exists(disc_path)) { disc += 1; Entry* entry = Entry_new(disc_path, ENTRY_ROM); free(entry->name); char name[16]; - sprintf(name, "Disc %i", disc); + snprintf(name, sizeof(name), "Disc %i", disc); entry->name = strdup(name); Array_push(entries, entry); } @@ -952,7 +952,7 @@ static int getFirstDisc(char* m3u_path, char* disc_path) { // based on getDiscs( trimTrailingNewlines(line); if (strlen(line)==0) continue; // skip empty lines - sprintf(disc_path, "%s%s", base_path, line); + snprintf(disc_path, 256, "%s%s", base_path, line); // disc_path is a char[256] at both callers if (exists(disc_path)) found = 1; break; @@ -972,7 +972,7 @@ static void addEntries(Array* entries, char* path) { tmp = full_path + strlen(full_path); while((dp = readdir(dh)) != NULL) { if (hide(dp->d_name)) continue; - strcpy(tmp, dp->d_name); + snprintf(tmp, sizeof(full_path) - (tmp - full_path), "%s", dp->d_name); int is_dir = dp->d_type==DT_DIR; int type; if (is_dir) { @@ -1029,7 +1029,7 @@ static Array* getEntries(char* path){ while((dp = readdir(dh)) != NULL) { if (hide(dp->d_name)) continue; if (dp->d_type!=DT_DIR) continue; - strcpy(tmp, dp->d_name); + snprintf(tmp, sizeof(full_path) - (tmp - full_path), "%s", dp->d_name); if (!prefixMatch(collated_path, full_path)) continue; addEntries(entries, full_path); @@ -1093,7 +1093,7 @@ static void readyResumePath(char* rom_path, int type) { can_resume = 0; has_preview = 0; char path[256]; - strcpy(path, rom_path); + snprintf(path, sizeof(path), "%s", rom_path); if (!prefixMatch(ROMS_PATH, path)) return; @@ -1101,17 +1101,17 @@ static void readyResumePath(char* rom_path, int type) { if (type==ENTRY_DIR) { if (!hasCue(path, auto_path)) { // no cue? tmp = strrchr(auto_path, '.') + 1; // extension - strcpy(tmp, "m3u"); // replace with m3u + snprintf(tmp, sizeof(auto_path) - (tmp - auto_path), "%s", "m3u"); // replace with m3u if (!exists(auto_path)) return; // no m3u } - strcpy(path, auto_path); // cue or m3u if one exists + snprintf(path, sizeof(path), "%s", auto_path); // cue or m3u if one exists } if (!suffixMatch(".m3u", path)) { char m3u_path[256]; if (hasM3u(path, m3u_path)) { // change path to m3u path - strcpy(path, m3u_path); + snprintf(path, sizeof(path), "%s", m3u_path); } } @@ -1173,7 +1173,7 @@ static int autoResume(void) { char cmd[256]; // dont escape sd_path again because it was already escaped for gametimectl and function modifies input str aswell - sprintf(cmd, "'%s' '%s'", escapeSingleQuotes(emu_path), sd_path); + snprintf(cmd, sizeof(cmd), "'%s' '%s'", escapeSingleQuotes(emu_path), sd_path); putInt(RESUME_SLOT_PATH, AUTO_RESUME_SLOT); queueNext(cmd); return 1; @@ -1188,7 +1188,7 @@ static void openPak(char* path) { saveLast(path); char cmd[256]; - sprintf(cmd, "'%s/launch.sh'", escapeSingleQuotes(path)); + snprintf(cmd, sizeof(cmd), "'%s/launch.sh'", escapeSingleQuotes(path)); queueNext(cmd); } static void openRom(char* path, char* last) { @@ -1232,7 +1232,7 @@ static void openRom(char* path, char* last) { else { // relative snprintf(sd_path, sizeof(sd_path), "%s", m3u_path); char* tmp = strrchr(sd_path, '/') + 1; - strcpy(tmp, disc_path); + snprintf(tmp, sizeof(sd_path) - (tmp - sd_path), "%s", disc_path); } } } @@ -1251,7 +1251,7 @@ static void openRom(char* path, char* last) { system(act); char cmd[256]; // dont escape sd_path again because it was already escaped for gametimectl and function modifies input str aswell - sprintf(cmd, "'%s' '%s'", escapeSingleQuotes(emu_path), sd_path); + snprintf(cmd, sizeof(cmd), "'%s' '%s'", escapeSingleQuotes(emu_path), sd_path); queueNext(cmd); } @@ -1337,7 +1337,7 @@ Array* pathToStack(const char* path) { // Append segment if (current_len + segment_len >= PATH_MAX) break; - strcat(temp_path, segment); + strncat(temp_path, segment, sizeof(temp_path)-strlen(temp_path)-1); current_len += segment_len; if (strcmp(segment, PLATFORM) == 0) { @@ -1376,9 +1376,9 @@ static void openDirectory(char* path, int auto_launch) { } char m3u_path[256]; - strcpy(m3u_path, auto_path); + snprintf(m3u_path, sizeof(m3u_path), "%s", auto_path); char* tmp = strrchr(m3u_path, '.') + 1; // extension - strcpy(tmp, "m3u"); // replace with m3u + snprintf(tmp, sizeof(m3u_path) - (tmp - m3u_path), "%s", "m3u"); // replace with m3u if (exists(m3u_path) && auto_launch) { auto_path[0] = '\0'; if (getFirstDisc(m3u_path, auto_path)) { @@ -1471,7 +1471,7 @@ static void Entry_open(Entry* self) { char filename[256]; tmp = strrchr(self->path, '/'); - if (tmp) strcpy(filename, tmp+1); + if (tmp) snprintf(filename, sizeof(filename), "%s", tmp+1); char last_path[256]; snprintf(last_path, sizeof(last_path), "%s/%s", top->path, filename); @@ -1515,7 +1515,7 @@ static void loadLast(void) { // call after loading root directory char* tmp; char filename[256]; tmp = strrchr(last_path, '/'); - if (tmp) strcpy(filename, tmp); + if (tmp) snprintf(filename, sizeof(filename), "%s", tmp); Array* last = Array_new(); while (!exactMatch(last_path, SDCARD_PATH)) { From 31bec8e8036336419d06d73c50c7d6d56e8bcef9 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Wed, 1 Jul 2026 18:30:03 +0200 Subject: [PATCH 11/77] nextui: type recents as std::vector First of the void*->T* cleanups. The recents list is now a real std::vector instead of a void*-backed Array, so the 8 static_cast at the use sites are gone and the compiler knows the element type. Mechanical, behaviour-preserving: push_back/insert/pop_back/erase for the old Array_* calls, std::swap for the bump-to-top, and the typed RecentArray_indexOf/free helpers now take the vector by reference. The generic Array_* stay put - stack and entries still use them until their turn. --- workspace/all/nextui/nextui.cpp | 67 +++++++++++++++------------------ 1 file changed, 30 insertions(+), 37 deletions(-) diff --git a/workspace/all/nextui/nextui.cpp b/workspace/all/nextui/nextui.cpp index d25059af1..5199699b3 100644 --- a/workspace/all/nextui/nextui.cpp +++ b/workspace/all/nextui/nextui.cpp @@ -398,25 +398,22 @@ static void Recent_free(Recent* self) { free(self); } -static int RecentArray_indexOf(Array* self, char* str) { - for (int i=0; icount(); i++) { - Recent* item = static_cast(self->v[i]); - if (exactMatch(item->path, str)) return i; +static int RecentArray_indexOf(std::vector& self, const char* str) { + for (size_t i=0; ipath, str)) return (int)i; } return -1; } -static void RecentArray_free(Array* self) { - for (int i=0; icount(); i++) { - Recent_free(static_cast(self->v[i])); - } - Array_free(self); +static void RecentArray_free(std::vector& self) { + for (Recent* r : self) Recent_free(r); + self.clear(); } /////////////////////////////////////// static Directory* top; static Array* stack; // DirectoryArray -static Array* recents; // RecentArray +static std::vector recents; static Array *quick; // EntryArray static Array *quickActions; // EntryArray @@ -442,8 +439,8 @@ static int startgame = 0; static void saveRecents(void) { FILE* file = fopen(RECENT_PATH, "w"); if (file) { - for (int i=0; icount(); i++) { - Recent* recent = static_cast(recents->v[i]); + for (int i=0; i<(int)recents.size(); i++) { + Recent* recent = recents[i]; fputs(recent->path, file); if (recent->alias) { fputs("\t", file); @@ -458,16 +455,15 @@ static void addRecent(char* path, char* alias) { path += strlen(SDCARD_PATH); // makes paths platform agnostic int id = RecentArray_indexOf(recents, path); if (id==-1) { // add - while (recents->count()>=MAX_RECENTS) { - Recent_free(static_cast(Array_pop(recents))); + while ((int)recents.size()>=MAX_RECENTS) { + Recent_free(recents.back()); + recents.pop_back(); } - Array_unshift(recents, Recent_new(path, alias)); + recents.insert(recents.begin(), Recent_new(path, alias)); } else if (id>0) { // bump to top for (int i=id; i>0; i--) { - void* tmp = recents->v[i-1]; - recents->v[i-1] = recents->v[i]; - recents->v[i] = tmp; + std::swap(recents[i-1], recents[i]); } } saveRecents(); @@ -541,7 +537,6 @@ static int hasRecents(void) { LOG_info("hasRecents %s\n", RECENT_PATH); int has = 0; RecentArray_free(recents); - recents = Array_new(); Array* parent_paths = Array_new(); if (exists(CHANGE_DISC_PATH)) { @@ -551,7 +546,7 @@ static int hasRecents(void) { char* disc_path = sd_path + strlen(SDCARD_PATH); // makes path platform agnostic Recent* recent = Recent_new(disc_path, NULL); if (recent->available) has += 1; - Array_push(recents, recent); + recents.push_back(recent); char parent_path[256]; snprintf(parent_path, sizeof(parent_path), "%s", disc_path); @@ -583,7 +578,7 @@ static int hasRecents(void) { char sd_path[256]; snprintf(sd_path, sizeof(sd_path), "%s%s", SDCARD_PATH, path); if (exists(sd_path)) { - if (recents->count()available) has += 1; - Array_push(recents, recent); + recents.push_back(recent); } } } @@ -770,7 +765,7 @@ static Array* getQuickEntries(void) { Array* entries = Array_new(); // We assume Menu_init was already called and populated this - if (recents && recents->count()) + if (!recents.empty()) Array_push(entries, Entry_newNamed(FAUX_RECENT_PATH, ENTRY_DIR, "Recents")); if (hasCollections()) @@ -862,8 +857,8 @@ static Entry* entryFromRecent(Recent* recent) static Array* getRecents(void) { Array* entries = Array_new(); - for (int i=0; icount(); i++) { - Recent* recent = static_cast(recents->v[i]); + for (int i=0; i<(int)recents.size(); i++) { + Recent* recent = recents[i]; Entry *entry = entryFromRecent(recent); if(entry) Array_push(entries, entry); @@ -1583,8 +1578,6 @@ static void QuickMenu_quit(void) { static void Menu_init(void) { stack = Array_new(); // array of open Directories - recents = Array_new(); - openDirectory(SDCARD_PATH, 0); loadLast(); // restore state when available @@ -2418,29 +2411,29 @@ int main (int argc, char *argv[]) { dirty = 1; folderbgchanged = 1; // The background painting code is a clusterfuck, just force a repaint here } - else if (recents->count() > 0 && PAD_justReleased(BTN_A)) { + else if ((int)recents.size() > 0 && PAD_justReleased(BTN_A)) { // this will drop us back into game switcher after leaving the game putFile(GAME_SWITCHER_PERSIST_PATH, "unused"); startgame = 1; - Entry *selectedEntry = entryFromRecent(static_cast(recents->v[switcher_selected])); + Entry *selectedEntry = entryFromRecent(recents[switcher_selected]); should_resume = can_resume; Entry_open(selectedEntry); dirty = 1; Entry_free(selectedEntry); } - else if (recents->count() > 0 && PAD_justReleased(BTN_Y)) { + else if ((int)recents.size() > 0 && PAD_justReleased(BTN_Y)) { // remove - Recent* recentEntry = static_cast(recents->v[switcher_selected--]); - Array_remove(recents, recentEntry); + Recent* recentEntry = recents[switcher_selected--]; + recents.erase(std::find(recents.begin(), recents.end(), recentEntry)); Recent_free(recentEntry); saveRecents(); if(switcher_selected < 0) - switcher_selected = recents->count() - 1; // wrap + switcher_selected = (int)recents.size() - 1; // wrap dirty = 1; } else if (PAD_justPressed(BTN_RIGHT)) { switcher_selected++; - if(switcher_selected == recents->count()) + if(switcher_selected == (int)recents.size()) switcher_selected = 0; // wrap dirty = 1; gsanimdir = SLIDE_LEFT; @@ -2448,7 +2441,7 @@ int main (int argc, char *argv[]) { else if (PAD_justPressed(BTN_LEFT)) { switcher_selected--; if(switcher_selected < 0) - switcher_selected = recents->count() - 1; // wrap + switcher_selected = (int)recents.size() - 1; // wrap dirty = 1; gsanimdir = SLIDE_RIGHT; } @@ -2789,8 +2782,8 @@ int main (int argc, char *argv[]) { oy = 0; // For all recents with resumable state (i.e. has savegame), show game switcher carousel - if(recents->count() > 0) { - Entry *selectedEntry = entryFromRecent(static_cast(recents->v[switcher_selected])); + if((int)recents.size() > 0) { + Entry *selectedEntry = entryFromRecent(recents[switcher_selected]); readyResume(selectedEntry); // title pill { From 7bd046c36521f55f1c1a0f62d6406114fec8aaa4 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Wed, 1 Jul 2026 18:32:54 +0200 Subject: [PATCH 12/77] nextui: type the directory stack as std::vector Second void*->T* cleanup. The nav stack (and pathToStack, which builds it) are now std::vector, dropping the 4 static_cast. pathToStack returns the vector by value; DirectoryArray_pop/free take it by reference. 'top' still just aliases the last element (stack.back()), so the pop-then-reassign ordering is unchanged. --- workspace/all/nextui/nextui.cpp | 57 ++++++++++++++++----------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/workspace/all/nextui/nextui.cpp b/workspace/all/nextui/nextui.cpp index 5199699b3..68a02a44d 100644 --- a/workspace/all/nextui/nextui.cpp +++ b/workspace/all/nextui/nextui.cpp @@ -357,14 +357,14 @@ static void Directory_free(Directory* self) { free(self); } -static void DirectoryArray_pop(Array* self) { - Directory_free(static_cast(Array_pop(self))); +static void DirectoryArray_pop(std::vector& self) { + if (self.empty()) return; + Directory_free(self.back()); + self.pop_back(); } -static void DirectoryArray_free(Array* self) { - for (int i=0; icount(); i++) { - Directory_free(static_cast(self->v[i])); - } - Array_free(self); +static void DirectoryArray_free(std::vector& self) { + for (Directory* d : self) Directory_free(d); + self.clear(); } /////////////////////////////////////// @@ -412,7 +412,7 @@ static void RecentArray_free(std::vector& self) { /////////////////////////////////////// static Directory* top; -static Array* stack; // DirectoryArray +static std::vector stack; static std::vector recents; static Array *quick; // EntryArray static Array *quickActions; // EntryArray @@ -1292,8 +1292,8 @@ static bool isDirectSubdirectory(const Directory* parent, const char* child_path return (levels == 1); // exactly one meaningful level deeper } -Array* pathToStack(const char* path) { - Array* array = Array_new(); +std::vector pathToStack(const char* path) { + std::vector array; if (!path || strlen(path) == 0) return array; @@ -1303,7 +1303,7 @@ Array* pathToStack(const char* path) { Directory* root_dir = Directory_new(SDCARD_PATH, 0); root_dir->start = 0; root_dir->end = (root_dir->entries->count() < MAIN_ROW_COUNT) ? root_dir->entries->count() : MAIN_ROW_COUNT; - Array_push(array, root_dir); + array.push_back(root_dir); if (exactMatch(path, SDCARD_PATH)) return array; @@ -1337,23 +1337,23 @@ Array* pathToStack(const char* path) { if (strcmp(segment, PLATFORM) == 0) { // Merge with previous directory - if (array->count() > 0) { + if (array.size() > 0) { // Remove the previous directory - Directory* last = (Directory*)array->v[array->count() - 1]; - Array_pop(array); + Directory* last = array.back(); + array.pop_back(); Directory_free(last); // assuming you have a Directory_free // Replace with updated one using combined path Directory* merged = Directory_new(temp_path, 0); merged->start = 0; merged->end = (merged->entries->count() < MAIN_ROW_COUNT) ? merged->entries->count() : MAIN_ROW_COUNT; - Array_push(array, merged); + array.push_back(merged); } } else { Directory* dir = Directory_new(temp_path, 0); dir->start = 0; dir->end = (dir->entries->count() < MAIN_ROW_COUNT) ? dir->entries->count() : MAIN_ROW_COUNT; - Array_push(array, dir); + array.push_back(dir); } if (!next) break; @@ -1394,7 +1394,7 @@ static void openDirectory(char* path, int auto_launch) { int start = 0; int end = 0; if (top && top->entries->count()>0) { - if (restore_depth==stack->count() && top->selected==restore_relative) { + if (restore_depth==(int)stack.size() && top->selected==restore_relative) { selected = restore_selected; start = restore_start; end = restore_end; @@ -1405,7 +1405,7 @@ static void openDirectory(char* path, int auto_launch) { top->start = start; top->end = end ? end : ((top->entries->count()entries->count() : MAIN_ROW_COUNT); - Array_push(stack, top); + stack.push_back(top); } else { // keep a copy of path, which might be a reference into stack which is about to be freed @@ -1416,7 +1416,7 @@ static void openDirectory(char* path, int auto_launch) { DirectoryArray_free(stack); stack = pathToStack(temp_path); - top = static_cast(stack->v[stack->count() - 1]); + top = stack[(int)stack.size() - 1]; } } @@ -1425,8 +1425,8 @@ static void closeDirectory(void) { restore_start = top->start; restore_end = top->end; DirectoryArray_pop(stack); - restore_depth = stack->count(); - top = static_cast(stack->v[stack->count()-1]); + restore_depth = (int)stack.size(); + top = stack[(int)stack.size()-1]; restore_relative = top->selected; } @@ -1577,7 +1577,6 @@ static void QuickMenu_quit(void) { } static void Menu_init(void) { - stack = Array_new(); // array of open Directories openDirectory(SDCARD_PATH, 0); loadLast(); // restore state when available @@ -2580,7 +2579,7 @@ int main (int argc, char *argv[]) { if (total>0) readyResume(static_cast(top->entries->v[top->selected])); } - else if (PAD_justPressed(BTN_B) && stack->count()>1) { + else if (PAD_justPressed(BTN_B) && (int)stack.size()>1) { closeDirectory(); animationdirection = SLIDE_RIGHT; total = top->entries->count(); @@ -2933,7 +2932,7 @@ int main (int argc, char *argv[]) { static int lastType = -1; // this is only a choice on the root folder - list_show_entry_names = stack->count() > 1 || CFG_getShowFolderNamesAtRoot(); + list_show_entry_names = (int)stack.size() > 1 || CFG_getShowFolderNamesAtRoot(); // load folder background char defaultBgPath[512]; @@ -2994,12 +2993,12 @@ int main (int argc, char *argv[]) { NULL }, 0, screen, 0); if (total==0) { - if (stack->count()>1) { + if ((int)stack.size()>1) { GFX_blitButtonGroup((char**)(const char*[]){ "B","BACK", NULL }, 0, screen, 1); } } else { - if (stack->count()>1) { + if ((int)stack.size()>1) { GFX_blitButtonGroup((char**)(const char*[]){ "B","BACK", "A","OPEN", NULL }, 1, screen, 1); } else { @@ -3020,7 +3019,7 @@ int main (int argc, char *argv[]) { int available_width = MAX(0,(had_thumb ? ox + SCALE1(BUTTON_MARGIN) : screen->w - SCALE1(BUTTON_MARGIN)) - SCALE1(PADDING * 2)); bool row_is_selected = (j == selected_row); bool row_is_top = (i == top->start); - bool row_has_moved = (previous_row != selected_row || previous_depth != stack->count()); + bool row_has_moved = (previous_row != selected_row || previous_depth != (int)stack.size()); if (row_is_top && !(had_thumb)) available_width -= ow; @@ -3050,7 +3049,7 @@ int main (int argc, char *argv[]) { if (row_is_selected) { is_scrolling = list_show_entry_names && GFX_textShouldScroll(font.large,display_name, max_width - SCALE1(BUTTON_PADDING*2), fontMutex); GFX_resetScrollText(); - bool should_animate = previous_depth == stack->count(); + bool should_animate = previous_depth == (int)stack.size(); SDL_LockMutex(animMutex); if(globalpill) { SDL_FreeSurface(globalpill); @@ -3100,7 +3099,7 @@ int main (int argc, char *argv[]) { } previous_row = selected_row; - previous_depth = stack->count(); + previous_depth = (int)stack.size(); } else { // TODO: for some reason screen's dimensions end up being 0x0 in GFX_blitMessage... From a4891e0d98b851abbb127f39c36210d2607f3113 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Wed, 1 Jul 2026 18:36:46 +0200 Subject: [PATCH 13/77] nextui: type the string lists as std::vector Third void*->T* cleanup. The two local path lists (parent_paths in getCollections and last in loadLast) are std::vector now. Dropped the unused StringArray_indexOf; StringArray_free takes the vector by ref and frees each strdup'd string before clearing. Only Entry is left on the void*-backed Array now. --- workspace/all/nextui/nextui.cpp | 35 +++++++++++++-------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/workspace/all/nextui/nextui.cpp b/workspace/all/nextui/nextui.cpp index 68a02a44d..611a36e03 100644 --- a/workspace/all/nextui/nextui.cpp +++ b/workspace/all/nextui/nextui.cpp @@ -78,17 +78,9 @@ static void Array_yoink(Array* self, Array* other) { Array_free(other); // container only; `self` now owns the entries } -static int StringArray_indexOf(Array* self, char* str) { - for (int i=0; icount(); i++) { - if (exactMatch(static_cast(self->v[i]), str)) return i; - } - return -1; -} -static void StringArray_free(Array* self) { - for (int i=0; icount(); i++) { - free(self->v[i]); - } - Array_free(self); +static void StringArray_free(std::vector& self) { + for (char* s : self) free(s); + self.clear(); } /////////////////////////////////////// @@ -538,7 +530,7 @@ static int hasRecents(void) { int has = 0; RecentArray_free(recents); - Array* parent_paths = Array_new(); + std::vector parent_paths; if (exists(CHANGE_DISC_PATH)) { char sd_path[256]; getFile(CHANGE_DISC_PATH, sd_path, 256); @@ -552,7 +544,7 @@ static int hasRecents(void) { snprintf(parent_path, sizeof(parent_path), "%s", disc_path); char* tmp = strrchr(parent_path, '/') + 1; tmp[0] = '\0'; - Array_push(parent_paths, strdup(parent_path)); + parent_paths.push_back(strdup(parent_path)); } unlink(CHANGE_DISC_PATH); } @@ -588,8 +580,8 @@ static int hasRecents(void) { tmp[0] = '\0'; int found = 0; - for (int i=0; icount(); i++) { - char* path = static_cast(parent_paths->v[i]); + for (int i=0; i<(int)parent_paths.size(); i++) { + char* path = parent_paths[i]; if (prefixMatch(path, parent_path)) { found = 1; break; @@ -597,7 +589,7 @@ static int hasRecents(void) { } if (found) continue; - Array_push(parent_paths, strdup(parent_path)); + parent_paths.push_back(strdup(parent_path)); } // LOG_info("path:%s alias:%s\n", path, alias); @@ -1512,16 +1504,17 @@ static void loadLast(void) { // call after loading root directory tmp = strrchr(last_path, '/'); if (tmp) snprintf(filename, sizeof(filename), "%s", tmp); - Array* last = Array_new(); + std::vector last; while (!exactMatch(last_path, SDCARD_PATH)) { - Array_push(last, strdup(last_path)); + last.push_back(strdup(last_path)); char* slash = strrchr(last_path, '/'); last_path[(slash-last_path)] = '\0'; } - while (last->count()>0) { - char* path = static_cast(Array_pop(last)); + while (!last.empty()) { + char* path = last.back(); + last.pop_back(); if (!exactMatch(path, ROMS_PATH)) { // romsDir is effectively root as far as restoring state after a game char collated_path[256]; collated_path[0] = '\0'; @@ -1545,7 +1538,7 @@ static void loadLast(void) { // call after loading root directory top->start = top->end - MAIN_ROW_COUNT; } } - if (last->count()==0 && !exactMatch(entry->path, FAUX_RECENT_PATH) && !(!exactMatch(entry->path, COLLECTIONS_PATH) && prefixMatch(COLLECTIONS_PATH, entry->path))) break; // don't show contents of auto-launch dirs + if (last.empty() && !exactMatch(entry->path, FAUX_RECENT_PATH) && !(!exactMatch(entry->path, COLLECTIONS_PATH) && prefixMatch(COLLECTIONS_PATH, entry->path))) break; // don't show contents of auto-launch dirs if (entry->type==ENTRY_DIR) { openDirectory(entry->path, 0); From 8ea874f7fa3b119d6dc7381d46d7839b9b9256c8 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Wed, 1 Jul 2026 19:34:04 +0200 Subject: [PATCH 14/77] nextui: type entries/quick as std::vector, retire the Array The last and biggest void*->T* cleanup, and it lets the hand-rolled Array type go away entirely. - Directory now holds its entries and alphas by value (std::vector), so Directory is allocated with new/delete instead of malloc/free. new Directory() value-initialises, so the scalar fields still start zeroed. - The nine get* builders (getRoot/getRoms/getEntries/getCollection/ getDiscs/getRecents/getCollections/getQuick*) return std::vector by value; quick/quickActions are by-value vectors too. - EntryArray_indexOf/sort/free take the vector by reference; the merge spots that used Array_yoink now splice with insert()+clear(). - Every static_cast is gone (58 casts removed across the whole Array->vector effort). With nothing left using it, the generic Array struct and its new/push/pop/unshift/remove/reverse/free/yoink are deleted. The whole crusty hand-rolled container layer is now std::vector. --- workspace/all/nextui/nextui.cpp | 290 ++++++++++++++------------------ 1 file changed, 122 insertions(+), 168 deletions(-) diff --git a/workspace/all/nextui/nextui.cpp b/workspace/all/nextui/nextui.cpp index 611a36e03..1d29495bb 100644 --- a/workspace/all/nextui/nextui.cpp +++ b/workspace/all/nextui/nextui.cpp @@ -39,45 +39,6 @@ extern "C" { /////////////////////////////////////// -typedef struct Array { - std::vector v; - int count() const { return (int)v.size(); } -} Array; - -static Array* Array_new(void) { - return new Array(); -} -static void Array_push(Array* self, void* item) { - self->v.push_back(item); -} -static void Array_unshift(Array* self, void* item) { - self->v.insert(self->v.begin(), item); -} -static void* Array_pop(Array* self) { - if (self->v.empty()) return NULL; - void* item = self->v.back(); - self->v.pop_back(); - return item; -} -static void Array_remove(Array* self, void* item) { - if (item == NULL) return; - auto it = std::find(self->v.begin(), self->v.end(), item); - if (it != self->v.end()) self->v.erase(it); -} -static void Array_reverse(Array* self) { - std::reverse(self->v.begin(), self->v.end()); -} -static void Array_free(Array* self) { - // container only; the elements are owned elsewhere. The typed - // *Array_free wrappers below free their elements before calling us. - delete self; -} -static void Array_yoink(Array* self, Array* other) { - // append other's entries to self and take ownership of them - self->v.insert(self->v.end(), other->v.begin(), other->v.end()); - Array_free(other); // container only; `self` now owns the entries -} - static void StringArray_free(std::vector& self) { for (char* s : self) free(s); self.clear(); @@ -145,25 +106,22 @@ static void Entry_free(Entry* self) { free(self); } -static int EntryArray_indexOf(Array* self, char* path) { - for (int i=0; icount(); i++) { - Entry* entry = static_cast(self->v[i]); - if (exactMatch(entry->path, path)) return i; +static int EntryArray_indexOf(std::vector& self, const char* path) { + for (size_t i=0; ipath, path)) return (int)i; } return -1; } -static void EntryArray_sort(Array* self) { +static void EntryArray_sort(std::vector& self) { // same not-stable, case-insensitive name ordering the old qsort gave us - std::sort(self->v.begin(), self->v.end(), [](void* a, void* b) { - return strcasecmp(static_cast(a)->name, static_cast(b)->name) < 0; + std::sort(self.begin(), self.end(), [](Entry* a, Entry* b) { + return strcasecmp(a->name, b->name) < 0; }); } -static void EntryArray_free(Array* self) { - for (int i=0; icount(); i++) { - Entry_free(static_cast(self->v[i])); - } - Array_free(self); +static void EntryArray_free(std::vector& self) { + for (Entry* e : self) Entry_free(e); + self.clear(); } /////////////////////////////////////// @@ -171,8 +129,8 @@ static void EntryArray_free(Array* self) { typedef struct Directory { char* path; char* name; - Array* entries; - std::vector* alphas; + std::vector entries; + std::vector alphas; // rendering int selected; int start; @@ -223,8 +181,8 @@ static void Directory_index(Directory* self) { int resort = 0; int filter = 0; - for (int i = 0; i < self->entries->count(); i++) { - Entry* entry = static_cast(self->entries->v[i]); + for (int i = 0; i < (int)self->entries.size(); i++) { + Entry* entry = self->entries[i]; char* filename = strrchr(entry->path, '/') + 1; const char* alias = Hash_get(map, filename); if (alias) { @@ -236,17 +194,16 @@ static void Directory_index(Directory* self) { } if (filter) { - Array* entries = Array_new(); - for (int i = 0; i < self->entries->count(); i++) { - Entry* entry = static_cast(self->entries->v[i]); + std::vector filtered; + for (int i = 0; i < (int)self->entries.size(); i++) { + Entry* entry = self->entries[i]; if (hide(entry->name)) { Entry_free(entry); // Ensure Entry_free handles all memory cleanup } else { - Array_push(entries, entry); + filtered.push_back(entry); } } - Array_free(self->entries); - self->entries = entries; + self->entries = std::move(filtered); } if (resort) EntryArray_sort(self->entries); } @@ -255,8 +212,8 @@ static void Directory_index(Directory* self) { Entry* prior = NULL; int alpha = -1; int index = 0; - for (int i = 0; i < self->entries->count(); i++) { - Entry* entry = static_cast(self->entries->v[i]); + for (int i = 0; i < (int)self->entries.size(); i++) { + Entry* entry = self->entries[i]; if (map) { char* filename = strrchr(entry->path, '/') + 1; const char* alias = Hash_get(map, filename); @@ -291,8 +248,8 @@ static void Directory_index(Directory* self) { if (!skip_index) { int a = getIndexChar(entry->name); if (a != alpha) { - index = (int)self->alphas->size(); - self->alphas->push_back(i); + index = (int)self->alphas.size(); + self->alphas.push_back(i); alpha = a; } entry->alpha = index; @@ -304,18 +261,18 @@ static void Directory_index(Directory* self) { if (map) Hash_free(map); // Free the map at the end } -static Array* getRoot(void); -static Array* getRoms(void); -static Array* getRecents(void); -static Array* getCollection(char* path); -static Array* getDiscs(char* path); -static Array* getEntries(char* path); +static std::vector getRoot(void); +static std::vector getRoms(void); +static std::vector getRecents(void); +static std::vector getCollection(char* path); +static std::vector getDiscs(char* path); +static std::vector getEntries(char* path); static Directory* Directory_new(char* path, int selected) { char display_name[256]; getDisplayName(path, display_name); - Directory* self = (Directory*)(malloc(sizeof(Directory))); + Directory* self = new Directory(); self->path = strdup(path); self->name = strdup(display_name); if (exactMatch(path, SDCARD_PATH)) { @@ -336,7 +293,6 @@ static Directory* Directory_new(char* path, int selected) { else { self->entries = getEntries(path); } - self->alphas = new std::vector(); self->selected = selected; Directory_index(self); return self; @@ -345,8 +301,7 @@ static void Directory_free(Directory* self) { free(self->path); free(self->name); EntryArray_free(self->entries); - delete self->alphas; - free(self); + delete self; } static void DirectoryArray_pop(std::vector& self) { @@ -406,8 +361,8 @@ static void RecentArray_free(std::vector& self) { static Directory* top; static std::vector stack; static std::vector recents; -static Array *quick; // EntryArray -static Array *quickActions; // EntryArray +static std::vector quick; +static std::vector quickActions; static int quit = 0; static int can_resume = 0; @@ -654,9 +609,9 @@ static int hasTools(void) { return exists(tools_path); } -static Array* getRoms() +static std::vector getRoms() { - Array* entries = Array_new(); + std::vector entries; DIR* dh = opendir(ROMS_PATH); if (dh) { struct dirent* dp; @@ -664,34 +619,33 @@ static Array* getRoms() snprintf(full_path, sizeof(full_path), "%s/", ROMS_PATH); char* tmp = full_path + strlen(full_path); - Array* emus = Array_new(); + std::vector emus; while ((dp = readdir(dh)) != NULL) { if (hide(dp->d_name)) continue; if (hasRoms(dp->d_name)) { snprintf(tmp, sizeof(full_path) - (tmp - full_path), "%s", dp->d_name); - Array_push(emus, Entry_new(full_path, ENTRY_DIR)); + emus.push_back(Entry_new(full_path, ENTRY_DIR)); } } closedir(dh); // Ensure directory is closed immediately after use EntryArray_sort(emus); Entry* prev_entry = NULL; - for (int i = 0; i < emus->count(); i++) { - Entry* entry = static_cast(emus->v[i]); + for (int i = 0; i < (int)emus.size(); i++) { + Entry* entry = emus[i]; if (prev_entry && exactMatch(prev_entry->name, entry->name)) { Entry_free(entry); continue; } - Array_push(entries, entry); + entries.push_back(entry); prev_entry = entry; } - Array_free(emus); // Only frees container, entries now owns the items } // Handle mapping logic char map_path[256]; snprintf(map_path, sizeof(map_path), "%s/map.txt", ROMS_PATH); - if (entries->count() > 0 && exists(map_path)) { + if ((int)entries.size() > 0 && exists(map_path)) { FILE* file = fopen(map_path, "r"); if (file) { Hash* map = Hash_new(); @@ -713,8 +667,8 @@ static Array* getRoms() fclose(file); int resort = 0; - for (int i = 0; i < entries->count(); i++) { - Entry* entry = static_cast(entries->v[i]); + for (int i = 0; i < (int)entries.size(); i++) { + Entry* entry = entries[i]; char* filename = strrchr(entry->path, '/') + 1; const char* alias = Hash_get(map, filename); if (alias) { @@ -731,7 +685,7 @@ static Array* getRoms() return entries; } -static Array* getCollections(void) +static std::vector getCollections(void) { DIR* dh = opendir(COLLECTIONS_PATH); if (dh) { @@ -740,92 +694,92 @@ static Array* getCollections(void) snprintf(full_path, sizeof(full_path), "%s/", COLLECTIONS_PATH); char* tmp = full_path + strlen(full_path); - Array* collections = Array_new(); + std::vector collections; while ((dp = readdir(dh)) != NULL) { if (hide(dp->d_name)) continue; snprintf(tmp, sizeof(full_path) - (tmp - full_path), "%s", dp->d_name); - Array_push(collections, Entry_new(full_path, ENTRY_DIR)); // Collections are fake directories + collections.push_back(Entry_new(full_path, ENTRY_DIR)); // Collections are fake directories } closedir(dh); // Close immediately after use EntryArray_sort(collections); return collections; } - return NULL; + return {}; } -static Array* getQuickEntries(void) { - Array* entries = Array_new(); +static std::vector getQuickEntries(void) { + std::vector entries; // We assume Menu_init was already called and populated this if (!recents.empty()) - Array_push(entries, Entry_newNamed(FAUX_RECENT_PATH, ENTRY_DIR, "Recents")); + entries.push_back(Entry_newNamed(FAUX_RECENT_PATH, ENTRY_DIR, "Recents")); if (hasCollections()) - Array_push(entries, Entry_new(COLLECTIONS_PATH, ENTRY_DIR)); + entries.push_back(Entry_new(COLLECTIONS_PATH, ENTRY_DIR)); // Not sure we need this, its just a button press away (B) - Array_push(entries, Entry_newNamed(ROMS_PATH, ENTRY_DIR, "Games")); + entries.push_back(Entry_newNamed(ROMS_PATH, ENTRY_DIR, "Games")); // Add tools if applicable if (hasTools() && !simple_mode) { char tools_path[256]; snprintf(tools_path, sizeof(tools_path), "%s/Tools/%s", SDCARD_PATH, PLATFORM); - Array_push(entries, Entry_new(tools_path, ENTRY_DIR)); + entries.push_back(Entry_new(tools_path, ENTRY_DIR)); } return entries; } -static Array* getQuickToggles(void) { - Array *entries = Array_new(); +static std::vector getQuickToggles(void) { + std::vector entries; Entry *settings = entryFromPakName("Settings"); if (settings) - Array_push(entries, settings); + entries.push_back(settings); Entry *store = entryFromPakName("Pak Store"); if (store) - Array_push(entries, store); + entries.push_back(store); // quick actions if(WIFI_supported()) - Array_push(entries, Entry_new("Wifi", ENTRY_DIP)); + entries.push_back(Entry_new("Wifi", ENTRY_DIP)); if(BT_supported()) - Array_push(entries, Entry_new("Bluetooth", ENTRY_DIP)); + entries.push_back(Entry_new("Bluetooth", ENTRY_DIP)); if(PLAT_supportsDeepSleep() && !simple_mode) - Array_push(entries, Entry_new("Sleep", ENTRY_DIP)); - Array_push(entries, Entry_new("Reboot", ENTRY_DIP)); - Array_push(entries, Entry_new("Poweroff", ENTRY_DIP)); + entries.push_back(Entry_new("Sleep", ENTRY_DIP)); + entries.push_back(Entry_new("Reboot", ENTRY_DIP)); + entries.push_back(Entry_new("Poweroff", ENTRY_DIP)); return entries; } -static Array* getRoot(void) { - Array* root = Array_new(); +static std::vector getRoot(void) { + std::vector root; if (hasRecents() && CFG_getShowRecents()) - Array_push(root, Entry_new(FAUX_RECENT_PATH, ENTRY_DIR)); + root.push_back(Entry_new(FAUX_RECENT_PATH, ENTRY_DIR)); - Array *entries = getRoms(); + std::vector entries = getRoms(); // Handle collections if (hasCollections() && CFG_getShowCollections()) { - if (entries->count()) { - Array_push(root, Entry_new(COLLECTIONS_PATH, ENTRY_DIR)); + if ((int)entries.size()) { + root.push_back(Entry_new(COLLECTIONS_PATH, ENTRY_DIR)); } else { // No visible systems, promote collections to root - Array *collections = getCollections(); - Array_yoink(entries, collections); + std::vector collections = getCollections(); + entries.insert(entries.end(), collections.begin(), collections.end()); collections.clear(); } } // Move entries to root - Array_yoink(root, entries); + root.insert(root.end(), entries.begin(), entries.end()); entries.clear(); // Add tools if applicable if (hasTools() && CFG_getShowTools() && !simple_mode) { char tools_path[256]; snprintf(tools_path, sizeof(tools_path), "%s/Tools/%s", SDCARD_PATH, PLATFORM); - Array_push(root, Entry_new(tools_path, ENTRY_DIR)); + root.push_back(Entry_new(tools_path, ENTRY_DIR)); } return root; @@ -834,7 +788,7 @@ static Array* getRoot(void) { static Entry* entryFromRecent(Recent* recent) { if(!recent || !recent->available) - return NULL; + return {}; char sd_path[256]; snprintf(sd_path, sizeof(sd_path), "%s%s", SDCARD_PATH, recent->path); @@ -847,19 +801,19 @@ static Entry* entryFromRecent(Recent* recent) return entry; } -static Array* getRecents(void) { - Array* entries = Array_new(); +static std::vector getRecents(void) { + std::vector entries; for (int i=0; i<(int)recents.size(); i++) { Recent* recent = recents[i]; Entry *entry = entryFromRecent(recent); if(entry) - Array_push(entries, entry); + entries.push_back(entry); } return entries; } -static Array* getCollection(char* path) { - Array* entries = Array_new(); +static std::vector getCollection(char* path) { + std::vector entries; FILE* file = fopen(path, "r"); if (file) { char line[256]; @@ -872,12 +826,12 @@ static Array* getCollection(char* path) { snprintf(sd_path, sizeof(sd_path), "%s%s", SDCARD_PATH, line); if (exists(sd_path)) { int type = suffixMatch(".pak", sd_path) ? ENTRY_PAK : ENTRY_ROM; // ??? - Array_push(entries, Entry_new(sd_path, type)); + entries.push_back(Entry_new(sd_path, type)); // char emu_name[256]; // getEmuName(sd_path, emu_name); // if (hasEmu(emu_name)) { - // Array_push(entries, Entry_new(sd_path, ENTRY_ROM)); + // entries.push_back(Entry_new(sd_path, ENTRY_ROM)); // } } } @@ -885,11 +839,11 @@ static Array* getCollection(char* path) { } return entries; } -static Array* getDiscs(char* path){ +static std::vector getDiscs(char* path){ // TODO: does path have SDCARD_PATH prefix? - Array* entries = Array_new(); + std::vector entries; char base_path[256]; snprintf(base_path, sizeof(base_path), "%s", path); @@ -916,7 +870,7 @@ static Array* getDiscs(char* path){ char name[16]; snprintf(name, sizeof(name), "Disc %i", disc); entry->name = strdup(name); - Array_push(entries, entry); + entries.push_back(entry); } } fclose(file); @@ -949,7 +903,7 @@ static int getFirstDisc(char* m3u_path, char* disc_path) { // based on getDiscs( return found; } -static void addEntries(Array* entries, char* path) { +static void addEntries(std::vector& entries, char* path) { DIR *dh = opendir(path); if (dh!=NULL) { struct dirent *dp; @@ -979,7 +933,7 @@ static void addEntries(Array* entries, char* path) { type = ENTRY_ROM; } } - Array_push(entries, Entry_new(full_path, type)); + entries.push_back(Entry_new(full_path, type)); } closedir(dh); } @@ -995,8 +949,8 @@ static int isConsoleDir(char* path) { return exactMatch(parent_dir, ROMS_PATH); } -static Array* getEntries(char* path){ - Array* entries = Array_new(); +static std::vector getEntries(char* path){ + std::vector entries; if (isConsoleDir(path)) { // top-level console folder, might collate char collated_path[256]; @@ -1294,7 +1248,7 @@ std::vector pathToStack(const char* path) { // Always include root directory Directory* root_dir = Directory_new(SDCARD_PATH, 0); root_dir->start = 0; - root_dir->end = (root_dir->entries->count() < MAIN_ROW_COUNT) ? root_dir->entries->count() : MAIN_ROW_COUNT; + root_dir->end = ((int)root_dir->entries.size() < MAIN_ROW_COUNT) ? (int)root_dir->entries.size() : MAIN_ROW_COUNT; array.push_back(root_dir); if (exactMatch(path, SDCARD_PATH)) return array; @@ -1338,13 +1292,13 @@ std::vector pathToStack(const char* path) { // Replace with updated one using combined path Directory* merged = Directory_new(temp_path, 0); merged->start = 0; - merged->end = (merged->entries->count() < MAIN_ROW_COUNT) ? merged->entries->count() : MAIN_ROW_COUNT; + merged->end = ((int)merged->entries.size() < MAIN_ROW_COUNT) ? (int)merged->entries.size() : MAIN_ROW_COUNT; array.push_back(merged); } } else { Directory* dir = Directory_new(temp_path, 0); dir->start = 0; - dir->end = (dir->entries->count() < MAIN_ROW_COUNT) ? dir->entries->count() : MAIN_ROW_COUNT; + dir->end = ((int)dir->entries.size() < MAIN_ROW_COUNT) ? (int)dir->entries.size() : MAIN_ROW_COUNT; array.push_back(dir); } @@ -1385,7 +1339,7 @@ static void openDirectory(char* path, int auto_launch) { int selected = 0; int start = 0; int end = 0; - if (top && top->entries->count()>0) { + if (top && (int)top->entries.size()>0) { if (restore_depth==(int)stack.size() && top->selected==restore_relative) { selected = restore_selected; start = restore_start; @@ -1395,7 +1349,7 @@ static void openDirectory(char* path, int auto_launch) { top = Directory_new(path, selected); top->start = start; - top->end = end ? end : ((top->entries->count()entries->count() : MAIN_ROW_COUNT); + top->end = end ? end : (((int)top->entries.size()entries.size() : MAIN_ROW_COUNT); stack.push_back(top); } @@ -1524,8 +1478,8 @@ static void loadLast(void) { // call after loading root directory if (tmp) tmp[1] = '\0'; // 1 because we want to keep the opening parenthesis to avoid collating "Game Boy Color" and "Game Boy Advance" into "Game Boy" } - for (int i=0; ientries->count(); i++) { - Entry* entry = static_cast(top->entries->v[i]); + for (int i=0; i<(int)top->entries.size(); i++) { + Entry* entry = top->entries[i]; // NOTE: strlen() is required for collated_path, '\0' wasn't reading as NULL for some reason if (exactMatch(entry->path, path) || (strlen(collated_path) && prefixMatch(collated_path, entry->path)) || (prefixMatch(COLLECTIONS_PATH, full_path) && suffixMatch(filename, entry->path))) { @@ -1533,8 +1487,8 @@ static void loadLast(void) { // call after loading root directory if (i>=top->end) { top->start = i; top->end = top->start + MAIN_ROW_COUNT; - if (top->end>top->entries->count()) { - top->end = top->entries->count(); + if (top->end>(int)top->entries.size()) { + top->end = (int)top->entries.size(); top->start = top->end - MAIN_ROW_COUNT; } } @@ -1552,8 +1506,8 @@ static void loadLast(void) { // call after loading root directory StringArray_free(last); - if (top->selected >= 0 && top->selected < top->entries->count()) { - Entry* selected_entry = static_cast(top->entries->v[top->selected]); + if (top->selected >= 0 && top->selected < (int)top->entries.size()) { + Entry* selected_entry = top->entries[top->selected]; readyResume(selected_entry); } } @@ -2229,7 +2183,7 @@ int main (int argc, char *argv[]) { int qm_col = 0; int qm_slot = 0; int qm_shift = 0; - int qm_slots = QUICK_SWITCHER_COUNT > quick->count() ? quick->count() : QUICK_SWITCHER_COUNT; + int qm_slots = QUICK_SWITCHER_COUNT > (int)quick.size() ? (int)quick.size() : QUICK_SWITCHER_COUNT; // LOG_info("- menu init: %lu\n", SDL_GetTicks() - main_begin); int lastScreen = SCREEN_OFF; @@ -2286,7 +2240,7 @@ int main (int argc, char *argv[]) { PAD_poll(); int selected = top->selected; - int total = top->entries->count(); + int total = (int)top->entries.size(); PWR_update(&dirty, &show_setting, NULL, NULL); @@ -2308,7 +2262,7 @@ int main (int argc, char *argv[]) { int gsanimdir = ANIM_NONE; if (currentScreen == SCREEN_QUICKMENU) { - int qm_total = qm_row == 0 ? quick->count() : quickActions->count(); + int qm_total = qm_row == 0 ? (int)quick.size() : (int)quickActions.size(); if (PAD_justPressed(BTN_B) || PAD_tappedMenu(now)) { currentScreen = SCREEN_GAMELIST; @@ -2316,10 +2270,10 @@ int main (int argc, char *argv[]) { dirty = 1; } else if (PAD_justReleased(BTN_A)) { - Entry* selected = static_cast(qm_row == 0 ? quick->v[qm_col] : quickActions->v[qm_col]); + Entry* selected = (qm_row == 0 ? quick[qm_col] : quickActions[qm_col]); if(selected->type != ENTRY_DIP) { currentScreen = SCREEN_GAMELIST; - total = top->entries->count(); + total = (int)top->entries.size(); // prevent restoring list state, game list screen currently isnt our nav origin top->selected = 0; top->start = 0; @@ -2520,10 +2474,10 @@ int main (int argc, char *argv[]) { } if (PAD_justRepeated(BTN_L1) && !PAD_isPressed(BTN_R1) && !PWR_ignoreSettingInput(BTN_L1, show_setting)) { // previous alpha - Entry* entry = static_cast(top->entries->v[selected]); + Entry* entry = top->entries[selected]; int i = entry->alpha-1; if (i>=0) { - selected = (*top->alphas)[i]; + selected = top->alphas[i]; if (total>MAIN_ROW_COUNT) { top->start = selected; top->end = top->start + MAIN_ROW_COUNT; @@ -2533,10 +2487,10 @@ int main (int argc, char *argv[]) { } } else if (PAD_justRepeated(BTN_R1) && !PAD_isPressed(BTN_L1) && !PWR_ignoreSettingInput(BTN_R1, show_setting)) { // next alpha - Entry* entry = static_cast(top->entries->v[selected]); + Entry* entry = top->entries[selected]; int i = entry->alpha+1; - if (i<(int)top->alphas->size()) { - selected = (*top->alphas)[i]; + if (i<(int)top->alphas.size()) { + selected = top->alphas[i]; if (total>MAIN_ROW_COUNT) { top->start = selected; top->end = top->start + MAIN_ROW_COUNT; @@ -2551,7 +2505,7 @@ int main (int argc, char *argv[]) { dirty = 1; } - Entry* entry = static_cast(top->entries->v[top->selected]); + Entry* entry = top->entries[top->selected]; if (dirty && total>0) readyResume(entry); @@ -2566,19 +2520,19 @@ int main (int argc, char *argv[]) { Entry_open(entry); if(entry->type == ENTRY_DIR) { animationdirection = SLIDE_LEFT; - total = top->entries->count(); + total = (int)top->entries.size(); } dirty = 1; - if (total>0) readyResume(static_cast(top->entries->v[top->selected])); + if (total>0) readyResume(top->entries[top->selected]); } else if (PAD_justPressed(BTN_B) && (int)stack.size()>1) { closeDirectory(); animationdirection = SLIDE_RIGHT; - total = top->entries->count(); + total = (int)top->entries.size(); dirty = 1; - if (total>0) readyResume(static_cast(top->entries->v[top->selected])); + if (total>0) readyResume(top->entries[top->selected]); } } @@ -2612,7 +2566,7 @@ int main (int argc, char *argv[]) { GFX_clearLayers(LAYER_THUMBNAIL); } - Entry* current = static_cast(qm_row == 0 ? quick->v[qm_col] : quickActions->v[qm_col]); + Entry* current = (qm_row == 0 ? quick[qm_col] : quickActions[qm_col]); char newBgPath[MAX_PATH]; char fallbackBgPath[MAX_PATH]; @@ -2665,10 +2619,10 @@ int main (int argc, char *argv[]) { // just to keep selection visible. // every display should be able to fit three items, we shift horizontally to accomodate. ox -= qm_shift * (item_size + SCALE1(MENU_ITEM_MARGIN)); - for (int c = 0; c < quick->count(); c++) + for (int c = 0; c < (int)quick.size(); c++) { SDL_Rect item_rect = {ox, oy, item_size, item_size}; - Entry* item = static_cast(quick->v[c]); + Entry* item = quick[c]; SDL_Color text_color = uintToColour(THEME_COLOR4_255); uint32_t item_color = THEME_COLOR3; @@ -2712,11 +2666,11 @@ int main (int argc, char *argv[]) { // secondary ox = SCALE1(PADDING + MENU_MARGIN_X); - ox += (screen->w - SCALE1(PADDING + MENU_MARGIN_X + MENU_MARGIN_X + PADDING) - SCALE1(quickActions->count() * PILL_SIZE) - SCALE1((quickActions->count() - 1) * MENU_TOGGLE_MARGIN))/2; + ox += (screen->w - SCALE1(PADDING + MENU_MARGIN_X + MENU_MARGIN_X + PADDING) - SCALE1((int)quickActions.size() * PILL_SIZE) - SCALE1(((int)quickActions.size() - 1) * MENU_TOGGLE_MARGIN))/2; oy = SCALE1(PADDING + PILL_SIZE + BUTTON_MARGIN + MENU_MARGIN_Y + MENU_LINE_MARGIN) + item_size + item_extra_y / 2; - for (int c = 0; c < quickActions->count(); c++) { + for (int c = 0; c < (int)quickActions.size(); c++) { SDL_Rect item_rect = {ox, oy, SCALE1(PILL_SIZE), SCALE1(PILL_SIZE)}; - Entry* item = static_cast(quickActions->v[c]); + Entry* item = quickActions[c]; SDL_Color text_color = uintToColour(THEME_COLOR4_255); uint32_t item_color = THEME_COLOR3; @@ -2900,7 +2854,7 @@ int main (int argc, char *argv[]) { } else { // if currentscreen == SCREEN_GAMELIST // background and game art file path stuff - Entry* entry = static_cast(top->entries->v[top->selected]); + Entry* entry = top->entries[top->selected]; assert(entry); char tmp_path[MAX_PATH]; strncpy(tmp_path, entry->path, sizeof(tmp_path) - 1); @@ -3006,7 +2960,7 @@ int main (int argc, char *argv[]) { targetY = selected_row * PILL_SIZE; SDL_Color text_color = uintToColour(THEME_COLOR4_255); // list text color for (int i = top->start, j = 0; i < top->end; i++, j++) { - Entry* entry = static_cast(top->entries->v[i]); + Entry* entry = top->entries[i]; char* entry_name = entry->name; char* entry_unique = entry->unique; int available_width = MAX(0,(had_thumb ? ox + SCALE1(BUTTON_MARGIN) : screen->w - SCALE1(BUTTON_MARGIN)) - SCALE1(PADDING * 2)); @@ -3259,7 +3213,7 @@ int main (int argc, char *argv[]) { if (currentScreen != SCREEN_GAMESWITCHER && currentScreen != SCREEN_QUICKMENU) { if(is_scrolling && pillanimdone && currentAnimQueueSize < 1) { int ow = GFX_blitHardwareGroup(screen, show_setting); - Entry* entry = static_cast(top->entries->v[top->selected]); + Entry* entry = top->entries[top->selected]; trimSortingMeta(&entry->name); char* entry_text = entry->name; if (entry->unique) { @@ -3339,7 +3293,7 @@ int main (int argc, char *argv[]) { if (has_hdmi!=had_hdmi) { had_hdmi = has_hdmi; - Entry* entry = static_cast(top->entries->v[top->selected]); + Entry* entry = top->entries[top->selected]; LOG_info("restarting after HDMI change... (%s)\n", entry->path); saveLast(entry->path); // NOTE: doesn't work in Recents (by design) sleep(4); From 0452b21d4e155f6b030852027e5e3018665e9e49 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Wed, 1 Jul 2026 20:08:19 +0200 Subject: [PATCH 15/77] core: add misuse-proof bounded string helpers, adopt in nextui Phase B kicks off common/core/ - a modern-C++ utility layer the other binaries can share (settings now, minarch once it's C++). core/str.h has copy/format/append that take the destination by reference to a fixed-size char array, so N is deduced at compile time. The nice part: you physically can't call them on a decayed char* - that's a compile error, not the silent 8-byte 'size' you'd get from snprintf(ptr, sizeof(ptr), ...). So they can't overflow and can't be mis-sized. There's a desktop self-test (tests/str_test.cpp) covering copy/format/append incl. truncation. Adopted them in nextui.cpp: the 63 snprintf(buf, sizeof(buf), ...) array sites became core::format(buf, ...) and the one bounded strncat became core::append. That it all compiles is itself a proof that every one of those targets really is a fixed array - if any were secretly a pointer, the template wouldn't compile. The pointer/cursor/param string writes stay as plain snprintf with their real runtime size. Header-only, so no makefile wiring - -I../common already covers it. --- workspace/all/common/core/str.h | 58 +++++++++ workspace/all/common/core/tests/str_test.cpp | 64 +++++++++ workspace/all/nextui/nextui.cpp | 129 ++++++++++--------- 3 files changed, 187 insertions(+), 64 deletions(-) create mode 100644 workspace/all/common/core/str.h create mode 100644 workspace/all/common/core/tests/str_test.cpp diff --git a/workspace/all/common/core/str.h b/workspace/all/common/core/str.h new file mode 100644 index 000000000..dc43a4648 --- /dev/null +++ b/workspace/all/common/core/str.h @@ -0,0 +1,58 @@ +// core/str.h — type-safe bounded string helpers (C++, header-only). +// +// The point of these over raw snprintf/strcpy: the destination is taken by +// reference to a fixed-size char array, so its size N is deduced at compile +// time. You physically cannot call these on a decayed char* pointer — that's a +// compile error, not a silent 8-byte "size" like snprintf(ptr, sizeof(ptr), …) +// would give you. So they can't overflow and can't be mis-sized. +// +// For the cases where the destination genuinely is a pointer with a runtime +// length (a function param, or a cursor into a larger buffer), keep using +// snprintf directly with the real remaining size — these helpers are for the +// common "write into a local char buf[N]" case. +// +// Usable from any C++ translation unit (nextui, settings, and minarch once its +// modules are C++). Include as: #include "core/str.h" + +#ifndef NEXTUI_CORE_STR_H +#define NEXTUI_CORE_STR_H + +#include +#include +#include + +namespace core { + +// Bounded copy of src into dst[N]. Truncates rather than overflowing. A null +// src yields an empty string. Returns true if the whole source fit. +template +inline bool copy(char (&dst)[N], const char* src) { + int n = snprintf(dst, N, "%s", src ? src : ""); + return n >= 0 && static_cast(n) < N; +} + +// Bounded printf-style format into dst[N]. Truncates rather than overflowing. +// Returns true if the whole formatted string fit. +template +inline bool format(char (&dst)[N], const char* fmt, ...) { + va_list ap; + va_start(ap, fmt); + int n = vsnprintf(dst, N, fmt, ap); + va_end(ap); + return n >= 0 && static_cast(n) < N; +} + +// Bounded append of src onto the string already in dst[N] (like strlcat). +// Truncates rather than overflowing. Returns true if the whole source fit. +template +inline bool append(char (&dst)[N], const char* src) { + size_t len = 0; + while (len < N && dst[len] != '\0') len++; + if (len >= N) return false; // not null-terminated within the buffer + int n = snprintf(dst + len, N - len, "%s", src ? src : ""); + return n >= 0 && static_cast(len) + static_cast(n) < N; +} + +} // namespace core + +#endif // NEXTUI_CORE_STR_H diff --git a/workspace/all/common/core/tests/str_test.cpp b/workspace/all/common/core/tests/str_test.cpp new file mode 100644 index 000000000..55587d594 --- /dev/null +++ b/workspace/all/common/core/tests/str_test.cpp @@ -0,0 +1,64 @@ +// Desktop self-test for core/str.h. Pure, no dependencies — compile and run: +// g++ -std=c++17 -I../../ str_test.cpp -o str_test && ./str_test +// Exits non-zero on the first failed check. + +#include "core/str.h" +#include +#include + +static int failures = 0; +#define CHECK(cond) do { \ + if (!(cond)) { printf("FAIL %s:%d %s\n", __FILE__, __LINE__, #cond); failures++; } \ +} while (0) + +int main() { + // copy: normal + { + char b[16]; + CHECK(core::copy(b, "hello")); + CHECK(strcmp(b, "hello") == 0); + } + // copy: exact fit (15 chars + NUL in 16) + { + char b[16]; + CHECK(core::copy(b, "123456789012345")); + CHECK(strlen(b) == 15); + } + // copy: truncation returns false, stays NUL-terminated, no overflow + { + char b[8] = {}; + CHECK(!core::copy(b, "this is far too long")); + CHECK(strcmp(b, "this is") == 0); + CHECK(b[7] == '\0'); + } + // copy: null source -> empty + { + char b[8]; b[0] = 'x'; + CHECK(core::copy(b, nullptr)); + CHECK(b[0] == '\0'); + } + // format: normal + truncation + { + char b[16]; + CHECK(core::format(b, "%s-%d", "id", 42)); + CHECK(strcmp(b, "id-42") == 0); + char s[6]; + CHECK(!core::format(s, "%s", "toolong")); + CHECK(strcmp(s, "toolo") == 0); + } + // append: onto existing + truncation + { + char b[16]; + core::copy(b, "foo"); + CHECK(core::append(b, "bar")); + CHECK(strcmp(b, "foobar") == 0); + char s[8]; + core::copy(s, "abcd"); + CHECK(!core::append(s, "efghij")); + CHECK(strcmp(s, "abcdefg") == 0); + CHECK(s[7] == '\0'); + } + + if (failures == 0) printf("core/str.h: all checks passed\n"); + return failures == 0 ? 0 : 1; +} diff --git a/workspace/all/nextui/nextui.cpp b/workspace/all/nextui/nextui.cpp index 1d29495bb..527c5a978 100644 --- a/workspace/all/nextui/nextui.cpp +++ b/workspace/all/nextui/nextui.cpp @@ -15,6 +15,7 @@ #include #include #include +#include "core/str.h" extern "C" { #include @@ -157,7 +158,7 @@ static void Directory_index(Directory* self) { Hash* map = NULL; char map_path[256]; - snprintf(map_path, sizeof(map_path), "%s/map.txt", is_collection ? COLLECTIONS_PATH : self->path); + core::format(map_path, "%s/map.txt", is_collection ? COLLECTIONS_PATH : self->path); if (exists(map_path)) { FILE* file = fopen(map_path, "r"); @@ -329,7 +330,7 @@ static Recent* Recent_new(char* path, char* alias) { Recent* self = (Recent*)(malloc(sizeof(Recent))); char sd_path[256]; // only need to get emu name - snprintf(sd_path, sizeof(sd_path), "%s%s", SDCARD_PATH, path); + core::format(sd_path, "%s%s", SDCARD_PATH, path); char emu_name[256]; getEmuName(sd_path, emu_name); @@ -420,17 +421,17 @@ static Entry* entryFromPakName(char* pak_name) { char pak_path[256]; // Check in Tools - snprintf(pak_path, sizeof(pak_path), "%s/Tools/%s/%s.pak", SDCARD_PATH, PLATFORM, pak_name); + core::format(pak_path, "%s/Tools/%s/%s.pak", SDCARD_PATH, PLATFORM, pak_name); if(exists(pak_path)) return Entry_newNamed(pak_path, ENTRY_PAK, pak_name); // Check in Emus - snprintf(pak_path, sizeof(pak_path), "%s/Emus/%s.pak", PAKS_PATH, pak_name); + core::format(pak_path, "%s/Emus/%s.pak", PAKS_PATH, pak_name); if(exists(pak_path)) return Entry_newNamed(pak_path, ENTRY_PAK, pak_name); // Check in platform Emus - snprintf(pak_path, sizeof(pak_path), "%s/Emus/%s/%s.pak", SDCARD_PATH, PLATFORM, pak_name); + core::format(pak_path, "%s/Emus/%s/%s.pak", SDCARD_PATH, PLATFORM, pak_name); if(exists(pak_path)) return Entry_newNamed(pak_path, ENTRY_PAK, pak_name); @@ -439,10 +440,10 @@ static Entry* entryFromPakName(char* pak_name) static int hasEmu(char* emu_name) { char pak_path[256]; - snprintf(pak_path, sizeof(pak_path), "%s/Emus/%s.pak/launch.sh", PAKS_PATH, emu_name); + core::format(pak_path, "%s/Emus/%s.pak/launch.sh", PAKS_PATH, emu_name); if (exists(pak_path)) return 1; - snprintf(pak_path, sizeof(pak_path), "%s/Emus/%s/%s.pak/launch.sh", SDCARD_PATH, PLATFORM, emu_name); + core::format(pak_path, "%s/Emus/%s/%s.pak/launch.sh", SDCARD_PATH, PLATFORM, emu_name); return exists(pak_path); } static int hasCue(char* dir_path, char* cue_path) { // NOTE: dir_path not rom_path @@ -459,7 +460,7 @@ static int hasM3u(char* rom_path, char* m3u_path) { // NOTE: rom_path not dir_pa // path to parent directory char base_path[256]; - snprintf(base_path, sizeof(base_path), "%s", m3u_path); + core::format(base_path, "%s", m3u_path); tmp = strrchr(m3u_path, '/'); tmp[0] = '\0'; @@ -467,7 +468,7 @@ static int hasM3u(char* rom_path, char* m3u_path) { // NOTE: rom_path not dir_pa // get parent directory name char dir_name[256]; tmp = strrchr(m3u_path, '/'); - snprintf(dir_name, sizeof(dir_name), "%s", tmp); + core::format(dir_name, "%s", tmp); // dir_name is also our m3u file name tmp = m3u_path + strlen(m3u_path); @@ -496,7 +497,7 @@ static int hasRecents(void) { recents.push_back(recent); char parent_path[256]; - snprintf(parent_path, sizeof(parent_path), "%s", disc_path); + core::format(parent_path, "%s", disc_path); char* tmp = strrchr(parent_path, '/') + 1; tmp[0] = '\0'; parent_paths.push_back(strdup(parent_path)); @@ -523,14 +524,14 @@ static int hasRecents(void) { } char sd_path[256]; - snprintf(sd_path, sizeof(sd_path), "%s%s", SDCARD_PATH, path); + core::format(sd_path, "%s%s", SDCARD_PATH, path); if (exists(sd_path)) { if ((int)recents.size() getRoms() if (dh) { struct dirent* dp; char full_path[256]; - snprintf(full_path, sizeof(full_path), "%s/", ROMS_PATH); + core::format(full_path, "%s/", ROMS_PATH); char* tmp = full_path + strlen(full_path); std::vector emus; @@ -644,7 +645,7 @@ static std::vector getRoms() // Handle mapping logic char map_path[256]; - snprintf(map_path, sizeof(map_path), "%s/map.txt", ROMS_PATH); + core::format(map_path, "%s/map.txt", ROMS_PATH); if ((int)entries.size() > 0 && exists(map_path)) { FILE* file = fopen(map_path, "r"); if (file) { @@ -691,7 +692,7 @@ static std::vector getCollections(void) if (dh) { struct dirent* dp; char full_path[256]; - snprintf(full_path, sizeof(full_path), "%s/", COLLECTIONS_PATH); + core::format(full_path, "%s/", COLLECTIONS_PATH); char* tmp = full_path + strlen(full_path); std::vector collections; @@ -723,7 +724,7 @@ static std::vector getQuickEntries(void) { // Add tools if applicable if (hasTools() && !simple_mode) { char tools_path[256]; - snprintf(tools_path, sizeof(tools_path), "%s/Tools/%s", SDCARD_PATH, PLATFORM); + core::format(tools_path, "%s/Tools/%s", SDCARD_PATH, PLATFORM); entries.push_back(Entry_new(tools_path, ENTRY_DIR)); } @@ -778,7 +779,7 @@ static std::vector getRoot(void) { // Add tools if applicable if (hasTools() && CFG_getShowTools() && !simple_mode) { char tools_path[256]; - snprintf(tools_path, sizeof(tools_path), "%s/Tools/%s", SDCARD_PATH, PLATFORM); + core::format(tools_path, "%s/Tools/%s", SDCARD_PATH, PLATFORM); root.push_back(Entry_new(tools_path, ENTRY_DIR)); } @@ -791,7 +792,7 @@ static Entry* entryFromRecent(Recent* recent) return {}; char sd_path[256]; - snprintf(sd_path, sizeof(sd_path), "%s%s", SDCARD_PATH, recent->path); + core::format(sd_path, "%s%s", SDCARD_PATH, recent->path); int type = suffixMatch(".pak", sd_path) ? ENTRY_PAK : ENTRY_ROM; // ??? Entry* entry = Entry_new(sd_path, type); if (recent->alias) { @@ -823,7 +824,7 @@ static std::vector getCollection(char* path) { if (strlen(line)==0) continue; // skip empty lines char sd_path[256]; - snprintf(sd_path, sizeof(sd_path), "%s%s", SDCARD_PATH, line); + core::format(sd_path, "%s%s", SDCARD_PATH, line); if (exists(sd_path)) { int type = suffixMatch(".pak", sd_path) ? ENTRY_PAK : ENTRY_ROM; // ??? entries.push_back(Entry_new(sd_path, type)); @@ -846,7 +847,7 @@ static std::vector getDiscs(char* path){ std::vector entries; char base_path[256]; - snprintf(base_path, sizeof(base_path), "%s", path); + core::format(base_path, "%s", path); char* tmp = strrchr(base_path, '/') + 1; tmp[0] = '\0'; @@ -861,14 +862,14 @@ static std::vector getDiscs(char* path){ if (strlen(line)==0) continue; // skip empty lines char disc_path[256]; - snprintf(disc_path, sizeof(disc_path), "%s%s", base_path, line); + core::format(disc_path, "%s%s", base_path, line); if (exists(disc_path)) { disc += 1; Entry* entry = Entry_new(disc_path, ENTRY_ROM); free(entry->name); char name[16]; - snprintf(name, sizeof(name), "Disc %i", disc); + core::format(name, "Disc %i", disc); entry->name = strdup(name); entries.push_back(entry); } @@ -881,7 +882,7 @@ static int getFirstDisc(char* m3u_path, char* disc_path) { // based on getDiscs( int found = 0; char base_path[256]; - snprintf(base_path, sizeof(base_path), "%s", m3u_path); + core::format(base_path, "%s", m3u_path); char* tmp = strrchr(base_path, '/') + 1; tmp[0] = '\0'; @@ -909,7 +910,7 @@ static void addEntries(std::vector& entries, char* path) { struct dirent *dp; char* tmp; char full_path[256]; - snprintf(full_path, sizeof(full_path), "%s/", path); + core::format(full_path, "%s/", path); tmp = full_path + strlen(full_path); while((dp = readdir(dh)) != NULL) { if (hide(dp->d_name)) continue; @@ -942,7 +943,7 @@ static void addEntries(std::vector& entries, char* path) { static int isConsoleDir(char* path) { char* tmp; char parent_dir[256]; - snprintf(parent_dir, sizeof(parent_dir), "%s", path); + core::format(parent_dir, "%s", path); tmp = strrchr(parent_dir, '/'); tmp[0] = '\0'; @@ -954,7 +955,7 @@ static std::vector getEntries(char* path){ if (isConsoleDir(path)) { // top-level console folder, might collate char collated_path[256]; - snprintf(collated_path, sizeof(collated_path), "%s", path); + core::format(collated_path, "%s", path); char* tmp = strrchr(collated_path, '('); // 1 because we want to keep the opening parenthesis to avoid collating "Game Boy Color" and "Game Boy Advance" into "Game Boy" // but conditional so we can continue to support a bare tag name as a folder name @@ -964,7 +965,7 @@ static std::vector getEntries(char* path){ if (dh!=NULL) { struct dirent *dp; char full_path[256]; - snprintf(full_path, sizeof(full_path), "%s/", ROMS_PATH); + core::format(full_path, "%s/", ROMS_PATH); tmp = full_path + strlen(full_path); // while loop so we can collate paths, see above while((dp = readdir(dh)) != NULL) { @@ -1034,7 +1035,7 @@ static void readyResumePath(char* rom_path, int type) { can_resume = 0; has_preview = 0; char path[256]; - snprintf(path, sizeof(path), "%s", rom_path); + core::format(path, "%s", rom_path); if (!prefixMatch(ROMS_PATH, path)) return; @@ -1045,14 +1046,14 @@ static void readyResumePath(char* rom_path, int type) { snprintf(tmp, sizeof(auto_path) - (tmp - auto_path), "%s", "m3u"); // replace with m3u if (!exists(auto_path)) return; // no m3u } - snprintf(path, sizeof(path), "%s", auto_path); // cue or m3u if one exists + core::format(path, "%s", auto_path); // cue or m3u if one exists } if (!suffixMatch(".m3u", path)) { char m3u_path[256]; if (hasM3u(path, m3u_path)) { // change path to m3u path - snprintf(path, sizeof(path), "%s", m3u_path); + core::format(path, "%s", m3u_path); } } @@ -1061,9 +1062,9 @@ static void readyResumePath(char* rom_path, int type) { char rom_file[256]; tmp = strrchr(path, '/') + 1; - snprintf(rom_file, sizeof(rom_file), "%s", tmp); + core::format(rom_file, "%s", tmp); - snprintf(slot_path, sizeof(slot_path), "%s/.minui/%s/%s.txt", SHARED_USERDATA_PATH, emu_name, rom_file); // /.userdata/.minui//.ext.txt + core::format(slot_path, "%s/.minui/%s/%s.txt", SHARED_USERDATA_PATH, emu_name, rom_file); // /.userdata/.minui//.ext.txt can_resume = exists(slot_path); // slot_path contains a single integer representing the last used slot @@ -1071,7 +1072,7 @@ static void readyResumePath(char* rom_path, int type) { char slot[16]; getFile(slot_path, slot, 16); int s = atoi(slot); - snprintf(preview_path, sizeof(preview_path), "%s/.minui/%s/%s.%0d.bmp", SHARED_USERDATA_PATH, emu_name, rom_file, s); // /.userdata/.minui//.ext..bmp + core::format(preview_path, "%s/.minui/%s/%s.%0d.bmp", SHARED_USERDATA_PATH, emu_name, rom_file, s); // /.userdata/.minui//.ext..bmp has_preview = exists(preview_path); } } @@ -1094,7 +1095,7 @@ static int autoResume(void) { // make sure rom still exists char sd_path[256]; - snprintf(sd_path, sizeof(sd_path), "%s%s", SDCARD_PATH, path); + core::format(sd_path, "%s%s", SDCARD_PATH, path); if (!exists(sd_path)) return 0; // make sure emu still exists @@ -1109,12 +1110,12 @@ static int autoResume(void) { // putFile(LAST_PATH, FAUX_RECENT_PATH); // saveLast() will crash here because top is NULL char act[256]; - snprintf(act, sizeof(act), "gametimectl.elf start '%s'", escapeSingleQuotes(sd_path)); + core::format(act, "gametimectl.elf start '%s'", escapeSingleQuotes(sd_path)); system(act); char cmd[256]; // dont escape sd_path again because it was already escaped for gametimectl and function modifies input str aswell - snprintf(cmd, sizeof(cmd), "'%s' '%s'", escapeSingleQuotes(emu_path), sd_path); + core::format(cmd, "'%s' '%s'", escapeSingleQuotes(emu_path), sd_path); putInt(RESUME_SLOT_PATH, AUTO_RESUME_SLOT); queueNext(cmd); return 1; @@ -1129,20 +1130,20 @@ static void openPak(char* path) { saveLast(path); char cmd[256]; - snprintf(cmd, sizeof(cmd), "'%s/launch.sh'", escapeSingleQuotes(path)); + core::format(cmd, "'%s/launch.sh'", escapeSingleQuotes(path)); queueNext(cmd); } static void openRom(char* path, char* last) { LOG_info("openRom(%s,%s)\n", path, last); char sd_path[256]; - snprintf(sd_path, sizeof(sd_path), "%s", path); + core::format(sd_path, "%s", path); char m3u_path[256]; int has_m3u = hasM3u(sd_path, m3u_path); char recent_path[256]; - snprintf(recent_path, sizeof(recent_path), "%s", has_m3u ? m3u_path : sd_path); + core::format(recent_path, "%s", has_m3u ? m3u_path : sd_path); if (has_m3u && suffixMatch(".m3u", sd_path)) { getFirstDisc(m3u_path, sd_path); @@ -1159,19 +1160,19 @@ static void openRom(char* path, char* last) { if (has_m3u) { char rom_file[256]; - snprintf(rom_file, sizeof(rom_file), "%s", strrchr(m3u_path, '/') + 1); + core::format(rom_file, "%s", strrchr(m3u_path, '/') + 1); // get disc for state char disc_path_path[256]; - snprintf(disc_path_path, sizeof(disc_path_path), "%s/.minui/%s/%s.%s.txt", SHARED_USERDATA_PATH, emu_name, rom_file, slot); // /.userdata/arm-480/.minui//.ext.0.txt + core::format(disc_path_path, "%s/.minui/%s/%s.%s.txt", SHARED_USERDATA_PATH, emu_name, rom_file, slot); // /.userdata/arm-480/.minui//.ext.0.txt if (exists(disc_path_path)) { // switch to disc path char disc_path[256]; getFile(disc_path_path, disc_path, 256); - if (disc_path[0]=='/') snprintf(sd_path, sizeof(sd_path), "%s", disc_path); // absolute + if (disc_path[0]=='/') core::format(sd_path, "%s", disc_path); // absolute else { // relative - snprintf(sd_path, sizeof(sd_path), "%s", m3u_path); + core::format(sd_path, "%s", m3u_path); char* tmp = strrchr(sd_path, '/') + 1; snprintf(tmp, sizeof(sd_path) - (tmp - sd_path), "%s", disc_path); } @@ -1188,11 +1189,11 @@ static void openRom(char* path, char* last) { addRecent(recent_path, recent_alias); // yiiikes saveLast(last==NULL ? sd_path : last); char act[256]; - snprintf(act, sizeof(act), "gametimectl.elf start '%s'", escapeSingleQuotes(sd_path)); + core::format(act, "gametimectl.elf start '%s'", escapeSingleQuotes(sd_path)); system(act); char cmd[256]; // dont escape sd_path again because it was already escaped for gametimectl and function modifies input str aswell - snprintf(cmd, sizeof(cmd), "'%s' '%s'", escapeSingleQuotes(emu_path), sd_path); + core::format(cmd, "'%s' '%s'", escapeSingleQuotes(emu_path), sd_path); queueNext(cmd); } @@ -1254,7 +1255,7 @@ std::vector pathToStack(const char* path) { if (exactMatch(path, SDCARD_PATH)) return array; char temp_path[PATH_MAX]; - snprintf(temp_path, sizeof(temp_path), "%s", SDCARD_PATH); + core::format(temp_path, "%s", SDCARD_PATH); size_t current_len = strlen(SDCARD_PATH); const char* cursor = path + current_len; @@ -1278,7 +1279,7 @@ std::vector pathToStack(const char* path) { // Append segment if (current_len + segment_len >= PATH_MAX) break; - strncat(temp_path, segment, sizeof(temp_path)-strlen(temp_path)-1); + core::append(temp_path, segment); current_len += segment_len; if (strcmp(segment, PLATFORM) == 0) { @@ -1317,7 +1318,7 @@ static void openDirectory(char* path, int auto_launch) { } char m3u_path[256]; - snprintf(m3u_path, sizeof(m3u_path), "%s", auto_path); + core::format(m3u_path, "%s", auto_path); char* tmp = strrchr(m3u_path, '.') + 1; // extension snprintf(tmp, sizeof(m3u_path) - (tmp - m3u_path), "%s", "m3u"); // replace with m3u if (exists(m3u_path) && auto_launch) { @@ -1356,7 +1357,7 @@ static void openDirectory(char* path, int auto_launch) { else { // keep a copy of path, which might be a reference into stack which is about to be freed char temp_path[256]; - snprintf(temp_path, sizeof(temp_path), "%s", path); + core::format(temp_path, "%s", path); // construct a fresh stack by walking upwards until SDCARD_ROOT DirectoryArray_free(stack); @@ -1412,10 +1413,10 @@ static void Entry_open(Entry* self) { char filename[256]; tmp = strrchr(self->path, '/'); - if (tmp) snprintf(filename, sizeof(filename), "%s", tmp+1); + if (tmp) core::format(filename, "%s", tmp+1); char last_path[256]; - snprintf(last_path, sizeof(last_path), "%s/%s", top->path, filename); + core::format(last_path, "%s/%s", top->path, filename); last = last_path; } openRom(self->path, last); @@ -1451,12 +1452,12 @@ static void loadLast(void) { // call after loading root directory getFile(LAST_PATH, last_path, 256); char full_path[256]; - snprintf(full_path, sizeof(full_path), "%s", last_path); + core::format(full_path, "%s", last_path); char* tmp; char filename[256]; tmp = strrchr(last_path, '/'); - if (tmp) snprintf(filename, sizeof(filename), "%s", tmp); + if (tmp) core::format(filename, "%s", tmp); std::vector last; while (!exactMatch(last_path, SDCARD_PATH)) { @@ -1473,7 +1474,7 @@ static void loadLast(void) { // call after loading root directory char collated_path[256]; collated_path[0] = '\0'; if (suffixMatch(")", path) && isConsoleDir(path)) { - snprintf(collated_path, sizeof(collated_path), "%s", path); + core::format(collated_path, "%s", path); tmp = strrchr(collated_path, '('); if (tmp) tmp[1] = '\0'; // 1 because we want to keep the opening parenthesis to avoid collating "Game Boy Color" and "Game Boy Advance" into "Game Boy" } @@ -2570,10 +2571,10 @@ int main (int argc, char *argv[]) { char newBgPath[MAX_PATH]; char fallbackBgPath[MAX_PATH]; - snprintf(newBgPath, sizeof(newBgPath), SDCARD_PATH "/.media/quick_%s%s.png", current->name, + core::format(newBgPath, SDCARD_PATH "/.media/quick_%s%s.png", current->name, !strcmp(current->name,"Wifi") && !CFG_getWifi() || // wifi or wifi_off, based on state !strcmp(current->name,"Bluetooth") && !CFG_getBluetooth() ? "_off" : ""); // bluetooth or bluetooth_off, based on state - snprintf(fallbackBgPath, sizeof(fallbackBgPath), SDCARD_PATH "/.media/quick.png"); + core::format(fallbackBgPath, SDCARD_PATH "/.media/quick.png"); // background if(!exists(newBgPath)) @@ -2637,7 +2638,7 @@ int main (int argc, char *argv[]) { GFX_blitRectColor(ASSET_STATE_BG, screen, &item_rect, item_color); char icon_path[MAX_PATH]; - snprintf(icon_path, sizeof(icon_path), SDCARD_PATH "/.system/res/%s@%ix.png", item->name, FIXED_SCALE); + core::format(icon_path, SDCARD_PATH "/.system/res/%s@%ix.png", item->name, FIXED_SCALE); SDL_Surface* bmp = IMG_Load(icon_path); if(bmp) { SDL_Surface* converted = SDL_ConvertSurfaceFormat(bmp, screen->format->format, 0); @@ -2883,7 +2884,7 @@ int main (int argc, char *argv[]) { // load folder background char defaultBgPath[512]; - snprintf(defaultBgPath, sizeof(defaultBgPath), SDCARD_PATH "/bg.png"); + core::format(defaultBgPath, SDCARD_PATH "/bg.png"); if(((entry->type == ENTRY_DIR || entry->type == ENTRY_ROM) && CFG_getRomsUseFolderBackground())) { char *newBg = entry->type == ENTRY_DIR ? entry->path:rompath; @@ -2892,13 +2893,13 @@ int main (int argc, char *argv[]) { char tmppath[512]; strncpy(folderBgPath, newBg, sizeof(folderBgPath) - 1); if (entry->type == ENTRY_DIR) - snprintf(tmppath, sizeof(tmppath), "%s/.media/bg.png", folderBgPath); + core::format(tmppath, "%s/.media/bg.png", folderBgPath); else if (entry->type == ENTRY_ROM) - snprintf(tmppath, sizeof(tmppath), "%s/.media/bglist.png", folderBgPath); + core::format(tmppath, "%s/.media/bglist.png", folderBgPath); if(!exists(tmppath)) { // Safeguard: If no background is available, still render the text to leave the user a way out list_show_entry_names = true; - snprintf(tmppath, sizeof(tmppath), defaultBgPath, folderBgPath); + core::format(tmppath, defaultBgPath, folderBgPath); } startLoadFolderBackground(tmppath, onBackgroundLoaded, NULL); } @@ -2915,7 +2916,7 @@ int main (int argc, char *argv[]) { if (total > 0) { if(CFG_getShowGameArt()) { char thumbpath[1024]; - snprintf(thumbpath, sizeof(thumbpath), "%s/.media/%s.png", rompath, res_copy); + core::format(thumbpath, "%s/.media/%s.png", rompath, res_copy); had_thumb = 0; startLoadThumb(thumbpath, onThumbLoaded, NULL); int max_w = (int)(screen->w - (screen->w * CFG_getGameArtWidth())); From 571fe9767e2596598e56d75d837f8444408c5145 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Wed, 1 Jul 2026 20:17:52 +0200 Subject: [PATCH 16/77] minarch: bound the string writes in ma_game.c Starts the minarch robustness pass (Phase E), in plain C - no C++ conversion, since these files are emulation-critical and full of C-isms (designated inits etc). Same approach as the nextui string work: - Array and struct-field targets (game.path/name/alt_name/m3u_path, local path buffers) get snprintf(T, sizeof(T), ...); dropped the redundant (char*) casts on the game.* fields. - The tmp m3u-path cursor is bounded to the space left in m3u_path. The dangerous ones here were the filename copies - strcpy(game.name, strrchr(path,'/')+1) into a 128-byte field would overflow on a long ROM name. Now it truncates. --- workspace/all/minarch/ma_game.c | 36 ++++++++++++++++----------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/workspace/all/minarch/ma_game.c b/workspace/all/minarch/ma_game.c index d971c388f..3048e54c2 100644 --- a/workspace/all/minarch/ma_game.c +++ b/workspace/all/minarch/ma_game.c @@ -17,9 +17,9 @@ void Game_open(char* path) { int skipzip = 0; memset(&game, 0, sizeof(game)); - strcpy((char*)game.path, path); - strcpy((char*)game.name, strrchr(path, '/')+1); - strcpy((char*)game.alt_name, game.name); // default it + snprintf(game.path, sizeof(game.path), "%s", path); + snprintf(game.name, sizeof(game.name), "%s", strrchr(path, '/')+1); + snprintf(game.alt_name, sizeof(game.alt_name), "%s", game.name); // default it // check first if the rom already is alive in tmp folder if so skip unzipping shit char tmpfldr[255]; @@ -30,11 +30,11 @@ void Game_open(char* path) { struct stat st; if (stat(tmppath, &st) == 0 && st.st_size > 0) { printf("File exists skipping unzipping and setting game.tmp_path: %s\n", tmppath); - strcpy((char*)game.tmp_path, tmppath); + snprintf(game.tmp_path, sizeof(game.tmp_path), "%s", tmppath); skipzip = 1; // Update the game name to the extracted file name instead of the zip name if (CFG_getUseExtractedFileName()) - strcpy((char*)game.alt_name, strrchr(game.tmp_path, '/')+1); + snprintf(game.alt_name, sizeof(game.alt_name), "%s", strrchr(game.tmp_path, '/')+1); } else { printf("File exists but is empty or inaccessible, will re-extract: %s\n", tmppath); } @@ -51,7 +51,7 @@ void Game_open(char* path) { char* ext; char exts[128]; char* extensions[32]; - strcpy(exts,core.extensions); + snprintf(exts, sizeof(exts), "%s", core.extensions); while ((ext=strtok(i?NULL:exts,"|"))) { extensions[i++] = ext; if (!strcmp("zip", ext)) { @@ -70,7 +70,7 @@ void Game_open(char* path) { return; // Update the game name to the extracted file name instead of the zip name if (CFG_getUseExtractedFileName()) - strcpy((char*)game.alt_name, strrchr(game.tmp_path, '/')+1); + snprintf(game.alt_name, sizeof(game.alt_name), "%s", strrchr(game.tmp_path, '/')+1); } else { LOG_info("Core can handle zip file: %s\n", game.path); @@ -109,28 +109,28 @@ void Game_open(char* path) { char base_path[256]; char dir_name[256]; - strcpy(m3u_path, game.path); + snprintf(m3u_path, sizeof(m3u_path), "%s", game.path); tmp = strrchr(m3u_path, '/') + 1; tmp[0] = '\0'; - strcpy(base_path, m3u_path); + snprintf(base_path, sizeof(base_path), "%s", m3u_path); tmp = strrchr(m3u_path, '/'); tmp[0] = '\0'; tmp = strrchr(m3u_path, '/'); - strcpy(dir_name, tmp); + snprintf(dir_name, sizeof(dir_name), "%s", tmp); tmp = m3u_path + strlen(m3u_path); - strcpy(tmp, dir_name); + snprintf(tmp, sizeof(m3u_path) - (tmp - m3u_path), "%s", dir_name); tmp = m3u_path + strlen(m3u_path); - strcpy(tmp, ".m3u"); + snprintf(tmp, sizeof(m3u_path) - (tmp - m3u_path), "%s", ".m3u"); if (exists(m3u_path)) { - strcpy(game.m3u_path, m3u_path); - strcpy((char*)game.name, strrchr(m3u_path, '/')+1); - strcpy((char*)game.alt_name, game.name); // default it + snprintf(game.m3u_path, sizeof(game.m3u_path), "%s", m3u_path); + snprintf(game.name, sizeof(game.name), "%s", strrchr(m3u_path, '/')+1); + snprintf(game.alt_name, sizeof(game.alt_name), "%s", game.name); // default it } game.is_open = 1; @@ -186,12 +186,12 @@ int extract_zip(char** extensions) if (zip_stat_index(za, i, 0, &sb) == 0) { len = strlen(sb.name); if (sb.name[len - 1] == '/') { - sprintf(game.tmp_path, "%s/%s", tmp_dirname, basename((char*)sb.name)); + snprintf(game.tmp_path, sizeof(game.tmp_path), "%s/%s", tmp_dirname, basename((char*)sb.name)); } else { int found = 0; char extension[8]; for (int e=0; extensions[e]; e++) { - sprintf(extension, ".%s", extensions[e]); + snprintf(extension, sizeof(extension), ".%s", extensions[e]); if (suffixMatch(extension, sb.name)) { found = 1; break; @@ -199,7 +199,7 @@ int extract_zip(char** extensions) } if (!found) continue; - sprintf(game.tmp_path, "%s/%s", tmp_dirname, basename((char*)sb.name)); + snprintf(game.tmp_path, sizeof(game.tmp_path), "%s/%s", tmp_dirname, basename((char*)sb.name)); // Check if file already exists and has the correct size struct stat st; From f0654aca6f49a2fa7d6457f1cb1e1d2eb250c2e7 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Wed, 1 Jul 2026 20:21:02 +0200 Subject: [PATCH 17/77] minarch: bound the string writes in ma_config.c Config path/key/value buffers now snprintf with sizeof. The param and cursor cases handled explicitly: Config_getPath's filename is MAX_PATH at every caller; the default.cfg path cursors are bounded to the space left in their path buffer. The calloc(strlen+1)+strcpy dup became a plain strdup. --- workspace/all/minarch/ma_config.c | 37 +++++++++++++++---------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/workspace/all/minarch/ma_config.c b/workspace/all/minarch/ma_config.c index 9d060677b..48fb008d9 100644 --- a/workspace/all/minarch/ma_config.c +++ b/workspace/all/minarch/ma_config.c @@ -300,9 +300,9 @@ char** list_files_in_folder(const char* folderPath, int* fileCount, const char* // CONFIG_WRITE_ALL, CONFIG_WRITE_GAME defined in minarch_internal.h static void Config_getPath(char* filename, int override) { char device_tag[64] = {0}; - if (config.device_tag) sprintf(device_tag,"-%s",config.device_tag); - if (override) sprintf(filename, "%s/%s%s.cfg", core.config_dir, game.alt_name, device_tag); - else sprintf(filename, "%s/minarch%s.cfg", core.config_dir, device_tag); + if (config.device_tag) snprintf(device_tag, sizeof(device_tag), "-%s",config.device_tag); + if (override) snprintf(filename, MAX_PATH, "%s/%s%s.cfg", core.config_dir, game.alt_name, device_tag); + else snprintf(filename, MAX_PATH, "%s/minarch%s.cfg", core.config_dir, device_tag); LOG_info("Config_getPath %s\n", filename); } void Config_init(void) { @@ -361,8 +361,7 @@ void Config_init(void) { LOG_info("\tbind %s (%s) %i:%i\n", button_name, button_id, local_id, retro_id); // TODO: test this without a final line return - tmp2 = calloc(strlen(button_name)+1, sizeof(char)); - strcpy(tmp2, button_name); + tmp2 = strdup(button_name); ButtonMapping* button = &core_button_mapping[i++]; button->name = tmp2; button->retro = retro_id; @@ -459,8 +458,8 @@ static void Config_readControlsString(char* cfg) { char* tmp; for (int i=0; config.controls[i].name; i++) { ButtonMapping* mapping = &config.controls[i]; - sprintf(key, "bind %s", mapping->name); - sprintf(value, "NONE"); + snprintf(key, sizeof(key), "bind %s", mapping->name); + snprintf(value, sizeof(value), "NONE"); if (!Config_getValue(cfg, key, value, NULL)) continue; if ((tmp = strrchr(value, ':'))) *tmp = '\0'; // this is a binding artifact in default.cfg, ignore @@ -486,8 +485,8 @@ static void Config_readControlsString(char* cfg) { for (int i=0; config.shortcuts[i].name; i++) { ButtonMapping* mapping = &config.shortcuts[i]; - sprintf(key, "bind %s", mapping->name); - sprintf(value, "NONE"); + snprintf(key, sizeof(key), "bind %s", mapping->name); + snprintf(value, sizeof(value), "NONE"); if (!Config_getValue(cfg, key, value, NULL)) continue; @@ -527,7 +526,7 @@ void Config_load(void) { char* system_path = SYSTEM_PATH "/system.cfg"; char device_system_path[MAX_PATH] = {0}; - if (config.device_tag) sprintf(device_system_path, SYSTEM_PATH "/system-%s.cfg", config.device_tag); + if (config.device_tag) snprintf(device_system_path, sizeof(device_system_path), SYSTEM_PATH "/system-%s.cfg", config.device_tag); if (config.device_tag && exists(device_system_path)) { LOG_info("usng device_system_path: %s\n", device_system_path); @@ -541,15 +540,15 @@ void Config_load(void) { char default_path[MAX_PATH]; getEmuPath((char *)core.tag, default_path); char* tmp = strrchr(default_path, '/'); - strcpy(tmp,"/default.cfg"); + snprintf(tmp, sizeof(default_path) - (tmp - default_path), "%s", "/default.cfg"); char device_default_path[MAX_PATH] = {0}; if (config.device_tag) { getEmuPath((char *)core.tag, device_default_path); tmp = strrchr(device_default_path, '/'); char filename[64]; - sprintf(filename,"/default-%s.cfg", config.device_tag); - strcpy(tmp,filename); + snprintf(filename, sizeof(filename), "/default-%s.cfg", config.device_tag); + snprintf(tmp, sizeof(device_default_path) - (tmp - device_default_path), "%s", filename); } if (config.device_tag && exists(device_default_path)) { @@ -591,7 +590,7 @@ void Config_readControls(void) { } void Config_write(int override) { char path[MAX_PATH]; - // sprintf(path, "%s/%s.cfg", core.config_dir, game.alt_name); + // snprintf(path, sizeof(path), "%s/%s.cfg", core.config_dir, game.alt_name); Config_getPath(path, CONFIG_WRITE_GAME); if (!override) { @@ -655,14 +654,14 @@ void Config_write(int override) { void Config_restore(void) { char path[MAX_PATH]; if (config.loaded==CONFIG_GAME) { - if (config.device_tag) sprintf(path, "%s/%s-%s.cfg", core.config_dir, game.alt_name, config.device_tag); - else sprintf(path, "%s/%s.cfg", core.config_dir, game.alt_name); + if (config.device_tag) snprintf(path, sizeof(path), "%s/%s-%s.cfg", core.config_dir, game.alt_name, config.device_tag); + else snprintf(path, sizeof(path), "%s/%s.cfg", core.config_dir, game.alt_name); unlink(path); LOG_info("deleted game config: %s\n", path); } else if (config.loaded==CONFIG_CONSOLE) { - if (config.device_tag) sprintf(path, "%s/minarch-%s.cfg", core.config_dir, config.device_tag); - else sprintf(path, "%s/minarch.cfg", core.config_dir); + if (config.device_tag) snprintf(path, sizeof(path), "%s/minarch-%s.cfg", core.config_dir, config.device_tag); + else snprintf(path, sizeof(path), "%s/minarch.cfg", core.config_dir); unlink(path); LOG_info("deleted console config: %s\n", path); } @@ -709,7 +708,7 @@ void Config_restore(void) { void readShadersPreset(int i) { char shaderspath[MAX_PATH] = {0}; - sprintf(shaderspath, SHADERS_FOLDER "/%s", config.shaders.options[SH_SHADERS_PRESET].values[i]); + snprintf(shaderspath, sizeof(shaderspath), SHADERS_FOLDER "/%s", config.shaders.options[SH_SHADERS_PRESET].values[i]); LOG_info("read shaders preset %s\n",shaderspath); if (exists(shaderspath)) { config.shaders_preset = allocFile(shaderspath); From 9d11e3186bc6457ea1d5faa8dc8fe94453597762 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Wed, 1 Jul 2026 20:30:34 +0200 Subject: [PATCH 18/77] minarch: bound the string writes across the remaining ma_*.c Finishes the minarch robustness pass - zero raw sprintf/strcpy/strcat left in the whole frontend. All in plain C (these stay .c for now). - Local + struct-field char arrays (game/core/menu fields, path buffers, cheat paths[][MAX_PATH]) -> snprintf with sizeof; const Core fields keep their (char*) cast. - Params bounded to the caller's real size: ma_saves filename is MAX_PATH; getAlias's alias is >=256 everywhere; Core_getName got an explicit out_size param (its one caller passes sizeof(core.name)) so the basename copy can't overflow core.name[128]. - The tmp path cursors are bounded to the space left in their parent. - The calloc(strlen+1)+strcpy dups became strdup - which also fixes a latent mis-size in ma_options where item->name was allocated for def->desc but copied getOptionNameFromKey()'s (possibly longer) result. Careful bit: an earlier auto-convert pass naively used sizeof() on struct-field targets, but field names like key/value are ambiguous across structs and some are char* (sizeof would be 8 -> truncation). Reverted that and classified every struct-field target by its real type. --- workspace/all/minarch/ma_cheats.c | 29 ++++++++++----------- workspace/all/minarch/ma_core.c | 26 +++++++++---------- workspace/all/minarch/ma_core.h | 2 +- workspace/all/minarch/ma_frontend_opts.c | 11 ++++---- workspace/all/minarch/ma_menu.c | 32 ++++++++++++------------ workspace/all/minarch/ma_options.c | 18 +++++-------- workspace/all/minarch/ma_saves.c | 26 +++++++++---------- workspace/all/minarch/ma_video.c | 32 ++++++++++++------------ workspace/all/minarch/minarch.c | 6 ++--- 9 files changed, 88 insertions(+), 94 deletions(-) diff --git a/workspace/all/minarch/ma_cheats.c b/workspace/all/minarch/ma_cheats.c index 289a2a303..1f5dbce75 100644 --- a/workspace/all/minarch/ma_cheats.c +++ b/workspace/all/minarch/ma_cheats.c @@ -168,9 +168,9 @@ void Cheat_getPaths(char paths[CHEAT_MAX_PATHS][MAX_PATH], int* count) { const int sanitized_paths_count = 3; // Generate possible paths, ordered by most likely to be used (pre v6.2.3 style first) - sprintf(paths[(*count)++], "%s/%s.cht", core.cheats_dir, game.name); // /mnt/SDCARD/Cheats/GB/Super Example World..cht + snprintf(paths[(*count)++], MAX_PATH, "%s/%s.cht", core.cheats_dir, game.name); // /mnt/SDCARD/Cheats/GB/Super Example World..cht if(CFG_getUseExtractedFileName()) - sprintf(paths[(*count)++], "%s/%s.cht", core.cheats_dir, game.alt_name); // /mnt/SDCARD/Cheats/GB/Super Example World (USA)..cht + snprintf(paths[(*count)++], MAX_PATH, "%s/%s.cht", core.cheats_dir, game.alt_name); // /mnt/SDCARD/Cheats/GB/Super Example World (USA)..cht // game.alt_name, but with all extension-like stuff removed (apart from .cht) // eg. Super Example World (USA).zip -> Super Example World (USA).cht @@ -183,7 +183,7 @@ void Cheat_getPaths(char paths[CHEAT_MAX_PATHS][MAX_PATH], int* count) { return; } - strcpy(exts, core.extensions); + snprintf(exts, sizeof(exts), "%s", core.extensions); while ((ext = strtok(i ? NULL : exts, "|"))) { // sanitized_paths_count slots are reserved for sanitized rom name, see below if (*count >= CHEAT_MAX_PATHS - sanitized_paths_count) { @@ -198,7 +198,7 @@ void Cheat_getPaths(char paths[CHEAT_MAX_PATHS][MAX_PATH], int* count) { continue; } - strcpy(rom_name, game.alt_name); + snprintf(rom_name, sizeof(rom_name), "%s", game.alt_name); char* tmp = strrchr(rom_name, '.'); if (tmp != NULL && strlen(tmp) > 2 && strlen(tmp) <= 5) { tmp[0] = '\0'; @@ -206,7 +206,7 @@ void Cheat_getPaths(char paths[CHEAT_MAX_PATHS][MAX_PATH], int* count) { // Add length check before sprintf to prevent buffer overflow int needed_len = strlen(core.cheats_dir) + strlen(rom_name) + strlen(ext) + 10; // +10 for "/", ".", ".cht", etc. if (needed_len < MAX_PATH) { - sprintf(paths[(*count)++], "%s/%s.%s.cht", core.cheats_dir, rom_name, ext); + snprintf(paths[(*count)++], MAX_PATH, "%s/%s.%s.cht", core.cheats_dir, rom_name, ext); } else { LOG_info("Path too long, skipping: %s/%s.%s.cht\n", core.cheats_dir, rom_name, ext); } @@ -222,24 +222,25 @@ void Cheat_getPaths(char paths[CHEAT_MAX_PATHS][MAX_PATH], int* count) { // Important: update `sanitized_paths_count` if adding more sanitized variations char rom_name[MAX_PATH]; getDisplayName(game.alt_name, rom_name); - sprintf(paths[(*count)++], "%s/%s.cht", core.cheats_dir, rom_name); // /mnt/SDCARD/Cheats/GB/Super Example World.cht + snprintf(paths[(*count)++], MAX_PATH, "%s/%s.cht", core.cheats_dir, rom_name); // /mnt/SDCARD/Cheats/GB/Super Example World.cht // Respect map.txt: use alias if available // eg. 1941.zip -> 1941: Counter Attack if(getAlias(game.path, rom_name)) - sprintf(paths[(*count)++], "%s/%s.cht", core.cheats_dir, rom_name); // /mnt/SDCARD/Cheats/GB/Super Example World.cht + snprintf(paths[(*count)++], MAX_PATH, "%s/%s.cht", core.cheats_dir, rom_name); // /mnt/SDCARD/Cheats/GB/Super Example World.cht // Santitized alias, ignoring all extra cruft - including Cheat specifics like "(Game Breaker)" etc. // This is a wildcard that may match something unexpected, but also may find something when nothing else does. getAlias(game.path, rom_name); - sprintf(paths[(*count)++], "%s/%s*.cht", core.cheats_dir, rom_name); // /mnt/SDCARD/Cheats/GB/Super Example World*.cht + snprintf(paths[(*count)++], MAX_PATH, "%s/%s*.cht", core.cheats_dir, rom_name); // /mnt/SDCARD/Cheats/GB/Super Example World*.cht // Log all path candidates { - char *list = calloc(*count * (MAX_PATH + 2) + 1, 1); // path + separator for each entry + size_t list_sz = *count * (MAX_PATH + 2) + 1; + char *list = calloc(list_sz, 1); // path + separator for each entry if (list != NULL) { int i; for (i=0; i<*count; i++) { - strcat(list, paths[i]); - if (i < *count-1) strcat(list, ", "); + strncat(list, paths[i], list_sz - strlen(list) - 1); + if (i < *count-1) strncat(list, ", ", list_sz - strlen(list) - 1); } //LOG_info("Cheat paths to check: %s\n", list); free(list); @@ -278,7 +279,7 @@ bool Cheats_load() { if (strchr(paths[i],'*')) { // Use glob to handle wildcards char glob_pattern[MAX_PATH]; - strcpy(glob_pattern, paths[i]); + snprintf(glob_pattern, sizeof(glob_pattern), "%s", paths[i]); glob_t glob_results; memset(&glob_results, 0, sizeof(glob_t)); @@ -287,7 +288,7 @@ bool Cheats_load() { if (glob_ret == 0 && glob_results.gl_pathc > 0) { for (size_t gi = 0; gi < glob_results.gl_pathc; ++gi) { if (!suffixMatch(".cht", glob_results.gl_pathv[gi])) continue; - strcpy(filename, glob_results.gl_pathv[gi]); + snprintf(filename, sizeof(filename), "%s", glob_results.gl_pathv[gi]); if (exists(filename)) { LOG_info("Found potential cheat file: %s\n", filename); break; @@ -298,7 +299,7 @@ bool Cheats_load() { globfree(&glob_results); if (filename[0] == '\0') continue; // no match } else { - strcpy(filename, paths[i]); + snprintf(filename, sizeof(filename), "%s", paths[i]); if (!exists(filename)) { filename[0] = '\0'; continue; diff --git a/workspace/all/minarch/ma_core.c b/workspace/all/minarch/ma_core.c index 771c8fb10..b5ab3fe02 100644 --- a/workspace/all/minarch/ma_core.c +++ b/workspace/all/minarch/ma_core.c @@ -11,8 +11,8 @@ #include "ma_core.h" -void Core_getName(char* in_name, char* out_name) { - strcpy(out_name, basename(in_name)); +void Core_getName(char* in_name, char* out_name, size_t out_size) { + snprintf(out_name, out_size, "%s", basename(in_name)); char* tmp = strrchr(out_name, '_'); tmp[0] = '\0'; } @@ -61,24 +61,24 @@ void Core_open(const char* core_path, const char* tag_name) { LOG_info("Block Extract: %d\n", info.block_extract); - Core_getName((char*)core_path, (char*)core.name); - sprintf((char*)core.version, "%s (%s)", info.library_name, info.library_version); - strcpy((char*)core.tag, tag_name); - strcpy((char*)core.extensions, info.valid_extensions); + Core_getName((char*)core_path, (char*)core.name, sizeof(core.name)); + snprintf((char*)core.version, sizeof(core.version), "%s (%s)", info.library_name, info.library_version); + snprintf((char*)core.tag, sizeof(core.tag), "%s", tag_name); + snprintf((char*)core.extensions, sizeof(core.extensions), "%s", info.valid_extensions); core.need_fullpath = info.need_fullpath; LOG_info("core: %s version: %s tag: %s (valid_extensions: %s need_fullpath: %i)\n", core.name, core.version, core.tag, info.valid_extensions, info.need_fullpath); - sprintf((char*)core.config_dir, USERDATA_PATH "/%s-%s", core.tag, core.name); - sprintf((char*)core.states_dir, SHARED_USERDATA_PATH "/%s-%s", core.tag, core.name); - sprintf((char*)core.saves_dir, SDCARD_PATH "/Saves/%s", core.tag); - sprintf((char*)core.bios_dir, SDCARD_PATH "/Bios/%s", core.tag); - sprintf((char*)core.cheats_dir, SDCARD_PATH "/Cheats/%s", core.tag); - sprintf((char*)core.overlays_dir, SDCARD_PATH "/Overlays/%s", core.tag); + snprintf((char*)core.config_dir, sizeof(core.config_dir), USERDATA_PATH "/%s-%s", core.tag, core.name); + snprintf((char*)core.states_dir, sizeof(core.states_dir), SHARED_USERDATA_PATH "/%s-%s", core.tag, core.name); + snprintf((char*)core.saves_dir, sizeof(core.saves_dir), SDCARD_PATH "/Saves/%s", core.tag); + snprintf((char*)core.bios_dir, sizeof(core.bios_dir), SDCARD_PATH "/Bios/%s", core.tag); + snprintf((char*)core.cheats_dir, sizeof(core.cheats_dir), SDCARD_PATH "/Cheats/%s", core.tag); + snprintf((char*)core.overlays_dir, sizeof(core.overlays_dir), SDCARD_PATH "/Overlays/%s", core.tag); char cmd[512]; - sprintf(cmd, "mkdir -p \"%s\"; mkdir -p \"%s\"", core.config_dir, core.states_dir); + snprintf(cmd, sizeof(cmd), "mkdir -p \"%s\"; mkdir -p \"%s\"", core.config_dir, core.states_dir); system(cmd); set_environment_callback(environment_callback); diff --git a/workspace/all/minarch/ma_core.h b/workspace/all/minarch/ma_core.h index 482e15170..b361d20b4 100644 --- a/workspace/all/minarch/ma_core.h +++ b/workspace/all/minarch/ma_core.h @@ -1,6 +1,6 @@ #pragma once -void Core_getName(char* in_name, char* out_name); +void Core_getName(char* in_name, char* out_name, size_t out_size); void Core_open(const char* core_path, const char* tag_name); void Core_init(void); void Core_applyCheats(struct Cheats *cheats); diff --git a/workspace/all/minarch/ma_frontend_opts.c b/workspace/all/minarch/ma_frontend_opts.c index 3c786b96c..e687722cb 100644 --- a/workspace/all/minarch/ma_frontend_opts.c +++ b/workspace/all/minarch/ma_frontend_opts.c @@ -514,8 +514,7 @@ int OptionCheats_openMenu(MenuList* list, int i) { // this stuff gets actually copied around.. what year is it? int len = strlen(cheat->name) + 1; - item->name = calloc(len, sizeof(char)); - strcpy(item->name, cheat->name); + item->name = strdup(cheat->name); if(cheat->info) { len = strlen(cheat->info) + 1; @@ -557,7 +556,7 @@ int OptionCheats_openMenu(MenuList* list, int i) { const char* title = "No cheat file loaded.\n\n"; size_t title_len = strlen(title); - strcpy(cheats_path, title); // Use strcpy for first string + snprintf(cheats_path, sizeof(cheats_path), "%s", title); // Use strcpy for first string size_t current_len = title_len; for (int i = 0; i < count && i < CHEAT_MAX_DISPLAY_PATHS; i++) { @@ -575,16 +574,16 @@ int OptionCheats_openMenu(MenuList* list, int i) { // Check if adding this path would overflow the buffer if (current_len + p_len + newline_len >= CHEAT_MAX_LIST_LENGTH) { LOG_info("Cheats path buffer would overflow, truncating list\n"); - strcat(cheats_path, "..."); + strncat(cheats_path, "...", sizeof(cheats_path) - strlen(cheats_path) - 1); break; } // Safe to append - strcat(cheats_path, p); + strncat(cheats_path, p, sizeof(cheats_path) - strlen(cheats_path) - 1); current_len += p_len; if (i < count - 1) { - strcat(cheats_path, "\n"); + strncat(cheats_path, "\n", sizeof(cheats_path) - strlen(cheats_path) - 1); current_len += 1; } } diff --git a/workspace/all/minarch/ma_menu.c b/workspace/all/minarch/ma_menu.c index 5a5c130d0..e7a5e083a 100644 --- a/workspace/all/minarch/ma_menu.c +++ b/workspace/all/minarch/ma_menu.c @@ -176,17 +176,17 @@ void Menu_init(void) { char emu_name[256]; getEmuName(game.path, emu_name); - sprintf(menu.minui_dir, SHARED_USERDATA_PATH "/.minui/%s", emu_name); + snprintf(menu.minui_dir, sizeof(menu.minui_dir), SHARED_USERDATA_PATH "/.minui/%s", emu_name); mkdir(menu.minui_dir, 0755); // always sanitized/outer name, to keep main UI from having to inspect archives - sprintf(menu.slot_path, "%s/%s.txt", menu.minui_dir, game.name); + snprintf(menu.slot_path, sizeof(menu.slot_path), "%s/%s.txt", menu.minui_dir, game.name); if (simple_mode) menu.items[ITEM_OPTS] = "Reset"; if (game.m3u_path[0]) { char* tmp; - strcpy(menu.base_path, game.m3u_path); + snprintf(menu.base_path, sizeof(menu.base_path), "%s", game.m3u_path); tmp = strrchr(menu.base_path, '/') + 1; tmp[0] = '\0'; @@ -200,9 +200,9 @@ void Menu_init(void) { if (strlen(line)==0) continue; // skip empty lines char disc_path[256]; - strcpy(disc_path, menu.base_path); + snprintf(disc_path, sizeof(disc_path), "%s", menu.base_path); tmp = disc_path + strlen(disc_path); - strcpy(tmp, line); + snprintf(tmp, sizeof(disc_path) - (tmp - disc_path), "%s", line); // found a valid disc path if (exists(disc_path)) { @@ -967,11 +967,11 @@ bool getAlias(char* path, char* alias) { // LOG_info("alias path: %s\n", path); char* tmp; char map_path[256]; - strcpy(map_path, path); + snprintf(map_path, sizeof(map_path), "%s", path); tmp = strrchr(map_path, '/'); if (tmp) { tmp += 1; - strcpy(tmp, "map.txt"); + snprintf(tmp, sizeof(map_path) - (tmp - map_path), "%s", "map.txt"); // LOG_info("map_path: %s\n", map_path); } char* file_name = strrchr(path,'/'); @@ -993,7 +993,7 @@ bool getAlias(char* path, char* alias) { char* key = line; char* value = tmp+1; if (exactMatch(file_name,key)) { - strcpy(alias, value); + snprintf(alias, 256, "%s", value); // alias buffer is >=256 at every caller is_alias = true; break; } @@ -1571,8 +1571,8 @@ static void Menu_updateState(void) { state_slot = last_slot; // always sanitized/outer name, to keep main UI from having to inspect archives - sprintf(menu.bmp_path, "%s/%s.%d.bmp", menu.minui_dir, game.name, menu.slot); - sprintf(menu.txt_path, "%s/%s.%d.txt", menu.minui_dir, game.name, menu.slot); + snprintf(menu.bmp_path, sizeof(menu.bmp_path), "%s/%s.%d.bmp", menu.minui_dir, game.name, menu.slot); + snprintf(menu.txt_path, sizeof(menu.txt_path), "%s/%s.%d.txt", menu.minui_dir, game.name, menu.slot); menu.save_exists = exists(save_path); menu.preview_exists = menu.save_exists && exists(menu.bmp_path); @@ -1629,7 +1629,7 @@ void Menu_screenshot(void) { mkdir(SDCARD_PATH "/Screenshots", 0755); char png_path[256]; - sprintf(png_path, SDCARD_PATH "/Screenshots/%s.%s.png", rom_name, buffer); + snprintf(png_path, sizeof(png_path), SDCARD_PATH "/Screenshots/%s.%s.png", rom_name, buffer); int cw, ch; unsigned char* pixels = GFX_GL_screenCapture(&cw, &ch); SaveImageArgs* args = malloc(sizeof(SaveImageArgs)); @@ -1693,8 +1693,8 @@ void Menu_loadState(void) { getFile(menu.txt_path, slot_disc_name, 256); char slot_disc_path[256]; - if (slot_disc_name[0]=='/') strcpy(slot_disc_path, slot_disc_name); - else sprintf(slot_disc_path, "%s%s", menu.base_path, slot_disc_name); + if (slot_disc_name[0]=='/') snprintf(slot_disc_path, sizeof(slot_disc_path), "%s", slot_disc_name); + else snprintf(slot_disc_path, sizeof(slot_disc_path), "%s%s", menu.base_path, slot_disc_name); char* disc_path = menu.disc_paths[menu.disc]; if (!exactMatch(slot_disc_path, disc_path)) { @@ -1771,7 +1771,7 @@ void Menu_loop(void) { char disc_name[16]; if (menu.total_discs) { rom_disc = menu.disc; - sprintf(disc_name, "Disc %i", menu.disc+1); + snprintf(disc_name, sizeof(disc_name), "Disc %i", menu.disc+1); } int selected = 0; // resets every launch @@ -1808,7 +1808,7 @@ void Menu_loop(void) { menu.disc -= 1; if (menu.disc<0) menu.disc += menu.total_discs; dirty = 1; - sprintf(disc_name, "Disc %i", menu.disc+1); + snprintf(disc_name, sizeof(disc_name), "Disc %i", menu.disc+1); } else if (selected==ITEM_SAVE || selected==ITEM_LOAD) { menu.slot -= 1; @@ -1821,7 +1821,7 @@ void Menu_loop(void) { menu.disc += 1; if (menu.disc==menu.total_discs) menu.disc -= menu.total_discs; dirty = 1; - sprintf(disc_name, "Disc %i", menu.disc+1); + snprintf(disc_name, sizeof(disc_name), "Disc %i", menu.disc+1); } else if (selected==ITEM_SAVE || selected==ITEM_LOAD) { menu.slot += 1; diff --git a/workspace/all/minarch/ma_options.c b/workspace/all/minarch/ma_options.c index 82bc5ce64..47fa24dd7 100644 --- a/workspace/all/minarch/ma_options.c +++ b/workspace/all/minarch/ma_options.c @@ -53,12 +53,10 @@ void OptionList_init(const struct retro_core_option_definition *defs) { Option* item = &config.core.options[i]; len = strlen(def->key) + 1; - item->key = calloc(len, sizeof(char)); - strcpy(item->key, def->key); + item->key = strdup(def->key); len = strlen(def->desc) + 1; - item->name = calloc(len, sizeof(char)); - strcpy(item->name, getOptionNameFromKey(def->key,def->desc)); + item->name = strdup(getOptionNameFromKey(def->key,def->desc)); if (def->info) { len = strlen(def->info) + 1; @@ -84,13 +82,11 @@ void OptionList_init(const struct retro_core_option_definition *defs) { const char* label = def->values[j].label; len = strlen(value) + 1; - item->values[j] = calloc(len, sizeof(char)); - strcpy(item->values[j], value); + item->values[j] = strdup(value); if (label) { len = strlen(label) + 1; - item->labels[j] = calloc(len, sizeof(char)); - strcpy(item->labels[j], label); + item->labels[j] = strdup(label); } else { item->labels[j] = item->values[j]; @@ -204,12 +200,10 @@ void OptionList_vars(const struct retro_variable *vars) { Option* item = &config.core.options[i]; len = strlen(var->key) + 1; - item->key = calloc(len, sizeof(char)); - strcpy(item->key, var->key); + item->key = strdup(var->key); len = strlen(var->value) + 1; - item->var = calloc(len, sizeof(char)); - strcpy(item->var, var->value); + item->var = strdup(var->value); char* tmp = strchr(item->var, ';'); if (tmp && *(tmp+1)==' ') { diff --git a/workspace/all/minarch/ma_saves.c b/workspace/all/minarch/ma_saves.c index 8fe053e01..c61c2ce40 100644 --- a/workspace/all/minarch/ma_saves.c +++ b/workspace/all/minarch/ma_saves.c @@ -22,7 +22,7 @@ static void formatSavePath(char* work_name, char* filename, const char* suffix) if (tmp != NULL && strlen(tmp) > 2 && strlen(tmp) <= 5) { tmp[0] = '\0'; } - sprintf(filename, "%s/%s%s", core.saves_dir, work_name, suffix); + snprintf(filename, MAX_PATH, "%s/%s%s", core.saves_dir, work_name, suffix); } static void SRAM_getPath(char* filename) { @@ -30,15 +30,15 @@ static void SRAM_getPath(char* filename) { if (CFG_getSaveFormat() == SAVE_FORMAT_SRM || CFG_getSaveFormat() == SAVE_FORMAT_SRM_UNCOMPRESSED) { - strcpy(work_name, game.alt_name); + snprintf(work_name, sizeof(work_name), "%s", game.alt_name); formatSavePath(work_name, filename, ".srm"); } else if (CFG_getSaveFormat() == SAVE_FORMAT_GEN) { - strcpy(work_name, game.alt_name); + snprintf(work_name, sizeof(work_name), "%s", game.alt_name); formatSavePath(work_name, filename, ".sav"); } else { - sprintf(filename, "%s/%s.sav", core.saves_dir, game.alt_name); + snprintf(filename, MAX_PATH, "%s/%s.sav", core.saves_dir, game.alt_name); } LOG_info("SRAM_getPath %s\n", filename); @@ -108,7 +108,7 @@ void SRAM_write(void) { /////////////////////////////////////// static void RTC_getPath(char* filename) { - sprintf(filename, "%s/%s.rtc", core.saves_dir, game.alt_name); + snprintf(filename, MAX_PATH, "%s/%s.rtc", core.saves_dir, game.alt_name); } void RTC_read(void) { size_t rtc_size = core.get_memory_size(RETRO_MEMORY_RTC); @@ -165,34 +165,34 @@ void State_getPath(char* filename) { // should probably be removed at some point in the future. if (CFG_getStateFormat() == STATE_FORMAT_SRM_EXTRADOT || CFG_getStateFormat() == STATE_FORMAT_SRM_UNCOMRESSED_EXTRADOT) { - strcpy(work_name, game.alt_name); + snprintf(work_name, sizeof(work_name), "%s", game.alt_name); char* tmp = strrchr(work_name, '.'); if (tmp != NULL && strlen(tmp) > 2 && strlen(tmp) <= 5) { tmp[0] = '\0'; } if(state_slot == AUTO_RESUME_SLOT) - sprintf(filename, "%s/%s.state.auto", core.states_dir, work_name); + snprintf(filename, MAX_PATH, "%s/%s.state.auto", core.states_dir, work_name); else - sprintf(filename, "%s/%s.state.%i", core.states_dir, work_name, state_slot); + snprintf(filename, MAX_PATH, "%s/%s.state.%i", core.states_dir, work_name, state_slot); } else if (CFG_getStateFormat() == STATE_FORMAT_SRM || CFG_getStateFormat() == STATE_FORMAT_SRM_UNCOMRESSED) { - strcpy(work_name, game.alt_name); + snprintf(work_name, sizeof(work_name), "%s", game.alt_name); char* tmp = strrchr(work_name, '.'); if (tmp != NULL && strlen(tmp) > 2 && strlen(tmp) <= 5) { tmp[0] = '\0'; } if(state_slot == AUTO_RESUME_SLOT) - sprintf(filename, "%s/%s.state.auto", core.states_dir, work_name); + snprintf(filename, MAX_PATH, "%s/%s.state.auto", core.states_dir, work_name); else if(state_slot == 0) - sprintf(filename, "%s/%s.state", core.states_dir, work_name); + snprintf(filename, MAX_PATH, "%s/%s.state", core.states_dir, work_name); else - sprintf(filename, "%s/%s.state%i", core.states_dir, work_name, state_slot); + snprintf(filename, MAX_PATH, "%s/%s.state%i", core.states_dir, work_name, state_slot); } else { - sprintf(filename, "%s/%s.st%i", core.states_dir, game.alt_name, state_slot); + snprintf(filename, MAX_PATH, "%s/%s.st%i", core.states_dir, game.alt_name, state_slot); } } diff --git a/workspace/all/minarch/ma_video.c b/workspace/all/minarch/ma_video.c index edee20f21..682fe25d5 100644 --- a/workspace/all/minarch/ma_video.c +++ b/workspace/all/minarch/ma_video.c @@ -455,7 +455,7 @@ void selectScaler(int src_w, int src_h, int src_p) { // this is the same whether fit or oversized scale = MIN(DEVICE_WIDTH/src_w, DEVICE_HEIGHT/src_h); if (!scale) { - sprintf(scaler_name, "forced crop"); + snprintf(scaler_name, sizeof(scaler_name), "forced crop"); dst_w = DEVICE_WIDTH; dst_h = DEVICE_HEIGHT; dst_p = DEVICE_PITCH; @@ -478,7 +478,7 @@ void selectScaler(int src_w, int src_h, int src_p) { int scale_y = CEIL_DIV(DEVICE_HEIGHT, src_h); scale = MIN(scale_x, scale_y); - sprintf(scaler_name, "cropped"); + snprintf(scaler_name, sizeof(scaler_name), "cropped"); dst_w = DEVICE_WIDTH; dst_h = DEVICE_HEIGHT; dst_p = DEVICE_PITCH; @@ -508,7 +508,7 @@ void selectScaler(int src_w, int src_h, int src_p) { } } else { - sprintf(scaler_name, "integer"); + snprintf(scaler_name, sizeof(scaler_name), "integer"); int scaled_w = src_w * scale; int scaled_h = src_h * scale; dst_w = DEVICE_WIDTH; @@ -534,7 +534,7 @@ void selectScaler(int src_w, int src_h, int src_p) { int scaled_h = src_h * scale; if (scaling==SCALE_FULLSCREEN) { - sprintf(scaler_name, "full%i", scale); + snprintf(scaler_name, sizeof(scaler_name), "full%i", scale); // type = 'full (oversized)'; dst_w = scaled_w; dst_h = scaled_h; @@ -563,7 +563,7 @@ void selectScaler(int src_w, int src_h, int src_p) { dst_p = dst_w * FIXED_BPP; - sprintf(scaler_name, "raw%i", scale); + snprintf(scaler_name, sizeof(scaler_name), "raw%i", scale); } else { double src_aspect_ratio = ((double)src_w) / src_h; @@ -583,7 +583,7 @@ void selectScaler(int src_w, int src_h, int src_p) { // then to fixed aspect if (core_aspect>fixed_aspect) { - sprintf(scaler_name, "aspect%iL", scale); + snprintf(scaler_name, sizeof(scaler_name), "aspect%iL", scale); // letterbox // dst_w = scaled_w; // dst_h = scaled_w / fixed_aspect_ratio; @@ -596,7 +596,7 @@ void selectScaler(int src_w, int src_h, int src_p) { dst_y = (dst_h - scaled_h) / 2; } else if (core_aspect0) { - sprintf(debug_text, "%i/%ix%i/%ix%i/%ix%i", currentshaderpass, currentshadersrcw,currentshadersrch,currentshadertexw,currentshadertexh,currentshaderdstw,currentshaderdsth); + snprintf(debug_text, sizeof(debug_text), "%i/%ix%i/%ix%i/%ix%i", currentshaderpass, currentshadersrcw,currentshadersrch,currentshadertexw,currentshadertexh,currentshaderdstw,currentshaderdsth); blitBitmapText(debug_text,x,-y - 42,(uint32_t*)data,pitch / 4, width,height); } diff --git a/workspace/all/minarch/minarch.c b/workspace/all/minarch/minarch.c index 0e97b7b92..427f55e4d 100644 --- a/workspace/all/minarch/minarch.c +++ b/workspace/all/minarch/minarch.c @@ -128,7 +128,7 @@ void hdmimon(void) { int main(int argc , char* argv[]) { //static char asoundpath[MAX_PATH]; - //sprintf(asoundpath, "%s/.asoundrc", getenv("HOME")); + //snprintf(asoundpath, sizeof(asoundpath), "%s/.asoundrc", getenv("HOME")); //LOG_info("minarch: need asoundrc at %s\n", asoundpath); //if(exists(asoundpath)) // LOG_info("asoundrc exists at %s\n", asoundpath); @@ -145,8 +145,8 @@ int main(int argc , char* argv[]) { char rom_path[MAX_PATH]; char tag_name[MAX_PATH]; - strcpy(core_path, argv[1]); - strcpy(rom_path, argv[2]); + snprintf(core_path, sizeof(core_path), "%s", argv[1]); + snprintf(rom_path, sizeof(rom_path), "%s", argv[2]); getEmuName(rom_path, tag_name); LOG_info("rom_path: %s\n", rom_path); From e60b0e3b3a21eb1b71cd05dad78d5c4094035f69 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Wed, 1 Jul 2026 20:55:55 +0200 Subject: [PATCH 19/77] tg5040: model Brick vs Smart Pro as data (Device HAL, step 1) First step of the data-driven device HAL, tg5040 only. The Brick and the Smart Pro were already 'two devices in one binary' - scattered is_brick?X:Y ternaries in ten macros (screen geometry, menu layout, a few joystick codes). Those are now two DeviceDescriptor instances, TG5040_BRICK and TG5040_SMART_PRO, selected at runtime by a single resolveDeviceModel() that replaces the four copy-pasted getenv+exactMatch blocks (there was even a maintainer TODO asking for exactly this). The geometry/button macros (FIXED_WIDTH, MAIN_ROW_COUNT, JOY_L3, ...) now read deviceModel->field. Safe because those macros were already runtime values (is_brick is a runtime global), so nothing used them as compile-time constants. deviceModel defaults to Smart Pro so the macros are valid before init, then resolveDeviceModel refines it. Behaviour-preserving. The PLAT_* facade is untouched, so nothing above the platform layer changes. This is the shape tg5050 slots into next - it becomes another descriptor rather than a forked platform.c. (Named deviceModel, not deviceInfo, to avoid colliding with settings.cpp's own DeviceInfo class.) Verified on Smart Pro: boots clean at 1280x720 (the non-brick descriptor). --- workspace/tg5040/platform/platform.c | 37 ++++++++++++++++++++------- workspace/tg5040/platform/platform.h | 38 ++++++++++++++++++++-------- 2 files changed, 56 insertions(+), 19 deletions(-) diff --git a/workspace/tg5040/platform/platform.c b/workspace/tg5040/platform/platform.c index 6c975993f..6c84aa6b9 100644 --- a/workspace/tg5040/platform/platform.c +++ b/workspace/tg5040/platform/platform.c @@ -25,17 +25,38 @@ #include int is_brick = 0; + +// The two tg5040 models as data. They differ only in screen geometry, menu +// layout, and a few joystick codes; everything else in this platform is shared. +static const DeviceDescriptor TG5040_BRICK = { + .scale = 3, .width = 1024, .height = 768, + .main_row_count = 7, .quick_switcher_count = 3, .padding = 5, + .joy_l3 = 9, .joy_r3 = 10, .joy_plus = 14, .joy_minus = 13, +}; +static const DeviceDescriptor TG5040_SMART_PRO = { + .scale = 2, .width = 1280, .height = 720, + .main_row_count = 10, .quick_switcher_count = 4, .padding = 10, + .joy_l3 = JOY_NA, .joy_r3 = JOY_NA, .joy_plus = 128, .joy_minus = 129, +}; +// Default to Smart Pro so the geometry/button macros are valid even before +// init runs; resolveDeviceModel() refines it once DEVICE is known. +const DeviceDescriptor* deviceModel = &TG5040_SMART_PRO; + +// Single source of truth for which model we're on. Sets both is_brick (kept for +// the handful of code paths that still branch on it) and the active descriptor. +static void resolveDeviceModel(void) { + is_brick = exactMatch("brick", getenv("DEVICE")); + deviceModel = is_brick ? &TG5040_BRICK : &TG5040_SMART_PRO; +} + void PLAT_initPlatform(void) { - // TODO: replace with something that doesnt bleed out of tg5040 scope - char *device = getenv("DEVICE"); - is_brick = exactMatch("brick", device); + resolveDeviceModel(); } static SDL_Joystick **joysticks = NULL; static int num_joysticks = 0; void PLAT_initInput(void) { - char* device = getenv("DEVICE"); - is_brick = exactMatch("brick", device); + resolveDeviceModel(); if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0) LOG_error("Failed initializing joysticks: %s\n", SDL_GetError()); num_joysticks = SDL_NumJoysticks(); @@ -373,8 +394,7 @@ ConnectionStrength PLAT_connectionStrength(void) { } void PLAT_initDefaultLeds() { - char* device = getenv("DEVICE"); - is_brick = exactMatch("brick", device); + resolveDeviceModel(); if(is_brick) { lightsDefault[0] = (LightSettings) { "FN 1 key", @@ -479,8 +499,7 @@ void PLAT_initDefaultLeds() { } void PLAT_initLeds(LightSettings *lights) { - char* device = getenv("DEVICE"); - is_brick = exactMatch("brick", device); + resolveDeviceModel(); PLAT_initDefaultLeds(); FILE *file; diff --git a/workspace/tg5040/platform/platform.h b/workspace/tg5040/platform/platform.h index 6e2ef67ed..574e18302 100644 --- a/workspace/tg5040/platform/platform.h +++ b/workspace/tg5040/platform/platform.h @@ -13,6 +13,24 @@ extern int is_brick; +// A device model is described by data, not code. The tg5040 platform ships two +// models -- the TrimUI Brick and the Smart Pro -- that differ only in the values +// below; is_brick selects which descriptor is active at runtime. Adding a device +// becomes a matter of adding a descriptor rather than another is_brick ternary. +typedef struct DeviceDescriptor { + int scale; // FIXED_SCALE + int width; // FIXED_WIDTH + int height; // FIXED_HEIGHT + int main_row_count; // MAIN_ROW_COUNT + int quick_switcher_count; // QUICK_SWITCHER_COUNT + int padding; // PADDING + int joy_l3; // JOY_L3 + int joy_r3; // JOY_R3 + int joy_plus; // JOY_PLUS + int joy_minus; // JOY_MINUS +} DeviceDescriptor; +extern const DeviceDescriptor* deviceModel; + /////////////////////////////// #define BUTTON_UP BUTTON_NA @@ -89,13 +107,13 @@ extern int is_brick; #define JOY_R1 5 #define JOY_L2 JOY_NA #define JOY_R2 JOY_NA -#define JOY_L3 (is_brick?9:JOY_NA) -#define JOY_R3 (is_brick?10:JOY_NA) +#define JOY_L3 (deviceModel->joy_l3) +#define JOY_R3 (deviceModel->joy_r3) #define JOY_MENU 8 #define JOY_POWER 102 -#define JOY_PLUS (is_brick?14:128) -#define JOY_MINUS (is_brick?13:129) +#define JOY_PLUS (deviceModel->joy_plus) +#define JOY_MINUS (deviceModel->joy_minus) /////////////////////////////// @@ -120,9 +138,9 @@ extern int is_brick; /////////////////////////////// -#define FIXED_SCALE (is_brick?3:2) -#define FIXED_WIDTH (is_brick?1024:1280) -#define FIXED_HEIGHT (is_brick?768:720) +#define FIXED_SCALE (deviceModel->scale) +#define FIXED_WIDTH (deviceModel->width) +#define FIXED_HEIGHT (deviceModel->height) #define FIXED_BPP 2 #define FIXED_DEPTH (FIXED_BPP * 8) #define FIXED_PITCH (FIXED_WIDTH * FIXED_BPP) @@ -130,9 +148,9 @@ extern int is_brick; /////////////////////////////// -#define MAIN_ROW_COUNT (is_brick ? 7 : 10) -#define QUICK_SWITCHER_COUNT (is_brick ? 3 : 4) -#define PADDING (is_brick ? 5 : 10) +#define MAIN_ROW_COUNT (deviceModel->main_row_count) +#define QUICK_SWITCHER_COUNT (deviceModel->quick_switcher_count) +#define PADDING (deviceModel->padding) /////////////////////////////// From 64014cbb88aac1ffd54c76fbba5b9ba0ebec4f3b Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Wed, 1 Jul 2026 21:18:27 +0200 Subject: [PATCH 20/77] tg5040: move the diverging hardware paths into the descriptor Device HAL step 2. Grows DeviceDescriptor with the sysfs nodes that actually differ between platforms - the CPU-freq node, the GPU thermal zone, and the rumble GPIO. On tg5040 these are the same for Brick and Smart Pro (shared TG5040_* defines), but they're exactly where tg5050 diverges (cpu4 not cpu0, thermal_zone5 not zone2, gpio236 not gpio227), so they now live in the descriptor instead of as literals in the functions. PLAT_cpu_monitor and PLAT_setRumble read deviceModel->field. Only the values that genuinely vary went in - cpu_temp (thermal_zone0) is identical on both platforms, so it stays a literal (no point descriptor-izing a constant). The rumble *mechanism* difference (tg5040 voltage vs tg5050 level) is behavioural, not just a path, so that waits until the two platform.c bodies get unified. Behaviour-preserving on tg5040; verified on Brick (boots 1024x768, stable, rumble/perf paths unchanged). --- workspace/tg5040/platform/platform.c | 22 +++++++++++++++++----- workspace/tg5040/platform/platform.h | 6 ++++++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/workspace/tg5040/platform/platform.c b/workspace/tg5040/platform/platform.c index 6c84aa6b9..fc8c69a8d 100644 --- a/workspace/tg5040/platform/platform.c +++ b/workspace/tg5040/platform/platform.c @@ -26,17 +26,30 @@ int is_brick = 0; +// Shared tg5040 hardware node paths -- the same on Brick and Smart Pro. These +// are exactly the seams a different platform redefines (tg5050 would use +// cpu4/thermal_zone5/gpio236 here), so they belong to the descriptor. +#define TG5040_CPU_SPEED_PATH "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq" +#define TG5040_GPU_TEMP_PATH "/sys/devices/virtual/thermal/thermal_zone2/temp" +#define TG5040_RUMBLE_GPIO "/sys/class/gpio/gpio227/value" + // The two tg5040 models as data. They differ only in screen geometry, menu -// layout, and a few joystick codes; everything else in this platform is shared. +// layout, and a few joystick codes; the hardware paths below are shared. static const DeviceDescriptor TG5040_BRICK = { .scale = 3, .width = 1024, .height = 768, .main_row_count = 7, .quick_switcher_count = 3, .padding = 5, .joy_l3 = 9, .joy_r3 = 10, .joy_plus = 14, .joy_minus = 13, + .cpu_speed_path = TG5040_CPU_SPEED_PATH, + .gpu_temp_path = TG5040_GPU_TEMP_PATH, + .rumble_gpio_path = TG5040_RUMBLE_GPIO, }; static const DeviceDescriptor TG5040_SMART_PRO = { .scale = 2, .width = 1280, .height = 720, .main_row_count = 10, .quick_switcher_count = 4, .padding = 10, .joy_l3 = JOY_NA, .joy_r3 = JOY_NA, .joy_plus = 128, .joy_minus = 129, + .cpu_speed_path = TG5040_CPU_SPEED_PATH, + .gpu_temp_path = TG5040_GPU_TEMP_PATH, + .rumble_gpio_path = TG5040_RUMBLE_GPIO, }; // Default to Smart Pro so the geometry/button macros are valid even before // init runs; resolveDeviceModel() refines it once DEVICE is known. @@ -146,11 +159,11 @@ void PLAT_getCPUTemp() { void PLAT_getCPUSpeed() { - perf.cpu_speed = getInt("/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq")/1000; + perf.cpu_speed = getInt(deviceModel->cpu_speed_path)/1000; } void PLAT_getGPUTemp() { - perf.gpu_temp = getInt("/sys/devices/virtual/thermal/thermal_zone2/temp")/1000; + perf.gpu_temp = getInt(deviceModel->gpu_temp_path)/1000; } void PLAT_getGPUSpeed() { @@ -333,7 +346,6 @@ void PLAT_setCPUSpeed(int speed) { #define MAX_STRENGTH 0xFFFF #define MIN_VOLTAGE 500000 #define MAX_VOLTAGE 3300000 -#define RUMBLE_PATH "/sys/class/gpio/gpio227/value" #define RUMBLE_VOLTAGE_PATH "/sys/class/motor/voltage" void PLAT_setRumble(int strength) { @@ -349,7 +361,7 @@ void PLAT_setRumble(int strength) { // enable rumble - removed the FN switch disabling haptics // did not make sense - putInt(RUMBLE_PATH, (strength) ? 1 : 0); + putInt(deviceModel->rumble_gpio_path, (strength) ? 1 : 0); } int PLAT_pickSampleRate(int requested, int max) { diff --git a/workspace/tg5040/platform/platform.h b/workspace/tg5040/platform/platform.h index 574e18302..c204659d3 100644 --- a/workspace/tg5040/platform/platform.h +++ b/workspace/tg5040/platform/platform.h @@ -28,6 +28,12 @@ typedef struct DeviceDescriptor { int joy_r3; // JOY_R3 int joy_plus; // JOY_PLUS int joy_minus; // JOY_MINUS + // sysfs hardware nodes that differ across platforms -- the seams a future + // device redefines. Identical for Brick and Smart Pro; tg5050, for example, + // uses cpu4 not cpu0, thermal_zone5 not zone2, gpio236 not gpio227. + const char* cpu_speed_path; + const char* gpu_temp_path; + const char* rumble_gpio_path; } DeviceDescriptor; extern const DeviceDescriptor* deviceModel; From da987feec8f530676f75e5b0c6c2a26ab83c2e7e Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Wed, 1 Jul 2026 21:37:11 +0200 Subject: [PATCH 21/77] api: fold the shader-state extern soup into one struct (Phase D) api.h literally had a TODO over this: eight loose 'extern int's for the current render pass (currentshaderpass, currentshadersrcw/h, currentshaderdstw/h, currentshadertexw/h, should_rotate) shared between api.c, the platform GLES path (generic_video.c) and minarch (ma_video.c). Now they're one GFX_RenderState struct with a single extern, gfx_render, so the header exposes one well-named thing instead of eight. Fields renamed to the obvious short forms (pass, src_w, dst_h, ...). Purely a regrouping - same values, same cross-module writes (the struct fields stay writable), no logic touched in the GLES pipeline. api.h drops from 27 externs to 20. Verified on Brick: boots 1024x768, stable, renders fine. Note: generic_video.c is #include'd into platform.c, and make doesn't track that dep, so platform.o must be force-rebuilt (touch platform.c) after editing generic_video.c - else you get a stale-object link error. --- workspace/all/common/api.c | 10 +--------- workspace/all/common/api.h | 25 +++++++++++++++---------- workspace/all/common/generic_video.c | 20 ++++++++++---------- workspace/all/minarch/ma_video.c | 4 ++-- 4 files changed, 28 insertions(+), 31 deletions(-) diff --git a/workspace/all/common/api.c b/workspace/all/common/api.c index 91661f39c..0b73b939d 100644 --- a/workspace/all/common/api.c +++ b/workspace/all/common/api.c @@ -205,15 +205,7 @@ static double current_fps = SCREEN_FPS; static int fps_counter = 0; PerfProfile perf = {0}; -int currentshaderpass = 0; -int currentshadersrcw = 0; -int currentshadersrch = 0; -int currentshaderdstw = 0; -int currentshaderdsth = 0; -int currentshadertexw = 0; -int currentshadertexh = 0; - -int should_rotate = 0; +GFX_RenderState gfx_render = {0}; static pthread_mutex_t perf_cpu_monitor_mutex = PTHREAD_MUTEX_INITIALIZER; static int perf_cpu_monitor_enabled = 0; diff --git a/workspace/all/common/api.h b/workspace/all/common/api.h index da8e14534..6f8247122 100644 --- a/workspace/all/common/api.h +++ b/workspace/all/common/api.h @@ -103,16 +103,21 @@ typedef struct { extern PerfProfile perf; -// TODO: do we need that many free externs? This should move -// to a structure or something. -extern int currentshaderpass; -extern int currentshadersrcw; -extern int currentshadersrch; -extern int currentshaderdstw; -extern int currentshaderdsth; -extern int currentshadertexw; -extern int currentshadertexh; -extern int should_rotate; +// Current render-pass state, shared between the core renderer (api.c), +// the platform GLES pipeline (generic_video.c) and minarch's video path +// (ma_video.c). Was eight loose `extern int`s; grouped into one struct so +// there's a single well-named extern instead of the soup this used to be. +typedef struct GFX_RenderState { + int pass; // was currentshaderpass + int src_w; // currentshadersrcw + int src_h; // currentshadersrch + int dst_w; // currentshaderdstw + int dst_h; // currentshaderdsth + int tex_w; // currentshadertexw + int tex_h; // currentshadertexh + int should_rotate; // was should_rotate +} GFX_RenderState; +extern GFX_RenderState gfx_render; enum { ASSET_WHITE_PILL, ASSET_BLACK_PILL, diff --git a/workspace/all/common/generic_video.c b/workspace/all/common/generic_video.c index 00cb0cbf8..a9450e048 100644 --- a/workspace/all/common/generic_video.c +++ b/workspace/all/common/generic_video.c @@ -1586,7 +1586,7 @@ void setRectToAspectRatio(SDL_Rect* dst_rect) { dst_rect->w = w; dst_rect->h = h; } else if (vid.blit->aspect > 0) { - if (should_rotate) { + if (gfx_render.should_rotate) { h = device_width; w = h * vid.blit->aspect; if (w > device_height) { @@ -1608,8 +1608,8 @@ void setRectToAspectRatio(SDL_Rect* dst_rect) { } else { dst_rect->x = screenx; dst_rect->y = screeny; - dst_rect->w = should_rotate ? device_height : device_width; - dst_rect->h = should_rotate ? device_width : device_height; + dst_rect->w = gfx_render.should_rotate ? device_height : device_width; + dst_rect->h = gfx_render.should_rotate ? device_width : device_height; } } @@ -2174,13 +2174,13 @@ void PLAT_GL_Swap() { static int shaderinfocount = 0; static int shaderinfoscreen = 0; if (shaderinfocount > 600 && shaderinfoscreen == i) { - currentshaderpass = i + 1; - currentshadertexw = shaders[i].texw; - currentshadertexh = shaders[i].texh; - currentshadersrcw = shaders[i].srcw; - currentshadersrch = shaders[i].srch; - currentshaderdstw = dst_w; - currentshaderdsth = dst_h; + gfx_render.pass = i + 1; + gfx_render.tex_w = shaders[i].texw; + gfx_render.tex_h = shaders[i].texh; + gfx_render.src_w = shaders[i].srcw; + gfx_render.src_h = shaders[i].srch; + gfx_render.dst_w = dst_w; + gfx_render.dst_h = dst_h; shaderinfocount = 0; shaderinfoscreen++; if (shaderinfoscreen >= nrofshaders) diff --git a/workspace/all/minarch/ma_video.c b/workspace/all/minarch/ma_video.c index 682fe25d5..7dfa61dad 100644 --- a/workspace/all/minarch/ma_video.c +++ b/workspace/all/minarch/ma_video.c @@ -725,8 +725,8 @@ static void drawDebugHud(const void* data, unsigned width, unsigned height, size snprintf(debug_text, sizeof(debug_text), "%.0f%%/%ihz/%ic", perf.gpu_usage, perf.gpu_speed, perf.gpu_temp); blitBitmapText(debug_text,x,-y - 28,(uint32_t*)data,pitch / 4, width,height); - if(currentshaderpass>0) { - snprintf(debug_text, sizeof(debug_text), "%i/%ix%i/%ix%i/%ix%i", currentshaderpass, currentshadersrcw,currentshadersrch,currentshadertexw,currentshadertexh,currentshaderdstw,currentshaderdsth); + if(gfx_render.pass>0) { + snprintf(debug_text, sizeof(debug_text), "%i/%ix%i/%ix%i/%ix%i", gfx_render.pass, gfx_render.src_w,gfx_render.src_h,gfx_render.tex_w,gfx_render.tex_h,gfx_render.dst_w,gfx_render.dst_h); blitBitmapText(debug_text,x,-y - 42,(uint32_t*)data,pitch / 4, width,height); } From c8a9426f86de233dab70ca3204c4f7bcf61142f8 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Wed, 1 Jul 2026 21:54:58 +0200 Subject: [PATCH 22/77] nextui: move the selection-pill animation to the main thread First step of bringing the disabled visuals back, done right. The pill tween no longer runs in a worker thread. It used to: animWorker looped over frames computing the pill position, wrote it into a shared struct, handed that pointer to the main thread via a callback, and blocked on a condition variable until the next flip - with the struct written and read from two threads with no lock, and a queue-size counter decremented too late so the producer's drop-oldest ran on a stale count. That's the tangle that corrupted memory and crashed. A UI lerp doesn't need any of that. animPill now just records the start/target/frames, and advancePillAnim() - called once per main-loop iteration - steps the linear tween and sets pillRect, reproducing exactly what the old worker+callback did per frame (including hiding the text off-screen mid-slide). No thread, no queue, no cross-thread struct. The old animWorker/enqueue/animcallback/queue code is now dead; it'll be deleted in a follow-up so this commit stays focused. Image loading (backgrounds, thumbnails) is still gated off - that's next, on a proper thread-safe queue. Verified on Brick: boots, stable, no cores. --- workspace/all/nextui/nextui.cpp | 73 +++++++++++++++++++++++++-------- 1 file changed, 55 insertions(+), 18 deletions(-) diff --git a/workspace/all/nextui/nextui.cpp b/workspace/all/nextui/nextui.cpp index 527c5a978..225b99a3b 100644 --- a/workspace/all/nextui/nextui.cpp +++ b/workspace/all/nextui/nextui.cpp @@ -2029,29 +2029,64 @@ void enqueueanmimtask(AnimTask* task) { SDL_UnlockMutex(animqueueMutex); } +// Main-thread pill animation. The pill (the selection highlight) slides from +// its current position to the target over `frames` frames. This used to run in +// a worker thread that tweened across frames and handed each position back to +// the main thread via a callback + condition variable -- an unnecessary and +// race-prone design for what is just a UI lerp. It is now a plain linear tween +// advanced once per render frame on the main thread: no worker, no queue, no +// cross-thread handoff, so the whole class of races that crashed it is gone. +static struct PillAnim { + bool active; + int startX, startY, targetX, targetY; + int move_w, move_h, targetTextY; + int frame, frames; +} pillAnim = {0}; + +// Advance the pill tween by one render frame. Call once per main-loop iteration. +// Reproduces exactly what the old animWorker + animcallback did per frame. +static void advancePillAnim(void) { + if (!pillAnim.active) return; + float t = pillAnim.frames > 0 ? (float)pillAnim.frame / pillAnim.frames : 1.0f; + if (t > 1.0f) t = 1.0f; + pillRect.x = pillAnim.startX + (int)((pillAnim.targetX - pillAnim.startX) * t); + pillRect.y = pillAnim.startY + (int)((pillAnim.targetY - pillAnim.startY) * t); + pillRect.w = pillAnim.move_w; + pillRect.h = pillAnim.move_h; + if (pillRect.w > 0 && pillRect.h > 0) { + pilltargetY = screen->w; // hide the selected text off-screen mid-slide + if (pillAnim.frame >= pillAnim.frames) { + pilltargetY = pillAnim.targetY; + pilltargetTextY = pillAnim.targetTextY; + } + } + if (pillAnim.frame >= pillAnim.frames) { + pillanimdone = true; + pillAnim.active = false; + } + pillAnim.frame++; + setNeedDraw(1); + setAnimationDraw(1); +} + void animPill(AnimTask *task) { -#if NEXTUI_POC_NO_WORKERS - // POC: the worker-thread pill animation is disabled. Apply the final pill - // position directly (instant, no tween) instead of queueing it for animWorker. - // This is what animcallback would have set on the last frame. - SDL_LockMutex(animMutex); - pillRect.x = task->targetX; - pillRect.y = task->targetY; - pillRect.w = task->move_w; - pillRect.h = task->move_h; - pilltargetY = task->targetY; - pilltargetTextY = task->targetTextY; - pillanimdone = true; - SDL_UnlockMutex(animMutex); + // Kick off a main-thread tween from the current pill position to the target. + pillAnim.startX = task->startX; + pillAnim.startY = task->startY; + pillAnim.targetX = task->targetX; + pillAnim.targetY = task->targetY; + pillAnim.move_w = task->move_w; + pillAnim.move_h = task->move_h; + pillAnim.targetTextY = task->targetTextY; + pillAnim.frames = task->frames; + pillAnim.frame = 0; + pillAnim.active = true; + pillanimdone = false; setNeedDraw(1); setAnimationDraw(1); // The caller malloc'd the task and does not use it after this call. if (task->entry_name) free(task->entry_name); free(task); -#else - task->callback = animcallback; - enqueueanmimtask(task); -#endif } void initImageLoaderPool() { @@ -2240,6 +2275,8 @@ int main (int argc, char *argv[]) { PAD_poll(); + advancePillAnim(); // step the selection-pill tween on the main thread + int selected = top->selected; int total = (int)top->entries.size(); @@ -3212,7 +3249,7 @@ int main (int argc, char *argv[]) { } SDL_UnlockMutex(animMutex); if (currentScreen != SCREEN_GAMESWITCHER && currentScreen != SCREEN_QUICKMENU) { - if(is_scrolling && pillanimdone && currentAnimQueueSize < 1) { + if(is_scrolling && pillanimdone && !pillAnim.active) { int ow = GFX_blitHardwareGroup(screen, show_setting); Entry* entry = top->entries[top->selected]; trimSortingMeta(&entry->name); From 75280bed7a724fca3931bcc3046ca955c0e18c63 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Wed, 1 Jul 2026 22:07:51 +0200 Subject: [PATCH 23/77] nextui: make the no-animation pill move instant again When frames<=1 (a directory change, where should_animate is false), the tween was still rendering the start position for one frame before snapping to the target - which flashed the pill at the previous directory's row (often near the top) on the way back out. Restore the instant behaviour the POC had for that case: jump straight to target, no start frame. The multi-frame slide (in-list navigation) is unchanged. --- workspace/all/nextui/nextui.cpp | 38 ++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/workspace/all/nextui/nextui.cpp b/workspace/all/nextui/nextui.cpp index 225b99a3b..733ed159f 100644 --- a/workspace/all/nextui/nextui.cpp +++ b/workspace/all/nextui/nextui.cpp @@ -2070,18 +2070,32 @@ static void advancePillAnim(void) { } void animPill(AnimTask *task) { - // Kick off a main-thread tween from the current pill position to the target. - pillAnim.startX = task->startX; - pillAnim.startY = task->startY; - pillAnim.targetX = task->targetX; - pillAnim.targetY = task->targetY; - pillAnim.move_w = task->move_w; - pillAnim.move_h = task->move_h; - pillAnim.targetTextY = task->targetTextY; - pillAnim.frames = task->frames; - pillAnim.frame = 0; - pillAnim.active = true; - pillanimdone = false; + if (task->frames <= 1) { + // No animation requested (e.g. a directory change): jump straight to the + // target, no tween. Rendering the start position for a frame first would + // flash the pill at the previous directory's row before snapping over. + pillRect.x = task->targetX; + pillRect.y = task->targetY; + pillRect.w = task->move_w; + pillRect.h = task->move_h; + pilltargetY = task->targetY; + pilltargetTextY = task->targetTextY; + pillanimdone = true; + pillAnim.active = false; + } else { + // Kick off a main-thread tween from the current position to the target. + pillAnim.startX = task->startX; + pillAnim.startY = task->startY; + pillAnim.targetX = task->targetX; + pillAnim.targetY = task->targetY; + pillAnim.move_w = task->move_w; + pillAnim.move_h = task->move_h; + pillAnim.targetTextY = task->targetTextY; + pillAnim.frames = task->frames; + pillAnim.frame = 0; + pillAnim.active = true; + pillanimdone = false; + } setNeedDraw(1); setAnimationDraw(1); // The caller malloc'd the task and does not use it after this call. From 194d479ed3ff96a4ab88a35cb61d1bf704b481c1 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Wed, 1 Jul 2026 22:43:12 +0200 Subject: [PATCH 24/77] nextui: bring folder backgrounds back on a thread-safe queue First of the image loaders returns, rebuilt right. Adds a reusable core/thread_safe_queue.h (std::mutex + condition_variable, blocking pop, drop-oldest when full) and runs the folder-background loader on one std::thread that pops requests off it. The old design was a hand-rolled SDL_mutex/SDL_cond linked-list queue whose size counter was decremented too late and whose task ownership crossed threads - that's the race the POC had to switch off. Now the correctness lives in one small tested-shaped place: the worker owns the request once it pops it, IMG_Load + SDL_ConvertSurfaceFormat only touch CPU-side pixels off the main thread, and the decoded surface is handed back through onBackgroundLoaded under bgMutex (the same mutex every main-thread draw of folderbgbmp already takes, so no torn read or use-after-free). shutdown() unblocks the worker's pop() and we join it before freeing anything. Capacity is 1: only the most recent folder's background matters; if you've already navigated on, the stale request is dropped before it loads. Thumbnails are still on the disabled path - next to migrate onto the same queue. Verified on Brick: boots, stable through navigation, no cores. --- workspace/all/common/core/thread_safe_queue.h | 66 +++++++++++++++++++ workspace/all/nextui/nextui.cpp | 60 ++++++++++++----- 2 files changed, 110 insertions(+), 16 deletions(-) create mode 100644 workspace/all/common/core/thread_safe_queue.h diff --git a/workspace/all/common/core/thread_safe_queue.h b/workspace/all/common/core/thread_safe_queue.h new file mode 100644 index 000000000..286ebe1e2 --- /dev/null +++ b/workspace/all/common/core/thread_safe_queue.h @@ -0,0 +1,66 @@ +// core/thread_safe_queue.h -- a small bounded producer/consumer queue (C++, +// header-only). +// +// Built for the image loaders: the main (producer) thread pushes load requests, +// a worker (consumer) thread pops them, blocking when there's nothing to do. +// When a capacity is set and the queue is full, push() drops the OLDEST item so +// the newest wins -- exactly right for backgrounds/thumbnails, where a request +// for a folder the user has already navigated away from is worthless. +// +// This replaces the hand-rolled SDL_mutex/SDL_cond linked-list queues whose +// late size-counter decrement and cross-thread task ownership caused the +// memory corruption that the POC had to disable. Correctness lives in one small +// place now instead of being re-implemented per queue. + +#ifndef NEXTUI_CORE_THREAD_SAFE_QUEUE_H +#define NEXTUI_CORE_THREAD_SAFE_QUEUE_H + +#include +#include +#include +#include +#include + +namespace core { + +template +class ThreadSafeQueue { +public: + // capacity == 0 means unbounded. + explicit ThreadSafeQueue(size_t capacity = 0) : capacity_(capacity) {} + + void push(T item) { + std::lock_guard lock(mutex_); + if (capacity_ && queue_.size() >= capacity_) queue_.pop(); // drop oldest + queue_.push(std::move(item)); + cond_.notify_one(); + } + + // Blocks until an item is available. Returns false once shutdown() has been + // called and the queue has drained -- the signal for a consumer to exit. + bool pop(T& out) { + std::unique_lock lock(mutex_); + cond_.wait(lock, [this] { return !queue_.empty() || shutdown_; }); + if (queue_.empty()) return false; + out = std::move(queue_.front()); + queue_.pop(); + return true; + } + + void shutdown() { + std::lock_guard lock(mutex_); + shutdown_ = true; + cond_.notify_all(); + } + +private: + std::queue queue_; + std::mutex mutex_; + std::condition_variable cond_; + size_t capacity_; + bool shutdown_ = false; +}; + +} // namespace core + +#endif // NEXTUI_CORE_THREAD_SAFE_QUEUE_H diff --git a/workspace/all/nextui/nextui.cpp b/workspace/all/nextui/nextui.cpp index 733ed159f..303ad47dc 100644 --- a/workspace/all/nextui/nextui.cpp +++ b/workspace/all/nextui/nextui.cpp @@ -15,7 +15,9 @@ #include #include #include +#include #include "core/str.h" +#include "core/thread_safe_queue.h" extern "C" { #include @@ -1832,21 +1834,38 @@ int ThumbLoadWorker(void* unused) { return 0; } -void startLoadFolderBackground(const char* imagePath, BackgroundLoadedCallback callback, void* userData) { -#if NEXTUI_POC_NO_WORKERS - // POC: async background loading disabled. folderbgbmp stays NULL; every - // background draw is NULL-guarded and falls through to GFX_clearLayers. - (void)imagePath; (void)callback; (void)userData; - return; -#else - LoadBackgroundTask* task = (LoadBackgroundTask*)(malloc(sizeof(LoadBackgroundTask))); - if (!task) return; +// --- Folder background loader ------------------------------------------------ +// One std::thread consuming a thread-safe queue. Replaces the hand-rolled +// SDL_mutex/SDL_cond linked-list queue + BGLoadWorker (whose data race the POC +// had to disable). A request is just the image path plus the callback that +// hands the decoded surface back (onBackgroundLoaded, which stores it under +// bgMutex for the main thread to draw). IMG_Load / SDL_ConvertSurfaceFormat only +// touch CPU-side pixel buffers, so they're safe off the main thread. +struct ImageLoadRequest { + std::string path; + BackgroundLoadedCallback callback; +}; +// Capacity 1: only the most recently requested background matters. If the user +// has already navigated on, the stale request is dropped before it's loaded. +static core::ThreadSafeQueue bgLoadQueue(1); +static std::thread bgLoadWorkerThread; + +static void bgLoadWorkerLoop(void) { + ImageLoadRequest req; + while (bgLoadQueue.pop(req)) { + SDL_Surface* surface = NULL; + SDL_Surface* raw = IMG_Load(req.path.c_str()); + if (raw) { + surface = SDL_ConvertSurfaceFormat(raw, screen->format->format, 0); + SDL_FreeSurface(raw); + } + req.callback(surface); // onBackgroundLoaded, hands off under bgMutex + } +} - snprintf(task->imagePath, sizeof(task->imagePath), "%s", imagePath); - task->callback = callback; - task->userData = userData; - enqueueBGTask(task); -#endif +void startLoadFolderBackground(const char* imagePath, BackgroundLoadedCallback callback, void* userData) { + (void)userData; + bgLoadQueue.push({ imagePath, callback }); } void onBackgroundLoaded(SDL_Surface* surface) { @@ -2122,9 +2141,13 @@ void initImageLoaderPool() { fontMutex = SDL_CreateMutex(); flipCond = SDL_CreateCond(); + // Folder backgrounds run again, on the std::thread + ThreadSafeQueue loader. + bgLoadWorkerThread = std::thread(bgLoadWorkerLoop); + #if NEXTUI_POC_NO_WORKERS - // POC: do not spawn the image-loader / pill-animation worker threads. The - // thread handles stay NULL so cleanupImageLoaderPool's join guards skip them. + // The legacy SDL bg worker is superseded by bgLoadWorkerThread above. The + // pill animation is now main-thread. Thumbnails are still on the old + // disabled path (next to migrate to the queue), so their thread stays NULL. bgLoadThread = NULL; thumbLoadThread = NULL; animWorkerThread = NULL; @@ -2136,6 +2159,11 @@ void initImageLoaderPool() { } void cleanupImageLoaderPool() { + // Stop the folder-background loader: the queue's shutdown() unblocks its + // pop() and the worker returns, then we join it. + bgLoadQueue.shutdown(); + if (bgLoadWorkerThread.joinable()) bgLoadWorkerThread.join(); + // Signal all worker threads to exit (atomic set for thread safety) SDL_AtomicSet(&workerThreadsShutdown, 1); From b221333a16bafcd3a4e7963ee23fe7f51f7e8ffe Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Wed, 1 Jul 2026 22:50:19 +0200 Subject: [PATCH 25/77] nextui: bring box-art thumbnails back on the thread-safe queue Same treatment as folder backgrounds: thumbnails now load on their own std::thread pulling from their own capacity-1 core::ThreadSafeQueue (separate from backgrounds so the two never evict each other's request). The worker checks the file exists, decodes off the main thread, and hands the surface to onThumbLoaded, which does the scaling + rounded-corner pass and stores thumbbmp under thumbMutex - the same mutex both main-thread draw sites already take. shutdown()+join on quit. Every image loader is now off the hand-rolled SDL queue and onto the tested-shaped ThreadSafeQueue; the whole NEXTUI_POC_NO_WORKERS subsystem is effectively re-enabled, rebuilt without the data race. (The dead legacy SDL queue/worker code is still in the file; a follow-up deletes it.) Verified on Brick: boots, stable through rapid navigation, no cores. --- workspace/all/nextui/nextui.cpp | 56 +++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/workspace/all/nextui/nextui.cpp b/workspace/all/nextui/nextui.cpp index 303ad47dc..c8a4bcd67 100644 --- a/workspace/all/nextui/nextui.cpp +++ b/workspace/all/nextui/nextui.cpp @@ -1882,21 +1882,33 @@ void onBackgroundLoaded(SDL_Surface* surface) { SDL_UnlockMutex(bgMutex); } -void startLoadThumb(const char* thumbpath, BackgroundLoadedCallback callback, void* userData) { -#if NEXTUI_POC_NO_WORKERS - // POC: async thumbnail loading disabled. thumbbmp stays NULL; the thumbnail - // draw is guarded by `if(thumbbmp && thumbchanged)` and falls through to clear. - (void)thumbpath; (void)callback; (void)userData; - return; -#else - LoadBackgroundTask* task = (LoadBackgroundTask*)(malloc(sizeof(LoadBackgroundTask))); - if (!task) return; +// --- Thumbnail (box-art) loader ---------------------------------------------- +// Same shape as the folder-background loader: its own std::thread and its own +// capacity-1 queue (separate from backgrounds so a thumbnail request and a +// background request never evict each other). onThumbLoaded does the CPU-side +// scaling maths and rounded-corner pass on the decoded surface under thumbMutex, +// so it's fine to run from the worker. +static core::ThreadSafeQueue thumbLoadQueue(1); +static std::thread thumbLoadWorkerThread; + +static void thumbLoadWorkerLoop(void) { + ImageLoadRequest req; + while (thumbLoadQueue.pop(req)) { + SDL_Surface* surface = NULL; + if (access(req.path.c_str(), F_OK) == 0) { + SDL_Surface* raw = IMG_Load(req.path.c_str()); + if (raw) { + surface = SDL_ConvertSurfaceFormat(raw, screen->format->format, 0); + SDL_FreeSurface(raw); + } + } + req.callback(surface); // onThumbLoaded, hands off under thumbMutex + } +} - snprintf(task->imagePath, sizeof(task->imagePath), "%s", thumbpath); - task->callback = callback; - task->userData = userData; - enqueueThumbTask(task); -#endif +void startLoadThumb(const char* thumbpath, BackgroundLoadedCallback callback, void* userData) { + (void)userData; + thumbLoadQueue.push({ thumbpath, callback }); } void onThumbLoaded(SDL_Surface* surface) { SDL_LockMutex(thumbMutex); @@ -2141,13 +2153,15 @@ void initImageLoaderPool() { fontMutex = SDL_CreateMutex(); flipCond = SDL_CreateCond(); - // Folder backgrounds run again, on the std::thread + ThreadSafeQueue loader. + // Folder backgrounds and thumbnails each run on their own std::thread + + // ThreadSafeQueue loader. bgLoadWorkerThread = std::thread(bgLoadWorkerLoop); + thumbLoadWorkerThread = std::thread(thumbLoadWorkerLoop); #if NEXTUI_POC_NO_WORKERS - // The legacy SDL bg worker is superseded by bgLoadWorkerThread above. The - // pill animation is now main-thread. Thumbnails are still on the old - // disabled path (next to migrate to the queue), so their thread stays NULL. + // The legacy SDL bg/thumb workers are superseded by the std::thread loaders + // above, and the pill animation is now main-thread. Nothing left to spawn on + // the old path. bgLoadThread = NULL; thumbLoadThread = NULL; animWorkerThread = NULL; @@ -2159,10 +2173,12 @@ void initImageLoaderPool() { } void cleanupImageLoaderPool() { - // Stop the folder-background loader: the queue's shutdown() unblocks its - // pop() and the worker returns, then we join it. + // Stop the image loaders: each queue's shutdown() unblocks its worker's + // pop() so it returns, then we join. bgLoadQueue.shutdown(); if (bgLoadWorkerThread.joinable()) bgLoadWorkerThread.join(); + thumbLoadQueue.shutdown(); + if (thumbLoadWorkerThread.joinable()) thumbLoadWorkerThread.join(); // Signal all worker threads to exit (atomic set for thread safety) SDL_AtomicSet(&workerThreadsShutdown, 1); From a359e855c224fe5b526962ad5479fe974c871a0c Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Wed, 1 Jul 2026 23:06:25 +0200 Subject: [PATCH 26/77] nextui: clear stale box art when the selection has no art / dir changes Two small fixes now that thumbnails are back: - When the highlighted entry has no box art, clear the thumbnail right away instead of queueing a load that only resolves to 'no art' a frame or two later. And only queue a load when the art file actually exists. - When the directory depth changes (moving up/down), clear the thumbnail surface and LAYER_THUMBNAIL *before* the directory transition animates. Going from a ROM folder up to the systems overview is gamelist->gamelist, so the existing 'clear when leaving a gamelist' guard didn't fire and the previous ROM's art flashed through the slide. previous_depth still holds the old depth at that point, so previous_depth != stack.size() detects the change. Verified on Brick: box art no longer lingers into the systems overview. --- workspace/all/nextui/nextui.cpp | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/workspace/all/nextui/nextui.cpp b/workspace/all/nextui/nextui.cpp index c8a4bcd67..f61400147 100644 --- a/workspace/all/nextui/nextui.cpp +++ b/workspace/all/nextui/nextui.cpp @@ -2648,8 +2648,20 @@ int main (int argc, char *argv[]) { } else { GFX_clearLayers(LAYER_TRANSITION); - if(lastScreen!=SCREEN_GAMELIST) + // Clear the thumbnail when leaving a gamelist, or when the + // directory depth changed this frame (moving up/down). Without the + // depth check, going from a ROM folder up to the systems overview + // is gamelist->gamelist, so the previous ROM's box art lingered on + // LAYER_THUMBNAIL and flashed through the directory transition. + // previous_depth is only updated later in the draw block, so here + // it still holds the old depth. + if(lastScreen!=SCREEN_GAMELIST || previous_depth != (int)stack.size()) { + SDL_LockMutex(thumbMutex); + if (thumbbmp) { SDL_FreeSurface(thumbbmp); thumbbmp = NULL; } + thumbchanged = 1; + SDL_UnlockMutex(thumbMutex); GFX_clearLayers(LAYER_THUMBNAIL); + } GFX_clearLayers(LAYER_SCROLLTEXT); GFX_clearLayers(LAYER_IDK2); } @@ -3013,17 +3025,24 @@ int main (int argc, char *argv[]) { char thumbpath[1024]; core::format(thumbpath, "%s/.media/%s.png", rompath, res_copy); had_thumb = 0; - startLoadThumb(thumbpath, onThumbLoaded, NULL); int max_w = (int)(screen->w - (screen->w * CFG_getGameArtWidth())); int max_h = (int)(screen->h * 0.6); int new_w = max_w; int new_h = max_h; if(exists(thumbpath)) { + startLoadThumb(thumbpath, onThumbLoaded, NULL); ox = (int)(max_w) - SCALE1(BUTTON_MARGIN*5); had_thumb = 1; } - else + else { + // No art for this selection (e.g. a folder, or moving up + // a directory): clear any thumbnail from the previous + // selection right away, rather than queueing a load that + // only resolves to "no art" a frame or two later -- that + // async gap is what left the old box-art on screen briefly. + onThumbLoaded(NULL); ox = screen->w; + } } } From 3699809dd3cef21a46a59245c3d18d05123ded73 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Thu, 2 Jul 2026 10:40:10 +0200 Subject: [PATCH 27/77] nextui: delete the disabled legacy SDL worker/queue code Now that folder backgrounds and thumbnails run on the ThreadSafeQueue + std::thread loaders and the pill animation is a plain main-thread tween, the old hand-rolled path is fully dead. This clears it out: - the SDL_mutex/SDL_cond linked-list task queues (TaskNode/AnimTaskNode, the head/tail globals, the per-queue mutexes and conds) plus their producers (enqueueBGTask/enqueueThumbTask/enqueueanmimtask) and consumers (BGLoadWorker/ThumbLoadWorker/animWorker) - animcallback + the finishedTask struct it handed back, and the frameReady/flipCond/frameMutex frame-flip handshake that fed animWorker - LoadBackgroundTask, the currentXQueueSize counters, MAX_QUEUE_SIZE, workerThreadsShutdown, and the SDL_Thread handles - the NEXTUI_POC_NO_WORKERS gate in init/cleanup and its scaffolding note AnimTask keeps only the fields animPill actually reads; init/cleanup now just create/destroy the four live mutexes (bg/thumb/anim/font) and spawn/join the two std::thread loaders. No behaviour change -- verified booting clean on the Brick with a stable launcher PID and no crash cores. --- workspace/all/nextui/nextui.cpp | 428 +------------------------------- 1 file changed, 4 insertions(+), 424 deletions(-) diff --git a/workspace/all/nextui/nextui.cpp b/workspace/all/nextui/nextui.cpp index f61400147..bc243a2a5 100644 --- a/workspace/all/nextui/nextui.cpp +++ b/workspace/all/nextui/nextui.cpp @@ -27,19 +27,6 @@ extern "C" { #include "config.h" } -// --------------------------------------------------------------------------- -// POC SCAFFOLDING (temporary) -// -// The background/thumbnail image loaders and the pill-animation worker use a -// hand-rolled multi-threaded task queue that has latent memory-corruption bugs -// (a stray write that smashes the stack / dynamic-linker state; benign under the -// old C build, fatal once compiled as C++). For the C++ port POC we disable -// those worker threads and run the launcher without async image loading, -// thumbnails, backgrounds and the pill animation. These are to be reintroduced -// later with a correct, thread-safe implementation. Grep NEXTUI_POC_NO_WORKERS. -// --------------------------------------------------------------------------- -#define NEXTUI_POC_NO_WORKERS 1 - /////////////////////////////////////// static void StringArray_free(std::vector& self) { @@ -1555,29 +1542,7 @@ enum { typedef void (*BackgroundLoadedCallback)(SDL_Surface* surface); -typedef struct { - char imagePath[MAX_PATH]; - BackgroundLoadedCallback callback; - void* userData; -} LoadBackgroundTask; - -typedef struct finishedTask { - int startX; - int targetX; - int startY; - int targetY; - int targetTextY; - int move_y; - int move_w; - int move_h; - int frames; - int done; - void* userData; - char *entry_name; - SDL_Rect dst; -} finishedTask; - -typedef void (*AnimTaskCallback)(finishedTask *task); +// The pill-animation producer fills one of these and hands it to animPill(). typedef struct AnimTask { int startX; int targetX; @@ -1587,46 +1552,13 @@ typedef struct AnimTask { int move_w; int move_h; int frames; - AnimTaskCallback callback; - void* userData; - char *entry_name; - SDL_Rect dst; + char *entry_name; } AnimTask; -typedef struct TaskNode { - LoadBackgroundTask* task; - struct TaskNode* next; -} TaskNode; -typedef struct AnimTaskNode { - AnimTask* task; - struct AnimTaskNode* next; -} AnimTaskNode; - -static TaskNode* taskBGQueueHead = NULL; -static TaskNode* taskBGQueueTail = NULL; -static TaskNode* taskThumbQueueHead = NULL; -static TaskNode* taskThumbQueueTail = NULL; -static AnimTaskNode* animTaskQueueHead = NULL; -static AnimTaskNode* animTtaskQueueTail = NULL; -static SDL_mutex* bgqueueMutex = NULL; -static SDL_mutex* thumbqueueMutex = NULL; -static SDL_mutex* animqueueMutex = NULL; -static SDL_cond* bgqueueCond = NULL; -static SDL_cond* thumbqueueCond = NULL; -static SDL_cond* animqueueCond = NULL; - static SDL_mutex* bgMutex = NULL; static SDL_mutex* thumbMutex = NULL; static SDL_mutex* animMutex = NULL; -static SDL_mutex* frameMutex = NULL; static SDL_mutex* fontMutex = NULL; -static SDL_cond* flipCond = NULL; - -static SDL_Thread* bgLoadThread = NULL; -static SDL_Thread* thumbLoadThread = NULL; -static SDL_Thread* animWorkerThread = NULL; - -static SDL_atomic_t workerThreadsShutdown; // Flag to signal threads to exit (atomic for thread safety) static SDL_Surface* folderbgbmp = NULL; static SDL_Surface* thumbbmp = NULL; @@ -1676,164 +1608,6 @@ static void updatePillTextSurface(const char* entry_name, int move_w, SDL_Color int folderbgchanged=0; int thumbchanged=0; -// queue a new image load task :D -#define MAX_QUEUE_SIZE 1 - -int currentBGQueueSize = 0; -int currentThumbQueueSize = 0; -int currentAnimQueueSize = 0; - -void enqueueBGTask(LoadBackgroundTask* task) { - SDL_LockMutex(bgqueueMutex); - TaskNode* node = (TaskNode*)malloc(sizeof(TaskNode)); - node->task = task; - node->next = NULL; - - // If queue is full, drop the oldest task (head) - if (currentBGQueueSize >= MAX_QUEUE_SIZE) { - TaskNode* oldNode = taskBGQueueHead; - if (oldNode) { - taskBGQueueHead = oldNode->next; - if (!taskBGQueueHead) { - taskBGQueueTail = NULL; - } - if (oldNode->task) { - free(oldNode->task); // Only if task was malloc'd - } - free(oldNode); - currentBGQueueSize--; - } - } - - // Enqueue the new task - if (taskBGQueueTail) { - taskBGQueueTail->next = node; - taskBGQueueTail = node; - } else { - taskBGQueueHead = taskBGQueueTail = node; - } - - currentBGQueueSize++; - SDL_CondSignal(bgqueueCond); - SDL_UnlockMutex(bgqueueMutex); -} -void enqueueThumbTask(LoadBackgroundTask* task) { - SDL_LockMutex(thumbqueueMutex); - TaskNode* node = (TaskNode*)malloc(sizeof(TaskNode)); - node->task = task; - node->next = NULL; - - // If queue is full, drop the oldest task (head) - if (currentThumbQueueSize >= MAX_QUEUE_SIZE) { - TaskNode* oldNode = taskThumbQueueHead; - if (oldNode) { - taskThumbQueueHead = oldNode->next; - if (!taskThumbQueueHead) { - taskThumbQueueTail = NULL; - } - if (oldNode->task) { - free(oldNode->task); // Only if task was malloc'd - } - free(oldNode); - currentThumbQueueSize--; - } - } - - // Enqueue the new task - if (taskThumbQueueTail) { - taskThumbQueueTail->next = node; - taskThumbQueueTail = node; - } else { - taskThumbQueueHead = taskThumbQueueTail = node; - } - - currentThumbQueueSize++; - SDL_CondSignal(thumbqueueCond); - SDL_UnlockMutex(thumbqueueMutex); -} - -// Worker thread -int BGLoadWorker(void* unused) { - while (!SDL_AtomicGet(&workerThreadsShutdown)) { - SDL_LockMutex(bgqueueMutex); - while (!taskBGQueueHead && !SDL_AtomicGet(&workerThreadsShutdown)) { - SDL_CondWait(bgqueueCond, bgqueueMutex); - } - if (SDL_AtomicGet(&workerThreadsShutdown)) { - SDL_UnlockMutex(bgqueueMutex); - break; - } - TaskNode* node = taskBGQueueHead; - taskBGQueueHead = node->next; - if (!taskBGQueueHead) taskBGQueueTail = NULL; - SDL_UnlockMutex(bgqueueMutex); - // give processor lil space in between queue items for other shit - //SDL_Delay(100); - LoadBackgroundTask* task = node->task; - free(node); - - SDL_Surface* result = NULL; - if (access(task->imagePath, F_OK) == 0) { - SDL_Surface* image = IMG_Load(task->imagePath); - if (image) { - SDL_Surface* imageRGBA = SDL_ConvertSurfaceFormat(image, screen->format->format, 0); - SDL_FreeSurface(image); - result = imageRGBA; - } - } - - if (task->callback) { - task->callback(result); - } - free(task); - SDL_LockMutex(bgqueueMutex); - if (!taskBGQueueHead) taskBGQueueTail = NULL; - currentBGQueueSize--; // <-- add this - SDL_UnlockMutex(bgqueueMutex); - } - return 0; -} -int ThumbLoadWorker(void* unused) { - while (!SDL_AtomicGet(&workerThreadsShutdown)) { - SDL_LockMutex(thumbqueueMutex); - while (!taskThumbQueueHead && !SDL_AtomicGet(&workerThreadsShutdown)) { - SDL_CondWait(thumbqueueCond, thumbqueueMutex); - } - if (SDL_AtomicGet(&workerThreadsShutdown)) { - SDL_UnlockMutex(thumbqueueMutex); - break; - } - TaskNode* node = taskThumbQueueHead; - taskThumbQueueHead = node->next; - if (!taskThumbQueueHead) taskThumbQueueTail = NULL; - SDL_UnlockMutex(thumbqueueMutex); - // give processor lil space in between queue items for other shit - //SDL_Delay(100); - LoadBackgroundTask* task = node->task; - free(node); - - SDL_Surface* result = NULL; - if (access(task->imagePath, F_OK) == 0) { - SDL_Surface* image = IMG_Load(task->imagePath); - if (image) { - SDL_Surface* imageRGBA = SDL_ConvertSurfaceFormat(image, screen->format->format, 0); - SDL_FreeSurface(image); - result = imageRGBA; - } - } - - if (task->callback) { - task->callback(result); - } - free(task); - SDL_LockMutex(thumbqueueMutex); - if (!taskThumbQueueHead) taskThumbQueueTail = NULL; - currentThumbQueueSize--; // <-- add this - SDL_UnlockMutex(thumbqueueMutex); - } - return 0; -} - // --- Folder background loader ------------------------------------------------ // One std::thread consuming a thread-safe queue. Replaces the hand-rolled // SDL_mutex/SDL_cond linked-list queue + BGLoadWorker (whose data race the POC @@ -1948,118 +1722,7 @@ void onThumbLoaded(SDL_Surface* surface) { SDL_Rect pillRect; int pilltargetY =0; int pilltargetTextY =0; -void animcallback(finishedTask *task) { - SDL_LockMutex(animMutex); - pillRect = task->dst; - if(pillRect.w > 0 && pillRect.h > 0) { - pilltargetY = +screen->w; // move offscreen - if(task->done) { - pilltargetY = task->targetY; - pilltargetTextY = task->targetTextY; - } - setNeedDraw(1); - } - SDL_UnlockMutex(animMutex); - setAnimationDraw(1); -} -bool frameReady = true; bool pillanimdone = false; - -int animWorker(void* unused) { - while (!SDL_AtomicGet(&workerThreadsShutdown)) { - SDL_LockMutex(animqueueMutex); - while (!animTaskQueueHead && !SDL_AtomicGet(&workerThreadsShutdown)) { - SDL_CondWait(animqueueCond, animqueueMutex); - } - if (SDL_AtomicGet(&workerThreadsShutdown)) { - SDL_UnlockMutex(animqueueMutex); - break; - } - AnimTaskNode* node = animTaskQueueHead; - animTaskQueueHead = node->next; - if (!animTaskQueueHead) animTtaskQueueTail = NULL; - SDL_UnlockMutex(animqueueMutex); - - AnimTask* task = node->task; - finishedTask* finaltask = (finishedTask*)malloc(sizeof(finishedTask)); - int total_frames = task->frames; - for (int frame = 0; frame <= total_frames; frame++) { - // Check for shutdown at start of each frame - if (SDL_AtomicGet(&workerThreadsShutdown)) break; - - float t = (float)frame / total_frames; - if (t > 1.0f) t = 1.0f; - - int current_x = task->startX + (int)((task->targetX - task->startX) * t); - int current_y = task->startY + (int)(( task->targetY - task->startY) * t); - - SDL_Rect moveDst = { current_x, current_y, task->move_w, task->move_h }; - finaltask->dst = moveDst; - finaltask->entry_name = task->entry_name; - finaltask->move_w = task->move_w; - finaltask->move_h = task->move_h; - finaltask->targetY = task->targetY; - finaltask->targetTextY = task->targetTextY; - finaltask->move_y = SCALE1(PADDING + task->targetY) + (task->targetTextY - task->targetY); - finaltask->done = 0; - if(frame >= total_frames) finaltask->done=1; - task->callback(finaltask); - SDL_LockMutex(frameMutex); - while (!frameReady && !SDL_AtomicGet(&workerThreadsShutdown)) { - SDL_CondWait(flipCond, frameMutex); - } - frameReady = false; - SDL_UnlockMutex(frameMutex); - - } - SDL_LockMutex(animqueueMutex); - if (!animTaskQueueHead) animTtaskQueueTail = NULL; - currentAnimQueueSize--; // <-- add this - SDL_UnlockMutex(animqueueMutex); - - SDL_LockMutex(animMutex); - pillanimdone = true; - free(finaltask); - SDL_UnlockMutex(animMutex); - } -} - -void enqueueanmimtask(AnimTask* task) { - AnimTaskNode* node = (AnimTaskNode*)malloc(sizeof(AnimTaskNode)); - node->task = task; - node->next = NULL; - - SDL_LockMutex(animqueueMutex); - pillanimdone = false; - // If queue is full, drop the oldest task (head) - if (currentAnimQueueSize >= 1) { - AnimTaskNode* oldNode = animTaskQueueHead; - if (oldNode) { - animTaskQueueHead = oldNode->next; - if (!animTaskQueueHead) { - animTtaskQueueTail = NULL; - } - if (oldNode->task) { - free(oldNode->task); // Only if task was malloc'd - } - free(oldNode); - currentAnimQueueSize--; - } - } - - // Enqueue the new task - if (animTtaskQueueTail) { - animTtaskQueueTail->next = node; - animTtaskQueueTail = node; - } else { - animTaskQueueHead = animTtaskQueueTail = node; - } - - currentAnimQueueSize++; - SDL_CondSignal(animqueueCond); - SDL_UnlockMutex(animqueueMutex); -} - // Main-thread pill animation. The pill (the selection highlight) slides from // its current position to the target over `frames` frames. This used to run in // a worker thread that tweened across frames and handed each position back to @@ -2135,41 +1798,18 @@ void animPill(AnimTask *task) { } void initImageLoaderPool() { - // Initialize shutdown flag to 0 - SDL_AtomicSet(&workerThreadsShutdown, 0); SDL_AtomicSet(&animationDrawAtomic, 1); SDL_AtomicSet(&needDrawAtomic, 0); - thumbqueueMutex = SDL_CreateMutex(); - bgqueueMutex = SDL_CreateMutex(); - bgqueueCond = SDL_CreateCond(); - thumbqueueCond = SDL_CreateCond(); bgMutex = SDL_CreateMutex(); thumbMutex = SDL_CreateMutex(); animMutex = SDL_CreateMutex(); - animqueueMutex = SDL_CreateMutex(); - animqueueCond = SDL_CreateCond(); - frameMutex = SDL_CreateMutex(); fontMutex = SDL_CreateMutex(); - flipCond = SDL_CreateCond(); // Folder backgrounds and thumbnails each run on their own std::thread + // ThreadSafeQueue loader. bgLoadWorkerThread = std::thread(bgLoadWorkerLoop); thumbLoadWorkerThread = std::thread(thumbLoadWorkerLoop); - -#if NEXTUI_POC_NO_WORKERS - // The legacy SDL bg/thumb workers are superseded by the std::thread loaders - // above, and the pill animation is now main-thread. Nothing left to spawn on - // the old path. - bgLoadThread = NULL; - thumbLoadThread = NULL; - animWorkerThread = NULL; -#else - bgLoadThread = SDL_CreateThread(BGLoadWorker, "BGLoadWorker", NULL); - thumbLoadThread = SDL_CreateThread(ThumbLoadWorker, "ThumbLoadWorker", NULL); - animWorkerThread = SDL_CreateThread(animWorker, "animWorker", NULL); -#endif } void cleanupImageLoaderPool() { @@ -2180,71 +1820,22 @@ void cleanupImageLoaderPool() { thumbLoadQueue.shutdown(); if (thumbLoadWorkerThread.joinable()) thumbLoadWorkerThread.join(); - // Signal all worker threads to exit (atomic set for thread safety) - SDL_AtomicSet(&workerThreadsShutdown, 1); - - // Wake up all waiting threads - if (bgqueueCond) SDL_CondSignal(bgqueueCond); - if (thumbqueueCond) SDL_CondSignal(thumbqueueCond); - if (animqueueCond) SDL_CondSignal(animqueueCond); - if (flipCond) SDL_CondSignal(flipCond); // Wake up animWorker if stuck waiting for frame flip - - // Wait for all worker threads to finish - if (bgLoadThread) { - SDL_WaitThread(bgLoadThread, NULL); - bgLoadThread = NULL; - } - if (thumbLoadThread) { - SDL_WaitThread(thumbLoadThread, NULL); - thumbLoadThread = NULL; - } - if (animWorkerThread) { - SDL_WaitThread(animWorkerThread, NULL); - animWorkerThread = NULL; - } - - // Small delay to ensure llvmpipe/OpenGL threads have completed any pending operations - SDL_Delay(10); - - // Acquire and release each mutex before destroying to ensure no thread is in a critical section - // This creates a memory barrier and ensures proper synchronization - if (bgqueueMutex) { SDL_LockMutex(bgqueueMutex); SDL_UnlockMutex(bgqueueMutex); } - if (thumbqueueMutex) { SDL_LockMutex(thumbqueueMutex); SDL_UnlockMutex(thumbqueueMutex); } - if (animqueueMutex) { SDL_LockMutex(animqueueMutex); SDL_UnlockMutex(animqueueMutex); } + // Acquire and release each mutex before destroying to ensure no thread is in a + // critical section -- a memory barrier for proper synchronization. if (bgMutex) { SDL_LockMutex(bgMutex); SDL_UnlockMutex(bgMutex); } if (thumbMutex) { SDL_LockMutex(thumbMutex); SDL_UnlockMutex(thumbMutex); } if (animMutex) { SDL_LockMutex(animMutex); SDL_UnlockMutex(animMutex); } - if (frameMutex) { SDL_LockMutex(frameMutex); SDL_UnlockMutex(frameMutex); } if (fontMutex) { SDL_LockMutex(fontMutex); SDL_UnlockMutex(fontMutex); } - // Destroy mutexes and condition variables - if (bgqueueMutex) SDL_DestroyMutex(bgqueueMutex); - if (thumbqueueMutex) SDL_DestroyMutex(thumbqueueMutex); - if (animqueueMutex) SDL_DestroyMutex(animqueueMutex); if (bgMutex) SDL_DestroyMutex(bgMutex); if (thumbMutex) SDL_DestroyMutex(thumbMutex); if (animMutex) SDL_DestroyMutex(animMutex); - if (frameMutex) SDL_DestroyMutex(frameMutex); if (fontMutex) SDL_DestroyMutex(fontMutex); - if (bgqueueCond) SDL_DestroyCond(bgqueueCond); - if (thumbqueueCond) SDL_DestroyCond(thumbqueueCond); - if (animqueueCond) SDL_DestroyCond(animqueueCond); - if (flipCond) SDL_DestroyCond(flipCond); - - // Set pointers to NULL after destruction - bgqueueMutex = NULL; - thumbqueueMutex = NULL; - animqueueMutex = NULL; bgMutex = NULL; thumbMutex = NULL; animMutex = NULL; - frameMutex = NULL; fontMutex = NULL; - bgqueueCond = NULL; - thumbqueueCond = NULL; - animqueueCond = NULL; - flipCond = NULL; } /////////////////////////////////////// @@ -3378,25 +2969,14 @@ int main (int argc, char *argv[]) { } else { // want to draw only if needed - SDL_LockMutex(bgqueueMutex); - SDL_LockMutex(thumbqueueMutex); - SDL_LockMutex(animqueueMutex); if(getNeedDraw()) { PLAT_GPU_Flip(); setNeedDraw(0); } else { GFX_sync(); } - SDL_UnlockMutex(animqueueMutex); - SDL_UnlockMutex(thumbqueueMutex); - SDL_UnlockMutex(bgqueueMutex); } - SDL_LockMutex(frameMutex); - frameReady = true; - SDL_CondSignal(flipCond); - SDL_UnlockMutex(frameMutex); - // animation does not carry over between loops, this should only ever be set by // input handling and directly consumed by the following render pass assert(animationdirection == ANIM_NONE); From 37cc7f5e8e8252471026501914ba27f3c4fdb035 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Thu, 2 Jul 2026 14:33:56 +0200 Subject: [PATCH 28/77] nextui: fix invisible button hints (g++ compound-literal miscompile) Every button-hint group was passed as GFX_blitButtonGroup((char**)(const char*[]){ ... }, ...). That GNU compound-literal argument is miscompiled by the toolchain's g++ 8.3 -- the callee reads garbage, the pill computes as zero-width, and nothing draws. Result: no on-screen hints (RESUME/OPEN/BACK /SLEEP...) anywhere in the launcher. Confirmed on device by probing one call two ways in the same frame: named local array -> ow = 259 (correct) compound literal -> ow = 0 (miscompiled) The pattern came in with the C->C++ port: the original C used (char*[]){...} (fine as C); it was cast to satisfy g++, which exposed the codegen bug. Route the hints through a named local array instead, via a small BTN_HINTS() macro (statement expression), and apply it to all 11 call sites. Same behaviour, correct codegen -- hints are back, and the game-switcher RESUME/OPEN split by save-state (from the upstream #751 merge) now shows correctly too. --- workspace/all/nextui/nextui.cpp | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/workspace/all/nextui/nextui.cpp b/workspace/all/nextui/nextui.cpp index 419fa4e56..1b58f1046 100644 --- a/workspace/all/nextui/nextui.cpp +++ b/workspace/all/nextui/nextui.cpp @@ -29,6 +29,14 @@ extern "C" { /////////////////////////////////////// +// g++ 8.3 miscompiles a GNU compound-literal argument -- passing +// (char**)(const char*[]){ ... } directly to a function makes the callee read +// garbage (the array's storage is dropped), so button-hint groups came back +// zero-width and drew nothing. Routing the hints through a *named* local array +// (via a statement expression) compiles correctly. Same call, safe codegen. +#define BTN_HINTS(primary, dst, align_right, ...) \ + ({ const char* _bh[] = { __VA_ARGS__ }; GFX_blitButtonGroup((char**)_bh, (primary), (dst), (align_right)); }) + static void StringArray_free(std::vector& self) { for (char* s : self) free(s); self.clear(); @@ -2286,9 +2294,9 @@ int main (int argc, char *argv[]) { // buttons (duped and trimmed from below) if (show_setting && !GetHDMI()) GFX_blitHardwareHints(screen, show_setting); - else GFX_blitButtonGroup((char**)(const char*[]){ BTN_SLEEP==BTN_POWER?"POWER":"MENU","SLEEP", NULL }, 0, screen, 0); + else BTN_HINTS(0, screen, 0, BTN_SLEEP==BTN_POWER?"POWER":"MENU","SLEEP", NULL); - GFX_blitButtonGroup((char**)(const char*[]){ "B","BACK", "A","OPEN", NULL }, 1, screen, 1); + BTN_HINTS(1, screen, 1, "B","BACK", "A","OPEN", NULL); if(CFG_getShowQuickswitcherUI()) { #define MENU_ITEM_SIZE 72 // item size, top line @@ -2453,10 +2461,10 @@ int main (int argc, char *argv[]) { SDL_FreeSurface(text); } - GFX_blitButtonGroup((char**)(const char*[]){ "B","BACK", NULL }, 0, screen, 0); + BTN_HINTS(0, screen, 0, "B","BACK", NULL); - if(can_resume) GFX_blitButtonGroup((char**)(const char*[]){ "Y", "REMOVE", "A","RESUME", NULL }, 1, screen, 1); - else GFX_blitButtonGroup((char**)(const char*[]){ "A","OPEN", NULL }, 1, screen, 1); + if(can_resume) BTN_HINTS(1, screen, 1, "Y","REMOVE", "A","RESUME", NULL); + else BTN_HINTS(1, screen, 1, "A","OPEN", NULL); if(has_preview) { // lotta memory churn here @@ -2543,7 +2551,7 @@ int main (int argc, char *argv[]) { SDL_Rect preview_rect = {ox,oy,screen->w,screen->h}; SDL_FillRect(screen, &preview_rect, 0); GFX_blitMessage(font.large, "No Recents", screen, &preview_rect); - GFX_blitButtonGroup((char**)(const char*[]){ "B","BACK", NULL }, 1, screen, 1); + BTN_HINTS(1, screen, 1, "B","BACK", NULL); } GFX_flipHidden(); @@ -2640,23 +2648,23 @@ int main (int argc, char *argv[]) { // buttons if (show_setting && !GetHDMI()) GFX_blitHardwareHints(screen, show_setting); - else if (can_resume) GFX_blitButtonGroup((char**)(const char*[]){ "X","RESUME", NULL }, 0, screen, 0); - else GFX_blitButtonGroup((char**)(const char*[]){ + else if (can_resume) BTN_HINTS(0, screen, 0, "X","RESUME", NULL); + else BTN_HINTS(0, screen, 0, BTN_SLEEP==BTN_POWER?"POWER":"MENU", BTN_SLEEP==BTN_POWER||simple_mode?"SLEEP":"INFO", - NULL }, 0, screen, 0); + NULL); if (total==0) { if ((int)stack.size()>1) { - GFX_blitButtonGroup((char**)(const char*[]){ "B","BACK", NULL }, 0, screen, 1); + BTN_HINTS(0, screen, 1, "B","BACK", NULL); } } else { if ((int)stack.size()>1) { - GFX_blitButtonGroup((char**)(const char*[]){ "B","BACK", "A","OPEN", NULL }, 1, screen, 1); + BTN_HINTS(1, screen, 1, "B","BACK", "A","OPEN", NULL); } else { - GFX_blitButtonGroup((char**)(const char*[]){ "A","OPEN", NULL }, 0, screen, 1); + BTN_HINTS(0, screen, 1, "A","OPEN", NULL); } } From dd7c3e4b042cc804b7d55b96767dc07f0cf5741d Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Thu, 2 Jul 2026 14:42:37 +0200 Subject: [PATCH 29/77] api: stop leaking lid and ALT_BUTTON_TEXT_COLOR through the facade Phase D nibble: both globals are used only inside api.c, yet were declared `extern` in api.h -- part of the god-object surface every module sees. Make them `static` and drop the externs. The LID_Context type stays public; only the instance goes private. Purely internal linkage -- no runtime change; the linker confirms nothing outside api.c referenced either symbol (all three binaries build clean). --- workspace/all/common/api.c | 4 ++-- workspace/all/common/api.h | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/workspace/all/common/api.c b/workspace/all/common/api.c index 17b14f2d6..6f9e67a02 100644 --- a/workspace/all/common/api.c +++ b/workspace/all/common/api.c @@ -103,7 +103,7 @@ uint32_t THEME_COLOR4; uint32_t THEME_COLOR5; uint32_t THEME_COLOR6; uint32_t THEME_COLOR7; -SDL_Color ALT_BUTTON_TEXT_COLOR; +static SDL_Color ALT_BUTTON_TEXT_COLOR; // move to utils? @@ -2927,7 +2927,7 @@ FALLBACK_IMPLEMENTATION void PLAT_overrideMute(int mute) {} /////////////////////////////// -LID_Context lid = { +static LID_Context lid = { .has_lid = 0, .is_open = 1, }; diff --git a/workspace/all/common/api.h b/workspace/all/common/api.h index 6f8247122..5f215c933 100644 --- a/workspace/all/common/api.h +++ b/workspace/all/common/api.h @@ -75,7 +75,6 @@ extern uint32_t THEME_COLOR4; extern uint32_t THEME_COLOR5; extern uint32_t THEME_COLOR6; extern uint32_t THEME_COLOR7; -extern SDL_Color ALT_BUTTON_TEXT_COLOR; typedef struct { float ratio; @@ -440,7 +439,6 @@ typedef struct LID_Context { int has_lid; int is_open; } LID_Context; -extern LID_Context lid; void PLAT_initLid(void); int PLAT_lidChanged(int* state); From 9b069643d2e86446c648db592b105dd37a60a449 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Thu, 2 Jul 2026 14:54:56 +0200 Subject: [PATCH 30/77] api: encapsulate the font god-object behind GFX_getFonts() The loaded fonts were a bare `extern GFX_Fonts font;` -- a mutable global on the facade that every module reached into directly (font.large, font.tiny, ...). Make the instance `static` in api.c and expose a `GFX_getFonts()` accessor; convert all ~170 call sites across nextui, minarch, settings and the tool paks to GFX_getFonts()->field. api.c keeps direct access to its own static. Mechanical and semantically a no-op -- the accessor just returns &font, same pointers -- so text rendering is unchanged. The linker verifies every site was converted (nothing outside api.c can still name `font`); all binaries build clean and the launcher boots stable on the Brick with no crash cores. --- workspace/all/battery/battery.c | 20 +++--- workspace/all/clock/clock.c | 4 +- workspace/all/common/api.c | 3 +- workspace/all/common/api.h | 4 +- workspace/all/common/notification.c | 12 ++-- workspace/all/gametime/gametime.c | 8 +-- workspace/all/ledcontrol/ledcontrol.c | 10 +-- workspace/all/minarch/ma_frontend_opts.c | 8 +-- workspace/all/minarch/ma_menu.c | 72 +++++++++++----------- workspace/all/minarch/ma_options.c | 8 +-- workspace/all/minput/minput.c | 8 +-- workspace/all/nextui/nextui.cpp | 30 ++++----- workspace/all/settings/btmenu.cpp | 12 ++-- workspace/all/settings/colorpickermenu.cpp | 20 +++--- workspace/all/settings/keyboardprompt.cpp | 14 ++--- workspace/all/settings/menu.cpp | 38 ++++++------ workspace/all/settings/settings.cpp | 4 +- workspace/all/settings/wifimenu.cpp | 6 +- 18 files changed, 142 insertions(+), 139 deletions(-) diff --git a/workspace/all/battery/battery.c b/workspace/all/battery/battery.c index 68fae04d5..44593b402 100644 --- a/workspace/all/battery/battery.c +++ b/workspace/all/battery/battery.c @@ -453,10 +453,10 @@ void renderPage() switch_zoom_profile(segment_duration); // x axis labels - renderText(label[0], font.small, COLOR_WHITE, &(SDL_Rect){graph.layout.label1_x, graph.layout.label_y, 32, 32}); - renderText(label[1], font.small, COLOR_WHITE, &(SDL_Rect){graph.layout.label2_x, graph.layout.label_y, 32, 32}); - renderText(label[2], font.small, COLOR_WHITE, &(SDL_Rect){graph.layout.label3_x, graph.layout.label_y, 32, 32}); - renderText(label[3], font.small, COLOR_WHITE, &(SDL_Rect){graph.layout.label4_x, graph.layout.label_y, 32, 32}); + renderText(label[0], GFX_getFonts()->small, COLOR_WHITE, &(SDL_Rect){graph.layout.label1_x, graph.layout.label_y, 32, 32}); + renderText(label[1], GFX_getFonts()->small, COLOR_WHITE, &(SDL_Rect){graph.layout.label2_x, graph.layout.label_y, 32, 32}); + renderText(label[2], GFX_getFonts()->small, COLOR_WHITE, &(SDL_Rect){graph.layout.label3_x, graph.layout.label_y, 32, 32}); + renderText(label[3], GFX_getFonts()->small, COLOR_WHITE, &(SDL_Rect){graph.layout.label4_x, graph.layout.label_y, 32, 32}); // y axis "labels" drawBatteryIcon(100, (SDL_Rect){graph.layout.icon_x, graph.layout.icon1_y}); @@ -466,16 +466,16 @@ void renderPage() char text_line[255]; sprintf(text_line, "Since Charge: %s", session_duration); - renderText(text_line, font.medium, COLOR_WHITE, &(SDL_Rect){graph.layout.label_session_x, graph.layout.label_session_y, graph.layout.label_size_x, graph.layout.label_size_y}); + renderText(text_line, GFX_getFonts()->medium, COLOR_WHITE, &(SDL_Rect){graph.layout.label_session_x, graph.layout.label_session_y, graph.layout.label_size_x, graph.layout.label_size_y}); sprintf(text_line, "Current: %s", current_percentage); - renderText(text_line, font.medium, COLOR_WHITE, &(SDL_Rect){graph.layout.label_current_x, graph.layout.label_current_y, graph.layout.label_size_x, graph.layout.label_size_y}); + renderText(text_line, GFX_getFonts()->medium, COLOR_WHITE, &(SDL_Rect){graph.layout.label_current_x, graph.layout.label_current_y, graph.layout.label_size_x, graph.layout.label_size_y}); sprintf(text_line, "Remaining: %s", session_left); - renderTextAlignRight(text_line, font.medium, COLOR_WHITE, &(SDL_Rect){graph.layout.label_left_x, graph.layout.label_left_y, graph.layout.label_size_x, graph.layout.label_size_y}); + renderTextAlignRight(text_line, GFX_getFonts()->medium, COLOR_WHITE, &(SDL_Rect){graph.layout.label_left_x, graph.layout.label_left_y, graph.layout.label_size_x, graph.layout.label_size_y}); sprintf(text_line, "Longest: %s", session_best); - renderTextAlignRight(text_line, font.medium, COLOR_WHITE, &(SDL_Rect){graph.layout.label_best_x, graph.layout.label_best_y, graph.layout.label_size_x, graph.layout.label_size_y}); + renderTextAlignRight(text_line, GFX_getFonts()->medium, COLOR_WHITE, &(SDL_Rect){graph.layout.label_best_x, graph.layout.label_best_y, graph.layout.label_size_x, graph.layout.label_size_y}); int half_line_width = (int)(GRAPH_LINE_WIDTH) / 2; @@ -746,11 +746,11 @@ int main(int argc, char *argv[]) } char title[256]; - int text_width = GFX_truncateText(font.large, display_name, title, max_width, SCALE1(BUTTON_PADDING * 2)); + int text_width = GFX_truncateText(GFX_getFonts()->large, display_name, title, max_width, SCALE1(BUTTON_PADDING * 2)); max_width = MIN(max_width, text_width); SDL_Surface *text; - text = TTF_RenderUTF8_Blended(font.large, title, COLOR_WHITE); + text = TTF_RenderUTF8_Blended(GFX_getFonts()->large, title, COLOR_WHITE); GFX_blitPill(ASSET_BLACK_PILL, screen, &(SDL_Rect){SCALE1(PADDING), SCALE1(PADDING), max_width, SCALE1(PILL_SIZE)}); SDL_BlitSurface(text, &(SDL_Rect){0, 0, max_width - SCALE1(BUTTON_PADDING * 2), text->h}, screen, &(SDL_Rect){SCALE1(PADDING + BUTTON_PADDING), SCALE1(PADDING + 4)}); diff --git a/workspace/all/clock/clock.c b/workspace/all/clock/clock.c index 3734f6329..d2782f818 100644 --- a/workspace/all/clock/clock.c +++ b/workspace/all/clock/clock.c @@ -41,7 +41,7 @@ int main(int argc , char* argv[]) { #define CHAR_SLASH 10 #define CHAR_COLON 11 while (c = chars[i]) { - digit = TTF_RenderUTF8_Blended(font.large, c, COLOR_WHITE); + digit = TTF_RenderUTF8_Blended(GFX_getFonts()->large, c, COLOR_WHITE); int y = i==CHAR_COLON ? SCALE1(-1.5) : 0; // : sits too low naturally // TODO: y offset is wrong here // printf("%s x:%i y:%i SCALE1(DIGIT_HEIGHT):%i SCALE1(DIGIT_HEIGHT) - digit->h:%i\n", c, (i * SCALE1(DIGIT_WIDTH)), y, SCALE1(DIGIT_HEIGHT), SCALE1(DIGIT_HEIGHT) - digit->h); fflush(stdout); @@ -294,7 +294,7 @@ int main(int argc , char* argv[]) { int ampm_w; if (!show_24hour) { x += SCALE1(10); // space - SDL_Surface* text = TTF_RenderUTF8_Blended(font.large, am_selected ? "AM" : "PM", COLOR_WHITE); + SDL_Surface* text = TTF_RenderUTF8_Blended(GFX_getFonts()->large, am_selected ? "AM" : "PM", COLOR_WHITE); ampm_w = text->w + SCALE1(2); SDL_BlitSurface(text, NULL, screen, &(SDL_Rect){x,y-SCALE1(3)}); SDL_FreeSurface(text); diff --git a/workspace/all/common/api.c b/workspace/all/common/api.c index 6f9e67a02..1d8854264 100644 --- a/workspace/all/common/api.c +++ b/workspace/all/common/api.c @@ -92,7 +92,8 @@ static struct GFX_Context static SDL_Rect asset_rects[ASSET_COUNT]; static uint32_t asset_rgbs[ASSET_COLORS]; -GFX_Fonts font; +static GFX_Fonts font; +GFX_Fonts* GFX_getFonts(void) { return &font; } /////////////////////////////// diff --git a/workspace/all/common/api.h b/workspace/all/common/api.h index 5f215c933..d937955bf 100644 --- a/workspace/all/common/api.h +++ b/workspace/all/common/api.h @@ -177,7 +177,9 @@ typedef struct GFX_Fonts { TTF_Font* tiny; // multi char button label TTF_Font* micro; // icon overlay text } GFX_Fonts; -extern GFX_Fonts font; +// The loaded fonts live inside api.c; reach them through this accessor rather +// than a bare extern global. +GFX_Fonts* GFX_getFonts(void); enum { SHARPNESS_SHARP, diff --git a/workspace/all/common/notification.c b/workspace/all/common/notification.c index f8d454f4a..34afaa65a 100644 --- a/workspace/all/common/notification.c +++ b/workspace/all/common/notification.c @@ -304,7 +304,7 @@ static void render_progress_indicator(const ProgressIndicatorState* snap) { } int text_w = 0, text_h = 0; - TTF_SizeUTF8(font.tiny, progress_text, &text_w, &text_h); + TTF_SizeUTF8(GFX_getFonts()->tiny, progress_text, &text_w, &text_h); // Calculate icon dimensions if present int icon_w = 0, icon_h = 0, icon_total_w = 0; @@ -339,7 +339,7 @@ static void render_progress_indicator(const ProgressIndicatorState* snap) { content_x += icon_total_w; } - SDL_Surface* text_surf = TTF_RenderUTF8_Blended(font.tiny, progress_text, text_color); + SDL_Surface* text_surf = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, progress_text, text_color); if (text_surf) { SDL_SetSurfaceBlendMode(text_surf, SDL_BLENDMODE_BLEND); SDL_Rect text_dst = {content_x, notif_padding_y, text_surf->w, text_surf->h}; @@ -356,7 +356,7 @@ static void render_progress_indicator(const ProgressIndicatorState* snap) { // Render a single notification pill static void render_notification_pill(Notification* n, int x, int y, SDL_Color text_color, SDL_Color bg_color_sdl) { int text_w = 0, text_h = 0; - TTF_SizeUTF8(font.tiny, n->message, &text_w, &text_h); + TTF_SizeUTF8(GFX_getFonts()->tiny, n->message, &text_w, &text_h); int icon_w = 0, icon_h = 0, icon_total_w = 0; if (n->icon) { @@ -402,7 +402,7 @@ static void render_notification_pill(Notification* n, int x, int y, SDL_Color te content_x += wifi_size + notif_icon_gap; } - SDL_Surface* text_surf = TTF_RenderUTF8_Blended(font.tiny, n->message, text_color); + SDL_Surface* text_surf = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, n->message, text_color); if (text_surf) { SDL_SetSurfaceBlendMode(text_surf, SDL_BLENDMODE_BLEND); SDL_Rect text_dst = {content_x, notif_padding_y, text_surf->w, text_surf->h}; @@ -428,14 +428,14 @@ static void render_notification_stack(void) { Notification* n = ¬ifications[i]; int text_h = 0; - TTF_SizeUTF8(font.tiny, n->message, NULL, &text_h); + TTF_SizeUTF8(GFX_getFonts()->tiny, n->message, NULL, &text_h); int pill_h = text_h + (notif_padding_y * 2); // Calculate stack offset (how far up from base) int stack_offset = 0; for (int j = i + 1; j < notification_count; j++) { int other_text_h = 0; - TTF_SizeUTF8(font.tiny, notifications[j].message, NULL, &other_text_h); + TTF_SizeUTF8(GFX_getFonts()->tiny, notifications[j].message, NULL, &other_text_h); int other_pill_h = other_text_h + (notif_padding_y * 2); stack_offset += other_pill_h + notif_stack_gap; } diff --git a/workspace/all/gametime/gametime.c b/workspace/all/gametime/gametime.c index 49f23c4ca..d46a93045 100644 --- a/workspace/all/gametime/gametime.c +++ b/workspace/all/gametime/gametime.c @@ -263,7 +263,7 @@ void renderList(int count, int start, int end, int selected) //textColor = colorFromUint(THEME_COLOR1); textColor = COLOR_BLACK; } - renderText(rom_name, font.medium, textColor, &(SDL_Rect){ + renderText(rom_name, GFX_getFonts()->medium, textColor, &(SDL_Rect){ layout.list_display_start_x + num_width + thumbMargin + SCALE1(IMG_MAX_WIDTH), layout.list_display_start_y + thumbMargin / 2 + elemHeight * row, layout.list_display_size_x, @@ -284,7 +284,7 @@ void renderList(int count, int start, int end, int selected) SDL_Color detailCol = i % 2 == 0 ? COLOR_DARK_TEXT : colorFromUint(THEME_COLOR2_255); //SDL_Color detailCol = colorFromUint(i % 2 == 0 ? THEME_COLOR3_255 : THEME_COLOR2_255); //SDL_Color detailCol = i % 2 == 0 ? COLOR_DARK_TEXT : COLOR_LIGHT_TEXT; - detailsRect.x += renderText(details[i], font.small, detailCol, &detailsRect); + detailsRect.x += renderText(details[i], GFX_getFonts()->small, detailCol, &detailsRect); } } @@ -420,11 +420,11 @@ int main(int argc, char *argv[]) sprintf(display_name, "Time spent having fun: %s", play_time_total_formatted); char title[256]; - int text_width = GFX_truncateText(font.large, display_name, title, max_width, SCALE1(BUTTON_PADDING * 2)); + int text_width = GFX_truncateText(GFX_getFonts()->large, display_name, title, max_width, SCALE1(BUTTON_PADDING * 2)); max_width = MIN(max_width, text_width); SDL_Surface *text; - text = TTF_RenderUTF8_Blended(font.large, title, COLOR_WHITE); + text = TTF_RenderUTF8_Blended(GFX_getFonts()->large, title, COLOR_WHITE); GFX_blitPill(ASSET_BLACK_PILL, screen, &(SDL_Rect){SCALE1(PADDING), SCALE1(PADDING), max_width, SCALE1(PILL_SIZE)}); SDL_BlitSurface(text, &(SDL_Rect){0, 0, max_width - SCALE1(BUTTON_PADDING * 2), text->h}, screen, &(SDL_Rect){SCALE1(PADDING + BUTTON_PADDING), SCALE1(PADDING + 4)}); SDL_FreeSurface(text); diff --git a/workspace/all/ledcontrol/ledcontrol.c b/workspace/all/ledcontrol/ledcontrol.c index 0452703f1..241b0f1a3 100644 --- a/workspace/all/ledcontrol/ledcontrol.c +++ b/workspace/all/ledcontrol/ledcontrol.c @@ -308,11 +308,11 @@ int main(int argc, char *argv[]) snprintf(light_name_text, sizeof(light_name_text), "%s", lightnames[selected_light]); char title[256]; - int text_width = GFX_truncateText(font.medium, light_name_text, title, max_width, SCALE1(BUTTON_PADDING * 2)); + int text_width = GFX_truncateText(GFX_getFonts()->medium, light_name_text, title, max_width, SCALE1(BUTTON_PADDING * 2)); max_width = MIN(max_width, text_width); SDL_Surface *text; - text = TTF_RenderUTF8_Blended(font.medium, title, COLOR_WHITE); + text = TTF_RenderUTF8_Blended(GFX_getFonts()->medium, title, COLOR_WHITE); GFX_blitPill(ASSET_BLACK_PILL, screen, &(SDL_Rect){SCALE1(PADDING), SCALE1(PADDING), max_width, SCALE1(PILL_SIZE)}); SDL_BlitSurface(text, &(SDL_Rect){0, 0, max_width - SCALE1(BUTTON_PADDING * 2), text->h}, screen, &(SDL_Rect){SCALE1(PADDING + BUTTON_PADDING), SCALE1(PADDING + 4)}); SDL_FreeSurface(text); @@ -346,7 +346,7 @@ int main(int argc, char *argv[]) if (j == 0) { // Display effect name instead of number snprintf(setting_text, sizeof(setting_text), "%s: %s", settings_labels[j], selected_light == 3 ? lr_effect_names[settings_values[j] - 1] : selected_light == 2 ? topbar_effect_names[settings_values[j] - 1] : effect_names[settings_values[j] - 1]); - SDL_Surface *text = TTF_RenderUTF8_Blended(font.medium, setting_text, current_color); + SDL_Surface *text = TTF_RenderUTF8_Blended(GFX_getFonts()->medium, setting_text, current_color); int text_width = text->w + SCALE1(BUTTON_PADDING * 2); GFX_blitPill(selected ? ASSET_WHITE_PILL : ASSET_BLACK_PILL, screen, &(SDL_Rect){SCALE1(PADDING), y, text_width, SCALE1(PILL_SIZE)}); @@ -356,7 +356,7 @@ int main(int argc, char *argv[]) SDL_FreeSurface(text); } else if (j == 1) { // Display color as hex code snprintf(setting_text, sizeof(setting_text), "%s", settings_labels[j]); - SDL_Surface *text = TTF_RenderUTF8_Blended(font.medium, setting_text, current_color); + SDL_Surface *text = TTF_RenderUTF8_Blended(GFX_getFonts()->medium, setting_text, current_color); int text_width = text->w + SCALE1(BUTTON_PADDING * 2); GFX_blitPill(selected ? ASSET_WHITE_PILL : ASSET_BLACK_PILL, screen, &(SDL_Rect){SCALE1(PADDING), y, text_width + SCALE1(BUTTON_MARGIN + BUTTON_SIZE), SCALE1(PILL_SIZE)}); @@ -371,7 +371,7 @@ int main(int argc, char *argv[]) }, settings_values[j]); } else { snprintf(setting_text, sizeof(setting_text), "%s: %d", settings_labels[j], settings_values[j]); - SDL_Surface *text = TTF_RenderUTF8_Blended(font.medium, setting_text, current_color); + SDL_Surface *text = TTF_RenderUTF8_Blended(GFX_getFonts()->medium, setting_text, current_color); int text_width = text->w + SCALE1(BUTTON_PADDING * 2); GFX_blitPill(selected ? ASSET_WHITE_PILL : ASSET_BLACK_PILL, screen, &(SDL_Rect){SCALE1(PADDING), y, text_width, SCALE1(PILL_SIZE)}); diff --git a/workspace/all/minarch/ma_frontend_opts.c b/workspace/all/minarch/ma_frontend_opts.c index e687722cb..a70d89bb6 100644 --- a/workspace/all/minarch/ma_frontend_opts.c +++ b/workspace/all/minarch/ma_frontend_opts.c @@ -35,7 +35,7 @@ int Menu_messageWithFont(char* message, char** pairs, TTF_Font* f) { } int Menu_message(char* message, char** pairs) { - return Menu_messageWithFont(message, pairs, font.medium); + return Menu_messageWithFont(message, pairs, GFX_getFonts()->medium); } static int MenuList_freeItems(MenuList* list, int i) { @@ -140,7 +140,7 @@ static int OptionEmulator_optionDetail(MenuList* list, int i) { } else { Option* option = OptionList_getOption(&config.core, item->key); - if (option->full) return Menu_messageWithFont(option->full, (char*[]){ "B","BACK", NULL }, font.medium); + if (option->full) return Menu_messageWithFont(option->full, (char*[]){ "B","BACK", NULL }, GFX_getFonts()->medium); else return MENU_CALLBACK_NOP; } } @@ -520,7 +520,7 @@ int OptionCheats_openMenu(MenuList* list, int i) { len = strlen(cheat->info) + 1; item->desc = calloc(len, sizeof(char)); strncpy(item->desc, cheat->info, len); - GFX_wrapText(font.tiny, item->desc, DEVICE_WIDTH - SCALE1(2*PADDING), 2); + GFX_wrapText(GFX_getFonts()->tiny, item->desc, DEVICE_WIDTH - SCALE1(2*PADDING), 2); } item->value = cheat->enabled; @@ -588,7 +588,7 @@ int OptionCheats_openMenu(MenuList* list, int i) { } } - Menu_messageWithFont(cheats_path, (char*[]){ "B","BACK", NULL }, font.small); + Menu_messageWithFont(cheats_path, (char*[]){ "B","BACK", NULL }, GFX_getFonts()->small); } return MENU_CALLBACK_NOP; diff --git a/workspace/all/minarch/ma_menu.c b/workspace/all/minarch/ma_menu.c index e7a5e083a..5297b33d3 100644 --- a/workspace/all/minarch/ma_menu.c +++ b/workspace/all/minarch/ma_menu.c @@ -49,7 +49,7 @@ void MSG_init(void) { char* c; int i = 0; while ((c = chars[i])) { - digit = TTF_RenderUTF8_Blended(font.tiny, c, COLOR_WHITE); + digit = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, c, COLOR_WHITE); SDL_BlitSurface(digit, NULL, digits, &(SDL_Rect){ (i * SCALE1(DIGIT_WIDTH)) + (SCALE1(DIGIT_WIDTH) - digit->w)/2, (SCALE1(DIGIT_HEIGHT) - digit->h)/2}); SDL_FreeSurface(digit); i += 1; @@ -390,11 +390,11 @@ static int OptionAchievements_showDetail(MenuList* list, int i) { // Title centered - wrap to max 2 lines with ellipsis if needed int max_text_width = screen->w - SCALE1(PADDING * 2); - content_y = GFX_blitWrappedText(font.medium, ach->title, max_text_width, 2, COLOR_WHITE, screen, content_y); + content_y = GFX_blitWrappedText(GFX_getFonts()->medium, ach->title, max_text_width, 2, COLOR_WHITE, screen, content_y); content_y += SCALE1(2); // Spacing after title // Description - unlimited lines - content_y = GFX_blitWrappedText(font.small, ach->description, max_text_width, 0, COLOR_WHITE, screen, content_y); + content_y = GFX_blitWrappedText(GFX_getFonts()->small, ach->description, max_text_width, 0, COLOR_WHITE, screen, content_y); content_y += SCALE1(4); // Spacing after description // Points (singular/plural) - use tiny font like other metadata @@ -404,7 +404,7 @@ static int OptionAchievements_showDetail(MenuList* list, int i) { } else { snprintf(points_str, sizeof(points_str), "%u points", ach->points); } - SDL_Surface* points_text = TTF_RenderUTF8_Blended(font.tiny, points_str, COLOR_LIGHT_TEXT); + SDL_Surface* points_text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, points_str, COLOR_LIGHT_TEXT); SDL_BlitSurface(points_text, NULL, screen, &(SDL_Rect){ center_x - points_text->w / 2, content_y }); @@ -416,7 +416,7 @@ static int OptionAchievements_showDetail(MenuList* list, int i) { struct tm* tm_info = localtime(&ach->unlock_time); char time_buf[64]; strftime(time_buf, sizeof(time_buf), "Unlocked %B %d %Y, %I:%M%p", tm_info); - SDL_Surface* time_text = TTF_RenderUTF8_Blended(font.tiny, time_buf, COLOR_LIGHT_TEXT); + SDL_Surface* time_text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, time_buf, COLOR_LIGHT_TEXT); SDL_BlitSurface(time_text, NULL, screen, &(SDL_Rect){ center_x - time_text->w / 2, content_y }); @@ -425,7 +425,7 @@ static int OptionAchievements_showDetail(MenuList* list, int i) { } else if (ach->measured_progress[0]) { char progress_buf[64]; snprintf(progress_buf, sizeof(progress_buf), "Progress: %s", ach->measured_progress); - SDL_Surface* progress_text = TTF_RenderUTF8_Blended(font.tiny, progress_buf, COLOR_LIGHT_TEXT); + SDL_Surface* progress_text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, progress_buf, COLOR_LIGHT_TEXT); SDL_BlitSurface(progress_text, NULL, screen, &(SDL_Rect){ center_x - progress_text->w / 2, content_y }); @@ -435,7 +435,7 @@ static int OptionAchievements_showDetail(MenuList* list, int i) { // Offline pending indicator if (is_offline_pending) { - SDL_Surface* offline_text = TTF_RenderUTF8_Blended(font.tiny, "Unlocked offline - pending sync", COLOR_LIGHT_TEXT); + SDL_Surface* offline_text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, "Unlocked offline - pending sync", COLOR_LIGHT_TEXT); int wifi_size = SCALE1(12); int total_w = wifi_size + SCALE1(4) + offline_text->w; int icon_x = center_x - total_w / 2; @@ -454,7 +454,7 @@ static int OptionAchievements_showDetail(MenuList* list, int i) { if (ach->rarity > 0) { char rarity_buf[32]; snprintf(rarity_buf, sizeof(rarity_buf), "%.2f%% unlock rate", ach->rarity); - SDL_Surface* rarity_text = TTF_RenderUTF8_Blended(font.tiny, rarity_buf, COLOR_LIGHT_TEXT); + SDL_Surface* rarity_text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, rarity_buf, COLOR_LIGHT_TEXT); SDL_BlitSurface(rarity_text, NULL, screen, &(SDL_Rect){ center_x - rarity_text->w / 2, content_y }); @@ -478,7 +478,7 @@ static int OptionAchievements_showDetail(MenuList* list, int i) { break; } if (type_str) { - SDL_Surface* type_text = TTF_RenderUTF8_Blended(font.tiny, type_str, COLOR_LIGHT_TEXT); + SDL_Surface* type_text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, type_str, COLOR_LIGHT_TEXT); SDL_BlitSurface(type_text, NULL, screen, &(SDL_Rect){ center_x - type_text->w / 2, content_y }); @@ -488,7 +488,7 @@ static int OptionAchievements_showDetail(MenuList* list, int i) { // Muted status below other info with gap before title if (is_muted) { - SDL_Surface* mute_text = TTF_RenderUTF8_Blended(font.tiny, "Muted - progress notifications silenced", COLOR_LIGHT_TEXT); + SDL_Surface* mute_text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, "Muted - progress notifications silenced", COLOR_LIGHT_TEXT); int mute_icon_w = SCALE1(10); int mute_icon_h = SCALE1(12); int total_w = mute_icon_w + SCALE1(4) + mute_text->w; @@ -728,7 +728,7 @@ static int OptionAchievements_openMenu(MenuList* list, int i) { // Status text at top, aligned with hardware pill (not part of centered content) char status_text[64]; snprintf(status_text, sizeof(status_text), "%u/%u unlocked", unlocked, total); - SDL_Surface* status_surface = TTF_RenderUTF8_Blended(font.tiny, status_text, COLOR_WHITE); + SDL_Surface* status_surface = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, status_text, COLOR_WHITE); SDL_BlitSurface(status_surface, NULL, screen, &(SDL_Rect){ (screen->w - status_surface->w) / 2, SCALE1(PADDING) + (SCALE1(PILL_SIZE) - status_surface->h) / 2 // Vertically centered with pill @@ -763,7 +763,7 @@ static int OptionAchievements_openMenu(MenuList* list, int i) { } // Draw ">" on the right side (always white) - SDL_Surface* arrow = TTF_RenderUTF8_Blended(font.small, ">", COLOR_WHITE); + SDL_Surface* arrow = TTF_RenderUTF8_Blended(GFX_getFonts()->small, ">", COLOR_WHITE); SDL_BlitSurface(arrow, NULL, screen, &(SDL_Rect){ ox + mw - arrow->w - opt_pad, oy + SCALE1((row * BUTTON_SIZE) + 3) @@ -775,7 +775,7 @@ static int OptionAchievements_openMenu(MenuList* list, int i) { // Calculate width needed for: badge + spacing + [mute icon] + [wifi icon] + title + padding int badge_display_size = SCALE1(BUTTON_SIZE - 4); // Badge sized to fit in row int title_width = 0; - TTF_SizeUTF8(font.small, ach->title, &title_width, NULL); + TTF_SizeUTF8(GFX_getFonts()->small, ach->title, &title_width, NULL); int mute_width = 0; if (is_muted) { mute_width = SCALE1(10) + SCALE1(4); // volume-mute icon + gap @@ -825,7 +825,7 @@ static int OptionAchievements_openMenu(MenuList* list, int i) { } // Title text - SDL_Surface* title_text = TTF_RenderUTF8_Blended(font.small, ach->title, text_color); + SDL_Surface* title_text = TTF_RenderUTF8_Blended(GFX_getFonts()->small, ach->title, text_color); SDL_BlitSurface(title_text, NULL, screen, &(SDL_Rect){ text_x, oy + SCALE1((row * BUTTON_SIZE) + 1) @@ -869,7 +869,7 @@ static int OptionAchievements_openMenu(MenuList* list, int i) { } // Title text (white for unselected) - SDL_Surface* title_text = TTF_RenderUTF8_Blended(font.small, ach->title, COLOR_WHITE); + SDL_Surface* title_text = TTF_RenderUTF8_Blended(GFX_getFonts()->small, ach->title, COLOR_WHITE); SDL_BlitSurface(title_text, NULL, screen, &(SDL_Rect){ text_x, oy + SCALE1((row * BUTTON_SIZE) + 1) @@ -1181,7 +1181,7 @@ int Menu_options(MenuList* list) { for (int i=0; iname, &w, NULL); + TTF_SizeUTF8(GFX_getFonts()->small, item->name, &w, NULL); w += SCALE1(OPTION_PADDING*2); if (w>mw) mw = w; } @@ -1199,7 +1199,7 @@ int Menu_options(MenuList* list) { if (j==selected_row) { // move out of conditional if centering int w = 0; - TTF_SizeUTF8(font.small, item->name, &w, NULL); + TTF_SizeUTF8(GFX_getFonts()->small, item->name, &w, NULL); w += SCALE1(OPTION_PADDING*2); GFX_blitPillDark(ASSET_BUTTON, screen, &(SDL_Rect){ @@ -1212,7 +1212,7 @@ int Menu_options(MenuList* list) { if (item->desc) desc = item->desc; } - text = TTF_RenderUTF8_Blended(font.small, item->name, text_color); + text = TTF_RenderUTF8_Blended(GFX_getFonts()->small, item->name, text_color); SDL_BlitSurface(text, NULL, screen, &(SDL_Rect){ ox+SCALE1(OPTION_PADDING), oy+SCALE1((j*BUTTON_SIZE)+1) @@ -1246,7 +1246,7 @@ int Menu_options(MenuList* list) { if (item->values == NULL) { // This is a navigation item, used to displayed a specific category - text = TTF_RenderUTF8_Blended(font.small, ">", COLOR_WHITE); // always white + text = TTF_RenderUTF8_Blended(GFX_getFonts()->small, ">", COLOR_WHITE); // always white SDL_BlitSurface(text, NULL, screen, &(SDL_Rect){ ox + mw - text->w - SCALE1(OPTION_PADDING), oy+SCALE1((j*BUTTON_SIZE)+3) @@ -1259,7 +1259,7 @@ int Menu_options(MenuList* list) { while ( item->values && item->values[count]) count++; if (item->value >= 0 && item->value < count) { const char *str = item->values[item->value]; - text = TTF_RenderUTF8_Blended(font.tiny, str ? str : "none", str ? COLOR_WHITE : COLOR_GRAY); // always white + text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, str ? str : "none", str ? COLOR_WHITE : COLOR_GRAY); // always white if (text) { SDL_BlitSurface(text, NULL, screen, &(SDL_Rect){ ox + mw - text->w - SCALE1(OPTION_PADDING), @@ -1275,7 +1275,7 @@ int Menu_options(MenuList* list) { if (j==selected_row) { // white pill int w = 0; - TTF_SizeUTF8(font.small, item->name, &w, NULL); + TTF_SizeUTF8(GFX_getFonts()->small, item->name, &w, NULL); w += SCALE1(OPTION_PADDING*2); GFX_blitPillDark(ASSET_BUTTON, screen, &(SDL_Rect){ ox, @@ -1287,7 +1287,7 @@ int Menu_options(MenuList* list) { if (item->desc) desc = item->desc; } - text = TTF_RenderUTF8_Blended(font.small, item->name, text_color); + text = TTF_RenderUTF8_Blended(GFX_getFonts()->small, item->name, text_color); SDL_BlitSurface(text, NULL, screen, &(SDL_Rect){ ox+SCALE1(OPTION_PADDING), oy+SCALE1((j*BUTTON_SIZE)+1) @@ -1305,13 +1305,13 @@ int Menu_options(MenuList* list) { int w = 0; int lw = 0; int rw = 0; - TTF_SizeUTF8(font.small, item->name, &lw, NULL); + TTF_SizeUTF8(GFX_getFonts()->small, item->name, &lw, NULL); // every value list in an input table is the same // so only calculate rw for the first item... if (!mrw || type!=MENU_INPUT) { if(item->values) { for (int j=0; item->values[j]; j++) { - TTF_SizeUTF8(font.tiny, item->values[j], &rw, NULL); + TTF_SizeUTF8(GFX_getFonts()->tiny, item->values[j], &rw, NULL); if (lw+rw>w) w = lw+rw; if (rw>mrw) mrw = rw; } @@ -1346,7 +1346,7 @@ int Menu_options(MenuList* list) { // white pill int w = 0; - TTF_SizeUTF8(font.small, item->name, &w, NULL); + TTF_SizeUTF8(GFX_getFonts()->small, item->name, &w, NULL); w += SCALE1(OPTION_PADDING*2); GFX_blitPillDark(ASSET_BUTTON, screen, &(SDL_Rect){ ox, @@ -1358,7 +1358,7 @@ int Menu_options(MenuList* list) { if (item->desc) desc = item->desc; } - text = TTF_RenderUTF8_Blended(font.small, item->name, text_color); + text = TTF_RenderUTF8_Blended(GFX_getFonts()->small, item->name, text_color); SDL_BlitSurface(text, NULL, screen, &(SDL_Rect){ ox+SCALE1(OPTION_PADDING), oy+SCALE1((j*BUTTON_SIZE)+1) @@ -1372,7 +1372,7 @@ int Menu_options(MenuList* list) { int count = 0; while ( item->values && item->values[count]) count++; if (item->value >= 0 && item->value < count) { - text = TTF_RenderUTF8_Blended(font.tiny, item->values[item->value], COLOR_WHITE); // always white + text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, item->values[item->value], COLOR_WHITE); // always white SDL_BlitSurface(text, NULL, screen, &(SDL_Rect){ ox + mw - text->w - SCALE1(OPTION_PADDING), oy+SCALE1((j*BUTTON_SIZE)+3) @@ -1396,8 +1396,8 @@ int Menu_options(MenuList* list) { if (desc) { int w,h; - GFX_sizeText(font.tiny, desc, SCALE1(12), &w,&h); - GFX_blitText(font.tiny, desc, SCALE1(12), COLOR_WHITE, screen, &(SDL_Rect){ + GFX_sizeText(GFX_getFonts()->tiny, desc, SCALE1(12), &w,&h); + GFX_blitText(GFX_getFonts()->tiny, desc, SCALE1(12), COLOR_WHITE, screen, &(SDL_Rect){ (screen->w - w) / 2, screen->h - SCALE1(PADDING) - h, w,h @@ -1909,11 +1909,11 @@ 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, SCALE1(BUTTON_PADDING*2)); + int text_width = GFX_truncateText(GFX_getFonts()->large, rom_name, display_name, max_width, SCALE1(BUTTON_PADDING*2)); max_width = MIN(max_width, text_width); SDL_Surface* text; - text = TTF_RenderUTF8_Blended(font.large, display_name, uintToColour(THEME_COLOR6_255)); + text = TTF_RenderUTF8_Blended(GFX_getFonts()->large, display_name, uintToColour(THEME_COLOR6_255)); GFX_blitPillLight(ASSET_WHITE_PILL, screen, &(SDL_Rect){ SCALE1(PADDING), SCALE1(PADDING), @@ -1952,7 +1952,7 @@ void Menu_loop(void) { screen->w - SCALE1(PADDING * 2), SCALE1(PILL_SIZE) }); - text = TTF_RenderUTF8_Blended(font.large, disc_name, text_color); + text = TTF_RenderUTF8_Blended(GFX_getFonts()->large, disc_name, text_color); SDL_BlitSurface(text, NULL, screen, &(SDL_Rect){ screen->w - SCALE1(PADDING + BUTTON_PADDING) - text->w, SCALE1(oy + PADDING + 4) @@ -1960,7 +1960,7 @@ void Menu_loop(void) { SDL_FreeSurface(text); } - TTF_SizeUTF8(font.large, item, &ow, NULL); + TTF_SizeUTF8(GFX_getFonts()->large, item, &ow, NULL); ow += SCALE1(BUTTON_PADDING*2); // pill @@ -1974,7 +1974,7 @@ void Menu_loop(void) { // text - text = TTF_RenderUTF8_Blended(font.large, item, text_color); + text = TTF_RenderUTF8_Blended(GFX_getFonts()->large, item, text_color); SDL_BlitSurface(text, NULL, screen, &(SDL_Rect){ SCALE1(PADDING + BUTTON_PADDING), SCALE1(oy + PADDING + (i * PILL_SIZE) + 4) @@ -2017,8 +2017,8 @@ void Menu_loop(void) { else { SDL_Rect preview_rect = {ox,oy,hw,hh}; SDL_FillRect(screen, &preview_rect, SDL_MapRGBA(screen->format,0,0,0,255)); - if (menu.save_exists) GFX_blitMessage(font.large, "No Preview", screen, &preview_rect); - else GFX_blitMessage(font.large, "Empty Slot", screen, &preview_rect); + if (menu.save_exists) GFX_blitMessage(GFX_getFonts()->large, "No Preview", screen, &preview_rect); + else GFX_blitMessage(GFX_getFonts()->large, "Empty Slot", screen, &preview_rect); } // pagination diff --git a/workspace/all/minarch/ma_options.c b/workspace/all/minarch/ma_options.c index 47fa24dd7..6775e6414 100644 --- a/workspace/all/minarch/ma_options.c +++ b/workspace/all/minarch/ma_options.c @@ -67,8 +67,8 @@ void OptionList_init(const struct retro_core_option_definition *defs) { strncpy(item->full, item->desc, len); // item->desc[len-1] = '\0'; - GFX_wrapText(font.tiny, item->desc, DEVICE_WIDTH - SCALE1(2*PADDING), 2); - GFX_wrapText(font.medium, item->full, DEVICE_WIDTH - SCALE1(2*PADDING), 16); + GFX_wrapText(GFX_getFonts()->tiny, item->desc, DEVICE_WIDTH - SCALE1(2*PADDING), 2); + GFX_wrapText(GFX_getFonts()->medium, item->full, DEVICE_WIDTH - SCALE1(2*PADDING), 16); } for (count=0; def->values[count].value; count++); @@ -151,8 +151,8 @@ void OptionList_v2_init(const struct retro_core_options_v2 *opt_defs) { item->desc = strdup(def->info); item->full = strdup(item->desc); - GFX_wrapText(font.tiny, item->desc, DEVICE_WIDTH - SCALE1(2*PADDING), 2); - GFX_wrapText(font.medium, item->full, DEVICE_WIDTH - SCALE1(2*PADDING), 16); + GFX_wrapText(GFX_getFonts()->tiny, item->desc, DEVICE_WIDTH - SCALE1(2*PADDING), 2); + GFX_wrapText(GFX_getFonts()->medium, item->full, DEVICE_WIDTH - SCALE1(2*PADDING), 16); } for (count=0; def->values[count].value; count++); diff --git a/workspace/all/minput/minput.c b/workspace/all/minput/minput.c index 8c06fef5b..3fb80626b 100644 --- a/workspace/all/minput/minput.c +++ b/workspace/all/minput/minput.c @@ -14,7 +14,7 @@ static int getButtonWidth(char* label) { if (strlen(label)<=2) w = SCALE1(BUTTON_SIZE); else { - text = TTF_RenderUTF8_Blended(font.tiny, label, COLOR_BUTTON_TEXT); + text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, label, COLOR_BUTTON_TEXT); w = SCALE1(BUTTON_SIZE) + text->w; SDL_FreeSurface(text); } @@ -27,12 +27,12 @@ static void blitButton(char* label, SDL_Surface* dst, int pressed, int x, int y, int len = strlen(label); if (len<=2) { - text = TTF_RenderUTF8_Blended(len==2?font.small:font.medium, label, COLOR_BUTTON_TEXT); + text = TTF_RenderUTF8_Blended(len==2?GFX_getFonts()->small:GFX_getFonts()->medium, label, COLOR_BUTTON_TEXT); GFX_blitAsset(pressed?ASSET_BUTTON:ASSET_HOLE, NULL, dst, &point); SDL_BlitSurface(text, NULL, dst, &(SDL_Rect){point.x+(SCALE1(BUTTON_SIZE)-text->w)/2,point.y+(SCALE1(BUTTON_SIZE)-text->h)/2}); } else { - text = TTF_RenderUTF8_Blended(font.tiny, label, COLOR_BUTTON_TEXT); + text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, label, COLOR_BUTTON_TEXT); w = w ? w : SCALE1(BUTTON_SIZE)/2+text->w; GFX_blitPill(pressed?ASSET_BUTTON:ASSET_HOLE, dst, &(SDL_Rect){point.x,point.y,w,SCALE1(BUTTON_SIZE)}); SDL_BlitSurface(text, NULL, dst, &(SDL_Rect){point.x+(w-text->w)/2,point.y+(SCALE1(BUTTON_SIZE)-text->h)/2,text->w,text->h}); @@ -230,7 +230,7 @@ int main(int argc , char* argv[]) { blitButton("START", screen, PAD_isPressed(BTN_START), x, y, w); x += w + SCALE1(BUTTON_MARGIN); - SDL_Surface* text = TTF_RenderUTF8_Blended(font.tiny, "QUIT", COLOR_LIGHT_TEXT); + SDL_Surface* text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, "QUIT", COLOR_LIGHT_TEXT); SDL_BlitSurface(text, NULL, screen, &(SDL_Rect){x,y+(SCALE1(BUTTON_SIZE)-text->h)/2}); SDL_FreeSurface(text); } diff --git a/workspace/all/nextui/nextui.cpp b/workspace/all/nextui/nextui.cpp index 1b58f1046..8db97dfea 100644 --- a/workspace/all/nextui/nextui.cpp +++ b/workspace/all/nextui/nextui.cpp @@ -1590,7 +1590,7 @@ static void updatePillTextSurface(const char* entry_name, int move_w, SDL_Color if (crop_w <= 0) return; SDL_LockMutex(fontMutex); - SDL_Surface* tmp = TTF_RenderUTF8_Blended(font.large, entry_name, text_color); + SDL_Surface* tmp = TTF_RenderUTF8_Blended(GFX_getFonts()->large, entry_name, text_color); SDL_UnlockMutex(fontMutex); if (!tmp) return; @@ -2365,9 +2365,9 @@ int main (int argc, char *argv[]) { } int w, h; - GFX_sizeText(font.tiny, item->name, SCALE1(FONT_TINY), &w, &h); + GFX_sizeText(GFX_getFonts()->tiny, item->name, SCALE1(FONT_TINY), &w, &h); SDL_Rect text_rect = {item_rect.x + (item_size - w) / 2, item_rect.y + item_size - h - SCALE1(BUTTON_MARGIN), w, h}; - GFX_blitText(font.tiny, item->name, SCALE1(FONT_TINY), text_color, screen, &text_rect); + GFX_blitText(GFX_getFonts()->tiny, item->name, SCALE1(FONT_TINY), text_color, screen, &text_rect); ox += item_rect.w + SCALE1(MENU_ITEM_MARGIN); } @@ -2444,13 +2444,13 @@ int main (int argc, char *argv[]) { int max_width = screen->w - SCALE1(PADDING * 2) - ow; char display_name[256]; - int text_width = GFX_truncateText(font.large, selectedEntry->name, display_name, max_width, SCALE1(BUTTON_PADDING*2)); + int text_width = GFX_truncateText(GFX_getFonts()->large, selectedEntry->name, display_name, max_width, SCALE1(BUTTON_PADDING*2)); max_width = MIN(max_width, text_width); SDL_Surface* text; SDL_Color textColor = uintToColour(THEME_COLOR6_255); SDL_LockMutex(fontMutex); - text = TTF_RenderUTF8_Blended(font.large, display_name, textColor); + text = TTF_RenderUTF8_Blended(GFX_getFonts()->large, display_name, textColor); SDL_UnlockMutex(fontMutex); const int text_offset_y = (SCALE1(PILL_SIZE) - text->h + 1) >> 1; SDL_Rect _pill_rect = { SCALE1(PADDING), SCALE1(PADDING), max_width, SCALE1(PILL_SIZE) }; @@ -2543,14 +2543,14 @@ int main (int argc, char *argv[]) { GFX_animateSurface(tmpsur,0-screen->w,0,0,0,screen->w,screen->h,CFG_getMenuTransitions() ? 80:20,0,255,LAYER_ALL); } SDL_FreeSurface(tmpsur); - GFX_blitMessage(font.large, "No Preview", screen, &preview_rect); + GFX_blitMessage(GFX_getFonts()->large, "No Preview", screen, &preview_rect); } Entry_free(selectedEntry); } else { SDL_Rect preview_rect = {ox,oy,screen->w,screen->h}; SDL_FillRect(screen, &preview_rect, 0); - GFX_blitMessage(font.large, "No Recents", screen, &preview_rect); + GFX_blitMessage(GFX_getFonts()->large, "No Recents", screen, &preview_rect); BTN_HINTS(1, screen, 1, "B","BACK", NULL); } @@ -2690,7 +2690,7 @@ int main (int argc, char *argv[]) { trimSortingMeta(&entry_unique); char display_name[256]; - int text_width = GFX_getTextWidth(font.large, entry_unique ? entry_unique : entry_name, display_name, available_width, SCALE1(BUTTON_PADDING * 2)); + int text_width = GFX_getTextWidth(GFX_getFonts()->large, entry_unique ? entry_unique : entry_name, display_name, available_width, SCALE1(BUTTON_PADDING * 2)); int max_width = MIN(available_width, text_width); // This spaghetti is preventing white text on white pill when volume/color temp is shown, @@ -2703,13 +2703,13 @@ int main (int argc, char *argv[]) { } SDL_LockMutex(fontMutex); - SDL_Surface* text = TTF_RenderUTF8_Blended(font.large, entry_name, text_color); - SDL_Surface* text_unique = TTF_RenderUTF8_Blended(font.large, display_name, COLOR_DARK_TEXT); + SDL_Surface* text = TTF_RenderUTF8_Blended(GFX_getFonts()->large, entry_name, text_color); + SDL_Surface* text_unique = TTF_RenderUTF8_Blended(GFX_getFonts()->large, display_name, COLOR_DARK_TEXT); SDL_UnlockMutex(fontMutex); // TODO: Use actual font metrics to center, this only works in simple cases const int text_offset_y = (SCALE1(PILL_SIZE) - text->h + 1) >> 1; if (row_is_selected) { - is_scrolling = list_show_entry_names && GFX_textShouldScroll(font.large,display_name, max_width - SCALE1(BUTTON_PADDING*2), fontMutex); + is_scrolling = list_show_entry_names && GFX_textShouldScroll(GFX_getFonts()->large,display_name, max_width - SCALE1(BUTTON_PADDING*2), fontMutex); GFX_resetScrollText(); bool should_animate = previous_depth == (int)stack.size(); SDL_LockMutex(animMutex); @@ -2765,7 +2765,7 @@ int main (int argc, char *argv[]) { } else { // TODO: for some reason screen's dimensions end up being 0x0 in GFX_blitMessage... - { SDL_Rect _r = {0,0,screen->w,screen->h}; GFX_blitMessage(font.large, "Empty folder", screen, &_r); } //, NULL); + { SDL_Rect _r = {0,0,screen->w,screen->h}; GFX_blitMessage(GFX_getFonts()->large, "Empty folder", screen, &_r); } //, NULL); } lastScreen = SCREEN_GAMELIST; @@ -2941,14 +2941,14 @@ int main (int argc, char *argv[]) { SDL_Color text_color = uintToColour(THEME_COLOR5_255); - int text_width = GFX_getTextWidth(font.large, entry_text, cached_display_name, available_width, SCALE1(BUTTON_PADDING * 2)); + int text_width = GFX_getTextWidth(GFX_getFonts()->large, entry_text, cached_display_name, available_width, SCALE1(BUTTON_PADDING * 2)); int max_width = MIN(available_width, text_width); - int text_offset_y = (SCALE1(PILL_SIZE) - TTF_FontHeight(font.large) + 1) >> 1; + int text_offset_y = (SCALE1(PILL_SIZE) - TTF_FontHeight(GFX_getFonts()->large) + 1) >> 1; GFX_clearLayers(LAYER_SCROLLTEXT); if (list_show_entry_names) { GFX_scrollTextTexture( - font.large, + GFX_getFonts()->large, entry_text, SCALE1(BUTTON_MARGIN + BUTTON_PADDING), SCALE1(PADDING + previous_row * PILL_SIZE) + text_offset_y, max_width - SCALE1(BUTTON_PADDING * 2), diff --git a/workspace/all/settings/btmenu.cpp b/workspace/all/settings/btmenu.cpp index 261971230..e2313a7ea 100644 --- a/workspace/all/settings/btmenu.cpp +++ b/workspace/all/settings/btmenu.cpp @@ -290,7 +290,7 @@ PairableItem::PairableItem(BT_device d, MenuList* submenu) void PairableItem::drawCustomItem(SDL_Surface *surface, const SDL_Rect &dst, const AbstractMenuItem &item, bool selected) const { SDL_Color text_color = uintToColour(THEME_COLOR4_255); - SDL_Surface *text = TTF_RenderUTF8_Blended(font.tiny, item.getLabel().c_str(), COLOR_WHITE); // always white + SDL_Surface *text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, item.getLabel().c_str(), COLOR_WHITE); // always white // hack - this should be correlated to max_width int mw = dst.w; @@ -315,13 +315,13 @@ void PairableItem::drawCustomItem(SDL_Surface *surface, const SDL_Rect &dst, con { // white pill int w = 0; - TTF_SizeUTF8(font.small, item.getName().c_str(), &w, NULL); + TTF_SizeUTF8(GFX_getFonts()->small, item.getName().c_str(), &w, NULL); w += SCALE1(OPTION_PADDING * 2); GFX_blitPillDarkCPP(ASSET_BUTTON, surface, {dst.x, dst.y, w, SCALE1(BUTTON_SIZE)}); text_color = uintToColour(THEME_COLOR5_255); } - text = TTF_RenderUTF8_Blended(font.small, item.getName().c_str(), text_color); + text = TTF_RenderUTF8_Blended(GFX_getFonts()->small, item.getName().c_str(), text_color); SDL_BlitSurfaceCPP(text, {}, surface, {dst.x + SCALE1(OPTION_PADDING), dst.y + SCALE1(1)}); SDL_FreeSurface(text); } @@ -333,7 +333,7 @@ PairedItem::PairedItem(BT_devicePaired d, MenuList* submenu) void PairedItem::drawCustomItem(SDL_Surface *surface, const SDL_Rect &dst, const AbstractMenuItem &item, bool selected) const { SDL_Color text_color = uintToColour(THEME_COLOR4_255); - SDL_Surface *text = TTF_RenderUTF8_Blended(font.tiny, item.getLabel().c_str(), COLOR_WHITE); // always white + SDL_Surface *text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, item.getLabel().c_str(), COLOR_WHITE); // always white // hack - this should be correlated to max_width int mw = dst.w; @@ -377,13 +377,13 @@ void PairedItem::drawCustomItem(SDL_Surface *surface, const SDL_Rect &dst, const { // white pill int w = 0; - TTF_SizeUTF8(font.small, item.getName().c_str(), &w, NULL); + TTF_SizeUTF8(GFX_getFonts()->small, item.getName().c_str(), &w, NULL); w += SCALE1(OPTION_PADDING * 2); GFX_blitPillDarkCPP(ASSET_BUTTON, surface, {dst.x, dst.y, w, SCALE1(BUTTON_SIZE)}); text_color = uintToColour(THEME_COLOR5_255); } - text = TTF_RenderUTF8_Blended(font.small, item.getName().c_str(), text_color); + text = TTF_RenderUTF8_Blended(GFX_getFonts()->small, item.getName().c_str(), text_color); SDL_BlitSurfaceCPP(text, {}, surface, {dst.x + SCALE1(OPTION_PADDING), dst.y + SCALE1(1)}); SDL_FreeSurface(text); } diff --git a/workspace/all/settings/colorpickermenu.cpp b/workspace/all/settings/colorpickermenu.cpp index 8d5e7f1ec..7f630721f 100644 --- a/workspace/all/settings/colorpickermenu.cpp +++ b/workspace/all/settings/colorpickermenu.cpp @@ -214,16 +214,16 @@ void ColorPickerMenu::drawSlider(SDL_Surface *surface, const SDL_Rect &row, int label_fixed_w; { int wr, wg, wb; - TTF_SizeUTF8(font.small, "R", &wr, nullptr); - TTF_SizeUTF8(font.small, "G", &wg, nullptr); - TTF_SizeUTF8(font.small, "B", &wb, nullptr); + TTF_SizeUTF8(GFX_getFonts()->small, "R", &wr, nullptr); + TTF_SizeUTF8(GFX_getFonts()->small, "G", &wg, nullptr); + TTF_SizeUTF8(GFX_getFonts()->small, "B", &wb, nullptr); label_fixed_w = std::max({wr, wg, wb}); } int hex_fixed_w; - TTF_SizeUTF8(font.tiny, "00", &hex_fixed_w, nullptr); + TTF_SizeUTF8(GFX_getFonts()->tiny, "00", &hex_fixed_w, nullptr); // Channel label ("R", "G", "B") — centered in fixed-width slot - SDL_Surface *label_surf = TTF_RenderUTF8_Blended(font.small, label, text_color); + SDL_Surface *label_surf = TTF_RenderUTF8_Blended(GFX_getFonts()->small, label, text_color); int label_x = row.x + SCALE1(OPTION_PADDING) + (label_fixed_w - label_surf->w) / 2; SDL_BlitSurfaceCPP(label_surf, {}, surface, {label_x, row.y + (row.h - label_surf->h) / 2}); @@ -232,7 +232,7 @@ void ColorPickerMenu::drawSlider(SDL_Surface *surface, const SDL_Rect &row, // Hex value right-aligned in fixed-width slot char hex_str[3]; snprintf(hex_str, sizeof(hex_str), "%02X", value); - SDL_Surface *hex_surf = TTF_RenderUTF8_Blended(font.tiny, hex_str, text_color); + SDL_Surface *hex_surf = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, hex_str, text_color); int hex_slot_x = row.x + row.w - SCALE1(OPTION_PADDING) - hex_fixed_w; SDL_BlitSurfaceCPP(hex_surf, {}, surface, {hex_slot_x + (hex_fixed_w - hex_surf->w), @@ -308,7 +308,7 @@ void ColorPickerMenu::drawPreset(SDL_Surface *surface, const SDL_Rect &row, // Hex value "#RRGGBB" char hex_str[8]; snprintf(hex_str, sizeof(hex_str), "#%06X", preset.color); - SDL_Surface *hex_surf = TTF_RenderUTF8_Blended(font.tiny, hex_str, text_color); + SDL_Surface *hex_surf = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, hex_str, text_color); int hex_x = sq_rect.x + sq + SCALE1(OPTION_PADDING / 2 + 2); SDL_BlitSurfaceCPP(hex_surf, {}, surface, {hex_x, row.y + (row.h - hex_surf->h) / 2}); @@ -316,7 +316,7 @@ void ColorPickerMenu::drawPreset(SDL_Surface *surface, const SDL_Rect &row, SDL_FreeSurface(hex_surf); // Name label - SDL_Surface *name_surf = TTF_RenderUTF8_Blended(font.tiny, preset.label.c_str(), text_color); + SDL_Surface *name_surf = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, preset.label.c_str(), text_color); SDL_BlitSurfaceCPP(name_surf, {}, surface, {hex_x + hex_w + SCALE1(OPTION_PADDING), row.y + (row.h - name_surf->h) / 2}); @@ -329,9 +329,9 @@ void ColorPickerMenu::drawCustom(SDL_Surface *surface, const SDL_Rect &dst, cons if(dstTitle.h > 0 && dstTitle.w > 0) { char display_name[256]; - GFX_truncateText(font.large, label_.c_str(), display_name, + GFX_truncateText(GFX_getFonts()->large, label_.c_str(), display_name, dstTitle.w, SCALE1(OPTION_PADDING * 2)); - SDL_Surface *title_text = TTF_RenderUTF8_Blended(font.large, display_name, uintToColour(THEME_COLOR4_255)); + SDL_Surface *title_text = TTF_RenderUTF8_Blended(GFX_getFonts()->large, display_name, uintToColour(THEME_COLOR4_255)); // hate the hardcoded +4, but we are matching MinUI code here SDL_BlitSurfaceCPP(title_text, {}, surface, {dstTitle.x + SCALE1(BUTTON_PADDING), dstTitle.y + 4, dstTitle.w - SCALE1(BUTTON_PADDING * 2), title_text->h}); SDL_FreeSurface(title_text); diff --git a/workspace/all/settings/keyboardprompt.cpp b/workspace/all/settings/keyboardprompt.cpp index 161af210e..19afef7f1 100644 --- a/workspace/all/settings/keyboardprompt.cpp +++ b/workspace/all/settings/keyboardprompt.cpp @@ -321,7 +321,7 @@ void KeyboardPrompt::drawKeyboard(SDL_Surface *screen, const AppState &state) // draw keyboard title if (!state.keyboard.title.empty()) { - SDL_Surface *title = TTF_RenderUTF8_Blended(font.large, state.keyboard.title.c_str(), COLOR_WHITE); + SDL_Surface *title = TTF_RenderUTF8_Blended(GFX_getFonts()->large, state.keyboard.title.c_str(), COLOR_WHITE); SDL_Rect title_pos = { (screen->w - title->w) / 2, // center horizontally 20, // 20px from top @@ -333,8 +333,8 @@ void KeyboardPrompt::drawKeyboard(SDL_Surface *screen, const AppState &state) // draw input field with current text // todo: use TTF_SizeUTF8 to compute the width of the input field - SDL_Surface *input_placeholder = TTF_RenderUTF8_Blended(font.medium, "p", COLOR_WHITE); - SDL_Surface *input = TTF_RenderUTF8_Blended(font.medium, state.keyboard.current_text.c_str(), COLOR_WHITE); + SDL_Surface *input_placeholder = TTF_RenderUTF8_Blended(GFX_getFonts()->medium, "p", COLOR_WHITE); + SDL_Surface *input = TTF_RenderUTF8_Blended(GFX_getFonts()->medium, state.keyboard.current_text.c_str(), COLOR_WHITE); SDL_Rect input_pos = { (screen->w) / 2, input_placeholder->h * 2, @@ -372,9 +372,9 @@ void KeyboardPrompt::drawKeyboard(SDL_Surface *screen, const AppState &state) // so we need to compute their width separately // compute them here to avoid doing it conditionally for each row int shift_width, space_width, enter_width; - TTF_SizeUTF8(font.medium, "shift", &shift_width, NULL); - TTF_SizeUTF8(font.medium, "space", &space_width, NULL); - TTF_SizeUTF8(font.medium, "enter", &enter_width, NULL); + TTF_SizeUTF8(GFX_getFonts()->medium, "shift", &shift_width, NULL); + TTF_SizeUTF8(GFX_getFonts()->medium, "space", &space_width, NULL); + TTF_SizeUTF8(GFX_getFonts()->medium, "enter", &enter_width, NULL); int special_key_width = std::max(shift_width, std::max(space_width, enter_width)) + (column_spacing * 4); for (int row = 0; row < num_rows; row++) @@ -409,7 +409,7 @@ void KeyboardPrompt::drawKeyboard(SDL_Surface *screen, const AppState &state) continue; SDL_Color text_color = (row == state.keyboard.row && col == state.keyboard.col) ? COLOR_BLACK : COLOR_WHITE; - SDL_Surface *key_text = TTF_RenderUTF8_Blended(font.medium, key.c_str(), text_color); + SDL_Surface *key_text = TTF_RenderUTF8_Blended(GFX_getFonts()->medium, key.c_str(), text_color); // special keys are not the same width as the other keys // so we need to compute their width separately diff --git a/workspace/all/settings/menu.cpp b/workspace/all/settings/menu.cpp index ab5915b03..5ddb1061a 100644 --- a/workspace/all/settings/menu.cpp +++ b/workspace/all/settings/menu.cpp @@ -497,7 +497,7 @@ SDL_Rect MenuList::itemSizeHint(const AbstractMenuItem &item) { // calculate the size of the list int w = 0; - TTF_SizeUTF8(font.small, item.getName().c_str(), &w, NULL); + TTF_SizeUTF8(GFX_getFonts()->small, item.getName().c_str(), &w, NULL); w += SCALE1(OPTION_PADDING * 2); return {0, 0, w, SCALE1(PILL_SIZE)}; } @@ -506,7 +506,7 @@ SDL_Rect MenuList::itemSizeHint(const AbstractMenuItem &item) int w = 0; int lw = 0; int rw = 0; - TTF_SizeUTF8(font.small, item.getName().c_str(), &lw, NULL); + TTF_SizeUTF8(GFX_getFonts()->small, item.getName().c_str(), &lw, NULL); // get the width of the widest row int mrw = 0; // every value list in an input table is the same @@ -515,7 +515,7 @@ SDL_Rect MenuList::itemSizeHint(const AbstractMenuItem &item) { for (int j = 0; item.getValues().size() > j && !item.getLabels()[j].empty(); j++) { - TTF_SizeUTF8(font.tiny, item.getLabels()[j].c_str(), &rw, NULL); + TTF_SizeUTF8(GFX_getFonts()->tiny, item.getLabels()[j].c_str(), &rw, NULL); if (lw + rw > w) w = lw + rw; if (rw > mrw) @@ -532,7 +532,7 @@ SDL_Rect MenuList::itemSizeHint(const AbstractMenuItem &item) else if (type == MenuItemType::Main) { int w = 0; - TTF_SizeUTF8(font.large, item.getName().c_str(), &w, NULL); + TTF_SizeUTF8(GFX_getFonts()->large, item.getName().c_str(), &w, NULL); w += SCALE1(BUTTON_PADDING * 2); return {0, 0, w, SCALE1(PILL_SIZE)}; } @@ -600,8 +600,8 @@ void MenuList::draw(SDL_Surface *surface, const SDL_Rect &dst, const SDL_Rect &d { int w, h; const auto description = cur->getDesc(); - GFX_sizeText(font.tiny, description.c_str(), SCALE1(FONT_SMALL), &w, &h); - GFX_blitTextCPP(font.tiny, description.c_str(), SCALE1(FONT_SMALL), uintToColour(THEME_COLOR4_255), surface, {(dst.x + dst.w - w) / 2, dst.y + dst.h - h, w, h}); + GFX_sizeText(GFX_getFonts()->tiny, description.c_str(), SCALE1(FONT_SMALL), &w, &h); + GFX_blitTextCPP(GFX_getFonts()->tiny, description.c_str(), SCALE1(FONT_SMALL), uintToColour(THEME_COLOR4_255), surface, {(dst.x + dst.w - w) / 2, dst.y + dst.h - h, w, h}); } } @@ -651,13 +651,13 @@ void MenuList::drawListItem(SDL_Surface *surface, const SDL_Rect &dst, const Abs { // move out of conditional if centering int w = 0; - TTF_SizeUTF8(font.small, item.getName().c_str(), &w, NULL); + TTF_SizeUTF8(GFX_getFonts()->small, item.getName().c_str(), &w, NULL); w += SCALE1(OPTION_PADDING * 2); GFX_blitPillDarkCPP(ASSET_BUTTON, surface, {dst.x, dst.y, w, SCALE1(BUTTON_SIZE)}); text_color = uintToColour(THEME_COLOR5_255); } - text = TTF_RenderUTF8_Blended(font.small, item.getName().c_str(), text_color); + text = TTF_RenderUTF8_Blended(GFX_getFonts()->small, item.getName().c_str(), text_color); SDL_BlitSurfaceCPP(text, {}, surface, {dst.x + SCALE1(OPTION_PADDING), dst.y + ((dst.h - text->h) / 2)}); SDL_FreeSurface(text); } @@ -716,7 +716,7 @@ void MenuList::drawFixedItem(SDL_Surface *surface, const SDL_Rect &dst, const Ab if (item.getValue().has_value()) { - text = TTF_RenderUTF8_Blended(font.tiny, item.getLabel().c_str(), text_color_value); + text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, item.getLabel().c_str(), text_color_value); if (item.getType() == ListItemType::Color) { @@ -741,7 +741,7 @@ void MenuList::drawFixedItem(SDL_Surface *surface, const SDL_Rect &dst, const Ab SDL_FreeSurface(text); char hexLabel[12]; snprintf(hexLabel, sizeof(hexLabel), "0x%06X", rawColor); - text = TTF_RenderUTF8_Blended(font.tiny, hexLabel, text_color_value); + text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, hexLabel, text_color_value); SDL_BlitSurfaceCPP(text, {}, surface, {dst.x + mw - text->w - SCALE1(OPTION_PADDING + COLOR_PADDING + FONT_TINY), dst.y + ((dst.h - text->h) / 2)}); } else if(item.getType() == ListItemType::Button) { @@ -760,13 +760,13 @@ void MenuList::drawFixedItem(SDL_Surface *surface, const SDL_Rect &dst, const Ab { // white pill int w = 0; - TTF_SizeUTF8(font.small, item.getName().c_str(), &w, NULL); + TTF_SizeUTF8(GFX_getFonts()->small, item.getName().c_str(), &w, NULL); w += SCALE1(OPTION_PADDING * 2); GFX_blitPillDarkCPP(ASSET_BUTTON, surface, {dst.x, dst.y, w, SCALE1(BUTTON_SIZE)}); text_color = uintToColour(THEME_COLOR5_255); } - text = TTF_RenderUTF8_Blended(font.small, item.getName().c_str(), text_color); + text = TTF_RenderUTF8_Blended(GFX_getFonts()->small, item.getName().c_str(), text_color); SDL_BlitSurfaceCPP(text, {}, surface, {dst.x + SCALE1(OPTION_PADDING), dst.y + ((dst.h - text->h) / 2)}); SDL_FreeSurface(text); } @@ -816,12 +816,12 @@ void MenuList::drawInputItem(SDL_Surface *surface, const SDL_Rect &dst, const Ab // white pill int w = 0; - TTF_SizeUTF8(font.small, item.getName().c_str(), &w, NULL); + TTF_SizeUTF8(GFX_getFonts()->small, item.getName().c_str(), &w, NULL); w += SCALE1(OPTION_PADDING * 2); GFX_blitPillDarkCPP(ASSET_BUTTON, surface, {dst.x, dst.y, w, SCALE1(BUTTON_SIZE)}); text_color = COLOR_BLACK; } - text = TTF_RenderUTF8_Blended(font.small, item.getName().c_str(), text_color); + text = TTF_RenderUTF8_Blended(GFX_getFonts()->small, item.getName().c_str(), text_color); SDL_BlitSurfaceCPP(text, {}, surface, {dst.x + SCALE1(OPTION_PADDING), dst.y + ((dst.h - text->h) / 2)}); SDL_FreeSurface(text); @@ -831,7 +831,7 @@ void MenuList::drawInputItem(SDL_Surface *surface, const SDL_Rect &dst, const Ab } else if (item.getValue().has_value()) { - text = TTF_RenderUTF8_Blended(font.tiny, item.getLabel().c_str(), COLOR_WHITE); // always white + text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, item.getLabel().c_str(), COLOR_WHITE); // always white SDL_BlitSurfaceCPP(text, {}, surface, {dst.x + mw - text->w - SCALE1(OPTION_PADDING), dst.y + ((dst.h - text->h) / 2)}); SDL_FreeSurface(text); } @@ -858,7 +858,7 @@ void MenuList::drawMain(SDL_Surface *surface, const SDL_Rect &dst, const SDL_Rec } else { - GFX_blitMessageCPP(font.large, "Empty folder", surface, dst); + GFX_blitMessageCPP(GFX_getFonts()->large, "Empty folder", surface, dst); } } @@ -871,7 +871,7 @@ void MenuList::drawMainItem(SDL_Surface *surface, const SDL_Rect &dst, const Abs const bool unique = false; char truncated[256]; - int text_width = GFX_truncateText(font.large, item.getName().c_str(), truncated, dst.w, SCALE1(BUTTON_PADDING * 2)); + int text_width = GFX_truncateText(GFX_getFonts()->large, item.getName().c_str(), truncated, dst.w, SCALE1(BUTTON_PADDING * 2)); int max_width = std::min(dst.w, text_width); if (selected) @@ -883,7 +883,7 @@ void MenuList::drawMainItem(SDL_Surface *surface, const SDL_Rect &dst, const Abs { // TODO: port this over when needed. Its complete spaghetti code... } - text = TTF_RenderUTF8_Blended(font.large, truncated, text_color); + text = TTF_RenderUTF8_Blended(GFX_getFonts()->large, truncated, text_color); SDL_BlitSurfaceCPP(text, {}, surface, {dst.x + SCALE1(BUTTON_PADDING), dst.y + ((dst.h - text->h) / 2)}); SDL_FreeSurface(text); } @@ -954,7 +954,7 @@ static void drawOverlayLocal(SDL_Surface* screen) { SDL_Rect screenRect = {0, 0, screen->w, screen->h}; - GFX_blitMessageCPP(font.medium, overlayMessage, screen, screenRect); + GFX_blitMessageCPP(GFX_getFonts()->medium, overlayMessage, screen, screenRect); if (overlayDismissMode != OverlayDismissMode::None) { if (overlayDismissMode == OverlayDismissMode::DismissOnB) { diff --git a/workspace/all/settings/settings.cpp b/workspace/all/settings/settings.cpp index f40153e1c..ba6a804ca 100644 --- a/workspace/all/settings/settings.cpp +++ b/workspace/all/settings/settings.cpp @@ -1108,11 +1108,11 @@ int main(int argc, char *argv[]) if (ctx.appManagesTitle) { char display_name[256]; - int text_width = GFX_truncateText(font.large, "Some title", display_name, max_width, SCALE1(BUTTON_PADDING * 2)); + int text_width = GFX_truncateText(GFX_getFonts()->large, "Some title", display_name, max_width, SCALE1(BUTTON_PADDING * 2)); max_width = MIN(max_width, text_width); SDL_Surface *text; - text = TTF_RenderUTF8_Blended(font.large, display_name, COLOR_WHITE); + text = TTF_RenderUTF8_Blended(GFX_getFonts()->large, display_name, COLOR_WHITE); SDL_Rect target = {SCALE1(PADDING), SCALE1(PADDING), max_width, SCALE1(PILL_SIZE)}; GFX_blitPillLight(ASSET_WHITE_PILL, ctx.screen, &target); SDL_BlitSurfaceCPP(text, {0, 0, max_width - SCALE1(BUTTON_PADDING * 2), text->h}, ctx.screen, {SCALE1(PADDING + BUTTON_PADDING), SCALE1(PADDING + 4)}); diff --git a/workspace/all/settings/wifimenu.cpp b/workspace/all/settings/wifimenu.cpp index 46f476c0f..071a8eb19 100644 --- a/workspace/all/settings/wifimenu.cpp +++ b/workspace/all/settings/wifimenu.cpp @@ -240,7 +240,7 @@ NetworkItem::NetworkItem(WIFI_network n, bool connected, MenuList* submenu) void NetworkItem::drawCustomItem(SDL_Surface *surface, const SDL_Rect &dst, const AbstractMenuItem &item, bool selected) const { SDL_Color text_color = uintToColour(THEME_COLOR4_255); - SDL_Surface *text = TTF_RenderUTF8_Blended(font.tiny, item.getLabel().c_str(), COLOR_WHITE); // always white + SDL_Surface *text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, item.getLabel().c_str(), COLOR_WHITE); // always white // hack - this should be correlated to max_width int mw = dst.w; @@ -283,13 +283,13 @@ void NetworkItem::drawCustomItem(SDL_Surface *surface, const SDL_Rect &dst, cons { // white pill int w = 0; - TTF_SizeUTF8(font.small, item.getName().c_str(), &w, NULL); + TTF_SizeUTF8(GFX_getFonts()->small, item.getName().c_str(), &w, NULL); w += SCALE1(OPTION_PADDING * 2); GFX_blitPillDarkCPP(ASSET_BUTTON, surface, {dst.x, dst.y, w, SCALE1(BUTTON_SIZE)}); text_color = uintToColour(THEME_COLOR5_255); } - text = TTF_RenderUTF8_Blended(font.small, item.getName().c_str(), text_color); + text = TTF_RenderUTF8_Blended(GFX_getFonts()->small, item.getName().c_str(), text_color); SDL_BlitSurfaceCPP(text, {}, surface, {dst.x + SCALE1(OPTION_PADDING), dst.y + SCALE1(1)}); SDL_FreeSurface(text); } \ No newline at end of file From 6c928b27e2de2db926aa3f6a4267dff4dee6f43e Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Thu, 2 Jul 2026 15:30:14 +0200 Subject: [PATCH 31/77] api: encapsulate the pad god-object behind PAD_getContext() `pad` was another bare extern on the facade. Make it `static` in api.c and expose PAD_getContext(); the only external reader is minarch's analog-axis path in ma_input.c (4 sites), converted to PAD_getContext()->laxis/raxis. Everything else already goes through the PAD_* facade. Semantic no-op -- accessor returns &pad; all binaries build clean and the launcher boots stable on the Brick with no crash cores. --- workspace/all/common/api.c | 3 ++- workspace/all/common/api.h | 4 +++- workspace/all/minarch/ma_input.c | 8 ++++---- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/workspace/all/common/api.c b/workspace/all/common/api.c index 1d8854264..df57145eb 100644 --- a/workspace/all/common/api.c +++ b/workspace/all/common/api.c @@ -2938,7 +2938,8 @@ FALLBACK_IMPLEMENTATION int PLAT_lidChanged(int *state) { return 0; } /////////////////////////////// -PAD_Context pad; +static PAD_Context pad; +PAD_Context* PAD_getContext(void) { return &pad; } #define AXIS_DEADZONE 0x4000 void PAD_setAnalog(int neg_id, int pos_id, int value, int repeat_at) diff --git a/workspace/all/common/api.h b/workspace/all/common/api.h index d937955bf..200021cfe 100644 --- a/workspace/all/common/api.h +++ b/workspace/all/common/api.h @@ -464,7 +464,9 @@ typedef struct PAD_Context { PAD_Axis laxis; PAD_Axis raxis; } PAD_Context; -extern PAD_Context pad; +// The pad state lives inside api.c; reach it through this accessor rather than +// a bare extern global. Most consumers should use the PAD_* facade instead. +PAD_Context* PAD_getContext(void); #define PAD_REPEAT_DELAY 300 #define PAD_REPEAT_INTERVAL 100 diff --git a/workspace/all/minarch/ma_input.c b/workspace/all/minarch/ma_input.c index 3233b214d..0e4cf1f4a 100644 --- a/workspace/all/minarch/ma_input.c +++ b/workspace/all/minarch/ma_input.c @@ -224,12 +224,12 @@ int16_t input_state_callback(unsigned port, unsigned device, unsigned index, uns } else if (port==0 && device==RETRO_DEVICE_ANALOG) { if (index==RETRO_DEVICE_INDEX_ANALOG_LEFT) { - if (id==RETRO_DEVICE_ID_ANALOG_X) return pad.laxis.x; - else if (id==RETRO_DEVICE_ID_ANALOG_Y) return pad.laxis.y; + if (id==RETRO_DEVICE_ID_ANALOG_X) return PAD_getContext()->laxis.x; + else if (id==RETRO_DEVICE_ID_ANALOG_Y) return PAD_getContext()->laxis.y; } else if (index==RETRO_DEVICE_INDEX_ANALOG_RIGHT) { - if (id==RETRO_DEVICE_ID_ANALOG_X) return pad.raxis.x; - else if (id==RETRO_DEVICE_ID_ANALOG_Y) return pad.raxis.y; + if (id==RETRO_DEVICE_ID_ANALOG_X) return PAD_getContext()->raxis.x; + else if (id==RETRO_DEVICE_ID_ANALOG_Y) return PAD_getContext()->raxis.y; } } return 0; From 6f20913589c69914a6c6852bfc8e3833e8dbde44 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Thu, 2 Jul 2026 15:36:45 +0200 Subject: [PATCH 32/77] minarch: group rewind config into a RewindConfig struct First cut at ma_internal.h's flat global soup (~54 externs). The six rewind_cfg_* ints are one cohesive unit -- fold them into a RewindConfig struct (rewind_cfg.enable/buffer_mb/granularity/audio/compress/ lz4_acceleration) declared once in ma_internal.h, defined with designated initializers in minarch.c, and referenced from ma_rewind.c / ma_config.c. rewind_init_ready stays separate (it's a runtime gate, not config). Mechanical, same values and reads -- no behaviour change. minarch builds clean. Worth an in-game rewind check since it touches the cfg-load and Rewind_init paths. --- workspace/all/minarch/ma_config.c | 12 ++++++------ workspace/all/minarch/ma_internal.h | 16 ++++++++++------ workspace/all/minarch/ma_rewind.c | 12 ++++++------ workspace/all/minarch/minarch.c | 14 ++++++++------ 4 files changed, 30 insertions(+), 24 deletions(-) diff --git a/workspace/all/minarch/ma_config.c b/workspace/all/minarch/ma_config.c index e82b727fb..367940ef1 100644 --- a/workspace/all/minarch/ma_config.c +++ b/workspace/all/minarch/ma_config.c @@ -178,12 +178,12 @@ void Config_syncFrontend(char* key, int value) { parsed = strtol(sval, NULL, 10); } switch (i) { - case FE_OPT_REWIND_ENABLE: rewind_cfg_enable = parsed; break; - case FE_OPT_REWIND_BUFFER: rewind_cfg_buffer_mb = parsed; break; - case FE_OPT_REWIND_GRANULARITY: rewind_cfg_granularity = parsed; break; - case FE_OPT_REWIND_AUDIO: rewind_cfg_audio = parsed; break; - case FE_OPT_REWIND_COMPRESSION: rewind_cfg_compress = parsed; break; - case FE_OPT_REWIND_COMPRESSION_ACCEL: rewind_cfg_lz4_acceleration = parsed; break; + case FE_OPT_REWIND_ENABLE: rewind_cfg.enable = parsed; break; + case FE_OPT_REWIND_BUFFER: rewind_cfg.buffer_mb = parsed; break; + case FE_OPT_REWIND_GRANULARITY: rewind_cfg.granularity = parsed; break; + case FE_OPT_REWIND_AUDIO: rewind_cfg.audio = parsed; break; + case FE_OPT_REWIND_COMPRESSION: rewind_cfg.compress = parsed; break; + case FE_OPT_REWIND_COMPRESSION_ACCEL: rewind_cfg.lz4_acceleration = parsed; break; } // Defer Rewind_init until after the explicit init in main(), otherwise FBN crashes if (rewind_init_ready) { diff --git a/workspace/all/minarch/ma_internal.h b/workspace/all/minarch/ma_internal.h index 28ffcaa57..729f14ed9 100644 --- a/workspace/all/minarch/ma_internal.h +++ b/workspace/all/minarch/ma_internal.h @@ -120,12 +120,16 @@ extern int sync_ref; extern int max_ff_speed; extern int overclock; -extern int rewind_cfg_enable; -extern int rewind_cfg_buffer_mb; -extern int rewind_cfg_granularity; -extern int rewind_cfg_audio; -extern int rewind_cfg_compress; -extern int rewind_cfg_lz4_acceleration; +// Rewind configuration, grouped out of the flat global soup. +typedef struct RewindConfig { + int enable; + int buffer_mb; + int granularity; + int audio; + int compress; + int lz4_acceleration; +} RewindConfig; +extern RewindConfig rewind_cfg; extern int rewind_init_ready; #include "ma_rewind.h" diff --git a/workspace/all/minarch/ma_rewind.c b/workspace/all/minarch/ma_rewind.c index 56bc5090f..e184deaa1 100644 --- a/workspace/all/minarch/ma_rewind.c +++ b/workspace/all/minarch/ma_rewind.c @@ -264,11 +264,11 @@ static int Rewind_compress_state(const uint8_t *src, size_t *dest_len, int *is_k int Rewind_init(size_t state_size) { Rewind_free(); // pull current option values directly - int enable = rewind_cfg_enable; - int buf_mb = rewind_cfg_buffer_mb; - int gran = rewind_cfg_granularity; - int audio = rewind_cfg_audio; - int compress = rewind_cfg_compress; + int enable = rewind_cfg.enable; + int buf_mb = rewind_cfg.buffer_mb; + int gran = rewind_cfg.granularity; + int audio = rewind_cfg.audio; + int compress = rewind_cfg.compress; if (!enable) { return 0; } @@ -289,7 +289,7 @@ int Rewind_init(size_t state_size) { state_size, rewind_ctx.capacity); rewind_ctx.compress = 1; } - int accel = rewind_cfg_lz4_acceleration; + int accel = rewind_cfg.lz4_acceleration; if (accel < 1) accel = 1; if (accel > REWIND_MAX_LZ4_ACCELERATION) accel = REWIND_MAX_LZ4_ACCELERATION; rewind_ctx.lz4_acceleration = accel; diff --git a/workspace/all/minarch/minarch.c b/workspace/all/minarch/minarch.c index 7285491b2..d1d2e2628 100644 --- a/workspace/all/minarch/minarch.c +++ b/workspace/all/minarch/minarch.c @@ -51,12 +51,14 @@ int ff_toggled = 0; int ff_hold_active = 0; int ff_paused_by_rewind_hold = 0; int rewinding = 0; -int rewind_cfg_enable = MINARCH_DEFAULT_REWIND_ENABLE; -int rewind_cfg_buffer_mb = MINARCH_DEFAULT_REWIND_BUFFER_MB; -int rewind_cfg_granularity = MINARCH_DEFAULT_REWIND_GRANULARITY; -int rewind_cfg_audio = MINARCH_DEFAULT_REWIND_AUDIO; -int rewind_cfg_compress = 1; -int rewind_cfg_lz4_acceleration = MINARCH_DEFAULT_REWIND_LZ4_ACCELERATION; +RewindConfig rewind_cfg = { + .enable = MINARCH_DEFAULT_REWIND_ENABLE, + .buffer_mb = MINARCH_DEFAULT_REWIND_BUFFER_MB, + .granularity = MINARCH_DEFAULT_REWIND_GRANULARITY, + .audio = MINARCH_DEFAULT_REWIND_AUDIO, + .compress = 1, + .lz4_acceleration = MINARCH_DEFAULT_REWIND_LZ4_ACCELERATION, +}; int rewind_init_ready = 0; // gate Rewind_init from syncFrontend until startup is past Core_load int overclock = 0; // auto int has_custom_controllers = 0; From cb5cc464b92a611d7fc2b1b60c2b1542ebfead9d Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Thu, 2 Jul 2026 16:06:39 +0200 Subject: [PATCH 33/77] minarch: group fast-forward flags into a FastForward struct Second ma_internal.h grouping. The five runtime fast-forward flags (fast_forward, ff_audio, ff_toggled, ff_hold_active, ff_paused_by_rewind_hold) become one FastForward struct: ff.active/audio/toggled/hold_active/ paused_by_rewind_hold. Verified each name was collision-free (no locals, no substring identifiers) before the bounded rename across the 7 ma_*.c files that use them. max_ff_speed stays separate -- it's config, not runtime state. Mechanical, same values/reads -- no behaviour change. minarch builds clean; the run-frame / audio / video hot paths that use these are exercised by any game running, and games launch/run/save fine. --- workspace/all/minarch/ma_audio.c | 8 +++--- workspace/all/minarch/ma_config.c | 4 +-- workspace/all/minarch/ma_input.c | 40 ++++++++++++++--------------- workspace/all/minarch/ma_internal.h | 15 +++++++---- workspace/all/minarch/ma_runframe.c | 20 +++++++-------- workspace/all/minarch/ma_saves.c | 12 ++++----- workspace/all/minarch/ma_video.c | 4 +-- workspace/all/minarch/minarch.c | 7 ++--- 8 files changed, 56 insertions(+), 54 deletions(-) diff --git a/workspace/all/minarch/ma_audio.c b/workspace/all/minarch/ma_audio.c index a8f66e765..88ba59021 100644 --- a/workspace/all/minarch/ma_audio.c +++ b/workspace/all/minarch/ma_audio.c @@ -33,8 +33,8 @@ void Audio_checkAndResetIfNeeded(void) { void audio_sample_callback(int16_t left, int16_t right) { if (rewinding && !rewind_ctx.audio) return; - if (!fast_forward || ff_audio) { - if (use_core_fps || fast_forward) { + if (!ff.active || ff.audio) { + if (use_core_fps || ff.active) { SND_batchSamples_fixed_rate(&(const SND_Frame){left,right}, 1); } else { @@ -45,8 +45,8 @@ void audio_sample_callback(int16_t left, int16_t right) { size_t audio_sample_batch_callback(const int16_t *data, size_t frames) { if (rewinding && !rewind_ctx.audio) return frames; - if (!fast_forward || ff_audio) { - if (use_core_fps || fast_forward) { + if (!ff.active || ff.audio) { + if (use_core_fps || ff.active) { return SND_batchSamples_fixed_rate((const SND_Frame*)data, frames); } else { diff --git a/workspace/all/minarch/ma_config.c b/workspace/all/minarch/ma_config.c index 367940ef1..fad8832fd 100644 --- a/workspace/all/minarch/ma_config.c +++ b/workspace/all/minarch/ma_config.c @@ -143,7 +143,7 @@ void Config_syncFrontend(char* key, int value) { i = FE_OPT_MAXFF; } else if (exactMatch(key,config.frontend.options[FE_OPT_FF_AUDIO].key)) { - ff_audio = value; + ff.audio = value; i = FE_OPT_FF_AUDIO; } else if (exactMatch(key,config.frontend.options[FE_OPT_REWIND_ENABLE].key)) { @@ -195,7 +195,7 @@ void Config_syncFrontend(char* key, int value) { rewind_pressed = 0; Rewind_sync_encode_state(); rewinding = 0; - ff_paused_by_rewind_hold = 0; + ff.paused_by_rewind_hold = 0; } } } diff --git a/workspace/all/minarch/ma_input.c b/workspace/all/minarch/ma_input.c index 0e4cf1f4a..d679ed30c 100644 --- a/workspace/all/minarch/ma_input.c +++ b/workspace/all/minarch/ma_input.c @@ -5,10 +5,10 @@ int setFastForward(int enable) { int val = enable ? 1 : 0; - if (fast_forward != val) { + if (ff.active != val) { LOG_info("FF state -> %i\n", val); } - fast_forward = val; + ff.active = val; return val; } @@ -53,10 +53,10 @@ void input_poll_callback(void) { if (!mapping->mod || PAD_isPressed(BTN_MENU)) { if (i==SHORTCUT_TOGGLE_FF) { if (PAD_justPressed(btn)) { - toggled_ff_on = setFastForward(!fast_forward); - ff_toggled = toggled_ff_on; - ff_hold_active = 0; - if (ff_toggled && rewind_toggle) { + toggled_ff_on = setFastForward(!ff.active); + ff.toggled = toggled_ff_on; + ff.hold_active = 0; + if (ff.toggled && rewind_toggle) { // last toggle wins: disable rewind toggle when FF toggle is enabled rewind_toggle = 0; rewind_pressed = 0; @@ -72,16 +72,16 @@ void input_poll_callback(void) { } } else if (i==SHORTCUT_HOLD_FF) { - // don't allow turn off fast_forward with a release of the hold button + // don't allow turn off ff.active with a release of the hold button // if it was initially turned on with the toggle button if (PAD_justPressed(btn) || (!toggled_ff_on && PAD_justReleased(btn))) { int pressed = PAD_isPressed(btn); - fast_forward = setFastForward(pressed); - ff_hold_active = pressed ? 1 : 0; + ff.active = setFastForward(pressed); + ff.hold_active = pressed ? 1 : 0; if (mapping->mod) ignore_menu = 1; // very unlikely but just in case } if (PAD_justReleased(btn) && toggled_ff_on) { - ff_hold_active = 0; + ff.hold_active = 0; } } else if (i==SHORTCUT_HOLD_REWIND) { @@ -90,24 +90,24 @@ void input_poll_callback(void) { LOG_info("Rewind hotkey %s\n", rewind_pressed ? "pressed" : "released"); last_rewind_pressed = rewind_pressed; } - if (rewind_pressed && ff_toggled && !ff_paused_by_rewind_hold) { - ff_paused_by_rewind_hold = 1; - fast_forward = setFastForward(0); + if (rewind_pressed && ff.toggled && !ff.paused_by_rewind_hold) { + ff.paused_by_rewind_hold = 1; + ff.active = setFastForward(0); } - else if (!rewind_pressed && ff_paused_by_rewind_hold) { - ff_paused_by_rewind_hold = 0; - if (ff_toggled) fast_forward = setFastForward(1); + else if (!rewind_pressed && ff.paused_by_rewind_hold) { + ff.paused_by_rewind_hold = 0; + if (ff.toggled) ff.active = setFastForward(1); } if (mapping->mod && rewind_pressed) ignore_menu = 1; } else if (i==SHORTCUT_TOGGLE_REWIND) { if (PAD_justPressed(btn)) { rewind_toggle = !rewind_toggle; - if (rewind_toggle && ff_toggled) { + if (rewind_toggle && ff.toggled) { // disable fast forward toggle when rewinding is toggled on - ff_toggled = 0; - fast_forward = setFastForward(0); - ff_paused_by_rewind_hold = 0; + ff.toggled = 0; + ff.active = setFastForward(0); + ff.paused_by_rewind_hold = 0; } if (mapping->mod) ignore_menu = 1; break; diff --git a/workspace/all/minarch/ma_internal.h b/workspace/all/minarch/ma_internal.h index 729f14ed9..7acd9bae0 100644 --- a/workspace/all/minarch/ma_internal.h +++ b/workspace/all/minarch/ma_internal.h @@ -89,15 +89,20 @@ extern SDL_Surface *screen; extern int quit; extern int show_menu; extern int newScreenshot; -extern int fast_forward; extern int rewinding; -extern int ff_audio; extern int use_core_fps; extern int rewind_pressed; extern int rewind_toggle; -extern int ff_toggled; -extern int ff_hold_active; -extern int ff_paused_by_rewind_hold; + +// Fast-forward runtime state, grouped out of the flat global soup. +typedef struct FastForward { + int active; // was fast_forward + int audio; // was ff_audio + int toggled; // was ff_toggled + int hold_active; // was ff_hold_active + int paused_by_rewind_hold; // was ff_paused_by_rewind_hold +} FastForward; +extern FastForward ff; extern int screen_scaling; extern int screen_effect; diff --git a/workspace/all/minarch/ma_runframe.c b/workspace/all/minarch/ma_runframe.c index 75984da90..cfb8d3675 100644 --- a/workspace/all/minarch/ma_runframe.c +++ b/workspace/all/minarch/ma_runframe.c @@ -28,7 +28,7 @@ static void limitFF(void) { } uint64_t now = getMicroseconds(); - if (fast_forward && max_ff_speed) { + if (ff.active && max_ff_speed) { if (last_time == 0) last_time = now; int elapsed = now - last_time; if (elapsed>0 && elapsed<0x80000) { @@ -47,20 +47,20 @@ static void limitFF(void) { void run_frame(void) { // if rewind is toggled, fast-forward toggle must stay off; fast-forward hold pauses rewind - int do_rewind = (rewind_pressed || rewind_toggle) && !(rewind_toggle && ff_hold_active); + int do_rewind = (rewind_pressed || rewind_toggle) && !(rewind_toggle && ff.hold_active); if (do_rewind) { int was_rewinding = rewinding; int rewind_result = Rewind_step_back(); if (rewind_result == REWIND_STEP_OK) { // Actually stepped back - run one frame to render the restored state rewinding = 1; - fast_forward = 0; + ff.active = 0; core.run(); } else if (rewind_result == REWIND_STEP_CADENCE) { // Waiting for cadence - don't run core, just re-render current frame rewinding = 1; - fast_forward = 0; + ff.active = 0; // Poll input manually since core.run() isn't called input_poll_callback(); // Skip core.run() entirely to avoid advancing the game @@ -75,9 +75,9 @@ void run_frame(void) { } else { // Buffer empty: auto untoggle rewind, resume FF if it was paused for a hold if (rewind_toggle) rewind_toggle = 0; - if (ff_paused_by_rewind_hold && ff_toggled) { - ff_paused_by_rewind_hold = 0; - fast_forward = setFastForward(1); + if (ff.paused_by_rewind_hold && ff.toggled) { + ff.paused_by_rewind_hold = 0; + ff.active = setFastForward(1); } if (was_rewinding) { rewinding = 1; @@ -92,10 +92,10 @@ void run_frame(void) { else { Rewind_sync_encode_state(); rewinding = 0; - if (ff_paused_by_rewind_hold && !rewind_pressed) { + if (ff.paused_by_rewind_hold && !rewind_pressed) { // resume fast forward after hold rewind ends - if (ff_toggled) fast_forward = setFastForward(1); - ff_paused_by_rewind_hold = 0; + if (ff.toggled) ff.active = setFastForward(1); + ff.paused_by_rewind_hold = 0; } core.run(); diff --git a/workspace/all/minarch/ma_saves.c b/workspace/all/minarch/ma_saves.c index c61c2ce40..18c9cb510 100644 --- a/workspace/all/minarch/ma_saves.c +++ b/workspace/all/minarch/ma_saves.c @@ -209,8 +209,8 @@ int State_read(void) { // from picoarch size_t state_size = core.serialize_size(); if (!state_size) return 0; - int was_ff = fast_forward; - fast_forward = 0; + int was_ff = ff.active; + ff.active = 0; void *state = calloc(1, state_size); if (!state) { @@ -297,7 +297,7 @@ int State_read(void) { // from picoarch if (state) free(state); if (state_file) fclose(state_file); #endif - fast_forward = was_ff; + ff.active = was_ff; return success; } @@ -313,8 +313,8 @@ int State_write(void) { // from picoarch size_t state_size = core.serialize_size(); if (!state_size) return 0; - int was_ff = fast_forward; - fast_forward = 0; + int was_ff = ff.active; + ff.active = 0; void *state = calloc(1, state_size); if (!state) { @@ -364,7 +364,7 @@ int State_write(void) { // from picoarch #endif sync(); - fast_forward = was_ff; + ff.active = was_ff; return success; } diff --git a/workspace/all/minarch/ma_video.c b/workspace/all/minarch/ma_video.c index 7dfa61dad..622e91525 100644 --- a/workspace/all/minarch/ma_video.c +++ b/workspace/all/minarch/ma_video.c @@ -746,7 +746,7 @@ static void video_refresh_callback_main(const void *data, unsigned width, unsign // 14 will let GB hit 10x but NES and SNES will drop to 1.5x at 30fps (not sure why) // but 10 hurts PS... // TODO: 10 was based on rg35xx, probably different results on other supported platforms - if (fast_forward && SDL_GetTicks()-last_flip_time<10) return; + if (ff.active && SDL_GetTicks()-last_flip_time<10) return; // FFVII menus // 16: 30/200 @@ -979,7 +979,7 @@ void video_refresh_callback(const void* data, unsigned width, unsigned height, s pitch = width * sizeof(Uint32); // Set ambient lighting color (if enabled) - if (ambient_mode && !fast_forward && data) { + if (ambient_mode && !ff.active && data) { GFX_setAmbientColor(data, width, height, pitch, ambient_mode); } diff --git a/workspace/all/minarch/minarch.c b/workspace/all/minarch/minarch.c index d1d2e2628..9fdc882bf 100644 --- a/workspace/all/minarch/minarch.c +++ b/workspace/all/minarch/minarch.c @@ -42,15 +42,12 @@ int use_core_fps = 0; int sync_ref = 0; int show_debug = 0; int max_ff_speed = 3; // 4x -int ff_audio = 0; -int fast_forward = 0; int rewind_pressed = 0; int rewind_toggle = 0; int last_rewind_pressed = 0; -int ff_toggled = 0; -int ff_hold_active = 0; -int ff_paused_by_rewind_hold = 0; int rewinding = 0; + +FastForward ff = {0}; RewindConfig rewind_cfg = { .enable = MINARCH_DEFAULT_REWIND_ENABLE, .buffer_mb = MINARCH_DEFAULT_REWIND_BUFFER_MB, From 17284ab7e3e7d4cc61cf5fdd0033aa5cb07a4ddd Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Thu, 2 Jul 2026 16:13:56 +0200 Subject: [PATCH 34/77] minarch: group rewind runtime flags into a RewindState struct Third ma_internal.h grouping, pairing with RewindConfig. The four runtime rewind flags (rewinding, rewind_pressed, rewind_toggle, last_rewind_pressed) become one RewindState struct: rewind_st.active/pressed/toggle/last_pressed. Collision-checked each name (no locals, no substring clashes -- \b protects last_rewind_pressed from the rewind_pressed rule) before the bounded rename across the 6 ma_*.c files that use them. Mechanical, same values/reads -- no behaviour change. minarch builds clean; this is the same rewind path already verified working on device. --- workspace/all/minarch/ma_audio.c | 4 ++-- workspace/all/minarch/ma_config.c | 8 ++++---- workspace/all/minarch/ma_input.c | 30 ++++++++++++++--------------- workspace/all/minarch/ma_internal.h | 14 ++++++++++---- workspace/all/minarch/ma_rewind.c | 14 +++++++------- workspace/all/minarch/ma_runframe.c | 22 ++++++++++----------- workspace/all/minarch/minarch.c | 5 +---- 7 files changed, 50 insertions(+), 47 deletions(-) diff --git a/workspace/all/minarch/ma_audio.c b/workspace/all/minarch/ma_audio.c index 88ba59021..44fb465d1 100644 --- a/workspace/all/minarch/ma_audio.c +++ b/workspace/all/minarch/ma_audio.c @@ -32,7 +32,7 @@ void Audio_checkAndResetIfNeeded(void) { } void audio_sample_callback(int16_t left, int16_t right) { - if (rewinding && !rewind_ctx.audio) return; + if (rewind_st.active && !rewind_ctx.audio) return; if (!ff.active || ff.audio) { if (use_core_fps || ff.active) { SND_batchSamples_fixed_rate(&(const SND_Frame){left,right}, 1); @@ -44,7 +44,7 @@ void audio_sample_callback(int16_t left, int16_t right) { } size_t audio_sample_batch_callback(const int16_t *data, size_t frames) { - if (rewinding && !rewind_ctx.audio) return frames; + if (rewind_st.active && !rewind_ctx.audio) return frames; if (!ff.active || ff.audio) { if (use_core_fps || ff.active) { return SND_batchSamples_fixed_rate((const SND_Frame*)data, frames); diff --git a/workspace/all/minarch/ma_config.c b/workspace/all/minarch/ma_config.c index fad8832fd..20d549422 100644 --- a/workspace/all/minarch/ma_config.c +++ b/workspace/all/minarch/ma_config.c @@ -191,10 +191,10 @@ void Config_syncFrontend(char* key, int value) { } if (i==FE_OPT_REWIND_ENABLE) { // ensure runtime toggles don't linger when enabling/disabling feature - rewind_toggle = 0; - rewind_pressed = 0; + rewind_st.toggle = 0; + rewind_st.pressed = 0; Rewind_sync_encode_state(); - rewinding = 0; + rewind_st.active = 0; ff.paused_by_rewind_hold = 0; } } @@ -1487,7 +1487,7 @@ struct Config config = { [FE_OPT_REWIND_AUDIO] = { .key = "minarch_rewind_audio", .name = "Rewind audio", - .desc = "Play or mute audio when rewinding.", + .desc = "Play or mute audio when rewind_st.active.", .default_value = MINARCH_DEFAULT_REWIND_AUDIO ? 1 : 0, .value = MINARCH_DEFAULT_REWIND_AUDIO ? 1 : 0, .count = 2, diff --git a/workspace/all/minarch/ma_input.c b/workspace/all/minarch/ma_input.c index d679ed30c..97cb7aa28 100644 --- a/workspace/all/minarch/ma_input.c +++ b/workspace/all/minarch/ma_input.c @@ -45,7 +45,7 @@ void input_poll_callback(void) { } static int toggled_ff_on = 0; // this logic only works because TOGGLE_FF is before HOLD_FF in the menu... - rewind_pressed = 0; + rewind_st.pressed = 0; for (int i=0; ilocal; @@ -56,12 +56,12 @@ void input_poll_callback(void) { toggled_ff_on = setFastForward(!ff.active); ff.toggled = toggled_ff_on; ff.hold_active = 0; - if (ff.toggled && rewind_toggle) { + if (ff.toggled && rewind_st.toggle) { // last toggle wins: disable rewind toggle when FF toggle is enabled - rewind_toggle = 0; - rewind_pressed = 0; + rewind_st.toggle = 0; + rewind_st.pressed = 0; Rewind_sync_encode_state(); - rewinding = 0; + rewind_st.active = 0; } if (mapping->mod) ignore_menu = 1; break; @@ -85,26 +85,26 @@ void input_poll_callback(void) { } } else if (i==SHORTCUT_HOLD_REWIND) { - rewind_pressed = PAD_isPressed(btn) ? 1 : 0; - if (rewind_pressed != last_rewind_pressed) { - LOG_info("Rewind hotkey %s\n", rewind_pressed ? "pressed" : "released"); - last_rewind_pressed = rewind_pressed; + rewind_st.pressed = PAD_isPressed(btn) ? 1 : 0; + if (rewind_st.pressed != rewind_st.last_pressed) { + LOG_info("Rewind hotkey %s\n", rewind_st.pressed ? "pressed" : "released"); + rewind_st.last_pressed = rewind_st.pressed; } - if (rewind_pressed && ff.toggled && !ff.paused_by_rewind_hold) { + if (rewind_st.pressed && ff.toggled && !ff.paused_by_rewind_hold) { ff.paused_by_rewind_hold = 1; ff.active = setFastForward(0); } - else if (!rewind_pressed && ff.paused_by_rewind_hold) { + else if (!rewind_st.pressed && ff.paused_by_rewind_hold) { ff.paused_by_rewind_hold = 0; if (ff.toggled) ff.active = setFastForward(1); } - if (mapping->mod && rewind_pressed) ignore_menu = 1; + if (mapping->mod && rewind_st.pressed) ignore_menu = 1; } else if (i==SHORTCUT_TOGGLE_REWIND) { if (PAD_justPressed(btn)) { - rewind_toggle = !rewind_toggle; - if (rewind_toggle && ff.toggled) { - // disable fast forward toggle when rewinding is toggled on + rewind_st.toggle = !rewind_st.toggle; + if (rewind_st.toggle && ff.toggled) { + // disable fast forward toggle when rewind_st.active is toggled on ff.toggled = 0; ff.active = setFastForward(0); ff.paused_by_rewind_hold = 0; diff --git a/workspace/all/minarch/ma_internal.h b/workspace/all/minarch/ma_internal.h index 7acd9bae0..4e9f30313 100644 --- a/workspace/all/minarch/ma_internal.h +++ b/workspace/all/minarch/ma_internal.h @@ -89,10 +89,17 @@ extern SDL_Surface *screen; extern int quit; extern int show_menu; extern int newScreenshot; -extern int rewinding; extern int use_core_fps; -extern int rewind_pressed; -extern int rewind_toggle; + +// Rewind runtime state, grouped out of the flat global soup (config lives in +// the RewindConfig struct). +typedef struct RewindState { + int active; // was rewinding + int pressed; // was rewind_pressed + int toggle; // was rewind_toggle + int last_pressed; // was last_rewind_pressed +} RewindState; +extern RewindState rewind_st; // Fast-forward runtime state, grouped out of the flat global soup. typedef struct FastForward { @@ -207,7 +214,6 @@ extern struct Config config; extern ButtonMapping default_button_mapping[]; extern ButtonMapping core_button_mapping[]; extern int gamepad_type; -extern int last_rewind_pressed; void Config_syncFrontend(char* key, int value); diff --git a/workspace/all/minarch/ma_rewind.c b/workspace/all/minarch/ma_rewind.c index e184deaa1..7cddefd96 100644 --- a/workspace/all/minarch/ma_rewind.c +++ b/workspace/all/minarch/ma_rewind.c @@ -62,7 +62,7 @@ void Rewind_free(void) { pthread_cond_destroy(&rewind_ctx.queue_cv); } memset(&rewind_ctx, 0, sizeof(rewind_ctx)); - rewinding = 0; + rewind_st.active = 0; } void Rewind_reset(void) { @@ -99,7 +99,7 @@ void Rewind_reset(void) { } pthread_mutex_unlock(&rewind_ctx.queue_mx); } - rewinding = 0; + rewind_st.active = 0; rewind_warn_empty = 0; } @@ -598,14 +598,14 @@ int Rewind_step_back(void) { uint32_t now_ms = SDL_GetTicks(); if (rewind_ctx.playback_interval_ms > 0 && rewind_ctx.last_step_ms && (int)(now_ms - rewind_ctx.last_step_ms) < rewind_ctx.playback_interval_ms) { - // still rewinding, just waiting for cadence; don't run core, just re-render + // still rewind_st.active, just waiting for cadence; don't run core, just re-render return REWIND_STEP_CADENCE; } // On first rewind step, we need to: // 1. Wait for any pending compression to finish (so entry indices are stable) // 2. Copy the last compressed state as our delta reference - if (!rewinding && rewind_ctx.compress && rewind_ctx.prev_state_dec) { + if (!rewind_st.active && rewind_ctx.compress && rewind_ctx.prev_state_dec) { // Wait for worker to finish all pending compressions Rewind_wait_for_worker_idle(); pthread_mutex_lock(&rewind_ctx.lock); @@ -708,7 +708,7 @@ int Rewind_step_back(void) { } pthread_mutex_unlock(&rewind_ctx.lock); - rewinding = 1; + rewind_st.active = 1; rewind_ctx.last_step_ms = now_ms; return REWIND_STEP_OK; } @@ -717,13 +717,13 @@ int Rewind_step_back(void) { // Also clears old entries that were compressed with a different delta chain void Rewind_sync_encode_state(void) { if (!rewind_ctx.enabled || !rewind_ctx.compress) return; - if (!rewinding) return; // Only sync if we were actually rewinding + if (!rewind_st.active) return; // Only sync if we were actually rewind_st.active pthread_mutex_lock(&rewind_ctx.lock); // The decoder's prev_state_dec contains the state we rewound to. // Use it as the new reference for future compressions so the existing - // rewind history remains valid and we can continue rewinding further back. + // rewind history remains valid and we can continue rewind_st.active further back. if (rewind_ctx.has_prev_dec && rewind_ctx.prev_state_dec && rewind_ctx.prev_state_enc) { memcpy(rewind_ctx.prev_state_enc, rewind_ctx.prev_state_dec, rewind_ctx.state_size); rewind_ctx.has_prev_enc = 1; diff --git a/workspace/all/minarch/ma_runframe.c b/workspace/all/minarch/ma_runframe.c index cfb8d3675..9a5d994ea 100644 --- a/workspace/all/minarch/ma_runframe.c +++ b/workspace/all/minarch/ma_runframe.c @@ -47,43 +47,43 @@ static void limitFF(void) { void run_frame(void) { // if rewind is toggled, fast-forward toggle must stay off; fast-forward hold pauses rewind - int do_rewind = (rewind_pressed || rewind_toggle) && !(rewind_toggle && ff.hold_active); + int do_rewind = (rewind_st.pressed || rewind_st.toggle) && !(rewind_st.toggle && ff.hold_active); if (do_rewind) { - int was_rewinding = rewinding; + int was_rewinding = rewind_st.active; int rewind_result = Rewind_step_back(); if (rewind_result == REWIND_STEP_OK) { // Actually stepped back - run one frame to render the restored state - rewinding = 1; + rewind_st.active = 1; ff.active = 0; core.run(); } else if (rewind_result == REWIND_STEP_CADENCE) { // Waiting for cadence - don't run core, just re-render current frame - rewinding = 1; + rewind_st.active = 1; ff.active = 0; // Poll input manually since core.run() isn't called input_poll_callback(); // Skip core.run() entirely to avoid advancing the game } else { - int hold_empty = rewind_ctx.enabled && rewind_pressed && !rewind_toggle; + int hold_empty = rewind_ctx.enabled && rewind_st.pressed && !rewind_st.toggle; if (hold_empty) { // Hold-to-rewind: freeze when empty to avoid advance/rewind oscillation. - rewinding = was_rewinding ? 1 : 0; + rewind_st.active = was_rewinding ? 1 : 0; // Poll input manually so release is detected while core.run() is skipped input_poll_callback(); } else { // Buffer empty: auto untoggle rewind, resume FF if it was paused for a hold - if (rewind_toggle) rewind_toggle = 0; + if (rewind_st.toggle) rewind_st.toggle = 0; if (ff.paused_by_rewind_hold && ff.toggled) { ff.paused_by_rewind_hold = 0; ff.active = setFastForward(1); } if (was_rewinding) { - rewinding = 1; + rewind_st.active = 1; Rewind_sync_encode_state(); } - rewinding = 0; + rewind_st.active = 0; core.run(); Rewind_push(0); } @@ -91,8 +91,8 @@ void run_frame(void) { } else { Rewind_sync_encode_state(); - rewinding = 0; - if (ff.paused_by_rewind_hold && !rewind_pressed) { + rewind_st.active = 0; + if (ff.paused_by_rewind_hold && !rewind_st.pressed) { // resume fast forward after hold rewind ends if (ff.toggled) ff.active = setFastForward(1); ff.paused_by_rewind_hold = 0; diff --git a/workspace/all/minarch/minarch.c b/workspace/all/minarch/minarch.c index 9fdc882bf..e216fbcc5 100644 --- a/workspace/all/minarch/minarch.c +++ b/workspace/all/minarch/minarch.c @@ -42,12 +42,9 @@ int use_core_fps = 0; int sync_ref = 0; int show_debug = 0; int max_ff_speed = 3; // 4x -int rewind_pressed = 0; -int rewind_toggle = 0; -int last_rewind_pressed = 0; -int rewinding = 0; FastForward ff = {0}; +RewindState rewind_st = {0}; RewindConfig rewind_cfg = { .enable = MINARCH_DEFAULT_REWIND_ENABLE, .buffer_mb = MINARCH_DEFAULT_REWIND_BUFFER_MB, From 774bc44cd3bac45182c2abfab5b5340df77259c0 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Thu, 2 Jul 2026 16:20:55 +0200 Subject: [PATCH 35/77] minarch: group display settings into a DisplayConfig struct Fourth ma_internal.h grouping. The five display-config ints (screen_scaling, screen_effect, screen_sharpness, cfg_screenx, cfg_screeny) become one DisplayConfig struct: display_cfg.scaling/effect/sharpness/screenx/screeny, with designated initializers preserving the defaults (SCALE_ASPECT, EFFECT_NONE, SHARPNESS_SOFT, 64, 64). `overlay` was deliberately left standalone -- its bare name collides with a local SDL_Surface*, the menu.overlay struct field, and comment/string text, so it's not safe for a mechanical rename and isn't worth hand-threading here. DEVICE_WIDTH/HEIGHT/PITCH stay as-is too (device geometry, all-caps, not config). Mechanical, same values/reads -- no behaviour change. minarch builds clean; worth an in-game visual check since it drives scaling/aspect/sharpness/offset. --- workspace/all/minarch/ma_config.c | 8 ++++---- workspace/all/minarch/ma_input.c | 8 ++++---- workspace/all/minarch/ma_internal.h | 14 +++++++++----- workspace/all/minarch/ma_menu.c | 12 ++++++------ workspace/all/minarch/ma_video.c | 2 +- workspace/all/minarch/minarch.c | 14 ++++++++------ 6 files changed, 32 insertions(+), 26 deletions(-) diff --git a/workspace/all/minarch/ma_config.c b/workspace/all/minarch/ma_config.c index 20d549422..80b66f506 100644 --- a/workspace/all/minarch/ma_config.c +++ b/workspace/all/minarch/ma_config.c @@ -71,7 +71,7 @@ void setOverclock(int i) { void Config_syncFrontend(char* key, int value) { int i = -1; if (exactMatch(key,config.frontend.options[FE_OPT_SCALING].key)) { - screen_scaling = value; + display_cfg.scaling = value; renderer.dst_p = 0; i = FE_OPT_SCALING; @@ -90,7 +90,7 @@ void Config_syncFrontend(char* key, int value) { i = FE_OPT_AMBIENT; } else if (exactMatch(key,config.frontend.options[FE_OPT_EFFECT].key)) { - screen_effect = value; + display_cfg.effect = value; GFX_setEffect(value); renderer.dst_p = 0; i = FE_OPT_EFFECT; @@ -111,12 +111,12 @@ void Config_syncFrontend(char* key, int value) { } } else if (exactMatch(key,config.frontend.options[FE_OPT_SCREENX].key)) { - cfg_screenx = value; + display_cfg.screenx = value; GFX_setOffsetX(value); i = FE_OPT_SCREENX; } else if (exactMatch(key,config.frontend.options[FE_OPT_SCREENY].key)) { - cfg_screeny = value; + display_cfg.screeny = value; GFX_setOffsetY(value); i = FE_OPT_SCREENY; } diff --git a/workspace/all/minarch/ma_input.c b/workspace/all/minarch/ma_input.c index 97cb7aa28..d9fe8691c 100644 --- a/workspace/all/minarch/ma_input.c +++ b/workspace/all/minarch/ma_input.c @@ -160,12 +160,12 @@ void input_poll_callback(void) { putFile(GAME_SWITCHER_PERSIST_PATH, game.path + strlen(SDCARD_PATH)); break; case SHORTCUT_CYCLE_SCALE: - screen_scaling = (screen_scaling + 1) % config.frontend.options[FE_OPT_SCALING].count; - Config_syncFrontend(config.frontend.options[FE_OPT_SCALING].key, screen_scaling); + display_cfg.scaling = (display_cfg.scaling + 1) % config.frontend.options[FE_OPT_SCALING].count; + Config_syncFrontend(config.frontend.options[FE_OPT_SCALING].key, display_cfg.scaling); break; case SHORTCUT_CYCLE_EFFECT: - screen_effect = (screen_effect + 1) % config.frontend.options[FE_OPT_EFFECT].count; - Config_syncFrontend(config.frontend.options[FE_OPT_EFFECT].key, screen_effect); + display_cfg.effect = (display_cfg.effect + 1) % config.frontend.options[FE_OPT_EFFECT].count; + Config_syncFrontend(config.frontend.options[FE_OPT_EFFECT].key, display_cfg.effect); break; default: break; } diff --git a/workspace/all/minarch/ma_internal.h b/workspace/all/minarch/ma_internal.h index 4e9f30313..cedaa4f40 100644 --- a/workspace/all/minarch/ma_internal.h +++ b/workspace/all/minarch/ma_internal.h @@ -111,8 +111,15 @@ typedef struct FastForward { } FastForward; extern FastForward ff; -extern int screen_scaling; -extern int screen_effect; +// Display configuration, grouped out of the flat global soup. +typedef struct DisplayConfig { + int scaling; // screen_scaling + int effect; // screen_effect + int sharpness; // screen_sharpness + int screenx; // cfg_screenx + int screeny; // cfg_screeny +} DisplayConfig; +extern DisplayConfig display_cfg; extern int DEVICE_WIDTH; extern int DEVICE_HEIGHT; @@ -124,9 +131,6 @@ extern int shader_reset_suppressed; extern char* scaling_labels[]; extern int simple_mode; extern int resampling_quality; -extern int screen_sharpness; -extern int cfg_screenx; -extern int cfg_screeny; extern int overlay; extern int sync_ref; extern int max_ff_speed; diff --git a/workspace/all/minarch/ma_menu.c b/workspace/all/minarch/ma_menu.c index 5297b33d3..0274b60dc 100644 --- a/workspace/all/minarch/ma_menu.c +++ b/workspace/all/minarch/ma_menu.c @@ -1435,7 +1435,7 @@ static void Menu_scale(SDL_Surface* src, SDL_Surface* dst) { int rw = dw; int rh = dh; - int scaling = screen_scaling; + int scaling = display_cfg.scaling; if (scaling==SCALE_CROPPED && DEVICE_WIDTH==HDMI_WIDTH) { scaling = SCALE_NATIVE; } @@ -1871,10 +1871,10 @@ void Menu_loop(void) { show_menu = 0; } else { - int old_scaling = screen_scaling; + int old_scaling = display_cfg.scaling; Options_updateVisibility(); Menu_options(&options_menu); - if (screen_scaling!=old_scaling) { + if (display_cfg.scaling!=old_scaling) { selectScaler(renderer.true_w,renderer.true_h,renderer.src_p); restore_w = screen->w; @@ -2051,13 +2051,13 @@ void Menu_loop(void) { GFX_setOverlay(overlayList[overlay],core.tag); } - GFX_setOffsetX(cfg_screenx); - GFX_setOffsetY(cfg_screeny); + GFX_setOffsetX(display_cfg.screenx); + GFX_setOffsetY(display_cfg.screeny); if (!quit) { if (restore_w!=DEVICE_WIDTH || restore_h!=DEVICE_HEIGHT) { screen = GFX_resize(restore_w,restore_h,restore_p); } - GFX_setEffect(screen_effect); + GFX_setEffect(display_cfg.effect); GFX_clear(screen); diff --git a/workspace/all/minarch/ma_video.c b/workspace/all/minarch/ma_video.c index 622e91525..49358f9f4 100644 --- a/workspace/all/minarch/ma_video.c +++ b/workspace/all/minarch/ma_video.c @@ -446,7 +446,7 @@ void selectScaler(int src_w, int src_h, int src_p) { renderer.true_h = src_h; // TODO: this is saving non-rgb30 devices from themselves...or rather, me - int scaling = screen_scaling; + int scaling = display_cfg.scaling; if (scaling==SCALE_CROPPED && DEVICE_WIDTH==HDMI_WIDTH) { scaling = SCALE_NATIVE; } diff --git a/workspace/all/minarch/minarch.c b/workspace/all/minarch/minarch.c index e216fbcc5..a23966fe3 100644 --- a/workspace/all/minarch/minarch.c +++ b/workspace/all/minarch/minarch.c @@ -30,14 +30,16 @@ int simple_mode = 0; enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_XRGB8888; // default frontend options -int screen_scaling = SCALE_ASPECT; int resampling_quality = 2; int ambient_mode = 0; -int screen_sharpness = SHARPNESS_SOFT; -int screen_effect = EFFECT_NONE; -int cfg_screenx = 64; -int cfg_screeny = 64; -int overlay = 0; +int overlay = 0; +DisplayConfig display_cfg = { + .scaling = SCALE_ASPECT, + .effect = EFFECT_NONE, + .sharpness = SHARPNESS_SOFT, + .screenx = 64, + .screeny = 64, +}; int use_core_fps = 0; int sync_ref = 0; int show_debug = 0; From 7ec4a0c865439e429f36f68098bde7ea44276928 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sun, 5 Jul 2026 12:41:54 +0200 Subject: [PATCH 36/77] chore: gitignore local tooling dirs (.headroom, graphify-out) --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 3136a5393..1d41efc6f 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,7 @@ workspace/.container_runtime AGENTS.md CLAUDE.md .worktrees/ + +# local tooling data (headroom memory, graphify output) +.headroom/ +graphify-out/ From 158c93580dce37e114b0fd05a15a8df15f4cefc3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 5 Jul 2026 09:37:22 +0000 Subject: [PATCH 37/77] fix: refresh a2600 core patches for tg5040/tg5050 --- workspace/tg5040/cores/patches/a2600.patch | 6 +++--- workspace/tg5050/cores/patches/a2600.patch | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/workspace/tg5040/cores/patches/a2600.patch b/workspace/tg5040/cores/patches/a2600.patch index 3a6ef9a05..43a050884 100644 --- a/workspace/tg5040/cores/patches/a2600.patch +++ b/workspace/tg5040/cores/patches/a2600.patch @@ -3,7 +3,7 @@ index a22eb5d..c55c8cf 100644 --- a/Makefile +++ b/Makefile @@ -383,6 +383,19 @@ else ifeq ($(platform), miyoo) - FLAGS += -fomit-frame-pointer -ffast-math -march=armv5te -mtune=arm926ej-s + FLAGS += -fomit-frame-pointer -march=armv5te -mtune=arm926ej-s fpic := -fPIC +# target platform tg5040 trimUI brick @@ -14,8 +14,8 @@ index a22eb5d..c55c8cf 100644 + AR = $(CROSS_COMPILE)ar + SHARED := -shared -Wl,--no-undefined + LDFLAGS += -shared -Wl,--version-script=link.T -+ CFLAGS += -DARM -DALIGN_DWORD -falign-functions=16 -pipe -fstack-protector -+ CFLAGS += -mtune=cortex-a53 -mcpu=cortex-a53 -march=armv8-a ++ FLAGS += -DARM -DALIGN_DWORD -falign-functions=16 -pipe -fstack-protector ++ FLAGS += -mtune=cortex-a53 -mcpu=cortex-a53 -march=armv8-a + fpic := -fPIC + HAVE_NEON = 1 + diff --git a/workspace/tg5050/cores/patches/a2600.patch b/workspace/tg5050/cores/patches/a2600.patch index d8f614d76..c107b7b4c 100644 --- a/workspace/tg5050/cores/patches/a2600.patch +++ b/workspace/tg5050/cores/patches/a2600.patch @@ -3,7 +3,7 @@ index a22eb5d..c55c8cf 100644 --- a/Makefile +++ b/Makefile @@ -383,6 +383,19 @@ else ifeq ($(platform), miyoo) - FLAGS += -fomit-frame-pointer -ffast-math -march=armv5te -mtune=arm926ej-s + FLAGS += -fomit-frame-pointer -march=armv5te -mtune=arm926ej-s fpic := -fPIC +# target platform tg5050 trimUI smart pro s @@ -14,8 +14,8 @@ index a22eb5d..c55c8cf 100644 + AR = $(CROSS_COMPILE)ar + SHARED := -shared -Wl,--no-undefined + LDFLAGS += -shared -Wl,--version-script=link.T -+ CFLAGS += -DARM -DALIGN_DWORD -falign-functions=16 -pipe -fstack-protector -+ CFLAGS += -mcpu=cortex-a55 ++ FLAGS += -DARM -DALIGN_DWORD -falign-functions=16 -pipe -fstack-protector ++ FLAGS += -mcpu=cortex-a55 + fpic := -fPIC + HAVE_NEON = 1 + From b70643b6feccacc5f27b8a54750a94bdb6cc947c Mon Sep 17 00:00:00 2001 From: frysee Date: Sun, 5 Jul 2026 12:00:53 +0200 Subject: [PATCH 38/77] chore: remove unmaintained platforms --- github/README.md | 3 - github/generate_screenshots.sh | 13 - github/logo.png | Bin 5753 -> 0 bytes github/logo_outline.png | Bin 72202 -> 0 bytes github/minui-clock.png | Bin 13472 -> 0 bytes github/minui-main.png | Bin 24977 -> 0 bytes github/minui-menu-gbc.png | Bin 43346 -> 0 bytes github/minui-menu-md.png | Bin 42366 -> 0 bytes github/minui-menu-options-controls.png | Bin 16473 -> 0 bytes github/minui-menu-options-core.png | Bin 35145 -> 0 bytes github/minui-menu-options-frontend.png | Bin 24882 -> 0 bytes github/minui-menu-options-shortcuts.png | Bin 24188 -> 0 bytes github/minui-menu-p8.png | Bin 24626 -> 0 bytes github/minui-menu-ps.png | Bin 119457 -> 0 bytes github/minui-menu-sfc.png | Bin 48477 -> 0 bytes github/minui-menu-sgb.png | Bin 44017 -> 0 bytes github/minui-menu-vb.png | Bin 35164 -> 0 bytes skeleton/_unmaintained/BOOT/magicx/init.sh | 17 - skeleton/_unmaintained/BOOT/miyoo/app/MainUI | 16 - skeleton/_unmaintained/BOOT/miyoo/app/keymon | 3 - .../_unmaintained/BOOT/miyoo/app/miyoomini.sh | 46 - .../_unmaintained/BOOT/miyoo/app/my282.sh | 18 - .../_unmaintained/BOOT/miyoo/app/my355.sh | 26 - .../EXTRAS/Emus/gkdpixel/GG.pak/default.cfg | 18 - .../EXTRAS/Emus/gkdpixel/GG.pak/launch.sh | 14 - .../EXTRAS/Emus/gkdpixel/MGBA.pak/default.cfg | 18 - .../EXTRAS/Emus/gkdpixel/MGBA.pak/launch.sh | 15 - .../EXTRAS/Emus/gkdpixel/NGP.pak/default.cfg | 7 - .../EXTRAS/Emus/gkdpixel/NGP.pak/launch.sh | 15 - .../EXTRAS/Emus/gkdpixel/NGPC.pak/default.cfg | 7 - .../EXTRAS/Emus/gkdpixel/NGPC.pak/launch.sh | 15 - .../EXTRAS/Emus/gkdpixel/PCE.pak/default.cfg | 15 - .../EXTRAS/Emus/gkdpixel/PCE.pak/launch.sh | 15 - .../EXTRAS/Emus/gkdpixel/PKM.pak/default.cfg | 17 - .../EXTRAS/Emus/gkdpixel/PKM.pak/launch.sh | 15 - .../EXTRAS/Emus/gkdpixel/SGB.pak/default.cfg | 24 - .../EXTRAS/Emus/gkdpixel/SGB.pak/launch.sh | 15 - .../EXTRAS/Emus/gkdpixel/SMS.pak/default.cfg | 19 - .../EXTRAS/Emus/gkdpixel/SMS.pak/launch.sh | 14 - .../EXTRAS/Emus/m17/GG.pak/default.cfg | 20 - .../EXTRAS/Emus/m17/GG.pak/launch.sh | 14 - .../EXTRAS/Emus/m17/MGBA.pak/default.cfg | 20 - .../EXTRAS/Emus/m17/MGBA.pak/launch.sh | 15 - .../EXTRAS/Emus/m17/NGP.pak/default.cfg | 11 - .../EXTRAS/Emus/m17/NGP.pak/launch.sh | 15 - .../EXTRAS/Emus/m17/NGPC.pak/default.cfg | 9 - .../EXTRAS/Emus/m17/NGPC.pak/launch.sh | 15 - .../EXTRAS/Emus/m17/P8.pak/default.cfg | 9 - .../EXTRAS/Emus/m17/P8.pak/launch.sh | 15 - .../EXTRAS/Emus/m17/PCE.pak/default.cfg | 15 - .../EXTRAS/Emus/m17/PCE.pak/launch.sh | 15 - .../EXTRAS/Emus/m17/PKM.pak/default.cfg | 18 - .../EXTRAS/Emus/m17/PKM.pak/launch.sh | 15 - .../EXTRAS/Emus/m17/SGB.pak/default.cfg | 26 - .../EXTRAS/Emus/m17/SGB.pak/launch.sh | 15 - .../EXTRAS/Emus/m17/SMS.pak/default.cfg | 19 - .../EXTRAS/Emus/m17/SMS.pak/launch.sh | 14 - .../EXTRAS/Emus/m17/SUPA.pak/default.cfg | 15 - .../EXTRAS/Emus/m17/SUPA.pak/launch.sh | 15 - .../EXTRAS/Emus/m17/VB.pak/default.cfg | 22 - .../EXTRAS/Emus/m17/VB.pak/launch.sh | 15 - .../EXTRAS/Emus/magicmini/GG.pak/default.cfg | 18 - .../EXTRAS/Emus/magicmini/GG.pak/launch.sh | 14 - .../Emus/magicmini/MGBA.pak/default.cfg | 18 - .../EXTRAS/Emus/magicmini/MGBA.pak/launch.sh | 15 - .../EXTRAS/Emus/magicmini/NGP.pak/default.cfg | 9 - .../EXTRAS/Emus/magicmini/NGP.pak/launch.sh | 15 - .../Emus/magicmini/NGPC.pak/default.cfg | 7 - .../EXTRAS/Emus/magicmini/NGPC.pak/launch.sh | 15 - .../EXTRAS/Emus/magicmini/P8.pak/default.cfg | 7 - .../EXTRAS/Emus/magicmini/P8.pak/launch.sh | 15 - .../EXTRAS/Emus/magicmini/PCE.pak/default.cfg | 15 - .../EXTRAS/Emus/magicmini/PCE.pak/launch.sh | 15 - .../EXTRAS/Emus/magicmini/PKM.pak/default.cfg | 17 - .../EXTRAS/Emus/magicmini/PKM.pak/launch.sh | 15 - .../EXTRAS/Emus/magicmini/SGB.pak/default.cfg | 24 - .../EXTRAS/Emus/magicmini/SGB.pak/launch.sh | 15 - .../EXTRAS/Emus/magicmini/SMS.pak/default.cfg | 19 - .../EXTRAS/Emus/magicmini/SMS.pak/launch.sh | 14 - .../Emus/magicmini/SUPA.pak/default.cfg | 15 - .../EXTRAS/Emus/magicmini/SUPA.pak/launch.sh | 15 - .../EXTRAS/Emus/magicmini/VB.pak/default.cfg | 20 - .../EXTRAS/Emus/magicmini/VB.pak/launch.sh | 15 - .../EXTRAS/Emus/miyoomini/GG.pak/default.cfg | 18 - .../EXTRAS/Emus/miyoomini/GG.pak/launch.sh | 14 - .../Emus/miyoomini/MGBA.pak/default.cfg | 18 - .../EXTRAS/Emus/miyoomini/MGBA.pak/launch.sh | 15 - .../EXTRAS/Emus/miyoomini/NGP.pak/default.cfg | 9 - .../EXTRAS/Emus/miyoomini/NGP.pak/launch.sh | 15 - .../Emus/miyoomini/NGPC.pak/default.cfg | 7 - .../EXTRAS/Emus/miyoomini/NGPC.pak/launch.sh | 15 - .../EXTRAS/Emus/miyoomini/P8.pak/default.cfg | 7 - .../EXTRAS/Emus/miyoomini/P8.pak/launch.sh | 15 - .../EXTRAS/Emus/miyoomini/PCE.pak/default.cfg | 15 - .../EXTRAS/Emus/miyoomini/PCE.pak/launch.sh | 15 - .../EXTRAS/Emus/miyoomini/PKM.pak/default.cfg | 17 - .../EXTRAS/Emus/miyoomini/PKM.pak/launch.sh | 15 - .../EXTRAS/Emus/miyoomini/SGB.pak/default.cfg | 24 - .../EXTRAS/Emus/miyoomini/SGB.pak/launch.sh | 15 - .../EXTRAS/Emus/miyoomini/SMS.pak/default.cfg | 19 - .../EXTRAS/Emus/miyoomini/SMS.pak/launch.sh | 14 - .../Emus/miyoomini/SUPA.pak/default.cfg | 15 - .../EXTRAS/Emus/miyoomini/SUPA.pak/launch.sh | 15 - .../EXTRAS/Emus/miyoomini/VB.pak/default.cfg | 20 - .../EXTRAS/Emus/miyoomini/VB.pak/launch.sh | 15 - .../EXTRAS/Emus/my282/GG.pak/default.cfg | 18 - .../EXTRAS/Emus/my282/GG.pak/launch.sh | 14 - .../EXTRAS/Emus/my282/MGBA.pak/default.cfg | 18 - .../EXTRAS/Emus/my282/MGBA.pak/launch.sh | 15 - .../EXTRAS/Emus/my282/NGP.pak/default.cfg | 9 - .../EXTRAS/Emus/my282/NGP.pak/launch.sh | 15 - .../EXTRAS/Emus/my282/NGPC.pak/default.cfg | 7 - .../EXTRAS/Emus/my282/NGPC.pak/launch.sh | 15 - .../EXTRAS/Emus/my282/P8.pak/default.cfg | 7 - .../EXTRAS/Emus/my282/P8.pak/launch.sh | 15 - .../EXTRAS/Emus/my282/PCE.pak/default.cfg | 15 - .../EXTRAS/Emus/my282/PCE.pak/launch.sh | 15 - .../EXTRAS/Emus/my282/PKM.pak/default.cfg | 17 - .../EXTRAS/Emus/my282/PKM.pak/launch.sh | 15 - .../EXTRAS/Emus/my282/SGB.pak/default.cfg | 24 - .../EXTRAS/Emus/my282/SGB.pak/launch.sh | 15 - .../EXTRAS/Emus/my282/SMS.pak/default.cfg | 19 - .../EXTRAS/Emus/my282/SMS.pak/launch.sh | 14 - .../EXTRAS/Emus/my282/SUPA.pak/default.cfg | 15 - .../EXTRAS/Emus/my282/SUPA.pak/launch.sh | 15 - .../EXTRAS/Emus/my282/VB.pak/default.cfg | 20 - .../EXTRAS/Emus/my282/VB.pak/launch.sh | 15 - .../EXTRAS/Emus/my355/GG.pak/default.cfg | 18 - .../EXTRAS/Emus/my355/GG.pak/launch.sh | 14 - .../EXTRAS/Emus/my355/MGBA.pak/default.cfg | 18 - .../EXTRAS/Emus/my355/MGBA.pak/launch.sh | 15 - .../EXTRAS/Emus/my355/NGP.pak/default.cfg | 9 - .../EXTRAS/Emus/my355/NGP.pak/launch.sh | 15 - .../EXTRAS/Emus/my355/NGPC.pak/default.cfg | 7 - .../EXTRAS/Emus/my355/NGPC.pak/launch.sh | 15 - .../EXTRAS/Emus/my355/P8.pak/default.cfg | 7 - .../EXTRAS/Emus/my355/P8.pak/launch.sh | 15 - .../EXTRAS/Emus/my355/PCE.pak/default.cfg | 15 - .../EXTRAS/Emus/my355/PCE.pak/launch.sh | 15 - .../EXTRAS/Emus/my355/PKM.pak/default.cfg | 17 - .../EXTRAS/Emus/my355/PKM.pak/launch.sh | 15 - .../EXTRAS/Emus/my355/SGB.pak/default.cfg | 24 - .../EXTRAS/Emus/my355/SGB.pak/launch.sh | 15 - .../EXTRAS/Emus/my355/SMS.pak/default.cfg | 19 - .../EXTRAS/Emus/my355/SMS.pak/launch.sh | 14 - .../EXTRAS/Emus/my355/SUPA.pak/default.cfg | 15 - .../EXTRAS/Emus/my355/SUPA.pak/launch.sh | 15 - .../EXTRAS/Emus/my355/VB.pak/default.cfg | 20 - .../EXTRAS/Emus/my355/VB.pak/launch.sh | 15 - .../EXTRAS/Emus/rg35xx/GG.pak/default.cfg | 18 - .../EXTRAS/Emus/rg35xx/GG.pak/launch.sh | 14 - .../EXTRAS/Emus/rg35xx/MGBA.pak/default.cfg | 18 - .../EXTRAS/Emus/rg35xx/MGBA.pak/launch.sh | 15 - .../EXTRAS/Emus/rg35xx/NGP.pak/default.cfg | 9 - .../EXTRAS/Emus/rg35xx/NGP.pak/launch.sh | 15 - .../EXTRAS/Emus/rg35xx/NGPC.pak/default.cfg | 7 - .../EXTRAS/Emus/rg35xx/NGPC.pak/launch.sh | 15 - .../EXTRAS/Emus/rg35xx/P8.pak/default.cfg | 7 - .../EXTRAS/Emus/rg35xx/P8.pak/launch.sh | 15 - .../EXTRAS/Emus/rg35xx/PCE.pak/default.cfg | 15 - .../EXTRAS/Emus/rg35xx/PCE.pak/launch.sh | 15 - .../EXTRAS/Emus/rg35xx/PKM.pak/default.cfg | 17 - .../EXTRAS/Emus/rg35xx/PKM.pak/launch.sh | 15 - .../EXTRAS/Emus/rg35xx/SGB.pak/default.cfg | 24 - .../EXTRAS/Emus/rg35xx/SGB.pak/launch.sh | 15 - .../EXTRAS/Emus/rg35xx/SMS.pak/default.cfg | 19 - .../EXTRAS/Emus/rg35xx/SMS.pak/launch.sh | 14 - .../EXTRAS/Emus/rg35xx/SUPA.pak/default.cfg | 15 - .../EXTRAS/Emus/rg35xx/SUPA.pak/launch.sh | 15 - .../EXTRAS/Emus/rg35xx/VB.pak/default.cfg | 20 - .../EXTRAS/Emus/rg35xx/VB.pak/launch.sh | 15 - .../EXTRAS/Emus/rg35xxplus/GG.pak/default.cfg | 20 - .../EXTRAS/Emus/rg35xxplus/GG.pak/launch.sh | 14 - .../Emus/rg35xxplus/MGBA.pak/default-cube.cfg | 21 - .../Emus/rg35xxplus/MGBA.pak/default-wide.cfg | 21 - .../Emus/rg35xxplus/MGBA.pak/default.cfg | 18 - .../EXTRAS/Emus/rg35xxplus/MGBA.pak/launch.sh | 15 - .../Emus/rg35xxplus/NGP.pak/default-cube.cfg | 13 - .../Emus/rg35xxplus/NGP.pak/default.cfg | 11 - .../EXTRAS/Emus/rg35xxplus/NGP.pak/launch.sh | 15 - .../Emus/rg35xxplus/NGPC.pak/default-cube.cfg | 13 - .../Emus/rg35xxplus/NGPC.pak/default.cfg | 11 - .../EXTRAS/Emus/rg35xxplus/NGPC.pak/launch.sh | 15 - .../Emus/rg35xxplus/P8.pak/default-cube.cfg | 10 - .../EXTRAS/Emus/rg35xxplus/P8.pak/default.cfg | 7 - .../EXTRAS/Emus/rg35xxplus/P8.pak/launch.sh | 15 - .../Emus/rg35xxplus/PCE.pak/default-cube.cfg | 18 - .../Emus/rg35xxplus/PCE.pak/default.cfg | 15 - .../EXTRAS/Emus/rg35xxplus/PCE.pak/launch.sh | 15 - .../Emus/rg35xxplus/PKM.pak/default-cube.cfg | 18 - .../Emus/rg35xxplus/PKM.pak/default-wide.cfg | 18 - .../Emus/rg35xxplus/PKM.pak/default.cfg | 18 - .../EXTRAS/Emus/rg35xxplus/PKM.pak/launch.sh | 15 - .../Emus/rg35xxplus/SGB.pak/default-cube.cfg | 28 - .../Emus/rg35xxplus/SGB.pak/default.cfg | 26 - .../EXTRAS/Emus/rg35xxplus/SGB.pak/launch.sh | 15 - .../Emus/rg35xxplus/SMS.pak/default-cube.cfg | 23 - .../Emus/rg35xxplus/SMS.pak/default.cfg | 21 - .../EXTRAS/Emus/rg35xxplus/SMS.pak/launch.sh | 14 - .../Emus/rg35xxplus/SUPA.pak/default-cube.cfg | 18 - .../Emus/rg35xxplus/SUPA.pak/default.cfg | 15 - .../EXTRAS/Emus/rg35xxplus/SUPA.pak/launch.sh | 15 - .../Emus/rg35xxplus/VB.pak/default-cube.cfg | 22 - .../Emus/rg35xxplus/VB.pak/default-wide.cfg | 22 - .../EXTRAS/Emus/rg35xxplus/VB.pak/default.cfg | 20 - .../EXTRAS/Emus/rg35xxplus/VB.pak/launch.sh | 15 - .../EXTRAS/Emus/rgb30/GG.pak/default.cfg | 20 - .../EXTRAS/Emus/rgb30/GG.pak/launch.sh | 14 - .../EXTRAS/Emus/rgb30/MGBA.pak/default.cfg | 20 - .../EXTRAS/Emus/rgb30/MGBA.pak/launch.sh | 15 - .../EXTRAS/Emus/rgb30/NGP.pak/default.cfg | 11 - .../EXTRAS/Emus/rgb30/NGP.pak/launch.sh | 15 - .../EXTRAS/Emus/rgb30/NGPC.pak/default.cfg | 9 - .../EXTRAS/Emus/rgb30/NGPC.pak/launch.sh | 15 - .../EXTRAS/Emus/rgb30/P8-NATIVE.pak/launch.sh | 21 - .../Emus/rgb30/P8-NATIVE.pak/missing.png | Bin 9868 -> 0 bytes .../EXTRAS/Emus/rgb30/P8.pak/default.cfg | 7 - .../EXTRAS/Emus/rgb30/P8.pak/launch.sh | 15 - .../EXTRAS/Emus/rgb30/PCE.pak/default.cfg | 17 - .../EXTRAS/Emus/rgb30/PCE.pak/launch.sh | 15 - .../EXTRAS/Emus/rgb30/PKM.pak/default.cfg | 17 - .../EXTRAS/Emus/rgb30/PKM.pak/launch.sh | 15 - .../EXTRAS/Emus/rgb30/SGB.pak/default.cfg | 27 - .../EXTRAS/Emus/rgb30/SGB.pak/launch.sh | 15 - .../EXTRAS/Emus/rgb30/SMS.pak/default.cfg | 23 - .../EXTRAS/Emus/rgb30/SMS.pak/launch.sh | 14 - .../EXTRAS/Emus/rgb30/SUPA.pak/default.cfg | 17 - .../EXTRAS/Emus/rgb30/SUPA.pak/launch.sh | 15 - .../EXTRAS/Emus/rgb30/VB.pak/default.cfg | 21 - .../EXTRAS/Emus/rgb30/VB.pak/launch.sh | 15 - .../Emus/trimuismart/GG.pak/default.cfg | 18 - .../EXTRAS/Emus/trimuismart/GG.pak/launch.sh | 14 - .../Emus/trimuismart/MGBA.pak/default.cfg | 18 - .../Emus/trimuismart/MGBA.pak/launch.sh | 15 - .../Emus/trimuismart/NGP.pak/default.cfg | 9 - .../EXTRAS/Emus/trimuismart/NGP.pak/launch.sh | 15 - .../Emus/trimuismart/NGPC.pak/default.cfg | 7 - .../Emus/trimuismart/NGPC.pak/launch.sh | 15 - .../Emus/trimuismart/P8.pak/default.cfg | 7 - .../EXTRAS/Emus/trimuismart/P8.pak/launch.sh | 15 - .../Emus/trimuismart/PCE.pak/default.cfg | 15 - .../EXTRAS/Emus/trimuismart/PCE.pak/launch.sh | 15 - .../Emus/trimuismart/PKM.pak/default.cfg | 17 - .../EXTRAS/Emus/trimuismart/PKM.pak/launch.sh | 15 - .../Emus/trimuismart/SGB.pak/default.cfg | 24 - .../EXTRAS/Emus/trimuismart/SGB.pak/launch.sh | 15 - .../Emus/trimuismart/SMS.pak/default.cfg | 19 - .../EXTRAS/Emus/trimuismart/SMS.pak/launch.sh | 14 - .../Emus/trimuismart/SUPA.pak/default.cfg | 15 - .../Emus/trimuismart/SUPA.pak/launch.sh | 15 - .../Emus/trimuismart/VB.pak/default.cfg | 21 - .../EXTRAS/Emus/trimuismart/VB.pak/launch.sh | 15 - .../EXTRAS/Emus/zero28/GG.pak/default.cfg | 18 - .../EXTRAS/Emus/zero28/GG.pak/launch.sh | 14 - .../EXTRAS/Emus/zero28/MGBA.pak/default.cfg | 18 - .../EXTRAS/Emus/zero28/MGBA.pak/launch.sh | 15 - .../EXTRAS/Emus/zero28/NGP.pak/default.cfg | 9 - .../EXTRAS/Emus/zero28/NGP.pak/launch.sh | 15 - .../EXTRAS/Emus/zero28/NGPC.pak/default.cfg | 7 - .../EXTRAS/Emus/zero28/NGPC.pak/launch.sh | 15 - .../EXTRAS/Emus/zero28/P8.pak/default.cfg | 7 - .../EXTRAS/Emus/zero28/P8.pak/launch.sh | 15 - .../EXTRAS/Emus/zero28/PCE.pak/default.cfg | 15 - .../EXTRAS/Emus/zero28/PCE.pak/launch.sh | 15 - .../EXTRAS/Emus/zero28/PKM.pak/default.cfg | 17 - .../EXTRAS/Emus/zero28/PKM.pak/launch.sh | 15 - .../EXTRAS/Emus/zero28/SGB.pak/default.cfg | 24 - .../EXTRAS/Emus/zero28/SGB.pak/launch.sh | 15 - .../EXTRAS/Emus/zero28/SMS.pak/default.cfg | 19 - .../EXTRAS/Emus/zero28/SMS.pak/launch.sh | 14 - .../EXTRAS/Emus/zero28/SUPA.pak/default.cfg | 15 - .../EXTRAS/Emus/zero28/SUPA.pak/launch.sh | 15 - .../EXTRAS/Emus/zero28/VB.pak/default.cfg | 20 - .../EXTRAS/Emus/zero28/VB.pak/launch.sh | 15 - .../EXTRAS/Tools/gkdpixel/Clock.pak/launch.sh | 4 - .../EXTRAS/Tools/gkdpixel/Files.pak/launch.sh | 6 - .../EXTRAS/Tools/gkdpixel/Input.pak/launch.sh | 4 - .../EXTRAS/Tools/m17/Bootlogo.pak/launch.sh | 72 -- .../EXTRAS/Tools/m17/Bootlogo.pak/logo.bmp | Bin 30056 -> 0 bytes .../Tools/m17/Bootlogo.pak/original.bmp | Bin 31736 -> 0 bytes .../EXTRAS/Tools/m17/Clock.pak/launch.sh | 4 - .../EXTRAS/Tools/m17/Input.pak/launch.sh | 4 - .../Tools/magicmini/Clock.pak/launch.sh | 4 - .../Tools/magicmini/Files.pak/launch.sh | 4 - .../Tools/magicmini/Input.pak/launch.sh | 4 - .../Tools/miyoomini/Bootlogo.pak/launch.sh | 44 - .../Tools/miyoomini/Clock.pak/launch.sh | 4 - .../Tools/miyoomini/Files.pak/launch.sh | 6 - .../Tools/miyoomini/Input.pak/launch.sh | 4 - .../Tools/my282/Bootlogo.pak/bootlogo.bmp | Bin 1228872 -> 0 bytes .../EXTRAS/Tools/my282/Bootlogo.pak/launch.sh | 51 - .../Tools/my282/Bootlogo.pak/res/abort.png | Bin 7991 -> 0 bytes .../Tools/my282/Bootlogo.pak/res/missing.png | Bin 7069 -> 0 bytes .../Bootlogo.pak/res/offset-20240401221906 | 1 - .../Bootlogo.pak/res/offset-20240426150228 | 1 - .../Bootlogo.pak/res/offset-20240516174101 | 1 - .../Bootlogo.pak/res/offset-20240713100458 | 1 - .../Tools/my282/Bootlogo.pak/res/simplify.png | Bin 13679 -> 0 bytes .../Tools/my282/Bootlogo.pak/res/updating.png | Bin 3376 -> 0 bytes .../EXTRAS/Tools/my282/Clock.pak/launch.sh | 4 - .../EXTRAS/Tools/my282/Files.pak/launch.sh | 6 - .../EXTRAS/Tools/my282/Input.pak/launch.sh | 4 - .../Tools/my282/Remove Loading.pak/abort.png | Bin 8151 -> 0 bytes .../Tools/my282/Remove Loading.pak/launch.sh | 52 - .../Tools/my282/Remove Loading.pak/patch.png | Bin 13722 -> 0 bytes .../Tools/my282/Reset Stick.pak/calibrate.png | Bin 4123 -> 0 bytes .../Tools/my282/Reset Stick.pak/launch.sh | 7 - .../EXTRAS/Tools/my355/Bootlogo.pak/apply.sh | 79 -- .../EXTRAS/Tools/my355/Bootlogo.pak/launch.sh | 4 - .../Bootlogo.pak/payload/logo-original.bmp | Bin 285176 -> 0 bytes .../Tools/my355/Bootlogo.pak/payload/logo.bmp | Bin 921656 -> 0 bytes .../my355/Bootlogo.pak/res/extract-img.png | Bin 3706 -> 0 bytes .../my355/Bootlogo.pak/res/flash-img.png | Bin 4487 -> 0 bytes .../Tools/my355/Bootlogo.pak/res/pack-img.png | Bin 4411 -> 0 bytes .../Tools/my355/Bootlogo.pak/res/pack-res.png | Bin 4428 -> 0 bytes .../Tools/my355/Bootlogo.pak/res/prep-env.png | Bin 3945 -> 0 bytes .../Tools/my355/Bootlogo.pak/res/reboot.png | Bin 3006 -> 0 bytes .../my355/Bootlogo.pak/res/replace-logo.png | Bin 3495 -> 0 bytes .../my355/Bootlogo.pak/res/unpack-img.png | Bin 3787 -> 0 bytes .../my355/Bootlogo.pak/res/unpack-res.png | Bin 4221 -> 0 bytes .../EXTRAS/Tools/my355/Clock.pak/launch.sh | 4 - .../EXTRAS/Tools/my355/Files.pak/launch.sh | 6 - .../EXTRAS/Tools/my355/Input.pak/launch.sh | 4 - .../EXTRAS/Tools/rg35xx/Clock.pak/launch.sh | 4 - .../EXTRAS/Tools/rg35xx/Files.pak/launch.sh | 6 - .../EXTRAS/Tools/rg35xx/Input.pak/launch.sh | 4 - .../rg35xxplus/Apply Panel Fix.pak/apply.sh | 205 ---- .../rg35xxplus/Apply Panel Fix.pak/bin/.keep | 0 .../rg35xxplus/Apply Panel Fix.pak/launch.sh | 5 - .../Apply Panel Fix.pak/res/applying.png | Bin 3728 -> 0 bytes .../Apply Panel Fix.pak/res/fail.png | Bin 4597 -> 0 bytes .../Apply Panel Fix.pak/res/mismatch.png | Bin 4935 -> 0 bytes .../Apply Panel Fix.pak/res/patched.png | Bin 3888 -> 0 bytes .../Apply Panel Fix.pak/res/preparing.png | Bin 3588 -> 0 bytes .../Apply Panel Fix.pak/res/rebooting.png | Bin 4343 -> 0 bytes .../Apply Panel Fix.pak/res/unknown.png | Bin 4381 -> 0 bytes .../Apply Panel Fix.pak/res/verifying.png | Bin 3928 -> 0 bytes .../Tools/rg35xxplus/Clock.pak/launch.sh | 4 - .../Tools/rg35xxplus/Enable SSH.pak/launch.sh | 32 - .../Tools/rg35xxplus/Enable SSH.pak/ssh.png | Bin 5337 -> 0 bytes .../Tools/rg35xxplus/Enable SSH.pak/wifi.png | Bin 14935 -> 0 bytes .../Tools/rg35xxplus/Files.pak/launch.sh | 15 - .../Tools/rg35xxplus/Files.pak/missing.png | Bin 11845 -> 0 bytes .../Tools/rg35xxplus/Input.pak/launch.sh | 4 - .../Tools/rg35xxplus/Swap Menu.pak/apply.sh | 84 -- .../Tools/rg35xxplus/Swap Menu.pak/bin/.keep | 0 .../Tools/rg35xxplus/Swap Menu.pak/launch.sh | 5 - .../rg35xxplus/Swap Menu.pak/res/applying.png | Bin 3728 -> 0 bytes .../rg35xxplus/Swap Menu.pak/res/fail.png | Bin 4597 -> 0 bytes .../Swap Menu.pak/res/preparing.png | Bin 3588 -> 0 bytes .../EXTRAS/Tools/rgb30/Clock.pak/launch.sh | 4 - .../EXTRAS/Tools/rgb30/Files.pak/launch.sh | 6 - .../EXTRAS/Tools/rgb30/Input.pak/launch.sh | 4 - .../Tools/rgb30/Splore.pak/extracting.png | Bin 3882 -> 0 bytes .../EXTRAS/Tools/rgb30/Splore.pak/launch.sh | 44 - .../EXTRAS/Tools/rgb30/Splore.pak/missing.png | Bin 9868 -> 0 bytes .../rgb30/Splore.pak/sdl_controllers.txt | 1 - .../EXTRAS/Tools/rgb30/Wi-Fi.pak/launch.sh | 68 -- .../Tools/rgb30/Wi-Fi.pak/res/disable.png | Bin 3878 -> 0 bytes .../Tools/rgb30/Wi-Fi.pak/res/enable.png | Bin 3491 -> 0 bytes .../Tools/rgb30/Wi-Fi.pak/res/update.png | Bin 3736 -> 0 bytes .../EXTRAS/Tools/rgb30/Wi-Fi.pak/wifi.txt | 0 .../Tools/trimuismart/Bootlogo.pak/launch.sh | 26 - .../Tools/trimuismart/Clock.pak/launch.sh | 4 - .../Tools/trimuismart/Files.pak/launch.sh | 6 - .../Tools/trimuismart/Input.pak/launch.sh | 4 - .../Tools/zero28/Bootlogo.pak/bootlogo.bmp | Bin 43256 -> 0 bytes .../Tools/zero28/Bootlogo.pak/launch.sh | 21 - .../EXTRAS/Tools/zero28/Clock.pak/launch.sh | 4 - .../EXTRAS/Tools/zero28/Files.pak/launch.sh | 6 - .../EXTRAS/Tools/zero28/Input.pak/launch.sh | 4 - .../SYSTEM/gkdpixel/bin/shutdown | 8 - .../_unmaintained/SYSTEM/gkdpixel/cores/.keep | 0 .../_unmaintained/SYSTEM/gkdpixel/dat/.keep | 0 .../_unmaintained/SYSTEM/gkdpixel/lib/.keep | 0 .../gkdpixel/paks/Emus/FC.pak/default.cfg | 22 - .../gkdpixel/paks/Emus/FC.pak/launch.sh | 14 - .../gkdpixel/paks/Emus/GB.pak/default.cfg | 18 - .../gkdpixel/paks/Emus/GB.pak/launch.sh | 14 - .../gkdpixel/paks/Emus/GBA.pak/default.cfg | 14 - .../gkdpixel/paks/Emus/GBA.pak/launch.sh | 14 - .../gkdpixel/paks/Emus/GBC.pak/default.cfg | 15 - .../gkdpixel/paks/Emus/GBC.pak/launch.sh | 14 - .../gkdpixel/paks/Emus/MD.pak/default.cfg | 20 - .../gkdpixel/paks/Emus/MD.pak/launch.sh | 14 - .../gkdpixel/paks/Emus/PS.pak/default.cfg | 17 - .../gkdpixel/paks/Emus/PS.pak/launch.sh | 14 - .../gkdpixel/paks/Emus/SFC.pak/default.cfg | 14 - .../gkdpixel/paks/Emus/SFC.pak/launch.sh | 14 - .../SYSTEM/gkdpixel/paks/MinUI.pak/launch.sh | 76 -- .../_unmaintained/SYSTEM/gkdpixel/system.cfg | 6 - .../_unmaintained/SYSTEM/m17/bin/shutdown | 8 - .../SYSTEM/m17/bin/start_adbd.sh | 36 - skeleton/_unmaintained/SYSTEM/m17/cores/.keep | 0 skeleton/_unmaintained/SYSTEM/m17/dat/.keep | 0 skeleton/_unmaintained/SYSTEM/m17/lib/.keep | 0 .../SYSTEM/m17/paks/Emus/FC.pak/default.cfg | 20 - .../SYSTEM/m17/paks/Emus/FC.pak/launch.sh | 14 - .../SYSTEM/m17/paks/Emus/GB.pak/default.cfg | 20 - .../SYSTEM/m17/paks/Emus/GB.pak/launch.sh | 14 - .../SYSTEM/m17/paks/Emus/GBA.pak/default.cfg | 16 - .../SYSTEM/m17/paks/Emus/GBA.pak/launch.sh | 14 - .../SYSTEM/m17/paks/Emus/GBC.pak/default.cfg | 17 - .../SYSTEM/m17/paks/Emus/GBC.pak/launch.sh | 14 - .../SYSTEM/m17/paks/Emus/MD.pak/default.cfg | 20 - .../SYSTEM/m17/paks/Emus/MD.pak/launch.sh | 14 - .../SYSTEM/m17/paks/Emus/PS.pak/default.cfg | 20 - .../SYSTEM/m17/paks/Emus/PS.pak/launch.sh | 14 - .../SYSTEM/m17/paks/Emus/SFC.pak/default.cfg | 12 - .../SYSTEM/m17/paks/Emus/SFC.pak/launch.sh | 14 - .../SYSTEM/m17/paks/MinUI.pak/launch.sh | 82 -- skeleton/_unmaintained/SYSTEM/m17/system.cfg | 4 - .../SYSTEM/magicmini/bin/shutdown | 9 - .../SYSTEM/magicmini/cores/.keep | 0 .../_unmaintained/SYSTEM/magicmini/dat/.keep | 0 .../_unmaintained/SYSTEM/magicmini/lib/.keep | 0 .../magicmini/paks/Emus/FC.pak/default.cfg | 20 - .../magicmini/paks/Emus/FC.pak/launch.sh | 14 - .../magicmini/paks/Emus/GB.pak/default.cfg | 20 - .../magicmini/paks/Emus/GB.pak/launch.sh | 14 - .../magicmini/paks/Emus/GBA.pak/default.cfg | 14 - .../magicmini/paks/Emus/GBA.pak/launch.sh | 14 - .../magicmini/paks/Emus/GBC.pak/default.cfg | 17 - .../magicmini/paks/Emus/GBC.pak/launch.sh | 14 - .../magicmini/paks/Emus/MD.pak/default.cfg | 18 - .../magicmini/paks/Emus/MD.pak/launch.sh | 14 - .../magicmini/paks/Emus/PS.pak/default.cfg | 22 - .../magicmini/paks/Emus/PS.pak/launch.sh | 14 - .../magicmini/paks/Emus/SFC.pak/default.cfg | 12 - .../magicmini/paks/Emus/SFC.pak/launch.sh | 14 - .../SYSTEM/magicmini/paks/MinUI.pak/launch.sh | 66 - .../_unmaintained/SYSTEM/magicmini/system.cfg | 2 - .../SYSTEM/miyoomini/bin/needs-swap | 12 - .../SYSTEM/miyoomini/bin/shutdown | 11 - .../SYSTEM/miyoomini/cores/.keep | 0 .../SYSTEM/miyoomini/dat/image1.jpg | Bin 8448 -> 0 bytes .../_unmaintained/SYSTEM/miyoomini/lib/.keep | 0 .../miyoomini/paks/Emus/FC.pak/default.cfg | 20 - .../miyoomini/paks/Emus/FC.pak/launch.sh | 14 - .../miyoomini/paks/Emus/GB.pak/default.cfg | 20 - .../miyoomini/paks/Emus/GB.pak/launch.sh | 14 - .../miyoomini/paks/Emus/GBA.pak/default.cfg | 14 - .../miyoomini/paks/Emus/GBA.pak/launch.sh | 14 - .../miyoomini/paks/Emus/GBC.pak/default.cfg | 17 - .../miyoomini/paks/Emus/GBC.pak/launch.sh | 14 - .../miyoomini/paks/Emus/MD.pak/default.cfg | 18 - .../miyoomini/paks/Emus/MD.pak/launch.sh | 14 - .../miyoomini/paks/Emus/PS.pak/default.cfg | 21 - .../miyoomini/paks/Emus/PS.pak/launch.sh | 14 - .../miyoomini/paks/Emus/SFC.pak/default.cfg | 12 - .../miyoomini/paks/Emus/SFC.pak/launch.sh | 14 - .../SYSTEM/miyoomini/paks/MinUI.pak/launch.sh | 147 --- .../_unmaintained/SYSTEM/miyoomini/system.cfg | 3 - .../_unmaintained/SYSTEM/my282/bin/setterm | 3 - .../_unmaintained/SYSTEM/my282/bin/shutdown | 12 - .../_unmaintained/SYSTEM/my282/cores/.keep | 0 skeleton/_unmaintained/SYSTEM/my282/dat/.keep | 0 skeleton/_unmaintained/SYSTEM/my282/lib/.keep | 0 .../SYSTEM/my282/paks/Emus/FC.pak/default.cfg | 20 - .../SYSTEM/my282/paks/Emus/FC.pak/launch.sh | 14 - .../SYSTEM/my282/paks/Emus/GB.pak/default.cfg | 20 - .../SYSTEM/my282/paks/Emus/GB.pak/launch.sh | 14 - .../my282/paks/Emus/GBA.pak/default.cfg | 14 - .../SYSTEM/my282/paks/Emus/GBA.pak/launch.sh | 14 - .../my282/paks/Emus/GBC.pak/default.cfg | 17 - .../SYSTEM/my282/paks/Emus/GBC.pak/launch.sh | 14 - .../SYSTEM/my282/paks/Emus/MD.pak/default.cfg | 18 - .../SYSTEM/my282/paks/Emus/MD.pak/launch.sh | 14 - .../SYSTEM/my282/paks/Emus/PS.pak/default.cfg | 22 - .../SYSTEM/my282/paks/Emus/PS.pak/launch.sh | 14 - .../my282/paks/Emus/SFC.pak/default.cfg | 12 - .../SYSTEM/my282/paks/Emus/SFC.pak/launch.sh | 14 - .../SYSTEM/my282/paks/MinUI.pak/launch.sh | 75 -- .../_unmaintained/SYSTEM/my282/system.cfg | 3 - .../_unmaintained/SYSTEM/my355/bin/shutdown | 17 - .../_unmaintained/SYSTEM/my355/cores/.keep | 0 skeleton/_unmaintained/SYSTEM/my355/dat/.keep | 0 skeleton/_unmaintained/SYSTEM/my355/lib/.keep | 0 .../SYSTEM/my355/paks/Emus/FC.pak/default.cfg | 20 - .../SYSTEM/my355/paks/Emus/FC.pak/launch.sh | 14 - .../SYSTEM/my355/paks/Emus/GB.pak/default.cfg | 20 - .../SYSTEM/my355/paks/Emus/GB.pak/launch.sh | 14 - .../my355/paks/Emus/GBA.pak/default.cfg | 14 - .../SYSTEM/my355/paks/Emus/GBA.pak/launch.sh | 14 - .../my355/paks/Emus/GBC.pak/default.cfg | 17 - .../SYSTEM/my355/paks/Emus/GBC.pak/launch.sh | 14 - .../SYSTEM/my355/paks/Emus/MD.pak/default.cfg | 18 - .../SYSTEM/my355/paks/Emus/MD.pak/launch.sh | 14 - .../SYSTEM/my355/paks/Emus/PS.pak/default.cfg | 22 - .../SYSTEM/my355/paks/Emus/PS.pak/launch.sh | 14 - .../my355/paks/Emus/SFC.pak/default.cfg | 12 - .../SYSTEM/my355/paks/Emus/SFC.pak/launch.sh | 14 - .../SYSTEM/my355/paks/MinUI.pak/launch.sh | 88 -- .../_unmaintained/SYSTEM/my355/system.cfg | 3 - .../_unmaintained/SYSTEM/rg35xx/bin/shutdown | 10 - .../_unmaintained/SYSTEM/rg35xx/cores/.keep | 0 .../_unmaintained/SYSTEM/rg35xx/dat/.keep | 0 .../_unmaintained/SYSTEM/rg35xx/lib/.keep | 0 .../rg35xx/paks/Emus/FC.pak/default.cfg | 20 - .../SYSTEM/rg35xx/paks/Emus/FC.pak/launch.sh | 14 - .../rg35xx/paks/Emus/GB.pak/default.cfg | 20 - .../SYSTEM/rg35xx/paks/Emus/GB.pak/launch.sh | 14 - .../rg35xx/paks/Emus/GBA.pak/default.cfg | 14 - .../SYSTEM/rg35xx/paks/Emus/GBA.pak/launch.sh | 14 - .../rg35xx/paks/Emus/GBC.pak/default.cfg | 17 - .../SYSTEM/rg35xx/paks/Emus/GBC.pak/launch.sh | 14 - .../rg35xx/paks/Emus/MD.pak/default.cfg | 18 - .../SYSTEM/rg35xx/paks/Emus/MD.pak/launch.sh | 14 - .../rg35xx/paks/Emus/PS.pak/default.cfg | 21 - .../SYSTEM/rg35xx/paks/Emus/PS.pak/launch.sh | 14 - .../rg35xx/paks/Emus/SFC.pak/default.cfg | 12 - .../SYSTEM/rg35xx/paks/Emus/SFC.pak/launch.sh | 14 - .../SYSTEM/rg35xx/paks/MinUI.pak/launch.sh | 71 -- .../_unmaintained/SYSTEM/rg35xx/system.cfg | 2 - .../SYSTEM/rg35xxplus/bin/hdmimon.sh | 91 -- .../SYSTEM/rg35xxplus/bin/shutdown | 12 - .../SYSTEM/rg35xxplus/cores/.keep | 0 .../_unmaintained/SYSTEM/rg35xxplus/dat/.keep | 0 .../_unmaintained/SYSTEM/rg35xxplus/lib/.keep | 0 .../paks/Emus/FC.pak/default-cube.cfg | 23 - .../rg35xxplus/paks/Emus/FC.pak/default.cfg | 20 - .../rg35xxplus/paks/Emus/FC.pak/launch.sh | 14 - .../rg35xxplus/paks/Emus/GB.pak/default.cfg | 22 - .../rg35xxplus/paks/Emus/GB.pak/launch.sh | 14 - .../paks/Emus/GBA.pak/default-cube.cfg | 18 - .../paks/Emus/GBA.pak/default-wide.cfg | 18 - .../rg35xxplus/paks/Emus/GBA.pak/default.cfg | 16 - .../rg35xxplus/paks/Emus/GBA.pak/launch.sh | 14 - .../rg35xxplus/paks/Emus/GBC.pak/default.cfg | 19 - .../rg35xxplus/paks/Emus/GBC.pak/launch.sh | 14 - .../rg35xxplus/paks/Emus/MD.pak/default.cfg | 18 - .../rg35xxplus/paks/Emus/MD.pak/launch.sh | 14 - .../rg35xxplus/paks/Emus/PS.pak/default.cfg | 23 - .../rg35xxplus/paks/Emus/PS.pak/launch.sh | 14 - .../paks/Emus/SFC.pak/default-cube.cfg | 15 - .../rg35xxplus/paks/Emus/SFC.pak/default.cfg | 12 - .../rg35xxplus/paks/Emus/SFC.pak/launch.sh | 14 - .../rg35xxplus/paks/MinUI.pak/launch.sh | 86 -- .../SYSTEM/rg35xxplus/system.cfg | 3 - .../_unmaintained/SYSTEM/rgb30/bin/shutdown | 12 - .../_unmaintained/SYSTEM/rgb30/cores/.keep | 0 skeleton/_unmaintained/SYSTEM/rgb30/dat/.keep | 0 skeleton/_unmaintained/SYSTEM/rgb30/lib/.keep | 0 .../SYSTEM/rgb30/paks/Emus/FC.pak/default.cfg | 22 - .../SYSTEM/rgb30/paks/Emus/FC.pak/launch.sh | 14 - .../SYSTEM/rgb30/paks/Emus/GB.pak/default.cfg | 20 - .../SYSTEM/rgb30/paks/Emus/GB.pak/launch.sh | 14 - .../rgb30/paks/Emus/GBA.pak/default.cfg | 17 - .../SYSTEM/rgb30/paks/Emus/GBA.pak/launch.sh | 14 - .../rgb30/paks/Emus/GBC.pak/default.cfg | 17 - .../SYSTEM/rgb30/paks/Emus/GBC.pak/launch.sh | 14 - .../SYSTEM/rgb30/paks/Emus/MD.pak/default.cfg | 18 - .../SYSTEM/rgb30/paks/Emus/MD.pak/launch.sh | 14 - .../SYSTEM/rgb30/paks/Emus/PS.pak/default.cfg | 23 - .../SYSTEM/rgb30/paks/Emus/PS.pak/launch.sh | 14 - .../rgb30/paks/Emus/SFC.pak/default.cfg | 14 - .../SYSTEM/rgb30/paks/Emus/SFC.pak/launch.sh | 14 - .../SYSTEM/rgb30/paks/MinUI.pak/launch.sh | 73 -- .../_unmaintained/SYSTEM/rgb30/system.cfg | 3 - .../SYSTEM/trimuismart/bin/leds_off | 5 - .../SYSTEM/trimuismart/bin/leds_on | 5 - .../SYSTEM/trimuismart/bin/shutdown | 8 - .../SYSTEM/trimuismart/cores/.keep | 0 .../SYSTEM/trimuismart/dat/logo.bmp | Bin 153672 -> 0 bytes .../SYSTEM/trimuismart/lib/.keep | 0 .../trimuismart/paks/Emus/FC.pak/default.cfg | 20 - .../trimuismart/paks/Emus/FC.pak/launch.sh | 14 - .../trimuismart/paks/Emus/GB.pak/default.cfg | 18 - .../trimuismart/paks/Emus/GB.pak/launch.sh | 14 - .../trimuismart/paks/Emus/GBA.pak/default.cfg | 14 - .../trimuismart/paks/Emus/GBA.pak/launch.sh | 14 - .../trimuismart/paks/Emus/GBC.pak/default.cfg | 15 - .../trimuismart/paks/Emus/GBC.pak/launch.sh | 14 - .../trimuismart/paks/Emus/MD.pak/default.cfg | 20 - .../trimuismart/paks/Emus/MD.pak/launch.sh | 14 - .../trimuismart/paks/Emus/PS.pak/default.cfg | 19 - .../trimuismart/paks/Emus/PS.pak/launch.sh | 14 - .../trimuismart/paks/Emus/SFC.pak/default.cfg | 12 - .../trimuismart/paks/Emus/SFC.pak/launch.sh | 14 - .../trimuismart/paks/MinUI.pak/launch.sh | 113 -- .../SYSTEM/trimuismart/system.cfg | 4 - .../_unmaintained/SYSTEM/zero28/bin/setterm | 3 - .../_unmaintained/SYSTEM/zero28/bin/shutdown | 16 - .../_unmaintained/SYSTEM/zero28/bin/suspend | 74 -- .../_unmaintained/SYSTEM/zero28/cores/.keep | 0 .../_unmaintained/SYSTEM/zero28/dat/.keep | 0 .../_unmaintained/SYSTEM/zero28/lib/.keep | 0 .../zero28/paks/Emus/FC.pak/default.cfg | 20 - .../SYSTEM/zero28/paks/Emus/FC.pak/launch.sh | 14 - .../zero28/paks/Emus/GB.pak/default.cfg | 20 - .../SYSTEM/zero28/paks/Emus/GB.pak/launch.sh | 14 - .../zero28/paks/Emus/GBA.pak/default.cfg | 14 - .../SYSTEM/zero28/paks/Emus/GBA.pak/launch.sh | 14 - .../zero28/paks/Emus/GBC.pak/default.cfg | 17 - .../SYSTEM/zero28/paks/Emus/GBC.pak/launch.sh | 14 - .../zero28/paks/Emus/MD.pak/default.cfg | 18 - .../SYSTEM/zero28/paks/Emus/MD.pak/launch.sh | 14 - .../zero28/paks/Emus/PS.pak/default.cfg | 22 - .../SYSTEM/zero28/paks/Emus/PS.pak/launch.sh | 14 - .../zero28/paks/Emus/SFC.pak/default.cfg | 12 - .../SYSTEM/zero28/paks/Emus/SFC.pak/launch.sh | 14 - .../SYSTEM/zero28/paks/MinUI.pak/launch.sh | 72 -- .../_unmaintained/SYSTEM/zero28/system.cfg | 3 - workspace/_unmaintained/gkdpixel/boot/boot.sh | 45 - .../_unmaintained/gkdpixel/boot/install.sh | 14 - .../gkdpixel/boot/installing.bmp | Bin 307256 -> 0 bytes .../_unmaintained/gkdpixel/boot/updating.bmp | Bin 307256 -> 0 bytes .../_unmaintained/gkdpixel/cores/makefile | 44 - .../gkdpixel/cores/patches/pcsx_rearmed.patch | 44 - .../_unmaintained/gkdpixel/input/input.c | 82 -- .../_unmaintained/gkdpixel/input/input.txt | 94 -- .../_unmaintained/gkdpixel/input/makefile | 18 - .../_unmaintained/gkdpixel/install/install.sh | 4 - .../_unmaintained/gkdpixel/keymon/credits.txt | 3 - .../_unmaintained/gkdpixel/keymon/keymon.c | 148 --- .../_unmaintained/gkdpixel/keymon/makefile | 14 - .../gkdpixel/libmsettings/makefile | 32 - .../gkdpixel/libmsettings/msettings.c | 188 --- .../gkdpixel/libmsettings/msettings.h | 25 - workspace/_unmaintained/gkdpixel/makefile | 19 - .../gkdpixel/platform/makefile.copy | 4 - .../gkdpixel/platform/makefile.env | 3 - .../gkdpixel/platform/platform.c | 689 ----------- .../gkdpixel/platform/platform.h | 124 -- workspace/_unmaintained/gkdpixel/test/main.c | 44 - .../_unmaintained/gkdpixel/test/makefile | 16 - workspace/_unmaintained/m17/boot/boot.sh | 48 - workspace/_unmaintained/m17/boot/build.sh | 33 - .../_unmaintained/m17/boot/installing.bmp | Bin 522296 -> 0 bytes workspace/_unmaintained/m17/boot/notes.txt | 85 -- workspace/_unmaintained/m17/boot/updating.bmp | Bin 522296 -> 0 bytes workspace/_unmaintained/m17/cores/makefile | 41 - .../m17/cores/patches/fake-08.patch | 34 - .../m17/cores/patches/fceumm.patch | 28 - .../m17/cores/patches/gambatte.patch | 24 - .../m17/cores/patches/gpsp.patch | 28 - .../m17/cores/patches/mednafen_pce_fast.patch | 29 - .../cores/patches/mednafen_supafaust.patch | 42 - .../m17/cores/patches/mednafen_vb.patch | 29 - .../m17/cores/patches/mgba.patch | 31 - .../m17/cores/patches/pcsx_rearmed.patch | 31 - .../m17/cores/patches/picodrive.patch | 35 - .../m17/cores/patches/pokemini.patch | 27 - .../m17/cores/patches/race.patch | 23 - .../m17/cores/patches/snes9x2005_plus.patch | 36 - .../_unmaintained/m17/install/install.sh | 7 - .../_unmaintained/m17/keymon/credits.txt | 3 - workspace/_unmaintained/m17/keymon/keymon.c | 167 --- workspace/_unmaintained/m17/keymon/makefile | 14 - .../_unmaintained/m17/libmsettings/makefile | 32 - .../m17/libmsettings/msettings.c | 190 --- .../m17/libmsettings/msettings.h | 25 - workspace/_unmaintained/m17/makefile | 24 - .../_unmaintained/m17/platform/makefile.copy | 8 - .../_unmaintained/m17/platform/makefile.env | 4 - .../_unmaintained/m17/platform/platform.c | 523 -------- .../_unmaintained/m17/platform/platform.h | 127 -- .../_unmaintained/magicmini/cores/makefile | 41 - .../magicmini/cores/patches/fake-08.patch | 33 - .../magicmini/cores/patches/fceumm.patch | 22 - .../magicmini/cores/patches/gambatte.patch | 23 - .../magicmini/cores/patches/gpsp.patch | 23 - .../cores/patches/mednafen_pce_fast.patch | 25 - .../cores/patches/mednafen_supafaust.patch | 34 - .../magicmini/cores/patches/mednafen_vb.patch | 23 - .../magicmini/cores/patches/mgba.patch | 27 - .../cores/patches/pcsx_rearmed.patch | 26 - .../magicmini/cores/patches/picodrive.patch | 22 - .../magicmini/cores/patches/pokemini.patch | 23 - .../magicmini/cores/patches/race.patch | 23 - .../cores/patches/snes9x2005_plus.patch | 23 - .../_unmaintained/magicmini/install/boot.sh | 41 - .../magicmini/install/installing.bmp | Bin 1228872 -> 0 bytes .../_unmaintained/magicmini/install/notes.txt | 18 - .../_unmaintained/magicmini/install/update.sh | 10 - .../magicmini/install/updating.bmp | Bin 1228872 -> 0 bytes .../magicmini/keymon/credits.txt | 3 - .../_unmaintained/magicmini/keymon/keymon.c | 143 --- .../_unmaintained/magicmini/keymon/makefile | 16 - .../magicmini/libmsettings/makefile | 32 - .../magicmini/libmsettings/msettings.c | 167 --- .../magicmini/libmsettings/msettings.h | 25 - workspace/_unmaintained/magicmini/makefile | 29 - .../magicmini/platform/makefile.copy | 7 - .../magicmini/platform/makefile.env | 4 - .../magicmini/platform/platform.c | 809 ------------ .../magicmini/platform/platform.h | 124 -- .../_unmaintained/miyoomini/batmon/batmon.c | 187 --- .../_unmaintained/miyoomini/batmon/makefile | 15 - .../_unmaintained/miyoomini/blank/blank.c | 21 - .../_unmaintained/miyoomini/blank/makefile | 15 - .../_unmaintained/miyoomini/cores/makefile | 40 - .../miyoomini/cores/patches/fake-08.patch | 33 - .../miyoomini/cores/patches/fceumm.patch | 28 - .../miyoomini/cores/patches/gambatte.patch | 24 - .../miyoomini/cores/patches/gpsp.patch | 47 - .../cores/patches/mednafen_pce_fast.patch | 29 - .../cores/patches/mednafen_supafaust.patch | 42 - .../miyoomini/cores/patches/mednafen_vb.patch | 29 - .../miyoomini/cores/patches/mgba.patch | 31 - .../cores/patches/pcsx_rearmed.patch | 31 - .../miyoomini/cores/patches/picodrive.patch | 35 - .../miyoomini/cores/patches/pokemini.patch | 27 - .../miyoomini/cores/patches/race.patch | 23 - .../cores/patches/snes9x2005_plus.patch | 36 - .../_unmaintained/miyoomini/install/boot.sh | 48 - .../miyoomini/install/installing.png | Bin 3647 -> 0 bytes .../_unmaintained/miyoomini/install/update.sh | 5 - .../miyoomini/install/updating.png | Bin 3677 -> 0 bytes .../miyoomini/keymon/credits.txt | 3 - .../_unmaintained/miyoomini/keymon/keymon.c | 340 ------ .../_unmaintained/miyoomini/keymon/makefile | 21 - .../miyoomini/libmsettings/makefile | 32 - .../miyoomini/libmsettings/msettings.c | 228 ---- .../miyoomini/libmsettings/msettings.h | 25 - .../_unmaintained/miyoomini/lumon/lumon.c | 38 - .../_unmaintained/miyoomini/lumon/makefile | 15 - workspace/_unmaintained/miyoomini/makefile | 45 - workspace/_unmaintained/miyoomini/other/.keep | 0 .../other/latency_reduction/Makefile | 16 - .../other/latency_reduction/audioserver.mod | Bin 13964 -> 0 bytes .../other/latency_reduction/credits.txt | 2 - .../miyoomini/other/latency_reduction/main.c | 34 - .../miyoomini/other/logotweak/credits.txt | 2 - .../miyoomini/other/logotweak/logomake.c | 99 -- .../miyoomini/other/logotweak/logoread.c | 73 -- .../miyoomini/other/logotweak/logowrite.c | 116 -- .../miyoomini/other/logotweak/makefile | 16 - .../miyoomini/other/screenshot/Makefile | 21 - .../miyoomini/other/screenshot/credits.txt | 2 - .../miyoomini/other/screenshot/main.c | 209 ---- .../miyoomini/overclock/credits.txt | 2 - .../miyoomini/overclock/makefile | 14 - .../miyoomini/overclock/overclock.c | 144 --- .../miyoomini/platform/makefile.copy | 20 - .../miyoomini/platform/makefile.env | 3 - .../miyoomini/platform/platform.c | 554 --------- .../miyoomini/platform/platform.h | 123 -- .../_unmaintained/miyoomini/show/makefile | 15 - workspace/_unmaintained/miyoomini/show/show.c | 51 - workspace/_unmaintained/my282/cores/makefile | 4 - workspace/_unmaintained/my282/install/boot.sh | 37 - .../my282/install/installing.png | Bin 3647 -> 0 bytes .../_unmaintained/my282/install/update.sh | 5 - .../_unmaintained/my282/install/updating.png | Bin 3677 -> 0 bytes .../_unmaintained/my282/keymon/credits.txt | 3 - workspace/_unmaintained/my282/keymon/keymon.c | 143 --- workspace/_unmaintained/my282/keymon/makefile | 16 - .../_unmaintained/my282/libmsettings/makefile | 32 - .../my282/libmsettings/msettings.c | 166 --- .../my282/libmsettings/msettings.h | 25 - .../_unmaintained/my282/libmstick/makefile | 34 - .../_unmaintained/my282/libmstick/mstick.c | 408 ------- .../_unmaintained/my282/libmstick/mstick.h | 8 - workspace/_unmaintained/my282/makefile | 41 - .../my282/other/squashfs/makefile | 15 - .../_unmaintained/my282/overclock/credits.txt | 3 - .../_unmaintained/my282/overclock/makefile | 16 - .../_unmaintained/my282/overclock/overclock.c | 1085 ----------------- .../my282/platform/makefile.copy | 16 - .../_unmaintained/my282/platform/makefile.env | 5 - .../_unmaintained/my282/platform/platform.c | 738 ----------- .../_unmaintained/my282/platform/platform.h | 123 -- workspace/_unmaintained/my282/show/makefile | 14 - workspace/_unmaintained/my282/show/show.c | 63 - .../my282/tests/brightness/brightness.c | 27 - .../my282/tests/brightness/makefile | 16 - .../my282/tests/calibrate/calibrate.c | 46 - .../my282/tests/calibrate/makefile | 40 - .../_unmaintained/my282/tests/volume/makefile | 16 - .../_unmaintained/my282/tests/volume/volume.c | 28 - workspace/_unmaintained/my355/cores/makefile | 40 - .../my355/cores/patches/fake-08.patch | 34 - .../my355/cores/patches/fceumm.patch | 28 - .../my355/cores/patches/gambatte.patch | 24 - .../my355/cores/patches/gpsp.patch | 26 - .../cores/patches/mednafen_pce_fast.patch | 25 - .../cores/patches/mednafen_supafaust.patch | 34 - .../my355/cores/patches/mednafen_vb.patch | 29 - .../my355/cores/patches/mgba.patch | 31 - .../my355/cores/patches/pcsx_rearmed.patch | 30 - .../my355/cores/patches/picodrive.patch | 35 - .../my355/cores/patches/pokemini.patch | 27 - .../my355/cores/patches/race.patch | 23 - .../my355/cores/patches/snes9x2005_plus.patch | 36 - workspace/_unmaintained/my355/init/init.sh | 75 -- .../my355/init/payload/runmiyoo.sh | 19 - .../my355/init/res/extract-root.png | Bin 3690 -> 0 bytes .../my355/init/res/flash-root.png | Bin 3424 -> 0 bytes .../my355/init/res/inject-hook.png | Bin 3449 -> 0 bytes .../my355/init/res/pack-root.png | Bin 3590 -> 0 bytes .../_unmaintained/my355/init/res/prep-env.png | Bin 3945 -> 0 bytes .../_unmaintained/my355/init/res/reboot.png | Bin 3006 -> 0 bytes .../my355/init/res/unpack-root.png | Bin 3846 -> 0 bytes workspace/_unmaintained/my355/install/boot.sh | 40 - .../my355/install/installing.png | Bin 3647 -> 0 bytes .../_unmaintained/my355/install/update.sh | 5 - .../_unmaintained/my355/install/updating.png | Bin 3677 -> 0 bytes .../_unmaintained/my355/keymon/credits.txt | 3 - workspace/_unmaintained/my355/keymon/keymon.c | 207 ---- workspace/_unmaintained/my355/keymon/makefile | 16 - .../_unmaintained/my355/libmsettings/makefile | 32 - .../my355/libmsettings/msettings.c | 258 ---- .../my355/libmsettings/msettings.h | 25 - workspace/_unmaintained/my355/makefile | 47 - .../my355/other/squashfs/makefile | 18 - .../my355/platform/makefile.copy | 16 - .../_unmaintained/my355/platform/makefile.env | 4 - .../_unmaintained/my355/platform/platform.c | 657 ---------- .../_unmaintained/my355/platform/platform.h | 147 --- workspace/_unmaintained/my355/show/makefile | 14 - workspace/_unmaintained/my355/show/show.c | 63 - workspace/_unmaintained/rg35xx/boot/boot.sh | 110 -- .../_unmaintained/rg35xx/boot/boot_logo.png | Bin 2529 -> 0 bytes workspace/_unmaintained/rg35xx/boot/build.sh | 27 - .../_unmaintained/rg35xx/boot/installing.bmp | Bin 614472 -> 0 bytes .../_unmaintained/rg35xx/boot/updating.bmp | Bin 614472 -> 0 bytes workspace/_unmaintained/rg35xx/cores/makefile | 40 - .../rg35xx/cores/patches/fake-08.patch | 34 - .../rg35xx/cores/patches/fceumm.patch | 25 - .../rg35xx/cores/patches/gambatte.patch | 24 - .../rg35xx/cores/patches/gpsp.patch | 30 - .../cores/patches/mednafen_pce_fast.patch | 24 - .../cores/patches/mednafen_supafaust.patch | 31 - .../rg35xx/cores/patches/mednafen_vb.patch | 24 - .../rg35xx/cores/patches/mgba.patch | 31 - .../rg35xx/cores/patches/pcsx_rearmed.patch | 30 - .../rg35xx/cores/patches/picodrive.patch | 28 - .../rg35xx/cores/patches/pokemini.patch | 24 - .../rg35xx/cores/patches/race.patch | 23 - .../cores/patches/snes9x2005_plus.patch | 39 - .../_unmaintained/rg35xx/install/install.sh | 75 -- .../_unmaintained/rg35xx/keymon/credits.txt | 3 - .../_unmaintained/rg35xx/keymon/keymon.c | 168 --- .../_unmaintained/rg35xx/keymon/makefile | 16 - .../rg35xx/libmsettings/makefile | 32 - .../rg35xx/libmsettings/msettings.c | 163 --- .../rg35xx/libmsettings/msettings.h | 25 - workspace/_unmaintained/rg35xx/makefile | 32 - workspace/_unmaintained/rg35xx/other/.keep | 0 .../rg35xx/overclock/credits.txt | 2 - .../_unmaintained/rg35xx/overclock/makefile | 16 - .../rg35xx/overclock/overclock.c | 109 -- .../rg35xx/platform/de_atm7059.h | 154 --- .../_unmaintained/rg35xx/platform/ion-owl.h | 51 - workspace/_unmaintained/rg35xx/platform/ion.h | 240 ---- .../rg35xx/platform/makefile.copy | 14 - .../rg35xx/platform/makefile.env | 4 - .../_unmaintained/rg35xx/platform/platform.c | 603 --------- .../_unmaintained/rg35xx/platform/platform.h | 122 -- .../_unmaintained/rg35xx/ramdisk/charging.png | Bin 3913 -> 0 bytes .../rg35xx/ramdisk/patched-ramdisk.img | Bin 669248 -> 0 bytes .../rg35xx/ramdisk/patched-ramdisk.meta | 3 - .../_unmaintained/rg35xx/ramdisk/readme.txt | 35 - .../_unmaintained/rg35xxplus/boot/boot.sh | 131 -- .../rg35xxplus/boot/bootlogo-r.bmp | Bin 921656 -> 0 bytes .../rg35xxplus/boot/bootlogo-s.bmp | Bin 1555256 -> 0 bytes .../rg35xxplus/boot/bootlogo-w.bmp | Bin 1036856 -> 0 bytes .../rg35xxplus/boot/bootlogo.bmp | Bin 921656 -> 0 bytes .../_unmaintained/rg35xxplus/boot/build.sh | 63 - .../rg35xxplus/boot/installing-r.bmp | Bin 1228856 -> 0 bytes .../rg35xxplus/boot/installing-s.bmp | Bin 2073656 -> 0 bytes .../rg35xxplus/boot/installing-w.bmp | Bin 1382456 -> 0 bytes .../rg35xxplus/boot/installing.bmp | Bin 1228856 -> 0 bytes .../rg35xxplus/boot/updating-r.bmp | Bin 1228856 -> 0 bytes .../rg35xxplus/boot/updating-s.bmp | Bin 2073656 -> 0 bytes .../rg35xxplus/boot/updating-w.bmp | Bin 1382456 -> 0 bytes .../rg35xxplus/boot/updating.bmp | Bin 1228856 -> 0 bytes .../_unmaintained/rg35xxplus/cores/makefile | 4 - .../_unmaintained/rg35xxplus/init/init.c | 6 - .../_unmaintained/rg35xxplus/init/makefile | 15 - .../rg35xxplus/install/install.sh | 51 - .../rg35xxplus/keymon/credits.txt | 3 - .../_unmaintained/rg35xxplus/keymon/keymon.c | 171 --- .../_unmaintained/rg35xxplus/keymon/makefile | 16 - .../rg35xxplus/libmsettings/makefile | 32 - .../rg35xxplus/libmsettings/msettings.c | 201 --- .../rg35xxplus/libmsettings/msettings.h | 25 - workspace/_unmaintained/rg35xxplus/makefile | 82 -- .../rg35xxplus/platform/makefile.copy | 15 - .../rg35xxplus/platform/makefile.env | 4 - .../rg35xxplus/platform/platform.c | 980 --------------- .../rg35xxplus/platform/platform.h | 145 --- .../_unmaintained/rg35xxplus/show/makefile | 14 - .../_unmaintained/rg35xxplus/show/show.c | 63 - workspace/_unmaintained/rgb30/cores/makefile | 40 - .../rgb30/cores/patches/fake-08.patch | 33 - .../rgb30/cores/patches/fceumm.patch | 22 - .../rgb30/cores/patches/gambatte.patch | 23 - .../rgb30/cores/patches/gpsp.patch | 23 - .../cores/patches/mednafen_pce_fast.patch | 25 - .../cores/patches/mednafen_supafaust.patch | 34 - .../rgb30/cores/patches/mednafen_vb.patch | 23 - .../rgb30/cores/patches/mgba.patch | 27 - .../rgb30/cores/patches/pcsx_rearmed.patch | 26 - .../rgb30/cores/patches/picodrive.patch | 22 - .../rgb30/cores/patches/pokemini.patch | 23 - .../rgb30/cores/patches/race.patch | 23 - .../rgb30/cores/patches/snes9x2005_plus.patch | 23 - .../_unmaintained/rgb30/keymon/credits.txt | 3 - workspace/_unmaintained/rgb30/keymon/keymon.c | 182 --- workspace/_unmaintained/rgb30/keymon/makefile | 14 - .../_unmaintained/rgb30/libmsettings/makefile | 32 - .../rgb30/libmsettings/msettings.c | 203 --- .../rgb30/libmsettings/msettings.h | 25 - workspace/_unmaintained/rgb30/makefile | 38 - workspace/_unmaintained/rgb30/other/.keep | 0 .../rgb30/platform/makefile.copy | 7 - .../_unmaintained/rgb30/platform/makefile.env | 4 - .../_unmaintained/rgb30/platform/platform.c | 741 ----------- .../_unmaintained/rgb30/platform/platform.h | 137 --- workspace/_unmaintained/rgb30/show/makefile | 14 - workspace/_unmaintained/rgb30/show/show.c | 43 - .../_unmaintained/trimuismart/cores/makefile | 41 - .../trimuismart/cores/patches/fake-08.patch | 34 - .../trimuismart/cores/patches/fceumm.patch | 28 - .../trimuismart/cores/patches/gambatte.patch | 24 - .../trimuismart/cores/patches/gpsp.patch | 27 - .../cores/patches/mednafen_pce_fast.patch | 29 - .../cores/patches/mednafen_supafaust.patch | 42 - .../cores/patches/mednafen_vb.patch | 29 - .../trimuismart/cores/patches/mgba.patch | 31 - .../cores/patches/pcsx_rearmed.patch | 31 - .../trimuismart/cores/patches/picodrive.patch | 35 - .../trimuismart/cores/patches/pokemini.patch | 27 - .../trimuismart/cores/patches/race.patch | 23 - .../cores/patches/snes9x2005_plus.patch | 36 - .../_unmaintained/trimuismart/install/boot.sh | 40 - .../trimuismart/install/installing.png | Bin 4423 -> 0 bytes .../trimuismart/install/updating.png | Bin 4414 -> 0 bytes .../trimuismart/keymon/credits.txt | 3 - .../_unmaintained/trimuismart/keymon/keymon.c | 104 -- .../_unmaintained/trimuismart/keymon/makefile | 14 - .../trimuismart/libmsettings/makefile | 32 - .../trimuismart/libmsettings/msettings.c | 165 --- .../trimuismart/libmsettings/msettings.h | 25 - .../trimuismart/libmsettings/sunxi_display2.h | 521 -------- workspace/_unmaintained/trimuismart/makefile | 34 - .../_unmaintained/trimuismart/other/.keep | 0 .../_unmaintained/trimuismart/platform/ion.h | 376 ------ .../trimuismart/platform/ion_sunxi.h | 105 -- .../trimuismart/platform/makefile.copy | 13 - .../trimuismart/platform/makefile.env | 3 - .../trimuismart/platform/platform.c | 538 -------- .../trimuismart/platform/platform.h | 122 -- .../trimuismart/platform/sunxi_display2.h | 521 -------- .../_unmaintained/trimuismart/show/makefile | 15 - .../_unmaintained/trimuismart/show/show.c | 39 - .../_unmaintained/zero28/bl/bl_disable.c | 16 - workspace/_unmaintained/zero28/bl/bl_enable.c | 16 - workspace/_unmaintained/zero28/bl/makefile | 15 - workspace/_unmaintained/zero28/cores/makefile | 4 - .../_unmaintained/zero28/install/boot.sh | 37 - .../zero28/install/installing.png | Bin 3647 -> 0 bytes .../_unmaintained/zero28/install/update.sh | 5 - .../_unmaintained/zero28/install/updating.png | Bin 3677 -> 0 bytes .../_unmaintained/zero28/keymon/credits.txt | 3 - .../_unmaintained/zero28/keymon/keymon.c | 163 --- .../_unmaintained/zero28/keymon/makefile | 16 - .../zero28/libmsettings/makefile | 29 - .../zero28/libmsettings/msettings.c | 237 ---- .../zero28/libmsettings/msettings.h | 25 - workspace/_unmaintained/zero28/makefile | 33 - .../zero28/platform/makefile.copy | 15 - .../zero28/platform/makefile.env | 4 - .../_unmaintained/zero28/platform/platform.c | 578 --------- .../_unmaintained/zero28/platform/platform.h | 136 --- workspace/_unmaintained/zero28/show/makefile | 14 - workspace/_unmaintained/zero28/show/show.c | 63 - 969 files changed, 33014 deletions(-) delete mode 100644 github/README.md delete mode 100755 github/generate_screenshots.sh delete mode 100644 github/logo.png delete mode 100644 github/logo_outline.png delete mode 100644 github/minui-clock.png delete mode 100644 github/minui-main.png delete mode 100644 github/minui-menu-gbc.png delete mode 100644 github/minui-menu-md.png delete mode 100644 github/minui-menu-options-controls.png delete mode 100644 github/minui-menu-options-core.png delete mode 100644 github/minui-menu-options-frontend.png delete mode 100644 github/minui-menu-options-shortcuts.png delete mode 100644 github/minui-menu-p8.png delete mode 100644 github/minui-menu-ps.png delete mode 100644 github/minui-menu-sfc.png delete mode 100644 github/minui-menu-sgb.png delete mode 100644 github/minui-menu-vb.png delete mode 100755 skeleton/_unmaintained/BOOT/magicx/init.sh delete mode 100755 skeleton/_unmaintained/BOOT/miyoo/app/MainUI delete mode 100755 skeleton/_unmaintained/BOOT/miyoo/app/keymon delete mode 100755 skeleton/_unmaintained/BOOT/miyoo/app/miyoomini.sh delete mode 100755 skeleton/_unmaintained/BOOT/miyoo/app/my282.sh delete mode 100755 skeleton/_unmaintained/BOOT/miyoo/app/my355.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/GG.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/GG.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/MGBA.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/MGBA.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/NGP.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/NGP.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/NGPC.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/NGPC.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/PCE.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/PCE.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/PKM.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/PKM.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/SGB.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/SGB.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/SMS.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/SMS.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/m17/GG.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/m17/GG.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/m17/MGBA.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/m17/MGBA.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/m17/NGP.pak/default.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/m17/NGP.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/m17/NGPC.pak/default.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/m17/NGPC.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/m17/P8.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/m17/P8.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/m17/PCE.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/m17/PCE.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/m17/PKM.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/m17/PKM.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/m17/SGB.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/m17/SGB.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/m17/SMS.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/m17/SMS.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/m17/SUPA.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/m17/SUPA.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/m17/VB.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/m17/VB.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/magicmini/GG.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/magicmini/GG.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/magicmini/MGBA.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/magicmini/MGBA.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/magicmini/NGP.pak/default.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/magicmini/NGP.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/magicmini/NGPC.pak/default.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/magicmini/NGPC.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/magicmini/P8.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/magicmini/P8.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/magicmini/PCE.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/magicmini/PCE.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/magicmini/PKM.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/magicmini/PKM.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/magicmini/SGB.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/magicmini/SGB.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/magicmini/SMS.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/magicmini/SMS.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/magicmini/SUPA.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/magicmini/SUPA.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/magicmini/VB.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/magicmini/VB.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/miyoomini/GG.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/miyoomini/GG.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/miyoomini/MGBA.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/miyoomini/MGBA.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/miyoomini/NGP.pak/default.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/miyoomini/NGP.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/miyoomini/NGPC.pak/default.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/miyoomini/NGPC.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/miyoomini/P8.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/miyoomini/P8.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/miyoomini/PCE.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/miyoomini/PCE.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/miyoomini/PKM.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/miyoomini/PKM.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/miyoomini/SGB.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/miyoomini/SGB.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/miyoomini/SMS.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/miyoomini/SMS.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/miyoomini/SUPA.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/miyoomini/SUPA.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/miyoomini/VB.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/miyoomini/VB.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/my282/GG.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/my282/GG.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/my282/MGBA.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/my282/MGBA.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/my282/NGP.pak/default.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/my282/NGP.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/my282/NGPC.pak/default.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/my282/NGPC.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/my282/P8.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/my282/P8.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/my282/PCE.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/my282/PCE.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/my282/PKM.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/my282/PKM.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/my282/SGB.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/my282/SGB.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/my282/SMS.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/my282/SMS.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/my282/SUPA.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/my282/SUPA.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/my282/VB.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/my282/VB.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/my355/GG.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/my355/GG.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/my355/MGBA.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/my355/MGBA.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/my355/NGP.pak/default.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/my355/NGP.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/my355/NGPC.pak/default.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/my355/NGPC.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/my355/P8.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/my355/P8.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/my355/PCE.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/my355/PCE.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/my355/PKM.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/my355/PKM.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/my355/SGB.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/my355/SGB.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/my355/SMS.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/my355/SMS.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/my355/SUPA.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/my355/SUPA.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/my355/VB.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/my355/VB.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xx/GG.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rg35xx/GG.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xx/MGBA.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rg35xx/MGBA.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xx/NGP.pak/default.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xx/NGP.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xx/NGPC.pak/default.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xx/NGPC.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xx/P8.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rg35xx/P8.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xx/PCE.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rg35xx/PCE.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xx/PKM.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rg35xx/PKM.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xx/SGB.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rg35xx/SGB.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xx/SMS.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rg35xx/SMS.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xx/SUPA.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rg35xx/SUPA.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xx/VB.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rg35xx/VB.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/GG.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/GG.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/MGBA.pak/default-cube.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/MGBA.pak/default-wide.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/MGBA.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/MGBA.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/NGP.pak/default-cube.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/NGP.pak/default.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/NGP.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/NGPC.pak/default-cube.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/NGPC.pak/default.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/NGPC.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/P8.pak/default-cube.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/P8.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/P8.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/PCE.pak/default-cube.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/PCE.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/PCE.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/PKM.pak/default-cube.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/PKM.pak/default-wide.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/PKM.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/PKM.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SGB.pak/default-cube.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SGB.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SGB.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SMS.pak/default-cube.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SMS.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SMS.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SUPA.pak/default-cube.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SUPA.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SUPA.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/VB.pak/default-cube.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/VB.pak/default-wide.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/VB.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/VB.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rgb30/GG.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rgb30/GG.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rgb30/MGBA.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rgb30/MGBA.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rgb30/NGP.pak/default.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rgb30/NGP.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rgb30/NGPC.pak/default.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rgb30/NGPC.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rgb30/P8-NATIVE.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rgb30/P8-NATIVE.pak/missing.png delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rgb30/P8.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rgb30/P8.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rgb30/PCE.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rgb30/PCE.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rgb30/PKM.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rgb30/PKM.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rgb30/SGB.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rgb30/SGB.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/rgb30/SMS.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rgb30/SMS.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rgb30/SUPA.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rgb30/SUPA.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rgb30/VB.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/rgb30/VB.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/trimuismart/GG.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/trimuismart/GG.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/trimuismart/MGBA.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/trimuismart/MGBA.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/trimuismart/NGP.pak/default.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/trimuismart/NGP.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/trimuismart/NGPC.pak/default.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/trimuismart/NGPC.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/trimuismart/P8.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/trimuismart/P8.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/trimuismart/PCE.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/trimuismart/PCE.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/trimuismart/PKM.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/trimuismart/PKM.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/trimuismart/SGB.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/trimuismart/SGB.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/trimuismart/SMS.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/trimuismart/SMS.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/trimuismart/SUPA.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/trimuismart/SUPA.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/trimuismart/VB.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/trimuismart/VB.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/zero28/GG.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/zero28/GG.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/zero28/MGBA.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/zero28/MGBA.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/zero28/NGP.pak/default.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/zero28/NGP.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/zero28/NGPC.pak/default.cfg delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/zero28/NGPC.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/zero28/P8.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/zero28/P8.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/zero28/PCE.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/zero28/PCE.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/zero28/PKM.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/zero28/PKM.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/zero28/SGB.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/zero28/SGB.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/zero28/SMS.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/zero28/SMS.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/zero28/SUPA.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/zero28/SUPA.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Emus/zero28/VB.pak/default.cfg delete mode 100755 skeleton/_unmaintained/EXTRAS/Emus/zero28/VB.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/gkdpixel/Clock.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/gkdpixel/Files.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/gkdpixel/Input.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/m17/Bootlogo.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/m17/Bootlogo.pak/logo.bmp delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/m17/Bootlogo.pak/original.bmp delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/m17/Clock.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/m17/Input.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/magicmini/Clock.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/magicmini/Files.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/magicmini/Input.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/miyoomini/Bootlogo.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/miyoomini/Clock.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/miyoomini/Files.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/miyoomini/Input.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/my282/Bootlogo.pak/bootlogo.bmp delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/my282/Bootlogo.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/my282/Bootlogo.pak/res/abort.png delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/my282/Bootlogo.pak/res/missing.png delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/my282/Bootlogo.pak/res/offset-20240401221906 delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/my282/Bootlogo.pak/res/offset-20240426150228 delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/my282/Bootlogo.pak/res/offset-20240516174101 delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/my282/Bootlogo.pak/res/offset-20240713100458 delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/my282/Bootlogo.pak/res/simplify.png delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/my282/Bootlogo.pak/res/updating.png delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/my282/Clock.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/my282/Files.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/my282/Input.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/my282/Remove Loading.pak/abort.png delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/my282/Remove Loading.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/my282/Remove Loading.pak/patch.png delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/my282/Reset Stick.pak/calibrate.png delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/my282/Reset Stick.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/apply.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/payload/logo-original.bmp delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/payload/logo.bmp delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/res/extract-img.png delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/res/flash-img.png delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/res/pack-img.png delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/res/pack-res.png delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/res/prep-env.png delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/res/reboot.png delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/res/replace-logo.png delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/res/unpack-img.png delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/res/unpack-res.png delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/my355/Clock.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/my355/Files.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/my355/Input.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/rg35xx/Clock.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/rg35xx/Files.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/rg35xx/Input.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Apply Panel Fix.pak/apply.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Apply Panel Fix.pak/bin/.keep delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Apply Panel Fix.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Apply Panel Fix.pak/res/applying.png delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Apply Panel Fix.pak/res/fail.png delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Apply Panel Fix.pak/res/mismatch.png delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Apply Panel Fix.pak/res/patched.png delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Apply Panel Fix.pak/res/preparing.png delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Apply Panel Fix.pak/res/rebooting.png delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Apply Panel Fix.pak/res/unknown.png delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Apply Panel Fix.pak/res/verifying.png delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Clock.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Enable SSH.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Enable SSH.pak/ssh.png delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Enable SSH.pak/wifi.png delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Files.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Files.pak/missing.png delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Input.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Swap Menu.pak/apply.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Swap Menu.pak/bin/.keep delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Swap Menu.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Swap Menu.pak/res/applying.png delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Swap Menu.pak/res/fail.png delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Swap Menu.pak/res/preparing.png delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/rgb30/Clock.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/rgb30/Files.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/rgb30/Input.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/rgb30/Splore.pak/extracting.png delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/rgb30/Splore.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/rgb30/Splore.pak/missing.png delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/rgb30/Splore.pak/sdl_controllers.txt delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/rgb30/Wi-Fi.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/rgb30/Wi-Fi.pak/res/disable.png delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/rgb30/Wi-Fi.pak/res/enable.png delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/rgb30/Wi-Fi.pak/res/update.png delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/rgb30/Wi-Fi.pak/wifi.txt delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/trimuismart/Bootlogo.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/trimuismart/Clock.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/trimuismart/Files.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/trimuismart/Input.pak/launch.sh delete mode 100644 skeleton/_unmaintained/EXTRAS/Tools/zero28/Bootlogo.pak/bootlogo.bmp delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/zero28/Bootlogo.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/zero28/Clock.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/zero28/Files.pak/launch.sh delete mode 100755 skeleton/_unmaintained/EXTRAS/Tools/zero28/Input.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/gkdpixel/bin/shutdown delete mode 100644 skeleton/_unmaintained/SYSTEM/gkdpixel/cores/.keep delete mode 100644 skeleton/_unmaintained/SYSTEM/gkdpixel/dat/.keep delete mode 100644 skeleton/_unmaintained/SYSTEM/gkdpixel/lib/.keep delete mode 100755 skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/FC.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/FC.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/GB.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/GB.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/GBA.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/GBA.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/GBC.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/GBC.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/MD.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/MD.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/PS.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/PS.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/SFC.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/SFC.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/gkdpixel/paks/MinUI.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/gkdpixel/system.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/m17/bin/shutdown delete mode 100755 skeleton/_unmaintained/SYSTEM/m17/bin/start_adbd.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/m17/cores/.keep delete mode 100644 skeleton/_unmaintained/SYSTEM/m17/dat/.keep delete mode 100644 skeleton/_unmaintained/SYSTEM/m17/lib/.keep delete mode 100755 skeleton/_unmaintained/SYSTEM/m17/paks/Emus/FC.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/m17/paks/Emus/FC.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/m17/paks/Emus/GB.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/m17/paks/Emus/GB.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/m17/paks/Emus/GBA.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/m17/paks/Emus/GBA.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/m17/paks/Emus/GBC.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/m17/paks/Emus/GBC.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/m17/paks/Emus/MD.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/m17/paks/Emus/MD.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/m17/paks/Emus/PS.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/m17/paks/Emus/PS.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/m17/paks/Emus/SFC.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/m17/paks/Emus/SFC.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/m17/paks/MinUI.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/m17/system.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/magicmini/bin/shutdown delete mode 100644 skeleton/_unmaintained/SYSTEM/magicmini/cores/.keep delete mode 100644 skeleton/_unmaintained/SYSTEM/magicmini/dat/.keep delete mode 100644 skeleton/_unmaintained/SYSTEM/magicmini/lib/.keep delete mode 100644 skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/FC.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/FC.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/GB.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/GB.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/GBA.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/GBA.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/GBC.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/GBC.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/MD.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/MD.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/PS.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/PS.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/SFC.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/SFC.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/magicmini/paks/MinUI.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/magicmini/system.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/miyoomini/bin/needs-swap delete mode 100755 skeleton/_unmaintained/SYSTEM/miyoomini/bin/shutdown delete mode 100644 skeleton/_unmaintained/SYSTEM/miyoomini/cores/.keep delete mode 100755 skeleton/_unmaintained/SYSTEM/miyoomini/dat/image1.jpg delete mode 100644 skeleton/_unmaintained/SYSTEM/miyoomini/lib/.keep delete mode 100644 skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/FC.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/FC.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/GB.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/GB.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/GBA.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/GBA.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/GBC.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/GBC.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/MD.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/MD.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/PS.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/PS.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/SFC.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/SFC.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/miyoomini/paks/MinUI.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/miyoomini/system.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/my282/bin/setterm delete mode 100755 skeleton/_unmaintained/SYSTEM/my282/bin/shutdown delete mode 100644 skeleton/_unmaintained/SYSTEM/my282/cores/.keep delete mode 100644 skeleton/_unmaintained/SYSTEM/my282/dat/.keep delete mode 100644 skeleton/_unmaintained/SYSTEM/my282/lib/.keep delete mode 100644 skeleton/_unmaintained/SYSTEM/my282/paks/Emus/FC.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/my282/paks/Emus/FC.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/my282/paks/Emus/GB.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/my282/paks/Emus/GB.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/my282/paks/Emus/GBA.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/my282/paks/Emus/GBA.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/my282/paks/Emus/GBC.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/my282/paks/Emus/GBC.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/my282/paks/Emus/MD.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/my282/paks/Emus/MD.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/my282/paks/Emus/PS.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/my282/paks/Emus/PS.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/my282/paks/Emus/SFC.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/my282/paks/Emus/SFC.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/my282/paks/MinUI.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/my282/system.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/my355/bin/shutdown delete mode 100644 skeleton/_unmaintained/SYSTEM/my355/cores/.keep delete mode 100644 skeleton/_unmaintained/SYSTEM/my355/dat/.keep delete mode 100644 skeleton/_unmaintained/SYSTEM/my355/lib/.keep delete mode 100755 skeleton/_unmaintained/SYSTEM/my355/paks/Emus/FC.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/my355/paks/Emus/FC.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/my355/paks/Emus/GB.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/my355/paks/Emus/GB.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/my355/paks/Emus/GBA.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/my355/paks/Emus/GBA.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/my355/paks/Emus/GBC.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/my355/paks/Emus/GBC.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/my355/paks/Emus/MD.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/my355/paks/Emus/MD.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/my355/paks/Emus/PS.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/my355/paks/Emus/PS.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/my355/paks/Emus/SFC.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/my355/paks/Emus/SFC.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/my355/paks/MinUI.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/my355/system.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/rg35xx/bin/shutdown delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xx/cores/.keep delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xx/dat/.keep delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xx/lib/.keep delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/FC.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/FC.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/GB.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/GB.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/GBA.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/GBA.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/GBC.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/GBC.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/MD.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/MD.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/PS.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/PS.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/SFC.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/SFC.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/rg35xx/paks/MinUI.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xx/system.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/rg35xxplus/bin/hdmimon.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/rg35xxplus/bin/shutdown delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xxplus/cores/.keep delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xxplus/dat/.keep delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xxplus/lib/.keep delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/FC.pak/default-cube.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/FC.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/FC.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GB.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GB.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GBA.pak/default-cube.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GBA.pak/default-wide.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GBA.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GBA.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GBC.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GBC.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/MD.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/MD.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/PS.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/PS.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/SFC.pak/default-cube.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/SFC.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/SFC.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/MinUI.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/rg35xxplus/system.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/rgb30/bin/shutdown delete mode 100644 skeleton/_unmaintained/SYSTEM/rgb30/cores/.keep delete mode 100644 skeleton/_unmaintained/SYSTEM/rgb30/dat/.keep delete mode 100644 skeleton/_unmaintained/SYSTEM/rgb30/lib/.keep delete mode 100644 skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/FC.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/FC.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/GB.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/GB.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/GBA.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/GBA.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/GBC.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/GBC.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/MD.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/MD.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/PS.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/PS.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/SFC.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/SFC.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/rgb30/paks/MinUI.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/rgb30/system.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/trimuismart/bin/leds_off delete mode 100755 skeleton/_unmaintained/SYSTEM/trimuismart/bin/leds_on delete mode 100755 skeleton/_unmaintained/SYSTEM/trimuismart/bin/shutdown delete mode 100644 skeleton/_unmaintained/SYSTEM/trimuismart/cores/.keep delete mode 100644 skeleton/_unmaintained/SYSTEM/trimuismart/dat/logo.bmp delete mode 100644 skeleton/_unmaintained/SYSTEM/trimuismart/lib/.keep delete mode 100644 skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/FC.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/FC.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/GB.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/GB.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/GBA.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/GBA.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/GBC.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/GBC.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/MD.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/MD.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/PS.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/PS.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/SFC.pak/default.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/SFC.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/trimuismart/paks/MinUI.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/trimuismart/system.cfg delete mode 100755 skeleton/_unmaintained/SYSTEM/zero28/bin/setterm delete mode 100755 skeleton/_unmaintained/SYSTEM/zero28/bin/shutdown delete mode 100755 skeleton/_unmaintained/SYSTEM/zero28/bin/suspend delete mode 100644 skeleton/_unmaintained/SYSTEM/zero28/cores/.keep delete mode 100644 skeleton/_unmaintained/SYSTEM/zero28/dat/.keep delete mode 100644 skeleton/_unmaintained/SYSTEM/zero28/lib/.keep delete mode 100644 skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/FC.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/FC.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/GB.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/GB.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/GBA.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/GBA.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/GBC.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/GBC.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/MD.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/MD.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/PS.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/PS.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/SFC.pak/default.cfg delete mode 100644 skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/SFC.pak/launch.sh delete mode 100755 skeleton/_unmaintained/SYSTEM/zero28/paks/MinUI.pak/launch.sh delete mode 100644 skeleton/_unmaintained/SYSTEM/zero28/system.cfg delete mode 100755 workspace/_unmaintained/gkdpixel/boot/boot.sh delete mode 100755 workspace/_unmaintained/gkdpixel/boot/install.sh delete mode 100644 workspace/_unmaintained/gkdpixel/boot/installing.bmp delete mode 100644 workspace/_unmaintained/gkdpixel/boot/updating.bmp delete mode 100644 workspace/_unmaintained/gkdpixel/cores/makefile delete mode 100644 workspace/_unmaintained/gkdpixel/cores/patches/pcsx_rearmed.patch delete mode 100644 workspace/_unmaintained/gkdpixel/input/input.c delete mode 100755 workspace/_unmaintained/gkdpixel/input/input.txt delete mode 100755 workspace/_unmaintained/gkdpixel/input/makefile delete mode 100755 workspace/_unmaintained/gkdpixel/install/install.sh delete mode 100644 workspace/_unmaintained/gkdpixel/keymon/credits.txt delete mode 100644 workspace/_unmaintained/gkdpixel/keymon/keymon.c delete mode 100755 workspace/_unmaintained/gkdpixel/keymon/makefile delete mode 100644 workspace/_unmaintained/gkdpixel/libmsettings/makefile delete mode 100644 workspace/_unmaintained/gkdpixel/libmsettings/msettings.c delete mode 100644 workspace/_unmaintained/gkdpixel/libmsettings/msettings.h delete mode 100644 workspace/_unmaintained/gkdpixel/makefile delete mode 100644 workspace/_unmaintained/gkdpixel/platform/makefile.copy delete mode 100644 workspace/_unmaintained/gkdpixel/platform/makefile.env delete mode 100644 workspace/_unmaintained/gkdpixel/platform/platform.c delete mode 100644 workspace/_unmaintained/gkdpixel/platform/platform.h delete mode 100644 workspace/_unmaintained/gkdpixel/test/main.c delete mode 100755 workspace/_unmaintained/gkdpixel/test/makefile delete mode 100755 workspace/_unmaintained/m17/boot/boot.sh delete mode 100755 workspace/_unmaintained/m17/boot/build.sh delete mode 100644 workspace/_unmaintained/m17/boot/installing.bmp delete mode 100644 workspace/_unmaintained/m17/boot/notes.txt delete mode 100644 workspace/_unmaintained/m17/boot/updating.bmp delete mode 100644 workspace/_unmaintained/m17/cores/makefile delete mode 100644 workspace/_unmaintained/m17/cores/patches/fake-08.patch delete mode 100644 workspace/_unmaintained/m17/cores/patches/fceumm.patch delete mode 100644 workspace/_unmaintained/m17/cores/patches/gambatte.patch delete mode 100644 workspace/_unmaintained/m17/cores/patches/gpsp.patch delete mode 100644 workspace/_unmaintained/m17/cores/patches/mednafen_pce_fast.patch delete mode 100644 workspace/_unmaintained/m17/cores/patches/mednafen_supafaust.patch delete mode 100644 workspace/_unmaintained/m17/cores/patches/mednafen_vb.patch delete mode 100644 workspace/_unmaintained/m17/cores/patches/mgba.patch delete mode 100644 workspace/_unmaintained/m17/cores/patches/pcsx_rearmed.patch delete mode 100644 workspace/_unmaintained/m17/cores/patches/picodrive.patch delete mode 100644 workspace/_unmaintained/m17/cores/patches/pokemini.patch delete mode 100644 workspace/_unmaintained/m17/cores/patches/race.patch delete mode 100644 workspace/_unmaintained/m17/cores/patches/snes9x2005_plus.patch delete mode 100755 workspace/_unmaintained/m17/install/install.sh delete mode 100644 workspace/_unmaintained/m17/keymon/credits.txt delete mode 100644 workspace/_unmaintained/m17/keymon/keymon.c delete mode 100755 workspace/_unmaintained/m17/keymon/makefile delete mode 100644 workspace/_unmaintained/m17/libmsettings/makefile delete mode 100644 workspace/_unmaintained/m17/libmsettings/msettings.c delete mode 100644 workspace/_unmaintained/m17/libmsettings/msettings.h delete mode 100644 workspace/_unmaintained/m17/makefile delete mode 100644 workspace/_unmaintained/m17/platform/makefile.copy delete mode 100644 workspace/_unmaintained/m17/platform/makefile.env delete mode 100644 workspace/_unmaintained/m17/platform/platform.c delete mode 100644 workspace/_unmaintained/m17/platform/platform.h delete mode 100644 workspace/_unmaintained/magicmini/cores/makefile delete mode 100644 workspace/_unmaintained/magicmini/cores/patches/fake-08.patch delete mode 100644 workspace/_unmaintained/magicmini/cores/patches/fceumm.patch delete mode 100644 workspace/_unmaintained/magicmini/cores/patches/gambatte.patch delete mode 100644 workspace/_unmaintained/magicmini/cores/patches/gpsp.patch delete mode 100644 workspace/_unmaintained/magicmini/cores/patches/mednafen_pce_fast.patch delete mode 100644 workspace/_unmaintained/magicmini/cores/patches/mednafen_supafaust.patch delete mode 100644 workspace/_unmaintained/magicmini/cores/patches/mednafen_vb.patch delete mode 100644 workspace/_unmaintained/magicmini/cores/patches/mgba.patch delete mode 100644 workspace/_unmaintained/magicmini/cores/patches/pcsx_rearmed.patch delete mode 100644 workspace/_unmaintained/magicmini/cores/patches/picodrive.patch delete mode 100644 workspace/_unmaintained/magicmini/cores/patches/pokemini.patch delete mode 100644 workspace/_unmaintained/magicmini/cores/patches/race.patch delete mode 100644 workspace/_unmaintained/magicmini/cores/patches/snes9x2005_plus.patch delete mode 100755 workspace/_unmaintained/magicmini/install/boot.sh delete mode 100755 workspace/_unmaintained/magicmini/install/installing.bmp delete mode 100644 workspace/_unmaintained/magicmini/install/notes.txt delete mode 100755 workspace/_unmaintained/magicmini/install/update.sh delete mode 100755 workspace/_unmaintained/magicmini/install/updating.bmp delete mode 100644 workspace/_unmaintained/magicmini/keymon/credits.txt delete mode 100644 workspace/_unmaintained/magicmini/keymon/keymon.c delete mode 100755 workspace/_unmaintained/magicmini/keymon/makefile delete mode 100644 workspace/_unmaintained/magicmini/libmsettings/makefile delete mode 100644 workspace/_unmaintained/magicmini/libmsettings/msettings.c delete mode 100644 workspace/_unmaintained/magicmini/libmsettings/msettings.h delete mode 100644 workspace/_unmaintained/magicmini/makefile delete mode 100644 workspace/_unmaintained/magicmini/platform/makefile.copy delete mode 100644 workspace/_unmaintained/magicmini/platform/makefile.env delete mode 100644 workspace/_unmaintained/magicmini/platform/platform.c delete mode 100644 workspace/_unmaintained/magicmini/platform/platform.h delete mode 100644 workspace/_unmaintained/miyoomini/batmon/batmon.c delete mode 100644 workspace/_unmaintained/miyoomini/batmon/makefile delete mode 100644 workspace/_unmaintained/miyoomini/blank/blank.c delete mode 100644 workspace/_unmaintained/miyoomini/blank/makefile delete mode 100644 workspace/_unmaintained/miyoomini/cores/makefile delete mode 100644 workspace/_unmaintained/miyoomini/cores/patches/fake-08.patch delete mode 100644 workspace/_unmaintained/miyoomini/cores/patches/fceumm.patch delete mode 100644 workspace/_unmaintained/miyoomini/cores/patches/gambatte.patch delete mode 100644 workspace/_unmaintained/miyoomini/cores/patches/gpsp.patch delete mode 100644 workspace/_unmaintained/miyoomini/cores/patches/mednafen_pce_fast.patch delete mode 100644 workspace/_unmaintained/miyoomini/cores/patches/mednafen_supafaust.patch delete mode 100644 workspace/_unmaintained/miyoomini/cores/patches/mednafen_vb.patch delete mode 100644 workspace/_unmaintained/miyoomini/cores/patches/mgba.patch delete mode 100644 workspace/_unmaintained/miyoomini/cores/patches/pcsx_rearmed.patch delete mode 100644 workspace/_unmaintained/miyoomini/cores/patches/picodrive.patch delete mode 100644 workspace/_unmaintained/miyoomini/cores/patches/pokemini.patch delete mode 100644 workspace/_unmaintained/miyoomini/cores/patches/race.patch delete mode 100644 workspace/_unmaintained/miyoomini/cores/patches/snes9x2005_plus.patch delete mode 100755 workspace/_unmaintained/miyoomini/install/boot.sh delete mode 100644 workspace/_unmaintained/miyoomini/install/installing.png delete mode 100755 workspace/_unmaintained/miyoomini/install/update.sh delete mode 100644 workspace/_unmaintained/miyoomini/install/updating.png delete mode 100644 workspace/_unmaintained/miyoomini/keymon/credits.txt delete mode 100644 workspace/_unmaintained/miyoomini/keymon/keymon.c delete mode 100755 workspace/_unmaintained/miyoomini/keymon/makefile delete mode 100644 workspace/_unmaintained/miyoomini/libmsettings/makefile delete mode 100644 workspace/_unmaintained/miyoomini/libmsettings/msettings.c delete mode 100644 workspace/_unmaintained/miyoomini/libmsettings/msettings.h delete mode 100644 workspace/_unmaintained/miyoomini/lumon/lumon.c delete mode 100644 workspace/_unmaintained/miyoomini/lumon/makefile delete mode 100644 workspace/_unmaintained/miyoomini/makefile delete mode 100644 workspace/_unmaintained/miyoomini/other/.keep delete mode 100644 workspace/_unmaintained/miyoomini/other/latency_reduction/Makefile delete mode 100755 workspace/_unmaintained/miyoomini/other/latency_reduction/audioserver.mod delete mode 100644 workspace/_unmaintained/miyoomini/other/latency_reduction/credits.txt delete mode 100644 workspace/_unmaintained/miyoomini/other/latency_reduction/main.c delete mode 100644 workspace/_unmaintained/miyoomini/other/logotweak/credits.txt delete mode 100644 workspace/_unmaintained/miyoomini/other/logotweak/logomake.c delete mode 100644 workspace/_unmaintained/miyoomini/other/logotweak/logoread.c delete mode 100644 workspace/_unmaintained/miyoomini/other/logotweak/logowrite.c delete mode 100644 workspace/_unmaintained/miyoomini/other/logotweak/makefile delete mode 100644 workspace/_unmaintained/miyoomini/other/screenshot/Makefile delete mode 100644 workspace/_unmaintained/miyoomini/other/screenshot/credits.txt delete mode 100644 workspace/_unmaintained/miyoomini/other/screenshot/main.c delete mode 100644 workspace/_unmaintained/miyoomini/overclock/credits.txt delete mode 100755 workspace/_unmaintained/miyoomini/overclock/makefile delete mode 100644 workspace/_unmaintained/miyoomini/overclock/overclock.c delete mode 100644 workspace/_unmaintained/miyoomini/platform/makefile.copy delete mode 100644 workspace/_unmaintained/miyoomini/platform/makefile.env delete mode 100644 workspace/_unmaintained/miyoomini/platform/platform.c delete mode 100644 workspace/_unmaintained/miyoomini/platform/platform.h delete mode 100644 workspace/_unmaintained/miyoomini/show/makefile delete mode 100644 workspace/_unmaintained/miyoomini/show/show.c delete mode 100644 workspace/_unmaintained/my282/cores/makefile delete mode 100755 workspace/_unmaintained/my282/install/boot.sh delete mode 100644 workspace/_unmaintained/my282/install/installing.png delete mode 100755 workspace/_unmaintained/my282/install/update.sh delete mode 100644 workspace/_unmaintained/my282/install/updating.png delete mode 100644 workspace/_unmaintained/my282/keymon/credits.txt delete mode 100644 workspace/_unmaintained/my282/keymon/keymon.c delete mode 100755 workspace/_unmaintained/my282/keymon/makefile delete mode 100644 workspace/_unmaintained/my282/libmsettings/makefile delete mode 100644 workspace/_unmaintained/my282/libmsettings/msettings.c delete mode 100644 workspace/_unmaintained/my282/libmsettings/msettings.h delete mode 100644 workspace/_unmaintained/my282/libmstick/makefile delete mode 100644 workspace/_unmaintained/my282/libmstick/mstick.c delete mode 100644 workspace/_unmaintained/my282/libmstick/mstick.h delete mode 100644 workspace/_unmaintained/my282/makefile delete mode 100644 workspace/_unmaintained/my282/other/squashfs/makefile delete mode 100644 workspace/_unmaintained/my282/overclock/credits.txt delete mode 100755 workspace/_unmaintained/my282/overclock/makefile delete mode 100644 workspace/_unmaintained/my282/overclock/overclock.c delete mode 100644 workspace/_unmaintained/my282/platform/makefile.copy delete mode 100644 workspace/_unmaintained/my282/platform/makefile.env delete mode 100644 workspace/_unmaintained/my282/platform/platform.c delete mode 100644 workspace/_unmaintained/my282/platform/platform.h delete mode 100755 workspace/_unmaintained/my282/show/makefile delete mode 100644 workspace/_unmaintained/my282/show/show.c delete mode 100644 workspace/_unmaintained/my282/tests/brightness/brightness.c delete mode 100755 workspace/_unmaintained/my282/tests/brightness/makefile delete mode 100644 workspace/_unmaintained/my282/tests/calibrate/calibrate.c delete mode 100755 workspace/_unmaintained/my282/tests/calibrate/makefile delete mode 100755 workspace/_unmaintained/my282/tests/volume/makefile delete mode 100644 workspace/_unmaintained/my282/tests/volume/volume.c delete mode 100644 workspace/_unmaintained/my355/cores/makefile delete mode 100644 workspace/_unmaintained/my355/cores/patches/fake-08.patch delete mode 100644 workspace/_unmaintained/my355/cores/patches/fceumm.patch delete mode 100644 workspace/_unmaintained/my355/cores/patches/gambatte.patch delete mode 100644 workspace/_unmaintained/my355/cores/patches/gpsp.patch delete mode 100644 workspace/_unmaintained/my355/cores/patches/mednafen_pce_fast.patch delete mode 100644 workspace/_unmaintained/my355/cores/patches/mednafen_supafaust.patch delete mode 100644 workspace/_unmaintained/my355/cores/patches/mednafen_vb.patch delete mode 100644 workspace/_unmaintained/my355/cores/patches/mgba.patch delete mode 100644 workspace/_unmaintained/my355/cores/patches/pcsx_rearmed.patch delete mode 100644 workspace/_unmaintained/my355/cores/patches/picodrive.patch delete mode 100644 workspace/_unmaintained/my355/cores/patches/pokemini.patch delete mode 100644 workspace/_unmaintained/my355/cores/patches/race.patch delete mode 100644 workspace/_unmaintained/my355/cores/patches/snes9x2005_plus.patch delete mode 100755 workspace/_unmaintained/my355/init/init.sh delete mode 100755 workspace/_unmaintained/my355/init/payload/runmiyoo.sh delete mode 100644 workspace/_unmaintained/my355/init/res/extract-root.png delete mode 100644 workspace/_unmaintained/my355/init/res/flash-root.png delete mode 100644 workspace/_unmaintained/my355/init/res/inject-hook.png delete mode 100644 workspace/_unmaintained/my355/init/res/pack-root.png delete mode 100644 workspace/_unmaintained/my355/init/res/prep-env.png delete mode 100644 workspace/_unmaintained/my355/init/res/reboot.png delete mode 100644 workspace/_unmaintained/my355/init/res/unpack-root.png delete mode 100755 workspace/_unmaintained/my355/install/boot.sh delete mode 100644 workspace/_unmaintained/my355/install/installing.png delete mode 100755 workspace/_unmaintained/my355/install/update.sh delete mode 100644 workspace/_unmaintained/my355/install/updating.png delete mode 100644 workspace/_unmaintained/my355/keymon/credits.txt delete mode 100644 workspace/_unmaintained/my355/keymon/keymon.c delete mode 100755 workspace/_unmaintained/my355/keymon/makefile delete mode 100644 workspace/_unmaintained/my355/libmsettings/makefile delete mode 100644 workspace/_unmaintained/my355/libmsettings/msettings.c delete mode 100644 workspace/_unmaintained/my355/libmsettings/msettings.h delete mode 100644 workspace/_unmaintained/my355/makefile delete mode 100644 workspace/_unmaintained/my355/other/squashfs/makefile delete mode 100644 workspace/_unmaintained/my355/platform/makefile.copy delete mode 100644 workspace/_unmaintained/my355/platform/makefile.env delete mode 100644 workspace/_unmaintained/my355/platform/platform.c delete mode 100644 workspace/_unmaintained/my355/platform/platform.h delete mode 100755 workspace/_unmaintained/my355/show/makefile delete mode 100644 workspace/_unmaintained/my355/show/show.c delete mode 100755 workspace/_unmaintained/rg35xx/boot/boot.sh delete mode 100644 workspace/_unmaintained/rg35xx/boot/boot_logo.png delete mode 100755 workspace/_unmaintained/rg35xx/boot/build.sh delete mode 100644 workspace/_unmaintained/rg35xx/boot/installing.bmp delete mode 100644 workspace/_unmaintained/rg35xx/boot/updating.bmp delete mode 100644 workspace/_unmaintained/rg35xx/cores/makefile delete mode 100644 workspace/_unmaintained/rg35xx/cores/patches/fake-08.patch delete mode 100644 workspace/_unmaintained/rg35xx/cores/patches/fceumm.patch delete mode 100644 workspace/_unmaintained/rg35xx/cores/patches/gambatte.patch delete mode 100644 workspace/_unmaintained/rg35xx/cores/patches/gpsp.patch delete mode 100644 workspace/_unmaintained/rg35xx/cores/patches/mednafen_pce_fast.patch delete mode 100644 workspace/_unmaintained/rg35xx/cores/patches/mednafen_supafaust.patch delete mode 100644 workspace/_unmaintained/rg35xx/cores/patches/mednafen_vb.patch delete mode 100644 workspace/_unmaintained/rg35xx/cores/patches/mgba.patch delete mode 100644 workspace/_unmaintained/rg35xx/cores/patches/pcsx_rearmed.patch delete mode 100644 workspace/_unmaintained/rg35xx/cores/patches/picodrive.patch delete mode 100644 workspace/_unmaintained/rg35xx/cores/patches/pokemini.patch delete mode 100644 workspace/_unmaintained/rg35xx/cores/patches/race.patch delete mode 100644 workspace/_unmaintained/rg35xx/cores/patches/snes9x2005_plus.patch delete mode 100755 workspace/_unmaintained/rg35xx/install/install.sh delete mode 100644 workspace/_unmaintained/rg35xx/keymon/credits.txt delete mode 100644 workspace/_unmaintained/rg35xx/keymon/keymon.c delete mode 100755 workspace/_unmaintained/rg35xx/keymon/makefile delete mode 100644 workspace/_unmaintained/rg35xx/libmsettings/makefile delete mode 100644 workspace/_unmaintained/rg35xx/libmsettings/msettings.c delete mode 100644 workspace/_unmaintained/rg35xx/libmsettings/msettings.h delete mode 100644 workspace/_unmaintained/rg35xx/makefile delete mode 100644 workspace/_unmaintained/rg35xx/other/.keep delete mode 100644 workspace/_unmaintained/rg35xx/overclock/credits.txt delete mode 100755 workspace/_unmaintained/rg35xx/overclock/makefile delete mode 100644 workspace/_unmaintained/rg35xx/overclock/overclock.c delete mode 100755 workspace/_unmaintained/rg35xx/platform/de_atm7059.h delete mode 100755 workspace/_unmaintained/rg35xx/platform/ion-owl.h delete mode 100755 workspace/_unmaintained/rg35xx/platform/ion.h delete mode 100644 workspace/_unmaintained/rg35xx/platform/makefile.copy delete mode 100644 workspace/_unmaintained/rg35xx/platform/makefile.env delete mode 100644 workspace/_unmaintained/rg35xx/platform/platform.c delete mode 100644 workspace/_unmaintained/rg35xx/platform/platform.h delete mode 100644 workspace/_unmaintained/rg35xx/ramdisk/charging.png delete mode 100644 workspace/_unmaintained/rg35xx/ramdisk/patched-ramdisk.img delete mode 100644 workspace/_unmaintained/rg35xx/ramdisk/patched-ramdisk.meta delete mode 100644 workspace/_unmaintained/rg35xx/ramdisk/readme.txt delete mode 100755 workspace/_unmaintained/rg35xxplus/boot/boot.sh delete mode 100644 workspace/_unmaintained/rg35xxplus/boot/bootlogo-r.bmp delete mode 100755 workspace/_unmaintained/rg35xxplus/boot/bootlogo-s.bmp delete mode 100755 workspace/_unmaintained/rg35xxplus/boot/bootlogo-w.bmp delete mode 100755 workspace/_unmaintained/rg35xxplus/boot/bootlogo.bmp delete mode 100755 workspace/_unmaintained/rg35xxplus/boot/build.sh delete mode 100644 workspace/_unmaintained/rg35xxplus/boot/installing-r.bmp delete mode 100644 workspace/_unmaintained/rg35xxplus/boot/installing-s.bmp delete mode 100644 workspace/_unmaintained/rg35xxplus/boot/installing-w.bmp delete mode 100644 workspace/_unmaintained/rg35xxplus/boot/installing.bmp delete mode 100644 workspace/_unmaintained/rg35xxplus/boot/updating-r.bmp delete mode 100644 workspace/_unmaintained/rg35xxplus/boot/updating-s.bmp delete mode 100644 workspace/_unmaintained/rg35xxplus/boot/updating-w.bmp delete mode 100644 workspace/_unmaintained/rg35xxplus/boot/updating.bmp delete mode 100644 workspace/_unmaintained/rg35xxplus/cores/makefile delete mode 100644 workspace/_unmaintained/rg35xxplus/init/init.c delete mode 100644 workspace/_unmaintained/rg35xxplus/init/makefile delete mode 100755 workspace/_unmaintained/rg35xxplus/install/install.sh delete mode 100644 workspace/_unmaintained/rg35xxplus/keymon/credits.txt delete mode 100644 workspace/_unmaintained/rg35xxplus/keymon/keymon.c delete mode 100755 workspace/_unmaintained/rg35xxplus/keymon/makefile delete mode 100644 workspace/_unmaintained/rg35xxplus/libmsettings/makefile delete mode 100644 workspace/_unmaintained/rg35xxplus/libmsettings/msettings.c delete mode 100644 workspace/_unmaintained/rg35xxplus/libmsettings/msettings.h delete mode 100644 workspace/_unmaintained/rg35xxplus/makefile delete mode 100644 workspace/_unmaintained/rg35xxplus/platform/makefile.copy delete mode 100644 workspace/_unmaintained/rg35xxplus/platform/makefile.env delete mode 100644 workspace/_unmaintained/rg35xxplus/platform/platform.c delete mode 100644 workspace/_unmaintained/rg35xxplus/platform/platform.h delete mode 100755 workspace/_unmaintained/rg35xxplus/show/makefile delete mode 100644 workspace/_unmaintained/rg35xxplus/show/show.c delete mode 100644 workspace/_unmaintained/rgb30/cores/makefile delete mode 100644 workspace/_unmaintained/rgb30/cores/patches/fake-08.patch delete mode 100644 workspace/_unmaintained/rgb30/cores/patches/fceumm.patch delete mode 100644 workspace/_unmaintained/rgb30/cores/patches/gambatte.patch delete mode 100644 workspace/_unmaintained/rgb30/cores/patches/gpsp.patch delete mode 100644 workspace/_unmaintained/rgb30/cores/patches/mednafen_pce_fast.patch delete mode 100644 workspace/_unmaintained/rgb30/cores/patches/mednafen_supafaust.patch delete mode 100644 workspace/_unmaintained/rgb30/cores/patches/mednafen_vb.patch delete mode 100644 workspace/_unmaintained/rgb30/cores/patches/mgba.patch delete mode 100644 workspace/_unmaintained/rgb30/cores/patches/pcsx_rearmed.patch delete mode 100644 workspace/_unmaintained/rgb30/cores/patches/picodrive.patch delete mode 100644 workspace/_unmaintained/rgb30/cores/patches/pokemini.patch delete mode 100644 workspace/_unmaintained/rgb30/cores/patches/race.patch delete mode 100644 workspace/_unmaintained/rgb30/cores/patches/snes9x2005_plus.patch delete mode 100644 workspace/_unmaintained/rgb30/keymon/credits.txt delete mode 100644 workspace/_unmaintained/rgb30/keymon/keymon.c delete mode 100755 workspace/_unmaintained/rgb30/keymon/makefile delete mode 100644 workspace/_unmaintained/rgb30/libmsettings/makefile delete mode 100644 workspace/_unmaintained/rgb30/libmsettings/msettings.c delete mode 100644 workspace/_unmaintained/rgb30/libmsettings/msettings.h delete mode 100644 workspace/_unmaintained/rgb30/makefile delete mode 100644 workspace/_unmaintained/rgb30/other/.keep delete mode 100644 workspace/_unmaintained/rgb30/platform/makefile.copy delete mode 100644 workspace/_unmaintained/rgb30/platform/makefile.env delete mode 100644 workspace/_unmaintained/rgb30/platform/platform.c delete mode 100644 workspace/_unmaintained/rgb30/platform/platform.h delete mode 100755 workspace/_unmaintained/rgb30/show/makefile delete mode 100644 workspace/_unmaintained/rgb30/show/show.c delete mode 100644 workspace/_unmaintained/trimuismart/cores/makefile delete mode 100644 workspace/_unmaintained/trimuismart/cores/patches/fake-08.patch delete mode 100644 workspace/_unmaintained/trimuismart/cores/patches/fceumm.patch delete mode 100644 workspace/_unmaintained/trimuismart/cores/patches/gambatte.patch delete mode 100644 workspace/_unmaintained/trimuismart/cores/patches/gpsp.patch delete mode 100644 workspace/_unmaintained/trimuismart/cores/patches/mednafen_pce_fast.patch delete mode 100644 workspace/_unmaintained/trimuismart/cores/patches/mednafen_supafaust.patch delete mode 100644 workspace/_unmaintained/trimuismart/cores/patches/mednafen_vb.patch delete mode 100644 workspace/_unmaintained/trimuismart/cores/patches/mgba.patch delete mode 100644 workspace/_unmaintained/trimuismart/cores/patches/pcsx_rearmed.patch delete mode 100644 workspace/_unmaintained/trimuismart/cores/patches/picodrive.patch delete mode 100644 workspace/_unmaintained/trimuismart/cores/patches/pokemini.patch delete mode 100644 workspace/_unmaintained/trimuismart/cores/patches/race.patch delete mode 100644 workspace/_unmaintained/trimuismart/cores/patches/snes9x2005_plus.patch delete mode 100755 workspace/_unmaintained/trimuismart/install/boot.sh delete mode 100644 workspace/_unmaintained/trimuismart/install/installing.png delete mode 100644 workspace/_unmaintained/trimuismart/install/updating.png delete mode 100644 workspace/_unmaintained/trimuismart/keymon/credits.txt delete mode 100644 workspace/_unmaintained/trimuismart/keymon/keymon.c delete mode 100755 workspace/_unmaintained/trimuismart/keymon/makefile delete mode 100644 workspace/_unmaintained/trimuismart/libmsettings/makefile delete mode 100644 workspace/_unmaintained/trimuismart/libmsettings/msettings.c delete mode 100644 workspace/_unmaintained/trimuismart/libmsettings/msettings.h delete mode 100755 workspace/_unmaintained/trimuismart/libmsettings/sunxi_display2.h delete mode 100644 workspace/_unmaintained/trimuismart/makefile delete mode 100644 workspace/_unmaintained/trimuismart/other/.keep delete mode 100755 workspace/_unmaintained/trimuismart/platform/ion.h delete mode 100755 workspace/_unmaintained/trimuismart/platform/ion_sunxi.h delete mode 100644 workspace/_unmaintained/trimuismart/platform/makefile.copy delete mode 100644 workspace/_unmaintained/trimuismart/platform/makefile.env delete mode 100644 workspace/_unmaintained/trimuismart/platform/platform.c delete mode 100644 workspace/_unmaintained/trimuismart/platform/platform.h delete mode 100755 workspace/_unmaintained/trimuismart/platform/sunxi_display2.h delete mode 100644 workspace/_unmaintained/trimuismart/show/makefile delete mode 100644 workspace/_unmaintained/trimuismart/show/show.c delete mode 100644 workspace/_unmaintained/zero28/bl/bl_disable.c delete mode 100644 workspace/_unmaintained/zero28/bl/bl_enable.c delete mode 100755 workspace/_unmaintained/zero28/bl/makefile delete mode 100644 workspace/_unmaintained/zero28/cores/makefile delete mode 100755 workspace/_unmaintained/zero28/install/boot.sh delete mode 100644 workspace/_unmaintained/zero28/install/installing.png delete mode 100755 workspace/_unmaintained/zero28/install/update.sh delete mode 100644 workspace/_unmaintained/zero28/install/updating.png delete mode 100644 workspace/_unmaintained/zero28/keymon/credits.txt delete mode 100644 workspace/_unmaintained/zero28/keymon/keymon.c delete mode 100755 workspace/_unmaintained/zero28/keymon/makefile delete mode 100644 workspace/_unmaintained/zero28/libmsettings/makefile delete mode 100644 workspace/_unmaintained/zero28/libmsettings/msettings.c delete mode 100644 workspace/_unmaintained/zero28/libmsettings/msettings.h delete mode 100644 workspace/_unmaintained/zero28/makefile delete mode 100644 workspace/_unmaintained/zero28/platform/makefile.copy delete mode 100644 workspace/_unmaintained/zero28/platform/makefile.env delete mode 100644 workspace/_unmaintained/zero28/platform/platform.c delete mode 100644 workspace/_unmaintained/zero28/platform/platform.h delete mode 100755 workspace/_unmaintained/zero28/show/makefile delete mode 100644 workspace/_unmaintained/zero28/show/show.c diff --git a/github/README.md b/github/README.md deleted file mode 100644 index 7aa3e8b47..000000000 --- a/github/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# NextUI screenshots - - diff --git a/github/generate_screenshots.sh b/github/generate_screenshots.sh deleted file mode 100755 index eb5f7fcad..000000000 --- a/github/generate_screenshots.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -pushd "$(dirname "$0")" >> /dev/null - -files=$(ls *.png) -screenshotText="# NextUI screenshots\n\n" - -for file in $files; do - screenshotText+=" " -done - -echo -e $screenshotText > README.md -popd >> /dev/null \ No newline at end of file diff --git a/github/logo.png b/github/logo.png deleted file mode 100644 index 014464f88e837b4058b9c67045aff01e818372d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5753 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 diff --git a/github/logo_outline.png b/github/logo_outline.png deleted file mode 100644 index c00ba743afe2d37792b7cdd126bbd69e1a0943eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 72202 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 diff --git a/github/minui-clock.png b/github/minui-clock.png deleted file mode 100644 index 72d9a96afd0500be25a3c3ee3ad1b67740fd55eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13472 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

?h= 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 diff --git a/github/minui-menu-sfc.png b/github/minui-menu-sfc.png deleted file mode 100644 index ed43ebd1f014f9ef7bcd6f47aa6f047c96118ee3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48477 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�Qj1kny}DA-~a?1ajN|s?ykL4g=YHjP`i-r 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 diff --git a/github/minui-menu-sgb.png b/github/minui-menu-sgb.png deleted file mode 100644 index 7c2d74163448f2f92b3b12d75911fc35cc039753..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44017 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�?D7)wF`@hnW?EprC;?YWwHFxr; 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 W_-jHR4lAL6-v=or$qI3!p#KLG3GZ+K diff --git a/github/minui-menu-vb.png b/github/minui-menu-vb.png deleted file mode 100644 index 356b072b66dd86d85e0d60e570a51f1aefa60dfd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35164 zcmdp-19N0u*sf#Swrx(5$;7tpWMZ>p8imb(m8w*AcUAAT z_Ihw%&%GlQf(%L&9$qK5q17CH; zzs{uhe-z#DG=g);rJCXu0D~0;BMKknC24br9SQ>EBeBvLqlXVt=7#TohZ_yRNCc%F z1W!f*&qraFBqfUfQNNA88?wqh9MR9CXuYSEYS+0pRc%p%2$P!4f3fk=F2m5}rB-vQ zwoq|;dbtG+G5c`!QSr2S^#pi0O)e&d2_*Ud<*zhfVLtBonpikq-}KY_?#b8vYRX_E z?d4Inrap!FlQWe1rp#2u?beTue6`SV=J_c8422>F`(b(IDSCeQ^ZL?nb>s0VC= zKr?GcBTNMUebfGNTed_bm}$=L>v3!F3_VK+qEAS&o zV9D3?4r=h<(0)70ZSJ?nw;#O0tE8mo)kLFJHb z{sh7wVP959lDrPsnYRH9hW4Q(gi!YlHryIs-57@DLN6H#ne4Xs2m+kmy!XbyADER#PenQ>z^zr^*cx657+w72G`oG8zRpiF5P|R$lMTs9cb)8LD3cC%_d_ENefy-f_b2n~lrdq5)Wnb9DT^@LpQ(djr&D`vxbb3QVi3KBBxPZs z&*wKjI;>L{ZL9~iX}!_kNm}7#L(uVlGqD)fCPnqn&J+|BIAAENy)_OKG7``sAR~*^ zP7A)BV;lGwHA(Kti>zj{fi{35jb-t>YfeM?zTp{4k`{jLk0v>QVIWal1tAOikLUcV zH32g?&%w#Dd>0wukh7QHDgDrV8jiuwM{t7r?dqNz4DgwA!cDX&3BHR-=ccjam03ho zT8LC~u|lC8R}9P2e&z85$n`XTS^9lM@nM+PRbJ385`90lRZ|~^O zVQp3kqPY>=%-P;XaYNk>WpOE+_e7r+rz{W<}bX~|ZOP0=Mn5Q_NaSj+% zxVH)ZThuML(j0wkx|zLx?yWQUpM36)ZPP0sZx{&qVN%ON##->9zPQb8h--c`a~n^Q zOHv+@KPyDXCp`1V9IjKAyb2C&AE2RJ+tZigZ5B!Ed*3hn_LB}^UOAMmCc54F@x%_G zemBu~Py4qm`F8pl_KS_~>F*x|qE+ecd^7WOqW`d~vlrF%6!ZoA)tU)7gDNyo1)kz8 zWAIF#@ol&8Xzni}!yKymd&8hM(_Bz-<)sd9?`|sg<;ovht-#FCiMw5Lt5UgCW8jX+ z6W0!v+4eHMwzj4K6&A&$b`;&}^wx!L8PH%c4OKGcTd3``Dg?I`o+%fez`sxa0S(pM z{Hse(n+79O9=%5{ z0WWbqKIhAIZEbBE8+!If^B&8;y{+vmElahl4yl=W*?Nnuob;mE@t_2lmmnP$`G{r! zB89+pw|$$r>z4~Gz{kheEhjUA?!Vm8@AuTr89SJH=%IKyZvf}L4HNRY9i@&9@h6Z| zP;ice>Z8=vKU~WHDJXnDVZ$fnw@DOvgd~hTjr8oyj4I52El1G^QH{8aU9aHSni_Q; z&chBX)s!P#tTcs^%RV&iF3I(CwoFVdg_Phbq|!Dt)9G>faezkyL3nlQzk_PDSAuWi z$M?7{VbA21R}Y@n@un>9T<57qi;6?4`@HB9Z(DU_F#%p-G2XXDL{!#Dc~-i5gq2_~By6rX@~7XydmObY=|34kJb*)wl~k2>)Uw@();s=G~$*IUqGWUk(uSKjF-QY;ahk^3LZI)avu|^PdUnARnjaVTT6u z`jRbm@m={lnjr7*n{;^J?vMKGj5

bcz&rRwiev2M1zo*iDwxgiH{`85iW#8Vs) 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 X1ROQ^aMmvI1ISsPu6{1-oD!M<6l`rT diff --git a/skeleton/_unmaintained/BOOT/magicx/init.sh b/skeleton/_unmaintained/BOOT/magicx/init.sh deleted file mode 100755 index 81f5138b6..000000000 --- a/skeleton/_unmaintained/BOOT/magicx/init.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh - -cd $(dirname "$0") - -export PATH=/usr/magicx/bin:/usr/bin:/usr/sbin:/bin:/sbin -export LD_LIBRARY_PATH=/usr/magicx/lib:/usr/lib:/lib - -SDCARD_PATH=/mnt/SDCARD - -# .tmp_update/updater does the actual installation (and later, updating) -cp -rf .tmp_update $SDCARD_PATH/ -rm -rf "$SDCARD_PATH/magicx" -sync -$SDCARD_PATH/.tmp_update/updater - -# under no circumstances should stock be allowed to touch this card -poweroff diff --git a/skeleton/_unmaintained/BOOT/miyoo/app/MainUI b/skeleton/_unmaintained/BOOT/miyoo/app/MainUI deleted file mode 100755 index 90b8bec26..000000000 --- a/skeleton/_unmaintained/BOOT/miyoo/app/MainUI +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -cd $(dirname "$0") - -INFO=`cat /proc/cpuinfo 2> /dev/null` -case $INFO in -*"0xd05"*) - ./my355.sh - ;; -*"sun8i"*) - ./my282.sh - ;; -*"SStar"*) - ./miyoomini.sh - ;; -esac \ No newline at end of file diff --git a/skeleton/_unmaintained/BOOT/miyoo/app/keymon b/skeleton/_unmaintained/BOOT/miyoo/app/keymon deleted file mode 100755 index c52d3c26b..000000000 --- a/skeleton/_unmaintained/BOOT/miyoo/app/keymon +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -exit 0 diff --git a/skeleton/_unmaintained/BOOT/miyoo/app/miyoomini.sh b/skeleton/_unmaintained/BOOT/miyoo/app/miyoomini.sh deleted file mode 100755 index bbbb33c72..000000000 --- a/skeleton/_unmaintained/BOOT/miyoo/app/miyoomini.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/sh - -IS_PLUS=false -if [ -f "/customer/app/axp_test" ]; then - IS_PLUS=true -fi - -if $IS_PLUS; then - MIYOO_DIR="miyoo354" -else - MIYOO_DIR="miyoo" -fi - - -SDCARD_PATH=/mnt/SDCARD -cd "$SDCARD_PATH/$MIYOO_DIR/app" - -export LD_LIBRARY_PATH=/lib:/config/lib:/customer/lib - -# update bootcmd if necessary -contains() { [ -z "${2##*$1*}" ]; } -MIYOO_VERSION=`/etc/fw_printenv miyoo_version` -MIYOO_VERSION=${MIYOO_VERSION#miyoo_version=} -SUPPORTED_VERSION="202205010000" # date after latest known version -# TODO: pretty sure this bricks a subsequent update -if [ $MIYOO_VERSION -lt $SUPPORTED_VERSION ]; then - OLD_CMD=`/etc/fw_printenv bootcmd` - NEW_CMD="gpio output 85 1; bootlogo 0 0 0 0 0; mw 1f001cc0 11; gpio out 8 0; sf probe 0;sf read 0x22000000 \${sf_kernel_start} \${sf_kernel_size}; gpio out 8 1; gpio output 4 1; bootm 0x22000000" - if contains "sleepms" "$OLD_CMD"; then - /etc/fw_setenv bootcmd $NEW_CMD - sleep 1 - fi -fi - -# .tmp_update/updater does the actual installation (and later, updating) -cp -rf .tmp_update $SDCARD_PATH/ -rm -rf "$SDCARD_PATH/$MIYOO_DIR" -sync -$SDCARD_PATH/.tmp_update/updater - -# under no circumstances should stock be allowed to touch this card -if $IS_PLUS; then - poweroff -else - reboot -fi \ No newline at end of file diff --git a/skeleton/_unmaintained/BOOT/miyoo/app/my282.sh b/skeleton/_unmaintained/BOOT/miyoo/app/my282.sh deleted file mode 100755 index 9a0121bd5..000000000 --- a/skeleton/_unmaintained/BOOT/miyoo/app/my282.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -cd $(dirname "$0") - -export PATH=/usr/miyoo/bin:/usr/miyoo/sbin:/usr/bin:/usr/sbin:/bin:/sbin -export LD_LIBRARY_PATH=/usr/miyoo/lib:/usr/lib:/lib - -SDCARD_PATH=/mnt/SDCARD -MIYOO_DIR=miyoo - -# .tmp_update/updater does the actual installation (and later, updating) -cp -rf .tmp_update $SDCARD_PATH/ -rm -rf "$SDCARD_PATH/$MIYOO_DIR" -sync -$SDCARD_PATH/.tmp_update/updater - -# under no circumstances should stock be allowed to touch this card -poweroff diff --git a/skeleton/_unmaintained/BOOT/miyoo/app/my355.sh b/skeleton/_unmaintained/BOOT/miyoo/app/my355.sh deleted file mode 100755 index 81a33e20f..000000000 --- a/skeleton/_unmaintained/BOOT/miyoo/app/my355.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh - -cd $(dirname "$0") - -SDCARD_PATH=/mnt/SDCARD -MIYOO_DIR=miyoo355 - -if [ ! -f /usr/miyoo/bin/runmiyoo-original.sh ]; then - if [ -d $SDCARD_PATH/.tmp_update/ ]; then - rm -rf $SDCARD_PATH/.tmp_update/ - fi - my355/init.sh -fi - -export PATH=/usr/miyoo/bin:/usr/miyoo/sbin:/usr/bin:/usr/sbin:/bin:/sbin -export LD_LIBRARY_PATH=/usr/miyoo/lib:/usr/lib:/lib - - -# .tmp_update/updater does the actual installation (and later, updating) -cp -rf .tmp_update $SDCARD_PATH/ -rm -rf "$SDCARD_PATH/$MIYOO_DIR" -sync -$SDCARD_PATH/.tmp_update/updater - -# under no circumstances should stock be allowed to touch this card -poweroff diff --git a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/GG.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/GG.pak/default.cfg deleted file mode 100755 index 44ce34743..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/GG.pak/default.cfg +++ /dev/null @@ -1,18 +0,0 @@ --picodrive_smstype = Game Gear --picodrive_smsmapper = Auto --picodrive_sound_rate = 44100 --picodrive_ramcart = disabled --picodrive_dacnoise = disabled --picodrive_input1 = 3 button pad --picodrive_input2 = 3 button pad --picodrive_fm_filter = off --picodrive_audio_filter = disabled --picodrive_overclk68k = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Button 1 = B -bind Button 2 = A -bind Pause = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/GG.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/GG.pak/launch.sh deleted file mode 100755 index 81688be79..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/GG.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/MGBA.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/MGBA.pak/default.cfg deleted file mode 100644 index 266d90c20..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/MGBA.pak/default.cfg +++ /dev/null @@ -1,18 +0,0 @@ -mgba_skip_bios = ON - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 -bind L Turbo = NONE:L2 -bind R Turbo = NONE:R2 -bind More Sun = NONE:L3 -bind Less Sun = NONE:R3 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/MGBA.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/MGBA.pak/launch.sh deleted file mode 100755 index 796c1be58..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/MGBA.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mgba -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/NGP.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/NGP.pak/default.cfg deleted file mode 100755 index 7d05719ba..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/NGP.pak/default.cfg +++ /dev/null @@ -1,7 +0,0 @@ -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = B -bind B Button = A -bind Option = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/NGP.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/NGP.pak/launch.sh deleted file mode 100755 index 138a2b10b..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/NGP.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=race -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/NGPC.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/NGPC.pak/default.cfg deleted file mode 100755 index 7d05719ba..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/NGPC.pak/default.cfg +++ /dev/null @@ -1,7 +0,0 @@ -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = B -bind B Button = A -bind Option = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/NGPC.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/NGPC.pak/launch.sh deleted file mode 100755 index 138a2b10b..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/NGPC.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=race -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/PCE.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/PCE.pak/default.cfg deleted file mode 100755 index 671219086..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/PCE.pak/default.cfg +++ /dev/null @@ -1,15 +0,0 @@ --pce_fast_turbo_toggle_hotkey = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Run = START -bind I = A -bind II = B -bind III = Y -bind IV = X -bind V = L1 -bind VI = R1 -bind Mode = L2 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/PCE.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/PCE.pak/launch.sh deleted file mode 100755 index 7bf829940..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/PCE.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mednafen_pce_fast -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/PKM.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/PKM.pak/default.cfg deleted file mode 100755 index ad36b411a..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/PKM.pak/default.cfg +++ /dev/null @@ -1,17 +0,0 @@ -minarch_screen_scaling = Native - --pokemini_video_scale = 3x --pokemini_60hz_mode = enabled -pokemini_palette = Old -pokemini_piezofilter = disabled -pokemini_lowpass_filter = enabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = A -bind B Button = B -bind C Button = R1 -bind Shake = L1 -bind Power = SELECT diff --git a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/PKM.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/PKM.pak/launch.sh deleted file mode 100755 index 098f76f1c..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/PKM.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=pokemini -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/SGB.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/SGB.pak/default.cfg deleted file mode 100644 index 78fdedb28..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/SGB.pak/default.cfg +++ /dev/null @@ -1,24 +0,0 @@ --mgba_gb_model = Super Game Boy -mgba_skip_bios = ON --mgba_gb_colors_preset = 2 --mgba_force_gbp = OFF --mgba_color_correction = OFF --mgba_interframe_blending = OFF -mgba_sgb_borders = ON - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 -bind L Turbo = NONE:L2 -bind R Turbo = NONE:R2 -bind More Sun = NONE:L3 -bind Less Sun = NONE:R3 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/SGB.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/SGB.pak/launch.sh deleted file mode 100755 index 796c1be58..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/SGB.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mgba -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/SMS.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/SMS.pak/default.cfg deleted file mode 100755 index 0d2df362d..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/SMS.pak/default.cfg +++ /dev/null @@ -1,19 +0,0 @@ --picodrive_smstype = Master System -picodrive_smsmapper = Auto --picodrive_ggghost = off --picodrive_sound_rate = 44100 --picodrive_ramcart = disabled --picodrive_dacnoise = disabled --picodrive_input1 = 3 button pad --picodrive_input2 = 3 button pad --picodrive_fm_filter = off --picodrive_audio_filter = disabled --picodrive_overclk68k = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Button 1 = B -bind Button 2 = A -bind Pause = START diff --git a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/SMS.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/SMS.pak/launch.sh deleted file mode 100755 index 81688be79..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/gkdpixel/SMS.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/m17/GG.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/m17/GG.pak/default.cfg deleted file mode 100755 index 9e92f130a..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/m17/GG.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ -minarch_screen_sharpness = Crisp - --picodrive_smstype = Game Gear --picodrive_smsmapper = Auto --picodrive_sound_rate = 44100 --picodrive_ramcart = disabled --picodrive_dacnoise = disabled --picodrive_input1 = 3 button pad --picodrive_input2 = 3 button pad --picodrive_fm_filter = off --picodrive_audio_filter = disabled --picodrive_overclk68k = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Button 1 = B -bind Button 2 = A -bind Pause = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/m17/GG.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/m17/GG.pak/launch.sh deleted file mode 100755 index 81688be79..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/m17/GG.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/m17/MGBA.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/m17/MGBA.pak/default.cfg deleted file mode 100755 index 0d00bbec4..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/m17/MGBA.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ -minarch_screen_sharpness = Crisp - -mgba_skip_bios = ON - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 -bind L Turbo = NONE:L2 -bind R Turbo = NONE:R2 -bind More Sun = NONE:L3 -bind Less Sun = NONE:R3 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/m17/MGBA.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/m17/MGBA.pak/launch.sh deleted file mode 100755 index 796c1be58..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/m17/MGBA.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mgba -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/m17/NGP.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/m17/NGP.pak/default.cfg deleted file mode 100644 index 0d84d47ce..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/m17/NGP.pak/default.cfg +++ /dev/null @@ -1,11 +0,0 @@ -minarch_screen_sharpness = Crisp - -race_dark_filter_level = 50 - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = B -bind B Button = A -bind Option = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/m17/NGP.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/m17/NGP.pak/launch.sh deleted file mode 100644 index 138a2b10b..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/m17/NGP.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=race -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/m17/NGPC.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/m17/NGPC.pak/default.cfg deleted file mode 100644 index edae53997..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/m17/NGPC.pak/default.cfg +++ /dev/null @@ -1,9 +0,0 @@ -minarch_screen_sharpness = Crisp - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = B -bind B Button = A -bind Option = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/m17/NGPC.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/m17/NGPC.pak/launch.sh deleted file mode 100644 index 138a2b10b..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/m17/NGPC.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=race -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/m17/P8.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/m17/P8.pak/default.cfg deleted file mode 100644 index 8f32c28fd..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/m17/P8.pak/default.cfg +++ /dev/null @@ -1,9 +0,0 @@ -minarch_screen_sharpness = Crisp - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = A -bind B Button = B -bind Start = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/m17/P8.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/m17/P8.pak/launch.sh deleted file mode 100755 index b3de7565d..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/m17/P8.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=fake08 -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/m17/PCE.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/m17/PCE.pak/default.cfg deleted file mode 100755 index 671219086..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/m17/PCE.pak/default.cfg +++ /dev/null @@ -1,15 +0,0 @@ --pce_fast_turbo_toggle_hotkey = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Run = START -bind I = A -bind II = B -bind III = Y -bind IV = X -bind V = L1 -bind VI = R1 -bind Mode = L2 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/m17/PCE.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/m17/PCE.pak/launch.sh deleted file mode 100755 index 7bf829940..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/m17/PCE.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mednafen_pce_fast -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/m17/PKM.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/m17/PKM.pak/default.cfg deleted file mode 100755 index f44d72aa7..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/m17/PKM.pak/default.cfg +++ /dev/null @@ -1,18 +0,0 @@ -minarch_screen_scaling = Native -minarch_screen_sharpness = Sharp - -pokemini_video_scale = 4x --pokemini_60hz_mode = enabled -pokemini_palette = Old -pokemini_piezofilter = disabled -pokemini_lowpass_filter = enabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = A -bind B Button = B -bind C Button = R1 -bind Shake = L1 -bind Power = SELECT diff --git a/skeleton/_unmaintained/EXTRAS/Emus/m17/PKM.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/m17/PKM.pak/launch.sh deleted file mode 100755 index 098f76f1c..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/m17/PKM.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=pokemini -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/m17/SGB.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/m17/SGB.pak/default.cfg deleted file mode 100755 index f044cde42..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/m17/SGB.pak/default.cfg +++ /dev/null @@ -1,26 +0,0 @@ -minarch_screen_sharpness = Crisp - --mgba_gb_model = Super Game Boy -mgba_skip_bios = ON --mgba_gb_colors_preset = 2 --mgba_force_gbp = OFF --mgba_color_correction = OFF --mgba_interframe_blending = OFF -mgba_sgb_borders = ON - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 -bind L Turbo = NONE:L2 -bind R Turbo = NONE:R2 -bind More Sun = NONE:L3 -bind Less Sun = NONE:R3 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/m17/SGB.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/m17/SGB.pak/launch.sh deleted file mode 100755 index 796c1be58..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/m17/SGB.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mgba -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/m17/SMS.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/m17/SMS.pak/default.cfg deleted file mode 100755 index 0d2df362d..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/m17/SMS.pak/default.cfg +++ /dev/null @@ -1,19 +0,0 @@ --picodrive_smstype = Master System -picodrive_smsmapper = Auto --picodrive_ggghost = off --picodrive_sound_rate = 44100 --picodrive_ramcart = disabled --picodrive_dacnoise = disabled --picodrive_input1 = 3 button pad --picodrive_input2 = 3 button pad --picodrive_fm_filter = off --picodrive_audio_filter = disabled --picodrive_overclk68k = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Button 1 = B -bind Button 2 = A -bind Pause = START diff --git a/skeleton/_unmaintained/EXTRAS/Emus/m17/SMS.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/m17/SMS.pak/launch.sh deleted file mode 100755 index 81688be79..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/m17/SMS.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/m17/SUPA.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/m17/SUPA.pak/default.cfg deleted file mode 100755 index 07fcd8d65..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/m17/SUPA.pak/default.cfg +++ /dev/null @@ -1,15 +0,0 @@ --supafaust_pixel_format = rgb565 --supafaust_thread_affinity_emu = 0x0 - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Y Button = Y -bind X Button = X -bind B Button = B -bind A Button = A -bind L Button = L1 -bind R Button = R1 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/m17/SUPA.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/m17/SUPA.pak/launch.sh deleted file mode 100755 index 331d02280..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/m17/SUPA.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mednafen_supafaust -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/m17/VB.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/m17/VB.pak/default.cfg deleted file mode 100755 index 64faaa2a9..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/m17/VB.pak/default.cfg +++ /dev/null @@ -1,22 +0,0 @@ -minarch_screen_scaling = Native -minarch_screen_sharpness = Sharp -minarch_cpu_speed = Performance - --vb_3dmode = anaglyph --vb_right_analog_to_digital = disabled - -bind L. Up = UP -bind L. Down = DOWN -bind L. Left = LEFT -bind L. Right = RIGHT -bind Select = SELECT -bind Start = START -bind A = A -bind B = B -bind L Button = L1 -bind R Button = R1 -bind Low Battery = NONE:X -bind R. Up = NONE:L2 -bind R. Down = NONE:L3 -bind R. Left = NONE:R2 -bind R. Right = NONE:R3 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/m17/VB.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/m17/VB.pak/launch.sh deleted file mode 100755 index e5146dd57..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/m17/VB.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mednafen_vb -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/GG.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/magicmini/GG.pak/default.cfg deleted file mode 100644 index 44ce34743..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/GG.pak/default.cfg +++ /dev/null @@ -1,18 +0,0 @@ --picodrive_smstype = Game Gear --picodrive_smsmapper = Auto --picodrive_sound_rate = 44100 --picodrive_ramcart = disabled --picodrive_dacnoise = disabled --picodrive_input1 = 3 button pad --picodrive_input2 = 3 button pad --picodrive_fm_filter = off --picodrive_audio_filter = disabled --picodrive_overclk68k = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Button 1 = B -bind Button 2 = A -bind Pause = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/GG.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/magicmini/GG.pak/launch.sh deleted file mode 100755 index 81688be79..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/GG.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/MGBA.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/magicmini/MGBA.pak/default.cfg deleted file mode 100644 index 266d90c20..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/MGBA.pak/default.cfg +++ /dev/null @@ -1,18 +0,0 @@ -mgba_skip_bios = ON - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 -bind L Turbo = NONE:L2 -bind R Turbo = NONE:R2 -bind More Sun = NONE:L3 -bind Less Sun = NONE:R3 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/MGBA.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/magicmini/MGBA.pak/launch.sh deleted file mode 100755 index 796c1be58..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/MGBA.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mgba -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/NGP.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/magicmini/NGP.pak/default.cfg deleted file mode 100644 index 33f5a6b95..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/NGP.pak/default.cfg +++ /dev/null @@ -1,9 +0,0 @@ -race_dark_filter_level = 50 - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = B -bind B Button = A -bind Option = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/NGP.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/magicmini/NGP.pak/launch.sh deleted file mode 100644 index 138a2b10b..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/NGP.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=race -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/NGPC.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/magicmini/NGPC.pak/default.cfg deleted file mode 100644 index 7d05719ba..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/NGPC.pak/default.cfg +++ /dev/null @@ -1,7 +0,0 @@ -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = B -bind B Button = A -bind Option = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/NGPC.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/magicmini/NGPC.pak/launch.sh deleted file mode 100644 index 138a2b10b..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/NGPC.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=race -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/P8.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/magicmini/P8.pak/default.cfg deleted file mode 100644 index 73611d3f3..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/P8.pak/default.cfg +++ /dev/null @@ -1,7 +0,0 @@ -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = A -bind B Button = B -bind Start = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/P8.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/magicmini/P8.pak/launch.sh deleted file mode 100755 index b3de7565d..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/P8.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=fake08 -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/PCE.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/magicmini/PCE.pak/default.cfg deleted file mode 100644 index 671219086..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/PCE.pak/default.cfg +++ /dev/null @@ -1,15 +0,0 @@ --pce_fast_turbo_toggle_hotkey = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Run = START -bind I = A -bind II = B -bind III = Y -bind IV = X -bind V = L1 -bind VI = R1 -bind Mode = L2 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/PCE.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/magicmini/PCE.pak/launch.sh deleted file mode 100755 index 7bf829940..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/PCE.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mednafen_pce_fast -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/PKM.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/magicmini/PKM.pak/default.cfg deleted file mode 100644 index f6d20d9bb..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/PKM.pak/default.cfg +++ /dev/null @@ -1,17 +0,0 @@ -minarch_screen_scaling = Native - -pokemini_video_scale = 3x --pokemini_60hz_mode = enabled -pokemini_palette = Old -pokemini_piezofilter = disabled -pokemini_lowpass_filter = enabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = A -bind B Button = B -bind C Button = R1 -bind Shake = L1 -bind Power = SELECT diff --git a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/PKM.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/magicmini/PKM.pak/launch.sh deleted file mode 100755 index 098f76f1c..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/PKM.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=pokemini -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/SGB.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/magicmini/SGB.pak/default.cfg deleted file mode 100644 index 78fdedb28..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/SGB.pak/default.cfg +++ /dev/null @@ -1,24 +0,0 @@ --mgba_gb_model = Super Game Boy -mgba_skip_bios = ON --mgba_gb_colors_preset = 2 --mgba_force_gbp = OFF --mgba_color_correction = OFF --mgba_interframe_blending = OFF -mgba_sgb_borders = ON - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 -bind L Turbo = NONE:L2 -bind R Turbo = NONE:R2 -bind More Sun = NONE:L3 -bind Less Sun = NONE:R3 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/SGB.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/magicmini/SGB.pak/launch.sh deleted file mode 100755 index 796c1be58..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/SGB.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mgba -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/SMS.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/magicmini/SMS.pak/default.cfg deleted file mode 100644 index 0d2df362d..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/SMS.pak/default.cfg +++ /dev/null @@ -1,19 +0,0 @@ --picodrive_smstype = Master System -picodrive_smsmapper = Auto --picodrive_ggghost = off --picodrive_sound_rate = 44100 --picodrive_ramcart = disabled --picodrive_dacnoise = disabled --picodrive_input1 = 3 button pad --picodrive_input2 = 3 button pad --picodrive_fm_filter = off --picodrive_audio_filter = disabled --picodrive_overclk68k = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Button 1 = B -bind Button 2 = A -bind Pause = START diff --git a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/SMS.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/magicmini/SMS.pak/launch.sh deleted file mode 100755 index 81688be79..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/SMS.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/SUPA.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/magicmini/SUPA.pak/default.cfg deleted file mode 100644 index 07fcd8d65..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/SUPA.pak/default.cfg +++ /dev/null @@ -1,15 +0,0 @@ --supafaust_pixel_format = rgb565 --supafaust_thread_affinity_emu = 0x0 - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Y Button = Y -bind X Button = X -bind B Button = B -bind A Button = A -bind L Button = L1 -bind R Button = R1 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/SUPA.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/magicmini/SUPA.pak/launch.sh deleted file mode 100755 index 331d02280..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/SUPA.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mednafen_supafaust -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/VB.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/magicmini/VB.pak/default.cfg deleted file mode 100644 index a83095a2b..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/VB.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ -minarch_cpu_speed = Performance - --vb_3dmode = anaglyph --vb_right_analog_to_digital = disabled - -bind L. Up = UP -bind L. Down = DOWN -bind L. Left = LEFT -bind L. Right = RIGHT -bind Select = SELECT -bind Start = START -bind A = A -bind B = B -bind L Button = L1 -bind R Button = R1 -bind Low Battery = NONE:X -bind R. Up = NONE:L2 -bind R. Down = NONE:L3 -bind R. Left = NONE:R2 -bind R. Right = NONE:R3 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/VB.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/magicmini/VB.pak/launch.sh deleted file mode 100755 index e5146dd57..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/magicmini/VB.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mednafen_vb -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/GG.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/GG.pak/default.cfg deleted file mode 100644 index 44ce34743..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/GG.pak/default.cfg +++ /dev/null @@ -1,18 +0,0 @@ --picodrive_smstype = Game Gear --picodrive_smsmapper = Auto --picodrive_sound_rate = 44100 --picodrive_ramcart = disabled --picodrive_dacnoise = disabled --picodrive_input1 = 3 button pad --picodrive_input2 = 3 button pad --picodrive_fm_filter = off --picodrive_audio_filter = disabled --picodrive_overclk68k = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Button 1 = B -bind Button 2 = A -bind Pause = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/GG.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/GG.pak/launch.sh deleted file mode 100755 index 0fdffa382..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/GG.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -nice -20 minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/MGBA.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/MGBA.pak/default.cfg deleted file mode 100644 index 266d90c20..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/MGBA.pak/default.cfg +++ /dev/null @@ -1,18 +0,0 @@ -mgba_skip_bios = ON - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 -bind L Turbo = NONE:L2 -bind R Turbo = NONE:R2 -bind More Sun = NONE:L3 -bind Less Sun = NONE:R3 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/MGBA.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/MGBA.pak/launch.sh deleted file mode 100755 index 6fbf5befb..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/MGBA.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mgba -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -nice -20 minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/NGP.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/NGP.pak/default.cfg deleted file mode 100644 index 33f5a6b95..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/NGP.pak/default.cfg +++ /dev/null @@ -1,9 +0,0 @@ -race_dark_filter_level = 50 - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = B -bind B Button = A -bind Option = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/NGP.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/NGP.pak/launch.sh deleted file mode 100644 index 138a2b10b..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/NGP.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=race -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/NGPC.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/NGPC.pak/default.cfg deleted file mode 100644 index 7d05719ba..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/NGPC.pak/default.cfg +++ /dev/null @@ -1,7 +0,0 @@ -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = B -bind B Button = A -bind Option = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/NGPC.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/NGPC.pak/launch.sh deleted file mode 100644 index 138a2b10b..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/NGPC.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=race -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/P8.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/P8.pak/default.cfg deleted file mode 100644 index 73611d3f3..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/P8.pak/default.cfg +++ /dev/null @@ -1,7 +0,0 @@ -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = A -bind B Button = B -bind Start = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/P8.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/P8.pak/launch.sh deleted file mode 100755 index f318da9d4..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/P8.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=fake08 -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -nice -20 minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/PCE.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/PCE.pak/default.cfg deleted file mode 100644 index 671219086..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/PCE.pak/default.cfg +++ /dev/null @@ -1,15 +0,0 @@ --pce_fast_turbo_toggle_hotkey = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Run = START -bind I = A -bind II = B -bind III = Y -bind IV = X -bind V = L1 -bind VI = R1 -bind Mode = L2 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/PCE.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/PCE.pak/launch.sh deleted file mode 100755 index 5d5868779..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/PCE.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mednafen_pce_fast -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -nice -20 minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/PKM.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/PKM.pak/default.cfg deleted file mode 100644 index 871a58d2b..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/PKM.pak/default.cfg +++ /dev/null @@ -1,17 +0,0 @@ -minarch_screen_scaling = Native - -pokemini_video_scale = 6x --pokemini_60hz_mode = enabled -pokemini_palette = Old -pokemini_piezofilter = disabled -pokemini_lowpass_filter = enabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = A -bind B Button = B -bind C Button = R1 -bind Shake = L1 -bind Power = SELECT diff --git a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/PKM.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/PKM.pak/launch.sh deleted file mode 100755 index e4fa81498..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/PKM.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=pokemini -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -nice -20 minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/SGB.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/SGB.pak/default.cfg deleted file mode 100644 index 78fdedb28..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/SGB.pak/default.cfg +++ /dev/null @@ -1,24 +0,0 @@ --mgba_gb_model = Super Game Boy -mgba_skip_bios = ON --mgba_gb_colors_preset = 2 --mgba_force_gbp = OFF --mgba_color_correction = OFF --mgba_interframe_blending = OFF -mgba_sgb_borders = ON - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 -bind L Turbo = NONE:L2 -bind R Turbo = NONE:R2 -bind More Sun = NONE:L3 -bind Less Sun = NONE:R3 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/SGB.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/SGB.pak/launch.sh deleted file mode 100755 index 6fbf5befb..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/SGB.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mgba -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -nice -20 minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/SMS.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/SMS.pak/default.cfg deleted file mode 100644 index 0d2df362d..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/SMS.pak/default.cfg +++ /dev/null @@ -1,19 +0,0 @@ --picodrive_smstype = Master System -picodrive_smsmapper = Auto --picodrive_ggghost = off --picodrive_sound_rate = 44100 --picodrive_ramcart = disabled --picodrive_dacnoise = disabled --picodrive_input1 = 3 button pad --picodrive_input2 = 3 button pad --picodrive_fm_filter = off --picodrive_audio_filter = disabled --picodrive_overclk68k = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Button 1 = B -bind Button 2 = A -bind Pause = START diff --git a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/SMS.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/SMS.pak/launch.sh deleted file mode 100755 index 0fdffa382..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/SMS.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -nice -20 minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/SUPA.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/SUPA.pak/default.cfg deleted file mode 100644 index 07fcd8d65..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/SUPA.pak/default.cfg +++ /dev/null @@ -1,15 +0,0 @@ --supafaust_pixel_format = rgb565 --supafaust_thread_affinity_emu = 0x0 - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Y Button = Y -bind X Button = X -bind B Button = B -bind A Button = A -bind L Button = L1 -bind R Button = R1 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/SUPA.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/SUPA.pak/launch.sh deleted file mode 100755 index 07d4eb23d..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/SUPA.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mednafen_supafaust -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -nice -20 minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/VB.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/VB.pak/default.cfg deleted file mode 100644 index a83095a2b..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/VB.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ -minarch_cpu_speed = Performance - --vb_3dmode = anaglyph --vb_right_analog_to_digital = disabled - -bind L. Up = UP -bind L. Down = DOWN -bind L. Left = LEFT -bind L. Right = RIGHT -bind Select = SELECT -bind Start = START -bind A = A -bind B = B -bind L Button = L1 -bind R Button = R1 -bind Low Battery = NONE:X -bind R. Up = NONE:L2 -bind R. Down = NONE:L3 -bind R. Left = NONE:R2 -bind R. Right = NONE:R3 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/VB.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/VB.pak/launch.sh deleted file mode 100755 index 7534512f1..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/miyoomini/VB.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mednafen_vb -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -nice -20 minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my282/GG.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/my282/GG.pak/default.cfg deleted file mode 100644 index 44ce34743..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my282/GG.pak/default.cfg +++ /dev/null @@ -1,18 +0,0 @@ --picodrive_smstype = Game Gear --picodrive_smsmapper = Auto --picodrive_sound_rate = 44100 --picodrive_ramcart = disabled --picodrive_dacnoise = disabled --picodrive_input1 = 3 button pad --picodrive_input2 = 3 button pad --picodrive_fm_filter = off --picodrive_audio_filter = disabled --picodrive_overclk68k = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Button 1 = B -bind Button 2 = A -bind Pause = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my282/GG.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/my282/GG.pak/launch.sh deleted file mode 100755 index 8ceb019a2..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my282/GG.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my282/MGBA.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/my282/MGBA.pak/default.cfg deleted file mode 100644 index 266d90c20..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my282/MGBA.pak/default.cfg +++ /dev/null @@ -1,18 +0,0 @@ -mgba_skip_bios = ON - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 -bind L Turbo = NONE:L2 -bind R Turbo = NONE:R2 -bind More Sun = NONE:L3 -bind Less Sun = NONE:R3 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my282/MGBA.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/my282/MGBA.pak/launch.sh deleted file mode 100755 index 598c1ca44..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my282/MGBA.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mgba -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my282/NGP.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/my282/NGP.pak/default.cfg deleted file mode 100644 index 33f5a6b95..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my282/NGP.pak/default.cfg +++ /dev/null @@ -1,9 +0,0 @@ -race_dark_filter_level = 50 - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = B -bind B Button = A -bind Option = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my282/NGP.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/my282/NGP.pak/launch.sh deleted file mode 100644 index 09ec144ee..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my282/NGP.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=race -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my282/NGPC.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/my282/NGPC.pak/default.cfg deleted file mode 100644 index 7d05719ba..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my282/NGPC.pak/default.cfg +++ /dev/null @@ -1,7 +0,0 @@ -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = B -bind B Button = A -bind Option = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my282/NGPC.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/my282/NGPC.pak/launch.sh deleted file mode 100644 index 09ec144ee..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my282/NGPC.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=race -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my282/P8.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/my282/P8.pak/default.cfg deleted file mode 100644 index 73611d3f3..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my282/P8.pak/default.cfg +++ /dev/null @@ -1,7 +0,0 @@ -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = A -bind B Button = B -bind Start = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my282/P8.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/my282/P8.pak/launch.sh deleted file mode 100755 index 2e6658a91..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my282/P8.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=fake08 -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my282/PCE.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/my282/PCE.pak/default.cfg deleted file mode 100644 index 671219086..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my282/PCE.pak/default.cfg +++ /dev/null @@ -1,15 +0,0 @@ --pce_fast_turbo_toggle_hotkey = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Run = START -bind I = A -bind II = B -bind III = Y -bind IV = X -bind V = L1 -bind VI = R1 -bind Mode = L2 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my282/PCE.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/my282/PCE.pak/launch.sh deleted file mode 100755 index 3d92d15cc..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my282/PCE.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mednafen_pce_fast -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my282/PKM.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/my282/PKM.pak/default.cfg deleted file mode 100644 index f6d20d9bb..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my282/PKM.pak/default.cfg +++ /dev/null @@ -1,17 +0,0 @@ -minarch_screen_scaling = Native - -pokemini_video_scale = 3x --pokemini_60hz_mode = enabled -pokemini_palette = Old -pokemini_piezofilter = disabled -pokemini_lowpass_filter = enabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = A -bind B Button = B -bind C Button = R1 -bind Shake = L1 -bind Power = SELECT diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my282/PKM.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/my282/PKM.pak/launch.sh deleted file mode 100755 index 4f9cbbf4d..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my282/PKM.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=pokemini -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my282/SGB.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/my282/SGB.pak/default.cfg deleted file mode 100644 index 78fdedb28..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my282/SGB.pak/default.cfg +++ /dev/null @@ -1,24 +0,0 @@ --mgba_gb_model = Super Game Boy -mgba_skip_bios = ON --mgba_gb_colors_preset = 2 --mgba_force_gbp = OFF --mgba_color_correction = OFF --mgba_interframe_blending = OFF -mgba_sgb_borders = ON - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 -bind L Turbo = NONE:L2 -bind R Turbo = NONE:R2 -bind More Sun = NONE:L3 -bind Less Sun = NONE:R3 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my282/SGB.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/my282/SGB.pak/launch.sh deleted file mode 100755 index 598c1ca44..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my282/SGB.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mgba -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my282/SMS.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/my282/SMS.pak/default.cfg deleted file mode 100644 index 0d2df362d..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my282/SMS.pak/default.cfg +++ /dev/null @@ -1,19 +0,0 @@ --picodrive_smstype = Master System -picodrive_smsmapper = Auto --picodrive_ggghost = off --picodrive_sound_rate = 44100 --picodrive_ramcart = disabled --picodrive_dacnoise = disabled --picodrive_input1 = 3 button pad --picodrive_input2 = 3 button pad --picodrive_fm_filter = off --picodrive_audio_filter = disabled --picodrive_overclk68k = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Button 1 = B -bind Button 2 = A -bind Pause = START diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my282/SMS.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/my282/SMS.pak/launch.sh deleted file mode 100755 index 8ceb019a2..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my282/SMS.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my282/SUPA.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/my282/SUPA.pak/default.cfg deleted file mode 100644 index 07fcd8d65..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my282/SUPA.pak/default.cfg +++ /dev/null @@ -1,15 +0,0 @@ --supafaust_pixel_format = rgb565 --supafaust_thread_affinity_emu = 0x0 - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Y Button = Y -bind X Button = X -bind B Button = B -bind A Button = A -bind L Button = L1 -bind R Button = R1 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my282/SUPA.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/my282/SUPA.pak/launch.sh deleted file mode 100755 index 09cc58d7a..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my282/SUPA.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mednafen_supafaust -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my282/VB.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/my282/VB.pak/default.cfg deleted file mode 100644 index a83095a2b..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my282/VB.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ -minarch_cpu_speed = Performance - --vb_3dmode = anaglyph --vb_right_analog_to_digital = disabled - -bind L. Up = UP -bind L. Down = DOWN -bind L. Left = LEFT -bind L. Right = RIGHT -bind Select = SELECT -bind Start = START -bind A = A -bind B = B -bind L Button = L1 -bind R Button = R1 -bind Low Battery = NONE:X -bind R. Up = NONE:L2 -bind R. Down = NONE:L3 -bind R. Left = NONE:R2 -bind R. Right = NONE:R3 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my282/VB.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/my282/VB.pak/launch.sh deleted file mode 100755 index 4094998e9..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my282/VB.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mednafen_vb -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my355/GG.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/my355/GG.pak/default.cfg deleted file mode 100644 index 44ce34743..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my355/GG.pak/default.cfg +++ /dev/null @@ -1,18 +0,0 @@ --picodrive_smstype = Game Gear --picodrive_smsmapper = Auto --picodrive_sound_rate = 44100 --picodrive_ramcart = disabled --picodrive_dacnoise = disabled --picodrive_input1 = 3 button pad --picodrive_input2 = 3 button pad --picodrive_fm_filter = off --picodrive_audio_filter = disabled --picodrive_overclk68k = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Button 1 = B -bind Button 2 = A -bind Pause = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my355/GG.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/my355/GG.pak/launch.sh deleted file mode 100755 index 8ceb019a2..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my355/GG.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my355/MGBA.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/my355/MGBA.pak/default.cfg deleted file mode 100644 index 266d90c20..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my355/MGBA.pak/default.cfg +++ /dev/null @@ -1,18 +0,0 @@ -mgba_skip_bios = ON - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 -bind L Turbo = NONE:L2 -bind R Turbo = NONE:R2 -bind More Sun = NONE:L3 -bind Less Sun = NONE:R3 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my355/MGBA.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/my355/MGBA.pak/launch.sh deleted file mode 100755 index 598c1ca44..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my355/MGBA.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mgba -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my355/NGP.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/my355/NGP.pak/default.cfg deleted file mode 100644 index 33f5a6b95..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my355/NGP.pak/default.cfg +++ /dev/null @@ -1,9 +0,0 @@ -race_dark_filter_level = 50 - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = B -bind B Button = A -bind Option = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my355/NGP.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/my355/NGP.pak/launch.sh deleted file mode 100644 index 09ec144ee..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my355/NGP.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=race -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my355/NGPC.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/my355/NGPC.pak/default.cfg deleted file mode 100644 index 7d05719ba..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my355/NGPC.pak/default.cfg +++ /dev/null @@ -1,7 +0,0 @@ -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = B -bind B Button = A -bind Option = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my355/NGPC.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/my355/NGPC.pak/launch.sh deleted file mode 100644 index 09ec144ee..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my355/NGPC.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=race -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my355/P8.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/my355/P8.pak/default.cfg deleted file mode 100644 index 73611d3f3..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my355/P8.pak/default.cfg +++ /dev/null @@ -1,7 +0,0 @@ -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = A -bind B Button = B -bind Start = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my355/P8.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/my355/P8.pak/launch.sh deleted file mode 100755 index 2e6658a91..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my355/P8.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=fake08 -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my355/PCE.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/my355/PCE.pak/default.cfg deleted file mode 100644 index 671219086..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my355/PCE.pak/default.cfg +++ /dev/null @@ -1,15 +0,0 @@ --pce_fast_turbo_toggle_hotkey = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Run = START -bind I = A -bind II = B -bind III = Y -bind IV = X -bind V = L1 -bind VI = R1 -bind Mode = L2 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my355/PCE.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/my355/PCE.pak/launch.sh deleted file mode 100755 index 3d92d15cc..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my355/PCE.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mednafen_pce_fast -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my355/PKM.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/my355/PKM.pak/default.cfg deleted file mode 100644 index f6d20d9bb..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my355/PKM.pak/default.cfg +++ /dev/null @@ -1,17 +0,0 @@ -minarch_screen_scaling = Native - -pokemini_video_scale = 3x --pokemini_60hz_mode = enabled -pokemini_palette = Old -pokemini_piezofilter = disabled -pokemini_lowpass_filter = enabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = A -bind B Button = B -bind C Button = R1 -bind Shake = L1 -bind Power = SELECT diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my355/PKM.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/my355/PKM.pak/launch.sh deleted file mode 100755 index 4f9cbbf4d..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my355/PKM.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=pokemini -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my355/SGB.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/my355/SGB.pak/default.cfg deleted file mode 100644 index 78fdedb28..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my355/SGB.pak/default.cfg +++ /dev/null @@ -1,24 +0,0 @@ --mgba_gb_model = Super Game Boy -mgba_skip_bios = ON --mgba_gb_colors_preset = 2 --mgba_force_gbp = OFF --mgba_color_correction = OFF --mgba_interframe_blending = OFF -mgba_sgb_borders = ON - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 -bind L Turbo = NONE:L2 -bind R Turbo = NONE:R2 -bind More Sun = NONE:L3 -bind Less Sun = NONE:R3 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my355/SGB.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/my355/SGB.pak/launch.sh deleted file mode 100755 index 598c1ca44..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my355/SGB.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mgba -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my355/SMS.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/my355/SMS.pak/default.cfg deleted file mode 100644 index 0d2df362d..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my355/SMS.pak/default.cfg +++ /dev/null @@ -1,19 +0,0 @@ --picodrive_smstype = Master System -picodrive_smsmapper = Auto --picodrive_ggghost = off --picodrive_sound_rate = 44100 --picodrive_ramcart = disabled --picodrive_dacnoise = disabled --picodrive_input1 = 3 button pad --picodrive_input2 = 3 button pad --picodrive_fm_filter = off --picodrive_audio_filter = disabled --picodrive_overclk68k = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Button 1 = B -bind Button 2 = A -bind Pause = START diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my355/SMS.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/my355/SMS.pak/launch.sh deleted file mode 100755 index 8ceb019a2..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my355/SMS.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my355/SUPA.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/my355/SUPA.pak/default.cfg deleted file mode 100644 index 07fcd8d65..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my355/SUPA.pak/default.cfg +++ /dev/null @@ -1,15 +0,0 @@ --supafaust_pixel_format = rgb565 --supafaust_thread_affinity_emu = 0x0 - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Y Button = Y -bind X Button = X -bind B Button = B -bind A Button = A -bind L Button = L1 -bind R Button = R1 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my355/SUPA.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/my355/SUPA.pak/launch.sh deleted file mode 100755 index 09cc58d7a..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my355/SUPA.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mednafen_supafaust -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my355/VB.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/my355/VB.pak/default.cfg deleted file mode 100644 index a83095a2b..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my355/VB.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ -minarch_cpu_speed = Performance - --vb_3dmode = anaglyph --vb_right_analog_to_digital = disabled - -bind L. Up = UP -bind L. Down = DOWN -bind L. Left = LEFT -bind L. Right = RIGHT -bind Select = SELECT -bind Start = START -bind A = A -bind B = B -bind L Button = L1 -bind R Button = R1 -bind Low Battery = NONE:X -bind R. Up = NONE:L2 -bind R. Down = NONE:L3 -bind R. Left = NONE:R2 -bind R. Right = NONE:R3 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/my355/VB.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/my355/VB.pak/launch.sh deleted file mode 100755 index 4094998e9..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/my355/VB.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mednafen_vb -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/GG.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/GG.pak/default.cfg deleted file mode 100644 index 44ce34743..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/GG.pak/default.cfg +++ /dev/null @@ -1,18 +0,0 @@ --picodrive_smstype = Game Gear --picodrive_smsmapper = Auto --picodrive_sound_rate = 44100 --picodrive_ramcart = disabled --picodrive_dacnoise = disabled --picodrive_input1 = 3 button pad --picodrive_input2 = 3 button pad --picodrive_fm_filter = off --picodrive_audio_filter = disabled --picodrive_overclk68k = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Button 1 = B -bind Button 2 = A -bind Pause = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/GG.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/GG.pak/launch.sh deleted file mode 100755 index 81688be79..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/GG.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/MGBA.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/MGBA.pak/default.cfg deleted file mode 100644 index 266d90c20..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/MGBA.pak/default.cfg +++ /dev/null @@ -1,18 +0,0 @@ -mgba_skip_bios = ON - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 -bind L Turbo = NONE:L2 -bind R Turbo = NONE:R2 -bind More Sun = NONE:L3 -bind Less Sun = NONE:R3 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/MGBA.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/MGBA.pak/launch.sh deleted file mode 100755 index 796c1be58..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/MGBA.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mgba -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/NGP.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/NGP.pak/default.cfg deleted file mode 100644 index 33f5a6b95..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/NGP.pak/default.cfg +++ /dev/null @@ -1,9 +0,0 @@ -race_dark_filter_level = 50 - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = B -bind B Button = A -bind Option = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/NGP.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/NGP.pak/launch.sh deleted file mode 100644 index 138a2b10b..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/NGP.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=race -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/NGPC.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/NGPC.pak/default.cfg deleted file mode 100644 index 7d05719ba..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/NGPC.pak/default.cfg +++ /dev/null @@ -1,7 +0,0 @@ -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = B -bind B Button = A -bind Option = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/NGPC.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/NGPC.pak/launch.sh deleted file mode 100644 index 138a2b10b..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/NGPC.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=race -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/P8.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/P8.pak/default.cfg deleted file mode 100644 index 73611d3f3..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/P8.pak/default.cfg +++ /dev/null @@ -1,7 +0,0 @@ -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = A -bind B Button = B -bind Start = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/P8.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/P8.pak/launch.sh deleted file mode 100755 index b3de7565d..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/P8.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=fake08 -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/PCE.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/PCE.pak/default.cfg deleted file mode 100644 index 671219086..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/PCE.pak/default.cfg +++ /dev/null @@ -1,15 +0,0 @@ --pce_fast_turbo_toggle_hotkey = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Run = START -bind I = A -bind II = B -bind III = Y -bind IV = X -bind V = L1 -bind VI = R1 -bind Mode = L2 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/PCE.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/PCE.pak/launch.sh deleted file mode 100755 index 7bf829940..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/PCE.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mednafen_pce_fast -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/PKM.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/PKM.pak/default.cfg deleted file mode 100644 index 871a58d2b..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/PKM.pak/default.cfg +++ /dev/null @@ -1,17 +0,0 @@ -minarch_screen_scaling = Native - -pokemini_video_scale = 6x --pokemini_60hz_mode = enabled -pokemini_palette = Old -pokemini_piezofilter = disabled -pokemini_lowpass_filter = enabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = A -bind B Button = B -bind C Button = R1 -bind Shake = L1 -bind Power = SELECT diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/PKM.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/PKM.pak/launch.sh deleted file mode 100755 index 098f76f1c..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/PKM.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=pokemini -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/SGB.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/SGB.pak/default.cfg deleted file mode 100644 index 78fdedb28..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/SGB.pak/default.cfg +++ /dev/null @@ -1,24 +0,0 @@ --mgba_gb_model = Super Game Boy -mgba_skip_bios = ON --mgba_gb_colors_preset = 2 --mgba_force_gbp = OFF --mgba_color_correction = OFF --mgba_interframe_blending = OFF -mgba_sgb_borders = ON - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 -bind L Turbo = NONE:L2 -bind R Turbo = NONE:R2 -bind More Sun = NONE:L3 -bind Less Sun = NONE:R3 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/SGB.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/SGB.pak/launch.sh deleted file mode 100755 index 796c1be58..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/SGB.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mgba -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/SMS.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/SMS.pak/default.cfg deleted file mode 100644 index 0d2df362d..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/SMS.pak/default.cfg +++ /dev/null @@ -1,19 +0,0 @@ --picodrive_smstype = Master System -picodrive_smsmapper = Auto --picodrive_ggghost = off --picodrive_sound_rate = 44100 --picodrive_ramcart = disabled --picodrive_dacnoise = disabled --picodrive_input1 = 3 button pad --picodrive_input2 = 3 button pad --picodrive_fm_filter = off --picodrive_audio_filter = disabled --picodrive_overclk68k = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Button 1 = B -bind Button 2 = A -bind Pause = START diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/SMS.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/SMS.pak/launch.sh deleted file mode 100755 index 81688be79..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/SMS.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/SUPA.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/SUPA.pak/default.cfg deleted file mode 100644 index 07fcd8d65..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/SUPA.pak/default.cfg +++ /dev/null @@ -1,15 +0,0 @@ --supafaust_pixel_format = rgb565 --supafaust_thread_affinity_emu = 0x0 - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Y Button = Y -bind X Button = X -bind B Button = B -bind A Button = A -bind L Button = L1 -bind R Button = R1 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/SUPA.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/SUPA.pak/launch.sh deleted file mode 100755 index 331d02280..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/SUPA.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mednafen_supafaust -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/VB.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/VB.pak/default.cfg deleted file mode 100644 index a83095a2b..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/VB.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ -minarch_cpu_speed = Performance - --vb_3dmode = anaglyph --vb_right_analog_to_digital = disabled - -bind L. Up = UP -bind L. Down = DOWN -bind L. Left = LEFT -bind L. Right = RIGHT -bind Select = SELECT -bind Start = START -bind A = A -bind B = B -bind L Button = L1 -bind R Button = R1 -bind Low Battery = NONE:X -bind R. Up = NONE:L2 -bind R. Down = NONE:L3 -bind R. Left = NONE:R2 -bind R. Right = NONE:R3 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/VB.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/VB.pak/launch.sh deleted file mode 100755 index e5146dd57..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xx/VB.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mednafen_vb -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/GG.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/GG.pak/default.cfg deleted file mode 100644 index 26e6650e3..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/GG.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ -minarch_cpu_speed = Powersave - --picodrive_smstype = Game Gear --picodrive_smsmapper = Auto --picodrive_sound_rate = 44100 --picodrive_ramcart = disabled --picodrive_dacnoise = disabled --picodrive_input1 = 3 button pad --picodrive_input2 = 3 button pad --picodrive_fm_filter = off --picodrive_audio_filter = disabled --picodrive_overclk68k = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Button 1 = B -bind Button 2 = A -bind Pause = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/GG.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/GG.pak/launch.sh deleted file mode 100755 index 8ceb019a2..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/GG.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/MGBA.pak/default-cube.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/MGBA.pak/default-cube.cfg deleted file mode 100644 index ac252c369..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/MGBA.pak/default-cube.cfg +++ /dev/null @@ -1,21 +0,0 @@ -minarch_screen_scaling = Native -minarch_screen_sharpness = Sharp - -mgba_skip_bios = ON - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 -bind L Turbo = NONE:L2 -bind R Turbo = NONE:R2 -bind More Sun = NONE:L3 -bind Less Sun = NONE:R3 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/MGBA.pak/default-wide.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/MGBA.pak/default-wide.cfg deleted file mode 100644 index ac252c369..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/MGBA.pak/default-wide.cfg +++ /dev/null @@ -1,21 +0,0 @@ -minarch_screen_scaling = Native -minarch_screen_sharpness = Sharp - -mgba_skip_bios = ON - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 -bind L Turbo = NONE:L2 -bind R Turbo = NONE:R2 -bind More Sun = NONE:L3 -bind Less Sun = NONE:R3 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/MGBA.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/MGBA.pak/default.cfg deleted file mode 100644 index 266d90c20..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/MGBA.pak/default.cfg +++ /dev/null @@ -1,18 +0,0 @@ -mgba_skip_bios = ON - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 -bind L Turbo = NONE:L2 -bind R Turbo = NONE:R2 -bind More Sun = NONE:L3 -bind Less Sun = NONE:R3 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/MGBA.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/MGBA.pak/launch.sh deleted file mode 100755 index 598c1ca44..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/MGBA.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mgba -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/NGP.pak/default-cube.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/NGP.pak/default-cube.cfg deleted file mode 100644 index f78a6e8fe..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/NGP.pak/default-cube.cfg +++ /dev/null @@ -1,13 +0,0 @@ -minarch_screen_scaling = Native -minarch_screen_sharpness = Sharp -minarch_cpu_speed = Powersave - -race_dark_filter_level = 50 - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = B -bind B Button = A -bind Option = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/NGP.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/NGP.pak/default.cfg deleted file mode 100644 index e25e3a592..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/NGP.pak/default.cfg +++ /dev/null @@ -1,11 +0,0 @@ -minarch_cpu_speed = Powersave - -race_dark_filter_level = 50 - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = B -bind B Button = A -bind Option = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/NGP.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/NGP.pak/launch.sh deleted file mode 100644 index 09ec144ee..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/NGP.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=race -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/NGPC.pak/default-cube.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/NGPC.pak/default-cube.cfg deleted file mode 100644 index f78a6e8fe..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/NGPC.pak/default-cube.cfg +++ /dev/null @@ -1,13 +0,0 @@ -minarch_screen_scaling = Native -minarch_screen_sharpness = Sharp -minarch_cpu_speed = Powersave - -race_dark_filter_level = 50 - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = B -bind B Button = A -bind Option = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/NGPC.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/NGPC.pak/default.cfg deleted file mode 100644 index e25e3a592..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/NGPC.pak/default.cfg +++ /dev/null @@ -1,11 +0,0 @@ -minarch_cpu_speed = Powersave - -race_dark_filter_level = 50 - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = B -bind B Button = A -bind Option = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/NGPC.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/NGPC.pak/launch.sh deleted file mode 100644 index 09ec144ee..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/NGPC.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=race -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/P8.pak/default-cube.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/P8.pak/default-cube.cfg deleted file mode 100644 index 299811b4a..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/P8.pak/default-cube.cfg +++ /dev/null @@ -1,10 +0,0 @@ -minarch_screen_scaling = Native -minarch_screen_sharpness = Sharp - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = A -bind B Button = B -bind Start = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/P8.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/P8.pak/default.cfg deleted file mode 100644 index 73611d3f3..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/P8.pak/default.cfg +++ /dev/null @@ -1,7 +0,0 @@ -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = A -bind B Button = B -bind Start = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/P8.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/P8.pak/launch.sh deleted file mode 100755 index 2e6658a91..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/P8.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=fake08 -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/PCE.pak/default-cube.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/PCE.pak/default-cube.cfg deleted file mode 100644 index 1c07fe5ed..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/PCE.pak/default-cube.cfg +++ /dev/null @@ -1,18 +0,0 @@ -minarch_screen_scaling = Cropped -minarch_screen_sharpness = Sharp - --pce_fast_turbo_toggle_hotkey = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Run = START -bind I = A -bind II = B -bind III = Y -bind IV = X -bind V = L1 -bind VI = R1 -bind Mode = L2 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/PCE.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/PCE.pak/default.cfg deleted file mode 100644 index 671219086..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/PCE.pak/default.cfg +++ /dev/null @@ -1,15 +0,0 @@ --pce_fast_turbo_toggle_hotkey = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Run = START -bind I = A -bind II = B -bind III = Y -bind IV = X -bind V = L1 -bind VI = R1 -bind Mode = L2 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/PCE.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/PCE.pak/launch.sh deleted file mode 100755 index 3d92d15cc..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/PCE.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mednafen_pce_fast -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/PKM.pak/default-cube.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/PKM.pak/default-cube.cfg deleted file mode 100644 index 58b6070a0..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/PKM.pak/default-cube.cfg +++ /dev/null @@ -1,18 +0,0 @@ -minarch_screen_scaling = Native -minarch_screen_sharpness = Sharp - -pokemini_video_scale = 7x --pokemini_60hz_mode = enabled -pokemini_palette = Old -pokemini_piezofilter = disabled -pokemini_lowpass_filter = enabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = A -bind B Button = B -bind C Button = R1 -bind Shake = L1 -bind Power = SELECT diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/PKM.pak/default-wide.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/PKM.pak/default-wide.cfg deleted file mode 100644 index 58b6070a0..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/PKM.pak/default-wide.cfg +++ /dev/null @@ -1,18 +0,0 @@ -minarch_screen_scaling = Native -minarch_screen_sharpness = Sharp - -pokemini_video_scale = 7x --pokemini_60hz_mode = enabled -pokemini_palette = Old -pokemini_piezofilter = disabled -pokemini_lowpass_filter = enabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = A -bind B Button = B -bind C Button = R1 -bind Shake = L1 -bind Power = SELECT diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/PKM.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/PKM.pak/default.cfg deleted file mode 100644 index c88bd456e..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/PKM.pak/default.cfg +++ /dev/null @@ -1,18 +0,0 @@ -minarch_screen_scaling = Native -minarch_screen_sharpness = Sharp - -pokemini_video_scale = 6x --pokemini_60hz_mode = enabled -pokemini_palette = Old -pokemini_piezofilter = disabled -pokemini_lowpass_filter = enabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = A -bind B Button = B -bind C Button = R1 -bind Shake = L1 -bind Power = SELECT diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/PKM.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/PKM.pak/launch.sh deleted file mode 100755 index 4f9cbbf4d..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/PKM.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=pokemini -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SGB.pak/default-cube.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SGB.pak/default-cube.cfg deleted file mode 100644 index 8bb01a30e..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SGB.pak/default-cube.cfg +++ /dev/null @@ -1,28 +0,0 @@ -minarch_screen_scaling = Cropped -minarch_screen_sharpness = Sharp -minarch_cpu_speed = Powersave - --mgba_gb_model = Super Game Boy -mgba_skip_bios = ON --mgba_gb_colors_preset = 2 --mgba_force_gbp = OFF --mgba_color_correction = OFF --mgba_interframe_blending = OFF -mgba_sgb_borders = ON - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 -bind L Turbo = NONE:L2 -bind R Turbo = NONE:R2 -bind More Sun = NONE:L3 -bind Less Sun = NONE:R3 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SGB.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SGB.pak/default.cfg deleted file mode 100644 index 2396b1330..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SGB.pak/default.cfg +++ /dev/null @@ -1,26 +0,0 @@ -minarch_cpu_speed = Powersave - --mgba_gb_model = Super Game Boy -mgba_skip_bios = ON --mgba_gb_colors_preset = 2 --mgba_force_gbp = OFF --mgba_color_correction = OFF --mgba_interframe_blending = OFF -mgba_sgb_borders = ON - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 -bind L Turbo = NONE:L2 -bind R Turbo = NONE:R2 -bind More Sun = NONE:L3 -bind Less Sun = NONE:R3 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SGB.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SGB.pak/launch.sh deleted file mode 100755 index 598c1ca44..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SGB.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mgba -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SMS.pak/default-cube.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SMS.pak/default-cube.cfg deleted file mode 100644 index 4fe5bd154..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SMS.pak/default-cube.cfg +++ /dev/null @@ -1,23 +0,0 @@ -minarch_screen_scaling = Cropped -minarch_screen_sharpness = Sharp -minarch_cpu_speed = Powersave - --picodrive_smstype = Master System -picodrive_smsmapper = Auto --picodrive_ggghost = off --picodrive_sound_rate = 44100 --picodrive_ramcart = disabled --picodrive_dacnoise = disabled --picodrive_input1 = 3 button pad --picodrive_input2 = 3 button pad --picodrive_fm_filter = off --picodrive_audio_filter = disabled --picodrive_overclk68k = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Button 1 = B -bind Button 2 = A -bind Pause = START diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SMS.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SMS.pak/default.cfg deleted file mode 100644 index a28f9271d..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SMS.pak/default.cfg +++ /dev/null @@ -1,21 +0,0 @@ -minarch_cpu_speed = Powersave - --picodrive_smstype = Master System -picodrive_smsmapper = Auto --picodrive_ggghost = off --picodrive_sound_rate = 44100 --picodrive_ramcart = disabled --picodrive_dacnoise = disabled --picodrive_input1 = 3 button pad --picodrive_input2 = 3 button pad --picodrive_fm_filter = off --picodrive_audio_filter = disabled --picodrive_overclk68k = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Button 1 = B -bind Button 2 = A -bind Pause = START diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SMS.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SMS.pak/launch.sh deleted file mode 100755 index 8ceb019a2..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SMS.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SUPA.pak/default-cube.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SUPA.pak/default-cube.cfg deleted file mode 100644 index ceb675749..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SUPA.pak/default-cube.cfg +++ /dev/null @@ -1,18 +0,0 @@ -minarch_screen_scaling = Cropped -minarch_screen_sharpness = Sharp - --supafaust_pixel_format = rgb565 --supafaust_thread_affinity_emu = 0x0 - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Y Button = Y -bind X Button = X -bind B Button = B -bind A Button = A -bind L Button = L1 -bind R Button = R1 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SUPA.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SUPA.pak/default.cfg deleted file mode 100644 index 07fcd8d65..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SUPA.pak/default.cfg +++ /dev/null @@ -1,15 +0,0 @@ --supafaust_pixel_format = rgb565 --supafaust_thread_affinity_emu = 0x0 - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Y Button = Y -bind X Button = X -bind B Button = B -bind A Button = A -bind L Button = L1 -bind R Button = R1 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SUPA.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SUPA.pak/launch.sh deleted file mode 100755 index 09cc58d7a..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/SUPA.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mednafen_supafaust -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/VB.pak/default-cube.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/VB.pak/default-cube.cfg deleted file mode 100644 index 162c2d503..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/VB.pak/default-cube.cfg +++ /dev/null @@ -1,22 +0,0 @@ -minarch_screen_scaling = Cropped -minarch_screen_sharpness = Sharp -minarch_cpu_speed = Performance - --vb_3dmode = anaglyph --vb_right_analog_to_digital = disabled - -bind L. Up = UP -bind L. Down = DOWN -bind L. Left = LEFT -bind L. Right = RIGHT -bind Select = SELECT -bind Start = START -bind A = A -bind B = B -bind L Button = L1 -bind R Button = R1 -bind Low Battery = NONE:X -bind R. Up = NONE:L2 -bind R. Down = NONE:L3 -bind R. Left = NONE:R2 -bind R. Right = NONE:R3 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/VB.pak/default-wide.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/VB.pak/default-wide.cfg deleted file mode 100644 index 162c2d503..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/VB.pak/default-wide.cfg +++ /dev/null @@ -1,22 +0,0 @@ -minarch_screen_scaling = Cropped -minarch_screen_sharpness = Sharp -minarch_cpu_speed = Performance - --vb_3dmode = anaglyph --vb_right_analog_to_digital = disabled - -bind L. Up = UP -bind L. Down = DOWN -bind L. Left = LEFT -bind L. Right = RIGHT -bind Select = SELECT -bind Start = START -bind A = A -bind B = B -bind L Button = L1 -bind R Button = R1 -bind Low Battery = NONE:X -bind R. Up = NONE:L2 -bind R. Down = NONE:L3 -bind R. Left = NONE:R2 -bind R. Right = NONE:R3 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/VB.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/VB.pak/default.cfg deleted file mode 100644 index a83095a2b..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/VB.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ -minarch_cpu_speed = Performance - --vb_3dmode = anaglyph --vb_right_analog_to_digital = disabled - -bind L. Up = UP -bind L. Down = DOWN -bind L. Left = LEFT -bind L. Right = RIGHT -bind Select = SELECT -bind Start = START -bind A = A -bind B = B -bind L Button = L1 -bind R Button = R1 -bind Low Battery = NONE:X -bind R. Up = NONE:L2 -bind R. Down = NONE:L3 -bind R. Left = NONE:R2 -bind R. Right = NONE:R3 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/VB.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/VB.pak/launch.sh deleted file mode 100755 index 4094998e9..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rg35xxplus/VB.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mednafen_vb -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/GG.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rgb30/GG.pak/default.cfg deleted file mode 100644 index 26e6650e3..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/GG.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ -minarch_cpu_speed = Powersave - --picodrive_smstype = Game Gear --picodrive_smsmapper = Auto --picodrive_sound_rate = 44100 --picodrive_ramcart = disabled --picodrive_dacnoise = disabled --picodrive_input1 = 3 button pad --picodrive_input2 = 3 button pad --picodrive_fm_filter = off --picodrive_audio_filter = disabled --picodrive_overclk68k = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Button 1 = B -bind Button 2 = A -bind Pause = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/GG.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rgb30/GG.pak/launch.sh deleted file mode 100755 index 81688be79..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/GG.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/MGBA.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rgb30/MGBA.pak/default.cfg deleted file mode 100755 index 978475011..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/MGBA.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ -minarch_screen_scaling = Native - -mgba_skip_bios = ON - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 -bind L Turbo = NONE:L2 -bind R Turbo = NONE:R2 -bind More Sun = NONE:L3 -bind Less Sun = NONE:R3 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/MGBA.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rgb30/MGBA.pak/launch.sh deleted file mode 100755 index 796c1be58..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/MGBA.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mgba -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/NGP.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rgb30/NGP.pak/default.cfg deleted file mode 100644 index e25e3a592..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/NGP.pak/default.cfg +++ /dev/null @@ -1,11 +0,0 @@ -minarch_cpu_speed = Powersave - -race_dark_filter_level = 50 - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = B -bind B Button = A -bind Option = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/NGP.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rgb30/NGP.pak/launch.sh deleted file mode 100644 index 138a2b10b..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/NGP.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=race -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/NGPC.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rgb30/NGPC.pak/default.cfg deleted file mode 100644 index 5ee84ebb6..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/NGPC.pak/default.cfg +++ /dev/null @@ -1,9 +0,0 @@ -minarch_cpu_speed = Powersave - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = B -bind B Button = A -bind Option = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/NGPC.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rgb30/NGPC.pak/launch.sh deleted file mode 100644 index 138a2b10b..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/NGPC.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=race -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/P8-NATIVE.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rgb30/P8-NATIVE.pak/launch.sh deleted file mode 100755 index 15b0cf5ce..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/P8-NATIVE.pak/launch.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -DIR=$(dirname "$0") -PICO8_DIR="$SDCARD_PATH/Tools/$PLATFORM/Splore.pak/pico-8" - -if [ ! -d "$PICO8_DIR" ]; then - show.elf "$DIR/missing.png" 4 - exit -# add sdl controller file if not present in pico-8 folder -elif [ ! -f "$PICO8_DIR/sdl_controllers.txt" ]; then - cp "$DIR/sdl_controllers.txt" "$PICO8_DIR"; -fi - -# ensure correct sdl controller file for rgb30 is in use -cmp -s "$DIR/sdl_controllers.txt" "$PICO8_DIR/sdl_controllers.txt" -if [ "$?" -eq 1 ]; then - cp -f "$DIR/sdl_controllers.txt" "$PICO8_DIR"; -fi - -cd "$PICO8_DIR" -./pico8_64 -run "$1" -pixel_perfect 1 -joystick 0 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/P8-NATIVE.pak/missing.png b/skeleton/_unmaintained/EXTRAS/Emus/rgb30/P8-NATIVE.pak/missing.png deleted file mode 100644 index 218043091144e14c98f1235277b7f977ff199552..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9868 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 bkZJ`zUKfhjd^{KTXGjAb!BoL>Du2r_<% diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/P8.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rgb30/P8.pak/default.cfg deleted file mode 100755 index 73611d3f3..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/P8.pak/default.cfg +++ /dev/null @@ -1,7 +0,0 @@ -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = A -bind B Button = B -bind Start = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/P8.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rgb30/P8.pak/launch.sh deleted file mode 100755 index b3de7565d..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/P8.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=fake08 -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/PCE.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rgb30/PCE.pak/default.cfg deleted file mode 100755 index 772f4b30d..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/PCE.pak/default.cfg +++ /dev/null @@ -1,17 +0,0 @@ -minarch_screen_scaling = Cropped - --pce_fast_turbo_toggle_hotkey = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Run = START -bind I = A -bind II = B -bind III = Y -bind IV = X -bind V = L1 -bind VI = R1 -bind Mode = L2 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/PCE.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rgb30/PCE.pak/launch.sh deleted file mode 100755 index 7bf829940..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/PCE.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mednafen_pce_fast -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/PKM.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rgb30/PKM.pak/default.cfg deleted file mode 100644 index 8dbd625f1..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/PKM.pak/default.cfg +++ /dev/null @@ -1,17 +0,0 @@ -minarch_screen_scaling = Native - -pokemini_video_scale = 7x --pokemini_60hz_mode = enabled -pokemini_palette = Old -pokemini_piezofilter = disabled -pokemini_lowpass_filter = enabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = A -bind B Button = B -bind C Button = R1 -bind Shake = L1 -bind Power = SELECT diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/PKM.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rgb30/PKM.pak/launch.sh deleted file mode 100755 index 098f76f1c..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/PKM.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=pokemini -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/SGB.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rgb30/SGB.pak/default.cfg deleted file mode 100755 index 95101f6a6..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/SGB.pak/default.cfg +++ /dev/null @@ -1,27 +0,0 @@ -minarch_screen_scaling = Cropped -minarch_cpu_speed = Powersave - --mgba_gb_model = Super Game Boy -mgba_skip_bios = ON --mgba_gb_colors_preset = 2 --mgba_force_gbp = OFF --mgba_color_correction = OFF --mgba_interframe_blending = OFF -mgba_sgb_borders = ON - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 -bind L Turbo = NONE:L2 -bind R Turbo = NONE:R2 -bind More Sun = NONE:L3 -bind Less Sun = NONE:R3 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/SGB.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rgb30/SGB.pak/launch.sh deleted file mode 100755 index 796c1be58..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/SGB.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mgba -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/SMS.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rgb30/SMS.pak/default.cfg deleted file mode 100644 index dc6082642..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/SMS.pak/default.cfg +++ /dev/null @@ -1,23 +0,0 @@ -minarch_screen_scaling = Cropped -minarch_cpu_speed = Powersave - - --picodrive_smstype = Master System -picodrive_smsmapper = Auto --picodrive_ggghost = off --picodrive_sound_rate = 44100 --picodrive_ramcart = disabled --picodrive_dacnoise = disabled --picodrive_input1 = 3 button pad --picodrive_input2 = 3 button pad --picodrive_fm_filter = off --picodrive_audio_filter = disabled --picodrive_overclk68k = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Button 1 = B -bind Button 2 = A -bind Pause = START diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/SMS.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rgb30/SMS.pak/launch.sh deleted file mode 100755 index 81688be79..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/SMS.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/SUPA.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rgb30/SUPA.pak/default.cfg deleted file mode 100755 index 442a7c9bf..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/SUPA.pak/default.cfg +++ /dev/null @@ -1,17 +0,0 @@ -minarch_screen_scaling = Cropped - --supafaust_pixel_format = rgb565 --supafaust_thread_affinity_emu = 0x0 - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Y Button = Y -bind X Button = X -bind B Button = B -bind A Button = A -bind L Button = L1 -bind R Button = R1 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/SUPA.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rgb30/SUPA.pak/launch.sh deleted file mode 100755 index 331d02280..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/SUPA.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mednafen_supafaust -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/VB.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/rgb30/VB.pak/default.cfg deleted file mode 100755 index 0430b7661..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/VB.pak/default.cfg +++ /dev/null @@ -1,21 +0,0 @@ -minarch_screen_scaling = Cropped -minarch_cpu_speed = Performance - --vb_3dmode = anaglyph --vb_right_analog_to_digital = disabled - -bind L. Up = UP -bind L. Down = DOWN -bind L. Left = LEFT -bind L. Right = RIGHT -bind Select = SELECT -bind Start = START -bind A = A -bind B = B -bind L Button = L1 -bind R Button = R1 -bind Low Battery = NONE:X -bind R. Up = NONE:L2 -bind R. Down = NONE:L3 -bind R. Left = NONE:R2 -bind R. Right = NONE:R3 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/VB.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/rgb30/VB.pak/launch.sh deleted file mode 100755 index e5146dd57..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/rgb30/VB.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mednafen_vb -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/GG.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/GG.pak/default.cfg deleted file mode 100644 index 44ce34743..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/GG.pak/default.cfg +++ /dev/null @@ -1,18 +0,0 @@ --picodrive_smstype = Game Gear --picodrive_smsmapper = Auto --picodrive_sound_rate = 44100 --picodrive_ramcart = disabled --picodrive_dacnoise = disabled --picodrive_input1 = 3 button pad --picodrive_input2 = 3 button pad --picodrive_fm_filter = off --picodrive_audio_filter = disabled --picodrive_overclk68k = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Button 1 = B -bind Button 2 = A -bind Pause = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/GG.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/GG.pak/launch.sh deleted file mode 100755 index 81688be79..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/GG.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/MGBA.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/MGBA.pak/default.cfg deleted file mode 100644 index 266d90c20..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/MGBA.pak/default.cfg +++ /dev/null @@ -1,18 +0,0 @@ -mgba_skip_bios = ON - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 -bind L Turbo = NONE:L2 -bind R Turbo = NONE:R2 -bind More Sun = NONE:L3 -bind Less Sun = NONE:R3 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/MGBA.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/MGBA.pak/launch.sh deleted file mode 100755 index 796c1be58..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/MGBA.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mgba -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/NGP.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/NGP.pak/default.cfg deleted file mode 100644 index 33f5a6b95..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/NGP.pak/default.cfg +++ /dev/null @@ -1,9 +0,0 @@ -race_dark_filter_level = 50 - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = B -bind B Button = A -bind Option = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/NGP.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/NGP.pak/launch.sh deleted file mode 100644 index 138a2b10b..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/NGP.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=race -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/NGPC.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/NGPC.pak/default.cfg deleted file mode 100644 index 7d05719ba..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/NGPC.pak/default.cfg +++ /dev/null @@ -1,7 +0,0 @@ -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = B -bind B Button = A -bind Option = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/NGPC.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/NGPC.pak/launch.sh deleted file mode 100644 index 138a2b10b..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/NGPC.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=race -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/P8.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/P8.pak/default.cfg deleted file mode 100644 index 73611d3f3..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/P8.pak/default.cfg +++ /dev/null @@ -1,7 +0,0 @@ -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = A -bind B Button = B -bind Start = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/P8.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/P8.pak/launch.sh deleted file mode 100755 index b3de7565d..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/P8.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=fake08 -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/PCE.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/PCE.pak/default.cfg deleted file mode 100644 index 671219086..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/PCE.pak/default.cfg +++ /dev/null @@ -1,15 +0,0 @@ --pce_fast_turbo_toggle_hotkey = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Run = START -bind I = A -bind II = B -bind III = Y -bind IV = X -bind V = L1 -bind VI = R1 -bind Mode = L2 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/PCE.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/PCE.pak/launch.sh deleted file mode 100755 index 7bf829940..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/PCE.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mednafen_pce_fast -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/PKM.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/PKM.pak/default.cfg deleted file mode 100644 index f6d20d9bb..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/PKM.pak/default.cfg +++ /dev/null @@ -1,17 +0,0 @@ -minarch_screen_scaling = Native - -pokemini_video_scale = 3x --pokemini_60hz_mode = enabled -pokemini_palette = Old -pokemini_piezofilter = disabled -pokemini_lowpass_filter = enabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = A -bind B Button = B -bind C Button = R1 -bind Shake = L1 -bind Power = SELECT diff --git a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/PKM.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/PKM.pak/launch.sh deleted file mode 100755 index 098f76f1c..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/PKM.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=pokemini -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/SGB.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/SGB.pak/default.cfg deleted file mode 100644 index 78fdedb28..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/SGB.pak/default.cfg +++ /dev/null @@ -1,24 +0,0 @@ --mgba_gb_model = Super Game Boy -mgba_skip_bios = ON --mgba_gb_colors_preset = 2 --mgba_force_gbp = OFF --mgba_color_correction = OFF --mgba_interframe_blending = OFF -mgba_sgb_borders = ON - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 -bind L Turbo = NONE:L2 -bind R Turbo = NONE:R2 -bind More Sun = NONE:L3 -bind Less Sun = NONE:R3 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/SGB.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/SGB.pak/launch.sh deleted file mode 100755 index 796c1be58..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/SGB.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mgba -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/SMS.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/SMS.pak/default.cfg deleted file mode 100644 index 0d2df362d..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/SMS.pak/default.cfg +++ /dev/null @@ -1,19 +0,0 @@ --picodrive_smstype = Master System -picodrive_smsmapper = Auto --picodrive_ggghost = off --picodrive_sound_rate = 44100 --picodrive_ramcart = disabled --picodrive_dacnoise = disabled --picodrive_input1 = 3 button pad --picodrive_input2 = 3 button pad --picodrive_fm_filter = off --picodrive_audio_filter = disabled --picodrive_overclk68k = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Button 1 = B -bind Button 2 = A -bind Pause = START diff --git a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/SMS.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/SMS.pak/launch.sh deleted file mode 100755 index 81688be79..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/SMS.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/SUPA.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/SUPA.pak/default.cfg deleted file mode 100644 index 07fcd8d65..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/SUPA.pak/default.cfg +++ /dev/null @@ -1,15 +0,0 @@ --supafaust_pixel_format = rgb565 --supafaust_thread_affinity_emu = 0x0 - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Y Button = Y -bind X Button = X -bind B Button = B -bind A Button = A -bind L Button = L1 -bind R Button = R1 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/SUPA.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/SUPA.pak/launch.sh deleted file mode 100755 index 331d02280..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/SUPA.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mednafen_supafaust -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/VB.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/VB.pak/default.cfg deleted file mode 100644 index 5d596116f..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/VB.pak/default.cfg +++ /dev/null @@ -1,21 +0,0 @@ -minarch_screen_scaling = Native -minarch_cpu_speed = Performance - --vb_3dmode = anaglyph --vb_right_analog_to_digital = disabled - -bind L. Up = UP -bind L. Down = DOWN -bind L. Left = LEFT -bind L. Right = RIGHT -bind Select = SELECT -bind Start = START -bind A = A -bind B = B -bind L Button = L1 -bind R Button = R1 -bind Low Battery = NONE:X -bind R. Up = NONE:L2 -bind R. Down = NONE:L3 -bind R. Left = NONE:R2 -bind R. Right = NONE:R3 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/VB.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/VB.pak/launch.sh deleted file mode 100755 index e5146dd57..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/trimuismart/VB.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mednafen_vb -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/zero28/GG.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/zero28/GG.pak/default.cfg deleted file mode 100644 index 44ce34743..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/zero28/GG.pak/default.cfg +++ /dev/null @@ -1,18 +0,0 @@ --picodrive_smstype = Game Gear --picodrive_smsmapper = Auto --picodrive_sound_rate = 44100 --picodrive_ramcart = disabled --picodrive_dacnoise = disabled --picodrive_input1 = 3 button pad --picodrive_input2 = 3 button pad --picodrive_fm_filter = off --picodrive_audio_filter = disabled --picodrive_overclk68k = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Button 1 = B -bind Button 2 = A -bind Pause = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/zero28/GG.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/zero28/GG.pak/launch.sh deleted file mode 100755 index 81688be79..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/zero28/GG.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/zero28/MGBA.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/zero28/MGBA.pak/default.cfg deleted file mode 100644 index 266d90c20..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/zero28/MGBA.pak/default.cfg +++ /dev/null @@ -1,18 +0,0 @@ -mgba_skip_bios = ON - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 -bind L Turbo = NONE:L2 -bind R Turbo = NONE:R2 -bind More Sun = NONE:L3 -bind Less Sun = NONE:R3 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/zero28/MGBA.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/zero28/MGBA.pak/launch.sh deleted file mode 100755 index 796c1be58..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/zero28/MGBA.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mgba -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/zero28/NGP.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/zero28/NGP.pak/default.cfg deleted file mode 100644 index 33f5a6b95..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/zero28/NGP.pak/default.cfg +++ /dev/null @@ -1,9 +0,0 @@ -race_dark_filter_level = 50 - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = B -bind B Button = A -bind Option = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/zero28/NGP.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/zero28/NGP.pak/launch.sh deleted file mode 100644 index 138a2b10b..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/zero28/NGP.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=race -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/zero28/NGPC.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/zero28/NGPC.pak/default.cfg deleted file mode 100644 index 7d05719ba..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/zero28/NGPC.pak/default.cfg +++ /dev/null @@ -1,7 +0,0 @@ -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = B -bind B Button = A -bind Option = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/zero28/NGPC.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/zero28/NGPC.pak/launch.sh deleted file mode 100644 index 138a2b10b..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/zero28/NGPC.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=race -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/zero28/P8.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/zero28/P8.pak/default.cfg deleted file mode 100644 index 73611d3f3..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/zero28/P8.pak/default.cfg +++ /dev/null @@ -1,7 +0,0 @@ -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = A -bind B Button = B -bind Start = START \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/zero28/P8.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/zero28/P8.pak/launch.sh deleted file mode 100755 index b3de7565d..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/zero28/P8.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=fake08 -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/zero28/PCE.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/zero28/PCE.pak/default.cfg deleted file mode 100644 index 671219086..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/zero28/PCE.pak/default.cfg +++ /dev/null @@ -1,15 +0,0 @@ --pce_fast_turbo_toggle_hotkey = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Run = START -bind I = A -bind II = B -bind III = Y -bind IV = X -bind V = L1 -bind VI = R1 -bind Mode = L2 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/zero28/PCE.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/zero28/PCE.pak/launch.sh deleted file mode 100755 index 7bf829940..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/zero28/PCE.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mednafen_pce_fast -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/zero28/PKM.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/zero28/PKM.pak/default.cfg deleted file mode 100644 index f6d20d9bb..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/zero28/PKM.pak/default.cfg +++ /dev/null @@ -1,17 +0,0 @@ -minarch_screen_scaling = Native - -pokemini_video_scale = 3x --pokemini_60hz_mode = enabled -pokemini_palette = Old -pokemini_piezofilter = disabled -pokemini_lowpass_filter = enabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind A Button = A -bind B Button = B -bind C Button = R1 -bind Shake = L1 -bind Power = SELECT diff --git a/skeleton/_unmaintained/EXTRAS/Emus/zero28/PKM.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/zero28/PKM.pak/launch.sh deleted file mode 100755 index 098f76f1c..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/zero28/PKM.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=pokemini -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/zero28/SGB.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/zero28/SGB.pak/default.cfg deleted file mode 100644 index 78fdedb28..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/zero28/SGB.pak/default.cfg +++ /dev/null @@ -1,24 +0,0 @@ --mgba_gb_model = Super Game Boy -mgba_skip_bios = ON --mgba_gb_colors_preset = 2 --mgba_force_gbp = OFF --mgba_color_correction = OFF --mgba_interframe_blending = OFF -mgba_sgb_borders = ON - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 -bind L Turbo = NONE:L2 -bind R Turbo = NONE:R2 -bind More Sun = NONE:L3 -bind Less Sun = NONE:R3 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/zero28/SGB.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/zero28/SGB.pak/launch.sh deleted file mode 100755 index 796c1be58..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/zero28/SGB.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mgba -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/zero28/SMS.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/zero28/SMS.pak/default.cfg deleted file mode 100644 index 0d2df362d..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/zero28/SMS.pak/default.cfg +++ /dev/null @@ -1,19 +0,0 @@ --picodrive_smstype = Master System -picodrive_smsmapper = Auto --picodrive_ggghost = off --picodrive_sound_rate = 44100 --picodrive_ramcart = disabled --picodrive_dacnoise = disabled --picodrive_input1 = 3 button pad --picodrive_input2 = 3 button pad --picodrive_fm_filter = off --picodrive_audio_filter = disabled --picodrive_overclk68k = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Button 1 = B -bind Button 2 = A -bind Pause = START diff --git a/skeleton/_unmaintained/EXTRAS/Emus/zero28/SMS.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/zero28/SMS.pak/launch.sh deleted file mode 100755 index 81688be79..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/zero28/SMS.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/zero28/SUPA.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/zero28/SUPA.pak/default.cfg deleted file mode 100644 index 07fcd8d65..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/zero28/SUPA.pak/default.cfg +++ /dev/null @@ -1,15 +0,0 @@ --supafaust_pixel_format = rgb565 --supafaust_thread_affinity_emu = 0x0 - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Y Button = Y -bind X Button = X -bind B Button = B -bind A Button = A -bind L Button = L1 -bind R Button = R1 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Emus/zero28/SUPA.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/zero28/SUPA.pak/launch.sh deleted file mode 100755 index 331d02280..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/zero28/SUPA.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mednafen_supafaust -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Emus/zero28/VB.pak/default.cfg b/skeleton/_unmaintained/EXTRAS/Emus/zero28/VB.pak/default.cfg deleted file mode 100644 index a83095a2b..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/zero28/VB.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ -minarch_cpu_speed = Performance - --vb_3dmode = anaglyph --vb_right_analog_to_digital = disabled - -bind L. Up = UP -bind L. Down = DOWN -bind L. Left = LEFT -bind L. Right = RIGHT -bind Select = SELECT -bind Start = START -bind A = A -bind B = B -bind L Button = L1 -bind R Button = R1 -bind Low Battery = NONE:X -bind R. Up = NONE:L2 -bind R. Down = NONE:L3 -bind R. Left = NONE:R2 -bind R. Right = NONE:R3 diff --git a/skeleton/_unmaintained/EXTRAS/Emus/zero28/VB.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Emus/zero28/VB.pak/launch.sh deleted file mode 100755 index e5146dd57..000000000 --- a/skeleton/_unmaintained/EXTRAS/Emus/zero28/VB.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -EMU_EXE=mednafen_vb -CORES_PATH=$(dirname "$0") - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/EXTRAS/Tools/gkdpixel/Clock.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Tools/gkdpixel/Clock.pak/launch.sh deleted file mode 100755 index 022a382c3..000000000 --- a/skeleton/_unmaintained/EXTRAS/Tools/gkdpixel/Clock.pak/launch.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -cd $(dirname "$0") -./clock.elf \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Tools/gkdpixel/Files.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Tools/gkdpixel/Files.pak/launch.sh deleted file mode 100755 index 2a26c75cd..000000000 --- a/skeleton/_unmaintained/EXTRAS/Tools/gkdpixel/Files.pak/launch.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -cd $(dirname "$0") - -HOME="$SDCARD_PATH" -/usr/bin/opkrun /media/data/apps/dinguxcmd_kai.opk diff --git a/skeleton/_unmaintained/EXTRAS/Tools/gkdpixel/Input.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Tools/gkdpixel/Input.pak/launch.sh deleted file mode 100755 index ca0aefe28..000000000 --- a/skeleton/_unmaintained/EXTRAS/Tools/gkdpixel/Input.pak/launch.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -cd $(dirname "$0") -./minput.elf diff --git a/skeleton/_unmaintained/EXTRAS/Tools/m17/Bootlogo.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Tools/m17/Bootlogo.pak/launch.sh deleted file mode 100755 index a499c7ff2..000000000 --- a/skeleton/_unmaintained/EXTRAS/Tools/m17/Bootlogo.pak/launch.sh +++ /dev/null @@ -1,72 +0,0 @@ -#!/bin/sh - -DIR=$(dirname "$0") -cd $DIR - -# 264x40 (or fewer pixels) -# Save as BMP -# Windows -# 24-bit -# DO NOT flip row order - -{ - -LOGO_PATH=$DIR/logo.bmp - -if [ ! -f $LOGO_PATH ]; then - echo "No logo.bmp available. Aborted." - exit 1 -fi - -# read new bitmap size -HEX=`dd if=$LOGO_PATH bs=1 skip=2 count=4 status=none | xxd -g4 -p` -# convert to decimal (need to swap le bytes) -COUNT=$((0x${HEX:6:2}${HEX:4:2}${HEX:2:2}${HEX:0:2})) -if [ $COUNT -gt 32768 ]; then - echo "logo.bmp too large ($COUNT). Aborted." - exit 1 -fi - -OFFSET=4044800 # rev A -SIGNATURE=`dd if=/dev/block/by-name/boot bs=1 skip=$OFFSET count=2 status=none` - -if [ "$SIGNATURE" = "BM" ]; then - echo "Rev A" -else - OFFSET=4045312 # rev B - SIGNATURE=`dd if=/dev/block/by-name/boot bs=1 skip=$OFFSET count=2 status=none` - if [ "$SIGNATURE" = "BM" ]; then - echo "Rev B" - else - OFFSET=4046848 # rev C - SIGNATURE=`dd if=/dev/block/by-name/boot bs=1 skip=$OFFSET count=2 status=none` - if [ "$SIGNATURE" = "BM" ]; then - echo "Rev C" - else - echo "Rev unknown. Aborted." - exit 1 - fi - fi -fi - -# current timestamp -DT=`date +'%Y%m%d%H%M%S'` -# read bitmap size -HEX=`dd if=/dev/block/by-name/boot bs=1 skip=$(($OFFSET+2)) count=4 status=none | xxd -g4 -p` -# convert to decimal (need to swap le bytes) -COUNT=$((0x${HEX:6:2}${HEX:4:2}${HEX:2:2}${HEX:0:2})) -# create backup -echo "copying $COUNT bytes from $OFFSET to backup-$DT.bmp" -dd if=/dev/block/by-name/boot of=./backup-$DT.bmp bs=1 skip=$OFFSET count=$COUNT - -# inject new -echo "injecting $LOGO_PATH" -dd conv=notrunc if=$LOGO_PATH of=/dev/block/by-name/boot bs=1 seek=$OFFSET - -sync -echo "Done." - -} &> ./log.txt - -# self-destruct -mv $DIR $DIR.disabled \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Tools/m17/Bootlogo.pak/logo.bmp b/skeleton/_unmaintained/EXTRAS/Tools/m17/Bootlogo.pak/logo.bmp deleted file mode 100644 index 95f2f082e06b9614d10ae5fc335075a6a6f8eae1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30056 zcmeHOv2GJV6f{x_OQeXXXd_XOf+7@r03DGiu#^Hz6etv+h?1W`DN{ue1(NxTP#~Ei zg^LuSKr#iADN;~SxS)WE*ILHdv)(=Pd?tEUV!fN2H#=`~=Um|K{=?_58l%@eyx+$6 zv+?(}#?29a7yEBq58ore-#h_Nz!UHUJONL@6YvB)0Z+ga@B};oPrwuK1Uvyxz!UHU zJONL@6Zn4<=zi>WPrHq^$qCjPz0)3cO`@r-?uRbEQjDp6(C_tn&Gly7Q$Zy5E}{4} zdbOXlc`a-PoWXQm%7AdSiJ`R}s|<(3tvg#-tAa?r!^N4=@cG&J&_WTxeEkYzhL+8MT?eOoE!}Azt~5C z-%5C)2%AN=gHDm3*n$%fr(xJETC`}n#mT`Tez=3LgHWTWa5{wEB0t=MkN2>N_ac#H zlB41MmzReYUMOH7)cHh<8Odjg(-C*TQq0!vF^=fTe4+xQYRT-)$Fc7dSG)YYr}SmTMH zLTDf;4|Vk_Kh`)OMXFXF6rXX6UZrV`^IWP{9u%K(i(aK^jq_ZpRvr|eaf@E1X^rz- zs#YEppK*&`rD=`xT&h+c6rXX6UZrV`^IWP{9u%K(i(aK^jq_ZpRvr|eaf@E1X^rz- zs#YEppK*&`rD=`xT&h+c6rXX6UZrV`^IWP{9u%K(i(aK^jq_ZpRvr|eaf@E1X^rz- zs#YEppK*&`rD=`xT&h+c6rXX6UZrV`^IWP{9u%K(i(aK^jq_ZpRvr|eaf@E1X^rz- zs#YEppK*&`rD=`xT&h+c6rXX6UZrV`^IWP{9u%K(i(aK^jq_ZpRvr|eaf@E1X^rz- zs#YEppK*&`rD=`xT&h+c6rXX6UZrV`^IWP{9u%K(i(aK^jq_ZpRvr|eaf@E1X^jtm z{<-szXXJWgePh}NK<3P>aa-ebV?bu|{{mHSUHITa{-<+vjvH>L?E#DgRX}{YF(9gi zan)NFj;Bl5-pm?zQ*Ufc99r1K?SC`L3??2?VVbJz%0#Vud~|tl`P>)c!hwW)6!C>3 zK2?!!JUlv7>!usSUe#L{&W}js_%GtLcPF0l;Tdyun7;}&juXDIJZFSV&hW<&;%dem z5!G8G9-mgo@t@DZ*_{|FM<>x<*RIW5n>kkwInzZB1R7kf?kz;?&DIqOMF<7z7_R_+&2n%?L7D=6*(nl*0Sm z^Bn}{uX2qe1Q$rSo=lu^*aZS;`G->+d6E0QqsU4X_=gw#oq{y*SMc|X@3_Lp3k5a- zV%N-nu34!O+>9sS33vjYfG6Mycmke)C*TQq0-k^;;0bsFo`5Id33vjYfG6Mycmkfl H3McRzQoe%5 diff --git a/skeleton/_unmaintained/EXTRAS/Tools/m17/Bootlogo.pak/original.bmp b/skeleton/_unmaintained/EXTRAS/Tools/m17/Bootlogo.pak/original.bmp deleted file mode 100644 index a0dad7c9f3d2990a468d559ad7a472d375b494f7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31736 zcmeHPNvsXq8a{}4fJ-Nsyj4ZCb5jHg@dTpV}(^AI8ugtX#Ef)zG0sQ>?03dSpS+ z_xbbZuV23&D`=9eipa>GUc7j5*REZyJ4n;0QKQzaTeorJ#@KosLi!ko9zA-jS+gd_ zS;ah@nm&EHHObL4X3S{6aVJrwei-iTN5WvlvU0t49QH_s?zrNqODuEN{fgiM~*-;8x>Wp0?Q%i?Afz@`t*@} z5;JGceE$477=ps7S8*6LXwd!p_k*0(O+x;*ZQGnlcG%k53d^e#9$Y0~td@q+u7s{% zzs?A!^ugMw&fxaog27}iZr;2(Y0{(=8>~CQEaaSIZMdKvJ$e*oKm~+|$SKgVK?o$A zIdi6O-@eWr;Nsb{XLQ7^;t+>aOTfjwd-sBD)lEWpIxcqY+QnQ{CqKDLzPLCvX6RB( zT);@iKiIb)7vsi_!@b9%MT>Us+zA!QnB|W zxNxCm&Lcd=vv==am<@rGCr?&_fD6heD5~}dN-5{^<;yEptiVYFSm@WUA9FNo)+}Bx zV)8MsTB-*w_V3>h-x1F#Q>Msw+*o1;^SH+S-{XSWvAt4;$@KGvB9=mI-n{wa$B&X9 zE5giq)geUD!q=}~FI%>Zg~ZyB7BaUpcajEx$iZXBj%l7mrsXjPESH_2Rp-#f>qX3d zE);(~a6#A5@7uRezVlj1n{g=SR~7T}MYLR%=!RCNX!3CAe5cJg1Va3lu=AF-JV{!KB# zjmeiTR~wp-5sw}{f_!*^9!`O{di5%UAdiwtZEX-2G5MSqe+(B^7qr87SaSOGX+;2A zm=x$yOGUmzuU}_#*fQ>@Xb3Y<2j0X47NyqI>MYVy2IQzL!wycM6X5&u<;&$e2|RO#CC&^ttkieAA93pP3|-vvENMTFQ(7Ec;DVci zi(nNYeR**4cM1OZ@71eU+K(WZb;X5C7WdKC7|^Z)YmN)ahc0(cpn2RYi7iM}iVMr{ zf>79D0dav`AZtln3?4if&tq{&XS`(Aa^gY~g1D&1In&k#WA1Q4uboFV#|1C7h#^{I zZ~;Zu_re0f8TJd|LeH0eWc7RJstCh8xL^fRNU%2e+%+lO&e&X6dX7a35O(bs1k$8O z^}q!kM<4XPQeQIpp~%L{m0w|p#l!_FFu1>nJzrAA=Enu95$)~Uw|MF3w|_P~JdwZ{ zVRM~X8xUgoSq#EOOaW2%cW7!i3cpD0jxzO;(k-K;AqJQ`9U5SfeQaD-ZIYIYPYuB#5bLS31{p86L zT%DPSn4%IF!N}AV7r3~iq4@Ef7QgqzUq);@b?Q`!i(pbXSt%~Wk6+gg95@i6Ub=KC z-VI|4*dyRhV~GnF5Dx2y3)VdQ*x$BFTm+NCN!2-SrSj~%EkEzR^o*KuCN!MJ5*IEY z9M&5b%!PXogjv(?jDm)7(&jp|Hn7Cpk_8>HMz&=-iZ{5l;~TIYHA4<9}Z zd${YQQ`~#f66b{`ZEdKQTmT1j@qp+kr0vU>Rb^5sh{wC-!Id{JH+ zNn~CxXgsVXfio>U`u4Eg2;j9vr2gZe$u>_vB&p+^j)mt<02Mn1eq=?0`wg| zGD>vZMJ$Mm?%liNGbw8L6p23nBGh#2)=dl`z%z2>NF6019vmgJ36%D?mR00ms zS@z`rvF`gqG`BX03%r2KgL{-N$7bpEiZSdGqG!g2;PpYL8jlu=^-yxiUgRL$Y1Das}U2Lx^V2o{g_D@LX3+ zTuhxh6=!37!vW{LV5sSlbI?U2xG;tbFstT4xOyfoB%ho?9+-rqWB|Y8$%zXo0s(<} z8kbNn_}kjr-0!vF0*ncYk~$sLj1^1a=n=!@yZVLNUj!ZDBs~HxAMH7Wpg>harH$^z_Ft3u3zv9s<5b3y3>Rmm<9(%7vwjd8wKra|bIG+5tpv@3PBC~g1+xsX5 zGl&bfPK!umzphJs5pZlIx zf7q~LutD~a=- ./log.txt - -# self-destruct -DIR=$(dirname "$0") -mv $DIR $DIR.disabled diff --git a/skeleton/_unmaintained/EXTRAS/Tools/miyoomini/Clock.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Tools/miyoomini/Clock.pak/launch.sh deleted file mode 100755 index 7eba99d00..000000000 --- a/skeleton/_unmaintained/EXTRAS/Tools/miyoomini/Clock.pak/launch.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -cd $(dirname "$0") -./clock.elf diff --git a/skeleton/_unmaintained/EXTRAS/Tools/miyoomini/Files.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Tools/miyoomini/Files.pak/launch.sh deleted file mode 100755 index 4923beefe..000000000 --- a/skeleton/_unmaintained/EXTRAS/Tools/miyoomini/Files.pak/launch.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -cd $(dirname "$0") - -HOME="$SDCARD_PATH" -./DinguxCommander \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Tools/miyoomini/Input.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Tools/miyoomini/Input.pak/launch.sh deleted file mode 100755 index ca0aefe28..000000000 --- a/skeleton/_unmaintained/EXTRAS/Tools/miyoomini/Input.pak/launch.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -cd $(dirname "$0") -./minput.elf diff --git a/skeleton/_unmaintained/EXTRAS/Tools/my282/Bootlogo.pak/bootlogo.bmp b/skeleton/_unmaintained/EXTRAS/Tools/my282/Bootlogo.pak/bootlogo.bmp deleted file mode 100644 index 410037627371e287db63625e2b34cc43be3bb535..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1228872 zcmeI*PiPeP9suyP&mIaMjORJq!xoM_)3!q5m}Se6l?A8<=58~o9re#v$NZoozGxMc6R>l_xt(H z_c!Ct%)bYA|L31QaoDx+vu)w$zi;&PjJ(;?^G45xo_{R7eskgd-hcJ{{3wCI5-&AuU{X!Ax}Po z{S5;QFwi{)DwRs8)oMj9yG?ET`1p7j9UTqZw{KUAd%DN3eUV%;z(869d-m)J6B83n z)sU4Ynwpvlaal>XBOdpbZTRlH@51o#aN<}cjjieJ7Z_lGf&3bX=S#C19zTAZxTX~S zoO3I&d;0WgIDY(i;+Sbq`E5^fBR32%(5!)Y+?v%8kE5Gi@8Wb>t-Hv}nVy~wLqkJ} zW49PXzqNM;7+|1y2KMgVo5}yb#$(?!=bwvQH?!XM+qZ9r-riny*#8eRzyJd!GVs+` zUxj!+w9)YV`SWo0?Ah?{yYFV|qS5-wI{w+SXJOyIeVN8szqok)VmXsD2FhpPi!Z(i z@qB2bVSau-oI7_ey#N0Dnbe3z>nZ#AlP6DR5?^h&d~I0H<(z?H8#sFOXo%;O8x1dB zya?ydpAQ>0Y-p)YG+Ms#AzZm~rKQ+vgT-!x@+W@`l-t1PpMSpM^+_*Zz6=*HUJUU% z-ZWO!*_9)3>(;GQaZQs8^OU=-%fI|HkWT}je)?&6^ypE;ViD``mtTIFxK=b=pf~=E zz}2f)6US9M%4a*07kOcTfwTq=95@iZ|Ni?wYs2e*yn6L2yz|aGiE72`^ZUDT1Wunm zohYtp^J_l)1_l^lAfE=*-^Mkv-S7BbbUxdJeU-d0z(6|<96Wf?`R8^Q*j1Jv?-jOb z(c<~{Y*-n7`Q?}J%{SkqzHdas1$(1z1n%6qqyDPD z3^2ez7aMT>QQh*Fi;?^H@7MOaxa~P6$@ejd{K!wc47mSBE=uf*8}a1H6ZKd9Wq<(& zy2OC{Pp(+eoW?-D4GatnWb*ulw9o&|U12N82E}`IYg_ql zTk<163^1^gfh?atnCAJv1u1vA+|1$OVKvw>Far!QP*4Mtlara%mNd`*jn~u|(na9g zZ@<;<3fk^g>JxjF8|!APL)z#6R;$%kS6%A)`}_OVU^SQl1{h!KfY0hd*=XOyZd9TbHA6Ezk1I00XNT=hR#; zp!%!t%K!rmFu=ec26pb;*^wF?@13G=SDwC|T+1~B3^1^|fzLkstnJ6Z*REYtfAxDA zV1NMz7+7K;UZ>m6VQg$n%$LMm-*EN5p%{q~0}OP#fg?wbw6pyFe*Jd0$I$1qpJ0Fi z1{g?cAbu~pox|+xtm9wDzYH+I00RuvG0@KX8<(B5PhfieNCp^SfPpd?P=7fugL9ve za|Rg5lYuQ;wzReUI{(ajp1j)@9vNUDF9v-7ip9KGv>hxmz(AP{xc-RuGI{q|d1ruu zJQz55@L*fdJ;#N+{|4)Mux=YTWPpLZ7}&96N0^_VZ+rc9|4HWaV%~PJ$N&R>w*k*z zVDRrYX#ET_z(83H#P2!B=MUb$f4}X=ysxjo^9QxDva~UulXV8NH4yI)b@S%UFgG{% zdRg&z6A^g$@S%He)Vbe@Hkxf46;JVGp!*C|DwR;H)taa@CaD*JGiT1Izv?do3^2ez zVguD`wO&~2;-9Q$#cd-OMe*8FbZCISw@6{u)Z{NPe@qInl{?_&xV1R-A7|62zPE1TB zt`DnM9aF>zoIZUzacs4-{IoN-b?#mUh9)HzyJf~G|)YjGW$<*<;oScSAUlQ1{h$VEe5i$THUe4 zQ>RX~CEohE%x z!Q;n|tGoKS3^2d|106R|tyW7{ejh%37>0+3J05HO)Z+G2aKn+0}L?0KrRgQ_4S2#99;Bs(Q*4HCnv+$*jTu6<3>1f;zSr6 z91QE%ug^uCv+g@tp8hxk3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rtkn}N-nH;0=yZ-%+KxnNj10x?E0RxxJX=D_E%Z)1P~20CY;QmKSm zt+sN}@$Rw+#F)j{vD!JSVlCDTFwji~s@3YU+G0d=5s0ztCJR1`eH#M|Fwi*zGcz;I z6&q76i$IJWtDUnd)?&>716dmQ`s=U5%a<>g?c0-%_~C~i!oa{l;(CyDJ*NL_1hTYX zS@taqFu*`(47~N$Tj96ge*5bVy@glP)6?p23-L=ctG3dawj$2r%m4#f8d$StO{VpC zYHCXTO;bc$m?ujQmSz9K00Rtk&cNvCXeKo{9{Yas$tUV>3$--OtlCQF+KO0J*vC=zi{C~c>C?Q6W7&dx3TU@jchss&Bobu_8SZ^z(76?tXsD(T)%$3 z?tcI7-MeASmMv|m!F5+?WYZDQp7PnAU?8c1Lx&E9pMU;&+5Z2hpMDBMLqnO@ z;AJZ^B2fgA=GXN02@Ej6Kz#hP-8v9!^M@aPm`M$;y8d9- z@mzJQIb6D2uaiZf)%cq~|7}o?!@iQmDhH^h4o$M0^X^-*t`#x);-v~f3I zdE2wx%RK|dG7zspI)DCr-NF#BUD~#7TdEpdcY#JW9RcmASnWu@eVatH)ZV7 z&Za%(t3Anwd@#U3vj!$7C)4iwm(BOR(g zT?At6c+Qt+`H&9=7$}N?N~IENwOYCYRN}c}%wp_{l4sj#pTqzI4CK$i2OoS8;<21_ z(W`eTVvJ&}V$4|1pJh3b69yPyfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ T0R|XgfB^;=V1NMzif-V4ox!E3 diff --git a/skeleton/_unmaintained/EXTRAS/Tools/my282/Bootlogo.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Tools/my282/Bootlogo.pak/launch.sh deleted file mode 100755 index b59693ae8..000000000 --- a/skeleton/_unmaintained/EXTRAS/Tools/my282/Bootlogo.pak/launch.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/sh - -LOGO_NAME="bootlogo.bmp" - -overclock.elf performance 2 1200 384 1080 0 - -DIR="$(dirname "$0")" -cd "$DIR" - -LOGO_PATH=$DIR/$LOGO_NAME -if [ ! -f $LOGO_PATH ]; then - show.elf $DIR/res/missing.png 2 - exit 1 -fi - -cp /dev/mtdblock0 boot0 - -VERSION=$(cat /usr/miyoo/version) -OFFSET_PATH="res/offset-$VERSION" - -if [ ! -f "$OFFSET_PATH" ]; then - show.elf $DIR/res/abort.png 2 - exit 1 -fi - -# offset is found with binwalk mtdblock0 -OFFSET=$(cat "$OFFSET_PATH") - -show.elf $DIR/res/updating.png 120 & - -gzip -k "$LOGO_PATH" -LOGO_PATH=$LOGO_PATH.gz -LOGO_SIZE=$(wc -c < "$LOGO_PATH") - -MAX_SIZE=62234 -if [ "$LOGO_SIZE" -gt "$MAX_SIZE" ]; then - show.elf $DIR/res/simplify.png 4 - exit 1 -fi - -# workaround for missing conv=notrunc support -OFFSET_PART=$((OFFSET+LOGO_SIZE)) -dd if=boot0 of=boot0-suffix bs=1 skip=$OFFSET_PART 2>/dev/null -dd if=$LOGO_PATH of=boot0 bs=1 seek=$OFFSET 2>/dev/null -dd if=boot0-suffix of=boot0 bs=1 seek=$OFFSET_PART 2>/dev/null - -mtd write "$DIR/boot0" boot -killall -9 show.elf - -rm $LOGO_PATH boot0 boot0-suffix -mv $DIR $DIR.disabled diff --git a/skeleton/_unmaintained/EXTRAS/Tools/my282/Bootlogo.pak/res/abort.png b/skeleton/_unmaintained/EXTRAS/Tools/my282/Bootlogo.pak/res/abort.png deleted file mode 100644 index 54ea508abf6c4a89ea56c5f5d62ccda732d82aa8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7991 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 diff --git a/skeleton/_unmaintained/EXTRAS/Tools/my282/Bootlogo.pak/res/missing.png b/skeleton/_unmaintained/EXTRAS/Tools/my282/Bootlogo.pak/res/missing.png deleted file mode 100644 index 44160817ab06858d7497a9b0dc4dbedc38ab6db4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7069 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 \/tmp\/.show_loading_txt.log/d' $BOOT_PATH -echo "patched $BOOT_PATH" - -mksquashfs squashfs-root rootfs.modified -comp xz -b 256k -if [ $? -ne 0 ]; then - killall -9 show.elf - show.elf "$DIR/abort.png" 2 - sync - exit 1 -fi - -mtd write /tmp/rootfs.modified rootfs -killall -9 show.elf - -} &> ./log.txt - -mv "$DIR" "$DIR.disabled" \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Tools/my282/Remove Loading.pak/patch.png b/skeleton/_unmaintained/EXTRAS/Tools/my282/Remove Loading.pak/patch.png deleted file mode 100644 index 6991d75ebf62470e46332d372fec09ba407c78b3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13722 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 L@w!s>&Aa~w5zqTD diff --git a/skeleton/_unmaintained/EXTRAS/Tools/my282/Reset Stick.pak/calibrate.png b/skeleton/_unmaintained/EXTRAS/Tools/my282/Reset Stick.pak/calibrate.png deleted file mode 100644 index d99e411e9ab6385b277ee71377657aa8dbcc0a46..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4123 zcmeHKX*(O*8da_8<*3u6sF|v%ges!uo|@_!V~)8bVje=xqOGc#4yrY)$T8NCm?PyF zYHEcNq>(C`h6piF6>iSw`v>layT9z`*?WIj&wAgr*1OYftW0^hgt^$**m%tD8`-k4 zu|HyCJNNw(JL{wiV~$~MLXpPKk#?cJk{a4 zi!(F&(>~@ao$Q|G;IP0JR+dU_xPSk5l?#9S-DB_1l%&;;44XX-$@)WuE1A8&_wK*o z%F}5VW##$Myl*onM3EvYqC$W^*{6QjrTVEn}3saUp+6)8Kc)6PohIZkY#P^-uJtld;i~sFp)cp)plrlPJ^mN_~u- zo!zekM$dX1sa7KRTldj)jU5??)`_Ca_jI3~{)#uBn|bd#rlJ`%*OZs3YQ9b*)N#5B zn-6e}U0!)~B*&?qtGDmW1jg^vR|9s1lKnZbw&sSECzs!zyCyE4Gu}Fq&#SjD4CuH)gn?J4q-V^jP_XVuB}=xfCTaW@n>5&(wpbRDVcw=WU`Dd0t}&xFy7HDGs^VJNOqH-I)jcA@$~5rzvOWTX=E4^HQgRJWJL=w<^jD{*rnZMJlx|dWu@LDb9!Fv= zTBj@3Z6j5>H}8deU9IU#INBal>6uq%ZdunBvWmY{;)ytt`KAP`tW)}}67G|Hp7V0h z*Ot|NQm8f75nGu3WBqHZ;;EU)RZkUtT==rd*dNt3GtUNJR^*Vq$XyS^>xDSWo55N1 zz{@JvdpX5pBy;ShEHk&>*EuyJj#sMy2fYmyezu3bT&kLyPWlu=I50px3;_s8~Xq;hP5ECDTae($0X%&q66?>9huIC}w?&x`klpbvxv%=;sKafqY4 z?@S6$$iY{6xXWC#vE@!^3=HqfsCUQiZ!Y#v#=I_ic`ieMnyvZGPm9{|)6GreIgv=r z7Sa6HU9B1Xbvk_PelN>Qfz>aG-LVm$O*Pg-!%IE{Y+)uK|8@?7^KItRbLbM1X@5X%60yIUlgC4Gc>jesAt)_o_NwZ#(85}N$ z-XYlK5&kwccQ?k>!Vw?HvpNkigs=;4;vBvp*z&I&Bq~zjU8>TqTPI*B?TX9TpTWZ8 zZJ*2&>Y%n*;dAYZ`2pI}4c^4Qxc%iBx><;?(O$foetpYToY%}VNw zm-)|{n7Y~p^C9^&H<2WBMNrk4J0Z*kh_-CF5+(9*)L*{rBe!QQbuBfRad+c>>;)7O1pNQ1bb9py~lS8xr)FK4uHqUYvnwdGTcBcLn@;JIs%b` z^`s4ZX$9kqn*)dqR$RL%auXWLI~yTVB6b?xO;zNsf^tbem*ve~0n&uG2DcBDo(S7> z7V|7&LeTDy6wWbW4<5ZPN^JhB)0SX>y;q!_jHNvy@tfz5((S6*dO5esc z0GHS;hrguAf8>a2!H;)WSvoOVv%$^qGrIR?Trn6-;&{q%!zS+NXOTOHv*nz%0aN|< z?JqZ;>m!vjRZ8{Zf$t?})=?`_KdDsA5wI-jG*)Xfs!n;x*IbGl{I4?ISo8@zC`idQ z0n>qE=sek;^-Ox-ndjQ*-V9lt?Z< zqQ4Pa17|UKeUYL)Q4W^>dq!Y_No@rM1%CBYMakN;F82d(JX92}-@Xeu*dWVU6|c|| z;IFEYYZ;EM#qMrrD>xg57@?Z&kjyarwF4hzN|Q}_4hZJHZs~GvrKb$`^n0)vY4fG`W`wR^cASVyxqhXA?-Li5mSW_wrvMV zXh&A-4x}?a94=*^xoi$g=MMbY`?)$TO%*$)8Giv1i`vK$FyJQoQ@vxUH*#XouCLH9 zmMRpgFfKpMfSBs9JVSnWGSq*8bWabLlQY;Odll!Wr>Awel|8zhEeb9A-yF&Zs$w{< zkoKlD&?)T|%b#Rj270~WaI|~fF10L4;A|j9bInGlL4Mj{nn)Qr4Cxw_eP%BQgO(Ey3$Wr zqOYKevfPM+f_iuvlLHV?%Rk`%b6kH&IqnJnK56- zr~RqC?WDtP${1iF_ubt{U&~S#H6Spb>?tO;m?Nh14?Q{?9X@0EfWh)$>UfFqnj@cm ziyNgfWWGc7i%rD!uDa?v>DR;LbUry&(Do$$+GkBD3zf7qH@B`xg_n6BZAV@!I(5a( zPnDx5y5S3n2W0rFF{q5y8Q$JY$9rq4!s89l`R?SmIp|0eoT=&ICpCP+8S`Lk`&&E% za3-GtF- zogC%~_e3@7oYgI0E;7hiOH_(cS9ZmNMVR8N>8w()Q1KIw5pOpF1aowB^u{Aj0he|D ztntHfZ5J5m7pQQt#!~t2UzpDt9!bnSddZShE7LUb$MB26GErMQK?%g+gZBP~Qp|)k z<-;+pP7J2W|LcpvuSk;Ys?tDjG@;KjfhY7)+LfeGkh;vX_8F?Rw2h;FZ4IOxgwA(>5S=XTs=>ym2d)8T=jP^WN3+r3J1;8h4cB8l zt#_)Cul#0zn(%=y-{AMclH%6PkqNq!w?7X1LC-?969!p zebjNc8!oOjmI+kK&l^A1GkB@3tt~vHI=IitD_(C$VN6knfp6}V{I2@)iZd`Xi5hQwkLEj=oJ z%Y+Qf7EOotdz)RiBMd1UyKU{|V-tfsnW$;V`&4-vx54@*5BF2bhG)k2d|J8_z`_8B zV8&$u3+JnZ0r$d}qT}Ma+IKQm`#kVcy9En5Ai*Li>8cRpOyKRM6V}8h&&!2m0`fP6 zzcV#((0BOJZ2cN%ftzFBZC`yM>el$<{SVbvr7}*F!2hfNk^kfRZw78jp7DFJ1wL2B U3CLYF`sd!v*vhEkp4XHA0Q^$FlK=n! diff --git a/skeleton/_unmaintained/EXTRAS/Tools/my282/Reset Stick.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Tools/my282/Reset Stick.pak/launch.sh deleted file mode 100755 index 019a0f6f4..000000000 --- a/skeleton/_unmaintained/EXTRAS/Tools/my282/Reset Stick.pak/launch.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -rm -f "$USERDATA_PATH/mstick.bin" - -DIR="$(dirname "$0")" -cd "$DIR" -show.elf "$DIR/calibrate.png" 2 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/apply.sh b/skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/apply.sh deleted file mode 100755 index 9ebddd8fa..000000000 --- a/skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/apply.sh +++ /dev/null @@ -1,79 +0,0 @@ -#!/bin/sh -set -x - -export PATH=/tmp/bin:$PATH -export LD_LIBRARY_PATH=/tmp/lib:$LD_LIBRARY_PATH - -DIR="$(cd "$(dirname "$0")" && pwd)" -LAST_CALL_TIME=0 -hide() { - killall show.elf || true -} -show() { - CURRENT_TIME=$(date +%s) - if [ $((CURRENT_TIME - LAST_CALL_TIME)) -lt 2 ]; then - DELAY=$((2 - (CURRENT_TIME - LAST_CALL_TIME))) - echo "delay for $DELAY seconds" - sleep $DELAY - fi - - hide - show.elf $DIR/res/$1 300 & - LAST_CALL_TIME=$(date +%s) -} - -show "prep-env.png" -echo "preparing environment" -cd $(dirname "$0") -cp -r payload/* /tmp -cd /tmp - -show "extract-img.png" -echo "extracting boot.img" -dd if=/dev/mtd2ro of=boot.img bs=131072 - -show "unpack-img.png" -echo "unpacking boot.img" -mkdir -p bootimg -unpackbootimg -i boot.img -o bootimg - -show "unpack-res.png" -echo "unpacking resources" -mkdir -p bootres -cp bootimg/boot.img-second bootres/ -cd bootres -rsce_tool -u boot.img-second - -show "replace-logo.png" -echo "replacing logo" -cp -f ../logo.bmp ./ -cp -f ../logo.bmp ./logo_kernel.bmp - -show "pack-res.png" -echo "packing updated resources" -for file in *; do - [ "$(basename "$file")" != "boot.img-second" ] && set -- "$@" -p "$file" -done -rsce_tool "$@" - -show "pack-img.png" -echo "packing updated boot.img" -cp -f boot-second ../bootimg -cd ../ -rm boot.img -mkbootimg --kernel bootimg/boot.img-kernel --second bootimg/boot-second --base 0x10000000 --kernel_offset 0x00008000 --ramdisk_offset 0xf0000000 --second_offset 0x00f00000 --pagesize 2048 --hashtype sha1 -o boot.img - -show "flash-img.png" -echo "flashing updated boot.img" -flashcp boot.img /dev/mtd2 && sync - -show "reboot.png" -echo "done, rebooting" - -sleep 2 - -# self-destruct -mv $DIR $DIR.disabled -reboot - -exit \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/launch.sh deleted file mode 100755 index 7f6676f36..000000000 --- a/skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/launch.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -cd $(dirname "$0") -./apply.sh > ./log.txt 2>&1 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/payload/logo-original.bmp b/skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/payload/logo-original.bmp deleted file mode 100644 index 6162709bf553a39d66fe09f60741d8b4fc04f3ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 285176 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 z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ a009C72oNAZfB*pk1PBlyK!Cs>PvHL#5(%6D diff --git a/skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/res/extract-img.png b/skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/res/extract-img.png deleted file mode 100644 index b0fd6efc418e154bbfecabb1b21a42b4378292c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3706 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 T64A{1_nf}2$-^q`XRrPbt;3dR diff --git a/skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/res/pack-img.png b/skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/res/pack-img.png deleted file mode 100644 index 47c6f007d367ad607ec988e6440cde5d20413f55..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4411 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 diff --git a/skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/res/pack-res.png b/skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/res/pack-res.png deleted file mode 100644 index 2294e8bfdf197fb6ef79f91a37ce42bd64603211..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4428 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 CSZ>Y$ diff --git a/skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/res/prep-env.png b/skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/res/prep-env.png deleted file mode 100644 index cd66635879075bb0a58a066d78db84da9423b967..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3945 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 diff --git a/skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/res/replace-logo.png b/skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/res/replace-logo.png deleted file mode 100644 index 7f7ed7579f43bf48d233b05c8359a84a896630b7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3495 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 diff --git a/skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/res/unpack-res.png b/skeleton/_unmaintained/EXTRAS/Tools/my355/Bootlogo.pak/res/unpack-res.png deleted file mode 100644 index 24e457ffe3e86342365ececc181f5c7d93dc6816..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4221 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/dev/null -} - -DIR="$(dirname "$0")" -cd "$DIR" - -show.elf "$DIR/res/preparing.png" 60 & - -# PATH doesn't like spaces in paths -cp -rf bin /tmp/ -PATH=/tmp/bin:$PATH - -# const -DT_NAME=device -DEV_PATH=/dev/mmcblk0 -# BOOT_OFFSET=$((16400 * 1024)) -# DTB_OFFSET=$((BOOT_OFFSET+1161216)) -DTB_OFFSET=17954816 -DTB_MAGIC=`xxd -s $DTB_OFFSET -l4 -ps $DEV_PATH` - -if [ "$DTB_MAGIC" != "d00dfeed" ]; then - echo "bad DTB_MAGIC at $DTB_OFFSET" - DTB_OFFSET=17971200 # alternate dtb location - DTB_MAGIC=`xxd -s $DTB_OFFSET -l4 -ps $DEV_PATH` - - if [ "$DTB_MAGIC" != "d00dfeed" ]; then - echo "bad DTB_MAGIC at $DTB_OFFSET" - killshow - show.elf "$DIR/res/fail.png" 2 - echo "unable to decompile dtb, aborting" - exit 1 - fi -fi - -# var -SIZE_OFFSET=$((DTB_OFFSET+4)) -DTB_SIZE=$((0x`xxd -s $SIZE_OFFSET -l4 -ps $DEV_PATH`)) - -dd if=$DEV_PATH of=$DT_NAME.dtb bs=1 skip=$DTB_OFFSET count=$DTB_SIZE 2>/dev/null # extract -dtc -I dtb -O dts -o $DT_NAME.dts $DT_NAME.dtb 2>/dev/null # decompile - -if [ ! -f $DT_NAME.dts ]; then - killshow - show.elf "$DIR/res/fail.png" 2 - echo "unable to decompile dtb, aborting" - exit 1 -fi - -CF= # lcd_dclk_freq -HT= # lcd_ht -VT= # lcd_vt -BL= # lcd_backlight - -# parse the values out of the decompiled dtb -while read -r LINE; do - KEY=$(echo "$LINE" | grep -oP '^[\w_]+') - HEX=$(echo "$LINE" | grep -oP '0x[\dA-Fa-f]+') - DEC=$(($HEX)) - - case $KEY in - lcd_dclk_freq) - CF=$DEC - ;; - lcd_ht) - HT=$DEC - ;; - lcd_vt) - VT=$DEC - ;; - lcd_backlight) - BL=$DEC - ;; - esac -# redirect instead of using a pipe so variables stay in scope -done < <(grep 'lcd_backlight\|lcd_dclk_freq\|lcd_ht\|lcd_vt' "$DT_NAME.dts") - -echo " CF HT VT (BL)" -echo "IN $CF-$HT-$VT ($BL)" - -# match to known (incorrect) values -CF_OFFSET=0 -HT_OFFSET=0 -VT_OFFSET=0 -case $CF-$HT-$VT in -24-770-526) # 35xx2024/35xxPLUS - HT_OFFSET=-2 # 768 - VT_OFFSET=-5 # 521 - ;; -24-770-528) # 35xxH - HT_OFFSET=-2 # 768 - VT_OFFSET=-7 # 521 - ;; -24-586-686) # 28xx - HT_OFFSET=-2 # 584 - VT_OFFSET=-1 # 685 - ;; -24-770-525) # 35xxSP - HT_OFFSET=-2 # 768 - VT_OFFSET=-4 # 521 - ;; -24-770-520) # Ry's 35xxSP - HT_OFFSET=-2 # 768 - VT_OFFSET= 1 # 521 - ;; -24-770-522) # 40xxH - HT_OFFSET=-2 # 768 - VT_OFFSET=-1 # 521 - ;; -25-728-568) # 35xxSP 1.0.6 - # the numbers don't add up but - # this is already hitting 60fps - # so fudge BL to exit early - echo "known good config" - BL=51 - ;; -36-812-756) # CubeXX - CF_OFFSET=1 # 37 - ;; -26-820-536) # 34xx - HT_OFFSET=-7 # 813 - VT_OFFSET=-3 # 533 - ;; -esac - -# update values or bail -BL_OFFSET=$((CF_OFFSET+HT_OFFSET+VT_OFFSET)) -if [ $BL_OFFSET -ne 0 ]; then - CF=$((CF+CF_OFFSET)) - HT=$((HT+HT_OFFSET)) - VT=$((VT+VT_OFFSET)) - BL=$((BL-BL_OFFSET)) -else - killshow - if [ $BL -ne 50 ]; then - show.elf "$DIR/res/patched.png" 2 - echo "this panel has (probably) already been patched" - else - show.elf "$DIR/res/unknown.png" 2 - echo "unrecognized panel configuration, aborting" - fi - exit 0 -fi - -echo "OUT $CF-$HT-$VT ($BL)" - -# dupe and inject updated values -MOD_PATH=$DT_NAME-mod.dts -cp $DT_NAME.dts $MOD_PATH -sed -i "s/\(lcd_dclk_freq = <\)0x[0-9A-Fa-f]\+/\1$CF/" "$MOD_PATH" -sed -i "s/\(lcd_ht = <\)0x[0-9A-Fa-f]\+/\1$HT/" "$MOD_PATH" -sed -i "s/\(lcd_vt = <\)0x[0-9A-Fa-f]\+/\1$VT/" "$MOD_PATH" -sed -i "s/\(lcd_backlight = <\)0x[0-9A-Fa-f]\+/\1$BL/" "$MOD_PATH" - -dtc -I dts -O dtb -o $DT_NAME-mod.dtb $DT_NAME-mod.dts 2>/dev/null # recompile -dd if=$DT_NAME.dtb of=$DT_NAME-mod.dtb bs=1 skip=4 seek=4 count=4 conv=notrunc 2>/dev/null # inject original size -fallocate -l $DTB_SIZE $DT_NAME-mod.dtb # zero fill empty space - -killshow -show.elf "$DIR/res/verifying.png" 60 & - -# validate checksum -A_PATH=$DT_NAME.dtb -B_PATH=$DT_NAME-mod.dtb - -declare -a BYTES -BYTES=(`xxd -p -c 1 $A_PATH | tr '\n' ' '`) -SUM=0 -for (( i=0; i<${#BYTES[@]}; i++)); do - SUM=$((SUM+0x${BYTES[i]})) -done -A_SUM=$SUM - -declare -a BYTES -BYTES=(`xxd -p -c 1 $B_PATH | tr '\n' ' '`) -SUM=0 -for (( i=0; i<${#BYTES[@]}; i++)); do - SUM=$((SUM+0x${BYTES[i]})) -done -B_SUM=$SUM - -if [ $A_SUM != $B_SUM ]; then - killshow - show.elf "$DIR/res/mismatch.png" 2 - echo "A $A_SUM" - echo "B $B_SUM" - echo "mismatched checksum, aborting" - exit 1 -fi - -killshow -show.elf "$DIR/res/applying.png" 60 & - -dd if=$DT_NAME-mod.dtb of=$DEV_PATH bs=1 seek=$DTB_OFFSET conv=notrunc 2>/dev/null # inject -sync - -echo "applied fix successfully!" - -show.elf "$DIR/res/rebooting.png" 2 -reboot diff --git a/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Apply Panel Fix.pak/bin/.keep b/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Apply Panel Fix.pak/bin/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Apply Panel Fix.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Apply Panel Fix.pak/launch.sh deleted file mode 100755 index 63a132679..000000000 --- a/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Apply Panel Fix.pak/launch.sh +++ /dev/null @@ -1,5 +0,0 @@ -#/bin/bash - -cd "$(dirname "$0")" - -bash ./apply.sh > ./log.txt 2>&1 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Apply Panel Fix.pak/res/applying.png b/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Apply Panel Fix.pak/res/applying.png deleted file mode 100644 index 3f3b46a8d782189336b2a6c68dce2d7aae13caa3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3728 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 diff --git a/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Apply Panel Fix.pak/res/fail.png b/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Apply Panel Fix.pak/res/fail.png deleted file mode 100644 index ca7fce89b2ccb190dd25f3fa47df60ca26a43232..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4597 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 M1T`$X@#w|>0-avM)c^nh diff --git a/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Apply Panel Fix.pak/res/mismatch.png b/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Apply Panel Fix.pak/res/mismatch.png deleted file mode 100644 index cc613f6d702f1139d4323e6908c9238774c0fc2d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4935 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 diff --git a/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Apply Panel Fix.pak/res/patched.png b/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Apply Panel Fix.pak/res/patched.png deleted file mode 100644 index 319d83496c6f509e4f6ca41e4a9a25c569b3555b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3888 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 diff --git a/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Apply Panel Fix.pak/res/preparing.png b/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Apply Panel Fix.pak/res/preparing.png deleted file mode 100644 index bddb1b62622796a1b6e7da2d4d7314e891f04c7d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3588 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 Tpk@#9|E_?pIb5x`^tk_jZLzAc diff --git a/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Apply Panel Fix.pak/res/rebooting.png b/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Apply Panel Fix.pak/res/rebooting.png deleted file mode 100644 index 02693b6301c086594be30606e5a1c456301217f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4343 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 UsS&^M$lr%%#xSEY1J@`20lKd#^#A|> diff --git a/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Apply Panel Fix.pak/res/unknown.png b/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Apply Panel Fix.pak/res/unknown.png deleted file mode 100644 index 66bb4ffc41705df853560771f797fea0193de9eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4381 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 /etc/default/locale - -# install or update ssh server -apt -y update && apt -y install --reinstall openssh-server -echo "d /run/sshd 0755 root root" > /etc/tmpfiles.d/sshd.conf - -# enable login root:root -echo "PermitRootLogin yes" >> /etc/ssh/sshd_config -printf "root\nroot" | passwd root - -killall -9 show.elf - -} &> ./log.txt - -mv "$DIR" "$DIR.disabled" -reboot # required for root:root to be recognized and new locale to take effect diff --git a/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Enable SSH.pak/ssh.png b/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Enable SSH.pak/ssh.png deleted file mode 100755 index f7963a51ec327d7fabd4bc53af35a49b64e3d473..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5337 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
S*qcG{aZu2n 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 diff --git a/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Files.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Files.pak/launch.sh deleted file mode 100755 index 56066fccc..000000000 --- a/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Files.pak/launch.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -DIR="/mnt/vendor/bin/fileM" - -if [ ! -d "$DIR" ]; then - DIR="$(dirname "$0")" - cd "$DIR" - show.elf "$DIR/missing.png" 4 -else - cd "$DIR" - HOME="$SDCARD_PATH" - syncsettings.elf & - ./dinguxCommand_en.dge -fi - diff --git a/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Files.pak/missing.png b/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Files.pak/missing.png deleted file mode 100644 index 2640abf3cd39d63ab3a97b0d0f298209cbaf5b1e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11845 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 k&+Gq(9r*5dC4)x*`dr!rzd(ow{r$/dev/null -} - -DIR="$(dirname "$0")" -cd "$DIR" - -show.elf "$DIR/res/preparing.png" 60 & - -# PATH doesn't like spaces in paths -cp -rf bin /tmp/ -PATH=/tmp/bin:$PATH - -# const -DT_NAME=device -DEV_PATH=/dev/mmcblk0 -# BOOT_OFFSET=$((16400 * 1024)) -# DTB_OFFSET=$((BOOT_OFFSET+1161216)) -DTB_OFFSET=17954816 -DTB_MAGIC=`xxd -s $DTB_OFFSET -l4 -ps $DEV_PATH` - -if [ "$DTB_MAGIC" != "d00dfeed" ]; then - echo "bad DTB_MAGIC at $DTB_OFFSET" - DTB_OFFSET=17971200 # alternate dtb location - DTB_MAGIC=`xxd -s $DTB_OFFSET -l4 -ps $DEV_PATH` - - if [ "$DTB_MAGIC" != "d00dfeed" ]; then - echo "bad DTB_MAGIC at $DTB_OFFSET" - killshow - show.elf "$DIR/res/fail.png" 2 - echo "unable to decompile dtb, aborting" - exit 1 - fi -fi - -# var -SIZE_OFFSET=$((DTB_OFFSET+4)) -DTB_SIZE=$((0x`xxd -s $SIZE_OFFSET -l4 -ps $DEV_PATH`)) - -dd if=$DEV_PATH of=$DT_NAME.dtb bs=1 skip=$DTB_OFFSET count=$DTB_SIZE 2>/dev/null # extract -dtc -I dtb -O dts -o $DT_NAME.dts $DT_NAME.dtb 2>/dev/null # decompile - -if [ ! -f $DT_NAME.dts ]; then - killshow - show.elf "$DIR/res/fail.png" 2 - echo "unable to decompile dtb, aborting" - exit 1 -fi - -# dupe so we modify a copy -MOD_PATH=$DT_NAME-mod.dts -cp $DT_NAME.dts $MOD_PATH - -# parse the values out of the decompiled dtb -KEY_SELECT=$(sed -n "/keySEl {/,/};/s/.*linux,code = <\(0x[^>]*\)>.*/\1/p" "$MOD_PATH") -KEY_MENU=$(sed -n "/keyMenu {/,/};/s/.*linux,code = <\(0x[^>]*\)>.*/\1/p" "$MOD_PATH") - -# swap the values -sed -i "/keySEl {/,/};/s/linux,code = <0x[^>]*>/linux,code = <${KEY_MENU}>/g" "$MOD_PATH" -sed -i "/keyMenu {/,/};/s/linux,code = <0x[^>]*>/linux,code = <${KEY_SELECT}>/g" "$MOD_PATH" - -dtc -I dts -O dtb -o $DT_NAME-mod.dtb $DT_NAME-mod.dts 2>/dev/null # recompile -dd if=$DT_NAME.dtb of=$DT_NAME-mod.dtb bs=1 skip=4 seek=4 count=4 conv=notrunc 2>/dev/null # inject original size -fallocate -l $DTB_SIZE $DT_NAME-mod.dtb # zero fill empty space - -killshow -show.elf "$DIR/res/applying.png" 60 & - -dd if=$DT_NAME-mod.dtb of=$DEV_PATH bs=1 seek=$DTB_OFFSET conv=notrunc 2>/dev/null # inject -sync - -killshow -exit 0 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Swap Menu.pak/bin/.keep b/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Swap Menu.pak/bin/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Swap Menu.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Swap Menu.pak/launch.sh deleted file mode 100644 index 63a132679..000000000 --- a/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Swap Menu.pak/launch.sh +++ /dev/null @@ -1,5 +0,0 @@ -#/bin/bash - -cd "$(dirname "$0")" - -bash ./apply.sh > ./log.txt 2>&1 \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Swap Menu.pak/res/applying.png b/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Swap Menu.pak/res/applying.png deleted file mode 100644 index 3f3b46a8d782189336b2a6c68dce2d7aae13caa3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3728 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 diff --git a/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Swap Menu.pak/res/fail.png b/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Swap Menu.pak/res/fail.png deleted file mode 100644 index ca7fce89b2ccb190dd25f3fa47df60ca26a43232..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4597 zcmeHKS6h=?w*_Sj8xT|s(xVgsLoo;GB_d5lgMgG65DgHJ9z`H@L_`uH5~VjOf^?~& zgBT2Zm5L)O+Afe>Mi*tU%ck#V9>v`72n(G~N%rVA_xd$~l%`L*s#>RH~)=fhT zHntPtY;5emxK6Nk8mdgISc|Z)k*%+#H`3St@l$6ueJ5{(^Tk`9k6oNCoF6-(QDkQw zHny`#w+!{~2aK;y!9M|KLUvX(S89 zJU$v6986NOXY9}6qT*XRbvyxIVHbin2i}Yp(4?xA8!F7xb3$WUf7*}BJu$&a#5x!k zrX{RutEthv^^ZJX`vP3j)6=VG;?c%-yo)zXR=B6Oi~E_}`kC^J{aHY!!h>qLV~Fq4 zJ%YpfbaT+$x7ab|Bt^L2)@(=8!@ynHT-Q1fPg!j3HQ?91e^`g?6#=Ix zGNm|R8+z^`DqCS4`kQze(;>q)z{_(q)hn$vmlI6ik=mt7xh(;E- z@JeX-eAwR_G=l)j#t>Yov}l3Mz?H&PW~``s%i(sn8RV$?bDNlaq=10H*52{K2CkKp zUm}=VN-(^0vd2n0ovo+ve>A`bAFj38Bs`}Mdrmc|Qf)$af7vX4D(6DVVmWs=5m*KWuXSkz-i^ z&CvGua&s#RMKvGMCa^#j?pkVUf=n@OKZRSSg6Rn$n}7dr+AAO4O8 z_91&1`yn0K<;f&-Bfm=nW%iAgz&lVV(o)h83?5tEr}b%X*fj?}4@K*9?EG0C%nG5w zNT!FUVuFd6_*{?ai&@*qdH6O77`8fEk(*r2US(IA-pV{~oNGc)#sMMI*6jzeo~=)W zVc^wbuA%-2-R?&v{$F367B{6_Ot7uhjZeH8BrQGBmmIRUK4qGy5EBzbTNU=3V6=@N=TK{g)1KYs0-vruh+&JF^?5`J z`HikOge_@TfYZO?Yi-os!nD5cUv}> zmzTpDwFCdSV&jz;qHS+hQsNU2CtQD~%Ct)E7#3m2S|q(L@te=RRDbPxR|@p17jwN= z%(j5{a$`xIrHBmz>{zKwSC$%~SR!VgcnRG;nLcz65LKT%hmFck>m2J4%kuCf0Gu6u zdWYvO6ivU0`==a1cczO3l@&u($2Is)BQm8+9Yx=MEVGTWlAAWsel!pAb4NR}>LV1% zfAW6apHZ0bZWkri9!G3+VjfpX-c#WmmX8Do=fh-%D|UOsQtteiJYUZpXzSIuRvS0S znvX2p;!9T31vkQ1T*oS%%Uh2FTR~kdMd+lEA=p@NF94wpQp;@_&C8@>fPW6^J~B{3 zIty4q#TDAmz6|XkrQlETxFHJDd#v(f9hh~Xw+ww(#xeWk<))d@Vf9&rM!?xmoe{a^ z#91a6l;GgTlN=@Wt7&AiqWpo~qXG1)T6^LiwHu!1Z_|DBeKy&Qkm*ftlU(Qu?4l_7 z?EW_Dv4HlOsZ>r}(vlz&6~qt5DQCM^nypn>XiV?4NrnkM#y2E`Yo7%N>)^A(5}0)f zow8q>Iwq~e!j$+tXlaMvOxo6v^(}~r@_4{kq|t{^zE#*MDv*7okcf!bbwP3TEQ$OI zzGUuNoCHzJ9i1kU^3GFaH@o0)u|iNe$nDe0_|+7d!gfr74<^lAC7IF^M!5Ih%)yG^ zP(98dGC4_IyHa1_Dl(>gHcJOV?#F+-s8(J_oxlWFj?u5+m&sgiNArYfHg(eghYC+? z{x>Z`!wM&MpFL`I{@lR64vR@}As@(5VAtB-d}4=+;PN201^KVfS*3%nyzqjjiHXWs z850zH3S{MPLyu+n+1Kep87u8Gih)yIVGcp1NHGzj&e-SRK$t~@aUdvej#ZeXncF)3jwEG=_Pmq15W>==TY;@Ct^4#!>vCRcr|jb%iw5WJ#91Pu;nbZ_s_X^# z%l~(&+kg2XRYt_mOXJ3_$VN-8YYUl}Sy#J5lq;ciMzGa9_-cDVa>_azerplGbu zzE3T0UGOyExN1Rg`&op+gx(|r-4cs|6Pj?|=m#9gkF&S)r3v)m)&hriD^|8ut<7((^Sdzq(uL3u&Mh#fR76CVn!WD&z*Od?jJm=H>jfam+I?-&ZX9{s$c7 zc)um&pey>edGY#Gqd#@H)J%`=bXYRgNxEc?ibd@Qk;MJa8`zg{M`utNU8i;h9ztrL z)e7}_oprURUBj&?JXjUUVPC(!d5OdoGaYI3{GNi|WXQYWWuM2^zdc8f0rvoS6kDm;fi%k_e?Sm6hNjbM` zLvl#$C)qUxpx#=w(#G9SdL7PoU`6l0m>Q6%`MvV9*hFxVK}D5#f;Vq7ktDxLg$oMofY@f1ev+NAs|1H}`${!8Dp z`5}j&bJ!oY1lPkOKy_TjJGS?R9K@CHhtkGe-pR|FWqLFXY;A2Jl#dVTJN-I4J*q0} zjTE&DlrHxU1l^Dj3?XTojo1fidF^pU~|==XE!y3cEE?cTA!+WtihN4d%@gs1{g zM8V?M$b5~XFPuOR-R&u*9{D&3zc!smP(g0JmvvxJ0IW>wZ(sPzxq2{8qnh>SoA#Ud zuC>`8ZGPn^zi$rOTc2r#K;~mDv{Y4V{MN>$cTR76Y|Z=p-u(TQZY6E*I9%_cx-*Ma zUa&DBo{}|zkZ`~a&>HI6Td^e*S=|8%`>EHr`VYbd$TcK#1H!0-sxdn%^RKtV1=LWC z0UW$>+3k0sa7U_~^;Q?C{CrrVxL~y?-7AR)Ai6O8F6#~3)U$qFy3%NKkUt?e3;FK` zs21j!sGBQ=EUbI{gxKNp$>;-A*u&;&cnf-G0deM4U+nr0w5k&I-vez;x65_~%CU==sk0lbn2qyCV)Lxwi^UGn;C!4d#;l z&({QpUNXy*Nu;q*C${&eYYuK@zghcBi}kUq1pJ{>unhi8<3+#8=Dle+YNcBLZz>32 z9_>}3=QdbVRa9;)1_O(^o&98aY61YaorJ;8AZB0u!z0P{EvpcO_Hr;|Wyy{*_uXPX z{KU_yA4M8P>+Z31)b%6Sm1((qlkJQr8}y5DakzYt9%scu1Afy_XV~LRG!nc)mn;lb zmk)cWkB!e7SqAfwcklM%9mFHN_-D%lL`@=J?ukxdWPKB(KbXLH(*O~vnxCP^B$OIcNE@``2<%Z9aAJk1bJI*>o721^D{SeSCiAd zNMMS_wb$s~zPq(WjHnvQ)mkC?yieZYi)kczBL%G`G2nbqQCG$aaz~?y4gvR$&c&Mx z{=dDxGXh8rmYgf*dZeH;*6~0%aAcJ{_X~S65Fn%3|ADgin)3Xv(_o$mCOBOOtmc3<{4ycA>&#ea&UuJ{{~zY3Jq zFQlGAErAwd_m-Pd(r&HT^^IH4v-ECdG2Lm}HM*?zn9&bmHc6g1eeU7eiBEs9N#P;e zWZB&fUWpK}haJcGl}H0|OPvsgFX}^R08W_ASnFQ4%UzR@X4}*+&fY)dW~wvZJQzVs z34dT;;Id7IK$zJLfCX2SziP(v^ zY_4DS_xFpeimgj*<3n`(*C&UDhKR(Mo&T{<&;MTRF9JQ4Os=bJ0!808ia4Zi{@uA{ M1T`$X@#w|>0-avM)c^nh diff --git a/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Swap Menu.pak/res/preparing.png b/skeleton/_unmaintained/EXTRAS/Tools/rg35xxplus/Swap Menu.pak/res/preparing.png deleted file mode 100644 index bddb1b62622796a1b6e7da2d4d7314e891f04c7d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3588 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 Tpk@#9|E_?pIb5x`^tk_jZLzAc diff --git a/skeleton/_unmaintained/EXTRAS/Tools/rgb30/Clock.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Tools/rgb30/Clock.pak/launch.sh deleted file mode 100755 index 7eba99d00..000000000 --- a/skeleton/_unmaintained/EXTRAS/Tools/rgb30/Clock.pak/launch.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -cd $(dirname "$0") -./clock.elf diff --git a/skeleton/_unmaintained/EXTRAS/Tools/rgb30/Files.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Tools/rgb30/Files.pak/launch.sh deleted file mode 100755 index 4923beefe..000000000 --- a/skeleton/_unmaintained/EXTRAS/Tools/rgb30/Files.pak/launch.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -cd $(dirname "$0") - -HOME="$SDCARD_PATH" -./DinguxCommander \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Tools/rgb30/Input.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Tools/rgb30/Input.pak/launch.sh deleted file mode 100755 index ca0aefe28..000000000 --- a/skeleton/_unmaintained/EXTRAS/Tools/rgb30/Input.pak/launch.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -cd $(dirname "$0") -./minput.elf diff --git a/skeleton/_unmaintained/EXTRAS/Tools/rgb30/Splore.pak/extracting.png b/skeleton/_unmaintained/EXTRAS/Tools/rgb30/Splore.pak/extracting.png deleted file mode 100644 index 18118480fb6086ac52f5b783e5a316ac716236b3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3882 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/dev/null | head -n 1) - if [[ ! -z "$PICO8_ZIP" && -f "$PICO8_ZIP" ]]; then - show.elf "$DIR/extracting.png" 60 & - unzip -o "$PICO8_ZIP" -d ./ - cp ./sdl_controllers.txt ./pico-8 - killall -s KILL show.elf - else - show.elf "$DIR/missing.png" 4 - exit - fi -fi - -# ensure correct sdl controller file is in place -cmp -s "$DIR/sdl_controllers.txt" "$DIR/pico-8/sdl_controllers.txt" -if [ "$?" -eq 1 ]; then - cp ./sdl_controllers.txt ./pico-8; -fi - -cd ./pico-8 && ./pico8_64 -splore -pixel_perfect 1 -joystick 0 diff --git a/skeleton/_unmaintained/EXTRAS/Tools/rgb30/Splore.pak/missing.png b/skeleton/_unmaintained/EXTRAS/Tools/rgb30/Splore.pak/missing.png deleted file mode 100644 index 218043091144e14c98f1235277b7f977ff199552..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9868 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 bkZJ`zUKfhjd^{KTXGjAb!BoL>Du2r_<% diff --git a/skeleton/_unmaintained/EXTRAS/Tools/rgb30/Splore.pak/sdl_controllers.txt b/skeleton/_unmaintained/EXTRAS/Tools/rgb30/Splore.pak/sdl_controllers.txt deleted file mode 100644 index 9ea8137c2..000000000 --- a/skeleton/_unmaintained/EXTRAS/Tools/rgb30/Splore.pak/sdl_controllers.txt +++ /dev/null @@ -1 +0,0 @@ -19009b4d4b4800000111000000020000,retrogame_joypad,platform:Linux,x:b2,a:b1,b:b0,y:b3,back:b8,start:b9,dpleft:b15,dpdown:b14,dpright:b16,dpup:b13,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,rightx:a2,righty:a3, \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Tools/rgb30/Wi-Fi.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Tools/rgb30/Wi-Fi.pak/launch.sh deleted file mode 100755 index 1f11481bc..000000000 --- a/skeleton/_unmaintained/EXTRAS/Tools/rgb30/Wi-Fi.pak/launch.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/bin/sh - -cd "$(dirname "$0")" - -OLDIFS=$IFS -IFS=$'\n' read -a WIFI -d '' < ./wifi.txt -IFS=$OLDIFS - -WIFI_NAME=${WIFI[0]} -WIFI_PASS=${WIFI[1]} - -############## - -. /etc/profile # NOTE: this nukes NextUI's PATH modifications -PATH=/storage/roms/.system/rgb30/bin:$PATH - -CUR_NAME=`get_setting wifi.ssid` -CUR_PASS=`get_setting wifi.key` - -RES_PATH="$(dirname "$0")/res" -STATUS=$(cat "/sys/class/net/wlan0/operstate") - -function disconnect() -{ - echo "disconnect" - - wifictl disable & - show.elf "$RES_PATH/disable.png" 2 - STATUS=down -} - -function connect() -{ - echo "connect" - wifictl enable & - DELAY=30 - show.elf "$RES_PATH/enable.png" $DELAY & - for i in `seq 1 $DELAY`; do - STATUS=$(cat "/sys/class/net/wlan0/operstate") - if [ "$STATUS" = "up" ]; then - break - fi - sleep 1 - done - killall -s KILL show.elf -} - -{ -if [ "$WIFI_NAME" != "$CUR_NAME" ] || [ "$WIFI_PASS" != "$CUR_PASS" ]; then - echo "change" - - if [ "$STATUS" = "up" ]; then - disconnect - fi - - echo "$WIFI_NAME:$WIFI_PASS" - show.elf "$RES_PATH/update.png" 2 - set_setting wifi.ssid "$WIFI_NAME" - set_setting wifi.key "$WIFI_PASS" -fi - -echo "toggle" -if [ "$STATUS" = "up" ]; then - disconnect -else - connect -fi -} &> ./log.txt \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Tools/rgb30/Wi-Fi.pak/res/disable.png b/skeleton/_unmaintained/EXTRAS/Tools/rgb30/Wi-Fi.pak/res/disable.png deleted file mode 100755 index a11cd454ccdcdf2780fc7a62e0c637d160ebc024..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3878 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 diff --git a/skeleton/_unmaintained/EXTRAS/Tools/rgb30/Wi-Fi.pak/res/enable.png b/skeleton/_unmaintained/EXTRAS/Tools/rgb30/Wi-Fi.pak/res/enable.png deleted file mode 100755 index 9e0b074f2e35e5e9a017114eb5d9ef5744585366..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3491 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 Q(?2D!rGrK7MZbH01C+Of6aWAK diff --git a/skeleton/_unmaintained/EXTRAS/Tools/rgb30/Wi-Fi.pak/res/update.png b/skeleton/_unmaintained/EXTRAS/Tools/rgb30/Wi-Fi.pak/res/update.png deleted file mode 100644 index 34d481ccd7a8dc225e2bda02dca56ed9bb35e5a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3736 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 diff --git a/skeleton/_unmaintained/EXTRAS/Tools/rgb30/Wi-Fi.pak/wifi.txt b/skeleton/_unmaintained/EXTRAS/Tools/rgb30/Wi-Fi.pak/wifi.txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/EXTRAS/Tools/trimuismart/Bootlogo.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Tools/trimuismart/Bootlogo.pak/launch.sh deleted file mode 100755 index c14b37239..000000000 --- a/skeleton/_unmaintained/EXTRAS/Tools/trimuismart/Bootlogo.pak/launch.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh - -cd $(dirname "$0") - -{ - -LOGO_PATH=./logo.bmp - -if [ ! -f $LOGO_PATH ]; then - LOGO_PATH=$SYSTEM_PATH/dat/logo.bmp -fi - -if [ ! -f $LOGO_PATH ]; then - echo "No logo.bmp available. Aborted" - exit 1 -fi - -dd if=$LOGO_PATH of=/dev/by-name/bootlogo bs=65536 - -echo "Done." - -} &> ./log.txt - -# self-destruct -DIR=$(dirname "$0") -mv $DIR $DIR.disabled diff --git a/skeleton/_unmaintained/EXTRAS/Tools/trimuismart/Clock.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Tools/trimuismart/Clock.pak/launch.sh deleted file mode 100755 index 7eba99d00..000000000 --- a/skeleton/_unmaintained/EXTRAS/Tools/trimuismart/Clock.pak/launch.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -cd $(dirname "$0") -./clock.elf diff --git a/skeleton/_unmaintained/EXTRAS/Tools/trimuismart/Files.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Tools/trimuismart/Files.pak/launch.sh deleted file mode 100755 index 4923beefe..000000000 --- a/skeleton/_unmaintained/EXTRAS/Tools/trimuismart/Files.pak/launch.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -cd $(dirname "$0") - -HOME="$SDCARD_PATH" -./DinguxCommander \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Tools/trimuismart/Input.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Tools/trimuismart/Input.pak/launch.sh deleted file mode 100755 index ca0aefe28..000000000 --- a/skeleton/_unmaintained/EXTRAS/Tools/trimuismart/Input.pak/launch.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -cd $(dirname "$0") -./minput.elf diff --git a/skeleton/_unmaintained/EXTRAS/Tools/zero28/Bootlogo.pak/bootlogo.bmp b/skeleton/_unmaintained/EXTRAS/Tools/zero28/Bootlogo.pak/bootlogo.bmp deleted file mode 100644 index 16a6237ac6aa893f9f66c5f12982443bbef0afe2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43256 zcmeI5IY?|t6hQxg1~LXR7<^Gd+|3k0#BdZ*Q83V4ja)z!4FnYp#K1K$5CaX|7;s6= zzlKIGC@P4!fgFMc9OG~%6xBofx z1FnIC;HICT{7IgcmUex8?NGqKxdm>5v;MI1CoSCQ-*V&V066OpD}T~DxVqqr3^?l# zD}U1RnQ?ZE46Dx0&bPNWRSqX7CnY5%-t4PdGhN>s2OR(Y{;ucd>FFu9gJnH~=BC2F zdy_vtKJ*-fBJItloc{b583$GQG&VLqKR;t54-XGD zH8rYsu!V4tRr!E^PEOA5?k)podU`rKI$GWulicw^c`{fNkj~7^FmM2Vc6K&a6Ua6H=jt_d{fa5DGD=#iCR8c_J20A#{4whA|nXZq0_a>j6o$0v= zs3RgGJet)rXl^Qx5SU1f!t4S9oFgM68EdYfxy1Bx?hyhLSy54ObabR@ABIx<`}-MF z?jVixyHQvw@LhP-`)H89jq_GC4{K>L#>Qa)YI%A2{{G&elBtwca19*P8)w6yNG1YA zfCvx)B0vO)01+SpM1Tko0U|&IhyW2F0z`la5CJ0KJOYV{iB(lqeSLk4i;L^)>#%nq z)aD!^KQLpJk&$5{{DOi4SQfIgv!gV%VWYCW`v)~{aeI6F-rk;##I%3f#(7vJ&OJRn zS65fsZrYyE#{GkmoNH@qwO8rbju&S@(%;~#B_}7ZuCC&&8Z8GOpv*5;S6AQM+!zg( z$-Io$LDm@@9Aq--fMAdr`uw@s*;xlrp-$C1A_K$<9T>D%&8pG*Rxp&YxxKw@G&iNp z+cnOgo13eYPt%p{nztGr9yT4FeEw~mhc$FMRi3R&)874q@$vDh8TP5awYAmK(gKIB z$UGXtL@@aW(a7{8ZgXTTU!~+6vPDX?(P_3dO>PkV5+>VN0m>-Tc#LH zfG4IGgKd(`69`njLFcsaY;g=d2QdxnWNO!0#}-=-U_Yg)sR>&q850O#zZ(WOii(P` zagyBxXdKCn!cxJCana4qO&AxY76^0W_~ZTcn$RJh3dZ^E-9Je4R!qUOC`j|L9>MCZ ze}?`DB=l$yB57R#Pe!{3CwN~Qt&`z7TeSX})_pOk_0~Vbx&=50oiT-jw2l$e@FvH_ z#f^-NJU%}1jVmaq(CPD*5XaNHTug(J6A}`}#>QZ-nI{Z;u{%0C7=1wywr}%B92p~k zz+XyAN`iL|!l(j|0_yO#wl+SA&luV_ff2!Ooyp0`*Vk8`@bU3+b8|CRR+3XwQ)wTN zi&$4zm&f-V!^@QdvVwy4wE^eY*jWBOyaxvdb#--0croGbVuj6mP#p z=k~bC1f<{Xw#Ez4Vh^`-sPx94VH~NvyqpK96ayQ;!{=Nz?eS-sb0K7~hsimC+T+iH zaef)Rj1EifO{{wD{3%vjU diff --git a/skeleton/_unmaintained/EXTRAS/Tools/zero28/Bootlogo.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Tools/zero28/Bootlogo.pak/launch.sh deleted file mode 100755 index 4ef99c966..000000000 --- a/skeleton/_unmaintained/EXTRAS/Tools/zero28/Bootlogo.pak/launch.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -DIR=$(dirname "$0") -cd $DIR - -BOOT_DEV=/dev/mmcblk0p1 -BOOT_PATH=/mnt/boot - -mkdir -p $BOOT_PATH -mount -t vfat $BOOT_DEV $BOOT_PATH - -# convert bootlogo.png -define bmp:format=bmp3 -depth 8 -channel BGRA BMP3:bootlogo.bmp -cp bootlogo.bmp $BOOT_PATH - -umount $BOOT_PATH -rm -rf $BOOT_PATH - -# self-destruct -mv $DIR $DIR.disabled - -reboot \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Tools/zero28/Clock.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Tools/zero28/Clock.pak/launch.sh deleted file mode 100755 index 34c09b523..000000000 --- a/skeleton/_unmaintained/EXTRAS/Tools/zero28/Clock.pak/launch.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -cd $(dirname "$0") -./clock.elf # &> ./log.txt diff --git a/skeleton/_unmaintained/EXTRAS/Tools/zero28/Files.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Tools/zero28/Files.pak/launch.sh deleted file mode 100755 index 4923beefe..000000000 --- a/skeleton/_unmaintained/EXTRAS/Tools/zero28/Files.pak/launch.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -cd $(dirname "$0") - -HOME="$SDCARD_PATH" -./DinguxCommander \ No newline at end of file diff --git a/skeleton/_unmaintained/EXTRAS/Tools/zero28/Input.pak/launch.sh b/skeleton/_unmaintained/EXTRAS/Tools/zero28/Input.pak/launch.sh deleted file mode 100755 index ca0aefe28..000000000 --- a/skeleton/_unmaintained/EXTRAS/Tools/zero28/Input.pak/launch.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -cd $(dirname "$0") -./minput.elf diff --git a/skeleton/_unmaintained/SYSTEM/gkdpixel/bin/shutdown b/skeleton/_unmaintained/SYSTEM/gkdpixel/bin/shutdown deleted file mode 100755 index 2edad76e1..000000000 --- a/skeleton/_unmaintained/SYSTEM/gkdpixel/bin/shutdown +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -# NOTE: doesn't actually shutdown because exiting auotmaically powers off cleanly - -if [ -n "$DATETIME_PATH" ]; then - echo `date +'%F %T'` > "$DATETIME_PATH" - sync -fi diff --git a/skeleton/_unmaintained/SYSTEM/gkdpixel/cores/.keep b/skeleton/_unmaintained/SYSTEM/gkdpixel/cores/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/SYSTEM/gkdpixel/dat/.keep b/skeleton/_unmaintained/SYSTEM/gkdpixel/dat/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/SYSTEM/gkdpixel/lib/.keep b/skeleton/_unmaintained/SYSTEM/gkdpixel/lib/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/FC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/FC.pak/default.cfg deleted file mode 100755 index 971d25715..000000000 --- a/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/FC.pak/default.cfg +++ /dev/null @@ -1,22 +0,0 @@ -minarch_screen_scaling = Native - -fceumm_sndquality = High -fceumm_sndvolume = 10 --fceumm_aspect = 8:7 PAR --fceumm_turbo_enable = Player 1 --fceumm_show_adv_system_options = disabled --fceumm_show_adv_sound_options = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Change Disk = NONE:L1 -bind Insert Disk = NONE:R1 -bind Insert Coin = NONE:R2 diff --git a/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/FC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/FC.pak/launch.sh deleted file mode 100755 index 280598bbc..000000000 --- a/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/FC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=fceumm - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/GB.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/GB.pak/default.cfg deleted file mode 100755 index d3e80e7b6..000000000 --- a/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/GB.pak/default.cfg +++ /dev/null @@ -1,18 +0,0 @@ -gambatte_gb_colorization = internal -gambatte_gb_internal_palette = TWB64 - Pack 1 -gambatte_gb_palette_twb64_1 = TWB64 038 - Pokemon mini Ver. -gambatte_gb_bootloader = disabled --gambatte_audio_resampler = sinc - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Prev. Palette = NONE:L1 -bind Next Palette = NONE:R1 diff --git a/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/GB.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/GB.pak/launch.sh deleted file mode 100755 index 9143f24c9..000000000 --- a/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/GB.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gambatte - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/GBA.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/GBA.pak/default.cfg deleted file mode 100755 index ea76e21f6..000000000 --- a/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/GBA.pak/default.cfg +++ /dev/null @@ -1,14 +0,0 @@ --gpsp_save_method = libretro - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 diff --git a/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/GBA.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/GBA.pak/launch.sh deleted file mode 100755 index 5678aaca7..000000000 --- a/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/GBA.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gpsp - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/GBC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/GBC.pak/default.cfg deleted file mode 100755 index 606e7b74c..000000000 --- a/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/GBC.pak/default.cfg +++ /dev/null @@ -1,15 +0,0 @@ -gambatte_gb_bootloader = disabled --gambatte_audio_resampler = sinc - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Prev. Palette = NONE:L1 -bind Next Palette = NONE:R1 diff --git a/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/GBC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/GBC.pak/launch.sh deleted file mode 100755 index 9143f24c9..000000000 --- a/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/GBC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gambatte - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/MD.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/MD.pak/default.cfg deleted file mode 100755 index 9c11684fc..000000000 --- a/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/MD.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ -minarch_screen_scaling = Native - --picodrive_sound_rate = 44100 --picodrive_smstype = Auto --picodrive_smsfm = off --picodrive_smsmapper = Auto --picodrive_ggghost = off - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Mode = SELECT -bind Start = START -bind A Button = Y -bind B Button = X:B -bind C Button = A -bind X Button = B:L1 -bind Y Button = L1:X -bind Z Button = R1 diff --git a/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/MD.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/MD.pak/launch.sh deleted file mode 100755 index 81688be79..000000000 --- a/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/MD.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/PS.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/PS.pak/default.cfg deleted file mode 100755 index 09cc2c1cd..000000000 --- a/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/PS.pak/default.cfg +++ /dev/null @@ -1,17 +0,0 @@ --pcsx_rearmed_display_internal_fps = disabled --pcsx_rearmed_show_input_settings = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Circle = A -bind Cross = B -bind Triangle = X -bind Square = Y -bind L1 Button = L1 -bind R1 Button = R1 -bind L2 Button = NONE:L2 -bind R2 Button = NONE:R2 diff --git a/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/PS.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/PS.pak/launch.sh deleted file mode 100755 index e3ba5ac06..000000000 --- a/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/PS.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=pcsx_rearmed - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/SFC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/SFC.pak/default.cfg deleted file mode 100755 index 34024e24c..000000000 --- a/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/SFC.pak/default.cfg +++ /dev/null @@ -1,14 +0,0 @@ -minarch_screen_scaling = Native - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Y Button = Y -bind X Button = X -bind B Button = B -bind A Button = A -bind L Button = L1 -bind R Button = R1 \ No newline at end of file diff --git a/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/SFC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/SFC.pak/launch.sh deleted file mode 100755 index 44e982862..000000000 --- a/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/Emus/SFC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=snes9x2005_plus - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/MinUI.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/MinUI.pak/launch.sh deleted file mode 100755 index 146e8d288..000000000 --- a/skeleton/_unmaintained/SYSTEM/gkdpixel/paks/MinUI.pak/launch.sh +++ /dev/null @@ -1,76 +0,0 @@ -#!/bin/sh -# MiniUI.pak - -####################################### - -export PLATFORM="gkdpixel" -export SDCARD_PATH="/media/roms" -export BIOS_PATH="$SDCARD_PATH/Bios" -export SAVES_PATH="$SDCARD_PATH/Saves" -export CHEATS_PATH="$SDCARD_PATH/Cheats" -export SYSTEM_PATH="$SDCARD_PATH/.system/$PLATFORM" -export CORES_PATH="$SYSTEM_PATH/cores" -export USERDATA_PATH="$SDCARD_PATH/.userdata/$PLATFORM" -export SHARED_USERDATA_PATH="$SDCARD_PATH/.userdata/shared" -export LOGS_PATH="$USERDATA_PATH/logs" -export DATETIME_PATH="$SHARED_USERDATA_PATH/datetime.txt" - -mkdir -p "$USERDATA_PATH" -mkdir -p "$LOGS_PATH" -mkdir -p "$SHARED_USERDATA_PATH/.minui" - -####################################### - -killall -9 power_daemon -killall -9 key_daemon - -####################################### - -export LD_LIBRARY_PATH=$SYSTEM_PATH/lib:$LD_LIBRARY_PATH -export PATH=$SYSTEM_PATH/bin:$PATH - -keymon.elf & - -####################################### - -# init datetime -if [ -f "$DATETIME_PATH" ]; then - DATETIME=`cat "$DATETIME_PATH"` - date +'%F %T' -s "$DATETIME" - DATETIME=`date +'%s'` - date -u -s "@$DATETIME" -fi - -####################################### - -AUTO_PATH=$USERDATA_PATH/auto.sh -if [ -f "$AUTO_PATH" ]; then - "$AUTO_PATH" -fi - -cd $(dirname "$0") - -####################################### - -EXEC_PATH="/tmp/nextui_exec" -NEXT_PATH="/tmp/next" -touch "$EXEC_PATH" && sync -while [ -f $EXEC_PATH ]; do - nextui.elf &> $LOGS_PATH/nextui.txt - echo `date +'%F %T'` > "$DATETIME_PATH" - sync - - if [ -f $NEXT_PATH ]; then - CMD=`cat $NEXT_PATH` - eval $CMD - rm -f $NEXT_PATH - echo `date +'%F %T'` > "$DATETIME_PATH" - sync - fi - - if [ -f "/tmp/poweroff" ]; then - break - fi -done - -poweroff # TODO: not sure this does anything diff --git a/skeleton/_unmaintained/SYSTEM/gkdpixel/system.cfg b/skeleton/_unmaintained/SYSTEM/gkdpixel/system.cfg deleted file mode 100755 index 7c528b3d8..000000000 --- a/skeleton/_unmaintained/SYSTEM/gkdpixel/system.cfg +++ /dev/null @@ -1,6 +0,0 @@ -minarch_screen_scaling = Aspect --minarch_screen_effect = None --minarch_screen_sharpness = Crisp --minarch_prevent_tearing = Lenient --minarch_thread_video = Off --minarch_cpu_speed = Normal diff --git a/skeleton/_unmaintained/SYSTEM/m17/bin/shutdown b/skeleton/_unmaintained/SYSTEM/m17/bin/shutdown deleted file mode 100755 index c95025368..000000000 --- a/skeleton/_unmaintained/SYSTEM/m17/bin/shutdown +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -# NOTE: doesn't actually shutdown because we have a physical power switch - -if [ -n "$DATETIME_PATH" ]; then - echo `date +'%F %T'` > "$DATETIME_PATH" - sync -fi diff --git a/skeleton/_unmaintained/SYSTEM/m17/bin/start_adbd.sh b/skeleton/_unmaintained/SYSTEM/m17/bin/start_adbd.sh deleted file mode 100755 index 1305d39c0..000000000 --- a/skeleton/_unmaintained/SYSTEM/m17/bin/start_adbd.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh - -# taken verbatim from https://github.com/octathorp/m17_tools/blob/master/ADB/usb_enabler.sh - -CONFIG_STRING=adb -PID=0x0006 - -mount -t configfs none /sys/kernel/config -mkdir /sys/kernel/config/usb_gadget/rockchip -m 0770 -echo 0x2207 > /sys/kernel/config/usb_gadget/rockchip/idVendor -echo $PID > /sys/kernel/config/usb_gadget/rockchip/idProduct -mkdir /sys/kernel/config/usb_gadget/rockchip/strings/0x409 -m 0770 -SERIAL=`cat /proc/cpuinfo | grep Serial | awk '{print $3}'` -if [ -z $SERIAL ];then - SERIAL=0123456789ABCDEF -fi -echo $SERIAL > /sys/kernel/config/usb_gadget/rockchip/strings/0x409/serialnumber -echo "rockchip" > /sys/kernel/config/usb_gadget/rockchip/strings/0x409/manufacturer -echo "rk3xxx" > /sys/kernel/config/usb_gadget/rockchip/strings/0x409/product -mkdir /sys/kernel/config/usb_gadget/rockchip/configs/b.1 -m 0770 -mkdir /sys/kernel/config/usb_gadget/rockchip/configs/b.1/strings/0x409 -m 0770 -echo 500 > /sys/kernel/config/usb_gadget/rockchip/configs/b.1/MaxPower -echo \"$CONFIG_STRING\" > /sys/kernel/config/usb_gadget/rockchip/configs/b.1/strings/0x409/configuration - -mkdir /sys/kernel/config/usb_gadget/rockchip/functions/ffs.adb -ln -s /sys/kernel/config/usb_gadget/rockchip/functions/ffs.adb /sys/kernel/config/usb_gadget/rockchip/configs/b.1/ffs.adb - -mkdir -p /dev/usb-ffs/adb -mount -o uid=2000,gid=2000 -t functionfs adb /dev/usb-ffs/adb -export service_adb_tcp_port=5555 -adbd& -sleep 1 - -UDC=`ls /sys/class/udc/| awk '{print $1}'` -echo $UDC > /sys/kernel/config/usb_gadget/rockchip/UDC - diff --git a/skeleton/_unmaintained/SYSTEM/m17/cores/.keep b/skeleton/_unmaintained/SYSTEM/m17/cores/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/SYSTEM/m17/dat/.keep b/skeleton/_unmaintained/SYSTEM/m17/dat/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/SYSTEM/m17/lib/.keep b/skeleton/_unmaintained/SYSTEM/m17/lib/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/FC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/FC.pak/default.cfg deleted file mode 100755 index 90365a9d1..000000000 --- a/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/FC.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ -fceumm_sndquality = High -fceumm_sndvolume = 10 --fceumm_aspect = 8:7 PAR --fceumm_turbo_enable = Player 1 --fceumm_show_adv_system_options = disabled --fceumm_show_adv_sound_options = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Change Disk = NONE:L1 -bind Insert Disk = NONE:R1 -bind Insert Coin = NONE:R2 diff --git a/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/FC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/FC.pak/launch.sh deleted file mode 100755 index 280598bbc..000000000 --- a/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/FC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=fceumm - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/GB.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/GB.pak/default.cfg deleted file mode 100755 index 631f921ed..000000000 --- a/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/GB.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ -minarch_screen_sharpness = Crisp - -gambatte_gb_colorization = internal -gambatte_gb_internal_palette = TWB64 - Pack 1 -gambatte_gb_palette_twb64_1 = TWB64 038 - Pokemon mini Ver. -gambatte_gb_bootloader = disabled --gambatte_audio_resampler = sinc - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Prev. Palette = NONE:L1 -bind Next Palette = NONE:R1 diff --git a/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/GB.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/GB.pak/launch.sh deleted file mode 100755 index 9143f24c9..000000000 --- a/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/GB.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gambatte - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/GBA.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/GBA.pak/default.cfg deleted file mode 100755 index 612de02ae..000000000 --- a/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/GBA.pak/default.cfg +++ /dev/null @@ -1,16 +0,0 @@ -minarch_screen_sharpness = Crisp - --gpsp_save_method = libretro - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 diff --git a/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/GBA.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/GBA.pak/launch.sh deleted file mode 100755 index 5678aaca7..000000000 --- a/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/GBA.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gpsp - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/GBC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/GBC.pak/default.cfg deleted file mode 100755 index feacafef9..000000000 --- a/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/GBC.pak/default.cfg +++ /dev/null @@ -1,17 +0,0 @@ -minarch_screen_sharpness = Crisp - -gambatte_gb_bootloader = disabled --gambatte_audio_resampler = sinc - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Prev. Palette = NONE:L1 -bind Next Palette = NONE:R1 diff --git a/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/GBC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/GBC.pak/launch.sh deleted file mode 100755 index 9143f24c9..000000000 --- a/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/GBC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gambatte - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/MD.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/MD.pak/default.cfg deleted file mode 100755 index af4bc7e8c..000000000 --- a/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/MD.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ -minarch_screen_sharpness = Crisp - --picodrive_sound_rate = 44100 --picodrive_smstype = Auto --picodrive_smsfm = off --picodrive_smsmapper = Auto --picodrive_ggghost = off - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Mode = SELECT -bind Start = START -bind A Button = Y -bind B Button = X:B -bind C Button = A -bind X Button = B:L1 -bind Y Button = L1:X -bind Z Button = R1 diff --git a/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/MD.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/MD.pak/launch.sh deleted file mode 100755 index 81688be79..000000000 --- a/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/MD.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/PS.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/PS.pak/default.cfg deleted file mode 100755 index c413978ea..000000000 --- a/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/PS.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ --minarch_thread_video = Off - --pcsx_rearmed_display_internal_fps = disabled --pcsx_rearmed_show_input_settings = disabled - -minarch_gamepad_type = 1 -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Circle = A -bind Cross = B -bind Triangle = X -bind Square = Y -bind L1 Button = L1 -bind R1 Button = R1 -bind L2 Button = NONE:L2 -bind R2 Button = NONE:R2 diff --git a/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/PS.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/PS.pak/launch.sh deleted file mode 100755 index e3ba5ac06..000000000 --- a/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/PS.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=pcsx_rearmed - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/SFC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/SFC.pak/default.cfg deleted file mode 100755 index 8100f20a1..000000000 --- a/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/SFC.pak/default.cfg +++ /dev/null @@ -1,12 +0,0 @@ -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Y Button = Y -bind X Button = X -bind B Button = B -bind A Button = A -bind L Button = L1 -bind R Button = R1 \ No newline at end of file diff --git a/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/SFC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/SFC.pak/launch.sh deleted file mode 100755 index 44e982862..000000000 --- a/skeleton/_unmaintained/SYSTEM/m17/paks/Emus/SFC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=snes9x2005_plus - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/m17/paks/MinUI.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/m17/paks/MinUI.pak/launch.sh deleted file mode 100755 index a139fcd7f..000000000 --- a/skeleton/_unmaintained/SYSTEM/m17/paks/MinUI.pak/launch.sh +++ /dev/null @@ -1,82 +0,0 @@ -#!/bin/sh -# MiniUI.pak - -####################################### - -export PLATFORM="m17" -export SDCARD_PATH="/sdcard" -export BIOS_PATH="$SDCARD_PATH/Bios" -export SAVES_PATH="$SDCARD_PATH/Saves" -export CHEATS_PATH="$SDCARD_PATH/Cheats" -export SYSTEM_PATH="$SDCARD_PATH/.system/$PLATFORM" -export CORES_PATH="$SYSTEM_PATH/cores" -export USERDATA_PATH="$SDCARD_PATH/.userdata/$PLATFORM" -export SHARED_USERDATA_PATH="$SDCARD_PATH/.userdata/shared" -export LOGS_PATH="$USERDATA_PATH/logs" -export DATETIME_PATH="$SHARED_USERDATA_PATH/datetime.txt" - -mkdir -p "$USERDATA_PATH" -mkdir -p "$LOGS_PATH" -mkdir -p "$SHARED_USERDATA_PATH/.minui" - -####################################### - -echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor -echo performance > /sys/devices/platform/10091000.gpu/devfreq/10091000.gpu/governor - -####################################### - -export LD_LIBRARY_PATH=$SYSTEM_PATH/lib:/usr/lib:$LD_LIBRARY_PATH -export PATH=$SYSTEM_PATH/bin:/usr/bin:$PATH - -start_adbd.sh -keymon.elf & - -####################################### - -# init datetime -if [ -f "$DATETIME_PATH" ]; then - DATETIME=`cat "$DATETIME_PATH"` - date +'%F %T' -s "$DATETIME" - DATETIME=`date +'%s'` - date -u -s "@$DATETIME" -fi - -####################################### - -AUTO_PATH=$USERDATA_PATH/auto.sh -if [ -f "$AUTO_PATH" ]; then - "$AUTO_PATH" -fi - -cd $(dirname "$0") - -####################################### - -EXEC_PATH="/tmp/nextui_exec" -NEXT_PATH="/tmp/next" -touch "$EXEC_PATH" && sync -while [ -f $EXEC_PATH ]; do - nextui.elf &> $LOGS_PATH/nextui.txt - echo `date +'%F %T'` > "$DATETIME_PATH" - sync - - if [ -f $NEXT_PATH ]; then - CMD=`cat $NEXT_PATH` - eval $CMD - rm -f $NEXT_PATH - echo `date +'%F %T'` > "$DATETIME_PATH" - sync - fi - - # physical powerswitch, enter low power mode - if [ -f "/tmp/poweroff" ]; then - rm -f "/tmp/poweroff" - killall keymon.elf - shutdown - # TODO: figure out how to control led? - while :; do - sleep 5 - done - fi -done diff --git a/skeleton/_unmaintained/SYSTEM/m17/system.cfg b/skeleton/_unmaintained/SYSTEM/m17/system.cfg deleted file mode 100755 index f3a85db08..000000000 --- a/skeleton/_unmaintained/SYSTEM/m17/system.cfg +++ /dev/null @@ -1,4 +0,0 @@ --minarch_screen_effect = None --minarch_prevent_tearing = Lenient --minarch_thread_video = Off --minarch_cpu_speed = Normal diff --git a/skeleton/_unmaintained/SYSTEM/magicmini/bin/shutdown b/skeleton/_unmaintained/SYSTEM/magicmini/bin/shutdown deleted file mode 100755 index 0f731a88b..000000000 --- a/skeleton/_unmaintained/SYSTEM/magicmini/bin/shutdown +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -if [ -n "$DATETIME_PATH" ]; then - echo `date +'%F %T'` > "$DATETIME_PATH" - sync -fi - -cat /dev/zero > /dev/fb0 -shutdown now \ No newline at end of file diff --git a/skeleton/_unmaintained/SYSTEM/magicmini/cores/.keep b/skeleton/_unmaintained/SYSTEM/magicmini/cores/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/SYSTEM/magicmini/dat/.keep b/skeleton/_unmaintained/SYSTEM/magicmini/dat/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/SYSTEM/magicmini/lib/.keep b/skeleton/_unmaintained/SYSTEM/magicmini/lib/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/FC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/FC.pak/default.cfg deleted file mode 100644 index 90365a9d1..000000000 --- a/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/FC.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ -fceumm_sndquality = High -fceumm_sndvolume = 10 --fceumm_aspect = 8:7 PAR --fceumm_turbo_enable = Player 1 --fceumm_show_adv_system_options = disabled --fceumm_show_adv_sound_options = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Change Disk = NONE:L1 -bind Insert Disk = NONE:R1 -bind Insert Coin = NONE:R2 diff --git a/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/FC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/FC.pak/launch.sh deleted file mode 100644 index 780ad5456..000000000 --- a/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/FC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=fceumm - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/GB.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/GB.pak/default.cfg deleted file mode 100644 index a5ec62866..000000000 --- a/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/GB.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ -minarch_screen_scaling = Native - -gambatte_gb_colorization = internal -gambatte_gb_internal_palette = TWB64 - Pack 1 -gambatte_gb_palette_twb64_1 = TWB64 038 - Pokemon mini Ver. -gambatte_gb_bootloader = disabled --gambatte_audio_resampler = sinc - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Prev. Palette = NONE:L1 -bind Next Palette = NONE:R1 diff --git a/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/GB.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/GB.pak/launch.sh deleted file mode 100644 index 9b93f4e5d..000000000 --- a/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/GB.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gambatte - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/GBA.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/GBA.pak/default.cfg deleted file mode 100644 index ea76e21f6..000000000 --- a/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/GBA.pak/default.cfg +++ /dev/null @@ -1,14 +0,0 @@ --gpsp_save_method = libretro - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 diff --git a/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/GBA.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/GBA.pak/launch.sh deleted file mode 100644 index 0ed0b8f3f..000000000 --- a/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/GBA.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gpsp - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/GBC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/GBC.pak/default.cfg deleted file mode 100644 index c854f885e..000000000 --- a/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/GBC.pak/default.cfg +++ /dev/null @@ -1,17 +0,0 @@ -minarch_screen_scaling = Native - -gambatte_gb_bootloader = disabled --gambatte_audio_resampler = sinc - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Prev. Palette = NONE:L1 -bind Next Palette = NONE:R1 diff --git a/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/GBC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/GBC.pak/launch.sh deleted file mode 100644 index 9b93f4e5d..000000000 --- a/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/GBC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gambatte - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/MD.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/MD.pak/default.cfg deleted file mode 100644 index dac408932..000000000 --- a/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/MD.pak/default.cfg +++ /dev/null @@ -1,18 +0,0 @@ --picodrive_sound_rate = 44100 --picodrive_smstype = Auto --picodrive_smsfm = off --picodrive_smsmapper = Auto --picodrive_ggghost = off - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Mode = SELECT -bind Start = START -bind A Button = Y -bind B Button = X:B -bind C Button = A -bind X Button = B:L1 -bind Y Button = L1:X -bind Z Button = R1 diff --git a/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/MD.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/MD.pak/launch.sh deleted file mode 100644 index 8ceb019a2..000000000 --- a/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/MD.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/PS.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/PS.pak/default.cfg deleted file mode 100644 index 857e895eb..000000000 --- a/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/PS.pak/default.cfg +++ /dev/null @@ -1,22 +0,0 @@ --minarch_thread_video = Off - --pcsx_rearmed_display_internal_fps = disabled --pcsx_rearmed_show_input_settings = disabled - -pcsx_rearmed_dithering = enabled - -minarch_gamepad_type = 1 -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Circle = A -bind Cross = B -bind Triangle = X -bind Square = Y -bind L1 Button = L1 -bind R1 Button = R1 -bind L2 Button = L2 -bind R2 Button = R2 \ No newline at end of file diff --git a/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/PS.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/PS.pak/launch.sh deleted file mode 100644 index d15d0b984..000000000 --- a/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/PS.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=pcsx_rearmed - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/SFC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/SFC.pak/default.cfg deleted file mode 100644 index 8100f20a1..000000000 --- a/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/SFC.pak/default.cfg +++ /dev/null @@ -1,12 +0,0 @@ -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Y Button = Y -bind X Button = X -bind B Button = B -bind A Button = A -bind L Button = L1 -bind R Button = R1 \ No newline at end of file diff --git a/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/SFC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/SFC.pak/launch.sh deleted file mode 100644 index 97dd502a0..000000000 --- a/skeleton/_unmaintained/SYSTEM/magicmini/paks/Emus/SFC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=snes9x2005_plus - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/magicmini/paks/MinUI.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/magicmini/paks/MinUI.pak/launch.sh deleted file mode 100755 index f5d6f4633..000000000 --- a/skeleton/_unmaintained/SYSTEM/magicmini/paks/MinUI.pak/launch.sh +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/sh - -# dmesg > /storage/TF1/dmesg.txt - -export PLATFORM="magicmini" -export SDCARD_PATH="/storage/TF2" -export BIOS_PATH="$SDCARD_PATH/Bios" -export SAVES_PATH="$SDCARD_PATH/Saves" -export CHEATS_PATH="$SDCARD_PATH/Cheats" -export SYSTEM_PATH="$SDCARD_PATH/.system/$PLATFORM" -export CORES_PATH="$SYSTEM_PATH/cores" -export USERDATA_PATH="$SDCARD_PATH/.userdata/$PLATFORM" -export SHARED_USERDATA_PATH="$SDCARD_PATH/.userdata/shared" -export LOGS_PATH="$USERDATA_PATH/logs" -export DATETIME_PATH="$SHARED_USERDATA_PATH/datetime.txt" - -export PATH=$SYSTEM_PATH/bin:$PATH -export LD_LIBRARY_PATH=$SYSTEM_PATH/lib:$LD_LIBRARY_PATH - -export SDL_AUDIODRIVER=alsa -amixer cset name='Playback Path' SPK # or HP, seems to switch automatically - -cat /dev/zero > /dev/fb0 - -export CPU_PATH=/sys/devices/system/cpu/cpufreq/policy0/scaling_setspeed -export CPU_SPEED_PERF=1608000 -echo performance > /sys/devices/platform/ff400000.gpu/devfreq/ff400000.gpu/governor -echo performance > /sys/devices/platform/dmc/devfreq/dmc/governor -echo userspace > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor -echo $CPU_SPEED_PERF > $CPU_PATH - -####################################### - -keymon.elf & # &> $SDCARD_PATH/keymon.txt & - -####################################### - -mkdir -p "$LOGS_PATH" -mkdir -p "$SHARED_USERDATA_PATH/.minui" -AUTO_PATH=$USERDATA_PATH/auto.sh -if [ -f "$AUTO_PATH" ]; then - "$AUTO_PATH" # &> $LOGS_PATH/auto.txt -fi - -cd $(dirname "$0") - -####################################### - -EXEC_PATH=/tmp/nextui_exec -NEXT_PATH="/tmp/next" -touch "$EXEC_PATH" && sync -while [ -f "$EXEC_PATH" ]; do - echo $CPU_SPEED_PERF > $CPU_PATH - nextui.elf &> $LOGS_PATH/nextui.txt - echo `date +'%F %T'` > "$DATETIME_PATH" - sync - - if [ -f $NEXT_PATH ]; then - echo $CPU_SPEED_PERF > $CPU_PATH - CMD=`cat $NEXT_PATH` - eval $CMD - rm -f $NEXT_PATH - echo `date +'%F %T'` > "$DATETIME_PATH" - sync - fi -done diff --git a/skeleton/_unmaintained/SYSTEM/magicmini/system.cfg b/skeleton/_unmaintained/SYSTEM/magicmini/system.cfg deleted file mode 100644 index 22516f35b..000000000 --- a/skeleton/_unmaintained/SYSTEM/magicmini/system.cfg +++ /dev/null @@ -1,2 +0,0 @@ -minarch_screen_sharpness = Crisp --minarch_prevent_tearing = Lenient diff --git a/skeleton/_unmaintained/SYSTEM/miyoomini/bin/needs-swap b/skeleton/_unmaintained/SYSTEM/miyoomini/bin/needs-swap deleted file mode 100755 index d9069c2cd..000000000 --- a/skeleton/_unmaintained/SYSTEM/miyoomini/bin/needs-swap +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - -SWAP_PATH=$USERDATA_PATH/swapfile -if [ ! -f "$SWAP_PATH" ]; then - say "Creating swap file" - dd if="/dev/zero" of="$SWAP_PATH" bs=1M count=128 - chmod 600 "$SWAP_PATH" - mkswap "$SWAP_PATH" -fi -swapon "$SWAP_PATH" - -touch "/tmp/using-swap" \ No newline at end of file diff --git a/skeleton/_unmaintained/SYSTEM/miyoomini/bin/shutdown b/skeleton/_unmaintained/SYSTEM/miyoomini/bin/shutdown deleted file mode 100755 index c72a0f3d5..000000000 --- a/skeleton/_unmaintained/SYSTEM/miyoomini/bin/shutdown +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -if [ -n "$DATETIME_PATH" ]; then - echo `date +'%F %T'` > "$DATETIME_PATH" -fi - -if $IS_PLUS; then - sync && poweroff -else - sync && reboot && sleep 10 -fi \ No newline at end of file diff --git a/skeleton/_unmaintained/SYSTEM/miyoomini/cores/.keep b/skeleton/_unmaintained/SYSTEM/miyoomini/cores/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/SYSTEM/miyoomini/dat/image1.jpg b/skeleton/_unmaintained/SYSTEM/miyoomini/dat/image1.jpg deleted file mode 100755 index a529c7da5577fd458d6d5fe93b588def6f725676..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8448 zcmeI1c~DbX_QxM!v#NmIvWOZHT!0`Vo3cg02HCqo_O00=0V1*q0YZ-owm`5!KnR9G zIwC><2@tk`4M;#_CxkVM!GtYg4SSMde*LTIsi~T(;aBtD&r|iPZr$aadp`GjU)}p2 zZBq}T-CMfjHKUe+HD6!v32;k#CBp@g#@IM3i_yrDqBPb*+A}aZ)(@g%@x8EI? zqCAsTKPxR$=X^!+nu6p%`TfHQZyY$hKbT)qKoWoe4DO$Czm~od_)6d_fv*G(PC(qR zXbtml2!92ZPq{hSAk}8;WMd;xv>;2wYv^a%h~DivuO{I0q&d&|wUvmMjNO)r`j&ud zOU+UVlGXRobE2^~eUb-cvLOg$HHNc`U*`d8j6EJe-~q)vpo(kLwY7(Yv`uf_KNgJ& z@2^Ms$A@DB(K!aALEW2vNE5Cu z54d!LKVeDS8uVS<*+tCR$O5St|2OSrP0uKeNqR{7-mWyfd<`AP17weB0bTKUovDhq4T4xq!qxcROl&)IYkF|w;F1; zt>ADqE$385RmNv0B+bED-u70jWOks5#3O}dvgz1nTWo@KzydYb*=d(n<{9Ko4s1A_Wcl$|Hyhj9Li%QUL)M0)U47e_ky~*jLq<6|CXOW2V?@1m z`~Bi~K{g&sb~xMP%0G5>z+_CGAAaakeLu7F!1?j>0E1LygiQv#G|}@DkO+xmj4v?) z=1xio9@#{|;?A{g6X#pnDiN5omLD&#>~yQl@PO|-9I;v!;H+YBOY7i(y3VTU{`Ofo zm9c;jB%Wj90>+G_(w=ZSr;T zfMFg$MV9V>8e0;PDagk>0M0?KCZsPGlx*_=@#J<{69Awsu5$*5Ed$p<&Ed@GHT*hCSm2v!#L4y4NFHFxmYzEvID}Sx9oVcj zC*>%a?McR>X7z*u`ur|-X(IbXqowuV_XZV;x2hMbk@n6UO?u0JGybDt;q&x%h{P5W zwWk-<6VA!`KrFy|Z@Sam8tXe4%x!7KcR`t~*d&m8fPvVgYCJ__=<;xA`Ni8AI5&6V zR9S*13mPYo^Gf$2;s(bUaUrMqY&7V!UN#v$tEZEMhG@N;L-cmVglCRkijj7G7aAUv zm*k^?uqCoWn=^Ci&X2VT$LDPvvM+re907?&4Rht)-wI%Cnl)~boFe+HQNNm}UAw#M zkuvl0*Z43IKaNWsE50%;b>mX%8uH7Ds7(Xy)gUiWt7M5z+n%?u!9mFa(%XwZyD#E0 zBe4@BVqIsD>9_*9K$!rZ)R?^1Z(LdZn$ zNR$1fR!?Y6kJ6R;G?-D>wn*}%hLlvMl_){Vg=_J`D{!(8tRQMP6W9t*W+dt!OFWA3 z*gitB?+i^q=dX6_q3Wk1tzhqoZ9XHjlS2h6$s>dhIq6RE#_Gr*@IWctuhO@k4o$0G zGmtNxmyr@RFfl)k`ancDHj` zt++GFZqU(Wyq{*{*3QvJKtFu&9JkPfPK*W1UW&;p3eoR>pxlST3CAH7Z+w$Tg!m*Z zy!P3&u{DfFJSVw^PWab+emPwZi!2Z7%K89vIc?GDW;p$Mky3LXYv1 zu`N(Ak=#nSCs241VAL!VXvx+HG=bRZf3z4PWtT5&|VUfpM1(Aim668Ix~ zCky&18WUC+=9^mHuO{4P0#WSVJc9eXZI;`{+Q7yK z?n)hfzQ5=kQM5iD?ceFA;jH{LWX?h{)1gA&FT=?~yj3Dm|EdA$>fDqHiggv0+}R+t z(yhZuz`E3(V&sS9azJ6N_7x_GSaz74HvY*w`kNXRS8|>iy~yKMkK#Z!a`Nnttii zGH+$m{}mhPU$_b!)rDBkxu=A6uNyY@6Hvu1i^rAh```wk;Jzg}R47jLifeyq&RA`5 zlATsYi3#;-m6;ZFt;6};gUUU5VS%>918YM^WIkXvh9QlWLU-&)XG-Z$T*GbzmA{G7 zQ#&)dVMRLff>rx$BCctV@xnJ;*S|R6(PZfU0*q8=zmG%da-Tn(86iX#hB#bF{&}6e zet&hB9O`-I{EF>F{_SLxZgxFB^vNtDl8)1cDKr=dqcVSk9vl5hTcl!Rim(Mz5_6&^ z{QkH|&WTG#z_;fT?vOhHfs0M5D?*hq3p1PNS1$ZzfTGOyAZ34`X}xYt@O~-eKyrn- zlp~_Y@Mu97DoH5@_6vor>d)P2QpJU`=IscnPcJ&)G@sIi@)FLlc>sS?!Geckbe_u> z!&1_ftvLTK*B`pceb6zLkW7c)Lw9<^J>O4`dRK(LkrTw?ojiYd*n`DR=|)Rr5Jk1H znEb+&zy7yobhvATD5XC<#<9_$W=1)&kZKvR81ujow4%0U4do0)bLo@5sb%3{6~Zr@ z;Hd}4ew=eXs!OM8eD>?QUDxS4)-mY%zOoPqZcaH3T{vC*3}n_l35TG&4Dbr#)2b-F z^A40J!LbpV`Yo0fgKyA&ECM{gZg4RIhfoL)lMU1GEt<fv1DCzFh5puhDG_R3?+B4bEL52m}3 z#{+((*T-^y>M4$h_tpx)fk!`ZvYG}R3q@-JNWQP!okq}XCbX6BLn^@6vII-#0g-#M z+qpa-8FPb=h2jCMmi&+4kIQSM{=h>3e0Q9-|1v}hCio+#8BeayN)E@gTv#V8a`A?Q z_>m+HdGu^vpVZscQph;7#B*}3*OQhk+J9$UPyo`PX1;&P?pD1VzPV|N-1O{)XT!H*XtSF92VN0iHe|_gQI7KMTyy$V z3W`P839zCgq;urBDFhgy`nUI=!ktQ&BrBGkQv%!Afg`o0VF8*7=bV*Y-EAM5+n+13 z4*K%w$ITa{*E%X}j}^#q>KiFt`kNW;LcfY|i1J3Bc z!X@+*i%jwrG`)oTTx!gGvq3b?AtQ-B?;~S~4;<6!+VupxIdo6>a>@NK{q36|MK4t2 z1K;{tgw*NkrgY2~dAP^(pbO-P)SCFD)sdzwRhB}fcd5lPE@(?&EO#Dq#G;4|x1?qj zJk$sMnB-cwHFY>`QvMvlm~v;`Zy|qETI?}f#m12Qn|ENac2u=uF&ushsp0}pgSE74 zqFIkitqJ87`9p&x=bXJDX}62Cu6@Bc-7fkpl)etLOZ7|j5}6$-*32~C^UHJkBiRG1 zLTGRY61eD|vSn=$T^7+?d`ise&7dZn4ML1Zr+@0vkY3@8y_!e1kGT~uv)-Wg1~_73 zkb&x=6&`Tzs=&rI(65HqmxV)*Eu$Et_sWQ30@}D1i>?O$xnArPJGU@Qq-Lt&L=sH= zNT!gCJ9+=2+r)u_xOg6rvp2AnOag$@Xv?YS)8REg=`taYX8zWpR4Ca#nlJpE|yo+z?{)a(+=HgiKBON9InL~S`YpP(Nal?9iAUTuVe?_ zJkl3A*BjBuY*IH!#A6%c@bSD*sICGW?LmIU=8<{bBWz?bi(3r*YftuiY^cc-yQ>|b$ tJlb(AuEU!38&b~E%;>Hq)$ diff --git a/skeleton/_unmaintained/SYSTEM/miyoomini/lib/.keep b/skeleton/_unmaintained/SYSTEM/miyoomini/lib/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/FC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/FC.pak/default.cfg deleted file mode 100644 index 90365a9d1..000000000 --- a/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/FC.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ -fceumm_sndquality = High -fceumm_sndvolume = 10 --fceumm_aspect = 8:7 PAR --fceumm_turbo_enable = Player 1 --fceumm_show_adv_system_options = disabled --fceumm_show_adv_sound_options = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Change Disk = NONE:L1 -bind Insert Disk = NONE:R1 -bind Insert Coin = NONE:R2 diff --git a/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/FC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/FC.pak/launch.sh deleted file mode 100755 index 1c82e1bf9..000000000 --- a/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/FC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=fceumm - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -nice -20 minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/GB.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/GB.pak/default.cfg deleted file mode 100644 index a5ec62866..000000000 --- a/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/GB.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ -minarch_screen_scaling = Native - -gambatte_gb_colorization = internal -gambatte_gb_internal_palette = TWB64 - Pack 1 -gambatte_gb_palette_twb64_1 = TWB64 038 - Pokemon mini Ver. -gambatte_gb_bootloader = disabled --gambatte_audio_resampler = sinc - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Prev. Palette = NONE:L1 -bind Next Palette = NONE:R1 diff --git a/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/GB.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/GB.pak/launch.sh deleted file mode 100755 index 74bda875b..000000000 --- a/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/GB.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gambatte - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -nice -20 minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/GBA.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/GBA.pak/default.cfg deleted file mode 100644 index ea76e21f6..000000000 --- a/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/GBA.pak/default.cfg +++ /dev/null @@ -1,14 +0,0 @@ --gpsp_save_method = libretro - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 diff --git a/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/GBA.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/GBA.pak/launch.sh deleted file mode 100755 index 4ad966e35..000000000 --- a/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/GBA.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gpsp - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -nice -20 minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/GBC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/GBC.pak/default.cfg deleted file mode 100644 index c854f885e..000000000 --- a/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/GBC.pak/default.cfg +++ /dev/null @@ -1,17 +0,0 @@ -minarch_screen_scaling = Native - -gambatte_gb_bootloader = disabled --gambatte_audio_resampler = sinc - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Prev. Palette = NONE:L1 -bind Next Palette = NONE:R1 diff --git a/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/GBC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/GBC.pak/launch.sh deleted file mode 100755 index 74bda875b..000000000 --- a/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/GBC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gambatte - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -nice -20 minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/MD.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/MD.pak/default.cfg deleted file mode 100644 index dac408932..000000000 --- a/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/MD.pak/default.cfg +++ /dev/null @@ -1,18 +0,0 @@ --picodrive_sound_rate = 44100 --picodrive_smstype = Auto --picodrive_smsfm = off --picodrive_smsmapper = Auto --picodrive_ggghost = off - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Mode = SELECT -bind Start = START -bind A Button = Y -bind B Button = X:B -bind C Button = A -bind X Button = B:L1 -bind Y Button = L1:X -bind Z Button = R1 diff --git a/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/MD.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/MD.pak/launch.sh deleted file mode 100755 index 0fdffa382..000000000 --- a/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/MD.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -nice -20 minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/PS.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/PS.pak/default.cfg deleted file mode 100644 index 54a1e8c11..000000000 --- a/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/PS.pak/default.cfg +++ /dev/null @@ -1,21 +0,0 @@ --minarch_thread_video = Off - --pcsx_rearmed_display_internal_fps = disabled --pcsx_rearmed_show_input_settings = disabled - -pcsx_rearmed_dithering = enabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Circle = A -bind Cross = B -bind Triangle = X -bind Square = Y -bind L1 Button = L1 -bind R1 Button = R1 -bind L2 Button = L2 -bind R2 Button = R2 \ No newline at end of file diff --git a/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/PS.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/PS.pak/launch.sh deleted file mode 100755 index 08aced005..000000000 --- a/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/PS.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=pcsx_rearmed - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -nice -20 minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/SFC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/SFC.pak/default.cfg deleted file mode 100644 index 8100f20a1..000000000 --- a/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/SFC.pak/default.cfg +++ /dev/null @@ -1,12 +0,0 @@ -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Y Button = Y -bind X Button = X -bind B Button = B -bind A Button = A -bind L Button = L1 -bind R Button = R1 \ No newline at end of file diff --git a/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/SFC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/SFC.pak/launch.sh deleted file mode 100755 index a06b27ad9..000000000 --- a/skeleton/_unmaintained/SYSTEM/miyoomini/paks/Emus/SFC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=snes9x2005_plus - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -nice -20 minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/miyoomini/paks/MinUI.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/miyoomini/paks/MinUI.pak/launch.sh deleted file mode 100755 index fb441fc7d..000000000 --- a/skeleton/_unmaintained/SYSTEM/miyoomini/paks/MinUI.pak/launch.sh +++ /dev/null @@ -1,147 +0,0 @@ -#!/bin/sh -# MiniUI.pak - -if [ -z "$LCD_INIT" ]; then - # an update may have already initilized the LCD - /mnt/SDCARD/.system/miyoomini/bin/blank.elf - - # init backlight - echo 0 > /sys/class/pwm/pwmchip0/export - echo 800 > /sys/class/pwm/pwmchip0/pwm0/period - echo 6 > /sys/class/pwm/pwmchip0/pwm0/duty_cycle - echo 1 > /sys/class/pwm/pwmchip0/pwm0/enable - - # init lcd - cat /proc/ls - sleep 0.5 -fi - -# init charger detection -if [ ! -f /sys/devices/gpiochip0/gpio/gpio59/direction ]; then - echo 59 > /sys/class/gpio/export - echo in > /sys/devices/gpiochip0/gpio/gpio59/direction -fi - - -####################################### - -if [ -f /customer/app/axp_test ]; then - IS_PLUS=true -else - IS_PLUS=false -fi -export IS_PLUS -export PLATFORM="miyoomini" -export SDCARD_PATH="/mnt/SDCARD" -export BIOS_PATH="$SDCARD_PATH/Bios" -export SAVES_PATH="$SDCARD_PATH/Saves" -export CHEATS_PATH="$SDCARD_PATH/Cheats" -export SYSTEM_PATH="$SDCARD_PATH/.system/$PLATFORM" -export CORES_PATH="$SYSTEM_PATH/cores" -export USERDATA_PATH="$SDCARD_PATH/.userdata/$PLATFORM" -export SHARED_USERDATA_PATH="$SDCARD_PATH/.userdata/shared" -export LOGS_PATH="$USERDATA_PATH/logs" -export DATETIME_PATH="$SHARED_USERDATA_PATH/datetime.txt" # used by bin/shutdown - -mkdir -p "$USERDATA_PATH" -mkdir -p "$LOGS_PATH" -mkdir -p "$SHARED_USERDATA_PATH/.minui" - -####################################### - -export CPU_SPEED_MENU=504000 -export CPU_SPEED_GAME=1296000 -export CPU_SPEED_PERF=1488000 -echo userspace > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor -overclock.elf $CPU_SPEED_PERF - -MIYOO_VERSION=`/etc/fw_printenv miyoo_version` -export MIYOO_VERSION=${MIYOO_VERSION#miyoo_version=} - -####################################### - -# killall tee # NOTE: killing tee is somehow responsible for audioserver crashes -rm -f "$SDCARD_PATH/update.log" - -####################################### - -export LD_LIBRARY_PATH=$SYSTEM_PATH/lib:$LD_LIBRARY_PATH -export PATH=$SYSTEM_PATH/bin:$PATH - -####################################### - -if $IS_PLUS; then - /customer/app/audioserver -60 & # &> $SDCARD_PATH/audioserver.txt & - export LD_PRELOAD=/customer/lib/libpadsp.so -else - if [ -f /customer/lib/libpadsp.so ]; then - LD_PRELOAD=as_preload.so audioserver.mod & - export LD_PRELOAD=libpadsp.so - fi -fi - -####################################### - -lumon.elf & # adjust lcd luma and saturation - -if $IS_PLUS; then - CHARGING=`/customer/app/axp_test | awk -F'[,: {}]+' '{print $7}'` - if [ "$CHARGING" == "3" ]; then - batmon.elf # &> /mnt/SDCARD/batmon.txt - fi -else - CHARGING=`cat /sys/devices/gpiochip0/gpio/gpio59/value` - if [ "$CHARGING" == "1" ]; then - batmon.elf # &> /mnt/SDCARD/batmon.txt - fi -fi - -keymon.elf & # &> /mnt/SDCARD/keymon.txt & - -####################################### - -# init datetime -if [ -f "$DATETIME_PATH" ] && [ ! -f "$USERDATA_PATH/enable-rtc" ]; then - DATETIME=`cat "$DATETIME_PATH"` - date +'%F %T' -s "$DATETIME" - DATETIME=`date +'%s'` - date -u -s "@$DATETIME" -fi - -####################################### - -AUTO_PATH=$USERDATA_PATH/auto.sh -if [ -f "$AUTO_PATH" ]; then - "$AUTO_PATH" -fi - -cd $(dirname "$0") - -####################################### - -EXEC_PATH=/tmp/nextui_exec -NEXT_PATH="/tmp/next" -touch "$EXEC_PATH" && sync -while [ -f "$EXEC_PATH" ]; do - overclock.elf $CPU_SPEED_PERF - nextui.elf &> $LOGS_PATH/nextui.txt - - echo `date +'%F %T'` > "$DATETIME_PATH" - sync - - if [ -f $NEXT_PATH ]; then - CMD=`cat $NEXT_PATH` - eval $CMD - rm -f $NEXT_PATH - if [ -f "/tmp/using-swap" ]; then - swapoff $USERDATA_PATH/swapfile - rm -f "/tmp/using-swap" - fi - - echo `date +'%F %T'` > "$DATETIME_PATH" - overclock.elf $CPU_SPEED_PERF - sync - fi -done - -shutdown # just in case diff --git a/skeleton/_unmaintained/SYSTEM/miyoomini/system.cfg b/skeleton/_unmaintained/SYSTEM/miyoomini/system.cfg deleted file mode 100644 index 36730954f..000000000 --- a/skeleton/_unmaintained/SYSTEM/miyoomini/system.cfg +++ /dev/null @@ -1,3 +0,0 @@ --minarch_screen_sharpness = Crisp --minarch_prevent_tearing = Lenient --minarch_thread_video = Off diff --git a/skeleton/_unmaintained/SYSTEM/my282/bin/setterm b/skeleton/_unmaintained/SYSTEM/my282/bin/setterm deleted file mode 100755 index 97983f35f..000000000 --- a/skeleton/_unmaintained/SYSTEM/my282/bin/setterm +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -# generates unnecessary errors when missing -exit 0 diff --git a/skeleton/_unmaintained/SYSTEM/my282/bin/shutdown b/skeleton/_unmaintained/SYSTEM/my282/bin/shutdown deleted file mode 100755 index 46ebe7c2f..000000000 --- a/skeleton/_unmaintained/SYSTEM/my282/bin/shutdown +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - -if [ -n "$DATETIME_PATH" ]; then - echo `date +'%F %T'` > "$DATETIME_PATH" - sync -fi - -cat /dev/zero > /dev/fb0 -poweroff -# echo s > /proc/sysrq-trigger -# echo u > /proc/sysrq-trigger -# echo o > /proc/sysrq-trigger diff --git a/skeleton/_unmaintained/SYSTEM/my282/cores/.keep b/skeleton/_unmaintained/SYSTEM/my282/cores/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/SYSTEM/my282/dat/.keep b/skeleton/_unmaintained/SYSTEM/my282/dat/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/SYSTEM/my282/lib/.keep b/skeleton/_unmaintained/SYSTEM/my282/lib/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/FC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/FC.pak/default.cfg deleted file mode 100644 index 90365a9d1..000000000 --- a/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/FC.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ -fceumm_sndquality = High -fceumm_sndvolume = 10 --fceumm_aspect = 8:7 PAR --fceumm_turbo_enable = Player 1 --fceumm_show_adv_system_options = disabled --fceumm_show_adv_sound_options = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Change Disk = NONE:L1 -bind Insert Disk = NONE:R1 -bind Insert Coin = NONE:R2 diff --git a/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/FC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/FC.pak/launch.sh deleted file mode 100644 index 780ad5456..000000000 --- a/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/FC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=fceumm - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/GB.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/GB.pak/default.cfg deleted file mode 100644 index a5ec62866..000000000 --- a/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/GB.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ -minarch_screen_scaling = Native - -gambatte_gb_colorization = internal -gambatte_gb_internal_palette = TWB64 - Pack 1 -gambatte_gb_palette_twb64_1 = TWB64 038 - Pokemon mini Ver. -gambatte_gb_bootloader = disabled --gambatte_audio_resampler = sinc - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Prev. Palette = NONE:L1 -bind Next Palette = NONE:R1 diff --git a/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/GB.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/GB.pak/launch.sh deleted file mode 100644 index 9b93f4e5d..000000000 --- a/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/GB.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gambatte - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/GBA.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/GBA.pak/default.cfg deleted file mode 100644 index ea76e21f6..000000000 --- a/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/GBA.pak/default.cfg +++ /dev/null @@ -1,14 +0,0 @@ --gpsp_save_method = libretro - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 diff --git a/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/GBA.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/GBA.pak/launch.sh deleted file mode 100644 index 0ed0b8f3f..000000000 --- a/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/GBA.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gpsp - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/GBC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/GBC.pak/default.cfg deleted file mode 100644 index c854f885e..000000000 --- a/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/GBC.pak/default.cfg +++ /dev/null @@ -1,17 +0,0 @@ -minarch_screen_scaling = Native - -gambatte_gb_bootloader = disabled --gambatte_audio_resampler = sinc - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Prev. Palette = NONE:L1 -bind Next Palette = NONE:R1 diff --git a/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/GBC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/GBC.pak/launch.sh deleted file mode 100644 index 9b93f4e5d..000000000 --- a/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/GBC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gambatte - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/MD.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/MD.pak/default.cfg deleted file mode 100644 index dac408932..000000000 --- a/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/MD.pak/default.cfg +++ /dev/null @@ -1,18 +0,0 @@ --picodrive_sound_rate = 44100 --picodrive_smstype = Auto --picodrive_smsfm = off --picodrive_smsmapper = Auto --picodrive_ggghost = off - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Mode = SELECT -bind Start = START -bind A Button = Y -bind B Button = X:B -bind C Button = A -bind X Button = B:L1 -bind Y Button = L1:X -bind Z Button = R1 diff --git a/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/MD.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/MD.pak/launch.sh deleted file mode 100644 index 8ceb019a2..000000000 --- a/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/MD.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/PS.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/PS.pak/default.cfg deleted file mode 100644 index 857e895eb..000000000 --- a/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/PS.pak/default.cfg +++ /dev/null @@ -1,22 +0,0 @@ --minarch_thread_video = Off - --pcsx_rearmed_display_internal_fps = disabled --pcsx_rearmed_show_input_settings = disabled - -pcsx_rearmed_dithering = enabled - -minarch_gamepad_type = 1 -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Circle = A -bind Cross = B -bind Triangle = X -bind Square = Y -bind L1 Button = L1 -bind R1 Button = R1 -bind L2 Button = L2 -bind R2 Button = R2 \ No newline at end of file diff --git a/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/PS.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/PS.pak/launch.sh deleted file mode 100644 index d15d0b984..000000000 --- a/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/PS.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=pcsx_rearmed - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/SFC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/SFC.pak/default.cfg deleted file mode 100644 index 8100f20a1..000000000 --- a/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/SFC.pak/default.cfg +++ /dev/null @@ -1,12 +0,0 @@ -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Y Button = Y -bind X Button = X -bind B Button = B -bind A Button = A -bind L Button = L1 -bind R Button = R1 \ No newline at end of file diff --git a/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/SFC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/SFC.pak/launch.sh deleted file mode 100644 index 97dd502a0..000000000 --- a/skeleton/_unmaintained/SYSTEM/my282/paks/Emus/SFC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=snes9x2005_plus - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/my282/paks/MinUI.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/my282/paks/MinUI.pak/launch.sh deleted file mode 100755 index f41aa5b98..000000000 --- a/skeleton/_unmaintained/SYSTEM/my282/paks/MinUI.pak/launch.sh +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/sh - -export PLATFORM="my282" -export SDCARD_PATH="/mnt/SDCARD" -export BIOS_PATH="$SDCARD_PATH/Bios" -export SAVES_PATH="$SDCARD_PATH/Saves" -export CHEATS_PATH="$SDCARD_PATH/Cheats" -export SYSTEM_PATH="$SDCARD_PATH/.system/$PLATFORM" -export CORES_PATH="$SYSTEM_PATH/cores" -export USERDATA_PATH="$SDCARD_PATH/.userdata/$PLATFORM" -export SHARED_USERDATA_PATH="$SDCARD_PATH/.userdata/shared" -export LOGS_PATH="$USERDATA_PATH/logs" -export DATETIME_PATH="$SHARED_USERDATA_PATH/datetime.txt" - -####################################### - -export PATH=$SYSTEM_PATH/bin:$PATH -export LD_LIBRARY_PATH=$SYSTEM_PATH/lib:$LD_LIBRARY_PATH - -####################################### - -reclock() -{ - overclock.elf userspace 2 1344 384 1080 0 -} - -echo 0 > /sys/class/leds/led1/brightness -reclock - -killall -9 tee -rm -f "$SDCARD_PATH/update.log" -while :; do - killall -9 wpa_supplicant - killall -9 MtpDaemon - ifconfig wlan0 down - sleep 2 -done & - -####################################### - -keymon.elf & #> $LOGS_PATH/keymon.txt 2>&1 & - -####################################### - -mkdir -p "$LOGS_PATH" -mkdir -p "$SHARED_USERDATA_PATH/.minui" -AUTO_PATH="$USERDATA_PATH/auto.sh" -if [ -f "$AUTO_PATH" ]; then - "$AUTO_PATH" # > $LOGS_PATH/auto.txt 2>&1 -fi - -cd $(dirname "$0") - -####################################### - -EXEC_PATH="/tmp/nextui_exec" -NEXT_PATH="/tmp/next" -touch "$EXEC_PATH" && sync -while [ -f "$EXEC_PATH" ]; do - nextui.elf > $LOGS_PATH/nextui.txt 2>&1 - reclock - echo `date +'%F %T'` > "$DATETIME_PATH" - sync - - if [ -f $NEXT_PATH ]; then - CMD=`cat $NEXT_PATH` - eval $CMD - rm -f $NEXT_PATH - reclock - echo `date +'%F %T'` > "$DATETIME_PATH" - sync - fi -done - -shutdown diff --git a/skeleton/_unmaintained/SYSTEM/my282/system.cfg b/skeleton/_unmaintained/SYSTEM/my282/system.cfg deleted file mode 100644 index 7685ca30b..000000000 --- a/skeleton/_unmaintained/SYSTEM/my282/system.cfg +++ /dev/null @@ -1,3 +0,0 @@ -minarch_screen_sharpness = Crisp --minarch_prevent_tearing = Lenient -minarch_cpu_speed = Normal diff --git a/skeleton/_unmaintained/SYSTEM/my355/bin/shutdown b/skeleton/_unmaintained/SYSTEM/my355/bin/shutdown deleted file mode 100755 index a5a5d03a9..000000000 --- a/skeleton/_unmaintained/SYSTEM/my355/bin/shutdown +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh - -if [ -n "$DATETIME_PATH" ]; then - echo `date +'%F %T'` > "$DATETIME_PATH" - sync -fi - -cat /dev/zero > /dev/fb0 -poweroff - -while :; do - sleep 5 -done - -# echo s > /proc/sysrq-trigger -# echo u > /proc/sysrq-trigger -# echo o > /proc/sysrq-trigger diff --git a/skeleton/_unmaintained/SYSTEM/my355/cores/.keep b/skeleton/_unmaintained/SYSTEM/my355/cores/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/SYSTEM/my355/dat/.keep b/skeleton/_unmaintained/SYSTEM/my355/dat/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/SYSTEM/my355/lib/.keep b/skeleton/_unmaintained/SYSTEM/my355/lib/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/FC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/FC.pak/default.cfg deleted file mode 100755 index 90365a9d1..000000000 --- a/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/FC.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ -fceumm_sndquality = High -fceumm_sndvolume = 10 --fceumm_aspect = 8:7 PAR --fceumm_turbo_enable = Player 1 --fceumm_show_adv_system_options = disabled --fceumm_show_adv_sound_options = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Change Disk = NONE:L1 -bind Insert Disk = NONE:R1 -bind Insert Coin = NONE:R2 diff --git a/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/FC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/FC.pak/launch.sh deleted file mode 100755 index 780ad5456..000000000 --- a/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/FC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=fceumm - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/GB.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/GB.pak/default.cfg deleted file mode 100755 index a5ec62866..000000000 --- a/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/GB.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ -minarch_screen_scaling = Native - -gambatte_gb_colorization = internal -gambatte_gb_internal_palette = TWB64 - Pack 1 -gambatte_gb_palette_twb64_1 = TWB64 038 - Pokemon mini Ver. -gambatte_gb_bootloader = disabled --gambatte_audio_resampler = sinc - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Prev. Palette = NONE:L1 -bind Next Palette = NONE:R1 diff --git a/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/GB.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/GB.pak/launch.sh deleted file mode 100755 index 9b93f4e5d..000000000 --- a/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/GB.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gambatte - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/GBA.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/GBA.pak/default.cfg deleted file mode 100755 index ea76e21f6..000000000 --- a/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/GBA.pak/default.cfg +++ /dev/null @@ -1,14 +0,0 @@ --gpsp_save_method = libretro - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 diff --git a/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/GBA.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/GBA.pak/launch.sh deleted file mode 100755 index 0ed0b8f3f..000000000 --- a/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/GBA.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gpsp - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/GBC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/GBC.pak/default.cfg deleted file mode 100755 index c854f885e..000000000 --- a/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/GBC.pak/default.cfg +++ /dev/null @@ -1,17 +0,0 @@ -minarch_screen_scaling = Native - -gambatte_gb_bootloader = disabled --gambatte_audio_resampler = sinc - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Prev. Palette = NONE:L1 -bind Next Palette = NONE:R1 diff --git a/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/GBC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/GBC.pak/launch.sh deleted file mode 100755 index 9b93f4e5d..000000000 --- a/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/GBC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gambatte - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/MD.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/MD.pak/default.cfg deleted file mode 100755 index dac408932..000000000 --- a/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/MD.pak/default.cfg +++ /dev/null @@ -1,18 +0,0 @@ --picodrive_sound_rate = 44100 --picodrive_smstype = Auto --picodrive_smsfm = off --picodrive_smsmapper = Auto --picodrive_ggghost = off - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Mode = SELECT -bind Start = START -bind A Button = Y -bind B Button = X:B -bind C Button = A -bind X Button = B:L1 -bind Y Button = L1:X -bind Z Button = R1 diff --git a/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/MD.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/MD.pak/launch.sh deleted file mode 100755 index 8ceb019a2..000000000 --- a/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/MD.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/PS.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/PS.pak/default.cfg deleted file mode 100755 index 857e895eb..000000000 --- a/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/PS.pak/default.cfg +++ /dev/null @@ -1,22 +0,0 @@ --minarch_thread_video = Off - --pcsx_rearmed_display_internal_fps = disabled --pcsx_rearmed_show_input_settings = disabled - -pcsx_rearmed_dithering = enabled - -minarch_gamepad_type = 1 -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Circle = A -bind Cross = B -bind Triangle = X -bind Square = Y -bind L1 Button = L1 -bind R1 Button = R1 -bind L2 Button = L2 -bind R2 Button = R2 \ No newline at end of file diff --git a/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/PS.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/PS.pak/launch.sh deleted file mode 100755 index d15d0b984..000000000 --- a/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/PS.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=pcsx_rearmed - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/SFC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/SFC.pak/default.cfg deleted file mode 100755 index 8100f20a1..000000000 --- a/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/SFC.pak/default.cfg +++ /dev/null @@ -1,12 +0,0 @@ -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Y Button = Y -bind X Button = X -bind B Button = B -bind A Button = A -bind L Button = L1 -bind R Button = R1 \ No newline at end of file diff --git a/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/SFC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/SFC.pak/launch.sh deleted file mode 100755 index 97dd502a0..000000000 --- a/skeleton/_unmaintained/SYSTEM/my355/paks/Emus/SFC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=snes9x2005_plus - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/my355/paks/MinUI.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/my355/paks/MinUI.pak/launch.sh deleted file mode 100755 index 948856161..000000000 --- a/skeleton/_unmaintained/SYSTEM/my355/paks/MinUI.pak/launch.sh +++ /dev/null @@ -1,88 +0,0 @@ -#!/bin/sh - -export PLATFORM="my355" -export SDCARD_PATH="/mnt/SDCARD" -export BIOS_PATH="$SDCARD_PATH/Bios" -export SAVES_PATH="$SDCARD_PATH/Saves" -export CHEATS_PATH="$SDCARD_PATH/Cheats" -export SYSTEM_PATH="$SDCARD_PATH/.system/$PLATFORM" -export CORES_PATH="$SYSTEM_PATH/cores" -export USERDATA_PATH="$SDCARD_PATH/.userdata/$PLATFORM" -export SHARED_USERDATA_PATH="$SDCARD_PATH/.userdata/shared" -export LOGS_PATH="$USERDATA_PATH/logs" -export DATETIME_PATH="$SHARED_USERDATA_PATH/datetime.txt" - -####################################### - -export PATH=$SYSTEM_PATH/bin:/usr/miyoo/bin:/usr/miyoo/sbin:$PATH -export LD_LIBRARY_PATH=$SYSTEM_PATH/lib:/usr/miyoo/lib:$LD_LIBRARY_PATH - -####################################### - -#headphone jack -echo 150 > /sys/class/gpio/export -echo -n in > /sys/class/gpio/gpio150/direction - -#motor -echo 20 > /sys/class/gpio/export -echo -n out > /sys/class/gpio/gpio20/direction -echo -n 0 > /sys/class/gpio/gpio20/value - -#keyboard -echo 0 > /sys/class/miyooio_chr_dev/joy_type - -#led -echo 0 > /sys/class/leds/work/brightness - -mkdir -p /tmp/miyoo_inputd -miyoo_inputd & - -# disable system-level lid handling -mv /dev/input/event1 /dev/input/event1.disabled - -# TODO: disable network stuff - -####################################### - -echo userspace > /sys/devices/system/cpu/cpufreq/policy0/scaling_governor -CPU_PATH=/sys/devices/system/cpu/cpufreq/policy0/scaling_setspeed -CPU_SPEED_PERF=1992000 -echo $CPU_SPEED_PERF > $CPU_PATH - -####################################### - -keymon.elf > $LOGS_PATH/keymon.txt 2>&1 & - -####################################### - -mkdir -p "$LOGS_PATH" -mkdir -p "$SHARED_USERDATA_PATH/.minui" -AUTO_PATH="$USERDATA_PATH/auto.sh" -if [ -f "$AUTO_PATH" ]; then - "$AUTO_PATH" # > $LOGS_PATH/auto.txt 2>&1 -fi - -cd $(dirname "$0") - -####################################### - -EXEC_PATH="/tmp/nextui_exec" -NEXT_PATH="/tmp/next" -touch "$EXEC_PATH" && sync -while [ -f "$EXEC_PATH" ]; do - nextui.elf > $LOGS_PATH/nextui.txt 2>&1 - echo $CPU_SPEED_PERF > $CPU_PATH - echo `date +'%F %T'` > "$DATETIME_PATH" - sync - - if [ -f $NEXT_PATH ]; then - CMD=`cat $NEXT_PATH` - eval $CMD - rm -f $NEXT_PATH - echo $CPU_SPEED_PERF > $CPU_PATH - echo `date +'%F %T'` > "$DATETIME_PATH" - sync - fi -done - -shutdown diff --git a/skeleton/_unmaintained/SYSTEM/my355/system.cfg b/skeleton/_unmaintained/SYSTEM/my355/system.cfg deleted file mode 100644 index 7685ca30b..000000000 --- a/skeleton/_unmaintained/SYSTEM/my355/system.cfg +++ /dev/null @@ -1,3 +0,0 @@ -minarch_screen_sharpness = Crisp --minarch_prevent_tearing = Lenient -minarch_cpu_speed = Normal diff --git a/skeleton/_unmaintained/SYSTEM/rg35xx/bin/shutdown b/skeleton/_unmaintained/SYSTEM/rg35xx/bin/shutdown deleted file mode 100755 index 2bf9e4130..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xx/bin/shutdown +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -if [ -n "$DATETIME_PATH" ]; then - echo `date +'%F %T'` > "$DATETIME_PATH" - sync -fi - -echo s > /proc/sysrq-trigger -echo u > /proc/sysrq-trigger -echo o > /proc/sysrq-trigger \ No newline at end of file diff --git a/skeleton/_unmaintained/SYSTEM/rg35xx/cores/.keep b/skeleton/_unmaintained/SYSTEM/rg35xx/cores/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/SYSTEM/rg35xx/dat/.keep b/skeleton/_unmaintained/SYSTEM/rg35xx/dat/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/SYSTEM/rg35xx/lib/.keep b/skeleton/_unmaintained/SYSTEM/rg35xx/lib/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/FC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/FC.pak/default.cfg deleted file mode 100644 index 90365a9d1..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/FC.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ -fceumm_sndquality = High -fceumm_sndvolume = 10 --fceumm_aspect = 8:7 PAR --fceumm_turbo_enable = Player 1 --fceumm_show_adv_system_options = disabled --fceumm_show_adv_sound_options = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Change Disk = NONE:L1 -bind Insert Disk = NONE:R1 -bind Insert Coin = NONE:R2 diff --git a/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/FC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/FC.pak/launch.sh deleted file mode 100755 index 280598bbc..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/FC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=fceumm - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/GB.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/GB.pak/default.cfg deleted file mode 100644 index a5ec62866..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/GB.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ -minarch_screen_scaling = Native - -gambatte_gb_colorization = internal -gambatte_gb_internal_palette = TWB64 - Pack 1 -gambatte_gb_palette_twb64_1 = TWB64 038 - Pokemon mini Ver. -gambatte_gb_bootloader = disabled --gambatte_audio_resampler = sinc - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Prev. Palette = NONE:L1 -bind Next Palette = NONE:R1 diff --git a/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/GB.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/GB.pak/launch.sh deleted file mode 100755 index 9143f24c9..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/GB.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gambatte - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/GBA.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/GBA.pak/default.cfg deleted file mode 100644 index ea76e21f6..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/GBA.pak/default.cfg +++ /dev/null @@ -1,14 +0,0 @@ --gpsp_save_method = libretro - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 diff --git a/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/GBA.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/GBA.pak/launch.sh deleted file mode 100755 index 5678aaca7..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/GBA.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gpsp - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/GBC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/GBC.pak/default.cfg deleted file mode 100644 index c854f885e..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/GBC.pak/default.cfg +++ /dev/null @@ -1,17 +0,0 @@ -minarch_screen_scaling = Native - -gambatte_gb_bootloader = disabled --gambatte_audio_resampler = sinc - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Prev. Palette = NONE:L1 -bind Next Palette = NONE:R1 diff --git a/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/GBC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/GBC.pak/launch.sh deleted file mode 100755 index 9143f24c9..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/GBC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gambatte - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/MD.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/MD.pak/default.cfg deleted file mode 100644 index dac408932..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/MD.pak/default.cfg +++ /dev/null @@ -1,18 +0,0 @@ --picodrive_sound_rate = 44100 --picodrive_smstype = Auto --picodrive_smsfm = off --picodrive_smsmapper = Auto --picodrive_ggghost = off - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Mode = SELECT -bind Start = START -bind A Button = Y -bind B Button = X:B -bind C Button = A -bind X Button = B:L1 -bind Y Button = L1:X -bind Z Button = R1 diff --git a/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/MD.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/MD.pak/launch.sh deleted file mode 100755 index 81688be79..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/MD.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/PS.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/PS.pak/default.cfg deleted file mode 100644 index 54a1e8c11..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/PS.pak/default.cfg +++ /dev/null @@ -1,21 +0,0 @@ --minarch_thread_video = Off - --pcsx_rearmed_display_internal_fps = disabled --pcsx_rearmed_show_input_settings = disabled - -pcsx_rearmed_dithering = enabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Circle = A -bind Cross = B -bind Triangle = X -bind Square = Y -bind L1 Button = L1 -bind R1 Button = R1 -bind L2 Button = L2 -bind R2 Button = R2 \ No newline at end of file diff --git a/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/PS.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/PS.pak/launch.sh deleted file mode 100755 index e3ba5ac06..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/PS.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=pcsx_rearmed - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/SFC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/SFC.pak/default.cfg deleted file mode 100644 index 8100f20a1..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/SFC.pak/default.cfg +++ /dev/null @@ -1,12 +0,0 @@ -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Y Button = Y -bind X Button = X -bind B Button = B -bind A Button = A -bind L Button = L1 -bind R Button = R1 \ No newline at end of file diff --git a/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/SFC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/SFC.pak/launch.sh deleted file mode 100755 index 44e982862..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xx/paks/Emus/SFC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=snes9x2005_plus - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/rg35xx/paks/MinUI.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/rg35xx/paks/MinUI.pak/launch.sh deleted file mode 100755 index 39352a2aa..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xx/paks/MinUI.pak/launch.sh +++ /dev/null @@ -1,71 +0,0 @@ -#!/bin/sh - -export PLATFORM="rg35xx" -export SDCARD_PATH="/mnt/sdcard" -export BIOS_PATH="$SDCARD_PATH/Bios" -export SAVES_PATH="$SDCARD_PATH/Saves" -export CHEATS_PATH="$SDCARD_PATH/Cheats" -export SYSTEM_PATH="$SDCARD_PATH/.system/$PLATFORM" -export CORES_PATH="$SYSTEM_PATH/cores" -export USERDATA_PATH="$SDCARD_PATH/.userdata/$PLATFORM" -export SHARED_USERDATA_PATH="$SDCARD_PATH/.userdata/shared" -export LOGS_PATH="$USERDATA_PATH/logs" -export DATETIME_PATH="$SHARED_USERDATA_PATH/datetime.txt" - -####################################### - -export PATH=$SYSTEM_PATH/bin:$PATH -export LD_LIBRARY_PATH=$SYSTEM_PATH/lib:$LD_LIBRARY_PATH - -####################################### - -echo noop > /sys/devices/b0238000.mmc/mmc_host/mmc0/emmc_boot_card/block/mmcblk0/queue/scheduler -echo noop > /sys/devices/b0230000.mmc/mmc_host/mmc1/sd_card/block/mmcblk1/queue/scheduler -echo on > /sys/devices/b0238000.mmc/mmc_host/mmc0/power/control -echo on > /sys/devices/b0230000.mmc/mmc_host/mmc1/power/control - -####################################### - -export CPU_SPEED_MENU=504000 -export CPU_SPEED_GAME=1296000 -export CPU_SPEED_PERF=1488000 -echo userspace > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor -overclock.elf $CPU_SPEED_PERF - -####################################### - -keymon.elf & # &> $LOGS_PATH/keymon.txt & - -####################################### - -mkdir -p "$LOGS_PATH" -mkdir -p "$SHARED_USERDATA_PATH/.minui" -AUTO_PATH=$USERDATA_PATH/auto.sh -if [ -f "$AUTO_PATH" ]; then - "$AUTO_PATH" # &> $LOGS_PATH/auto.txt -fi - -cd $(dirname "$0") - -####################################### - -EXEC_PATH=/tmp/nextui_exec -NEXT_PATH="/tmp/next" -touch "$EXEC_PATH" && sync -while [ -f "$EXEC_PATH" ]; do - overclock.elf $CPU_SPEED_PERF - nextui.elf &> $LOGS_PATH/nextui.txt - echo `date +'%F %T'` > "$DATETIME_PATH" - sync - - if [ -f $NEXT_PATH ]; then - CMD=`cat $NEXT_PATH` - eval $CMD - rm -f $NEXT_PATH - overclock.elf $CPU_SPEED_PERF - echo `date +'%F %T'` > "$DATETIME_PATH" - sync - fi -done - -shutdown # just in case \ No newline at end of file diff --git a/skeleton/_unmaintained/SYSTEM/rg35xx/system.cfg b/skeleton/_unmaintained/SYSTEM/rg35xx/system.cfg deleted file mode 100644 index fe146ac9e..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xx/system.cfg +++ /dev/null @@ -1,2 +0,0 @@ --minarch_screen_sharpness = Crisp --minarch_thread_video = Off diff --git a/skeleton/_unmaintained/SYSTEM/rg35xxplus/bin/hdmimon.sh b/skeleton/_unmaintained/SYSTEM/rg35xxplus/bin/hdmimon.sh deleted file mode 100755 index 46c045b65..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xxplus/bin/hdmimon.sh +++ /dev/null @@ -1,91 +0,0 @@ -#!/bin/sh - -cd $(dirname "$0") - -HDMI_WIDTH=1280 -HDMI_HEIGHT=720 - -DEVICE_WIDTH=640 -DEVICE_HEIGHT=480 -if [ "$RGXX_MODEL" = "RGcubexx" ]; then - DEVICE_WIDTH=720 - DEVICE_HEIGHT=720 -elif [ "$RGXX_MODEL" = "RG34xx" ]; then - DEVICE_WIDTH=720 -elif [ "$RGXX_MODEL" = "RG28xx" ]; then # rotated - TMP_WIDTH=$DEVICE_WIDTH - DEVICE_WIDTH=$DEVICE_HEIGHT - DEVICE_HEIGHT=$TMP_WIDTH -fi - -DISP_PATH="/sys/kernel/debug/dispdbg" -BLANK_PATH="/sys/class/graphics/fb0/blank" -touch $HDMI_EXPORT_PATH - -ALSA_CONF_DIR=/usr/share/alsa/alsa.conf.d -mkdir -p $ALSA_CONF_DIR - -enable_hdmi() { - echo 'enabling HDMI' - - echo 4 > $BLANK_PATH - cat /dev/zero > /dev/fb0 2>/dev/null - - echo disp0 > $DISP_PATH/name - echo switch > $DISP_PATH/command - echo "4 10 0 0 0x4 0x101 0 0 0 8" > $DISP_PATH/param - echo 1 > $DISP_PATH/start - - fbset -fb /dev/fb0 -g 0 0 0 0 32 - sleep 0.25 - fbset -fb /dev/fb0 -g $HDMI_WIDTH $HDMI_HEIGHT $HDMI_WIDTH $((HDMI_HEIGHT * 2)) 32 - sleep 0.25 - echo 0 > $BLANK_PATH - - echo "export AUDIODEV='hw:2,0'" > $HDMI_EXPORT_PATH - echo "export DEVICE=hdmi" >> $HDMI_EXPORT_PATH -} - -disable_hdmi() { - echo 'disabling HDMI' - - echo 4 > $BLANK_PATH - cat /dev/zero > /dev/fb0 2>/dev/null - - echo disp0 > $DISP_PATH/name - echo switch > $DISP_PATH/command - echo "1 0" > $DISP_PATH/param - echo 1 > $DISP_PATH/start - - fbset -fb /dev/fb0 -g 0 0 0 0 32 - sleep 0.25 - fbset -fb /dev/fb0 -g $DEVICE_WIDTH $DEVICE_HEIGHT $DEVICE_WIDTH $((DEVICE_HEIGHT * 2)) 32 - sleep 0.25 - echo 0 > $BLANK_PATH - - echo "unset AUDIODEV" > $HDMI_EXPORT_PATH - if [ -n "$DEVICE" ]; then - echo "export DEVICE=$DEVICE" >> $HDMI_EXPORT_PATH - else - echo "unset DEVICE" >> $HDMI_EXPORT_PATH - fi -} - -HDMI_STATE_PATH="/sys/class/switch/hdmi/cable.0/state" -HAD_HDMI=$(cat "$HDMI_STATE_PATH") -if [ "$HAD_HDMI" = "1" ]; then - enable_hdmi -fi - -while :; do - HAS_HDMI=$(cat "$HDMI_STATE_PATH") - if [ "$HAS_HDMI" != "$HAD_HDMI" ]; then - if [ "$HAS_HDMI" = "1" ]; then - enable_hdmi - else - disable_hdmi - fi - fi - HAD_HDMI=$HAS_HDMI - sleep 2 -done \ No newline at end of file diff --git a/skeleton/_unmaintained/SYSTEM/rg35xxplus/bin/shutdown b/skeleton/_unmaintained/SYSTEM/rg35xxplus/bin/shutdown deleted file mode 100755 index 46ebe7c2f..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xxplus/bin/shutdown +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - -if [ -n "$DATETIME_PATH" ]; then - echo `date +'%F %T'` > "$DATETIME_PATH" - sync -fi - -cat /dev/zero > /dev/fb0 -poweroff -# echo s > /proc/sysrq-trigger -# echo u > /proc/sysrq-trigger -# echo o > /proc/sysrq-trigger diff --git a/skeleton/_unmaintained/SYSTEM/rg35xxplus/cores/.keep b/skeleton/_unmaintained/SYSTEM/rg35xxplus/cores/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/SYSTEM/rg35xxplus/dat/.keep b/skeleton/_unmaintained/SYSTEM/rg35xxplus/dat/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/SYSTEM/rg35xxplus/lib/.keep b/skeleton/_unmaintained/SYSTEM/rg35xxplus/lib/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/FC.pak/default-cube.cfg b/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/FC.pak/default-cube.cfg deleted file mode 100644 index d70f896e5..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/FC.pak/default-cube.cfg +++ /dev/null @@ -1,23 +0,0 @@ -minarch_screen_scaling = Cropped -minarch_screen_sharpness = Sharp - -fceumm_sndquality = High -fceumm_sndvolume = 10 --fceumm_aspect = 8:7 PAR --fceumm_turbo_enable = Player 1 --fceumm_show_adv_system_options = disabled --fceumm_show_adv_sound_options = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Change Disk = NONE:L1 -bind Insert Disk = NONE:R1 -bind Insert Coin = NONE:R2 diff --git a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/FC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/FC.pak/default.cfg deleted file mode 100644 index 90365a9d1..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/FC.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ -fceumm_sndquality = High -fceumm_sndvolume = 10 --fceumm_aspect = 8:7 PAR --fceumm_turbo_enable = Player 1 --fceumm_show_adv_system_options = disabled --fceumm_show_adv_sound_options = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Change Disk = NONE:L1 -bind Insert Disk = NONE:R1 -bind Insert Coin = NONE:R2 diff --git a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/FC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/FC.pak/launch.sh deleted file mode 100644 index 780ad5456..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/FC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=fceumm - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GB.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GB.pak/default.cfg deleted file mode 100644 index 5fd6c2dfb..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GB.pak/default.cfg +++ /dev/null @@ -1,22 +0,0 @@ -minarch_screen_scaling = Native -minarch_screen_sharpness = Sharp -minarch_cpu_speed = Powersave - -gambatte_gb_colorization = internal -gambatte_gb_internal_palette = TWB64 - Pack 1 -gambatte_gb_palette_twb64_1 = TWB64 038 - Pokemon mini Ver. -gambatte_gb_bootloader = disabled --gambatte_audio_resampler = sinc - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Prev. Palette = NONE:L1 -bind Next Palette = NONE:R1 diff --git a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GB.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GB.pak/launch.sh deleted file mode 100644 index 9b93f4e5d..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GB.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gambatte - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GBA.pak/default-cube.cfg b/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GBA.pak/default-cube.cfg deleted file mode 100644 index 962b6748b..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GBA.pak/default-cube.cfg +++ /dev/null @@ -1,18 +0,0 @@ -minarch_screen_scaling = Native -minarch_screen_sharpness = Sharp -minarch_cpu_speed = Powersave - --gpsp_save_method = libretro - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 diff --git a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GBA.pak/default-wide.cfg b/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GBA.pak/default-wide.cfg deleted file mode 100644 index 962b6748b..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GBA.pak/default-wide.cfg +++ /dev/null @@ -1,18 +0,0 @@ -minarch_screen_scaling = Native -minarch_screen_sharpness = Sharp -minarch_cpu_speed = Powersave - --gpsp_save_method = libretro - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 diff --git a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GBA.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GBA.pak/default.cfg deleted file mode 100644 index 444933571..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GBA.pak/default.cfg +++ /dev/null @@ -1,16 +0,0 @@ -minarch_cpu_speed = Powersave - --gpsp_save_method = libretro - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 diff --git a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GBA.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GBA.pak/launch.sh deleted file mode 100644 index 0ed0b8f3f..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GBA.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gpsp - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GBC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GBC.pak/default.cfg deleted file mode 100644 index 83a211c9f..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GBC.pak/default.cfg +++ /dev/null @@ -1,19 +0,0 @@ -minarch_screen_scaling = Native -minarch_screen_sharpness = Sharp -minarch_cpu_speed = Powersave - -gambatte_gb_bootloader = disabled --gambatte_audio_resampler = sinc - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Prev. Palette = NONE:L1 -bind Next Palette = NONE:R1 diff --git a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GBC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GBC.pak/launch.sh deleted file mode 100644 index 9b93f4e5d..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/GBC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gambatte - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/MD.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/MD.pak/default.cfg deleted file mode 100644 index dac408932..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/MD.pak/default.cfg +++ /dev/null @@ -1,18 +0,0 @@ --picodrive_sound_rate = 44100 --picodrive_smstype = Auto --picodrive_smsfm = off --picodrive_smsmapper = Auto --picodrive_ggghost = off - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Mode = SELECT -bind Start = START -bind A Button = Y -bind B Button = X:B -bind C Button = A -bind X Button = B:L1 -bind Y Button = L1:X -bind Z Button = R1 diff --git a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/MD.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/MD.pak/launch.sh deleted file mode 100644 index 8ceb019a2..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/MD.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/PS.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/PS.pak/default.cfg deleted file mode 100644 index 46bc31226..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/PS.pak/default.cfg +++ /dev/null @@ -1,23 +0,0 @@ -minarch_cpu_speed = Performance --minarch_thread_video = Off - --pcsx_rearmed_display_internal_fps = disabled --pcsx_rearmed_show_input_settings = disabled - -pcsx_rearmed_dithering = enabled - -minarch_gamepad_type = 1 -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Circle = A -bind Cross = B -bind Triangle = X -bind Square = Y -bind L1 Button = L1 -bind R1 Button = R1 -bind L2 Button = L2 -bind R2 Button = R2 \ No newline at end of file diff --git a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/PS.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/PS.pak/launch.sh deleted file mode 100644 index d15d0b984..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/PS.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=pcsx_rearmed - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/SFC.pak/default-cube.cfg b/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/SFC.pak/default-cube.cfg deleted file mode 100644 index f888ca5d9..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/SFC.pak/default-cube.cfg +++ /dev/null @@ -1,15 +0,0 @@ -minarch_screen_scaling = Cropped -minarch_screen_sharpness = Sharp - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Y Button = Y -bind X Button = X -bind B Button = B -bind A Button = A -bind L Button = L1 -bind R Button = R1 \ No newline at end of file diff --git a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/SFC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/SFC.pak/default.cfg deleted file mode 100644 index 8100f20a1..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/SFC.pak/default.cfg +++ /dev/null @@ -1,12 +0,0 @@ -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Y Button = Y -bind X Button = X -bind B Button = B -bind A Button = A -bind L Button = L1 -bind R Button = R1 \ No newline at end of file diff --git a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/SFC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/SFC.pak/launch.sh deleted file mode 100644 index 97dd502a0..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/Emus/SFC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=snes9x2005_plus - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/MinUI.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/MinUI.pak/launch.sh deleted file mode 100755 index d0e962db1..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xxplus/paks/MinUI.pak/launch.sh +++ /dev/null @@ -1,86 +0,0 @@ -#!/bin/sh - -export PLATFORM="rg35xxplus" -export SDCARD_PATH="/mnt/sdcard" -export BIOS_PATH="$SDCARD_PATH/Bios" -export SAVES_PATH="$SDCARD_PATH/Saves" -export CHEATS_PATH="$SDCARD_PATH/Cheats" -export SYSTEM_PATH="$SDCARD_PATH/.system/$PLATFORM" -export CORES_PATH="$SYSTEM_PATH/cores" -export USERDATA_PATH="$SDCARD_PATH/.userdata/$PLATFORM" -export SHARED_USERDATA_PATH="$SDCARD_PATH/.userdata/shared" -export LOGS_PATH="$USERDATA_PATH/logs" -export DATETIME_PATH="$SHARED_USERDATA_PATH/datetime.txt" -export HDMI_EXPORT_PATH="/tmp/hdmi_export.sh" - -####################################### - -export PATH=$SYSTEM_PATH/bin:$PATH -export LD_LIBRARY_PATH=$SYSTEM_PATH/lib:$LD_LIBRARY_PATH - -####################################### - -systemctl disable ondemand -echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor -echo 0 > /sys/class/power_supply/axp2202-battery/work_led - -export RGXX_MODEL=`strings /mnt/vendor/bin/dmenu.bin | grep ^RG` -# export RGXX_TIMESTAMP=`strings /mnt/vendor/bin/dmenu.bin | grep ^202` -# export RGXX_VERSION=`strings /mnt/vendor/bin/dmenu.bin | grep -P ^V[0-9]+` - -if [ "$RGXX_MODEL" = "RGcubexx" ]; then - export DEVICE="cube" -elif [ "$RGXX_MODEL" = "RG34xx" ]; then - export DEVICE="wide" -fi - -####################################### - -keymon.elf & # > $LOGS_PATH/keymon.txt 2>&1 & - -####################################### - -mkdir -p "$LOGS_PATH" -mkdir -p "$SHARED_USERDATA_PATH/.minui" -AUTO_PATH="$USERDATA_PATH/auto.sh" -if [ -f "$AUTO_PATH" ]; then - "$AUTO_PATH" # > $LOGS_PATH/auto.txt 2>&1 -fi - -cd $(dirname "$0") - -####################################### - -init.elf # > $LOGS_PATH/init.txt 2>&1 - -####################################### - -hdmimon.sh & # > $LOGS_PATH/hdmimon.txt 2>&1 & - -HDMI_STATE_PATH="/sys/class/switch/hdmi/cable.0/state" -HAS_HDMI=$(cat "$HDMI_STATE_PATH") -if [ "$HAS_HDMI" = "1" ]; then - sleep 3 -fi - -####################################### - -EXEC_PATH="/tmp/nextui_exec" -NEXT_PATH="/tmp/next" -touch "$EXEC_PATH" && sync -while [ -f "$EXEC_PATH" ]; do - . $HDMI_EXPORT_PATH - nextui.elf > $LOGS_PATH/nextui.txt 2>&1 - echo `date +'%F %T'` > "$DATETIME_PATH" - sync - - if [ -f $NEXT_PATH ]; then - . $HDMI_EXPORT_PATH - . $NEXT_PATH - rm -f $NEXT_PATH - echo `date +'%F %T'` > "$DATETIME_PATH" - sync - fi -done - -shutdown diff --git a/skeleton/_unmaintained/SYSTEM/rg35xxplus/system.cfg b/skeleton/_unmaintained/SYSTEM/rg35xxplus/system.cfg deleted file mode 100644 index 166805116..000000000 --- a/skeleton/_unmaintained/SYSTEM/rg35xxplus/system.cfg +++ /dev/null @@ -1,3 +0,0 @@ -minarch_screen_sharpness = Crisp --minarch_prevent_tearing = Lenient --minarch_cpu_speed = Normal diff --git a/skeleton/_unmaintained/SYSTEM/rgb30/bin/shutdown b/skeleton/_unmaintained/SYSTEM/rgb30/bin/shutdown deleted file mode 100755 index 46ebe7c2f..000000000 --- a/skeleton/_unmaintained/SYSTEM/rgb30/bin/shutdown +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - -if [ -n "$DATETIME_PATH" ]; then - echo `date +'%F %T'` > "$DATETIME_PATH" - sync -fi - -cat /dev/zero > /dev/fb0 -poweroff -# echo s > /proc/sysrq-trigger -# echo u > /proc/sysrq-trigger -# echo o > /proc/sysrq-trigger diff --git a/skeleton/_unmaintained/SYSTEM/rgb30/cores/.keep b/skeleton/_unmaintained/SYSTEM/rgb30/cores/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/SYSTEM/rgb30/dat/.keep b/skeleton/_unmaintained/SYSTEM/rgb30/dat/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/SYSTEM/rgb30/lib/.keep b/skeleton/_unmaintained/SYSTEM/rgb30/lib/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/FC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/FC.pak/default.cfg deleted file mode 100644 index 5071d35c8..000000000 --- a/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/FC.pak/default.cfg +++ /dev/null @@ -1,22 +0,0 @@ -minarch_screen_scaling = Cropped - -fceumm_sndquality = High -fceumm_sndvolume = 10 --fceumm_aspect = 8:7 PAR --fceumm_turbo_enable = Player 1 --fceumm_show_adv_system_options = disabled --fceumm_show_adv_sound_options = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Change Disk = NONE:L1 -bind Insert Disk = NONE:R1 -bind Insert Coin = NONE:R2 diff --git a/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/FC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/FC.pak/launch.sh deleted file mode 100644 index 280598bbc..000000000 --- a/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/FC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=fceumm - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/GB.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/GB.pak/default.cfg deleted file mode 100644 index c17e6be0e..000000000 --- a/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/GB.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ -minarch_cpu_speed = Powersave - -gambatte_gb_colorization = internal -gambatte_gb_internal_palette = TWB64 - Pack 1 -gambatte_gb_palette_twb64_1 = TWB64 038 - Pokemon mini Ver. -gambatte_gb_bootloader = disabled --gambatte_audio_resampler = sinc - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Prev. Palette = NONE:L1 -bind Next Palette = NONE:R1 diff --git a/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/GB.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/GB.pak/launch.sh deleted file mode 100755 index 9143f24c9..000000000 --- a/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/GB.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gambatte - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/GBA.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/GBA.pak/default.cfg deleted file mode 100644 index a1833809a..000000000 --- a/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/GBA.pak/default.cfg +++ /dev/null @@ -1,17 +0,0 @@ -minarch_screen_scaling = Native -minarch_cpu_speed = Powersave - --gpsp_save_method = libretro - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 diff --git a/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/GBA.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/GBA.pak/launch.sh deleted file mode 100755 index 5678aaca7..000000000 --- a/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/GBA.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gpsp - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/GBC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/GBC.pak/default.cfg deleted file mode 100644 index f9e281ac6..000000000 --- a/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/GBC.pak/default.cfg +++ /dev/null @@ -1,17 +0,0 @@ -minarch_cpu_speed = Powersave - -gambatte_gb_bootloader = disabled --gambatte_audio_resampler = sinc - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Prev. Palette = NONE:L1 -bind Next Palette = NONE:R1 diff --git a/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/GBC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/GBC.pak/launch.sh deleted file mode 100755 index 9143f24c9..000000000 --- a/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/GBC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gambatte - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/MD.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/MD.pak/default.cfg deleted file mode 100644 index dac408932..000000000 --- a/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/MD.pak/default.cfg +++ /dev/null @@ -1,18 +0,0 @@ --picodrive_sound_rate = 44100 --picodrive_smstype = Auto --picodrive_smsfm = off --picodrive_smsmapper = Auto --picodrive_ggghost = off - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Mode = SELECT -bind Start = START -bind A Button = Y -bind B Button = X:B -bind C Button = A -bind X Button = B:L1 -bind Y Button = L1:X -bind Z Button = R1 diff --git a/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/MD.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/MD.pak/launch.sh deleted file mode 100644 index 81688be79..000000000 --- a/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/MD.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/PS.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/PS.pak/default.cfg deleted file mode 100644 index 46bc31226..000000000 --- a/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/PS.pak/default.cfg +++ /dev/null @@ -1,23 +0,0 @@ -minarch_cpu_speed = Performance --minarch_thread_video = Off - --pcsx_rearmed_display_internal_fps = disabled --pcsx_rearmed_show_input_settings = disabled - -pcsx_rearmed_dithering = enabled - -minarch_gamepad_type = 1 -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Circle = A -bind Cross = B -bind Triangle = X -bind Square = Y -bind L1 Button = L1 -bind R1 Button = R1 -bind L2 Button = L2 -bind R2 Button = R2 \ No newline at end of file diff --git a/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/PS.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/PS.pak/launch.sh deleted file mode 100644 index e3ba5ac06..000000000 --- a/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/PS.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=pcsx_rearmed - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/SFC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/SFC.pak/default.cfg deleted file mode 100644 index 2d9b31aa0..000000000 --- a/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/SFC.pak/default.cfg +++ /dev/null @@ -1,14 +0,0 @@ -minarch_screen_scaling = Cropped - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Y Button = Y -bind X Button = X -bind B Button = B -bind A Button = A -bind L Button = L1 -bind R Button = R1 \ No newline at end of file diff --git a/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/SFC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/SFC.pak/launch.sh deleted file mode 100644 index 44e982862..000000000 --- a/skeleton/_unmaintained/SYSTEM/rgb30/paks/Emus/SFC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=snes9x2005_plus - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/rgb30/paks/MinUI.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/rgb30/paks/MinUI.pak/launch.sh deleted file mode 100755 index ef31e9de5..000000000 --- a/skeleton/_unmaintained/SYSTEM/rgb30/paks/MinUI.pak/launch.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/sh - -export PLATFORM="rgb30" -export SDCARD_PATH="/storage/roms" -export BIOS_PATH="$SDCARD_PATH/Bios" -export SAVES_PATH="$SDCARD_PATH/Saves" -export CHEATS_PATH="$SDCARD_PATH/Cheats" -export SYSTEM_PATH="$SDCARD_PATH/.system/$PLATFORM" -export CORES_PATH="$SYSTEM_PATH/cores" -export USERDATA_PATH="$SDCARD_PATH/.userdata/$PLATFORM" -export SHARED_USERDATA_PATH="$SDCARD_PATH/.userdata/shared" -export LOGS_PATH="$USERDATA_PATH/logs" -export DATETIME_PATH="$SHARED_USERDATA_PATH/datetime.txt" - -####################################### - -# JELOS aggressively repairs disks and leaves litter on the SD card -rm $SDCARD_PATH/FSCK*.REC - -export PATH=$SYSTEM_PATH/bin:$PATH -export LD_LIBRARY_PATH=$SYSTEM_PATH/lib:$LD_LIBRARY_PATH - -# required for sdl12-compat -export SDL_VIDEODRIVER=kmsdrm -export SDL_AUDIODRIVER=alsa - -# required for sdl1 fbcon -# export SDL_VIDEODRIVER=fbcon -# export SDL_AUDIODRIVER=alsa -# export SDL_NOMOUSE=1 - -echo userspace > /sys/devices/system/cpu/cpufreq/policy0/scaling_governor -CPU_PATH=/sys/devices/system/cpu/cpufreq/policy0/scaling_setspeed -CPU_SPEED_PERF=1992000 -echo $CPU_SPEED_PERF > $CPU_PATH - -####################################### - -keymon.elf & # &> $SDCARD_PATH/keymon.txt & - -####################################### - -mkdir -p "$LOGS_PATH" -mkdir -p "$SHARED_USERDATA_PATH/.minui" -AUTO_PATH=$USERDATA_PATH/auto.sh -if [ -f "$AUTO_PATH" ]; then - "$AUTO_PATH" # &> $LOGS_PATH/auto.txt -fi - -cd $(dirname "$0") - -####################################### - -EXEC_PATH=/tmp/nextui_exec -NEXT_PATH="/tmp/next" -touch "$EXEC_PATH" && sync -while [ -f "$EXEC_PATH" ]; do - echo $CPU_SPEED_PERF > $CPU_PATH - nextui.elf &> $LOGS_PATH/nextui.txt - echo `date +'%F %T'` > "$DATETIME_PATH" - sync - - if [ -f $NEXT_PATH ]; then - CMD=`cat $NEXT_PATH` - eval $CMD - rm -f $NEXT_PATH - echo $CPU_SPEED_PERF > $CPU_PATH - echo `date +'%F %T'` > "$DATETIME_PATH" - sync - fi -done - -shutdown # just in case diff --git a/skeleton/_unmaintained/SYSTEM/rgb30/system.cfg b/skeleton/_unmaintained/SYSTEM/rgb30/system.cfg deleted file mode 100644 index 0bfb57838..000000000 --- a/skeleton/_unmaintained/SYSTEM/rgb30/system.cfg +++ /dev/null @@ -1,3 +0,0 @@ --minarch_screen_sharpness = Crisp --minarch_prevent_tearing = Lenient - diff --git a/skeleton/_unmaintained/SYSTEM/trimuismart/bin/leds_off b/skeleton/_unmaintained/SYSTEM/trimuismart/bin/leds_off deleted file mode 100755 index f8e8bd82d..000000000 --- a/skeleton/_unmaintained/SYSTEM/trimuismart/bin/leds_off +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -echo 0 > /sys/devices/platform/sunxi-led/leds/led1/brightness -echo 0 > /sys/devices/platform/sunxi-led/leds/led2/brightness -echo 0 > /sys/devices/platform/sunxi-led/leds/led3/brightness diff --git a/skeleton/_unmaintained/SYSTEM/trimuismart/bin/leds_on b/skeleton/_unmaintained/SYSTEM/trimuismart/bin/leds_on deleted file mode 100755 index 2123b5904..000000000 --- a/skeleton/_unmaintained/SYSTEM/trimuismart/bin/leds_on +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -echo 255 > /sys/devices/platform/sunxi-led/leds/led1/brightness -echo 255 > /sys/devices/platform/sunxi-led/leds/led2/brightness -echo 255 > /sys/devices/platform/sunxi-led/leds/led3/brightness diff --git a/skeleton/_unmaintained/SYSTEM/trimuismart/bin/shutdown b/skeleton/_unmaintained/SYSTEM/trimuismart/bin/shutdown deleted file mode 100755 index c95025368..000000000 --- a/skeleton/_unmaintained/SYSTEM/trimuismart/bin/shutdown +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -# NOTE: doesn't actually shutdown because we have a physical power switch - -if [ -n "$DATETIME_PATH" ]; then - echo `date +'%F %T'` > "$DATETIME_PATH" - sync -fi diff --git a/skeleton/_unmaintained/SYSTEM/trimuismart/cores/.keep b/skeleton/_unmaintained/SYSTEM/trimuismart/cores/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/SYSTEM/trimuismart/dat/logo.bmp b/skeleton/_unmaintained/SYSTEM/trimuismart/dat/logo.bmp deleted file mode 100644 index 9bd3e2a3a2a360ec8e0276d88f65646efadc5739..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 153672 zcmeI)v1`;&90%~Ig9ROmI5-F@xHt+99XhCksNi6yT6C!5B>n+i9UO|Ii*mTR=zk!1 zV;7-=1sCCPyTL)BLj;F-X-R!elxr?|cUSInaOCAK`Mu=xZPMOra@X(NTt1rQj~j#M z!r=LH@Vt5?Nsc7*$+1EE=-~ZRCz74#V0QQMD@nc`Pm*)RyeRt287lkY1ZzU0aM?%jD(O=6Tx%j>+_bQJG_Po(i_ z<@HX+XZue}8JDvfZGN%;{PIM0Os9JS>q~2!d3s-a7lQNYXn9uGy5DyU?@>>r@h)n< zS@vqPdiI~lj?Q4GvCq%D$MfA6Ge|q(T^`5ZSH;=7mpVs}JMMcszjKQO^6CE1zu`O0 z+gqJ+@87KV7jt~0`t$H6eK}Hwq z$+q)pTCbW>lUJObo95B>`c2X-uj~JVZKu<`UOA&C^ZvizJde5+&P2XG_V3Tbn(K4w zhSS3Gh*GKk_+)o*f9S%-=a=u@9~vbQMF|ifK!5-N0t5&UAV7csfw}_q$2a~z zlDXKwb-Ql=mX9mYWPGxk^kP5m)~a3>70XyS77%$bHdDG-oKw^arZ{` zvcT%xmA84i+ns-ZyG@vU8|`xc=Hm;TeAG>|?Ddz&m#TfWk!e_?+Jjf(3p~D*-;do* zPd+O56=u^$yIkM=cm%G^ZFlngPQP6ZzP&C<+Q>AlF`m8AOCeCbe)8UC@m@X+vuUFp z*4B "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/GB.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/GB.pak/default.cfg deleted file mode 100644 index d3e80e7b6..000000000 --- a/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/GB.pak/default.cfg +++ /dev/null @@ -1,18 +0,0 @@ -gambatte_gb_colorization = internal -gambatte_gb_internal_palette = TWB64 - Pack 1 -gambatte_gb_palette_twb64_1 = TWB64 038 - Pokemon mini Ver. -gambatte_gb_bootloader = disabled --gambatte_audio_resampler = sinc - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Prev. Palette = NONE:L1 -bind Next Palette = NONE:R1 diff --git a/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/GB.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/GB.pak/launch.sh deleted file mode 100755 index 9143f24c9..000000000 --- a/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/GB.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gambatte - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/GBA.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/GBA.pak/default.cfg deleted file mode 100644 index ea76e21f6..000000000 --- a/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/GBA.pak/default.cfg +++ /dev/null @@ -1,14 +0,0 @@ --gpsp_save_method = libretro - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 diff --git a/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/GBA.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/GBA.pak/launch.sh deleted file mode 100755 index 5678aaca7..000000000 --- a/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/GBA.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gpsp - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/GBC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/GBC.pak/default.cfg deleted file mode 100644 index 606e7b74c..000000000 --- a/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/GBC.pak/default.cfg +++ /dev/null @@ -1,15 +0,0 @@ -gambatte_gb_bootloader = disabled --gambatte_audio_resampler = sinc - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Prev. Palette = NONE:L1 -bind Next Palette = NONE:R1 diff --git a/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/GBC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/GBC.pak/launch.sh deleted file mode 100755 index 9143f24c9..000000000 --- a/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/GBC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gambatte - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/MD.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/MD.pak/default.cfg deleted file mode 100644 index 9c11684fc..000000000 --- a/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/MD.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ -minarch_screen_scaling = Native - --picodrive_sound_rate = 44100 --picodrive_smstype = Auto --picodrive_smsfm = off --picodrive_smsmapper = Auto --picodrive_ggghost = off - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Mode = SELECT -bind Start = START -bind A Button = Y -bind B Button = X:B -bind C Button = A -bind X Button = B:L1 -bind Y Button = L1:X -bind Z Button = R1 diff --git a/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/MD.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/MD.pak/launch.sh deleted file mode 100755 index 81688be79..000000000 --- a/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/MD.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/PS.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/PS.pak/default.cfg deleted file mode 100644 index 8e02071aa..000000000 --- a/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/PS.pak/default.cfg +++ /dev/null @@ -1,19 +0,0 @@ --minarch_thread_video = Off - --pcsx_rearmed_display_internal_fps = disabled --pcsx_rearmed_show_input_settings = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Circle = A -bind Cross = B -bind Triangle = X -bind Square = Y -bind L1 Button = L1 -bind R1 Button = R1 -bind L2 Button = NONE:L2 -bind R2 Button = NONE:R2 diff --git a/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/PS.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/PS.pak/launch.sh deleted file mode 100755 index e3ba5ac06..000000000 --- a/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/PS.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=pcsx_rearmed - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/SFC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/SFC.pak/default.cfg deleted file mode 100644 index 8100f20a1..000000000 --- a/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/SFC.pak/default.cfg +++ /dev/null @@ -1,12 +0,0 @@ -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Y Button = Y -bind X Button = X -bind B Button = B -bind A Button = A -bind L Button = L1 -bind R Button = R1 \ No newline at end of file diff --git a/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/SFC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/SFC.pak/launch.sh deleted file mode 100755 index 44e982862..000000000 --- a/skeleton/_unmaintained/SYSTEM/trimuismart/paks/Emus/SFC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=snes9x2005_plus - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" &> "$LOGS_PATH/$EMU_TAG.txt" diff --git a/skeleton/_unmaintained/SYSTEM/trimuismart/paks/MinUI.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/trimuismart/paks/MinUI.pak/launch.sh deleted file mode 100755 index 816f56895..000000000 --- a/skeleton/_unmaintained/SYSTEM/trimuismart/paks/MinUI.pak/launch.sh +++ /dev/null @@ -1,113 +0,0 @@ -#!/bin/sh -# MiniUI.pak - -# recover from readonly SD card ------------------------------- -touch /mnt/writetest -sync -if [ -f /mnt/writetest ] ; then - rm -f /mnt/writetest -else - e2fsck -p /dev/root > /mnt/SDCARD/RootRecovery.txt - reboot -fi - -####################################### - -export PLATFORM="trimuismart" -export SDCARD_PATH="/mnt/SDCARD" -export BIOS_PATH="$SDCARD_PATH/Bios" -export SAVES_PATH="$SDCARD_PATH/Saves" -export CHEATS_PATH="$SDCARD_PATH/Cheats" -export SYSTEM_PATH="$SDCARD_PATH/.system/$PLATFORM" -export CORES_PATH="$SYSTEM_PATH/cores" -export USERDATA_PATH="$SDCARD_PATH/.userdata/$PLATFORM" -export SHARED_USERDATA_PATH="$SDCARD_PATH/.userdata/shared" -export LOGS_PATH="$USERDATA_PATH/logs" -export DATETIME_PATH="$SHARED_USERDATA_PATH/datetime.txt" - -mkdir -p "$USERDATA_PATH" -mkdir -p "$LOGS_PATH" -mkdir -p "$SHARED_USERDATA_PATH/.minui" - -####################################### - -echo A,B,X,Y,L,R > /sys/module/gpio_keys_polled/parameters/button_config - -echo userspace > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor -CPU_PATH=/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed -CPU_SPEED_PERF=1536000 -echo $CPU_SPEED_PERF > $CPU_PATH - -####################################### - -export LD_LIBRARY_PATH=$SYSTEM_PATH/lib:/usr/trimui/lib:$LD_LIBRARY_PATH -export PATH=$SYSTEM_PATH/bin:/usr/trimui/bin:$PATH - -leds_off - -killall -9 MtpDaemon -killall -9 wpa_supplicant -ifconfig wlan0 down - -keymon.elf & - -####################################### - -# init datetime -if [ -f "$DATETIME_PATH" ]; then - DATETIME=`cat "$DATETIME_PATH"` - date +'%F %T' -s "$DATETIME" - DATETIME=`date +'%s'` - date -u -s "@$DATETIME" -fi - -####################################### - -AUTO_PATH=$USERDATA_PATH/auto.sh -if [ -f "$AUTO_PATH" ]; then - "$AUTO_PATH" -fi - -cd $(dirname "$0") - -####################################### - -EXEC_PATH="/tmp/nextui_exec" -NEXT_PATH="/tmp/next" -touch "$EXEC_PATH" && sync -while [ -f $EXEC_PATH ]; do - nextui.elf &> $LOGS_PATH/nextui.txt - echo $CPU_SPEED_PERF > $CPU_PATH - echo `date +'%F %T'` > "$DATETIME_PATH" - sync - - if [ -f $NEXT_PATH ]; then - CMD=`cat $NEXT_PATH` - eval $CMD - rm -f $NEXT_PATH - echo $CPU_SPEED_PERF > $CPU_PATH - echo `date +'%F %T'` > "$DATETIME_PATH" - sync - fi - - # physical powerswitch, enter low power mode - if [ -f "/tmp/poweroff" ]; then - rm -f "/tmp/poweroff" - killall keymon.elf - shutdown - echo 60000 > $CPU_PATH - LED_ON=true - while :; do - if $LED_ON; then - LED_ON=false - leds_off - else - LED_ON=true - leds_on - fi - sleep 0.5 - done - fi -done - -poweroff # just in case diff --git a/skeleton/_unmaintained/SYSTEM/trimuismart/system.cfg b/skeleton/_unmaintained/SYSTEM/trimuismart/system.cfg deleted file mode 100644 index 0a7de1ab0..000000000 --- a/skeleton/_unmaintained/SYSTEM/trimuismart/system.cfg +++ /dev/null @@ -1,4 +0,0 @@ --minarch_screen_effect = None --minarch_screen_sharpness = Crisp --minarch_thread_video = Off - diff --git a/skeleton/_unmaintained/SYSTEM/zero28/bin/setterm b/skeleton/_unmaintained/SYSTEM/zero28/bin/setterm deleted file mode 100755 index 97983f35f..000000000 --- a/skeleton/_unmaintained/SYSTEM/zero28/bin/setterm +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -# generates unnecessary errors when missing -exit 0 diff --git a/skeleton/_unmaintained/SYSTEM/zero28/bin/shutdown b/skeleton/_unmaintained/SYSTEM/zero28/bin/shutdown deleted file mode 100755 index 0041e1525..000000000 --- a/skeleton/_unmaintained/SYSTEM/zero28/bin/shutdown +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -if [ -n "$DATETIME_PATH" ]; then - echo `date +'%F %T'` > "$DATETIME_PATH" - sync -fi - -cat /dev/zero > /dev/fb0 -poweroff -while :; do - sleep 1 -done - -# echo s > /proc/sysrq-trigger -# echo u > /proc/sysrq-trigger -# echo o > /proc/sysrq-trigger diff --git a/skeleton/_unmaintained/SYSTEM/zero28/bin/suspend b/skeleton/_unmaintained/SYSTEM/zero28/bin/suspend deleted file mode 100755 index 3a1106de2..000000000 --- a/skeleton/_unmaintained/SYSTEM/zero28/bin/suspend +++ /dev/null @@ -1,74 +0,0 @@ -#!/bin/sh -set -euo pipefail -exec 0<&- - -wpa_running= -hciattach_running= -bluetoothd_running= - -asound_state_dir=/tmp/asound-suspend - -before() { - >&2 echo "Preparing for suspend..." - - >&2 echo "Saving mixer state..." - mkdir -p "$asound_state_dir" - alsactl --file "$asound_state_dir/asound.state.pre" store || true - - if pgrep wpa_supplicant; then - wpa_running=1 - >&2 echo "Stopping wpa_supplicant..." - killall -9 wpa_supplicant || true - fi - ifconfig wlan0 down || true - - if pgrep hciattach; then - hciattach_running=1 - >&2 echo "Stopping hciattach..." - /etc/init.d/hciattach stop || true - fi - if pgrep bluetoothd; then - bluetoothd_running=1 - >&2 echo "Stopping bluetoothd..." - /etc/bluetooth/bluetoothd stop || true - killall -15 bluealsa || true - fi - - >&2 echo "Blocking wireless..." - echo 0 >/sys/class/rfkill/rfkill0/state || true -} - -after() { - >&2 echo "Resumed from suspend." - - >&2 echo "Restoring mixer state..." - alsactl --file "$asound_state_dir/asound.state.post" store || true - alsactl --file "$asound_state_dir/asound.state.pre" restore || true - - >&2 echo "Unblocking wireless..." - echo 1 >/sys/class/rfkill/rfkill0/state || true - - if [ -n "$wpa_running" ]; then - >&2 echo "Starting wpa_supplicant..." - wpa_supplicant -B -D nl80211 -iwlan0 -c /etc/wifi/wpa_supplicant.conf -O /etc/wifi/sockets || true - (( udhcpc -i wlan0 &)&) - fi - - if [ -n "$hciattach_running" ]; then - >&2 echo "Starting hciattach..." - /etc/init.d/hciattach start || true - fi - if [ -n "$bluetoothd_running" ]; then - >&2 echo "Starting bluetoothd..." - /etc/bluetooth/bluetoothd start || true - /usr/bin/bluetoothctl power on || true - fi -} - -before - ->&2 echo "Suspending..." -echo mem >/sys/power/state - -# Resume services in background to reduce UI latency -(( after &)&) diff --git a/skeleton/_unmaintained/SYSTEM/zero28/cores/.keep b/skeleton/_unmaintained/SYSTEM/zero28/cores/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/SYSTEM/zero28/dat/.keep b/skeleton/_unmaintained/SYSTEM/zero28/dat/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/SYSTEM/zero28/lib/.keep b/skeleton/_unmaintained/SYSTEM/zero28/lib/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/FC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/FC.pak/default.cfg deleted file mode 100644 index 90365a9d1..000000000 --- a/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/FC.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ -fceumm_sndquality = High -fceumm_sndvolume = 10 --fceumm_aspect = 8:7 PAR --fceumm_turbo_enable = Player 1 --fceumm_show_adv_system_options = disabled --fceumm_show_adv_sound_options = disabled - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Change Disk = NONE:L1 -bind Insert Disk = NONE:R1 -bind Insert Coin = NONE:R2 diff --git a/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/FC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/FC.pak/launch.sh deleted file mode 100644 index 780ad5456..000000000 --- a/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/FC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=fceumm - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/GB.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/GB.pak/default.cfg deleted file mode 100644 index a5ec62866..000000000 --- a/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/GB.pak/default.cfg +++ /dev/null @@ -1,20 +0,0 @@ -minarch_screen_scaling = Native - -gambatte_gb_colorization = internal -gambatte_gb_internal_palette = TWB64 - Pack 1 -gambatte_gb_palette_twb64_1 = TWB64 038 - Pokemon mini Ver. -gambatte_gb_bootloader = disabled --gambatte_audio_resampler = sinc - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Prev. Palette = NONE:L1 -bind Next Palette = NONE:R1 diff --git a/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/GB.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/GB.pak/launch.sh deleted file mode 100644 index 9b93f4e5d..000000000 --- a/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/GB.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gambatte - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/GBA.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/GBA.pak/default.cfg deleted file mode 100644 index ea76e21f6..000000000 --- a/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/GBA.pak/default.cfg +++ /dev/null @@ -1,14 +0,0 @@ --gpsp_save_method = libretro - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind L Button = L1 -bind R Button = R1 diff --git a/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/GBA.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/GBA.pak/launch.sh deleted file mode 100644 index 0ed0b8f3f..000000000 --- a/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/GBA.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gpsp - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/GBC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/GBC.pak/default.cfg deleted file mode 100644 index c854f885e..000000000 --- a/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/GBC.pak/default.cfg +++ /dev/null @@ -1,17 +0,0 @@ -minarch_screen_scaling = Native - -gambatte_gb_bootloader = disabled --gambatte_audio_resampler = sinc - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind A Button = A -bind B Button = B -bind A Turbo = NONE:X -bind B Turbo = NONE:Y -bind Prev. Palette = NONE:L1 -bind Next Palette = NONE:R1 diff --git a/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/GBC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/GBC.pak/launch.sh deleted file mode 100644 index 9b93f4e5d..000000000 --- a/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/GBC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=gambatte - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/MD.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/MD.pak/default.cfg deleted file mode 100644 index dac408932..000000000 --- a/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/MD.pak/default.cfg +++ /dev/null @@ -1,18 +0,0 @@ --picodrive_sound_rate = 44100 --picodrive_smstype = Auto --picodrive_smsfm = off --picodrive_smsmapper = Auto --picodrive_ggghost = off - -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Mode = SELECT -bind Start = START -bind A Button = Y -bind B Button = X:B -bind C Button = A -bind X Button = B:L1 -bind Y Button = L1:X -bind Z Button = R1 diff --git a/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/MD.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/MD.pak/launch.sh deleted file mode 100644 index 8ceb019a2..000000000 --- a/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/MD.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=picodrive - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/PS.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/PS.pak/default.cfg deleted file mode 100644 index 857e895eb..000000000 --- a/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/PS.pak/default.cfg +++ /dev/null @@ -1,22 +0,0 @@ --minarch_thread_video = Off - --pcsx_rearmed_display_internal_fps = disabled --pcsx_rearmed_show_input_settings = disabled - -pcsx_rearmed_dithering = enabled - -minarch_gamepad_type = 1 -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Circle = A -bind Cross = B -bind Triangle = X -bind Square = Y -bind L1 Button = L1 -bind R1 Button = R1 -bind L2 Button = L2 -bind R2 Button = R2 \ No newline at end of file diff --git a/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/PS.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/PS.pak/launch.sh deleted file mode 100644 index d15d0b984..000000000 --- a/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/PS.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=pcsx_rearmed - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/SFC.pak/default.cfg b/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/SFC.pak/default.cfg deleted file mode 100644 index 8100f20a1..000000000 --- a/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/SFC.pak/default.cfg +++ /dev/null @@ -1,12 +0,0 @@ -bind Up = UP -bind Down = DOWN -bind Left = LEFT -bind Right = RIGHT -bind Select = SELECT -bind Start = START -bind Y Button = Y -bind X Button = X -bind B Button = B -bind A Button = A -bind L Button = L1 -bind R Button = R1 \ No newline at end of file diff --git a/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/SFC.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/SFC.pak/launch.sh deleted file mode 100644 index 97dd502a0..000000000 --- a/skeleton/_unmaintained/SYSTEM/zero28/paks/Emus/SFC.pak/launch.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -EMU_EXE=snes9x2005_plus - -############################### - -EMU_TAG=$(basename "$(dirname "$0")" .pak) -ROM="$1" -mkdir -p "$BIOS_PATH/$EMU_TAG" -mkdir -p "$SAVES_PATH/$EMU_TAG" -mkdir -p "$CHEATS_PATH/$EMU_TAG" -HOME="$USERDATA_PATH" -cd "$HOME" -minarch.elf "$CORES_PATH/${EMU_EXE}_libretro.so" "$ROM" > "$LOGS_PATH/$EMU_TAG.txt" 2>&1 diff --git a/skeleton/_unmaintained/SYSTEM/zero28/paks/MinUI.pak/launch.sh b/skeleton/_unmaintained/SYSTEM/zero28/paks/MinUI.pak/launch.sh deleted file mode 100755 index 2c0005558..000000000 --- a/skeleton/_unmaintained/SYSTEM/zero28/paks/MinUI.pak/launch.sh +++ /dev/null @@ -1,72 +0,0 @@ -#!/bin/sh -# MiniUI.pak - -####################################### - -export PLATFORM="zero28" -export SDCARD_PATH="/mnt/SDCARD" -export BIOS_PATH="$SDCARD_PATH/Bios" -export ROMS_PATH="$SDCARD_PATH/Roms" -export SAVES_PATH="$SDCARD_PATH/Saves" -export CHEATS_PATH="$SDCARD_PATH/Cheats" -export SYSTEM_PATH="$SDCARD_PATH/.system/$PLATFORM" -export CORES_PATH="$SYSTEM_PATH/cores" -export USERDATA_PATH="$SDCARD_PATH/.userdata/$PLATFORM" -export SHARED_USERDATA_PATH="$SDCARD_PATH/.userdata/shared" -export LOGS_PATH="$USERDATA_PATH/logs" -export DATETIME_PATH="$SHARED_USERDATA_PATH/datetime.txt" - -mkdir -p "$BIOS_PATH" -mkdir -p "$ROMS_PATH" -mkdir -p "$SAVES_PATH" -mkdir -p "$CHEATS_PATH" -mkdir -p "$USERDATA_PATH" -mkdir -p "$LOGS_PATH" -mkdir -p "$SHARED_USERDATA_PATH/.minui" - -####################################### - -export LD_LIBRARY_PATH=$SYSTEM_PATH/lib:$LD_LIBRARY_PATH -export PATH=$SYSTEM_PATH/bin:$PATH - -# corrects brightness control -bl_disable && bl_enable - -echo userspace > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor -CPU_PATH=/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed -CPU_SPEED_PERF=1800000 -echo $CPU_SPEED_PERF > $CPU_PATH - -keymon.elf & # &> $SDCARD_PATH/keymon.txt & - -####################################### - -AUTO_PATH=$USERDATA_PATH/auto.sh -if [ -f "$AUTO_PATH" ]; then - "$AUTO_PATH" -fi - -cd $(dirname "$0") - -####################################### - -EXEC_PATH="/tmp/nextui_exec" -NEXT_PATH="/tmp/next" -touch "$EXEC_PATH" && sync -while [ -f $EXEC_PATH ]; do - nextui.elf &> $LOGS_PATH/nextui.txt - echo $CPU_SPEED_PERF > $CPU_PATH - echo `date +'%F %T'` > "$DATETIME_PATH" - sync - - if [ -f $NEXT_PATH ]; then - CMD=`cat $NEXT_PATH` - eval $CMD - rm -f $NEXT_PATH - echo $CPU_SPEED_PERF > $CPU_PATH - echo `date +'%F %T'` > "$DATETIME_PATH" - sync - fi -done - -poweroff # just in case diff --git a/skeleton/_unmaintained/SYSTEM/zero28/system.cfg b/skeleton/_unmaintained/SYSTEM/zero28/system.cfg deleted file mode 100644 index 7685ca30b..000000000 --- a/skeleton/_unmaintained/SYSTEM/zero28/system.cfg +++ /dev/null @@ -1,3 +0,0 @@ -minarch_screen_sharpness = Crisp --minarch_prevent_tearing = Lenient -minarch_cpu_speed = Normal diff --git a/workspace/_unmaintained/gkdpixel/boot/boot.sh b/workspace/_unmaintained/gkdpixel/boot/boot.sh deleted file mode 100755 index 0bc11cebe..000000000 --- a/workspace/_unmaintained/gkdpixel/boot/boot.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/sh -# becomes /usr/sbin/frontend_start - -# Restore the framebuffer to a working state -# Reset the console -# Disactivate the console on framebuffer -/usr/sbin/unlockvt > /dev/null -/usr/bin/reset -echo 0 > /sys/devices/virtual/vtconsole/vtcon1/bind - -SDCARD_PATH=/media/roms -SYSTEM_PATH=$SDCARD_PATH/.system/gkdpixel -UPDATE_PATH=$SDCARD_PATH/NextUI.zip - -# is there an update available? -if [ -f $UPDATE_PATH ]; then - echo "zip detected" >> $SDCARD_PATH/log.txt - - if [ ! -d $SYSTEM_PATH ]; then - ACTION=installing - echo "install NextUI" >> $SDCARD_PATH/log.txt - else - ACTION=updating - echo "update NextUI" >> $SDCARD_PATH/log.txt - fi - - # show action - dd skip=54 if=/usr/share/nextui/$ACTION.bmp of=/dev/fb0 bs=1 - sync - - unzip -o $UPDATE_PATH -d $SDCARD_PATH - rm -f $UPDATE_PATH - - rm -rf $SDCARD_PATH/gkdpixel - - # the updated system finishes the install/update - $SYSTEM_PATH/bin/install.sh -fi - -LAUNCH_PATH=/media/roms/.system/gkdpixel/paks/NextUI.pak/launch.sh -if [ -f "$LAUNCH_PATH" ]; then - $LAUNCH_PATH > /media/roms/log.txt 2>&1 -else - /usr/sbin/frontend_start.original -fi \ No newline at end of file diff --git a/workspace/_unmaintained/gkdpixel/boot/install.sh b/workspace/_unmaintained/gkdpixel/boot/install.sh deleted file mode 100755 index 889d248ae..000000000 --- a/workspace/_unmaintained/gkdpixel/boot/install.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -cd $(dirname "$0") - -if [ ! -f /usr/sbin/frontend_start.original ]; then - mv /usr/sbin/frontend_start /usr/sbin/frontend_start.original -fi - -cp boot.sh /usr/sbin/frontend_start - -mkdir -p /usr/share/nextui -cp *.bmp /usr/share/nextui - -/usr/sbin/frontend_start \ No newline at end of file diff --git a/workspace/_unmaintained/gkdpixel/boot/installing.bmp b/workspace/_unmaintained/gkdpixel/boot/installing.bmp deleted file mode 100644 index 8b5557dc910f37a092b608dd2811922e71123cee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 307256 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 z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs N0RjXF5cocU{{^q(tr`FT diff --git a/workspace/_unmaintained/gkdpixel/boot/updating.bmp b/workspace/_unmaintained/gkdpixel/boot/updating.bmp deleted file mode 100644 index acbae4d3b785ecbfe0ddfe1394ba4fcc96a841f1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 307256 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 PK!5-N0t5(ruLS-N+<@7- diff --git a/workspace/_unmaintained/gkdpixel/cores/makefile b/workspace/_unmaintained/gkdpixel/cores/makefile deleted file mode 100644 index 908f8785f..000000000 --- a/workspace/_unmaintained/gkdpixel/cores/makefile +++ /dev/null @@ -1,44 +0,0 @@ -CORES = gambatte gpsp fceumm picodrive snes9x2005_plus pcsx_rearmed -CORES+= mednafen_pce_fast pokemini race mgba -# CORES+= mednafen_supafaust mednafen_vb fake-08 - -PLATFORM = gcw0 - -############################### - -# optional core vars -# *_REPO= -# *_HASH= -# *_CORE= -# *_FLAGS= -# *_MAKEFILE= -# *_BUILD_PATH= - -mednafen_pce_fast_REPO = https://github.com/libretro/beetle-pce-fast-libretro -mednafen_vb_REPO = https://github.com/libretro/beetle-vb-libretro - -fake-08_REPO = https://github.com/jtothebell/fake-08 -fake-08_CORE = fake08_libretro.so -fake-08_BUILD_PATH = fake-08/platform/libretro - -fceumm_REPO = https://github.com/libretro/libretro-fceumm - -gambatte_REPO = https://github.com/libretro/gambatte-libretro - -mednafen_supafaust_REPO = https://github.com/libretro/supafaust - -pcsx_rearmed_MAKEFILE = Makefile.libretro -pcsx_rearmed_HASH = 87a0a631 - -picodrive_REPO = https://github.com/irixxxx/picodrive -picodrive_MAKEFILE = Makefile.libretro - -pokemini_REPO = https://github.com/libretro/PokeMini -pokemini_MAKEFILE = Makefile.libretro - -snes9x2005_plus_REPO = https://github.com/libretro/snes9x2005 -snes9x2005_plus_FLAGS = USE_BLARGG_APU=1 - -############################### - -include ../../all/cores/makefile \ No newline at end of file diff --git a/workspace/_unmaintained/gkdpixel/cores/patches/pcsx_rearmed.patch b/workspace/_unmaintained/gkdpixel/cores/patches/pcsx_rearmed.patch deleted file mode 100644 index 3316547c8..000000000 --- a/workspace/_unmaintained/gkdpixel/cores/patches/pcsx_rearmed.patch +++ /dev/null @@ -1,44 +0,0 @@ -diff --git a/Makefile.libretro b/Makefile.libretro -index 1169d89..0746529 100644 ---- a/Makefile.libretro -+++ b/Makefile.libretro -@@ -530,6 +530,19 @@ else ifneq (,$(findstring armv,$(platform))) - ARCH = arm - DYNAREC = ari64 - -+# GCW0 -+else ifeq ($(platform), gcw0) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = /opt/gcw0-toolchain/usr/bin/mipsel-linux-gcc -+ CXX = /opt/gcw0-toolchain/usr/bin/mipsel-linux-g++ -+ fpic := -fPIC -+ CFLAGS += -fomit-frame-pointer -ffast-math -march=mips32 -mtune=mips32r2 -mhard-float -+ CFLAGS += -D_DINGUX -std=gnu99 -+ ARCH = mips -+ BUILTIN_GPU = unai -+ DYNAREC = lightrec -+ HAVE_NEON = 0 -+ - else ifeq ($(platform), miyoo) - TARGET := $(TARGET_NAME)_libretro.so - fpic := -fPIC -diff --git a/deps/lightrec/lightrec-private.h b/deps/lightrec/lightrec-private.h -index 0df9f93..1174f6c 100644 ---- a/deps/lightrec/lightrec-private.h -+++ b/deps/lightrec/lightrec-private.h -@@ -56,11 +56,11 @@ - #define SET_DEFAULT_ELM(table, value) [0] = NULL - #endif - --#if __has_attribute(__fallthrough__) --# define fallthrough __attribute__((__fallthrough__)) --#else -+// #if __has_attribute(__fallthrough__) -+// # define fallthrough __attribute__((__fallthrough__)) -+// #else - # define fallthrough do {} while (0) /* fallthrough */ --#endif -+// #endif - - #define container_of(ptr, type, member) \ - ((type *)((void *)(ptr) - offsetof(type, member))) diff --git a/workspace/_unmaintained/gkdpixel/input/input.c b/workspace/_unmaintained/gkdpixel/input/input.c deleted file mode 100644 index e0601df28..000000000 --- a/workspace/_unmaintained/gkdpixel/input/input.c +++ /dev/null @@ -1,82 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - - -// for ev.value -#define RELEASED 0 -#define PRESSED 1 -#define REPEAT 2 - -#define INPUT_COUNT 4 -static int inputs[INPUT_COUNT]; -static struct input_event ev; - -#define O_CLOEXEC 0 - -void raw_input(void) { - puts("raw"); fflush(stdout); - char path[32]; - for (int i=0; i10) return; - } - } - usleep(16666); - } -} - -void sdl_input(void) { - SDL_Init(SDL_INIT_VIDEO); - puts("sdl"); fflush(stdout); - - SDL_SetVideoMode(0,0,0,0); - int count = 0; - - while (1) { - SDL_Event event; - while (SDL_PollEvent(&event)) { - if (event.type==SDL_KEYDOWN || event.type==SDL_KEYUP) { - uint8_t code = event.key.keysym.scancode; - uint8_t pressed = event.type==SDL_KEYDOWN; - printf("key event: %i (%i)\n", code,pressed); fflush(stdout); - } - - count += 1; - if (count>10) return; - } - } - SDL_Quit(); -} - -int main (int argc, char *argv[]) { - // printf("input.elf\n"); fflush(stdout); - // raw_input(); - sdl_input(); -} diff --git a/workspace/_unmaintained/gkdpixel/input/input.txt b/workspace/_unmaintained/gkdpixel/input/input.txt deleted file mode 100755 index 965ede797..000000000 --- a/workspace/_unmaintained/gkdpixel/input/input.txt +++ /dev/null @@ -1,94 +0,0 @@ -path 0: /dev/input/event0 -path 1: /dev/input/event1 -path 2: /dev/input/event2 -path 3: /dev/input/event3 - -input: 0 type:1 code:103 value:1 UP -input: 2 type:1 code:103 value:1 -input: 0 type:1 code:103 value:0 -input: 2 type:1 code:103 value:0 - -input: 0 type:1 code:108 value:1 DOWN -input: 2 type:1 code:108 value:1 -input: 0 type:1 code:108 value:0 -input: 2 type:1 code:108 value:0 - -input: 0 type:1 code:105 value:1 LEFT -input: 2 type:1 code:105 value:1 -input: 0 type:1 code:105 value:0 -input: 2 type:1 code:105 value:0 - -input: 0 type:1 code:106 value:1 RIGHT -input: 2 type:1 code:106 value:1 -input: 0 type:1 code:106 value:0 -input: 2 type:1 code:106 value:0 - -input: 0 type:1 code:57 value:1 X -input: 2 type:1 code:57 value:1 -input: 0 type:1 code:57 value:0 -input: 2 type:1 code:57 value:0 - -input: 0 type:1 code:56 value:1 B -input: 2 type:1 code:56 value:1 -input: 0 type:1 code:56 value:0 -input: 2 type:1 code:56 value:0 - -input: 0 type:1 code:42 value:1 Y -input: 2 type:1 code:42 value:1 -input: 0 type:1 code:42 value:0 -input: 2 type:1 code:42 value:0 - -input: 0 type:1 code:29 value:1 A -input: 2 type:1 code:29 value:1 -input: 0 type:1 code:29 value:0 -input: 2 type:1 code:29 value:0 - -input: 0 type:1 code:1 value:1 SELECT -input: 2 type:1 code:1 value:1 -input: 0 type:1 code:1 value:0 -input: 2 type:1 code:1 value:0 - -input: 0 type:1 code:28 value:1 START -input: 2 type:1 code:28 value:1 -input: 0 type:1 code:28 value:0 -input: 2 type:1 code:28 value:0 - -input: 0 type:1 code:15 value:1 L1 -input: 2 type:1 code:15 value:1 -input: 0 type:1 code:15 value:0 -input: 2 type:1 code:15 value:0 - -input: 0 type:1 code:104 value:1 L2 -input: 2 type:1 code:104 value:1 -input: 0 type:1 code:104 value:0 -input: 2 type:1 code:104 value:0 - -input: 0 type:1 code:109 value:1 R2 -input: 2 type:1 code:109 value:1 -input: 0 type:1 code:109 value:0 -input: 2 type:1 code:109 value:0 - -input: 0 type:1 code:14 value:1 R1 -input: 2 type:1 code:14 value:1 -input: 0 type:1 code:14 value:0 -input: 2 type:1 code:14 value:0 - -input: 0 type:1 code:78 value:1 PLUS -input: 2 type:1 code:78 value:1 -input: 0 type:1 code:78 value:0 -input: 2 type:1 code:78 value:0 - -input: 0 type:1 code:74 value:1 MINUS -input: 2 type:1 code:74 value:1 -input: 0 type:1 code:74 value:0 -input: 2 type:1 code:74 value:0 - -input: 0 type:1 code:102 value:1 MENU -input: 2 type:1 code:102 value:1 -input: 0 type:1 code:102 value:0 -input: 2 type:1 code:102 value:0 - -input: 3 type:1 code:116 value:1 POWER (killall -9 power_daemon) -input: 3 type:1 code:116 value:0 -input: 3 type:1 code:116 value:1 -input: 3 type:1 code:116 value:0 diff --git a/workspace/_unmaintained/gkdpixel/input/makefile b/workspace/_unmaintained/gkdpixel/input/makefile deleted file mode 100755 index f9d359fbc..000000000 --- a/workspace/_unmaintained/gkdpixel/input/makefile +++ /dev/null @@ -1,18 +0,0 @@ -#keymon - -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif - -TARGET = input - -CC = $(CROSS_COMPILE)gcc -CFLAGS = -Os -std=gnu99 -lSDL -lrt -ldl -Wl,--gc-sections -s -# -lmsettings -lpthread -CFLAGS += -I. -DPLATFORM=\"$(UNION_PLATFORM)\" -# -I../../all/common -I../platform/ - -all: - $(CC) $(TARGET).c -o $(TARGET).elf $(CFLAGS) -clean: - rm -rf $(TARGET).elf \ No newline at end of file diff --git a/workspace/_unmaintained/gkdpixel/install/install.sh b/workspace/_unmaintained/gkdpixel/install/install.sh deleted file mode 100755 index 918508d8e..000000000 --- a/workspace/_unmaintained/gkdpixel/install/install.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -# make sure frontend_start stays up to date -cp /media/roms/.system/gkdpixel/dat/boot.sh /usr/sbin/frontend_start \ No newline at end of file diff --git a/workspace/_unmaintained/gkdpixel/keymon/credits.txt b/workspace/_unmaintained/gkdpixel/keymon/credits.txt deleted file mode 100644 index e885e5dd1..000000000 --- a/workspace/_unmaintained/gkdpixel/keymon/credits.txt +++ /dev/null @@ -1,3 +0,0 @@ -based on eggs custom keymon for Trimui: - https://www.dropbox.com/sh/5e9xwvp672vt8cr/AABUIdw1vLYp9h0waoCUqHPOa/source?dl=0&subfolder_nav_tracking=1 -modified to use libmsettings \ No newline at end of file diff --git a/workspace/_unmaintained/gkdpixel/keymon/keymon.c b/workspace/_unmaintained/gkdpixel/keymon/keymon.c deleted file mode 100644 index fd8eda27d..000000000 --- a/workspace/_unmaintained/gkdpixel/keymon/keymon.c +++ /dev/null @@ -1,148 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include "defines.h" - -#define VOLUME_MIN 0 -#define VOLUME_MAX 20 -#define BRIGHTNESS_MIN 0 -#define BRIGHTNESS_MAX 10 - -// for ev.value -#define RELEASED 0 -#define PRESSED 1 -#define REPEAT 2 - -static int input_fd = 0; -static struct input_event ev; - -int main (int argc, char *argv[]) { - InitSettings(); - - input_fd = open("/dev/input/event0", O_RDONLY | O_NONBLOCK); - - uint32_t input; - uint32_t val; - uint32_t menu_pressed = 0; - - uint32_t up_pressed = 0; - uint32_t up_just_pressed = 0; - uint32_t up_repeat_at = 0; - - uint32_t down_pressed = 0; - uint32_t down_just_pressed = 0; - uint32_t down_repeat_at = 0; - - uint8_t ignore; - uint32_t then; - uint32_t now; - struct timeval tod; - - // TODO: tmp - // uint32_t l1_pressed = 0; - // uint32_t r1_pressed = 0; - // uint32_t select_pressed = 0; - // uint32_t start_pressed = 0; - - gettimeofday(&tod, NULL); - then = tod.tv_sec * 1000 + tod.tv_usec / 1000; // essential SDL_GetTicks() - ignore = 0; - - while (1) { - gettimeofday(&tod, NULL); - now = tod.tv_sec * 1000 + tod.tv_usec / 1000; - if (now-then>1000) ignore = 1; // ignore input that arrived during sleep - - while(read(input_fd, &ev, sizeof(ev))==sizeof(ev)) { - if (ignore) continue; - val = ev.value; - - if (( ev.type != EV_KEY ) || ( val > REPEAT )) continue; - // printf("code: %i (%i)\n", ev.code, val); fflush(stdout); - switch (ev.code) { - case CODE_MENU: - menu_pressed = val; - break; - break; - case CODE_PLUS: - up_pressed = up_just_pressed = val; - if (val) up_repeat_at = now + 300; - break; - case CODE_MINUS: - down_pressed = down_just_pressed = val; - if (val) down_repeat_at = now + 300; - break; - // TODO: tmp - // case CODE_L1: l1_pressed = val; break; - // case CODE_R1: r1_pressed = val; break; - // case CODE_START: start_pressed = val; break; - // case CODE_SELECT: select_pressed = val; break; - default: - break; - } - } - - if (ignore) { - menu_pressed = 0; - up_pressed = up_just_pressed = 0; - down_pressed = down_just_pressed = 0; - up_repeat_at = 0; - down_repeat_at = 0; - } - - // TODO: tmp - // if (l1_pressed && r1_pressed && start_pressed && select_pressed) { - // system("sync && killall -9 minarch.elf"); // TODO: tmp - // system("sync && killall -9 launch.sh"); // TODO: tmp - // } - - if (up_just_pressed || (up_pressed && now>=up_repeat_at)) { - if (menu_pressed) { - // printf("brightness up\n"); fflush(stdout); - val = GetBrightness(); - if (val=down_repeat_at)) { - if (menu_pressed) { - // printf("brightness down\n"); fflush(stdout); - val = GetBrightness(); - if (val>BRIGHTNESS_MIN) SetBrightness(--val); - } - else { - // printf("volume down\n"); fflush(stdout); - val = GetVolume(); - if (val>VOLUME_MIN) SetVolume(--val); - } - - if (down_just_pressed) down_just_pressed = 0; - else down_repeat_at += 100; - } - - then = now; - ignore = 0; - - usleep(16666); // 60fps - } -} diff --git a/workspace/_unmaintained/gkdpixel/keymon/makefile b/workspace/_unmaintained/gkdpixel/keymon/makefile deleted file mode 100755 index b51481434..000000000 --- a/workspace/_unmaintained/gkdpixel/keymon/makefile +++ /dev/null @@ -1,14 +0,0 @@ -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif - -TARGET = keymon -PRODUCT = $(TARGET).elf - -CC = $(CROSS_COMPILE)gcc -I../../all/common/ -I../platform/ -std=gnu99 -FLAGS = -Os -lmsettings -lpthread -lrt -ldl -Wl,--gc-sections -s - -all: - $(CC) $(TARGET).c -o $(PRODUCT) $(FLAGS) -clean: - rm -rf $(PRODUCT) \ No newline at end of file diff --git a/workspace/_unmaintained/gkdpixel/libmsettings/makefile b/workspace/_unmaintained/gkdpixel/libmsettings/makefile deleted file mode 100644 index b1418a21d..000000000 --- a/workspace/_unmaintained/gkdpixel/libmsettings/makefile +++ /dev/null @@ -1,32 +0,0 @@ -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif -ifeq (,$(PREFIX)) -$(error missing PREFIX for this toolchain) -endif - -TARGET=msettings - -.PHONY: build -.PHONY: clean - -CC = $(CROSS_COMPILE)gcc - -SYSROOT := $(shell $(CC) --print-sysroot) - -INCLUDEDIR = $(SYSROOT)/usr/include -CFLAGS = -I$(INCLUDEDIR) -LDFLAGS = -ldl -lrt -s - -OPTM=-Ofast - -build: - $(CC) -c -Werror -fpic "$(TARGET).c" -Wl,--no-as-needed $(LDFLAGS) - $(CC) -shared -o "lib$(TARGET).so" "$(TARGET).o" $(LDFLAGS) - cp "$(TARGET).h" "$(PREFIX)/include" - cp "lib$(TARGET).so" "$(PREFIX)/lib" -clean: - rm -f *.o - rm -f "lib$(TARGET).so" - rm -f $(PREFIX)/include/$(TARGET).h - rm -f $(PREFIX)/lib/lib$(TARGET).so \ No newline at end of file diff --git a/workspace/_unmaintained/gkdpixel/libmsettings/msettings.c b/workspace/_unmaintained/gkdpixel/libmsettings/msettings.c deleted file mode 100644 index d62776420..000000000 --- a/workspace/_unmaintained/gkdpixel/libmsettings/msettings.c +++ /dev/null @@ -1,188 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "msettings.h" - -/////////////////////////////////////// - -#define SETTINGS_VERSION 2 -typedef struct Settings { - int version; // future proofing - int brightness; - int headphones; - int speaker; - int unused[2]; // for future use - // NOTE: doesn't really need to be persisted but still needs to be shared - int jack; - int hdmi; -} Settings; -static Settings DefaultSettings = { - .version = SETTINGS_VERSION, - .brightness = 2, - .headphones = 4, - .speaker = 8, - .jack = 0, - .hdmi = 0, -}; -static Settings* settings; - -#define SHM_KEY "/SharedSettings" -static char SettingsPath[256]; -static int shm_fd = -1; -static int is_host = 0; -static int shm_size = sizeof(Settings); - -int getInt(char* path) { - int i = 0; - FILE *file = fopen(path, "r"); - if (file!=NULL) { - fscanf(file, "%i", &i); - fclose(file); - } - return i; -} - -void InitSettings(void) { - sprintf(SettingsPath, "%s/msettings.bin", getenv("USERDATA_PATH")); - - shm_fd = shm_open(SHM_KEY, O_RDWR | O_CREAT | O_EXCL, 0644); // see if it exists - if (shm_fd==-1 && errno==EEXIST) { // already exists - puts("Settings client"); - shm_fd = shm_open(SHM_KEY, O_RDWR, 0644); - settings = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); - } - else { // host - puts("Settings host"); // should always be keymon - is_host = 1; - // we created it so set initial size and populate - ftruncate(shm_fd, shm_size); - settings = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); - - int fd = open(SettingsPath, O_RDONLY); - if (fd>=0) { - read(fd, settings, shm_size); - // TODO: use settings->version for future proofing? - close(fd); - } - else { - // load defaults - memcpy(settings, &DefaultSettings, shm_size); - } - - // these shouldn't be persisted - // settings->jack = 0; - // settings->hdmi = 0; - } - - int jack = 0; - int hdmi = 0; - printf("brightness: %i (hdmi: %i)\nspeaker: %i (jack: %i)\n", settings->brightness, hdmi, settings->speaker, jack); fflush(stdout); - - SetBrightness(GetBrightness()); - // system("echo $(< " BRIGHTNESS_PATH ")"); -} -void QuitSettings(void) { - munmap(settings, shm_size); - if (is_host) shm_unlink(SHM_KEY); -} -static inline void SaveSettings(void) { - int fd = open(SettingsPath, O_CREAT|O_WRONLY, 0644); - if (fd>=0) { - write(fd, settings, shm_size); - close(fd); - sync(); - } -} - -int GetBrightness(void) { // 0-10 - return settings->brightness; -} -void SetBrightness(int value) { - if (settings->hdmi) return; - - // TODO: this needs a curve, 1,10,20,30 are - // indistinguishable, even in near dark - int raw = value * 10; - if (!raw) raw = 5; - - SetRawBrightness(raw); - settings->brightness = value; - SaveSettings(); -} - -int GetVolume(void) { // 0-20 - return settings->jack ? settings->headphones : settings->speaker; -} -void SetVolume(int value) { - if (settings->hdmi) return; - - if (settings->jack) settings->headphones = value; - else settings->speaker = value; - - int raw = value * 5; - SetRawVolume(raw); - SaveSettings(); -} - -#define DISP_LCD_SET_BRIGHTNESS 0x102 -void SetRawBrightness(int val) { // 0 - 100 - if (settings->hdmi) return; - - // TODO: setting to 0 prevents the screen from coming back on - - // printf("SetRawBrightness(%i)\n", val); fflush(stdout); - char cmd[256]; - sprintf(cmd, "echo %i > /sys/devices/platform/jz-pwm-dev.0/jz-pwm/pwm0/dutyratio", val); - system(cmd); -} -void SetRawVolume(int val) { // 0 - 100 - // printf("SetRawVolume(%i)\n", val); fflush(stdout); - - // TODO: this is still weird - if (val) val = 60 + (val * 2) / 5; - char cmd[256]; - sprintf(cmd, "amixer sset 'PCM' %i%% > /dev/null 2>&1", val); - // // puts(cmd); fflush(stdout); - system(cmd); -} - -// monitored and set by thread in keymon -int GetJack(void) { - return settings->jack; -} -void SetJack(int value) { - // printf("SetJack(%i)\n", value); fflush(stdout); - - // char cmd[256]; - // sprintf(cmd, "amixer cset name='Playback Path' '%s' &> /dev/null", value?"HP":"SPK"); - // system(cmd); - - settings->jack = value; - SetVolume(GetVolume()); -} - -int GetHDMI(void) { - // printf("GetHDMI() %i\n", settings->hdmi); fflush(stdout); - return settings->hdmi; -} -void SetHDMI(int value) { - // printf("SetHDMI(%i)\n", value); fflush(stdout); - - // if (settings->hdmi!=value) system("/usr/lib/autostart/common/055-hdmi-check"); - - settings->hdmi = value; - if (value) SetRawVolume(100); // max - else SetVolume(GetVolume()); // restore -} - -int GetMute(void) { return 0; } -void SetMute(int value) {} diff --git a/workspace/_unmaintained/gkdpixel/libmsettings/msettings.h b/workspace/_unmaintained/gkdpixel/libmsettings/msettings.h deleted file mode 100644 index 47e5fb003..000000000 --- a/workspace/_unmaintained/gkdpixel/libmsettings/msettings.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef __msettings_h__ -#define __msettings_h__ - -void InitSettings(void); -void QuitSettings(void); - -int GetBrightness(void); -int GetVolume(void); - -void SetRawBrightness(int value); // 0-1024 -void SetRawVolume(int value); // 0-40 - -void SetBrightness(int value); // 0-10 -void SetVolume(int value); // 0-20 - -int GetJack(void); -void SetJack(int value); // 0-1 - -int GetHDMI(void); -void SetHDMI(int value); // 0-1 - -int GetMute(void); -void SetMute(int value); // 0-1 - -#endif // __msettings_h__ diff --git a/workspace/_unmaintained/gkdpixel/makefile b/workspace/_unmaintained/gkdpixel/makefile deleted file mode 100644 index 983d5bc26..000000000 --- a/workspace/_unmaintained/gkdpixel/makefile +++ /dev/null @@ -1,19 +0,0 @@ -########################################################### - -ifeq (,$(PLATFORM)) -PLATFORM=$(UNION_PLATFORM) -endif - -ifeq (,$(PLATFORM)) -$(error please specify PLATFORM, eg. PLATFORM=trimui make) -endif - -########################################################### - -all: readmes - -early: - -clean: - -include ../all/readmes/makefile \ No newline at end of file diff --git a/workspace/_unmaintained/gkdpixel/platform/makefile.copy b/workspace/_unmaintained/gkdpixel/platform/makefile.copy deleted file mode 100644 index c58e1bf96..000000000 --- a/workspace/_unmaintained/gkdpixel/platform/makefile.copy +++ /dev/null @@ -1,4 +0,0 @@ -$(PLATFORM): - cp ./workspace/$@/install/install.sh ./build/SYSTEM/$@/bin/ - cp ./workspace/$@/boot/boot.sh ./build/SYSTEM/$@/dat/ - cp -r ./workspace/$@/boot/ ./build/BASE/$@/ \ No newline at end of file diff --git a/workspace/_unmaintained/gkdpixel/platform/makefile.env b/workspace/_unmaintained/gkdpixel/platform/makefile.env deleted file mode 100644 index 95303db21..000000000 --- a/workspace/_unmaintained/gkdpixel/platform/makefile.env +++ /dev/null @@ -1,3 +0,0 @@ -# gkdpixel -ARCH = -std=gnu99 -LIBS = -flto diff --git a/workspace/_unmaintained/gkdpixel/platform/platform.c b/workspace/_unmaintained/gkdpixel/platform/platform.c deleted file mode 100644 index 0b4b0811c..000000000 --- a/workspace/_unmaintained/gkdpixel/platform/platform.c +++ /dev/null @@ -1,689 +0,0 @@ -// gkdpixel -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include "defines.h" -#include "platform.h" -#include "api.h" -#include "utils.h" - -#include "scaler.h" - -/////////////////////////////// - -void PLAT_initInput(void) { - // buh -} - -void PLAT_quitInput(void) { - // buh -} - -/////////////////////////////// - -static struct VID_Context { - SDL_Surface* screen; - GFX_Renderer* renderer; -} vid; -static int _; - -SDL_Surface* PLAT_initVideo(void) { - SDL_Init(SDL_INIT_VIDEO); - SDL_ShowCursor(0); - - vid.screen = SDL_SetVideoMode(FIXED_WIDTH, FIXED_HEIGHT, FIXED_DEPTH, SDL_HWSURFACE | SDL_TRIPLEBUF); - PLAT_clearVideo(vid.screen); - - return vid.screen; -} - -void PLAT_quitVideo(void) { - SDL_Quit(); -} - -void PLAT_clearVideo(SDL_Surface* IGNORED) { - memset(vid.screen->pixels, 0, FIXED_SIZE); -} -void PLAT_clearAll(void) { - PLAT_clearVideo(vid.screen); -} - -void PLAT_setVsync(int vsync) { - // buh -} - -SDL_Surface* PLAT_resizeVideo(int w, int h, int pitch) { - PLAT_clearVideo(vid.screen); - return vid.screen; -} - -void PLAT_setVideoScaleClip(int x, int y, int width, int height) { - // buh -} -void PLAT_setNearestNeighbor(int enabled) { - // buh -} -void PLAT_setSharpness(int sharpness) { - // buh -} -void PLAT_setEffect(int effect) { - // buh -} -void PLAT_vsync(int remaining) { - if (remaining>0) SDL_Delay(remaining); -} - -// from https://github.com/jdgleaver/ReGBA/blob/master/source/opendingux/draw.c#L972 -/*************************************************************************** - * Scaler copyright (C) 2013 by Paul Cercueil * - * paul@crapouillou.net * - ***************************************************************************/ - -// Explaining the magic constants: -// F7DEh is the mask to remove the lower bit of all color -// components before dividing them by 2. Otherwise, the lower bit -// would bleed into the high bit of the next component. - -// RRRRR GGGGGG BBBBB RRRRR GGGGGG BBBBB -// 11110 111110 11110 [>> 1] 01111 011111 01111 - -// 0821h is the mask to gather the low bits again for averaging -// after discarding them. - -// RRRRR GGGGGG BBBBB RRRRR GGGGGG BBBBB -// 00001 000001 00001 [+ X] 00010 000010 00010 - -// E79Ch is the mask to remove the lower 2 bits of all color -// components before dividing them by 4. Otherwise, the lower bits -// would bleed into the high bits of the next component. - -// RRRRR GGGGGG BBBBB RRRRR GGGGGG BBBBB -// 11100 111100 11100 [>> 2] 00111 001111 00111 - -// 1863h is the mask to gather the low bits again for averaging -// after discarding them. - -// RRRRR GGGGGG BBBBB RRRRR GGGGGG BBBBB -// 00011 000011 00011 [+ X] 00110 000110 00110 - -/* Calculates the average of two RGB565 pixels. The source of the pixels is - * the lower 16 bits of both parameters. The result is in the lower 16 bits. - */ - -#define MAGIC_VAL1 0xF7DEu -#define MAGIC_VAL2 0x0821u -#define MAGIC_VAL3 0xE79Cu -#define MAGIC_VAL4 0x1863u -#define MAGIC_DOUBLE(n) ((n << 16) | n) -#define MAGIC_VAL1D MAGIC_DOUBLE(MAGIC_VAL1) -#define MAGIC_VAL2D MAGIC_DOUBLE(MAGIC_VAL2) -#define Average(A, B) ((((A) & MAGIC_VAL1) >> 1) + (((B) & MAGIC_VAL1) >> 1) + ((A) & (B) & MAGIC_VAL2)) - -/* Calculates the average of two RGB565 pixels. The source of the pixels is - * the lower 16 bits of both parameters. The result is in the lower 16 bits. - * The average is weighted so that the first pixel contributes 3/4 of its - * color and the second pixel contributes 1/4. */ -#define AverageQuarters3_1(A, B) ( (((A) & MAGIC_VAL1) >> 1) + (((A) & MAGIC_VAL3) >> 2) + (((B) & MAGIC_VAL3) >> 2) + ((( (( ((A) & MAGIC_VAL4) + ((A) & MAGIC_VAL2) ) << 1) + ((B) & MAGIC_VAL4) ) >> 2) & MAGIC_VAL4) ) - -#define RED_FROM_NATIVE(rgb565) (((rgb565) >> 11) & 0x1F) -#define RED_TO_NATIVE(r) (((r) & 0x1F) << 11) -#define GREEN_FROM_NATIVE(rgb565) (((rgb565) >> 5) & 0x3F) -#define GREEN_TO_NATIVE(g) (((g) & 0x3F) << 5) -#define BLUE_FROM_NATIVE(rgb565) ((rgb565) & 0x1F) -#define BLUE_TO_NATIVE(b) ((b) & 0x1F) - - -#ifdef __GNUC__ -# define likely(x) __builtin_expect((x),1) -# define unlikely(x) __builtin_expect((x),0) -# define prefetch(x, y) __builtin_prefetch((x),(y)) -#else -# define likely(x) (x) -# define unlikely(x) (x) -# define prefetch(x, y) -#endif - -/* - * Approximately bilinear scalers - * - * Copyright (C) 2019 hi-ban, Nebuleon - * - * This function and all auxiliary functions are free software; you can - * redistribute them and/or modify them under the terms of the GNU Lesser - * General Public License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * These functions are distributed in the hope that they will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -//from RGB565 -#define cR(A) (((A) & 0xf800) >> 11) -#define cG(A) (((A) & 0x7e0) >> 5) -#define cB(A) ((A) & 0x1f) -//to RGB565 -#define Weight1_1(A, B) ((((cR(A) + cR(B)) >> 1) & 0x1f) << 11 | (((cG(A) + cG(B)) >> 1) & 0x3f) << 5 | (((cB(A) + cB(B)) >> 1) & 0x1f)) -#define Weight1_2(A, B) ((((cR(A) + (cR(B) << 1)) / 3) & 0x1f) << 11 | (((cG(A) + (cG(B) << 1)) / 3) & 0x3f) << 5 | (((cB(A) + (cB(B) << 1)) / 3) & 0x1f)) -#define Weight2_1(A, B) ((((cR(B) + (cR(A) << 1)) / 3) & 0x1f) << 11 | (((cG(B) + (cG(A) << 1)) / 3) & 0x3f) << 5 | (((cB(B) + (cB(A) << 1)) / 3) & 0x1f)) -#define Weight1_3(A, B) ((((cR(A) + (cR(B) * 3)) >> 2) & 0x1f) << 11 | (((cG(A) + (cG(B) * 3)) >> 2) & 0x3f) << 5 | (((cB(A) + (cB(B) * 3)) >> 2) & 0x1f)) -#define Weight3_1(A, B) ((((cR(B) + (cR(A) * 3)) >> 2) & 0x1f) << 11 | (((cG(B) + (cG(A) * 3)) >> 2) & 0x3f) << 5 | (((cB(B) + (cB(A) * 3)) >> 2) & 0x1f)) -#define Weight1_4(A, B) ((((cR(A) + (cR(B) << 2)) / 5) & 0x1f) << 11 | (((cG(A) + (cG(B) << 2)) / 5) & 0x3f) << 5 | (((cB(A) + (cB(B) << 2)) / 5) & 0x1f)) -#define Weight4_1(A, B) ((((cR(B) + (cR(A) << 2)) / 5) & 0x1f) << 11 | (((cG(B) + (cG(A) << 2)) / 5) & 0x3f) << 5 | (((cB(B) + (cB(A) << 2)) / 5) & 0x1f)) -#define Weight2_3(A, B) (((((cR(A) << 1) + (cR(B) * 3)) / 5) & 0x1f) << 11 | ((((cG(A) << 1) + (cG(B) * 3)) / 5) & 0x3f) << 5 | ((((cB(A) << 1) + (cB(B) * 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)) - -static inline uint16_t SUBPIXEL_3_1(uint16_t A, uint16_t B) { - return RED_TO_NATIVE(RED_FROM_NATIVE(A)) - | GREEN_TO_NATIVE(GREEN_FROM_NATIVE(A) * 3 / 4 + GREEN_FROM_NATIVE(B) * 1 / 4) - | BLUE_TO_NATIVE(BLUE_FROM_NATIVE(A) * 1 / 4 + BLUE_FROM_NATIVE(B) * 3 / 4); -} - -static inline uint16_t SUBPIXEL_1_1(uint16_t A, uint16_t B) { - return RED_TO_NATIVE(RED_FROM_NATIVE(A) * 3 / 4 + RED_FROM_NATIVE(B) * 1 / 4) - | GREEN_TO_NATIVE(GREEN_FROM_NATIVE(A) * 1 / 2 + GREEN_FROM_NATIVE(B) * 1 / 2) - | BLUE_TO_NATIVE(BLUE_FROM_NATIVE(A) * 1 / 4 + BLUE_FROM_NATIVE(B) * 3 / 4); -} - -static inline uint16_t SUBPIXEL_1_3(uint16_t A, uint16_t B) { - return RED_TO_NATIVE(RED_FROM_NATIVE(B) * 1 / 4 + RED_FROM_NATIVE(A) * 3 / 4) - | GREEN_TO_NATIVE(GREEN_FROM_NATIVE(B) * 3 / 4 + GREEN_FROM_NATIVE(A) * 1 / 4) - | BLUE_TO_NATIVE(BLUE_FROM_NATIVE(B)); -} - -static inline uint16_t SUBPIXEL_2_1(uint16_t A, uint16_t B) { - return RED_TO_NATIVE(RED_FROM_NATIVE(A)) - | GREEN_TO_NATIVE(GREEN_FROM_NATIVE(A) * 2 / 3 + GREEN_FROM_NATIVE(B) * 1 / 3) - | BLUE_TO_NATIVE(BLUE_FROM_NATIVE(A) * 1 / 3 + BLUE_FROM_NATIVE(B) * 2 / 3); -} - -static inline uint16_t SUBPIXEL_1_2(uint16_t A, uint16_t B) { - return RED_TO_NATIVE(RED_FROM_NATIVE(B) * 1 / 3 + RED_FROM_NATIVE(A) * 2 / 3) - | GREEN_TO_NATIVE(GREEN_FROM_NATIVE(B) * 2 / 3 + GREEN_FROM_NATIVE(A) * 1 / 3) - | BLUE_TO_NATIVE(BLUE_FROM_NATIVE(B)); -} - - -static inline uint16_t AVERAGE_1_1(uint16_t A, uint16_t B) { - return ((((A) & MAGIC_VAL1) >> 1) + (((B) & MAGIC_VAL1) >> 1) + ((A) & (B) & MAGIC_VAL2)); -} -static inline uint16_t AVERAGE_3_1(uint16_t A, uint16_t B) { - return ( (((A) & MAGIC_VAL1) >> 1) + (((A) & MAGIC_VAL3) >> 2) + (((B) & MAGIC_VAL3) >> 2) + ((( (( ((A) & MAGIC_VAL4) + ((A) & MAGIC_VAL2) ) << 1) + ((B) & MAGIC_VAL4) ) >> 2) & MAGIC_VAL4) ); -} - -// TODO: not sure how to create AVERAGE_2_1() using the above MAGIC values -#define AVERAGE_2_1 Weight2_1 // TODO: the WeightX_Y macros serve a similar (the same?) purpose -#define AVERAGE_1_2 Weight1_2 // TODO: the WeightX_Y macros serve a similar (the same?) purpose - -static inline void scale_240x160_320x213(void* __restrict src_, void* __restrict dst_, uint32_t src_w, uint32_t src_h, uint32_t src_pitch, uint32_t dst_w, uint32_t dst_h, uint32_t dst_pitch) { - uint16_t* src = src_; - uint16_t* dst = dst_; - - const uint32_t src_skip = src_pitch - src_w * FIXED_BPP; - const uint32_t dst_skip = dst_pitch - dst_w * FIXED_BPP; - - // upscale 3x3 pixel chunks to 4x4 - for (uint_fast16_t chunk_y=0; chunk_yscale) { - case 6: return scale6x6_c16; - case 5: return scale5x5_c16; - case 4: return scale4x4_c16; - case 3: return scale3x3_c16; - case 2: return scale2x2_c16; - case -1: { - if (renderer->src_w==256 && renderer->src_h==224) { - // TODO: can I fudge this here to fix minarch menu scaled preview? nope. - // renderer->dst_x = 0; - // renderer->dst_y = 1; - // renderer->dst_w = 320; - // renderer->dst_h = 238; - return scale_256x224_320x238; - } - if (renderer->src_w==240 && renderer->src_h==160) return renderer->dst_h==240 ? GFX_getAAScaler(renderer) : scale_240x160_320x213; - if (renderer->src_w==160 && renderer->src_h==144) return renderer->dst_w==320 ? GFX_getAAScaler(renderer) : scale_160x144_266x240; - else return GFX_getAAScaler(renderer); - } - default: return scale1x1_c16; - } -} - -void PLAT_blitRenderer(GFX_Renderer* renderer) { - void* src = renderer->src + (renderer->src_y * renderer->src_p) + (renderer->src_x * FIXED_BPP); - void* dst = renderer->dst + (renderer->dst_y * renderer->dst_p) + (renderer->dst_x * FIXED_BPP); - ((scaler_t)renderer->blit)(src,dst,renderer->src_w,renderer->src_h,renderer->src_p,renderer->dst_w,renderer->dst_h,renderer->dst_p); -} - -void PLAT_flip(SDL_Surface* IGNORED, int sync) { - SDL_Flip(vid.screen); -} - -/////////////////////////////// - -// TODO: -#define OVERLAY_WIDTH PILL_SIZE // unscaled -#define OVERLAY_HEIGHT PILL_SIZE // unscaled -#define OVERLAY_BPP 4 -#define OVERLAY_DEPTH 16 -#define OVERLAY_PITCH (OVERLAY_WIDTH * OVERLAY_BPP) // unscaled -#define OVERLAY_RGBA_MASK 0x00ff0000,0x0000ff00,0x000000ff,0xff000000 // ARGB -static struct OVL_Context { - SDL_Surface* overlay; -} ovl; - -SDL_Surface* PLAT_initOverlay(void) { - // setup surface - ovl.overlay = SDL_CreateRGBSurface(SDL_SWSURFACE, SCALE2(OVERLAY_WIDTH,OVERLAY_HEIGHT),OVERLAY_DEPTH,OVERLAY_RGBA_MASK); - return ovl.overlay; -} -void PLAT_quitOverlay(void) { - if (ovl.overlay) SDL_FreeSurface(ovl.overlay); -} -void PLAT_enableOverlay(int enable) { - // buh -} - - -/////////////////////////////// - -void PLAT_getBatteryStatus(int* is_charging, int* charge) { - PLAT_getBatteryStatusFine(is_charging, charge); - - // worry less about battery and more about the game you're playing - if (*charge>80) *charge = 100; - else if (*charge>60) *charge = 80; - else if (*charge>40) *charge = 60; - else if (*charge>20) *charge = 40; - else if (*charge>10) *charge = 20; - else *charge = 10; -} - -void PLAT_getBatteryStatusFine(int* is_charging, int* charge) -{ - *is_charging = getInt("/sys/class/power_supply/usb/online"); - *charge = getInt("/sys/class/power_supply/battery/capacity"); -} - -void PLAT_enableBacklight(int enable) { - // putInt("/sys/class/graphics/fb0/blank", enable ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN); - if (enable) SetBrightness(GetBrightness()); - else SetRawBrightness(0); -} - -void PLAT_powerOff(void) { - sleep(2); - - SetRawVolume(MUTE_VOLUME_RAW); - PLAT_enableBacklight(0); - SND_quit(); - VIB_quit(); - PWR_quit(); - GFX_quit(); - - touch("/tmp/poweroff"); - exit(0); -} - -/////////////////////////////// - -void PLAT_setCPUSpeed(int speed) { - // buh -} - -void PLAT_setRumble(int strength) { - // buh -} - -int PLAT_pickSampleRate(int requested, int max) { - return MIN(requested, max); -} - -char* PLAT_getModel(void) { - return "GKD Pixel"; -} - -int PLAT_isOnline(void) { - return 0; -} \ No newline at end of file diff --git a/workspace/_unmaintained/gkdpixel/platform/platform.h b/workspace/_unmaintained/gkdpixel/platform/platform.h deleted file mode 100644 index 364528de8..000000000 --- a/workspace/_unmaintained/gkdpixel/platform/platform.h +++ /dev/null @@ -1,124 +0,0 @@ -// gkdpixel/platform/platform.h - -#ifndef PLATFORM_H -#define PLATFORM_H - -/////////////////////////////// - -#include "sdl.h" - -/////////////////////////////// - -#define BUTTON_UP BUTTON_NA -#define BUTTON_DOWN BUTTON_NA -#define BUTTON_LEFT BUTTON_NA -#define BUTTON_RIGHT BUTTON_NA - -#define BUTTON_SELECT BUTTON_NA -#define BUTTON_START BUTTON_NA - -#define BUTTON_A BUTTON_NA -#define BUTTON_B BUTTON_NA -#define BUTTON_X BUTTON_NA -#define BUTTON_Y BUTTON_NA - -#define BUTTON_L1 BUTTON_NA -#define BUTTON_R1 BUTTON_NA -#define BUTTON_L2 BUTTON_NA -#define BUTTON_R2 BUTTON_NA -#define BUTTON_L3 BUTTON_NA -#define BUTTON_R3 BUTTON_NA - -#define BUTTON_MENU BUTTON_NA -#define BUTTON_POWER BUTTON_NA -#define BUTTON_PLUS BUTTON_NA -#define BUTTON_MINUS BUTTON_NA - -/////////////////////////////// - -#define CODE_UP 103 -#define CODE_DOWN 108 -#define CODE_LEFT 105 -#define CODE_RIGHT 106 - -#define CODE_SELECT 1 -#define CODE_START 28 - -#define CODE_A 29 -#define CODE_B 56 -#define CODE_X 57 -#define CODE_Y 42 - -#define CODE_L1 15 -#define CODE_R1 14 -#define CODE_L2 104 -#define CODE_R2 109 -#define CODE_L3 CODE_NA -#define CODE_R3 CODE_NA - -#define CODE_MENU 102 -#define CODE_MENU_ALT 107 -#define CODE_POWER 116 -#define CODE_POWEROFF 68 - -#define CODE_PLUS 78 -#define CODE_MINUS 74 - -/////////////////////////////// - -#define JOY_UP JOY_NA -#define JOY_DOWN JOY_NA -#define JOY_LEFT JOY_NA -#define JOY_RIGHT JOY_NA - -#define JOY_SELECT JOY_NA -#define JOY_START JOY_NA - -#define JOY_A JOY_NA -#define JOY_B JOY_NA -#define JOY_X JOY_NA -#define JOY_Y JOY_NA - -#define JOY_L1 JOY_NA -#define JOY_R1 JOY_NA -#define JOY_L2 JOY_NA -#define JOY_R2 JOY_NA -#define JOY_L3 JOY_NA -#define JOY_R3 JOY_NA - -#define JOY_MENU JOY_NA -#define JOY_POWER JOY_NA -#define JOY_PLUS JOY_NA -#define JOY_MINUS JOY_NA - -/////////////////////////////// - -#define BTN_RESUME BTN_X -#define BTN_SLEEP BTN_POWER -#define BTN_WAKE BTN_POWER -#define BTN_MOD_VOLUME BTN_NONE -#define BTN_MOD_BRIGHTNESS BTN_MENU -#define BTN_MOD_PLUS BTN_PLUS -#define BTN_MOD_MINUS BTN_MINUS - -/////////////////////////////// - -#define FIXED_SCALE 1 -#define FIXED_WIDTH 320 -#define FIXED_HEIGHT 240 -#define FIXED_BPP 2 -#define FIXED_DEPTH (FIXED_BPP * 8) -#define FIXED_PITCH (FIXED_WIDTH * FIXED_BPP) -#define FIXED_SIZE (FIXED_PITCH * FIXED_HEIGHT) - -/////////////////////////////// - -#define SDCARD_PATH "/media/roms" -#define MUTE_VOLUME_RAW 0 -#define USES_SWSCALER - -// this should be set to the devices native screen refresh rate -#define SCREEN_FPS 60.0 -/////////////////////////////// - -#endif diff --git a/workspace/_unmaintained/gkdpixel/test/main.c b/workspace/_unmaintained/gkdpixel/test/main.c deleted file mode 100644 index 56a64b6ce..000000000 --- a/workspace/_unmaintained/gkdpixel/test/main.c +++ /dev/null @@ -1,44 +0,0 @@ -#include - -enum { - FE_OPT_SCALING, - FE_OPT_COUNT, -}; - -typedef struct Option { - char* key; - char* name; -} Option; -typedef struct OptionList { - int count; - Option* options; -} OptionList; - -static struct Config { - OptionList frontend; -} config = { - .frontend = { // (OptionList) - .count = FE_OPT_COUNT, - .options = (Option[]){ - [FE_OPT_SCALING] = { - .key = "minarch_screen_scaling", - }, - [FE_OPT_COUNT] = {NULL} - } - } -}; - -// (OptionList){ -// .count = FE_OPT_COUNT, -// .options =(Option[]){ - // [FE_OPT_SCALING] = { - // .key = "minarch_screen_scaling", - // }, - // [FE_OPT_COUNT] = {NULL} -// } -// } - -int main (int argc, char *argv[]) { - printf("%p\n", config.frontend); - return 0; -} diff --git a/workspace/_unmaintained/gkdpixel/test/makefile b/workspace/_unmaintained/gkdpixel/test/makefile deleted file mode 100755 index 375dc5e93..000000000 --- a/workspace/_unmaintained/gkdpixel/test/makefile +++ /dev/null @@ -1,16 +0,0 @@ -#keymon - -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif - -TARGET = main - -CC = $(CROSS_COMPILE)gcc -CFLAGS = -Os -std=gnu99 -lrt -ldl -Wl,--gc-sections -s -CFLAGS += -I. -DPLATFORM=\"$(UNION_PLATFORM)\" - -all: - $(CC) $(TARGET).c -o $(TARGET).elf $(CFLAGS) -clean: - rm -rf $(TARGET).elf \ No newline at end of file diff --git a/workspace/_unmaintained/m17/boot/boot.sh b/workspace/_unmaintained/m17/boot/boot.sh deleted file mode 100755 index 091e52553..000000000 --- a/workspace/_unmaintained/m17/boot/boot.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/sh - -# NOTE: becomes em_ui.sh - -PLATFORM="m17" -SDCARD_PATH="/sdcard" -UPDATE_PATH="$SDCARD_PATH/NextUI.zip" -SYSTEM_PATH="$SDCARD_PATH/.system" - -# install/update -if [ -f "$UPDATE_PATH" ]; then - if [ ! -d $SYSTEM_PATH ]; then - ACTION=installing - else - ACTION=updating - fi - - # initialize fb0 - cat /sys/class/graphics/fb0/modes > /sys/class/graphics/fb0/mode - - # extract the zip file appended to the end of this script to tmp - CUT=$((`grep -n '^BINARY' $0 | cut -d ':' -f 1 | tail -1` + 1)) - tail -n +$CUT "$0" | uudecode -o /tmp/data - - # unzip and display one of the two images it contains - unzip -o /tmp/data -d /tmp - dd if=/tmp/$ACTION of=/dev/fb0 - sync - - # finally unzip NextUI.zip - unzip -o "$UPDATE_PATH" -d "$SDCARD_PATH" - rm -f "$UPDATE_PATH" - sync - - # the updated system finishes the install/update - $SYSTEM_PATH/$PLATFORM/bin/install.sh # &> $SDCARD_PATH/install.txt - dd if=/dev/zero of=/dev/fb0 -fi - -LAUNCH_PATH="$SYSTEM_PATH/$PLATFORM/paks/NextUI.pak/launch.sh" -while [ -f "$LAUNCH_PATH" ] ; do - taskset 8 "$LAUNCH_PATH" -done - -poweroff # under no circumstances should stock be allowed to touch this card - -exit 0 - diff --git a/workspace/_unmaintained/m17/boot/build.sh b/workspace/_unmaintained/m17/boot/build.sh deleted file mode 100755 index 41713d62d..000000000 --- a/workspace/_unmaintained/m17/boot/build.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/sh - -# based on rg35xx implementation - -TARGET=em_ui.sh - -# remove header from bitmaps -mkdir -p output -if [ ! -f output/installing ]; then - dd bs=54 skip=1 if=installing.bmp of=output/installing -fi -if [ ! -f output/updating ]; then - dd bs=54 skip=1 if=updating.bmp of=output/updating -fi - -cd output - -# zip headerless bitmaps -if [ ! -f data ]; then - zip -r data.zip installing updating - mv data.zip data -fi - -# encode and add to end of boot.sh -cat ../boot.sh > $TARGET -echo BINARY >> $TARGET -uuencode data data >> $TARGET - -# tar missing libs from toolchain -if [ ! -f libpng16.so.16 ] || [ ! -f libSDL2_ttf-2.0.so.0 ]; then - cp /opt/m17-toolchain/usr/arm-buildroot-linux-gnueabihf/sysroot/usr/lib/libpng16.so.16.34.0 libpng16.so.16 - cp /opt/m17-toolchain/usr/arm-buildroot-linux-gnueabihf/sysroot/usr/lib/libSDL2_ttf-2.0.so.0.14.0 libSDL2_ttf-2.0.so.0 -fi \ No newline at end of file diff --git a/workspace/_unmaintained/m17/boot/installing.bmp b/workspace/_unmaintained/m17/boot/installing.bmp deleted file mode 100644 index e112ce0fd75d63815b5a016207db869c4e498e3a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 522296 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 z*DJ=~9bfDSqc0x){qIbR1PBlyK!8ArK;OQ7)3Y(-voFia%1X*42oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk V1PBlyK!5-N0t5&UAn@}M_+LO^uP*=q diff --git a/workspace/_unmaintained/m17/boot/notes.txt b/workspace/_unmaintained/m17/boot/notes.txt deleted file mode 100644 index 0e0263157..000000000 --- a/workspace/_unmaintained/m17/boot/notes.txt +++ /dev/null @@ -1,85 +0,0 @@ -FRAMBUFFER - -480x272 -Save as BMP -Windows -32 bit -Flip row order - ---- - -BOOT LOGO - - oof, offsets in /dev/block/by-name/boot are different between revs - maybe copy the first two bytes at the known offsets to confirm the "BM" bitmap signature before proceeding? - - SIGNATURE=`dd if=/dev/block/by-name/boot bs=1 skip=$OFFSET count=2 status=none` # then test for "BM" - - http://www.ece.ualberta.ca/~elliott/ee552/studentAppNotes/2003_w/misc/bmp_file_format/bmp_file_format.htm - filesize is 31734 (Photoshop created one is 31736) - - rev a - HORIZONTAL extract - dd if=/dev/block/by-name/boot of=/sdcard/logo-h.bmp bs=1 skip=4044800 count=31734 - VERTICAL extract - dd if=/dev/block/by-name/boot of=/sdcard/logo-v.bmp bs=1 skip=4087296 count=31734 - REPLACE (tested and working) - dd conv=notrunc if=/sdcard/logo-h.bmp of=/dev/block/by-name/boot bs=1 seek=4044800 - - rev b - HORIZONTAL extract - dd if=/dev/block/by-name/boot of=/sdcard/logo-h.bmp bs=1 skip=4045312 count=31734 - VERTICAL extract - dd if=/dev/block/by-name/boot of=/sdcard/logo-v.bmp bs=1 skip=4087808 count=31734 - REPLACE (tested and working) - dd conv=notrunc if=/sdcard/logo-h.bmp of=/dev/block/by-name/boot bs=1 seek=4045312 - ---- - -OFFSETS - - HORIZONTAL VERTICAL - REV A 4044800 4087296 - REV B 4045312 4087808 - ---- - -264x40 (flipped vertical) - or -40x264 (rotated 90 then flipped horizontal) - -appears to be centered in framebuffer at 1x - can it be different dimensions within a certain size? - yes, 100x100 works :tada: - -Photoshop - 264x40 (or fewer pixels) - Save as BMP - Windows - 24-bit - DO NOT flip row order - - ---- - -tests - - echo ANDROID > tmp - printf 'BA' | dd conv=notrunc of=tmp bs=1 - cat tmp - BADROID - printf 'AN' | dd conv=notrunc of=tmp bs=1 - cat tmp - ANDROID - printf 'EW' | dd conv=notrunc of=tmp bs=1 seek=4 - cat tmp - ANDREWD - printf 'OI' | dd conv=notrunc of=tmp bs=1 seek=4 - cat tmp - ANDROID - -tested with /dev/block/by-name/boot - it's writable (at least it didn't claim it wasn't) - -figure out which it uses, I'm guessing the vertical version - nope, it's using the horizontal version \ No newline at end of file diff --git a/workspace/_unmaintained/m17/boot/updating.bmp b/workspace/_unmaintained/m17/boot/updating.bmp deleted file mode 100644 index b866d9d9bfd5e618fbdd0f2604b291598edfa8cc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 522296 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 diff --git a/workspace/_unmaintained/m17/cores/makefile b/workspace/_unmaintained/m17/cores/makefile deleted file mode 100644 index 968cdee8c..000000000 --- a/workspace/_unmaintained/m17/cores/makefile +++ /dev/null @@ -1,41 +0,0 @@ -CORES = gpsp gambatte fceumm pcsx_rearmed picodrive snes9x2005_plus -CORES+= mednafen_pce_fast mednafen_vb mednafen_supafaust mgba pokemini race -# CORES+= fake-08 - -############################### - -# optional core vars -# *_REPO= -# *_HASH= -# *_CORE= -# *_FLAGS= -# *_MAKEFILE= -# *_BUILD_PATH= - -mednafen_pce_fast_REPO = https://github.com/libretro/beetle-pce-fast-libretro -mednafen_vb_REPO = https://github.com/libretro/beetle-vb-libretro - -fake-08_REPO = https://github.com/jtothebell/fake-08 -fake-08_CORE = fake08_libretro.so -fake-08_BUILD_PATH = fake-08/platform/libretro - -fceumm_REPO = https://github.com/libretro/libretro-fceumm - -gambatte_REPO = https://github.com/libretro/gambatte-libretro - -mednafen_supafaust_REPO = https://github.com/libretro/supafaust - -pcsx_rearmed_MAKEFILE = Makefile.libretro - -picodrive_REPO = https://github.com/irixxxx/picodrive -picodrive_MAKEFILE = Makefile.libretro - -pokemini_REPO = https://github.com/libretro/PokeMini -pokemini_MAKEFILE = Makefile.libretro - -snes9x2005_plus_REPO = https://github.com/libretro/snes9x2005 -snes9x2005_plus_FLAGS = USE_BLARGG_APU=1 - -############################### - -include ../../all/cores/makefile \ No newline at end of file diff --git a/workspace/_unmaintained/m17/cores/patches/fake-08.patch b/workspace/_unmaintained/m17/cores/patches/fake-08.patch deleted file mode 100644 index b7a77e55f..000000000 --- a/workspace/_unmaintained/m17/cores/patches/fake-08.patch +++ /dev/null @@ -1,34 +0,0 @@ -diff --git forkSrcPrefix/platform/libretro/Makefile forkDstPrefix/platform/libretro/Makefile -index be0f1b46bb3ab10be4a9f896f5e8841dd630b35b..1b24657bd4b161718b9f878b6f0a9cde1b8dd035 100644 ---- forkSrcPrefix/platform/libretro/Makefile -+++ forkDstPrefix/platform/libretro/Makefile -@@ -123,7 +123,16 @@ else ifeq ($(platform), miyoomini) - CXXFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7ve -D_NEED_FULL_PATH_ - fpic := -fPIC - SHARED := -shared -Wl,--version-script=link.T -- -+else ifeq ($(platform), m17) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ STRIP = $(CROSS_COMPILE)strip -+ CXXFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 -+ CXXFLAGS += -fomit-frame-pointer -ffast-math -fno-common -ftree-vectorize -funswitch-loops -+ fpic := -fPIC -+ SHARED := -shared -Wl,--version-script=link.T - else ifeq ($(platform), gcw0) - TARGET := $(TARGET_NAME)_libretro_gcw0.so - CC = /opt/gcw0-toolchain/usr/bin/mipsel-linux-gcc -diff --git forkSrcPrefix/platform/libretro/libretro.cpp forkDstPrefix/platform/libretro/libretro.cpp -index d95ccb6cab52abfe7620ff84dd5cbb450bafe750..24687335ad410096aa48f29e13dcb479171a06fc 100644 ---- forkSrcPrefix/platform/libretro/libretro.cpp -+++ forkDstPrefix/platform/libretro/libretro.cpp -@@ -636,6 +636,7 @@ EXPORT bool retro_load_game(struct retro_game_info const *info) - else { - _vm->QueueCartChange(info->path); - } -+ _vm->UpdateAndDraw(); - - return true; - } diff --git a/workspace/_unmaintained/m17/cores/patches/fceumm.patch b/workspace/_unmaintained/m17/cores/patches/fceumm.patch deleted file mode 100644 index 9df3411f0..000000000 --- a/workspace/_unmaintained/m17/cores/patches/fceumm.patch +++ /dev/null @@ -1,28 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index 036c41f48b087c99b2276b2d41a71d661fd85145..891eb96ceeb1da868d6d2ed40392b51b65dcbb20 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -461,6 +461,23 @@ else ifeq ($(platform), miyoo) - PLATFORM_DEFINES += -fomit-frame-pointer -ffast-math -mcpu=arm926ej-s - EXTERNAL_ZLIB = 1 - -+# M17 -+else ifeq ($(platform), m17) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=src/drivers/libretro/link.T -Wl,-no-undefined -+ LDFLAGS += -fPIC -flto -+ CFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 -+ CFLAGS += -fomit-frame-pointer -ffast-math -fPIC -flto -+ OPTIMIZE := -Ofast -DNDEBUG -+ EXTERNAL_ZLIB = 1 -+ HAVE_NTSC = 0 -+ ifeq (,$(DEBUG)) -+ # LDFLAGS += -s -+ endif -+ - # Windows MSVC 2017 all architectures - else ifneq (,$(findstring windows_msvc2017,$(platform))) - CC = cl.exe diff --git a/workspace/_unmaintained/m17/cores/patches/gambatte.patch b/workspace/_unmaintained/m17/cores/patches/gambatte.patch deleted file mode 100644 index 9d3892866..000000000 --- a/workspace/_unmaintained/m17/cores/patches/gambatte.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index ffaba21e7a88f90786d818ab550b68acd05738bf..2095b2f843eaf6be9abec24ce3da69b551da86a6 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -381,6 +381,19 @@ else ifeq ($(platform), gcw0) - CFLAGS += -fomit-frame-pointer -ffast-math -march=mips32 -mtune=mips32r2 -mhard-float - CXXFLAGS += $(CFLAGS) - -+# M17 -+else ifeq ($(platform), m17) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=$(version_script) -+ LDFLAGS += -fPIC -flto -+ PLATFORM_DEFINES := -DCC_RESAMPLER -DCC_RESAMPLER_NO_HIGHPASS -+ CFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 -+ CFLAGS += -fomit-frame-pointer -ffast-math -fPIC -flto -+ CXXFLAGS += $(CFLAGS) -+ - # RETROFW - else ifeq ($(platform), retrofw) - TARGET := $(TARGET_NAME)_libretro.so diff --git a/workspace/_unmaintained/m17/cores/patches/gpsp.patch b/workspace/_unmaintained/m17/cores/patches/gpsp.patch deleted file mode 100644 index 48c7e888d..000000000 --- a/workspace/_unmaintained/m17/cores/patches/gpsp.patch +++ /dev/null @@ -1,28 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index dc4b60dec7f70a153dbc2eb849cd5acfc90f9d4d..d09272e897def69e6a26024e2f7224d30be76ab5 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -499,6 +499,23 @@ else ifeq ($(platform), miyoo) - CPU_ARCH := arm - - -+# M17 -+else ifeq ($(platform), m17) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=link.T -+ fpic := -fPIC -DPIC -+ CFLAGS += -fomit-frame-pointer -ffast-math -+ CFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 -+ HAVE_NEON = 1 -+ ARCH = arm -+ BUILTIN_GPU = neon -+ CPU_ARCH := arm -+ MMAP_JIT_CACHE = 1 -+ HAVE_DYNAREC = 1 -+ - else ifeq ($(platform), miyoomini) - TARGET := $(TARGET_NAME)_plus_libretro.so - CC = /opt/miyoomini-toolchain/usr/bin/arm-linux-gcc diff --git a/workspace/_unmaintained/m17/cores/patches/mednafen_pce_fast.patch b/workspace/_unmaintained/m17/cores/patches/mednafen_pce_fast.patch deleted file mode 100644 index 20aaf56a1..000000000 --- a/workspace/_unmaintained/m17/cores/patches/mednafen_pce_fast.patch +++ /dev/null @@ -1,29 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index d580571511b43d1ec4597db4a9611b0924bb2c53..2a7a5348c59220f82a99916bf85cc720a0f7f502 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -377,6 +377,24 @@ else ifeq ($(platform), miyoo) - CXXFLAGS += -std=c++11 - CFLAGS += -std=gnu11 - -+# M17 -+else ifeq ($(platform), m17) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ fpic := -fPIC -+ SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T -+ LDFLAGS += -lrt -+ CXXFLAGS += -std=c++11 -+ CFLAGS += -std=gnu11 -+ CFLAGS += -fomit-frame-pointer -ffast-math -fPIC -flto -+ CFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 -+ LDFLAGS += -flto -+ ifeq (,$(DEBUG)) -+ LDFLAGS += -s -+ endif -+ - # Windows MSVC 2017 all architectures - else ifneq (,$(findstring windows_msvc2017,$(platform))) - diff --git a/workspace/_unmaintained/m17/cores/patches/mednafen_supafaust.patch b/workspace/_unmaintained/m17/cores/patches/mednafen_supafaust.patch deleted file mode 100644 index bd23b01a7..000000000 --- a/workspace/_unmaintained/m17/cores/patches/mednafen_supafaust.patch +++ /dev/null @@ -1,42 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index 58120a1a88eab75ca13f2ed062f37d075c05a51b..8c8cd8a54c6b5a874725400d4de6d037ef500d3b 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -38,6 +38,37 @@ ifeq ($(platform), unix) - FLAGS += -pthread - endif - -+# M17 -+else ifeq ($(platform), m17) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ fpic := -fPIC -+ SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T -+ CFLAGS += -Ofast \ -+ -flto=4 -fwhole-program -fuse-linker-plugin \ -+ -fdata-sections -ffunction-sections -Wl,--gc-sections \ -+ -fno-stack-protector -fno-ident -fomit-frame-pointer \ -+ -falign-functions=1 -falign-jumps=1 -falign-loops=1 \ -+ -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-unroll-loops \ -+ -fmerge-all-constants -fno-math-errno \ -+ -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -+ CXXFLAGS += $(CFLAGS) -+ CFLAGS += -fPIC -+ LDFLAGS += -flto -+ HAVE_NEON = 1 -+ ARCH = arm -+ ifeq ($(shell echo `$(CC) -dumpversion` "< 4.9" | bc -l), 1) -+ CFLAGS += -march=armv7-a -+ else -+ CFLAGS += -mcpu=cortex-a7 -+ # If gcc is 5.0 or later -+ ifeq ($(shell echo `$(CC) -dumpversion` ">= 5" | bc -l), 1) -+ LDFLAGS += -static-libgcc -static-libstdc++ -+ endif -+ endif -+ - # Classic Platforms #################### - # Platform affix = classic__<µARCH> - # Help at https://modmyclassic.com/comp diff --git a/workspace/_unmaintained/m17/cores/patches/mednafen_vb.patch b/workspace/_unmaintained/m17/cores/patches/mednafen_vb.patch deleted file mode 100644 index ebfb4dedb..000000000 --- a/workspace/_unmaintained/m17/cores/patches/mednafen_vb.patch +++ /dev/null @@ -1,29 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index c3d5d3b30d71a8f9ed332482fa2af1c21b02605d..5e710154e499ddd7b1ae699122c38753b0f4bb4c 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -217,6 +217,24 @@ else ifneq (,$(filter $(platform), ps3 psl1ght)) - endif - FLAGS += -D__PS3__ - -+# M17 -+else ifeq ($(platform), m17) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ NEED_BPP := 16 -+ fpic := -fPIC -+ SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T -+ LDFLAGS += -lrt -+ CFLAGS += -fomit-frame-pointer -ffast-math -fPIC -flto -+ CFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 -+ CPPFLAGS += $(CFLAGS) -+ LDFLAGS += -flto -+ ifeq (,$(DEBUG)) -+ LDFLAGS += -s -+ endif -+ - # PSP - else ifeq ($(platform), psp1) - TARGET := $(TARGET_NAME)_libretro_$(platform).a diff --git a/workspace/_unmaintained/m17/cores/patches/mgba.patch b/workspace/_unmaintained/m17/cores/patches/mgba.patch deleted file mode 100644 index d4a2a1a3e..000000000 --- a/workspace/_unmaintained/m17/cores/patches/mgba.patch +++ /dev/null @@ -1,31 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index 108148f4579f4727146e5b8c1e05ef7382654208..35e6399147a4ef75947ecb2ad4a94f0820ef24d0 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -417,6 +417,26 @@ else ifeq ($(platform), miyoo) - CFLAGS += -fno-common -ftree-vectorize -funswitch-loops - DEFINES += -std=c99 - -+# M17 -+else ifeq ($(platform), m17) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=link.T -+ fpic := -fPIC -+ PLATFORM_DEFINES += -D_GNU_SOURCE -DHAVE_STRTOF_L -DHAVE_LOCALE -+ CFLAGS += -fomit-frame-pointer -ffast-math -+ CFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 -+ CFLAGS += -fno-common -ftree-vectorize -funswitch-loops -+ HAVE_NEON = 1 -+ ARCH = arm -+ BUILTIN_GPU = neon -+ CPU_ARCH := arm -+ MMAP_JIT_CACHE = 1 -+ HAVE_DYNAREC = 1 -+ DEFINES += -std=c99 -+ - # Windows - else - TARGET := $(TARGET_NAME)_libretro.dll diff --git a/workspace/_unmaintained/m17/cores/patches/pcsx_rearmed.patch b/workspace/_unmaintained/m17/cores/patches/pcsx_rearmed.patch deleted file mode 100644 index 7f713e048..000000000 --- a/workspace/_unmaintained/m17/cores/patches/pcsx_rearmed.patch +++ /dev/null @@ -1,31 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index 7b9618e1ccfc63982be50b82fda498d75e307fdc..f314adcbea17f05f473e1cbafc8711ab8ea0c5f1 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -391,6 +391,26 @@ else ifeq ($(platform), rpi4_64) - fpic := -fPIC - CFLAGS += -march=armv8-a+crc+simd -mtune=cortex-a72 -ftree-vectorize - -+# M17 -+else ifeq ($(platform), m17) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ CFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 -fomit-frame-pointer -+ CFLAGS += -ffast-math -fdata-sections -ffunction-sections -fsingle-precision-constant -flto -fPIC -+ LDFLAGS += -flto -fPIC -+ ifeq (,$(DEBUG)) -+ # LDFLAGS += -s -+ endif -+ CPU_ARCH := arm -+ OPTIMIZE := -Ofast -DNDEBUG=1 -+ HAVE_NEON = 1 -+ HAVE_NEON_ASM = 1 -+ BUILTIN_GPU = neon -+ ARCH = arm -+ DYNAREC = ari64 -+ - # Classic Platforms #################### - # Platform affix = classic__<µARCH> - # Help at https://modmyclassic.com/comp diff --git a/workspace/_unmaintained/m17/cores/patches/picodrive.patch b/workspace/_unmaintained/m17/cores/patches/picodrive.patch deleted file mode 100644 index 6d6d424fc..000000000 --- a/workspace/_unmaintained/m17/cores/patches/picodrive.patch +++ /dev/null @@ -1,35 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index 0d1dc08f81a11cef6b3b7238367b1ff27fcf1ead..1f87c76c3242023c4095f0c9087c52765d93c33c 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -497,6 +497,30 @@ else ifeq ($(platform), miyoo) - HAVE_ARMv6 = 0 - LOW_MEMORY = 1 - -+# M17 -+else ifeq ($(platform), m17) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--no-undefined -+ DONT_COMPILE_IN_ZLIB = 1 -+ CFLAGS += -Ofast \ -+ -fdata-sections -ffunction-sections -Wl,--gc-sections \ -+ -fno-stack-protector -fno-ident -fomit-frame-pointer \ -+ -falign-functions=1 -falign-jumps=1 -falign-loops=1 \ -+ -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-unroll-loops \ -+ -fmerge-all-constants -fno-math-errno -+ CFLAGS += -fPIC -flto -+ CFLAGS += -fomit-frame-pointer -ffast-math -D__GCW0__ -+ CFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 -+ LDFLAGS += -flto -+ HAVE_NEON = 1 -+ BUILTIN_GPU = neon -+ ifeq (,$(DEBUG)) -+ LDFLAGS += -s -+ endif -+ - # Windows MSVC 2017 all architectures - else ifneq (,$(findstring windows_msvc2017,$(platform))) - NO_GCC := 1 diff --git a/workspace/_unmaintained/m17/cores/patches/pokemini.patch b/workspace/_unmaintained/m17/cores/patches/pokemini.patch deleted file mode 100644 index 1ae9d33b4..000000000 --- a/workspace/_unmaintained/m17/cores/patches/pokemini.patch +++ /dev/null @@ -1,27 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index ef2f9e7d1c6041bea8e2c8a61cdd363ed73a7482..ada8785f566af89cc77f5ab2dd9e670b0a998545 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -504,6 +504,22 @@ else ifeq ($(platform), retrofw) - CFLAGS += -ffast-math -fomit-frame-pointer -march=mips32 -mtune=mips32 -mhard-float - CFLAGS += -DDINGUX - -+# M17 -+else ifeq ($(platform), m17) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=libretro/link.T -Wl,--no-undefined -+ fpic := -fPIC -+ CFLAGS += -DARM -+ CFLAGS += $(PTHREAD_FLAGS) -+ CFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 -+ CFLAGS += -ffast-math -fomit-frame-pointer -+ CFLAGS += -DDINGUX -+ HAVE_NEON = 1 -+ ARCH = arm -+ - else ifeq ($(platform), msvc) - OBJOUT = -Fo - diff --git a/workspace/_unmaintained/m17/cores/patches/race.patch b/workspace/_unmaintained/m17/cores/patches/race.patch deleted file mode 100644 index dc4cdbd73..000000000 --- a/workspace/_unmaintained/m17/cores/patches/race.patch +++ /dev/null @@ -1,23 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index 792a6d82915c32edd3df6ceec541499f6ca25ac5..dc02b361d7db47e011b6d3addf89cfb31503575a 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -373,6 +373,18 @@ else ifeq ($(platform), miyoo) - CFLAGS += -fomit-frame-pointer -ffast-math -march=armv5te -mtune=arm926ej-s - CXXFLAGS += $(CFLAGS) - -+# M17 -+else ifeq ($(platform), m17) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ fpic := -fPIC -+ SHARED := -shared -Wl,-version-script=$(LIBRETRO_DIR)/link.T -+ PLATFORM_DEFINES := -DCC_RESAMPLER -DCC_RESAMPLER_NO_HIGHPASS -+ CFLAGS += -fomit-frame-pointer -ffast-math -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 -+ CXXFLAGS += $(CFLAGS) -+ - # Windows MSVC 2010 x64 - else ifeq ($(platform), windows_msvc2010_x64) - CC = cl.exe diff --git a/workspace/_unmaintained/m17/cores/patches/snes9x2005_plus.patch b/workspace/_unmaintained/m17/cores/patches/snes9x2005_plus.patch deleted file mode 100644 index 922b3923c..000000000 --- a/workspace/_unmaintained/m17/cores/patches/snes9x2005_plus.patch +++ /dev/null @@ -1,36 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index 07d5368a8e78a020813732239ec369d83e931ede..009f13b8e61c634de4cb83e97785a10b83b4322d 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -288,6 +288,31 @@ else ifeq ($(platform), miyoo) - FLAGS += -fomit-frame-pointer -ffast-math -march=armv5te -mtune=arm926ej-s - FLAGS += -DFAST_ALIGNED_LSB_WORD_ACCESS -fno-unroll-loops - -+# M17 -+else ifeq ($(platform), m17) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=link.T -+ LIBM := -+ CFLAGS += -Ofast \ -+ -flto=4 -fwhole-program -fuse-linker-plugin \ -+ -fdata-sections -ffunction-sections -Wl,--gc-sections \ -+ -fno-stack-protector -fno-ident -fomit-frame-pointer \ -+ -falign-functions=1 -falign-jumps=1 -falign-loops=1 \ -+ -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-unroll-loops \ -+ -fmerge-all-constants -fno-math-errno -+ CFLAGS += -fPIC -+ CFLAGS += -DLSB_FIRST -DFAST_ALIGNED_LSB_WORD_ACCESS -DRIGHTSHIFT_IS_SAR -+ CFLAGS += -std=c99 -fomit-frame-pointer -ffast-math -+ CFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 -+ LDFLAGS += -flto -+ OPTIMIZE += -Ofast -DNDEBUG=1 -+ ifeq (,$(DEBUG)) -+ LDFLAGS += -s -+ endif -+ - # (armv7 a7, hard point, neon based) ### - # NESC, SNESC, C64 mini - else ifeq ($(platform), classic_armv7_a7) diff --git a/workspace/_unmaintained/m17/install/install.sh b/workspace/_unmaintained/m17/install/install.sh deleted file mode 100755 index af9103318..000000000 --- a/workspace/_unmaintained/m17/install/install.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -SYSTEM_PATH=/sdcard/.system/m17 -tar xf $SYSTEM_PATH/dat/extra-libs.tar -C $SYSTEM_PATH/lib - -cp $SYSTEM_PATH/dat/em_ui.sh /sdcard -sync \ No newline at end of file diff --git a/workspace/_unmaintained/m17/keymon/credits.txt b/workspace/_unmaintained/m17/keymon/credits.txt deleted file mode 100644 index e885e5dd1..000000000 --- a/workspace/_unmaintained/m17/keymon/credits.txt +++ /dev/null @@ -1,3 +0,0 @@ -based on eggs custom keymon for Trimui: - https://www.dropbox.com/sh/5e9xwvp672vt8cr/AABUIdw1vLYp9h0waoCUqHPOa/source?dl=0&subfolder_nav_tracking=1 -modified to use libmsettings \ No newline at end of file diff --git a/workspace/_unmaintained/m17/keymon/keymon.c b/workspace/_unmaintained/m17/keymon/keymon.c deleted file mode 100644 index f1e57e6fb..000000000 --- a/workspace/_unmaintained/m17/keymon/keymon.c +++ /dev/null @@ -1,167 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -// #include "defines.h" - -#define VOLUME_MIN 0 -#define VOLUME_MAX 20 -#define BRIGHTNESS_MIN 0 -#define BRIGHTNESS_MAX 10 - -#define CODE_PLUS 115 -#define CODE_MINUS 114 - -#define CODE_SELECT 54 -#define CODE_START 28 -#define CODE_L1 38 -#define CODE_R1 19 - -#define RELEASED 0 -#define PRESSED 1 - -#define INPUT_COUNT 4 -static int inputs[INPUT_COUNT]; -static struct input_event ev; - -static pthread_t ports_pt; -#define JACK_STATE_PATH "/sys/devices/virtual/switch/h2w/state" // 0 or 2 - -int getInt(char* path) { - int i = 0; - FILE *file = fopen(path, "r"); - if (file!=NULL) { - fscanf(file, "%i", &i); - fclose(file); - } - return i; -} - -static void* watchPorts(void *arg) { - int has_headphones,had_headphones; - - has_headphones = had_headphones = getInt(JACK_STATE_PATH); - SetJack(has_headphones); - - while(1) { - sleep(1); - - has_headphones = getInt(JACK_STATE_PATH); - if (had_headphones!=has_headphones) { - had_headphones = has_headphones; - SetJack(has_headphones); - } - } - - return 0; -} - -int main (int argc, char *argv[]) { - printf("keymon\n"); fflush(stdout); - InitSettings(); - pthread_create(&ports_pt, NULL, &watchPorts, NULL); - - char path[256]; - for (int i=0; i /sys/devices/platform/0gpio-keys/scaled"); - SetVolume(GetVolume()); - break; - default: - break; - } - } - } - - if (up_just_pressed || (up_pressed && now>=up_repeat_at)) { - if (start_pressed) { - val = GetBrightness(); - if (val=down_repeat_at)) { - if (start_pressed) { - val = GetBrightness(); - if (val>BRIGHTNESS_MIN) SetBrightness(--val); - } - else if (select_pressed) { - val = GetVolume(); - if (val>VOLUME_MIN) SetVolume(--val); - } - - if (down_just_pressed) down_just_pressed = 0; - else down_repeat_at += 100; - } - - usleep(16666); // 60fps - } -} diff --git a/workspace/_unmaintained/m17/keymon/makefile b/workspace/_unmaintained/m17/keymon/makefile deleted file mode 100755 index e23c35820..000000000 --- a/workspace/_unmaintained/m17/keymon/makefile +++ /dev/null @@ -1,14 +0,0 @@ -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif - -TARGET = keymon -PRODUCT = $(TARGET).elf - -CC = $(CROSS_COMPILE)gcc -I../../all/common/ -I../platform/ -FLAGS = -Os -lmsettings -lpthread -lrt -ldl -Wl,--gc-sections -s - -all: - $(CC) $(TARGET).c -o $(PRODUCT) $(FLAGS) -clean: - rm -rf $(PRODUCT) \ No newline at end of file diff --git a/workspace/_unmaintained/m17/libmsettings/makefile b/workspace/_unmaintained/m17/libmsettings/makefile deleted file mode 100644 index b1418a21d..000000000 --- a/workspace/_unmaintained/m17/libmsettings/makefile +++ /dev/null @@ -1,32 +0,0 @@ -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif -ifeq (,$(PREFIX)) -$(error missing PREFIX for this toolchain) -endif - -TARGET=msettings - -.PHONY: build -.PHONY: clean - -CC = $(CROSS_COMPILE)gcc - -SYSROOT := $(shell $(CC) --print-sysroot) - -INCLUDEDIR = $(SYSROOT)/usr/include -CFLAGS = -I$(INCLUDEDIR) -LDFLAGS = -ldl -lrt -s - -OPTM=-Ofast - -build: - $(CC) -c -Werror -fpic "$(TARGET).c" -Wl,--no-as-needed $(LDFLAGS) - $(CC) -shared -o "lib$(TARGET).so" "$(TARGET).o" $(LDFLAGS) - cp "$(TARGET).h" "$(PREFIX)/include" - cp "lib$(TARGET).so" "$(PREFIX)/lib" -clean: - rm -f *.o - rm -f "lib$(TARGET).so" - rm -f $(PREFIX)/include/$(TARGET).h - rm -f $(PREFIX)/lib/lib$(TARGET).so \ No newline at end of file diff --git a/workspace/_unmaintained/m17/libmsettings/msettings.c b/workspace/_unmaintained/m17/libmsettings/msettings.c deleted file mode 100644 index e26802f01..000000000 --- a/workspace/_unmaintained/m17/libmsettings/msettings.c +++ /dev/null @@ -1,190 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "msettings.h" - -/////////////////////////////////////// - -#define SETTINGS_VERSION 2 -typedef struct Settings { - int version; // future proofing - int brightness; - int headphones; - int speaker; - int unused[3]; // for future use - // NOTE: doesn't really need to be persisted but still needs to be shared - int jack; -} Settings; -static Settings DefaultSettings = { - .version = SETTINGS_VERSION, - .brightness = 2, - .headphones = 4, - .speaker = 8, - .jack = 0, -}; -static Settings* settings; - -#define SHM_KEY "/SharedSettings" -static char SettingsPath[256]; -static int shm_fd = -1; -static int is_host = 0; -static int shm_size = sizeof(Settings); - -// #define BACKLIGHT_PATH "/sys/class/backlight/backlight/bl_power" -// #define BRIGHTNESS_PATH "/sys/class/backlight/backlight/brightness" -// #define JACK_STATE_PATH "/sys/bus/platform/devices/singleadc-joypad/hp" -// #define HDMI_STATE_PATH "/sys/class/extcon/hdmi/cable.0/state" - -int getInt(char* path) { - int i = 0; - FILE *file = fopen(path, "r"); - if (file!=NULL) { - fscanf(file, "%i", &i); - fclose(file); - } - return i; -} - - -void InitSettings(void) { - sprintf(SettingsPath, "%s/msettings.bin", getenv("USERDATA_PATH")); - - shm_fd = shm_open(SHM_KEY, O_RDWR | O_CREAT | O_EXCL, 0644); // see if it exists - if (shm_fd==-1 && errno==EEXIST) { // already exists - // puts("Settings client"); - shm_fd = shm_open(SHM_KEY, O_RDWR, 0644); - settings = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); - } - else { // host - // puts("Settings host"); // keymon - is_host = 1; - // we created it so set initial size and populate - ftruncate(shm_fd, shm_size); - settings = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); - - int fd = open(SettingsPath, O_RDONLY); - if (fd>=0) { - read(fd, settings, shm_size); - // TODO: use settings->version for future proofing? - close(fd); - } - else { - // load defaults - memcpy(settings, &DefaultSettings, shm_size); - } - - // these shouldn't be persisted - // settings->jack = 0; - // settings->hdmi = 0; - } - // printf("brightness: %i\nspeaker: %i \n", settings->brightness, settings->speaker); - - // SetJack(getInt(JACK_STATE_PATH)); - // SetHDMI(getInt(HDMI_STATE_PATH)); - SetVolume(GetVolume()); - SetBrightness(GetBrightness()); -} -void QuitSettings(void) { - munmap(settings, shm_size); - if (is_host) shm_unlink(SHM_KEY); -} -static inline void SaveSettings(void) { - int fd = open(SettingsPath, O_CREAT|O_WRONLY, 0644); - if (fd>=0) { - write(fd, settings, shm_size); - close(fd); - sync(); - } -} - -int GetBrightness(void) { // 0-10 - return settings->brightness; -} -void SetBrightness(int value) { - - int raw; - switch (value) { - case 0: raw=8000; break; - case 1: raw=7500; break; - case 2: raw=7000; break; - case 3: raw=6500; break; - case 4: raw=6000; break; - case 5: raw=5000; break; - case 6: raw=4000; break; - case 7: raw=3000; break; - case 8: raw=2000; break; - case 9: raw=1000; break; - case 10: raw=0; break; - } - SetRawBrightness(raw); - settings->brightness = value; - SaveSettings(); -} - -int GetVolume(void) { // 0-20 - return settings->jack ? settings->headphones : settings->speaker; -} -void SetVolume(int value) { - // if (settings->hdmi) return; - - if (settings->jack) settings->headphones = value; - else settings->speaker = value; - - int raw = value * 5; - SetRawVolume(raw); - SaveSettings(); -} - -void SetRawBrightness(int val) { // 8000-0 (>8000 == off) - // if (settings->hdmi) return; - printf("SetRawBrightness(%i)\n", val); fflush(stdout); - int fd = open("/dev/gpio-pwm", O_WRONLY); - if (fd>=0) { - dprintf(fd,"%d",val); - close(fd); - } -} -void SetRawVolume(int val) { // 0 - 100 - printf("SetRawVolume(%i)\n", val); fflush(stdout); - char cmd[256]; - sprintf(cmd, "amixer cset name='Master Playback Volume' %i%%,0 &> /dev/null", val); - // puts(cmd); fflush(stdout); - system(cmd); -} - -// monitored and set by thread in keymon -int GetJack(void) { - return settings->jack; -} -void SetJack(int value) { - printf("SetJack(%i)\n", value); fflush(stdout); - - settings->jack = value; - SetVolume(GetVolume()); -} - -int GetHDMI(void) { - // printf("GetHDMI() %i\n", settings->hdmi); fflush(stdout); - // return settings->hdmi; - return 0; -} -void SetHDMI(int value) { - // printf("SetHDMI(%i)\n", value); fflush(stdout); - - // if (settings->hdmi!=value) system("/usr/lib/autostart/common/055-hdmi-check"); - - // settings->hdmi = value; - // if (value) SetRawVolume(100); // max - // else SetVolume(GetVolume()); // restore -} - -int GetMute(void) { return 0; } -void SetMute(int value) {} diff --git a/workspace/_unmaintained/m17/libmsettings/msettings.h b/workspace/_unmaintained/m17/libmsettings/msettings.h deleted file mode 100644 index 642a1f54f..000000000 --- a/workspace/_unmaintained/m17/libmsettings/msettings.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef __msettings_h__ -#define __msettings_h__ - -void InitSettings(void); -void QuitSettings(void); - -int GetBrightness(void); -int GetVolume(void); - -void SetRawBrightness(int value); // 8000-0 (>8000 == off) -void SetRawVolume(int value); // 0-40 - -void SetBrightness(int value); // 0-10 -void SetVolume(int value); // 0-20 - -int GetJack(void); -void SetJack(int value); // 0-1 - -int GetHDMI(void); -void SetHDMI(int value); // 0-1 - -int GetMute(void); -void SetMute(int value); // 0-1 - -#endif // __msettings_h__ diff --git a/workspace/_unmaintained/m17/makefile b/workspace/_unmaintained/m17/makefile deleted file mode 100644 index d88c27edc..000000000 --- a/workspace/_unmaintained/m17/makefile +++ /dev/null @@ -1,24 +0,0 @@ -########################################################### - -ifeq (,$(PLATFORM)) -PLATFORM=$(UNION_PLATFORM) -endif - -ifeq (,$(PLATFORM)) -$(error please specify PLATFORM, eg. PLATFORM=rgb30 make) -endif - -########################################################### - -all: readmes - cd ./boot && ./build.sh - -early: - # early - -clean: - cd ./overclock && make clean - -########################################################### - -include ../all/readmes/makefile diff --git a/workspace/_unmaintained/m17/platform/makefile.copy b/workspace/_unmaintained/m17/platform/makefile.copy deleted file mode 100644 index 21b561ea8..000000000 --- a/workspace/_unmaintained/m17/platform/makefile.copy +++ /dev/null @@ -1,8 +0,0 @@ -$(PLATFORM): - # $@ - cp ./workspace/$@/boot/output/em_ui.sh ./build/BASE/ - cp ./workspace/$@/boot/output/em_ui.sh ./build/SYSTEM/$@/dat/ - cp ./workspace/$@/boot/output/lib* ./build/SYSTEM/$@/lib/ - cp ./workspace/$@/install/install.sh ./build/SYSTEM/$@/bin/ - # extras - \ No newline at end of file diff --git a/workspace/_unmaintained/m17/platform/makefile.env b/workspace/_unmaintained/m17/platform/makefile.env deleted file mode 100644 index 1e74aa9d7..000000000 --- a/workspace/_unmaintained/m17/platform/makefile.env +++ /dev/null @@ -1,4 +0,0 @@ -# tg5040 -ARCH = -O3 -LIBS = -flto -SDL = SDL2 \ No newline at end of file diff --git a/workspace/_unmaintained/m17/platform/platform.c b/workspace/_unmaintained/m17/platform/platform.c deleted file mode 100644 index 392414ffd..000000000 --- a/workspace/_unmaintained/m17/platform/platform.c +++ /dev/null @@ -1,523 +0,0 @@ -// m17 -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include "defines.h" -#include "platform.h" -#include "api.h" -#include "utils.h" - -#include "scaler.h" - -/////////////////////////////// - -#define RAW_UP 103 -#define RAW_DOWN 108 -#define RAW_LEFT 105 -#define RAW_RIGHT 106 -#define RAW_A 48 -#define RAW_B 30 -#define RAW_X 21 -#define RAW_Y 45 -#define RAW_START 28 -#define RAW_SELECT 54 -#define RAW_MENU 115 -#define RAW_L1 38 -#define RAW_L2 44 -#define RAW_R1 19 -#define RAW_R2 46 -#define RAW_PLUS 115 -#define RAW_MINUS 114 - -#define RAW_MENU1 RAW_PLUS -#define RAW_MENU2 RAW_MINUS - -#define INPUT_COUNT 4 -static int inputs[INPUT_COUNT]; - -void PLAT_initInput(void) { - char path[256]; - for (int i=0; i which has BTN_ constants that conflict with platform.h -struct input_event { - struct timeval time; - __u16 type; - __u16 code; - __s32 value; -}; -#define EV_KEY 0x01 -#define EV_ABS 0x03 - -void PLAT_pollInput(void) { - // reset transient state - pad.just_pressed = BTN_NONE; - pad.just_released = BTN_NONE; - pad.just_repeated = BTN_NONE; - - uint32_t tick = SDL_GetTicks(); - for (int i=0; i=pad.repeat_at[i])) { - pad.just_repeated |= btn; // set - pad.repeat_at[i] += PAD_REPEAT_INTERVAL; - } - } - - // the actual poll - int input; - static struct input_event event; - for (int i=0; i1) continue; // ignore repeats - - pressed = value; - // LOG_info("key event: %i (%i)\n", code,pressed); // no L3/R3 - if (code==RAW_UP) { btn = BTN_DPAD_UP; id = BTN_ID_DPAD_UP; } - else if (code==RAW_DOWN) { btn = BTN_DPAD_DOWN; id = BTN_ID_DPAD_DOWN; } - else if (code==RAW_LEFT) { btn = BTN_DPAD_LEFT; id = BTN_ID_DPAD_LEFT; } - else if (code==RAW_RIGHT) { btn = BTN_DPAD_RIGHT; id = BTN_ID_DPAD_RIGHT; } - else if (code==RAW_A) { btn = BTN_A; id = BTN_ID_A; } - else if (code==RAW_B) { btn = BTN_B; id = BTN_ID_B; } - else if (code==RAW_X) { btn = BTN_X; id = BTN_ID_X; } - else if (code==RAW_Y) { btn = BTN_Y; id = BTN_ID_Y; } - else if (code==RAW_START) { btn = BTN_START; id = BTN_ID_START; } - else if (code==RAW_SELECT) { btn = BTN_SELECT; id = BTN_ID_SELECT; } - else if (code==RAW_MENU) { btn = BTN_MENU; id = BTN_ID_MENU; } - else if (code==RAW_MENU1) { btn = BTN_MENU; id = BTN_ID_MENU; } - else if (code==RAW_MENU2) { btn = BTN_MENU; id = BTN_ID_MENU; } - else if (code==RAW_L1) { btn = BTN_L1; id = BTN_ID_L1; } - else if (code==RAW_L2) { btn = BTN_L2; id = BTN_ID_L2; } - else if (code==RAW_R1) { btn = BTN_R1; id = BTN_ID_R1; } - else if (code==RAW_R2) { btn = BTN_R2; id = BTN_ID_R2; } - } - else if (type==EV_ABS) { - // LOG_info("axis: %i (%i)\n",code,value); - // else if (code==RAW_LSX) pad.laxis.x = (value * 32767) / 4096; - // else if (code==RAW_LSY) pad.laxis.y = (value * 32767) / 4096; - // else if (code==RAW_RSX) pad.raxis.x = (value * 32767) / 4096; - // else if (code==RAW_RSY) pad.raxis.y = (value * 32767) / 4096; - - btn = BTN_NONE; // already handled, force continue - } - - if (btn==BTN_NONE) continue; - - if (!pressed) { - pad.is_pressed &= ~btn; // unset - pad.just_repeated &= ~btn; // unset - pad.just_released |= btn; // set - } - else if ((pad.is_pressed & btn)==BTN_NONE) { - pad.just_pressed |= btn; // set - pad.just_repeated |= btn; // set - pad.is_pressed |= btn; // set - pad.repeat_at[id] = tick + PAD_REPEAT_DELAY; - } - } - } -} - -int PLAT_shouldWake(void) { - int input; - static struct input_event event; - for (int i=0; i /dev/fb0 2>/dev/null"); -} - -void PLAT_clearVideo(SDL_Surface* screen) { - SDL_FillRect(screen, NULL, 0); // TODO: revisit -} -void PLAT_clearAll(void) { - clearVideo(); -} - -void PLAT_setVsync(int vsync) { - -} - -static int hard_scale = 4; // TODO: base src size, eg. 160x144 can be 4 o - -static void resizeVideo(int w, int h, int p) { - if (w==vid.width && h==vid.height && p==vid.pitch) return; - - if (w>=FIXED_WIDTH && h>=FIXED_HEIGHT) { - hard_scale = 1; - } - else if (h>=160) { - hard_scale = 2; - } - else { - hard_scale = 4; - } - - // TODO: figure out how to ignore minarch upscale requests - LOG_info("resizeVideo(%i,%i,%i) hard_scale: %i\n",w,h,p, hard_scale); - - SDL_FreeSurface(vid.buffer); - SDL_DestroyTexture(vid.texture); - if (vid.target) SDL_DestroyTexture(vid.target); - - SDL_SetHintWithPriority(SDL_HINT_RENDER_SCALE_QUALITY, vid.sharpness==SHARPNESS_SOFT?"1":"0", SDL_HINT_OVERRIDE); - vid.texture = SDL_CreateTexture(vid.renderer,SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, w,h); - - if (vid.sharpness==SHARPNESS_CRISP) { - SDL_SetHintWithPriority(SDL_HINT_RENDER_SCALE_QUALITY, "1", SDL_HINT_OVERRIDE); - vid.target = SDL_CreateTexture(vid.renderer,SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_TARGET, w * hard_scale,h * hard_scale); - } - else { - vid.target = NULL; - } - - vid.buffer = SDL_CreateRGBSurfaceFrom(NULL, w,h, FIXED_DEPTH, p, RGBA_MASK_565); - - vid.width = w; - vid.height = h; - vid.pitch = p; -} - -SDL_Surface* PLAT_resizeVideo(int w, int h, int p) { - // LOG_info("Current audio driver: %s\n", SDL_GetCurrentAudioDriver()); - resizeVideo(w,h,p); - return vid.screen; -} - -void PLAT_setVideoScaleClip(int x, int y, int width, int height) { - // buh -} -void PLAT_setNearestNeighbor(int enabled) { - // always enabled? -} -void PLAT_setSharpness(int sharpness) { - if (vid.sharpness==sharpness) return; - int p = vid.pitch; - vid.pitch = 0; - vid.sharpness = sharpness; - resizeVideo(vid.width,vid.height,p); -} -void PLAT_setEffect(int effect) { - // buh -} - -void PLAT_vsync(int remaining) { - if (remaining>0) SDL_Delay(remaining); -} - -scaler_t PLAT_getScaler(GFX_Renderer* renderer) { - return scale1x1_n16; -} - -void PLAT_blitRenderer(GFX_Renderer* renderer) { - vid.blit = renderer; - SDL_RenderClear(vid.renderer); - resizeVideo(vid.blit->true_w,vid.blit->true_h,vid.blit->src_p); -} - -void PLAT_flip(SDL_Surface* IGNORED, int ignored) { - if (!vid.blit) { - resizeVideo(FIXED_WIDTH,FIXED_HEIGHT,FIXED_PITCH); // !!!??? - SDL_LockTexture(vid.texture,NULL,&vid.buffer->pixels,&vid.buffer->pitch); - SDL_BlitSurface(vid.screen, NULL, vid.buffer, NULL); - SDL_UnlockTexture(vid.texture); - SDL_RenderCopy(vid.renderer, vid.texture, NULL,NULL); - SDL_RenderPresent(vid.renderer); - return; - } - - SDL_LockTexture(vid.texture,NULL,&vid.buffer->pixels,&vid.buffer->pitch); - ((scaler_t)vid.blit->blit)( - vid.blit->src,vid.buffer->pixels, - vid.blit->src_w,vid.blit->src_h,vid.blit->src_p, - // vid.blit->true_w,vid.blit->true_h,vid.blit->src_p, // TODO: fix to be confirmed, issue may not present on this platform - vid.buffer->w,vid.buffer->h,vid.buffer->pitch - ); - SDL_UnlockTexture(vid.texture); - - SDL_Texture* target = vid.texture; - int w = vid.blit->src_w; - int h = vid.blit->src_h; - if (vid.sharpness==SHARPNESS_CRISP) { - SDL_SetRenderTarget(vid.renderer,vid.target); - SDL_RenderCopy(vid.renderer, vid.texture, NULL,NULL); - SDL_SetRenderTarget(vid.renderer,NULL); - w *= hard_scale; - h *= hard_scale; - target = vid.target; - } - - SDL_Rect* src_rect = &(SDL_Rect){0,0,w,h}; - SDL_Rect* dst_rect = NULL; - if (vid.blit->aspect==0) { // native or cropped - int w = vid.blit->src_w * vid.blit->scale; - int h = vid.blit->src_h * vid.blit->scale; - int x = (FIXED_WIDTH - w) / 2; - int y = (FIXED_HEIGHT - h) / 2; - dst_rect = &(SDL_Rect){x,y,w,h}; - } - else if (vid.blit->aspect>0) { // aspect - int h = FIXED_HEIGHT; - int w = h * vid.blit->aspect; - if (w>FIXED_WIDTH) { - double ratio = 1 / vid.blit->aspect; - w = FIXED_WIDTH; - h = w * ratio; - } - int x = (FIXED_WIDTH - w) / 2; - int y = (FIXED_HEIGHT - h) / 2; - dst_rect = &(SDL_Rect){x,y,w,h}; - } - SDL_RenderCopy(vid.renderer, target, src_rect, dst_rect); - SDL_RenderPresent(vid.renderer); - vid.blit = NULL; -} - -/////////////////////////////// - -// TODO: -#define OVERLAY_WIDTH PILL_SIZE // unscaled -#define OVERLAY_HEIGHT PILL_SIZE // unscaled -#define OVERLAY_BPP 4 -#define OVERLAY_DEPTH 16 -#define OVERLAY_PITCH (OVERLAY_WIDTH * OVERLAY_BPP) // unscaled -#define OVERLAY_RGBA_MASK 0x00ff0000,0x0000ff00,0x000000ff,0xff000000 // ARGB -static struct OVL_Context { - SDL_Surface* overlay; -} ovl; - -SDL_Surface* PLAT_initOverlay(void) { - ovl.overlay = SDL_CreateRGBSurface(SDL_SWSURFACE, SCALE2(OVERLAY_WIDTH,OVERLAY_HEIGHT),OVERLAY_DEPTH,OVERLAY_RGBA_MASK); - return ovl.overlay; -} -void PLAT_quitOverlay(void) { - if (ovl.overlay) SDL_FreeSurface(ovl.overlay); -} -void PLAT_enableOverlay(int enable) { - -} - -/////////////////////////////// - -void PLAT_getBatteryStatus(int* is_charging, int* charge) { - PLAT_getBatteryStatusFine(is_charging, charge); - - // worry less about battery and more about the game you're playing - if (i>80) *charge = 100; - else if (i>60) *charge = 80; - else if (i>40) *charge = 60; - else if (i>20) *charge = 40; - else if (i>10) *charge = 20; - else *charge = 10; -} - -void PLAT_getBatteryStatusFine(int* is_charging, int* charge) -{ - // *is_charging = 0; - // *charge = PWR_LOW_CHARGE; - // return; - - char state[256]; - - // works with old model - getFile("/sys/class/udc/10180000.usb/state", state, 256); - *is_charging = strncmp("not attached",state,strlen("not attached")); // I don't understand how this works, if it's a match it would equal 0 which is false... - - // nothing works with new model :sob: - // getFile("/sys/class/power_supply/battery/status", state, 256); - // *is_charging = exactMatch(state,"Charging\n"); - - *charge = getInt("/sys/class/power_supply/battery/capacity"); -} - -void PLAT_enableBacklight(int enable) { - // haven't figured out how to turn it off (or change brightness) - if (!enable) { - putInt("/sys/class/graphics/fb0/blank", 1); // clear - SetRawBrightness(8001); // off - } - else { - SetBrightness(GetBrightness()); - } -} - -void PLAT_powerOff(void) { - // system("leds_on"); - sleep(2); - - SetRawVolume(MUTE_VOLUME_RAW); - PLAT_enableBacklight(0); - SND_quit(); - VIB_quit(); - PWR_quit(); - GFX_quit(); - - touch("/tmp/poweroff"); - exit(0); -} - -/////////////////////////////// - -void PLAT_setCPUSpeed(int speed) { - // M17 can go any speed you like as long as that speed is 1200000 -} - -void PLAT_setRumble(int strength) { - // buh -} - -int PLAT_pickSampleRate(int requested, int max) { - return MIN(requested, max); -} - -char* PLAT_getModel(void) { - return "M17"; -} - -int PLAT_isOnline(void) { - return 0; -} \ No newline at end of file diff --git a/workspace/_unmaintained/m17/platform/platform.h b/workspace/_unmaintained/m17/platform/platform.h deleted file mode 100644 index 63c37ac2d..000000000 --- a/workspace/_unmaintained/m17/platform/platform.h +++ /dev/null @@ -1,127 +0,0 @@ -// m17 - -#ifndef PLATFORM_H -#define PLATFORM_H - -/////////////////////////////// - -#include "sdl.h" - -/////////////////////////////// - -#define BUTTON_UP SDLK_UP -#define BUTTON_DOWN SDLK_DOWN -#define BUTTON_LEFT SDLK_LEFT -#define BUTTON_RIGHT SDLK_RIGHT - -#define BUTTON_SELECT SDLK_RSHIFT -#define BUTTON_START SDLK_RETURN - -#define BUTTON_A SDLK_B -#define BUTTON_B SDLK_A -#define BUTTON_X SDLK_Y -#define BUTTON_Y SDLK_X - -#define BUTTON_L1 SDLK_L -#define BUTTON_R1 SDLK_R -#define BUTTON_L2 SDLK_z -#define BUTTON_R2 SDLK_c -#define BUTTON_L3 BUTTON_NA -#define BUTTON_R3 BUTTON_NA - -#define BUTTON_MENU BUTTON_NA -#define BUTTON_MENU_ALT BUTTON_NA -#define BUTTON_POWER BUTTON_NA -#define BUTTON_PLUS BUTTON_NA -#define BUTTON_MINUS BUTTON_NA - -/////////////////////////////// - -#define CODE_UP CODE_NA -#define CODE_DOWN CODE_NA -#define CODE_LEFT CODE_NA -#define CODE_RIGHT CODE_NA - -#define CODE_SELECT CODE_NA -#define CODE_START CODE_NA - -#define CODE_A CODE_NA -#define CODE_B CODE_NA -#define CODE_X CODE_NA -#define CODE_Y CODE_NA - -#define CODE_L1 CODE_NA -#define CODE_R1 CODE_NA -#define CODE_L2 CODE_NA -#define CODE_R2 CODE_NA -#define CODE_L3 CODE_NA -#define CODE_R3 CODE_NA - -#define CODE_MENU CODE_NA -#define CODE_MENU_ALT CODE_NA -#define CODE_POWER CODE_NA - -#define CODE_PLUS CODE_NA -#define CODE_MINUS CODE_NA - -/////////////////////////////// - -#define JOY_UP 11 -#define JOY_DOWN 14 -#define JOY_LEFT 12 -#define JOY_RIGHT 13 - -#define JOY_SELECT 10 -#define JOY_START 3 - -#define JOY_A 9 -#define JOY_B 4 -#define JOY_X 2 -#define JOY_Y 7 - -#define JOY_L1 5 -#define JOY_R1 1 -#define JOY_L2 6 -#define JOY_R2 8 -#define JOY_L3 JOY_NA -#define JOY_R3 JOY_NA - -#define JOY_MENU 15 -#define JOY_MENU_ALT 16 -#define JOY_POWER JOY_NA -#define JOY_PLUS JOY_NA -#define JOY_MINUS JOY_NA - -/////////////////////////////// - -#define BTN_RESUME BTN_X -#define BTN_SLEEP BTN_MENU -#define BTN_WAKE BTN_MENU -#define BTN_MOD_VOLUME BTN_SELECT -#define BTN_MOD_BRIGHTNESS BTN_START -#define BTN_MOD_PLUS BTN_R1 -#define BTN_MOD_MINUS BTN_L1 - -/////////////////////////////// - -#define FIXED_SCALE 1 -#define FIXED_WIDTH 480 -#define FIXED_HEIGHT 273 -#define FIXED_BPP 2 -#define FIXED_DEPTH (FIXED_BPP * 8) -#define FIXED_PITCH (FIXED_WIDTH * FIXED_BPP) -#define FIXED_SIZE (FIXED_PITCH * FIXED_HEIGHT) - -/////////////////////////////// - -#define SDCARD_PATH "/sdcard" -#define MUTE_VOLUME_RAW 0 -#define HAS_NEON // maybe? - -#define MAIN_ROW_COUNT 7 - -// this should be set to the devices native screen refresh rate -#define SCREEN_FPS 60.0 -/////////////////////////////// - -#endif diff --git a/workspace/_unmaintained/magicmini/cores/makefile b/workspace/_unmaintained/magicmini/cores/makefile deleted file mode 100644 index 2a7c2cb3e..000000000 --- a/workspace/_unmaintained/magicmini/cores/makefile +++ /dev/null @@ -1,41 +0,0 @@ -CORES = fceumm gambatte gpsp pcsx_rearmed picodrive snes9x2005_plus -CORES+= mednafen_pce_fast mednafen_vb mednafen_supafaust mgba pokemini race -CORES+= fake-08 - -############################### - -# optional core vars -# *_REPO= -# *_HASH= -# *_CORE= -# *_FLAGS= -# *_MAKEFILE= -# *_BUILD_PATH= - -mednafen_pce_fast_REPO = https://github.com/libretro/beetle-pce-fast-libretro -mednafen_vb_REPO = https://github.com/libretro/beetle-vb-libretro - -fake-08_REPO = https://github.com/jtothebell/fake-08 -fake-08_CORE = fake08_libretro.so -fake-08_BUILD_PATH = fake-08/platform/libretro - -fceumm_REPO = https://github.com/libretro/libretro-fceumm - -gambatte_REPO = https://github.com/libretro/gambatte-libretro - -mednafen_supafaust_REPO = https://github.com/libretro/supafaust - -pcsx_rearmed_MAKEFILE = Makefile.libretro - -picodrive_REPO = https://github.com/irixxxx/picodrive -picodrive_MAKEFILE = Makefile.libretro - -pokemini_REPO = https://github.com/libretro/PokeMini -pokemini_MAKEFILE = Makefile.libretro - -snes9x2005_plus_REPO = https://github.com/libretro/snes9x2005 -snes9x2005_plus_FLAGS = USE_BLARGG_APU=1 - -############################### - -include ../../all/cores/makefile \ No newline at end of file diff --git a/workspace/_unmaintained/magicmini/cores/patches/fake-08.patch b/workspace/_unmaintained/magicmini/cores/patches/fake-08.patch deleted file mode 100644 index fe8edaab3..000000000 --- a/workspace/_unmaintained/magicmini/cores/patches/fake-08.patch +++ /dev/null @@ -1,33 +0,0 @@ -diff --git forkSrcPrefix/platform/libretro/Makefile forkDstPrefix/platform/libretro/Makefile -index be0f1b46bb3ab10be4a9f896f5e8841dd630b35b..4811e985c7ea369e26df9586424d32d8bec9faf7 100644 ---- forkSrcPrefix/platform/libretro/Makefile -+++ forkDstPrefix/platform/libretro/Makefile -@@ -123,7 +123,15 @@ else ifeq ($(platform), miyoomini) - CXXFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7ve -D_NEED_FULL_PATH_ - fpic := -fPIC - SHARED := -shared -Wl,--version-script=link.T -- -+else ifeq ($(platform), magicmini) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ STRIP = $(CROSS_COMPILE)strip -+ CXXFLAGS += -mtune=cortex-a55 -march=armv8-a+crc+simd -+ fpic := -fPIC -+ SHARED := -shared -Wl,--version-script=link.T - else ifeq ($(platform), gcw0) - TARGET := $(TARGET_NAME)_libretro_gcw0.so - CC = /opt/gcw0-toolchain/usr/bin/mipsel-linux-gcc -diff --git forkSrcPrefix/platform/libretro/libretro.cpp forkDstPrefix/platform/libretro/libretro.cpp -index d95ccb6cab52abfe7620ff84dd5cbb450bafe750..24687335ad410096aa48f29e13dcb479171a06fc 100644 ---- forkSrcPrefix/platform/libretro/libretro.cpp -+++ forkDstPrefix/platform/libretro/libretro.cpp -@@ -636,6 +636,7 @@ EXPORT bool retro_load_game(struct retro_game_info const *info) - else { - _vm->QueueCartChange(info->path); - } -+ _vm->UpdateAndDraw(); - - return true; - } diff --git a/workspace/_unmaintained/magicmini/cores/patches/fceumm.patch b/workspace/_unmaintained/magicmini/cores/patches/fceumm.patch deleted file mode 100644 index 82cb0336c..000000000 --- a/workspace/_unmaintained/magicmini/cores/patches/fceumm.patch +++ /dev/null @@ -1,22 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index 0cd567cf174249e92a43c4c78be582ba4c36a57c..2597db6a4fe1a1c4a4a9dd5e42de37f50f643b1c 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -463,6 +463,17 @@ else ifeq ($(platform), miyoo) - PLATFORM_DEFINES += -fomit-frame-pointer -ffast-math -mcpu=arm926ej-s - EXTERNAL_ZLIB = 1 - -+# RGB30 -+else ifeq ($(platform), magicmini) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ fpic := -fPIC -+ SHARED := -shared -Wl,--version-script=src/drivers/libretro/link.T -Wl,-no-undefined -+ PLATFORM_DEFINES += -fomit-frame-pointer -ffast-math -mtune=cortex-a55 -march=armv8.2-a -+ EXTERNAL_ZLIB = 1 -+ - # Windows MSVC 2017 all architectures - else ifneq (,$(findstring windows_msvc2017,$(platform))) - CC = cl.exe diff --git a/workspace/_unmaintained/magicmini/cores/patches/gambatte.patch b/workspace/_unmaintained/magicmini/cores/patches/gambatte.patch deleted file mode 100644 index 89d557290..000000000 --- a/workspace/_unmaintained/magicmini/cores/patches/gambatte.patch +++ /dev/null @@ -1,23 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index ffaba21e7a88f90786d818ab550b68acd05738bf..87309c332f50bb39abba853322f7637d3dc2192d 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -393,6 +393,18 @@ else ifeq ($(platform), retrofw) - CFLAGS += -fomit-frame-pointer -ffast-math -march=mips32 -mtune=mips32 -mhard-float - CXXFLAGS += $(CFLAGS) - -+# RGB30 -+else ifeq ($(platform), magicmini) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ fpic := -fPIC -+ SHARED := -shared -Wl,-version-script=$(version_script) -+ PLATFORM_DEFINES := -DDINGUX -+ CFLAGS += -fomit-frame-pointer -ffast-math -mtune=cortex-a55 -march=armv8.2-a -+ CXXFLAGS += $(CFLAGS) -+ - # MIYOO - else ifeq ($(platform), miyoo) - TARGET := $(TARGET_NAME)_libretro.so diff --git a/workspace/_unmaintained/magicmini/cores/patches/gpsp.patch b/workspace/_unmaintained/magicmini/cores/patches/gpsp.patch deleted file mode 100644 index d807c187d..000000000 --- a/workspace/_unmaintained/magicmini/cores/patches/gpsp.patch +++ /dev/null @@ -1,23 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index dc4b60dec7f70a153dbc2eb849cd5acfc90f9d4d..89f8f4ce13348c134d5c3bced1dc5259964fb647 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -498,6 +498,18 @@ else ifeq ($(platform), miyoo) - HAVE_DYNAREC := 1 - CPU_ARCH := arm - -+else ifeq ($(platform), magicmini) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=link.T -+ fpic := -fPIC -+ CFLAGS += -fomit-frame-pointer -ffast-math -mtune=cortex-a55 -march=armv8.2-a -+ LDFLAGS += -Wl,--no-undefined -+ HAVE_DYNAREC := 1 -+ MMAP_JIT_CACHE = 1 -+ CPU_ARCH := arm64 - - else ifeq ($(platform), miyoomini) - TARGET := $(TARGET_NAME)_plus_libretro.so diff --git a/workspace/_unmaintained/magicmini/cores/patches/mednafen_pce_fast.patch b/workspace/_unmaintained/magicmini/cores/patches/mednafen_pce_fast.patch deleted file mode 100644 index 7d4df4de6..000000000 --- a/workspace/_unmaintained/magicmini/cores/patches/mednafen_pce_fast.patch +++ /dev/null @@ -1,25 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index 5b54403d915e46cb0df8f428355665fbe26e05b4..f72733d9689aa78795ce8b9d777b0ab9fcc5b65e 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -380,6 +380,20 @@ else ifeq ($(platform), miyoo) - CXXFLAGS += -std=c++11 - CFLAGS += -std=gnu11 - -+# RGB30 -+else ifeq ($(platform), magicmini) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ fpic := -fPIC -+ SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T -+ LDFLAGS += -lrt -+ FLAGS += -mtune=cortex-a55 -march=armv8-a+crc+simd -+ FLAGS += -fomit-frame-pointer -ffast-math -D_GNU_SOURCE -+ CXXFLAGS += -std=c++11 -+ CFLAGS += -std=gnu11 -+ - # Windows MSVC 2017 all architectures - else ifneq (,$(findstring windows_msvc2017,$(platform))) - diff --git a/workspace/_unmaintained/magicmini/cores/patches/mednafen_supafaust.patch b/workspace/_unmaintained/magicmini/cores/patches/mednafen_supafaust.patch deleted file mode 100644 index 337f6ad2d..000000000 --- a/workspace/_unmaintained/magicmini/cores/patches/mednafen_supafaust.patch +++ /dev/null @@ -1,34 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index f34a01587cda48cc28ebdfd7f00151b06ea88c42..6966d3c4802b200dea33bdbe8e96b2082a36d577 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -88,6 +88,29 @@ else ifeq ($(platform), classic_armv8_a35) - ARCH = arm - CFLAGS += -march=armv8-a - LDFLAGS += -static-libgcc -static-libstdc++ -+ -+# RGB30 -+else ifeq ($(platform), magicmini) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ STRIP = $(CROSS_COMPILE)strip -+ NEED_BPP := 16 -+ fpic := -fPIC -+ SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T -+ CFLAGS += -mtune=cortex-a55 -march=armv8-a+crc+simd -+ CFLAGS += -Ofast \ -+ -flto=4 -fwhole-program -fuse-linker-plugin \ -+ -fdata-sections -ffunction-sections -Wl,--gc-sections \ -+ -fno-stack-protector -fno-ident -fomit-frame-pointer \ -+ -falign-functions=1 -falign-jumps=1 -falign-loops=1 \ -+ -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-unroll-loops \ -+ -fmerge-all-constants -fno-math-errno -+ CXXFLAGS += $(CFLAGS) -+ HAVE_NEON = 1 -+ ARCH = arm -+ - ####################################### - - else ifeq ($(platform), osx) diff --git a/workspace/_unmaintained/magicmini/cores/patches/mednafen_vb.patch b/workspace/_unmaintained/magicmini/cores/patches/mednafen_vb.patch deleted file mode 100644 index 76429afc4..000000000 --- a/workspace/_unmaintained/magicmini/cores/patches/mednafen_vb.patch +++ /dev/null @@ -1,23 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index 56395207d969b61b52328ea62cea75ff3eb5195d..3765e9be6350f307ea4a24ef6c3201f646cd3815 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -310,6 +310,18 @@ else ifeq ($(platform), emscripten) - TARGET := $(TARGET_NAME)_libretro_$(platform).bc - STATIC_LINKING = 1 - -+# RGB30 -+else ifeq ($(platform), magicmini) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ STRIP = $(CROSS_COMPILE)strip -+ NEED_BPP := 16 -+ fpic := -fPIC -+ SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T -+ FLAGS += -ffast-math -mtune=cortex-a55 -march=armv8-a+crc+simd -flto -+ - # GCW0 - else ifeq ($(platform), gcw0) - TARGET := $(TARGET_NAME)_libretro.so diff --git a/workspace/_unmaintained/magicmini/cores/patches/mgba.patch b/workspace/_unmaintained/magicmini/cores/patches/mgba.patch deleted file mode 100644 index f80c2443b..000000000 --- a/workspace/_unmaintained/magicmini/cores/patches/mgba.patch +++ /dev/null @@ -1,27 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index 9cab7e4bd79fe03fde4aa7448c1d29c84f7b8eba..ec039524e9d14037640c9a5cb569c61a4bfca38e 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -419,6 +419,22 @@ else ifeq ($(platform), miyoo) - CFLAGS += -fno-common -ftree-vectorize -funswitch-loops - DEFINES += -std=c99 - -+# RGB30 -+else ifeq ($(platform), magicmini) -+ TARGET := $(TARGET_NAME)_libretro.so -+ fpic := -fPIC -+ SHARED := -shared -Wl,-version-script=link.T -+ CC = $(CROSS_COMPILE)gcc -+ AR = $(CROSS_COMPILE)ar -+ PLATFORM_DEFINES += -D_GNU_SOURCE -+ CPUFLAGS := -mtune=cortex-a55 -march=armv8-a+crc+simd -+ CFLAGS += -Ofast -flto -DUSE_RENDER_THREAD -DNO_ASM -DARM_ASM -frename-registers -ftree-vectorize -DNDEBUG -fno-ident -+ CFLAGS += -fpic -fomit-frame-pointer -fno-exceptions -fno-non-call-exceptions -Wno-psabi -Wno-format -+ LDFLAGS += $(CPUFLAGS) -lpthread -Wl,--gc-sections -shared -+ LDFLAGS += -Ofast -fno-ident -+ DEFINES += -std=c99 -D_GNU_SOURCE -DHAVE_LOCALE -+ HAVE_VFS_FD = 0 -+ - # Windows - else - TARGET := $(TARGET_NAME)_libretro.dll diff --git a/workspace/_unmaintained/magicmini/cores/patches/pcsx_rearmed.patch b/workspace/_unmaintained/magicmini/cores/patches/pcsx_rearmed.patch deleted file mode 100644 index f28c719d7..000000000 --- a/workspace/_unmaintained/magicmini/cores/patches/pcsx_rearmed.patch +++ /dev/null @@ -1,26 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index 831964f57dfd82c691e4a6707fbf8dea9a8989dc..32c2f38f419b7a3df5508304299d3b2ba544adf0 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -535,6 +535,21 @@ else ifeq ($(platform), miyoo) - DYNAREC = ari64 - HAVE_NEON = 0 - -+# RGB30 -+else ifeq ($(platform), magicmini) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ CFLAGS += -mtune=cortex-a55 -march=armv8-a+crc+simd -+ CFLAGS += -fomit-frame-pointer -ffast-math -fdata-sections -ffunction-sections -fsingle-precision-constant -flto -fPIC -ftree-vectorize -+ LDFLAGS += -flto -fPIC -+ OPTIMIZE += -Ofast -DNDEBUG=1 -+ HAVE_NEON = 1 -+ BUILTIN_GPU = neon -+ ARCH = arm64 -+ DYNAREC = ari64 -+ - # Emscripten - else ifeq ($(platform), emscripten) - TARGET := $(TARGET_NAME)_libretro_$(platform).bc diff --git a/workspace/_unmaintained/magicmini/cores/patches/picodrive.patch b/workspace/_unmaintained/magicmini/cores/patches/picodrive.patch deleted file mode 100644 index baaf183f2..000000000 --- a/workspace/_unmaintained/magicmini/cores/patches/picodrive.patch +++ /dev/null @@ -1,22 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index a57a24c73b12bfe25a526c1fbc223b054b3a02fc..1a8a9054bd2577b481168824cf6cde935b3f2394 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -492,6 +492,17 @@ else ifeq ($(platform), miyoo) - HAVE_ARMv6 = 0 - LOW_MEMORY = 1 - -+# RGB30 -+else ifeq ($(platform), magicmini) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -nostdlib -+ fpic := -fPIC -+ LIBM := -+ CFLAGS += -fomit-frame-pointer -ffast-math -mtune=cortex-a55 -march=armv8.2-a -D__GCW0__ -+ CFLAGS += -DFAMEC_NO_GOTOS -+ - # Windows MSVC 2017 all architectures - else ifneq (,$(findstring windows_msvc2017,$(platform))) - NO_GCC := 1 diff --git a/workspace/_unmaintained/magicmini/cores/patches/pokemini.patch b/workspace/_unmaintained/magicmini/cores/patches/pokemini.patch deleted file mode 100644 index 97d34ec80..000000000 --- a/workspace/_unmaintained/magicmini/cores/patches/pokemini.patch +++ /dev/null @@ -1,23 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index af8cc75cf1a998791a071e8cff915fb8c97ffcc9..e2a4e8cdd951f71f9ebfdb2cf53a21d190939ffd 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -482,6 +482,18 @@ else ifeq ($(platform), miyoo) - CFLAGS += -ffast-math -fomit-frame-pointer -march=armv5te -mtune=arm926ej-s - CFLAGS += -DDINGUX -DRS90 - -+# RGB30 -+else ifeq ($(platform), magicmini) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=libretro/link.T -+ fpic := -fPIC -+ CFLAGS += $(PTHREAD_FLAGS) -+ CFLAGS += -fomit-frame-pointer -ffast-math -mtune=cortex-a55 -march=armv8.2-a -+ CFLAGS += -DDINGUX -+ - # GCW0 - else ifeq ($(platform), gcw0) - TARGET := $(TARGET_NAME)_libretro.so diff --git a/workspace/_unmaintained/magicmini/cores/patches/race.patch b/workspace/_unmaintained/magicmini/cores/patches/race.patch deleted file mode 100644 index 081bd397a..000000000 --- a/workspace/_unmaintained/magicmini/cores/patches/race.patch +++ /dev/null @@ -1,23 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index 792a6d82915c32edd3df6ceec541499f6ca25ac5..dc02b361d7db47e011b6d3addf89cfb31503575a 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -373,6 +373,18 @@ else ifeq ($(platform), miyoo) - CFLAGS += -fomit-frame-pointer -ffast-math -march=armv5te -mtune=arm926ej-s - CXXFLAGS += $(CFLAGS) - -+# RGB30 -+else ifeq ($(platform), magicmini) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ fpic := -fPIC -+ SHARED := -shared -Wl,-version-script=$(LIBRETRO_DIR)/link.T -+ PLATFORM_DEFINES := -DCC_RESAMPLER -DCC_RESAMPLER_NO_HIGHPASS -+ CFLAGS += -fomit-frame-pointer -ffast-math -mtune=cortex-a55 -march=armv8.2-a -+ CXXFLAGS += $(CFLAGS) -+ - # Windows MSVC 2010 x64 - else ifeq ($(platform), windows_msvc2010_x64) - CC = cl.exe diff --git a/workspace/_unmaintained/magicmini/cores/patches/snes9x2005_plus.patch b/workspace/_unmaintained/magicmini/cores/patches/snes9x2005_plus.patch deleted file mode 100644 index d9fc20964..000000000 --- a/workspace/_unmaintained/magicmini/cores/patches/snes9x2005_plus.patch +++ /dev/null @@ -1,23 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index 07d5368a8e78a020813732239ec369d83e931ede..a1f7fefd144c9d0ead913fad350e660c73348991 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -288,6 +288,18 @@ else ifeq ($(platform), miyoo) - FLAGS += -fomit-frame-pointer -ffast-math -march=armv5te -mtune=arm926ej-s - FLAGS += -DFAST_ALIGNED_LSB_WORD_ACCESS -fno-unroll-loops - -+# RGB30 -+else ifeq ($(platform), magicmini) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ fpic := -fPIC -nostdlib -+ SHARED := -shared -Wl,--version-script=link.T -+ LIBM := -+ FLAGS += -fomit-frame-pointer -ffast-math -mtune=cortex-a55 -march=armv8.2-a -+ FLAGS += -DFAST_ALIGNED_LSB_WORD_ACCESS -fno-unroll-loops -+ - # (armv7 a7, hard point, neon based) ### - # NESC, SNESC, C64 mini - else ifeq ($(platform), classic_armv7_a7) diff --git a/workspace/_unmaintained/magicmini/install/boot.sh b/workspace/_unmaintained/magicmini/install/boot.sh deleted file mode 100755 index d4e7f52e5..000000000 --- a/workspace/_unmaintained/magicmini/install/boot.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/sh - -# SYSTEM/usr/bin/autostart.sh - -SDCARD_PATH=/storage/TF2 -SYSTEM_FRAG=/.system/magicmini -UPDATE_FRAG=/NextUI.zip -SYSTEM_PATH=${SDCARD_PATH}${SYSTEM_FRAG} -UPDATE_PATH=${SDCARD_PATH}${UPDATE_FRAG} - -# is there an update available? -if [ -f $UPDATE_PATH ]; then - echo "zip detected" >> $SDCARD_PATH/log.txt - - if [ ! -d $SYSTEM_PATH ]; then - ACTION=installing - echo "install NextUI" >> $SDCARD_PATH/log.txt - else - ACTION=updating - echo "update NextUI" >> $SDCARD_PATH/log.txt - fi - - # show action - dd if=/usr/config/nextui/$ACTION.bmp of=/dev/fb0 bs=71 skip=1 - echo 0,0 > /sys/class/graphics/fb0/pan - - unzip -o $UPDATE_PATH -d $SDCARD_PATH >> $SDCARD_PATH/log.txt - rm -f $UPDATE_PATH - - # the updated system finishes the install/update - if [ -f $SYSTEM_PATH/bin/install.sh ]; then - $SYSTEM_PATH/bin/install.sh >> $SDCARD_PATH/log.txt - fi -fi - -LAUNCH_PATH=$SYSTEM_PATH/paks/NextUI.pak/launch.sh -if [ -f $LAUNCH_PATH ]; then - $LAUNCH_PATH -fi - -sync && shutdown now diff --git a/workspace/_unmaintained/magicmini/install/installing.bmp b/workspace/_unmaintained/magicmini/install/installing.bmp deleted file mode 100755 index 66d9471714a7f31b17cb1bc1b2d5b032f55d4d1f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1228872 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 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U cAV7cs0RjXF5FkK+009C72oNAZ;5R1le=`nV4gdfE diff --git a/workspace/_unmaintained/magicmini/install/notes.txt b/workspace/_unmaintained/magicmini/install/notes.txt deleted file mode 100644 index 9762c8b3d..000000000 --- a/workspace/_unmaintained/magicmini/install/notes.txt +++ /dev/null @@ -1,18 +0,0 @@ -640x480 bmp, rotated 90 degrees - -File format: Windows -Flip row order: [x] - -Advanced Modes -32 bit -(•) X8 R8 G8 B8 - -show with - - dd if=image.bmp of=/dev/fb0 bs=71 skip=1 - -70 is the bitmap header (as saved by Photoshop) -+1 to address white (xxFFFFFF) shifting to teal (00FFFFxx) - -installing and updating bmp will be copied to SYSTEM.squashfs/usr/config/nextui/ -boot.sh will become SYSTEM.squashfs/usr/bin/autostart.sh \ No newline at end of file diff --git a/workspace/_unmaintained/magicmini/install/update.sh b/workspace/_unmaintained/magicmini/install/update.sh deleted file mode 100755 index 827a8b0f3..000000000 --- a/workspace/_unmaintained/magicmini/install/update.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -# becomes /.system/magicmini/bin/install.sh - -# clean up from an previous ill-considered update -DTB_PATH=/storage/TF2/.system/magicmini/dat/rk3562-magicx-linux.dtb -if [ -f "$DTB_PATH" ]; then - rm -rf "$DTB_PATH" -fi - diff --git a/workspace/_unmaintained/magicmini/install/updating.bmp b/workspace/_unmaintained/magicmini/install/updating.bmp deleted file mode 100755 index f3e8ad71019edd7a1b3a4868cc5e2b632df01ec1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1228872 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 -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -// #include "defines.h" - -#define VOLUME_MIN 0 -#define VOLUME_MAX 20 -#define BRIGHTNESS_MIN 0 -#define BRIGHTNESS_MAX 10 - -// uses different codes from SDL -#define CODE_MENU 704 -#define CODE_PLUS 115 -#define CODE_MINUS 114 - -// for ev.value -#define RELEASED 0 -#define PRESSED 1 -#define REPEAT 2 - -#define INPUT_COUNT 2 -static int inputs[INPUT_COUNT]; -static struct input_event ev; - -int main (int argc, char *argv[]) { - InitSettings(); - - // TODO: will require two inputs - // input_fd = open("/dev/input/event0", O_RDONLY | O_NONBLOCK | O_CLOEXEC); - inputs[0] = open("/dev/input/event2", O_RDONLY | O_NONBLOCK | O_CLOEXEC); // gamepad/menu - inputs[1] = open("/dev/input/event3", O_RDONLY | O_NONBLOCK | O_CLOEXEC); // volume - - uint32_t input; - uint32_t val; - uint32_t menu_pressed = 0; - - uint32_t up_pressed = 0; - uint32_t up_just_pressed = 0; - uint32_t up_repeat_at = 0; - - uint32_t down_pressed = 0; - uint32_t down_just_pressed = 0; - uint32_t down_repeat_at = 0; - - uint8_t ignore; - uint32_t then; - uint32_t now; - struct timeval tod; - - gettimeofday(&tod, NULL); - then = tod.tv_sec * 1000 + tod.tv_usec / 1000; // essential SDL_GetTicks() - ignore = 0; - - while (1) { - gettimeofday(&tod, NULL); - now = tod.tv_sec * 1000 + tod.tv_usec / 1000; - if (now-then>1000) ignore = 1; // ignore input that arrived during sleep - - for (int i=0; i REPEAT )) continue; - // printf("code: %i (%i)\n", ev.code, val); fflush(stdout); - switch (ev.code) { - case CODE_MENU: - menu_pressed = val; - break; - break; - case CODE_PLUS: - up_pressed = up_just_pressed = val; - if (val) up_repeat_at = now + 300; - break; - case CODE_MINUS: - down_pressed = down_just_pressed = val; - if (val) down_repeat_at = now + 300; - break; - default: - break; - } - } - } - - if (ignore) { - menu_pressed = 0; - up_pressed = up_just_pressed = 0; - down_pressed = down_just_pressed = 0; - up_repeat_at = 0; - down_repeat_at = 0; - } - - if (up_just_pressed || (up_pressed && now>=up_repeat_at)) { - if (menu_pressed) { - // printf("brightness up\n"); fflush(stdout); - val = GetBrightness(); - if (val=down_repeat_at)) { - if (menu_pressed) { - // printf("brightness down\n"); fflush(stdout); - val = GetBrightness(); - if (val>BRIGHTNESS_MIN) SetBrightness(--val); - } - else { - // printf("volume down\n"); fflush(stdout); - val = GetVolume(); - if (val>VOLUME_MIN) SetVolume(--val); - } - - if (down_just_pressed) down_just_pressed = 0; - else down_repeat_at += 100; - } - - then = now; - ignore = 0; - - usleep(16666); // 60fps - } -} diff --git a/workspace/_unmaintained/magicmini/keymon/makefile b/workspace/_unmaintained/magicmini/keymon/makefile deleted file mode 100755 index edbe1279c..000000000 --- a/workspace/_unmaintained/magicmini/keymon/makefile +++ /dev/null @@ -1,16 +0,0 @@ -#keymon - -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif - -TARGET = keymon - -CC = $(CROSS_COMPILE)gcc -CFLAGS = -Os -lmsettings -lrt -ldl -Wl,--gc-sections -s -CFLAGS += -I. -I../../all/common -I../platform/ -DPLATFORM=\"$(UNION_PLATFORM)\" - -all: - $(CC) $(TARGET).c -o $(TARGET).elf $(CFLAGS) -clean: - rm -rf $(TARGET).elf \ No newline at end of file diff --git a/workspace/_unmaintained/magicmini/libmsettings/makefile b/workspace/_unmaintained/magicmini/libmsettings/makefile deleted file mode 100644 index b1418a21d..000000000 --- a/workspace/_unmaintained/magicmini/libmsettings/makefile +++ /dev/null @@ -1,32 +0,0 @@ -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif -ifeq (,$(PREFIX)) -$(error missing PREFIX for this toolchain) -endif - -TARGET=msettings - -.PHONY: build -.PHONY: clean - -CC = $(CROSS_COMPILE)gcc - -SYSROOT := $(shell $(CC) --print-sysroot) - -INCLUDEDIR = $(SYSROOT)/usr/include -CFLAGS = -I$(INCLUDEDIR) -LDFLAGS = -ldl -lrt -s - -OPTM=-Ofast - -build: - $(CC) -c -Werror -fpic "$(TARGET).c" -Wl,--no-as-needed $(LDFLAGS) - $(CC) -shared -o "lib$(TARGET).so" "$(TARGET).o" $(LDFLAGS) - cp "$(TARGET).h" "$(PREFIX)/include" - cp "lib$(TARGET).so" "$(PREFIX)/lib" -clean: - rm -f *.o - rm -f "lib$(TARGET).so" - rm -f $(PREFIX)/include/$(TARGET).h - rm -f $(PREFIX)/lib/lib$(TARGET).so \ No newline at end of file diff --git a/workspace/_unmaintained/magicmini/libmsettings/msettings.c b/workspace/_unmaintained/magicmini/libmsettings/msettings.c deleted file mode 100644 index dedf799cd..000000000 --- a/workspace/_unmaintained/magicmini/libmsettings/msettings.c +++ /dev/null @@ -1,167 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "msettings.h" - -/////////////////////////////////////// - -#define SETTINGS_VERSION 1 -typedef struct Settings { - int version; // future proofing - int brightness; - int headphones; - int speaker; - int unused[2]; // for future use - // NOTE: doesn't really need to be persisted but still needs to be shared - int jack; - int hdmi; -} Settings; -static Settings DefaultSettings = { - .version = SETTINGS_VERSION, - .brightness = 2, - .headphones = 4, - .speaker = 8, - .jack = 0, - .hdmi = 0, -}; -static Settings* settings; - -#define SHM_KEY "/SharedSettings" -static char SettingsPath[256]; -static int shm_fd = -1; -static int is_host = 0; -static int shm_size = sizeof(Settings); - -void InitSettings(void) { - sprintf(SettingsPath, "%s/msettings.bin", getenv("USERDATA_PATH")); - - shm_fd = shm_open(SHM_KEY, O_RDWR | O_CREAT | O_EXCL, 0644); // see if it exists - if (shm_fd==-1 && errno==EEXIST) { // already exists - puts("Settings client"); - shm_fd = shm_open(SHM_KEY, O_RDWR, 0644); - settings = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); - } - else { // host - puts("Settings host"); // should always be keymon - is_host = 1; - // we created it so set initial size and populate - ftruncate(shm_fd, shm_size); - settings = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); - - int fd = open(SettingsPath, O_RDONLY); - if (fd>=0) { - read(fd, settings, shm_size); - // TODO: use settings->version for future proofing? - close(fd); - } - else { - // load defaults - memcpy(settings, &DefaultSettings, shm_size); - } - - // these shouldn't be persisted - // settings->jack = 0; - // settings->hdmi = 0; - } - - printf("brightness: %i \nspeaker: %i\n", settings->brightness, settings->speaker); fflush(stdout); - - SetVolume(GetVolume()); - SetBrightness(GetBrightness()); - // system("echo $(< " BRIGHTNESS_PATH ")"); -} -void QuitSettings(void) { - munmap(settings, shm_size); - if (is_host) shm_unlink(SHM_KEY); -} -static inline void SaveSettings(void) { - int fd = open(SettingsPath, O_CREAT|O_WRONLY, 0644); - if (fd>=0) { - write(fd, settings, shm_size); - close(fd); - sync(); - } -} - -int GetBrightness(void) { // 0-10 - return settings->brightness; -} -void SetBrightness(int value) { - if (settings->hdmi) return; - - int raw; - switch (value) { - case 0: raw = 1; break; - case 1: raw = 2; break; - case 2: raw = 4; break; - case 3: raw = 6; break; - case 4: raw = 9; break; - case 5: raw = 12; break; - case 6: raw = 16; break; - case 7: raw = 20; break; - case 8: raw = 24; break; - case 9: raw = 28; break; - case 10: raw = 32; break; - } - SetRawBrightness(raw); - settings->brightness = value; - SaveSettings(); -} - -int GetVolume(void) { // 0-20 - return settings->jack ? settings->headphones : settings->speaker; -} -void SetVolume(int value) { - if (settings->hdmi) return; - - if (settings->jack) settings->headphones = value; - else settings->speaker = value; - - int raw = value * 5; - SetRawVolume(raw); - SaveSettings(); -} - -#define BRIGHTNESS_PATH "/sys/devices/platform/backlight/backlight/backlight/brightness" -void SetRawBrightness(int val) { // 0-32 - if (settings->hdmi) return; - - printf("SetRawBrightness(%i)\n", val); fflush(stdout); - // return; - - char cmd[256]; - sprintf(cmd, "echo %i > " BRIGHTNESS_PATH, val); - system(cmd); -} -void SetRawVolume(int val) { // 0 - 100 - printf("SetRawVolume(%i)\n", val); fflush(stdout); - // return; - - char cmd[256]; - sprintf(cmd, "amixer -q sset 'Playback' %i%% > /dev/null 2>&1", val); - system(cmd); -} - -// monitored and set by thread in keymon? -int GetJack(void) { - return settings->jack; -} -void SetJack(int value) { - settings->jack = value; - SetVolume(GetVolume()); -} - -int GetHDMI(void) { return 0; } -void SetHDMI(int value) { /* buh */ } - -int GetMute(void) { return 0; } -void SetMute(int value) {} diff --git a/workspace/_unmaintained/magicmini/libmsettings/msettings.h b/workspace/_unmaintained/magicmini/libmsettings/msettings.h deleted file mode 100644 index 3c72ffe22..000000000 --- a/workspace/_unmaintained/magicmini/libmsettings/msettings.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef __msettings_h__ -#define __msettings_h__ - -void InitSettings(void); -void QuitSettings(void); - -int GetBrightness(void); -int GetVolume(void); - -void SetRawBrightness(int value); // 0-32 -void SetRawVolume(int value); // 0-100 - -void SetBrightness(int value); // 0-10 -void SetVolume(int value); // 0-20 - -int GetJack(void); -void SetJack(int value); // 0-1 - -int GetHDMI(void); -void SetHDMI(int value); // 0-1 - -int GetMute(void); -void SetMute(int value); // 0-1 - -#endif // __msettings_h__ diff --git a/workspace/_unmaintained/magicmini/makefile b/workspace/_unmaintained/magicmini/makefile deleted file mode 100644 index 9419bc32f..000000000 --- a/workspace/_unmaintained/magicmini/makefile +++ /dev/null @@ -1,29 +0,0 @@ -#magicmini - -########################################################### - -ifeq (,$(PLATFORM)) -PLATFORM=$(UNION_PLATFORM) -endif - -ifeq (,$(PLATFORM)) -$(error please specify PLATFORM, eg. PLATFORM=trimui make) -endif - -########################################################### - -REQUIRES_351FILES=other/351files - -all: readmes - -early: $(REQUIRES_351FILES) - mkdir -p other - cd $(REQUIRES_351FILES) && START_PATH=/storage/TF2 CC=${CROSS_COMPILE}gcc make - -clean: - cd $(REQUIRES_351FILES) && make clean - -$(REQUIRES_351FILES): - git clone --depth 1 https://github.com/shauninman/351Files.git $(REQUIRES_351FILES) - -include ../all/readmes/makefile diff --git a/workspace/_unmaintained/magicmini/platform/makefile.copy b/workspace/_unmaintained/magicmini/platform/makefile.copy deleted file mode 100644 index 279ab5e48..000000000 --- a/workspace/_unmaintained/magicmini/platform/makefile.copy +++ /dev/null @@ -1,7 +0,0 @@ -$(PLATFORM): - # $@ - cp ./workspace/$@/other/351files/351Files ./build/EXTRAS/Tools/$@/Files.pak/ - cp -r ./workspace/$@/other/351files/res ./build/EXTRAS/Tools/$@/Files.pak/ - # update - cp ./workspace/$@/install/update.sh ./build/SYSTEM/$@/bin/install.sh - diff --git a/workspace/_unmaintained/magicmini/platform/makefile.env b/workspace/_unmaintained/magicmini/platform/makefile.env deleted file mode 100644 index 212b2bedc..000000000 --- a/workspace/_unmaintained/magicmini/platform/makefile.env +++ /dev/null @@ -1,4 +0,0 @@ -# magicmini -ARCH = -O3 -mtune=cortex-a55 -march=armv8-a+crc+simd -LIBS = -flto -SDL = SDL2 \ No newline at end of file diff --git a/workspace/_unmaintained/magicmini/platform/platform.c b/workspace/_unmaintained/magicmini/platform/platform.c deleted file mode 100644 index 22fa99011..000000000 --- a/workspace/_unmaintained/magicmini/platform/platform.c +++ /dev/null @@ -1,809 +0,0 @@ -// magicmini -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include "defines.h" -#include "platform.h" -#include "api.h" -#include "utils.h" - -#include "scaler.h" - -/////////////////////////////// - -#define RAW_UP 544 -#define RAW_DOWN 545 -#define RAW_LEFT 546 -#define RAW_RIGHT 547 - -#define RAW_A 308 -#define RAW_B 305 -#define RAW_X 307 -#define RAW_Y 304 - -#define RAW_START 315 -#define RAW_SELECT 314 -#define RAW_MENU 704 - -#define RAW_L1 310 -#define RAW_L2 313 -#define RAW_L3 317 -#define RAW_R1 311 -#define RAW_R2 312 -#define RAW_R3 318 - -#define RAW_PLUS 115 -#define RAW_MINUS 114 -#define RAW_POWER 116 - -#define RAW_LSY 1 -#define RAW_LSX 0 -#define RAW_RSY 2 -#define RAW_RSX 5 - -#define RAW_MENU1 RAW_L3 -#define RAW_MENU2 RAW_R3 - -#define INPUT_COUNT 3 -static int inputs[INPUT_COUNT]; - -void PLAT_initInput(void) { - inputs[0] = open("/dev/input/event0", O_RDONLY | O_NONBLOCK | O_CLOEXEC); // power - inputs[1] = open("/dev/input/event2", O_RDONLY | O_NONBLOCK | O_CLOEXEC); // gamepad - inputs[2] = open("/dev/input/event3", O_RDONLY | O_NONBLOCK | O_CLOEXEC); // volume -} -void PLAT_quitInput(void) { - for (int i=0; i which has BTN_ constants that conflict with platform.h -struct input_event { - struct timeval time; - __u16 type; - __u16 code; - __s32 value; -}; -#define EV_KEY 0x01 -#define EV_ABS 0x03 - -static void updateButton(int btn, int id, int pressed, uint32_t tick) { - if (btn==BTN_NONE) return; - - if (!pressed) { - pad.is_pressed &= ~btn; // unset - pad.just_repeated &= ~btn; // unset - pad.just_released |= btn; // set - } - else if ((pad.is_pressed & btn)==BTN_NONE) { - pad.just_pressed |= btn; // set - pad.just_repeated |= btn; // set - pad.is_pressed |= btn; // set - pad.repeat_at[id] = tick + PAD_REPEAT_DELAY; - } -} - -void PLAT_pollInput(void) { - // reset transient state - pad.just_pressed = BTN_NONE; - pad.just_released = BTN_NONE; - pad.just_repeated = BTN_NONE; - - uint32_t tick = SDL_GetTicks(); - for (int i=0; i=pad.repeat_at[i])) { - pad.just_repeated |= btn; // set - pad.repeat_at[i] += PAD_REPEAT_INTERVAL; - } - } - - // gross hack for out of order hat events - // doesn't work because we can catch it's - // bad state update but it's own internal - // state is broken so it never sends the - // real release event - // static time_t x_sec = 0; - // static time_t y_sec = 0; - // static suseconds_t x_usec = 0; - // static suseconds_t y_usec = 0; - - // the actual poll - int input; - static struct input_event event; - for (int i=0; i1) continue; // ignore repeats - - pressed = value; - // LOG_info("key event: %i (%i)\n", code,pressed); - if (code==RAW_UP) { btn = BTN_DPAD_UP; id = BTN_ID_DPAD_UP; } - else if (code==RAW_DOWN) { btn = BTN_DPAD_DOWN; id = BTN_ID_DPAD_DOWN; } - else if (code==RAW_LEFT) { btn = BTN_DPAD_LEFT; id = BTN_ID_DPAD_LEFT; } - else if (code==RAW_RIGHT) { btn = BTN_DPAD_RIGHT; id = BTN_ID_DPAD_RIGHT; } - else if (code==RAW_A) { btn = BTN_A; id = BTN_ID_A; } - else if (code==RAW_B) { btn = BTN_B; id = BTN_ID_B; } - else if (code==RAW_X) { btn = BTN_X; id = BTN_ID_X; } - else if (code==RAW_Y) { btn = BTN_Y; id = BTN_ID_Y; } - else if (code==RAW_START) { btn = BTN_START; id = BTN_ID_START; } - else if (code==RAW_SELECT) { btn = BTN_SELECT; id = BTN_ID_SELECT; } - else if (code==RAW_MENU) { btn = BTN_MENU; id = BTN_ID_MENU; } - else if (code==RAW_MENU1) { btn = BTN_MENU; id = BTN_ID_MENU; } - else if (code==RAW_MENU2) { btn = BTN_MENU; id = BTN_ID_MENU; } - else if (code==RAW_L1) { btn = BTN_L1; id = BTN_ID_L1; } - else if (code==RAW_L2) { btn = BTN_L2; id = BTN_ID_L2; } - else if (code==RAW_L3) { btn = BTN_L3; id = BTN_ID_L3; } - else if (code==RAW_R1) { btn = BTN_R1; id = BTN_ID_R1; } - else if (code==RAW_R2) { btn = BTN_R2; id = BTN_ID_R2; } - else if (code==RAW_R3) { btn = BTN_R3; id = BTN_ID_R3; } - else if (code==RAW_PLUS) { btn = BTN_PLUS; id = BTN_ID_PLUS; } - else if (code==RAW_MINUS) { btn = BTN_MINUS; id = BTN_ID_MINUS; } - else if (code==RAW_POWER) { btn = BTN_POWER; id = BTN_ID_POWER; } - } - else if (type==EV_ABS) { - LOG_info("abs event: %i (%i)\n", code,value); - if (code==RAW_LSX) { pad.laxis.x = value; PAD_setAnalog(BTN_ID_ANALOG_LEFT, BTN_ID_ANALOG_RIGHT, pad.laxis.x, tick+PAD_REPEAT_DELAY); } - else if (code==RAW_LSY) { pad.laxis.y = value; PAD_setAnalog(BTN_ID_ANALOG_UP, BTN_ID_ANALOG_DOWN, pad.laxis.y, tick+PAD_REPEAT_DELAY); } - else if (code==RAW_RSX) pad.raxis.x = value; - else if (code==RAW_RSY) pad.raxis.y = value; - } - - if (btn==BTN_NONE) continue; - - updateButton(btn, id, pressed, tick); - if (btn==BTN_L3||btn==BTN_R3) updateButton(BTN_MENU, BTN_ID_MENU, pressed, tick); - } - } -} - -int PLAT_shouldWake(void) { - - int input; - static struct input_event event; - for (int i=0; imode.w) rotate = 3; - vid.renderer = SDL_CreateRenderer(vid.window,-1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC); - // SDL_RenderSetLogicalSize(vid.renderer, w,h); // TODO: wrong, but without and with the below it's even wrong-er - - // int renderer_width,renderer_height; - // SDL_GetRendererOutputSize(vid.renderer, &renderer_width, &renderer_height); - // LOG_info("output size: %ix%i\n", renderer_width, renderer_height); - // if (renderer_width!=w) { // I think this can only be hdmi - // float x_scale = (float)renderer_width / w; - // float y_scale = (float)renderer_height / h; - // SDL_SetWindowSize(vid.window, w / x_scale, h / y_scale); - // - // SDL_GetRendererOutputSize(vid.renderer, &renderer_width, &renderer_height); - // LOG_info("adjusted size: %ix%i\n", renderer_width, renderer_height); - // x_scale = (float)renderer_width / w; - // y_scale = (float)renderer_height / h; - // SDL_RenderSetScale(vid.renderer, x_scale,y_scale); - // - // // for some reason we need to clear and present - // // after setting the window size or we'll miss - // // the first frame - // SDL_RenderClear(vid.renderer); - // SDL_RenderPresent(vid.renderer); - // } - - // SDL_RendererInfo info; - // SDL_GetRendererInfo(vid.renderer, &info); - // LOG_info("Current render driver: %s\n", info.name); - - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY,"1"); // linear - vid.texture = SDL_CreateTexture(vid.renderer,SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, w,h); - SDL_SetTextureBlendMode(vid.texture, SDL_BLENDMODE_BLEND); - vid.target = NULL; // only needed for non-native sizes - - // TODO: doesn't work here - // SDL_SetTextureScaleMode(vid.texture, SDL_ScaleModeLinear); // we always start at device size so use linear for better upscaling over hdmi - - // SDL_ScaleMode scale_mode; - // SDL_GetTextureScaleMode(vid.texture, &scale_mode); - // LOG_info("texture scale mode: %i\n", scale_mode); - - // int format; - // int access_; - // SDL_QueryTexture(vid.texture, &format, &access_, NULL,NULL); - // LOG_info("texture format: %s (streaming: %i)\n", SDL_GetPixelFormatName(format), access_==SDL_TEXTUREACCESS_STREAMING); - - vid.buffer = SDL_CreateRGBSurfaceFrom(NULL, w,h, FIXED_DEPTH, p, RGBA_MASK_565); - vid.screen = SDL_CreateRGBSurface(SDL_SWSURFACE, w,h, FIXED_DEPTH, RGBA_MASK_565); - vid.width = w; - vid.height = h; - vid.pitch = p; - - device_width = w; - device_height = h; - device_pitch = p; - - vid.sharpness = SHARPNESS_SOFT; - - return vid.screen; -} - -static void clearVideo(void) { - SDL_FillRect(vid.screen, NULL, 0); - for (int i=0; i<3; i++) { - SDL_RenderClear(vid.renderer); - SDL_RenderPresent(vid.renderer); - } -} - -void PLAT_quitVideo(void) { - // clearVideo(); - - SDL_FreeSurface(vid.screen); - SDL_FreeSurface(vid.buffer); - if (vid.target) SDL_DestroyTexture(vid.target); - if (vid.effect) SDL_DestroyTexture(vid.effect); - SDL_DestroyTexture(vid.texture); - SDL_DestroyRenderer(vid.renderer); - SDL_DestroyWindow(vid.window); - - - // system("cat /dev/zero > /dev/fb0 2>/dev/null"); - SDL_Quit(); -} - -void PLAT_clearVideo(SDL_Surface* screen) { - SDL_FillRect(screen, NULL, 0); // TODO: revisit -} -void PLAT_clearAll(void) { - PLAT_clearVideo(vid.screen); // TODO: revist - SDL_RenderClear(vid.renderer); -} - -void PLAT_setVsync(int vsync) { - // buh -} - -static int hard_scale = 4; // TODO: base src size, eg. 160x144 can be 4 - -static void resizeVideo(int w, int h, int p) { - if (w==vid.width && h==vid.height && p==vid.pitch) return; - - // TODO: minarch disables crisp (and nn upscale before linear downscale) when native - - if (w>=device_width && h>=device_height) hard_scale = 1; - else if (h>=160) hard_scale = 2; // limits gba and up to 2x (seems sufficient) - else hard_scale = 4; - - LOG_info("resizeVideo(%i,%i,%i) hard_scale: %i crisp: %i\n",w,h,p, hard_scale,vid.sharpness==SHARPNESS_CRISP); - - SDL_FreeSurface(vid.buffer); - SDL_DestroyTexture(vid.texture); - if (vid.target) SDL_DestroyTexture(vid.target); - - SDL_SetHintWithPriority(SDL_HINT_RENDER_SCALE_QUALITY, vid.sharpness==SHARPNESS_SOFT?"1":"0", SDL_HINT_OVERRIDE); - vid.texture = SDL_CreateTexture(vid.renderer,SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, w,h); - SDL_SetTextureBlendMode(vid.texture, SDL_BLENDMODE_BLEND); - - if (vid.sharpness==SHARPNESS_CRISP) { - SDL_SetHintWithPriority(SDL_HINT_RENDER_SCALE_QUALITY, "1", SDL_HINT_OVERRIDE); - vid.target = SDL_CreateTexture(vid.renderer,SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_TARGET, w * hard_scale,h * hard_scale); - SDL_SetTextureBlendMode(vid.target, SDL_BLENDMODE_BLEND); - } - else { - vid.target = NULL; - } - - vid.buffer = SDL_CreateRGBSurfaceFrom(NULL, w,h, FIXED_DEPTH, p, RGBA_MASK_565); - - vid.width = w; - vid.height = h; - vid.pitch = p; -} - -SDL_Surface* PLAT_resizeVideo(int w, int h, int p) { - resizeVideo(w,h,p); - return vid.screen; -} - -void PLAT_setVideoScaleClip(int x, int y, int width, int height) { - // buh -} -void PLAT_setNearestNeighbor(int enabled) { - // buh -} -void PLAT_setSharpness(int sharpness) { - if (vid.sharpness==sharpness) return; - int p = vid.pitch; - vid.pitch = 0; - vid.sharpness = sharpness; - resizeVideo(vid.width,vid.height,p); -} - -static struct FX_Context { - int scale; - int type; - int color; - int next_scale; - int next_type; - int next_color; - int live_type; - int opacity; -} effect = { - .scale = 1, - .next_scale = 1, - .type = EFFECT_NONE, - .next_type = EFFECT_NONE, - .live_type = EFFECT_NONE, - .color = 0, - .next_color = 0, -}; -static void rgb565_to_rgb888(uint32_t rgb565, uint8_t *r, uint8_t *g, uint8_t *b) { - // Extract the red component (5 bits) - uint8_t red = (rgb565 >> 11) & 0x1F; - // Extract the green component (6 bits) - uint8_t green = (rgb565 >> 5) & 0x3F; - // Extract the blue component (5 bits) - uint8_t blue = rgb565 & 0x1F; - - // Scale the values to 8-bit range - *r = (red << 3) | (red >> 2); - *g = (green << 2) | (green >> 4); - *b = (blue << 3) | (blue >> 2); -} -static void updateEffect(void) { - if (effect.next_scale==effect.scale && effect.next_type==effect.type && effect.next_color==effect.color) return; // unchanged - - int live_scale = effect.scale; - int live_color = effect.color; - effect.scale = effect.next_scale; - effect.type = effect.next_type; - effect.color = effect.next_color; - - if (effect.type==EFFECT_NONE) return; // disabled - if (effect.type==effect.live_type && effect.scale==live_scale && effect.color==live_color) return; // already loaded - - char* effect_path; - int opacity = 128; // 1 - 1/2 = 50% - if (effect.type==EFFECT_LINE) { - if (effect.scale<3) { - effect_path = RES_PATH "/line-2.png"; - } - else if (effect.scale<4) { - effect_path = RES_PATH "/line-3.png"; - } - else if (effect.scale<5) { - effect_path = RES_PATH "/line-4.png"; - } - else if (effect.scale<6) { - effect_path = RES_PATH "/line-5.png"; - } - else if (effect.scale<8) { - effect_path = RES_PATH "/line-6.png"; - } - else { - effect_path = RES_PATH "/line-8.png"; - } - } - else if (effect.type==EFFECT_GRID) { - if (effect.scale<3) { - effect_path = RES_PATH "/grid-2.png"; - opacity = 64; // 1 - 3/4 = 25% - } - else if (effect.scale<4) { - effect_path = RES_PATH "/grid-3.png"; - opacity = 112; // 1 - 5/9 = ~44% - } - else if (effect.scale<5) { - effect_path = RES_PATH "/grid-4.png"; - opacity = 144; // 1 - 7/16 = ~56% - } - else if (effect.scale<6) { - effect_path = RES_PATH "/grid-5.png"; - opacity = 160; // 1 - 9/25 = ~64% - } - else if (effect.scale<8) { - effect_path = RES_PATH "/grid-6.png"; - opacity = 112; // 1 - 5/9 = ~44% - } - else if (effect.scale<11) { - effect_path = RES_PATH "/grid-8.png"; - opacity = 144; // 1 - 7/16 = ~56% - } - else { - effect_path = RES_PATH "/grid-11.png"; - opacity = 136; // 1 - 57/121 = ~52% - } - } - - // LOG_info("effect: %s opacity: %i\n", effect_path, opacity); - SDL_Surface* tmp = IMG_Load(effect_path); - if (tmp) { - if (effect.type==EFFECT_GRID) { - if (effect.color) { - // LOG_info("dmg color grid...\n"); - - uint8_t r,g,b; - rgb565_to_rgb888(effect.color,&r,&g,&b); - // LOG_info("rgb %i,%i,%i\n",r,g,b); - - uint32_t* pixels = (uint32_t*)tmp->pixels; - int width = tmp->w; - int height = tmp->h; - for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) { - uint32_t pixel = pixels[y * width + x]; - uint8_t _,a; - SDL_GetRGBA(pixel, tmp->format, &_, &_, &_, &a); - if (a) pixels[y * width + x] = SDL_MapRGBA(tmp->format, r,g,b, a); - } - } - } - } - - if (vid.effect) SDL_DestroyTexture(vid.effect); - vid.effect = SDL_CreateTextureFromSurface(vid.renderer, tmp); - SDL_SetTextureBlendMode(vid.effect, SDL_BLENDMODE_BLEND); - effect.opacity = opacity; - SDL_SetTextureAlphaMod(vid.effect, opacity); - SDL_FreeSurface(tmp); - effect.live_type = effect.type; - } -} -void PLAT_setEffect(int next_type) { - effect.next_type = next_type; -} -void PLAT_setEffectColor(int next_color) { - effect.next_color = next_color; -} -void PLAT_vsync(int remaining) { - if (remaining>0) SDL_Delay(remaining); -} - -scaler_t PLAT_getScaler(GFX_Renderer* renderer) { - // LOG_info("getScaler for scale: %i\n", renderer->scale); - effect.next_scale = renderer->scale; - return scale1x1_c16; -} - -void PLAT_blitRenderer(GFX_Renderer* renderer) { - vid.blit = renderer; - SDL_RenderClear(vid.renderer); - resizeVideo(vid.blit->true_w,vid.blit->true_h,vid.blit->src_p); -} - -static uint8_t combine_alpha(uint8_t a, uint8_t b) { - return (a * b + 255) / 255; -} -void PLAT_flip(SDL_Surface* IGNORED, int ignored) { - int alpha = GetBrightness(); - if (alpha<5) alpha = 255 - (192 - (alpha * 192) / 5); - else alpha = 255; - - if (!vid.blit) { - resizeVideo(device_width,device_height,FIXED_PITCH); // !!!??? - SDL_UpdateTexture(vid.texture,NULL,vid.screen->pixels,vid.screen->pitch); - SDL_SetTextureAlphaMod(vid.texture, alpha); - if (rotate) SDL_RenderCopyEx(vid.renderer,vid.texture,NULL,&(SDL_Rect){0,device_width,device_width,device_height},rotate*90,NULL,SDL_FLIP_NONE); - else SDL_RenderCopy(vid.renderer, vid.texture, NULL,NULL); - SDL_RenderPresent(vid.renderer); - return; - } - - // uint32_t then = SDL_GetTicks(); - SDL_UpdateTexture(vid.texture,NULL,vid.blit->src,vid.blit->src_p); - // LOG_info("blit blocked for %ims (%i,%i)\n", SDL_GetTicks()-then,vid.buffer->w,vid.buffer->h); - - SDL_Texture* target = vid.texture; - int x = vid.blit->src_x; - int y = vid.blit->src_y; - int w = vid.blit->src_w; - int h = vid.blit->src_h; - if (vid.sharpness==SHARPNESS_CRISP) { - SDL_SetRenderTarget(vid.renderer,vid.target); - SDL_SetTextureAlphaMod(vid.texture, 255); - SDL_RenderCopy(vid.renderer, vid.texture, NULL,NULL); - SDL_SetRenderTarget(vid.renderer,NULL); - x *= hard_scale; - y *= hard_scale; - w *= hard_scale; - h *= hard_scale; - target = vid.target; - } - - SDL_Rect* src_rect = &(SDL_Rect){x,y,w,h}; - SDL_Rect* dst_rect = &(SDL_Rect){0,0,device_width,device_height}; - if (vid.blit->aspect==0) { // native or cropped - // LOG_info("src_rect %i,%i %ix%i\n",src_rect->x,src_rect->y,src_rect->w,src_rect->h); - - int w = vid.blit->src_w * vid.blit->scale; - int h = vid.blit->src_h * vid.blit->scale; - int x = (device_width - w) / 2; - int y = (device_height - h) / 2; - dst_rect->x = x; - dst_rect->y = y; - dst_rect->w = w; - dst_rect->h = h; - - // LOG_info("dst_rect %i,%i %ix%i\n",dst_rect->x,dst_rect->y,dst_rect->w,dst_rect->h); - } - else if (vid.blit->aspect>0) { // aspect - int h = device_height; - int w = h * vid.blit->aspect; - if (w>device_width) { - double ratio = 1 / vid.blit->aspect; - w = device_width; - h = w * ratio; - } - int x = (device_width - w) / 2; - int y = (device_height - h) / 2; - // dst_rect = &(SDL_Rect){x,y,w,h}; - dst_rect->x = x; - dst_rect->y = y; - dst_rect->w = w; - dst_rect->h = h; - } - - int ox,oy; - oy = (device_width-device_height)/2; - ox = -oy; - SDL_SetTextureAlphaMod(target, alpha); - if (rotate) SDL_RenderCopyEx(vid.renderer,target,src_rect,&(SDL_Rect){ox+dst_rect->x,oy+dst_rect->y,dst_rect->w,dst_rect->h},rotate*90,NULL,SDL_FLIP_NONE); - else SDL_RenderCopy(vid.renderer, target, src_rect, dst_rect); - - updateEffect(); - if (vid.blit && effect.type!=EFFECT_NONE && vid.effect) { - ox = effect.scale - (dst_rect->x % effect.scale); - oy = effect.scale - (dst_rect->y % effect.scale); - if (ox==effect.scale) ox = 0; - if (oy==effect.scale) oy = 0; - int opacity = combine_alpha(alpha, effect.opacity); - // LOG_info("alpha: %i opacity: %i combined: %i\n percent: %f", alpha, effect.opacity, opacity, (float)opacity/255); - SDL_SetTextureAlphaMod(vid.effect, opacity); - if (rotate) SDL_RenderCopyEx(vid.renderer,vid.effect,dst_rect,&(SDL_Rect){oy,ox+device_width,device_width,device_height},rotate*90,&(SDL_Point){0,0},SDL_FLIP_NONE); - else SDL_RenderCopy(vid.renderer, vid.effect, dst_rect,dst_rect); - } - - // uint32_t then = SDL_GetTicks(); - SDL_RenderPresent(vid.renderer); - // LOG_info("SDL_RenderPresent blocked for %ims\n", SDL_GetTicks()-then); - vid.blit = NULL; -} - -/////////////////////////////// - -// TODO: -#define OVERLAY_WIDTH PILL_SIZE // unscaled -#define OVERLAY_HEIGHT PILL_SIZE // unscaled -#define OVERLAY_BPP 4 -#define OVERLAY_DEPTH 16 -#define OVERLAY_PITCH (OVERLAY_WIDTH * OVERLAY_BPP) // unscaled -#define OVERLAY_RGBA_MASK 0x00ff0000,0x0000ff00,0x000000ff,0xff000000 // ARGB -static struct OVL_Context { - SDL_Surface* overlay; -} ovl; - -SDL_Surface* PLAT_initOverlay(void) { - ovl.overlay = SDL_CreateRGBSurface(SDL_SWSURFACE, SCALE2(OVERLAY_WIDTH,OVERLAY_HEIGHT),OVERLAY_DEPTH,OVERLAY_RGBA_MASK); - return ovl.overlay; -} -void PLAT_quitOverlay(void) { - if (ovl.overlay) SDL_FreeSurface(ovl.overlay); -} -void PLAT_enableOverlay(int enable) { - -} - -/////////////////////////////// - -static int online = 0; -void PLAT_getBatteryStatus(int* is_charging, int* charge) { - PLAT_getBatteryStatusFine(is_charging, charge); - - // worry less about battery and more about the game you're playing - if (*charge>80) *charge = 100; - else if (*charge>60) *charge = 80; - else if (*charge>40) *charge = 60; - else if (*charge>20) *charge = 40; - else if (*charge>10) *charge = 20; - else *charge = 10; -} - -void PLAT_getBatteryStatusFine(int* is_charging, int* charge) -{ - // *is_charging = 0; - // *charge = PWR_LOW_CHARGE; - // return; - - *is_charging = getInt("/sys/class/power_supply/ac/online"); - - // fallback - // char state[256]; - // getFile("/sys/class/power_supply/battery/status", state, 256); - // *is_charging = prefixMatch("Charging",state); // this is working better - - *charge = getInt("/sys/class/power_supply/battery/capacity"); - - // wifi status, just hooking into the regular PWR polling - // char status[16]; - // getFile("/sys/class/net/wlan0/operstate", status,16); - // online = prefixMatch("up", status); -} - -#define BACKLIGHT_PATH "/sys/class/backlight/backlight/bl_power" - -void PLAT_enableBacklight(int enable) { - if (enable) { - SetBrightness(GetBrightness()); - putInt(BACKLIGHT_PATH, FB_BLANK_UNBLANK); - } - else { - SetRawBrightness(0); - system("dd if=/dev/zero of=/dev/fb0"); // does nothing... - putInt(BACKLIGHT_PATH, FB_BLANK_POWERDOWN); - } -} - -void PLAT_powerOff(void) { - system("rm -f /tmp/nextui_exec && sync"); - sleep(2); - - SetRawVolume(MUTE_VOLUME_RAW); - PLAT_enableBacklight(0); - // putInt(LED_PATH,255); - SND_quit(); - VIB_quit(); - PWR_quit(); - GFX_quit(); - exit(0); -} - -/////////////////////////////// - -#define CPU_PATH "/sys/devices/system/cpu/cpufreq/policy0/scaling_setspeed" -#define GPU_PATH "/sys/devices/platform/ff400000.gpu/devfreq/ff400000.gpu/governor" -#define DMC_PATH "/sys/devices/platform/dmc/devfreq/dmc/governor" -void PLAT_setCPUSpeed(int speed) { - int freq = 0; - switch (speed) { - case CPU_SPEED_MENU: freq = 600000; break; - case CPU_SPEED_POWERSAVE: freq = 816000; break; - case CPU_SPEED_NORMAL: freq = 1416000; break; - case CPU_SPEED_PERFORMANCE: freq = 2016000; break; // not viable on lower binned chips - } - - if (speed==CPU_SPEED_PERFORMANCE) { - putFile(GPU_PATH, "performance"); - putFile(DMC_PATH, "performance"); - } - else { - putFile(GPU_PATH, "simple_ondemand"); - putFile(DMC_PATH, "dmc_ondemand"); - } - putInt(CPU_PATH, freq); // userspace -} - -// #define RUMBLE_PATH "/sys/devices/virtual/timed_output/vibrator/enable" -void PLAT_setRumble(int strength) { - // putInt(RUMBLE_PATH, strength?1000:0); -} - -int PLAT_pickSampleRate(int requested, int max) { - return MIN(requested, max); -} - -char* PLAT_getModel(void) { - return "MagicX XU Mini M"; -} - -int PLAT_isOnline(void) { - return online; -} \ No newline at end of file diff --git a/workspace/_unmaintained/magicmini/platform/platform.h b/workspace/_unmaintained/magicmini/platform/platform.h deleted file mode 100644 index f136bd62c..000000000 --- a/workspace/_unmaintained/magicmini/platform/platform.h +++ /dev/null @@ -1,124 +0,0 @@ -// magicmini/platform/platform.h - -#ifndef PLATFORM_H -#define PLATFORM_H - -/////////////////////////////// - -#include "sdl.h" - -/////////////////////////////// - -#define BUTTON_UP BUTTON_NA -#define BUTTON_DOWN BUTTON_NA -#define BUTTON_LEFT BUTTON_NA -#define BUTTON_RIGHT BUTTON_NA - -#define BUTTON_SELECT BUTTON_NA -#define BUTTON_START BUTTON_NA - -#define BUTTON_A BUTTON_NA -#define BUTTON_B BUTTON_NA -#define BUTTON_X BUTTON_NA -#define BUTTON_Y BUTTON_NA - -#define BUTTON_L1 BUTTON_NA -#define BUTTON_R1 BUTTON_NA -#define BUTTON_L2 BUTTON_NA -#define BUTTON_R2 BUTTON_NA -#define BUTTON_L3 BUTTON_NA -#define BUTTON_R3 BUTTON_NA - -#define BUTTON_MENU BUTTON_NA -#define BUTTON_POWER BUTTON_NA -#define BUTTON_PLUS BUTTON_NA -#define BUTTON_MINUS BUTTON_NA - -/////////////////////////////// - -#define CODE_UP CODE_NA -#define CODE_DOWN CODE_NA -#define CODE_LEFT CODE_NA -#define CODE_RIGHT CODE_NA - -#define CODE_SELECT CODE_NA -#define CODE_START CODE_NA - -#define CODE_A CODE_NA -#define CODE_B CODE_NA -#define CODE_X CODE_NA -#define CODE_Y CODE_NA - -#define CODE_L1 CODE_NA -#define CODE_R1 CODE_NA -#define CODE_L2 CODE_NA -#define CODE_R2 CODE_NA -#define CODE_L3 CODE_NA -#define CODE_R3 CODE_NA - -#define CODE_MENU CODE_NA -#define CODE_POWER 116 - -#define CODE_PLUS 115 -#define CODE_MINUS 114 - -/////////////////////////////// - -// TODO: unused -#define JOY_UP 13 -#define JOY_DOWN 16 -#define JOY_LEFT 14 -#define JOY_RIGHT 15 - -#define JOY_SELECT 6 -#define JOY_START 7 - -#define JOY_A 0 -#define JOY_B 1 -#define JOY_X 3 -#define JOY_Y 2 - -#define JOY_L1 4 -#define JOY_R1 5 -#define JOY_L2 9 -#define JOY_R2 10 -#define JOY_L3 JOY_NA -#define JOY_R3 JOY_NA - -#define JOY_MENU 8 -#define JOY_POWER JOY_NA -#define JOY_PLUS JOY_NA -#define JOY_MINUS JOY_NA - -/////////////////////////////// - -#define BTN_RESUME BTN_X -#define BTN_SLEEP BTN_POWER -#define BTN_WAKE BTN_POWER -#define BTN_MOD_VOLUME BTN_NONE -#define BTN_MOD_BRIGHTNESS BTN_MENU -#define BTN_MOD_PLUS BTN_PLUS -#define BTN_MOD_MINUS BTN_MINUS - -/////////////////////////////// - -#define FIXED_SCALE 2 -#define FIXED_WIDTH 640 -#define FIXED_HEIGHT 480 -#define FIXED_BPP 2 -#define FIXED_DEPTH (FIXED_BPP * 8) -#define FIXED_PITCH (FIXED_WIDTH * FIXED_BPP) -#define FIXED_SIZE (FIXED_PITCH * FIXED_HEIGHT) - -/////////////////////////////// - -#define SDCARD_PATH "/storage/TF2" -#define MUTE_VOLUME_RAW 0 -#define HAS_NEON -#define SAMPLES 400 // fix for (most) fceumm underruns, not super helpful here - -// this should be set to the devices native screen refresh rate -#define SCREEN_FPS 60.0 -/////////////////////////////// - -#endif diff --git a/workspace/_unmaintained/miyoomini/batmon/batmon.c b/workspace/_unmaintained/miyoomini/batmon/batmon.c deleted file mode 100644 index e2d905987..000000000 --- a/workspace/_unmaintained/miyoomini/batmon/batmon.c +++ /dev/null @@ -1,187 +0,0 @@ -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -// mmplus axp223 (via eggs) -#define AXPDEV "/dev/i2c-1" -#define AXPID (0x34) - -// -// AXP223 write (plus) -// 32 .. bit7: Shutdown Control -// -int axp_write(unsigned char address, unsigned char val) { - struct i2c_msg msg[1]; - struct i2c_rdwr_ioctl_data packets; - unsigned char buf[2]; - int ret; - int fd = open(AXPDEV, O_RDWR); - ioctl(fd, I2C_TIMEOUT, 5); - ioctl(fd, I2C_RETRIES, 1); - - buf[0] = address; - buf[1] = val; - msg[0].addr = AXPID; - msg[0].flags = 0; - msg[0].len = 2; - msg[0].buf = buf; - - packets.nmsgs = 1; - packets.msgs = &msg[0]; - ret = ioctl(fd, I2C_RDWR, &packets); - - close(fd); - if (ret < 0) return -1; - return 0; -} - -// -// AXP223 read (plus) -// 00 .. C4/C5(USBDC connected) 00(discharging) -// bit7: ACIN presence indication 0:ACIN not exist, 1:ACIN exists -// bit6: Indicating whether ACIN is usable (used by axp_test) -// bit4: Indicating whether VBUS is usable (used by axp_test) -// bit2: Indicating the Battery current direction 0: discharging, 1: charging -// bit0: Indicating whether the boot source is ACIN or VBUS -// 01 .. 70(charging) 30(non-charging) -// bit6: Charge indication 0:not charge or charge finished, 1: in charging -// B9 .. (& 0x7F) battery percentage -// -int axp_read(unsigned char address) { - struct i2c_msg msg[2]; - struct i2c_rdwr_ioctl_data packets; - unsigned char val; - int ret; - int fd = open(AXPDEV, O_RDWR); - ioctl(fd, I2C_TIMEOUT, 5); - ioctl(fd, I2C_RETRIES, 1); - - msg[0].addr = AXPID; - msg[0].flags = 0; - msg[0].len = 1; - msg[0].buf = &address; - msg[1].addr = AXPID; - msg[1].flags = I2C_M_RD; - msg[1].len = 1; - msg[1].buf = &val; - - packets.nmsgs = 2; - packets.msgs = &msg[0]; - ret = ioctl(fd, I2C_RDWR, &packets); - - close(fd); - if(ret < 0) return -1; - return val; -} - -static int is_plus = 0; -static int is_charging = 1; -static int screen_on = 0; -static unsigned long screen_start; -void screenOn(void) { - screen_start = SDL_GetTicks(); - if (!screen_on) system("echo 50 > /sys/class/pwm/pwmchip0/pwm0/duty_cycle"); - screen_on = 1; -} -void screenOff(void) { - system("echo 0 > /sys/class/pwm/pwmchip0/pwm0/duty_cycle"); - screen_on = 0; -} -int isCharging(void) { - if (is_plus) return (axp_read(0x00) & 0x4) > 0; - - int i = 0; - FILE *file = fopen("/sys/devices/gpiochip0/gpio/gpio59/value", "r"); - if (file!=NULL) { - fscanf(file, "%i", &i); - fclose(file); - } - return i; -} -static pthread_t charging_pt; -void* chargingThread(void* arg) { - while (1) { - sleep(1); - is_charging = isCharging(); - } -} - -static int launch = 0; -static int input_fd; -static pthread_t input_pt; -void* inputThread(void* arg) { - struct input_event event; - while (read(input_fd, &event, sizeof(event))==sizeof(event)) { - if (event.type!=EV_KEY || event.value>1) continue; - if (event.type==EV_KEY) screenOn(); - if (event.code==KEY_POWER) launch = 1; - } -} - -int main(void) { - is_plus = access("/customer/app/axp_test", F_OK)==0; - int fb0_fd = open("/dev/fb0", O_RDWR); - struct fb_var_screeninfo vinfo; - ioctl(fb0_fd, FBIOGET_VSCREENINFO, &vinfo); - int map_size = vinfo.xres * vinfo.yres * (vinfo.bits_per_pixel / 8); // 640x480x4 - char* fb0_map = (char*)mmap(0, map_size, PROT_READ | PROT_WRITE, MAP_SHARED, fb0_fd, 0); - - memset(fb0_map, 0, map_size); // clear screen - - SDL_Surface* img = IMG_Load("/mnt/SDCARD/.system/res/charging-640-480.png"); // 24-bit opaque png - - uint8_t* dst = (uint8_t*)fb0_map; // rgba - uint8_t* src = (uint8_t*)img->pixels; // bgr - src += ((img->h * img->w) - 1) * 3; - for (int y=0; yh; y++) { - for (int x=0; xw; x++) { - *(dst+0) = *(src+2); // r - *(dst+1) = *(src+1); // g - *(dst+2) = *(src+0); // b - *(dst+3) = 0xf; // alpha - dst += 4; - src -= 3; - } - } - SDL_FreeSurface(img); - - screenOn(); - - input_fd = open("/dev/input/event0", O_RDONLY); - pthread_create(&input_pt, NULL, &inputThread, NULL); - - pthread_create(&charging_pt, NULL, &chargingThread, NULL); - - while (!launch && is_charging) { - if (screen_on && SDL_GetTicks()-screen_start>=3000) screenOff(); - } - - close(input_fd); - - pthread_cancel(input_pt); - pthread_join(input_pt, NULL); - - pthread_cancel(charging_pt); - pthread_join(charging_pt, NULL); - - munmap(fb0_map, map_size); - close(fb0_fd); - - if (!launch) { - system("shutdown"); - while (1) pause(); - } - - return EXIT_SUCCESS; -} diff --git a/workspace/_unmaintained/miyoomini/batmon/makefile b/workspace/_unmaintained/miyoomini/batmon/makefile deleted file mode 100644 index 60292e611..000000000 --- a/workspace/_unmaintained/miyoomini/batmon/makefile +++ /dev/null @@ -1,15 +0,0 @@ -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif - -TARGET = batmon -PRODUCT = $(TARGET).elf - -CC = $(CROSS_COMPILE)gcc -CFLAGS = -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7ve -LDFLAGS = -lSDL -lSDL_image -lpthread - -all: - $(CC) $(TARGET).c -o $(PRODUCT) $(CFLAGS) $(LDFLAGS) -clean: - rm -f $(PRODUCT) \ No newline at end of file diff --git a/workspace/_unmaintained/miyoomini/blank/blank.c b/workspace/_unmaintained/miyoomini/blank/blank.c deleted file mode 100644 index 3f396fce0..000000000 --- a/workspace/_unmaintained/miyoomini/blank/blank.c +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include - -#include -#include -#include -#include -#include - -int main(int argc , char* argv[]) { - // clear screen - int fb0_fd = open("/dev/fb0", O_RDWR); - struct fb_var_screeninfo vinfo; - ioctl(fb0_fd, FBIOGET_VSCREENINFO, &vinfo); - int map_size = vinfo.xres * vinfo.yres * (vinfo.bits_per_pixel / 8); // 640x480x4 - char* fb0_map = (char*)mmap(0, map_size, PROT_READ | PROT_WRITE, MAP_SHARED, fb0_fd, 0); - memset(fb0_map, 0, map_size); - munmap(fb0_map, map_size); - close(fb0_fd); - return 0; -} diff --git a/workspace/_unmaintained/miyoomini/blank/makefile b/workspace/_unmaintained/miyoomini/blank/makefile deleted file mode 100644 index 9ed596a00..000000000 --- a/workspace/_unmaintained/miyoomini/blank/makefile +++ /dev/null @@ -1,15 +0,0 @@ -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif - -TARGET = blank -PRODUCT = $(TARGET).elf - -CC = $(CROSS_COMPILE)gcc -CFLAGS = -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7ve -LDFLAGS = - -all: - $(CC) $(TARGET).c -o $(PRODUCT) $(CFLAGS) $(LDFLAGS) -clean: - rm -f $(PRODUCT) \ No newline at end of file diff --git a/workspace/_unmaintained/miyoomini/cores/makefile b/workspace/_unmaintained/miyoomini/cores/makefile deleted file mode 100644 index fdd68e554..000000000 --- a/workspace/_unmaintained/miyoomini/cores/makefile +++ /dev/null @@ -1,40 +0,0 @@ -CORES = fceumm gambatte gpsp pcsx_rearmed picodrive snes9x2005_plus -CORES+= mednafen_pce_fast mednafen_vb fake-08 mednafen_supafaust mgba pokemini race - -############################### - -# optional core vars -# *_REPO= -# *_HASH= -# *_CORE= -# *_FLAGS= -# *_MAKEFILE= -# *_BUILD_PATH= - -mednafen_pce_fast_REPO = https://github.com/libretro/beetle-pce-fast-libretro -mednafen_vb_REPO = https://github.com/libretro/beetle-vb-libretro - -fake-08_REPO = https://github.com/jtothebell/fake-08 -fake-08_CORE = fake08_libretro.so -fake-08_BUILD_PATH = fake-08/platform/libretro - -fceumm_REPO = https://github.com/libretro/libretro-fceumm - -gambatte_REPO = https://github.com/libretro/gambatte-libretro - -mednafen_supafaust_REPO = https://github.com/libretro/supafaust - -pcsx_rearmed_MAKEFILE = Makefile.libretro - -picodrive_REPO = https://github.com/irixxxx/picodrive -picodrive_MAKEFILE = Makefile.libretro - -pokemini_REPO = https://github.com/libretro/PokeMini -pokemini_MAKEFILE = Makefile.libretro - -snes9x2005_plus_REPO = https://github.com/libretro/snes9x2005 -snes9x2005_plus_FLAGS = USE_BLARGG_APU=1 - -############################### - -include ../../all/cores/makefile \ No newline at end of file diff --git a/workspace/_unmaintained/miyoomini/cores/patches/fake-08.patch b/workspace/_unmaintained/miyoomini/cores/patches/fake-08.patch deleted file mode 100644 index 94f35780e..000000000 --- a/workspace/_unmaintained/miyoomini/cores/patches/fake-08.patch +++ /dev/null @@ -1,33 +0,0 @@ -diff --git forkSrcPrefix/platform/libretro/libretro.cpp forkDstPrefix/platform/libretro/libretro.cpp -index d95ccb6cab52abfe7620ff84dd5cbb450bafe750..24687335ad410096aa48f29e13dcb479171a06fc 100644 ---- forkSrcPrefix/platform/libretro/libretro.cpp -+++ forkDstPrefix/platform/libretro/libretro.cpp -@@ -636,6 +636,7 @@ EXPORT bool retro_load_game(struct retro_game_info const *info) - else { - _vm->QueueCartChange(info->path); - } -+ _vm->UpdateAndDraw(); - - return true; - } -diff --git forkSrcPrefix/platform/libretro/Makefile forkDstPrefix/platform/libretro/Makefile -index be0f1b46bb3ab10be4a9f896f5e8841dd630b35b..0a8048bb88840e6b1e366a745947e047f616033e 100644 ---- forkSrcPrefix/platform/libretro/Makefile -+++ forkDstPrefix/platform/libretro/Makefile -@@ -115,7 +115,7 @@ else ifeq ($(platform), vita) - CXXFLAGS += -Wl,-q -Wall -O3 - STATIC_LINKING = 1 - else ifeq ($(platform), miyoomini) -- TARGET := $(TARGET_NAME)_libretro_miyoomini.so -+ TARGET := $(TARGET_NAME)_libretro.so - CC = arm-linux-gnueabihf-gcc - CXX = arm-linux-gnueabihf-g++ - AR = arm-linux-gnueabihf-ar -@@ -123,7 +123,6 @@ else ifeq ($(platform), miyoomini) - CXXFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7ve -D_NEED_FULL_PATH_ - fpic := -fPIC - SHARED := -shared -Wl,--version-script=link.T -- - else ifeq ($(platform), gcw0) - TARGET := $(TARGET_NAME)_libretro_gcw0.so - CC = /opt/gcw0-toolchain/usr/bin/mipsel-linux-gcc diff --git a/workspace/_unmaintained/miyoomini/cores/patches/fceumm.patch b/workspace/_unmaintained/miyoomini/cores/patches/fceumm.patch deleted file mode 100644 index e7bcc58f0..000000000 --- a/workspace/_unmaintained/miyoomini/cores/patches/fceumm.patch +++ /dev/null @@ -1,28 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index 036c41f48b087c99b2276b2d41a71d661fd85145..891eb96ceeb1da868d6d2ed40392b51b65dcbb20 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -461,6 +461,23 @@ else ifeq ($(platform), miyoo) - PLATFORM_DEFINES += -fomit-frame-pointer -ffast-math -mcpu=arm926ej-s - EXTERNAL_ZLIB = 1 - -+# MIYOOMINI -+else ifeq ($(platform), miyoomini) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=src/drivers/libretro/link.T -Wl,-no-undefined -+ LDFLAGS += -fPIC -flto -+ CFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7ve -+ CFLAGS += -fomit-frame-pointer -ffast-math -fPIC -flto -+ OPTIMIZE := -Ofast -DNDEBUG -+ EXTERNAL_ZLIB = 1 -+ HAVE_NTSC = 0 -+ ifeq (,$(DEBUG)) -+ # LDFLAGS += -s -+ endif -+ - # Windows MSVC 2017 all architectures - else ifneq (,$(findstring windows_msvc2017,$(platform))) - CC = cl.exe diff --git a/workspace/_unmaintained/miyoomini/cores/patches/gambatte.patch b/workspace/_unmaintained/miyoomini/cores/patches/gambatte.patch deleted file mode 100644 index cbe507ce7..000000000 --- a/workspace/_unmaintained/miyoomini/cores/patches/gambatte.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index ffaba21e7a88f90786d818ab550b68acd05738bf..2095b2f843eaf6be9abec24ce3da69b551da86a6 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -381,6 +381,19 @@ else ifeq ($(platform), gcw0) - CFLAGS += -fomit-frame-pointer -ffast-math -march=mips32 -mtune=mips32r2 -mhard-float - CXXFLAGS += $(CFLAGS) - -+# MIYOOMINI -+else ifeq ($(platform), miyoomini) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=$(version_script) -+ LDFLAGS += -fPIC -flto -+ PLATFORM_DEFINES := -DCC_RESAMPLER -DCC_RESAMPLER_NO_HIGHPASS -+ CFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7ve -+ CFLAGS += -fomit-frame-pointer -ffast-math -fPIC -flto -+ CXXFLAGS += $(CFLAGS) -+ - # RETROFW - else ifeq ($(platform), retrofw) - TARGET := $(TARGET_NAME)_libretro.so diff --git a/workspace/_unmaintained/miyoomini/cores/patches/gpsp.patch b/workspace/_unmaintained/miyoomini/cores/patches/gpsp.patch deleted file mode 100644 index 680ad9747..000000000 --- a/workspace/_unmaintained/miyoomini/cores/patches/gpsp.patch +++ /dev/null @@ -1,47 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index dc4b60dec7f70a153dbc2eb849cd5acfc90f9d4d..754d227998603ec0ee49d7b35b607a344924d688 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -499,30 +499,22 @@ else ifeq ($(platform), miyoo) - CPU_ARCH := arm - - -+# MIYOOMINI - else ifeq ($(platform), miyoomini) -- TARGET := $(TARGET_NAME)_plus_libretro.so -- CC = /opt/miyoomini-toolchain/usr/bin/arm-linux-gcc -- CXX = /opt/miyoomini-toolchain/usr/bin/arm-linux-g++ -- AR = /opt/miyoomini-toolchain/usr/bin/arm-linux-ar -- fpic := -fPIC -- SHARED := -shared -Wl,--version-script=link.T -Wl,--no-undefined -- CFLAGS += -Ofast \ -- -flto=4 -fwhole-program -fuse-linker-plugin \ -- -fdata-sections -ffunction-sections -Wl,--gc-sections \ -- -fno-stack-protector -fno-ident -fomit-frame-pointer \ -- -falign-functions=1 -falign-jumps=1 -falign-loops=1 \ -- -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-unroll-loops \ -- -fmerge-all-constants -fno-math-errno \ -- -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -- CXXFLAGS = $(CFLAGS) -std=gnu++11 -- CPPFLAGS += $(CFLAGS) -- ASFLAGS += $(CFLAGS) -- CPU_ARCH := arm -- MMAP_JIT_CACHE = 1 -- HAVE_DYNAREC = 1 -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=link.T -+ fpic := -fPIC -DPIC -+ CFLAGS += -fomit-frame-pointer -ffast-math -+ CFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7ve - HAVE_NEON = 1 - ARCH = arm - BUILTIN_GPU = neon -+ CPU_ARCH := arm -+ MMAP_JIT_CACHE = 1 -+ HAVE_DYNAREC = 1 - - # Windows - else diff --git a/workspace/_unmaintained/miyoomini/cores/patches/mednafen_pce_fast.patch b/workspace/_unmaintained/miyoomini/cores/patches/mednafen_pce_fast.patch deleted file mode 100644 index e994fb198..000000000 --- a/workspace/_unmaintained/miyoomini/cores/patches/mednafen_pce_fast.patch +++ /dev/null @@ -1,29 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index d580571511b43d1ec4597db4a9611b0924bb2c53..2a7a5348c59220f82a99916bf85cc720a0f7f502 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -377,6 +377,24 @@ else ifeq ($(platform), miyoo) - CXXFLAGS += -std=c++11 - CFLAGS += -std=gnu11 - -+# MIYOO MINI -+else ifeq ($(platform), miyoomini) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ fpic := -fPIC -+ SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T -+ LDFLAGS += -lrt -+ CXXFLAGS += -std=c++11 -+ CFLAGS += -std=gnu11 -+ CFLAGS += -fomit-frame-pointer -ffast-math -fPIC -flto -+ CFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7ve -+ LDFLAGS += -flto -+ ifeq (,$(DEBUG)) -+ LDFLAGS += -s -+ endif -+ - # Windows MSVC 2017 all architectures - else ifneq (,$(findstring windows_msvc2017,$(platform))) - diff --git a/workspace/_unmaintained/miyoomini/cores/patches/mednafen_supafaust.patch b/workspace/_unmaintained/miyoomini/cores/patches/mednafen_supafaust.patch deleted file mode 100644 index 5354165e0..000000000 --- a/workspace/_unmaintained/miyoomini/cores/patches/mednafen_supafaust.patch +++ /dev/null @@ -1,42 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index 58120a1a88eab75ca13f2ed062f37d075c05a51b..8c8cd8a54c6b5a874725400d4de6d037ef500d3b 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -38,6 +38,37 @@ ifeq ($(platform), unix) - FLAGS += -pthread - endif - -+# MIYOOMINI -+else ifeq ($(platform), miyoomini) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ fpic := -fPIC -+ SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T -+ CFLAGS += -Ofast \ -+ -flto=4 -fwhole-program -fuse-linker-plugin \ -+ -fdata-sections -ffunction-sections -Wl,--gc-sections \ -+ -fno-stack-protector -fno-ident -fomit-frame-pointer \ -+ -falign-functions=1 -falign-jumps=1 -falign-loops=1 \ -+ -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-unroll-loops \ -+ -fmerge-all-constants -fno-math-errno \ -+ -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -+ CXXFLAGS += $(CFLAGS) -+ CFLAGS += -fPIC -+ LDFLAGS += -flto -+ HAVE_NEON = 1 -+ ARCH = arm -+ ifeq ($(shell echo `$(CC) -dumpversion` "< 4.9" | bc -l), 1) -+ CFLAGS += -march=armv7-a -+ else -+ CFLAGS += -march=armv7ve -+ # If gcc is 5.0 or later -+ ifeq ($(shell echo `$(CC) -dumpversion` ">= 5" | bc -l), 1) -+ LDFLAGS += -static-libgcc -static-libstdc++ -+ endif -+ endif -+ - # Classic Platforms #################### - # Platform affix = classic__<µARCH> - # Help at https://modmyclassic.com/comp diff --git a/workspace/_unmaintained/miyoomini/cores/patches/mednafen_vb.patch b/workspace/_unmaintained/miyoomini/cores/patches/mednafen_vb.patch deleted file mode 100644 index d92a501b6..000000000 --- a/workspace/_unmaintained/miyoomini/cores/patches/mednafen_vb.patch +++ /dev/null @@ -1,29 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index c3d5d3b30d71a8f9ed332482fa2af1c21b02605d..5e710154e499ddd7b1ae699122c38753b0f4bb4c 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -217,6 +217,24 @@ else ifneq (,$(filter $(platform), ps3 psl1ght)) - endif - FLAGS += -D__PS3__ - -+# MIYOO MINI -+else ifeq ($(platform), miyoomini) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ NEED_BPP := 16 -+ fpic := -fPIC -+ SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T -+ LDFLAGS += -lrt -+ CFLAGS += -fomit-frame-pointer -ffast-math -fPIC -flto -+ CFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7ve -+ CPPFLAGS += $(CFLAGS) -+ LDFLAGS += -flto -+ ifeq (,$(DEBUG)) -+ LDFLAGS += -s -+ endif -+ - # PSP - else ifeq ($(platform), psp1) - TARGET := $(TARGET_NAME)_libretro_$(platform).a diff --git a/workspace/_unmaintained/miyoomini/cores/patches/mgba.patch b/workspace/_unmaintained/miyoomini/cores/patches/mgba.patch deleted file mode 100644 index 1cef6a26d..000000000 --- a/workspace/_unmaintained/miyoomini/cores/patches/mgba.patch +++ /dev/null @@ -1,31 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index 108148f4579f4727146e5b8c1e05ef7382654208..35e6399147a4ef75947ecb2ad4a94f0820ef24d0 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -417,6 +417,26 @@ else ifeq ($(platform), miyoo) - CFLAGS += -fno-common -ftree-vectorize -funswitch-loops - DEFINES += -std=c99 - -+# MIYOOMINI -+else ifeq ($(platform), miyoomini) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=link.T -+ fpic := -fPIC -+ PLATFORM_DEFINES += -D_GNU_SOURCE -DHAVE_STRTOF_L -DHAVE_LOCALE -+ CFLAGS += -fomit-frame-pointer -ffast-math -+ CFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7ve -+ CFLAGS += -fno-common -ftree-vectorize -funswitch-loops -+ HAVE_NEON = 1 -+ ARCH = arm -+ BUILTIN_GPU = neon -+ CPU_ARCH := arm -+ MMAP_JIT_CACHE = 1 -+ HAVE_DYNAREC = 1 -+ DEFINES += -std=c99 -+ - # Windows - else - TARGET := $(TARGET_NAME)_libretro.dll diff --git a/workspace/_unmaintained/miyoomini/cores/patches/pcsx_rearmed.patch b/workspace/_unmaintained/miyoomini/cores/patches/pcsx_rearmed.patch deleted file mode 100644 index e9c8404fe..000000000 --- a/workspace/_unmaintained/miyoomini/cores/patches/pcsx_rearmed.patch +++ /dev/null @@ -1,31 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index 7b9618e1ccfc63982be50b82fda498d75e307fdc..f314adcbea17f05f473e1cbafc8711ab8ea0c5f1 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -391,6 +391,26 @@ else ifeq ($(platform), rpi4_64) - fpic := -fPIC - CFLAGS += -march=armv8-a+crc+simd -mtune=cortex-a72 -ftree-vectorize - -+# MIYOOMINI -+else ifeq ($(platform), miyoomini) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ CFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7ve -fomit-frame-pointer -+ CFLAGS += -ffast-math -fdata-sections -ffunction-sections -fsingle-precision-constant -flto -fPIC -+ LDFLAGS += -flto -fPIC -+ ifeq (,$(DEBUG)) -+ # LDFLAGS += -s -+ endif -+ CPU_ARCH := arm -+ OPTIMIZE := -Ofast -DNDEBUG=1 -+ HAVE_NEON = 1 -+ HAVE_NEON_ASM = 1 -+ BUILTIN_GPU = neon -+ ARCH = arm -+ DYNAREC = ari64 -+ - # Classic Platforms #################### - # Platform affix = classic__<µARCH> - # Help at https://modmyclassic.com/comp diff --git a/workspace/_unmaintained/miyoomini/cores/patches/picodrive.patch b/workspace/_unmaintained/miyoomini/cores/patches/picodrive.patch deleted file mode 100644 index 0e90252ec..000000000 --- a/workspace/_unmaintained/miyoomini/cores/patches/picodrive.patch +++ /dev/null @@ -1,35 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index 0d1dc08f81a11cef6b3b7238367b1ff27fcf1ead..1f87c76c3242023c4095f0c9087c52765d93c33c 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -497,6 +497,30 @@ else ifeq ($(platform), miyoo) - HAVE_ARMv6 = 0 - LOW_MEMORY = 1 - -+# MIYOO MINI -+else ifeq ($(platform), miyoomini) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--no-undefined -+ DONT_COMPILE_IN_ZLIB = 1 -+ CFLAGS += -Ofast \ -+ -fdata-sections -ffunction-sections -Wl,--gc-sections \ -+ -fno-stack-protector -fno-ident -fomit-frame-pointer \ -+ -falign-functions=1 -falign-jumps=1 -falign-loops=1 \ -+ -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-unroll-loops \ -+ -fmerge-all-constants -fno-math-errno -+ CFLAGS += -fPIC -flto -+ CFLAGS += -fomit-frame-pointer -ffast-math -D__GCW0__ -+ CFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7ve -+ LDFLAGS += -flto -+ HAVE_NEON = 1 -+ BUILTIN_GPU = neon -+ ifeq (,$(DEBUG)) -+ LDFLAGS += -s -+ endif -+ - # Windows MSVC 2017 all architectures - else ifneq (,$(findstring windows_msvc2017,$(platform))) - NO_GCC := 1 diff --git a/workspace/_unmaintained/miyoomini/cores/patches/pokemini.patch b/workspace/_unmaintained/miyoomini/cores/patches/pokemini.patch deleted file mode 100644 index 6b6206b3d..000000000 --- a/workspace/_unmaintained/miyoomini/cores/patches/pokemini.patch +++ /dev/null @@ -1,27 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index ef2f9e7d1c6041bea8e2c8a61cdd363ed73a7482..ada8785f566af89cc77f5ab2dd9e670b0a998545 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -504,6 +504,22 @@ else ifeq ($(platform), retrofw) - CFLAGS += -ffast-math -fomit-frame-pointer -march=mips32 -mtune=mips32 -mhard-float - CFLAGS += -DDINGUX - -+# MIYOOMINI -+else ifeq ($(platform), miyoomini) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=libretro/link.T -Wl,--no-undefined -+ fpic := -fPIC -+ CFLAGS += -DARM -+ CFLAGS += $(PTHREAD_FLAGS) -+ CFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7ve -+ CFLAGS += -ffast-math -fomit-frame-pointer -+ CFLAGS += -DDINGUX -+ HAVE_NEON = 1 -+ ARCH = arm -+ - else ifeq ($(platform), msvc) - OBJOUT = -Fo - diff --git a/workspace/_unmaintained/miyoomini/cores/patches/race.patch b/workspace/_unmaintained/miyoomini/cores/patches/race.patch deleted file mode 100644 index 8bae037ab..000000000 --- a/workspace/_unmaintained/miyoomini/cores/patches/race.patch +++ /dev/null @@ -1,23 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index 792a6d82915c32edd3df6ceec541499f6ca25ac5..dc02b361d7db47e011b6d3addf89cfb31503575a 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -373,6 +373,18 @@ else ifeq ($(platform), miyoo) - CFLAGS += -fomit-frame-pointer -ffast-math -march=armv5te -mtune=arm926ej-s - CXXFLAGS += $(CFLAGS) - -+# MIYOOMINI -+else ifeq ($(platform), miyoomini) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ fpic := -fPIC -+ SHARED := -shared -Wl,-version-script=$(LIBRETRO_DIR)/link.T -+ PLATFORM_DEFINES := -DCC_RESAMPLER -DCC_RESAMPLER_NO_HIGHPASS -+ CFLAGS += -fomit-frame-pointer -ffast-math -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7ve -+ CXXFLAGS += $(CFLAGS) -+ - # Windows MSVC 2010 x64 - else ifeq ($(platform), windows_msvc2010_x64) - CC = cl.exe diff --git a/workspace/_unmaintained/miyoomini/cores/patches/snes9x2005_plus.patch b/workspace/_unmaintained/miyoomini/cores/patches/snes9x2005_plus.patch deleted file mode 100644 index 700518010..000000000 --- a/workspace/_unmaintained/miyoomini/cores/patches/snes9x2005_plus.patch +++ /dev/null @@ -1,36 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index 07d5368a8e78a020813732239ec369d83e931ede..009f13b8e61c634de4cb83e97785a10b83b4322d 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -288,6 +288,31 @@ else ifeq ($(platform), miyoo) - FLAGS += -fomit-frame-pointer -ffast-math -march=armv5te -mtune=arm926ej-s - FLAGS += -DFAST_ALIGNED_LSB_WORD_ACCESS -fno-unroll-loops - -+# MIYOOMINI -+else ifeq ($(platform), miyoomini) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=link.T -+ LIBM := -+ CFLAGS += -Ofast \ -+ -flto=4 -fwhole-program -fuse-linker-plugin \ -+ -fdata-sections -ffunction-sections -Wl,--gc-sections \ -+ -fno-stack-protector -fno-ident -fomit-frame-pointer \ -+ -falign-functions=1 -falign-jumps=1 -falign-loops=1 \ -+ -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-unroll-loops \ -+ -fmerge-all-constants -fno-math-errno -+ CFLAGS += -fPIC -+ CFLAGS += -DLSB_FIRST -DFAST_ALIGNED_LSB_WORD_ACCESS -DRIGHTSHIFT_IS_SAR -+ CFLAGS += -std=c99 -fomit-frame-pointer -ffast-math -+ CFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7ve -+ LDFLAGS += -flto -+ OPTIMIZE += -Ofast -DNDEBUG=1 -+ ifeq (,$(DEBUG)) -+ LDFLAGS += -s -+ endif -+ - # (armv7 a7, hard point, neon based) ### - # NESC, SNESC, C64 mini - else ifeq ($(platform), classic_armv7_a7) diff --git a/workspace/_unmaintained/miyoomini/install/boot.sh b/workspace/_unmaintained/miyoomini/install/boot.sh deleted file mode 100755 index 75beea8d3..000000000 --- a/workspace/_unmaintained/miyoomini/install/boot.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/sh -# NOTE: becomes .tmp_update/miyoomini.sh - -PLATFORM="miyoomini" -SDCARD_PATH="/mnt/SDCARD" -UPDATE_PATH="$SDCARD_PATH/NextUI.zip" -SYSTEM_PATH="$SDCARD_PATH/.system" - -CPU_PATH=/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor -echo performance > "$CPU_PATH" - -# install/update -if [ -f "$UPDATE_PATH" ]; then - cd $(dirname "$0")/$PLATFORM - - # init backlight - echo 0 > /sys/class/pwm/pwmchip0/export - echo 800 > /sys/class/pwm/pwmchip0/pwm0/period - echo 50 > /sys/class/pwm/pwmchip0/pwm0/duty_cycle - echo 1 > /sys/class/pwm/pwmchip0/pwm0/enable - - # init lcd - cat /proc/ls - sleep 1 - export LCD_INIT=1 - - if [ -d "$SYSTEM_PATH" ]; then - ./show.elf ./updating.png - else - ./show.elf ./installing.png - fi - - mv $SDCARD_PATH/.tmp_update $SDCARD_PATH/.tmp_update-old - unzip -o "$UPDATE_PATH" -d "$SDCARD_PATH" - rm -f "$UPDATE_PATH" - rm -rf $SDCARD_PATH/.tmp_update-old - - # the updated system finishes the install/update - $SYSTEM_PATH/$PLATFORM/bin/install.sh -fi - -# or launch (and keep launched) -LAUNCH_PATH="$SYSTEM_PATH/$PLATFORM/paks/NextUI.pak/launch.sh" -while [ -f "$LAUNCH_PATH" ] ; do - "$LAUNCH_PATH" -done - -reboot # under no circumstances should stock be allowed to touch this card diff --git a/workspace/_unmaintained/miyoomini/install/installing.png b/workspace/_unmaintained/miyoomini/install/installing.png deleted file mode 100644 index acde62551b3bffd9c192883ec06bb5ba0d6efc76..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3647 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 B=!^gW diff --git a/workspace/_unmaintained/miyoomini/keymon/credits.txt b/workspace/_unmaintained/miyoomini/keymon/credits.txt deleted file mode 100644 index e885e5dd1..000000000 --- a/workspace/_unmaintained/miyoomini/keymon/credits.txt +++ /dev/null @@ -1,3 +0,0 @@ -based on eggs custom keymon for Trimui: - https://www.dropbox.com/sh/5e9xwvp672vt8cr/AABUIdw1vLYp9h0waoCUqHPOa/source?dl=0&subfolder_nav_tracking=1 -modified to use libmsettings \ No newline at end of file diff --git a/workspace/_unmaintained/miyoomini/keymon/keymon.c b/workspace/_unmaintained/miyoomini/keymon/keymon.c deleted file mode 100644 index e9e4be760..000000000 --- a/workspace/_unmaintained/miyoomini/keymon/keymon.c +++ /dev/null @@ -1,340 +0,0 @@ -// miyoomini/keymon.c - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -// Button Defines -#define BUTTON_MENU KEY_ESC -#define BUTTON_POWER KEY_POWER -#define BUTTON_SELECT KEY_RIGHTCTRL -#define BUTTON_START KEY_ENTER -#define BUTTON_L1 KEY_E -#define BUTTON_R1 KEY_T -#define BUTTON_L2 KEY_TAB -#define BUTTON_R2 KEY_BACKSPACE -#define BUTTON_PLUS KEY_VOLUMEUP -#define BUTTON_MINUS KEY_VOLUMEDOWN - -// for keyshm -#define VOLUME 0 -#define BRIGHTNESS 1 -#define VOLMAX 20 -#define BRIMAX 10 - -// for ev.value -#define RELEASED 0 -#define PRESSED 1 -#define REPEAT 2 - -// for button_flag -#define SELECT_BIT 0 -#define START_BIT 1 -#define SELECT (1< 0) close(input_fd); - if (sar_fd > 0) close(sar_fd); - exit(exitcode); -} - -static int getADCValue(void) { - if (is_plus) return axp_read(0xB9) & 0x7F; - - ioctl(sar_fd, IOCTL_SAR_SET_CHANNEL_READ_VALUE, &adc_config); - - int current_charge = 0; - if (adc_config.adc_value>=528) { - current_charge = adc_config.adc_value - 478; - } - else if (adc_config.adc_value>=512){ - current_charge = adc_config.adc_value * 2.125 - 1068; - } - else if (adc_config.adc_value>=480){ - current_charge = adc_config.adc_value * 0.51613 - 243.742; - } - - if (current_charge<0) current_charge = 0; - else if (current_charge>100) current_charge = 100; - - return current_charge; -} -static int isCharging(void) { - if (is_plus) return (axp_read(0x00) & 0x4) > 0; - - int i = 0; - FILE *file = fopen("/sys/devices/gpiochip0/gpio/gpio59/value", "r"); - if (file!=NULL) { - fscanf(file, "%i", &i); - fclose(file); - } - return i; -} -static void initADC(void) { - is_plus = access("/customer/app/axp_test", F_OK)==0; - sar_fd = open("/dev/sar", O_WRONLY); - ioctl(sar_fd, IOCTL_SAR_INIT, NULL); -} -static void checkADC(void) { - int was_charging = is_charging; - is_charging = isCharging(); - - int current_charge = getADCValue(); - - static int first_run = 1; - if (first_run || (was_charging && !is_charging)) { - first_run = 0; - eased_charge = current_charge; - } - else if (eased_charge100) eased_charge = 100; - } - else if (eased_charge>current_charge) { - eased_charge -= 1; - if (eased_charge<0) eased_charge = 0; - } - - // new implementation - int bat_fd = open("/tmp/battery", O_CREAT | O_WRONLY | O_TRUNC); - if (bat_fd>0) { - char value[3]; - sprintf(value, "%d", eased_charge); - write(bat_fd, value, strlen(value)); - close(bat_fd); - } -} -static void* runADC(void *arg) { - while(1) { - sleep(5); - checkADC(); - } - return 0; -} - -int main (int argc, char *argv[]) { - initADC(); - checkADC(); - pthread_create(&adc_pt, NULL, &runADC, NULL); - - // Set Initial Volume / Brightness - InitSettings(); - - input_fd = open("/dev/input/event0", O_RDONLY); - - // Main Loop - register uint32_t val; - register uint32_t code; - register uint32_t button_flag = 0; - register uint32_t menu_pressed = 0; - register uint32_t power_pressed = 0; - uint32_t repeat_LR = 0; - while( read(input_fd, &ev, sizeof(ev)) == sizeof(ev) ) { - val = ev.value; - if (( ev.type != EV_KEY ) || ( val > REPEAT )) continue; - code = ev.code; - switch (code) { - case BUTTON_MENU: - if ( val != REPEAT ) menu_pressed = val; - break; - case BUTTON_POWER: - if ( val != REPEAT ) power_pressed = val; - break; - case BUTTON_SELECT: - if ( val != REPEAT ) button_flag = button_flag & (~SELECT) | (val< /mnt/SDCARD/%04i-nice.txt", tick); - // system(cmd); - // - // sprintf(cmd, "top -b -n 1 > /mnt/SDCARD/%04i-top.txt", tick++); - // system(cmd); - // } - break; - case BUTTON_START: - if ( val != REPEAT ) button_flag = button_flag & (~START) | (val<0) SetVolume(--val); - } - else if ((is_plus && menu_pressed) || button_flag==START) { - // VOLUMEDOWN or START + L : brightness down - val = GetBrightness(); - if (val>0) SetBrightness(--val); - } - } - } - break; - case BUTTON_R1: - case BUTTON_R2: - case BUTTON_PLUS: - if (code==BUTTON_PLUS || !is_plus) { - if ( val == REPEAT ) { - // Adjust repeat speed to 1/2 - val = repeat_LR; - repeat_LR ^= PRESSED; - } else { - repeat_LR = 0; - } - - if ( val == PRESSED ) { - if ((is_plus && !menu_pressed) || button_flag==SELECT) { - // VOLUMEUP or SELECT + R : volume up - val = GetVolume(); - if (val -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "msettings.h" - -/////////////////////////////////////// - -// mmplus axp223 (via eggs) -#define AXPDEV "/dev/i2c-1" -#define AXPID (0x34) - -// -// AXP223 write (plus) -// 32 .. bit7: Shutdown Control -// -int axp_write(unsigned char address, unsigned char val) { - struct i2c_msg msg[1]; - struct i2c_rdwr_ioctl_data packets; - unsigned char buf[2]; - int ret; - int fd = open(AXPDEV, O_RDWR); - ioctl(fd, I2C_TIMEOUT, 5); - ioctl(fd, I2C_RETRIES, 1); - - buf[0] = address; - buf[1] = val; - msg[0].addr = AXPID; - msg[0].flags = 0; - msg[0].len = 2; - msg[0].buf = buf; - - packets.nmsgs = 1; - packets.msgs = &msg[0]; - ret = ioctl(fd, I2C_RDWR, &packets); - - close(fd); - if (ret < 0) return -1; - return 0; -} - -// -// AXP223 read (plus) -// 00 .. C4/C5(USBDC connected) 00(discharging) -// bit7: ACIN presence indication 0:ACIN not exist, 1:ACIN exists -// bit6: Indicating whether ACIN is usable (used by axp_test) -// bit4: Indicating whether VBUS is usable (used by axp_test) -// bit2: Indicating the Battery current direction 0: discharging, 1: charging -// bit0: Indicating whether the boot source is ACIN or VBUS -// 01 .. 70(charging) 30(non-charging) -// bit6: Charge indication 0:not charge or charge finished, 1: in charging -// B9 .. (& 0x7F) battery percentage -// -int axp_read(unsigned char address) { - struct i2c_msg msg[2]; - struct i2c_rdwr_ioctl_data packets; - unsigned char val; - int ret; - int fd = open(AXPDEV, O_RDWR); - ioctl(fd, I2C_TIMEOUT, 5); - ioctl(fd, I2C_RETRIES, 1); - - msg[0].addr = AXPID; - msg[0].flags = 0; - msg[0].len = 1; - msg[0].buf = &address; - msg[1].addr = AXPID; - msg[1].flags = I2C_M_RD; - msg[1].len = 1; - msg[1].buf = &val; - - packets.nmsgs = 2; - packets.msgs = &msg[0]; - ret = ioctl(fd, I2C_RDWR, &packets); - - close(fd); - if(ret < 0) return -1; - return val; -} - -/////////////////////////////////////// - -typedef struct Settings { - int version; // future proofing - int brightness; - int unused1; - int speaker; - int unused[4]; // for future use -} Settings; -static Settings DefaultSettings = { - .version = 1, - .brightness = 3, - .speaker = 20, -}; -static Settings* settings; - -#define SHM_KEY "/SharedSettings" -static char SettingsPath[256]; -static int shm_fd = -1; -static int is_host = 0; -static int shm_size = sizeof(Settings); -static int is_plus = 0; - -void InitSettings(void) { - is_plus = access("/customer/app/axp_test", F_OK)==0; - - sprintf(SettingsPath, "%s/msettings.bin", getenv("USERDATA_PATH")); - - shm_fd = shm_open(SHM_KEY, O_RDWR | O_CREAT | O_EXCL, 0644); // see if it exists - if (shm_fd==-1 && errno==EEXIST) { // already exists - puts("Settings client"); - shm_fd = shm_open(SHM_KEY, O_RDWR, 0644); - settings = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); - } - else { // host - puts("Settings host"); - is_host = 1; - // we created it so set initial size and populate - ftruncate(shm_fd, shm_size); - settings = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); - - int fd = open(SettingsPath, O_RDONLY); - if (fd>=0) { - read(fd, settings, shm_size); - // TODO: use settings->version for future proofing - close(fd); - } - else { - // load defaults - memcpy(settings, &DefaultSettings, shm_size); - } - } - printf("brightness: %i\nspeaker: %i\n", settings->brightness, settings->speaker); - - MI_AO_Enable(0); - MI_AO_EnableChn(0,0); - SetVolume(GetVolume()); - SetBrightness(GetBrightness()); -} -void QuitSettings(void) { - munmap(settings, shm_size); - if (is_host) shm_unlink(SHM_KEY); -} -static inline void SaveSettings(void) { - int fd = open(SettingsPath, O_CREAT|O_WRONLY, 0644); - if (fd>=0) { - write(fd, settings, shm_size); - close(fd); - sync(); - } -} - -int GetBrightness(void) { // 0-10 - return settings->brightness; -} -void SetBrightness(int value) { - SetRawBrightness(value==0?6:value*10); - settings->brightness = value; - SaveSettings(); -} - -int GetVolume(void) { // 0-20 - return settings->speaker; -} -void SetVolume(int value) { - int raw = -60 + value * 3; - SetRawVolume(raw); - settings->speaker = value; - SaveSettings(); -} - -void SetRawBrightness(int val) { - int fd = open("/sys/class/pwm/pwmchip0/pwm0/duty_cycle", O_WRONLY); - if (fd>=0) { - dprintf(fd,"%d",val); - close(fd); - } -} - -#define MI_AO_SETMUTE 0x4008690d -static void setMute(int flag) { - int fd = open("/dev/mi_ao", O_RDWR); // TODO: can this be kept open? - if (fd >= 0) { - int buf2[] = {0, flag}; - uint64_t buf1[] = {sizeof(buf2), (uintptr_t)buf2}; - ioctl(fd, MI_AO_SETMUTE, buf1); - close(fd); - } -} - -void SetRawVolume(int val) { - int old; MI_AO_GetVolume(0, &old); - // printf("SetRawVolume(%i) // %i\n", val,old); fflush(stdout); - if (old!=val) { - if (val==-60) setMute(1); - else if (old==-60) setMute(0); - } - MI_AO_SetVolume(0,val); -} - -int GetJack(void) { - return 0; -} -void SetJack(int value) { - // buh -} - -int GetHDMI(void) { - return 0; -} -void SetHDMI(int value) { - // buh -} - -int GetMute(void) { return 0; } -void SetMute(int value) {} diff --git a/workspace/_unmaintained/miyoomini/libmsettings/msettings.h b/workspace/_unmaintained/miyoomini/libmsettings/msettings.h deleted file mode 100644 index e0980571a..000000000 --- a/workspace/_unmaintained/miyoomini/libmsettings/msettings.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef msettings_h__ -#define msettings_h__ - -void InitSettings(void); -void QuitSettings(void); - -int GetBrightness(void); -int GetVolume(void); - -void SetRawBrightness(int value); // 0-100 -void SetRawVolume(int value); // -60-0 - -void SetBrightness(int value); // 0-10 -void SetVolume(int value); // 0-20 - -int GetJack(void); -void SetJack(int value); // 0-1 - -int GetHDMI(void); -void SetHDMI(int value); // 0-1 - -int GetMute(void); -void SetMute(int value); // 0-1 - -#endif // msettings_h__ diff --git a/workspace/_unmaintained/miyoomini/lumon/lumon.c b/workspace/_unmaintained/miyoomini/lumon/lumon.c deleted file mode 100644 index d420c5b56..000000000 --- a/workspace/_unmaintained/miyoomini/lumon/lumon.c +++ /dev/null @@ -1,38 +0,0 @@ -#include -#include -#include - -#include -#include -#include -#include - -int main(void) { - MI_DISP_DEV dev = 0; - - MI_DISP_PubAttr_t attrs; - memset(&attrs,0,sizeof(MI_DISP_PubAttr_t)); - MI_DISP_GetPubAttr(dev,&attrs); - - attrs.eIntfType = E_MI_DISP_INTF_LCD; - attrs.eIntfSync = E_MI_DISP_OUTPUT_USER; - MI_DISP_SetPubAttr(dev,&attrs); - - MI_DISP_Enable(dev); - - MI_DISP_LcdParam_t params; - memset(¶ms,0,sizeof(MI_DISP_LcdParam_t)); - MI_DISP_GetLcdParam(dev, ¶ms); - - params.stCsc.u32Luma = 45; - params.stCsc.u32Contrast = 50; - params.stCsc.u32Hue = 50; - params.stCsc.u32Saturation = 45; - params.u32Sharpness = 0; - - MI_DISP_SetLcdParam(dev,¶ms); - - while (1) pause(); - - // MI_DISP_Disable(dev); -} diff --git a/workspace/_unmaintained/miyoomini/lumon/makefile b/workspace/_unmaintained/miyoomini/lumon/makefile deleted file mode 100644 index ad579f798..000000000 --- a/workspace/_unmaintained/miyoomini/lumon/makefile +++ /dev/null @@ -1,15 +0,0 @@ -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif - -TARGET = lumon -PRODUCT = $(TARGET).elf - -CC = $(CROSS_COMPILE)gcc -CFLAGS = -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7ve -LDFLAGS = -Os -lmi_sys -lmi_disp - -all: - $(CC) $(TARGET).c -o $(PRODUCT) $(CFLAGS) $(LDFLAGS) -clean: - rm -f $(PRODUCT) \ No newline at end of file diff --git a/workspace/_unmaintained/miyoomini/makefile b/workspace/_unmaintained/miyoomini/makefile deleted file mode 100644 index 9c1b48c44..000000000 --- a/workspace/_unmaintained/miyoomini/makefile +++ /dev/null @@ -1,45 +0,0 @@ -########################################################### - -ifeq (,$(PLATFORM)) -PLATFORM=$(UNION_PLATFORM) -endif - -ifeq (,$(PLATFORM)) -$(error please specify PLATFORM, eg. PLATFORM=trimui make) -endif - -########################################################### - -REQUIRES_SDL=other/sdl -REQUIRES_COMMANDER=other/DinguxCommander - -all: readmes - cd blank && make - cd batmon && make - cd lumon && make - cd show && make - cd overclock && make - -early: $(REQUIRES_SDL) $(REQUIRES_COMMANDER) - cd other/sdl && ./make.sh - cd other/logotweak && make - cd other/latency_reduction && make - cd other/DinguxCommander && make -j - -clean: - cd blank && make clean - cd batmon && make clean - cd lumon && make clean - cd show && make clean - cd other/sdl && make distclean - cd other/latency_reduction && make clean - cd other/DinguxCommander && make clean - -########################################################### - -$(REQUIRES_SDL): - git clone --depth 1 --branch miniui-miyoomini https://github.com/shauninman/SDL-1.2.git $(REQUIRES_SDL) -$(REQUIRES_COMMANDER): - git clone --depth 1 --branch miniui-miyoomini https://github.com/shauninman/DinguxCommander.git $(REQUIRES_COMMANDER) - -include ../all/readmes/makefile diff --git a/workspace/_unmaintained/miyoomini/other/.keep b/workspace/_unmaintained/miyoomini/other/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/workspace/_unmaintained/miyoomini/other/latency_reduction/Makefile b/workspace/_unmaintained/miyoomini/other/latency_reduction/Makefile deleted file mode 100644 index 4a555a0c3..000000000 --- a/workspace/_unmaintained/miyoomini/other/latency_reduction/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -TARGET = as_preload.so - -CC = $(CROSS_COMPILE)gcc - -SOURCES = . -CFILES = $(foreach dir, $(SOURCES), $(wildcard $(dir)/*.c)) - -CFLAGS = -Os -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7ve+simd -CFLAGS += -fPIC -Wall -LDFLAGS = -shared -ldl -s - -$(TARGET): $(CFILES) - $(CC) $(CFLAGS) $(LDFLAGS) $(CFILES) -o $@ - -clean: - rm -f $(TARGET) diff --git a/workspace/_unmaintained/miyoomini/other/latency_reduction/audioserver.mod b/workspace/_unmaintained/miyoomini/other/latency_reduction/audioserver.mod deleted file mode 100755 index e7b4209f21560e03e1a92afbbc0fac207d098e7f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13964 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 -#include -#include -#include - -#include - -#define FREQ 48000 -#define BUSY_THRESHOLD ((FREQ<<2)/(1000/20)) // 20ms - -MI_S32 MI_AO_SendFrame(MI_AUDIO_DEV AoDevId, MI_AO_CHN AoChn, MI_AUDIO_Frame_t *pstData, MI_S32 s32MilliSec) { - static void* mi_ao_handle = NULL; - static MI_S32 (*_MI_AO_SendFrame)(MI_AUDIO_DEV AoDevId, MI_AO_CHN AoChn, MI_AUDIO_Frame_t *pstData, MI_S32 s32MilliSec); - static MI_S32 (*_MI_AO_QueryChnStat)(MI_AUDIO_DEV AoDevId , MI_AO_CHN AoChn, MI_AO_ChnState_t *pstStatus); - - if (!mi_ao_handle) { - mi_ao_handle = dlopen("/config/lib/libmi_ao.so", RTLD_LAZY); - _MI_AO_SendFrame = dlsym(mi_ao_handle, "MI_AO_SendFrame"); - _MI_AO_QueryChnStat = dlsym(mi_ao_handle, "MI_AO_QueryChnStat"); - } - - MI_S32 ret = _MI_AO_SendFrame(AoDevId, AoChn, pstData, 0); - - if (s32MilliSec) { - MI_AO_ChnState_t status; - _MI_AO_QueryChnStat(AoDevId, AoChn, &status); - if (status.u32ChnBusyNum > BUSY_THRESHOLD) { - useconds_t usleepclock = (uint64_t)(status.u32ChnBusyNum - BUSY_THRESHOLD) * 1000000 / (FREQ << 2); - if (usleepclock) usleep(usleepclock); - } - } - - return ret; -} diff --git a/workspace/_unmaintained/miyoomini/other/logotweak/credits.txt b/workspace/_unmaintained/miyoomini/other/logotweak/credits.txt deleted file mode 100644 index f1b0a6d44..000000000 --- a/workspace/_unmaintained/miyoomini/other/logotweak/credits.txt +++ /dev/null @@ -1,2 +0,0 @@ -created by eggs for the Miyoo Mini: - https://www.dropbox.com/sh/hqcsr1h1d7f8nr3/AABtSOygIX_e4mio3rkLetWTa?preview=logotweak.zip \ No newline at end of file diff --git a/workspace/_unmaintained/miyoomini/other/logotweak/logomake.c b/workspace/_unmaintained/miyoomini/other/logotweak/logomake.c deleted file mode 100644 index 37078ce4b..000000000 --- a/workspace/_unmaintained/miyoomini/other/logotweak/logomake.c +++ /dev/null @@ -1,99 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define IMGSIZE 0x20000 - -int main() -{ - mtd_info_t mtdinfo; - uint32_t i, a, size, size32, imgcount, *read_ofs32; - uint8_t *read_buf, *read_ofs; - const char img_name[4][12] = { "image1.jpg", "image2.jpg", "image3.jpg", "logo.img" }; - int mtdfd, imgfd; - struct stat fst; - - read_buf = malloc(IMGSIZE); - if (!read_buf) { puts("malloc failed"); return -1; } - - printf("Reading /dev/mtd3 ... "); - mtdfd = open("/dev/mtd3", O_RDONLY); - if (mtdfd < 0) { puts("failed to open"); return -1; } - - ioctl(mtdfd, MEMGETINFO, &mtdinfo); - if (mtdinfo.type != 3) { puts("MTD type incorrect"); return -1; } - if (mtdinfo.size != IMGSIZE) { puts("MTD size incorrect"); return -1; } - if (mtdinfo.erasesize != 0x10000) { puts("MTD erasesize incorrect"); return -1; } - - lseek(mtdfd, 0, SEEK_SET); - if (read(mtdfd, read_buf, IMGSIZE) != IMGSIZE) { puts("failed to read"); return -1; } - close(mtdfd); - puts("OK"); - - printf("Checking partition ... "); - read_ofs = read_buf; // "SSTAR" offset - read_ofs32 = (uint32_t*)read_ofs; - if ((read_ofs32[0] != 0x41545353)||(read_ofs32[1] != 0x52)||(read_ofs32[2] != 4)) { puts("missing SSTAR"); return -1; } - - read_ofs = read_ofs + 12; // "DISP" offset - read_ofs32 = (uint32_t*)read_ofs; - if (read_ofs32[0] != 0x50534944) { puts("missing DISP"); return -1; } - for (i=1,a=0; i<8; i++) a += read_ofs32[i]; - read_ofs = read_ofs + read_ofs32[8] + read_ofs32[9]; // 1st "LOGO" offset - if ((a)||(read_ofs - read_buf) > (IMGSIZE-0x2c)) { puts("invalid DISP format"); return -1; } - - read_ofs32 = (uint32_t*)read_ofs; - if (read_ofs32[0] != 0x4F474F4C) { puts("missing LOGO"); return -1; } - puts("OK"); - - // read 3 jpg images - for (imgcount=0; imgcount<3; imgcount++) { - printf("Reading %s ... ",img_name[imgcount]); - - read_ofs32[0] = 0x4F474F4C; - for (i=1; i<8; i++) read_ofs32[i] = 0; - read_ofs32[9] = 0x2c; read_ofs32[10] = 1; - - imgfd = open(img_name[imgcount], O_RDONLY); - if (imgfd < 0) { puts("failed to open"); return -1; } - - fstat(imgfd, &fst); - size = fst.st_size; - size32 = (size+3)&~3; - read_ofs32[8] = size32; - - read_ofs += 0x2c; - if (read_ofs + size32 > read_buf + IMGSIZE) { puts("img size overflow"); return -1; } - if (size) { - memset(read_ofs, 0, size32); - if (read(imgfd, read_ofs, size) != size) { puts("failed to read"); return -1; } - } - close(imgfd); - if (size != size32) read_ofs[size] = 0xff; - puts("OK"); - - read_ofs += size32; - read_ofs32 = (uint32_t*)read_ofs; - } - - // fill rest bytes to 0xFF - if (IMGSIZE-(read_ofs-read_buf) > 0) memset(read_ofs, 0xFF, IMGSIZE-(read_ofs-read_buf)); - - // write logo.img - printf("Writing %s ... ",img_name[3]); - imgfd = creat(img_name[3], 777); - if (imgfd < 0) { puts("failed to create"); return -1; } - if (write(imgfd, read_buf, IMGSIZE) != IMGSIZE) { puts("failed to write"); return -1; } - close(imgfd); - puts("OK"); - - free(read_buf); - - return 0; -} diff --git a/workspace/_unmaintained/miyoomini/other/logotweak/logoread.c b/workspace/_unmaintained/miyoomini/other/logotweak/logoread.c deleted file mode 100644 index add7f937e..000000000 --- a/workspace/_unmaintained/miyoomini/other/logotweak/logoread.c +++ /dev/null @@ -1,73 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#define IMGSIZE 0x20000 - -int main() -{ - mtd_info_t mtdinfo; - uint32_t i, a, size, imgcount, *read_ofs32; - uint8_t *read_buf, *read_ofs; - const char img_name[3][12] = { "image1.jpg", "image2.jpg", "image3.jpg" }; - int mtdfd, imgfd; - - read_buf = malloc(IMGSIZE); - if (!read_buf) { puts("malloc failed"); return -1; } - - printf("Reading /dev/mtd3 ... "); - mtdfd = open("/dev/mtd3", O_RDONLY); - if (mtdfd < 0) { puts("failed to open"); return -1; } - - ioctl(mtdfd, MEMGETINFO, &mtdinfo); - if (mtdinfo.type != 3) { puts("MTD type incorrect"); return -1; } - if (mtdinfo.size != IMGSIZE) { puts("MTD size incorrect"); return -1; } - if (mtdinfo.erasesize != 0x10000) { puts("MTD erasesize incorrect"); return -1; } - - lseek(mtdfd, 0, SEEK_SET); - if (read(mtdfd, read_buf, IMGSIZE) != IMGSIZE) { puts("failed to read"); return -1; } - close(mtdfd); - puts("OK"); - - printf("Checking partition ... "); - read_ofs = read_buf; // "SSTAR" offset - read_ofs32 = (uint32_t*)read_ofs; - if ((read_ofs32[0] != 0x41545353)||(read_ofs32[1] != 0x52)||(read_ofs32[2] != 4)) { puts("missing SSTAR"); return -1; } - - read_ofs = read_ofs + 12; // "DISP" offset - read_ofs32 = (uint32_t*)read_ofs; - if (read_ofs32[0] != 0x50534944) { puts("missing DISP"); return -1; } - for (i=1,a=0; i<8; i++) a += read_ofs32[i]; - read_ofs = read_ofs + read_ofs32[8] + read_ofs32[9]; // 1st "LOGO" offset - if ((a)||(read_ofs - read_buf) > (IMGSIZE-0x2c)) { puts("invalid DISP format"); return -1; } - - read_ofs32 = (uint32_t*)read_ofs; - if (read_ofs32[0] != 0x4F474F4C) { puts("missing LOGO"); return -1; } - puts("OK"); - - for (imgcount=0; imgcount<3; imgcount++) { - printf("Writing %s ... ",img_name[imgcount]); - - if (read_ofs32[0] != 0x4F474F4C) { puts("missing LOGO"); return -1; } - for (i=1,a=0; i<8; i++) a += read_ofs32[i]; - if ((a)||(read_ofs32[9] != 0x2c)||(read_ofs32[10] != 0x1)) { puts("invalid LOGO format"); return -1; } - size = read_ofs32[8]; - read_ofs += 0x2c; - - imgfd = creat(img_name[imgcount], 777); - if (imgfd < 0) { puts("failed to create"); return -1; } - if (size) if (write(imgfd, read_ofs, size) != size) { puts("failed to read"); return -1; } - close(imgfd); - puts("OK"); - - read_ofs += size; - read_ofs32 = (uint32_t*)read_ofs; - } - free(read_buf); - - return 0; -} diff --git a/workspace/_unmaintained/miyoomini/other/logotweak/logowrite.c b/workspace/_unmaintained/miyoomini/other/logotweak/logowrite.c deleted file mode 100644 index a0512b41d..000000000 --- a/workspace/_unmaintained/miyoomini/other/logotweak/logowrite.c +++ /dev/null @@ -1,116 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define IMGSIZE 0x20000 - -int main() -{ - mtd_info_t mtdinfo; - erase_info_t ei; - uint32_t i, a, *read_ofs32; - uint8_t r, *read_buf, *read_ofs, *verify_buf; - int imgfd, mtdfd; - struct stat fst; - const char img_name[] = "logo.img"; - - read_buf = malloc(IMGSIZE); - if (!read_buf) { puts("malloc failed"); return -1; } - - printf("Opening logo.img ... "); - imgfd = open(img_name, O_RDONLY); - if (imgfd < 0) { puts("failed to open"); return -1; } - fstat(imgfd, &fst); - if (fst.st_size != IMGSIZE) { puts("invalid size"); return -1; } - puts("OK"); - - printf("Checking logo.img ... "); - lseek(imgfd, 0, SEEK_SET); - if (read(imgfd, read_buf, IMGSIZE) != IMGSIZE) { puts("failed to read"); return -1; } - read_ofs = read_buf; // "SSTAR" offset - read_ofs32 = (uint32_t*)read_ofs; - if ((read_ofs32[0] != 0x41545353)||(read_ofs32[1] != 0x52)||(read_ofs32[2] != 4)) { puts("missing SSTAR"); return -1; } - - read_ofs = read_ofs + 12; // "DISP" offset - read_ofs32 = (uint32_t*)read_ofs; - if (read_ofs32[0] != 0x50534944) { puts("missing DISP"); return -1; } - for (i=1,a=0; i<8; i++) a += read_ofs32[i]; - read_ofs += read_ofs32[8] + read_ofs32[9]; // 1st "LOGO" offset - if ((a)||(read_ofs - read_buf) > (IMGSIZE-0x2c)) { puts("invalid DISP format"); return -1; } - - read_ofs32 = (uint32_t*)read_ofs; - if (read_ofs32[0] != 0x4F474F4C) { puts("missing LOGO1"); return -1; } - for (i=1,a=0; i<8; i++) a += read_ofs32[i]; - read_ofs += read_ofs32[8] + read_ofs32[9]; - if ((a)||(read_ofs - read_buf) > (IMGSIZE-0x2c)) { puts("invalid LOGO1 format"); return -1; } - - read_ofs32 = (uint32_t*)read_ofs; - if (read_ofs32[0] != 0x4F474F4C) { puts("missing LOGO2"); return -1; } - for (i=1,a=0; i<8; i++) a += read_ofs32[i]; - read_ofs += read_ofs32[8] + read_ofs32[9]; - if ((a)||(read_ofs - read_buf) > (IMGSIZE-0x2c)) { puts("invalid LOGO2 format"); return -1; } - - read_ofs32 = (uint32_t*)read_ofs; - if (read_ofs32[0] != 0x4F474F4C) { puts("missing LOGO3"); return -1; } - for (i=1,a=0; i<8; i++) a += read_ofs32[i]; - read_ofs += read_ofs32[8] + read_ofs32[9]; - if ((a)||(read_ofs - read_buf) > IMGSIZE) { puts("invalid LOGO3 format"); return -1; } - puts("OK"); - - printf("Opening /dev/mtd3 ... "); - mtdfd = open("/dev/mtd3", O_RDWR); - if (mtdfd < 0) { puts("failed to open"); return -1; } - - ioctl(mtdfd, MEMGETINFO, &mtdinfo); - if (mtdinfo.type != 3) { puts("MTD type incorrect"); return -1; } - if (mtdinfo.size != IMGSIZE) { puts("MTD size incorrect"); return -1; } - if (mtdinfo.erasesize != 0x10000) { puts("MTD erasesize incorrect"); return -1; } - puts("OK"); - - printf("Erasing /dev/mtd3 ... "); - ei.length = mtdinfo.erasesize; - for (ei.start = 0; ei.start < mtdinfo.size; ei.start += ei.length) { - ioctl(mtdfd, MEMUNLOCK, &ei); - ioctl(mtdfd, MEMERASE, &ei); - } - puts("OK"); - - printf("Checking erased /dev/mtd3 ... "); - lseek(mtdfd, 0, SEEK_SET); - if (read(mtdfd, read_buf, IMGSIZE) != IMGSIZE) { puts("failed to read"); return -1; } - for (i=0, r=0xff; i -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// -// Rumble ON(1) / OFF(0) -// -void rumble(uint32_t val) { - int fd; - const char str_export[] = "48"; - const char str_direction[] = "out"; - char value[1]; - value[0] = ((val&1)^1) + 0x30; - - fd = open("/sys/class/gpio/export", O_WRONLY); - if (fd > 0) { - write(fd, str_export, 2); - close(fd); - } - fd = open("/sys/class/gpio/gpio48/direction", O_WRONLY); - if (fd > 0) { - write(fd, str_direction, 3); - close(fd); - } - fd = open("/sys/class/gpio/gpio48/value", O_WRONLY); - if (fd > 0) { - write(fd, value, 1); - close(fd); - } -} - -// -// Search pid of running executable -// -pid_t searchpid(const char *commname) { - DIR *procdp; - struct dirent *dir; - char fname[32]; - char comm[128]; - pid_t pid; - pid_t ret = 0; - - procdp = opendir("/proc"); - while ((dir = readdir(procdp))) { - if (dir->d_type == DT_DIR) { - pid = atoi(dir->d_name); - if ( pid > 2 ) { - sprintf(fname, "/proc/%d/comm", pid); - FILE *fp = fopen(fname, "r"); - if (fp) { - fscanf(fp, "%127s", comm); - fclose(fp); - if (!strcmp(comm, commname)) { ret = pid; break; } - } - } - } - } - closedir(procdp); - return ret; -} - -// -// Get Most recent file name from Roms/recentlist.json -// -char* getrecent(char *filename) { - FILE *fp; - char *fnptr; - uint32_t i; - - strcpy(filename, "/mnt/SDCARD/Screenshots/"); - if (access(filename, F_OK)) mkdir(filename, 777); - - fnptr = filename + strlen(filename); - - if (!access("/tmp/cmd_to_run.sh", F_OK)) { - // for stock - if ((fp = fopen("/mnt/SDCARD/Roms/recentlist.json", "r"))) { - fscanf(fp, "%*255[^:]%*[:]%*[\"]%255[^\"]", fnptr); - fclose(fp); - } - } else if ((fp = fopen("/tmp/next", "r"))) { - // for MiniUI - char ename[256]; - char fname[256]; - char *strptr; - ename[0] = 0; fname[0] = 0; - fscanf(fp, "%*[\"]%255[^\"]%*[\" ]%255[^\"]", ename, fname); - fclose(fp); - if (fname[0]) { - if ((strptr = strrchr(fname, '.'))) *strptr = 0; - if ((strptr = strrchr(fname, '/'))) strptr++; else strptr = fname; - strcpy(fnptr, strptr); - } else if (ename[0]) { - if ((strptr = strrchr(ename, '/'))) *strptr = 0; - if ((strptr = strrchr(ename, '.'))) *strptr = 0; - if ((strptr = strrchr(ename, '/'))) strptr++; else strptr = ename; - strcpy(fnptr, strptr); - } - } - - if (!(*fnptr)) { - if (searchpid("MiniUI")) strcat(filename, "MiniUI"); - else strcat(filename, "MainUI"); - } - - fnptr = filename + strlen(filename); - for (i=0; i<1000; i++) { - sprintf(fnptr, "_%03d.png", i); - if ( access(filename, F_OK) != 0 ) break; - } if (i > 999) return NULL; - return filename; -} - -// -// Screenshot (640x480, rotate180, png) -// -void screenshot(void) { - char screenshotname[512]; - uint32_t *buffer, *src; - uint32_t linebuffer[640], x, y, pix; - FILE *fp; - int fd_fb; - struct fb_var_screeninfo vinfo; - png_structp png_ptr; - png_infop info_ptr; - - if (getrecent(screenshotname) == NULL) return; - if ((buffer = (uint32_t*)malloc(640*480*4)) != NULL) { - fd_fb = open("/dev/fb0", O_RDWR); - ioctl(fd_fb, FBIOGET_VSCREENINFO, &vinfo); - lseek(fd_fb, 640*vinfo.yoffset*4, SEEK_SET); - read(fd_fb, buffer, 640*480*4); - close(fd_fb); - - fp = fopen(screenshotname, "wb"); - if (fp != NULL) { - png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); - info_ptr = png_create_info_struct(png_ptr); - png_init_io(png_ptr, fp); - png_set_IHDR(png_ptr, info_ptr, 640, 480, 8, PNG_COLOR_TYPE_RGBA, - PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - png_write_info(png_ptr, info_ptr); - src = buffer + 640*480; - for (y=0; y<480; y++) { - for (x=0; x<640; x++){ - pix = *--src; - linebuffer[x] = 0xFF000000 | (pix & 0x0000FF00) | (pix & 0x00FF0000)>>16 | (pix & 0x000000FF)<<16; - } - png_write_row(png_ptr, (png_bytep)linebuffer); - } - png_write_end(png_ptr, info_ptr); - png_destroy_write_struct(&png_ptr, &info_ptr); - fclose(fp); - sync(); - } - free(buffer); - } -} - -// -// Screenshot Sample Main -// -#define BUTTON_MENU KEY_ESC -#define BUTTON_POWER KEY_POWER -#define BUTTON_L2 KEY_TAB -#define BUTTON_R2 KEY_BACKSPACE -int main() { - int input_fd; - struct input_event ev; - uint32_t val; - uint32_t l2_pressed = 0; - uint32_t r2_pressed = 0; - - // Prepare for Poll button input - input_fd = open("/dev/input/event0", O_RDONLY); - - while( read(input_fd, &ev, sizeof(ev)) == sizeof(ev) ) { - val = ev.value; - if (( ev.type != EV_KEY ) || ( val > 1 )) continue; - if (( ev.code == BUTTON_L2 )||( ev.code == BUTTON_R2 )) { - if ( ev.code == BUTTON_L2 ) { - l2_pressed = val; - } else if ( ev.code == BUTTON_R2 ) { - r2_pressed = val; - } - if (l2_pressed & r2_pressed) { - rumble(1); - screenshot(); - usleep(100000); //0.1s - rumble(0); - l2_pressed = r2_pressed = 0; - } - } - } - - // Quit - close(input_fd); - - return 0; -} diff --git a/workspace/_unmaintained/miyoomini/overclock/credits.txt b/workspace/_unmaintained/miyoomini/overclock/credits.txt deleted file mode 100644 index d99994870..000000000 --- a/workspace/_unmaintained/miyoomini/overclock/credits.txt +++ /dev/null @@ -1,2 +0,0 @@ -based on eggs example code: - https://www.dropbox.com/sh/hqcsr1h1d7f8nr3/AABtSOygIX_e4mio3rkLetWTa?preview=overclock_test.zip \ No newline at end of file diff --git a/workspace/_unmaintained/miyoomini/overclock/makefile b/workspace/_unmaintained/miyoomini/overclock/makefile deleted file mode 100755 index 8aaee0c5b..000000000 --- a/workspace/_unmaintained/miyoomini/overclock/makefile +++ /dev/null @@ -1,14 +0,0 @@ -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif - -TARGET = overclock -PRODUCT = $(TARGET).elf - -CC = $(CROSS_COMPILE)gcc -CFLAGS = -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7ve - -all: - $(CC) $(TARGET).c -o $(PRODUCT) $(CFLAGS) -clean: - rm -f $(PRODUCT) \ No newline at end of file diff --git a/workspace/_unmaintained/miyoomini/overclock/overclock.c b/workspace/_unmaintained/miyoomini/overclock/overclock.c deleted file mode 100644 index 699729345..000000000 --- a/workspace/_unmaintained/miyoomini/overclock/overclock.c +++ /dev/null @@ -1,144 +0,0 @@ -// -// cpu over/underclock (based on code from eggs) -// -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define BASE_REG_RIU_PA (0x1F000000) -#define BASE_REG_MPLL_PA (BASE_REG_RIU_PA + 0x103000*2) -#define PLL_SIZE (0x1000) - -void* pll_map; - -void print_clock(void) { - uint32_t rate; - uint32_t lpf_value; - uint32_t post_div; - volatile uint8_t* p8 = (uint8_t*)pll_map; - volatile uint16_t* p16 = (uint16_t*)pll_map; - - //get LPF / post_div - lpf_value = p16[0x2A4] + (p16[0x2A6] << 16); post_div = p16[0x232] + 1; - if (lpf_value == 0) lpf_value= (p8[0x2C2<<1] << 16) + (p8[0x2C1<<1] << 8) + p8[0x2C0<<1]; - - /* - * Calculate LPF value for DFS - * LPF_value(5.19) = (432MHz / Ref_clk) * 2^19 => it's for post_div=2 - * Ref_clk = CPU_CLK * 2 / 32 - */ - static const uint64_t divsrc = 432000000llu * 524288; - rate = (divsrc / lpf_value * 2 / post_div * 16); - - printf("cpuclock=%u (lpf=%u, post_div=%u)\n", rate, lpf_value, post_div); -} - -void writefile(const char* fname, char* str) { - int fd = open(fname, O_WRONLY); - if (fd>=0) { write(fd, str, strlen(str)); close(fd); } -} - -// -// set cpu clock -// set governor = userspace, clk = 1200000 before call -// -void set_cpuclock(int clock) { - uint32_t post_div; - if (clock >= 800000) post_div = 2; - else if (clock >= 400000) post_div = 4; - else if (clock >= 200000) post_div = 8; - else post_div = 16; - - static const uint64_t divsrc = 432000000llu * 524288; - uint32_t rate = (clock * 1000)/16 * post_div / 2; - uint32_t lpf = (uint32_t)(divsrc / rate); - volatile uint16_t* p16 = (uint16_t*)pll_map; - - uint32_t cur_post_div = (p16[0x232] & 0x0F) + 1; - uint32_t tmp_post_div = cur_post_div; - if (post_div > cur_post_div) { - while (tmp_post_div != post_div) { - tmp_post_div <<= 1; - p16[0x232] = (p16[0x232] & 0xF0) | ((tmp_post_div-1) & 0x0F); - } - } - - p16[0x2A8] = 0x0000; //reg_lpf_enable = 0 - p16[0x2AE] = 0x000F; //reg_lpf_update_cnt = 32 - p16[0x2A4] = lpf&0xFFFF; //set target freq to LPF high - p16[0x2A6] = lpf>>16; //set target freq to LPF high - p16[0x2B0] = 0x0001; //switch to LPF control - p16[0x2B2] |= 0x1000; //from low to high - p16[0x2A8] = 0x0001; //reg_lpf_enable = 1 - while( !(p16[0x2BA]&1) ); //polling done - p16[0x2A0] = lpf&0xFFFF; //store freq to LPF low - p16[0x2A2] = lpf>>16; //store freq to LPF low - - if (post_div < cur_post_div) { - while (tmp_post_div != post_div) { - tmp_post_div >>= 1; - p16[0x232] = (p16[0x232] & 0xF0) | ((tmp_post_div-1) & 0x0F); - } - } -} - -int cpu_clocks[] = { - 1700000, // 1.7GHz, Miyoo Mini max - 1488000, // 1.5GHz, NextUI Performance + launch - 1392000, // 1.4GHz - 1296000, // 1.3GHz, NextUI Normal - 1200000, // 1.2GHz, Miyoo Mini default - 1104000, // 1.1GHz, NextUI Powersave - 1008000, // 1.0GHz, Anbernic RG35XX default - 840000, // 840MHz, - 720000, // 720MHz, - 504000, // 500MHz, NextUI menus - 240000, // 240MHz, - 0, -}; - -int main(int argc, char* argv[]) { - int fd_mem = open("/dev/mem", O_RDWR); - pll_map = mmap(0, PLL_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd_mem, BASE_REG_MPLL_PA); - - if (argc<2) { - printf("Usage: %s \n", argv[0]); - for (int i=0; cpu_clocks[i]; i++) { - printf(" %8i\n", cpu_clocks[i]); - } - munmap(pll_map, PLL_SIZE); - close(fd_mem); - return 0; - } - - int clk = 1200000; // default - char *p; - errno = 0; - long arg = strtol(argv[1], &p, 10); - - if (errno != 0 || *p != '\0' || arg > INT_MAX || arg < INT_MIN); // buh - else clk = arg; - - for (int i=0; cpu_clocks[i]; i++) { - int cpu_clock = cpu_clocks[i]; - if (clk>=cpu_clock) { - char clockstr[16]; - sprintf(clockstr, "%d", clk); - writefile("/sys/devices/system/cpu/cpufreq/policy0/scaling_governor", "userspace"); - writefile("/sys/devices/system/cpu/cpufreq/policy0/scaling_setspeed", clockstr); - set_cpuclock(cpu_clock); - break; - } - } - - munmap(pll_map, PLL_SIZE); - close(fd_mem); - - return 0; -} diff --git a/workspace/_unmaintained/miyoomini/platform/makefile.copy b/workspace/_unmaintained/miyoomini/platform/makefile.copy deleted file mode 100644 index b17652e77..000000000 --- a/workspace/_unmaintained/miyoomini/platform/makefile.copy +++ /dev/null @@ -1,20 +0,0 @@ -$(PLATFORM): - # $@ - cp ./workspace/$@/overclock/overclock.elf ./build/SYSTEM/$@/bin/ - cp ./workspace/$@/blank/blank.elf ./build/SYSTEM/$@/bin/ - cp ./workspace/$@/batmon/batmon.elf ./build/SYSTEM/$@/bin/ - cp ./workspace/$@/lumon/lumon.elf ./build/SYSTEM/$@/bin/ - cp ./workspace/$@/show/show.elf ./build/SYSTEM/$@/bin - cp ./workspace/$@/other/sdl/build/.libs/libSDL-1.2.so.0.11.5 ./build/SYSTEM/$@/lib/libSDL-1.2.so.0 - cp ./workspace/$@/other/latency_reduction/as_preload.so ./build/SYSTEM/$@/lib/ - cp ./workspace/$@/other/latency_reduction/audioserver.mod ./build/SYSTEM/$@/bin/ - # installer - cp ./workspace/$@/install/update.sh ./build/SYSTEM/$@/bin/install.sh - mkdir -p ./build/BOOT/common/$@/ - cp ./workspace/$@/install/boot.sh ./build/BOOT/common/$@.sh - cp ./workspace/$@/install/*.png ./build/BOOT/common/$@/ - cp ./workspace/$@/show/show.elf ./build/BOOT/common/$@/ - # extras - cp ./workspace/$@/other/DinguxCommander/output/DinguxCommander ./build/EXTRAS/Tools/$@/Files.pak/ - cp -r ./workspace/$@/other/DinguxCommander/res ./build/EXTRAS/Tools/$@/Files.pak/ - cp -r ./workspace/$@/other/logotweak/output/*.elf ./build/EXTRAS/Tools/$@/Bootlogo.pak/ diff --git a/workspace/_unmaintained/miyoomini/platform/makefile.env b/workspace/_unmaintained/miyoomini/platform/makefile.env deleted file mode 100644 index 5da794419..000000000 --- a/workspace/_unmaintained/miyoomini/platform/makefile.env +++ /dev/null @@ -1,3 +0,0 @@ -# miyoomini-toolchain doesn't need to override these -ARCH = -LIBS = -lmi_sys -lmi_gfx -lpthread \ No newline at end of file diff --git a/workspace/_unmaintained/miyoomini/platform/platform.c b/workspace/_unmaintained/miyoomini/platform/platform.c deleted file mode 100644 index e00ba3711..000000000 --- a/workspace/_unmaintained/miyoomini/platform/platform.c +++ /dev/null @@ -1,554 +0,0 @@ -// miyoomini -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include -#include - -#include "defines.h" -#include "platform.h" -#include "api.h" -#include "utils.h" -#include "scaler.h" - -/////////////////////////////// -// based on eggs GFXSample_rev15 - -#include -#include - -int is_plus = 0; - -#define pixelsPa unused1 -#define ALIGN4K(val) ((val+4095)&(~4095)) - -// -// Get GFX_ColorFmt from SDL_Surface -// -static inline MI_GFX_ColorFmt_e GFX_ColorFmt(SDL_Surface *surface) { - if (surface) { - if (surface->format->BytesPerPixel == 2) { - if (surface->format->Amask == 0x0000) return E_MI_GFX_FMT_RGB565; - if (surface->format->Amask == 0x8000) return E_MI_GFX_FMT_ARGB1555; - if (surface->format->Amask == 0xF000) return E_MI_GFX_FMT_ARGB4444; - if (surface->format->Amask == 0x0001) return E_MI_GFX_FMT_RGBA5551; - if (surface->format->Amask == 0x000F) return E_MI_GFX_FMT_RGBA4444; - return E_MI_GFX_FMT_RGB565; - } - if (surface->format->Bmask == 0x000000FF) return E_MI_GFX_FMT_ARGB8888; - if (surface->format->Rmask == 0x000000FF) return E_MI_GFX_FMT_ABGR8888; - } - return E_MI_GFX_FMT_ARGB8888; -} - -// -// Flush write cache of needed segments -// x and w are not considered since 4K units -// -static inline void FlushCacheNeeded(void* pixels, uint32_t pitch, uint32_t y, uint32_t h) { - uintptr_t pixptr = (uintptr_t)pixels; - uintptr_t startaddress = (pixptr + pitch*y)&(~4095); - uint32_t size = ALIGN4K(pixptr + pitch*(y+h)) - startaddress; - if (size) MI_SYS_FlushInvCache((void*)startaddress, size); -} - -// -// GFX BlitSurface (MI_GFX ver) / in place of SDL_BlitSurface -// with scale/bpp convert and rotate/mirror -// rotate : 1 = 90 / 2 = 180 / 3 = 270 -// mirror : 1 = Horizontal / 2 = Vertical / 3 = Both -// nowait : 0 = wait until done / 1 = no wait -// -static inline void GFX_BlitSurfaceExec(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect, uint32_t rotate, uint32_t mirror, uint32_t nowait) { - if ((src)&&(dst)&&(src->pixelsPa)&&(dst->pixelsPa)) { - MI_GFX_Surface_t Src; - MI_GFX_Surface_t Dst; - MI_GFX_Rect_t SrcRect; - MI_GFX_Rect_t DstRect; - MI_GFX_Opt_t Opt; - MI_U16 Fence; - - Src.phyAddr = src->pixelsPa; - Src.u32Width = src->w; - Src.u32Height = src->h; - Src.u32Stride = src->pitch; - Src.eColorFmt = GFX_ColorFmt(src); - if (srcrect) { - SrcRect.s32Xpos = srcrect->x; - SrcRect.s32Ypos = srcrect->y; - SrcRect.u32Width = srcrect->w; - SrcRect.u32Height = srcrect->h; - } else { - SrcRect.s32Xpos = 0; - SrcRect.s32Ypos = 0; - SrcRect.u32Width = Src.u32Width; - SrcRect.u32Height = Src.u32Height; - } - FlushCacheNeeded(src->pixels, src->pitch, SrcRect.s32Ypos, SrcRect.u32Height); - - Dst.phyAddr = dst->pixelsPa; - Dst.u32Width = dst->w; - Dst.u32Height = dst->h; - Dst.u32Stride = dst->pitch; - Dst.eColorFmt = GFX_ColorFmt(dst); - if (dstrect) { - DstRect.s32Xpos = dstrect->x; - DstRect.s32Ypos = dstrect->y; - if (dstrect->w|dstrect->h) { - DstRect.u32Width = dstrect->w; - DstRect.u32Height = dstrect->h; - } else { - DstRect.u32Width = SrcRect.u32Width; - DstRect.u32Height = SrcRect.u32Height; - } - } else { - DstRect.s32Xpos = 0; - DstRect.s32Ypos = 0; - DstRect.u32Width = Dst.u32Width; - DstRect.u32Height = Dst.u32Height; - } - if (rotate & 1) FlushCacheNeeded(dst->pixels, dst->pitch, DstRect.s32Ypos, DstRect.u32Width); - else FlushCacheNeeded(dst->pixels, dst->pitch, DstRect.s32Ypos, DstRect.u32Height); - - memset(&Opt, 0, sizeof(Opt)); - if (src->flags & SDL_SRCALPHA) { - Opt.eDstDfbBldOp = E_MI_GFX_DFB_BLD_INVSRCALPHA; - if (src->format->alpha != SDL_ALPHA_OPAQUE) { - Opt.u32GlobalSrcConstColor = (src->format->alpha << (src->format->Ashift - src->format->Aloss)) & src->format->Amask; - Opt.eDFBBlendFlag = (MI_Gfx_DfbBlendFlags_e) - (E_MI_GFX_DFB_BLEND_SRC_PREMULTIPLY | E_MI_GFX_DFB_BLEND_COLORALPHA | E_MI_GFX_DFB_BLEND_ALPHACHANNEL); - } else Opt.eDFBBlendFlag = E_MI_GFX_DFB_BLEND_SRC_PREMULTIPLY; - } - if (src->flags & SDL_SRCCOLORKEY) { - Opt.stSrcColorKeyInfo.bEnColorKey = TRUE; - Opt.stSrcColorKeyInfo.eCKeyFmt = Src.eColorFmt; - Opt.stSrcColorKeyInfo.eCKeyOp = E_MI_GFX_RGB_OP_EQUAL; - Opt.stSrcColorKeyInfo.stCKeyVal.u32ColorStart = - Opt.stSrcColorKeyInfo.stCKeyVal.u32ColorEnd = src->format->colorkey; - } - Opt.eSrcDfbBldOp = E_MI_GFX_DFB_BLD_ONE; - Opt.eRotate = (MI_GFX_Rotate_e)rotate; - Opt.eMirror = (MI_GFX_Mirror_e)mirror; - Opt.stClipRect.s32Xpos = dst->clip_rect.x; - Opt.stClipRect.s32Ypos = dst->clip_rect.y; - Opt.stClipRect.u32Width = dst->clip_rect.w; - Opt.stClipRect.u32Height = dst->clip_rect.h; - - MI_GFX_BitBlit(&Src, &SrcRect, &Dst, &DstRect, &Opt, &Fence); - if (!nowait) MI_GFX_WaitAllDone(FALSE, Fence); - } else SDL_BlitSurface(src, srcrect, dst, dstrect); -} - -/////////////////////////////// - -void PLAT_initInput(void) { - // buh -} -void PLAT_quitInput(void) { - // buh -} - -/////////////////////////////// - -typedef struct HWBuffer { - MI_PHY padd; - void* vadd; -} HWBuffer; - -static struct VID_Context { - SDL_Surface* video; - SDL_Surface* screen; - HWBuffer buffer; - - int page; - int width; - int height; - int pitch; - - int direct; - int cleared; -} vid; - -SDL_Surface* PLAT_initVideo(void) { - is_plus = exists("/customer/app/axp_test"); - - putenv("SDL_HIDE_BATTERY=1"); // using MiniUI's custom SDL - SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER); - SDL_ShowCursor(0); - - vid.video = SDL_SetVideoMode(FIXED_WIDTH, FIXED_HEIGHT, FIXED_DEPTH, SDL_SWSURFACE); - - int buffer_size = ALIGN4K(PAGE_SIZE) * PAGE_COUNT; - MI_SYS_MMA_Alloc(NULL, ALIGN4K(buffer_size), &vid.buffer.padd); - MI_SYS_Mmap(vid.buffer.padd, ALIGN4K(buffer_size), &vid.buffer.vadd, true); - // memset(vid.buffer.vadd, 0, PAGE_SIZE); - - vid.page = 1; - vid.direct = 1; - vid.width = FIXED_WIDTH; - vid.height = FIXED_HEIGHT; - vid.pitch = FIXED_PITCH; - vid.cleared = 0; - - vid.screen = SDL_CreateRGBSurfaceFrom(vid.buffer.vadd + ALIGN4K(vid.page*PAGE_SIZE),vid.width,vid.height,FIXED_DEPTH,vid.pitch,RGBA_MASK_AUTO); - vid.screen->pixelsPa = vid.buffer.padd + ALIGN4K(vid.page*PAGE_SIZE); - memset(vid.screen->pixels, 0, vid.pitch * vid.height); - - return vid.direct ? vid.video : vid.screen; -} - -void PLAT_quitVideo(void) { - SDL_FreeSurface(vid.screen); - - MI_SYS_Munmap(vid.buffer.vadd, ALIGN4K(PAGE_SIZE)); - MI_SYS_MMA_Free(vid.buffer.padd); - - SDL_Quit(); -} - -void PLAT_clearVideo(SDL_Surface* screen) { - MI_SYS_FlushInvCache(vid.buffer.vadd + ALIGN4K(vid.page*PAGE_SIZE), ALIGN4K(PAGE_SIZE)); - MI_SYS_MemsetPa(vid.buffer.padd + ALIGN4K(vid.page*PAGE_SIZE), 0, PAGE_SIZE); - SDL_FillRect(screen, NULL, 0); - // memset(screen->pixels, 0, PAGE_SIZE); // this causes crashing -} -void PLAT_clearAll(void) { - // buh - // MI_SYS_FlushInvCache(vid.buffer.vadd, ALIGN4K(PAGE_SIZE)); - // MI_SYS_MemsetPa(vid.buffer.padd, 0, PAGE_SIZE); - - PLAT_clearVideo(vid.screen); // clear backbuffer - vid.cleared = 1; // defer clearing frontbuffer until offscreen -} - -void PLAT_setVsync(int vsync) { - // TODO: Prevent Tearing/Vsync - // isn't a 1:1 mapping of what's happening here... - if (vsync==VSYNC_OFF) { - putenv("GFX_FLIPWAIT=0"); - putenv("GFX_BLOCKING=0"); - } - else if (vsync==VSYNC_LENIENT) { // this is tear free but results in flicker issues with settings overlay - putenv("GFX_FLIPWAIT=0"); - putenv("GFX_BLOCKING=1"); - } - else if (vsync==VSYNC_STRICT) { // this actually introduces tearing but reduces/eliminates judder and fixes flicker issues with settings overlay - putenv("GFX_FLIPWAIT=1"); - putenv("GFX_BLOCKING=1"); - } - SDL_GetVideoInfo(); -} - -SDL_Surface* PLAT_resizeVideo(int w, int h, int pitch) { - vid.direct = w==FIXED_WIDTH && h==FIXED_HEIGHT && pitch==FIXED_PITCH; - vid.width = w; - vid.height = h; - vid.pitch = pitch; - - if (vid.direct) memset(vid.video->pixels, 0, vid.pitch * vid.height); - else { - vid.screen->pixels = NULL; - vid.screen->pixelsPa = NULL; // otherwise custom SDL will try to free it? - SDL_FreeSurface(vid.screen); - - vid.screen = SDL_CreateRGBSurfaceFrom(vid.buffer.vadd + ALIGN4K(vid.page*PAGE_SIZE),vid.width,vid.height,FIXED_DEPTH,vid.pitch,RGBA_MASK_AUTO); - vid.screen->pixelsPa = vid.buffer.padd + ALIGN4K(vid.page*PAGE_SIZE); - memset(vid.screen->pixels, 0, vid.pitch * vid.height); - } - - return vid.direct ? vid.video : vid.screen; -} - -void PLAT_setVideoScaleClip(int x, int y, int width, int height) { - // buh -} -void PLAT_setNearestNeighbor(int enabled) { - // buh -} -static int next_effect = EFFECT_NONE; -static int effect_type = EFFECT_NONE; -void PLAT_setSharpness(int sharpness) { - // force effect to reload - // on scaling change - if (effect_type>=EFFECT_NONE) next_effect = effect_type; - effect_type = -1; -} - -void PLAT_setEffect(int effect) { - next_effect = effect; -} - -void PLAT_vsync(int remaining) { - if (remaining>0) SDL_Delay(remaining); -} - -scaler_t PLAT_getScaler(GFX_Renderer* renderer) { - if (effect_type==EFFECT_LINE) { - switch (renderer->scale) { - case 4: return scale4x_line; - case 3: return scale3x_line; - case 2: return scale2x_line; - default: return scale1x_line; - } - } - else if (effect_type==EFFECT_GRID) { - switch (renderer->scale) { - case 3: return scale3x_grid; - case 2: return scale2x_grid; - } - } - - switch (renderer->scale) { - case 6: return scale6x6_n16; - case 5: return scale5x5_n16; - case 4: return scale4x4_n16; - case 3: return scale3x3_n16; - case 2: return scale2x2_n16; - default: return scale1x1_n16; - } -} - -void PLAT_blitRenderer(GFX_Renderer* renderer) { - if (effect_type!=next_effect) { - effect_type = next_effect; - renderer->blit = PLAT_getScaler(renderer); // refresh the scaler - } - void* dst = renderer->dst + (renderer->dst_y * renderer->dst_p) + (renderer->dst_x * FIXED_BPP); - ((scaler_t)renderer->blit)(renderer->src,dst,renderer->src_w,renderer->src_h,renderer->src_p,renderer->dst_w,renderer->dst_h,renderer->dst_p); -} - - -void PLAT_flip(SDL_Surface* IGNORED, int sync) { - if (!vid.direct) GFX_BlitSurfaceExec(vid.screen, NULL, vid.video, NULL, 0,0,1); // TODO: handle aspect clipping - SDL_Flip(vid.video); - - // swap backbuffer - if (!vid.direct) { - vid.page ^= 1; - vid.screen->pixels = vid.buffer.vadd + ALIGN4K(vid.page*PAGE_SIZE); - vid.screen->pixelsPa = vid.buffer.padd + ALIGN4K(vid.page*PAGE_SIZE); - } - - if (vid.cleared) { - PLAT_clearVideo(vid.screen); - vid.cleared = 0; - } -} - -/////////////////////////////// - -// TODO: -#define OVERLAY_WIDTH PILL_SIZE // unscaled -#define OVERLAY_HEIGHT PILL_SIZE // unscaled -#define OVERLAY_BPP 4 -#define OVERLAY_DEPTH 16 -#define OVERLAY_PITCH (OVERLAY_WIDTH * OVERLAY_BPP) // unscaled -#define OVERLAY_RGBA_MASK 0x00ff0000,0x0000ff00,0x000000ff,0xff000000 // ARGB -static struct OVL_Context { - SDL_Surface* overlay; -} ovl; - -SDL_Surface* PLAT_initOverlay(void) { - // setup surface - ovl.overlay = SDL_CreateRGBSurface(SDL_SWSURFACE, SCALE2(OVERLAY_WIDTH,OVERLAY_HEIGHT),OVERLAY_DEPTH,OVERLAY_RGBA_MASK); - return ovl.overlay; -} -void PLAT_quitOverlay(void) { - if (ovl.overlay) SDL_FreeSurface(ovl.overlay); -} -void PLAT_enableOverlay(int enable) { - -} - -/////////////////////////////// - -// mmplus axp223 (via eggs) -#define AXPDEV "/dev/i2c-1" -#define AXPID (0x34) - -// -// AXP223 write (plus) -// 32 .. bit7: Shutdown Control -// -int axp_write(unsigned char address, unsigned char val) { - struct i2c_msg msg[1]; - struct i2c_rdwr_ioctl_data packets; - unsigned char buf[2]; - int ret; - int fd = open(AXPDEV, O_RDWR); - ioctl(fd, I2C_TIMEOUT, 5); - ioctl(fd, I2C_RETRIES, 1); - - buf[0] = address; - buf[1] = val; - msg[0].addr = AXPID; - msg[0].flags = 0; - msg[0].len = 2; - msg[0].buf = buf; - - packets.nmsgs = 1; - packets.msgs = &msg[0]; - ret = ioctl(fd, I2C_RDWR, &packets); - - close(fd); - if (ret < 0) return -1; - return 0; -} - -// -// AXP223 read (plus) -// 00 .. C4/C5(USBDC connected) 00(discharging) -// bit7: ACIN presence indication 0:ACIN not exist, 1:ACIN exists -// bit6: Indicating whether ACIN is usable (used by axp_test) -// bit4: Indicating whether VBUS is usable (used by axp_test) -// bit2: Indicating the Battery current direction 0: discharging, 1: charging -// bit0: Indicating whether the boot source is ACIN or VBUS -// 01 .. 70(charging) 30(non-charging) -// bit6: Charge indication 0:not charge or charge finished, 1: in charging -// B9 .. (& 0x7F) battery percentage -// -int axp_read(unsigned char address) { - struct i2c_msg msg[2]; - struct i2c_rdwr_ioctl_data packets; - unsigned char val; - int ret; - int fd = open(AXPDEV, O_RDWR); - ioctl(fd, I2C_TIMEOUT, 5); - ioctl(fd, I2C_RETRIES, 1); - - msg[0].addr = AXPID; - msg[0].flags = 0; - msg[0].len = 1; - msg[0].buf = &address; - msg[1].addr = AXPID; - msg[1].flags = I2C_M_RD; - msg[1].len = 1; - msg[1].buf = &val; - - packets.nmsgs = 2; - packets.msgs = &msg[0]; - ret = ioctl(fd, I2C_RDWR, &packets); - - close(fd); - if(ret < 0) return -1; - return val; -} - -/////////////////////////////// - -void PLAT_getBatteryStatus(int* is_charging, int* charge) { - PLAT_getBatteryStatusFine(is_charging, charge); - - // worry less about battery and more about the game you're playing - if (*charge>80) *charge = 100; - else if (*charge>60) *charge = 80; - else if (*charge>40) *charge = 60; - else if (*charge>20) *charge = 40; - else if (*charge>10) *charge = 20; - else *charge = 10; -} - -void PLAT_getBatteryStatusFine(int* is_charging, int* charge) -{ - *is_charging = is_plus ? (axp_read(0x00) & 0x4) > 0 : getInt("/sys/devices/gpiochip0/gpio/gpio59/value"); - - *charge = getInt("/tmp/battery"); // 0-100? - - // TODO: tmp - // *is_charging = 0; - // *charge = PWR_LOW_CHARGE; -} - -void PLAT_enableBacklight(int enable) { - if (enable) { - putInt("/sys/class/gpio/gpio4/value", 1); - putInt("/sys/class/gpio/unexport", 4); - putInt("/sys/class/pwm/pwmchip0/export", 0); - putInt("/sys/class/pwm/pwmchip0/pwm0/enable",0); - putInt("/sys/class/pwm/pwmchip0/pwm0/enable",1); - } - else { - putInt("/sys/class/gpio/export", 4); - putFile("/sys/class/gpio/gpio4/direction", "out"); - putInt("/sys/class/gpio/gpio4/value", 0); - } -} -void PLAT_powerOff(void) { - sleep(2); - - SetRawVolume(MUTE_VOLUME_RAW); - PLAT_enableBacklight(0); - SND_quit(); - VIB_quit(); - PWR_quit(); - GFX_quit(); - - system("shutdown"); - while (1) pause(); // lolwat -} - -/////////////////////////////// - -// #define GOVERNOR_PATH "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor" -// void PLAT_setCPUSpeed(int speed) { -// // TODO: this isn't quite right -// if (speed==CPU_SPEED_MENU) putFile(GOVERNOR_PATH, "powersave"); -// else if (speed==CPU_SPEED_POWERSAVE) putFile(GOVERNOR_PATH, "ondemand"); -// else putFile(GOVERNOR_PATH, "performance"); -// } - -// copy/paste of 35XX version now that we have our own overclock.elf -void PLAT_setCPUSpeed(int speed) { - int freq = 0; - switch (speed) { - case CPU_SPEED_MENU: freq = 504000; break; - case CPU_SPEED_POWERSAVE: freq = 1104000; break; - case CPU_SPEED_NORMAL: freq = 1296000; break; - case CPU_SPEED_PERFORMANCE: freq = 1488000; break; - } - - char cmd[32]; - sprintf(cmd,"overclock.elf %d\n", freq); - system(cmd); -} - -void PLAT_setRumble(int strength) { - static char lastvalue = 0; - const char str_export[2] = "48"; - const char str_direction[3] = "out"; - char value[1]; - int fd; - - value[0] = (strength == 0 ? 0x31 : 0x30); // '0' : '1' - if (lastvalue != value[0]) { - fd = open("/sys/class/gpio/export", O_WRONLY); - if (fd > 0) { write(fd, str_export, 2); close(fd); } - fd = open("/sys/class/gpio/gpio48/direction", O_WRONLY); - if (fd > 0) { write(fd, str_direction, 3); close(fd); } - fd = open("/sys/class/gpio/gpio48/value", O_WRONLY); - if (fd > 0) { write(fd, value, 1); close(fd); } - lastvalue = value[0]; - } -} - -int PLAT_pickSampleRate(int requested, int max) { - return max; -} - -char* PLAT_getModel(void) { - return is_plus ? "Miyoo Mini Plus" : "Miyoo Mini"; -} - -int PLAT_isOnline(void) { - return 0; -} \ No newline at end of file diff --git a/workspace/_unmaintained/miyoomini/platform/platform.h b/workspace/_unmaintained/miyoomini/platform/platform.h deleted file mode 100644 index d75fe5c39..000000000 --- a/workspace/_unmaintained/miyoomini/platform/platform.h +++ /dev/null @@ -1,123 +0,0 @@ -// miyoomini/platform/platform.h - -#ifndef PLATFORM_H -#define PLATFORM_H - -/////////////////////////////// - -#include "sdl.h" - -/////////////////////////////// - -#define BUTTON_UP SDLK_UP -#define BUTTON_DOWN SDLK_DOWN -#define BUTTON_LEFT SDLK_LEFT -#define BUTTON_RIGHT SDLK_RIGHT - -#define BUTTON_SELECT SDLK_RCTRL -#define BUTTON_START SDLK_RETURN - -#define BUTTON_A SDLK_SPACE -#define BUTTON_B SDLK_LCTRL -#define BUTTON_X SDLK_LSHIFT -#define BUTTON_Y SDLK_LALT - -#define BUTTON_L1 SDLK_e -#define BUTTON_R1 SDLK_t -#define BUTTON_L2 SDLK_TAB -#define BUTTON_R2 SDLK_BACKSPACE -#define BUTTON_L3 BUTTON_NA -#define BUTTON_R3 BUTTON_NA - -#define BUTTON_MENU SDLK_ESCAPE -#define BUTTON_POWER SDLK_POWER -#define BUTTON_PLUS SDLK_RSUPER -#define BUTTON_MINUS SDLK_LSUPER - -/////////////////////////////// - -#define CODE_UP 103 -#define CODE_DOWN 108 -#define CODE_LEFT 105 -#define CODE_RIGHT 106 - -#define CODE_SELECT 97 -#define CODE_START 28 - -#define CODE_A 57 -#define CODE_B 29 -#define CODE_X 42 -#define CODE_Y 56 - -#define CODE_L1 18 -#define CODE_R1 20 -#define CODE_L2 15 -#define CODE_R2 14 -#define CODE_L3 CODE_NA -#define CODE_R3 CODE_NA - -#define CODE_MENU 1 -#define CODE_POWER 116 - -#define CODE_PLUS 115 -#define CODE_MINUS 114 - -/////////////////////////////// - -#define JOY_UP JOY_NA -#define JOY_DOWN JOY_NA -#define JOY_LEFT JOY_NA -#define JOY_RIGHT JOY_NA - -#define JOY_SELECT JOY_NA -#define JOY_START JOY_NA - -#define JOY_A JOY_NA -#define JOY_B JOY_NA -#define JOY_X JOY_NA -#define JOY_Y JOY_NA - -#define JOY_L1 JOY_NA -#define JOY_R1 JOY_NA -#define JOY_L2 JOY_NA -#define JOY_R2 JOY_NA -#define JOY_L3 JOY_NA -#define JOY_R3 JOY_NA - -#define JOY_MENU JOY_NA -#define JOY_POWER JOY_NA -#define JOY_PLUS JOY_NA -#define JOY_MINUS JOY_NA - -/////////////////////////////// - -extern int is_plus; -#define BTN_RESUME BTN_X -#define BTN_SLEEP BTN_POWER -#define BTN_WAKE BTN_POWER -#define BTN_MOD_VOLUME (is_plus ? BTN_NONE : BTN_SELECT) -#define BTN_MOD_BRIGHTNESS (is_plus ? BTN_MENU : BTN_START) -#define BTN_MOD_PLUS (is_plus ? BTN_PLUS : BTN_R1) -#define BTN_MOD_MINUS (is_plus ? BTN_MINUS : BTN_L1) - -/////////////////////////////// - -#define FIXED_SCALE 2 -#define FIXED_WIDTH 640 -#define FIXED_HEIGHT 480 -#define FIXED_BPP 2 -#define FIXED_DEPTH (FIXED_BPP * 8) -#define FIXED_PITCH (FIXED_WIDTH * FIXED_BPP) -#define FIXED_SIZE (FIXED_PITCH * FIXED_HEIGHT) - -/////////////////////////////// - -#define SDCARD_PATH "/mnt/SDCARD" -#define MUTE_VOLUME_RAW -60 -#define HAS_NEON - -// this should be set to the devices native screen refresh rate -#define SCREEN_FPS 60.0 -/////////////////////////////// - -#endif diff --git a/workspace/_unmaintained/miyoomini/show/makefile b/workspace/_unmaintained/miyoomini/show/makefile deleted file mode 100644 index fd75ce9ec..000000000 --- a/workspace/_unmaintained/miyoomini/show/makefile +++ /dev/null @@ -1,15 +0,0 @@ -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif - -TARGET = show -PRODUCT= $(TARGET).elf - -CC = $(CROSS_COMPILE)gcc -CFLAGS = -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7ve -LDFLAGS = -lSDL -lSDL_image - -all: - $(CC) $(TARGET).c -o $(PRODUCT) $(CFLAGS) $(LDFLAGS) -clean: - rm -f $(PRODUCT) \ No newline at end of file diff --git a/workspace/_unmaintained/miyoomini/show/show.c b/workspace/_unmaintained/miyoomini/show/show.c deleted file mode 100644 index d4c217411..000000000 --- a/workspace/_unmaintained/miyoomini/show/show.c +++ /dev/null @@ -1,51 +0,0 @@ -// miyoomini -#include -#include - -#include -#include -#include -#include -#include - -int main(int argc , char* argv[]) { - if (argc<2) { - puts("Usage: show.elf image.png"); - return 0; - } - - char path[256]; - if (strchr(argv[1], '/')==NULL) sprintf(path, "/mnt/SDCARD/.system/res/%s", argv[1]); - else strncpy(path,argv[1],256); - - if (access(path, F_OK)!=0) return 0; // nothing to show :( - - int fb0_fd = open("/dev/fb0", O_RDWR); - struct fb_var_screeninfo vinfo; - ioctl(fb0_fd, FBIOGET_VSCREENINFO, &vinfo); - int map_size = vinfo.xres * vinfo.yres * (vinfo.bits_per_pixel / 8); // 640x480x4 - char* fb0_map = (char*)mmap(0, map_size, PROT_READ | PROT_WRITE, MAP_SHARED, fb0_fd, 0); - memset(fb0_map, 0, map_size); // clear screen - - SDL_Surface* img = IMG_Load(path); // 24-bit opaque png - - uint8_t* dst = (uint8_t*)fb0_map; // rgba - uint8_t* src = (uint8_t*)img->pixels; // bgr - src += ((img->h * img->w) - 1) * 3; - for (int y=0; yh; y++) { - for (int x=0; xw; x++) { - *(dst+0) = *(src+2); // r - *(dst+1) = *(src+1); // g - *(dst+2) = *(src+0); // b - *(dst+3) = 0xf; // alpha - dst += 4; - src -= 3; - } - } - SDL_FreeSurface(img); - - munmap(fb0_map, map_size); - close(fb0_fd); - - return EXIT_SUCCESS; -} diff --git a/workspace/_unmaintained/my282/cores/makefile b/workspace/_unmaintained/my282/cores/makefile deleted file mode 100644 index 6ec85be3e..000000000 --- a/workspace/_unmaintained/my282/cores/makefile +++ /dev/null @@ -1,4 +0,0 @@ -all: - # copy from original rg35xx (for now?) - rm -rf output - cp -r ../../rg35xx/cores/output ./ \ No newline at end of file diff --git a/workspace/_unmaintained/my282/install/boot.sh b/workspace/_unmaintained/my282/install/boot.sh deleted file mode 100755 index 46c0fbd8e..000000000 --- a/workspace/_unmaintained/my282/install/boot.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh -# NOTE: becomes .tmp_update/my282.sh - -PLATFORM="my282" -SDCARD_PATH="/mnt/SDCARD" -UPDATE_PATH="$SDCARD_PATH/NextUI.zip" -SYSTEM_PATH="$SDCARD_PATH/.system" - -CPU_PATH=/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor -echo performance > "$CPU_PATH" - -# install/update -if [ -f "$UPDATE_PATH" ]; then - cd $(dirname "$0")/$PLATFORM - - if [ -d "$SYSTEM_PATH" ]; then - ./show.elf ./updating.png - else - ./show.elf ./installing.png - fi - - mv $SDCARD_PATH/.tmp_update $SDCARD_PATH/.tmp_update-old - ./unzip -o "$UPDATE_PATH" -d "$SDCARD_PATH" - rm -f "$UPDATE_PATH" - rm -rf $SDCARD_PATH/.tmp_update-old - - # the updated system finishes the install/update - $SYSTEM_PATH/$PLATFORM/bin/install.sh -fi - -# or launch (and keep launched) -LAUNCH_PATH="$SYSTEM_PATH/$PLATFORM/paks/NextUI.pak/launch.sh" -while [ -f "$LAUNCH_PATH" ] ; do - "$LAUNCH_PATH" -done - -poweroff # under no circumstances should stock be allowed to touch this card diff --git a/workspace/_unmaintained/my282/install/installing.png b/workspace/_unmaintained/my282/install/installing.png deleted file mode 100644 index acde62551b3bffd9c192883ec06bb5ba0d6efc76..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3647 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 B=!^gW diff --git a/workspace/_unmaintained/my282/keymon/credits.txt b/workspace/_unmaintained/my282/keymon/credits.txt deleted file mode 100644 index e885e5dd1..000000000 --- a/workspace/_unmaintained/my282/keymon/credits.txt +++ /dev/null @@ -1,3 +0,0 @@ -based on eggs custom keymon for Trimui: - https://www.dropbox.com/sh/5e9xwvp672vt8cr/AABUIdw1vLYp9h0waoCUqHPOa/source?dl=0&subfolder_nav_tracking=1 -modified to use libmsettings \ No newline at end of file diff --git a/workspace/_unmaintained/my282/keymon/keymon.c b/workspace/_unmaintained/my282/keymon/keymon.c deleted file mode 100644 index 9ecbde8e9..000000000 --- a/workspace/_unmaintained/my282/keymon/keymon.c +++ /dev/null @@ -1,143 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -// #include "defines.h" - -#define VOLUME_MIN 0 -#define VOLUME_MAX 20 -#define BRIGHTNESS_MIN 0 -#define BRIGHTNESS_MAX 10 - -// uses different codes from SDL -#define CODE_MENU 1 // but also 354 -#define CODE_PLUS 115 -#define CODE_MINUS 114 - -// for ev.value -#define RELEASED 0 -#define PRESSED 1 -#define REPEAT 2 - -#define INPUT_COUNT 2 -static int inputs[INPUT_COUNT]; -static struct input_event ev; - -int main (int argc, char *argv[]) { - InitSettings(); - - // TODO: will require two inputs - // input_fd = open("/dev/input/event0", O_RDONLY | O_NONBLOCK | O_CLOEXEC); - inputs[0] = open("/dev/input/event0", O_RDONLY | O_NONBLOCK | O_CLOEXEC); - inputs[1] = open("/dev/input/event3", O_RDONLY | O_NONBLOCK | O_CLOEXEC); - - uint32_t input; - uint32_t val; - uint32_t menu_pressed = 0; - - uint32_t up_pressed = 0; - uint32_t up_just_pressed = 0; - uint32_t up_repeat_at = 0; - - uint32_t down_pressed = 0; - uint32_t down_just_pressed = 0; - uint32_t down_repeat_at = 0; - - uint8_t ignore; - uint32_t then; - uint32_t now; - struct timeval tod; - - gettimeofday(&tod, NULL); - then = tod.tv_sec * 1000 + tod.tv_usec / 1000; // essential SDL_GetTicks() - ignore = 0; - - while (1) { - gettimeofday(&tod, NULL); - now = tod.tv_sec * 1000 + tod.tv_usec / 1000; - if (now-then>1000) ignore = 1; // ignore input that arrived during sleep - - for (int i=0; i REPEAT )) continue; - // printf("code: %i (%i)\n", ev.code, val); fflush(stdout); - switch (ev.code) { - case CODE_MENU: - menu_pressed = val; - break; - break; - case CODE_PLUS: - up_pressed = up_just_pressed = val; - if (val) up_repeat_at = now + 300; - break; - case CODE_MINUS: - down_pressed = down_just_pressed = val; - if (val) down_repeat_at = now + 300; - break; - default: - break; - } - } - } - - if (ignore) { - menu_pressed = 0; - up_pressed = up_just_pressed = 0; - down_pressed = down_just_pressed = 0; - up_repeat_at = 0; - down_repeat_at = 0; - } - - if (up_just_pressed || (up_pressed && now>=up_repeat_at)) { - if (menu_pressed) { - // printf("brightness up\n"); fflush(stdout); - val = GetBrightness(); - if (val=down_repeat_at)) { - if (menu_pressed) { - // printf("brightness down\n"); fflush(stdout); - val = GetBrightness(); - if (val>BRIGHTNESS_MIN) SetBrightness(--val); - } - else { - // printf("volume down\n"); fflush(stdout); - val = GetVolume(); - if (val>VOLUME_MIN) SetVolume(--val); - } - - if (down_just_pressed) down_just_pressed = 0; - else down_repeat_at += 100; - } - - then = now; - ignore = 0; - - usleep(16666); // 60fps - } -} diff --git a/workspace/_unmaintained/my282/keymon/makefile b/workspace/_unmaintained/my282/keymon/makefile deleted file mode 100755 index edbe1279c..000000000 --- a/workspace/_unmaintained/my282/keymon/makefile +++ /dev/null @@ -1,16 +0,0 @@ -#keymon - -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif - -TARGET = keymon - -CC = $(CROSS_COMPILE)gcc -CFLAGS = -Os -lmsettings -lrt -ldl -Wl,--gc-sections -s -CFLAGS += -I. -I../../all/common -I../platform/ -DPLATFORM=\"$(UNION_PLATFORM)\" - -all: - $(CC) $(TARGET).c -o $(TARGET).elf $(CFLAGS) -clean: - rm -rf $(TARGET).elf \ No newline at end of file diff --git a/workspace/_unmaintained/my282/libmsettings/makefile b/workspace/_unmaintained/my282/libmsettings/makefile deleted file mode 100644 index b1418a21d..000000000 --- a/workspace/_unmaintained/my282/libmsettings/makefile +++ /dev/null @@ -1,32 +0,0 @@ -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif -ifeq (,$(PREFIX)) -$(error missing PREFIX for this toolchain) -endif - -TARGET=msettings - -.PHONY: build -.PHONY: clean - -CC = $(CROSS_COMPILE)gcc - -SYSROOT := $(shell $(CC) --print-sysroot) - -INCLUDEDIR = $(SYSROOT)/usr/include -CFLAGS = -I$(INCLUDEDIR) -LDFLAGS = -ldl -lrt -s - -OPTM=-Ofast - -build: - $(CC) -c -Werror -fpic "$(TARGET).c" -Wl,--no-as-needed $(LDFLAGS) - $(CC) -shared -o "lib$(TARGET).so" "$(TARGET).o" $(LDFLAGS) - cp "$(TARGET).h" "$(PREFIX)/include" - cp "lib$(TARGET).so" "$(PREFIX)/lib" -clean: - rm -f *.o - rm -f "lib$(TARGET).so" - rm -f $(PREFIX)/include/$(TARGET).h - rm -f $(PREFIX)/lib/lib$(TARGET).so \ No newline at end of file diff --git a/workspace/_unmaintained/my282/libmsettings/msettings.c b/workspace/_unmaintained/my282/libmsettings/msettings.c deleted file mode 100644 index 0660a6c45..000000000 --- a/workspace/_unmaintained/my282/libmsettings/msettings.c +++ /dev/null @@ -1,166 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "msettings.h" - -/////////////////////////////////////// - -#define SETTINGS_VERSION 1 -typedef struct Settings { - int version; // future proofing - int brightness; - int headphones; - int speaker; - int unused[2]; // for future use - // NOTE: doesn't really need to be persisted but still needs to be shared - int jack; - int hdmi; -} Settings; -static Settings DefaultSettings = { - .version = SETTINGS_VERSION, - .brightness = 2, - .headphones = 4, - .speaker = 8, - .jack = 0, - .hdmi = 0, -}; -static Settings* settings; - -#define SHM_KEY "/SharedSettings" -static char SettingsPath[256]; -static int shm_fd = -1; -static int is_host = 0; -static int shm_size = sizeof(Settings); - -void InitSettings(void) { - sprintf(SettingsPath, "%s/msettings.bin", getenv("USERDATA_PATH")); - - shm_fd = shm_open(SHM_KEY, O_RDWR | O_CREAT | O_EXCL, 0644); // see if it exists - if (shm_fd==-1 && errno==EEXIST) { // already exists - puts("Settings client"); - shm_fd = shm_open(SHM_KEY, O_RDWR, 0644); - settings = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); - } - else { // host - puts("Settings host"); // should always be keymon - is_host = 1; - // we created it so set initial size and populate - ftruncate(shm_fd, shm_size); - settings = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); - - int fd = open(SettingsPath, O_RDONLY); - if (fd>=0) { - read(fd, settings, shm_size); - // TODO: use settings->version for future proofing? - close(fd); - } - else { - // load defaults - memcpy(settings, &DefaultSettings, shm_size); - } - - // these shouldn't be persisted - // settings->jack = 0; - // settings->hdmi = 0; - } - - printf("brightness: %i \nspeaker: %i\n", settings->brightness, settings->speaker); fflush(stdout); - - SetVolume(GetVolume()); - SetBrightness(GetBrightness()); - // system("echo $(< " BRIGHTNESS_PATH ")"); -} -void QuitSettings(void) { - munmap(settings, shm_size); - if (is_host) shm_unlink(SHM_KEY); -} -static inline void SaveSettings(void) { - int fd = open(SettingsPath, O_CREAT|O_WRONLY, 0644); - if (fd>=0) { - write(fd, settings, shm_size); - close(fd); - sync(); - } -} - -int GetBrightness(void) { // 0-10 - return settings->brightness; -} -void SetBrightness(int value) { - if (settings->hdmi) return; - - int raw; - switch (value) { - case 0: raw = 3; break; // 0 - case 1: raw = 4; break; // 1 - case 2: raw = 5; break; // 1 - case 3: raw = 6; break; // 1 - case 4: raw = 8; break; // 2 - case 5: raw = 12; break; // 4 - case 6: raw = 16; break; // 4 - case 7: raw = 24; break; // 8 - case 8: raw = 72; break; // 48 - case 9: raw = 128; break; // 80 - case 10: raw = 255; break; // * - } - SetRawBrightness(raw); - settings->brightness = value; - SaveSettings(); -} - -int GetVolume(void) { // 0-20 - return settings->jack ? settings->headphones : settings->speaker; -} -void SetVolume(int value) { - if (settings->hdmi) return; - - if (settings->jack) settings->headphones = value; - else settings->speaker = value; - - int raw = value * 5; - SetRawVolume(raw); - SaveSettings(); -} - -#define DISP_LCD_SET_BRIGHTNESS 0x102 -void SetRawBrightness(int val) { // 0 - 255 - if (settings->hdmi) return; - - printf("SetRawBrightness(%i)\n", val); fflush(stdout); - int fd = open("/dev/disp", O_RDWR); - if (fd) { - unsigned long param[4]={0,val,0,0}; - ioctl(fd, DISP_LCD_SET_BRIGHTNESS, ¶m); - close(fd); - } -} -void SetRawVolume(int val) { // 0 - 100 - printf("SetRawVolume(%i)\n", val); fflush(stdout); - char cmd[256]; - sprintf(cmd, "amixer set 'headphone volume' %i%% > /dev/null 2>&1", val); - system(cmd); -} - -// monitored and set by thread in keymon? -int GetJack(void) { - return settings->jack; -} -void SetJack(int value) { - settings->jack = value; - SetVolume(GetVolume()); -} - -int GetHDMI(void) { return 0; } -void SetHDMI(int value) { /* buh */ } - -int GetMute(void) { return 0; } -void SetMute(int value) {} diff --git a/workspace/_unmaintained/my282/libmsettings/msettings.h b/workspace/_unmaintained/my282/libmsettings/msettings.h deleted file mode 100644 index e1122bdff..000000000 --- a/workspace/_unmaintained/my282/libmsettings/msettings.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef __msettings_h__ -#define __msettings_h__ - -void InitSettings(void); -void QuitSettings(void); - -int GetBrightness(void); -int GetVolume(void); - -void SetRawBrightness(int value); // 0-255 -void SetRawVolume(int value); // 0-100 - -void SetBrightness(int value); // 0-10 -void SetVolume(int value); // 0-20 - -int GetJack(void); -void SetJack(int value); // 0-1 - -int GetHDMI(void); -void SetHDMI(int value); // 0-1 - -int GetMute(void); -void SetMute(int value); // 0-1 - -#endif // __msettings_h__ diff --git a/workspace/_unmaintained/my282/libmstick/makefile b/workspace/_unmaintained/my282/libmstick/makefile deleted file mode 100644 index 336a60de8..000000000 --- a/workspace/_unmaintained/my282/libmstick/makefile +++ /dev/null @@ -1,34 +0,0 @@ -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif -ifeq (,$(PREFIX)) -$(error missing PREFIX for this toolchain) -endif - -include ../platform/makefile.env - -TARGET=mstick - -.PHONY: build -.PHONY: clean - -CC = $(CROSS_COMPILE)gcc - -SYSROOT := $(shell $(CC) --print-sysroot) - -INCLUDEDIR = $(SYSROOT)/usr/include -CFLAGS = -I$(INCLUDEDIR) $(ARCH) -LDFLAGS = -ldl -lpthread -lrt -s - -OPTM=-Ofast - -build: - $(CC) -c -Werror -fpic "$(TARGET).c" $(CFLAGS) -Wl,--no-as-needed $(LDFLAGS) - $(CC) -shared -o "lib$(TARGET).so" "$(TARGET).o" $(CFLAGS) $(LDFLAGS) - cp "$(TARGET).h" "$(PREFIX)/include" - cp "lib$(TARGET).so" "$(PREFIX)/lib" -clean: - rm -f *.o - rm -f "lib$(TARGET).so" - rm -f $(PREFIX)/include/$(TARGET).h - rm -f $(PREFIX)/lib/lib$(TARGET).so \ No newline at end of file diff --git a/workspace/_unmaintained/my282/libmstick/mstick.c b/workspace/_unmaintained/my282/libmstick/mstick.c deleted file mode 100644 index 20c3b8b55..000000000 --- a/workspace/_unmaintained/my282/libmstick/mstick.c +++ /dev/null @@ -1,408 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// based on https://steward-fu.github.io/website/handheld/miyoo_a30_cpp_joystick.htm - -#define SERIAL_GAMEDECK "/dev/ttyS0" -#define MIYOO_AXIS_MAX_COUNT 16 -#define MIYOO_PLAYER_MAGIC 0xFF -#define MIYOO_PLAYER_MAGIC_END 0xFE -#define MIYOO_PAD_FRAME_LEN 6 - -struct MIYOO_PAD_FRAME { - uint8_t magic; - uint8_t unused0; - uint8_t unused1; - uint8_t axis0; - uint8_t axis1; - uint8_t magicEnd; -}; - -static int s_fd = -1; -static int g_lastX = 0; -static int g_lastY = 0; - -#define MIYOO_ADC_MIDDLE 128 -#define MIYOO_ADC_RANGE 64 - -typedef struct Calibration { - int x_max; - int x_mid; - int x_min; - - int y_max; - int y_mid; - int y_min; -} Calibration; - -static Calibration calibration = { - .x_max = MIYOO_ADC_MIDDLE+MIYOO_ADC_RANGE, - .x_mid = MIYOO_ADC_MIDDLE, - .x_min = MIYOO_ADC_MIDDLE-MIYOO_ADC_RANGE, - - .y_max = MIYOO_ADC_MIDDLE+MIYOO_ADC_RANGE, - .y_mid = MIYOO_ADC_MIDDLE, - .y_min = MIYOO_ADC_MIDDLE-MIYOO_ADC_RANGE, -}; - -static int MIYOO_ADC_DEAD_ZONE = 10; -static int MIYOO_AXIS_INT8_DRIFT = 5; - -static struct MIYOO_PAD_FRAME s_frame = {0}; -static int32_t s_miyoo_axis[MIYOO_AXIS_MAX_COUNT] = {0}; -static int32_t s_miyoo_axis_last[MIYOO_AXIS_MAX_COUNT] = {0}; - -int uart_open(const char *port) { - int fd = -1; - - fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY); - if (-1 == fd) { - printf("Failed to open uart\n"); - return -1; - } - - if (fcntl(fd, F_SETFL, 0) < 0) { - printf("Failed to call fcntl\n"); - return -1; - } - return fd; -} -static void uart_close(int fd) { - close(fd); -} - -static int uart_set(int fd, int speed, int flow_ctrl, int databits, int stopbits, int parity) { - int i = 0; - int speed_arr[] = {B115200, B19200, B9600, B4800, B2400, B1200, B300}; - int name_arr[] = {115200, 19200, 9600, 4800, 2400, 1200, 300}; - struct termios options = {0}; - - if (tcgetattr(fd, &options) != 0) { - printf("Failed to get uart attributes\n"); - return -1; - } - - for (i = 0; i < sizeof(speed_arr) / sizeof(int); i++) { - if (speed == name_arr[i]) { - cfsetispeed(&options, speed_arr[i]); - cfsetospeed(&options, speed_arr[i]); - } - } - - options.c_cflag |= CLOCAL; - options.c_cflag |= CREAD; - switch (flow_ctrl) { - case 0: - options.c_cflag &= ~CRTSCTS; - break; - case 1: - options.c_cflag |= CRTSCTS; - break; - case 2: - options.c_cflag |= IXON | IXOFF | IXANY; - break; - } - - options.c_cflag &= ~CSIZE; - switch (databits) { - case 5: - options.c_cflag |= CS5; - break; - case 6: - options.c_cflag |= CS6; - break; - case 7: - options.c_cflag |= CS7; - break; - case 8: - options.c_cflag |= CS8; - break; - default: - return -1; - } - - switch (parity) { - case 'n': - case 'N': - options.c_cflag &= ~PARENB; - options.c_iflag &= ~INPCK; - break; - case 'o': - case 'O': - options.c_cflag |= (PARODD | PARENB); - options.c_iflag |= INPCK; - break; - case 'e': - case 'E': - options.c_cflag |= PARENB; - options.c_cflag &= ~PARODD; - options.c_iflag |= INPCK; - break; - case 's': - case 'S': - options.c_cflag &= ~PARENB; - options.c_cflag &= ~CSTOPB; - break; - default: - return -1; - } - - switch (stopbits) { - case 1: - options.c_cflag &= ~CSTOPB; - break; - case 2: - options.c_cflag |= CSTOPB; - break; - default: - return -1; - } - - options.c_oflag &= ~OPOST; - options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); - options.c_iflag &= ~(INLCR | ICRNL | IGNCR); - options.c_oflag &= ~(ONLCR | OCRNL); - options.c_cc[VTIME] = 1; - options.c_cc[VMIN] = 1; - - tcflush(fd, TCIFLUSH); - if (tcsetattr(fd, TCSANOW, &options) != 0) { - return -1; - } - return 0; -} -static int uart_init(int fd, int speed, int flow_ctrl, int databits, int stopbits, int parity) { - if (uart_set(fd, speed, flow_ctrl, databits, stopbits, parity) == -1) { - return -1; - } - return 0; -} -static int uart_read(int fd, char *rcv_buf, int data_len) { - int f_sel; - fd_set f_set; - fd_set f_read; - struct timeval time = {0}; - - FD_ZERO(&f_read); - FD_SET(fd, &f_read); - - time.tv_sec = 10; - time.tv_usec = 0; - f_sel = select(fd + 1, &f_read, NULL, NULL, &time); - if (f_sel) { - return read(fd, rcv_buf, data_len); - } - return 0; -} - -static int filterDeadzone(int newAxis, int oldAxis) { - // TODO: this causes it to ignore small changes which might be desirable as dejitter - // but it also ignores many small changes that might add up to a big change - // if (abs(newAxis - oldAxis) < MIYOO_AXIS_INT8_DRIFT) { - // return 1; - // } - return 0; -} -static int limitValue8(int value) { - if (value > 127) value = 127; - else if (value < -128) value = -128; - return value; -} - -static void check_axis_event(void) { - int i = 0; - for (i = 0; i < MIYOO_AXIS_MAX_COUNT; i++) { - if (s_miyoo_axis[i] != s_miyoo_axis_last[i]) { - if (!filterDeadzone(s_miyoo_axis[i], s_miyoo_axis_last[i])) { - if (i == 0) { - g_lastX = limitValue8(s_miyoo_axis[i]); - // printf("X %d\n", g_lastX); - } - else if (i == 1) { - g_lastY = limitValue8(s_miyoo_axis[i]); - // printf("Y %d\n", g_lastY); - } - } - } - s_miyoo_axis_last[i] = s_miyoo_axis[i]; - } - - // printf("x:%i-%i (%i) y:%i-%i (%i) %i,%i (%u,%u)\n", calibration.x_min,calibration.x_max,calibration.x_mid, calibration.y_min,calibration.y_max,calibration.y_mid, g_lastX,g_lastY, s_frame.axis0,s_frame.axis1); -} -static int miyoo_frame_to_axis_x(uint8_t rawX) { - // printf("raw x: %u\n", rawX); - - int maxX = rawX-8; - int minX = rawX+8; - if (maxX>calibration.x_max || minXcalibration.x_max) calibration.x_max = maxX; - if (minX calibration.x_mid && (calibration.x_max - calibration.x_mid) != 0) { - value = (rawX - calibration.x_mid) * 128 / (calibration.x_max - calibration.x_mid); - } - if (rawX < calibration.x_mid && (calibration.x_mid - calibration.x_min) != 0) { - value = (rawX - calibration.x_mid) * 128 / (calibration.x_mid - calibration.x_min); - } - - if (value > 0 && value < MIYOO_ADC_DEAD_ZONE) { - return 0; - } - if (value < 0 && value > -(MIYOO_ADC_DEAD_ZONE)) { - return 0; - } - return value; -} -static int miyoo_frame_to_axis_y(uint8_t rawY) { - // printf("raw y: %u\n", rawY); - - int maxY = rawY-8; - int minY = rawY+8; - if (maxY>calibration.y_max || minYcalibration.y_max) calibration.y_max = maxY; - if (minY calibration.y_mid && (calibration.y_max - calibration.y_mid) != 0) { - value = (rawY - calibration.y_mid) * 128 / (calibration.y_max - calibration.y_mid); - } - if (rawY < calibration.y_mid && (calibration.y_mid - calibration.y_min) != 0) { - value = (rawY - calibration.y_mid) * 128 / (calibration.y_mid - calibration.y_min); - } - - if (value > 0 && value < MIYOO_ADC_DEAD_ZONE) { - return 0; - } - if (value < 0 && value > -(MIYOO_ADC_DEAD_ZONE)) { - return 0; - } - return value; -} - -static int parser_miyoo_input(const char *cmd, int len) { - int i = 0; - int p = 0; - - if ((!cmd) || (len < MIYOO_PAD_FRAME_LEN)) { - return - 1; - } - - for (i = 0; i < len - MIYOO_PAD_FRAME_LEN + 1; i += MIYOO_PAD_FRAME_LEN) { - for (p = 0; p < MIYOO_PAD_FRAME_LEN - 1; p++) { - if ((cmd[i] == MIYOO_PLAYER_MAGIC) && (cmd[i + MIYOO_PAD_FRAME_LEN - 1] == MIYOO_PLAYER_MAGIC_END)) { - memcpy(&s_frame, cmd + i, sizeof(s_frame)); - break; - } - else { - i++; - } - } - } - s_miyoo_axis[ABS_X] = miyoo_frame_to_axis_x(s_frame.axis0); - s_miyoo_axis[ABS_Y] = miyoo_frame_to_axis_y(s_frame.axis1); - check_axis_event(); - return 0; -} - -static int miyoo_init_serial_input(void) { - int err = 0; - - memset(&s_frame, 0, sizeof(s_frame)); - memset(s_miyoo_axis, 0, sizeof(s_miyoo_axis)); - memset(s_miyoo_axis_last, 0, sizeof(s_miyoo_axis_last)); - s_fd = uart_open(SERIAL_GAMEDECK); - err = uart_init(s_fd, 9600, 0, 8, 1, 'N'); - if (s_fd <= 0) { - return -1; - } - return 0; -} -static void miyoo_close_serial_input(void) { - uart_close(s_fd); - s_fd = -1; -} - -/////////////////////////////// - -static char StickPath[256]; -static pthread_t stick_pt; - -static void printCalibration(void) { - printf("calibration\n"); - - printf("\tx_max: %i\n",calibration.x_max); - printf("\tx_mid: %i\n",calibration.x_mid); - printf("\tx_min: %i\n",calibration.x_min); - printf("\ty_max: %i\n",calibration.y_max); - printf("\ty_mid: %i\n",calibration.y_mid); - printf("\ty_min: %i\n",calibration.y_min); - fflush(stdout); -} - -static void* readStick(void *arg) { - while (1) { - char rcv_buf[256] = {0}; - int len = uart_read(s_fd, rcv_buf, 256); - if (len > 0) { - rcv_buf[len] = '\0'; - parser_miyoo_input(rcv_buf, len); - } - } - return NULL; -} - -void Stick_init(void) { - miyoo_init_serial_input(); - - // load calibration data if present - sprintf(StickPath, "%s/mstick.bin", getenv("USERDATA_PATH")); - int fd = open(StickPath, O_RDONLY); - if (fd>=0) { - read(fd, &calibration, sizeof(Calibration)); - close(fd); - - printf("loaded stick calibration\n"); - printCalibration(); - } - - pthread_create(&stick_pt, NULL, &readStick, NULL); -} -void Stick_quit(void) { - miyoo_close_serial_input(); - - // save calibration data - int fd = open(StickPath, O_CREAT|O_WRONLY, 0644); - if (fd>=0) { - write(fd, &calibration, sizeof(Calibration)); - close(fd); - sync(); - - printf("saved stick calibration\n"); - printCalibration(); - } - - pthread_cancel(stick_pt); - pthread_join(stick_pt, NULL); -} -void Stick_get(int* x, int* y) { // -32768 thru 32767 - *x = g_lastX * 256; - *y = g_lastY * 256; -} \ No newline at end of file diff --git a/workspace/_unmaintained/my282/libmstick/mstick.h b/workspace/_unmaintained/my282/libmstick/mstick.h deleted file mode 100644 index 7258b7bd8..000000000 --- a/workspace/_unmaintained/my282/libmstick/mstick.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __mstick_h__ -#define __mstick_h__ - -void Stick_init(void); -void Stick_quit(void); -void Stick_get(int* x, int* y); // -32768 thru 32767 - -#endif // __mstick_h__ diff --git a/workspace/_unmaintained/my282/makefile b/workspace/_unmaintained/my282/makefile deleted file mode 100644 index c54c49242..000000000 --- a/workspace/_unmaintained/my282/makefile +++ /dev/null @@ -1,41 +0,0 @@ -#my282 - -########################################################### - -ifeq (,$(PLATFORM)) -PLATFORM=$(UNION_PLATFORM) -endif - -ifeq (,$(PLATFORM)) -$(error please specify PLATFORM, eg. PLATFORM=trimui make) -endif - -########################################################### - -REQUIRES_COMMANDER=other/DinguxCommander-sdl2 -REQUIRES_UNZIP60=other/unzip60 - -all: readmes - cd show && make - cd overclock && make - cd other/squashfs && make - -early: $(REQUIRES_COMMANDER) $(REQUIRES_UNZIP60) - mkdir -p other - cd $(REQUIRES_COMMANDER) && make -j - cd $(REQUIRES_UNZIP60) && make -f unix/Makefile.trimuismart unzip - cd libmstick && make - -clean: - cd show && make clean - cd overclock && make clean - cd other/squashfs && make clean - cd $(REQUIRES_COMMANDER) && make clean - cd $(REQUIRES_UNZIP60) && make -f unix/Makefile.trimuismart clean - -$(REQUIRES_COMMANDER): - git clone --depth 1 https://github.com/shauninman/DinguxCommander-sdl2.git $(REQUIRES_COMMANDER) -$(REQUIRES_UNZIP60): - git clone --depth 1 https://github.com/shauninman/unzip60.git $(REQUIRES_UNZIP60) - -include ../all/readmes/makefile diff --git a/workspace/_unmaintained/my282/other/squashfs/makefile b/workspace/_unmaintained/my282/other/squashfs/makefile deleted file mode 100644 index 93917730d..000000000 --- a/workspace/_unmaintained/my282/other/squashfs/makefile +++ /dev/null @@ -1,15 +0,0 @@ -#my282 - -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif - -all: - mkdir -p ./output - mkdir -p ./output/bin - mkdir -p ./output/lib - cp /root/buildroot/output/target/usr/bin/*squashfs ./output/bin/ - cp /root/buildroot/output/target/usr/lib/liblzma.so.5.2.3 ./output/lib/liblzma.so.5 - -clean: - rm -rf output \ No newline at end of file diff --git a/workspace/_unmaintained/my282/overclock/credits.txt b/workspace/_unmaintained/my282/overclock/credits.txt deleted file mode 100644 index 9b9a3946f..000000000 --- a/workspace/_unmaintained/my282/overclock/credits.txt +++ /dev/null @@ -1,3 +0,0 @@ -Based on Steward-fu's A30 utils GUI/CLI (currently just the CLI portion with swap disabled) - source: https://github.com/steward-fu/website/releases/tag/miyoo-a30 - src_utils-v1.5.zip (current) \ No newline at end of file diff --git a/workspace/_unmaintained/my282/overclock/makefile b/workspace/_unmaintained/my282/overclock/makefile deleted file mode 100755 index 030c74aa5..000000000 --- a/workspace/_unmaintained/my282/overclock/makefile +++ /dev/null @@ -1,16 +0,0 @@ -#overclock - -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif - -TARGET = overclock - -CC = $(CROSS_COMPILE)gcc -CFLAGS = -Os -lrt -ldl -Wl,--gc-sections -s -CFLAGS += -I. -DPLATFORM=\"$(UNION_PLATFORM)\" - -all: - $(CC) $(TARGET).c -o $(TARGET).elf $(CFLAGS) -clean: - rm -rf $(TARGET).elf \ No newline at end of file diff --git a/workspace/_unmaintained/my282/overclock/overclock.c b/workspace/_unmaintained/my282/overclock/overclock.c deleted file mode 100644 index a99cec927..000000000 --- a/workspace/_unmaintained/my282/overclock/overclock.c +++ /dev/null @@ -1,1085 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#define CCU_BASE 0x01C20000 - -enum _state { - S_DISABLED = 0, - S_CHANGED, - S_NOT_CHANGED -} ; - -enum _type { - T_CORE = 0, - T_SCH, - T_CPU, - T_GPU, - T_RAM, - T_SWAP -}; - -struct _cpu_clock { - int clk; - uint32_t reg; -}; - -static const char *sch_name[] = { - "interactive", - "conservative", - "userspace", - "ondemand", - "performance", - "" -}; - -static struct _cpu_clock gpu_clock[] = { - 1, 0x8000000c, - 2, 0x80000008, - 3, 0x80000006, - 4, 0x80000004, - 5, 0x80000108, - 6, 0x80000003, - 7, 0x80000209, - 8, 0x80000002, - 9, 0x80000104, - 10, 0x80000206, - 11, 0x8000050c, - 12, 0x80000001, - 13, 0x80000306, - 14, 0x80000204, - 15, 0x80000407, - 16, 0x80000102, - 17, 0x80000406, - 18, 0x80000203, - 19, 0x80000304, - 20, 0x80000405, - 21, 0x80000607, - 22, 0x80000a0b, - 24, 0x80000000, - 25, 0x80000d0c, - 26, 0x80000908, - 27, 0x80000706, - 28, 0x80000504, - 29, 0x80000a08, - 30, 0x80000403, - 31, 0x80000c09, - 32, 0x80000302, - 33, 0x80000604, - 34, 0x80000906, - 35, 0x8000120c, - 36, 0x80000201, - 37, 0x80000a06, - 38, 0x80000704, - 39, 0x80000c07, - 40, 0x80000402, - 41, 0x80000b06, - 42, 0x80000603, - 43, 0x80000804, - 44, 0x80000a05, - 45, 0x80000e07, - 46, 0x8000160b, - 48, 0x80000100, - 49, 0x80001a0c, - 50, 0x80001208, - 51, 0x80000e06, - 52, 0x80000a04, - 53, 0x80001308, - 54, 0x80000803, - 55, 0x80001609, - 56, 0x80000602, - 57, 0x80000b04, - 58, 0x80001006, - 59, 0x80001f0c, - 60, 0x80000401, - 61, 0x80001106, - 62, 0x80000c04, - 63, 0x80001407, - 64, 0x80000702, - 65, 0x80001206, - 66, 0x80000a03, - 67, 0x80000d04, - 68, 0x80001005, - 69, 0x80001607, - 70, 0x8000220b, - 72, 0x80000200, - 73, 0x8000270c, - 74, 0x80001b08, - 75, 0x80001506, - 76, 0x80000f04, - 77, 0x80001c08, - 78, 0x80000c03, - 79, 0x80002009, - 80, 0x80000902, - 81, 0x80001004, - 82, 0x80001706, - 83, 0x80002c0c, - 84, 0x80000601, - 85, 0x80001806, - 86, 0x80001104, - 87, 0x80001c07, - 88, 0x80000a02, - 89, 0x80001906, - 90, 0x80000e03, - 91, 0x80001204, - 92, 0x80001605, - 93, 0x80001e07, - 94, 0x80002e0b, - 96, 0x80000300, - 97, 0x8000340c, - 98, 0x80002408, - 99, 0x80001c06, - 100, 0x80001404, - 101, 0x80002508, - 102, 0x80001003, - 103, 0x80002a09, - 104, 0x80000c02, - 105, 0x80001504, - 106, 0x80001e06, - 107, 0x8000390c, - 108, 0x80000801, - 109, 0x80001f06, - 110, 0x80001604, - 111, 0x80002407, - 112, 0x80000d02, - 113, 0x80002006, - 114, 0x80001203, - 115, 0x80001704, - 116, 0x80001c05, - 117, 0x80002607, - 118, 0x80003a0b, - 120, 0x80000400, - 121, 0x8000410c, - 122, 0x80002d08, - 123, 0x80002306, - 124, 0x80001904, - 125, 0x80002e08, - 126, 0x80001403, - 127, 0x80003409, - 128, 0x80000f02, - 129, 0x80001a04, - 130, 0x80002506, - 131, 0x8000460c, - 132, 0x80000a01, - 133, 0x80002606, - 134, 0x80001b04, - 135, 0x80002c07, - 136, 0x80001002, - 137, 0x80002706, - 138, 0x80001603, - 139, 0x80001c04, - 140, 0x80002205, - 141, 0x80002e07, - 142, 0x8000460b, - 144, 0x80000500, - 145, 0x80004e0c, - 146, 0x80003608, - 147, 0x80002a06, - 148, 0x80001e04, - 149, 0x80003708, - 150, 0x80001803, - 151, 0x80003e09, - 152, 0x80001202, - 153, 0x80001f04, - 154, 0x80002c06, - 155, 0x8000530c, - 156, 0x80000c01, - 157, 0x80002d06, - 158, 0x80002004, - 159, 0x80003407, - 160, 0x80001302, - 161, 0x80002e06, - 162, 0x80001a03, - 163, 0x80002104, - 164, 0x80002805, - 165, 0x80003607, - 166, 0x8000520b, - 168, 0x80000600, - 169, 0x80005b0c, - 170, 0x80003f08, - 171, 0x80003106, - 172, 0x80002304, - 173, 0x80004008, - 174, 0x80001c03, - 175, 0x80004809, - 176, 0x80001502, - 177, 0x80002404, - 178, 0x80003306, - 179, 0x8000600c, - 180, 0x80000e01, - 181, 0x80003406, - 182, 0x80002504, - 183, 0x80003c07, - 184, 0x80001602, - 185, 0x80003506, - 186, 0x80001e03, - 187, 0x80002604, - 188, 0x80002e05, - 189, 0x80003e07, - 190, 0x80005e0b, - 192, 0x80000700, - 193, 0x8000680c, - 194, 0x80004808, - 195, 0x80003806, - 196, 0x80002804, - 197, 0x80004908, - 198, 0x80002003, - 199, 0x80005209, - 200, 0x80001802, - 201, 0x80002904, - 202, 0x80003a06, - 203, 0x80006d0c, - 204, 0x80001001, - 205, 0x80003b06, - 206, 0x80002a04, - 207, 0x80004407, - 208, 0x80001902, - 209, 0x80003c06, - 210, 0x80002203, - 211, 0x80002b04, - 212, 0x80003405, - 213, 0x80004607, - 214, 0x80006a0b, - 216, 0x80000800, - 217, 0x8000750c, - 218, 0x80005108, - 219, 0x80003f06, - 220, 0x80002d04, - 221, 0x80005208, - 222, 0x80002403, - 223, 0x80005c09, - 224, 0x80001b02, - 225, 0x80002e04, - 226, 0x80004106, - 227, 0x80007a0c, - 228, 0x80001201, - 229, 0x80004206, - 230, 0x80002f04, - 231, 0x80004c07, - 232, 0x80001c02, - 233, 0x80004306, - 234, 0x80002603, - 235, 0x80003004, - 236, 0x80003a05, - 237, 0x80004e07, - 238, 0x8000760b, - 240, 0x80000900, - 242, 0x80005a08, - 243, 0x80004606, - 244, 0x80003204, - 245, 0x80005b08, - 246, 0x80002803, - 247, 0x80006609, - 248, 0x80001e02, - 249, 0x80003304, - 250, 0x80004806, - 252, 0x80001401, - 253, 0x80004906, - 254, 0x80003404, - 255, 0x80005407, - 256, 0x80001f02, - 257, 0x80004a06, - 258, 0x80002a03, - 259, 0x80003504, - 260, 0x80004005, - 261, 0x80005607, - 264, 0x80000a00, - 266, 0x80006308, - 267, 0x80004d06, - 268, 0x80003704, - 269, 0x80006408, - 270, 0x80002c03, - 271, 0x80007009, - 272, 0x80002102, - 273, 0x80003804, - 274, 0x80004f06, - 276, 0x80001601, - 277, 0x80005006, - 278, 0x80003904, - 279, 0x80005c07, - 280, 0x80002202, - 281, 0x80005106, - 282, 0x80002e03, - 283, 0x80003a04, - 284, 0x80004605, - 285, 0x80005e07, - 288, 0x80000b00, - 290, 0x80006c08, - 291, 0x80005406, - 292, 0x80003c04, - 293, 0x80006d08, - 294, 0x80003003, - 295, 0x80007a09, - 296, 0x80002402, - 297, 0x80003d04, - 298, 0x80005606, - 300, 0x80001801, - 301, 0x80005706, - 302, 0x80003e04, - 303, 0x80006407, - 304, 0x80002502, - 305, 0x80005806, - 306, 0x80003203, - 307, 0x80003f04, - 308, 0x80004c05, - 309, 0x80006607, - 312, 0x80000c00, - 314, 0x80007508, - 315, 0x80005b06, - 316, 0x80004104, - 317, 0x80007608, - 318, 0x80003403, - 320, 0x80002702, - 321, 0x80004204, - 322, 0x80005d06, - 324, 0x80001a01, - 325, 0x80005e06, - 326, 0x80004304, - 327, 0x80006c07, - 328, 0x80002802, - 329, 0x80005f06, - 330, 0x80003603, - 331, 0x80004404, - 332, 0x80005205, - 333, 0x80006e07, - 336, 0x80000d00, - 338, 0x80007e08, - 339, 0x80006206, - 340, 0x80004604, - 341, 0x80007f08, - 342, 0x80003803, - 344, 0x80002a02, - 345, 0x80004704, - 346, 0x80006406, - 348, 0x80001c01, - 349, 0x80006506, - 350, 0x80004804, - 351, 0x80007407, - 352, 0x80002b02, - 353, 0x80006606, - 354, 0x80003a03, - 355, 0x80004904, - 356, 0x80005805, - 357, 0x80007607, - 360, 0x80000e00, - 363, 0x80006906, - 364, 0x80004b04, - 366, 0x80003c03, - 368, 0x80002d02, - 369, 0x80004c04, - 370, 0x80006b06, - 372, 0x80001e01, - 373, 0x80006c06, - 374, 0x80004d04, - 375, 0x80007c07, - 376, 0x80002e02, - 377, 0x80006d06, - 378, 0x80003e03, - 379, 0x80004e04, - 380, 0x80005e05, - 381, 0x80007e07, - 384, 0x80000f00, - 387, 0x80007006, - 388, 0x80005004, - 390, 0x80004003, - 392, 0x80003002, - 393, 0x80005104, - 394, 0x80007206, - 396, 0x80002001, - 397, 0x80007306, - 398, 0x80005204, - 400, 0x80003102, - 401, 0x80007406, - 402, 0x80004203, - 403, 0x80005304, - 404, 0x80006405, - 408, 0x80001000, - 411, 0x80007706, - 412, 0x80005504, - 414, 0x80004403, - 416, 0x80003302, - 417, 0x80005604, - 418, 0x80007906, - 420, 0x80002201, - 421, 0x80007a06, - 422, 0x80005704, - 424, 0x80003402, - 425, 0x80007b06, - 426, 0x80004603, - 427, 0x80005804, - 428, 0x80006a05, - 432, 0x80001100, - 435, 0x80007e06, - 436, 0x80005a04, - 438, 0x80004803, - 440, 0x80003602, - 441, 0x80005b04, - 444, 0x80002401, - 446, 0x80005c04, - 448, 0x80003702, - 450, 0x80004a03, - 451, 0x80005d04, - 452, 0x80007005, - 456, 0x80001200, - 460, 0x80005f04, - 462, 0x80004c03, - 464, 0x80003902, - 465, 0x80006004, - 468, 0x80002601, - 470, 0x80006104, - 472, 0x80003a02, - 474, 0x80004e03, - 475, 0x80006204, - 476, 0x80007605, - 480, 0x80001300, - 484, 0x80006404, - 486, 0x80005003, - 488, 0x80003c02, - 489, 0x80006504, - 492, 0x80002801, - 494, 0x80006604, - 496, 0x80003d02, - 498, 0x80005203, - 499, 0x80006704, - 500, 0x80007c05, - 504, 0x80001400, - 508, 0x80006904, - 510, 0x80005403, - 512, 0x80003f02, - 513, 0x80006a04, - 516, 0x80002a01, - 518, 0x80006b04, - 520, 0x80004002, - 522, 0x80005603, - 523, 0x80006c04, - 528, 0x80001500, - 532, 0x80006e04, - 534, 0x80005803, - 536, 0x80004202, - 537, 0x80006f04, - 540, 0x80002c01, - 542, 0x80007004, - 544, 0x80004302, - 546, 0x80005a03, - 547, 0x80007104, - 552, 0x80001600, - 556, 0x80007304, - 558, 0x80005c03, - 560, 0x80004502, - 561, 0x80007404, - 564, 0x80002e01, - 566, 0x80007504, - 568, 0x80004602, - 570, 0x80005e03, - 571, 0x80007604, - 576, 0x80001700, - 580, 0x80007804, - 582, 0x80006003, - 584, 0x80004802, - 585, 0x80007904, - 588, 0x80003001, - 590, 0x80007a04, - 592, 0x80004902, - 594, 0x80006203, - 595, 0x80007b04, - 600, 0x80001800, - 604, 0x80007d04, - 606, 0x80006403, - 608, 0x80004b02, - 609, 0x80007e04, - 612, 0x80003201, - 614, 0x80007f04, - 616, 0x80004c02, - 618, 0x80006603, - 624, 0x80001900, - 630, 0x80006803, - 632, 0x80004e02, - 636, 0x80003401, - 640, 0x80004f02, - 642, 0x80006a03, - 648, 0x80001a00, - 654, 0x80006c03, - 656, 0x80005102, - 660, 0x80003601, - 664, 0x80005202, - 666, 0x80006e03, - 672, 0x80001b00, - 678, 0x80007003, - 680, 0x80005402, - 684, 0x80003801, - 688, 0x80005502, - 690, 0x80007203, - 696, 0x80001c00, - 702, 0x80007403, - 704, 0x80005702, - 708, 0x80003a01, - 712, 0x80005802, - 714, 0x80007603, - 720, 0x80001d00, - 726, 0x80007803, - 728, 0x80005a02, - 732, 0x80003c01, - 736, 0x80005b02, - 738, 0x80007a03, - 744, 0x80001e00, - 750, 0x80007c03, - 752, 0x80005d02, - 756, 0x80003e01, - 760, 0x80005e02, - 762, 0x80007e03, - 768, 0x80001f00, - 776, 0x80006002, - 780, 0x80004001, - 784, 0x80006102, - 792, 0x80002000, - 800, 0x80006302, - 804, 0x80004201, - 808, 0x80006402, - 816, 0x80002100, - 824, 0x80006602, - 828, 0x80004401, - 832, 0x80006702, - 840, 0x80002200, - 848, 0x80006902, - 852, 0x80004601, - 856, 0x80006a02, - 864, 0x80002300, - 872, 0x80006c02, - 876, 0x80004801, - 880, 0x80006d02, - 888, 0x80002400, - 896, 0x80006f02, - 900, 0x80004a01, - 904, 0x80007002, - 912, 0x80002500, - 920, 0x80007202, - 924, 0x80004c01, - 928, 0x80007302, - 936, 0x80002600, - 944, 0x80007502, - 948, 0x80004e01, - 952, 0x80007602, - 960, 0x80002700, - 968, 0x80007802, - 972, 0x80005001, - 976, 0x80007902, - 984, 0x80002800, - 992, 0x80007b02, - 996, 0x80005201, - 1000, 0x80007c02, - 1008, 0x80002900, - 1016, 0x80007e02, - 1020, 0x80005401, - 1024, 0x80007f02, - 1032, 0x80002a00, - 1044, 0x80005601, - 1056, 0x80002b00, - 1068, 0x80005801, - 1080, 0x80002c00, - 1092, 0x80005a01, - 1104, 0x80002d00, - 1116, 0x80005c01, - 1128, 0x80002e00, - 1140, 0x80005e01, - 1152, 0x80002f00, - 1164, 0x80006001, - 1176, 0x80003000, - 1188, 0x80006201, - 1200, 0x80003100, - 1212, 0x80006401, - 1224, 0x80003200, - 1236, 0x80006601, - 1248, 0x80003300, - 1260, 0x80006801, - 1272, 0x80003400, - 1284, 0x80006a01, - 1296, 0x80003500, - 1308, 0x80006c01, - 1320, 0x80003600, - 1332, 0x80006e01, - 1344, 0x80003700, - 1356, 0x80007001, - 1368, 0x80003800, - 1380, 0x80007201, - 1392, 0x80003900, - 1404, 0x80007401, - 1416, 0x80003a00, - 1428, 0x80007601, - 1440, 0x80003b00, - 1452, 0x80007801, - 1464, 0x80003c00, - 1476, 0x80007a01, - 1488, 0x80003d00, - 1500, 0x80007c01, - 1512, 0x80003e00, - 1524, 0x80007e01, - 1536, 0x80003f00, - 1560, 0x80004000, - 1584, 0x80004100, - 1608, 0x80004200, - 1632, 0x80004300, - 1656, 0x80004400, - 1680, 0x80004500, - 1704, 0x80004600, - 1728, 0x80004700, - 1752, 0x80004800, - 1776, 0x80004900, - 1800, 0x80004a00, - 1824, 0x80004b00, - 1848, 0x80004c00, - 1872, 0x80004d00, - 1896, 0x80004e00, - 1920, 0x80004f00, - 1944, 0x80005000, - 1968, 0x80005100, - 1992, 0x80005200, - 2016, 0x80005300, - 2040, 0x80005400, - 2064, 0x80005500, - 2088, 0x80005600, - 2112, 0x80005700, - 2136, 0x80005800, - 2160, 0x80005900, - 2184, 0x80005a00, - 2208, 0x80005b00, - 2232, 0x80005c00, - 2256, 0x80005d00, - 2280, 0x80005e00, - 2304, 0x80005f00, - 2328, 0x80006000, - 2352, 0x80006100, - 2376, 0x80006200, - 2400, 0x80006300, - 2424, 0x80006400, - 2448, 0x80006500, - 2472, 0x80006600, - 2496, 0x80006700, - 2520, 0x80006800, - 2544, 0x80006900, - 2568, 0x80006a00, - 2592, 0x80006b00, - 2616, 0x80006c00, - 2640, 0x80006d00, - 2664, 0x80006e00, - 2688, 0x80006f00, - 2712, 0x80007000, - 2736, 0x80007100, - 2760, 0x80007200, - 2784, 0x80007300, - 2808, 0x80007400, - 2832, 0x80007500, - 2856, 0x80007600, - 2880, 0x80007700, - 2904, 0x80007800, - 2928, 0x80007900, - 2952, 0x80007a00, - 2976, 0x80007b00, - 3000, 0x80007c00, - 3024, 0x80007d00, - 3048, 0x80007e00, - 3072, 0x80007f00, -}; - -static struct _cpu_clock cpu_clock[] = { - 96, 0x80000110, - 144, 0x80000120, - 192, 0x80000130, - 216, 0x80000220, - 240, 0x80000410, - 288, 0x80000230, - 336, 0x80000610, - 360, 0x80000420, - 384, 0x80000330, - 432, 0x80000520, - 480, 0x80000430, - 504, 0x80000620, - 528, 0x80000a10, - 576, 0x80000530, - 624, 0x80000c10, - 648, 0x80000820, - 672, 0x80000630, - 720, 0x80000920, - 768, 0x80000730, - 792, 0x80000a20, - 816, 0x80001010, - 864, 0x80000830, - 864, 0x80001110, - 912, 0x80001210, - 936, 0x80000c20, - 960, 0x80000930, - 1008, 0x80000d20, - 1056, 0x80000a30, - 1080, 0x80000e20, - 1104, 0x80001610, - 1152, 0x80000b30, - 1200, 0x80001810, - 1224, 0x80001020, - 1248, 0x80000c30, - 1296, 0x80001120, - 1344, 0x80000d30, - 1368, 0x80001220, - 1392, 0x80001c10, - 1440, 0x80000e30, - 1488, 0x80001e10, - 1512, 0x80001420, - 1536, 0x80000f30, - 1584, 0x80001520, - 1632, 0x80001030, - 1656, 0x80001620, - 1728, 0x80001130, - 1800, 0x80001820, - 1824, 0x80001230, - 1872, 0x80001920, - 1920, 0x80001330, - 1944, 0x80001a20, - 2016, 0x80001430, - 2088, 0x80001c20, - 2112, 0x80001530, - 2160, 0x80001d20, - 2208, 0x80001630, - 2232, 0x80001e20, - 2304, 0x80001730, - 2400, 0x80001830, - 2496, 0x80001930, - 2592, 0x80001a30, - 2688, 0x80001b30, - 2784, 0x80001c30, - 2880, 0x80001d30, - 2976, 0x80001e30, - 3072, 0x80001f30, -}; - -static int cur_sel = 0; -static int max_cpu_item = sizeof(cpu_clock) / sizeof(struct _cpu_clock); -static int max_gpu_item = sizeof(gpu_clock) / sizeof(struct _cpu_clock); - -static uint8_t *pmem = NULL; -static int mem_fd = -1; -static int core_val[2] = {0}; -static int cpu_val[2] = {0}; -static int gpu_val[2] = {0}; -static int ram_val[2] = {0}; -static int sch_val[2] = {0}; -static int swap_val[2] = {0}; - -static int get_core(int index) -{ - FILE *fd = NULL; - char buf[255] = {0}; - - sprintf(buf, "cat /sys/devices/system/cpu/cpu%d/online", index % 4); - fd = popen(buf, "r"); - if (fd == NULL) { - return -1; - } - fgets(buf, sizeof(buf), fd); - pclose(fd); - return atoi(buf); -} - -static enum _state ret_state(int v0, int v1) -{ - if (v1 <= 0) { - return S_DISABLED; - } - return v1 == v0 ? S_NOT_CHANGED : S_CHANGED; -} - -static enum _state get_state(enum _type t) -{ - if (t == T_SCH) { - return ret_state(sch_val[0], sch_val[1]); - } - else if (t == T_CORE) { - return ret_state(core_val[0], core_val[1]); - } - else if (t == T_CPU) { - return ret_state(cpu_val[0], cpu_val[1]); - } - else if (t == T_GPU) { - return ret_state(gpu_val[0], gpu_val[1]); - } - else if (t == T_RAM) { - return ret_state(ram_val[0], ram_val[1]); - } - else if (t == T_SWAP) { - return ret_state(swap_val[0], swap_val[1]); - } -} - -static int find_best_match_cpu_clock(int clk) -{ - int cc = 0; - - for (cc = 0; cc < max_cpu_item; cc++) { - if (cpu_clock[cc].clk >= clk) { - // printf("Found Best Match CPU %dMHz (0x%08x)\n", cpu_clock[cc].clk, cpu_clock[cc].reg); - return cc; - } - } - return -1; -} - -static int find_best_match_gpu_clock(int clk) -{ - int cc = 0; - - for (cc = 0; cc < max_gpu_item; cc++) { - if (gpu_clock[cc].clk >= clk) { - // printf("Found Best Match GPU %dMHz (0x%08x)\n", gpu_clock[cc].clk, gpu_clock[cc].reg); - return cc; - } - } - return -1; -} - -static void read_value(void) -{ - uint32_t m, p, n, k; - uint32_t v = 0; - uint32_t p_idx[] = {1, 2, 4, 8}; - - core_val[0] = get_core(0) + get_core(1) + get_core(2) + get_core(3); - v = *((uint32_t *)&pmem[0x00]); - m = (v & 3) + 1; - k = ((v >> 4) & 3) + 1; - n = ((v >> 8) & 0x1f) + 1; - p = p_idx[(v >> 16) & 3]; - cpu_val[0] = find_best_match_cpu_clock(24 * n * k); - // printf("CPU %dMHz,%dMHz (0x%08x,0x%08x, n:%d, k:%d, m:%d, p:%d)\n", - // (24 * n * k) / (m * p), cpu_clock[cpu_val[0]].clk, - // v, cpu_clock[cpu_val[0]].reg, - // n, k, m, p); - - v = *((uint32_t *)&pmem[0x38]); - m = (v & 0xf) + 1; - n = ((v >> 8) & 0x7f) + 1; - gpu_val[0] = find_best_match_gpu_clock((24 * n) / m); - // printf("GPU %dMHz,%dMHz (0x%08x,0x%08x, n:%d, m:%d)\n", - // (24 * n) / m, gpu_clock[gpu_val[0]].clk, - // v, gpu_clock[gpu_val[0]].reg, - // n, m); - - v = *((uint32_t *)&pmem[0xf8]); - if ((v & (1 << 16)) == 0) { - v = *((uint32_t *)&pmem[0x20]); - m = (v & 3) + 1; - k = ((v >> 4) & 3) + 1; - n = ((v >> 8) & 0x1f) + 1; - ram_val[0] = (n * k) / m; - // printf("DDR0 %dMHz (0x%08x)\n", 24 * ram_val[0], v); - } - else { - v = *((uint32_t *)&pmem[0x4c]); - n = (v >> 8) & 0x3f; - ram_val[0] = n; - // printf("DDR1 %dMHz (0x%08x)\n", 24 * ram_val[0], v); - } - - FILE *fd = NULL; - char buf[255] = {0}; - - fd = popen("cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor", "r"); - if (fd ) { - int len = 0; - int cc = 0; - - fgets(buf, sizeof(buf), fd); - len = strlen(buf); - for (cc = 0; cc < len; cc++) { - if (buf[cc] == '\r') { - buf[cc] = 0; - } - if (buf[cc] == '\n') { - buf[cc] = 0; - } - } - // printf("Governor: %s\n", buf); - for (cc = 0; cc < 5; cc++) { - if (!strcmp(buf, sch_name[cc])) { - sch_val[0] = cc; - // printf("Find Governor Index: %d\n", cc); - break; - } - } - pclose(fd); - } - - memset(buf, 0, sizeof(buf)); - fd = popen("swapon -s | grep swap", "r"); - if (fd ) { - fgets(buf, sizeof(buf), fd); - if (strlen(buf) > 10) { - swap_val[0] = 1; - } - pclose(fd); - } - // printf("SWAP %dMB\n", swap_val[0] ? 1024 : 0); - - sch_val[1] = sch_val[0]; - core_val[1] = core_val[0]; - cpu_val[1] = cpu_val[0]; - gpu_val[1] = gpu_val[0]; - ram_val[1] = ram_val[0]; - swap_val[1] = swap_val[0]; -} - -static void check_before_set(int num, int v) -{ - char buf[255] = {0}; - - if (get_core(num) != v) { - sprintf(buf, "echo %d > /sys/devices/system/cpu/cpu%d/online", v ? 1 : 0, num); - system(buf); - } -} - -static void set_core(int n) -{ - if (n <= 1) { - // printf("New CPU Core: 1\n"); - check_before_set(0, 1); - check_before_set(1, 0); - check_before_set(2, 0); - check_before_set(3, 0); - } - else if (n == 2) { - // printf("New CPU Core: 2\n"); - check_before_set(0, 1); - check_before_set(1, 1); - check_before_set(2, 0); - check_before_set(3, 0); - } - else if (n == 3) { - // printf("New CPU Core: 3\n"); - check_before_set(0, 1); - check_before_set(1, 1); - check_before_set(2, 1); - check_before_set(3, 0); - } - else { - // printf("New CPU Core: 4\n"); - check_before_set(0, 1); - check_before_set(1, 1); - check_before_set(2, 1); - check_before_set(3, 1); - } -} - -static void set_swap(int v) -{ - return; // disabled, no swap on NextUI - - #define SWAP "/mnt/SDCARD/App/utils/swap" - - int org = 0; - FILE *fd = NULL; - char buf[255] = {0}; - - fd = popen("swapon -s | grep swap", "r"); - if (fd ) { - fgets(buf, sizeof(buf), fd); - if (strlen(buf) > 10) { - org = 1; - } - pclose(fd); - } - - if (org != v) { - if (v) { - system("swapon " SWAP); - } - else { - system("swapoff " SWAP); - } - } -} - -static void set_ram(uint32_t v) -{ - uint32_t *p = (uint32_t *)&pmem[0x4c]; - - v &= 0x3f; - *p = (1 << 31) | (v << 8); - // printf("New DDR1 Clock is %dMHz\n", (24 * v)); -} - -static void set_cpu(uint32_t v) -{ - uint32_t *p = (uint32_t *)&pmem[0x00]; - - *p = cpu_clock[v].reg; - // printf("New CPU Clock is %dMHz (0x%08x)\n", cpu_clock[v].clk, cpu_clock[v].reg); -} - -static void set_gpu(uint32_t v) -{ - uint32_t *p = (uint32_t *)&pmem[0x38]; - - *p = gpu_clock[v].reg; - // printf("New GPU Clock is %dMHz (0x%08x)\n", gpu_clock[v].clk, gpu_clock[v].reg); -} - -static void set_sch(uint32_t v) -{ - char buf[255] = {0}; - - sprintf(buf, "echo %s > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor", sch_name[v % 5]); - system(buf); - // printf("New Schedule: %s\n", sch_name[v % 5]); -} - -static void set_sch_by_name(const char *s) -{ - char buf[255] = {0}; - - sprintf(buf, "echo %s > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor", s); - system(buf); - // printf("New Schedule: %s\n", s); -} - -int main(int argc, char **argv) { - mem_fd = open("/dev/mem", O_RDWR); - if (mem_fd < 0) { - printf("Failed to open /dev/mem\n"); - return -1; - } - pmem = mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, CCU_BASE); - if (pmem == MAP_FAILED) { - printf("Failed to map memory\n"); - return -1; - } - // printf("pmem %p\n", pmem); - read_value(); - - if (argc == 7) { - // printf("User Prefers: %s, %s, %d, %d, %d, %d\n\n", argv[1], argv[2], atoi(argv[3]), atoi(argv[4]), atoi(argv[5]), atoi(argv[6])); - set_sch_by_name(argv[1]); - set_core(atoi(argv[2])); - cpu_val[0] = find_best_match_cpu_clock(atoi(argv[3])); - gpu_val[0] = find_best_match_gpu_clock(atoi(argv[4])); - set_cpu(cpu_val[0]); - set_gpu(gpu_val[0]); - set_ram(atoi(argv[5]) / 24); - set_swap(atoi(argv[6])); - } - else { - printf("Usage: \n"); - printf("\t%s governor core cpu-freq gpu-freq ddr-freq swap\n\n", argv[0]); - printf("\tgovernor: interactive, conservative, userspace, ondemand, performance\n"); - printf("\tcore: 1~4\n"); - printf("\tcpu-freq: MHz\n"); - printf("\tgpu-freq: MHz\n"); - printf("\tddr-freq: MHz\n"); - printf("\tswap: on | off (ignored)\n\n"); - printf("Examples:\n"); - printf("\t%s userspace 1 648 384 1080 0\n", argv[0]); - printf("\t%s performance 4 1512 384 1080 1\n\n", argv[0]); - } - - return 0; -} diff --git a/workspace/_unmaintained/my282/platform/makefile.copy b/workspace/_unmaintained/my282/platform/makefile.copy deleted file mode 100644 index 2fc1fbf7c..000000000 --- a/workspace/_unmaintained/my282/platform/makefile.copy +++ /dev/null @@ -1,16 +0,0 @@ -$(PLATFORM): - # $@ - cp ./workspace/$@/overclock/overclock.elf ./build/SYSTEM/$@/bin/ - cp ./workspace/$@/show/show.elf ./build/SYSTEM/$@/bin - cp ./workspace/$@/libmstick/libmstick.so ./build/SYSTEM/$@/lib - # installer - cp ./workspace/$@/install/update.sh ./build/SYSTEM/$@/bin/install.sh - mkdir -p ./build/BOOT/common/$@/ - cp ./workspace/$@/install/boot.sh ./build/BOOT/common/$@.sh - cp ./workspace/$@/show/show.elf ./build/BOOT/common/$@/ - cp ./workspace/$@/install/*.png ./build/BOOT/common/$@/ - cp ./workspace/$@/other/unzip60/unzip ./build/BOOT/common/$@/ - #extras - cp -r ./workspace/$@/other/squashfs/output/* ./build/EXTRAS/Tools/$@/Remove\ Loading.pak/ - cp ./workspace/$@/other/DinguxCommander-sdl2/DinguxCommander ./build/EXTRAS/Tools/$@/Files.pak/ - cp -r ./workspace/$@/other/DinguxCommander-sdl2/res ./build/EXTRAS/Tools/$@/Files.pak/ diff --git a/workspace/_unmaintained/my282/platform/makefile.env b/workspace/_unmaintained/my282/platform/makefile.env deleted file mode 100644 index 0a66369bd..000000000 --- a/workspace/_unmaintained/my282/platform/makefile.env +++ /dev/null @@ -1,5 +0,0 @@ -# my282 -# ARCH = -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 # trimuismart -ARCH = -marm -mtune=cortex-a53 -mfpu=neon-fp-armv8 -mfloat-abi=hard -mcpu=cortex-a53 # rg35xx -LIBS = -flto -lmstick -SDL = SDL2 \ No newline at end of file diff --git a/workspace/_unmaintained/my282/platform/platform.c b/workspace/_unmaintained/my282/platform/platform.c deleted file mode 100644 index b35ba606d..000000000 --- a/workspace/_unmaintained/my282/platform/platform.c +++ /dev/null @@ -1,738 +0,0 @@ -// rgb30 -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include "defines.h" -#include "platform.h" -#include "api.h" -#include "utils.h" - -#include "scaler.h" - -/////////////////////////////// - -#define RAW_UP 103 -#define RAW_DOWN 108 -#define RAW_LEFT 105 -#define RAW_RIGHT 106 -#define RAW_A 57 -#define RAW_B 29 -#define RAW_X 42 -#define RAW_Y 56 -#define RAW_START 28 -#define RAW_SELECT 97 -#define RAW_MENU 1 -#define RAW_L1 18 -#define RAW_L2 15 -#define RAW_R1 20 -#define RAW_R2 14 -#define RAW_PLUS 115 -#define RAW_MINUS 114 -#define RAW_POWER 116 - -#define INPUT_COUNT 2 -static int inputs[INPUT_COUNT]; - -void PLAT_initInput(void) { - inputs[0] = open("/dev/input/event0", O_RDONLY | O_NONBLOCK | O_CLOEXEC); // power - inputs[1] = open("/dev/input/event3", O_RDONLY | O_NONBLOCK | O_CLOEXEC); // controller - Stick_init(); // analog -} -void PLAT_quitInput(void) { - Stick_quit(); - for (int i=0; i which has BTN_ constants that conflict with platform.h -struct input_event { - struct timeval time; - __u16 type; - __u16 code; - __s32 value; -}; -#define EV_KEY 0x01 -#define EV_ABS 0x03 - -void PLAT_pollInput(void) { - // reset transient state - pad.just_pressed = BTN_NONE; - pad.just_released = BTN_NONE; - pad.just_repeated = BTN_NONE; - - uint32_t tick = SDL_GetTicks(); - for (int i=0; i=pad.repeat_at[i])) { - pad.just_repeated |= btn; // set - pad.repeat_at[i] += PAD_REPEAT_INTERVAL; - } - } - - // the actual poll - int input; - static struct input_event event; - for (int i=0; i1) continue; // ignore repeats - - pressed = value; - // LOG_info("key event: %i (%i)\n", code,pressed); - if (code==RAW_UP) { btn = BTN_DPAD_UP; id = BTN_ID_DPAD_UP; } - else if (code==RAW_DOWN) { btn = BTN_DPAD_DOWN; id = BTN_ID_DPAD_DOWN; } - else if (code==RAW_LEFT) { btn = BTN_DPAD_LEFT; id = BTN_ID_DPAD_LEFT; } - else if (code==RAW_RIGHT) { btn = BTN_DPAD_RIGHT; id = BTN_ID_DPAD_RIGHT; } - else if (code==RAW_A) { btn = BTN_A; id = BTN_ID_A; } - else if (code==RAW_B) { btn = BTN_B; id = BTN_ID_B; } - else if (code==RAW_X) { btn = BTN_X; id = BTN_ID_X; } - else if (code==RAW_Y) { btn = BTN_Y; id = BTN_ID_Y; } - else if (code==RAW_START) { btn = BTN_START; id = BTN_ID_START; } - else if (code==RAW_SELECT) { btn = BTN_SELECT; id = BTN_ID_SELECT; } - else if (code==RAW_MENU) { btn = BTN_MENU; id = BTN_ID_MENU; } - else if (code==RAW_L1) { btn = BTN_L1; id = BTN_ID_L1; } - else if (code==RAW_L2) { btn = BTN_L2; id = BTN_ID_L2; } - else if (code==RAW_R1) { btn = BTN_R1; id = BTN_ID_R1; } - else if (code==RAW_R2) { btn = BTN_R2; id = BTN_ID_R2; } - else if (code==RAW_PLUS) { btn = BTN_PLUS; id = BTN_ID_PLUS; } - else if (code==RAW_MINUS) { btn = BTN_MINUS; id = BTN_ID_MINUS; } - else if (code==RAW_POWER) { btn = BTN_POWER; id = BTN_ID_POWER; } - } - - if (btn==BTN_NONE) continue; - - if (!pressed) { - pad.is_pressed &= ~btn; // unset - pad.just_repeated &= ~btn; // unset - pad.just_released |= btn; // set - } - else if ((pad.is_pressed & btn)==BTN_NONE) { - pad.just_pressed |= btn; // set - pad.just_repeated |= btn; // set - pad.is_pressed |= btn; // set - pad.repeat_at[id] = tick + PAD_REPEAT_DELAY; - } - } - } - - Stick_get(&(pad.laxis.x), &(pad.laxis.y)); - PAD_setAnalog(BTN_ID_ANALOG_LEFT, BTN_ID_ANALOG_RIGHT, pad.laxis.x, tick+PAD_REPEAT_DELAY); - PAD_setAnalog(BTN_ID_ANALOG_UP, BTN_ID_ANALOG_DOWN, pad.laxis.y, tick+PAD_REPEAT_DELAY); -} - -int PLAT_shouldWake(void) { - int input; - static struct input_event event; - for (int i=0; imode.w) rotate = 3; - vid.renderer = SDL_CreateRenderer(vid.window,-1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC); - // SDL_RenderSetLogicalSize(vid.renderer, w,h); // TODO: wrong, but without and with the below it's even wrong-er - - // int renderer_width,renderer_height; - // SDL_GetRendererOutputSize(vid.renderer, &renderer_width, &renderer_height); - // LOG_info("output size: %ix%i\n", renderer_width, renderer_height); - // if (renderer_width!=w) { // I think this can only be hdmi - // float x_scale = (float)renderer_width / w; - // float y_scale = (float)renderer_height / h; - // SDL_SetWindowSize(vid.window, w / x_scale, h / y_scale); - // - // SDL_GetRendererOutputSize(vid.renderer, &renderer_width, &renderer_height); - // LOG_info("adjusted size: %ix%i\n", renderer_width, renderer_height); - // x_scale = (float)renderer_width / w; - // y_scale = (float)renderer_height / h; - // SDL_RenderSetScale(vid.renderer, x_scale,y_scale); - // - // // for some reason we need to clear and present - // // after setting the window size or we'll miss - // // the first frame - // SDL_RenderClear(vid.renderer); - // SDL_RenderPresent(vid.renderer); - // } - - // SDL_RendererInfo info; - // SDL_GetRendererInfo(vid.renderer, &info); - // LOG_info("Current render driver: %s\n", info.name); - - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY,"1"); // linear - vid.texture = SDL_CreateTexture(vid.renderer,SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, w,h); - vid.target = NULL; // only needed for non-native sizes - - // TODO: doesn't work here - // SDL_SetTextureScaleMode(vid.texture, SDL_ScaleModeLinear); // we always start at device size so use linear for better upscaling over hdmi - - // SDL_ScaleMode scale_mode; - // SDL_GetTextureScaleMode(vid.texture, &scale_mode); - // LOG_info("texture scale mode: %i\n", scale_mode); - - // int format; - // int access_; - // SDL_QueryTexture(vid.texture, &format, &access_, NULL,NULL); - // LOG_info("texture format: %s (streaming: %i)\n", SDL_GetPixelFormatName(format), access_==SDL_TEXTUREACCESS_STREAMING); - - vid.buffer = SDL_CreateRGBSurfaceFrom(NULL, w,h, FIXED_DEPTH, p, RGBA_MASK_565); - vid.screen = SDL_CreateRGBSurface(SDL_SWSURFACE, w,h, FIXED_DEPTH, RGBA_MASK_565); - vid.width = w; - vid.height = h; - vid.pitch = p; - - device_width = w; - device_height = h; - device_pitch = p; - - vid.sharpness = SHARPNESS_SOFT; - - return vid.screen; -} - -static void clearVideo(void) { - SDL_FillRect(vid.screen, NULL, 0); - for (int i=0; i<3; i++) { - SDL_RenderClear(vid.renderer); - SDL_RenderPresent(vid.renderer); - } -} - -void PLAT_quitVideo(void) { - // clearVideo(); - - SDL_FreeSurface(vid.screen); - SDL_FreeSurface(vid.buffer); - if (vid.target) SDL_DestroyTexture(vid.target); - if (vid.effect) SDL_DestroyTexture(vid.effect); - SDL_DestroyTexture(vid.texture); - SDL_DestroyRenderer(vid.renderer); - SDL_DestroyWindow(vid.window); - - // system("cat /dev/zero > /dev/fb0 2>/dev/null"); - SDL_Quit(); -} - -void PLAT_clearVideo(SDL_Surface* screen) { - SDL_FillRect(screen, NULL, 0); // TODO: revisit -} -void PLAT_clearAll(void) { - PLAT_clearVideo(vid.screen); // TODO: revist - SDL_RenderClear(vid.renderer); -} - -void PLAT_setVsync(int vsync) { - // buh -} - -static int hard_scale = 4; // TODO: base src size, eg. 160x144 can be 4 - -static void resizeVideo(int w, int h, int p) { - if (w==vid.width && h==vid.height && p==vid.pitch) return; - - // TODO: minarch disables crisp (and nn upscale before linear downscale) when native - - if (w>=device_width && h>=device_height) hard_scale = 1; - else if (h>=160) hard_scale = 2; // limits gba and up to 2x (seems sufficient) - else hard_scale = 4; - - LOG_info("resizeVideo(%i,%i,%i) hard_scale: %i crisp: %i\n",w,h,p, hard_scale,vid.sharpness==SHARPNESS_CRISP); - - SDL_FreeSurface(vid.buffer); - SDL_DestroyTexture(vid.texture); - if (vid.target) SDL_DestroyTexture(vid.target); - - SDL_SetHintWithPriority(SDL_HINT_RENDER_SCALE_QUALITY, vid.sharpness==SHARPNESS_SOFT?"1":"0", SDL_HINT_OVERRIDE); - vid.texture = SDL_CreateTexture(vid.renderer,SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, w,h); - - if (vid.sharpness==SHARPNESS_CRISP) { - SDL_SetHintWithPriority(SDL_HINT_RENDER_SCALE_QUALITY, "1", SDL_HINT_OVERRIDE); - vid.target = SDL_CreateTexture(vid.renderer,SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_TARGET, w * hard_scale,h * hard_scale); - } - else { - vid.target = NULL; - } - - vid.buffer = SDL_CreateRGBSurfaceFrom(NULL, w,h, FIXED_DEPTH, p, RGBA_MASK_565); - - vid.width = w; - vid.height = h; - vid.pitch = p; -} - -SDL_Surface* PLAT_resizeVideo(int w, int h, int p) { - resizeVideo(w,h,p); - return vid.screen; -} - -void PLAT_setVideoScaleClip(int x, int y, int width, int height) { - // buh -} -void PLAT_setNearestNeighbor(int enabled) { - // buh -} -void PLAT_setSharpness(int sharpness) { - if (vid.sharpness==sharpness) return; - int p = vid.pitch; - vid.pitch = 0; - vid.sharpness = sharpness; - resizeVideo(vid.width,vid.height,p); -} - -static struct FX_Context { - int scale; - int type; - int color; - int next_scale; - int next_type; - int next_color; - int live_type; -} effect = { - .scale = 1, - .next_scale = 1, - .type = EFFECT_NONE, - .next_type = EFFECT_NONE, - .live_type = EFFECT_NONE, - .color = 0, - .next_color = 0, -}; -static void rgb565_to_rgb888(uint32_t rgb565, uint8_t *r, uint8_t *g, uint8_t *b) { - // Extract the red component (5 bits) - uint8_t red = (rgb565 >> 11) & 0x1F; - // Extract the green component (6 bits) - uint8_t green = (rgb565 >> 5) & 0x3F; - // Extract the blue component (5 bits) - uint8_t blue = rgb565 & 0x1F; - - // Scale the values to 8-bit range - *r = (red << 3) | (red >> 2); - *g = (green << 2) | (green >> 4); - *b = (blue << 3) | (blue >> 2); -} -static void updateEffect(void) { - if (effect.next_scale==effect.scale && effect.next_type==effect.type && effect.next_color==effect.color) return; // unchanged - - int live_scale = effect.scale; - int live_color = effect.color; - effect.scale = effect.next_scale; - effect.type = effect.next_type; - effect.color = effect.next_color; - - if (effect.type==EFFECT_NONE) return; // disabled - if (effect.type==effect.live_type && effect.scale==live_scale && effect.color==live_color) return; // already loaded - - char* effect_path; - int opacity = 128; // 1 - 1/2 = 50% - if (effect.type==EFFECT_LINE) { - if (effect.scale<3) { - effect_path = RES_PATH "/line-2.png"; - } - else if (effect.scale<4) { - effect_path = RES_PATH "/line-3.png"; - } - else if (effect.scale<5) { - effect_path = RES_PATH "/line-4.png"; - } - else if (effect.scale<6) { - effect_path = RES_PATH "/line-5.png"; - } - else if (effect.scale<8) { - effect_path = RES_PATH "/line-6.png"; - } - else { - effect_path = RES_PATH "/line-8.png"; - } - } - else if (effect.type==EFFECT_GRID) { - if (effect.scale<3) { - effect_path = RES_PATH "/grid-2.png"; - opacity = 64; // 1 - 3/4 = 25% - } - else if (effect.scale<4) { - effect_path = RES_PATH "/grid-3.png"; - opacity = 112; // 1 - 5/9 = ~44% - } - else if (effect.scale<5) { - effect_path = RES_PATH "/grid-4.png"; - opacity = 144; // 1 - 7/16 = ~56% - } - else if (effect.scale<6) { - effect_path = RES_PATH "/grid-5.png"; - opacity = 160; // 1 - 9/25 = ~64% - } - else if (effect.scale<8) { - effect_path = RES_PATH "/grid-6.png"; - opacity = 112; // 1 - 5/9 = ~44% - } - else if (effect.scale<11) { - effect_path = RES_PATH "/grid-8.png"; - opacity = 144; // 1 - 7/16 = ~56% - } - else { - effect_path = RES_PATH "/grid-11.png"; - opacity = 136; // 1 - 57/121 = ~52% - } - } - - // LOG_info("effect: %s opacity: %i\n", effect_path, opacity); - SDL_Surface* tmp = IMG_Load(effect_path); - if (tmp) { - if (effect.type==EFFECT_GRID) { - if (effect.color) { - // LOG_info("dmg color grid...\n"); - - uint8_t r,g,b; - rgb565_to_rgb888(effect.color,&r,&g,&b); - // LOG_info("rgb %i,%i,%i\n",r,g,b); - - uint32_t* pixels = (uint32_t*)tmp->pixels; - int width = tmp->w; - int height = tmp->h; - for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) { - uint32_t pixel = pixels[y * width + x]; - uint8_t _,a; - SDL_GetRGBA(pixel, tmp->format, &_, &_, &_, &a); - if (a) pixels[y * width + x] = SDL_MapRGBA(tmp->format, r,g,b, a); - } - } - } - } - - if (vid.effect) SDL_DestroyTexture(vid.effect); - vid.effect = SDL_CreateTextureFromSurface(vid.renderer, tmp); - SDL_SetTextureAlphaMod(vid.effect, opacity); - SDL_FreeSurface(tmp); - effect.live_type = effect.type; - } - } -void PLAT_setEffect(int next_type) { - effect.next_type = next_type; -} -void PLAT_setEffectColor(int next_color) { - effect.next_color = next_color; -} -void PLAT_vsync(int remaining) { - if (remaining>0) SDL_Delay(remaining); -} - -scaler_t PLAT_getScaler(GFX_Renderer* renderer) { - // LOG_info("getScaler for scale: %i\n", renderer->scale); - effect.next_scale = renderer->scale; - return scale1x1_c16; -} - -void PLAT_blitRenderer(GFX_Renderer* renderer) { - vid.blit = renderer; - SDL_RenderClear(vid.renderer); - resizeVideo(vid.blit->true_w,vid.blit->true_h,vid.blit->src_p); -} - -void PLAT_flip(SDL_Surface* IGNORED, int ignored) { - if (!vid.blit) { - resizeVideo(device_width,device_height,FIXED_PITCH); // !!!??? - SDL_UpdateTexture(vid.texture,NULL,vid.screen->pixels,vid.screen->pitch); - if (rotate) SDL_RenderCopyEx(vid.renderer,vid.texture,NULL,&(SDL_Rect){0,device_width,device_width,device_height},rotate*90,&(SDL_Point){0,0},SDL_FLIP_NONE); - else SDL_RenderCopy(vid.renderer, vid.texture, NULL,NULL); - SDL_RenderPresent(vid.renderer); - return; - } - - // uint32_t then = SDL_GetTicks(); - SDL_UpdateTexture(vid.texture,NULL,vid.blit->src,vid.blit->src_p); - // LOG_info("blit blocked for %ims (%i,%i)\n", SDL_GetTicks()-then,vid.buffer->w,vid.buffer->h); - - SDL_Texture* target = vid.texture; - int x = vid.blit->src_x; - int y = vid.blit->src_y; - int w = vid.blit->src_w; - int h = vid.blit->src_h; - if (vid.sharpness==SHARPNESS_CRISP) { - SDL_SetRenderTarget(vid.renderer,vid.target); - SDL_RenderCopy(vid.renderer, vid.texture, NULL,NULL); - SDL_SetRenderTarget(vid.renderer,NULL); - x *= hard_scale; - y *= hard_scale; - w *= hard_scale; - h *= hard_scale; - target = vid.target; - } - - SDL_Rect* src_rect = &(SDL_Rect){x,y,w,h}; - SDL_Rect* dst_rect = &(SDL_Rect){0,0,device_width,device_height}; - if (vid.blit->aspect==0) { // native or cropped - // LOG_info("src_rect %i,%i %ix%i\n",src_rect->x,src_rect->y,src_rect->w,src_rect->h); - - int w = vid.blit->src_w * vid.blit->scale; - int h = vid.blit->src_h * vid.blit->scale; - int x = (device_width - w) / 2; - int y = (device_height - h) / 2; - dst_rect->x = x; - dst_rect->y = y; - dst_rect->w = w; - dst_rect->h = h; - - // LOG_info("dst_rect %i,%i %ix%i\n",dst_rect->x,dst_rect->y,dst_rect->w,dst_rect->h); - } - else if (vid.blit->aspect>0) { // aspect - int h = device_height; - int w = h * vid.blit->aspect; - if (w>device_width) { - double ratio = 1 / vid.blit->aspect; - w = device_width; - h = w * ratio; - } - int x = (device_width - w) / 2; - int y = (device_height - h) / 2; - // dst_rect = &(SDL_Rect){x,y,w,h}; - dst_rect->x = x; - dst_rect->y = y; - dst_rect->w = w; - dst_rect->h = h; - } - - int ox,oy; - oy = (device_width-device_height)/2; - ox = -oy; - if (rotate) SDL_RenderCopyEx(vid.renderer,target,src_rect,&(SDL_Rect){ox+dst_rect->x,oy+dst_rect->y,dst_rect->w,dst_rect->h},rotate*90,NULL,SDL_FLIP_NONE); - else SDL_RenderCopy(vid.renderer, target, src_rect, dst_rect); - - updateEffect(); - if (vid.blit && effect.type!=EFFECT_NONE && vid.effect) { - // ox = effect.scale - (dst_rect->x % effect.scale); - // oy = effect.scale - (dst_rect->y % effect.scale); - // if (ox==effect.scale) ox = 0; - // if (oy==effect.scale) oy = 0; - // LOG_info("rotate: %i ox: %i oy: %i\n", rotate, ox,oy); - if (rotate) SDL_RenderCopyEx(vid.renderer,vid.effect,&(SDL_Rect){0,0,dst_rect->w,dst_rect->h},&(SDL_Rect){ox+dst_rect->x,oy+dst_rect->y,dst_rect->w,dst_rect->h},rotate*90,NULL,SDL_FLIP_NONE); - else SDL_RenderCopy(vid.renderer, vid.effect, &(SDL_Rect){0,0,dst_rect->w,dst_rect->h},dst_rect); - } - - // uint32_t then = SDL_GetTicks(); - SDL_RenderPresent(vid.renderer); - // LOG_info("SDL_RenderPresent blocked for %ims\n", SDL_GetTicks()-then); - vid.blit = NULL; -} - -/////////////////////////////// - -// TODO: -#define OVERLAY_WIDTH PILL_SIZE // unscaled -#define OVERLAY_HEIGHT PILL_SIZE // unscaled -#define OVERLAY_BPP 4 -#define OVERLAY_DEPTH 16 -#define OVERLAY_PITCH (OVERLAY_WIDTH * OVERLAY_BPP) // unscaled -#define OVERLAY_RGBA_MASK 0x00ff0000,0x0000ff00,0x000000ff,0xff000000 // ARGB -static struct OVL_Context { - SDL_Surface* overlay; -} ovl; - -SDL_Surface* PLAT_initOverlay(void) { - ovl.overlay = SDL_CreateRGBSurface(SDL_SWSURFACE, SCALE2(OVERLAY_WIDTH,OVERLAY_HEIGHT),OVERLAY_DEPTH,OVERLAY_RGBA_MASK); - return ovl.overlay; -} -void PLAT_quitOverlay(void) { - if (ovl.overlay) SDL_FreeSurface(ovl.overlay); -} -void PLAT_enableOverlay(int enable) { - -} - -/////////////////////////////// - -static int online = 0; -void PLAT_getBatteryStatus(int* is_charging, int* charge) { - PLAT_getBatteryStatusFine(is_charging, charge); - - // worry less about battery and more about the game you're playing - if (*charge>80) *charge = 100; - else if (*charge>60) *charge = 80; - else if (*charge>40) *charge = 60; - else if (*charge>20) *charge = 40; - else if (*charge>10) *charge = 20; - else *charge = 10; -} - -void PLAT_getBatteryStatusFine(int* is_charging, int* charge) -{ - // *is_charging = 0; - // *charge = PWR_LOW_CHARGE; - // return; - - *is_charging = getInt("/sys/class/power_supply/usb/online"); - - *charge = getInt("/sys/class/power_supply/battery/capacity"); - - // wifi status, just hooking into the regular PWR polling - // char status[16]; - // getFile("/sys/class/net/wlan0/operstate", status,16); - // online = prefixMatch("up", status); -} - -#define LED_PATH "/sys/class/leds/led1/brightness" -void PLAT_enableBacklight(int enable) { - if (enable) { - SetBrightness(GetBrightness()); - putInt(LED_PATH, 0); - } - else { - SetRawBrightness(0); - putInt(LED_PATH, 255); - } -} - -void PLAT_powerOff(void) { - system("rm -f /tmp/nextui_exec && sync"); - sleep(2); - - SetRawVolume(MUTE_VOLUME_RAW); - PLAT_enableBacklight(0); - putInt(LED_PATH,255); - SND_quit(); - VIB_quit(); - PWR_quit(); - GFX_quit(); - exit(0); -} - -/////////////////////////////// - -void PLAT_setCPUSpeed(int speed) { - int freq = 0; - int cpu = 1; - switch (speed) { - case CPU_SPEED_MENU: freq = 576; cpu = 1; break; - case CPU_SPEED_POWERSAVE: freq = 1056; cpu = 1; break; - case CPU_SPEED_NORMAL: freq = 1344; cpu = 2; break; - case CPU_SPEED_PERFORMANCE: freq = 1512; cpu = 2; break; - } - - char cmd[128]; - sprintf(cmd,"overclock.elf userspace %d %d 384 1080 0", cpu, freq); - system(cmd); -} - -#define RUMBLE_PATH "/sys/devices/virtual/timed_output/vibrator/enable" -void PLAT_setRumble(int strength) { - putInt(RUMBLE_PATH, strength?1000:0); -} - -int PLAT_pickSampleRate(int requested, int max) { - return MIN(requested, max); -} - -char* PLAT_getModel(void) { - return "Miyoo A30"; -} - -int PLAT_isOnline(void) { - return online; -} \ No newline at end of file diff --git a/workspace/_unmaintained/my282/platform/platform.h b/workspace/_unmaintained/my282/platform/platform.h deleted file mode 100644 index e586ffd94..000000000 --- a/workspace/_unmaintained/my282/platform/platform.h +++ /dev/null @@ -1,123 +0,0 @@ -// my282/platform/platform.h - -#ifndef PLATFORM_H -#define PLATFORM_H - -/////////////////////////////// - -#include "sdl.h" - -/////////////////////////////// - -#define BUTTON_UP BUTTON_NA -#define BUTTON_DOWN BUTTON_NA -#define BUTTON_LEFT BUTTON_NA -#define BUTTON_RIGHT BUTTON_NA - -#define BUTTON_SELECT BUTTON_NA -#define BUTTON_START BUTTON_NA - -#define BUTTON_A BUTTON_NA -#define BUTTON_B BUTTON_NA -#define BUTTON_X BUTTON_NA -#define BUTTON_Y BUTTON_NA - -#define BUTTON_L1 BUTTON_NA -#define BUTTON_R1 BUTTON_NA -#define BUTTON_L2 BUTTON_NA -#define BUTTON_R2 BUTTON_NA -#define BUTTON_L3 BUTTON_NA -#define BUTTON_R3 BUTTON_NA - -#define BUTTON_MENU BUTTON_NA -#define BUTTON_POWER BUTTON_NA -#define BUTTON_PLUS BUTTON_NA -#define BUTTON_MINUS BUTTON_NA - -/////////////////////////////// - -#define CODE_UP CODE_NA -#define CODE_DOWN CODE_NA -#define CODE_LEFT CODE_NA -#define CODE_RIGHT CODE_NA - -#define CODE_SELECT CODE_NA -#define CODE_START CODE_NA - -#define CODE_A CODE_NA -#define CODE_B CODE_NA -#define CODE_X CODE_NA -#define CODE_Y CODE_NA - -#define CODE_L1 CODE_NA -#define CODE_R1 CODE_NA -#define CODE_L2 CODE_NA -#define CODE_R2 CODE_NA -#define CODE_L3 CODE_NA -#define CODE_R3 CODE_NA - -#define CODE_MENU CODE_NA -#define CODE_POWER 102 - -#define CODE_PLUS CODE_NA -#define CODE_MINUS CODE_NA - -/////////////////////////////// - -// TODO: unused -#define JOY_UP 13 -#define JOY_DOWN 16 -#define JOY_LEFT 14 -#define JOY_RIGHT 15 - -#define JOY_SELECT 6 -#define JOY_START 7 - -#define JOY_A 0 -#define JOY_B 1 -#define JOY_X 3 -#define JOY_Y 2 - -#define JOY_L1 4 -#define JOY_R1 5 -#define JOY_L2 9 -#define JOY_R2 10 -#define JOY_L3 JOY_NA -#define JOY_R3 JOY_NA - -#define JOY_MENU 8 -#define JOY_POWER JOY_NA -#define JOY_PLUS 18 -#define JOY_MINUS 17 - -/////////////////////////////// - -#define BTN_RESUME BTN_X -#define BTN_SLEEP BTN_POWER -#define BTN_WAKE BTN_POWER -#define BTN_MOD_VOLUME BTN_NONE -#define BTN_MOD_BRIGHTNESS BTN_MENU -#define BTN_MOD_PLUS BTN_PLUS -#define BTN_MOD_MINUS BTN_MINUS - -/////////////////////////////// - -#define FIXED_SCALE 2 -#define FIXED_WIDTH 640 -#define FIXED_HEIGHT 480 -#define FIXED_BPP 2 -#define FIXED_DEPTH (FIXED_BPP * 8) -#define FIXED_PITCH (FIXED_WIDTH * FIXED_BPP) -#define FIXED_SIZE (FIXED_PITCH * FIXED_HEIGHT) - -/////////////////////////////// - -#define SDCARD_PATH "/mnt/SDCARD" -#define MUTE_VOLUME_RAW 0 -#define HAS_NEON - -// this should be set to the devices native screen refresh rate -#define SCREEN_FPS 60.0 -/////////////////////////////// - -#endif diff --git a/workspace/_unmaintained/my282/show/makefile b/workspace/_unmaintained/my282/show/makefile deleted file mode 100755 index b61deed63..000000000 --- a/workspace/_unmaintained/my282/show/makefile +++ /dev/null @@ -1,14 +0,0 @@ -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif - -TARGET = show -PRODUCT = $(TARGET).elf - -CC = $(CROSS_COMPILE)gcc -FLAGS = -Os -lSDL2 -lSDL2_image -lrt -ldl -Wl,--gc-sections -s - -all: - $(CC) $(TARGET).c -o $(PRODUCT) $(FLAGS) -clean: - rm -rf $(PRODUCT) \ No newline at end of file diff --git a/workspace/_unmaintained/my282/show/show.c b/workspace/_unmaintained/my282/show/show.c deleted file mode 100644 index 63304c9da..000000000 --- a/workspace/_unmaintained/my282/show/show.c +++ /dev/null @@ -1,63 +0,0 @@ -// my282 -#include -#include -#include -#include - -#define FIXED_WIDTH 640 -#define FIXED_HEIGHT 480 -#define FIXED_BPP 2 -#define FIXED_DEPTH (FIXED_BPP * 8) -#define FIXED_PITCH (FIXED_WIDTH * FIXED_BPP) - -#define RGBA_MASK_565 0xF800, 0x07E0, 0x001F, 0x0000 - -int main(int argc , char* argv[]) { - if (argc<2) { - puts("Usage: show.elf image.png delay"); - return 0; - } - - char path[256]; - strncpy(path,argv[1],256); - if (access(path, F_OK)!=0) return 0; // nothing to show :( - - int delay = argc>2 ? atoi(argv[2]) : 2; - - SDL_Init(SDL_INIT_VIDEO); - SDL_ShowCursor(0); - - int w = FIXED_WIDTH; - int h = FIXED_HEIGHT; - int p = FIXED_PITCH; - SDL_Window* window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w,h, SDL_WINDOW_SHOWN); - - int rotate = 0; - SDL_DisplayMode mode; - SDL_GetCurrentDisplayMode(0, &mode); - if (mode.h>mode.w) rotate = 3; - - SDL_Renderer* renderer = SDL_CreateRenderer(window,-1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC); - SDL_Texture* texture = SDL_CreateTexture(renderer,SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, w,h); - SDL_Surface* screen = SDL_CreateRGBSurfaceFrom(NULL, w,h, FIXED_DEPTH, p, RGBA_MASK_565); - - SDL_LockTexture(texture,NULL,&screen->pixels,&screen->pitch); - SDL_FillRect(screen, NULL, 0); - SDL_Surface* img = IMG_Load(path); - SDL_BlitSurface(img, NULL, screen, &(SDL_Rect){(screen->w-img->w)/2,(screen->h-img->h)/2}); - SDL_FreeSurface(img); - SDL_UnlockTexture(texture); - - if (rotate) SDL_RenderCopyEx(renderer,texture,NULL,&(SDL_Rect){0,w,w,h},rotate*90,&(SDL_Point){0,0},SDL_FLIP_NONE); - else SDL_RenderCopy(renderer, texture, NULL,NULL); - SDL_RenderPresent(renderer); - - sleep(delay); - - SDL_FreeSurface(screen); - SDL_DestroyTexture(texture); - SDL_DestroyRenderer(renderer); - SDL_DestroyWindow(window); - SDL_Quit(); - return 0; -} diff --git a/workspace/_unmaintained/my282/tests/brightness/brightness.c b/workspace/_unmaintained/my282/tests/brightness/brightness.c deleted file mode 100644 index 3d71749a1..000000000 --- a/workspace/_unmaintained/my282/tests/brightness/brightness.c +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include -#include -#include -#include - -// stock = 20,50,70,140,200 -// my panel gets really gnarly below 20 - -#define DISP_LCD_SET_BRIGHTNESS 0x102 -#define DISP_LCD_GET_BRIGHTNESS 0x103 - -int main (int argc, char *argv[]) { - int fd = open("/dev/disp", O_RDWR); - if (fd) { - int val = argc>1?atoi(argv[1]):-1; - unsigned long param[4]={0,0,0,0}; - int bl = ioctl(fd, DISP_LCD_GET_BRIGHTNESS, ¶m); - printf("%i\n", bl); fflush(stdout); - if (val>=0) { - param[1] = val; - ioctl(fd, DISP_LCD_SET_BRIGHTNESS, ¶m); - } - close(fd); - } - return 0; -} diff --git a/workspace/_unmaintained/my282/tests/brightness/makefile b/workspace/_unmaintained/my282/tests/brightness/makefile deleted file mode 100755 index ba553d3d7..000000000 --- a/workspace/_unmaintained/my282/tests/brightness/makefile +++ /dev/null @@ -1,16 +0,0 @@ -#keymon - -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif - -TARGET = brightness - -CC = $(CROSS_COMPILE)gcc -CFLAGS = -Os -lrt -ldl -Wl,--gc-sections -s -CFLAGS += -I. - -all: - $(CC) $(TARGET).c -o $(TARGET).elf $(CFLAGS) -clean: - rm -rf $(TARGET).elf \ No newline at end of file diff --git a/workspace/_unmaintained/my282/tests/calibrate/calibrate.c b/workspace/_unmaintained/my282/tests/calibrate/calibrate.c deleted file mode 100644 index fb260a73f..000000000 --- a/workspace/_unmaintained/my282/tests/calibrate/calibrate.c +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include -#include -#include -#include - -#include "defines.h" -#include "api.h" -#include "utils.h" - -#define STICK_SIZE 320 - -int main(int argc , char* argv[]) { - PWR_setCPUSpeed(CPU_SPEED_MENU); - - SDL_Surface* screen = GFX_init(MODE_MAIN); - PAD_init(); - - SDL_Event event; - int quit = 0; - while(!quit) { - uint32_t frame_start = SDL_GetTicks(); - - PAD_poll(); - if (PAD_justPressed(BTN_A)) quit = 1; - if (PAD_justPressed(BTN_B)) GFX_clear(screen); - - float rx = (float)pad.laxis.x / 32768; - float ry = (float)pad.laxis.y / 32768; - - SDL_FillRect(screen, &(SDL_Rect){(FIXED_WIDTH/2)+(STICK_SIZE*rx)/2-2,(FIXED_HEIGHT/2)+(STICK_SIZE*ry)/2-2,4,4}, 0xffff); - SDL_FillRect(screen, &(SDL_Rect){0,0,FIXED_WIDTH,80}, 0); - - char text[256]; - sprintf(text, "%0.02f, %0.02f", rx,ry); - SDL_Surface* txt = TTF_RenderUTF8_Blended(font.large, text, COLOR_WHITE); - SDL_BlitSurface(txt, NULL, screen, &(SDL_Rect){8,8}); - SDL_FreeSurface(txt); - - GFX_flip(screen); - } - - PAD_quit(); - GFX_quit(); - return 0; -} diff --git a/workspace/_unmaintained/my282/tests/calibrate/makefile b/workspace/_unmaintained/my282/tests/calibrate/makefile deleted file mode 100755 index d30a9364a..000000000 --- a/workspace/_unmaintained/my282/tests/calibrate/makefile +++ /dev/null @@ -1,40 +0,0 @@ -########################################################### - -ifeq (,$(PLATFORM)) -PLATFORM=$(UNION_PLATFORM) -endif - -ifeq (,$(PLATFORM)) - $(error please specify PLATFORM, eg. PLATFORM=trimui make) -endif - -ifeq (,$(CROSS_COMPILE)) - $(error missing CROSS_COMPILE for this toolchain) -endif - -########################################################### - -include ../../$(PLATFORM)/platform/makefile.env -SDL?=SDL - -########################################################### - -TARGET = calibrate -INCDIR = -I. -I../../all/common/ -I../platform/ -SOURCE = $(TARGET).c ../../all/common/utils.c ../../all/common/api.c ../../all/common/scaler.c ../platform/platform.c - -CC = $(CROSS_COMPILE)gcc -CFLAGS = $(ARCH) -fomit-frame-pointer -CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" -DUSE_$(SDL) -Ofast -LDFLAGS = -ldl $(LIBS) -l$(SDL) -l$(SDL)_image -l$(SDL)_ttf -lpthread -lm -lz -LDFLAGS += -lmsettings - -PRODUCT= $(TARGET).elf - -all: $(PREFIX)/include/msettings.h - $(CC) $(SOURCE) -o $(PRODUCT) $(CFLAGS) $(LDFLAGS) -clean: - rm -f $(PRODUCT) - -$(PREFIX)/include/msettings.h: - cd /root/workspace/$(PLATFORM)/libmsettings && make \ No newline at end of file diff --git a/workspace/_unmaintained/my282/tests/volume/makefile b/workspace/_unmaintained/my282/tests/volume/makefile deleted file mode 100755 index a13eabfb6..000000000 --- a/workspace/_unmaintained/my282/tests/volume/makefile +++ /dev/null @@ -1,16 +0,0 @@ -#keymon - -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif - -TARGET = volume - -CC = $(CROSS_COMPILE)gcc -CFLAGS = -Os -lrt -ldl -Wl,--gc-sections -s -CFLAGS += -I. - -all: - $(CC) $(TARGET).c -o $(TARGET).elf $(CFLAGS) -clean: - rm -rf $(TARGET).elf \ No newline at end of file diff --git a/workspace/_unmaintained/my282/tests/volume/volume.c b/workspace/_unmaintained/my282/tests/volume/volume.c deleted file mode 100644 index b711ecd7f..000000000 --- a/workspace/_unmaintained/my282/tests/volume/volume.c +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include -#include -#include -#include -#include - -int main(int argc, char* argv[]) -{ - int fd = -1; - uint8_t *mem = NULL; - volatile uint32_t *p = NULL; - - fd = open("/dev/mem", O_RDWR); - mem = mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0x1c22000); - - int val = argc>1?atoi(argv[1]):-1; - uint32_t l = val; - uint32_t r = val; - - p = (uint32_t *)(&mem[0xc00 + 0x258]); - printf("%d\n", (*p & 0xff)); fflush(stdout); - if (val>-1) *p = (l << 8) | r; - - munmap(mem, 4096); - close(fd); - return 0; -} \ No newline at end of file diff --git a/workspace/_unmaintained/my355/cores/makefile b/workspace/_unmaintained/my355/cores/makefile deleted file mode 100644 index 2ba8dde3c..000000000 --- a/workspace/_unmaintained/my355/cores/makefile +++ /dev/null @@ -1,40 +0,0 @@ -CORES = fceumm gambatte gpsp pcsx_rearmed picodrive snes9x2005_plus -CORES+= mednafen_pce_fast mednafen_vb fake-08 mednafen_supafaust mgba pokemini race - -############################### - -# optional core vars -# *_REPO= -# *_HASH= -# *_CORE= -# *_FLAGS= -# *_MAKEFILE= -# *_BUILD_PATH= - -mednafen_pce_fast_REPO = https://github.com/libretro/beetle-pce-fast-libretro -mednafen_vb_REPO = https://github.com/libretro/beetle-vb-libretro - -fake-08_REPO = https://github.com/jtothebell/fake-08 -fake-08_CORE = fake08_libretro.so -fake-08_BUILD_PATH = fake-08/platform/libretro - -fceumm_REPO = https://github.com/libretro/libretro-fceumm - -gambatte_REPO = https://github.com/libretro/gambatte-libretro - -mednafen_supafaust_REPO = https://github.com/libretro/supafaust - -pcsx_rearmed_MAKEFILE = Makefile.libretro - -picodrive_REPO = https://github.com/irixxxx/picodrive -picodrive_MAKEFILE = Makefile.libretro - -pokemini_REPO = https://github.com/libretro/PokeMini -pokemini_MAKEFILE = Makefile.libretro - -snes9x2005_plus_REPO = https://github.com/libretro/snes9x2005 -snes9x2005_plus_FLAGS = USE_BLARGG_APU=1 - -############################### - -include ../../all/cores/makefile diff --git a/workspace/_unmaintained/my355/cores/patches/fake-08.patch b/workspace/_unmaintained/my355/cores/patches/fake-08.patch deleted file mode 100644 index 47e445203..000000000 --- a/workspace/_unmaintained/my355/cores/patches/fake-08.patch +++ /dev/null @@ -1,34 +0,0 @@ -diff --git forkSrcPrefix/platform/libretro/libretro.cpp forkDstPrefix/platform/libretro/libretro.cpp -index d95ccb6cab52abfe7620ff84dd5cbb450bafe750..24687335ad410096aa48f29e13dcb479171a06fc 100644 ---- forkSrcPrefix/platform/libretro/libretro.cpp -+++ forkDstPrefix/platform/libretro/libretro.cpp -@@ -636,6 +636,7 @@ EXPORT bool retro_load_game(struct retro_game_info const *info) - else { - _vm->QueueCartChange(info->path); - } -+ _vm->UpdateAndDraw(); - - return true; - } -diff --git forkSrcPrefix/platform/libretro/Makefile forkDstPrefix/platform/libretro/Makefile -index be0f1b46bb3ab10be4a9f896f5e8841dd630b35b..f6b4d892627ec2a81b01ddb4da7f0c7a8022221f 100644 ---- forkSrcPrefix/platform/libretro/Makefile -+++ forkDstPrefix/platform/libretro/Makefile -@@ -123,7 +123,16 @@ else ifeq ($(platform), miyoomini) - CXXFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7ve -D_NEED_FULL_PATH_ - fpic := -fPIC - SHARED := -shared -Wl,--version-script=link.T -- -+# MIYOO FLIP -+else ifeq ($(platform), my355) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ STRIP = $(CROSS_COMPILE)strip -+ CXXFLAGS += -mcpu=cortex-a55 -mtune=cortex-a55 -march=armv8.2-a -+ fpic := -fPIC -+ SHARED := -shared -Wl,--version-script=link.T - else ifeq ($(platform), gcw0) - TARGET := $(TARGET_NAME)_libretro_gcw0.so - CC = /opt/gcw0-toolchain/usr/bin/mipsel-linux-gcc diff --git a/workspace/_unmaintained/my355/cores/patches/fceumm.patch b/workspace/_unmaintained/my355/cores/patches/fceumm.patch deleted file mode 100644 index 85d3833e8..000000000 --- a/workspace/_unmaintained/my355/cores/patches/fceumm.patch +++ /dev/null @@ -1,28 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index 036c41f48b087c99b2276b2d41a71d661fd85145..891eb96ceeb1da868d6d2ed40392b51b65dcbb20 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -461,6 +461,23 @@ else ifeq ($(platform), miyoo) - PLATFORM_DEFINES += -fomit-frame-pointer -ffast-math -mcpu=arm926ej-s - EXTERNAL_ZLIB = 1 - -+# MIYOO FLIP -+else ifeq ($(platform), my355) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=src/drivers/libretro/link.T -Wl,-no-undefined -+ LDFLAGS += -fPIC -flto -+ CFLAGS += -mcpu=cortex-a55 -mtune=cortex-a55 -march=armv8.2-a -+ CFLAGS += -fomit-frame-pointer -ffast-math -fPIC -flto -+ OPTIMIZE := -Ofast -DNDEBUG -+ EXTERNAL_ZLIB = 1 -+ HAVE_NTSC = 0 -+ ifeq (,$(DEBUG)) -+ # LDFLAGS += -s -+ endif -+ - # Windows MSVC 2017 all architectures - else ifneq (,$(findstring windows_msvc2017,$(platform))) - CC = cl.exe diff --git a/workspace/_unmaintained/my355/cores/patches/gambatte.patch b/workspace/_unmaintained/my355/cores/patches/gambatte.patch deleted file mode 100644 index d288384b7..000000000 --- a/workspace/_unmaintained/my355/cores/patches/gambatte.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index ffaba21e7a88f90786d818ab550b68acd05738bf..2095b2f843eaf6be9abec24ce3da69b551da86a6 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -381,6 +381,19 @@ else ifeq ($(platform), gcw0) - CFLAGS += -fomit-frame-pointer -ffast-math -march=mips32 -mtune=mips32r2 -mhard-float - CXXFLAGS += $(CFLAGS) - -+# MIYOO FLIP -+else ifeq ($(platform), my355) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=$(version_script) -+ LDFLAGS += -fPIC -flto -+ PLATFORM_DEFINES := -DCC_RESAMPLER -DCC_RESAMPLER_NO_HIGHPASS -+ CFLAGS += -mcpu=cortex-a55 -mtune=cortex-a55 -march=armv8.2-a -+ CFLAGS += -fomit-frame-pointer -ffast-math -fPIC -flto -+ CXXFLAGS += $(CFLAGS) -+ - # RETROFW - else ifeq ($(platform), retrofw) - TARGET := $(TARGET_NAME)_libretro.so diff --git a/workspace/_unmaintained/my355/cores/patches/gpsp.patch b/workspace/_unmaintained/my355/cores/patches/gpsp.patch deleted file mode 100644 index f267703db..000000000 --- a/workspace/_unmaintained/my355/cores/patches/gpsp.patch +++ /dev/null @@ -1,26 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index dc4b60dec7f70a153dbc2eb849cd5acfc90f9d4d..94c7f8dd037284153b6858730a10b6aaaafd5ad4 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -524,6 +524,21 @@ else ifeq ($(platform), miyoomini) - ARCH = arm - BUILTIN_GPU = neon - -+# MIYOO FLIP -+else ifeq ($(platform), my355) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=link.T -+ fpic := -fPIC -DPIC -+ CFLAGS += -fomit-frame-pointer -ffast-math -+ CFLAGS += -mcpu=cortex-a55 -mtune=cortex-a55 -march=armv8.2-a -+ ARCH = arm64 -+ CPU_ARCH := arm64 -+ MMAP_JIT_CACHE = 1 -+ HAVE_DYNAREC = 1 -+ - # Windows - else - TARGET := $(TARGET_NAME)_libretro.dll diff --git a/workspace/_unmaintained/my355/cores/patches/mednafen_pce_fast.patch b/workspace/_unmaintained/my355/cores/patches/mednafen_pce_fast.patch deleted file mode 100644 index d23f6c8bf..000000000 --- a/workspace/_unmaintained/my355/cores/patches/mednafen_pce_fast.patch +++ /dev/null @@ -1,25 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index 5b54403d915e46cb0df8f428355665fbe26e05b4..f72733d9689aa78795ce8b9d777b0ab9fcc5b65e 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -380,6 +380,20 @@ else ifeq ($(platform), miyoo) - CXXFLAGS += -std=c++11 - CFLAGS += -std=gnu11 - -+# MIYOO FLIP -+else ifeq ($(platform), my355) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ fpic := -fPIC -+ SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T -+ LDFLAGS += -lrt -+ FLAGS += -mcpu=cortex-a55 -mtune=cortex-a55 -march=armv8.2-a -+ FLAGS += -fomit-frame-pointer -ffast-math -D_GNU_SOURCE -+ CXXFLAGS += -std=c++11 -+ CFLAGS += -std=gnu11 -+ - # Windows MSVC 2017 all architectures - else ifneq (,$(findstring windows_msvc2017,$(platform))) - diff --git a/workspace/_unmaintained/my355/cores/patches/mednafen_supafaust.patch b/workspace/_unmaintained/my355/cores/patches/mednafen_supafaust.patch deleted file mode 100644 index ddec7a7ba..000000000 --- a/workspace/_unmaintained/my355/cores/patches/mednafen_supafaust.patch +++ /dev/null @@ -1,34 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index f34a01587cda48cc28ebdfd7f00151b06ea88c42..6966d3c4802b200dea33bdbe8e96b2082a36d577 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -88,6 +88,29 @@ else ifeq ($(platform), classic_armv8_a35) - ARCH = arm - CFLAGS += -march=armv8-a - LDFLAGS += -static-libgcc -static-libstdc++ -+ -+# MIYOO FLIP -+else ifeq ($(platform), my355) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ STRIP = $(CROSS_COMPILE)strip -+ NEED_BPP := 16 -+ fpic := -fPIC -+ SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T -+ CFLAGS += -mcpu=cortex-a55 -mtune=cortex-a55 -march=armv8.2-a -+ CFLAGS += -Ofast \ -+ -flto=4 -fwhole-program -fuse-linker-plugin \ -+ -fdata-sections -ffunction-sections -Wl,--gc-sections \ -+ -fno-stack-protector -fno-ident -fomit-frame-pointer \ -+ -falign-functions=1 -falign-jumps=1 -falign-loops=1 \ -+ -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-unroll-loops \ -+ -fmerge-all-constants -fno-math-errno -+ CXXFLAGS += $(CFLAGS) -+ HAVE_NEON = 1 -+ ARCH = arm64 -+ - ####################################### - - else ifeq ($(platform), osx) diff --git a/workspace/_unmaintained/my355/cores/patches/mednafen_vb.patch b/workspace/_unmaintained/my355/cores/patches/mednafen_vb.patch deleted file mode 100644 index 6855681e2..000000000 --- a/workspace/_unmaintained/my355/cores/patches/mednafen_vb.patch +++ /dev/null @@ -1,29 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index c3d5d3b30d71a8f9ed332482fa2af1c21b02605d..5e710154e499ddd7b1ae699122c38753b0f4bb4c 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -217,6 +217,24 @@ else ifneq (,$(filter $(platform), ps3 psl1ght)) - endif - FLAGS += -D__PS3__ - -+# MIYOO FLIP -+else ifeq ($(platform), my355) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ NEED_BPP := 16 -+ fpic := -fPIC -+ SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T -+ LDFLAGS += -lrt -+ CFLAGS += -fomit-frame-pointer -ffast-math -fPIC -flto -+ CFLAGS += -mcpu=cortex-a55 -mtune=cortex-a55 -march=armv8.2-a -+ CPPFLAGS += $(CFLAGS) -+ LDFLAGS += -flto -+ ifeq (,$(DEBUG)) -+ LDFLAGS += -s -+ endif -+ - # PSP - else ifeq ($(platform), psp1) - TARGET := $(TARGET_NAME)_libretro_$(platform).a diff --git a/workspace/_unmaintained/my355/cores/patches/mgba.patch b/workspace/_unmaintained/my355/cores/patches/mgba.patch deleted file mode 100644 index 1e6363a0a..000000000 --- a/workspace/_unmaintained/my355/cores/patches/mgba.patch +++ /dev/null @@ -1,31 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index 108148f4579f4727146e5b8c1e05ef7382654208..35e6399147a4ef75947ecb2ad4a94f0820ef24d0 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -417,6 +417,26 @@ else ifeq ($(platform), miyoo) - CFLAGS += -fno-common -ftree-vectorize -funswitch-loops - DEFINES += -std=c99 - -+# MIYOO FLIP -+else ifeq ($(platform), my355) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=link.T -+ fpic := -fPIC -+ PLATFORM_DEFINES += -D_GNU_SOURCE -DHAVE_STRTOF_L -DHAVE_LOCALE -+ CFLAGS += -fomit-frame-pointer -ffast-math -+ CFLAGS += -mcpu=cortex-a55 -mtune=cortex-a55 -march=armv8.2-a -+ CFLAGS += -fno-common -ftree-vectorize -funswitch-loops -+ HAVE_NEON = 1 -+ ARCH = arm64 -+ BUILTIN_GPU = neon -+ CPU_ARCH := arm -+ MMAP_JIT_CACHE = 1 -+ HAVE_DYNAREC = 1 -+ DEFINES += -std=c99 -+ - # Windows - else - TARGET := $(TARGET_NAME)_libretro.dll diff --git a/workspace/_unmaintained/my355/cores/patches/pcsx_rearmed.patch b/workspace/_unmaintained/my355/cores/patches/pcsx_rearmed.patch deleted file mode 100644 index 4b51adc0f..000000000 --- a/workspace/_unmaintained/my355/cores/patches/pcsx_rearmed.patch +++ /dev/null @@ -1,30 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index 7b9618e1ccfc63982be50b82fda498d75e307fdc..f314adcbea17f05f473e1cbafc8711ab8ea0c5f1 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -391,6 +391,25 @@ else ifeq ($(platform), rpi4_64) - fpic := -fPIC - CFLAGS += -march=armv8-a+crc+simd -mtune=cortex-a72 -ftree-vectorize - -+# MIYOO FLIP -+else ifeq ($(platform), my355) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ CFLAGS += -mcpu=cortex-a55 -mtune=cortex-a55 -march=armv8.2-a -fomit-frame-pointer -+ CFLAGS += -ffast-math -fdata-sections -ffunction-sections -fsingle-precision-constant -flto -fPIC -+ LDFLAGS += -flto -fPIC -+ ifeq (,$(DEBUG)) -+ # LDFLAGS += -s -+ endif -+ CPU_ARCH := arm64 -+ OPTIMIZE := -Ofast -DNDEBUG=1 -+ HAVE_NEON = 1 -+ BUILTIN_GPU = neon -+ ARCH = arm64 -+ DYNAREC = ari64 -+ - # Classic Platforms #################### - # Platform affix = classic__<µARCH> - # Help at https://modmyclassic.com/comp diff --git a/workspace/_unmaintained/my355/cores/patches/picodrive.patch b/workspace/_unmaintained/my355/cores/patches/picodrive.patch deleted file mode 100644 index cd8262243..000000000 --- a/workspace/_unmaintained/my355/cores/patches/picodrive.patch +++ /dev/null @@ -1,35 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index 0d1dc08f81a11cef6b3b7238367b1ff27fcf1ead..1f87c76c3242023c4095f0c9087c52765d93c33c 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -497,6 +497,30 @@ else ifeq ($(platform), miyoo) - HAVE_ARMv6 = 0 - LOW_MEMORY = 1 - -+# MIYOO FLIP -+else ifeq ($(platform), my355) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--no-undefined -+ DONT_COMPILE_IN_ZLIB = 1 -+ CFLAGS += -Ofast \ -+ -fdata-sections -ffunction-sections -Wl,--gc-sections \ -+ -fno-stack-protector -fno-ident -fomit-frame-pointer \ -+ -falign-functions=1 -falign-jumps=1 -falign-loops=1 \ -+ -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-unroll-loops \ -+ -fmerge-all-constants -fno-math-errno -+ CFLAGS += -fPIC -flto -+ CFLAGS += -fomit-frame-pointer -ffast-math -D__GCW0__ -+ CFLAGS += -mcpu=cortex-a55 -mtune=cortex-a55 -march=armv8.2-a -+ LDFLAGS += -flto -+ HAVE_NEON = 1 -+ BUILTIN_GPU = neon -+ ifeq (,$(DEBUG)) -+ LDFLAGS += -s -+ endif -+ - # Windows MSVC 2017 all architectures - else ifneq (,$(findstring windows_msvc2017,$(platform))) - NO_GCC := 1 diff --git a/workspace/_unmaintained/my355/cores/patches/pokemini.patch b/workspace/_unmaintained/my355/cores/patches/pokemini.patch deleted file mode 100644 index 329a20c89..000000000 --- a/workspace/_unmaintained/my355/cores/patches/pokemini.patch +++ /dev/null @@ -1,27 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index ef2f9e7d1c6041bea8e2c8a61cdd363ed73a7482..ada8785f566af89cc77f5ab2dd9e670b0a998545 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -504,6 +504,22 @@ else ifeq ($(platform), retrofw) - CFLAGS += -ffast-math -fomit-frame-pointer -march=mips32 -mtune=mips32 -mhard-float - CFLAGS += -DDINGUX - -+# MIYOO FLIP -+else ifeq ($(platform), my355) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=libretro/link.T -Wl,--no-undefined -+ fpic := -fPIC -+ CFLAGS += -DARM -+ CFLAGS += $(PTHREAD_FLAGS) -+ CFLAGS += -mcpu=cortex-a55 -mtune=cortex-a55 -march=armv8.2-a -+ CFLAGS += -ffast-math -fomit-frame-pointer -+ CFLAGS += -DDINGUX -+ HAVE_NEON = 1 -+ ARCH = arm64 -+ - else ifeq ($(platform), msvc) - OBJOUT = -Fo - diff --git a/workspace/_unmaintained/my355/cores/patches/race.patch b/workspace/_unmaintained/my355/cores/patches/race.patch deleted file mode 100644 index f2eaedd11..000000000 --- a/workspace/_unmaintained/my355/cores/patches/race.patch +++ /dev/null @@ -1,23 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index 792a6d82915c32edd3df6ceec541499f6ca25ac5..dc02b361d7db47e011b6d3addf89cfb31503575a 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -373,6 +373,18 @@ else ifeq ($(platform), miyoo) - CFLAGS += -fomit-frame-pointer -ffast-math -march=armv5te -mtune=arm926ej-s - CXXFLAGS += $(CFLAGS) - -+# MIYOO FLIP -+else ifeq ($(platform), my355) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ fpic := -fPIC -+ SHARED := -shared -Wl,-version-script=$(LIBRETRO_DIR)/link.T -+ PLATFORM_DEFINES := -DCC_RESAMPLER -DCC_RESAMPLER_NO_HIGHPASS -+ CFLAGS += -fomit-frame-pointer -ffast-math -mcpu=cortex-a55 -mtune=cortex-a55 -march=armv8.2-a -+ CXXFLAGS += $(CFLAGS) -+ - # Windows MSVC 2010 x64 - else ifeq ($(platform), windows_msvc2010_x64) - CC = cl.exe diff --git a/workspace/_unmaintained/my355/cores/patches/snes9x2005_plus.patch b/workspace/_unmaintained/my355/cores/patches/snes9x2005_plus.patch deleted file mode 100644 index c87429f92..000000000 --- a/workspace/_unmaintained/my355/cores/patches/snes9x2005_plus.patch +++ /dev/null @@ -1,36 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index 07d5368a8e78a020813732239ec369d83e931ede..009f13b8e61c634de4cb83e97785a10b83b4322d 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -288,6 +288,31 @@ else ifeq ($(platform), miyoo) - FLAGS += -fomit-frame-pointer -ffast-math -march=armv5te -mtune=arm926ej-s - FLAGS += -DFAST_ALIGNED_LSB_WORD_ACCESS -fno-unroll-loops - -+# MIYOO FLIP -+else ifeq ($(platform), my355) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=link.T -+ LIBM := -+ CFLAGS += -Ofast \ -+ -flto=4 -fwhole-program -fuse-linker-plugin \ -+ -fdata-sections -ffunction-sections -Wl,--gc-sections \ -+ -fno-stack-protector -fno-ident -fomit-frame-pointer \ -+ -falign-functions=1 -falign-jumps=1 -falign-loops=1 \ -+ -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-unroll-loops \ -+ -fmerge-all-constants -fno-math-errno -+ CFLAGS += -fPIC -+ CFLAGS += -DLSB_FIRST -DFAST_ALIGNED_LSB_WORD_ACCESS -DRIGHTSHIFT_IS_SAR -+ CFLAGS += -std=c99 -fomit-frame-pointer -ffast-math -+ CFLAGS += -mcpu=cortex-a55 -mtune=cortex-a55 -march=armv8.2-a -+ LDFLAGS += -flto -+ OPTIMIZE += -Ofast -DNDEBUG=1 -+ ifeq (,$(DEBUG)) -+ LDFLAGS += -s -+ endif -+ - # (armv7 a7, hard point, neon based) ### - # NESC, SNESC, C64 mini - else ifeq ($(platform), classic_armv7_a7) diff --git a/workspace/_unmaintained/my355/init/init.sh b/workspace/_unmaintained/my355/init/init.sh deleted file mode 100755 index f90dac850..000000000 --- a/workspace/_unmaintained/my355/init/init.sh +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/sh -# will be copied to /miyoo355/app/355/ during build - -set -x - -if [ -f /usr/miyoo/bin/runmiyoo-original.sh ]; then - echo "already installed" - exit 0 -fi - -DIR="$(cd "$(dirname "$0")" && pwd)" - -export PATH=/tmp/bin:$DIR/payload/bin:$PATH -export LD_LIBRARY_PATH=/tmp/lib:$DIR/payload/lib:$LD_LIBRARY_PATH - -LAST_CALL_TIME=0 -hide() { - # killall show.elf || true - touch /tmp/fbdisplay_exit -} -show() { - CURRENT_TIME=$(date +%s) - if [ $((CURRENT_TIME - LAST_CALL_TIME)) -lt 2 ]; then - DELAY=$((2 - (CURRENT_TIME - LAST_CALL_TIME))) - echo "delay for $DELAY seconds" - sleep $DELAY - fi - - hide - # show.elf $DIR/res/$1 300 & - /usr/bin/fbdisplay $DIR/res/$1 & - LAST_CALL_TIME=$(date +%s) -} - -show "prep-env.png" -echo "preparing environment" -cd "$DIR" -cp -r payload/* /tmp -cd /tmp - -show "extract-root.png" -echo "extracting rootfs" -dd if=/dev/mtd3ro of=old_rootfs.squashfs bs=131072 - -show "unpack-root.png" -echo "unpacking rootfs" -unsquashfs old_rootfs.squashfs - -show "inject-hook.png" -echo "swapping runmiyoo.sh" -mv squashfs-root/usr/miyoo/bin/runmiyoo.sh squashfs-root/usr/miyoo/bin/runmiyoo-original.sh -mv runmiyoo.sh squashfs-root/usr/miyoo/bin/ - -show "pack-root.png" -echo "packing updated rootfs" -mksquashfs squashfs-root new_rootfs.squashfs -comp gzip -b 131072 -noappend -exports -all-root -force-uid 0 -force-gid 0 - -# mount so reboot remains available -mkdir -p /tmp/rootfs -mount /tmp/new_rootfs.squashfs /tmp/rootfs -export PATH=/tmp/rootfs/bin:/tmp/rootfs/usr/bin:/tmp/rootfs/sbin:$PATH -export LD_LIBRARY_PATH=/tmp/rootfs/lib:/tmp/rootfs/usr/lib:$LD_LIBRARY_PATH - -show "flash-root.png" -echo "flashing updated rootfs" -flashcp new_rootfs.squashfs /dev/mtd3 && sync - -show "reboot.png" -echo "done, rebooting" -sleep 2 -reboot -while :; do - sleep 1 -done -exit diff --git a/workspace/_unmaintained/my355/init/payload/runmiyoo.sh b/workspace/_unmaintained/my355/init/payload/runmiyoo.sh deleted file mode 100755 index e14170bad..000000000 --- a/workspace/_unmaintained/my355/init/payload/runmiyoo.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh - -# becomes /usr/miyoo/bin/runmiyoo.sh on my355 - -#wait for sdcard mounted -mounted=`cat /proc/mounts | grep SDCARD` -cnt=0 -while [ "$mounted" == "" ] && [ $cnt -lt 6 ] ; do - sleep 0.5 - cnt=`expr $cnt + 1` - mounted=`cat /proc/mounts | grep SDCARD` -done - -UPDATER_PATH=/mnt/SDCARD/.tmp_update/updater -if [ -f "$UPDATER_PATH" ]; then - "$UPDATER_PATH" -else - /usr/miyoo/bin/runmiyoo-original.sh -fi diff --git a/workspace/_unmaintained/my355/init/res/extract-root.png b/workspace/_unmaintained/my355/init/res/extract-root.png deleted file mode 100644 index c42410bfc12712539bb06e1e6a501eab6f756c99..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3690 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 B_KE-i diff --git a/workspace/_unmaintained/my355/init/res/flash-root.png b/workspace/_unmaintained/my355/init/res/flash-root.png deleted file mode 100644 index 4747ad0f787a1c0b0d7d32f84f557ea5273f795d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3424 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 diff --git a/workspace/_unmaintained/my355/init/res/pack-root.png b/workspace/_unmaintained/my355/init/res/pack-root.png deleted file mode 100644 index 6c587775a550752e8a07f97db25c9cc789ed0941..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3590 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 diff --git a/workspace/_unmaintained/my355/init/res/unpack-root.png b/workspace/_unmaintained/my355/init/res/unpack-root.png deleted file mode 100644 index 0b563d576817336d54c938fb0279d7e0fc282ad4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3846 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 /dev/fb0 - -PLATFORM="my355" -SDCARD_PATH="/mnt/SDCARD" -UPDATE_PATH="$SDCARD_PATH/NextUI.zip" -SYSTEM_PATH="$SDCARD_PATH/.system" - -CPU_PATH=/sys/devices/system/cpu/cpufreq/policy0/scaling_governor -echo performance > "$CPU_PATH" - -# install/update -if [ -f "$UPDATE_PATH" ]; then - cd $(dirname "$0")/$PLATFORM - - if [ -d "$SYSTEM_PATH" ]; then - ./show.elf ./updating.png - else - ./show.elf ./installing.png - fi - - mv $SDCARD_PATH/.tmp_update $SDCARD_PATH/.tmp_update-old - unzip -o "$UPDATE_PATH" -d "$SDCARD_PATH" - rm -f "$UPDATE_PATH" - rm -rf $SDCARD_PATH/.tmp_update-old - - # the updated system finishes the install/update - $SYSTEM_PATH/$PLATFORM/bin/install.sh -fi - -# or launch (and keep launched) -LAUNCH_PATH="$SYSTEM_PATH/$PLATFORM/paks/NextUI.pak/launch.sh" -while [ -f "$LAUNCH_PATH" ] ; do - "$LAUNCH_PATH" -done - -poweroff # under no circumstances should stock be allowed to touch this card \ No newline at end of file diff --git a/workspace/_unmaintained/my355/install/installing.png b/workspace/_unmaintained/my355/install/installing.png deleted file mode 100644 index acde62551b3bffd9c192883ec06bb5ba0d6efc76..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3647 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 B=!^gW diff --git a/workspace/_unmaintained/my355/keymon/credits.txt b/workspace/_unmaintained/my355/keymon/credits.txt deleted file mode 100644 index e885e5dd1..000000000 --- a/workspace/_unmaintained/my355/keymon/credits.txt +++ /dev/null @@ -1,3 +0,0 @@ -based on eggs custom keymon for Trimui: - https://www.dropbox.com/sh/5e9xwvp672vt8cr/AABUIdw1vLYp9h0waoCUqHPOa/source?dl=0&subfolder_nav_tracking=1 -modified to use libmsettings \ No newline at end of file diff --git a/workspace/_unmaintained/my355/keymon/keymon.c b/workspace/_unmaintained/my355/keymon/keymon.c deleted file mode 100644 index affb4951d..000000000 --- a/workspace/_unmaintained/my355/keymon/keymon.c +++ /dev/null @@ -1,207 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -// #include "defines.h" - -#define VOLUME_MIN 0 -#define VOLUME_MAX 20 -#define BRIGHTNESS_MIN 0 -#define BRIGHTNESS_MAX 10 - -// uses different codes from SDL -#define CODE_MENU 1 -#define CODE_PLUS 115 -#define CODE_MINUS 114 - -// for ev.value -#define RELEASED 0 -#define PRESSED 1 -#define REPEAT 2 - -int getInt(char* path) { - int i = 0; - FILE *file = fopen(path, "r"); - if (file!=NULL) { - fscanf(file, "%i", &i); - fclose(file); - } - return i; -} -void getFile(char* path, char* buffer, size_t buffer_size) { - FILE *file = fopen(path, "r"); - if (file) { - fseek(file, 0L, SEEK_END); - size_t size = ftell(file); - if (size>buffer_size-1) size = buffer_size - 1; - rewind(file); - fread(buffer, sizeof(char), size, file); - fclose(file); - buffer[size] = '\0'; - } -} -int exactMatch(char* str1, char* str2) { - int len1 = strlen(str1); - if (len1!=strlen(str2)) return 0; - return (strncmp(str1,str2,len1)==0); -} - -static int input_fd = 0; -static struct input_event ev; - -static pthread_t ports_pt; -#define JACK_STATE_PATH "/sys/class/gpio/gpio150/value" -#define HDMI_STATE_PATH "/sys/class/drm/card0-HDMI-A-1/status" - -static int JACK_enabled(void) { - return !getInt(JACK_STATE_PATH); -} -static int HDMI_enabled(void) { - char value[64]; - getFile(HDMI_STATE_PATH, value, 64); - return exactMatch(value, "connected\n"); -} - -static void* watchPorts(void *arg) { - int has_jack,had_jack; - had_jack = had_jack = JACK_enabled(); - SetJack(has_jack); - - int has_hdmi,had_hdmi; - has_hdmi = had_hdmi = HDMI_enabled(); - SetHDMI(has_hdmi); - - while(1) { - sleep(1); - - has_jack = JACK_enabled(); - if (had_jack!=has_jack) { - had_jack = has_jack; - SetJack(has_jack); - } - - has_hdmi = HDMI_enabled(); - if (had_hdmi!=has_hdmi) { - had_hdmi = has_hdmi; - SetHDMI(has_hdmi); - } - } - - return 0; -} - -int main (int argc, char *argv[]) { - InitSettings(); - pthread_create(&ports_pt, NULL, &watchPorts, NULL); - - input_fd = open("/dev/input/event0", O_RDONLY | O_NONBLOCK | O_CLOEXEC); - - uint32_t input; - uint32_t val; - uint32_t menu_pressed = 0; - - uint32_t up_pressed = 0; - uint32_t up_just_pressed = 0; - uint32_t up_repeat_at = 0; - - uint32_t down_pressed = 0; - uint32_t down_just_pressed = 0; - uint32_t down_repeat_at = 0; - - uint8_t ignore; - uint32_t then; - uint32_t now; - struct timeval tod; - - gettimeofday(&tod, NULL); - then = tod.tv_sec * 1000 + tod.tv_usec / 1000; // essential SDL_GetTicks() - ignore = 0; - - while (1) { - gettimeofday(&tod, NULL); - now = tod.tv_sec * 1000 + tod.tv_usec / 1000; - // TODO: check if if necessary - if (now-then>1000) ignore = 1; // ignore input that arrived during sleep - - while(read(input_fd, &ev, sizeof(ev))==sizeof(ev)) { - if (ignore) continue; - val = ev.value; - - if (( ev.type != EV_KEY ) || ( val > REPEAT )) continue; - // printf("code: %i (%i)\n", ev.code, val); fflush(stdout); - switch (ev.code) { - case CODE_MENU: - menu_pressed = val; - break; - break; - case CODE_PLUS: - up_pressed = up_just_pressed = val; - if (val) up_repeat_at = now + 300; - break; - case CODE_MINUS: - down_pressed = down_just_pressed = val; - if (val) down_repeat_at = now + 300; - break; - default: - break; - } - } - - if (ignore) { - menu_pressed = 0; - up_pressed = up_just_pressed = 0; - down_pressed = down_just_pressed = 0; - up_repeat_at = 0; - down_repeat_at = 0; - } - - if (up_just_pressed || (up_pressed && now>=up_repeat_at)) { - if (menu_pressed) { - // printf("brightness up\n"); fflush(stdout); - val = GetBrightness(); - if (val=down_repeat_at)) { - if (menu_pressed) { - // printf("brightness down\n"); fflush(stdout); - val = GetBrightness(); - if (val>BRIGHTNESS_MIN) SetBrightness(--val); - } - else { - // printf("volume down\n"); fflush(stdout); - val = GetVolume(); - if (val>VOLUME_MIN) SetVolume(--val); - } - - if (down_just_pressed) down_just_pressed = 0; - else down_repeat_at += 100; - } - - then = now; - ignore = 0; - - usleep(16666); // 60fps - } -} diff --git a/workspace/_unmaintained/my355/keymon/makefile b/workspace/_unmaintained/my355/keymon/makefile deleted file mode 100755 index 0212b6bbc..000000000 --- a/workspace/_unmaintained/my355/keymon/makefile +++ /dev/null @@ -1,16 +0,0 @@ -#keymon - -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif - -TARGET = keymon - -CC = $(CROSS_COMPILE)gcc -CFLAGS = -Os -lmsettings -lpthread -lrt -ldl -Wl,--gc-sections -s -CFLAGS += -I. -I../../all/common -I../platform/ -DPLATFORM=\"$(UNION_PLATFORM)\" - -all: - $(CC) $(TARGET).c -o $(TARGET).elf $(CFLAGS) -clean: - rm -rf $(TARGET).elf \ No newline at end of file diff --git a/workspace/_unmaintained/my355/libmsettings/makefile b/workspace/_unmaintained/my355/libmsettings/makefile deleted file mode 100644 index b1418a21d..000000000 --- a/workspace/_unmaintained/my355/libmsettings/makefile +++ /dev/null @@ -1,32 +0,0 @@ -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif -ifeq (,$(PREFIX)) -$(error missing PREFIX for this toolchain) -endif - -TARGET=msettings - -.PHONY: build -.PHONY: clean - -CC = $(CROSS_COMPILE)gcc - -SYSROOT := $(shell $(CC) --print-sysroot) - -INCLUDEDIR = $(SYSROOT)/usr/include -CFLAGS = -I$(INCLUDEDIR) -LDFLAGS = -ldl -lrt -s - -OPTM=-Ofast - -build: - $(CC) -c -Werror -fpic "$(TARGET).c" -Wl,--no-as-needed $(LDFLAGS) - $(CC) -shared -o "lib$(TARGET).so" "$(TARGET).o" $(LDFLAGS) - cp "$(TARGET).h" "$(PREFIX)/include" - cp "lib$(TARGET).so" "$(PREFIX)/lib" -clean: - rm -f *.o - rm -f "lib$(TARGET).so" - rm -f $(PREFIX)/include/$(TARGET).h - rm -f $(PREFIX)/lib/lib$(TARGET).so \ No newline at end of file diff --git a/workspace/_unmaintained/my355/libmsettings/msettings.c b/workspace/_unmaintained/my355/libmsettings/msettings.c deleted file mode 100644 index 0ae6d6550..000000000 --- a/workspace/_unmaintained/my355/libmsettings/msettings.c +++ /dev/null @@ -1,258 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "msettings.h" - -/////////////////////////////////////// - -#define SETTINGS_VERSION 2 -typedef struct Settings { - int version; // future proofing - int brightness; - int headphones; - int speaker; - int unused[2]; // for future use - // NOTE: doesn't really need to be persisted but still needs to be shared - int jack; - int hdmi; -} Settings; -static Settings DefaultSettings = { - .version = SETTINGS_VERSION, - .brightness = 2, - .headphones = 4, - .speaker = 8, - .jack = 0, - .hdmi = 0, -}; -static Settings* settings; - -#define SHM_KEY "/SharedSettings" -static char SettingsPath[256]; -static int shm_fd = -1; -static int is_host = 0; -static int shm_size = sizeof(Settings); - -int getInt(char* path) { - int i = 0; - FILE *file = fopen(path, "r"); - if (file!=NULL) { - fscanf(file, "%i", &i); - fclose(file); - } - return i; -} -void getFile(char* path, char* buffer, size_t buffer_size) { - FILE *file = fopen(path, "r"); - if (file) { - fseek(file, 0L, SEEK_END); - size_t size = ftell(file); - if (size>buffer_size-1) size = buffer_size - 1; - rewind(file); - fread(buffer, sizeof(char), size, file); - fclose(file); - buffer[size] = '\0'; - } -} -void putFile(char* path, char* contents) { - FILE* file = fopen(path, "w"); - if (file) { - fputs(contents, file); - fclose(file); - } -} -void putInt(char* path, int value) { - char buffer[8]; - sprintf(buffer, "%d", value); - putFile(path, buffer); -} - -int exactMatch(char* str1, char* str2) { - int len1 = strlen(str1); - if (len1!=strlen(str2)) return 0; - return (strncmp(str1,str2,len1)==0); -} - - -#define JACK_STATE_PATH "/sys/class/gpio/gpio150/value" -#define HDMI_STATE_PATH "/sys/class/drm/card0-HDMI-A-1/status" - -static int JACK_enabled(void) { - return !getInt(JACK_STATE_PATH); -} -static int HDMI_enabled(void) { - char value[64]; - getFile(HDMI_STATE_PATH, value, 64); - return exactMatch(value, "connected\n"); -} - -void InitSettings(void) { - sprintf(SettingsPath, "%s/msettings.bin", getenv("USERDATA_PATH")); - - shm_fd = shm_open(SHM_KEY, O_RDWR | O_CREAT | O_EXCL, 0644); // see if it exists - if (shm_fd==-1 && errno==EEXIST) { // already exists - puts("Settings client"); - shm_fd = shm_open(SHM_KEY, O_RDWR, 0644); - settings = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); - } - else { // host - puts("Settings host"); // should always be keymon - is_host = 1; - // we created it so set initial size and populate - ftruncate(shm_fd, shm_size); - settings = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); - - int fd = open(SettingsPath, O_RDONLY); - if (fd>=0) { - read(fd, settings, shm_size); - // TODO: use settings->version for future proofing? - close(fd); - } - else { - // load defaults - memcpy(settings, &DefaultSettings, shm_size); - } - - // these shouldn't be persisted - // settings->jack = 0; - // settings->hdmi = 0; - } - - int jack = JACK_enabled(); - int hdmi = HDMI_enabled(); - printf("brightness: %i (hdmi: %i)\nspeaker: %i (jack: %i)\n", settings->brightness, hdmi, settings->speaker, jack); fflush(stdout); - - // both of these set volume - SetJack(jack); - SetHDMI(hdmi); - - char cmd[256]; - sprintf(cmd, "amixer sset 'Playback Path' '%s' > /dev/null 2>&1", GetJack() ? "HP" : "SPK"); - system(cmd); - - SetVolume(GetVolume()); - SetBrightness(GetBrightness()); - // system("echo $(< " BRIGHTNESS_PATH ")"); -} -void QuitSettings(void) { - munmap(settings, shm_size); - if (is_host) shm_unlink(SHM_KEY); -} -static inline void SaveSettings(void) { - int fd = open(SettingsPath, O_CREAT|O_WRONLY, 0644); - if (fd>=0) { - write(fd, settings, shm_size); - close(fd); - sync(); - } -} - -int GetBrightness(void) { // 0-10 - return settings->brightness; -} -void SetBrightness(int value) { - if (settings->hdmi) return; - - int raw; - switch (value) { - // TODO :revisit - case 0: raw = 1; break; // - case 1: raw = 6; break; // - case 2: raw = 10; break; // - case 3: raw = 16; break; // - case 4: raw = 32; break; // - case 5: raw = 48; break; // - case 6: raw = 64; break; // - case 7: raw = 96; break; // - case 8: raw = 128; break; // - case 9: raw = 192; break; // - case 10: raw = 255; break; // - } - - SetRawBrightness(raw); - settings->brightness = value; - SaveSettings(); -} - -int GetVolume(void) { // 0-20 - return settings->jack ? settings->headphones : settings->speaker; -} -void SetVolume(int value) { - if (settings->hdmi) return; - - if (settings->jack) settings->headphones = value; - else settings->speaker = value; - - int raw = value * 5; - SetRawVolume(raw); - SaveSettings(); -} - -#define DISP_LCD_SET_BRIGHTNESS 0x102 -void SetRawBrightness(int val) { // 0 - 255 - if (settings->hdmi) return; - - printf("SetRawBrightness(%i)\n", val); fflush(stdout); - putInt("/sys/class/backlight/backlight/brightness", val); -} -void SetRawVolume(int val) { // 0 - 100 - printf("SetRawVolume(%i)\n", val); fflush(stdout); - - system("amixer sset 'SPK' 1% > /dev/null 2>&1"); // ensure there is always a change - if (settings->jack) { - system("amixer sset 'Playback Path' 'HP' > /dev/null 2>&1"); - puts("headphones"); fflush(stdout); - } - else if (val==0) { - system("amixer sset 'Playback Path' 'OFF' > /dev/null 2>&1"); // mute speaker (not headphone as that produces white noise) - puts("mute"); fflush(stdout); - } - else { - system("amixer sset 'Playback Path' 'SPK' > /dev/null 2>&1"); - puts("speaker"); fflush(stdout); - } - - char cmd[256]; - sprintf(cmd, "amixer sset 'SPK' %i%% > /dev/null 2>&1", val); - puts(cmd); fflush(stdout); - system(cmd); -} - -// monitored and set by thread in keymon -int GetJack(void) { - // printf("GetJack() %i\n", settings->jack); fflush(stdout); - return settings->jack; -} -void SetJack(int value) { - // printf("SetJack(%i)\n", value); fflush(stdout); - - // char cmd[256]; - // sprintf(cmd, "amixer cset name='Playback Path' '%s' &> /dev/null", value?"HP":"SPK"); - // system(cmd); - - settings->jack = value; - SetVolume(GetVolume()); -} - -int GetHDMI(void) { - // printf("GetHDMI() %i\n", settings->hdmi); fflush(stdout); - return settings->hdmi; -} -void SetHDMI(int value) { - // printf("SetHDMI(%i)\n", value); fflush(stdout); - - settings->hdmi = value; - if (value) SetRawVolume(100); // max - else SetVolume(GetVolume()); // restore -} - -int GetMute(void) { return 0; } -void SetMute(int value) {} diff --git a/workspace/_unmaintained/my355/libmsettings/msettings.h b/workspace/_unmaintained/my355/libmsettings/msettings.h deleted file mode 100644 index 47e5fb003..000000000 --- a/workspace/_unmaintained/my355/libmsettings/msettings.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef __msettings_h__ -#define __msettings_h__ - -void InitSettings(void); -void QuitSettings(void); - -int GetBrightness(void); -int GetVolume(void); - -void SetRawBrightness(int value); // 0-1024 -void SetRawVolume(int value); // 0-40 - -void SetBrightness(int value); // 0-10 -void SetVolume(int value); // 0-20 - -int GetJack(void); -void SetJack(int value); // 0-1 - -int GetHDMI(void); -void SetHDMI(int value); // 0-1 - -int GetMute(void); -void SetMute(int value); // 0-1 - -#endif // __msettings_h__ diff --git a/workspace/_unmaintained/my355/makefile b/workspace/_unmaintained/my355/makefile deleted file mode 100644 index 5cb6727c3..000000000 --- a/workspace/_unmaintained/my355/makefile +++ /dev/null @@ -1,47 +0,0 @@ -# my355 - -########################################################### - -ifeq (,$(PLATFORM)) -PLATFORM=$(UNION_PLATFORM) -endif - -ifeq (,$(PLATFORM)) -$(error please specify PLATFORM, eg. PLATFORM=trimui make) -endif - -########################################################### - -REQUIRES_EVTEST=other/evtest -REQUIRES_MKBOOTIMG=other/mkbootimg -REQUIRES_RSCEGO=other/rsce-go -REQUIRES_COMMANDER=other/DinguxCommander-sdl2 - -all: readmes - cd show && make - cd other/squashfs && make - -early: $(REQUIRES_EVTEST) $(REQUIRES_MKBOOTIMG) $(REQUIRES_RSCEGO) $(REQUIRES_COMMANDER) - mkdir -p other - cd $(REQUIRES_COMMANDER) && make -j - cd $(REQUIRES_EVTEST) && $(CROSS_COMPILE)gcc -o evtest evtest.c - cd $(REQUIRES_MKBOOTIMG) && make - cd $(REQUIRES_RSCEGO) && go build -o rsce_tool - -clean: - cd show && make clean - cd $(REQUIRES_COMMANDER) && make clean - -########################################################### - -$(REQUIRES_COMMANDER): - git clone --depth 1 https://github.com/shauninman/DinguxCommander-sdl2.git $(REQUIRES_COMMANDER) -$(REQUIRES_EVTEST): - git clone --depth 1 https://github.com/freedesktop-unofficial-mirror/evtest.git $(REQUIRES_EVTEST) -$(REQUIRES_MKBOOTIMG): - git clone --depth 1 https://github.com/osm0sis/mkbootimg $(REQUIRES_MKBOOTIMG) -$(REQUIRES_RSCEGO): - git clone --depth 1 https://github.com/Evsio0n/rsce-go $(REQUIRES_RSCEGO) - cd $(REQUIRES_RSCEGO) && go mod tidy && go mod download - -include ../all/readmes/makefile diff --git a/workspace/_unmaintained/my355/other/squashfs/makefile b/workspace/_unmaintained/my355/other/squashfs/makefile deleted file mode 100644 index 2ade6436e..000000000 --- a/workspace/_unmaintained/my355/other/squashfs/makefile +++ /dev/null @@ -1,18 +0,0 @@ -#my355 - -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif - -all: - mkdir -p output - mkdir -p output/bin - mkdir -p output/lib - cp /usr/bin/*squashfs output/bin/ - cp /usr/lib/aarch64-linux-gnu/liblzma.so.5.4.1 output/lib/liblzma.so.5 - cp /usr/lib/aarch64-linux-gnu/liblzo2.so.2.0.0 output/lib/liblzo2.so.2 - cp /usr/lib/aarch64-linux-gnu/liblz4.so.1.9.4 output/lib/liblz4.so.1 - cp /usr/lib/aarch64-linux-gnu/libzstd.so.1.5.4 output/lib/libzstd.so.1 - -clean: - rm -rf output \ No newline at end of file diff --git a/workspace/_unmaintained/my355/platform/makefile.copy b/workspace/_unmaintained/my355/platform/makefile.copy deleted file mode 100644 index 6a2b71a54..000000000 --- a/workspace/_unmaintained/my355/platform/makefile.copy +++ /dev/null @@ -1,16 +0,0 @@ -$(PLATFORM): - # $@ - cp ./workspace/$@/show/show.elf ./build/SYSTEM/$@/bin - # installer - cp ./workspace/$@/install/update.sh ./build/SYSTEM/$@/bin/install.sh - mkdir -p ./build/BOOT/common/$@/ - cp ./workspace/$@/install/boot.sh ./build/BOOT/common/$@.sh - cp ./workspace/$@/show/show.elf ./build/BOOT/common/$@/ - cp ./workspace/$@/install/*.png ./build/BOOT/common/$@/ - # extras - cp ./workspace/$@/other/DinguxCommander-sdl2/DinguxCommander ./build/EXTRAS/Tools/$@/Files.pak/ - cp -r ./workspace/$@/other/DinguxCommander-sdl2/res ./build/EXTRAS/Tools/$@/Files.pak/ - mkdir -p ./build/EXTRAS/Tools/$@/Bootlogo.pak/payload/bin/ - cp ./workspace/$@/other/mkbootimg/mkbootimg ./build/EXTRAS/Tools/$@/Bootlogo.pak/payload/bin/ - cp ./workspace/$@/other/mkbootimg/unpackbootimg ./build/EXTRAS/Tools/$@/Bootlogo.pak/payload/bin/ - cp ./workspace/$@/other/rsce-go/rsce_tool ./build/EXTRAS/Tools/$@/Bootlogo.pak/payload/bin/ \ No newline at end of file diff --git a/workspace/_unmaintained/my355/platform/makefile.env b/workspace/_unmaintained/my355/platform/makefile.env deleted file mode 100644 index e9ffdfd36..000000000 --- a/workspace/_unmaintained/my355/platform/makefile.env +++ /dev/null @@ -1,4 +0,0 @@ -# rg35xx -ARCH = -mtune=cortex-a55 -march=armv8.2-a -mcpu=cortex-a55 -LIBS = -flto -SDL = SDL2 \ No newline at end of file diff --git a/workspace/_unmaintained/my355/platform/platform.c b/workspace/_unmaintained/my355/platform/platform.c deleted file mode 100644 index c9cc5739d..000000000 --- a/workspace/_unmaintained/my355/platform/platform.c +++ /dev/null @@ -1,657 +0,0 @@ -// my355 -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include "defines.h" -#include "platform.h" -#include "api.h" -#include "utils.h" - -#include "scaler.h" - -int on_hdmi = 0; - -/////////////////////////////// - -#define LID_PATH "/sys/devices/platform/hall-mh248/hallvalue" // 1 open, 0 closed -void PLAT_initLid(void) { - lid.has_lid = exists(LID_PATH); -} -int PLAT_lidChanged(int* state) { - if (lid.has_lid) { - int lid_open = getInt(LID_PATH); - if (lid_open!=lid.is_open) { - lid.is_open = lid_open; - if (state) *state = lid_open; - return 1; - } - } - return 0; -} - -/////////////////////////////// - -static SDL_Joystick *joystick; -void PLAT_initInput(void) { - SDL_InitSubSystem(SDL_INIT_JOYSTICK); - joystick = SDL_JoystickOpen(0); -} -void PLAT_quitInput(void) { - SDL_JoystickClose(joystick); - SDL_QuitSubSystem(SDL_INIT_JOYSTICK); -} - -/////////////////////////////// - -#define BLANK_PATH "/sys/class/backlight/backlight/bl_power" -#define HDMI_STATE_PATH "/sys/class/drm/card0-HDMI-A-1/status" - -static int HDMI_enabled(void) { - char value[64]; - getFile(HDMI_STATE_PATH, value, 64); - return exactMatch(value, "connected\n"); -} - -static struct VID_Context { - SDL_Window* window; - SDL_Renderer* renderer; - SDL_Texture* texture; - SDL_Texture* target; - SDL_Texture* effect; - - SDL_Surface* buffer; - SDL_Surface* screen; - - GFX_Renderer* blit; // yeesh - - int width; - int height; - int pitch; - int sharpness; -} vid; - -static int device_width; -static int device_height; -static int device_pitch; -static int rotate = 0; -SDL_Surface* PLAT_initVideo(void) { - LOG_info("PLAT_initVideo\n"); - - // char* model = getenv("RGXX_MODEL"); - // is_cubexx = exactMatch("RGcubexx", model); - // is_rg34xx = exactMatch("RG34xx", model); - - SDL_version compiled; - SDL_version linked; - SDL_VERSION(&compiled); - SDL_GetVersion(&linked); - LOG_info("Compiled SDL version %d.%d.%d ...\n", compiled.major, compiled.minor, compiled.patch); - LOG_info("Linked SDL version %d.%d.%d.\n", linked.major, linked.minor, linked.patch); - - int num_displays = SDL_GetNumVideoDisplays(); - LOG_info("SDL_GetNumVideoDisplays(): %i\n", num_displays); - - LOG_info("Available video drivers:\n"); - for (int i=0; imode.w) rotate = 3; // no longer set on 28xx (because of SDL2 rotation patch?) - vid.renderer = SDL_CreateRenderer(vid.window,-1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC); - // SDL_RenderSetLogicalSize(vid.renderer, w,h); // TODO: wrong, but without and with the below it's even wrong-er - - // int renderer_width,renderer_height; - // SDL_GetRendererOutputSize(vid.renderer, &renderer_width, &renderer_height); - // LOG_info("output size: %ix%i\n", renderer_width, renderer_height); - // if (renderer_width!=w) { // I think this can only be hdmi - // float x_scale = (float)renderer_width / w; - // float y_scale = (float)renderer_height / h; - // SDL_SetWindowSize(vid.window, w / x_scale, h / y_scale); - // - // SDL_GetRendererOutputSize(vid.renderer, &renderer_width, &renderer_height); - // LOG_info("adjusted size: %ix%i\n", renderer_width, renderer_height); - // x_scale = (float)renderer_width / w; - // y_scale = (float)renderer_height / h; - // SDL_RenderSetScale(vid.renderer, x_scale,y_scale); - // - // // for some reason we need to clear and present - // // after setting the window size or we'll miss - // // the first frame - // SDL_RenderClear(vid.renderer); - // SDL_RenderPresent(vid.renderer); - // } - - SDL_RendererInfo info; - SDL_GetRendererInfo(vid.renderer, &info); - LOG_info("Current render driver: %s\n", info.name); - - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY,"1"); // linear - vid.texture = SDL_CreateTexture(vid.renderer,SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, w,h); - vid.target = NULL; // only needed for non-native sizes - - // TODO: doesn't work here - // SDL_SetTextureScaleMode(vid.texture, SDL_ScaleModeLinear); // we always start at device size so use linear for better upscaling over hdmi - - // SDL_ScaleMode scale_mode; - // SDL_GetTextureScaleMode(vid.texture, &scale_mode); - // LOG_info("texture scale mode: %i\n", scale_mode); - - // int format; - // int access_; - // SDL_QueryTexture(vid.texture, &format, &access_, NULL,NULL); - // LOG_info("texture format: %s (streaming: %i)\n", SDL_GetPixelFormatName(format), access_==SDL_TEXTUREACCESS_STREAMING); - - vid.buffer = SDL_CreateRGBSurfaceFrom(NULL, w,h, FIXED_DEPTH, p, RGBA_MASK_565); - vid.screen = SDL_CreateRGBSurface(SDL_SWSURFACE, w,h, FIXED_DEPTH, RGBA_MASK_565); - vid.width = w; - vid.height = h; - vid.pitch = p; - - device_width = w; - device_height = h; - device_pitch = p; - - vid.sharpness = SHARPNESS_SOFT; - - return vid.screen; -} - -static void clearVideo(void) { - SDL_FillRect(vid.screen, NULL, 0); - for (int i=0; i<3; i++) { - SDL_RenderClear(vid.renderer); - SDL_RenderPresent(vid.renderer); - } -} - -void PLAT_quitVideo(void) { - // clearVideo(); - - SDL_FreeSurface(vid.screen); - SDL_FreeSurface(vid.buffer); - if (vid.target) SDL_DestroyTexture(vid.target); - if (vid.effect) SDL_DestroyTexture(vid.effect); - SDL_DestroyTexture(vid.texture); - SDL_DestroyRenderer(vid.renderer); - SDL_DestroyWindow(vid.window); - - // system("cat /dev/zero > /dev/fb0 2>/dev/null"); - SDL_Quit(); -} - -void PLAT_clearVideo(SDL_Surface* screen) { - SDL_FillRect(screen, NULL, 0); // TODO: revisit -} -void PLAT_clearAll(void) { - PLAT_clearVideo(vid.screen); // TODO: revist - SDL_RenderClear(vid.renderer); -} - -void PLAT_setVsync(int vsync) { - // buh -} - -static int hard_scale = 4; // TODO: base src size, eg. 160x144 can be 4 - -static void resizeVideo(int w, int h, int p) { - if (w==vid.width && h==vid.height && p==vid.pitch) return; - - // TODO: minarch disables crisp (and nn upscale before linear downscale) when native - - if (w>=device_width && h>=device_height) hard_scale = 1; - else if (h>=160) hard_scale = 2; // limits gba and up to 2x (seems sufficient for 640x480) - else hard_scale = 4; - - LOG_info("resizeVideo(%i,%i,%i) hard_scale: %i crisp: %i\n",w,h,p, hard_scale,vid.sharpness==SHARPNESS_CRISP); - - SDL_FreeSurface(vid.buffer); - SDL_DestroyTexture(vid.texture); - if (vid.target) SDL_DestroyTexture(vid.target); - - SDL_SetHintWithPriority(SDL_HINT_RENDER_SCALE_QUALITY, vid.sharpness==SHARPNESS_SOFT?"1":"0", SDL_HINT_OVERRIDE); - vid.texture = SDL_CreateTexture(vid.renderer,SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, w,h); - - if (vid.sharpness==SHARPNESS_CRISP) { - SDL_SetHintWithPriority(SDL_HINT_RENDER_SCALE_QUALITY, "1", SDL_HINT_OVERRIDE); - vid.target = SDL_CreateTexture(vid.renderer,SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_TARGET, w * hard_scale,h * hard_scale); - } - else { - vid.target = NULL; - } - - vid.buffer = SDL_CreateRGBSurfaceFrom(NULL, w,h, FIXED_DEPTH, p, RGBA_MASK_565); - - vid.width = w; - vid.height = h; - vid.pitch = p; -} - -SDL_Surface* PLAT_resizeVideo(int w, int h, int p) { - resizeVideo(w,h,p); - return vid.screen; -} - -void PLAT_setVideoScaleClip(int x, int y, int width, int height) { - // buh -} -void PLAT_setNearestNeighbor(int enabled) { - // buh -} -void PLAT_setSharpness(int sharpness) { - if (vid.sharpness==sharpness) return; - int p = vid.pitch; - vid.pitch = 0; - vid.sharpness = sharpness; - resizeVideo(vid.width,vid.height,p); -} - -static struct FX_Context { - int scale; - int type; - int color; - int next_scale; - int next_type; - int next_color; - int live_type; -} effect = { - .scale = 1, - .next_scale = 1, - .type = EFFECT_NONE, - .next_type = EFFECT_NONE, - .live_type = EFFECT_NONE, - .color = 0, - .next_color = 0, -}; -static void rgb565_to_rgb888(uint32_t rgb565, uint8_t *r, uint8_t *g, uint8_t *b) { - // Extract the red component (5 bits) - uint8_t red = (rgb565 >> 11) & 0x1F; - // Extract the green component (6 bits) - uint8_t green = (rgb565 >> 5) & 0x3F; - // Extract the blue component (5 bits) - uint8_t blue = rgb565 & 0x1F; - - // Scale the values to 8-bit range - *r = (red << 3) | (red >> 2); - *g = (green << 2) | (green >> 4); - *b = (blue << 3) | (blue >> 2); -} -static void updateEffect(void) { - if (effect.next_scale==effect.scale && effect.next_type==effect.type && effect.next_color==effect.color) return; // unchanged - - int live_scale = effect.scale; - int live_color = effect.color; - effect.scale = effect.next_scale; - effect.type = effect.next_type; - effect.color = effect.next_color; - - if (effect.type==EFFECT_NONE) return; // disabled - if (effect.type==effect.live_type && effect.scale==live_scale && effect.color==live_color) return; // already loaded - - char* effect_path; - int opacity = 128; // 1 - 1/2 = 50% - if (effect.type==EFFECT_LINE) { - if (effect.scale<3) { - effect_path = RES_PATH "/line-2.png"; - } - else if (effect.scale<4) { - effect_path = RES_PATH "/line-3.png"; - } - else if (effect.scale<5) { - effect_path = RES_PATH "/line-4.png"; - } - else if (effect.scale<6) { - effect_path = RES_PATH "/line-5.png"; - } - else if (effect.scale<8) { - effect_path = RES_PATH "/line-6.png"; - } - else { - effect_path = RES_PATH "/line-8.png"; - } - } - else if (effect.type==EFFECT_GRID) { - if (effect.scale<3) { - effect_path = RES_PATH "/grid-2.png"; - opacity = 64; // 1 - 3/4 = 25% - } - else if (effect.scale<4) { - effect_path = RES_PATH "/grid-3.png"; - opacity = 112; // 1 - 5/9 = ~44% - } - else if (effect.scale<5) { - effect_path = RES_PATH "/grid-4.png"; - opacity = 144; // 1 - 7/16 = ~56% - } - else if (effect.scale<6) { - effect_path = RES_PATH "/grid-5.png"; - opacity = 160; // 1 - 9/25 = ~64% - } - else if (effect.scale<8) { - effect_path = RES_PATH "/grid-6.png"; - opacity = 112; // 1 - 5/9 = ~44% - } - else if (effect.scale<11) { - effect_path = RES_PATH "/grid-8.png"; - opacity = 144; // 1 - 7/16 = ~56% - } - else { - effect_path = RES_PATH "/grid-11.png"; - opacity = 136; // 1 - 57/121 = ~52% - } - } - - // LOG_info("effect: %s opacity: %i\n", effect_path, opacity); - SDL_Surface* tmp = IMG_Load(effect_path); - if (tmp) { - if (effect.type==EFFECT_GRID) { - if (effect.color) { - // LOG_info("dmg color grid...\n"); - - uint8_t r,g,b; - rgb565_to_rgb888(effect.color,&r,&g,&b); - // LOG_info("rgb %i,%i,%i\n",r,g,b); - - uint32_t* pixels = (uint32_t*)tmp->pixels; - int width = tmp->w; - int height = tmp->h; - for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) { - uint32_t pixel = pixels[y * width + x]; - uint8_t _,a; - SDL_GetRGBA(pixel, tmp->format, &_, &_, &_, &a); - if (a) pixels[y * width + x] = SDL_MapRGBA(tmp->format, r,g,b, a); - } - } - } - } - - if (vid.effect) SDL_DestroyTexture(vid.effect); - vid.effect = SDL_CreateTextureFromSurface(vid.renderer, tmp); - SDL_SetTextureAlphaMod(vid.effect, opacity); - SDL_FreeSurface(tmp); - effect.live_type = effect.type; - } - } -void PLAT_setEffect(int next_type) { - effect.next_type = next_type; -} -void PLAT_setEffectColor(int next_color) { - effect.next_color = next_color; -} -void PLAT_vsync(int remaining) { - if (remaining>0) SDL_Delay(remaining); -} - -scaler_t PLAT_getScaler(GFX_Renderer* renderer) { - // LOG_info("getScaler for scale: %i\n", renderer->scale); - effect.next_scale = renderer->scale; - return scale1x1_c16; -} - -void PLAT_blitRenderer(GFX_Renderer* renderer) { - vid.blit = renderer; - SDL_RenderClear(vid.renderer); - resizeVideo(vid.blit->true_w,vid.blit->true_h,vid.blit->src_p); -} - -void PLAT_flip(SDL_Surface* IGNORED, int ignored) { - - on_hdmi = GetHDMI(); // use settings instead of getInt(HDMI_STATE_PATH) - - if (!vid.blit) { - resizeVideo(device_width,device_height,FIXED_PITCH); // !!!??? - SDL_UpdateTexture(vid.texture,NULL,vid.screen->pixels,vid.screen->pitch); - if (rotate && !on_hdmi) SDL_RenderCopyEx(vid.renderer,vid.texture,NULL,&(SDL_Rect){0,device_width,device_width,device_height},rotate*90,&(SDL_Point){0,0},SDL_FLIP_NONE); - else SDL_RenderCopy(vid.renderer, vid.texture, NULL,NULL); - SDL_RenderPresent(vid.renderer); - return; - } - - // uint32_t then = SDL_GetTicks(); - SDL_UpdateTexture(vid.texture,NULL,vid.blit->src,vid.blit->src_p); - // LOG_info("blit blocked for %ims (%i,%i)\n", SDL_GetTicks()-then,vid.buffer->w,vid.buffer->h); - - SDL_Texture* target = vid.texture; - int x = vid.blit->src_x; - int y = vid.blit->src_y; - int w = vid.blit->src_w; - int h = vid.blit->src_h; - if (vid.sharpness==SHARPNESS_CRISP) { - SDL_SetRenderTarget(vid.renderer,vid.target); - SDL_RenderCopy(vid.renderer, vid.texture, NULL,NULL); - SDL_SetRenderTarget(vid.renderer,NULL); - x *= hard_scale; - y *= hard_scale; - w *= hard_scale; - h *= hard_scale; - target = vid.target; - } - - SDL_Rect* src_rect = &(SDL_Rect){x,y,w,h}; - SDL_Rect* dst_rect = &(SDL_Rect){0,0,device_width,device_height}; - if (vid.blit->aspect==0) { // native or cropped - // LOG_info("src_rect %i,%i %ix%i\n",src_rect->x,src_rect->y,src_rect->w,src_rect->h); - - int w = vid.blit->src_w * vid.blit->scale; - int h = vid.blit->src_h * vid.blit->scale; - int x = (device_width - w) / 2; - int y = (device_height - h) / 2; - dst_rect->x = x; - dst_rect->y = y; - dst_rect->w = w; - dst_rect->h = h; - - // LOG_info("dst_rect %i,%i %ix%i\n",dst_rect->x,dst_rect->y,dst_rect->w,dst_rect->h); - } - else if (vid.blit->aspect>0) { // aspect - int h = device_height; - int w = h * vid.blit->aspect; - if (w>device_width) { - double ratio = 1 / vid.blit->aspect; - w = device_width; - h = w * ratio; - } - int x = (device_width - w) / 2; - int y = (device_height - h) / 2; - // dst_rect = &(SDL_Rect){x,y,w,h}; - dst_rect->x = x; - dst_rect->y = y; - dst_rect->w = w; - dst_rect->h = h; - } - - int ox,oy; - oy = (device_width-device_height)/2; - ox = -oy; - if (rotate && !on_hdmi) SDL_RenderCopyEx(vid.renderer,target,src_rect,&(SDL_Rect){ox+dst_rect->x,oy+dst_rect->y,dst_rect->w,dst_rect->h},rotate*90,NULL,SDL_FLIP_NONE); - else SDL_RenderCopy(vid.renderer, target, src_rect, dst_rect); - - updateEffect(); - if (vid.blit && effect.type!=EFFECT_NONE && vid.effect) { - // ox = effect.scale - (dst_rect->x % effect.scale); - // oy = effect.scale - (dst_rect->y % effect.scale); - // if (ox==effect.scale) ox = 0; - // if (oy==effect.scale) oy = 0; - // LOG_info("rotate: %i ox: %i oy: %i\n", rotate, ox,oy); - if (rotate && !on_hdmi) SDL_RenderCopyEx(vid.renderer,vid.effect,&(SDL_Rect){0,0,dst_rect->w,dst_rect->h},&(SDL_Rect){ox+dst_rect->x,oy+dst_rect->y,dst_rect->w,dst_rect->h},rotate*90,NULL,SDL_FLIP_NONE); - else SDL_RenderCopy(vid.renderer, vid.effect, &(SDL_Rect){0,0,dst_rect->w,dst_rect->h},dst_rect); - } - - // uint32_t then = SDL_GetTicks(); - SDL_RenderPresent(vid.renderer); - // LOG_info("SDL_RenderPresent blocked for %ims\n", SDL_GetTicks()-then); - vid.blit = NULL; -} - -int PLAT_supportsOverscan(void) { return 0; } - -/////////////////////////////// - -// TODO: -#define OVERLAY_WIDTH PILL_SIZE // unscaled -#define OVERLAY_HEIGHT PILL_SIZE // unscaled -#define OVERLAY_BPP 4 -#define OVERLAY_DEPTH 16 -#define OVERLAY_PITCH (OVERLAY_WIDTH * OVERLAY_BPP) // unscaled -#define OVERLAY_RGBA_MASK 0x00ff0000,0x0000ff00,0x000000ff,0xff000000 // ARGB -static struct OVL_Context { - SDL_Surface* overlay; -} ovl; - -SDL_Surface* PLAT_initOverlay(void) { - ovl.overlay = SDL_CreateRGBSurface(SDL_SWSURFACE, SCALE2(OVERLAY_WIDTH,OVERLAY_HEIGHT),OVERLAY_DEPTH,OVERLAY_RGBA_MASK); - return ovl.overlay; -} -void PLAT_quitOverlay(void) { - if (ovl.overlay) SDL_FreeSurface(ovl.overlay); -} -void PLAT_enableOverlay(int enable) { - -} - -/////////////////////////////// - -static int online = 0; -void PLAT_getBatteryStatus(int* is_charging, int* charge) { - PLAT_getBatteryStatusFine(is_charging, charge); - - // worry less about battery and more about the game you're playing - if (*charge>80) *charge = 100; - else if (*charge>60) *charge = 80; - else if (*charge>40) *charge = 60; - else if (*charge>20) *charge = 40; - else if (*charge>10) *charge = 20; - else *charge = 10; -} - -void PLAT_getBatteryStatusFine(int* is_charging, int* charge) -{ - // *is_charging = 0; - // *charge = PWR_LOW_CHARGE; - // return; - - *is_charging = getInt("/sys/class/power_supply/ac/online"); - - *charge = getInt("/sys/class/power_supply/battery/capacity"); - - // wifi status, just hooking into the regular PWR polling - char status[16]; - getFile("/sys/class/net/wlan0/operstate", status,16); - online = prefixMatch("up", status); -} - -#define LED_PATH "/sys/class/leds/work/brightness" -void PLAT_enableBacklight(int enable) { - if (enable) { - putInt(BLANK_PATH, FB_BLANK_UNBLANK); // wake - SetBrightness(GetBrightness()); - putInt(LED_PATH,0); - } - else { - putInt(BLANK_PATH, FB_BLANK_POWERDOWN); // sleep - SetRawBrightness(0); - putInt(LED_PATH,255); - } -} - -void PLAT_powerOff(void) { - system("rm -f /tmp/nextui_exec && sync"); - sleep(2); - - SetRawVolume(MUTE_VOLUME_RAW); - PLAT_enableBacklight(0); - system("echo 255 > /sys/class/leds/work/brightness"); - SND_quit(); - VIB_quit(); - PWR_quit(); - GFX_quit(); - - // system("cat /dev/zero > /dev/fb0 2>/dev/null"); - // system("poweroff"); - // while (1) pause(); // lolwat - - // touch("/tmp/poweroff"); - // sync(); - // system("touch /tmp/poweroff && sync"); - exit(0); -} - -/////////////////////////////// - -#define GOVERNOR_PATH "/sys/devices/system/cpu/cpufreq/policy0/scaling_setspeed" -void PLAT_setCPUSpeed(int speed) { - int freq = 0; - switch (speed) { - case CPU_SPEED_MENU: freq = 600000; break; - case CPU_SPEED_POWERSAVE: freq = 1104000; break; - case CPU_SPEED_NORMAL: freq = 1608000; break; - case CPU_SPEED_PERFORMANCE: freq = 1992000; break; - } - putInt(GOVERNOR_PATH, freq); -} - -#define RUMBLE_PATH "/sys/class/gpio/gpio20/value" -void PLAT_setRumble(int strength) { - if (GetHDMI()) return; // assume we're using a controller? - putInt(RUMBLE_PATH, strength?1:0); -} - -int PLAT_pickSampleRate(int requested, int max) { - return MIN(requested, max); -} - -char* PLAT_getModel(void) { - return "Miyoo Flip"; -} - -int PLAT_isOnline(void) { - return online; -} \ No newline at end of file diff --git a/workspace/_unmaintained/my355/platform/platform.h b/workspace/_unmaintained/my355/platform/platform.h deleted file mode 100644 index 82bbdf141..000000000 --- a/workspace/_unmaintained/my355/platform/platform.h +++ /dev/null @@ -1,147 +0,0 @@ -// my355/platform/platform.h - -#ifndef PLATFORM_H -#define PLATFORM_H - -/////////////////////////////// - -#include "sdl.h" - -/////////////////////////////// - -#define BUTTON_UP BUTTON_NA -#define BUTTON_DOWN BUTTON_NA -#define BUTTON_LEFT BUTTON_NA -#define BUTTON_RIGHT BUTTON_NA - -#define BUTTON_SELECT BUTTON_NA -#define BUTTON_START BUTTON_NA - -#define BUTTON_A BUTTON_NA -#define BUTTON_B BUTTON_NA -#define BUTTON_X BUTTON_NA -#define BUTTON_Y BUTTON_NA - -#define BUTTON_L1 BUTTON_NA -#define BUTTON_R1 BUTTON_NA -#define BUTTON_L2 BUTTON_NA -#define BUTTON_R2 BUTTON_NA -#define BUTTON_L3 BUTTON_NA -#define BUTTON_R3 BUTTON_NA - -#define BUTTON_MENU BUTTON_NA -#define BUTTON_POWER BUTTON_NA -#define BUTTON_PLUS BUTTON_NA -#define BUTTON_MINUS BUTTON_NA - -/////////////////////////////// - -#define CODE_UP 82 -#define CODE_DOWN 81 -#define CODE_LEFT 80 -#define CODE_RIGHT 79 - -#define CODE_SELECT 228 -#define CODE_START 40 - -#define CODE_A 44 -#define CODE_B 224 -#define CODE_X 225 -#define CODE_Y 226 - -#define CODE_L1 43 -#define CODE_R1 42 -#define CODE_L2 75 -#define CODE_R2 78 -#define CODE_L3 230 -#define CODE_R3 229 - -#define CODE_MENU 41 -#define CODE_POWER 102 - -#define CODE_PLUS 128 -#define CODE_MINUS 129 - -/////////////////////////////// - -#define JOY_UP JOY_NA -#define JOY_DOWN JOY_NA -#define JOY_LEFT JOY_NA -#define JOY_RIGHT JOY_NA - -#define JOY_SELECT JOY_NA -#define JOY_START JOY_NA - -#define JOY_A JOY_NA -#define JOY_B JOY_NA -#define JOY_X JOY_NA -#define JOY_Y JOY_NA - -#define JOY_L1 JOY_NA -#define JOY_R1 JOY_NA -#define JOY_L2 JOY_NA -#define JOY_R2 JOY_NA -#define JOY_L3 JOY_NA -#define JOY_R3 JOY_NA - -#define JOY_MENU JOY_NA -#define JOY_POWER JOY_NA -#define JOY_PLUS JOY_NA -#define JOY_MINUS JOY_NA - -/////////////////////////////// - -#define AXIS_LX 0 -#define AXIS_LY 1 -#define AXIS_RX 4 -#define AXIS_RY 3 - -/////////////////////////////// - -#define BTN_RESUME BTN_X -#define BTN_SLEEP BTN_POWER -#define BTN_WAKE BTN_POWER -#define BTN_MOD_VOLUME BTN_NONE -#define BTN_MOD_BRIGHTNESS BTN_MENU -#define BTN_MOD_PLUS BTN_PLUS -#define BTN_MOD_MINUS BTN_MINUS - -/////////////////////////////// - -extern int on_hdmi; - -#define FIXED_SCALE 2 -#define FIXED_WIDTH 640 -#define FIXED_HEIGHT 480 -#define FIXED_BPP 2 -#define FIXED_DEPTH (FIXED_BPP * 8) -#define FIXED_PITCH (FIXED_WIDTH * FIXED_BPP) -#define FIXED_SIZE (FIXED_PITCH * FIXED_HEIGHT) - -/////////////////////////////// - -#define HAS_HDMI 1 -#define HDMI_WIDTH 1280 -#define HDMI_HEIGHT 720 -#define HDMI_PITCH (HDMI_WIDTH * FIXED_BPP) -#define HDMI_SIZE (HDMI_PITCH * HDMI_HEIGHT) - -// TODO: if HDMI_HEIGHT > FIXED_HEIGHT then MAIN_ROW_COUNT will be insufficient - -/////////////////////////////// - -#define MAIN_ROW_COUNT (on_hdmi?8:6) -#define PADDING (on_hdmi?40:10) - -/////////////////////////////// - -#define SDCARD_PATH "/mnt/SDCARD" -#define MUTE_VOLUME_RAW 0 -// #define HAS_NEON -#define SAMPLES 400 // fix for (most) fceumm underruns - -// this should be set to the devices native screen refresh rate -#define SCREEN_FPS 60.0 -/////////////////////////////// - -#endif diff --git a/workspace/_unmaintained/my355/show/makefile b/workspace/_unmaintained/my355/show/makefile deleted file mode 100755 index b61deed63..000000000 --- a/workspace/_unmaintained/my355/show/makefile +++ /dev/null @@ -1,14 +0,0 @@ -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif - -TARGET = show -PRODUCT = $(TARGET).elf - -CC = $(CROSS_COMPILE)gcc -FLAGS = -Os -lSDL2 -lSDL2_image -lrt -ldl -Wl,--gc-sections -s - -all: - $(CC) $(TARGET).c -o $(PRODUCT) $(FLAGS) -clean: - rm -rf $(PRODUCT) \ No newline at end of file diff --git a/workspace/_unmaintained/my355/show/show.c b/workspace/_unmaintained/my355/show/show.c deleted file mode 100644 index f0c673c68..000000000 --- a/workspace/_unmaintained/my355/show/show.c +++ /dev/null @@ -1,63 +0,0 @@ -// rg35xxplus -#include -#include -#include -#include - -#define FIXED_BPP 2 -#define FIXED_DEPTH (FIXED_BPP * 8) - -#define RGBA_MASK_565 0xF800, 0x07E0, 0x001F, 0x0000 - -int main(int argc , char* argv[]) { - if (argc<2) { - puts("Usage: show.elf image.png delay"); - return 0; - } - - char path[256]; - strncpy(path,argv[1],256); - if (access(path, F_OK)!=0) return 0; // nothing to show :( - - int delay = argc>2 ? atoi(argv[2]) : 2; - - SDL_Init(SDL_INIT_VIDEO); - SDL_ShowCursor(0); - - int w = 0; - int h = 0; - int p = 0; - SDL_Window* window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w,h, SDL_WINDOW_SHOWN); - - int rotate = 0; - SDL_DisplayMode mode; - SDL_GetCurrentDisplayMode(0, &mode); - if (mode.h>mode.w) rotate = 3; - w = mode.w; - h = mode.h; - p = mode.w * FIXED_BPP; - - SDL_Renderer* renderer = SDL_CreateRenderer(window,-1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC); - SDL_Texture* texture = SDL_CreateTexture(renderer,SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, w,h); - SDL_Surface* screen = SDL_CreateRGBSurfaceFrom(NULL, w,h, FIXED_DEPTH, p, RGBA_MASK_565); - - SDL_LockTexture(texture,NULL,&screen->pixels,&screen->pitch); - SDL_FillRect(screen, NULL, 0); - SDL_Surface* img = IMG_Load(path); - SDL_BlitSurface(img, NULL, screen, &(SDL_Rect){(screen->w-img->w)/2,(screen->h-img->h)/2}); - SDL_FreeSurface(img); - SDL_UnlockTexture(texture); - - if (rotate) SDL_RenderCopyEx(renderer,texture,NULL,&(SDL_Rect){0,w,w,h},rotate*90,&(SDL_Point){0,0},SDL_FLIP_NONE); - else SDL_RenderCopy(renderer, texture, NULL,NULL); - SDL_RenderPresent(renderer); - - sleep(delay); - - SDL_FreeSurface(screen); - SDL_DestroyTexture(texture); - SDL_DestroyRenderer(renderer); - SDL_DestroyWindow(window); - SDL_Quit(); - return 0; -} diff --git a/workspace/_unmaintained/rg35xx/boot/boot.sh b/workspace/_unmaintained/rg35xx/boot/boot.sh deleted file mode 100755 index 7ca41b039..000000000 --- a/workspace/_unmaintained/rg35xx/boot/boot.sh +++ /dev/null @@ -1,110 +0,0 @@ -#!/system/bin/sh - -/usbdbg.sh device - -TF1_PATH=/mnt/mmc # ROMS partition -TF2_PATH=/mnt/sdcard -SDCARD_PATH=$TF1_PATH -SYSTEM_DIR=/.system -SYSTEM_FRAG=$SYSTEM_DIR/rg35xx -UPDATE_FRAG=/NextUI.zip -SYSTEM_PATH=${SDCARD_PATH}${SYSTEM_FRAG} -UPDATE_PATH=${SDCARD_PATH}${UPDATE_FRAG} - -mkdir /mnt/sdcard -if [ -e /dev/block/mmcblk1p1 ]; then - SDCARD_DEVICE=/dev/block/mmcblk1p1 -else - SDCARD_DEVICE=/dev/block/mmcblk1 -fi -mount -t vfat -o rw,utf8,noatime $SDCARD_DEVICE /mnt/sdcard -if [ $? -ne 0 ]; then - mount -t exfat -o rw,utf8,noatime $SDCARD_DEVICE /mnt/sdcard - if [ $? -ne 0 ]; then - rm -rf $TF2_PATH - ln -s $TF1_PATH $TF2_PATH - fi -fi - -if [ -d ${TF1_PATH}${SYSTEM_FRAG} ] || [ -f ${TF1_PATH}${UPDATE_FRAG} ]; then - if [ ! -L $TF2_PATH ]; then - # .system found on TF1 but TF2 is present - # so unmount and symlink to TF1 path - umount $TF2_PATH - rm -rf $TF2_PATH - ln -s $TF1_PATH $TF2_PATH - fi -fi - -SDCARD_PATH=$TF2_PATH -SYSTEM_PATH=${SDCARD_PATH}${SYSTEM_FRAG} -UPDATE_PATH=${SDCARD_PATH}${UPDATE_FRAG} - -# is there an update available? -if [ -f $UPDATE_PATH ]; then - FLAG_PATH=/misc/.minstalled - if [ ! -f $FLAG_PATH ]; then - ACTION=installing - else - ACTION=updating - fi - - # extract the zip file appended to the end of this script to tmp - # and display one of the two images it contains - CUT=$((`busybox grep -n '^BINARY' $0 | busybox cut -d ':' -f 1 | busybox tail -1` + 1)) - busybox tail -n +$CUT "$0" | busybox uudecode -o /tmp/data - busybox unzip -o /tmp/data -d /tmp - busybox fbset -g 640 480 640 480 16 - dd if=/tmp/$ACTION of=/dev/fb0 - sync - - busybox unzip -o $UPDATE_PATH -d $SDCARD_PATH - rm -f $UPDATE_PATH - - # the updated system finishes the install/update - $SYSTEM_PATH/bin/install.sh # &> $SDCARD_PATH/install.txt -fi - -ROOTFS_IMAGE=$SYSTEM_PATH/rootfs.ext2 -if [ ! -f $ROOTFS_IMAGE ]; then - # fallback to stock demenu.bin, based on dmenu_ln - ACT="/tmp/.next" - CMD="/mnt/vendor/bin/dmenu.bin" - touch "$ACT" - while [ -f $CMD ]; do - if $CMD; then - if [ -f "$ACT" ]; then - if ! sh $ACT; then - echo - fi - rm -f "$ACT" - fi - fi - done - sync && reboot -p -fi - -ROOTFS_MOUNTPOINT=/cfw -LOOPDEVICE=/dev/block/loop7 -mkdir $ROOTFS_MOUNTPOINT -busybox losetup $LOOPDEVICE $ROOTFS_IMAGE -mount -r -w -o loop -t ext4 $LOOPDEVICE $ROOTFS_MOUNTPOINT -rm -rf $ROOTFS_MOUNTPOINT/tmp/* -mkdir $ROOTFS_MOUNTPOINT/mnt/mmc -mkdir $ROOTFS_MOUNTPOINT/mnt/sdcard -for f in dev dev/pts proc sys mnt/mmc mnt/sdcard # tmp doesn't work for some reason? -do - mount -o bind /$f $ROOTFS_MOUNTPOINT/$f -done - -export PATH=/usr/sbin:/usr/bin:/sbin:/bin:$PATH -export LD_LIBRARY_PATH=/usr/lib/:/lib/ -export HOME=$SDCARD_PATH -busybox chroot $ROOTFS_MOUNTPOINT $SYSTEM_PATH/paks/NextUI.pak/launch.sh - -umount $ROOTFS_MOUNTPOINT -busybox losetup --detach $LOOPDEVICE -sync && reboot -p - -exit 0 - diff --git a/workspace/_unmaintained/rg35xx/boot/boot_logo.png b/workspace/_unmaintained/rg35xx/boot/boot_logo.png deleted file mode 100644 index d333e01efad0f910da19f2182c59e6c6ae7a6a95..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2529 zcmeHGX*iqd8h#TbwlLRGYZYCGp{4dgY>nbDt)Ueigjkv>5>!x2$u#CT9n+#(L_1ov zNG*}jY9$g|2dB0g6{Xf%YdJy1q!G^NoWJw$oa_9W=X$Q|y}tW?-{-sE=e?hsUgum< z@>=o$0F=8M#v1@Q1pwHTEF40b>OJbAMU(8}NA`)nOisjK4F^tP(IMe_?nFEx+&df} zmK56^ZU=xI)g9w>;o9iRxQE*XqEyTJPNhrm;Vo4cnOvJbudE|~|4u#p&cKmv;c%Pc z4gIewA6?8MIiGBMq!#E~>OZF5p!~Q5r{C?Ne;MapJ+Y&60KxMNith^$OMJ};#c{<8 zJ)ROlpUHoKx?p)2>Of@YAv|3O4%VB2k) zU;lJ_W=eU+L7MIIGM};cU~p*2oL@*qDksFp|7ccITPw7O>4lV>&htSak?N-QiuZMN z6M8z5os%oFbxC1s)x7jQd$h;*f?{+^n(e$qyse4$0lVMlnFTZ_$M3e{TYA=Mxbq2p zHW|;WtBtURFh|OlNCaYDR~vC4h(gWJSA!w+2r#8nflcQ8F2R5?HS0u+Q)p-zkjkkC z+gn?`7N&L=I$%1wx|1*CDj@VeKrZzCavyCJ^#IK(gliwm>mD5RhN@V>)>c=4fpDYG z0GX}ppcV|Ss!UDw(9Fy_GuXUCzS=MniBz1_$mQZFu&!??>7s`WU57NI8Ndj5xv{m( zr?bn-%GR$1KrD{JOOq5eUH>>lUxJ}fDBdA2bC^=1%1z87DZ*nhwvq)&c>*9!g!$}> zLYFWc&?MgeH>(DxwS$8E{1bWZ(0!1w2~N^xM@PpB{Ks3qq_4QbY z8-ppOiG+lYDW&h^!bnou=9ZT7Cg5vX!ElYg53eSAv@v?J?N^6mEl!bkajKfLY-G8%L8(Z6jy*ZVX z?KO#Llkibfux|wm3yZ_?fq{Y3zxJ$RYXd}tzrJAR>~C*~h>Sdwd}amujSasLGF;4O zhqRp+sUp_49C)`mX#g4VkAm`q4oM*r4{2!?1w5|v7&*N{!U4YrPoF+*ZEfu~&lqoa zQnQV=(=mRZ6v`}2R03Dz3dng^6p)uzI7A{beTV}D>G^_tBk#_hJqzs|IW9?RpHT?M z{r=nCYx2QqhrfKYgEurdZJe{AdmaX4P4-i-Wj`rE3Q7Q1+|U0I|7UKNotvBMc3UO8 zQ{CP=*9~L3BoNeLzmV40T?AMx);LvAawhW#jZ7vF8Op*HW$2BKR(C!;u#OFxrk*dh zqhYg<(i*Iq`g*fFA67<~WlU!5;iK(!t7DC>rc0U1x||z&EnYd0k5t~46crUIXRauOwvjt2<|s| zxL|uOQgN@gxw-j^0?Cdjj&VrVJUk~lA{LAJj3D0Zcp!`l5w_~50=o8GaGYyz3}qadN$WGO!gLf~du&Qejv0ZC zZ^V^-82sb|c{>eZZDb^=hdwv>w+>ou)Nrk$Cw`tClGdPbgiw=q z=+SX%MNsv@5z~fu$1KpdLYJgznHtrIZUl{@Qr@~*pWml diff --git a/workspace/_unmaintained/rg35xx/boot/build.sh b/workspace/_unmaintained/rg35xx/boot/build.sh deleted file mode 100755 index e7d7241e0..000000000 --- a/workspace/_unmaintained/rg35xx/boot/build.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/sh - -TARGET=dmenu.bin - -mkdir -p output -# TODO: shouldn't this be skipping 54 bytes (the size of the bitmap format header)? -if [ ! -f output/installing ]; then - dd skip=64 iflag=skip_bytes if=installing.bmp of=output/installing -fi -if [ ! -f output/updating ]; then - dd skip=64 iflag=skip_bytes if=updating.bmp of=output/updating -fi - -convert boot_logo.png -type truecolor output/boot_logo.bmp && gzip -f -n output/boot_logo.bmp - -cd output -if [ ! -f data ]; then - # tar -czvf data installing updating - zip -r data.zip installing updating - mv data.zip data -fi - -cp ~/buildroot/output/images/rootfs.ext2 ./ - -cat ../boot.sh > $TARGET -echo BINARY >> $TARGET -uuencode data data >> $TARGET \ No newline at end of file diff --git a/workspace/_unmaintained/rg35xx/boot/installing.bmp b/workspace/_unmaintained/rg35xx/boot/installing.bmp deleted file mode 100644 index 9ee57b7555779658fc9ab6060d6528a8cd8938db..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 614472 zcmeI*y-p;{6#(Gzbzm$fmS4b52zUcx0?P^ECMyExM8qV10A2tI@dg{hBap1bBOqsl z1O!+@@_3KSN2j``hk@~B@1pz7)$VlHR9Bt;=GNKjADV;1zy1C9i+KI@+n@b!fBx~) zV)2)MFPFbr{BiNyZ|gsO`}|LTSp4_Tx7GIg*JAO{-z^q@&UNnu2oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U_|5{47f1J(PoKV2w`0kt zFPBf3PmdQ><40Qhv7`Huq{KqtM-ce>`TTade7-w8{^g_j`g!@k*U4FnW-NKU$Qs`x z13q3{J}sB~H#-NbHZ3pj-|X(yXWK;=-@wuR`R&)w)lx3)?pomSnWc<@xP<$6I|L-S=58`u+4J^YHUs#j#yhEnZKA6g?sB<01B|(Odu0T<{v&)}x!>Lid{luNPe11oa63A@z8dFEFDs4N zZm}3k9!@jf$~rH%x$URZ9Cvizw^LC?G?|$ei*2GiJkC8@E?2*Sm-63g?LJ1!1PE*v zcxm))-g>@9&1ot(%-5WjR$j^NR!bgE_iy%Z-hb@(c`1zg*>Pp1_@tkSzCF6WpVhsp zo>C-wY_HYYQ%!3G2y7C_(KI*v*tG4s&udKQs9jfcTE3d?R!gQ^yx&^&+=OaRcK6CG zmijY*Z;z*}=Dq>>@9mhSpRxIYTsIXF3MZ9ZN+oc5or9_`MR?Cwold~LLg#mU+E?epFF?c+uC z8dp}&Z})F1>VDrAi@NgAgeuFOoRwKysx99ho%~mNmI!=rff~y#|LyLzoOb!NbMSDQ z`7N$a_L<`A=l<$IwsC#6SbY6l+hqCWQ)|23yOE{w9{2iH4y?SHv#qgY=b)kssnD7RU6=Ug_7&E91>LbIUBRW8-b2lmE)x5`ph6P@}lzsLD8F28fKzZ}~~Szm)&_k)HM2dmdX>zIc27o3(ow~+bZEcRW>gG~L*Q;b6tyn5=W*@oz+}Xm~&JqCv zuMrr>Q{|xebzs>t#`ts^GmfGB^ z`p(flmaJcoR_3Ff=CZNQeE#dRQVO&?j_bT&Ddf-VZ4+JJll=FZ|6|o5@bd{o-e|AY z`ClvP&-b^I++w-Rb7FDcuSRc;>C9spZ(O^`qv*rq%7<-kHRg|g=GIyoYt(wqhgPHQ z>$E)E*O||Mwaw9eWxTlOFtcIY_m>WN2TYZW(XNlKtg=p8#k=`muVI|EfXNHSzsJb;~0(>Y81Bo*JqD7 z&z9FOvbP%3IcoEh@x6MBPiif<8%s8=M=N8rwTBgF|I;0@&G@P|;%=F2;po2dVqcy) zberhPYA&PoakLmSmbu#FURWnU;AMevJdI;Gwysgw@?Xu{a_jTkI{IBKYD{My%NXK* z!u^{#C%AtT_ZU`hQKQy!yRl@`dbBc)wz5}dsi?D9WaQJ*_Ss@lGu$|0uH*D7k6c=9 zw9NYU=z6QUj8^-SBGqRvo^g98K;SI`<9Hg!aI{sUFvr}^LFI&Op`Hb`F8>`KSN>>Q zRV&fYYTskYruEfmE0#P;jXHf!YwOd$bDvsHs$R3awN=qKm#WvY)wmvgjFuIj{5Sm$ ztPyyBfgI5}`d%|;TT~}!dG;>bXxD%HIZe)5VvByH=N9!IHCFo`OE#@XE7J^9XY8g= zjH*l=+e}}5r143=-Xd;i604{Ad^biLZPhj{XZAOpOmbU{I@7t^&&uE8-Z~= zy=Kf-KPP832a1;3ogkGja@58aW45fGV<~E^_C1ztT8~!73{(BYr|q@wsJMMv*N5}Y z#LAYfwU((WnwAf1eLf#X>tl5NQFL9OX>nBU&O3zq+VWph@;8C)1u8qtAHzkqL@?Fa& zwVrpz^%%OwZ9o_sf1T%#frb>{i^kr{8!hMqwU9wmg(Y2 zTCv_^<{eMYCKU-9KK$?a&)j#%kYV z$)@#aWg2ai)QmOzyL_r>qQ>-R>66Fm)AoJUdOO#! zX}w~%M1Vk!;JiDe=4pBC*UwMdm^(bqt!lJIma8qMXV}`=t7%zmxqp-AzS`KWnPtxZ z#*&JzoqeqJ>O0%4=kl#Sl`x)#nz66`Kaj`Ad7dw7R3vrYvwuoz$W%0Mi!Oc=u;R(M z+WXOc%|RoMl+W+0@^b5Q(|WYwMSwsPXiqYYGkGb}@<%??Bud-poc`AFc=~gV)XS&q ztCkzHmHt_$+4jysjn3!0C~Y~hW;m_yx|2F{ZY5SP z`@?C}9Dla? diff --git a/workspace/_unmaintained/rg35xx/boot/updating.bmp b/workspace/_unmaintained/rg35xx/boot/updating.bmp deleted file mode 100644 index 66e86a702b20427cae112f4b1574a29eed57c1df..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 614472 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 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly xK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0tB{A;6IZy(n0_L diff --git a/workspace/_unmaintained/rg35xx/cores/makefile b/workspace/_unmaintained/rg35xx/cores/makefile deleted file mode 100644 index 2ba8dde3c..000000000 --- a/workspace/_unmaintained/rg35xx/cores/makefile +++ /dev/null @@ -1,40 +0,0 @@ -CORES = fceumm gambatte gpsp pcsx_rearmed picodrive snes9x2005_plus -CORES+= mednafen_pce_fast mednafen_vb fake-08 mednafen_supafaust mgba pokemini race - -############################### - -# optional core vars -# *_REPO= -# *_HASH= -# *_CORE= -# *_FLAGS= -# *_MAKEFILE= -# *_BUILD_PATH= - -mednafen_pce_fast_REPO = https://github.com/libretro/beetle-pce-fast-libretro -mednafen_vb_REPO = https://github.com/libretro/beetle-vb-libretro - -fake-08_REPO = https://github.com/jtothebell/fake-08 -fake-08_CORE = fake08_libretro.so -fake-08_BUILD_PATH = fake-08/platform/libretro - -fceumm_REPO = https://github.com/libretro/libretro-fceumm - -gambatte_REPO = https://github.com/libretro/gambatte-libretro - -mednafen_supafaust_REPO = https://github.com/libretro/supafaust - -pcsx_rearmed_MAKEFILE = Makefile.libretro - -picodrive_REPO = https://github.com/irixxxx/picodrive -picodrive_MAKEFILE = Makefile.libretro - -pokemini_REPO = https://github.com/libretro/PokeMini -pokemini_MAKEFILE = Makefile.libretro - -snes9x2005_plus_REPO = https://github.com/libretro/snes9x2005 -snes9x2005_plus_FLAGS = USE_BLARGG_APU=1 - -############################### - -include ../../all/cores/makefile diff --git a/workspace/_unmaintained/rg35xx/cores/patches/fake-08.patch b/workspace/_unmaintained/rg35xx/cores/patches/fake-08.patch deleted file mode 100644 index dff15be18..000000000 --- a/workspace/_unmaintained/rg35xx/cores/patches/fake-08.patch +++ /dev/null @@ -1,34 +0,0 @@ -diff --git forkSrcPrefix/platform/libretro/Makefile forkDstPrefix/platform/libretro/Makefile -index be0f1b46bb3ab10be4a9f896f5e8841dd630b35b..cc7a7249135bb690885e7f5fda09f9eb8fdeac22 100644 ---- forkSrcPrefix/platform/libretro/Makefile -+++ forkDstPrefix/platform/libretro/Makefile -@@ -123,7 +123,16 @@ else ifeq ($(platform), miyoomini) - CXXFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7ve -D_NEED_FULL_PATH_ - fpic := -fPIC - SHARED := -shared -Wl,--version-script=link.T -- -+else ifeq ($(platform), rg35xx) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ STRIP = $(CROSS_COMPILE)strip -+ CXXFLAGS += -marm -mtune=cortex-a9 -mfpu=neon-fp16 -mfloat-abi=hard -march=armv7-a -+ CXXFLAGS += -fomit-frame-pointer -ffast-math -fno-common -ftree-vectorize -funswitch-loops -+ fpic := -fPIC -+ SHARED := -shared -Wl,--version-script=link.T - else ifeq ($(platform), gcw0) - TARGET := $(TARGET_NAME)_libretro_gcw0.so - CC = /opt/gcw0-toolchain/usr/bin/mipsel-linux-gcc -diff --git forkSrcPrefix/platform/libretro/libretro.cpp forkDstPrefix/platform/libretro/libretro.cpp -index d95ccb6cab52abfe7620ff84dd5cbb450bafe750..24687335ad410096aa48f29e13dcb479171a06fc 100644 ---- forkSrcPrefix/platform/libretro/libretro.cpp -+++ forkDstPrefix/platform/libretro/libretro.cpp -@@ -636,6 +636,7 @@ EXPORT bool retro_load_game(struct retro_game_info const *info) - else { - _vm->QueueCartChange(info->path); - } -+ _vm->UpdateAndDraw(); - - return true; - } diff --git a/workspace/_unmaintained/rg35xx/cores/patches/fceumm.patch b/workspace/_unmaintained/rg35xx/cores/patches/fceumm.patch deleted file mode 100644 index c823a48ff..000000000 --- a/workspace/_unmaintained/rg35xx/cores/patches/fceumm.patch +++ /dev/null @@ -1,25 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index 14b8cbedb12860aedc2bc21119735247929bdbd3..0d1787ef81ffc6cdb2b4982c779a89ef198c954f 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -461,6 +461,20 @@ else ifeq ($(platform), miyoo) - PLATFORM_DEFINES += -fomit-frame-pointer -ffast-math -mcpu=arm926ej-s - EXTERNAL_ZLIB = 1 - -+# RG35XX -+else ifeq ($(platform), rg35xx) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=src/drivers/libretro/link.T -Wl,-no-undefined -+ LDFLAGS += -fPIC -flto -+ CFLAGS += -marm -mtune=cortex-a9 -mfpu=neon-fp16 -mfloat-abi=hard -march=armv7-a -fomit-frame-pointer -+ CFLAGS += -fomit-frame-pointer -ffast-math -fPIC -flto -+ OPTIMIZE := -Ofast -DNDEBUG -+ EXTERNAL_ZLIB = 1 -+ HAVE_NTSC = 0 -+ - # Windows MSVC 2017 all architectures - else ifneq (,$(findstring windows_msvc2017,$(platform))) - CC = cl.exe diff --git a/workspace/_unmaintained/rg35xx/cores/patches/gambatte.patch b/workspace/_unmaintained/rg35xx/cores/patches/gambatte.patch deleted file mode 100644 index b19895f61..000000000 --- a/workspace/_unmaintained/rg35xx/cores/patches/gambatte.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index ffaba21e7a88f90786d818ab550b68acd05738bf..3c5a057d89d12e6c34910350859e9842a98e224a 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -405,6 +405,19 @@ else ifeq ($(platform), miyoo) - CFLAGS += -fomit-frame-pointer -ffast-math -march=armv5te -mtune=arm926ej-s - CXXFLAGS += $(CFLAGS) - -+# RG35XX -+else ifeq ($(platform), rg35xx) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=$(version_script) -+ LDFLAGS += -fPIC -flto -+ PLATFORM_DEFINES := -DCC_RESAMPLER -DCC_RESAMPLER_NO_HIGHPASS -+ CFLAGS += -marm -mtune=cortex-a9 -mfpu=neon-fp16 -mfloat-abi=hard -march=armv7-a -fomit-frame-pointer -+ CFLAGS += -fomit-frame-pointer -ffast-math -fPIC -flto -+ CXXFLAGS += $(CFLAGS) -+ - # Windows MSVC 2003 Xbox 1 - else ifeq ($(platform), xbox1_msvc2003) - TARGET := $(TARGET_NAME)_libretro_xdk1.lib diff --git a/workspace/_unmaintained/rg35xx/cores/patches/gpsp.patch b/workspace/_unmaintained/rg35xx/cores/patches/gpsp.patch deleted file mode 100644 index 5ab301210..000000000 --- a/workspace/_unmaintained/rg35xx/cores/patches/gpsp.patch +++ /dev/null @@ -1,30 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index dc4b60dec7f70a153dbc2eb849cd5acfc90f9d4d..918054035afe9a37bb24540d9a6ac3cc2f699dbb 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -524,6 +524,25 @@ else ifeq ($(platform), miyoomini) - ARCH = arm - BUILTIN_GPU = neon - -+# RG35XX -+else ifeq ($(platform), rg35xx) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=link.T -+ fpic := -fPIC -DPIC -+ LDFLAGS += -fPIC -flto -+ PLATFORM_DEFINES := -DCC_RESAMPLER -DCC_RESAMPLER_NO_HIGHPASS -+ CFLAGS += -marm -mtune=cortex-a9 -mfpu=neon-fp16 -mfloat-abi=hard -march=armv7-a -fomit-frame-pointer -+ CFLAGS += -fomit-frame-pointer -ffast-math -fPIC -flto -+ HAVE_NEON = 1 -+ ARCH = arm -+ BUILTIN_GPU = neon -+ CPU_ARCH := arm -+ MMAP_JIT_CACHE = 1 -+ HAVE_DYNAREC := 1 -+ - # Windows - else - TARGET := $(TARGET_NAME)_libretro.dll diff --git a/workspace/_unmaintained/rg35xx/cores/patches/mednafen_pce_fast.patch b/workspace/_unmaintained/rg35xx/cores/patches/mednafen_pce_fast.patch deleted file mode 100644 index b3b9a40fb..000000000 --- a/workspace/_unmaintained/rg35xx/cores/patches/mednafen_pce_fast.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index d580571511b43d1ec4597db4a9611b0924bb2c53..d2a2f9929cee1f7fb45a1a002efd7b04812ded49 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -377,6 +377,19 @@ else ifeq ($(platform), miyoo) - CXXFLAGS += -std=c++11 - CFLAGS += -std=gnu11 - -+# RG35XX -+else ifeq ($(platform), rg35xx) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ fpic := -fPIC -+ SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T -+ FLAGS += -marm -mtune=cortex-a9 -mfpu=neon-fp16 -mfloat-abi=hard -march=armv7-a -fomit-frame-pointer -DRG35XX -+ FLAGS += -fomit-frame-pointer -ffast-math -D_GNU_SOURCE -flto -fPIC -+ CXXFLAGS += -std=c++11 -+ CFLAGS += -std=gnu11 -+ - # Windows MSVC 2017 all architectures - else ifneq (,$(findstring windows_msvc2017,$(platform))) - diff --git a/workspace/_unmaintained/rg35xx/cores/patches/mednafen_supafaust.patch b/workspace/_unmaintained/rg35xx/cores/patches/mednafen_supafaust.patch deleted file mode 100644 index 331f62dca..000000000 --- a/workspace/_unmaintained/rg35xx/cores/patches/mednafen_supafaust.patch +++ /dev/null @@ -1,31 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index 58120a1a88eab75ca13f2ed062f37d075c05a51b..c60ebf68483aebf7a0dc320e4589f29cf6457013 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -187,6 +187,26 @@ else ifeq ($(platform), wii) - - EXTRA_INCLUDES := -I$(DEVKITPRO)/libogc/include - STATIC_LINKING = 1 -+else ifeq ($(platform), rg35xx) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ fpic := -fPIC -+ SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T -+ CFLAGS += -Ofast \ -+ -flto=4 -fwhole-program -fuse-linker-plugin \ -+ -fdata-sections -ffunction-sections -Wl,--gc-sections \ -+ -fno-stack-protector -fno-ident -fomit-frame-pointer \ -+ -falign-functions=1 -falign-jumps=1 -falign-loops=1 \ -+ -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-unroll-loops \ -+ -fmerge-all-constants -fno-math-errno -+ CFLAGS += -marm -mtune=cortex-a9 -mfpu=neon-fp16 -mfloat-abi=hard -march=armv7-a -fomit-frame-pointer -DRG35XX -+ CXXFLAGS += $(CFLAGS) -+ CFLAGS += -fPIC -+ LDFLAGS += -flto -+ HAVE_NEON = 1 -+ ARCH = arm - else ifneq (,$(findstring rpi,$(platform))) - TARGET := $(TARGET_NAME)_libretro.so - fpic := -fPIC diff --git a/workspace/_unmaintained/rg35xx/cores/patches/mednafen_vb.patch b/workspace/_unmaintained/rg35xx/cores/patches/mednafen_vb.patch deleted file mode 100644 index ad98fc71e..000000000 --- a/workspace/_unmaintained/rg35xx/cores/patches/mednafen_vb.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index 1e94d9eae2e1ce664eecc3edfc5187f393f98a45..912369d4cfad20bc9a0852aa9faf1859e3fbbac7 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -320,6 +320,19 @@ else ifeq ($(platform), gcw0) - SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T - FLAGS += -ffast-math -march=mips32 -mtune=mips32r2 -mhard-float - -+# RG35XX -+else ifeq ($(platform), rg35xx) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ fpic := -fPIC -+ SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T -+ FLAGS += -marm -mtune=cortex-a9 -mfpu=neon-fp16 -mfloat-abi=hard -march=armv7-a -fomit-frame-pointer -DRG35XX -+ FLAGS += -ffast-math -fdata-sections -ffunction-sections -fsingle-precision-constant -flto -fPIC -+ NEED_BPP = 16 -+# STATIC_LINKING = 1 -+ - # Windows MSVC 2010 x64 - else ifeq ($(platform), windows_msvc2010_x64) - CC = cl.exe diff --git a/workspace/_unmaintained/rg35xx/cores/patches/mgba.patch b/workspace/_unmaintained/rg35xx/cores/patches/mgba.patch deleted file mode 100644 index 0a9e6588a..000000000 --- a/workspace/_unmaintained/rg35xx/cores/patches/mgba.patch +++ /dev/null @@ -1,31 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index 108148f4579f4727146e5b8c1e05ef7382654208..4ff34d4c2b5c6031ce4c3256f1b70daba99a583c 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -417,6 +417,26 @@ else ifeq ($(platform), miyoo) - CFLAGS += -fno-common -ftree-vectorize -funswitch-loops - DEFINES += -std=c99 - -+# RG35XX -+else ifeq ($(platform), rg35xx) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=link.T -+ fpic := -fPIC -+ PLATFORM_DEFINES += -D_GNU_SOURCE -DHAVE_STRTOF_L -DHAVE_LOCALE -+ CFLAGS += -fomit-frame-pointer -ffast-math -+ CFLAGS += -marm -mtune=cortex-a9 -mfpu=neon-fp16 -mfloat-abi=hard -march=armv7-a -+ CFLAGS += -fno-common -ftree-vectorize -funswitch-loops -+ HAVE_NEON = 1 -+ ARCH = arm -+ BUILTIN_GPU = neon -+ CPU_ARCH := arm -+ MMAP_JIT_CACHE = 1 -+ HAVE_DYNAREC = 1 -+ DEFINES += -std=c99 -+ - # Windows - else - TARGET := $(TARGET_NAME)_libretro.dll diff --git a/workspace/_unmaintained/rg35xx/cores/patches/pcsx_rearmed.patch b/workspace/_unmaintained/rg35xx/cores/patches/pcsx_rearmed.patch deleted file mode 100644 index eb769cc63..000000000 --- a/workspace/_unmaintained/rg35xx/cores/patches/pcsx_rearmed.patch +++ /dev/null @@ -1,30 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index 7b9618e1ccfc63982be50b82fda498d75e307fdc..6fae9d28a2867214e3cae29b2abbe1f9a6bafbe2 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -490,6 +490,25 @@ else ifeq ($(platform), miyoo) - DYNAREC = ari64 - HAVE_NEON = 0 - -+# RG35XX -+else ifeq ($(platform), rg35xx) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ # CFLAGS += -marm -mtune=cortex-a9 -mfpu=vfpv3-d16 -mfloat-abi=hard -march=armv7-a -+ CFLAGS += -marm -mtune=cortex-a9 -mfpu=neon-fp16 -mfloat-abi=hard -march=armv7-a -fomit-frame-pointer -+ CFLAGS += -ffast-math -fdata-sections -ffunction-sections -fsingle-precision-constant -flto -fPIC -DNO_HWCAP -+ LDFLAGS += -flto -fPIC -+ LDFLAGS += -flto -+ CPU_ARCH := arm -+ OPTIMIZE += -Ofast -DNDEBUG=1 -+ HAVE_NEON = 1 -+ HAVE_NEON_ASM = 1 -+ BUILTIN_GPU = neon -+ ARCH = arm -+ DYNAREC = ari64 -+ - # Emscripten - else ifeq ($(platform), emscripten) - TARGET := $(TARGET_NAME)_libretro_$(platform).bc diff --git a/workspace/_unmaintained/rg35xx/cores/patches/picodrive.patch b/workspace/_unmaintained/rg35xx/cores/patches/picodrive.patch deleted file mode 100644 index 10a96d3e6..000000000 --- a/workspace/_unmaintained/rg35xx/cores/patches/picodrive.patch +++ /dev/null @@ -1,28 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index 0d1dc08f81a11cef6b3b7238367b1ff27fcf1ead..13e7f1b601e2476c81d34e515978355115f8bdd1 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -497,6 +497,23 @@ else ifeq ($(platform), miyoo) - HAVE_ARMv6 = 0 - LOW_MEMORY = 1 - -+# RG35XX -+else ifeq ($(platform), rg35xx) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -+ LIBM := -+ fpic := -fPIC -flto -+ CFLAGS += -marm -mtune=cortex-a9 -mfpu=neon-fp16 -mfloat-abi=hard -march=armv7-a -fomit-frame-pointer -+ CFLAGS += -fomit-frame-pointer -ffast-math -fno-finite-math-only -D__GCW0__ -+ DONT_COMPILE_IN_ZLIB = 1 -+ HAVE_ARMv6 = 0 -+ LOW_MEMORY = 1 -+ HAVE_NEON = 1 -+ BUILTIN_GPU = neon -+ - # Windows MSVC 2017 all architectures - else ifneq (,$(findstring windows_msvc2017,$(platform))) - NO_GCC := 1 diff --git a/workspace/_unmaintained/rg35xx/cores/patches/pokemini.patch b/workspace/_unmaintained/rg35xx/cores/patches/pokemini.patch deleted file mode 100644 index 4afb80737..000000000 --- a/workspace/_unmaintained/rg35xx/cores/patches/pokemini.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index ef2f9e7d1c6041bea8e2c8a61cdd363ed73a7482..6c525fe787e205fbd1352b74c00ebfca67d791e2 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -504,6 +504,19 @@ else ifeq ($(platform), retrofw) - CFLAGS += -ffast-math -fomit-frame-pointer -march=mips32 -mtune=mips32 -mhard-float - CFLAGS += -DDINGUX - -+# RG35XX -+else ifeq ($(platform), rg35xx) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=libretro/link.T -+ fpic += -fPIC -flto -+ CFLAGS += $(PTHREAD_FLAGS) -+ CFLAGS += -marm -mtune=cortex-a9 -mfpu=neon-fp16 -mfloat-abi=hard -march=armv7-a -fomit-frame-pointer -+ CFLAGS += -fomit-frame-pointer -ffast-math -fPIC -flto -+ CFLAGS += -DDINGUX -+ - else ifeq ($(platform), msvc) - OBJOUT = -Fo - diff --git a/workspace/_unmaintained/rg35xx/cores/patches/race.patch b/workspace/_unmaintained/rg35xx/cores/patches/race.patch deleted file mode 100644 index bf1af3d0c..000000000 --- a/workspace/_unmaintained/rg35xx/cores/patches/race.patch +++ /dev/null @@ -1,23 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index 792a6d82915c32edd3df6ceec541499f6ca25ac5..dc02b361d7db47e011b6d3addf89cfb31503575a 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -373,6 +373,18 @@ else ifeq ($(platform), miyoo) - CFLAGS += -fomit-frame-pointer -ffast-math -march=armv5te -mtune=arm926ej-s - CXXFLAGS += $(CFLAGS) - -+# RG35XX -+else ifeq ($(platform), rg35xx) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ fpic := -fPIC -+ SHARED := -shared -Wl,-version-script=$(LIBRETRO_DIR)/link.T -+ PLATFORM_DEFINES := -DCC_RESAMPLER -DCC_RESAMPLER_NO_HIGHPASS -+ CFLAGS += -fomit-frame-pointer -ffast-math -marm -mtune=cortex-a9 -mfpu=neon-fp16 -mfloat-abi=hard -march=armv7-a -+ CXXFLAGS += $(CFLAGS) -+ - # Windows MSVC 2010 x64 - else ifeq ($(platform), windows_msvc2010_x64) - CC = cl.exe diff --git a/workspace/_unmaintained/rg35xx/cores/patches/snes9x2005_plus.patch b/workspace/_unmaintained/rg35xx/cores/patches/snes9x2005_plus.patch deleted file mode 100644 index 4b6b41b17..000000000 --- a/workspace/_unmaintained/rg35xx/cores/patches/snes9x2005_plus.patch +++ /dev/null @@ -1,39 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index 07d5368a8e78a020813732239ec369d83e931ede..8a9d2cd5415021f8288fb930db89ee4aff529abc 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -288,6 +288,34 @@ else ifeq ($(platform), miyoo) - FLAGS += -fomit-frame-pointer -ffast-math -march=armv5te -mtune=arm926ej-s - FLAGS += -DFAST_ALIGNED_LSB_WORD_ACCESS -fno-unroll-loops - -+# RG35XX -+else ifeq ($(platform), rg35xx) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=link.T -+ LIBM := -+ fpic := -fPIC -flto -+ CFLAGS += -Ofast \ -+ -flto=4 -fwhole-program -fuse-linker-plugin \ -+ -fdata-sections -ffunction-sections -Wl,--gc-sections \ -+ -fno-stack-protector -fno-ident -fomit-frame-pointer \ -+ -falign-functions=1 -falign-jumps=1 -falign-loops=1 \ -+ -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-unroll-loops \ -+ -fmerge-all-constants -fno-math-errno -+ CFLAGS += -fPIC -+ CFLAGS += -DLSB_FIRST -DFAST_ALIGNED_LSB_WORD_ACCESS -DRIGHTSHIFT_IS_SAR -+ CFLAGS += -std=c99 -fomit-frame-pointer -ffast-math -+ CFLAGS += -marm -mtune=cortex-a9 -mfpu=neon-fp16 -mfloat-abi=hard -march=armv7-a -fomit-frame-pointer -+ # CFLAGS += -marm -mtune=cortex-a9 -mfpu=vfpv3-d16 -mfloat-abi=hard -march=armv7-a -+ LDFLAGS += -flto -+ OPTIMIZE += -Ofast -DNDEBUG=1 -+ HAVE_NEON = 1 -+ ARCH = arm -+ BUILTIN_GPU = neon -+ USE_DYNAREC = 1 -+ - # (armv7 a7, hard point, neon based) ### - # NESC, SNESC, C64 mini - else ifeq ($(platform), classic_armv7_a7) diff --git a/workspace/_unmaintained/rg35xx/install/install.sh b/workspace/_unmaintained/rg35xx/install/install.sh deleted file mode 100755 index e76023507..000000000 --- a/workspace/_unmaintained/rg35xx/install/install.sh +++ /dev/null @@ -1,75 +0,0 @@ -#!/system/bin/sh - -# NOTE: this file is not chrooted so it's using stock's everything! -# { - -TF1_PATH=/mnt/mmc -TF2_PATH=/mnt/sdcard # TF1 should be linked to this path if TF2 is missing or doesn't contain our system folder -SYSTEM_PATH=${TF2_PATH}/.system/rg35xx -FLAG_PATH=/misc/.minstalled - -echo "installing/updating" - -if [ ! -f $FLAG_PATH ]; then - echo "backing up" - BAK_PATH=$TF1_PATH/bak - mkdir -p $BAK_PATH - cp /misc/boot_logo.bmp.gz $BAK_PATH -fi - -was_updated() { - # intiial releases didn't install this properly :sob: - if [ ! -f /misc/charging.png ]; then - return 0 - fi - - for FILE in /misc/* /misc/*/*; do - A_PATH=$FILE - A_NAME=$(busybox basename "$A_PATH") - B_PATH=$SYSTEM_PATH/dat/$A_NAME - - if [[ "$A_NAME" == "boot_logo.bmp.gz" ]]; then - # we don't care if the user has changed their boot logo - continue - fi - - if [[ "$A_NAME" == "charging.png" ]]; then - # we don't care if the user has changed their charging image - continue - fi - - if [ ! -f "$B_PATH" ]; then - continue - fi - - A_SUM=$(busybox md5sum $A_PATH | busybox cut -d ' ' -f 1) - B_SUM=$(busybox md5sum $B_PATH | busybox cut -d ' ' -f 1) - - if [[ "$A_SUM" != "$B_SUM" ]]; then - return 0 - fi - done - - return 1 -} - -if [ ! -f $FLAG_PATH ] || was_updated; then - echo "updating misc partition" - mount -o remount,rw /dev/block/actb /misc - cp $SYSTEM_PATH/dat/dmenu.bin /misc - cp $SYSTEM_PATH/dat/ramdisk.img /misc - - # boot logo, only installed, never updated - if [ ! -f $FLAG_PATH ]; then - cp $SYSTEM_PATH/dat/boot_logo.bmp.gz /misc - fi - # charging graphic, only installed, never updated - if [ ! -f /misc/charging.png ]; then - cp $SYSTEM_PATH/dat/charging.png /misc - fi - - touch $FLAG_PATH - sync && reboot -fi - -# } &> /mnt/sdcard/install.txt diff --git a/workspace/_unmaintained/rg35xx/keymon/credits.txt b/workspace/_unmaintained/rg35xx/keymon/credits.txt deleted file mode 100644 index e885e5dd1..000000000 --- a/workspace/_unmaintained/rg35xx/keymon/credits.txt +++ /dev/null @@ -1,3 +0,0 @@ -based on eggs custom keymon for Trimui: - https://www.dropbox.com/sh/5e9xwvp672vt8cr/AABUIdw1vLYp9h0waoCUqHPOa/source?dl=0&subfolder_nav_tracking=1 -modified to use libmsettings \ No newline at end of file diff --git a/workspace/_unmaintained/rg35xx/keymon/keymon.c b/workspace/_unmaintained/rg35xx/keymon/keymon.c deleted file mode 100644 index 94d8bbb22..000000000 --- a/workspace/_unmaintained/rg35xx/keymon/keymon.c +++ /dev/null @@ -1,168 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include "defines.h" - -// for ev.value -#define RELEASED 0 -#define PRESSED 1 -#define REPEAT 2 - -#define INPUT_COUNT 2 -static int inputs[INPUT_COUNT]; -static struct input_event ev; - -static pthread_t ports_pt; - -#define JACK_STATE_PATH "/sys/class/switch/h2w/state" -#define BACKLIGHT_PATH "/sys/class/backlight/backlight.2/bl_power" - -int getInt(char* path) { - int i = 0; - FILE *file = fopen(path, "r"); - if (file!=NULL) { - fscanf(file, "%i", &i); - fclose(file); - } - return i; -} - -static void* watchPorts(void *arg) { - int has_headphones,had_headphones; - - has_headphones = had_headphones = getInt(JACK_STATE_PATH); - SetJack(has_headphones); - - while(1) { - sleep(1); - - has_headphones = getInt(JACK_STATE_PATH); - if (had_headphones!=has_headphones) { - had_headphones = has_headphones; - SetJack(has_headphones); - } - } - - return 0; -} - -int main (int argc, char *argv[]) { - InitSettings(); - pthread_create(&ports_pt, NULL, &watchPorts, NULL); - - char path[32]; - for (int i=0; i1000) ignore = 1; // ignore input that arrived during sleep - - for (int i=0; i REPEAT )) continue; - switch (ev.code) { - case CODE_MENU: - menu_pressed = val; - break; - case CODE_POWER: - power_pressed = val; - break; - case CODE_PLUS: - up_pressed = up_just_pressed = val; - if (val) up_repeat_at = now + 300; - break; - case CODE_MINUS: - down_pressed = down_just_pressed = val; - if (val) down_repeat_at = now + 300; - break; - default: - break; - } - } - } - - if (ignore) { - menu_pressed = 0; - power_pressed = 0; - up_pressed = up_just_pressed = 0; - down_pressed = down_just_pressed = 0; - up_repeat_at = 0; - down_repeat_at = 0; - } - - if (up_just_pressed || (up_pressed && now>=up_repeat_at)) { - if (menu_pressed) { - val = GetBrightness(); - if (val=down_repeat_at)) { - if (menu_pressed) { - val = GetBrightness(); - if (val>BRIGHTNESS_MIN) SetBrightness(--val); - } - else { - val = GetVolume(); - if (val>VOLUME_MIN) SetVolume(--val); - } - - if (down_just_pressed) down_just_pressed = 0; - else down_repeat_at += 100; - } - - then = now; - ignore = 0; - - usleep(16666); // 60fps - } -} diff --git a/workspace/_unmaintained/rg35xx/keymon/makefile b/workspace/_unmaintained/rg35xx/keymon/makefile deleted file mode 100755 index 0212b6bbc..000000000 --- a/workspace/_unmaintained/rg35xx/keymon/makefile +++ /dev/null @@ -1,16 +0,0 @@ -#keymon - -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif - -TARGET = keymon - -CC = $(CROSS_COMPILE)gcc -CFLAGS = -Os -lmsettings -lpthread -lrt -ldl -Wl,--gc-sections -s -CFLAGS += -I. -I../../all/common -I../platform/ -DPLATFORM=\"$(UNION_PLATFORM)\" - -all: - $(CC) $(TARGET).c -o $(TARGET).elf $(CFLAGS) -clean: - rm -rf $(TARGET).elf \ No newline at end of file diff --git a/workspace/_unmaintained/rg35xx/libmsettings/makefile b/workspace/_unmaintained/rg35xx/libmsettings/makefile deleted file mode 100644 index b1418a21d..000000000 --- a/workspace/_unmaintained/rg35xx/libmsettings/makefile +++ /dev/null @@ -1,32 +0,0 @@ -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif -ifeq (,$(PREFIX)) -$(error missing PREFIX for this toolchain) -endif - -TARGET=msettings - -.PHONY: build -.PHONY: clean - -CC = $(CROSS_COMPILE)gcc - -SYSROOT := $(shell $(CC) --print-sysroot) - -INCLUDEDIR = $(SYSROOT)/usr/include -CFLAGS = -I$(INCLUDEDIR) -LDFLAGS = -ldl -lrt -s - -OPTM=-Ofast - -build: - $(CC) -c -Werror -fpic "$(TARGET).c" -Wl,--no-as-needed $(LDFLAGS) - $(CC) -shared -o "lib$(TARGET).so" "$(TARGET).o" $(LDFLAGS) - cp "$(TARGET).h" "$(PREFIX)/include" - cp "lib$(TARGET).so" "$(PREFIX)/lib" -clean: - rm -f *.o - rm -f "lib$(TARGET).so" - rm -f $(PREFIX)/include/$(TARGET).h - rm -f $(PREFIX)/lib/lib$(TARGET).so \ No newline at end of file diff --git a/workspace/_unmaintained/rg35xx/libmsettings/msettings.c b/workspace/_unmaintained/rg35xx/libmsettings/msettings.c deleted file mode 100644 index 0d36a17e9..000000000 --- a/workspace/_unmaintained/rg35xx/libmsettings/msettings.c +++ /dev/null @@ -1,163 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "msettings.h" - -/////////////////////////////////////// - -#define SETTINGS_VERSION 2 -typedef struct Settings { - int version; // future proofing - int brightness; - int headphones; - int speaker; - int unused[2]; // for future use - // NOTE: doesn't really need to be persisted but still needs to be shared - int jack; -} Settings; -static Settings DefaultSettings = { - .version = SETTINGS_VERSION, - .brightness = 2, - .headphones = 4, - .speaker = 8, - .jack = 0, -}; -static Settings* settings; - -#define SHM_KEY "/SharedSettings" -static char SettingsPath[256]; -static int shm_fd = -1; -static int is_host = 0; -static int shm_size = sizeof(Settings); - -#define BACKLIGHT_PATH "/sys/class/backlight/backlight.2/bl_power" -#define BRIGHTNESS_PATH "/sys/class/backlight/backlight.2/brightness" -#define VOLUME_PATH "/sys/class/volume/value" - -void InitSettings(void) { - sprintf(SettingsPath, "%s/msettings.bin", getenv("USERDATA_PATH")); - - shm_fd = shm_open(SHM_KEY, O_RDWR | O_CREAT | O_EXCL, 0644); // see if it exists - if (shm_fd==-1 && errno==EEXIST) { // already exists - puts("Settings client"); - shm_fd = shm_open(SHM_KEY, O_RDWR, 0644); - settings = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); - } - else { // host - puts("Settings host"); // keymon - is_host = 1; - // we created it so set initial size and populate - ftruncate(shm_fd, shm_size); - settings = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); - - int fd = open(SettingsPath, O_RDONLY); - if (fd>=0) { - read(fd, settings, shm_size); - // TODO: use settings->version for future proofing? - close(fd); - } - else { - // load defaults - memcpy(settings, &DefaultSettings, shm_size); - } - - // these shouldn't be persisted - // settings->jack = 0; - } - printf("brightness: %i\nspeaker: %i \n", settings->brightness, settings->speaker); - - SetVolume(GetVolume()); - SetBrightness(GetBrightness()); -} -void QuitSettings(void) { - munmap(settings, shm_size); - if (is_host) shm_unlink(SHM_KEY); -} -static inline void SaveSettings(void) { - int fd = open(SettingsPath, O_CREAT|O_WRONLY, 0644); - if (fd>=0) { - write(fd, settings, shm_size); - close(fd); - sync(); - } -} - -int GetBrightness(void) { // 0-10 - return settings->brightness; -} -void SetBrightness(int value) { - int raw; - switch (value) { - case 0: raw=16; break; // 0 - case 1: raw=24; break; // 8 - case 2: raw=40; break; // 16 - case 3: raw=64; break; // 24 - case 4: raw=128; break; // 64 - case 5: raw=192; break; // 64 - case 6: raw=256; break; // 64 - case 7: raw=384; break; // 128 - case 8: raw=512; break; // 128 - case 9: raw=768; break; // 256 - case 10: raw=1024; break; // 256 - } - SetRawBrightness(raw); - settings->brightness = value; - SaveSettings(); -} - -int GetVolume(void) { // 0-20 - return settings->jack ? settings->headphones : settings->speaker; -} -void SetVolume(int value) { - if (settings->jack) settings->headphones = value; - else settings->speaker = value; - - int raw = value * 2; - SetRawVolume(raw); - SaveSettings(); -} - -void SetRawBrightness(int val) { // 0 - 1024 - // printf("SetRawBrightness(%i)\n", val); fflush(stdout); - int fd = open(BRIGHTNESS_PATH, O_WRONLY); - if (fd>=0) { - dprintf(fd,"%d",val); - close(fd); - } -} -void SetRawVolume(int val) { // 0 - 40 - int fd = open(VOLUME_PATH, O_WRONLY); - if (fd>=0) { - dprintf(fd,"%d",val); - close(fd); - } -} - -// monitored and set by thread in keymon -int GetJack(void) { - return settings->jack; -} -void SetJack(int value) { - // printf("SetJack(%i)\n", value); fflush(stdout); - - settings->jack = value; - SetVolume(GetVolume()); -} - -int GetHDMI(void) { - return 0; -} -void SetHDMI(int value) { - // buh -} - -int GetMute(void) { return 0; } -void SetMute(int value) {} diff --git a/workspace/_unmaintained/rg35xx/libmsettings/msettings.h b/workspace/_unmaintained/rg35xx/libmsettings/msettings.h deleted file mode 100644 index 47e5fb003..000000000 --- a/workspace/_unmaintained/rg35xx/libmsettings/msettings.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef __msettings_h__ -#define __msettings_h__ - -void InitSettings(void); -void QuitSettings(void); - -int GetBrightness(void); -int GetVolume(void); - -void SetRawBrightness(int value); // 0-1024 -void SetRawVolume(int value); // 0-40 - -void SetBrightness(int value); // 0-10 -void SetVolume(int value); // 0-20 - -int GetJack(void); -void SetJack(int value); // 0-1 - -int GetHDMI(void); -void SetHDMI(int value); // 0-1 - -int GetMute(void); -void SetMute(int value); // 0-1 - -#endif // __msettings_h__ diff --git a/workspace/_unmaintained/rg35xx/makefile b/workspace/_unmaintained/rg35xx/makefile deleted file mode 100644 index 0feb56382..000000000 --- a/workspace/_unmaintained/rg35xx/makefile +++ /dev/null @@ -1,32 +0,0 @@ -#rg35xx - -########################################################### - -ifeq (,$(PLATFORM)) -PLATFORM=$(UNION_PLATFORM) -endif - -ifeq (,$(PLATFORM)) -$(error please specify PLATFORM, eg. PLATFORM=trimui make) -endif - -########################################################### - -REQUIRES_COMMANDER=other/DinguxCommander - -all: readmes - cd ./overclock && make - cd ./boot && ./build.sh - -early: $(REQUIRES_COMMANDER) - cd other/DinguxCommander && make -j - -clean: - cd ./overclock && make clean - cd ./boot && rm -rf ./output - cd other/DinguxCommander && make clean - -$(REQUIRES_COMMANDER): - git clone --depth 1 --branch minui-rg35xx https://github.com/shauninman/DinguxCommander.git $(REQUIRES_COMMANDER) - -include ../all/readmes/makefile diff --git a/workspace/_unmaintained/rg35xx/other/.keep b/workspace/_unmaintained/rg35xx/other/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/workspace/_unmaintained/rg35xx/overclock/credits.txt b/workspace/_unmaintained/rg35xx/overclock/credits.txt deleted file mode 100644 index a428c9150..000000000 --- a/workspace/_unmaintained/rg35xx/overclock/credits.txt +++ /dev/null @@ -1,2 +0,0 @@ -based on eggs example code: - https://discord.com/channels/529983248114122762/1009790045303087125/1085260407788290168 \ No newline at end of file diff --git a/workspace/_unmaintained/rg35xx/overclock/makefile b/workspace/_unmaintained/rg35xx/overclock/makefile deleted file mode 100755 index 030c74aa5..000000000 --- a/workspace/_unmaintained/rg35xx/overclock/makefile +++ /dev/null @@ -1,16 +0,0 @@ -#overclock - -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif - -TARGET = overclock - -CC = $(CROSS_COMPILE)gcc -CFLAGS = -Os -lrt -ldl -Wl,--gc-sections -s -CFLAGS += -I. -DPLATFORM=\"$(UNION_PLATFORM)\" - -all: - $(CC) $(TARGET).c -o $(TARGET).elf $(CFLAGS) -clean: - rm -rf $(TARGET).elf \ No newline at end of file diff --git a/workspace/_unmaintained/rg35xx/overclock/overclock.c b/workspace/_unmaintained/rg35xx/overclock/overclock.c deleted file mode 100644 index c760c0cbb..000000000 --- a/workspace/_unmaintained/rg35xx/overclock/overclock.c +++ /dev/null @@ -1,109 +0,0 @@ -// -// cpu over/underclock (based on code from eggs) -// -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// -- 0xe64e v 1000000 : 700000 + (25000x12) / 0x0c 01100 1110[01100]1001110 -// - 0xe6ce v 1025000 : 700000 + (25000x13) / 0x0d 01101 1110[01101]1001110 -// 0xe84e v 1100000 : 700000 + (25000x16) / 0x10 10000 1110[10000]1001110 -// + 0xebce v 1275000 : 700000 + (25000x23) / 0x17 10111 1110[10111]1001110 -// ++ 0xedce v 1375000 : 700000 + (25000x27) / 0x1b 11011 1110[11011]1001110 -#define VOLTMIN (700000) -#define VOLTMAX (1400000) -#define VOLTMUL (25000) -void setcpuvolt(int volt) { - if (volt < VOLTMIN) volt = VOLTMIN; - else if (volt > VOLTMAX) volt = VOLTMAX; - volt = ((volt-VOLTMIN) / VOLTMUL)<<7; - - char str[16]; - sprintf(str, "11=%04x", 0xe04e | volt); - int fd_reg = open("/sys/class/i2c-adapter/i2c-1/1-0065/reg_dbg", O_WRONLY); - write(fd_reg, str, strlen(str)); - close(fd_reg); -} - -#define CMU_BASE (0xB0160000) -#define CLKMIN (192000) -#define CLKMAX (1524000) -#define CLKMUL (12000) -void setcpuclock(int clock) { - if (clock < CLKMIN) clock = CLKMIN; - else if (clock > CLKMAX) clock = CLKMAX; - clock = clock / CLKMUL; - - int fd_mem = open("/dev/mem", O_RDWR); - uint32_t* cmu_mem = mmap(0, 4, PROT_READ|PROT_WRITE, MAP_SHARED, fd_mem, CMU_BASE); - cmu_mem[0] = (cmu_mem[0] & 0xFFFFFF80) | clock; - munmap(cmu_mem, 4); - close(fd_mem); -} - -void setcpu(int clock, int volt) { - setcpuvolt(VOLTMAX); // Temporarily maximize - setcpuclock(clock); - setcpuvolt(volt); -} - -// clk 240000 volt 975000 -// clk 504000 volt 1000000 -// clk 720000 volt 1025000 -// clk 1008000 volt 1100000 -// clk 1296000 volt 1275000 -// clk 1488000 volt 1375000 - -static struct cpu_opp { - int clk; - int volt; - char* desc; -} cpu_opps[] = { - {1488000, 1375000}, // 1.5GHz, NextUI Performance + launch - {1392000, 1325000}, // 1.4GHz - {1296000, 1275000}, // 1.3GHz, NextUI Normal - {1200000, 1200000}, // 1.2GHz - {1104000, 1175000}, // 1.1GHz, NextUI Powersave - {1008000, 1100000}, // 1.0GHz, Anbernic default max, overvolted to stabilize - { 840000, 1075000}, // 840MHz, overvolted to stabilize - { 720000, 1025000}, // 720MHz, overvolted to stabilize - { 504000, 1000000}, // 500MHz, overvolted to stabilize, NextUI menus - { 240000, 975000}, // 240MHz, overvolted to stabilize - { 0, 0}, -}; - -int main(int argc, char* argv[]) { - if (argc<2) { - printf("Usage: %s \n", argv[0]); - for (int i=0; cpu_opps[i].clk; i++) { - printf(" %8i\n", cpu_opps[i].clk); - } - return 0; - } - - int clk = 1008000; // default - char *p; - errno = 0; - long arg = strtol(argv[1], &p, 10); - - if (errno != 0 || *p != '\0' || arg > INT_MAX || arg < INT_MIN); // buh - else clk = arg; - - for (int i=0; cpu_opps[i].clk; i++) { - struct cpu_opp* cpu = &cpu_opps[i]; - if (clk>=cpu->clk) { - setcpu( cpu->clk, cpu->volt ); - char cmd[128]; - sprintf(cmd, "echo %i > /tmp/cpu_freq\n", cpu->clk); - system(cmd); - break; - } - } - return 0; -} diff --git a/workspace/_unmaintained/rg35xx/platform/de_atm7059.h b/workspace/_unmaintained/rg35xx/platform/de_atm7059.h deleted file mode 100755 index ca06ab514..000000000 --- a/workspace/_unmaintained/rg35xx/platform/de_atm7059.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * linux/drivers/video/owl/dss/de_atm7059.h - * - * NOTE: SHOULD only be included by de_atm7059.c - * - * Copyright (C) 2014 Actions - * Author: lipeng - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ - -#ifndef _DE_ATM7059_H_ -#define _DE_ATM7059_H_ - -//#include "de.h" - -/*================================================================ - * Definition of registers and bit position - *==============================================================*/ - - -/* please fixme */ -#define DE_SIZE_BIT_WIDTH 12 - -/* - * DE common registers - */ -#define DE_IRQSTATUS 0x0004 -#define DE_IRQENABLE 0x0000 -#define DE_IF_CON 0x000c - -#define DE_MMU_EN 0x0010 -#define DE_MMU_BASE 0x0014 - -#define DE_OUTPUT_CON 0x1000 -#define DE_OUTPUT_STAT 0x100c -#define DE_WB_CON 0x1004 -#define DE_WB_ADDR 0x1008 - -/* dither for path0, only for ATM7059A */ -#define DE_PATH_DITHER 0x150 - -/* - * dehw manager/channel specific registers - */ -#define DE_PATH_BASE 0x0100 -#define DE_PATH_CTL(n) (DE_PATH_BASE + (n) * 0x100 + 0x0000) - -#define DE_PATH_EN(n) DE_PATH_CTL(n) -#define DE_PATH_ENABLE_BIT 28 - -#define DE_PATH_FCR(n) DE_PATH_CTL(n) -#define DE_PATH_BK(n) (DE_PATH_BASE + (n) * 0x100 + 0x0020) -#define DE_PATH_SIZE(n) (DE_PATH_BASE + (n) * 0x100 + 0x0024) -#define DE_PATH_E_COOR(n) (DE_PATH_BASE + (n) * 0x100 + 0x0028) - -#define DE_PATH_GAMMA_IDX(n) (DE_PATH_BASE + (n) * 0x100 + 0x002C) -#define DE_PATH_GAMMA_IDX_BUSY_BIT (14) -#define DE_PATH_GAMMA_IDX_OP_SEL_BEGIN_BIT (12) -#define DE_PATH_GAMMA_IDX_OP_SEL_END_BIT (13) -#define DE_PATH_GAMMA_IDX_INDEX_BEGIN_BIT (0) -#define DE_PATH_GAMMA_IDX_INDEX_END_BIT (7) - -#define DE_PATH_GAMMA_RAM(n) (DE_PATH_BASE + (n) * 0x100 + 0x0030) - -#define DE_PATH_CURSOR_FB(n) (DE_PATH_BASE + (n) * 0x100 + 0x0034) -#define DE_PATH_CURSOR_STR(n) (DE_PATH_BASE + (n) * 0x100 + 0x0038) - -/* DE overlay registers */ -#define DE_OVL_BASE 0x0400 -#define DE_OVL_CFG(n) (DE_OVL_BASE + (n) * 0x100 + 0x0000) -#define DE_OVL_ISIZE(n) (DE_OVL_BASE + (n) * 0x100 + 0x0004) -#define DE_OVL_OSIZE(n) (DE_OVL_BASE + (n) * 0x100 + 0x0008) -#define DE_OVL_SR(n) (DE_OVL_BASE + (n) * 0x100 + 0x000c) -#define DE_OVL_SCOEF0(n) (DE_OVL_BASE + (n) * 0x100 + 0x0010) -#define DE_OVL_SCOEF1(n) (DE_OVL_BASE + (n) * 0x100 + 0x0014) -#define DE_OVL_SCOEF2(n) (DE_OVL_BASE + (n) * 0x100 + 0x0018) -#define DE_OVL_SCOEF3(n) (DE_OVL_BASE + (n) * 0x100 + 0x001c) -#define DE_OVL_SCOEF4(n) (DE_OVL_BASE + (n) * 0x100 + 0x0020) -#define DE_OVL_SCOEF5(n) (DE_OVL_BASE + (n) * 0x100 + 0x0024) -#define DE_OVL_SCOEF6(n) (DE_OVL_BASE + (n) * 0x100 + 0x0028) -#define DE_OVL_SCOEF7(n) (DE_OVL_BASE + (n) * 0x100 + 0x002c) -#define DE_OVL_BA0(n) (DE_OVL_BASE + (n) * 0x100 + 0x0030) -#define DE_OVL_BA1UV(n) (DE_OVL_BASE + (n) * 0x100 + 0x0034) -#define DE_OVL_BA2V(n) (DE_OVL_BASE + (n) * 0x100 + 0x0038) -#define DE_OVL_3D_RIGHT_BA0(n) (DE_OVL_BASE + (n) * 0x100 + 0x003C) -#define DE_OVL_3D_RIGHT_BA1UV(n) (DE_OVL_BASE + (n) * 0x100 + 0x0040) -#define DE_OVL_3D_RIGHT_BA2V(n) (DE_OVL_BASE + (n) * 0x100 + 0x0044) -#define DE_OVL_STR(n) (DE_OVL_BASE + (n) * 0x100 + 0x0048) -#define DE_OVL_CRITICAL_CFG(n) (DE_OVL_BASE + (n) * 0x100 + 0x004c) -#define DE_OVL_REMAPPING(n) (DE_OVL_BASE + (n) * 0x100 + 0x0050) -#define DE_OVL_CKMAX(n) (DE_OVL_BASE + (n) * 0x100 + 0x005c) -#define DE_OVL_CKMIN(n) (DE_OVL_BASE + (n) * 0x100 + 0x0060) -#define DE_OVL_BLEND(n) (DE_OVL_BASE + (n) * 0x100 + 0x0064) - -#define DE_OVL_COOR(m, n) (DE_OVL_BASE + (n) * 0x100 + 0x0054) -#define DE_OVL_ALPHA_CFG(m, n) (DE_OVL_BASE + (n) * 0x100 + 0x0058) -#define DE_OVL_ALPHA_ENABLE(m, n) DE_OVL_BLEND(n) -#define DE_PATH_GAMMA_ENABLE(n) DE_PATH_CTL(n) -#define DE_PATH_GAMMA_ENABLE_BIT (9) - -#define DE_OVL_CSC(n) DE_OVL_CFG(n) -#define DE_OVL_CSC_CON_BEGIN_BIT 4 -#define DE_OVL_CSC_CON_END_BIT 7 -#define DE_OVL_CSC_STA_BEGIN_BIT 8 -#define DE_OVL_CSC_STA_END_BIT 11 -#define DE_OVL_CSC_BRI_BEGIN_BIT 12 -#define DE_OVL_CSC_BRI_END_BIT 19 -#define DE_OVL_CSC_BYPASS_BIT 0 - -#define DE_OVL_CFG_FLIP_BIT 20 -#define DE_OVL_CFG_FMT_BEGIN_BIT 0 -#define DE_OVL_CFG_FMT_END_BIT 2 -#define DE_OVL_CFG_BYPASS_BIT 3 -#define DE_OVL_CFG_CONTRAST_BEGIN_BIT 4 -#define DE_OVL_CFG_CONTRAST_END_BIT 7 -#define DE_OVL_CFG_SATURATION_BEGIN_BIT 8 -#define DE_OVL_CFG_SATURATION_END_BIT 11 -#define DE_OVL_CFG_LIGHTNESS_BEGIN_BIT 12 -#define DE_OVL_CFG_LIGHTNESS_END_BIT 19 -#define DE_OVL_CFG_CRITICAL_CTL_BEGIN_BIT 26 -#define DE_OVL_CFG_CRITICAL_CTL_END_BIT 27 - -#define DE_OVL_ALPHA_CFG_PRE_MUTI_BIT 8 -#define DE_OVL_ALPHA_CFG_VALUE_BEGIN_BIT 0 -#define DE_OVL_ALPHA_CFG_VALUE_END_BIT 7 -#define DE_OVL_ALPHA_CFG_ENABLE_BEGIN_BIT 0 -#define DE_OVL_ALPHA_CFG_ENABLE_END_BIT 0 - -#define DE_OUTPUT_PATH1_DEVICE_BEGIN_BIT 0 -#define DE_OUTPUT_PATH1_DEVICE_END_BIT 2 -#define DE_OUTPUT_PATH2_DEVICE_BEGIN_BIT 4 -#define DE_OUTPUT_PATH2_DEVICE_END_BIT 6 - -#define DE_PATH_CTL_IYUV_QEN_BIT 16 -#define DE_PATH_CTL_YUV_FMT_BIT 15 -#define DE_PATH_CTL_ILACE_BIT 11 -#define DE_PATH_CTL_GAMMA_ENABLE_BIT 9 - -#define DE_PANEL_ENABLE_BIT 20 -#define DE_PANEL_CURSOR_ENABLE_BIT 24 -#define DE_PATH_FCR_BIT 29 - -#endif diff --git a/workspace/_unmaintained/rg35xx/platform/ion-owl.h b/workspace/_unmaintained/rg35xx/platform/ion-owl.h deleted file mode 100755 index cbe732e45..000000000 --- a/workspace/_unmaintained/rg35xx/platform/ion-owl.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * include/linux/ion-owl.h - * - * Copyright 2012 Actions Semi Inc. - * Author: Actions Semi, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#if !defined(__KERNEL__) -#define __user -#endif - -#ifndef _UAPI_LINUX_ION_OWL_H -#define _UAPI_LINUX_ION_OWL_H - -#include - -/* for cmd OWL_ION_GET_PHY */ -struct owl_ion_phys_data { - ion_user_handle_t handle; - unsigned long phys_addr; - size_t size; -}; - -/* Custom Ioctl's. */ -enum { - OWL_ION_GET_PHY = 0, -}; - -/** - * These are the only ids that should be used for Ion heap ids. - * The ids listed are the order in which allocation will be attempted - * if specified. Don't swap the order of heap ids unless you know what - * you are doing! - * Id's are spaced by purpose to allow new Id's to be inserted in-between (for - * possible fallbacks) - */ - -enum ion_heap_ids { - ION_HEAP_ID_INVALID = -1, - ION_HEAP_ID_PMEM = 0, - ION_HEAP_ID_FB = 8, - ION_HEAP_ID_SYSTEM = 12, - ION_HEAP_ID_RESERVED = 31 /** Bit reserved for ION_SECURE flag */ -}; - -#endif /* _UAPI_LINUX_ION_OWL_H */ diff --git a/workspace/_unmaintained/rg35xx/platform/ion.h b/workspace/_unmaintained/rg35xx/platform/ion.h deleted file mode 100755 index eafcc0333..000000000 --- a/workspace/_unmaintained/rg35xx/platform/ion.h +++ /dev/null @@ -1,240 +0,0 @@ -/* - * drivers/staging/android/uapi/ion.h - * - * Copyright (C) 2011 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _UAPI_LINUX_ION_H -#define _UAPI_LINUX_ION_H - -#include -#include - -typedef int ion_user_handle_t; - -/** - * enum ion_heap_types - list of all possible types of heaps - * @ION_HEAP_TYPE_SYSTEM: memory allocated via vmalloc - * @ION_HEAP_TYPE_SYSTEM_CONTIG: memory allocated via kmalloc - * @ION_HEAP_TYPE_CARVEOUT: memory allocated from a prereserved - * carveout heap, allocations are physically - * contiguous - * @ION_HEAP_TYPE_DMA: memory allocated via DMA API - * @ION_NUM_HEAPS: helper for iterating over heaps, a bit mask - * is used to identify the heaps, so only 32 - * total heap types are supported - */ -enum ion_heap_type { - ION_HEAP_TYPE_SYSTEM, - ION_HEAP_TYPE_SYSTEM_CONTIG, - ION_HEAP_TYPE_CARVEOUT, - ION_HEAP_TYPE_CHUNK, - ION_HEAP_TYPE_DMA, - ION_HEAP_TYPE_CUSTOM, /* must be last so device specific heaps always - are at the end of this enum */ - ION_NUM_HEAPS = 16, -}; - -#define ION_HEAP_SYSTEM_MASK (1 << ION_HEAP_TYPE_SYSTEM) -#define ION_HEAP_SYSTEM_CONTIG_MASK (1 << ION_HEAP_TYPE_SYSTEM_CONTIG) -#define ION_HEAP_CARVEOUT_MASK (1 << ION_HEAP_TYPE_CARVEOUT) -#define ION_HEAP_TYPE_DMA_MASK (1 << ION_HEAP_TYPE_DMA) - -#define ION_NUM_HEAP_IDS sizeof(unsigned int) * 8 - -/** - * allocation flags - the lower 16 bits are used by core ion, the upper 16 - * bits are reserved for use by the heaps themselves. - */ -#define ION_FLAG_CACHED 1 /* mappings of this buffer should be - cached, ion will do cache - maintenance when the buffer is - mapped for dma */ -#define ION_FLAG_CACHED_NEEDS_SYNC 2 /* mappings of this buffer will created - at mmap time, if this is set - caches must be managed manually */ - -/** - * DOC: Ion Userspace API - * - * create a client by opening /dev/ion - * most operations handled via following ioctls - * - */ - -/** - * struct ion_allocation_data - metadata passed from userspace for allocations - * @len: size of the allocation - * @align: required alignment of the allocation - * @heap_id_mask: mask of heap ids to allocate from - * @flags: flags passed to heap - * @handle: pointer that will be populated with a cookie to use to - * refer to this allocation - * - * Provided by userspace as an argument to the ioctl - */ -struct ion_allocation_data { - size_t len; - size_t align; - unsigned int heap_id_mask; - unsigned int flags; - ion_user_handle_t handle; -}; - -/** - * struct ion_fd_data - metadata passed to/from userspace for a handle/fd pair - * @handle: a handle - * @fd: a file descriptor representing that handle - * - * For ION_IOC_SHARE or ION_IOC_MAP userspace populates the handle field with - * the handle returned from ion alloc, and the kernel returns the file - * descriptor to share or map in the fd field. For ION_IOC_IMPORT, userspace - * provides the file descriptor and the kernel returns the handle. - */ -struct ion_fd_data { - ion_user_handle_t handle; - int fd; -}; - -/** - * struct ion_handle_data - a handle passed to/from the kernel - * @handle: a handle - */ -struct ion_handle_data { - ion_user_handle_t handle; -}; - -/** - * struct ion_custom_data - metadata passed to/from userspace for a custom ioctl - * @cmd: the custom ioctl function to call - * @arg: additional data to pass to the custom ioctl, typically a user - * pointer to a predefined structure - * - * This works just like the regular cmd and arg fields of an ioctl. - */ -struct ion_custom_data { - unsigned int cmd; - unsigned long arg; -}; - -/** struct ion_flush_data - data passed to ion for flushing caches - * - * @handle: handle with data to flush - * @fd: fd to flush - * @vaddr: userspace virtual address mapped with mmap - * @offset: offset into the handle to flush - * @length: length of handle to flush - * - * Performs cache operations on the handle. If p is the start address - * of the handle, p + offset through p + offset + length will have - * the cache operations performed - */ -struct ion_flush_data { - void *handle; /* no used, kept for compatibility */ - int fd; - void *vaddr; - unsigned int offset; - unsigned int length; -}; - -#define ION_IOC_MAGIC 'I' - -/** - * DOC: ION_IOC_ALLOC - allocate memory - * - * Takes an ion_allocation_data struct and returns it with the handle field - * populated with the opaque handle for the allocation. - */ -#define ION_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, \ - struct ion_allocation_data) - -/** - * DOC: ION_IOC_FREE - free memory - * - * Takes an ion_handle_data struct and frees the handle. - */ -#define ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data) - -/** - * DOC: ION_IOC_MAP - get a file descriptor to mmap - * - * Takes an ion_fd_data struct with the handle field populated with a valid - * opaque handle. Returns the struct with the fd field set to a file - * descriptor open in the current address space. This file descriptor - * can then be used as an argument to mmap. - */ -#define ION_IOC_MAP _IOWR(ION_IOC_MAGIC, 2, struct ion_fd_data) - -/** - * DOC: ION_IOC_SHARE - creates a file descriptor to use to share an allocation - * - * Takes an ion_fd_data struct with the handle field populated with a valid - * opaque handle. Returns the struct with the fd field set to a file - * descriptor open in the current address space. This file descriptor - * can then be passed to another process. The corresponding opaque handle can - * be retrieved via ION_IOC_IMPORT. - */ -#define ION_IOC_SHARE _IOWR(ION_IOC_MAGIC, 4, struct ion_fd_data) - -/** - * DOC: ION_IOC_IMPORT - imports a shared file descriptor - * - * Takes an ion_fd_data struct with the fd field populated with a valid file - * descriptor obtained from ION_IOC_SHARE and returns the struct with the handle - * filed set to the corresponding opaque handle. - */ -#define ION_IOC_IMPORT _IOWR(ION_IOC_MAGIC, 5, struct ion_fd_data) - -/** - * DOC: ION_IOC_SYNC - syncs a shared file descriptors to memory - * - * Deprecated in favor of using the dma_buf api's correctly (syncing - * will happend automatically when the buffer is mapped to a device). - * If necessary should be used after touching a cached buffer from the cpu, - * this will make the buffer in memory coherent. - */ -#define ION_IOC_SYNC _IOWR(ION_IOC_MAGIC, 7, struct ion_fd_data) - -/** - * DOC: ION_IOC_CUSTOM - call architecture specific ion ioctl - * - * Takes the argument of the architecture specific ioctl to call and - * passes appropriate userdata for that ioctl - */ -#define ION_IOC_CUSTOM _IOWR(ION_IOC_MAGIC, 6, struct ion_custom_data) - - -/** - * DOC: ION_IOC_CLEAN_CACHES - clean the caches - * - * Clean the caches of the handle specified. - */ -#define ION_IOC_CLEAN_CACHES _IOWR(ION_IOC_MAGIC, 20, \ - struct ion_flush_data) -/** - * DOC: ION_MSM_IOC_INV_CACHES - invalidate the caches - * - * Invalidate the caches of the handle specified. - */ -#define ION_IOC_INV_CACHES _IOWR(ION_IOC_MAGIC, 21, \ - struct ion_flush_data) -/** - * DOC: ION_MSM_IOC_CLEAN_CACHES - clean and invalidate the caches - * - * Clean and invalidate the caches of the handle specified. - */ -#define ION_IOC_CLEAN_INV_CACHES _IOWR(ION_IOC_MAGIC, 22, \ - struct ion_flush_data) - - -#endif /* _UAPI_LINUX_ION_H */ diff --git a/workspace/_unmaintained/rg35xx/platform/makefile.copy b/workspace/_unmaintained/rg35xx/platform/makefile.copy deleted file mode 100644 index 1eb41406f..000000000 --- a/workspace/_unmaintained/rg35xx/platform/makefile.copy +++ /dev/null @@ -1,14 +0,0 @@ -$(PLATFORM): - # $@ - cp ./workspace/$@/overclock/overclock.elf ./build/SYSTEM/$@/bin/ - mkdir -p ./build/BASE/$@ - cp ./workspace/$@/boot/output/dmenu.bin ./build/BASE/$@/ - cp ./workspace/$@/boot/output/dmenu.bin ./build/SYSTEM/$@/dat/ - cp ./workspace/$@/boot/output/boot_logo.bmp.gz ./build/SYSTEM/$@/dat/ - cp ./workspace/$@/boot/output/rootfs.ext2 ./build/SYSTEM/$@/ - cp ./workspace/$@/install/install.sh ./build/SYSTEM/$@/bin/ - cp ./workspace/$@/ramdisk/patched-ramdisk.img ./build/SYSTEM/$@/dat/ramdisk.img - cp ./workspace/$@/ramdisk/charging.png ./build/SYSTEM/$@/dat/ - # extras - cp ./workspace/$@/other/DinguxCommander/output/DinguxCommander ./build/EXTRAS/Tools/$@/Files.pak/ - cp -r ./workspace/$@/other/DinguxCommander/res ./build/EXTRAS/Tools/$@/Files.pak/ diff --git a/workspace/_unmaintained/rg35xx/platform/makefile.env b/workspace/_unmaintained/rg35xx/platform/makefile.env deleted file mode 100644 index f99d44f03..000000000 --- a/workspace/_unmaintained/rg35xx/platform/makefile.env +++ /dev/null @@ -1,4 +0,0 @@ -# rg35xx -ARCH = -marm -mtune=cortex-a9 -mfpu=neon-fp16 -mfloat-abi=hard -march=armv7-a -LIBS = -SDL = SDL2 \ No newline at end of file diff --git a/workspace/_unmaintained/rg35xx/platform/platform.c b/workspace/_unmaintained/rg35xx/platform/platform.c deleted file mode 100644 index 01fa2df88..000000000 --- a/workspace/_unmaintained/rg35xx/platform/platform.c +++ /dev/null @@ -1,603 +0,0 @@ -// rg35xx -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include "defines.h" -#include "platform.h" -#include "api.h" -#include "utils.h" - -#include "ion.h" -#include "ion-owl.h" -#include "de_atm7059.h" -#include "scaler.h" - -/////////////////////////////// - -void PLAT_initInput(void) { - // buh -} -void PLAT_quitInput(void) { - // buh -} - -/////////////////////////////// - -typedef struct ion_alloc_info { - uint32_t size; - struct ion_handle *handle; - int fd; - void* padd; - void* vadd; -} ion_alloc_info_t; -static void ion_alloc(int fd_ion, ion_alloc_info_t* info) { - struct ion_allocation_data iad; - struct ion_fd_data ifd; - struct ion_custom_data icd; - struct owl_ion_phys_data ipd; - - iad.len = info->size; - iad.align = sysconf(_SC_PAGESIZE); - iad.heap_id_mask = (1<handle = (void*)iad.handle; - info->fd = ifd.fd; - info->padd = (void*)ipd.phys_addr; - info->vadd = mmap(0, info->size, PROT_READ|PROT_WRITE, MAP_SHARED, info->fd, 0); - -} -static void ion_free(int fd_ion, ion_alloc_info_t* info) { - struct ion_handle_data ihd; - munmap(info->vadd, info->size); - close(info->fd); - ihd.handle = (uintptr_t)info->handle; - if (ioctl(fd_ion, ION_IOC_FREE, &ihd)<0) fprintf(stderr, "ION_FREE failed %s\n",strerror(errno)); - fflush(stdout); -} - -/////////////////////////////// - -#define DE (0xB02E0000) -#define DE_SIZE (0x00002000) -static int de_enable_overlay = 0; -enum { - DE_SCOEF_NONE, - DE_SCOEF_CRISPY, - DE_SCOEF_ZOOMIN, - DE_SCOEF_HALF_ZOOMOUT, - DE_SCOEF_SMALLER_ZOOMOUT, - DE_SCOEF_MAX -}; -static void DE_setScaleCoef(uint32_t* de_mem, int plane, int scale) { - switch(scale) { - case DE_SCOEF_NONE: // for integer scale < L R > (0x40=100%) Applies to the following pixels: - de_mem[DE_OVL_SCOEF0(plane)/4]= 0x00400000; // L 100% R 0% - de_mem[DE_OVL_SCOEF1(plane)/4]= 0x00400000; // L 87.5% R 12.5% - de_mem[DE_OVL_SCOEF2(plane)/4]= 0x00400000; // L 75% R 25% - de_mem[DE_OVL_SCOEF3(plane)/4]= 0x00400000; // L 62.5% R 37.5% - de_mem[DE_OVL_SCOEF4(plane)/4]= 0x00004000; // L 50% R 50% - de_mem[DE_OVL_SCOEF5(plane)/4]= 0x00004000; // L 37.5% R 62.5% - de_mem[DE_OVL_SCOEF6(plane)/4]= 0x00004000; // L 25% R 75% - de_mem[DE_OVL_SCOEF7(plane)/4]= 0x00004000; // L 12.5% R 87.5% - break; - case DE_SCOEF_CRISPY: // crispy setting for upscale - de_mem[DE_OVL_SCOEF0(plane)/4]= 0x00400000; - de_mem[DE_OVL_SCOEF1(plane)/4]= 0x00400000; - de_mem[DE_OVL_SCOEF2(plane)/4]= 0x00400000; - de_mem[DE_OVL_SCOEF3(plane)/4]= 0x00400000; - de_mem[DE_OVL_SCOEF4(plane)/4]= 0x00202000; - de_mem[DE_OVL_SCOEF5(plane)/4]= 0x00004000; - de_mem[DE_OVL_SCOEF6(plane)/4]= 0x00004000; - de_mem[DE_OVL_SCOEF7(plane)/4]= 0x00004000; - break; - case DE_SCOEF_ZOOMIN: - de_mem[DE_OVL_SCOEF0(plane)/4]= 0x00400000; - de_mem[DE_OVL_SCOEF1(plane)/4]= 0xFC3E07FF; - de_mem[DE_OVL_SCOEF2(plane)/4]= 0xFA3810FE; - de_mem[DE_OVL_SCOEF3(plane)/4]= 0xF9301BFC; - de_mem[DE_OVL_SCOEF4(plane)/4]= 0xFA2626FA; - de_mem[DE_OVL_SCOEF5(plane)/4]= 0xFC1B30F9; - de_mem[DE_OVL_SCOEF6(plane)/4]= 0xFE1038FA; - de_mem[DE_OVL_SCOEF7(plane)/4]= 0xFF073EFC; - break; - case DE_SCOEF_HALF_ZOOMOUT: - de_mem[DE_OVL_SCOEF0(plane)/4]= 0x00400000; - de_mem[DE_OVL_SCOEF1(plane)/4]= 0x00380800; - de_mem[DE_OVL_SCOEF2(plane)/4]= 0x00301000; - de_mem[DE_OVL_SCOEF3(plane)/4]= 0x00281800; - de_mem[DE_OVL_SCOEF4(plane)/4]= 0x00202000; - de_mem[DE_OVL_SCOEF5(plane)/4]= 0x00182800; - de_mem[DE_OVL_SCOEF6(plane)/4]= 0x00103000; - de_mem[DE_OVL_SCOEF7(plane)/4]= 0x00083800; - break; - case DE_SCOEF_SMALLER_ZOOMOUT: - de_mem[DE_OVL_SCOEF0(plane)/4]= 0x10201000; - de_mem[DE_OVL_SCOEF1(plane)/4]= 0x0E1E1202; - de_mem[DE_OVL_SCOEF2(plane)/4]= 0x0C1C1404; - de_mem[DE_OVL_SCOEF3(plane)/4]= 0x0A1A1606; - de_mem[DE_OVL_SCOEF4(plane)/4]= 0x08181808; - de_mem[DE_OVL_SCOEF5(plane)/4]= 0x06161A0A; - de_mem[DE_OVL_SCOEF6(plane)/4]= 0x04141C0C; - de_mem[DE_OVL_SCOEF7(plane)/4]= 0x02121E0E; - break; - default: - break; - } -} -static void DE_enableLayer(uint32_t* de_mem) { - de_mem[DE_PATH_CTL(0)/4] = (de_enable_overlay?0x30300000:0x30100000) | (de_mem[DE_PATH_CTL(0)/4] & 0xCF0FFFFF); -} -static void DE_setRect(uint32_t* de_mem, int x, int y, int w, int h) { - de_mem[(DE_OVL_OSIZE(0))/4] = ((w-1)&0xFFFF) | ((h-1)<<16); - de_mem[(DE_OVL_SR(0))/4] = ((0x2000*((de_mem[(DE_OVL_ISIZE(0))/4]&0xFFFF)+1)/w)&0xFFFF) | - ((0x2000*((de_mem[(DE_OVL_ISIZE(0))/4]>>16)+1)/h)<<16); - de_mem[(DE_OVL_COOR(0,0))/4] = (y<<16) | (x&0xFFFF); -} - -/////////////////////////////// - -#define MAX_PRIVATE_DATA_SIZE 40 -struct owlfb_disp_device{ - __u32 mType; - __u32 mState; - __u32 mPluginState; - __u32 mWidth; - __u32 mHeight; - __u32 mRefreshRate; - __u32 mWidthScale; - __u32 mHeightScale; - __u32 mCmdMode; - __u32 mIcType; - __u32 mPrivateInfo[MAX_PRIVATE_DATA_SIZE]; -}; - -struct display_private_info { - int LCD_TYPE; // 1 - int LCD_LIGHTENESS; // 128 - int LCD_SATURATION; // 7 - int LCD_CONSTRAST; // 5 -}; - -enum CmdMode { - SET_LIGHTENESS = 0, - SET_SATURATION = 1, - SET_CONSTRAST = 2, - SET_DEFAULT = 3, -}; - -struct owlfb_sync_info { - __u8 enabled; - __u8 disp_id; - __u16 reserved2; -}; -enum owlfb_overlay_type { - OWLFB_OVERLAY_VIDEO = 1, - OWLFB_OVERLAY_CURSOR, -}; -enum owl_color_mode { - OWL_DSS_COLOR_RGB16 = 0, - OWL_DSS_COLOR_BGR16 = 1, - OWL_DSS_COLOR_ARGB32 = 4, - OWL_DSS_COLOR_ABGR32 = 5, - OWL_DSS_COLOR_RGBA32 = 6, - OWL_DSS_COLOR_BGRA32 = 7, - OWL_DSS_COLOR_NV21 = 8, - OWL_DSS_COLOR_NU21 = 9, - OWL_DSS_COLOR_YU12 = 10, - OWL_DSS_COLOR_ARGB16 = 12, - OWL_DSS_COLOR_ABGR16 = 13, - OWL_DSS_COLOR_RGBA16 = 14, - OWL_DSS_COLOR_BGRA16 = 15, - OWL_DSS_COLOR_RGB24U = 16, - OWL_DSS_COLOR_RGB24P = 17, - OWL_DSS_COLOR_RGBX32 = 18, - OWL_DSS_COLOR_NV12 = 19, - OWL_DSS_COLOR_XBGR32 = 20, - OWL_DSS_COLOR_XRGB32 = 21, -}; -struct owlfb_overlay_args { - __u16 fb_id; - __u16 overlay_id; - __u16 overlay_type; - __u32 overlay_mem_base; - __u32 overlay_mem_size; - __u32 uintptr_overly_info; -}; -struct owlfb_overlay_info { - __u32 mem_off; - __u32 mem_size; - __u32 screen_width; - enum owl_color_mode color_mode; - __u32 img_width; - __u32 img_height; - __u32 xoff; - __u32 yoff; - __u32 width; - __u32 height; - __u8 rotation; - __u32 pos_x; - __u32 pos_y; - __u32 out_width; - __u32 out_height; - __u8 lightness; - __u8 saturation; - __u8 contrast; - bool global_alpha_en; - __u8 global_alpha; - bool pre_mult_alpha_en; - __u8 zorder; -}; - -#define OWL_IOW(num, dtype) _IOW('O', num, dtype) -#define OWL_IOR(num, dtype) _IOR('O', num, dtype) -#define OWLFB_WAITFORVSYNC OWL_IOW(57, long long) -#define OWLFB_GET_DISPLAY_INFO OWL_IOW(74, struct owlfb_disp_device) -#define OWLFB_SET_DISPLAY_INFO OWL_IOW(75, struct owlfb_disp_device) -#define OWLFB_VSYNC_EVENT_EN OWL_IOW(67, struct owlfb_sync_info) -#define OWLFB_OVERLAY_REQUEST OWL_IOR(41, struct owlfb_overlay_args) -#define OWLFB_OVERLAY_RELEASE OWL_IOR(42, struct owlfb_overlay_args) -#define OWLFB_OVERLAY_ENABLE OWL_IOR(43, struct owlfb_overlay_args) -#define OWLFB_OVERLAY_DISABLE OWL_IOR(45, struct owlfb_overlay_args) -#define OWLFB_OVERLAY_GETINFO OWL_IOW(46, struct owlfb_overlay_args) -#define OWLFB_OVERLAY_SETINFO OWL_IOW(47, struct owlfb_overlay_args) - -/////////////////////////////// - -static struct VID_Context { - SDL_Surface* screen; - - int fd_fb; - int fd_ion; - int fd_mem; - - uint32_t* de_mem; - - struct fb_fix_screeninfo finfo; - struct fb_var_screeninfo vinfo; - ion_alloc_info_t fb_info; - - int page; - int width; - int height; - int pitch; - int cleared; -} vid; -static int _; - -SDL_Surface* PLAT_initVideo(void) { - SDL_Init(SDL_INIT_VIDEO); - SDL_ShowCursor(0); - SDL_SetVideoMode(0,0,FIXED_DEPTH,0); - - vid.fd_fb = open("/dev/fb0", O_RDWR); - vid.fd_ion = open("/dev/ion", O_RDWR); - vid.fd_mem = open("/dev/mem", O_RDWR); - vid.de_mem = mmap(0, DE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, vid.fd_mem, DE); - - ioctl(vid.fd_fb, FBIOGET_FSCREENINFO, &vid.finfo); - ioctl(vid.fd_fb, FBIOGET_VSCREENINFO, &vid.vinfo); - - struct owlfb_sync_info sinfo; - sinfo.enabled = 1; - sinfo.disp_id = 2; - if (ioctl(vid.fd_fb, OWLFB_VSYNC_EVENT_EN, &sinfo)<0) fprintf(stderr, "VSYNC_EVENT_EN failed %s\n",strerror(errno)); - - vid.page = 1; - vid.width = FIXED_WIDTH; - vid.height = FIXED_HEIGHT; - vid.pitch = FIXED_PITCH; - - vid.fb_info.size = PAGE_SIZE * PAGE_COUNT; - ion_alloc(vid.fd_ion, &vid.fb_info); - - vid.screen = SDL_CreateRGBSurfaceFrom(vid.fb_info.vadd+PAGE_SIZE, vid.width,vid.height,FIXED_DEPTH,vid.pitch, RGBA_MASK_AUTO); - memset(vid.screen->pixels, 0, vid.pitch * vid.height); - - int vw = (vid.de_mem[DE_PATH_SIZE(0)/4]&0xFFFF)+1; - int vh = (vid.de_mem[DE_PATH_SIZE(0)/4]>>16)+1; - - vid.de_mem[DE_OVL_ISIZE(0)/4] = vid.de_mem[DE_OVL_ISIZE(2)/4] = ((vid.width-1) & 0xFFFF) | ((vid.height-1) << 16); - vid.de_mem[DE_OVL_SR(0)/4] = vid.de_mem[DE_OVL_SR(2)/4] = ((0x2000*vid.width/vw)&0xFFFF) | ((0x2000*vid.height/vh)<<16); - vid.de_mem[DE_OVL_STR(0)/4] = vid.de_mem[DE_OVL_STR(2)/4] = vid.pitch / 8; - vid.de_mem[DE_OVL_BA0(0)/4] = (uintptr_t)(vid.fb_info.padd + PAGE_SIZE); - - GFX_setNearestNeighbor(0); // false? - - return vid.screen; -} - -void PLAT_quitVideo(void) { - ion_free(vid.fd_ion, &vid.fb_info); - munmap(vid.de_mem, DE_SIZE); - close(vid.fd_mem); - close(vid.fd_ion); - close(vid.fd_fb); - SDL_FreeSurface(vid.screen); - SDL_Quit(); -} - -void PLAT_clearVideo(SDL_Surface* screen) { - // this buffer is offscreen when cleared - memset(screen->pixels, 0, PAGE_SIZE); -} -void PLAT_clearAll(void) { - PLAT_clearVideo(vid.screen); // clear backbuffer - vid.cleared = 1; // defer clearing frontbuffer until offscreen -} - -void PLAT_setVsync(int vsync) { - // buh -} - -SDL_Surface* PLAT_resizeVideo(int w, int h, int pitch) { - vid.width = w; - vid.height = h; - vid.pitch = pitch; - - SDL_FreeSurface(vid.screen); - vid.screen = SDL_CreateRGBSurfaceFrom(vid.fb_info.vadd + vid.page*PAGE_SIZE, vid.width,vid.height,FIXED_DEPTH,vid.pitch, RGBA_MASK_AUTO); - memset(vid.screen->pixels, 0, vid.pitch * vid.height); - - int vw = (vid.de_mem[DE_PATH_SIZE(0)/4]&0xFFFF)+1; - int vh = (vid.de_mem[DE_PATH_SIZE(0)/4]>>16)+1; - - vid.de_mem[DE_OVL_ISIZE(0)/4] = vid.de_mem[DE_OVL_ISIZE(2)/4] = ((vid.width-1) & 0xFFFF) | ((vid.height-1) << 16); - vid.de_mem[DE_OVL_SR(0)/4] = vid.de_mem[DE_OVL_SR(2)/4] = ((0x2000*vid.width/vw)&0xFFFF) | ((0x2000*vid.height/vh)<<16); - vid.de_mem[DE_OVL_STR(0)/4] = vid.de_mem[DE_OVL_STR(2)/4] = vid.pitch / 8; - vid.de_mem[DE_OVL_BA0(0)/4] = (uintptr_t)(vid.fb_info.padd + vid.page * PAGE_SIZE); - - return vid.screen; -} - -void PLAT_setVideoScaleClip(int x, int y, int width, int height) { - DE_setRect(vid.de_mem, x,y,width,height); -} - -void PLAT_setNearestNeighbor(int enabled) { - int scale_coef = enabled ? DE_SCOEF_NONE : DE_SCOEF_HALF_ZOOMOUT; - DE_setScaleCoef(vid.de_mem, 0, scale_coef); - DE_setScaleCoef(vid.de_mem, 1, scale_coef); - DE_setScaleCoef(vid.de_mem, 2, scale_coef); - DE_setScaleCoef(vid.de_mem, 3, scale_coef); -} - -static int next_effect = EFFECT_NONE; -static int effect_type = EFFECT_NONE; -void PLAT_setSharpness(int sharpness) { - // force effect to reload - // on scaling change - if (effect_type>=EFFECT_NONE) next_effect = effect_type; - effect_type = -1; -} - -void PLAT_setEffect(int effect) { - next_effect = effect; -} - -void PLAT_vsync(int remaining) { - if (ioctl(vid.fd_fb, OWLFB_WAITFORVSYNC, &_)) LOG_info("OWLFB_WAITFORVSYNC failed %s\n", strerror(errno)); -} - -scaler_t PLAT_getScaler(GFX_Renderer* renderer) { - if (effect_type==EFFECT_LINE) { - switch (renderer->scale) { - case 4: return scale4x_line; - case 3: return scale3x_line; - case 2: return scale2x_line; - default: return scale1x_line; - } - } - else if (effect_type==EFFECT_GRID) { - switch (renderer->scale) { - case 3: return scale3x_grid; - case 2: return scale2x_grid; - } - } - - switch (renderer->scale) { - case 6: return scale6x6_n16; - case 5: return scale5x5_n16; - case 4: return scale4x4_n16; - case 3: return scale3x3_n16; - case 2: return scale2x2_n16; - default: return scale1x1_n16; - } -} - -void PLAT_blitRenderer(GFX_Renderer* renderer) { - if (effect_type!=next_effect) { - effect_type = next_effect; - renderer->blit = PLAT_getScaler(renderer); // refresh the scaler - } - void* dst = renderer->dst + (renderer->dst_y * renderer->dst_p) + (renderer->dst_x * FIXED_BPP); - ((scaler_t)renderer->blit)(renderer->src,dst,renderer->src_w,renderer->src_h,renderer->src_p,renderer->dst_w,renderer->dst_h,renderer->dst_p); -} - -void PLAT_flip(SDL_Surface* IGNORED, int sync) { - vid.de_mem[DE_OVL_BA0(0)/4] = vid.de_mem[DE_OVL_BA0(2)/4] = (uintptr_t)(vid.fb_info.padd + vid.page * PAGE_SIZE); - DE_enableLayer(vid.de_mem); - - if (sync) PLAT_vsync(0); - - // swap backbuffer - vid.page ^= 1; - vid.screen->pixels = vid.fb_info.vadd + vid.page * PAGE_SIZE; - - if (vid.cleared) { - PLAT_clearVideo(vid.screen); - vid.cleared = 0; - } -} - -/////////////////////////////// - -#define OVERLAY_WIDTH PILL_SIZE // unscaled -#define OVERLAY_HEIGHT PILL_SIZE // unscaled -#define OVERLAY_BPP 4 -#define OVERLAY_DEPTH 32 -#define OVERLAY_PITCH (OVERLAY_WIDTH * OVERLAY_BPP) // unscaled -#define OVERLAY_RGBA_MASK 0x00ff0000,0x0000ff00,0x000000ff,0xff000000 // ARGB -#define OVERLAY_FB 0 -#define OVERLAY_ID 1 -static struct OVL_Context { - SDL_Surface* overlay; - struct owlfb_overlay_args oargs; - struct owlfb_overlay_info oinfo; - ion_alloc_info_t ov_info; -} ovl; - -SDL_Surface* PLAT_initOverlay(void) { - // setup surface - ovl.overlay = SDL_CreateRGBSurfaceFrom(NULL,SCALE2(OVERLAY_WIDTH,OVERLAY_HEIGHT),OVERLAY_DEPTH,SCALE1(OVERLAY_PITCH), OVERLAY_RGBA_MASK); - uint32_t size = ovl.overlay->h * ovl.overlay->pitch; - ovl.ov_info.size = size; - ion_alloc(vid.fd_ion, &ovl.ov_info); - ovl.overlay->pixels = ovl.ov_info.vadd; - memset(ovl.overlay->pixels, 0xff, size); - - // setup overlay - memset(&ovl.oargs, 0, sizeof(struct owlfb_overlay_args)); - ovl.oargs.fb_id = OVERLAY_FB; - ovl.oargs.overlay_id = OVERLAY_ID; - ovl.oargs.overlay_type = OWLFB_OVERLAY_VIDEO; - ovl.oargs.uintptr_overly_info = (uintptr_t)&ovl.oinfo; - - int x,y,w,h; - w = h = ovl.overlay->w; - x = FIXED_WIDTH - SCALE1(PADDING) - w; - y = SCALE1(PADDING); - - ovl.oinfo.mem_off = (uintptr_t)ovl.ov_info.padd - vid.finfo.smem_start; - ovl.oinfo.mem_size = size; - ovl.oinfo.screen_width = PAGE_WIDTH; // ??? - ovl.oinfo.color_mode = OWL_DSS_COLOR_ARGB32; - ovl.oinfo.img_width = w; - ovl.oinfo.img_height = h; - ovl.oinfo.xoff = 0; - ovl.oinfo.yoff = 0; - ovl.oinfo.width = w; - ovl.oinfo.height = h; - ovl.oinfo.rotation = 0; - ovl.oinfo.pos_x = x; // position - ovl.oinfo.pos_y = y; // - ovl.oinfo.out_width = w; // scaled size - ovl.oinfo.out_height = h; // - ovl.oinfo.global_alpha_en = 0; - ovl.oinfo.global_alpha = 0; - ovl.oinfo.pre_mult_alpha_en = 0; - ovl.oinfo.zorder = 3; - if (ioctl(vid.fd_fb, OWLFB_OVERLAY_SETINFO, &ovl.oargs)<0) printf("SETINFO failed %s\n",strerror(errno)); - if (ioctl(vid.fd_fb, OWLFB_OVERLAY_ENABLE, &ovl.oargs)<0) printf("ENABLE failed %s\n",strerror(errno)); - DE_enableLayer(vid.de_mem); // we don't want it to show immediately - - return ovl.overlay; -} -void PLAT_quitOverlay(void) { - if (ovl.overlay) SDL_FreeSurface(ovl.overlay); - ion_free(vid.fd_ion, &ovl.ov_info); - - memset(&ovl.oargs, 0, sizeof(struct owlfb_overlay_args)); - ovl.oargs.fb_id = OVERLAY_FB; - ovl.oargs.overlay_id = OVERLAY_ID; - ovl.oargs.overlay_type = OWLFB_OVERLAY_VIDEO; - ovl.oargs.uintptr_overly_info = 0; - ioctl(vid.fd_fb, OWLFB_OVERLAY_DISABLE, &ovl.oargs); -} -void PLAT_enableOverlay(int enable) { - de_enable_overlay = enable; -} - -/////////////////////////////// - -void PLAT_getBatteryStatus(int* is_charging, int* charge) { - PLAT_getBatteryStatusFine(is_charging, charge); - - // worry less about battery and more about the game you're playing - if (*charge>80) *charge = 100; - else if (*charge>60) *charge = 80; - else if (*charge>40) *charge = 60; - else if (*charge>20) *charge = 40; - else if (*charge>10) *charge = 20; - else *charge = 10; -} - -void PLAT_getBatteryStatusFine(int* is_charging, int* charge) -{ - *is_charging = getInt("/sys/class/power_supply/battery/charger_online"); - - *charge = getInt("/sys/class/power_supply/battery/voltage_now") / 10000; // 310-410 - *charge -= 310; // ~0-100 - - // TODO: tmp - // *is_charging = 0; - // *charge = PWR_LOW_CHARGE; -} - -void PLAT_enableBacklight(int enable) { - putInt("/sys/class/backlight/backlight.2/bl_power", enable ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN); -} -void PLAT_powerOff(void) { - sleep(2); - - SetRawVolume(MUTE_VOLUME_RAW); - PLAT_enableBacklight(0); - SND_quit(); - VIB_quit(); - PWR_quit(); - GFX_quit(); - - system("shutdown"); -} - -/////////////////////////////// - -void PLAT_setCPUSpeed(int speed) { - int freq = 0; - switch (speed) { - case CPU_SPEED_MENU: freq = 504000; break; - case CPU_SPEED_POWERSAVE: freq = 1104000; break; - case CPU_SPEED_NORMAL: freq = 1296000; break; - case CPU_SPEED_PERFORMANCE: freq = 1488000; break; - } - - char cmd[32]; - sprintf(cmd,"overclock.elf %d\n", freq); - system(cmd); -} - -#define RUMBLE_PATH "/sys/class/power_supply/battery/moto" -void PLAT_setRumble(int strength) { - int val = MAX(0, MIN((100 * strength)>>16, 100)); - // LOG_info("strength: %8i (%3i/100)\n", strength, val); - putInt(RUMBLE_PATH, val); -} - -int PLAT_pickSampleRate(int requested, int max) { - return MIN(requested, max); -} - -char* PLAT_getModel(void) { - return "Anbernic RG35XX"; -} - -int PLAT_isOnline(void) { - return 0; -} \ No newline at end of file diff --git a/workspace/_unmaintained/rg35xx/platform/platform.h b/workspace/_unmaintained/rg35xx/platform/platform.h deleted file mode 100644 index 43c21b96e..000000000 --- a/workspace/_unmaintained/rg35xx/platform/platform.h +++ /dev/null @@ -1,122 +0,0 @@ -// rg35xx/platform/platform.h - -#ifndef PLATFORM_H -#define PLATFORM_H - -/////////////////////////////// - -#include "sdl.h" - -/////////////////////////////// - -#define BUTTON_UP SDLK_KATAKANA -#define BUTTON_DOWN SDLK_HIRAGANA -#define BUTTON_LEFT SDLK_HENKAN -#define BUTTON_RIGHT SDLK_KATAKANAHIRAGANA - -#define BUTTON_SELECT SDLK_PRINT -#define BUTTON_START SDLK_KP_DIVIDE - -#define BUTTON_A SDLK_MUHENKAN -#define BUTTON_B SDLK_KP_JPCOMMA -#define BUTTON_X SDLK_KP_ENTER -#define BUTTON_Y SDLK_RCTRL - -#define BUTTON_L1 SDLK_RALT -#define BUTTON_R1 SDLK_BREAK -#define BUTTON_L2 SDLK_HOME -#define BUTTON_R2 SDLK_UP -#define BUTTON_L3 BUTTON_NA -#define BUTTON_R3 BUTTON_NA - -#define BUTTON_MENU SDLK_PAGEUP -#define BUTTON_POWER SDLK_POWER -#define BUTTON_PLUS SDLK_DOWN -#define BUTTON_MINUS SDLK_PAGEDOWN - -/////////////////////////////// - -#define CODE_UP 0x5A -#define CODE_DOWN 0x5B -#define CODE_LEFT 0x5C -#define CODE_RIGHT 0x5D - -#define CODE_SELECT 0x63 -#define CODE_START 0x62 - -#define CODE_A 0x5E -#define CODE_B 0x5F -#define CODE_X 0x60 -#define CODE_Y 0x61 - -#define CODE_L1 0x64 -#define CODE_R1 0x65 -#define CODE_L2 0x66 -#define CODE_R2 0x67 -#define CODE_L3 CODE_NA -#define CODE_R3 CODE_NA - -#define CODE_MENU 0x68 -#define CODE_POWER 0x74 - -#define CODE_PLUS 0x6C -#define CODE_MINUS 0x6D - -/////////////////////////////// - -#define JOY_UP JOY_NA -#define JOY_DOWN JOY_NA -#define JOY_LEFT JOY_NA -#define JOY_RIGHT JOY_NA - -#define JOY_SELECT JOY_NA -#define JOY_START JOY_NA - -#define JOY_A JOY_NA -#define JOY_B JOY_NA -#define JOY_X JOY_NA -#define JOY_Y JOY_NA - -#define JOY_L1 JOY_NA -#define JOY_R1 JOY_NA -#define JOY_L2 JOY_NA -#define JOY_R2 JOY_NA -#define JOY_L3 JOY_NA -#define JOY_R3 JOY_NA - -#define JOY_MENU JOY_NA -#define JOY_POWER JOY_NA -#define JOY_PLUS JOY_NA -#define JOY_MINUS JOY_NA - -/////////////////////////////// - -#define BTN_RESUME BTN_X -#define BTN_SLEEP BTN_POWER -#define BTN_WAKE BTN_POWER -#define BTN_MOD_VOLUME BTN_NONE -#define BTN_MOD_BRIGHTNESS BTN_MENU -#define BTN_MOD_PLUS BTN_PLUS -#define BTN_MOD_MINUS BTN_MINUS - -/////////////////////////////// - -#define FIXED_SCALE 2 -#define FIXED_WIDTH 640 -#define FIXED_HEIGHT 480 -#define FIXED_BPP 2 -#define FIXED_DEPTH (FIXED_BPP * 8) -#define FIXED_PITCH (FIXED_WIDTH * FIXED_BPP) -#define FIXED_SIZE (FIXED_PITCH * FIXED_HEIGHT) - -/////////////////////////////// - -#define SDCARD_PATH "/mnt/sdcard" -#define MUTE_VOLUME_RAW 0 -#define HAS_NEON - -// this should be set to the devices native screen refresh rate -#define SCREEN_FPS 60.0 -/////////////////////////////// - -#endif diff --git a/workspace/_unmaintained/rg35xx/ramdisk/charging.png b/workspace/_unmaintained/rg35xx/ramdisk/charging.png deleted file mode 100644 index bc8a67d39293496bef20da892e066b5fa09abbca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3913 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 JdIkN*KLBj3QN92G diff --git a/workspace/_unmaintained/rg35xx/ramdisk/patched-ramdisk.img b/workspace/_unmaintained/rg35xx/ramdisk/patched-ramdisk.img deleted file mode 100644 index 8bd4fbc5938223bcd62462f0469e44b0de5c0837..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 669248 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
}e+*daBN+Zs76|d(pG=-L64Ne4lKVebM0R!R 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

3jn)1Ya7QveHz3Ej`s&WqcA@SXG98heSO?#{ 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

g5(zo|I=-L9 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

bmBvwMX3wdd51RRwYrc4YN;2xrXF}r@BR!YD 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

uq_=?%%5{v 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 i`+9r}FU<(XEx*>`?(1PhFuHSO? ../ramdisk.cpio - mkimage -A arm -O linux -T ramdisk -n "Initial RAM Disk" -d ../ramdisk.cpio ../ramdisk.img.new - -based on - - https://boundarydevices.com/hacking-ram-disks/ - ---- - -if I decide to use this will need to copy charging.png and patched-ramdisk.img (as ramdisk.img) to /.system/rg35xx/dat \ No newline at end of file diff --git a/workspace/_unmaintained/rg35xxplus/boot/boot.sh b/workspace/_unmaintained/rg35xxplus/boot/boot.sh deleted file mode 100755 index 8d61ffc67..000000000 --- a/workspace/_unmaintained/rg35xxplus/boot/boot.sh +++ /dev/null @@ -1,131 +0,0 @@ -#!/bin/sh - -TF1_PATH=/mnt/mmc # TF1/NO NAME partition -TF2_PATH=/mnt/sdcard # TF2 - -rm $TF1_PATH/log.txt -touch $TF1_PATH/log.txt - -RGXX_MODEL=`strings /mnt/vendor/bin/dmenu.bin | grep ^RG` - -FLAG_PATH=$TF1_PATH/.minstalled -SDCARD_PATH=$TF1_PATH -SYSTEM_DIR=/.system -SYSTEM_FRAG=$SYSTEM_DIR/rg35xxplus -UPDATE_FRAG=/NextUI.zip -SYSTEM_PATH=${SDCARD_PATH}${SYSTEM_FRAG} -UPDATE_PATH=${SDCARD_PATH}${UPDATE_FRAG} - -# rm /mnt/sdcard -# mkdir -p /mnt/sdcard -# poweroff - -if [ -h $TF2_PATH ] && [ "$TF2_PATH" -ef "$TF1_PATH" ]; then - echo "deleting old TF2 -> TF1 symlink" >> $TF1_PATH/log.txt - unlink $TF2_PATH -fi - -if mountpoint -q $TF2_PATH; then - echo "TF2 already mounted" >> $TF1_PATH/log.txt -else - echo "mount TF2" >> $TF1_PATH/log.txt - mkdir -p $TF2_PATH - SDCARD_DEVICE=/dev/mmcblk1p1 - mount -t vfat -o rw,utf8,noatime $SDCARD_DEVICE $TF2_PATH - if [ $? -ne 0 ]; then - echo "mount failed, symlink to TF1" >> $TF1_PATH/log.txt - rm -d $TF2_PATH - ln -s $TF1_PATH $TF2_PATH - fi -fi - -if [ -d ${TF1_PATH}${SYSTEM_FRAG} ] || [ -f ${TF1_PATH}${UPDATE_FRAG} ]; then - echo "found NextUI on TF1" >> $TF1_PATH/log.txt - if [ ! -h $TF2_PATH ]; then - echo "no system on TF2, unmount and symlink to TF1" >> $TF1_PATH/log.txt - umount $TF2_PATH - rm -rf $TF2_PATH - ln -s $TF1_PATH $TF2_PATH - fi -fi - -SDCARD_PATH=$TF2_PATH -SYSTEM_PATH=${SDCARD_PATH}${SYSTEM_FRAG} -UPDATE_PATH=${SDCARD_PATH}${UPDATE_FRAG} - -# is there an update available? -if [ -f $UPDATE_PATH ]; then - echo "zip detected" >> $TF1_PATH/log.txt - - MODES=`cat /sys/class/graphics/fb0/modes` - case $MODES in - *"480x640"*) - SUFFIX="-r" - echo "rotated framebuffer" >> $TF1_PATH/log.txt - ;; - esac - - if [ "$RGXX_MODEL" = "RGcubexx" ]; then - SUFFIX="-s" - elif [ "$RGXX_MODEL" = "RG34xx" ]; then - SUFFIX="-w" - fi - - if [ ! -d $SYSTEM_PATH ]; then - ACTION=installing - echo "install NextUI" >> $TF1_PATH/log.txt - else - ACTION=updating - echo "update NextUI" >> $TF1_PATH/log.txt - fi - - # extract tar.gz from this sh file - LINE=$((`grep -na '^BINARY' $0 | cut -d ':' -f 1 | tail -1` + 1)) - tail -n +$LINE "$0" > /tmp/data - tar -xf /tmp/data -C /tmp > /dev/null 2>&1 - - # show action - dd if=/tmp/$ACTION$SUFFIX of=/dev/fb0 - sync - echo 0,0 > /sys/class/graphics/fb0/pan - - # install bootlogo.bmp - if [ $ACTION = "installing" ] || [ ! -f $FLAG_PATH ]; then - echo "replace bootlogo" >> $TF1_PATH/log.txt - touch $FLAG_PATH - BOOT_DEVICE=/dev/mmcblk0p2 - BOOT_PATH=/mnt/boot - mkdir -p $BOOT_PATH - mount -t vfat -o rw,utf8,noatime $BOOT_DEVICE $BOOT_PATH - cp /tmp/bootlogo$SUFFIX.bmp $BOOT_PATH/bootlogo.bmp - umount $BOOT_PATH - rm -rf $BOOT_PATH - fi - - /tmp/unzip -o $UPDATE_PATH -d $SDCARD_PATH >> $TF1_PATH/log.txt - rm -f $UPDATE_PATH - - # ls -la $SDCARD_PATH >> $TF1_PATH/log.txt - - # cd /tmp - # rm data installing updating bootlogo.bmp installing-r updating-r bootlogo-r.bmp unzip - - # the updated system finishes the install/update - echo "finishing update..." >> $TF1_PATH/log.txt - $SYSTEM_PATH/bin/install.sh >> $TF1_PATH/log.txt -fi - -if [ -f $SYSTEM_PATH/paks/NextUI.pak/launch.sh ]; then - echo "launch NextUI" >> $TF1_PATH/log.txt - $SYSTEM_PATH/paks/NextUI.pak/launch.sh -else - echo "couldn't find launch.sh" >> $TF1_PATH/log.txt - if [ -h $TF2_PATH ] && [ "$TF2_PATH" -ef "$TF1_PATH" ]; then - echo "deleting old TF2 -> TF1 symlink" >> $TF1_PATH/log.txt - unlink $TF2_PATH - fi -fi - -sync && poweroff - -exit 0 diff --git a/workspace/_unmaintained/rg35xxplus/boot/bootlogo-r.bmp b/workspace/_unmaintained/rg35xxplus/boot/bootlogo-r.bmp deleted file mode 100644 index 0bcffee2c0690b0dd62ff31b6f00ae01815fc089..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 921656 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 z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ wfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1nNfM|8vU=1ONa4 diff --git a/workspace/_unmaintained/rg35xxplus/boot/bootlogo-s.bmp b/workspace/_unmaintained/rg35xxplus/boot/bootlogo-s.bmp deleted file mode 100755 index e29f6502a8a55065dc55af20671e3c25c1a20191..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1555256 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 z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ QfB*pk1PBlyuw4TG18~9&+5i9m diff --git a/workspace/_unmaintained/rg35xxplus/boot/bootlogo.bmp b/workspace/_unmaintained/rg35xxplus/boot/bootlogo.bmp deleted file mode 100755 index 7dc7e21c4211e531e14269e8142ca662f7b40d10..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 921656 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 z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF X5FkK+009C72oNAZfB=C%pTPeC&NT}J diff --git a/workspace/_unmaintained/rg35xxplus/boot/build.sh b/workspace/_unmaintained/rg35xxplus/boot/build.sh deleted file mode 100755 index b55f3d9fe..000000000 --- a/workspace/_unmaintained/rg35xxplus/boot/build.sh +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/sh - -SOURCE=boot.sh -TARGET=dmenu.bin - -# TODO: test -# SOURCE=test.sh -# TARGET=launch.sh - -mkdir -p output -if [ ! -f output/installing ]; then - dd skip=54 iflag=skip_bytes if=installing.bmp of=output/installing -fi -if [ ! -f output/updating ]; then - dd skip=54 iflag=skip_bytes if=updating.bmp of=output/updating -fi -if [ ! -f output/bootlogo.bmp ]; then - cp bootlogo.bmp ./output/ -fi - -# rotated for 28xx -if [ ! -f output/installing-r ]; then - dd skip=54 iflag=skip_bytes if=installing-r.bmp of=output/installing-r -fi -if [ ! -f output/updating-r ]; then - dd skip=54 iflag=skip_bytes if=updating-r.bmp of=output/updating-r -fi -if [ ! -f output/bootlogo.bmp-r ]; then - cp bootlogo-r.bmp ./output/ -fi - -# square for cubexx -if [ ! -f output/installing-s ]; then - dd skip=54 iflag=skip_bytes if=installing-s.bmp of=output/installing-s -fi -if [ ! -f output/updating-s ]; then - dd skip=54 iflag=skip_bytes if=updating-s.bmp of=output/updating-s -fi -if [ ! -f output/bootlogo.bmp-s ]; then - cp bootlogo-s.bmp ./output/ -fi - -# wide for 34xx -if [ ! -f output/installing-w ]; then - dd skip=54 iflag=skip_bytes if=installing-w.bmp of=output/installing-w -fi -if [ ! -f output/updating-w ]; then - dd skip=54 iflag=skip_bytes if=updating-w.bmp of=output/updating-w -fi -if [ ! -f output/bootlogo.bmp-w ]; then - cp bootlogo-w.bmp ./output/ -fi - -cp ../other/unzip60/unzip ./output/ - -cd output - -tar -czvf data bootlogo.bmp installing updating bootlogo-r.bmp installing-r updating-r bootlogo-s.bmp installing-s updating-s bootlogo-w.bmp installing-w updating-w unzip - -cat ../$SOURCE > $TARGET -echo BINARY >> $TARGET -cat data >> $TARGET -echo >> $TARGET diff --git a/workspace/_unmaintained/rg35xxplus/boot/installing-r.bmp b/workspace/_unmaintained/rg35xxplus/boot/installing-r.bmp deleted file mode 100644 index bbaf21a0367daeee71f06e6028ecb8c888d5ca60..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1228856 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 zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk b1PBlyK!5-N0t5&UAV7cs0RjY`gTVg)lucUR diff --git a/workspace/_unmaintained/rg35xxplus/boot/installing-s.bmp b/workspace/_unmaintained/rg35xxplus/boot/installing-s.bmp deleted file mode 100644 index abbc5c13ce123606cce68b7f32625fa32228db84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2073656 zcmeI*J&r6_83y3SDH$7pzyZ#P5Gglj0eA<%tr@@i-EaQ#^GnLF-+cY@&DTFZxLkhq zpVzN{a{0xZ?=F`Q-W>ngPcLu3-tO=p0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly 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 zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAaEOj F{{l9KT44YH diff --git a/workspace/_unmaintained/rg35xxplus/boot/installing-w.bmp b/workspace/_unmaintained/rg35xxplus/boot/installing-w.bmp deleted file mode 100644 index 8a562541cd9e00bf129eb5745067a7cc1a5f30d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1382456 zcmeI*J&r6_83y3SDH#$Hp#uWE0Yu8pS%AF*d=BLP+3@ z%YCo(NuLj2{mgXJ?tAAs()iR=ojN~H^{C&jTQh$3hu{6`mzR{^zWMsio3DR-aJhW= zpVzN{cKPtlcbCftZ;t=s=a;u%Z+G|)0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U 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 z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly PK!5-N0t5(LufYES1eDn# diff --git a/workspace/_unmaintained/rg35xxplus/boot/updating-s.bmp b/workspace/_unmaintained/rg35xxplus/boot/updating-s.bmp deleted file mode 100644 index 39b309c09058eeec9a7560427bc5b9064408a60a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2073656 zcmeI*KaOli6$jvkl#C5PK!7tMM2d43fOmkr1dAP5tiU27LUL$!U_uMA0FyZ(ByfZt z?>E+wj!NhLnR(qkfA~u3SGT+Bo~rt8x8_XEop~Ss?l*t=*(K%I?;pQ>|Mrhk@PdB`5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs 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 zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N O0t5&UAVA>x1^x#aUf87o diff --git a/workspace/_unmaintained/rg35xxplus/boot/updating-w.bmp b/workspace/_unmaintained/rg35xxplus/boot/updating-w.bmp deleted file mode 100644 index fcc533cd59c785c1a88cc6e635b173b6c9087c73..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1382456 zcmeI*KaOli6$jwPDH#$HAprs203yXX3&1--UV_CAELLE#03?TI2PQ;_1(?hUA%Qa< z?>E+wj!NhLnR(qkfBcoyuWonMJyrGHZq1pRJM%vI{cnHq^GnKa-amf*{_)R`E|*{a z@7=qfTz>if+2!)l`}Uvx^z!g{c)>pe2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N 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 z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk Q1PBlyK!5;&AFsgw0sIr!Y5)KL diff --git a/workspace/_unmaintained/rg35xxplus/boot/updating.bmp b/workspace/_unmaintained/rg35xxplus/boot/updating.bmp deleted file mode 100644 index 488f41ec9fecb77d61cd297f2633d3365eeabfd1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1228856 zcmeI*KaOli6$jwPDVbN`fBZ>Mzz&d?U?H&pixpTb0Lh_=NlZw<0!-$FkiZ#_ z_Z#a-N2PQB^h|fpd(U4<%Igw?Dsp`}3!dE|*XK z_vX#dE}y)8b-8@>w*BLuU!H!RPWTT20t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly 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 diff --git a/workspace/_unmaintained/rg35xxplus/cores/makefile b/workspace/_unmaintained/rg35xxplus/cores/makefile deleted file mode 100644 index 6ec85be3e..000000000 --- a/workspace/_unmaintained/rg35xxplus/cores/makefile +++ /dev/null @@ -1,4 +0,0 @@ -all: - # copy from original rg35xx (for now?) - rm -rf output - cp -r ../../rg35xx/cores/output ./ \ No newline at end of file diff --git a/workspace/_unmaintained/rg35xxplus/init/init.c b/workspace/_unmaintained/rg35xxplus/init/init.c deleted file mode 100644 index 16f1e44ec..000000000 --- a/workspace/_unmaintained/rg35xxplus/init/init.c +++ /dev/null @@ -1,6 +0,0 @@ -#include -void main(void) { - SDL_Init(SDL_INIT_VIDEO); - SDL_SetVideoMode(0,0,0,0); - SDL_Quit(); -} diff --git a/workspace/_unmaintained/rg35xxplus/init/makefile b/workspace/_unmaintained/rg35xxplus/init/makefile deleted file mode 100644 index aec7101c2..000000000 --- a/workspace/_unmaintained/rg35xxplus/init/makefile +++ /dev/null @@ -1,15 +0,0 @@ -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif - -TARGET = init -PRODUCT= $(TARGET).elf - -CC = $(CROSS_COMPILE)gcc -CFLAGS = -marm -mtune=cortex-a53 -mfpu=neon-fp-armv8 -mfloat-abi=hard -mcpu=cortex-a53 -LDFLAGS = -lSDL - -all: - $(CC) $(TARGET).c -o $(PRODUCT) $(CFLAGS) $(LDFLAGS) -clean: - rm -f $(PRODUCT) diff --git a/workspace/_unmaintained/rg35xxplus/install/install.sh b/workspace/_unmaintained/rg35xxplus/install/install.sh deleted file mode 100755 index 302caf5fa..000000000 --- a/workspace/_unmaintained/rg35xxplus/install/install.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/sh - -TF1_PATH=/mnt/mmc -TF2_PATH=/mnt/sdcard # TF1 should be linked to this path if TF2 is missing or doesn't contain our system folder -SYSTEM_PATH=${TF2_PATH}/.system/rg35xxplus - -# make sure dmenu stays up to date -echo "update dmenu.bin" -cp $SYSTEM_PATH/dat/dmenu.bin $TF1_PATH -sync - -# -------------------------------------- -# remove old cube system folder -CUBE_PATH=${TF2_PATH}/.system/rg40xxcube -echo "check for $CUBE_PATH" -# this will always exist so we can pull up old cards -if [ -d $CUBE_PATH ]; then - echo "deleting cube system folder $CUBE_PATH" - rm -rf "$CUBE_PATH" - - # copy cube configs from userdata - SRC_PATH=${TF2_PATH}/.userdata/rg40xxcube - if [ -d $SRC_PATH ]; then - DST_PATH=${TF2_PATH}/.userdata/rg35xxplus - mkdir -p $DST_PATH # just in case - - for SUB_PATH in $SRC_PATH/*; do - if [ -d $SUB_PATH ]; then - SUB_NAME=$(basename $SUB_PATH) - NEW_PATH=$DST_PATH/$SUB_NAME - - if [ ! -d $NEW_PATH ]; then - echo "creating new path $NEW_PATH" - mkdir -p $NEW_PATH - fi - - for CFG_PATH in $SUB_PATH/*.cfg; do - if [ -f $CFG_PATH ]; then - CFG_NAME=$(basename $CFG_PATH .cfg) - echo "copying $CFG_PATH to $NEW_PATH/$CFG_NAME-cube.cfg" - cp $CFG_PATH $NEW_PATH/$CFG_NAME-cube.cfg - fi - done - fi - done - echo "deleting cube userdata $SRC_PATH" - rm -rf $SRC_PATH - reboot - fi -fi -# -------------------------------------- diff --git a/workspace/_unmaintained/rg35xxplus/keymon/credits.txt b/workspace/_unmaintained/rg35xxplus/keymon/credits.txt deleted file mode 100644 index e885e5dd1..000000000 --- a/workspace/_unmaintained/rg35xxplus/keymon/credits.txt +++ /dev/null @@ -1,3 +0,0 @@ -based on eggs custom keymon for Trimui: - https://www.dropbox.com/sh/5e9xwvp672vt8cr/AABUIdw1vLYp9h0waoCUqHPOa/source?dl=0&subfolder_nav_tracking=1 -modified to use libmsettings \ No newline at end of file diff --git a/workspace/_unmaintained/rg35xxplus/keymon/keymon.c b/workspace/_unmaintained/rg35xxplus/keymon/keymon.c deleted file mode 100644 index 84e05f05f..000000000 --- a/workspace/_unmaintained/rg35xxplus/keymon/keymon.c +++ /dev/null @@ -1,171 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -// #include "defines.h" - -#define VOLUME_MIN 0 -#define VOLUME_MAX 20 -#define BRIGHTNESS_MIN 0 -#define BRIGHTNESS_MAX 10 - -// uses different codes from SDL -#define CODE_MENU 312 // but also 354 -#define CODE_PLUS 115 -#define CODE_MINUS 114 - -// for ev.value -#define RELEASED 0 -#define PRESSED 1 -#define REPEAT 2 - -static int input_fd = 0; -static struct input_event ev; - -static pthread_t hdmi_pt; -#define HDMI_STATE_PATH "/sys/class/extcon/hdmi/cable.0/state" - -int getInt(char* path) { - int i = 0; - FILE *file = fopen(path, "r"); - if (file!=NULL) { - fscanf(file, "%i", &i); - fclose(file); - } - return i; -} - -static void* watchHDMI(void *arg) { - int has_hdmi,had_hdmi; - - has_hdmi = had_hdmi = getInt(HDMI_STATE_PATH); - SetHDMI(has_hdmi); - - while(1) { - sleep(1); - - has_hdmi = getInt(HDMI_STATE_PATH); - if (had_hdmi!=has_hdmi) { - had_hdmi = has_hdmi; - SetHDMI(has_hdmi); - } - } - - return 0; -} - -int main (int argc, char *argv[]) { - InitSettings(); - pthread_create(&hdmi_pt, NULL, &watchHDMI, NULL); - - input_fd = open("/dev/input/event1", O_RDONLY | O_NONBLOCK | O_CLOEXEC); - - uint32_t input; - uint32_t val; - uint32_t menu_pressed = 0; - - uint32_t up_pressed = 0; - uint32_t up_just_pressed = 0; - uint32_t up_repeat_at = 0; - - uint32_t down_pressed = 0; - uint32_t down_just_pressed = 0; - uint32_t down_repeat_at = 0; - - uint8_t ignore; - uint32_t then; - uint32_t now; - struct timeval tod; - - gettimeofday(&tod, NULL); - then = tod.tv_sec * 1000 + tod.tv_usec / 1000; // essential SDL_GetTicks() - ignore = 0; - - while (1) { - gettimeofday(&tod, NULL); - now = tod.tv_sec * 1000 + tod.tv_usec / 1000; - // TODO: check if if necessary - if (now-then>1000) ignore = 1; // ignore input that arrived during sleep - - while(read(input_fd, &ev, sizeof(ev))==sizeof(ev)) { - if (ignore) continue; - val = ev.value; - - if (( ev.type != EV_KEY ) || ( val > REPEAT )) continue; - // printf("code: %i (%i)\n", ev.code, val); fflush(stdout); - switch (ev.code) { - case CODE_MENU: - menu_pressed = val; - break; - break; - case CODE_PLUS: - up_pressed = up_just_pressed = val; - if (val) up_repeat_at = now + 300; - break; - case CODE_MINUS: - down_pressed = down_just_pressed = val; - if (val) down_repeat_at = now + 300; - break; - default: - break; - } - } - - if (ignore) { - menu_pressed = 0; - up_pressed = up_just_pressed = 0; - down_pressed = down_just_pressed = 0; - up_repeat_at = 0; - down_repeat_at = 0; - } - - if (up_just_pressed || (up_pressed && now>=up_repeat_at)) { - if (menu_pressed) { - // printf("brightness up\n"); fflush(stdout); - val = GetBrightness(); - if (val=down_repeat_at)) { - if (menu_pressed) { - // printf("brightness down\n"); fflush(stdout); - val = GetBrightness(); - if (val>BRIGHTNESS_MIN) SetBrightness(--val); - } - else { - // printf("volume down\n"); fflush(stdout); - val = GetVolume(); - if (val>VOLUME_MIN) SetVolume(--val); - } - - if (down_just_pressed) down_just_pressed = 0; - else down_repeat_at += 100; - } - - then = now; - ignore = 0; - - usleep(16666); // 60fps - } -} diff --git a/workspace/_unmaintained/rg35xxplus/keymon/makefile b/workspace/_unmaintained/rg35xxplus/keymon/makefile deleted file mode 100755 index 0212b6bbc..000000000 --- a/workspace/_unmaintained/rg35xxplus/keymon/makefile +++ /dev/null @@ -1,16 +0,0 @@ -#keymon - -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif - -TARGET = keymon - -CC = $(CROSS_COMPILE)gcc -CFLAGS = -Os -lmsettings -lpthread -lrt -ldl -Wl,--gc-sections -s -CFLAGS += -I. -I../../all/common -I../platform/ -DPLATFORM=\"$(UNION_PLATFORM)\" - -all: - $(CC) $(TARGET).c -o $(TARGET).elf $(CFLAGS) -clean: - rm -rf $(TARGET).elf \ No newline at end of file diff --git a/workspace/_unmaintained/rg35xxplus/libmsettings/makefile b/workspace/_unmaintained/rg35xxplus/libmsettings/makefile deleted file mode 100644 index b1418a21d..000000000 --- a/workspace/_unmaintained/rg35xxplus/libmsettings/makefile +++ /dev/null @@ -1,32 +0,0 @@ -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif -ifeq (,$(PREFIX)) -$(error missing PREFIX for this toolchain) -endif - -TARGET=msettings - -.PHONY: build -.PHONY: clean - -CC = $(CROSS_COMPILE)gcc - -SYSROOT := $(shell $(CC) --print-sysroot) - -INCLUDEDIR = $(SYSROOT)/usr/include -CFLAGS = -I$(INCLUDEDIR) -LDFLAGS = -ldl -lrt -s - -OPTM=-Ofast - -build: - $(CC) -c -Werror -fpic "$(TARGET).c" -Wl,--no-as-needed $(LDFLAGS) - $(CC) -shared -o "lib$(TARGET).so" "$(TARGET).o" $(LDFLAGS) - cp "$(TARGET).h" "$(PREFIX)/include" - cp "lib$(TARGET).so" "$(PREFIX)/lib" -clean: - rm -f *.o - rm -f "lib$(TARGET).so" - rm -f $(PREFIX)/include/$(TARGET).h - rm -f $(PREFIX)/lib/lib$(TARGET).so \ No newline at end of file diff --git a/workspace/_unmaintained/rg35xxplus/libmsettings/msettings.c b/workspace/_unmaintained/rg35xxplus/libmsettings/msettings.c deleted file mode 100644 index eb8d9af4c..000000000 --- a/workspace/_unmaintained/rg35xxplus/libmsettings/msettings.c +++ /dev/null @@ -1,201 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "msettings.h" - -/////////////////////////////////////// - -#define SETTINGS_VERSION 2 -typedef struct Settings { - int version; // future proofing - int brightness; - int headphones; - int speaker; - int unused[2]; // for future use - // NOTE: doesn't really need to be persisted but still needs to be shared - int jack; - int hdmi; -} Settings; -static Settings DefaultSettings = { - .version = SETTINGS_VERSION, - .brightness = 2, - .headphones = 4, - .speaker = 8, - .jack = 0, - .hdmi = 0, -}; -static Settings* settings; - -#define SHM_KEY "/SharedSettings" -static char SettingsPath[256]; -static int shm_fd = -1; -static int is_host = 0; -static int shm_size = sizeof(Settings); - -#define JACK_STATE_PATH "/sys/module/snd_soc_sunxi_component_jack/parameters/jack_state" // TODO: doesn't change, always 0 -#define HDMI_STATE_PATH "/sys/class/switch/hdmi/cable.0/state" - -int getInt(char* path) { - int i = 0; - FILE *file = fopen(path, "r"); - if (file!=NULL) { - fscanf(file, "%i", &i); - fclose(file); - } - return i; -} - -void InitSettings(void) { - sprintf(SettingsPath, "%s/msettings.bin", getenv("USERDATA_PATH")); - - shm_fd = shm_open(SHM_KEY, O_RDWR | O_CREAT | O_EXCL, 0644); // see if it exists - if (shm_fd==-1 && errno==EEXIST) { // already exists - puts("Settings client"); - shm_fd = shm_open(SHM_KEY, O_RDWR, 0644); - settings = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); - } - else { // host - puts("Settings host"); // should always be keymon - is_host = 1; - // we created it so set initial size and populate - ftruncate(shm_fd, shm_size); - settings = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); - - int fd = open(SettingsPath, O_RDONLY); - if (fd>=0) { - read(fd, settings, shm_size); - // TODO: use settings->version for future proofing? - close(fd); - } - else { - // load defaults - memcpy(settings, &DefaultSettings, shm_size); - } - - // these shouldn't be persisted - // settings->jack = 0; - // settings->hdmi = 0; - } - - int jack = getInt(JACK_STATE_PATH); - int hdmi = getInt(HDMI_STATE_PATH); - printf("brightness: %i (hdmi: %i)\nspeaker: %i (jack: %i)\n", settings->brightness, hdmi, settings->speaker, jack); fflush(stdout); - - // both of these set volume - SetJack(jack); - SetHDMI(hdmi); - - SetBrightness(GetBrightness()); - // system("echo $(< " BRIGHTNESS_PATH ")"); -} -void QuitSettings(void) { - munmap(settings, shm_size); - if (is_host) shm_unlink(SHM_KEY); -} -static inline void SaveSettings(void) { - int fd = open(SettingsPath, O_CREAT|O_WRONLY, 0644); - if (fd>=0) { - write(fd, settings, shm_size); - close(fd); - sync(); - } -} - -int GetBrightness(void) { // 0-10 - return settings->brightness; -} -void SetBrightness(int value) { - if (settings->hdmi) return; - - int raw; - switch (value) { - case 0: raw= 4; break; // 0 - case 1: raw= 6; break; // 2 - case 2: raw= 10; break; // 4 - case 3: raw= 16; break; // 6 - case 4: raw= 32; break; // 16 - case 5: raw= 48; break; // 16 - case 6: raw= 64; break; // 16 - case 7: raw= 96; break; // 32 - case 8: raw=128; break; // 32 - case 9: raw=192; break; // 64 - case 10: raw=255; break; // 64 - } - - SetRawBrightness(raw); - settings->brightness = value; - SaveSettings(); -} - -int GetVolume(void) { // 0-20 - return settings->jack ? settings->headphones : settings->speaker; -} -void SetVolume(int value) { - if (settings->hdmi) return; - - if (settings->jack) settings->headphones = value; - else settings->speaker = value; - - int raw = value * 5; - SetRawVolume(raw); - SaveSettings(); -} - -#define DISP_LCD_SET_BRIGHTNESS 0x102 -void SetRawBrightness(int val) { // 0 - 255 - if (settings->hdmi) return; - - printf("SetRawBrightness(%i)\n", val); fflush(stdout); - int fd = open("/dev/disp", O_RDWR); - if (fd) { - unsigned long param[4]={0,val,0,0}; - ioctl(fd, DISP_LCD_SET_BRIGHTNESS, ¶m); - close(fd); - } -} -void SetRawVolume(int val) { // 0 - 100 - printf("SetRawVolume(%i)\n", val); fflush(stdout); - char cmd[256]; - sprintf(cmd, "amixer sset 'lineout volume' %i%% > /dev/null 2>&1", val); - // // puts(cmd); fflush(stdout); - system(cmd); -} - -// monitored and set by thread in keymon -int GetJack(void) { - return settings->jack; -} -void SetJack(int value) { - // printf("SetJack(%i)\n", value); fflush(stdout); - - // char cmd[256]; - // sprintf(cmd, "amixer cset name='Playback Path' '%s' &> /dev/null", value?"HP":"SPK"); - // system(cmd); - - settings->jack = value; - SetVolume(GetVolume()); -} - -int GetHDMI(void) { - // printf("GetHDMI() %i\n", settings->hdmi); fflush(stdout); - return settings->hdmi; -} -void SetHDMI(int value) { - // printf("SetHDMI(%i)\n", value); fflush(stdout); - - settings->hdmi = value; - if (value) SetRawVolume(100); // max - else SetVolume(GetVolume()); // restore -} - -int GetMute(void) { return 0; } -void SetMute(int value) {} diff --git a/workspace/_unmaintained/rg35xxplus/libmsettings/msettings.h b/workspace/_unmaintained/rg35xxplus/libmsettings/msettings.h deleted file mode 100644 index 47e5fb003..000000000 --- a/workspace/_unmaintained/rg35xxplus/libmsettings/msettings.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef __msettings_h__ -#define __msettings_h__ - -void InitSettings(void); -void QuitSettings(void); - -int GetBrightness(void); -int GetVolume(void); - -void SetRawBrightness(int value); // 0-1024 -void SetRawVolume(int value); // 0-40 - -void SetBrightness(int value); // 0-10 -void SetVolume(int value); // 0-20 - -int GetJack(void); -void SetJack(int value); // 0-1 - -int GetHDMI(void); -void SetHDMI(int value); // 0-1 - -int GetMute(void); -void SetMute(int value); // 0-1 - -#endif // __msettings_h__ diff --git a/workspace/_unmaintained/rg35xxplus/makefile b/workspace/_unmaintained/rg35xxplus/makefile deleted file mode 100644 index 4518b4b62..000000000 --- a/workspace/_unmaintained/rg35xxplus/makefile +++ /dev/null @@ -1,82 +0,0 @@ -#rg35xx - -########################################################### - -ifeq (,$(PLATFORM)) -PLATFORM=$(UNION_PLATFORM) -endif - -ifeq (,$(PLATFORM)) -$(error please specify PLATFORM, eg. PLATFORM=trimui make) -endif - -########################################################### - -REQUIRES_UNZIP60=other/unzip60 -REQUIRES_SDL2=other/sdl2 -REQUIRES_DTC=other/dtc -REQUIRES_FBSET=other/fbset - -all: readmes - cd boot && ./build.sh - cd init && make - cd show && make - -early: $(REQUIRES_UNZIP60) $(REQUIRES_SDL2) $(REQUIRES_DTC) $(REQUIRES_FBSET) - mkdir -p other - cd $(REQUIRES_DTC) && CC=${CROSS_COMPILE}gcc make NO_PYTHON=1 dtc - cd $(REQUIRES_UNZIP60) && make -f unix/Makefile.trimuismart unzip - cd $(REQUIRES_FBSET) && make - cd $(REQUIRES_SDL2) && CFLAGS="-O2 -march=armv8-a+crc -mtune=cortex-a53 -mcpu=cortex-a53 -ffast-math -ftree-vectorize" \ - ./configure CC=${CROSS_COMPILE}gcc --host=arm-buildroot-linux-gnueabihf \ - --enable-arm-neon \ - --disable-oss \ - --disable-rpath \ - --disable-arts \ - --disable-esd \ - --disable-dbus \ - --disable-diskaudio \ - --disable-dummyaudio \ - --disable-pulseaudio \ - --disable-video-kmsdrm \ - --disable-video-vivante \ - --disable-video-cocoa \ - --disable-video-metal \ - --disable-video-dummy \ - --disable-video-offscreen \ - --disable-video-x11 \ - --disable-video-vulkan \ - --disable-ime \ - --disable-ibus \ - --disable-fcitx \ - --disable-joystick-mfi \ - --disable-directx \ - --disable-xinput \ - --disable-wasapi \ - --disable-hidapi-joystick \ - --disable-hidapi-libusb \ - --disable-joystick-virtual \ - --enable-video-mali \ - --disable-libsamplerate && make - # copy libs from toolchain (later moved to build) - cp $(PREFIX)/lib/libSDL2_image-2.0.so.0.0.1 ../libSDL2_image-2.0.so.0 - cp $(PREFIX)/lib/libSDL2_ttf-2.0.so.0.14.0 ../libSDL2_ttf-2.0.so.0 - -clean: - cd boot && rm -rf output - cd $(REQUIRES_UNZIP60) && make -f unix/Makefile.trimuismart clean - cd $(REQUIRES_FBSET) && make clean - -$(REQUIRES_UNZIP60): - git clone --depth 1 https://github.com/shauninman/unzip60.git $(REQUIRES_UNZIP60) - -$(REQUIRES_SDL2): - git clone https://github.com/JohnnyonFlame/SDL-malifbdev-rot $(REQUIRES_SDL2) - -$(REQUIRES_DTC): - git clone https://github.com/dgibson/dtc $(REQUIRES_DTC) - -$(REQUIRES_FBSET): - git clone https://github.com/shauninman/union-fbset $(REQUIRES_FBSET) - -include ../all/readmes/makefile diff --git a/workspace/_unmaintained/rg35xxplus/platform/makefile.copy b/workspace/_unmaintained/rg35xxplus/platform/makefile.copy deleted file mode 100644 index b487cffc8..000000000 --- a/workspace/_unmaintained/rg35xxplus/platform/makefile.copy +++ /dev/null @@ -1,15 +0,0 @@ -$(PLATFORM): - # $@ - cp ./workspace/$@/init/init.elf ./build/SYSTEM/$@/bin/ - cp ./workspace/$@/install/install.sh ./build/SYSTEM/$@/bin/ - cp ./workspace/$@/boot/output/dmenu.bin ./build/SYSTEM/$@/dat/ - mkdir -p ./build/BASE/$@ - cp ./workspace/$@/boot/output/dmenu.bin ./build/BASE/$@/ - cp ./workspace/$@/show/show.elf ./build/SYSTEM/$@/bin - cp ./workspace/$@/other/fbset/fbset ./build/SYSTEM/$@/bin - cp ./workspace/$@/other/dtc/dtc ./build/EXTRAS/Tools/$@/Apply\ Panel\ Fix.pak/bin - cp ./workspace/$@/other/dtc/dtc ./build/EXTRAS/Tools/$@/Swap\ Menu.pak/bin - cp ./workspace/$@/other/sdl2/build/.libs/libSDL2-2.0.so.0.2800.5 ./build/SYSTEM/$@/lib/libSDL2-2.0.so.0 - # move libs (copied from toolchain) - mv ./workspace/libSDL2_image-2.0.so.0 ./build/SYSTEM/$@/lib/ - mv ./workspace/libSDL2_ttf-2.0.so.0 ./build/SYSTEM/$@/lib/ \ No newline at end of file diff --git a/workspace/_unmaintained/rg35xxplus/platform/makefile.env b/workspace/_unmaintained/rg35xxplus/platform/makefile.env deleted file mode 100644 index b625daa49..000000000 --- a/workspace/_unmaintained/rg35xxplus/platform/makefile.env +++ /dev/null @@ -1,4 +0,0 @@ -# rg35xx -ARCH = -marm -mtune=cortex-a53 -mfpu=neon-fp-armv8 -mfloat-abi=hard -mcpu=cortex-a53 -LIBS = -flto -SDL = SDL2 \ No newline at end of file diff --git a/workspace/_unmaintained/rg35xxplus/platform/platform.c b/workspace/_unmaintained/rg35xxplus/platform/platform.c deleted file mode 100644 index ef342ab92..000000000 --- a/workspace/_unmaintained/rg35xxplus/platform/platform.c +++ /dev/null @@ -1,980 +0,0 @@ -// rg35xxplus -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include "defines.h" -#include "platform.h" -#include "api.h" -#include "utils.h" - -#include "scaler.h" - -int is_cubexx = 0; -int is_rg34xx = 0; -int on_hdmi = 0; - -/////////////////////////////// - -#define RAW_UP 103 -#define RAW_DOWN 108 -#define RAW_LEFT 105 -#define RAW_RIGHT 106 -#define RAW_A 304 -#define RAW_B 305 -#define RAW_X 307 -#define RAW_Y 306 -#define RAW_START 311 -#define RAW_SELECT 310 -#define RAW_MENU 312 -#define RAW_L1 308 -#define RAW_L2 314 -#define RAW_L3 313 -#define RAW_R1 309 -#define RAW_R2 315 -#define RAW_R3 316 -#define RAW_PLUS 115 -#define RAW_MINUS 114 -#define RAW_POWER 116 -#define RAW_HATY 17 -#define RAW_HATX 16 -#define RAW_LSY 3 -#define RAW_LSX 2 -#define RAW_RSY 5 -#define RAW_RSX 4 - -#define RAW_MENU1 RAW_L3 -#define RAW_MENU2 RAW_R3 - -// TODO: thanks I hate it -// RG P01 -#define RGP01_A 305 -#define RGP01_B 304 -#define RGP01_X 308 -#define RGP01_Y 307 -#define RGP01_START 315 -#define RGP01_SELECT 314 -#define RGP01_MENU 316 -#define RGP01_L1 310 -#define RGP01_L2 312 -#define RGP01_L3 317 -#define RGP01_R1 311 -#define RGP01_R2 313 -#define RGP01_R3 318 -#define RGP01_LSY 1 -#define RGP01_LSX 0 -#define RGP01_RSY 5 -#define RGP01_RSX 2 -#define RGP01_MENU1 RGP01_L3 -#define RGP01_MENU2 RGP01_R3 - -// X-box (8BitDo SN30 Pro) -#define XBOX_A 305 -#define XBOX_B 304 -#define XBOX_X 308 -#define XBOX_Y 307 -#define XBOX_START 315 -#define XBOX_SELECT 314 -#define XBOX_MENU 316 -#define XBOX_L1 310 -#define XBOX_L2 2 -#define XBOX_L3 317 -#define XBOX_R1 311 -#define XBOX_R2 5 -#define XBOX_R3 318 -#define XBOX_LSY 1 -#define XBOX_LSX 0 -#define XBOX_RSY 4 -#define XBOX_RSX 3 -#define XBOX_MENU1 XBOX_L3 -#define XBOX_MENU2 XBOX_R3 - -typedef enum GamepadType { - kGamepadTypeUnknown, - kGamepadTypeRGP01, - kGamepadTypeXbox, -} GamepadType; - -#define INPUT_COUNT 3 -static int inputs[INPUT_COUNT]; - -#define kPadIndex 2 -static GamepadType pad_type = kGamepadTypeUnknown; - -#define LID_PATH "/sys/class/power_supply/axp2202-battery/hallkey" -void PLAT_initLid(void) { - lid.has_lid = exists(LID_PATH); -} -int PLAT_lidChanged(int* state) { - if (lid.has_lid) { - int lid_open = getInt(LID_PATH); - if (lid_open!=lid.is_open) { - lid.is_open = lid_open; - if (state) *state = lid_open; - return 1; - } - } - return 0; -} - -static void checkForGamepad(void) { - uint32_t now = SDL_GetTicks(); - static uint32_t last_check = 0; - if (last_check==0 || now-last_check>2000) { - last_check = now; - int connected = exists("/dev/input/event3"); - if (inputs[kPadIndex]<0 && connected) { - LOG_info("Connecting gamepad: "); - char pad_name[256]; - getFile("/sys/class/input/event3/device/name", pad_name, 256); - if (containsString(pad_name,"Anbernic")) { - LOG_info("P01\n"); - pad_type = kGamepadTypeRGP01; - } - else if (containsString(pad_name, "Microsoft")) { - LOG_info("Xbox\n"); - pad_type = kGamepadTypeXbox; - } - else { - LOG_info("Unknown\n"); - pad_type = kGamepadTypeUnknown; - } - - inputs[kPadIndex] = open("/dev/input/event3", O_RDONLY | O_NONBLOCK | O_CLOEXEC); - } - else if (inputs[kPadIndex]>=0 && !connected) { - LOG_info("Gamepad disconnected\n"); - close(inputs[kPadIndex]); - inputs[kPadIndex] = -1; - pad_type = kGamepadTypeUnknown; - } - } -} - -void PLAT_initInput(void) { - inputs[0] = open("/dev/input/event0", O_RDONLY | O_NONBLOCK | O_CLOEXEC); - inputs[1] = open("/dev/input/event1", O_RDONLY | O_NONBLOCK | O_CLOEXEC); - inputs[kPadIndex] = -1; - checkForGamepad(); -} -void PLAT_quitInput(void) { - for (int i=0; i which has BTN_ constants that conflict with platform.h -struct input_event { - struct timeval time; - __u16 type; - __u16 code; - __s32 value; -}; -#define EV_KEY 0x01 -#define EV_ABS 0x03 - -void PLAT_pollInput(void) { - // reset transient state - pad.just_pressed = BTN_NONE; - pad.just_released = BTN_NONE; - pad.just_repeated = BTN_NONE; - - uint32_t tick = SDL_GetTicks(); - for (int i=0; i=pad.repeat_at[i])) { - pad.just_repeated |= btn; // set - pad.repeat_at[i] += PAD_REPEAT_INTERVAL; - } - } - - checkForGamepad(); - - // the actual poll - int input; - static struct input_event event; - for (int i=0; i1) continue; // ignore repeats - - pressed = value; - // LOG_info("key event: %i (%i)\n", code,pressed); - if (i==kPadIndex) { - if (pad_type==kGamepadTypeRGP01) { - if (code==RGP01_A) { btn = BTN_A; id = BTN_ID_A; } - else if (code==RGP01_B) { btn = BTN_B; id = BTN_ID_B; } - else if (code==RGP01_X) { btn = BTN_X; id = BTN_ID_X; } - else if (code==RGP01_Y) { btn = BTN_Y; id = BTN_ID_Y; } - else if (code==RGP01_START) { btn = BTN_START; id = BTN_ID_START; } - else if (code==RGP01_SELECT) { btn = BTN_SELECT; id = BTN_ID_SELECT; } - else if (code==RGP01_MENU) { btn = BTN_MENU; id = BTN_ID_MENU; } - else if (code==RGP01_MENU1) { btn = BTN_MENU; id = BTN_ID_MENU; } - else if (code==RGP01_MENU2) { btn = BTN_MENU; id = BTN_ID_MENU; } - else if (code==RGP01_L1) { btn = BTN_L1; id = BTN_ID_L1; } - else if (code==RGP01_L2) { btn = BTN_L2; id = BTN_ID_L2; } - else if (code==RGP01_L3) { btn = BTN_L3; id = BTN_ID_L3; } - else if (code==RGP01_R1) { btn = BTN_R1; id = BTN_ID_R1; } - else if (code==RGP01_R2) { btn = BTN_R2; id = BTN_ID_R2; } - else if (code==RGP01_R3) { btn = BTN_R3; id = BTN_ID_R3; } - } - else if (pad_type==kGamepadTypeXbox) { - if (code==XBOX_A) { btn = BTN_A; id = BTN_ID_A; } - else if (code==XBOX_B) { btn = BTN_B; id = BTN_ID_B; } - else if (code==XBOX_X) { btn = BTN_X; id = BTN_ID_X; } - else if (code==XBOX_Y) { btn = BTN_Y; id = BTN_ID_Y; } - else if (code==XBOX_START) { btn = BTN_START; id = BTN_ID_START; } - else if (code==XBOX_SELECT) { btn = BTN_SELECT; id = BTN_ID_SELECT; } - else if (code==XBOX_MENU) { btn = BTN_MENU; id = BTN_ID_MENU; } - else if (code==XBOX_MENU1) { btn = BTN_MENU; id = BTN_ID_MENU; } - else if (code==XBOX_MENU2) { btn = BTN_MENU; id = BTN_ID_MENU; } - else if (code==XBOX_L1) { btn = BTN_L1; id = BTN_ID_L1; } - else if (code==XBOX_L3) { btn = BTN_L3; id = BTN_ID_L3; } - else if (code==XBOX_R1) { btn = BTN_R1; id = BTN_ID_R1; } - else if (code==XBOX_R3) { btn = BTN_R3; id = BTN_ID_R3; } - } - } - else { - if (code==RAW_UP) { btn = BTN_DPAD_UP; id = BTN_ID_DPAD_UP; } - else if (code==RAW_DOWN) { btn = BTN_DPAD_DOWN; id = BTN_ID_DPAD_DOWN; } - else if (code==RAW_LEFT) { btn = BTN_DPAD_LEFT; id = BTN_ID_DPAD_LEFT; } - else if (code==RAW_RIGHT) { btn = BTN_DPAD_RIGHT; id = BTN_ID_DPAD_RIGHT; } - else if (code==RAW_A) { btn = BTN_A; id = BTN_ID_A; } - else if (code==RAW_B) { btn = BTN_B; id = BTN_ID_B; } - else if (code==RAW_X) { btn = BTN_X; id = BTN_ID_X; } - else if (code==RAW_Y) { btn = BTN_Y; id = BTN_ID_Y; } - else if (code==RAW_START) { btn = BTN_START; id = BTN_ID_START; } - else if (code==RAW_SELECT) { btn = BTN_SELECT; id = BTN_ID_SELECT; } - else if (code==RAW_MENU) { btn = BTN_MENU; id = BTN_ID_MENU; } - else if (code==RAW_MENU1) { btn = BTN_MENU; id = BTN_ID_MENU; } - else if (code==RAW_MENU2) { btn = BTN_MENU; id = BTN_ID_MENU; } - else if (code==RAW_L1) { btn = BTN_L1; id = BTN_ID_L1; } - else if (code==RAW_L2) { btn = BTN_L2; id = BTN_ID_L2; } - else if (code==RAW_L3) { btn = BTN_L3; id = BTN_ID_L3; } - else if (code==RAW_R1) { btn = BTN_R1; id = BTN_ID_R1; } - else if (code==RAW_R2) { btn = BTN_R2; id = BTN_ID_R2; } - else if (code==RAW_R3) { btn = BTN_R3; id = BTN_ID_R3; } - else if (code==RAW_PLUS) { btn = BTN_PLUS; id = BTN_ID_PLUS; } - else if (code==RAW_MINUS) { btn = BTN_MINUS; id = BTN_ID_MINUS; } - else if (code==RAW_POWER) { btn = BTN_POWER; id = BTN_ID_POWER; } - } - } - else if (type==EV_ABS) { - // LOG_info("abs event: %i (%i)\n", code,value); - // { up, down, left, right } - if (code==RAW_HATY || code==RAW_HATX) { - if (value>1) continue; // ignore repeats - - int hats[4] = {-1,-1,-1,-1}; // -1=no change,1=pressed,0=released - if (code==RAW_HATY) { - hats[0] = value==-1; // up - hats[1] = value==1; // down - } - else if (code==RAW_HATX) { // left/right - hats[2] = value==-1; // left - hats[3] = value==1; // right - } - - for (id=0; id<4; id++) { - int state = hats[id]; - btn = 1 << id; - if (state==0) { - pad.is_pressed &= ~btn; // unset - pad.just_repeated &= ~btn; // unset - pad.just_released |= btn; // set - } - else if (state==1 && (pad.is_pressed & btn)==BTN_NONE) { - pad.just_pressed |= btn; // set - pad.just_repeated |= btn; // set - pad.is_pressed |= btn; // set - pad.repeat_at[id] = tick + PAD_REPEAT_DELAY; - } - } - - btn = BTN_NONE; // already handled, force continue - } - else if (i==kPadIndex) { - if (pad_type==kGamepadTypeRGP01) { - if (code==RGP01_LSX) { pad.laxis.x = ((value-128) * 32767) / 128; PAD_setAnalog(BTN_ID_ANALOG_LEFT, BTN_ID_ANALOG_RIGHT, pad.laxis.x, tick+PAD_REPEAT_DELAY); } - else if (code==RGP01_LSY) { pad.laxis.y = ((value-128) * 32767) / 128; PAD_setAnalog(BTN_ID_ANALOG_UP, BTN_ID_ANALOG_DOWN, pad.laxis.y, tick+PAD_REPEAT_DELAY); } - else if (code==RGP01_RSX) pad.raxis.x = ((value-128) * 32767) / 128; - else if (code==RGP01_RSY) pad.raxis.y = ((value-128) * 32767) / 128; - } - else if (pad_type==kGamepadTypeXbox) { - if (code==XBOX_LSX) { pad.laxis.x = value; PAD_setAnalog(BTN_ID_ANALOG_LEFT, BTN_ID_ANALOG_RIGHT, pad.laxis.x, tick+PAD_REPEAT_DELAY); } - else if (code==XBOX_LSY) { pad.laxis.y = value; PAD_setAnalog(BTN_ID_ANALOG_UP, BTN_ID_ANALOG_DOWN, pad.laxis.y, tick+PAD_REPEAT_DELAY); } - else if (code==XBOX_RSX) pad.raxis.x = value; - else if (code==XBOX_RSY) pad.raxis.y = value; - else if (code==XBOX_L2) { pressed = value>0; btn = BTN_L2; id = BTN_ID_L2; } - else if (code==XBOX_R2) { pressed = value>0; btn = BTN_R2; id = BTN_ID_R2; } - } - } - else { - if (code==RAW_LSX) { pad.laxis.x = (value * 32767) / 4096; PAD_setAnalog(BTN_ID_ANALOG_LEFT, BTN_ID_ANALOG_RIGHT, pad.laxis.x, tick+PAD_REPEAT_DELAY); } - else if (code==RAW_LSY) { pad.laxis.y = (value * 32767) / 4096; PAD_setAnalog(BTN_ID_ANALOG_UP, BTN_ID_ANALOG_DOWN, pad.laxis.y, tick+PAD_REPEAT_DELAY); } - else if (code==RAW_RSX) pad.raxis.x = (value * 32767) / 4096; - else if (code==RAW_RSY) pad.raxis.y = (value * 32767) / 4096; - } - } - - if (btn==BTN_NONE) continue; - - if (!pressed) { - pad.is_pressed &= ~btn; // unset - pad.just_repeated &= ~btn; // unset - pad.just_released |= btn; // set - } - else if ((pad.is_pressed & btn)==BTN_NONE) { - pad.just_pressed |= btn; // set - pad.just_repeated |= btn; // set - pad.is_pressed |= btn; // set - pad.repeat_at[id] = tick + PAD_REPEAT_DELAY; - } - } - } - - if (lid.has_lid && PLAT_lidChanged(NULL)) pad.just_released |= BTN_SLEEP; -} - -int PLAT_shouldWake(void) { - int lid_open = 1; // assume open by default - if (lid.has_lid && PLAT_lidChanged(&lid_open) && lid_open) return 1; - - int input; - static struct input_event event; - for (int i=0; imode.w) rotate = 3; // no longer set on 28xx (because of SDL2 rotation patch?) - vid.renderer = SDL_CreateRenderer(vid.window,-1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC); - // SDL_RenderSetLogicalSize(vid.renderer, w,h); // TODO: wrong, but without and with the below it's even wrong-er - - // int renderer_width,renderer_height; - // SDL_GetRendererOutputSize(vid.renderer, &renderer_width, &renderer_height); - // LOG_info("output size: %ix%i\n", renderer_width, renderer_height); - // if (renderer_width!=w) { // I think this can only be hdmi - // float x_scale = (float)renderer_width / w; - // float y_scale = (float)renderer_height / h; - // SDL_SetWindowSize(vid.window, w / x_scale, h / y_scale); - // - // SDL_GetRendererOutputSize(vid.renderer, &renderer_width, &renderer_height); - // LOG_info("adjusted size: %ix%i\n", renderer_width, renderer_height); - // x_scale = (float)renderer_width / w; - // y_scale = (float)renderer_height / h; - // SDL_RenderSetScale(vid.renderer, x_scale,y_scale); - // - // // for some reason we need to clear and present - // // after setting the window size or we'll miss - // // the first frame - // SDL_RenderClear(vid.renderer); - // SDL_RenderPresent(vid.renderer); - // } - // - // SDL_RendererInfo info; - // SDL_GetRendererInfo(vid.renderer, &info); - // LOG_info("Current render driver: %s\n", info.name); - - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY,"1"); // linear - vid.texture = SDL_CreateTexture(vid.renderer,SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, w,h); - vid.target = NULL; // only needed for non-native sizes - - // TODO: doesn't work here - // SDL_SetTextureScaleMode(vid.texture, SDL_ScaleModeLinear); // we always start at device size so use linear for better upscaling over hdmi - - // SDL_ScaleMode scale_mode; - // SDL_GetTextureScaleMode(vid.texture, &scale_mode); - // LOG_info("texture scale mode: %i\n", scale_mode); - - // int format; - // int access_; - // SDL_QueryTexture(vid.texture, &format, &access_, NULL,NULL); - // LOG_info("texture format: %s (streaming: %i)\n", SDL_GetPixelFormatName(format), access_==SDL_TEXTUREACCESS_STREAMING); - - vid.buffer = SDL_CreateRGBSurfaceFrom(NULL, w,h, FIXED_DEPTH, p, RGBA_MASK_565); - vid.screen = SDL_CreateRGBSurface(SDL_SWSURFACE, w,h, FIXED_DEPTH, RGBA_MASK_565); - vid.width = w; - vid.height = h; - vid.pitch = p; - - device_width = w; - device_height = h; - device_pitch = p; - - vid.sharpness = SHARPNESS_SOFT; - - return vid.screen; -} - -static void clearVideo(void) { - SDL_FillRect(vid.screen, NULL, 0); - for (int i=0; i<3; i++) { - SDL_RenderClear(vid.renderer); - SDL_RenderPresent(vid.renderer); - } -} - -void PLAT_quitVideo(void) { - // clearVideo(); - - SDL_FreeSurface(vid.screen); - SDL_FreeSurface(vid.buffer); - if (vid.target) SDL_DestroyTexture(vid.target); - if (vid.effect) SDL_DestroyTexture(vid.effect); - SDL_DestroyTexture(vid.texture); - SDL_DestroyRenderer(vid.renderer); - SDL_DestroyWindow(vid.window); - - // system("cat /dev/zero > /dev/fb0 2>/dev/null"); - SDL_Quit(); -} - -void PLAT_clearVideo(SDL_Surface* screen) { - SDL_FillRect(screen, NULL, 0); // TODO: revisit -} -void PLAT_clearAll(void) { - PLAT_clearVideo(vid.screen); // TODO: revist - SDL_RenderClear(vid.renderer); -} - -void PLAT_setVsync(int vsync) { - // buh -} - -static int hard_scale = 4; // TODO: base src size, eg. 160x144 can be 4 - -static void resizeVideo(int w, int h, int p) { - if (w==vid.width && h==vid.height && p==vid.pitch) return; - - // TODO: minarch disables crisp (and nn upscale before linear downscale) when native - - if (w>=device_width && h>=device_height) hard_scale = 1; - else if (h>=160) hard_scale = 2; // limits gba and up to 2x (seems sufficient for 640x480) - else hard_scale = 4; - - LOG_info("resizeVideo(%i,%i,%i) hard_scale: %i crisp: %i\n",w,h,p, hard_scale,vid.sharpness==SHARPNESS_CRISP); - - SDL_FreeSurface(vid.buffer); - SDL_DestroyTexture(vid.texture); - if (vid.target) SDL_DestroyTexture(vid.target); - - SDL_SetHintWithPriority(SDL_HINT_RENDER_SCALE_QUALITY, vid.sharpness==SHARPNESS_SOFT?"1":"0", SDL_HINT_OVERRIDE); - vid.texture = SDL_CreateTexture(vid.renderer,SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, w,h); - - if (vid.sharpness==SHARPNESS_CRISP) { - SDL_SetHintWithPriority(SDL_HINT_RENDER_SCALE_QUALITY, "1", SDL_HINT_OVERRIDE); - vid.target = SDL_CreateTexture(vid.renderer,SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_TARGET, w * hard_scale,h * hard_scale); - } - else { - vid.target = NULL; - } - - vid.buffer = SDL_CreateRGBSurfaceFrom(NULL, w,h, FIXED_DEPTH, p, RGBA_MASK_565); - - vid.width = w; - vid.height = h; - vid.pitch = p; -} - -SDL_Surface* PLAT_resizeVideo(int w, int h, int p) { - resizeVideo(w,h,p); - return vid.screen; -} - -void PLAT_setVideoScaleClip(int x, int y, int width, int height) { - // buh -} -void PLAT_setNearestNeighbor(int enabled) { - // buh -} -void PLAT_setSharpness(int sharpness) { - if (vid.sharpness==sharpness) return; - int p = vid.pitch; - vid.pitch = 0; - vid.sharpness = sharpness; - resizeVideo(vid.width,vid.height,p); -} - -static struct FX_Context { - int scale; - int type; - int color; - int next_scale; - int next_type; - int next_color; - int live_type; -} effect = { - .scale = 1, - .next_scale = 1, - .type = EFFECT_NONE, - .next_type = EFFECT_NONE, - .live_type = EFFECT_NONE, - .color = 0, - .next_color = 0, -}; -static void rgb565_to_rgb888(uint32_t rgb565, uint8_t *r, uint8_t *g, uint8_t *b) { - // Extract the red component (5 bits) - uint8_t red = (rgb565 >> 11) & 0x1F; - // Extract the green component (6 bits) - uint8_t green = (rgb565 >> 5) & 0x3F; - // Extract the blue component (5 bits) - uint8_t blue = rgb565 & 0x1F; - - // Scale the values to 8-bit range - *r = (red << 3) | (red >> 2); - *g = (green << 2) | (green >> 4); - *b = (blue << 3) | (blue >> 2); -} -static void updateEffect(void) { - if (effect.next_scale==effect.scale && effect.next_type==effect.type && effect.next_color==effect.color) return; // unchanged - - int live_scale = effect.scale; - int live_color = effect.color; - effect.scale = effect.next_scale; - effect.type = effect.next_type; - effect.color = effect.next_color; - - if (effect.type==EFFECT_NONE) return; // disabled - if (effect.type==effect.live_type && effect.scale==live_scale && effect.color==live_color) return; // already loaded - - char* effect_path; - int opacity = 128; // 1 - 1/2 = 50% - if (effect.type==EFFECT_LINE) { - if (effect.scale<3) { - effect_path = RES_PATH "/line-2.png"; - } - else if (effect.scale<4) { - effect_path = RES_PATH "/line-3.png"; - } - else if (effect.scale<5) { - effect_path = RES_PATH "/line-4.png"; - } - else if (effect.scale<6) { - effect_path = RES_PATH "/line-5.png"; - } - else if (effect.scale<8) { - effect_path = RES_PATH "/line-6.png"; - } - else { - effect_path = RES_PATH "/line-8.png"; - } - } - else if (effect.type==EFFECT_GRID) { - if (effect.scale<3) { - effect_path = RES_PATH "/grid-2.png"; - opacity = 64; // 1 - 3/4 = 25% - } - else if (effect.scale<4) { - effect_path = RES_PATH "/grid-3.png"; - opacity = 112; // 1 - 5/9 = ~44% - } - else if (effect.scale<5) { - effect_path = RES_PATH "/grid-4.png"; - opacity = 144; // 1 - 7/16 = ~56% - } - else if (effect.scale<6) { - effect_path = RES_PATH "/grid-5.png"; - opacity = 160; // 1 - 9/25 = ~64% - } - else if (effect.scale<8) { - effect_path = RES_PATH "/grid-6.png"; - opacity = 112; // 1 - 5/9 = ~44% - } - else if (effect.scale<11) { - effect_path = RES_PATH "/grid-8.png"; - opacity = 144; // 1 - 7/16 = ~56% - } - else { - effect_path = RES_PATH "/grid-11.png"; - opacity = 136; // 1 - 57/121 = ~52% - } - } - - // LOG_info("effect: %s opacity: %i\n", effect_path, opacity); - SDL_Surface* tmp = IMG_Load(effect_path); - if (tmp) { - if (effect.type==EFFECT_GRID) { - if (effect.color) { - // LOG_info("dmg color grid...\n"); - - uint8_t r,g,b; - rgb565_to_rgb888(effect.color,&r,&g,&b); - // LOG_info("rgb %i,%i,%i\n",r,g,b); - - uint32_t* pixels = (uint32_t*)tmp->pixels; - int width = tmp->w; - int height = tmp->h; - for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) { - uint32_t pixel = pixels[y * width + x]; - uint8_t _,a; - SDL_GetRGBA(pixel, tmp->format, &_, &_, &_, &a); - if (a) pixels[y * width + x] = SDL_MapRGBA(tmp->format, r,g,b, a); - } - } - } - } - - if (vid.effect) SDL_DestroyTexture(vid.effect); - vid.effect = SDL_CreateTextureFromSurface(vid.renderer, tmp); - SDL_SetTextureAlphaMod(vid.effect, opacity); - SDL_FreeSurface(tmp); - effect.live_type = effect.type; - } - } -void PLAT_setEffect(int next_type) { - effect.next_type = next_type; -} -void PLAT_setEffectColor(int next_color) { - effect.next_color = next_color; -} -void PLAT_vsync(int remaining) { - if (remaining>0) SDL_Delay(remaining); -} - -scaler_t PLAT_getScaler(GFX_Renderer* renderer) { - // LOG_info("getScaler for scale: %i\n", renderer->scale); - effect.next_scale = renderer->scale; - return scale1x1_c16; -} - -void PLAT_blitRenderer(GFX_Renderer* renderer) { - vid.blit = renderer; - SDL_RenderClear(vid.renderer); - resizeVideo(vid.blit->true_w,vid.blit->true_h,vid.blit->src_p); -} - -void PLAT_flip(SDL_Surface* IGNORED, int ignored) { - - on_hdmi = GetHDMI(); // use settings instead of getInt(HDMI_STATE_PATH) - - if (!vid.blit) { - resizeVideo(device_width,device_height,FIXED_PITCH); // !!!??? - SDL_UpdateTexture(vid.texture,NULL,vid.screen->pixels,vid.screen->pitch); - if (rotate && !on_hdmi) SDL_RenderCopyEx(vid.renderer,vid.texture,NULL,&(SDL_Rect){0,device_width,device_width,device_height},rotate*90,&(SDL_Point){0,0},SDL_FLIP_NONE); - else SDL_RenderCopy(vid.renderer, vid.texture, NULL,NULL); - SDL_RenderPresent(vid.renderer); - return; - } - - // uint32_t then = SDL_GetTicks(); - SDL_UpdateTexture(vid.texture,NULL,vid.blit->src,vid.blit->src_p); - // LOG_info("blit blocked for %ims (%i,%i)\n", SDL_GetTicks()-then,vid.buffer->w,vid.buffer->h); - - SDL_Texture* target = vid.texture; - int x = vid.blit->src_x; - int y = vid.blit->src_y; - int w = vid.blit->src_w; - int h = vid.blit->src_h; - if (vid.sharpness==SHARPNESS_CRISP) { - SDL_SetRenderTarget(vid.renderer,vid.target); - SDL_RenderCopy(vid.renderer, vid.texture, NULL,NULL); - SDL_SetRenderTarget(vid.renderer,NULL); - x *= hard_scale; - y *= hard_scale; - w *= hard_scale; - h *= hard_scale; - target = vid.target; - } - - SDL_Rect* src_rect = &(SDL_Rect){x,y,w,h}; - SDL_Rect* dst_rect = &(SDL_Rect){0,0,device_width,device_height}; - if (vid.blit->aspect==0) { // native or cropped - // LOG_info("src_rect %i,%i %ix%i\n",src_rect->x,src_rect->y,src_rect->w,src_rect->h); - - int w = vid.blit->src_w * vid.blit->scale; - int h = vid.blit->src_h * vid.blit->scale; - int x = (device_width - w) / 2; - int y = (device_height - h) / 2; - dst_rect->x = x; - dst_rect->y = y; - dst_rect->w = w; - dst_rect->h = h; - - // LOG_info("dst_rect %i,%i %ix%i\n",dst_rect->x,dst_rect->y,dst_rect->w,dst_rect->h); - } - else if (vid.blit->aspect>0) { // aspect - int h = device_height; - int w = h * vid.blit->aspect; - if (w>device_width) { - double ratio = 1 / vid.blit->aspect; - w = device_width; - h = w * ratio; - } - int x = (device_width - w) / 2; - int y = (device_height - h) / 2; - // dst_rect = &(SDL_Rect){x,y,w,h}; - dst_rect->x = x; - dst_rect->y = y; - dst_rect->w = w; - dst_rect->h = h; - } - - int ox,oy; - oy = (device_width-device_height)/2; - ox = -oy; - if (rotate && !on_hdmi) SDL_RenderCopyEx(vid.renderer,target,src_rect,&(SDL_Rect){ox+dst_rect->x,oy+dst_rect->y,dst_rect->w,dst_rect->h},rotate*90,NULL,SDL_FLIP_NONE); - else SDL_RenderCopy(vid.renderer, target, src_rect, dst_rect); - - updateEffect(); - if (vid.blit && effect.type!=EFFECT_NONE && vid.effect) { - // ox = effect.scale - (dst_rect->x % effect.scale); - // oy = effect.scale - (dst_rect->y % effect.scale); - // if (ox==effect.scale) ox = 0; - // if (oy==effect.scale) oy = 0; - // LOG_info("rotate: %i ox: %i oy: %i\n", rotate, ox,oy); - if (rotate && !on_hdmi) SDL_RenderCopyEx(vid.renderer,vid.effect,&(SDL_Rect){0,0,dst_rect->w,dst_rect->h},&(SDL_Rect){ox+dst_rect->x,oy+dst_rect->y,dst_rect->w,dst_rect->h},rotate*90,NULL,SDL_FLIP_NONE); - else SDL_RenderCopy(vid.renderer, vid.effect, &(SDL_Rect){0,0,dst_rect->w,dst_rect->h},dst_rect); - } - - // uint32_t then = SDL_GetTicks(); - SDL_RenderPresent(vid.renderer); - // LOG_info("SDL_RenderPresent blocked for %ims\n", SDL_GetTicks()-then); - vid.blit = NULL; -} - -int PLAT_supportsOverscan(void) { return is_cubexx; } - -/////////////////////////////// - -// TODO: -#define OVERLAY_WIDTH PILL_SIZE // unscaled -#define OVERLAY_HEIGHT PILL_SIZE // unscaled -#define OVERLAY_BPP 4 -#define OVERLAY_DEPTH 16 -#define OVERLAY_PITCH (OVERLAY_WIDTH * OVERLAY_BPP) // unscaled -#define OVERLAY_RGBA_MASK 0x00ff0000,0x0000ff00,0x000000ff,0xff000000 // ARGB -static struct OVL_Context { - SDL_Surface* overlay; -} ovl; - -SDL_Surface* PLAT_initOverlay(void) { - ovl.overlay = SDL_CreateRGBSurface(SDL_SWSURFACE, SCALE2(OVERLAY_WIDTH,OVERLAY_HEIGHT),OVERLAY_DEPTH,OVERLAY_RGBA_MASK); - return ovl.overlay; -} -void PLAT_quitOverlay(void) { - if (ovl.overlay) SDL_FreeSurface(ovl.overlay); -} -void PLAT_enableOverlay(int enable) { - -} - -/////////////////////////////// - -static int online = 0; -void PLAT_getBatteryStatus(int* is_charging, int* charge) { - PLAT_getBatteryStatusFine(is_charging, charge); - - // worry less about battery and more about the game you're playing - if (*charge>80) *charge = 100; - else if (*charge>60) *charge = 80; - else if (*charge>40) *charge = 60; - else if (*charge>20) *charge = 40; - else if (*charge>10) *charge = 20; - else *charge = 10; -} - -void PLAT_getBatteryStatusFine(int* is_charging, int* charge) -{ - // *is_charging = 0; - // *charge = PWR_LOW_CHARGE; - // return; - - *is_charging = getInt("/sys/class/power_supply/axp2202-usb/online"); - - *charge = getInt("/sys/class/power_supply/axp2202-battery/capacity"); - - // wifi status, just hooking into the regular PWR polling - char status[16]; - getFile("/sys/class/net/wlan0/operstate", status,16); - online = prefixMatch("up", status); -} - -#define LED_PATH "/sys/class/power_supply/axp2202-battery/work_led" -void PLAT_enableBacklight(int enable) { - if (enable) { - putInt(BLANK_PATH, FB_BLANK_UNBLANK); // wake - SetBrightness(GetBrightness()); - putInt(LED_PATH,0); - } - else { - putInt(BLANK_PATH, FB_BLANK_POWERDOWN); // sleep - SetRawBrightness(0); - putInt(LED_PATH,1); - } -} - -void PLAT_powerOff(void) { - system("rm -f /tmp/nextui_exec && sync"); - sleep(2); - - SetRawVolume(MUTE_VOLUME_RAW); - PLAT_enableBacklight(0); - system("echo 1 > /sys/class/power_supply/axp2202-battery/work_led"); - SND_quit(); - VIB_quit(); - PWR_quit(); - GFX_quit(); - - // system("cat /dev/zero > /dev/fb0 2>/dev/null"); - // system("shutdown"); - // while (1) pause(); // lolwat - - // touch("/tmp/poweroff"); - // sync(); - // system("touch /tmp/poweroff && sync"); - exit(0); -} - -/////////////////////////////// - -void PLAT_setCPUSpeed(int speed) { - // TODO: why wasn't this ever implemented? -} - -#define RUMBLE_PATH "/sys/class/power_supply/axp2202-battery/moto" -void PLAT_setRumble(int strength) { - if (GetHDMI()) return; // assume we're using a controller? - putInt(RUMBLE_PATH, strength?1:0); -} - -int PLAT_pickSampleRate(int requested, int max) { - return MIN(requested, max); -} - -static char model[256]; -char* PLAT_getModel(void) { - // firmware "strings /mnt/vendor/bin/dmenu.bin | grep ^20" - char* _model = getenv("RGXX_MODEL"); - if (_model!=NULL) { - if (exactMatch(_model,"RGcubexx")) _model = "RG CubeXX"; - - sprintf(model, "Anbernic %s", _model); - char* tmp = strrchr(model, '_'); - if (tmp) *tmp = '\0'; - return model; - } - return "Anbernic RG*XX"; -} - -int PLAT_isOnline(void) { - return online; -} \ No newline at end of file diff --git a/workspace/_unmaintained/rg35xxplus/platform/platform.h b/workspace/_unmaintained/rg35xxplus/platform/platform.h deleted file mode 100644 index fc7aee0e7..000000000 --- a/workspace/_unmaintained/rg35xxplus/platform/platform.h +++ /dev/null @@ -1,145 +0,0 @@ -// rg35xx/platform/platform.h - -#ifndef PLATFORM_H -#define PLATFORM_H - -/////////////////////////////// - -#include "sdl.h" - -/////////////////////////////// - -extern int is_cubexx; -extern int is_rg34xx; -extern int on_hdmi; - -/////////////////////////////// - -#define BUTTON_UP BUTTON_NA -#define BUTTON_DOWN BUTTON_NA -#define BUTTON_LEFT BUTTON_NA -#define BUTTON_RIGHT BUTTON_NA - -#define BUTTON_SELECT BUTTON_NA -#define BUTTON_START BUTTON_NA - -#define BUTTON_A BUTTON_NA -#define BUTTON_B BUTTON_NA -#define BUTTON_X BUTTON_NA -#define BUTTON_Y BUTTON_NA - -#define BUTTON_L1 BUTTON_NA -#define BUTTON_R1 BUTTON_NA -#define BUTTON_L2 BUTTON_NA -#define BUTTON_R2 BUTTON_NA -#define BUTTON_L3 BUTTON_NA -#define BUTTON_R3 BUTTON_NA - -#define BUTTON_MENU BUTTON_NA -#define BUTTON_POWER BUTTON_NA -#define BUTTON_PLUS BUTTON_NA -#define BUTTON_MINUS BUTTON_NA - -/////////////////////////////// - -#define CODE_UP CODE_NA -#define CODE_DOWN CODE_NA -#define CODE_LEFT CODE_NA -#define CODE_RIGHT CODE_NA - -#define CODE_SELECT CODE_NA -#define CODE_START CODE_NA - -#define CODE_A CODE_NA -#define CODE_B CODE_NA -#define CODE_X CODE_NA -#define CODE_Y CODE_NA - -#define CODE_L1 CODE_NA -#define CODE_R1 CODE_NA -#define CODE_L2 CODE_NA -#define CODE_R2 CODE_NA -#define CODE_L3 CODE_NA -#define CODE_R3 CODE_NA - -#define CODE_MENU CODE_NA -#define CODE_POWER 102 - -#define CODE_PLUS CODE_NA -#define CODE_MINUS CODE_NA - -/////////////////////////////// - -#define JOY_UP 13 -#define JOY_DOWN 16 -#define JOY_LEFT 14 -#define JOY_RIGHT 15 - -#define JOY_SELECT 6 -#define JOY_START 7 - -#define JOY_A 0 -#define JOY_B 1 -#define JOY_X 3 -#define JOY_Y 2 - -#define JOY_L1 4 -#define JOY_R1 5 -#define JOY_L2 9 -#define JOY_R2 10 -#define JOY_L3 JOY_NA -#define JOY_R3 JOY_NA - -#define JOY_MENU 8 -#define JOY_POWER JOY_NA -#define JOY_PLUS 18 -#define JOY_MINUS 17 - -/////////////////////////////// - -#define BTN_RESUME BTN_X -#define BTN_SLEEP BTN_POWER -#define BTN_WAKE BTN_POWER -#define BTN_MOD_VOLUME BTN_NONE -#define BTN_MOD_BRIGHTNESS BTN_MENU -#define BTN_MOD_PLUS BTN_PLUS -#define BTN_MOD_MINUS BTN_MINUS - -/////////////////////////////// - -#define FIXED_SCALE 2 -#define FIXED_WIDTH (is_cubexx?720:(is_rg34xx?720:640)) -#define FIXED_HEIGHT (is_cubexx?720:480) -#define FIXED_BPP 2 -#define FIXED_DEPTH (FIXED_BPP * 8) -#define FIXED_PITCH (FIXED_WIDTH * FIXED_BPP) -#define FIXED_SIZE (FIXED_PITCH * FIXED_HEIGHT) - -/////////////////////////////// - -#define HAS_HDMI 1 -#define HDMI_WIDTH 1280 -#define HDMI_HEIGHT 720 -#define HDMI_PITCH (HDMI_WIDTH * FIXED_BPP) -#define HDMI_SIZE (HDMI_PITCH * HDMI_HEIGHT) - -// TODO: if HDMI_HEIGHT > FIXED_HEIGHT then MAIN_ROW_COUNT will be insufficient - - -/////////////////////////////// - -#define MAIN_ROW_COUNT (is_cubexx||on_hdmi?8:6) -#define PADDING (is_cubexx||on_hdmi?40:10) - -/////////////////////////////// - -#define SDCARD_PATH "/mnt/sdcard" -#define MUTE_VOLUME_RAW 0 -#define HAS_NEON -#define SAMPLES 400 // fix for (most) fceumm underruns - -// this should be set to the devices native screen refresh rate -#define SCREEN_FPS 60.0 -/////////////////////////////// - -#endif diff --git a/workspace/_unmaintained/rg35xxplus/show/makefile b/workspace/_unmaintained/rg35xxplus/show/makefile deleted file mode 100755 index b61deed63..000000000 --- a/workspace/_unmaintained/rg35xxplus/show/makefile +++ /dev/null @@ -1,14 +0,0 @@ -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif - -TARGET = show -PRODUCT = $(TARGET).elf - -CC = $(CROSS_COMPILE)gcc -FLAGS = -Os -lSDL2 -lSDL2_image -lrt -ldl -Wl,--gc-sections -s - -all: - $(CC) $(TARGET).c -o $(PRODUCT) $(FLAGS) -clean: - rm -rf $(PRODUCT) \ No newline at end of file diff --git a/workspace/_unmaintained/rg35xxplus/show/show.c b/workspace/_unmaintained/rg35xxplus/show/show.c deleted file mode 100644 index f0c673c68..000000000 --- a/workspace/_unmaintained/rg35xxplus/show/show.c +++ /dev/null @@ -1,63 +0,0 @@ -// rg35xxplus -#include -#include -#include -#include - -#define FIXED_BPP 2 -#define FIXED_DEPTH (FIXED_BPP * 8) - -#define RGBA_MASK_565 0xF800, 0x07E0, 0x001F, 0x0000 - -int main(int argc , char* argv[]) { - if (argc<2) { - puts("Usage: show.elf image.png delay"); - return 0; - } - - char path[256]; - strncpy(path,argv[1],256); - if (access(path, F_OK)!=0) return 0; // nothing to show :( - - int delay = argc>2 ? atoi(argv[2]) : 2; - - SDL_Init(SDL_INIT_VIDEO); - SDL_ShowCursor(0); - - int w = 0; - int h = 0; - int p = 0; - SDL_Window* window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w,h, SDL_WINDOW_SHOWN); - - int rotate = 0; - SDL_DisplayMode mode; - SDL_GetCurrentDisplayMode(0, &mode); - if (mode.h>mode.w) rotate = 3; - w = mode.w; - h = mode.h; - p = mode.w * FIXED_BPP; - - SDL_Renderer* renderer = SDL_CreateRenderer(window,-1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC); - SDL_Texture* texture = SDL_CreateTexture(renderer,SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, w,h); - SDL_Surface* screen = SDL_CreateRGBSurfaceFrom(NULL, w,h, FIXED_DEPTH, p, RGBA_MASK_565); - - SDL_LockTexture(texture,NULL,&screen->pixels,&screen->pitch); - SDL_FillRect(screen, NULL, 0); - SDL_Surface* img = IMG_Load(path); - SDL_BlitSurface(img, NULL, screen, &(SDL_Rect){(screen->w-img->w)/2,(screen->h-img->h)/2}); - SDL_FreeSurface(img); - SDL_UnlockTexture(texture); - - if (rotate) SDL_RenderCopyEx(renderer,texture,NULL,&(SDL_Rect){0,w,w,h},rotate*90,&(SDL_Point){0,0},SDL_FLIP_NONE); - else SDL_RenderCopy(renderer, texture, NULL,NULL); - SDL_RenderPresent(renderer); - - sleep(delay); - - SDL_FreeSurface(screen); - SDL_DestroyTexture(texture); - SDL_DestroyRenderer(renderer); - SDL_DestroyWindow(window); - SDL_Quit(); - return 0; -} diff --git a/workspace/_unmaintained/rgb30/cores/makefile b/workspace/_unmaintained/rgb30/cores/makefile deleted file mode 100644 index dd72a09fe..000000000 --- a/workspace/_unmaintained/rgb30/cores/makefile +++ /dev/null @@ -1,40 +0,0 @@ -CORES = fceumm gambatte gpsp pcsx_rearmed picodrive snes9x2005_plus -CORES+= pokemini fake-08 mednafen_pce_fast mednafen_vb mednafen_supafaust mgba race - -############################### - -# optional core vars -# *_REPO= -# *_HASH= -# *_CORE= -# *_FLAGS= -# *_MAKEFILE= -# *_BUILD_PATH= - -mednafen_pce_fast_REPO = https://github.com/libretro/beetle-pce-fast-libretro -mednafen_vb_REPO = https://github.com/libretro/beetle-vb-libretro - -fake-08_REPO = https://github.com/jtothebell/fake-08 -fake-08_CORE = fake08_libretro.so -fake-08_BUILD_PATH = fake-08/platform/libretro - -fceumm_REPO = https://github.com/libretro/libretro-fceumm - -gambatte_REPO = https://github.com/libretro/gambatte-libretro - -mednafen_supafaust_REPO = https://github.com/libretro/supafaust - -pcsx_rearmed_MAKEFILE = Makefile.libretro - -picodrive_REPO = https://github.com/irixxxx/picodrive -picodrive_MAKEFILE = Makefile.libretro - -pokemini_REPO = https://github.com/libretro/PokeMini -pokemini_MAKEFILE = Makefile.libretro - -snes9x2005_plus_REPO = https://github.com/libretro/snes9x2005 -snes9x2005_plus_FLAGS = USE_BLARGG_APU=1 - -############################### - -include ../../all/cores/makefile \ No newline at end of file diff --git a/workspace/_unmaintained/rgb30/cores/patches/fake-08.patch b/workspace/_unmaintained/rgb30/cores/patches/fake-08.patch deleted file mode 100644 index f857fc686..000000000 --- a/workspace/_unmaintained/rgb30/cores/patches/fake-08.patch +++ /dev/null @@ -1,33 +0,0 @@ -diff --git forkSrcPrefix/platform/libretro/Makefile forkDstPrefix/platform/libretro/Makefile -index be0f1b46bb3ab10be4a9f896f5e8841dd630b35b..4811e985c7ea369e26df9586424d32d8bec9faf7 100644 ---- forkSrcPrefix/platform/libretro/Makefile -+++ forkDstPrefix/platform/libretro/Makefile -@@ -123,7 +123,15 @@ else ifeq ($(platform), miyoomini) - CXXFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7ve -D_NEED_FULL_PATH_ - fpic := -fPIC - SHARED := -shared -Wl,--version-script=link.T -- -+else ifeq ($(platform), rgb30) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ STRIP = $(CROSS_COMPILE)strip -+ CXXFLAGS += -mtune=cortex-a55 -march=armv8-a+crc+simd -+ fpic := -fPIC -+ SHARED := -shared -Wl,--version-script=link.T - else ifeq ($(platform), gcw0) - TARGET := $(TARGET_NAME)_libretro_gcw0.so - CC = /opt/gcw0-toolchain/usr/bin/mipsel-linux-gcc -diff --git forkSrcPrefix/platform/libretro/libretro.cpp forkDstPrefix/platform/libretro/libretro.cpp -index d95ccb6cab52abfe7620ff84dd5cbb450bafe750..24687335ad410096aa48f29e13dcb479171a06fc 100644 ---- forkSrcPrefix/platform/libretro/libretro.cpp -+++ forkDstPrefix/platform/libretro/libretro.cpp -@@ -636,6 +636,7 @@ EXPORT bool retro_load_game(struct retro_game_info const *info) - else { - _vm->QueueCartChange(info->path); - } -+ _vm->UpdateAndDraw(); - - return true; - } diff --git a/workspace/_unmaintained/rgb30/cores/patches/fceumm.patch b/workspace/_unmaintained/rgb30/cores/patches/fceumm.patch deleted file mode 100644 index 0b478b911..000000000 --- a/workspace/_unmaintained/rgb30/cores/patches/fceumm.patch +++ /dev/null @@ -1,22 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index 0cd567cf174249e92a43c4c78be582ba4c36a57c..2597db6a4fe1a1c4a4a9dd5e42de37f50f643b1c 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -463,6 +463,17 @@ else ifeq ($(platform), miyoo) - PLATFORM_DEFINES += -fomit-frame-pointer -ffast-math -mcpu=arm926ej-s - EXTERNAL_ZLIB = 1 - -+# RGB30 -+else ifeq ($(platform), rgb30) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ fpic := -fPIC -+ SHARED := -shared -Wl,--version-script=src/drivers/libretro/link.T -Wl,-no-undefined -+ PLATFORM_DEFINES += -fomit-frame-pointer -ffast-math -mtune=cortex-a55 -march=armv8.2-a -+ EXTERNAL_ZLIB = 1 -+ - # Windows MSVC 2017 all architectures - else ifneq (,$(findstring windows_msvc2017,$(platform))) - CC = cl.exe diff --git a/workspace/_unmaintained/rgb30/cores/patches/gambatte.patch b/workspace/_unmaintained/rgb30/cores/patches/gambatte.patch deleted file mode 100644 index 933bbf8a3..000000000 --- a/workspace/_unmaintained/rgb30/cores/patches/gambatte.patch +++ /dev/null @@ -1,23 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index ffaba21e7a88f90786d818ab550b68acd05738bf..87309c332f50bb39abba853322f7637d3dc2192d 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -393,6 +393,18 @@ else ifeq ($(platform), retrofw) - CFLAGS += -fomit-frame-pointer -ffast-math -march=mips32 -mtune=mips32 -mhard-float - CXXFLAGS += $(CFLAGS) - -+# RGB30 -+else ifeq ($(platform), rgb30) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ fpic := -fPIC -+ SHARED := -shared -Wl,-version-script=$(version_script) -+ PLATFORM_DEFINES := -DDINGUX -+ CFLAGS += -fomit-frame-pointer -ffast-math -mtune=cortex-a55 -march=armv8.2-a -+ CXXFLAGS += $(CFLAGS) -+ - # MIYOO - else ifeq ($(platform), miyoo) - TARGET := $(TARGET_NAME)_libretro.so diff --git a/workspace/_unmaintained/rgb30/cores/patches/gpsp.patch b/workspace/_unmaintained/rgb30/cores/patches/gpsp.patch deleted file mode 100644 index fd66cb5f9..000000000 --- a/workspace/_unmaintained/rgb30/cores/patches/gpsp.patch +++ /dev/null @@ -1,23 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index dc4b60dec7f70a153dbc2eb849cd5acfc90f9d4d..4ef410b9999fdd744a8f9906a54122984cbe7fe1 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -498,6 +498,18 @@ else ifeq ($(platform), miyoo) - HAVE_DYNAREC := 1 - CPU_ARCH := arm - -+else ifeq ($(platform), rgb30) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=link.T -+ fpic := -fPIC -+ CFLAGS += -fomit-frame-pointer -ffast-math -mtune=cortex-a55 -march=armv8.2-a -+ LDFLAGS += -Wl,--no-undefined -+ HAVE_DYNAREC := 1 -+ MMAP_JIT_CACHE = 1 -+ CPU_ARCH := arm64 - - else ifeq ($(platform), miyoomini) - TARGET := $(TARGET_NAME)_plus_libretro.so diff --git a/workspace/_unmaintained/rgb30/cores/patches/mednafen_pce_fast.patch b/workspace/_unmaintained/rgb30/cores/patches/mednafen_pce_fast.patch deleted file mode 100644 index 73f96f798..000000000 --- a/workspace/_unmaintained/rgb30/cores/patches/mednafen_pce_fast.patch +++ /dev/null @@ -1,25 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index 5b54403d915e46cb0df8f428355665fbe26e05b4..f72733d9689aa78795ce8b9d777b0ab9fcc5b65e 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -380,6 +380,20 @@ else ifeq ($(platform), miyoo) - CXXFLAGS += -std=c++11 - CFLAGS += -std=gnu11 - -+# RGB30 -+else ifeq ($(platform), rgb30) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ fpic := -fPIC -+ SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T -+ LDFLAGS += -lrt -+ FLAGS += -mtune=cortex-a55 -march=armv8-a+crc+simd -+ FLAGS += -fomit-frame-pointer -ffast-math -D_GNU_SOURCE -+ CXXFLAGS += -std=c++11 -+ CFLAGS += -std=gnu11 -+ - # Windows MSVC 2017 all architectures - else ifneq (,$(findstring windows_msvc2017,$(platform))) - diff --git a/workspace/_unmaintained/rgb30/cores/patches/mednafen_supafaust.patch b/workspace/_unmaintained/rgb30/cores/patches/mednafen_supafaust.patch deleted file mode 100644 index a25d3b401..000000000 --- a/workspace/_unmaintained/rgb30/cores/patches/mednafen_supafaust.patch +++ /dev/null @@ -1,34 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index f34a01587cda48cc28ebdfd7f00151b06ea88c42..6966d3c4802b200dea33bdbe8e96b2082a36d577 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -88,6 +88,29 @@ else ifeq ($(platform), classic_armv8_a35) - ARCH = arm - CFLAGS += -march=armv8-a - LDFLAGS += -static-libgcc -static-libstdc++ -+ -+# RGB30 -+else ifeq ($(platform), rgb30) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ STRIP = $(CROSS_COMPILE)strip -+ NEED_BPP := 16 -+ fpic := -fPIC -+ SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T -+ CFLAGS += -mtune=cortex-a55 -march=armv8-a+crc+simd -+ CFLAGS += -Ofast \ -+ -flto=4 -fwhole-program -fuse-linker-plugin \ -+ -fdata-sections -ffunction-sections -Wl,--gc-sections \ -+ -fno-stack-protector -fno-ident -fomit-frame-pointer \ -+ -falign-functions=1 -falign-jumps=1 -falign-loops=1 \ -+ -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-unroll-loops \ -+ -fmerge-all-constants -fno-math-errno -+ CXXFLAGS += $(CFLAGS) -+ HAVE_NEON = 1 -+ ARCH = arm -+ - ####################################### - - else ifeq ($(platform), osx) diff --git a/workspace/_unmaintained/rgb30/cores/patches/mednafen_vb.patch b/workspace/_unmaintained/rgb30/cores/patches/mednafen_vb.patch deleted file mode 100644 index 1976c57c9..000000000 --- a/workspace/_unmaintained/rgb30/cores/patches/mednafen_vb.patch +++ /dev/null @@ -1,23 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index 56395207d969b61b52328ea62cea75ff3eb5195d..3765e9be6350f307ea4a24ef6c3201f646cd3815 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -310,6 +310,18 @@ else ifeq ($(platform), emscripten) - TARGET := $(TARGET_NAME)_libretro_$(platform).bc - STATIC_LINKING = 1 - -+# RGB30 -+else ifeq ($(platform), rgb30) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ STRIP = $(CROSS_COMPILE)strip -+ NEED_BPP := 16 -+ fpic := -fPIC -+ SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T -+ FLAGS += -ffast-math -mtune=cortex-a55 -march=armv8-a+crc+simd -flto -+ - # GCW0 - else ifeq ($(platform), gcw0) - TARGET := $(TARGET_NAME)_libretro.so diff --git a/workspace/_unmaintained/rgb30/cores/patches/mgba.patch b/workspace/_unmaintained/rgb30/cores/patches/mgba.patch deleted file mode 100644 index a8b7d617a..000000000 --- a/workspace/_unmaintained/rgb30/cores/patches/mgba.patch +++ /dev/null @@ -1,27 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index 9cab7e4bd79fe03fde4aa7448c1d29c84f7b8eba..ec039524e9d14037640c9a5cb569c61a4bfca38e 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -419,6 +419,22 @@ else ifeq ($(platform), miyoo) - CFLAGS += -fno-common -ftree-vectorize -funswitch-loops - DEFINES += -std=c99 - -+# RGB30 -+else ifeq ($(platform), rgb30) -+ TARGET := $(TARGET_NAME)_libretro.so -+ fpic := -fPIC -+ SHARED := -shared -Wl,-version-script=link.T -+ CC = $(CROSS_COMPILE)gcc -+ AR = $(CROSS_COMPILE)ar -+ PLATFORM_DEFINES += -D_GNU_SOURCE -+ CPUFLAGS := -mtune=cortex-a55 -march=armv8-a+crc+simd -+ CFLAGS += -Ofast -flto -DUSE_RENDER_THREAD -DNO_ASM -DARM_ASM -frename-registers -ftree-vectorize -DNDEBUG -fno-ident -+ CFLAGS += -fpic -fomit-frame-pointer -fno-exceptions -fno-non-call-exceptions -Wno-psabi -Wno-format -+ LDFLAGS += $(CPUFLAGS) -lpthread -Wl,--gc-sections -shared -+ LDFLAGS += -Ofast -fno-ident -+ DEFINES += -std=c99 -D_GNU_SOURCE -DHAVE_LOCALE -+ HAVE_VFS_FD = 0 -+ - # Windows - else - TARGET := $(TARGET_NAME)_libretro.dll diff --git a/workspace/_unmaintained/rgb30/cores/patches/pcsx_rearmed.patch b/workspace/_unmaintained/rgb30/cores/patches/pcsx_rearmed.patch deleted file mode 100644 index 5896962a5..000000000 --- a/workspace/_unmaintained/rgb30/cores/patches/pcsx_rearmed.patch +++ /dev/null @@ -1,26 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index 831964f57dfd82c691e4a6707fbf8dea9a8989dc..32c2f38f419b7a3df5508304299d3b2ba544adf0 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -535,6 +535,21 @@ else ifeq ($(platform), miyoo) - DYNAREC = ari64 - HAVE_NEON = 0 - -+# RGB30 -+else ifeq ($(platform), rgb30) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ CFLAGS += -mtune=cortex-a55 -march=armv8-a+crc+simd -+ CFLAGS += -fomit-frame-pointer -ffast-math -fdata-sections -ffunction-sections -fsingle-precision-constant -flto -fPIC -ftree-vectorize -+ LDFLAGS += -flto -fPIC -+ OPTIMIZE += -Ofast -DNDEBUG=1 -+ HAVE_NEON = 1 -+ BUILTIN_GPU = neon -+ ARCH = arm64 -+ DYNAREC = ari64 -+ - # Emscripten - else ifeq ($(platform), emscripten) - TARGET := $(TARGET_NAME)_libretro_$(platform).bc diff --git a/workspace/_unmaintained/rgb30/cores/patches/picodrive.patch b/workspace/_unmaintained/rgb30/cores/patches/picodrive.patch deleted file mode 100644 index 79a08d35f..000000000 --- a/workspace/_unmaintained/rgb30/cores/patches/picodrive.patch +++ /dev/null @@ -1,22 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index a57a24c73b12bfe25a526c1fbc223b054b3a02fc..1a8a9054bd2577b481168824cf6cde935b3f2394 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -492,6 +492,17 @@ else ifeq ($(platform), miyoo) - HAVE_ARMv6 = 0 - LOW_MEMORY = 1 - -+# RGB30 -+else ifeq ($(platform), rgb30) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -nostdlib -+ fpic := -fPIC -+ LIBM := -+ CFLAGS += -fomit-frame-pointer -ffast-math -mtune=cortex-a55 -march=armv8.2-a -D__GCW0__ -+ CFLAGS += -DFAMEC_NO_GOTOS -+ - # Windows MSVC 2017 all architectures - else ifneq (,$(findstring windows_msvc2017,$(platform))) - NO_GCC := 1 diff --git a/workspace/_unmaintained/rgb30/cores/patches/pokemini.patch b/workspace/_unmaintained/rgb30/cores/patches/pokemini.patch deleted file mode 100644 index fea88697c..000000000 --- a/workspace/_unmaintained/rgb30/cores/patches/pokemini.patch +++ /dev/null @@ -1,23 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index af8cc75cf1a998791a071e8cff915fb8c97ffcc9..e2a4e8cdd951f71f9ebfdb2cf53a21d190939ffd 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -482,6 +482,18 @@ else ifeq ($(platform), miyoo) - CFLAGS += -ffast-math -fomit-frame-pointer -march=armv5te -mtune=arm926ej-s - CFLAGS += -DDINGUX -DRS90 - -+# RGB30 -+else ifeq ($(platform), rgb30) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=libretro/link.T -+ fpic := -fPIC -+ CFLAGS += $(PTHREAD_FLAGS) -+ CFLAGS += -fomit-frame-pointer -ffast-math -mtune=cortex-a55 -march=armv8.2-a -+ CFLAGS += -DDINGUX -+ - # GCW0 - else ifeq ($(platform), gcw0) - TARGET := $(TARGET_NAME)_libretro.so diff --git a/workspace/_unmaintained/rgb30/cores/patches/race.patch b/workspace/_unmaintained/rgb30/cores/patches/race.patch deleted file mode 100644 index 56a003133..000000000 --- a/workspace/_unmaintained/rgb30/cores/patches/race.patch +++ /dev/null @@ -1,23 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index 792a6d82915c32edd3df6ceec541499f6ca25ac5..dc02b361d7db47e011b6d3addf89cfb31503575a 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -373,6 +373,18 @@ else ifeq ($(platform), miyoo) - CFLAGS += -fomit-frame-pointer -ffast-math -march=armv5te -mtune=arm926ej-s - CXXFLAGS += $(CFLAGS) - -+# RGB30 -+else ifeq ($(platform), rgb30) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ fpic := -fPIC -+ SHARED := -shared -Wl,-version-script=$(LIBRETRO_DIR)/link.T -+ PLATFORM_DEFINES := -DCC_RESAMPLER -DCC_RESAMPLER_NO_HIGHPASS -+ CFLAGS += -fomit-frame-pointer -ffast-math -mtune=cortex-a55 -march=armv8.2-a -+ CXXFLAGS += $(CFLAGS) -+ - # Windows MSVC 2010 x64 - else ifeq ($(platform), windows_msvc2010_x64) - CC = cl.exe diff --git a/workspace/_unmaintained/rgb30/cores/patches/snes9x2005_plus.patch b/workspace/_unmaintained/rgb30/cores/patches/snes9x2005_plus.patch deleted file mode 100644 index 75b668817..000000000 --- a/workspace/_unmaintained/rgb30/cores/patches/snes9x2005_plus.patch +++ /dev/null @@ -1,23 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index 07d5368a8e78a020813732239ec369d83e931ede..a1f7fefd144c9d0ead913fad350e660c73348991 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -288,6 +288,18 @@ else ifeq ($(platform), miyoo) - FLAGS += -fomit-frame-pointer -ffast-math -march=armv5te -mtune=arm926ej-s - FLAGS += -DFAST_ALIGNED_LSB_WORD_ACCESS -fno-unroll-loops - -+# RGB30 -+else ifeq ($(platform), rgb30) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ fpic := -fPIC -nostdlib -+ SHARED := -shared -Wl,--version-script=link.T -+ LIBM := -+ FLAGS += -fomit-frame-pointer -ffast-math -mtune=cortex-a55 -march=armv8.2-a -+ FLAGS += -DFAST_ALIGNED_LSB_WORD_ACCESS -fno-unroll-loops -+ - # (armv7 a7, hard point, neon based) ### - # NESC, SNESC, C64 mini - else ifeq ($(platform), classic_armv7_a7) diff --git a/workspace/_unmaintained/rgb30/keymon/credits.txt b/workspace/_unmaintained/rgb30/keymon/credits.txt deleted file mode 100644 index e885e5dd1..000000000 --- a/workspace/_unmaintained/rgb30/keymon/credits.txt +++ /dev/null @@ -1,3 +0,0 @@ -based on eggs custom keymon for Trimui: - https://www.dropbox.com/sh/5e9xwvp672vt8cr/AABUIdw1vLYp9h0waoCUqHPOa/source?dl=0&subfolder_nav_tracking=1 -modified to use libmsettings \ No newline at end of file diff --git a/workspace/_unmaintained/rgb30/keymon/keymon.c b/workspace/_unmaintained/rgb30/keymon/keymon.c deleted file mode 100644 index d1e47d1fd..000000000 --- a/workspace/_unmaintained/rgb30/keymon/keymon.c +++ /dev/null @@ -1,182 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -// for ev.value -#define RELEASED 0 -#define PRESSED 1 -#define REPEAT 2 - -// L3 or R3 -#define CODE_MENU 317 // 11 in SDL for some reason... -#define CODE_MENU_ALT 318 // 12 in SDL... - -#define CODE_PLUS 114 -#define CODE_MINUS 115 - -#define VOLUME_MIN 0 -#define VOLUME_MAX 20 -#define BRIGHTNESS_MIN 0 -#define BRIGHTNESS_MAX 10 - -#define INPUT_COUNT 6 -static int inputs[INPUT_COUNT]; -static struct input_event ev; - -static pthread_t ports_pt; -#define JACK_STATE_PATH "/sys/bus/platform/devices/singleadc-joypad/hp" -#define HDMI_STATE_PATH "/sys/class/extcon/hdmi/cable.0/state" - -int getInt(char* path) { - int i = 0; - FILE *file = fopen(path, "r"); - if (file!=NULL) { - fscanf(file, "%i", &i); - fclose(file); - } - return i; -} - -static void* watchPorts(void *arg) { - int has_headphones,had_headphones; - int has_hdmi,had_hdmi; - - has_headphones = had_headphones = getInt(JACK_STATE_PATH); - has_hdmi = had_hdmi = getInt(HDMI_STATE_PATH); - SetJack(has_headphones); - SetHDMI(has_hdmi); - - while(1) { - sleep(1); - - has_headphones = getInt(JACK_STATE_PATH); - if (had_headphones!=has_headphones) { - had_headphones = has_headphones; - SetJack(has_headphones); - } - - has_hdmi = getInt(HDMI_STATE_PATH); - if (had_hdmi!=has_hdmi) { - had_hdmi = has_hdmi; - SetHDMI(has_hdmi); - } - } - - return 0; -} - - -int main (int argc, char *argv[]) { - printf("keymon\n"); fflush(stdout); - InitSettings(); - pthread_create(&ports_pt, NULL, &watchPorts, NULL); - - char path[32]; - for (int i=0; i1000) ignore = 1; // ignore input that arrived during sleep - - for (int i=0; i REPEAT )) continue; - // printf("value: %i code: %i\n", val, ev.code); fflush(stdout); - switch (ev.code) { - case CODE_MENU: - case CODE_MENU_ALT: - menu_pressed = val; - break; - case CODE_PLUS: - up_pressed = up_just_pressed = val; - if (val) up_repeat_at = now + 300; - break; - case CODE_MINUS: - down_pressed = down_just_pressed = val; - if (val) down_repeat_at = now + 300; - break; - default: - break; - } - } - } - - if (ignore) { - menu_pressed = 0; - up_pressed = up_just_pressed = 0; - down_pressed = down_just_pressed = 0; - up_repeat_at = 0; - down_repeat_at = 0; - } - - if (up_just_pressed || (up_pressed && now>=up_repeat_at)) { - if (menu_pressed) { - val = GetBrightness(); - if (val=down_repeat_at)) { - if (menu_pressed) { - val = GetBrightness(); - if (val>BRIGHTNESS_MIN) SetBrightness(--val); - } - else { - val = GetVolume(); - if (val>VOLUME_MIN) SetVolume(--val); - } - - if (down_just_pressed) down_just_pressed = 0; - else down_repeat_at += 100; - } - - then = now; - ignore = 0; - - usleep(16666); // 60fps - } -} diff --git a/workspace/_unmaintained/rgb30/keymon/makefile b/workspace/_unmaintained/rgb30/keymon/makefile deleted file mode 100755 index e23c35820..000000000 --- a/workspace/_unmaintained/rgb30/keymon/makefile +++ /dev/null @@ -1,14 +0,0 @@ -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif - -TARGET = keymon -PRODUCT = $(TARGET).elf - -CC = $(CROSS_COMPILE)gcc -I../../all/common/ -I../platform/ -FLAGS = -Os -lmsettings -lpthread -lrt -ldl -Wl,--gc-sections -s - -all: - $(CC) $(TARGET).c -o $(PRODUCT) $(FLAGS) -clean: - rm -rf $(PRODUCT) \ No newline at end of file diff --git a/workspace/_unmaintained/rgb30/libmsettings/makefile b/workspace/_unmaintained/rgb30/libmsettings/makefile deleted file mode 100644 index b1418a21d..000000000 --- a/workspace/_unmaintained/rgb30/libmsettings/makefile +++ /dev/null @@ -1,32 +0,0 @@ -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif -ifeq (,$(PREFIX)) -$(error missing PREFIX for this toolchain) -endif - -TARGET=msettings - -.PHONY: build -.PHONY: clean - -CC = $(CROSS_COMPILE)gcc - -SYSROOT := $(shell $(CC) --print-sysroot) - -INCLUDEDIR = $(SYSROOT)/usr/include -CFLAGS = -I$(INCLUDEDIR) -LDFLAGS = -ldl -lrt -s - -OPTM=-Ofast - -build: - $(CC) -c -Werror -fpic "$(TARGET).c" -Wl,--no-as-needed $(LDFLAGS) - $(CC) -shared -o "lib$(TARGET).so" "$(TARGET).o" $(LDFLAGS) - cp "$(TARGET).h" "$(PREFIX)/include" - cp "lib$(TARGET).so" "$(PREFIX)/lib" -clean: - rm -f *.o - rm -f "lib$(TARGET).so" - rm -f $(PREFIX)/include/$(TARGET).h - rm -f $(PREFIX)/lib/lib$(TARGET).so \ No newline at end of file diff --git a/workspace/_unmaintained/rgb30/libmsettings/msettings.c b/workspace/_unmaintained/rgb30/libmsettings/msettings.c deleted file mode 100644 index ab87f4b14..000000000 --- a/workspace/_unmaintained/rgb30/libmsettings/msettings.c +++ /dev/null @@ -1,203 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "msettings.h" - -/////////////////////////////////////// - -#define SETTINGS_VERSION 2 -typedef struct Settings { - int version; // future proofing - int brightness; - int headphones; - int speaker; - int unused[2]; // for future use - // NOTE: doesn't really need to be persisted but still needs to be shared - int jack; - int hdmi; -} Settings; -static Settings DefaultSettings = { - .version = SETTINGS_VERSION, - .brightness = 2, - .headphones = 4, - .speaker = 8, - .jack = 0, - .hdmi = 0, -}; -static Settings* settings; - -#define SHM_KEY "/SharedSettings" -static char SettingsPath[256]; -static int shm_fd = -1; -static int is_host = 0; -static int shm_size = sizeof(Settings); - -#define BACKLIGHT_PATH "/sys/class/backlight/backlight/bl_power" -#define BRIGHTNESS_PATH "/sys/class/backlight/backlight/brightness" -#define JACK_STATE_PATH "/sys/bus/platform/devices/singleadc-joypad/hp" -#define HDMI_STATE_PATH "/sys/class/extcon/hdmi/cable.0/state" - -int getInt(char* path) { - int i = 0; - FILE *file = fopen(path, "r"); - if (file!=NULL) { - fscanf(file, "%i", &i); - fclose(file); - } - return i; -} - - -void InitSettings(void) { - sprintf(SettingsPath, "%s/msettings.bin", getenv("USERDATA_PATH")); - - shm_fd = shm_open(SHM_KEY, O_RDWR | O_CREAT | O_EXCL, 0644); // see if it exists - if (shm_fd==-1 && errno==EEXIST) { // already exists - puts("Settings client"); - shm_fd = shm_open(SHM_KEY, O_RDWR, 0644); - settings = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); - } - else { // host - puts("Settings host"); // should always be keymon - is_host = 1; - // we created it so set initial size and populate - ftruncate(shm_fd, shm_size); - settings = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); - - int fd = open(SettingsPath, O_RDONLY); - if (fd>=0) { - read(fd, settings, shm_size); - // TODO: use settings->version for future proofing? - close(fd); - } - else { - // load defaults - memcpy(settings, &DefaultSettings, shm_size); - } - - // these shouldn't be persisted - // settings->jack = 0; - // settings->hdmi = 0; - } - - int jack = getInt(JACK_STATE_PATH); - int hdmi = getInt(HDMI_STATE_PATH); - printf("brightness: %i (hdmi: %i)\nspeaker: %i (jack: %i)\n", settings->brightness, hdmi, settings->speaker, jack); fflush(stdout); - - // both of these set volume - SetJack(jack); - SetHDMI(hdmi); - - SetBrightness(GetBrightness()); - // system("echo $(< " BRIGHTNESS_PATH ")"); -} -void QuitSettings(void) { - munmap(settings, shm_size); - if (is_host) shm_unlink(SHM_KEY); -} -static inline void SaveSettings(void) { - int fd = open(SettingsPath, O_CREAT|O_WRONLY, 0644); - if (fd>=0) { - write(fd, settings, shm_size); - close(fd); - sync(); - } -} - -int GetBrightness(void) { // 0-10 - return settings->brightness; -} -void SetBrightness(int value) { - if (settings->hdmi) return; - - int raw; - switch (value) { - // TODO: redo, range is 0-255 - case 0: raw=4; break; // 0 - case 1: raw=6; break; // 2 - case 2: raw=10; break; // 4 - case 3: raw=16; break; // 6 - case 4: raw=32; break; // 16 - case 5: raw=48; break; // 16 - case 6: raw=64; break; // 16 - case 7: raw=96; break; // 32 - case 8: raw=128; break; // 32 - case 9: raw=192; break; // 64 - case 10: raw=255; break; // 64 - } - SetRawBrightness(raw); - settings->brightness = value; - SaveSettings(); -} - -int GetVolume(void) { // 0-20 - return settings->jack ? settings->headphones : settings->speaker; -} -void SetVolume(int value) { - if (settings->hdmi) return; - - if (settings->jack) settings->headphones = value; - else settings->speaker = value; - - int raw = value * 5; - SetRawVolume(raw); - SaveSettings(); -} - -void SetRawBrightness(int val) { // 0 - 255 - if (settings->hdmi) return; - - // printf("SetRawBrightness(%i)\n", val); fflush(stdout); - int fd = open(BRIGHTNESS_PATH, O_WRONLY); - if (fd>=0) { - dprintf(fd,"%d",val); - close(fd); - } -} -void SetRawVolume(int val) { // 0 - 100 - // printf("SetRawVolume(%i)\n", val); fflush(stdout); - char cmd[256]; - sprintf(cmd, "amixer sset -M 'Master' %i%% &> /dev/null", val); - // puts(cmd); fflush(stdout); - system(cmd); -} - -// monitored and set by thread in keymon -int GetJack(void) { - return settings->jack; -} -void SetJack(int value) { - // printf("SetJack(%i)\n", value); fflush(stdout); - - char cmd[256]; - sprintf(cmd, "amixer cset name='Playback Path' '%s' &> /dev/null", value?"HP":"SPK"); - system(cmd); - - settings->jack = value; - SetVolume(GetVolume()); -} - -int GetHDMI(void) { - // printf("GetHDMI() %i\n", settings->hdmi); fflush(stdout); - return settings->hdmi; -} -void SetHDMI(int value) { - // printf("SetHDMI(%i)\n", value); fflush(stdout); - - // if (settings->hdmi!=value) system("/usr/lib/autostart/common/055-hdmi-check"); - - settings->hdmi = value; - if (value) SetRawVolume(100); // max - else SetVolume(GetVolume()); // restore -} - -int GetMute(void) { return 0; } -void SetMute(int value) { } \ No newline at end of file diff --git a/workspace/_unmaintained/rgb30/libmsettings/msettings.h b/workspace/_unmaintained/rgb30/libmsettings/msettings.h deleted file mode 100644 index 47e5fb003..000000000 --- a/workspace/_unmaintained/rgb30/libmsettings/msettings.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef __msettings_h__ -#define __msettings_h__ - -void InitSettings(void); -void QuitSettings(void); - -int GetBrightness(void); -int GetVolume(void); - -void SetRawBrightness(int value); // 0-1024 -void SetRawVolume(int value); // 0-40 - -void SetBrightness(int value); // 0-10 -void SetVolume(int value); // 0-20 - -int GetJack(void); -void SetJack(int value); // 0-1 - -int GetHDMI(void); -void SetHDMI(int value); // 0-1 - -int GetMute(void); -void SetMute(int value); // 0-1 - -#endif // __msettings_h__ diff --git a/workspace/_unmaintained/rgb30/makefile b/workspace/_unmaintained/rgb30/makefile deleted file mode 100644 index 219529be2..000000000 --- a/workspace/_unmaintained/rgb30/makefile +++ /dev/null @@ -1,38 +0,0 @@ -########################################################### - -ifeq (,$(PLATFORM)) -PLATFORM=$(UNION_PLATFORM) -endif - -ifeq (,$(PLATFORM)) -$(error please specify PLATFORM, eg. PLATFORM=rgb30 make) -endif - -########################################################### - -REQUIRES_COMMANDER=other/DinguxCommander -REQUIRES_SDLCOMPAT=other/sdl12-compat - -all: readmes - cd show && make - -early: $(REQUIRES_COMMANDER) $(REQUIRES_SDLCOMPAT)/build - cd $(REQUIRES_COMMANDER) && make -j - cd $(REQUIRES_SDLCOMPAT) && cmake --build build - -clean: - cd $(REQUIRES_COMMANDER) && make clean - cd $(REQUIRES_SDLCOMPAT) && rm -rf build - -########################################################### - -$(REQUIRES_COMMANDER): - git clone --depth 1 --branch minui-rgb30 https://github.com/shauninman/DinguxCommander.git $(REQUIRES_COMMANDER) - -$(REQUIRES_SDLCOMPAT): - git clone --depth 1 --branch minui-rgb30 https://github.com/shauninman/sdl12-compat.git $(REQUIRES_SDLCOMPAT) - -$(REQUIRES_SDLCOMPAT)/build: $(REQUIRES_SDLCOMPAT) - cd $(REQUIRES_SDLCOMPAT) && cmake --toolchain ./toolchain.cmake -Bbuild -DCMAKE_BUILD_TYPE=Release . - -include ../all/readmes/makefile diff --git a/workspace/_unmaintained/rgb30/other/.keep b/workspace/_unmaintained/rgb30/other/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/workspace/_unmaintained/rgb30/platform/makefile.copy b/workspace/_unmaintained/rgb30/platform/makefile.copy deleted file mode 100644 index 28e116582..000000000 --- a/workspace/_unmaintained/rgb30/platform/makefile.copy +++ /dev/null @@ -1,7 +0,0 @@ -$(PLATFORM): - # $@ - cp ./workspace/$@/show/show.elf ./build/SYSTEM/$@/bin - # extras - cp ./workspace/$@/other/DinguxCommander/output/DinguxCommander ./build/EXTRAS/Tools/$@/Files.pak/ - cp -r ./workspace/$@/other/DinguxCommander/res ./build/EXTRAS/Tools/$@/Files.pak/ - cp ./workspace/$@/other/sdl12-compat/build/libSDL-1.2.so.1.2.69 ./build/SYSTEM/$@/lib/libSDL-1.2.so.0 \ No newline at end of file diff --git a/workspace/_unmaintained/rgb30/platform/makefile.env b/workspace/_unmaintained/rgb30/platform/makefile.env deleted file mode 100644 index 83adf3a73..000000000 --- a/workspace/_unmaintained/rgb30/platform/makefile.env +++ /dev/null @@ -1,4 +0,0 @@ -# rgb30 -ARCH = -mtune=cortex-a55 -march=armv8.2-a -O3 -LIBS = -flto -lrga -SDL = SDL2 diff --git a/workspace/_unmaintained/rgb30/platform/platform.c b/workspace/_unmaintained/rgb30/platform/platform.c deleted file mode 100644 index a09aabdea..000000000 --- a/workspace/_unmaintained/rgb30/platform/platform.c +++ /dev/null @@ -1,741 +0,0 @@ -// rgb30 -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include "defines.h" -#include "platform.h" -#include "api.h" -#include "utils.h" - -#include "scaler.h" - -/////////////////////////////// - -#define RAW_UP 544 -#define RAW_DOWN 545 -#define RAW_LEFT 546 -#define RAW_RIGHT 547 -#define RAW_A 305 -#define RAW_B 304 -#define RAW_X 307 -#define RAW_Y 308 -#define RAW_START 315 -#define RAW_SELECT 314 -#define RAW_MENU 139 -#define RAW_L1 310 -#define RAW_L2 312 -#define RAW_L3 317 -#define RAW_R1 311 -#define RAW_R2 313 -#define RAW_R3 318 -#define RAW_PLUS 115 -#define RAW_MINUS 114 -#define RAW_POWER 116 -#define RAW_HATY 17 -#define RAW_HATX 16 -#define RAW_LSY 1 -#define RAW_LSX 0 -#define RAW_RSY 3 -#define RAW_RSX 4 - -#define RAW_MENU1 RAW_L3 -#define RAW_MENU2 RAW_R3 - -#define INPUT_COUNT 4 -static int inputs[INPUT_COUNT]; - -void PLAT_initInput(void) { - inputs[0] = open("/dev/input/event0", O_RDONLY | O_NONBLOCK | O_CLOEXEC); - inputs[1] = open("/dev/input/event1", O_RDONLY | O_NONBLOCK | O_CLOEXEC); - inputs[2] = open("/dev/input/event2", O_RDONLY | O_NONBLOCK | O_CLOEXEC); - inputs[3] = open("/dev/input/event3", O_RDONLY | O_NONBLOCK | O_CLOEXEC); -} -void PLAT_quitInput(void) { - for (int i=0; i which has BTN_ constants that conflict with platform.h -struct input_event { - struct timeval time; - __u16 type; - __u16 code; - __s32 value; -}; -#define EV_KEY 0x01 -#define EV_ABS 0x03 - -void PLAT_pollInput(void) { - // reset transient state - pad.just_pressed = BTN_NONE; - pad.just_released = BTN_NONE; - pad.just_repeated = BTN_NONE; - - uint32_t tick = SDL_GetTicks(); - for (int i=0; i=pad.repeat_at[i])) { - pad.just_repeated |= btn; // set - pad.repeat_at[i] += PAD_REPEAT_INTERVAL; - } - } - - // the actual poll - int input; - static struct input_event event; - for (int i=0; i1) continue; // ignore repeats - - pressed = value; - LOG_info("key event: %i (%i)\n", code,pressed); - if (code==RAW_UP) { btn = BTN_DPAD_UP; id = BTN_ID_DPAD_UP; } - else if (code==RAW_DOWN) { btn = BTN_DPAD_DOWN; id = BTN_ID_DPAD_DOWN; } - else if (code==RAW_LEFT) { btn = BTN_DPAD_LEFT; id = BTN_ID_DPAD_LEFT; } - else if (code==RAW_RIGHT) { btn = BTN_DPAD_RIGHT; id = BTN_ID_DPAD_RIGHT; } - else if (code==RAW_A) { btn = BTN_A; id = BTN_ID_A; } - else if (code==RAW_B) { btn = BTN_B; id = BTN_ID_B; } - else if (code==RAW_X) { btn = BTN_X; id = BTN_ID_X; } - else if (code==RAW_Y) { btn = BTN_Y; id = BTN_ID_Y; } - else if (code==RAW_START) { btn = BTN_START; id = BTN_ID_START; } - else if (code==RAW_SELECT) { btn = BTN_SELECT; id = BTN_ID_SELECT; } - else if (code==RAW_MENU) { btn = BTN_MENU; id = BTN_ID_MENU; } - else if (code==RAW_MENU1) { btn = BTN_MENU; id = BTN_ID_MENU; } - else if (code==RAW_MENU2) { btn = BTN_MENU; id = BTN_ID_MENU; } - else if (code==RAW_L1) { btn = BTN_L1; id = BTN_ID_L1; } - else if (code==RAW_L2) { btn = BTN_L2; id = BTN_ID_L2; } - else if (code==RAW_L3) { btn = BTN_L3; id = BTN_ID_L3; } - else if (code==RAW_R1) { btn = BTN_R1; id = BTN_ID_R1; } - else if (code==RAW_R2) { btn = BTN_R2; id = BTN_ID_R2; } - else if (code==RAW_R3) { btn = BTN_R3; id = BTN_ID_R3; } - else if (code==RAW_PLUS) { btn = BTN_PLUS; id = BTN_ID_PLUS; } - else if (code==RAW_MINUS) { btn = BTN_MINUS; id = BTN_ID_MINUS; } - else if (code==RAW_POWER) { btn = BTN_POWER; id = BTN_ID_POWER; } - } - else if (type==EV_ABS) { - LOG_info("abs event: %i (%i==%i)\n",code,value,(value * 32767) / 1800); - - if (code==RAW_LSX) { pad.laxis.x = (value * 32767) / 1800; PAD_setAnalog(BTN_ID_ANALOG_LEFT, BTN_ID_ANALOG_RIGHT, pad.laxis.x, tick+PAD_REPEAT_DELAY); } - else if (code==RAW_LSY) { pad.laxis.y = (value * 32767) / 1800; PAD_setAnalog(BTN_ID_ANALOG_UP, BTN_ID_ANALOG_DOWN, pad.laxis.y, tick+PAD_REPEAT_DELAY); } - // TODO: these seem to be switched on the rgb30 according to the padtest rom - else if (code==RAW_RSX) pad.raxis.y = (value * 32767) / 1800; - else if (code==RAW_RSY) pad.raxis.x = (value * 32767) / 1800; - - btn = BTN_NONE; // already handled, force continue - } - - if (btn==BTN_NONE) continue; - - if (!pressed) { - pad.is_pressed &= ~btn; // unset - pad.just_repeated &= ~btn; // unset - pad.just_released |= btn; // set - } - else if ((pad.is_pressed & btn)==BTN_NONE) { - pad.just_pressed |= btn; // set - pad.just_repeated |= btn; // set - pad.is_pressed |= btn; // set - pad.repeat_at[id] = tick + PAD_REPEAT_DELAY; - } - } - } -} - -int PLAT_shouldWake(void) { - int input; - static struct input_event event; - for (int i=0; i /dev/fb0 2>/dev/null"); - SDL_Quit(); -} - -void PLAT_clearVideo(SDL_Surface* screen) { - SDL_FillRect(screen, NULL, 0); // TODO: revisit -} -void PLAT_clearAll(void) { - PLAT_clearVideo(vid.screen); // TODO: revist - SDL_RenderClear(vid.renderer); -} - -void PLAT_setVsync(int vsync) { - // buh -} - -static int hard_scale = 4; // TODO: base src size, eg. 160x144 can be 4 - -static void resizeVideo(int w, int h, int p) { - if (w==vid.width && h==vid.height && p==vid.pitch) return; - - // TODO: minarch disables crisp (and nn upscale before linear downscale) when native - - if (w>=device_width && h>=device_height) hard_scale = 1; - else if (h>=160) hard_scale = 2; // limits gba and up to 2x (seems sufficient) - else hard_scale = 4; - - LOG_info("resizeVideo(%i,%i,%i) hard_scale: %i crisp: %i\n",w,h,p, hard_scale,vid.sharpness==SHARPNESS_CRISP); - - SDL_FreeSurface(vid.buffer); - SDL_DestroyTexture(vid.texture); - if (vid.target) SDL_DestroyTexture(vid.target); - - SDL_SetHintWithPriority(SDL_HINT_RENDER_SCALE_QUALITY, vid.sharpness==SHARPNESS_SOFT?"1":"0", SDL_HINT_OVERRIDE); - vid.texture = SDL_CreateTexture(vid.renderer,SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, w,h); - - if (vid.sharpness==SHARPNESS_CRISP) { - SDL_SetHintWithPriority(SDL_HINT_RENDER_SCALE_QUALITY, "1", SDL_HINT_OVERRIDE); - vid.target = SDL_CreateTexture(vid.renderer,SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_TARGET, w * hard_scale,h * hard_scale); - } - else { - vid.target = NULL; - } - - vid.buffer = SDL_CreateRGBSurfaceFrom(NULL, w,h, FIXED_DEPTH, p, RGBA_MASK_565); - - vid.width = w; - vid.height = h; - vid.pitch = p; -} - -SDL_Surface* PLAT_resizeVideo(int w, int h, int p) { - resizeVideo(w,h,p); - return vid.screen; -} - -void PLAT_setVideoScaleClip(int x, int y, int width, int height) { - // buh -} -void PLAT_setNearestNeighbor(int enabled) { - // buh -} -void PLAT_setSharpness(int sharpness) { - if (vid.sharpness==sharpness) return; - int p = vid.pitch; - vid.pitch = 0; - vid.sharpness = sharpness; - resizeVideo(vid.width,vid.height,p); -} - -static struct FX_Context { - int scale; - int type; - int color; - int next_scale; - int next_type; - int next_color; - int live_type; -} effect = { - .scale = 1, - .next_scale = 1, - .type = EFFECT_NONE, - .next_type = EFFECT_NONE, - .live_type = EFFECT_NONE, - .color = 0, - .next_color = 0, -}; -static void rgb565_to_rgb888(uint32_t rgb565, uint8_t *r, uint8_t *g, uint8_t *b) { - // Extract the red component (5 bits) - uint8_t red = (rgb565 >> 11) & 0x1F; - // Extract the green component (6 bits) - uint8_t green = (rgb565 >> 5) & 0x3F; - // Extract the blue component (5 bits) - uint8_t blue = rgb565 & 0x1F; - - // Scale the values to 8-bit range - *r = (red << 3) | (red >> 2); - *g = (green << 2) | (green >> 4); - *b = (blue << 3) | (blue >> 2); -} -static void updateEffect(void) { - if (effect.next_scale==effect.scale && effect.next_type==effect.type && effect.next_color==effect.color) return; // unchanged - - int live_scale = effect.scale; - int live_color = effect.color; - effect.scale = effect.next_scale; - effect.type = effect.next_type; - effect.color = effect.next_color; - - if (effect.type==EFFECT_NONE) return; // disabled - if (effect.type==effect.live_type && effect.scale==live_scale && effect.color==live_color) return; // already loaded - - char* effect_path; - int opacity = 128; // 1 - 1/2 = 50% - if (effect.type==EFFECT_LINE) { - if (effect.scale<3) { - effect_path = RES_PATH "/line-2.png"; - } - else if (effect.scale<4) { - effect_path = RES_PATH "/line-3.png"; - } - else if (effect.scale<5) { - effect_path = RES_PATH "/line-4.png"; - } - else if (effect.scale<6) { - effect_path = RES_PATH "/line-5.png"; - } - else if (effect.scale<8) { - effect_path = RES_PATH "/line-6.png"; - } - else { - effect_path = RES_PATH "/line-8.png"; - } - } - else if (effect.type==EFFECT_GRID) { - if (effect.scale<3) { - effect_path = RES_PATH "/grid-2.png"; - opacity = 64; // 1 - 3/4 = 25% - } - else if (effect.scale<4) { - effect_path = RES_PATH "/grid-3.png"; - opacity = 112; // 1 - 5/9 = ~44% - } - else if (effect.scale<5) { - effect_path = RES_PATH "/grid-4.png"; - opacity = 144; // 1 - 7/16 = ~56% - } - else if (effect.scale<6) { - effect_path = RES_PATH "/grid-5.png"; - opacity = 160; // 1 - 9/25 = ~64% - } - else if (effect.scale<8) { - effect_path = RES_PATH "/grid-6.png"; - opacity = 112; // 1 - 5/9 = ~44% - } - else if (effect.scale<11) { - effect_path = RES_PATH "/grid-8.png"; - opacity = 144; // 1 - 7/16 = ~56% - } - else { - effect_path = RES_PATH "/grid-11.png"; - opacity = 136; // 1 - 57/121 = ~52% - } - } - - // LOG_info("effect: %s opacity: %i\n", effect_path, opacity); - SDL_Surface* tmp = IMG_Load(effect_path); - if (tmp) { - if (effect.type==EFFECT_GRID) { - if (effect.color) { - // LOG_info("dmg color grid...\n"); - - uint8_t r,g,b; - rgb565_to_rgb888(effect.color,&r,&g,&b); - // LOG_info("rgb %i,%i,%i\n",r,g,b); - - uint32_t* pixels = (uint32_t*)tmp->pixels; - int width = tmp->w; - int height = tmp->h; - for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) { - uint32_t pixel = pixels[y * width + x]; - uint8_t _,a; - SDL_GetRGBA(pixel, tmp->format, &_, &_, &_, &a); - if (a) pixels[y * width + x] = SDL_MapRGBA(tmp->format, r,g,b, a); - } - } - } - } - - if (vid.effect) SDL_DestroyTexture(vid.effect); - vid.effect = SDL_CreateTextureFromSurface(vid.renderer, tmp); - SDL_SetTextureAlphaMod(vid.effect, opacity); - SDL_FreeSurface(tmp); - effect.live_type = effect.type; - } - } -void PLAT_setEffect(int next_type) { - effect.next_type = next_type; -} -void PLAT_setEffectColor(int next_color) { - effect.next_color = next_color; -} -void PLAT_vsync(int remaining) { - if (remaining>0) SDL_Delay(remaining); -} - -scaler_t PLAT_getScaler(GFX_Renderer* renderer) { - // LOG_info("getScaler for scale: %i\n", renderer->scale); - effect.next_scale = renderer->scale; - return scale1x1_c16; -} - -void PLAT_blitRenderer(GFX_Renderer* renderer) { - vid.blit = renderer; - SDL_RenderClear(vid.renderer); - resizeVideo(vid.blit->true_w,vid.blit->true_h,vid.blit->src_p); -} - -void PLAT_flip(SDL_Surface* IGNORED, int ignored) { - if (!vid.blit) { - resizeVideo(device_width,device_height,FIXED_PITCH); // !!!??? - SDL_UpdateTexture(vid.texture,NULL,vid.screen->pixels,vid.screen->pitch); - SDL_RenderCopy(vid.renderer, vid.texture, NULL,NULL); - SDL_RenderPresent(vid.renderer); - return; - } - - // uint32_t then = SDL_GetTicks(); - SDL_UpdateTexture(vid.texture,NULL,vid.blit->src,vid.blit->src_p); - // LOG_info("blit blocked for %ims (%i,%i)\n", SDL_GetTicks()-then,vid.buffer->w,vid.buffer->h); - - SDL_Texture* target = vid.texture; - int x = vid.blit->src_x; - int y = vid.blit->src_y; - int w = vid.blit->src_w; - int h = vid.blit->src_h; - if (vid.sharpness==SHARPNESS_CRISP) { - SDL_SetRenderTarget(vid.renderer,vid.target); - SDL_RenderCopy(vid.renderer, vid.texture, NULL,NULL); - SDL_SetRenderTarget(vid.renderer,NULL); - x *= hard_scale; - y *= hard_scale; - w *= hard_scale; - h *= hard_scale; - target = vid.target; - } - - SDL_Rect* src_rect = &(SDL_Rect){x,y,w,h}; - SDL_Rect* dst_rect = &(SDL_Rect){0,0,device_width,device_height}; - if (vid.blit->aspect==0) { // native or cropped - // LOG_info("src_rect %i,%i %ix%i\n",src_rect->x,src_rect->y,src_rect->w,src_rect->h); - - int w = vid.blit->src_w * vid.blit->scale; - int h = vid.blit->src_h * vid.blit->scale; - int x = (device_width - w) / 2; - int y = (device_height - h) / 2; - dst_rect->x = x; - dst_rect->y = y; - dst_rect->w = w; - dst_rect->h = h; - - // LOG_info("dst_rect %i,%i %ix%i\n",dst_rect->x,dst_rect->y,dst_rect->w,dst_rect->h); - } - else if (vid.blit->aspect>0) { // aspect - int h = device_height; - int w = h * vid.blit->aspect; - if (w>device_width) { - double ratio = 1 / vid.blit->aspect; - w = device_width; - h = w * ratio; - } - int x = (device_width - w) / 2; - int y = (device_height - h) / 2; - // dst_rect = &(SDL_Rect){x,y,w,h}; - dst_rect->x = x; - dst_rect->y = y; - dst_rect->w = w; - dst_rect->h = h; - } - - SDL_RenderCopy(vid.renderer, target, src_rect, dst_rect); - - updateEffect(); - if (vid.blit && effect.type!=EFFECT_NONE && vid.effect) { - SDL_RenderCopy(vid.renderer, vid.effect, &(SDL_Rect){0,0,dst_rect->w,dst_rect->h},dst_rect); - } - - // uint32_t then = SDL_GetTicks(); - SDL_RenderPresent(vid.renderer); - // LOG_info("SDL_RenderPresent blocked for %ims\n", SDL_GetTicks()-then); - vid.blit = NULL; -} - -int PLAT_supportsOverscan(void) { return 1; } - -/////////////////////////////// - -// TODO: -#define OVERLAY_WIDTH PILL_SIZE // unscaled -#define OVERLAY_HEIGHT PILL_SIZE // unscaled -#define OVERLAY_BPP 4 -#define OVERLAY_DEPTH 16 -#define OVERLAY_PITCH (OVERLAY_WIDTH * OVERLAY_BPP) // unscaled -#define OVERLAY_RGBA_MASK 0x00ff0000,0x0000ff00,0x000000ff,0xff000000 // ARGB -static struct OVL_Context { - SDL_Surface* overlay; -} ovl; - -SDL_Surface* PLAT_initOverlay(void) { - ovl.overlay = SDL_CreateRGBSurface(SDL_SWSURFACE, SCALE2(OVERLAY_WIDTH,OVERLAY_HEIGHT),OVERLAY_DEPTH,OVERLAY_RGBA_MASK); - return ovl.overlay; -} -void PLAT_quitOverlay(void) { - if (ovl.overlay) SDL_FreeSurface(ovl.overlay); -} -void PLAT_enableOverlay(int enable) { - -} - -/////////////////////////////// - -static int online = 0; -void PLAT_getBatteryStatus(int* is_charging, int* charge) { - PLAT_getBatteryStatusFine(is_charging, charge); - - // worry less about battery and more about the game you're playing - if (*charge>80) *charge = 100; - else if (*charge>60) *charge = 80; - else if (*charge>40) *charge = 60; - else if (*charge>20) *charge = 40; - else if (*charge>10) *charge = 20; - else *charge = 10; -} - -void PLAT_getBatteryStatusFine(int* is_charging, int* charge) -{ - // *is_charging = 0; - // *charge = PWR_LOW_CHARGE; - // return; - - *is_charging = getInt("/sys/class/power_supply/ac/online"); - - *charge = getInt("/sys/class/power_supply/battery/capacity"); - - // wifi status, just hooking into the regular PWR polling - char status[16]; - getFile("/sys/class/net/wlan0/operstate", status,16); - online = prefixMatch("up", status); -} - -void PLAT_enableBacklight(int enable) { - putInt("/sys/class/backlight/backlight/bl_power", enable ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN); -} - -void PLAT_powerOff(void) { - sleep(2); - - SetRawVolume(MUTE_VOLUME_RAW); - PLAT_enableBacklight(0); - SND_quit(); - VIB_quit(); - PWR_quit(); - GFX_quit(); - - system("shutdown"); - while (1) pause(); // lolwat -} - -/////////////////////////////// - -#define GOVERNOR_PATH "/sys/devices/system/cpu/cpufreq/policy0/scaling_setspeed" -void PLAT_setCPUSpeed(int speed) { - int freq = 0; - switch (speed) { - case CPU_SPEED_MENU: freq = 600000; break; - case CPU_SPEED_POWERSAVE: freq = 1104000; break; - case CPU_SPEED_NORMAL: freq = 1608000; break; - case CPU_SPEED_PERFORMANCE: freq = 1992000; break; - } - putInt(GOVERNOR_PATH, freq); -} - -void PLAT_setRumble(int strength) { - // buh -} - -int PLAT_pickSampleRate(int requested, int max) { - return MIN(requested, max); -} - -static char model[256]; -char* PLAT_getModel(void) { - char buffer[256]; - getFile("/proc/device-tree/model", buffer, 256); - - char* tmp = strrchr(buffer, ' '); - if (tmp) strcpy(model, tmp+1); - else strcpy(model, "RGB30"); - - return model; -} - -int PLAT_isOnline(void) { - return online; -} \ No newline at end of file diff --git a/workspace/_unmaintained/rgb30/platform/platform.h b/workspace/_unmaintained/rgb30/platform/platform.h deleted file mode 100644 index 16a3703c4..000000000 --- a/workspace/_unmaintained/rgb30/platform/platform.h +++ /dev/null @@ -1,137 +0,0 @@ -// rgb30 - -#ifndef PLATFORM_H -#define PLATFORM_H - -/////////////////////////////// - -#include "sdl.h" - -/////////////////////////////// - -#define BUTTON_UP BUTTON_NA -#define BUTTON_DOWN BUTTON_NA -#define BUTTON_LEFT BUTTON_NA -#define BUTTON_RIGHT BUTTON_NA - -#define BUTTON_SELECT BUTTON_NA -#define BUTTON_START BUTTON_NA - -#define BUTTON_A BUTTON_NA -#define BUTTON_B BUTTON_NA -#define BUTTON_X BUTTON_NA -#define BUTTON_Y BUTTON_NA - -#define BUTTON_L1 BUTTON_NA -#define BUTTON_R1 BUTTON_NA -#define BUTTON_L2 BUTTON_NA -#define BUTTON_R2 BUTTON_NA -#define BUTTON_L3 BUTTON_NA -#define BUTTON_R3 BUTTON_NA - -#define BUTTON_MENU BUTTON_NA -#define BUTTON_MENU_ALT BUTTON_NA -#define BUTTON_POWER SDLK_POWER -#define BUTTON_PLUS BUTTON_NA // SDLK_RSUPER -#define BUTTON_MINUS BUTTON_NA // SDLK_LSUPER - -/////////////////////////////// - -#define CODE_UP CODE_NA -#define CODE_DOWN CODE_NA -#define CODE_LEFT CODE_NA -#define CODE_RIGHT CODE_NA - -#define CODE_SELECT CODE_NA -#define CODE_START CODE_NA - -#define CODE_A CODE_NA -#define CODE_B CODE_NA -#define CODE_X CODE_NA -#define CODE_Y CODE_NA - -#define CODE_L1 CODE_NA -#define CODE_R1 CODE_NA -#define CODE_L2 CODE_NA -#define CODE_R2 CODE_NA -#define CODE_L3 CODE_NA -#define CODE_R3 CODE_NA - -#define CODE_MENU CODE_NA -#define CODE_MENU_ALT CODE_NA -#define CODE_POWER 102 // 116 in SDL1? - -// TODO: these were swapped from keymon? -#define CODE_PLUS 129 // 114 in SDL1? -#define CODE_MINUS 128 // 115 in SDL1? - -/////////////////////////////// - -#define JOY_UP 13 -#define JOY_DOWN 14 -#define JOY_LEFT 15 -#define JOY_RIGHT 16 - -#define JOY_SELECT 8 -#define JOY_START 9 - -#define JOY_A 1 -#define JOY_B 0 -#define JOY_X 2 -#define JOY_Y 3 - -#define JOY_L1 4 -#define JOY_R1 5 -#define JOY_L2 6 -#define JOY_R2 7 -#define JOY_L3 JOY_NA -#define JOY_R3 JOY_NA - -#define JOY_MENU 11 -#define JOY_MENU_ALT 12 -#define JOY_POWER JOY_NA -#define JOY_PLUS JOY_NA -#define JOY_MINUS JOY_NA - -/////////////////////////////// - -#define BTN_RESUME BTN_X -#define BTN_SLEEP BTN_POWER -#define BTN_WAKE BTN_POWER -#define BTN_MOD_VOLUME BTN_NONE -#define BTN_MOD_BRIGHTNESS BTN_MENU -#define BTN_MOD_PLUS BTN_PLUS -#define BTN_MOD_MINUS BTN_MINUS - -/////////////////////////////// - -#define FIXED_SCALE 2 -#define FIXED_WIDTH 720 -#define FIXED_HEIGHT 720 -#define FIXED_BPP 2 -#define FIXED_DEPTH (FIXED_BPP * 8) -#define FIXED_PITCH (FIXED_WIDTH * FIXED_BPP) -#define FIXED_SIZE (FIXED_PITCH * FIXED_HEIGHT) - -#define HAS_HDMI 1 -#define HDMI_WIDTH 1280 -#define HDMI_HEIGHT 720 -#define HDMI_PITCH (HDMI_WIDTH * FIXED_BPP) -#define HDMI_SIZE (HDMI_PITCH * HDMI_HEIGHT) - -/////////////////////////////// - -#define MAIN_ROW_COUNT 8 -#define PADDING 40 - -/////////////////////////////// - -#define SDCARD_PATH "/storage/roms" -#define MUTE_VOLUME_RAW 0 -#define SAMPLES 400 - -// this should be set to the devices native screen refresh rate -#define SCREEN_FPS 60.0 -/////////////////////////////// - -#endif diff --git a/workspace/_unmaintained/rgb30/show/makefile b/workspace/_unmaintained/rgb30/show/makefile deleted file mode 100755 index b61deed63..000000000 --- a/workspace/_unmaintained/rgb30/show/makefile +++ /dev/null @@ -1,14 +0,0 @@ -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif - -TARGET = show -PRODUCT = $(TARGET).elf - -CC = $(CROSS_COMPILE)gcc -FLAGS = -Os -lSDL2 -lSDL2_image -lrt -ldl -Wl,--gc-sections -s - -all: - $(CC) $(TARGET).c -o $(PRODUCT) $(FLAGS) -clean: - rm -rf $(PRODUCT) \ No newline at end of file diff --git a/workspace/_unmaintained/rgb30/show/show.c b/workspace/_unmaintained/rgb30/show/show.c deleted file mode 100644 index f68cb5165..000000000 --- a/workspace/_unmaintained/rgb30/show/show.c +++ /dev/null @@ -1,43 +0,0 @@ -// rgb30 -#include -#include -#include -#include - -SDL_Window* window; -SDL_Surface* screen; - -int main(int argc , char* argv[]) { - if (argc<2) { - puts("Usage: show.elf image.png delay"); - return 0; - } - - char path[256]; - strncpy(path,argv[1],256); - if (access(path, F_OK)!=0) return 0; // nothing to show :( - - int delay = argc>2 ? atoi(argv[2]) : 2; - - SDL_Init(SDL_INIT_VIDEO); - SDL_ShowCursor(0); - - int w = 720; - int h = 720; - window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w,h, SDL_WINDOW_SHOWN); - puts(""); - - screen = SDL_GetWindowSurface(window); - SDL_FillRect(screen, NULL, 0); - - SDL_Surface* img = IMG_Load(path); - SDL_BlitSurface(img, NULL, screen, &(SDL_Rect){(screen->w-img->w)/2,(screen->h-img->h)/2}); - - SDL_UpdateWindowSurface(window); - sleep(delay); - - SDL_FreeSurface(img); - SDL_DestroyWindow(window); - SDL_Quit(); - return 0; -} diff --git a/workspace/_unmaintained/trimuismart/cores/makefile b/workspace/_unmaintained/trimuismart/cores/makefile deleted file mode 100644 index e2aa09940..000000000 --- a/workspace/_unmaintained/trimuismart/cores/makefile +++ /dev/null @@ -1,41 +0,0 @@ -CORES = fceumm gambatte gpsp pcsx_rearmed picodrive snes9x2005_plus -CORES+= mednafen_pce_fast mednafen_vb mednafen_supafaust mgba pokemini race -# CORES+= fake-08 - -############################### - -# optional core vars -# *_REPO= -# *_HASH= -# *_CORE= -# *_FLAGS= -# *_MAKEFILE= -# *_BUILD_PATH= - -mednafen_pce_fast_REPO = https://github.com/libretro/beetle-pce-fast-libretro -mednafen_vb_REPO = https://github.com/libretro/beetle-vb-libretro - -fake-08_REPO = https://github.com/jtothebell/fake-08 -fake-08_CORE = fake08_libretro.so -fake-08_BUILD_PATH = fake-08/platform/libretro - -fceumm_REPO = https://github.com/libretro/libretro-fceumm - -gambatte_REPO = https://github.com/libretro/gambatte-libretro - -mednafen_supafaust_REPO = https://github.com/libretro/supafaust - -pcsx_rearmed_MAKEFILE = Makefile.libretro - -picodrive_REPO = https://github.com/irixxxx/picodrive -picodrive_MAKEFILE = Makefile.libretro - -pokemini_REPO = https://github.com/libretro/PokeMini -pokemini_MAKEFILE = Makefile.libretro - -snes9x2005_plus_REPO = https://github.com/libretro/snes9x2005 -snes9x2005_plus_FLAGS = USE_BLARGG_APU=1 - -############################### - -include ../../all/cores/makefile \ No newline at end of file diff --git a/workspace/_unmaintained/trimuismart/cores/patches/fake-08.patch b/workspace/_unmaintained/trimuismart/cores/patches/fake-08.patch deleted file mode 100644 index 96224062d..000000000 --- a/workspace/_unmaintained/trimuismart/cores/patches/fake-08.patch +++ /dev/null @@ -1,34 +0,0 @@ -diff --git forkSrcPrefix/platform/libretro/Makefile forkDstPrefix/platform/libretro/Makefile -index 40805b8adf8101c90e68c5418e7ea697905562ac..c57d3c28dd22040f19299402a0d569f32585fcf0 100644 ---- forkSrcPrefix/platform/libretro/Makefile -+++ forkDstPrefix/platform/libretro/Makefile -@@ -123,7 +123,16 @@ else ifeq ($(platform), miyoomini) - CXXFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7ve -D_NEED_FULL_PATH_ - fpic := -fPIC - SHARED := -shared -Wl,--version-script=link.T -- -+else ifeq ($(platform), trimuismart) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ STRIP = $(CROSS_COMPILE)strip -+ CXXFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 -+ CXXFLAGS += -fomit-frame-pointer -ffast-math -fno-common -ftree-vectorize -funswitch-loops -+ fpic := -fPIC -+ SHARED := -shared -Wl,--version-script=link.T - else ifeq ($(platform), gcw0) - TARGET := $(TARGET_NAME)_libretro_gcw0.so - CC = /opt/gcw0-toolchain/usr/bin/mipsel-linux-gcc -diff --git forkSrcPrefix/platform/libretro/libretro.cpp forkDstPrefix/platform/libretro/libretro.cpp -index bc160dba6d676c7f9c05768f002ea6bce8fe8437..cfa237d9763e2c7092d83aa9fd346c14e4e79db8 100644 ---- forkSrcPrefix/platform/libretro/libretro.cpp -+++ forkDstPrefix/platform/libretro/libretro.cpp -@@ -517,6 +517,7 @@ EXPORT bool retro_load_game(struct retro_game_info const *info) - else { - _vm->QueueCartChange(info->path); - } -+ _vm->UpdateAndDraw(); - - return true; - } diff --git a/workspace/_unmaintained/trimuismart/cores/patches/fceumm.patch b/workspace/_unmaintained/trimuismart/cores/patches/fceumm.patch deleted file mode 100644 index 7409afbcc..000000000 --- a/workspace/_unmaintained/trimuismart/cores/patches/fceumm.patch +++ /dev/null @@ -1,28 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index 036c41f48b087c99b2276b2d41a71d661fd85145..891eb96ceeb1da868d6d2ed40392b51b65dcbb20 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -461,6 +461,23 @@ else ifeq ($(platform), miyoo) - PLATFORM_DEFINES += -fomit-frame-pointer -ffast-math -mcpu=arm926ej-s - EXTERNAL_ZLIB = 1 - -+# MIYOOMINI -+else ifeq ($(platform), trimuismart) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=src/drivers/libretro/link.T -Wl,-no-undefined -+ LDFLAGS += -fPIC -flto -+ CFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 -+ CFLAGS += -fomit-frame-pointer -ffast-math -fPIC -flto -+ OPTIMIZE := -Ofast -DNDEBUG -+ EXTERNAL_ZLIB = 1 -+ HAVE_NTSC = 0 -+ ifeq (,$(DEBUG)) -+ # LDFLAGS += -s -+ endif -+ - # Windows MSVC 2017 all architectures - else ifneq (,$(findstring windows_msvc2017,$(platform))) - CC = cl.exe diff --git a/workspace/_unmaintained/trimuismart/cores/patches/gambatte.patch b/workspace/_unmaintained/trimuismart/cores/patches/gambatte.patch deleted file mode 100644 index ea349d0f9..000000000 --- a/workspace/_unmaintained/trimuismart/cores/patches/gambatte.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index ffaba21e7a88f90786d818ab550b68acd05738bf..2095b2f843eaf6be9abec24ce3da69b551da86a6 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -381,6 +381,19 @@ else ifeq ($(platform), gcw0) - CFLAGS += -fomit-frame-pointer -ffast-math -march=mips32 -mtune=mips32r2 -mhard-float - CXXFLAGS += $(CFLAGS) - -+# MIYOOMINI -+else ifeq ($(platform), trimuismart) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=$(version_script) -+ LDFLAGS += -fPIC -flto -+ PLATFORM_DEFINES := -DCC_RESAMPLER -DCC_RESAMPLER_NO_HIGHPASS -+ CFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 -+ CFLAGS += -fomit-frame-pointer -ffast-math -fPIC -flto -+ CXXFLAGS += $(CFLAGS) -+ - # RETROFW - else ifeq ($(platform), retrofw) - TARGET := $(TARGET_NAME)_libretro.so diff --git a/workspace/_unmaintained/trimuismart/cores/patches/gpsp.patch b/workspace/_unmaintained/trimuismart/cores/patches/gpsp.patch deleted file mode 100644 index 9b75da24a..000000000 --- a/workspace/_unmaintained/trimuismart/cores/patches/gpsp.patch +++ /dev/null @@ -1,27 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index dc4b60dec7f70a153dbc2eb849cd5acfc90f9d4d..09339c7bf819559d5e570b592ac8ab9c50566fba 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -498,6 +498,22 @@ else ifeq ($(platform), miyoo) - HAVE_DYNAREC := 1 - CPU_ARCH := arm - -+# TRIMUISMART -+else ifeq ($(platform), trimuismart) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=link.T -+ fpic := -fPIC -DPIC -+ CFLAGS += -fomit-frame-pointer -ffast-math -+ CFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 -+ HAVE_NEON = 1 -+ ARCH = arm -+ BUILTIN_GPU = neon -+ CPU_ARCH := arm -+ MMAP_JIT_CACHE = 1 -+ HAVE_DYNAREC = 1 - - else ifeq ($(platform), miyoomini) - TARGET := $(TARGET_NAME)_plus_libretro.so diff --git a/workspace/_unmaintained/trimuismart/cores/patches/mednafen_pce_fast.patch b/workspace/_unmaintained/trimuismart/cores/patches/mednafen_pce_fast.patch deleted file mode 100644 index 40f49f857..000000000 --- a/workspace/_unmaintained/trimuismart/cores/patches/mednafen_pce_fast.patch +++ /dev/null @@ -1,29 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index d580571511b43d1ec4597db4a9611b0924bb2c53..2a7a5348c59220f82a99916bf85cc720a0f7f502 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -377,6 +377,24 @@ else ifeq ($(platform), miyoo) - CXXFLAGS += -std=c++11 - CFLAGS += -std=gnu11 - -+# MIYOO MINI -+else ifeq ($(platform), trimuismart) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ fpic := -fPIC -+ SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T -+ LDFLAGS += -lrt -+ CXXFLAGS += -std=c++11 -+ CFLAGS += -std=gnu11 -+ CFLAGS += -fomit-frame-pointer -ffast-math -fPIC -flto -+ CFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 -+ LDFLAGS += -flto -+ ifeq (,$(DEBUG)) -+ LDFLAGS += -s -+ endif -+ - # Windows MSVC 2017 all architectures - else ifneq (,$(findstring windows_msvc2017,$(platform))) - diff --git a/workspace/_unmaintained/trimuismart/cores/patches/mednafen_supafaust.patch b/workspace/_unmaintained/trimuismart/cores/patches/mednafen_supafaust.patch deleted file mode 100644 index fce3073ae..000000000 --- a/workspace/_unmaintained/trimuismart/cores/patches/mednafen_supafaust.patch +++ /dev/null @@ -1,42 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index 58120a1a88eab75ca13f2ed062f37d075c05a51b..8c8cd8a54c6b5a874725400d4de6d037ef500d3b 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -38,6 +38,37 @@ ifeq ($(platform), unix) - FLAGS += -pthread - endif - -+# MIYOOMINI -+else ifeq ($(platform), trimuismart) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ fpic := -fPIC -+ SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T -+ CFLAGS += -Ofast \ -+ -flto=4 -fwhole-program -fuse-linker-plugin \ -+ -fdata-sections -ffunction-sections -Wl,--gc-sections \ -+ -fno-stack-protector -fno-ident -fomit-frame-pointer \ -+ -falign-functions=1 -falign-jumps=1 -falign-loops=1 \ -+ -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-unroll-loops \ -+ -fmerge-all-constants -fno-math-errno \ -+ -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -+ CXXFLAGS += $(CFLAGS) -+ CFLAGS += -fPIC -+ LDFLAGS += -flto -+ HAVE_NEON = 1 -+ ARCH = arm -+ ifeq ($(shell echo `$(CC) -dumpversion` "< 4.9" | bc -l), 1) -+ CFLAGS += -march=armv7-a -+ else -+ CFLAGS += -mcpu=cortex-a7 -+ # If gcc is 5.0 or later -+ ifeq ($(shell echo `$(CC) -dumpversion` ">= 5" | bc -l), 1) -+ LDFLAGS += -static-libgcc -static-libstdc++ -+ endif -+ endif -+ - # Classic Platforms #################### - # Platform affix = classic__<µARCH> - # Help at https://modmyclassic.com/comp diff --git a/workspace/_unmaintained/trimuismart/cores/patches/mednafen_vb.patch b/workspace/_unmaintained/trimuismart/cores/patches/mednafen_vb.patch deleted file mode 100644 index 77a9f4f61..000000000 --- a/workspace/_unmaintained/trimuismart/cores/patches/mednafen_vb.patch +++ /dev/null @@ -1,29 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index c3d5d3b30d71a8f9ed332482fa2af1c21b02605d..5e710154e499ddd7b1ae699122c38753b0f4bb4c 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -217,6 +217,24 @@ else ifneq (,$(filter $(platform), ps3 psl1ght)) - endif - FLAGS += -D__PS3__ - -+# MIYOO MINI -+else ifeq ($(platform), trimuismart) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ NEED_BPP := 16 -+ fpic := -fPIC -+ SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T -+ LDFLAGS += -lrt -+ CFLAGS += -fomit-frame-pointer -ffast-math -fPIC -flto -+ CFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 -+ CPPFLAGS += $(CFLAGS) -+ LDFLAGS += -flto -+ ifeq (,$(DEBUG)) -+ LDFLAGS += -s -+ endif -+ - # PSP - else ifeq ($(platform), psp1) - TARGET := $(TARGET_NAME)_libretro_$(platform).a diff --git a/workspace/_unmaintained/trimuismart/cores/patches/mgba.patch b/workspace/_unmaintained/trimuismart/cores/patches/mgba.patch deleted file mode 100644 index 3b76b8f38..000000000 --- a/workspace/_unmaintained/trimuismart/cores/patches/mgba.patch +++ /dev/null @@ -1,31 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index 108148f4579f4727146e5b8c1e05ef7382654208..35e6399147a4ef75947ecb2ad4a94f0820ef24d0 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -417,6 +417,26 @@ else ifeq ($(platform), miyoo) - CFLAGS += -fno-common -ftree-vectorize -funswitch-loops - DEFINES += -std=c99 - -+# MIYOOMINI -+else ifeq ($(platform), trimuismart) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=link.T -+ fpic := -fPIC -+ PLATFORM_DEFINES += -D_GNU_SOURCE -DHAVE_STRTOF_L -DHAVE_LOCALE -+ CFLAGS += -fomit-frame-pointer -ffast-math -+ CFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 -+ CFLAGS += -fno-common -ftree-vectorize -funswitch-loops -+ HAVE_NEON = 1 -+ ARCH = arm -+ BUILTIN_GPU = neon -+ CPU_ARCH := arm -+ MMAP_JIT_CACHE = 1 -+ HAVE_DYNAREC = 1 -+ DEFINES += -std=c99 -+ - # Windows - else - TARGET := $(TARGET_NAME)_libretro.dll diff --git a/workspace/_unmaintained/trimuismart/cores/patches/pcsx_rearmed.patch b/workspace/_unmaintained/trimuismart/cores/patches/pcsx_rearmed.patch deleted file mode 100644 index 8089ca651..000000000 --- a/workspace/_unmaintained/trimuismart/cores/patches/pcsx_rearmed.patch +++ /dev/null @@ -1,31 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index 7b9618e1ccfc63982be50b82fda498d75e307fdc..f314adcbea17f05f473e1cbafc8711ab8ea0c5f1 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -391,6 +391,26 @@ else ifeq ($(platform), rpi4_64) - fpic := -fPIC - CFLAGS += -march=armv8-a+crc+simd -mtune=cortex-a72 -ftree-vectorize - -+# MIYOOMINI -+else ifeq ($(platform), trimuismart) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ CFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 -fomit-frame-pointer -+ CFLAGS += -ffast-math -fdata-sections -ffunction-sections -fsingle-precision-constant -flto -fPIC -DNO_HWCAP -+ LDFLAGS += -flto -fPIC -+ ifeq (,$(DEBUG)) -+ # LDFLAGS += -s -+ endif -+ CPU_ARCH := arm -+ OPTIMIZE := -Ofast -DNDEBUG=1 -+ HAVE_NEON = 1 -+ HAVE_NEON_ASM = 1 -+ BUILTIN_GPU = neon -+ ARCH = arm -+ DYNAREC = ari64 -+ - # Classic Platforms #################### - # Platform affix = classic__<µARCH> - # Help at https://modmyclassic.com/comp diff --git a/workspace/_unmaintained/trimuismart/cores/patches/picodrive.patch b/workspace/_unmaintained/trimuismart/cores/patches/picodrive.patch deleted file mode 100644 index 6016a81c4..000000000 --- a/workspace/_unmaintained/trimuismart/cores/patches/picodrive.patch +++ /dev/null @@ -1,35 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index 0d1dc08f81a11cef6b3b7238367b1ff27fcf1ead..1f87c76c3242023c4095f0c9087c52765d93c33c 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -497,6 +497,30 @@ else ifeq ($(platform), miyoo) - HAVE_ARMv6 = 0 - LOW_MEMORY = 1 - -+# MIYOO MINI -+else ifeq ($(platform), trimuismart) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--no-undefined -+ DONT_COMPILE_IN_ZLIB = 1 -+ CFLAGS += -Ofast \ -+ -fdata-sections -ffunction-sections -Wl,--gc-sections \ -+ -fno-stack-protector -fno-ident -fomit-frame-pointer \ -+ -falign-functions=1 -falign-jumps=1 -falign-loops=1 \ -+ -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-unroll-loops \ -+ -fmerge-all-constants -fno-math-errno -+ CFLAGS += -fPIC -flto -+ CFLAGS += -fomit-frame-pointer -ffast-math -D__GCW0__ -+ CFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 -+ LDFLAGS += -flto -+ HAVE_NEON = 1 -+ BUILTIN_GPU = neon -+ ifeq (,$(DEBUG)) -+ LDFLAGS += -s -+ endif -+ - # Windows MSVC 2017 all architectures - else ifneq (,$(findstring windows_msvc2017,$(platform))) - NO_GCC := 1 diff --git a/workspace/_unmaintained/trimuismart/cores/patches/pokemini.patch b/workspace/_unmaintained/trimuismart/cores/patches/pokemini.patch deleted file mode 100644 index e1372c744..000000000 --- a/workspace/_unmaintained/trimuismart/cores/patches/pokemini.patch +++ /dev/null @@ -1,27 +0,0 @@ -diff --git forkSrcPrefix/Makefile.libretro forkDstPrefix/Makefile.libretro -index ef2f9e7d1c6041bea8e2c8a61cdd363ed73a7482..ada8785f566af89cc77f5ab2dd9e670b0a998545 100644 ---- forkSrcPrefix/Makefile.libretro -+++ forkDstPrefix/Makefile.libretro -@@ -504,6 +504,22 @@ else ifeq ($(platform), retrofw) - CFLAGS += -ffast-math -fomit-frame-pointer -march=mips32 -mtune=mips32 -mhard-float - CFLAGS += -DDINGUX - -+# MIYOOMINI -+else ifeq ($(platform), trimuismart) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=libretro/link.T -Wl,--no-undefined -+ fpic := -fPIC -+ CFLAGS += -DARM -+ CFLAGS += $(PTHREAD_FLAGS) -+ CFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 -+ CFLAGS += -ffast-math -fomit-frame-pointer -+ CFLAGS += -DDINGUX -+ HAVE_NEON = 1 -+ ARCH = arm -+ - else ifeq ($(platform), msvc) - OBJOUT = -Fo - diff --git a/workspace/_unmaintained/trimuismart/cores/patches/race.patch b/workspace/_unmaintained/trimuismart/cores/patches/race.patch deleted file mode 100644 index cb8afaf2f..000000000 --- a/workspace/_unmaintained/trimuismart/cores/patches/race.patch +++ /dev/null @@ -1,23 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index 792a6d82915c32edd3df6ceec541499f6ca25ac5..dc02b361d7db47e011b6d3addf89cfb31503575a 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -373,6 +373,18 @@ else ifeq ($(platform), miyoo) - CFLAGS += -fomit-frame-pointer -ffast-math -march=armv5te -mtune=arm926ej-s - CXXFLAGS += $(CFLAGS) - -+# TRIMUI SMART -+else ifeq ($(platform), trimuismart) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ fpic := -fPIC -+ SHARED := -shared -Wl,-version-script=$(LIBRETRO_DIR)/link.T -+ PLATFORM_DEFINES := -DCC_RESAMPLER -DCC_RESAMPLER_NO_HIGHPASS -+ CFLAGS += -fomit-frame-pointer -ffast-math -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 -+ CXXFLAGS += $(CFLAGS) -+ - # Windows MSVC 2010 x64 - else ifeq ($(platform), windows_msvc2010_x64) - CC = cl.exe diff --git a/workspace/_unmaintained/trimuismart/cores/patches/snes9x2005_plus.patch b/workspace/_unmaintained/trimuismart/cores/patches/snes9x2005_plus.patch deleted file mode 100644 index 364c3cb6e..000000000 --- a/workspace/_unmaintained/trimuismart/cores/patches/snes9x2005_plus.patch +++ /dev/null @@ -1,36 +0,0 @@ -diff --git forkSrcPrefix/Makefile forkDstPrefix/Makefile -index 07d5368a8e78a020813732239ec369d83e931ede..009f13b8e61c634de4cb83e97785a10b83b4322d 100644 ---- forkSrcPrefix/Makefile -+++ forkDstPrefix/Makefile -@@ -288,6 +288,31 @@ else ifeq ($(platform), miyoo) - FLAGS += -fomit-frame-pointer -ffast-math -march=armv5te -mtune=arm926ej-s - FLAGS += -DFAST_ALIGNED_LSB_WORD_ACCESS -fno-unroll-loops - -+# MIYOOMINI -+else ifeq ($(platform), trimuismart) -+ TARGET := $(TARGET_NAME)_libretro.so -+ CC = $(CROSS_COMPILE)gcc -+ CXX = $(CROSS_COMPILE)g++ -+ AR = $(CROSS_COMPILE)ar -+ SHARED := -shared -Wl,--version-script=link.T -+ LIBM := -+ CFLAGS += -Ofast \ -+ -flto=4 -fwhole-program -fuse-linker-plugin \ -+ -fdata-sections -ffunction-sections -Wl,--gc-sections \ -+ -fno-stack-protector -fno-ident -fomit-frame-pointer \ -+ -falign-functions=1 -falign-jumps=1 -falign-loops=1 \ -+ -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-unroll-loops \ -+ -fmerge-all-constants -fno-math-errno -+ CFLAGS += -fPIC -+ CFLAGS += -DLSB_FIRST -DFAST_ALIGNED_LSB_WORD_ACCESS -DRIGHTSHIFT_IS_SAR -+ CFLAGS += -std=c99 -fomit-frame-pointer -ffast-math -+ CFLAGS += -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 -+ LDFLAGS += -flto -+ OPTIMIZE += -Ofast -DNDEBUG=1 -+ ifeq (,$(DEBUG)) -+ LDFLAGS += -s -+ endif -+ - # (armv7 a7, hard point, neon based) ### - # NESC, SNESC, C64 mini - else ifeq ($(platform), classic_armv7_a7) diff --git a/workspace/_unmaintained/trimuismart/install/boot.sh b/workspace/_unmaintained/trimuismart/install/boot.sh deleted file mode 100755 index eda17fedd..000000000 --- a/workspace/_unmaintained/trimuismart/install/boot.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/sh -# NOTE: becomes .tmp_update/trimuismart.sh - -PLATFORM="trimuismart" -SDCARD_PATH="/mnt/SDCARD" -UPDATE_PATH="$SDCARD_PATH/NextUI.zip" -SYSTEM_PATH="$SDCARD_PATH/.system" - -CPU_PATH=/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor -echo performance > "$CPU_PATH" - -# install/update -if [ -f "$UPDATE_PATH" ]; then - # TODO: this shouldn't be necessary but might be? - export LD_LIBRARY_PATH=/usr/trimui/lib:$LD_LIBRARY_PATH - export PATH=/usr/trimui/bin:$PATH - - cd $(dirname "$0")/$PLATFORM - ./leds_off - if [ -d "$SYSTEM_PATH" ]; then - ./show.elf ./updating.png - else - ./show.elf ./installing.png - fi - - ./unzip -o "$UPDATE_PATH" -d "$SDCARD_PATH" # &> /mnt/SDCARD/unzip.txt - rm -f "$UPDATE_PATH" - - # the updated system finishes the install/update - if [ -f $SYSTEM_PATH/$PLATFORM/bin/install.sh ]; then - $SYSTEM_PATH/$PLATFORM/bin/install.sh # &> $SDCARD_PATH/log.txt - fi -fi - -LAUNCH_PATH="$SYSTEM_PATH/$PLATFORM/paks/NextUI.pak/launch.sh" -while [ -f "$LAUNCH_PATH" ] ; do - "$LAUNCH_PATH" -done - -poweroff # under no circumstances should stock be allowed to touch this card diff --git a/workspace/_unmaintained/trimuismart/install/installing.png b/workspace/_unmaintained/trimuismart/install/installing.png deleted file mode 100644 index d395a24967623c5442fb72a42c3eff48f83975a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4423 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 Ad;kCd diff --git a/workspace/_unmaintained/trimuismart/install/updating.png b/workspace/_unmaintained/trimuismart/install/updating.png deleted file mode 100644 index ffca469d0d065d2a5752ed50836c0ef4b910ca72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4414 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 diff --git a/workspace/_unmaintained/trimuismart/keymon/credits.txt b/workspace/_unmaintained/trimuismart/keymon/credits.txt deleted file mode 100644 index e885e5dd1..000000000 --- a/workspace/_unmaintained/trimuismart/keymon/credits.txt +++ /dev/null @@ -1,3 +0,0 @@ -based on eggs custom keymon for Trimui: - https://www.dropbox.com/sh/5e9xwvp672vt8cr/AABUIdw1vLYp9h0waoCUqHPOa/source?dl=0&subfolder_nav_tracking=1 -modified to use libmsettings \ No newline at end of file diff --git a/workspace/_unmaintained/trimuismart/keymon/keymon.c b/workspace/_unmaintained/trimuismart/keymon/keymon.c deleted file mode 100644 index 76e8bd1fc..000000000 --- a/workspace/_unmaintained/trimuismart/keymon/keymon.c +++ /dev/null @@ -1,104 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include "defines.h" - -#define RELEASED 0 -#define PRESSED 1 - -#define INPUT_COUNT 2 -static int input_fd = 0; -static struct input_event ev; - -int main (int argc, char *argv[]) { - InitSettings(); - - input_fd = open("/dev/input/event0", O_RDONLY | O_NONBLOCK | O_CLOEXEC); - - uint32_t input; - uint32_t val; - uint32_t start_pressed = 0; - uint32_t select_pressed = 0; - - uint32_t up_pressed = 0; - uint32_t up_just_pressed = 0; - uint32_t up_repeat_at = 0; - - uint32_t down_pressed = 0; - uint32_t down_just_pressed = 0; - uint32_t down_repeat_at = 0; - - uint32_t now; - struct timeval tod; - - while (1) { - gettimeofday(&tod, NULL); - now = tod.tv_sec * 1000 + tod.tv_usec / 1000; - - while(read(input_fd, &ev, sizeof(ev))==sizeof(ev)) { - if (ev.type != EV_KEY ) continue; - val = ev.value; - - switch (ev.code) { - case CODE_START: - start_pressed = val; - break; - case CODE_SELECT: - select_pressed = val; - break; - case CODE_R1: - up_pressed = up_just_pressed = val; - if (val) up_repeat_at = now + 300; - break; - case CODE_L1: - down_pressed = down_just_pressed = val; - if (val) down_repeat_at = now + 300; - break; - default: - break; - } - } - - if (up_just_pressed || (up_pressed && now>=up_repeat_at)) { - if (start_pressed) { - val = GetBrightness(); - if (val=down_repeat_at)) { - if (start_pressed) { - val = GetBrightness(); - if (val>BRIGHTNESS_MIN) SetBrightness(--val); - } - else if (select_pressed) { - val = GetVolume(); - if (val>VOLUME_MIN) SetVolume(--val); - } - - if (down_just_pressed) down_just_pressed = 0; - else down_repeat_at += 100; - } - - usleep(16666); // 60fps - } -} diff --git a/workspace/_unmaintained/trimuismart/keymon/makefile b/workspace/_unmaintained/trimuismart/keymon/makefile deleted file mode 100755 index e23c35820..000000000 --- a/workspace/_unmaintained/trimuismart/keymon/makefile +++ /dev/null @@ -1,14 +0,0 @@ -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif - -TARGET = keymon -PRODUCT = $(TARGET).elf - -CC = $(CROSS_COMPILE)gcc -I../../all/common/ -I../platform/ -FLAGS = -Os -lmsettings -lpthread -lrt -ldl -Wl,--gc-sections -s - -all: - $(CC) $(TARGET).c -o $(PRODUCT) $(FLAGS) -clean: - rm -rf $(PRODUCT) \ No newline at end of file diff --git a/workspace/_unmaintained/trimuismart/libmsettings/makefile b/workspace/_unmaintained/trimuismart/libmsettings/makefile deleted file mode 100644 index b1418a21d..000000000 --- a/workspace/_unmaintained/trimuismart/libmsettings/makefile +++ /dev/null @@ -1,32 +0,0 @@ -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif -ifeq (,$(PREFIX)) -$(error missing PREFIX for this toolchain) -endif - -TARGET=msettings - -.PHONY: build -.PHONY: clean - -CC = $(CROSS_COMPILE)gcc - -SYSROOT := $(shell $(CC) --print-sysroot) - -INCLUDEDIR = $(SYSROOT)/usr/include -CFLAGS = -I$(INCLUDEDIR) -LDFLAGS = -ldl -lrt -s - -OPTM=-Ofast - -build: - $(CC) -c -Werror -fpic "$(TARGET).c" -Wl,--no-as-needed $(LDFLAGS) - $(CC) -shared -o "lib$(TARGET).so" "$(TARGET).o" $(LDFLAGS) - cp "$(TARGET).h" "$(PREFIX)/include" - cp "lib$(TARGET).so" "$(PREFIX)/lib" -clean: - rm -f *.o - rm -f "lib$(TARGET).so" - rm -f $(PREFIX)/include/$(TARGET).h - rm -f $(PREFIX)/lib/lib$(TARGET).so \ No newline at end of file diff --git a/workspace/_unmaintained/trimuismart/libmsettings/msettings.c b/workspace/_unmaintained/trimuismart/libmsettings/msettings.c deleted file mode 100644 index 86284d251..000000000 --- a/workspace/_unmaintained/trimuismart/libmsettings/msettings.c +++ /dev/null @@ -1,165 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sunxi_display2.h" -#include "msettings.h" - -/////////////////////////////////////// - -#define SETTINGS_VERSION 1 -typedef struct Settings { - int version; // future proofing - int brightness; - int headphones; // available? - int speaker; - int unused[2]; // for future use - // NOTE: doesn't really need to be persisted but still needs to be shared - int jack; -} Settings; -static Settings DefaultSettings = { - .version = SETTINGS_VERSION, - .brightness = 3, - .headphones = 4, - .speaker = 8, - .jack = 0, -}; -static Settings* settings; - -#define SHM_KEY "/SharedSettings" -static char SettingsPath[256]; -static int shm_fd = -1; -static int disp_fd = -1; -static int is_host = 0; -static int shm_size = sizeof(Settings); - -void InitSettings(void) { - sprintf(SettingsPath, "%s/msettings.bin", getenv("USERDATA_PATH")); - - shm_fd = shm_open(SHM_KEY, O_RDWR | O_CREAT | O_EXCL, 0644); // see if it exists - if (shm_fd==-1 && errno==EEXIST) { // already exists - puts("Settings client"); - shm_fd = shm_open(SHM_KEY, O_RDWR, 0644); - settings = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); - } - else { // host - puts("Settings host"); // keymon - is_host = 1; - // we created it so set initial size and populate - ftruncate(shm_fd, shm_size); - settings = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); - - int fd = open(SettingsPath, O_RDONLY); - if (fd>=0) { - read(fd, settings, shm_size); - // TODO: use settings->version for future proofing? - close(fd); - } - else { - // load defaults - memcpy(settings, &DefaultSettings, shm_size); - } - - // these shouldn't be persisted - // settings->jack = 0; - } - printf("brightness: %i\nspeaker: %i \n", settings->brightness, settings->speaker); - - disp_fd = open("/dev/disp", O_RDWR); - - SetVolume(GetVolume()); - SetBrightness(GetBrightness()); -} -void QuitSettings(void) { - close(disp_fd); - munmap(settings, shm_size); - if (is_host) shm_unlink(SHM_KEY); -} -static inline void SaveSettings(void) { - int fd = open(SettingsPath, O_CREAT|O_WRONLY, 0644); - if (fd>=0) { - write(fd, settings, shm_size); - close(fd); - sync(); - } -} - -int GetBrightness(void) { // 0-10 - return settings->brightness; -} -void SetBrightness(int value) { - settings->brightness = value; - - int raw; - switch (value) { - case 0: raw = 8; break; - case 1: raw = 12; break; - case 2: raw = 16; break; - case 3: raw = 24; break; - case 4: raw = 32; break; - case 5: raw = 48; break; - case 6: raw = 64; break; - case 7: raw = 96; break; - case 8: raw = 128; break; - case 9: raw = 192; break; - case 10: raw = 256; break; - } - - SetRawBrightness(raw); - SaveSettings(); -} - -int GetVolume(void) { // 0-20 - return settings->jack ? settings->headphones : settings->speaker; -} -void SetVolume(int value) { - if (settings->jack) settings->headphones = value; - else settings->speaker = value; - - int raw = value * 31 / 20; - SetRawVolume(raw); - SaveSettings(); -} - -void SetRawBrightness(int val) { // 0 - 255 - // char cmd[256]; - // sprintf(cmd, "iodisp 0 %i", val); - // system(cmd); - - u32 args[4] = {0}; - args[1] = val; - ioctl(disp_fd, DISP_LCD_SET_BRIGHTNESS, args); -} -void SetRawVolume(int val) { // 0 - 40 - char cmd[256]; - sprintf(cmd, "amixer sset 'Lineout volume' %i", val); - system(cmd); -} - -// monitored and set by thread in keymon -int GetJack(void) { - return settings->jack; -} -void SetJack(int value) { - // printf("SetJack(%i)\n", value); fflush(stdout); - settings->jack = value; - SetVolume(GetVolume()); -} - -int GetHDMI(void) { - return 0; -} -void SetHDMI(int value) { - // buh -} - -int GetMute(void) { return 0; } -void SetMute(int value) {} diff --git a/workspace/_unmaintained/trimuismart/libmsettings/msettings.h b/workspace/_unmaintained/trimuismart/libmsettings/msettings.h deleted file mode 100644 index 47e5fb003..000000000 --- a/workspace/_unmaintained/trimuismart/libmsettings/msettings.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef __msettings_h__ -#define __msettings_h__ - -void InitSettings(void); -void QuitSettings(void); - -int GetBrightness(void); -int GetVolume(void); - -void SetRawBrightness(int value); // 0-1024 -void SetRawVolume(int value); // 0-40 - -void SetBrightness(int value); // 0-10 -void SetVolume(int value); // 0-20 - -int GetJack(void); -void SetJack(int value); // 0-1 - -int GetHDMI(void); -void SetHDMI(int value); // 0-1 - -int GetMute(void); -void SetMute(int value); // 0-1 - -#endif // __msettings_h__ diff --git a/workspace/_unmaintained/trimuismart/libmsettings/sunxi_display2.h b/workspace/_unmaintained/trimuismart/libmsettings/sunxi_display2.h deleted file mode 100755 index efb7f186a..000000000 --- a/workspace/_unmaintained/trimuismart/libmsettings/sunxi_display2.h +++ /dev/null @@ -1,521 +0,0 @@ -#ifndef __SUNXI_DISPLAY_H__ -#define __SUNXI_DISPLAY_H__ - -typedef int bool; -typedef unsigned int u32; - -struct disp_manager; -struct disp_device; -struct disp_smbl; -struct disp_enhance; -struct disp_capture; - -typedef struct {unsigned char alpha;unsigned char red;unsigned char green; unsigned char blue; }disp_color; -typedef struct {int x; int y; unsigned int width; unsigned int height;}disp_rect; -typedef struct {unsigned int width;unsigned int height; }disp_rectsz; -typedef struct {int x; int y; }disp_position; - -typedef enum -{ - DISP_FORMAT_ARGB_8888 = 0x00,//MSB A-R-G-B LSB - DISP_FORMAT_ABGR_8888 = 0x01, - DISP_FORMAT_RGBA_8888 = 0x02, - DISP_FORMAT_BGRA_8888 = 0x03, - DISP_FORMAT_XRGB_8888 = 0x04, - DISP_FORMAT_XBGR_8888 = 0x05, - DISP_FORMAT_RGBX_8888 = 0x06, - DISP_FORMAT_BGRX_8888 = 0x07, - DISP_FORMAT_RGB_888 = 0x08, - DISP_FORMAT_BGR_888 = 0x09, - DISP_FORMAT_RGB_565 = 0x0a, - DISP_FORMAT_BGR_565 = 0x0b, - DISP_FORMAT_ARGB_4444 = 0x0c, - DISP_FORMAT_ABGR_4444 = 0x0d, - DISP_FORMAT_RGBA_4444 = 0x0e, - DISP_FORMAT_BGRA_4444 = 0x0f, - DISP_FORMAT_ARGB_1555 = 0x10, - DISP_FORMAT_ABGR_1555 = 0x11, - DISP_FORMAT_RGBA_5551 = 0x12, - DISP_FORMAT_BGRA_5551 = 0x13, - - /* SP: semi-planar, P:planar, I:interleaved - * UVUV: U in the LSBs; VUVU: V in the LSBs */ - DISP_FORMAT_YUV444_I_AYUV = 0x40,//MSB A-Y-U-V LSB, reserved - DISP_FORMAT_YUV444_I_VUYA = 0x41,//MSB V-U-Y-A LSB - DISP_FORMAT_YUV422_I_YVYU = 0x42,//MSB Y-V-Y-U LSB - DISP_FORMAT_YUV422_I_YUYV = 0x43,//MSB Y-U-Y-V LSB - DISP_FORMAT_YUV422_I_UYVY = 0x44,//MSB U-Y-V-Y LSB - DISP_FORMAT_YUV422_I_VYUY = 0x45,//MSB V-Y-U-Y LSB - DISP_FORMAT_YUV444_P = 0x46,//MSB P3-2-1-0 LSB, YYYY UUUU VVVV, reserved - DISP_FORMAT_YUV422_P = 0x47,//MSB P3-2-1-0 LSB YYYY UU VV - DISP_FORMAT_YUV420_P = 0x48,//MSB P3-2-1-0 LSB YYYY U V - DISP_FORMAT_YUV411_P = 0x49,//MSB P3-2-1-0 LSB YYYY U V - DISP_FORMAT_YUV422_SP_UVUV = 0x4a,//MSB V-U-V-U LSB - DISP_FORMAT_YUV422_SP_VUVU = 0x4b,//MSB U-V-U-V LSB - DISP_FORMAT_YUV420_SP_UVUV = 0x4c, - DISP_FORMAT_YUV420_SP_VUVU = 0x4d, - DISP_FORMAT_YUV411_SP_UVUV = 0x4e, - DISP_FORMAT_YUV411_SP_VUVU = 0x4f, -}disp_pixel_format; - -typedef enum -{ - DISP_3D_OUT_MODE_CI_1 = 0x5,//column interlaved 1 - DISP_3D_OUT_MODE_CI_2 = 0x6,//column interlaved 2 - DISP_3D_OUT_MODE_CI_3 = 0x7,//column interlaved 3 - DISP_3D_OUT_MODE_CI_4 = 0x8,//column interlaved 4 - DISP_3D_OUT_MODE_LIRGB = 0x9,//line interleaved rgb - - DISP_3D_OUT_MODE_TB = 0x0,//top bottom - DISP_3D_OUT_MODE_FP = 0x1,//frame packing - DISP_3D_OUT_MODE_SSF = 0x2,//side by side full - DISP_3D_OUT_MODE_SSH = 0x3,//side by side half - DISP_3D_OUT_MODE_LI = 0x4,//line interleaved - DISP_3D_OUT_MODE_FA = 0xa,//field alternative -}disp_3d_out_mode; - -typedef enum -{ - DISP_BT601 = 0, - DISP_BT709 = 1, - DISP_YCC = 2, -}disp_color_space; - -typedef enum -{ - DISP_CSC_TYPE_RGB = 0, - DISP_CSC_TYPE_YUV1 = 1,//HDMI - DISP_CSC_TYPE_YUV2 = 2,//TV -}disp_csc_type; - -typedef enum -{ - DISP_COLOR_RANGE_16_255 = 0, - DISP_COLOR_RANGE_0_255 = 1, - DISP_COLOR_RANGE_16_235 = 2, -}disp_color_range; - -typedef enum -{ - DISP_OUTPUT_TYPE_NONE = 0, - DISP_OUTPUT_TYPE_LCD = 1, - DISP_OUTPUT_TYPE_TV = 2, - DISP_OUTPUT_TYPE_HDMI = 4, - DISP_OUTPUT_TYPE_VGA = 8, -}disp_output_type; - -typedef enum -{ - DISP_TV_MOD_480I = 0, - DISP_TV_MOD_576I = 1, - DISP_TV_MOD_480P = 2, - DISP_TV_MOD_576P = 3, - DISP_TV_MOD_720P_50HZ = 4, - DISP_TV_MOD_720P_60HZ = 5, - DISP_TV_MOD_1080I_50HZ = 6, - DISP_TV_MOD_1080I_60HZ = 7, - DISP_TV_MOD_1080P_24HZ = 8, - DISP_TV_MOD_1080P_50HZ = 9, - DISP_TV_MOD_1080P_60HZ = 0xa, - DISP_TV_MOD_1080P_24HZ_3D_FP = 0x17, - DISP_TV_MOD_720P_50HZ_3D_FP = 0x18, - DISP_TV_MOD_720P_60HZ_3D_FP = 0x19, - DISP_TV_MOD_1080P_25HZ = 0x1a, - DISP_TV_MOD_1080P_30HZ = 0x1b, - DISP_TV_MOD_PAL = 0xb, - DISP_TV_MOD_PAL_SVIDEO = 0xc, - DISP_TV_MOD_NTSC = 0xe, - DISP_TV_MOD_NTSC_SVIDEO = 0xf, - DISP_TV_MOD_PAL_M = 0x11, - DISP_TV_MOD_PAL_M_SVIDEO = 0x12, - DISP_TV_MOD_PAL_NC = 0x14, - DISP_TV_MOD_PAL_NC_SVIDEO = 0x15, - DISP_TV_MOD_3840_2160P_30HZ = 0x1c, - DISP_TV_MOD_3840_2160P_25HZ = 0x1d, - DISP_TV_MOD_3840_2160P_24HZ = 0x1e, - DISP_TV_MODE_NUM = 0x1f, -}disp_tv_mode; - - -//FIXME:still need? -typedef enum -{ - DISP_EXIT_MODE_CLEAN_ALL = 0, - DISP_EXIT_MODE_CLEAN_PARTLY = 1,//only clean interrupt temply -}disp_exit_mode; - -typedef enum -{ - DISP_BF_NORMAL = 0,//non-stereo - DISP_BF_STEREO_TB = 1 << 0,//stereo top-bottom - DISP_BF_STEREO_FP = 1 << 1,//stereo frame packing - DISP_BF_STEREO_SSH = 1 << 2,//stereo side by side half - DISP_BF_STEREO_SSF = 1 << 3,//stereo side by side full - DISP_BF_STEREO_LI = 1 << 4,//stereo line interlace -}disp_buffer_flags; - -typedef enum -{ - LAYER_MODE_BUFFER = 0, - LAYER_MODE_COLOR = 1, -}disp_layer_mode; - -typedef enum -{ - DISP_SCAN_PROGRESSIVE = 0,//non interlace - DISP_SCAN_INTERLACED_ODD_FLD_FIRST = 1 << 0,//interlace ,odd field first - DISP_SCAN_INTERLACED_EVEN_FLD_FIRST = 1 << 1,//interlace,even field first -}disp_scan_flags; - -typedef struct -{ - unsigned int type; - unsigned int mode; -}disp_output; - -typedef struct -{ - long long x; - long long y; - long long width; - long long height; -}disp_rect64; - -typedef struct -{ - unsigned long long addr[3]; /* address of frame buffer, - single addr for interleaved fomart, - double addr for semi-planar fomart - triple addr for planar format */ - disp_rectsz size[3]; //size for 3 component,unit: pixels - unsigned int align[3]; //align for 3 comonent,unit: bytes(align=2^n,i.e. 1/2/4/8/16/32..) - disp_pixel_format format; - disp_color_space color_space; //color space - unsigned int trd_right_addr[3];/* right address of 3d fb, - used when in frame packing 3d mode */ - bool pre_multiply; //true: pre-multiply fb - disp_rect64 crop; //crop rectangle boundaries - disp_buffer_flags flags; //indicate stereo or non-stereo buffer - disp_scan_flags scan; //scan type & scan order -}disp_fb_info; - -typedef struct -{ - disp_layer_mode mode; - unsigned char zorder; /*specifies the front-to-back ordering of the layers on the screen, - the top layer having the highest Z value - can't set zorder, but can get */ - unsigned char alpha_mode; //0: pixel alpha; 1: global alpha; 2: global pixel alpha - unsigned char alpha_value; //global alpha value - disp_rect screen_win; //display window on the screen - bool b_trd_out; //3d display - disp_3d_out_mode out_trd_mode;//3d display mode - union { - unsigned int color; //valid when LAYER_MODE_COLOR - disp_fb_info fb; //framebuffer, valid when LAYER_MODE_BUFFER - }; - - unsigned int id; /* frame id, can get the id of frame display currently - by DISP_LAYER_GET_FRAME_ID */ -}disp_layer_info; - -typedef struct -{ - disp_layer_info info; - bool enable; - unsigned int channel; - unsigned int layer_id; -}disp_layer_config; - -typedef struct -{ - disp_color ck_max; - disp_color ck_min; - unsigned int red_match_rule;//0/1:always match; 2:match if min<=color<=max; 3:match if color>max or colormax or colormax or color - -struct ion_handle; -/** - * enum ion_heap_types - list of all possible types of heaps - * @ION_HEAP_TYPE_SYSTEM: memory allocated via vmalloc - * @ION_HEAP_TYPE_SYSTEM_CONTIG: memory allocated via kmalloc - * @ION_HEAP_TYPE_CARVEOUT: memory allocated from a prereserved - * carveout heap, allocations are physically - * contiguous - * @ION_HEAP_TYPE_DMA: memory allocated via DMA API - * @ION_NUM_HEAPS: helper for iterating over heaps, a bit mask - * is used to identify the heaps, so only 32 - * total heap types are supported - */ -enum ion_heap_type { - ION_HEAP_TYPE_SYSTEM, - ION_HEAP_TYPE_SYSTEM_CONTIG, - ION_HEAP_TYPE_CARVEOUT, - ION_HEAP_TYPE_CHUNK, - ION_HEAP_TYPE_DMA, - ION_HEAP_TYPE_CUSTOM, /* must be last so device specific heaps always - are at the end of this enum */ - ION_NUM_HEAPS = 16, -}; - -#define ION_HEAP_SYSTEM_MASK (1 << ION_HEAP_TYPE_SYSTEM) -#define ION_HEAP_SYSTEM_CONTIG_MASK (1 << ION_HEAP_TYPE_SYSTEM_CONTIG) -#define ION_HEAP_CARVEOUT_MASK (1 << ION_HEAP_TYPE_CARVEOUT) -#define ION_HEAP_TYPE_DMA_MASK (1 << ION_HEAP_TYPE_DMA) - -#define ION_NUM_HEAP_IDS sizeof(unsigned int) * 8 - -/** - * allocation flags - the lower 16 bits are used by core ion, the upper 16 - * bits are reserved for use by the heaps themselves. - */ -#define ION_FLAG_CACHED 1 /* mappings of this buffer should be - cached, ion will do cache - maintenance when the buffer is - mapped for dma */ -#define ION_FLAG_CACHED_NEEDS_SYNC 2 /* mappings of this buffer will created - at mmap time, if this is set - caches must be managed manually */ - -#ifdef __KERNEL__ -struct ion_device; -struct ion_heap; -struct ion_mapper; -struct ion_client; -struct ion_buffer; - -/* This should be removed some day when phys_addr_t's are fully - plumbed in the kernel, and all instances of ion_phys_addr_t should - be converted to phys_addr_t. For the time being many kernel interfaces - do not accept phys_addr_t's that would have to */ -#define ion_phys_addr_t unsigned long - -/** - * struct ion_platform_heap - defines a heap in the given platform - * @type: type of the heap from ion_heap_type enum - * @id: unique identifier for heap. When allocating higher numbers - * will be allocated from first. At allocation these are passed - * as a bit mask and therefore can not exceed ION_NUM_HEAP_IDS. - * @name: used for debug purposes - * @base: base address of heap in physical memory if applicable - * @size: size of the heap in bytes if applicable - * @align: required alignment in physical memory if applicable - * @priv: private info passed from the board file - * - * Provided by the board file. - */ -struct ion_platform_heap { - enum ion_heap_type type; - unsigned int id; - const char *name; - ion_phys_addr_t base; - size_t size; - ion_phys_addr_t align; - void *priv; -}; - -/** - * struct ion_platform_data - array of platform heaps passed from board file - * @nr: number of structures in the array - * @heaps: array of platform_heap structions - * - * Provided by the board file in the form of platform data to a platform device. - */ -struct ion_platform_data { - int nr; - struct ion_platform_heap heaps[]; -}; - -/** - * ion_reserve() - reserve memory for ion heaps if applicable - * @data: platform data specifying starting physical address and - * size - * - * Calls memblock reserve to set aside memory for heaps that are - * located at specific memory addresses or of specfic sizes not - * managed by the kernel - */ -void ion_reserve(struct ion_platform_data *data); - -/** - * ion_client_create() - allocate a client and returns it - * @dev: the global ion device - * @heap_type_mask: mask of heaps this client can allocate from - * @name: used for debugging - */ -struct ion_client *ion_client_create(struct ion_device *dev, - const char *name); - -/** - * ion_client_destroy() - free's a client and all it's handles - * @client: the client - * - * Free the provided client and all it's resources including - * any handles it is holding. - */ -void ion_client_destroy(struct ion_client *client); - -/** - * ion_alloc - allocate ion memory - * @client: the client - * @len: size of the allocation - * @align: requested allocation alignment, lots of hardware blocks - * have alignment requirements of some kind - * @heap_id_mask: mask of heaps to allocate from, if multiple bits are set - * heaps will be tried in order from highest to lowest - * id - * @flags: heap flags, the low 16 bits are consumed by ion, the - * high 16 bits are passed on to the respective heap and - * can be heap custom - * - * Allocate memory in one of the heaps provided in heap mask and return - * an opaque handle to it. - */ -struct ion_handle *ion_alloc(struct ion_client *client, size_t len, - size_t align, unsigned int heap_id_mask, - unsigned int flags); - -/** - * ion_free - free a handle - * @client: the client - * @handle: the handle to free - * - * Free the provided handle. - */ -void ion_free(struct ion_client *client, struct ion_handle *handle); - -/** - * ion_phys - returns the physical address and len of a handle - * @client: the client - * @handle: the handle - * @addr: a pointer to put the address in - * @len: a pointer to put the length in - * - * This function queries the heap for a particular handle to get the - * handle's physical address. It't output is only correct if - * a heap returns physically contiguous memory -- in other cases - * this api should not be implemented -- ion_sg_table should be used - * instead. Returns -EINVAL if the handle is invalid. This has - * no implications on the reference counting of the handle -- - * the returned value may not be valid if the caller is not - * holding a reference. - */ -int ion_phys(struct ion_client *client, struct ion_handle *handle, - ion_phys_addr_t *addr, size_t *len); - -/** - * ion_map_dma - return an sg_table describing a handle - * @client: the client - * @handle: the handle - * - * This function returns the sg_table describing - * a particular ion handle. - */ -struct sg_table *ion_sg_table(struct ion_client *client, - struct ion_handle *handle); - -/** - * ion_map_kernel - create mapping for the given handle - * @client: the client - * @handle: handle to map - * - * Map the given handle into the kernel and return a kernel address that - * can be used to access this address. - */ -void *ion_map_kernel(struct ion_client *client, struct ion_handle *handle); - -/** - * ion_unmap_kernel() - destroy a kernel mapping for a handle - * @client: the client - * @handle: handle to unmap - */ -void ion_unmap_kernel(struct ion_client *client, struct ion_handle *handle); - -/** - * ion_share_dma_buf() - share buffer as dma-buf - * @client: the client - * @handle: the handle - */ -struct dma_buf *ion_share_dma_buf(struct ion_client *client, - struct ion_handle *handle); - -/** - * ion_share_dma_buf_fd() - given an ion client, create a dma-buf fd - * @client: the client - * @handle: the handle - */ -int ion_share_dma_buf_fd(struct ion_client *client, struct ion_handle *handle); - -/** - * ion_import_dma_buf() - given an dma-buf fd from the ion exporter get handle - * @client: the client - * @fd: the dma-buf fd - * - * Given an dma-buf fd that was allocated through ion via ion_share_dma_buf, - * import that fd and return a handle representing it. If a dma-buf from - * another exporter is passed in this function will return ERR_PTR(-EINVAL) - */ -struct ion_handle *ion_import_dma_buf(struct ion_client *client, int fd); - -#endif /* __KERNEL__ */ - -/** - * DOC: Ion Userspace API - * - * create a client by opening /dev/ion - * most operations handled via following ioctls - * - */ - -/** - * struct ion_allocation_data - metadata passed from userspace for allocations - * @len: size of the allocation - * @align: required alignment of the allocation - * @heap_id_mask: mask of heap ids to allocate from - * @flags: flags passed to heap - * @handle: pointer that will be populated with a cookie to use to - * refer to this allocation - * - * Provided by userspace as an argument to the ioctl - */ -struct ion_allocation_data { - size_t len; - size_t align; - unsigned int heap_id_mask; - unsigned int flags; - struct ion_handle *handle; -}; - -/** - * struct ion_fd_data - metadata passed to/from userspace for a handle/fd pair - * @handle: a handle - * @fd: a file descriptor representing that handle - * - * For ION_IOC_SHARE or ION_IOC_MAP userspace populates the handle field with - * the handle returned from ion alloc, and the kernel returns the file - * descriptor to share or map in the fd field. For ION_IOC_IMPORT, userspace - * provides the file descriptor and the kernel returns the handle. - */ -struct ion_fd_data { - struct ion_handle *handle; - int fd; -}; - -/** - * struct ion_handle_data - a handle passed to/from the kernel - * @handle: a handle - */ -struct ion_handle_data { - struct ion_handle *handle; -}; - -/** - * struct ion_custom_data - metadata passed to/from userspace for a custom ioctl - * @cmd: the custom ioctl function to call - * @arg: additional data to pass to the custom ioctl, typically a user - * pointer to a predefined structure - * - * This works just like the regular cmd and arg fields of an ioctl. - */ -struct ion_custom_data { - unsigned int cmd; - unsigned long arg; -}; - -#define ION_IOC_MAGIC 'I' - -/** - * DOC: ION_IOC_ALLOC - allocate memory - * - * Takes an ion_allocation_data struct and returns it with the handle field - * populated with the opaque handle for the allocation. - */ -#define ION_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, \ - struct ion_allocation_data) - -/** - * DOC: ION_IOC_FREE - free memory - * - * Takes an ion_handle_data struct and frees the handle. - */ -#define ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data) - -/** - * DOC: ION_IOC_MAP - get a file descriptor to mmap - * - * Takes an ion_fd_data struct with the handle field populated with a valid - * opaque handle. Returns the struct with the fd field set to a file - * descriptor open in the current address space. This file descriptor - * can then be used as an argument to mmap. - */ -#define ION_IOC_MAP _IOWR(ION_IOC_MAGIC, 2, struct ion_fd_data) - -/** - * DOC: ION_IOC_SHARE - creates a file descriptor to use to share an allocation - * - * Takes an ion_fd_data struct with the handle field populated with a valid - * opaque handle. Returns the struct with the fd field set to a file - * descriptor open in the current address space. This file descriptor - * can then be passed to another process. The corresponding opaque handle can - * be retrieved via ION_IOC_IMPORT. - */ -#define ION_IOC_SHARE _IOWR(ION_IOC_MAGIC, 4, struct ion_fd_data) - -/** - * DOC: ION_IOC_IMPORT - imports a shared file descriptor - * - * Takes an ion_fd_data struct with the fd field populated with a valid file - * descriptor obtained from ION_IOC_SHARE and returns the struct with the handle - * filed set to the corresponding opaque handle. - */ -#define ION_IOC_IMPORT _IOWR(ION_IOC_MAGIC, 5, struct ion_fd_data) - -/** - * DOC: ION_IOC_SYNC - syncs a shared file descriptors to memory - * - * Deprecated in favor of using the dma_buf api's correctly (syncing - * will happend automatically when the buffer is mapped to a device). - * If necessary should be used after touching a cached buffer from the cpu, - * this will make the buffer in memory coherent. - */ -#define ION_IOC_SYNC _IOWR(ION_IOC_MAGIC, 7, struct ion_fd_data) - -/** - * DOC: ION_IOC_CUSTOM - call architecture specific ion ioctl - * - * Takes the argument of the architecture specific ioctl to call and - * passes appropriate userdata for that ioctl - */ -#define ION_IOC_CUSTOM _IOWR(ION_IOC_MAGIC, 6, struct ion_custom_data) - -#endif /* _LINUX_ION_H */ diff --git a/workspace/_unmaintained/trimuismart/platform/ion_sunxi.h b/workspace/_unmaintained/trimuismart/platform/ion_sunxi.h deleted file mode 100755 index 424993768..000000000 --- a/workspace/_unmaintained/trimuismart/platform/ion_sunxi.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * include/linux/ion_sunxi.h - * - * Copyright(c) 2013-2015 Allwinnertech Co., Ltd. - * http://www.allwinnertech.com - * - * Author: liugang - * - * sunxi ion header file - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#ifndef __ION_SUNXI_H -#define __ION_SUNXI_H - -#define ION_HEAP_TYPE_SUNXI_START (ION_HEAP_TYPE_CUSTOM + 1) -#define ION_HEAP_TYPE_SECURE (ION_HEAP_TYPE_SUNXI_START) - -typedef struct { - long start; - long end; -}sunxi_cache_range; - -typedef struct { - void *handle; - unsigned int phys_addr; - unsigned int size; -}sunxi_phys_data; - - -#define DMA_BUF_MAXCNT 8 - -typedef struct { - unsigned int src_va; - unsigned int src_pa; - unsigned int dst_va; - unsigned int dst_pa; - unsigned int size; -}dma_buf_item; - -typedef struct { - bool multi_dma; - unsigned int cnt; - dma_buf_item item[DMA_BUF_MAXCNT]; -}dma_buf_group; - -#define ION_IOC_SUNXI_FLUSH_RANGE 5 -#define ION_IOC_SUNXI_FLUSH_ALL 6 -#define ION_IOC_SUNXI_PHYS_ADDR 7 -#define ION_IOC_SUNXI_DMA_COPY 8 -#define ION_IOC_SUNXI_DUMP 9 -#define ION_IOC_SUNXI_POOL_FREE 10 -int flush_clean_user_range(long start, long end); -int flush_user_range(long start, long end); -void flush_dcache_all(void); - -/** - * sunxi_buf_alloc - alloc phys contigous memory in SUNXI platform. - * @size: size in bytes to allocate. - * @paddr: store the start phys address allocated. - * - * return the start virtual address, or 0 if failed. - */ -void *sunxi_buf_alloc(unsigned int size, unsigned int *paddr); -/** - * sunxi_buf_free - free buffer allocated by sunxi_buf_alloc. - * @vaddr: the kernel virt addr of the area. - * @paddr: the start phys addr of the area. - * @size: size in bytes of the area. - */ -void sunxi_buf_free(void *vaddr, unsigned int paddr, unsigned int size); -/** - * sunxi_alloc_phys - alloc phys contigous memory in SUNXI platform. - * @size: size in bytes to allocate. - * - * return the start phys addr, or 0 if failed. - */ -u32 sunxi_alloc_phys(size_t size); -/** - * sunxi_free_phys - free phys contigous memory allocted by sunxi_alloc_phys. - * @paddr: the start phys addr of the area. - * @size: size in bytes of the area. - */ -void sunxi_free_phys(u32 paddr, size_t size); -/** - * sunxi_map_kernel - map phys contigous memory to kernel virtual space. - * @paddr: the start phys addr of the area. - * @size: size in bytes of the area. - * - * return the start virt addr which is in vmalloc space, or NULL if failed. - */ -void *sunxi_map_kernel(unsigned int paddr, unsigned int size); -/** - * sunxi_unmap_kernel - unmap phys contigous memory from kernel space. - * @vaddr: the kernel virt addr of the area. - * @paddr: the start phys addr of the area. - * @size: size in bytes of the area. - */ -void sunxi_unmap_kernel(void *vaddr, unsigned int paddr, unsigned int size); - -#endif diff --git a/workspace/_unmaintained/trimuismart/platform/makefile.copy b/workspace/_unmaintained/trimuismart/platform/makefile.copy deleted file mode 100644 index ac4a953b8..000000000 --- a/workspace/_unmaintained/trimuismart/platform/makefile.copy +++ /dev/null @@ -1,13 +0,0 @@ -$(PLATFORM): - # $@ - cp ./workspace/$@/show/show.elf ./build/SYSTEM/$@/bin - # installer - cp ./workspace/$@/install/boot.sh ./build/BOOT/common/$@.sh - mkdir -p ./build/BOOT/common/$@/ - cp ./workspace/$@/install/*.png ./build/BOOT/common/$@/ - cp ./workspace/$@/show/show.elf ./build/BOOT/common/$@/ - cp ./workspace/$@/other/unzip60/unzip ./build/BOOT/common/$@/ - cp ./build/SYSTEM/$@/bin/leds_off ./build/BOOT/common/$@/ - # extras - cp ./workspace/$@/other/DinguxCommander/output/DinguxCommander ./build/EXTRAS/Tools/$@/Files.pak/ - cp -r ./workspace/$@/other/DinguxCommander/res ./build/EXTRAS/Tools/$@/Files.pak/ diff --git a/workspace/_unmaintained/trimuismart/platform/makefile.env b/workspace/_unmaintained/trimuismart/platform/makefile.env deleted file mode 100644 index 6c189f6f1..000000000 --- a/workspace/_unmaintained/trimuismart/platform/makefile.env +++ /dev/null @@ -1,3 +0,0 @@ -# trimuismart -ARCH = -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 -LIBS = diff --git a/workspace/_unmaintained/trimuismart/platform/platform.c b/workspace/_unmaintained/trimuismart/platform/platform.c deleted file mode 100644 index e229bfc6a..000000000 --- a/workspace/_unmaintained/trimuismart/platform/platform.c +++ /dev/null @@ -1,538 +0,0 @@ -// trimuismart -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include "defines.h" -#include "platform.h" -#include "api.h" -#include "utils.h" - -#include "sunxi_display2.h" -#include "ion.h" -#include "ion_sunxi.h" -#include "scaler.h" - -/////////////////////////////// - -void PLAT_initInput(void) { - // buh -} -void PLAT_quitInput(void) { - // buh -} - -/////////////////////////////// -// 100% eggs - -#define FB_CH (0) -#define FB_LAYER (0) -#define FB_ZORDER (0) -#define SCALER_CH (1) -#define SCALER_LAYER (0) -#define SCALER_ZORDER (10) -#define OVERLAY_CH (2) -#define OVERLAY_LAYER (0) -#define OVERLAY_ZORDER (11) -#define DEF_FB_CH (2) -#define DEF_FB_LAYER (0) - -#define DE (0x01000000) -#define RT_MIXER0 (DE+0x00100000) -#define OVL_V (RT_MIXER0+0x2000+(SCALER_CH*0x1000)) -#define OVL_V_TOP_LADD0 (0x18+(SCALER_LAYER*0x30)) - -typedef struct ion_alloc_info { - uint32_t size; - struct ion_handle *handle; - int fd; - void* padd; - void* vadd; -} ion_alloc_info_t; - -// -// allocate ion memory -// input: info.size -// -void ion_alloc(int ion_fd, ion_alloc_info_t* info) { - struct ion_allocation_data iad; - struct ion_fd_data ifd; - struct ion_custom_data icd; - sunxi_phys_data spd; - - iad.len = info->size; - iad.align = sysconf(_SC_PAGESIZE); - iad.heap_id_mask = ION_HEAP_TYPE_DMA_MASK; - iad.flags = 0; - if (ioctl(ion_fd, ION_IOC_ALLOC, &iad)<0) fprintf(stderr, "ION_ALLOC failed %s\n",strerror(errno)); - icd.cmd = ION_IOC_SUNXI_PHYS_ADDR; - icd.arg = (uintptr_t)&spd; - spd.handle = iad.handle; - if (ioctl(ion_fd, ION_IOC_CUSTOM, &icd)<0) fprintf(stderr, "ION_GET_PHY failed %s\n",strerror(errno)); - ifd.handle = iad.handle; - if (ioctl(ion_fd, ION_IOC_MAP, &ifd)<0) fprintf(stderr, "ION_MAP failed %s\n",strerror(errno)); - - info->handle = iad.handle; - info->fd = ifd.fd; - info->padd = (void*)spd.phys_addr; - info->vadd = mmap(0, info->size, PROT_READ|PROT_WRITE, MAP_SHARED, info->fd, 0); - fprintf(stderr, "allocated padd: 0x%x vadd: 0x%x size: 0x%x\n", (uintptr_t)info->padd, (uintptr_t)info->vadd, info->size); -} - -// -// free ion memory -// -void ion_free(int ion_fd, ion_alloc_info_t* info) { - struct ion_handle_data ihd; - munmap(info->vadd, info->size); - close(info->fd); - ihd.handle = info->handle; - if (ioctl(ion_fd, ION_IOC_FREE, &ihd)<0) fprintf(stderr, "ION_FREE failed %s\n",strerror(errno)); -} - -void rotate_16bpp(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dp) { - uint16_t* s = (uint16_t*)src; - uint16_t* d = (uint16_t*)dst; - int spx = sp/FIXED_BPP; - int dpx = dp/FIXED_BPP; - - - for (int y=0; ypixels, 0, FIXED_SIZE); - - vid.disp_fd = open("/dev/disp", O_RDWR); - vid.fb_fd = open("/dev/fb0", O_RDWR); - vid.ion_fd = open("/dev/ion", O_RDWR); - vid.mem_fd = open("/dev/mem", O_RDWR); - vid.mem_map = mmap(0, sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, vid.mem_fd, OVL_V); - - memset(&vid.fb_config, 0, sizeof(disp_layer_config)); - memset(&vid.buffer_config, 0, sizeof(disp_layer_config)); - - // wait for vsync to avoid glitch - ioctl(vid.fb_fd, FBIO_WAITFORVSYNC, &_); - - // save and disable default FB layer first - uint32_t args[4] = {0, (uintptr_t)&vid.fb_config, 1, 0}; - vid.fb_config.channel = DEF_FB_CH; - vid.fb_config.layer_id = DEF_FB_LAYER; - ioctl(vid.disp_fd, DISP_LAYER_GET_CONFIG, args); - - vid.fb_config.enable = 0; - ioctl(vid.disp_fd, DISP_LAYER_SET_CONFIG, args); - - // intermediate buffer - vid.page = 1; - vid.width = FIXED_WIDTH; - vid.height = FIXED_HEIGHT; - vid.pitch = FIXED_PITCH; - - vid.screen_info.size = PAGE_SIZE; - ion_alloc(vid.ion_fd, &vid.screen_info); - vid.screen = SDL_CreateRGBSurfaceFrom(vid.screen_info.vadd, vid.width, vid.height, FIXED_DEPTH, vid.pitch, RGBA_MASK_565); - - // setup ch1 screen layer (RGB565, DOUBLEBUF) ch0/1 can use scaler, but cannot use alpha - vid.buffer_info.size = PAGE_SIZE * PAGE_COUNT; - ion_alloc(vid.ion_fd, &vid.buffer_info); - - vid.buffer = SDL_CreateRGBSurfaceFrom(vid.buffer_info.vadd + vid.page * PAGE_SIZE, PAGE_HEIGHT, PAGE_WIDTH, FIXED_DEPTH, PAGE_HEIGHT*FIXED_BPP, RGBA_MASK_565); - vid.buffer_config.channel = SCALER_CH; - vid.buffer_config.layer_id = SCALER_LAYER; - vid.buffer_config.enable = 1; - vid.buffer_config.info.fb.format = DISP_FORMAT_RGB_565; - vid.buffer_config.info.fb.addr[0] = (uintptr_t)vid.buffer_info.padd; - vid.buffer_config.info.fb.size[0].width = vid.height; // PAGE_HEIGHT; - vid.buffer_config.info.fb.size[0].height = vid.width; // PAGE_WIDTH; - vid.buffer_config.info.mode = LAYER_MODE_BUFFER; - vid.buffer_config.info.zorder = SCALER_ZORDER; - vid.buffer_config.info.alpha_mode = 0; //0: pixel alpha; 1: global alpha; 2: global pixel alpha - vid.buffer_config.info.alpha_value = 0; - vid.buffer_config.info.screen_win.x = 0; - vid.buffer_config.info.screen_win.y = 0; - vid.buffer_config.info.screen_win.width = vid.height; - vid.buffer_config.info.screen_win.height = vid.width; - vid.buffer_config.info.fb.pre_multiply = 0; - vid.buffer_config.info.fb.crop.x = (int64_t)0 << 32; - vid.buffer_config.info.fb.crop.y = (int64_t)0 << 32; - vid.buffer_config.info.fb.crop.width = (int64_t)vid.height << 32; - vid.buffer_config.info.fb.crop.height = (int64_t)vid.width << 32; - - args[1] = (uintptr_t)&vid.buffer_config; - ioctl(vid.disp_fd, DISP_LAYER_SET_CONFIG, args); - - // lotta waiting for vsync... - ioctl(vid.fb_fd, FBIO_WAITFORVSYNC, &_); - // return vid.buffer; - - // trimui's SDL pukes so much debug info - puts("--------------------------------"); fflush(stdout); - - return vid.screen; -} - -void PLAT_quitVideo(void) { - puts("--------------------------------"); fflush(stdout); - - ADC_quit(); - - ioctl(vid.fb_fd, FBIO_WAITFORVSYNC, &_); - - memset(vid.video->pixels, 0, FIXED_SIZE); - - SDL_FreeSurface(vid.screen); - SDL_FreeSurface(vid.buffer); - - // disable all channels & revert FB channel - vid.fb_config.enable = vid.buffer_config.enable = 0; - uint32_t args[4] = {0, (uintptr_t)&vid.fb_config, 1, 0}; - ioctl(vid.disp_fd, DISP_LAYER_SET_CONFIG, args); - - args[1] = (uintptr_t)&vid.buffer_config; - ioctl(vid.disp_fd, DISP_LAYER_SET_CONFIG, args); - - vid.fb_config.enable = 1; - vid.fb_config.channel = DEF_FB_CH; - vid.fb_config.layer_id = DEF_FB_LAYER; - args[1] = (uintptr_t)&vid.fb_config; - ioctl(vid.disp_fd, DISP_LAYER_SET_CONFIG, args); - - // free & unmap & close - ion_free(vid.ion_fd, &vid.buffer_info); - munmap(vid.mem_map, sysconf(_SC_PAGESIZE)); - close(vid.mem_fd); - close(vid.ion_fd); - close(vid.fb_fd); - close(vid.disp_fd); - - SDL_Quit(); -} - -void PLAT_clearVideo(SDL_Surface* IGNORED) { - if (!vid.cleared) memset(vid.screen->pixels, 0, vid.pitch * vid.height); - memset(vid.buffer->pixels, 0, PAGE_SIZE); -} -void PLAT_clearAll(void) { - vid.cleared = 1; - PLAT_clearVideo(vid.buffer); // clear backbuffer -} - -void PLAT_setVsync(int vsync) { - // buh -} - -SDL_Surface* PLAT_resizeVideo(int w, int h, int pitch) { - - SDL_FreeSurface(vid.screen); - vid.width = w; - vid.height = h; - vid.pitch = pitch; - - vid.screen = SDL_CreateRGBSurfaceFrom(vid.screen_info.vadd, vid.width, vid.height, FIXED_DEPTH, vid.pitch, RGBA_MASK_565); - memset(vid.screen->pixels, 0, vid.pitch * vid.height); - - vid.resized = 1; - - vid.rotated_pitch = 0; - if (vid.renderer) vid.renderer->src_w = 0; - return vid.screen; -} - -void PLAT_setVideoScaleClip(int x, int y, int width, int height) { - // buh -} -void PLAT_setNearestNeighbor(int enabled) { - // buh -} -void PLAT_setSharpness(int sharpness) { - // buh -} -void PLAT_setEffect(int effect) { - // buh -} -void PLAT_vsync(int remaining) { - ioctl(vid.fb_fd, FBIO_WAITFORVSYNC, &_); -} - -scaler_t PLAT_getScaler(GFX_Renderer* renderer) { - switch (renderer->scale) { - case 6: return scale6x6_n16; - case 5: return scale5x5_n16; - case 4: return scale4x4_n16; - case 3: return scale3x3_n16; - case 2: return scale2x2_n16; - default: return scale1x1_n16; - } -} - -void PLAT_blitRenderer(GFX_Renderer* renderer) { - vid.renderer = renderer; - int p = ((renderer->src_h+7)/8)*8 * FIXED_BPP; - if (!vid.special || vid.special->w!=renderer->src_h || vid.special->h!=renderer->src_w || vid.special->pitch!=p || !vid.rotated_pitch) { - // LOG_info("!special:%i sp_w!=src_h:%i sp_h!=src_w:%i sp_p!=src_h*FIXED_BPP:%i !rot_p: %i\n", - // !vid.special, vid.special && vid.special->w!=renderer->src_h, vid.special && vid.special->h!=renderer->src_w, vid.special && vid.special->pitch!=p, !vid.rotated_pitch); - - if (vid.special) SDL_FreeSurface(vid.special); - - vid.special = SDL_CreateRGBSurface(SDL_SWSURFACE, renderer->src_h,renderer->src_w, FIXED_DEPTH,RGBA_MASK_565); - vid.rotated_pitch = vid.height * FIXED_BPP; // ((vid.height+7)/8)*8 * FIXED_BPP; // TODO: this should be the fix but it's not :sob: - vid.rotated_offset = (renderer->dst_x * vid.rotated_pitch) + (renderer->dst_y * FIXED_BPP); - vid.source_offset = (renderer->src_x * vid.special->pitch) + (renderer->src_y * FIXED_BPP); - - LOG_info("PLAT_blitRenderer >> src:%p dst:%p blit:%p src:%ix%i (%i) dst:%i,%i %ix%i (%i) vid: %ix%i (%i) (%i)\n", - vid.renderer->src, - vid.renderer->dst, // unused - vid.renderer->blit, - - vid.renderer->src_w, - vid.renderer->src_h, - vid.renderer->src_p, // unused - - vid.renderer->dst_x, - vid.renderer->dst_y, - vid.renderer->dst_w, // unused - vid.renderer->dst_h, // unused? - vid.renderer->dst_p, // unused - - vid.width, - vid.height, - vid.pitch, - vid.rotated_pitch - ); - } - rotate_16bpp(renderer->src, vid.special->pixels, renderer->src_w,renderer->src_h,renderer->src_p,vid.special->pitch); - ((scaler_t)renderer->blit)(vid.special->pixels + vid.source_offset, vid.buffer->pixels+vid.rotated_offset, vid.special->w,vid.special->h, vid.special->pitch, vid.renderer->dst_h, vid.renderer->dst_w,vid.rotated_pitch); - - // LOG_info("blit(%p,%p, %i,%i,%i, %i,%i,%i)\n", vid.special->pixels, vid.buffer->pixels+vid.rotated_offset, vid.special->w,vid.special->h, vid.special->pitch, vid.renderer->dst_h, vid.renderer->dst_w,vid.rotated_pitch); -} - -void PLAT_flip(SDL_Surface* IGNORED, int sync) { - if (!vid.renderer) rotate_16bpp(vid.screen->pixels, vid.buffer->pixels, vid.width, vid.height,vid.pitch,vid.height*FIXED_BPP); - - vid.buffer_config.info.fb.addr[0] = (uintptr_t)vid.buffer_info.padd + vid.page * PAGE_SIZE; - vid.mem_map[OVL_V_TOP_LADD0/4] = (uintptr_t)vid.buffer_info.padd + vid.page * PAGE_SIZE; - - if (vid.resized) { - vid.buffer_config.info.fb.size[0].width = vid.height; - vid.buffer_config.info.fb.size[0].height = vid.width; - vid.buffer_config.info.fb.crop.width = (int64_t)vid.height << 32; - vid.buffer_config.info.fb.crop.height = (int64_t)vid.width << 32; - uint32_t args[4] = {0, (uintptr_t)&vid.buffer_config, 1, 0}; - ioctl(vid.disp_fd, DISP_LAYER_SET_CONFIG, args); - vid.resized = 0; - } - - vid.page ^= 1; - vid.buffer->pixels = vid.buffer_info.vadd + vid.page * PAGE_SIZE; - - if (sync) PLAT_vsync(0); - - if (vid.cleared) { - PLAT_clearVideo(vid.buffer); - vid.cleared = 0; - } - - vid.renderer = NULL; -} - -/////////////////////////////// - -// TODO: -#define OVERLAY_WIDTH PILL_SIZE // unscaled -#define OVERLAY_HEIGHT PILL_SIZE // unscaled -#define OVERLAY_BPP 4 -#define OVERLAY_DEPTH 16 -#define OVERLAY_PITCH (OVERLAY_WIDTH * OVERLAY_BPP) // unscaled -#define OVERLAY_RGBA_MASK 0x00ff0000,0x0000ff00,0x000000ff,0xff000000 // ARGB -static struct OVL_Context { - SDL_Surface* overlay; -} ovl; - -SDL_Surface* PLAT_initOverlay(void) { - // setup surface - ovl.overlay = SDL_CreateRGBSurface(SDL_SWSURFACE, SCALE2(OVERLAY_WIDTH,OVERLAY_HEIGHT),OVERLAY_DEPTH,OVERLAY_RGBA_MASK); - return ovl.overlay; -} -void PLAT_quitOverlay(void) { - if (ovl.overlay) SDL_FreeSurface(ovl.overlay); -} -void PLAT_enableOverlay(int enable) { - -} - -/////////////////////////////// - -#define LRADC 0x01C22800 -#define LRADC_VALUE 0x10 -static struct ADC_Context { - int mem_fd; - int page_size; - void* mem_map; - void* adc_addr; -} adc; - -void ADC_init(void) { - adc.page_size = sysconf(_SC_PAGESIZE); - int page_mask = (~(adc.page_size - 1)); - int addr_start = LRADC & page_mask; - int addr_offset = LRADC & ~page_mask; - - adc.mem_fd = open("/dev/mem",O_RDWR); - adc.mem_map = mmap(0, adc.page_size*2, PROT_READ|PROT_WRITE, MAP_SHARED, adc.mem_fd, addr_start); - adc.adc_addr = adc.mem_map + addr_offset; - *(uint32_t*)adc.adc_addr = 0xC0004D; -} -int ADC_read(void) { - return *((uint32_t *)(adc.adc_addr + LRADC_VALUE)); -} -void ADC_quit(void) { - munmap(adc.mem_map, adc.page_size*2); - close(adc.mem_fd); -} - -/////////////////////////////// - -#define USB_SPEED "/sys/devices/platform/sunxi_usb_udc/udc/sunxi_usb_udc/current_speed" -void PLAT_getBatteryStatus(int* is_charging, int* charge) { - PLAT_getBatteryStatusFine(is_charging, charge); -} - -void PLAT_getBatteryStatusFine(int* is_charging, int* charge) -{ - // *is_charging = 0; - // *charge = PWR_LOW_CHARGE; - // return; - - char value[16]; memset(value, 0, 16); - getFile(USB_SPEED, value, 16); - *is_charging = !exactMatch(value, "UNKNOWN\n"); - - int i = ADC_read(); - // worry less about battery and more about the game you're playing - if (i>43) *charge = 100; - else if (i>41) *charge = 80; - else if (i>40) *charge = 60; - else if (i>39) *charge = 40; - else if (i>38) *charge = 20; - else *charge = 10; -} - -void PLAT_enableBacklight(int enable) { - if (enable) { - // TODO: restore screen - SetBrightness(GetBrightness()); - system("leds_off"); - } - else { - // TODO: copy screen - // TODO: clear screen - SetRawBrightness(0); - system("leds_on"); - } -} - -void PLAT_powerOff(void) { - system("leds_on"); - sleep(2); - - SetRawVolume(MUTE_VOLUME_RAW); - PLAT_enableBacklight(0); - SND_quit(); - VIB_quit(); - PWR_quit(); - GFX_quit(); - - touch("/tmp/poweroff"); - exit(0); -} - -/////////////////////////////// - -#define GOVERNOR_PATH "/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed" -void PLAT_setCPUSpeed(int speed) { - int freq = 0; - switch (speed) { - case CPU_SPEED_MENU: freq = 504000; break; - case CPU_SPEED_POWERSAVE: freq = 1104000; break; - case CPU_SPEED_NORMAL: freq = 1344000; break; - case CPU_SPEED_PERFORMANCE: freq = 1536000; break; - } - - char cmd[256]; - sprintf(cmd,"echo %i > %s", freq, GOVERNOR_PATH); - system(cmd); -} - -void PLAT_setRumble(int strength) { - // buh -} - -int PLAT_pickSampleRate(int requested, int max) { - return MIN(requested, max); -} - -char* PLAT_getModel(void) { - return "Trimui Smart"; -} - -int PLAT_isOnline(void) { - return 0; -} \ No newline at end of file diff --git a/workspace/_unmaintained/trimuismart/platform/platform.h b/workspace/_unmaintained/trimuismart/platform/platform.h deleted file mode 100644 index b34de195e..000000000 --- a/workspace/_unmaintained/trimuismart/platform/platform.h +++ /dev/null @@ -1,122 +0,0 @@ -// trimuismart - -#ifndef PLATFORM_H -#define PLATFORM_H - -/////////////////////////////// - -#include "sdl.h" - -/////////////////////////////// - -#define BUTTON_UP SDLK_UP -#define BUTTON_DOWN SDLK_DOWN -#define BUTTON_LEFT SDLK_LEFT -#define BUTTON_RIGHT SDLK_RIGHT - -#define BUTTON_SELECT SDLK_RCTRL -#define BUTTON_START SDLK_RETURN - -#define BUTTON_A SDLK_SPACE -#define BUTTON_B SDLK_LCTRL -#define BUTTON_X SDLK_LSHIFT -#define BUTTON_Y SDLK_LALT - -#define BUTTON_L1 SDLK_TAB -#define BUTTON_R1 SDLK_BACKSPACE -#define BUTTON_L2 BUTTON_NA -#define BUTTON_R2 BUTTON_NA -#define BUTTON_L3 BUTTON_NA -#define BUTTON_R3 BUTTON_NA - -#define BUTTON_MENU SDLK_ESCAPE -#define BUTTON_POWER BUTTON_NA -#define BUTTON_PLUS BUTTON_NA -#define BUTTON_MINUS BUTTON_NA - -/////////////////////////////// - -#define CODE_UP 103 -#define CODE_DOWN 108 -#define CODE_LEFT 105 -#define CODE_RIGHT 106 - -#define CODE_SELECT 97 -#define CODE_START 28 - -#define CODE_A 57 -#define CODE_B 29 -#define CODE_X 42 -#define CODE_Y 56 - -#define CODE_L1 15 -#define CODE_R1 14 -#define CODE_L2 CODE_NA -#define CODE_R2 CODE_NA -#define CODE_L3 CODE_NA -#define CODE_R3 CODE_NA - -#define CODE_MENU 1 -#define CODE_POWER CODE_NA - -#define CODE_PLUS CODE_NA -#define CODE_MINUS CODE_NA - -/////////////////////////////// - -#define JOY_UP JOY_NA -#define JOY_DOWN JOY_NA -#define JOY_LEFT JOY_NA -#define JOY_RIGHT JOY_NA - -#define JOY_SELECT JOY_NA -#define JOY_START JOY_NA - -#define JOY_A JOY_NA -#define JOY_B JOY_NA -#define JOY_X JOY_NA -#define JOY_Y JOY_NA - -#define JOY_L1 JOY_NA -#define JOY_R1 JOY_NA -#define JOY_L2 JOY_NA -#define JOY_R2 JOY_NA -#define JOY_L3 JOY_NA -#define JOY_R3 JOY_NA - -#define JOY_MENU JOY_NA -#define JOY_POWER JOY_NA -#define JOY_PLUS JOY_NA -#define JOY_MINUS JOY_NA - -/////////////////////////////// - -#define BTN_RESUME BTN_X -#define BTN_SLEEP BTN_MENU -#define BTN_WAKE BTN_MENU -#define BTN_MOD_VOLUME BTN_SELECT -#define BTN_MOD_BRIGHTNESS BTN_START -#define BTN_MOD_PLUS BTN_R1 -#define BTN_MOD_MINUS BTN_L1 - -/////////////////////////////// - -#define FIXED_SCALE 1 -#define FIXED_WIDTH 320 -#define FIXED_HEIGHT 240 -#define FIXED_BPP 2 -#define FIXED_DEPTH (FIXED_BPP * 8) -#define FIXED_PITCH (FIXED_WIDTH * FIXED_BPP) -#define FIXED_SIZE (FIXED_PITCH * FIXED_HEIGHT) - -/////////////////////////////// - -#define SDCARD_PATH "/mnt/SDCARD" -#define MUTE_VOLUME_RAW 0 -#define HAS_NEON - -// this should be set to the devices native screen refresh rate -#define SCREEN_FPS 60.0 -/////////////////////////////// - -#endif diff --git a/workspace/_unmaintained/trimuismart/platform/sunxi_display2.h b/workspace/_unmaintained/trimuismart/platform/sunxi_display2.h deleted file mode 100755 index efb7f186a..000000000 --- a/workspace/_unmaintained/trimuismart/platform/sunxi_display2.h +++ /dev/null @@ -1,521 +0,0 @@ -#ifndef __SUNXI_DISPLAY_H__ -#define __SUNXI_DISPLAY_H__ - -typedef int bool; -typedef unsigned int u32; - -struct disp_manager; -struct disp_device; -struct disp_smbl; -struct disp_enhance; -struct disp_capture; - -typedef struct {unsigned char alpha;unsigned char red;unsigned char green; unsigned char blue; }disp_color; -typedef struct {int x; int y; unsigned int width; unsigned int height;}disp_rect; -typedef struct {unsigned int width;unsigned int height; }disp_rectsz; -typedef struct {int x; int y; }disp_position; - -typedef enum -{ - DISP_FORMAT_ARGB_8888 = 0x00,//MSB A-R-G-B LSB - DISP_FORMAT_ABGR_8888 = 0x01, - DISP_FORMAT_RGBA_8888 = 0x02, - DISP_FORMAT_BGRA_8888 = 0x03, - DISP_FORMAT_XRGB_8888 = 0x04, - DISP_FORMAT_XBGR_8888 = 0x05, - DISP_FORMAT_RGBX_8888 = 0x06, - DISP_FORMAT_BGRX_8888 = 0x07, - DISP_FORMAT_RGB_888 = 0x08, - DISP_FORMAT_BGR_888 = 0x09, - DISP_FORMAT_RGB_565 = 0x0a, - DISP_FORMAT_BGR_565 = 0x0b, - DISP_FORMAT_ARGB_4444 = 0x0c, - DISP_FORMAT_ABGR_4444 = 0x0d, - DISP_FORMAT_RGBA_4444 = 0x0e, - DISP_FORMAT_BGRA_4444 = 0x0f, - DISP_FORMAT_ARGB_1555 = 0x10, - DISP_FORMAT_ABGR_1555 = 0x11, - DISP_FORMAT_RGBA_5551 = 0x12, - DISP_FORMAT_BGRA_5551 = 0x13, - - /* SP: semi-planar, P:planar, I:interleaved - * UVUV: U in the LSBs; VUVU: V in the LSBs */ - DISP_FORMAT_YUV444_I_AYUV = 0x40,//MSB A-Y-U-V LSB, reserved - DISP_FORMAT_YUV444_I_VUYA = 0x41,//MSB V-U-Y-A LSB - DISP_FORMAT_YUV422_I_YVYU = 0x42,//MSB Y-V-Y-U LSB - DISP_FORMAT_YUV422_I_YUYV = 0x43,//MSB Y-U-Y-V LSB - DISP_FORMAT_YUV422_I_UYVY = 0x44,//MSB U-Y-V-Y LSB - DISP_FORMAT_YUV422_I_VYUY = 0x45,//MSB V-Y-U-Y LSB - DISP_FORMAT_YUV444_P = 0x46,//MSB P3-2-1-0 LSB, YYYY UUUU VVVV, reserved - DISP_FORMAT_YUV422_P = 0x47,//MSB P3-2-1-0 LSB YYYY UU VV - DISP_FORMAT_YUV420_P = 0x48,//MSB P3-2-1-0 LSB YYYY U V - DISP_FORMAT_YUV411_P = 0x49,//MSB P3-2-1-0 LSB YYYY U V - DISP_FORMAT_YUV422_SP_UVUV = 0x4a,//MSB V-U-V-U LSB - DISP_FORMAT_YUV422_SP_VUVU = 0x4b,//MSB U-V-U-V LSB - DISP_FORMAT_YUV420_SP_UVUV = 0x4c, - DISP_FORMAT_YUV420_SP_VUVU = 0x4d, - DISP_FORMAT_YUV411_SP_UVUV = 0x4e, - DISP_FORMAT_YUV411_SP_VUVU = 0x4f, -}disp_pixel_format; - -typedef enum -{ - DISP_3D_OUT_MODE_CI_1 = 0x5,//column interlaved 1 - DISP_3D_OUT_MODE_CI_2 = 0x6,//column interlaved 2 - DISP_3D_OUT_MODE_CI_3 = 0x7,//column interlaved 3 - DISP_3D_OUT_MODE_CI_4 = 0x8,//column interlaved 4 - DISP_3D_OUT_MODE_LIRGB = 0x9,//line interleaved rgb - - DISP_3D_OUT_MODE_TB = 0x0,//top bottom - DISP_3D_OUT_MODE_FP = 0x1,//frame packing - DISP_3D_OUT_MODE_SSF = 0x2,//side by side full - DISP_3D_OUT_MODE_SSH = 0x3,//side by side half - DISP_3D_OUT_MODE_LI = 0x4,//line interleaved - DISP_3D_OUT_MODE_FA = 0xa,//field alternative -}disp_3d_out_mode; - -typedef enum -{ - DISP_BT601 = 0, - DISP_BT709 = 1, - DISP_YCC = 2, -}disp_color_space; - -typedef enum -{ - DISP_CSC_TYPE_RGB = 0, - DISP_CSC_TYPE_YUV1 = 1,//HDMI - DISP_CSC_TYPE_YUV2 = 2,//TV -}disp_csc_type; - -typedef enum -{ - DISP_COLOR_RANGE_16_255 = 0, - DISP_COLOR_RANGE_0_255 = 1, - DISP_COLOR_RANGE_16_235 = 2, -}disp_color_range; - -typedef enum -{ - DISP_OUTPUT_TYPE_NONE = 0, - DISP_OUTPUT_TYPE_LCD = 1, - DISP_OUTPUT_TYPE_TV = 2, - DISP_OUTPUT_TYPE_HDMI = 4, - DISP_OUTPUT_TYPE_VGA = 8, -}disp_output_type; - -typedef enum -{ - DISP_TV_MOD_480I = 0, - DISP_TV_MOD_576I = 1, - DISP_TV_MOD_480P = 2, - DISP_TV_MOD_576P = 3, - DISP_TV_MOD_720P_50HZ = 4, - DISP_TV_MOD_720P_60HZ = 5, - DISP_TV_MOD_1080I_50HZ = 6, - DISP_TV_MOD_1080I_60HZ = 7, - DISP_TV_MOD_1080P_24HZ = 8, - DISP_TV_MOD_1080P_50HZ = 9, - DISP_TV_MOD_1080P_60HZ = 0xa, - DISP_TV_MOD_1080P_24HZ_3D_FP = 0x17, - DISP_TV_MOD_720P_50HZ_3D_FP = 0x18, - DISP_TV_MOD_720P_60HZ_3D_FP = 0x19, - DISP_TV_MOD_1080P_25HZ = 0x1a, - DISP_TV_MOD_1080P_30HZ = 0x1b, - DISP_TV_MOD_PAL = 0xb, - DISP_TV_MOD_PAL_SVIDEO = 0xc, - DISP_TV_MOD_NTSC = 0xe, - DISP_TV_MOD_NTSC_SVIDEO = 0xf, - DISP_TV_MOD_PAL_M = 0x11, - DISP_TV_MOD_PAL_M_SVIDEO = 0x12, - DISP_TV_MOD_PAL_NC = 0x14, - DISP_TV_MOD_PAL_NC_SVIDEO = 0x15, - DISP_TV_MOD_3840_2160P_30HZ = 0x1c, - DISP_TV_MOD_3840_2160P_25HZ = 0x1d, - DISP_TV_MOD_3840_2160P_24HZ = 0x1e, - DISP_TV_MODE_NUM = 0x1f, -}disp_tv_mode; - - -//FIXME:still need? -typedef enum -{ - DISP_EXIT_MODE_CLEAN_ALL = 0, - DISP_EXIT_MODE_CLEAN_PARTLY = 1,//only clean interrupt temply -}disp_exit_mode; - -typedef enum -{ - DISP_BF_NORMAL = 0,//non-stereo - DISP_BF_STEREO_TB = 1 << 0,//stereo top-bottom - DISP_BF_STEREO_FP = 1 << 1,//stereo frame packing - DISP_BF_STEREO_SSH = 1 << 2,//stereo side by side half - DISP_BF_STEREO_SSF = 1 << 3,//stereo side by side full - DISP_BF_STEREO_LI = 1 << 4,//stereo line interlace -}disp_buffer_flags; - -typedef enum -{ - LAYER_MODE_BUFFER = 0, - LAYER_MODE_COLOR = 1, -}disp_layer_mode; - -typedef enum -{ - DISP_SCAN_PROGRESSIVE = 0,//non interlace - DISP_SCAN_INTERLACED_ODD_FLD_FIRST = 1 << 0,//interlace ,odd field first - DISP_SCAN_INTERLACED_EVEN_FLD_FIRST = 1 << 1,//interlace,even field first -}disp_scan_flags; - -typedef struct -{ - unsigned int type; - unsigned int mode; -}disp_output; - -typedef struct -{ - long long x; - long long y; - long long width; - long long height; -}disp_rect64; - -typedef struct -{ - unsigned long long addr[3]; /* address of frame buffer, - single addr for interleaved fomart, - double addr for semi-planar fomart - triple addr for planar format */ - disp_rectsz size[3]; //size for 3 component,unit: pixels - unsigned int align[3]; //align for 3 comonent,unit: bytes(align=2^n,i.e. 1/2/4/8/16/32..) - disp_pixel_format format; - disp_color_space color_space; //color space - unsigned int trd_right_addr[3];/* right address of 3d fb, - used when in frame packing 3d mode */ - bool pre_multiply; //true: pre-multiply fb - disp_rect64 crop; //crop rectangle boundaries - disp_buffer_flags flags; //indicate stereo or non-stereo buffer - disp_scan_flags scan; //scan type & scan order -}disp_fb_info; - -typedef struct -{ - disp_layer_mode mode; - unsigned char zorder; /*specifies the front-to-back ordering of the layers on the screen, - the top layer having the highest Z value - can't set zorder, but can get */ - unsigned char alpha_mode; //0: pixel alpha; 1: global alpha; 2: global pixel alpha - unsigned char alpha_value; //global alpha value - disp_rect screen_win; //display window on the screen - bool b_trd_out; //3d display - disp_3d_out_mode out_trd_mode;//3d display mode - union { - unsigned int color; //valid when LAYER_MODE_COLOR - disp_fb_info fb; //framebuffer, valid when LAYER_MODE_BUFFER - }; - - unsigned int id; /* frame id, can get the id of frame display currently - by DISP_LAYER_GET_FRAME_ID */ -}disp_layer_info; - -typedef struct -{ - disp_layer_info info; - bool enable; - unsigned int channel; - unsigned int layer_id; -}disp_layer_config; - -typedef struct -{ - disp_color ck_max; - disp_color ck_min; - unsigned int red_match_rule;//0/1:always match; 2:match if min<=color<=max; 3:match if color>max or colormax or colormax or color -#include - -#include -#include -#include -#include -#include - -// TODO: revisit - -int main(int argc , char* argv[]) { - if (argc<2) { - puts("Usage: show.elf image.png"); - return 0; - } - - char path[256]; - if (strchr(argv[1], '/')==NULL) sprintf(path, "/mnt/SDCARD/.system/res/%s", argv[1]); - else strncpy(path,argv[1],256); - - if (access(path, F_OK)!=0) return 0; // nothing to show :( - - putenv("SDL_VIDEO_FBCON_ROTATION=CCW"); - SDL_Init(SDL_INIT_VIDEO); - SDL_ShowCursor(0); - - SDL_Surface *screen = SDL_SetVideoMode(320,240,16,SDL_SWSURFACE); - SDL_Surface* img = IMG_Load(path); // 24-bit opaque png - if (img==NULL) puts(IMG_GetError()); - SDL_BlitSurface(img, NULL, screen, NULL); - SDL_Flip(screen); - - SDL_FreeSurface(img); - IMG_Quit(); - SDL_Quit(); - return EXIT_SUCCESS; -} diff --git a/workspace/_unmaintained/zero28/bl/bl_disable.c b/workspace/_unmaintained/zero28/bl/bl_disable.c deleted file mode 100644 index e4f8103a6..000000000 --- a/workspace/_unmaintained/zero28/bl/bl_disable.c +++ /dev/null @@ -1,16 +0,0 @@ -#include -#include -#include -#include -#include - -#define DISP_LCD_BACKLIGHT_DISABLE 0x105 -int main (int argc, char *argv[]) { - int fd = open("/dev/disp", O_RDWR); - if (fd) { - int _; - ioctl(fd, DISP_LCD_BACKLIGHT_DISABLE, &_); - close(fd); - } - return 0; -} diff --git a/workspace/_unmaintained/zero28/bl/bl_enable.c b/workspace/_unmaintained/zero28/bl/bl_enable.c deleted file mode 100644 index 11e0d87d9..000000000 --- a/workspace/_unmaintained/zero28/bl/bl_enable.c +++ /dev/null @@ -1,16 +0,0 @@ -#include -#include -#include -#include -#include - -#define DISP_LCD_BACKLIGHT_ENABLE 0x104 -int main (int argc, char *argv[]) { - int fd = open("/dev/disp", O_RDWR); - if (fd) { - int _; - ioctl(fd, DISP_LCD_BACKLIGHT_ENABLE, &_); - close(fd); - } - return 0; -} diff --git a/workspace/_unmaintained/zero28/bl/makefile b/workspace/_unmaintained/zero28/bl/makefile deleted file mode 100755 index ec4672943..000000000 --- a/workspace/_unmaintained/zero28/bl/makefile +++ /dev/null @@ -1,15 +0,0 @@ -#keymon - -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif - -CC = $(CROSS_COMPILE)gcc -CFLAGS = -Os -lrt -ldl -Wl,--gc-sections -s -CFLAGS += -I. - -all: - $(CC) bl_enable.c -o bl_enable $(CFLAGS) - $(CC) bl_disable.c -o bl_disable $(CFLAGS) -clean: - rm -rf bl_enable bl_disable \ No newline at end of file diff --git a/workspace/_unmaintained/zero28/cores/makefile b/workspace/_unmaintained/zero28/cores/makefile deleted file mode 100644 index 9f99f4a3b..000000000 --- a/workspace/_unmaintained/zero28/cores/makefile +++ /dev/null @@ -1,4 +0,0 @@ -all: - # copy from trimui smart pro (for now?) - rm -rf output - cp -r ../../tg5040/cores/output ./ \ No newline at end of file diff --git a/workspace/_unmaintained/zero28/install/boot.sh b/workspace/_unmaintained/zero28/install/boot.sh deleted file mode 100755 index 377703c09..000000000 --- a/workspace/_unmaintained/zero28/install/boot.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh -# NOTE: becomes .tmp_update/zero28.sh - -PLATFORM="zero28" -SDCARD_PATH="/mnt/SDCARD" -UPDATE_PATH="$SDCARD_PATH/NextUI.zip" -SYSTEM_PATH="$SDCARD_PATH/.system" - -CPU_PATH=/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor -echo performance > "$CPU_PATH" - -# install/update -if [ -f "$UPDATE_PATH" ]; then - cd $(dirname "$0")/$PLATFORM - - if [ -d "$SYSTEM_PATH" ]; then - ./show.elf ./updating.png - else - ./show.elf ./installing.png - fi - - mv $SDCARD_PATH/.tmp_update $SDCARD_PATH/.tmp_update-old - unzip -o "$UPDATE_PATH" -d "$SDCARD_PATH" - rm -f "$UPDATE_PATH" - rm -rf $SDCARD_PATH/.tmp_update-old - - # the updated system finishes the install/update - $SYSTEM_PATH/$PLATFORM/bin/install.sh -fi - -# or launch (and keep launched) -LAUNCH_PATH="$SYSTEM_PATH/$PLATFORM/paks/NextUI.pak/launch.sh" -while [ -f "$LAUNCH_PATH" ] ; do - "$LAUNCH_PATH" -done - -poweroff # under no circumstances should stock be allowed to touch this card diff --git a/workspace/_unmaintained/zero28/install/installing.png b/workspace/_unmaintained/zero28/install/installing.png deleted file mode 100644 index acde62551b3bffd9c192883ec06bb5ba0d6efc76..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3647 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 B=!^gW diff --git a/workspace/_unmaintained/zero28/keymon/credits.txt b/workspace/_unmaintained/zero28/keymon/credits.txt deleted file mode 100644 index e885e5dd1..000000000 --- a/workspace/_unmaintained/zero28/keymon/credits.txt +++ /dev/null @@ -1,3 +0,0 @@ -based on eggs custom keymon for Trimui: - https://www.dropbox.com/sh/5e9xwvp672vt8cr/AABUIdw1vLYp9h0waoCUqHPOa/source?dl=0&subfolder_nav_tracking=1 -modified to use libmsettings \ No newline at end of file diff --git a/workspace/_unmaintained/zero28/keymon/keymon.c b/workspace/_unmaintained/zero28/keymon/keymon.c deleted file mode 100644 index 12a993250..000000000 --- a/workspace/_unmaintained/zero28/keymon/keymon.c +++ /dev/null @@ -1,163 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -// #include "defines.h" - -#define VOLUME_MIN 0 -#define VOLUME_MAX 20 -#define BRIGHTNESS_MIN 0 -#define BRIGHTNESS_MAX 10 - -#define CODE_MENU 158 -#define CODE_PLUS 115 -#define CODE_MINUS 114 -#define CODE_JACK 2 - -// keymon and api might need different codes - -// for ev.value -#define RELEASED 0 -#define PRESSED 1 -#define REPEAT 2 - -#define INPUT_COUNT 2 -static int inputs[INPUT_COUNT] = {}; -static struct input_event ev; - -static int getInt(char* path) { - int i = 0; - FILE *file = fopen(path, "r"); - if (file!=NULL) { - fscanf(file, "%i", &i); - fclose(file); - } - return i; -} - -int main (int argc, char *argv[]) { - InitSettings(); - - char path[32]; - for (int i=0; i1000) ignore = 1; // ignore input that arrived during sleep - - for (int i=0; i REPEAT )) continue; - printf("code: %i (%i)\n", ev.code, val); fflush(stdout); - switch (ev.code) { - case CODE_MENU: - menu_pressed = val; - break; - break; - case CODE_PLUS: - up_pressed = up_just_pressed = val; - if (val) up_repeat_at = now + 300; - break; - case CODE_MINUS: - down_pressed = down_just_pressed = val; - if (val) down_repeat_at = now + 300; - break; - default: - break; - } - } - } - - if (ignore) { - menu_pressed = 0; - up_pressed = up_just_pressed = 0; - down_pressed = down_just_pressed = 0; - up_repeat_at = 0; - down_repeat_at = 0; - } - - if (up_just_pressed || (up_pressed && now>=up_repeat_at)) { - if (menu_pressed) { - printf("brightness up\n"); fflush(stdout); - val = GetBrightness(); - if (val=down_repeat_at)) { - if (menu_pressed) { - printf("brightness down\n"); fflush(stdout); - val = GetBrightness(); - if (val>BRIGHTNESS_MIN) SetBrightness(--val); - } - else { - printf("volume down\n"); fflush(stdout); - val = GetVolume(); - if (val>VOLUME_MIN) SetVolume(--val); - } - - if (down_just_pressed) down_just_pressed = 0; - else down_repeat_at += 100; - } - - then = now; - ignore = 0; - - usleep(16666); // 60fps - } -} diff --git a/workspace/_unmaintained/zero28/keymon/makefile b/workspace/_unmaintained/zero28/keymon/makefile deleted file mode 100755 index 0212b6bbc..000000000 --- a/workspace/_unmaintained/zero28/keymon/makefile +++ /dev/null @@ -1,16 +0,0 @@ -#keymon - -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif - -TARGET = keymon - -CC = $(CROSS_COMPILE)gcc -CFLAGS = -Os -lmsettings -lpthread -lrt -ldl -Wl,--gc-sections -s -CFLAGS += -I. -I../../all/common -I../platform/ -DPLATFORM=\"$(UNION_PLATFORM)\" - -all: - $(CC) $(TARGET).c -o $(TARGET).elf $(CFLAGS) -clean: - rm -rf $(TARGET).elf \ No newline at end of file diff --git a/workspace/_unmaintained/zero28/libmsettings/makefile b/workspace/_unmaintained/zero28/libmsettings/makefile deleted file mode 100644 index 990c69f60..000000000 --- a/workspace/_unmaintained/zero28/libmsettings/makefile +++ /dev/null @@ -1,29 +0,0 @@ -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif -ifeq (,$(PREFIX)) -$(error missing PREFIX for this toolchain) -endif - -TARGET=msettings - -.PHONY: build -.PHONY: clean - -CC = $(CROSS_COMPILE)gcc - -CFLAGS = -LDFLAGS = -ldl -lrt -s - -OPTM=-Ofast - -build: - $(CC) -c -Werror -fpic "$(TARGET).c" $(CFLAGS) -Wl,--no-as-needed $(LDFLAGS) - $(CC) -shared -o "lib$(TARGET).so" "$(TARGET).o" $(LDFLAGS) - cp "$(TARGET).h" "$(PREFIX)/include" - cp "lib$(TARGET).so" "$(PREFIX)/lib" -clean: - rm -f *.o - rm -f "lib$(TARGET).so" - rm -f $(PREFIX)/include/$(TARGET).h - rm -f $(PREFIX)/lib/lib$(TARGET).so \ No newline at end of file diff --git a/workspace/_unmaintained/zero28/libmsettings/msettings.c b/workspace/_unmaintained/zero28/libmsettings/msettings.c deleted file mode 100644 index c0521b71d..000000000 --- a/workspace/_unmaintained/zero28/libmsettings/msettings.c +++ /dev/null @@ -1,237 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -// #include - -#include "msettings.h" - -/////////////////////////////////////// - -#define SETTINGS_VERSION 3 -typedef struct Settings { - int version; // future proofing - int brightness; - int headphones; - int speaker; - int mute; - int unused[2]; // for future use - // NOTE: doesn't really need to be persisted but still needs to be shared - int jack; -} Settings; -static Settings DefaultSettings = { - .version = SETTINGS_VERSION, - .brightness = 2, - .headphones = 4, - .speaker = 8, - .mute = 0, - .jack = 0, -}; -static Settings* settings; - -#define SHM_KEY "/SharedSettings" -static char SettingsPath[256]; -static int shm_fd = -1; -static int is_host = 0; -static int shm_size = sizeof(Settings); - -// #define BACKLIGHT_PATH "/sys/class/backlight/backlight/bl_power" -// #define BRIGHTNESS_PATH "/sys/class/backlight/backlight/brightness" -// #define JACK_STATE_PATH "/sys/bus/platform/devices/singleadc-joypad/hp" -// #define HDMI_STATE_PATH "/sys/class/extcon/hdmi/cable.0/state" - -int getInt(char* path) { - int i = 0; - FILE *file = fopen(path, "r"); - if (file!=NULL) { - fscanf(file, "%i", &i); - fclose(file); - } - return i; -} - -void InitSettings(void) { - sprintf(SettingsPath, "%s/msettings.bin", getenv("USERDATA_PATH")); - - shm_fd = shm_open(SHM_KEY, O_RDWR | O_CREAT | O_EXCL, 0644); // see if it exists - if (shm_fd==-1 && errno==EEXIST) { // already exists - // puts("Settings client"); - shm_fd = shm_open(SHM_KEY, O_RDWR, 0644); - settings = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); - } - else { // host - // puts("Settings host"); // keymon - is_host = 1; - // we created it so set initial size and populate - ftruncate(shm_fd, shm_size); - settings = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); - - int fd = open(SettingsPath, O_RDONLY); - if (fd>=0) { - read(fd, settings, shm_size); - // TODO: use settings->version for future proofing? - close(fd); - } - else { - // load defaults - memcpy(settings, &DefaultSettings, shm_size); - } - - // these shouldn't be persisted - // settings->jack = 0; - // settings->hdmi = 0; - settings->mute = 0; - } - // printf("brightness: %i\nspeaker: %i \n", settings->brightness, settings->speaker); - - system("amixer sset 'Headphone' 0"); // 100% - system("amixer sset 'digital volume' 0"); // 100% - system("amixer sset 'Soft Volume Master' 255"); // 100% - // volume is set with 'DAC volume' - - SetVolume(GetVolume()); - SetBrightness(GetBrightness()); -} -void QuitSettings(void) { - munmap(settings, shm_size); - if (is_host) shm_unlink(SHM_KEY); -} -static inline void SaveSettings(void) { - int fd = open(SettingsPath, O_CREAT|O_WRONLY, 0644); - if (fd>=0) { - write(fd, settings, shm_size); - close(fd); - sync(); - } -} - -int GetBrightness(void) { // 0-10 - return settings->brightness; -} -void SetBrightness(int value) { - - int raw; - switch (value) { - // TODO: revisit - case 0: raw = 1; break; // 0 - case 1: raw = 8; break; // 8 - case 2: raw = 16; break; // 8 - case 3: raw = 32; break; // 16 - case 4: raw = 48; break; // 16 - case 5: raw = 72; break; // 24 - case 6: raw = 96; break; // 24 - case 7: raw = 128; break; // 32 - case 8: raw = 160; break; // 32 - case 9: raw = 192; break; // 32 - case 10: raw = 255; break; // 64 - } - SetRawBrightness(raw); - settings->brightness = value; - SaveSettings(); -} - -int GetVolume(void) { // 0-20 - if (settings->mute) return 0; - return settings->jack ? settings->headphones : settings->speaker; -} -void SetVolume(int value) { // 0-20 - if (settings->mute) return SetRawVolume(0); - // if (settings->hdmi) return; - - if (settings->jack) settings->headphones = value; - else settings->speaker = value; - - int raw = value * 5; - if (raw>0) raw = 96 + (64 * raw) / 100; - SetRawVolume(raw); - SaveSettings(); -} - -#define DISP_LCD_SET_BRIGHTNESS 0x102 -void SetRawBrightness(int val) { // 0 - 255 - // if (settings->hdmi) return; - - // val = 255-val; // inverted - printf("SetRawBrightness(%i)\n", val); fflush(stdout); - - int fd = open("/dev/disp", O_RDWR); - if (fd) { - unsigned long param[4]={0,val,0,0}; - ioctl(fd, DISP_LCD_SET_BRIGHTNESS, ¶m); - close(fd); - } -} -void SetRawVolume(int val) { // 0 or 96 - 160 - printf("SetRawVolume(%i)\n", val); fflush(stdout); - if (settings->mute) val = 0; - - char cmd[256]; - sprintf(cmd, "amixer sset 'DAC volume' %i &> /dev/null", val); - system(cmd); - - // TODO: unfortunately doing it this way creating a linker nightmare - // struct mixer *mixer = mixer_open(0); - // struct mixer_ctl *ctl; - // - // // digital volume (one-time?) - // ctl = mixer_get_ctl(mixer, 3); - // mixer_ctl_set_value(ctl,0,0); - // - // // Soft Volume Master (one-time?) - // ctl = mixer_get_ctl(mixer, 16); - // mixer_ctl_set_value(ctl,0,255); - // mixer_ctl_set_value(ctl,1,255); - // - // // DAC volume - // ctl = mixer_get_ctl(mixer, 7); - // mixer_ctl_set_value(ctl,0,val); - // mixer_ctl_set_value(ctl,1,val); - // mixer_close(mixer); - - // char cmd[256]; - // sprintf(cmd, "amixer sset 'digital volume' %i%% &> /dev/null", 100-val); - // // puts(cmd); fflush(stdout); - // system(cmd); -} - -// monitored and set by thread in keymon -int GetJack(void) { - return settings->jack; -} -void SetJack(int value) { - printf("SetJack(%i)\n", value); fflush(stdout); - - settings->jack = value; - SetVolume(GetVolume()); -} - -int GetHDMI(void) { - // printf("GetHDMI() %i\n", settings->hdmi); fflush(stdout); - // return settings->hdmi; - return 0; -} -void SetHDMI(int value) { - // printf("SetHDMI(%i)\n", value); fflush(stdout); - - // if (settings->hdmi!=value) system("/usr/lib/autostart/common/055-hdmi-check"); - - // settings->hdmi = value; - // if (value) SetRawVolume(100); // max - // else SetVolume(GetVolume()); // restore -} - -int GetMute(void) { - return settings->mute; -} -void SetMute(int value) { - settings->mute = value; - if (settings->mute) SetRawVolume(0); - else SetVolume(GetVolume()); -} \ No newline at end of file diff --git a/workspace/_unmaintained/zero28/libmsettings/msettings.h b/workspace/_unmaintained/zero28/libmsettings/msettings.h deleted file mode 100644 index 0b9394fec..000000000 --- a/workspace/_unmaintained/zero28/libmsettings/msettings.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef __msettings_h__ -#define __msettings_h__ - -void InitSettings(void); -void QuitSettings(void); - -int GetBrightness(void); -int GetVolume(void); - -void SetRawBrightness(int value); // 0-255 -void SetRawVolume(int value); // 0-160 - -void SetBrightness(int value); // 0-10 -void SetVolume(int value); // 0-20 - -int GetJack(void); -void SetJack(int value); // 0-1 - -int GetHDMI(void); -void SetHDMI(int value); // 0-1 - -int GetMute(void); -void SetMute(int value); // 0-1 - -#endif // __msettings_h__ diff --git a/workspace/_unmaintained/zero28/makefile b/workspace/_unmaintained/zero28/makefile deleted file mode 100644 index f4e4f6681..000000000 --- a/workspace/_unmaintained/zero28/makefile +++ /dev/null @@ -1,33 +0,0 @@ -# zero28 - -########################################################### - -ifeq (,$(PLATFORM)) -PLATFORM=$(UNION_PLATFORM) -endif - -ifeq (,$(PLATFORM)) -$(error please specify PLATFORM, eg. PLATFORM=trimui make) -endif - -########################################################### - -REQUIRES_COMMANDER=other/DinguxCommander-sdl2 - -all: readmes - cd bl && make - cd show && make - -early: $(REQUIRES_COMMANDER) - mkdir -p other - cd $(REQUIRES_COMMANDER) && make -j - -clean: - cd bl && make clean - cd show && make clean - cd $(REQUIRES_COMMANDER) && make clean - -$(REQUIRES_COMMANDER): - git clone --depth 1 https://github.com/shauninman/DinguxCommander-sdl2.git $(REQUIRES_COMMANDER) - -include ../all/readmes/makefile diff --git a/workspace/_unmaintained/zero28/platform/makefile.copy b/workspace/_unmaintained/zero28/platform/makefile.copy deleted file mode 100644 index 861d4d0e1..000000000 --- a/workspace/_unmaintained/zero28/platform/makefile.copy +++ /dev/null @@ -1,15 +0,0 @@ -$(PLATFORM): - # $@ - cp ./workspace/$@/show/show.elf ./build/SYSTEM/$@/bin - cp ./workspace/$@/bl/bl_disable ./build/SYSTEM/$@/bin - cp ./workspace/$@/bl/bl_enable ./build/SYSTEM/$@/bin - # installer - cp ./workspace/$@/install/boot.sh ./build/BOOT/common/$@.sh - cp ./workspace/$@/install/update.sh ./build/SYSTEM/$@/bin/install.sh - mkdir -p ./build/BOOT/common/$@/ - cp ./workspace/$@/install/*.png ./build/BOOT/common/$@/ - cp ./workspace/$@/show/show.elf ./build/BOOT/common/$@/ - # extras - cp ./workspace/$@/other/DinguxCommander-sdl2/DinguxCommander ./build/EXTRAS/Tools/$@/Files.pak/ - cp -r ./workspace/$@/other/DinguxCommander-sdl2/res ./build/EXTRAS/Tools/$@/Files.pak/ - \ No newline at end of file diff --git a/workspace/_unmaintained/zero28/platform/makefile.env b/workspace/_unmaintained/zero28/platform/makefile.env deleted file mode 100644 index 1e74aa9d7..000000000 --- a/workspace/_unmaintained/zero28/platform/makefile.env +++ /dev/null @@ -1,4 +0,0 @@ -# tg5040 -ARCH = -O3 -LIBS = -flto -SDL = SDL2 \ No newline at end of file diff --git a/workspace/_unmaintained/zero28/platform/platform.c b/workspace/_unmaintained/zero28/platform/platform.c deleted file mode 100644 index 12e0d57b9..000000000 --- a/workspace/_unmaintained/zero28/platform/platform.c +++ /dev/null @@ -1,578 +0,0 @@ -// zero28 -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include "defines.h" -#include "platform.h" -#include "api.h" -#include "utils.h" - -#include "scaler.h" - -/////////////////////////////// - -static SDL_Joystick *joystick; -void PLAT_initInput(void) { - SDL_InitSubSystem(SDL_INIT_JOYSTICK); - joystick = SDL_JoystickOpen(0); -} -void PLAT_quitInput(void) { - SDL_JoystickClose(joystick); - SDL_QuitSubSystem(SDL_INIT_JOYSTICK); -} - -/////////////////////////////// - -static struct VID_Context { - SDL_Window* window; - SDL_Renderer* renderer; - SDL_Texture* texture; - SDL_Texture* target; - SDL_Texture* effect; - SDL_Surface* buffer; - SDL_Surface* screen; - - GFX_Renderer* blit; // yeesh - - int width; - int height; - int pitch; - int sharpness; -} vid; - -static int device_width; -static int device_height; -static int device_pitch; -static int rotate = 0; -SDL_Surface* PLAT_initVideo(void) { - SDL_InitSubSystem(SDL_INIT_VIDEO); - SDL_ShowCursor(0); - - SDL_version compiled; - SDL_version linked; - SDL_VERSION(&compiled); - SDL_GetVersion(&linked); - LOG_info("Compiled SDL version %d.%d.%d ...\n", compiled.major, compiled.minor, compiled.patch); - LOG_info("Linked SDL version %d.%d.%d.\n", linked.major, linked.minor, linked.patch); - - LOG_info("Available video drivers:\n"); - for (int i=0; imode.w) rotate = 1; - LOG_info("Current display mode: %ix%i (%s)\n", mode.w,mode.h, SDL_GetPixelFormatName(mode.format)); - - int w = FIXED_WIDTH; - int h = FIXED_HEIGHT; - int p = FIXED_PITCH; - vid.window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w,h, SDL_WINDOW_SHOWN); - vid.renderer = SDL_CreateRenderer(vid.window,-1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC); - - SDL_RendererInfo info; - SDL_GetRendererInfo(vid.renderer, &info); - LOG_info("Current render driver: %s\n", info.name); - - int rw,rh; - SDL_GetRendererOutputSize(vid.renderer, &rw,&rh); - LOG_info("renderer size: %ix%i\n", rw,rh); - - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY,"0"); - vid.texture = SDL_CreateTexture(vid.renderer,SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, w,h); - int tw,th; - SDL_QueryTexture(vid.texture, NULL,NULL,&tw,&th); - LOG_info("texture size: %ix%i\n", tw,th); // TODO: why is this 1024x768? :lolsob: - - vid.target = NULL; // only needed for non-native sizes - - // SDL_SetTextureScaleMode(vid.texture, SDL_ScaleModeNearest); - - vid.buffer = SDL_CreateRGBSurfaceFrom(NULL, w,h, FIXED_DEPTH, p, RGBA_MASK_565); - vid.screen = SDL_CreateRGBSurface(SDL_SWSURFACE, w,h, FIXED_DEPTH, RGBA_MASK_565); - vid.width = w; - vid.height = h; - vid.pitch = p; - - device_width = w; - device_height = h; - device_pitch = p; - - vid.sharpness = SHARPNESS_SOFT; - - return vid.screen; -} - -static void clearVideo(void) { - for (int i=0; i<3; i++) { - SDL_RenderClear(vid.renderer); - SDL_FillRect(vid.screen, NULL, 0); - - SDL_LockTexture(vid.texture,NULL,&vid.buffer->pixels,&vid.buffer->pitch); - SDL_FillRect(vid.buffer, NULL, 0); - SDL_UnlockTexture(vid.texture); - SDL_RenderCopy(vid.renderer, vid.texture, NULL, NULL); - - SDL_RenderPresent(vid.renderer); - } -} - -void PLAT_quitVideo(void) { - clearVideo(); - - SDL_FreeSurface(vid.screen); - SDL_FreeSurface(vid.buffer); - if (vid.target) SDL_DestroyTexture(vid.target); - if (vid.effect) SDL_DestroyTexture(vid.effect); - SDL_DestroyTexture(vid.texture); - SDL_DestroyRenderer(vid.renderer); - SDL_DestroyWindow(vid.window); - - SDL_Quit(); - system("cat /dev/zero > /dev/fb0 2>/dev/null"); -} - -void PLAT_clearVideo(SDL_Surface* screen) { - SDL_FillRect(screen, NULL, 0); // TODO: revisit -} -void PLAT_clearAll(void) { - PLAT_clearVideo(vid.screen); // TODO: revist - SDL_RenderClear(vid.renderer); -} - -void PLAT_setVsync(int vsync) { - -} - -static int hard_scale = 4; // TODO: base src size, eg. 160x144 can be 4 - -static void resizeVideo(int w, int h, int p) { - if (w==vid.width && h==vid.height && p==vid.pitch) return; - - // TODO: minarch disables crisp (and nn upscale before linear downscale) when native, is this true? - - if (w>=device_width && h>=device_height) hard_scale = 1; - // else if (h>=160) hard_scale = 2; // limits gba and up to 2x (seems sufficient for 640x480) - else hard_scale = 4; - - LOG_info("resizeVideo(%i,%i,%i) hard_scale: %i crisp: %i\n",w,h,p, hard_scale,vid.sharpness==SHARPNESS_CRISP); - - SDL_FreeSurface(vid.buffer); - SDL_DestroyTexture(vid.texture); - if (vid.target) SDL_DestroyTexture(vid.target); - - SDL_SetHintWithPriority(SDL_HINT_RENDER_SCALE_QUALITY, vid.sharpness==SHARPNESS_SOFT?"1":"0", SDL_HINT_OVERRIDE); - vid.texture = SDL_CreateTexture(vid.renderer,SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, w,h); - - if (vid.sharpness==SHARPNESS_CRISP) { - SDL_SetHintWithPriority(SDL_HINT_RENDER_SCALE_QUALITY, "1", SDL_HINT_OVERRIDE); - vid.target = SDL_CreateTexture(vid.renderer,SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_TARGET, w * hard_scale,h * hard_scale); - } - else { - vid.target = NULL; - } - - vid.buffer = SDL_CreateRGBSurfaceFrom(NULL, w,h, FIXED_DEPTH, p, RGBA_MASK_565); - - vid.width = w; - vid.height = h; - vid.pitch = p; -} - -SDL_Surface* PLAT_resizeVideo(int w, int h, int p) { - resizeVideo(w,h,p); - return vid.screen; -} - -void PLAT_setVideoScaleClip(int x, int y, int width, int height) { - // buh -} -void PLAT_setNearestNeighbor(int enabled) { - // always enabled? -} -void PLAT_setSharpness(int sharpness) { - if (vid.sharpness==sharpness) return; - int p = vid.pitch; - vid.pitch = 0; - vid.sharpness = sharpness; - resizeVideo(vid.width,vid.height,p); -} - -static struct FX_Context { - int scale; - int type; - int color; - int next_scale; - int next_type; - int next_color; - int live_type; -} effect = { - .scale = 1, - .next_scale = 1, - .type = EFFECT_NONE, - .next_type = EFFECT_NONE, - .live_type = EFFECT_NONE, - .color = 0, - .next_color = 0, -}; -static void rgb565_to_rgb888(uint32_t rgb565, uint8_t *r, uint8_t *g, uint8_t *b) { - // Extract the red component (5 bits) - uint8_t red = (rgb565 >> 11) & 0x1F; - // Extract the green component (6 bits) - uint8_t green = (rgb565 >> 5) & 0x3F; - // Extract the blue component (5 bits) - uint8_t blue = rgb565 & 0x1F; - - // Scale the values to 8-bit range - *r = (red << 3) | (red >> 2); - *g = (green << 2) | (green >> 4); - *b = (blue << 3) | (blue >> 2); -} -static void updateEffect(void) { - if (effect.next_scale==effect.scale && effect.next_type==effect.type && effect.next_color==effect.color) return; // unchanged - - int live_scale = effect.scale; - int live_color = effect.color; - effect.scale = effect.next_scale; - effect.type = effect.next_type; - effect.color = effect.next_color; - - if (effect.type==EFFECT_NONE) return; // disabled - if (effect.type==effect.live_type && effect.scale==live_scale && effect.color==live_color) return; // already loaded - - char* effect_path; - int opacity = 128; // 1 - 1/2 = 50% - if (effect.type==EFFECT_LINE) { - if (effect.scale<3) { - effect_path = RES_PATH "/line-2.png"; - } - else if (effect.scale<4) { - effect_path = RES_PATH "/line-3.png"; - } - else if (effect.scale<5) { - effect_path = RES_PATH "/line-4.png"; - } - else if (effect.scale<6) { - effect_path = RES_PATH "/line-5.png"; - } - else if (effect.scale<8) { - effect_path = RES_PATH "/line-6.png"; - } - else { - effect_path = RES_PATH "/line-8.png"; - } - } - else if (effect.type==EFFECT_GRID) { - if (effect.scale<3) { - effect_path = RES_PATH "/grid-2.png"; - opacity = 64; // 1 - 3/4 = 25% - } - else if (effect.scale<4) { - effect_path = RES_PATH "/grid-3.png"; - opacity = 112; // 1 - 5/9 = ~44% - } - else if (effect.scale<5) { - effect_path = RES_PATH "/grid-4.png"; - opacity = 144; // 1 - 7/16 = ~56% - } - else if (effect.scale<6) { - effect_path = RES_PATH "/grid-5.png"; - opacity = 160; // 1 - 9/25 = ~64% - // opacity = 96; // TODO: tmp, for white grid - } - else if (effect.scale<8) { - effect_path = RES_PATH "/grid-6.png"; - opacity = 112; // 1 - 5/9 = ~44% - } - else if (effect.scale<11) { - effect_path = RES_PATH "/grid-8.png"; - opacity = 144; // 1 - 7/16 = ~56% - } - else { - effect_path = RES_PATH "/grid-11.png"; - opacity = 136; // 1 - 57/121 = ~52% - } - } - - // LOG_info("effect: %s opacity: %i\n", effect_path, opacity); - SDL_Surface* tmp = IMG_Load(effect_path); - if (tmp) { - if (effect.type==EFFECT_GRID) { - if (effect.color) { - // LOG_info("dmg color grid...\n"); - - uint8_t r,g,b; - rgb565_to_rgb888(effect.color,&r,&g,&b); - // LOG_info("rgb %i,%i,%i\n",r,g,b); - - uint32_t* pixels = (uint32_t*)tmp->pixels; - int width = tmp->w; - int height = tmp->h; - for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) { - uint32_t pixel = pixels[y * width + x]; - uint8_t _,a; - SDL_GetRGBA(pixel, tmp->format, &_, &_, &_, &a); - if (a) pixels[y * width + x] = SDL_MapRGBA(tmp->format, r,g,b, a); - } - } - - // if (r==247 && g==243 & b==247) opacity = 64; - } - } - - if (vid.effect) SDL_DestroyTexture(vid.effect); - vid.effect = SDL_CreateTextureFromSurface(vid.renderer, tmp); - SDL_SetTextureAlphaMod(vid.effect, opacity); - SDL_FreeSurface(tmp); - effect.live_type = effect.type; - } -} -void PLAT_setEffect(int next_type) { - effect.next_type = next_type; -} -void PLAT_setEffectColor(int next_color) { - effect.next_color = next_color; -} -void PLAT_vsync(int remaining) { - if (remaining>0) SDL_Delay(remaining); -} - -scaler_t PLAT_getScaler(GFX_Renderer* renderer) { - // LOG_info("getScaler for scale: %i\n", renderer->scale); - effect.next_scale = renderer->scale; - return scale1x1_c16; -} - -void PLAT_blitRenderer(GFX_Renderer* renderer) { - vid.blit = renderer; - SDL_RenderClear(vid.renderer); - resizeVideo(vid.blit->true_w,vid.blit->true_h,vid.blit->src_p); -} - -void PLAT_flip(SDL_Surface* IGNORED, int ignored) { - - if (!vid.blit) { - resizeVideo(device_width,device_height,FIXED_PITCH); // !!!??? - SDL_UpdateTexture(vid.texture,NULL,vid.screen->pixels,vid.screen->pitch); - if (rotate) SDL_RenderCopyEx(vid.renderer,vid.texture,NULL,&(SDL_Rect){device_height,0,device_width,device_height},rotate*90,&(SDL_Point){0,0},SDL_FLIP_NONE); - else SDL_RenderCopy(vid.renderer, vid.texture, NULL,NULL); - SDL_RenderPresent(vid.renderer); - return; - } - - // uint32_t then = SDL_GetTicks(); - SDL_UpdateTexture(vid.texture,NULL,vid.blit->src,vid.blit->src_p); - // LOG_info("blit blocked for %ims (%i,%i)\n", SDL_GetTicks()-then,vid.buffer->w,vid.buffer->h); - - SDL_Texture* target = vid.texture; - int x = vid.blit->src_x; - int y = vid.blit->src_y; - int w = vid.blit->src_w; - int h = vid.blit->src_h; - if (vid.sharpness==SHARPNESS_CRISP) { - SDL_SetRenderTarget(vid.renderer,vid.target); - SDL_RenderCopy(vid.renderer, vid.texture, NULL,NULL); - SDL_SetRenderTarget(vid.renderer,NULL); - x *= hard_scale; - y *= hard_scale; - w *= hard_scale; - h *= hard_scale; - target = vid.target; - } - - SDL_Rect* src_rect = &(SDL_Rect){x,y,w,h}; - SDL_Rect* dst_rect = &(SDL_Rect){0,0,device_width,device_height}; - if (vid.blit->aspect==0) { // native or cropped - // LOG_info("src_rect %i,%i %ix%i\n",src_rect->x,src_rect->y,src_rect->w,src_rect->h); - - int w = vid.blit->src_w * vid.blit->scale; - int h = vid.blit->src_h * vid.blit->scale; - int x = (device_width - w) / 2; - int y = (device_height - h) / 2; - dst_rect->x = x; - dst_rect->y = y; - dst_rect->w = w; - dst_rect->h = h; - - // LOG_info("dst_rect %i,%i %ix%i\n",dst_rect->x,dst_rect->y,dst_rect->w,dst_rect->h); - } - else if (vid.blit->aspect>0) { // aspect - int h = device_height; - int w = h * vid.blit->aspect; - if (w>device_width) { - double ratio = 1 / vid.blit->aspect; - w = device_width; - h = w * ratio; - } - int x = (device_width - w) / 2; - int y = (device_height - h) / 2; - // dst_rect = &(SDL_Rect){x,y,w,h}; - dst_rect->x = x; - dst_rect->y = y; - dst_rect->w = w; - dst_rect->h = h; - } - - // SDL_RenderCopy(vid.renderer, target, src_rect, dst_rect); - int ox,oy; - oy = (device_width-device_height)/2; - ox = -oy; - if (rotate) SDL_RenderCopyEx(vid.renderer,target,src_rect,&(SDL_Rect){ox+dst_rect->x,oy+dst_rect->y,dst_rect->w,dst_rect->h},rotate*90,NULL,SDL_FLIP_NONE); - else SDL_RenderCopy(vid.renderer, target, src_rect, dst_rect); - - updateEffect(); - if (vid.blit && effect.type!=EFFECT_NONE && vid.effect) { - // SDL_RenderCopy(vid.renderer, vid.effect, &(SDL_Rect){0,0,dst_rect->w,dst_rect->h}, dst_rect); - if (rotate) SDL_RenderCopyEx(vid.renderer,vid.effect,&(SDL_Rect){0,0,dst_rect->w,dst_rect->h},&(SDL_Rect){ox+dst_rect->x,oy+dst_rect->y,dst_rect->w,dst_rect->h},rotate*90,NULL,SDL_FLIP_NONE); - else SDL_RenderCopy(vid.renderer, vid.effect, &(SDL_Rect){0,0,dst_rect->w,dst_rect->h},dst_rect); - } - // uint32_t then = SDL_GetTicks(); - SDL_RenderPresent(vid.renderer); - // LOG_info("SDL_RenderPresent blocked for %ims\n", SDL_GetTicks()-then); - vid.blit = NULL; -} - -/////////////////////////////// - -// TODO: -#define OVERLAY_WIDTH PILL_SIZE // unscaled -#define OVERLAY_HEIGHT PILL_SIZE // unscaled -#define OVERLAY_BPP 4 -#define OVERLAY_DEPTH 16 -#define OVERLAY_PITCH (OVERLAY_WIDTH * OVERLAY_BPP) // unscaled -#define OVERLAY_RGBA_MASK 0x00ff0000,0x0000ff00,0x000000ff,0xff000000 // ARGB -static struct OVL_Context { - SDL_Surface* overlay; -} ovl; - -SDL_Surface* PLAT_initOverlay(void) { - ovl.overlay = SDL_CreateRGBSurface(SDL_SWSURFACE, SCALE2(OVERLAY_WIDTH,OVERLAY_HEIGHT),OVERLAY_DEPTH,OVERLAY_RGBA_MASK); - return ovl.overlay; -} -void PLAT_quitOverlay(void) { - if (ovl.overlay) SDL_FreeSurface(ovl.overlay); -} -void PLAT_enableOverlay(int enable) { - -} - -/////////////////////////////// - -static int online = 0; -void PLAT_getBatteryStatus(int* is_charging, int* charge) { - PLAT_getBatteryStatusFine(is_charging, charge); - - // worry less about battery and more about the game you're playing - if (*charge>80) *charge = 100; - else if (*charge>60) *charge = 80; - else if (*charge>40) *charge = 60; - else if (*charge>20) *charge = 40; - else if (*charge>10) *charge = 20; - else *charge = 10; -} - -void PLAT_getBatteryStatusFine(int* is_charging, int* charge) -{ - - // *is_charging = 0; - // *charge = PWR_LOW_CHARGE; - // return; - - *is_charging = getInt("/sys/class/power_supply/axp2202-usb/online"); - - *charge = getInt("/sys/class/power_supply/axp2202-battery/capacity"); - - // // wifi status, just hooking into the regular PWR polling - char status[16]; - getFile("/sys/class/net/wlan0/operstate", status,16); - online = prefixMatch("up", status); -} - -#define BLANK_PATH "/sys/class/graphics/fb0/blank" -void PLAT_enableBacklight(int enable) { - // no LED control - if (enable) { - SetBrightness(GetBrightness()); - system("bl_enable"); - putInt(BLANK_PATH,FB_BLANK_UNBLANK); - } - else { - SetRawBrightness(0); - system("bl_disable"); - putInt(BLANK_PATH,FB_BLANK_POWERDOWN); - } -} - -void PLAT_powerOff(void) { - system("rm -f /tmp/nextui_exec && sync"); - sleep(2); - - SetRawVolume(MUTE_VOLUME_RAW); - PLAT_enableBacklight(0); - SND_quit(); - VIB_quit(); - PWR_quit(); - GFX_quit(); - - system("cat /dev/zero > /dev/fb0 2>/dev/null"); - system("poweroff"); - exit(0); - // while (1) pause(); // lolwat -} - -int PLAT_supportsDeepSleep(void) { return 1; } - -/////////////////////////////// - -#define GOVERNOR_PATH "/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed" -void PLAT_setCPUSpeed(int speed) { - int freq = 0; - switch (speed) { - case CPU_SPEED_MENU: freq = 600000; break; - case CPU_SPEED_POWERSAVE: freq = 816000; break; - case CPU_SPEED_NORMAL: freq = 1416000; break; - case CPU_SPEED_PERFORMANCE: freq = 1800000; break; - } - putInt(GOVERNOR_PATH, freq); -} - -#define RUMBLE_PATH "/sys/class/gpio/gpio227/value" -void PLAT_setRumble(int strength) { - // putInt(RUMBLE_PATH, (strength && !GetMute())?1:0); -} - -int PLAT_pickSampleRate(int requested, int max) { - return MIN(requested, max); -} - -char* PLAT_getModel(void) { - return "Mini Zero 28"; -} - -int PLAT_isOnline(void) { - return online; -} \ No newline at end of file diff --git a/workspace/_unmaintained/zero28/platform/platform.h b/workspace/_unmaintained/zero28/platform/platform.h deleted file mode 100644 index 397afc378..000000000 --- a/workspace/_unmaintained/zero28/platform/platform.h +++ /dev/null @@ -1,136 +0,0 @@ -// zero28 - -#ifndef PLATFORM_H -#define PLATFORM_H - -/////////////////////////////// - -#include "sdl.h" - -/////////////////////////////// - -#define BUTTON_UP BUTTON_NA -#define BUTTON_DOWN BUTTON_NA -#define BUTTON_LEFT BUTTON_NA -#define BUTTON_RIGHT BUTTON_NA - -#define BUTTON_SELECT BUTTON_NA -#define BUTTON_START BUTTON_NA - -#define BUTTON_A BUTTON_NA -#define BUTTON_B BUTTON_NA -#define BUTTON_X BUTTON_NA -#define BUTTON_Y BUTTON_NA - -#define BUTTON_L1 BUTTON_NA -#define BUTTON_R1 BUTTON_NA -#define BUTTON_L2 BUTTON_NA -#define BUTTON_R2 BUTTON_NA -#define BUTTON_L3 BUTTON_NA -#define BUTTON_R3 BUTTON_NA - -#define BUTTON_MENU BUTTON_NA -#define BUTTON_MENU_ALT BUTTON_NA -#define BUTTON_POWER 116 // BUTTON_NA -#define BUTTON_PLUS BUTTON_NA -#define BUTTON_MINUS BUTTON_NA - -/////////////////////////////// - -#define CODE_UP CODE_NA -#define CODE_DOWN CODE_NA -#define CODE_LEFT CODE_NA -#define CODE_RIGHT CODE_NA - -#define CODE_SELECT CODE_NA -#define CODE_START CODE_NA - -#define CODE_A CODE_NA -#define CODE_B CODE_NA -#define CODE_X CODE_NA -#define CODE_Y CODE_NA - -#define CODE_L1 CODE_NA -#define CODE_R1 CODE_NA -#define CODE_L2 CODE_NA -#define CODE_R2 CODE_NA -#define CODE_L3 CODE_NA -#define CODE_R3 CODE_NA - -#define CODE_MENU CODE_NA -#define CODE_POWER 102 - -#define CODE_PLUS 128 -#define CODE_MINUS 129 - -/////////////////////////////// - // HATS -#define JOY_UP 13 -#define JOY_DOWN 16 -#define JOY_LEFT 14 -#define JOY_RIGHT 15 - -#define JOY_SELECT 8 -#define JOY_START 9 - -// TODO: these ended up swapped in the first public release of stock :sob: -#define JOY_A 0 -#define JOY_B 1 -#define JOY_X 2 -#define JOY_Y 3 - -#define JOY_L1 4 -#define JOY_R1 5 -#define JOY_L2 6 -#define JOY_R2 7 -#define JOY_L3 10 -#define JOY_R3 11 - -#define JOY_MENU 19 -#define JOY_POWER 102 -#define JOY_PLUS 18 -#define JOY_MINUS 17 - -/////////////////////////////// - -#define AXIS_LX 0 // ABS_X, -30k (left) to 30k (right) -#define AXIS_LY 1 // ABS_Y, -30k (up) to 30k (down) -#define AXIS_RX 2 // ABS_RX, -30k (left) to 30k (right) -#define AXIS_RY 3 // ABS_RY, -30k (up) to 30k (down) - -/////////////////////////////// - -#define BTN_RESUME BTN_X -#define BTN_SLEEP BTN_POWER -#define BTN_WAKE BTN_POWER -#define BTN_MOD_VOLUME BTN_NONE -#define BTN_MOD_BRIGHTNESS BTN_MENU -#define BTN_MOD_PLUS BTN_PLUS -#define BTN_MOD_MINUS BTN_MINUS - -/////////////////////////////// - -#define FIXED_SCALE 2 -#define FIXED_WIDTH 640 -#define FIXED_HEIGHT 480 -#define FIXED_BPP 2 -#define FIXED_DEPTH (FIXED_BPP * 8) -#define FIXED_PITCH (FIXED_WIDTH * FIXED_BPP) -#define FIXED_SIZE (FIXED_PITCH * FIXED_HEIGHT) - -/////////////////////////////// - -#define MAIN_ROW_COUNT 6 -#define PADDING 10 - -/////////////////////////////// - -#define SDCARD_PATH "/mnt/SDCARD" -#define MUTE_VOLUME_RAW 63 // 0 unintuitively is 100% volume -#define SAMPLES 400 // fix for (most) fceumm underruns - -// this should be set to the devices native screen refresh rate -#define SCREEN_FPS 60.0 -/////////////////////////////// - -#endif diff --git a/workspace/_unmaintained/zero28/show/makefile b/workspace/_unmaintained/zero28/show/makefile deleted file mode 100755 index b61deed63..000000000 --- a/workspace/_unmaintained/zero28/show/makefile +++ /dev/null @@ -1,14 +0,0 @@ -ifeq (,$(CROSS_COMPILE)) -$(error missing CROSS_COMPILE for this toolchain) -endif - -TARGET = show -PRODUCT = $(TARGET).elf - -CC = $(CROSS_COMPILE)gcc -FLAGS = -Os -lSDL2 -lSDL2_image -lrt -ldl -Wl,--gc-sections -s - -all: - $(CC) $(TARGET).c -o $(PRODUCT) $(FLAGS) -clean: - rm -rf $(PRODUCT) \ No newline at end of file diff --git a/workspace/_unmaintained/zero28/show/show.c b/workspace/_unmaintained/zero28/show/show.c deleted file mode 100644 index 4a775d032..000000000 --- a/workspace/_unmaintained/zero28/show/show.c +++ /dev/null @@ -1,63 +0,0 @@ -// my282 -#include -#include -#include -#include - -#define FIXED_WIDTH 640 -#define FIXED_HEIGHT 480 -#define FIXED_BPP 2 -#define FIXED_DEPTH (FIXED_BPP * 8) -#define FIXED_PITCH (FIXED_WIDTH * FIXED_BPP) - -#define RGBA_MASK_565 0xF800, 0x07E0, 0x001F, 0x0000 - -int main(int argc , char* argv[]) { - if (argc<2) { - puts("Usage: show.elf image.png delay"); - return 0; - } - - char path[256]; - strncpy(path,argv[1],256); - if (access(path, F_OK)!=0) return 0; // nothing to show :( - - int delay = argc>2 ? atoi(argv[2]) : 2; - - SDL_Init(SDL_INIT_VIDEO); - SDL_ShowCursor(0); - - int w = FIXED_WIDTH; - int h = FIXED_HEIGHT; - int p = FIXED_PITCH; - SDL_Window* window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w,h, SDL_WINDOW_SHOWN); - - int rotate = 0; - SDL_DisplayMode mode; - SDL_GetCurrentDisplayMode(0, &mode); - if (mode.h>mode.w) rotate = 1; - - SDL_Renderer* renderer = SDL_CreateRenderer(window,-1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC); - SDL_Texture* texture = SDL_CreateTexture(renderer,SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, w,h); - SDL_Surface* screen = SDL_CreateRGBSurfaceFrom(NULL, w,h, FIXED_DEPTH, p, RGBA_MASK_565); - - SDL_LockTexture(texture,NULL,&screen->pixels,&screen->pitch); - SDL_FillRect(screen, NULL, 0); - SDL_Surface* img = IMG_Load(path); - SDL_BlitSurface(img, NULL, screen, &(SDL_Rect){(screen->w-img->w)/2,(screen->h-img->h)/2}); - SDL_FreeSurface(img); - SDL_UnlockTexture(texture); - - if (rotate) SDL_RenderCopyEx(renderer,texture,NULL,&(SDL_Rect){h,0,w,h},rotate*90,&(SDL_Point){0,0},SDL_FLIP_NONE); - else SDL_RenderCopy(renderer, texture, NULL,NULL); - SDL_RenderPresent(renderer); - - sleep(delay); - - SDL_FreeSurface(screen); - SDL_DestroyTexture(texture); - SDL_DestroyRenderer(renderer); - SDL_DestroyWindow(window); - SDL_Quit(); - return 0; -} From f5dc2dad893573eb047b554f01c41813b26dc879 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sun, 5 Jul 2026 13:13:58 +0200 Subject: [PATCH 39/77] nextui: fix name leak in Entry_newNamed (double-alloc) --- workspace/all/nextui/nextui.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/workspace/all/nextui/nextui.cpp b/workspace/all/nextui/nextui.cpp index 92c117a73..0107ba1dc 100644 --- a/workspace/all/nextui/nextui.cpp +++ b/workspace/all/nextui/nextui.cpp @@ -93,6 +93,7 @@ static Entry* Entry_new(char* path, int type) { static Entry* Entry_newNamed(char* path, int type, char* displayName) { Entry *self = Entry_new(path, type); + free(self->name); // Entry_new already strdup'd a display name; replace it self->name = strdup(displayName); return self; } From 6d71d5a8da168b083adb55746a5580a64adf4593 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sun, 5 Jul 2026 13:26:12 +0200 Subject: [PATCH 40/77] tg5040: hoist DeviceDescriptor into shared common/device.h --- workspace/all/common/device.h | 29 ++++++++++++++++++++++++++++ workspace/tg5040/platform/platform.h | 24 +---------------------- 2 files changed, 30 insertions(+), 23 deletions(-) create mode 100644 workspace/all/common/device.h diff --git a/workspace/all/common/device.h b/workspace/all/common/device.h new file mode 100644 index 000000000..a7045f749 --- /dev/null +++ b/workspace/all/common/device.h @@ -0,0 +1,29 @@ +#ifndef DEVICE_H +#define DEVICE_H + +// A device model is described by data, not code: the fields below are the +// only things that differ between hardware variants. Each platform defines +// one or more descriptors and points deviceModel at the active one (see +// resolveDeviceModel in the platform layer). Adding a device becomes a +// matter of adding a descriptor rather than another runtime branch. +typedef struct DeviceDescriptor { + int scale; // FIXED_SCALE + int width; // FIXED_WIDTH + int height; // FIXED_HEIGHT + int main_row_count; // MAIN_ROW_COUNT + int quick_switcher_count; // QUICK_SWITCHER_COUNT + int padding; // PADDING + int joy_l3; // JOY_L3 + int joy_r3; // JOY_R3 + int joy_plus; // JOY_PLUS + int joy_minus; // JOY_MINUS + // sysfs hardware nodes that differ across platforms -- the seams a future + // device redefines. Identical for Brick and Smart Pro; tg5050, for example, + // uses cpu4 not cpu0, thermal_zone5 not zone2, gpio236 not gpio227. + const char* cpu_speed_path; + const char* gpu_temp_path; + const char* rumble_gpio_path; +} DeviceDescriptor; +extern const DeviceDescriptor* deviceModel; + +#endif // DEVICE_H diff --git a/workspace/tg5040/platform/platform.h b/workspace/tg5040/platform/platform.h index c204659d3..0669cc6d9 100644 --- a/workspace/tg5040/platform/platform.h +++ b/workspace/tg5040/platform/platform.h @@ -13,29 +13,7 @@ extern int is_brick; -// A device model is described by data, not code. The tg5040 platform ships two -// models -- the TrimUI Brick and the Smart Pro -- that differ only in the values -// below; is_brick selects which descriptor is active at runtime. Adding a device -// becomes a matter of adding a descriptor rather than another is_brick ternary. -typedef struct DeviceDescriptor { - int scale; // FIXED_SCALE - int width; // FIXED_WIDTH - int height; // FIXED_HEIGHT - int main_row_count; // MAIN_ROW_COUNT - int quick_switcher_count; // QUICK_SWITCHER_COUNT - int padding; // PADDING - int joy_l3; // JOY_L3 - int joy_r3; // JOY_R3 - int joy_plus; // JOY_PLUS - int joy_minus; // JOY_MINUS - // sysfs hardware nodes that differ across platforms -- the seams a future - // device redefines. Identical for Brick and Smart Pro; tg5050, for example, - // uses cpu4 not cpu0, thermal_zone5 not zone2, gpio236 not gpio227. - const char* cpu_speed_path; - const char* gpu_temp_path; - const char* rumble_gpio_path; -} DeviceDescriptor; -extern const DeviceDescriptor* deviceModel; +#include "device.h" /////////////////////////////// From 99d76f9709947f830f1cf97e124ba46228f9d99b Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sun, 5 Jul 2026 13:47:47 +0200 Subject: [PATCH 41/77] device: add GPU freq/usage descriptor fields; tg5040 reads gpu_speed_fixed --- workspace/all/common/device.h | 6 ++++++ workspace/tg5040/platform/platform.c | 8 +++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/workspace/all/common/device.h b/workspace/all/common/device.h index a7045f749..e602dbd69 100644 --- a/workspace/all/common/device.h +++ b/workspace/all/common/device.h @@ -23,6 +23,12 @@ typedef struct DeviceDescriptor { const char* cpu_speed_path; const char* gpu_temp_path; const char* rumble_gpio_path; + // GPU frequency/utilization: some devices read a sysfs node, others report + // a fixed clock. gpu_freq_path NULL => PLAT_getGPUSpeed uses gpu_speed_fixed; + // gpu_usage_path NULL => GPU utilization is unavailable on this device. + int gpu_speed_fixed; + const char* gpu_freq_path; + const char* gpu_usage_path; } DeviceDescriptor; extern const DeviceDescriptor* deviceModel; diff --git a/workspace/tg5040/platform/platform.c b/workspace/tg5040/platform/platform.c index fc8c69a8d..ff502f47a 100644 --- a/workspace/tg5040/platform/platform.c +++ b/workspace/tg5040/platform/platform.c @@ -41,6 +41,9 @@ static const DeviceDescriptor TG5040_BRICK = { .joy_l3 = 9, .joy_r3 = 10, .joy_plus = 14, .joy_minus = 13, .cpu_speed_path = TG5040_CPU_SPEED_PATH, .gpu_temp_path = TG5040_GPU_TEMP_PATH, + .gpu_speed_fixed = 660, + .gpu_freq_path = NULL, + .gpu_usage_path = NULL, .rumble_gpio_path = TG5040_RUMBLE_GPIO, }; static const DeviceDescriptor TG5040_SMART_PRO = { @@ -49,6 +52,9 @@ static const DeviceDescriptor TG5040_SMART_PRO = { .joy_l3 = JOY_NA, .joy_r3 = JOY_NA, .joy_plus = 128, .joy_minus = 129, .cpu_speed_path = TG5040_CPU_SPEED_PATH, .gpu_temp_path = TG5040_GPU_TEMP_PATH, + .gpu_speed_fixed = 660, + .gpu_freq_path = NULL, + .gpu_usage_path = NULL, .rumble_gpio_path = TG5040_RUMBLE_GPIO, }; // Default to Smart Pro so the geometry/button macros are valid even before @@ -167,7 +173,7 @@ void PLAT_getGPUTemp() { } void PLAT_getGPUSpeed() { - perf.gpu_speed = 660; // MHz + perf.gpu_speed = deviceModel->gpu_speed_fixed; // MHz } static struct WIFI_connection connection = { From 2098f94be074c61af9577221bea869ba7c7e483c Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sun, 5 Jul 2026 13:54:23 +0200 Subject: [PATCH 42/77] build: track header deps via -MMD -MP so common/*.h edits force rebuilds --- workspace/all/minarch/makefile | 9 ++++++--- workspace/all/nextui/makefile | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/workspace/all/minarch/makefile b/workspace/all/minarch/makefile index 0c6c3b2b0..7df9bc7b3 100644 --- a/workspace/all/minarch/makefile +++ b/workspace/all/minarch/makefile @@ -110,6 +110,7 @@ CFLAGS += -DBUILD_DATE=\"${BUILD_DATE}\" -DBUILD_HASH=\"${BUILD_HASH}\" OBJ_DIR = build/$(PLATFORM) OBJS = $(addprefix $(OBJ_DIR)/,$(notdir $(CSOURCE:.c=.o))) \ $(addprefix $(OBJ_DIR)/,$(notdir $(CXXSOURCE:.cpp=.o))) +DEPS = $(OBJS:.o=.d) # Locate sources across their directories so single pattern rules suffice. vpath %.c . ../common ../../$(PLATFORM)/platform @@ -144,10 +145,10 @@ $(PRODUCT): $(OBJS) $(CXX) $(OBJS) -o $(PRODUCT) $(LDFLAGS) -lstdc++ $(OBJ_DIR)/%.o: %.c | $(OBJ_DIR) - $(CC) $(CFLAGS) -c $< -o $@ + $(CC) $(CFLAGS) -MMD -MP -c $< -o $@ $(OBJ_DIR)/%.o: %.cpp | $(OBJ_DIR) - $(CXX) $(CXXFLAGS) -c $< -o $@ + $(CXX) $(CXXFLAGS) -MMD -MP -c $< -o $@ $(OBJ_DIR): mkdir -p $(OBJ_DIR) @@ -187,7 +188,9 @@ $(OBJECTS) : libsrm.a: $(OBJECTS) cd libretro-common && $(AR) $(ARFLAGS) $@ $? +-include $(DEPS) + clean: rm -f $(PRODUCT) - rm -f $(OBJS) + rm -f $(OBJS) $(DEPS) rm -f $(OBJECTS) $(LIBRARY) \ No newline at end of file diff --git a/workspace/all/nextui/makefile b/workspace/all/nextui/makefile index 4f94d5e9f..036a8dfa8 100644 --- a/workspace/all/nextui/makefile +++ b/workspace/all/nextui/makefile @@ -44,6 +44,7 @@ LDFLAGS += -lmsettings OBJ_DIR = build/$(PLATFORM) OBJS = $(addprefix $(OBJ_DIR)/,$(notdir $(CSOURCE:.c=.o))) \ $(addprefix $(OBJ_DIR)/,$(notdir $(CXXSOURCE:.cpp=.o))) +DEPS = $(OBJS:.o=.d) PRODUCT= build/$(PLATFORM)/$(TARGET).elf @@ -57,16 +58,18 @@ $(PRODUCT): $(OBJS) $(CXX) $(OBJS) -o $(PRODUCT) $(LDFLAGS) -lstdc++ $(OBJ_DIR)/%.o: %.c | $(OBJ_DIR) - $(CC) $(CFLAGS) -c $< -o $@ + $(CC) $(CFLAGS) -MMD -MP -c $< -o $@ $(OBJ_DIR)/%.o: %.cpp | $(OBJ_DIR) - $(CXX) $(CXXFLAGS) -c $< -o $@ + $(CXX) $(CXXFLAGS) -MMD -MP -c $< -o $@ $(OBJ_DIR): mkdir -p $(OBJ_DIR) +-include $(DEPS) + clean: - rm -f $(PRODUCT) $(OBJS) + rm -f $(PRODUCT) $(OBJS) $(DEPS) $(PREFIX_LOCAL)/include/msettings.h: cd ../../$(PLATFORM)/libmsettings && make From a90521b316573e8f5c7ed3449a934587bc269f1d Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sun, 5 Jul 2026 15:34:36 +0200 Subject: [PATCH 43/77] tg5050: migrate Smart Pro S onto shared DeviceDescriptor --- workspace/tg5050/platform/platform.c | 20 ++++++++++++++++++++ workspace/tg5050/platform/platform.h | 21 +++++++++++---------- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/workspace/tg5050/platform/platform.c b/workspace/tg5050/platform/platform.c index c20ebdc7c..279e57b03 100644 --- a/workspace/tg5050/platform/platform.c +++ b/workspace/tg5050/platform/platform.c @@ -17,6 +17,26 @@ #include "defines.h" #include "platform.h" + +// Smart Pro S device descriptor. Single model -- no runtime variant selector +// (unlike tg5040, which picks Brick vs Smart Pro from DEVICE=brick). +#define TG5050_CPU_SPEED_PATH "/sys/devices/system/cpu/cpu4/cpufreq/scaling_cur_freq" +#define TG5050_GPU_TEMP_PATH "/sys/devices/virtual/thermal/thermal_zone5/temp" +#define TG5050_GPU_FREQ_PATH "/sys/devices/platform/soc@3000000/1800000.gpu/devfreq/1800000.gpu/cur_freq" +#define TG5050_GPU_USAGE_PATH "/sys/devices/platform/soc@3000000/1800000.gpu/sunxi_gpu/sunxi_gpu_freq" +#define TG5050_RUMBLE_GPIO "/sys/class/gpio/gpio236/value" +static const DeviceDescriptor TG5050 = { + .scale = 2, .width = 1280, .height = 720, + .main_row_count = 10, .quick_switcher_count = 4, .padding = 10, + .joy_l3 = 9, .joy_r3 = 10, .joy_plus = 128, .joy_minus = 129, + .cpu_speed_path = TG5050_CPU_SPEED_PATH, + .gpu_temp_path = TG5050_GPU_TEMP_PATH, + .gpu_speed_fixed = 0, + .gpu_freq_path = TG5050_GPU_FREQ_PATH, + .gpu_usage_path = TG5050_GPU_USAGE_PATH, + .rumble_gpio_path = TG5050_RUMBLE_GPIO, +}; +const DeviceDescriptor* deviceModel = &TG5050; #include "api.h" #include "utils.h" diff --git a/workspace/tg5050/platform/platform.h b/workspace/tg5050/platform/platform.h index 7613920ab..39f0d1f3e 100644 --- a/workspace/tg5050/platform/platform.h +++ b/workspace/tg5050/platform/platform.h @@ -2,6 +2,7 @@ #ifndef PLATFORM_H #define PLATFORM_H +#include "device.h" /////////////////////////////// @@ -86,13 +87,13 @@ #define JOY_R1 5 #define JOY_L2 JOY_NA #define JOY_R2 JOY_NA -#define JOY_L3 9 -#define JOY_R3 10 +#define JOY_L3 (deviceModel->joy_l3) +#define JOY_R3 (deviceModel->joy_r3) #define JOY_MENU 8 #define JOY_POWER 102 -#define JOY_PLUS 128 -#define JOY_MINUS 129 +#define JOY_PLUS (deviceModel->joy_plus) +#define JOY_MINUS (deviceModel->joy_minus) /////////////////////////////// @@ -117,9 +118,9 @@ /////////////////////////////// -#define FIXED_SCALE 2 -#define FIXED_WIDTH 1280 -#define FIXED_HEIGHT 720 +#define FIXED_SCALE (deviceModel->scale) +#define FIXED_WIDTH (deviceModel->width) +#define FIXED_HEIGHT (deviceModel->height) #define FIXED_BPP 2 #define FIXED_DEPTH (FIXED_BPP * 8) #define FIXED_PITCH (FIXED_WIDTH * FIXED_BPP) @@ -127,9 +128,9 @@ /////////////////////////////// -#define MAIN_ROW_COUNT 10 -#define QUICK_SWITCHER_COUNT 4 -#define PADDING 10 +#define MAIN_ROW_COUNT (deviceModel->main_row_count) +#define QUICK_SWITCHER_COUNT (deviceModel->quick_switcher_count) +#define PADDING (deviceModel->padding) /////////////////////////////// From 7df9a5ade61500172ab5b5418cd4eca43a706896 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sun, 5 Jul 2026 15:44:11 +0200 Subject: [PATCH 44/77] platform: converge CPU/GPU freq+temp reads onto descriptor paths --- workspace/tg5040/platform/platform.c | 2 +- workspace/tg5050/platform/platform.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/workspace/tg5040/platform/platform.c b/workspace/tg5040/platform/platform.c index ff502f47a..33e32188d 100644 --- a/workspace/tg5040/platform/platform.c +++ b/workspace/tg5040/platform/platform.c @@ -173,7 +173,7 @@ void PLAT_getGPUTemp() { } void PLAT_getGPUSpeed() { - perf.gpu_speed = deviceModel->gpu_speed_fixed; // MHz + perf.gpu_speed = deviceModel->gpu_freq_path ? getInt(deviceModel->gpu_freq_path)/1000000 : deviceModel->gpu_speed_fixed; // MHz } static struct WIFI_connection connection = { diff --git a/workspace/tg5050/platform/platform.c b/workspace/tg5050/platform/platform.c index 279e57b03..1af0c76de 100644 --- a/workspace/tg5050/platform/platform.c +++ b/workspace/tg5050/platform/platform.c @@ -140,15 +140,15 @@ void PLAT_getCPUTemp() { void PLAT_getCPUSpeed() { - perf.cpu_speed = getInt("/sys/devices/system/cpu/cpu4/cpufreq/scaling_cur_freq")/1000; + perf.cpu_speed = getInt(deviceModel->cpu_speed_path)/1000; } void PLAT_getGPUTemp() { - perf.gpu_temp = getInt("/sys/devices/virtual/thermal/thermal_zone5/temp")/1000; + perf.gpu_temp = getInt(deviceModel->gpu_temp_path)/1000; } void PLAT_getGPUSpeed() { - perf.gpu_speed = getInt("/sys/devices/platform/soc@3000000/1800000.gpu/devfreq/1800000.gpu/cur_freq")/1000000; + perf.gpu_speed = deviceModel->gpu_freq_path ? getInt(deviceModel->gpu_freq_path)/1000000 : deviceModel->gpu_speed_fixed; // MHz } void PLAT_getGPUUsage() { From d3b4ecfdea09a143c97a80581ad099703d5ae960 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sun, 5 Jul 2026 16:13:01 +0200 Subject: [PATCH 45/77] platform: extract 28 shared PLAT_ funcs into common/generic_platform.c --- workspace/all/common/generic_platform.c | 399 ++++++++++++++++++++++++ workspace/tg5040/platform/platform.c | 366 +--------------------- workspace/tg5050/platform/platform.c | 366 +--------------------- 3 files changed, 401 insertions(+), 730 deletions(-) create mode 100644 workspace/all/common/generic_platform.c diff --git a/workspace/all/common/generic_platform.c b/workspace/all/common/generic_platform.c new file mode 100644 index 000000000..a3f305d81 --- /dev/null +++ b/workspace/all/common/generic_platform.c @@ -0,0 +1,399 @@ +// generic_platform.c -- PLAT_ functions identical across tg5040 and tg5050. +// Text-included near the end of each platform's platform.c (after the file-local +// static helpers and globals it references). Phase C device-HAL dedup: divergent +// functions (LEDs, timezones, NTP, rumble, model, input init) stay per-platform; +// a new device only reimplements those. + +void PLAT_quitInput(void) { + if (joysticks) { + for (int i = 0; i < num_joysticks; i++) { + if (SDL_JoystickGetAttached(joysticks[i])) { + LOG_info("Closing joystick %d: %s\n", i, SDL_JoystickName(joysticks[i])); + SDL_JoystickClose(joysticks[i]); + } + } + free(joysticks); + joysticks = NULL; + num_joysticks = 0; + } + SDL_QuitSubSystem(SDL_INIT_JOYSTICK); +} + +void PLAT_updateInput(const SDL_Event *event) { + switch (event->type) { + case SDL_JOYDEVICEADDED: { + int device_index = event->jdevice.which; + SDL_Joystick *new_joy = SDL_JoystickOpen(device_index); + if (new_joy) { + joysticks = realloc(joysticks, sizeof(SDL_Joystick *) * (num_joysticks + 1)); + joysticks[num_joysticks++] = new_joy; + LOG_info("Joystick added at index %d: %s\n", device_index, SDL_JoystickName(new_joy)); + } else { + LOG_error("Failed to open added joystick at index %d: %s\n", device_index, SDL_GetError()); + } + break; + } + + case SDL_JOYDEVICEREMOVED: { + SDL_JoystickID removed_id = event->jdevice.which; + for (int i = 0; i < num_joysticks; ++i) { + if (SDL_JoystickInstanceID(joysticks[i]) == removed_id) { + LOG_info("Joystick removed: %s\n", SDL_JoystickName(joysticks[i])); + SDL_JoystickClose(joysticks[i]); + + // Shift down the remaining entries + for (int j = i; j < num_joysticks - 1; ++j) + joysticks[j] = joysticks[j + 1]; + num_joysticks--; + + if (num_joysticks == 0) { + free(joysticks); + joysticks = NULL; + } else { + joysticks = realloc(joysticks, sizeof(SDL_Joystick *) * num_joysticks); + } + break; + } + } + break; + } + + default: + break; + } +} + +void PLAT_getBatteryStatus(int* is_charging, int* charge) { + PLAT_getBatteryStatusFine(is_charging, charge); + + // worry less about battery and more about the game you're playing + if (*charge>80) *charge = 100; + else if (*charge>60) *charge = 80; + else if (*charge>40) *charge = 60; + else if (*charge>20) *charge = 40; + else if (*charge>10) *charge = 20; + else *charge = 10; +} + +void PLAT_getCPUTemp() { + perf.cpu_temp = getInt("/sys/devices/virtual/thermal/thermal_zone0/temp")/1000; +} + +void PLAT_getCPUSpeed() +{ + perf.cpu_speed = getInt(deviceModel->cpu_speed_path)/1000; +} + +void PLAT_getGPUTemp() { + perf.gpu_temp = getInt(deviceModel->gpu_temp_path)/1000; +} + +void PLAT_getGPUSpeed() { + perf.gpu_speed = deviceModel->gpu_freq_path ? getInt(deviceModel->gpu_freq_path)/1000000 : deviceModel->gpu_speed_fixed; // MHz +} + +void PLAT_getNetworkStatus(int* is_online) +{ + if(WIFI_enabled()) + WIFI_connectionInfo(&connection); + else + connection_reset(&connection); + + if(is_online) + *is_online = (connection.valid && connection.ssid[0] != '\0'); + + if(BT_enabled()) { + bluetoothConnected = PLAT_bluetoothConnected(); + } + else + bluetoothConnected = false; +} + +void PLAT_getBatteryStatusFine(int *is_charging, int *charge) +{ + if(is_charging) { + int time_to_full = getInt("/sys/class/power_supply/axp2202-battery/time_to_full_now"); + int charger_present = getInt("/sys/class/power_supply/axp2202-usb/online"); + *is_charging = (charger_present == 1) && (time_to_full > 0); + } + if(charge) { + *charge = getInt("/sys/class/power_supply/axp2202-battery/capacity"); + } +} + +void PLAT_powerOff(int reboot) { + if (CFG_getHaptics()) { + VIB_singlePulse(VIB_bootStrength, VIB_bootDuration_ms); + } + system("rm -f /tmp/nextui_exec && sync"); + sleep(2); + + SetRawVolume(MUTE_VOLUME_RAW); + PLAT_enableBacklight(0); + SND_quit(); + VIB_quit(); + PWR_quit(); + GFX_quit(); + + system("cat /dev/zero > /dev/fb0 2>/dev/null"); + if(reboot > 0) + touch("/tmp/reboot"); + else + touch("/tmp/poweroff"); + sync(); + exit(0); +} + +int PLAT_supportsDeepSleep(void) { return 1; } + +void *PLAT_cpu_monitor(void *arg) { + if (!Perf_tryBeginCPUMonitor()) return NULL; + + double prev_real_time = get_time_sec(); + double prev_cpu_time = get_process_cpu_time_sec(); + + double cpu_usage_history[ROLLING_WINDOW] = {0}; + int history_index = 0; + int history_count = 0; + + while (Perf_isCPUMonitorEnabled()) { + double curr_real_time = get_time_sec(); + double curr_cpu_time = get_process_cpu_time_sec(); + + double elapsed_real_time = curr_real_time - prev_real_time; + double elapsed_cpu_time = curr_cpu_time - prev_cpu_time; + + if (elapsed_real_time > 0) { + double cpu_usage = (elapsed_cpu_time / elapsed_real_time) * 100.0; + + pthread_mutex_lock(¤tcpuinfo); + + cpu_usage_history[history_index] = cpu_usage; + history_index = (history_index + 1) % ROLLING_WINDOW; + if (history_count < ROLLING_WINDOW) history_count++; + + double sum_cpu_usage = 0; + for (int i = 0; i < history_count; i++) sum_cpu_usage += cpu_usage_history[i]; + perf.cpu_usage = sum_cpu_usage / history_count; + + pthread_mutex_unlock(¤tcpuinfo); + } + + prev_real_time = curr_real_time; + prev_cpu_time = curr_cpu_time; + usleep(100000); + } + + Perf_endCPUMonitor(); + return NULL; +} + +void PLAT_setCPUSpeed(int speed) { + const char* mode; + switch (speed) { + case CPU_SPEED_AUTO: mode = "auto"; break; + case CPU_SPEED_PERFORMANCE: mode = "performance"; break; + case CPU_SPEED_POWERSAVE: mode = "powersave"; break; + default: return; + } + + const char* system_path = getenv("SYSTEM_PATH"); + if (!system_path) { + LOG_info("WARNING: SYSTEM_PATH not set, cannot run governor script\n"); + return; + } + char cmd[512]; + int n = snprintf(cmd, sizeof(cmd), "sh \"%s/bin/governor.sh\" \"%s\"", system_path, mode); + if (n < 0 || n >= (int)sizeof(cmd)) { + LOG_info("WARNING: SYSTEM_PATH too long for governor script path\n"); + return; + } + int ret = system(cmd); + if (ret != 0) LOG_info("WARNING: governor script exited with status %d for mode '%s'\n", ret, mode); +} + +int PLAT_pickSampleRate(int requested, int max) { + // bluetooth: allow limiting the maximum to improve compatibility + if(PLAT_bluetoothConnected()) + return MIN(requested, CFG_getBluetoothSamplingrateLimit()); + + return MIN(requested, max); +} + +void PLAT_overrideMute(int mute) { + putInt("/sys/class/speaker/mute", mute); +} + +void PLAT_getOsVersionInfo(char* output_str, size_t max_len) +{ + return getFile("/etc/version", output_str,max_len); +} + +bool PLAT_btIsConnected(void) +{ + return bluetoothConnected; +} + +ConnectionStrength PLAT_connectionStrength(void) { + if(!WIFI_enabled() || !connection.valid || connection.rssi == -1) + return SIGNAL_STRENGTH_OFF; + else if (connection.rssi == 0) + return SIGNAL_STRENGTH_DISCONNECTED; + else if (connection.rssi >= -60) + return SIGNAL_STRENGTH_HIGH; + else if (connection.rssi >= -70) + return SIGNAL_STRENGTH_MED; + else + return SIGNAL_STRENGTH_LOW; +} + +void PLAT_setLedEffect(LightSettings *led) +{ + char filepath[256]; + FILE *file; + // first set brightness + snprintf(filepath, sizeof(filepath), "/sys/class/led_anim/effect_%s", led->filename); + file = fopen(filepath, "w"); + if (file != NULL) + { + fprintf(file, "%i\n", led->effect); + fclose(file); + } +} + +void PLAT_setLedEffectCycles(LightSettings *led) +{ + char filepath[256]; + FILE *file; + // first set brightness + snprintf(filepath, sizeof(filepath), "/sys/class/led_anim/effect_cycles_%s", led->filename); + file = fopen(filepath, "w"); + if (file != NULL) + { + fprintf(file, "%i\n", led->cycles); + fclose(file); + } +} + +void PLAT_setLedEffectSpeed(LightSettings *led) +{ + char filepath[256]; + FILE *file; + // first set brightness + snprintf(filepath, sizeof(filepath), "/sys/class/led_anim/effect_duration_%s", led->filename); + file = fopen(filepath, "w"); + if (file != NULL) + { + fprintf(file, "%i\n", led->speed); + fclose(file); + } +} + +void PLAT_setLedColor(LightSettings *led) +{ + char filepath[256]; + FILE *file; + // first set brightness + snprintf(filepath, sizeof(filepath), "/sys/class/led_anim/effect_rgb_hex_%s", led->filename); + file = fopen(filepath, "w"); + if (file != NULL) + { + fprintf(file, "%06X\n", led->color1); + fclose(file); + } +} + +bool PLAT_canTurbo(void) { return true; } + +int PLAT_toggleTurbo(int btn_id) +{ + // avoid extra file IO on each call + static int initialized = 0; + if (!initialized) { + mkdir(INPUTD_PATH, 0755); + initialized = 1; + } + + for (int i = 0; turbo_mapping[i].path; i++) { + if (turbo_mapping[i].brn_id == btn_id) { + return toggle_file(turbo_mapping[i].path); + } + } + return 0; +} + +void PLAT_clearTurbo() { + for (int i = 0; turbo_mapping[i].path; i++) { + unlink(turbo_mapping[i].path); + } +} + +int PLAT_setDateTime(int y, int m, int d, int h, int i, int s) { + char cmd[512]; + sprintf(cmd, "date -s '%d-%d-%d %d:%d:%d'; hwclock -u -w", y,m,d,h,i,s); + system(cmd); + return 0; // why does this return an int? +} + +void PLAT_initTimezones() { + if (cached_tz_count != -1) { // Already initialized + return; + } + + FILE *file = fopen(ZONE_TAB_PATH, "r"); + if (!file) { + LOG_info("Error opening file %s\n", ZONE_TAB_PATH); + return; + } + + char line[MAX_LINE_LENGTH]; + cached_tz_count = 0; + + while (fgets(line, sizeof(line), file)) { + // Skip comment lines + if (line[0] == '#' || strlen(line) < 3) { + continue; + } + + char *token = strtok(line, "\t"); // Skip country code + if (!token) continue; + + token = strtok(NULL, "\t"); // Skip latitude/longitude + if (!token) continue; + + token = strtok(NULL, "\t\n"); // Extract timezone + if (!token) continue; + + // Check for duplicates before adding + int duplicate = 0; + for (int i = 0; i < cached_tz_count; i++) { + if (strcmp(cached_timezones[i], token) == 0) { + duplicate = 1; + break; + } + } + + if (!duplicate && cached_tz_count < MAX_TIMEZONES) { + strncpy(cached_timezones[cached_tz_count], token, MAX_TZ_LENGTH - 1); + cached_timezones[cached_tz_count][MAX_TZ_LENGTH - 1] = '\0'; // Ensure null-termination + cached_tz_count++; + } + } + + fclose(file); + + // Sort the list alphabetically + qsort(cached_timezones, cached_tz_count, MAX_TZ_LENGTH, compare_timezones); +} + +void PLAT_getTimezones(char timezones[MAX_TIMEZONES][MAX_TZ_LENGTH], int *tz_count) { + if (cached_tz_count == -1) { + LOG_warn("Error: Timezones not initialized. Call PLAT_initTimezones first.\n"); + *tz_count = 0; + return; + } + + memcpy(timezones, cached_timezones, sizeof(cached_timezones)); + *tz_count = cached_tz_count; +} + diff --git a/workspace/tg5040/platform/platform.c b/workspace/tg5040/platform/platform.c index 33e32188d..c05827e00 100644 --- a/workspace/tg5040/platform/platform.c +++ b/workspace/tg5040/platform/platform.c @@ -88,93 +88,12 @@ void PLAT_initInput(void) { } } -void PLAT_quitInput(void) { - if (joysticks) { - for (int i = 0; i < num_joysticks; i++) { - if (SDL_JoystickGetAttached(joysticks[i])) { - LOG_info("Closing joystick %d: %s\n", i, SDL_JoystickName(joysticks[i])); - SDL_JoystickClose(joysticks[i]); - } - } - free(joysticks); - joysticks = NULL; - num_joysticks = 0; - } - SDL_QuitSubSystem(SDL_INIT_JOYSTICK); -} -void PLAT_updateInput(const SDL_Event *event) { - switch (event->type) { - case SDL_JOYDEVICEADDED: { - int device_index = event->jdevice.which; - SDL_Joystick *new_joy = SDL_JoystickOpen(device_index); - if (new_joy) { - joysticks = realloc(joysticks, sizeof(SDL_Joystick *) * (num_joysticks + 1)); - joysticks[num_joysticks++] = new_joy; - LOG_info("Joystick added at index %d: %s\n", device_index, SDL_JoystickName(new_joy)); - } else { - LOG_error("Failed to open added joystick at index %d: %s\n", device_index, SDL_GetError()); - } - break; - } - case SDL_JOYDEVICEREMOVED: { - SDL_JoystickID removed_id = event->jdevice.which; - for (int i = 0; i < num_joysticks; ++i) { - if (SDL_JoystickInstanceID(joysticks[i]) == removed_id) { - LOG_info("Joystick removed: %s\n", SDL_JoystickName(joysticks[i])); - SDL_JoystickClose(joysticks[i]); - - // Shift down the remaining entries - for (int j = i; j < num_joysticks - 1; ++j) - joysticks[j] = joysticks[j + 1]; - num_joysticks--; - - if (num_joysticks == 0) { - free(joysticks); - joysticks = NULL; - } else { - joysticks = realloc(joysticks, sizeof(SDL_Joystick *) * num_joysticks); - } - break; - } - } - break; - } - default: - break; - } -} -void PLAT_getBatteryStatus(int* is_charging, int* charge) { - PLAT_getBatteryStatusFine(is_charging, charge); - // worry less about battery and more about the game you're playing - if (*charge>80) *charge = 100; - else if (*charge>60) *charge = 80; - else if (*charge>40) *charge = 60; - else if (*charge>20) *charge = 40; - else if (*charge>10) *charge = 20; - else *charge = 10; -} -void PLAT_getCPUTemp() { - perf.cpu_temp = getInt("/sys/devices/virtual/thermal/thermal_zone0/temp")/1000; -} - -void PLAT_getCPUSpeed() -{ - perf.cpu_speed = getInt(deviceModel->cpu_speed_path)/1000; -} - -void PLAT_getGPUTemp() { - perf.gpu_temp = getInt(deviceModel->gpu_temp_path)/1000; -} - -void PLAT_getGPUSpeed() { - perf.gpu_speed = deviceModel->gpu_freq_path ? getInt(deviceModel->gpu_freq_path)/1000000 : deviceModel->gpu_speed_fixed; // MHz -} static struct WIFI_connection connection = { .valid = false, @@ -199,34 +118,7 @@ static inline void connection_reset(struct WIFI_connection *connection_info) static bool bluetoothConnected = false; -void PLAT_getNetworkStatus(int* is_online) -{ - if(WIFI_enabled()) - WIFI_connectionInfo(&connection); - else - connection_reset(&connection); - - if(is_online) - *is_online = (connection.valid && connection.ssid[0] != '\0'); - - if(BT_enabled()) { - bluetoothConnected = PLAT_bluetoothConnected(); - } - else - bluetoothConnected = false; -} -void PLAT_getBatteryStatusFine(int *is_charging, int *charge) -{ - if(is_charging) { - int time_to_full = getInt("/sys/class/power_supply/axp2202-battery/time_to_full_now"); - int charger_present = getInt("/sys/class/power_supply/axp2202-usb/online"); - *is_charging = (charger_present == 1) && (time_to_full > 0); - } - if(charge) { - *charge = getInt("/sys/class/power_supply/axp2202-battery/capacity"); - } -} void PLAT_enableBacklight(int enable) { if (enable) { @@ -238,30 +130,7 @@ void PLAT_enableBacklight(int enable) { } } -void PLAT_powerOff(int reboot) { - if (CFG_getHaptics()) { - VIB_singlePulse(VIB_bootStrength, VIB_bootDuration_ms); - } - system("rm -f /tmp/nextui_exec && sync"); - sleep(2); - - SetRawVolume(MUTE_VOLUME_RAW); - PLAT_enableBacklight(0); - SND_quit(); - VIB_quit(); - PWR_quit(); - GFX_quit(); - - system("cat /dev/zero > /dev/fb0 2>/dev/null"); - if(reboot > 0) - touch("/tmp/reboot"); - else - touch("/tmp/poweroff"); - sync(); - exit(0); -} -int PLAT_supportsDeepSleep(void) { return 1; } /////////////////////////////// @@ -283,71 +152,7 @@ static pthread_mutex_t currentcpuinfo; // a roling average for the display values of about 2 frames, otherwise they are unreadable jumping too fast up and down and stuff to read #define ROLLING_WINDOW 120 -void *PLAT_cpu_monitor(void *arg) { - if (!Perf_tryBeginCPUMonitor()) return NULL; - - double prev_real_time = get_time_sec(); - double prev_cpu_time = get_process_cpu_time_sec(); - - double cpu_usage_history[ROLLING_WINDOW] = {0}; - int history_index = 0; - int history_count = 0; - - while (Perf_isCPUMonitorEnabled()) { - double curr_real_time = get_time_sec(); - double curr_cpu_time = get_process_cpu_time_sec(); - - double elapsed_real_time = curr_real_time - prev_real_time; - double elapsed_cpu_time = curr_cpu_time - prev_cpu_time; - - if (elapsed_real_time > 0) { - double cpu_usage = (elapsed_cpu_time / elapsed_real_time) * 100.0; - - pthread_mutex_lock(¤tcpuinfo); - - cpu_usage_history[history_index] = cpu_usage; - history_index = (history_index + 1) % ROLLING_WINDOW; - if (history_count < ROLLING_WINDOW) history_count++; - - double sum_cpu_usage = 0; - for (int i = 0; i < history_count; i++) sum_cpu_usage += cpu_usage_history[i]; - perf.cpu_usage = sum_cpu_usage / history_count; - - pthread_mutex_unlock(¤tcpuinfo); - } - - prev_real_time = curr_real_time; - prev_cpu_time = curr_cpu_time; - usleep(100000); - } - - Perf_endCPUMonitor(); - return NULL; -} -void PLAT_setCPUSpeed(int speed) { - const char* mode; - switch (speed) { - case CPU_SPEED_AUTO: mode = "auto"; break; - case CPU_SPEED_PERFORMANCE: mode = "performance"; break; - case CPU_SPEED_POWERSAVE: mode = "powersave"; break; - default: return; - } - - const char* system_path = getenv("SYSTEM_PATH"); - if (!system_path) { - LOG_info("WARNING: SYSTEM_PATH not set, cannot run governor script\n"); - return; - } - char cmd[512]; - int n = snprintf(cmd, sizeof(cmd), "sh \"%s/bin/governor.sh\" \"%s\"", system_path, mode); - if (n < 0 || n >= (int)sizeof(cmd)) { - LOG_info("WARNING: SYSTEM_PATH too long for governor script path\n"); - return; - } - int ret = system(cmd); - if (ret != 0) LOG_info("WARNING: governor script exited with status %d for mode '%s'\n", ret, mode); -} #define MAX_STRENGTH 0xFFFF #define MIN_VOLTAGE 500000 @@ -370,17 +175,7 @@ void PLAT_setRumble(int strength) { putInt(deviceModel->rumble_gpio_path, (strength) ? 1 : 0); } -int PLAT_pickSampleRate(int requested, int max) { - // bluetooth: allow limiting the maximum to improve compatibility - if(PLAT_bluetoothConnected()) - return MIN(requested, CFG_getBluetoothSamplingrateLimit()); - - return MIN(requested, max); -} -void PLAT_overrideMute(int mute) { - putInt("/sys/class/speaker/mute", mute); -} char* PLAT_getModel(void) { char* model = getenv("TRIMUI_MODEL"); @@ -388,28 +183,8 @@ char* PLAT_getModel(void) { return "Trimui Smart Pro"; } -void PLAT_getOsVersionInfo(char* output_str, size_t max_len) -{ - return getFile("/etc/version", output_str,max_len); -} -bool PLAT_btIsConnected(void) -{ - return bluetoothConnected; -} -ConnectionStrength PLAT_connectionStrength(void) { - if(!WIFI_enabled() || !connection.valid || connection.rssi == -1) - return SIGNAL_STRENGTH_OFF; - else if (connection.rssi == 0) - return SIGNAL_STRENGTH_DISCONNECTED; - else if (connection.rssi >= -60) - return SIGNAL_STRENGTH_HIGH; - else if (connection.rssi >= -70) - return SIGNAL_STRENGTH_MED; - else - return SIGNAL_STRENGTH_LOW; -} void PLAT_initDefaultLeds() { resolveDeviceModel(); @@ -665,62 +440,9 @@ void PLAT_setLedBrightness(LightSettings *led) } } } -void PLAT_setLedEffect(LightSettings *led) -{ - char filepath[256]; - FILE *file; - // first set brightness - snprintf(filepath, sizeof(filepath), "/sys/class/led_anim/effect_%s", led->filename); - file = fopen(filepath, "w"); - if (file != NULL) - { - fprintf(file, "%i\n", led->effect); - fclose(file); - } -} -void PLAT_setLedEffectCycles(LightSettings *led) -{ - char filepath[256]; - FILE *file; - // first set brightness - snprintf(filepath, sizeof(filepath), "/sys/class/led_anim/effect_cycles_%s", led->filename); - file = fopen(filepath, "w"); - if (file != NULL) - { - fprintf(file, "%i\n", led->cycles); - fclose(file); - } -} -void PLAT_setLedEffectSpeed(LightSettings *led) -{ - char filepath[256]; - FILE *file; - // first set brightness - snprintf(filepath, sizeof(filepath), "/sys/class/led_anim/effect_duration_%s", led->filename); - file = fopen(filepath, "w"); - if (file != NULL) - { - fprintf(file, "%i\n", led->speed); - fclose(file); - } -} -void PLAT_setLedColor(LightSettings *led) -{ - char filepath[256]; - FILE *file; - // first set brightness - snprintf(filepath, sizeof(filepath), "/sys/class/led_anim/effect_rgb_hex_%s", led->filename); - file = fopen(filepath, "w"); - if (file != NULL) - { - fprintf(file, "%06X\n", led->color1); - fclose(file); - } -} ////////////////////////////////////////////// -bool PLAT_canTurbo(void) { return true; } #define INPUTD_PATH "/tmp/trimui_inputd" @@ -755,37 +477,10 @@ int toggle_file(const char *path) { } } -int PLAT_toggleTurbo(int btn_id) -{ - // avoid extra file IO on each call - static int initialized = 0; - if (!initialized) { - mkdir(INPUTD_PATH, 0755); - initialized = 1; - } - for (int i = 0; turbo_mapping[i].path; i++) { - if (turbo_mapping[i].brn_id == btn_id) { - return toggle_file(turbo_mapping[i].path); - } - } - return 0; -} - -void PLAT_clearTurbo() { - for (int i = 0; turbo_mapping[i].path; i++) { - unlink(turbo_mapping[i].path); - } -} ////////////////////////////////////////////// -int PLAT_setDateTime(int y, int m, int d, int h, int i, int s) { - char cmd[512]; - sprintf(cmd, "date -s '%d-%d-%d %d:%d:%d'; hwclock -u -w", y,m,d,h,i,s); - system(cmd); - return 0; // why does this return an int? -} #define MAX_LINE_LENGTH 200 #define ZONE_PATH "/usr/share/zoneinfo" @@ -798,67 +493,7 @@ int compare_timezones(const void *a, const void *b) { return strcmp((const char *)a, (const char *)b); } -void PLAT_initTimezones() { - if (cached_tz_count != -1) { // Already initialized - return; - } - - FILE *file = fopen(ZONE_TAB_PATH, "r"); - if (!file) { - LOG_info("Error opening file %s\n", ZONE_TAB_PATH); - return; - } - - char line[MAX_LINE_LENGTH]; - cached_tz_count = 0; - - while (fgets(line, sizeof(line), file)) { - // Skip comment lines - if (line[0] == '#' || strlen(line) < 3) { - continue; - } - - char *token = strtok(line, "\t"); // Skip country code - if (!token) continue; - - token = strtok(NULL, "\t"); // Skip latitude/longitude - if (!token) continue; - - token = strtok(NULL, "\t\n"); // Extract timezone - if (!token) continue; - - // Check for duplicates before adding - int duplicate = 0; - for (int i = 0; i < cached_tz_count; i++) { - if (strcmp(cached_timezones[i], token) == 0) { - duplicate = 1; - break; - } - } - - if (!duplicate && cached_tz_count < MAX_TIMEZONES) { - strncpy(cached_timezones[cached_tz_count], token, MAX_TZ_LENGTH - 1); - cached_timezones[cached_tz_count][MAX_TZ_LENGTH - 1] = '\0'; // Ensure null-termination - cached_tz_count++; - } - } - - fclose(file); - - // Sort the list alphabetically - qsort(cached_timezones, cached_tz_count, MAX_TZ_LENGTH, compare_timezones); -} -void PLAT_getTimezones(char timezones[MAX_TIMEZONES][MAX_TZ_LENGTH], int *tz_count) { - if (cached_tz_count == -1) { - LOG_warn("Error: Timezones not initialized. Call PLAT_initTimezones first.\n"); - *tz_count = 0; - return; - } - - memcpy(timezones, cached_timezones, sizeof(cached_timezones)); - *tz_count = cached_tz_count; -} char *PLAT_getCurrentTimezone() { @@ -949,6 +584,7 @@ void PLAT_setNetworkTimeSync(bool on) { ///////////////////////// // We use the generic video implementation here +#include "generic_platform.c" #include "generic_video.c" ///////////////////////// diff --git a/workspace/tg5050/platform/platform.c b/workspace/tg5050/platform/platform.c index 1af0c76de..b45e53db4 100644 --- a/workspace/tg5050/platform/platform.c +++ b/workspace/tg5050/platform/platform.c @@ -61,95 +61,14 @@ void PLAT_initInput(void) { } } -void PLAT_quitInput(void) { - if (joysticks) { - for (int i = 0; i < num_joysticks; i++) { - if (SDL_JoystickGetAttached(joysticks[i])) { - LOG_info("Closing joystick %d: %s\n", i, SDL_JoystickName(joysticks[i])); - SDL_JoystickClose(joysticks[i]); - } - } - free(joysticks); - joysticks = NULL; - num_joysticks = 0; - } - SDL_QuitSubSystem(SDL_INIT_JOYSTICK); -} -void PLAT_updateInput(const SDL_Event *event) { - switch (event->type) { - case SDL_JOYDEVICEADDED: { - int device_index = event->jdevice.which; - SDL_Joystick *new_joy = SDL_JoystickOpen(device_index); - if (new_joy) { - joysticks = realloc(joysticks, sizeof(SDL_Joystick *) * (num_joysticks + 1)); - joysticks[num_joysticks++] = new_joy; - LOG_info("Joystick added at index %d: %s\n", device_index, SDL_JoystickName(new_joy)); - } else { - LOG_error("Failed to open added joystick at index %d: %s\n", device_index, SDL_GetError()); - } - break; - } - - case SDL_JOYDEVICEREMOVED: { - SDL_JoystickID removed_id = event->jdevice.which; - for (int i = 0; i < num_joysticks; ++i) { - if (SDL_JoystickInstanceID(joysticks[i]) == removed_id) { - LOG_info("Joystick removed: %s\n", SDL_JoystickName(joysticks[i])); - SDL_JoystickClose(joysticks[i]); - - // Shift down the remaining entries - for (int j = i; j < num_joysticks - 1; ++j) - joysticks[j] = joysticks[j + 1]; - num_joysticks--; - - if (num_joysticks == 0) { - free(joysticks); - joysticks = NULL; - } else { - joysticks = realloc(joysticks, sizeof(SDL_Joystick *) * num_joysticks); - } - break; - } - } - break; - } - - default: - break; - } -} /////////////////////////////// -void PLAT_getBatteryStatus(int* is_charging, int* charge) { - PLAT_getBatteryStatusFine(is_charging, charge); - // worry less about battery and more about the game you're playing - if (*charge>80) *charge = 100; - else if (*charge>60) *charge = 80; - else if (*charge>40) *charge = 60; - else if (*charge>20) *charge = 40; - else if (*charge>10) *charge = 20; - else *charge = 10; -} - -void PLAT_getCPUTemp() { - perf.cpu_temp = getInt("/sys/devices/virtual/thermal/thermal_zone0/temp")/1000; -} -void PLAT_getCPUSpeed() -{ - perf.cpu_speed = getInt(deviceModel->cpu_speed_path)/1000; -} -void PLAT_getGPUTemp() { - perf.gpu_temp = getInt(deviceModel->gpu_temp_path)/1000; -} -void PLAT_getGPUSpeed() { - perf.gpu_speed = deviceModel->gpu_freq_path ? getInt(deviceModel->gpu_freq_path)/1000000 : deviceModel->gpu_speed_fixed; // MHz -} void PLAT_getGPUUsage() { // cat /sys/devices/platform/soc@3000000/1800000.gpu/sunxi_gpu/sunxi_gpu_freq | grep -o '[0-9]*%' | tr -d '%' @@ -206,33 +125,6 @@ static inline void connection_reset(struct WIFI_connection *connection_info) static bool bluetoothConnected = false; -void PLAT_getNetworkStatus(int* is_online) -{ - if(WIFI_enabled()) - WIFI_connectionInfo(&connection); - else - connection_reset(&connection); - - if(is_online) - *is_online = (connection.valid && connection.ssid[0] != '\0'); - - if(BT_enabled()) { - bluetoothConnected = PLAT_bluetoothConnected(); - } - else - bluetoothConnected = false; -} -void PLAT_getBatteryStatusFine(int *is_charging, int *charge) -{ - if(is_charging) { - int time_to_full = getInt("/sys/class/power_supply/axp2202-battery/time_to_full_now"); - int charger_present = getInt("/sys/class/power_supply/axp2202-usb/online"); - *is_charging = (charger_present == 1) && (time_to_full > 0); - } - if(charge) { - *charge = getInt("/sys/class/power_supply/axp2202-battery/capacity"); - } -} void PLAT_enableBacklight(int enable) { if (enable) { @@ -243,30 +135,7 @@ void PLAT_enableBacklight(int enable) { } } -void PLAT_powerOff(int reboot) { - if (CFG_getHaptics()) { - VIB_singlePulse(VIB_bootStrength, VIB_bootDuration_ms); - } - system("rm -f /tmp/nextui_exec && sync"); - sleep(2); - - SetRawVolume(MUTE_VOLUME_RAW); - PLAT_enableBacklight(0); - SND_quit(); - VIB_quit(); - PWR_quit(); - GFX_quit(); - - system("cat /dev/zero > /dev/fb0 2>/dev/null"); - if(reboot > 0) - touch("/tmp/reboot"); - else - touch("/tmp/poweroff"); - sync(); - exit(0); -} -int PLAT_supportsDeepSleep(void) { return 1; } /////////////////////////////// @@ -308,71 +177,7 @@ void PLAT_pinToCores(int core_type) LOG_error("Failed to pin: Are all cores sleeping?\n"); } -void *PLAT_cpu_monitor(void *arg) { - if (!Perf_tryBeginCPUMonitor()) return NULL; - - double prev_real_time = get_time_sec(); - double prev_cpu_time = get_process_cpu_time_sec(); - - double cpu_usage_history[ROLLING_WINDOW] = {0}; - int history_index = 0; - int history_count = 0; - - while (Perf_isCPUMonitorEnabled()) { - double curr_real_time = get_time_sec(); - double curr_cpu_time = get_process_cpu_time_sec(); - - double elapsed_real_time = curr_real_time - prev_real_time; - double elapsed_cpu_time = curr_cpu_time - prev_cpu_time; - - if (elapsed_real_time > 0) { - double cpu_usage = (elapsed_cpu_time / elapsed_real_time) * 100.0; - - pthread_mutex_lock(¤tcpuinfo); - cpu_usage_history[history_index] = cpu_usage; - history_index = (history_index + 1) % ROLLING_WINDOW; - if (history_count < ROLLING_WINDOW) history_count++; - - double sum_cpu_usage = 0; - for (int i = 0; i < history_count; i++) sum_cpu_usage += cpu_usage_history[i]; - perf.cpu_usage = sum_cpu_usage / history_count; - - pthread_mutex_unlock(¤tcpuinfo); - } - - prev_real_time = curr_real_time; - prev_cpu_time = curr_cpu_time; - usleep(100000); - } - - Perf_endCPUMonitor(); - return NULL; -} - -void PLAT_setCPUSpeed(int speed) { - const char* mode; - switch (speed) { - case CPU_SPEED_AUTO: mode = "auto"; break; - case CPU_SPEED_PERFORMANCE: mode = "performance"; break; - case CPU_SPEED_POWERSAVE: mode = "powersave"; break; - default: return; - } - - const char* system_path = getenv("SYSTEM_PATH"); - if (!system_path) { - LOG_info("WARNING: SYSTEM_PATH not set, cannot run governor script\n"); - return; - } - char cmd[512]; - int n = snprintf(cmd, sizeof(cmd), "sh \"%s/bin/governor.sh\" \"%s\"", system_path, mode); - if (n < 0 || n >= (int)sizeof(cmd)) { - LOG_info("WARNING: SYSTEM_PATH too long for governor script path\n"); - return; - } - int ret = system(cmd); - if (ret != 0) LOG_info("WARNING: governor script exited with status %d for mode '%s'\n", ret, mode); -} #define MAX_STRENGTH 0xFFFF #define RUMBLE_PATH "/sys/class/gpio/gpio236/value" @@ -389,17 +194,7 @@ void PLAT_setRumble(int strength) { putInt(RUMBLE_PATH, (strength) ? 1 : 0); } -int PLAT_pickSampleRate(int requested, int max) { - // bluetooth: allow limiting the maximum to improve compatibility - if(PLAT_bluetoothConnected()) - return MIN(requested, CFG_getBluetoothSamplingrateLimit()); - - return MIN(requested, max); -} -void PLAT_overrideMute(int mute) { - putInt("/sys/class/speaker/mute", mute); -} char* PLAT_getModel(void) { char* model = getenv("TRIMUI_MODEL"); @@ -407,28 +202,8 @@ char* PLAT_getModel(void) { return "Trimui Smart Pro S"; } -void PLAT_getOsVersionInfo(char* output_str, size_t max_len) -{ - return getFile("/etc/version", output_str,max_len); -} -bool PLAT_btIsConnected(void) -{ - return bluetoothConnected; -} -ConnectionStrength PLAT_connectionStrength(void) { - if(!WIFI_enabled() || !connection.valid || connection.rssi == -1) - return SIGNAL_STRENGTH_OFF; - else if (connection.rssi == 0) - return SIGNAL_STRENGTH_DISCONNECTED; - else if (connection.rssi >= -60) - return SIGNAL_STRENGTH_HIGH; - else if (connection.rssi >= -70) - return SIGNAL_STRENGTH_MED; - else - return SIGNAL_STRENGTH_LOW; -} void PLAT_initDefaultLeds() { lightsDefault[0] = (LightSettings) { @@ -596,62 +371,9 @@ void PLAT_setLedBrightness(LightSettings *led) } } } -void PLAT_setLedEffect(LightSettings *led) -{ - char filepath[256]; - FILE *file; - // first set brightness - snprintf(filepath, sizeof(filepath), "/sys/class/led_anim/effect_%s", led->filename); - file = fopen(filepath, "w"); - if (file != NULL) - { - fprintf(file, "%i\n", led->effect); - fclose(file); - } -} -void PLAT_setLedEffectCycles(LightSettings *led) -{ - char filepath[256]; - FILE *file; - // first set brightness - snprintf(filepath, sizeof(filepath), "/sys/class/led_anim/effect_cycles_%s", led->filename); - file = fopen(filepath, "w"); - if (file != NULL) - { - fprintf(file, "%i\n", led->cycles); - fclose(file); - } -} -void PLAT_setLedEffectSpeed(LightSettings *led) -{ - char filepath[256]; - FILE *file; - // first set brightness - snprintf(filepath, sizeof(filepath), "/sys/class/led_anim/effect_duration_%s", led->filename); - file = fopen(filepath, "w"); - if (file != NULL) - { - fprintf(file, "%i\n", led->speed); - fclose(file); - } -} -void PLAT_setLedColor(LightSettings *led) -{ - char filepath[256]; - FILE *file; - // first set brightness - snprintf(filepath, sizeof(filepath), "/sys/class/led_anim/effect_rgb_hex_%s", led->filename); - file = fopen(filepath, "w"); - if (file != NULL) - { - fprintf(file, "%06X\n", led->color1); - fclose(file); - } -} ////////////////////////////////////////////// -bool PLAT_canTurbo(void) { return true; } #define INPUTD_PATH "/tmp/trimui_inputd" @@ -686,37 +408,10 @@ int toggle_file(const char *path) { } } -int PLAT_toggleTurbo(int btn_id) -{ - // avoid extra file IO on each call - static int initialized = 0; - if (!initialized) { - mkdir(INPUTD_PATH, 0755); - initialized = 1; - } - for (int i = 0; turbo_mapping[i].path; i++) { - if (turbo_mapping[i].brn_id == btn_id) { - return toggle_file(turbo_mapping[i].path); - } - } - return 0; -} - -void PLAT_clearTurbo() { - for (int i = 0; turbo_mapping[i].path; i++) { - unlink(turbo_mapping[i].path); - } -} ////////////////////////////////////////////// -int PLAT_setDateTime(int y, int m, int d, int h, int i, int s) { - char cmd[512]; - sprintf(cmd, "date -s '%d-%d-%d %d:%d:%d'; hwclock -u -w", y,m,d,h,i,s); - system(cmd); - return 0; // why does this return an int? -} #define MAX_LINE_LENGTH 200 #define ZONE_PATH "/usr/share/zoneinfo" @@ -729,67 +424,7 @@ int compare_timezones(const void *a, const void *b) { return strcmp((const char *)a, (const char *)b); } -void PLAT_initTimezones() { - if (cached_tz_count != -1) { // Already initialized - return; - } - - FILE *file = fopen(ZONE_TAB_PATH, "r"); - if (!file) { - LOG_info("Error opening file %s\n", ZONE_TAB_PATH); - return; - } - - char line[MAX_LINE_LENGTH]; - cached_tz_count = 0; - - while (fgets(line, sizeof(line), file)) { - // Skip comment lines - if (line[0] == '#' || strlen(line) < 3) { - continue; - } - - char *token = strtok(line, "\t"); // Skip country code - if (!token) continue; - - token = strtok(NULL, "\t"); // Skip latitude/longitude - if (!token) continue; - - token = strtok(NULL, "\t\n"); // Extract timezone - if (!token) continue; - - // Check for duplicates before adding - int duplicate = 0; - for (int i = 0; i < cached_tz_count; i++) { - if (strcmp(cached_timezones[i], token) == 0) { - duplicate = 1; - break; - } - } - - if (!duplicate && cached_tz_count < MAX_TIMEZONES) { - strncpy(cached_timezones[cached_tz_count], token, MAX_TZ_LENGTH - 1); - cached_timezones[cached_tz_count][MAX_TZ_LENGTH - 1] = '\0'; // Ensure null-termination - cached_tz_count++; - } - } - - fclose(file); - - // Sort the list alphabetically - qsort(cached_timezones, cached_tz_count, MAX_TZ_LENGTH, compare_timezones); -} -void PLAT_getTimezones(char timezones[MAX_TIMEZONES][MAX_TZ_LENGTH], int *tz_count) { - if (cached_tz_count == -1) { - LOG_warn("Error: Timezones not initialized. Call PLAT_initTimezones first.\n"); - *tz_count = 0; - return; - } - - memcpy(timezones, cached_timezones, sizeof(cached_timezones)); - *tz_count = cached_tz_count; -} char *PLAT_getCurrentTimezone() { // easy enough, get current index from config and return the string @@ -872,6 +507,7 @@ void PLAT_setNetworkTimeSync(bool on) { ///////////////////////// // We use the generic video implementation here +#include "generic_platform.c" #include "generic_video.c" ///////////////////////// From bfcadaff05f5b00daa5c4c76c4bd15e1f2c5ae7d Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sun, 5 Jul 2026 17:11:34 +0200 Subject: [PATCH 46/77] common/core: add RAII SurfacePtr wrapper for SDL_Surface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Header-only core::SurfacePtr — a std::unique_ptr alias with an SDL_FreeSurface deleter. Frees on scope exit, move-only, .get() hands the raw pointer to the C APIs (blit, GFX_*, IMG/TTF) that still take one. Forward-declares SDL_Surface / SDL_FreeSurface so core/ stays clear of the SDL1-vs-SDL2 include tangle (see common/sdl.h), matching str.h's zero- dependency style; every real use site pulls in the complete type via api.h. Adds a standalone surface_test.cpp that stubs SDL with a counting SDL_FreeSurface (no SDL link needed, like str_test.cpp), covering single free at scope exit, .get() non-owning, move transfer, move-assign, reset, release, and null-handle-frees-nothing. --- workspace/all/common/core/surface.h | 52 ++++++++++ .../all/common/core/tests/surface_test.cpp | 95 +++++++++++++++++++ 2 files changed, 147 insertions(+) create mode 100644 workspace/all/common/core/surface.h create mode 100644 workspace/all/common/core/tests/surface_test.cpp diff --git a/workspace/all/common/core/surface.h b/workspace/all/common/core/surface.h new file mode 100644 index 000000000..7d4d7a0d3 --- /dev/null +++ b/workspace/all/common/core/surface.h @@ -0,0 +1,52 @@ +// core/surface.h — RAII owner for SDL_Surface (C++, header-only). +// +// SDL_Surface is a C resource freed with SDL_FreeSurface(). Scattering manual +// SDL_FreeSurface() calls through the launcher is exactly the ownership +// bookkeeping that leaks on an early return and double-frees when two variables +// alias the same surface — the class of bug Phase A's audit kept turning up. +// +// core::SurfacePtr is a std::unique_ptr specialization that frees the surface +// when it goes out of scope, moves ownership explicitly, and (via .get()) +// hands a raw SDL_Surface* to the many C APIs — SDL_BlitSurface, the GFX_* +// helpers, IMG/TTF calls — that still take one. +// +// Usage: +// core::SurfacePtr img{IMG_Load(path)}; // adopt a freshly-made surface +// if (!img) return; // NULL-safe, like the raw ptr +// SDL_BlitSurface(img.get(), NULL, dst, &r); // hand the raw ptr to C APIs +// thumb = std::move(img); // transfer ownership, no double free +// // freed automatically at scope exit +// +// Ownership mirrors unique_ptr: exactly one owner, copy deleted, move transfers. +// Use .release() to hand ownership to a C API that will free it itself, and +// .reset(p) to replace the managed surface (frees the old one first). +// +// This header forward-declares SDL_Surface / SDL_FreeSurface so core/ stays +// clear of the SDL1-vs-SDL2 include tangle (see common/sdl.h); every real use +// site already includes SDL through api.h, which supplies the complete type the +// deleter needs at the point of destruction. +// +// Usable from any C++ translation unit. Include as: #include "core/surface.h" + +#ifndef NEXTUI_CORE_SURFACE_H +#define NEXTUI_CORE_SURFACE_H + +#include + +struct SDL_Surface; +extern "C" void SDL_FreeSurface(SDL_Surface* surface); + +namespace core { + +// Deleter that returns an owned SDL_Surface to SDL. unique_ptr only invokes it +// on a non-null pointer, so no null guard is needed here. +struct SurfaceDeleter { + void operator()(SDL_Surface* s) const { SDL_FreeSurface(s); } +}; + +// Move-only owning handle for an SDL_Surface. Frees on destruction. +using SurfacePtr = std::unique_ptr; + +} // namespace core + +#endif // NEXTUI_CORE_SURFACE_H diff --git a/workspace/all/common/core/tests/surface_test.cpp b/workspace/all/common/core/tests/surface_test.cpp new file mode 100644 index 000000000..5d0065772 --- /dev/null +++ b/workspace/all/common/core/tests/surface_test.cpp @@ -0,0 +1,95 @@ +// Desktop self-test for core/surface.h. Standalone — no SDL link needed: +// g++ -std=c++17 -I../../ surface_test.cpp -o surface_test && ./surface_test +// Exits non-zero on the first failed check. +// +// We supply our own complete SDL_Surface plus a counting SDL_FreeSurface stub +// so the RAII semantics (single free, move transfer, reset, release) can be +// checked without pulling in real SDL. + +struct SDL_Surface { int id; }; + +static int free_calls = 0; +extern "C" void SDL_FreeSurface(SDL_Surface* s) { + if (s) { free_calls++; delete s; } +} + +#include "core/surface.h" + +#include +#include + +static int failures = 0; +#define CHECK(cond) do { \ + if (!(cond)) { printf("FAIL %s:%d %s\n", __FILE__, __LINE__, #cond); failures++; } \ +} while (0) + +static SDL_Surface* make() { return new SDL_Surface{0}; } + +int main() { + // scope exit frees exactly once + { + free_calls = 0; + { core::SurfacePtr s{make()}; CHECK(free_calls == 0); } + CHECK(free_calls == 1); + } + // get() exposes the raw pointer without giving up ownership + { + free_calls = 0; + SDL_Surface* raw = make(); + core::SurfacePtr s{raw}; + CHECK(s.get() == raw); + CHECK(static_cast(s)); + CHECK(free_calls == 0); + } // freed here + CHECK(free_calls == 1); + // move transfers ownership — source empties, no double free + { + free_calls = 0; + core::SurfacePtr a{make()}; + core::SurfacePtr b{std::move(a)}; + CHECK(a.get() == nullptr); + CHECK(!a); + CHECK(b.get() != nullptr); + CHECK(free_calls == 0); + } // only b frees + CHECK(free_calls == 1); + // move-assignment frees the old target before taking the new surface + { + free_calls = 0; + core::SurfacePtr a{make()}; + core::SurfacePtr b{make()}; + b = std::move(a); // b's original surface freed here + CHECK(free_calls == 1); + } // b (now holding a's surface) frees + CHECK(free_calls == 2); + // reset(p) frees the old surface and adopts the new one + { + free_calls = 0; + core::SurfacePtr s{make()}; + s.reset(make()); + CHECK(free_calls == 1); + s.reset(); // explicit empty + CHECK(free_calls == 2); + CHECK(!s); + } + CHECK(free_calls == 2); // already empty, nothing more freed at scope exit + // release() yields the pointer without freeing; caller owns it now + { + free_calls = 0; + core::SurfacePtr s{make()}; + SDL_Surface* raw = s.release(); + CHECK(!s); + CHECK(free_calls == 0); + SDL_FreeSurface(raw); // manual free + CHECK(free_calls == 1); + } + // a default (null) handle frees nothing + { + free_calls = 0; + { core::SurfacePtr s; CHECK(!s); } + CHECK(free_calls == 0); + } + + if (failures == 0) printf("core/surface.h: all checks passed\n"); + return failures == 0 ? 0 : 1; +} From c631698c80bf11b9b9a1d372fcfed8d6c8564db2 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sun, 5 Jul 2026 17:11:45 +0200 Subject: [PATCH 47/77] settings: adopt SurfacePtr, fix 6 SDL_Surface leaks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert the ~20 manual TTF/scratch surface create->blit->free sites across the settings render path (menu, colorpicker, wifi, bt, keyboard, settings) to core::SurfacePtr. Behavior-preserving RAII; only the freeing changes. Fixes 6 leaks found during the sweep: - wifimenu NetworkItem, btmenu Pairable/PairedItem: a tiny-font label was rendered into `text`, never blitted, then overwritten — leaking every draw. The render was dead (nothing observed it), so it is removed outright, which also drops a wasted per-frame TTF_Render. - keyboardprompt drawKeyboard: input_placeholder was rendered for its height and never freed — leaked every keyboard frame. - settings.cpp bg setup: convertedbg was never freed on the convert-success path (screen-sized), and the final background surface was never freed at teardown. Both now owned by SurfacePtr with the temporary scoped so it frees promptly. Left as-is: menu.cpp's static overlaySurface / drawOverlayLocal shadow are persistent cross-call caches, not scope-based ownership, so RAII does not apply — that is the one remaining SDL_FreeSurface in the settings app. tg5040 build verified: all six files compile and link into settings.elf. --- workspace/all/settings/btmenu.cpp | 14 ++--- workspace/all/settings/colorpickermenu.cpp | 73 ++++++++++------------ workspace/all/settings/keyboardprompt.cpp | 21 +++---- workspace/all/settings/menu.cpp | 41 +++++------- workspace/all/settings/settings.cpp | 27 ++++---- workspace/all/settings/wifimenu.cpp | 8 +-- 6 files changed, 83 insertions(+), 101 deletions(-) diff --git a/workspace/all/settings/btmenu.cpp b/workspace/all/settings/btmenu.cpp index e2313a7ea..4e7162b15 100644 --- a/workspace/all/settings/btmenu.cpp +++ b/workspace/all/settings/btmenu.cpp @@ -4,6 +4,8 @@ # include "btagent.hpp" #endif +#include "core/surface.h" + #include #include @@ -290,7 +292,6 @@ PairableItem::PairableItem(BT_device d, MenuList* submenu) void PairableItem::drawCustomItem(SDL_Surface *surface, const SDL_Rect &dst, const AbstractMenuItem &item, bool selected) const { SDL_Color text_color = uintToColour(THEME_COLOR4_255); - SDL_Surface *text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, item.getLabel().c_str(), COLOR_WHITE); // always white // hack - this should be correlated to max_width int mw = dst.w; @@ -321,9 +322,8 @@ void PairableItem::drawCustomItem(SDL_Surface *surface, const SDL_Rect &dst, con text_color = uintToColour(THEME_COLOR5_255); } - text = TTF_RenderUTF8_Blended(GFX_getFonts()->small, item.getName().c_str(), text_color); - SDL_BlitSurfaceCPP(text, {}, surface, {dst.x + SCALE1(OPTION_PADDING), dst.y + SCALE1(1)}); - SDL_FreeSurface(text); + core::SurfacePtr text{TTF_RenderUTF8_Blended(GFX_getFonts()->small, item.getName().c_str(), text_color)}; + SDL_BlitSurfaceCPP(text.get(), {}, surface, {dst.x + SCALE1(OPTION_PADDING), dst.y + SCALE1(1)}); } PairedItem::PairedItem(BT_devicePaired d, MenuList* submenu) @@ -333,7 +333,6 @@ PairedItem::PairedItem(BT_devicePaired d, MenuList* submenu) void PairedItem::drawCustomItem(SDL_Surface *surface, const SDL_Rect &dst, const AbstractMenuItem &item, bool selected) const { SDL_Color text_color = uintToColour(THEME_COLOR4_255); - SDL_Surface *text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, item.getLabel().c_str(), COLOR_WHITE); // always white // hack - this should be correlated to max_width int mw = dst.w; @@ -383,7 +382,6 @@ void PairedItem::drawCustomItem(SDL_Surface *surface, const SDL_Rect &dst, const text_color = uintToColour(THEME_COLOR5_255); } - text = TTF_RenderUTF8_Blended(GFX_getFonts()->small, item.getName().c_str(), text_color); - SDL_BlitSurfaceCPP(text, {}, surface, {dst.x + SCALE1(OPTION_PADDING), dst.y + SCALE1(1)}); - SDL_FreeSurface(text); + core::SurfacePtr text{TTF_RenderUTF8_Blended(GFX_getFonts()->small, item.getName().c_str(), text_color)}; + SDL_BlitSurfaceCPP(text.get(), {}, surface, {dst.x + SCALE1(OPTION_PADDING), dst.y + SCALE1(1)}); } diff --git a/workspace/all/settings/colorpickermenu.cpp b/workspace/all/settings/colorpickermenu.cpp index 559245f9e..67d3ad99a 100644 --- a/workspace/all/settings/colorpickermenu.cpp +++ b/workspace/all/settings/colorpickermenu.cpp @@ -1,5 +1,6 @@ #include "colorpickermenu.hpp" +#include "core/surface.h" #include static constexpr int NUM_SLIDERS = 4; @@ -175,12 +176,12 @@ static void drawRoundedAlphaRect(SDL_Surface *surface, const SDL_Rect &rect, int { if (rect.w <= 0 || rect.h <= 0) return; - SDL_Surface *tmp = SDL_CreateRGBSurfaceWithFormat(0, rect.w, rect.h, - 32, SDL_PIXELFORMAT_ARGB8888); + core::SurfacePtr tmp{SDL_CreateRGBSurfaceWithFormat(0, rect.w, rect.h, + 32, SDL_PIXELFORMAT_ARGB8888)}; if (!tmp) return; - SDL_SetSurfaceBlendMode(tmp, SDL_BLENDMODE_BLEND); - SDL_FillRect(tmp, nullptr, SDL_MapRGBA(tmp->format, 0, 0, 0, 0)); + SDL_SetSurfaceBlendMode(tmp.get(), SDL_BLENDMODE_BLEND); + SDL_FillRect(tmp.get(), nullptr, SDL_MapRGBA(tmp->format, 0, 0, 0, 0)); auto remap = [&](uint32_t c) -> uint32_t { uint8_t rr, gg, bb, aa; @@ -189,21 +190,20 @@ static void drawRoundedAlphaRect(SDL_Surface *surface, const SDL_Rect &rect, int }; SDL_Rect r0 = {0, 0, rect.w, rect.h}; - drawSolidRoundedRect(tmp, r0, radius, remap(outer)); + drawSolidRoundedRect(tmp.get(),r0, radius, remap(outer)); if (rect.w > 2 && rect.h > 2) { SDL_Rect r1 = {1, 1, rect.w - 2, rect.h - 2}; - drawSolidRoundedRect(tmp, r1, std::max(0, radius - 1), remap(middle)); + drawSolidRoundedRect(tmp.get(),r1, std::max(0, radius - 1), remap(middle)); } if (rect.w > 4 && rect.h > 4) { SDL_Rect r2 = {2, 2, rect.w - 4, rect.h - 4}; - drawSolidRoundedRect(tmp, r2, std::max(0, radius - 2), remap(fill)); + drawSolidRoundedRect(tmp.get(),r2, std::max(0, radius - 2), remap(fill)); } SDL_Rect dst = rect; - SDL_BlitSurface(tmp, nullptr, surface, &dst); - SDL_FreeSurface(tmp); + SDL_BlitSurface(tmp.get(), nullptr, surface, &dst); } static void drawGradientCapsule(SDL_Surface *surface, const SDL_Rect &bar, @@ -214,11 +214,11 @@ static void drawGradientCapsule(SDL_Surface *surface, const SDL_Rect &bar, // SDL_FillRect does not alpha blend into destination surfaces. Build the // gradient into an ARGB temp surface, then alpha-blit it onto destination. - SDL_Surface *grad = SDL_CreateRGBSurfaceWithFormat(0, bar.w, bar.h, - 32, SDL_PIXELFORMAT_ARGB8888); + core::SurfacePtr grad{SDL_CreateRGBSurfaceWithFormat(0, bar.w, bar.h, + 32, SDL_PIXELFORMAT_ARGB8888)}; if (!grad) return; - SDL_SetSurfaceBlendMode(grad, SDL_BLENDMODE_BLEND); - SDL_FillRect(grad, nullptr, SDL_MapRGBA(grad->format, 0, 0, 0, 0)); + SDL_SetSurfaceBlendMode(grad.get(), SDL_BLENDMODE_BLEND); + SDL_FillRect(grad.get(), nullptr, SDL_MapRGBA(grad->format, 0, 0, 0, 0)); for (int x = 0; x < bar.w; x++) { @@ -246,12 +246,11 @@ static void drawGradientCapsule(SDL_Surface *surface, const SDL_Rect &bar, int col_h = bar.h - 2 * y_inset; if (col_h <= 0) continue; SDL_Rect col_rect = {x, y_inset, 1, col_h}; - SDL_FillRect(grad, &col_rect, col); + SDL_FillRect(grad.get(), &col_rect, col); } SDL_Rect dst = bar; - SDL_BlitSurface(grad, nullptr, surface, &dst); - SDL_FreeSurface(grad); + SDL_BlitSurface(grad.get(), nullptr, surface, &dst); } void ColorPickerMenu::drawSlider(SDL_Surface *surface, const SDL_Rect &row, @@ -276,21 +275,19 @@ void ColorPickerMenu::drawSlider(SDL_Surface *surface, const SDL_Rect &row, TTF_SizeUTF8(GFX_getFonts()->tiny, "00", &hex_fixed_w, nullptr); // Channel label ("R", "G", "B", "A") — centered in fixed-width slot - SDL_Surface *label_surf = TTF_RenderUTF8_Blended(GFX_getFonts()->small, label, text_color); + core::SurfacePtr label_surf{TTF_RenderUTF8_Blended(GFX_getFonts()->small, label, text_color)}; int label_x = row.x + SCALE1(OPTION_PADDING) + (label_fixed_w - label_surf->w) / 2; - SDL_BlitSurfaceCPP(label_surf, {}, surface, + SDL_BlitSurfaceCPP(label_surf.get(), {}, surface, {label_x, row.y + (row.h - label_surf->h) / 2}); - SDL_FreeSurface(label_surf); // Hex value right-aligned in fixed-width slot char hex_str[4]; snprintf(hex_str, sizeof(hex_str), "%02X", value); - SDL_Surface *hex_surf = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, hex_str, text_color); + core::SurfacePtr hex_surf{TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, hex_str, text_color)}; int hex_slot_x = row.x + row.w - SCALE1(OPTION_PADDING) - hex_fixed_w; - SDL_BlitSurfaceCPP(hex_surf, {}, surface, + SDL_BlitSurfaceCPP(hex_surf.get(), {}, surface, {hex_slot_x + (hex_fixed_w - hex_surf->w), row.y + (row.h - hex_surf->h) / 2}); - SDL_FreeSurface(hex_surf); // Slider bar — stable bounds derived from fixed label/hex widths int bar_x = row.x + SCALE1(OPTION_PADDING) + label_fixed_w + SCALE1(OPTION_PADDING); @@ -326,23 +323,22 @@ void ColorPickerMenu::drawSlider(SDL_Surface *surface, const SDL_Rect &row, // Draw the thumb onto a temporary ARGB surface so alpha blending works. // SDL_FillRect writes directly (no blend); blitting FROM an alpha surface does blend. - SDL_Surface *thumb = SDL_CreateRGBSurfaceWithFormat(0, circ_d, circ_d, - 32, SDL_PIXELFORMAT_ARGB8888); - SDL_SetSurfaceBlendMode(thumb, SDL_BLENDMODE_BLEND); - SDL_SetColorKey(thumb, SDL_FALSE, 0); - SDL_FillRect(thumb, nullptr, SDL_MapRGBA(thumb->format, 0, 0, 0, 0)); + core::SurfacePtr thumb{SDL_CreateRGBSurfaceWithFormat(0, circ_d, circ_d, + 32, SDL_PIXELFORMAT_ARGB8888)}; + SDL_SetSurfaceBlendMode(thumb.get(), SDL_BLENDMODE_BLEND); + SDL_SetColorKey(thumb.get(), SDL_FALSE, 0); + SDL_FillRect(thumb.get(), nullptr, SDL_MapRGBA(thumb->format, 0, 0, 0, 0)); SDL_Rect thumb_outer = {0, 0, circ_d, circ_d}; uint32_t thumbB = SDL_MapRGBA(thumb->format, 0, 0, 0, 200); - drawSolidRoundedRect(thumb, thumb_outer, circ_d / 2, thumbB); + drawSolidRoundedRect(thumb.get(),thumb_outer, circ_d / 2, thumbB); int inner_d = circ_d - circ_border * 2; SDL_Rect thumb_inner = {circ_border, circ_border, inner_d, inner_d}; uint32_t thumbF = SDL_MapRGBA(thumb->format, 255, 255, 255, 200); - drawSolidRoundedRect(thumb, thumb_inner, inner_d / 2, thumbF); + drawSolidRoundedRect(thumb.get(),thumb_inner, inner_d / 2, thumbF); SDL_Rect outer_rect = {cx - circ_d / 2, cy - circ_d / 2, circ_d, circ_d}; - SDL_BlitSurface(thumb, nullptr, surface, &outer_rect); - SDL_FreeSurface(thumb); + SDL_BlitSurface(thumb.get(), nullptr, surface, &outer_rect); } } @@ -365,19 +361,17 @@ void ColorPickerMenu::drawPreset(SDL_Surface *surface, const SDL_Rect &row, // Hex value "#RRGGBBAA" char hex_str[9]; snprintf(hex_str, sizeof(hex_str), "#%08X", preset.color); - SDL_Surface *hex_surf = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, hex_str, text_color); + core::SurfacePtr hex_surf{TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, hex_str, text_color)}; int hex_x = sq_rect.x + sq + SCALE1(OPTION_PADDING / 2 + 2); - SDL_BlitSurfaceCPP(hex_surf, {}, surface, + SDL_BlitSurfaceCPP(hex_surf.get(), {}, surface, {hex_x, row.y + (row.h - hex_surf->h) / 2}); int hex_w = hex_surf->w; - SDL_FreeSurface(hex_surf); // Name label - SDL_Surface *name_surf = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, preset.label.c_str(), text_color); - SDL_BlitSurfaceCPP(name_surf, {}, surface, + core::SurfacePtr name_surf{TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, preset.label.c_str(), text_color)}; + SDL_BlitSurfaceCPP(name_surf.get(), {}, surface, {hex_x + hex_w + SCALE1(OPTION_PADDING), row.y + (row.h - name_surf->h) / 2}); - SDL_FreeSurface(name_surf); } void ColorPickerMenu::drawCustom(SDL_Surface *surface, const SDL_Rect &dst, const SDL_Rect &dstTitle) @@ -388,10 +382,9 @@ void ColorPickerMenu::drawCustom(SDL_Surface *surface, const SDL_Rect &dst, cons char display_name[256]; GFX_truncateText(GFX_getFonts()->large, label_.c_str(), display_name, dstTitle.w, SCALE1(OPTION_PADDING * 2)); - SDL_Surface *title_text = TTF_RenderUTF8_Blended(GFX_getFonts()->large, display_name, uintToColour(THEME_COLOR4_255)); + core::SurfacePtr title_text{TTF_RenderUTF8_Blended(GFX_getFonts()->large, display_name, uintToColour(THEME_COLOR4_255))}; // hate the hardcoded +4, but we are matching MinUI code here - SDL_BlitSurfaceCPP(title_text, {}, surface, {dstTitle.x + SCALE1(BUTTON_PADDING), dstTitle.y + 4, dstTitle.w - SCALE1(BUTTON_PADDING * 2), title_text->h}); - SDL_FreeSurface(title_text); + SDL_BlitSurfaceCPP(title_text.get(), {}, surface, {dstTitle.x + SCALE1(BUTTON_PADDING), dstTitle.y + 4, dstTitle.w - SCALE1(BUTTON_PADDING * 2), title_text->h}); } // Button hints at the bottom of the screen diff --git a/workspace/all/settings/keyboardprompt.cpp b/workspace/all/settings/keyboardprompt.cpp index 19afef7f1..b91cc3d19 100644 --- a/workspace/all/settings/keyboardprompt.cpp +++ b/workspace/all/settings/keyboardprompt.cpp @@ -1,5 +1,7 @@ #include "keyboardprompt.hpp" +#include "core/surface.h" + constexpr int keyboardRows = 5; constexpr int keyboardColumns = 14; // keyboard_layout_lowercase is the default keyboard layout @@ -321,26 +323,25 @@ void KeyboardPrompt::drawKeyboard(SDL_Surface *screen, const AppState &state) // draw keyboard title if (!state.keyboard.title.empty()) { - SDL_Surface *title = TTF_RenderUTF8_Blended(GFX_getFonts()->large, state.keyboard.title.c_str(), COLOR_WHITE); + core::SurfacePtr title{TTF_RenderUTF8_Blended(GFX_getFonts()->large, state.keyboard.title.c_str(), COLOR_WHITE)}; SDL_Rect title_pos = { (screen->w - title->w) / 2, // center horizontally 20, // 20px from top title->w, title->h}; - SDL_BlitSurface(title, NULL, screen, &title_pos); - SDL_FreeSurface(title); + SDL_BlitSurface(title.get(), NULL, screen, &title_pos); } // draw input field with current text // todo: use TTF_SizeUTF8 to compute the width of the input field - SDL_Surface *input_placeholder = TTF_RenderUTF8_Blended(GFX_getFonts()->medium, "p", COLOR_WHITE); - SDL_Surface *input = TTF_RenderUTF8_Blended(GFX_getFonts()->medium, state.keyboard.current_text.c_str(), COLOR_WHITE); + core::SurfacePtr input_placeholder{TTF_RenderUTF8_Blended(GFX_getFonts()->medium, "p", COLOR_WHITE)}; + core::SurfacePtr input{TTF_RenderUTF8_Blended(GFX_getFonts()->medium, state.keyboard.current_text.c_str(), COLOR_WHITE)}; SDL_Rect input_pos = { (screen->w) / 2, input_placeholder->h * 2, 0, input_placeholder->h}; - if (input != NULL) + if (input) { input_pos.x = (screen->w - input->w) / 2; input_pos.w = input->w; @@ -354,8 +355,7 @@ void KeyboardPrompt::drawKeyboard(SDL_Surface *screen, const AppState &state) screen->w - 80, input_placeholder->h}; SDL_FillRect(screen, &input_bg, SDL_MapRGB(screen->format, TRIAD_DARK_GRAY)); - SDL_BlitSurface(input, NULL, screen, &input_pos); - SDL_FreeSurface(input); + SDL_BlitSurface(input.get(), NULL, screen, &input_pos); // draw keyboard layout int start_y = input_placeholder->h * 4; @@ -409,7 +409,7 @@ void KeyboardPrompt::drawKeyboard(SDL_Surface *screen, const AppState &state) continue; SDL_Color text_color = (row == state.keyboard.row && col == state.keyboard.col) ? COLOR_BLACK : COLOR_WHITE; - SDL_Surface *key_text = TTF_RenderUTF8_Blended(GFX_getFonts()->medium, key.c_str(), text_color); + core::SurfacePtr key_text{TTF_RenderUTF8_Blended(GFX_getFonts()->medium, key.c_str(), text_color)}; // special keys are not the same width as the other keys // so we need to compute their width separately @@ -438,8 +438,7 @@ void KeyboardPrompt::drawKeyboard(SDL_Surface *screen, const AppState &state) key_text->w, key_text->h}; - SDL_BlitSurface(key_text, NULL, screen, &text_pos); - SDL_FreeSurface(key_text); + SDL_BlitSurface(key_text.get(), NULL, screen, &text_pos); } } } diff --git a/workspace/all/settings/menu.cpp b/workspace/all/settings/menu.cpp index e726675cd..e4a2098cb 100644 --- a/workspace/all/settings/menu.cpp +++ b/workspace/all/settings/menu.cpp @@ -7,6 +7,8 @@ extern "C" #include "utils.h" } +#include "core/surface.h" + #include #include #include @@ -644,7 +646,6 @@ void MenuList::drawList(SDL_Surface *surface, const SDL_Rect &dst, const SDL_Rec void MenuList::drawListItem(SDL_Surface *surface, const SDL_Rect &dst, const AbstractMenuItem &item, bool selected) { SDL_Color text_color = uintToColour(THEME_COLOR4_255); - SDL_Surface *text; // int ox = (dst.w - w) / 2; // if we're centering these (but I don't think we should after seeing it) if (selected) @@ -657,9 +658,8 @@ void MenuList::drawListItem(SDL_Surface *surface, const SDL_Rect &dst, const Abs GFX_blitPillDarkCPP(ASSET_BUTTON, surface, {dst.x, dst.y, w, SCALE1(BUTTON_SIZE)}); text_color = uintToColour(THEME_COLOR5_255); } - text = TTF_RenderUTF8_Blended(GFX_getFonts()->small, item.getName().c_str(), text_color); - SDL_BlitSurfaceCPP(text, {}, surface, {dst.x + SCALE1(OPTION_PADDING), dst.y + ((dst.h - text->h) / 2)}); - SDL_FreeSurface(text); + core::SurfacePtr text{TTF_RenderUTF8_Blended(GFX_getFonts()->small, item.getName().c_str(), text_color)}; + SDL_BlitSurfaceCPP(text.get(), {}, surface, {dst.x + SCALE1(OPTION_PADDING), dst.y + ((dst.h - text->h) / 2)}); } void MenuList::drawFixed(SDL_Surface *surface, const SDL_Rect &dst, const SDL_Rect &dstTitle) @@ -704,7 +704,6 @@ void MenuList::drawFixedItem(SDL_Surface *surface, const SDL_Rect &dst, const Ab { SDL_Color text_color = uintToColour(THEME_COLOR4_255); SDL_Color text_color_value = uintToColour(THEME_COLOR4_255); - SDL_Surface *text; // hack - this should be correlated to max_width int mw = dst.w; @@ -717,7 +716,7 @@ void MenuList::drawFixedItem(SDL_Surface *surface, const SDL_Rect &dst, const Ab if (item.getValue().has_value()) { - text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, item.getLabel().c_str(), text_color_value); + core::SurfacePtr text{TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, item.getLabel().c_str(), text_color_value)}; if (item.getType() == ListItemType::Color) { @@ -739,11 +738,10 @@ void MenuList::drawFixedItem(SDL_Surface *surface, const SDL_Rect &dst, const Ab SDL_FillRect(surface, &rect, color); #define COLOR_PADDING 4 // Rerender the label from the live hex value - SDL_FreeSurface(text); char hexLabel[12]; snprintf(hexLabel, sizeof(hexLabel), "0x%08X", rawColor); - text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, hexLabel, text_color_value); - SDL_BlitSurfaceCPP(text, {}, surface, {dst.x + mw - text->w - SCALE1(OPTION_PADDING + COLOR_PADDING + FONT_TINY), dst.y + ((dst.h - text->h) / 2)}); + text.reset(TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, hexLabel, text_color_value)); + SDL_BlitSurfaceCPP(text.get(), {}, surface, {dst.x + mw - text->w - SCALE1(OPTION_PADDING + COLOR_PADDING + FONT_TINY), dst.y + ((dst.h - text->h) / 2)}); } else if(item.getType() == ListItemType::Button) { // dont draw anything for now, could be a button hint later @@ -752,8 +750,7 @@ void MenuList::drawFixedItem(SDL_Surface *surface, const SDL_Rect &dst, const Ab item.drawCustomItem(surface, dst, item, selected); } else // Generic and fallback - SDL_BlitSurfaceCPP(text, {}, surface, {dst.x + mw - text->w - SCALE1(OPTION_PADDING), dst.y + ((dst.h - text->h) / 2)}); - SDL_FreeSurface(text); + SDL_BlitSurfaceCPP(text.get(), {}, surface, {dst.x + mw - text->w - SCALE1(OPTION_PADDING), dst.y + ((dst.h - text->h) / 2)}); } // TODO: blit a black pill on unselected rows (to cover longer item->values?) or truncate longer item->values? @@ -767,9 +764,8 @@ void MenuList::drawFixedItem(SDL_Surface *surface, const SDL_Rect &dst, const Ab text_color = uintToColour(THEME_COLOR5_255); } - text = TTF_RenderUTF8_Blended(GFX_getFonts()->small, item.getName().c_str(), text_color); - SDL_BlitSurfaceCPP(text, {}, surface, {dst.x + SCALE1(OPTION_PADDING), dst.y + ((dst.h - text->h) / 2)}); - SDL_FreeSurface(text); + core::SurfacePtr name{TTF_RenderUTF8_Blended(GFX_getFonts()->small, item.getName().c_str(), text_color)}; + SDL_BlitSurfaceCPP(name.get(), {}, surface, {dst.x + SCALE1(OPTION_PADDING), dst.y + ((dst.h - name->h) / 2)}); } void MenuList::drawInput(SDL_Surface *surface, const SDL_Rect &dst, const SDL_Rect &dstTitle) @@ -805,7 +801,6 @@ void MenuList::drawInput(SDL_Surface *surface, const SDL_Rect &dst, const SDL_Re void MenuList::drawInputItem(SDL_Surface *surface, const SDL_Rect &dst, const AbstractMenuItem &item, bool selected) { SDL_Color text_color = COLOR_WHITE; - SDL_Surface *text; // hack int mw = dst.w; @@ -822,9 +817,8 @@ void MenuList::drawInputItem(SDL_Surface *surface, const SDL_Rect &dst, const Ab GFX_blitPillDarkCPP(ASSET_BUTTON, surface, {dst.x, dst.y, w, SCALE1(BUTTON_SIZE)}); text_color = COLOR_BLACK; } - text = TTF_RenderUTF8_Blended(GFX_getFonts()->small, item.getName().c_str(), text_color); - SDL_BlitSurfaceCPP(text, {}, surface, {dst.x + SCALE1(OPTION_PADDING), dst.y + ((dst.h - text->h) / 2)}); - SDL_FreeSurface(text); + core::SurfacePtr text{TTF_RenderUTF8_Blended(GFX_getFonts()->small, item.getName().c_str(), text_color)}; + SDL_BlitSurfaceCPP(text.get(), {}, surface, {dst.x + SCALE1(OPTION_PADDING), dst.y + ((dst.h - text->h) / 2)}); if (/*await_input &&*/ selected) { @@ -832,9 +826,8 @@ void MenuList::drawInputItem(SDL_Surface *surface, const SDL_Rect &dst, const Ab } else if (item.getValue().has_value()) { - text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, item.getLabel().c_str(), COLOR_WHITE); // always white - SDL_BlitSurfaceCPP(text, {}, surface, {dst.x + mw - text->w - SCALE1(OPTION_PADDING), dst.y + ((dst.h - text->h) / 2)}); - SDL_FreeSurface(text); + text.reset(TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, item.getLabel().c_str(), COLOR_WHITE)); // always white + SDL_BlitSurfaceCPP(text.get(), {}, surface, {dst.x + mw - text->w - SCALE1(OPTION_PADDING), dst.y + ((dst.h - text->h) / 2)}); } } @@ -866,7 +859,6 @@ void MenuList::drawMain(SDL_Surface *surface, const SDL_Rect &dst, const SDL_Rec void MenuList::drawMainItem(SDL_Surface *surface, const SDL_Rect &dst, const AbstractMenuItem &item, bool selected) { SDL_Color text_color = COLOR_WHITE; - SDL_Surface *text; // TODO: unique item handling (draws grey text) const bool unique = false; @@ -884,9 +876,8 @@ void MenuList::drawMainItem(SDL_Surface *surface, const SDL_Rect &dst, const Abs { // TODO: port this over when needed. Its complete spaghetti code... } - text = TTF_RenderUTF8_Blended(GFX_getFonts()->large, truncated, text_color); - SDL_BlitSurfaceCPP(text, {}, surface, {dst.x + SCALE1(BUTTON_PADDING), dst.y + ((dst.h - text->h) / 2)}); - SDL_FreeSurface(text); + core::SurfacePtr text{TTF_RenderUTF8_Blended(GFX_getFonts()->large, truncated, text_color)}; + SDL_BlitSurfaceCPP(text.get(), {}, surface, {dst.x + SCALE1(BUTTON_PADDING), dst.y + ((dst.h - text->h) / 2)}); } void MenuList::resetAllItems() diff --git a/workspace/all/settings/settings.cpp b/workspace/all/settings/settings.cpp index 414306abd..a60983a24 100644 --- a/workspace/all/settings/settings.cpp +++ b/workspace/all/settings/settings.cpp @@ -10,6 +10,8 @@ extern "C" #include "ra_sync.h" } +#include "core/surface.h" + #include #include #include @@ -1052,14 +1054,15 @@ int main(int argc, char *argv[]) ctx.menu = new MenuList(MenuItemType::List, "Main", mainItems); - SDL_Surface* bgbmp = IMG_Load(SDCARD_PATH "/bg.png"); - SDL_Surface* convertedbg = SDL_ConvertSurfaceFormat(bgbmp, SDL_PIXELFORMAT_RGB565, 0); - if (convertedbg) { - SDL_FreeSurface(bgbmp); - SDL_Surface* scaled = SDL_CreateRGBSurfaceWithFormat(0, ctx.screen->w, ctx.screen->h, 32, SDL_PIXELFORMAT_RGB565); - GFX_blitScaleToFill(convertedbg, scaled); - bgbmp = scaled; - } + core::SurfacePtr bgbmp{IMG_Load(SDCARD_PATH "/bg.png")}; + { + core::SurfacePtr convertedbg{SDL_ConvertSurfaceFormat(bgbmp.get(), SDL_PIXELFORMAT_RGB565, 0)}; + if (convertedbg) { + core::SurfacePtr scaled{SDL_CreateRGBSurfaceWithFormat(0, ctx.screen->w, ctx.screen->h, 32, SDL_PIXELFORMAT_RGB565)}; + GFX_blitScaleToFill(convertedbg.get(), scaled.get()); + bgbmp = std::move(scaled); // move-assign frees the original IMG_Load surface + } + } // convertedbg freed here (was previously leaked on the success path) // main content (list) // PADDING all around @@ -1097,7 +1100,7 @@ int main(int argc, char *argv[]) GFX_clear(ctx.screen); if(bgbmp) { SDL_Rect image_rect = {0, 0, ctx.screen->w, ctx.screen->h}; - SDL_BlitSurface(bgbmp, NULL, ctx.screen, &image_rect); + SDL_BlitSurface(bgbmp.get(), NULL, ctx.screen, &image_rect); } else { uint32_t bgc = CFG_getColor(COLOR_BACKGROUND); SDL_FillRect(ctx.screen, NULL, SDL_MapRGBA(ctx.screen->format, (bgc >> 24) & 0xFF, (bgc >> 16) & 0xFF, (bgc >> 8) & 0xFF, bgc & 0xFF)); @@ -1119,12 +1122,10 @@ int main(int argc, char *argv[]) int text_width = GFX_truncateText(GFX_getFonts()->large, "Some title", display_name, max_width, SCALE1(BUTTON_PADDING * 2)); max_width = MIN(max_width, text_width); - SDL_Surface *text; - text = TTF_RenderUTF8_Blended(GFX_getFonts()->large, display_name, COLOR_WHITE); + core::SurfacePtr text{TTF_RenderUTF8_Blended(GFX_getFonts()->large, display_name, COLOR_WHITE)}; SDL_Rect target = {SCALE1(PADDING), SCALE1(PADDING), max_width, SCALE1(PILL_SIZE)}; GFX_blitPillLight(ASSET_WHITE_PILL, ctx.screen, &target); - SDL_BlitSurfaceCPP(text, {0, 0, max_width - SCALE1(BUTTON_PADDING * 2), text->h}, ctx.screen, {SCALE1(PADDING + BUTTON_PADDING), SCALE1(PADDING + 4)}); - SDL_FreeSurface(text); + SDL_BlitSurfaceCPP(text.get(), {0, 0, max_width - SCALE1(BUTTON_PADDING * 2), text->h}, ctx.screen, {SCALE1(PADDING + BUTTON_PADDING), SCALE1(PADDING + 4)}); } else { // just set the titleRect and we will pass it on to the list to populate as needed diff --git a/workspace/all/settings/wifimenu.cpp b/workspace/all/settings/wifimenu.cpp index 071a8eb19..6da89948e 100644 --- a/workspace/all/settings/wifimenu.cpp +++ b/workspace/all/settings/wifimenu.cpp @@ -1,6 +1,8 @@ #include "wifimenu.hpp" #include "keyboardprompt.hpp" +#include "core/surface.h" + #include #include @@ -240,7 +242,6 @@ NetworkItem::NetworkItem(WIFI_network n, bool connected, MenuList* submenu) void NetworkItem::drawCustomItem(SDL_Surface *surface, const SDL_Rect &dst, const AbstractMenuItem &item, bool selected) const { SDL_Color text_color = uintToColour(THEME_COLOR4_255); - SDL_Surface *text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, item.getLabel().c_str(), COLOR_WHITE); // always white // hack - this should be correlated to max_width int mw = dst.w; @@ -289,7 +290,6 @@ void NetworkItem::drawCustomItem(SDL_Surface *surface, const SDL_Rect &dst, cons text_color = uintToColour(THEME_COLOR5_255); } - text = TTF_RenderUTF8_Blended(GFX_getFonts()->small, item.getName().c_str(), text_color); - SDL_BlitSurfaceCPP(text, {}, surface, {dst.x + SCALE1(OPTION_PADDING), dst.y + SCALE1(1)}); - SDL_FreeSurface(text); + core::SurfacePtr text{TTF_RenderUTF8_Blended(GFX_getFonts()->small, item.getName().c_str(), text_color)}; + SDL_BlitSurfaceCPP(text.get(), {}, surface, {dst.x + SCALE1(OPTION_PADDING), dst.y + SCALE1(1)}); } \ No newline at end of file From 9944daf7fb9cc3400f1fdb9b5bf3459102febe5f Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sun, 5 Jul 2026 18:17:16 +0200 Subject: [PATCH 48/77] nextui: adopt SurfacePtr for scratch surfaces, fix 3 SDL_Surface leaks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert the scope-local scratch SDL_Surface* in nextui.cpp to core::SurfacePtr: updatePillTextSurface (tmp/converted), both worker-loop scratch (raw), and the quick-switcher render locals (text, text_unique, tmpNewScreen x2, tmpsur, the preview bmp, blackBG). Behavior-preserving RAII; only the freeing changes. Fixes 3 leaks the sweep uncovered — all in the game-switcher path: - tmpOldScreen: full-screen capture, declared NULL each frame so its free-on-replace guard was a no-op, and it was never freed elsewhere — leaked a screen-sized surface on every switcher transition. - switcherSur: same pattern, leaked on every switcher entry. - the quick-action icon bmp: after conversion replaced the original, the converted surface was used but never freed — leaked per icon, per frame. RAII frees each at scope end, which is safe here: GFX_drawOnLayer / GFX_animateSurface* copy the pixels into a texture synchronously and retain no pointer (verified in PLAT_drawOnLayer, and by tmpNewScreen's existing free-immediately-after-animate). Left raw: the cross-thread globals folderbgbmp, thumbbmp, globalText, globalpill (worker-produced, mutex-guarded, freed on replace) — RAII on those belongs to the worker-queue redesign, not a scope conversion. Validated on tg5040 (Smart Pro) hardware: menu, navigation, switcher render and 12 slide transitions all correct; nextui RSS held flat at 34844 kB across the transitions (the leaks would previously have grown it ~40 MB). --- workspace/all/nextui/nextui.cpp | 122 ++++++++++++++------------------ 1 file changed, 53 insertions(+), 69 deletions(-) diff --git a/workspace/all/nextui/nextui.cpp b/workspace/all/nextui/nextui.cpp index 0107ba1dc..eae3359b1 100644 --- a/workspace/all/nextui/nextui.cpp +++ b/workspace/all/nextui/nextui.cpp @@ -17,6 +17,7 @@ #include #include #include "core/str.h" +#include "core/surface.h" #include "core/thread_safe_queue.h" extern "C" { @@ -1591,12 +1592,11 @@ static void updatePillTextSurface(const char* entry_name, int move_w, SDL_Color if (crop_w <= 0) return; SDL_LockMutex(fontMutex); - SDL_Surface* tmp = TTF_RenderUTF8_Blended(GFX_getFonts()->large, entry_name, text_color); + core::SurfacePtr tmp{TTF_RenderUTF8_Blended(GFX_getFonts()->large, entry_name, text_color)}; SDL_UnlockMutex(fontMutex); if (!tmp) return; - SDL_Surface* converted = SDL_ConvertSurfaceFormat(tmp, screen->format->format, 0); - SDL_FreeSurface(tmp); + core::SurfacePtr converted{SDL_ConvertSurfaceFormat(tmp.get(), screen->format->format, 0)}; if (!converted) return; SDL_Rect crop_rect = { 0, 0, crop_w, converted->h }; @@ -1604,9 +1604,8 @@ static void updatePillTextSurface(const char* entry_name, int move_w, SDL_Color 0, crop_rect.w, crop_rect.h, screen->format->BitsPerPixel, screen->format->format ); if (cropped) { - SDL_BlitSurface(converted, &crop_rect, cropped, NULL); + SDL_BlitSurface(converted.get(), &crop_rect, cropped, NULL); } - SDL_FreeSurface(converted); if (!cropped) return; SDL_LockMutex(animMutex); @@ -1637,10 +1636,9 @@ static void bgLoadWorkerLoop(void) { ImageLoadRequest req; while (bgLoadQueue.pop(req)) { SDL_Surface* surface = NULL; - SDL_Surface* raw = IMG_Load(req.path.c_str()); + core::SurfacePtr raw{IMG_Load(req.path.c_str())}; if (raw) { - surface = SDL_ConvertSurfaceFormat(raw, screen->format->format, 0); - SDL_FreeSurface(raw); + surface = SDL_ConvertSurfaceFormat(raw.get(), screen->format->format, 0); } req.callback(surface); // onBackgroundLoaded, hands off under bgMutex } @@ -1679,10 +1677,9 @@ static void thumbLoadWorkerLoop(void) { while (thumbLoadQueue.pop(req)) { SDL_Surface* surface = NULL; if (access(req.path.c_str(), F_OK) == 0) { - SDL_Surface* raw = IMG_Load(req.path.c_str()); + core::SurfacePtr raw{IMG_Load(req.path.c_str())}; if (raw) { - surface = SDL_ConvertSurfaceFormat(raw, screen->format->format, 0); - SDL_FreeSurface(raw); + surface = SDL_ConvertSurfaceFormat(raw.get(), screen->format->format, 0); } } req.callback(surface); // onThumbLoaded, hands off under thumbMutex @@ -1917,8 +1914,8 @@ int main (int argc, char *argv[]) { char folderBgPath[1024]; folderbgbmp = NULL; - SDL_Surface * blackBG = SDL_CreateRGBSurfaceWithFormat(0,screen->w,screen->h,screen->format->BitsPerPixel,screen->format->format); - SDL_FillRect(blackBG,NULL,SDL_MapRGBA(screen->format,0,0,0,255)); + core::SurfacePtr blackBG{SDL_CreateRGBSurfaceWithFormat(0,screen->w,screen->h,screen->format->BitsPerPixel,screen->format->format)}; + SDL_FillRect(blackBG.get(),NULL,SDL_MapRGBA(screen->format,0,0,0,255)); SDL_LockMutex(animMutex); globalpill = SDL_CreateRGBSurfaceWithFormat(SDL_SWSURFACE, screen->w, SCALE1(PILL_SIZE), FIXED_DEPTH, screen->format->format); @@ -2234,13 +2231,12 @@ int main (int argc, char *argv[]) { } if(dirty) { - SDL_Surface *tmpOldScreen = NULL; - SDL_Surface * switcherSur = NULL; + core::SurfacePtr tmpOldScreen; + core::SurfacePtr switcherSur; // NOTE:22 This causes slowdown when CFG_getMenuTransitions is set to false because animationdirection turns > 0 somewhere but is never set back to 0 and so this code runs on every action, will fix later if(animationdirection != ANIM_NONE || (lastScreen==SCREEN_GAMELIST && currentScreen == SCREEN_GAMESWITCHER)) { - if(tmpOldScreen) SDL_FreeSurface(tmpOldScreen); - tmpOldScreen = GFX_captureRendererToSurface(); - SDL_SetSurfaceBlendMode(tmpOldScreen,SDL_BLENDMODE_BLEND); + tmpOldScreen.reset(GFX_captureRendererToSurface()); + SDL_SetSurfaceBlendMode(tmpOldScreen.get(),SDL_BLENDMODE_BLEND); } // clear only background layer on start @@ -2352,12 +2348,11 @@ int main (int argc, char *argv[]) { char icon_path[MAX_PATH]; core::format(icon_path, SDCARD_PATH "/.system/res/%s@%ix.png", item->name, FIXED_SCALE); - SDL_Surface* bmp = IMG_Load(icon_path); + core::SurfacePtr bmp{IMG_Load(icon_path)}; if(bmp) { - SDL_Surface* converted = SDL_ConvertSurfaceFormat(bmp, screen->format->format, 0); + SDL_Surface* converted = SDL_ConvertSurfaceFormat(bmp.get(), screen->format->format, 0); if (converted) { - SDL_FreeSurface(bmp); - bmp = converted; + bmp.reset(converted); } } if(bmp) { @@ -2367,7 +2362,7 @@ int main (int argc, char *argv[]) { SDL_Rect destRect = { ox+x, oy+y, 0, 0 }; // width/height not required //SDL_BlitSurface(bmp, NULL, screen, &destRect); - GFX_blitSurfaceColor(bmp, NULL, screen, &destRect, icon_color); + GFX_blitSurfaceColor(bmp.get(), NULL, screen, &destRect, icon_color); } int w, h; @@ -2434,7 +2429,7 @@ int main (int argc, char *argv[]) { GFX_clearLayers(LAYER_ALL); GFX_clear(screen); GFX_flipHidden(); - GFX_animateSurfaceOpacity(tmpOldScreen,0,0,screen->w,screen->h,255,0,CFG_getMenuTransitions() ? 150:20,LAYER_BACKGROUND); + GFX_animateSurfaceOpacity(tmpOldScreen.get(),0,0,screen->w,screen->h,255,0,CFG_getMenuTransitions() ? 150:20,LAYER_BACKGROUND); } else if(currentScreen == SCREEN_GAMESWITCHER) { GFX_clearLayers(LAYER_ALL); @@ -2453,18 +2448,16 @@ int main (int argc, char *argv[]) { int text_width = GFX_truncateText(GFX_getFonts()->large, selectedEntry->name, display_name, max_width, SCALE1(BUTTON_PADDING*2)); max_width = MIN(max_width, text_width); - SDL_Surface* text; SDL_Color textColor = uintToColour(THEME_COLOR6_255); SDL_LockMutex(fontMutex); - text = TTF_RenderUTF8_Blended(GFX_getFonts()->large, display_name, textColor); + core::SurfacePtr text{TTF_RenderUTF8_Blended(GFX_getFonts()->large, display_name, textColor)}; SDL_UnlockMutex(fontMutex); const int text_offset_y = (SCALE1(PILL_SIZE) - text->h + 1) >> 1; SDL_Rect _pill_rect = { SCALE1(PADDING), SCALE1(PADDING), max_width, SCALE1(PILL_SIZE) }; GFX_blitPillLight(ASSET_WHITE_PILL, screen, &_pill_rect); SDL_Rect _text_src = { 0, 0, max_width-SCALE1(BUTTON_PADDING*2), text->h }; SDL_Rect _text_dst = { SCALE1(PADDING+BUTTON_PADDING), SCALE1(PADDING) + text_offset_y }; - SDL_BlitSurface(text, &_text_src, screen, &_text_dst); - SDL_FreeSurface(text); + SDL_BlitSurface(text.get(), &_text_src, screen, &_text_dst); } BTN_HINTS(0, screen, 0, "B","BACK", NULL); @@ -2475,11 +2468,10 @@ int main (int argc, char *argv[]) { if(has_preview) { // lotta memory churn here - SDL_Surface* bmp = IMG_Load(preview_path); - SDL_Surface* raw_preview = SDL_ConvertSurfaceFormat(bmp, screen->format->format, 0); + core::SurfacePtr bmp{IMG_Load(preview_path)}; + SDL_Surface* raw_preview = SDL_ConvertSurfaceFormat(bmp.get(), screen->format->format, 0); if (raw_preview) { - SDL_FreeSurface(bmp); - bmp = raw_preview; + bmp.reset(raw_preview); } if(bmp) { int aw = screen->w; @@ -2503,52 +2495,49 @@ int main (int argc, char *argv[]) { if(lastScreen == SCREEN_GAME) { // need to flip once so streaming_texture1 is updated GFX_flipHidden(); - GFX_animateSurfaceOpacity(bmp,0,0,screen->w,screen->h,0,255,CFG_getMenuTransitions() ? 150:20,LAYER_ALL); + GFX_animateSurfaceOpacity(bmp.get(),0,0,screen->w,screen->h,0,255,CFG_getMenuTransitions() ? 150:20,LAYER_ALL); } else if(lastScreen == SCREEN_GAMELIST) { - GFX_drawOnLayer(blackBG,0,0,screen->w,screen->h,1.0f,0,LAYER_BACKGROUND); - GFX_drawOnLayer(bmp,ax,ay,aw, ah,1.0f,0,LAYER_BACKGROUND); + GFX_drawOnLayer(blackBG.get(),0,0,screen->w,screen->h,1.0f,0,LAYER_BACKGROUND); + GFX_drawOnLayer(bmp.get(),ax,ay,aw, ah,1.0f,0,LAYER_BACKGROUND); GFX_flipHidden(); - SDL_Surface *tmpNewScreen = GFX_captureRendererToSurface(); + core::SurfacePtr tmpNewScreen{GFX_captureRendererToSurface()}; GFX_clearLayers(LAYER_ALL); folderbgchanged=1; - GFX_drawOnLayer(tmpOldScreen,0,0,screen->w, screen->h,1.0f,0,LAYER_ALL); - GFX_animateSurface(tmpNewScreen,0,0-screen->h,0,0,screen->w,screen->h,CFG_getMenuTransitions() ? 100:20,255,255,LAYER_BACKGROUND); - SDL_FreeSurface(tmpNewScreen); + GFX_drawOnLayer(tmpOldScreen.get(),0,0,screen->w, screen->h,1.0f,0,LAYER_ALL); + GFX_animateSurface(tmpNewScreen.get(),0,0-screen->h,0,0,screen->w,screen->h,CFG_getMenuTransitions() ? 100:20,255,255,LAYER_BACKGROUND); } else if(lastScreen == SCREEN_GAMESWITCHER) { GFX_flipHidden(); - GFX_drawOnLayer(blackBG,0,0,screen->w, screen->h,1.0f,0,LAYER_BACKGROUND); + GFX_drawOnLayer(blackBG.get(),0,0,screen->w, screen->h,1.0f,0,LAYER_BACKGROUND); if(gsanimdir == SLIDE_LEFT) - GFX_animateSurface(bmp,ax+screen->w,ay,ax,ay,aw,ah,CFG_getMenuTransitions() ? 80:20,0,255,LAYER_ALL); + GFX_animateSurface(bmp.get(),ax+screen->w,ay,ax,ay,aw,ah,CFG_getMenuTransitions() ? 80:20,0,255,LAYER_ALL); else if(gsanimdir == SLIDE_RIGHT) - GFX_animateSurface(bmp,ax-screen->w,ay,ax,ay,aw,ah,CFG_getMenuTransitions() ? 80:20,0,255,LAYER_ALL); + GFX_animateSurface(bmp.get(),ax-screen->w,ay,ax,ay,aw,ah,CFG_getMenuTransitions() ? 80:20,0,255,LAYER_ALL); - GFX_drawOnLayer(bmp,ax,ay,aw,ah,1.0f,0,LAYER_BACKGROUND); + GFX_drawOnLayer(bmp.get(),ax,ay,aw,ah,1.0f,0,LAYER_BACKGROUND); } else if(lastScreen == SCREEN_QUICKMENU) { GFX_flipHidden(); - GFX_drawOnLayer(blackBG,0,0,screen->w, screen->h,1.0f,0,LAYER_BACKGROUND); - GFX_drawOnLayer(bmp,ax,ay,aw,ah,1.0f,0,LAYER_BACKGROUND); + GFX_drawOnLayer(blackBG.get(),0,0,screen->w, screen->h,1.0f,0,LAYER_BACKGROUND); + GFX_drawOnLayer(bmp.get(),ax,ay,aw,ah,1.0f,0,LAYER_BACKGROUND); } - SDL_FreeSurface(bmp); // Free after rendering } } else { SDL_Rect preview_rect = {ox,oy,screen->w,screen->h}; - SDL_Surface * tmpsur = SDL_CreateRGBSurfaceWithFormat(0,screen->w,screen->h,screen->format->BitsPerPixel,screen->format->format); - SDL_FillRect(tmpsur, &preview_rect, CFG_getColor(COLOR_BACKGROUND)); + core::SurfacePtr tmpsur{SDL_CreateRGBSurfaceWithFormat(0,screen->w,screen->h,screen->format->BitsPerPixel,screen->format->format)}; + SDL_FillRect(tmpsur.get(), &preview_rect, CFG_getColor(COLOR_BACKGROUND)); if(lastScreen == SCREEN_GAME) { - GFX_animateSurfaceOpacity(tmpsur,0,0,screen->w,screen->h,255,0,CFG_getMenuTransitions() ? 150:20,LAYER_BACKGROUND); + GFX_animateSurfaceOpacity(tmpsur.get(),0,0,screen->w,screen->h,255,0,CFG_getMenuTransitions() ? 150:20,LAYER_BACKGROUND); } else if(lastScreen == SCREEN_GAMELIST) { - GFX_animateSurface(tmpsur,0,0-screen->h,0,0,screen->w,screen->h,CFG_getMenuTransitions() ? 100:20,255,255,LAYER_ALL); + GFX_animateSurface(tmpsur.get(),0,0-screen->h,0,0,screen->w,screen->h,CFG_getMenuTransitions() ? 100:20,255,255,LAYER_ALL); } else if(lastScreen == SCREEN_GAMESWITCHER) { GFX_flipHidden(); if(gsanimdir == SLIDE_LEFT) - GFX_animateSurface(tmpsur,0+screen->w,0,0,0,screen->w,screen->h,CFG_getMenuTransitions() ? 80:20,0,255,LAYER_ALL); + GFX_animateSurface(tmpsur.get(),0+screen->w,0,0,0,screen->w,screen->h,CFG_getMenuTransitions() ? 80:20,0,255,LAYER_ALL); else if(gsanimdir == SLIDE_RIGHT) - GFX_animateSurface(tmpsur,0-screen->w,0,0,0,screen->w,screen->h,CFG_getMenuTransitions() ? 80:20,0,255,LAYER_ALL); + GFX_animateSurface(tmpsur.get(),0-screen->w,0,0,0,screen->w,screen->h,CFG_getMenuTransitions() ? 80:20,0,255,LAYER_ALL); } - SDL_FreeSurface(tmpsur); GFX_blitMessage(GFX_getFonts()->large, "No Preview", screen, &preview_rect); } Entry_free(selectedEntry); @@ -2562,8 +2551,7 @@ int main (int argc, char *argv[]) { GFX_flipHidden(); - if(switcherSur) SDL_FreeSurface(switcherSur); - switcherSur = GFX_captureRendererToSurface(); + switcherSur.reset(GFX_captureRendererToSurface()); lastScreen = SCREEN_GAMESWITCHER; } else { // if currentscreen == SCREEN_GAMELIST @@ -2709,8 +2697,8 @@ int main (int argc, char *argv[]) { } SDL_LockMutex(fontMutex); - SDL_Surface* text = TTF_RenderUTF8_Blended(GFX_getFonts()->large, entry_name, text_color); - SDL_Surface* text_unique = TTF_RenderUTF8_Blended(GFX_getFonts()->large, display_name, COLOR_DARK_TEXT); + core::SurfacePtr text{TTF_RenderUTF8_Blended(GFX_getFonts()->large, entry_name, text_color)}; + core::SurfacePtr text_unique{TTF_RenderUTF8_Blended(GFX_getFonts()->large, display_name, COLOR_DARK_TEXT)}; SDL_UnlockMutex(fontMutex); // TODO: Use actual font metrics to center, this only works in simple cases const int text_offset_y = (SCALE1(PILL_SIZE) - text->h + 1) >> 1; @@ -2745,11 +2733,9 @@ int main (int argc, char *argv[]) { SDL_Rect dest_rect = { SCALE1(BUTTON_MARGIN + BUTTON_PADDING), SCALE1(PADDING + (j * PILL_SIZE)) + text_offset_y }; if(list_show_entry_names) { - SDL_BlitSurface(text_unique, &text_rect, screen, &dest_rect); - SDL_BlitSurface(text, &text_rect, screen, &dest_rect); + SDL_BlitSurface(text_unique.get(), &text_rect, screen, &dest_rect); + SDL_BlitSurface(text.get(), &text_rect, screen, &dest_rect); } - SDL_FreeSurface(text_unique); // Free after use - SDL_FreeSurface(text); // Free after use } if(lastScreen==SCREEN_GAMESWITCHER) { if(switcherSur) { @@ -2758,12 +2744,12 @@ int main (int argc, char *argv[]) { folderbgchanged=1; GFX_flipHidden(); - GFX_animateSurface(switcherSur,0,0,0,0-screen->h,screen->w,screen->h,CFG_getMenuTransitions() ? 100:20,255,255,LAYER_BACKGROUND); + GFX_animateSurface(switcherSur.get(),0,0,0,0-screen->h,screen->w,screen->h,CFG_getMenuTransitions() ? 100:20,255,255,LAYER_BACKGROUND); animationdirection = ANIM_NONE; } } if(lastScreen==SCREEN_OFF) { - GFX_animateSurfaceOpacity(blackBG,0,0,screen->w,screen->h,255,0,CFG_getMenuTransitions() ? 200:20,LAYER_THUMBNAIL); + GFX_animateSurfaceOpacity(blackBG.get(),0,0,screen->w,screen->h,255,0,CFG_getMenuTransitions() ? 200:20,LAYER_THUMBNAIL); } previous_row = selected_row; @@ -2800,19 +2786,18 @@ int main (int argc, char *argv[]) { SDL_UnlockMutex(animMutex); } GFX_flipHidden(); - SDL_Surface *tmpNewScreen = GFX_captureRendererToSurface(); - SDL_SetSurfaceBlendMode(tmpNewScreen,SDL_BLENDMODE_BLEND); + core::SurfacePtr tmpNewScreen{GFX_captureRendererToSurface()}; + SDL_SetSurfaceBlendMode(tmpNewScreen.get(),SDL_BLENDMODE_BLEND); GFX_clearLayers(LAYER_SCROLLTEXT); // baked into tmpNewScreen; must clear or it floats above the animation GFX_clearLayers(LAYER_THUMBNAIL); { int _duration = (CFG_getMenuTransitions() == TRANSITION_COMFY) ? TRANSITION_COMFY_DURATION : TRANSITION_SNAPPY_DURATION; - if(animationdirection == SLIDE_LEFT) GFX_animateAndFadeSurface(tmpOldScreen,0,0,-250,0,FIXED_WIDTH,FIXED_HEIGHT,_duration,tmpNewScreen,FIXED_WIDTH,0,0,0,FIXED_WIDTH,FIXED_HEIGHT,255,255,LAYER_THUMBNAIL,TRANSITION_CURVE,TRANSITION_CURVE,TRANSITION_INTENSITY); - if(animationdirection == SLIDE_RIGHT) GFX_animateAndFadeSurface(tmpNewScreen,-250,0,0,0,FIXED_WIDTH,FIXED_HEIGHT,_duration,tmpOldScreen,0,0,FIXED_WIDTH,0,FIXED_WIDTH,FIXED_HEIGHT,255,255,LAYER_THUMBNAIL,TRANSITION_CURVE,TRANSITION_CURVE,TRANSITION_INTENSITY); + if(animationdirection == SLIDE_LEFT) GFX_animateAndFadeSurface(tmpOldScreen.get(),0,0,-250,0,FIXED_WIDTH,FIXED_HEIGHT,_duration,tmpNewScreen.get(),FIXED_WIDTH,0,0,0,FIXED_WIDTH,FIXED_HEIGHT,255,255,LAYER_THUMBNAIL,TRANSITION_CURVE,TRANSITION_CURVE,TRANSITION_INTENSITY); + if(animationdirection == SLIDE_RIGHT) GFX_animateAndFadeSurface(tmpNewScreen.get(),-250,0,0,0,FIXED_WIDTH,FIXED_HEIGHT,_duration,tmpOldScreen.get(),0,0,FIXED_WIDTH,0,FIXED_WIDTH,FIXED_HEIGHT,255,255,LAYER_THUMBNAIL,TRANSITION_CURVE,TRANSITION_CURVE,TRANSITION_INTENSITY); } GFX_clearLayers(LAYER_THUMBNAIL); - SDL_FreeSurface(tmpNewScreen); } // animation done animationdirection = ANIM_NONE; @@ -3021,7 +3006,6 @@ int main (int argc, char *argv[]) { GFX_quit(); // Cleanup video subsystem first to stop GPU threads // Now safe to free surfaces after GPU threads are stopped - if(blackBG) SDL_FreeSurface(blackBG); if (folderbgbmp) SDL_FreeSurface(folderbgbmp); if (thumbbmp) SDL_FreeSurface(thumbbmp); From 15c98ed728d5b9b4050647b670129fc26c4087d3 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sun, 5 Jul 2026 19:11:59 +0200 Subject: [PATCH 49/77] minarch: convert ma_audio to C++ (Phase E pilot) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit First minarch .c -> .cpp conversion, establishing the incremental pattern: rename the file, move it from CSOURCE to CXXSOURCE, and include the project C headers wrapped in extern "C" so the C++ unit links against the unmangled symbols (core, SND_*, LOG_*) still defined in the C translation units — the same wrapping nextui.cpp/settings already use around api.h. Only behavioral change: the two audio_sample_callback compound literals &(const SND_Frame){left,right} are hoisted to a named local. g++ 8.3 silently miscompiles compound literals passed as function arguments in C++ (see the alpha-colour BTN_HINTS incident), so this both is required for the port and removes that hazard. Diff against the original is otherwise byte-identical. tg5040 build verified: ma_audio.cpp compiles as gnu++2a and minarch.elf links with no undefined references. --- workspace/all/minarch/{ma_audio.c => ma_audio.cpp} | 14 ++++++++++++-- workspace/all/minarch/makefile | 4 ++-- 2 files changed, 14 insertions(+), 4 deletions(-) rename workspace/all/minarch/{ma_audio.c => ma_audio.cpp} (76%) diff --git a/workspace/all/minarch/ma_audio.c b/workspace/all/minarch/ma_audio.cpp similarity index 76% rename from workspace/all/minarch/ma_audio.c rename to workspace/all/minarch/ma_audio.cpp index 44fb465d1..98ce3c2c0 100644 --- a/workspace/all/minarch/ma_audio.c +++ b/workspace/all/minarch/ma_audio.cpp @@ -1,8 +1,15 @@ #include #include + +// minarch's C headers declare C-linkage symbols (core, SND_*, LOG_*, …) that +// are defined in the still-C translation units. Include them as extern "C" so +// this C++ unit links against the unmangled names. (Same pattern nextui.cpp and +// settings use around api.h.) +extern "C" { #include #include "ma_internal.h" #include "ma_audio.h" +} static bool resetAudio = false; @@ -34,11 +41,14 @@ void Audio_checkAndResetIfNeeded(void) { void audio_sample_callback(int16_t left, int16_t right) { if (rewind_st.active && !rewind_ctx.audio) return; if (!ff.active || ff.audio) { + // Named local rather than a compound literal: g++ 8.3 silently + // miscompiles &(const SND_Frame){...} passed as a function argument. + const SND_Frame frame = {left, right}; if (use_core_fps || ff.active) { - SND_batchSamples_fixed_rate(&(const SND_Frame){left,right}, 1); + SND_batchSamples_fixed_rate(&frame, 1); } else { - SND_batchSamples(&(const SND_Frame){left,right}, 1); + SND_batchSamples(&frame, 1); } } } diff --git a/workspace/all/minarch/makefile b/workspace/all/minarch/makefile index 7df9bc7b3..77dbaa915 100644 --- a/workspace/all/minarch/makefile +++ b/workspace/all/minarch/makefile @@ -26,11 +26,11 @@ INCDIR = -I. -I./libretro-common/include/ -I../common/ -I../../$(PLATFORM)/platf # C and C++ translation units are listed separately. C files compile as C; # C++ files compile as C++; everything links through g++ so the two can mix # as modules are migrated to C++ incrementally. -CSOURCE = $(TARGET).c ma_cheats.c ma_rewind.c ma_audio.c ma_input.c \ +CSOURCE = $(TARGET).c ma_cheats.c ma_rewind.c ma_input.c \ ma_options.c ma_frontend_opts.c ma_saves.c ma_video.c ma_core.c ma_game.c ma_environment.c ma_config.c ma_menu.c ma_runframe.c \ ../common/scaler.c ../common/utils.c ../common/config.c ../common/api.c \ ../common/notification.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = +CXXSOURCE = ma_audio.cpp # RA support ifneq (,$(filter $(PLATFORM),tg5040 tg5050 my355 desktop)) From a2075b8ad665ad9443b43132248064a574efc5d2 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sun, 5 Jul 2026 23:33:32 +0200 Subject: [PATCH 50/77] minarch: convert ma_input/ma_runframe/ma_cheats/ma_core to C++ Continue the incremental minarch C->C++ migration (Phase E) following the ma_audio pilot pattern: rename each .c to .cpp, wrap the project C headers in extern "C" so the C++ TU links against the unmangled C-linkage symbols, and move each file from CSOURCE to CXXSOURCE in the makefile. ma_input and ma_runframe are pure mechanical conversions (no casts needed). ma_cheats needs explicit casts on its 5 calloc() results (C++ won't implicitly convert void*). It also had a latent bug the C++ compiler surfaced: Cheats_load (bool) fell off the end without returning, yielding a garbage register value (UB in C++). Its return value gates Core_applyCheats, so cheats applied only by stack luck; now returns the real success flag. ma_core needs casts on its ~24 dlsym() results (void* -> function pointer, which C++ forbids implicitly). Each assignment casts to (decltype(LHS)) so it picks up the field/local's exact function-pointer type without a manual type lookup. Builds clean with -std=gnu++2a; minarch.elf links through g++. Behaviour is otherwise byte-for-byte the same as the C originals. --- .../minarch/{ma_cheats.c => ma_cheats.cpp} | 27 ++++++--- .../all/minarch/{ma_core.c => ma_core.cpp} | 56 +++++++++++-------- .../all/minarch/{ma_input.c => ma_input.cpp} | 9 ++- .../{ma_runframe.c => ma_runframe.cpp} | 6 ++ workspace/all/minarch/makefile | 6 +- 5 files changed, 67 insertions(+), 37 deletions(-) rename workspace/all/minarch/{ma_cheats.c => ma_cheats.cpp} (91%) rename workspace/all/minarch/{ma_core.c => ma_core.cpp} (63%) rename workspace/all/minarch/{ma_input.c => ma_input.cpp} (97%) rename workspace/all/minarch/{ma_runframe.c => ma_runframe.cpp} (92%) diff --git a/workspace/all/minarch/ma_cheats.c b/workspace/all/minarch/ma_cheats.cpp similarity index 91% rename from workspace/all/minarch/ma_cheats.c rename to workspace/all/minarch/ma_cheats.cpp index 1f5dbce75..91c0b1dd5 100644 --- a/workspace/all/minarch/ma_cheats.c +++ b/workspace/all/minarch/ma_cheats.cpp @@ -1,10 +1,15 @@ -#include "ma_internal.h" -#include "ma_cheats.h" - #include #include #include +// Project C headers declare C-linkage symbols (cheatcodes, core, LOG_*, …) +// defined in the still-C translation units. Include them as extern "C" so this +// C++ unit links against the unmangled names. (Same pattern as ma_audio.cpp.) +extern "C" { +#include "ma_internal.h" +#include "ma_cheats.h" +} + // based on picoarch/cheat.c struct Cheats cheatcodes; @@ -115,7 +120,7 @@ static int parse_cheats(struct Cheats *cheats, FILE *file) { if (len == 0) continue; - cheat->name = calloc(len+1, sizeof(char)); + cheat->name = (char *)calloc(len+1, sizeof(char)); if (!cheat->name) goto finish; @@ -123,7 +128,7 @@ static int parse_cheats(struct Cheats *cheats, FILE *file) { truncateString((char *)cheat->name, CHEAT_MAX_DESC_LEN); if (len >= CHEAT_MAX_DESC_LEN) { - cheat->info = calloc(len+1, sizeof(char)); + cheat->info = (char *)calloc(len+1, sizeof(char)); if (!cheat->info) goto finish; @@ -141,7 +146,7 @@ static int parse_cheats(struct Cheats *cheats, FILE *file) { if (len == 0) continue; - cheat->code = calloc(len+1, sizeof(char)); + cheat->code = (char *)calloc(len+1, sizeof(char)); if (!cheat->code) goto finish; @@ -235,7 +240,7 @@ void Cheat_getPaths(char paths[CHEAT_MAX_PATHS][MAX_PATH], int* count) { // Log all path candidates { size_t list_sz = *count * (MAX_PATH + 2) + 1; - char *list = calloc(list_sz, 1); // path + separator for each entry + char *list = (char *)calloc(list_sz, 1); // path + separator for each entry if (list != NULL) { int i; for (i=0; i<*count; i++) { @@ -326,7 +331,7 @@ bool Cheats_load() { goto finish; } - cheatcodes.cheats = calloc(cheatcodes.count, sizeof(struct Cheat)); + cheatcodes.cheats = (struct Cheat *)calloc(cheatcodes.count, sizeof(struct Cheat)); if (!cheatcodes.cheats) { LOG_error("Couldn't allocate memory for cheats\n"); goto finish; @@ -347,4 +352,10 @@ bool Cheats_load() { if (file) fclose(file); + + // Was missing in the C original: the function fell off the end, returning a + // garbage register value (UB in C++, undefined-but-tolerated in C). The + // caller (Core_load) gates Core_applyCheats on this, so return the real + // success flag so cheats apply exactly when a file was parsed successfully. + return success; } diff --git a/workspace/all/minarch/ma_core.c b/workspace/all/minarch/ma_core.cpp similarity index 63% rename from workspace/all/minarch/ma_core.c rename to workspace/all/minarch/ma_core.cpp index b5ab3fe02..8b757eb6b 100644 --- a/workspace/all/minarch/ma_core.c +++ b/workspace/all/minarch/ma_core.cpp @@ -2,6 +2,13 @@ #include #include +// Project C headers declare C-linkage symbols (core, cheatcodes, the retro_* +// callbacks, LOG_*, …) defined in the still-C translation units. Include them +// as extern "C" so this C++ unit links against the unmangled names. dlsym() +// returns void*, which C++ won't implicitly convert to a function pointer, so +// each core.* / set_*_callback assignment casts to the field's decltype. +// (Same header pattern as ma_audio.cpp.) +extern "C" { #include "ma_internal.h" #include "ma_saves.h" #include "ma_video.h" @@ -9,6 +16,7 @@ #include "ma_input.h" #include "ma_cheats.h" #include "ma_core.h" +} void Core_getName(char* in_name, char* out_name, size_t out_size) { @@ -22,24 +30,24 @@ void Core_open(const char* core_path, const char* tag_name) { if (!core.handle) LOG_error("%s\n", dlerror()); - core.init = dlsym(core.handle, "retro_init"); - core.deinit = dlsym(core.handle, "retro_deinit"); - core.get_system_info = dlsym(core.handle, "retro_get_system_info"); - core.get_system_av_info = dlsym(core.handle, "retro_get_system_av_info"); - core.set_controller_port_device = dlsym(core.handle, "retro_set_controller_port_device"); - core.reset = dlsym(core.handle, "retro_reset"); - core.run = dlsym(core.handle, "retro_run"); - core.serialize_size = dlsym(core.handle, "retro_serialize_size"); - core.serialize = dlsym(core.handle, "retro_serialize"); - core.unserialize = dlsym(core.handle, "retro_unserialize"); - core.cheat_reset = dlsym(core.handle, "retro_cheat_reset"); - core.cheat_set = dlsym(core.handle, "retro_cheat_set"); - core.load_game = dlsym(core.handle, "retro_load_game"); - core.load_game_special = dlsym(core.handle, "retro_load_game_special"); - core.unload_game = dlsym(core.handle, "retro_unload_game"); - core.get_region = dlsym(core.handle, "retro_get_region"); - core.get_memory_data = dlsym(core.handle, "retro_get_memory_data"); - core.get_memory_size = dlsym(core.handle, "retro_get_memory_size"); + core.init = (decltype(core.init))dlsym(core.handle, "retro_init"); + core.deinit = (decltype(core.deinit))dlsym(core.handle, "retro_deinit"); + core.get_system_info = (decltype(core.get_system_info))dlsym(core.handle, "retro_get_system_info"); + core.get_system_av_info = (decltype(core.get_system_av_info))dlsym(core.handle, "retro_get_system_av_info"); + core.set_controller_port_device = (decltype(core.set_controller_port_device))dlsym(core.handle, "retro_set_controller_port_device"); + core.reset = (decltype(core.reset))dlsym(core.handle, "retro_reset"); + core.run = (decltype(core.run))dlsym(core.handle, "retro_run"); + core.serialize_size = (decltype(core.serialize_size))dlsym(core.handle, "retro_serialize_size"); + core.serialize = (decltype(core.serialize))dlsym(core.handle, "retro_serialize"); + core.unserialize = (decltype(core.unserialize))dlsym(core.handle, "retro_unserialize"); + core.cheat_reset = (decltype(core.cheat_reset))dlsym(core.handle, "retro_cheat_reset"); + core.cheat_set = (decltype(core.cheat_set))dlsym(core.handle, "retro_cheat_set"); + core.load_game = (decltype(core.load_game))dlsym(core.handle, "retro_load_game"); + core.load_game_special = (decltype(core.load_game_special))dlsym(core.handle, "retro_load_game_special"); + core.unload_game = (decltype(core.unload_game))dlsym(core.handle, "retro_unload_game"); + core.get_region = (decltype(core.get_region))dlsym(core.handle, "retro_get_region"); + core.get_memory_data = (decltype(core.get_memory_data))dlsym(core.handle, "retro_get_memory_data"); + core.get_memory_size = (decltype(core.get_memory_size))dlsym(core.handle, "retro_get_memory_size"); void (*set_environment_callback)(retro_environment_t); void (*set_video_refresh_callback)(retro_video_refresh_t); @@ -48,12 +56,12 @@ void Core_open(const char* core_path, const char* tag_name) { void (*set_input_poll_callback)(retro_input_poll_t); void (*set_input_state_callback)(retro_input_state_t); - set_environment_callback = dlsym(core.handle, "retro_set_environment"); - set_video_refresh_callback = dlsym(core.handle, "retro_set_video_refresh"); - set_audio_sample_callback = dlsym(core.handle, "retro_set_audio_sample"); - set_audio_sample_batch_callback = dlsym(core.handle, "retro_set_audio_sample_batch"); - set_input_poll_callback = dlsym(core.handle, "retro_set_input_poll"); - set_input_state_callback = dlsym(core.handle, "retro_set_input_state"); + set_environment_callback = (decltype(set_environment_callback))dlsym(core.handle, "retro_set_environment"); + set_video_refresh_callback = (decltype(set_video_refresh_callback))dlsym(core.handle, "retro_set_video_refresh"); + set_audio_sample_callback = (decltype(set_audio_sample_callback))dlsym(core.handle, "retro_set_audio_sample"); + set_audio_sample_batch_callback = (decltype(set_audio_sample_batch_callback))dlsym(core.handle, "retro_set_audio_sample_batch"); + set_input_poll_callback = (decltype(set_input_poll_callback))dlsym(core.handle, "retro_set_input_poll"); + set_input_state_callback = (decltype(set_input_state_callback))dlsym(core.handle, "retro_set_input_state"); struct retro_system_info info = {}; core.get_system_info(&info); diff --git a/workspace/all/minarch/ma_input.c b/workspace/all/minarch/ma_input.cpp similarity index 97% rename from workspace/all/minarch/ma_input.c rename to workspace/all/minarch/ma_input.cpp index d9fe8691c..824e49ac6 100644 --- a/workspace/all/minarch/ma_input.c +++ b/workspace/all/minarch/ma_input.cpp @@ -1,7 +1,12 @@ +#include + +// Project C headers declare C-linkage symbols (core, pad, PAD_*, LOG_*, …) +// defined in the still-C translation units. Include them as extern "C" so this +// C++ unit links against the unmangled names. (Same pattern as ma_audio.cpp.) +extern "C" { #include "ma_internal.h" #include "ma_input.h" - -#include +} int setFastForward(int enable) { int val = enable ? 1 : 0; diff --git a/workspace/all/minarch/ma_runframe.c b/workspace/all/minarch/ma_runframe.cpp similarity index 92% rename from workspace/all/minarch/ma_runframe.c rename to workspace/all/minarch/ma_runframe.cpp index 9a5d994ea..761b7d2d6 100644 --- a/workspace/all/minarch/ma_runframe.c +++ b/workspace/all/minarch/ma_runframe.cpp @@ -1,9 +1,15 @@ #include + +// Project C headers declare C-linkage symbols (core, rewind_st, ff, LOG_*, …) +// defined in the still-C translation units. Include them as extern "C" so this +// C++ unit links against the unmangled names. (Same pattern as ma_audio.cpp.) +extern "C" { #include "ma_internal.h" #include "ma_rewind.h" #include "ma_input.h" #include "ma_config.h" #include "ma_runframe.h" +} void chooseSyncRef(void) { switch (sync_ref) { diff --git a/workspace/all/minarch/makefile b/workspace/all/minarch/makefile index 77dbaa915..65d81f70c 100644 --- a/workspace/all/minarch/makefile +++ b/workspace/all/minarch/makefile @@ -26,11 +26,11 @@ INCDIR = -I. -I./libretro-common/include/ -I../common/ -I../../$(PLATFORM)/platf # C and C++ translation units are listed separately. C files compile as C; # C++ files compile as C++; everything links through g++ so the two can mix # as modules are migrated to C++ incrementally. -CSOURCE = $(TARGET).c ma_cheats.c ma_rewind.c ma_input.c \ - ma_options.c ma_frontend_opts.c ma_saves.c ma_video.c ma_core.c ma_game.c ma_environment.c ma_config.c ma_menu.c ma_runframe.c \ +CSOURCE = $(TARGET).c ma_rewind.c \ + ma_options.c ma_frontend_opts.c ma_saves.c ma_video.c ma_game.c ma_environment.c ma_config.c ma_menu.c \ ../common/scaler.c ../common/utils.c ../common/config.c ../common/api.c \ ../common/notification.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = ma_audio.cpp +CXXSOURCE = ma_audio.cpp ma_input.cpp ma_runframe.cpp ma_cheats.cpp ma_core.cpp # RA support ifneq (,$(filter $(PLATFORM),tg5040 tg5050 my355 desktop)) From 5229dd0a45ca64ee058470037ffff8100564d977 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sun, 5 Jul 2026 23:59:36 +0200 Subject: [PATCH 51/77] minarch: convert ma_environment/ma_game/ma_saves/ma_rewind/ma_options to C++ Continue the incremental minarch C->C++ migration (Phase E), same pattern as the prior batch: rename each .c to .cpp, wrap the project C headers in extern "C" so the C++ TU links against the unmangled C-linkage symbols, and move each file CSOURCE->CXXSOURCE in the makefile. ma_environment and ma_game are pure mechanical conversions (game.data is void*, so its malloc needs no cast). ma_options casts its 12 calloc() results to (decltype(LHS)) (C++ won't implicitly convert void*). ma_rewind casts its 13 calloc() results: 12 via (decltype(LHS)) on member-access targets, plus one explicit (uint8_t*) for the capture_pool[i] subscript (decltype on a subscript yields a reference type, wrong for a cast). ma_saves casts nothing (its state buffers are void*) but needed a goto fix: State_read jumped to its error: label over the initializers of rastate_header and state_rzfile, which C++ forbids (jump into scope past initialization). Both declarations are hoisted above the first goto; state_rzfile in particular must be NULL before any goto reaches error:, which reads it. Behaviour is unchanged. ma_frontend_opts and ma_config are intentionally left as C for now: both rely on C compound-literal arrays (&(char*[]){...}, (Option[]){...}) and out-of-order aggregate designated initializers that do not exist in C++ and need an invasive restructure (a separate later pass), not a mechanical conversion. Builds clean with -std=gnu++2a; minarch.elf links through g++. --- .../{ma_environment.c => ma_environment.cpp} | 5 +++ .../all/minarch/{ma_game.c => ma_game.cpp} | 5 +++ .../minarch/{ma_options.c => ma_options.cpp} | 36 ++++++++++-------- .../minarch/{ma_rewind.c => ma_rewind.cpp} | 38 +++++++++++-------- .../all/minarch/{ma_saves.c => ma_saves.cpp} | 19 ++++++++-- workspace/all/minarch/makefile | 8 ++-- 6 files changed, 73 insertions(+), 38 deletions(-) rename workspace/all/minarch/{ma_environment.c => ma_environment.cpp} (98%) rename workspace/all/minarch/{ma_game.c => ma_game.cpp} (96%) rename workspace/all/minarch/{ma_options.c => ma_options.cpp} (87%) rename workspace/all/minarch/{ma_rewind.c => ma_rewind.cpp} (94%) rename workspace/all/minarch/{ma_saves.c => ma_saves.cpp} (94%) diff --git a/workspace/all/minarch/ma_environment.c b/workspace/all/minarch/ma_environment.cpp similarity index 98% rename from workspace/all/minarch/ma_environment.c rename to workspace/all/minarch/ma_environment.cpp index 3f4da0452..a656f2791 100644 --- a/workspace/all/minarch/ma_environment.c +++ b/workspace/all/minarch/ma_environment.cpp @@ -1,10 +1,15 @@ #include +// Project C headers declare C-linkage symbols (core, config, LOG_*, …) defined +// in the still-C translation units. Include them as extern "C" so this C++ unit +// links against the unmangled names. (Same pattern as ma_audio.cpp.) +extern "C" { #include "ma_internal.h" #include "ma_options.h" #include "ma_input.h" #include "ra_integration.h" #include "ma_environment.h" +} static bool set_rumble_state(unsigned port, enum retro_rumble_effect effect, uint16_t strength) { // TODO: handle other args? not sure I can diff --git a/workspace/all/minarch/ma_game.c b/workspace/all/minarch/ma_game.cpp similarity index 96% rename from workspace/all/minarch/ma_game.c rename to workspace/all/minarch/ma_game.cpp index 3048e54c2..6e6b6c182 100644 --- a/workspace/all/minarch/ma_game.c +++ b/workspace/all/minarch/ma_game.cpp @@ -6,8 +6,13 @@ #include #include +// Project C headers declare C-linkage symbols (core, game, LOG_*, …) defined in +// the still-C translation units. Include them as extern "C" so this C++ unit +// links against the unmangled names. (Same pattern as ma_audio.cpp.) +extern "C" { #include "ma_internal.h" #include "ma_game.h" +} struct Game game; struct retro_disk_control_ext_callback disk_control_ext; diff --git a/workspace/all/minarch/ma_options.c b/workspace/all/minarch/ma_options.cpp similarity index 87% rename from workspace/all/minarch/ma_options.c rename to workspace/all/minarch/ma_options.cpp index 6775e6414..2e65e7746 100644 --- a/workspace/all/minarch/ma_options.c +++ b/workspace/all/minarch/ma_options.cpp @@ -1,10 +1,16 @@ -#include "ma_internal.h" -#include "ma_options.h" - #include #include #include +// Project C headers declare C-linkage symbols (config, core, LOG_*, …) defined +// in the still-C translation units. Include them as extern "C" so this C++ unit +// links against the unmangled names. calloc() results are cast to (decltype(LHS)) +// because C++ won't implicitly convert void*. (Same pattern as ma_audio.cpp.) +extern "C" { +#include "ma_internal.h" +#include "ma_options.h" +} + int Option_getValueIndex(Option* item, const char* value) { if (!value || !item || !item->values) return 0; int i = 0; @@ -45,7 +51,7 @@ void OptionList_init(const struct retro_core_option_definition *defs) { config.core.count = count; config.core.categories = NULL; // There is no categories in v1 definition if (count) { - config.core.options = calloc(count+1, sizeof(Option)); + config.core.options = (decltype(config.core.options))calloc(count+1, sizeof(Option)); for (int i=0; iinfo) { len = strlen(def->info) + 1; - item->desc = calloc(len, sizeof(char)); + item->desc = (decltype(item->desc))calloc(len, sizeof(char)); strncpy(item->desc, def->info, len); - item->full = calloc(len, sizeof(char)); + item->full = (decltype(item->full))calloc(len, sizeof(char)); strncpy(item->full, item->desc, len); // item->desc[len-1] = '\0'; @@ -74,8 +80,8 @@ void OptionList_init(const struct retro_core_option_definition *defs) { for (count=0; def->values[count].value; count++); item->count = count; - item->values = calloc(count+1, sizeof(char*)); - item->labels = calloc(count+1, sizeof(char*)); + item->values = (decltype(item->values))calloc(count+1, sizeof(char*)); + item->labels = (decltype(item->labels))calloc(count+1, sizeof(char*)); for (int j=0; jvalues[j].value; @@ -119,7 +125,7 @@ void OptionList_v2_init(const struct retro_core_options_v2 *opt_defs) { // TODO: add frontend options to this? so the can use the same override method? eg. minarch_* if (cat_count) { - config.core.categories = calloc(cat_count + 1, sizeof(OptionCategory)); + config.core.categories = (decltype(config.core.categories))calloc(cat_count + 1, sizeof(OptionCategory)); for (int i=0; ivalues[count].value; count++); item->count = count; - item->values = calloc(count+1, sizeof(char*)); - item->labels = calloc(count+1, sizeof(char*)); + item->values = (decltype(item->values))calloc(count+1, sizeof(char*)); + item->labels = (decltype(item->labels))calloc(count+1, sizeof(char*)); for (int j=0; jvalues[j].value; @@ -192,7 +198,7 @@ void OptionList_vars(const struct retro_variable *vars) { config.core.count = count; if (count) { - config.core.options = calloc(count+1, sizeof(Option)); + config.core.options = (decltype(config.core.options))calloc(count+1, sizeof(Option)); for (int i=0; icount = count; - item->values = calloc(count+1, sizeof(char*)); - item->labels = calloc(count+1, sizeof(char*)); + item->values = (decltype(item->values))calloc(count+1, sizeof(char*)); + item->labels = (decltype(item->labels))calloc(count+1, sizeof(char*)); tmp = opt; int j; diff --git a/workspace/all/minarch/ma_rewind.c b/workspace/all/minarch/ma_rewind.cpp similarity index 94% rename from workspace/all/minarch/ma_rewind.c rename to workspace/all/minarch/ma_rewind.cpp index 7cddefd96..0c73aea95 100644 --- a/workspace/all/minarch/ma_rewind.c +++ b/workspace/all/minarch/ma_rewind.cpp @@ -1,10 +1,16 @@ -#include "ma_internal.h" -#include "ma_rewind.h" - #include #include #include +// Project C headers declare C-linkage symbols (core, rewind_ctx, rewind_st, ff, +// LOG_*, …) defined in the still-C translation units. Include them as extern "C" +// so this C++ unit links against the unmangled names. (Same pattern as +// ma_audio.cpp.) +extern "C" { +#include "ma_internal.h" +#include "ma_rewind.h" +} + RewindContext rewind_ctx = {0}; #define REWIND_ENTRY_SIZE_HINT 4096 // assumed avg entry size for capacity calc @@ -301,14 +307,14 @@ int Rewind_init(size_t state_size) { LOG_info("Rewind: config enable=%i bufferMB=%i interval=%ims audio=%i compression=raw\n", enable, buf_mb, gran, audio); } - rewind_ctx.buffer = calloc(1, rewind_ctx.capacity); + rewind_ctx.buffer = (decltype(rewind_ctx.buffer))calloc(1, rewind_ctx.capacity); if (!rewind_ctx.buffer) { LOG_error("Rewind: failed to allocate buffer\n"); return 0; } rewind_ctx.state_size = state_size; - rewind_ctx.state_buf = calloc(1, state_size); + rewind_ctx.state_buf = (decltype(rewind_ctx.state_buf))calloc(1, state_size); if (!rewind_ctx.state_buf) { LOG_error("Rewind: failed to allocate state buffer\n"); Rewind_free(); @@ -317,7 +323,7 @@ int Rewind_init(size_t state_size) { rewind_ctx.scratch_size = LZ4_compressBound((int)state_size); if (!rewind_ctx.compress) rewind_ctx.scratch_size = state_size; - rewind_ctx.scratch = calloc(1, rewind_ctx.scratch_size); + rewind_ctx.scratch = (decltype(rewind_ctx.scratch))calloc(1, rewind_ctx.scratch_size); if (!rewind_ctx.scratch) { LOG_error("Rewind: failed to allocate scratch buffer\n"); Rewind_free(); @@ -325,9 +331,9 @@ int Rewind_init(size_t state_size) { } // Allocate delta compression buffers (separate for encode/decode to avoid race conditions) - rewind_ctx.prev_state_enc = calloc(1, state_size); - rewind_ctx.prev_state_dec = calloc(1, state_size); - rewind_ctx.delta_buf = calloc(1, state_size); + rewind_ctx.prev_state_enc = (decltype(rewind_ctx.prev_state_enc))calloc(1, state_size); + rewind_ctx.prev_state_dec = (decltype(rewind_ctx.prev_state_dec))calloc(1, state_size); + rewind_ctx.delta_buf = (decltype(rewind_ctx.delta_buf))calloc(1, state_size); if (!rewind_ctx.prev_state_enc || !rewind_ctx.prev_state_dec || !rewind_ctx.delta_buf) { LOG_error("Rewind: failed to allocate delta buffers\n"); Rewind_free(); @@ -339,7 +345,7 @@ int Rewind_init(size_t state_size) { int entry_cap = rewind_ctx.capacity / REWIND_ENTRY_SIZE_HINT; if (entry_cap < REWIND_MIN_ENTRIES) entry_cap = REWIND_MIN_ENTRIES; rewind_ctx.entry_capacity = entry_cap; - rewind_ctx.entries = calloc(entry_cap, sizeof(RewindEntry)); + rewind_ctx.entries = (decltype(rewind_ctx.entries))calloc(entry_cap, sizeof(RewindEntry)); if (!rewind_ctx.entries) { LOG_error("Rewind: failed to allocate entry table\n"); Rewind_free(); @@ -377,18 +383,18 @@ int Rewind_init(size_t state_size) { // Larger states need a deeper pool to avoid drops; cap to a modest size to limit RAM rewind_ctx.pool_size = (state_size > REWIND_LARGE_STATE_THRESHOLD) ? REWIND_POOL_SIZE_LARGE : REWIND_POOL_SIZE_SMALL; if (rewind_ctx.pool_size < 1) rewind_ctx.pool_size = 1; - rewind_ctx.capture_pool = calloc(rewind_ctx.pool_size, sizeof(uint8_t*)); - rewind_ctx.capture_gen = calloc(rewind_ctx.pool_size, sizeof(unsigned int)); - rewind_ctx.capture_busy = calloc(rewind_ctx.pool_size, sizeof(uint8_t)); - rewind_ctx.free_stack = calloc(rewind_ctx.pool_size, sizeof(int)); - rewind_ctx.queue = calloc(rewind_ctx.pool_size, sizeof(int)); + rewind_ctx.capture_pool = (decltype(rewind_ctx.capture_pool))calloc(rewind_ctx.pool_size, sizeof(uint8_t*)); + rewind_ctx.capture_gen = (decltype(rewind_ctx.capture_gen))calloc(rewind_ctx.pool_size, sizeof(unsigned int)); + rewind_ctx.capture_busy = (decltype(rewind_ctx.capture_busy))calloc(rewind_ctx.pool_size, sizeof(uint8_t)); + rewind_ctx.free_stack = (decltype(rewind_ctx.free_stack))calloc(rewind_ctx.pool_size, sizeof(int)); + rewind_ctx.queue = (decltype(rewind_ctx.queue))calloc(rewind_ctx.pool_size, sizeof(int)); if (!rewind_ctx.capture_pool || !rewind_ctx.capture_gen || !rewind_ctx.capture_busy || !rewind_ctx.free_stack || !rewind_ctx.queue) { LOG_error("Rewind: failed to allocate async capture buffers\n"); Rewind_free(); return 0; } for (int i = 0; i < rewind_ctx.pool_size; i++) { - rewind_ctx.capture_pool[i] = calloc(1, state_size); + rewind_ctx.capture_pool[i] = (uint8_t*)calloc(1, state_size); if (!rewind_ctx.capture_pool[i]) { LOG_error("Rewind: failed to allocate capture slot %i\n", i); Rewind_free(); diff --git a/workspace/all/minarch/ma_saves.c b/workspace/all/minarch/ma_saves.cpp similarity index 94% rename from workspace/all/minarch/ma_saves.c rename to workspace/all/minarch/ma_saves.cpp index 18c9cb510..b8e6fc54d 100644 --- a/workspace/all/minarch/ma_saves.c +++ b/workspace/all/minarch/ma_saves.cpp @@ -4,6 +4,11 @@ #include #include +// Project C headers declare C-linkage symbols (core, game, LOG_*, the libretro +// streams API, …) defined in the still-C translation units. Include them as +// extern "C" so this C++ unit links against the unmangled names. (Same pattern +// as ma_audio.cpp.) +extern "C" { #include "ma_internal.h" #include "ra_integration.h" #include "notification.h" @@ -14,6 +19,7 @@ #endif #include "ma_saves.h" +} /////////////////////////////////////// @@ -212,6 +218,15 @@ int State_read(void) { // from picoarch int was_ff = ff.active; ff.active = 0; + // Hoisted above the first `goto error` below: C++ forbids a goto that jumps + // over a variable's initialization into its scope, and the error: label is + // in scope for these. state_rzfile in particular MUST be NULL before any + // goto reaches error: (which reads it). filename/state need no hoist. + uint8_t rastate_header[RASTATE_HEADER_SIZE] = {0}; +#ifdef HAS_SRM + rzipstream_t *state_rzfile = NULL; +#endif + void *state = calloc(1, state_size); if (!state) { LOG_error("Couldn't allocate memory for state\n"); @@ -221,11 +236,7 @@ int State_read(void) { // from picoarch char filename[MAX_PATH]; State_getPath(filename); - uint8_t rastate_header[RASTATE_HEADER_SIZE] = {0}; - #ifdef HAS_SRM - rzipstream_t *state_rzfile = NULL; - state_rzfile = rzipstream_open(filename, RETRO_VFS_FILE_ACCESS_READ); if(!state_rzfile) { if (state_slot!=8) { // st8 is a default state in MiniUI and may not exist, that's okay diff --git a/workspace/all/minarch/makefile b/workspace/all/minarch/makefile index 65d81f70c..a5838cedb 100644 --- a/workspace/all/minarch/makefile +++ b/workspace/all/minarch/makefile @@ -26,11 +26,13 @@ INCDIR = -I. -I./libretro-common/include/ -I../common/ -I../../$(PLATFORM)/platf # C and C++ translation units are listed separately. C files compile as C; # C++ files compile as C++; everything links through g++ so the two can mix # as modules are migrated to C++ incrementally. -CSOURCE = $(TARGET).c ma_rewind.c \ - ma_options.c ma_frontend_opts.c ma_saves.c ma_video.c ma_game.c ma_environment.c ma_config.c ma_menu.c \ +CSOURCE = $(TARGET).c \ + ma_frontend_opts.c ma_video.c ma_config.c ma_menu.c \ ../common/scaler.c ../common/utils.c ../common/config.c ../common/api.c \ ../common/notification.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = ma_audio.cpp ma_input.cpp ma_runframe.cpp ma_cheats.cpp ma_core.cpp +CXXSOURCE = ma_audio.cpp ma_input.cpp ma_runframe.cpp ma_cheats.cpp ma_core.cpp \ + ma_rewind.cpp ma_saves.cpp ma_game.cpp ma_environment.cpp \ + ma_options.cpp # RA support ifneq (,$(filter $(PLATFORM),tg5040 tg5050 my355 desktop)) From 6ad01fcd7c89cb001cc27a73d7db61b7e47af8ab Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Mon, 6 Jul 2026 09:56:59 +0200 Subject: [PATCH 52/77] minarch: convert ma_video and ma_menu to C++ Two more minarch TUs move from C to C++ (12 of ~16 now C++). Both wrap their project C headers in extern "C" to link the unmangled C-linkage symbols and move from CSOURCE to CXXSOURCE. ma_video: - bitmap_font was a C99 sparse designated array (['0'] = ...); g++ 8.3 rejects non-trivial array designators in C++, so it becomes a {char, rows} pair table with a small linear lookup (bitmap_glyph). Debug HUD only, not a hot path. - renderer.blit (void*) <- GFX_getScaler() (scaler_t fn ptr): explicit cast. ma_menu (the invasive one): - 47x &(SDL_Rect){...} scratch-rect args: g++ 8.3 rejects taking the address of a compound literal in C++ ("taking address of temporary"). Introduce RectArg{ SDL_Rect{...} } -- a class temporary whose lifetime spans the enclosing call and converts to SDL_Rect*. Verified correct on the tg5040 g++ 8.3 toolchain at -O3 -Ofast -flto; handles brace-less-if and loop-variable sites with no restructuring. - 7x (char*[]){...} button-hint arrays: g++ 8.3 silently drops the temp array's storage; route through real static/local storage. - options_menu: (MenuItem[]){...} file-scope compound-literal array (also mutated at runtime) hoisted to a named static; elements fully designated in declaration order. menu global: [ITEM_*]= array designators -> positional, .items reordered ahead of scalar fields. - const/void*/sign conversions the C compiler allowed now cast explicitly. Builds green on tg5040. --- .../all/minarch/{ma_menu.c => ma_menu.cpp} | 264 ++++++++++-------- .../all/minarch/{ma_video.c => ma_video.cpp} | 151 +++++----- workspace/all/minarch/makefile | 4 +- 3 files changed, 233 insertions(+), 186 deletions(-) rename workspace/all/minarch/{ma_menu.c => ma_menu.cpp} (88%) rename workspace/all/minarch/{ma_video.c => ma_video.cpp} (93%) diff --git a/workspace/all/minarch/ma_menu.c b/workspace/all/minarch/ma_menu.cpp similarity index 88% rename from workspace/all/minarch/ma_menu.c rename to workspace/all/minarch/ma_menu.cpp index 0274b60dc..f2cc77c95 100644 --- a/workspace/all/minarch/ma_menu.c +++ b/workspace/all/minarch/ma_menu.cpp @@ -7,6 +7,10 @@ #include #include #include + +// Project C headers declare C-linkage symbols defined in the still-C translation +// units; include them as extern "C" so this C++ TU links the unmangled names. +extern "C" { #include #include "defines.h" #include "api.h" @@ -22,6 +26,19 @@ #include "ma_video.h" #include "ma_frontend_opts.h" #include "ma_menu.h" +} + +// g++ 8.3 rejects taking the address of an SDL_Rect compound literal in C++ +// ("taking address of temporary"), the scratch-rect idiom this file used +// throughout. RectArg wraps an SDL_Rect in a class temporary whose lifetime +// spans the enclosing call and implicitly converts to SDL_Rect*, so a former +// address-of-compound-literal becomes RectArg{ SDL_Rect{ ...fields... } }. +// Verified correct on the tg5040 g++ 8.3 toolchain at -O3 -Ofast -flto. +struct RectArg { SDL_Rect r; operator SDL_Rect*() { return &r; } }; + +// g++ 8.3 silently drops the backing storage of a (char*[]){...} temporary array +// passed as an argument, so shared button-hint lists get their own real storage. +static const char* BACK_PAIR[] = { "B", "BACK", NULL }; /////////////////////////////// @@ -50,13 +67,13 @@ void MSG_init(void) { int i = 0; while ((c = chars[i])) { digit = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, c, COLOR_WHITE); - SDL_BlitSurface(digit, NULL, digits, &(SDL_Rect){ (i * SCALE1(DIGIT_WIDTH)) + (SCALE1(DIGIT_WIDTH) - digit->w)/2, (SCALE1(DIGIT_HEIGHT) - digit->h)/2}); + SDL_BlitSurface(digit, NULL, digits, RectArg{ SDL_Rect{ (i * SCALE1(DIGIT_WIDTH)) + (SCALE1(DIGIT_WIDTH) - digit->w)/2, (SCALE1(DIGIT_HEIGHT) - digit->h)/2} }); SDL_FreeSurface(digit); i += 1; } } static int MSG_blitChar(int n, int x, int y) { - if (n!=DIGIT_SPACE) SDL_BlitSurface(digits, &(SDL_Rect){n*SCALE1(DIGIT_WIDTH),0,SCALE2(DIGIT_WIDTH,DIGIT_HEIGHT)}, screen, &(SDL_Rect){x,y}); + if (n!=DIGIT_SPACE) SDL_BlitSurface(digits, RectArg{ SDL_Rect{n*SCALE1(DIGIT_WIDTH),0,SCALE2(DIGIT_WIDTH,DIGIT_HEIGHT)} }, screen, RectArg{ SDL_Rect{x,y} }); return x + SCALE1(DIGIT_WIDTH + DIGIT_TRACKING); } static int MSG_blitInt(int num, int x, int y) { @@ -152,18 +169,20 @@ static struct { int preview_exists; } menu = { .bitmap = NULL, + // Positional, in ITEM_CONT..ITEM_QUIT order (0..4); C++ has no [index]= + // array designators. Reordered ahead of the scalar fields below because + // C++ requires designated initializers in declaration order. + .items = { + "Continue", + "Save", + "Load", + "Options", + "Quit", + }, .disc = -1, .total_discs = 0, .save_exists = 0, .preview_exists = 0, - - .items = { - [ITEM_CONT] = "Continue", - [ITEM_SAVE] = "Save", - [ITEM_LOAD] = "Load", - [ITEM_OPTS] = "Options", - [ITEM_QUIT] = "Quit", - } }; void Menu_init(void) { @@ -405,9 +424,9 @@ static int OptionAchievements_showDetail(MenuList* list, int i) { snprintf(points_str, sizeof(points_str), "%u points", ach->points); } SDL_Surface* points_text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, points_str, COLOR_LIGHT_TEXT); - SDL_BlitSurface(points_text, NULL, screen, &(SDL_Rect){ + SDL_BlitSurface(points_text, NULL, screen, RectArg{ SDL_Rect{ center_x - points_text->w / 2, content_y - }); + } }); content_y += points_text->h + SCALE1(2); SDL_FreeSurface(points_text); @@ -417,18 +436,18 @@ static int OptionAchievements_showDetail(MenuList* list, int i) { char time_buf[64]; strftime(time_buf, sizeof(time_buf), "Unlocked %B %d %Y, %I:%M%p", tm_info); SDL_Surface* time_text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, time_buf, COLOR_LIGHT_TEXT); - SDL_BlitSurface(time_text, NULL, screen, &(SDL_Rect){ + SDL_BlitSurface(time_text, NULL, screen, RectArg{ SDL_Rect{ center_x - time_text->w / 2, content_y - }); + } }); content_y += time_text->h + SCALE1(2); SDL_FreeSurface(time_text); } else if (ach->measured_progress[0]) { char progress_buf[64]; snprintf(progress_buf, sizeof(progress_buf), "Progress: %s", ach->measured_progress); SDL_Surface* progress_text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, progress_buf, COLOR_LIGHT_TEXT); - SDL_BlitSurface(progress_text, NULL, screen, &(SDL_Rect){ + SDL_BlitSurface(progress_text, NULL, screen, RectArg{ SDL_Rect{ center_x - progress_text->w / 2, content_y - }); + } }); content_y += progress_text->h + SCALE1(2); SDL_FreeSurface(progress_text); } @@ -442,10 +461,10 @@ static int OptionAchievements_showDetail(MenuList* list, int i) { int text_x = icon_x + wifi_size + SCALE1(4); int wifi_y = content_y + (offline_text->h - wifi_size) / 2; GFX_blitAssetColor(ASSET_WIFI_OFF, NULL, screen, - &(SDL_Rect){icon_x, wifi_y}, 0xCCCCCC); - SDL_BlitSurface(offline_text, NULL, screen, &(SDL_Rect){ + RectArg{ SDL_Rect{icon_x, wifi_y} }, 0xCCCCCC); + SDL_BlitSurface(offline_text, NULL, screen, RectArg{ SDL_Rect{ text_x, content_y - }); + } }); content_y += offline_text->h + SCALE1(2); SDL_FreeSurface(offline_text); } @@ -455,9 +474,9 @@ static int OptionAchievements_showDetail(MenuList* list, int i) { char rarity_buf[32]; snprintf(rarity_buf, sizeof(rarity_buf), "%.2f%% unlock rate", ach->rarity); SDL_Surface* rarity_text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, rarity_buf, COLOR_LIGHT_TEXT); - SDL_BlitSurface(rarity_text, NULL, screen, &(SDL_Rect){ + SDL_BlitSurface(rarity_text, NULL, screen, RectArg{ SDL_Rect{ center_x - rarity_text->w / 2, content_y - }); + } }); content_y += rarity_text->h + SCALE1(2); SDL_FreeSurface(rarity_text); } @@ -479,9 +498,9 @@ static int OptionAchievements_showDetail(MenuList* list, int i) { } if (type_str) { SDL_Surface* type_text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, type_str, COLOR_LIGHT_TEXT); - SDL_BlitSurface(type_text, NULL, screen, &(SDL_Rect){ + SDL_BlitSurface(type_text, NULL, screen, RectArg{ SDL_Rect{ center_x - type_text->w / 2, content_y - }); + } }); content_y += type_text->h + SCALE1(2); SDL_FreeSurface(type_text); } @@ -497,16 +516,16 @@ static int OptionAchievements_showDetail(MenuList* list, int i) { int icon_y = content_y + SCALE1(4) + (mute_text->h - mute_icon_h) / 2; SDL_Rect mute_src = {0, SCALE1(4), SCALE1(10), SCALE1(12)}; GFX_blitAssetColor(ASSET_VOLUME_MUTE, &mute_src, screen, - &(SDL_Rect){icon_x, icon_y}, 0xCCCCCC); - SDL_BlitSurface(mute_text, NULL, screen, &(SDL_Rect){ + RectArg{ SDL_Rect{icon_x, icon_y} }, 0xCCCCCC); + SDL_BlitSurface(mute_text, NULL, screen, RectArg{ SDL_Rect{ text_x, content_y + SCALE1(4) - }); + } }); SDL_FreeSurface(mute_text); } // Button hints - update based on current mute state - char* hints[] = {"X", is_muted ? "UNMUTE" : "MUTE", "B", "BACK", NULL}; - GFX_blitButtonGroup(hints, 0, screen, 1); + const char* hints[] = {"X", is_muted ? "UNMUTE" : "MUTE", "B", "BACK", NULL}; + GFX_blitButtonGroup((char**)hints, 0, screen, 1); GFX_flip(screen); dirty = 0; } @@ -521,7 +540,7 @@ static int OptionAchievements_showDetail(MenuList* list, int i) { static int OptionAchievements_openMenu(MenuList* list, int i) { if (!RA_isGameLoaded()) { - Menu_message("No achievements found for this game.\n\nThis ROM may need a compatibility patch\nor may not be a supported version.\n\nVisit retroachievements.org to check\nsupported game files.", (char*[]){"B","BACK", NULL}); + Menu_message("No achievements found for this game.\n\nThis ROM may need a compatibility patch\nor may not be a supported version.\n\nVisit retroachievements.org to check\nsupported game files.", (char**)BACK_PAIR); return MENU_CALLBACK_NOP; } @@ -529,7 +548,7 @@ static int OptionAchievements_openMenu(MenuList* list, int i) { RA_getAchievementSummary(&unlocked, &total); if (total == 0) { - Menu_message("No achievements available for this game.\n\nThis game may not have achievements yet.\n\nVisit retroachievements.org for details.", (char*[]){"B","BACK", NULL}); + Menu_message("No achievements available for this game.\n\nThis game may not have achievements yet.\n\nVisit retroachievements.org for details.", (char**)BACK_PAIR); return MENU_CALLBACK_NOP; } @@ -549,7 +568,7 @@ static int OptionAchievements_openMenu(MenuList* list, int i) { RC_CLIENT_ACHIEVEMENT_CATEGORY_CORE, RC_CLIENT_ACHIEVEMENT_LIST_GROUPING_LOCK_STATE); if (!ach_menu_list) { - Menu_message("Failed to load achievements", (char*[]){"B","BACK", NULL}); + Menu_message("Failed to load achievements", (char**)BACK_PAIR); return MENU_CALLBACK_NOP; } @@ -564,12 +583,12 @@ static int OptionAchievements_openMenu(MenuList* list, int i) { ach_menu_list = NULL; // This can happen with unsupported game versions where pseudo-achievements // are counted in the summary but not available in the achievement list - Menu_message("Achievement list not available", (char*[]){"B","BACK", NULL}); + Menu_message("Achievement list not available", (char**)BACK_PAIR); return MENU_CALLBACK_NOP; } // Create flattened array of all achievement pointers - const rc_client_achievement_t** all_achievements = calloc(total_achievements, sizeof(rc_client_achievement_t*)); + const rc_client_achievement_t** all_achievements = (const rc_client_achievement_t**)calloc(total_achievements, sizeof(rc_client_achievement_t*)); int idx = 0; for (uint32_t b = 0; b < ach_menu_list->num_buckets && idx < total_achievements; b++) { const rc_client_achievement_bucket_t* bucket = &ach_menu_list->buckets[b]; @@ -590,7 +609,7 @@ static int OptionAchievements_openMenu(MenuList* list, int i) { int max_visible = (screen->h - ((SCALE1(PADDING + PILL_SIZE) * 2) + SCALE1(BUTTON_SIZE))) / SCALE1(BUTTON_SIZE); // Allocate filtered array once (max size = all achievements) - const rc_client_achievement_t** filtered = calloc(total_achievements, sizeof(rc_client_achievement_t*)); + const rc_client_achievement_t** filtered = (const rc_client_achievement_t**)calloc(total_achievements, sizeof(rc_client_achievement_t*)); int filtered_count = 0; // Hide "Unknown Emulator" warning (ID 101000001) when hardcore mode is disabled. @@ -628,7 +647,7 @@ static int OptionAchievements_openMenu(MenuList* list, int i) { ach_menu_list = NULL; ach_menu_achievements = NULL; ach_menu_count = 0; - Menu_message("No achievements found", (char*[]){"B","BACK", NULL}); + Menu_message("No achievements found", (char**)BACK_PAIR); return MENU_CALLBACK_NOP; } @@ -729,10 +748,10 @@ static int OptionAchievements_openMenu(MenuList* list, int i) { char status_text[64]; snprintf(status_text, sizeof(status_text), "%u/%u unlocked", unlocked, total); SDL_Surface* status_surface = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, status_text, COLOR_WHITE); - SDL_BlitSurface(status_surface, NULL, screen, &(SDL_Rect){ + SDL_BlitSurface(status_surface, NULL, screen, RectArg{ SDL_Rect{ (screen->w - status_surface->w) / 2, SCALE1(PADDING) + (SCALE1(PILL_SIZE) - status_surface->h) / 2 // Vertically centered with pill - }); + } }); SDL_FreeSurface(status_surface); // Calculate vertical centering for list only @@ -757,17 +776,17 @@ static int OptionAchievements_openMenu(MenuList* list, int i) { if (is_selected) { // Gray pill background for full row width (like MENU_FIXED selected) - GFX_blitPillLight(ASSET_BUTTON, screen, &(SDL_Rect){ + GFX_blitPillLight(ASSET_BUTTON, screen, RectArg{ SDL_Rect{ ox, oy + SCALE1(row * BUTTON_SIZE), mw, row_height - }); + } }); } // Draw ">" on the right side (always white) SDL_Surface* arrow = TTF_RenderUTF8_Blended(GFX_getFonts()->small, ">", COLOR_WHITE); - SDL_BlitSurface(arrow, NULL, screen, &(SDL_Rect){ + SDL_BlitSurface(arrow, NULL, screen, RectArg{ SDL_Rect{ ox + mw - arrow->w - opt_pad, oy + SCALE1((row * BUTTON_SIZE) + 3) - }); + } }); SDL_FreeSurface(arrow); if (is_selected) { @@ -786,9 +805,9 @@ static int OptionAchievements_openMenu(MenuList* list, int i) { } int pill_width = opt_pad + badge_display_size + SCALE1(6) + mute_width + offline_width + title_width + opt_pad; - GFX_blitPillDark(ASSET_BUTTON, screen, &(SDL_Rect){ + GFX_blitPillDark(ASSET_BUTTON, screen, RectArg{ SDL_Rect{ ox, oy + SCALE1(row * BUTTON_SIZE), pill_width, row_height - }); + } }); text_color = uintToColour(THEME_COLOR5_255); // Badge icon inside the white pill @@ -811,7 +830,7 @@ static int OptionAchievements_openMenu(MenuList* list, int i) { int mute_y = oy + SCALE1(row * BUTTON_SIZE) + (row_height - mute_icon_h) / 2; SDL_Rect mute_src = {0, SCALE1(4), SCALE1(10), SCALE1(12)}; GFX_blitAssetColor(ASSET_VOLUME_MUTE, &mute_src, screen, - &(SDL_Rect){text_x, mute_y}, THEME_COLOR5_255); + RectArg{ SDL_Rect{text_x, mute_y} }, THEME_COLOR5_255); text_x += mute_width; } @@ -820,16 +839,16 @@ static int OptionAchievements_openMenu(MenuList* list, int i) { int wifi_size = SCALE1(12); int wifi_y = oy + SCALE1(row * BUTTON_SIZE) + (row_height - wifi_size) / 2; GFX_blitAssetColor(ASSET_WIFI_OFF, NULL, screen, - &(SDL_Rect){text_x, wifi_y}, THEME_COLOR5_255); + RectArg{ SDL_Rect{text_x, wifi_y} }, THEME_COLOR5_255); text_x += offline_width; } // Title text SDL_Surface* title_text = TTF_RenderUTF8_Blended(GFX_getFonts()->small, ach->title, text_color); - SDL_BlitSurface(title_text, NULL, screen, &(SDL_Rect){ + SDL_BlitSurface(title_text, NULL, screen, RectArg{ SDL_Rect{ text_x, oy + SCALE1((row * BUTTON_SIZE) + 1) - }); + } }); SDL_FreeSurface(title_text); } else { // Unselected row - just badge + title + indicators, no pills @@ -855,7 +874,7 @@ static int OptionAchievements_openMenu(MenuList* list, int i) { int mute_y = oy + SCALE1(row * BUTTON_SIZE) + (row_height - mute_icon_h) / 2; SDL_Rect mute_src = {0, SCALE1(4), SCALE1(10), SCALE1(12)}; GFX_blitAssetColor(ASSET_VOLUME_MUTE, &mute_src, screen, - &(SDL_Rect){text_x, mute_y}, RGB_WHITE); + RectArg{ SDL_Rect{text_x, mute_y} }, RGB_WHITE); text_x += SCALE1(10) + SCALE1(4); } @@ -864,24 +883,24 @@ static int OptionAchievements_openMenu(MenuList* list, int i) { int wifi_size = SCALE1(12); int wifi_y = oy + SCALE1(row * BUTTON_SIZE) + (row_height - wifi_size) / 2; GFX_blitAssetColor(ASSET_WIFI_OFF, NULL, screen, - &(SDL_Rect){text_x, wifi_y}, RGB_WHITE); + RectArg{ SDL_Rect{text_x, wifi_y} }, RGB_WHITE); text_x += wifi_size + SCALE1(4); } // Title text (white for unselected) SDL_Surface* title_text = TTF_RenderUTF8_Blended(GFX_getFonts()->small, ach->title, COLOR_WHITE); - SDL_BlitSurface(title_text, NULL, screen, &(SDL_Rect){ + SDL_BlitSurface(title_text, NULL, screen, RectArg{ SDL_Rect{ text_x, oy + SCALE1((row * BUTTON_SIZE) + 1) - }); + } }); SDL_FreeSurface(title_text); } } // Button hints at bottom with dynamic Y and X button text int selected_muted = (filtered_count > 0) ? RA_isAchievementMuted(filtered[selected]->id) : 0; - char* hints[] = {"Y", ach_filter_locked_only ? "SHOW ALL" : "SHOW LOCKED", "X", selected_muted ? "UNMUTE" : "MUTE", NULL}; - GFX_blitButtonGroup(hints, 0, screen, 1); + const char* hints[] = {"Y", ach_filter_locked_only ? "SHOW ALL" : "SHOW LOCKED", "X", selected_muted ? "UNMUTE" : "MUTE", NULL}; + GFX_blitButtonGroup((char**)hints, 0, screen, 1); GFX_flip(screen); dirty = 0; @@ -901,20 +920,26 @@ static int OptionAchievements_openMenu(MenuList* list, int i) { return MENU_CALLBACK_NOP; } +// Hoisted out of options_menu's initializer: C++ has no (MenuItem[]){...} +// compound-literal array, and this table is mutated at runtime (see +// Options_updateVisibility), so it needs its own writable static storage. +// Each element is fully designated in declaration order (name, desc, on_confirm) +// because C++ forbids mixing positional and designated initializers. +static MenuItem options_menu_items[] = { + {.name="Frontend", .desc="NextUI (" BUILD_DATE " " BUILD_HASH ")", .on_confirm=OptionFrontend_openMenu}, + {.name="Emulator", .on_confirm=OptionEmulator_openMenu}, + {.name="Shaders", .on_confirm=OptionShaders_openMenu}, + {.name="Cheats", .on_confirm=OptionCheats_openMenu}, + {.name="Controls", .on_confirm=OptionControls_openMenu}, + {.name="Shortcuts", .on_confirm=OptionShortcuts_openMenu}, + {.name="Achievements", .on_confirm=OptionAchievements_openMenu}, + {.name="Save Changes", .on_confirm=OptionSaveChanges_openMenu}, + {NULL}, + {NULL}, +}; static MenuList options_menu = { .type = MENU_LIST, - .items = (MenuItem[]) { - {"Frontend", "NextUI (" BUILD_DATE " " BUILD_HASH ")",.on_confirm=OptionFrontend_openMenu}, - {"Emulator",.on_confirm=OptionEmulator_openMenu}, - {"Shaders",.on_confirm=OptionShaders_openMenu}, - {"Cheats",.on_confirm=OptionCheats_openMenu}, - {"Controls",.on_confirm=OptionControls_openMenu}, - {"Shortcuts",.on_confirm=OptionShortcuts_openMenu}, - {"Achievements",.on_confirm=OptionAchievements_openMenu}, - {"Save Changes",.on_confirm=OptionSaveChanges_openMenu}, - {NULL}, - {NULL}, - } + .items = options_menu_items, }; // Track the index of Save Changes menu item (changes based on RA visibility) @@ -1202,21 +1227,21 @@ int Menu_options(MenuList* list) { TTF_SizeUTF8(GFX_getFonts()->small, item->name, &w, NULL); w += SCALE1(OPTION_PADDING*2); - GFX_blitPillDark(ASSET_BUTTON, screen, &(SDL_Rect){ + GFX_blitPillDark(ASSET_BUTTON, screen, RectArg{ SDL_Rect{ ox, oy+SCALE1(j*BUTTON_SIZE), w, SCALE1(BUTTON_SIZE) - }); + } }); text_color = uintToColour(THEME_COLOR5_255); if (item->desc) desc = item->desc; } text = TTF_RenderUTF8_Blended(GFX_getFonts()->small, item->name, text_color); - SDL_BlitSurface(text, NULL, screen, &(SDL_Rect){ + SDL_BlitSurface(text, NULL, screen, RectArg{ SDL_Rect{ ox+SCALE1(OPTION_PADDING), oy+SCALE1((j*BUTTON_SIZE)+1) - }); + } }); SDL_FreeSurface(text); } } @@ -1236,21 +1261,21 @@ int Menu_options(MenuList* list) { if (j==selected_row) { // gray pill - GFX_blitPillLight(ASSET_BUTTON, screen, &(SDL_Rect){ + GFX_blitPillLight(ASSET_BUTTON, screen, RectArg{ SDL_Rect{ ox, oy+SCALE1(j*BUTTON_SIZE), mw, SCALE1(BUTTON_SIZE) - }); + } }); } if (item->values == NULL) { // This is a navigation item, used to displayed a specific category text = TTF_RenderUTF8_Blended(GFX_getFonts()->small, ">", COLOR_WHITE); // always white - SDL_BlitSurface(text, NULL, screen, &(SDL_Rect){ + SDL_BlitSurface(text, NULL, screen, RectArg{ SDL_Rect{ ox + mw - text->w - SCALE1(OPTION_PADDING), oy+SCALE1((j*BUTTON_SIZE)+3) - }); + } }); SDL_FreeSurface(text); } else { @@ -1261,10 +1286,10 @@ int Menu_options(MenuList* list) { const char *str = item->values[item->value]; text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, str ? str : "none", str ? COLOR_WHITE : COLOR_GRAY); // always white if (text) { - SDL_BlitSurface(text, NULL, screen, &(SDL_Rect){ + SDL_BlitSurface(text, NULL, screen, RectArg{ SDL_Rect{ ox + mw - text->w - SCALE1(OPTION_PADDING), oy+SCALE1((j*BUTTON_SIZE)+3) - }); + } }); SDL_FreeSurface(text); } } @@ -1277,21 +1302,21 @@ int Menu_options(MenuList* list) { int w = 0; TTF_SizeUTF8(GFX_getFonts()->small, item->name, &w, NULL); w += SCALE1(OPTION_PADDING*2); - GFX_blitPillDark(ASSET_BUTTON, screen, &(SDL_Rect){ + GFX_blitPillDark(ASSET_BUTTON, screen, RectArg{ SDL_Rect{ ox, oy+SCALE1(j*BUTTON_SIZE), w, SCALE1(BUTTON_SIZE) - }); + } }); text_color = uintToColour(THEME_COLOR5_255); if (item->desc) desc = item->desc; } text = TTF_RenderUTF8_Blended(GFX_getFonts()->small, item->name, text_color); - SDL_BlitSurface(text, NULL, screen, &(SDL_Rect){ + SDL_BlitSurface(text, NULL, screen, RectArg{ SDL_Rect{ ox+SCALE1(OPTION_PADDING), oy+SCALE1((j*BUTTON_SIZE)+1) - }); + } }); SDL_FreeSurface(text); } } @@ -1337,32 +1362,32 @@ int Menu_options(MenuList* list) { if (j==selected_row) { // gray pill - GFX_blitPillLight(ASSET_BUTTON, screen, &(SDL_Rect){ + GFX_blitPillLight(ASSET_BUTTON, screen, RectArg{ SDL_Rect{ ox, oy+SCALE1(j*BUTTON_SIZE), mw, SCALE1(BUTTON_SIZE) - }); + } }); // white pill int w = 0; TTF_SizeUTF8(GFX_getFonts()->small, item->name, &w, NULL); w += SCALE1(OPTION_PADDING*2); - GFX_blitPillDark(ASSET_BUTTON, screen, &(SDL_Rect){ + GFX_blitPillDark(ASSET_BUTTON, screen, RectArg{ SDL_Rect{ ox, oy+SCALE1(j*BUTTON_SIZE), w, SCALE1(BUTTON_SIZE) - }); + } }); text_color = uintToColour(THEME_COLOR5_255); if (item->desc) desc = item->desc; } text = TTF_RenderUTF8_Blended(GFX_getFonts()->small, item->name, text_color); - SDL_BlitSurface(text, NULL, screen, &(SDL_Rect){ + SDL_BlitSurface(text, NULL, screen, RectArg{ SDL_Rect{ ox+SCALE1(OPTION_PADDING), oy+SCALE1((j*BUTTON_SIZE)+1) - }); + } }); SDL_FreeSurface(text); if (await_input && j==selected_row) { @@ -1373,10 +1398,10 @@ int Menu_options(MenuList* list) { while ( item->values && item->values[count]) count++; if (item->value >= 0 && item->value < count) { text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, item->values[item->value], COLOR_WHITE); // always white - SDL_BlitSurface(text, NULL, screen, &(SDL_Rect){ + SDL_BlitSurface(text, NULL, screen, RectArg{ SDL_Rect{ ox + mw - text->w - SCALE1(OPTION_PADDING), oy+SCALE1((j*BUTTON_SIZE)+3) - }); + } }); SDL_FreeSurface(text); } } @@ -1388,8 +1413,8 @@ int Menu_options(MenuList* list) { #define SCROLL_HEIGHT 4 int ox = (screen->w - SCALE1(SCROLL_WIDTH))/2; int oy = SCALE1((PILL_SIZE - SCROLL_HEIGHT) / 2); - if (start>0) GFX_blitAsset(ASSET_SCROLL_UP, NULL, screen, &(SDL_Rect){ox, SCALE1(PADDING) + oy}); - if (endh - SCALE1(PADDING + PILL_SIZE + BUTTON_SIZE) + oy}); + if (start>0) GFX_blitAsset(ASSET_SCROLL_UP, NULL, screen, RectArg{ SDL_Rect{ox, SCALE1(PADDING) + oy} }); + if (endh - SCALE1(PADDING + PILL_SIZE + BUTTON_SIZE) + oy} }); } if (!desc && list->desc) desc = list->desc; @@ -1397,11 +1422,11 @@ int Menu_options(MenuList* list) { if (desc) { int w,h; GFX_sizeText(GFX_getFonts()->tiny, desc, SCALE1(12), &w,&h); - GFX_blitText(GFX_getFonts()->tiny, desc, SCALE1(12), COLOR_WHITE, screen, &(SDL_Rect){ + GFX_blitText(GFX_getFonts()->tiny, desc, SCALE1(12), COLOR_WHITE, screen, RectArg{ SDL_Rect{ (screen->w - w) / 2, screen->h - SCALE1(PADDING) - h, w,h - }); + } }); } GFX_flip(screen); @@ -1419,8 +1444,8 @@ int Menu_options(MenuList* list) { static void Menu_scale(SDL_Surface* src, SDL_Surface* dst) { // LOG_info("Menu_scale src: %ix%i dst: %ix%i\n", src->w,src->h,dst->w,dst->h); - uint16_t* s = src->pixels; - uint16_t* d = dst->pixels; + uint16_t* s = (uint16_t*)src->pixels; + uint16_t* d = (uint16_t*)dst->pixels; int sw = src->w; int sh = src->h; @@ -1632,8 +1657,8 @@ void Menu_screenshot(void) { snprintf(png_path, sizeof(png_path), SDCARD_PATH "/Screenshots/%s.%s.png", rom_name, buffer); int cw, ch; unsigned char* pixels = GFX_GL_screenCapture(&cw, &ch); - SaveImageArgs* args = malloc(sizeof(SaveImageArgs)); - args->pixels = pixels; + SaveImageArgs* args = (SaveImageArgs*)malloc(sizeof(SaveImageArgs)); + args->pixels = (char*)pixels; args->w = cw; args->h = ch; args->path = SDL_strdup(png_path); @@ -1658,8 +1683,8 @@ void Menu_saveState(void) { if (newScreenshot) { int cw, ch; unsigned char* pixels = GFX_GL_screenCapture(&cw, &ch); - SaveImageArgs* args = malloc(sizeof(SaveImageArgs)); - args->pixels = pixels; + SaveImageArgs* args = (SaveImageArgs*)malloc(sizeof(SaveImageArgs)); + args->pixels = (char*)pixels; args->w = cw; args->h = ch; args->path = SDL_strdup(menu.bmp_path); @@ -1914,26 +1939,33 @@ void Menu_loop(void) { SDL_Surface* text; text = TTF_RenderUTF8_Blended(GFX_getFonts()->large, display_name, uintToColour(THEME_COLOR6_255)); - GFX_blitPillLight(ASSET_WHITE_PILL, screen, &(SDL_Rect){ + GFX_blitPillLight(ASSET_WHITE_PILL, screen, RectArg{ SDL_Rect{ SCALE1(PADDING), SCALE1(PADDING), max_width, SCALE1(PILL_SIZE) - }); - SDL_BlitSurface(text, &(SDL_Rect){ + } }); + SDL_BlitSurface(text, RectArg{ SDL_Rect{ 0, 0, max_width-SCALE1(BUTTON_PADDING*2), text->h - }, screen, &(SDL_Rect){ + } }, screen, RectArg{ SDL_Rect{ SCALE1(PADDING+BUTTON_PADDING), SCALE1(PADDING+4) - }); + } }); SDL_FreeSurface(text); if (show_setting && !GetHDMI()) GFX_blitHardwareHints(screen, show_setting); - else GFX_blitButtonGroup((char*[]){ BTN_SLEEP==BTN_POWER?"POWER":"MENU","SLEEP", NULL }, 0, screen, 0); - GFX_blitButtonGroup((char*[]){ "B","BACK", "A","OKAY", NULL }, 1, screen, 1); + else { + // Hoisted: g++ 8.3 silently drops (char*[]){...} temp-array storage. + const char* sleep_hints[] = { BTN_SLEEP==BTN_POWER?"POWER":"MENU", "SLEEP", NULL }; + GFX_blitButtonGroup((char**)sleep_hints, 0, screen, 0); + } + { + const char* nav_hints[] = { "B","BACK", "A","OKAY", NULL }; + GFX_blitButtonGroup((char**)nav_hints, 1, screen, 1); + } // list oy = (((DEVICE_HEIGHT / FIXED_SCALE) - PADDING * 2) - (MENU_ITEM_COUNT * PILL_SIZE)) / 2; @@ -1946,17 +1978,17 @@ void Menu_loop(void) { // disc change if (menu.total_discs>1 && i==ITEM_CONT) { - GFX_blitPillDark(ASSET_WHITE_PILL, screen, &(SDL_Rect){ + GFX_blitPillDark(ASSET_WHITE_PILL, screen, RectArg{ SDL_Rect{ SCALE1(PADDING), SCALE1(oy + PADDING), screen->w - SCALE1(PADDING * 2), SCALE1(PILL_SIZE) - }); + } }); text = TTF_RenderUTF8_Blended(GFX_getFonts()->large, disc_name, text_color); - SDL_BlitSurface(text, NULL, screen, &(SDL_Rect){ + SDL_BlitSurface(text, NULL, screen, RectArg{ SDL_Rect{ screen->w - SCALE1(PADDING + BUTTON_PADDING) - text->w, SCALE1(oy + PADDING + 4) - }); + } }); SDL_FreeSurface(text); } @@ -1964,21 +1996,21 @@ void Menu_loop(void) { ow += SCALE1(BUTTON_PADDING*2); // pill - GFX_blitPillDark(ASSET_WHITE_PILL, screen, &(SDL_Rect){ + GFX_blitPillDark(ASSET_WHITE_PILL, screen, RectArg{ SDL_Rect{ SCALE1(PADDING), SCALE1(oy + PADDING + (i * PILL_SIZE)), ow, SCALE1(PILL_SIZE) - }); + } }); } // text text = TTF_RenderUTF8_Blended(GFX_getFonts()->large, item, text_color); - SDL_BlitSurface(text, NULL, screen, &(SDL_Rect){ + SDL_BlitSurface(text, NULL, screen, RectArg{ SDL_Rect{ SCALE1(PADDING + BUTTON_PADDING), SCALE1(oy + PADDING + (i * PILL_SIZE) + 4) - }); + } }); SDL_FreeSurface(text); } @@ -1995,7 +2027,7 @@ void Menu_loop(void) { oy = (DEVICE_HEIGHT - ph) / 2; // window - GFX_blitRect(ASSET_STATE_BG, screen, &(SDL_Rect){ox,oy,pw,ph}); + GFX_blitRect(ASSET_STATE_BG, screen, RectArg{ SDL_Rect{ox,oy,pw,ph} }); ox += SCALE1(WINDOW_RADIUS); oy += SCALE1(WINDOW_RADIUS); @@ -2011,7 +2043,7 @@ void Menu_loop(void) { SDL_Rect preview_rect = {ox,oy,hw,hh}; SDL_FillRect(screen, &preview_rect, SDL_MapRGBA(screen->format,0,0,0,255)); SDL_BlitScaled(bmp,NULL,preview,NULL); - SDL_BlitSurface(preview, NULL, screen, &(SDL_Rect){ox,oy}); + SDL_BlitSurface(preview, NULL, screen, RectArg{ SDL_Rect{ox,oy} }); SDL_FreeSurface(bmp); } else { @@ -2025,8 +2057,8 @@ void Menu_loop(void) { ox += (pw-SCALE1(15*MENU_SLOT_COUNT))/2; oy += hh+SCALE1(WINDOW_RADIUS); for (int i=0; i #include +// Project C headers declare C-linkage symbols defined in the still-C translation +// units; include them as extern "C" so this C++ unit links against the unmangled +// names. ( further down is self-guarded and stays where it is.) +extern "C" { #include "ma_internal.h" #include "scaler.h" #include "ma_video.h" +} -static const char* bitmap_font[] = { - ['0'] = +// A sparse char->glyph table. Was a C99 designated array (`['0'] = ...`); g++ 8.3 +// rejects sparse/non-trivial array designators in C++, so it's a {char, rows} pair +// table with a linear lookup (see bitmap_glyph) — the debug HUD is not hot. +struct BitmapGlyph { unsigned char ch; const char* rows; }; +static const BitmapGlyph bitmap_font[] = { + { '0', " 111 " "1 1" "1 1" @@ -16,8 +25,8 @@ static const char* bitmap_font[] = { "11 1" "1 1" "1 1" - " 111 ", - ['1'] = + " 111 " }, + { '1', " 1 " " 111 " " 1 " @@ -26,8 +35,8 @@ static const char* bitmap_font[] = { " 1 " " 1 " " 1 " - " 1 ", - ['2'] = + " 1 " }, + { '2', " 111 " "1 1" " 1" @@ -36,8 +45,8 @@ static const char* bitmap_font[] = { " 1 " "1 " "1 " - "11111", - ['3'] = + "11111" }, + { '3', " 111 " "1 1" " 1" @@ -46,8 +55,8 @@ static const char* bitmap_font[] = { " 1" " 1" "1 1" - " 111 ", - ['4'] = + " 111 " }, + { '4', "1 1" "1 1" "1 1" @@ -56,8 +65,8 @@ static const char* bitmap_font[] = { "1 1" "11111" " 1" - " 1", - ['5'] = + " 1" }, + { '5', "11111" "1 " "1 " @@ -66,8 +75,8 @@ static const char* bitmap_font[] = { " 1" " 1" "1 1" - " 111 ", - ['6'] = + " 111 " }, + { '6', " 111 " "1 " "1 " @@ -76,8 +85,8 @@ static const char* bitmap_font[] = { "1 1" "1 1" "1 1" - " 111 ", - ['7'] = + " 111 " }, + { '7', "11111" " 1" " 1" @@ -86,8 +95,8 @@ static const char* bitmap_font[] = { " 1 " " 1 " " 1 " - " 1 ", - ['8'] = + " 1 " }, + { '8', " 111 " "1 1" "1 1" @@ -96,8 +105,8 @@ static const char* bitmap_font[] = { "1 1" "1 1" "1 1" - " 111 ", - ['9'] = + " 111 " }, + { '9', " 111 " "1 1" "1 1" @@ -106,8 +115,8 @@ static const char* bitmap_font[] = { " 1111" " 1" " 1" - " 111 ", - ['.'] = + " 111 " }, + { '.', " " " " " " @@ -116,8 +125,8 @@ static const char* bitmap_font[] = { " " " " " 11 " - " 11 ", - [','] = + " 11 " }, + { ',', " " " " " " @@ -126,8 +135,8 @@ static const char* bitmap_font[] = { " " " 1 " " 1 " - " 1 ", - [' '] = + " 1 " }, + { ' ', " " " " " " @@ -136,8 +145,8 @@ static const char* bitmap_font[] = { " " " " " " - " ", - ['('] = + " " }, + { '(', " 1 " " 1 " " 1 " @@ -146,8 +155,8 @@ static const char* bitmap_font[] = { " 1 " " 1 " " 1 " - " 1 ", - [')'] = + " 1 " }, + { ')', " 1 " " 1 " " 1 " @@ -156,8 +165,8 @@ static const char* bitmap_font[] = { " 1 " " 1 " " 1 " - " 1 ", - ['/'] = + " 1 " }, + { '/', " 1 " " 1 " " 1 " @@ -166,8 +175,8 @@ static const char* bitmap_font[] = { " 1 " " 1 " " 1 " - " 1 ", - ['x'] = + " 1 " }, + { 'x', " " " " "1 1" @@ -176,8 +185,8 @@ static const char* bitmap_font[] = { " 1 " " 1 1 " "1 1" - "1 1", - ['%'] = + "1 1" }, + { '%', " 1 " "1 1 " "1 1 1" @@ -186,8 +195,8 @@ static const char* bitmap_font[] = { " 1 1 " "1 1 1" " 1 1" - " 1 ", - ['-'] = + " 1 " }, + { '-', " " " " " " @@ -196,8 +205,8 @@ static const char* bitmap_font[] = { " " " " " " - " ", - ['c'] = + " " }, + { 'c', " " " " " 111 " @@ -206,8 +215,8 @@ static const char* bitmap_font[] = { "1 " "1 " "1 1" - " 111 ", - ['m'] = + " 111 " }, + { 'm', " " " " "11 11" @@ -216,8 +225,8 @@ static const char* bitmap_font[] = { "1 1" "1 1" "1 1" - "1 1", - ['z'] = + "1 1" }, + { 'z', " " " " " " @@ -226,8 +235,8 @@ static const char* bitmap_font[] = { " 1 " " 1 " "1 " - "11111", - ['h'] = + "11111" }, + { 'h', " " "1 " "1 " @@ -236,8 +245,8 @@ static const char* bitmap_font[] = { "1 1" "1 1" "1 1" - "1 1", - ['D'] = + "1 1" }, + { 'D', "1111 " "1 1" "1 1" @@ -246,8 +255,8 @@ static const char* bitmap_font[] = { "1 1" "1 1" "1 1" - "1111 ", - ['J'] = + "1111 " }, + { 'J', " 111" " 1" " 1" @@ -256,8 +265,8 @@ static const char* bitmap_font[] = { "1 1" "1 1" "1 1" - " 111 ", - ['A'] = + " 111 " }, + { 'A', " 1 " " 1 1 " "1 1" @@ -266,8 +275,8 @@ static const char* bitmap_font[] = { "1 1" "1 1" "1 1" - "1 1", - ['M'] = + "1 1" }, + { 'M', "1 1" "11 11" "1 1 1" @@ -276,8 +285,8 @@ static const char* bitmap_font[] = { "1 1" "1 1" "1 1" - "1 1", - [':'] = + "1 1" }, + { ':', " " " " " 1 " @@ -286,8 +295,8 @@ static const char* bitmap_font[] = { " " " 1 " " " - " ", - ['B'] = + " " }, + { 'B', "1111 " "1 1" "1 1" @@ -296,8 +305,8 @@ static const char* bitmap_font[] = { "1 1" "1 1" "1 1" - "1111 ", - ['C'] = + "1111 " }, + { 'C', " 111 " "1 1" "1 " @@ -306,8 +315,8 @@ static const char* bitmap_font[] = { "1 " "1 " "1 1" - " 111 ", - ['N'] = + " 111 " }, + { 'N', "1 1" "1 1" "11 1" @@ -316,8 +325,8 @@ static const char* bitmap_font[] = { "1 1" "1 11" "1 1" - "1 1", - ['H'] = + "1 1" }, + { 'H', "1 1" "1 1" "1 1" @@ -326,9 +335,15 @@ static const char* bitmap_font[] = { "1 1" "1 1" "1 1" - "1 1", + "1 1" }, }; +static const char* bitmap_glyph(unsigned char ch) { + for (unsigned i = 0; i < sizeof(bitmap_font) / sizeof(bitmap_font[0]); i++) + if (bitmap_font[i].ch == ch) return bitmap_font[i].rows; + return NULL; +} + void drawRect(int x, int y, int w, int h, uint32_t c, uint32_t *data, int stride) { for (int _x = x; _x < x + w; _x++) { data[_x + y * stride] = c; @@ -378,8 +393,8 @@ static void blitBitmapText(char* text, int ox, int oy, uint32_t* data, int strid // uint32_t* row = data + y * stride; int current_x = 0; for (int i = 0; i < len; i++) { - const char* c = bitmap_font[(unsigned char)text[i]]; - if (!c) c = bitmap_font[' ']; + const char* c = bitmap_glyph((unsigned char)text[i]); + if (!c) c = bitmap_glyph(' '); for (int x = 0; x < DEBUG_CHAR_WIDTH; x++) { if (current_x >= w) break; @@ -633,7 +648,7 @@ void selectScaler(int src_w, int src_h, int src_p) { renderer.scale = scale; renderer.aspect = (scaling==SCALE_ASPECT_SCREEN) ? aspect: (scaling==SCALE_NATIVE||scaling==SCALE_CROPPED)?0:(scaling==SCALE_FULLSCREEN?-1:core.aspect_ratio); - renderer.blit = GFX_getScaler(&renderer); + renderer.blit = (decltype(renderer.blit))GFX_getScaler(&renderer); } static void screen_flip(SDL_Surface* screen) { diff --git a/workspace/all/minarch/makefile b/workspace/all/minarch/makefile index a5838cedb..26327f067 100644 --- a/workspace/all/minarch/makefile +++ b/workspace/all/minarch/makefile @@ -27,12 +27,12 @@ INCDIR = -I. -I./libretro-common/include/ -I../common/ -I../../$(PLATFORM)/platf # C++ files compile as C++; everything links through g++ so the two can mix # as modules are migrated to C++ incrementally. CSOURCE = $(TARGET).c \ - ma_frontend_opts.c ma_video.c ma_config.c ma_menu.c \ + ma_frontend_opts.c ma_config.c \ ../common/scaler.c ../common/utils.c ../common/config.c ../common/api.c \ ../common/notification.c ../../$(PLATFORM)/platform/platform.c CXXSOURCE = ma_audio.cpp ma_input.cpp ma_runframe.cpp ma_cheats.cpp ma_core.cpp \ ma_rewind.cpp ma_saves.cpp ma_game.cpp ma_environment.cpp \ - ma_options.cpp + ma_options.cpp ma_video.cpp ma_menu.cpp # RA support ifneq (,$(filter $(PLATFORM),tg5040 tg5050 my355 desktop)) From 4b2838aaea8fb852144cc46fbaae1de665fa15e2 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Mon, 6 Jul 2026 10:21:36 +0200 Subject: [PATCH 53/77] minarch: convert ma_frontend_opts to C++ ma_frontend_opts.c -> ma_frontend_opts.cpp (13 of ~16 minarch TUs now C++). Wrap project C headers in extern "C"; move to CXXSOURCE. Applies the same recipe proven on ma_menu: - 2x &(SDL_Rect){...} -> RectArg{ SDL_Rect{...} } (address-of-temporary). - 9x (char*[]){...} button-hint arrays -> shared static storage (BACK_PAIR / OKAY_PAIR); g++ 8.3 silently drops the temp array's storage otherwise. - 8 MenuList globals had .items designated after .on_confirm/.on_change; C++ requires designators in declaration order, so each is reordered (type, [desc,] items, on_confirm, on_change). - OptionSaveChanges_menu's (MenuItem[]){...} inline array hoisted to a named static. - 11 calloc/realloc results cast via (decltype(lhs)) (all member-access LHS). Builds green on tg5040. --- ...a_frontend_opts.c => ma_frontend_opts.cpp} | 92 +++++++++++-------- workspace/all/minarch/makefile | 4 +- 2 files changed, 56 insertions(+), 40 deletions(-) rename workspace/all/minarch/{ma_frontend_opts.c => ma_frontend_opts.cpp} (86%) diff --git a/workspace/all/minarch/ma_frontend_opts.c b/workspace/all/minarch/ma_frontend_opts.cpp similarity index 86% rename from workspace/all/minarch/ma_frontend_opts.c rename to workspace/all/minarch/ma_frontend_opts.cpp index a70d89bb6..9946f7820 100644 --- a/workspace/all/minarch/ma_frontend_opts.c +++ b/workspace/all/minarch/ma_frontend_opts.cpp @@ -1,13 +1,28 @@ +#include +#include +#include +#include + +// Project C headers declare C-linkage symbols defined in the still-C translation +// units; include them as extern "C" so this C++ TU links the unmangled names. +extern "C" { #include "ma_internal.h" #include "ma_frontend_opts.h" #include "ma_cheats.h" #include "ra_integration.h" #include "notification.h" +} -#include -#include -#include -#include +// g++ 8.3 rejects taking the address of an SDL_Rect compound literal in C++ +// ("taking address of temporary"). RectArg wraps one in a class temporary whose +// lifetime spans the enclosing call and converts to SDL_Rect*, so a former +// RectArg{ SDL_Rect{...} } becomes RectArg{ SDL_Rect{...} }. Verified on tg5040 g++ 8.3. +struct RectArg { SDL_Rect r; operator SDL_Rect*() { return &r; } }; + +// g++ 8.3 silently drops the backing storage of a (char*[]){...} temporary array +// passed as an argument, so shared button-hint lists get real static storage. +static const char* BACK_PAIR[] = { "B", "BACK", NULL }; +static const char* OKAY_PAIR[] = { "A", "OKAY", NULL }; int Menu_messageWithFont(char* message, char** pairs, TTF_Font* f) { GFX_setMode(MODE_MAIN); @@ -22,7 +37,7 @@ int Menu_messageWithFont(char* message, char** pairs, TTF_Font* f) { GFX_clear(screen); - GFX_blitMessage(f, message, screen, &(SDL_Rect){SCALE1(PADDING),SCALE1(PADDING),screen->w-SCALE1(2*PADDING),screen->h-SCALE1(PILL_SIZE+PADDING)}); + GFX_blitMessage(f, message, screen, RectArg{ SDL_Rect{SCALE1(PADDING),SCALE1(PADDING),screen->w-SCALE1(2*PADDING),screen->h-SCALE1(PILL_SIZE+PADDING)} }); GFX_blitButtonGroup(pairs, 0, screen, 1); GFX_flip(screen); dirty = 0; @@ -51,8 +66,8 @@ static int OptionFrontend_optionChanged(MenuList* list, int i) { } static MenuList OptionFrontend_menu = { .type = MENU_VAR, - .on_change = OptionFrontend_optionChanged, .items = NULL, + .on_change = OptionFrontend_optionChanged, }; int OptionFrontend_openMenu(MenuList* list, int i) { if (OptionFrontend_menu.items==NULL) { @@ -63,7 +78,7 @@ int OptionFrontend_openMenu(MenuList* list, int i) { if (!config.frontend.options[i].lock) enabled_count += 1; } config.frontend.enabled_count = enabled_count; - config.frontend.enabled_options = calloc(enabled_count+1, sizeof(Option*)); + config.frontend.enabled_options = (decltype(config.frontend.enabled_options))calloc(enabled_count+1, sizeof(Option*)); int j = 0; for (int i=0; ikey); - if (option->full) return Menu_messageWithFont(option->full, (char*[]){ "B","BACK", NULL }, GFX_getFonts()->medium); + if (option->full) return Menu_messageWithFont(option->full, (char**)BACK_PAIR, GFX_getFonts()->medium); else return MENU_CALLBACK_NOP; } } @@ -156,7 +171,7 @@ int OptionEmulator_openMenu(MenuList* list, int index) { } int enabled_count = 0; - config.core.enabled_options = calloc(config.core.count + 1, sizeof(Option*)); + config.core.enabled_options = (decltype(config.core.enabled_options))calloc(config.core.count + 1, sizeof(Option*)); for (int i=0; icategory) { - Menu_message("This category has no options.", (char*[]){ "B","BACK", NULL }); + Menu_message("This category has no options.", (char**)BACK_PAIR); } else { - Menu_message("This core has no options.", (char*[]){ "B","BACK", NULL }); + Menu_message("This core has no options.", (char**)BACK_PAIR); } } @@ -286,9 +301,9 @@ static MenuList OptionControls_menu = { .desc = "Press A to set and X to clear." "\nSupports single button and MENU+button." // TODO: not supported on nano because POWER doubles as MENU , + .items = NULL, .on_confirm = OptionControls_bind, .on_change = OptionControls_unbind, - .items = NULL }; int OptionControls_openMenu(MenuList* list, int i) { @@ -297,7 +312,7 @@ int OptionControls_openMenu(MenuList* list, int i) { if (OptionControls_menu.items==NULL) { // TODO: where do I free this? - OptionControls_menu.items = calloc(RETRO_BUTTON_COUNT+1+has_custom_controllers, sizeof(MenuItem)); + OptionControls_menu.items = (decltype(OptionControls_menu.items))calloc(RETRO_BUTTON_COUNT+1+has_custom_controllers, sizeof(MenuItem)); int k = 0; if (has_custom_controllers) { @@ -387,9 +402,9 @@ static MenuList OptionShortcuts_menu = { .desc = "Press A to set and X to clear." "\nSupports single button and MENU+button." // TODO: not supported on nano because POWER doubles as MENU , + .items = NULL, .on_confirm = OptionShortcuts_bind, .on_change = OptionShortcuts_unbind, - .items = NULL }; char* getSaveDesc(void) { switch (config.loaded) { @@ -402,7 +417,7 @@ char* getSaveDesc(void) { int OptionShortcuts_openMenu(MenuList* list, int i) { if (OptionShortcuts_menu.items==NULL) { // TODO: where do I free this? I guess I don't :sweat_smile: - OptionShortcuts_menu.items = calloc(SHORTCUT_COUNT+1, sizeof(MenuItem)); + OptionShortcuts_menu.items = (decltype(OptionShortcuts_menu.items))calloc(SHORTCUT_COUNT+1, sizeof(MenuItem)); for (int j=0; config.shortcuts[j].name; j++) { ButtonMapping* button = &config.shortcuts[j]; MenuItem* item = &OptionShortcuts_menu.items[j]; @@ -447,19 +462,20 @@ static int OptionSaveChanges_onConfirm(MenuList* list, int i) { break; } } - Menu_message(message, (char*[]){ "A","OKAY", NULL }); + Menu_message(message, (char**)OKAY_PAIR); OptionSaveChanges_updateDesc(); return MENU_CALLBACK_EXIT; } +static MenuItem OptionSaveChanges_items[] = { + {"Save for console"}, + {"Save for game"}, + {"Restore defaults"}, + {NULL}, +}; static MenuList OptionSaveChanges_menu = { .type = MENU_LIST, + .items = OptionSaveChanges_items, .on_confirm = OptionSaveChanges_onConfirm, - .items = (MenuItem[]){ - {"Save for console"}, - {"Save for game"}, - {"Restore defaults"}, - {NULL}, - } }; int OptionSaveChanges_openMenu(MenuList* list, int i) { OptionSaveChanges_updateDesc(); @@ -494,20 +510,20 @@ static int OptionCheats_optionDetail(MenuList* list, int i) { MenuItem* item = &list->items[i]; struct Cheat *cheat = &cheatcodes.cheats[i]; if (cheat->info) - return Menu_message((char*)cheat->info, (char*[]){ "B","BACK", NULL }); + return Menu_message((char*)cheat->info, (char**)BACK_PAIR); else return MENU_CALLBACK_NOP; } static MenuList OptionCheats_menu = { .type = MENU_FIXED, + .items = NULL, .on_confirm = OptionCheats_optionDetail, // TODO: this needs pagination to be truly useful .on_change = OptionCheats_optionChanged, - .items = NULL, }; int OptionCheats_openMenu(MenuList* list, int i) { if (OptionCheats_menu.items == NULL) { // populate - OptionCheats_menu.items = calloc(cheatcodes.count + 1, sizeof(MenuItem)); + OptionCheats_menu.items = (decltype(OptionCheats_menu.items))calloc(cheatcodes.count + 1, sizeof(MenuItem)); for (int i = 0; iinfo) { len = strlen(cheat->info) + 1; - item->desc = calloc(len, sizeof(char)); + item->desc = (decltype(item->desc))calloc(len, sizeof(char)); strncpy(item->desc, cheat->info, len); GFX_wrapText(GFX_getFonts()->tiny, item->desc, DEVICE_WIDTH - SCALE1(2*PADDING), 2); } @@ -588,7 +604,7 @@ int OptionCheats_openMenu(MenuList* list, int i) { } } - Menu_messageWithFont(cheats_path, (char*[]){ "B","BACK", NULL }, GFX_getFonts()->small); + Menu_messageWithFont(cheats_path, (char**)BACK_PAIR, GFX_getFonts()->small); } return MENU_CALLBACK_NOP; @@ -617,9 +633,9 @@ static int OptionPragmas_optionChanged(MenuList* list, int i) { static MenuList PragmasOptions_menu = { .type = MENU_FIXED, + .items = NULL, .on_confirm = NULL, .on_change = OptionPragmas_optionChanged, - .items = NULL }; static int OptionPragmas_openMenu(MenuList* list, int i) { int progressCount = 0; @@ -627,7 +643,7 @@ static int OptionPragmas_openMenu(MenuList* list, int i) { for (int y=0; y < config.shaders.options[SH_NROFSHADERS].value; y++) { totalcount += config.shaderpragmas[y].count; } - PragmasOptions_menu.items = calloc(totalcount + 1, sizeof(MenuItem)); + PragmasOptions_menu.items = (decltype(PragmasOptions_menu.items))calloc(totalcount + 1, sizeof(MenuItem)); for (int y=0; y < config.shaders.options[SH_NROFSHADERS].value; y++) { for (int j = 0; j < config.shaderpragmas[y].count; j++) { MenuItem* item = &PragmasOptions_menu.items[progressCount]; @@ -645,7 +661,7 @@ static int OptionPragmas_openMenu(MenuList* list, int i) { if (PragmasOptions_menu.items[0].name) { Menu_options(&PragmasOptions_menu); } else { - Menu_message("No extra settings found", (char*[]){"B", "BACK", NULL}); + Menu_message("No extra settings found", (char**)BACK_PAIR); } return MENU_CALLBACK_NOP; @@ -680,9 +696,9 @@ static int OptionShaders_optionChanged(MenuList* list, int i) { static MenuList ShaderOptions_menu = { .type = MENU_FIXED, + .items = NULL, .on_confirm = NULL, .on_change = OptionShaders_optionChanged, - .items = NULL }; int OptionShaders_openMenu(MenuList* list, int i) { @@ -691,11 +707,11 @@ int OptionShaders_openMenu(MenuList* list, int i) { // Check if folder read failed or no files found if (!filelist || filecount == 0) { - Menu_message("No shaders available\n/Shaders folder or shader files not found", (char*[]){"B", "BACK", NULL}); + Menu_message("No shaders available\n/Shaders folder or shader files not found", (char**)BACK_PAIR); return MENU_CALLBACK_NOP; } - ShaderOptions_menu.items = calloc(config.shaders.count + 1, sizeof(MenuItem)); + ShaderOptions_menu.items = (decltype(ShaderOptions_menu.items))calloc(config.shaders.count + 1, sizeof(MenuItem)); for (int i = 0; i < config.shaders.count; i++) { MenuItem* item = &ShaderOptions_menu.items[i]; Option* configitem = &config.shaders.options[i]; @@ -720,7 +736,7 @@ int OptionShaders_openMenu(MenuList* list, int i) { if (ShaderOptions_menu.items[0].name) { Menu_options(&ShaderOptions_menu); } else { - Menu_message("No shaders available\n/Shaders folder or shader files not found", (char*[]){"B", "BACK", NULL}); + Menu_message("No shaders available\n/Shaders folder or shader files not found", (char**)BACK_PAIR); } return MENU_CALLBACK_NOP; diff --git a/workspace/all/minarch/makefile b/workspace/all/minarch/makefile index 26327f067..8be738cb4 100644 --- a/workspace/all/minarch/makefile +++ b/workspace/all/minarch/makefile @@ -27,12 +27,12 @@ INCDIR = -I. -I./libretro-common/include/ -I../common/ -I../../$(PLATFORM)/platf # C++ files compile as C++; everything links through g++ so the two can mix # as modules are migrated to C++ incrementally. CSOURCE = $(TARGET).c \ - ma_frontend_opts.c ma_config.c \ + ma_config.c \ ../common/scaler.c ../common/utils.c ../common/config.c ../common/api.c \ ../common/notification.c ../../$(PLATFORM)/platform/platform.c CXXSOURCE = ma_audio.cpp ma_input.cpp ma_runframe.cpp ma_cheats.cpp ma_core.cpp \ ma_rewind.cpp ma_saves.cpp ma_game.cpp ma_environment.cpp \ - ma_options.cpp ma_video.cpp ma_menu.cpp + ma_options.cpp ma_video.cpp ma_menu.cpp ma_frontend_opts.cpp # RA support ifneq (,$(filter $(PLATFORM),tg5040 tg5050 my355 desktop)) From e844231252834e1bcfff9859db99a206ba7e4701 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Mon, 6 Jul 2026 10:29:45 +0200 Subject: [PATCH 54/77] minarch: convert ma_config to C++ ma_config.c -> ma_config.cpp (14 of ~16 minarch TUs now C++; only the big minarch.c remains). Wrap project C headers in extern "C"; move to CXXSOURCE. - 7 calloc/malloc/realloc results cast via (decltype(lhs)) (the variable is in scope within its own initializer, so this works for the local decls too). - device_button_names used sparse/out-of-order [BTN_ID_*]= array designators (SELECT/START/Y/X/B/A listed against an enum ordered A,B,X,Y,START,SELECT); g++ 8.3 rejects these as "non-trivial designated initializers". Rewritten positional in exact BTN_ID enum order (0..15) so device_button_names[BTN_ID_X] still resolves to the same string. - The config global's .frontend/.core/.shaders.options = (Option[]){...} and .shortcuts = (ButtonMapping[]){...} keep their [FE_OPT_*]/[SH_*]/[SHORTCUT_*] designators: those are dense and in enum order, which g++ 8.3 accepts as trivial. Their trailing bare {NULL} terminators (which mixed positional with designated -> ill-formed in C++) are made designated: [SH_NONE] and [SHORTCUT_COUNT]. Verified on-device that namespace-scope compound-literal arrays get static storage on g++ 8.3 (data survives init, stays mutable), so config.*.options is not left dangling. Builds green on tg5040. --- .../minarch/{ma_config.c => ma_config.cpp} | 58 +++++++++++-------- workspace/all/minarch/makefile | 4 +- 2 files changed, 35 insertions(+), 27 deletions(-) rename workspace/all/minarch/{ma_config.c => ma_config.cpp} (96%) diff --git a/workspace/all/minarch/ma_config.c b/workspace/all/minarch/ma_config.cpp similarity index 96% rename from workspace/all/minarch/ma_config.c rename to workspace/all/minarch/ma_config.cpp index 80b66f506..7f0c9ac59 100644 --- a/workspace/all/minarch/ma_config.c +++ b/workspace/all/minarch/ma_config.cpp @@ -4,9 +4,13 @@ #include #include +// Project C headers declare C-linkage symbols defined in the still-C translation +// units; include them as extern "C" so this C++ TU links the unmangled names. +extern "C" { #include "ma_internal.h" #include "ma_options.h" #include "ma_config.h" +} static ButtonMapping button_label_mapping[] = { // used to lookup the retro_id and local btn_id from button name {"NONE", -1, BTN_ID_NONE}, @@ -226,7 +230,7 @@ char** list_files_in_folder(const char* folderPath, int* fileCount, const char* *fileCount = 0; if(defaultElement) { - fileList = malloc(sizeof(char* ) * 2); + fileList = (decltype(fileList))malloc(sizeof(char* ) * 2); fileList[0] = strdup(defaultElement); fileList[1] = NULL; (*fileCount)++; @@ -251,7 +255,7 @@ char** list_files_in_folder(const char* folderPath, int* fileCount, const char* } } - char** temp = realloc(fileList, sizeof(char*) * (*fileCount + 1)); + char** temp = (decltype(temp))realloc(fileList, sizeof(char*) * (*fileCount + 1)); if (!temp) { perror("realloc"); for (int i = 0; i < *fileCount; ++i) { @@ -281,7 +285,7 @@ char** list_files_in_folder(const char* folderPath, int* fileCount, const char* } // NUll terminate the list - char** temp = realloc(fileList, sizeof(char*) * (*fileCount + 1)); + char** temp = (decltype(temp))realloc(fileList, sizeof(char*) * (*fileCount + 1)); if (!temp) { perror("realloc"); for (int i = 0; i < *fileCount; ++i) { @@ -718,7 +722,7 @@ void readShadersPreset(int i) { void loadShaderSettings(int i) { int menucount = 0; - config.shaderpragmas[i].options = calloc(32 + 1, sizeof(Option)); + config.shaderpragmas[i].options = (decltype(config.shaderpragmas[i].options))calloc(32 + 1, sizeof(Option)); ShaderParam *params = PLAT_getShaderPragmas(i); if(params == NULL) return; for (int j = 0; j < 32; j++) { @@ -738,11 +742,11 @@ void loadShaderSettings(int i) { config.shaderpragmas[i].options[menucount].default_value = params[j].def; int steps = (int)((params[j].max - params[j].min) / params[j].step) + 1; - config.shaderpragmas[i].options[menucount].values = malloc(sizeof(char *) * (steps + 1)); - config.shaderpragmas[i].options[menucount].labels = malloc(sizeof(char *) * (steps + 1)); + config.shaderpragmas[i].options[menucount].values = (decltype(config.shaderpragmas[i].options[menucount].values))malloc(sizeof(char *) * (steps + 1)); + config.shaderpragmas[i].options[menucount].labels = (decltype(config.shaderpragmas[i].options[menucount].labels))malloc(sizeof(char *) * (steps + 1)); for (int s = 0; s < steps; s++) { float val = params[j].min + s * params[j].step; - char *str = malloc(16); + char *str = (decltype(str))malloc(16); snprintf(str, 16, "%.2f", val); config.shaderpragmas[i].options[menucount].values[s] = str; config.shaderpragmas[i].options[menucount].labels[s] = str; @@ -1208,23 +1212,27 @@ ButtonMapping default_button_mapping[] = { // used if pak.cfg doesn't exist or d ButtonMapping core_button_mapping[RETRO_BUTTON_COUNT+1] = {0}; +// Positional in BTN_ID enum order (0..15); C++ rejects the sparse/out-of-order +// [BTN_ID_*]= array designators this used ("non-trivial designated initializers"). +// Order below matches the enum exactly, so indexing device_button_names[BTN_ID_X] +// still yields the same string. static const char* device_button_names[LOCAL_BUTTON_COUNT] = { - [BTN_ID_DPAD_UP] = "UP", - [BTN_ID_DPAD_DOWN] = "DOWN", - [BTN_ID_DPAD_LEFT] = "LEFT", - [BTN_ID_DPAD_RIGHT] = "RIGHT", - [BTN_ID_SELECT] = "SELECT", - [BTN_ID_START] = "START", - [BTN_ID_Y] = "Y", - [BTN_ID_X] = "X", - [BTN_ID_B] = "B", - [BTN_ID_A] = "A", - [BTN_ID_L1] = "L1", - [BTN_ID_R1] = "R1", - [BTN_ID_L2] = "L2", - [BTN_ID_R2] = "R2", - [BTN_ID_L3] = "L3", - [BTN_ID_R3] = "R3", + "UP", // BTN_ID_DPAD_UP (0) + "DOWN", // BTN_ID_DPAD_DOWN (1) + "LEFT", // BTN_ID_DPAD_LEFT (2) + "RIGHT", // BTN_ID_DPAD_RIGHT (3) + "A", // BTN_ID_A (4) + "B", // BTN_ID_B (5) + "X", // BTN_ID_X (6) + "Y", // BTN_ID_Y (7) + "START", // BTN_ID_START (8) + "SELECT", // BTN_ID_SELECT (9) + "L1", // BTN_ID_L1 (10) + "R1", // BTN_ID_R1 (11) + "L2", // BTN_ID_L2 (12) + "R2", // BTN_ID_R2 (13) + "L3", // BTN_ID_L3 (14) + "R3", // BTN_ID_R3 (15) }; @@ -1689,7 +1697,7 @@ struct Config config = { .values = shupscale_labels, .labels = shupscale_labels, }, - {NULL} + [SH_NONE] = {NULL} }, }, .shaderpragmas = {{ @@ -1720,7 +1728,7 @@ struct Config config = { [SHORTCUT_TOGGLE_TURBO_R] = {"Toggle Turbo R", -1, BTN_ID_NONE, 0}, [SHORTCUT_TOGGLE_TURBO_R2] = {"Toggle Turbo R2", -1, BTN_ID_NONE, 0}, // ----- - {NULL} + [SHORTCUT_COUNT] = {NULL} }, }; diff --git a/workspace/all/minarch/makefile b/workspace/all/minarch/makefile index 8be738cb4..1df79dc34 100644 --- a/workspace/all/minarch/makefile +++ b/workspace/all/minarch/makefile @@ -27,12 +27,12 @@ INCDIR = -I. -I./libretro-common/include/ -I../common/ -I../../$(PLATFORM)/platf # C++ files compile as C++; everything links through g++ so the two can mix # as modules are migrated to C++ incrementally. CSOURCE = $(TARGET).c \ - ma_config.c \ + \ ../common/scaler.c ../common/utils.c ../common/config.c ../common/api.c \ ../common/notification.c ../../$(PLATFORM)/platform/platform.c CXXSOURCE = ma_audio.cpp ma_input.cpp ma_runframe.cpp ma_cheats.cpp ma_core.cpp \ ma_rewind.cpp ma_saves.cpp ma_game.cpp ma_environment.cpp \ - ma_options.cpp ma_video.cpp ma_menu.cpp ma_frontend_opts.cpp + ma_options.cpp ma_video.cpp ma_menu.cpp ma_frontend_opts.cpp ma_config.cpp # RA support ifneq (,$(filter $(PLATFORM),tg5040 tg5050 my355 desktop)) From 4091f1fdfc4303023e00670e48fed52648697a0d Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Mon, 6 Jul 2026 10:46:52 +0200 Subject: [PATCH 55/77] minarch: convert minarch.c to C++ (final minarch TU) Renames minarch.c -> minarch.cpp and moves it from CSOURCE to CXXSOURCE. minarch is now 100% C++; only shared common/ and RA C files remain in CSOURCE. C++ conversion fixes: - Wrap project headers (msettings.h, notification.h, ra_integration.h, all ma_*.h incl. ma_runframe.h) in extern "C" so the definitions here and the cross-TU calls resolve to the same unmangled symbols. - Scope the post-Game_open body in main() in its own block: C++ forbids the `goto finish` guard from jumping over the initialized locals (has_pending_opt_change, rewind_initialized, pixels, rawSurface, converted) that are otherwise in scope at the label. - `struct Core core = {}`: Core has const char[] members, so C++ needs explicit zero-init (matches C's static zero-init). - Cast game.data (void*) to const uint8_t* for RA_loadGame. --- workspace/all/minarch/makefile | 7 +++--- .../all/minarch/{minarch.c => minarch.cpp} | 22 ++++++++++++++----- 2 files changed, 20 insertions(+), 9 deletions(-) rename workspace/all/minarch/{minarch.c => minarch.cpp} (93%) diff --git a/workspace/all/minarch/makefile b/workspace/all/minarch/makefile index 1df79dc34..57acb4b9c 100644 --- a/workspace/all/minarch/makefile +++ b/workspace/all/minarch/makefile @@ -26,11 +26,10 @@ INCDIR = -I. -I./libretro-common/include/ -I../common/ -I../../$(PLATFORM)/platf # C and C++ translation units are listed separately. C files compile as C; # C++ files compile as C++; everything links through g++ so the two can mix # as modules are migrated to C++ incrementally. -CSOURCE = $(TARGET).c \ - \ - ../common/scaler.c ../common/utils.c ../common/config.c ../common/api.c \ +CSOURCE = ../common/scaler.c ../common/utils.c ../common/config.c ../common/api.c \ ../common/notification.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = ma_audio.cpp ma_input.cpp ma_runframe.cpp ma_cheats.cpp ma_core.cpp \ +CXXSOURCE = $(TARGET).cpp \ + ma_audio.cpp ma_input.cpp ma_runframe.cpp ma_cheats.cpp ma_core.cpp \ ma_rewind.cpp ma_saves.cpp ma_game.cpp ma_environment.cpp \ ma_options.cpp ma_video.cpp ma_menu.cpp ma_frontend_opts.cpp ma_config.cpp diff --git a/workspace/all/minarch/minarch.c b/workspace/all/minarch/minarch.cpp similarity index 93% rename from workspace/all/minarch/minarch.c rename to workspace/all/minarch/minarch.cpp index a23966fe3..cbd19ead0 100644 --- a/workspace/all/minarch/minarch.c +++ b/workspace/all/minarch/minarch.cpp @@ -1,8 +1,12 @@ #include -#include - #include +// Project C headers declare C-linkage symbols shared with the still-C common/ +// units and with the (now C++) sibling ma_* modules; include them as extern "C" +// so this C++ unit both links against and defines the unmangled names. +extern "C" { +#include + #include "notification.h" #include "ra_integration.h" @@ -19,6 +23,7 @@ #include "ma_environment.h" #include "ma_config.h" #include "ma_runframe.h" +} /////////////////////////////////////// @@ -70,7 +75,7 @@ GFX_Renderer renderer; /////////////////////////////////////// -struct Core core; +struct Core core = {}; // Core has const char[] members; C++ needs explicit zero-init (matches C static init) @@ -173,7 +178,12 @@ int main(int argc , char* argv[]) { Game_open(rom_path); // nes tries to load gamegenie setting before this returns ffs if (!game.is_open) goto finish; - + // C++ forbids `goto` jumping over an initialized local that is still in scope + // at the label. Everything from here to `finish:` lives in its own block so the + // jump above lands outside it (has_pending_opt_change, rewind_initialized, + // pixels, rawSurface, converted are all scoped inside). + { + simple_mode = exists(SIMPLE_MODE_PATH); // restore options @@ -210,7 +220,7 @@ int main(int argc , char* argv[]) { // Pass ROM data if available, otherwise just path (for cores that load from file) { char* rom_path_for_ra = game.tmp_path[0] ? game.tmp_path : game.path; - RA_loadGame(rom_path_for_ra, game.data, game.size, core.tag); + RA_loadGame(rom_path_for_ra, (const uint8_t*)game.data, game.size, core.tag); } State_resume(); @@ -344,6 +354,8 @@ int main(int argc , char* argv[]) { Menu_quit(); QuitSettings(); + } // end goto-scope block + finish: Perf_setCPUMonitorEnabled(0); From 88bb6354e7db92bea065aa93f5b2a311ff9f28e4 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Mon, 6 Jul 2026 11:56:58 +0200 Subject: [PATCH 56/77] minarch: don't let a throwing core abort the emulator on cheat apply Some libretro cores throw a C++ exception (Mednafen::MDFN_Error) instead of returning an error when handed a cheat code they can't parse -- e.g. RetroArch Game Genie format on the supafaust SNES core. Because libretro is a C ABI the frontend never guarded these calls, so the uncaught throw unwound back across the boundary into minarch and hit std::terminate -> the whole emulator aborted. (Pre-existing; the original all-C minarch aborted the same way. Now that minarch is C++ we can actually catch it.) Confirmed on-device: supafaust does not throw from retro_cheat_set -- it stores the code and defers parsing to retro_run(), so the throw escapes core.run() in the emulation loop, not the cheat-set call. - ma_runframe.cpp: wrap the run_frame() body so a core exception during emulation is caught. recoverFromCoreFault() clears the core's cheat state (so the next frame is clean instead of re-throwing), clears the frontend's enabled flags, and shows a one-time "Cheat rejected by core - cheats disabled" notification. - ma_core.cpp: defensively guard retro_cheat_set for cores that throw synchronously, and log when a core doesn't implement cheats at all. - ma_frontend_opts.cpp: the cheat menu's refresh loop skipped disabled cheats, leaving a stale "on" checkbox after auto-disable; mirror the data model unconditionally so the box reflects reality. Verified on tg5040 (Brick): SUPA/supafaust throws -> recovers with toast; PCE/ Beetle PCE doesn't throw -> unaffected; GB/gambatte applies cheats normally. --- workspace/all/minarch/ma_core.cpp | 35 ++++++++++++++++++++-- workspace/all/minarch/ma_frontend_opts.cpp | 8 ++--- workspace/all/minarch/ma_runframe.cpp | 29 ++++++++++++++++++ 3 files changed, 65 insertions(+), 7 deletions(-) diff --git a/workspace/all/minarch/ma_core.cpp b/workspace/all/minarch/ma_core.cpp index 8b757eb6b..9f36bfb95 100644 --- a/workspace/all/minarch/ma_core.cpp +++ b/workspace/all/minarch/ma_core.cpp @@ -1,6 +1,7 @@ #include #include #include +#include // Project C headers declare C-linkage symbols (core, cheatcodes, the retro_* // callbacks, LOG_*, …) defined in the still-C translation units. Include them @@ -107,13 +108,41 @@ void Core_applyCheats(struct Cheats *cheats) if (!cheats) return; - if (!core.cheat_reset || !core.cheat_set) + if (!core.cheat_reset || !core.cheat_set) { + LOG_info("Core_applyCheats: core does not support cheats (retro_cheat_%s unavailable)\n", + !core.cheat_set ? "set" : "reset"); return; + } + + // libretro is a C ABI, but some cores (notably Mednafen/supafaust) throw a C++ + // exception out of retro_cheat_set when handed a cheat code they can't parse + // (e.g. RetroArch Game Genie format "CB01-54DF+..." on a core that expects raw + // address/value pairs). An uncaught throw unwinds back across the boundary into + // the frontend and hits std::terminate -> the whole emulator aborts. Guard each + // core call so a single bad cheat is skipped and logged, and the game survives. + try { + core.cheat_reset(); + } catch (const std::exception& e) { + LOG_error("Core_applyCheats: cheat_reset threw: %s\n", e.what()); + return; + } catch (...) { + LOG_error("Core_applyCheats: cheat_reset threw an unknown exception\n"); + return; + } - core.cheat_reset(); for (int i = 0; i < cheats->count; i++) { - if (cheats->cheats[i].enabled) { + if (!cheats->cheats[i].enabled) + continue; + const char* name = cheats->cheats[i].name ? cheats->cheats[i].name : ""; + const char* code = cheats->cheats[i].code ? cheats->cheats[i].code : ""; + try { + // Most cores parse the code here; some (Mednafen/supafaust) defer to + // retro_run() — that deferred throw is caught in run_frame(). core.cheat_set(i, cheats->cheats[i].enabled, cheats->cheats[i].code); + } catch (const std::exception& e) { + LOG_error("Core_applyCheats: core rejected cheat %d \"%s\" (%s): %s\n", i, name, code, e.what()); + } catch (...) { + LOG_error("Core_applyCheats: core rejected cheat %d \"%s\" (%s): unknown exception\n", i, name, code); } } } diff --git a/workspace/all/minarch/ma_frontend_opts.cpp b/workspace/all/minarch/ma_frontend_opts.cpp index 9946f7820..243c277b1 100644 --- a/workspace/all/minarch/ma_frontend_opts.cpp +++ b/workspace/all/minarch/ma_frontend_opts.cpp @@ -544,13 +544,13 @@ int OptionCheats_openMenu(MenuList* list, int i) { } } else { - // update + // update: mirror the data model unconditionally. run_frame's cheat-fault + // recovery can clear cheat->enabled behind the menu's back, so we must sync + // disabled cheats too (the old `if(!enabled) continue` left a stale "on" + // checkbox after a cheat was auto-disabled). for (int j = 0; j < cheatcodes.count; j++) { struct Cheat *cheat = &cheatcodes.cheats[j]; MenuItem *item = &OptionCheats_menu.items[j]; - // I guess that makes sense, nobody is changing these but us - what about state restore? - if(!cheat->enabled) - continue; item->value = cheat->enabled; } } diff --git a/workspace/all/minarch/ma_runframe.cpp b/workspace/all/minarch/ma_runframe.cpp index 761b7d2d6..5cac5e3db 100644 --- a/workspace/all/minarch/ma_runframe.cpp +++ b/workspace/all/minarch/ma_runframe.cpp @@ -1,4 +1,5 @@ #include +#include // Project C headers declare C-linkage symbols (core, rewind_st, ff, LOG_*, …) // defined in the still-C translation units. Include them as extern "C" so this @@ -8,7 +9,21 @@ extern "C" { #include "ma_rewind.h" #include "ma_input.h" #include "ma_config.h" +#include "ma_cheats.h" #include "ma_runframe.h" +#include "notification.h" +} + +// Recover after a core throws mid-emulation (see run_frame). The known trigger is +// a cheat the core can't parse (Mednafen/supafaust defers Game-Genie parsing to +// retro_run and throws). Clear the core's cheat state so the next frame is clean, +// clear the frontend's enabled flags so the cheat menu reflects reality, and tell +// the user once. Called only from the catch, so it runs at most once per fault. +static void recoverFromCoreFault(void) { + if (core.cheat_reset) { try { core.cheat_reset(); } catch (...) {} } + for (size_t i = 0; i < cheatcodes.count; i++) cheatcodes.cheats[i].enabled = 0; + cheatcodes.enabled = 0; + Notification_push(NOTIFICATION_SETTING, "Cheat rejected by core - cheats disabled", NULL); } void chooseSyncRef(void) { @@ -52,6 +67,13 @@ static void limitFF(void) { } void run_frame(void) { + // Some cores (Mednafen/supafaust) DEFER cheat parsing to the emulation frame: + // retro_cheat_set only stores the code, and retro_run() parses it and throws a + // C++ exception (Mednafen::MDFN_Error) if it can't (e.g. Game Genie format on a + // core that wants raw addresses). Uncaught, that unwinds out of core.run() into + // the frontend and hits std::terminate -> abort. Guard the whole frame so a + // throwing core is recovered by clearing cheats instead of killing the emulator. + try { // if rewind is toggled, fast-forward toggle must stay off; fast-forward hold pauses rewind int do_rewind = (rewind_st.pressed || rewind_st.toggle) && !(rewind_st.toggle && ff.hold_active); if (do_rewind) { @@ -108,4 +130,11 @@ void run_frame(void) { Rewind_push(0); } limitFF(); + } catch (const std::exception& e) { + LOG_error("run_frame: core threw during emulation: %s — disabling cheats to recover\n", e.what()); + recoverFromCoreFault(); + } catch (...) { + LOG_error("run_frame: core threw an unknown exception during emulation — disabling cheats to recover\n"); + recoverFromCoreFault(); + } } From 0a646888ecf6bc68621d2c713fedf317b80134a2 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Mon, 6 Jul 2026 14:46:37 +0200 Subject: [PATCH 57/77] tg5040: add TrimUI Brick Pro support (Brick screen + Smart Pro sticks) The Brick Pro is a tg5040 hybrid: a Brick chassis and 1024x768 screen with the Smart Pro's dual analog thumbsticks. Detect it via the stock MainUI model string (DEVICE=brickpro) and route it as a Brick-family device for everything screen/LED/brightness/display-cal related, while giving it Smart Pro-style analog-stick handling. - utils.{c,h}: central isBrickModel() (brick + brickpro) replacing the scattered exactMatch("brick", ...) checks in api.c, ledcontrol.c, bootlogo.c, platform.c; msettings.c carries a local mirror (standalone .so). - platform.c: new TG5040_BRICK_PRO descriptor; resolveDeviceModel() selects it. - settings.cpp: new Model::BrickPro (appended); hasAnalogSticks() true for it; Brick display-cal preset (shared screen). - launch.sh / dbg/launch.sh / install/boot.sh: detect the Brick Pro, power the L/R thumbstick GPIOs, and use the Brick LED channels + splash geometry. Existing Brick/Smart Pro behaviour is unchanged (all additions are additive). UNVERIFIED pending real hardware: the exact MainUI model string ("Trimui Brick Pro" assumed) and the joystick button codes/stick enumeration. --- skeleton/SYSTEM/tg5040/dbg/launch.sh | 3 ++ .../SYSTEM/tg5040/paks/MinUI.pak/launch.sh | 22 +++++++++----- workspace/all/bootlogo/bootlogo.c | 3 +- workspace/all/common/api.c | 2 +- workspace/all/common/utils.c | 5 ++++ workspace/all/common/utils.h | 5 ++++ workspace/all/ledcontrol/ledcontrol.c | 4 +-- workspace/all/settings/settings.cpp | 12 ++++++-- workspace/tg5040/install/boot.sh | 6 +++- workspace/tg5040/libmsettings/msettings.c | 8 ++++- workspace/tg5040/platform/platform.c | 29 +++++++++++++++++-- 11 files changed, 80 insertions(+), 19 deletions(-) diff --git a/skeleton/SYSTEM/tg5040/dbg/launch.sh b/skeleton/SYSTEM/tg5040/dbg/launch.sh index 1c9096d49..9c90cd4b4 100755 --- a/skeleton/SYSTEM/tg5040/dbg/launch.sh +++ b/skeleton/SYSTEM/tg5040/dbg/launch.sh @@ -16,6 +16,9 @@ export DATETIME_PATH="$SHARED_USERDATA_PATH/datetime.txt" export TRIMUI_MODEL=`strings /usr/trimui/bin/MainUI | grep ^Trimui` if [ "$TRIMUI_MODEL" = "Trimui Brick" ]; then export DEVICE="brick" +elif [ "$TRIMUI_MODEL" = "Trimui Brick Pro" ]; then + # UNVERIFIED model string; confirm on hardware. + export DEVICE="brickpro" fi export IS_NEXT="yes" diff --git a/skeleton/SYSTEM/tg5040/paks/MinUI.pak/launch.sh b/skeleton/SYSTEM/tg5040/paks/MinUI.pak/launch.sh index 0aad231b8..f229b6302 100755 --- a/skeleton/SYSTEM/tg5040/paks/MinUI.pak/launch.sh +++ b/skeleton/SYSTEM/tg5040/paks/MinUI.pak/launch.sh @@ -49,11 +49,16 @@ mkdir -p "$HOOKS_PATH" mkdir -p "$SHARED_USERDATA_PATH/.minui" export TRIMUI_MODEL=`strings /usr/trimui/bin/MainUI | grep ^Trimui` -if [ "$TRIMUI_MODEL" = "Trimui Brick" ]; then - export DEVICE="brick" -else - export DEVICE="smartpro" -fi +case "$TRIMUI_MODEL" in + "Trimui Brick") + export DEVICE="brick" ;; + "Trimui Brick Pro") + # UNVERIFIED model string -- confirm on real hardware with: + # strings /usr/trimui/bin/MainUI | grep ^Trimui + export DEVICE="brickpro" ;; + *) + export DEVICE="smartpro" ;; +esac export IS_NEXT="yes" @@ -81,7 +86,9 @@ echo 227 > /sys/class/gpio/export echo -n out > /sys/class/gpio/gpio227/direction echo -n 0 > /sys/class/gpio/gpio227/value -if [ "$TRIMUI_MODEL" = "Trimui Smart Pro" ]; then +# Left/Right analog thumbstick power (PD14/PD18). Smart Pro and Brick Pro have +# front thumbsticks; the original Brick does not. +if [ "$DEVICE" = "smartpro" ] || [ "$DEVICE" = "brickpro" ]; then #Left/Right Pad PD14/PD18 echo 110 > /sys/class/gpio/export echo -n out > /sys/class/gpio/gpio110/direction @@ -105,7 +112,8 @@ export PATH=$SYSTEM_PATH/bin:/usr/trimui/bin:$PATH # leds_off echo 0 > /sys/class/led_anim/max_scale -if [ "$TRIMUI_MODEL" = "Trimui Brick" ]; then +# Brick family (Brick + Brick Pro) has the extra LR / F1F2 LED channels. +if [ "$DEVICE" = "brick" ] || [ "$DEVICE" = "brickpro" ]; then echo 0 > /sys/class/led_anim/max_scale_lr echo 0 > /sys/class/led_anim/max_scale_f1f2 fi diff --git a/workspace/all/bootlogo/bootlogo.c b/workspace/all/bootlogo/bootlogo.c index d1201dc50..744e70295 100644 --- a/workspace/all/bootlogo/bootlogo.c +++ b/workspace/all/bootlogo/bootlogo.c @@ -38,7 +38,8 @@ int loadImages() // This needs to get a bit more flexible down the line, but for now we either expect the files // in the pak root directory or in the "brick" subfolder. char basepath[MAX_PATH]; - if(exactMatch("brick", device)) { + if(isBrickModel(device)) { + // Brick and Brick Pro share the 1024x768 screen, so the same bootlogos. snprintf(basepath, sizeof(basepath), "%s/Bootlogo.pak/brick/", TOOLS_PATH); } else { diff --git a/workspace/all/common/api.c b/workspace/all/common/api.c index 2be33d630..ba1aed796 100644 --- a/workspace/all/common/api.c +++ b/workspace/all/common/api.c @@ -4364,7 +4364,7 @@ void LEDS_updateLeds(bool indicator_only) int lightsize = 3; char *device = getenv("DEVICE"); - int is_brick = exactMatch("brick", device); + int is_brick = isBrickModel(device); if (is_brick) lightsize = 4; if(!lights) diff --git a/workspace/all/common/utils.c b/workspace/all/common/utils.c index 4db67860d..bd58fbadd 100644 --- a/workspace/all/common/utils.c +++ b/workspace/all/common/utils.c @@ -30,6 +30,11 @@ int exactMatch(const char* str1, const char* str2) { if (len1!=strlen(str2)) return 0; return (strncmp(str1,str2,len1)==0); } +int isBrickModel(const char* device) { + // Brick and Brick Pro share the Brick chassis/screen/LED layout; both take + // the is_brick code paths. Smart Pro (and S) are a different family. + return exactMatch("brick", device) || exactMatch("brickpro", device); +} int containsString(char* haystack, char* needle) { return strcasestr(haystack, needle) != NULL; } diff --git a/workspace/all/common/utils.h b/workspace/all/common/utils.h index f61fc9caf..4934a6c75 100644 --- a/workspace/all/common/utils.h +++ b/workspace/all/common/utils.h @@ -8,6 +8,11 @@ int prefixMatch(char* pre, const char* str); int suffixMatch(char* suf,const char* str); int exactMatch(const char* str1, const char* str2); +// True for every device in the "Brick" family (original Brick + Brick Pro). +// They share the 1024x768 screen, brightness handling, 4-light LED layout and +// display-cal preset, so all the code that used to test exactMatch("brick",...) +// must treat both the same. Add future Brick variants here in one place. +int isBrickModel(const char* device); int containsString(char* haystack, char* needle); int hide(char* file_name); diff --git a/workspace/all/ledcontrol/ledcontrol.c b/workspace/all/ledcontrol/ledcontrol.c index 241b0f1a3..84d347046 100644 --- a/workspace/all/ledcontrol/ledcontrol.c +++ b/workspace/all/ledcontrol/ledcontrol.c @@ -33,7 +33,7 @@ void save_settings() { LOG_debug("saving settings plat\n"); char diskfilename[256]; char* device = getenv("DEVICE"); - int is_brick = exactMatch("brick", device); + int is_brick = isBrickModel(device); int maxlights = 4; // TODO: this shouldnt be in shared userdata if(is_brick) { @@ -214,7 +214,7 @@ void handle_light_input(LightSettings *light, SDL_Event *event, int selected_set int main(int argc, char *argv[]) { char* device = getenv("DEVICE"); - int is_brick = exactMatch("brick", device); + int is_brick = isBrickModel(device); InitSettings(); PWR_setCPUSpeed(CPU_SPEED_AUTO); diff --git a/workspace/all/settings/settings.cpp b/workspace/all/settings/settings.cpp index a60983a24..8885a2933 100644 --- a/workspace/all/settings/settings.cpp +++ b/workspace/all/settings/settings.cpp @@ -245,7 +245,8 @@ namespace { Brick, SmartPro, SmartProS, - Flip + Flip, + BrickPro // Brick screen + Smart Pro analog sticks; appended to keep values stable }; enum Platform { @@ -262,6 +263,10 @@ namespace { m_vendor = Trimui; m_model = Brick; m_platform = tg5040; + } else if(exactMatch("brickpro", device)) { + m_vendor = Trimui; + m_model = BrickPro; + m_platform = tg5040; } else if(exactMatch("smartpro", device)) { m_vendor = Trimui; m_model = SmartPro; @@ -307,7 +312,8 @@ namespace { } bool hasAnalogSticks() const { - return m_model == SmartPro || m_model == SmartProS; + // Brick Pro adds Smart Pro-style front thumbsticks to the Brick. + return m_model == SmartPro || m_model == SmartProS || m_model == BrickPro; } bool hasWifi() const { @@ -521,7 +527,7 @@ int main(int argc, char *argv[]) if(deviceInfo.hasDisplayCal()) { const DisplayCalDefaults defaultDisplayCal = DisplayCal_getDefaultSettings( - deviceInfo.getModel() == DeviceInfo::Brick ? DISPLAYCAL_PRESET_BRICK : + (deviceInfo.getModel() == DeviceInfo::Brick || deviceInfo.getModel() == DeviceInfo::BrickPro) ? DISPLAYCAL_PRESET_BRICK : deviceInfo.getModel() == DeviceInfo::SmartPro ? DISPLAYCAL_PRESET_SMARTPRO : DISPLAYCAL_PRESET_DEFAULT); displayItems.push_back( new MenuItem{ListItemType::Generic, "White point correction", "Corrects the display white point to better match the \nsRGB standard, at the expense of some peak brightness.", {false, true}, on_off, []() -> std::any diff --git a/workspace/tg5040/install/boot.sh b/workspace/tg5040/install/boot.sh index a4d22d5e9..f8b4cc3bf 100755 --- a/workspace/tg5040/install/boot.sh +++ b/workspace/tg5040/install/boot.sh @@ -13,6 +13,9 @@ export PATH=/usr/trimui/bin:$PATH TRIMUI_MODEL=`strings /usr/trimui/bin/MainUI | grep ^Trimui` if [ "$TRIMUI_MODEL" = "Trimui Brick" ]; then DEVICE="brick" +elif [ "$TRIMUI_MODEL" = "Trimui Brick Pro" ]; then + # UNVERIFIED model string; confirm on hardware. + DEVICE="brickpro" fi # only show splash if either UPDATE_PATH or pakz files exist @@ -35,7 +38,8 @@ fi if [ "$SHOW_SPLASH" = "yes" ] ; then cd $(dirname "$0")/$PLATFORM - if [ "$DEVICE" = "brick" ]; then + # Brick family (Brick + Brick Pro) shares the 1024x768 screen -> taller logo. + if [ "$DEVICE" = "brick" ] || [ "$DEVICE" = "brickpro" ]; then ./show2.elf --mode=daemon --image="$LOGO_PATH" --text="Installing..." --logoheight=144 --fontsize=32 --progress=-1 & else ./show2.elf --mode=daemon --image="$LOGO_PATH" --text="Installing..." --logoheight=128 --progress=-1 & diff --git a/workspace/tg5040/libmsettings/msettings.c b/workspace/tg5040/libmsettings/msettings.c index 6ec93eefd..83a4e229c 100644 --- a/workspace/tg5040/libmsettings/msettings.c +++ b/workspace/tg5040/libmsettings/msettings.c @@ -303,6 +303,12 @@ int exactMatch(char* str1, char* str2) { if (len1!=strlen(str2)) return 0; return (strncmp(str1,str2,len1)==0); } +// Brick family = original Brick + Brick Pro; they share this .so's brick display +// preset and brick audio quirks. libmsettings is a standalone .so with its own +// exactMatch, so it carries its own copy (mirrors utils.c:isBrickModel). +static int isBrickModel(char* device) { + return exactMatch("brick", device) || exactMatch("brickpro", device); +} int peekVersion(const char *filename) { int version = 0; @@ -330,7 +336,7 @@ static void applyDisplayCalDefaultsForDevice(Settings *target) { void InitSettings(void) { char* device = getenv("DEVICE"); - is_brick = exactMatch("brick", device); + is_brick = isBrickModel(device); is_smartpro = exactMatch("smartpro", device); sprintf(SettingsPath, "%s/msettings.bin", getenv("USERDATA_PATH")); diff --git a/workspace/tg5040/platform/platform.c b/workspace/tg5040/platform/platform.c index c05827e00..26eb633c3 100644 --- a/workspace/tg5040/platform/platform.c +++ b/workspace/tg5040/platform/platform.c @@ -57,15 +57,38 @@ static const DeviceDescriptor TG5040_SMART_PRO = { .gpu_usage_path = NULL, .rumble_gpio_path = TG5040_RUMBLE_GPIO, }; +// TrimUI Brick Pro: physically a Brick (same 1024x768 screen, LED layout and +// button map) with the Smart Pro's dual analog thumbsticks added at the front. +// The sticks are powered in launch.sh (the Left/Right pad GPIOs) and surface +// through SDL as generic joystick axes, so no field here differs from the Brick +// yet -- this named descriptor is the seam for any Brick-Pro-only tuning that a +// real unit turns out to need. UNVERIFIED: geometry and joystick codes are +// inherited from the Brick on the assumption the shared chassis matches; confirm +// against actual hardware. +static const DeviceDescriptor TG5040_BRICK_PRO = { + .scale = 3, .width = 1024, .height = 768, + .main_row_count = 7, .quick_switcher_count = 3, .padding = 5, + .joy_l3 = 9, .joy_r3 = 10, .joy_plus = 14, .joy_minus = 13, + .cpu_speed_path = TG5040_CPU_SPEED_PATH, + .gpu_temp_path = TG5040_GPU_TEMP_PATH, + .gpu_speed_fixed = 660, + .gpu_freq_path = NULL, + .gpu_usage_path = NULL, + .rumble_gpio_path = TG5040_RUMBLE_GPIO, +}; // Default to Smart Pro so the geometry/button macros are valid even before // init runs; resolveDeviceModel() refines it once DEVICE is known. const DeviceDescriptor* deviceModel = &TG5040_SMART_PRO; // Single source of truth for which model we're on. Sets both is_brick (kept for -// the handful of code paths that still branch on it) and the active descriptor. +// the handful of code paths that still branch on it -- Brick Pro is in the Brick +// family, see isBrickModel) and the active descriptor. static void resolveDeviceModel(void) { - is_brick = exactMatch("brick", getenv("DEVICE")); - deviceModel = is_brick ? &TG5040_BRICK : &TG5040_SMART_PRO; + const char* device = getenv("DEVICE"); + is_brick = isBrickModel(device); + if (exactMatch("brickpro", device)) deviceModel = &TG5040_BRICK_PRO; + else if (exactMatch("brick", device)) deviceModel = &TG5040_BRICK; + else deviceModel = &TG5040_SMART_PRO; } void PLAT_initPlatform(void) { From f46b514bbad85b3b2a673b69133a6bb90ac8e630 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sat, 11 Jul 2026 13:56:45 +0200 Subject: [PATCH 58/77] minarch: fix goto crossing state_file init in ma_saves (desktop build) State_read/State_write in the non-HAS_SRM (#else) path declared `FILE *state_file = fopen(...)` after the early `goto error;` sites, so the error: label sat in scope of an initialization the goto jumped over -- ill-formed in C++. The HAS_SRM path was already hoisted (state_rzfile = NULL); the #else path was missed. The toolchain g++ 8.3 accepted it, so device builds passed, but the host g++ used for PLATFORM=desktop rejected it, breaking the desktop build at minarch. Hoist state_file to NULL before the first goto (as already done for state_rzfile) and assign the fopen() result later. Builds clean on tg5040 and desktop. --- workspace/all/minarch/ma_saves.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/workspace/all/minarch/ma_saves.cpp b/workspace/all/minarch/ma_saves.cpp index b8e6fc54d..6ed4ff560 100644 --- a/workspace/all/minarch/ma_saves.cpp +++ b/workspace/all/minarch/ma_saves.cpp @@ -221,10 +221,12 @@ int State_read(void) { // from picoarch // Hoisted above the first `goto error` below: C++ forbids a goto that jumps // over a variable's initialization into its scope, and the error: label is // in scope for these. state_rzfile in particular MUST be NULL before any - // goto reaches error: (which reads it). filename/state need no hoist. + // goto reaches error: (which reads them). filename/state need no hoist. uint8_t rastate_header[RASTATE_HEADER_SIZE] = {0}; #ifdef HAS_SRM rzipstream_t *state_rzfile = NULL; +#else + FILE *state_file = NULL; #endif void *state = calloc(1, state_size); @@ -273,7 +275,7 @@ int State_read(void) { // from picoarch if (state) free(state); if (state_rzfile) rzipstream_close(state_rzfile); #else - FILE *state_file = fopen(filename, "r"); + state_file = fopen(filename, "r"); if (!state_file) { if (state_slot!=8) { // st8 is a default state in MiniUI and may not exist, that's okay LOG_error("Error opening state file: %s (%s)\n", filename, strerror(errno)); @@ -327,6 +329,12 @@ int State_write(void) { // from picoarch int was_ff = ff.active; ff.active = 0; + // Hoisted above the first `goto error` below (see State_read): the error: + // label reads state_file, and C++ forbids a goto crossing its initialization. +#ifndef HAS_SRM + FILE *state_file = NULL; +#endif + void *state = calloc(1, state_size); if (!state) { LOG_error("Couldn't allocate memory for state\n"); @@ -359,7 +367,7 @@ int State_write(void) { // from picoarch error: if (state) free(state); #else - FILE *state_file = fopen(filename, "w"); + state_file = fopen(filename, "w"); if (!state_file) { LOG_error("Error opening state file: %s (%s)\n", filename, strerror(errno)); goto error; From 8f873ec8d1c105d43eef38c3dc7999a9c79586e6 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sat, 18 Jul 2026 03:01:51 +0200 Subject: [PATCH 59/77] fix: tg5050 SUPA crash on game launch + load exception guard Two related fixes: 1. skeleton/EXTRAS/Emus/tg5050/SUPA.pak/default.cfg: change supafaust_thread_affinity_ppu from 0xc (CPUs 2+3, offline on tg5050) to 0x10 (CPU 4, online). Mirrors the upstream fix in PR #784. 2. workspace/all/minarch/ma_core.cpp: wrap retro_load_game in try/catch in Core_load(). A core that throws during load now logs the exception and exits cleanly instead of hitting std::terminate with no context. (C++ only; upstream's ma_core.c has no equivalent guard available.) --- skeleton/EXTRAS/Emus/tg5050/SUPA.pak/default.cfg | 2 +- workspace/all/minarch/ma_core.cpp | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/skeleton/EXTRAS/Emus/tg5050/SUPA.pak/default.cfg b/skeleton/EXTRAS/Emus/tg5050/SUPA.pak/default.cfg index 4a77a7b31..a60c7e36d 100755 --- a/skeleton/EXTRAS/Emus/tg5050/SUPA.pak/default.cfg +++ b/skeleton/EXTRAS/Emus/tg5050/SUPA.pak/default.cfg @@ -1,6 +1,6 @@ -supafaust_pixel_format = rgb565 -supafaust_thread_affinity_emu = 0x3 --supafaust_thread_affinity_ppu = 0xc +-supafaust_thread_affinity_ppu = 0x10 bind Up = UP bind Down = DOWN diff --git a/workspace/all/minarch/ma_core.cpp b/workspace/all/minarch/ma_core.cpp index 9f36bfb95..4fab04ed2 100644 --- a/workspace/all/minarch/ma_core.cpp +++ b/workspace/all/minarch/ma_core.cpp @@ -172,7 +172,15 @@ void Core_load(void) { game_info.data = game.data; game_info.size = game.size; LOG_info("game path: %s (%i)\n", game_info.path, game.size); - core.load_game(&game_info); + try { + core.load_game(&game_info); + } catch (const std::exception& e) { + LOG_error("Core_load: retro_load_game threw: %s\n", e.what()); + exit(1); + } catch (...) { + LOG_error("Core_load: retro_load_game threw an unknown exception\n"); + exit(1); + } if (Cheats_load()) Core_applyCheats(&cheatcodes); From 0bd45d9e872d78cd92b15c0f052f686b7f319c79 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Mon, 20 Jul 2026 09:42:21 +0200 Subject: [PATCH 60/77] fix: post-merge C++20 corrections after upstream sync - nextui.cpp: restore if(lastScreen==SCREEN_GAME) branch eaten by conflict resolution and update runFnAction() to use C++20 vector accessor (entries.size() / entries[i]) - api.c/h: restore ALT_BUTTON_TEXT_COLOR as public (non-static) with extern declaration so minput.c can reference it after upstream introduced its use there - platform.c: restore MAX_STRENGTH and MIN_VOLTAGE defines lost during conflict resolution --- workspace/all/common/api.c | 2 +- workspace/all/common/api.h | 1 + workspace/all/nextui/nextui.cpp | 5 +++-- workspace/tg5040/platform/platform.c | 2 ++ 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/workspace/all/common/api.c b/workspace/all/common/api.c index 47ad30183..64477d600 100644 --- a/workspace/all/common/api.c +++ b/workspace/all/common/api.c @@ -106,7 +106,7 @@ uint32_t THEME_COLOR4; uint32_t THEME_COLOR5; uint32_t THEME_COLOR6; uint32_t THEME_COLOR7; -static SDL_Color ALT_BUTTON_TEXT_COLOR; +SDL_Color ALT_BUTTON_TEXT_COLOR; // move to utils? diff --git a/workspace/all/common/api.h b/workspace/all/common/api.h index d16a69b26..1cadc5533 100644 --- a/workspace/all/common/api.h +++ b/workspace/all/common/api.h @@ -75,6 +75,7 @@ extern uint32_t THEME_COLOR4; extern uint32_t THEME_COLOR5; extern uint32_t THEME_COLOR6; extern uint32_t THEME_COLOR7; +extern SDL_Color ALT_BUTTON_TEXT_COLOR; typedef struct { float ratio; diff --git a/workspace/all/nextui/nextui.cpp b/workspace/all/nextui/nextui.cpp index 87d359b7a..a1759f3bc 100644 --- a/workspace/all/nextui/nextui.cpp +++ b/workspace/all/nextui/nextui.cpp @@ -1156,8 +1156,8 @@ static int runFnAction(int index) { // unlike openPak() we save where the user *is*, not the pak itself, so exiting // the pak comes back to the same spot in the list - if (top && top->entries->count>0) { - Entry* entry = top->entries->items[top->selected]; + if (top && (int)top->entries.size()>0) { + Entry* entry = top->entries[top->selected]; saveLast(entry->path); } @@ -2571,6 +2571,7 @@ int main (int argc, char *argv[]) { SDL_Rect preview_rect = {ox,oy,screen->w,screen->h}; core::SurfacePtr tmpsur{SDL_CreateRGBSurfaceWithFormat(0,screen->w,screen->h,screen->format->BitsPerPixel,screen->format->format)}; SDL_FillRect(tmpsur.get(), &preview_rect, THEME_COLOR7); + if(lastScreen == SCREEN_GAME) { GFX_animateSurfaceOpacity(tmpsur.get(),0,0,screen->w,screen->h,255,0,CFG_getMenuTransitions() ? 150:20,LAYER_BACKGROUND); } else if(lastScreen == SCREEN_GAMELIST) { GFX_animateSurface(tmpsur.get(),0,0-screen->h,0,0,screen->w,screen->h,CFG_getMenuTransitions() ? 100:20,255,255,LAYER_ALL); diff --git a/workspace/tg5040/platform/platform.c b/workspace/tg5040/platform/platform.c index 64f4fa97c..261c8a5ab 100644 --- a/workspace/tg5040/platform/platform.c +++ b/workspace/tg5040/platform/platform.c @@ -214,6 +214,8 @@ static pthread_mutex_t currentcpuinfo; +#define MAX_STRENGTH 0xFFFF +#define MIN_VOLTAGE 500000 // Brick Pro has a 3.3V motor driver, but its getting very annoying on higher rumble strengths, so we limit it to 2.5V for now. #define MAX_VOLTAGE (is_brickpro ? 2500000 : 3300000) #define RUMBLE_VOLTAGE_PATH "/sys/class/motor/voltage" From b96a58c8a4f49eba6b461629d6c3f5f7ccdd53b4 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Mon, 20 Jul 2026 09:53:19 +0200 Subject: [PATCH 61/77] refactor: convert palette.c to C++20 palette.c is only consumed by the settings component (C++); no C-only tool includes it, so there is no reason to keep it as a C translation unit. - palette.h: #pragma once, , drop (native bool in C++), struct tag instead of typedef struct - palette.cpp: / instead of C headers; extern "C" wrapper around config.h (which has no __cplusplus guard) to preserve C linkage for CFG_* calls - settings/makefile: move from gcc SOURCE to g++ CXXSOURCE; drop palette.o from the intermediate-object mv and link list - palettemenu.cpp: move palette.h include out of the extern "C" block --- .../all/common/{palette.c => palette.cpp} | 14 +++------- workspace/all/common/palette.h | 28 +++---------------- workspace/all/settings/makefile | 8 +++--- workspace/all/settings/palettemenu.cpp | 2 +- 4 files changed, 13 insertions(+), 39 deletions(-) rename workspace/all/common/{palette.c => palette.cpp} (86%) diff --git a/workspace/all/common/palette.c b/workspace/all/common/palette.cpp similarity index 86% rename from workspace/all/common/palette.c rename to workspace/all/common/palette.cpp index 4a3c17f15..00b351e57 100644 --- a/workspace/all/common/palette.c +++ b/workspace/all/common/palette.cpp @@ -1,13 +1,14 @@ #include "palette.h" -#include -#include -#include +#include +#include #include #include #include "defines.h" +extern "C" { #include "config.h" +} static const uint32_t palette_default_colors[PALETTE_COLOR_COUNT] = { CFG_DEFAULT_COLOR1, CFG_DEFAULT_COLOR2, CFG_DEFAULT_COLOR3, @@ -15,7 +16,6 @@ static const uint32_t palette_default_colors[PALETTE_COLOR_COUNT] = { CFG_DEFAULT_COLOR7, }; -// Derive a display name from a filename: strip .txt, replace underscores with spaces. static void palette_nameFromFilename(const char *filename, char *out, size_t out_size) { size_t len = strlen(filename); @@ -28,7 +28,6 @@ static void palette_nameFromFilename(const char *filename, char *out, size_t out out[len] = '\0'; } -// Parse a single palette file. Returns true on success and a supported version. static bool palette_loadFile(const char *path, const char *filename, bool builtin, ColorPalette *out) { FILE *file = fopen(path, "r"); @@ -76,7 +75,6 @@ static bool palette_loadFile(const char *path, const char *filename, bool builti } fclose(file); - // Skip palettes authored for a newer format than we understand. if (out->version > PALETTE_VERSION_MAX) return false; @@ -116,7 +114,6 @@ int PALETTE_enumerate(ColorPalette *out, int max) return 0; int count = 0; - // Built-ins first (read-only), then user/community drop-ins. count = palette_scanDir(RES_PATH "/palettes", true, out, max, count); count = palette_scanDir(SDCARD_PATH "/Palettes", false, out, max, count); return count; @@ -126,8 +123,5 @@ void PALETTE_apply(const ColorPalette *palette) { if (!palette) return; - // CFG_applyPalette sets the 7 colors and the palette name as one atomic step, - // so the persisted "current palette" can never point at a color set that - // doesn't match it. CFG_applyPalette(palette->name, palette->colors); } diff --git a/workspace/all/common/palette.h b/workspace/all/common/palette.h index bb704dd46..88f71e6b8 100644 --- a/workspace/all/common/palette.h +++ b/workspace/all/common/palette.h @@ -1,40 +1,20 @@ -#ifndef __PALETTE_H__ -#define __PALETTE_H__ +#pragma once -#include -#include +#include -// Predefined color palettes: file-based color presets users can pick from in -// Settings, in addition to the fully custom color1-7 controls. "Palette" is -// deliberately scoped to colors only - a future "Theme" feature may bundle -// palettes with other assets (fonts, backgrounds, etc.). See config.h for the -// persisted "currently selected palette" state (CFG_getPaletteName/ -// CFG_applyPalette/CFG_clearPalette). - -// Highest palette-file format version this build understands. Palette files -// with a higher version= are skipped during enumeration. #define PALETTE_VERSION_MAX 1 #define PALETTE_NAME_MAX 64 // keep in sync with NextUISettings.paletteName in config.h #define PALETTE_PATH_MAX 512 #define PALETTE_COLOR_COUNT 7 -typedef struct +struct ColorPalette { int version; // palette-file format version char name[PALETTE_NAME_MAX]; // display label char path[PALETTE_PATH_MAX]; // absolute path to the palette file bool builtin; // true if shipped in RES_PATH/palettes (read-only) uint32_t colors[PALETTE_COLOR_COUNT]; // packed RGBA, index 0 == color1 -} ColorPalette; +}; -// Enumerate predefined color palettes found on disk. -// Scans RES_PATH/palettes (built-ins, listed first) and SDCARD_PATH/Palettes (user). -// Files whose version= exceeds PALETTE_VERSION_MAX are skipped. Missing colors fall -// back to the CFG defaults. Writes up to max entries into out; returns the count. int PALETTE_enumerate(ColorPalette *out, int max); - -// Apply a palette's colors to the current settings and record it as the selected -// palette. Fires the color-set callback per color; does not modify the palette file. void PALETTE_apply(const ColorPalette *palette); - -#endif diff --git a/workspace/all/settings/makefile b/workspace/all/settings/makefile index 4c7ec860e..c17861c0e 100644 --- a/workspace/all/settings/makefile +++ b/workspace/all/settings/makefile @@ -21,9 +21,9 @@ SDL?=SDL TARGET = settings INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ -SOURCE = -c ../common/utils.c ../common/api.c ../common/config.c ../common/palette.c ../common/scaler.c ../common/http.c ../common/ra_auth.c ../common/ra_offline.c ../common/ra_sync.c ../common/ra_event_queue.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = $(TARGET).cpp menu.cpp colorpickermenu.cpp palettemenu.cpp fnbuttonmenu.cpp wifimenu.cpp btmenu.cpp keyboardprompt.cpp -CXXSOURCE += build/$(PLATFORM)/utils.o build/$(PLATFORM)/api.o build/$(PLATFORM)/config.o build/$(PLATFORM)/palette.o build/$(PLATFORM)/scaler.o build/$(PLATFORM)/http.o build/$(PLATFORM)/ra_auth.o build/$(PLATFORM)/ra_offline.o build/$(PLATFORM)/ra_sync.o build/$(PLATFORM)/ra_event_queue.o build/$(PLATFORM)/platform.o +SOURCE = -c ../common/utils.c ../common/api.c ../common/config.c ../common/scaler.c ../common/http.c ../common/ra_auth.c ../common/ra_offline.c ../common/ra_sync.c ../common/ra_event_queue.c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = ../common/palette.cpp $(TARGET).cpp menu.cpp colorpickermenu.cpp palettemenu.cpp fnbuttonmenu.cpp wifimenu.cpp btmenu.cpp keyboardprompt.cpp +CXXSOURCE += build/$(PLATFORM)/utils.o build/$(PLATFORM)/api.o build/$(PLATFORM)/config.o build/$(PLATFORM)/scaler.o build/$(PLATFORM)/http.o build/$(PLATFORM)/ra_auth.o build/$(PLATFORM)/ra_offline.o build/$(PLATFORM)/ra_sync.o build/$(PLATFORM)/ra_event_queue.o build/$(PLATFORM)/platform.o CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ @@ -53,7 +53,7 @@ PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/msettings.h mkdir -p build/$(PLATFORM) $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) - mv utils.o api.o config.o palette.o scaler.o http.o ra_auth.o ra_offline.o ra_sync.o ra_event_queue.o platform.o build/$(PLATFORM) + mv utils.o api.o config.o scaler.o http.o ra_auth.o ra_offline.o ra_sync.o ra_event_queue.o platform.o build/$(PLATFORM) $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) diff --git a/workspace/all/settings/palettemenu.cpp b/workspace/all/settings/palettemenu.cpp index a40296782..3d59c1269 100644 --- a/workspace/all/settings/palettemenu.cpp +++ b/workspace/all/settings/palettemenu.cpp @@ -2,8 +2,8 @@ extern "C" { #include "config.h" -#include "palette.h" } +#include "palette.h" namespace { From bf712dd8e8950fbce866a664fdd981824e9a3225 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sun, 26 Jul 2026 09:57:23 +0200 Subject: [PATCH 62/77] refactor: convert minarch chd_reader + ra_integration to C++20 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Finishes minarch at 100% first-party C++: the two remaining C units move from CSOURCE to CXXSOURCE in the makefile (the RA-conditional block). Both sit on the rcheevos C hashing/callback boundary, so the conversion stays conservative — allocation remains malloc/free (non-throwing) and no STL containers are introduced on the callback path. - Add extern "C" guards to chd_reader.h and ra_integration.h so their symbols keep C linkage for the 5 already-C++ consumers. - Wrap the still-C project headers (config/http/api/notification/RA helpers) in extern "C" in each .cpp, matching the ma_environment.cpp pattern; keep system/SDL/rcheevos headers outside. - chd_reader: C++ headers, libchdr includes wrapped extern "C" defensively (cdrom.h is unguarded but only supplies macros/enums). - ra_integration: drop the redundant `volatile` on ra_response_queue_count (every access is under ra_queue_mutex, so the lock provides ordering; this also clears C++20's -Wvolatile deprecation on ++/--). Builds clean on tg5040 (g++ 8.3, gnu++2a) and desktop (host g++, gnu++20). --- .../minarch/{chd_reader.c => chd_reader.cpp} | 18 ++++++++++++------ workspace/all/minarch/chd_reader.h | 8 ++++++++ workspace/all/minarch/makefile | 7 +++++-- .../{ra_integration.c => ra_integration.cpp} | 16 ++++++++++++---- workspace/all/minarch/ra_integration.h | 8 ++++++++ 5 files changed, 45 insertions(+), 12 deletions(-) rename workspace/all/minarch/{chd_reader.c => chd_reader.cpp} (97%) rename workspace/all/minarch/{ra_integration.c => ra_integration.cpp} (99%) diff --git a/workspace/all/minarch/chd_reader.c b/workspace/all/minarch/chd_reader.cpp similarity index 97% rename from workspace/all/minarch/chd_reader.c rename to workspace/all/minarch/chd_reader.cpp index 0c48f723f..2f67b41ce 100644 --- a/workspace/all/minarch/chd_reader.c +++ b/workspace/all/minarch/chd_reader.cpp @@ -1,17 +1,23 @@ /** - * chd_reader.c - CHD file reader for rcheevos hashing - * + * chd_reader.cpp - CHD file reader for rcheevos hashing + * * Provides CD reader callbacks for rcheevos to hash CHD disc images. */ #include "chd_reader.h" -#include -#include -#include -#include +#include +#include +#include +#include +// libchdr is a C library. chd.h carries its own extern "C" guard; cdrom.h does +// not, so wrap both to keep any function declarations at C linkage. Allocation +// on this path stays malloc/free (non-throwing): these readers run inside the +// rcheevos C hashing callbacks, where a C++ exception would be undefined. +extern "C" { #include #include +} /***************************************************************************** * Track info structure diff --git a/workspace/all/minarch/chd_reader.h b/workspace/all/minarch/chd_reader.h index 1aca00d63..400504741 100644 --- a/workspace/all/minarch/chd_reader.h +++ b/workspace/all/minarch/chd_reader.h @@ -12,6 +12,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /** * Open a track from a CHD file. * @@ -65,4 +69,8 @@ uint32_t chd_first_track_sector(void* track_handle); */ int chd_reader_is_chd(const char* path); +#ifdef __cplusplus +} +#endif + #endif /* CHD_READER_H */ diff --git a/workspace/all/minarch/makefile b/workspace/all/minarch/makefile index 57acb4b9c..230d32070 100644 --- a/workspace/all/minarch/makefile +++ b/workspace/all/minarch/makefile @@ -35,8 +35,11 @@ CXXSOURCE = $(TARGET).cpp \ # RA support ifneq (,$(filter $(PLATFORM),tg5040 tg5050 my355 desktop)) -# RA source files -CSOURCE += ../common/http.c ../common/ra_badges.c ../common/ra_offline.c ../common/ra_sync.c ../common/ra_event_queue.c ra_integration.c chd_reader.c +# RA source files (shared common/ helpers stay C; the two minarch-local RA units +# are C++). ra_integration sits on the rcheevos C callback boundary — kept +# mechanical, no throwing constructs on that path. +CSOURCE += ../common/http.c ../common/ra_badges.c ../common/ra_offline.c ../common/ra_sync.c ../common/ra_event_queue.c +CXXSOURCE += ra_integration.cpp chd_reader.cpp endif CC = $(CROSS_COMPILE)gcc diff --git a/workspace/all/minarch/ra_integration.c b/workspace/all/minarch/ra_integration.cpp similarity index 99% rename from workspace/all/minarch/ra_integration.c rename to workspace/all/minarch/ra_integration.cpp index f898ebc51..8ea6ee869 100644 --- a/workspace/all/minarch/ra_integration.c +++ b/workspace/all/minarch/ra_integration.cpp @@ -1,6 +1,12 @@ #define RA_LOG_PREFIX "RA" -#include "ra_log.h" +// Project C headers declare C-linkage symbols (config, http, api, notification, +// the RA helpers, …) defined in the still-C common translation units. Include +// them as extern "C" so this C++ unit links against the unmangled names. +// (Same pattern as ma_environment.cpp / ma_saves.cpp.) +#define RA_UTIL_NEED_SDL +extern "C" { +#include "ra_log.h" #include "ra_integration.h" #include "ra_consoles.h" #include "chd_reader.h" @@ -12,10 +18,9 @@ #include "ra_sync.h" #include "defines.h" #include "api.h" - -#define RA_UTIL_NEED_SDL #include "ra_util.h" #include "ra_event_queue.h" +} #include #include @@ -210,7 +215,10 @@ typedef struct { #define RA_RESPONSE_QUEUE_SIZE 16 static RA_QueuedResponse ra_response_queue[RA_RESPONSE_QUEUE_SIZE]; -static volatile int ra_response_queue_count = 0; +// Always accessed under ra_queue_mutex (except the pre-thread init), so the +// lock — not a volatile qualifier — provides visibility/ordering. Plain int +// also avoids C++20's deprecation of ++/-- on volatile-qualified types. +static int ra_response_queue_count = 0; static int ra_response_queue_head = 0; /* next slot to read (main thread) */ static int ra_response_queue_tail = 0; /* next slot to write (worker threads) */ static SDL_mutex* ra_queue_mutex = NULL; diff --git a/workspace/all/minarch/ra_integration.h b/workspace/all/minarch/ra_integration.h index 45f5bc2ce..aadc1a0e3 100644 --- a/workspace/all/minarch/ra_integration.h +++ b/workspace/all/minarch/ra_integration.h @@ -5,6 +5,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + // See: https://github.com/RetroAchievements/rcheevos/wiki/rc_client-integration /** @@ -171,4 +175,8 @@ void RA_setMemoryMap(const void* mmap); */ void RA_initMemoryRegions(uint32_t console_id); +#ifdef __cplusplus +} +#endif + #endif // __RA_INTEGRATION_H__ From efd362f0a3ac6578ba70d483077fbe0283f4e90c Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sun, 26 Jul 2026 10:15:11 +0200 Subject: [PATCH 63/77] refactor: convert batmon, gametimectl, nextval, syncsettings to C++20 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 2 (leaf tools), clean group — no SDL/compound-literals/nested functions, so these are near-mechanical. Each makefile moves from a single gcc compile+link to the settings.cpp-style mixed build: shared common/ + platform stay C (compiled to objects with gcc), the tool's .cpp is C++20, everything links through g++ -lstdc++. Still-C project headers (defines/api/utils/config, batmondb/gametimedb, msettings) are wrapped extern "C" in each .cpp. Also modernized: C++ headers, NULL -> nullptr. Dropped the C-only -std=gnu99 from the shared CFLAGS (it lazily leaked into the g++ command line via CXXFLAGS += $(CFLAGS)); common C now compiles at the default std, matching settings/makefile. Verified: tg5040 build clean (0 errors/warnings); nextval also builds desktop. On-device (tg5040): nextval --help, gametimectl usage, and syncsettings all run and exit 0 with correct output. batmon is a daemon — build-verified, logic unchanged. --- workspace/all/batmon/{batmon.c => batmon.cpp} | 18 +++++++++++------- workspace/all/batmon/makefile | 17 ++++++++++++++--- .../{gametimectl.c => gametimectl.cpp} | 11 ++++++++--- workspace/all/gametimectl/makefile | 17 ++++++++++++++--- workspace/all/nextval/makefile | 19 +++++++++++++++---- .../all/nextval/{nextval.c => nextval.cpp} | 9 +++++++-- workspace/all/syncsettings/makefile | 11 ++++++++--- .../{syncsettings.c => syncsettings.cpp} | 6 +++++- 8 files changed, 82 insertions(+), 26 deletions(-) rename workspace/all/batmon/{batmon.c => batmon.cpp} (97%) rename workspace/all/gametimectl/{gametimectl.c => gametimectl.cpp} (91%) rename workspace/all/nextval/{nextval.c => nextval.cpp} (81%) rename workspace/all/syncsettings/{syncsettings.c => syncsettings.cpp} (60%) diff --git a/workspace/all/batmon/batmon.c b/workspace/all/batmon/batmon.cpp similarity index 97% rename from workspace/all/batmon/batmon.c rename to workspace/all/batmon/batmon.cpp index 25761af08..629efac48 100644 --- a/workspace/all/batmon/batmon.c +++ b/workspace/all/batmon/batmon.cpp @@ -1,17 +1,21 @@ // heavily modified from the Onion original: https://github.com/OnionUI/Onion/tree/main/src/batmon -#include -#include -#include -#include +#include +#include +#include #include #include #include +#include + +// Project + libbatmondb C headers declare C-linkage symbols defined in the +// still-C common/ and libbatmondb translation units; include them as extern "C" +// so this C++ unit links against the unmangled names. +extern "C" { #include #include - -#include #include +} #define CHECK_BATTERY_TIMEOUT_S 15 // s - check battery percentage every 15s @@ -24,7 +28,7 @@ static bool is_suspended = false; int battery_current_state_duration = 0; int best_session_time = 0; -char *device_model = NULL; +char *device_model = nullptr; void register_handler(); void sigintHandler(int signum) { diff --git a/workspace/all/batmon/makefile b/workspace/all/batmon/makefile index 869d837d5..9bd9c2dc7 100644 --- a/workspace/all/batmon/makefile +++ b/workspace/all/batmon/makefile @@ -21,18 +21,29 @@ SDL?=SDL TARGET = batmon INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ -SOURCE = $(TARGET).c ../common/utils.c ../common/api.c ../common/config.c ../common/scaler.c ../../$(PLATFORM)/platform/platform.c +# Shared common/ + platform stay C; the tool itself is C++20. Compile the C +# units to objects, then compile the .cpp and link everything through g++. +SOURCE = -c ../common/utils.c ../common/api.c ../common/config.c ../common/scaler.c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp +CXXSOURCE += build/$(PLATFORM)/utils.o build/$(PLATFORM)/api.o build/$(PLATFORM)/config.o build/$(PLATFORM)/scaler.o build/$(PLATFORM)/platform.o CC = $(CROSS_COMPILE)gcc +CXX = $(CROSS_COMPILE)g++ +# Prefer real C++20; fall back to gnu++2a on older toolchains (e.g. the current +# gcc 8.3 tg5040 cross-compiler, which predates the -std=gnu++20 spelling). +CXXSTD := $(shell printf 'int main(){return 0;}' | $(CXX) -std=gnu++20 -x c++ - -o /dev/null >/dev/null 2>&1 && echo gnu++20 || echo gnu++2a) CFLAGS += $(OPT) -CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" -std=gnu99 +CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" +CXXFLAGS += $(CFLAGS) -std=$(CXXSTD) LDFLAGS += -lmsettings -lbatmondb -lsqlite3 PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/msettings.h $(PREFIX_LOCAL)/include/batmondb.h mkdir -p build/$(PLATFORM) - $(CC) $(SOURCE) -o $(PRODUCT) $(CFLAGS) $(LDFLAGS) + $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) + mv utils.o api.o config.o scaler.o platform.o build/$(PLATFORM) + $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) diff --git a/workspace/all/gametimectl/gametimectl.c b/workspace/all/gametimectl/gametimectl.cpp similarity index 91% rename from workspace/all/gametimectl/gametimectl.c rename to workspace/all/gametimectl/gametimectl.cpp index 9b030b76c..c2b05e3a3 100644 --- a/workspace/all/gametimectl/gametimectl.c +++ b/workspace/all/gametimectl/gametimectl.cpp @@ -1,12 +1,17 @@ // heavily modified from the Onion original: https://github.com/OnionUI/Onion/blob/main/src/playActivity/playActivity.c -#include +#include +#include +#include + +// Project + libgametimedb C headers declare C-linkage symbols defined in the +// still-C common/ and libgametimedb translation units; include as extern "C". +extern "C" { #include "defines.h" #include "api.h" #include "utils.h" - -#include #include +} void printUsage() { diff --git a/workspace/all/gametimectl/makefile b/workspace/all/gametimectl/makefile index 77d515141..db6ba485b 100644 --- a/workspace/all/gametimectl/makefile +++ b/workspace/all/gametimectl/makefile @@ -21,18 +21,29 @@ SDL?=SDL TARGET = gametimectl INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ -SOURCE = $(TARGET).c ../common/utils.c ../common/api.c ../common/scaler.c ../common/config.c ../../$(PLATFORM)/platform/platform.c +# Shared common/ + platform stay C; the tool itself is C++20. Compile the C +# units to objects, then compile the .cpp and link everything through g++. +SOURCE = -c ../common/utils.c ../common/api.c ../common/scaler.c ../common/config.c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp +CXXSOURCE += build/$(PLATFORM)/utils.o build/$(PLATFORM)/api.o build/$(PLATFORM)/scaler.o build/$(PLATFORM)/config.o build/$(PLATFORM)/platform.o CC = $(CROSS_COMPILE)gcc +CXX = $(CROSS_COMPILE)g++ +# Prefer real C++20; fall back to gnu++2a on older toolchains (e.g. the current +# gcc 8.3 tg5040 cross-compiler, which predates the -std=gnu++20 spelling). +CXXSTD := $(shell printf 'int main(){return 0;}' | $(CXX) -std=gnu++20 -x c++ - -o /dev/null >/dev/null 2>&1 && echo gnu++20 || echo gnu++2a) CFLAGS += $(OPT) -CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" -std=gnu99 +CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" +CXXFLAGS += $(CFLAGS) -std=$(CXXSTD) LDFLAGS += -lmsettings -lgametimedb -lsqlite3 PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/gametimedb.h mkdir -p build/$(PLATFORM) - $(CC) $(SOURCE) -o $(PRODUCT) $(CFLAGS) $(LDFLAGS) + $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) + mv utils.o api.o scaler.o config.o platform.o build/$(PLATFORM) + $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) diff --git a/workspace/all/nextval/makefile b/workspace/all/nextval/makefile index 2467a08be..f56c6230a 100644 --- a/workspace/all/nextval/makefile +++ b/workspace/all/nextval/makefile @@ -20,16 +20,27 @@ include ../../$(PLATFORM)/platform/makefile.env TARGET = nextval INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ -SOURCE = $(TARGET).c ../common/utils.c ../common/config.c +# Shared common/ stays C; the tool itself is C++20. Compile the C units to +# objects, then compile the .cpp and link everything through g++. +SOURCE = -c ../common/utils.c ../common/config.c +CXXSOURCE = $(TARGET).cpp +CXXSOURCE += build/$(PLATFORM)/utils.o build/$(PLATFORM)/config.o CC = $(CROSS_COMPILE)gcc +CXX = $(CROSS_COMPILE)g++ +# Prefer real C++20; fall back to gnu++2a on older toolchains (e.g. the current +# gcc 8.3 tg5040 cross-compiler, which predates the -std=gnu++20 spelling). +CXXSTD := $(shell printf 'int main(){return 0;}' | $(CXX) -std=gnu++20 -x c++ - -o /dev/null >/dev/null 2>&1 && echo gnu++20 || echo gnu++2a) CFLAGS += $(OPT) -CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" -std=gnu99 +CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" +CXXFLAGS += $(CFLAGS) -std=$(CXXSTD) PRODUCT= build/$(PLATFORM)/$(TARGET).elf -all: +all: mkdir -p build/$(PLATFORM) - $(CC) $(SOURCE) -o $(PRODUCT) $(CFLAGS) $(LDFLAGS) + $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) + mv utils.o config.o build/$(PLATFORM) + $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) diff --git a/workspace/all/nextval/nextval.c b/workspace/all/nextval/nextval.cpp similarity index 81% rename from workspace/all/nextval/nextval.c rename to workspace/all/nextval/nextval.cpp index fc68bf40a..cd7614347 100644 --- a/workspace/all/nextval/nextval.c +++ b/workspace/all/nextval/nextval.cpp @@ -1,8 +1,13 @@ -#include +#include +#include +// Project C headers declare C-linkage symbols defined in the still-C common/ +// translation units; include them as extern "C". +extern "C" { #include "defines.h" #include "api.h" #include "utils.h" +} void printUsage() { @@ -11,7 +16,7 @@ void printUsage() int main(int argc, char *argv[]) { - CFG_init(NULL, NULL); + CFG_init(nullptr, nullptr); if (argc <= 1) { CFG_print(); diff --git a/workspace/all/syncsettings/makefile b/workspace/all/syncsettings/makefile index d4f784b9d..c0b898619 100755 --- a/workspace/all/syncsettings/makefile +++ b/workspace/all/syncsettings/makefile @@ -15,17 +15,22 @@ endif ########################################################### TARGET = syncsettings -SOURCE = $(TARGET).c +# Single C++20 translation unit, no shared common/ deps; link through g++. +SOURCE = $(TARGET).cpp CC = $(CROSS_COMPILE)gcc -CFLAGS = $(OPT) -I$(PREFIX_LOCAL)/include -DPLATFORM=\"$(PLATFORM)\" +CXX = $(CROSS_COMPILE)g++ +# Prefer real C++20; fall back to gnu++2a on older toolchains (e.g. the current +# gcc 8.3 tg5040 cross-compiler, which predates the -std=gnu++20 spelling). +CXXSTD := $(shell printf 'int main(){return 0;}' | $(CXX) -std=gnu++20 -x c++ - -o /dev/null >/dev/null 2>&1 && echo gnu++20 || echo gnu++2a) +CXXFLAGS = $(OPT) -I$(PREFIX_LOCAL)/include -DPLATFORM=\"$(PLATFORM)\" -std=$(CXXSTD) LDFLAGS = -Os -L$(PREFIX_LOCAL)/lib -lmsettings -lrt -ldl -Wl,--gc-sections -s PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/msettings.h mkdir -p build/$(PLATFORM) - $(CC) $(SOURCE) -o $(PRODUCT) $(CFLAGS) $(LDFLAGS) + $(CXX) $(SOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) diff --git a/workspace/all/syncsettings/syncsettings.c b/workspace/all/syncsettings/syncsettings.cpp similarity index 60% rename from workspace/all/syncsettings/syncsettings.c rename to workspace/all/syncsettings/syncsettings.cpp index 2bf4c5934..5f93b918f 100644 --- a/workspace/all/syncsettings/syncsettings.c +++ b/workspace/all/syncsettings/syncsettings.cpp @@ -1,6 +1,10 @@ -#include +#include #include + +// libmsettings' public header is C (no extern "C" guard); include as extern "C". +extern "C" { #include "msettings.h" +} int main (int argc, char *argv[]) { InitSettings(); From 78327d3b4706be28e22118bc0e3740f6a0051167 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sun, 26 Jul 2026 10:22:42 +0200 Subject: [PATCH 64/77] refactor: convert bootlogo and clock to C++20 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 2 (leaf tools), UI group with SDL. Same settings.cpp-style mixed makefile (common/ + platform stay C; tool .cpp is C++20, linked via g++ -lstdc++), C project headers wrapped extern "C". C→C++ fixes: - (SDL_Rect){...} compound literals -> named local SDL_Rect (the nextui.cpp convention; g++'s handling of address-of-compound-literal is unreliable). - (char*[]){...} button-hint arrays -> named local const char* arrays, avoiding the g++ 8.3 miscompile that drops the literal's storage. - clock: the four GCC nested functions (blit/blitBar/blitNumber/validate, a C-only extension) become lambdas capturing the enclosing state by reference. - string-literal arrays -> const char*; realloc results cast (bootlogo); ampm_w initialized. Residual -Wwrite-strings warnings (string literal -> char* C-API params) are left as-is: they are inherent to the still-C common headers and already present in bulk across nextui.cpp (~545). Verified clean builds: bootlogo tg5040; clock tg5040 + desktop (host g++, gnu++20). --- .../all/bootlogo/{bootlogo.c => bootlogo.cpp} | 25 +++++--- workspace/all/bootlogo/makefile | 17 +++++- workspace/all/clock/{clock.c => clock.cpp} | 61 ++++++++++++------- workspace/all/clock/makefile | 17 +++++- 4 files changed, 83 insertions(+), 37 deletions(-) rename workspace/all/bootlogo/{bootlogo.c => bootlogo.cpp} (84%) rename workspace/all/clock/{clock.c => clock.cpp} (82%) diff --git a/workspace/all/bootlogo/bootlogo.c b/workspace/all/bootlogo/bootlogo.cpp similarity index 84% rename from workspace/all/bootlogo/bootlogo.c rename to workspace/all/bootlogo/bootlogo.cpp index c9c2913a3..52bccd62a 100644 --- a/workspace/all/bootlogo/bootlogo.c +++ b/workspace/all/bootlogo/bootlogo.cpp @@ -1,14 +1,17 @@ -#include +#include #include -#include -#include +#include #include #include -#include +// Project + libmsettings C headers declare C-linkage symbols defined in the +// still-C common/ and libmsettings translation units; include as extern "C". +extern "C" { +#include #include "defines.h" #include "api.h" #include "utils.h" +} static bool quit = false; @@ -57,9 +60,9 @@ int loadImages() SDL_Surface *bmp = IMG_Load(path); if (bmp) { count++; - images = realloc(images, sizeof(SDL_Surface*) * count); + images = (SDL_Surface**)realloc(images, sizeof(SDL_Surface*) * count); images[count-1] = bmp; - image_paths = realloc(image_paths, sizeof(char*) * count); + image_paths = (char**)realloc(image_paths, sizeof(char*) * count); image_paths[count-1] = strdup(path); } } @@ -140,7 +143,7 @@ int main(int argc, char *argv[]) // sync // umount $BOOT_PATH // reboot - char* boot_path = "/mnt/boot/"; + const char* boot_path = "/mnt/boot/"; char* logo_path = image_paths[selected]; char cmd[256]; snprintf(cmd, sizeof(cmd), "mkdir -p %s && mount -t vfat /dev/mmcblk0p1 %s && cp \"%s\" %s/bootlogo.bmp && sync && umount %s && reboot", boot_path, boot_path, logo_path, boot_path, boot_path); @@ -179,8 +182,12 @@ int main(int argc, char *argv[]) SDL_BlitSurface(image, NULL, screen, &image_rect); } - GFX_blitButtonGroup((char *[]){"L/R", "SCROLL", NULL}, 0, screen, 0); - GFX_blitButtonGroup((char *[]){"A", "SET", "B", "BACK", NULL}, 1, screen, 1); + // Route button hints through named local arrays: g++ 8.3 miscompiles + // a (char*[]){...} compound literal passed straight to a function. + const char* hints_scroll[] = {"L/R", "SCROLL", NULL}; + GFX_blitButtonGroup((char**)hints_scroll, 0, screen, 0); + const char* hints_set[] = {"A", "SET", "B", "BACK", NULL}; + GFX_blitButtonGroup((char**)hints_set, 1, screen, 1); GFX_flip(screen); dirty = 0; diff --git a/workspace/all/bootlogo/makefile b/workspace/all/bootlogo/makefile index b9a16f2bb..5ecd49199 100644 --- a/workspace/all/bootlogo/makefile +++ b/workspace/all/bootlogo/makefile @@ -21,18 +21,29 @@ SDL?=SDL TARGET = bootlogo INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ -SOURCE = $(TARGET).c ../common/utils.c ../common/api.c ../common/config.c ../common/scaler.c ../../$(PLATFORM)/platform/platform.c +# Shared common/ + platform stay C; the tool itself is C++20. Compile the C +# units to objects, then compile the .cpp and link everything through g++. +SOURCE = -c ../common/utils.c ../common/api.c ../common/config.c ../common/scaler.c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp +CXXSOURCE += build/$(PLATFORM)/utils.o build/$(PLATFORM)/api.o build/$(PLATFORM)/config.o build/$(PLATFORM)/scaler.o build/$(PLATFORM)/platform.o CC = $(CROSS_COMPILE)gcc +CXX = $(CROSS_COMPILE)g++ +# Prefer real C++20; fall back to gnu++2a on older toolchains (e.g. the current +# gcc 8.3 tg5040 cross-compiler, which predates the -std=gnu++20 spelling). +CXXSTD := $(shell printf 'int main(){return 0;}' | $(CXX) -std=gnu++20 -x c++ - -o /dev/null >/dev/null 2>&1 && echo gnu++20 || echo gnu++2a) CFLAGS += $(OPT) -CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" -std=gnu99 +CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" +CXXFLAGS += $(CFLAGS) -std=$(CXXSTD) LDFLAGS += -lmsettings PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/msettings.h mkdir -p build/$(PLATFORM) - $(CC) $(SOURCE) -o $(PRODUCT) $(CFLAGS) $(LDFLAGS) + $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) + mv utils.o api.o config.o scaler.o platform.o build/$(PLATFORM) + $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) diff --git a/workspace/all/clock/clock.c b/workspace/all/clock/clock.cpp similarity index 82% rename from workspace/all/clock/clock.c rename to workspace/all/clock/clock.cpp index d2782f818..6547e933a 100644 --- a/workspace/all/clock/clock.c +++ b/workspace/all/clock/clock.cpp @@ -1,13 +1,17 @@ // loosely based on https://github.com/gameblabla/clock_sdl_app -#include -#include +#include +#include #include -#include +// Project + libmsettings C headers declare C-linkage symbols defined in the +// still-C common/ and libmsettings translation units; include as extern "C". +extern "C" { +#include #include "defines.h" #include "api.h" #include "utils.h" +} enum { CURSOR_YEAR, @@ -32,20 +36,21 @@ int main(int argc , char* argv[]) { SDL_FillRect(digits, NULL, RGB_BLACK); SDL_Surface* digit; - char* chars[] = { "0","1","2","3","4","5","6","7","8","9","/",":", NULL }; - char* c; + const char* chars[] = { "0","1","2","3","4","5","6","7","8","9","/",":", NULL }; + const char* c; int i = 0; #define DIGIT_WIDTH 10 #define DIGIT_HEIGHT 16 #define CHAR_SLASH 10 #define CHAR_COLON 11 - while (c = chars[i]) { + while ((c = chars[i])) { digit = TTF_RenderUTF8_Blended(GFX_getFonts()->large, c, COLOR_WHITE); int y = i==CHAR_COLON ? SCALE1(-1.5) : 0; // : sits too low naturally // TODO: y offset is wrong here // printf("%s x:%i y:%i SCALE1(DIGIT_HEIGHT):%i SCALE1(DIGIT_HEIGHT) - digit->h:%i\n", c, (i * SCALE1(DIGIT_WIDTH)), y, SCALE1(DIGIT_HEIGHT), SCALE1(DIGIT_HEIGHT) - digit->h); fflush(stdout); - SDL_BlitSurface(digit, NULL, digits, &(SDL_Rect){ (i * SCALE1(DIGIT_WIDTH)) + (SCALE1(DIGIT_WIDTH) - digit->w)/2, y + (SCALE1(DIGIT_HEIGHT) - digit->h)/2 }); + SDL_Rect dst = { (i * SCALE1(DIGIT_WIDTH)) + (SCALE1(DIGIT_WIDTH) - digit->w)/2, y + (SCALE1(DIGIT_HEIGHT) - digit->h)/2 }; + SDL_BlitSurface(digit, NULL, digits, &dst); SDL_FreeSurface(digit); i += 1; } @@ -67,15 +72,20 @@ int main(int argc , char* argv[]) { int32_t seconds_selected = tm.tm_sec; int32_t am_selected = tm.tm_hour < 12; - // x,y,w are pre-scaled - int blit(int i, int x, int y) { - SDL_BlitSurface(digits, &(SDL_Rect){i*SCALE1(10),0,SCALE2(10,16)}, screen, &(SDL_Rect){x,y}); + // x,y,w are pre-scaled. These were GCC nested functions (a C-only extension); + // as C++ they become lambdas capturing the enclosing state (digits/screen and + // the date fields) by reference. + auto blit = [&](int i, int x, int y) -> int { + SDL_Rect src = { i*SCALE1(10), 0, SCALE2(10,16) }; + SDL_Rect dst = { x, y }; + SDL_BlitSurface(digits, &src, screen, &dst); return x + SCALE1(10); - } - void blitBar(int x, int y, int w) { - GFX_blitPill(ASSET_UNDERLINE, screen, &(SDL_Rect){x,y,w}); - } - int blitNumber(int num, int x, int y) { + }; + auto blitBar = [&](int x, int y, int w) { + SDL_Rect dst = { x, y, w }; + GFX_blitPill(ASSET_UNDERLINE, screen, &dst); + }; + auto blitNumber = [&](int num, int x, int y) -> int { int n; if (num > 999) { n = num / 1000; @@ -94,8 +104,8 @@ int main(int argc , char* argv[]) { x = blit(n, x,y); return x; - } - void validate(void) { + }; + auto validate = [&]() { // leap year uint32_t february_days = 28; if ( ((year_selected % 4 == 0) && (year_selected % 100 != 0)) || (year_selected % 400 == 0)) february_days = 29; @@ -135,7 +145,7 @@ int main(int argc , char* argv[]) { else if (minute_selected < 0) minute_selected += 60; if (seconds_selected > 59) seconds_selected -= 60; else if (seconds_selected < 0) seconds_selected += 60; - } + }; int option_count = 7; @@ -254,9 +264,15 @@ int main(int argc , char* argv[]) { GFX_blitHardwareGroup(screen, show_setting); if (show_setting) GFX_blitHardwareHints(screen, show_setting); - else GFX_blitButtonGroup((char*[]){ "SELECT",show_24hour?"12 HOUR":"24 HOUR", NULL }, 0, screen, 0); + else { + // Named local array: g++ 8.3 miscompiles a (char*[]){...} compound + // literal passed straight to a function. + const char* hints_hour[] = { "SELECT", show_24hour?"12 HOUR":"24 HOUR", NULL }; + GFX_blitButtonGroup((char**)hints_hour, 0, screen, 0); + } - GFX_blitButtonGroup((char*[]){ "B","CANCEL", "A","SET", NULL }, 1, screen, 1); + const char* hints_setcancel[] = { "B","CANCEL", "A","SET", NULL }; + GFX_blitButtonGroup((char**)hints_setcancel, 1, screen, 1); // 376 or 446 (@2x) // 188 or 223 (@1x) @@ -291,12 +307,13 @@ int main(int argc , char* argv[]) { x = blit(CHAR_COLON, x,y); x = blitNumber(seconds_selected, x,y); - int ampm_w; + int ampm_w = 0; if (!show_24hour) { x += SCALE1(10); // space SDL_Surface* text = TTF_RenderUTF8_Blended(GFX_getFonts()->large, am_selected ? "AM" : "PM", COLOR_WHITE); ampm_w = text->w + SCALE1(2); - SDL_BlitSurface(text, NULL, screen, &(SDL_Rect){x,y-SCALE1(3)}); + SDL_Rect dst = { x, y-SCALE1(3) }; + SDL_BlitSurface(text, NULL, screen, &dst); SDL_FreeSurface(text); } diff --git a/workspace/all/clock/makefile b/workspace/all/clock/makefile index cd5b08bde..83048c6d1 100644 --- a/workspace/all/clock/makefile +++ b/workspace/all/clock/makefile @@ -21,18 +21,29 @@ SDL?=SDL TARGET = clock INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ -SOURCE = $(TARGET).c ../common/utils.c ../common/api.c ../common/config.c ../common/scaler.c ../../$(PLATFORM)/platform/platform.c +# Shared common/ + platform stay C; the tool itself is C++20. Compile the C +# units to objects, then compile the .cpp and link everything through g++. +SOURCE = -c ../common/utils.c ../common/api.c ../common/config.c ../common/scaler.c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp +CXXSOURCE += build/$(PLATFORM)/utils.o build/$(PLATFORM)/api.o build/$(PLATFORM)/config.o build/$(PLATFORM)/scaler.o build/$(PLATFORM)/platform.o CC = $(CROSS_COMPILE)gcc +CXX = $(CROSS_COMPILE)g++ +# Prefer real C++20; fall back to gnu++2a on older toolchains (e.g. the current +# gcc 8.3 tg5040 cross-compiler, which predates the -std=gnu++20 spelling). +CXXSTD := $(shell printf 'int main(){return 0;}' | $(CXX) -std=gnu++20 -x c++ - -o /dev/null >/dev/null 2>&1 && echo gnu++20 || echo gnu++2a) CFLAGS += $(OPT) -CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" -std=gnu99 +CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" +CXXFLAGS += $(CFLAGS) -std=$(CXXSTD) LDFLAGS += -lmsettings PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/msettings.h mkdir -p build/$(PLATFORM) - $(CC) $(SOURCE) -o $(PRODUCT) $(CFLAGS) $(LDFLAGS) + $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) + mv utils.o api.o config.o scaler.o platform.o build/$(PLATFORM) + $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) From 02ceef83b00e7baa0e3d3426154af449a31a11f1 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sun, 26 Jul 2026 10:40:36 +0200 Subject: [PATCH 65/77] refactor: convert minput, gametime, ledcontrol, battery to C++20 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 2 (leaf tools), the SDL-heavy UI group. Same settings.cpp-style mixed makefile (common/ + platform stay C, tool .cpp is C++20, linked via g++ -lstdc++); still-C project headers (defines/api/utils/sdl, batmondb/gametimedb, msettings) wrapped extern "C". C→C++ fixes: - Every &(SDL_Rect){...} compound literal -> a named local SDL_Rect. g++ in strict C++ rejects taking the address of a compound-literal temporary ("taking address of temporary"), so this is required, not cosmetic. By-value compound literals (drawBatteryIcon, rect = ...) become SDL_Rect{...}. - (char*[]){...} button-hint arrays -> named local const char* arrays (the g++ 8.3 storage-drop miscompile). - malloc/realloc results cast; NULL -> nullptr; C++ headers. - ledcontrol: explicit (int) cast on color1 in the int settings_values[] brace-init to make the uint32_t->int narrowing intentional (-Wnarrowing). Verified: full `make build` clean on tg5040 (g++ 8.3, gnu++2a) and desktop (host g++, gnu++20); all 10 tool elfs produced. minput also builds desktop. --- .../all/battery/{battery.c => battery.cpp} | 94 ++++++++++++------- workspace/all/battery/makefile | 17 +++- .../all/gametime/{gametime.c => gametime.cpp} | 81 ++++++++++------ workspace/all/gametime/makefile | 17 +++- .../{ledcontrol.c => ledcontrol.cpp} | 56 ++++++----- workspace/all/ledcontrol/makefile | 17 +++- workspace/all/minput/makefile | 17 +++- workspace/all/minput/{minput.c => minput.cpp} | 57 ++++++----- 8 files changed, 232 insertions(+), 124 deletions(-) rename workspace/all/battery/{battery.c => battery.cpp} (88%) rename workspace/all/gametime/{gametime.c => gametime.cpp} (85%) rename workspace/all/ledcontrol/{ledcontrol.c => ledcontrol.cpp} (87%) rename workspace/all/minput/{minput.c => minput.cpp} (80%) diff --git a/workspace/all/battery/battery.c b/workspace/all/battery/battery.cpp similarity index 88% rename from workspace/all/battery/battery.c rename to workspace/all/battery/battery.cpp index 6541d66eb..2426ac76a 100644 --- a/workspace/all/battery/battery.c +++ b/workspace/all/battery/battery.cpp @@ -1,16 +1,20 @@ // heavily modified from the Onion original: https://github.com/OnionUI/Onion/tree/main/src/batteryMonitorUI -#include +#include #include -#include -#include -#include +#include +#include + +#include +// Project + libbatmondb C headers declare C-linkage symbols defined in the +// still-C common/ and libbatmondb translation units; include as extern "C". +extern "C" { +#include #include "defines.h" #include "api.h" #include "utils.h" - -#include #include +} #define GRAPH_LINE_WIDTH 1 @@ -126,8 +130,8 @@ static void sigHandler(int sig) static SDL_Surface *screen; -char *device_model = NULL; -sqlite3 *bat_log_db = NULL; +char *device_model = nullptr; +sqlite3 *bat_log_db = nullptr; void secondsToHoursMinutes(int seconds, char *output) { @@ -196,8 +200,10 @@ int _renderText(const char *text, TTF_Font *font, SDL_Color color, SDL_Rect *rec if (textSurface != NULL) { text_width = textSurface->w; - if (right_align) - SDL_BlitSurface(textSurface, NULL, screen, &(SDL_Rect){rect->x - textSurface->w, rect->y, rect->w, rect->h}); + if (right_align) { + SDL_Rect r = {rect->x - textSurface->w, rect->y, rect->w, rect->h}; + SDL_BlitSurface(textSurface, NULL, screen, &r); + } else SDL_BlitSurface(textSurface, NULL, screen, rect); SDL_FreeSurface(textSurface); @@ -395,18 +401,20 @@ void drawBatteryIcon(int percent, SDL_Rect dst) { int x = dst.x; int y = dst.y; //SDL_Rect rect = asset_rects[ASSET_BATTERY]; - SDL_Rect rect = (SDL_Rect){SCALE4(47,51,17,10)}; - GFX_blitAsset(ASSET_BATTERY, NULL, screen, &(SDL_Rect){x,y}); + SDL_Rect rect = {SCALE4(47,51,17,10)}; + SDL_Rect battery_dst = {x,y}; + GFX_blitAsset(ASSET_BATTERY, NULL, screen, &battery_dst); //rect = asset_rects[ASSET_BATTERY_FILL]; - rect = (SDL_Rect){SCALE4(81,33,12,6)}; + rect = SDL_Rect{SCALE4(81,33,12,6)}; SDL_Rect clip = rect; clip.w *= percent; clip.w /= 100; if (clip.w<=0) return; clip.x = rect.w - clip.w; clip.y = 0; - - GFX_blitAsset(ASSET_BATTERY_FILL, &clip, screen, &(SDL_Rect){x+SCALE1(3)+clip.x,y+SCALE1(2)}); + + SDL_Rect fill_dst = {x+SCALE1(3)+clip.x,y+SCALE1(2)}; + GFX_blitAsset(ASSET_BATTERY_FILL, &clip, screen, &fill_dst); } void renderPage() @@ -453,29 +461,37 @@ void renderPage() switch_zoom_profile(segment_duration); // x axis labels - renderText(label[0], GFX_getFonts()->small, COLOR_WHITE, &(SDL_Rect){graph.layout.label1_x, graph.layout.label_y, 32, 32}); - renderText(label[1], GFX_getFonts()->small, COLOR_WHITE, &(SDL_Rect){graph.layout.label2_x, graph.layout.label_y, 32, 32}); - renderText(label[2], GFX_getFonts()->small, COLOR_WHITE, &(SDL_Rect){graph.layout.label3_x, graph.layout.label_y, 32, 32}); - renderText(label[3], GFX_getFonts()->small, COLOR_WHITE, &(SDL_Rect){graph.layout.label4_x, graph.layout.label_y, 32, 32}); + SDL_Rect lbl0 = {graph.layout.label1_x, graph.layout.label_y, 32, 32}; + renderText(label[0], GFX_getFonts()->small, COLOR_WHITE, &lbl0); + SDL_Rect lbl1 = {graph.layout.label2_x, graph.layout.label_y, 32, 32}; + renderText(label[1], GFX_getFonts()->small, COLOR_WHITE, &lbl1); + SDL_Rect lbl2 = {graph.layout.label3_x, graph.layout.label_y, 32, 32}; + renderText(label[2], GFX_getFonts()->small, COLOR_WHITE, &lbl2); + SDL_Rect lbl3 = {graph.layout.label4_x, graph.layout.label_y, 32, 32}; + renderText(label[3], GFX_getFonts()->small, COLOR_WHITE, &lbl3); // y axis "labels" - drawBatteryIcon(100, (SDL_Rect){graph.layout.icon_x, graph.layout.icon1_y}); - drawBatteryIcon(66, (SDL_Rect){graph.layout.icon_x, graph.layout.icon2_y}); - drawBatteryIcon(33, (SDL_Rect){graph.layout.icon_x, graph.layout.icon3_y}); - drawBatteryIcon(0, (SDL_Rect){graph.layout.icon_x, graph.layout.icon4_y}); + drawBatteryIcon(100, SDL_Rect{graph.layout.icon_x, graph.layout.icon1_y}); + drawBatteryIcon(66, SDL_Rect{graph.layout.icon_x, graph.layout.icon2_y}); + drawBatteryIcon(33, SDL_Rect{graph.layout.icon_x, graph.layout.icon3_y}); + drawBatteryIcon(0, SDL_Rect{graph.layout.icon_x, graph.layout.icon4_y}); char text_line[255]; sprintf(text_line, "Since Charge: %s", session_duration); - renderText(text_line, GFX_getFonts()->medium, COLOR_WHITE, &(SDL_Rect){graph.layout.label_session_x, graph.layout.label_session_y, graph.layout.label_size_x, graph.layout.label_size_y}); + SDL_Rect session_rect = {graph.layout.label_session_x, graph.layout.label_session_y, graph.layout.label_size_x, graph.layout.label_size_y}; + renderText(text_line, GFX_getFonts()->medium, COLOR_WHITE, &session_rect); sprintf(text_line, "Current: %s", current_percentage); - renderText(text_line, GFX_getFonts()->medium, COLOR_WHITE, &(SDL_Rect){graph.layout.label_current_x, graph.layout.label_current_y, graph.layout.label_size_x, graph.layout.label_size_y}); + SDL_Rect current_rect = {graph.layout.label_current_x, graph.layout.label_current_y, graph.layout.label_size_x, graph.layout.label_size_y}; + renderText(text_line, GFX_getFonts()->medium, COLOR_WHITE, ¤t_rect); sprintf(text_line, "Remaining: %s", session_left); - renderTextAlignRight(text_line, GFX_getFonts()->medium, COLOR_WHITE, &(SDL_Rect){graph.layout.label_left_x, graph.layout.label_left_y, graph.layout.label_size_x, graph.layout.label_size_y}); + SDL_Rect left_rect = {graph.layout.label_left_x, graph.layout.label_left_y, graph.layout.label_size_x, graph.layout.label_size_y}; + renderTextAlignRight(text_line, GFX_getFonts()->medium, COLOR_WHITE, &left_rect); sprintf(text_line, "Longest: %s", session_best); - renderTextAlignRight(text_line, GFX_getFonts()->medium, COLOR_WHITE, &(SDL_Rect){graph.layout.label_best_x, graph.layout.label_best_y, graph.layout.label_size_x, graph.layout.label_size_y}); + SDL_Rect best_rect = {graph.layout.label_best_x, graph.layout.label_best_y, graph.layout.label_size_x, graph.layout.label_size_y}; + renderTextAlignRight(text_line, GFX_getFonts()->medium, COLOR_WHITE, &best_rect); int half_line_width = (int)(GRAPH_LINE_WIDTH) / 2; @@ -556,8 +572,10 @@ void renderPage() } } SDL_UnlockSurface(screen); - if (x_end != 0) - GFX_blitAsset(ASSET_BATTERY_LOW, NULL, screen, &(SDL_Rect){x_end, y_end}); + if (x_end != 0) { + SDL_Rect low_dst = {x_end, y_end}; + GFX_blitAsset(ASSET_BATTERY_LOW, NULL, screen, &low_dst); + } } } @@ -752,8 +770,11 @@ int main(int argc, char *argv[]) SDL_Surface *text; text = TTF_RenderUTF8_Blended(GFX_getFonts()->large, title, COLOR_WHITE); - GFX_blitPill(ASSET_BLACK_PILL, screen, &(SDL_Rect){SCALE1(PADDING), SCALE1(PADDING), max_width, SCALE1(PILL_SIZE)}); - SDL_BlitSurface(text, &(SDL_Rect){0, 0, max_width - SCALE1(BUTTON_PADDING * 2), text->h}, screen, &(SDL_Rect){SCALE1(PADDING + BUTTON_PADDING), SCALE1(PADDING + 4)}); + SDL_Rect title_pill = {SCALE1(PADDING), SCALE1(PADDING), max_width, SCALE1(PILL_SIZE)}; + GFX_blitPill(ASSET_BLACK_PILL, screen, &title_pill); + SDL_Rect title_src = {0, 0, max_width - SCALE1(BUTTON_PADDING * 2), text->h}; + SDL_Rect title_dst = {SCALE1(PADDING + BUTTON_PADDING), SCALE1(PADDING + 4)}; + SDL_BlitSurface(text, &title_src, screen, &title_dst); SDL_FreeSurface(text); } @@ -761,10 +782,15 @@ int main(int argc, char *argv[]) if (show_setting) GFX_blitHardwareHints(screen, show_setting); - else - GFX_blitButtonGroup((char *[]){"L/R", "SCROLL", "L1/R1", "ZOOM", NULL}, 0, screen, 0); + else { + // Named local array: g++ 8.3 miscompiles a (char*[]){...} compound + // literal passed straight to a function. + const char* hints_scroll[] = {"L/R", "SCROLL", "L1/R1", "ZOOM", NULL}; + GFX_blitButtonGroup((char**)hints_scroll, 0, screen, 0); + } - GFX_blitButtonGroup((char *[]){"B", "BACK", NULL}, 1, screen, 1); + const char* hints_back[] = {"B", "BACK", NULL}; + GFX_blitButtonGroup((char**)hints_back, 1, screen, 1); GFX_flip(screen); dirty = 0; diff --git a/workspace/all/battery/makefile b/workspace/all/battery/makefile index 98856bfba..ada509f3d 100644 --- a/workspace/all/battery/makefile +++ b/workspace/all/battery/makefile @@ -21,18 +21,29 @@ SDL?=SDL TARGET = battery INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ -SOURCE = $(TARGET).c ../common/utils.c ../common/api.c ../common/config.c ../common/scaler.c ../../$(PLATFORM)/platform/platform.c +# Shared common/ + platform stay C; the tool itself is C++20. Compile the C +# units to objects, then compile the .cpp and link everything through g++. +SOURCE = -c ../common/utils.c ../common/api.c ../common/config.c ../common/scaler.c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp +CXXSOURCE += build/$(PLATFORM)/utils.o build/$(PLATFORM)/api.o build/$(PLATFORM)/config.o build/$(PLATFORM)/scaler.o build/$(PLATFORM)/platform.o CC = $(CROSS_COMPILE)gcc +CXX = $(CROSS_COMPILE)g++ +# Prefer real C++20; fall back to gnu++2a on older toolchains (e.g. the current +# gcc 8.3 tg5040 cross-compiler, which predates the -std=gnu++20 spelling). +CXXSTD := $(shell printf 'int main(){return 0;}' | $(CXX) -std=gnu++20 -x c++ - -o /dev/null >/dev/null 2>&1 && echo gnu++20 || echo gnu++2a) CFLAGS += $(OPT) -CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" -std=gnu99 +CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" +CXXFLAGS += $(CFLAGS) -std=$(CXXSTD) LDFLAGS += -lmsettings -lbatmondb -lsqlite3 PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/batmondb.h mkdir -p build/$(PLATFORM) - $(CC) $(SOURCE) -o $(PRODUCT) $(CFLAGS) $(LDFLAGS) + $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) + mv utils.o api.o config.o scaler.o platform.o build/$(PLATFORM) + $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) diff --git a/workspace/all/gametime/gametime.c b/workspace/all/gametime/gametime.cpp similarity index 85% rename from workspace/all/gametime/gametime.c rename to workspace/all/gametime/gametime.cpp index 39fee9647..7ce3b92cb 100644 --- a/workspace/all/gametime/gametime.c +++ b/workspace/all/gametime/gametime.cpp @@ -1,16 +1,20 @@ // heavily modified from the Onion original: https://github.com/OnionUI/Onion/blob/main/src/playActivity/playActivityUI.c -#include +#include #include -#include -#include -#include +#include +#include + +#include +// Project + libgametimedb C headers declare C-linkage symbols defined in the +// still-C common/ and libgametimedb translation units; include as extern "C". +extern "C" { +#include #include "defines.h" #include "api.h" #include "utils.h" - -#include #include +} struct ListLayout { @@ -59,8 +63,10 @@ int _renderText(const char *text, TTF_Font *font, SDL_Color color, SDL_Rect *rec SDL_Surface *textSurface = TTF_RenderUTF8_Blended(font, text, color); if (textSurface != NULL) { text_width = textSurface->w; - if (right_align) - SDL_BlitSurface(textSurface, NULL, screen, &(SDL_Rect){rect->w - textSurface->w, rect->y, rect->w, rect->h}); + if (right_align) { + SDL_Rect r = {rect->w - textSurface->w, rect->y, rect->w, rect->h}; + SDL_BlitSurface(textSurface, NULL, screen, &r); + } else SDL_BlitSurface(textSurface, NULL, screen, rect); SDL_FreeSurface(textSurface); @@ -172,7 +178,7 @@ SDL_Surface *loadRomImage(char *image_path) void preloadRomImages() { // load all rom images into SDL_Surfaces - romImages = malloc(sizeof(SDL_Surface *) * play_activities->count); + romImages = (SDL_Surface **)malloc(sizeof(SDL_Surface *) * play_activities->count); for (int i = 0; i < play_activities->count; i++) { PlayActivity *entry = play_activities->play_activity[i]; ROM *rom = entry->rom; @@ -209,12 +215,13 @@ void renderList(int count, int start, int end, int selected) PlayActivity *entry = play_activities->play_activity[index]; ROM *rom = entry->rom; - renderRoundedRectangle((SDL_Rect){ - layout.list_display_start_x, - layout.list_display_start_y + row * elemHeight, - layout.list_display_size_x, + SDL_Rect rowRect = { + layout.list_display_start_x, + layout.list_display_start_y + row * elemHeight, + layout.list_display_size_x, elemHeight - }, isSelected ? RGB_WHITE : RGB_BLACK, SCALE1(24)); + }; + renderRoundedRectangle(rowRect, isSelected ? RGB_WHITE : RGB_BLACK, SCALE1(24)); SDL_Surface *romImage = romImages[index]; if (romImage) { @@ -238,13 +245,14 @@ void renderList(int count, int start, int end, int selected) // TODO: no getter exposed for this right now //SDL_Rect rect = asset_rects[ASSET_GAMEPAD]; - SDL_Rect rect = (SDL_Rect){SCALE4(92,51,18,10)}; + SDL_Rect rect = {SCALE4(92,51,18,10)}; int x = rectRomImage.x; int y = rectRomImage.y; x += (SCALE1(IMG_MAX_WIDTH) - rect.w) / 2; y += (SCALE1(IMG_MAX_HEIGHT) - rect.h) / 2; - GFX_blitAssetColor(ASSET_GAMEPAD, NULL, screen, &(SDL_Rect){x,y}, THEME_COLOR1_255); + SDL_Rect gamepad_dst = {x,y}; + GFX_blitAssetColor(ASSET_GAMEPAD, NULL, screen, &gamepad_dst, THEME_COLOR1_255); } cleanName(rom_name, rom->name); @@ -253,11 +261,12 @@ void renderList(int count, int start, int end, int selected) //textColor = uintToColour(THEME_COLOR1); textColor = COLOR_BLACK; } - renderText(rom_name, GFX_getFonts()->medium, textColor, &(SDL_Rect){ - layout.list_display_start_x + num_width + thumbMargin + SCALE1(IMG_MAX_WIDTH), - layout.list_display_start_y + thumbMargin / 2 + elemHeight * row, - layout.list_display_size_x, - textHeight}); + SDL_Rect nameRect = { + layout.list_display_start_x + num_width + thumbMargin + SCALE1(IMG_MAX_WIDTH), + layout.list_display_start_y + thumbMargin / 2 + elemHeight * row, + layout.list_display_size_x, + textHeight}; + renderText(rom_name, GFX_getFonts()->medium, textColor, &nameRect); serializeTime(total, entry->play_time_total); serializeTime(average, entry->play_time_average); @@ -283,10 +292,14 @@ void renderList(int count, int start, int end, int selected) #define SCROLL_HEIGHT 4 int ox = (screen->w - SCALE1(SCROLL_WIDTH)) / 2; int oy = SCALE1((PILL_SIZE - SCROLL_HEIGHT) / 2); - if (start>0) - GFX_blitAsset(ASSET_SCROLL_UP, NULL, screen, &(SDL_Rect){ox, SCALE1(PADDING + PILL_SIZE)}); - if (endh - SCALE1(PADDING + PILL_SIZE + BUTTON_SIZE) + oy}); + if (start>0) { + SDL_Rect up_dst = {ox, SCALE1(PADDING + PILL_SIZE)}; + GFX_blitAsset(ASSET_SCROLL_UP, NULL, screen, &up_dst); + } + if (endh - SCALE1(PADDING + PILL_SIZE + BUTTON_SIZE) + oy}; + GFX_blitAsset(ASSET_SCROLL_DOWN, NULL, screen, &down_dst); + } } } @@ -415,8 +428,11 @@ int main(int argc, char *argv[]) SDL_Surface *text; text = TTF_RenderUTF8_Blended(GFX_getFonts()->large, title, COLOR_WHITE); - GFX_blitPill(ASSET_BLACK_PILL, screen, &(SDL_Rect){SCALE1(PADDING), SCALE1(PADDING), max_width, SCALE1(PILL_SIZE)}); - SDL_BlitSurface(text, &(SDL_Rect){0, 0, max_width - SCALE1(BUTTON_PADDING * 2), text->h}, screen, &(SDL_Rect){SCALE1(PADDING + BUTTON_PADDING), SCALE1(PADDING + 4)}); + SDL_Rect pill = {SCALE1(PADDING), SCALE1(PADDING), max_width, SCALE1(PILL_SIZE)}; + GFX_blitPill(ASSET_BLACK_PILL, screen, &pill); + SDL_Rect title_src = {0, 0, max_width - SCALE1(BUTTON_PADDING * 2), text->h}; + SDL_Rect title_dst = {SCALE1(PADDING + BUTTON_PADDING), SCALE1(PADDING + 4)}; + SDL_BlitSurface(text, &title_src, screen, &title_dst); SDL_FreeSurface(text); } @@ -424,10 +440,15 @@ int main(int argc, char *argv[]) if (show_setting) GFX_blitHardwareHints(screen, show_setting); - else - GFX_blitButtonGroup((char *[]){"U/D", "SCROLL", NULL}, 0, screen, 0); + else { + // Named local array: g++ 8.3 miscompiles a (char*[]){...} compound + // literal passed straight to a function. + const char* hints_scroll[] = {"U/D", "SCROLL", NULL}; + GFX_blitButtonGroup((char**)hints_scroll, 0, screen, 0); + } - GFX_blitButtonGroup((char *[]){"B", "BACK", NULL}, 1, screen, 1); + const char* hints_back[] = {"B", "BACK", NULL}; + GFX_blitButtonGroup((char**)hints_back, 1, screen, 1); GFX_flip(screen); dirty = 0; diff --git a/workspace/all/gametime/makefile b/workspace/all/gametime/makefile index 6448fcee6..5a4467766 100644 --- a/workspace/all/gametime/makefile +++ b/workspace/all/gametime/makefile @@ -21,18 +21,29 @@ SDL?=SDL TARGET = gametime INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ -SOURCE = $(TARGET).c ../common/utils.c ../common/api.c ../common/config.c ../common/scaler.c ../../$(PLATFORM)/platform/platform.c +# Shared common/ + platform stay C; the tool itself is C++20. Compile the C +# units to objects, then compile the .cpp and link everything through g++. +SOURCE = -c ../common/utils.c ../common/api.c ../common/config.c ../common/scaler.c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp +CXXSOURCE += build/$(PLATFORM)/utils.o build/$(PLATFORM)/api.o build/$(PLATFORM)/config.o build/$(PLATFORM)/scaler.o build/$(PLATFORM)/platform.o CC = $(CROSS_COMPILE)gcc +CXX = $(CROSS_COMPILE)g++ +# Prefer real C++20; fall back to gnu++2a on older toolchains (e.g. the current +# gcc 8.3 tg5040 cross-compiler, which predates the -std=gnu++20 spelling). +CXXSTD := $(shell printf 'int main(){return 0;}' | $(CXX) -std=gnu++20 -x c++ - -o /dev/null >/dev/null 2>&1 && echo gnu++20 || echo gnu++2a) CFLAGS += $(OPT) -CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" -std=gnu99 +CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" +CXXFLAGS += $(CFLAGS) -std=$(CXXSTD) LDFLAGS += -lmsettings -lgametimedb -lsqlite3 PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/gametimedb.h mkdir -p build/$(PLATFORM) - $(CC) $(SOURCE) -o $(PRODUCT) $(CFLAGS) $(LDFLAGS) + $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) + mv utils.o api.o config.o scaler.o platform.o build/$(PLATFORM) + $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) diff --git a/workspace/all/ledcontrol/ledcontrol.c b/workspace/all/ledcontrol/ledcontrol.cpp similarity index 87% rename from workspace/all/ledcontrol/ledcontrol.c rename to workspace/all/ledcontrol/ledcontrol.cpp index fd85b18dd..aa886d415 100644 --- a/workspace/all/ledcontrol/ledcontrol.c +++ b/workspace/all/ledcontrol/ledcontrol.cpp @@ -1,10 +1,12 @@ -#include +// Project + libmsettings C headers declare C-linkage symbols defined in the +// still-C common/ and libmsettings translation units; include as extern "C". +extern "C" { #include - #include "sdl.h" #include "defines.h" #include "api.h" #include "utils.h" +} #define NUM_OPTIONS 4 @@ -307,8 +309,10 @@ int main(int argc, char *argv[]) if (show_setting) GFX_blitHardwareHints(screen, show_setting); - GFX_blitButtonGroup((char*[]){ "B","BACK", NULL }, 1, screen, 1); - GFX_blitButtonGroup((char*[]){ "L/R","Select light", NULL }, 0, screen, 0); + const char* hints_back[] = { "B","BACK", NULL }; + GFX_blitButtonGroup((char**)hints_back, 1, screen, 1); + const char* hints_light[] = { "L/R","Select light", NULL }; + GFX_blitButtonGroup((char**)hints_light, 0, screen, 0); int max_width = screen->w - SCALE1(PADDING * 2) - ow; @@ -322,8 +326,11 @@ int main(int argc, char *argv[]) SDL_Surface *text; text = TTF_RenderUTF8_Blended(GFX_getFonts()->medium, title, COLOR_WHITE); - GFX_blitPill(ASSET_BLACK_PILL, screen, &(SDL_Rect){SCALE1(PADDING), SCALE1(PADDING), max_width, SCALE1(PILL_SIZE)}); - SDL_BlitSurface(text, &(SDL_Rect){0, 0, max_width - SCALE1(BUTTON_PADDING * 2), text->h}, screen, &(SDL_Rect){SCALE1(PADDING + BUTTON_PADDING), SCALE1(PADDING + 4)}); + SDL_Rect title_pill = {SCALE1(PADDING), SCALE1(PADDING), max_width, SCALE1(PILL_SIZE)}; + GFX_blitPill(ASSET_BLACK_PILL, screen, &title_pill); + SDL_Rect title_src = {0, 0, max_width - SCALE1(BUTTON_PADDING * 2), text->h}; + SDL_Rect title_dst = {SCALE1(PADDING + BUTTON_PADDING), SCALE1(PADDING + 4)}; + SDL_BlitSurface(text, &title_src, screen, &title_dst); SDL_FreeSurface(text); // Display settings @@ -339,7 +346,7 @@ int main(int argc, char *argv[]) } int settings_values[5] = { lightsDefault[selected_light].effect, - lightsDefault[selected_light].color1, + (int)lightsDefault[selected_light].color1, // 0xRRGGBB fits in int; explicit narrowing lightsDefault[selected_light].speed, lightsDefault[selected_light].brightness, lightsDefault[selected_light].inbrightness @@ -357,37 +364,38 @@ int main(int argc, char *argv[]) snprintf(setting_text, sizeof(setting_text), "%s: %s", settings_labels[j], selected_light == 3 ? lr_effect_names[settings_values[j] - 1] : selected_light == 2 ? topbar_effect_names[settings_values[j] - 1] : effect_names[settings_values[j] - 1]); SDL_Surface *text = TTF_RenderUTF8_Blended(GFX_getFonts()->medium, setting_text, current_color); int text_width = text->w + SCALE1(BUTTON_PADDING * 2); - GFX_blitPill(selected ? ASSET_WHITE_PILL : ASSET_BLACK_PILL, screen, - &(SDL_Rect){SCALE1(PADDING), y, text_width, SCALE1(PILL_SIZE)}); - SDL_BlitSurface(text, - &(SDL_Rect){0, 0, text->w, text->h}, screen, - &(SDL_Rect){SCALE1(PADDING + BUTTON_PADDING), y + SCALE1(4)}); + SDL_Rect pill = {SCALE1(PADDING), y, text_width, SCALE1(PILL_SIZE)}; + GFX_blitPill(selected ? ASSET_WHITE_PILL : ASSET_BLACK_PILL, screen, &pill); + SDL_Rect blit_src = {0, 0, text->w, text->h}; + SDL_Rect blit_dst = {SCALE1(PADDING + BUTTON_PADDING), y + SCALE1(4)}; + SDL_BlitSurface(text, &blit_src, screen, &blit_dst); SDL_FreeSurface(text); } else if (j == 1) { // Display color as hex code snprintf(setting_text, sizeof(setting_text), "%s", settings_labels[j]); SDL_Surface *text = TTF_RenderUTF8_Blended(GFX_getFonts()->medium, setting_text, current_color); int text_width = text->w + SCALE1(BUTTON_PADDING * 2); - GFX_blitPill(selected ? ASSET_WHITE_PILL : ASSET_BLACK_PILL, screen, - &(SDL_Rect){SCALE1(PADDING), y, text_width + SCALE1(BUTTON_MARGIN + BUTTON_SIZE), SCALE1(PILL_SIZE)}); - SDL_BlitSurface(text, - &(SDL_Rect){0, 0, text->w, text->h}, screen, - &(SDL_Rect){SCALE1(PADDING + BUTTON_PADDING), y + SCALE1(4)}); + SDL_Rect pill = {SCALE1(PADDING), y, text_width + SCALE1(BUTTON_MARGIN + BUTTON_SIZE), SCALE1(PILL_SIZE)}; + GFX_blitPill(selected ? ASSET_WHITE_PILL : ASSET_BLACK_PILL, screen, &pill); + SDL_Rect blit_src = {0, 0, text->w, text->h}; + SDL_Rect blit_dst = {SCALE1(PADDING + BUTTON_PADDING), y + SCALE1(4)}; + SDL_BlitSurface(text, &blit_src, screen, &blit_dst); SDL_FreeSurface(text); // color1 is stored as 0xRRGGBB; GFX_blitAssetColor expects 0xRRGGBBAA - GFX_blitAssetColor(ASSET_BUTTON, NULL, screen, &(SDL_Rect){ + SDL_Rect color_dst = { SCALE1(PADDING) + text_width, y + SCALE1(BUTTON_MARGIN) - }, ((uint32_t)settings_values[j] << 8) | 0xFF); + }; + GFX_blitAssetColor(ASSET_BUTTON, NULL, screen, &color_dst, ((uint32_t)settings_values[j] << 8) | 0xFF); } else { snprintf(setting_text, sizeof(setting_text), "%s: %d", settings_labels[j], settings_values[j]); SDL_Surface *text = TTF_RenderUTF8_Blended(GFX_getFonts()->medium, setting_text, current_color); int text_width = text->w + SCALE1(BUTTON_PADDING * 2); - GFX_blitPill(selected ? ASSET_WHITE_PILL : ASSET_BLACK_PILL, screen, - &(SDL_Rect){SCALE1(PADDING), y, text_width, SCALE1(PILL_SIZE)}); - SDL_BlitSurface(text, - &(SDL_Rect){0, 0, text->w, text->h}, screen, - &(SDL_Rect){SCALE1(PADDING + BUTTON_PADDING), y + SCALE1(4)}); + SDL_Rect pill = {SCALE1(PADDING), y, text_width, SCALE1(PILL_SIZE)}; + GFX_blitPill(selected ? ASSET_WHITE_PILL : ASSET_BLACK_PILL, screen, &pill); + SDL_Rect blit_src = {0, 0, text->w, text->h}; + SDL_Rect blit_dst = {SCALE1(PADDING + BUTTON_PADDING), y + SCALE1(4)}; + SDL_BlitSurface(text, &blit_src, screen, &blit_dst); SDL_FreeSurface(text); } } diff --git a/workspace/all/ledcontrol/makefile b/workspace/all/ledcontrol/makefile index c893d5787..b085c634a 100644 --- a/workspace/all/ledcontrol/makefile +++ b/workspace/all/ledcontrol/makefile @@ -21,18 +21,29 @@ SDL?=SDL TARGET = ledcontrol INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ -SOURCE = $(TARGET).c ../common/utils.c ../common/api.c ../common/config.c ../common/scaler.c ../../$(PLATFORM)/platform/platform.c +# Shared common/ + platform stay C; the tool itself is C++20. Compile the C +# units to objects, then compile the .cpp and link everything through g++. +SOURCE = -c ../common/utils.c ../common/api.c ../common/config.c ../common/scaler.c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp +CXXSOURCE += build/$(PLATFORM)/utils.o build/$(PLATFORM)/api.o build/$(PLATFORM)/config.o build/$(PLATFORM)/scaler.o build/$(PLATFORM)/platform.o CC = $(CROSS_COMPILE)gcc +CXX = $(CROSS_COMPILE)g++ +# Prefer real C++20; fall back to gnu++2a on older toolchains (e.g. the current +# gcc 8.3 tg5040 cross-compiler, which predates the -std=gnu++20 spelling). +CXXSTD := $(shell printf 'int main(){return 0;}' | $(CXX) -std=gnu++20 -x c++ - -o /dev/null >/dev/null 2>&1 && echo gnu++20 || echo gnu++2a) CFLAGS += $(OPT) -CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" -std=gnu99 +CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" +CXXFLAGS += $(CFLAGS) -std=$(CXXSTD) LDFLAGS += -lmsettings PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/msettings.h mkdir -p build/$(PLATFORM) - $(CC) $(SOURCE) -o $(PRODUCT) $(CFLAGS) $(LDFLAGS) + $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) + mv utils.o api.o config.o scaler.o platform.o build/$(PLATFORM) + $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) diff --git a/workspace/all/minput/makefile b/workspace/all/minput/makefile index cf532818a..7b22c866f 100644 --- a/workspace/all/minput/makefile +++ b/workspace/all/minput/makefile @@ -21,18 +21,29 @@ SDL?=SDL TARGET = minput INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ -SOURCE = $(TARGET).c ../common/utils.c ../common/api.c ../common/config.c ../common/scaler.c ../../$(PLATFORM)/platform/platform.c +# Shared common/ + platform stay C; the tool itself is C++20. Compile the C +# units to objects, then compile the .cpp and link everything through g++. +SOURCE = -c ../common/utils.c ../common/api.c ../common/config.c ../common/scaler.c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp +CXXSOURCE += build/$(PLATFORM)/utils.o build/$(PLATFORM)/api.o build/$(PLATFORM)/config.o build/$(PLATFORM)/scaler.o build/$(PLATFORM)/platform.o CC = $(CROSS_COMPILE)gcc +CXX = $(CROSS_COMPILE)g++ +# Prefer real C++20; fall back to gnu++2a on older toolchains (e.g. the current +# gcc 8.3 tg5040 cross-compiler, which predates the -std=gnu++20 spelling). +CXXSTD := $(shell printf 'int main(){return 0;}' | $(CXX) -std=gnu++20 -x c++ - -o /dev/null >/dev/null 2>&1 && echo gnu++20 || echo gnu++2a) CFLAGS += $(OPT) -CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" -std=gnu99 +CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" +CXXFLAGS += $(CFLAGS) -std=$(CXXSTD) LDFLAGS += -lmsettings PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/msettings.h mkdir -p build/$(PLATFORM) - $(CC) $(SOURCE) -o $(PRODUCT) $(CFLAGS) $(LDFLAGS) + $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) + mv utils.o api.o config.o scaler.o platform.o build/$(PLATFORM) + $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) diff --git a/workspace/all/minput/minput.c b/workspace/all/minput/minput.cpp similarity index 80% rename from workspace/all/minput/minput.c rename to workspace/all/minput/minput.cpp index 73671e97b..60e8f526e 100644 --- a/workspace/all/minput/minput.c +++ b/workspace/all/minput/minput.cpp @@ -1,13 +1,17 @@ -#include -#include +#include +#include #include -#include -#include +#include +// Project + libmsettings C headers declare C-linkage symbols defined in the +// still-C common/ and libmsettings translation units; include as extern "C". +extern "C" { +#include #include "sdl.h" #include "defines.h" #include "api.h" #include "utils.h" +} // full-scale SDL joystick axis magnitude, used to map raw axis values to on-screen nub travel #define STICK_AXIS_MAX 32767 @@ -37,13 +41,16 @@ static void blitButton(char* label, SDL_Surface* dst, int pressed, int x, int y, if (len<=2) { text = TTF_RenderUTF8_Blended(len==2?GFX_getFonts()->small:GFX_getFonts()->medium, label, text_color); GFX_blitAssetColor(ASSET_BUTTON, NULL, dst, &point, fill); - SDL_BlitSurface(text, NULL, dst, &(SDL_Rect){point.x+(SCALE1(BUTTON_SIZE)-text->w)/2,point.y+(SCALE1(BUTTON_SIZE)-text->h)/2}); + SDL_Rect text_dst = {point.x+(SCALE1(BUTTON_SIZE)-text->w)/2,point.y+(SCALE1(BUTTON_SIZE)-text->h)/2}; + SDL_BlitSurface(text, NULL, dst, &text_dst); } else { text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, label, text_color); w = w ? w : SCALE1(BUTTON_SIZE)/2+text->w; - GFX_blitPillColor(ASSET_BUTTON, dst, &(SDL_Rect){point.x,point.y,w,SCALE1(BUTTON_SIZE)}, fill, RGB_WHITE); - SDL_BlitSurface(text, NULL, dst, &(SDL_Rect){point.x+(w-text->w)/2,point.y+(SCALE1(BUTTON_SIZE)-text->h)/2,text->w,text->h}); + SDL_Rect pill = {point.x,point.y,w,SCALE1(BUTTON_SIZE)}; + GFX_blitPillColor(ASSET_BUTTON, dst, &pill, fill, RGB_WHITE); + SDL_Rect text_dst = {point.x+(w-text->w)/2,point.y+(SCALE1(BUTTON_SIZE)-text->h)/2,text->w,text->h}; + SDL_BlitSurface(text, NULL, dst, &text_dst); } SDL_FreeSurface(text); @@ -54,7 +61,8 @@ static void blitButton(char* label, SDL_Surface* dst, int pressed, int x, int y, static void fillCircle(SDL_Surface* dst, int cx, int cy, int radius, uint32_t color) { for (int dy = -radius; dy <= radius; dy++) { int dx = (int)(sqrt((double)radius*radius - (double)dy*dy) + 0.5); - SDL_FillRect(dst, &(SDL_Rect){cx-dx, cy+dy, dx*2, 1}, color); + SDL_Rect row = {cx-dx, cy+dy, dx*2, 1}; + SDL_FillRect(dst, &row, color); } } @@ -123,7 +131,7 @@ int main(int argc , char* argv[]) { if (has_L2) w += getButtonWidth("L2") + SCALE1(BUTTON_MARGIN); if (has_L4) w += getButtonWidth("L4") + SCALE1(BUTTON_MARGIN); if (!has_L2 && !has_L4) x += SCALE1(PILL_SIZE); - GFX_blitPillLight(ASSET_WHITE_PILL, screen, &(SDL_Rect){x, y, w}); + { SDL_Rect pill = {x, y, w}; GFX_blitPillLight(ASSET_WHITE_PILL, screen, &pill); } blitButton("L1", screen, PAD_isPressed(BTN_L1), x + SCALE1(BUTTON_MARGIN), y+SCALE1(BUTTON_MARGIN),0); if (has_L2) { @@ -152,7 +160,7 @@ int main(int argc , char* argv[]) { x = FIXED_WIDTH - w - SCALE1(BUTTON_MARGIN + PADDING); if (!has_R2 && !has_R4) x -= SCALE1(PILL_SIZE); - GFX_blitPillLight(ASSET_WHITE_PILL, screen, &(SDL_Rect){x,y,w}); + { SDL_Rect pill = {x,y,w}; GFX_blitPillLight(ASSET_WHITE_PILL, screen, &pill); } if(has_R4) { x+= SCALE1(BUTTON_MARGIN); @@ -173,24 +181,24 @@ int main(int argc , char* argv[]) { int y = oy + SCALE1(PILL_SIZE*2); int o = SCALE1(BUTTON_MARGIN); - SDL_FillRect(screen, &(SDL_Rect){x,y+SCALE1(PILL_SIZE/2),SCALE1(PILL_SIZE),SCALE1(PILL_SIZE*2)}, THEME_COLOR2); - GFX_blitPillLight(ASSET_WHITE_PILL, screen, &(SDL_Rect){x,y,0}); + { SDL_Rect r = {x,y+SCALE1(PILL_SIZE/2),SCALE1(PILL_SIZE),SCALE1(PILL_SIZE*2)}; SDL_FillRect(screen, &r, THEME_COLOR2); } + { SDL_Rect pill = {x,y,0}; GFX_blitPillLight(ASSET_WHITE_PILL, screen, &pill); } blitButton("U", screen, PAD_isPressed(BTN_DPAD_UP), x+o, y+o,0); y += SCALE1(PILL_SIZE*2); - GFX_blitPillLight(ASSET_WHITE_PILL, screen, &(SDL_Rect){x,y,0}); + { SDL_Rect pill = {x,y,0}; GFX_blitPillLight(ASSET_WHITE_PILL, screen, &pill); } blitButton("D", screen, PAD_isPressed(BTN_DPAD_DOWN), x+o, y+o,0); x -= SCALE1(PILL_SIZE); y -= SCALE1(PILL_SIZE); - SDL_FillRect(screen, &(SDL_Rect){x+SCALE1(PILL_SIZE/2),y,SCALE1(PILL_SIZE*2),SCALE1(PILL_SIZE)}, THEME_COLOR2); + { SDL_Rect r = {x+SCALE1(PILL_SIZE/2),y,SCALE1(PILL_SIZE*2),SCALE1(PILL_SIZE)}; SDL_FillRect(screen, &r, THEME_COLOR2); } - GFX_blitPillLight(ASSET_WHITE_PILL, screen, &(SDL_Rect){x,y,0}); + { SDL_Rect pill = {x,y,0}; GFX_blitPillLight(ASSET_WHITE_PILL, screen, &pill); } blitButton("L", screen, PAD_isPressed(BTN_DPAD_LEFT), x+o, y+o,0); x += SCALE1(PILL_SIZE*2); - GFX_blitPillLight(ASSET_WHITE_PILL, screen, &(SDL_Rect){x,y,0}); + { SDL_Rect pill = {x,y,0}; GFX_blitPillLight(ASSET_WHITE_PILL, screen, &pill); } blitButton("R", screen, PAD_isPressed(BTN_DPAD_RIGHT), x+o, y+o,0); } @@ -201,21 +209,21 @@ int main(int argc , char* argv[]) { int y = oy + SCALE1(PILL_SIZE*2); int o = SCALE1(BUTTON_MARGIN); - GFX_blitPillLight(ASSET_WHITE_PILL, screen, &(SDL_Rect){x,y,0}); + { SDL_Rect pill = {x,y,0}; GFX_blitPillLight(ASSET_WHITE_PILL, screen, &pill); } blitButton("X", screen, PAD_isPressed(BTN_X), x+o, y+o,0); y += SCALE1(PILL_SIZE*2); - GFX_blitPillLight(ASSET_WHITE_PILL, screen, &(SDL_Rect){x,y,0}); + { SDL_Rect pill = {x,y,0}; GFX_blitPillLight(ASSET_WHITE_PILL, screen, &pill); } blitButton("B", screen, PAD_isPressed(BTN_B), x+o, y+o,0); x -= SCALE1(PILL_SIZE); y -= SCALE1(PILL_SIZE); - GFX_blitPillLight(ASSET_WHITE_PILL, screen, &(SDL_Rect){x,y,0}); + { SDL_Rect pill = {x,y,0}; GFX_blitPillLight(ASSET_WHITE_PILL, screen, &pill); } blitButton("Y", screen, PAD_isPressed(BTN_Y), x+o, y+o,0); x += SCALE1(PILL_SIZE*2); - GFX_blitPillLight(ASSET_WHITE_PILL, screen, &(SDL_Rect){x,y,0}); + { SDL_Rect pill = {x,y,0}; GFX_blitPillLight(ASSET_WHITE_PILL, screen, &pill); } blitButton("A", screen, PAD_isPressed(BTN_A), x+o, y+o,0); } @@ -225,7 +233,7 @@ int main(int argc , char* argv[]) { int y = oy + SCALE1(PILL_SIZE); int w = SCALE1(42); - GFX_blitPillLight(ASSET_WHITE_PILL, screen, &(SDL_Rect){x,y,SCALE1(98)}); + { SDL_Rect pill = {x,y,SCALE1(98)}; GFX_blitPillLight(ASSET_WHITE_PILL, screen, &pill); } x += SCALE1(BUTTON_MARGIN); y += SCALE1(BUTTON_MARGIN); blitButton("VOL. -", screen, PAD_isPressed(BTN_MINUS), x, y, w); @@ -243,7 +251,7 @@ int main(int argc , char* argv[]) { int y = oy + SCALE1(PILL_SIZE * 3); int w = SCALE1(bw); - GFX_blitPillLight(ASSET_WHITE_PILL, screen, &(SDL_Rect){x,y,SCALE1(pw)}); + { SDL_Rect pill = {x,y,SCALE1(pw)}; GFX_blitPillLight(ASSET_WHITE_PILL, screen, &pill); } x += SCALE1(BUTTON_MARGIN); y += SCALE1(BUTTON_MARGIN); if (has_menu) { @@ -262,7 +270,7 @@ int main(int argc , char* argv[]) { int y = oy + SCALE1(PILL_SIZE * 5); int w = SCALE1(42); - GFX_blitPillLight(ASSET_WHITE_PILL, screen, &(SDL_Rect){x,y,SCALE1(130)}); + { SDL_Rect pill = {x,y,SCALE1(130)}; GFX_blitPillLight(ASSET_WHITE_PILL, screen, &pill); } x += SCALE1(BUTTON_MARGIN); y += SCALE1(BUTTON_MARGIN); blitButton("SELECT", screen, PAD_isPressed(BTN_SELECT), x, y, w); @@ -271,7 +279,8 @@ int main(int argc , char* argv[]) { x += w + SCALE1(BUTTON_MARGIN); SDL_Surface* text = TTF_RenderUTF8_Blended(GFX_getFonts()->tiny, "QUIT", uintToColour(THEME_COLOR6_255)); - SDL_BlitSurface(text, NULL, screen, &(SDL_Rect){x,y+(SCALE1(BUTTON_SIZE)-text->h)/2}); + SDL_Rect quit_dst = {x,y+(SCALE1(BUTTON_SIZE)-text->h)/2}; + SDL_BlitSurface(text, NULL, screen, &quit_dst); SDL_FreeSurface(text); } From 36e042e1fe49a484c582c1e1d9d21729fbf661de Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sun, 26 Jul 2026 14:11:43 +0200 Subject: [PATCH 66/77] refactor: convert libbatmondb and libgametimedb to C++20 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 3 (leaf libraries). These build .so's whose C ABI is consumed by the battery/batmon and gametime/gametimectl binaries, so the exports must stay C-linkable: batmondb.h / gametimedb.h gain #ifdef __cplusplus / extern "C" guards, which also keeps their existing consumers (that wrap the include in extern "C") working via harmless nested extern "C". - Convert .c -> .cpp; wrap the still-C common headers (defines/utils) in extern "C"; sqlite3.h and the guarded lib header stay outside. - Makefiles split into a gcc C compile (common utils/api/platform) + a g++ C++20 compile of the library unit, linked -shared through g++ -lstdc++. - The library compile keeps -Werror; the C++ unit adds -Wno-write-strings because the exports call common C helpers taking char* (exists/touch, sql string literals) — benign but an error under C++ -Werror. Modernized internals only (nullptr in batmondb, malloc cast in gametimedb); no ABI change. Verified: full `make build` clean on tg5040; both .so's rebuilt and all four consumer elfs relink. On-device, `gametimectl list` loads the new C++ libgametimedb.so and prints play activity correctly (exit 0). --- .../libbatmondb/{batmondb.c => batmondb.cpp} | 20 +++++++++++-------- workspace/all/libbatmondb/batmondb.h | 8 ++++++++ workspace/all/libbatmondb/makefile | 19 ++++++++++++++---- .../{gametimedb.c => gametimedb.cpp} | 16 +++++++++------ workspace/all/libgametimedb/gametimedb.h | 8 ++++++++ workspace/all/libgametimedb/makefile | 18 +++++++++++++---- 6 files changed, 67 insertions(+), 22 deletions(-) rename workspace/all/libbatmondb/{batmondb.c => batmondb.cpp} (88%) rename workspace/all/libgametimedb/{gametimedb.c => gametimedb.cpp} (98%) diff --git a/workspace/all/libbatmondb/batmondb.c b/workspace/all/libbatmondb/batmondb.cpp similarity index 88% rename from workspace/all/libbatmondb/batmondb.c rename to workspace/all/libbatmondb/batmondb.cpp index 68c5a5192..d375acbea 100644 --- a/workspace/all/libbatmondb/batmondb.c +++ b/workspace/all/libbatmondb/batmondb.cpp @@ -1,14 +1,18 @@ // heavily modified from the Onion original: https://github.com/OnionUI/Onion/tree/main/src/batmon -#include -#include +#include #include -#include -#include +#include +#include #include +#include + +// Project C headers declare C-linkage symbols defined in the still-C common/ +// translation units; include as extern "C". batmondb.h carries its own guard. +extern "C" { #include #include -#include +} #include "batmondb.h" @@ -22,12 +26,12 @@ sqlite3* open_battery_log_db(void) if (!db_exists) touch(BATTERY_LOG_FILE); - sqlite3 *bat_log_db = NULL; + sqlite3 *bat_log_db = nullptr; if (sqlite3_open(BATTERY_LOG_FILE, &bat_log_db) != SQLITE_OK) { printf("%s\n", sqlite3_errmsg(bat_log_db)); close_battery_log_db(bat_log_db); - return NULL; + return nullptr; } if (!db_exists) { @@ -49,7 +53,7 @@ sqlite3* open_battery_log_db(void) void close_battery_log_db(sqlite3* bat_log_db) { sqlite3_close(bat_log_db); - bat_log_db = NULL; + bat_log_db = nullptr; } int get_best_session_time(sqlite3* bat_log_db, const char* device) diff --git a/workspace/all/libbatmondb/batmondb.h b/workspace/all/libbatmondb/batmondb.h index 7483d7fdb..92eb63582 100644 --- a/workspace/all/libbatmondb/batmondb.h +++ b/workspace/all/libbatmondb/batmondb.h @@ -2,8 +2,16 @@ #ifndef __batmon_db_h__ #define __batmon_db_h__ +#ifdef __cplusplus +extern "C" { +#endif + sqlite3* open_battery_log_db(void); void close_battery_log_db(sqlite3* ctx); int get_best_session_time(sqlite3* ctx, const char* device); +#ifdef __cplusplus +} +#endif + #endif // __batmon_db_h__ \ No newline at end of file diff --git a/workspace/all/libbatmondb/makefile b/workspace/all/libbatmondb/makefile index 1fbf98c30..9637b2146 100644 --- a/workspace/all/libbatmondb/makefile +++ b/workspace/all/libbatmondb/makefile @@ -29,22 +29,33 @@ TARGET=batmondb .PHONY: clean CC = $(CROSS_COMPILE)gcc +CXX = $(CROSS_COMPILE)g++ +# Prefer real C++20; fall back to gnu++2a on older toolchains (e.g. the current +# gcc 8.3 tg5040 cross-compiler, which predates the -std=gnu++20 spelling). +CXXSTD := $(shell printf 'int main(){return 0;}' | $(CXX) -std=gnu++20 -x c++ - -o /dev/null >/dev/null 2>&1 && echo gnu++20 || echo gnu++2a) SYSROOT := $(shell $(CC) --print-sysroot) INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ -SOURCE = $(TARGET).c ../common/utils.c ../common/api.c ../../$(PLATFORM)/platform/platform.c +# The shared common/ + platform units stay C; the library itself is C++20. +CSOURCE = ../common/utils.c ../common/api.c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp CFLAGS += $(OPT) CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" -std=gnu99 +# -Wno-write-strings: the exported functions call common C helpers that take +# char* (exists/touch); passing string literals is benign but would error under +# C++ -Werror. +CXXFLAGS = $(OPT) $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" -std=$(CXXSTD) -Wno-write-strings LDFLAGS += -s -lsqlite3 PRODUCT= build/$(PLATFORM)/lib$(TARGET).so -build: +build: mkdir -p build/$(PLATFORM) - $(CC) -c -Werror -fpic $(SOURCE) -Wl,--no-as-needed $(LDFLAGS) $(CFLAGS) - $(CC) -shared -o $(PRODUCT) "$(TARGET).o" "utils.o" $(LDFLAGS) + $(CC) -c -Werror -fpic $(CSOURCE) -Wl,--no-as-needed $(LDFLAGS) $(CFLAGS) + $(CXX) -c -Werror -fpic $(CXXSOURCE) $(CXXFLAGS) + $(CXX) -shared -o $(PRODUCT) "$(TARGET).o" "utils.o" $(LDFLAGS) -lstdc++ mkdir -p "$(PREFIX_LOCAL)/include" mkdir -p "$(PREFIX_LOCAL)/lib" cp "$(TARGET).h" "$(PREFIX_LOCAL)/include" diff --git a/workspace/all/libgametimedb/gametimedb.c b/workspace/all/libgametimedb/gametimedb.cpp similarity index 98% rename from workspace/all/libgametimedb/gametimedb.c rename to workspace/all/libgametimedb/gametimedb.cpp index afbb0469d..3648d1014 100644 --- a/workspace/all/libgametimedb/gametimedb.c +++ b/workspace/all/libgametimedb/gametimedb.cpp @@ -1,14 +1,18 @@ // heavily modified from the Onion original: https://github.com/OnionUI/Onion/blob/main/src/playActivity/playActivityDB.h -#include -#include +#include #include -#include -#include +#include +#include #include +#include + +// Project C headers declare C-linkage symbols defined in the still-C common/ +// translation units; include as extern "C". gametimedb.h carries its own guard. +extern "C" { #include #include -#include +} #include "gametimedb.h" @@ -184,7 +188,7 @@ PlayActivities *play_activity_find_all(void) rom->name = strdup((const char *)sqlite3_column_text(stmt, 2)); if (sqlite3_column_text(stmt, 3) != NULL) { rom->file_path = strdup((const char *)sqlite3_column_text(stmt, 3)); - rom->image_path = malloc(STR_MAX * sizeof(char)); + rom->image_path = (char *)malloc(STR_MAX * sizeof(char)); memset(rom->image_path, 0, STR_MAX); get_rom_image_path(rom->file_path, rom->image_path); } diff --git a/workspace/all/libgametimedb/gametimedb.h b/workspace/all/libgametimedb/gametimedb.h index 4c0e4eb1d..c5b00ae07 100644 --- a/workspace/all/libgametimedb/gametimedb.h +++ b/workspace/all/libgametimedb/gametimedb.h @@ -2,6 +2,10 @@ #ifndef __gametime_db_h__ #define __gametime_db_h__ +#ifdef __cplusplus +extern "C" { +#endif + typedef struct ROM ROM; typedef struct PlayActivity PlayActivity; typedef struct PlayActivities PlayActivities; @@ -42,4 +46,8 @@ void play_activity_stop(char *rom_file_path); void play_activity_stop_all(void); void play_activity_list_all(void); +#ifdef __cplusplus +} +#endif + #endif // __gametime_db_h__ \ No newline at end of file diff --git a/workspace/all/libgametimedb/makefile b/workspace/all/libgametimedb/makefile index 1b1c941ac..39d1f4dd6 100644 --- a/workspace/all/libgametimedb/makefile +++ b/workspace/all/libgametimedb/makefile @@ -29,22 +29,32 @@ TARGET=gametimedb .PHONY: clean CC = $(CROSS_COMPILE)gcc +CXX = $(CROSS_COMPILE)g++ +# Prefer real C++20; fall back to gnu++2a on older toolchains (e.g. the current +# gcc 8.3 tg5040 cross-compiler, which predates the -std=gnu++20 spelling). +CXXSTD := $(shell printf 'int main(){return 0;}' | $(CXX) -std=gnu++20 -x c++ - -o /dev/null >/dev/null 2>&1 && echo gnu++20 || echo gnu++2a) SYSROOT := $(shell $(CC) --print-sysroot) INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ -SOURCE = $(TARGET).c ../common/utils.c ../common/api.c ../../$(PLATFORM)/platform/platform.c +# The shared common/ + platform units stay C; the library itself is C++20. +CSOURCE = ../common/utils.c ../common/api.c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp CFLAGS += $(OPT) CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" -std=gnu99 +# -Wno-write-strings: the exported functions call common C helpers that take +# char*; passing string literals is benign but would error under C++ -Werror. +CXXFLAGS = $(OPT) $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" -std=$(CXXSTD) -Wno-write-strings LDFLAGS += -s -lsqlite3 PRODUCT= build/$(PLATFORM)/lib$(TARGET).so -build: +build: mkdir -p build/$(PLATFORM) - $(CC) -c -Werror -fpic $(SOURCE) -Wl,--no-as-needed $(LDFLAGS) $(CFLAGS) - $(CC) -shared -o $(PRODUCT) "$(TARGET).o" "utils.o" $(LDFLAGS) + $(CC) -c -Werror -fpic $(CSOURCE) -Wl,--no-as-needed $(LDFLAGS) $(CFLAGS) + $(CXX) -c -Werror -fpic $(CXXSOURCE) $(CXXFLAGS) + $(CXX) -shared -o $(PRODUCT) "$(TARGET).o" "utils.o" $(LDFLAGS) -lstdc++ cp "$(TARGET).h" "$(PREFIX_LOCAL)/include" cp $(PRODUCT) "$(PREFIX_LOCAL)/lib" From 1d2719b6011c4784ade7f1a7c40cfbb867ee4ce7 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sun, 26 Jul 2026 14:49:32 +0200 Subject: [PATCH 67/77] refactor: convert common/ ra_offline, ra_sync, ra_event_queue to C++20 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 4 (shared common/ core), first sub-batch — the lowest-fan-out RA helpers, consumed only by minarch and/or settings. Both consumers already link via g++, so this just moves the units from each makefile's C-compiled list to the C++-compiled list. The common files keep C linkage (platform.c is still C and calls into them): ra_sync.h / ra_event_queue.h were already extern "C"-guarded; added guards to ra_offline.h. Each .cpp wraps the still-C project headers it includes in extern "C" (ra_integration.cpp pattern). C++ fixes required by the stricter compiler: - ra_offline.cpp: two functions used `goto` to cleanup labels across local initializations; hoisted the crossed declarations above the jumps (the labels don't use those vars). Same class as the earlier ma_saves fix. - ra_event_queue.cpp: it forward-declares LOG_note locally (to avoid api.h's transitive deps); marked that declaration extern "C" so it resolves to api.c's C symbol instead of a mangled C++ one. Verified: full `make build` clean on tg5040 (g++ 8.3) and desktop (host g++); minarch + settings relink on both. --- .../{ra_event_queue.c => ra_event_queue.cpp} | 2 +- .../common/{ra_offline.c => ra_offline.cpp} | 47 ++++++++++++------- workspace/all/common/ra_offline.h | 8 ++++ .../all/common/{ra_sync.c => ra_sync.cpp} | 10 +++- workspace/all/minarch/makefile | 4 +- workspace/all/settings/makefile | 8 ++-- 6 files changed, 54 insertions(+), 25 deletions(-) rename workspace/all/common/{ra_event_queue.c => ra_event_queue.cpp} (97%) rename workspace/all/common/{ra_offline.c => ra_offline.cpp} (98%) rename workspace/all/common/{ra_sync.c => ra_sync.cpp} (97%) diff --git a/workspace/all/common/ra_event_queue.c b/workspace/all/common/ra_event_queue.cpp similarity index 97% rename from workspace/all/common/ra_event_queue.c rename to workspace/all/common/ra_event_queue.cpp index 7a612ef13..b31f84dfe 100644 --- a/workspace/all/common/ra_event_queue.c +++ b/workspace/all/common/ra_event_queue.cpp @@ -18,7 +18,7 @@ * deps) so declare LOG_note and define the macros we need locally. * Values must stay in sync with the LOG_* enum in api.h. */ enum { LOG_DEBUG = 0, LOG_INFO = 1, LOG_WARN = 2 }; -void LOG_note(int level, const char* fmt, ...); +extern "C" void LOG_note(int level, const char* fmt, ...); // C symbol defined in api.c #define LOG_debug(fmt, ...) LOG_note(LOG_DEBUG, fmt, ##__VA_ARGS__) #define LOG_info(fmt, ...) LOG_note(LOG_INFO, fmt, ##__VA_ARGS__) #define LOG_warn(fmt, ...) LOG_note(LOG_WARN, fmt, ##__VA_ARGS__) diff --git a/workspace/all/common/ra_offline.c b/workspace/all/common/ra_offline.cpp similarity index 98% rename from workspace/all/common/ra_offline.c rename to workspace/all/common/ra_offline.cpp index 2d9374ea7..29565c3dd 100644 --- a/workspace/all/common/ra_offline.c +++ b/workspace/all/common/ra_offline.cpp @@ -1,10 +1,15 @@ #define RA_LOG_PREFIX "RA_OFFLINE" -#include "ra_log.h" +// Project C headers declare C-linkage symbols; include them as extern "C" so +// this C++ unit links against the unmangled names and its own exports keep C +// linkage for the still-C platform.c. (Same pattern as ra_integration.cpp.) +extern "C" { +#include "ra_log.h" #include "ra_offline.h" #include "ra_util.h" #include "defines.h" #include "api.h" +} #include #include @@ -436,6 +441,12 @@ static bool patch_startsession_with_ledger(char* body, size_t body_len, /* Get pending unlocks from ledger, pre-filtered by game hash */ RA_PendingUnlock* pending = NULL; uint32_t pending_count = 0; + /* Hoisted above the `goto passthrough` jumps below: C++ forbids a goto that + * crosses a variable's initialization (the label doesn't use these). */ + char* current_body = body; + size_t current_len = body_len; + bool body_replaced = false; + uint32_t total_injected = 0; if (!RA_Offline_ledgerGetPendingByGameHash(game_hash, &pending, &pending_count)) goto passthrough; @@ -448,10 +459,6 @@ static bool patch_startsession_with_ledger(char* body, size_t body_len, * in both modes, preventing it from re-awarding them via its own * server call (which would lack &o= and record the wrong timestamp). */ - char* current_body = body; - size_t current_len = body_len; - bool body_replaced = false; - uint32_t total_injected = 0; /* Pass 1: Inject into "Unlocks" (softcore) */ { @@ -1444,26 +1451,38 @@ void RA_Offline_patchStartsessionCacheWithUnlock(const char* game_hash, /* Read existing cache file */ char* body = NULL; size_t body_len = 0; + /* Hoisted above the `goto done` jumps below: C++ forbids a goto that crosses + * a variable's initialization (the label only unlocks the mutex). */ + const char* unlocks_key = "\"Unlocks\""; + char* unlocks_pos; + char* arr_start; + char* arr_end; + bool already_in_softcore = false; + bool already_in_hardcore = false; + const char* hc_key = "\"HardcoreUnlocks\""; + char* hc_pos; + char* current_body; + size_t current_len; + bool body_replaced = false; if (!cache_read_file(path, &body, &body_len)) { /* No cached startsession for this game, or corrupt — nothing to patch */ goto done; } /* Find the "Unlocks" array */ - const char* unlocks_key = "\"Unlocks\""; - char* unlocks_pos = strstr(body, unlocks_key); + unlocks_pos = strstr(body, unlocks_key); if (!unlocks_pos) { free(body); goto done; } - char* arr_start = strchr(unlocks_pos + strlen(unlocks_key), '['); + arr_start = strchr(unlocks_pos + strlen(unlocks_key), '['); if (!arr_start) { free(body); goto done; } - char* arr_end = strchr(arr_start, ']'); + arr_end = strchr(arr_start, ']'); if (!arr_end) { free(body); goto done; @@ -1472,7 +1491,6 @@ void RA_Offline_patchStartsessionCacheWithUnlock(const char* game_hash, /* Check if this achievement ID is already in the Unlocks array */ char id_pattern[32]; snprintf(id_pattern, sizeof(id_pattern), "\"ID\":%u", achievement_id); - bool already_in_softcore = false; for (char* p = arr_start; p < arr_end; p++) { if (strncmp(p, id_pattern, strlen(id_pattern)) == 0) { already_in_softcore = true; @@ -1481,9 +1499,7 @@ void RA_Offline_patchStartsessionCacheWithUnlock(const char* game_hash, } /* Also check HardcoreUnlocks array */ - bool already_in_hardcore = false; - const char* hc_key = "\"HardcoreUnlocks\""; - char* hc_pos = strstr(body, hc_key); + hc_pos = strstr(body, hc_key); if (hc_pos) { char* hc_arr_start = strchr(hc_pos + strlen(hc_key), '['); if (hc_arr_start) { @@ -1519,9 +1535,8 @@ void RA_Offline_patchStartsessionCacheWithUnlock(const char* game_hash, * but if we pass NULL as game_hash it accepts all entries). */ single.game_hash[0] = '\0'; - char* current_body = body; - size_t current_len = body_len; - bool body_replaced = false; + current_body = body; + current_len = body_len; /* Inject into "Unlocks" if not already present */ if (!already_in_softcore) { diff --git a/workspace/all/common/ra_offline.h b/workspace/all/common/ra_offline.h index ba0c333be..1ac0991c6 100644 --- a/workspace/all/common/ra_offline.h +++ b/workspace/all/common/ra_offline.h @@ -5,6 +5,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /** * Offline RetroAchievements support for NextUI. * @@ -312,4 +316,8 @@ void RA_Offline_patchStartsessionCacheWithUnlock(const char* game_hash, uint32_t achievement_id, uint32_t timestamp); +#ifdef __cplusplus +} +#endif + #endif /* RA_OFFLINE_H */ diff --git a/workspace/all/common/ra_sync.c b/workspace/all/common/ra_sync.cpp similarity index 97% rename from workspace/all/common/ra_sync.c rename to workspace/all/common/ra_sync.cpp index 1665f5af2..715aba3dd 100644 --- a/workspace/all/common/ra_sync.c +++ b/workspace/all/common/ra_sync.cpp @@ -10,16 +10,22 @@ */ #define RA_LOG_PREFIX "RA_SYNC" -#include "ra_log.h" +// Project C headers declare C-linkage symbols (LOG_*, config, http, api, the RA +// helpers, …). Include them as extern "C" so this C++ unit links against the +// unmangled names — and so this unit's own exports keep C linkage for the +// still-C platform.c and any C consumers. (Same pattern as ra_integration.cpp.) +#define RA_UTIL_NEED_SDL +extern "C" { +#include "ra_log.h" #include "ra_sync.h" #include "ra_offline.h" -#define RA_UTIL_NEED_SDL #include "ra_util.h" #include "http.h" #include "config.h" #include "defines.h" #include "api.h" +} #include #include diff --git a/workspace/all/minarch/makefile b/workspace/all/minarch/makefile index 230d32070..1c7b81487 100644 --- a/workspace/all/minarch/makefile +++ b/workspace/all/minarch/makefile @@ -38,8 +38,8 @@ ifneq (,$(filter $(PLATFORM),tg5040 tg5050 my355 desktop)) # RA source files (shared common/ helpers stay C; the two minarch-local RA units # are C++). ra_integration sits on the rcheevos C callback boundary — kept # mechanical, no throwing constructs on that path. -CSOURCE += ../common/http.c ../common/ra_badges.c ../common/ra_offline.c ../common/ra_sync.c ../common/ra_event_queue.c -CXXSOURCE += ra_integration.cpp chd_reader.cpp +CSOURCE += ../common/http.c ../common/ra_badges.c +CXXSOURCE += ra_integration.cpp chd_reader.cpp ../common/ra_offline.cpp ../common/ra_sync.cpp ../common/ra_event_queue.cpp endif CC = $(CROSS_COMPILE)gcc diff --git a/workspace/all/settings/makefile b/workspace/all/settings/makefile index c17861c0e..468312b16 100644 --- a/workspace/all/settings/makefile +++ b/workspace/all/settings/makefile @@ -21,9 +21,9 @@ SDL?=SDL TARGET = settings INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ -SOURCE = -c ../common/utils.c ../common/api.c ../common/config.c ../common/scaler.c ../common/http.c ../common/ra_auth.c ../common/ra_offline.c ../common/ra_sync.c ../common/ra_event_queue.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = ../common/palette.cpp $(TARGET).cpp menu.cpp colorpickermenu.cpp palettemenu.cpp fnbuttonmenu.cpp wifimenu.cpp btmenu.cpp keyboardprompt.cpp -CXXSOURCE += build/$(PLATFORM)/utils.o build/$(PLATFORM)/api.o build/$(PLATFORM)/config.o build/$(PLATFORM)/scaler.o build/$(PLATFORM)/http.o build/$(PLATFORM)/ra_auth.o build/$(PLATFORM)/ra_offline.o build/$(PLATFORM)/ra_sync.o build/$(PLATFORM)/ra_event_queue.o build/$(PLATFORM)/platform.o +SOURCE = -c ../common/utils.c ../common/api.c ../common/config.c ../common/scaler.c ../common/http.c ../common/ra_auth.c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = ../common/palette.cpp ../common/ra_offline.cpp ../common/ra_sync.cpp ../common/ra_event_queue.cpp $(TARGET).cpp menu.cpp colorpickermenu.cpp palettemenu.cpp fnbuttonmenu.cpp wifimenu.cpp btmenu.cpp keyboardprompt.cpp +CXXSOURCE += build/$(PLATFORM)/utils.o build/$(PLATFORM)/api.o build/$(PLATFORM)/config.o build/$(PLATFORM)/scaler.o build/$(PLATFORM)/http.o build/$(PLATFORM)/ra_auth.o build/$(PLATFORM)/platform.o CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ @@ -53,7 +53,7 @@ PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/msettings.h mkdir -p build/$(PLATFORM) $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) - mv utils.o api.o config.o scaler.o http.o ra_auth.o ra_offline.o ra_sync.o ra_event_queue.o platform.o build/$(PLATFORM) + mv utils.o api.o config.o scaler.o http.o ra_auth.o platform.o build/$(PLATFORM) $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) From b75052f782b9f1ee4871cf7177179b6c2e8d28a1 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sun, 26 Jul 2026 14:56:50 +0200 Subject: [PATCH 68/77] refactor: convert common/ ra_badges, notification, ra_auth, http to C++20 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 4 (shared common/ core), second sub-batch — the rest of the low-fan-out RA/http/notification helpers (consumed only by minarch and/or settings). Added extern "C" guards to their headers so exports stay C-linkable for the still-C platform.c; each .cpp wraps the still-C project headers it includes in extern "C". Moved the units to the C++ side of the minarch + settings makefiles. Code fixes surfaced by C++: - http.cpp: 9 malloc/calloc/realloc results explicitly cast to their target type. - ra_auth.cpp: calloc result cast. - notification.cpp: the one &(SDL_Rect){...} compound literal -> a named local. Verified: full `make build` clean on tg5040 (g++ 8.3) and desktop (host g++); minarch + settings relink on both. Remaining in Phase 4: the four high-fan-out core files (utils, scaler, config, api), each compiled into 11-14 binaries. --- workspace/all/common/{http.c => http.cpp} | 25 ++++++++++++------- workspace/all/common/http.h | 8 ++++++ .../{notification.c => notification.cpp} | 8 +++++- workspace/all/common/notification.h | 8 ++++++ .../all/common/{ra_auth.c => ra_auth.cpp} | 7 +++++- workspace/all/common/ra_auth.h | 8 ++++++ .../all/common/{ra_badges.c => ra_badges.cpp} | 7 +++++- workspace/all/common/ra_badges.h | 8 ++++++ workspace/all/minarch/makefile | 7 +++--- workspace/all/settings/makefile | 8 +++--- 10 files changed, 74 insertions(+), 20 deletions(-) rename workspace/all/common/{http.c => http.cpp} (91%) rename workspace/all/common/{notification.c => notification.cpp} (98%) rename workspace/all/common/{ra_auth.c => ra_auth.cpp} (96%) rename workspace/all/common/{ra_badges.c => ra_badges.cpp} (98%) diff --git a/workspace/all/common/http.c b/workspace/all/common/http.cpp similarity index 91% rename from workspace/all/common/http.c rename to workspace/all/common/http.cpp index 16397f0b9..515f39650 100644 --- a/workspace/all/common/http.c +++ b/workspace/all/common/http.cpp @@ -1,5 +1,10 @@ +// Project C headers declare C-linkage symbols; include as extern "C" so this +// C++ unit links against the unmangled names and its own exports keep C linkage +// for the still-C platform.c. http.h carries its own guard. +extern "C" { #include "http.h" #include "defines.h" +} #include #include @@ -10,7 +15,9 @@ // SDL is used here only for threading (SDL_CreateThread/SDL_DetachThread) // to run HTTP requests asynchronously without blocking the main loop. // HTTP communication itself uses curl via popen(). +extern "C" { #include "sdl.h" +} // Build version info (defined in makefile) #ifndef BUILD_HASH @@ -33,7 +40,7 @@ typedef struct { static int HTTPBuffer_init(HTTPBuffer* buf) { buf->capacity = 4096; - buf->data = malloc(buf->capacity); + buf->data = (char*)malloc(buf->capacity); if (!buf->data) return -1; buf->data[0] = '\0'; buf->size = 0; @@ -49,7 +56,7 @@ static int HTTPBuffer_append(HTTPBuffer* buf, const char* data, size_t len) { if (new_cap > HTTP_MAX_RESPONSE_SIZE) { return -1; // Too large } - char* new_data = realloc(buf->data, new_cap); + char* new_data = (char*)realloc(buf->data, new_cap); if (!new_data) return -1; buf->data = new_data; buf->capacity = new_cap; @@ -81,7 +88,7 @@ static char* shell_escape(const char* str) { } // Allocate: original + 3 chars per quote ('"'"') + 2 for surrounding quotes + 1 for null - char* escaped = malloc(len + quotes * 3 + 3); + char* escaped = (char*)malloc(len + quotes * 3 + 3); if (!escaped) return NULL; char* p = escaped; @@ -106,7 +113,7 @@ static char* shell_escape(const char* str) { // Execute curl and capture output static HTTP_Response* execute_curl(const char* url, const char* post_data, const char* content_type) { - HTTP_Response* response = calloc(1, sizeof(HTTP_Response)); + HTTP_Response* response = (HTTP_Response*)calloc(1, sizeof(HTTP_Response)); if (!response) return NULL; response->http_status = -1; @@ -287,10 +294,10 @@ static int async_request_thread(void* data) { static void start_async_request(const char* url, const char* post_data, const char* content_type, HTTP_Callback callback, void* userdata) { - AsyncRequestData* req = calloc(1, sizeof(AsyncRequestData)); + AsyncRequestData* req = (AsyncRequestData*)calloc(1, sizeof(AsyncRequestData)); if (!req) { // Callback with error - HTTP_Response* response = calloc(1, sizeof(HTTP_Response)); + HTTP_Response* response = (HTTP_Response*)calloc(1, sizeof(HTTP_Response)); if (response) { response->http_status = -1; response->error = strdup("Memory allocation failed"); @@ -309,7 +316,7 @@ static void start_async_request(const char* url, const char* post_data, free(req->post_data); free(req->content_type); free(req); - HTTP_Response* response = calloc(1, sizeof(HTTP_Response)); + HTTP_Response* response = (HTTP_Response*)calloc(1, sizeof(HTTP_Response)); if (response) { response->http_status = -1; response->error = strdup("Memory allocation failed"); @@ -325,7 +332,7 @@ static void start_async_request(const char* url, const char* post_data, free(req->post_data); free(req->content_type); free(req); - HTTP_Response* response = calloc(1, sizeof(HTTP_Response)); + HTTP_Response* response = (HTTP_Response*)calloc(1, sizeof(HTTP_Response)); if (response) { response->http_status = -1; response->error = strdup("Failed to create thread"); @@ -371,7 +378,7 @@ char* HTTP_urlEncode(const char* str) { // Count required size (worst case: every char becomes %XX) size_t len = strlen(str); - char* encoded = malloc(len * 3 + 1); + char* encoded = (char*)malloc(len * 3 + 1); if (!encoded) return NULL; char* p = encoded; diff --git a/workspace/all/common/http.h b/workspace/all/common/http.h index 81aef77c2..f0b6ab0a4 100644 --- a/workspace/all/common/http.h +++ b/workspace/all/common/http.h @@ -3,6 +3,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /** * HTTP client wrapper for NextUI * @@ -89,4 +93,8 @@ char* HTTP_urlEncode(const char* str); */ void HTTP_getUserAgent(char* buffer, size_t buffer_size); +#ifdef __cplusplus +} +#endif + #endif // __HTTP_H__ diff --git a/workspace/all/common/notification.c b/workspace/all/common/notification.cpp similarity index 98% rename from workspace/all/common/notification.c rename to workspace/all/common/notification.cpp index 34afaa65a..2c8d5a085 100644 --- a/workspace/all/common/notification.c +++ b/workspace/all/common/notification.cpp @@ -1,7 +1,12 @@ +// Project C headers declare C-linkage symbols; include as extern "C" so this +// C++ unit links against the unmangled names and its own exports keep C linkage +// for the still-C platform.c. notification.h carries its own guard. +extern "C" { #include "notification.h" #include "defines.h" #include "api.h" #include "config.h" +} #include #include @@ -397,8 +402,9 @@ static void render_notification_pill(Notification* n, int x, int y, SDL_Color te if (n->type == NOTIFICATION_OFFLINE_ACHIEVEMENT) { int wifi_size = SCALE1(12); int wifi_y = notif_padding_y + (text_h - wifi_size) / 2; + SDL_Rect wifi_dst = {content_x, wifi_y}; GFX_blitAssetColor(ASSET_WIFI_OFF, NULL, notif_surface, - &(SDL_Rect){content_x, wifi_y}, THEME_COLOR1_255); + &wifi_dst, THEME_COLOR1_255); content_x += wifi_size + notif_icon_gap; } diff --git a/workspace/all/common/notification.h b/workspace/all/common/notification.h index eeb3608fc..40c877281 100644 --- a/workspace/all/common/notification.h +++ b/workspace/all/common/notification.h @@ -5,6 +5,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /////////////////////////////// // Notification System // Toast-style notifications for save states, achievements, etc. @@ -157,4 +161,8 @@ void Notification_setProgressIndicatorPersistent(bool persistent); */ bool Notification_hasProgressIndicator(void); +#ifdef __cplusplus +} +#endif + #endif // __NOTIFICATION_H__ diff --git a/workspace/all/common/ra_auth.c b/workspace/all/common/ra_auth.cpp similarity index 96% rename from workspace/all/common/ra_auth.c rename to workspace/all/common/ra_auth.cpp index 1f3587aa5..80fb792a3 100644 --- a/workspace/all/common/ra_auth.c +++ b/workspace/all/common/ra_auth.cpp @@ -1,8 +1,13 @@ +// Project C headers declare C-linkage symbols; include as extern "C" so this +// C++ unit links against the unmangled names and its own exports keep C linkage +// for the still-C platform.c. ra_auth.h / http.h carry their own guards. +extern "C" { #include "ra_auth.h" #include "ra_util.h" #include "http.h" #include "config.h" #include "defines.h" +} #include #include @@ -138,7 +143,7 @@ void RA_authenticate(const char* username, const char* password, } // Create async context - RA_AsyncAuthContext* ctx = calloc(1, sizeof(RA_AsyncAuthContext)); + RA_AsyncAuthContext* ctx = (RA_AsyncAuthContext*)calloc(1, sizeof(RA_AsyncAuthContext)); if (!ctx) { RA_AuthResponse response = {0}; response.result = RA_AUTH_ERROR_UNKNOWN; diff --git a/workspace/all/common/ra_auth.h b/workspace/all/common/ra_auth.h index 90ae88267..e88545791 100644 --- a/workspace/all/common/ra_auth.h +++ b/workspace/all/common/ra_auth.h @@ -1,6 +1,10 @@ #ifndef __RA_AUTH_H__ #define __RA_AUTH_H__ +#ifdef __cplusplus +extern "C" { +#endif + // Handles RA login outside of rc_client for use before rc_client initialization. // See: https://github.com/RetroAchievements/rcheevos/wiki/rc_client-integration#login @@ -56,4 +60,8 @@ void RA_authenticate(const char* username, const char* password, RA_AuthResult RA_authenticateSync(const char* username, const char* password, RA_AuthResponse* response); +#ifdef __cplusplus +} +#endif + #endif // __RA_AUTH_H__ diff --git a/workspace/all/common/ra_badges.c b/workspace/all/common/ra_badges.cpp similarity index 98% rename from workspace/all/common/ra_badges.c rename to workspace/all/common/ra_badges.cpp index 24039645a..c96b5eee7 100644 --- a/workspace/all/common/ra_badges.c +++ b/workspace/all/common/ra_badges.cpp @@ -1,6 +1,10 @@ #define RA_LOG_PREFIX "RA_BADGES" -#include "ra_log.h" +// Project C headers declare C-linkage symbols; include as extern "C" so this +// C++ unit links against the unmangled names and its own exports keep C linkage +// for the still-C platform.c. (Same pattern as ra_integration.cpp.) +extern "C" { +#include "ra_log.h" #include "ra_badges.h" #include "ra_util.h" #include "http.h" @@ -8,6 +12,7 @@ #include "api.h" #include "sdl.h" #include "notification.h" +} #include #include diff --git a/workspace/all/common/ra_badges.h b/workspace/all/common/ra_badges.h index ba93d55a8..f4b9d0ef1 100644 --- a/workspace/all/common/ra_badges.h +++ b/workspace/all/common/ra_badges.h @@ -5,6 +5,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + // Implements the badge download/caching that the integration guide leaves to the emulator. // See: https://github.com/RetroAchievements/rcheevos/wiki/rc_client-integration#showing-the-game-placard @@ -110,4 +114,8 @@ void RA_Badges_getCachePath(const char* badge_name, bool locked, char* buffer, s */ void RA_Badges_getUrl(const char* badge_name, bool locked, char* buffer, size_t buffer_size); +#ifdef __cplusplus +} +#endif + #endif // __RA_BADGES_H__ diff --git a/workspace/all/minarch/makefile b/workspace/all/minarch/makefile index 1c7b81487..33877815a 100644 --- a/workspace/all/minarch/makefile +++ b/workspace/all/minarch/makefile @@ -27,8 +27,8 @@ INCDIR = -I. -I./libretro-common/include/ -I../common/ -I../../$(PLATFORM)/platf # C++ files compile as C++; everything links through g++ so the two can mix # as modules are migrated to C++ incrementally. CSOURCE = ../common/scaler.c ../common/utils.c ../common/config.c ../common/api.c \ - ../common/notification.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = $(TARGET).cpp \ + ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp ../common/notification.cpp \ ma_audio.cpp ma_input.cpp ma_runframe.cpp ma_cheats.cpp ma_core.cpp \ ma_rewind.cpp ma_saves.cpp ma_game.cpp ma_environment.cpp \ ma_options.cpp ma_video.cpp ma_menu.cpp ma_frontend_opts.cpp ma_config.cpp @@ -38,8 +38,7 @@ ifneq (,$(filter $(PLATFORM),tg5040 tg5050 my355 desktop)) # RA source files (shared common/ helpers stay C; the two minarch-local RA units # are C++). ra_integration sits on the rcheevos C callback boundary — kept # mechanical, no throwing constructs on that path. -CSOURCE += ../common/http.c ../common/ra_badges.c -CXXSOURCE += ra_integration.cpp chd_reader.cpp ../common/ra_offline.cpp ../common/ra_sync.cpp ../common/ra_event_queue.cpp +CXXSOURCE += ra_integration.cpp chd_reader.cpp ../common/ra_offline.cpp ../common/ra_sync.cpp ../common/ra_event_queue.cpp ../common/http.cpp ../common/ra_badges.cpp endif CC = $(CROSS_COMPILE)gcc diff --git a/workspace/all/settings/makefile b/workspace/all/settings/makefile index 468312b16..9485b0034 100644 --- a/workspace/all/settings/makefile +++ b/workspace/all/settings/makefile @@ -21,9 +21,9 @@ SDL?=SDL TARGET = settings INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ -SOURCE = -c ../common/utils.c ../common/api.c ../common/config.c ../common/scaler.c ../common/http.c ../common/ra_auth.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = ../common/palette.cpp ../common/ra_offline.cpp ../common/ra_sync.cpp ../common/ra_event_queue.cpp $(TARGET).cpp menu.cpp colorpickermenu.cpp palettemenu.cpp fnbuttonmenu.cpp wifimenu.cpp btmenu.cpp keyboardprompt.cpp -CXXSOURCE += build/$(PLATFORM)/utils.o build/$(PLATFORM)/api.o build/$(PLATFORM)/config.o build/$(PLATFORM)/scaler.o build/$(PLATFORM)/http.o build/$(PLATFORM)/ra_auth.o build/$(PLATFORM)/platform.o +SOURCE = -c ../common/utils.c ../common/api.c ../common/config.c ../common/scaler.c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = ../common/palette.cpp ../common/ra_offline.cpp ../common/ra_sync.cpp ../common/ra_event_queue.cpp ../common/http.cpp ../common/ra_auth.cpp $(TARGET).cpp menu.cpp colorpickermenu.cpp palettemenu.cpp fnbuttonmenu.cpp wifimenu.cpp btmenu.cpp keyboardprompt.cpp +CXXSOURCE += build/$(PLATFORM)/utils.o build/$(PLATFORM)/api.o build/$(PLATFORM)/config.o build/$(PLATFORM)/scaler.o build/$(PLATFORM)/platform.o CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ @@ -53,7 +53,7 @@ PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/msettings.h mkdir -p build/$(PLATFORM) $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) - mv utils.o api.o config.o scaler.o http.o ra_auth.o platform.o build/$(PLATFORM) + mv utils.o api.o config.o scaler.o platform.o build/$(PLATFORM) $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) From 0a81324603f3896525321a7f97cf75f28d833e51 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sun, 26 Jul 2026 15:24:03 +0200 Subject: [PATCH 69/77] refactor: convert common/ utils, config, scaler to C++20 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 4 (shared common/ core), third batch — three of the four high-fan-out core files, done together so each consumer makefile is edited once. Converted across all 15 consumers (9 tools, minarch, settings, nextui, both libs, and the tg5040 poweroff_next platform tool). Only api.c remains in C. Kept C linkage throughout (platform.c is still C and calls these): added extern "C" guards to utils.h / config.h / scaler.h; scaler.cpp now includes its own header so its exports keep C linkage; each .cpp wraps still-C project headers in extern "C". C++ fixes the stricter compiler required: - utils.cpp: strrchr/strstr on const args return const char* in C++ — const- correct baseName's local and cast the replaceString2 traversal. - config.cpp: reordered the NextUISettings default initializer to declaration order (C++20 requires it), and — because g++ 8.3 rejects designated initializers for char-array members — moved the six char[] string fields out of the aggregate into strcpy() calls. - scaler.cpp: bare `restrict` -> `__restrict` (C++ has no `restrict` keyword); `(void*)p + n` void-pointer arithmetic -> `(uint16_t*)((char*)p + n)`. - poweroff_next: its makefile now compiles the tool as C and utils/config as C++20, linking through g++. Verified: full `make build` clean on tg5040 (g++ 8.3, gnu++2a) and desktop (host g++, gnu++20); nextui/minarch/settings/all tools/libs relink on both. Remaining in Phase 4: api.c (the last core file, ~4.7k lines w/ ~210 compound literals). --- workspace/all/batmon/makefile | 8 ++-- workspace/all/battery/makefile | 8 ++-- workspace/all/bootlogo/makefile | 8 ++-- workspace/all/clock/makefile | 8 ++-- workspace/all/common/{config.c => config.cpp} | 37 ++++++++++++------- workspace/all/common/config.h | 8 ++++ workspace/all/common/{scaler.c => scaler.cpp} | 30 +++++++++------ workspace/all/common/scaler.h | 8 ++++ workspace/all/common/{utils.c => utils.cpp} | 14 +++++-- workspace/all/common/utils.h | 8 ++++ workspace/all/gametime/makefile | 8 ++-- workspace/all/gametimectl/makefile | 8 ++-- workspace/all/ledcontrol/makefile | 8 ++-- workspace/all/libbatmondb/makefile | 4 +- workspace/all/libgametimedb/makefile | 4 +- workspace/all/minarch/makefile | 5 +-- workspace/all/minput/makefile | 8 ++-- workspace/all/nextui/makefile | 4 +- workspace/all/nextval/makefile | 9 +---- workspace/all/settings/makefile | 8 ++-- workspace/tg5040/poweroff_next/makefile | 12 +++++- 21 files changed, 131 insertions(+), 84 deletions(-) rename workspace/all/common/{config.c => config.cpp} (98%) rename workspace/all/common/{scaler.c => scaler.cpp} (99%) rename workspace/all/common/{utils.c => utils.cpp} (97%) diff --git a/workspace/all/batmon/makefile b/workspace/all/batmon/makefile index 9bd9c2dc7..7e5b0ef18 100644 --- a/workspace/all/batmon/makefile +++ b/workspace/all/batmon/makefile @@ -23,9 +23,9 @@ TARGET = batmon INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # Shared common/ + platform stay C; the tool itself is C++20. Compile the C # units to objects, then compile the .cpp and link everything through g++. -SOURCE = -c ../common/utils.c ../common/api.c ../common/config.c ../common/scaler.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = $(TARGET).cpp -CXXSOURCE += build/$(PLATFORM)/utils.o build/$(PLATFORM)/api.o build/$(PLATFORM)/config.o build/$(PLATFORM)/scaler.o build/$(PLATFORM)/platform.o +SOURCE = -c ../common/api.c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp +CXXSOURCE += build/$(PLATFORM)/api.o build/$(PLATFORM)/platform.o CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ @@ -42,7 +42,7 @@ PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/msettings.h $(PREFIX_LOCAL)/include/batmondb.h mkdir -p build/$(PLATFORM) $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) - mv utils.o api.o config.o scaler.o platform.o build/$(PLATFORM) + mv api.o platform.o build/$(PLATFORM) $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) diff --git a/workspace/all/battery/makefile b/workspace/all/battery/makefile index ada509f3d..7654766b5 100644 --- a/workspace/all/battery/makefile +++ b/workspace/all/battery/makefile @@ -23,9 +23,9 @@ TARGET = battery INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # Shared common/ + platform stay C; the tool itself is C++20. Compile the C # units to objects, then compile the .cpp and link everything through g++. -SOURCE = -c ../common/utils.c ../common/api.c ../common/config.c ../common/scaler.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = $(TARGET).cpp -CXXSOURCE += build/$(PLATFORM)/utils.o build/$(PLATFORM)/api.o build/$(PLATFORM)/config.o build/$(PLATFORM)/scaler.o build/$(PLATFORM)/platform.o +SOURCE = -c ../common/api.c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp +CXXSOURCE += build/$(PLATFORM)/api.o build/$(PLATFORM)/platform.o CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ @@ -42,7 +42,7 @@ PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/batmondb.h mkdir -p build/$(PLATFORM) $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) - mv utils.o api.o config.o scaler.o platform.o build/$(PLATFORM) + mv api.o platform.o build/$(PLATFORM) $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) diff --git a/workspace/all/bootlogo/makefile b/workspace/all/bootlogo/makefile index 5ecd49199..8cf0ef285 100644 --- a/workspace/all/bootlogo/makefile +++ b/workspace/all/bootlogo/makefile @@ -23,9 +23,9 @@ TARGET = bootlogo INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # Shared common/ + platform stay C; the tool itself is C++20. Compile the C # units to objects, then compile the .cpp and link everything through g++. -SOURCE = -c ../common/utils.c ../common/api.c ../common/config.c ../common/scaler.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = $(TARGET).cpp -CXXSOURCE += build/$(PLATFORM)/utils.o build/$(PLATFORM)/api.o build/$(PLATFORM)/config.o build/$(PLATFORM)/scaler.o build/$(PLATFORM)/platform.o +SOURCE = -c ../common/api.c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp +CXXSOURCE += build/$(PLATFORM)/api.o build/$(PLATFORM)/platform.o CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ @@ -42,7 +42,7 @@ PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/msettings.h mkdir -p build/$(PLATFORM) $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) - mv utils.o api.o config.o scaler.o platform.o build/$(PLATFORM) + mv api.o platform.o build/$(PLATFORM) $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) diff --git a/workspace/all/clock/makefile b/workspace/all/clock/makefile index 83048c6d1..a74127d82 100644 --- a/workspace/all/clock/makefile +++ b/workspace/all/clock/makefile @@ -23,9 +23,9 @@ TARGET = clock INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # Shared common/ + platform stay C; the tool itself is C++20. Compile the C # units to objects, then compile the .cpp and link everything through g++. -SOURCE = -c ../common/utils.c ../common/api.c ../common/config.c ../common/scaler.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = $(TARGET).cpp -CXXSOURCE += build/$(PLATFORM)/utils.o build/$(PLATFORM)/api.o build/$(PLATFORM)/config.o build/$(PLATFORM)/scaler.o build/$(PLATFORM)/platform.o +SOURCE = -c ../common/api.c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp +CXXSOURCE += build/$(PLATFORM)/api.o build/$(PLATFORM)/platform.o CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ @@ -42,7 +42,7 @@ PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/msettings.h mkdir -p build/$(PLATFORM) $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) - mv utils.o api.o config.o scaler.o platform.o build/$(PLATFORM) + mv api.o platform.o build/$(PLATFORM) $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) diff --git a/workspace/all/common/config.c b/workspace/all/common/config.cpp similarity index 98% rename from workspace/all/common/config.c rename to workspace/all/common/config.cpp index e1ec3ba7b..b82cb27a8 100644 --- a/workspace/all/common/config.c +++ b/workspace/all/common/config.cpp @@ -1,12 +1,17 @@ -#include "config.h" #include #include #include -#include #include #include + +// Project C headers declare C-linkage symbols; include as extern "C" so this +// C++ unit's own exports keep C linkage for the still-C platform.c and any C +// consumers. config.h / utils.h carry their own guards. +extern "C" { +#include "config.h" #include "defines.h" #include "utils.h" +} NextUISettings settings = {0}; @@ -31,7 +36,6 @@ void CFG_defaults(NextUISettings *cfg) return; NextUISettings defaults = { - .fontFile = CFG_DEFAULT_FONT_FILE, .fontStyle = CFG_DEFAULT_FONT_STYLE, .color1_255 = CFG_DEFAULT_COLOR1, .color2_255 = CFG_DEFAULT_COLOR2, @@ -41,10 +45,10 @@ void CFG_defaults(NextUISettings *cfg) .color6_255 = CFG_DEFAULT_COLOR6, .color7_255 = CFG_DEFAULT_COLOR7, .thumbRadius = CFG_DEFAULT_THUMBRADIUS, + .gameSwitcherScaling = CFG_DEFAULT_GAMESWITCHERSCALING, + .gameSwitcherCurtain = CFG_DEFAULT_GAMESWITCHER_CURTAIN, .gameArtWidth = CFG_DEFAULT_GAMEARTWIDTH, - .showFolderNamesAtRoot = CFG_DEFAULT_SHOWFOLDERNAMESATROOT, .inputPromptStyle = CFG_DEFAULT_INPUT_PROMPT_STYLE, - .paletteName = CFG_DEFAULT_PALETTE_NAME, .customColors = {CFG_DEFAULT_COLOR1, CFG_DEFAULT_COLOR2, CFG_DEFAULT_COLOR3, CFG_DEFAULT_COLOR4, CFG_DEFAULT_COLOR5, CFG_DEFAULT_COLOR6, CFG_DEFAULT_COLOR7}, @@ -58,10 +62,10 @@ void CFG_defaults(NextUISettings *cfg) .showTools = CFG_DEFAULT_SHOWTOOLS, .showCollections = CFG_DEFAULT_SHOWCOLLECTIONS, .showGameArt = CFG_DEFAULT_SHOWGAMEART, - .gameSwitcherScaling = CFG_DEFAULT_GAMESWITCHERSCALING, - .defaultView = CFG_DEFAULT_VIEW, + .showFolderNamesAtRoot = CFG_DEFAULT_SHOWFOLDERNAMESATROOT, + .romsUseFolderBackground = CFG_DEFAULT_ROMSUSEFOLDERBACKGROUND, .showQuickSwitcherUi = CFG_DEFAULT_SHOWQUICKWITCHERUI, - .gameSwitcherCurtain = CFG_DEFAULT_GAMESWITCHER_CURTAIN, + .defaultView = CFG_DEFAULT_VIEW, .muteLeds = CFG_DEFAULT_MUTELEDS, @@ -72,12 +76,12 @@ void CFG_defaults(NextUISettings *cfg) .powerOffProtection = CFG_DEFAULT_POWEROFFPROTECTION, .keepAwakeWhenUSB = CFG_DEFAULT_KEEPAWAKEWHENUSB, - .haptics = CFG_DEFAULT_HAPTICS, - .romsUseFolderBackground = CFG_DEFAULT_ROMSUSEFOLDERBACKGROUND, .saveFormat = CFG_DEFAULT_SAVEFORMAT, .stateFormat = CFG_DEFAULT_STATEFORMAT, .useExtractedFileName = CFG_DEFAULT_EXTRACTEDFILENAME, + .haptics = CFG_DEFAULT_HAPTICS, + .ntp = CFG_DEFAULT_NTP, .currentTimezone = CFG_DEFAULT_TIMEZONE, .wifi = CFG_DEFAULT_WIFI, @@ -93,11 +97,7 @@ void CFG_defaults(NextUISettings *cfg) .notifyDuration = CFG_DEFAULT_NOTIFY_DURATION, .raEnable = CFG_DEFAULT_RA_ENABLE, - .raUsername = CFG_DEFAULT_RA_USERNAME, - .raPassword = CFG_DEFAULT_RA_PASSWORD, .raHardcoreMode = CFG_DEFAULT_RA_HARDCOREMODE, - .raToken = CFG_DEFAULT_RA_TOKEN, - .raServerUsername = CFG_DEFAULT_RA_SERVER_USERNAME, .raAuthenticated = CFG_DEFAULT_RA_AUTHENTICATED, .raShowNotifications = CFG_DEFAULT_RA_SHOW_NOTIFICATIONS, .raNotificationDuration = CFG_DEFAULT_RA_NOTIFICATION_DURATION, @@ -105,6 +105,15 @@ void CFG_defaults(NextUISettings *cfg) .raAchievementSortOrder = CFG_DEFAULT_RA_ACHIEVEMENT_SORT_ORDER, }; + // g++ 8.3 (gnu++2a) rejects designated initializers for char-array members, + // so set the string fields here instead of in the aggregate above. + strcpy(defaults.fontFile, CFG_DEFAULT_FONT_FILE); + strcpy(defaults.paletteName, CFG_DEFAULT_PALETTE_NAME); + strcpy(defaults.raUsername, CFG_DEFAULT_RA_USERNAME); + strcpy(defaults.raPassword, CFG_DEFAULT_RA_PASSWORD); + strcpy(defaults.raToken, CFG_DEFAULT_RA_TOKEN); + strcpy(defaults.raServerUsername, CFG_DEFAULT_RA_SERVER_USERNAME); + *cfg = defaults; } diff --git a/workspace/all/common/config.h b/workspace/all/common/config.h index cdd577866..40443732c 100644 --- a/workspace/all/common/config.h +++ b/workspace/all/common/config.h @@ -4,6 +4,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + // portability, deprecated extern uint32_t THEME_COLOR1_255; extern uint32_t THEME_COLOR2_255; @@ -479,4 +483,8 @@ void CFG_setRAAchievementSortOrder(int sortOrder); void CFG_sync(void); void CFG_quit(void); +#ifdef __cplusplus +} +#endif + #endif diff --git a/workspace/all/common/scaler.c b/workspace/all/common/scaler.cpp similarity index 99% rename from workspace/all/common/scaler.c rename to workspace/all/common/scaler.cpp index 1ca94ef19..7727c2242 100644 --- a/workspace/all/common/scaler.c +++ b/workspace/all/common/scaler.cpp @@ -2,7 +2,13 @@ #include #include +// Project C headers declare C-linkage symbols; include as extern "C" so this +// C++ unit's exports (declared in scaler.h) keep C linkage for the still-C +// platform.c and any C consumers. +extern "C" { #include "platform.h" // for HAS_NEON +#include "scaler.h" +} // // arm NEON / C integer scalers for ARMv7 devices @@ -2914,8 +2920,8 @@ void scale1x_line(void* __restrict src, void* __restrict dst, uint32_t sw, uint3 int cpy_pitch = MIN(ip, dp); uint16_t k = 0x0000; - uint16_t* restrict src_row = (uint16_t*)src; - uint16_t* restrict dst_row = (uint16_t*)dst; + uint16_t* __restrict src_row = (uint16_t*)src; + uint16_t* __restrict dst_row = (uint16_t*)dst; for (int y=0; y +#ifdef __cplusplus +extern "C" { +#endif + // // arm NEON / C integer scalers for rg35xx // args/ src : src offset address of top left corner @@ -187,4 +191,8 @@ void scale4x_line(void* __restrict src, void* __restrict dst, uint32_t sw, uint3 void scale2x_grid(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp); void scale3x_grid(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp); +#ifdef __cplusplus +} +#endif + #endif diff --git a/workspace/all/common/utils.c b/workspace/all/common/utils.cpp similarity index 97% rename from workspace/all/common/utils.c rename to workspace/all/common/utils.cpp index 4db67860d..fc10ae0cd 100644 --- a/workspace/all/common/utils.c +++ b/workspace/all/common/utils.cpp @@ -11,8 +11,14 @@ #include #include #include + +// Project C headers declare C-linkage symbols; include as extern "C" so this +// C++ unit's own exports keep C linkage for the still-C platform.c and any C +// consumers. utils.h carries its own guard. +extern "C" { #include "defines.h" #include "utils.h" +} /////////////////////////////////////// @@ -93,7 +99,7 @@ char *replaceString2(const char *orig, char *rep, char *with) // count the number of replacements needed ins = orig; - for (count = 0; (tmp = strstr(ins, rep)); ++count) + for (count = 0; (tmp = (char*)strstr(ins, rep)); ++count) ins = tmp + len_rep; char *result = @@ -241,8 +247,8 @@ char *removeExtension(const char *myStr) } const char *baseName(const char *filename) { - char *p = strrchr(filename, '/'); - return p ? p + 1 : (char *)filename; + const char *p = strrchr(filename, '/'); + return p ? p + 1 : filename; } void folderPath(const char *path, char *result) { char pathCopy[256]; @@ -456,7 +462,7 @@ char* allocFile(char* path) { // caller must free! if (file) { fseek(file, 0L, SEEK_END); size_t size = ftell(file); - contents = calloc(size+1, sizeof(char)); + contents = (char*)calloc(size+1, sizeof(char)); fseek(file, 0L, SEEK_SET); fread(contents, sizeof(char), size, file); fclose(file); diff --git a/workspace/all/common/utils.h b/workspace/all/common/utils.h index f61fc9caf..5a1b0f39b 100644 --- a/workspace/all/common/utils.h +++ b/workspace/all/common/utils.h @@ -5,6 +5,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + int prefixMatch(char* pre, const char* str); int suffixMatch(char* suf,const char* str); int exactMatch(const char* str1, const char* str2); @@ -49,4 +53,8 @@ double clampd(double x, double lower, double upper); char* findFileInDir(const char *directory, const char *filename); +#ifdef __cplusplus +} +#endif + #endif diff --git a/workspace/all/gametime/makefile b/workspace/all/gametime/makefile index 5a4467766..c6a2ce976 100644 --- a/workspace/all/gametime/makefile +++ b/workspace/all/gametime/makefile @@ -23,9 +23,9 @@ TARGET = gametime INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # Shared common/ + platform stay C; the tool itself is C++20. Compile the C # units to objects, then compile the .cpp and link everything through g++. -SOURCE = -c ../common/utils.c ../common/api.c ../common/config.c ../common/scaler.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = $(TARGET).cpp -CXXSOURCE += build/$(PLATFORM)/utils.o build/$(PLATFORM)/api.o build/$(PLATFORM)/config.o build/$(PLATFORM)/scaler.o build/$(PLATFORM)/platform.o +SOURCE = -c ../common/api.c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp +CXXSOURCE += build/$(PLATFORM)/api.o build/$(PLATFORM)/platform.o CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ @@ -42,7 +42,7 @@ PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/gametimedb.h mkdir -p build/$(PLATFORM) $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) - mv utils.o api.o config.o scaler.o platform.o build/$(PLATFORM) + mv api.o platform.o build/$(PLATFORM) $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) diff --git a/workspace/all/gametimectl/makefile b/workspace/all/gametimectl/makefile index db6ba485b..2e386478a 100644 --- a/workspace/all/gametimectl/makefile +++ b/workspace/all/gametimectl/makefile @@ -23,9 +23,9 @@ TARGET = gametimectl INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # Shared common/ + platform stay C; the tool itself is C++20. Compile the C # units to objects, then compile the .cpp and link everything through g++. -SOURCE = -c ../common/utils.c ../common/api.c ../common/scaler.c ../common/config.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = $(TARGET).cpp -CXXSOURCE += build/$(PLATFORM)/utils.o build/$(PLATFORM)/api.o build/$(PLATFORM)/scaler.o build/$(PLATFORM)/config.o build/$(PLATFORM)/platform.o +SOURCE = -c ../common/api.c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/scaler.cpp ../common/config.cpp +CXXSOURCE += build/$(PLATFORM)/api.o build/$(PLATFORM)/platform.o CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ @@ -42,7 +42,7 @@ PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/gametimedb.h mkdir -p build/$(PLATFORM) $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) - mv utils.o api.o scaler.o config.o platform.o build/$(PLATFORM) + mv api.o platform.o build/$(PLATFORM) $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) diff --git a/workspace/all/ledcontrol/makefile b/workspace/all/ledcontrol/makefile index b085c634a..7b27fa3b5 100644 --- a/workspace/all/ledcontrol/makefile +++ b/workspace/all/ledcontrol/makefile @@ -23,9 +23,9 @@ TARGET = ledcontrol INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # Shared common/ + platform stay C; the tool itself is C++20. Compile the C # units to objects, then compile the .cpp and link everything through g++. -SOURCE = -c ../common/utils.c ../common/api.c ../common/config.c ../common/scaler.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = $(TARGET).cpp -CXXSOURCE += build/$(PLATFORM)/utils.o build/$(PLATFORM)/api.o build/$(PLATFORM)/config.o build/$(PLATFORM)/scaler.o build/$(PLATFORM)/platform.o +SOURCE = -c ../common/api.c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp +CXXSOURCE += build/$(PLATFORM)/api.o build/$(PLATFORM)/platform.o CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ @@ -42,7 +42,7 @@ PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/msettings.h mkdir -p build/$(PLATFORM) $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) - mv utils.o api.o config.o scaler.o platform.o build/$(PLATFORM) + mv api.o platform.o build/$(PLATFORM) $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) diff --git a/workspace/all/libbatmondb/makefile b/workspace/all/libbatmondb/makefile index 9637b2146..391dcaa82 100644 --- a/workspace/all/libbatmondb/makefile +++ b/workspace/all/libbatmondb/makefile @@ -38,8 +38,8 @@ SYSROOT := $(shell $(CC) --print-sysroot) INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # The shared common/ + platform units stay C; the library itself is C++20. -CSOURCE = ../common/utils.c ../common/api.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = $(TARGET).cpp +CSOURCE = ../common/api.c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp ../common/utils.cpp CFLAGS += $(OPT) CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" -std=gnu99 diff --git a/workspace/all/libgametimedb/makefile b/workspace/all/libgametimedb/makefile index 39d1f4dd6..d39687548 100644 --- a/workspace/all/libgametimedb/makefile +++ b/workspace/all/libgametimedb/makefile @@ -38,8 +38,8 @@ SYSROOT := $(shell $(CC) --print-sysroot) INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # The shared common/ + platform units stay C; the library itself is C++20. -CSOURCE = ../common/utils.c ../common/api.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = $(TARGET).cpp +CSOURCE = ../common/api.c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp ../common/utils.cpp CFLAGS += $(OPT) CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" -std=gnu99 diff --git a/workspace/all/minarch/makefile b/workspace/all/minarch/makefile index 33877815a..83f2387f5 100644 --- a/workspace/all/minarch/makefile +++ b/workspace/all/minarch/makefile @@ -26,9 +26,8 @@ INCDIR = -I. -I./libretro-common/include/ -I../common/ -I../../$(PLATFORM)/platf # C and C++ translation units are listed separately. C files compile as C; # C++ files compile as C++; everything links through g++ so the two can mix # as modules are migrated to C++ incrementally. -CSOURCE = ../common/scaler.c ../common/utils.c ../common/config.c ../common/api.c \ - ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = $(TARGET).cpp ../common/notification.cpp \ +CSOURCE = ../common/api.c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp ../common/notification.cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp \ ma_audio.cpp ma_input.cpp ma_runframe.cpp ma_cheats.cpp ma_core.cpp \ ma_rewind.cpp ma_saves.cpp ma_game.cpp ma_environment.cpp \ ma_options.cpp ma_video.cpp ma_menu.cpp ma_frontend_opts.cpp ma_config.cpp diff --git a/workspace/all/minput/makefile b/workspace/all/minput/makefile index 7b22c866f..3f062db56 100644 --- a/workspace/all/minput/makefile +++ b/workspace/all/minput/makefile @@ -23,9 +23,9 @@ TARGET = minput INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # Shared common/ + platform stay C; the tool itself is C++20. Compile the C # units to objects, then compile the .cpp and link everything through g++. -SOURCE = -c ../common/utils.c ../common/api.c ../common/config.c ../common/scaler.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = $(TARGET).cpp -CXXSOURCE += build/$(PLATFORM)/utils.o build/$(PLATFORM)/api.o build/$(PLATFORM)/config.o build/$(PLATFORM)/scaler.o build/$(PLATFORM)/platform.o +SOURCE = -c ../common/api.c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp +CXXSOURCE += build/$(PLATFORM)/api.o build/$(PLATFORM)/platform.o CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ @@ -42,7 +42,7 @@ PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/msettings.h mkdir -p build/$(PLATFORM) $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) - mv utils.o api.o config.o scaler.o platform.o build/$(PLATFORM) + mv api.o platform.o build/$(PLATFORM) $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) diff --git a/workspace/all/nextui/makefile b/workspace/all/nextui/makefile index 036a8dfa8..bd27505e2 100644 --- a/workspace/all/nextui/makefile +++ b/workspace/all/nextui/makefile @@ -25,8 +25,8 @@ INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # C and C++ translation units are listed separately. C files compile as C; # C++ files compile as C++; everything links through g++ so the two can mix # as modules are migrated to C++ incrementally. -CSOURCE = ../common/scaler.c ../common/utils.c ../common/config.c ../common/api.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = $(TARGET).cpp +CSOURCE = ../common/api.c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ diff --git a/workspace/all/nextval/makefile b/workspace/all/nextval/makefile index f56c6230a..c8c537435 100644 --- a/workspace/all/nextval/makefile +++ b/workspace/all/nextval/makefile @@ -20,11 +20,8 @@ include ../../$(PLATFORM)/platform/makefile.env TARGET = nextval INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ -# Shared common/ stays C; the tool itself is C++20. Compile the C units to -# objects, then compile the .cpp and link everything through g++. -SOURCE = -c ../common/utils.c ../common/config.c -CXXSOURCE = $(TARGET).cpp -CXXSOURCE += build/$(PLATFORM)/utils.o build/$(PLATFORM)/config.o +# Common utils/config are now C++20 too; single g++ compile+link, no C sources. +CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ @@ -39,8 +36,6 @@ PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: mkdir -p build/$(PLATFORM) - $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) - mv utils.o config.o build/$(PLATFORM) $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) diff --git a/workspace/all/settings/makefile b/workspace/all/settings/makefile index 9485b0034..5229fb9e6 100644 --- a/workspace/all/settings/makefile +++ b/workspace/all/settings/makefile @@ -21,9 +21,9 @@ SDL?=SDL TARGET = settings INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ -SOURCE = -c ../common/utils.c ../common/api.c ../common/config.c ../common/scaler.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = ../common/palette.cpp ../common/ra_offline.cpp ../common/ra_sync.cpp ../common/ra_event_queue.cpp ../common/http.cpp ../common/ra_auth.cpp $(TARGET).cpp menu.cpp colorpickermenu.cpp palettemenu.cpp fnbuttonmenu.cpp wifimenu.cpp btmenu.cpp keyboardprompt.cpp -CXXSOURCE += build/$(PLATFORM)/utils.o build/$(PLATFORM)/api.o build/$(PLATFORM)/config.o build/$(PLATFORM)/scaler.o build/$(PLATFORM)/platform.o +SOURCE = -c ../common/api.c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = ../common/palette.cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp ../common/ra_offline.cpp ../common/ra_sync.cpp ../common/ra_event_queue.cpp ../common/http.cpp ../common/ra_auth.cpp $(TARGET).cpp menu.cpp colorpickermenu.cpp palettemenu.cpp fnbuttonmenu.cpp wifimenu.cpp btmenu.cpp keyboardprompt.cpp +CXXSOURCE += build/$(PLATFORM)/api.o build/$(PLATFORM)/platform.o CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ @@ -53,7 +53,7 @@ PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/msettings.h mkdir -p build/$(PLATFORM) $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) - mv utils.o api.o config.o scaler.o platform.o build/$(PLATFORM) + mv api.o platform.o build/$(PLATFORM) $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) diff --git a/workspace/tg5040/poweroff_next/makefile b/workspace/tg5040/poweroff_next/makefile index 52d3e63ac..4c224765e 100644 --- a/workspace/tg5040/poweroff_next/makefile +++ b/workspace/tg5040/poweroff_next/makefile @@ -20,19 +20,27 @@ include ../platform/makefile.env TARGET = poweroff_next INCDIR = -I. -I../../all/common -I../platform -SOURCE = $(TARGET).c ../../all/common/utils.c ../../all/common/config.c +# common/ utils + config are C++20 now; poweroff_next.c stays C. Compile the +# tool as C, the common units as C++20, and link through g++. +CSOURCE = -c $(TARGET).c +CXXSOURCE = ../../all/common/utils.cpp ../../all/common/config.cpp CC = $(CROSS_COMPILE)gcc +CXX = $(CROSS_COMPILE)g++ +CXXSTD := $(shell printf 'int main(){return 0;}' | $(CXX) -std=gnu++20 -x c++ - -o /dev/null >/dev/null 2>&1 && echo gnu++20 || echo gnu++2a) # Override CFLAGS and LDFLAGS to not include SDL2 dependencies CFLAGS = $(OPT) -g -std=gnu11 -Wall -Wextra CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" +CXXFLAGS = $(OPT) -g $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" -std=$(CXXSTD) LDFLAGS = -lpthread -ldl PRODUCT = build/$(PLATFORM)/$(TARGET).elf all: mkdir -p build/$(PLATFORM) - $(CC) $(SOURCE) -o $(PRODUCT) $(CFLAGS) $(LDFLAGS) + $(CC) $(CSOURCE) $(CFLAGS) + mv $(TARGET).o build/$(PLATFORM) + $(CXX) build/$(PLATFORM)/$(TARGET).o $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) From 5802e69eb89bfff29ce2a84680500bcaead85994 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sun, 26 Jul 2026 16:14:22 +0200 Subject: [PATCH 70/77] =?UTF-8?q?refactor:=20convert=20common/=20api=20to?= =?UTF-8?q?=20C++20=20=E2=80=94=20shared=20core=20now=20fully=20C++?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 4 complete: api.c was the last high-fan-out core file (13 consumers, ~4.7k lines). Moved to the C++ side of all 13 makefiles (8 tools, minarch, settings, nextui; the two libs don't link api so it's just dropped there). The only remaining common/ .c files are generic_*/displaycal, which are #included into platform.c and stay C with the platform layer. Kept C linkage (platform.c is still C and calls GFX_*/PAD_*/etc.): added extern "C" guards to api.h; api.cpp wraps the still-C project headers. C++ fixes: - 39 address-of-a-compound-literal sites &(SDL_Rect){...} -> named local rects (g++ rejects taking the address of a temporary). The ~84 by-value asset-rect compound literals stay as GNU compound-literal rvalues (no address, no miscompile). Two `dst_rect = &(SDL_Rect){...}` defaults became function-scope locals so the pointer doesn't dangle. - 3 (char*[]){...} button-hint literals in GFX_blitHardwareHints -> named local arrays (the g++ 8.3 storage-drop miscompile). - Reordered the libsamplerate SRC_DATA designated init to declaration order. - int -> enum casts nextui surfaced without -fpermissive (LightProfile); one float->int narrowing cast in a progress-bar rect. Verified: full `make build` clean on tg5040 (g++ 8.3) and desktop (host g++); every binary (nextui, minarch, settings, all 10 tools) and both libs relink. --- workspace/all/batmon/makefile | 8 +- workspace/all/battery/makefile | 8 +- workspace/all/bootlogo/makefile | 8 +- workspace/all/clock/makefile | 8 +- workspace/all/common/{api.c => api.cpp} | 136 +++++++++++++----------- workspace/all/common/api.h | 8 ++ workspace/all/gametime/makefile | 8 +- workspace/all/gametimectl/makefile | 8 +- workspace/all/ledcontrol/makefile | 8 +- workspace/all/libbatmondb/makefile | 2 +- workspace/all/libgametimedb/makefile | 2 +- workspace/all/minarch/makefile | 4 +- workspace/all/minput/makefile | 8 +- workspace/all/nextui/makefile | 4 +- workspace/all/settings/makefile | 8 +- 15 files changed, 122 insertions(+), 106 deletions(-) rename workspace/all/common/{api.c => api.cpp} (96%) diff --git a/workspace/all/batmon/makefile b/workspace/all/batmon/makefile index 7e5b0ef18..a41672fd9 100644 --- a/workspace/all/batmon/makefile +++ b/workspace/all/batmon/makefile @@ -23,9 +23,9 @@ TARGET = batmon INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # Shared common/ + platform stay C; the tool itself is C++20. Compile the C # units to objects, then compile the .cpp and link everything through g++. -SOURCE = -c ../common/api.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp -CXXSOURCE += build/$(PLATFORM)/api.o build/$(PLATFORM)/platform.o +SOURCE = -c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp ../common/api.cpp +CXXSOURCE += build/$(PLATFORM)/platform.o CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ @@ -42,7 +42,7 @@ PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/msettings.h $(PREFIX_LOCAL)/include/batmondb.h mkdir -p build/$(PLATFORM) $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) - mv api.o platform.o build/$(PLATFORM) + mv platform.o build/$(PLATFORM) $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) diff --git a/workspace/all/battery/makefile b/workspace/all/battery/makefile index 7654766b5..84884379d 100644 --- a/workspace/all/battery/makefile +++ b/workspace/all/battery/makefile @@ -23,9 +23,9 @@ TARGET = battery INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # Shared common/ + platform stay C; the tool itself is C++20. Compile the C # units to objects, then compile the .cpp and link everything through g++. -SOURCE = -c ../common/api.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp -CXXSOURCE += build/$(PLATFORM)/api.o build/$(PLATFORM)/platform.o +SOURCE = -c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp ../common/api.cpp +CXXSOURCE += build/$(PLATFORM)/platform.o CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ @@ -42,7 +42,7 @@ PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/batmondb.h mkdir -p build/$(PLATFORM) $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) - mv api.o platform.o build/$(PLATFORM) + mv platform.o build/$(PLATFORM) $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) diff --git a/workspace/all/bootlogo/makefile b/workspace/all/bootlogo/makefile index 8cf0ef285..d91ce1b58 100644 --- a/workspace/all/bootlogo/makefile +++ b/workspace/all/bootlogo/makefile @@ -23,9 +23,9 @@ TARGET = bootlogo INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # Shared common/ + platform stay C; the tool itself is C++20. Compile the C # units to objects, then compile the .cpp and link everything through g++. -SOURCE = -c ../common/api.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp -CXXSOURCE += build/$(PLATFORM)/api.o build/$(PLATFORM)/platform.o +SOURCE = -c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp ../common/api.cpp +CXXSOURCE += build/$(PLATFORM)/platform.o CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ @@ -42,7 +42,7 @@ PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/msettings.h mkdir -p build/$(PLATFORM) $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) - mv api.o platform.o build/$(PLATFORM) + mv platform.o build/$(PLATFORM) $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) diff --git a/workspace/all/clock/makefile b/workspace/all/clock/makefile index a74127d82..c8d56e08f 100644 --- a/workspace/all/clock/makefile +++ b/workspace/all/clock/makefile @@ -23,9 +23,9 @@ TARGET = clock INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # Shared common/ + platform stay C; the tool itself is C++20. Compile the C # units to objects, then compile the .cpp and link everything through g++. -SOURCE = -c ../common/api.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp -CXXSOURCE += build/$(PLATFORM)/api.o build/$(PLATFORM)/platform.o +SOURCE = -c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp ../common/api.cpp +CXXSOURCE += build/$(PLATFORM)/platform.o CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ @@ -42,7 +42,7 @@ PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/msettings.h mkdir -p build/$(PLATFORM) $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) - mv api.o platform.o build/$(PLATFORM) + mv platform.o build/$(PLATFORM) $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) diff --git a/workspace/all/common/api.c b/workspace/all/common/api.cpp similarity index 96% rename from workspace/all/common/api.c rename to workspace/all/common/api.cpp index 64477d600..a35570c1f 100644 --- a/workspace/all/common/api.c +++ b/workspace/all/common/api.cpp @@ -1,13 +1,8 @@ -#include "defines.h" -#include "api.h" - #include #include #include -#include #include #include -#include #include #include #include @@ -16,10 +11,16 @@ #include #include +// Project + libmsettings C headers declare C-linkage symbols; include as +// extern "C" so this C++ unit's own exports keep C linkage for the still-C +// platform.c. api.h / utils.h / config.h carry their own guards. +extern "C" { +#include +#include "defines.h" +#include "api.h" #include "utils.h" #include "config.h" - -#include +} extern pthread_mutex_t audio_mutex; @@ -1082,9 +1083,8 @@ int GFX_blitWrappedText(TTF_Font *font, const char *text, int max_width, int max // Render line and continue to next SDL_Surface *line_surface = TTF_RenderUTF8_Blended(font, line, color); if (line_surface) { - SDL_BlitSurface(line_surface, NULL, surface, &(SDL_Rect){ - center_x - line_surface->w / 2, y - }); + { SDL_Rect _r = { center_x - line_surface->w / 2, y }; + SDL_BlitSurface(line_surface, NULL, surface, &_r); } y += line_surface->h; SDL_FreeSurface(line_surface); } @@ -1096,9 +1096,8 @@ int GFX_blitWrappedText(TTF_Font *font, const char *text, int max_width, int max snprintf(truncated, sizeof(truncated), "%s...", line); SDL_Surface *line_surface = TTF_RenderUTF8_Blended(font, truncated, color); if (line_surface) { - SDL_BlitSurface(line_surface, NULL, surface, &(SDL_Rect){ - center_x - line_surface->w / 2, y - }); + { SDL_Rect _r = { center_x - line_surface->w / 2, y }; + SDL_BlitSurface(line_surface, NULL, surface, &_r); } y += line_surface->h; SDL_FreeSurface(line_surface); } @@ -1114,9 +1113,8 @@ int GFX_blitWrappedText(TTF_Font *font, const char *text, int max_width, int max if (line[0] != '\0') { SDL_Surface *line_surface = TTF_RenderUTF8_Blended(font, line, color); if (line_surface) { - SDL_BlitSurface(line_surface, NULL, surface, &(SDL_Rect){ - center_x - line_surface->w / 2, y - }); + { SDL_Rect _r = { center_x - line_surface->w / 2, y }; + SDL_BlitSurface(line_surface, NULL, surface, &_r); } y += line_surface->h; SDL_FreeSurface(line_surface); } @@ -1856,7 +1854,7 @@ void GFX_blitPillColor(int asset, SDL_Surface *dst, SDL_Rect *dst_rect, uint32_t w = h; w -= h; - GFX_blitAssetColor(asset, &(SDL_Rect){0, 0, r, h}, dst, &(SDL_Rect){x, y}, asset_color); + { SDL_Rect _s = {0, 0, r, h}, _d = {x, y}; GFX_blitAssetColor(asset, &_s, dst, &_d, asset_color); } x += r; if (w > 0) { @@ -1871,11 +1869,11 @@ void GFX_blitPillColor(int asset, SDL_Surface *dst, SDL_Rect *dst_rect, uint32_t else { // Fallback for non-pill assets that still use this helper. - GFX_fillRectBlend(dst, &(SDL_Rect){x, y, w, h}, asset_color); + { SDL_Rect _r = {x, y, w, h}; GFX_fillRectBlend(dst, &_r, asset_color); } } x += w; } - GFX_blitAssetColor(asset, &(SDL_Rect){r, 0, r, h}, dst, &(SDL_Rect){x, y}, asset_color); + { SDL_Rect _s = {r, 0, r, h}, _d = {x, y}; GFX_blitAssetColor(asset, &_s, dst, &_d, asset_color); } } void GFX_blitPill(int asset, SDL_Surface *dst, SDL_Rect *dst_rect) { @@ -1929,13 +1927,13 @@ void GFX_blitRectColor(int asset, SDL_Surface *dst, SDL_Rect *dst_rect, uint32_t int d = rect->w; int r = d / 2; - GFX_blitAssetColor(asset, &(SDL_Rect){0, 0, r, r}, dst, &(SDL_Rect){x, y}, asset_color); - SDL_FillRect(dst, &(SDL_Rect){x + r, y, w - d, r}, asset_color); - GFX_blitAssetColor(asset, &(SDL_Rect){r, 0, r, r}, dst, &(SDL_Rect){x + w - r, y}, asset_color); - SDL_FillRect(dst, &(SDL_Rect){x, y + r, w, h - d}, asset_color); - GFX_blitAssetColor(asset, &(SDL_Rect){0, r, r, r}, dst, &(SDL_Rect){x, y + h - r}, asset_color); - SDL_FillRect(dst, &(SDL_Rect){x + r, y + h - r, w - d, r}, asset_color); - GFX_blitAssetColor(asset, &(SDL_Rect){r, r, r, r}, dst, &(SDL_Rect){x + w - r, y + h - r}, asset_color); + { SDL_Rect _s = {0, 0, r, r}, _d = {x, y}; GFX_blitAssetColor(asset, &_s, dst, &_d, asset_color); } + { SDL_Rect _r = {x + r, y, w - d, r}; SDL_FillRect(dst, &_r, asset_color); } + { SDL_Rect _s = {r, 0, r, r}, _d = {x + w - r, y}; GFX_blitAssetColor(asset, &_s, dst, &_d, asset_color); } + { SDL_Rect _r = {x, y + r, w, h - d}; SDL_FillRect(dst, &_r, asset_color); } + { SDL_Rect _s = {0, r, r, r}, _d = {x, y + h - r}; GFX_blitAssetColor(asset, &_s, dst, &_d, asset_color); } + { SDL_Rect _r = {x + r, y + h - r, w - d, r}; SDL_FillRect(dst, &_r, asset_color); } + { SDL_Rect _s = {r, r, r, r}, _d = {x + w - r, y + h - r}; GFX_blitAssetColor(asset, &_s, dst, &_d, asset_color); } } void GFX_assetRect(int asset, SDL_Rect *dst_rect) @@ -2051,7 +2049,7 @@ void GFX_blitButton(char *hint, char *button, SDL_Surface *dst, SDL_Rect *dst_re else { // label text = TTF_RenderUTF8_Blended(font.medium, button, ALT_BUTTON_TEXT_COLOR); - SDL_BlitSurface(text, NULL, dst, &(SDL_Rect){dst_rect->x + (SCALE1(BUTTON_SIZE) - text->w) / 2, dst_rect->y + (SCALE1(BUTTON_SIZE) - text->h) / 2}); + { SDL_Rect _r = {dst_rect->x + (SCALE1(BUTTON_SIZE) - text->w) / 2, dst_rect->y + (SCALE1(BUTTON_SIZE) - text->h) / 2}; SDL_BlitSurface(text, NULL, dst, &_r); } ox += SCALE1(BUTTON_SIZE); SDL_FreeSurface(text); } @@ -2067,11 +2065,11 @@ void GFX_blitButton(char *hint, char *button, SDL_Surface *dst, SDL_Rect *dst_re } else { text = TTF_RenderUTF8_Blended(special_case ? font.large : font.tiny, button, ALT_BUTTON_TEXT_COLOR); - GFX_blitPillDark(ASSET_BUTTON, dst, &(SDL_Rect){dst_rect->x, dst_rect->y, SCALE1(BUTTON_SIZE) / 2 + text->w, SCALE1(BUTTON_SIZE)}); + { SDL_Rect _r = {dst_rect->x, dst_rect->y, SCALE1(BUTTON_SIZE) / 2 + text->w, SCALE1(BUTTON_SIZE)}; GFX_blitPillDark(ASSET_BUTTON, dst, &_r); } ox += SCALE1(BUTTON_SIZE) / 4; int oy = special_case ? SCALE1(-2) : 0; - SDL_BlitSurface(text, NULL, dst, &(SDL_Rect){ox + dst_rect->x, oy + dst_rect->y + (SCALE1(BUTTON_SIZE) - text->h) / 2, text->w, text->h}); + { SDL_Rect _r = {ox + dst_rect->x, oy + dst_rect->y + (SCALE1(BUTTON_SIZE) - text->h) / 2, text->w, text->h}; SDL_BlitSurface(text, NULL, dst, &_r); } ox += text->w; ox += SCALE1(BUTTON_SIZE) / 4; SDL_FreeSurface(text); @@ -2083,13 +2081,14 @@ void GFX_blitButton(char *hint, char *button, SDL_Surface *dst, SDL_Rect *dst_re // hint text SDL_Color text_color = uintToColour(THEME_COLOR6_255); text = TTF_RenderUTF8_Blended(font.small, hint, text_color); - 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_Rect _r = {ox + dst_rect->x, dst_rect->y + (SCALE1(BUTTON_SIZE) - text->h) / 2, text->w, text->h}; SDL_BlitSurface(text, NULL, dst, &_r); } SDL_FreeSurface(text); } void GFX_blitMessage(TTF_Font *font, char *msg, SDL_Surface *dst, SDL_Rect *dst_rect) { + SDL_Rect _full_rect = {0, 0, dst->w, dst->h}; if (!dst_rect) - dst_rect = &(SDL_Rect){0, 0, dst->w, dst->h}; + dst_rect = &_full_rect; // LOG_info("GFX_blitMessage: %p (%ix%i)", dst, dst_rect->w,dst_rect->h); @@ -2134,7 +2133,7 @@ void GFX_blitMessage(TTF_Font *font, char *msg, SDL_Surface *dst, SDL_Rect *dst_ text = TTF_RenderUTF8_Blended_Wrapped(font, line, uintToColour(CFG_getColor(COLOR_LIST_TEXT)), dst_rect->w); int x = dst_rect->x; x += (dst_rect->w - text->w) / 2; - SDL_BlitSurface(text, NULL, dst, &(SDL_Rect){x, y}); + { SDL_Rect _r = {x, y}; SDL_BlitSurface(text, NULL, dst, &_r); } SDL_FreeSurface(text); } y += line_height; @@ -2147,13 +2146,13 @@ void GFX_blitBatteryAtPosition(SDL_Surface *dst, int x, int y) if (SDL_AtomicGet(&pwr.is_charging)) { - GFX_blitAssetColor(ASSET_BATTERY, NULL, dst, &(SDL_Rect){x, y}, THEME_COLOR6); - GFX_blitAssetColor(ASSET_BATTERY_BOLT, NULL, dst, &(SDL_Rect){x + SCALE1(3), y + SCALE1(2)}, THEME_COLOR6); + { SDL_Rect _d = {x, y}; GFX_blitAssetColor(ASSET_BATTERY, NULL, dst, &_d, THEME_COLOR6); } + { SDL_Rect _d = {x + SCALE1(3), y + SCALE1(2)}; GFX_blitAssetColor(ASSET_BATTERY_BOLT, NULL, dst, &_d, THEME_COLOR6); } } else { int percent = SDL_AtomicGet(&pwr.charge); - GFX_blitAssetColor(percent <= 10 ? ASSET_BATTERY_LOW : ASSET_BATTERY, NULL, dst, &(SDL_Rect){x, y}, THEME_COLOR6); + { SDL_Rect _d = {x, y}; GFX_blitAssetColor(percent <= 10 ? ASSET_BATTERY_LOW : ASSET_BATTERY, NULL, dst, &_d, THEME_COLOR6); } if (CFG_getShowBatteryPercent()) { @@ -2176,8 +2175,8 @@ void GFX_blitBatteryAtPosition(SDL_Surface *dst, int x, int y) { clip.x = fill_rect.w - clip.w; clip.y = 0; - GFX_blitAssetColor(percent <= 20 ? ASSET_BATTERY_FILL_LOW : ASSET_BATTERY_FILL, &clip, dst, - &(SDL_Rect){x + SCALE1(3) + clip.x, y + SCALE1(2)}, THEME_COLOR6); + { SDL_Rect _d = {x + SCALE1(3) + clip.x, y + SCALE1(2)}; + GFX_blitAssetColor(percent <= 20 ? ASSET_BATTERY_FILL_LOW : ASSET_BATTERY_FILL, &clip, dst, &_d, THEME_COLOR6); } } } } @@ -2198,8 +2197,8 @@ int GFX_blitHardwareIndicator(SDL_Surface *dst, int x, int y, IndicatorType indi int oy = y; // Draw the pill background - GFX_blitPillLight(ASSET_WHITE_PILL, dst, &(SDL_Rect){ox, oy, ow, SCALE1(PILL_SIZE)}); - + { SDL_Rect _d = {ox, oy, ow, SCALE1(PILL_SIZE)}; GFX_blitPillLight(ASSET_WHITE_PILL, dst, &_d); } + // Determine which setting to display if (indicator_type == INDICATOR_BRIGHTNESS) { @@ -2234,13 +2233,13 @@ int GFX_blitHardwareIndicator(SDL_Surface *dst, int x, int y, IndicatorType indi GFX_assetRect(asset, &asset_rect); int ax = ox + (SCALE1(PILL_SIZE) - asset_rect.w) / 2; int ay = oy + (SCALE1(PILL_SIZE) - asset_rect.h) / 2; - GFX_blitAssetColor(asset, NULL, dst, &(SDL_Rect){ax, ay}, THEME_COLOR6_255); + { SDL_Rect _d = {ax, ay}; GFX_blitAssetColor(asset, NULL, dst, &_d, THEME_COLOR6_255); } // Draw the progress bar background ox += SCALE1(PILL_SIZE); int bar_y = y + SCALE1((PILL_SIZE - SETTINGS_SIZE) / 2); - GFX_blitPillColor(gfx.mode == MODE_MAIN ? ASSET_BAR_BG : ASSET_BAR_BG_MENU, dst, - &(SDL_Rect){ox, bar_y, SCALE1(SETTINGS_WIDTH), SCALE1(SETTINGS_SIZE)}, THEME_COLOR3, RGB_WHITE); + { SDL_Rect _d = {ox, bar_y, SCALE1(SETTINGS_WIDTH), SCALE1(SETTINGS_SIZE)}; + GFX_blitPillColor(gfx.mode == MODE_MAIN ? ASSET_BAR_BG : ASSET_BAR_BG_MENU, dst, &_d, THEME_COLOR3, RGB_WHITE); } // Draw the lock icon centered over the bar if the setting is read-only if (readonly) @@ -2249,7 +2248,7 @@ int GFX_blitHardwareIndicator(SDL_Surface *dst, int x, int y, IndicatorType indi GFX_assetRect(ASSET_LOCK, &lock_rect); int lx = ox + (SCALE1(SETTINGS_WIDTH) - lock_rect.w) / 2; int ly = bar_y + (SCALE1(SETTINGS_SIZE) - lock_rect.h) / 2; - GFX_blitAssetColor(ASSET_LOCK, NULL, dst, &(SDL_Rect){lx, ly}, THEME_COLOR6_255); + { SDL_Rect _d = {lx, ly}; GFX_blitAssetColor(ASSET_LOCK, NULL, dst, &_d, THEME_COLOR6_255); } } else { // Draw the progress bar fill @@ -2257,7 +2256,7 @@ int GFX_blitHardwareIndicator(SDL_Surface *dst, int x, int y, IndicatorType indi if (indicator_type == 1 || indicator_type == 3 || setting_value > 0) { if(!readonly) - GFX_blitPillDark(ASSET_BAR, dst, &(SDL_Rect){ox, bar_y, SCALE1(SETTINGS_WIDTH) * percent, SCALE1(SETTINGS_SIZE)}); + { SDL_Rect _d = {ox, bar_y, (int)(SCALE1(SETTINGS_WIDTH) * percent), SCALE1(SETTINGS_SIZE)}; GFX_blitPillDark(ASSET_BAR, dst, &_d); } } } @@ -2305,7 +2304,7 @@ int GFX_blitHardwareGroup(SDL_Surface *dst, int show_setting) ox = dst->w - SCALE1(PADDING) - ow; oy = SCALE1(PADDING); - GFX_blitPillColor(ASSET_WHITE_PILL, dst, &(SDL_Rect){ox, oy, ow, SCALE1(PILL_SIZE)}, THEME_COLOR2, RGB_WHITE); + { SDL_Rect _d = {ox, oy, ow, SCALE1(PILL_SIZE)}; GFX_blitPillColor(ASSET_WHITE_PILL, dst, &_d, THEME_COLOR2, RGB_WHITE); } int battery_x = ox + (SCALE1(PILL_SIZE) - (battery_rect.w + FIXED_SCALE)) / 2; int battery_y = oy + (SCALE1(PILL_SIZE) - battery_rect.h) / 2; @@ -2355,7 +2354,7 @@ int GFX_blitHardwareGroup(SDL_Surface *dst, int show_setting) ox = dst->w - SCALE1(PADDING) - ow; oy = SCALE1(PADDING); - GFX_blitPillColor(ASSET_WHITE_PILL, dst, &(SDL_Rect){ox, oy, ow, SCALE1(PILL_SIZE)}, THEME_COLOR2, RGB_WHITE); + { SDL_Rect _d = {ox, oy, ow, SCALE1(PILL_SIZE)}; GFX_blitPillColor(ASSET_WHITE_PILL, dst, &_d, THEME_COLOR2, RGB_WHITE); } ox += SCALE1(BUTTON_MARGIN); @@ -2366,7 +2365,7 @@ int GFX_blitHardwareGroup(SDL_Surface *dst, int show_setting) int x = ox; int y = oy + (SCALE1(PILL_SIZE) - bt_rect.h) / 2; - GFX_blitAssetColor(asset, NULL, dst, &(SDL_Rect){x, y}, THEME_COLOR6); + { SDL_Rect _d = {x, y}; GFX_blitAssetColor(asset, NULL, dst, &_d, THEME_COLOR6); } ox += bt_rect.w + SCALE1(BUTTON_MARGIN); } @@ -2380,7 +2379,7 @@ int GFX_blitHardwareGroup(SDL_Surface *dst, int show_setting) int x = ox; int y = oy + (SCALE1(PILL_SIZE) - wifi_rect.h) / 2; - GFX_blitAssetColor(asset, NULL, dst, &(SDL_Rect){x, y}, THEME_COLOR6); + { SDL_Rect _d = {x, y}; GFX_blitAssetColor(asset, NULL, dst, &_d, THEME_COLOR6); } ox += wifi_rect.w + SCALE1(BUTTON_MARGIN); } @@ -2391,7 +2390,7 @@ int GFX_blitHardwareGroup(SDL_Surface *dst, int show_setting) int x = ox; int y = oy + (SCALE1(PILL_SIZE) - external_audio_rect.h) / 2; - GFX_blitAssetColor(asset, NULL, dst, &(SDL_Rect){x, y}, THEME_COLOR6); + { SDL_Rect _d = {x, y}; GFX_blitAssetColor(asset, NULL, dst, &_d, THEME_COLOR6); } ox += external_audio_rect.w + SCALE1(BUTTON_MARGIN); } @@ -2405,7 +2404,7 @@ int GFX_blitHardwareGroup(SDL_Surface *dst, int show_setting) { int x = ox; int y = oy + (SCALE1(PILL_SIZE) - clock->h) / 2; - SDL_BlitSurface(clock, NULL, dst, &(SDL_Rect){x, y}); + { SDL_Rect _r = {x, y}; SDL_BlitSurface(clock, NULL, dst, &_r); } SDL_FreeSurface(clock); } } @@ -2416,12 +2415,20 @@ int GFX_blitHardwareGroup(SDL_Surface *dst, int show_setting) void GFX_blitHardwareHints(SDL_Surface *dst, int show_setting) { - if (show_setting == 1) - GFX_blitButtonGroup((char *[]){BRIGHTNESS_BUTTON_LABEL, "BRIGHTNESS", NULL}, 0, dst, 0); - else if (show_setting == 3) - GFX_blitButtonGroup((char *[]){BRIGHTNESS_BUTTON_LABEL, "COLOR TEMP", NULL}, 0, dst, 0); - else - GFX_blitButtonGroup((char *[]){"MNU", "BRGHT", "SEL", "CLTMP", NULL}, 0, dst, 0); + // Named local arrays: g++ 8.3 miscompiles a (char*[]){...} compound literal + // passed straight to a function. + if (show_setting == 1) { + const char* _h[] = {BRIGHTNESS_BUTTON_LABEL, "BRIGHTNESS", NULL}; + GFX_blitButtonGroup((char**)_h, 0, dst, 0); + } + else if (show_setting == 3) { + const char* _h[] = {BRIGHTNESS_BUTTON_LABEL, "COLOR TEMP", NULL}; + GFX_blitButtonGroup((char**)_h, 0, dst, 0); + } + else { + const char* _h[] = {"MNU", "BRGHT", "SEL", "CLTMP", NULL}; + GFX_blitButtonGroup((char**)_h, 0, dst, 0); + } } int GFX_blitButtonGroup(char **pairs, int primary, SDL_Surface *dst, int align_right) @@ -2464,13 +2471,13 @@ int GFX_blitButtonGroup(char **pairs, int primary, SDL_Surface *dst, int align_r ow += SCALE1(BUTTON_MARGIN); if (align_right) ox -= ow; - GFX_blitPillColor(ASSET_WHITE_PILL, dst, &(SDL_Rect){ox, oy, ow, SCALE1(PILL_SIZE)}, THEME_COLOR2, RGB_WHITE); + { SDL_Rect _d = {ox, oy, ow, SCALE1(PILL_SIZE)}; GFX_blitPillColor(ASSET_WHITE_PILL, dst, &_d, THEME_COLOR2, RGB_WHITE); } ox += SCALE1(BUTTON_MARGIN); oy += SCALE1(BUTTON_MARGIN); for (int i = 0; i < h; i++) { - GFX_blitButton(hints[i].hint, hints[i].button, dst, &(SDL_Rect){ox, oy}); + { SDL_Rect _r = {ox, oy}; GFX_blitButton(hints[i].hint, hints[i].button, dst, &_r); } ox += hints[i].ow + SCALE1(BUTTON_MARGIN); } return ow; @@ -2542,8 +2549,9 @@ void GFX_sizeText(TTF_Font *font, const char *str, int leading, int *w, int *h) } void GFX_blitText(TTF_Font *font, const char *str, int leading, SDL_Color color, SDL_Surface *dst, SDL_Rect *dst_rect) { + SDL_Rect _full_rect = {0, 0, dst->w, dst->h}; if (dst_rect == NULL) - dst_rect = &(SDL_Rect){0, 0, dst->w, dst->h}; + dst_rect = &_full_rect; const char *lines[MAX_TEXT_LINES]; int count = 0; @@ -2580,7 +2588,7 @@ void GFX_blitText(TTF_Font *font, const char *str, int leading, SDL_Color color, if (len) { text = TTF_RenderUTF8_Blended(font, line, color); - SDL_BlitSurface(text, NULL, dst, &(SDL_Rect){x + ((dst_rect->w - text->w) / 2), y + (i * leading)}); + { SDL_Rect _r = {x + ((dst_rect->w - text->w) / 2), y + (i * leading)}; SDL_BlitSurface(text, NULL, dst, &_r); } SDL_FreeSurface(text); } } @@ -2729,8 +2737,8 @@ ResampledFrames resample_audio(const SND_Frame *input_frames, .data_out = output_buffer, .input_frames = input_frame_count, .output_frames = max_output_frames, - .src_ratio = final_ratio, - .end_of_input = 0}; + .end_of_input = 0, + .src_ratio = final_ratio}; if (src_process(src_state, &src_data) != 0) { @@ -4224,7 +4232,7 @@ void PWR_powerOff(int reboot) PLAT_clearLayers(0); PLAT_clearAll(); - GFX_blitMessage(font.large, msg, gfx.screen, &(SDL_Rect){0, 0, gfx.screen->w, gfx.screen->h}); //, NULL); + { SDL_Rect _r = {0, 0, gfx.screen->w, gfx.screen->h}; GFX_blitMessage(font.large, msg, gfx.screen, &_r); } //, NULL); GFX_flip(gfx.screen); system("killall -TERM keymon.elf"); @@ -4621,7 +4629,7 @@ bool LEDS_pushProfileOverride(int profile) LOG_debug("LED_profile stack is full, ignoring.\n"); return false; } - profile_override[++profile_override_top] = profile; + profile_override[++profile_override_top] = (LightProfile)profile; LEDS_applyRules(); return true; diff --git a/workspace/all/common/api.h b/workspace/all/common/api.h index 1cadc5533..6372c6324 100644 --- a/workspace/all/common/api.h +++ b/workspace/all/common/api.h @@ -6,6 +6,10 @@ #include "config.h" #include +#ifdef __cplusplus +extern "C" { +#endif + /////////////////////////////// enum { @@ -974,4 +978,8 @@ void PLAT_bluetoothSetVolume(int vol); #define BT_getVolume PLAT_bluetoothVolume #define BT_setVolume PLAT_bluetoothSetVolume +#ifdef __cplusplus +} +#endif + #endif diff --git a/workspace/all/gametime/makefile b/workspace/all/gametime/makefile index c6a2ce976..ac8154010 100644 --- a/workspace/all/gametime/makefile +++ b/workspace/all/gametime/makefile @@ -23,9 +23,9 @@ TARGET = gametime INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # Shared common/ + platform stay C; the tool itself is C++20. Compile the C # units to objects, then compile the .cpp and link everything through g++. -SOURCE = -c ../common/api.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp -CXXSOURCE += build/$(PLATFORM)/api.o build/$(PLATFORM)/platform.o +SOURCE = -c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp ../common/api.cpp +CXXSOURCE += build/$(PLATFORM)/platform.o CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ @@ -42,7 +42,7 @@ PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/gametimedb.h mkdir -p build/$(PLATFORM) $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) - mv api.o platform.o build/$(PLATFORM) + mv platform.o build/$(PLATFORM) $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) diff --git a/workspace/all/gametimectl/makefile b/workspace/all/gametimectl/makefile index 2e386478a..edbc1cc42 100644 --- a/workspace/all/gametimectl/makefile +++ b/workspace/all/gametimectl/makefile @@ -23,9 +23,9 @@ TARGET = gametimectl INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # Shared common/ + platform stay C; the tool itself is C++20. Compile the C # units to objects, then compile the .cpp and link everything through g++. -SOURCE = -c ../common/api.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/scaler.cpp ../common/config.cpp -CXXSOURCE += build/$(PLATFORM)/api.o build/$(PLATFORM)/platform.o +SOURCE = -c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/scaler.cpp ../common/config.cpp ../common/api.cpp +CXXSOURCE += build/$(PLATFORM)/platform.o CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ @@ -42,7 +42,7 @@ PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/gametimedb.h mkdir -p build/$(PLATFORM) $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) - mv api.o platform.o build/$(PLATFORM) + mv platform.o build/$(PLATFORM) $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) diff --git a/workspace/all/ledcontrol/makefile b/workspace/all/ledcontrol/makefile index 7b27fa3b5..79785bfc0 100644 --- a/workspace/all/ledcontrol/makefile +++ b/workspace/all/ledcontrol/makefile @@ -23,9 +23,9 @@ TARGET = ledcontrol INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # Shared common/ + platform stay C; the tool itself is C++20. Compile the C # units to objects, then compile the .cpp and link everything through g++. -SOURCE = -c ../common/api.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp -CXXSOURCE += build/$(PLATFORM)/api.o build/$(PLATFORM)/platform.o +SOURCE = -c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp ../common/api.cpp +CXXSOURCE += build/$(PLATFORM)/platform.o CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ @@ -42,7 +42,7 @@ PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/msettings.h mkdir -p build/$(PLATFORM) $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) - mv api.o platform.o build/$(PLATFORM) + mv platform.o build/$(PLATFORM) $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) diff --git a/workspace/all/libbatmondb/makefile b/workspace/all/libbatmondb/makefile index 391dcaa82..0939d5644 100644 --- a/workspace/all/libbatmondb/makefile +++ b/workspace/all/libbatmondb/makefile @@ -38,7 +38,7 @@ SYSROOT := $(shell $(CC) --print-sysroot) INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # The shared common/ + platform units stay C; the library itself is C++20. -CSOURCE = ../common/api.c ../../$(PLATFORM)/platform/platform.c +CSOURCE = ../../$(PLATFORM)/platform/platform.c CXXSOURCE = $(TARGET).cpp ../common/utils.cpp CFLAGS += $(OPT) diff --git a/workspace/all/libgametimedb/makefile b/workspace/all/libgametimedb/makefile index d39687548..fa287508d 100644 --- a/workspace/all/libgametimedb/makefile +++ b/workspace/all/libgametimedb/makefile @@ -38,7 +38,7 @@ SYSROOT := $(shell $(CC) --print-sysroot) INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # The shared common/ + platform units stay C; the library itself is C++20. -CSOURCE = ../common/api.c ../../$(PLATFORM)/platform/platform.c +CSOURCE = ../../$(PLATFORM)/platform/platform.c CXXSOURCE = $(TARGET).cpp ../common/utils.cpp CFLAGS += $(OPT) diff --git a/workspace/all/minarch/makefile b/workspace/all/minarch/makefile index 83f2387f5..19f96c250 100644 --- a/workspace/all/minarch/makefile +++ b/workspace/all/minarch/makefile @@ -26,8 +26,8 @@ INCDIR = -I. -I./libretro-common/include/ -I../common/ -I../../$(PLATFORM)/platf # C and C++ translation units are listed separately. C files compile as C; # C++ files compile as C++; everything links through g++ so the two can mix # as modules are migrated to C++ incrementally. -CSOURCE = ../common/api.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = $(TARGET).cpp ../common/notification.cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp \ +CSOURCE = ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp ../common/notification.cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp ../common/api.cpp \ ma_audio.cpp ma_input.cpp ma_runframe.cpp ma_cheats.cpp ma_core.cpp \ ma_rewind.cpp ma_saves.cpp ma_game.cpp ma_environment.cpp \ ma_options.cpp ma_video.cpp ma_menu.cpp ma_frontend_opts.cpp ma_config.cpp diff --git a/workspace/all/minput/makefile b/workspace/all/minput/makefile index 3f062db56..33d0c9dbd 100644 --- a/workspace/all/minput/makefile +++ b/workspace/all/minput/makefile @@ -23,9 +23,9 @@ TARGET = minput INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # Shared common/ + platform stay C; the tool itself is C++20. Compile the C # units to objects, then compile the .cpp and link everything through g++. -SOURCE = -c ../common/api.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp -CXXSOURCE += build/$(PLATFORM)/api.o build/$(PLATFORM)/platform.o +SOURCE = -c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp ../common/api.cpp +CXXSOURCE += build/$(PLATFORM)/platform.o CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ @@ -42,7 +42,7 @@ PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/msettings.h mkdir -p build/$(PLATFORM) $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) - mv api.o platform.o build/$(PLATFORM) + mv platform.o build/$(PLATFORM) $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) diff --git a/workspace/all/nextui/makefile b/workspace/all/nextui/makefile index bd27505e2..1ee600b36 100644 --- a/workspace/all/nextui/makefile +++ b/workspace/all/nextui/makefile @@ -25,8 +25,8 @@ INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # C and C++ translation units are listed separately. C files compile as C; # C++ files compile as C++; everything links through g++ so the two can mix # as modules are migrated to C++ incrementally. -CSOURCE = ../common/api.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp +CSOURCE = ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp ../common/api.cpp CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ diff --git a/workspace/all/settings/makefile b/workspace/all/settings/makefile index 5229fb9e6..81749221f 100644 --- a/workspace/all/settings/makefile +++ b/workspace/all/settings/makefile @@ -21,9 +21,9 @@ SDL?=SDL TARGET = settings INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ -SOURCE = -c ../common/api.c ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = ../common/palette.cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp ../common/ra_offline.cpp ../common/ra_sync.cpp ../common/ra_event_queue.cpp ../common/http.cpp ../common/ra_auth.cpp $(TARGET).cpp menu.cpp colorpickermenu.cpp palettemenu.cpp fnbuttonmenu.cpp wifimenu.cpp btmenu.cpp keyboardprompt.cpp -CXXSOURCE += build/$(PLATFORM)/api.o build/$(PLATFORM)/platform.o +SOURCE = -c ../../$(PLATFORM)/platform/platform.c +CXXSOURCE = ../common/palette.cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp ../common/api.cpp ../common/ra_offline.cpp ../common/ra_sync.cpp ../common/ra_event_queue.cpp ../common/http.cpp ../common/ra_auth.cpp $(TARGET).cpp menu.cpp colorpickermenu.cpp palettemenu.cpp fnbuttonmenu.cpp wifimenu.cpp btmenu.cpp keyboardprompt.cpp +CXXSOURCE += build/$(PLATFORM)/platform.o CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ @@ -53,7 +53,7 @@ PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/msettings.h mkdir -p build/$(PLATFORM) $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) - mv api.o platform.o build/$(PLATFORM) + mv platform.o build/$(PLATFORM) $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: rm -f $(PRODUCT) From 054126a37469e487e0c8ef6472ea941e76faca3d Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sun, 26 Jul 2026 16:38:00 +0200 Subject: [PATCH 71/77] refactor: convert common/ displaycal to C++20 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit displaycal is the last shared common/ source still compiled as C. It is only built into tg5040's libmsettings.so. Compile it with g++ under -std=gnu++2a but with -fno-exceptions/-fno-rtti so the object references no libstdc++ symbols, and keep linking libmsettings.so with gcc — the .so's NEEDED graph is byte-identical (no libstdc++ injected into a lib loaded by every process, including the still-C daemons). --- workspace/all/common/{displaycal.c => displaycal.cpp} | 0 workspace/tg5040/libmsettings/makefile | 6 +++++- 2 files changed, 5 insertions(+), 1 deletion(-) rename workspace/all/common/{displaycal.c => displaycal.cpp} (100%) diff --git a/workspace/all/common/displaycal.c b/workspace/all/common/displaycal.cpp similarity index 100% rename from workspace/all/common/displaycal.c rename to workspace/all/common/displaycal.cpp diff --git a/workspace/tg5040/libmsettings/makefile b/workspace/tg5040/libmsettings/makefile index e666406ff..4d546ef4a 100644 --- a/workspace/tg5040/libmsettings/makefile +++ b/workspace/tg5040/libmsettings/makefile @@ -11,15 +11,19 @@ TARGET=msettings .PHONY: clean CC = $(CROSS_COMPILE)gcc +CXX = $(CROSS_COMPILE)g++ CFLAGS = -I../../all/common +# displaycal is C++ but uses no C++ runtime; -fno-exceptions/-fno-rtti keeps the +# object free of libstdc++ symbols so libmsettings.so still links with plain gcc. +CXXFLAGS = $(CFLAGS) -std=gnu++2a -fno-exceptions -fno-rtti LDFLAGS = -ltinyalsa -ldl -lrt -lm -s OPTM=-Ofast build: $(CC) -c -Werror -fpic "$(TARGET).c" $(CFLAGS) -Wl,--no-as-needed $(LDFLAGS) - $(CC) -c -Werror -fpic "../../all/common/displaycal.c" $(CFLAGS) -Wl,--no-as-needed $(LDFLAGS) + $(CXX) -c -Werror -fpic "../../all/common/displaycal.cpp" $(CXXFLAGS) -Wl,--no-as-needed $(LDFLAGS) $(CC) -shared -o "lib$(TARGET).so" "$(TARGET).o" "displaycal.o" $(LDFLAGS) mkdir -p "$(PREFIX_LOCAL)/include" mkdir -p "$(PREFIX_LOCAL)/lib" From dd102ceda444f85b9a1c8054bdcf46640d2b160d Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sun, 26 Jul 2026 16:44:03 +0200 Subject: [PATCH 72/77] refactor: make platform HAL generic_* compile-clean under C++ Prep for converting each platform's platform.c (which unity-includes these shared generic_*.c files) to C++20. All fixes are valid C as well, so the files keep compiling as C for platforms not yet converted: - explicit casts on realloc/malloc/calloc void* results (generic_platform joysticks; generic_video cleaned/pragmas/overlay_path/pixels) - reorder FX_Context 'effect' designated initializer to declaration order - replace two &(SDL_Rect){...} compound-literal pointers in PLAT_flip with named SDL_Rect locals (address-of-temporary is ill-formed in C++) No behavior change; tg5040 C build verified green. --- workspace/all/common/generic_platform.c | 4 ++-- workspace/all/common/generic_video.c | 22 +++++++++++----------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/workspace/all/common/generic_platform.c b/workspace/all/common/generic_platform.c index a3f305d81..4daa8ce68 100644 --- a/workspace/all/common/generic_platform.c +++ b/workspace/all/common/generic_platform.c @@ -25,7 +25,7 @@ void PLAT_updateInput(const SDL_Event *event) { int device_index = event->jdevice.which; SDL_Joystick *new_joy = SDL_JoystickOpen(device_index); if (new_joy) { - joysticks = realloc(joysticks, sizeof(SDL_Joystick *) * (num_joysticks + 1)); + joysticks = (SDL_Joystick **)realloc(joysticks, sizeof(SDL_Joystick *) * (num_joysticks + 1)); joysticks[num_joysticks++] = new_joy; LOG_info("Joystick added at index %d: %s\n", device_index, SDL_JoystickName(new_joy)); } else { @@ -50,7 +50,7 @@ void PLAT_updateInput(const SDL_Event *event) { free(joysticks); joysticks = NULL; } else { - joysticks = realloc(joysticks, sizeof(SDL_Joystick *) * num_joysticks); + joysticks = (SDL_Joystick **)realloc(joysticks, sizeof(SDL_Joystick *) * num_joysticks); } break; } diff --git a/workspace/all/common/generic_video.c b/workspace/all/common/generic_video.c index a9450e048..9a5f33b4f 100644 --- a/workspace/all/common/generic_video.c +++ b/workspace/all/common/generic_video.c @@ -320,7 +320,7 @@ GLuint load_shader_from_file(GLenum type, const char* filepath) { LOG_info("load shader from file %s\n", filepath); // Filter out lines starting with "#pragma parameter" - char* cleaned = malloc(strlen(source) + 1); + char* cleaned = (char*)malloc(strlen(source) + 1); if (!cleaned) { fprintf(stderr, "Out of memory\n"); free(source); @@ -475,7 +475,7 @@ GLuint load_shader_from_file(GLenum type, const char* filepath) { #define MAX_SHADER_PRAGMAS 32 void loadShaderPragmas(ShaderProgram *shader, const char *shaderSource) { - shader->pragmas = calloc(MAX_SHADER_PRAGMAS, sizeof(ShaderParam)); + shader->pragmas = (ShaderParam*)calloc(MAX_SHADER_PRAGMAS, sizeof(ShaderParam)); if (!shader->pragmas) { fprintf(stderr, "Out of memory allocating pragmas for %s\n", shader->filename); return; @@ -906,12 +906,12 @@ static struct FX_Context { int live_type; } effect = { .scale = 1, - .next_scale = 1, .type = EFFECT_NONE, - .next_type = EFFECT_NONE, - .live_type = EFFECT_NONE, .color = 0, + .next_scale = 1, + .next_type = EFFECT_NONE, .next_color = 0, + .live_type = EFFECT_NONE, }; static void rgb565_to_rgb888(uint32_t rgb565, uint8_t *r, uint8_t *g, uint8_t *b) { // Extract the red component (5 bits) @@ -1048,7 +1048,7 @@ void PLAT_setOverlay(const char* filename, const char* tag) { } size_t path_len = strlen(OVERLAYS_FOLDER) + strlen(tag) + strlen(filename) + 4; // +3 for slashes and null-terminator - overlay_path = malloc(path_len); + overlay_path = (char*)malloc(path_len); if (!overlay_path) { perror("malloc failed"); @@ -1690,12 +1690,12 @@ void PLAT_flip(SDL_Surface* IGNORED, int ignored) { target = vid.target; } - SDL_Rect* src_rect = &(SDL_Rect){x, y, w, h}; - SDL_Rect* dst_rect = &(SDL_Rect){0, 0, device_width, device_height}; + SDL_Rect src_rect = {x, y, w, h}; + SDL_Rect dst_rect = {0, 0, device_width, device_height}; - setRectToAspectRatio(dst_rect); + setRectToAspectRatio(&dst_rect); - SDL_RenderCopy(vid.renderer, target, src_rect, dst_rect); + SDL_RenderCopy(vid.renderer, target, &src_rect, &dst_rect); SDL_RenderPresent(vid.renderer); vid.blit = NULL; @@ -2310,7 +2310,7 @@ unsigned char* PLAT_GL_screenCapture(int* outWidth, int* outHeight) { if (outWidth) *outWidth = width; if (outHeight) *outHeight = height; - unsigned char* pixels = malloc(width * height * 4); // RGBA + unsigned char* pixels = (unsigned char*)malloc(width * height * 4); // RGBA if (!pixels) return NULL; glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); From 7d6f04744ac2babd10496298d1b6eeef06a08e4d Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sun, 26 Jul 2026 16:49:19 +0200 Subject: [PATCH 73/77] refactor: make tg5040/tg5050 platform.c compile-clean under C++ Prep for renaming platform.c -> platform.cpp. Valid C as well (no behavior change), so the files keep building as C until the makefiles switch: - reorder DeviceDescriptor initializers (joy_l4/r4/menu_alt before joy_plus/minus; rumble_gpio_path before gpu_speed_fixed) and the WIFI_connection initializer to declaration order (C++ rejects out-of-order designators) - PLAT_getCurrentTimezone: return NULL not false on failure (char*, not bool -- harmless 0==NULL in C, a type error in C++) desktop/platform/platform.c already compiles clean as C++; no change. --- workspace/tg5040/platform/platform.c | 25 ++++++++++++++----------- workspace/tg5050/platform/platform.c | 11 ++++++----- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/workspace/tg5040/platform/platform.c b/workspace/tg5040/platform/platform.c index 261c8a5ab..bb095c321 100644 --- a/workspace/tg5040/platform/platform.c +++ b/workspace/tg5040/platform/platform.c @@ -39,26 +39,28 @@ int is_brickpro = 0; static const DeviceDescriptor TG5040_BRICK = { .scale = 3, .width = 1024, .height = 768, .main_row_count = 7, .quick_switcher_count = 3, .padding = 5, - .joy_l3 = 9, .joy_r3 = 10, .joy_plus = 14, .joy_minus = 13, + .joy_l3 = 9, .joy_r3 = 10, .joy_l4 = JOY_NA, .joy_r4 = JOY_NA, .joy_menu_alt = JOY_NA, + .joy_plus = 14, .joy_minus = 13, .cpu_speed_path = TG5040_CPU_SPEED_PATH, .gpu_temp_path = TG5040_GPU_TEMP_PATH, + .rumble_gpio_path = TG5040_RUMBLE_GPIO, .gpu_speed_fixed = 660, .gpu_freq_path = NULL, .gpu_usage_path = NULL, - .rumble_gpio_path = TG5040_RUMBLE_GPIO, }; static const DeviceDescriptor TG5040_SMART_PRO = { .scale = 2, .width = 1280, .height = 720, .main_row_count = 10, .quick_switcher_count = 4, .padding = 10, - .joy_l3 = JOY_NA, .joy_r3 = JOY_NA, .joy_plus = 128, .joy_minus = 129, + .joy_l3 = JOY_NA, .joy_r3 = JOY_NA, .joy_l4 = JOY_NA, .joy_r4 = JOY_NA, .joy_menu_alt = JOY_NA, + .joy_plus = 128, .joy_minus = 129, .cpu_speed_path = TG5040_CPU_SPEED_PATH, .gpu_temp_path = TG5040_GPU_TEMP_PATH, + .rumble_gpio_path = TG5040_RUMBLE_GPIO, .gpu_speed_fixed = 660, .gpu_freq_path = NULL, .gpu_usage_path = NULL, - .rumble_gpio_path = TG5040_RUMBLE_GPIO, }; // TrimUI Brick Pro: a distinct tg5040 device (is_brickpro) sharing the Brick's // 1024x768 screen and menu layout, but adding the Smart Pro's dual analog @@ -70,14 +72,15 @@ static const DeviceDescriptor TG5040_SMART_PRO = { static const DeviceDescriptor TG5040_BRICK_PRO = { .scale = 3, .width = 1024, .height = 768, .main_row_count = 7, .quick_switcher_count = 3, .padding = 5, - .joy_l3 = 9, .joy_r3 = 10, .joy_plus = 14, .joy_minus = 13, + .joy_l3 = 9, .joy_r3 = 10, .joy_l4 = 11, .joy_r4 = 12, .joy_menu_alt = 15, + .joy_plus = 14, .joy_minus = 13, .cpu_speed_path = TG5040_CPU_SPEED_PATH, .gpu_temp_path = TG5040_GPU_TEMP_PATH, + .rumble_gpio_path = TG5040_RUMBLE_GPIO, .gpu_speed_fixed = 660, .gpu_freq_path = NULL, .gpu_usage_path = NULL, - .rumble_gpio_path = TG5040_RUMBLE_GPIO, }; // Default to Smart Pro so the geometry/button macros are valid even before // init runs; resolveDeviceModel() refines it once DEVICE is known. @@ -124,12 +127,12 @@ void PLAT_initInput(void) { static struct WIFI_connection connection = { .valid = false, + .ssid = {0}, + .ip = {0}, .freq = -1, + .rssi = -1, .link_speed = -1, .noise = -1, - .rssi = -1, - .ip = {0}, - .ssid = {0}, }; static inline void connection_reset(struct WIFI_connection *connection_info) @@ -481,12 +484,12 @@ char *PLAT_getCurrentTimezone() { char *output = (char *)malloc(256); if (!output) { - return false; + return NULL; } FILE *fp = popen("uci get system.@system[0].zonename", "r"); if (!fp) { free(output); - return false; + return NULL; } fgets(output, 256, fp); pclose(fp); diff --git a/workspace/tg5050/platform/platform.c b/workspace/tg5050/platform/platform.c index 033612ae9..3be958e90 100644 --- a/workspace/tg5050/platform/platform.c +++ b/workspace/tg5050/platform/platform.c @@ -28,14 +28,15 @@ static const DeviceDescriptor TG5050 = { .scale = 2, .width = 1280, .height = 720, .main_row_count = 10, .quick_switcher_count = 4, .padding = 10, - .joy_l3 = 9, .joy_r3 = 10, .joy_plus = 128, .joy_minus = 129, + .joy_l3 = 9, .joy_r3 = 10, .joy_l4 = JOY_NA, .joy_r4 = JOY_NA, .joy_menu_alt = JOY_NA, + .joy_plus = 128, .joy_minus = 129, .cpu_speed_path = TG5050_CPU_SPEED_PATH, .gpu_temp_path = TG5050_GPU_TEMP_PATH, + .rumble_gpio_path = TG5050_RUMBLE_GPIO, .gpu_speed_fixed = 0, .gpu_freq_path = TG5050_GPU_FREQ_PATH, .gpu_usage_path = TG5050_GPU_USAGE_PATH, - .rumble_gpio_path = TG5050_RUMBLE_GPIO, }; const DeviceDescriptor* deviceModel = &TG5050; #include "api.h" @@ -105,12 +106,12 @@ void PLAT_getGPUUsage() { static struct WIFI_connection connection = { .valid = false, + .ssid = {0}, + .ip = {0}, .freq = -1, + .rssi = -1, .link_speed = -1, .noise = -1, - .rssi = -1, - .ip = {0}, - .ssid = {0}, }; static inline void connection_reset(struct WIFI_connection *connection_info) From 6f77467b893c8e1e206b384a6743eab6145d5175 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sun, 26 Jul 2026 17:01:01 +0200 Subject: [PATCH 74/77] refactor: convert platform layer (platform.c -> platform.cpp) to C++20 Renames each platform's platform.c to platform.cpp and compiles it with g++. The four shared common/generic_*.c files are textual #include fragments of platform.cpp, so they now build as C++ too (no standalone C compile remains); they keep the .c extension as include-only fragments, per route (a) -- the GLES pipeline in generic_video.c is compile-clean but otherwise untouched. - 9 tool makefiles + settings: compile the platform TU with $(CXX)/$(CXXFLAGS) instead of $(CC)/$(CFLAGS) - nextui, minarch: move the platform TU from CSOURCE to CXXSOURCE (the %.cpp pattern rule + vpath already cover it) - libbatmondb, libgametimedb: drop the platform compile entirely -- that object was compiled but never linked into the .so (dead build step) - platform.cpp wraps in extern "C" (a C library header without its own guards) so libmsettings' symbols resolve with C linkage Builds green on tg5040, tg5050, and desktop. On-device runtime validation across the three handhelds still pending. --- workspace/all/batmon/makefile | 4 ++-- workspace/all/battery/makefile | 4 ++-- workspace/all/bootlogo/makefile | 4 ++-- workspace/all/clock/makefile | 4 ++-- workspace/all/gametime/makefile | 4 ++-- workspace/all/gametimectl/makefile | 4 ++-- workspace/all/ledcontrol/makefile | 4 ++-- workspace/all/libbatmondb/makefile | 5 ++--- workspace/all/libgametimedb/makefile | 5 ++--- workspace/all/minarch/makefile | 4 ++-- workspace/all/minput/makefile | 4 ++-- workspace/all/nextui/makefile | 4 ++-- workspace/all/settings/makefile | 4 ++-- workspace/desktop/platform/{platform.c => platform.cpp} | 4 ++++ workspace/tg5040/platform/{platform.c => platform.cpp} | 4 ++++ workspace/tg5050/platform/{platform.c => platform.cpp} | 4 ++++ 16 files changed, 38 insertions(+), 28 deletions(-) rename workspace/desktop/platform/{platform.c => platform.cpp} (97%) rename workspace/tg5040/platform/{platform.c => platform.cpp} (99%) rename workspace/tg5050/platform/{platform.c => platform.cpp} (98%) diff --git a/workspace/all/batmon/makefile b/workspace/all/batmon/makefile index a41672fd9..2d8a8f534 100644 --- a/workspace/all/batmon/makefile +++ b/workspace/all/batmon/makefile @@ -23,7 +23,7 @@ TARGET = batmon INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # Shared common/ + platform stay C; the tool itself is C++20. Compile the C # units to objects, then compile the .cpp and link everything through g++. -SOURCE = -c ../../$(PLATFORM)/platform/platform.c +SOURCE = -c ../../$(PLATFORM)/platform/platform.cpp CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp ../common/api.cpp CXXSOURCE += build/$(PLATFORM)/platform.o @@ -41,7 +41,7 @@ PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/msettings.h $(PREFIX_LOCAL)/include/batmondb.h mkdir -p build/$(PLATFORM) - $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) + $(CXX) $(SOURCE) $(CXXFLAGS) $(LDFLAGS) mv platform.o build/$(PLATFORM) $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: diff --git a/workspace/all/battery/makefile b/workspace/all/battery/makefile index 84884379d..bce505120 100644 --- a/workspace/all/battery/makefile +++ b/workspace/all/battery/makefile @@ -23,7 +23,7 @@ TARGET = battery INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # Shared common/ + platform stay C; the tool itself is C++20. Compile the C # units to objects, then compile the .cpp and link everything through g++. -SOURCE = -c ../../$(PLATFORM)/platform/platform.c +SOURCE = -c ../../$(PLATFORM)/platform/platform.cpp CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp ../common/api.cpp CXXSOURCE += build/$(PLATFORM)/platform.o @@ -41,7 +41,7 @@ PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/batmondb.h mkdir -p build/$(PLATFORM) - $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) + $(CXX) $(SOURCE) $(CXXFLAGS) $(LDFLAGS) mv platform.o build/$(PLATFORM) $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: diff --git a/workspace/all/bootlogo/makefile b/workspace/all/bootlogo/makefile index d91ce1b58..e62b41fc8 100644 --- a/workspace/all/bootlogo/makefile +++ b/workspace/all/bootlogo/makefile @@ -23,7 +23,7 @@ TARGET = bootlogo INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # Shared common/ + platform stay C; the tool itself is C++20. Compile the C # units to objects, then compile the .cpp and link everything through g++. -SOURCE = -c ../../$(PLATFORM)/platform/platform.c +SOURCE = -c ../../$(PLATFORM)/platform/platform.cpp CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp ../common/api.cpp CXXSOURCE += build/$(PLATFORM)/platform.o @@ -41,7 +41,7 @@ PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/msettings.h mkdir -p build/$(PLATFORM) - $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) + $(CXX) $(SOURCE) $(CXXFLAGS) $(LDFLAGS) mv platform.o build/$(PLATFORM) $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: diff --git a/workspace/all/clock/makefile b/workspace/all/clock/makefile index c8d56e08f..5dd8e3b19 100644 --- a/workspace/all/clock/makefile +++ b/workspace/all/clock/makefile @@ -23,7 +23,7 @@ TARGET = clock INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # Shared common/ + platform stay C; the tool itself is C++20. Compile the C # units to objects, then compile the .cpp and link everything through g++. -SOURCE = -c ../../$(PLATFORM)/platform/platform.c +SOURCE = -c ../../$(PLATFORM)/platform/platform.cpp CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp ../common/api.cpp CXXSOURCE += build/$(PLATFORM)/platform.o @@ -41,7 +41,7 @@ PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/msettings.h mkdir -p build/$(PLATFORM) - $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) + $(CXX) $(SOURCE) $(CXXFLAGS) $(LDFLAGS) mv platform.o build/$(PLATFORM) $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: diff --git a/workspace/all/gametime/makefile b/workspace/all/gametime/makefile index ac8154010..b5edb96a3 100644 --- a/workspace/all/gametime/makefile +++ b/workspace/all/gametime/makefile @@ -23,7 +23,7 @@ TARGET = gametime INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # Shared common/ + platform stay C; the tool itself is C++20. Compile the C # units to objects, then compile the .cpp and link everything through g++. -SOURCE = -c ../../$(PLATFORM)/platform/platform.c +SOURCE = -c ../../$(PLATFORM)/platform/platform.cpp CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp ../common/api.cpp CXXSOURCE += build/$(PLATFORM)/platform.o @@ -41,7 +41,7 @@ PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/gametimedb.h mkdir -p build/$(PLATFORM) - $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) + $(CXX) $(SOURCE) $(CXXFLAGS) $(LDFLAGS) mv platform.o build/$(PLATFORM) $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: diff --git a/workspace/all/gametimectl/makefile b/workspace/all/gametimectl/makefile index edbc1cc42..c5c098398 100644 --- a/workspace/all/gametimectl/makefile +++ b/workspace/all/gametimectl/makefile @@ -23,7 +23,7 @@ TARGET = gametimectl INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # Shared common/ + platform stay C; the tool itself is C++20. Compile the C # units to objects, then compile the .cpp and link everything through g++. -SOURCE = -c ../../$(PLATFORM)/platform/platform.c +SOURCE = -c ../../$(PLATFORM)/platform/platform.cpp CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/scaler.cpp ../common/config.cpp ../common/api.cpp CXXSOURCE += build/$(PLATFORM)/platform.o @@ -41,7 +41,7 @@ PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/gametimedb.h mkdir -p build/$(PLATFORM) - $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) + $(CXX) $(SOURCE) $(CXXFLAGS) $(LDFLAGS) mv platform.o build/$(PLATFORM) $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: diff --git a/workspace/all/ledcontrol/makefile b/workspace/all/ledcontrol/makefile index 79785bfc0..c5e72d9b6 100644 --- a/workspace/all/ledcontrol/makefile +++ b/workspace/all/ledcontrol/makefile @@ -23,7 +23,7 @@ TARGET = ledcontrol INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # Shared common/ + platform stay C; the tool itself is C++20. Compile the C # units to objects, then compile the .cpp and link everything through g++. -SOURCE = -c ../../$(PLATFORM)/platform/platform.c +SOURCE = -c ../../$(PLATFORM)/platform/platform.cpp CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp ../common/api.cpp CXXSOURCE += build/$(PLATFORM)/platform.o @@ -41,7 +41,7 @@ PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/msettings.h mkdir -p build/$(PLATFORM) - $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) + $(CXX) $(SOURCE) $(CXXFLAGS) $(LDFLAGS) mv platform.o build/$(PLATFORM) $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: diff --git a/workspace/all/libbatmondb/makefile b/workspace/all/libbatmondb/makefile index 0939d5644..1e5e34e00 100644 --- a/workspace/all/libbatmondb/makefile +++ b/workspace/all/libbatmondb/makefile @@ -37,8 +37,8 @@ CXXSTD := $(shell printf 'int main(){return 0;}' | $(CXX) -std=gnu++20 -x c++ - SYSROOT := $(shell $(CC) --print-sysroot) INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ -# The shared common/ + platform units stay C; the library itself is C++20. -CSOURCE = ../../$(PLATFORM)/platform/platform.c +# The library itself is C++20 and pulls in only common/utils. (It used to also +# compile the platform TU, but that object was never linked into the .so.) CXXSOURCE = $(TARGET).cpp ../common/utils.cpp CFLAGS += $(OPT) @@ -53,7 +53,6 @@ PRODUCT= build/$(PLATFORM)/lib$(TARGET).so build: mkdir -p build/$(PLATFORM) - $(CC) -c -Werror -fpic $(CSOURCE) -Wl,--no-as-needed $(LDFLAGS) $(CFLAGS) $(CXX) -c -Werror -fpic $(CXXSOURCE) $(CXXFLAGS) $(CXX) -shared -o $(PRODUCT) "$(TARGET).o" "utils.o" $(LDFLAGS) -lstdc++ mkdir -p "$(PREFIX_LOCAL)/include" diff --git a/workspace/all/libgametimedb/makefile b/workspace/all/libgametimedb/makefile index fa287508d..980361ebc 100644 --- a/workspace/all/libgametimedb/makefile +++ b/workspace/all/libgametimedb/makefile @@ -37,8 +37,8 @@ CXXSTD := $(shell printf 'int main(){return 0;}' | $(CXX) -std=gnu++20 -x c++ - SYSROOT := $(shell $(CC) --print-sysroot) INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ -# The shared common/ + platform units stay C; the library itself is C++20. -CSOURCE = ../../$(PLATFORM)/platform/platform.c +# The library itself is C++20 and pulls in only common/utils. (It used to also +# compile the platform TU, but that object was never linked into the .so.) CXXSOURCE = $(TARGET).cpp ../common/utils.cpp CFLAGS += $(OPT) @@ -52,7 +52,6 @@ PRODUCT= build/$(PLATFORM)/lib$(TARGET).so build: mkdir -p build/$(PLATFORM) - $(CC) -c -Werror -fpic $(CSOURCE) -Wl,--no-as-needed $(LDFLAGS) $(CFLAGS) $(CXX) -c -Werror -fpic $(CXXSOURCE) $(CXXFLAGS) $(CXX) -shared -o $(PRODUCT) "$(TARGET).o" "utils.o" $(LDFLAGS) -lstdc++ cp "$(TARGET).h" "$(PREFIX_LOCAL)/include" diff --git a/workspace/all/minarch/makefile b/workspace/all/minarch/makefile index 19f96c250..57ab7c40d 100644 --- a/workspace/all/minarch/makefile +++ b/workspace/all/minarch/makefile @@ -26,8 +26,8 @@ INCDIR = -I. -I./libretro-common/include/ -I../common/ -I../../$(PLATFORM)/platf # C and C++ translation units are listed separately. C files compile as C; # C++ files compile as C++; everything links through g++ so the two can mix # as modules are migrated to C++ incrementally. -CSOURCE = ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = $(TARGET).cpp ../common/notification.cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp ../common/api.cpp \ +CSOURCE = +CXXSOURCE = ../../$(PLATFORM)/platform/platform.cpp $(TARGET).cpp ../common/notification.cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp ../common/api.cpp \ ma_audio.cpp ma_input.cpp ma_runframe.cpp ma_cheats.cpp ma_core.cpp \ ma_rewind.cpp ma_saves.cpp ma_game.cpp ma_environment.cpp \ ma_options.cpp ma_video.cpp ma_menu.cpp ma_frontend_opts.cpp ma_config.cpp diff --git a/workspace/all/minput/makefile b/workspace/all/minput/makefile index 33d0c9dbd..2a59499b3 100644 --- a/workspace/all/minput/makefile +++ b/workspace/all/minput/makefile @@ -23,7 +23,7 @@ TARGET = minput INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # Shared common/ + platform stay C; the tool itself is C++20. Compile the C # units to objects, then compile the .cpp and link everything through g++. -SOURCE = -c ../../$(PLATFORM)/platform/platform.c +SOURCE = -c ../../$(PLATFORM)/platform/platform.cpp CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp ../common/api.cpp CXXSOURCE += build/$(PLATFORM)/platform.o @@ -41,7 +41,7 @@ PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/msettings.h mkdir -p build/$(PLATFORM) - $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) + $(CXX) $(SOURCE) $(CXXFLAGS) $(LDFLAGS) mv platform.o build/$(PLATFORM) $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: diff --git a/workspace/all/nextui/makefile b/workspace/all/nextui/makefile index 1ee600b36..90ba8bd67 100644 --- a/workspace/all/nextui/makefile +++ b/workspace/all/nextui/makefile @@ -25,8 +25,8 @@ INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ # C and C++ translation units are listed separately. C files compile as C; # C++ files compile as C++; everything links through g++ so the two can mix # as modules are migrated to C++ incrementally. -CSOURCE = ../../$(PLATFORM)/platform/platform.c -CXXSOURCE = $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp ../common/api.cpp +CSOURCE = +CXXSOURCE = ../../$(PLATFORM)/platform/platform.cpp $(TARGET).cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp ../common/api.cpp CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ diff --git a/workspace/all/settings/makefile b/workspace/all/settings/makefile index 81749221f..4f37494c6 100644 --- a/workspace/all/settings/makefile +++ b/workspace/all/settings/makefile @@ -21,7 +21,7 @@ SDL?=SDL TARGET = settings INCDIR = -I. -I../common/ -I../../$(PLATFORM)/platform/ -SOURCE = -c ../../$(PLATFORM)/platform/platform.c +SOURCE = -c ../../$(PLATFORM)/platform/platform.cpp CXXSOURCE = ../common/palette.cpp ../common/utils.cpp ../common/config.cpp ../common/scaler.cpp ../common/api.cpp ../common/ra_offline.cpp ../common/ra_sync.cpp ../common/ra_event_queue.cpp ../common/http.cpp ../common/ra_auth.cpp $(TARGET).cpp menu.cpp colorpickermenu.cpp palettemenu.cpp fnbuttonmenu.cpp wifimenu.cpp btmenu.cpp keyboardprompt.cpp CXXSOURCE += build/$(PLATFORM)/platform.o @@ -52,7 +52,7 @@ PRODUCT= build/$(PLATFORM)/$(TARGET).elf all: $(PREFIX_LOCAL)/include/msettings.h mkdir -p build/$(PLATFORM) - $(CC) $(SOURCE) $(CFLAGS) $(LDFLAGS) + $(CXX) $(SOURCE) $(CXXFLAGS) $(LDFLAGS) mv platform.o build/$(PLATFORM) $(CXX) $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ clean: diff --git a/workspace/desktop/platform/platform.c b/workspace/desktop/platform/platform.cpp similarity index 97% rename from workspace/desktop/platform/platform.c rename to workspace/desktop/platform/platform.cpp index 48091515e..4d3fac126 100644 --- a/workspace/desktop/platform/platform.c +++ b/workspace/desktop/platform/platform.cpp @@ -10,7 +10,11 @@ #include #include +// msettings.h is a C library header without extern "C" guards; wrap it so this +// (now C++) unit resolves libmsettings' symbols with C linkage. +extern "C" { #include +} #include "defines.h" #include "platform.h" diff --git a/workspace/tg5040/platform/platform.c b/workspace/tg5040/platform/platform.cpp similarity index 99% rename from workspace/tg5040/platform/platform.c rename to workspace/tg5040/platform/platform.cpp index bb095c321..baedc908c 100644 --- a/workspace/tg5040/platform/platform.c +++ b/workspace/tg5040/platform/platform.cpp @@ -11,7 +11,11 @@ #include #include +// msettings.h is a C library header without extern "C" guards; wrap it so this +// (now C++) unit resolves libmsettings' symbols with C linkage. +extern "C" { #include +} #include "defines.h" #include "platform.h" diff --git a/workspace/tg5050/platform/platform.c b/workspace/tg5050/platform/platform.cpp similarity index 98% rename from workspace/tg5050/platform/platform.c rename to workspace/tg5050/platform/platform.cpp index 3be958e90..279ac04b2 100644 --- a/workspace/tg5050/platform/platform.c +++ b/workspace/tg5050/platform/platform.cpp @@ -13,7 +13,11 @@ #include #include +// msettings.h is a C library header without extern "C" guards; wrap it so this +// (now C++) unit resolves libmsettings' symbols with C linkage. +extern "C" { #include +} #include "defines.h" #include "platform.h" From 0fe6aa5f8b6c980cea44430f029f9cd728fb2ce3 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sun, 26 Jul 2026 21:08:47 +0200 Subject: [PATCH 75/77] refactor: convert libmsettings (msettings.c -> msettings.cpp) to C++20 msettings is the settings-persistence shared library loaded by every process. Compile it with g++ (-fno-exceptions/-fno-rtti, -Wno-write-strings for the benign string-literal->char* helper calls) but keep linking libmsettings.so with plain gcc, so its dependency graph is unchanged -- no libstdc++ injected into a lib loaded everywhere. Verified on all 3 platforms: NEEDED list identical and SetVolume/SetBrightness/... still exported unmangled (C linkage), so every consumer links. - wrap the TU's own include in extern "C" so the definitions keep C linkage (else the .so would export mangled names and break the ABI) - (Settings*) cast on mmap() results (tg5040/tg5050) - explicit (unsigned long) cast to avoid a narrowing conversion in a braced initializer (tg5040 SetRawBrightness) --- workspace/desktop/libmsettings/makefile | 10 ++++++++-- .../libmsettings/{msettings.c => msettings.cpp} | 5 +++++ workspace/tg5040/libmsettings/makefile | 6 ++++-- .../libmsettings/{msettings.c => msettings.cpp} | 11 ++++++++--- workspace/tg5050/libmsettings/makefile | 10 ++++++++-- .../libmsettings/{msettings.c => msettings.cpp} | 9 +++++++-- 6 files changed, 40 insertions(+), 11 deletions(-) rename workspace/desktop/libmsettings/{msettings.c => msettings.cpp} (98%) rename workspace/tg5040/libmsettings/{msettings.c => msettings.cpp} (98%) rename workspace/tg5050/libmsettings/{msettings.c => msettings.cpp} (98%) diff --git a/workspace/desktop/libmsettings/makefile b/workspace/desktop/libmsettings/makefile index f525df7f9..0c91d4f9f 100644 --- a/workspace/desktop/libmsettings/makefile +++ b/workspace/desktop/libmsettings/makefile @@ -11,7 +11,13 @@ TARGET=msettings .PHONY: clean CC = $(CROSS_COMPILE)gcc +CXX = $(CROSS_COMPILE)g++ CFLAGS = -I../../all/common +# msettings is C++ but uses no C++ runtime; -fno-exceptions/-fno-rtti keeps the +# object free of libstdc++ so libmsettings.so still links with plain gcc. +# -Wno-write-strings: msettings passes string literals to char* helpers +# (touch/putInt); benign, tolerated elsewhere in the tree. +CXXFLAGS = $(CFLAGS) -std=gnu++2a -fno-exceptions -fno-rtti -Wno-write-strings ifeq ($(PROFILE), 1) CFLAGS += -pg @@ -23,8 +29,8 @@ LDFLAGS = -ldl OPTM=-Ofast -build: - $(CC) -c -Werror -fpic "$(TARGET).c" $(CFLAGS) -Wl,--no-as-needed $(LDFLAGS) +build: + $(CXX) -c -Werror -fpic "$(TARGET).cpp" $(CXXFLAGS) -Wl,--no-as-needed $(LDFLAGS) $(CC) -shared -o "lib$(TARGET).so" "$(TARGET).o" $(LDFLAGS) mkdir -p "$(PREFIX_LOCAL)/include" mkdir -p "$(PREFIX_LOCAL)/lib" diff --git a/workspace/desktop/libmsettings/msettings.c b/workspace/desktop/libmsettings/msettings.cpp similarity index 98% rename from workspace/desktop/libmsettings/msettings.c rename to workspace/desktop/libmsettings/msettings.cpp index d327a34d1..37e35c6ab 100644 --- a/workspace/desktop/libmsettings/msettings.c +++ b/workspace/desktop/libmsettings/msettings.cpp @@ -1,4 +1,9 @@ +// This TU implements libmsettings. Wrap its own header in extern "C" so the +// definitions below keep C linkage -- the .so must export unmangled symbols to +// stay ABI-compatible with every consumer (which includes msettings.h as C). +extern "C" { #include "msettings.h" +} #include "displaycal.h" // desktop diff --git a/workspace/tg5040/libmsettings/makefile b/workspace/tg5040/libmsettings/makefile index 4d546ef4a..51602fed9 100644 --- a/workspace/tg5040/libmsettings/makefile +++ b/workspace/tg5040/libmsettings/makefile @@ -16,13 +16,15 @@ CXX = $(CROSS_COMPILE)g++ CFLAGS = -I../../all/common # displaycal is C++ but uses no C++ runtime; -fno-exceptions/-fno-rtti keeps the # object free of libstdc++ symbols so libmsettings.so still links with plain gcc. -CXXFLAGS = $(CFLAGS) -std=gnu++2a -fno-exceptions -fno-rtti +# -Wno-write-strings: msettings passes string literals to char* helpers +# (touch/putInt); benign, tolerated elsewhere in the tree. +CXXFLAGS = $(CFLAGS) -std=gnu++2a -fno-exceptions -fno-rtti -Wno-write-strings LDFLAGS = -ltinyalsa -ldl -lrt -lm -s OPTM=-Ofast build: - $(CC) -c -Werror -fpic "$(TARGET).c" $(CFLAGS) -Wl,--no-as-needed $(LDFLAGS) + $(CXX) -c -Werror -fpic "$(TARGET).cpp" $(CXXFLAGS) -Wl,--no-as-needed $(LDFLAGS) $(CXX) -c -Werror -fpic "../../all/common/displaycal.cpp" $(CXXFLAGS) -Wl,--no-as-needed $(LDFLAGS) $(CC) -shared -o "lib$(TARGET).so" "$(TARGET).o" "displaycal.o" $(LDFLAGS) mkdir -p "$(PREFIX_LOCAL)/include" diff --git a/workspace/tg5040/libmsettings/msettings.c b/workspace/tg5040/libmsettings/msettings.cpp similarity index 98% rename from workspace/tg5040/libmsettings/msettings.c rename to workspace/tg5040/libmsettings/msettings.cpp index 9b1c11edd..f92585c06 100644 --- a/workspace/tg5040/libmsettings/msettings.c +++ b/workspace/tg5040/libmsettings/msettings.cpp @@ -13,7 +13,12 @@ #include #include "displaycal.h" +// This TU implements libmsettings. Wrap its own header in extern "C" so the +// definitions below keep C linkage -- the .so must export unmangled symbols to +// stay ABI-compatible with every consumer (which includes msettings.h as C). +extern "C" { #include "msettings.h" +} /////////////////////////////////////// @@ -344,14 +349,14 @@ void InitSettings(void) { if (shm_fd==-1 && errno==EEXIST) { // already exists // puts("Settings client"); shm_fd = shm_open(SHM_KEY, O_RDWR, 0644); - settings = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); + settings = (Settings*)mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); } else { // host // puts("Settings host"); // keymon is_host = 1; // we created it so set initial size and populate ftruncate(shm_fd, shm_size); - settings = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); + settings = (Settings*)mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); // peek the first int from fd, it's the version int version = peekVersion(SettingsPath); @@ -1212,7 +1217,7 @@ void SetRawBrightness(int val) { // 0 - 255 int fd = open("/dev/disp", O_RDWR); if (fd) { - unsigned long param[4]={0,val,0,0}; + unsigned long param[4]={0,(unsigned long)val,0,0}; ioctl(fd, DISP_LCD_SET_BRIGHTNESS, ¶m); close(fd); } diff --git a/workspace/tg5050/libmsettings/makefile b/workspace/tg5050/libmsettings/makefile index 804df7d52..348b8a2b2 100644 --- a/workspace/tg5050/libmsettings/makefile +++ b/workspace/tg5050/libmsettings/makefile @@ -11,15 +11,21 @@ TARGET=msettings .PHONY: clean CC = $(CROSS_COMPILE)gcc +CXX = $(CROSS_COMPILE)g++ CFLAGS = -I../../all/common +# msettings is C++ but uses no C++ runtime; -fno-exceptions/-fno-rtti keeps the +# object free of libstdc++ so libmsettings.so still links with plain gcc. +# -Wno-write-strings: msettings passes string literals to char* helpers +# (touch/putInt); benign, tolerated elsewhere in the tree. +CXXFLAGS = $(CFLAGS) -std=gnu++2a -fno-exceptions -fno-rtti -Wno-write-strings LDFLAGS = -ltinyalsa -ldl -lrt -lm -s #LDFLAGS = -ldl -lrt -s OPTM=-Ofast -build: - $(CC) -c -Werror -fpic "$(TARGET).c" $(CFLAGS) -Wl,--no-as-needed $(LDFLAGS) +build: + $(CXX) -c -Werror -fpic "$(TARGET).cpp" $(CXXFLAGS) -Wl,--no-as-needed $(LDFLAGS) $(CC) -shared -o "lib$(TARGET).so" "$(TARGET).o" $(LDFLAGS) mkdir -p "$(PREFIX_LOCAL)/include" mkdir -p "$(PREFIX_LOCAL)/lib" diff --git a/workspace/tg5050/libmsettings/msettings.c b/workspace/tg5050/libmsettings/msettings.cpp similarity index 98% rename from workspace/tg5050/libmsettings/msettings.c rename to workspace/tg5050/libmsettings/msettings.cpp index a8ddea691..15bbc1d25 100644 --- a/workspace/tg5050/libmsettings/msettings.c +++ b/workspace/tg5050/libmsettings/msettings.cpp @@ -12,7 +12,12 @@ #include #include +// This TU implements libmsettings. Wrap its own header in extern "C" so the +// definitions below keep C linkage -- the .so must export unmangled symbols to +// stay ABI-compatible with every consumer (which includes msettings.h as C). +extern "C" { #include "msettings.h" +} #include "displaycal.h" /////////////////////////////////////// @@ -195,14 +200,14 @@ void InitSettings(void) { if (shm_fd==-1 && errno==EEXIST) { // already exists // puts("Settings client"); shm_fd = shm_open(SHM_KEY, O_RDWR, 0644); - settings = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); + settings = (Settings*)mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); } else { // host // puts("Settings host"); // keymon is_host = 1; // we created it so set initial size and populate ftruncate(shm_fd, shm_size); - settings = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); + settings = (Settings*)mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); // peek the first int from fd, it's the version int version = peekVersion(SettingsPath); From 9578caa9b4996a4e7f46978e4a7fc5ab61677622 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sun, 26 Jul 2026 21:13:30 +0200 Subject: [PATCH 76/77] refactor: convert keymon/rfkill/poweroff_next daemons to C++20 The last first-party C daemons. These are standalone binaries (not the shared libmsettings.so), so linking libstdc++ is fine and consistent with how the tools link. - keymon (tg5040/tg5050): compile with g++; wrap in extern "C" so libmsettings' symbols resolve with C linkage - rfkill (tg5040): compile+link with g++ - poweroff_next (tg5040): move the tool TU from the C compile to the g++ one (the makefile already linked common/utils+config as C++ through g++) Builds green on tg5040 and tg5050. --- workspace/tg5040/keymon/{keymon.c => keymon.cpp} | 4 ++++ workspace/tg5040/keymon/makefile | 3 ++- workspace/tg5040/poweroff_next/makefile | 8 ++++---- .../poweroff_next/{poweroff_next.c => poweroff_next.cpp} | 0 workspace/tg5040/rfkill/makefile | 5 +++-- workspace/tg5040/rfkill/{rfkill.c => rfkill.cpp} | 0 workspace/tg5050/keymon/{keymon.c => keymon.cpp} | 4 ++++ workspace/tg5050/keymon/makefile | 3 ++- 8 files changed, 19 insertions(+), 8 deletions(-) rename workspace/tg5040/keymon/{keymon.c => keymon.cpp} (97%) rename workspace/tg5040/poweroff_next/{poweroff_next.c => poweroff_next.cpp} (100%) rename workspace/tg5040/rfkill/{rfkill.c => rfkill.cpp} (100%) rename workspace/tg5050/keymon/{keymon.c => keymon.cpp} (96%) diff --git a/workspace/tg5040/keymon/keymon.c b/workspace/tg5040/keymon/keymon.cpp similarity index 97% rename from workspace/tg5040/keymon/keymon.c rename to workspace/tg5040/keymon/keymon.cpp index 0cbf6965b..831f4ae4a 100644 --- a/workspace/tg5040/keymon/keymon.c +++ b/workspace/tg5040/keymon/keymon.cpp @@ -9,7 +9,11 @@ #include #include +// msettings.h is a C library header without extern "C" guards; wrap it so this +// (now C++) unit resolves libmsettings' symbols with C linkage. +extern "C" { #include +} #include #include diff --git a/workspace/tg5040/keymon/makefile b/workspace/tg5040/keymon/makefile index c2752ebd2..6e2e5208a 100755 --- a/workspace/tg5040/keymon/makefile +++ b/workspace/tg5040/keymon/makefile @@ -10,11 +10,12 @@ TARGET = keymon PRODUCT = $(TARGET).elf CC = $(CROSS_COMPILE)gcc +CXX = $(CROSS_COMPILE)g++ CFLAGS = -Os -lmsettings -lpthread -lrt -ldl -Wl,--gc-sections -s CFLAGS += -I. -I../../all/common -I../platform/ -I$(PREFIX_LOCAL)/include -L$(PREFIX_LOCAL)/lib -DPLATFORM=\"$(UNION_PLATFORM)\" all: $(PREFIX)/include/msettings.h - $(CC) $(TARGET).c -o $(PRODUCT) $(CFLAGS) + $(CXX) $(TARGET).cpp -o $(PRODUCT) $(CFLAGS) clean: rm -rf $(PRODUCT) diff --git a/workspace/tg5040/poweroff_next/makefile b/workspace/tg5040/poweroff_next/makefile index 4c224765e..f1a9029a6 100644 --- a/workspace/tg5040/poweroff_next/makefile +++ b/workspace/tg5040/poweroff_next/makefile @@ -20,9 +20,9 @@ include ../platform/makefile.env TARGET = poweroff_next INCDIR = -I. -I../../all/common -I../platform -# common/ utils + config are C++20 now; poweroff_next.c stays C. Compile the -# tool as C, the common units as C++20, and link through g++. -CSOURCE = -c $(TARGET).c +# poweroff_next and the common/ utils + config units are all C++20; compile them +# and link through g++. +CSOURCE = -c $(TARGET).cpp CXXSOURCE = ../../all/common/utils.cpp ../../all/common/config.cpp CC = $(CROSS_COMPILE)gcc @@ -38,7 +38,7 @@ PRODUCT = build/$(PLATFORM)/$(TARGET).elf all: mkdir -p build/$(PLATFORM) - $(CC) $(CSOURCE) $(CFLAGS) + $(CXX) $(CSOURCE) $(CXXFLAGS) mv $(TARGET).o build/$(PLATFORM) $(CXX) build/$(PLATFORM)/$(TARGET).o $(CXXSOURCE) -o $(PRODUCT) $(CXXFLAGS) $(LDFLAGS) -lstdc++ diff --git a/workspace/tg5040/poweroff_next/poweroff_next.c b/workspace/tg5040/poweroff_next/poweroff_next.cpp similarity index 100% rename from workspace/tg5040/poweroff_next/poweroff_next.c rename to workspace/tg5040/poweroff_next/poweroff_next.cpp diff --git a/workspace/tg5040/rfkill/makefile b/workspace/tg5040/rfkill/makefile index 55c8ade45..b0cecbb32 100644 --- a/workspace/tg5040/rfkill/makefile +++ b/workspace/tg5040/rfkill/makefile @@ -5,10 +5,11 @@ endif TARGET = rfkill PRODUCT = $(TARGET).elf -CC = $(CROSS_COMPILE)gcc +CC = $(CROSS_COMPILE)gcc +CXX = $(CROSS_COMPILE)g++ FLAGS = -Os -lrt -ldl -Wl,--gc-sections -s all: - $(CC) $(TARGET).c -o $(PRODUCT) $(FLAGS) + $(CXX) $(TARGET).cpp -o $(PRODUCT) $(FLAGS) clean: rm -rf $(PRODUCT) \ No newline at end of file diff --git a/workspace/tg5040/rfkill/rfkill.c b/workspace/tg5040/rfkill/rfkill.cpp similarity index 100% rename from workspace/tg5040/rfkill/rfkill.c rename to workspace/tg5040/rfkill/rfkill.cpp diff --git a/workspace/tg5050/keymon/keymon.c b/workspace/tg5050/keymon/keymon.cpp similarity index 96% rename from workspace/tg5050/keymon/keymon.c rename to workspace/tg5050/keymon/keymon.cpp index 5135397b3..b79d94ade 100644 --- a/workspace/tg5050/keymon/keymon.c +++ b/workspace/tg5050/keymon/keymon.cpp @@ -9,7 +9,11 @@ #include #include +// msettings.h is a C library header without extern "C" guards; wrap it so this +// (now C++) unit resolves libmsettings' symbols with C linkage. +extern "C" { #include +} #include #include diff --git a/workspace/tg5050/keymon/makefile b/workspace/tg5050/keymon/makefile index c2752ebd2..6e2e5208a 100755 --- a/workspace/tg5050/keymon/makefile +++ b/workspace/tg5050/keymon/makefile @@ -10,11 +10,12 @@ TARGET = keymon PRODUCT = $(TARGET).elf CC = $(CROSS_COMPILE)gcc +CXX = $(CROSS_COMPILE)g++ CFLAGS = -Os -lmsettings -lpthread -lrt -ldl -Wl,--gc-sections -s CFLAGS += -I. -I../../all/common -I../platform/ -I$(PREFIX_LOCAL)/include -L$(PREFIX_LOCAL)/lib -DPLATFORM=\"$(UNION_PLATFORM)\" all: $(PREFIX)/include/msettings.h - $(CC) $(TARGET).c -o $(PRODUCT) $(CFLAGS) + $(CXX) $(TARGET).cpp -o $(PRODUCT) $(CFLAGS) clean: rm -rf $(PRODUCT) From 1e9bfa595e3d44a91378edba63b3fe8d40569562 Mon Sep 17 00:00:00 2001 From: Christophe Vanlancker Date: Sun, 26 Jul 2026 22:54:12 +0200 Subject: [PATCH 77/77] revert: keep tg5050 SUPA ppu affinity at upstream 0xc The C++20 migration PR must not change behavior. Commit 8f873ec8 had slipped in a tg5050-specific crash workaround (supafaust_thread_affinity_ppu 0xc->0x10, the #785/#784 fix) that belongs in its own change, not this migration. Restore it to upstream's 0xc so the PR stays behavior-neutral. --- skeleton/EXTRAS/Emus/tg5050/SUPA.pak/default.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skeleton/EXTRAS/Emus/tg5050/SUPA.pak/default.cfg b/skeleton/EXTRAS/Emus/tg5050/SUPA.pak/default.cfg index a60c7e36d..4a77a7b31 100755 --- a/skeleton/EXTRAS/Emus/tg5050/SUPA.pak/default.cfg +++ b/skeleton/EXTRAS/Emus/tg5050/SUPA.pak/default.cfg @@ -1,6 +1,6 @@ -supafaust_pixel_format = rgb565 -supafaust_thread_affinity_emu = 0x3 --supafaust_thread_affinity_ppu = 0x10 +-supafaust_thread_affinity_ppu = 0xc bind Up = UP bind Down = DOWN

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

Zf0Q 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 ){Iz>%MURnrrfO;|)=AL@Y?+e6bQv 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

~>Mf}|fqh-s=A?#~1h(;6v& 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 diff --git a/github/minui-menu-md.png b/github/minui-menu-md.png deleted file mode 100644 index ceac27a7f233801d75f11e30fb072a8c24babebc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 42366 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 diff --git a/github/minui-menu-options-controls.png b/github/minui-menu-options-controls.png deleted file mode 100644 index 03a7a5a10ca76e1b2ff9e36a8cde120b61b2d7eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16473 zcmd_RWmHse*f%-|f`Oo@AZ-vzN;gPIcQ;5k!qBY<$R7de5)kR38wMDVuAw`nVThrI zj&u9`-?QHLobx=-hj*QIzMTDqwU}9Z_P+OZU)Qg8sIsEegL`E6AP~p{8EFYs2;^1( z1cLSF&MojCc!gXA_(SUQUfV^@(Za?3gR?nA)XdSu{JD(%2TOBR^ABd8PTl5$5QxZy zjD)DV$Mp6bp_QH`;*W3D)|?heIeM&N#r(+~b)8!p3EPsZYecu%_3+pwEI1?#oy%H~ zwCpo4*d2o>zkBYKHrj^tF9owqzBn{V>2D`U4Wra86}K!E_b!uNZztGkzxQU+GbQZl zwA^UTCkEEV@Lk2)Z6&|iPNjZ6e*S1?DOE%|pUcYO`Vf@r&APkafM{R|BVx)gU1gyIKf!K*d@5xE&)GM@F*e^P3^On=U}R)850lMS4GauC zrzXRC=J82mbWH!vzu&>wH~E|$G?(BqEgY||uGZDnrSLfBj99zMlHucq6ce;BJKcJ_ z_jy`g3)+5{&0xgp9MT{eZ7dT+`=Z*B@#c=%b@;-0|1|tnQsS{#N8GfDYe!xYQ#UG7(@jV>m+3eqW^))x2nh&w zUFnL#E#f16yGOA?wT3e1JkTZKOus`m6fe@u=lr}p6|+wE7V`7ApvT_x(hAMUcLTmL zGZmJEq;DY*%~TO|p~`^5^#{Zji9sd!&;QE@neIpT!3i-A2&9zxS4d_B^?>l%@?$RM zIUU&_ii1oL$f)vyo-hAV@<_}2{cB3UX}sq9TeQiLsu8bBS2wrn(c#6##jvJ^JVUv+ z5uM9tK7PCI(5gI{qFyO3T_5Z#>`s$Tu?%JIltw=H!_;2%6DpF?UlK1L`El7TyoL&J z94>z2qj!Ez6fU{GwpM;pemo$QB#-M)F$z71JOGsu78Z6E;%V>zjlK;D7ai8;*fM}u zm|gQ7%zrh6URQW>Ra}UQkx_K6d@5r?oVQ@jQwe z={1Gc{`VUX1_zZ7kY?}yz3fLEi?5$j(mp2h@P1cPcaA}=;Ki^@S#m@ZJusk*Hq#}R z>F2!IFElHQ-|CFU?Y=ictsrOZ)tAtapT%n4+XQ&k+7Mh~@D}Dxv5b#C`{P z{~Pt^Z~5v}VlVRz+e`*1ejlD)UKQ${d9Y||YI65COG>Icw)G@1#t}qqZEU<2=wwOg zO){bpCV(Kj8?Yz)WRb#Vp_ywtGSP*3QM`yMKRX!>S~)7Pe8ZGyC4A0Ogv;gl=;#J1 z)eoMwafEfTk?ZZlS}&-xm)~P06prd=U8ty+lnY_+A_kdPdufbtE7aP2)Yy$7$n17Y z!_Q+eZ7Lj3#}8@Wv*`V#(r0#>pb9`Lw%hb{R)6Ps+xy(JlMTfps?V}nWxG`Incz=ZfgaEu%7d^qh= zib#A_ag1I-BV@qt9vK-qXEBuVd>ks_Xv7*mC7-|7Ze$o6!y%MgRW;^)&KRGNkS^%S zE{qsTXEGx4uDy!!KclaA+Zn!FbCvTU0P>CQWHUD%HSzoB46=67ck%k#@5+)cMkaT} zB9b1-^-#`a8?UsEkSQ-FddD(>%>x07q{eY`y-kMHKc{is^X*wXlTc`92# z4%?CN%W<$-Gznae4=S*X@Z1{GJW=E6&cN)n6SrywV@`7GQ`VzzSxJKRxhN7ne<2ay zNw<*_W_BBM%8SWalUAikW4-LOw`KB7)vsBbE3U|{7jkBIx>U7a;-Cgeo`<-&aknQDIL zJD4{QQbLNLKK>~UC7a_}m4t&YN7=Og09zouyUs^&;+dW2z5Fj4op@PYHPSDanrE;r zZZSiDIBq(;!8Oo<-Kx9PG9*#zO%qy(?qWV%rR+tJKsXtEA4etmqKrOsbgO8%D{t|l z78Vm)EBoVDzP|ay(ZE``wt@57kDXh<|Mo=UIwVpEuz$?=Ff{#Z$*e(Aa`J%?bA|Jg%hI3UfqqR! z183YPMRo!l9BLl=KiRM#dt|=pm;0f~!Nml1B@_ZwBaC`Epw&O~@D4b}fi%ZVMOq?x z$)?Gjb?VSX2vsa?g=KW4mezwCf~J*mqCbqfUr1Ic*j!mwuaP(bxQ}NkDew6wH| ziOQ-fW)>FIS!V=g!5S}lIE)03km?B075(}`_f$GX!O^kA>(L#Y{&W$gK!_C)D5pua z$*xad6YwXu9}{fjZ=AhChbM0K9!ZVFP|NF{6Pl-jI<`@m8fS9DY-#8itx3a|%cV(Z zY32B$sq$U3w7q{(%#*}(dL1w8c)k$TmHj>z-=s_B@BbqL>1E+pGD;G_jWvi*L&kUf zq8`7U;b{P}cpKE9cK}bxgOpYTjhNi2OJT>K`aqU2b(L(~AemZbx;ByT?plYdcFoSn z`fYPZL8*LbK670&miiaa=JkJ>X5M(3n20rj(Qe2cDe;m>*gX0*uP}njh$E@5&5`?` zd$<#7WAC1qMvV(zoL^sEM68N<9d(&U$wnSs=t^V`MMXWTfNfz35Zl^UQT+}H4nAcc z%>~o7918il&*WcK`1roe2jpm}dfKA!9ox!#E0XsiMJZc3b~O}dgqS#GQ@=AE36#^2kLK&< zi7`jhF$mn#{S2SV++u^=7qUDEl<7_3XSLZ+O2BmushG0PKM}(-=JVO&$`wiG9uPT| z9VPc2Nb&JG$loMn^kY|C{+YA!S<*hqz;mM5Am)acIuH}6&7{da&}GIBwIwDY0dvi3 zoai2MKm>YKCE2oA>c`AALAXdpNjVnBHlb2JRcLtVwpN|yc>GW1JmS~ERjiV|g+<5p z*zG&bR)T8}r0et*iI${kUb1Q6WtD4vW;KA1URSs!MO?0Q6&uvk9OR$}yWGBSy8;pph-l8nP7l@FTpnJE3-%Wvq_C;cnerM9~Xt~E4soZ|Us#x}h#IlcbR zZf``rtr|ZI|)|HzSH=`K@>`(NWZqWc0hRO5SDfx91=3tZlQ4s z#_vjy=LLFl@)@=JtKqxFKe_>YO%7WL)D(K%ZRUL1L^z@eA?pUf>^y=X)bjXgU%dtM z$-2iGTX4_-$9+bwbPdrKjEGlXJHArwh(Xi}z8t%w}&I9k?w!U#O~aC3hG0 zFv;4mJH|y{q_$OFV~#}Tz(!N1hXT%TR;NG<`hH5U*%{VdnQ?R9!--db^m51le7%kp zv20~lrP>ss?DmMT@~?*Qzjfrb$#G)YFgWo$0lwU{P_pima^beR+tb%4zvz@Po`Mb8 zd-)G#q!6GVotwYi332DC@;28X$^*Jqw?-9dh~8Aaeh3gZ20`TY7a-YI*4@7$@E4>S zSU-d|r5qyeAf<$N&Dh@<(F@V1Aah1GXLc9H-0zCII-Wd1dj=k@oB(P2zUkMTC>9^MP0SeMfk z7!5MMZjM9wUn3%HF=eMFJ5%DI+3 zZ0aRUkKpPF%l~=5f7eoKZf^3?V2FCKgCxJb<{Se{PU21d8LBMc^6Nv2#LFlj;S%TZ z!}Wo!O4B8t$9h$sZ=Y4>w#QGLpcmYkZibRo!_-lN!os_?pI3Tby?W)vn@A-<9M-X+@#61LI?(Z~T1$oeR_nO0qe>-SK!jK4865 z!!=F<^UrNFy2u3@iKV^47elR$H_gjxGnL4S{w44O&_6H4?#VdTDX1nuV5t?hxR7Bz zc`*>X8yhFAXH^}~ne1ZZ={RaEoSal#=`O}Qe)fYtj#VX@;;70?FySM|EA&`Y`POw(q_AqjB< z=jP_B=6&vC@6FY_^AHyru&T4}L_T=)Kb!Uhi(x~pEiywqgpQ7Gv@hz>E-o(CGljMM zl64ZHy4myAV8tK2D)q?!wLup*cxeA%H!_3!&1VN2b#JCFOY?(E=*SUIplWRBMq(&9 zHm1FU3x1C1m-*lLL8JVl1M3KqaVPErc2OadDz`akE<9z!k+LQAy6dIu2kmQsr*#sX znKte6-^0xorVmMvG}bp3Ut`ts0iF?bOq{!i_y}0S`R7~iFEiX~5ufbYIXOoc7D}L+ z99xa9TjTL|EH6r{sx-`*0h8cyoZsHq_$XgO`xDmurgN%ovu$=(|N6tc{gB$i-d-tu zvhZG$%Vu=LYr|KUzd<`rcV0&AY{hl6tNlXvB>d3AvU+Fer|@C%Fi3U%Q=Ef?@KKM` zaG)+S<@0Fjd-!+Nuv-Gyga~hCnAu?my)XGN*wJ1&G#bYO!TYm1!VbMs1E#&oYA&Lg z!R4UIGD-(Kp+?_yv(}g$_K~!Ap6QN9@trHa@Qs>`E|QHe^p2Kejuxz~7&*%&q_yTI znOf-oVeJ{dzSR@Qc&uoV#33knIc-~FjyAV`2?@_{=WG2wE4G$!)7S*#PH51{hMgx6 zslQ+!@p0B%auNG~w$(>`|F+fn_Y98A-SEPJ!#D^8*+=vwGbA%2vN3i{)|DgPpbfj| zzwN2v>p*hRWAWl86Cj(pvAht^P=5OifBO#S4%$!{vr4@VC4^4dxzScQZ=oIc56cve z&xr9W@$NL|sr^>oyF5D#jk(*I{>N8z#knqN0jYm8vvu&fMB*^j?x}w_>Ww|tt+y!2 z=MSIxxWDz}pQ=o9SjF4QC(JF@uWMl?Gr?u^lxxSQ|%1NU;6p~@qh3njX3R^(D}o|fc=KbQ^^iVTwL6h?-HiG zRQaZ5ll`dzB3Df!m@AH*A$59f0k`e%H^kTeEck(tZ|jc?gyH)tmm=-f_uQlJp)YDK zu6NPbyPIl6ITjc6e{Qs{J0qz_o;-(`>OqY{5k*pZ)^}Nf$iz!=eT7_z!Q+`}3iKZn z!v}k5#%9G)a>>bgp~qye|HghjH{DNGjnfD}hm{P+*e(VXXR|-$PfCU=#|4Cc?G53{ zHFbv>7kSfy(JA$}Zn5^-2Y2J{;@s*rV(#@P_mw(0yNqMhx);;}C^xOpTs4oqt?lxB zR!%I^qVD~(r;F7J>K1!*zhRl^rKKf+!wh{fV-hbH**~5i2qbXS$O$Vkl#4hcE-u$P z4Ni`ZXBIEm?#k{(Ee745c_j(@%NU{RqPk zTD+NAn^V=$&`_GuQ7s9Vi|gw+S$k)r2nxRP(~$Nh#T|m;;$jD*SHc*|v&~0oG4F}+ z_cn0U-<8+E1QbBG$um;Av@kI@Z+EJ?I6)^c_w@2(3fd?36DWNWP_LnLq|(>xW=9`K z*+m*ynGPA@fax0 zM@g^z4#WdI1R3@@3o7N{QM**D-vM!RyKwek*sD^KysMCB@p@g1fQ zYS|ky^o`Ne*LUf6y1L#=)-v>bKM*@%lf$Ht zJ7RBdzq7Lw@3-CG-#=mKt#Dm%9Xn>|f90yfkM9GT3%j$5*wy5?jvQpQOKl zS;V7YZ-OBBx87FIUyIBb%>^gPTdc~3Fe2iprYix&IHKRITRcf4TZTv~x|Mzpt<1 zuTB|l4&{>4{3}L@hY)DEE2;1jt&wZc|6>$g#VXIXf7NTUL>}2WHl}}uLcPZ^277V# z%ZVl_hfDCHp7+-f(lHpLGT{sE!1SxCv{!7WN#ZLN6N!g}hw)n@h^h}J=Ut4BxfM2B zb?qdia(Tzoi7#$_q^vveH_*B9qa!-N3||5^#2=3u{r8dHRQzd|Ut}VwZ=tUI=qVPRpUj5T}XXinkgi$)Y$us=?_Ck1@ z6;kqtBF#~FTE4ohyLkdUmoz*MXTX=;GL6>)(KW~fG%S`CYAufGu5Et;+`#r_UAo8f zHGa2&7o&`cGe-9q#&bAAKts^NY}s+!;%Y&o$Y4d0b2B4}dHH2!Y#c9gM3rq_L|dVK z9*HGKq9R24m@zdc6szLYL><_4NsqOR8kx_7u;nVbZz^fFQb-+I#RIp#pZN@;(x3KZ zz81y(#$4lEvLraL?ax9B@aS-0YJ`u)V59em1E$_0tImQiO1e!x0<=1N2MwP+bn@W5 zayvRPdjig9-%9%wR7XqQ)kzJb5E0U6Bj3Aj*wE_A!|?8>^N38)abWH{2dlm0uGbmt z*Ob?TWEE-THQc0uy?xJjxFD8ynt`;qvGF-r3!2`CxlS-dZ>4DY@3j7;iQe4v0gvh* zzd7k!X?`$CZ*T8yZ9CNYs0F`kHr-CpG0(imaz{8he<6%PraF~Bf$R#C=T{FZDZc>_ zHqdDqeLMC1{lgre{4KTS$Dy8e`u!KnKWP&;CmI_YyUm8nTWpgifO&wZ>eP{D*}Ad> z-GMLD@jS)Ow%DyRrEr6|RX>b-Ade@arZ@vI1iEF__twXZttZ0kErST7T zmfMBS(!bSiy=8bu!pZO!vlx34hl$g@YZ1{}*w;3+uSf;$OE}{v3-3_U^;ec&+qn2V zs<)*;Atkq&RJP34TT!+$0P4K4?guol{>#qidN~$nxmtgoR`+}=?7ijBKAc2eVW~VC z;n^l11;A_uqomkF~Nj-xHrr3kZW^+GuBH{Nl8v)EFB22XJ?*rA$1KG zz_U>$<&dUdkY{0L);RJmV~~Mg*G!zTjO7B)#$#jf#Ubf(-0eStSkIn%gwnlx54LBS zJDrG>a~DUYL5R?CjAg}CGZ_X5x@_oOW{ew9EHn#vcTt94^7CPl=se4Vxj(z? z4+B)hiHZRrFFp!3-Y|91(WkJg7pMT^P6t0lo{^A0ht2&#@m!{KLalh`9X;|+g{Wxt2WIxxt z@XukwSklxceSol@)s#nIFqqe)X5{T%f8FgB8;%eX5|S|b#R`UkCWY6%pz7-C&;`Z8 zC%ZX0IW#A$XZT2|2cfx?%3Q@*rjM_uPA=3L5}Q{9zzvwJ$OYMR?vtIKxj5ijwwTsfUbq@<%s2V_=V#YAE>KZX&0nf{ zO3jl4_W)6qzHNVDO`c8y`AOOq(U}Is*5xDMH~?`ycKYp^Mfqs37Z}Gztw3qjum+&$ z&=YG?5s0ICsnRs6HY(2_ZtQGP0*lSbdLvGGs->|IJNArt=K=V|_?u}ZtY!M;O2Pn1 zT0Vy(d?5x7^w7xd@8_qY_*<+@ozo&3Scc!tLkS9nkTS zk;C(3@GRTg-wWLU5BoR{knX7}+X-7+76W+Jx{=>{dGZ@M4kPu8R{vE$@}Z_yqv~%< z{LDVE2fHC`IKPcQ`uOOtw_RObRXza98x@KKYA)*^?cnG*aftotU4EeHv0*i@c?EgU z>;NpOoYRY!|7z$6s6p}9tx+eE@w-gj{$uIo(_lxH=Vb97z!MLI-_Q+)j@P%39JPqW!mzq^?)g#lMAr1i9W`%lC~gm z+4hhhAlxPJqL!nL8g??jTVRvp`2x7YzqH~%GD6oxKogb4uRb!BYa25d1S^A@@QU`Z z8_ya|WcR$!D#L+_xt?8ZkaZVMfb-t^j+MC&yw%XJ>@v?r=6nI}SmM#3BmHeWm?l1B zw8a;_l$f%9=qYDiR5Xt5z!0aZ(xBbnA5dKVo|A0M`Z1ZJrDg6pdzaRGcVW5RlxrG= z<-ZEY^N{K@F2L*G!1fo^-0+xvi?7kOJ zyt$x2*cPe)b&);d4V2()wP`aqfvw&S1aZ20-*$ey%*`8g!N0uTFJBKf_^{9M)&vHO zy`1Q7v$b*Q^SpY0@r>^)Z8K0T4Wiw45hi%y$JL%VjFytGs*;dMgX9e#7gu)rA{ReD z?4(^EFPyfN!`RQqav*K>m+;@JNMJFrxzVYYm-2Hq1A;FReDu=z?c`h|*-k2&C`JM=d(PUAg6ip>3B^?sKH%c$e$th9scgc=MCl15X^jUJR`JI;9 z;4g#N*`Vg3bO?{PNjgb)Q${7b7Ko-3`mHOF8}=Ts&MWQnq>m z95z^_l41i>*b#KZjFRl08BorrE_60_Nfc0Gz{ySPNu!h2=(YmPC(zILUK)g3eEOHVDCd`zG} zVDjf@Px%WYEs4sO)_op#*QH8m4{D3d|8tAy2&8l*JddS{>wC z7pJDCj*pK4O;K4_y%f0I_Yh1Um{}MyS24Z2ji05O9~T#wL}E{o-R-HFpyzK1kR(s=6|HQ@1)5WO9X3v;9IP|O1K{$gy)!^xu%WxI> zH8O-WtrZ_yup2kp1BinTBkKi%rH$12JgR~z`N~6+dD?1^c;WP7IU+sG9ExryFraj1 z+5?K-sn)k?&m_9$;|&zb%l@y3=H=x@W2-ap{_}5%mnznH;bw1V27T2OQVW*K1%|BD z8%y=$-Ha-)?5jwlyI>?>6aW>q^ZnwU*Ff9psYiZC0ul**gl30 zq%3M`#`Beb?tK{bx^4%HjK^RY&BpmR0*$kg;m3Idsm^=MV@l8Fwfc-{nm1TX zd@B`z49K;rP*dHXEomnc*B1lnWU)fmnwx#9N7<;XyW;aO{w9zO$%cWr#3m7{VY~n8;)GJm<7gx5KW@2Vch^BKavx5d zeyt6Buvq`Zg)aT3*A~SnS3#<}ER5Dt4%O3d~wL|7dQ)sZAI7UTtZW zD@*VvA48i1`{L84Kaqiyp%KbfLId%bdcXNq?ec`Vzxj&3zCI>q=AzC-`86O45}ndc zcBQj~H9T>kex|Rr!nBB)FsgC6N!GG)tsMgnO}uROKa@|0ubqv(QB~R_U`LGJ#)xHn zJX}LcQX3NdXQTGZHk1y(nYU6loJ`Gz{mQ*wejHcEjWTQVo(Vr5U z!(3Q#57Lf*k*~zAD8u6`nF|j(nadYbxL;BQ+&15fof@!X5LHym0Qm9%70V`73F<1A6X)Zr+`U=mrjEN)F z!Z)dk3%U(e*Qs@NTnnUN%&yB5DN`nC?iQP|C!x~VVtZGQj2W3zki@J{OCEGYO`x=W zK;`)Y_5@`{&7Nqc_Y}A+X>4Bo-mR~Y;bLycNqyPd+Z&$a{CAJhds{D@+o}8Vvb6trE^^aw zc0AH)+TGYF6Ika(fopn|ki%_4ozj}SEZZz?A#B|e}&kq*r z8m?`5BgSM>gjBs)xj~Y|qvz#}Gb6a4C$p5XuQDm7w+W+4!_vR?vZ>JZD!oZOBE;X2 zi70hGsw~NmC_To`GZSGqy7eJ{yZRTu95)@7A$9%gPF66{^%%v~24N_U%>Go-2{n6NKdK;i6DjG7nRjOAjZgZH4g0iED@QR z1YCDKpyAvPY61F%^TJA+qXux=K=y@mUAp~$LJ;fr+XM)K$+qm5%jjZPUGMk&-zcYpzG$0?Gm>n~o3{9p0P z*}r&&`ul&1SE@tXO+Yr~sr}2O9=dw#zy9)vI>gqmf`Y9ot`GuB)aGUsj%_3RZ{wFy zlP$PTQvwM#-m{rVp1JBM3C+e0G&+*vD=*8vkcs-&9i5$WzW2)OJXMz(wGC>qz3u`T zB4&j@FtEK@S<%YT>L9S&WVjA~z9PdGNa5+&Hd_klRiFN;&x;1f<-s>Y1{SiP^TzSF z@udxIJDA_7t;H6-)0|~g1ZX<5i7M_{A<51{lmFEnzvnNlW7OXbn|P{q=dBE)*+kqH z{$AHqX1RjaIt>Ee)&OFo5r~5~1`Qr%jg42p?>IbbxFG3k)Mk$9mcKIo%UAN%H1HAF z0qX;0MiUf{tCP2x@upO-KJm}?oRgDR7fMMq=6sP%diANZ><2)va|Je}jt-``5AuA1kv5F1v|G+A#a#eFDU8W;rP5%R>#4jaCH8!|xs)8irE9lj)#5&l- zzDGm33D(a#4&!c0|+r2yTL#-+moQL56f^YUqh6Z^d zp1e%5%@;4#5d$V`G)^zg-Ry?(sc3ms00ItRJyPb3d`aJLP~Y_Fl8hLzk89mo#@zlw zwDW-gB;k;}2GY0Ygg(XKxlMkj36g8|RZOH(4(Ox@n})=rjlr=dd%S( zLpjS~MWkx?&#%Y>Q;q`0-2E{9K!`FevmA~ES^=<9ZMFO_zEkk+l2DPDT~AIXqHt?w6?Nz4 zHDEbGjw$~M+8Fh#VRHx)6K$&Y!P#y1VtNdw@~2hmHE%DkqjqV&=eh*37GLg^IEm27 z*2aCM!Y_{WqNJj7^ZB#724o5_OvUTXOu-CB9emtRdIp7_RGiG+&v!vHsE)MM#Qe~r z6mXO0D)iClbNmX2p!Mph3q3ZxbPt|Llx${etMR8IsyyTx)9U%O1gmZVf=r;+lnRLb z7cx3E)bqR*XFj1}*0{!*B<7+(lvb(dBnvya?UFjck11w_xu%f(wF^L^d zw=ykm0>1=m0{DFK>$*VI0>ZG$vMsRQfe^&MwmB<(D}$E7c310RBL~`<474rSqQ^OiSo>0%ET!~oMKOWrvO7XQTO_ES*eSO{4ka3+lj<_Jm z@U9HwW~hG=geLFyZCjvHQ~# zI}tGh8~tj2A?(Fkt)4X8^5p{rNgP1y#D-2Cdm+1)(kXR8vp?YTa16+ND6xOq$e~=R zw~|kUi=;Z^6>b~fwKn&!$WVtIm%E!67}!Lev}}dXzv?Zju~6H3_qyJCe%4MgUaz`= z#MW9B${xrA;l$@)trWo$Uz+7`8ns5WnlkC7-Hl%}&FyQ=6E>Vl@83uqsnx=eb}%=s znGx3Tmka|4GF4yx?+*8R<(-w5YhUsKGzRD34_A~$@k>63IEq3sStyg$ZRGy!`|4Fq zWAKs}fuXZmtoY37MgM^4H-J7~s1gLlQ@p?V6_Bl@!5U{m3)4{>BTl!Yb+qjMvNBkh ze){6Wa2eh2IZ+LblXce(8t`hX4B*Qw9=4iR%x{@3W@{~w<; zX1}HrUU;UfkaNd@qi}@rn$9rpydKKhnmzGRG@=bV)X^56A9B8Sa zGoIn>gjbZ7K4%5noz9QrLnLzF!w2L=hg|?<058|9wI=P9>;W|-R6_`&b^I zx)#wu)|t!&xmh5wyJ{~2RtZ}SL{s6ohx4*L@bfz_AH`et}%jAQXp2vA)}{aPTDX1}d)PsMurU`{Ci?3LqBI7~kgZ z=Z8q73KAna1X)gCYIz6>v#~`DtgGdZf^i~pbu=<$6bZxVMOM4HxODZ@>F)wHATu*_ z4P&a~wbqyPk$3y#qGD9~inM6gGsXMR9YK_MwfZZ9UAgM*_yW0cR0 zN%J)Kv-qM2U3&B1 zP%APBvA@|1p1Al}7;uhjIqQ3QdK!mjn+hPx?xdv@ddM@BNrpU(M0fa=Cv*2-tsu1= z*fBmGPbD}U$1^|T%~O>c8OPhr^r{NznCaB1>vFreb{Uq#E$m84IX|18YgBu&T=d}A2HBk_c8GDZH zjk|pv&M;%evY-LUJAp9qwQ)$z5T`G{W9Fli-CeDfj_@syvnyC<@a$ zTDNE(#53ybe|{mVKOQUIu$xhZN9g_2xg_lZkpK%gBUUXmy}LE^OQIr$9?K%3yfe|J zr0z?H>L=(Sa)YA-sYA!tREB4KqFDqVBHKbRL0B~*@!v$9?2Exr~>8(shdR zZS<-O&Q}#$l5deb(fcP#kDfnzp^KkCVDmY{;n+j{lWdmX?@-V2Y~^0ACc18ZtP&2$ zYtJp9uYbdVZ1n{>1n43A7-J2(|7j_vr^hq0L8VLy;~`I9@;70bY_KMMhb^Ybgp=J( zO7pu|pU0+Ox2FFtdw1?;`5Ik{ispDyUS*<$!<6~mMpccm=m8vK!Xi}TP}*7Xt#<$? zby{B;+fa=5DXOPVb&0A)wAc)vaCM80_hr$GB*uy$Yut=%awC@+jJxQ(^g1!FIC0SX zazV%;J$Os}*Hy#D@{3*VPwalR3SEBlnH=guQbP8v^ACQCC?`Oe*!s2~#@9eeAywTL zoQ#_uGl_MPhPq?knNA60HX$?LmBr6|5ET_8!ia8)>&FBoomtASD=)Ey6j4gp{_um< z9-tC>y?h!8cz?I3J~i=Nf^L_Se$yPt5>r?@&emqsV0Z&G6H04q^DI%$W~_a2a|K#% z3qsWuX09NSnPqn7$VrB@s9+yK*X%}6nE|ckhx>ZSz8Z-8FB&SyGBUOg6$Obcg6#@K5%7B7iNetf z)+UQrx=-#A(fvDREFD2^l=`M4)4yAEco~F>se~Uwr$iG7&gh zoptOfH`;N0IaJowTtIW67cs+V-0kbSP}oq__Ovl_%b;EnSvPq2HWv27@%^O(V^c_Iow&?>&oU$R^Laf^V_;nPe`D3cJ z+dpM)m7=Fo*jFD4UJX?WClfXZ{dA0u3d}6Dp4Vgy5j)9_D3g8A#zo)T#S}vto@K)D zI+>?hmUB2|2K|UZPw2##RRc?5LZVuA;CTTjHa9j576|YczoyP^m@9c}!=}a2)UNq( z{qqMK6?4HW^RO|lWW=YUQ3YGb9>qo{Z|%)dOUM3}j`N^P1FKp@aI|icln+#O*?KO4 zKaFiD7dV~dH~uy01c zGFS7-SO}K}%aHR^#Z9;juN^*c==Si?V+`Tf@Z8_o8U?nT6?j1zLl9KZ7gD}xxL~Vv z)QUL4$Lw9~GC@}B%PS|}#F$q(6uTG|Rl_Iut@k~3VBH@K3=W|_?r}7H^ILEBW$*~E zN@?y=tvSBiq%y5P7=zA%ODW|dBKw!Y!vg#~%wu#pYF{oOlje$S7)X3d{urPiCb zs!l!6IeYK3Pld`#i@?KR!F>7h1zt>4Q2xsoP@gYfKz5)&fg^4867|3@Oa~!V2L)>* z2WLGy!!LXW*7}A7VwQTwhVq7b2ClZFhMZr%gq(>9@+rEkop-{UWG<&(w#WZvSmga1 zIW;JNVnr~vlQjZ4t!ng3^{`<0SG;~`y8g)qiuH7hs=hpx9HdwViW*~QlNh900s3fx zKgqAbUl#CqCYVUVsJ?2;nsfYk;o`i%)lvId4#h6u3}PP*!V0L@p{O=_d0j> zR*(DSv7T6Zt=+nR_NctC$`t+14@DU8|KpFCixGheP~hq{!h?c>dRZXK%gVyCZfzFq&2zt?P+fv-g9=;q+cG!Jpn*VkXJ(h?95sNez)lgJoEEln+)KAvVST9U30ZR363 z=yW+$sX5zcSEhfOY!!Wv#rpRE>L_<+Sw!v|cf!KLUXD&*UtiJD&^BJKwas-yNuySt?|fF%hlN<0k?$DlmeFoo+%0+h$kMGpvU$42@gr1Ha&o)& zX!z2IuqW|YB zw&1JBLDx}^orvM2cU3RxwT=EkwhGdxc2ThMr=H`@V_fs+vlHP7Bj}PLcfJizXO*vS{~7)E*tJ9%N)WiaGy$yFxSQkj`~!>F z*LzJMMuwna_BWYgBKK=D>!ZwPhCx~o_s~)}^UeNiQ7*fsD$)m)RcKy~vIAqKZh2!y zaBQ>)k7um`-|eiRN1PQKLTTwWBx3dJ~!gn+!THOaLGFQF^Ky`?1Tb{ z$OiWDQ&M;H0sC^gMkugBzp!VU6o0D+J?s9w|B%u@;~|4tF;kGS1{bq0(Kgxb(Xd!R zNn5Ac40{&z&e7SejY5dD@?~5U$^v$&EgCV3O@{m6g3np>+fMtP?uK8+4iyz#ORke6 zM%P}&C)iorz6pjD4A;c7N-|0vlq76ToUgS>qcl-{a?J zwAXTNQ!gs?@Wn94I4nxjf`a;#^TeQfU9F^l%pDw%#d-(gI?@p$M1cm4`28ku;>3X) zv3Vm`?h^S$yr@?sV51g}-}QX}WiCL}_6<_==gAI%bgyd+sgdhOr~Ba1kQy1N$Sn7F z7!1SPa`^j+^Wm&I7>vcRmqAE%J`G%PuJh0(iKx~(^k!E3e!bfPFL0bsZHIO`!%)dn zH8IRJO8(c=`TS&8iAy+**`HPow;Op0qK&@}PzVu1K+#OU(1QjV2c}DYuKK?qdSbR{ zi;%((ru)&=&Ox*hyx4~31d6blbM-*-g9t#b>=dtwv%{M6lqi_S9SfSgh0ebiw2miHe{!ktc`{fdO_ETK%U)eGnnVouip8VT#{T?JnXTMC^CI5~9)GS` zTwIhaXtvw5eD`?1m5pv4+RUNIl$NQaXJKist0RIeFE1}HE(W8NuD-?@C_9Jg;kLD~ zu(*G43knVjVkGyjf@yWOwYB~0-}>YjQnfl$W7SAaP2Jes45{6ujqQxw-`_7Cc=Ww? zq+D<$QQMW;b8>q(AO`X)RLNcNN!I24F=B{$IV^!#61UpTMtvJQ8#u@>1_uAj76_fC z->L4*7SSs!E38-fARa|t+^9#kK-M1eVh##N=g}VcghaqYfes4Z+I}HFa*1@n3p;!9;OjKIRG~p785n zPY*%ldukkVP#2K>ntYgr64m^{A(cQh?lF5d1(zkXq@<+eXM+*&zsdGwQ?DoaG~vBm z%Sz&Jnx92#(#S$bx6?9Jtj*^5a%XyGTO?nqFGMA-NW>3Si)3U7PiaQb zPpjRbD!PmA<<<)$V7tx?hLHU1iY5Q$YVi#nhs{o~Tc_QLx+@Nfp?U{=jr7GhoYGmb zsbhr*Hg;#_W08ie6(*xo&(;7n{%QzarJ1r=`Vtjy4Woiwb@a1#s4s>=h6}xv6w5 zEH96H35GT{Qgv3}PkA$5>Xc$-3j}`~P44RI%HL*Rd%0MuDP%zKfqeTL;piu~tmE}u zcnMG&g-8>oZVZ-&YprBH%4evoDSsWXSSnfYOJZ$Y{tDwB0)ndb^ zWo#{fTZO)+^%y}(X;jPxux#%?_cdtzV+T-$mY{rY*3xIMtsd2b;7A=dKY)w02$-{2pD&S39o^Xur0T~ zuJMF3VVnnTPg7DGbi^Y^0_gC6@^%Ggbz@vf`n?PwZg zerC3O>!>jdm1(B>$`~2$65Zx%{V)<}2;YH_%DcKKGb(GuP%R#sL^HQNgdC`f{JPhPeLo|fo;2k*0By&geK8wyzV z&Mct7hsW2E=})vVpUk`Hv~2*!^98Yo*S?87=+FG8Teo*KREzmTu3hSF8U35|J_vr} z>+UvXcVB?a4uXs6m>rsMhPSg}dtoR>qD#R0=+_PT&U&oWSmG(}m67@(!Ubc;taP2w z4EzZnvG6mN(WJA07%A`p(H^vK=Iu5vutxDhUdjX6kAcB|-M3G#@ToL0ATP@GTP{@++b`Q_y{WG6Zk0Alrn*U>vwhqn#QImogIc=w6L6jTCR$ z&(Vix+2yn^0?>qpKT=D!)U-B8fP8i6;0b`(=YyKl&@yWEGqtdeP&X0R(yFSaZJ;zv zG^(ekr70^b14W~85z=UKUhY9eN@{X{-vHoWtKwL4&FiIW(Bw&I7N(}99*p_0Dqihz z(#1!IhsxH~WgeN?*~6+sz5Y5pstHHhPbYzj6iiG^i*J)go@1%=#^0E5`~I#ScpR-+e`!7N!J;-knhAUbNinUNZV z``2PRc{n(rgu!qBSszu^*32hy>IsBpu4wsdqO9EK9Z7r!YQHi&OQ^FW^LTgHlZaBe z@#*I6`{#}|QCYGsl-T4Qo5kwx@sWjzi4dV!Cfn;fDjgN=lWP2>q}xx`IeYjcp0r>! zNPDq$>>#`-jl?hM;3DT#;50*g(^+k{dsDd6us9ySXS97FvfdBQpVs$8;kT~^H6hI9 zBs*AFzw2t{(GrnkNVR-v&T&Tjb>mpOr)3Mclo0*NB3cYo^xuYuI_xeLV{@qL;P8+Mxbzx?#7)Ffs1q!`f(oW~&R(QN0 zPq3)MqQURqdp*$*HaLC7&CSh~mDIe|=@(C0y9|2K4y0byFf{nK_-CfvC^;o$2pPb+ z8OZP3xB3E@n(PRv}7{M?9gv!f|ne@{iWm zTSBdUvf7fIpJ$=kw&3YQM%O=F2jTo=3BmGs#LJw3qI@D@O?jM&QZto@xo*8aPD0lJ zz0YIGf76Gp@&)rzhYx8ZWnpdq5R>5qSF4-*;8W}|SqO2Jo#lNHevK{RQU^uip#pb_ zoJHvC+|m!gSPhX?nc@^DgjtCKk#ltAVU+&g*9<8L0)~r-B#T<=_bJp_+Jh*SUtei9 z3lSv(XWZ@NTgFTDLYg3}yCO#GlUHYI*0Fpz(<;25^+~|}9N40-jAhnOo2OUWGP}3E zVMBv#Js{UpLgs0;(?^_e0Dw~|7D!GOmgTiIc1Feo+nptSs(-KzHg1DBQ+lrsSiyU& z9|_>@c4oS|ygwCeC)*a)G_YCwqm2O&H90YX!{xRB{XNhSEQ8A(EgAz8^Mqr0d2uoD zGdU^g?pG%FXlPp-`?0Ra3=iGg%j@g?LZkUIjH^jTT4>3-ydnqTI%-NEJ5dK>+MTws zXhrA3j@UyxbgIoDQ)g$VY&O>H``hjG0jwtbr=)?SVa}*PkL;-ZtK4oS2qad$L=J;fGR_-&x?jlRQ z`P4~ydTPqdPcME30cIADZUTpi*CIi+J%Q=*SLjbCDU66C7~ zM#1=CNSteCn`3rAR)k0`hFnLD2w)pyyZ0Qw9UuMD$wF!?=}O;1y_WcoAt@g`)Oz7Un&p0LjH7BTg(YNhrlO&l@}yI7VdhLnRN0b(LqG@@DlO8K^JzcPX-E9b zbzPA35Km(z)Cde>%J9FqxbQ`n>0qL-vF2?mk57i(L1tlL8K)aY#8m#y$H2hw^eq`h zXI}}b#kplu?0cRrfC_{Eo*W;`vVD1cIVsMz`jl>u|KTzLAXCyc>5;@OX}GS&RkyFv zLxV3`p4){oNpA;!hyKZ>zqi*JzEnMLa#F%SFL)vWMMO}Z#d=FHt8mE7++3(;gkub` zOwYq(V{A^U<#G2=zK8is-AlFY_IQ(gmr>+#!n^lj8a#&b=H})cc0svk+nuRxIlul+ zQ}xmH45!)8;2t@0WFWoz)vhisGTr`_Tmk3WJ}cD_K=m*Cjw>h|2@7kre?B`V(m%)f z*l!O81_q=~w8d}g>gqJw9VVM_@K}2iw(no*I5^Ha-~-=s3S3pNJpO_~ej8aLN~Y23 z`9|9yz*G%A?(%^3{QI4FLUqKisW(n&y z?x-*b%M;VpGNQddB13Lb5nH-HoMV-w4&_Yi){{R@CbZYp!_xa3#hgh=c)>MsEKm$x zTvV4J6GMRNu8hd9kcXU8j%p&Ozap42;mXrcz@#t*EZBL!-gE_v`E}bon))w=-QD;C zVnN+en@J0duk9LT% z9h;h%s3JLCCoIKP4)IQ9ad7|(hK&sq18D`0vqOlZ^8%7t+I@cn(HO1s!eAY!+=FWf zou%aU6^}c;{;!`7JVT=jGF(anOuj-MCSFX)tV4gTfil9ydV7kAIhCiS_+vah-~|Fi zF{-P?KX&m|{qjxZ_QNsXhKqDNb%2~Cyfz4-%LIqRlUl37;!IOM#RlU!J@y~x0N}%O z&+@|ap62W%{maWsjL})MMkci5u_8R)UH2BPw!sBMqjsd_9ocjy2jsZ0|MbHJ62*?k zjI;I5XKvel<%O>=h-KXKv#Y4L!xE6#XPD$pYCOXleaC-Ca}{l4e`8YQk_(jH25Q+I zTcSP}qt|4>;)PL(6Mqv32JU9@lE~KtaeMpvuEejnR8<90rLgEUBTb$xRvX9X=L6sS zSDcY7OiX;rhR8|UYl4cR6O?+kRKC)u@#_;CAggYKFaW-svFO*uE&Vsx& z)-yS_l;`T}>q~04wtSXp9DehK&>k7?LPi}g#}sX6f9sHENwaaP0oY>s5+Voxh{W*& zpRc>%z$iq6#8S3Q3^wd)NPlij@KD9SirujWz3O$G6XLbHX$6xj;Pvj9)`(l3(ToG8 zLm9_Mihdj-;Kz!@{6(qFsH!`-h!%w6vkBGLZ@jA?y1CsU(P;bk0(u?}-x0d_L#K#$ ztRpSrYoEc-8t3YfI^ub!2OrCYg{m=oi|iW8OxM7&GK$odQw+3oArheZjE|`8a!P ze)+SgN|Ks}Mp{zRr5b$$mXxGYbiivgT2@p1xyfce!cyT=BpwcIG5lR< zGJdn|c5>6s<{n{_G}hqX`rT8Izp`{eHOvBaaw%<8y*Uu5lO)DVPJga47F@V7_e0;p zB*lCQDAtuxr~Lb}!uQ@zlI{G(5j1xE6^=t1rx%jil+LM2;ZlA%O!EJWX5QIDmkP)K zr21|FdYWBs?b4-Zet?N-<(5kxYjB3h{}&9wGPeUDEv?4WSvB=Qe+3%@Lv%x`p<|`a zdb?{pnO5fAV@x}SJ*n@yT%|hd-C{yaxoUaO&QM4wQ2X}z<|up_o%H8VfGb$tsGD)D z22HFJ14`L)wT?{jJW!QNvgK#~n*qVW!#j2^H2xSXbj8EQHh*`bGz1|G_zKqOcI51w z$I}AA9r>Zwn*Zy{Da4LT8_??U{)y5Zc{O){%5V!%ggSP=Tl~rGr%Cwf#<8L=fW+<- zZYxo123;f|_>S_ZmUQx1e1KTroiTYb1Y}q`AD}5D5}E0CpvX2}=qgNU;}Lr!do4N$ zrgCVI2dLuE)!S>1^+F|Hb?j42iHX7|O$~5wCcItF4i3lH$fVM6?=GTU_-uA0`EX`t zhukUUm6h-k_@U0(r(Sh0qjbU0X1aEE@?DRQk3d~UOj`KIeX>08adAE0u7|^S)0a54 zkR6+fAXd$-teo`01`}veZ4V?Ck(JPCG)tNE2ii@XotaqqSF@_zuh(4v`^{<(3&ui6w}r${`N|Flx#w^CA57B&_65iE;*J-A#KqP5oQ!l$JJRROiWB< zkI45}3bf8j%gfC#u_7ZQYew##fO7igg@B{xh^6b?+|(45>f-P3@5&K%ZE9_uoVMES z%>&~{RT*APF&)!!X&djY^}Z~nLX$lOMM=Iv`@AbDA(9=I>LTX{4{Qdv-aq}pOxA0E zqVakDMtoD;aU&^ZXI=YB3YN(^gTk9Uq-FEo_#_>invpT!Pshv7!9iR=l3@N=YUTdb z(hT42G*RILmPWHhS7i6@t^xOE1S3mZR8hfv$Q#EMwjQflXunpLK+!OOrb=$)o`iSA*KWa<~dI#$M9$XQ~diwqt;S+l;3^j z`_B{?-z=BOL9t0=IAe*8+84dDvr?cjxonwWY<7)1#ZCdw^raibN}&cn^=`kS&G{*! zo2%*``4D6eR1@u-?FUygG*>S>r7h=+$akdV2>d+;Dq#*w%# z=L}hGqcLQi6CC_6LhIAXb}?i6Ifnub#qYE5cK|BC;82-n_gb_i40h$M;w_ zvmX_+$rH9+v)?0ek&XwR$+JwrEe>K!T+5lyQ+n0XQ-MDV{cmL{{Rxzy;T*1YmXuuhqH%`n<`HC(x;jAPjtIS#s@wYQuxp?QLNHN(pg6#O z#BCA5V$d@>EbLH4?d&-}65AQh4;YGm_YQ)t<@~iXxrrxX>ZgW(q=|nFsz#Voxi_gi zP$Iyoo<;VPiakOrseN)5u@HZxS92RbQn^R@ue;V{OY4I_L=C7MQ$XUqD2&!ud`;6$ zzYzY=Pv0YmppFW1-OjLIWV#xrc}RUIK@1@NR%Z359tB&P;293ZlSD=zFp52{$>Y^N z^nJujn4;|*QyCW&h{gIpwKc&l-i0vrr6CF~8Xn6qU}Sp^a~e_a2o#NS9vYVolzP&T zGr3jfm5+*Je~3z6kgkQSQRWy`fG%b2P0FAvfvmqQygj{s`KxqtNv4aloS+2pqQLv9 z_^A!|4aXMLv;@s~Kuv>zT_vqZIg_Ro`ZmXI%x5F7$aQI$ZCPW%Px1Gx*+GgU*&Ljh zTCx84g!bP!X!x$I5Ez~b*{fl)nZf5P!vXORt8 zO$HU}5n-?fYjrXZtHI^ku+==5T~vlr?irF@60hG~6vOm3lboySuHTzgwkAYkmIVTn z&=E)-e*4lb1Cqa30s5T{?V+x)I5IAjPKU_CHwC#BeoDzDZH}vNjm!#Sf*NUYPP7}^Cj@+7~-XN zcn!i6!6sZt(OtS9NifAE(BdtK%F$jIEX411NY=Fuzug2a;AnT_xKk1 z;MOcX+5fD!WD&4jS=5-tt7-Om2>f|{bA4SUHWZfkS}Bi9zSjG8d!|Pl!4^NJzdJ6X zaFyT?V|VlDZK-KMbqJdb!=L^Dy7y_1@NHzF;$g{oHmT%+DO< zVmw!satTNlXJ@b*ZGZX#VIQ=}rT*L;jN9W+94Jzg8JU}xZ?=3vDsFGr(8j%fh)PL& z0eU6yeVYb1fbuxrNccwUljz4ehMMz5^2c(;pKc>Zrs+sgi8Plx-kIQ24IB)plJBGb zP7j4LU}sM|!TVu7K)Y zh%DZed0`c!cQlyj>+1`&YX>T{_c3?P4>vK_2b5EEW5&vD^{R(Oj~v*cX|z>sRFrwt zpO1sK?5ZDRspYjRd2wb7?8Xv#CZY6=2#Qg5ZLW8PMmb+r0I_XSWK3W%gbkU0v%127(!-CNj}g>uu`_ zK+_7~ZwB}AQ{meRJAT>Ro@?AC zs+Y6+Wa3S7b3i|$?NU{aOrUiJyOMi`?;COH)mt*7EsNUk1kr9GN4)_(suAv$wRXiM zwu=_K@o}>k<+k_!hc%{{Zwc9D0-8kWW_%gBrX;Ir#pd5|SYv8~mu7f!BVtDYAD3g< z;2If`Or_+AX3Sl{(2GEFvSE&+g99(fIGVbhlDj(xk}t^hL9&kcbu6U$p8nO#z5al( zi+=mac_8oo7I9;iM;vP7v!Uyqx46eFb)%2U7&rWsqqRjhH9*wJV!Qi+k`5tVTxQu z1HAFJfsfE8;|8tvo5a}rDl}}+DPVKj=y0v??%p=j84-7w)M|G^Z7D3?&cDw%Z}b6! zDB#(_QF!S|o!>Aca-$6hluli#EY96@cXQ+X?MfV#)z9RM5SX+2S^VnkX_@Tx@G+}R zp9;%Ie7ggvL@r-n&H#<*z(8`pk)6gVOUcOLjmh;8(s(CM{8%0WTD{dmi_)kyFLRJs zB#QM`X3I#%++1~cnDD&x4T;tYWo^he=fYw<2;8?UTQgfIUWHUC#C;vrGwFIy2rJLJ zBt6{9#}`h)VjyP-XNW&1(DP)j4IeBsVBty=SHw=-`NnTK9CoMA%t9~uIRC|o5M}Z=@G*gjAz`PFsG9pP zXQ96|b6dr%(S@A+iTHXyxV)uOU8ziN;rAR(clkU zP#~6ST8W1hG)?fNw0i5(M3lUZ`kCN@FS3ae6vm9rzvS!oDYVllI_;-;pNJ}UQ0l1r zkj}9+r;5&87jl^g9=0XMyU*E37qN9fIL_?)n`*8vNzjdZD@pz1Fh%I}{R2Y`dmdFl zjNe^FloV&NZAZfX_GH#ngeuvn{ey=2>2qE32coWO2iTtf?k3M{bT;4X-a>=$ z+$G>!{BB8xP$=l52&}oF6!UInbWgH!WdM9fPnWL|%Mry=cvjl&v2)|>cVA+mz-Xh1 z>Uu-?4)ouTmP!VX%eO2I%)XzHMg@d*hZNFjQNQCAAaLr5&0%br&l}d|*;6O-zg@KN zrR$kGK-Us8BP>#`EW7px1(@$xdxTxYMnz3f^v6tX=IcQTy)9s%7!>oqVRV=8H zNdH1ykpg2e5q#)#s9EUVq*~_YzYJSB89ijHz!R6FnXG5RB5G2qT@QU?NnD^ow52fG zb^XFXwmV!#Sh-)wQS7D%Iwrh2WxGGG6U^!tyL)GR$s#J*G5iT-ydo}2-c}$B_n_6= zlj+o;le>`hC(gmRr2-x?vpfY4O|xDVeuE~c_>UWL24!MNiZftFFLWHUm2=R z_3ilTTnn=YQEQ`hqtFp><7`^z2E0~s^yy6CM=v4V(ZyfKKQSDS;m{oRSa}v35BNMs zzllGWYFFw&QwfGsUpLK)dc|vMR|&y<;B&+efWedDAiPGharV7zoXyeI`TTmYG4yT! z%9;o17|yt7(Gd){^8U4hC4b52bw7mo$pCL~=#OnDdp?F;oqHDpUQAkwCSol|WpK!r zPMDo(R%QoVcXAHm9u(J~b4-+fkd#N3`l+|(^nk45)(JB&rr{d;6*WG z;GY5cf2y;eo&q>Cv9qjK+MY!Y)3r^+NmkwX@bWT?&>J%s|iKi+_;htruNeMaYL5tL?#da&$A$~VM&g$-jhK%Y($nfS0{Zsv%G zRxDK*r3)qEoRv?IyNyQsqe^TL9xJJMSuwSEyp4moO{B=9hI^DYCZ6x0p$_52NU+Vp z&VKh4icA{h#YwUqjl-5VZ2lj~%%2i1i5uyXd+{BBCwkIIf}i{Q1s<1|m)S1nL{z1K zxjdHZnVX&cO5m+-CNFQzXJzwA?i|z#*?FX@Bh#EH29`>C=*skZ{836&DW1#KctluuwC@ z*c*v*)8t`bAU3{4A92;v!X4_{*w~mOmC&di-05^deKjf4|1bZ891(U-+)K4v#h7+e zOH0VOvQ_0%e4xAi+mr2xD&y+S%`bH`7Z;c7y+Oaa*#GEfbMF7q&xXh|Lv(`L?c}K2 z&3CYcTDVzZozW;{qjQoPlUdQr?KwXlTJ}IVzNzhy&J6cmFb5-cm8~$09_0V}erMnnHYc~MxH6Tn#ITp&!&kARjhxYBx&r^0F^4hnB zcbWfNCc;>uBWiI+$qxeo>tW}}E5da>;_;z}J{kct<{2`0EGJt*E}%d0wHhxtEkwcB zjSJO$$`-<-Vn;YS)_<1USv=0UUb7Y|N7`e$i zz$tJ)C|G?{M-x24mz2r>Pnh4z`Ll?ruWkGrN{zUx2LVA0B^0-Nfra5jnGYdL|GuMO zP<_%5^WAl@#cE%CQF+|i<1b#NVN0?8Epv#OP5rFdJ?zazyjM9AR>w)cNwt$f#KT~f z0+V6`k!-Vo0YlJp2r&5;WQFvGgf)t(m13}xrYI!}Yn0g5<<>1Db6*e16;;JOY85AL z#$EtEGHvZHmur2&eZrJ>=+Gl7YQsEsiENrxg6XkJR1$5agFwL!UAwvVa;t2PIRN19 zfVbz&mX|Zx9q7FJ`^SmBWlI-ZZ*`RF$uG;d+wkF?YIU>#R!t1FuN?L-5!?+01h?u8 zK-aY-X?E6;FUNe9Kqm^HM_WZDc%r(hYB!2fr3#S7!KwVkf3B^qMd7gdg&*`REG%4I z**Mss7EJ@&>gxF6!HIMzN>4$d-YS1$auWA_NzMaU)~)u&T7Jj=V=BU*1w&J(TU%R2 zML)5(I031Xk*1<^Dk@^9hnT>unpPVh3$M?=Pug@iMB0PHcWvlXhUc9TA}R^pGE-H9 zgN>ekcBZDwOPkc^d>~*Mc?qJ<2?I`;B_UJ#_r~bpudXWsMlQENrHuFYclC9E#DNPM zN@va$k3o zY9~z5lm;hY#*GF*@Sjsb#4Tdx0l;t#H4TvcQXu)j{=czTacU7=R+g5nrhh zTTN8|BxKz8ADhi9rA%$?NMljVEcm_YIayE%f}Ire)p2KK+=400V19wF%R>4}aMD1x zhsTJy;{bG6p28)TDj+(7SQ9SPm#0$o+no>L_pwi+gMLFVJWl@zA9Irwh)Wst=9QXK z2KbJ{udkluDI7?=q5cKns1+>R)%3|*KyZIhiuh;eM{{#*UToc~`?CdMYZ{@aBCw`8h z_jmEME!zaS@?DEw7E22YI87phVB@dh__WMk`L&IUTHX1S?9Aa4%FKF9@9z(;!dXKzLj@hR}*|)d1dJ>idyE!L>-)$sP9c@|# zW&rJita#A_!<3A92+pl?fD&dPstqs%ADbj7Fb@^-?G3D%NqWl{FWc}l9#3Km_S@e( z{b{JOL^JfbJC=h#aY;Jls`bmz?DAL@>k!0h&g*j@U#bE_e?EW@N<@u_nNIHXR*F`_ z6~mn^>b<|%Hcb|Brh+5d2$(J=Mfd zqt&L^^y|e}u8`kSS6A1?1;d-4S3+aYdu1GO23hIrgMw+SqYUyPAo8KvQb_M2N*p); zC?P_eC*y7lU>LX0`S4kp)FU)eRoCD6JtD#W{U`hA0rhl8F_`X(qmu)TXIns)#qTV- zw0kTAf+N?wNQ%j4P&u&hZozoiwF@}|Icv3X^TngSK2V5XZRRQ}Dh*G8y=51>PYCk7 zvn@-6d=jh1rEN-pS%b`|S>=y8GQ65?eXJ(!w~t5um-6x(Qlth5E~}Hv%SYPypcUVa zIZ5@x8cSaf=#0+p>vU|uIA{bvE*P9+$qMTfsr5yF&&%H$ZjCjUy+RFrmFCT?*R6Rr z9G0;TzR_S=R3fIJfbckk#Zcga2ANR<;b(e^&B~26b|^nAyTk;^6Pk$EN&fP3R8nQc z$M**E#wK0;J&ipq`f*o8WtvbP0z#AZ3KKUid_bsldJz^9Tp_}3$ai!Gg(M%!Z{u)6 z{9%WL@f;Du(6aeqnqTp8uQ?S7u3TD)<|(*z^OEc@R`^VbCgrn5R!>3E>rnL54KXP~ zKe4UNY4e)x4aZ2pb&!<7ssflDkURx zxz;G5sbRkT#|^_lhWoj|qMSq~_8y%qS>2Kj><{#byq`(Ow}thy6+=2B_par5op%?+ zns$(WUO%I&A(HQ;t&LGs=Vz(T#(BujH_(qXM%;QCWnjKPVee8T6o2=_HOm|Eh zZP`UZ^%~0Y7fO1-y7xTt%Q9yLB=Mt)S>o_`X+qj91xmD-J2@%qKsNuD>eL8*_%{tG zDiw?|^qN|4%$S0Szn*+9m=2RsGj)hS(CfN5wbLoc&4l^~z3dfMM&d26Mih_i@8ncd(VVu#&vDI$zk1KCcvI-*d}mV?izt9ZJRwDI|O- z0<=E`>{beQ>r}INHYr+EaWpoL5n7kXO;E5+VOsCimsM(yS{In@1NhKuN?>(ALD?FF zqEes`G~Q8;8AaTKUBZ6<-pw`Z??VdcEg=tSH7jTD!-irA_-z$&P$3$&C0KE6c<0`O z*q-~Gxu(grlY!)I!>Q{oo+$?f>8P`yP@9-fjQi_r87w|V1^bYp=$Z<0p?NQ4BW$C^ zIY^c=Fdv4Sj&Y+WZH9xe(&pT@L$C(+(4CKg_^noG{tuA)DQ1?IfBaw(9Xy@^Rqq}1 zg+fpb&b^;~$IG^K_O=`t6K;X5I5D~Yq2db-Q8m7vg?9x3d))MB1a&TWhN)UlhEO%7 z<@lfidfEAi_t9;45O&|%Uz7maayF^P%)}JR<^FW_2as!x*C%NFf}_h}*|RFVZU#b; zu`|@SjWlc+^)k3WAfrVzmayTHE!?FE5wdA2X~ESy{&orV24ZdhJAEBgd`w5jSx~%?TfypHj2cZ3-ss($_N?;s?gy?d_&{7<`C+165 zqUnPlRN!g0d(=w0j1VT$@`;iZVa2~t6$f1Y1m+_c$&IV9qAIBJeI7pc3Tpaao-@sUx=j(2O$;;Gzq!!lvy@(48g!h06CNAz`aGoYx;8M7}Fptxpt*a|K zs!F1Vm$;u@g?wim=8vF|6_q`#{o<469?OqbOe5Vl>xn);Ug#l;wt1JCvTCM;K+3Uw zIEUphS|IW+XL1E7=;^-9iuF~gjDPHo2sM5Y^wG7A@(D_+2B~Jq(K-`;_6zji z{9-iVxMRNtcleQd%9Y!H=aE+7y|hTl@<56aHI?>yab4Y zPt8dKh%JEYxKI3R=d|(mlyQy12x672 zlzKB8@&k*eg8D7iK%S(`7#Ia$Z`e zaZqW34gEb?gHL?%Bg0nqCOR(7`C7~hjU2vTX)bQJRV(nx!>ThZD0gTsD~~f5od#RJ z2^Du{zuwFNC0(W7Fm!pO^3^*kmVJj<+C~Os4$lTeRvGX^|{zDzpaI-Q-x7w zIMJd1uC*1ywW3sUQ0Zg&*fgG%uR&4KpDY5hZgpa%*ExAr?K>uRKcvzVm5$vM8|MAG z&1&810>+Vg<*taxfp5tSo^gMK>v)yp^ASiG<&52eoRpZ}Hf-&2g84H`TuvC6__I=e zbxW)_j@JrD|ED{y!zsx{;oX-Tuj}zXR*M7S ztE-8O0<)d~Q=<5g7ffb3uV_YFTz1S?5j-_?B2gC*q(zoBhIZOs9GR)ms59__(IqTf2~krL^B&=i!!@op^ws)IM5!z)$?QX~Q0*wSNUn@Aq41rq1n618>AU0p~s|`*blVfqcE__ zkorK!fzp)Fc%t3+uTXcgCl}bMmn&}vjXXb8rZoTL3Vq5c-sBKh6DAo4ptGz;K_k&K zFa40PJ7bc1`voCR-(YcvMUP17nh_Sy`hP3D$>ZQrO#cR^H_TnC^ro}Vfw`2bva&Ld z0y}JL7MT&xJuCf#hq0SV!^@+k`EZrbkFpOOE<%#CD>WtyS8z=wt;N~dST{oO!ttRW z1#f_pN#@OCcWzs|4}A%OkZrZ@i%wG(XjMhUxo2hbfhsJQ7C*B;Bc{9g`P=ht7B6AI zz>q>;vpADkmwcF@!mzyc=k7&YTiZat1vfu42m-0o<<@&2EbZGo&-*-SwnyI!0m)BP zRMf;z^MljP#r98S51p137}it_96V0@L%3g)NyG;Ap>e=_5pX%2Iv#npCEhsB{9{@k z&WNKq{XSJbyNP7rybD|UUoXb3S>Bs}HlY)yqqX$4f8PG>er@k=cYmZY_m6pksoH&{ zu-fkGBuBOR1#$t5_;Ia=#z;v!IywTTecGxwKQB5$Hj~zE2{aW*bSV&o4}+T0&@Ng+ z4PnU3r)}WWTkaJw{C0D_LJ>mfA|S<4g;Q@j#w*ML7KH!q=}gA^eU!&e3XPCWR!*+= z#d=UJUMXNXhJun37$@@iWYJ)%tf~Sib#9$}sbVM|Jw3f|anC)1rbAOh1Mn6DR2LYQ z-Ou9`K8FuWK`7Yb!sYr7pDPFJgK+xWyRmWf18vFSb%X%VAvBQ$xHQP_6lHS43|?Q*;DhE zDwfH4`uS(Z3W<~z3>IFx`?>A%Sx9l^*XmENy@3=vWv6A>uqq8?WqQHwQ`lt98 z?}1SqM#hk&wfjabx6^U&=epxHe$@X}+gk?J5qImJAwY1~;O_4376=mDC1`MW*aUYA zgy0_B-QC^Y-Q72EJLf$!b89}Gsk)O-qza0rclY`)d7j@g0Tg+F@HaLf*7TpT0^~4u zo^o{bBMjp(iiby7nAl7odY?EddL>Cnt2$p_Q?s$7PA?}ssxVVz`sg;Xh@SmoY*S80 zXXR+7U_`yVbG(wXF_q^rDj?M=v(zN#Im~jRhlVJTpUw$A2`fgmbX|XpJOmiM>sZWG zG4!qK`xs*Ibp=_DM@L6Hp1ZgJ4dKG$N0Xwb)G@$+2;^`c{0bZRjK|g1A*{7MgEc6`E%eD)tqUtcqX1ige+yTH|-r%c*8wH5m8FSlHOi6+()L z1DSd&&~3)}Jz^&tQm03oGRF)V4epD(d4G6fOTg4?KC++5jS(o8_Vs#ch*)SFN{Gah zp#q9zE7$qWO~AYualN{};F+3Xmy(`w2yB<&)&AS<5i5`ISUo{%oUrUe6lEBo2sits2i2`!fczD z=%9^D+uMoM0;o<;P6CeMZvw*=6cuB3Gma!*{ycJQ7Ot^UzysRy=e#gwo z=`g2R|8W~+=V&yx6|js;NEmdiw;+{RSJz^tQlxs~rfo!1qS>Pd-~?DgCfnDT-AZ($ zlW&59Kh1{OCZhN_-B*mu5?Q(~q`kfU0Kw=twXq2Z2wcretk*$!Y%|b{I#?>qi!i&k z%~CE&m47sSS=6z@z;<)8Py!JTra00*i+sVnBnO^o|NHR3S9fBNX*Pga0L*|_$-W>w zY^G0ho-l27AGxPS^z{gxai#E5Dm!_^2{aHF1_#mTF94q$z&p7F0fUNpwXtl^fNQ(D z$FO>gXT4sIKP`N229_;|wzjox)l0)z9XPzX3zOP#!1zMBa?leDn1$<8*J$1b6XCHEf+$VApv(LIqMJx;w zmcx~5yMwry2II)z5759`N07YIZwOUCyRq}hOcTGoJ%5WC3BKCqD14{YQehG&u5^e9 zE_}+WMcz(&EKy;Pce;u>*_ekq;@}<&!OAlCx=TcHjZMMF_NSlSQ4{b#)Y;ZR%BzFZ)6!n7Bw?L? zm^1hXOc$7@`8(w#YIxzB?^MnE*wt@`4P2vwoBmaqQCp9VjXq{CTBt3n(3Re(W)8Wc8u0MUcE+ znH#Q%3I(Ufn~mj0NPWp!PLcTB-%IS;m6&0pX3ofs$ee=Hy^tJrxJm}Rv4{kpBll%t}x z7k7j{F-!Ew45NNguKz}yG&i^&+hdaRw&b}I6br#IlP%1jC!La#g1u0=Gzo`n$HTyw z{&*fX{wsYME{@)Ub1w97>$T!;gfXd~X;0&9Ack1utmMjdqV>fPnbBXi{Z^O>x;7!O zTThyEXvlR~H&)n!H$j$r0!5a8;1hLu^y0C{W!aomYtij40A!zm=l z^#fz0qZg$MMO}d_N@N+p9ysJ$K84rpzV$HIFk#XjNtK~-kAhSEL1k>!{x|yfXk}5U zL_~3O5Oj)GLY#~M(6{vz6bNJ4!72Edw4Y;9$)qNoqj>Q?^9p!&H))Ngl}aHFNUACJ z{eQhzKFMIt(-{sxGo!sNBd@3ol~ma^Y~vL{MS3q1yeT8d^j7$hjwl_tPM0`$B&NGH zeIzH-^7^K^Dd!($RB(Ns^Ub)axfFg8t|nJQrb&tPNaqL`3JQvXhrZu%r?%bk*m+)T zib{0S`*SQTsSjF2e*Yp-x4<_+9i125iRW}1xU6;@aQ~`COvnE9I^)gPtQqsDhx*qS zh*WW}s7457QYdvqX;<*(lg%E7&=i;DbmF+G?6}b0Ogwd_6eyp&Y#bGc=C0YNuZ0 z3^|#6jFNhaJ~=C8WFuk1>?~BDDFR$rKt!F)%);6G4n~=woxBr$K17{|#Hh$W3ZlXk zP|E9WmhOrJ&8-%qnv5Et96GU}ZL)tk>-r=S%sLBL+l&^)mR6uB|7uInCfC)Ij+nes zf0_myQTI;=nYq7fv$rgD0aOEl*2?qU#GG+x_+wAh+ZP_h;Qf6wdOX7esgU|}xh8P$ zk)#Y5P`w%1;5g7-FlqNz>DICs%10q1Reb+-@>}pNDHi?N??G9_l+yA8mhX1oox=4~ z*~G%#FoHaOU`6C1b@7xUnDuL+y?ZmddjMv?`Dt0zRtFI>W{U!0PFpY4Vyt*3FDy5L z!XGcxRsE_Nn88n_+>cj|P|qTYk~|fIHogd;Q0~}sSLd4kH zTi2N=_}8&mAxzY^SO5|DSu}CkDCSREnglJ!o{QH_8C;{fd*Fsn_Z=I{@|1L$=?5iR*3|jz$t`aEzymLF)hZbjK z*>DHWf@vo#7gaOV+(JNqsOUR;*2fv8dK5p=z7N6_@)171*|+6pyE_M_h?hVtqL}x{ z>X*DP2d`nlH7`#x31|;-MP7Gue&z!I=KHN2@dT7q*CiZhh)GO)pFzPlNpTHUGv(K= zznzu_2SfX@dVka}Z1#5|N^n{<@)J>;`W+{ZGn6zNM#>U*GG=s-FGH-4Ie%!JO`;aq zF+N(5WAQT~)Rn+bOflK^jn#%U4aRe&Y90q~j&?r%oSK?yJqTv4C0n(SQG}JJHnY;e zTj7drkb5oN_Fcw0S*GYRLpzrKc$4 zd|G1Efnq_e+A&2!-_8t@N*KQfSS}MBQcT4Yb|2h6EZ~>`IdAudtMuD;Xn)D8s0*Co zte{GPAhu%KlVQKZ>sh$z6)j{^5RlAkL7%$O4{Q)TxNfiT7-Xmf>?b&Wx8YOFA-V46 zkjU@HF?RWo>$lP|W1DXP=30(~$6fa%#fVx@c|pJ-Q4R@d1sxw|4di~lUR;B_M?)Wd zo<^HJ0}>e3M)6V|c|$K@u%mgI(rBY_cyK{p%M48@-?NORg+*aa4LeJEg}Qeg;@MeQ z{9PjK`7EGnb*gg**CDN7h-(a=eC|d<8Yd_?+lE0V805V9X=M_wK(u$QlAy0T-s=?I ziiH&_JZs;3%$ruGCr(I+mAi}`+xqL*uW~bZ9HkzRp!d~wU-X5mg$0D~CGg_fm?$8X zel*pqMGU4c*3UBdA=-2tQDY>O<5R{v87FV8%g<<)%k;LpebpgQ9k!R)~Zb&vz%W zOx4f&O=MVWAV~9=8QCZ8B&p z)PvQmDcTq3%RK{KY-sPz31pelbuUTxF?7Z}NX(xvjaZb$S%86Uy}?UGOI-Y5BGZlP zcq(&y^oCH_S0E-T^wldhI}Q&YKbtn6)Mg-RQISW;{!SHQ!|kO6@DrmC6dNVr5%O8d zOD%9&&RNnX=Uv%Jo0p{lbNc?|l5_7SjQOf^Nq@dx9)|6EW=UENL#3+5w!+ykW~M|= z6QuN{yE?mq4eg%8+XqGQ)e|{SJX~0v&l#LKAHGp(SCVOg1+BwqF5KY-@XO;v$~A;i90R zpzZR_Ixa)N+3U)$m+0qPp}i!_%`*@^0*k`%JxQYwCU3*7d}1692?a%Gq-{2bu~}Ti zYiwd-gC(oJXZ~uRLhLD-*G7Cgl68gJ7xoZV~UAym`OmoxVgo2 z2%c|5!rcq<2`G>*9dows?LBx;9{O}U;fJ|tJByQT&H}|Y?);!edV>M~`I`pky@4mm~&7w2$U#(#@ zJCdEI^vVVqJKC;dYRs2de~Y@LqU$dij=ktAUY4sJ79N zZe3${@%7akp6e%+k-e;XGLuhrEnv=#R6P8^!Jg)lZg)e^h)8<%J9ajiI8C%CqQOL* z)zS=`5Enz4L%_kr1Zt-~ttC)<;%zvQ9#_@ka0DZXP;tsj?YR%z<`n?QgbHW+KL2p< zi6y~h&&|#K`9`zc_fof3H*3E)8kYS1Y(qK05gPr!YS6_ZaI*yz&<(WwuHx^IcLCGg znf_#Gc7686gC5Q@7wC=P8WesG`|Ex}{JsqvJxCR;4?gN3uooM?o0yNN{)s-FP}g)I z#IUST&UYD?+||{!m5IpDD{4EpBL3TKBU9~5PDWaLDwL6qJJ@=cnmhy#Ijp$n{Y_+N z6c4}o3a?!F*`e7Unjq0JR)3nNR`;)h!aXu-`^ootuH{*xN(P0IBWz9c==-2!LBI>| zjTUx)s9cJ#xA4LOLT+X_oLs+FICL?xp;ugdSP978G)WcDRFs$bn>%O8(Rr{+20F^ z=6y-ExuSCwuIb99;XP_!=5ULaN)^eY9Q7;Ac1~-BX}V&k^)-7zsKe%84>xd+p@$TL z!iV3u6-MK3KtB5BOxYT@8XQVYS9qKdoY5ioI@1OglwKzG5b#Z_#=Bm-}K&XX=v}+UZdBIKhozucPD)GycZRZ_& zkbXmO0axRZ7N1`QnsNO%*YkA^=rm0)7e4NEo1AEm!u4Tk_8Ca61<(=nb>F9?TgqR6 zkpxg$62`zRNQ3`+uGP3)vqkP}wYx*a;)p%m6t8QQAqd_|=|Jf~Uat*-dfPgey1U=S ze2980Z2n}vof%;~tgkp#M|oEAEs~-6ce1%UyB_MHy|8EqswZ+zP##TKeb1W`26v_?fog^!Pw(M;b?rZ^2HRZmM>`CN>Vz8 zPdMYJn1|O}sUFL94Vt{tel|hZo=x3rnVHMmuBS=QzV5upm)8{n*-x!!TECMBIpJJ# zu3v{Y^c+&qJz$*;V-tcksi>$ZsQa|>sQQw?D*-eS>PZC`@Ao-1cyeF`-TB8csk2O0 z{8@B%(}Lijb|JeJHUZmLEPJ)-B|g7A?8h5AG@As$!Ecu>kSJJqPo?F}Rrch*6!>bB zb92xwoGuiJ(w(2j0@efGjmipz5U}VmFs_UF1HaKF`j-XV$Cf#lQHPWBFs1G+aySU~ zx3;I!Uv)-DBkKi~9QBmU+)3OgV%4z&G{3WDJ!<1(Rp7L^QreX_vD!2pG`F&%XX+PE z|A5R#&&EI{z!7+At_90G$5kEpdrpMaxpQ+f%i1-He4Ux{&+7K~#pQMIUK=b#xisUK z7AR~12RjJDv{s;u>%q1sHMKh^b;iR9q|H`Nps!>HY74Curft>H-Wu&Im<|Vfgx6qi zOe=nxY?oFI+wTmDiAwdekQOSg;s$HT3aygR3h576~-=1iFLPDFIAgJ{$C z_$160xsp>_JIvYF>jMV5z3;9X_0^`hJw=@ch76Ov^)nMCR)K2%vy620c{M0Ni@^6^ z8zx6_Z%VREUbjA0h;-!(C+6F=J{l&A$z*p0_W6rqHHO$VDj8q_W(8@-p~gE9`Ezv+ zC5A+>1-G;>^xcz~j5q+@JmnYkc=|s0Wl%m%k$2kLW0pR)2rL?{&YT zCQ9J$vD3PKlU_m|5uNtm_^_b{>a+0gVuOE8&CLG3=HJIN36Yt+kaomqmCh0|X}6zy zuIMJ1w|I-m{9ImGQHoqnihU{Yi7574m=EIO;)(`a2cAg)KMm-l+U z3|wAt1IorVx+d8D>UgeX?GAfy0{o-Ke#eRu%0K^^kU+~kRh z?*0SzE&KC6HUXf0l}75|9>90WD**F>dcW1- z)L5ACaOryR#0bE>HsSXK{Le($ZM!o7WcaUIXa3;(U%VdxzAg9wpCEOo-_AB+q8H#Y ze*|V<_&!dzzy+9|PJlR2F1jt*LL&eLI8Pz549en(5#0P~`4Om%_=tovG-1e%3cx}} zavhRJ#KMFUnm}@I-wWhKqL&38`cCR#GVUJI%`(gu)I0db?N-xnqVIujvN(^B5XAw} zH|{4Ijk|G6cq*}aK_!=;>(CS##hsO!B+)N(#Rl%h`XTOcgQ9F(UvKsZO=s~Ne$r8`EtCgJT_ov)19AytAfKL8r;rT5n`dz5cl@49V*ut^B_2}l8t zB|={z2AUcG&@!NojP4MO24KI=v;gckf$@FHBlMTJ0JPw`843zgC^RKdn6K0}Q!tQ2 zm{Zsygp&S*a*#m(ITmrXX<&+7;M@qUC{f=A(0)0$*>+~J4LBw>>Q(VFxJ-)sDecSe4 z2gq0Sw3=+=0f}*4ef@p<$xKa=D&2Qp-Svm){xhClryKmVo*D z(XOlj-;NYFhte)u^_R-%oxTX1h5U_iOZVT;SJGvG&iVsqFp9IQPusyxGyuu)ZKZiQ zHYLZA-rmjrOGVBH1lqKkWL?oLN4dSbWo)8p%gLdt!Ih&Po zpwsnoaA}Mu3UIZ>#Z!Q13vB!Q1meK4;%)*Q7kj-c%!l&Ld`zX3{)f4P0Qy+jQ{E&cq(7m@GU+B)c(QBkpi=@^wXm`o)ZbYTszUI(j1yLenzK zPg4`L>hObQEEDwNT1w@m!Z0feX0bOr4-|J(Q%YkKHB+3%XtY{SFSYg_kLkQq&Y%s1 z4p)E|{F3^9DDXI;U4Xp-Oi&XPrKLm0zUb-wHSS_d_i+2$IX_zA40stl_v&srtxA+H z(W+?$49QnbYUk%awUW;Q=8!m8lPRD-UwU3zIOwsaa?1!%Cya7(+u8(Qjhg=rmQ8p{AFa}U-fEQq|m#%V3%6mj`P=pDLzA(hSa6#L4qF`m(;wP%B{!42+X=U%hmw(XRX| zIn(mvYr4&e-!}P+hCb@1JGc^4+Qpq-+~RLHTn^YiU*+YEz?iREd(4ESd86=}^X8GS z*47uqXFgyQqJaW{-LV$a+Au6}$#KJY0r_4Hc%2=wk1=R92|u54OYe5&NRwQt?(Fvh zy@|b%pPaidi}_V&rG6Mz2%uXpH@5~574atxU`WR1VVG(I7)^d+#~QyurARidw|u@P zCQj`JWL*7WH$UFY*n4q$tS9K!!XotYH_G1&I33VAkti{KOUsF=CC*j|fUFZ6j|NSeKN1%(a6i$s%*;Y$xsPk&Vxf}VlCJ6IPgt3K=OMrXIaL_}$Q?ul4q{ySD0q zdg5Xk;U(nL0M}96_-zf3KECE3-ho*?8mpWLF7ShhP8;N0;@5`nMaqx`~*f3EK zh1Rma)mWY%u2h0bi2re9NGT|s9?~E(619F@F8=M6f%7IuOHJ7{$7g7?>!l87vS$yp zdwez*0D~gcdkz3jwRLn%c^`)vFT6BiXEUaQgr6zj+M3Im$B(no_kid!WgbUqCmoF% ztER>Mb0j4-)#h+9rvyE%FuFk*#JHL3G3ZTO>U>|v^pXzj2mqW)9vACvfY!5d=MP0IxZecBsHasHS3SEppMJ`v?UJ@Tv`v_zQkC80%0VJddlZ z*<~}YR`Jh7=N!A!f5Ia7b~dlRJ^-%Y!SN7`8xWlPDrE{lJ-L)3m3j85!~fzGP84&V z?vfTvFVQ+_{$;Uq@S#eOfL%&hX9@N|a~p~KyqA{Kj!KK_APJ_0MiS-MK^E4Oshby4 zNp+F-ZDQ+C0NBu}r0=|YFoO6`L(e3-B&mZE=8x?Qz+66a4UGSH?nlV=rJ-JWWZ?M2e$Jyn8ZfqRN~6gy=wv@%yV5u z#$8H#;pYHJN?L#}KJ*P(^nm=|87jv9x%DS#-EgoS5gkzxz&isJIGc+E|MpCHQ$>4} zTZ)FU^3Y+QHj<=7w5I_m8go zz|Us{&okaud1?mYjW`biZ}R7rX?hHPS^Aet@$mMlSPNh;^@u|v&Y9$#nWU=Y2+63g z$^vO8tno*L8va z6_;q)`99~uC>Cgf2H+x@40!^Pdd4El(YE+xQ9_G#&A+_rM~7>lltR&M>R#L_p7XuQ z11HO$kWyYmFL>3^xg;g@Ns*r#-4?JqT2%Ap7CzELeGKVLIMQ#Ngs&2ZhUVcKLU=Bd z?&5!RLz4yl=AFyYOiwjBSxZu4&!9?OJ9=SfXK-aNc~~7uxvl+JwizfsMC)K+Zy0%> zcw&k0gl23U0MODj)XPIW05mla zaRK7_(UK}1)|S(*4>MB+FltXu=JmWS95dm)A^siGSp(olpA!I+F2FlD+vpHZSEzt7 zvb4%iB4@9Ml`*ogfDHrGgge{WTiJjn7Q3R7xpR?(K!YTd8vYOqs3Gv{16Cr|LD>H%B_@s_Ak{*U?&L? zAz@juBlUO7hgqr2pl|d8tlr@6`ImUzcMN|qX>PyG;tIDmd&G&iH(!Tz;dijp!Raub zeF7-~`1lB*rL1^-fzf^I{G(4}7DfM+;?CNdMdB5A0djm#-%2ezcQpwteL#9#>Jjcj zd4^D}kLa=EzZJUR(v5A@L}ag@AK+80v25?T303U!b*kM}Xt94fj`(Hr&f`kA+I-AB zeW9WM&eLh2)KaV-=a~8Xq!GqJY8@@2R{4nj#h1nfJ1C! zX(?G+O-28gO@AD@^zH~yO0Xudd=+?bJA3Ta!PstLj|xQn^{1)m8ynWbv*3v&qm+-^sBFi8wZZP~PM(?@CgoqabRS>7IYf}am!IwH8+Q=Q?xsM|1Jgsc)DUb z)1Z#GyNV?A2}?6$W8;cO;ic(a*`k#Dlw0&;q5Kf|mJn=eWLyv{NwD1f?+n4|YtQK` zgArb|3)e`ki8S5-bwu(?z#rWqGkza-QwneE@i@6wuZ1ue}#oj6=B^X%Ww5_LB#6Sw0eoetiSEvYPXzR_g_dHT za3@>-=bw=^Q-ghG_qfwGE0#~jQdZ7uzYqIC7#qaNdv1lAySwvTY-K&`VSSQ%4!UTy zuWWu*PMQf=T4uM0gao+jHPi?hKwS)MS~)s80(51FnS}K>;cN?4D&ZSMbby~`)eCo5 zap3;LByQT8HAaQP*A79!$I~oAs+>#mzOC9PXUEL`T3O8 zj2yd>V#RcT3r|yij$bD#!tLjTxYLXctbN*&mdi>MtQ3_FnpQ<0$i{bS zHm=aQqNYy^j(iiy7N6KSIq$Af^xH3U5r8SL$GTow^0}7Zu4gRT^7Wm8uEC2vV>N7p z^rfPgJNU>L1S&qgb5_q0&nQD;@1t^ zex%A2Sc1a5zNjHgt8U0E!^Mt*r@(bFtwF5F8{C7VVyMZ> z*kv8eKf%0rUGV8#`&Wd`M0vy+oJk3BV$R1tza;p({aC4`-d+++n~uG)<~irXh8ZS% zfAa`b54#WDY5n!S`Kh#;L#(jnv`u^Q?Mt`bFJUI}?7(?F=rn1ciJ9Fe!?h0w2n;jD zbOC2j31jIlUaoTG1{Y_d8m<`|`V%uX`ihtp*nG}-ONim=|DMec9F(}VmtI=OoS*rZ z_rs)YxL?g7WoO99I&!qaeu#aLpcz-2Ad`@Bmj=0q$68L3ATlI=Jz9!o@k}WsiVw0# z*J4_AZ;f`6p5n7bJPua&W)umif1v0}qqb*jp{e<6dXdOJeMwt~(9(82U@8+g=^^en z9{1b^bIW%ofa187HuAId#|M|EVk7Bb<)#`NEOJ#I-ee*8eb}Y0iZ{{3X}s5}ef>vI z-m6(Yi}JlT9KPb;Fz}{o@`G1UXY|{nWF5=F$#2E11-vji+)SU!?J~RLkXVolH^8&m zG{rxyn~H1`qC-ZpBa$}0%n!GPh`uRbBO)W;-`$z&{LO(grA~dgGnI?Y=!J?lFCJ;K zs`{hcD;^;6&5{L-z*q*VTn{h)|C1o{KW=XSkBXRW0ZA;>X`knebNt6)kuqOc2@mC! zj?}S&_nRZ}DTwt9 zf8Xm}IE0{BrXKUoKmuGJ#fLlLwU`c=8Mw!sB@2$n+ay#zL$PS)*VknHPk<&f;v|0= zE*p|6&{}0efVIDuP%HB;Z~ieS?nzI93*+DKf%DI;~Xn8 z6FUU9CzgG)v`kSM3!H?&5L=e>{=dKGi%3t|2fqLR>}~qr_Pp>W+=BAoD?^nlkc9YU zOkG*_nJgY@FtZXmK#P!pXzGnbEaNH4$;PdN(Hv`b)NJ{*~u!@$7kRjh7+p04)- z(2u4SnbscXqTqkU0-`@19i7MOCi#M2{K2X-_O!2VWMMrbl_`XpYb9>vaS=Go=kD7! z2u{zp3Yor!hFJ*nezD{%;5nhS+m#u>@Sw1-d713)vMu5ngzHfvfMpwkh%1)Al7#(> z-{hrDJH=Op**!eH$c)eX8^ON+uT_P2LX%?V-PBGvhXT=E)xgf^J z=XW{AZ0?C664ch!)qOW4q~yA9OFt^g&L(w+Wg%JyTd0r;fZhb4&QDIn9}^Q3o0@nH zK1Hs@(R{S_sis77cXqxVPv;MX;_`7eseQVjvQ01`AL^@#6;3h?+*eQ~cJ;gs_GXlQ!h8J@JS9xT$iUFcdGwI{(Q^elEPNCdkxuMKzi~w1#7J)L z)|E#8)vu_UC2O)>fVD$AZWsNQP600||E;AgxljgZ%f{ND_EiBV<}A&Vo52i?!Ph1% zsy}06W0o$8pC6Yyd*8o`)HiL676~!yHAB6Ud!G%BCoUL(UP}yK>9iX##3jDP&CaMr z4F@pes8-3A~>Rq&TxIo(Oxbc>r=uJCr-pstx+ckO{nl2xH>+8)Irj zruD};qysXc*yH8Y1@K9iBww{J4Ct&wX05+evGFFJe$-!p6Lj%#@dbSS`SsjFpee-z z(F{}v>FrtioD-#4~h7n$-{(!0VjWTFEw9KPxQl&gA)1=Q;Vt5~a8qce__!}dk5g5%rhEq{Y zb_e%kt>pkx?$IYkYct}LpR!uGLKBufB+qB?NFV;{z9;4{d!c!%5WNJlzJE%0W8q!Z zj15Y&aA{_k*6;&&eXtZKXB5cc2E((Xfw9z?ah*gT0|m&4bU32%OdF&GIz(Sr6pZL| z_Fbl~Kk5jp*8kc5ci*$hn9IFBMM0cPlv^Ai8tlSzkZ7=YNABvSD%YiC7FZs#%eiS- zFF-t~-%#Xj=i+rN53%F_plFujJCRtZp~bT~V7qtp))#$Tlc$=-l2nnvz*?ZE(%~Ps zz^cCfSZB~y0ULAzi@g||bm3>dkt~T&tFCzJpQ$U0ZJioYemRt4A?6tS`AKrq`tM0g zt|hUHxr{AB%t=|hx%X6%m{e&To)G^jj>^BkB|K1u&=s55ipjJ!F@7WKjXol!;64j7 zm=mX~_U+_8-mx!XQtIPUsrrK$A)7;{f;mmnsUp8ZH0fVG2 zPBx)bVw>@?F;OC|B?w>#E;ThZh8>PGWgoE7!5c@Sh~Z!e^$T+PExY;nAXzTJD+dQD zJU_!PJL%fd-5ehm>+5Q3^SPbt+PGoJ>|N4&wgZULUf_@eFxr!zz9nHP`olS2o~qm1 zYr>HlIxA%g4Gxw(y0{+i3!RWp@%)Hf*gQUWJR!Swf;72s<3`M`|L}Ju8Kdn*}JX`wy-+ z6waMz5IyoFYoqPV4@X~MaVc9b({aM>nBgm=L zY5!=2u~0(sxSc0Ukx-ay_q`6ao1zoI2YR{1ZO@kY*YLTC0_l`ttW} zzVqr9oV2CZ)=R#)P}Sb?YJBmX69xiu%LhLMqxaV*eVQ(~mEm-cxmhoV@q zA6{Am$NLV*mw}%1RJ#iX)XK1L+7kCK^57LTs64K6vB&=ub6nAzm@WV>4Lr=zRZGi20`biQ)<4D5$ z{+Dnb&h?~QQW9jux5tybGDCJE?{{3G#|hPa6$h>b;qpvvf8bBND^t{pyoj2=4%uQ< zz8IXDL4f+I%W3W(Y^dkKp~Zw`5tW`1EzKYf2kqhro36V33t{Ifuhfsyuk;3lk-RZ!Ond>n=Dww3yFkE1Hdv%oCwq zRh--J892;i4!&)}5yg@bJL4!{B*g@D_+cM;VrUkmZvmJLHOY_YDA!J=Slt?zH^s zxZit_Lakw&8m`(LS+VAx3^_}b9{f?5Ny`NBfJ0>}9@wnbTR#kV@dz~T+p<`)_o<7Q zjUG=~b_4g-#@DSf0#zS+t38C1&IB)#jpR>XDFdZdMr#-zhcXXDH<8;=`Tyu1F;Ev^ zJ#n)J>qfM`a=oBy)8V(XKOvoTK<4m;5K9v1Bz~tWX6dqatvSzM2oL!B8p^E*3`6>m z|DaBjHo~W%R>vsgPs06I+I??twXbgD)xn@9`oHDD|1xZun3<_E9;~Hx_nw@iLb2iB zUR~`8-f-kP8OXe=;o@|cm}>R}t^1FU?(boO_{)#2Rlr)%=H_B%LOD_W!0Ogk@ay}V z?}L-WH9obdYxu=4pTFKVHb@I`NeAyIPwVvjsV8}kr+#7|_w<2PNuD+)&Jyci8me2b z=Vx{3dVmZw*2&0dt2>4Xs?AQRTTZyi8OUIP4YX3ZSHRw|5jhfM#l0An*gbVi9@1SI zV-y+3@%$Cu7U3vJfjun9znfbr&*u(;#SKaJj_JzL=}Mt0=Uv9k#Gq%*iC~0Gb^=B= z!O>OT(5p+;HwmnKsD2vI_FUML+re3~iU(&Js$=aG#(F^JZ9}fAeJ4vPx35c2vK^v+ zWNyfDnNOoxg*ZAdvQW$V9b_0hyE17(oNhsaF*W9Pg4boOjR#!dNtD<}D9Ty(*RACm zcIFeCNqsMRP%$LaG;eD=xp-?ZhL~qB#Ky~wphrkpT{epcp<}0~bBkaDmpdzR{0w_} zI!4%@hKHz9678r=P+GrJx@NSEMku2jBIwQl)-Sslne`5HTg+}(#$rd+Z6)V^S^sHe z&o5nNPqO3+Pr(zny=oiR;bgunXoG3cO|#SMp}GcObk*br>;>&ocQ`l#iEpxb##8In zQ!YqATT_$9TY>98iMAL8P!{0h;{)qK_#0-efSq3HID~lq`T7P18>_2`x~o3RNjP%= zOA_=x&fW?n)Y2co6pCaGLQB)`)j#XK{$om8-_oJH_Kx&XJY*|&UW?~n#60}-%i_~@vF6iEC@<+h{Ra~6K4vbNtF#-f1v0+ayuJJ-a& zUoTPZ{*#?oXF=C0c6%bJ*)oGCQK2ljQlXCpvxZ|jX_A0WAQB>?$Xj1u-yIMI0`yFJ zzl|`1p5!RBSA4bXWVL`BZUS{Gpgp6|@Q(b=r?TO}F>w-h(c`@wkv2`EpRYptmU*~) zK}MC&3dg%IycI@@`rNcQ;)MUP( zOg%X+O-ics=3*QMhtcYTG#uZC73D2fkgRgy`niTLE!vBv$nW&yX1I47|sMt@!93i{Y)8iQRbar`>veH`g+f?S|B{9RS14$H~DoBSI870yDjNG<*x}kKJ(pcuo^g(*6%SVyxgn_xQA|2vde~yp0gK|vEwoPqp-;D zZOAc)dSc9?Y5wPfW|}qAc}wmywvG?RvCyw?6-Ua8qrKK0cVBJV5D{t(VhV4U^f$kY zsWzQ9?4#=V6oaEFPy;%m>PSrHR-r>GxeDe9w{u*4d(1;tl%g{r>q~rVzt-q3ScUPr zkRi68t_d~Oikl$jo_!6NCD?d)lq*7*TbUa+*zjT&v=wEB{~5>ZjG5Q18B!L<&+HP- zZwSOC{>@G5h4Tfszelq&TEDWTFgm)0hNTyFLf5`go4ct$;;7`vI(NF7K%NjUgAFd*DSKf?di))V7QgOs{#<~=opV54}3%~c`$ZJ(t*;v>u z$yaJy+F8UI*o58tg`{?pUJPy~L&VvsIS)%MI`kW|l_VcX1R~M0RmIx-j1RvBztess zL#&prZtn&#ZF;zaMhpa&ac+j7tmWrXKP%=%O!XIX2`{Imrs5M%P`&ooYw7D}q@~U7 z35Suc&?vJ2GL#ZehaW$VR-2sS)mw(AwuTie5N*ic^#R)*mNIXF-7B~ZctwCL_-;CX zt?2aXYNf%h;_ads>ubj$S+48VW*4NiaV!k)nZ(`z4xH2bn@zliysp(#S z6h0*6k_?b~Is=jW@4Uee0=OmpI54nc+S6Pn=`?41Pjhj2%X#jqHhyLwN1jI@@aOvO z@a1KtOJ_P{k3mOAj&1c>;)W%yTKC%86Rx80(PvW__wI2~H) zces-BpPoR6I|^cBugXnUA>C1$;t_6Y7}B_ElcTa8` z6i%8=sYjZXbdw%=B{Cq$wL`leB2XP82`bN91AqL6445T_2Ids+(?qy(t-mSPD|ZmKRR`*v-6moPFrQML9tL)Qn_kP~prO>;e$X{tOlj5YT}C;zf< zux%sVXi*gEmjgx%vC;APO?3kMY|j?mr}Xr1cp|Rnd|LAX>1Pl|w8)xvffQ-!6nQw4 zZ|){?G37V4{LF;-c^b~MxT}IcaF&*l;+p5?I{u)m5zXHpb@mCbbTyT*nCz`;fj@L{ zf2L^nCCMis46+yydx$?8RBq_R-k<%=U;ZzHWUTSpa+`Y0ciJJ=K@-5OR%%--1=ppC zSN1`?XsH(v>GqXrxe}Ba@CC-^A~BEyQL>Rz_>VTyT67NZsed$SwHVMD&z5ZL!$XcV zo{c7v=>{LXO`?d3DvlJ*a?KC@Ou}Vz8w&1NR=*fgH!`X*_UBxQr;bTy>d{*;)$!SzW~1^jrisSQ}jy!JtB4|)VLs?i`F)CJr>FK8fD{Q2Tq?Ml8*2(tao7$ zC$Kc3B_WM$yqdZBf`Kv-1)yX&7SNk4xDHdP`|>(P)%*XC8oK|l4DJ8Ze+Nkq-l1_n ZRB)tmeJQd{`vCm=BB>xzE@tTezW_{9!Giz* diff --git a/github/minui-menu-options-frontend.png b/github/minui-menu-options-frontend.png deleted file mode 100644 index 846fdbcc6fcdd272fe7516ffb5f0790896940a3b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24882 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 diff --git a/github/minui-menu-options-shortcuts.png b/github/minui-menu-options-shortcuts.png deleted file mode 100644 index 7f76f0b029accd25e5152cac25b5c8ba79e8df0d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24188 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