Update to fully support Clang/LLVM.

Also a general cleanup of CMakeLists.txt and many small code changes to satisfy Clang that complained quite a lot and actually wouldn't compile the binary at all at first.
This commit is contained in:
Leon Styhre 2020-06-25 19:52:38 +02:00
parent 1cc96a2d21
commit 0387d515fb
44 changed files with 265 additions and 186 deletions

View file

@ -1,41 +1,39 @@
cmake_minimum_required(VERSION 3.0) cmake_minimum_required(VERSION 3.10)
project(emulationstation-de)
# Set this to ON to show verbose compiler output (e.g. compiler flags, include directories etc.)
set(CMAKE_VERBOSE_MAKEFILE OFF CACHE BOOL "Show verbose compiler output" FORCE)
# Add local find modules to CMAKE path.
LIST(APPEND CMAKE_MODULE_PATH
${CMAKE_CURRENT_SOURCE_DIR}/CMake/Utils
${CMAKE_CURRENT_SOURCE_DIR}/CMake/Packages)
# Options.
option(GLES "Set to ON if targeting Embedded OpenGL" ${GLES}) option(GLES "Set to ON if targeting Embedded OpenGL" ${GLES})
option(GL "Set to ON if targeting Desktop OpenGL" ${GL}) option(GL "Set to ON if targeting Desktop OpenGL" ${GL})
option(RPI "Set to ON to enable the Raspberry PI video player (omxplayer)" ${RPI}) option(RPI "Set to ON to enable the Raspberry PI video player (omxplayer)" ${RPI})
option(CEC "Set to ON to enable CEC" ${CEC}) option(CEC "Set to ON to enable CEC" ${CEC})
# Set this to on to show verbose compiler output (e.g. compiler flags, include directories etc.) #---------------------------------------------------------------------------------------------------
set(CMAKE_VERBOSE_MAKEFILE OFF CACHE BOOL "Show verbose compiler output" FORCE)
project(emulationstation-de)
#-------------------------------------------------------------------------------
# Add local find scripts to CMAKE path.
LIST(APPEND CMAKE_MODULE_PATH
${CMAKE_CURRENT_SOURCE_DIR}/CMake/Utils
${CMAKE_CURRENT_SOURCE_DIR}/CMake/Packages
)
#-------------------------------------------------------------------------------
# Set up OpenGL system variable. # Set up OpenGL system variable.
if(GLES) if(GLES)
set(GLSystem "Embedded OpenGL" CACHE STRING "The OpenGL system to be used") set(GLSystem "Embedded OpenGL" CACHE STRING "The OpenGL system to be used")
elseif(GL) elseif(GL)
set(GLSystem "Desktop OpenGL" CACHE STRING "The OpenGL system to be used") set(GLSystem "Desktop OpenGL" CACHE STRING "The OpenGL system to be used")
#-------------------------------------------------------------------------------
# Check if we're running on a Raspberry Pi. # Check if we're running on a Raspberry Pi.
elseif(EXISTS "${CMAKE_FIND_ROOT_PATH}/opt/vc/include/bcm_host.h") elseif(EXISTS "${CMAKE_FIND_ROOT_PATH}/opt/vc/include/bcm_host.h")
MESSAGE("bcm_host.h found") MESSAGE("bcm_host.h found")
set(BCMHOST found) set(BCMHOST found)
set(GLSystem "Embedded OpenGL" CACHE STRING "The OpenGL system to be used") set(GLSystem "Embedded OpenGL" CACHE STRING "The OpenGL system to be used")
#-------------------------------------------------------------------------------
# Check if we're running on OSMC Vero4K. # Check if we're running on OSMC Vero4K.
elseif(EXISTS "${CMAKE_FIND_ROOT_PATH}/opt/vero3/lib/libMali.so") elseif(EXISTS "${CMAKE_FIND_ROOT_PATH}/opt/vero3/lib/libMali.so")
MESSAGE("libMali.so found") MESSAGE("libMali.so found")
set(VERO4K found) set(VERO4K found)
set(GLSystem "Embedded OpenGL" CACHE STRING "The OpenGL system to be used") set(GLSystem "Embedded OpenGL" CACHE STRING "The OpenGL system to be used")
#-------------------------------------------------------------------------------
# Check if we're running on olinuxino / odroid / etc. # Check if we're running on olinuxino / odroid / etc.
elseif(EXISTS "${CMAKE_FIND_ROOT_PATH}/usr/lib/libMali.so" OR elseif(EXISTS "${CMAKE_FIND_ROOT_PATH}/usr/lib/libMali.so" OR
EXISTS "${CMAKE_FIND_ROOT_PATH}/usr/lib/arm-linux-gnueabihf/libMali.so" OR EXISTS "${CMAKE_FIND_ROOT_PATH}/usr/lib/arm-linux-gnueabihf/libMali.so" OR
@ -50,8 +48,8 @@ endif(GLES)
set_property(CACHE GLSystem PROPERTY STRINGS "Desktop OpenGL" "Embedded OpenGL") set_property(CACHE GLSystem PROPERTY STRINGS "Desktop OpenGL" "Embedded OpenGL")
#---------------------------------------------------------------------------------------------------
# Package dependencies. # Package dependencies.
#-------------------------------------------------------------------------------
if(${GLSystem} MATCHES "Desktop OpenGL") if(${GLSystem} MATCHES "Desktop OpenGL")
set(OpenGL_GL_PREFERENCE "GLVND") set(OpenGL_GL_PREFERENCE "GLVND")
find_package(OpenGL REQUIRED) find_package(OpenGL REQUIRED)
@ -76,8 +74,7 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
find_package(ALSA REQUIRED) find_package(ALSA REQUIRED)
endif() endif()
#------------------------------------------------------------------------------- # Set up compiler flags.
# Set up compiler flags and excutable names.
if(DEFINED BCMHOST OR RPI) if(DEFINED BCMHOST OR RPI)
add_definitions(-D_RPI_) add_definitions(-D_RPI_)
endif() endif()
@ -90,9 +87,22 @@ if(DEFINED libCEC_FOUND)
add_definitions(-DHAVE_LIBCEC) add_definitions(-DHAVE_LIBCEC)
endif() endif()
#------------------------------------------------------------------------------- #---------------------------------------------------------------------------------------------------
# Check for compiler type and version and apply specific compiler settings.
if(MSVC) if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
message("-- Compiler is Clang/LLVM")
execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE CLANG_VERSION)
if (CLANG_VERSION VERSION_LESS 6.0.0)
message(SEND_ERROR "You need at least Clang 6.0.0 to compile EmulationStation-DE!")
endif()
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
message("-- Compiler is GNU/GCC")
execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpfullversion OUTPUT_VARIABLE G++_VERSION)
if (G++_VERSION VERSION_LESS 4.8)
message(SEND_ERROR "You need at least GCC 4.8 to compile EmulationStation-DE!")
endif()
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
message("-- Compiler is MSVC (NOT TESTED)")
set(CMAKE_DEBUG_POSTFIX "d") set(CMAKE_DEBUG_POSTFIX "d")
add_definitions(-D_CRT_SECURE_NO_DEPRECATE) add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE)
@ -101,24 +111,23 @@ if(MSVC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MP") # Multi-processor compilation. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MP") # Multi-processor compilation.
endif() endif()
# Check for a GCC/G++ version higher than 4.8. # Set up compiler flags for debug or release builds.
if(CMAKE_COMPILER_IS_GNUCXX)
execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE G++_VERSION)
if (G++_VERSION VERSION_LESS 4.8)
message(SEND_ERROR "You need at least GCC 4.8 to compile EmulationStation!")
endif()
# Set up compiler flags for GCC.
if (CMAKE_BUILD_TYPE MATCHES Debug) if (CMAKE_BUILD_TYPE MATCHES Debug)
# Enable the C++11 standard and disable optimizations as it's a debug build. # Enable the C++11 standard and disable optimizations as it's a debug build.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-attributes -O0") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-attributes -O0")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -O0") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -O0")
# If using Clang, then add additional debug data needed by GDB.
# Comment this out if you're using LLDB for debugging as this flag makes
# the binary much larger and the application much slower.
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_GLIBCXX_DEBUG")
endif()
else() else()
# Enable the C++11 standard and enable optimizations as it's a release build. # Enable the C++11 standard and enable optimizations as it's a release build.
# Also disable the assert() macros. # Also disable the assert() macros and strip the binary.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-attributes -O2 -DNDEBUG") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-attributes -O2 -DNDEBUG")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -O2") #-s = strip binary set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -O2 -s")
endif()
endif() endif()
if(${GLSystem} MATCHES "Desktop OpenGL") if(${GLSystem} MATCHES "Desktop OpenGL")
@ -127,14 +136,14 @@ else()
add_definitions(-DUSE_OPENGLES_10) add_definitions(-DUSE_OPENGLES_10)
endif() endif()
# Add the installation prefix. # Assign the installation prefix to local $ES_INSTALL_PREFIX variable.
add_definitions(-DES_INSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}") add_definitions(-DES_INSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}")
# 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")
#------------------------------------------------------------------------------- #---------------------------------------------------------------------------------------------------
# Add include directories. # Add include directories.
set(COMMON_INCLUDE_DIRS set(COMMON_INCLUDE_DIRS
${CURL_INCLUDE_DIR} ${CURL_INCLUDE_DIR}
@ -148,18 +157,16 @@ set(COMMON_INCLUDE_DIRS
${CMAKE_CURRENT_SOURCE_DIR}/es-core/src ${CMAKE_CURRENT_SOURCE_DIR}/es-core/src
) )
# Add libCEC_INCLUDE_DIR. # Add libCEC include directory.
if(DEFINED libCEC_FOUND) if(DEFINED libCEC_FOUND)
LIST(APPEND COMMON_INCLUDE_DIRS LIST(APPEND COMMON_INCLUDE_DIRS
${libCEC_INCLUDE_DIR} ${libCEC_INCLUDE_DIR})
)
endif() endif()
# Add ALSA for Linux. # Add ALSA for Linux include directory.
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
LIST(APPEND COMMON_INCLUDE_DIRS LIST(APPEND COMMON_INCLUDE_DIRS
${ALSA_INCLUDE_DIRS} ${ALSA_INCLUDE_DIRS})
)
endif() endif()
if(DEFINED BCMHOST) if(DEFINED BCMHOST)
@ -167,35 +174,30 @@ if(DEFINED BCMHOST)
"${CMAKE_FIND_ROOT_PATH}/opt/vc/include" "${CMAKE_FIND_ROOT_PATH}/opt/vc/include"
"${CMAKE_FIND_ROOT_PATH}/opt/vc/include/interface/vcos" "${CMAKE_FIND_ROOT_PATH}/opt/vc/include/interface/vcos"
"${CMAKE_FIND_ROOT_PATH}/opt/vc/include/interface/vmcs_host/linux" "${CMAKE_FIND_ROOT_PATH}/opt/vc/include/interface/vmcs_host/linux"
"${CMAKE_FIND_ROOT_PATH}/opt/vc/include/interface/vcos/pthreads" "${CMAKE_FIND_ROOT_PATH}/opt/vc/include/interface/vcos/pthreads")
) # Add Vero4k include directory.
#add include directory for Vero4K
elseif(DEFINED VERO4K) elseif(DEFINED VERO4K)
LIST(APPEND COMMON_INCLUDE_DIRS LIST(APPEND COMMON_INCLUDE_DIRS
"${CMAKE_FIND_ROOT_PATH}/opt/vero3/include" "${CMAKE_FIND_ROOT_PATH}/opt/vero3/include")
)
else() else()
# Add OpenGL include directory.
if(${GLSystem} MATCHES "Desktop OpenGL") if(${GLSystem} MATCHES "Desktop OpenGL")
LIST(APPEND COMMON_INCLUDE_DIRS LIST(APPEND COMMON_INCLUDE_DIRS
${OPENGL_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR})
)
else() else()
# Add OpenGL ES include directory.
LIST(APPEND COMMON_INCLUDE_DIRS LIST(APPEND COMMON_INCLUDE_DIRS
${OPENGLES_INCLUDE_DIR} ${OPENGLES_INCLUDE_DIR})
)
endif() endif()
endif() endif()
#-------------------------------------------------------------------------------
# Define libraries and directories. # Define libraries and directories.
if(DEFINED BCMHOST) if(DEFINED BCMHOST)
link_directories( link_directories(
"${CMAKE_FIND_ROOT_PATH}/opt/vc/lib" "${CMAKE_FIND_ROOT_PATH}/opt/vc/lib")
)
elseif(DEFINED VERO4K) elseif(DEFINED VERO4K)
link_directories( link_directories(
"${CMAKE_FIND_ROOT_PATH}/opt/vero3/lib" "${CMAKE_FIND_ROOT_PATH}/opt/vero3/lib")
)
endif() endif()
set(COMMON_LIBRARIES set(COMMON_LIBRARIES
@ -205,67 +207,56 @@ set(COMMON_LIBRARIES
${PUGIXML_LIBRARIES} ${PUGIXML_LIBRARIES}
${SDL2_LIBRARY} ${SDL2_LIBRARY}
${VLC_LIBRARIES} ${VLC_LIBRARIES}
nanosvg nanosvg)
)
# Add libCEC_LIBRARIES. # Add libCEC libraries.
if(DEFINED libCEC_FOUND) if(DEFINED libCEC_FOUND)
if(DEFINED BCMHOST) if(DEFINED BCMHOST)
LIST(APPEND COMMON_LIBRARIES LIST(APPEND COMMON_LIBRARIES
vchiq_arm vchiq_arm)
)
endif() endif()
LIST(APPEND COMMON_LIBRARIES LIST(APPEND COMMON_LIBRARIES
dl dl
${libCEC_LIBRARIES} ${libCEC_LIBRARIES})
)
endif() endif()
# Add ALSA for Linux. # Add ALSA for Linux libraries.
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
LIST(APPEND COMMON_LIBRARIES LIST(APPEND COMMON_LIBRARIES
${ALSA_LIBRARY} ${ALSA_LIBRARY})
)
endif() endif()
if(DEFINED BCMHOST) if(DEFINED BCMHOST)
LIST(APPEND COMMON_LIBRARIES LIST(APPEND COMMON_LIBRARIES
bcm_host bcm_host
brcmEGL brcmEGL
${OPENGLES_LIBRARIES} ${OPENGLES_LIBRARIES})
)
elseif(DEFINED VERO4K) elseif(DEFINED VERO4K)
LIST(APPEND COMMON_LIBRARIES LIST(APPEND COMMON_LIBRARIES
EGL EGL
${OPENGLES_LIBRARIES} ${OPENGLES_LIBRARIES})
)
else() else()
if(MSVC) if(MSVC)
LIST(APPEND COMMON_LIBRARIES LIST(APPEND COMMON_LIBRARIES
winmm winmm)
)
endif() endif()
if(${GLSystem} MATCHES "Desktop OpenGL") if(${GLSystem} MATCHES "Desktop OpenGL")
LIST(APPEND COMMON_LIBRARIES LIST(APPEND COMMON_LIBRARIES
${OPENGL_LIBRARIES} ${OPENGL_LIBRARIES})
)
else() else()
LIST(APPEND COMMON_LIBRARIES LIST(APPEND COMMON_LIBRARIES
EGL EGL
${OPENGLES_LIBRARIES} ${OPENGLES_LIBRARIES})
)
endif() endif()
endif() endif()
#------------------------------------------------------------------------------- #---------------------------------------------------------------------------------------------------
# Set up build directories. # Set up build directories.
set(dir ${CMAKE_CURRENT_SOURCE_DIR}) set(dir ${CMAKE_CURRENT_SOURCE_DIR})
set(EXECUTABLE_OUTPUT_PATH ${dir} CACHE PATH "Build directory" FORCE) set(EXECUTABLE_OUTPUT_PATH ${dir} CACHE PATH "Build directory" FORCE)
set(LIBRARY_OUTPUT_PATH ${dir} CACHE PATH "Build directory" FORCE) set(LIBRARY_OUTPUT_PATH ${dir} CACHE PATH "Build directory" FORCE)
#-------------------------------------------------------------------------------
# Add each component. # Add each component.
add_subdirectory("external") add_subdirectory("external")
add_subdirectory("es-core") add_subdirectory("es-core")
add_subdirectory("es-app") add_subdirectory("es-app")

View file

@ -36,34 +36,34 @@ There are a few types of metadata:
* `integer` - an integer value (written as a string). * `integer` - an integer value (written as a string).
* `datetime` - a date and, potentially, a time. These are encoded as an ISO string, in the following format: "%Y%m%dT%H%M%S%F%q". For example, the release date for Chrono Trigger is encoded as "19950311T000000" (no time specified). * `datetime` - a date and, potentially, a time. These are encoded as an ISO string, in the following format: "%Y%m%dT%H%M%S%F%q". For example, the release date for Chrono Trigger is encoded as "19950311T000000" (no time specified).
Some metadata is also marked as "statistic" - these are kept track of by ES and do not show up in the metadata editor. They are shown in certain views (for example, the detailed and video views show `lastplayed`, although it can be disabled by the theme). Some metadata is also marked as "statistic" - these are kept track of by ES and do not show up in the metadata editor. They are shown in certain views (for example, the detailed view and the video view both show `lastplayed`, although the label can be disabled by the theme).
#### `<game>` #### `<game>`
* `name` - string, the displayed name for the game. * `name` - string, the displayed name for the game.
* `desc` - string, a description of the game. Longer descriptions will automatically scroll, so don't worry about size. * `desc` - string, a description of the game. Longer descriptions will automatically scroll, so don't worry about size.
* `rating` - float, the rating for the game, expressed as a floating point number between 0 and 1. Arbitrary values are fine (ES can display half-stars, quarter-stars, etc). * `rating` - float, the rating for the game, expressed as a floating point number between 0 and 1. ES will round fractional values to half-stars.
* `releasedate` - datetime, the date the game was released. Displayed as date only, time is ignored. * `releasedate` - datetime, the date the game was released. Displayed as date only, time is ignored.
* `developer` - string, the developer for the game. * `developer` - string, the developer for the game.
* `publisher` - string, the publisher for the game. * `publisher` - string, the publisher for the game.
* `genre` - string, the (primary) genre for the game. * `genre` - string, the (primary) genre for the game.
* `players` - integer, the number of players the game supports. * `players` - integer, the number of players the game supports.
* `favorite` - bool, indicates whether the game is a favorite * `favorite` - bool, indicates whether the game is a favorite.
* `completed`- bool, indicates whether the game has been completed * `completed`- bool, indicates whether the game has been completed.
* `broken` - bool, indicates a game that doesn't work (useful for MAME) * `broken` - bool, indicates a game that doesn't work (useful for MAME).
* `kidgame` - bool, indicates whether the game is suitable for children, used by the `kid' UI mode * `kidgame` - bool, indicates whether the game is suitable for children, used by the `kid' UI mode.
* `playcount` - integer, the number of times this game has been played. * `playcount` - integer, the number of times this game has been played.
* `lastplayed` - statistic, datetime, the last date and time this game was played. * `lastplayed` - statistic, datetime, the last date and time this game was played.
* `sortname` - string, used in sorting the gamelist in a system, instead of `name`. * `sortname` - string, used in sorting the gamelist in a system, instead of `name`.
* `launchstring` - optional tag that is used to override the emulator and core settings on a per-game basis * `launchstring` - optional tag that is used to override the emulator and core settings on a per-game basis.
#### `<folder>` #### `<folder>`
* `name` - string, the displayed name for the folder. * `name` - string, the displayed name for the folder.
* `desc` - string, the description for the folder. * `desc` - string, the description for the folder.
* `developer` - string, developer(s) * `developer` - string, developer(s).
* `publisher` - string, publisher(s) * `publisher` - string, publisher(s).
* `genre` - string, genre(s) * `genre` - string, genre(s).
* `players` - integer, the number of players the game supports * `players` - integer, the number of players the game supports.
Things to be aware of Things to be aware of

View file

@ -7,9 +7,6 @@ EmulationStation Desktop Edition - Installation
Building Building
======== ========
EmulationStation-DE uses some C++11 code, which means you'll need to use a compiler that supports that. \
GCC is recommended although other compilers should hopefully work fine as well.
The code has a few dependencies. For building, you'll need CMake and development packages for cURL, FreeImage, FreeType, libVLC, pugixml, SDL2 and RapidJSON. The code has a few dependencies. For building, you'll need CMake and development packages for cURL, FreeImage, FreeType, libVLC, pugixml, SDL2 and RapidJSON.
**On Debian/Ubuntu:** **On Debian/Ubuntu:**
@ -17,6 +14,7 @@ All of the required packages can be easily installed with `apt-get`:
``` ```
sudo apt-get install build-essential cmake libsdl2-dev libfreeimage-dev libfreetype6-dev libcurl4-openssl-dev libpugixml-dev rapidjson-dev libasound2-dev libvlc-dev libgl1-mesa-dev sudo apt-get install build-essential cmake libsdl2-dev libfreeimage-dev libfreetype6-dev libcurl4-openssl-dev libpugixml-dev rapidjson-dev libasound2-dev libvlc-dev libgl1-mesa-dev
``` ```
**On Fedora:** **On Fedora:**
For this operating system, use `dnf` (with rpmfusion activated) : For this operating system, use `dnf` (with rpmfusion activated) :
``` ```
@ -59,6 +57,52 @@ cmake -DCMAKE_INSTALL_PREFIX=/opt .
It's important to know that this is not only the directory used by the install script, the CMAKE_INSTALL_PREFIX variable also modifies code inside ES used to locate the required program resources. So it's necessary that the install prefix corresponds to the location where the application will actually be installed. It's important to know that this is not only the directory used by the install script, the CMAKE_INSTALL_PREFIX variable also modifies code inside ES used to locate the required program resources. So it's necessary that the install prefix corresponds to the location where the application will actually be installed.
**Compilers:**
Both Clang/LLVM and GCC work fine for building ES.
The Microsoft Visual C++ compiler (MSVC) could maybe work as well, there are some old settings in CMakeLists.txt for it. Try it if you want, but I recommend Clang or GCC instead of this legacy compiler.
I did some small benchmarks comparing Clang to GCC with the ES codebase (as of writing it's year 2020) and it's pretty interesting.
Advantages with Clang (vs GCC):
* 10% smaller binary size for a release build
* 17% smaller binary size for a debug build
* 2% faster compile time for a release build
* 16% faster compile time for a debug build
* 4% faster application startup time for a debug build
Advantage with GCC (vs Clang):
* 1% faster application startup time for a release build
*Release build: Optimizations enabled, debug info disabled, binary stripped.* \
*Debug build: Optimizations disabled, debug info enabled, binary not stripped.*
This Clang debug build is LLVM "native", i.e. intended to be debugged using the LLVM project debugger LLDB. The problem is that this is still not well integrated with VSCodium that I use for development so I need to keep using GDB. But this is problematic as the libstd++ data required by GDB is missing in the binary, making it impossible to see the values of for instance `std::string` variables.
It's possible to activate the additional debug info needed by GDB by using the flag `-D_GLIBCXX_DEBUG`. I've added this to CMakeLists.txt when using Clang, but this bloats the binary and makes the code much slower. Actually, instead of a 4% faster application startup, it's now 36% slower! The same goes for the binary size, instead of 17% smaller it's now 17% larger.
So overall Clang is interesting and perhaps even a better compiler than GCC, but it needs better integration with VSCodium before it's really usable. For macOS it seems as if Clang is the preferred compiler though, so it's good that ES now fully supports it. (It took quite some effort to get all the compile errors and compile warnings sorted out.)
It's by the way very easy to switch between LLVM and GCC using Ubuntu, just use the `update-alternatives` command:
```
user@computer:~$ sudo update-alternatives --config c++
[sudo] password for user:
There are 2 choices for the alternative c++ (providing /usr/bin/c++).
Selection Path Priority Status
------------------------------------------------------------
* 0 /usr/bin/g++ 20 auto mode
1 /usr/bin/clang++ 10 manual mode
2 /usr/bin/g++ 20 manual mode
Press <enter> to keep the current choice[*], or type selection number: 1
update-alternatives: using /usr/bin/clang++ to provide /usr/bin/c++ (c++) in manual mode
```
Following this, just re-run cmake and make and the binary should be built by Clang instead.
**Installing:** **Installing:**
Installing the software requires root permissions, the following command will install all the required application files: Installing the software requires root permissions, the following command will install all the required application files:

View file

@ -11,7 +11,7 @@ Check out the [User Guide](USERGUIDE.md) for how to quickly get the application
(It will also show how to use its more advanced features.) (It will also show how to use its more advanced features.)
**Help needed:** ### Help needed:
Apart from code commits, help is especially needed for thorough testing of the software and for working on the rbsimple-DE theme. Apart from code commits, help is especially needed for thorough testing of the software and for working on the rbsimple-DE theme.

View file

@ -815,6 +815,8 @@ void CollectionSystemManager::populateAutoCollection(CollectionSystemData* sysDa
// want in auto collections in "favorites" // want in auto collections in "favorites"
include = (*gameIt)->metadata.get("favorite") == "true"; include = (*gameIt)->metadata.get("favorite") == "true";
break; break;
default:
break;
} }
if (include) { if (include) {

View file

@ -461,8 +461,9 @@ void FileData::launchGame(Window* window)
LOG(LogInfo) << " " << command; LOG(LogInfo) << " " << command;
int exitCode = runSystemCommand(command); int exitCode = runSystemCommand(command);
if (exitCode != 0) if (exitCode != 0) {
LOG(LogWarning) << "...launch terminated with nonzero exit code " << exitCode << "!"; LOG(LogWarning) << "...launch terminated with nonzero exit code " << exitCode << "!";
}
Scripting::fireEvent("game-end"); Scripting::fireEvent("game-end");

View file

@ -174,6 +174,8 @@ std::string FileFilterIndex::getIndexableKey(FileData* game,
key = Utils::String::toUpper(game->metadata.get("kidgame")); key = Utils::String::toUpper(game->metadata.get("kidgame"));
break; break;
} }
default:
break;
} }
key = Utils::String::trim(key); key = Utils::String::trim(key);
if (key.empty() || (type == RATINGS_FILTER && key == "0 STARS")) { if (key.empty() || (type == RATINGS_FILTER && key == "0 STARS")) {

View file

@ -1,5 +1,5 @@
// //
// PlatformId.h // PlatformId.cpp
// //
// Index of all supported systems/platforms. // Index of all supported systems/platforms.
// //

View file

@ -180,6 +180,8 @@ void SystemData::indexAllGameFilters(const FileData* folder)
indexAllGameFilters(*it); indexAllGameFilters(*it);
} }
break; break;
default:
break;
} }
} }
} }

View file

@ -25,7 +25,7 @@ public:
void onSizeChanged() override; void onSizeChanged() override;
bool input(InputConfig* config, Input input) override; bool input(InputConfig* config, Input input) override;
void update(int deltaTime); void update(int deltaTime) override;
virtual std::vector<HelpPrompt> getHelpPrompts() override; virtual std::vector<HelpPrompt> getHelpPrompts() override;
HelpStyle getHelpStyle() override; HelpStyle getHelpStyle() override;

View file

@ -20,7 +20,7 @@ public:
GuiInfoPopup(Window* window, std::string message, int duration); GuiInfoPopup(Window* window, std::string message, int duration);
~GuiInfoPopup(); ~GuiInfoPopup();
void render(const Transform4x4f& parentTrans) override; void render(const Transform4x4f& parentTrans) override;
inline void stop() { running = false; }; inline void stop() override { running = false; };
private: private:
std::string mMessage; std::string mMessage;

View file

@ -579,8 +579,9 @@ void GuiMenu::openQuitMenu()
"REALLY REBOOT?", "YES", [] { "REALLY REBOOT?", "YES", [] {
Scripting::fireEvent("quit", "reboot"); Scripting::fireEvent("quit", "reboot");
Scripting::fireEvent("reboot"); Scripting::fireEvent("reboot");
if (quitES(QuitMode::REBOOT) != 0) if (quitES(QuitMode::REBOOT) != 0) {
LOG(LogWarning) << "Reboot terminated with non-zero result!"; LOG(LogWarning) << "Reboot terminated with non-zero result!";
}
}, "NO", nullptr)); }, "NO", nullptr));
}); });
row.addElement(std::make_shared<TextComponent>(window, "REBOOT SYSTEM", row.addElement(std::make_shared<TextComponent>(window, "REBOOT SYSTEM",
@ -595,8 +596,9 @@ void GuiMenu::openQuitMenu()
"REALLY POWER OFF?", "YES", [] { "REALLY POWER OFF?", "YES", [] {
Scripting::fireEvent("quit", "poweroff"); Scripting::fireEvent("quit", "poweroff");
Scripting::fireEvent("poweroff"); Scripting::fireEvent("poweroff");
if (quitES(QuitMode::POWEROFF) != 0) if (quitES(QuitMode::POWEROFF) != 0) {
LOG(LogWarning) << "Power off terminated with non-zero result!"; LOG(LogWarning) << "Power off terminated with non-zero result!";
}
}, "NO", nullptr)); }, "NO", nullptr));
}); });
row.addElement(std::make_shared<TextComponent>(window, "POWER OFF SYSTEM", row.addElement(std::make_shared<TextComponent>(window, "POWER OFF SYSTEM",

View file

@ -124,7 +124,7 @@ void thegamesdb_generate_json_scraper_requests(
usingGameID = true; usingGameID = true;
} }
else { else {
if (cleanName.empty()) if (cleanName.empty()) {
// If it's an arcade game (MAME or Neo Geo) then use the regular name. // If it's an arcade game (MAME or Neo Geo) then use the regular name.
if (params.system->hasPlatformId(PlatformIds::ARCADE) || if (params.system->hasPlatformId(PlatformIds::ARCADE) ||
params.system->hasPlatformId(PlatformIds::NEOGEO)) { params.system->hasPlatformId(PlatformIds::NEOGEO)) {
@ -132,13 +132,15 @@ void thegamesdb_generate_json_scraper_requests(
cleanName = MameNames::getInstance()->getCleanName(params.game->getCleanName()); cleanName = MameNames::getInstance()->getCleanName(params.game->getCleanName());
} }
else else {
cleanName = params.game->getCleanName(); cleanName = params.game->getCleanName();
}
path += "/Games/ByGameName?" + apiKey + path += "/Games/ByGameName?" + apiKey +
"&fields=players,publishers,genres,overview,last_updated,rating," "&fields=players,publishers,genres,overview,last_updated,rating,"
"platform,coop,youtube,os,processor,ram,hdd,video,sound,alternates&name=" + "platform,coop,youtube,os,processor,ram,hdd,video,sound,alternates&name=" +
HttpReq::urlEncode(cleanName); HttpReq::urlEncode(cleanName);
}
} }
if (usingGameID) { if (usingGameID) {

View file

@ -404,8 +404,9 @@ bool resizeImage(const std::string& path, int maxWidth, int maxHeight)
bool saved = (FreeImage_Save(format, imageRescaled, path.c_str()) != 0); bool saved = (FreeImage_Save(format, imageRescaled, path.c_str()) != 0);
FreeImage_Unload(imageRescaled); FreeImage_Unload(imageRescaled);
if (!saved) if (!saved) {
LOG(LogError) << "Failed to save resized image!"; LOG(LogError) << "Failed to save resized image!";
}
return saved; return saved;
} }

View file

@ -358,8 +358,9 @@ void ScreenScraperRequest::processList(const pugi::xml_document& xmldoc,
pugi::xml_node data = xmldoc.child("Data"); pugi::xml_node data = xmldoc.child("Data");
pugi::xml_node game = data.child("jeu"); pugi::xml_node game = data.child("jeu");
if (!game) if (!game) {
LOG(LogDebug) << "Found nothing"; LOG(LogDebug) << "Found nothing";
}
ScreenScraperRequest::ScreenScraperConfig ssConfig; ScreenScraperRequest::ScreenScraperConfig ssConfig;

View file

@ -68,7 +68,7 @@ public:
protected: protected:
void onCursorChanged(const CursorState& state) override; void onCursorChanged(const CursorState& state) override;
virtual void onScroll() { virtual void onScroll() override {
NavigationSounds::getInstance()->playThemeNavigationSound(SYSTEMBROWSESOUND); } NavigationSounds::getInstance()->playThemeNavigationSound(SYSTEMBROWSESOUND); }
private: private:

View file

@ -17,9 +17,9 @@ public:
BasicGameListView(Window* window, FileData* root); BasicGameListView(Window* window, FileData* root);
// Called when a FileData* is added, has its metadata changed, or is removed. // Called when a FileData* is added, has its metadata changed, or is removed.
virtual void onFileChanged(FileData* file, FileChangeType change); virtual void onFileChanged(FileData* file, FileChangeType change) override;
virtual void onThemeChanged(const std::shared_ptr<ThemeData>& theme); virtual void onThemeChanged(const std::shared_ptr<ThemeData>& theme) override;
virtual FileData* getCursor() override; virtual FileData* getCursor() override;
virtual void setCursor(FileData* file) override; virtual void setCursor(FileData* file) override;

View file

@ -214,7 +214,7 @@ const std::string GridGameListView::getImagePath(FileData* file)
return file->getMarqueePath(); return file->getMarqueePath();
// If no thumbnail was found, then use the image media type. // If no thumbnail was found, then use the image media type.
if (file->getThumbnailPath() == ""); if (file->getThumbnailPath() == "")
return file->getImagePath(); return file->getImagePath();
return file->getThumbnailPath(); return file->getThumbnailPath();

View file

@ -24,16 +24,16 @@ public:
// or a file's children are sorted. // or a file's children are sorted.
// NOTE: FILE_SORTED is only reported for the topmost FileData, where the sort started. // NOTE: FILE_SORTED is only reported for the topmost FileData, where the sort started.
// Since sorts are recursive, that FileData's children probably changed too. // Since sorts are recursive, that FileData's children probably changed too.
virtual void onFileChanged(FileData* file, FileChangeType change); virtual void onFileChanged(FileData* file, FileChangeType change) override;
// Called whenever the theme changes. // Called whenever the theme changes.
virtual void onThemeChanged(const std::shared_ptr<ThemeData>& theme); virtual void onThemeChanged(const std::shared_ptr<ThemeData>& theme) override;
virtual FileData* getCursor() = 0; virtual FileData* getCursor() override = 0;
virtual void setCursor(FileData*) = 0; virtual void setCursor(FileData*) override = 0;
virtual bool input(InputConfig* config, Input input) override; virtual bool input(InputConfig* config, Input input) override;
virtual void launch(FileData* game) = 0; virtual void launch(FileData* game) override = 0;
protected: protected:
virtual std::string getQuickSystemSelectRightButton() = 0; virtual std::string getQuickSystemSelectRightButton() = 0;

View file

@ -200,8 +200,9 @@ void GuiComponent::removeChild(GuiComponent* cmp)
if (!cmp->getParent()) if (!cmp->getParent())
return; return;
if (cmp->getParent() != this) if (cmp->getParent() != this) {
LOG(LogError) << "Tried to remove child from incorrect parent!"; LOG(LogError) << "Tried to remove child from incorrect parent!";
}
cmp->setParent(nullptr); cmp->setParent(nullptr);

View file

@ -121,9 +121,10 @@ HttpReq::~HttpReq()
CURLMcode merr = curl_multi_remove_handle(s_multi_handle, mHandle); CURLMcode merr = curl_multi_remove_handle(s_multi_handle, mHandle);
if (merr != CURLM_OK) if (merr != CURLM_OK) {
LOG(LogError) << "Error removing curl_easy handle from curl_multi: " << LOG(LogError) << "Error removing curl_easy handle from curl_multi: " <<
curl_multi_strerror(merr); curl_multi_strerror(merr);
}
curl_easy_cleanup(mHandle); curl_easy_cleanup(mHandle);
} }

View file

@ -193,9 +193,10 @@ void InputConfig::loadFromXML(pugi::xml_node& node)
int id = input.attribute("id").as_int(); int id = input.attribute("id").as_int();
int value = input.attribute("value").as_int(); int value = input.attribute("value").as_int();
if (value == 0) if (value == 0) {
LOG(LogWarning) << "WARNING: InputConfig value is 0 for " << LOG(LogWarning) << "WARNING: InputConfig value is 0 for " <<
type << " " << id << "!\n"; type << " " << id << "!\n";
}
mNameMap[toLower(name)] = Input(mDeviceId, typeEnum, id, value, true); mNameMap[toLower(name)] = Input(mDeviceId, typeEnum, id, value, true);
} }

View file

@ -429,9 +429,10 @@ void InputManager::doOnFinish()
int exitCode = runSystemCommand(tocall); int exitCode = runSystemCommand(tocall);
std::cout << "==============================================\n"; std::cout << "==============================================\n";
if (exitCode != 0) if (exitCode != 0) {
LOG(LogWarning) << "...launch terminated with nonzero exit code " << LOG(LogWarning) << "...launch terminated with nonzero exit code " <<
exitCode << "!"; exitCode << "!";
}
} }
} }
} }

View file

@ -5,7 +5,7 @@
#include <sstream> #include <sstream>
#define LOG(level) \ #define LOG(level) \
if(level > Log::getReportingLevel()) ; \ if(level > Log::getReportingLevel()); \
else Log().get(level) else Log().get(level)
enum LogLevel { LogError, LogWarning, LogInfo, LogDebug }; enum LogLevel { LogError, LogWarning, LogInfo, LogDebug };

View file

@ -84,5 +84,7 @@ void processQuitMode()
LOG(LogInfo) << "Powering off system"; LOG(LogInfo) << "Powering off system";
runPoweroffCommand(); runPoweroffCommand();
break; break;
default:
break;
} }
} }

View file

@ -23,31 +23,31 @@ Settings* Settings::sInstance = NULL;
// functions. // functions.
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. "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
{ "ShowExit" }, // --no-exit "ShowExit", // --no-exit
{ "SplashScreen" }, // --no-splash "SplashScreen", // --no-splash
{ "VSync" }, // --vsync [1/on or 0/off] "VSync", // --vsync [1/on or 0/off]
{ "Windowed" }, // --windowed "Windowed", // --windowed
{ "WindowWidth" }, // Set via --resolution [width] [height] "WindowWidth", // Set via --resolution [width] [height]
{ "WindowHeight" }, // set via --resolution [width] [height] "WindowHeight", // set via --resolution [width] [height]
// These options are not shown in the --help text and are intended // These options are not shown in the --help text and are intended
// for debugging and testing purposes: // for debugging and testing purposes:
{ "ScreenWidth" }, // Set via --screensize [width] [height] "ScreenWidth", // Set via --screensize [width] [height]
{ "ScreenHeight" }, // set via --screensize [width] [height] "ScreenHeight", // set via --screensize [width] [height]
{ "ScreenOffsetX" }, // Set via --screenoffset [X] [Y] "ScreenOffsetX", // Set via --screenoffset [X] [Y]
{ "ScreenOffsetY" }, // Set via --screenoffset [X] [Y] "ScreenOffsetY", // Set via --screenoffset [X] [Y]
{ "ScreenRotate" }, // --screenrotate [0-3] "ScreenRotate", // --screenrotate [0-3]
// These options are not configurable from the command-line: // These options are not configurable from the command-line:
{ "DebugGrid" }, "DebugGrid",
{ "DebugText" }, "DebugText",
{ "DebugImage" }, "DebugImage",
{ "SplashScreenProgress" } "SplashScreenProgress"
}; };
Settings::Settings() Settings::Settings()

View file

@ -5,6 +5,7 @@
class Animation class Animation
{ {
public: public:
virtual ~Animation() {};
virtual int getDuration() const = 0; virtual int getDuration() const = 0;
virtual void apply(float t) = 0; virtual void apply(float t) = 0;
}; };

View file

@ -44,7 +44,7 @@ public:
void setDisplayMode(DisplayMode mode); void setDisplayMode(DisplayMode mode);
// Text color. // Text color.
void setColor(unsigned int color); void setColor(unsigned int color) override;
// Font to use. Default is Font::get(FONT_SIZE_MEDIUM). // Font to use. Default is Font::get(FONT_SIZE_MEDIUM).
void setFont(std::shared_ptr<Font> font); void setFont(std::shared_ptr<Font> font);
// Force text to be uppercase when in DISP_RELATIVE_TO_NOW mode. // Force text to be uppercase when in DISP_RELATIVE_TO_NOW mode.

View file

@ -22,7 +22,7 @@ public:
GridTileComponent(Window* window); GridTileComponent(Window* window);
void render(const Transform4x4f& parentTrans) override; void render(const Transform4x4f& parentTrans) override;
virtual void applyTheme(const std::shared_ptr<ThemeData>& theme, const std::string& view, const std::string& element, unsigned int properties); virtual void applyTheme(const std::shared_ptr<ThemeData>& theme, const std::string& view, const std::string& element, unsigned int properties) override;
// Made this a static function because the ImageGridComponent need to know the default tile max size // Made this a static function because the ImageGridComponent need to know the default tile max size
// to calculate the grid dimension before it instantiate the GridTileComponents // to calculate the grid dimension before it instantiate the GridTileComponents
@ -41,7 +41,7 @@ public:
Vector3f getBackgroundPosition(); Vector3f getBackgroundPosition();
virtual void update(int deltaTime); virtual void update(int deltaTime) override;
std::shared_ptr<TextureResource> getTexture(); std::shared_ptr<TextureResource> getTexture();

View file

@ -54,7 +54,7 @@ public:
void uncrop(); void uncrop();
// Multiply all pixels in the image by this color when rendering. // Multiply all pixels in the image by this color when rendering.
void setColorShift(unsigned int color); void setColorShift(unsigned int color) override;
void setColorShiftEnd(unsigned int color); void setColorShiftEnd(unsigned int color);
void setColorGradientHorizontal(bool horizontal); void setColorGradientHorizontal(bool horizontal);

View file

@ -40,8 +40,11 @@ protected:
using IList<ImageGridData, T>::getTransform; using IList<ImageGridData, T>::getTransform;
using IList<ImageGridData, T>::mSize; using IList<ImageGridData, T>::mSize;
using IList<ImageGridData, T>::mCursor; using IList<ImageGridData, T>::mCursor;
using IList<ImageGridData, T>::Entry;
using IList<ImageGridData, T>::mWindow; using IList<ImageGridData, T>::mWindow;
// The following change is required for compilation with Clang.
// http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2070
// using IList<ImageGridData, T>::Entry;
using IList<ImageGridData, T>::IList;
public: public:
using IList<ImageGridData, T>::size; using IList<ImageGridData, T>::size;
@ -694,10 +697,12 @@ void ImageGridComponent<T>::calcGridDimension()
mGridDimension = Vector2i(gridDimension.x(), Math::ceilf(gridDimension.y())); mGridDimension = Vector2i(gridDimension.x(), Math::ceilf(gridDimension.y()));
// Grid dimension validation // Grid dimension validation
if (mGridDimension.x() < 1) if (mGridDimension.x() < 1) {
LOG(LogError) << "Theme defined grid X dimension below 1"; LOG(LogError) << "Theme defined grid X dimension below 1";
if (mGridDimension.y() < 1) }
if (mGridDimension.y() < 1) {
LOG(LogError) << "Theme defined grid Y dimension below 1"; LOG(LogError) << "Theme defined grid Y dimension below 1";
}
// Add extra tiles to both sides : Add EXTRAITEMS before, EXTRAITEMS after // Add extra tiles to both sides : Add EXTRAITEMS before, EXTRAITEMS after
if (isVertical()) if (isVertical())

View file

@ -72,8 +72,9 @@ public:
mLeftArrow.setResize(0, mText.getFont()->getLetterHeight()); mLeftArrow.setResize(0, mText.getFont()->getLetterHeight());
mRightArrow.setResize(0, mText.getFont()->getLetterHeight()); mRightArrow.setResize(0, mText.getFont()->getLetterHeight());
if(mSize.x() < (mLeftArrow.getSize().x() + mRightArrow.getSize().x())) if(mSize.x() < (mLeftArrow.getSize().x() + mRightArrow.getSize().x())) {
LOG(LogWarning) << "OptionListComponent too narrow!"; LOG(LogWarning) << "OptionListComponent too narrow!";
}
mText.setSize(mSize.x() - mLeftArrow.getSize().x() - mText.setSize(mSize.x() - mLeftArrow.getSize().x() -
mRightArrow.getSize().x(), mText.getFont()->getHeight()); mRightArrow.getSize().x(), mText.getFont()->getHeight());

View file

@ -31,14 +31,14 @@ public:
void setValue(const std::string& value) override; void setValue(const std::string& value) override;
bool input(InputConfig* config, Input input) override; bool input(InputConfig* config, Input input) override;
void render(const Transform4x4f& parentTrans); void render(const Transform4x4f& parentTrans) override;
void onSizeChanged() override; void onSizeChanged() override;
void setOpacity(unsigned char opacity) override; void setOpacity(unsigned char opacity) override;
// Multiply all pixels in the image by this color when rendering. // Multiply all pixels in the image by this color when rendering.
void setColorShift(unsigned int color); void setColorShift(unsigned int color) override;
virtual void applyTheme(const std::shared_ptr<ThemeData>& theme, const std::string& view, virtual void applyTheme(const std::shared_ptr<ThemeData>& theme, const std::string& view,
const std::string& element, unsigned int properties) override; const std::string& element, unsigned int properties) override;

View file

@ -23,7 +23,7 @@ public:
bool getState() const; bool getState() const;
void setState(bool state); void setState(bool state);
std::string getValue() const; std::string getValue() const override;
void setValue(const std::string& statestring) override; void setValue(const std::string& statestring) override;
virtual std::vector<HelpPrompt> getHelpPrompts() override; virtual std::vector<HelpPrompt> getHelpPrompts() override;

View file

@ -120,6 +120,8 @@ void TextComponent::render(const Transform4x4f& parentTrans)
case ALIGN_CENTER: case ALIGN_CENTER:
yOff = (getSize().y() - textSize.y()) / 2.0f; yOff = (getSize().y() - textSize.y()) / 2.0f;
break; break;
default:
break;
} }
Vector3f off(0, yOff, 0); Vector3f off(0, yOff, 0);
@ -147,6 +149,8 @@ void TextComponent::render(const Transform4x4f& parentTrans)
case ALIGN_RIGHT: case ALIGN_RIGHT:
Renderer::drawRect(mSize.x() - mTextCache->metrics.size.x(), 0.0f, mTextCache->metrics.size.x(), mTextCache->metrics.size.y(), 0x00000033, 0x00000033); Renderer::drawRect(mSize.x() - mTextCache->metrics.size.x(), 0.0f, mTextCache->metrics.size.x(), mTextCache->metrics.size.y(), 0x00000033, 0x00000033);
break; break;
default:
break;
} }
} }
mFont->renderTextCache(mTextCache.get()); mFont->renderTextCache(mTextCache.get());

View file

@ -23,7 +23,7 @@ public:
void setUppercase(bool uppercase); void setUppercase(bool uppercase);
void onSizeChanged() override; void onSizeChanged() override;
void setText(const std::string& text); void setText(const std::string& text);
void setColor(unsigned int color); void setColor(unsigned int color) override;
void setHorizontalAlignment(Alignment align); void setHorizontalAlignment(Alignment align);
void setVerticalAlignment(Alignment align); void setVerticalAlignment(Alignment align);
void setLineSpacing(float spacing); void setLineSpacing(float spacing);

View file

@ -34,7 +34,10 @@ protected:
using IList<TextListData, T>::getTransform; using IList<TextListData, T>::getTransform;
using IList<TextListData, T>::mSize; using IList<TextListData, T>::mSize;
using IList<TextListData, T>::mCursor; using IList<TextListData, T>::mCursor;
using IList<TextListData, T>::Entry; // The following change is required for compilation with Clang.
// http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2070
// using IList<TextListData, T>::Entry;
using IList<TextListData, T>::IList;
public: public:
using IList<TextListData, T>::size; using IList<TextListData, T>::size;
@ -87,9 +90,9 @@ public:
inline void setLineSpacing(float lineSpacing) { mLineSpacing = lineSpacing; } inline void setLineSpacing(float lineSpacing) { mLineSpacing = lineSpacing; }
protected: protected:
virtual void onScroll() { virtual void onScroll() override {
NavigationSounds::getInstance()->playThemeNavigationSound(SCROLLSOUND); } NavigationSounds::getInstance()->playThemeNavigationSound(SCROLLSOUND); }
virtual void onCursorChanged(const CursorState& state); virtual void onCursorChanged(const CursorState& state) override;
private: private:
int mMarqueeOffset; int mMarqueeOffset;

View file

@ -56,7 +56,7 @@ public:
virtual std::vector<HelpPrompt> getHelpPrompts() override; virtual std::vector<HelpPrompt> getHelpPrompts() override;
virtual void update(int deltaTime); virtual void update(int deltaTime) override;
// Resize the video to fit this size. If one axis is zero, scale that axis to maintain aspect ratio. // Resize the video to fit this size. If one axis is zero, scale that axis to maintain aspect ratio.
// If both are non-zero, potentially break the aspect ratio. If both are zero, no resizing. // If both are non-zero, potentially break the aspect ratio. If both are zero, no resizing.

View file

@ -41,23 +41,23 @@ public:
// If both are non-zero, potentially break the aspect ratio. If both are zero, no resizing. // If both are non-zero, potentially break the aspect ratio. If both are zero, no resizing.
// Can be set before or after a video is loaded. // Can be set before or after a video is loaded.
// setMaxSize() and setResize() are mutually exclusive. // setMaxSize() and setResize() are mutually exclusive.
void setResize(float width, float height); void setResize(float width, float height) override;
// Resize the video to be as large as possible but fit within a box of this size. // Resize the video to be as large as possible but fit within a box of this size.
// Can be set before or after a video is loaded. // Can be set before or after a video is loaded.
// Never breaks the aspect ratio. setMaxSize() and setResize() are mutually exclusive. // Never breaks the aspect ratio. setMaxSize() and setResize() are mutually exclusive.
void setMaxSize(float width, float height); void setMaxSize(float width, float height) override;
private: private:
// Calculates the correct mSize from our resizing information (set by setResize/setMaxSize). // Calculates the correct mSize from our resizing information (set by setResize/setMaxSize).
// Used internally whenever the resizing parameters or texture change. // Used internally whenever the resizing parameters or texture change.
void resize(); void resize();
// Start the video Immediately // Start the video Immediately
virtual void startVideo(); virtual void startVideo() override;
// Stop the video // Stop the video
virtual void stopVideo(); virtual void stopVideo() override;
// Handle looping the video. Must be called periodically // Handle looping the video. Must be called periodically
virtual void handleLooping(); virtual void handleLooping() override;
void setupContext(); void setupContext();
void freeContext(); void freeContext();

View file

@ -32,8 +32,8 @@ public:
const char* acceptBtnText = "OK", const char* acceptBtnText = "OK",
const char* saveConfirmationText = "SAVE CHANGES?"); const char* saveConfirmationText = "SAVE CHANGES?");
bool input(InputConfig* config, Input input); bool input(InputConfig* config, Input input) override;
void onSizeChanged(); void onSizeChanged() override;
std::vector<HelpPrompt> getHelpPrompts() override; std::vector<HelpPrompt> getHelpPrompts() override;
HelpStyle getHelpStyle() override { return mHelpStyle; }; HelpStyle getHelpStyle() override { return mHelpStyle; };

View file

@ -28,8 +28,8 @@ public:
const char* acceptBtnText = "OK", const char* acceptBtnText = "OK",
const char* saveConfirmationText = "SAVE CHANGES?"); const char* saveConfirmationText = "SAVE CHANGES?");
bool input(InputConfig* config, Input input); bool input(InputConfig* config, Input input) override;
void onSizeChanged(); void onSizeChanged() override;
std::vector<HelpPrompt> getHelpPrompts() override; std::vector<HelpPrompt> getHelpPrompts() override;
HelpStyle getHelpStyle() override { return mHelpStyle; }; HelpStyle getHelpStyle() override { return mHelpStyle; };

View file

@ -18,8 +18,9 @@ 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 << " failed with error code: " << errorCode; LOG(LogError) << "OpenGLES error: " << _funcName << " failed with error code: " << errorCode;
}
} }
#else #else
#define GL_CHECK_ERROR(Function) (Function) #define GL_CHECK_ERROR(Function) (Function)
@ -246,8 +247,9 @@ namespace Renderer
// SDL_GL_SetSwapInterval returns 0 on success, -1 on error. // SDL_GL_SetSwapInterval returns 0 on success, -1 on error.
// if vsync is requested, try normal vsync; if that doesn't work, try late swap tearing // if vsync is requested, try normal vsync; if that doesn't work, try late swap tearing
// if that doesn't work, report an error // if that doesn't work, report an error
if(SDL_GL_SetSwapInterval(1) != 0 && SDL_GL_SetSwapInterval(-1) != 0) if(SDL_GL_SetSwapInterval(1) != 0 && SDL_GL_SetSwapInterval(-1) != 0) {
LOG(LogWarning) << "Tried to enable vsync, but failed! (" << SDL_GetError() << ")"; LOG(LogWarning) << "Tried to enable vsync, but failed! (" << SDL_GetError() << ")";
}
} }
else else
SDL_GL_SetSwapInterval(0); SDL_GL_SetSwapInterval(0);

View file

@ -555,12 +555,13 @@ float Font::getNewlineStartOffset(const std::string& text, const unsigned int& c
case ALIGN_LEFT: case ALIGN_LEFT:
return 0; return 0;
case ALIGN_CENTER: { case ALIGN_CENTER: {
unsigned int endChar = (unsigned int)text.find('\n', charStart); int endChar = 0;
endChar = (int)text.find('\n', charStart);
return (xLen - sizeText(text.substr(charStart, endChar != return (xLen - sizeText(text.substr(charStart, endChar !=
std::string::npos ? endChar - charStart : endChar)).x()) / 2.0f; std::string::npos ? endChar - charStart : endChar)).x()) / 2.0f;
} }
case ALIGN_RIGHT: { case ALIGN_RIGHT: {
unsigned int endChar = (unsigned int)text.find('\n', charStart); int endChar = (int)text.find('\n', charStart);
return xLen - (sizeText(text.substr(charStart, endChar != return xLen - (sizeText(text.substr(charStart, endChar !=
std::string::npos ? endChar - charStart : endChar)).x()); std::string::npos ? endChar - charStart : endChar)).x());
} }

View file

@ -27,23 +27,32 @@ namespace Utils
// 110xxxxx, two byte character. // 110xxxxx, two byte character.
else if ((c & 0xE0) == 0xC0) { else if ((c & 0xE0) == 0xC0) {
// 110xxxxx 10xxxxxx // 110xxxxx 10xxxxxx
result = ((_string[_cursor++] & 0x1F) << 6) | result = (_string[_cursor++] & 0x1F) << 6;
((_string[_cursor++] & 0x3F) ); result |= _string[_cursor++] & 0x3F;
// result = ((_string[_cursor++] & 0x1F) << 6) |
// ((_string[_cursor++] & 0x3F) );
} }
// 1110xxxx, three byte character. // 1110xxxx, three byte character.
else if ((c & 0xF0) == 0xE0) { else if ((c & 0xF0) == 0xE0) {
// 1110xxxx 10xxxxxx 10xxxxxx // 1110xxxx 10xxxxxx 10xxxxxx
result = ((_string[_cursor++] & 0x0F) << 12) | result = (_string[_cursor++] & 0x0F) << 12;
((_string[_cursor++] & 0x3F) << 6) | result |= (_string[_cursor++] & 0x3F) << 6;
((_string[_cursor++] & 0x3F) ); result |= _string[_cursor++] & 0x3F;
// result = ((_string[_cursor++] & 0x0F) << 12) |
// ((_string[_cursor++] & 0x3F) << 6) |
// ((_string[_cursor++] & 0x3F) );
} }
// 11110xxx, four byte character. // 11110xxx, four byte character.
else if ((c & 0xF8) == 0xF0) { else if ((c & 0xF8) == 0xF0) {
// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
result = ((_string[_cursor++] & 0x07) << 18) | result = (_string[_cursor++] & 0x07) << 18;
((_string[_cursor++] & 0x3F) << 12) | result |= (_string[_cursor++] & 0x3F) << 12;
((_string[_cursor++] & 0x3F) << 6) | result |= (_string[_cursor++] & 0x3F) << 6;
((_string[_cursor++] & 0x3F) ); result |= _string[_cursor++] & 0x3F;
// result = ((_string[_cursor++] & 0x07) << 18) |
// ((_string[_cursor++] & 0x3F) << 12) |
// ((_string[_cursor++] & 0x3F) << 6) |
// ((_string[_cursor++] & 0x3F) );
} }
else { else {
// Error, invalid unicode. // Error, invalid unicode.
@ -156,7 +165,7 @@ namespace Utils
std::string trim(const std::string& _string) std::string trim(const std::string& _string)
{ {
const size_t strBegin = _string.find_first_not_of(" \t"); const size_t strBegin = _string.find_first_not_of(" \t");
const size_t strEnd = _string.find_last_not_of(" \t"); const size_t strEnd = _string.find_last_not_of(" \t");
if (strBegin == std::string::npos) if (strBegin == std::string::npos)
return ""; return "";
@ -168,7 +177,7 @@ namespace Utils
const std::string& _with) const std::string& _with)
{ {
std::string string = _string; std::string string = _string;
size_t pos; size_t pos;
while ((pos = string.find(_replace)) != std::string::npos) while ((pos = string.find(_replace)) != std::string::npos)
string = string.replace(pos, _replace.length(), _with.c_str(), _with.length()); string = string.replace(pos, _replace.length(), _with.c_str(), _with.length());
@ -189,10 +198,10 @@ namespace Utils
std::string removeParenthesis(const std::string& _string) std::string removeParenthesis(const std::string& _string)
{ {
static const char remove[4] = { '(', ')', '[', ']' }; static const char remove[4] = { '(', ')', '[', ']' };
std::string string = _string; std::string string = _string;
size_t start; size_t start;
size_t end; size_t end;
bool done = false; bool done = false;
while (!done) { while (!done) {
done = true; done = true;
@ -215,8 +224,8 @@ namespace Utils
const std::string& _delimiter, bool sort) const std::string& _delimiter, bool sort)
{ {
stringVector vector; stringVector vector;
size_t start = 0; size_t start = 0;
size_t comma = _string.find(_delimiter); size_t comma = _string.find(_delimiter);
while (comma != std::string::npos) { while (comma != std::string::npos) {
vector.push_back(_string.substr(start, comma - start)); vector.push_back(_string.substr(start, comma - start));
@ -267,7 +276,7 @@ namespace Utils
va_end(args); va_end(args);
std::string out(buffer); std::string out(buffer);
delete buffer; delete[] buffer;
return out; return out;
} }
@ -283,5 +292,4 @@ namespace Utils
} }
} // String:: } // String::
} // Utils:: } // Utils::