Skip to content

Commit

Permalink
Tidy up for initial release
Browse files Browse the repository at this point in the history
- spruced up docs
- added Fixed::MIN() and Fixed::MAX() constant-like functions for min and max range of type, along with tests for them.
- added todo-list in docs
  • Loading branch information
saxbophone committed Sep 14, 2021
1 parent 240b03f commit 3c75084
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 63 deletions.
2 changes: 1 addition & 1 deletion Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ PROJECT_NUMBER = $(TAG_NAME)
# for a project that appears at the top of each page and should give viewer a
# quick idea about the purpose of the project. Keep the description short.

PROJECT_BRIEF = "Lazy-evaluated type-wrapper for numeric types in C++"
PROJECT_BRIEF = "More convenient fixed-point arithmetic for the Sony PlayStation"

# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
# in the documentation. The maximum height of the logo should not exceed 55
Expand Down
62 changes: 3 additions & 59 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,60 +1,4 @@
# CPP20-Cross-Platform-Template
A template for a cross-platform C++20 project including modern CMake, unit-testing with Catch, cross-platform CI and release builds using using Github Actions.
# SxPsxFp
More convenient fixed-point arithmetic for the Sony PlayStation

## What's included
- CMake C++20 project skeleton, with strict warning flags enabled when using GCC or Clang.
- Usage of modern CMake practices for setting project-wide compiler options, etc. in a target-focused way.
- Properly exported CMake project that can be used by other CMake projects with minimal effort (no hand-written `FindMyProject.cmake` files)
- Unit testing using [Catch2](https://github.com/catchorg/Catch2), with automatic test discovery integration with CTest.
- Github Actions config files supporting building and running tests on Linux, macOS and Windows using the following compilers:
- Linux: GCC-10, Clang-10
- macOS: GCC-10, Clang-12
- Windows: MSVC 2019
- Building Releases on each platform when a Github Release is published, uploading these as build Artifacts.
- Doxygen config file with tweaks from the default config settings to provide a few more graphs (usage, caller/callee relationships) than are enabled by default.

> **Note** There's also a Travis-CI build config for a cross-platform build of similar structure to the Github Actions builds, however this is no longer maintained as Travis-CI has been found to not support more recent versions of CMake on all platforms.
## Usage
1. Click the <kbd>Use this template</kbd> button at the top of this page to create your own new copy of this template
2. Fill in the project details on the next page as you desire
3. Once you've got your new project produced from this template, make changes in the following files:
- `CMakeLists.txt`, `project/CMakeLists.txt`, `project/src/CMakeLists.txt`, `tests/CMakeLists.txt`:
- Replace all instances of `PROJECT`, `project` and `Project` with your project's name, capitalised or uncapitalised as appropriate
- `Doxyfile`:
- Change the `PROJECT_NAME` and `INPUT` settings to your project's name.
- `project`:
- Rename this directory to the name of your project.
- **Choose a Software License for your code** if it is open-source and you want other people to be able to use it with ease!

This _project template_ is placed into the public domain, but you may want to use a different license for your own projects that you create from this template. Here is the public domain dedication text for this project:

```
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
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 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.
For more information, please refer to <http://unlicense.org/>
```
4. Enjoy!
> The above instructions are the bare minimum required to get your own project based on this template off of the ground. You'll almost certainly want to change more things in `Doxyfile` and definitely `README.md`, but that should be well within the capabilities of a developer and also beyond the scope of this guide.
- [sxpsxfp](@ref com::saxbophone::sxpsxfp) API reference
35 changes: 32 additions & 3 deletions sxpsxfp/include/sxpsxfp/Fixed.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
#include <sys/types.h>
#endif

/**
* @todo Consider shortening the namespace name to its last component
* @todo Consider choosing a more intuitive name than @b sxpsxfp
*/
namespace com::saxbophone::sxpsxfp {
class Fixed; // forward-declaration to allow declaration of user-defined literals

Expand Down Expand Up @@ -60,6 +64,7 @@ namespace com::saxbophone::sxpsxfp {
* point arithmetic and allows arithmetic operations to be done on these
* instances directly, handling the additional arithmetic for emulating
* fixed-point internally.
* @todo Document constants
*/
class Fixed {
public:
Expand All @@ -72,6 +77,15 @@ namespace com::saxbophone::sxpsxfp {
static constexpr UnderlyingType DECIMAL_MIN = -(1 << Fixed::DECIMAL_BITS);
static constexpr double FRACTIONAL_MAX = Fixed::DECIMAL_MAX + (1.0 - Fixed::FRACTIONAL_STEP);
static constexpr double FRACTIONAL_MIN = Fixed::DECIMAL_MIN - (1.0 - Fixed::FRACTIONAL_STEP);

static constexpr Fixed MAX() {
return Fixed((UnderlyingType)2147483647);
}

static constexpr Fixed MIN() {
return Fixed((UnderlyingType)-2147483648);
}

/**
* @brief Default constructor, creates a Fixed instance with value `0.0_fx`
*/
Expand All @@ -93,6 +107,9 @@ namespace com::saxbophone::sxpsxfp {
* @note Not recommended to use this outside of constexpr contexts
* where avoidable on the PlayStation, as the console has no hardware
* floating point support, so slow software floats will be used.
* @todo Consider adding a single-precision `float` version of this
* methodfor faster emulation when doing runtime conversions on the
* PlayStation and `double` precision is not needed.
*/
constexpr Fixed(double value) {
double scaled = value * Fixed::SCALE;
Expand All @@ -111,9 +128,9 @@ namespace com::saxbophone::sxpsxfp {
* @warning Don't use this for converting raw fixed-point integers to Fixed.
* Use Fixed::Fixed(UnderlyingType) for that.
* @see Fixed::Fixed(UnderlyingType)
* @todo Check for overflow? No exceptions on the PS1...
*/
static constexpr Fixed from_integer(int value) {
// TODO: Check for overflow? No exceptions on the PS1...
return Fixed(value << Fixed::FRACTION_BITS);
}
/**
Expand Down Expand Up @@ -202,32 +219,44 @@ namespace com::saxbophone::sxpsxfp {
}
/**
* @brief Compound assignment multiplication operator
* @todo Investigate performance impact of compiler-generated 64-bit
* multiplication emulation on 32-bit MIPS. If poor performance,
* consider utilising Lameguy64's suggested implementation using inline
* assembly to take advantage of the R3000's 64-bit double-word multiply
* feature.
*/
constexpr Fixed& operator *=(const Fixed& rhs) {
// XXX: no int64_t on PS1, needs rewrite to run on that platform
// XXX: no int64_t on PS1, software emulation kicks in automatically
int64_t result = (int64_t)this->_raw_value * rhs._raw_value;
// shift back down
this->_raw_value = (UnderlyingType)(result / Fixed::SCALE);
return *this;
}
/**
* @brief Compound assignment integer multiplication operator
* @todo Investigate overflow?
*/
constexpr Fixed& operator *=(const UnderlyingType& rhs) {
this->_raw_value *= rhs;
return *this;
}
/**
* @brief Compound assignment division operator
* @todo Investigate performance impact of compiler-generated 64-bit
* multiplication emulation on 32-bit MIPS. If poor performance,
* consider utilising Lameguy64's suggested implementation using inline
* assembly to take advantage of the R3000's 64-bit double-word multiply
* feature.
*/
constexpr Fixed& operator /=(const Fixed& rhs) {
// XXX: no int64_t on PS1, needs rewrite to run on that platform
// XXX: no int64_t on PS1, software emulation kicks in automatically
int64_t scaled = (int64_t)this->_raw_value * Fixed::SCALE;
this->_raw_value = (UnderlyingType)(scaled / rhs._raw_value);
return *this;
}
/**
* @brief Compound assignment integer division operator
* @todo Investigate overflow?
*/
constexpr Fixed& operator /=(const UnderlyingType& rhs) {
this->_raw_value /= rhs;
Expand Down
16 changes: 16 additions & 0 deletions tests/static_checks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,22 @@ TEST_CASE("Fixed::FRACTIONAL_MIN == Fixed::DECIMAL_MIN - (1 - Fixed::FRACTIONAL_
STATIC_REQUIRE(Fixed::FRACTIONAL_MIN == Fixed::DECIMAL_MIN - (1.0 - Fixed::FRACTIONAL_STEP));
}

TEST_CASE("Fixed::MAX() == Max 32-bit signed integer") {
STATIC_REQUIRE(Fixed::MAX() == Fixed(INT_MAX));
}

TEST_CASE("Fixed::MIN() == Min 32-bit signed integer") {
STATIC_REQUIRE(Fixed::MIN() == Fixed(INT_MIN));
}

TEST_CASE("typeof(Fixed::MAX()) == Fixed") {
STATIC_REQUIRE(std::is_same_v<decltype(Fixed::MAX()), Fixed>);
}

TEST_CASE("typeof(Fixed::MIN()) == Fixed") {
STATIC_REQUIRE(std::is_same_v<decltype(Fixed::MIN()), Fixed>);
}

TEST_CASE("typeof(Fixed + Fixed) == Fixed") {
Fixed x = {}, y = {};
STATIC_REQUIRE(std::is_same_v<decltype(x + y), Fixed>);
Expand Down

0 comments on commit 3c75084

Please sign in to comment.