mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-25 07:35:38 +00:00
Initial update to make the application build and run on Windows.
Much more work will be needed to get the Windows port working properly.
This commit is contained in:
parent
e4fdd1e20d
commit
76aa239855
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -6,6 +6,9 @@
|
||||||
# Compiled Dynamic libraries
|
# Compiled Dynamic libraries
|
||||||
*.so
|
*.so
|
||||||
|
|
||||||
|
# Windows Dynamic-link libraries
|
||||||
|
*.[dD][lL][lL]
|
||||||
|
|
||||||
# Compiled Static libraries
|
# Compiled Static libraries
|
||||||
*.lai
|
*.lai
|
||||||
*.la
|
*.la
|
||||||
|
@ -16,6 +19,7 @@
|
||||||
|
|
||||||
# Compiled executable
|
# Compiled executable
|
||||||
emulationstation
|
emulationstation
|
||||||
|
emulationstation.exe
|
||||||
|
|
||||||
# build directory
|
# build directory
|
||||||
build
|
build
|
||||||
|
|
|
@ -56,13 +56,17 @@ if(${GLSystem} MATCHES "Desktop OpenGL")
|
||||||
else()
|
else()
|
||||||
find_package(OpenGLES REQUIRED)
|
find_package(OpenGLES REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
find_package(CURL REQUIRED)
|
|
||||||
find_package(FreeImage REQUIRED)
|
# Skip package dependency checks if we're on Windows.
|
||||||
find_package(Freetype REQUIRED)
|
if (NOT WIN32)
|
||||||
find_package(Pugixml REQUIRED)
|
find_package(CURL REQUIRED)
|
||||||
find_package(RapidJSON REQUIRED)
|
find_package(FreeImage REQUIRED)
|
||||||
find_package(SDL2 REQUIRED)
|
find_package(Freetype REQUIRED)
|
||||||
find_package(VLC REQUIRED)
|
find_package(Pugixml REQUIRED)
|
||||||
|
find_package(RapidJSON REQUIRED)
|
||||||
|
find_package(SDL2 REQUIRED)
|
||||||
|
find_package(VLC REQUIRED)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Add libCEC support.
|
# Add libCEC support.
|
||||||
if(CEC)
|
if(CEC)
|
||||||
|
@ -101,14 +105,10 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||||
if (G++_VERSION VERSION_LESS 4.8)
|
if (G++_VERSION VERSION_LESS 4.8)
|
||||||
message(SEND_ERROR "You need at least GCC 4.8 to compile EmulationStation-DE!")
|
message(SEND_ERROR "You need at least GCC 4.8 to compile EmulationStation-DE!")
|
||||||
endif()
|
endif()
|
||||||
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
if (WIN32)
|
||||||
message("-- Compiler is MSVC (NOT TESTED)")
|
set(CMAKE_CXX_FLAGS "-mwindows ${CMAKE_CXX_FLAGS}")
|
||||||
set(CMAKE_DEBUG_POSTFIX "d")
|
# set(CMAKE_CXX_FLAGS "-static-libstdc++ -static-libgcc ${CMAKE_CXX_FLAGS}")
|
||||||
add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
|
endif()
|
||||||
add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE)
|
|
||||||
add_definitions(-DNOMINMAX)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") # Multi-processor compilation.
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MP") # Multi-processor compilation.
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Set up compiler flags for debug or release builds.
|
# Set up compiler flags for debug or release builds.
|
||||||
|
@ -136,13 +136,24 @@ else()
|
||||||
add_definitions(-DUSE_OPENGLES_10)
|
add_definitions(-DUSE_OPENGLES_10)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Assign the installation prefix to local $ES_INSTALL_PREFIX variable.
|
# For Unix systems, assign the installation prefix to local $ES_INSTALL_PREFIX variable.
|
||||||
add_definitions(-DES_INSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}")
|
if (NOT WIN32)
|
||||||
|
add_definitions(-DES_INSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}")
|
||||||
|
endif()
|
||||||
|
|
||||||
# Enable additional defines for the Debug build configuration.
|
# Enable additional defines for the Debug build configuration.
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG")
|
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG")
|
||||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG")
|
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG")
|
||||||
|
|
||||||
|
# Handle additional (required) include files for dependency packages.
|
||||||
|
if (WIN32)
|
||||||
|
set(WIN32_INCLUDE_DIR "NOT_DEFINED" CACHE FILEPATH "")
|
||||||
|
if(NOT EXISTS ${WIN32_INCLUDE_DIR})
|
||||||
|
message(SEND_ERROR "Can't find WIN32 include directory: ${WIN32_INCLUDE_DIR}")
|
||||||
|
endif()
|
||||||
|
#include_directories(${WIN32_INCLUDE_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------------------------
|
||||||
# Add include directories.
|
# Add include directories.
|
||||||
set(COMMON_INCLUDE_DIRS
|
set(COMMON_INCLUDE_DIRS
|
||||||
|
@ -157,6 +168,12 @@ set(COMMON_INCLUDE_DIRS
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/es-core/src
|
${CMAKE_CURRENT_SOURCE_DIR}/es-core/src
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
set(COMMON_INCLUDE_DIRS
|
||||||
|
${COMMON_INCLUDE_DIRS}
|
||||||
|
${WIN32_INCLUDE_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
# Add libCEC include directory.
|
# Add libCEC include directory.
|
||||||
if(DEFINED libCEC_FOUND)
|
if(DEFINED libCEC_FOUND)
|
||||||
LIST(APPEND COMMON_INCLUDE_DIRS
|
LIST(APPEND COMMON_INCLUDE_DIRS
|
||||||
|
@ -200,14 +217,28 @@ elseif(DEFINED VERO4K)
|
||||||
"${CMAKE_FIND_ROOT_PATH}/opt/vero3/lib")
|
"${CMAKE_FIND_ROOT_PATH}/opt/vero3/lib")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(COMMON_LIBRARIES
|
if (NOT WIN32)
|
||||||
${CURL_LIBRARIES}
|
set(COMMON_LIBRARIES
|
||||||
${FreeImage_LIBRARIES}
|
${CURL_LIBRARIES}
|
||||||
${FREETYPE_LIBRARIES}
|
${FreeImage_LIBRARIES}
|
||||||
${PUGIXML_LIBRARIES}
|
${FREETYPE_LIBRARIES}
|
||||||
${SDL2_LIBRARY}
|
${PUGIXML_LIBRARIES}
|
||||||
${VLC_LIBRARIES}
|
${SDL2_LIBRARY}
|
||||||
nanosvg)
|
${VLC_LIBRARIES}
|
||||||
|
nanosvg)
|
||||||
|
elseif(WIN32)
|
||||||
|
set(COMMON_LIBRARIES
|
||||||
|
"${PROJECT_SOURCE_DIR}/libpugixml.dll"
|
||||||
|
"${PROJECT_SOURCE_DIR}/FreeImage.dll"
|
||||||
|
"${PROJECT_SOURCE_DIR}/libcurl-x64.dll"
|
||||||
|
"${PROJECT_SOURCE_DIR}/libvlc.dll"
|
||||||
|
"${PROJECT_SOURCE_DIR}/libfreetype.dll"
|
||||||
|
"Winmm.dll"
|
||||||
|
"mingw32"
|
||||||
|
"${PROJECT_SOURCE_DIR}/libSDL2main.a"
|
||||||
|
"${PROJECT_SOURCE_DIR}/SDL2.dll"
|
||||||
|
"nanosvg")
|
||||||
|
endif()
|
||||||
|
|
||||||
# Add libCEC libraries.
|
# Add libCEC libraries.
|
||||||
if(DEFINED libCEC_FOUND)
|
if(DEFINED libCEC_FOUND)
|
||||||
|
|
176
INSTALL.md
176
INSTALL.md
|
@ -175,25 +175,177 @@ sudo apt-get install rpm
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
**On Windows:**
|
### On Windows:
|
||||||
|
|
||||||
[CMake](http://www.cmake.org/cmake/resources/software.html)
|
This is a strange legacy operating system. However it's still popular, so we need to support it for the time being.
|
||||||
|
|
||||||
[SDL2](http://www.libsdl.org/release/SDL2-devel-2.0.8-VC.zip)
|
I did a brief evaluation of the Microsoft Visual C++ compiler (MSVC) but as far as I'm concerned it's an abomination so I won't cover it here and it won't be supported.
|
||||||
|
|
||||||
[FreeImage](http://downloads.sourceforge.net/freeimage/FreeImage3154Win32.zip)
|
At the moment I have only built the software using GCC on Windows, but I may try to get Clang/LLVM working at a later date.
|
||||||
|
|
||||||
[FreeType2](http://download.savannah.gnu.org/releases/freetype/freetype-2.4.9.tar.bz2) (you'll need to compile)
|
Anyway, here's a brief summary of how to get a build environment up and running on Windows.
|
||||||
|
|
||||||
[cURL](http://curl.haxx.se/download.html) (you'll need to compile or get the pre-compiled DLL version)
|
**Install Git, CMake, MinGW and your code editor:**
|
||||||
|
|
||||||
[RapisJSON](https://github.com/tencent/rapidjson) (you need to add `include/rapidsjon` to your include path)
|
[Git](https://gitforwindows.org)
|
||||||
|
|
||||||
Remember to copy the necessary .DLL files into the same folder as the executable: probably FreeImage.dll, freetype6.dll, SDL2.dll, libcurl.dll, and zlib1.dll. Exact list depends on if you built your libraries in "static" mode or not.
|
[CMake](https://cmake.org/download)
|
||||||
|
|
||||||
|
[MinGW](https://gnutoolchains.com/mingw64)
|
||||||
|
|
||||||
|
Make a copy of `mingw64/bin/mingw32-make` to `make` just for convenience and make sure that the necessary paths are defined for the PATH environmental variable.
|
||||||
|
|
||||||
|
I won't get into the details on how to configure Git, but there are many resources available online to support with this. The `Git Bash` shell is very useful though as it's somewhat reproducing a Unix environment using MinGW/MSYS.
|
||||||
|
|
||||||
|
Install your editor of choice. As for VSCodium it's unfortunately broken or crippled under Windows, making some important extensions impossible to install. VSCode works fine, but make sure to disable all surveillance functionality (telemetry).
|
||||||
|
|
||||||
|
It's strongly recommended to set line breaks to linefeed (Unix-style) directly in the editor, although it can also be configured in Git for conversion during commit. The source code for EmulationStation-DE only uses Unix-style line breaks.
|
||||||
|
|
||||||
|
**Enable pretty printing for GDB:**
|
||||||
|
|
||||||
|
This is useful for displaying std::string values for example.
|
||||||
|
|
||||||
|
Adjust your paths accordingly, the below are just examples of course.
|
||||||
|
|
||||||
|
Save a file to
|
||||||
|
C:/Programming/mingw64/bin/pp.gdb with the following contents:
|
||||||
|
|
||||||
|
```
|
||||||
|
python
|
||||||
|
import sys
|
||||||
|
sys.path.insert(0, 'c:/Programming/mingw64/share/gcc-9.1.0/python/libstdcxx/v6')
|
||||||
|
from printers import register_libstdcxx_printers
|
||||||
|
register_libstdcxx_printers (None)
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
If using VSCode, add the following line to launch.json:
|
||||||
|
|
||||||
|
`"miDebuggerArgs": "-x c:/programming/mingw64/bin/pp.gdb",`
|
||||||
|
|
||||||
|
An equivalent setup should be possible on other code editors as well.
|
||||||
|
|
||||||
|
Note that most GDB builds for Windows have broken Python support so that pretty printing won't work. The MinGW installation recommended in the previous step seems to work fine though.
|
||||||
|
|
||||||
|
**Download the dependency packages:**
|
||||||
|
|
||||||
|
[FreeImage](https://sourceforge.net/projects/freeimage)
|
||||||
|
|
||||||
|
[cURL](https://curl.haxx.se/download.html)
|
||||||
|
|
||||||
|
[SDL2](https://www.libsdl.org/download-2.0.php)
|
||||||
|
|
||||||
|
[libVLC](https://ftp.lysator.liu.se/pub/videolan/vlc)
|
||||||
|
|
||||||
|
Uncompress the files to a suitable directory, for example C:/Programming/Dependencies/
|
||||||
|
|
||||||
|
The following packages are not readily available for Windows, so clone the repos and build them yourself:
|
||||||
|
|
||||||
|
[FreeType](https://www.freetype.org)
|
||||||
|
```
|
||||||
|
git clone git://git.savannah.gnu.org/freetype/freetype2.git
|
||||||
|
git checkout VER-2-10-2
|
||||||
|
mkdir build
|
||||||
|
cmake -G "MinGW Makefiles" -DBUILD_SHARED_LIBS=ON ..
|
||||||
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
[pugixml](https://pugixml.org)
|
||||||
|
```
|
||||||
|
git clone git://github.com/zeux/pugixml
|
||||||
|
git checkout v1.10
|
||||||
|
cmake -G "MinGW Makefiles" -DBUILD_SHARED_LIBS=ON .
|
||||||
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
As for RapidJSON, you don't need to compile it, you just need the include files:
|
||||||
|
|
||||||
|
[RapidJSON](http://rapidjson.org)
|
||||||
|
```
|
||||||
|
git clone git://github.com/Tencent/rapidjson
|
||||||
|
git checkout v1.1.0
|
||||||
|
```
|
||||||
|
|
||||||
|
**Clone the EmulationStation-DE repository:**
|
||||||
|
|
||||||
|
This works the same as in Unix, just run the following:
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://gitlab.com/leonstyhre/emulationstation-de
|
||||||
|
```
|
||||||
|
|
||||||
|
**Setup the include directories:**
|
||||||
|
|
||||||
|
As there is no standardized include directory structure in Windows and no package manager, you need to provide the include files manually.
|
||||||
|
|
||||||
|
Make a directory in your build environment tree, for instance under `C:/Programming/include`.
|
||||||
|
|
||||||
|
Copy the include files from cURL, FreeImage, FreeType, pugixml, RapidJSON, SDL2 and VLC to this directory.
|
||||||
|
It should then look something like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ls -1 include/
|
||||||
|
curl/
|
||||||
|
FreeImage.h
|
||||||
|
freetype/
|
||||||
|
ft2build.h
|
||||||
|
pugiconfig.hpp
|
||||||
|
pugixml.hpp
|
||||||
|
rapidjson/
|
||||||
|
SDL2/
|
||||||
|
vlc/
|
||||||
|
```
|
||||||
|
|
||||||
|
**Copy the required DLL files to the EmulationStation build directory:**
|
||||||
|
|
||||||
|
As there's no package manager in Windows and no way to handle dependencies, we need to ship all the required shared libraries with the application.
|
||||||
|
|
||||||
|
Copy the following files to the `emulationstation-de` build directory. Most of them will come from the packages that were provided in the previous steps of this guide:
|
||||||
|
|
||||||
|
```
|
||||||
|
FreeImage.dll
|
||||||
|
libcrypto-1_1-x64.dll (from the OpenSSL package, located in Git MinGW/MSYS under /mingw/bin/)
|
||||||
|
libcurl-x64.dll
|
||||||
|
libfreetype.dll
|
||||||
|
libgcc_s_seh-1.dll (located in Git MinGW/MSYS under /mingw/bin/)
|
||||||
|
libpugixml.dll
|
||||||
|
libssl-1_1-x64.dll (from the OpenSSL package, located in Git MinGW under /mingw/bin/)
|
||||||
|
libstdc++-6.dll
|
||||||
|
libvlc.dll
|
||||||
|
libvlccore.dll
|
||||||
|
libwinpthread-1.dll (located in Git MinGW under /mingw/bin/)
|
||||||
|
SDL2.dll
|
||||||
|
libSDL2main.a
|
||||||
|
```
|
||||||
|
|
||||||
|
The files from the MinGW installation must correspond to the version used to compile the binary.
|
||||||
|
|
||||||
|
*So if the MinGW installation is upgraded to a newer version or so, make sure to copy the .dll files again, overwriting the old ones.*
|
||||||
|
|
||||||
|
**Building the application:**
|
||||||
|
|
||||||
|
For a release build:
|
||||||
|
|
||||||
|
cmake -G "MinGW Makefiles" -DWIN32_INCLUDE_DIR=../include .
|
||||||
|
|
||||||
|
Or for a debug build:
|
||||||
|
|
||||||
|
cmake -G "MinGW Makefiles" -DWIN32_INCLUDE_DIR=../include -DCMAKE_BUILD_TYPE=Debug .
|
||||||
|
|
||||||
|
For some reason defining the '../include' path doesn't work when running CMake from PowerShell (and no, changing to backslash doesn't help). Instead use Bash, by running from a `Git Bash` shell.
|
||||||
|
|
||||||
|
The make command works fine directly in PowerShell though so it can be run from the VSCode terminal.
|
||||||
|
|
||||||
|
Running `make -j6` (or whatever number of parallel jobs you prefer) should now build the binary.
|
||||||
|
|
||||||
|
Note that compilation time is much longer than on Unix, and linking time is excessive for a debug build. The debug binary is also much larger than on Unix.
|
||||||
|
|
||||||
|
A worthwhile endeavour could be to setup a cross-compilation environment using WLS/WLS2 (Linux), but I have not tried it.
|
||||||
|
|
||||||
|
|
||||||
Configuring
|
|
||||||
===========
|
Configuring EmulationStation-DE
|
||||||
|
===============================
|
||||||
|
|
||||||
|
|
||||||
**~/.emulationstation/es_systems.cfg:**
|
**~/.emulationstation/es_systems.cfg:**
|
||||||
|
@ -320,7 +472,9 @@ Here's an overview of the file layout:
|
||||||
<extension>.smc .SMC .sfc .SFC .swc .SWC .fig .FIG .bs .BS .bin .BIN .mgd .MGD .7z .7Z .zip .ZIP</extension>
|
<extension>.smc .SMC .sfc .SFC .swc .SWC .fig .FIG .bs .BS .bin .BIN .mgd .MGD .7z .7Z .zip .ZIP</extension>
|
||||||
|
|
||||||
<!-- The command executed when a game is launched. A few special variables are replaced if found in a command, like %ROM% (see below).
|
<!-- The command executed when a game is launched. A few special variables are replaced if found in a command, like %ROM% (see below).
|
||||||
This example would run RetroArch with the the snes9x_libretro core. -->
|
This example would run RetroArch with the the snes9x_libretro core.
|
||||||
|
If there are spaces in the path or file name, you must enclose them in quotation marks, for example:
|
||||||
|
retroarch -L "~/my configs/retroarch/cores/snes9x_libretro.so" %ROM% -->
|
||||||
<command>retroarch -L ~/.config/retroarch/cores/snes9x_libretro.so %ROM%</command>
|
<command>retroarch -L ~/.config/retroarch/cores/snes9x_libretro.so %ROM%</command>
|
||||||
|
|
||||||
<!-- The platform(s) to use when scraping. You can see the full list of accepted platforms in src/PlatformIds.cpp.
|
<!-- The platform(s) to use when scraping. You can see the full list of accepted platforms in src/PlatformIds.cpp.
|
||||||
|
|
|
@ -102,7 +102,7 @@ set(ES_SOURCES
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
# Define OS specific sources and headers.
|
# Define OS specific sources and headers.
|
||||||
if(MSVC)
|
if(WIN32)
|
||||||
LIST(APPEND ES_SOURCES
|
LIST(APPEND ES_SOURCES
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/EmulationStation.rc
|
${CMAKE_CURRENT_SOURCE_DIR}/src/EmulationStation.rc
|
||||||
)
|
)
|
||||||
|
@ -114,18 +114,6 @@ include_directories(${COMMON_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
||||||
add_executable(emulationstation ${ES_SOURCES} ${ES_HEADERS})
|
add_executable(emulationstation ${ES_SOURCES} ${ES_HEADERS})
|
||||||
target_link_libraries(emulationstation ${COMMON_LIBRARIES} es-core)
|
target_link_libraries(emulationstation ${COMMON_LIBRARIES} es-core)
|
||||||
|
|
||||||
# Special properties for Windows builds.
|
|
||||||
if(MSVC)
|
|
||||||
# Always compile with the "WINDOWS" subsystem to avoid console window flashing at startup
|
|
||||||
# when --debug is not set (see es-core/src/main.cpp for explanation).
|
|
||||||
# The console will still be shown if launched with --debug.
|
|
||||||
# Note that up to CMake 2.8.10 this feature is broken: http://public.kitware.com/Bug/view.php?id=12566
|
|
||||||
set_target_properties(emulationstation PROPERTIES LINK_FLAGS_DEBUG "/SUBSYSTEM:WINDOWS")
|
|
||||||
set_target_properties(emulationstation PROPERTIES LINK_FLAGS_RELWITHDEBINFO "/SUBSYSTEM:WINDOWS")
|
|
||||||
set_target_properties(emulationstation PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS")
|
|
||||||
set_target_properties(emulationstation PROPERTIES LINK_FLAGS_MINSIZEREL "/SUBSYSTEM:WINDOWS")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
# Set up CPack install for `make install`.
|
# Set up CPack install for `make install`.
|
||||||
|
|
||||||
|
|
|
@ -436,7 +436,11 @@ void FileData::launchGame(Window* window)
|
||||||
AudioManager::getInstance()->deinit();
|
AudioManager::getInstance()->deinit();
|
||||||
VolumeControl::getInstance()->deinit();
|
VolumeControl::getInstance()->deinit();
|
||||||
|
|
||||||
// window->deinit();
|
// TEMPORARY - Windows does not like it at all if you launch a game without
|
||||||
|
// first doing a deinit(). Need to fix this properly at a later date.
|
||||||
|
#ifdef _WIN64
|
||||||
|
window->deinit();
|
||||||
|
#endif
|
||||||
|
|
||||||
std::string command = "";
|
std::string command = "";
|
||||||
|
|
||||||
|
@ -448,9 +452,9 @@ void FileData::launchGame(Window* window)
|
||||||
else
|
else
|
||||||
command = mEnvData->mLaunchCommand;
|
command = mEnvData->mLaunchCommand;
|
||||||
|
|
||||||
const std::string rom = Utils::FileSystem::getEscapedPath(getPath());
|
const std::string rom = Utils::FileSystem::getEscapedPath(getPath());
|
||||||
const std::string basename = Utils::FileSystem::getStem(getPath());
|
const std::string basename = Utils::FileSystem::getStem(getPath());
|
||||||
const std::string rom_raw = Utils::FileSystem::getPreferredPath(getPath());
|
const std::string rom_raw = Utils::FileSystem::getPreferredPath(getPath());
|
||||||
|
|
||||||
command = Utils::String::replace(command, "%ROM%", rom);
|
command = Utils::String::replace(command, "%ROM%", rom);
|
||||||
command = Utils::String::replace(command, "%BASENAME%", basename);
|
command = Utils::String::replace(command, "%BASENAME%", basename);
|
||||||
|
@ -467,7 +471,11 @@ void FileData::launchGame(Window* window)
|
||||||
|
|
||||||
Scripting::fireEvent("game-end");
|
Scripting::fireEvent("game-end");
|
||||||
|
|
||||||
// window->init();
|
// TEMPORARY - Windows does not like it at all if you launch a game without
|
||||||
|
// first doing a deinit(). Need to fix this properly at a later date.
|
||||||
|
#ifdef _WIN64
|
||||||
|
window->init();
|
||||||
|
#endif
|
||||||
|
|
||||||
VolumeControl::getInstance()->init();
|
VolumeControl::getInstance()->init();
|
||||||
window->normalizeNextUpdate();
|
window->normalizeNextUpdate();
|
||||||
|
|
|
@ -20,11 +20,9 @@
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
#include "ThemeData.h"
|
#include "ThemeData.h"
|
||||||
#include "views/UIModeController.h"
|
#include "views/UIModeController.h"
|
||||||
|
|
||||||
#include <pugixml.hpp>
|
#include <pugixml.hpp>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#ifdef WIN32
|
|
||||||
#include <Windows.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
std::vector<SystemData*> SystemData::sSystemVector;
|
std::vector<SystemData*> SystemData::sSystemVector;
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,14 @@
|
||||||
#include "PowerSaver.h"
|
#include "PowerSaver.h"
|
||||||
#include "Sound.h"
|
#include "Sound.h"
|
||||||
#include "SystemData.h"
|
#include "SystemData.h"
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
#include <cstring>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define FADE_TIME 300
|
#define FADE_TIME 300
|
||||||
|
|
||||||
SystemScreenSaver::SystemScreenSaver(
|
SystemScreenSaver::SystemScreenSaver(
|
||||||
|
|
|
@ -9,7 +9,8 @@
|
||||||
#include "math/Misc.h"
|
#include "math/Misc.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
#ifdef WIN32
|
|
||||||
|
#ifdef _WIN64
|
||||||
#include <mmdeviceapi.h>
|
#include <mmdeviceapi.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -34,7 +35,7 @@ VolumeControl::VolumeControl()
|
||||||
mixerHandle(nullptr),
|
mixerHandle(nullptr),
|
||||||
mixerElem(nullptr),
|
mixerElem(nullptr),
|
||||||
mixerSelemId(nullptr)
|
mixerSelemId(nullptr)
|
||||||
#elif defined(WIN32) || defined(_WIN32)
|
#elif defined(_WIN64)
|
||||||
, mixerHandle(nullptr),
|
, mixerHandle(nullptr),
|
||||||
endpointVolume(nullptr)
|
endpointVolume(nullptr)
|
||||||
#endif
|
#endif
|
||||||
|
@ -56,7 +57,7 @@ VolumeControl::VolumeControl(
|
||||||
mixerHandle(nullptr),
|
mixerHandle(nullptr),
|
||||||
mixerElem(nullptr),
|
mixerElem(nullptr),
|
||||||
mixerSelemId(nullptr)
|
mixerSelemId(nullptr)
|
||||||
#elif defined(WIN32) || defined(_WIN32)
|
#elif defined(_WIN64)
|
||||||
, mixerHandle(nullptr),
|
, mixerHandle(nullptr),
|
||||||
endpointVolume(nullptr)
|
endpointVolume(nullptr)
|
||||||
#endif
|
#endif
|
||||||
|
@ -156,7 +157,7 @@ void VolumeControl::init()
|
||||||
LOG(LogError) << "VolumeControl::init() - Failed to open ALSA mixer!";
|
LOG(LogError) << "VolumeControl::init() - Failed to open ALSA mixer!";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#elif defined(WIN32) || defined(_WIN32)
|
#elif defined(_WIN64)
|
||||||
// Get windows version information.
|
// Get windows version information.
|
||||||
OSVERSIONINFOEXA osVer = {sizeof(OSVERSIONINFO)};
|
OSVERSIONINFOEXA osVer = {sizeof(OSVERSIONINFO)};
|
||||||
::GetVersionExA(reinterpret_cast<LPOSVERSIONINFOA>(&osVer));
|
::GetVersionExA(reinterpret_cast<LPOSVERSIONINFOA>(&osVer));
|
||||||
|
@ -164,7 +165,11 @@ void VolumeControl::init()
|
||||||
if (osVer.dwMajorVersion < 6) {
|
if (osVer.dwMajorVersion < 6) {
|
||||||
// Windows older than Vista. use mixer API. open default mixer.
|
// Windows older than Vista. use mixer API. open default mixer.
|
||||||
if (mixerHandle == nullptr) {
|
if (mixerHandle == nullptr) {
|
||||||
|
#if defined(_WIN64)
|
||||||
|
if (mixerOpen(&mixerHandle, 0, (DWORD_PTR)nullptr, 0, 0) == MMSYSERR_NOERROR) {
|
||||||
|
#else
|
||||||
if (mixerOpen(&mixerHandle, 0, nullptr, 0, 0) == MMSYSERR_NOERROR) {
|
if (mixerOpen(&mixerHandle, 0, nullptr, 0, 0) == MMSYSERR_NOERROR) {
|
||||||
|
#endif
|
||||||
// Retrieve info on the volume slider control for the "Speaker Out" line.
|
// Retrieve info on the volume slider control for the "Speaker Out" line.
|
||||||
MIXERLINECONTROLS mixerLineControls;
|
MIXERLINECONTROLS mixerLineControls;
|
||||||
mixerLineControls.cbStruct = sizeof(MIXERLINECONTROLS);
|
mixerLineControls.cbStruct = sizeof(MIXERLINECONTROLS);
|
||||||
|
@ -239,7 +244,7 @@ void VolumeControl::deinit()
|
||||||
mixerHandle = nullptr;
|
mixerHandle = nullptr;
|
||||||
mixerElem = nullptr;
|
mixerElem = nullptr;
|
||||||
}
|
}
|
||||||
#elif defined(WIN32) || defined(_WIN32)
|
#elif defined(_WIN64)
|
||||||
if (mixerHandle != nullptr) {
|
if (mixerHandle != nullptr) {
|
||||||
mixerClose(mixerHandle);
|
mixerClose(mixerHandle);
|
||||||
mixerHandle = nullptr;
|
mixerHandle = nullptr;
|
||||||
|
@ -283,7 +288,7 @@ int VolumeControl::getVolume() const
|
||||||
LOG(LogError) << "VolumeControl::getVolume() - Failed to get volume range!";
|
LOG(LogError) << "VolumeControl::getVolume() - Failed to get volume range!";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#elif defined(WIN32) || defined(_WIN32)
|
#elif defined(_WIN64)
|
||||||
if (mixerHandle != nullptr) {
|
if (mixerHandle != nullptr) {
|
||||||
// Windows older than Vista. use mixer API. get volume from line control.
|
// Windows older than Vista. use mixer API. get volume from line control.
|
||||||
MIXERCONTROLDETAILS_UNSIGNED value;
|
MIXERCONTROLDETAILS_UNSIGNED value;
|
||||||
|
@ -355,7 +360,7 @@ void VolumeControl::setVolume(int volume)
|
||||||
LOG(LogError) << "VolumeControl::getVolume() - Failed to get volume range!";
|
LOG(LogError) << "VolumeControl::getVolume() - Failed to get volume range!";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#elif defined(WIN32) || defined(_WIN32)
|
#elif defined(_WIN64)
|
||||||
if (mixerHandle != nullptr) {
|
if (mixerHandle != nullptr) {
|
||||||
// Windows older than Vista. use mixer API. get volume from line control.
|
// Windows older than Vista. use mixer API. get volume from line control.
|
||||||
MIXERCONTROLDETAILS_UNSIGNED value;
|
MIXERCONTROLDETAILS_UNSIGNED value;
|
||||||
|
|
|
@ -16,10 +16,10 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <alsa/asoundlib.h>
|
#include <alsa/asoundlib.h>
|
||||||
#elif defined(WIN32) || defined(_WIN32)
|
#elif defined(_WIN64)
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <endpointvolume.h>
|
#include <endpointvolume.h>
|
||||||
#include <mmeapi.h>
|
//#include <mmeapi.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Singleton pattern. Call getInstance() to get an object.
|
// Singleton pattern. Call getInstance() to get an object.
|
||||||
|
@ -34,7 +34,7 @@ class VolumeControl
|
||||||
snd_mixer_t* mixerHandle;
|
snd_mixer_t* mixerHandle;
|
||||||
snd_mixer_elem_t* mixerElem;
|
snd_mixer_elem_t* mixerElem;
|
||||||
snd_mixer_selem_id_t* mixerSelemId;
|
snd_mixer_selem_id_t* mixerSelemId;
|
||||||
#elif defined(WIN32) || defined(_WIN32)
|
#elif defined(_WIN64)
|
||||||
HMIXER mixerHandle;
|
HMIXER mixerHandle;
|
||||||
MIXERCONTROL mixerControl;
|
MIXERCONTROL mixerControl;
|
||||||
IAudioEndpointVolume * endpointVolume;
|
IAudioEndpointVolume * endpointVolume;
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "components/NinePatchComponent.h"
|
#include "components/NinePatchComponent.h"
|
||||||
#include "components/TextComponent.h"
|
#include "components/TextComponent.h"
|
||||||
|
|
||||||
#ifdef __linux__
|
#if defined(__linux__) || defined(_WIN64)
|
||||||
#include <SDL2/SDL_timer.h>
|
#include <SDL2/SDL_timer.h>
|
||||||
#else
|
#else
|
||||||
#include "SDL_timer.h"
|
#include "SDL_timer.h"
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#ifdef __linux__
|
#if defined(__linux__) || defined(_WIN64)
|
||||||
#include <SDL2/SDL_events.h>
|
#include <SDL2/SDL_events.h>
|
||||||
#else
|
#else
|
||||||
#include "SDL_events.h"
|
#include "SDL_events.h"
|
||||||
|
|
|
@ -31,7 +31,12 @@
|
||||||
#include "SystemData.h"
|
#include "SystemData.h"
|
||||||
#include "SystemScreenSaver.h"
|
#include "SystemScreenSaver.h"
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef _WIN64
|
||||||
|
#include <cstring>
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__linux__) || defined(_WIN64)
|
||||||
#include <SDL2/SDL_events.h>
|
#include <SDL2/SDL_events.h>
|
||||||
#include <SDL2/SDL_main.h>
|
#include <SDL2/SDL_main.h>
|
||||||
#include <SDL2/SDL_timer.h>
|
#include <SDL2/SDL_timer.h>
|
||||||
|
@ -44,9 +49,6 @@
|
||||||
#include <FreeImage.h>
|
#include <FreeImage.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#ifdef WIN32
|
|
||||||
#include <Windows.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum eErrorCodes {
|
enum eErrorCodes {
|
||||||
NO_ERRORS,
|
NO_ERRORS,
|
||||||
|
@ -54,10 +56,96 @@ enum eErrorCodes {
|
||||||
NO_ROMS
|
NO_ROMS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
enum eConsoleType {
|
||||||
|
NO_CONSOLE,
|
||||||
|
PARENT_CONSOLE,
|
||||||
|
ALLOCATED_CONSOLE
|
||||||
|
};
|
||||||
|
|
||||||
|
// Console output for Windows. The handling of consoles is a mess on this operating system,
|
||||||
|
// and this is the best solution I could find. EmulationStation is built using the WINDOWS
|
||||||
|
// subsystem (using the -mwindows compiler flag). The idea is to attach to or allocate a new
|
||||||
|
// console as needed. However some console types such as the 'Git Bash' shell simply doesn't
|
||||||
|
// work properly. Windows thinks it's attaching to a console but is unable to redirect the
|
||||||
|
// standard input and output. Output also can't be redirected or piped by the user for any
|
||||||
|
// console type and PowerShell behaves quite strange. Still, it works well enough to be
|
||||||
|
// somewhat usable, at least for the moment. If the allocConsole argument is set to true
|
||||||
|
// and there is no console available, a new console window will be spawned.
|
||||||
|
eConsoleType outputToConsole(bool allocConsole)
|
||||||
|
{
|
||||||
|
HANDLE outputHandle = nullptr;
|
||||||
|
HWND consoleWindow = nullptr;
|
||||||
|
eConsoleType ConsoleType = NO_CONSOLE;
|
||||||
|
|
||||||
|
// Try to attach to a parent console process.
|
||||||
|
if (AttachConsole(ATTACH_PARENT_PROCESS))
|
||||||
|
outputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
|
||||||
|
// If there is a parent console process, then attempt to retrieve its handle.
|
||||||
|
if (outputHandle != INVALID_HANDLE_VALUE && outputHandle != nullptr) {
|
||||||
|
consoleWindow = GetConsoleWindow();
|
||||||
|
ConsoleType = PARENT_CONSOLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we couldn't retrieve the handle, it means we need to allocate a new console window.
|
||||||
|
if (!consoleWindow && allocConsole) {
|
||||||
|
AllocConsole();
|
||||||
|
ConsoleType = ALLOCATED_CONSOLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we are attached to the parent console or we have opened a new console window,
|
||||||
|
// then redirect stdin, stdout and stderr accordingly.
|
||||||
|
if (ConsoleType == PARENT_CONSOLE || ConsoleType == ALLOCATED_CONSOLE) {
|
||||||
|
|
||||||
|
FILE* fp = nullptr;
|
||||||
|
freopen_s(&fp, "CONIN$", "rb", stdin);
|
||||||
|
freopen_s(&fp, "CONOUT$", "wb", stdout);
|
||||||
|
setvbuf(stdout, NULL, _IONBF, 0);
|
||||||
|
freopen_s(&fp, "CONOUT$", "wb", stderr);
|
||||||
|
setvbuf(stderr, NULL, _IONBF, 0);
|
||||||
|
|
||||||
|
// Point the standard streams to the console.
|
||||||
|
std::ios::sync_with_stdio(true);
|
||||||
|
|
||||||
|
// Clear the error state for each standard stream.
|
||||||
|
std::wcout.clear();
|
||||||
|
std::cout.clear();
|
||||||
|
std::wcerr.clear();
|
||||||
|
std::cerr.clear();
|
||||||
|
std::wcin.clear();
|
||||||
|
std::cin.clear();
|
||||||
|
|
||||||
|
std::cout << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return ConsoleType;
|
||||||
|
}
|
||||||
|
|
||||||
|
void closeConsole()
|
||||||
|
{
|
||||||
|
FILE* fp;
|
||||||
|
|
||||||
|
// Redirect stdin, stdout and stderr to NUL.
|
||||||
|
freopen_s(&fp, "NUL:", "r", stdin);
|
||||||
|
freopen_s(&fp, "NUL:", "w", stdout);
|
||||||
|
freopen_s(&fp, "NUL:", "w", stderr);
|
||||||
|
|
||||||
|
FreeConsole();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool parseArgs(int argc, char* argv[])
|
bool parseArgs(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
Utils::FileSystem::setExePath(argv[0]);
|
Utils::FileSystem::setExePath(argv[0]);
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
// Print any command line output to the console.
|
||||||
|
if (argc > 1)
|
||||||
|
eConsoleType ConsoleType = outputToConsole(false);
|
||||||
|
#endif
|
||||||
|
|
||||||
// We need to process --home before any call to Settings::getInstance(),
|
// We need to process --home before any call to Settings::getInstance(),
|
||||||
// because settings are loaded from the home path.
|
// because settings are loaded from the home path.
|
||||||
for (int i = 1; i < argc; i++) {
|
for (int i = 1; i < argc; i++) {
|
||||||
|
@ -161,7 +249,6 @@ bool parseArgs(int argc, char* argv[])
|
||||||
}
|
}
|
||||||
else if (strcmp(argv[i], "--debug") == 0) {
|
else if (strcmp(argv[i], "--debug") == 0) {
|
||||||
Settings::getInstance()->setBool("Debug", true);
|
Settings::getInstance()->setBool("Debug", true);
|
||||||
Settings::getInstance()->setBool("HideConsole", false);
|
|
||||||
Log::setReportingLevel(LogDebug);
|
Log::setReportingLevel(LogDebug);
|
||||||
}
|
}
|
||||||
else if (strcmp(argv[i], "--fullscreen-normal") == 0) {
|
else if (strcmp(argv[i], "--fullscreen-normal") == 0) {
|
||||||
|
@ -194,14 +281,6 @@ bool parseArgs(int argc, char* argv[])
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
|
else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
|
||||||
#ifdef WIN32
|
|
||||||
// This is a bit of a hack, but otherwise output will go to nowhere when the
|
|
||||||
// application is compiled with the "WINDOWS" subsystem (which we usually are).
|
|
||||||
// If you're an experienced Windows programmer and know how to do this
|
|
||||||
// the right way, please submit a pull request!
|
|
||||||
AttachConsole(ATTACH_PARENT_PROCESS);
|
|
||||||
freopen("CONOUT$", "wb", stdout);
|
|
||||||
#endif
|
|
||||||
std::cout <<
|
std::cout <<
|
||||||
"EmulationStation Desktop Edition\n"
|
"EmulationStation Desktop Edition\n"
|
||||||
"An Emulator Front-end\n\n"
|
"An Emulator Front-end\n\n"
|
||||||
|
@ -212,11 +291,7 @@ bool parseArgs(int argc, char* argv[])
|
||||||
"--draw-framerate Display the framerate\n"
|
"--draw-framerate Display the framerate\n"
|
||||||
"--no-exit Don't show the exit option in the menu\n"
|
"--no-exit Don't show the exit option in the menu\n"
|
||||||
"--no-splash Don't show the splash screen\n"
|
"--no-splash Don't show the splash screen\n"
|
||||||
#ifdef WIN32
|
|
||||||
"--debug Show console and print debug information\n"
|
|
||||||
#else
|
|
||||||
"--debug Print debug information\n"
|
"--debug Print debug information\n"
|
||||||
#endif
|
|
||||||
"--windowed Windowed mode, should be combined with --resolution\n"
|
"--windowed Windowed mode, should be combined with --resolution\n"
|
||||||
"--fullscreen-normal Normal fullscreen mode\n"
|
"--fullscreen-normal Normal fullscreen mode\n"
|
||||||
"--fullscreen-borderless Borderless fullscreen mode (always on top)\n"
|
"--fullscreen-borderless Borderless fullscreen mode (always on top)\n"
|
||||||
|
@ -300,45 +375,23 @@ int main(int argc, char* argv[])
|
||||||
|
|
||||||
std::locale::global(std::locale("C"));
|
std::locale::global(std::locale("C"));
|
||||||
|
|
||||||
if (!parseArgs(argc, argv))
|
if (!parseArgs(argc, argv)) {
|
||||||
|
#ifdef _WIN64
|
||||||
|
closeConsole();
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Only show the console on Windows if HideConsole is false.
|
#ifdef _WIN64
|
||||||
#ifdef WIN32
|
// Send debug output to the console..
|
||||||
// MSVC has a "SubSystem" option, with two primary options: "WINDOWS" and "CONSOLE".
|
if (Settings::getInstance()->getBool("Debug"))
|
||||||
// In "WINDOWS" mode, no console is automatically created for us. This is good,
|
outputToConsole(true);
|
||||||
// because we can choose to only create the console window if the user explicitly
|
#endif
|
||||||
// asks for it, preventing it from flashing open and then closing.
|
|
||||||
// In "CONSOLE" mode, a console is always automatically created for us before we
|
|
||||||
// enter main. In this case, we can only hide the console after the fact, which
|
|
||||||
// will leave a brief flash.
|
|
||||||
// TL;DR: You should compile ES under the "WINDOWS" subsystem.
|
|
||||||
// I have no idea how this works with non-MSVC compilers.
|
|
||||||
if (!Settings::getInstance()->getBool("HideConsole")) {
|
|
||||||
// We want to show the console.
|
|
||||||
// If we're compiled in "CONSOLE" mode, this is already done.
|
|
||||||
// If we're compiled in "WINDOWS" mode, no console is created for us automatically;
|
|
||||||
// the user asked for one, so make one and then hook stdin/stdout/sterr up to it.
|
|
||||||
if (AllocConsole()) { // Should only pass in "WINDOWS" mode.
|
|
||||||
freopen("CONIN$", "r", stdin);
|
|
||||||
freopen("CONOUT$", "wb", stdout);
|
|
||||||
freopen("CONOUT$", "wb", stderr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// We want to hide the console.
|
|
||||||
// If we're compiled with the "WINDOWS" subsystem, this is already done.
|
|
||||||
// If we're compiled with the "CONSOLE" subsystem, a console is already created;
|
|
||||||
// it'll flash open, but we hide it nearly immediately.
|
|
||||||
if (GetConsoleWindow()) // Should only pass in "CONSOLE" mode.
|
|
||||||
ShowWindow(GetConsoleWindow(), SW_HIDE);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Call this ONLY when linking with FreeImage as a static library.
|
// Call this ONLY when linking with FreeImage as a static library.
|
||||||
#ifdef FREEIMAGE_LIB
|
#ifdef FREEIMAGE_LIB
|
||||||
FreeImage_Initialise();
|
FreeImage_Initialise();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// If ~/.emulationstation doesn't exist and cannot be created, bail.
|
// If ~/.emulationstation doesn't exist and cannot be created, bail.
|
||||||
if (!verifyHomeFolderExists())
|
if (!verifyHomeFolderExists())
|
||||||
|
@ -500,13 +553,17 @@ int main(int argc, char* argv[])
|
||||||
SystemData::deleteSystems();
|
SystemData::deleteSystems();
|
||||||
|
|
||||||
// Call this ONLY when linking with FreeImage as a static library.
|
// Call this ONLY when linking with FreeImage as a static library.
|
||||||
#ifdef FREEIMAGE_LIB
|
#ifdef FREEIMAGE_LIB
|
||||||
FreeImage_DeInitialise();
|
FreeImage_DeInitialise();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
processQuitMode();
|
processQuitMode();
|
||||||
|
|
||||||
LOG(LogInfo) << "EmulationStation cleanly shutting down.";
|
LOG(LogInfo) << "EmulationStation cleanly shutting down.";
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
closeConsole();
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,8 +162,7 @@ void screenscraper_generate_scraper_requests(const ScraperSearchParams& params,
|
||||||
auto last = std::unique(p_ids.begin(), p_ids.end());
|
auto last = std::unique(p_ids.begin(), p_ids.end());
|
||||||
p_ids.erase(last, p_ids.end());
|
p_ids.erase(last, p_ids.end());
|
||||||
|
|
||||||
for (auto platform = p_ids.cbegin(); platform != p_ids.cend(); platform++)
|
for (auto platform = p_ids.cbegin(); platform != p_ids.cend(); platform++) {
|
||||||
{
|
|
||||||
path += "&systemeid=";
|
path += "&systemeid=";
|
||||||
path += HttpReq::urlEncode(std::to_string(*platform));
|
path += HttpReq::urlEncode(std::to_string(*platform));
|
||||||
requests.push(std::unique_ptr<ScraperRequest>
|
requests.push(std::unique_ptr<ScraperRequest>
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
#include "Sound.h"
|
#include "Sound.h"
|
||||||
|
|
||||||
#ifdef __linux__
|
#if defined(__linux__) || defined(_WIN64)
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#else
|
#else
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#ifndef ES_CORE_AUDIO_MANAGER_H
|
#ifndef ES_CORE_AUDIO_MANAGER_H
|
||||||
#define ES_CORE_AUDIO_MANAGER_H
|
#define ES_CORE_AUDIO_MANAGER_H
|
||||||
|
|
||||||
#ifdef __linux__
|
#if defined(__linux__) || defined (_WIN64)
|
||||||
#include <SDL2/SDL_audio.h>
|
#include <SDL2/SDL_audio.h>
|
||||||
#else
|
#else
|
||||||
#include "SDL_audio.h"
|
#include "SDL_audio.h"
|
||||||
|
|
|
@ -8,8 +8,10 @@
|
||||||
|
|
||||||
#include "HttpReq.h"
|
#include "HttpReq.h"
|
||||||
|
|
||||||
|
#include "resources/ResourceManager.h"
|
||||||
#include "utils/FileSystemUtil.h"
|
#include "utils/FileSystemUtil.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
CURLM* HttpReq::s_multi_handle = curl_multi_init();
|
CURLM* HttpReq::s_multi_handle = curl_multi_init();
|
||||||
|
@ -48,6 +50,15 @@ HttpReq::HttpReq(const std::string& url) : mStatus(REQ_IN_PROGRESS), mHandle(nul
|
||||||
{
|
{
|
||||||
mHandle = curl_easy_init();
|
mHandle = curl_easy_init();
|
||||||
|
|
||||||
|
// On Windows, use the bundled cURL TLS/SSL certificates (which actually come from the
|
||||||
|
// Mozilla project). There is a possibility to use the OS provided Schannel certificates
|
||||||
|
// but I haven't been able to get this to work and it also seems to be problematic on
|
||||||
|
// older Windows versions.
|
||||||
|
#ifdef _WIN64
|
||||||
|
curl_easy_setopt(mHandle, CURLOPT_CAINFO, ResourceManager::getInstance()->
|
||||||
|
getResourcePath(":/certificates/curl-ca-bundle.crt").c_str());
|
||||||
|
#endif
|
||||||
|
|
||||||
if (mHandle == nullptr) {
|
if (mHandle == nullptr) {
|
||||||
mStatus = REQ_IO_ERROR;
|
mStatus = REQ_IO_ERROR;
|
||||||
onError("curl_easy_init failed");
|
onError("curl_easy_init failed");
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#ifdef __linux__
|
#if defined(__linux__) || defined(_WIN64)
|
||||||
#include <SDL2/SDL_joystick.h>
|
#include <SDL2/SDL_joystick.h>
|
||||||
#include <SDL2/SDL_keyboard.h>
|
#include <SDL2/SDL_keyboard.h>
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#include "Scripting.h"
|
#include "Scripting.h"
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
|
|
||||||
#ifdef __linux__
|
#if defined(__linux__) || defined(_WIN64)
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#else
|
#else
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#ifndef ES_CORE_INPUT_MANAGER_H
|
#ifndef ES_CORE_INPUT_MANAGER_H
|
||||||
#define ES_CORE_INPUT_MANAGER_H
|
#define ES_CORE_INPUT_MANAGER_H
|
||||||
|
|
||||||
#ifdef __linux__
|
#if defined(__linux__) || defined(_WIN64)
|
||||||
#include <SDL2/SDL_joystick.h>
|
#include <SDL2/SDL_joystick.h>
|
||||||
#else
|
#else
|
||||||
#include "SDL_joystick.h"
|
#include "SDL_joystick.h"
|
||||||
|
|
|
@ -6,14 +6,15 @@
|
||||||
|
|
||||||
#include "Platform.h"
|
#include "Platform.h"
|
||||||
|
|
||||||
#ifdef __linux__
|
#if defined(__linux__) || defined(_WIN64)
|
||||||
#include <SDL2/SDL_events.h>
|
#include <SDL2/SDL_events.h>
|
||||||
#else
|
#else
|
||||||
#include "SDL_events.h"
|
#include "SDL_events.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef _WIN64
|
||||||
#include <codecvt>
|
#include <codecvt>
|
||||||
|
#include <locale>
|
||||||
#else
|
#else
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -23,7 +24,7 @@
|
||||||
|
|
||||||
int runRebootCommand()
|
int runRebootCommand()
|
||||||
{
|
{
|
||||||
#ifdef WIN32 // Windows.
|
#ifdef _WIN64 // Windows.
|
||||||
return system("shutdown -r -t 0");
|
return system("shutdown -r -t 0");
|
||||||
#else // macOS and Linux.
|
#else // macOS and Linux.
|
||||||
return system("shutdown --reboot now");
|
return system("shutdown --reboot now");
|
||||||
|
@ -32,7 +33,7 @@ int runRebootCommand()
|
||||||
|
|
||||||
int runPoweroffCommand()
|
int runPoweroffCommand()
|
||||||
{
|
{
|
||||||
#ifdef WIN32 // Windows.
|
#ifdef _WIN64 // Windows.
|
||||||
return system("shutdown -s -t 0");
|
return system("shutdown -s -t 0");
|
||||||
#else // macOS and Linux.
|
#else // macOS and Linux.
|
||||||
return system("shutdown --poweroff now");
|
return system("shutdown --poweroff now");
|
||||||
|
@ -41,7 +42,7 @@ int runPoweroffCommand()
|
||||||
|
|
||||||
int runSystemCommand(const std::string& cmd_utf8)
|
int runSystemCommand(const std::string& cmd_utf8)
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef _WIN64
|
||||||
// On Windows we use _wsystem to support non-ASCII paths
|
// On Windows we use _wsystem to support non-ASCII paths
|
||||||
// which requires converting from UTF8 to a wstring.
|
// which requires converting from UTF8 to a wstring.
|
||||||
typedef std::codecvt_utf8<wchar_t> convert_type;
|
typedef std::codecvt_utf8<wchar_t> convert_type;
|
||||||
|
@ -67,7 +68,7 @@ int quitES(QuitMode mode)
|
||||||
|
|
||||||
void touch(const std::string& filename)
|
void touch(const std::string& filename)
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef _WIN64
|
||||||
FILE* fp = fopen(filename.c_str(), "ab+");
|
FILE* fp = fopen(filename.c_str(), "ab+");
|
||||||
if (fp != nullptr)
|
if (fp != nullptr)
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
// Why the hell this naming inconsistency exists is well beyond me.
|
// Why the hell this naming inconsistency exists is well beyond me.
|
||||||
#ifdef WIN32
|
#ifdef _WIN64
|
||||||
#define sleep Sleep
|
#define sleep Sleep
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,6 @@ Settings* Settings::sInstance = nullptr;
|
||||||
std::vector<const char*> settings_dont_save {
|
std::vector<const char*> settings_dont_save {
|
||||||
// These options can be set using command-line arguments:
|
// These options can be set using command-line arguments:
|
||||||
"Debug", // --debug
|
"Debug", // --debug
|
||||||
"HideConsole", // Implicitly set via the --debug flag.
|
|
||||||
"ForceKid", // --force-kid
|
"ForceKid", // --force-kid
|
||||||
"ForceKiosk", // --force-kiosk
|
"ForceKiosk", // --force-kiosk
|
||||||
"IgnoreGamelist", // --ignore-gamelist
|
"IgnoreGamelist", // --ignore-gamelist
|
||||||
|
@ -185,7 +184,6 @@ void Settings::setDefaults()
|
||||||
|
|
||||||
// Options listed using --help
|
// Options listed using --help
|
||||||
mBoolMap["Debug"] = false;
|
mBoolMap["Debug"] = false;
|
||||||
mBoolMap["HideConsole"] = true; // Implicitly set via the --debug flag.
|
|
||||||
mBoolMap["ForceKid"] = false;
|
mBoolMap["ForceKid"] = false;
|
||||||
mBoolMap["ForceKiosk"] = false;
|
mBoolMap["ForceKiosk"] = false;
|
||||||
mBoolMap["IgnoreGamelist"] = false;
|
mBoolMap["IgnoreGamelist"] = false;
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#ifndef ES_CORE_SOUND_H
|
#ifndef ES_CORE_SOUND_H
|
||||||
#define ES_CORE_SOUND_H
|
#define ES_CORE_SOUND_H
|
||||||
|
|
||||||
#ifdef __linux__
|
#if defined(__linux__) || defined (_WIN64)
|
||||||
#include <SDL2/SDL_audio.h>
|
#include <SDL2/SDL_audio.h>
|
||||||
#else
|
#else
|
||||||
#include "SDL_audio.h"
|
#include "SDL_audio.h"
|
||||||
|
|
|
@ -593,12 +593,17 @@ std::map<std::string, ThemeSet> ThemeData::getThemeSets()
|
||||||
{
|
{
|
||||||
std::map<std::string, ThemeSet> sets;
|
std::map<std::string, ThemeSet> sets;
|
||||||
|
|
||||||
// Check for themes under the data installation directory (install prefix), as well
|
// Check for themes under the data installation directory for Unix or under the
|
||||||
// as under the user home directory.
|
// executable directory for Windows, as well as under the user home directory regardless
|
||||||
|
// of operating system.
|
||||||
static const size_t pathCount = 2;
|
static const size_t pathCount = 2;
|
||||||
std::string paths[pathCount] =
|
std::string paths[pathCount] =
|
||||||
{
|
{
|
||||||
Utils::FileSystem::getInstallPrefixPath() + "/emulationstation/themes",
|
#ifdef _WIN64
|
||||||
|
Utils::FileSystem::getExePath() + "/themes",
|
||||||
|
#else
|
||||||
|
Utils::FileSystem::getProgramDataPath() + "/themes",
|
||||||
|
#endif
|
||||||
Utils::FileSystem::getHomePath() + "/.emulationstation/themes"
|
Utils::FileSystem::getHomePath() + "/.emulationstation/themes"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include "ThemeData.h"
|
#include "ThemeData.h"
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
|
|
||||||
#ifdef __linux__
|
#if defined(__linux__) || defined(_WIN64)
|
||||||
#include <SDL2/SDL_timer.h>
|
#include <SDL2/SDL_timer.h>
|
||||||
#else
|
#else
|
||||||
#include "SDL_timer.h"
|
#include "SDL_timer.h"
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include "PowerSaver.h"
|
#include "PowerSaver.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
|
|
||||||
#ifdef __linux__
|
#if defined(__linux__) || defined(_WIN64)
|
||||||
#include <SDL2/SDL_mutex.h>
|
#include <SDL2/SDL_mutex.h>
|
||||||
#include <SDL2/SDL_timer.h>
|
#include <SDL2/SDL_timer.h>
|
||||||
#else
|
#else
|
||||||
|
@ -22,8 +22,9 @@
|
||||||
|
|
||||||
#include <vlc/vlc.h>
|
#include <vlc/vlc.h>
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef _WIN64
|
||||||
#include <codecvt>
|
#include <codecvt>
|
||||||
|
#include <cstring>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
libvlc_instance_t* VideoVlcComponent::mVLC = nullptr;
|
libvlc_instance_t* VideoVlcComponent::mVLC = nullptr;
|
||||||
|
@ -243,7 +244,7 @@ void VideoVlcComponent::startVideo()
|
||||||
mVideoWidth = 0;
|
mVideoWidth = 0;
|
||||||
mVideoHeight = 0;
|
mVideoHeight = 0;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef _WIN64
|
||||||
std::string path(Utils::String::replace(mVideoPath, "/", "\\"));
|
std::string path(Utils::String::replace(mVideoPath, "/", "\\"));
|
||||||
#else
|
#else
|
||||||
std::string path(mVideoPath);
|
std::string path(mVideoPath);
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
|
|
||||||
#ifdef __linux__
|
#if defined(__linux__) || defined(_WIN64)
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#else
|
#else
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
|
|
||||||
#ifdef __linux__
|
#if defined(__linux__) || defined(_WIN64)
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#include <SDL2/SDL_opengl.h>
|
#include <SDL2/SDL_opengl.h>
|
||||||
#else
|
#else
|
||||||
|
@ -29,7 +29,7 @@ namespace Renderer
|
||||||
const GLenum errorCode = glGetError();
|
const GLenum errorCode = glGetError();
|
||||||
|
|
||||||
if (errorCode != GL_NO_ERROR) {
|
if (errorCode != GL_NO_ERROR) {
|
||||||
LOG(LogError) << "OpenGLES error: " << _funcName <<
|
LOG(LogError) << "OpenGL error: " << _funcName <<
|
||||||
" failed with error code: " << errorCode;
|
" failed with error code: " << errorCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
|
|
||||||
#ifdef __linux__
|
#if defined(__linux__) || defined(_WIN64)
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#include <SDL2/SDL_opengles.h>
|
#include <SDL2/SDL_opengles.h>
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -12,10 +12,6 @@
|
||||||
#include "utils/StringUtil.h"
|
#include "utils/StringUtil.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
#include <Windows.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
FT_Library Font::sLibrary = nullptr;
|
FT_Library Font::sLibrary = nullptr;
|
||||||
|
|
||||||
int Font::getSize() const { return mSize; }
|
int Font::getSize() const { return mSize; }
|
||||||
|
@ -215,40 +211,6 @@ void Font::getTextureForNewGlyph(const Vector2i& glyphSize,
|
||||||
|
|
||||||
std::vector<std::string> getFallbackFontPaths()
|
std::vector<std::string> getFallbackFontPaths()
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
|
||||||
// Windows
|
|
||||||
|
|
||||||
// TEMPORARY, remove this and use the bundled fallback fonts instead.
|
|
||||||
|
|
||||||
// Get this system's equivalent of "C:\Windows" (might be on a different drive or
|
|
||||||
// in a different folder) so we can check the Fonts subdirectory for fallback fonts.
|
|
||||||
TCHAR winDir[MAX_PATH];
|
|
||||||
GetWindowsDirectory(winDir, MAX_PATH);
|
|
||||||
std::string fontDir = winDir;
|
|
||||||
fontDir += "\\Fonts\\";
|
|
||||||
|
|
||||||
const char* fontNames[] = {
|
|
||||||
"meiryo.ttc", // Japanese.
|
|
||||||
"simhei.ttf", // Chinese.
|
|
||||||
"arial.ttf" // Latin.
|
|
||||||
};
|
|
||||||
|
|
||||||
// Prepend to font file names.
|
|
||||||
std::vector<std::string> fontPaths;
|
|
||||||
fontPaths.reserve(sizeof(fontNames) / sizeof(fontNames[0]));
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < sizeof(fontNames) / sizeof(fontNames[0]); i++) {
|
|
||||||
std::string path = fontDir + fontNames[i];
|
|
||||||
if (ResourceManager::getInstance()->fileExists(path))
|
|
||||||
fontPaths.push_back(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
fontPaths.shrink_to_fit();
|
|
||||||
return fontPaths;
|
|
||||||
|
|
||||||
#else
|
|
||||||
// Linux.
|
|
||||||
|
|
||||||
std::vector<std::string> fontPaths;
|
std::vector<std::string> fontPaths;
|
||||||
|
|
||||||
// Vera sans Unicode:
|
// Vera sans Unicode:
|
||||||
|
@ -269,8 +231,6 @@ std::vector<std::string> getFallbackFontPaths()
|
||||||
|
|
||||||
fontPaths.shrink_to_fit();
|
fontPaths.shrink_to_fit();
|
||||||
return fontPaths;
|
return fontPaths;
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FT_Face Font::getFaceForChar(unsigned int id)
|
FT_Face Font::getFaceForChar(unsigned int id)
|
||||||
|
|
|
@ -38,11 +38,16 @@ std::string ResourceManager::getResourcePath(const std::string& path) const
|
||||||
if (Utils::FileSystem::exists(test))
|
if (Utils::FileSystem::exists(test))
|
||||||
return test;
|
return test;
|
||||||
|
|
||||||
// Check under the data installation directory (install prefix).
|
// Check for the resource under the data installation directory for Unix or under
|
||||||
test = Utils::FileSystem::getInstallPrefixPath() +
|
// the executable directory for Windows.
|
||||||
"/emulationstation/resources/" + &path[2];
|
#ifdef _WIN64
|
||||||
if (Utils::FileSystem::exists(test))
|
test = Utils::FileSystem::getExePath() + "/resources/" + &path[2];
|
||||||
return test;
|
#else
|
||||||
|
test = Utils::FileSystem::getProgramDataPath() + "/resources/" + &path[2];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (Utils::FileSystem::exists(test))
|
||||||
|
return test;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not a resource, return unmodified path.
|
// Not a resource, return unmodified path.
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#ifdef WIN32
|
#if defined(_WIN64)
|
||||||
// Because windows...
|
// Because windows...
|
||||||
#include <direct.h>
|
#include <direct.h>
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
@ -22,17 +22,17 @@
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
#define stat64 _stat64
|
#define stat64 _stat64
|
||||||
#define unlink _unlink
|
#define unlink _unlink
|
||||||
#define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
|
//#define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
|
||||||
#define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR)
|
//#define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR)
|
||||||
#else
|
#else
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Try to get the install prefix as defined when CMake was run.
|
// For Unix systems, try to get the install prefix as defined when CMake was run.
|
||||||
// The installPrefix directory is the value set for CMAKE_INSTALL_PREFIX during build.
|
// The installPrefix directory is the value set for CMAKE_INSTALL_PREFIX during build.
|
||||||
// If not defined, the default prefix path '/usr/local' will be used.
|
// If not defined, the default prefix path '/usr/local' will be used.
|
||||||
#ifdef __unix__
|
#if defined(__unix__)
|
||||||
#ifdef ES_INSTALL_PREFIX
|
#ifdef ES_INSTALL_PREFIX
|
||||||
std::string installPrefix = ES_INSTALL_PREFIX;
|
std::string installPrefix = ES_INSTALL_PREFIX;
|
||||||
#else
|
#else
|
||||||
|
@ -47,7 +47,7 @@ namespace Utils
|
||||||
static std::string homePath = "";
|
static std::string homePath = "";
|
||||||
static std::string exePath = "";
|
static std::string exePath = "";
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN64)
|
||||||
static std::string convertFromWideString(const std::wstring wstring)
|
static std::string convertFromWideString(const std::wstring wstring)
|
||||||
{
|
{
|
||||||
int numBytes = WideCharToMultiByte(CP_UTF8, 0, wstring.c_str(),
|
int numBytes = WideCharToMultiByte(CP_UTF8, 0, wstring.c_str(),
|
||||||
|
@ -70,7 +70,7 @@ namespace Utils
|
||||||
// Only parse the directory, if it's a directory.
|
// Only parse the directory, if it's a directory.
|
||||||
if (isDirectory(path)) {
|
if (isDirectory(path)) {
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN64)
|
||||||
WIN32_FIND_DATAW findData;
|
WIN32_FIND_DATAW findData;
|
||||||
std::string wildcard = path + "/*";
|
std::string wildcard = path + "/*";
|
||||||
HANDLE hFind = FindFirstFileW(std::wstring(wildcard.begin(),
|
HANDLE hFind = FindFirstFileW(std::wstring(wildcard.begin(),
|
||||||
|
@ -149,14 +149,7 @@ namespace Utils
|
||||||
if (homePath.length())
|
if (homePath.length())
|
||||||
return homePath;
|
return homePath;
|
||||||
|
|
||||||
// Check for HOME environment variable.
|
#if defined(_WIN64)
|
||||||
if (!homePath.length()) {
|
|
||||||
std::string envHome = getenv("HOME");
|
|
||||||
if (envHome.length())
|
|
||||||
homePath = getGenericPath(envHome);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
// On Windows we need to check HOMEDRIVE and HOMEPATH.
|
// On Windows we need to check HOMEDRIVE and HOMEPATH.
|
||||||
if (!homePath.length()) {
|
if (!homePath.length()) {
|
||||||
std::string envHomeDrive = getenv("HOMEDRIVE");
|
std::string envHomeDrive = getenv("HOMEDRIVE");
|
||||||
|
@ -164,7 +157,14 @@ namespace Utils
|
||||||
if (envHomeDrive.length() && envHomePath.length())
|
if (envHomeDrive.length() && envHomePath.length())
|
||||||
homePath = getGenericPath(envHomeDrive + "/" + envHomePath);
|
homePath = getGenericPath(envHomeDrive + "/" + envHomePath);
|
||||||
}
|
}
|
||||||
#endif // _WIN32
|
#else
|
||||||
|
// Check for HOME environment variable.
|
||||||
|
if (!homePath.length()) {
|
||||||
|
std::string envHome = getenv("HOME");
|
||||||
|
if (envHome.length())
|
||||||
|
homePath = getGenericPath(envHome);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// No homepath found, fall back to current working directory.
|
// No homepath found, fall back to current working directory.
|
||||||
if (!homePath.length())
|
if (!homePath.length())
|
||||||
|
@ -184,7 +184,7 @@ namespace Utils
|
||||||
void setExePath(const std::string& _path)
|
void setExePath(const std::string& _path)
|
||||||
{
|
{
|
||||||
constexpr int path_max = 32767;
|
constexpr int path_max = 32767;
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN64)
|
||||||
std::wstring result(path_max, 0);
|
std::wstring result(path_max, 0);
|
||||||
if (GetModuleFileNameW(nullptr, &result[0], path_max) != 0)
|
if (GetModuleFileNameW(nullptr, &result[0], path_max) != 0)
|
||||||
exePath = convertFromWideString(result);
|
exePath = convertFromWideString(result);
|
||||||
|
@ -207,22 +207,28 @@ namespace Utils
|
||||||
return exePath;
|
return exePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getInstallPrefixPath()
|
std::string getProgramDataPath()
|
||||||
{
|
{
|
||||||
// installPrefix should be populated by CMAKE from $CMAKE_INSTALL_PREFIX.
|
// For Unix systems, installPrefix should be populated by CMAKE from
|
||||||
// But just as a precaution, let's check if this variable is blank, and if so
|
// $CMAKE_INSTALL_PREFIX. But just as a precaution, let's check if this
|
||||||
// set it to '/usr/local'. Just in case some make environments won't handle this
|
// variable is blank, and if so set it to '/usr/local'.
|
||||||
// correctly.
|
// Just in case some build environments won't handle this correctly.
|
||||||
|
// For Windows it doesn't really work like that and the application could have
|
||||||
|
// been install to an arbitrary location, so this function won't be used on that OS.
|
||||||
|
#ifdef __unix__
|
||||||
if (!installPrefix.length())
|
if (!installPrefix.length())
|
||||||
installPrefix = "/usr/local";
|
installPrefix = "/usr/local";
|
||||||
return installPrefix + "/share";
|
return installPrefix + "/share/emulationstation";
|
||||||
|
#else
|
||||||
|
return "";
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getPreferredPath(const std::string& _path)
|
std::string getPreferredPath(const std::string& _path)
|
||||||
{
|
{
|
||||||
std::string path = _path;
|
std::string path = _path;
|
||||||
size_t offset = std::string::npos;
|
size_t offset = std::string::npos;
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN64)
|
||||||
// Convert '/' to '\\'
|
// Convert '/' to '\\'
|
||||||
while ((offset = path.find('/')) != std::string::npos)
|
while ((offset = path.find('/')) != std::string::npos)
|
||||||
path.replace(offset, 1, "\\");
|
path.replace(offset, 1, "\\");
|
||||||
|
@ -258,7 +264,7 @@ namespace Utils
|
||||||
{
|
{
|
||||||
std::string path = getGenericPath(_path);
|
std::string path = getGenericPath(_path);
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN64)
|
||||||
// Windows escapes stuff by just putting everything in quotes.
|
// Windows escapes stuff by just putting everything in quotes.
|
||||||
return '"' + getPreferredPath(path) + '"';
|
return '"' + getPreferredPath(path) + '"';
|
||||||
#else
|
#else
|
||||||
|
@ -316,7 +322,7 @@ namespace Utils
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN64)
|
||||||
// Append folder to path.
|
// Append folder to path.
|
||||||
path += (path.size() == 0) ? (*it) : ("/" + (*it));
|
path += (path.size() == 0) ? (*it) : ("/" + (*it));
|
||||||
#else
|
#else
|
||||||
|
@ -481,20 +487,23 @@ namespace Utils
|
||||||
std::string path = getGenericPath(_path);
|
std::string path = getGenericPath(_path);
|
||||||
std::string resolved;
|
std::string resolved;
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN64)
|
||||||
HANDLE hFile = CreateFile(path.c_str(), FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
|
HANDLE hFile = CreateFile(path.c_str(), FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
|
||||||
0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
|
0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
|
||||||
|
/*
|
||||||
if (hFile != INVALID_HANDLE_VALUE) {
|
if (hFile != INVALID_HANDLE_VALUE) {
|
||||||
|
resolved.resize(GetFinalPathNameByHandle(hFile, nullptr, 0,
|
||||||
resolved.resize(GetFinalPathNameByHandle(hFile, nullptr, 0,
|
resolved.resize(GetFinalPathNameByHandle(hFile, nullptr, 0,
|
||||||
FILE_NAME_NORMALIZED) + 1);
|
FILE_NAME_NORMALIZED) + 1);
|
||||||
if (GetFinalPathNameByHandle(hFile, (LPSTR)resolved.data(),
|
if (GetFinalPathNameByHandle(hFile, (LPSTR)resolved.data(),
|
||||||
|
if (GetFinalPathNameByHandle(hFile, (LPSTR)resolved.data(),
|
||||||
(DWORD)resolved.size(), FILE_NAME_NORMALIZED) > 0) {
|
(DWORD)resolved.size(), FILE_NAME_NORMALIZED) > 0) {
|
||||||
resolved.resize(resolved.size() - 1);
|
resolved.resize(resolved.size() - 1);
|
||||||
resolved = getGenericPath(resolved);
|
resolved = getGenericPath(resolved);
|
||||||
}
|
}
|
||||||
CloseHandle(hFile);
|
CloseHandle(hFile);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
#else
|
#else
|
||||||
struct stat info;
|
struct stat info;
|
||||||
|
|
||||||
|
@ -555,7 +564,7 @@ namespace Utils
|
||||||
{
|
{
|
||||||
std::string path = getGenericPath(_path);
|
std::string path = getGenericPath(_path);
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN64)
|
||||||
return ((path.size() > 1) && (path[1] == ':'));
|
return ((path.size() > 1) && (path[1] == ':'));
|
||||||
#else
|
#else
|
||||||
return ((path.size() > 0) && (path[0] == '/'));
|
return ((path.size() > 0) && (path[0] == '/'));
|
||||||
|
@ -590,7 +599,7 @@ namespace Utils
|
||||||
{
|
{
|
||||||
std::string path = getGenericPath(_path);
|
std::string path = getGenericPath(_path);
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN64)
|
||||||
// Check for symlink attribute.
|
// Check for symlink attribute.
|
||||||
const DWORD Attributes = GetFileAttributes(path.c_str());
|
const DWORD Attributes = GetFileAttributes(path.c_str());
|
||||||
if ((Attributes != INVALID_FILE_ATTRIBUTES) &&
|
if ((Attributes != INVALID_FILE_ATTRIBUTES) &&
|
||||||
|
@ -614,12 +623,12 @@ namespace Utils
|
||||||
{
|
{
|
||||||
std::string path = getGenericPath(_path);
|
std::string path = getGenericPath(_path);
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN64)
|
||||||
// Check for hidden attribute.
|
// Check for hidden attribute.
|
||||||
const DWORD Attributes = GetFileAttributes(path.c_str());
|
const DWORD Attributes = GetFileAttributes(path.c_str());
|
||||||
if ((Attributes != INVALID_FILE_ATTRIBUTES) && (Attributes & FILE_ATTRIBUTE_HIDDEN))
|
if ((Attributes != INVALID_FILE_ATTRIBUTES) && (Attributes & FILE_ATTRIBUTE_HIDDEN))
|
||||||
return true;
|
return true;
|
||||||
#endif // _WIN32
|
#endif // _WIN64
|
||||||
|
|
||||||
// Filenames starting with . are hidden in Linux, but
|
// Filenames starting with . are hidden in Linux, but
|
||||||
// we do this check for windows as well.
|
// we do this check for windows as well.
|
||||||
|
|
|
@ -27,7 +27,7 @@ namespace Utils
|
||||||
std::string getCWDPath();
|
std::string getCWDPath();
|
||||||
void setExePath(const std::string& _path);
|
void setExePath(const std::string& _path);
|
||||||
std::string getExePath();
|
std::string getExePath();
|
||||||
std::string getInstallPrefixPath ();
|
std::string getProgramDataPath ();
|
||||||
std::string getPreferredPath(const std::string& _path);
|
std::string getPreferredPath(const std::string& _path);
|
||||||
std::string getGenericPath(const std::string& _path);
|
std::string getGenericPath(const std::string& _path);
|
||||||
std::string getEscapedPath(const std::string& _path);
|
std::string getEscapedPath(const std::string& _path);
|
||||||
|
|
3466
resources/certificates/curl-ca-bundle.crt
Normal file
3466
resources/certificates/curl-ca-bundle.crt
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue