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(GL "Set to ON if targeting Desktop OpenGL" ${GL})
option(RPI "Set to ON to enable the Raspberry PI video player (omxplayer)" ${RPI})
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.
if(GLES)
set(GLSystem "Embedded OpenGL" CACHE STRING "The OpenGL system to be used")
elseif(GL)
set(GLSystem "Desktop OpenGL" CACHE STRING "The OpenGL system to be used")
#-------------------------------------------------------------------------------
# Check if we're running on a Raspberry Pi.
elseif(EXISTS "${CMAKE_FIND_ROOT_PATH}/opt/vc/include/bcm_host.h")
MESSAGE("bcm_host.h found")
set(BCMHOST found)
set(GLSystem "Embedded OpenGL" CACHE STRING "The OpenGL system to be used")
#-------------------------------------------------------------------------------
# Check if we're running on OSMC Vero4K.
elseif(EXISTS "${CMAKE_FIND_ROOT_PATH}/opt/vero3/lib/libMali.so")
MESSAGE("libMali.so found")
set(VERO4K found)
set(GLSystem "Embedded OpenGL" CACHE STRING "The OpenGL system to be used")
#-------------------------------------------------------------------------------
# Check if we're running on olinuxino / odroid / etc.
elseif(EXISTS "${CMAKE_FIND_ROOT_PATH}/usr/lib/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")
#---------------------------------------------------------------------------------------------------
# Package dependencies.
#-------------------------------------------------------------------------------
if(${GLSystem} MATCHES "Desktop OpenGL")
set(OpenGL_GL_PREFERENCE "GLVND")
find_package(OpenGL REQUIRED)
@ -76,8 +74,7 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
find_package(ALSA REQUIRED)
endif()
#-------------------------------------------------------------------------------
# Set up compiler flags and excutable names.
# Set up compiler flags.
if(DEFINED BCMHOST OR RPI)
add_definitions(-D_RPI_)
endif()
@ -90,9 +87,22 @@ if(DEFINED libCEC_FOUND)
add_definitions(-DHAVE_LIBCEC)
endif()
#-------------------------------------------------------------------------------
if(MSVC)
#---------------------------------------------------------------------------------------------------
# Check for compiler type and version and apply specific compiler settings.
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")
add_definitions(-D_CRT_SECURE_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.
endif()
# Check for a GCC/G++ version higher than 4.8.
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.
# Set up compiler flags for debug or release builds.
if (CMAKE_BUILD_TYPE MATCHES Debug)
# 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_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()
# 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_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -O2") #-s = strip binary
endif()
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -O2 -s")
endif()
if(${GLSystem} MATCHES "Desktop OpenGL")
@ -127,14 +136,14 @@ else()
add_definitions(-DUSE_OPENGLES_10)
endif()
# Add the installation prefix.
# Assign the installation prefix to local $ES_INSTALL_PREFIX variable.
add_definitions(-DES_INSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}")
# Enable additional defines for the Debug build configuration.
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG")
#-------------------------------------------------------------------------------
#---------------------------------------------------------------------------------------------------
# Add include directories.
set(COMMON_INCLUDE_DIRS
${CURL_INCLUDE_DIR}
@ -148,18 +157,16 @@ set(COMMON_INCLUDE_DIRS
${CMAKE_CURRENT_SOURCE_DIR}/es-core/src
)
# Add libCEC_INCLUDE_DIR.
# Add libCEC include directory.
if(DEFINED libCEC_FOUND)
LIST(APPEND COMMON_INCLUDE_DIRS
${libCEC_INCLUDE_DIR}
)
${libCEC_INCLUDE_DIR})
endif()
# Add ALSA for Linux.
# Add ALSA for Linux include directory.
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
LIST(APPEND COMMON_INCLUDE_DIRS
${ALSA_INCLUDE_DIRS}
)
${ALSA_INCLUDE_DIRS})
endif()
if(DEFINED BCMHOST)
@ -167,35 +174,30 @@ if(DEFINED BCMHOST)
"${CMAKE_FIND_ROOT_PATH}/opt/vc/include"
"${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/vcos/pthreads"
)
#add include directory for Vero4K
"${CMAKE_FIND_ROOT_PATH}/opt/vc/include/interface/vcos/pthreads")
# Add Vero4k include directory.
elseif(DEFINED VERO4K)
LIST(APPEND COMMON_INCLUDE_DIRS
"${CMAKE_FIND_ROOT_PATH}/opt/vero3/include"
)
"${CMAKE_FIND_ROOT_PATH}/opt/vero3/include")
else()
# Add OpenGL include directory.
if(${GLSystem} MATCHES "Desktop OpenGL")
LIST(APPEND COMMON_INCLUDE_DIRS
${OPENGL_INCLUDE_DIR}
)
${OPENGL_INCLUDE_DIR})
else()
# Add OpenGL ES include directory.
LIST(APPEND COMMON_INCLUDE_DIRS
${OPENGLES_INCLUDE_DIR}
)
${OPENGLES_INCLUDE_DIR})
endif()
endif()
#-------------------------------------------------------------------------------
# Define libraries and directories.
if(DEFINED BCMHOST)
link_directories(
"${CMAKE_FIND_ROOT_PATH}/opt/vc/lib"
)
"${CMAKE_FIND_ROOT_PATH}/opt/vc/lib")
elseif(DEFINED VERO4K)
link_directories(
"${CMAKE_FIND_ROOT_PATH}/opt/vero3/lib"
)
"${CMAKE_FIND_ROOT_PATH}/opt/vero3/lib")
endif()
set(COMMON_LIBRARIES
@ -205,67 +207,56 @@ set(COMMON_LIBRARIES
${PUGIXML_LIBRARIES}
${SDL2_LIBRARY}
${VLC_LIBRARIES}
nanosvg
)
nanosvg)
# Add libCEC_LIBRARIES.
# Add libCEC libraries.
if(DEFINED libCEC_FOUND)
if(DEFINED BCMHOST)
LIST(APPEND COMMON_LIBRARIES
vchiq_arm
)
vchiq_arm)
endif()
LIST(APPEND COMMON_LIBRARIES
dl
${libCEC_LIBRARIES}
)
${libCEC_LIBRARIES})
endif()
# Add ALSA for Linux.
# Add ALSA for Linux libraries.
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
LIST(APPEND COMMON_LIBRARIES
${ALSA_LIBRARY}
)
${ALSA_LIBRARY})
endif()
if(DEFINED BCMHOST)
LIST(APPEND COMMON_LIBRARIES
bcm_host
brcmEGL
${OPENGLES_LIBRARIES}
)
${OPENGLES_LIBRARIES})
elseif(DEFINED VERO4K)
LIST(APPEND COMMON_LIBRARIES
EGL
${OPENGLES_LIBRARIES}
)
${OPENGLES_LIBRARIES})
else()
if(MSVC)
LIST(APPEND COMMON_LIBRARIES
winmm
)
winmm)
endif()
if(${GLSystem} MATCHES "Desktop OpenGL")
LIST(APPEND COMMON_LIBRARIES
${OPENGL_LIBRARIES}
)
${OPENGL_LIBRARIES})
else()
LIST(APPEND COMMON_LIBRARIES
EGL
${OPENGLES_LIBRARIES}
)
${OPENGLES_LIBRARIES})
endif()
endif()
#-------------------------------------------------------------------------------
#---------------------------------------------------------------------------------------------------
# Set up build directories.
set(dir ${CMAKE_CURRENT_SOURCE_DIR})
set(EXECUTABLE_OUTPUT_PATH ${dir} CACHE PATH "Build directory" FORCE)
set(LIBRARY_OUTPUT_PATH ${dir} CACHE PATH "Build directory" FORCE)
#-------------------------------------------------------------------------------
# Add each component.
add_subdirectory("external")
add_subdirectory("es-core")
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).
* `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>`
* `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.
* `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.
* `developer` - string, the developer for the game.
* `publisher` - string, the publisher for the game.
* `genre` - string, the (primary) genre for the game.
* `players` - integer, the number of players the game supports.
* `favorite` - bool, indicates whether the game is a favorite
* `completed`- bool, indicates whether the game has been completed
* `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
* `favorite` - bool, indicates whether the game is a favorite.
* `completed`- bool, indicates whether the game has been completed.
* `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.
* `playcount` - integer, the number of times this game has been 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`.
* `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>`
* `name` - string, the displayed name for the folder.
* `desc` - string, the description for the folder.
* `developer` - string, developer(s)
* `publisher` - string, publisher(s)
* `genre` - string, genre(s)
* `players` - integer, the number of players the game supports
* `developer` - string, developer(s).
* `publisher` - string, publisher(s).
* `genre` - string, genre(s).
* `players` - integer, the number of players the game supports.
Things to be aware of

View file

@ -7,9 +7,6 @@ EmulationStation Desktop Edition - Installation
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.
**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
```
**On Fedora:**
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.
**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 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.)
**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.

View file

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

View file

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

View file

@ -174,6 +174,8 @@ std::string FileFilterIndex::getIndexableKey(FileData* game,
key = Utils::String::toUpper(game->metadata.get("kidgame"));
break;
}
default:
break;
}
key = Utils::String::trim(key);
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.
//

View file

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

View file

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

View file

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

View file

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

View file

@ -124,7 +124,7 @@ void thegamesdb_generate_json_scraper_requests(
usingGameID = true;
}
else {
if (cleanName.empty())
if (cleanName.empty()) {
// If it's an arcade game (MAME or Neo Geo) then use the regular name.
if (params.system->hasPlatformId(PlatformIds::ARCADE) ||
params.system->hasPlatformId(PlatformIds::NEOGEO)) {
@ -132,13 +132,15 @@ void thegamesdb_generate_json_scraper_requests(
cleanName = MameNames::getInstance()->getCleanName(params.game->getCleanName());
}
else
else {
cleanName = params.game->getCleanName();
}
path += "/Games/ByGameName?" + apiKey +
"&fields=players,publishers,genres,overview,last_updated,rating,"
"platform,coop,youtube,os,processor,ram,hdd,video,sound,alternates&name=" +
HttpReq::urlEncode(cleanName);
}
}
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);
FreeImage_Unload(imageRescaled);
if (!saved)
if (!saved) {
LOG(LogError) << "Failed to save resized image!";
}
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 game = data.child("jeu");
if (!game)
if (!game) {
LOG(LogDebug) << "Found nothing";
}
ScreenScraperRequest::ScreenScraperConfig ssConfig;

View file

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

View file

@ -17,9 +17,9 @@ public:
BasicGameListView(Window* window, FileData* root);
// 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 void setCursor(FileData* file) override;

View file

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

View file

@ -24,16 +24,16 @@ public:
// or a file's children are sorted.
// 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.
virtual void onFileChanged(FileData* file, FileChangeType change);
virtual void onFileChanged(FileData* file, FileChangeType change) override;
// 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 void setCursor(FileData*) = 0;
virtual FileData* getCursor() override = 0;
virtual void setCursor(FileData*) override = 0;
virtual bool input(InputConfig* config, Input input) override;
virtual void launch(FileData* game) = 0;
virtual void launch(FileData* game) override = 0;
protected:
virtual std::string getQuickSystemSelectRightButton() = 0;

View file

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

View file

@ -121,9 +121,10 @@ HttpReq::~HttpReq()
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: " <<
curl_multi_strerror(merr);
}
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 value = input.attribute("value").as_int();
if (value == 0)
if (value == 0) {
LOG(LogWarning) << "WARNING: InputConfig value is 0 for " <<
type << " " << id << "!\n";
}
mNameMap[toLower(name)] = Input(mDeviceId, typeEnum, id, value, true);
}

View file

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

View file

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

View file

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

View file

@ -23,31 +23,31 @@ Settings* Settings::sInstance = NULL;
// functions.
std::vector<const char*> settings_dont_save {
// These options can be set using command-line arguments:
{ "Debug" }, // --debug
{ "HideConsole" }, // Implicitly set via the --debug flag.
{ "ForceKid" }, // --force-kid
{ "ForceKiosk" }, // --force-kiosk
{ "IgnoreGamelist" }, // --ignore-gamelist
{ "ShowExit" }, // --no-exit
{ "SplashScreen" }, // --no-splash
{ "VSync" }, // --vsync [1/on or 0/off]
{ "Windowed" }, // --windowed
{ "WindowWidth" }, // Set via --resolution [width] [height]
{ "WindowHeight" }, // set via --resolution [width] [height]
"Debug", // --debug
"HideConsole", // Implicitly set via the --debug flag.
"ForceKid", // --force-kid
"ForceKiosk", // --force-kiosk
"IgnoreGamelist", // --ignore-gamelist
"ShowExit", // --no-exit
"SplashScreen", // --no-splash
"VSync", // --vsync [1/on or 0/off]
"Windowed", // --windowed
"WindowWidth", // Set via --resolution [width] [height]
"WindowHeight", // set via --resolution [width] [height]
// These options are not shown in the --help text and are intended
// for debugging and testing purposes:
{ "ScreenWidth" }, // Set via --screensize [width] [height]
{ "ScreenHeight" }, // set via --screensize [width] [height]
{ "ScreenOffsetX" }, // Set via --screenoffset [X] [Y]
{ "ScreenOffsetY" }, // Set via --screenoffset [X] [Y]
{ "ScreenRotate" }, // --screenrotate [0-3]
"ScreenWidth", // Set via --screensize [width] [height]
"ScreenHeight", // set via --screensize [width] [height]
"ScreenOffsetX", // Set via --screenoffset [X] [Y]
"ScreenOffsetY", // Set via --screenoffset [X] [Y]
"ScreenRotate", // --screenrotate [0-3]
// These options are not configurable from the command-line:
{ "DebugGrid" },
{ "DebugText" },
{ "DebugImage" },
{ "SplashScreenProgress" }
"DebugGrid",
"DebugText",
"DebugImage",
"SplashScreenProgress"
};
Settings::Settings()

View file

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

View file

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

View file

@ -22,7 +22,7 @@ public:
GridTileComponent(Window* window);
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
// to calculate the grid dimension before it instantiate the GridTileComponents
@ -41,7 +41,7 @@ public:
Vector3f getBackgroundPosition();
virtual void update(int deltaTime);
virtual void update(int deltaTime) override;
std::shared_ptr<TextureResource> getTexture();

View file

@ -54,7 +54,7 @@ public:
void uncrop();
// 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 setColorGradientHorizontal(bool horizontal);

View file

@ -40,8 +40,11 @@ protected:
using IList<ImageGridData, T>::getTransform;
using IList<ImageGridData, T>::mSize;
using IList<ImageGridData, T>::mCursor;
using IList<ImageGridData, T>::Entry;
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:
using IList<ImageGridData, T>::size;
@ -694,10 +697,12 @@ void ImageGridComponent<T>::calcGridDimension()
mGridDimension = Vector2i(gridDimension.x(), Math::ceilf(gridDimension.y()));
// Grid dimension validation
if (mGridDimension.x() < 1)
if (mGridDimension.x() < 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";
}
// Add extra tiles to both sides : Add EXTRAITEMS before, EXTRAITEMS after
if (isVertical())

View file

@ -72,8 +72,9 @@ public:
mLeftArrow.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!";
}
mText.setSize(mSize.x() - mLeftArrow.getSize().x() -
mRightArrow.getSize().x(), mText.getFont()->getHeight());

View file

@ -31,14 +31,14 @@ public:
void setValue(const std::string& value) override;
bool input(InputConfig* config, Input input) override;
void render(const Transform4x4f& parentTrans);
void render(const Transform4x4f& parentTrans) override;
void onSizeChanged() override;
void setOpacity(unsigned char opacity) override;
// 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,
const std::string& element, unsigned int properties) override;

View file

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

View file

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

View file

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

View file

@ -34,7 +34,10 @@ protected:
using IList<TextListData, T>::getTransform;
using IList<TextListData, T>::mSize;
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:
using IList<TextListData, T>::size;
@ -87,9 +90,9 @@ public:
inline void setLineSpacing(float lineSpacing) { mLineSpacing = lineSpacing; }
protected:
virtual void onScroll() {
virtual void onScroll() override {
NavigationSounds::getInstance()->playThemeNavigationSound(SCROLLSOUND); }
virtual void onCursorChanged(const CursorState& state);
virtual void onCursorChanged(const CursorState& state) override;
private:
int mMarqueeOffset;

View file

@ -56,7 +56,7 @@ public:
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.
// 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.
// Can be set before or after a video is loaded.
// 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.
// Can be set before or after a video is loaded.
// 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:
// Calculates the correct mSize from our resizing information (set by setResize/setMaxSize).
// Used internally whenever the resizing parameters or texture change.
void resize();
// Start the video Immediately
virtual void startVideo();
virtual void startVideo() override;
// Stop the video
virtual void stopVideo();
virtual void stopVideo() override;
// Handle looping the video. Must be called periodically
virtual void handleLooping();
virtual void handleLooping() override;
void setupContext();
void freeContext();

View file

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

View file

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

View file

@ -18,8 +18,9 @@ namespace Renderer
{
const GLenum errorCode = glGetError();
if(errorCode != GL_NO_ERROR)
if(errorCode != GL_NO_ERROR) {
LOG(LogError) << "OpenGLES error: " << _funcName << " failed with error code: " << errorCode;
}
}
#else
#define GL_CHECK_ERROR(Function) (Function)
@ -246,8 +247,9 @@ namespace Renderer
// 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 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() << ")";
}
}
else
SDL_GL_SetSwapInterval(0);

View file

@ -555,12 +555,13 @@ float Font::getNewlineStartOffset(const std::string& text, const unsigned int& c
case ALIGN_LEFT:
return 0;
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 !=
std::string::npos ? endChar - charStart : endChar)).x()) / 2.0f;
}
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 !=
std::string::npos ? endChar - charStart : endChar)).x());
}

View file

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