diff --git a/makefile b/makefile index 5388beeed..539005a3e 100644 --- a/makefile +++ b/makefile @@ -119,8 +119,8 @@ endif cp ./workspace/all/minarch/build/$(PLATFORM)/liblzma.* ./build/SYSTEM/$(PLATFORM)/lib/ cp ./workspace/all/minarch/build/$(PLATFORM)/libzstd.* ./build/SYSTEM/$(PLATFORM)/lib/ - # libchdr for RetroAchievements CHD hashing (use -L to dereference symlinks) - cp -L ./workspace/all/minarch/build/$(PLATFORM)/libchdr.so.0 ./build/SYSTEM/$(PLATFORM)/lib/ + # libchdr for RetroAchievements CHD hashing + cp ./workspace/all/minarch/build/$(PLATFORM)/libchdr.so.* ./build/SYSTEM/$(PLATFORM)/lib/ ifeq ($(PLATFORM), tg5040) # liblz4 for Rewind support diff --git a/workspace/all/common/generic_video.c b/workspace/all/common/generic_video.c index c022e7e4c..0d68a74ef 100644 --- a/workspace/all/common/generic_video.c +++ b/workspace/all/common/generic_video.c @@ -551,9 +551,16 @@ SDL_Surface* PLAT_initVideo(void) { LOG_info("- %s\n", SDL_GetPixelFormatName(info.texture_formats[i])); } - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); + if(strcmp("Desktop", PLAT_getModel()) == 0) { + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + } + else { + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); + } vid.gl_context = SDL_GL_CreateContext(vid.window); SDL_GL_MakeCurrent(vid.window, vid.gl_context); diff --git a/workspace/all/common/generic_wifi.c b/workspace/all/common/generic_wifi.c index 06bb13cf5..bf744a6f5 100644 --- a/workspace/all/common/generic_wifi.c +++ b/workspace/all/common/generic_wifi.c @@ -22,7 +22,7 @@ bool PLAT_hasWifi() { return true; } #define WIFI_INTERFACE "wlan0" -#define WPA_CLI_CMD "wpa_cli -p /etc/wifi/sockets -i " WIFI_INTERFACE +#define WPA_CLI_CMD "wpa_cli -p " WIFI_SOCK_DIR " -i " WIFI_INTERFACE #define wifilog(fmt, ...) \ LOG_note(PLAT_wifiDiagnosticsEnabled() ? LOG_INFO : LOG_DEBUG, fmt, ##__VA_ARGS__) @@ -331,6 +331,10 @@ int PLAT_wifiConnection(struct WIFI_connection *connection_info) connection_info->link_speed = (int)atof(bitrate + 11); } } + else { + wifilog("iw command is not supported."); + connection_info->rssi = -60; + } wifilog("Connected AP: %s\n", connection_info->ssid); wifilog("IP address: %s\n", connection_info->ip); diff --git a/workspace/all/minarch/libchdr.makefile b/workspace/all/minarch/libchdr.makefile index c93db66a0..49d8d3ec6 100644 --- a/workspace/all/minarch/libchdr.makefile +++ b/workspace/all/minarch/libchdr.makefile @@ -1,7 +1,9 @@ # Makefile wrapper for libchdr (CMake-based project) # Builds libchdr as a shared library for the target platform -PLATFORM ?= tg5040 +ifeq (,$(PLATFORM)) + $(error please specify PLATFORM, eg. PLATFORM=tg5040 make) +endif BUILD_DIR = build/$(PLATFORM) @@ -13,7 +15,7 @@ endif .PHONY: all build clean -all: build +all: build install build: $(BUILD_DIR)/libchdr.so @@ -23,6 +25,7 @@ $(BUILD_DIR)/libchdr.so: | $(BUILD_DIR) -DINSTALL_STATIC_LIBS=OFF \ -DCMAKE_BUILD_TYPE=Release \ -DWITH_SYSTEM_ZLIB=OFF \ + -DCMAKE_SHARED_LIBRARY_SUFFIX_C=".so" \ $(CMAKE_EXTRA) cd $(BUILD_DIR) && make -j$$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4) @# Copy the .so to expected location (cmake may put it in a subdir) @@ -35,5 +38,11 @@ $(BUILD_DIR)/libchdr.so: | $(BUILD_DIR) $(BUILD_DIR): mkdir -p $(BUILD_DIR) +install: $(BUILD_DIR)/libchdr.so + mkdir -p "$(PREFIX_LOCAL)/lib" + cp $(BUILD_DIR)/libchdr.so "$(PREFIX_LOCAL)/lib/" + mkdir -p "$(PREFIX_LOCAL)/include/libchdr" + cp -r include/libchdr/* "$(PREFIX_LOCAL)/include/libchdr/" + clean: rm -rf $(BUILD_DIR) diff --git a/workspace/all/minarch/makefile b/workspace/all/minarch/makefile index c587ec782..cb389dd9e 100644 --- a/workspace/all/minarch/makefile +++ b/workspace/all/minarch/makefile @@ -22,23 +22,18 @@ SDL?=SDL TARGET = minarch PRODUCT= build/$(PLATFORM)/$(TARGET).elf INCDIR = -I. -I./libretro-common/include/ -I../common/ -I../../$(PLATFORM)/platform/ -SOURCE = $(TARGET).c ../common/scaler.c ../common/utils.c ../common/config.c ../common/api.c ../common/notification.c ../common/http.c ../../$(PLATFORM)/platform/platform.c - -# RA support for tg5040, tg5050, and desktop -ifneq (,$(filter $(PLATFORM),tg5040 tg5050 desktop)) -# rcheevos include paths -INCDIR += -I../rcheevos/src/include -I../rcheevos/src/src -# libchdr include path (for CHD disc image support) -INCDIR += -I../libchdr/include +SOURCE = $(TARGET).c ../common/scaler.c ../common/utils.c ../common/config.c ../common/api.c ../common/notification.c ../../$(PLATFORM)/platform/platform.c + +# RA support +ifneq (,$(filter $(PLATFORM),tg5040 tg5050 my355 desktop)) # RA source files -SOURCE += ../common/ra_badges.c ra_integration.c chd_reader.c +SOURCE += ../common/http.c ../common/ra_badges.c ra_integration.c chd_reader.c endif CC = $(CROSS_COMPILE)gcc CFLAGS += $(OPT) CFLAGS += $(INCDIR) -DPLATFORM=\"$(PLATFORM)\" -std=gnu99 LDFLAGS += -lmsettings -lsamplerate -LDFLAGS += -llz4 ifeq ($(PROFILE), 1) CFLAGS += -pg @@ -50,6 +45,10 @@ CFLAGS += -g LDFLAGS += -lprofiler endif +# Rewind support +LDFLAGS += -llz4 + +# SaveRAM support ifeq ($(PLATFORM), desktop) ifeq ($(UNAME_S),Linux) CFLAGS += `pkg-config --cflags libzip` @@ -63,18 +62,17 @@ CFLAGS += -DHAS_SRM LDFLAGS += -lasound endif -# RA support: rcheevos and libchdr linking for tg5040, tg5050, and desktop -ifneq (,$(filter $(PLATFORM),tg5040 tg5050 desktop)) -LDFLAGS += -L../rcheevos/build/$(PLATFORM) -lrcheevos -LDFLAGS += -L../libchdr/build/$(PLATFORM) -lchdr -CFLAGS += -DRC_CLIENT_SUPPORTS_HASH +# RA support: rcheevos and libchdr linking +ifneq (,$(filter $(PLATFORM),tg5040 tg5050 my355 desktop)) +LDFLAGS += -lrcheevos -lchdr +CFLAGS += -DRC_CLIENT_SUPPORTS_HASH -DHAS_CHEEVOS -DHAS_CHDR ifeq ($(PLATFORM), desktop) # Desktop needs rpath for local shared library lookup LDFLAGS += -Wl,-rpath,'$$ORIGIN' endif endif -# CFLAGS += -Wall -Wno-unused-variable -Wno-unused-function -Wno-format-overflow +# Sanitizers ifeq ($(PLATFORM), desktop) ifeq ($(TSAN), 1) CFLAGS += -fsanitize=thread @@ -94,7 +92,7 @@ BUILD_HASH!=cat ../../hash.txt CFLAGS += -DBUILD_DATE=\"${BUILD_DATE}\" -DBUILD_HASH=\"${BUILD_HASH}\" ifeq ($(PLATFORM), desktop) -all: clean libretro-common rcheevos-desktop libchdr-desktop $(PREFIX_LOCAL)/include/msettings.h +all: clean libretro-common rcheevos libchdr $(PREFIX_LOCAL)/include/msettings.h mkdir -p build/$(PLATFORM) $(CC) $(SOURCE) -o $(PRODUCT) $(CFLAGS) $(LDFLAGS) else ifneq (,$(filter $(PLATFORM),tg5040 tg5050)) @@ -103,48 +101,45 @@ all: clean libretro-common libsrm.a rcheevos libchdr $(PREFIX_LOCAL)/include/mse mkdir -p build/$(PLATFORM) cp -L $(PREFIX)/lib/libsamplerate.so.* build/$(PLATFORM) # This is a bandaid fix, needs to be cleaned up if/when we expand to other platforms. - cp -L $(PREFIX)/lib/libzip.so.* build/$(PLATFORM) - cp -L $(PREFIX)/lib/libbz2.so.1.0 build/$(PLATFORM) - cp -L $(PREFIX)/lib/liblzma.so.5 build/$(PLATFORM) - 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.2 build/$(PLATFORM)/libchdr.so.0 - $(CC) $(SOURCE) -o $(PRODUCT) $(CFLAGS) $(LDFLAGS) -else -# Other platforms - no RA support -all: clean libretro-common libsrm.a $(PREFIX_LOCAL)/include/msettings.h - mkdir -p build/$(PLATFORM) - cp -L $(PREFIX)/lib/libsamplerate.so.* build/$(PLATFORM) - cp -L $(PREFIX)/lib/libzip.so.* build/$(PLATFORM) +ifeq ($(PLATFORM), my355) + cp -L $(PREFIX)/lib/libcrypto.so.3 build/$(PLATFORM) + cp -L $(PREFIX)/lib/libsqlite3.so build/$(PLATFORM) + cp -L $(PREFIX)/lib/libffi.so.7 build/$(PLATFORM) + cp -L $(PREFIX)/lib/libtinyalsa.so.2 build/$(PLATFORM) +endif + cp -L $(PREFIX)/lib/libsamplerate.so.0 build/$(PLATFORM) + cp -L $(PREFIX)/lib/libzip.so.5 build/$(PLATFORM) cp -L $(PREFIX)/lib/libbz2.so.1.0 build/$(PLATFORM) cp -L $(PREFIX)/lib/liblzma.so.5 build/$(PLATFORM) 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 libretro-common: git clone https://github.com/libretro/libretro-common -rcheevos: - cd ../rcheevos && make build PLATFORM=$(PLATFORM) +rcheevos: rcheevos/makefile $(PREFIX_LOCAL)/lib/librcheevos.a + +libchdr: libchdr/CMakeLists.txt $(PREFIX_LOCAL)/lib/libchdr.so -# Desktop rcheevos build - uses native gcc instead of cross-compiler -rcheevos-desktop: - cd ../rcheevos && make build PLATFORM=desktop +rcheevos/makefile: + rm -rf rcheevos + mkdir -p rcheevos + cp rcheevos.makefile rcheevos/makefile -../libchdr/CMakeLists.txt: - rm -rf ../libchdr - git clone https://github.com/rtissera/libchdr ../libchdr - cp libchdr.makefile ../libchdr/makefile +$(PREFIX_LOCAL)/lib/librcheevos.a: + cd rcheevos && make build install PLATFORM=$(PLATFORM) -libchdr: ../libchdr/CMakeLists.txt - cd ../libchdr && make build PLATFORM=$(PLATFORM) +libchdr/CMakeLists.txt: + rm -rf libchdr + git clone https://github.com/rtissera/libchdr + cp libchdr.makefile libchdr/makefile -# Desktop libchdr - build from source -libchdr-desktop: ../libchdr/CMakeLists.txt - cd ../libchdr && make build PLATFORM=desktop - +$(PREFIX_LOCAL)/lib/libchdr.so: + cd libchdr && make build install PLATFORM=$(PLATFORM) + $(PREFIX_LOCAL)/include/msettings.h: cd ../../$(PLATFORM)/libmsettings && make diff --git a/workspace/all/minarch/minarch.c b/workspace/all/minarch/minarch.c index 1c3240969..b257d81b0 100644 --- a/workspace/all/minarch/minarch.c +++ b/workspace/all/minarch/minarch.c @@ -30,10 +30,10 @@ #include "config.h" #include "ra_integration.h" #include "ra_badges.h" -#include "rc_client.h" #include #include #include +#include /////////////////////////////////////// diff --git a/workspace/all/minarch/ra_consoles.h b/workspace/all/minarch/ra_consoles.h index 9356e0f6b..8b4c62a53 100644 --- a/workspace/all/minarch/ra_consoles.h +++ b/workspace/all/minarch/ra_consoles.h @@ -8,8 +8,8 @@ * This is used to identify games when loading them for achievement tracking. */ -#include "rc_consoles.h" #include +#include /** * Mapping entry from EMU tag to RetroAchievements console ID diff --git a/workspace/all/minarch/ra_integration.c b/workspace/all/minarch/ra_integration.c index ddf503723..3f6a77291 100644 --- a/workspace/all/minarch/ra_integration.c +++ b/workspace/all/minarch/ra_integration.c @@ -1,8 +1,5 @@ #include "ra_integration.h" #include "ra_consoles.h" -#include "rc_client.h" -#include "rc_libretro.h" -#include "rc_hash.h" #include "chd_reader.h" #include "config.h" #include "http.h" @@ -19,6 +16,10 @@ #include #include +#include +#include +#include + // Logging macros - use NextUI log levels #define RA_LOG_DEBUG(fmt, ...) LOG_debug("[RA] " fmt, ##__VA_ARGS__) #define RA_LOG_INFO(fmt, ...) LOG_info("[RA] " fmt, ##__VA_ARGS__) diff --git a/workspace/all/minarch/rcheevos.makefile b/workspace/all/minarch/rcheevos.makefile new file mode 100644 index 000000000..4ac7861bd --- /dev/null +++ b/workspace/all/minarch/rcheevos.makefile @@ -0,0 +1,113 @@ +########################################################### +# rcheevos static library build for NextUI +########################################################### + +ifeq (,$(PLATFORM)) +PLATFORM=$(UNION_PLATFORM) +endif + +ifeq (,$(PLATFORM)) + $(error please specify PLATFORM, eg. PLATFORM=tg5040 make) +endif + +# Desktop builds use native compiler +ifeq (,$(CROSS_COMPILE)) + $(error missing CROSS_COMPILE for this toolchain) +endif + +########################################################### + +include ../../../$(PLATFORM)/platform/makefile.env + +########################################################### + +TARGET = rcheevos +SRCDIR = src/src +INCDIR = src/include +OBJDIR = build/$(PLATFORM)/obj + +# rcheevos source files +SOURCES = \ + $(SRCDIR)/rc_client.c \ + $(SRCDIR)/rc_compat.c \ + $(SRCDIR)/rc_util.c \ + $(SRCDIR)/rc_version.c \ + $(SRCDIR)/rc_libretro.c \ + $(SRCDIR)/rcheevos/alloc.c \ + $(SRCDIR)/rcheevos/condition.c \ + $(SRCDIR)/rcheevos/condset.c \ + $(SRCDIR)/rcheevos/consoleinfo.c \ + $(SRCDIR)/rcheevos/format.c \ + $(SRCDIR)/rcheevos/lboard.c \ + $(SRCDIR)/rcheevos/memref.c \ + $(SRCDIR)/rcheevos/operand.c \ + $(SRCDIR)/rcheevos/richpresence.c \ + $(SRCDIR)/rcheevos/runtime.c \ + $(SRCDIR)/rcheevos/runtime_progress.c \ + $(SRCDIR)/rcheevos/trigger.c \ + $(SRCDIR)/rcheevos/value.c \ + $(SRCDIR)/rcheevos/rc_validate.c \ + $(SRCDIR)/rapi/rc_api_common.c \ + $(SRCDIR)/rapi/rc_api_editor.c \ + $(SRCDIR)/rapi/rc_api_info.c \ + $(SRCDIR)/rapi/rc_api_runtime.c \ + $(SRCDIR)/rapi/rc_api_user.c \ + $(SRCDIR)/rhash/aes.c \ + $(SRCDIR)/rhash/cdreader.c \ + $(SRCDIR)/rhash/hash.c \ + $(SRCDIR)/rhash/hash_disc.c \ + $(SRCDIR)/rhash/hash_encrypted.c \ + $(SRCDIR)/rhash/hash_rom.c \ + $(SRCDIR)/rhash/hash_zip.c \ + $(SRCDIR)/rhash/md5.c + +# Object files go in platform-specific directory +OBJECTS = $(patsubst $(SRCDIR)/%.c,$(OBJDIR)/%.o,$(SOURCES)) + +CFLAGS += $(OPT) +CFLAGS += -I$(INCDIR) -I$(SRCDIR) -std=gnu99 +# libretro.h is in minarch/libretro-common/include +CFLAGS += -I../libretro-common/include +CFLAGS += -DRC_DISABLE_LUA +CFLAGS += -DRC_CLIENT_SUPPORTS_HASH +CFLAGS += -fPIC + +PRODUCT = build/$(PLATFORM)/lib$(TARGET).a + +# rcheevos version to use (can be overridden) +RCHEEVOS_VERSION ?= 40d916de00fe757bab40fb4db41a7912193a48e3 + +.PHONY: build clean install clone + +# Clone rcheevos source if not present +clone: + @if [ ! -f "src/include/rc_client.h" ]; then \ + echo "Cloning rcheevos..."; \ + rm -rf src; \ + git clone https://github.com/RetroAchievements/rcheevos.git src; \ + cd src && git checkout $(RCHEEVOS_VERSION); \ + fi + +# Build target: first clone, then compile (recursive make ensures sources exist) +build: clone + $(MAKE) $(PRODUCT) PLATFORM=$(PLATFORM) + +$(PRODUCT): $(OBJECTS) + mkdir -p build/$(PLATFORM) + $(AR) rcs $@ $(OBJECTS) + +$(OBJDIR)/%.o: $(SRCDIR)/%.c + mkdir -p $(dir $@) + $(CC) $(CFLAGS) -c -o $@ $< + +install: $(PRODUCT) + mkdir -p "$(PREFIX_LOCAL)/include/rcheevos" + mkdir -p "$(PREFIX_LOCAL)/lib" + cp $(INCDIR)/*.h "$(PREFIX_LOCAL)/include/rcheevos/" + cp $(SRCDIR)/rc_libretro.h "$(PREFIX_LOCAL)/include/rcheevos/" + cp $(PRODUCT) "$(PREFIX_LOCAL)/lib/" + +clean: + rm -rf build + rm -f $(PREFIX_LOCAL)/lib/lib$(TARGET).a + rm -rf $(PREFIX_LOCAL)/include/rcheevos diff --git a/workspace/all/rcheevos/makefile b/workspace/all/minarch/rcheevos/makefile similarity index 89% rename from workspace/all/rcheevos/makefile rename to workspace/all/minarch/rcheevos/makefile index 36513ca9a..4ac7861bd 100644 --- a/workspace/all/rcheevos/makefile +++ b/workspace/all/minarch/rcheevos/makefile @@ -11,19 +11,13 @@ ifeq (,$(PLATFORM)) endif # Desktop builds use native compiler -ifneq ($(PLATFORM), desktop) ifeq (,$(CROSS_COMPILE)) $(error missing CROSS_COMPILE for this toolchain) endif -ifeq (,$(PREFIX)) - $(error missing PREFIX for this toolchain) -endif -endif - ########################################################### -include ../../$(PLATFORM)/platform/makefile.env +include ../../../$(PLATFORM)/platform/makefile.env ########################################################### @@ -32,14 +26,6 @@ SRCDIR = src/src INCDIR = src/include OBJDIR = build/$(PLATFORM)/obj -ifeq ($(PLATFORM), desktop) -CC = gcc -AR = ar -else -CC = $(CROSS_COMPILE)gcc -AR = $(CROSS_COMPILE)ar -endif - # rcheevos source files SOURCES = \ $(SRCDIR)/rc_client.c \ @@ -78,10 +64,10 @@ SOURCES = \ # Object files go in platform-specific directory OBJECTS = $(patsubst $(SRCDIR)/%.c,$(OBJDIR)/%.o,$(SOURCES)) -CFLAGS += $(OPT) -fomit-frame-pointer +CFLAGS += $(OPT) CFLAGS += -I$(INCDIR) -I$(SRCDIR) -std=gnu99 # libretro.h is in minarch/libretro-common/include -CFLAGS += -I../minarch/libretro-common/include +CFLAGS += -I../libretro-common/include CFLAGS += -DRC_DISABLE_LUA CFLAGS += -DRC_CLIENT_SUPPORTS_HASH CFLAGS += -fPIC @@ -118,6 +104,7 @@ install: $(PRODUCT) mkdir -p "$(PREFIX_LOCAL)/include/rcheevos" mkdir -p "$(PREFIX_LOCAL)/lib" cp $(INCDIR)/*.h "$(PREFIX_LOCAL)/include/rcheevos/" + cp $(SRCDIR)/rc_libretro.h "$(PREFIX_LOCAL)/include/rcheevos/" cp $(PRODUCT) "$(PREFIX_LOCAL)/lib/" clean: diff --git a/workspace/all/nextui/nextui.c b/workspace/all/nextui/nextui.c index a6b59e246..e5fe5ebd3 100644 --- a/workspace/all/nextui/nextui.c +++ b/workspace/all/nextui/nextui.c @@ -2035,16 +2035,7 @@ int animWorker(void* unused) { AnimTask* task = node->task; finishedTask* finaltask = (finishedTask*)malloc(sizeof(finishedTask)); - int total_frames = task->frames; - // This somehow leads to the pill not rendering correctly when wrapping the list (last element to first, or reverse). - // TODO: Figure out why this is here. Ideally we shouldnt refer to specific platforms in here, but the commit message doesnt - // help all that much and comparing magic numbers also isnt that descriptive on its own. - if(strcmp("Desktop", PLAT_getModel()) != 0) { - if(task->targetY > task->startY + SCALE1(PILL_SIZE) || task->targetY < task->startY - SCALE1(PILL_SIZE)) { - total_frames = 0; - } - } - + 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; @@ -3089,7 +3080,7 @@ int main (int argc, char *argv[]) { pilltargetTextY = +screen->w; task->move_w = max_width; task->move_h = SCALE1(PILL_SIZE); - task->frames = should_animate && CFG_getMenuAnimations() ? 3:0; + task->frames = should_animate && CFG_getMenuAnimations() ? 3:1; task->entry_name = strdup(notext ? " " : entry_name); animPill(task); } diff --git a/workspace/all/settings/menu.cpp b/workspace/all/settings/menu.cpp index c49a714ae..98574dcc8 100644 --- a/workspace/all/settings/menu.cpp +++ b/workspace/all/settings/menu.cpp @@ -581,18 +581,18 @@ void MenuList::draw(SDL_Surface *surface, const SDL_Rect &dst) if (type != MenuItemType::Main && items.size() > scope.max_visible_options) { const int SCROLL_WIDTH = 24; - const int SCROLL_HEIGHT = 4; + const int SCROLL_HEIGHT = 6; SDL_Rect rect = dst; rect = dx(rect, (rect.w - SCALE1(SCROLL_WIDTH)) / 2); rect = dy(rect, SCALE1((-SCROLL_HEIGHT) / 2)); + rect.w = SCALE1(SCROLL_WIDTH); + rect.h -= SCALE1(PILL_SIZE); // account for description space at the bottom if (scope.start > 0) // assumes there is some padding above we can yoink GFX_blitAssetCPP(ASSET_SCROLL_UP, {}, surface, {rect.x, rect.y - SCALE1(PADDING)}); if (scope.end < scope.count) - // this is with 2 * pill_size bottom margin - // GFX_blitAssetCPP(ASSET_SCROLL_DOWN, {}, surface, {rect.x, rect.h - SCALE1(PADDING + PILL_SIZE + BUTTON_SIZE) + rect.y}); - GFX_blitAssetCPP(ASSET_SCROLL_DOWN, {}, surface, {rect.x, rect.h - SCALE1(PADDING + PILL_SIZE) + rect.y}); + GFX_blitAssetCPP(ASSET_SCROLL_DOWN, {}, surface, {rect.x, rect.y + rect.h + (SCALE1(SCROLL_HEIGHT) / 2)}); } if (cur && cur->getDesc().length() > 0) diff --git a/workspace/all/settings/settings.cpp b/workspace/all/settings/settings.cpp index 91fa7f35f..50c7fb5fa 100644 --- a/workspace/all/settings/settings.cpp +++ b/workspace/all/settings/settings.cpp @@ -139,25 +139,111 @@ namespace { } std::string extractBusyBoxVersion(const std::string& output) { - std::regex versionRegex(R"(BusyBox\s+v[\d.]+.*)"); + std::regex versionRegex(R"(BusyBox\s+(v[\d.]+))"); std::smatch match; if (std::regex_search(output, match, versionRegex)) { - return match.str(0); + return match.str(1); } return ""; } + + class DeviceInfo { + public: + enum Vendor { + Unknown, + Trimui, + Miyoo + }; + + enum Model { + UnknownModel, + Brick, + SmartPro, + SmartProS, + Flip + }; + + enum Platform { + UnknownPlatform, + tg5040, + tg5050, + my355 + }; + + DeviceInfo() { + char* device = getenv("DEVICE"); + if (device) { + if(exactMatch("brick", device)) { + m_vendor = Trimui; + m_model = Brick; + m_platform = tg5040; + } else if(exactMatch("smartpro", device)) { + m_vendor = Trimui; + m_model = SmartPro; + m_platform = tg5040; + } else if(exactMatch("smartpros", device)) { + m_vendor = Trimui; + m_model = SmartProS; + m_platform = tg5050; + } else if(exactMatch("my355", device)) { + m_vendor = Trimui; + m_model = Flip; + m_platform = my355; + } + } + } + + Vendor getVendor() const { return m_vendor; } + Model getModel() const { return m_model; } + Platform getPlatform() const { return m_platform; } + + bool hasColorTemperature() const { + return m_platform == tg5040; + } + + bool hasContrastSaturation() const { + return m_platform == my355 || m_platform == tg5040; + } + + bool hasExposure() const { + return m_platform == tg5040; + } + + bool hasActiveCooling() const { + return m_platform == tg5050; + } + + bool hasMuteToggle() const { + return m_platform == tg5050 || m_platform == tg5040; + } + + bool hasAnalogSticks() const { + return m_model == SmartPro || m_model == SmartProS; + } + + bool hasWifi() const { + return m_platform == tg5050 || m_platform == tg5040 || m_platform == my355; + } + + bool hasBluetooth() const { + return m_platform == tg5050 || m_platform == tg5040 || m_platform == my355; + } + + private: + Vendor m_vendor = Unknown; + Model m_model = UnknownModel; + Platform m_platform = UnknownPlatform; + }; } int main(int argc, char *argv[]) { try { - char* device = getenv("DEVICE"); - bool is_brick = exactMatch("brick", device); - bool is_smartpro_s = exactMatch("smartpros", device); + DeviceInfo deviceInfo; char version[128]; PLAT_getOsVersionInfo(version, 128); - LOG_info("This is TrimUI stock OS version %s\n", version); + LOG_info("This is stock OS version %s\n", version); InitSettings(); PWR_setCPUSpeed(CPU_SPEED_MENU); @@ -255,10 +341,6 @@ int main(int argc, char *argv[]) []() -> std::any { return CFG_getShowTools(); }, [](const std::any &value) { CFG_setShowTools(std::any_cast(value)); }, []() { CFG_setShowTools(CFG_DEFAULT_SHOWTOOLS);}}, - new MenuItem{ListItemType::Generic, "Show Collections", "Show \"Collections\" menu entry in game list.", {false, true}, on_off, - []() -> std::any { return CFG_getShowCollections(); }, - [](const std::any &value) { CFG_setShowCollections(std::any_cast(value)); }, - []() { CFG_setShowCollections(CFG_DEFAULT_SHOWCOLLECTIONS);}}, new MenuItem{ListItemType::Generic, "Show game art", "Show game artwork in the main menu", {false, true}, on_off, []() -> std::any { return CFG_getShowGameArt(); }, [](const std::any &value) @@ -291,14 +373,17 @@ int main(int argc, char *argv[]) }; - // tg5050 does not have display engine, no contrast/saturation/exposure/colortemp for now - if(exactMatch("smartpro", device) || exactMatch("brick", device)) + if(deviceInfo.hasColorTemperature()) { displayItems.push_back( new MenuItem{ListItemType::Generic, "Color temperature", "Color temperature (0 to 40)", 0, 40, "",[]() -> std::any { return GetColortemp(); }, [](const std::any &value) { SetColortemp(std::any_cast(value)); }, []() { SetColortemp(SETTINGS_DEFAULT_COLORTEMP);}}); + } + + if(deviceInfo.hasContrastSaturation()) + { displayItems.push_back( new MenuItem{ListItemType::Generic, "Contrast", "Contrast enhancement (-4 to 5)", -4, 5, "",[]() -> std::any { return GetContrast(); }, [](const std::any &value) @@ -309,6 +394,10 @@ int main(int argc, char *argv[]) { return GetSaturation(); }, [](const std::any &value) { SetSaturation(std::any_cast(value)); }, []() { SetSaturation(SETTINGS_DEFAULT_SATURATION);}}); + } + + if(deviceInfo.hasExposure()) + { displayItems.push_back( new MenuItem{ListItemType::Generic, "Exposure", "Exposure enhancement (-4 to 5)", -4, 5, "",[]() -> std::any { return GetExposure(); }, [](const std::any &value) @@ -381,7 +470,7 @@ int main(int argc, char *argv[]) []() { CFG_setUseExtractedFileName(CFG_DEFAULT_EXTRACTEDFILENAME);}} }; - if(exactMatch("smartpro", device) || exactMatch("brick", device)) + if(deviceInfo.getPlatform() == DeviceInfo::tg5040) { systemItems.push_back( new MenuItem{ListItemType::Generic, "Safe poweroff", "Bypasses the stock shutdown procedure to avoid the \"limbo bug\".\nInstructs the PMIC directly to soft disconnect the battery.", {false, true}, on_off, @@ -391,7 +480,7 @@ int main(int argc, char *argv[]) ); } - if(is_smartpro_s) + if(deviceInfo.hasActiveCooling()) { systemItems.push_back( new MenuItem{ListItemType::Generic, "Fan Speed", "Select the fan speed percentage (Quiet/Normal/Performance or 0-100%)", @@ -427,71 +516,82 @@ int main(int argc, char *argv[]) []() { SetMutedBrightness(SETTINGS_DEFAULT_MUTE_NO_CHANGE);}}, }; - if(exactMatch("smartpro", device) || exactMatch("brick", device)) + if(deviceInfo.hasMuteToggle()) { + if(deviceInfo.hasColorTemperature()) { + muteItems.push_back( + new MenuItem{ListItemType::Generic, "Color temperature when toggled", "Color temperature (0 to 40)", + {(int)SETTINGS_DEFAULT_MUTE_NO_CHANGE, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40}, + {"Unchanged","0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31","32","33","34","35","36","37","38","39","40"}, + []() -> std::any{ return GetMutedColortemp(); }, [](const std::any &value) + { SetMutedColortemp(std::any_cast(value)); }, + []() { SetMutedColortemp(SETTINGS_DEFAULT_MUTE_NO_CHANGE);}} + ); + } + if(deviceInfo.hasContrastSaturation()) { + muteItems.insert(muteItems.end(), { + new MenuItem{ListItemType::Generic, "Contrast when toggled", "Contrast enhancement (-4 to 5)", + {(int)SETTINGS_DEFAULT_MUTE_NO_CHANGE, -4,-3,-2,-1,0,1,2,3,4,5}, + {"Unchanged","-4","-3","-2","-1","0","1","2","3","4","5"}, + []() -> std::any { return GetMutedContrast(); }, [](const std::any &value) + { SetMutedContrast(std::any_cast(value)); }, + []() { SetMutedContrast(SETTINGS_DEFAULT_MUTE_NO_CHANGE);}}, + new MenuItem{ListItemType::Generic, "Saturation when toggled", "Saturation enhancement (-5 to 5)", + {(int)SETTINGS_DEFAULT_MUTE_NO_CHANGE, -5,-4,-3,-2,-1,0,1,2,3,4,5}, + {"Unchanged","-5","-4","-3","-2","-1","0","1","2","3","4","5"}, + []() -> std::any{ return GetMutedSaturation(); }, [](const std::any &value) + { SetMutedSaturation(std::any_cast(value)); }, + []() { SetMutedSaturation(SETTINGS_DEFAULT_MUTE_NO_CHANGE);}}} + ); + } + if(deviceInfo.hasExposure()) { + muteItems.push_back( + new MenuItem{ListItemType::Generic, "Exposure when toggled", "Exposure enhancement (-4 to 5)", + {(int)SETTINGS_DEFAULT_MUTE_NO_CHANGE, -4,-3,-2,-1,0,1,2,3,4,5}, + {"Unchanged","-4","-3","-2","-1","0","1","2","3","4","5"}, + []() -> std::any { return GetMutedExposure(); }, [](const std::any &value) + { SetMutedExposure(std::any_cast(value)); }, + []() { SetMutedExposure(SETTINGS_DEFAULT_MUTE_NO_CHANGE);}} + ); + } + muteItems.insert(muteItems.end(), { - new MenuItem{ListItemType::Generic, "Color temperature when toggled", "Color temperature (0 to 40)", - {(int)SETTINGS_DEFAULT_MUTE_NO_CHANGE, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40}, - {"Unchanged","0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31","32","33","34","35","36","37","38","39","40"}, - []() -> std::any{ return GetMutedColortemp(); }, [](const std::any &value) - { SetMutedColortemp(std::any_cast(value)); }, - []() { SetMutedColortemp(SETTINGS_DEFAULT_MUTE_NO_CHANGE);}}, - new MenuItem{ListItemType::Generic, "Contrast when toggled", "Contrast enhancement (-4 to 5)", - {(int)SETTINGS_DEFAULT_MUTE_NO_CHANGE, -4,-3,-2,-1,0,1,2,3,4,5}, - {"Unchanged","-4","-3","-2","-1","0","1","2","3","4","5"}, - []() -> std::any { return GetMutedContrast(); }, [](const std::any &value) - { SetMutedContrast(std::any_cast(value)); }, - []() { SetMutedContrast(SETTINGS_DEFAULT_MUTE_NO_CHANGE);}}, - new MenuItem{ListItemType::Generic, "Saturation when toggled", "Saturation enhancement (-5 to 5)", - {(int)SETTINGS_DEFAULT_MUTE_NO_CHANGE, -5,-4,-3,-2,-1,0,1,2,3,4,5}, - {"Unchanged","-5","-4","-3","-2","-1","0","1","2","3","4","5"}, - []() -> std::any{ return GetMutedSaturation(); }, [](const std::any &value) - { SetMutedSaturation(std::any_cast(value)); }, - []() { SetMutedSaturation(SETTINGS_DEFAULT_MUTE_NO_CHANGE);}}, - new MenuItem{ListItemType::Generic, "Exposure when toggled", "Exposure enhancement (-4 to 5)", - {(int)SETTINGS_DEFAULT_MUTE_NO_CHANGE, -4,-3,-2,-1,0,1,2,3,4,5}, - {"Unchanged","-4","-3","-2","-1","0","1","2","3","4","5"}, - []() -> std::any { return GetMutedExposure(); }, [](const std::any &value) - { SetMutedExposure(std::any_cast(value)); }, - []() { SetMutedExposure(SETTINGS_DEFAULT_MUTE_NO_CHANGE);}}}); + new MenuItem{ListItemType::Generic, "Turbo fire A", "Enable turbo fire A", {0, 1}, on_off, []() -> std::any + { return GetMuteTurboA(); }, + [](const std::any &value) { SetMuteTurboA(std::any_cast(value));}, + []() { SetMuteTurboA(0);}}, + new MenuItem{ListItemType::Generic, "Turbo fire B", "Enable turbo fire B", {0, 1}, on_off, []() -> std::any + { return GetMuteTurboB(); }, + [](const std::any &value) { SetMuteTurboB(std::any_cast(value));}, + []() { SetMuteTurboB(0);}}, + new MenuItem{ListItemType::Generic, "Turbo fire X", "Enable turbo fire X", {0, 1}, on_off, []() -> std::any + { return GetMuteTurboX(); }, + [](const std::any &value) { SetMuteTurboX(std::any_cast(value));}, + []() { SetMuteTurboX(0);}}, + new MenuItem{ListItemType::Generic, "Turbo fire Y", "Enable turbo fire Y", {0, 1}, on_off, []() -> std::any + { return GetMuteTurboY(); }, + [](const std::any &value) { SetMuteTurboY(std::any_cast(value));}, + []() { SetMuteTurboY(0);}}, + new MenuItem{ListItemType::Generic, "Turbo fire L1", "Enable turbo fire L1", {0, 1}, on_off, []() -> std::any + { return GetMuteTurboL1(); }, + [](const std::any &value) { SetMuteTurboL1(std::any_cast(value));}, + []() { SetMuteTurboL1(0);}}, + new MenuItem{ListItemType::Generic, "Turbo fire L2", "Enable turbo fire L2", {0, 1}, on_off, []() -> std::any + { return GetMuteTurboL2(); }, + [](const std::any &value) { SetMuteTurboL2(std::any_cast(value));}, + []() { SetMuteTurboL2(0);}}, + new MenuItem{ListItemType::Generic, "Turbo fire R1", "Enable turbo fire R1", {0, 1}, on_off, []() -> std::any + { return GetMuteTurboR1(); }, + [](const std::any &value) { SetMuteTurboR1(std::any_cast(value));}, + []() { SetMuteTurboR1(0);}}, + new MenuItem{ListItemType::Generic, "Turbo fire R2", "Enable turbo fire R2", {0, 1}, on_off, []() -> std::any + { return GetMuteTurboR2(); }, + [](const std::any &value) { SetMuteTurboR2(std::any_cast(value));}, + []() { SetMuteTurboR2(0);}} + }); } - muteItems.insert(muteItems.end(), { - new MenuItem{ListItemType::Generic, "Turbo fire A", "Enable turbo fire A", {0, 1}, on_off, []() -> std::any - { return GetMuteTurboA(); }, - [](const std::any &value) { SetMuteTurboA(std::any_cast(value));}, - []() { SetMuteTurboA(0);}}, - new MenuItem{ListItemType::Generic, "Turbo fire B", "Enable turbo fire B", {0, 1}, on_off, []() -> std::any - { return GetMuteTurboB(); }, - [](const std::any &value) { SetMuteTurboB(std::any_cast(value));}, - []() { SetMuteTurboB(0);}}, - new MenuItem{ListItemType::Generic, "Turbo fire X", "Enable turbo fire X", {0, 1}, on_off, []() -> std::any - { return GetMuteTurboX(); }, - [](const std::any &value) { SetMuteTurboX(std::any_cast(value));}, - []() { SetMuteTurboX(0);}}, - new MenuItem{ListItemType::Generic, "Turbo fire Y", "Enable turbo fire Y", {0, 1}, on_off, []() -> std::any - { return GetMuteTurboY(); }, - [](const std::any &value) { SetMuteTurboY(std::any_cast(value));}, - []() { SetMuteTurboY(0);}}, - new MenuItem{ListItemType::Generic, "Turbo fire L1", "Enable turbo fire L1", {0, 1}, on_off, []() -> std::any - { return GetMuteTurboL1(); }, - [](const std::any &value) { SetMuteTurboL1(std::any_cast(value));}, - []() { SetMuteTurboL1(0);}}, - new MenuItem{ListItemType::Generic, "Turbo fire L2", "Enable turbo fire L2", {0, 1}, on_off, []() -> std::any - { return GetMuteTurboL2(); }, - [](const std::any &value) { SetMuteTurboL2(std::any_cast(value));}, - []() { SetMuteTurboL2(0);}}, - new MenuItem{ListItemType::Generic, "Turbo fire R1", "Enable turbo fire R1", {0, 1}, on_off, []() -> std::any - { return GetMuteTurboR1(); }, - [](const std::any &value) { SetMuteTurboR1(std::any_cast(value));}, - []() { SetMuteTurboR1(0);}}, - new MenuItem{ListItemType::Generic, "Turbo fire R2", "Enable turbo fire R2", {0, 1}, on_off, []() -> std::any - { return GetMuteTurboR2(); }, - [](const std::any &value) { SetMuteTurboR2(std::any_cast(value));}, - []() { SetMuteTurboR2(0);}} - }); - - if(is_brick) { + if(deviceInfo.hasMuteToggle() && deviceInfo.hasAnalogSticks()){ muteItems.push_back( new MenuItem{ListItemType::Generic, "Dpad mode when toggled", "Dpad: default. Joystick: Dpad exclusively acts as analog stick.\nBoth: Dpad and Joystick inputs at the same time.", {0, 1, 2}, {"Dpad", "Joystick", "Both"}, []() -> std::any { @@ -513,14 +613,6 @@ int main(int argc, char *argv[]) } muteItems.push_back(new MenuItem{ListItemType::Button, "Reset to defaults", "Resets all options in this menu to their default values.", ResetCurrentMenu}); - auto muteMenu = new MenuList(MenuItemType::Fixed, "FN Switch", muteItems); - - // TODO: check WIFI_supported(), hide menu otherwise - auto networkMenu = new Wifi::Menu(appQuit, ctx.dirty); - - // TODO: check BT_supported(), hide menu otherwise - auto btMenu = new Bluetooth::Menu(appQuit, ctx.dirty); - auto notificationsMenu = new MenuList(MenuItemType::Fixed, "Notifications", { new MenuItem{ListItemType::Generic, "Save states", "Show notification when saving game state", {false, true}, on_off, @@ -647,13 +739,13 @@ int main(int argc, char *argv[]) new MenuItem{ListItemType::Generic, "Notifications", "Save state notifications", {}, {}, nullptr, nullptr, DeferToSubmenu, notificationsMenu}, new MenuItem{ListItemType::Generic, "RetroAchievements", "Achievement tracking settings", {}, {}, nullptr, nullptr, DeferToSubmenu, retroAchievementsMenu}, }); - + // We need to alert the user about potential issues if the // stock OS was modified in way that are known to cause issues std::string bbver = extractBusyBoxVersion(execCommand("cat --help")); if (bbver.empty()) bbver = "BusyBox version not found."; - else if(bbver.find(BUSYBOX_STOCK_VERSION) == std::string::npos && (exactMatch("smartpro", device) || exactMatch("brick", device))) + else if(deviceInfo.getPlatform() == DeviceInfo::tg5040 && bbver.find(BUSYBOX_STOCK_VERSION) == std::string::npos) ctx.menu->showOverlay( "Stock OS changes detected.\n" "This may cause instability or issues.\n" @@ -685,17 +777,27 @@ int main(int argc, char *argv[]) }, }); - ctx.menu = new MenuList(MenuItemType::List, "Main", - { + std::vector mainItems = { new MenuItem{ListItemType::Generic, "Appearance", "UI customization", {}, {}, nullptr, nullptr, DeferToSubmenu, appearanceMenu}, new MenuItem{ListItemType::Generic, "Display", "", {}, {}, nullptr, nullptr, DeferToSubmenu, displayMenu}, new MenuItem{ListItemType::Generic, "System", "", {}, {}, nullptr, nullptr, DeferToSubmenu, systemMenu}, - new MenuItem{ListItemType::Generic, "FN switch", "FN switch settings", {}, {}, nullptr, nullptr, DeferToSubmenu, muteMenu}, - new MenuItem{ListItemType::Generic, "In-Game", "In-game settings for MinArch", {}, {}, nullptr, nullptr, DeferToSubmenu, minarchMenu}, - new MenuItem{ListItemType::Generic, "Network", "", {}, {}, nullptr, nullptr, DeferToSubmenu, networkMenu}, - new MenuItem{ListItemType::Generic, "Bluetooth", "", {}, {}, nullptr, nullptr, DeferToSubmenu, btMenu}, - new MenuItem{ListItemType::Generic, "About", "", {}, {}, nullptr, nullptr, DeferToSubmenu, aboutMenu}, - }); + }; + + if(deviceInfo.hasMuteToggle()) + mainItems.push_back(new MenuItem{ListItemType::Generic, "FN switch", "FN switch settings", {}, {}, nullptr, nullptr, DeferToSubmenu, + new MenuList(MenuItemType::Fixed, "FN Switch", muteItems)}); + + mainItems.push_back(new MenuItem{ListItemType::Generic, "In-Game", "In-game settings for MinArch", {}, {}, nullptr, nullptr, DeferToSubmenu, minarchMenu}); + + if(deviceInfo.hasWifi()) + mainItems.push_back(new MenuItem{ListItemType::Generic, "Network", "", {}, {}, nullptr, nullptr, DeferToSubmenu, new Wifi::Menu(appQuit, ctx.dirty)}); + + if(deviceInfo.hasBluetooth()) + mainItems.push_back(new MenuItem{ListItemType::Generic, "Bluetooth", "", {}, {}, nullptr, nullptr, DeferToSubmenu, new Bluetooth::Menu(appQuit, ctx.dirty)}); + + mainItems.push_back(new MenuItem{ListItemType::Generic, "About", "", {}, {}, nullptr, nullptr, DeferToSubmenu, aboutMenu}); + + ctx.menu = new MenuList(MenuItemType::List, "Main", mainItems); const bool showTitle = false; const bool showIndicator = true; @@ -822,4 +924,4 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; } -} +} \ No newline at end of file diff --git a/workspace/all/show2/show2.cpp b/workspace/all/show2/show2.cpp index 612f82b35..92515a568 100644 --- a/workspace/all/show2/show2.cpp +++ b/workspace/all/show2/show2.cpp @@ -165,21 +165,19 @@ class ShowApp { std::cerr << "Image not found: " << config.image_path << std::endl; } - // Initialize font for progress/daemon modes - if (config.mode != DisplayMode::Simple) { - if (TTF_Init() < 0) { - std::cerr << "TTF_Init failed: " << TTF_GetError() << std::endl; - } else { - SDL_RWops* rw = SDL_RWFromConstMem(RoundedMplus1c_Bold_reduced_ttf, - RoundedMplus1c_Bold_reduced_ttf_len); - if (rw) { - font = TTF_OpenFontRW(rw, 1, config.font_size); - if (!font) { - std::cerr << "Failed to load embedded font: " << TTF_GetError() << std::endl; - } - } else { - std::cerr << "Failed to create RWops for embedded font" << std::endl; + // Initialize font + if (TTF_Init() < 0) { + std::cerr << "TTF_Init failed: " << TTF_GetError() << std::endl; + } else { + SDL_RWops* rw = SDL_RWFromConstMem(RoundedMplus1c_Bold_reduced_ttf, + RoundedMplus1c_Bold_reduced_ttf_len); + if (rw) { + font = TTF_OpenFontRW(rw, 1, config.font_size); + if (!font) { + std::cerr << "Failed to load embedded font: " << TTF_GetError() << std::endl; } + } else { + std::cerr << "Failed to create RWops for embedded font" << std::endl; } } @@ -344,20 +342,6 @@ class ShowApp { } void renderSimple() { - if (logo) { - // Center image without stretching - use original dimensions - SDL_Rect src = {0, 0, logo->w, logo->h}; - SDL_Rect dst = { - (screen->w - logo->w) / 2, - (screen->h - logo->h) / 2, - logo->w, - logo->h - }; - SDL_BlitSurface(logo, &src, screen, &dst); - } - } - - void renderProgress() { // Draw logo - always centered without stretching if (logo) { SDL_Rect src = {0, 0, logo->w, logo->h}; @@ -385,6 +369,10 @@ class ShowApp { SDL_FreeSurface(text_surface); } } + } + + void renderProgress() { + renderSimple(); // Draw logo and text first // Draw progress bar at percentage-based Y position int progress_y = (screen->h * current_progress_y_pct) / 100; @@ -543,7 +531,9 @@ std::map parseArguments(int argc, char* argv[]) { void printUsage() { std::cout << "Usage:\n"; - std::cout << " Simple mode: show2.elf --mode=simple --image= [--bgcolor=0x000000] [--logoheight=N] [--timeout=N]\n"; + std::cout << " Simple mode: show2.elf --mode=simple --image= [--bgcolor=0x000000] [--fontcolor=0xFFFFFF]\n"; + std::cout << " [--text=\"message\"] [--texty=80] [--progressy=90]\n"; + std::cout << " [--logoheight=N] [--fontsize=24] [--timeout=N]\n"; std::cout << " Progress mode: show2.elf --mode=progress --image= [--bgcolor=0x000000] [--fontcolor=0xFFFFFF]\n"; std::cout << " [--text=\"message\"] [--progress=0] [--texty=80] [--progressy=90]\n"; std::cout << " [--logoheight=N] [--fontsize=24] [--timeout=N]\n"; @@ -641,4 +631,4 @@ int main(int argc, char* argv[]) { app.run(); return 0; -} +} \ No newline at end of file diff --git a/workspace/tg5040/platform/platform.c b/workspace/tg5040/platform/platform.c index 24d591375..07b915b55 100644 --- a/workspace/tg5040/platform/platform.c +++ b/workspace/tg5040/platform/platform.c @@ -987,6 +987,7 @@ void PLAT_setNetworkTimeSync(bool on) { ///////////////////////// // We use the generic wifi implementation here +#define WIFI_SOCK_DIR "/etc/wifi/sockets" #include "generic_wifi.c" ///////////////////////// diff --git a/workspace/tg5040/platform/platform.h b/workspace/tg5040/platform/platform.h index 410438404..6e2ef67ed 100644 --- a/workspace/tg5040/platform/platform.h +++ b/workspace/tg5040/platform/platform.h @@ -5,7 +5,9 @@ /////////////////////////////// -#include "sdl.h" +#ifdef SDL +# include "sdl.h" +#endif /////////////////////////////// diff --git a/workspace/tg5050/platform/platform.c b/workspace/tg5050/platform/platform.c index 220d708fa..cef0e80d0 100644 --- a/workspace/tg5050/platform/platform.c +++ b/workspace/tg5050/platform/platform.c @@ -931,6 +931,7 @@ void PLAT_setNetworkTimeSync(bool on) { ///////////////////////// // We use the generic wifi implementation here +#define WIFI_SOCK_DIR "/etc/wifi/sockets" #include "generic_wifi.c" /////////////////////////