diff --git a/RetroFE/Source/CMakeLists.txt b/RetroFE/Source/CMakeLists.txt index e8f172743..e50b9878f 100644 --- a/RetroFE/Source/CMakeLists.txt +++ b/RetroFE/Source/CMakeLists.txt @@ -372,8 +372,8 @@ set(RETROFE_SOURCES "${KISSFFT_ROOT}/kiss_fftr.c" ) -set(EXECUTABLE_OUTPUT_PATH "${RETROFE_DIR}/Build" CACHE PATH "Build directory" FORCE) -set(LIBRARY_OUTPUT_PATH "${RETROFE_DIR}/Build" CACHE PATH "Build directory" FORCE) +set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}" CACHE PATH "Build directory" FORCE) +set(LIBRARY_OUTPUT_PATH "${CMAKE_BINARY_DIR}" CACHE PATH "Build directory" FORCE) include_directories(${RETROFE_INCLUDE_DIRS}) add_executable(retrofe ${RETROFE_SOURCES} ${RETROFE_HEADERS}) diff --git a/RetroFE/Source/Database/HiScores.h b/RetroFE/Source/Database/HiScores.h index 281b30a0c..b20af3326 100644 --- a/RetroFE/Source/Database/HiScores.h +++ b/RetroFE/Source/Database/HiScores.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -76,7 +77,7 @@ class HiScores { // Direct upsert (if caller already has rows for an id) void upsertIScoredGame(const std::string& gameId, const std::string& gameName, - const std::vector& rows); // replaces that id’s rows + const std::vector& rows); // replaces that id�s rows // Shutdown cleanup (persist if you want, then clear) void deinitialize(); diff --git a/RetroFE/Source/Execute/Launcher.cpp b/RetroFE/Source/Execute/Launcher.cpp index 42b673150..b44cb0e01 100644 --- a/RetroFE/Source/Execute/Launcher.cpp +++ b/RetroFE/Source/Execute/Launcher.cpp @@ -28,6 +28,7 @@ #include "../Utility/Utils.h" // --- C++ Standard Library --- +#include #include #include // For getenv #include @@ -35,6 +36,7 @@ #include // For std::unique_ptr #include #include +#include // --- New Refactored Components --- #include "Input/InputMonitor.h" @@ -365,7 +367,7 @@ bool Launcher::run(std::string collection, Item* collectionItem, Page* currentPa break; } case PreWaitMode::UpToMs: { - // IMPORTANT: use simpleLaunch() so job-close doesn’t kill it + // IMPORTANT: use simpleLaunch() so job-close doesn�t kill it LOG_INFO("Launcher", std::string("Waiting up to ") + std::to_string(preWaitMs) + " ms for pre-hook (non-blocking)..."); if (!preMgr->simpleLaunch(pExe.string(), preArgs, pCwd.string())) { LOG_ERROR("Launcher", "Pre-hook failed to start: " + pExe.string()); @@ -379,14 +381,14 @@ bool Launcher::run(std::string collection, Item* collectionItem, Page* currentPa // ~30fps std::this_thread::sleep_for(std::chrono::milliseconds(33)); } - // We can’t know exit code in this mode (no handle by design) + // We can�t know exit code in this mode (no handle by design) LOG_INFO("Launcher", std::string("Pre-hook still running after ") + std::to_string(preWaitMs) + " ms; continuing."); break; } case PreWaitMode::NoWait: default: { - // IMPORTANT: use simpleLaunch() so job-close doesn’t kill it + // IMPORTANT: use simpleLaunch() so job-close doesn�t kill it if (!preMgr->simpleLaunch(pExe.string(), preArgs, pCwd.string())) { LOG_ERROR("Launcher", "Pre-hook failed to start: " + pExe.string()); return false; diff --git a/RetroFE/Source/Execute/Platform/Unix/UnixProcessManager.cpp b/RetroFE/Source/Execute/Platform/Unix/UnixProcessManager.cpp index 50f71a243..d8c5c1ee4 100644 --- a/RetroFE/Source/Execute/Platform/Unix/UnixProcessManager.cpp +++ b/RetroFE/Source/Execute/Platform/Unix/UnixProcessManager.cpp @@ -69,7 +69,8 @@ bool UnixProcessManager::simpleLaunch(const std::string& executable, const std:: } } - std::string commandLine = executable + " " + args; + std::string quotedExecutable = "\"" + executable + "\""; + std::string commandLine = quotedExecutable + " " + args; WordExpWrapper we; if (wordexp(commandLine.c_str(), &we.p, WRDE_NOCMD) != 0) { _exit(EXIT_FAILURE); @@ -98,7 +99,8 @@ bool UnixProcessManager::launch(const std::string& executable, } // Build argv via wordexp (blocks command substitution) - std::string commandLine = executable + " " + args; + std::string quotedExecutable = "\"" + executable + "\""; + std::string commandLine = quotedExecutable + " " + args; WordExpWrapper we; if (wordexp(commandLine.c_str(), &we.p, WRDE_NOCMD) != 0) { LOG_ERROR("ProcessManager", "Failed to parse command line: " + commandLine); @@ -204,7 +206,7 @@ bool UnixProcessManager::launch(const std::string& executable, return false; } - // Short/partial read: unexpected—treat as failure. + // Short/partial read: unexpected�treat as failure. { int status = 0; (void)waitpid(pid_, &status, 0); LOG_ERROR("ProcessManager", "Launch status unknown (short read). Treating as failure."); @@ -246,7 +248,7 @@ WaitResult UnixProcessManager::wait(double timeoutSeconds, const std::function #include +#include #include #include diff --git a/RetroFE/Source/SDL.cpp b/RetroFE/Source/SDL.cpp index 066045790..125d006a3 100644 --- a/RetroFE/Source/SDL.cpp +++ b/RetroFE/Source/SDL.cpp @@ -524,7 +524,7 @@ bool SDL::initialize(Configuration& config) { MusicPlayer* mp; // nullptr if music player disabled }; - // … during init … + // � during init � bool musicPlayerEnabled = false; config.getProperty("musicPlayer.enabled", musicPlayerEnabled); @@ -1529,28 +1529,10 @@ bool SDL::renderCopyF(SDL_Texture* texture, return SDL_RenderCopyF(renderer_[m], texture, &srcRect, &dPx) == 0; } - // === MID PATH (per-item angle only; no mirror, no reflection, no global rot) === - if (!mir && !viewInfo.hasReflection && rot == 0 && viewInfo.Angle != 0.0f) { - SDL_Rect s = srcRect; - SDL_FRect d = dstRect; - - if (hasContainer) { - const float rx0 = d.x, ry0 = d.y, rx1 = d.x + d.w, ry1 = d.y + d.h; - const float cx0 = container.x, cy0 = container.y; - const float cx1 = cx0 + container.w, cy1 = cy0 + container.h; - if (rx1 <= cx0 || ry1 <= cy0 || rx0 >= cx1 || ry0 >= cy1) return true; - - const SDL_Rect sCopy = s; const SDL_FRect dCopy = d; - clip_to_container(s, d, sCopy, dCopy); - if (d.w <= 0.f || d.h <= 0.f || s.w <= 0 || s.h <= 0) return true; - } - - SDL_FRect dPx = to_pixels(d); - set_alpha_if_needed(clamp_u8(alpha)); - return SDL_RenderCopyExF(renderer_[m], texture, &s, &dPx, viewInfo.Angle, nullptr, SDL_FLIP_NONE) == 0; - } - - // === GEOMETRY PATH (mirror and/or global rotation and/or reflections) === + // === GEOMETRY PATH (mirror and/or global rotation and/or reflections, or any non-zero angle) === + // SDL_RenderCopyExF is avoided for rotation: SDL's OpenGL renderer has a Y-axis inversion + // bug when rendering to a texture render target, which causes rotated elements to be placed + // off-screen. SDL_RenderGeometry with manually-computed vertices is used instead. const SDL_Rect src0 = srcRect; const SDL_FRect dst0 = dstRect; diff --git a/RetroFE/Source/Sound/AudioBus.cpp b/RetroFE/Source/Sound/AudioBus.cpp index c25f645d1..a902bb349 100644 --- a/RetroFE/Source/Sound/AudioBus.cpp +++ b/RetroFE/Source/Sound/AudioBus.cpp @@ -6,9 +6,10 @@ #elif defined(__ARM_NEON) #include #endif -#include -#include #include +#include +#include +#include #include "../Utility/Log.h" @@ -70,7 +71,7 @@ int AudioBus::SpscRing::write(const uint8_t* data, int bytes) { if ((size_t)bytes > free) { size_t need = (size_t)bytes - free; need = align_up(need, align_); // drop whole frames - if (need > used) need = used; // don’t jump past head + if (need > used) need = used; // don�t jump past head tail_.store(t + need, std::memory_order_release); t += need; } diff --git a/RetroFE/Source/Video/GStreamerVideo.cpp b/RetroFE/Source/Video/GStreamerVideo.cpp index 1999e46dc..14a32fd41 100644 --- a/RetroFE/Source/Video/GStreamerVideo.cpp +++ b/RetroFE/Source/Video/GStreamerVideo.cpp @@ -1958,13 +1958,21 @@ bool GStreamerVideo::hasFinishedLoops() const { } void GStreamerVideo::detectStreamTypes() { - if (!playbin_) return; + if (!playbin_ || !videoSink_) return; - gint n_video = 0; - g_object_get(playbin_, "n-video", &n_video, nullptr); + bool hasVideo = false; + GstPad *pad = gst_element_get_static_pad(videoSink_, "sink"); + if (pad) { + GstCaps *caps = gst_pad_get_current_caps(pad); + if (caps) { + hasVideo = true; + gst_caps_unref(caps); + } + gst_object_unref(pad); + } - hasVideoStream_.store(n_video > 0, std::memory_order_release); + hasVideoStream_.store(hasVideo, std::memory_order_release); LOG_DEBUG("GStreamerVideo", "Stream detection for " + currentFile_ + - ": video streams=" + std::to_string(n_video)); + ": hasVideo=" + std::string(hasVideo ? "true" : "false")); } \ No newline at end of file diff --git a/RetroFE/ThirdParty/rapidxml-1.13/rapidxml_print.hpp b/RetroFE/ThirdParty/rapidxml-1.13/rapidxml_print.hpp index 0ae2b14fa..1c9464bba 100644 --- a/RetroFE/ThirdParty/rapidxml-1.13/rapidxml_print.hpp +++ b/RetroFE/ThirdParty/rapidxml-1.13/rapidxml_print.hpp @@ -101,7 +101,17 @@ namespace rapidxml /////////////////////////////////////////////////////////////////////////// // Internal printing operations - + + // Forward declarations + template inline OutIt print_children(OutIt out, const xml_node *node, int flags, int indent); + template inline OutIt print_element_node(OutIt out, const xml_node *node, int flags, int indent); + template inline OutIt print_data_node(OutIt out, const xml_node *node, int flags, int indent); + template inline OutIt print_cdata_node(OutIt out, const xml_node *node, int flags, int indent); + template inline OutIt print_declaration_node(OutIt out, const xml_node *node, int flags, int indent); + template inline OutIt print_comment_node(OutIt out, const xml_node *node, int flags, int indent); + template inline OutIt print_doctype_node(OutIt out, const xml_node *node, int flags, int indent); + template inline OutIt print_pi_node(OutIt out, const xml_node *node, int flags, int indent); + // Print node template inline OutIt print_node(OutIt out, const xml_node *node, int flags, int indent)