diff --git a/Source/Core/Common/GL/GLContext.cpp b/Source/Core/Common/GL/GLContext.cpp index cbc50463db..5d740f9211 100644 --- a/Source/Core/Common/GL/GLContext.cpp +++ b/Source/Core/Common/GL/GLContext.cpp @@ -108,7 +108,7 @@ std::unique_ptr GLContext::Create(const WindowSystemInfo& wsi, bool s } #endif #if HAVE_EGL - if (wsi.type == WindowSystemType::Headless) + if (wsi.type == WindowSystemType::Headless || wsi.type == WindowSystemType::FBDev) context = std::make_unique(); #endif diff --git a/Source/Core/Common/WindowSystemInfo.h b/Source/Core/Common/WindowSystemInfo.h index bea853d445..03f230f8e6 100644 --- a/Source/Core/Common/WindowSystemInfo.h +++ b/Source/Core/Common/WindowSystemInfo.h @@ -11,7 +11,8 @@ enum class WindowSystemType MacOS, Android, X11, - Wayland + Wayland, + FBDev, }; struct WindowSystemInfo diff --git a/Source/Core/DolphinNoGUI/CMakeLists.txt b/Source/Core/DolphinNoGUI/CMakeLists.txt index 0b54022594..6247dac2d0 100644 --- a/Source/Core/DolphinNoGUI/CMakeLists.txt +++ b/Source/Core/DolphinNoGUI/CMakeLists.txt @@ -9,6 +9,10 @@ if(ENABLE_X11 AND X11_FOUND) target_sources(dolphin-nogui PRIVATE PlatformX11.cpp) endif() +if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") + target_sources(dolphin-nogui PRIVATE PlatformFBDev.cpp) +endif() + set_target_properties(dolphin-nogui PROPERTIES OUTPUT_NAME dolphin-emu-nogui) target_link_libraries(dolphin-nogui diff --git a/Source/Core/DolphinNoGUI/MainNoGUI.cpp b/Source/Core/DolphinNoGUI/MainNoGUI.cpp index 711583f736..1736c52edd 100644 --- a/Source/Core/DolphinNoGUI/MainNoGUI.cpp +++ b/Source/Core/DolphinNoGUI/MainNoGUI.cpp @@ -121,6 +121,11 @@ static std::unique_ptr GetPlatform(const optparse::Values& options) return Platform::CreateX11Platform(); #endif +#ifdef __linux__ + if (platform_name == "fbdev" || platform_name.empty()) + return Platform::CreateFBDevPlatform(); +#endif + if (platform_name == "headless" || platform_name.empty()) return Platform::CreateHeadlessPlatform(); @@ -135,6 +140,10 @@ int main(int argc, char* argv[]) .help("Window platform to use [%choices]") .choices({ "headless" +#ifdef __linux__ + , + "fbdev" +#endif #if HAVE_X11 , "x11" diff --git a/Source/Core/DolphinNoGUI/Platform.h b/Source/Core/DolphinNoGUI/Platform.h index 19edbb1168..af39492447 100644 --- a/Source/Core/DolphinNoGUI/Platform.h +++ b/Source/Core/DolphinNoGUI/Platform.h @@ -35,6 +35,9 @@ public: #ifdef HAVE_X11 static std::unique_ptr CreateX11Platform(); #endif +#ifdef __linux__ + static std::unique_ptr CreateFBDevPlatform(); +#endif protected: void UpdateRunningFlag(); diff --git a/Source/Core/DolphinNoGUI/PlatformFBDev.cpp b/Source/Core/DolphinNoGUI/PlatformFBDev.cpp new file mode 100644 index 0000000000..9818105521 --- /dev/null +++ b/Source/Core/DolphinNoGUI/PlatformFBDev.cpp @@ -0,0 +1,102 @@ +// Copyright 2018 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include + +#include "DolphinNoGUI/Platform.h" + +#include "Common/MsgHandler.h" +#include "Core/ConfigManager.h" +#include "Core/Core.h" +#include "Core/State.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include "VideoCommon/RenderBase.h" + +namespace +{ +class PlatformFBDev : public Platform +{ +public: + ~PlatformFBDev() override; + + bool Init() override; + void SetTitle(const std::string& string) override; + void MainLoop() override; + + WindowSystemInfo GetWindowSystemInfo() const; + +private: + bool OpenFramebuffer(); + + int m_fb_fd = -1; +}; + +PlatformFBDev::~PlatformFBDev() +{ + if (m_fb_fd >= 0) + close(m_fb_fd); +} + +bool PlatformFBDev::Init() +{ + if (!OpenFramebuffer()) + return false; + + return true; +} + +bool PlatformFBDev::OpenFramebuffer() +{ + m_fb_fd = open("/dev/fb0", O_RDWR); + if (m_fb_fd < 0) + { + std::fprintf(stderr, "open(/dev/fb0) failed\n"); + return false; + } + + return true; +} + +void PlatformFBDev::SetTitle(const std::string& string) +{ + std::fprintf(stdout, "%s\n", string.c_str()); +} + +void PlatformFBDev::MainLoop() +{ + while (IsRunning()) + { + UpdateRunningFlag(); + Core::HostDispatchJobs(); + + // TODO: Is this sleep appropriate? + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } +} + +WindowSystemInfo PlatformFBDev::GetWindowSystemInfo() const +{ + WindowSystemInfo wsi; + wsi.type = WindowSystemType::FBDev; + wsi.display_connection = nullptr; // EGL_DEFAULT_DISPLAY + wsi.render_surface = nullptr; + return wsi; +} +} // namespace + +std::unique_ptr Platform::CreateFBDevPlatform() +{ + return std::make_unique(); +}