diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 00000000..d3cc464f --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,19 @@ +version: 1.3.0.{build} +pull_requests: + do_not_increment_build_number: true +image: Visual Studio 2017 +cache: C:\Tools\vcpkg\installed\ +configuration: Release +install: +- cmd: cd C:\Tools\vcpkg\ && git pull +- cmd: .\bootstrap-vcpkg.bat +- cmd: vcpkg install assimp libepoxy sdl2 sdl2-mixer bullet3 tinyxml2 freeimage +before_build: +- cmd: cd C:\projects\radixengine +- cmd: git submodule init && git submodule update +- cmd: cmake -DCMAKE_TOOLCHAIN_FILE=C:/Tools/vcpkg/scripts/buildsystems/vcpkg.cmake . +build: + project: RadixEngine.sln + parallel: true + verbosity: normal +test: off diff --git a/.gitignore b/.gitignore index bed36afb..d1d63cd0 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ docs/ /Default /.* !.travis.yml +!.appveyor.yml /glPortal.* /build Debug/ diff --git a/.travis.yml b/.travis.yml index e9a2b6b7..b14713db 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,7 +30,7 @@ matrix: - git submodule update --init --recursive - mkdir build && cd build script: - - cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install .. + - cmake -DCMAKE_CXX_COMPILER=g++-5 -DCMAKE_C_COMPILER=gcc-5 -DCMAKE_BUILD_TYPE="Release" -DCMAKE_INSTALL_PREFIX=$PWD/install .. - make -j4 - os: osx osx_image: xcode8.3 diff --git a/CMakeLists.txt b/CMakeLists.txt index 41e20eb6..b66685ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,8 +15,8 @@ set(CMAKE_CXX_STANDARD 14) list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) -#### UTILITY #### +#### UTILITY #### set(RADIX_DEFINITIONS "") function(radix_add_exported_definition) add_definitions("-D${ARGV0}") @@ -24,8 +24,8 @@ function(radix_add_exported_definition) set(RADIX_DEFINITIONS "${RADIX_DEFINITIONS}" PARENT_SCOPE) endfunction(radix_add_exported_definition) -#### COMPILE-TIME SETTINGS #### +#### COMPILE-TIME SETTINGS #### set(RADIX_GL_LOADER "libepoxy" CACHE STRING "OpenGL loader to use. One of 'libepoxy', 'glad'") if ("${RADIX_GL_LOADER}" STREQUAL "libepoxy") @@ -37,14 +37,14 @@ if ("${RADIX_GL_LOADER}" STREQUAL "glad") radix_add_exported_definition("RADIX_GL_USE_GLAD") endif() -#### PLATFORM-SPECIFIC FIXES #### -if(DEFINED WIN32) +#### PLATFORM-SPECIFIC FIXES #### +if(WIN32) add_definitions("-D_USE_MATH_DEFINES") endif() -#### LIBRARIES #### +#### LIBRARIES #### set(RADIX_INCLUDE_DIRS "") find_package(OpenGL REQUIRED) @@ -53,10 +53,10 @@ list(APPEND RADIX_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/external/stx/include) set(RADIX_LIBRARIES ${OPENGL_gl_LIBRARY}) -find_package(PkgConfig REQUIRED) +find_package(PkgConfig) if (RADIX_GL_USE_LIBEPOXY) - pkg_search_module(EPOXY REQUIRED epoxy) + find_package(EPOXY REQUIRED) list(APPEND RADIX_INCLUDE_DIRS ${EPOXY_INCLUDE_DIRS}) list(APPEND RADIX_LIBRARIES ${EPOXY_LIBRARIES}) elseif (RADIX_GL_USE_GLAD) @@ -104,24 +104,28 @@ find_package(FreeImage REQUIRED) list(APPEND RADIX_INCLUDE_DIRS ${FREEIMAGE_INCLUDE_DIR}) list(APPEND RADIX_LIBRARIES ${FREEIMAGE_LIBRARIES}) +set(RADIX_ENABLE_PROFILER OFF CACHE BOOL "Enable Radix's profiler") find_package(easy_profiler REQUIRED) list(APPEND RADIX_INCLUDE_DIRS ${EASY_PROFILER_INCLUDE_DIR}) -set(RADIX_ENABLE_PROFILER ON CACHE BOOL "Enable Radix's profiler") if (RADIX_ENABLE_PROFILER) list(APPEND RADIX_LIBRARIES ${EASY_PROFILER_LIBRARIES}) else () radix_add_exported_definition("DISABLE_EASY_PROFILER") endif () + set(PORTAL_TEST_LIBRARIES ${RADIX_LIBRARIES}) list(APPEND RADIX_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/external/serine/include") -#### ENGINE #### +#### ENGINE #### if (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") add_definitions("-Wall") endif () +if (WIN32) + add_definitions("/w") +endif () find_package(RadixEntity REQUIRED) list(APPEND RADIX_INCLUDE_DIRS ${RADIXENTITY_INCLUDE_DIR}) @@ -148,8 +152,8 @@ if (RADIX_EXPORT_CMAKE_PACKAGE_VARS) set(RADIX_DEFINITIONS "${RADIX_DEFINITIONS}" PARENT_SCOPE) endif () -#### UNIT TESTING #### +#### UNIT TESTING #### include_directories(${RADIX_INCLUDE_DIRS} ${UnitTestPlusPlus_INCLUDE_DIRS}) enable_testing() add_subdirectory(tests) diff --git a/cmake/FindAssimp.cmake b/cmake/FindAssimp.cmake index 3b3ea473..ce3a27f4 100644 --- a/cmake/FindAssimp.cmake +++ b/cmake/FindAssimp.cmake @@ -11,12 +11,18 @@ FIND_PATH( ASSIMP_INCLUDE_DIR assimp/mesh.h /opt/local/include ) -FIND_LIBRARY( ASSIMP_LIBRARY assimp - /usr/lib64 - /usr/lib - /usr/local/lib - /opt/local/lib -) +IF(WIN32) + FIND_LIBRARY( ASSIMP_LIBRARY assimp-vc140-mt + lib + ) +ELSE(WIN32) + FIND_LIBRARY( ASSIMP_LIBRARY assimp + /usr/lib64 + /usr/lib + /usr/local/lib + /opt/local/lib + ) +ENDIF(WIN32) IF(ASSIMP_INCLUDE_DIR AND ASSIMP_LIBRARY) SET( ASSIMP_FOUND TRUE ) @@ -27,6 +33,6 @@ ENDIF(ASSIMP_INCLUDE_DIR AND ASSIMP_LIBRARY) # handle REQUIRED and QUIET options include ( FindPackageHandleStandardArgs ) -find_package_handle_standard_args ( Assimp +find_package_handle_standard_args ( Assimp REQUIRED_VARS ASSIMP_LIBRARY ASSIMP_INCLUDE_DIR -) \ No newline at end of file +) diff --git a/cmake/FindEPOXY.cmake b/cmake/FindEPOXY.cmake new file mode 100644 index 00000000..11fba04b --- /dev/null +++ b/cmake/FindEPOXY.cmake @@ -0,0 +1,17 @@ +# Copyright (c) 2015 Andrew Kelley +# This file is MIT licensed. +# See http://opensource.org/licenses/MIT + +# This module defines +# EPOXY_FOUND +# EPOXY_INCLUDE_DIR +# EPOXY_LIBRARY + +find_path(EPOXY_INCLUDE_DIR NAMES epoxy/gl.h epoxy/glx.h) + +find_library(EPOXY_LIBRARY NAMES epoxy) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(EPOXY DEFAULT_MSG EPOXY_LIBRARY EPOXY_INCLUDE_DIR) + +mark_as_advanced(EPOXY_INCLUDE_DIR EPOXY_LIBRARY) \ No newline at end of file diff --git a/external/easy_profiler b/external/easy_profiler index 86f2ff0c..5e632bed 160000 --- a/external/easy_profiler +++ b/external/easy_profiler @@ -1 +1 @@ -Subproject commit 86f2ff0c71650c17e48e5c0b20ade0a4baa0e702 +Subproject commit 5e632bedee27f627ce3f612c82b5ab1eb4673962 diff --git a/external/vhacd-lib b/external/vhacd-lib index 1800c263..6faccd26 160000 --- a/external/vhacd-lib +++ b/external/vhacd-lib @@ -1 +1 @@ -Subproject commit 1800c2639dc293230300b8bb47daa9c045a07f85 +Subproject commit 6faccd26fda1f884f2f7eeb15d31f763f5168046 diff --git a/include/radix/util/Profiling.hpp b/include/radix/util/Profiling.hpp index 226819a4..9b75770c 100644 --- a/include/radix/util/Profiling.hpp +++ b/include/radix/util/Profiling.hpp @@ -1,3 +1,4 @@ + #ifndef RADIX_UTIL_PROFILING_HPP #define RADIX_UTIL_PROFILING_HPP @@ -14,3 +15,4 @@ #define PROFILER_MAIN_THREAD EASY_MAIN_THREAD #endif /* RADIX_UTIL_PROFILING_HPP */ + diff --git a/include/radix/util/SimpleOpt.h b/include/radix/util/SimpleOpt.h new file mode 100644 index 00000000..1289a923 --- /dev/null +++ b/include/radix/util/SimpleOpt.h @@ -0,0 +1,1045 @@ +/*! @file SimpleOpt.h + + @version 3.6 + + @brief A cross-platform command line library which can parse almost any + of the standard command line formats in use today. It is designed + explicitly to be portable to any platform and has been tested on Windows + and Linux. See CSimpleOptTempl for the class definition. + + @section features FEATURES + - MIT Licence allows free use in all software (including GPL + and commercial) + - multi-platform (Windows 95/98/ME/NT/2K/XP, Linux, Unix) + - supports all lengths of option names: + +
- + switch character only (e.g. use stdin for input) +
-o + short (single character) +
-long + long (multiple character, single switch character) +
--longer + long (multiple character, multiple switch characters) +
+ - supports all types of arguments for options: + +
--option + short/long option flag (no argument) +
--option ARG + short/long option with separate required argument +
--option=ARG + short/long option with combined required argument +
--option[=ARG] + short/long option with combined optional argument +
-oARG + short option with combined required argument +
-o[ARG] + short option with combined optional argument +
+ - supports options with multiple or variable numbers of arguments: + +
--multi ARG1 ARG2 + Multiple arguments +
--multi N ARG-1 ARG-2 ... ARG-N + Variable number of arguments +
+ - supports case-insensitive option matching on short, long and/or + word arguments. + - supports options which do not use a switch character. i.e. a special + word which is construed as an option. + e.g. "foo.exe open /directory/file.txt" + - supports clumping of multiple short options (no arguments) in a string + e.g. "foo.exe -abcdef file1" <==> "foo.exe -a -b -c -d -e -f file1" + - automatic recognition of a single slash as equivalent to a single + hyphen on Windows, e.g. "/f FILE" is equivalent to "-f FILE". + - file arguments can appear anywhere in the argument list: + "foo.exe file1.txt -a ARG file2.txt --flag file3.txt file4.txt" + files will be returned to the application in the same order they were + supplied on the command line + - short-circuit option matching: "--man" will match "--mandate" + invalid options can be handled while continuing to parse the command + line valid options list can be changed dynamically during command line + processing, i.e. accept different options depending on an option + supplied earlier in the command line. + - implemented with only a single C++ header file + - optionally use no C runtime or OS functions + - char, wchar_t and Windows TCHAR in the same program + - complete working examples included + - compiles cleanly at warning level 4 (Windows/VC.NET 2003), warning + level 3 (Windows/VC6) and -Wall (Linux/gcc) + + @section usage USAGE + The SimpleOpt class is used by following these steps: +
    +
  1. Include the SimpleOpt.h header file +
    +        \#include "SimpleOpt.h"
    +        
    +
  2. Define an array of valid options for your program. +
    +@link CSimpleOptTempl::SOption CSimpleOpt::SOption @endlink g_rgOptions[] = {
    +    { OPT_FLAG, _T("-a"),     SO_NONE    }, // "-a"
    +    { OPT_FLAG, _T("-b"),     SO_NONE    }, // "-b"
    +    { OPT_ARG,  _T("-f"),     SO_REQ_SEP }, // "-f ARG"
    +    { OPT_HELP, _T("-?"),     SO_NONE    }, // "-?"
    +    { OPT_HELP, _T("--help"), SO_NONE    }, // "--help"
    +    SO_END_OF_OPTIONS                       // END
    +};
    +
    + Note that all options must start with a hyphen even if the slash will + be accepted. This is because the slash character is automatically + converted into a hyphen to test against the list of options. + For example, the following line matches both "-?" and "/?" + (on Windows). +
    +    { OPT_HELP, _T("-?"),     SO_NONE    }, // "-?"
    +
    +
  3. Instantiate a CSimpleOpt object supplying argc, argv and the option + table +
    +@link CSimpleOptTempl CSimpleOpt @endlink args(argc, argv, g_rgOptions);
    +
    +
  4. Process the arguments by calling Next() until it returns false. + On each call, first check for an error by calling LastError(), then + either handle the error or process the argument. +
    +while (args.Next()) {
    +    if (args.LastError() == SO_SUCCESS) {
    +        handle option: use OptionId(), OptionText() and OptionArg()
    +    }
    +    else {
    +        handle error: see ESOError enums
    +    }
    +}
    +
    +
  5. Process all non-option arguments with File(), Files() and FileCount() +
    +ShowFiles(args.FileCount(), args.Files());
    +
    +
+ + @section notes NOTES + - In MBCS mode, this library is guaranteed to work correctly only when + all option names use only ASCII characters. + - Note that if case-insensitive matching is being used then the first + matching option in the argument list will be returned. + + @section licence MIT LICENCE +
+    The licence text below is the boilerplate "MIT Licence" used from:
+    http://www.opensource.org/licenses/mit-license.php
+
+    Copyright (c) 2006-2013, Brodie Thiesfield
+
+    Permission is hereby granted, free of charge, to any person obtaining a
+    copy of this software and associated documentation files (the "Software"),
+    to deal in the Software without restriction, including without limitation
+    the rights to use, copy, modify, merge, publish, distribute, sublicense,
+    and/or sell copies of the Software, and to permit persons to whom the
+    Software is furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be included
+    in all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
+    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
+    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 
+    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
+    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 
+    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ + @mainpage + + +
Library SimpleOpt +
Author Brodie Thiesfield [code at jellycan dot com] +
Source https://github.com/brofield/simpleopt +
+ + @section SimpleOpt SimpleOpt + + A cross-platform library providing a simple method to parse almost any of + the standard command-line formats in use today. + + See the @link SimpleOpt.h SimpleOpt @endlink documentation for full + details. + + @section SimpleGlob SimpleGlob + + A cross-platform file globbing library providing the ability to + expand wildcards in command-line arguments to a list of all matching + files. + + See the @link SimpleGlob.h SimpleGlob @endlink documentation for full + details. +*/ + +#ifndef INCLUDED_SimpleOpt +#define INCLUDED_SimpleOpt + +// Default the max arguments to a fixed value. If you want to be able to +// handle any number of arguments, then predefine this to 0 and it will +// use an internal dynamically allocated buffer instead. +#ifdef SO_MAX_ARGS +# define SO_STATICBUF SO_MAX_ARGS +#else +# include // malloc, free +# include // memcpy +# define SO_STATICBUF 50 +#endif + +//! Error values +typedef enum _ESOError +{ + //! No error + SO_SUCCESS = 0, + + /*! It looks like an option (it starts with a switch character), but + it isn't registered in the option table. */ + SO_OPT_INVALID = -1, + + /*! Multiple options matched the supplied option text. + Only returned when NOT using SO_O_EXACT. */ + SO_OPT_MULTIPLE = -2, + + /*! Option doesn't take an argument, but a combined argument was + supplied. */ + SO_ARG_INVALID = -3, + + /*! SO_REQ_CMB style-argument was supplied to a SO_REQ_SEP option + Only returned when using SO_O_PEDANTIC. */ + SO_ARG_INVALID_TYPE = -4, + + //! Required argument was not supplied + SO_ARG_MISSING = -5, + + /*! Option argument looks like another option. + Only returned when NOT using SO_O_NOERR. */ + SO_ARG_INVALID_DATA = -6 +} ESOError; + +//! Option flags +enum _ESOFlags +{ + /*! Disallow partial matching of option names */ + SO_O_EXACT = 0x0001, + + /*! Disallow use of slash as an option marker on Windows. + Un*x only ever recognizes a hyphen. */ + SO_O_NOSLASH = 0x0002, + + /*! Permit arguments on single letter options with no equals sign. + e.g. -oARG or -o[ARG] */ + SO_O_SHORTARG = 0x0004, + + /*! Permit single character options to be clumped into a single + option string. e.g. "-a -b -c" <==> "-abc" */ + SO_O_CLUMP = 0x0008, + + /*! Process the entire argv array for options, including the + argv[0] entry. */ + SO_O_USEALL = 0x0010, + + /*! Do not generate an error for invalid options. errors for missing + arguments will still be generated. invalid options will be + treated as files. invalid options in clumps will be silently + ignored. */ + SO_O_NOERR = 0x0020, + + /*! Validate argument type pedantically. Return an error when a + separated argument "-opt arg" is supplied by the user as a + combined argument "-opt=arg". By default this is not considered + an error. */ + SO_O_PEDANTIC = 0x0040, + + /*! Case-insensitive comparisons for short arguments */ + SO_O_ICASE_SHORT = 0x0100, + + /*! Case-insensitive comparisons for long arguments */ + SO_O_ICASE_LONG = 0x0200, + + /*! Case-insensitive comparisons for word arguments + i.e. arguments without any hyphens at the start. */ + SO_O_ICASE_WORD = 0x0400, + + /*! Case-insensitive comparisons for all arg types */ + SO_O_ICASE = 0x0700 +}; + +/*! Types of arguments that options may have. Note that some of the _ESOFlags + are not compatible with all argument types. SO_O_SHORTARG requires that + relevant options use either SO_REQ_CMB or SO_OPT. SO_O_CLUMP requires + that relevant options use only SO_NONE. + */ +typedef enum _ESOArgType { + /*! No argument. Just the option flags. + e.g. -o --opt */ + SO_NONE, + + /*! Required separate argument. + e.g. -o ARG --opt ARG */ + SO_REQ_SEP, + + /*! Required combined argument. + e.g. -oARG -o=ARG --opt=ARG */ + SO_REQ_CMB, + + /*! Optional combined argument. + e.g. -o[ARG] -o[=ARG] --opt[=ARG] */ + SO_OPT, + + /*! Multiple separate arguments. The actual number of arguments is + determined programatically at the time the argument is processed. + e.g. -o N ARG1 ARG2 ... ARGN --opt N ARG1 ARG2 ... ARGN */ + SO_MULTI +} ESOArgType; + +//! this option definition must be the last entry in the table +#define SO_END_OF_OPTIONS { -1, NULL, SO_NONE } + +#ifdef _DEBUG +# ifdef _MSC_VER +# include +# define SO_ASSERT(b) _ASSERTE(b) +# else +# include +# define SO_ASSERT(b) assert(b) +# endif +#else +# define SO_ASSERT(b) //!< assertion used to test input data +#endif + +// --------------------------------------------------------------------------- +// MAIN TEMPLATE CLASS +// --------------------------------------------------------------------------- + +/*! @brief Implementation of the SimpleOpt class */ +template +class CSimpleOptTempl +{ +public: + /*! @brief Structure used to define all known options. */ + struct SOption { + /*! ID to return for this flag. Optional but must be >= 0 */ + int nId; + + /*! arg string to search for, e.g. "open", "-", "-f", "--file" + Note that on Windows the slash option marker will be converted + to a hyphen so that "-f" will also match "/f". */ + const SOCHAR * pszArg; + + /*! type of argument accepted by this option */ + ESOArgType nArgType; + }; + + /*! @brief Initialize the class. Init() must be called later. */ + CSimpleOptTempl() + : m_rgShuffleBuf(NULL) + { + Init(0, NULL, NULL, 0); + } + + /*! @brief Initialize the class in preparation for use. */ + CSimpleOptTempl( + int argc, + SOCHAR * argv[], + const SOption * a_rgOptions, + int a_nFlags = 0 + ) + : m_rgShuffleBuf(NULL) + { + Init(argc, argv, a_rgOptions, a_nFlags); + } + +#ifndef SO_MAX_ARGS + /*! @brief Deallocate any allocated memory. */ + ~CSimpleOptTempl() { if (m_rgShuffleBuf) free(m_rgShuffleBuf); } +#endif + + /*! @brief Initialize the class in preparation for calling Next. + + The table of options pointed to by a_rgOptions does not need to be + valid at the time that Init() is called. However on every call to + Next() the table pointed to must be a valid options table with the + last valid entry set to SO_END_OF_OPTIONS. + + NOTE: the array pointed to by a_argv will be modified by this + class and must not be used or modified outside of member calls to + this class. + + @param a_argc Argument array size + @param a_argv Argument array + @param a_rgOptions Valid option array + @param a_nFlags Optional flags to modify the processing of + the arguments + + @return true Successful + @return false if SO_MAX_ARGC > 0: Too many arguments + if SO_MAX_ARGC == 0: Memory allocation failure + */ + bool Init( + int a_argc, + SOCHAR * a_argv[], + const SOption * a_rgOptions, + int a_nFlags = 0 + ); + + /*! @brief Change the current options table during option parsing. + + @param a_rgOptions Valid option array + */ + inline void SetOptions(const SOption * a_rgOptions) { + m_rgOptions = a_rgOptions; + } + + /*! @brief Change the current flags during option parsing. + + Note that changing the SO_O_USEALL flag here will have no affect. + It must be set using Init() or the constructor. + + @param a_nFlags Flags to modify the processing of the arguments + */ + inline void SetFlags(int a_nFlags) { m_nFlags = a_nFlags; } + + /*! @brief Query if a particular flag is set */ + inline bool HasFlag(int a_nFlag) const { + return (m_nFlags & a_nFlag) == a_nFlag; + } + + /*! @brief Advance to the next option if available. + + When all options have been processed it will return false. When true + has been returned, you must check for an invalid or unrecognized + option using the LastError() method. This will be return an error + value other than SO_SUCCESS on an error. All standard data + (e.g. OptionText(), OptionArg(), OptionId(), etc) will be available + depending on the error. + + After all options have been processed, the remaining files from the + command line can be processed in same order as they were passed to + the program. + + @return true option or error available for processing + @return false all options have been processed + */ + bool Next(); + + /*! Stops processing of the command line and returns all remaining + arguments as files. The next call to Next() will return false. + */ + void Stop(); + + /*! @brief Return the last error that occurred. + + This function must always be called before processing the current + option. This function is available only when Next() has returned true. + */ + inline ESOError LastError() const { return m_nLastError; } + + /*! @brief Return the nId value from the options array for the current + option. + + This function is available only when Next() has returned true. + */ + inline int OptionId() const { return m_nOptionId; } + + /*! @brief Return the pszArg from the options array for the current + option. + + This function is available only when Next() has returned true. + */ + inline const SOCHAR * OptionText() const { return m_pszOptionText; } + + /*! @brief Return the argument for the current option where one exists. + + If there is no argument for the option, this will return NULL. + This function is available only when Next() has returned true. + */ + inline SOCHAR * OptionArg() const { return m_pszOptionArg; } + + /*! @brief Validate and return the desired number of arguments. + + This is only valid when OptionId() has return the ID of an option + that is registered as SO_MULTI. It may be called multiple times + each time returning the desired number of arguments. Previously + returned argument pointers are remain valid. + + If an error occurs during processing, NULL will be returned and + the error will be available via LastError(). + + @param n Number of arguments to return. + */ + SOCHAR ** MultiArg(int n); + + /*! @brief Returned the number of entries in the Files() array. + + After Next() has returned false, this will be the list of files (or + otherwise unprocessed arguments). + */ + inline int FileCount() const { return m_argc - m_nLastArg; } + + /*! @brief Return the specified file argument. + + @param n Index of the file to return. This must be between 0 + and FileCount() - 1; + */ + inline SOCHAR * File(int n) const { + SO_ASSERT(n >= 0 && n < FileCount()); + return m_argv[m_nLastArg + n]; + } + + /*! @brief Return the array of files. */ + inline SOCHAR ** Files() const { return &m_argv[m_nLastArg]; } + +private: + CSimpleOptTempl(const CSimpleOptTempl &); // disabled + CSimpleOptTempl & operator=(const CSimpleOptTempl &); // disabled + + SOCHAR PrepareArg(SOCHAR * a_pszString) const; + bool NextClumped(); + void ShuffleArg(int a_nStartIdx, int a_nCount); + int LookupOption(const SOCHAR * a_pszOption) const; + int CalcMatch(const SOCHAR *a_pszSource, const SOCHAR *a_pszTest) const; + + // Find the '=' character within a string. + inline SOCHAR * FindEquals(SOCHAR *s) const { + while (*s && *s != (SOCHAR)'=') ++s; + return *s ? s : NULL; + } + bool IsEqual(SOCHAR a_cLeft, SOCHAR a_cRight, int a_nArgType) const; + + inline void Copy(SOCHAR ** ppDst, SOCHAR ** ppSrc, int nCount) const { +#ifdef SO_MAX_ARGS + // keep our promise of no CLIB usage + while (nCount-- > 0) *ppDst++ = *ppSrc++; +#else + memcpy(ppDst, ppSrc, nCount * sizeof(SOCHAR*)); +#endif + } + +private: + const SOption * m_rgOptions; //!< pointer to options table + int m_nFlags; //!< flags + int m_nOptionIdx; //!< current argv option index + int m_nOptionId; //!< id of current option (-1 = invalid) + int m_nNextOption; //!< index of next option + int m_nLastArg; //!< last argument, after this are files + int m_argc; //!< argc to process + SOCHAR ** m_argv; //!< argv + const SOCHAR * m_pszOptionText; //!< curr option text, e.g. "-f" + SOCHAR * m_pszOptionArg; //!< curr option arg, e.g. "c:\file.txt" + SOCHAR * m_pszClump; //!< clumped single character options + SOCHAR m_szShort[3]; //!< temp for clump and combined args + ESOError m_nLastError; //!< error status from the last call + SOCHAR ** m_rgShuffleBuf; //!< shuffle buffer for large argc +}; + +// --------------------------------------------------------------------------- +// IMPLEMENTATION +// --------------------------------------------------------------------------- + +template +bool +CSimpleOptTempl::Init( + int a_argc, + SOCHAR * a_argv[], + const SOption * a_rgOptions, + int a_nFlags + ) +{ + m_argc = a_argc; + m_nLastArg = a_argc; + m_argv = a_argv; + m_rgOptions = a_rgOptions; + m_nLastError = SO_SUCCESS; + m_nOptionIdx = 0; + m_nOptionId = -1; + m_pszOptionText = NULL; + m_pszOptionArg = NULL; + m_nNextOption = (a_nFlags & SO_O_USEALL) ? 0 : 1; + m_szShort[0] = (SOCHAR)'-'; + m_szShort[2] = (SOCHAR)'\0'; + m_nFlags = a_nFlags; + m_pszClump = NULL; + +#ifdef SO_MAX_ARGS + if (m_argc > SO_MAX_ARGS) { + m_nLastError = SO_ARG_INVALID_DATA; + m_nLastArg = 0; + return false; + } +#else + if (m_rgShuffleBuf) { + free(m_rgShuffleBuf); + } + if (m_argc > SO_STATICBUF) { + m_rgShuffleBuf = (SOCHAR**) malloc(sizeof(SOCHAR*) * m_argc); + if (!m_rgShuffleBuf) { + return false; + } + } +#endif + + return true; +} + +template +bool +CSimpleOptTempl::Next() +{ +#ifdef SO_MAX_ARGS + if (m_argc > SO_MAX_ARGS) { + SO_ASSERT(!"Too many args! Check the return value of Init()!"); + return false; + } +#endif + + // process a clumped option string if appropriate + if (m_pszClump && *m_pszClump) { + // silently discard invalid clumped option + bool bIsValid = NextClumped(); + while (*m_pszClump && !bIsValid && HasFlag(SO_O_NOERR)) { + bIsValid = NextClumped(); + } + + // return this option if valid or we are returning errors + if (bIsValid || !HasFlag(SO_O_NOERR)) { + return true; + } + } + SO_ASSERT(!m_pszClump || !*m_pszClump); + m_pszClump = NULL; + + // init for the next option + m_nOptionIdx = m_nNextOption; + m_nOptionId = -1; + m_pszOptionText = NULL; + m_pszOptionArg = NULL; + m_nLastError = SO_SUCCESS; + + // find the next option + SOCHAR cFirst; + int nTableIdx = -1; + int nOptIdx = m_nOptionIdx; + while (nTableIdx < 0 && nOptIdx < m_nLastArg) { + SOCHAR * pszArg = m_argv[nOptIdx]; + m_pszOptionArg = NULL; + + // find this option in the options table + cFirst = PrepareArg(pszArg); + if (pszArg[0] == (SOCHAR)'-') { + // find any combined argument string and remove equals sign + m_pszOptionArg = FindEquals(pszArg); + if (m_pszOptionArg) { + *m_pszOptionArg++ = (SOCHAR)'\0'; + } + } + nTableIdx = LookupOption(pszArg); + + // if we didn't find this option but if it is a short form + // option then we try the alternative forms + if (nTableIdx < 0 + && !m_pszOptionArg + && pszArg[0] == (SOCHAR)'-' + && pszArg[1] + && pszArg[1] != (SOCHAR)'-' + && pszArg[2]) + { + // test for a short-form with argument if appropriate + if (HasFlag(SO_O_SHORTARG)) { + m_szShort[1] = pszArg[1]; + int nIdx = LookupOption(m_szShort); + if (nIdx >= 0 + && (m_rgOptions[nIdx].nArgType == SO_REQ_CMB + || m_rgOptions[nIdx].nArgType == SO_OPT)) + { + m_pszOptionArg = &pszArg[2]; + pszArg = m_szShort; + nTableIdx = nIdx; + } + } + + // test for a clumped short-form option string and we didn't + // match on the short-form argument above + if (nTableIdx < 0 && HasFlag(SO_O_CLUMP)) { + m_pszClump = &pszArg[1]; + ++m_nNextOption; + if (nOptIdx > m_nOptionIdx) { + ShuffleArg(m_nOptionIdx, nOptIdx - m_nOptionIdx); + } + return Next(); + } + } + + // The option wasn't found. If it starts with a switch character + // and we are not suppressing errors for invalid options then it + // is reported as an error, otherwise it is data. + if (nTableIdx < 0) { + if (!HasFlag(SO_O_NOERR) && pszArg[0] == (SOCHAR)'-') { + m_pszOptionText = pszArg; + break; + } + + pszArg[0] = cFirst; + ++nOptIdx; + if (m_pszOptionArg) { + *(--m_pszOptionArg) = (SOCHAR)'='; + } + } + } + + // end of options + if (nOptIdx >= m_nLastArg) { + if (nOptIdx > m_nOptionIdx) { + ShuffleArg(m_nOptionIdx, nOptIdx - m_nOptionIdx); + } + return false; + } + ++m_nNextOption; + + // get the option id + ESOArgType nArgType = SO_NONE; + if (nTableIdx < 0) { + m_nLastError = (ESOError) nTableIdx; // error code + } + else { + m_nOptionId = m_rgOptions[nTableIdx].nId; + m_pszOptionText = m_rgOptions[nTableIdx].pszArg; + + // ensure that the arg type is valid + nArgType = m_rgOptions[nTableIdx].nArgType; + switch (nArgType) { + case SO_NONE: + if (m_pszOptionArg) { + m_nLastError = SO_ARG_INVALID; + } + break; + + case SO_REQ_SEP: + if (m_pszOptionArg) { + // they wanted separate args, but we got a combined one, + // unless we are pedantic, just accept it. + if (HasFlag(SO_O_PEDANTIC)) { + m_nLastError = SO_ARG_INVALID_TYPE; + } + } + // more processing after we shuffle + break; + + case SO_REQ_CMB: + if (!m_pszOptionArg) { + m_nLastError = SO_ARG_MISSING; + } + break; + + case SO_OPT: + // nothing to do + break; + + case SO_MULTI: + // nothing to do. Caller must now check for valid arguments + // using GetMultiArg() + break; + } + } + + // shuffle the files out of the way + if (nOptIdx > m_nOptionIdx) { + ShuffleArg(m_nOptionIdx, nOptIdx - m_nOptionIdx); + } + + // we need to return the separate arg if required, just re-use the + // multi-arg code because it all does the same thing + if ( nArgType == SO_REQ_SEP + && !m_pszOptionArg + && m_nLastError == SO_SUCCESS) + { + SOCHAR ** ppArgs = MultiArg(1); + if (ppArgs) { + m_pszOptionArg = *ppArgs; + } + } + + return true; +} + +template +void +CSimpleOptTempl::Stop() +{ + if (m_nNextOption < m_nLastArg) { + ShuffleArg(m_nNextOption, m_nLastArg - m_nNextOption); + } +} + +template +SOCHAR +CSimpleOptTempl::PrepareArg( + SOCHAR * a_pszString + ) const +{ +#ifdef _WIN32 + // On Windows we can accept the forward slash as a single character + // option delimiter, but it cannot replace the '-' option used to + // denote stdin. On Un*x paths may start with slash so it may not + // be used to start an option. + if (!HasFlag(SO_O_NOSLASH) + && a_pszString[0] == (SOCHAR)'/' + && a_pszString[1] + && a_pszString[1] != (SOCHAR)'-') + { + a_pszString[0] = (SOCHAR)'-'; + return (SOCHAR)'/'; + } +#endif + return a_pszString[0]; +} + +template +bool +CSimpleOptTempl::NextClumped() +{ + // prepare for the next clumped option + m_szShort[1] = *m_pszClump++; + m_nOptionId = -1; + m_pszOptionText = NULL; + m_pszOptionArg = NULL; + m_nLastError = SO_SUCCESS; + + // lookup this option, ensure that we are using exact matching + int nSavedFlags = m_nFlags; + m_nFlags = SO_O_EXACT; + int nTableIdx = LookupOption(m_szShort); + m_nFlags = nSavedFlags; + + // unknown option + if (nTableIdx < 0) { + m_pszOptionText = m_szShort; // invalid option + m_nLastError = (ESOError) nTableIdx; // error code + return false; + } + + // valid option + m_pszOptionText = m_rgOptions[nTableIdx].pszArg; + ESOArgType nArgType = m_rgOptions[nTableIdx].nArgType; + if (nArgType == SO_NONE) { + m_nOptionId = m_rgOptions[nTableIdx].nId; + return true; + } + + if (nArgType == SO_REQ_CMB && *m_pszClump) { + m_nOptionId = m_rgOptions[nTableIdx].nId; + m_pszOptionArg = m_pszClump; + while (*m_pszClump) ++m_pszClump; // must point to an empty string + return true; + } + + // invalid option as it requires an argument + m_nLastError = SO_ARG_MISSING; + return true; +} + +// Shuffle arguments to the end of the argv array. +// +// For example: +// argv[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8" }; +// +// ShuffleArg(1, 1) = { "0", "2", "3", "4", "5", "6", "7", "8", "1" }; +// ShuffleArg(5, 2) = { "0", "1", "2", "3", "4", "7", "8", "5", "6" }; +// ShuffleArg(2, 4) = { "0", "1", "6", "7", "8", "2", "3", "4", "5" }; +template +void +CSimpleOptTempl::ShuffleArg( + int a_nStartIdx, + int a_nCount + ) +{ + SOCHAR * staticBuf[SO_STATICBUF]; + SOCHAR ** buf = m_rgShuffleBuf ? m_rgShuffleBuf : staticBuf; + int nTail = m_argc - a_nStartIdx - a_nCount; + + // make a copy of the elements to be moved + Copy(buf, m_argv + a_nStartIdx, a_nCount); + + // move the tail down + Copy(m_argv + a_nStartIdx, m_argv + a_nStartIdx + a_nCount, nTail); + + // append the moved elements to the tail + Copy(m_argv + a_nStartIdx + nTail, buf, a_nCount); + + // update the index of the last unshuffled arg + m_nLastArg -= a_nCount; +} + +// match on the long format strings. partial matches will be +// accepted only if that feature is enabled. +template +int +CSimpleOptTempl::LookupOption( + const SOCHAR * a_pszOption + ) const +{ + int nBestMatch = -1; // index of best match so far + int nBestMatchLen = 0; // matching characters of best match + int nLastMatchLen = 0; // matching characters of last best match + + for (int n = 0; m_rgOptions[n].nId >= 0; ++n) { + // the option table must use hyphens as the option character, + // the slash character is converted to a hyphen for testing. + SO_ASSERT(m_rgOptions[n].pszArg[0] != (SOCHAR)'/'); + + int nMatchLen = CalcMatch(m_rgOptions[n].pszArg, a_pszOption); + if (nMatchLen == -1) { + return n; + } + if (nMatchLen > 0 && nMatchLen >= nBestMatchLen) { + nLastMatchLen = nBestMatchLen; + nBestMatchLen = nMatchLen; + nBestMatch = n; + } + } + + // only partial matches or no match gets to here, ensure that we + // don't return a partial match unless it is a clear winner + if (HasFlag(SO_O_EXACT) || nBestMatch == -1) { + return SO_OPT_INVALID; + } + return (nBestMatchLen > nLastMatchLen) ? nBestMatch : SO_OPT_MULTIPLE; +} + +// calculate the number of characters that match (case-sensitive) +// 0 = no match, > 0 == number of characters, -1 == perfect match +template +int +CSimpleOptTempl::CalcMatch( + const SOCHAR * a_pszSource, + const SOCHAR * a_pszTest + ) const +{ + if (!a_pszSource || !a_pszTest) { + return 0; + } + + // determine the argument type + int nArgType = SO_O_ICASE_LONG; + if (a_pszSource[0] != '-') { + nArgType = SO_O_ICASE_WORD; + } + else if (a_pszSource[1] != '-' && !a_pszSource[2]) { + nArgType = SO_O_ICASE_SHORT; + } + + // match and skip leading hyphens + while (*a_pszSource == (SOCHAR)'-' && *a_pszSource == *a_pszTest) { + ++a_pszSource; + ++a_pszTest; + } + if (*a_pszSource == (SOCHAR)'-' || *a_pszTest == (SOCHAR)'-') { + return 0; + } + + // find matching number of characters in the strings + int nLen = 0; + while (*a_pszSource && IsEqual(*a_pszSource, *a_pszTest, nArgType)) { + ++a_pszSource; + ++a_pszTest; + ++nLen; + } + + // if we have exhausted the source... + if (!*a_pszSource) { + // and the test strings, then it's a perfect match + if (!*a_pszTest) { + return -1; + } + + // otherwise the match failed as the test is longer than + // the source. i.e. "--mant" will not match the option "--man". + return 0; + } + + // if we haven't exhausted the test string then it is not a match + // i.e. "--mantle" will not best-fit match to "--mandate" at all. + if (*a_pszTest) { + return 0; + } + + // partial match to the current length of the test string + return nLen; +} + +template +bool +CSimpleOptTempl::IsEqual( + SOCHAR a_cLeft, + SOCHAR a_cRight, + int a_nArgType + ) const +{ + // if this matches then we are doing case-insensitive matching + if (m_nFlags & a_nArgType) { + if (a_cLeft >= 'A' && a_cLeft <= 'Z') a_cLeft += 'a' - 'A'; + if (a_cRight >= 'A' && a_cRight <= 'Z') a_cRight += 'a' - 'A'; + } + return a_cLeft == a_cRight; +} + +// calculate the number of characters that match (case-sensitive) +// 0 = no match, > 0 == number of characters, -1 == perfect match +template +SOCHAR ** +CSimpleOptTempl::MultiArg( + int a_nCount + ) +{ + // ensure we have enough arguments + if (m_nNextOption + a_nCount > m_nLastArg) { + m_nLastError = SO_ARG_MISSING; + return NULL; + } + + // our argument array + SOCHAR ** rgpszArg = &m_argv[m_nNextOption]; + + // Ensure that each of the following don't start with an switch character. + // Only make this check if we are returning errors for unknown arguments. + if (!HasFlag(SO_O_NOERR)) { + for (int n = 0; n < a_nCount; ++n) { + SOCHAR ch = PrepareArg(rgpszArg[n]); + if (rgpszArg[n][0] == (SOCHAR)'-') { + rgpszArg[n][0] = ch; + m_nLastError = SO_ARG_INVALID_DATA; + return NULL; + } + rgpszArg[n][0] = ch; + } + } + + // all good + m_nNextOption += a_nCount; + return rgpszArg; +} + + +// --------------------------------------------------------------------------- +// TYPE DEFINITIONS +// --------------------------------------------------------------------------- + +/*! @brief ASCII/MBCS version of CSimpleOpt */ +typedef CSimpleOptTempl CSimpleOptA; + +/*! @brief wchar_t version of CSimpleOpt */ +typedef CSimpleOptTempl CSimpleOptW; + +#if defined(_UNICODE) +/*! @brief TCHAR version dependent on if _UNICODE is defined */ +# define CSimpleOpt CSimpleOptW +#else +/*! @brief TCHAR version dependent on if _UNICODE is defined */ +# define CSimpleOpt CSimpleOptA +#endif + +#endif // INCLUDED_SimpleOpt diff --git a/source/SimulationManager.cpp b/source/SimulationManager.cpp index f7b2e4c2..f91b0b03 100644 --- a/source/SimulationManager.cpp +++ b/source/SimulationManager.cpp @@ -121,40 +121,40 @@ void SimulationManager::computeSimulationOrder() { for (GraphNodeRef &node : graph) { if (node) { for (const GraphNodeRef &otherNode : graph) { - if (otherNode and + if (otherNode && otherNode.get() != node.get()) { bool nodeRunsBeforeOther = node->simulation->runsBefore(*otherNode->simulation), nodeRunsAfterOther = node->simulation->runsAfter(*otherNode->simulation), otherRunsBeforeNode = otherNode->simulation->runsBefore(*node->simulation), otherRunsAfterNode = otherNode->simulation->runsAfter(*node->simulation); // Sanity checks - if (nodeRunsBeforeOther and nodeRunsAfterOther) { + if (nodeRunsBeforeOther && nodeRunsAfterOther) { throw std::logic_error( std::string("Simulation ") + node->simulation->getName() + - " wants to run both before and after " + otherNode->simulation->getName()); + " wants to run both before && after " + otherNode->simulation->getName()); } - if (otherRunsBeforeNode and otherRunsAfterNode) { + if (otherRunsBeforeNode && otherRunsAfterNode) { throw std::logic_error( std::string("Simulation ") + otherNode->simulation->getName() + - " wants to run both before and after " + node->simulation->getName()); + " wants to run both before && after " + node->simulation->getName()); } - if (nodeRunsBeforeOther and otherRunsBeforeNode) { + if (nodeRunsBeforeOther && otherRunsBeforeNode) { throw std::logic_error( - std::string("Both ") + node->simulation->getName() + " and " + + std::string("Both ") + node->simulation->getName() + " && " + otherNode->simulation->getName() + " want to run before each other"); } - if (nodeRunsAfterOther and otherRunsAfterNode) { + if (nodeRunsAfterOther && otherRunsAfterNode) { throw std::logic_error( - std::string("Both ") + node->simulation->getName() + " and " + + std::string("Both ") + node->simulation->getName() + " && " + otherNode->simulation->getName() + " want to run after each other"); } // Node -> Other - if (nodeRunsBeforeOther or otherRunsAfterNode) { + if (nodeRunsBeforeOther || otherRunsAfterNode) { node->successors.insert(otherNode.get()); otherNode->predecessors.insert(node.get()); } // Other -> Node - else if (nodeRunsAfterOther or otherRunsBeforeNode) { + else if (nodeRunsAfterOther || otherRunsBeforeNode) { otherNode->successors.insert(node.get()); node->predecessors.insert(otherNode.get()); } diff --git a/source/SoundManager.cpp b/source/SoundManager.cpp index 4260523a..3a66a8b7 100644 --- a/source/SoundManager.cpp +++ b/source/SoundManager.cpp @@ -34,7 +34,7 @@ void SoundManager::init() { music = nullptr; sounds.clear(); - if (not isDisabled) { + if ( !isDisabled) { int flags = MIX_INIT_OGG; if ((Mix_Init(flags) & flags) != flags) { @@ -44,7 +44,7 @@ void SoundManager::init() { } } - if (not isDisabled) { + if ( !isDisabled) { int audioRate = 22050; Uint16 audioFormat = AUDIO_S16; int audioChannels = 2; @@ -118,7 +118,7 @@ void SoundManager::update(const Entity &listener) { std::vector erase_list; for (auto sound : sounds) { - if (not Mix_Playing(sound.first)) { + if ( !Mix_Playing(sound.first)) { Mix_FreeChunk(sound.second.chunk); erase_list.push_back(sound.first); } diff --git a/source/Window.cpp b/source/Window.cpp index ddd41e65..d7836f08 100644 --- a/source/Window.cpp +++ b/source/Window.cpp @@ -306,13 +306,13 @@ void Window::processMouseAxisEvents() { bool nonZero = mouseRelative != Vector2i::ZERO; - if (nonZero or lastNonZero) { + if (nonZero || lastNonZero) { const MouseAxisEvent mae(*this, Vector2f(mouseRelative)); - for (auto &d : dispatchers) { + for (auto &d : dispatchers) { d.get().dispatch(mae); } } - + lastNonZero = nonZero; } @@ -342,7 +342,7 @@ void Window::processControllerStickEvents() { } else { normalisedStickState.x = float(currentStickState.x) / float(controllerStickMax[i].x); } - + if (currentStickState.y > 0) { normalisedStickState.y = float(currentStickState.y) / float(controllerStickMax[i].y); } else { @@ -653,4 +653,3 @@ void Window::setSdlGlAttributes() { } } /* namespace radix */ - diff --git a/source/core/diag/AnsiConsoleLogger.cpp b/source/core/diag/AnsiConsoleLogger.cpp index 8b212f4f..cd5d1c04 100644 --- a/source/core/diag/AnsiConsoleLogger.cpp +++ b/source/core/diag/AnsiConsoleLogger.cpp @@ -33,8 +33,8 @@ AnsiConsoleLogger::AnsiConsoleLogger() : #ifndef _WIN32 const auto term = getenv("TERM"); const bool tty = isatty(fileno(stdout)); - if (not tty or - (term != nullptr and std::string(term) == "linux")) { + if ( !tty || + (term != nullptr && std::string(term) == "linux")) { // Linux fbcon VTs don't handle extended colors // This is also what's reported by some IDEs' output window which aren't full fledged terminals enableColors = false; @@ -62,7 +62,7 @@ bool needBlackText(int bgcol) { // http://www.pixelbeat.org/docs/terminal_colours/ const int x = ((bgcol-16)%36)%6, y = ((bgcol-16)%36)/6, z = (bgcol-16)/36; // Bottom and right parts of the cube are the brightest. Higher you go, brightest also. - return x > 3 or y > 3 or (z >= 3 and (x > 2 or y > 2)); + return x > 3 || y > 3 || (z >= 3 && (x > 2 || y > 2)); } void AnsiConsoleLogger::log(const std::string &message, LogLevel lvl, const std::string &tag) { diff --git a/source/core/diag/LogInput.cpp b/source/core/diag/LogInput.cpp index fdfa614e..e5826151 100644 --- a/source/core/diag/LogInput.cpp +++ b/source/core/diag/LogInput.cpp @@ -19,7 +19,7 @@ LogInput::LogInput(Logger &sink, LogLevel lvl, const std::string &tag) : } LogInput::~LogInput() { - if (not buf.empty()) { + if ( !buf.empty()) { sink.log(buf, lvl, tag); } } diff --git a/source/core/diag/StdoutLogger.cpp b/source/core/diag/StdoutLogger.cpp index 9445e08d..c6264a96 100644 --- a/source/core/diag/StdoutLogger.cpp +++ b/source/core/diag/StdoutLogger.cpp @@ -11,7 +11,7 @@ const char* StdoutLogger::getName() const { void StdoutLogger::log(const std::string &message, LogLevel lvl, const std::string &tag) { std::unique_lock lk(mtx); - if (not tag.empty()) { + if ( !tag.empty()) { std::cout << tag << ' '; } std::cout << message << std::endl; diff --git a/source/core/event/EventDispatcher.cpp b/source/core/event/EventDispatcher.cpp index a89e97fe..aa27c4ae 100644 --- a/source/core/event/EventDispatcher.cpp +++ b/source/core/event/EventDispatcher.cpp @@ -13,7 +13,7 @@ EventDispatcher::EventDispatcher() : void EventDispatcher::dispatch(const Event &event) { ObserverMap::iterator it; it = observerMap.find(event.getType()); - if (debugLogLevel == DebugLogLevel::DispatchedEvents or + if (debugLogLevel == DebugLogLevel::DispatchedEvents || debugLogLevel == DebugLogLevel::DispatchedEventsRepr) { unsigned int obsCount = 0; if (it != observerMap.end()) { diff --git a/source/core/file/Path.cpp b/source/core/file/Path.cpp index 917a847d..92d1fcc6 100644 --- a/source/core/file/Path.cpp +++ b/source/core/file/Path.cpp @@ -22,7 +22,7 @@ bool Path::DirectoryExist(std::string &directory) { #ifndef _WIN32 struct stat sb; - if (stat(directory.c_str(), &sb) == 0 and S_ISDIR(sb.st_mode)) { + if (stat(directory.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)) { return true; } return false; diff --git a/source/core/math/Vector2f.cpp b/source/core/math/Vector2f.cpp index 5e5f4cd9..d35aec6b 100644 --- a/source/core/math/Vector2f.cpp +++ b/source/core/math/Vector2f.cpp @@ -31,8 +31,8 @@ std::string Vector2f::str() const { } bool Vector2f::fuzzyEqual(const Vector2f &v, float threshold) const { - return (x > v.x - threshold and x < v.x + threshold) and - (y > v.y - threshold and y < v.y + threshold); + return (x > v.x - threshold && x < v.x + threshold) && + (y > v.y - threshold && y < v.y + threshold); } } /* namespace radix */ diff --git a/source/core/math/Vector3f.cpp b/source/core/math/Vector3f.cpp index 0ce36bf1..9e4cd139 100644 --- a/source/core/math/Vector3f.cpp +++ b/source/core/math/Vector3f.cpp @@ -43,9 +43,9 @@ void Vector3f::serialize(serine::Archiver &ar) { /* Operator overloads */ bool Vector3f::fuzzyEqual(const Vector3f &v, float threshold) const { - return (x > v.x - threshold and x < v.x + threshold) and - (y > v.y - threshold and y < v.y + threshold) and - (z > v.z - threshold and z < v.z + threshold); + return (x > v.x - threshold && x < v.x + threshold) && + (y > v.y - threshold && y < v.y + threshold) && + (z > v.z - threshold && z < v.z + threshold); } /* Bullet interop */ diff --git a/source/core/math/Vector4f.cpp b/source/core/math/Vector4f.cpp index 5cd38caa..26de7866 100644 --- a/source/core/math/Vector4f.cpp +++ b/source/core/math/Vector4f.cpp @@ -31,10 +31,10 @@ Vector4f& Vector4f::operator=(const btVector4 &v) { } bool Vector4f::fuzzyEqual(const Vector4f &v, float threshold) const { - return (x > v.x - threshold and x < v.x + threshold) and - (y > v.y - threshold and y < v.y + threshold) and - (z > v.z - threshold and z < v.z + threshold) and - (w > v.w - threshold and w < v.w + threshold); + return (x > v.x - threshold && x < v.x + threshold) && + (y > v.y - threshold && y < v.y + threshold) && + (z > v.z - threshold && z < v.z + threshold) && + (w > v.w - threshold && w < v.w + threshold); } Vector4f::operator btQuaternion() const { diff --git a/source/data/map/MapListLoader.cpp b/source/data/map/MapListLoader.cpp index 7ab48b1e..b7848652 100644 --- a/source/data/map/MapListLoader.cpp +++ b/source/data/map/MapListLoader.cpp @@ -12,7 +12,7 @@ vector MapListLoader::getMapList() { std::string path = Environment::getDataDir() + "/maps/maplist"; ifstream file(path); - if (not file.is_open()) { + if ( !file.is_open()) { throw runtime_error("Could not find file: " + path); } diff --git a/source/data/model/MeshLoader.cpp b/source/data/model/MeshLoader.cpp index b8fa09d9..492b2ba9 100644 --- a/source/data/model/MeshLoader.cpp +++ b/source/data/model/MeshLoader.cpp @@ -172,7 +172,7 @@ Mesh MeshLoader::getPortalBox(const Entity &wall) { glGenVertexArrays(1, &vao); glBindVertexArray(vao); - /* == Static part: vertices, normals and tangents == */ + /* == Static part: vertices, normals && tangents == */ constexpr unsigned int coordsSize = sizeof(float) * 3, texcSize = sizeof(float) * 2, normalsSize = sizeof(int8_t) * 3, diff --git a/source/data/screen/XmlScreenLoader.cpp b/source/data/screen/XmlScreenLoader.cpp index e1e07924..9b03a9c1 100644 --- a/source/data/screen/XmlScreenLoader.cpp +++ b/source/data/screen/XmlScreenLoader.cpp @@ -30,10 +30,10 @@ std::shared_ptr XmlScreenLoader::loadScreen(const std::string &path) { XMLElement *element = docHandle.FirstChildElement("screen").ToElement(); XMLHandle rootHandle = XMLHandle(element); - if (not loadText(rootHandle, &screen->text)) { + if ( !loadText(rootHandle, &screen->text)) { XmlScreenLoader::handleFailureForElement(module, std::string("text"), path); } - if (not extractColor(element, &screen->color)) { + if ( !extractColor(element, &screen->color)) { XmlScreenLoader::handleFailureForElement(module, std::string("color"), path); } @@ -55,7 +55,7 @@ bool XmlScreenLoader::loadText(XMLHandle &rootHandle, std::vector* textVec currentElement->QueryFloatAttribute("z", &text.z); currentElement->QueryFloatAttribute("top", &text.top); currentElement->QueryFloatAttribute("size", &text.size); - if (not extractColor(currentElement, &text.color)) { + if ( !extractColor(currentElement, &text.color)) { return false; } align = currentElement->Attribute("align"); diff --git a/source/data/shader/ShaderLoader.cpp b/source/data/shader/ShaderLoader.cpp index 31b9baf2..af873a02 100644 --- a/source/data/shader/ShaderLoader.cpp +++ b/source/data/shader/ShaderLoader.cpp @@ -153,7 +153,7 @@ unsigned int ShaderLoader::loadShader(const std::string &path, Shader::Type type) { // Read file and point to end of file std::ifstream file(path, std::ifstream::ate); - if (not file.is_open()) { + if ( !file.is_open()) { Util::Log(Error, "ShaderLoader") << "Could not find shader file " << path; } // Get file size diff --git a/source/data/texture/TextureLoader.cpp b/source/data/texture/TextureLoader.cpp index f775d2b9..e408e8da 100644 --- a/source/data/texture/TextureLoader.cpp +++ b/source/data/texture/TextureLoader.cpp @@ -92,7 +92,7 @@ Texture TextureLoader::uploadTexture(const unsigned char *data, PixelFormat pixF GLuint handle; glGenTextures(1, &handle); // Create Texture OpenGL handler glBindTexture(GL_TEXTURE_2D, - handle); // Bind and Set OpenGL Texture type 2D Texture + handle); // Bind && Set OpenGL Texture type 2D Texture glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // sets pixel storage modes // Allocate texture with (width x height x 4) and copy data from CPU to GPU glTexImage2D(GL_TEXTURE_2D, 0, getGlInternalPixelFormat(pixFormat), diff --git a/source/entities/Player.cpp b/source/entities/Player.cpp index 9e358b5b..5b38bb97 100644 --- a/source/entities/Player.cpp +++ b/source/entities/Player.cpp @@ -96,7 +96,7 @@ void Player::tick(TDelta dtime) { float rot = headAngle.heading; privSetPosition(obj->getWorldTransform().getOrigin()); - if (attemptJump and controller->canJump()) { + if (attemptJump && controller->canJump()) { std::uniform_int_distribution<> dis(0, PLAYER_JUMP_SOUND.size()-1); playSound(Environment::getDataDir() + PLAYER_JUMP_SOUND[dis(Util::Rand)]); controller->jump(); diff --git a/source/entities/traits/HealthTrait.cpp b/source/entities/traits/HealthTrait.cpp index 4c69a05e..3af6dbd9 100644 --- a/source/entities/traits/HealthTrait.cpp +++ b/source/entities/traits/HealthTrait.cpp @@ -29,7 +29,7 @@ void HealthTrait::kill() { } void HealthTrait::revive() { - if (not isAlive()) { + if ( !isAlive()) { health = 1.f; } } diff --git a/source/env/ArgumentsParser.cpp b/source/env/ArgumentsParser.cpp index 84ac75ee..b664da44 100644 --- a/source/env/ArgumentsParser.cpp +++ b/source/env/ArgumentsParser.cpp @@ -3,8 +3,8 @@ #include #include #include -#include #include +#include #include #include @@ -21,6 +21,38 @@ bool ArgumentsParser::consoleEnabled = false; bool ArgumentsParser::profilerEnabled = false; int ArgumentsParser::screen = 0; + +// option identifiers +enum { + OPT_VERSION, + OPT_HELP, + OPT_SHOWCURSOR, + OPT_IGNOREGLVERSION, + OPT_DEBUGMODE, + OPT_DATADIR, + OPT_MAP, + OPT_MAPFROMPATH, + OPT_CONSOLE, + OPT_PROFILER, + OPT_SCREEN +}; + +// option array +CSimpleOpt::SOption cmdline_options[] = { + { OPT_VERSION, ("-version"), SO_NONE }, + { OPT_HELP, ("-help"), SO_NONE }, + { OPT_SHOWCURSOR, ("-showcursor"), SO_NONE }, + { OPT_IGNOREGLVERSION, ("-ignoreGlVersion"), SO_NONE }, + { OPT_DEBUGMODE, ("-debugMode"), SO_NONE }, + { OPT_DATADIR, ("-datadir"), SO_REQ_SEP }, + { OPT_MAP, ("-map"), SO_REQ_SEP }, + { OPT_MAPFROMPATH, ("-mapfrompath"), SO_REQ_SEP }, + { OPT_CONSOLE, ("-console"), SO_NONE }, + { OPT_PROFILER, ("-profiler"), SO_NONE }, + { OPT_SCREEN, ("-screen"), SO_REQ_SEP }, + SO_END_OF_OPTIONS +}; + void ArgumentsParser::showUsage(char **argv) { std::cout << "Usage: " << argv[0] << " [options]" << std::endl << std::endl; @@ -38,81 +70,67 @@ void ArgumentsParser::showUsage(char **argv) { std::cout << " -s, --screen Use alternate display" << std::endl; } -void ArgumentsParser::setEnvironmentFromArgs(const int argc, char **argv) { - static struct option longOptions[] = { - {"version", no_argument, 0, 'v'}, - {"help", no_argument, 0, 'h'}, - {"showcursor", no_argument, 0, 'c'}, - {"ignoreGlVersion", no_argument, 0, 'G'}, - {"debugMode", no_argument, 0, 'D'}, - {"datadir", required_argument, 0, 'd'}, - {"map", required_argument, 0, 'm'}, - {"mapfrompath", required_argument, 0, 'M'}, - {"console", no_argument , 0, 'a'}, - {"profiler", no_argument , 0, 'p'}, - {"screen", required_argument, 0, 's'}, - {0, 0, 0, 0} - }; - - while (1) { - int optionIndex = 0; - int argument; - argument = getopt_long(argc, argv, "pvhacd:m:M:GD", longOptions, &optionIndex); - - if (argument == NO_ARGUMENT) { - break; - } - - switch (argument) { - case 'v': - showVersion(); - exit(0); - case 'd': - Environment::setDataDir(optarg); - break; - case 'h': - showUsage(argv); - exit(0); - case 'm': - mapName = optarg; - break; - case 'M': - mapPath = optarg; - break; - case 'c': - showCursor = true; - break; - case '?': - showUsage(argv); - exit(1); - case 'G': - ignoreGlVersion = true; - break; - case 'D': - debugMode = true; - showCursor = true; - ignoreGlVersion = true; - break; - case 'a': - consoleEnabled = true; - break; - case 'p': - profilerEnabled = true; - case 's': - screen = atoi(optarg); - break; - default: - break; +void ArgumentsParser::setEnvironmentFromArgs (const int argc, char **argv) { + + CSimpleOpt args (argc, argv, cmdline_options); + + while (args.Next ()) + { + if (args.LastError () != SO_SUCCESS) + { + showUsage (argv); + exit (1); + } + switch (args.OptionId ()) { + case OPT_VERSION: + showVersion (); + exit (0); + case OPT_DATADIR: + Environment::setDataDir (args.OptionArg ()); + break; + case OPT_HELP: + showUsage (argv); + exit (0); + case OPT_MAP: + mapName = args.OptionArg (); + break; + case OPT_MAPFROMPATH: + mapPath = args.OptionArg (); + break; + case OPT_SHOWCURSOR: + showCursor = true; + break; + case OPT_IGNOREGLVERSION: + ignoreGlVersion = true; + break; + case OPT_DEBUGMODE: + debugMode = true; + showCursor = true; + ignoreGlVersion = true; + break; + case OPT_CONSOLE: + consoleEnabled = true; + break; + case OPT_PROFILER: + profilerEnabled = true; + case OPT_SCREEN: + screen = atoi (args.OptionArg ()); + break; + default: + showUsage (argv); + exit (0); + break; + } } - } } + void ArgumentsParser::populateConfig(radix::Config &config) { - if (not mapName.empty()) { + if ( !mapName.empty()) { config.map = mapName; } - if (not mapPath.empty()) { + if ( !mapPath.empty()) { config.mapPath = mapPath; } diff --git a/source/input/Channel.cpp b/source/input/Channel.cpp index 6b6b3dba..4c0c8c5f 100644 --- a/source/input/Channel.cpp +++ b/source/input/Channel.cpp @@ -80,7 +80,7 @@ void SubChannel::init(const int &id, EventDispatcher &event, const Bind& bind this->bind = bind; this->setSensitivity(bind.sensitivity); - if (InputManager::isActionDigital(bind.action) or Bind::isInputTypeDigital(bind.inputType)) { + if (InputManager::isActionDigital(bind.action) || Bind::isInputTypeDigital(bind.inputType)) { this->setDigital(bind.actPoint); } else { if (bind.inputType == Bind::CONTROLLER_AXIS) { @@ -172,7 +172,7 @@ void SubChannel::addObservers(EventDispatcher &event) { case Bind::MOUSE_AXIS: { event.addObserverRaw(InputSource::MouseAxisEvent::Type, [this](const radix::Event& event) { const Vector2f value = ((radix::InputSource::MouseAxisEvent &) event).value; - + this->set(value); }); break; diff --git a/source/input/ChannelBase.cpp b/source/input/ChannelBase.cpp index a824429e..7739936a 100644 --- a/source/input/ChannelBase.cpp +++ b/source/input/ChannelBase.cpp @@ -76,7 +76,7 @@ void ChannelBase::set(T newValue) { newValue *= sensitivity; } - if (value != newValue or alwaysNotifyListener) { + if (value != newValue || alwaysNotifyListener) { value = newValue; notifyListeners(); @@ -114,7 +114,7 @@ void ChannelBase::set(Vector2f newValue) { newValue *= sensitivity; } - if (alwaysNotifyListener or !newValue.fuzzyEqual(value, 0.0001)) { + if (alwaysNotifyListener || !newValue.fuzzyEqual(value, 0.0001)) { value = newValue; notifyListeners(); diff --git a/source/physics/KinematicCharacterController.cpp b/source/physics/KinematicCharacterController.cpp index c1c363a1..98785d4f 100644 --- a/source/physics/KinematicCharacterController.cpp +++ b/source/physics/KinematicCharacterController.cpp @@ -98,7 +98,7 @@ class KinematicClosestNotMeConvexResultCallback : return btScalar(1.0); } - if (not convexResult.m_hitCollisionObject->hasContactResponse()){ + if ( !convexResult.m_hitCollisionObject->hasContactResponse()){ return btScalar(1.0); } @@ -231,7 +231,7 @@ bool KinematicCharacterController::recoverFromPenetration(btCollisionWorld *coll btCollisionObject* obj1 = static_cast(collisionPair->m_pProxy1->m_clientObject); - if ((obj0 && not obj0->hasContactResponse()) || (obj1 && not obj1->hasContactResponse())){ + if ((obj0 && !obj0->hasContactResponse()) || (obj1 && !obj1->hasContactResponse())){ continue; } @@ -453,8 +453,8 @@ void KinematicCharacterController::stepDown(btCollisionWorld *collisionWorld, bt btScalar downVelocity = (m_verticalVelocity<0.f?-m_verticalVelocity:0.f) * dt; - if (downVelocity > 0.0 and downVelocity > m_fallSpeed - and (m_wasOnGround or not m_wasJumping)) { + if (downVelocity > 0.0 && downVelocity > m_fallSpeed + && (m_wasOnGround || ! m_wasJumping)) { downVelocity = m_fallSpeed; } btVector3 step_drop = getUpAxisDirections()[m_upAxis] * (m_currentStepOffset + downVelocity); @@ -493,10 +493,10 @@ void KinematicCharacterController::stepDown(btCollisionWorld *collisionWorld, bt start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration); - if (not callback.hasHit()) + if ( !callback.hasHit()) { // test a double fall height, to see if the character should interpolate it's fall (full) - // or not (partial) + // || not (partial) m_ghostObject->convexSweepTest(m_convexShape, start, end_double, callback2, collisionWorld->getDispatchInfo().m_allowedCcdPenetration); @@ -505,10 +505,10 @@ void KinematicCharacterController::stepDown(btCollisionWorld *collisionWorld, bt collisionWorld->convexSweepTest(m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration); - if (not callback.hasHit()) + if ( !callback.hasHit()) { // test a double fall height, to see if the character should interpolate it's - // fall (large) or not (small) + // fall (large) || not (small) collisionWorld->convexSweepTest(m_convexShape, start, end_double, callback2, collisionWorld->getDispatchInfo().m_allowedCcdPenetration); } @@ -523,7 +523,7 @@ void KinematicCharacterController::stepDown(btCollisionWorld *collisionWorld, bt } if (downVelocity2 > 0.0 && downVelocity2 < m_stepHeight && has_hit == true && runonce == false - && (m_wasOnGround || not m_wasJumping)) { + && (m_wasOnGround || ! m_wasJumping)) { //redo the velocity calculation when falling a small amount, for fast stairs motion //for larger falls, use the smoother/slower interpolated movement by not touching //the target position @@ -539,7 +539,7 @@ void KinematicCharacterController::stepDown(btCollisionWorld *collisionWorld, bt break; } - if (callback.hasHit() or runonce) { + if (callback.hasHit() || runonce) { // we dropped a fraction of the height -> hit floor btScalar fraction = (m_currentPosition.getY() - callback.m_hitPointWorld.getY()) / 2; @@ -571,7 +571,7 @@ void KinematicCharacterController::stepDown(btCollisionWorld *collisionWorld, bt if (bounce_fix) { downVelocity = (m_verticalVelocity<0.f?-m_verticalVelocity:0.f) * dt; - if (downVelocity > m_fallSpeed and (m_wasOnGround or not m_wasJumping)) { + if (downVelocity > m_fallSpeed && (m_wasOnGround || ! m_wasJumping)) { m_targetPosition += step_drop; //undo previous target change downVelocity = m_fallSpeed; step_drop = getUpAxisDirections()[m_upAxis] * (m_currentStepOffset + downVelocity); @@ -638,7 +638,7 @@ void KinematicCharacterController::preStep(btCollisionWorld *collisionWorld) { void KinematicCharacterController::playerStep(btCollisionWorld *collisionWorld, btScalar dt) { // quick check... - if (not m_useWalkDirection and (m_velocityTimeInterval <= 0.0 or m_walkDirection.fuzzyZero())) { + if ( !m_useWalkDirection && (m_velocityTimeInterval <= 0.0 || m_walkDirection.fuzzyZero())) { return; } @@ -700,7 +700,7 @@ void KinematicCharacterController::jump(const btVector3& dir) { #else void KinematicCharacterController::jump() { #endif - if (not canJump()) { + if ( !canJump()) { return; } diff --git a/source/physics/Uncollider.cpp b/source/physics/Uncollider.cpp index 0a81897d..2e9c3929 100644 --- a/source/physics/Uncollider.cpp +++ b/source/physics/Uncollider.cpp @@ -82,7 +82,7 @@ void Uncollider::nearCallback(btBroadphasePair &collisionPair, btManifoldResult contactPointResult(&obj0Wrap, &obj1Wrap); - if (not collisionPair.m_algorithm) { + if ( !collisionPair.m_algorithm) { #if (BT_BULLET_VERSION >=286) collisionPair.m_algorithm = dispatcher.findAlgorithm(&obj0Wrap, &obj1Wrap, diff --git a/source/simulation/Physics.cpp b/source/simulation/Physics.cpp index 25c6fd24..93ddbf77 100644 --- a/source/simulation/Physics.cpp +++ b/source/simulation/Physics.cpp @@ -73,7 +73,7 @@ void Physics::update(TDelta timeDelta) { physicsWorld->stepSimulation(timeDelta.sec(), 10); for (Entity &entity : world.entityManager) { RigidBodyTrait *rbtp = dynamic_cast(&entity); - if (rbtp and rbtp->body and not rbtp->body->isStaticObject()) { + if (rbtp && rbtp->body && !rbtp->body->isStaticObject()) { btTransform btTform; rbtp->body->getMotionState()->getWorldTransform(btTform); entity.privSetPosition(btTform.getOrigin()); diff --git a/tests/SystemGraphTest.cpp b/tests/SystemGraphTest.cpp index 01e339bc..6cf4ed0e 100644 --- a/tests/SystemGraphTest.cpp +++ b/tests/SystemGraphTest.cpp @@ -26,7 +26,7 @@ class TestSystem : public radix::System { } bool runsAfter(const System &s) { - return s.getTypeId() == System::getTypeId() or + return s.getTypeId() == System::getTypeId() || s.getTypeId() == System::getTypeId(); } /*bool runsBefore(const System &s) { @@ -102,7 +102,7 @@ template class TinySystem : public radix::System { } bool runsBefore(const System &s) { - return strncmp(s.getName(), "TinySystem", 10) == 0 and + return strncmp(s.getName(), "TinySystem", 10) == 0 && atoi(s.getName() + 10) > I; } diff --git a/tests/core/math/MathTest.cpp b/tests/core/math/MathTest.cpp index ab71abc5..a3da6264 100644 --- a/tests/core/math/MathTest.cpp +++ b/tests/core/math/MathTest.cpp @@ -21,11 +21,11 @@ bool fuzzyEq(float f1, float f2) { } bool fuzzyEq(const Quaternion &q, float x, float y, float z, float w) { - return fuzzyEq(q.x, x) and fuzzyEq(q.y, y) and fuzzyEq(q.z, z) and fuzzyEq(q.w, w); + return fuzzyEq(q.x, x) && fuzzyEq(q.y, y) && fuzzyEq(q.z, z) && fuzzyEq(q.w, w); } bool fuzzyEq(const Quaternion &q, const Quaternion &k) { - return fuzzyEq(q.x, k.x) and fuzzyEq(q.y, k.y) and fuzzyEq(q.z, k.z) and fuzzyEq(q.w, k.w); + return fuzzyEq(q.x, k.x) && fuzzyEq(q.y, k.y) && fuzzyEq(q.z, k.z) && fuzzyEq(q.w, k.w); } void printq(const Quaternion &q) { @@ -86,14 +86,14 @@ TEST_CASE_METHOD(MathTestFixtures, "toDirection test") { Vector3f backward(0, 0, 1); REQUIRE(direction.fuzzyEqual(backward)); } - + SECTION("to forward") { quat.fromAxAngle(1, 0, 0, rad(0)); Vector3f direction = Math::toDirection(quat); Vector3f forward(0, 0, -1); REQUIRE(direction.fuzzyEqual(forward)); } - + SECTION("to right") { quat.fromAxAngle(0, 1, 0, rad(-90)); Vector3f direction = Math::toDirection(quat); @@ -104,7 +104,7 @@ TEST_CASE_METHOD(MathTestFixtures, "toDirection test") { quat.fromAxAngle(0, 1, 0, rad(90)); Vector3f direction = Math::toDirection(quat); Vector3f left(-1, 0, 0); - REQUIRE(direction.fuzzyEqual(left)); + REQUIRE(direction.fuzzyEqual(left)); } SECTION("to up") { quat.fromAxAngle(1, 0, 0, rad(90)); @@ -116,59 +116,59 @@ TEST_CASE_METHOD(MathTestFixtures, "toDirection test") { quat.fromAxAngle(1, 0, 0, rad(-90)); Vector3f direction = Math::toDirection(quat); Vector3f down(0, -1, 0); - REQUIRE(direction.fuzzyEqual(down)); + REQUIRE(direction.fuzzyEqual(down)); } - + // Now each quadrant (there are eight) SECTION("to first quadrant") { quat.fromAxAngle(1, -1, 0, rad(135)); Vector3f direction = Math::toDirection(quat); Vector3f first(.5, .5, .7071); - REQUIRE(direction.fuzzyEqual(first)); + REQUIRE(direction.fuzzyEqual(first)); } SECTION("to second quadrant") { quat.fromAxAngle(1, 1, 0, rad(135)); Vector3f direction = Math::toDirection(quat); Vector3f second(-.5, .5, .7071); - REQUIRE(direction.fuzzyEqual(second)); + REQUIRE(direction.fuzzyEqual(second)); } SECTION("to third quadrant") { quat.fromAxAngle(-1, 1, 0, rad(135)); Vector3f direction = Math::toDirection(quat); Vector3f third(-.5, -.5, .7071); - REQUIRE(direction.fuzzyEqual(third)); + REQUIRE(direction.fuzzyEqual(third)); } SECTION("to fourth quadrant") { quat.fromAxAngle(-1, -1, 0, rad(135)); Vector3f direction = Math::toDirection(quat); Vector3f fourth(.5, -.5, .7071); - REQUIRE(direction.fuzzyEqual(fourth)); + REQUIRE(direction.fuzzyEqual(fourth)); } SECTION("to fifth quadrant") { quat.fromAxAngle(1, -1, 0, rad(45)); Vector3f direction = Math::toDirection(quat); Vector3f fifth(.5, .5, -.7071); - REQUIRE(direction.fuzzyEqual(fifth)); + REQUIRE(direction.fuzzyEqual(fifth)); } SECTION("to sixth quadrant") { quat.fromAxAngle(1, 1, 0, rad(45)); Vector3f direction = Math::toDirection(quat); Vector3f sixth(-.5, .5, -.7071); - REQUIRE(direction.fuzzyEqual(sixth)); + REQUIRE(direction.fuzzyEqual(sixth)); } SECTION("to seventh quadrant") { quat.fromAxAngle(-1, 1, 0, rad(45)); Vector3f direction = Math::toDirection(quat); Vector3f seventh(-.5, -.5, -.7071); - REQUIRE(direction.fuzzyEqual(seventh)); + REQUIRE(direction.fuzzyEqual(seventh)); } SECTION("to eighth quadrant") { quat.fromAxAngle(-1, -1, 0, rad(45)); Vector3f direction = Math::toDirection(quat); Vector3f eighth(.5, -.5, -.7071); - REQUIRE(direction.fuzzyEqual(eighth)); + REQUIRE(direction.fuzzyEqual(eighth)); } } @@ -210,4 +210,3 @@ TEST_CASE_METHOD(MathTestFixtures, "ToEuler test") { REQUIRE(euler.fuzzyEqual(correct, .001)); } } - diff --git a/tests/core/math/QuaternionTest.cpp b/tests/core/math/QuaternionTest.cpp index 69060b8c..4f448244 100644 --- a/tests/core/math/QuaternionTest.cpp +++ b/tests/core/math/QuaternionTest.cpp @@ -35,11 +35,11 @@ bool fuzzyEq(float f1, float f2) { } bool fuzzyEq(const Quaternion &q, float x, float y, float z, float w) { - return fuzzyEq(q.x, x) and fuzzyEq(q.y, y) and fuzzyEq(q.z, z) and fuzzyEq(q.w, w); + return fuzzyEq(q.x, x) && fuzzyEq(q.y, y) && fuzzyEq(q.z, z) && fuzzyEq(q.w, w); } bool fuzzyEq(const Quaternion &q, const Quaternion &k) { - return fuzzyEq(q.x, k.x) and fuzzyEq(q.y, k.y) and fuzzyEq(q.z, k.z) and fuzzyEq(q.w, k.w); + return fuzzyEq(q.x, k.x) && fuzzyEq(q.y, k.y) && fuzzyEq(q.z, k.z) && fuzzyEq(q.w, k.w); } void printq(const Quaternion &q) {