Dependencies: Remove GLFW, Add SDL2
citra: Remove GLFW, Add SDL2 FindSDL2: Do not CACHE SDL2_* variables if library is not found EmuWindow_SDL2: Set minimal client area at initialisation time EmuWindow_SDL2: Corrections EmuWindow_SDL2: Fix no decorations on startup on OS X cmake: windows_copy_files
This commit is contained in:
		| @@ -13,18 +13,13 @@ if [ "$TRAVIS_OS_NAME" = "linux" -o -z "$TRAVIS_OS_NAME" ]; then | |||||||
|         | tar -xz -C $HOME/.local --strip-components=1 |         | tar -xz -C $HOME/.local --strip-components=1 | ||||||
|  |  | ||||||
|     ( |     ( | ||||||
|         git clone https://github.com/glfw/glfw.git --branch 3.1.1 --depth 1 |         wget http://libsdl.org/release/SDL2-2.0.4.tar.gz -O - | tar xz | ||||||
|         mkdir glfw/build && cd glfw/build |         cd SDL2-2.0.4 | ||||||
|         cmake -DBUILD_SHARED_LIBS=ON \ |         ./configure --prefix=$HOME/.local | ||||||
|               -DGLFW_BUILD_EXAMPLES=OFF \ |  | ||||||
|               -DGLFW_BUILD_TESTS=OFF \ |  | ||||||
|               -DCMAKE_INSTALL_PREFIX=$HOME/.local \ |  | ||||||
|               .. |  | ||||||
|         make -j4 && make install |         make -j4 && make install | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
| elif [ "$TRAVIS_OS_NAME" = "osx" ]; then | elif [ "$TRAVIS_OS_NAME" = "osx" ]; then | ||||||
|     brew update > /dev/null # silence the very verbose output |     brew update > /dev/null # silence the very verbose output | ||||||
|     brew install qt5 glfw3 |     brew install qt5 sdl2 | ||||||
|     gem install xcpretty |     gem install xcpretty | ||||||
| fi | fi | ||||||
|   | |||||||
| @@ -18,8 +18,6 @@ addons: | |||||||
|       - gcc-4.9 |       - gcc-4.9 | ||||||
|       - g++-4.9 |       - g++-4.9 | ||||||
|       - xorg-dev |       - xorg-dev | ||||||
|       - libglu1-mesa-dev |  | ||||||
|       - libxcursor-dev |  | ||||||
|       - lib32stdc++6 # For CMake |       - lib32stdc++6 # For CMake | ||||||
|       - lftp # To upload builds |       - lftp # To upload builds | ||||||
|  |  | ||||||
|   | |||||||
| @@ -35,8 +35,8 @@ endfunction() | |||||||
|  |  | ||||||
| project(citra) | project(citra) | ||||||
|  |  | ||||||
| option(ENABLE_GLFW "Enable the GLFW frontend" ON) | option(ENABLE_SDL2 "Enable the SDL2 frontend" ON) | ||||||
| option(CITRA_USE_BUNDLED_GLFW "Download bundled GLFW binaries" OFF) | option(CITRA_USE_BUNDLED_SDL2 "Download bundled SDL2 binaries" OFF) | ||||||
|  |  | ||||||
| option(ENABLE_QT "Enable the Qt frontend" ON) | option(ENABLE_QT "Enable the Qt frontend" ON) | ||||||
| option(CITRA_USE_BUNDLED_QT "Download bundled Qt binaries" OFF) | option(CITRA_USE_BUNDLED_QT "Download bundled Qt binaries" OFF) | ||||||
| @@ -135,34 +135,29 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/externals/cmake-modules") | |||||||
| find_package(OpenGL REQUIRED) | find_package(OpenGL REQUIRED) | ||||||
| include_directories(${OPENGL_INCLUDE_DIR}) | include_directories(${OPENGL_INCLUDE_DIR}) | ||||||
|  |  | ||||||
| if (ENABLE_GLFW) | if (ENABLE_SDL2) | ||||||
|     if (CITRA_USE_BUNDLED_GLFW) |     if (CITRA_USE_BUNDLED_SDL2) | ||||||
|         # Detect toolchain and platform |         # Detect toolchain and platform | ||||||
|         if (MSVC14 AND ARCHITECTURE_x86_64) |         if (MSVC14 AND ARCHITECTURE_x86_64) | ||||||
|             set(GLFW_VER "glfw-3.1.1-msvc2015_64") |             set(SDL2_VER "SDL2-2.0.4") | ||||||
|         elseif (MSVC12 AND ARCHITECTURE_x86_64) |  | ||||||
|             set(GLFW_VER "glfw-3.1.1-msvc2013_64") |  | ||||||
|         else() |         else() | ||||||
|             message(FATAL_ERROR "No bundled GLFW binaries for your toolchain. Disable CITRA_USE_BUNDLED_GLFW and provide your own.") |             message(FATAL_ERROR "No bundled SDL2 binaries for your toolchain. Disable CITRA_USE_BUNDLED_SDL2 and provide your own.") | ||||||
|         endif() |         endif() | ||||||
|  |  | ||||||
|         if (DEFINED GLFW_VER) |         if (DEFINED SDL2_VER) | ||||||
|             download_bundled_external("glfw/" ${GLFW_VER} GLFW_PREFIX) |             download_bundled_external("sdl2/" ${SDL2_VER} SDL2_PREFIX) | ||||||
|         endif() |         endif() | ||||||
|  |  | ||||||
|         set(GLFW_INCLUDE_DIRS "${GLFW_PREFIX}/include" CACHE PATH "Path to GLFW3 headers") |         set(SDL2_INCLUDE_DIR "${SDL2_PREFIX}/include" CACHE PATH "Path to SDL2 headers") | ||||||
|         set(GLFW_LIBRARY_DIRS "${GLFW_PREFIX}/lib" CACHE PATH "Path to GLFW3 libraries") |         set(SDL2_LIBRARY "${SDL2_PREFIX}/lib/x64/SDL2.lib" CACHE PATH "Path to SDL2 library") | ||||||
|         set(GLFW_LIBRARIES glfw3) |         set(SDL2_DLL_DIR "${SDL2_PREFIX}/lib/x64/" CACHE PATH "Path to SDL2.dll") | ||||||
|     else() |     else() | ||||||
|         find_package(PkgConfig REQUIRED) |         find_package(SDL2 REQUIRED) | ||||||
|         pkg_search_module(GLFW REQUIRED glfw3) |  | ||||||
|     endif() |     endif() | ||||||
| endif() | endif() | ||||||
|  |  | ||||||
| IF (APPLE) | IF (APPLE) | ||||||
|     FIND_LIBRARY(COCOA_LIBRARY Cocoa)           # Umbrella framework for everything GUI-related |     FIND_LIBRARY(COCOA_LIBRARY Cocoa)           # Umbrella framework for everything GUI-related | ||||||
|     FIND_LIBRARY(IOKIT_LIBRARY IOKit)           # GLFW dependency |  | ||||||
|     FIND_LIBRARY(COREVIDEO_LIBRARY CoreVideo)   # GLFW dependency |  | ||||||
|     set(PLATFORM_LIBRARIES iconv ${COCOA_LIBRARY} ${IOKIT_LIBRARY} ${COREVIDEO_LIBRARY}) |     set(PLATFORM_LIBRARIES iconv ${COCOA_LIBRARY} ${IOKIT_LIBRARY} ${COREVIDEO_LIBRARY}) | ||||||
|  |  | ||||||
|     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") |     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") | ||||||
|   | |||||||
| @@ -19,7 +19,7 @@ install: | |||||||
| before_build: | before_build: | ||||||
|   - mkdir build |   - mkdir build | ||||||
|   - cd build |   - cd build | ||||||
|   - cmake -G "Visual Studio 14 2015 Win64" -DCITRA_USE_BUNDLED_GLFW=1 -DCITRA_USE_BUNDLED_QT=1 .. |   - cmake -G "Visual Studio 14 2015 Win64" -DCITRA_USE_BUNDLED_QT=1 -DCITRA_USE_BUNDLED_SDL2=1 .. | ||||||
|   - cd .. |   - cd .. | ||||||
|  |  | ||||||
| after_build: | after_build: | ||||||
|   | |||||||
							
								
								
									
										224
									
								
								externals/cmake-modules/FindSDL2.cmake
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										224
									
								
								externals/cmake-modules/FindSDL2.cmake
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,224 @@ | |||||||
|  |  | ||||||
|  | # This module defines | ||||||
|  | # SDL2_LIBRARY, the name of the library to link against | ||||||
|  | # SDL2_FOUND, if false, do not try to link to SDL2 | ||||||
|  | # SDL2_INCLUDE_DIR, where to find SDL.h | ||||||
|  | # | ||||||
|  | # This module responds to the the flag: | ||||||
|  | # SDL2_BUILDING_LIBRARY | ||||||
|  | # If this is defined, then no SDL2main will be linked in because | ||||||
|  | # only applications need main(). | ||||||
|  | # Otherwise, it is assumed you are building an application and this | ||||||
|  | # module will attempt to locate and set the the proper link flags | ||||||
|  | # as part of the returned SDL2_LIBRARY variable. | ||||||
|  | # | ||||||
|  | # Don't forget to include SDLmain.h and SDLmain.m your project for the | ||||||
|  | # OS X framework based version. (Other versions link to -lSDL2main which | ||||||
|  | # this module will try to find on your behalf.) Also for OS X, this | ||||||
|  | # module will automatically add the -framework Cocoa on your behalf. | ||||||
|  | # | ||||||
|  | # | ||||||
|  | # Additional Note: If you see an empty SDL2_LIBRARY_TEMP in your configuration | ||||||
|  | # and no SDL2_LIBRARY, it means CMake did not find your SDL2 library | ||||||
|  | # (SDL2.dll, libsdl2.so, SDL2.framework, etc). | ||||||
|  | # Set SDL2_LIBRARY_TEMP to point to your SDL2 library, and configure again. | ||||||
|  | # Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value | ||||||
|  | # as appropriate. These values are used to generate the final SDL2_LIBRARY | ||||||
|  | # variable, but when these values are unset, SDL2_LIBRARY does not get created. | ||||||
|  | # | ||||||
|  | # | ||||||
|  | # $SDL2DIR is an environment variable that would | ||||||
|  | # correspond to the ./configure --prefix=$SDL2DIR | ||||||
|  | # used in building SDL2. | ||||||
|  | # l.e.galup  9-20-02 | ||||||
|  | # | ||||||
|  | # Modified by Eric Wing. | ||||||
|  | # Added code to assist with automated building by using environmental variables | ||||||
|  | # and providing a more controlled/consistent search behavior. | ||||||
|  | # Added new modifications to recognize OS X frameworks and | ||||||
|  | # additional Unix paths (FreeBSD, etc). | ||||||
|  | # Also corrected the header search path to follow "proper" SDL guidelines. | ||||||
|  | # Added a search for SDL2main which is needed by some platforms. | ||||||
|  | # Added a search for threads which is needed by some platforms. | ||||||
|  | # Added needed compile switches for MinGW. | ||||||
|  | # | ||||||
|  | # On OSX, this will prefer the Framework version (if found) over others. | ||||||
|  | # People will have to manually change the cache values of | ||||||
|  | # SDL2_LIBRARY to override this selection or set the CMake environment | ||||||
|  | # CMAKE_INCLUDE_PATH to modify the search paths. | ||||||
|  | # | ||||||
|  | # Note that the header path has changed from SDL2/SDL.h to just SDL.h | ||||||
|  | # This needed to change because "proper" SDL convention | ||||||
|  | # is #include "SDL.h", not <SDL2/SDL.h>. This is done for portability | ||||||
|  | # reasons because not all systems place things in SDL2/ (see FreeBSD). | ||||||
|  |  | ||||||
|  | #============================================================================= | ||||||
|  | # Copyright 2003-2009 Kitware, Inc. | ||||||
|  | # | ||||||
|  | # Distributed under the OSI-approved BSD License (the "License"). | ||||||
|  | # | ||||||
|  | # This software is distributed WITHOUT ANY WARRANTY; without even the | ||||||
|  | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||||||
|  | # See the License for more information. | ||||||
|  | #============================================================================= | ||||||
|  | # CMake - Cross Platform Makefile Generator | ||||||
|  | # Copyright 2000-2016 Kitware, Inc. | ||||||
|  | # Copyright 2000-2011 Insight Software Consortium | ||||||
|  | # All rights reserved. | ||||||
|  | #  | ||||||
|  | # Redistribution and use in source and binary forms, with or without | ||||||
|  | # modification, are permitted provided that the following conditions | ||||||
|  | # are met: | ||||||
|  | #  | ||||||
|  | # * Redistributions of source code must retain the above copyright | ||||||
|  | #   notice, this list of conditions and the following disclaimer. | ||||||
|  | #  | ||||||
|  | # * Redistributions in binary form must reproduce the above copyright | ||||||
|  | #   notice, this list of conditions and the following disclaimer in the | ||||||
|  | #   documentation and/or other materials provided with the distribution. | ||||||
|  | #  | ||||||
|  | # * Neither the names of Kitware, Inc., the Insight Software Consortium, | ||||||
|  | #   nor the names of their contributors may be used to endorse or promote | ||||||
|  | #   products derived from this software without specific prior written | ||||||
|  | #   permission. | ||||||
|  | #  | ||||||
|  | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||||
|  | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||||||
|  | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||||||
|  | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||||||
|  | # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||||||
|  | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||||||
|  | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||||
|  | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||||
|  | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||||
|  | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||||
|  | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||||
|  | #  | ||||||
|  | # ------------------------------------------------------------------------------ | ||||||
|  | #  | ||||||
|  | # The above copyright and license notice applies to distributions of | ||||||
|  | # CMake in source and binary form.  Some source files contain additional | ||||||
|  | # notices of original copyright by their contributors; see each source | ||||||
|  | # for details.  Third-party software packages supplied with CMake under | ||||||
|  | # compatible licenses provide their own copyright notices documented in | ||||||
|  | # corresponding subdirectories. | ||||||
|  | #  | ||||||
|  | # ------------------------------------------------------------------------------ | ||||||
|  | #  | ||||||
|  | # CMake was initially developed by Kitware with the following sponsorship: | ||||||
|  | #  | ||||||
|  | #  * National Library of Medicine at the National Institutes of Health | ||||||
|  | #    as part of the Insight Segmentation and Registration Toolkit (ITK). | ||||||
|  | #  | ||||||
|  | #  * US National Labs (Los Alamos, Livermore, Sandia) ASC Parallel | ||||||
|  | #    Visualization Initiative. | ||||||
|  | #  | ||||||
|  | #  * National Alliance for Medical Image Computing (NAMIC) is funded by the | ||||||
|  | #    National Institutes of Health through the NIH Roadmap for Medical Research, | ||||||
|  | #    Grant U54 EB005149. | ||||||
|  | #  | ||||||
|  | #  * Kitware, Inc. | ||||||
|  | # | ||||||
|  |  | ||||||
|  | message("<FindSDL2.cmake>") | ||||||
|  |  | ||||||
|  | SET(SDL2_SEARCH_PATHS | ||||||
|  |     ~/Library/Frameworks | ||||||
|  |     /Library/Frameworks | ||||||
|  |     /usr/local | ||||||
|  |     /usr | ||||||
|  |     /sw # Fink | ||||||
|  |     /opt/local # DarwinPorts | ||||||
|  |     /opt/csw # Blastwave | ||||||
|  |     /opt | ||||||
|  |     ${SDL2_PATH} | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | FIND_LIBRARY(SDL2_LIBRARY_TEMP | ||||||
|  |     NAMES SDL2 | ||||||
|  |     HINTS | ||||||
|  |     $ENV{SDL2DIR} | ||||||
|  |     PATH_SUFFIXES lib64 lib | ||||||
|  |     PATHS ${SDL2_SEARCH_PATHS} | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | IF(SDL2_LIBRARY_TEMP) | ||||||
|  |     FIND_PATH(SDL2_INCLUDE_DIR SDL.h | ||||||
|  |         HINTS | ||||||
|  |         $ENV{SDL2DIR} | ||||||
|  |         PATH_SUFFIXES include/SDL2 include | ||||||
|  |         PATHS ${SDL2_SEARCH_PATHS} | ||||||
|  |     ) | ||||||
|  |  | ||||||
|  |     IF(NOT SDL2_BUILDING_LIBRARY) | ||||||
|  |         IF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") | ||||||
|  |             # Non-OS X framework versions expect you to also dynamically link to | ||||||
|  |             # SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms | ||||||
|  |             # seem to provide SDL2main for compatibility even though they don't | ||||||
|  |             # necessarily need it. | ||||||
|  |             FIND_LIBRARY(SDL2MAIN_LIBRARY | ||||||
|  |                 NAMES SDL2main | ||||||
|  |                 HINTS | ||||||
|  |                 $ENV{SDL2DIR} | ||||||
|  |                 PATH_SUFFIXES lib64 lib | ||||||
|  |                 PATHS ${SDL2_SEARCH_PATHS} | ||||||
|  |             ) | ||||||
|  |         ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") | ||||||
|  |     ENDIF(NOT SDL2_BUILDING_LIBRARY) | ||||||
|  |  | ||||||
|  |     # SDL2 may require threads on your system. | ||||||
|  |     # The Apple build may not need an explicit flag because one of the | ||||||
|  |     # frameworks may already provide it. | ||||||
|  |     # But for non-OSX systems, I will use the CMake Threads package. | ||||||
|  |     IF(NOT APPLE) | ||||||
|  |         FIND_PACKAGE(Threads) | ||||||
|  |     ENDIF(NOT APPLE) | ||||||
|  |  | ||||||
|  |     # MinGW needs an additional library, mwindows | ||||||
|  |     # It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -lmwindows | ||||||
|  |     # (Actually on second look, I think it only needs one of the m* libraries.) | ||||||
|  |     IF(MINGW) | ||||||
|  |         SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW") | ||||||
|  |     ENDIF(MINGW) | ||||||
|  |  | ||||||
|  |     # For SDL2main | ||||||
|  |     IF(NOT SDL2_BUILDING_LIBRARY) | ||||||
|  |         IF(SDL2MAIN_LIBRARY) | ||||||
|  |             SET(SDL2_LIBRARY_TEMP ${SDL2MAIN_LIBRARY} ${SDL2_LIBRARY_TEMP}) | ||||||
|  |         ENDIF(SDL2MAIN_LIBRARY) | ||||||
|  |     ENDIF(NOT SDL2_BUILDING_LIBRARY) | ||||||
|  |  | ||||||
|  |     # For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa. | ||||||
|  |     # CMake doesn't display the -framework Cocoa string in the UI even | ||||||
|  |     # though it actually is there if I modify a pre-used variable. | ||||||
|  |     # I think it has something to do with the CACHE STRING. | ||||||
|  |     # So I use a temporary variable until the end so I can set the | ||||||
|  |     # "real" variable in one-shot. | ||||||
|  |     IF(APPLE) | ||||||
|  |         SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} "-framework Cocoa") | ||||||
|  |     ENDIF(APPLE) | ||||||
|  |  | ||||||
|  |     # For threads, as mentioned Apple doesn't need this. | ||||||
|  |     # In fact, there seems to be a problem if I used the Threads package | ||||||
|  |     # and try using this line, so I'm just skipping it entirely for OS X. | ||||||
|  |     IF(NOT APPLE) | ||||||
|  |         SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT}) | ||||||
|  |     ENDIF(NOT APPLE) | ||||||
|  |  | ||||||
|  |     # For MinGW library | ||||||
|  |     IF(MINGW) | ||||||
|  |         SET(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP}) | ||||||
|  |     ENDIF(MINGW) | ||||||
|  |  | ||||||
|  |     # Set the final string here so the GUI reflects the final state. | ||||||
|  |     SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found") | ||||||
|  |  | ||||||
|  |     # Unset the temp variable to INTERNAL so it is not seen in the CMake GUI | ||||||
|  |     UNSET(SDL2_LIBRARY_TEMP) | ||||||
|  | ENDIF(SDL2_LIBRARY_TEMP) | ||||||
|  |  | ||||||
|  | message("</FindSDL2.cmake>") | ||||||
|  |  | ||||||
|  | INCLUDE(FindPackageHandleStandardArgs) | ||||||
|  |  | ||||||
|  | FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR) | ||||||
							
								
								
									
										28
									
								
								externals/cmake-modules/WindowsCopyFiles.cmake
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								externals/cmake-modules/WindowsCopyFiles.cmake
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | |||||||
|  | # Copyright 2016 Citra Emulator Project | ||||||
|  | # Licensed under GPLv2 or any later version | ||||||
|  | # Refer to the license.txt file included. | ||||||
|  |  | ||||||
|  | # This file provides the function windows_copy_files. | ||||||
|  | # This is only valid on Windows. | ||||||
|  |  | ||||||
|  | # Include guard | ||||||
|  | if(__windows_copy_files) | ||||||
|  | 	return() | ||||||
|  | endif() | ||||||
|  | set(__windows_copy_files YES) | ||||||
|  |  | ||||||
|  | # Any number of files to copy from SOURCE_DIR to DEST_DIR can be specified after DEST_DIR. | ||||||
|  | # This copying happens post-build. | ||||||
|  | function(windows_copy_files TARGET SOURCE_DIR DEST_DIR) | ||||||
|  |     # windows commandline expects the / to be \ so switch them | ||||||
|  |     string(REPLACE "/" "\\\\" SOURCE_DIR ${SOURCE_DIR}) | ||||||
|  |     string(REPLACE "/" "\\\\" DEST_DIR ${DEST_DIR}) | ||||||
|  |  | ||||||
|  |     # /NJH /NJS /NDL /NFL /NC /NS /NP - Silence any output | ||||||
|  |     # cmake adds an extra check for command success which doesn't work too well with robocopy | ||||||
|  |     # so trick it into thinking the command was successful with the || cmd /c "exit /b 0" | ||||||
|  |     add_custom_command(TARGET ${TARGET} POST_BUILD | ||||||
|  |         COMMAND if not exist ${DEST_DIR} mkdir ${DEST_DIR} 2> nul | ||||||
|  |         COMMAND robocopy ${SOURCE_DIR} ${DEST_DIR} ${ARGN} /NJH /NJS /NDL /NFL /NC /NS /NP || cmd /c "exit /b 0" | ||||||
|  |     ) | ||||||
|  | endfunction() | ||||||
| @@ -5,7 +5,7 @@ add_subdirectory(common) | |||||||
| add_subdirectory(core) | add_subdirectory(core) | ||||||
| add_subdirectory(video_core) | add_subdirectory(video_core) | ||||||
| add_subdirectory(audio_core) | add_subdirectory(audio_core) | ||||||
| if (ENABLE_GLFW) | if (ENABLE_SDL2) | ||||||
|     add_subdirectory(citra) |     add_subdirectory(citra) | ||||||
| endif() | endif() | ||||||
| if (ENABLE_QT) | if (ENABLE_QT) | ||||||
|   | |||||||
| @@ -1,11 +1,11 @@ | |||||||
| set(SRCS | set(SRCS | ||||||
|             emu_window/emu_window_glfw.cpp |             emu_window/emu_window_sdl2.cpp | ||||||
|             citra.cpp |             citra.cpp | ||||||
|             config.cpp |             config.cpp | ||||||
|             citra.rc |             citra.rc | ||||||
|             ) |             ) | ||||||
| set(HEADERS | set(HEADERS | ||||||
|             emu_window/emu_window_glfw.h |             emu_window/emu_window_sdl2.h | ||||||
|             config.h |             config.h | ||||||
|             default_ini.h |             default_ini.h | ||||||
|             resource.h |             resource.h | ||||||
| @@ -13,12 +13,11 @@ set(HEADERS | |||||||
|  |  | ||||||
| create_directory_groups(${SRCS} ${HEADERS}) | create_directory_groups(${SRCS} ${HEADERS}) | ||||||
|  |  | ||||||
| include_directories(${GLFW_INCLUDE_DIRS}) | include_directories(${SDL2_INCLUDE_DIR}) | ||||||
| link_directories(${GLFW_LIBRARY_DIRS}) |  | ||||||
|  |  | ||||||
| add_executable(citra ${SRCS} ${HEADERS}) | add_executable(citra ${SRCS} ${HEADERS}) | ||||||
| target_link_libraries(citra core video_core audio_core common) | target_link_libraries(citra core video_core audio_core common) | ||||||
| target_link_libraries(citra ${GLFW_LIBRARIES} ${OPENGL_gl_LIBRARY} inih glad) | target_link_libraries(citra ${SDL2_LIBRARY} ${OPENGL_gl_LIBRARY} inih glad) | ||||||
| if (MSVC) | if (MSVC) | ||||||
|     target_link_libraries(citra getopt) |     target_link_libraries(citra getopt) | ||||||
| endif() | endif() | ||||||
| @@ -27,3 +26,13 @@ target_link_libraries(citra ${PLATFORM_LIBRARIES}) | |||||||
| if(${CMAKE_SYSTEM_NAME} MATCHES "Linux|FreeBSD|OpenBSD|NetBSD") | if(${CMAKE_SYSTEM_NAME} MATCHES "Linux|FreeBSD|OpenBSD|NetBSD") | ||||||
|     install(TARGETS citra RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") |     install(TARGETS citra RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") | ||||||
| endif() | endif() | ||||||
|  |  | ||||||
|  | if (MSVC) | ||||||
|  |     include(WindowsCopyFiles) | ||||||
|  |  | ||||||
|  |     set(DLL_DEST "${CMAKE_BINARY_DIR}/bin/$<CONFIG>/") | ||||||
|  |  | ||||||
|  |     windows_copy_files(citra ${SDL2_DLL_DIR} ${DLL_DEST} SDL2.dll) | ||||||
|  |  | ||||||
|  |     unset(DLL_DEST) | ||||||
|  | endif() | ||||||
|   | |||||||
| @@ -27,7 +27,7 @@ | |||||||
| #include "core/loader/loader.h" | #include "core/loader/loader.h" | ||||||
|  |  | ||||||
| #include "citra/config.h" | #include "citra/config.h" | ||||||
| #include "citra/emu_window/emu_window_glfw.h" | #include "citra/emu_window/emu_window_sdl2.h" | ||||||
|  |  | ||||||
| #include "video_core/video_core.h" | #include "video_core/video_core.h" | ||||||
|  |  | ||||||
| @@ -76,7 +76,7 @@ int main(int argc, char **argv) { | |||||||
|     GDBStub::ToggleServer(Settings::values.use_gdbstub); |     GDBStub::ToggleServer(Settings::values.use_gdbstub); | ||||||
|     GDBStub::SetServerPort(static_cast<u32>(Settings::values.gdbstub_port)); |     GDBStub::SetServerPort(static_cast<u32>(Settings::values.gdbstub_port)); | ||||||
|  |  | ||||||
|     EmuWindow_GLFW* emu_window = new EmuWindow_GLFW; |     EmuWindow_SDL2* emu_window = new EmuWindow_SDL2; | ||||||
|  |  | ||||||
|     VideoCore::g_hw_renderer_enabled = Settings::values.use_hw_renderer; |     VideoCore::g_hw_renderer_enabled = Settings::values.use_hw_renderer; | ||||||
|     VideoCore::g_shader_jit_enabled = Settings::values.use_shader_jit; |     VideoCore::g_shader_jit_enabled = Settings::values.use_shader_jit; | ||||||
|   | |||||||
| @@ -2,10 +2,10 @@ | |||||||
| // Licensed under GPLv2 or any later version | // Licensed under GPLv2 or any later version | ||||||
| // Refer to the license.txt file included. | // Refer to the license.txt file included. | ||||||
|  |  | ||||||
| #define GLFW_INCLUDE_NONE |  | ||||||
| #include <GLFW/glfw3.h> |  | ||||||
| #include <inih/cpp/INIReader.h> | #include <inih/cpp/INIReader.h> | ||||||
|  |  | ||||||
|  | #include <SDL.h> | ||||||
|  |  | ||||||
| #include "citra/default_ini.h" | #include "citra/default_ini.h" | ||||||
|  |  | ||||||
| #include "common/file_util.h" | #include "common/file_util.h" | ||||||
| @@ -17,8 +17,8 @@ | |||||||
|  |  | ||||||
| Config::Config() { | Config::Config() { | ||||||
|     // TODO: Don't hardcode the path; let the frontend decide where to put the config files. |     // TODO: Don't hardcode the path; let the frontend decide where to put the config files. | ||||||
|     glfw_config_loc = FileUtil::GetUserPath(D_CONFIG_IDX) + "glfw-config.ini"; |     sdl2_config_loc = FileUtil::GetUserPath(D_CONFIG_IDX) + "sdl2-config.ini"; | ||||||
|     glfw_config = new INIReader(glfw_config_loc); |     sdl2_config = new INIReader(sdl2_config_loc); | ||||||
|  |  | ||||||
|     Reload(); |     Reload(); | ||||||
| } | } | ||||||
| @@ -41,51 +41,51 @@ bool Config::LoadINI(INIReader* config, const char* location, const std::string& | |||||||
| } | } | ||||||
|  |  | ||||||
| static const std::array<int, Settings::NativeInput::NUM_INPUTS> defaults = { | static const std::array<int, Settings::NativeInput::NUM_INPUTS> defaults = { | ||||||
|     GLFW_KEY_A, GLFW_KEY_S, GLFW_KEY_Z, GLFW_KEY_X, |     SDL_SCANCODE_A, SDL_SCANCODE_S, SDL_SCANCODE_Z, SDL_SCANCODE_X, | ||||||
|     GLFW_KEY_Q, GLFW_KEY_W, GLFW_KEY_1, GLFW_KEY_2, |     SDL_SCANCODE_Q, SDL_SCANCODE_W, SDL_SCANCODE_1, SDL_SCANCODE_2, | ||||||
|     GLFW_KEY_M, GLFW_KEY_N, GLFW_KEY_B, |     SDL_SCANCODE_M, SDL_SCANCODE_N, SDL_SCANCODE_B, | ||||||
|     GLFW_KEY_T, GLFW_KEY_G, GLFW_KEY_F, GLFW_KEY_H, |     SDL_SCANCODE_T, SDL_SCANCODE_G, SDL_SCANCODE_F, SDL_SCANCODE_H, | ||||||
|     GLFW_KEY_UP, GLFW_KEY_DOWN, GLFW_KEY_LEFT, GLFW_KEY_RIGHT, |     SDL_SCANCODE_UP, SDL_SCANCODE_DOWN, SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT, | ||||||
|     GLFW_KEY_I, GLFW_KEY_K, GLFW_KEY_J, GLFW_KEY_L |     SDL_SCANCODE_I, SDL_SCANCODE_K, SDL_SCANCODE_J, SDL_SCANCODE_L | ||||||
| }; | }; | ||||||
|  |  | ||||||
| void Config::ReadValues() { | void Config::ReadValues() { | ||||||
|     // Controls |     // Controls | ||||||
|     for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) { |     for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) { | ||||||
|         Settings::values.input_mappings[Settings::NativeInput::All[i]] = |         Settings::values.input_mappings[Settings::NativeInput::All[i]] = | ||||||
|             glfw_config->GetInteger("Controls", Settings::NativeInput::Mapping[i], defaults[i]); |             sdl2_config->GetInteger("Controls", Settings::NativeInput::Mapping[i], defaults[i]); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Core |     // Core | ||||||
|     Settings::values.frame_skip = glfw_config->GetInteger("Core", "frame_skip", 0); |     Settings::values.frame_skip = sdl2_config->GetInteger("Core", "frame_skip", 0); | ||||||
|  |  | ||||||
|     // Renderer |     // Renderer | ||||||
|     Settings::values.use_hw_renderer = glfw_config->GetBoolean("Renderer", "use_hw_renderer", false); |     Settings::values.use_hw_renderer = sdl2_config->GetBoolean("Renderer", "use_hw_renderer", false); | ||||||
|     Settings::values.use_shader_jit = glfw_config->GetBoolean("Renderer", "use_shader_jit", true); |     Settings::values.use_shader_jit = sdl2_config->GetBoolean("Renderer", "use_shader_jit", true); | ||||||
|  |  | ||||||
|     Settings::values.bg_red   = (float)glfw_config->GetReal("Renderer", "bg_red",   1.0); |     Settings::values.bg_red   = (float)sdl2_config->GetReal("Renderer", "bg_red",   1.0); | ||||||
|     Settings::values.bg_green = (float)glfw_config->GetReal("Renderer", "bg_green", 1.0); |     Settings::values.bg_green = (float)sdl2_config->GetReal("Renderer", "bg_green", 1.0); | ||||||
|     Settings::values.bg_blue  = (float)glfw_config->GetReal("Renderer", "bg_blue",  1.0); |     Settings::values.bg_blue  = (float)sdl2_config->GetReal("Renderer", "bg_blue",  1.0); | ||||||
|  |  | ||||||
|     // Data Storage |     // Data Storage | ||||||
|     Settings::values.use_virtual_sd = glfw_config->GetBoolean("Data Storage", "use_virtual_sd", true); |     Settings::values.use_virtual_sd = sdl2_config->GetBoolean("Data Storage", "use_virtual_sd", true); | ||||||
|  |  | ||||||
|     // System Region |     // System Region | ||||||
|     Settings::values.region_value = glfw_config->GetInteger("System Region", "region_value", 1); |     Settings::values.region_value = sdl2_config->GetInteger("System Region", "region_value", 1); | ||||||
|  |  | ||||||
|     // Miscellaneous |     // Miscellaneous | ||||||
|     Settings::values.log_filter = glfw_config->Get("Miscellaneous", "log_filter", "*:Info"); |     Settings::values.log_filter = sdl2_config->Get("Miscellaneous", "log_filter", "*:Info"); | ||||||
|  |  | ||||||
|     // Debugging |     // Debugging | ||||||
|     Settings::values.use_gdbstub = glfw_config->GetBoolean("Debugging", "use_gdbstub", false); |     Settings::values.use_gdbstub = sdl2_config->GetBoolean("Debugging", "use_gdbstub", false); | ||||||
|     Settings::values.gdbstub_port = glfw_config->GetInteger("Debugging", "gdbstub_port", 24689); |     Settings::values.gdbstub_port = sdl2_config->GetInteger("Debugging", "gdbstub_port", 24689); | ||||||
| } | } | ||||||
|  |  | ||||||
| void Config::Reload() { | void Config::Reload() { | ||||||
|     LoadINI(glfw_config, glfw_config_loc.c_str(), DefaultINI::glfw_config_file); |     LoadINI(sdl2_config, sdl2_config_loc.c_str(), DefaultINI::sdl2_config_file); | ||||||
|     ReadValues(); |     ReadValues(); | ||||||
| } | } | ||||||
|  |  | ||||||
| Config::~Config() { | Config::~Config() { | ||||||
|     delete glfw_config; |     delete sdl2_config; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -9,8 +9,8 @@ | |||||||
| class INIReader; | class INIReader; | ||||||
|  |  | ||||||
| class Config { | class Config { | ||||||
|     INIReader* glfw_config; |     INIReader* sdl2_config; | ||||||
|     std::string glfw_config_loc; |     std::string sdl2_config_loc; | ||||||
|  |  | ||||||
|     bool LoadINI(INIReader* config, const char* location, const std::string& default_contents="", bool retry=true); |     bool LoadINI(INIReader* config, const char* location, const std::string& default_contents="", bool retry=true); | ||||||
|     void ReadValues(); |     void ReadValues(); | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ | |||||||
|  |  | ||||||
| namespace DefaultINI { | namespace DefaultINI { | ||||||
|  |  | ||||||
| const char* glfw_config_file = R"( | const char* sdl2_config_file = R"( | ||||||
| [Controls] | [Controls] | ||||||
| pad_start = | pad_start = | ||||||
| pad_select = | pad_select = | ||||||
|   | |||||||
| @@ -1,168 +0,0 @@ | |||||||
| // Copyright 2014 Citra Emulator Project |  | ||||||
| // Licensed under GPLv2 or any later version |  | ||||||
| // Refer to the license.txt file included. |  | ||||||
|  |  | ||||||
| #include <algorithm> |  | ||||||
| #include <cstdlib> |  | ||||||
| #include <string> |  | ||||||
|  |  | ||||||
| // Let’s use our own GL header, instead of one from GLFW. |  | ||||||
| #include <glad/glad.h> |  | ||||||
| #define GLFW_INCLUDE_NONE |  | ||||||
| #include <GLFW/glfw3.h> |  | ||||||
|  |  | ||||||
| #include "common/assert.h" |  | ||||||
| #include "common/key_map.h" |  | ||||||
| #include "common/logging/log.h" |  | ||||||
| #include "common/scm_rev.h" |  | ||||||
| #include "common/string_util.h" |  | ||||||
|  |  | ||||||
| #include "video_core/video_core.h" |  | ||||||
|  |  | ||||||
| #include "core/settings.h" |  | ||||||
| #include "core/hle/service/hid/hid.h" |  | ||||||
|  |  | ||||||
| #include "citra/emu_window/emu_window_glfw.h" |  | ||||||
|  |  | ||||||
| EmuWindow_GLFW* EmuWindow_GLFW::GetEmuWindow(GLFWwindow* win) { |  | ||||||
|     return static_cast<EmuWindow_GLFW*>(glfwGetWindowUserPointer(win)); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void EmuWindow_GLFW::OnMouseButtonEvent(GLFWwindow* win, int button, int action, int mods) { |  | ||||||
|     if (button == GLFW_MOUSE_BUTTON_LEFT) { |  | ||||||
|         auto emu_window = GetEmuWindow(win); |  | ||||||
|         auto layout = emu_window->GetFramebufferLayout(); |  | ||||||
|         double x, y; |  | ||||||
|         glfwGetCursorPos(win, &x, &y); |  | ||||||
|  |  | ||||||
|         if (action == GLFW_PRESS) |  | ||||||
|             emu_window->TouchPressed(static_cast<unsigned>(x), static_cast<unsigned>(y)); |  | ||||||
|         else if (action == GLFW_RELEASE) |  | ||||||
|             emu_window->TouchReleased(); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void EmuWindow_GLFW::OnCursorPosEvent(GLFWwindow* win, double x, double y) { |  | ||||||
|     GetEmuWindow(win)->TouchMoved(static_cast<unsigned>(std::max(x, 0.0)), static_cast<unsigned>(std::max(y, 0.0))); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /// Called by GLFW when a key event occurs |  | ||||||
| void EmuWindow_GLFW::OnKeyEvent(GLFWwindow* win, int key, int scancode, int action, int mods) { |  | ||||||
|     auto emu_window = GetEmuWindow(win); |  | ||||||
|     int keyboard_id = emu_window->keyboard_id; |  | ||||||
|  |  | ||||||
|     if (action == GLFW_PRESS) { |  | ||||||
|         emu_window->KeyPressed({key, keyboard_id}); |  | ||||||
|     } else if (action == GLFW_RELEASE) { |  | ||||||
|         emu_window->KeyReleased({key, keyboard_id}); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /// Whether the window is still open, and a close request hasn't yet been sent |  | ||||||
| const bool EmuWindow_GLFW::IsOpen() { |  | ||||||
|     return glfwWindowShouldClose(m_render_window) == 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void EmuWindow_GLFW::OnFramebufferResizeEvent(GLFWwindow* win, int width, int height) { |  | ||||||
|     GetEmuWindow(win)->NotifyFramebufferLayoutChanged(EmuWindow::FramebufferLayout::DefaultScreenLayout(width, height)); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void EmuWindow_GLFW::OnClientAreaResizeEvent(GLFWwindow* win, int width, int height) { |  | ||||||
|     // NOTE: GLFW provides no proper way to set a minimal window size. |  | ||||||
|     //       Hence, we just ignore the corresponding EmuWindow hint. |  | ||||||
|     OnFramebufferResizeEvent(win, width, height); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /// EmuWindow_GLFW constructor |  | ||||||
| EmuWindow_GLFW::EmuWindow_GLFW() { |  | ||||||
|     keyboard_id = KeyMap::NewDeviceId(); |  | ||||||
|  |  | ||||||
|     ReloadSetKeymaps(); |  | ||||||
|  |  | ||||||
|     glfwSetErrorCallback([](int error, const char *desc){ |  | ||||||
|         LOG_ERROR(Frontend, "GLFW 0x%08x: %s", error, desc); |  | ||||||
|     }); |  | ||||||
|  |  | ||||||
|     // Initialize the window |  | ||||||
|     if(glfwInit() != GL_TRUE) { |  | ||||||
|         LOG_CRITICAL(Frontend, "Failed to initialize GLFW! Exiting..."); |  | ||||||
|         exit(1); |  | ||||||
|     } |  | ||||||
|     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); |  | ||||||
|     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); |  | ||||||
|     // GLFW on OSX requires these window hints to be set to create a 3.2+ GL context. |  | ||||||
|     glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); |  | ||||||
|     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); |  | ||||||
|  |  | ||||||
|     std::string window_title = Common::StringFromFormat("Citra | %s-%s", Common::g_scm_branch, Common::g_scm_desc); |  | ||||||
|     m_render_window = glfwCreateWindow(VideoCore::kScreenTopWidth, |  | ||||||
|         (VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight), |  | ||||||
|         window_title.c_str(), nullptr, nullptr); |  | ||||||
|  |  | ||||||
|     if (m_render_window == nullptr) { |  | ||||||
|         LOG_CRITICAL(Frontend, "Failed to create GLFW window! Exiting..."); |  | ||||||
|         exit(1); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     glfwSetWindowUserPointer(m_render_window, this); |  | ||||||
|  |  | ||||||
|     // Notify base interface about window state |  | ||||||
|     int width, height; |  | ||||||
|     glfwGetFramebufferSize(m_render_window, &width, &height); |  | ||||||
|     OnFramebufferResizeEvent(m_render_window, width, height); |  | ||||||
|  |  | ||||||
|     glfwGetWindowSize(m_render_window, &width, &height); |  | ||||||
|     OnClientAreaResizeEvent(m_render_window, width, height); |  | ||||||
|  |  | ||||||
|     // Setup callbacks |  | ||||||
|     glfwSetKeyCallback(m_render_window, OnKeyEvent); |  | ||||||
|     glfwSetMouseButtonCallback(m_render_window, OnMouseButtonEvent); |  | ||||||
|     glfwSetCursorPosCallback(m_render_window, OnCursorPosEvent); |  | ||||||
|     glfwSetFramebufferSizeCallback(m_render_window, OnFramebufferResizeEvent); |  | ||||||
|     glfwSetWindowSizeCallback(m_render_window, OnClientAreaResizeEvent); |  | ||||||
|  |  | ||||||
|     DoneCurrent(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /// EmuWindow_GLFW destructor |  | ||||||
| EmuWindow_GLFW::~EmuWindow_GLFW() { |  | ||||||
|     glfwTerminate(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /// Swap buffers to display the next frame |  | ||||||
| void EmuWindow_GLFW::SwapBuffers() { |  | ||||||
|     glfwSwapBuffers(m_render_window); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /// Polls window events |  | ||||||
| void EmuWindow_GLFW::PollEvents() { |  | ||||||
|     glfwPollEvents(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /// Makes the GLFW OpenGL context current for the caller thread |  | ||||||
| void EmuWindow_GLFW::MakeCurrent() { |  | ||||||
|     glfwMakeContextCurrent(m_render_window); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /// Releases (dunno if this is the "right" word) the GLFW context from the caller thread |  | ||||||
| void EmuWindow_GLFW::DoneCurrent() { |  | ||||||
|     glfwMakeContextCurrent(nullptr); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void EmuWindow_GLFW::ReloadSetKeymaps() { |  | ||||||
|     for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) { |  | ||||||
|         KeyMap::SetKeyMapping({Settings::values.input_mappings[Settings::NativeInput::All[i]], keyboard_id}, Service::HID::pad_mapping[i]); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void EmuWindow_GLFW::OnMinimalClientAreaChangeRequest(const std::pair<unsigned,unsigned>& minimal_size) { |  | ||||||
|     std::pair<int,int> current_size; |  | ||||||
|     glfwGetWindowSize(m_render_window, ¤t_size.first, ¤t_size.second); |  | ||||||
|  |  | ||||||
|     DEBUG_ASSERT((int)minimal_size.first > 0 && (int)minimal_size.second > 0); |  | ||||||
|     int new_width  = std::max(current_size.first,  (int)minimal_size.first); |  | ||||||
|     int new_height = std::max(current_size.second, (int)minimal_size.second); |  | ||||||
|  |  | ||||||
|     if (current_size != std::make_pair(new_width, new_height)) |  | ||||||
|         glfwSetWindowSize(m_render_window, new_width, new_height); |  | ||||||
| } |  | ||||||
| @@ -1,54 +0,0 @@ | |||||||
| // Copyright 2014 Citra Emulator Project |  | ||||||
| // Licensed under GPLv2 or any later version |  | ||||||
| // Refer to the license.txt file included. |  | ||||||
|  |  | ||||||
| #pragma once |  | ||||||
|  |  | ||||||
| #include <utility> |  | ||||||
|  |  | ||||||
| #include "common/emu_window.h" |  | ||||||
|  |  | ||||||
| struct GLFWwindow; |  | ||||||
|  |  | ||||||
| class EmuWindow_GLFW : public EmuWindow { |  | ||||||
| public: |  | ||||||
|     EmuWindow_GLFW(); |  | ||||||
|     ~EmuWindow_GLFW(); |  | ||||||
|  |  | ||||||
|     /// Swap buffers to display the next frame |  | ||||||
|     void SwapBuffers() override; |  | ||||||
|  |  | ||||||
|     /// Polls window events |  | ||||||
|     void PollEvents() override; |  | ||||||
|  |  | ||||||
|     /// Makes the graphics context current for the caller thread |  | ||||||
|     void MakeCurrent() override; |  | ||||||
|  |  | ||||||
|     /// Releases (dunno if this is the "right" word) the GLFW context from the caller thread |  | ||||||
|     void DoneCurrent() override; |  | ||||||
|  |  | ||||||
|     static void OnKeyEvent(GLFWwindow* win, int key, int scancode, int action, int mods); |  | ||||||
|  |  | ||||||
|     static void OnMouseButtonEvent(GLFWwindow* window, int button, int action, int mods); |  | ||||||
|  |  | ||||||
|     static void OnCursorPosEvent(GLFWwindow* window, double x, double y); |  | ||||||
|  |  | ||||||
|     /// Whether the window is still open, and a close request hasn't yet been sent |  | ||||||
|     const bool IsOpen(); |  | ||||||
|  |  | ||||||
|     static void OnClientAreaResizeEvent(GLFWwindow* win, int width, int height); |  | ||||||
|  |  | ||||||
|     static void OnFramebufferResizeEvent(GLFWwindow* win, int width, int height); |  | ||||||
|  |  | ||||||
|     void ReloadSetKeymaps() override; |  | ||||||
|  |  | ||||||
| private: |  | ||||||
|     void OnMinimalClientAreaChangeRequest(const std::pair<unsigned,unsigned>& minimal_size) override; |  | ||||||
|  |  | ||||||
|     static EmuWindow_GLFW* GetEmuWindow(GLFWwindow* win); |  | ||||||
|  |  | ||||||
|     GLFWwindow* m_render_window; ///< Internal GLFW render window |  | ||||||
|  |  | ||||||
|     /// Device id of keyboard for use with KeyMap |  | ||||||
|     int keyboard_id; |  | ||||||
| }; |  | ||||||
							
								
								
									
										167
									
								
								src/citra/emu_window/emu_window_sdl2.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								src/citra/emu_window/emu_window_sdl2.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,167 @@ | |||||||
|  | // Copyright 2016 Citra Emulator Project | ||||||
|  | // Licensed under GPLv2 or any later version | ||||||
|  | // Refer to the license.txt file included. | ||||||
|  |  | ||||||
|  | #include <algorithm> | ||||||
|  | #include <cstdlib> | ||||||
|  | #include <string> | ||||||
|  |  | ||||||
|  | #define SDL_MAIN_HANDLED | ||||||
|  | #include <SDL.h> | ||||||
|  |  | ||||||
|  | #include "common/key_map.h" | ||||||
|  | #include "common/logging/log.h" | ||||||
|  | #include "common/scm_rev.h" | ||||||
|  | #include "common/string_util.h" | ||||||
|  |  | ||||||
|  | #include "core/settings.h" | ||||||
|  | #include "core/hle/service/hid/hid.h" | ||||||
|  |  | ||||||
|  | #include "citra/emu_window/emu_window_sdl2.h" | ||||||
|  |  | ||||||
|  | #include "video_core/video_core.h" | ||||||
|  |  | ||||||
|  | void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) { | ||||||
|  |     TouchMoved((unsigned)std::max(x, 0), (unsigned)std::max(y, 0)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) { | ||||||
|  |     if (button != SDL_BUTTON_LEFT) | ||||||
|  |         return; | ||||||
|  |  | ||||||
|  |     if (state == SDL_PRESSED) { | ||||||
|  |         TouchPressed((unsigned)std::max(x, 0), (unsigned)std::max(y, 0)); | ||||||
|  |     } else { | ||||||
|  |         TouchReleased(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void EmuWindow_SDL2::OnKeyEvent(int key, u8 state) { | ||||||
|  |     if (state == SDL_PRESSED) { | ||||||
|  |         KeyPressed({ key, keyboard_id }); | ||||||
|  |     } else if (state == SDL_RELEASED) { | ||||||
|  |         KeyReleased({ key, keyboard_id }); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool EmuWindow_SDL2::IsOpen() const { | ||||||
|  |     return is_open; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void EmuWindow_SDL2::OnResize() { | ||||||
|  |     int width, height; | ||||||
|  |  | ||||||
|  |     SDL_GetWindowSize(render_window, &width, &height); | ||||||
|  |  | ||||||
|  |     NotifyFramebufferLayoutChanged(EmuWindow::FramebufferLayout::DefaultScreenLayout(width, height)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | EmuWindow_SDL2::EmuWindow_SDL2() { | ||||||
|  |     keyboard_id = KeyMap::NewDeviceId(); | ||||||
|  |  | ||||||
|  |     ReloadSetKeymaps(); | ||||||
|  |  | ||||||
|  |     SDL_SetMainReady(); | ||||||
|  |  | ||||||
|  |     // Initialize the window | ||||||
|  |     if (SDL_Init(SDL_INIT_VIDEO) < 0) { | ||||||
|  |         LOG_CRITICAL(Frontend, "Failed to initialize SDL2! Exiting..."); | ||||||
|  |         exit(1); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); | ||||||
|  |     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); | ||||||
|  |     SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); | ||||||
|  |     SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); | ||||||
|  |  | ||||||
|  |     std::string window_title = Common::StringFromFormat("Citra | %s-%s", Common::g_scm_branch, Common::g_scm_desc); | ||||||
|  |     render_window = SDL_CreateWindow(window_title.c_str(), | ||||||
|  |         SDL_WINDOWPOS_UNDEFINED, // x position | ||||||
|  |         SDL_WINDOWPOS_UNDEFINED, // y position | ||||||
|  |         VideoCore::kScreenTopWidth, | ||||||
|  |         VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight, | ||||||
|  |         SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); | ||||||
|  |  | ||||||
|  |     if (render_window == nullptr) { | ||||||
|  |         LOG_CRITICAL(Frontend, "Failed to create SDL2 window! Exiting..."); | ||||||
|  |         exit(1); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     gl_context = SDL_GL_CreateContext(render_window); | ||||||
|  |  | ||||||
|  |     if (gl_context == nullptr) { | ||||||
|  |         LOG_CRITICAL(Frontend, "Failed to create SDL2 GL context! Exiting..."); | ||||||
|  |         exit(1); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     OnResize(); | ||||||
|  |     OnMinimalClientAreaChangeRequest(GetActiveConfig().min_client_area_size); | ||||||
|  |     SDL_PumpEvents(); | ||||||
|  |  | ||||||
|  |     DoneCurrent(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | EmuWindow_SDL2::~EmuWindow_SDL2() { | ||||||
|  |     SDL_GL_DeleteContext(gl_context); | ||||||
|  |     SDL_Quit(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void EmuWindow_SDL2::SwapBuffers() { | ||||||
|  |     SDL_GL_SwapWindow(render_window); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void EmuWindow_SDL2::PollEvents() { | ||||||
|  |     SDL_Event event; | ||||||
|  |  | ||||||
|  |     // SDL_PollEvent returns 0 when there are no more events in the event queue | ||||||
|  |     while (SDL_PollEvent(&event)) { | ||||||
|  |         switch (event.type) { | ||||||
|  |         case SDL_WINDOWEVENT: | ||||||
|  |             switch (event.window.event) { | ||||||
|  |             case SDL_WINDOWEVENT_SIZE_CHANGED: | ||||||
|  |             case SDL_WINDOWEVENT_RESIZED: | ||||||
|  |             case SDL_WINDOWEVENT_MAXIMIZED: | ||||||
|  |             case SDL_WINDOWEVENT_RESTORED: | ||||||
|  |             case SDL_WINDOWEVENT_MINIMIZED: | ||||||
|  |                 OnResize(); | ||||||
|  |                 break; | ||||||
|  |             case SDL_WINDOWEVENT_CLOSE: | ||||||
|  |                 is_open = false; | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |             break; | ||||||
|  |         case SDL_KEYDOWN: | ||||||
|  |         case SDL_KEYUP: | ||||||
|  |             OnKeyEvent(static_cast<int>(event.key.keysym.scancode), event.key.state); | ||||||
|  |             break; | ||||||
|  |         case SDL_MOUSEMOTION: | ||||||
|  |             OnMouseMotion(event.motion.x, event.motion.y); | ||||||
|  |             break; | ||||||
|  |         case SDL_MOUSEBUTTONDOWN: | ||||||
|  |         case SDL_MOUSEBUTTONUP: | ||||||
|  |             OnMouseButton(event.button.button, event.button.state, event.button.x, event.button.y); | ||||||
|  |             break; | ||||||
|  |         case SDL_QUIT: | ||||||
|  |             is_open = false; | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void EmuWindow_SDL2::MakeCurrent() { | ||||||
|  |     SDL_GL_MakeCurrent(render_window, gl_context); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void EmuWindow_SDL2::DoneCurrent() { | ||||||
|  |     SDL_GL_MakeCurrent(render_window, nullptr); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void EmuWindow_SDL2::ReloadSetKeymaps() { | ||||||
|  |     for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) { | ||||||
|  |         KeyMap::SetKeyMapping({ Settings::values.input_mappings[Settings::NativeInput::All[i]], keyboard_id }, Service::HID::pad_mapping[i]); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void EmuWindow_SDL2::OnMinimalClientAreaChangeRequest(const std::pair<unsigned, unsigned>& minimal_size) { | ||||||
|  |     SDL_SetWindowMinimumSize(render_window, minimal_size.first, minimal_size.second); | ||||||
|  | } | ||||||
							
								
								
									
										64
									
								
								src/citra/emu_window/emu_window_sdl2.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								src/citra/emu_window/emu_window_sdl2.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | |||||||
|  | // Copyright 2016 Citra Emulator Project | ||||||
|  | // Licensed under GPLv2 or any later version | ||||||
|  | // Refer to the license.txt file included. | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include <utility> | ||||||
|  |  | ||||||
|  | #include "common/emu_window.h" | ||||||
|  |  | ||||||
|  | struct SDL_Window; | ||||||
|  |  | ||||||
|  | class EmuWindow_SDL2 : public EmuWindow { | ||||||
|  | public: | ||||||
|  |     EmuWindow_SDL2(); | ||||||
|  |     ~EmuWindow_SDL2(); | ||||||
|  |  | ||||||
|  |     /// Swap buffers to display the next frame | ||||||
|  |     void SwapBuffers() override; | ||||||
|  |  | ||||||
|  |     /// Polls window events | ||||||
|  |     void PollEvents() override; | ||||||
|  |  | ||||||
|  |     /// Makes the graphics context current for the caller thread | ||||||
|  |     void MakeCurrent() override; | ||||||
|  |  | ||||||
|  |     /// Releases the GL context from the caller thread | ||||||
|  |     void DoneCurrent() override; | ||||||
|  |  | ||||||
|  |     /// Whether the window is still open, and a close request hasn't yet been sent | ||||||
|  |     bool IsOpen() const; | ||||||
|  |  | ||||||
|  |     /// Load keymap from configuration | ||||||
|  |     void ReloadSetKeymaps() override; | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     /// Called by PollEvents when a key is pressed or released. | ||||||
|  |     void OnKeyEvent(int key, u8 state); | ||||||
|  |  | ||||||
|  |     /// Called by PollEvents when the mouse moves. | ||||||
|  |     void OnMouseMotion(s32 x, s32 y); | ||||||
|  |  | ||||||
|  |     /// Called by PollEvents when a mouse button is pressed or released | ||||||
|  |     void OnMouseButton(u32 button, u8 state, s32 x, s32 y); | ||||||
|  |  | ||||||
|  |     /// Called by PollEvents when any event that may cause the window to be resized occurs | ||||||
|  |     void OnResize(); | ||||||
|  |  | ||||||
|  |     /// Called when a configuration change affects the minimal size of the window | ||||||
|  |     void OnMinimalClientAreaChangeRequest(const std::pair<unsigned, unsigned>& minimal_size) override; | ||||||
|  |  | ||||||
|  |     /// Is the window still open? | ||||||
|  |     bool is_open = true; | ||||||
|  |  | ||||||
|  |     /// Internal SDL2 render window | ||||||
|  |     SDL_Window* render_window; | ||||||
|  |  | ||||||
|  |     using SDL_GLContext = void *; | ||||||
|  |     /// The OpenGL context associated with the window | ||||||
|  |     SDL_GLContext gl_context; | ||||||
|  |  | ||||||
|  |     /// Device id of keyboard for use with KeyMap | ||||||
|  |     int keyboard_id; | ||||||
|  | }; | ||||||
| @@ -88,9 +88,14 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Linux|FreeBSD|OpenBSD|NetBSD") | |||||||
| endif() | endif() | ||||||
|  |  | ||||||
| if (Qt5_FOUND AND MSVC) | if (Qt5_FOUND AND MSVC) | ||||||
|  |     include(WindowsCopyFiles) | ||||||
|  |  | ||||||
|     set(Qt5_DLL_DIR "${Qt5_DIR}/../../../bin") |     set(Qt5_DLL_DIR "${Qt5_DIR}/../../../bin") | ||||||
|     set(Qt5_PLATFORMS_DIR "${Qt5_DIR}/../../../plugins/platforms/") |     set(Qt5_PLATFORMS_DIR "${Qt5_DIR}/../../../plugins/platforms/") | ||||||
|     set(Qt5_DLLS |     set(DLL_DEST "${CMAKE_BINARY_DIR}/bin/$<CONFIG>/") | ||||||
|  |     set(PLATFORMS ${DLL_DEST}platforms/) | ||||||
|  |  | ||||||
|  |     windows_copy_files(citra-qt ${Qt5_DLL_DIR} ${DLL_DEST} | ||||||
|         icudt*.dll |         icudt*.dll | ||||||
|         icuin*.dll |         icuin*.dll | ||||||
|         icuuc*.dll |         icuuc*.dll | ||||||
| @@ -99,24 +104,8 @@ if (Qt5_FOUND AND MSVC) | |||||||
|         Qt5OpenGL$<$<CONFIG:Debug>:d>.* |         Qt5OpenGL$<$<CONFIG:Debug>:d>.* | ||||||
|         Qt5Widgets$<$<CONFIG:Debug>:d>.* |         Qt5Widgets$<$<CONFIG:Debug>:d>.* | ||||||
|     ) |     ) | ||||||
|     set(DLL_DEST "${CMAKE_BINARY_DIR}/bin/$<CONFIG>/") |     windows_copy_files(citra-qt ${Qt5_PLATFORMS_DIR} ${PLATFORMS} qwindows$<$<CONFIG:Debug>:d>.*) | ||||||
|     set(PLATFORMS ${DLL_DEST}platforms/) |  | ||||||
|  |  | ||||||
|     # windows commandline expects the / to be \ so switch them |  | ||||||
|     string(REPLACE "/" "\\\\" Qt5_DLL_DIR ${Qt5_DLL_DIR}) |  | ||||||
|     string(REPLACE "/" "\\\\" Qt5_PLATFORMS_DIR ${Qt5_PLATFORMS_DIR}) |  | ||||||
|     string(REPLACE "/" "\\\\" DLL_DEST ${DLL_DEST}) |  | ||||||
|     string(REPLACE "/" "\\\\" PLATFORMS ${PLATFORMS}) |  | ||||||
|  |  | ||||||
|     # /NJH /NJS /NDL /NFL /NC /NS /NP - Silence any output |  | ||||||
|     # cmake adds an extra check for command success which doesn't work too well with robocopy |  | ||||||
|     # so trick it into thinking the command was successful with the || cmd /c "exit /b 0" |  | ||||||
|     add_custom_command(TARGET citra-qt POST_BUILD |  | ||||||
|         COMMAND robocopy ${Qt5_DLL_DIR} ${DLL_DEST} ${Qt5_DLLS} /NJH /NJS /NDL /NFL /NC /NS /NP || cmd /c "exit /b 0" |  | ||||||
|         COMMAND if not exist ${PLATFORMS} mkdir ${PLATFORMS} 2> nul |  | ||||||
|         COMMAND robocopy ${Qt5_PLATFORMS_DIR} ${PLATFORMS} qwindows$<$<CONFIG:Debug>:d>.* /NJH /NJS /NDL /NFL /NC /NS /NP || cmd /c "exit /b 0" |  | ||||||
|     ) |  | ||||||
|     unset(Qt5_DLLS) |  | ||||||
|     unset(Qt5_DLL_DIR) |     unset(Qt5_DLL_DIR) | ||||||
|     unset(Qt5_PLATFORMS_DIR) |     unset(Qt5_PLATFORMS_DIR) | ||||||
|     unset(DLL_DEST) |     unset(DLL_DEST) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user