diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index f8e49c4..33a2a5c 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1,5 +1,5 @@
-# These are supported funding model platforms
-
-github: [kr15h]
-patreon: kriwkrow
-custom: ['https://paypal.me/kriwkrow']
+# These are supported funding model platforms
+
+github: [kr15h]
+patreon: kriwkrow
+custom: ['https://paypal.me/kriwkrow']
diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml
index 5913a7b..dd28607 100644
--- a/.github/workflows/linux.yml
+++ b/.github/workflows/linux.yml
@@ -1,57 +1,57 @@
-name: linux
-on:
- push:
- branches:
- - master
-jobs:
- compile:
- runs-on: ubuntu-latest
- env:
- OF_URL: https://github.com/openframeworks/openFrameworks/releases/download/0.11.2/of_v0.11.2_linux64gcc6_release.tar.gz
- steps:
- - name: Fetch ofxPiMapper
- uses: actions/checkout@v2
- with:
- fetch-depth: 1
- - name: Download openFrameworks and add ofxPiMapper to addons
- run: |
- mkdir .ofxPiMapper
- mv ./* .ofxPiMapper/
- wget ${OF_URL} --tries=10 --quiet
- echo "Unarchive openFrameworks"
- OF_ARCHIVE_NAME=$(basename -- "$OF_URL")
- tar -xf ${OF_ARCHIVE_NAME}
- rm ${OF_ARCHIVE_NAME}
- OF_EXTRACT_NAME=$(basename ${OF_ARCHIVE_NAME} .tar.gz)
- mv ${OF_EXTRACT_NAME} openFrameworks
- mv .ofxPiMapper openFrameworks/addons/ofxPiMapper
- - name: Install openFrameworks Dependencies
- working-directory: ./openFrameworks/scripts/linux/ubuntu
- run: sudo ./install_dependencies.sh -y
- - name: Compile openFrameworks
- working-directory: ./openFrameworks/scripts/linux
- run: ./compileOF.sh
- - name: Compile example_basic
- working-directory: ./openFrameworks/addons/ofxPiMapper/example_basic
- run: mv addons.make.norpi addons.make && make
- - name: Compile example_camera
- working-directory: ./openFrameworks/addons/ofxPiMapper/example_camera
- run: mv addons.make.norpi addons.make && make
- - name: Compile example_fbo-sources
- working-directory: ./openFrameworks/addons/ofxPiMapper/example_fbo-sources
- run: mv addons.make.norpi addons.make && make
- - name: Compile example_pocketvj
- working-directory: ./openFrameworks/addons/ofxPiMapper/example_pocketvj
- run: mv addons.make.norpi addons.make && make
- - name: Install ofxJSON dependency
- working-directory: ./openFrameworks/addons/
- run: git clone https://github.com/jeffcrouse/ofxJSON.git --depth 1
- - name: Compile example_remote-client
- working-directory: ./openFrameworks/addons/ofxPiMapper/example_remote-client
- run: mv addons.make.norpi addons.make && make
- - name: Compile example_remote-server
- working-directory: ./openFrameworks/addons/ofxPiMapper/example_remote-server
- run: mv addons.make.norpi addons.make && make
- - name: Compile example_simpler
- working-directory: ./openFrameworks/addons/ofxPiMapper/example_simpler
- run: mv addons.make.norpi addons.make && make
+name: linux
+on:
+ push:
+ branches:
+ - master
+jobs:
+ compile:
+ runs-on: ubuntu-latest
+ env:
+ OF_URL: https://github.com/openframeworks/openFrameworks/releases/download/0.11.2/of_v0.11.2_linux64gcc6_release.tar.gz
+ steps:
+ - name: Fetch ofxPiMapper
+ uses: actions/checkout@v2
+ with:
+ fetch-depth: 1
+ - name: Download openFrameworks and add ofxPiMapper to addons
+ run: |
+ mkdir .ofxPiMapper
+ mv ./* .ofxPiMapper/
+ wget ${OF_URL} --tries=10 --quiet
+ echo "Unarchive openFrameworks"
+ OF_ARCHIVE_NAME=$(basename -- "$OF_URL")
+ tar -xf ${OF_ARCHIVE_NAME}
+ rm ${OF_ARCHIVE_NAME}
+ OF_EXTRACT_NAME=$(basename ${OF_ARCHIVE_NAME} .tar.gz)
+ mv ${OF_EXTRACT_NAME} openFrameworks
+ mv .ofxPiMapper openFrameworks/addons/ofxPiMapper
+ - name: Install openFrameworks Dependencies
+ working-directory: ./openFrameworks/scripts/linux/ubuntu
+ run: sudo ./install_dependencies.sh -y
+ - name: Compile openFrameworks
+ working-directory: ./openFrameworks/scripts/linux
+ run: ./compileOF.sh
+ - name: Compile example_basic
+ working-directory: ./openFrameworks/addons/ofxPiMapper/example_basic
+ run: mv addons.make.norpi addons.make && make
+ - name: Compile example_camera
+ working-directory: ./openFrameworks/addons/ofxPiMapper/example_camera
+ run: mv addons.make.norpi addons.make && make
+ - name: Compile example_fbo-sources
+ working-directory: ./openFrameworks/addons/ofxPiMapper/example_fbo-sources
+ run: mv addons.make.norpi addons.make && make
+ - name: Compile example_pocketvj
+ working-directory: ./openFrameworks/addons/ofxPiMapper/example_pocketvj
+ run: mv addons.make.norpi addons.make && make
+ - name: Install ofxJSON dependency
+ working-directory: ./openFrameworks/addons/
+ run: git clone https://github.com/jeffcrouse/ofxJSON.git --depth 1
+ - name: Compile example_remote-client
+ working-directory: ./openFrameworks/addons/ofxPiMapper/example_remote-client
+ run: mv addons.make.norpi addons.make && make
+ - name: Compile example_remote-server
+ working-directory: ./openFrameworks/addons/ofxPiMapper/example_remote-server
+ run: mv addons.make.norpi addons.make && make
+ - name: Compile example_simpler
+ working-directory: ./openFrameworks/addons/ofxPiMapper/example_simpler
+ run: mv addons.make.norpi addons.make && make
diff --git a/.github/workflows/osx.yml b/.github/workflows/osx.yml
index 026ba48..b1bb690 100644
--- a/.github/workflows/osx.yml
+++ b/.github/workflows/osx.yml
@@ -1,60 +1,60 @@
-name: osx
-on:
- push:
- branches:
- - master
-jobs:
- compile:
- runs-on: macos-latest
- env:
- OF_URL: https://github.com/openframeworks/openFrameworks/releases/download/0.11.2/of_v0.11.2_osx_release.zip
- steps:
- - name: Fetch ofxPiMapper
- uses: actions/checkout@v2
- with:
- fetch-depth: 1
- - name: Download openFrameworks and add ofxPiMapper to addons
- run: |
- mkdir .ofxPiMapper
- mv ./* .ofxPiMapper/
- wget ${OF_URL} --tries=10 --quiet
- echo "Unarchive openFrameworks"
- OF_ARCHIVE_NAME=$(basename -- "$OF_URL")
- unzip ${OF_ARCHIVE_NAME}
- rm ${OF_ARCHIVE_NAME}
- OF_EXTRACT_NAME=$(basename ${OF_ARCHIVE_NAME} .zip)
- mv ${OF_EXTRACT_NAME} openFrameworks
- mv .ofxPiMapper openFrameworks/addons/ofxPiMapper
- - name: Install Dependencies
- run: |
- set -ev
- brew update
- brew install gdb
- brew install coreutils
- - name: Compile openFrameworks
- working-directory: ./openFrameworks/scripts/templates/osx
- run: make
- - name: Compile example_basic
- working-directory: ./openFrameworks/addons/ofxPiMapper/example_basic
- run: mv addons.make.norpi addons.make && make
- - name: Compile example_camera
- working-directory: ./openFrameworks/addons/ofxPiMapper/example_camera
- run: mv addons.make.norpi addons.make && make
- - name: Compile example_fbo-sources
- working-directory: ./openFrameworks/addons/ofxPiMapper/example_fbo-sources
- run: mv addons.make.norpi addons.make && make
- - name: Compile example_pocketvj
- working-directory: ./openFrameworks/addons/ofxPiMapper/example_pocketvj
- run: mv addons.make.norpi addons.make && make
- - name: Install ofxJSON dependency
- working-directory: ./openFrameworks/addons/
- run: git clone https://github.com/jeffcrouse/ofxJSON.git --depth 1
- - name: Compile example_remote-client
- working-directory: ./openFrameworks/addons/ofxPiMapper/example_remote-client
- run: mv addons.make.norpi addons.make && make
- - name: Compile example_remote-server
- working-directory: ./openFrameworks/addons/ofxPiMapper/example_remote-server
- run: mv addons.make.norpi addons.make && make
- - name: Compile example_simpler
- working-directory: ./openFrameworks/addons/ofxPiMapper/example_simpler
- run: mv addons.make.norpi addons.make && make
+name: osx
+on:
+ push:
+ branches:
+ - master
+jobs:
+ compile:
+ runs-on: macos-latest
+ env:
+ OF_URL: https://github.com/openframeworks/openFrameworks/releases/download/0.11.2/of_v0.11.2_osx_release.zip
+ steps:
+ - name: Fetch ofxPiMapper
+ uses: actions/checkout@v2
+ with:
+ fetch-depth: 1
+ - name: Download openFrameworks and add ofxPiMapper to addons
+ run: |
+ mkdir .ofxPiMapper
+ mv ./* .ofxPiMapper/
+ wget ${OF_URL} --tries=10 --quiet
+ echo "Unarchive openFrameworks"
+ OF_ARCHIVE_NAME=$(basename -- "$OF_URL")
+ unzip ${OF_ARCHIVE_NAME}
+ rm ${OF_ARCHIVE_NAME}
+ OF_EXTRACT_NAME=$(basename ${OF_ARCHIVE_NAME} .zip)
+ mv ${OF_EXTRACT_NAME} openFrameworks
+ mv .ofxPiMapper openFrameworks/addons/ofxPiMapper
+ - name: Install Dependencies
+ run: |
+ set -ev
+ brew update
+ brew install gdb
+ brew install coreutils
+ - name: Compile openFrameworks
+ working-directory: ./openFrameworks/scripts/templates/osx
+ run: make
+ - name: Compile example_basic
+ working-directory: ./openFrameworks/addons/ofxPiMapper/example_basic
+ run: mv addons.make.norpi addons.make && make
+ - name: Compile example_camera
+ working-directory: ./openFrameworks/addons/ofxPiMapper/example_camera
+ run: mv addons.make.norpi addons.make && make
+ - name: Compile example_fbo-sources
+ working-directory: ./openFrameworks/addons/ofxPiMapper/example_fbo-sources
+ run: mv addons.make.norpi addons.make && make
+ - name: Compile example_pocketvj
+ working-directory: ./openFrameworks/addons/ofxPiMapper/example_pocketvj
+ run: mv addons.make.norpi addons.make && make
+ - name: Install ofxJSON dependency
+ working-directory: ./openFrameworks/addons/
+ run: git clone https://github.com/jeffcrouse/ofxJSON.git --depth 1
+ - name: Compile example_remote-client
+ working-directory: ./openFrameworks/addons/ofxPiMapper/example_remote-client
+ run: mv addons.make.norpi addons.make && make
+ - name: Compile example_remote-server
+ working-directory: ./openFrameworks/addons/ofxPiMapper/example_remote-server
+ run: mv addons.make.norpi addons.make && make
+ - name: Compile example_simpler
+ working-directory: ./openFrameworks/addons/ofxPiMapper/example_simpler
+ run: mv addons.make.norpi addons.make && make
diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml
index 93cc5ec..88dff75 100644
--- a/.github/workflows/windows.yml
+++ b/.github/workflows/windows.yml
@@ -1,67 +1,67 @@
-name: windows
-on:
- push:
- branches:
- - master
-jobs:
- compile:
- runs-on: windows-latest
- env:
- OF_URL: https://github.com/openframeworks/openFrameworks/releases/download/0.11.2/of_v0.11.2_msys2_mingw64_release.zip
- defaults:
- run:
- shell: msys2 {0}
- steps:
- - uses: msys2/setup-msys2@v2
- with:
- update: true
- install: unzip git
- msystem: MINGW64
- - uses: actions/checkout@v2
- with:
- fetch-depth: 1
- - name: Download openFrameworks and add ofxPiMapper to addons
- run: |
- mkdir .ofxPiMapper
- mv ./* .ofxPiMapper/
- wget ${OF_URL} --tries=10 --quiet
- echo "Unarchive openFrameworks"
- OF_ARCHIVE_NAME=$(basename -- "$OF_URL")
- unzip ${OF_ARCHIVE_NAME}
- rm ${OF_ARCHIVE_NAME}
- OF_EXTRACT_NAME=$(basename ${OF_ARCHIVE_NAME} .zip)
- mv ${OF_EXTRACT_NAME} openFrameworks
- mv .ofxPiMapper openFrameworks/addons/ofxPiMapper
- - name: Install openFrameworks Dependencies
- working-directory: ./openFrameworks/scripts/msys2
- run: ./install_dependencies.sh --noconfirm
- - name: Apply patches
- working-directory: ./openFrameworks/addons/ofxPiMapper/patches/msys2
- run: ./patch.sh
- - name: Compile openFrameworks
- working-directory: ./openFrameworks/scripts/msys2
- run: ./compileOF.sh
- - name: Compile example_basic
- working-directory: ./openFrameworks/addons/ofxPiMapper/example_basic
- run: mv addons.make.norpi addons.make && make
- - name: Compile example_camera
- working-directory: ./openFrameworks/addons/ofxPiMapper/example_camera
- run: mv addons.make.norpi addons.make && make
- - name: Compile example_fbo-sources
- working-directory: ./openFrameworks/addons/ofxPiMapper/example_fbo-sources
- run: mv addons.make.norpi addons.make && make
- - name: Compile example_pocketvj
- working-directory: ./openFrameworks/addons/ofxPiMapper/example_pocketvj
- run: mv addons.make.norpi addons.make && make
- - name: Install ofxJSON dependency
- working-directory: ./openFrameworks/addons/
- run: git clone https://github.com/jeffcrouse/ofxJSON.git --depth 1
- - name: Compile example_remote-client
- working-directory: ./openFrameworks/addons/ofxPiMapper/example_remote-client
- run: mv addons.make.norpi addons.make && make
- - name: Compile example_remote-server
- working-directory: ./openFrameworks/addons/ofxPiMapper/example_remote-server
- run: mv addons.make.norpi addons.make && make
- - name: Compile example_simpler
- working-directory: ./openFrameworks/addons/ofxPiMapper/example_simpler
- run: mv addons.make.norpi addons.make && make
+name: windows
+on:
+ push:
+ branches:
+ - master
+jobs:
+ compile:
+ runs-on: windows-latest
+ env:
+ OF_URL: https://github.com/openframeworks/openFrameworks/releases/download/0.11.2/of_v0.11.2_msys2_mingw64_release.zip
+ defaults:
+ run:
+ shell: msys2 {0}
+ steps:
+ - uses: msys2/setup-msys2@v2
+ with:
+ update: true
+ install: unzip git
+ msystem: MINGW64
+ - uses: actions/checkout@v2
+ with:
+ fetch-depth: 1
+ - name: Download openFrameworks and add ofxPiMapper to addons
+ run: |
+ mkdir .ofxPiMapper
+ mv ./* .ofxPiMapper/
+ wget ${OF_URL} --tries=10 --quiet
+ echo "Unarchive openFrameworks"
+ OF_ARCHIVE_NAME=$(basename -- "$OF_URL")
+ unzip ${OF_ARCHIVE_NAME}
+ rm ${OF_ARCHIVE_NAME}
+ OF_EXTRACT_NAME=$(basename ${OF_ARCHIVE_NAME} .zip)
+ mv ${OF_EXTRACT_NAME} openFrameworks
+ mv .ofxPiMapper openFrameworks/addons/ofxPiMapper
+ - name: Install openFrameworks Dependencies
+ working-directory: ./openFrameworks/scripts/msys2
+ run: ./install_dependencies.sh --noconfirm
+ - name: Apply patches
+ working-directory: ./openFrameworks/addons/ofxPiMapper/patches/msys2
+ run: ./patch.sh
+ - name: Compile openFrameworks
+ working-directory: ./openFrameworks/scripts/msys2
+ run: ./compileOF.sh
+ - name: Compile example_basic
+ working-directory: ./openFrameworks/addons/ofxPiMapper/example_basic
+ run: mv addons.make.norpi addons.make && make
+ - name: Compile example_camera
+ working-directory: ./openFrameworks/addons/ofxPiMapper/example_camera
+ run: mv addons.make.norpi addons.make && make
+ - name: Compile example_fbo-sources
+ working-directory: ./openFrameworks/addons/ofxPiMapper/example_fbo-sources
+ run: mv addons.make.norpi addons.make && make
+ - name: Compile example_pocketvj
+ working-directory: ./openFrameworks/addons/ofxPiMapper/example_pocketvj
+ run: mv addons.make.norpi addons.make && make
+ - name: Install ofxJSON dependency
+ working-directory: ./openFrameworks/addons/
+ run: git clone https://github.com/jeffcrouse/ofxJSON.git --depth 1
+ - name: Compile example_remote-client
+ working-directory: ./openFrameworks/addons/ofxPiMapper/example_remote-client
+ run: mv addons.make.norpi addons.make && make
+ - name: Compile example_remote-server
+ working-directory: ./openFrameworks/addons/ofxPiMapper/example_remote-server
+ run: mv addons.make.norpi addons.make && make
+ - name: Compile example_simpler
+ working-directory: ./openFrameworks/addons/ofxPiMapper/example_simpler
+ run: mv addons.make.norpi addons.make && make
diff --git a/.gitignore b/.gitignore
index 8cd07bf..b6ae21c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,121 +1,121 @@
-#########################
-# general patterns
-#########################
-
-docs/html
-docs/tagfile.xml
-
-*/bin/*
-!*/bin/data/
-
-# for bin folder in root
-/bin/*
-!/bin/data/
-
-[Bb]uild/
-[Oo]bj/
-*.o
-[Dd]ebug*/
-[Rr]elease*/
-*.mode*
-*.app/
-*.pyc
-.svn/
-
-#########################
-# IDE
-#########################
-
-# XCode
-*.pbxuser
-*.perspective
-*.perspectivev3
-*.mode1v3
-*.mode2v3
-#XCode 4
-xcuserdata
-*.xcworkspace
-
-# Code::Blocks
-*.depend
-*.layout
-*.cbTemp
-
-# Visual Studio
-*.sdf
-*.opensdf
-*.suo
-*.pdb
-*.ilk
-*.aps
-ipch/
-
-# Eclipse
-.metadata
-local.properties
-.externalToolBuilders
-
-# Codelite
-*.session
-*.tags
-*.workspace.*
-
-#########################
-# operating system
-#########################
-
-# Linux
-*~
-# KDE
-.directory
-.AppleDouble
-
-# OSX
-.DS_Store
-*.swp
-*~.nib
-# Thumbnails
-._*
-
-# Windows
-# Windows image file caches
-Thumbs.db
-# Folder config file
-Desktop.ini
-
-#Android
-.csettings
-
-#########################
-# packages
-#########################
-
-# it's better to unpack these files and commit the raw source
-# git has its own built in compression methods
-*.7z
-*.dmg
-*.gz
-*.iso
-*.jar
-*.rar
-*.tar
-*.zip
-
-# Logs and databases
-*.log
-*.sql
-*.sqlite
-
-example/cmake-build-debug/
-
-example/\.idea/
-
-example/cmake-build-release/
-
-example/example\.xcodeproj/xcshareddata/xcschemes/
-
-.idea/
-
-cmake-build-debug/
-
-CMakeLists\.txt
+#########################
+# general patterns
+#########################
+
+docs/html
+docs/tagfile.xml
+
+*/bin/*
+!*/bin/data/
+
+# for bin folder in root
+/bin/*
+!/bin/data/
+
+[Bb]uild/
+[Oo]bj/
+*.o
+[Dd]ebug*/
+[Rr]elease*/
+*.mode*
+*.app/
+*.pyc
+.svn/
+
+#########################
+# IDE
+#########################
+
+# XCode
+*.pbxuser
+*.perspective
+*.perspectivev3
+*.mode1v3
+*.mode2v3
+#XCode 4
+xcuserdata
+*.xcworkspace
+
+# Code::Blocks
+*.depend
+*.layout
+*.cbTemp
+
+# Visual Studio
+*.sdf
+*.opensdf
+*.suo
+*.pdb
+*.ilk
+*.aps
+ipch/
+
+# Eclipse
+.metadata
+local.properties
+.externalToolBuilders
+
+# Codelite
+*.session
+*.tags
+*.workspace.*
+
+#########################
+# operating system
+#########################
+
+# Linux
+*~
+# KDE
+.directory
+.AppleDouble
+
+# OSX
+.DS_Store
+*.swp
+*~.nib
+# Thumbnails
+._*
+
+# Windows
+# Windows image file caches
+Thumbs.db
+# Folder config file
+Desktop.ini
+
+#Android
+.csettings
+
+#########################
+# packages
+#########################
+
+# it's better to unpack these files and commit the raw source
+# git has its own built in compression methods
+*.7z
+*.dmg
+*.gz
+*.iso
+*.jar
+*.rar
+*.tar
+*.zip
+
+# Logs and databases
+*.log
+*.sql
+*.sqlite
+
+example/cmake-build-debug/
+
+example/\.idea/
+
+example/cmake-build-release/
+
+example/example\.xcodeproj/xcshareddata/xcschemes/
+
+.idea/
+
+cmake-build-debug/
+
+CMakeLists\.txt
diff --git a/LICENSE.md b/LICENSE.md
index 57dd202..882064b 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -1,9 +1,9 @@
-ofxPiMapper is distributed under the [MIT License](https://secure.wikimedia.org/wikipedia/en/wiki/Mit_license). This gives everyone the freedoms to use ofxPiMapper in any context: commercial or non-commercial, public or private, open or closed source.
-
-**Copyright (c) 2014–2021, Krisjanis Rijnieks and contributors**
-
-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.
+ofxPiMapper is distributed under the [MIT License](https://secure.wikimedia.org/wikipedia/en/wiki/Mit_license). This gives everyone the freedoms to use ofxPiMapper in any context: commercial or non-commercial, public or private, open or closed source.
+
+**Copyright (c) 2014–2021, Krisjanis Rijnieks and contributors**
+
+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.
diff --git a/README.md b/README.md
index 57f9d34..25b2e81 100644
--- a/README.md
+++ b/README.md
@@ -1,248 +1,248 @@
-# ofxPiMapper
-
-[](https://github.com/kr15h/ofxPiMapper/actions?query=workflow%3Alinux)
-[](https://github.com/kr15h/ofxPiMapper/actions?query=workflow%3Awindows)
-[](https://github.com/kr15h/ofxPiMapper/actions?query=workflow%3Aosx)
-
-Projection mapping addon for openFrameworks that runs on the Raspberry Pi. It has been tested against openFrameworks version (0.11.0).
-
-The project started as master's thesis project by [Krisjanis Rijnieks](https://rijnieks.com) at the [Aalto Media Lab](https://www.aalto.fi/en/aalto-media-lab). Currently being developed during free time. Please [donate](https://ofxpimapper.com/) to create more free time.
-
-Note on build status: GitHub Actions ubuntu-latest, windows-latest and osx-latest images with 64bit environments are used. To be reviewed.
-
-## Disk Image
-
-For those not using openFrameworks, there is a precompiled disk image available via [ofxPiMapper website](https://ofxpimapper.com). It works with Raspberry Pi up until version 3B+ (with the older BCM2837 chip). Given the recent growing interest in the project, some effort is being put into figuring out how to make the disk image to work on Pi 4 and Pi 5 (and Pi 3B+ with the more recent BCM2837B0 chip). Please [donate](https://ofxpimapper.com/) to increase the frequency and duration of these efforts.
-
-> **Warning!** It does not work on the latest generation of Raspberry Pi 3B+ with the BCM2837B0 chip. Make sure the Pi has the older BCM2837 chip when purchasing.
-
-## Introduction
-
-This repository contains the addon for [openFrameworks](https://openframeworks.cc). It is expected to be used as an extension for your custom openFrameworks project where you create a custom [FBO source](example_fbo-sources) that is being animated by an advanced process rather than a plain video.
-
-If you are planning to use videos and images only, consider using the precompiled Raspberry Pi image available from the [ofxPiMapper website](https://ofxpimapper.com). It is based on a recent Raspberry Pi OS disk image and contains compiled installation of openFrameworks along with all the scripts and services that make Pi Mapper start automatically.
-
-## Installation
-
-Clone or download the repository to your openFrameworks addons folder. Make sure that default openFrameworks examples compile and run before trying ofxPiMapper examples. There are a few things that you should do depending on if you are compiling on the Raspberry Pi or not.
-
-- Raspberry Pi
- Please install the [ofxOMXPlayer](https://github.com/jvcleave/ofxOMXPlayer) addon before compiling.
-- Windows MSYS2
- Go to `patches/msys2` directory and run `./patch.sh`
-- Other platforms
- Please rename the `addons.make.rpi` file to `addons.make`.
-
-To test, use Terminal to change the directory to `example_basic`, compile and run.
-
-```
-cd path/to/openFrameworks/addons/ofxPiMapper/example_basic
-make
-cd bin
-./example_basic
-```
-
-If you plan to use `example_remote-server` and `example_remote-client`, make sure that you have added [ofxJSON](https://github.com/jeffcrouse/ofxJSON) dependency to your `openFrameworks/addons` folder prior compilation.
-
-## Usage
-
-Currently a keyboard and a mouse has to be used in order to do the mapping with ofxPiMapper.
-
-
-### Modes
-
-PiMapper has 4 modes:
-
-1. Presentation mode
-2. Texture mapping mode
-3. Surface editing mode
-4. Source assignment mode
-
-You can access these modes by pressing 1, 2, 3 or 4 respectively.
-
-
-#### Presentation mode
-
-This mode is activated once the application starts up. It does not show anything else except the final projection mapping as it was saved previously.
-
-
-#### Texture mapping mode
-
-In this mode you can adjust the texture coordinates of the surface you have selected in the surface editing mode.
-
-
-#### Surface editing mode
-
-Here you can select, move and distort the surfaces you have created.
-
-
-#### Source assignment mode
-
-After you select a surface in surface editing mode, activate this mode to be able to choose a source for the surface. Afterwards you might want to go to the texture mapping mode to adjust texture coordinates.
-
-
-### Other shortcuts
-
-These other shortcuts that you can use while using the example app.
-
-Key | Function
-:--- | :---
-1 | Presentation mode
-2 | Texture editing mode
-3 | Projection mapping mode, use this to select a surface first
-4 | Source selection mode
-i | Show info
-t | Add triangle surface
-q | Add quad surface
-g | Add grid warp surface
-c | Add circle surface
-d | Duplicate selected surface
-\+ | Scale surface up
-\- | Scale surface down
-p | Toggle perspective warping (quad surfaces only)
-F | Expand selected surface to fill the screen (quad surfaces only)
-] | Add columns to grid surface (grid warp surfaces only)
-[ | Remove columns from grid surface (grid warp surfaces only)
-} | Add rows to grid surface (grid warp surfaces only)
-{ | Remove rows from grid surface (grid warp surfaces only)
-. | Select next surface (projection mapping mode only)
-, | Select previous surface (projection mapping mode only)
-\> | Select next vertex
-\< | Select previous vertex
-0 | Move selected surface one layer up
-9 | Move selected surface one layer down
-s | Save composition
-l | Hide/show layer panel
-z | Undo
-rbt | Reboot (Raspberry Pi only)
-sdn | Shutdown (Raspberry Pi only)
-new | Clear composition (remove all surfaces)
-ext | Exit application and return to command line
-BACKSPACE ('\' via SSH) | Delete surface.
-SPACE | Toggle pause for video sources (texture and projection mapping modes)
-TAB | Select next source (no need to use the source selection interface)
-Arrow keys | Move selection. If no surface is selected in the projection mapping mode, all surfaces are moved.
-\/ | Toggle 1px/10px steps for keyboard moves on Raspberry Pi
-
-## Notes on Video Encoding
-
-Easiest way to achieve success is to use [HandBrake](https://handbrake.fr/) with the following settings. This will produce a `.mkv` file with 16bit FLAC audio with 22.05KHz sampling rate.
-
-```
-Preset: Fast 720p30
-Summary / Format: MKV File
-Video / Framerate: Same as source
-Video / Profile: Baseline
-Audio / Codec: FLAC 16-bit
-Audio / Samplerate: 22.05
-```
-
-If you are familiar with [ffmpeg](http://ffmpeg.org/), use the following. It will produce a `.mov` file. PCM audio codec with 22KHz sampling rate is used.
-
-```
-ffmpeg -i input-video.mp4 -s 1280x720 -aspect 16:9 \
- -c:v libx264 -profile:v baseline \
- -c:a pcm_s16le -ar 22000 -ac 2 \
- output-video.mov
-```
-
-These two settings have shown the best results so far. Audio problems and video playback at the beginning of longer video files was the main issue in most cases. Please open an issue if you have better suggestions.
-
-## Extended Functionality
-
-Examples represent extended functionality of ofxPiMapper. Enter each example separately to find out more.
-
-- [Basic Example](example_basic).
-- [FBO Sources Example](example_fbo-sources).
-- [Camera Example](example_camera).
-- [Remote Control Server](example_remote-server) example.
-- [Remote Control Client](example_remote-client) example.
-- Readme's for the rest are cooking...
-
-## Problems with Audio
-
-If you are having problems with audio playback, here are two steps for you. Before you do these, make sure audio of your video file works.
-
-
-### Step 1
-
-Open example openFrameworks application `ofApp.cpp` file in a text editor.
-
-```
-cd /home/pi/openFrameworks/addons/ofxPiMapper/example
-nano src/ofApp.cpp
-```
-
-Make sure that the following line looks as follows.
-
-```
-ofx::piMapper::VideoSource::enableAudio = true;
-```
-
-Save the file (CTRL + X, Y and ENTER). Recompile and run the example.
-
-```
-make && make run
-```
-
-### Step 2
-
-If the sound still does not work, try to use `raspi-config`.
-
-```
-sudo raspi-config
-```
-
-Select "7 Advanced Options" and "A9 Audio" then "0 Auto". You can use one of the force options if you want to be 100% sure.
-
-Open alsamixer.
-
-```
-alsamixer
-```
-
-Set the volume to a value between 90 to 100 by using the arrow keys. ESC to exit the mixer.
-
-Launch ofxPiMapper example, select a surface and set a video source with audio. Should work.
-
-
-## Development
-
-Keeping it simple. Developing ofxPiMapper master branch against the latest stable release version of openFrameworks.
-
-
-## Licence
-
-ofxPiMapper is distributed under the [MIT License](https://en.wikipedia.org/wiki/MIT_License). See the [LICENSE](LICENSE.md) file for further details. Just add my name somewhere along your project [Krisjanis Rijnieks](https://rijnieks.com) whenever possible.
-
-
-## Supporters
-
-You can become a supporter by donating BitCoins, via PayPal or becoming a Patreon. Please check https://ofxpimapper.com for details. List of supporters below.
-
-- [Marc-André Gasser](https://www.magdesign.ch/)
-- Manuel Meißner
-
-
-## Dependencies
-
-Before moving on, make sure that you have all the dependencies installed.
-
- - ofxGui (available in oF by default)
- - ofxXmlSettings (available in oF by default)
- - [ofxOMXPlayer](https://github.com/jvcleave/ofxOMXPlayer) (needed only on Raspberry Pi)
-
-To install dependencies, `cd` into `openFrameworks/addons` directory and execute the following:
-
-```bash
-git clone https://github.com/jvcleave/ofxOMXPlayer.git
-```
-
-The `ofxOMXPlayer` addon recommends you to use its releases. Currently the latest release is `0.9.0-compatible`. To checkout the code of the relase, go to the `ofxOMXPlayer` addon directory and checkout the relase.
-
-```
-cd openFrameworks/addons/ofxOMXPlayer
-git checkout 0.9.0-compatible
-```
-
-You can check the latest releases on the [ofxOMXPlayer GitHub repository](https://github.com/jvcleave/ofxOMXPlayer/releases).
+# ofxPiMapper
+
+[](https://github.com/kr15h/ofxPiMapper/actions?query=workflow%3Alinux)
+[](https://github.com/kr15h/ofxPiMapper/actions?query=workflow%3Awindows)
+[](https://github.com/kr15h/ofxPiMapper/actions?query=workflow%3Aosx)
+
+Projection mapping addon for openFrameworks that runs on the Raspberry Pi. It has been tested against openFrameworks version (0.11.0).
+
+The project started as master's thesis project by [Krisjanis Rijnieks](https://rijnieks.com) at the [Aalto Media Lab](https://www.aalto.fi/en/aalto-media-lab). Currently being developed during free time. Please [donate](https://ofxpimapper.com/) to create more free time.
+
+Note on build status: GitHub Actions ubuntu-latest, windows-latest and osx-latest images with 64bit environments are used. To be reviewed.
+
+## Disk Image
+
+For those not using openFrameworks, there is a precompiled disk image available via [ofxPiMapper website](https://ofxpimapper.com). It works with Raspberry Pi up until version 3B+ (with the older BCM2837 chip). Given the recent growing interest in the project, some effort is being put into figuring out how to make the disk image to work on Pi 4 and Pi 5 (and Pi 3B+ with the more recent BCM2837B0 chip). Please [donate](https://ofxpimapper.com/) to increase the frequency and duration of these efforts.
+
+> **Warning!** It does not work on the latest generation of Raspberry Pi 3B+ with the BCM2837B0 chip. Make sure the Pi has the older BCM2837 chip when purchasing.
+
+## Introduction
+
+This repository contains the addon for [openFrameworks](https://openframeworks.cc). It is expected to be used as an extension for your custom openFrameworks project where you create a custom [FBO source](example_fbo-sources) that is being animated by an advanced process rather than a plain video.
+
+If you are planning to use videos and images only, consider using the precompiled Raspberry Pi image available from the [ofxPiMapper website](https://ofxpimapper.com). It is based on a recent Raspberry Pi OS disk image and contains compiled installation of openFrameworks along with all the scripts and services that make Pi Mapper start automatically.
+
+## Installation
+
+Clone or download the repository to your openFrameworks addons folder. Make sure that default openFrameworks examples compile and run before trying ofxPiMapper examples. There are a few things that you should do depending on if you are compiling on the Raspberry Pi or not.
+
+- Raspberry Pi
+ Please install the [ofxOMXPlayer](https://github.com/jvcleave/ofxOMXPlayer) addon before compiling.
+- Windows MSYS2
+ Go to `patches/msys2` directory and run `./patch.sh`
+- Other platforms
+ Please rename the `addons.make.rpi` file to `addons.make`.
+
+To test, use Terminal to change the directory to `example_basic`, compile and run.
+
+```
+cd path/to/openFrameworks/addons/ofxPiMapper/example_basic
+make
+cd bin
+./example_basic
+```
+
+If you plan to use `example_remote-server` and `example_remote-client`, make sure that you have added [ofxJSON](https://github.com/jeffcrouse/ofxJSON) dependency to your `openFrameworks/addons` folder prior compilation.
+
+## Usage
+
+Currently a keyboard and a mouse has to be used in order to do the mapping with ofxPiMapper.
+
+
+### Modes
+
+PiMapper has 4 modes:
+
+1. Presentation mode
+2. Texture mapping mode
+3. Surface editing mode
+4. Source assignment mode
+
+You can access these modes by pressing 1, 2, 3 or 4 respectively.
+
+
+#### Presentation mode
+
+This mode is activated once the application starts up. It does not show anything else except the final projection mapping as it was saved previously.
+
+
+#### Texture mapping mode
+
+In this mode you can adjust the texture coordinates of the surface you have selected in the surface editing mode.
+
+
+#### Surface editing mode
+
+Here you can select, move and distort the surfaces you have created.
+
+
+#### Source assignment mode
+
+After you select a surface in surface editing mode, activate this mode to be able to choose a source for the surface. Afterwards you might want to go to the texture mapping mode to adjust texture coordinates.
+
+
+### Other shortcuts
+
+These other shortcuts that you can use while using the example app.
+
+Key | Function
+:--- | :---
+1 | Presentation mode
+2 | Texture editing mode
+3 | Projection mapping mode, use this to select a surface first
+4 | Source selection mode
+i | Show info
+t | Add triangle surface
+q | Add quad surface
+g | Add grid warp surface
+c | Add circle surface
+d | Duplicate selected surface
+\+ | Scale surface up
+\- | Scale surface down
+p | Toggle perspective warping (quad surfaces only)
+F | Expand selected surface to fill the screen (quad surfaces only)
+] | Add columns to grid surface (grid warp surfaces only)
+[ | Remove columns from grid surface (grid warp surfaces only)
+} | Add rows to grid surface (grid warp surfaces only)
+{ | Remove rows from grid surface (grid warp surfaces only)
+. | Select next surface (projection mapping mode only)
+, | Select previous surface (projection mapping mode only)
+\> | Select next vertex
+\< | Select previous vertex
+0 | Move selected surface one layer up
+9 | Move selected surface one layer down
+s | Save composition
+l | Hide/show layer panel
+z | Undo
+rbt | Reboot (Raspberry Pi only)
+sdn | Shutdown (Raspberry Pi only)
+new | Clear composition (remove all surfaces)
+ext | Exit application and return to command line
+BACKSPACE ('\' via SSH) | Delete surface.
+SPACE | Toggle pause for video sources (texture and projection mapping modes)
+TAB | Select next source (no need to use the source selection interface)
+Arrow keys | Move selection. If no surface is selected in the projection mapping mode, all surfaces are moved.
+\/ | Toggle 1px/10px steps for keyboard moves on Raspberry Pi
+
+## Notes on Video Encoding
+
+Easiest way to achieve success is to use [HandBrake](https://handbrake.fr/) with the following settings. This will produce a `.mkv` file with 16bit FLAC audio with 22.05KHz sampling rate.
+
+```
+Preset: Fast 720p30
+Summary / Format: MKV File
+Video / Framerate: Same as source
+Video / Profile: Baseline
+Audio / Codec: FLAC 16-bit
+Audio / Samplerate: 22.05
+```
+
+If you are familiar with [ffmpeg](http://ffmpeg.org/), use the following. It will produce a `.mov` file. PCM audio codec with 22KHz sampling rate is used.
+
+```
+ffmpeg -i input-video.mp4 -s 1280x720 -aspect 16:9 \
+ -c:v libx264 -profile:v baseline \
+ -c:a pcm_s16le -ar 22000 -ac 2 \
+ output-video.mov
+```
+
+These two settings have shown the best results so far. Audio problems and video playback at the beginning of longer video files was the main issue in most cases. Please open an issue if you have better suggestions.
+
+## Extended Functionality
+
+Examples represent extended functionality of ofxPiMapper. Enter each example separately to find out more.
+
+- [Basic Example](example_basic).
+- [FBO Sources Example](example_fbo-sources).
+- [Camera Example](example_camera).
+- [Remote Control Server](example_remote-server) example.
+- [Remote Control Client](example_remote-client) example.
+- Readme's for the rest are cooking...
+
+## Problems with Audio
+
+If you are having problems with audio playback, here are two steps for you. Before you do these, make sure audio of your video file works.
+
+
+### Step 1
+
+Open example openFrameworks application `ofApp.cpp` file in a text editor.
+
+```
+cd /home/pi/openFrameworks/addons/ofxPiMapper/example
+nano src/ofApp.cpp
+```
+
+Make sure that the following line looks as follows.
+
+```
+ofx::piMapper::VideoSource::enableAudio = true;
+```
+
+Save the file (CTRL + X, Y and ENTER). Recompile and run the example.
+
+```
+make && make run
+```
+
+### Step 2
+
+If the sound still does not work, try to use `raspi-config`.
+
+```
+sudo raspi-config
+```
+
+Select "7 Advanced Options" and "A9 Audio" then "0 Auto". You can use one of the force options if you want to be 100% sure.
+
+Open alsamixer.
+
+```
+alsamixer
+```
+
+Set the volume to a value between 90 to 100 by using the arrow keys. ESC to exit the mixer.
+
+Launch ofxPiMapper example, select a surface and set a video source with audio. Should work.
+
+
+## Development
+
+Keeping it simple. Developing ofxPiMapper master branch against the latest stable release version of openFrameworks.
+
+
+## Licence
+
+ofxPiMapper is distributed under the [MIT License](https://en.wikipedia.org/wiki/MIT_License). See the [LICENSE](LICENSE.md) file for further details. Just add my name somewhere along your project [Krisjanis Rijnieks](https://rijnieks.com) whenever possible.
+
+
+## Supporters
+
+You can become a supporter by donating BitCoins, via PayPal or becoming a Patreon. Please check https://ofxpimapper.com for details. List of supporters below.
+
+- [Marc-André Gasser](https://www.magdesign.ch/)
+- Manuel Meißner
+
+
+## Dependencies
+
+Before moving on, make sure that you have all the dependencies installed.
+
+ - ofxGui (available in oF by default)
+ - ofxXmlSettings (available in oF by default)
+ - [ofxOMXPlayer](https://github.com/jvcleave/ofxOMXPlayer) (needed only on Raspberry Pi)
+
+To install dependencies, `cd` into `openFrameworks/addons` directory and execute the following:
+
+```bash
+git clone https://github.com/jvcleave/ofxOMXPlayer.git
+```
+
+The `ofxOMXPlayer` addon recommends you to use its releases. Currently the latest release is `0.9.0-compatible`. To checkout the code of the relase, go to the `ofxOMXPlayer` addon directory and checkout the relase.
+
+```
+cd openFrameworks/addons/ofxOMXPlayer
+git checkout 0.9.0-compatible
+```
+
+You can check the latest releases on the [ofxOMXPlayer GitHub repository](https://github.com/jvcleave/ofxOMXPlayer/releases).
diff --git a/addon_config.mk b/addon_config.mk
index a7be1ec..0fb168b 100644
--- a/addon_config.mk
+++ b/addon_config.mk
@@ -1,76 +1,76 @@
-# All variables and this file are optional, if they are not present the PG and the
-# makefiles will try to parse the correct values from the file system.
-#
-# Variables that specify exclusions can use % as a wildcard to specify that anything in
-# that position will match. A partial path can also be specified to, for example, exclude
-# a whole folder from the parsed paths from the file system
-#
-# Variables can be specified using = or +=
-# = will clear the contents of that variable both specified from the file or the ones parsed
-# from the file system
-# += will add the values to the previous ones in the file or the ones parsed from the file
-# system
-#
-# The PG can be used to detect errors in this file, just create a new project with this addon
-# and the PG will write to the console the kind of error and in which line it is
-
-meta:
-ADDON_NAME = ofxPiMapper
-ADDON_DESCRIPTION = Projection mapping addon for openFrameworks
-ADDON_AUTHOR = @kr15h
-ADDON_TAGS = "addon" "rpi" "mapping"
-ADDON_URL = http://github.com/kr15h/ofxPiMapper
-
-common:
-# dependencies with other addons, a list of them separated by spaces
-# or use += in several lines
-ADDON_DEPENDENCIES = ofxXmlSettings ofxGui
-
-# include search paths, this will be usually parsed from the file system
-# but if the addon or addon libraries need special search paths they can be
-# specified here separated by spaces or one per line using +=
-# ADDON_INCLUDES =
-
-# any special flag that should be passed to the compiler when using this
-# addon
-# ADDON_CFLAGS =
-
-# any special flag that should be passed to the linker when using this
-# addon, also used for system libraries with -lname
-# ADDON_LDFLAGS =
-
-# linux only, any library that should be included in the project using
-# pkg-config
-# ADDON_PKG_CONFIG_LIBRARIES =
-
-# osx/iOS only, any framework that should be included in the project
-# ADDON_FRAMEWORKS =
-
-# source files, these will be usually parsed from the file system looking
-# in the src folders in libs and the root of the addon. if your addon needs
-# to include files in different places or a different set of files per platform
-# they can be specified here
-# ADDON_SOURCES =
-
-# some addons need resources to be copied to the bin/data folder of the project
-# specify here any files that need to be copied, you can use wildcards like * and ?
-# ADDON_DATA =
-
-# when parsing the file system looking for libraries exclude this for all or
-# a specific platform
-# ADDON_LIBS_EXCLUDE =
-
-linux64:
-# binary libraries, these will be usually parsed from the file system but some
-# libraries need to passed to the linker in a specific order
-ADDON_LIBS =
-linux:
-ADDON_LIBS =
-win_cb:
-ADDON_LIBS =
-linuxarmv6l:
-ADDON_LIBS =
-linuxarmv7l:
-ADDON_LIBS =
-android/armeabi:
-ADDON_LIBS =
+# All variables and this file are optional, if they are not present the PG and the
+# makefiles will try to parse the correct values from the file system.
+#
+# Variables that specify exclusions can use % as a wildcard to specify that anything in
+# that position will match. A partial path can also be specified to, for example, exclude
+# a whole folder from the parsed paths from the file system
+#
+# Variables can be specified using = or +=
+# = will clear the contents of that variable both specified from the file or the ones parsed
+# from the file system
+# += will add the values to the previous ones in the file or the ones parsed from the file
+# system
+#
+# The PG can be used to detect errors in this file, just create a new project with this addon
+# and the PG will write to the console the kind of error and in which line it is
+
+meta:
+ADDON_NAME = ofxPiMapper
+ADDON_DESCRIPTION = Projection mapping addon for openFrameworks
+ADDON_AUTHOR = @kr15h
+ADDON_TAGS = "addon" "rpi" "mapping"
+ADDON_URL = http://github.com/kr15h/ofxPiMapper
+
+common:
+# dependencies with other addons, a list of them separated by spaces
+# or use += in several lines
+ADDON_DEPENDENCIES = ofxXmlSettings ofxGui
+
+# include search paths, this will be usually parsed from the file system
+# but if the addon or addon libraries need special search paths they can be
+# specified here separated by spaces or one per line using +=
+# ADDON_INCLUDES =
+
+# any special flag that should be passed to the compiler when using this
+# addon
+# ADDON_CFLAGS =
+
+# any special flag that should be passed to the linker when using this
+# addon, also used for system libraries with -lname
+# ADDON_LDFLAGS =
+
+# linux only, any library that should be included in the project using
+# pkg-config
+# ADDON_PKG_CONFIG_LIBRARIES =
+
+# osx/iOS only, any framework that should be included in the project
+# ADDON_FRAMEWORKS =
+
+# source files, these will be usually parsed from the file system looking
+# in the src folders in libs and the root of the addon. if your addon needs
+# to include files in different places or a different set of files per platform
+# they can be specified here
+# ADDON_SOURCES =
+
+# some addons need resources to be copied to the bin/data folder of the project
+# specify here any files that need to be copied, you can use wildcards like * and ?
+# ADDON_DATA =
+
+# when parsing the file system looking for libraries exclude this for all or
+# a specific platform
+# ADDON_LIBS_EXCLUDE =
+
+linux64:
+# binary libraries, these will be usually parsed from the file system but some
+# libraries need to passed to the linker in a specific order
+ADDON_LIBS =
+linux:
+ADDON_LIBS =
+win_cb:
+ADDON_LIBS =
+linuxarmv6l:
+ADDON_LIBS =
+linuxarmv7l:
+ADDON_LIBS =
+android/armeabi:
+ADDON_LIBS =
diff --git a/example_basic/Makefile b/example_basic/Makefile
index 8d8e4c0..c83af71 100644
--- a/example_basic/Makefile
+++ b/example_basic/Makefile
@@ -1,13 +1,13 @@
-# Attempt to load a config.make file.
-# If none is found, project defaults in config.project.make will be used.
-ifneq ($(wildcard config.make),)
- include config.make
-endif
-
-# make sure the the OF_ROOT location is defined
-ifndef OF_ROOT
- OF_ROOT=$(realpath ../../..)
-endif
-
-# call the project makefile!
-include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk
+# Attempt to load a config.make file.
+# If none is found, project defaults in config.project.make will be used.
+ifneq ($(wildcard config.make),)
+ include config.make
+endif
+
+# make sure the the OF_ROOT location is defined
+ifndef OF_ROOT
+ OF_ROOT=$(realpath ../../..)
+endif
+
+# call the project makefile!
+include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk
diff --git a/example_basic/README.md b/example_basic/README.md
index f58ab84..9bff592 100644
--- a/example_basic/README.md
+++ b/example_basic/README.md
@@ -1,7 +1,7 @@
-# Basic Example
-
-This is a very basic example. It shows how to use ofxPiMapper addon with it's integrated functionality. You can map images and videos with this. ofxPiMapper takes care of loading and saving your composition.
-
-For now you have to put your sources under `bin/data/sources`. There are two directories: `images` and `videos`. As you may expect, put images in the `images` folder and videos in the `videos` one.
-
-The addon is made so that you have to pass the keyboard and mouse events to it. It is because in this way you can gain more control over how it behaves. If you do not pass the keyboard and mouse events, ofxPiMapper reads the configuration file from `data/ofxpimapper.xml` and continues working from there. It just starts up, loads the configuration and displays the composition until the application quits.
+# Basic Example
+
+This is a very basic example. It shows how to use ofxPiMapper addon with it's integrated functionality. You can map images and videos with this. ofxPiMapper takes care of loading and saving your composition.
+
+For now you have to put your sources under `bin/data/sources`. There are two directories: `images` and `videos`. As you may expect, put images in the `images` folder and videos in the `videos` one.
+
+The addon is made so that you have to pass the keyboard and mouse events to it. It is because in this way you can gain more control over how it behaves. If you do not pass the keyboard and mouse events, ofxPiMapper reads the configuration file from `data/ofxpimapper.xml` and continues working from there. It just starts up, loads the configuration and displays the composition until the application quits.
diff --git a/example_basic/addons.make b/example_basic/addons.make
index 963941c..596425d 100644
--- a/example_basic/addons.make
+++ b/example_basic/addons.make
@@ -1,4 +1,4 @@
-ofxGui
-ofxPiMapper
-ofxXmlSettings
-ofxOMXPlayer
+ofxGui
+ofxPiMapper
+ofxXmlSettings
+ofxOMXPlayer
diff --git a/example_basic/addons.make.norpi b/example_basic/addons.make.norpi
index e72d2dd..69d8f94 100644
--- a/example_basic/addons.make.norpi
+++ b/example_basic/addons.make.norpi
@@ -1,3 +1,3 @@
-ofxGui
-ofxPiMapper
-ofxXmlSettings
+ofxGui
+ofxPiMapper
+ofxXmlSettings
diff --git a/example_basic/bin/data/ofxpimapper.xml b/example_basic/bin/data/ofxpimapper.xml
index 1e79640..fe78244 100644
--- a/example_basic/bin/data/ofxpimapper.xml
+++ b/example_basic/bin/data/ofxpimapper.xml
@@ -1,36 +1,203 @@
-
-
-
-
- 512.000000000
- 50.000000000
-
-
- 974.000000000
- 718.000000000
-
-
- 50.000000000
- 718.000000000
-
-
-
-
- 0.500000000
- 0.000000000
-
-
- 1.000000000
- 1.000000000
-
-
- 0.000000000
- 1.000000000
-
-
-
- video
- gene-nsynthesis-loop-a.mp4
-
-
-
+
+
+
+
+ 452.000000000
+ 221.000000000
+
+
+ 1017.744750977
+ 744.464965820
+
+
+ 6.254730225
+ 744.464965820
+
+
+
+
+ 0.500000000
+ 0.000000000
+
+
+ 1.000000000
+ 1.000000000
+
+
+ 0.000000000
+ 1.000000000
+
+
+
+ video
+ gene-nsynthesis-loop-c.mp4
+ 1
+
+
+
+
+
+ 512.000000000
+ 50.000000000
+
+
+ 974.000000000
+ 718.000000000
+
+
+ 50.000000000
+ 718.000000000
+
+
+
+
+ 0.500000000
+ 0.000000000
+
+
+ 1.000000000
+ 1.000000000
+
+
+ 0.000000000
+ 1.000000000
+
+
+
+ video
+ gene-nsynthesis-loop-a.mp4
+ 1
+
+
+
+
+
+ -8.000000000
+ 6.000000000
+
+
+ 434.000000000
+ 250.000000000
+
+
+ 920.000000000
+ 101.000000000
+
+
+ -4.000000000
+ 397.000000000
+
+
+ 508.000000000
+ 385.000000000
+
+
+ 920.000000000
+ 385.000000000
+
+
+ 2.254730225
+ 745.464965820
+
+
+ 508.000000000
+ 669.000000000
+
+
+ 920.000000000
+ 669.000000000
+
+
+
+
+ 0.000000000
+ 0.000000000
+
+
+ 0.500000000
+ 0.000000000
+
+
+ 1.000000000
+ 0.000000000
+
+
+ 0.000000000
+ 0.500000000
+
+
+ 0.500000000
+ 0.500000000
+
+
+ 1.000000000
+ 0.500000000
+
+
+ 0.000000000
+ 1.000000000
+
+
+ 0.500000000
+ 1.000000000
+
+
+ 1.000000000
+ 1.000000000
+
+
+
+ none
+ none
+
+
+ 2
+ 2
+
+
+
+
+
+ 267.996795654
+ 22.747558594
+
+
+ 267.996795654
+ 147.252563477
+
+
+ 434.003723145
+ 147.252563477
+
+
+ 434.003723145
+ 22.747558594
+
+
+
+
+ 0.000000000
+ 0.000000000
+
+
+ 1.000000000
+ 0.000000000
+
+
+ 1.000000000
+ 1.000000000
+
+
+ 0.000000000
+ 1.000000000
+
+
+
+ none
+ none
+
+
+ 1
+
+
+
diff --git a/example_basic/src/main.cpp b/example_basic/src/main.cpp
index 1f97405..2da2b3b 100644
--- a/example_basic/src/main.cpp
+++ b/example_basic/src/main.cpp
@@ -1,7 +1,7 @@
-#include "ofMain.h"
-#include "ofApp.h"
-
-int main(){
- ofSetupOpenGL(1024,768,OF_WINDOW);
- ofRunApp(new ofApp());
-}
+#include "ofMain.h"
+#include "ofApp.h"
+
+int main(){
+ ofSetupOpenGL(1024,768,OF_WINDOW);
+ ofRunApp(new ofApp());
+}
diff --git a/example_basic/src/ofApp.cpp b/example_basic/src/ofApp.cpp
index c8b58d6..32b56db 100644
--- a/example_basic/src/ofApp.cpp
+++ b/example_basic/src/ofApp.cpp
@@ -1,38 +1,38 @@
-#include "ofApp.h"
-
-void ofApp::setup(){
- ofBackground(0);
- mapper.setup();
-
- #ifdef TARGET_RASPBERRY_PI
- ofSetFullscreen(true);
- #endif
-}
-
-void ofApp::update(){
- mapper.update();
-}
-
-void ofApp::draw(){
- mapper.draw();
-}
-
-void ofApp::keyPressed(int key){
- mapper.keyPressed(key);
-}
-
-void ofApp::keyReleased(int key){
- mapper.keyReleased(key);
-}
-
-void ofApp::mouseDragged(int x, int y, int button){
- mapper.mouseDragged(x, y, button);
-}
-
-void ofApp::mousePressed(int x, int y, int button){
- mapper.mousePressed(x, y, button);
-}
-
-void ofApp::mouseReleased(int x, int y, int button){
- mapper.mouseReleased(x, y, button);
-}
+#include "ofApp.h"
+
+void ofApp::setup(){
+ ofBackground(0);
+ mapper.setup();
+
+ #ifdef TARGET_RASPBERRY_PI
+ ofSetFullscreen(true);
+ #endif
+}
+
+void ofApp::update(){
+ mapper.update();
+}
+
+void ofApp::draw(){
+ mapper.draw();
+}
+
+void ofApp::keyPressed(int key){
+ mapper.keyPressed(key);
+}
+
+void ofApp::keyReleased(int key){
+ mapper.keyReleased(key);
+}
+
+void ofApp::mouseDragged(int x, int y, int button){
+ mapper.mouseDragged(x, y, button);
+}
+
+void ofApp::mousePressed(int x, int y, int button){
+ mapper.mousePressed(x, y, button);
+}
+
+void ofApp::mouseReleased(int x, int y, int button){
+ mapper.mouseReleased(x, y, button);
+}
diff --git a/example_basic/src/ofApp.h b/example_basic/src/ofApp.h
index c74bb4f..2bc449f 100644
--- a/example_basic/src/ofApp.h
+++ b/example_basic/src/ofApp.h
@@ -1,25 +1,25 @@
-#pragma once
-
-#include "ofMain.h"
-#include "ofxPiMapper.h"
-
-class ofApp : public ofBaseApp{
-public:
- void setup();
- void update();
- void draw();
-
- // We need to forward key and mouse events to ofxPiMapper.
- // By not doing it we have the opportunity to use ofxPiMapper
- // witout the interface.
-
- void keyPressed(int key);
- void keyReleased(int key);
-
- void mouseDragged(int x, int y, int button);
- void mousePressed(int x, int y, int button);
- void mouseReleased(int x, int y, int button);
-
- // This is our mapper object.
- ofxPiMapper mapper;
-};
+#pragma once
+
+#include "ofMain.h"
+#include "ofxPiMapper.h"
+
+class ofApp : public ofBaseApp{
+public:
+ void setup();
+ void update();
+ void draw();
+
+ // We need to forward key and mouse events to ofxPiMapper.
+ // By not doing it we have the opportunity to use ofxPiMapper
+ // witout the interface.
+
+ void keyPressed(int key);
+ void keyReleased(int key);
+
+ void mouseDragged(int x, int y, int button);
+ void mousePressed(int x, int y, int button);
+ void mouseReleased(int x, int y, int button);
+
+ // This is our mapper object.
+ ofxPiMapper mapper;
+};
diff --git a/example_camera/.gitignore b/example_camera/.gitignore
index e4d4b5d..ad71cfd 100644
--- a/example_camera/.gitignore
+++ b/example_camera/.gitignore
@@ -1,5 +1,5 @@
-obj
-*.xcworkspace
-*.xcuserdatad
-*~
-config.make
+obj
+*.xcworkspace
+*.xcuserdatad
+*~
+config.make
diff --git a/example_camera/Makefile b/example_camera/Makefile
index 8d8e4c0..c83af71 100644
--- a/example_camera/Makefile
+++ b/example_camera/Makefile
@@ -1,13 +1,13 @@
-# Attempt to load a config.make file.
-# If none is found, project defaults in config.project.make will be used.
-ifneq ($(wildcard config.make),)
- include config.make
-endif
-
-# make sure the the OF_ROOT location is defined
-ifndef OF_ROOT
- OF_ROOT=$(realpath ../../..)
-endif
-
-# call the project makefile!
-include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk
+# Attempt to load a config.make file.
+# If none is found, project defaults in config.project.make will be used.
+ifneq ($(wildcard config.make),)
+ include config.make
+endif
+
+# make sure the the OF_ROOT location is defined
+ifndef OF_ROOT
+ OF_ROOT=$(realpath ../../..)
+endif
+
+# call the project makefile!
+include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk
diff --git a/example_camera/README.md b/example_camera/README.md
index 09d037b..48148c4 100644
--- a/example_camera/README.md
+++ b/example_camera/README.md
@@ -1,9 +1,9 @@
-# Camera Example
-
-This example demonstrates the possibility to use camera input as a texture source. Make sure you clone the [ofxRPiCameraVideoGrabber](https://github.com/jvcleave/ofxRPiCameraVideoGrabber) addon into your `openFrameworks/addons` folder before compiling on Raspberry Pi.
-
-```
-cd openFrameworks/addons
-git clone https://github.com/jvcleave/ofxRPiCameraVideoGrabber.git
-```
-
+# Camera Example
+
+This example demonstrates the possibility to use camera input as a texture source. Make sure you clone the [ofxRPiCameraVideoGrabber](https://github.com/jvcleave/ofxRPiCameraVideoGrabber) addon into your `openFrameworks/addons` folder before compiling on Raspberry Pi.
+
+```
+cd openFrameworks/addons
+git clone https://github.com/jvcleave/ofxRPiCameraVideoGrabber.git
+```
+
diff --git a/example_camera/addons.make b/example_camera/addons.make
index 0bda1a1..bad4b22 100644
--- a/example_camera/addons.make
+++ b/example_camera/addons.make
@@ -1,5 +1,5 @@
-ofxGui
-ofxPiMapper
-ofxXmlSettings
-ofxOMXPlayer
-ofxRPiCameraVideoGrabber
+ofxGui
+ofxPiMapper
+ofxXmlSettings
+ofxOMXPlayer
+ofxRPiCameraVideoGrabber
diff --git a/example_camera/addons.make.norpi b/example_camera/addons.make.norpi
index e72d2dd..69d8f94 100644
--- a/example_camera/addons.make.norpi
+++ b/example_camera/addons.make.norpi
@@ -1,3 +1,3 @@
-ofxGui
-ofxPiMapper
-ofxXmlSettings
+ofxGui
+ofxPiMapper
+ofxXmlSettings
diff --git a/example_camera/bin/data/defaultSurfaces.xml b/example_camera/bin/data/defaultSurfaces.xml
index fc48ade..d4237fc 100755
--- a/example_camera/bin/data/defaultSurfaces.xml
+++ b/example_camera/bin/data/defaultSurfaces.xml
@@ -1,36 +1,36 @@
-
-
-
-
- 415.000000000
- 51.000000000
-
-
- 581.000000000
- 388.000000000
-
-
- 183.000000000
- 357.000000000
-
-
-
-
- 0.556249976
- 0.108333334
-
-
- 0.862500012
- 0.941666663
-
-
- 0.118749999
- 0.862500012
-
-
-
- fbo
- Camera Source
-
-
-
+
+
+
+
+ 415.000000000
+ 51.000000000
+
+
+ 581.000000000
+ 388.000000000
+
+
+ 183.000000000
+ 357.000000000
+
+
+
+
+ 0.556249976
+ 0.108333334
+
+
+ 0.862500012
+ 0.941666663
+
+
+ 0.118749999
+ 0.862500012
+
+
+
+ fbo
+ Camera Source
+
+
+
diff --git a/example_camera/bin/data/ofxpimapper.xml b/example_camera/bin/data/ofxpimapper.xml
index 11d445a..e1f90ab 100644
--- a/example_camera/bin/data/ofxpimapper.xml
+++ b/example_camera/bin/data/ofxpimapper.xml
@@ -1,70 +1,70 @@
-
-
-
-
- 437.000000000
- 82.000000000
-
-
- 991.000000000
- 75.000000000
-
-
- 750.000000000
- 485.000000000
-
-
-
-
- 0.351562500
- 0.072222225
-
-
- 0.857812524
- 0.125000000
-
-
- 0.549218774
- 0.695833325
-
-
-
- fbo
- Camera Source
-
-
-
-
-
- 437.000000000
- 82.000000000
-
-
- 750.000000000
- 485.000000000
-
-
- 112.000000000
- 476.000000000
-
-
-
-
- 0.341406256
- 0.073611110
-
-
- 0.557031274
- 0.690277755
-
-
- 0.064843751
- 0.558333337
-
-
-
- fbo
- Camera Source
-
-
-
+
+
+
+
+ 437.000000000
+ 82.000000000
+
+
+ 991.000000000
+ 75.000000000
+
+
+ 750.000000000
+ 485.000000000
+
+
+
+
+ 0.351562500
+ 0.072222225
+
+
+ 0.857812524
+ 0.125000000
+
+
+ 0.549218774
+ 0.695833325
+
+
+
+ fbo
+ Camera Source
+
+
+
+
+
+ 437.000000000
+ 82.000000000
+
+
+ 750.000000000
+ 485.000000000
+
+
+ 112.000000000
+ 476.000000000
+
+
+
+
+ 0.341406256
+ 0.073611110
+
+
+ 0.557031274
+ 0.690277755
+
+
+ 0.064843751
+ 0.558333337
+
+
+
+ fbo
+ Camera Source
+
+
+
diff --git a/example_camera/src/CameraSource.cpp b/example_camera/src/CameraSource.cpp
index 2513475..a5d6021 100644
--- a/example_camera/src/CameraSource.cpp
+++ b/example_camera/src/CameraSource.cpp
@@ -1,62 +1,62 @@
-#include "CameraSource.h"
-
-CameraSource::CameraSource(){
- name = "Camera Source";
-
- _cameraWidth = 1280;
- _cameraHeight = 720;
-
- #ifdef TARGET_RASPBERRY_PI
- _omxCameraSettings.width = _cameraWidth;
- _omxCameraSettings.height = _cameraHeight;
- _omxCameraSettings.framerate = 30;
- _omxCameraSettings.enableTexture = true;
- _omxCameraSettings.doRecording = false;
-
- _videoGrabber.setup(_omxCameraSettings);
- #else
- std::vector devices = _videoGrabber.listDevices();
- _cameraFound = false;
-
- for(int i = 0; i < devices.size(); i++){
- if(devices[i].bAvailable){
- ofLogNotice() << devices[i].id << ": " << devices[i].deviceName;
- _cameraFound = true;
- break;
- }
- }
-
- if(_cameraFound){
- _videoGrabber.setDeviceID(0);
- _videoGrabber.setup(_cameraWidth, _cameraHeight);
- }
- #endif
-
- allocate(_cameraWidth, _cameraHeight);
-}
-
-void CameraSource::update(){
- #ifndef TARGET_RASPBERRY_PI
- if(_videoGrabber.isInitialized()){
- _videoGrabber.update();
- }
- #endif
-}
-
-void CameraSource::draw(){
- ofClear(0);
- ofSetHexColor(0xffffff);
- #ifdef TARGET_RASPBERRY_PI
- ofDisableNormalizedTexCoords();
- _videoGrabber.draw(0, 0);
- ofEnableNormalizedTexCoords();
- #else
- if(_videoGrabber.isInitialized()){
- ofDisableNormalizedTexCoords();
- _videoGrabber.draw(0, 0);
- ofEnableNormalizedTexCoords();
- }else{
- ofDrawBitmapString("no camera", _cameraWidth / 2.0f - 40.0f, _cameraHeight / 2.0f + 10.0f);
- }
- #endif
-}
+#include "CameraSource.h"
+
+CameraSource::CameraSource(){
+ name = "Camera Source";
+
+ _cameraWidth = 1280;
+ _cameraHeight = 720;
+
+ #ifdef TARGET_RASPBERRY_PI
+ _omxCameraSettings.width = _cameraWidth;
+ _omxCameraSettings.height = _cameraHeight;
+ _omxCameraSettings.framerate = 30;
+ _omxCameraSettings.enableTexture = true;
+ _omxCameraSettings.doRecording = false;
+
+ _videoGrabber.setup(_omxCameraSettings);
+ #else
+ std::vector devices = _videoGrabber.listDevices();
+ _cameraFound = false;
+
+ for(int i = 0; i < devices.size(); i++){
+ if(devices[i].bAvailable){
+ ofLogNotice() << devices[i].id << ": " << devices[i].deviceName;
+ _cameraFound = true;
+ break;
+ }
+ }
+
+ if(_cameraFound){
+ _videoGrabber.setDeviceID(0);
+ _videoGrabber.setup(_cameraWidth, _cameraHeight);
+ }
+ #endif
+
+ allocate(_cameraWidth, _cameraHeight);
+}
+
+void CameraSource::update(){
+ #ifndef TARGET_RASPBERRY_PI
+ if(_videoGrabber.isInitialized()){
+ _videoGrabber.update();
+ }
+ #endif
+}
+
+void CameraSource::draw(){
+ ofClear(0);
+ ofSetHexColor(0xffffff);
+ #ifdef TARGET_RASPBERRY_PI
+ ofDisableNormalizedTexCoords();
+ _videoGrabber.draw(0, 0);
+ ofEnableNormalizedTexCoords();
+ #else
+ if(_videoGrabber.isInitialized()){
+ ofDisableNormalizedTexCoords();
+ _videoGrabber.draw(0, 0);
+ ofEnableNormalizedTexCoords();
+ }else{
+ ofDrawBitmapString("no camera", _cameraWidth / 2.0f - 40.0f, _cameraHeight / 2.0f + 10.0f);
+ }
+ #endif
+}
diff --git a/example_camera/src/CameraSource.h b/example_camera/src/CameraSource.h
index 5a6ecb2..61aadc2 100644
--- a/example_camera/src/CameraSource.h
+++ b/example_camera/src/CameraSource.h
@@ -1,34 +1,34 @@
-/*
- * CameraSource
- * Camera source for ofxPiMapper
- * Created by Krisjanis Rijnieks on 25/01/2016
- */
-
-#pragma once
-
-#include "ofMain.h"
-#include "FboSource.h"
-
-#ifdef TARGET_RASPBERRY_PI
- #include "ofxRPiCameraVideoGrabber.h"
-#endif
-
-class CameraSource : public ofx::piMapper::FboSource {
- public:
- CameraSource();
-
- void update();
- void draw();
-
- private:
-
- #ifdef TARGET_RASPBERRY_PI
- OMXCameraSettings _omxCameraSettings;
- ofxRPiCameraVideoGrabber _videoGrabber;
- #else
- ofVideoGrabber _videoGrabber;
- #endif
- int _cameraWidth;
- int _cameraHeight;
- bool _cameraFound;
+/*
+ * CameraSource
+ * Camera source for ofxPiMapper
+ * Created by Krisjanis Rijnieks on 25/01/2016
+ */
+
+#pragma once
+
+#include "ofMain.h"
+#include "FboSource.h"
+
+#ifdef TARGET_RASPBERRY_PI
+ #include "ofxRPiCameraVideoGrabber.h"
+#endif
+
+class CameraSource : public ofx::piMapper::FboSource {
+ public:
+ CameraSource();
+
+ void update();
+ void draw();
+
+ private:
+
+ #ifdef TARGET_RASPBERRY_PI
+ OMXCameraSettings _omxCameraSettings;
+ ofxRPiCameraVideoGrabber _videoGrabber;
+ #else
+ ofVideoGrabber _videoGrabber;
+ #endif
+ int _cameraWidth;
+ int _cameraHeight;
+ bool _cameraFound;
};
\ No newline at end of file
diff --git a/example_camera/src/main.cpp b/example_camera/src/main.cpp
index 602382f..a518e54 100644
--- a/example_camera/src/main.cpp
+++ b/example_camera/src/main.cpp
@@ -1,24 +1,24 @@
-#include "ofMain.h"
-#include "ofApp.h"
-#include
-#include
-
-int main(int argc, char * argv[]){
- bool fullscreen = false;
-
- std::vector arguments = std::vector(argv, argv + argc);
- for(int i = 0; i < arguments.size(); ++i){
- if(arguments.at(i) == "-f"){
- fullscreen = true;
- break;
- }
- }
-
- if(fullscreen){
- ofSetupOpenGL(800, 450, OF_FULLSCREEN);
- }else{
- ofSetupOpenGL(800, 450, OF_WINDOW);
- }
-
- ofRunApp(new ofApp());
-}
+#include "ofMain.h"
+#include "ofApp.h"
+#include
+#include
+
+int main(int argc, char * argv[]){
+ bool fullscreen = false;
+
+ std::vector arguments = std::vector(argv, argv + argc);
+ for(int i = 0; i < arguments.size(); ++i){
+ if(arguments.at(i) == "-f"){
+ fullscreen = true;
+ break;
+ }
+ }
+
+ if(fullscreen){
+ ofSetupOpenGL(800, 450, OF_FULLSCREEN);
+ }else{
+ ofSetupOpenGL(800, 450, OF_WINDOW);
+ }
+
+ ofRunApp(new ofApp());
+}
diff --git a/example_camera/src/ofApp.cpp b/example_camera/src/ofApp.cpp
index 9751f39..8ea1615 100644
--- a/example_camera/src/ofApp.cpp
+++ b/example_camera/src/ofApp.cpp
@@ -1,36 +1,36 @@
-#include "ofApp.h"
-
-void ofApp::setup(){
- ofBackground(0);
- cameraSource = new CameraSource();
- piMapper.registerFboSource(*cameraSource);
- piMapper.setup();
-}
-
-void ofApp::update(){
- piMapper.update();
-}
-
-void ofApp::draw(){
- piMapper.draw();
-}
-
-void ofApp::keyPressed(int key){
- piMapper.keyPressed(key);
-}
-
-void ofApp::keyReleased(int key){
- piMapper.keyReleased(key);
-}
-
-void ofApp::mousePressed(int x, int y, int button){
- piMapper.mousePressed(x, y, button);
-}
-
-void ofApp::mouseDragged(int x, int y, int button){
- piMapper.mouseDragged(x, y, button);
-}
-
-void ofApp::mouseReleased(int x, int y, int button){
- piMapper.mouseReleased(x, y, button);
-}
+#include "ofApp.h"
+
+void ofApp::setup(){
+ ofBackground(0);
+ cameraSource = new CameraSource();
+ piMapper.registerFboSource(*cameraSource);
+ piMapper.setup();
+}
+
+void ofApp::update(){
+ piMapper.update();
+}
+
+void ofApp::draw(){
+ piMapper.draw();
+}
+
+void ofApp::keyPressed(int key){
+ piMapper.keyPressed(key);
+}
+
+void ofApp::keyReleased(int key){
+ piMapper.keyReleased(key);
+}
+
+void ofApp::mousePressed(int x, int y, int button){
+ piMapper.mousePressed(x, y, button);
+}
+
+void ofApp::mouseDragged(int x, int y, int button){
+ piMapper.mouseDragged(x, y, button);
+}
+
+void ofApp::mouseReleased(int x, int y, int button){
+ piMapper.mouseReleased(x, y, button);
+}
diff --git a/example_camera/src/ofApp.h b/example_camera/src/ofApp.h
index a76db1a..8719b9c 100644
--- a/example_camera/src/ofApp.h
+++ b/example_camera/src/ofApp.h
@@ -1,31 +1,31 @@
-/*
- * CameraSource example
- * Can be used with the Raspberry Pi camera module or the Auvidea HDMI bridge.
- * B101 HDMI to CSI-2 Bridge (15 pin FPC).
- * Available at http://www.auvidea.eu/index.php/theme-styles/2014-12-30-22-32-06/b101
- * Created by Krisjanis Rijnieks on 25/01/2016
- * Last modified on 10/02/2016
- */
-
-#pragma once
-
-#include "ofMain.h"
-#include "ofxPiMapper.h"
-#include "CameraSource.h"
-
-class ofApp : public ofBaseApp {
- public:
- void setup();
- void update();
- void draw();
-
- void keyPressed(int key);
- void keyReleased(int key);
-
- void mousePressed(int x, int y, int button);
- void mouseDragged(int x, int y, int button);
- void mouseReleased(int x, int y, int button);
-
- ofxPiMapper piMapper;
- CameraSource * cameraSource;
+/*
+ * CameraSource example
+ * Can be used with the Raspberry Pi camera module or the Auvidea HDMI bridge.
+ * B101 HDMI to CSI-2 Bridge (15 pin FPC).
+ * Available at http://www.auvidea.eu/index.php/theme-styles/2014-12-30-22-32-06/b101
+ * Created by Krisjanis Rijnieks on 25/01/2016
+ * Last modified on 10/02/2016
+ */
+
+#pragma once
+
+#include "ofMain.h"
+#include "ofxPiMapper.h"
+#include "CameraSource.h"
+
+class ofApp : public ofBaseApp {
+ public:
+ void setup();
+ void update();
+ void draw();
+
+ void keyPressed(int key);
+ void keyReleased(int key);
+
+ void mousePressed(int x, int y, int button);
+ void mouseDragged(int x, int y, int button);
+ void mouseReleased(int x, int y, int button);
+
+ ofxPiMapper piMapper;
+ CameraSource * cameraSource;
};
\ No newline at end of file
diff --git a/example_fbo-sources/.gitignore b/example_fbo-sources/.gitignore
index e4d4b5d..ad71cfd 100644
--- a/example_fbo-sources/.gitignore
+++ b/example_fbo-sources/.gitignore
@@ -1,5 +1,5 @@
-obj
-*.xcworkspace
-*.xcuserdatad
-*~
-config.make
+obj
+*.xcworkspace
+*.xcuserdatad
+*~
+config.make
diff --git a/example_fbo-sources/Makefile b/example_fbo-sources/Makefile
index 8d8e4c0..c83af71 100644
--- a/example_fbo-sources/Makefile
+++ b/example_fbo-sources/Makefile
@@ -1,13 +1,13 @@
-# Attempt to load a config.make file.
-# If none is found, project defaults in config.project.make will be used.
-ifneq ($(wildcard config.make),)
- include config.make
-endif
-
-# make sure the the OF_ROOT location is defined
-ifndef OF_ROOT
- OF_ROOT=$(realpath ../../..)
-endif
-
-# call the project makefile!
-include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk
+# Attempt to load a config.make file.
+# If none is found, project defaults in config.project.make will be used.
+ifneq ($(wildcard config.make),)
+ include config.make
+endif
+
+# make sure the the OF_ROOT location is defined
+ifndef OF_ROOT
+ OF_ROOT=$(realpath ../../..)
+endif
+
+# call the project makefile!
+include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk
diff --git a/example_fbo-sources/README.md b/example_fbo-sources/README.md
index 454e3ad..9fc787e 100644
--- a/example_fbo-sources/README.md
+++ b/example_fbo-sources/README.md
@@ -1,28 +1,28 @@
-# FBO Sources Example
-
-This example shows how to use custom (FBO) source functionality with ofxPiMapper. Below you can see a list of custom sources and feel free to add your own via pull requests!
-
-- ScanlineSource
-- SlideShowSource
-
-To build your own source, one should start by extending the `FboSource` class. When the source is ready, it should be instantiated in the `ofApp` class and passed via `mapper.registerFboSource(...source)` function before the `mapper.setup()` call. This will make the source name to appear under **FBO Sources** category in the source selection mode.
-
-Look at the source code of the custom sources to understand how to build one, but essentially it is extending the `FboSource` class of `ofxPiMapper` and overriding the `setup()`, `update()` and `draw()` functions.
-
-In the `setup()` function you should set a name for your custom source.
-
-```
-name = "Name Your Source";
-```
-
-Then you should set the dimensions of your source by using the `allocate()` function.
-
-```
-allocate(500, 500);
-```
-
-In the `draw()` of your custom `FboSource` you should decide whether you want the previous frame to be cleared from the gfx buffer or not. If you want to draw a fresh frame, use the `ofClear()` function.
-
-```
-ofClear(0); // Clear with black
-```
+# FBO Sources Example
+
+This example shows how to use custom (FBO) source functionality with ofxPiMapper. Below you can see a list of custom sources and feel free to add your own via pull requests!
+
+- ScanlineSource
+- SlideShowSource
+
+To build your own source, one should start by extending the `FboSource` class. When the source is ready, it should be instantiated in the `ofApp` class and passed via `mapper.registerFboSource(...source)` function before the `mapper.setup()` call. This will make the source name to appear under **FBO Sources** category in the source selection mode.
+
+Look at the source code of the custom sources to understand how to build one, but essentially it is extending the `FboSource` class of `ofxPiMapper` and overriding the `setup()`, `update()` and `draw()` functions.
+
+In the `setup()` function you should set a name for your custom source.
+
+```
+name = "Name Your Source";
+```
+
+Then you should set the dimensions of your source by using the `allocate()` function.
+
+```
+allocate(500, 500);
+```
+
+In the `draw()` of your custom `FboSource` you should decide whether you want the previous frame to be cleared from the gfx buffer or not. If you want to draw a fresh frame, use the `ofClear()` function.
+
+```
+ofClear(0); // Clear with black
+```
diff --git a/example_fbo-sources/addons.make b/example_fbo-sources/addons.make
index 963941c..596425d 100644
--- a/example_fbo-sources/addons.make
+++ b/example_fbo-sources/addons.make
@@ -1,4 +1,4 @@
-ofxGui
-ofxPiMapper
-ofxXmlSettings
-ofxOMXPlayer
+ofxGui
+ofxPiMapper
+ofxXmlSettings
+ofxOMXPlayer
diff --git a/example_fbo-sources/addons.make.norpi b/example_fbo-sources/addons.make.norpi
index e72d2dd..69d8f94 100644
--- a/example_fbo-sources/addons.make.norpi
+++ b/example_fbo-sources/addons.make.norpi
@@ -1,3 +1,3 @@
-ofxGui
-ofxPiMapper
-ofxXmlSettings
+ofxGui
+ofxPiMapper
+ofxXmlSettings
diff --git a/example_fbo-sources/bin/data/magslideshow_settings.xml b/example_fbo-sources/bin/data/magslideshow_settings.xml
index 3e12c23..8a48c5d 100644
--- a/example_fbo-sources/bin/data/magslideshow_settings.xml
+++ b/example_fbo-sources/bin/data/magslideshow_settings.xml
@@ -1,15 +1,15 @@
-
- 800
- 600
- 2
-
- NORMAL
- 0
-
-
- Dissolve
- 3
-
-
- FitProportionally
-
+
+ 800
+ 600
+ 2
+
+ NORMAL
+ 0
+
+
+ Dissolve
+ 3
+
+
+ FitProportionally
+
diff --git a/example_fbo-sources/bin/data/ofxpimapper.xml b/example_fbo-sources/bin/data/ofxpimapper.xml
index bd79dc9..6b6fa37 100644
--- a/example_fbo-sources/bin/data/ofxpimapper.xml
+++ b/example_fbo-sources/bin/data/ofxpimapper.xml
@@ -1,126 +1,126 @@
-
-
-
-
- 337.195068359
- 362.146270752
-
-
- 337.195068359
- 595.853759766
-
-
- 648.804992676
- 595.853759766
-
-
- 648.804992676
- 362.146270752
-
-
-
-
- 0.000000000
- 0.000000000
-
-
- 1.000000000
- 0.000000000
-
-
- 1.000000000
- 1.000000000
-
-
- 0.000000000
- 1.000000000
-
-
-
- image
- image4.jpg
-
-
- 1
-
-
-
-
-
- 522.590332031
- 188.924621582
-
-
- 835.409606934
- 188.924621582
-
-
- 835.409606934
- 415.075378418
-
-
- 522.590332031
- 415.075378418
-
-
-
-
- 0.000000000
- 0.000000000
-
-
- 1.000000000
- 0.000000000
-
-
- 1.000000000
- 1.000000000
-
-
- 0.000000000
- 1.000000000
-
-
-
- image
- image1.jpg
-
-
- 1
-
-
-
-
-
- 325.000000000
- 196.999847412
-
-
- 479.922424316
- 421.000091553
-
-
- 170.077636719
- 421.000091553
-
-
-
-
- 0.500000000
- 0.000000000
-
-
- 1.000000000
- 1.000000000
-
-
- 0.000000000
- 1.000000000
-
-
-
- image
- image2.jpg
-
-
-
+
+
+
+
+ 337.195068359
+ 362.146270752
+
+
+ 337.195068359
+ 595.853759766
+
+
+ 648.804992676
+ 595.853759766
+
+
+ 648.804992676
+ 362.146270752
+
+
+
+
+ 0.000000000
+ 0.000000000
+
+
+ 1.000000000
+ 0.000000000
+
+
+ 1.000000000
+ 1.000000000
+
+
+ 0.000000000
+ 1.000000000
+
+
+
+ image
+ image4.jpg
+
+
+ 1
+
+
+
+
+
+ 522.590332031
+ 188.924621582
+
+
+ 835.409606934
+ 188.924621582
+
+
+ 835.409606934
+ 415.075378418
+
+
+ 522.590332031
+ 415.075378418
+
+
+
+
+ 0.000000000
+ 0.000000000
+
+
+ 1.000000000
+ 0.000000000
+
+
+ 1.000000000
+ 1.000000000
+
+
+ 0.000000000
+ 1.000000000
+
+
+
+ image
+ image1.jpg
+
+
+ 1
+
+
+
+
+
+ 325.000000000
+ 196.999847412
+
+
+ 479.922424316
+ 421.000091553
+
+
+ 170.077636719
+ 421.000091553
+
+
+
+
+ 0.500000000
+ 0.000000000
+
+
+ 1.000000000
+ 1.000000000
+
+
+ 0.000000000
+ 1.000000000
+
+
+
+ image
+ image2.jpg
+
+
+
diff --git a/example_fbo-sources/src/BrickSource/BrickSource.cpp b/example_fbo-sources/src/BrickSource/BrickSource.cpp
index df1e9c7..4a8931f 100644
--- a/example_fbo-sources/src/BrickSource/BrickSource.cpp
+++ b/example_fbo-sources/src/BrickSource/BrickSource.cpp
@@ -1,52 +1,52 @@
-#include "BrickSource.h"
-
-void BrickSource::setup(){
- // Give our source a decent name
- name = "Brick Source";
-
- // Allocate our FBO source, decide how big it should be
- allocate(500, 500);
- ofSetFrameRate(60);
-
- // Genereate rects to be rendered into the FBO
- int numX = 21;
- int numY = 21; // change this to add more or less rects
- int motar = 4;
- int brickLength = 20;
- int brickWidth = 20;
- int counter = 0;
- for(int k = 0; k < numY;k++){
- for(int i = 0; i < numX; i++){
-
- bricks.push_back(ofRectangle(i*(brickLength + motar),
- k*(brickWidth + motar),
- brickLength,
- brickWidth));
- brickColor.push_back(ofRandom(0, 220));
- }
- }
-}
-
-// Don't do any drawing here
-void BrickSource::update(){
- if (ofGetFrameNum()%30 == 0) {
- for(int i = 0; i < bricks.size(); i++){
- brickColor[i] = ofRandom(0, 220);
- }
- } // Move quads
-}
-
-// No need to take care of fbo.begin() and fbo.end() here.
-// All within draw() is being rendered into fbo;
-void BrickSource::draw(){
- // Fill FBO with our quads
- ofClear(0);
- //ofBackground(0);
- ofFill();
-
- for(int i = 0; i < bricks.size(); i++){
- //ofSetLineWidth(ofRandom(5));
- ofSetColor(brickColor[i]);
- ofDrawRectangle(bricks[i]);
- }
-}
+#include "BrickSource.h"
+
+void BrickSource::setup(){
+ // Give our source a decent name
+ name = "Brick Source";
+
+ // Allocate our FBO source, decide how big it should be
+ allocate(500, 500);
+ ofSetFrameRate(60);
+
+ // Genereate rects to be rendered into the FBO
+ int numX = 21;
+ int numY = 21; // change this to add more or less rects
+ int motar = 4;
+ int brickLength = 20;
+ int brickWidth = 20;
+ int counter = 0;
+ for(int k = 0; k < numY;k++){
+ for(int i = 0; i < numX; i++){
+
+ bricks.push_back(ofRectangle(i*(brickLength + motar),
+ k*(brickWidth + motar),
+ brickLength,
+ brickWidth));
+ brickColor.push_back(ofRandom(0, 220));
+ }
+ }
+}
+
+// Don't do any drawing here
+void BrickSource::update(){
+ if (ofGetFrameNum()%30 == 0) {
+ for(int i = 0; i < bricks.size(); i++){
+ brickColor[i] = ofRandom(0, 220);
+ }
+ } // Move quads
+}
+
+// No need to take care of fbo.begin() and fbo.end() here.
+// All within draw() is being rendered into fbo;
+void BrickSource::draw(){
+ // Fill FBO with our quads
+ ofClear(0);
+ //ofBackground(0);
+ ofFill();
+
+ for(int i = 0; i < bricks.size(); i++){
+ //ofSetLineWidth(ofRandom(5));
+ ofSetColor(brickColor[i]);
+ ofDrawRectangle(bricks[i]);
+ }
+}
diff --git a/example_fbo-sources/src/BrickSource/BrickSource.h b/example_fbo-sources/src/BrickSource/BrickSource.h
index eaa6ec8..dcbd6b7 100644
--- a/example_fbo-sources/src/BrickSource/BrickSource.h
+++ b/example_fbo-sources/src/BrickSource/BrickSource.h
@@ -1,15 +1,15 @@
-#pragma once
-
-#include "ofMain.h"
-#include "FboSource.h"
-
-class BrickSource : public ofx::piMapper::FboSource {
- public:
- void setup();
- void update();
- void draw();
-
- std::vector bricks;
- std::vector brickColor;
- int counter;
-};
+#pragma once
+
+#include "ofMain.h"
+#include "FboSource.h"
+
+class BrickSource : public ofx::piMapper::FboSource {
+ public:
+ void setup();
+ void update();
+ void draw();
+
+ std::vector bricks;
+ std::vector brickColor;
+ int counter;
+};
diff --git a/example_fbo-sources/src/CircleSource/CircleSource.cpp b/example_fbo-sources/src/CircleSource/CircleSource.cpp
index 138f535..1d3815a 100644
--- a/example_fbo-sources/src/CircleSource/CircleSource.cpp
+++ b/example_fbo-sources/src/CircleSource/CircleSource.cpp
@@ -1,43 +1,43 @@
-#include "CircleSource.h"
-
-bool col = true;
-
-void CircleSource::setup(){
- // Give our source a decent name
- name = "Circle Source";
-
- // Allocate our FBO source, decide how big it should be
- allocate(500, 500);
- ofSetCircleResolution(50);
-
- // Genereate rects to be rendered into the FBO
- int numCircles = 10; // change this to add more or less rects
- for(int i = 0; i < numCircles; i++){
- circlesRadius.push_back(ofRandom(fbo->getHeight()/2));
- circlesSpeeds.push_back((1.0f + ofRandom(2)));
- }
-}
-
-// Don't do any drawing here
-void CircleSource::update(){
- // Move rects
- for(int i = 0; i < circlesRadius.size(); i++){
- circlesRadius[i] += circlesSpeeds[i];
- if(circlesRadius[i] > fbo->getHeight()/2){
- circlesRadius[i] = fbo->getHeight()/2*(-1);
- }
- }
-}
-
-// No need to take care of fbo.begin() and fbo.end() here.
-// All within draw() is being rendered into fbo;
-void CircleSource::draw(){
- // Fill FBO with our rects
- ofClear(0);
- ofSetColor(255);
- ofSetLineWidth(ofRandom(3));
- ofNoFill();
- for(int i = 0; i < circlesRadius.size(); i++){
- ofDrawCircle(fbo->getHeight()/2,fbo->getHeight()/2,circlesRadius[i]);
- }
-}
+#include "CircleSource.h"
+
+bool col = true;
+
+void CircleSource::setup(){
+ // Give our source a decent name
+ name = "Circle Source";
+
+ // Allocate our FBO source, decide how big it should be
+ allocate(500, 500);
+ ofSetCircleResolution(50);
+
+ // Genereate rects to be rendered into the FBO
+ int numCircles = 10; // change this to add more or less rects
+ for(int i = 0; i < numCircles; i++){
+ circlesRadius.push_back(ofRandom(fbo->getHeight()/2));
+ circlesSpeeds.push_back((1.0f + ofRandom(2)));
+ }
+}
+
+// Don't do any drawing here
+void CircleSource::update(){
+ // Move rects
+ for(int i = 0; i < circlesRadius.size(); i++){
+ circlesRadius[i] += circlesSpeeds[i];
+ if(circlesRadius[i] > fbo->getHeight()/2){
+ circlesRadius[i] = fbo->getHeight()/2*(-1);
+ }
+ }
+}
+
+// No need to take care of fbo.begin() and fbo.end() here.
+// All within draw() is being rendered into fbo;
+void CircleSource::draw(){
+ // Fill FBO with our rects
+ ofClear(0);
+ ofSetColor(255);
+ ofSetLineWidth(ofRandom(3));
+ ofNoFill();
+ for(int i = 0; i < circlesRadius.size(); i++){
+ ofDrawCircle(fbo->getHeight()/2,fbo->getHeight()/2,circlesRadius[i]);
+ }
+}
diff --git a/example_fbo-sources/src/CircleSource/CircleSource.h b/example_fbo-sources/src/CircleSource/CircleSource.h
index 905b113..978e6e1 100644
--- a/example_fbo-sources/src/CircleSource/CircleSource.h
+++ b/example_fbo-sources/src/CircleSource/CircleSource.h
@@ -1,14 +1,14 @@
-#pragma once
-
-#include "ofMain.h"
-#include "FboSource.h"
-
-class CircleSource : public ofx::piMapper::FboSource {
- public:
- void setup();
- void update();
- void draw();
-
- std::vector circlesRadius;
- std::vector circlesSpeeds;
-};
+#pragma once
+
+#include "ofMain.h"
+#include "FboSource.h"
+
+class CircleSource : public ofx::piMapper::FboSource {
+ public:
+ void setup();
+ void update();
+ void draw();
+
+ std::vector circlesRadius;
+ std::vector circlesSpeeds;
+};
diff --git a/example_fbo-sources/src/QuadSource/QuadSource.cpp b/example_fbo-sources/src/QuadSource/QuadSource.cpp
index 9c060dc..e0c6efc 100644
--- a/example_fbo-sources/src/QuadSource/QuadSource.cpp
+++ b/example_fbo-sources/src/QuadSource/QuadSource.cpp
@@ -1,62 +1,62 @@
-#include "QuadSource.h"
-
-void QuadSource::setup(){
- // Give our source a decent name
- name = "Quad Source";
-
- // Allocate our FBO source, decide how big it should be
- allocate(500, 500);
-
- // Genereate rects to be rendered into the FBO
- int numQuads = 20; // change this to add more or less rects
- for(int i = 0; i < numQuads; i++){
- float qsize = ofRandom(fbo->getWidth());
- float fbosize = fbo->getWidth();
-
- quads.push_back(ofRectangle(fbosize/2 - qsize/2,
- fbosize/2 - qsize/2,
- qsize,
- qsize));
-
- quadSpeeds.push_back((1.0f + ofRandom(5)));
- }
-}
-
-// Don't do any drawing here
-void QuadSource::update(){
- // Move quads
- for(int i = 0; i < quads.size(); i++){
- quads[i].x -= quadSpeeds[i]/2;
- quads[i].y -= quadSpeeds[i]/2;
- quads[i].width += quadSpeeds[i];
- quads[i].height += quadSpeeds[i];
-
- if(quads[i].width > fbo->getHeight()){
- quads[i].x = fbo->getWidth()/2;
- quads[i].y = fbo->getWidth()/2;
- quads[i].width = 0.0f;
- quads[i].height = 0.0f;
- }
- }
-}
-
-// No need to take care of fbo.begin() and fbo.end() here.
-// All within draw() is being rendered into fbo;
-void QuadSource::draw(){
- // Fill FBO with our quads
- ofClear(0);
- //ofBackground(0);
- ofNoFill();
- ofSetColor(255);
-
- #if (OF_VERSION_MAJOR == 0 && OF_VERSION_MINOR >= 9) || OF_VERSION_MAJOR > 0
- for(int i = 0; i < quads.size(); i++){
- ofSetLineWidth(ofRandom(5));
- ofDrawRectangle(quads[i]);
- }
- #else
- for(int i = 0; i < quads.size(); i++){
- ofRect(quads[i]);
- }
- #endif
-}
+#include "QuadSource.h"
+
+void QuadSource::setup(){
+ // Give our source a decent name
+ name = "Quad Source";
+
+ // Allocate our FBO source, decide how big it should be
+ allocate(500, 500);
+
+ // Genereate rects to be rendered into the FBO
+ int numQuads = 20; // change this to add more or less rects
+ for(int i = 0; i < numQuads; i++){
+ float qsize = ofRandom(fbo->getWidth());
+ float fbosize = fbo->getWidth();
+
+ quads.push_back(ofRectangle(fbosize/2 - qsize/2,
+ fbosize/2 - qsize/2,
+ qsize,
+ qsize));
+
+ quadSpeeds.push_back((1.0f + ofRandom(5)));
+ }
+}
+
+// Don't do any drawing here
+void QuadSource::update(){
+ // Move quads
+ for(int i = 0; i < quads.size(); i++){
+ quads[i].x -= quadSpeeds[i]/2;
+ quads[i].y -= quadSpeeds[i]/2;
+ quads[i].width += quadSpeeds[i];
+ quads[i].height += quadSpeeds[i];
+
+ if(quads[i].width > fbo->getHeight()){
+ quads[i].x = fbo->getWidth()/2;
+ quads[i].y = fbo->getWidth()/2;
+ quads[i].width = 0.0f;
+ quads[i].height = 0.0f;
+ }
+ }
+}
+
+// No need to take care of fbo.begin() and fbo.end() here.
+// All within draw() is being rendered into fbo;
+void QuadSource::draw(){
+ // Fill FBO with our quads
+ ofClear(0);
+ //ofBackground(0);
+ ofNoFill();
+ ofSetColor(255);
+
+ #if (OF_VERSION_MAJOR == 0 && OF_VERSION_MINOR >= 9) || OF_VERSION_MAJOR > 0
+ for(int i = 0; i < quads.size(); i++){
+ ofSetLineWidth(ofRandom(5));
+ ofDrawRectangle(quads[i]);
+ }
+ #else
+ for(int i = 0; i < quads.size(); i++){
+ ofRect(quads[i]);
+ }
+ #endif
+}
diff --git a/example_fbo-sources/src/QuadSource/QuadSource.h b/example_fbo-sources/src/QuadSource/QuadSource.h
index bb3309e..3e33f27 100644
--- a/example_fbo-sources/src/QuadSource/QuadSource.h
+++ b/example_fbo-sources/src/QuadSource/QuadSource.h
@@ -1,14 +1,14 @@
-#pragma once
-
-#include "ofMain.h"
-#include "FboSource.h"
-
-class QuadSource : public ofx::piMapper::FboSource {
- public:
- void setup();
- void update();
- void draw();
-
- std::vector quads;
- std::vector quadSpeeds;
-};
+#pragma once
+
+#include "ofMain.h"
+#include "FboSource.h"
+
+class QuadSource : public ofx::piMapper::FboSource {
+ public:
+ void setup();
+ void update();
+ void draw();
+
+ std::vector quads;
+ std::vector quadSpeeds;
+};
diff --git a/example_fbo-sources/src/ScanLineSource/ScanlineSource.cpp b/example_fbo-sources/src/ScanLineSource/ScanlineSource.cpp
index edd68fb..1b57f22 100644
--- a/example_fbo-sources/src/ScanLineSource/ScanlineSource.cpp
+++ b/example_fbo-sources/src/ScanLineSource/ScanlineSource.cpp
@@ -1,48 +1,48 @@
-#include "ScanlineSource.h"
-
-void ScanlineSource::setup(){
- // Give our source a decent name
- name = "Scanline Source";
-
- // Allocate our FBO source, decide how big it should be
- allocate(500, 500);
-
- // Genereate rects to be rendered into the FBO
- int numRects = 20; // change this to add more or less rects
- for(int i = 0; i < numRects; i++){
- rects.push_back(ofRectangle(0,
- ofRandom(fbo->getHeight()),
- fbo->getWidth(),
- ofRandom(20)));
- rectSpeeds.push_back((1.0f + ofRandom(5)));
- }
-}
-
-// Don't do any drawing here
-void ScanlineSource::update(){
- // Move rects
- for(int i = 0; i < rects.size(); i++){
- rects[i].y += rectSpeeds[i];
- if(rects[i].y > fbo->getHeight()){
- rects[i].y = -rects[i].getHeight();
- }
- }
-}
-
-// No need to take care of fbo.begin() and fbo.end() here.
-// All within draw() is being rendered into fbo;
-void ScanlineSource::draw(){
- // Fill FBO with our rects
- ofClear(0);
- //ofBackground(0);
- ofSetColor(255);
- #if (OF_VERSION_MAJOR == 0 && OF_VERSION_MINOR >= 9) || OF_VERSION_MAJOR > 0
- for(int i = 0; i < rects.size(); i++){
- ofDrawRectangle(rects[i]);
- }
- #else
- for(int i = 0; i < rects.size(); i++){
- ofRect(rects[i]);
- }
- #endif
-}
+#include "ScanlineSource.h"
+
+void ScanlineSource::setup(){
+ // Give our source a decent name
+ name = "Scanline Source";
+
+ // Allocate our FBO source, decide how big it should be
+ allocate(500, 500);
+
+ // Genereate rects to be rendered into the FBO
+ int numRects = 20; // change this to add more or less rects
+ for(int i = 0; i < numRects; i++){
+ rects.push_back(ofRectangle(0,
+ ofRandom(fbo->getHeight()),
+ fbo->getWidth(),
+ ofRandom(20)));
+ rectSpeeds.push_back((1.0f + ofRandom(5)));
+ }
+}
+
+// Don't do any drawing here
+void ScanlineSource::update(){
+ // Move rects
+ for(int i = 0; i < rects.size(); i++){
+ rects[i].y += rectSpeeds[i];
+ if(rects[i].y > fbo->getHeight()){
+ rects[i].y = -rects[i].getHeight();
+ }
+ }
+}
+
+// No need to take care of fbo.begin() and fbo.end() here.
+// All within draw() is being rendered into fbo;
+void ScanlineSource::draw(){
+ // Fill FBO with our rects
+ ofClear(0);
+ //ofBackground(0);
+ ofSetColor(255);
+ #if (OF_VERSION_MAJOR == 0 && OF_VERSION_MINOR >= 9) || OF_VERSION_MAJOR > 0
+ for(int i = 0; i < rects.size(); i++){
+ ofDrawRectangle(rects[i]);
+ }
+ #else
+ for(int i = 0; i < rects.size(); i++){
+ ofRect(rects[i]);
+ }
+ #endif
+}
diff --git a/example_fbo-sources/src/ScanLineSource/ScanlineSource.h b/example_fbo-sources/src/ScanLineSource/ScanlineSource.h
index 255aead..fc267ba 100644
--- a/example_fbo-sources/src/ScanLineSource/ScanlineSource.h
+++ b/example_fbo-sources/src/ScanLineSource/ScanlineSource.h
@@ -1,14 +1,14 @@
-#pragma once
-
-#include "ofMain.h"
-#include "FboSource.h"
-
-class ScanlineSource : public ofx::piMapper::FboSource {
- public:
- void setup();
- void update();
- void draw();
-
- std::vector rects;
- std::vector rectSpeeds;
-};
+#pragma once
+
+#include "ofMain.h"
+#include "FboSource.h"
+
+class ScanlineSource : public ofx::piMapper::FboSource {
+ public:
+ void setup();
+ void update();
+ void draw();
+
+ std::vector rects;
+ std::vector rectSpeeds;
+};
diff --git a/example_fbo-sources/src/SlideShowSource/magSlide.cpp b/example_fbo-sources/src/SlideShowSource/magSlide.cpp
index adffed8..0a8639f 100644
--- a/example_fbo-sources/src/SlideShowSource/magSlide.cpp
+++ b/example_fbo-sources/src/SlideShowSource/magSlide.cpp
@@ -1,201 +1,201 @@
-//
-// magSlide.cpp
-// Copyright (c) 2017 Cristobal Mendoza
-// http://cuppetellimendoza.com
-//
-
-#include "magSlide.h"
-#include "magSlideTransition.h"
-
-#pragma mark magSlide
-
-int magSlide::idCount = 0;
-
-magSlide::magSlide(std::string type)
-{
- this->type = type;
- position = ofPoint(0, 0);
- id = magSlide::idCount;
- magSlide::idCount++;
-}
-
-void magSlide::update(uint64_t deltaTime)
-{
- transition->update(deltaTime);
- runningTime += deltaTime;
-
- switch (slideState){
-// case SlideState::BuildIn:
-// if (runningTime >= buildInDuration)
-// {
-// setState(Normal);
-// activeTransition = nullptr;
-// }
-// break;
-
- case SlideState::Normal:
- if (runningTime >= buildOutStartTime){
- setState(BuildOut);
- }
- break;
-
- case SlideState::BuildOut:
- if (runningTime >= endTime){
- setState(Complete);
- }
- break;
- default:
- break;
- }
-}
-
-void magSlide::setSize(float w, float h)
-{
- width = w;
- height = h;
-}
-
-void magSlide::setResizeOption(magSlide::ResizeOptions resizeOption)
-{
- this->resizeOption = resizeOption;
-}
-
-magSlide::ResizeOptions magSlide::getResizeOption() const
-{
- return resizeOption;
-}
-
-void magSlide::setDuration(uint64_t duration)
-{
- this->duration = duration;
-}
-
-void magSlide::setState(SlideState state)
-{
- // Don't do anything if the new state is the same
- // as the current one:
- if (slideState == state) return;
-
- slideState = state;
- ofEventArgs args;
- ofNotifyEvent(slideStateChangedEvent, args, this);
-
- if (slideState == Complete)
- {
- ofNotifyEvent(slideCompleteEvent, args, this);
- }
-}
-
-void magSlide::setTransitionDuration(uint64_t tDuration)
-{
- buildOutDuration = tDuration;
-}
-
-const std::string magSlide::getSlideStateName()
-{
- switch (slideState)
- {
-// case SlideState::BuildIn:
-// return "BuildIn";
- case SlideState::BuildOut:
- return "BuildOut";
- case Normal:
- return "Normal";
- case SlideState::Complete:
- return "Complete";
- case SlideState::Off:
- return "Off";
- }
-
- return "unknown";
-}
-
-void magSlide::start(uint64_t startTime)
-{
- this->startTime = startTime;
- runningTime = 0;
- endTime = duration + (buildOutDuration*2); // *2 because we take into account transition in and out
- buildOutStartTime = duration + buildOutDuration;
- slideState = magSlide::SlideState::Normal;
- position.set(0, 0);
- opacity = 255;
- isComplete = false;
-}
-
-void magSlide::draw()
-{
- ofSetColor(255, opacity);
- if(transition->isActive())
- {
- transition->draw();
- }
-}
-
-
-////////////////////////////////////////////////////////
-#pragma mark MAG_IMAGE_SLIDE
-////////////////////////////////////////////////////////
-
-magImageSlide::magImageSlide() : magSlide("magImageSlide") {}
-
-magImageSlide::~magImageSlide() {}
-
-void magImageSlide::setup(ofImage &image)
-{
- // Make a copy of the image:
- this->image = ofImage(image);
- image.setAnchorPercent(0.5, 0.5);
- width = image.getWidth();
- height = image.getHeight();
-}
-
-void magImageSlide::draw()
-{
- magSlide::draw();
- image.draw(position, width, height);
-}
-
-////////////////////////////////////////////////////////
-#pragma mark MAG_VIDEO_SLIDE
-////////////////////////////////////////////////////////
-
-magVideoSlide::magVideoSlide() : magSlide("magVideoSlide")
-{}
-
-magVideoSlide::~magVideoSlide()
-{
- videoPlayer.stop();
-}
-
-bool magVideoSlide::setup(ofFile &file, bool useVideoDuration)
-{
-
- bool success = videoPlayer.load(file.getAbsolutePath());
-
- if (success)
- {
- videoPlayer.setAnchorPercent(0.5, 0.5);
- if (useVideoDuration)
- {
- useVideoForDuration();
- }
- }
-
- return success;
-}
-
-void magVideoSlide::update()
-{
- videoPlayer.update();
-}
-
-void magVideoSlide::draw()
-{
- magSlide::draw();
- videoPlayer.draw(position.x, position.y, width, height);
-}
-
-void magVideoSlide::useVideoForDuration()
-{
- duration = uint64_t((videoPlayer.getDuration()*1000)) - buildOutDuration;
-}
+//
+// magSlide.cpp
+// Copyright (c) 2017 Cristobal Mendoza
+// http://cuppetellimendoza.com
+//
+
+#include "magSlide.h"
+#include "magSlideTransition.h"
+
+#pragma mark magSlide
+
+int magSlide::idCount = 0;
+
+magSlide::magSlide(std::string type)
+{
+ this->type = type;
+ position = ofPoint(0, 0);
+ id = magSlide::idCount;
+ magSlide::idCount++;
+}
+
+void magSlide::update(uint64_t deltaTime)
+{
+ transition->update(deltaTime);
+ runningTime += deltaTime;
+
+ switch (slideState){
+// case SlideState::BuildIn:
+// if (runningTime >= buildInDuration)
+// {
+// setState(Normal);
+// activeTransition = nullptr;
+// }
+// break;
+
+ case SlideState::Normal:
+ if (runningTime >= buildOutStartTime){
+ setState(BuildOut);
+ }
+ break;
+
+ case SlideState::BuildOut:
+ if (runningTime >= endTime){
+ setState(Complete);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void magSlide::setSize(float w, float h)
+{
+ width = w;
+ height = h;
+}
+
+void magSlide::setResizeOption(magSlide::ResizeOptions resizeOption)
+{
+ this->resizeOption = resizeOption;
+}
+
+magSlide::ResizeOptions magSlide::getResizeOption() const
+{
+ return resizeOption;
+}
+
+void magSlide::setDuration(uint64_t duration)
+{
+ this->duration = duration;
+}
+
+void magSlide::setState(SlideState state)
+{
+ // Don't do anything if the new state is the same
+ // as the current one:
+ if (slideState == state) return;
+
+ slideState = state;
+ ofEventArgs args;
+ ofNotifyEvent(slideStateChangedEvent, args, this);
+
+ if (slideState == Complete)
+ {
+ ofNotifyEvent(slideCompleteEvent, args, this);
+ }
+}
+
+void magSlide::setTransitionDuration(uint64_t tDuration)
+{
+ buildOutDuration = tDuration;
+}
+
+const std::string magSlide::getSlideStateName()
+{
+ switch (slideState)
+ {
+// case SlideState::BuildIn:
+// return "BuildIn";
+ case SlideState::BuildOut:
+ return "BuildOut";
+ case Normal:
+ return "Normal";
+ case SlideState::Complete:
+ return "Complete";
+ case SlideState::Off:
+ return "Off";
+ }
+
+ return "unknown";
+}
+
+void magSlide::start(uint64_t startTime)
+{
+ this->startTime = startTime;
+ runningTime = 0;
+ endTime = duration + (buildOutDuration*2); // *2 because we take into account transition in and out
+ buildOutStartTime = duration + buildOutDuration;
+ slideState = magSlide::SlideState::Normal;
+ position.set(0, 0);
+ opacity = 255;
+ isComplete = false;
+}
+
+void magSlide::draw()
+{
+ ofSetColor(255, opacity);
+ if(transition->isActive())
+ {
+ transition->draw();
+ }
+}
+
+
+////////////////////////////////////////////////////////
+#pragma mark MAG_IMAGE_SLIDE
+////////////////////////////////////////////////////////
+
+magImageSlide::magImageSlide() : magSlide("magImageSlide") {}
+
+magImageSlide::~magImageSlide() {}
+
+void magImageSlide::setup(ofImage &image)
+{
+ // Make a copy of the image:
+ this->image = ofImage(image);
+ image.setAnchorPercent(0.5, 0.5);
+ width = image.getWidth();
+ height = image.getHeight();
+}
+
+void magImageSlide::draw()
+{
+ magSlide::draw();
+ image.draw(position, width, height);
+}
+
+////////////////////////////////////////////////////////
+#pragma mark MAG_VIDEO_SLIDE
+////////////////////////////////////////////////////////
+
+magVideoSlide::magVideoSlide() : magSlide("magVideoSlide")
+{}
+
+magVideoSlide::~magVideoSlide()
+{
+ videoPlayer.stop();
+}
+
+bool magVideoSlide::setup(ofFile &file, bool useVideoDuration)
+{
+
+ bool success = videoPlayer.load(file.getAbsolutePath());
+
+ if (success)
+ {
+ videoPlayer.setAnchorPercent(0.5, 0.5);
+ if (useVideoDuration)
+ {
+ useVideoForDuration();
+ }
+ }
+
+ return success;
+}
+
+void magVideoSlide::update()
+{
+ videoPlayer.update();
+}
+
+void magVideoSlide::draw()
+{
+ magSlide::draw();
+ videoPlayer.draw(position.x, position.y, width, height);
+}
+
+void magVideoSlide::useVideoForDuration()
+{
+ duration = uint64_t((videoPlayer.getDuration()*1000)) - buildOutDuration;
+}
diff --git a/example_fbo-sources/src/SlideShowSource/magSlide.h b/example_fbo-sources/src/SlideShowSource/magSlide.h
index f0aa175..e876501 100644
--- a/example_fbo-sources/src/SlideShowSource/magSlide.h
+++ b/example_fbo-sources/src/SlideShowSource/magSlide.h
@@ -1,263 +1,263 @@
-//
-// Created by Cristobal Mendoza on 11/9/17.
-//
-
-#ifndef MAGSLIDE_H
-#define MAGSLIDE_H
-
-#include "ofMain.h"
-
-class magSlideTransition;
-
-class magSlide
-{
-public:
- magSlide(std::string type);
-// ~magSlide();
- virtual void update(uint64_t deltaTime);
- virtual void draw();
-
- /**
- * Sets the slide up for playback. This method must be
- * called before displaying the slide.
- * @param startTime
- */
- void start(uint64_t startTime);
-
- enum ResizeOptions : short
- {
- /**
- * No resizing applied, displays the slide in its native pixel dimensions.
- * This is the default behavior.
- */
- NoResize = 0,
- /**
- * Explicitly set a slide to display in its native dimension.
- * None and NoResize result in the same output, but if you specify
- * a default resizing option in your slideshow and you want a particular
- * slide not to resize, you must specify this option. Otherwise the
- * slide show option will apply.
- */
- Native,
-
- /**
- * Sets width and height to match the source's.
- * This will distort the slide if the aspect ratios
- * don't match.
- */
- Fit,
-
- /**
- * Resizes the largest dimension to the source's max,
- * the other dimension is resized proportionally.
- */
- FitProportionally,
-
- /**
- * Resizes the shortest dimensions to the source's max,
- */
- FillProportionally,
- };
-
- enum SlideState : short
- {
- Off = 0,
-// BuildIn,
- Normal,
- BuildOut,
- Complete
- };
-
- const std::string &getType()
- { return type; }
-
- float getWidth()
- { return width; }
-
- float getHeight()
- { return height; }
-
- float getOpacity() const
- {
- return opacity;
- }
-
- void setOpacity(float opacity)
- {
- magSlide::opacity = opacity;
- }
-
- /**
- * Change the display size of a slide. This will implicitly
- * set resizeOptions to ResizeOption.NoResize.
- * This method does not resize the pixel source of the slide.
- * @param w The new width
- * @param h The new height
- */
- virtual void setSize(float w, float h);
-
- uint64_t getDuration()
- {
- return duration;
- }
-
- /**
- * Sets the display time of the slide, excluding
- * builds (in or out)
- * @param duration in milliseconds.
- */
- void setDuration(uint64_t duration);
-
- /**
- * Sets the duration of the buildIn and buildOut
- * transitions. Transition times are added to the
- * duration of the slide.
- * @param tDuration in milliseconds.
- */
- void setTransitionDuration(uint64_t tDuration);
-
- ResizeOptions getResizeOption() const;
- void setResizeOption(ResizeOptions resizeOption);
-
- SlideState getSlideState() const
- {
- return slideState;
- }
-
- bool isSlideComplete()
- { return isComplete; }
-
- int getId()
- { return id; }
-
- const std::string getSlideStateName();
-
- //////////////////////////////
- /// Events
- //////////////////////////////
- ofEvent slideCompleteEvent;
- ofEvent slideStateChangedEvent;
-
- friend class magSlideShowSource;
-
-protected:
- int id;
- std::string type;
- float width;
- float height;
- ofPoint position;
-public:
- const ofPoint &getPosition() const
- {
- return position;
- }
-
- void setPosition(const ofPoint &position)
- {
- magSlide::position = position;
- }
-
- void setPosition(float x, float y)
- {
- position.set(x, y);
- }
-
-
-protected:
- float opacity = 255;
- ResizeOptions resizeOption = NoResize;
- SlideState slideState = Off;
- bool isComplete = false;
-
-// std::shared_ptr buildIn = nullptr;
-// std::shared_ptr buildOut = nullptr;
- std::shared_ptr transition = nullptr;
-public:
- const shared_ptr &getTransition() const
- {
- return transition;
- }
-
-protected:
- /**
- * The duration of the slide in millis, not counting builds
- */
- uint64_t duration;
-
- /**
- * The start time of the slide in milliseconds, in "local time".
- * In practice, this means that the start time is always 0.
- */
- uint64_t startTime;
-
- /**
- * The end time of the slide in milliseconds, in "local time".
- * The endTime is startTime + buildInDuration + duration + buildOutDuration.
- */
- uint64_t endTime;
-
- /**
- * The duration of the build in transition or effect, in milliseconds.
- */
-// uint64_t buildInDuration;
-
- /**
- * The duration of the build out transition or effect, in milliseconds.
- */
- uint64_t buildOutDuration;
-
- /**
- * The "local time" start of the build out transition. This time should also
- * signal the enqueuing of the next slide, if applicable.
- */
- uint64_t buildOutStartTime;
-
- /**
- * The amount of time the slide has been displayed, in milliseconds.
- * This constitutes the "local time" of the slide.
- */
- uint64_t runningTime;
-
- void setState(SlideState state);
-
- static int idCount;
-};
-
-class magImageSlide : public magSlide
-{
-public:
- magImageSlide();
- ~ magImageSlide();
- /**
- * Sets up an image slide.
- * @param image is copied into the member magImageSlide::image and is
- * not modified in any way.
- */
- void setup(ofImage &image);
-
- void draw();
-
-protected:
- ofImage image;
-};
-
-class magVideoSlide : public magSlide
-{
-public:
- magVideoSlide();
- ~magVideoSlide();
- bool setup(ofFile &file, bool useVideoDuration = false);
- void update();
- void draw();
-
- /**
- * Sets the slide duration to the duration of the video.
- * magSlide::duration will be changed by this call, so if you later
- * change your mind you'll have to use magSlide::setDuration.
- */
- void useVideoForDuration();
-protected:
- ofVideoPlayer videoPlayer;
-};
-
-#endif
+//
+// Created by Cristobal Mendoza on 11/9/17.
+//
+
+#ifndef MAGSLIDE_H
+#define MAGSLIDE_H
+
+#include "ofMain.h"
+
+class magSlideTransition;
+
+class magSlide
+{
+public:
+ magSlide(std::string type);
+// ~magSlide();
+ virtual void update(uint64_t deltaTime);
+ virtual void draw();
+
+ /**
+ * Sets the slide up for playback. This method must be
+ * called before displaying the slide.
+ * @param startTime
+ */
+ void start(uint64_t startTime);
+
+ enum ResizeOptions : short
+ {
+ /**
+ * No resizing applied, displays the slide in its native pixel dimensions.
+ * This is the default behavior.
+ */
+ NoResize = 0,
+ /**
+ * Explicitly set a slide to display in its native dimension.
+ * None and NoResize result in the same output, but if you specify
+ * a default resizing option in your slideshow and you want a particular
+ * slide not to resize, you must specify this option. Otherwise the
+ * slide show option will apply.
+ */
+ Native,
+
+ /**
+ * Sets width and height to match the source's.
+ * This will distort the slide if the aspect ratios
+ * don't match.
+ */
+ Fit,
+
+ /**
+ * Resizes the largest dimension to the source's max,
+ * the other dimension is resized proportionally.
+ */
+ FitProportionally,
+
+ /**
+ * Resizes the shortest dimensions to the source's max,
+ */
+ FillProportionally,
+ };
+
+ enum SlideState : short
+ {
+ Off = 0,
+// BuildIn,
+ Normal,
+ BuildOut,
+ Complete
+ };
+
+ const std::string &getType()
+ { return type; }
+
+ float getWidth()
+ { return width; }
+
+ float getHeight()
+ { return height; }
+
+ float getOpacity() const
+ {
+ return opacity;
+ }
+
+ void setOpacity(float opacity)
+ {
+ magSlide::opacity = opacity;
+ }
+
+ /**
+ * Change the display size of a slide. This will implicitly
+ * set resizeOptions to ResizeOption.NoResize.
+ * This method does not resize the pixel source of the slide.
+ * @param w The new width
+ * @param h The new height
+ */
+ virtual void setSize(float w, float h);
+
+ uint64_t getDuration()
+ {
+ return duration;
+ }
+
+ /**
+ * Sets the display time of the slide, excluding
+ * builds (in or out)
+ * @param duration in milliseconds.
+ */
+ void setDuration(uint64_t duration);
+
+ /**
+ * Sets the duration of the buildIn and buildOut
+ * transitions. Transition times are added to the
+ * duration of the slide.
+ * @param tDuration in milliseconds.
+ */
+ void setTransitionDuration(uint64_t tDuration);
+
+ ResizeOptions getResizeOption() const;
+ void setResizeOption(ResizeOptions resizeOption);
+
+ SlideState getSlideState() const
+ {
+ return slideState;
+ }
+
+ bool isSlideComplete()
+ { return isComplete; }
+
+ int getId()
+ { return id; }
+
+ const std::string getSlideStateName();
+
+ //////////////////////////////
+ /// Events
+ //////////////////////////////
+ ofEvent slideCompleteEvent;
+ ofEvent slideStateChangedEvent;
+
+ friend class magSlideShowSource;
+
+protected:
+ int id;
+ std::string type;
+ float width;
+ float height;
+ ofPoint position;
+public:
+ const ofPoint &getPosition() const
+ {
+ return position;
+ }
+
+ void setPosition(const ofPoint &position)
+ {
+ magSlide::position = position;
+ }
+
+ void setPosition(float x, float y)
+ {
+ position.set(x, y);
+ }
+
+
+protected:
+ float opacity = 255;
+ ResizeOptions resizeOption = NoResize;
+ SlideState slideState = Off;
+ bool isComplete = false;
+
+// std::shared_ptr buildIn = nullptr;
+// std::shared_ptr buildOut = nullptr;
+ std::shared_ptr transition = nullptr;
+public:
+ const shared_ptr &getTransition() const
+ {
+ return transition;
+ }
+
+protected:
+ /**
+ * The duration of the slide in millis, not counting builds
+ */
+ uint64_t duration;
+
+ /**
+ * The start time of the slide in milliseconds, in "local time".
+ * In practice, this means that the start time is always 0.
+ */
+ uint64_t startTime;
+
+ /**
+ * The end time of the slide in milliseconds, in "local time".
+ * The endTime is startTime + buildInDuration + duration + buildOutDuration.
+ */
+ uint64_t endTime;
+
+ /**
+ * The duration of the build in transition or effect, in milliseconds.
+ */
+// uint64_t buildInDuration;
+
+ /**
+ * The duration of the build out transition or effect, in milliseconds.
+ */
+ uint64_t buildOutDuration;
+
+ /**
+ * The "local time" start of the build out transition. This time should also
+ * signal the enqueuing of the next slide, if applicable.
+ */
+ uint64_t buildOutStartTime;
+
+ /**
+ * The amount of time the slide has been displayed, in milliseconds.
+ * This constitutes the "local time" of the slide.
+ */
+ uint64_t runningTime;
+
+ void setState(SlideState state);
+
+ static int idCount;
+};
+
+class magImageSlide : public magSlide
+{
+public:
+ magImageSlide();
+ ~ magImageSlide();
+ /**
+ * Sets up an image slide.
+ * @param image is copied into the member magImageSlide::image and is
+ * not modified in any way.
+ */
+ void setup(ofImage &image);
+
+ void draw();
+
+protected:
+ ofImage image;
+};
+
+class magVideoSlide : public magSlide
+{
+public:
+ magVideoSlide();
+ ~magVideoSlide();
+ bool setup(ofFile &file, bool useVideoDuration = false);
+ void update();
+ void draw();
+
+ /**
+ * Sets the slide duration to the duration of the video.
+ * magSlide::duration will be changed by this call, so if you later
+ * change your mind you'll have to use magSlide::setDuration.
+ */
+ void useVideoForDuration();
+protected:
+ ofVideoPlayer videoPlayer;
+};
+
+#endif
diff --git a/example_fbo-sources/src/SlideShowSource/magSlideShowSource.cpp b/example_fbo-sources/src/SlideShowSource/magSlideShowSource.cpp
index a26b003..64ec990 100644
--- a/example_fbo-sources/src/SlideShowSource/magSlideShowSource.cpp
+++ b/example_fbo-sources/src/SlideShowSource/magSlideShowSource.cpp
@@ -1,529 +1,529 @@
-//
-// magSlideShowSource.cpp
-// Copyright (c) 2017 Cristobal Mendoza
-// http://cuppetellimendoza.com
-//
-
-
-#include "magSlideShowSource.h"
-#include "magSlideTransition.h"
-#include "SettingsLoader.h"
-#include "magSlideTransitionFactory.h"
-
-const std::string magSlideShowSource::SettingsFileName = "magslideshow_settings.xml";
-
-magSlideShowSource::magSlideShowSource() {
- name = "Slide Show Source";
- currentSlideIndex = 0;
- isPlaying = false;
- directoryWatcher = 0;
- doInit = false;
- if (!loadFromXml(SettingsFileName))
- {
- ofLogError("magSlideShowSource") << "Could not find slide show settings file " << SettingsFileName;
- Settings sets;
- initialize(sets);
- }
-}
-
-magSlideShowSource::~magSlideShowSource(){
- if(directoryWatcher != 0){
- delete directoryWatcher;
- }
-}
-
-bool magSlideShowSource::initialize(magSlideShowSource::Settings settings) {
- this->settings = settings;
- bool success = true;
-
- if (settings.width <= 0 || settings.height <= 0)
- {
- ofLogError("magSlideShowSource::initialize") << "Invalid value for width or height. Width and height "
- "must be assigned in your Settings struct!";
- return false;
- }
-
- // Allocate the FBO:
- allocate(settings.width, settings.height);
-
- // If there is a path in slidesFolderPath, attempt
- // to load the folder and any files in it:
- if (!settings.slidesFolderPath.empty())
- {
-// ofDirectory dir = ofDirectory(settings.slidesFolderPath);
- success = createFromFolderContents(settings.slidesFolderPath);
-
- if (!success)
- {
- ofLogError("magSlideShowSource::initialize") << "Failed to create slide show from folder "
- << settings.slidesFolderPath;
- return success;
- }
- {
- if (directoryWatcher == 0)
- {
-
- using namespace ofx::piMapper;
- directoryWatcher = new DirectoryWatcher(settings.slidesFolderPath,
- SourceTypeHelper::GetSourceTypeHelperEnum(
- SOURCE_TYPE_NAME_IMAGE));
- ofAddListener(directoryWatcher->directoryFileAddedEvent, this, &magSlideShowSource::fileAddedListener);
- ofAddListener(directoryWatcher->directoryFileRemovedEvent, this,
- &magSlideShowSource::fileRemovedListener);
- directoryWatcher->beginWatch();
- }
- }
-
- }
- else if (!settings.slideshowFilePath.empty())
- {
- success = false;
- }
-
- return success;
-}
-
-void magSlideShowSource::setup() {
- ofx::piMapper::FboSource::setup();
-}
-
-void magSlideShowSource::update() {
-
- // Perform re-initialization if the DirectoryWatcher
- // detects file changes:
- if (doInit)
- {
- initialize(settings);
- doInit = false;
- }
-
- if (!isPlaying) return;
-
- auto nowTime = ofGetElapsedTimeMillis();
- deltaTime = nowTime-lastTime;
- runningTime += deltaTime;
- lastTime = nowTime;
-
- for (auto &slide : activeSlides)
- {
- slide->update(deltaTime);
- }
-
- // Queue the next slide if it is time
- if (doPlayNextSlide)
- {
- playNextSlide();
- if (activeSlides.size() > 1)
- {
- activeSlides[1]->transition->start(activeSlides[0]);
- }
- doPlayNextSlide = false;
- }
-
- // Erase any complete slides:
- auto iter = activeSlides.begin();
- for (; iter < activeSlides.end(); iter++)
- {
- if ((*iter)->isSlideComplete())
- {
-// ofLogVerbose() << "Removing from active slides id: " << (*iter)->getId();
- activeSlides.erase(iter);
- --iter;
- }
- }
-
- if (activeSlides.size() == 0 && isPlaying)
- {
- ofEventArgs args;
- isPlaying = false;
- ofNotifyEvent(slideshowCompleteEvent, args, this);
- }
-}
-
-void magSlideShowSource::draw() {
- ofBackground(0, 0);
- ofPushMatrix();
- ofPushStyle();
- ofTranslate(getWidth()/2.0f, getHeight()/2.0f);
- //ofEnableAlphaBlending();
- ofSetRectMode(OF_RECTMODE_CENTER);
- ofFill();
- ofSetColor(255, 255);
- for (auto &slide : activeSlides)
- {
- slide->draw();
- }
- ofPopStyle();
- ofPopMatrix();
- //ofDisableAlphaBlending();
-}
-
-bool magSlideShowSource::createFromFolderContents(std::string path) {
- ofDirectory dir = ofDirectory(path);
- slides.clear();
-
- if (!dir.isDirectory())
- {
- ofLogError("magSlideShowSource::createFromFolderContents") << "Folder path " << dir.getAbsolutePath()
- << " is not a directory";
- return false;
- }
-
- ofDirectory sortedDir = dir.getSorted();
- std::vector files = sortedDir.getFiles();
-
- if (files.size() < 1){
- ofLogError("magSlideShowSource::createFromFolderContents") << "Folder " << dir.getAbsolutePath() << " is empty";
- return false;
- }
-
- ofImage tempImage;
- for(ofFile &file : files){
- if (tempImage.load(file.getFileName())){
-
- // make a new image slide
- auto slide = std::make_shared();
- slide->setup(tempImage);
- slide->setDuration(static_cast(settings.slideDuration*1000));
- slide->setTransitionDuration(static_cast(settings.transitionDuration*1000));
-// if (settings.transitionName == "")
- addSlide(slide);
- }else{
- auto ext = ofToLower(file.getExtension());
-
- static std::vector movieExtensions = {
- "mov", "qt", // Mac
- "mp4", "m4p", "m4v", // MPEG
- "mpg", "mp2", "mpeg", "mpe", "mpv", "m2v", // MPEG
- "3gp", // Phones
- "avi", "wmv", "asf", // Windows
- "webm", "mkv", "flv", "vob", // Other containers
- "ogv", "ogg",
- "drc", "mxf"
- };
-
- // Check if the extension matches known movie formats:
- if (ofContains(movieExtensions, ext))
- {
- // Make a new video slide
- auto slide = std::make_shared();
- if (slide->setup(file))
- {
- slide->setDuration(settings.slideDuration*1000.0);
- slide->setTransitionDuration(settings.transitionDuration*1000.0);
- addSlide(slide);
- }
- else
- {
- ofLogError("magSlideShowSource") << "Failed loading video: " << file.getAbsolutePath();
- }
- }
-
- }
- }
-
- if (slides.size() > 0)
- {
- return true;
- }
- else
- {
- return false;
- }
-}
-
-bool magSlideShowSource::loadFromXml(std::string path) {
- auto xml = ofxXmlSettings();
- Settings settings;
-
- if (!xml.load(path))
- {
- ofLogError("magSlideShowSource") << "Could not load settings file " << path;
- return false;
- }
-
-// xml.pushTag("surfaces");
- if (!xml.pushTag("magSlideShow"))
- {
- ofLogError("magSlideShowSource") << "Slide show settings not found in " << path;
- return false;
- }
-
- settings.width = xml.getValue("Width", settings.width);
- settings.height = xml.getValue("Height", settings.height);
-
- // Default slide duration:
- settings.slideDuration = xml.getValue("SlideDuration", settings.slideDuration);
-
- // Default loop:
- if (xml.pushTag("Loop"))
- {
- auto type = xml.getValue("Type", "");
- if (type == "NONE")
- {
- settings.loopType = LoopType::NONE;
- }
- else if (type == "NORMAL")
- {
- settings.loopType = LoopType::NORMAL;
- }
- else if (type == "PING-PONG")
- {
- settings.loopType = LoopType::PING_PONG;
- }
-
- settings.numLoops = xml.getValue("Count", settings.numLoops);
- xml.popTag();
- }
-
- if (xml.pushTag("Transition"))
- {
- settings.transitionName = xml.getValue("Type", settings.transitionName);
- settings.transitionDuration = xml.getValue("Duration", settings.transitionDuration);
- xml.popTag();
- }
-
- // Default resize options:
- auto ropts = xml.getValue("ResizeOption", "");
- if (ropts == "NoResize")
- {
- settings.resizeOption = magSlide::NoResize;
- }
- else if (ropts == "Native")
- {
- settings.resizeOption = magSlide::Native;
- }
- else if (ropts == "Fit")
- {
- settings.resizeOption = magSlide::Fit;
- }
- else if (ropts == "FitProportionally")
- {
- settings.resizeOption = magSlide::FitProportionally;
- }
- else if (ropts == "FillProportionally")
- {
- settings.resizeOption = magSlide::FillProportionally;
- }
-
- initialize(settings);
- return true;
-}
-
-void magSlideShowSource::addSlide(std::shared_ptr slide) {
-// ofLogVerbose("addSlide") << slide->getId();
- slides.insert(slides.begin(), slide);
- auto rOption = slide->getResizeOption();
-
- // If the slide does not have a resize option assign
- // the slide show's option
- if (rOption == magSlide::ResizeOptions::NoResize)
- {
- rOption = settings.resizeOption;
- }
-
- // Resize the slide according to the resize option:
- switch (rOption){
- float sw, sh, ratio;
-
- case magSlide::ResizeOptions::FitProportionally:
- sw = slide->getWidth();
- sh = slide->getHeight();
-
- if (sw > sh)
- {
- ratio = (float) getWidth()/sw;
- }
- else
- {
- ratio = (float) getHeight()/sh;
- }
-
- slide->setSize(sw*ratio, sh*ratio);
- break;
-
- case magSlide::ResizeOptions::FillProportionally:
- sw = slide->getWidth();
- sh = slide->getHeight();
-
- if (sw > sh)
- {
- ratio = (float) getHeight()/sh;
- }
- else
- {
- ratio = (float) getWidth()/sw;
- }
-
- slide->setSize(sw*ratio, sh*ratio);
- break;
-
- case magSlide::Fit:
- slide->setSize(getWidth(), getHeight());
- break;
-
- default:
- break;
- }
-
- // Add transitions:
-
- static ofParameterGroup bogusParamGroup; // This is temporary so that things compile
-
- auto tf = magSlideTransitionFactory::instance();
-// slide->buildIn = tf->createTransition(settings.transitionName,
-// slide,
-// bogusParamGroup,
-// slide->buildInDuration);
- slide->transition = tf->createTransition(settings.transitionName,
- slide,
- bogusParamGroup,
- slide->buildOutDuration);
-
- //// void method(const void * sender, ArgumentsType &args)
- ofAddListener(slide->slideStateChangedEvent, this, &magSlideShowSource::slideStateChanged);
- ofAddListener(slide->slideCompleteEvent, this, &magSlideShowSource::slideComplete);
-
-}
-
-void magSlideShowSource::play() {
- if (!isPlaying && slides.size()){
- runningTime = 0;
- lastTime = ofGetElapsedTimeMillis();
- isPlaying = true;
- auto currentSlide = slides[currentSlideIndex];
- enqueueSlide(currentSlide, ofGetElapsedTimeMillis());
- }
-}
-
-void magSlideShowSource::pause() {
- isPlaying = false;
-}
-
-void magSlideShowSource::playNextSlide() {
- //TODO
- // I should check here to see if there are less than two slides.
- // If so, we should probably return
-
- currentSlideIndex += direction;
- ofEventArgs args;
-
- // This makes sure that we are doing a signed integer comparison,
- // otherwise things get weird
- int num = slides.size();
- switch (settings.loopType)
- {
- case LoopType::NONE:
- if (currentSlideIndex >= slides.size() || currentSlideIndex < 0)
- {
- // If we are not looping and we are out of bounds, return
- // without enqueueing a slide. This will cause the slide show
- // to end once the last slide builds out.
- return;
- }
- break;
- case LoopType::NORMAL:
- if (currentSlideIndex >= num)
- {
- loopCount++;
- if (loopCount == settings.numLoops)
- {
- // Return without enqueueing a new slide if we have
- // reached the max number of loops.
- return;
- }
- currentSlideIndex = 0;
- ofNotifyEvent(slideshowWillLoopEvent, args, this);
- }
- else if (currentSlideIndex < 0)
- {
- loopCount++;
- if (loopCount == settings.numLoops)
- {
- // Return without enqueueing a new slide if we have
- // reached the max number of loops.
- return;
- }
- currentSlideIndex = slides.size()-1;
- ofNotifyEvent(slideshowWillLoopEvent, args, this);
- }
- break;
- case LoopType::PING_PONG:
-
- int num = slides.size();
- if (currentSlideIndex >= num)
- {
- loopCount++;
- if (loopCount == settings.numLoops)
- {
- // Return without enqueueing a new slide if we have
- // reached the max number of loops.
- return;
- }
-
- direction = -1;
- currentSlideIndex = slides.size()-2;
- ofNotifyEvent(slideshowWillLoopEvent, args, this);
- }
- else if (currentSlideIndex < 0)
- {
- loopCount++;
- if (loopCount == settings.numLoops)
- {
- // Return without enqueueing a new slide if we have
- // reached the max number of loops.
- return;
- }
-
- direction = 1;
- currentSlideIndex = 1;
- ofNotifyEvent(slideshowWillLoopEvent, args, this);
- }
- break;
- }
-
- enqueueSlide(slides[currentSlideIndex], ofGetElapsedTimeMillis());
-}
-
-void magSlideShowSource::playPrevSlide() {
- currentSlideIndex -= (direction*2);
- playNextSlide();
-}
-
-void magSlideShowSource::playSlide(int slideIndex) {
- currentSlideIndex = slideIndex-direction;
- playNextSlide();
-}
-
-void magSlideShowSource::enqueueSlide(std::shared_ptr slide, uint64_t startTime) {
-// ofLogVerbose() << "Enqueuing slide " << currentSlideIndex << " slide id: " << slide->getId();
- slide->start(startTime);
- activeSlides.insert(activeSlides.begin(), slide);
-}
-
-void magSlideShowSource::slideStateChanged(const void *sender, ofEventArgs &args) {
- magSlide *slide = (magSlide *) sender;
-
-// ofLogVerbose("slideStateChanged") << "Slide id: " << slide->getId() << " Slide state: "
-// << slide->getSlideStateName();
- if (slide->getSlideState() == magSlide::SlideState::BuildOut)
- {
- // Flag that we need to load the next slide:
- doPlayNextSlide = true;
- }
-
-}
-
-void magSlideShowSource::slideComplete(const void *sender, ofEventArgs &args) {
- magSlide *slide = (magSlide *) sender;
-// ofLogVerbose() << "Slide Complete. id: " << slide->getId();
- slide->isComplete = true;
-}
-
-void magSlideShowSource::fileAddedListener(const void *sender) {
- doInit = true;
-}
-
-void magSlideShowSource::fileRemovedListener(const void *sender) {
- doInit = true;
-}
+//
+// magSlideShowSource.cpp
+// Copyright (c) 2017 Cristobal Mendoza
+// http://cuppetellimendoza.com
+//
+
+
+#include "magSlideShowSource.h"
+#include "magSlideTransition.h"
+#include "SettingsLoader.h"
+#include "magSlideTransitionFactory.h"
+
+const std::string magSlideShowSource::SettingsFileName = "magslideshow_settings.xml";
+
+magSlideShowSource::magSlideShowSource() {
+ name = "Slide Show Source";
+ currentSlideIndex = 0;
+ isPlaying = false;
+ directoryWatcher = 0;
+ doInit = false;
+ if (!loadFromXml(SettingsFileName))
+ {
+ ofLogError("magSlideShowSource") << "Could not find slide show settings file " << SettingsFileName;
+ Settings sets;
+ initialize(sets);
+ }
+}
+
+magSlideShowSource::~magSlideShowSource(){
+ if(directoryWatcher != 0){
+ delete directoryWatcher;
+ }
+}
+
+bool magSlideShowSource::initialize(magSlideShowSource::Settings settings) {
+ this->settings = settings;
+ bool success = true;
+
+ if (settings.width <= 0 || settings.height <= 0)
+ {
+ ofLogError("magSlideShowSource::initialize") << "Invalid value for width or height. Width and height "
+ "must be assigned in your Settings struct!";
+ return false;
+ }
+
+ // Allocate the FBO:
+ allocate(settings.width, settings.height);
+
+ // If there is a path in slidesFolderPath, attempt
+ // to load the folder and any files in it:
+ if (!settings.slidesFolderPath.empty())
+ {
+// ofDirectory dir = ofDirectory(settings.slidesFolderPath);
+ success = createFromFolderContents(settings.slidesFolderPath);
+
+ if (!success)
+ {
+ ofLogError("magSlideShowSource::initialize") << "Failed to create slide show from folder "
+ << settings.slidesFolderPath;
+ return success;
+ }
+ {
+ if (directoryWatcher == 0)
+ {
+
+ using namespace ofx::piMapper;
+ directoryWatcher = new DirectoryWatcher(settings.slidesFolderPath,
+ SourceTypeHelper::GetSourceTypeHelperEnum(
+ SOURCE_TYPE_NAME_IMAGE));
+ ofAddListener(directoryWatcher->directoryFileAddedEvent, this, &magSlideShowSource::fileAddedListener);
+ ofAddListener(directoryWatcher->directoryFileRemovedEvent, this,
+ &magSlideShowSource::fileRemovedListener);
+ directoryWatcher->beginWatch();
+ }
+ }
+
+ }
+ else if (!settings.slideshowFilePath.empty())
+ {
+ success = false;
+ }
+
+ return success;
+}
+
+void magSlideShowSource::setup() {
+ ofx::piMapper::FboSource::setup();
+}
+
+void magSlideShowSource::update() {
+
+ // Perform re-initialization if the DirectoryWatcher
+ // detects file changes:
+ if (doInit)
+ {
+ initialize(settings);
+ doInit = false;
+ }
+
+ if (!isPlaying) return;
+
+ auto nowTime = ofGetElapsedTimeMillis();
+ deltaTime = nowTime-lastTime;
+ runningTime += deltaTime;
+ lastTime = nowTime;
+
+ for (auto &slide : activeSlides)
+ {
+ slide->update(deltaTime);
+ }
+
+ // Queue the next slide if it is time
+ if (doPlayNextSlide)
+ {
+ playNextSlide();
+ if (activeSlides.size() > 1)
+ {
+ activeSlides[1]->transition->start(activeSlides[0]);
+ }
+ doPlayNextSlide = false;
+ }
+
+ // Erase any complete slides:
+ auto iter = activeSlides.begin();
+ for (; iter < activeSlides.end(); iter++)
+ {
+ if ((*iter)->isSlideComplete())
+ {
+// ofLogVerbose() << "Removing from active slides id: " << (*iter)->getId();
+ activeSlides.erase(iter);
+ --iter;
+ }
+ }
+
+ if (activeSlides.size() == 0 && isPlaying)
+ {
+ ofEventArgs args;
+ isPlaying = false;
+ ofNotifyEvent(slideshowCompleteEvent, args, this);
+ }
+}
+
+void magSlideShowSource::draw() {
+ ofBackground(0, 0);
+ ofPushMatrix();
+ ofPushStyle();
+ ofTranslate(getWidth()/2.0f, getHeight()/2.0f);
+ //ofEnableAlphaBlending();
+ ofSetRectMode(OF_RECTMODE_CENTER);
+ ofFill();
+ ofSetColor(255, 255);
+ for (auto &slide : activeSlides)
+ {
+ slide->draw();
+ }
+ ofPopStyle();
+ ofPopMatrix();
+ //ofDisableAlphaBlending();
+}
+
+bool magSlideShowSource::createFromFolderContents(std::string path) {
+ ofDirectory dir = ofDirectory(path);
+ slides.clear();
+
+ if (!dir.isDirectory())
+ {
+ ofLogError("magSlideShowSource::createFromFolderContents") << "Folder path " << dir.getAbsolutePath()
+ << " is not a directory";
+ return false;
+ }
+
+ ofDirectory sortedDir = dir.getSorted();
+ std::vector files = sortedDir.getFiles();
+
+ if (files.size() < 1){
+ ofLogError("magSlideShowSource::createFromFolderContents") << "Folder " << dir.getAbsolutePath() << " is empty";
+ return false;
+ }
+
+ ofImage tempImage;
+ for(ofFile &file : files){
+ if (tempImage.load(file.getFileName())){
+
+ // make a new image slide
+ auto slide = std::make_shared();
+ slide->setup(tempImage);
+ slide->setDuration(static_cast(settings.slideDuration*1000));
+ slide->setTransitionDuration(static_cast(settings.transitionDuration*1000));
+// if (settings.transitionName == "")
+ addSlide(slide);
+ }else{
+ auto ext = ofToLower(file.getExtension());
+
+ static std::vector movieExtensions = {
+ "mov", "qt", // Mac
+ "mp4", "m4p", "m4v", // MPEG
+ "mpg", "mp2", "mpeg", "mpe", "mpv", "m2v", // MPEG
+ "3gp", // Phones
+ "avi", "wmv", "asf", // Windows
+ "webm", "mkv", "flv", "vob", // Other containers
+ "ogv", "ogg",
+ "drc", "mxf"
+ };
+
+ // Check if the extension matches known movie formats:
+ if (ofContains(movieExtensions, ext))
+ {
+ // Make a new video slide
+ auto slide = std::make_shared();
+ if (slide->setup(file))
+ {
+ slide->setDuration(settings.slideDuration*1000.0);
+ slide->setTransitionDuration(settings.transitionDuration*1000.0);
+ addSlide(slide);
+ }
+ else
+ {
+ ofLogError("magSlideShowSource") << "Failed loading video: " << file.getAbsolutePath();
+ }
+ }
+
+ }
+ }
+
+ if (slides.size() > 0)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+bool magSlideShowSource::loadFromXml(std::string path) {
+ auto xml = ofxXmlSettings();
+ Settings settings;
+
+ if (!xml.load(path))
+ {
+ ofLogError("magSlideShowSource") << "Could not load settings file " << path;
+ return false;
+ }
+
+// xml.pushTag("surfaces");
+ if (!xml.pushTag("magSlideShow"))
+ {
+ ofLogError("magSlideShowSource") << "Slide show settings not found in " << path;
+ return false;
+ }
+
+ settings.width = xml.getValue("Width", settings.width);
+ settings.height = xml.getValue("Height", settings.height);
+
+ // Default slide duration:
+ settings.slideDuration = xml.getValue("SlideDuration", settings.slideDuration);
+
+ // Default loop:
+ if (xml.pushTag("Loop"))
+ {
+ auto type = xml.getValue("Type", "");
+ if (type == "NONE")
+ {
+ settings.loopType = LoopType::NONE;
+ }
+ else if (type == "NORMAL")
+ {
+ settings.loopType = LoopType::NORMAL;
+ }
+ else if (type == "PING-PONG")
+ {
+ settings.loopType = LoopType::PING_PONG;
+ }
+
+ settings.numLoops = xml.getValue("Count", settings.numLoops);
+ xml.popTag();
+ }
+
+ if (xml.pushTag("Transition"))
+ {
+ settings.transitionName = xml.getValue("Type", settings.transitionName);
+ settings.transitionDuration = xml.getValue("Duration", settings.transitionDuration);
+ xml.popTag();
+ }
+
+ // Default resize options:
+ auto ropts = xml.getValue("ResizeOption", "");
+ if (ropts == "NoResize")
+ {
+ settings.resizeOption = magSlide::NoResize;
+ }
+ else if (ropts == "Native")
+ {
+ settings.resizeOption = magSlide::Native;
+ }
+ else if (ropts == "Fit")
+ {
+ settings.resizeOption = magSlide::Fit;
+ }
+ else if (ropts == "FitProportionally")
+ {
+ settings.resizeOption = magSlide::FitProportionally;
+ }
+ else if (ropts == "FillProportionally")
+ {
+ settings.resizeOption = magSlide::FillProportionally;
+ }
+
+ initialize(settings);
+ return true;
+}
+
+void magSlideShowSource::addSlide(std::shared_ptr slide) {
+// ofLogVerbose("addSlide") << slide->getId();
+ slides.insert(slides.begin(), slide);
+ auto rOption = slide->getResizeOption();
+
+ // If the slide does not have a resize option assign
+ // the slide show's option
+ if (rOption == magSlide::ResizeOptions::NoResize)
+ {
+ rOption = settings.resizeOption;
+ }
+
+ // Resize the slide according to the resize option:
+ switch (rOption){
+ float sw, sh, ratio;
+
+ case magSlide::ResizeOptions::FitProportionally:
+ sw = slide->getWidth();
+ sh = slide->getHeight();
+
+ if (sw > sh)
+ {
+ ratio = (float) getWidth()/sw;
+ }
+ else
+ {
+ ratio = (float) getHeight()/sh;
+ }
+
+ slide->setSize(sw*ratio, sh*ratio);
+ break;
+
+ case magSlide::ResizeOptions::FillProportionally:
+ sw = slide->getWidth();
+ sh = slide->getHeight();
+
+ if (sw > sh)
+ {
+ ratio = (float) getHeight()/sh;
+ }
+ else
+ {
+ ratio = (float) getWidth()/sw;
+ }
+
+ slide->setSize(sw*ratio, sh*ratio);
+ break;
+
+ case magSlide::Fit:
+ slide->setSize(getWidth(), getHeight());
+ break;
+
+ default:
+ break;
+ }
+
+ // Add transitions:
+
+ static ofParameterGroup bogusParamGroup; // This is temporary so that things compile
+
+ auto tf = magSlideTransitionFactory::instance();
+// slide->buildIn = tf->createTransition(settings.transitionName,
+// slide,
+// bogusParamGroup,
+// slide->buildInDuration);
+ slide->transition = tf->createTransition(settings.transitionName,
+ slide,
+ bogusParamGroup,
+ slide->buildOutDuration);
+
+ //// void method(const void * sender, ArgumentsType &args)
+ ofAddListener(slide->slideStateChangedEvent, this, &magSlideShowSource::slideStateChanged);
+ ofAddListener(slide->slideCompleteEvent, this, &magSlideShowSource::slideComplete);
+
+}
+
+void magSlideShowSource::play() {
+ if (!isPlaying && slides.size()){
+ runningTime = 0;
+ lastTime = ofGetElapsedTimeMillis();
+ isPlaying = true;
+ auto currentSlide = slides[currentSlideIndex];
+ enqueueSlide(currentSlide, ofGetElapsedTimeMillis());
+ }
+}
+
+void magSlideShowSource::pause() {
+ isPlaying = false;
+}
+
+void magSlideShowSource::playNextSlide() {
+ //TODO
+ // I should check here to see if there are less than two slides.
+ // If so, we should probably return
+
+ currentSlideIndex += direction;
+ ofEventArgs args;
+
+ // This makes sure that we are doing a signed integer comparison,
+ // otherwise things get weird
+ int num = slides.size();
+ switch (settings.loopType)
+ {
+ case LoopType::NONE:
+ if (currentSlideIndex >= slides.size() || currentSlideIndex < 0)
+ {
+ // If we are not looping and we are out of bounds, return
+ // without enqueueing a slide. This will cause the slide show
+ // to end once the last slide builds out.
+ return;
+ }
+ break;
+ case LoopType::NORMAL:
+ if (currentSlideIndex >= num)
+ {
+ loopCount++;
+ if (loopCount == settings.numLoops)
+ {
+ // Return without enqueueing a new slide if we have
+ // reached the max number of loops.
+ return;
+ }
+ currentSlideIndex = 0;
+ ofNotifyEvent(slideshowWillLoopEvent, args, this);
+ }
+ else if (currentSlideIndex < 0)
+ {
+ loopCount++;
+ if (loopCount == settings.numLoops)
+ {
+ // Return without enqueueing a new slide if we have
+ // reached the max number of loops.
+ return;
+ }
+ currentSlideIndex = slides.size()-1;
+ ofNotifyEvent(slideshowWillLoopEvent, args, this);
+ }
+ break;
+ case LoopType::PING_PONG:
+
+ int num = slides.size();
+ if (currentSlideIndex >= num)
+ {
+ loopCount++;
+ if (loopCount == settings.numLoops)
+ {
+ // Return without enqueueing a new slide if we have
+ // reached the max number of loops.
+ return;
+ }
+
+ direction = -1;
+ currentSlideIndex = slides.size()-2;
+ ofNotifyEvent(slideshowWillLoopEvent, args, this);
+ }
+ else if (currentSlideIndex < 0)
+ {
+ loopCount++;
+ if (loopCount == settings.numLoops)
+ {
+ // Return without enqueueing a new slide if we have
+ // reached the max number of loops.
+ return;
+ }
+
+ direction = 1;
+ currentSlideIndex = 1;
+ ofNotifyEvent(slideshowWillLoopEvent, args, this);
+ }
+ break;
+ }
+
+ enqueueSlide(slides[currentSlideIndex], ofGetElapsedTimeMillis());
+}
+
+void magSlideShowSource::playPrevSlide() {
+ currentSlideIndex -= (direction*2);
+ playNextSlide();
+}
+
+void magSlideShowSource::playSlide(int slideIndex) {
+ currentSlideIndex = slideIndex-direction;
+ playNextSlide();
+}
+
+void magSlideShowSource::enqueueSlide(std::shared_ptr slide, uint64_t startTime) {
+// ofLogVerbose() << "Enqueuing slide " << currentSlideIndex << " slide id: " << slide->getId();
+ slide->start(startTime);
+ activeSlides.insert(activeSlides.begin(), slide);
+}
+
+void magSlideShowSource::slideStateChanged(const void *sender, ofEventArgs &args) {
+ magSlide *slide = (magSlide *) sender;
+
+// ofLogVerbose("slideStateChanged") << "Slide id: " << slide->getId() << " Slide state: "
+// << slide->getSlideStateName();
+ if (slide->getSlideState() == magSlide::SlideState::BuildOut)
+ {
+ // Flag that we need to load the next slide:
+ doPlayNextSlide = true;
+ }
+
+}
+
+void magSlideShowSource::slideComplete(const void *sender, ofEventArgs &args) {
+ magSlide *slide = (magSlide *) sender;
+// ofLogVerbose() << "Slide Complete. id: " << slide->getId();
+ slide->isComplete = true;
+}
+
+void magSlideShowSource::fileAddedListener(const void *sender) {
+ doInit = true;
+}
+
+void magSlideShowSource::fileRemovedListener(const void *sender) {
+ doInit = true;
+}
diff --git a/example_fbo-sources/src/SlideShowSource/magSlideShowSource.h b/example_fbo-sources/src/SlideShowSource/magSlideShowSource.h
index 47b4cd5..4ea817c 100644
--- a/example_fbo-sources/src/SlideShowSource/magSlideShowSource.h
+++ b/example_fbo-sources/src/SlideShowSource/magSlideShowSource.h
@@ -1,167 +1,167 @@
-//
-// magSlideShowSource.h
-// Copyright (c) 2017 Cristobal Mendoza
-// http://cuppetellimendoza.com
-//
-
-#ifndef MAGSLIDESHOWSOURCE_H
-#define MAGSLIDESHOWSOURCE_H
-
-#include "FboSource.h"
-#include "magSlide.h"
-#include "DirectoryWatcher.h"
-
-class magSlide;
-
-class magSlideShowSource : public ofx::piMapper::FboSource {
- public:
- magSlideShowSource();
-
- /**
- * Default settings file name.
- */
- static const std::string SettingsFileName;
- struct Settings; // forward declaration
- bool initialize(magSlideShowSource::Settings settings);
- void setup() override;
- void update() override;
- void draw() override;
-
- /**
- * Removes all slides and then attempts to create a new slide show
- * based on the contents of the ofDirectory specified. The files may
- * be images or videos, which will be transformed into the appropriate slide type.
- * Any other file type in the directory is ignored (including other directories).
- * The slide order is alphabetical according to filename.
- *
- * @param dir The ofDirectory to use as a source for a slide show.
- * @return true if at least one slide was created. false is returned
- * otherwise. Check the console for the specific error.
- */
- bool createFromFolderContents(std::string path);
- bool loadFromXml(std::string path);
- void addSlide(std::shared_ptr slide);
- void play();
- void pause();
- void playNextSlide();
- void playPrevSlide();
- void playSlide(int slideIndex);
-
- enum LoopType : int {
- NONE = 0,
- NORMAL,
- PING_PONG
- };
-
- struct Settings {
- /**
- * The pixel width of the FBO.
- */
- float width = 1280;
-
- /**
- * The pixel height of the FBO.
- */
- float height = 720;
- /**
- * An optional default slide duration, in seconds.
- * If a slide specifies a duration this value is ignored.
- */
- float slideDuration = 5;
-
- /**
- * The default transition for the slide show.
- */
- std::string transitionName = "Dissolve";
-
- /**
- * Default transition duration.
- */
- float transitionDuration = 1;
-
- /**
- * If specified, all applicable files in the folder will
- * be used as slides in the slide show. They will be ordered
- * alphabetically according to their file names.
- *
- * If path is relative, the root will likely be the Data folder.
- */
- std::string slidesFolderPath = "sources/images";
-
- /**
- * If specified,
- */
- std::string slideshowFilePath;
-
-
- /**
- * Loop type for the slide show. See @code LoopType for options.
- * The default is @code LoopType:None.
- */
- LoopType loopType = LoopType::NONE;
-
- /**
- * The number of loops to perform, if the loopType is not NONE.
- * If the value is 0 or less than 0, the slide show loops forever.
- */
- int numLoops = 0;
-
- /**
- * The resizing option for the slide show. The default is FitProportionally.
- * If a slide already has a resizing option applied, that option will be
- * respected and this resizeOption will not be used.
- */
- magSlide::ResizeOptions resizeOption = magSlide::ResizeOptions::FitProportionally;
- };
-
- ////////////////////////////////////////////
- //// Event Listeners
- ////////////////////////////////////////////
- void slideStateChanged(const void *sender, ofEventArgs &args);
- void slideComplete(const void *sender, ofEventArgs &args);
- virtual ~magSlideShowSource();
-
-
- /**
- * Fires when the slide show is done, which happens when
- * the loop count is equal to Settings::numLoops, or when
- * the last slide is played when @code LoopType::NONE is specified.
- * Sender is this slide show.
- */
- ofEvent slideshowCompleteEvent;
-
-
- /**
- * Fires when the slide show reaches the last slide
- * and will perform a loop in the next call.
- * Sender is this slide show.
- */
- ofEvent slideshowWillLoopEvent;
-
- protected:
- Settings settings;
- std::vector> slides;
-
- private:
-// std::shared_ptr currentSlide;
- std::vector> activeSlides;
- void enqueueSlide(std::shared_ptr slide, uint64_t startTime);
-
- uint64_t lastTime;
- uint64_t deltaTime;
- uint64_t runningTime;
-
- bool isInitialized = false;
- bool isPlaying = false;
- int currentSlideIndex = 0;
- int direction = 1;
- int loopCount = 0;
- ofx::piMapper::DirectoryWatcher * directoryWatcher;
- void fileAddedListener(const void * sender);
- void fileRemovedListener(const void * sender);
- bool doInit;
- bool doPlayNextSlide = false;
-};
-
-
-#endif
+//
+// magSlideShowSource.h
+// Copyright (c) 2017 Cristobal Mendoza
+// http://cuppetellimendoza.com
+//
+
+#ifndef MAGSLIDESHOWSOURCE_H
+#define MAGSLIDESHOWSOURCE_H
+
+#include "FboSource.h"
+#include "magSlide.h"
+#include "DirectoryWatcher.h"
+
+class magSlide;
+
+class magSlideShowSource : public ofx::piMapper::FboSource {
+ public:
+ magSlideShowSource();
+
+ /**
+ * Default settings file name.
+ */
+ static const std::string SettingsFileName;
+ struct Settings; // forward declaration
+ bool initialize(magSlideShowSource::Settings settings);
+ void setup() override;
+ void update() override;
+ void draw() override;
+
+ /**
+ * Removes all slides and then attempts to create a new slide show
+ * based on the contents of the ofDirectory specified. The files may
+ * be images or videos, which will be transformed into the appropriate slide type.
+ * Any other file type in the directory is ignored (including other directories).
+ * The slide order is alphabetical according to filename.
+ *
+ * @param dir The ofDirectory to use as a source for a slide show.
+ * @return true if at least one slide was created. false is returned
+ * otherwise. Check the console for the specific error.
+ */
+ bool createFromFolderContents(std::string path);
+ bool loadFromXml(std::string path);
+ void addSlide(std::shared_ptr slide);
+ void play();
+ void pause();
+ void playNextSlide();
+ void playPrevSlide();
+ void playSlide(int slideIndex);
+
+ enum LoopType : int {
+ NONE = 0,
+ NORMAL,
+ PING_PONG
+ };
+
+ struct Settings {
+ /**
+ * The pixel width of the FBO.
+ */
+ float width = 1280;
+
+ /**
+ * The pixel height of the FBO.
+ */
+ float height = 720;
+ /**
+ * An optional default slide duration, in seconds.
+ * If a slide specifies a duration this value is ignored.
+ */
+ float slideDuration = 5;
+
+ /**
+ * The default transition for the slide show.
+ */
+ std::string transitionName = "Dissolve";
+
+ /**
+ * Default transition duration.
+ */
+ float transitionDuration = 1;
+
+ /**
+ * If specified, all applicable files in the folder will
+ * be used as slides in the slide show. They will be ordered
+ * alphabetically according to their file names.
+ *
+ * If path is relative, the root will likely be the Data folder.
+ */
+ std::string slidesFolderPath = "sources/images";
+
+ /**
+ * If specified,
+ */
+ std::string slideshowFilePath;
+
+
+ /**
+ * Loop type for the slide show. See @code LoopType for options.
+ * The default is @code LoopType:None.
+ */
+ LoopType loopType = LoopType::NONE;
+
+ /**
+ * The number of loops to perform, if the loopType is not NONE.
+ * If the value is 0 or less than 0, the slide show loops forever.
+ */
+ int numLoops = 0;
+
+ /**
+ * The resizing option for the slide show. The default is FitProportionally.
+ * If a slide already has a resizing option applied, that option will be
+ * respected and this resizeOption will not be used.
+ */
+ magSlide::ResizeOptions resizeOption = magSlide::ResizeOptions::FitProportionally;
+ };
+
+ ////////////////////////////////////////////
+ //// Event Listeners
+ ////////////////////////////////////////////
+ void slideStateChanged(const void *sender, ofEventArgs &args);
+ void slideComplete(const void *sender, ofEventArgs &args);
+ virtual ~magSlideShowSource();
+
+
+ /**
+ * Fires when the slide show is done, which happens when
+ * the loop count is equal to Settings::numLoops, or when
+ * the last slide is played when @code LoopType::NONE is specified.
+ * Sender is this slide show.
+ */
+ ofEvent slideshowCompleteEvent;
+
+
+ /**
+ * Fires when the slide show reaches the last slide
+ * and will perform a loop in the next call.
+ * Sender is this slide show.
+ */
+ ofEvent slideshowWillLoopEvent;
+
+ protected:
+ Settings settings;
+ std::vector> slides;
+
+ private:
+// std::shared_ptr currentSlide;
+ std::vector> activeSlides;
+ void enqueueSlide(std::shared_ptr slide, uint64_t startTime);
+
+ uint64_t lastTime;
+ uint64_t deltaTime;
+ uint64_t runningTime;
+
+ bool isInitialized = false;
+ bool isPlaying = false;
+ int currentSlideIndex = 0;
+ int direction = 1;
+ int loopCount = 0;
+ ofx::piMapper::DirectoryWatcher * directoryWatcher;
+ void fileAddedListener(const void * sender);
+ void fileRemovedListener(const void * sender);
+ bool doInit;
+ bool doPlayNextSlide = false;
+};
+
+
+#endif
diff --git a/example_fbo-sources/src/SlideShowSource/magSlideTransition.cpp b/example_fbo-sources/src/SlideShowSource/magSlideTransition.cpp
index 2377702..93f532e 100644
--- a/example_fbo-sources/src/SlideShowSource/magSlideTransition.cpp
+++ b/example_fbo-sources/src/SlideShowSource/magSlideTransition.cpp
@@ -1,60 +1,60 @@
-//
-// magSlideTransition.cpp
-// Copyright (c) 2017 Cristobal Mendoza
-// http://cuppetellimendoza.com
-//
-
-#include "magSlideTransition.h"
-
-void magSlideTransition::start(std::shared_ptr nextSlide)
-{
- runningTime = 0;
- active = true;
- this->nextSlide = nextSlide;
-}
-
-void magSlideTransition::update(uint64_t timeDelta)
-{
- if (!active) return;
-
- runningTime += timeDelta;
- if (runningTime >= duration)
- {
- ofEventArgs arghh; // arghhhh...
- nextSlide->setOpacity(255);
- nextSlide->setPosition(0, 0);
- end();
- transitionCompleteEvent.notify(this, arghh);
- active = false;
- }
-
-}
-
-uint64_t magSlideTransition::getRunningTime()
-{
- return runningTime;
-}
-
-float magSlideTransition::getNormalizedTime()
-{
- return (double)runningTime / (double)duration;
-}
-
-
-void magDissolveTransition::draw()
-{
- slide->setOpacity(255 - (getNormalizedTime() * 255));
- nextSlide->setOpacity(getNormalizedTime()*255);
-}
-
-void magDissolveTransition::start(std::shared_ptr nextSlide)
-{
- magSlideTransition::start(nextSlide);
- nextSlide->setOpacity(0);
-}
-
-void magDissolveTransition::end()
-{
- nextSlide->setOpacity(255);
- slide->setOpacity(0);
-}
+//
+// magSlideTransition.cpp
+// Copyright (c) 2017 Cristobal Mendoza
+// http://cuppetellimendoza.com
+//
+
+#include "magSlideTransition.h"
+
+void magSlideTransition::start(std::shared_ptr nextSlide)
+{
+ runningTime = 0;
+ active = true;
+ this->nextSlide = nextSlide;
+}
+
+void magSlideTransition::update(uint64_t timeDelta)
+{
+ if (!active) return;
+
+ runningTime += timeDelta;
+ if (runningTime >= duration)
+ {
+ ofEventArgs arghh; // arghhhh...
+ nextSlide->setOpacity(255);
+ nextSlide->setPosition(0, 0);
+ end();
+ transitionCompleteEvent.notify(this, arghh);
+ active = false;
+ }
+
+}
+
+uint64_t magSlideTransition::getRunningTime()
+{
+ return runningTime;
+}
+
+float magSlideTransition::getNormalizedTime()
+{
+ return (double)runningTime / (double)duration;
+}
+
+
+void magDissolveTransition::draw()
+{
+ slide->setOpacity(255 - (getNormalizedTime() * 255));
+ nextSlide->setOpacity(getNormalizedTime()*255);
+}
+
+void magDissolveTransition::start(std::shared_ptr nextSlide)
+{
+ magSlideTransition::start(nextSlide);
+ nextSlide->setOpacity(0);
+}
+
+void magDissolveTransition::end()
+{
+ nextSlide->setOpacity(255);
+ slide->setOpacity(0);
+}
diff --git a/example_fbo-sources/src/SlideShowSource/magSlideTransition.h b/example_fbo-sources/src/SlideShowSource/magSlideTransition.h
index 421b057..524b98d 100644
--- a/example_fbo-sources/src/SlideShowSource/magSlideTransition.h
+++ b/example_fbo-sources/src/SlideShowSource/magSlideTransition.h
@@ -1,129 +1,129 @@
-//
-// magSlideTransition.h
-// Copyright (c) 2017 Cristobal Mendoza
-// http://cuppetellimendoza.com
-//
-
-#ifndef MAGSLIDETRANSITION_H
-#define MAGSLIDETRANSITION_H
-
-#include "magSlide.h"
-
-class magSlideTransitionFactory;
-
-class magSlideTransition
-{
-public:
- /**
- * Subclassing notes: Make sure to provide a value for name in your
- * magSlideTransition subclass.
- */
- magSlideTransition() { name = "Void"; }
- /**
- * Begins the transition. This needs to be called in order for the
- * transition to do anything.
- * @param nextSlide The subsequent slide in the slide show needs to be
- * passed here.
- *
- * You can override this call to set any initial conditions to the transition,
- * but make sure to call this method in your override.
- */
- virtual void start(std::shared_ptr nextSlide);
-
- /**
- * Called automatically when the transition is complete. Useful to set
- * end states for the parameters of the slide and nextSlide. Default implementation
- * does nothing.
- */
- virtual void end(){}
-
- /**
- * NOTE: The transition settings system is not yet implemented.
- * Called when the transition is created. Loads settings for magSlideTransition
- * subclasses. The default implementation does nothing.
- * @param settings ofParameterGroup with settings for your custom magSlideTransition
- * subclass.
- */
- virtual void loadSettings(ofParameterGroup &settings){}
-
- /**
- * Updates the transition.
- * @param timeDelta The elapsed time (in ms.) between the last call to update() and
- * this one (i.e. the frame time).
- *
- * If you need to override update, make sure to call this implementation
- * in your subclass.
- */
- virtual void update(uint64_t timeDelta);
-
- /**
- * Draws the transition. Default implementation does nothing.
- */
- virtual void draw(){
- ofLogNotice("magSlideTransition") << "transition draw - this should be overriden " << getNormalizedTime();
- }
-
- /**
- * Current running time in milliseconds.
- * @return uint64_t
- */
- uint64_t getRunningTime();
-
- /**
- * Returns the current time in normalized form.
- * 0 = start, 1 = end.
- * @return Float between 0 and 1.
- */
- float getNormalizedTime();
-
- std::string const &getName() const
- {
- return name;
- }
-
- const shared_ptr &getNextSlide() const
- {
- return nextSlide;
- }
-
- bool isActive() const
- {
- return active;
- }
-
- /**
- * Sender is a raw pointer to this magSlideTransition
- */
- ofEvent transitionCompleteEvent;
-
-protected:
- std::string name;
- std::shared_ptr slide;
- std::shared_ptr nextSlide;
-
- uint64_t runningTime;
- uint64_t duration;
- uint64_t endTime;
- bool active = false;
-
-
-protected:
-
- friend class magSlideTransitionFactory;
-};
-
-class magDissolveTransition : public magSlideTransition
-{
-public:
- magDissolveTransition()
- {
- name = "Dissolve";
- }
-
- void start(std::shared_ptr nextSlide) override;
-
- void draw() override;
- void end() override;
-};
-
-#endif
+//
+// magSlideTransition.h
+// Copyright (c) 2017 Cristobal Mendoza
+// http://cuppetellimendoza.com
+//
+
+#ifndef MAGSLIDETRANSITION_H
+#define MAGSLIDETRANSITION_H
+
+#include "magSlide.h"
+
+class magSlideTransitionFactory;
+
+class magSlideTransition
+{
+public:
+ /**
+ * Subclassing notes: Make sure to provide a value for name in your
+ * magSlideTransition subclass.
+ */
+ magSlideTransition() { name = "Void"; }
+ /**
+ * Begins the transition. This needs to be called in order for the
+ * transition to do anything.
+ * @param nextSlide The subsequent slide in the slide show needs to be
+ * passed here.
+ *
+ * You can override this call to set any initial conditions to the transition,
+ * but make sure to call this method in your override.
+ */
+ virtual void start(std::shared_ptr nextSlide);
+
+ /**
+ * Called automatically when the transition is complete. Useful to set
+ * end states for the parameters of the slide and nextSlide. Default implementation
+ * does nothing.
+ */
+ virtual void end(){}
+
+ /**
+ * NOTE: The transition settings system is not yet implemented.
+ * Called when the transition is created. Loads settings for magSlideTransition
+ * subclasses. The default implementation does nothing.
+ * @param settings ofParameterGroup with settings for your custom magSlideTransition
+ * subclass.
+ */
+ virtual void loadSettings(ofParameterGroup &settings){}
+
+ /**
+ * Updates the transition.
+ * @param timeDelta The elapsed time (in ms.) between the last call to update() and
+ * this one (i.e. the frame time).
+ *
+ * If you need to override update, make sure to call this implementation
+ * in your subclass.
+ */
+ virtual void update(uint64_t timeDelta);
+
+ /**
+ * Draws the transition. Default implementation does nothing.
+ */
+ virtual void draw(){
+ ofLogNotice("magSlideTransition") << "transition draw - this should be overriden " << getNormalizedTime();
+ }
+
+ /**
+ * Current running time in milliseconds.
+ * @return uint64_t
+ */
+ uint64_t getRunningTime();
+
+ /**
+ * Returns the current time in normalized form.
+ * 0 = start, 1 = end.
+ * @return Float between 0 and 1.
+ */
+ float getNormalizedTime();
+
+ std::string const &getName() const
+ {
+ return name;
+ }
+
+ const shared_ptr &getNextSlide() const
+ {
+ return nextSlide;
+ }
+
+ bool isActive() const
+ {
+ return active;
+ }
+
+ /**
+ * Sender is a raw pointer to this magSlideTransition
+ */
+ ofEvent transitionCompleteEvent;
+
+protected:
+ std::string name;
+ std::shared_ptr slide;
+ std::shared_ptr nextSlide;
+
+ uint64_t runningTime;
+ uint64_t duration;
+ uint64_t endTime;
+ bool active = false;
+
+
+protected:
+
+ friend class magSlideTransitionFactory;
+};
+
+class magDissolveTransition : public magSlideTransition
+{
+public:
+ magDissolveTransition()
+ {
+ name = "Dissolve";
+ }
+
+ void start(std::shared_ptr nextSlide) override;
+
+ void draw() override;
+ void end() override;
+};
+
+#endif
diff --git a/example_fbo-sources/src/SlideShowSource/magSlideTransitionFactory.cpp b/example_fbo-sources/src/SlideShowSource/magSlideTransitionFactory.cpp
index ef44d1b..90fffef 100644
--- a/example_fbo-sources/src/SlideShowSource/magSlideTransitionFactory.cpp
+++ b/example_fbo-sources/src/SlideShowSource/magSlideTransitionFactory.cpp
@@ -1,76 +1,76 @@
-//
-// Created by Cristobal Mendoza on 12/3/17.
-//
-
-#include "magSlideTransitionFactory.h"
-
-/*
- *
- *
- *
-class Base {};
-
-class DerivedA : public Base {};
-class DerivedB : public Base {};
-class DerivedC : public Base {};
-
-Base* create(const std::string& type)
-{
- static std::map> type_creator_map =
- {
- {"DerivedA", [](){return new DerivedA();}},
- {"DerivedB", [](){return new DerivedB();}},
- {"DerivedC", [](){return new DerivedC();}}
- };
-
- auto it = type_creator_map.find(type);
- if(it != type_creator_map.end())
- {
- return it->second();
- }
-
- return nullptr;
-}
- */
-
-magSlideTransitionFactory* magSlideTransitionFactory::_instance = 0;
-
-magSlideTransitionFactory::magSlideTransitionFactory()
-{
- magSlideTransition voidTransition;
- magDissolveTransition dissolve;
-
- registerTransition(voidTransition);
- registerTransition(dissolve);
-}
-
-magSlideTransitionFactory* magSlideTransitionFactory::instance()
-{
- if (_instance == 0)
- {
- _instance = new magSlideTransitionFactory();
- }
-
- return _instance;
-}
-
-std::shared_ptr
-magSlideTransitionFactory::createTransition(std::string transitionName, std::shared_ptr slide,
- ofParameterGroup &settings, uint64_t duration)
-{
- std::shared_ptr transition;
-
- if (transitionsMap.count(transitionName) > 0)
- {
- transition = transitionsMap[transitionName]();
- }
- else
- {
- transition = transitionsMap[transition->getName()]();
- }
-
- transition->slide = slide;
- transition->duration = duration;
- transition->loadSettings(settings);
- return transition;
-}
+//
+// Created by Cristobal Mendoza on 12/3/17.
+//
+
+#include "magSlideTransitionFactory.h"
+
+/*
+ *
+ *
+ *
+class Base {};
+
+class DerivedA : public Base {};
+class DerivedB : public Base {};
+class DerivedC : public Base {};
+
+Base* create(const std::string& type)
+{
+ static std::map> type_creator_map =
+ {
+ {"DerivedA", [](){return new DerivedA();}},
+ {"DerivedB", [](){return new DerivedB();}},
+ {"DerivedC", [](){return new DerivedC();}}
+ };
+
+ auto it = type_creator_map.find(type);
+ if(it != type_creator_map.end())
+ {
+ return it->second();
+ }
+
+ return nullptr;
+}
+ */
+
+magSlideTransitionFactory* magSlideTransitionFactory::_instance = 0;
+
+magSlideTransitionFactory::magSlideTransitionFactory()
+{
+ magSlideTransition voidTransition;
+ magDissolveTransition dissolve;
+
+ registerTransition(voidTransition);
+ registerTransition(dissolve);
+}
+
+magSlideTransitionFactory* magSlideTransitionFactory::instance()
+{
+ if (_instance == 0)
+ {
+ _instance = new magSlideTransitionFactory();
+ }
+
+ return _instance;
+}
+
+std::shared_ptr
+magSlideTransitionFactory::createTransition(std::string transitionName, std::shared_ptr slide,
+ ofParameterGroup &settings, uint64_t duration)
+{
+ std::shared_ptr transition;
+
+ if (transitionsMap.count(transitionName) > 0)
+ {
+ transition = transitionsMap[transitionName]();
+ }
+ else
+ {
+ transition = transitionsMap[transition->getName()]();
+ }
+
+ transition->slide = slide;
+ transition->duration = duration;
+ transition->loadSettings(settings);
+ return transition;
+}
diff --git a/example_fbo-sources/src/SlideShowSource/magSlideTransitionFactory.h b/example_fbo-sources/src/SlideShowSource/magSlideTransitionFactory.h
index 75986e8..6b15d00 100644
--- a/example_fbo-sources/src/SlideShowSource/magSlideTransitionFactory.h
+++ b/example_fbo-sources/src/SlideShowSource/magSlideTransitionFactory.h
@@ -1,41 +1,41 @@
-//
-// Created by Cristobal Mendoza on 12/3/17.
-//
-
-#ifndef MAGSLIDETRANSITIONFACTORY_H
-#define MAGSLIDETRANSITIONFACTORY_H
-
-#include "magSlide.h"
-#include "magSlideTransition.h"
-
-/**
- * Factory class to register and instantiate transitions.
- */
-class magSlideTransitionFactory
-{
-public:
- static magSlideTransitionFactory* instance();
-
- std::shared_ptr createTransition(std::string transitionName,
- std::shared_ptr slide,
- ofParameterGroup &group,
- uint64_t duration);
- template
- void registerTransition(T transition)
- {
- if (transitionsMap.count(transition.getName()) == 0)
- {
- transitionsMap[transition.getName()] = [](){
- return std::make_shared();
- };
- }
- }
-
-protected:
- std::unordered_map()>> transitionsMap;
-private:
- static magSlideTransitionFactory* _instance;
- magSlideTransitionFactory();
-};
-
-#endif //MAGSLIDETRANSITIONFACTORY_H
+//
+// Created by Cristobal Mendoza on 12/3/17.
+//
+
+#ifndef MAGSLIDETRANSITIONFACTORY_H
+#define MAGSLIDETRANSITIONFACTORY_H
+
+#include "magSlide.h"
+#include "magSlideTransition.h"
+
+/**
+ * Factory class to register and instantiate transitions.
+ */
+class magSlideTransitionFactory
+{
+public:
+ static magSlideTransitionFactory* instance();
+
+ std::shared_ptr createTransition(std::string transitionName,
+ std::shared_ptr slide,
+ ofParameterGroup &group,
+ uint64_t duration);
+ template
+ void registerTransition(T transition)
+ {
+ if (transitionsMap.count(transition.getName()) == 0)
+ {
+ transitionsMap[transition.getName()] = [](){
+ return std::make_shared();
+ };
+ }
+ }
+
+protected:
+ std::unordered_map()>> transitionsMap;
+private:
+ static magSlideTransitionFactory* _instance;
+ magSlideTransitionFactory();
+};
+
+#endif //MAGSLIDETRANSITIONFACTORY_H
diff --git a/example_fbo-sources/src/SyphonSource/SyphonSource.cpp b/example_fbo-sources/src/SyphonSource/SyphonSource.cpp
index 3392120..be53f86 100644
--- a/example_fbo-sources/src/SyphonSource/SyphonSource.cpp
+++ b/example_fbo-sources/src/SyphonSource/SyphonSource.cpp
@@ -1,87 +1,87 @@
-// #include "SyphonSource.h"
-//
-// void SyphonSource::setup(){
-// // Give our source a decent name
-// name = "Syphon Source";
-//
-// // Allocate our FBO source, decide how big it should be
-// allocate(500, 500);
-//
-// //setup our directory
-// dir.setup();
-// //setup our client
-// mClient.setup();
-//
-// //register for our directory's callbacks
-// ofAddListener(dir.events.serverAnnounced, this, &SyphonSource::serverAnnounced);
-// // not yet implemented
-// //ofAddListener(dir.events.serverUpdated, this, &ofApp::serverUpdated);
-// ofAddListener(dir.events.serverRetired, this, &SyphonSource::serverRetired);
-//
-// dirIdx = -1;
-// }
-//
-// //these are our directory's callbacks
-// void SyphonSource::serverAnnounced(ofxSyphonServerDirectoryEventArgs &arg)
-// {
-// for( auto& dir : arg.servers ){
-// ofLogNotice("ofxSyphonServerDirectory Server Announced")<<" Server Name: "< 0)
-// {
-// dirIdx++;
-// if(dirIdx > dir.size() - 1)
-// dirIdx = 0;
-//
-// mClient.set(dir.getDescription(dirIdx));
-// string serverName = mClient.getServerName();
-// string appName = mClient.getApplicationName();
-//
-// if(serverName == ""){
-// serverName = "null";
-// }
-// if(appName == ""){
-// appName = "null";
-// }
-// ofSetWindowTitle(serverName + ":" + appName);
-// }
-// else
-// {
-// ofSetWindowTitle("No Server");
-// }
-// }
+// #include "SyphonSource.h"
+//
+// void SyphonSource::setup(){
+// // Give our source a decent name
+// name = "Syphon Source";
+//
+// // Allocate our FBO source, decide how big it should be
+// allocate(500, 500);
+//
+// //setup our directory
+// dir.setup();
+// //setup our client
+// mClient.setup();
+//
+// //register for our directory's callbacks
+// ofAddListener(dir.events.serverAnnounced, this, &SyphonSource::serverAnnounced);
+// // not yet implemented
+// //ofAddListener(dir.events.serverUpdated, this, &ofApp::serverUpdated);
+// ofAddListener(dir.events.serverRetired, this, &SyphonSource::serverRetired);
+//
+// dirIdx = -1;
+// }
+//
+// //these are our directory's callbacks
+// void SyphonSource::serverAnnounced(ofxSyphonServerDirectoryEventArgs &arg)
+// {
+// for( auto& dir : arg.servers ){
+// ofLogNotice("ofxSyphonServerDirectory Server Announced")<<" Server Name: "< 0)
+// {
+// dirIdx++;
+// if(dirIdx > dir.size() - 1)
+// dirIdx = 0;
+//
+// mClient.set(dir.getDescription(dirIdx));
+// string serverName = mClient.getServerName();
+// string appName = mClient.getApplicationName();
+//
+// if(serverName == ""){
+// serverName = "null";
+// }
+// if(appName == ""){
+// appName = "null";
+// }
+// ofSetWindowTitle(serverName + ":" + appName);
+// }
+// else
+// {
+// ofSetWindowTitle("No Server");
+// }
+// }
diff --git a/example_fbo-sources/src/SyphonSource/SyphonSource.h b/example_fbo-sources/src/SyphonSource/SyphonSource.h
index 2f7ca52..9aa95f6 100644
--- a/example_fbo-sources/src/SyphonSource/SyphonSource.h
+++ b/example_fbo-sources/src/SyphonSource/SyphonSource.h
@@ -1,21 +1,21 @@
-// #pragma once
-//
-// #include "ofMain.h"
-// #include "FboSource.h"
-// #include "ofxSyphon.h"
-// class SyphonSource : public ofx::piMapper::FboSource {
-// public:
-// void setup();
-// void update();
-// void draw();
-//
-// void keyReleased(int key);
-//
-// void serverAnnounced(ofxSyphonServerDirectoryEventArgs &arg);
-// void serverUpdated(ofxSyphonServerDirectoryEventArgs &args);
-// void serverRetired(ofxSyphonServerDirectoryEventArgs &arg);
-//
-// ofxSyphonServerDirectory dir;
-// ofxSyphonClient mClient;
-// int dirIdx;
-// };
+// #pragma once
+//
+// #include "ofMain.h"
+// #include "FboSource.h"
+// #include "ofxSyphon.h"
+// class SyphonSource : public ofx::piMapper::FboSource {
+// public:
+// void setup();
+// void update();
+// void draw();
+//
+// void keyReleased(int key);
+//
+// void serverAnnounced(ofxSyphonServerDirectoryEventArgs &arg);
+// void serverUpdated(ofxSyphonServerDirectoryEventArgs &args);
+// void serverRetired(ofxSyphonServerDirectoryEventArgs &arg);
+//
+// ofxSyphonServerDirectory dir;
+// ofxSyphonClient mClient;
+// int dirIdx;
+// };
diff --git a/example_fbo-sources/src/main.cpp b/example_fbo-sources/src/main.cpp
index d191606..d80b1de 100644
--- a/example_fbo-sources/src/main.cpp
+++ b/example_fbo-sources/src/main.cpp
@@ -1,7 +1,7 @@
-#include "ofMain.h"
-#include "ofApp.h"
-
-int main(){
- ofSetupOpenGL(1024, 768, OF_WINDOW);
- ofRunApp(new ofApp());
-}
+#include "ofMain.h"
+#include "ofApp.h"
+
+int main(){
+ ofSetupOpenGL(1024, 768, OF_WINDOW);
+ ofRunApp(new ofApp());
+}
diff --git a/example_fbo-sources/src/ofApp.cpp b/example_fbo-sources/src/ofApp.cpp
index e2c626c..6f6c763 100644
--- a/example_fbo-sources/src/ofApp.cpp
+++ b/example_fbo-sources/src/ofApp.cpp
@@ -1,57 +1,57 @@
-#include "ofApp.h"
-
-void ofApp::setup(){
- ofBackground(0);
-
- // Enable or disable audio for video sources globally
- // Set this to false to save resources on the Raspberry Pi
- ofx::piMapper::VideoSource::enableAudio = true;
- ofx::piMapper::VideoSource::useHDMIForAudio = false;
-
- // Register our sources.
- // This should be done before mapper.setup().
- piMapper.registerFboSource(ScanLSource);
- piMapper.registerFboSource(QuadiSource);
- piMapper.registerFboSource(CircLSource);
- piMapper.registerFboSource(BricksSource);
- //piMapper.registerFboSource(SyphonClient);
- //piMapper.registerFboSource(slideShowSource);
- piMapper.setup();
-
- // This will set the app fullscreen if compiled on Raspberry Pi.
- #ifdef TARGET_RASPBERRY_PI
- ofSetFullscreen(true);
- #endif
-
- // Start slideshow.
- //slideShowSource.play();
-}
-
-void ofApp::update(){
- piMapper.update();
-}
-
-void ofApp::draw(){
- piMapper.draw();
-}
-
-void ofApp::keyPressed(int key){
- piMapper.keyPressed(key);
-}
-
-void ofApp::keyReleased(int key){
- piMapper.keyReleased(key);
-}
-
-void ofApp::mousePressed(int x, int y, int button){
-
- piMapper.mousePressed(x, y, button);
-}
-
-void ofApp::mouseReleased(int x, int y, int button){
- piMapper.mouseReleased(x, y, button);
-}
-
-void ofApp::mouseDragged(int x, int y, int button){
- piMapper.mouseDragged(x, y, button);
-}
+#include "ofApp.h"
+
+void ofApp::setup(){
+ ofBackground(0);
+
+ // Enable or disable audio for video sources globally
+ // Set this to false to save resources on the Raspberry Pi
+ ofx::piMapper::VideoSource::enableAudio = true;
+ ofx::piMapper::VideoSource::useHDMIForAudio = false;
+
+ // Register our sources.
+ // This should be done before mapper.setup().
+ piMapper.registerFboSource(ScanLSource);
+ piMapper.registerFboSource(QuadiSource);
+ piMapper.registerFboSource(CircLSource);
+ piMapper.registerFboSource(BricksSource);
+ //piMapper.registerFboSource(SyphonClient);
+ //piMapper.registerFboSource(slideShowSource);
+ piMapper.setup();
+
+ // This will set the app fullscreen if compiled on Raspberry Pi.
+ #ifdef TARGET_RASPBERRY_PI
+ ofSetFullscreen(true);
+ #endif
+
+ // Start slideshow.
+ //slideShowSource.play();
+}
+
+void ofApp::update(){
+ piMapper.update();
+}
+
+void ofApp::draw(){
+ piMapper.draw();
+}
+
+void ofApp::keyPressed(int key){
+ piMapper.keyPressed(key);
+}
+
+void ofApp::keyReleased(int key){
+ piMapper.keyReleased(key);
+}
+
+void ofApp::mousePressed(int x, int y, int button){
+
+ piMapper.mousePressed(x, y, button);
+}
+
+void ofApp::mouseReleased(int x, int y, int button){
+ piMapper.mouseReleased(x, y, button);
+}
+
+void ofApp::mouseDragged(int x, int y, int button){
+ piMapper.mouseDragged(x, y, button);
+}
diff --git a/example_fbo-sources/src/ofApp.h b/example_fbo-sources/src/ofApp.h
index ff90d55..a5523dd 100644
--- a/example_fbo-sources/src/ofApp.h
+++ b/example_fbo-sources/src/ofApp.h
@@ -1,37 +1,37 @@
-#pragma once
-
-#include "ofMain.h"
-#include "ofxPiMapper.h"
-#include "VideoSource.h"
-#include "ScanlineSource.h"
-#include "CircleSource.h"
-#include "QuadSource.h"
-#include "BrickSource.h"
-//#include "SyphonSource.h"
-#include "magSlideShowSource.h"
-
-class ofApp : public ofBaseApp{
-public:
- void setup();
- void update();
- void draw();
-
- void keyPressed(int key);
- void keyReleased(int key);
-
- void mousePressed(int x, int y, int button);
- void mouseReleased(int x, int y, int button);
- void mouseDragged(int x, int y, int button);
-
- ofxPiMapper piMapper;
-
- // By using a custom source that is derived from FboSource
- // you will be able to see the source listed in sources editor
- ScanlineSource ScanLSource;
- QuadSource QuadiSource;
- CircleSource CircLSource;
- BrickSource BricksSource;
- //SyphonSource SyphonClient;
- magSlideShowSource slideShowSource;
-
-};
+#pragma once
+
+#include "ofMain.h"
+#include "ofxPiMapper.h"
+#include "VideoSource.h"
+#include "ScanlineSource.h"
+#include "CircleSource.h"
+#include "QuadSource.h"
+#include "BrickSource.h"
+//#include "SyphonSource.h"
+#include "magSlideShowSource.h"
+
+class ofApp : public ofBaseApp{
+public:
+ void setup();
+ void update();
+ void draw();
+
+ void keyPressed(int key);
+ void keyReleased(int key);
+
+ void mousePressed(int x, int y, int button);
+ void mouseReleased(int x, int y, int button);
+ void mouseDragged(int x, int y, int button);
+
+ ofxPiMapper piMapper;
+
+ // By using a custom source that is derived from FboSource
+ // you will be able to see the source listed in sources editor
+ ScanlineSource ScanLSource;
+ QuadSource QuadiSource;
+ CircleSource CircLSource;
+ BrickSource BricksSource;
+ //SyphonSource SyphonClient;
+ magSlideShowSource slideShowSource;
+
+};
diff --git a/example_pocketvj/.gitignore b/example_pocketvj/.gitignore
index 4572154..7e10cee 100644
--- a/example_pocketvj/.gitignore
+++ b/example_pocketvj/.gitignore
@@ -1,6 +1,6 @@
-obj
-*.xcworkspace
-*.xcuserdatad
-*~
-config.make
-bin/*.app
+obj
+*.xcworkspace
+*.xcuserdatad
+*~
+config.make
+bin/*.app
diff --git a/example_pocketvj/Makefile b/example_pocketvj/Makefile
index 177e172..7012784 100644
--- a/example_pocketvj/Makefile
+++ b/example_pocketvj/Makefile
@@ -1,13 +1,13 @@
-# Attempt to load a config.make file.
-# If none is found, project defaults in config.project.make will be used.
-ifneq ($(wildcard config.make),)
- include config.make
-endif
-
-# make sure the the OF_ROOT location is defined
-ifndef OF_ROOT
- OF_ROOT=$(realpath ../../..)
-endif
-
-# call the project makefile!
-include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk
+# Attempt to load a config.make file.
+# If none is found, project defaults in config.project.make will be used.
+ifneq ($(wildcard config.make),)
+ include config.make
+endif
+
+# make sure the the OF_ROOT location is defined
+ifndef OF_ROOT
+ OF_ROOT=$(realpath ../../..)
+endif
+
+# call the project makefile!
+include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk
diff --git a/example_pocketvj/addons.make b/example_pocketvj/addons.make
index 963941c..596425d 100644
--- a/example_pocketvj/addons.make
+++ b/example_pocketvj/addons.make
@@ -1,4 +1,4 @@
-ofxGui
-ofxPiMapper
-ofxXmlSettings
-ofxOMXPlayer
+ofxGui
+ofxPiMapper
+ofxXmlSettings
+ofxOMXPlayer
diff --git a/example_pocketvj/addons.make.norpi b/example_pocketvj/addons.make.norpi
index e72d2dd..69d8f94 100644
--- a/example_pocketvj/addons.make.norpi
+++ b/example_pocketvj/addons.make.norpi
@@ -1,3 +1,3 @@
-ofxGui
-ofxPiMapper
-ofxXmlSettings
+ofxGui
+ofxPiMapper
+ofxXmlSettings
diff --git a/example_pocketvj/bin/data/ofxpimapper.xml b/example_pocketvj/bin/data/ofxpimapper.xml
index 961b490..e3ead7a 100644
--- a/example_pocketvj/bin/data/ofxpimapper.xml
+++ b/example_pocketvj/bin/data/ofxpimapper.xml
@@ -1,36 +1,36 @@
-
-
-
-
- 431.000000000
- 13.000000000
-
-
- 781.000000000
- 363.000000000
-
-
- 81.000000000
- 363.000000000
-
-
-
-
- 0.500000000
- 0.000000000
-
-
- 1.000000000
- 1.000000000
-
-
- 0.000000000
- 1.000000000
-
-
-
- image
- image1.jpg
-
-
-
+
+
+
+
+ 431.000000000
+ 13.000000000
+
+
+ 781.000000000
+ 363.000000000
+
+
+ 81.000000000
+ 363.000000000
+
+
+
+
+ 0.500000000
+ 0.000000000
+
+
+ 1.000000000
+ 1.000000000
+
+
+ 0.000000000
+ 1.000000000
+
+
+
+ image
+ image1.jpg
+
+
+
diff --git a/example_pocketvj/src/main.cpp b/example_pocketvj/src/main.cpp
index 17f4ae7..1c5c250 100644
--- a/example_pocketvj/src/main.cpp
+++ b/example_pocketvj/src/main.cpp
@@ -1,9 +1,9 @@
-#include "ofMain.h"
-#include "ofApp.h"
-
-int main(){
- ofGLFWWindowSettings settings;
- settings.windowMode = OF_FULLSCREEN;
- ofCreateWindow(settings);
- ofRunApp(new ofApp);
-}
+#include "ofMain.h"
+#include "ofApp.h"
+
+int main(){
+ ofGLFWWindowSettings settings;
+ settings.windowMode = OF_FULLSCREEN;
+ ofCreateWindow(settings);
+ ofRunApp(new ofApp);
+}
diff --git a/example_pocketvj/src/ofApp.cpp b/example_pocketvj/src/ofApp.cpp
index d9644c8..d703462 100644
--- a/example_pocketvj/src/ofApp.cpp
+++ b/example_pocketvj/src/ofApp.cpp
@@ -1,124 +1,124 @@
-#include "ofApp.h"
-
-void ofApp::setup(){
- ofBackground(0);
- mapper.setup();
-
- // Set different info text for PocketVJ
- std::string multilineInfoText =
- "Custom ofxPiMapper shortcuts\n\n"
- "Good day user.\n"
- "Shortcuts have been customized.\n"
- "Please make sure to provide your own documentation.";
- mapper.setInfoText(multilineInfoText);
-}
-
-void ofApp::update(){
- mapper.update();
-}
-
-void ofApp::draw(){
- mapper.draw();
-}
-
-void ofApp::keyPressed(int key){
- if(key == '1'){
- mapper.setMode(ofx::piMapper::PRESENTATION_MODE);
- }else if(key == '2'){
- mapper.setMode(ofx::piMapper::TEXTURE_MODE);
- }else if(key == '3'){
- mapper.setMode(ofx::piMapper::MAPPING_MODE);
- }else if(key == '4'){
- mapper.setMode(ofx::piMapper::SOURCE_MODE);
- }else if(key == 'c'){
- mapper.toggleInfo();
- }else if(key == 't'){
- mapper.createSurface(ofx::piMapper::TRIANGLE_SURFACE);
- }else if(key == 'q'){
- mapper.createSurface(ofx::piMapper::QUAD_SURFACE);
- }else if(key == 'r'){
- mapper.createSurface(ofx::piMapper::CIRCLE_SURFACE);
- }else if(key == 'x'){
- mapper.createSurface(ofx::piMapper::HEXAGON_SURFACE);
- }else if(key == 'g'){
- mapper.createSurface(ofx::piMapper::GRID_WARP_SURFACE);
- }else if(key == 'a'){
- mapper.duplicateSurface();
- }else if(key == 'o'){
- mapper.scaleUp();
- }else if(key == 'i'){
- mapper.scaleDown();
- }else if(key == 'p'){
- mapper.togglePerspective();
- }else if(key == 'v'){
- mapper.addGridColumn();
- }else if(key == 'b'){
- mapper.removeGridColumn();
- }else if(key == 'n'){
- mapper.addGridRow();
- }else if(key == 'm'){
- mapper.removeGridRow();
- }else if(key == '.'){
- mapper.selectNextSurface();
- }else if(key == ','){
- mapper.selectPrevSurface();
- }else if(key == 'k'){
- mapper.selectNextVertex();
- }else if(key == 'l'){
- mapper.selectPrevVertex();
- }else if(key == 'h'){
- mapper.moveLayerUp();
- }else if(key == 'j'){
- mapper.moveLayerDown();
- }else if(key == 's'){
- mapper.saveProject();
- }else if(key == 'y'){
- mapper.toggleLayerPanel();
- }else if(key == 'z'){
- mapper.undo();
- }else if(key == 'd'){
- mapper.eraseSurface(mapper.getSelectedSurface());
- }else if(key == 'w'){
- mapper.togglePause();
- }else if(key == '5'){
- mapper.setNextSource();
- }else if(key == '8'){
- mapper.moveSelection(ofx::piMapper::Vec3(0.0f, -1.0f, 0.0f));
- }else if(key == '9'){
- mapper.moveSelection(ofx::piMapper::Vec3(0.0f, 1.0f, 0.0f));
- }else if(key == '7'){
- mapper.moveSelection(ofx::piMapper::Vec3(-1.0f, 0.0f, 0.0f));
- }else if(key == '0'){
- mapper.moveSelection(ofx::piMapper::Vec3(1.0f, 0.0f, 0.0f));
- }else if(key == '/'){
- bool shiftIsDown = mapper.toggleShift();
- if(shiftIsDown){
- ofLogNotice("ofApp") << "Shift key is down";
- }else{
- ofLogNotice("ofApp") << "Shift key is up";
- }
- }
-
- /* For these one has to figure out her own ways.
- * rbt Reboot (Raspberry Pi only)
- * sdn Shutdown (Raspberry Pi only)
- * new Clear composition (remove all surfaces)
- * ext Exit application and return to command line
- */
-}
-
-void ofApp::keyReleased(int key){
- mapper.keyReleased(key);
-}
-
-void ofApp::mousePressed(int x, int y, int button){
- mapper.mousePressed(x, y, button);
-}
-
-void ofApp::mouseReleased(int x, int y, int button){
- mapper.mouseReleased(x, y, button);
-}
-
-void ofApp::mouseDragged(int x, int y, int button){
- mapper.mouseDragged(x, y, button);
-}
+#include "ofApp.h"
+
+void ofApp::setup(){
+ ofBackground(0);
+ mapper.setup();
+
+ // Set different info text for PocketVJ
+ std::string multilineInfoText =
+ "Custom ofxPiMapper shortcuts\n\n"
+ "Good day user.\n"
+ "Shortcuts have been customized.\n"
+ "Please make sure to provide your own documentation.";
+ mapper.setInfoText(multilineInfoText);
+}
+
+void ofApp::update(){
+ mapper.update();
+}
+
+void ofApp::draw(){
+ mapper.draw();
+}
+
+void ofApp::keyPressed(int key){
+ if(key == '1'){
+ mapper.setMode(ofx::piMapper::PRESENTATION_MODE);
+ }else if(key == '2'){
+ mapper.setMode(ofx::piMapper::TEXTURE_MODE);
+ }else if(key == '3'){
+ mapper.setMode(ofx::piMapper::MAPPING_MODE);
+ }else if(key == '4'){
+ mapper.setMode(ofx::piMapper::SOURCE_MODE);
+ }else if(key == 'c'){
+ mapper.toggleInfo();
+ }else if(key == 't'){
+ mapper.createSurface(ofx::piMapper::TRIANGLE_SURFACE);
+ }else if(key == 'q'){
+ mapper.createSurface(ofx::piMapper::QUAD_SURFACE);
+ }else if(key == 'r'){
+ mapper.createSurface(ofx::piMapper::CIRCLE_SURFACE);
+ }else if(key == 'x'){
+ mapper.createSurface(ofx::piMapper::HEXAGON_SURFACE);
+ }else if(key == 'g'){
+ mapper.createSurface(ofx::piMapper::GRID_WARP_SURFACE);
+ }else if(key == 'a'){
+ mapper.duplicateSurface();
+ }else if(key == 'o'){
+ mapper.scaleUp();
+ }else if(key == 'i'){
+ mapper.scaleDown();
+ }else if(key == 'p'){
+ mapper.togglePerspective();
+ }else if(key == 'v'){
+ mapper.addGridColumn();
+ }else if(key == 'b'){
+ mapper.removeGridColumn();
+ }else if(key == 'n'){
+ mapper.addGridRow();
+ }else if(key == 'm'){
+ mapper.removeGridRow();
+ }else if(key == '.'){
+ mapper.selectNextSurface();
+ }else if(key == ','){
+ mapper.selectPrevSurface();
+ }else if(key == 'k'){
+ mapper.selectNextVertex();
+ }else if(key == 'l'){
+ mapper.selectPrevVertex();
+ }else if(key == 'h'){
+ mapper.moveLayerUp();
+ }else if(key == 'j'){
+ mapper.moveLayerDown();
+ }else if(key == 's'){
+ mapper.saveProject();
+ }else if(key == 'y'){
+ mapper.toggleLayerPanel();
+ }else if(key == 'z'){
+ mapper.undo();
+ }else if(key == 'd'){
+ mapper.eraseSurface(mapper.getSelectedSurface());
+ }else if(key == 'w'){
+ mapper.togglePause();
+ }else if(key == '5'){
+ mapper.setNextSource();
+ }else if(key == '8'){
+ mapper.moveSelection(ofx::piMapper::Vec3(0.0f, -1.0f, 0.0f));
+ }else if(key == '9'){
+ mapper.moveSelection(ofx::piMapper::Vec3(0.0f, 1.0f, 0.0f));
+ }else if(key == '7'){
+ mapper.moveSelection(ofx::piMapper::Vec3(-1.0f, 0.0f, 0.0f));
+ }else if(key == '0'){
+ mapper.moveSelection(ofx::piMapper::Vec3(1.0f, 0.0f, 0.0f));
+ }else if(key == '/'){
+ bool shiftIsDown = mapper.toggleShift();
+ if(shiftIsDown){
+ ofLogNotice("ofApp") << "Shift key is down";
+ }else{
+ ofLogNotice("ofApp") << "Shift key is up";
+ }
+ }
+
+ /* For these one has to figure out her own ways.
+ * rbt Reboot (Raspberry Pi only)
+ * sdn Shutdown (Raspberry Pi only)
+ * new Clear composition (remove all surfaces)
+ * ext Exit application and return to command line
+ */
+}
+
+void ofApp::keyReleased(int key){
+ mapper.keyReleased(key);
+}
+
+void ofApp::mousePressed(int x, int y, int button){
+ mapper.mousePressed(x, y, button);
+}
+
+void ofApp::mouseReleased(int x, int y, int button){
+ mapper.mouseReleased(x, y, button);
+}
+
+void ofApp::mouseDragged(int x, int y, int button){
+ mapper.mouseDragged(x, y, button);
+}
diff --git a/example_pocketvj/src/ofApp.h b/example_pocketvj/src/ofApp.h
index 63be198..271ec45 100644
--- a/example_pocketvj/src/ofApp.h
+++ b/example_pocketvj/src/ofApp.h
@@ -1,21 +1,21 @@
-#pragma once
-
-#include "ofMain.h"
-#include "ofxPiMapper.h"
-#include "Vec3.h"
-
-class ofApp : public ofBaseApp {
- public:
- void setup();
- void update();
- void draw();
-
- void keyPressed(int key);
- void keyReleased(int key);
-
- void mousePressed(int x, int y, int button);
- void mouseReleased(int x, int y, int button);
- void mouseDragged(int x, int y, int button);
-
- ofxPiMapper mapper;
-};
+#pragma once
+
+#include "ofMain.h"
+#include "ofxPiMapper.h"
+#include "Vec3.h"
+
+class ofApp : public ofBaseApp {
+ public:
+ void setup();
+ void update();
+ void draw();
+
+ void keyPressed(int key);
+ void keyReleased(int key);
+
+ void mousePressed(int x, int y, int button);
+ void mouseReleased(int x, int y, int button);
+ void mouseDragged(int x, int y, int button);
+
+ ofxPiMapper mapper;
+};
diff --git a/example_remote-client/Makefile b/example_remote-client/Makefile
index 8d8e4c0..c83af71 100644
--- a/example_remote-client/Makefile
+++ b/example_remote-client/Makefile
@@ -1,13 +1,13 @@
-# Attempt to load a config.make file.
-# If none is found, project defaults in config.project.make will be used.
-ifneq ($(wildcard config.make),)
- include config.make
-endif
-
-# make sure the the OF_ROOT location is defined
-ifndef OF_ROOT
- OF_ROOT=$(realpath ../../..)
-endif
-
-# call the project makefile!
-include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk
+# Attempt to load a config.make file.
+# If none is found, project defaults in config.project.make will be used.
+ifneq ($(wildcard config.make),)
+ include config.make
+endif
+
+# make sure the the OF_ROOT location is defined
+ifndef OF_ROOT
+ OF_ROOT=$(realpath ../../..)
+endif
+
+# call the project makefile!
+include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk
diff --git a/example_remote-client/README.md b/example_remote-client/README.md
index 9957c03..89b10c4 100644
--- a/example_remote-client/README.md
+++ b/example_remote-client/README.md
@@ -1,22 +1,22 @@
-# Remote Control Client for ofxPiMapper
-
-This example demonstrates a TCP **client** for ofxPiMapper remote control. The other part of this is the [Remote Control Server](../example_remote-server). What it does is the following.
-
-- Reads IP address and port defined in `bin/data/config.json`.
-- Connects to server by using the IP address and port.
-- Once connected, ofxPiMapper configuration is received.
-- Instance of ofxPiMapper class is being set up.
-- TCP messages are sent on every keyboard and mouse event.
-
-In reality this example should be used as the remote control residing on your laptop computa. Set up your Raspberry Pi, connect it to the same network as your laptop and get to know the IP address of the Raspberry Pi. Update `bin/data/config.json` with the IP address of your Raspberry Pi and launch the app!
-
-**Warning!** Sources are not being sent. Click once with the mouse after the application launches to see the borders of the surfaces. There should be a green rectangle visible in the top left corner of the screen if the connection is successfull.
-
-## Dependencies
-
-JSON is used as the data format between ofxPiMapper remote control server and client, therefore additionally [ofxJSON](https://github.com/jeffcrouse/ofxJSON) addon is used. Install it by using the following lines of bash code.
-
-```
-cd openFrameworks/addons
-git clone --depth=1 https://github.com/jeffcrouse/ofxJSON
-```
+# Remote Control Client for ofxPiMapper
+
+This example demonstrates a TCP **client** for ofxPiMapper remote control. The other part of this is the [Remote Control Server](../example_remote-server). What it does is the following.
+
+- Reads IP address and port defined in `bin/data/config.json`.
+- Connects to server by using the IP address and port.
+- Once connected, ofxPiMapper configuration is received.
+- Instance of ofxPiMapper class is being set up.
+- TCP messages are sent on every keyboard and mouse event.
+
+In reality this example should be used as the remote control residing on your laptop computa. Set up your Raspberry Pi, connect it to the same network as your laptop and get to know the IP address of the Raspberry Pi. Update `bin/data/config.json` with the IP address of your Raspberry Pi and launch the app!
+
+**Warning!** Sources are not being sent. Click once with the mouse after the application launches to see the borders of the surfaces. There should be a green rectangle visible in the top left corner of the screen if the connection is successfull.
+
+## Dependencies
+
+JSON is used as the data format between ofxPiMapper remote control server and client, therefore additionally [ofxJSON](https://github.com/jeffcrouse/ofxJSON) addon is used. Install it by using the following lines of bash code.
+
+```
+cd openFrameworks/addons
+git clone --depth=1 https://github.com/jeffcrouse/ofxJSON
+```
diff --git a/example_remote-client/addons.make b/example_remote-client/addons.make
index 4205a02..9819b47 100644
--- a/example_remote-client/addons.make
+++ b/example_remote-client/addons.make
@@ -1,6 +1,6 @@
-ofxGui
-ofxJSON
-ofxNetwork
-ofxPiMapper
-ofxXmlSettings
-ofxOMXPlayer
+ofxGui
+ofxJSON
+ofxNetwork
+ofxPiMapper
+ofxXmlSettings
+ofxOMXPlayer
diff --git a/example_remote-client/addons.make.norpi b/example_remote-client/addons.make.norpi
index cd0471e..35de469 100644
--- a/example_remote-client/addons.make.norpi
+++ b/example_remote-client/addons.make.norpi
@@ -1,5 +1,5 @@
-ofxGui
-ofxJSON
-ofxNetwork
-ofxPiMapper
-ofxXmlSettings
+ofxGui
+ofxJSON
+ofxNetwork
+ofxPiMapper
+ofxXmlSettings
diff --git a/example_remote-client/bin/data/config.json b/example_remote-client/bin/data/config.json
index 1eed9ca..308cf46 100644
--- a/example_remote-client/bin/data/config.json
+++ b/example_remote-client/bin/data/config.json
@@ -1,4 +1,4 @@
-{
- "ip":"127.0.0.1",
- "port":9999
-}
+{
+ "ip":"127.0.0.1",
+ "port":9999
+}
diff --git a/example_remote-client/bin/data/ofxpimapper.xml b/example_remote-client/bin/data/ofxpimapper.xml
index a11fe2e..8cc5e99 100644
--- a/example_remote-client/bin/data/ofxpimapper.xml
+++ b/example_remote-client/bin/data/ofxpimapper.xml
@@ -1,36 +1,36 @@
-
-
-
-
- 640.000000000
- 50.000000000
-
-
- 1230.000000000
- 750.000000000
-
-
- 50.000000000
- 750.000000000
-
-
-
-
- 0.500000000
- 0.000000000
-
-
- 1.000000000
- 1.000000000
-
-
- 0.000000000
- 1.000000000
-
-
-
- video
- gene-nsynthesis-loop-b.mp4
-
-
-
+
+
+
+
+ 640.000000000
+ 50.000000000
+
+
+ 1230.000000000
+ 750.000000000
+
+
+ 50.000000000
+ 750.000000000
+
+
+
+
+ 0.500000000
+ 0.000000000
+
+
+ 1.000000000
+ 1.000000000
+
+
+ 0.000000000
+ 1.000000000
+
+
+
+ video
+ gene-nsynthesis-loop-b.mp4
+
+
+
diff --git a/example_remote-client/src/TCPClient.cpp b/example_remote-client/src/TCPClient.cpp
index cdc4dfe..649e19d 100644
--- a/example_remote-client/src/TCPClient.cpp
+++ b/example_remote-client/src/TCPClient.cpp
@@ -1,49 +1,49 @@
-#include "TCPClient.h"
-
-shared_ptr TCPClient::_instance = 0;
-
-shared_ptr TCPClient::instance(){
- if(_instance == 0){
- _instance = shared_ptr(new TCPClient);
- }
- return _instance;
-}
-
-TCPClient::TCPClient(){
-
-}
-
-void TCPClient::setup(string ip, int port){
- _tcpClient.setup(ip, port);
-}
-
-void TCPClient::update(){
- if(_tcpClient.isConnected()){
- string rx = _tcpClient.receive();
- if(rx.length() > 0){
- ofxJSONElement json;
- json["event"] = "received";
- json["data"] = rx;
-
- ofMessage m(json.getRawString());
- ofSendMessage(m);
- }
- }
-}
-
-void TCPClient::draw(){
- if(_tcpClient.isConnected()){
- ofSetColor(0, 255, 0);
- }else{
- ofSetColor(255, 0, 0);
- }
-
- ofPushMatrix();
- ofTranslate(10, 10);
- ofDrawRectangle(0, 0, 10, 10);
- ofPopMatrix();
-}
-
-void TCPClient::send(string message){
- _tcpClient.send(message);
-}
+#include "TCPClient.h"
+
+shared_ptr TCPClient::_instance = 0;
+
+shared_ptr TCPClient::instance(){
+ if(_instance == 0){
+ _instance = shared_ptr(new TCPClient);
+ }
+ return _instance;
+}
+
+TCPClient::TCPClient(){
+
+}
+
+void TCPClient::setup(string ip, int port){
+ _tcpClient.setup(ip, port);
+}
+
+void TCPClient::update(){
+ if(_tcpClient.isConnected()){
+ string rx = _tcpClient.receive();
+ if(rx.length() > 0){
+ ofxJSONElement json;
+ json["event"] = "received";
+ json["data"] = rx;
+
+ ofMessage m(json.getRawString());
+ ofSendMessage(m);
+ }
+ }
+}
+
+void TCPClient::draw(){
+ if(_tcpClient.isConnected()){
+ ofSetColor(0, 255, 0);
+ }else{
+ ofSetColor(255, 0, 0);
+ }
+
+ ofPushMatrix();
+ ofTranslate(10, 10);
+ ofDrawRectangle(0, 0, 10, 10);
+ ofPopMatrix();
+}
+
+void TCPClient::send(string message){
+ _tcpClient.send(message);
+}
diff --git a/example_remote-client/src/TCPClient.h b/example_remote-client/src/TCPClient.h
index 5d3f655..598f5d9 100644
--- a/example_remote-client/src/TCPClient.h
+++ b/example_remote-client/src/TCPClient.h
@@ -1,22 +1,22 @@
-#pragma once
-
-#include "ofMain.h"
-#include "ofxNetwork.h"
-#include "ofxJSONElement.h"
-
-class TCPClient{
-public:
- static shared_ptr instance();
-
- void setup(string ip, int port);
- void update();
- void draw();
-
- void send(string message);
-
-private:
- TCPClient();
- static shared_ptr _instance;
-
- ofxTCPClient _tcpClient;
-};
+#pragma once
+
+#include "ofMain.h"
+#include "ofxNetwork.h"
+#include "ofxJSONElement.h"
+
+class TCPClient{
+public:
+ static shared_ptr instance();
+
+ void setup(string ip, int port);
+ void update();
+ void draw();
+
+ void send(string message);
+
+private:
+ TCPClient();
+ static shared_ptr _instance;
+
+ ofxTCPClient _tcpClient;
+};
diff --git a/example_remote-client/src/main.cpp b/example_remote-client/src/main.cpp
index c696d20..527f84b 100644
--- a/example_remote-client/src/main.cpp
+++ b/example_remote-client/src/main.cpp
@@ -1,7 +1,7 @@
-#include "ofMain.h"
-#include "ofApp.h"
-
-int main(){
- ofSetupOpenGL(1280, 800, OF_WINDOW);
- ofRunApp(new ofApp());
-}
+#include "ofMain.h"
+#include "ofApp.h"
+
+int main(){
+ ofSetupOpenGL(1280, 800, OF_WINDOW);
+ ofRunApp(new ofApp());
+}
diff --git a/example_remote-client/src/ofApp.cpp b/example_remote-client/src/ofApp.cpp
index b12b1cc..2cec1a3 100644
--- a/example_remote-client/src/ofApp.cpp
+++ b/example_remote-client/src/ofApp.cpp
@@ -1,109 +1,109 @@
-#include "ofApp.h"
-
-void ofApp::setup(){
- ofBackground(0);
-
- isMapperSetup = false;
-
- // Set IP address of your RasPi in data/config.json
- ofxJSONElement json;
- json.open("config.json");
- TCPClient::instance()->setup(json["ip"].asString(), json["port"].asInt());
-}
-
-void ofApp::update(){
- TCPClient::instance()->update();
- if(isMapperSetup){
- mapper.update();
- }
-}
-
-void ofApp::draw(){
- TCPClient::instance()->draw();
- if(isMapperSetup){
- mapper.draw();
- }
-}
-
-// This is where we get configuration from the server part of this.
-void ofApp::gotMessage(ofMessage m){
- ofxJSONElement json;
- bool ok = json.parse(m.message);
- if(ok){
- if(json["event"] == "received"){
- std::string buffer = json["data"].asString();
- ofxXmlSettings xml;
- xml.loadFromBuffer(buffer);
- xml.save("ofxpimapper.xml");
-
- mapper.setup();
- isMapperSetup = true;
- }
- }
-}
-
-void ofApp::keyPressed(int key){
- if(isMapperSetup){
- mapper.keyPressed(key);
-
- ofxJSONElement json;
- json["event"] = "keyPressed";
- json["key"] = key;
-
- TCPClient::instance()->send(json.getRawString());
- }
-}
-
-void ofApp::keyReleased(int key){
- if(isMapperSetup){
- mapper.keyReleased(key);
-
- ofxJSONElement json;
- json["event"] = "keyReleased";
- json["key"] = key;
-
- TCPClient::instance()->send(json.getRawString());
- }
-}
-
-void ofApp::mousePressed(int x, int y, int button){
- if(isMapperSetup){
- mapper.mousePressed(x, y, button);
-
- ofxJSONElement json;
- json["event"] = "mousePressed";
- json["x"] = x;
- json["y"] = y;
- json["button"] = button;
-
- TCPClient::instance()->send(json.getRawString());
- }
-}
-
-void ofApp::mouseReleased(int x, int y, int button){
- if(isMapperSetup){
- mapper.mouseReleased(x, y, button);
-
- ofxJSONElement json;
- json["event"] = "mouseReleased";
- json["x"] = x;
- json["y"] = y;
- json["button"] = button;
-
- TCPClient::instance()->send(json.getRawString());
- }
-}
-
-void ofApp::mouseDragged(int x, int y, int button){
- if(isMapperSetup){
- mapper.mouseDragged(x, y, button);
-
- ofxJSONElement json;
- json["event"] = "mouseDragged";
- json["x"] = x;
- json["y"] = y;
- json["button"] = button;
-
- TCPClient::instance()->send(json.getRawString());
- }
-}
+#include "ofApp.h"
+
+void ofApp::setup(){
+ ofBackground(0);
+
+ isMapperSetup = false;
+
+ // Set IP address of your RasPi in data/config.json
+ ofxJSONElement json;
+ json.open("config.json");
+ TCPClient::instance()->setup(json["ip"].asString(), json["port"].asInt());
+}
+
+void ofApp::update(){
+ TCPClient::instance()->update();
+ if(isMapperSetup){
+ mapper.update();
+ }
+}
+
+void ofApp::draw(){
+ TCPClient::instance()->draw();
+ if(isMapperSetup){
+ mapper.draw();
+ }
+}
+
+// This is where we get configuration from the server part of this.
+void ofApp::gotMessage(ofMessage m){
+ ofxJSONElement json;
+ bool ok = json.parse(m.message);
+ if(ok){
+ if(json["event"] == "received"){
+ std::string buffer = json["data"].asString();
+ ofxXmlSettings xml;
+ xml.loadFromBuffer(buffer);
+ xml.save("ofxpimapper.xml");
+
+ mapper.setup();
+ isMapperSetup = true;
+ }
+ }
+}
+
+void ofApp::keyPressed(int key){
+ if(isMapperSetup){
+ mapper.keyPressed(key);
+
+ ofxJSONElement json;
+ json["event"] = "keyPressed";
+ json["key"] = key;
+
+ TCPClient::instance()->send(json.getRawString());
+ }
+}
+
+void ofApp::keyReleased(int key){
+ if(isMapperSetup){
+ mapper.keyReleased(key);
+
+ ofxJSONElement json;
+ json["event"] = "keyReleased";
+ json["key"] = key;
+
+ TCPClient::instance()->send(json.getRawString());
+ }
+}
+
+void ofApp::mousePressed(int x, int y, int button){
+ if(isMapperSetup){
+ mapper.mousePressed(x, y, button);
+
+ ofxJSONElement json;
+ json["event"] = "mousePressed";
+ json["x"] = x;
+ json["y"] = y;
+ json["button"] = button;
+
+ TCPClient::instance()->send(json.getRawString());
+ }
+}
+
+void ofApp::mouseReleased(int x, int y, int button){
+ if(isMapperSetup){
+ mapper.mouseReleased(x, y, button);
+
+ ofxJSONElement json;
+ json["event"] = "mouseReleased";
+ json["x"] = x;
+ json["y"] = y;
+ json["button"] = button;
+
+ TCPClient::instance()->send(json.getRawString());
+ }
+}
+
+void ofApp::mouseDragged(int x, int y, int button){
+ if(isMapperSetup){
+ mapper.mouseDragged(x, y, button);
+
+ ofxJSONElement json;
+ json["event"] = "mouseDragged";
+ json["x"] = x;
+ json["y"] = y;
+ json["button"] = button;
+
+ TCPClient::instance()->send(json.getRawString());
+ }
+}
diff --git a/example_remote-client/src/ofApp.h b/example_remote-client/src/ofApp.h
index df387f4..bfc5889 100644
--- a/example_remote-client/src/ofApp.h
+++ b/example_remote-client/src/ofApp.h
@@ -1,25 +1,25 @@
-#pragma once
-
-#include "ofMain.h"
-#include "TCPClient.h"
-#include "ofxPiMapper.h"
-#include "ofxJSONElement.h"
-
-class ofApp : public ofBaseApp{
-public:
- void setup();
- void update();
- void draw();
-
- void gotMessage(ofMessage m);
-
- void keyPressed(int key);
- void keyReleased(int key);
-
- void mousePressed(int x, int y, int button);
- void mouseReleased(int x, int y, int button);
- void mouseDragged(int x, int y, int button);
-
- ofxPiMapper mapper;
- bool isMapperSetup;
-};
+#pragma once
+
+#include "ofMain.h"
+#include "TCPClient.h"
+#include "ofxPiMapper.h"
+#include "ofxJSONElement.h"
+
+class ofApp : public ofBaseApp{
+public:
+ void setup();
+ void update();
+ void draw();
+
+ void gotMessage(ofMessage m);
+
+ void keyPressed(int key);
+ void keyReleased(int key);
+
+ void mousePressed(int x, int y, int button);
+ void mouseReleased(int x, int y, int button);
+ void mouseDragged(int x, int y, int button);
+
+ ofxPiMapper mapper;
+ bool isMapperSetup;
+};
diff --git a/example_remote-server/Makefile b/example_remote-server/Makefile
index 8d8e4c0..c83af71 100644
--- a/example_remote-server/Makefile
+++ b/example_remote-server/Makefile
@@ -1,13 +1,13 @@
-# Attempt to load a config.make file.
-# If none is found, project defaults in config.project.make will be used.
-ifneq ($(wildcard config.make),)
- include config.make
-endif
-
-# make sure the the OF_ROOT location is defined
-ifndef OF_ROOT
- OF_ROOT=$(realpath ../../..)
-endif
-
-# call the project makefile!
-include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk
+# Attempt to load a config.make file.
+# If none is found, project defaults in config.project.make will be used.
+ifneq ($(wildcard config.make),)
+ include config.make
+endif
+
+# make sure the the OF_ROOT location is defined
+ifndef OF_ROOT
+ OF_ROOT=$(realpath ../../..)
+endif
+
+# call the project makefile!
+include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk
diff --git a/example_remote-server/README.md b/example_remote-server/README.md
index 2db8db4..0e7285d 100644
--- a/example_remote-server/README.md
+++ b/example_remote-server/README.md
@@ -1,25 +1,25 @@
-# Remote Control Server for ofxPiMapper
-
-This example demonstrates a TCP server for ofxPiMapper remote control. The other part of this is the [Remote Control Client](../example_remote-client). What it does is the following.
-
-- It creates a `TCPServer` singleton.
-- Waits for a client to connect via TCP.
-- Sends ofxPiMapper configuration once client is connected.
-- Accepts keyboard and mouse events from client after.
-- Forwards events to ofxPiMapper instance.
-
-In a real-world scenario, the server should reside on the Raspberry Pi side of your installation. The Raspberry Pi should be connected to wired or wireless network. An IP address should be set.
-
-The client should know the following.
-
-- The **IP address** of the Raspberry Pi with the server.
-- The port, which is **9999** in this case.
-
-## Dependencies
-
-JSON is used as the data format between ofxPiMapper remote control server and client, therefore additionally [ofxJSON](https://github.com/jeffcrouse/ofxJSON) addon is used. Install it by using the following lines of bash code.
-
-```
-cd openFrameworks/addons
-git clone --depth=1 https://github.com/jeffcrouse/ofxJSON
-```
+# Remote Control Server for ofxPiMapper
+
+This example demonstrates a TCP server for ofxPiMapper remote control. The other part of this is the [Remote Control Client](../example_remote-client). What it does is the following.
+
+- It creates a `TCPServer` singleton.
+- Waits for a client to connect via TCP.
+- Sends ofxPiMapper configuration once client is connected.
+- Accepts keyboard and mouse events from client after.
+- Forwards events to ofxPiMapper instance.
+
+In a real-world scenario, the server should reside on the Raspberry Pi side of your installation. The Raspberry Pi should be connected to wired or wireless network. An IP address should be set.
+
+The client should know the following.
+
+- The **IP address** of the Raspberry Pi with the server.
+- The port, which is **9999** in this case.
+
+## Dependencies
+
+JSON is used as the data format between ofxPiMapper remote control server and client, therefore additionally [ofxJSON](https://github.com/jeffcrouse/ofxJSON) addon is used. Install it by using the following lines of bash code.
+
+```
+cd openFrameworks/addons
+git clone --depth=1 https://github.com/jeffcrouse/ofxJSON
+```
diff --git a/example_remote-server/addons.make b/example_remote-server/addons.make
index 4205a02..9819b47 100644
--- a/example_remote-server/addons.make
+++ b/example_remote-server/addons.make
@@ -1,6 +1,6 @@
-ofxGui
-ofxJSON
-ofxNetwork
-ofxPiMapper
-ofxXmlSettings
-ofxOMXPlayer
+ofxGui
+ofxJSON
+ofxNetwork
+ofxPiMapper
+ofxXmlSettings
+ofxOMXPlayer
diff --git a/example_remote-server/addons.make.norpi b/example_remote-server/addons.make.norpi
index cd0471e..35de469 100644
--- a/example_remote-server/addons.make.norpi
+++ b/example_remote-server/addons.make.norpi
@@ -1,5 +1,5 @@
-ofxGui
-ofxJSON
-ofxNetwork
-ofxPiMapper
-ofxXmlSettings
+ofxGui
+ofxJSON
+ofxNetwork
+ofxPiMapper
+ofxXmlSettings
diff --git a/example_remote-server/bin/data/ofxpimapper.xml b/example_remote-server/bin/data/ofxpimapper.xml
index 54f551c..340d7df 100644
--- a/example_remote-server/bin/data/ofxpimapper.xml
+++ b/example_remote-server/bin/data/ofxpimapper.xml
@@ -1,36 +1,36 @@
-
-
-
-
- 640.000000000
- 50.000000000
-
-
- 1230.000000000
- 750.000000000
-
-
- 50.000000000
- 750.000000000
-
-
-
-
- 0.500000000
- 0.000000000
-
-
- 1.000000000
- 1.000000000
-
-
- 0.000000000
- 1.000000000
-
-
-
- image
- gene-nsynthesis.jpg
-
-
-
+
+
+
+
+ 640.000000000
+ 50.000000000
+
+
+ 1230.000000000
+ 750.000000000
+
+
+ 50.000000000
+ 750.000000000
+
+
+
+
+ 0.500000000
+ 0.000000000
+
+
+ 1.000000000
+ 1.000000000
+
+
+ 0.000000000
+ 1.000000000
+
+
+
+ image
+ gene-nsynthesis.jpg
+
+
+
diff --git a/example_remote-server/src/TCPServer.cpp b/example_remote-server/src/TCPServer.cpp
index 2bfa21a..7487f08 100644
--- a/example_remote-server/src/TCPServer.cpp
+++ b/example_remote-server/src/TCPServer.cpp
@@ -1,95 +1,95 @@
-#include "TCPServer.h"
-
-shared_ptr TCPServer::_instance = 0;
-
-shared_ptr TCPServer::instance(){
- if(_instance == 0){
- _instance = shared_ptr(new TCPServer);
- }
- return _instance;
-}
-
-TCPServer::TCPServer(){
- std::cout << "TCPServer initialized" << std::endl;
-}
-
-void TCPServer::setup(int port){
- _tcpServer.setup(port);
-}
-
-void TCPServer::update(){
- int numClients = _tcpServer.getLastID();
- for(auto i = 0; i < numClients; ++i){
- if(_tcpServer.isClientConnected(i)){
-
- // Notify application when new client connects
- if(!_tcpConnections[i]){
- ofxJSONElement json;
- json["ip"] = _tcpServer.getClientIP(i);
- json["port"] = _tcpServer.getClientPort(i);
- json["id"] = i;
- json["event"] = "connected";
-
- ofMessage message(json.getRawString());
- ofSendMessage(message);
-
- _tcpConnections[i] = true;
- }
-
- // Receive messages
- string rx = _tcpServer.receive(i);
- if(rx.length() > 0){
- ofxJSONElement json;
- bool ok = json.parse(rx);
-
- if(!ok){
- json["ip"] = _tcpServer.getClientIP(i);
- json["port"] = _tcpServer.getClientPort(i);
- json["id"] = i;
- json["event"] = "received";
- json["data"] = rx;
- }
-
- ofMessage message(json.getRawString());
- ofSendMessage(message);
- }
- }else{
-
- // Notify application when client disconnects
- if(_tcpConnections[i]){
- ofxJSONElement json;
- json["ip"] = _tcpServer.getClientIP(i);
- json["port"] = _tcpServer.getClientPort(i);
- json["id"] = i;
- json["event"] = "disconnected";
-
- ofMessage message(json.getRawString());
- ofSendMessage(message);
-
- _tcpConnections[i] = false;
- }
- }
- }
-}
-
-void TCPServer::draw(){
- int numClients = _tcpServer.getLastID();
- int clientsConnected = 0;
- for(auto i = 0; i < numClients; ++i){
- if(_tcpServer.isClientConnected(i)){
- ofPushMatrix();
- ofTranslate(10, 10);
- ofPushStyle();
- ofSetColor(0, 255, 0);
- ofDrawRectangle(clientsConnected * 20, 0, 10, 10);
- ofPopStyle();
- ofPopMatrix();
- clientsConnected++;
- }
- }
-}
-
-void TCPServer::send(int clientID, std::string message){
- _tcpServer.send(clientID, message);
-}
-
+#include "TCPServer.h"
+
+shared_ptr TCPServer::_instance = 0;
+
+shared_ptr TCPServer::instance(){
+ if(_instance == 0){
+ _instance = shared_ptr(new TCPServer);
+ }
+ return _instance;
+}
+
+TCPServer::TCPServer(){
+ std::cout << "TCPServer initialized" << std::endl;
+}
+
+void TCPServer::setup(int port){
+ _tcpServer.setup(port);
+}
+
+void TCPServer::update(){
+ int numClients = _tcpServer.getLastID();
+ for(auto i = 0; i < numClients; ++i){
+ if(_tcpServer.isClientConnected(i)){
+
+ // Notify application when new client connects
+ if(!_tcpConnections[i]){
+ ofxJSONElement json;
+ json["ip"] = _tcpServer.getClientIP(i);
+ json["port"] = _tcpServer.getClientPort(i);
+ json["id"] = i;
+ json["event"] = "connected";
+
+ ofMessage message(json.getRawString());
+ ofSendMessage(message);
+
+ _tcpConnections[i] = true;
+ }
+
+ // Receive messages
+ string rx = _tcpServer.receive(i);
+ if(rx.length() > 0){
+ ofxJSONElement json;
+ bool ok = json.parse(rx);
+
+ if(!ok){
+ json["ip"] = _tcpServer.getClientIP(i);
+ json["port"] = _tcpServer.getClientPort(i);
+ json["id"] = i;
+ json["event"] = "received";
+ json["data"] = rx;
+ }
+
+ ofMessage message(json.getRawString());
+ ofSendMessage(message);
+ }
+ }else{
+
+ // Notify application when client disconnects
+ if(_tcpConnections[i]){
+ ofxJSONElement json;
+ json["ip"] = _tcpServer.getClientIP(i);
+ json["port"] = _tcpServer.getClientPort(i);
+ json["id"] = i;
+ json["event"] = "disconnected";
+
+ ofMessage message(json.getRawString());
+ ofSendMessage(message);
+
+ _tcpConnections[i] = false;
+ }
+ }
+ }
+}
+
+void TCPServer::draw(){
+ int numClients = _tcpServer.getLastID();
+ int clientsConnected = 0;
+ for(auto i = 0; i < numClients; ++i){
+ if(_tcpServer.isClientConnected(i)){
+ ofPushMatrix();
+ ofTranslate(10, 10);
+ ofPushStyle();
+ ofSetColor(0, 255, 0);
+ ofDrawRectangle(clientsConnected * 20, 0, 10, 10);
+ ofPopStyle();
+ ofPopMatrix();
+ clientsConnected++;
+ }
+ }
+}
+
+void TCPServer::send(int clientID, std::string message){
+ _tcpServer.send(clientID, message);
+}
+
diff --git a/example_remote-server/src/TCPServer.h b/example_remote-server/src/TCPServer.h
index a6be1c2..837720d 100644
--- a/example_remote-server/src/TCPServer.h
+++ b/example_remote-server/src/TCPServer.h
@@ -1,23 +1,23 @@
-#pragma once
-
-#include "ofMain.h"
-#include "ofxNetwork.h"
-#include "ofxJSONElement.h"
-
-class TCPServer {
-public:
- static shared_ptr instance();
-
- void setup(int port);
- void update();
- void draw();
-
- void send(int clientID, std::string message);
-
-private:
- TCPServer();
- static shared_ptr _instance;
-
- ofxTCPServer _tcpServer;
- std::map _tcpConnections;
-};
+#pragma once
+
+#include "ofMain.h"
+#include "ofxNetwork.h"
+#include "ofxJSONElement.h"
+
+class TCPServer {
+public:
+ static shared_ptr instance();
+
+ void setup(int port);
+ void update();
+ void draw();
+
+ void send(int clientID, std::string message);
+
+private:
+ TCPServer();
+ static shared_ptr _instance;
+
+ ofxTCPServer _tcpServer;
+ std::map _tcpConnections;
+};
diff --git a/example_remote-server/src/main.cpp b/example_remote-server/src/main.cpp
index c696d20..527f84b 100644
--- a/example_remote-server/src/main.cpp
+++ b/example_remote-server/src/main.cpp
@@ -1,7 +1,7 @@
-#include "ofMain.h"
-#include "ofApp.h"
-
-int main(){
- ofSetupOpenGL(1280, 800, OF_WINDOW);
- ofRunApp(new ofApp());
-}
+#include "ofMain.h"
+#include "ofApp.h"
+
+int main(){
+ ofSetupOpenGL(1280, 800, OF_WINDOW);
+ ofRunApp(new ofApp());
+}
diff --git a/example_remote-server/src/ofApp.cpp b/example_remote-server/src/ofApp.cpp
index 7532328..8c62ad9 100644
--- a/example_remote-server/src/ofApp.cpp
+++ b/example_remote-server/src/ofApp.cpp
@@ -1,84 +1,84 @@
-#include "ofApp.h"
-
-void ofApp::setup(){
- ofBackground(0);
- mapper.setup();
- TCPServer::instance()->setup(9999);
-
-#ifdef TARGET_RASPBERRY_PI
- ofSetFullscreen(true);
-#endif
-}
-
-void ofApp::update(){
- mapper.update();
- TCPServer::instance()->update();
-}
-
-void ofApp::draw(){
- mapper.draw();
- TCPServer::instance()->draw();
-}
-
-// Here is where we process messages received from TCPServer instance
-void ofApp::gotMessage(ofMessage m){
- std::cout << m.message << std::endl;
-
- ofxJSONElement json;
- bool ok = json.parse(m.message);
- if(ok){
- if(json["event"].asString() == "connected"){
- // Save Mapper composition and get config as string
- std::cout << "Sending mapper config" << std::endl;
- mapper.saveProject();
-
- ofFile file;
- file.open(ofToDataPath("ofxpimapper.xml"), ofFile::ReadOnly, false);
- ofBuffer buff = file.readToBuffer();
- string text = buff.getText();
-
- TCPServer::instance()->send(json["id"].asInt(), text);
- }
-
- if(json["event"].asString() == "keyPressed"){
- mapper.keyPressed(json["key"].asInt());
- }
-
- if(json["event"].asString() == "keyReleased"){
- mapper.keyReleased(json["key"].asInt());
- }
-
- if(json["event"].asString() == "mousePressed"){
- mapper.mousePressed(json["x"].asInt(), json["y"].asInt(), json["button"].asInt());
- }
-
- if(json["event"].asString() == "mouseReleased"){
- mapper.mouseReleased(json["x"].asInt(), json["y"].asInt(), json["button"].asInt());
- }
-
- if(json["event"].asString() == "mouseDragged"){
- mapper.mouseDragged(json["x"].asInt(), json["y"].asInt(), json["button"].asInt());
- }
- }
-}
-
-void ofApp::keyPressed(int key){
- mapper.keyPressed(key);
-}
-
-void ofApp::keyReleased(int key){
- mapper.keyReleased(key);
-}
-
-void ofApp::mousePressed(int x, int y, int button){
- mapper.mousePressed(x, y, button);
-}
-
-void ofApp::mouseReleased(int x, int y, int button){
- mapper.mouseReleased(x, y, button);
-}
-
-void ofApp::mouseDragged(int x, int y, int button){
- mapper.mouseDragged(x, y, button);
-}
-
+#include "ofApp.h"
+
+void ofApp::setup(){
+ ofBackground(0);
+ mapper.setup();
+ TCPServer::instance()->setup(9999);
+
+#ifdef TARGET_RASPBERRY_PI
+ ofSetFullscreen(true);
+#endif
+}
+
+void ofApp::update(){
+ mapper.update();
+ TCPServer::instance()->update();
+}
+
+void ofApp::draw(){
+ mapper.draw();
+ TCPServer::instance()->draw();
+}
+
+// Here is where we process messages received from TCPServer instance
+void ofApp::gotMessage(ofMessage m){
+ std::cout << m.message << std::endl;
+
+ ofxJSONElement json;
+ bool ok = json.parse(m.message);
+ if(ok){
+ if(json["event"].asString() == "connected"){
+ // Save Mapper composition and get config as string
+ std::cout << "Sending mapper config" << std::endl;
+ mapper.saveProject();
+
+ ofFile file;
+ file.open(ofToDataPath("ofxpimapper.xml"), ofFile::ReadOnly, false);
+ ofBuffer buff = file.readToBuffer();
+ string text = buff.getText();
+
+ TCPServer::instance()->send(json["id"].asInt(), text);
+ }
+
+ if(json["event"].asString() == "keyPressed"){
+ mapper.keyPressed(json["key"].asInt());
+ }
+
+ if(json["event"].asString() == "keyReleased"){
+ mapper.keyReleased(json["key"].asInt());
+ }
+
+ if(json["event"].asString() == "mousePressed"){
+ mapper.mousePressed(json["x"].asInt(), json["y"].asInt(), json["button"].asInt());
+ }
+
+ if(json["event"].asString() == "mouseReleased"){
+ mapper.mouseReleased(json["x"].asInt(), json["y"].asInt(), json["button"].asInt());
+ }
+
+ if(json["event"].asString() == "mouseDragged"){
+ mapper.mouseDragged(json["x"].asInt(), json["y"].asInt(), json["button"].asInt());
+ }
+ }
+}
+
+void ofApp::keyPressed(int key){
+ mapper.keyPressed(key);
+}
+
+void ofApp::keyReleased(int key){
+ mapper.keyReleased(key);
+}
+
+void ofApp::mousePressed(int x, int y, int button){
+ mapper.mousePressed(x, y, button);
+}
+
+void ofApp::mouseReleased(int x, int y, int button){
+ mapper.mouseReleased(x, y, button);
+}
+
+void ofApp::mouseDragged(int x, int y, int button){
+ mapper.mouseDragged(x, y, button);
+}
+
diff --git a/example_remote-server/src/ofApp.h b/example_remote-server/src/ofApp.h
index 6c95a21..9abbc0d 100644
--- a/example_remote-server/src/ofApp.h
+++ b/example_remote-server/src/ofApp.h
@@ -1,23 +1,23 @@
-#pragma once
-
-#include "ofMain.h"
-#include "TCPServer.h"
-#include "ofxPiMapper.h"
-#include "ofxJSONElement.h"
-
-class ofApp : public ofBaseApp{
-public:
- void setup();
- void update();
- void draw();
-
- void gotMessage(ofMessage m);
-
- void keyPressed(int key);
- void keyReleased(int key);
- void mousePressed(int x, int y, int button);
- void mouseReleased(int x, int y, int button);
- void mouseDragged(int x, int y, int button);
-
- ofxPiMapper mapper;
-};
+#pragma once
+
+#include "ofMain.h"
+#include "TCPServer.h"
+#include "ofxPiMapper.h"
+#include "ofxJSONElement.h"
+
+class ofApp : public ofBaseApp{
+public:
+ void setup();
+ void update();
+ void draw();
+
+ void gotMessage(ofMessage m);
+
+ void keyPressed(int key);
+ void keyReleased(int key);
+ void mousePressed(int x, int y, int button);
+ void mouseReleased(int x, int y, int button);
+ void mouseDragged(int x, int y, int button);
+
+ ofxPiMapper mapper;
+};
diff --git a/example_simpler/.gitignore b/example_simpler/.gitignore
index e4d4b5d..ad71cfd 100644
--- a/example_simpler/.gitignore
+++ b/example_simpler/.gitignore
@@ -1,5 +1,5 @@
-obj
-*.xcworkspace
-*.xcuserdatad
-*~
-config.make
+obj
+*.xcworkspace
+*.xcuserdatad
+*~
+config.make
diff --git a/example_simpler/Makefile b/example_simpler/Makefile
index 8d8e4c0..c83af71 100644
--- a/example_simpler/Makefile
+++ b/example_simpler/Makefile
@@ -1,13 +1,13 @@
-# Attempt to load a config.make file.
-# If none is found, project defaults in config.project.make will be used.
-ifneq ($(wildcard config.make),)
- include config.make
-endif
-
-# make sure the the OF_ROOT location is defined
-ifndef OF_ROOT
- OF_ROOT=$(realpath ../../..)
-endif
-
-# call the project makefile!
-include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk
+# Attempt to load a config.make file.
+# If none is found, project defaults in config.project.make will be used.
+ifneq ($(wildcard config.make),)
+ include config.make
+endif
+
+# make sure the the OF_ROOT location is defined
+ifndef OF_ROOT
+ OF_ROOT=$(realpath ../../..)
+endif
+
+# call the project makefile!
+include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk
diff --git a/example_simpler/addons.make b/example_simpler/addons.make
index 963941c..596425d 100644
--- a/example_simpler/addons.make
+++ b/example_simpler/addons.make
@@ -1,4 +1,4 @@
-ofxGui
-ofxPiMapper
-ofxXmlSettings
-ofxOMXPlayer
+ofxGui
+ofxPiMapper
+ofxXmlSettings
+ofxOMXPlayer
diff --git a/example_simpler/addons.make.norpi b/example_simpler/addons.make.norpi
index e72d2dd..69d8f94 100644
--- a/example_simpler/addons.make.norpi
+++ b/example_simpler/addons.make.norpi
@@ -1,3 +1,3 @@
-ofxGui
-ofxPiMapper
-ofxXmlSettings
+ofxGui
+ofxPiMapper
+ofxXmlSettings
diff --git a/example_simpler/bin/data/ofxpimapper.xml b/example_simpler/bin/data/ofxpimapper.xml
index 1c44003..c75d65b 100644
--- a/example_simpler/bin/data/ofxpimapper.xml
+++ b/example_simpler/bin/data/ofxpimapper.xml
@@ -1,81 +1,81 @@
-
-
-
-
- 193.000000000
- 58.187255859
-
-
- 466.000000000
- 413.000000000
-
-
- 39.374511719
- 211.812774658
-
-
-
-
- -0.006000000
- -0.014000000
-
-
- 1.000000000
- 1.000000000
-
-
- 0.000000000
- 1.000000000
-
-
-
- image
- image4.jpg
-
-
-
-
-
- 758.067382812
- 360.033691406
-
-
- 1125.932617188
- 360.033691406
-
-
- 1129.000000000
- 719.000000000
-
-
- 759.000000000
- 721.000000000
-
-
-
-
- 0.000000000
- 0.000000000
-
-
- 1.000000000
- 0.000000000
-
-
- 1.000000000
- 1.000000000
-
-
- 0.000000000
- 1.000000000
-
-
-
- fbo
- Custom FBO Source
-
-
- 1
-
-
-
+
+
+
+
+ 193.000000000
+ 58.187255859
+
+
+ 466.000000000
+ 413.000000000
+
+
+ 39.374511719
+ 211.812774658
+
+
+
+
+ -0.006000000
+ -0.014000000
+
+
+ 1.000000000
+ 1.000000000
+
+
+ 0.000000000
+ 1.000000000
+
+
+
+ image
+ image4.jpg
+
+
+
+
+
+ 758.067382812
+ 360.033691406
+
+
+ 1125.932617188
+ 360.033691406
+
+
+ 1129.000000000
+ 719.000000000
+
+
+ 759.000000000
+ 721.000000000
+
+
+
+
+ 0.000000000
+ 0.000000000
+
+
+ 1.000000000
+ 0.000000000
+
+
+ 1.000000000
+ 1.000000000
+
+
+ 0.000000000
+ 1.000000000
+
+
+
+ fbo
+ Custom FBO Source
+
+
+ 1
+
+
+
diff --git a/example_simpler/src/CustomSource.cpp b/example_simpler/src/CustomSource.cpp
index f5eb1d0..4840bbc 100644
--- a/example_simpler/src/CustomSource.cpp
+++ b/example_simpler/src/CustomSource.cpp
@@ -1,41 +1,41 @@
-#include "CustomSource.h"
-
-void CustomSource::setup(){
- // Give our source a decent name
- name = "Custom FBO Source";
-
- // Allocate our FBO source, decide how big it should be
- allocate(500, 500);
-
- // Genereate rects to be rendered into the FBO
- int numRects = 20; // change this to add more or less rects
- for(int i = 0; i < numRects; i++){
- rects.push_back(ofRectangle(0,
- ofRandom(fbo->getHeight()),
- fbo->getWidth(),
- ofRandom(20)));
- rectSpeeds.push_back((1.0f + ofRandom(5)));
- }
-}
-
-// Don't do any drawing here
-void CustomSource::update(){
- // Move rects
- for(int i = 0; i < rects.size(); i++){
- rects[i].y += rectSpeeds[i];
- if(rects[i].y > fbo->getHeight()){
- rects[i].y = -rects[i].getHeight();
- }
- }
-}
-
-// No need to take care of fbo.begin() and fbo.end() here.
-// All within draw() is being rendered into fbo;
-void CustomSource::draw(){
- // Fill FBO with our rects
- ofClear(0);
- ofSetColor(255);
- for(int i = 0; i < rects.size(); i++){
- ofDrawRectangle(rects[i]);
- }
-}
+#include "CustomSource.h"
+
+void CustomSource::setup(){
+ // Give our source a decent name
+ name = "Custom FBO Source";
+
+ // Allocate our FBO source, decide how big it should be
+ allocate(500, 500);
+
+ // Genereate rects to be rendered into the FBO
+ int numRects = 20; // change this to add more or less rects
+ for(int i = 0; i < numRects; i++){
+ rects.push_back(ofRectangle(0,
+ ofRandom(fbo->getHeight()),
+ fbo->getWidth(),
+ ofRandom(20)));
+ rectSpeeds.push_back((1.0f + ofRandom(5)));
+ }
+}
+
+// Don't do any drawing here
+void CustomSource::update(){
+ // Move rects
+ for(int i = 0; i < rects.size(); i++){
+ rects[i].y += rectSpeeds[i];
+ if(rects[i].y > fbo->getHeight()){
+ rects[i].y = -rects[i].getHeight();
+ }
+ }
+}
+
+// No need to take care of fbo.begin() and fbo.end() here.
+// All within draw() is being rendered into fbo;
+void CustomSource::draw(){
+ // Fill FBO with our rects
+ ofClear(0);
+ ofSetColor(255);
+ for(int i = 0; i < rects.size(); i++){
+ ofDrawRectangle(rects[i]);
+ }
+}
diff --git a/example_simpler/src/CustomSource.h b/example_simpler/src/CustomSource.h
index a473d73..9506198 100644
--- a/example_simpler/src/CustomSource.h
+++ b/example_simpler/src/CustomSource.h
@@ -1,14 +1,14 @@
-#pragma once
-
-#include "ofMain.h"
-#include "FboSource.h"
-
-class CustomSource : public ofx::piMapper::FboSource {
- public:
- void setup();
- void update();
- void draw();
-
- std::vector rects;
- std::vector rectSpeeds;
+#pragma once
+
+#include "ofMain.h"
+#include "FboSource.h"
+
+class CustomSource : public ofx::piMapper::FboSource {
+ public:
+ void setup();
+ void update();
+ void draw();
+
+ std::vector rects;
+ std::vector rectSpeeds;
};
\ No newline at end of file
diff --git a/example_simpler/src/Settings.cpp b/example_simpler/src/Settings.cpp
index 509371e..0d9dd73 100644
--- a/example_simpler/src/Settings.cpp
+++ b/example_simpler/src/Settings.cpp
@@ -1,22 +1,22 @@
-#include "Settings.h"
-
-Settings * Settings::_instance = 0;
-
-Settings * Settings::instance(){
- if(_instance == 0){
- _instance = new Settings();
- }
- return _instance;
-}
-
-Settings::Settings(){
- _fullscreen = false;
-}
-
-void Settings::setFullscreen(bool f){
- _fullscreen = f;
-}
-
-bool Settings::getFullscreen(){
- return _fullscreen;
+#include "Settings.h"
+
+Settings * Settings::_instance = 0;
+
+Settings * Settings::instance(){
+ if(_instance == 0){
+ _instance = new Settings();
+ }
+ return _instance;
+}
+
+Settings::Settings(){
+ _fullscreen = false;
+}
+
+void Settings::setFullscreen(bool f){
+ _fullscreen = f;
+}
+
+bool Settings::getFullscreen(){
+ return _fullscreen;
}
\ No newline at end of file
diff --git a/example_simpler/src/Settings.h b/example_simpler/src/Settings.h
index db3db66..7adbab2 100644
--- a/example_simpler/src/Settings.h
+++ b/example_simpler/src/Settings.h
@@ -1,18 +1,18 @@
-#pragma once
-
-#include "ofMain.h"
-
-class Settings {
- public:
- static Settings * instance();
-
- void setFullscreen(bool f);
- bool getFullscreen();
-
- private:
- static Settings * _instance;
-
- Settings();
-
- bool _fullscreen;
-};
+#pragma once
+
+#include "ofMain.h"
+
+class Settings {
+ public:
+ static Settings * instance();
+
+ void setFullscreen(bool f);
+ bool getFullscreen();
+
+ private:
+ static Settings * _instance;
+
+ Settings();
+
+ bool _fullscreen;
+};
diff --git a/example_simpler/src/main.cpp b/example_simpler/src/main.cpp
index 764dcff..3f1cdc4 100644
--- a/example_simpler/src/main.cpp
+++ b/example_simpler/src/main.cpp
@@ -1,22 +1,22 @@
-#include "ofMain.h"
-#include "ofApp.h"
-#include
-#include
-#include "Settings.h"
-
-int main(int argc, char * argv[]){
- bool fullscreen = false;
-
- std::vector arguments = std::vector(argv, argv + argc);
- for(int i = 0; i < arguments.size(); ++i){
- if(arguments.at(i) == "-f"){
- fullscreen = true;
- break;
- }
- }
-
- Settings::instance()->setFullscreen(fullscreen);
-
- ofSetupOpenGL(800, 450, OF_WINDOW);
- ofRunApp(new ofApp());
-}
+#include "ofMain.h"
+#include "ofApp.h"
+#include
+#include
+#include "Settings.h"
+
+int main(int argc, char * argv[]){
+ bool fullscreen = false;
+
+ std::vector arguments = std::vector(argv, argv + argc);
+ for(int i = 0; i < arguments.size(); ++i){
+ if(arguments.at(i) == "-f"){
+ fullscreen = true;
+ break;
+ }
+ }
+
+ Settings::instance()->setFullscreen(fullscreen);
+
+ ofSetupOpenGL(800, 450, OF_WINDOW);
+ ofRunApp(new ofApp());
+}
diff --git a/example_simpler/src/ofApp.cpp b/example_simpler/src/ofApp.cpp
index 02ba925..f39d1a7 100644
--- a/example_simpler/src/ofApp.cpp
+++ b/example_simpler/src/ofApp.cpp
@@ -1,55 +1,55 @@
-#include "ofApp.h"
-
-void ofApp::setup(){
- ofBackground(0);
-
- // Enable or disable audio for video sources globally
- // Set this to false to save resources on the Raspberry Pi
- ofx::piMapper::VideoSource::enableAudio = true;
- ofx::piMapper::VideoSource::useHDMIForAudio = false;
-
- // Add our CustomSource to list of fbo sources of the piMapper
- // FBO sources should be added before piMapper.setup() so the
- // piMapper is able to load the source if it is assigned to
- // a surface in XML settings.
- customSource = new CustomSource();
- piMapper.registerFboSource(customSource);
- piMapper.setup();
-
- // The info layer is hidden by default, press to toggle
- // piMapper.showInfo();
-
- ofSetFullscreen(Settings::instance()->getFullscreen());
- ofSetEscapeQuitsApp(false);
-
- dummyObjects.load("dummy-objects.png");
-}
-
-void ofApp::update(){
- piMapper.update();
-}
-
-void ofApp::draw(){
- dummyObjects.draw(200,200);
- piMapper.draw();
-}
-
-void ofApp::keyPressed(int key){
- piMapper.keyPressed(key);
-}
-
-void ofApp::keyReleased(int key){
- piMapper.keyReleased(key);
-}
-
-void ofApp::mousePressed(int x, int y, int button){
- piMapper.mousePressed(x, y, button);
-}
-
-void ofApp::mouseReleased(int x, int y, int button){
- piMapper.mouseReleased(x, y, button);
-}
-
-void ofApp::mouseDragged(int x, int y, int button){
- piMapper.mouseDragged(x, y, button);
-}
+#include "ofApp.h"
+
+void ofApp::setup(){
+ ofBackground(0);
+
+ // Enable or disable audio for video sources globally
+ // Set this to false to save resources on the Raspberry Pi
+ ofx::piMapper::VideoSource::enableAudio = true;
+ ofx::piMapper::VideoSource::useHDMIForAudio = false;
+
+ // Add our CustomSource to list of fbo sources of the piMapper
+ // FBO sources should be added before piMapper.setup() so the
+ // piMapper is able to load the source if it is assigned to
+ // a surface in XML settings.
+ customSource = new CustomSource();
+ piMapper.registerFboSource(customSource);
+ piMapper.setup();
+
+ // The info layer is hidden by default, press to toggle
+ // piMapper.showInfo();
+
+ ofSetFullscreen(Settings::instance()->getFullscreen());
+ ofSetEscapeQuitsApp(false);
+
+ dummyObjects.load("dummy-objects.png");
+}
+
+void ofApp::update(){
+ piMapper.update();
+}
+
+void ofApp::draw(){
+ dummyObjects.draw(200,200);
+ piMapper.draw();
+}
+
+void ofApp::keyPressed(int key){
+ piMapper.keyPressed(key);
+}
+
+void ofApp::keyReleased(int key){
+ piMapper.keyReleased(key);
+}
+
+void ofApp::mousePressed(int x, int y, int button){
+ piMapper.mousePressed(x, y, button);
+}
+
+void ofApp::mouseReleased(int x, int y, int button){
+ piMapper.mouseReleased(x, y, button);
+}
+
+void ofApp::mouseDragged(int x, int y, int button){
+ piMapper.mouseDragged(x, y, button);
+}
diff --git a/example_simpler/src/ofApp.h b/example_simpler/src/ofApp.h
index 75c7f10..4915c6f 100644
--- a/example_simpler/src/ofApp.h
+++ b/example_simpler/src/ofApp.h
@@ -1,28 +1,28 @@
-#pragma once
-
-#include "ofMain.h"
-#include "Settings.h"
-#include "ofxPiMapper.h"
-#include "CustomSource.h"
-#include "VideoSource.h"
-
-class ofApp : public ofBaseApp {
- public:
- void setup();
- void update();
- void draw();
-
- void keyPressed(int key);
- void keyReleased(int key);
-
- void mousePressed(int x, int y, int button);
- void mouseReleased(int x, int y, int button);
- void mouseDragged(int x, int y, int button);
-
- ofxPiMapper piMapper;
-
- // By using a custom source that is derived from FboSource
- // you will be able to see the source listed in sources editor
- CustomSource * customSource;
- ofImage dummyObjects;
-};
+#pragma once
+
+#include "ofMain.h"
+#include "Settings.h"
+#include "ofxPiMapper.h"
+#include "CustomSource.h"
+#include "VideoSource.h"
+
+class ofApp : public ofBaseApp {
+ public:
+ void setup();
+ void update();
+ void draw();
+
+ void keyPressed(int key);
+ void keyReleased(int key);
+
+ void mousePressed(int x, int y, int button);
+ void mouseReleased(int x, int y, int button);
+ void mouseDragged(int x, int y, int button);
+
+ ofxPiMapper piMapper;
+
+ // By using a custom source that is derived from FboSource
+ // you will be able to see the source listed in sources editor
+ CustomSource * customSource;
+ ofImage dummyObjects;
+};
diff --git a/patches/msys2/makefileCommon/config.addons.mk b/patches/msys2/makefileCommon/config.addons.mk
index 4b38a3d..68ecdf6 100644
--- a/patches/msys2/makefileCommon/config.addons.mk
+++ b/patches/msys2/makefileCommon/config.addons.mk
@@ -1,266 +1,266 @@
-########################################################################
-# PROCESS VALID ADDONS IF AVAILABLE
-########################################################################
-
-
-# parses addons includes, in PARSED_ADDON_INCLUDES receives full PATHS to addons
-define parse_addons_includes
- $(eval ADDONS_INCLUDES_FILTER = $(addprefix $1/, $(ADDON_INCLUDES_EXCLUDE))) \
- $(eval PARSED_ADDONS_SOURCE_PATHS = $(addsuffix /src, $1)) \
- $(eval PARSED_ADDONS_SOURCE_INCLUDES = $(shell $(FIND) $(PARSED_ADDONS_SOURCE_PATHS) -type d 2> /dev/null | grep -v "/\.[^\.]" )) \
- $(eval PARSED_ADDONS_FILTERED_INCLUDE_PATHS = $(filter-out $(ADDONS_INCLUDES_FILTER),$(PARSED_ADDONS_SOURCE_INCLUDES))) \
- $(eval PARSED_ADDONS_LIBS_SOURCE_PATHS = $(addsuffix /libs, $1)) \
- $(eval PARSED_ADDONS_LIBS_SOURCE_INCLUDES = $(shell $(FIND) $(PARSED_ADDONS_LIBS_SOURCE_PATHS) -type d 2> /dev/null | grep -v "/\.[^\.]" )) \
- $(eval PARSED_ADDONS_FILTERED_LIBS_SOURCE_INCLUDE_PATHS = $(filter-out $(ADDONS_INCLUDES_FILTER),$(PARSED_ADDONS_LIBS_SOURCE_INCLUDES))) \
- $(eval PARSED_ADDONS_LIBS_INCLUDES_PATHS = $(addsuffix /libs/*/include, $1)) \
- $(eval PARSED_ADDONS_LIBS_INCLUDES = $(shell $(FIND) $(PARSED_ADDONS_LIBS_INCLUDES_PATHS) -type d 2> /dev/null | grep -v "/\.[^\.]" )) \
- $(eval PARSED_ADDONS_FILTERED_LIBS_INCLUDE_PATHS = $(filter-out $(ADDONS_INCLUDES_FILTER),$(PARSED_ADDONS_LIBS_INCLUDES))) \
- $(eval PARSED_ADDONS_INCLUDES = $(PARSED_ADDONS_FILTERED_INCLUDE_PATHS)) \
- $(eval PARSED_ADDONS_INCLUDES += $(PARSED_ADDONS_FILTERED_LIBS_SOURCE_INCLUDE_PATHS)) \
- $(eval PARSED_ADDONS_INCLUDES += $(PARSED_ADDONS_FILTERED_LIBS_INCLUDE_PATHS))
-endef
-
-# parses addons sources, in PARSED_ADDON_SOURCES receives full PATHS to addons
-define parse_addons_sources
- $(eval ADDONS_SOURCES_FILTER = $(addprefix $1/, $(ADDON_SOURCES_EXCLUDE))) \
- $(eval PARSED_ADDONS_SOURCE_PATHS = $(addsuffix /src, $1)) \
- $(eval PARSED_ADDONS_OFX_SOURCES = $(shell $(FIND) $(PARSED_ADDONS_SOURCE_PATHS) -type f \( -name "*.cpp" -or -name "*.c" -or -name "*.cc" -or -name "*.cxx" \) 2> /dev/null | grep -v "/\.[^\.]" )) \
- $(eval PARSED_ADDONS_FILTERED_SOURCE_PATHS = $(filter-out $(ADDONS_SOURCES_FILTER),$(PARSED_ADDONS_OFX_SOURCES))) \
- $(eval PARSED_ADDONS_LIBS_SOURCE_PATHS = $(addsuffix /libs, $1)) \
- $(eval PARSED_ADDONS_LIBS_SOURCES = $(shell $(FIND) $(PARSED_ADDONS_LIBS_SOURCE_PATHS) -type f \( -name "*.cpp" -or -name "*.c" -or -name "*.cc" -or -name "*.cxx" \) 2> /dev/null | grep -v "/\.[^\.]" )) \
- $(eval PARSED_ADDONS_FILTERED_LIBS_SOURCE_PATHS = $(filter-out $(ADDONS_SOURCES_FILTER),$(PARSED_ADDONS_LIBS_SOURCES))) \
- $(eval PARSED_ADDONS_SOURCE_FILES = $(PARSED_ADDONS_FILTERED_SOURCE_PATHS)) \
- $(eval PARSED_ADDONS_SOURCE_FILES += $(PARSED_ADDONS_FILTERED_LIBS_SOURCE_PATHS))
-endef
-
-# parses addons libraries, in PARSED_ADDON_LIBS receives full PATHS to addons and libs_exclude
-define parse_addons_libraries
- $(eval PARSED_ADDONS_LIBS_PLATFORM_LIB_PATHS = $(filter-out $(ADDON_LIBS_EXCLUDE),$(addsuffix /libs/*/lib/$(ABI_LIB_SUBPATH), $1))) \
- $(eval PARSED_ALL_PLATFORM_LIBS = $(shell $(FIND) $(PARSED_ADDONS_LIBS_PLATFORM_LIB_PATHS) -type d 2> /dev/null | grep -v "/\.[^\.]" )) \
- $(if $(PARSED_ALL_PLATFORM_LIBS), \
- $(eval PARSED_ADDONS_LIBS_PLATFORM_LIBS_STATICS = $(shell $(FIND) $(PARSED_ALL_PLATFORM_LIBS) -name *.a 2> /dev/null | grep -v "/\.[^\.]" )) \
- $(eval PARSED_ADDONS_LIBS_PLATFORM_LIBS_SHARED = $(shell $(FIND) $(PARSED_ALL_PLATFORM_LIBS) -name *.so 2> /dev/null | grep -v "/\.[^\.]" )) \
- $(eval PARSED_ADDONS_LIBS_PLATFORM_LIBS_SHARED += $(shell $(FIND) $(PARSED_ALL_PLATFORM_LIBS) -name *.dylib 2> /dev/null | grep -v "/\.[^\.]" )) \
- $(eval PARSED_ADDONS_LIBS_PLATFORM_LIBS_SHARED += $(shell $(FIND) $(PARSED_ALL_PLATFORM_LIBS) -name *.dll 2> /dev/null | grep -v "/\.[^\.]" )) \
- $(eval PARSED_ADDONS_LIBS = $(PARSED_ADDONS_LIBS_PLATFORM_LIBS_STATICS)) \
- $(eval PARSED_ADDONS_LIBS += $(PARSED_ADDONS_LIBS_PLATFORM_LIBS_SHARED)) \
- )
-endef
-
-
-space :=
-space +=
-
-define src_to_obj
- $(addsuffix .o,$(basename $(filter %.c %.cpp %.cc %.cxx %.cc %.s %.S, $(addprefix $3,$(addprefix $2,$1)))))
-endef
-
-define rwildcard
- $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2)$(filter $(subst *,%,$2),$d))
-endef
-
-# PARSE addon_config.mk FILES
-#
-# 1. read the addon_config.mk file for each adddon that has it
-# 2. read each line of the addon by converting \n to \t since makefiles treat \n as spaces
-# also convert spaces to ? so foreach works for each line instead of each word
-# 3. unscape ? to space inside the loop
-# 4. if the line matches common: or platform: set the PROCESS_NEXT flag to true
-# 5. if the line matches %: but it's not common or platform: set PROCESS_NEXT to false
-# 6: if PROCESS_NEXT eval the line to put the variable in the makefile space
-define parse_addon
- $(if $(wildcard $(PROJECT_ROOT)/$1), \
- $(eval addon=$(realpath $(addprefix $(PROJECT_ROOT)/, $1))) \
- $(eval addon_obj_path=$(PROJECT_ROOT)) \
- $(eval ADDON_PATHS+= $(dir $(addon))) \
- $(eval obj_prefix=$(OF_PROJECT_OBJ_OUTPUT_PATH)addons/) \
- , \
- $(eval addon=$(realpath $(addprefix $(OF_ADDONS_PATH)/, $1))) \
- $(eval addon_obj_path=$(OF_ADDONS_PATH)) \
- $(eval obj_prefix=$(OF_PROJECT_OBJ_OUTPUT_PATH)) \
- ) \
- $(eval ADDON_DEPENDENCIES= ) \
- $(eval ADDON_DATA= ) \
- $(eval ADDON_CFLAGS= ) \
- $(eval ADDON_CPPFLAGS= ) \
- $(eval ADDON_LDFLAGS= ) \
- $(eval ADDON_PKG_CONFIG_LIBRARIES= ) \
- $(eval ADDON_FRAMEWORKS= ) \
- $(eval ADDON_LIBS_EXCLUDE= ) \
- $(eval ADDON_SOURCES_EXCLUDE= ) \
- $(call parse_addons_includes, $(addon)) \
- $(eval ADDON_INCLUDES=$(PARSED_ADDONS_INCLUDES)) \
- $(call parse_addons_libraries, $(addon)) \
- $(eval ADDON_LIBS=$(PARSED_ADDONS_LIBS)) \
- $(call parse_addons_sources, $(addon)) \
- $(eval ADDON_SOURCES=$(PARSED_ADDONS_SOURCE_FILES)) \
- $(eval PROCESS_NEXT=0) \
- $(if $(wildcard $(addon)/addon_config.mk), \
- $(foreach var_line, $(shell cat $(addon)/addon_config.mk | tr '\n ' '\t?'), \
- $(eval unscaped_var_line=$(strip $(subst ?, ,$(var_line)))) \
- $(if $(filter $(PROCESS_NEXT),1), $(eval $(unscaped_var_line))) \
- $(if $(filter %:,$(unscaped_var_line)), \
- $(if $(filter common:,$(unscaped_var_line)), \
- $(eval PROCESS_NEXT=1), \
- $(if $(filter $(ABI_LIB_SUBPATH):,$(unscaped_var_line)), \
- $(eval PROCESS_NEXT=1), \
- $(eval PROCESS_NEXT=0) \
- ) \
- ) \
- ) \
- ) \
- ) \
- $(if $(strip $(ADDON_INCLUDES)), \
- $(eval ADDON_INCLUDES_FILTERED = $(filter-out $(addprefix $(addon)/,$(ADDON_INCLUDES_EXCLUDE)),$(ADDON_INCLUDES))) \
- $(foreach addon_include, $(strip $(ADDON_INCLUDES_FILTERED)), \
- $(if $(wildcard $(addon)/$(addon_include)), \
- $(eval TMP_PROJECT_ADDONS_INCLUDES += $(addon)/$(addon_include)) \
- ) \
- $(if $(wildcard $(addon_include)), \
- $(eval TMP_PROJECT_ADDONS_INCLUDES += $(addon_include)) \
- ) \
- ) \
- ) \
- $(eval TMP_PROJECT_ADDONS_CFLAGS += $(ADDON_CFLAGS)) \
- $(eval TMP_PROJECT_ADDONS_CFLAGS += $(ADDON_CPPFLAGS)) \
- $(if $(strip $(ADDON_LIBS)), \
- $(foreach addon_lib, $(strip $(ADDON_LIBS)), \
- $(if $(wildcard $(addon)/$(addon_lib)), \
- $(eval TMP_PROJECT_ADDONS_LIBS += $(addon)/$(addon_lib)) \
- ) \
- $(if $(wildcard $(addon_lib)), \
- $(eval TMP_PROJECT_ADDONS_LIBS += $(addon_lib)) \
- ) \
- ) \
- ) \
- $(eval TMP_PROJECT_ADDONS_LDFLAGS += $(ADDON_LDFLAGS)) \
- $(eval TMP_PROJECT_ADDONS_PKG_CONFIG_LIBRARIES += $(ADDON_PKG_CONFIG_LIBRARIES)) \
- $(eval TMP_PROJECT_ADDONS_FRAMEWORKS += $(ADDON_FRAMEWORKS)) \
- $(eval PROJECT_AFTER += $(ADDON_AFTER)) \
- $(if $(strip $(ADDON_SOURCES)), \
- $(eval ADDON_SOURCES_FILTERED = $(filter-out $(addprefix $(addon)/,$(ADDON_SOURCES_EXCLUDE)),$(ADDON_SOURCES))) \
- $(foreach addon_src, $(strip $(ADDON_SOURCES_FILTERED)), \
- $(if $(filter $(addon)%, $(addon_src)), \
- $(eval addon_path=$(subst %,*,$(addon_src))) \
- $(if $(findstring *,$(addon_path)), \
- $(eval addon_dir=$(dir $(addon_path))) \
- $(eval addon_rest=$(notdir $(addon_path))) \
- $(eval addon_files=$(strip $(call rwildcard,$(addon_dir),$(addon_rest)))) \
- $(foreach expanded_addon_src, $(addon_files), \
- $(eval TMP_PROJECT_ADDONS_SOURCE_FILES += $(expanded_addon_src)) \
- $(eval SRC_OBJ_FILE=$(addprefix $(addon_obj_path)/,$(strip $(call src_to_obj, $(expanded_addon_src:$(addon)/%=%),$(notdir $1)/,$(obj_prefix))))) \
- $(eval TMP_PROJECT_ADDONS_OBJ_FILES += $(SRC_OBJ_FILE)) \
- ) \
- , \
- $(eval TMP_PROJECT_ADDONS_SOURCE_FILES += $(addon_src)) \
- $(eval SRC_OBJ_FILE=$(addprefix $(addon_obj_path)/,$(strip $(call src_to_obj, $(addon_src:$(addon)/%=%),$(notdir $1)/,$(obj_prefix))))) \
- $(eval TMP_PROJECT_ADDONS_OBJ_FILES += $(SRC_OBJ_FILE)) \
- ) \
- , \
- $(if $(filter $(OF_ROOT)%, $(addon_src)), \
- $(eval addon_path=$(subst %,*,$(addon_src))) \
- $(if $(findstring *,$(addon_path)), \
- $(eval addon_dir=$(dir $(addon_src))) \
- $(eval addon_rest=$(notdir $(addon_src))) \
- $(eval addon_files=$(strip $(call rwildcard,$(addon_dir),$(addon_rest)))) \
- $(foreach expanded_addon_src, $(addon_files), \
- $(eval TMP_PROJECT_ADDONS_SOURCE_FILES += $(expanded_addon_src)) \
- $(eval SRC_OBJ_FILE=$(strip $(call src_to_obj, $(expanded_addon_src:$(OF_ROOT)/%=%),,$(obj_prefix)))) \
- $(eval TMP_PROJECT_ADDONS_OBJ_FILES += $(SRC_OBJ_FILE)) \
- ) \
- , \
- $(eval TMP_PROJECT_ADDONS_SOURCE_FILES += $(addon_src)) \
- $(eval SRC_OBJ_FILE=$(strip $(call src_to_obj, $(addon_src:$(OF_ROOT)/%=%),,$(obj_prefix)))) \
- $(eval TMP_PROJECT_ADDONS_OBJ_FILES += $(SRC_OBJ_FILE)) \
- ) \
- ,$(if $(filter-out /%, $(addon_src)), \
- $(eval addon_path=$(addon)/$(subst %,*,$(addon_src))) \
- $(if $(findstring *,$(addon_path)), \
- $(eval addon_dir=$(dir $(addon_path))) \
- $(eval addon_rest=$(notdir $(addon_path))) \
- $(eval addon_files=$(strip $(call rwildcard,$(addon_dir),$(addon_rest)))) \
- $(foreach expanded_addon_src, $(addon_files), \
- $(eval TMP_PROJECT_ADDONS_SOURCE_FILES += $(expanded_addon_src)) \
- $(eval SRC_OBJ_FILE=$(addprefix $(addon_obj_path)/,$(strip $(call src_to_obj, $(expanded_addon_src:$(addon)/%=%),$(notdir $1)/,$(obj_prefix))))) \
- $(eval TMP_PROJECT_ADDONS_OBJ_FILES += $(SRC_OBJ_FILE)) \
- ) \
- , \
- $(eval TMP_PROJECT_ADDONS_SOURCE_FILES += $(addon_path)) \
- $(eval SRC_OBJ_FILE=$(addprefix $(addon_obj_path)/,$(strip $(call src_to_obj, $(addon_path:$(addon)/%=%),$(notdir $1)/,$(obj_prefix))))) \
- $(eval TMP_PROJECT_ADDONS_OBJ_FILES += $(SRC_OBJ_FILE)) \
- ) \
- ,$(error cannot find addon source file $(addon_src))) \
- ) \
- ) \
- ) \
- ) \
- $(if $(strip $(ADDON_DATA)), \
- $(eval TMP_PROJECT_ADDONS_DATA += $(addprefix $(addon)/,$(ADDON_DATA))) \
- ) \
- $(foreach addon_dep, $(strip $(ADDON_DEPENDENCIES)), \
- $(if $(filter %$(addon_dep), $(PROJECT_ADDONS)), \
- , \
- $(eval PROJECT_ADDONS += $(addon_dep)) \
- $(call parse_addon,$(addon_dep)) \
- ) \
- )
-endef
-
-
-$(foreach addon_to_parse, $(PROJECT_ADDONS), \
- $(call parse_addon,$(addon_to_parse)) \
-)
-
-#define uniq =
-# $(eval seen :=)
-# $(foreach _,$1,$(if $(filter $_,${seen}),,$(eval seen += $_)))
-# ${seen}
-#endef
-
-
-uniq = $(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1)))
-
-
-PROJECT_ADDONS_CFLAGS = $(call uniq,$(TMP_PROJECT_ADDONS_CFLAGS))
-PROJECT_ADDONS_INCLUDES = $(call uniq,$(TMP_PROJECT_ADDONS_INCLUDES))
-PROJECT_ADDONS_LIBS = $(call uniq,$(TMP_PROJECT_ADDONS_LIBS))
-PROJECT_ADDONS_LDFLAGS = $(call uniq,$(TMP_PROJECT_ADDONS_LDFLAGS))
-PROJECT_ADDONS_PKG_CONFIG_LIBRARIES = $(call uniq,$(TMP_PROJECT_ADDONS_PKG_CONFIG_LIBRARIES))
-PROJECT_ADDONS_FRAMEWORKS = $(call uniq,$(TMP_PROJECT_ADDONS_FRAMEWORKS))
-PROJECT_ADDONS_SOURCE_FILES = $(call uniq,$(TMP_PROJECT_ADDONS_SOURCE_FILES))
-PROJECT_ADDONS_OBJ_FILES = $(call uniq,$(TMP_PROJECT_ADDONS_OBJ_FILES))
-PROJECT_ADDONS_DATA = $(call uniq,$(TMP_PROJECT_ADDONS_DATA))
-VPATH += $(call uniq, $(ADDON_PATHS))
-
-
-OF_PROJECT_ADDONS_OBJS = $(PROJECT_ADDONS_OBJ_FILES)
-OF_PROJECT_ADDONS_DEPS = $(patsubst %.o,%.d,$(PROJECT_ADDONS_OBJ_FILES))
-
-########################################################################
-# DEBUGGING
-########################################################################
-# print debug information if so instructed
-ifdef MAKEFILE_DEBUG
- $(info ---PROJECT_ADDONS_PATHS---)
- $(foreach v, $(PROJECT_ADDONS_PATHS),$(info $(v)))
- $(info ---PROJECT_ADDONS_WITH_CONFIG---)
- $(foreach v, $(PROJECT_ADDONS_WITH_CONFIG),$(info $(v)))
- $(info ---PROJECT_ADDONS_INCLUDES---)
- $(foreach v, $(PROJECT_ADDONS_INCLUDES),$(info $(v)))
- $(info ---PROJECT_ADDONS_SOURCE_FILES---)
- $(foreach v, $(PROJECT_ADDONS_SOURCE_FILES),$(info $(v)))
- $(info ---PROJECT_ADDONS_LIBS---)
- $(foreach v, $(PROJECT_ADDONS_LIBS),$(info $(v)))
- $(info ---PROJECT_ADDONS_OBJFILES---)
- $(foreach v, $(PROJECT_ADDONS_OBJFILES),$(info $(v)))
- $(info ---PROJECT_ADDONS_BASE_CFLAGS---)
- $(foreach v, $(PROJECT_ADDONS_BASE_CFLAGS),$(info $(v)))
- $(info ---PROJECT_ADDONS_DEFINES_CFLAGS---)
- $(foreach v, $(PROJECT_ADDONS_DEFINES_CFLAGS),$(info $(v)))
- $(info ---PROJECT_ADDONS_INCLUDES_CFLAGS---)
- $(foreach v, $(PROJECT_ADDONS_INCLUDES_CFLAGS),$(info $(v)))
- $(info ---PROJECT_ADDONS_LDFLAGS---)
- $(foreach v, $(PROJECT_ADDONS_LDFLAGS),$(info $(v)))
- $(info ---PROJECT_ADDONS_DATA---)
- $(foreach v, $(PROJECT_ADDONS_DATA),$(info $(v)))
-endif
+########################################################################
+# PROCESS VALID ADDONS IF AVAILABLE
+########################################################################
+
+
+# parses addons includes, in PARSED_ADDON_INCLUDES receives full PATHS to addons
+define parse_addons_includes
+ $(eval ADDONS_INCLUDES_FILTER = $(addprefix $1/, $(ADDON_INCLUDES_EXCLUDE))) \
+ $(eval PARSED_ADDONS_SOURCE_PATHS = $(addsuffix /src, $1)) \
+ $(eval PARSED_ADDONS_SOURCE_INCLUDES = $(shell $(FIND) $(PARSED_ADDONS_SOURCE_PATHS) -type d 2> /dev/null | grep -v "/\.[^\.]" )) \
+ $(eval PARSED_ADDONS_FILTERED_INCLUDE_PATHS = $(filter-out $(ADDONS_INCLUDES_FILTER),$(PARSED_ADDONS_SOURCE_INCLUDES))) \
+ $(eval PARSED_ADDONS_LIBS_SOURCE_PATHS = $(addsuffix /libs, $1)) \
+ $(eval PARSED_ADDONS_LIBS_SOURCE_INCLUDES = $(shell $(FIND) $(PARSED_ADDONS_LIBS_SOURCE_PATHS) -type d 2> /dev/null | grep -v "/\.[^\.]" )) \
+ $(eval PARSED_ADDONS_FILTERED_LIBS_SOURCE_INCLUDE_PATHS = $(filter-out $(ADDONS_INCLUDES_FILTER),$(PARSED_ADDONS_LIBS_SOURCE_INCLUDES))) \
+ $(eval PARSED_ADDONS_LIBS_INCLUDES_PATHS = $(addsuffix /libs/*/include, $1)) \
+ $(eval PARSED_ADDONS_LIBS_INCLUDES = $(shell $(FIND) $(PARSED_ADDONS_LIBS_INCLUDES_PATHS) -type d 2> /dev/null | grep -v "/\.[^\.]" )) \
+ $(eval PARSED_ADDONS_FILTERED_LIBS_INCLUDE_PATHS = $(filter-out $(ADDONS_INCLUDES_FILTER),$(PARSED_ADDONS_LIBS_INCLUDES))) \
+ $(eval PARSED_ADDONS_INCLUDES = $(PARSED_ADDONS_FILTERED_INCLUDE_PATHS)) \
+ $(eval PARSED_ADDONS_INCLUDES += $(PARSED_ADDONS_FILTERED_LIBS_SOURCE_INCLUDE_PATHS)) \
+ $(eval PARSED_ADDONS_INCLUDES += $(PARSED_ADDONS_FILTERED_LIBS_INCLUDE_PATHS))
+endef
+
+# parses addons sources, in PARSED_ADDON_SOURCES receives full PATHS to addons
+define parse_addons_sources
+ $(eval ADDONS_SOURCES_FILTER = $(addprefix $1/, $(ADDON_SOURCES_EXCLUDE))) \
+ $(eval PARSED_ADDONS_SOURCE_PATHS = $(addsuffix /src, $1)) \
+ $(eval PARSED_ADDONS_OFX_SOURCES = $(shell $(FIND) $(PARSED_ADDONS_SOURCE_PATHS) -type f \( -name "*.cpp" -or -name "*.c" -or -name "*.cc" -or -name "*.cxx" \) 2> /dev/null | grep -v "/\.[^\.]" )) \
+ $(eval PARSED_ADDONS_FILTERED_SOURCE_PATHS = $(filter-out $(ADDONS_SOURCES_FILTER),$(PARSED_ADDONS_OFX_SOURCES))) \
+ $(eval PARSED_ADDONS_LIBS_SOURCE_PATHS = $(addsuffix /libs, $1)) \
+ $(eval PARSED_ADDONS_LIBS_SOURCES = $(shell $(FIND) $(PARSED_ADDONS_LIBS_SOURCE_PATHS) -type f \( -name "*.cpp" -or -name "*.c" -or -name "*.cc" -or -name "*.cxx" \) 2> /dev/null | grep -v "/\.[^\.]" )) \
+ $(eval PARSED_ADDONS_FILTERED_LIBS_SOURCE_PATHS = $(filter-out $(ADDONS_SOURCES_FILTER),$(PARSED_ADDONS_LIBS_SOURCES))) \
+ $(eval PARSED_ADDONS_SOURCE_FILES = $(PARSED_ADDONS_FILTERED_SOURCE_PATHS)) \
+ $(eval PARSED_ADDONS_SOURCE_FILES += $(PARSED_ADDONS_FILTERED_LIBS_SOURCE_PATHS))
+endef
+
+# parses addons libraries, in PARSED_ADDON_LIBS receives full PATHS to addons and libs_exclude
+define parse_addons_libraries
+ $(eval PARSED_ADDONS_LIBS_PLATFORM_LIB_PATHS = $(filter-out $(ADDON_LIBS_EXCLUDE),$(addsuffix /libs/*/lib/$(ABI_LIB_SUBPATH), $1))) \
+ $(eval PARSED_ALL_PLATFORM_LIBS = $(shell $(FIND) $(PARSED_ADDONS_LIBS_PLATFORM_LIB_PATHS) -type d 2> /dev/null | grep -v "/\.[^\.]" )) \
+ $(if $(PARSED_ALL_PLATFORM_LIBS), \
+ $(eval PARSED_ADDONS_LIBS_PLATFORM_LIBS_STATICS = $(shell $(FIND) $(PARSED_ALL_PLATFORM_LIBS) -name *.a 2> /dev/null | grep -v "/\.[^\.]" )) \
+ $(eval PARSED_ADDONS_LIBS_PLATFORM_LIBS_SHARED = $(shell $(FIND) $(PARSED_ALL_PLATFORM_LIBS) -name *.so 2> /dev/null | grep -v "/\.[^\.]" )) \
+ $(eval PARSED_ADDONS_LIBS_PLATFORM_LIBS_SHARED += $(shell $(FIND) $(PARSED_ALL_PLATFORM_LIBS) -name *.dylib 2> /dev/null | grep -v "/\.[^\.]" )) \
+ $(eval PARSED_ADDONS_LIBS_PLATFORM_LIBS_SHARED += $(shell $(FIND) $(PARSED_ALL_PLATFORM_LIBS) -name *.dll 2> /dev/null | grep -v "/\.[^\.]" )) \
+ $(eval PARSED_ADDONS_LIBS = $(PARSED_ADDONS_LIBS_PLATFORM_LIBS_STATICS)) \
+ $(eval PARSED_ADDONS_LIBS += $(PARSED_ADDONS_LIBS_PLATFORM_LIBS_SHARED)) \
+ )
+endef
+
+
+space :=
+space +=
+
+define src_to_obj
+ $(addsuffix .o,$(basename $(filter %.c %.cpp %.cc %.cxx %.cc %.s %.S, $(addprefix $3,$(addprefix $2,$1)))))
+endef
+
+define rwildcard
+ $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2)$(filter $(subst *,%,$2),$d))
+endef
+
+# PARSE addon_config.mk FILES
+#
+# 1. read the addon_config.mk file for each adddon that has it
+# 2. read each line of the addon by converting \n to \t since makefiles treat \n as spaces
+# also convert spaces to ? so foreach works for each line instead of each word
+# 3. unscape ? to space inside the loop
+# 4. if the line matches common: or platform: set the PROCESS_NEXT flag to true
+# 5. if the line matches %: but it's not common or platform: set PROCESS_NEXT to false
+# 6: if PROCESS_NEXT eval the line to put the variable in the makefile space
+define parse_addon
+ $(if $(wildcard $(PROJECT_ROOT)/$1), \
+ $(eval addon=$(realpath $(addprefix $(PROJECT_ROOT)/, $1))) \
+ $(eval addon_obj_path=$(PROJECT_ROOT)) \
+ $(eval ADDON_PATHS+= $(dir $(addon))) \
+ $(eval obj_prefix=$(OF_PROJECT_OBJ_OUTPUT_PATH)addons/) \
+ , \
+ $(eval addon=$(realpath $(addprefix $(OF_ADDONS_PATH)/, $1))) \
+ $(eval addon_obj_path=$(OF_ADDONS_PATH)) \
+ $(eval obj_prefix=$(OF_PROJECT_OBJ_OUTPUT_PATH)) \
+ ) \
+ $(eval ADDON_DEPENDENCIES= ) \
+ $(eval ADDON_DATA= ) \
+ $(eval ADDON_CFLAGS= ) \
+ $(eval ADDON_CPPFLAGS= ) \
+ $(eval ADDON_LDFLAGS= ) \
+ $(eval ADDON_PKG_CONFIG_LIBRARIES= ) \
+ $(eval ADDON_FRAMEWORKS= ) \
+ $(eval ADDON_LIBS_EXCLUDE= ) \
+ $(eval ADDON_SOURCES_EXCLUDE= ) \
+ $(call parse_addons_includes, $(addon)) \
+ $(eval ADDON_INCLUDES=$(PARSED_ADDONS_INCLUDES)) \
+ $(call parse_addons_libraries, $(addon)) \
+ $(eval ADDON_LIBS=$(PARSED_ADDONS_LIBS)) \
+ $(call parse_addons_sources, $(addon)) \
+ $(eval ADDON_SOURCES=$(PARSED_ADDONS_SOURCE_FILES)) \
+ $(eval PROCESS_NEXT=0) \
+ $(if $(wildcard $(addon)/addon_config.mk), \
+ $(foreach var_line, $(shell cat $(addon)/addon_config.mk | tr '\n ' '\t?'), \
+ $(eval unscaped_var_line=$(strip $(subst ?, ,$(var_line)))) \
+ $(if $(filter $(PROCESS_NEXT),1), $(eval $(unscaped_var_line))) \
+ $(if $(filter %:,$(unscaped_var_line)), \
+ $(if $(filter common:,$(unscaped_var_line)), \
+ $(eval PROCESS_NEXT=1), \
+ $(if $(filter $(ABI_LIB_SUBPATH):,$(unscaped_var_line)), \
+ $(eval PROCESS_NEXT=1), \
+ $(eval PROCESS_NEXT=0) \
+ ) \
+ ) \
+ ) \
+ ) \
+ ) \
+ $(if $(strip $(ADDON_INCLUDES)), \
+ $(eval ADDON_INCLUDES_FILTERED = $(filter-out $(addprefix $(addon)/,$(ADDON_INCLUDES_EXCLUDE)),$(ADDON_INCLUDES))) \
+ $(foreach addon_include, $(strip $(ADDON_INCLUDES_FILTERED)), \
+ $(if $(wildcard $(addon)/$(addon_include)), \
+ $(eval TMP_PROJECT_ADDONS_INCLUDES += $(addon)/$(addon_include)) \
+ ) \
+ $(if $(wildcard $(addon_include)), \
+ $(eval TMP_PROJECT_ADDONS_INCLUDES += $(addon_include)) \
+ ) \
+ ) \
+ ) \
+ $(eval TMP_PROJECT_ADDONS_CFLAGS += $(ADDON_CFLAGS)) \
+ $(eval TMP_PROJECT_ADDONS_CFLAGS += $(ADDON_CPPFLAGS)) \
+ $(if $(strip $(ADDON_LIBS)), \
+ $(foreach addon_lib, $(strip $(ADDON_LIBS)), \
+ $(if $(wildcard $(addon)/$(addon_lib)), \
+ $(eval TMP_PROJECT_ADDONS_LIBS += $(addon)/$(addon_lib)) \
+ ) \
+ $(if $(wildcard $(addon_lib)), \
+ $(eval TMP_PROJECT_ADDONS_LIBS += $(addon_lib)) \
+ ) \
+ ) \
+ ) \
+ $(eval TMP_PROJECT_ADDONS_LDFLAGS += $(ADDON_LDFLAGS)) \
+ $(eval TMP_PROJECT_ADDONS_PKG_CONFIG_LIBRARIES += $(ADDON_PKG_CONFIG_LIBRARIES)) \
+ $(eval TMP_PROJECT_ADDONS_FRAMEWORKS += $(ADDON_FRAMEWORKS)) \
+ $(eval PROJECT_AFTER += $(ADDON_AFTER)) \
+ $(if $(strip $(ADDON_SOURCES)), \
+ $(eval ADDON_SOURCES_FILTERED = $(filter-out $(addprefix $(addon)/,$(ADDON_SOURCES_EXCLUDE)),$(ADDON_SOURCES))) \
+ $(foreach addon_src, $(strip $(ADDON_SOURCES_FILTERED)), \
+ $(if $(filter $(addon)%, $(addon_src)), \
+ $(eval addon_path=$(subst %,*,$(addon_src))) \
+ $(if $(findstring *,$(addon_path)), \
+ $(eval addon_dir=$(dir $(addon_path))) \
+ $(eval addon_rest=$(notdir $(addon_path))) \
+ $(eval addon_files=$(strip $(call rwildcard,$(addon_dir),$(addon_rest)))) \
+ $(foreach expanded_addon_src, $(addon_files), \
+ $(eval TMP_PROJECT_ADDONS_SOURCE_FILES += $(expanded_addon_src)) \
+ $(eval SRC_OBJ_FILE=$(addprefix $(addon_obj_path)/,$(strip $(call src_to_obj, $(expanded_addon_src:$(addon)/%=%),$(notdir $1)/,$(obj_prefix))))) \
+ $(eval TMP_PROJECT_ADDONS_OBJ_FILES += $(SRC_OBJ_FILE)) \
+ ) \
+ , \
+ $(eval TMP_PROJECT_ADDONS_SOURCE_FILES += $(addon_src)) \
+ $(eval SRC_OBJ_FILE=$(addprefix $(addon_obj_path)/,$(strip $(call src_to_obj, $(addon_src:$(addon)/%=%),$(notdir $1)/,$(obj_prefix))))) \
+ $(eval TMP_PROJECT_ADDONS_OBJ_FILES += $(SRC_OBJ_FILE)) \
+ ) \
+ , \
+ $(if $(filter $(OF_ROOT)%, $(addon_src)), \
+ $(eval addon_path=$(subst %,*,$(addon_src))) \
+ $(if $(findstring *,$(addon_path)), \
+ $(eval addon_dir=$(dir $(addon_src))) \
+ $(eval addon_rest=$(notdir $(addon_src))) \
+ $(eval addon_files=$(strip $(call rwildcard,$(addon_dir),$(addon_rest)))) \
+ $(foreach expanded_addon_src, $(addon_files), \
+ $(eval TMP_PROJECT_ADDONS_SOURCE_FILES += $(expanded_addon_src)) \
+ $(eval SRC_OBJ_FILE=$(strip $(call src_to_obj, $(expanded_addon_src:$(OF_ROOT)/%=%),,$(obj_prefix)))) \
+ $(eval TMP_PROJECT_ADDONS_OBJ_FILES += $(SRC_OBJ_FILE)) \
+ ) \
+ , \
+ $(eval TMP_PROJECT_ADDONS_SOURCE_FILES += $(addon_src)) \
+ $(eval SRC_OBJ_FILE=$(strip $(call src_to_obj, $(addon_src:$(OF_ROOT)/%=%),,$(obj_prefix)))) \
+ $(eval TMP_PROJECT_ADDONS_OBJ_FILES += $(SRC_OBJ_FILE)) \
+ ) \
+ ,$(if $(filter-out /%, $(addon_src)), \
+ $(eval addon_path=$(addon)/$(subst %,*,$(addon_src))) \
+ $(if $(findstring *,$(addon_path)), \
+ $(eval addon_dir=$(dir $(addon_path))) \
+ $(eval addon_rest=$(notdir $(addon_path))) \
+ $(eval addon_files=$(strip $(call rwildcard,$(addon_dir),$(addon_rest)))) \
+ $(foreach expanded_addon_src, $(addon_files), \
+ $(eval TMP_PROJECT_ADDONS_SOURCE_FILES += $(expanded_addon_src)) \
+ $(eval SRC_OBJ_FILE=$(addprefix $(addon_obj_path)/,$(strip $(call src_to_obj, $(expanded_addon_src:$(addon)/%=%),$(notdir $1)/,$(obj_prefix))))) \
+ $(eval TMP_PROJECT_ADDONS_OBJ_FILES += $(SRC_OBJ_FILE)) \
+ ) \
+ , \
+ $(eval TMP_PROJECT_ADDONS_SOURCE_FILES += $(addon_path)) \
+ $(eval SRC_OBJ_FILE=$(addprefix $(addon_obj_path)/,$(strip $(call src_to_obj, $(addon_path:$(addon)/%=%),$(notdir $1)/,$(obj_prefix))))) \
+ $(eval TMP_PROJECT_ADDONS_OBJ_FILES += $(SRC_OBJ_FILE)) \
+ ) \
+ ,$(error cannot find addon source file $(addon_src))) \
+ ) \
+ ) \
+ ) \
+ ) \
+ $(if $(strip $(ADDON_DATA)), \
+ $(eval TMP_PROJECT_ADDONS_DATA += $(addprefix $(addon)/,$(ADDON_DATA))) \
+ ) \
+ $(foreach addon_dep, $(strip $(ADDON_DEPENDENCIES)), \
+ $(if $(filter %$(addon_dep), $(PROJECT_ADDONS)), \
+ , \
+ $(eval PROJECT_ADDONS += $(addon_dep)) \
+ $(call parse_addon,$(addon_dep)) \
+ ) \
+ )
+endef
+
+
+$(foreach addon_to_parse, $(PROJECT_ADDONS), \
+ $(call parse_addon,$(addon_to_parse)) \
+)
+
+#define uniq =
+# $(eval seen :=)
+# $(foreach _,$1,$(if $(filter $_,${seen}),,$(eval seen += $_)))
+# ${seen}
+#endef
+
+
+uniq = $(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1)))
+
+
+PROJECT_ADDONS_CFLAGS = $(call uniq,$(TMP_PROJECT_ADDONS_CFLAGS))
+PROJECT_ADDONS_INCLUDES = $(call uniq,$(TMP_PROJECT_ADDONS_INCLUDES))
+PROJECT_ADDONS_LIBS = $(call uniq,$(TMP_PROJECT_ADDONS_LIBS))
+PROJECT_ADDONS_LDFLAGS = $(call uniq,$(TMP_PROJECT_ADDONS_LDFLAGS))
+PROJECT_ADDONS_PKG_CONFIG_LIBRARIES = $(call uniq,$(TMP_PROJECT_ADDONS_PKG_CONFIG_LIBRARIES))
+PROJECT_ADDONS_FRAMEWORKS = $(call uniq,$(TMP_PROJECT_ADDONS_FRAMEWORKS))
+PROJECT_ADDONS_SOURCE_FILES = $(call uniq,$(TMP_PROJECT_ADDONS_SOURCE_FILES))
+PROJECT_ADDONS_OBJ_FILES = $(call uniq,$(TMP_PROJECT_ADDONS_OBJ_FILES))
+PROJECT_ADDONS_DATA = $(call uniq,$(TMP_PROJECT_ADDONS_DATA))
+VPATH += $(call uniq, $(ADDON_PATHS))
+
+
+OF_PROJECT_ADDONS_OBJS = $(PROJECT_ADDONS_OBJ_FILES)
+OF_PROJECT_ADDONS_DEPS = $(patsubst %.o,%.d,$(PROJECT_ADDONS_OBJ_FILES))
+
+########################################################################
+# DEBUGGING
+########################################################################
+# print debug information if so instructed
+ifdef MAKEFILE_DEBUG
+ $(info ---PROJECT_ADDONS_PATHS---)
+ $(foreach v, $(PROJECT_ADDONS_PATHS),$(info $(v)))
+ $(info ---PROJECT_ADDONS_WITH_CONFIG---)
+ $(foreach v, $(PROJECT_ADDONS_WITH_CONFIG),$(info $(v)))
+ $(info ---PROJECT_ADDONS_INCLUDES---)
+ $(foreach v, $(PROJECT_ADDONS_INCLUDES),$(info $(v)))
+ $(info ---PROJECT_ADDONS_SOURCE_FILES---)
+ $(foreach v, $(PROJECT_ADDONS_SOURCE_FILES),$(info $(v)))
+ $(info ---PROJECT_ADDONS_LIBS---)
+ $(foreach v, $(PROJECT_ADDONS_LIBS),$(info $(v)))
+ $(info ---PROJECT_ADDONS_OBJFILES---)
+ $(foreach v, $(PROJECT_ADDONS_OBJFILES),$(info $(v)))
+ $(info ---PROJECT_ADDONS_BASE_CFLAGS---)
+ $(foreach v, $(PROJECT_ADDONS_BASE_CFLAGS),$(info $(v)))
+ $(info ---PROJECT_ADDONS_DEFINES_CFLAGS---)
+ $(foreach v, $(PROJECT_ADDONS_DEFINES_CFLAGS),$(info $(v)))
+ $(info ---PROJECT_ADDONS_INCLUDES_CFLAGS---)
+ $(foreach v, $(PROJECT_ADDONS_INCLUDES_CFLAGS),$(info $(v)))
+ $(info ---PROJECT_ADDONS_LDFLAGS---)
+ $(foreach v, $(PROJECT_ADDONS_LDFLAGS),$(info $(v)))
+ $(info ---PROJECT_ADDONS_DATA---)
+ $(foreach v, $(PROJECT_ADDONS_DATA),$(info $(v)))
+endif
diff --git a/patches/msys2/patch.sh b/patches/msys2/patch.sh
index b51f9fa..53e974a 100755
--- a/patches/msys2/patch.sh
+++ b/patches/msys2/patch.sh
@@ -1,8 +1,8 @@
-#!/usr/bin/bash
-
-echo "This script should be run from the patches/msys2 directory"
-
-cp --force ./sound/ofOpenALSoundPlayer.* ../../../../libs/openFrameworks/sound/
-cp --force ./makefileCommon/config.addons.mk ../../../../libs/openFrameworksCompiled/project/makefileCommon/config.addons.mk
-
-echo "Patch for msys2 complete"
+#!/usr/bin/bash
+
+echo "This script should be run from the patches/msys2 directory"
+
+cp --force ./sound/ofOpenALSoundPlayer.* ../../../../libs/openFrameworks/sound/
+cp --force ./makefileCommon/config.addons.mk ../../../../libs/openFrameworksCompiled/project/makefileCommon/config.addons.mk
+
+echo "Patch for msys2 complete"
diff --git a/patches/msys2/sound/ofOpenALSoundPlayer.cpp b/patches/msys2/sound/ofOpenALSoundPlayer.cpp
index 9ae533e..e23b444 100644
--- a/patches/msys2/sound/ofOpenALSoundPlayer.cpp
+++ b/patches/msys2/sound/ofOpenALSoundPlayer.cpp
@@ -1,1076 +1,1076 @@
-#include "ofOpenALSoundPlayer.h"
-
-#ifdef OF_SOUND_PLAYER_OPENAL
-
-#include "ofConstants.h"
-#include "glm/gtc/constants.hpp"
-#include "glm/common.hpp"
-#include "ofLog.h"
-#include "ofEvents.h"
-#include
-
-#if defined (TARGET_OF_IOS) || defined (TARGET_OSX)
-#include
-#include
-#else
-#include
-#include
-#endif
-
-#ifdef OF_USING_MPG123
-#include
-#endif
-
-using namespace std;
-
-static ALCdevice * alDevice = nullptr;
-static ALCcontext * alContext = nullptr;
-vector ofOpenALSoundPlayer::window;
-float ofOpenALSoundPlayer::windowSum = 0.f;
-
-
-kiss_fftr_cfg ofOpenALSoundPlayer::systemFftCfg=0;
-vector ofOpenALSoundPlayer::systemWindowedSignal;
-vector ofOpenALSoundPlayer::systemBins;
-vector ofOpenALSoundPlayer::systemCx_out;
-
-static set & players(){
- static set * players = new set;
- return *players;
-}
-
-void ofOpenALSoundUpdate(){
- alcProcessContext(alContext);
-}
-
-// ----------------------------------------------------------------------------
-// from http://devmaster.net/posts/2893/openal-lesson-6-advanced-loading-and-error-handles
-static string getALErrorString(ALenum error) {
- switch(error) {
- case AL_NO_ERROR:
- return "AL_NO_ERROR";
- case AL_INVALID_NAME:
- return "AL_INVALID_NAME";
- case AL_INVALID_ENUM:
- return "AL_INVALID_ENUM";
- case AL_INVALID_VALUE:
- return "AL_INVALID_VALUE";
- case AL_INVALID_OPERATION:
- return "AL_INVALID_OPERATION";
- case AL_OUT_OF_MEMORY:
- return "AL_OUT_OF_MEMORY";
- };
- return "UNKWOWN_ERROR";
-}
-
-static string getALCErrorString(ALCenum error) {
- switch(error) {
- case ALC_NO_ERROR:
- return "ALC_NO_ERROR";
- case ALC_INVALID_DEVICE:
- return "ALC_INVALID_DEVICE";
- case ALC_INVALID_CONTEXT:
- return "ALC_INVALID_CONTEXT";
- case ALC_INVALID_ENUM:
- return "ALC_INVALID_ENUM";
- case ALC_INVALID_VALUE:
- return "ALC_INVALID_VALUE";
- case ALC_OUT_OF_MEMORY:
- return "ALC_OUT_OF_MEMORY";
- };
- return "UNKWOWN_ERROR";
-}
-
-#ifdef OF_USING_MPG123
-static string getMpg123EncodingString(int encoding) {
- switch(encoding) {
- case MPG123_ENC_16:
- return "MPG123_ENC_16";
-#if MPG123_API_VERSION>=36
- case MPG123_ENC_24:
- return "MPG123_ENC_24";
-#endif
- case MPG123_ENC_32:
- return "MPG123_ENC_32";
- case MPG123_ENC_8:
- return "MPG123_ENC_8";
- case MPG123_ENC_ALAW_8:
- return "MPG123_ENC_ALAW_8";
- case MPG123_ENC_FLOAT:
- return "MPG123_ENC_FLOAT";
- case MPG123_ENC_FLOAT_32:
- return "MPG123_ENC_FLOAT_32";
- case MPG123_ENC_FLOAT_64:
- return "MPG123_ENC_FLOAT_64";
- case MPG123_ENC_SIGNED:
- return "MPG123_ENC_SIGNED";
- case MPG123_ENC_SIGNED_16:
- return "MPG123_ENC_SIGNED_16";
-#if MPG123_API_VERSION>=36
- case MPG123_ENC_SIGNED_24:
- return "MPG123_ENC_SIGNED_24";
-#endif
- case MPG123_ENC_SIGNED_32:
- return "MPG123_ENC_SIGNED_32";
- case MPG123_ENC_SIGNED_8:
- return "MPG123_ENC_SIGNED_8";
- case MPG123_ENC_ULAW_8:
- return "MPG123_ENC_ULAW_8";
- case MPG123_ENC_UNSIGNED_16:
- return "MPG123_ENC_UNSIGNED_16";
-#if MPG123_API_VERSION>=36
- case MPG123_ENC_UNSIGNED_24:
- return "MPG123_ENC_UNSIGNED_24";
-#endif
- case MPG123_ENC_UNSIGNED_32:
- return "MPG123_ENC_UNSIGNED_32";
- case MPG123_ENC_UNSIGNED_8:
- return "MPG123_ENC_UNSIGNED_8";
- default:
- return "MPG123_ENC_ANY";
- }
-}
-#endif
-
-#define BUFFER_STREAM_SIZE 4096
-
-// now, the individual sound player:
-//------------------------------------------------------------
-ofOpenALSoundPlayer::ofOpenALSoundPlayer(){
- bLoop = false;
- bLoadedOk = false;
- pan = 0.0f; // range for oF is -1 to 1,
- volume = 1.0f;
- internalFreq = 44100;
- speed = 1;
- bPaused = false;
- isStreaming = false;
- channels = 0;
- duration = 0;
- fftCfg = 0;
- streamf = 0;
-#ifdef OF_USING_MPG123
- mp3streamf = 0;
-#endif
- players().insert(this);
-}
-
-// ----------------------------------------------------------------------------
-ofOpenALSoundPlayer::~ofOpenALSoundPlayer(){
- unload();
- kiss_fftr_free(fftCfg);
- players().erase(this);
- if( players().empty() ){
- close();
- }
-}
-
-//---------------------------------------
-// this should only be called once
-void ofOpenALSoundPlayer::initialize(){
- if( !alDevice ){
- alDevice = alcOpenDevice( nullptr );
- if( !alDevice ){
- ofLogError("ofOpenALSoundPlayer") << "initialize(): couldn't open OpenAL default device";
- return;
- }else{
- ofLogVerbose("ofOpenALSoundPlayer") << "initialize(): opening "<< alcGetString( alDevice, ALC_DEVICE_SPECIFIER );
- }
- // Create OpenAL context and make it current. If fails, close the OpenAL device that was just opened.
- alContext = alcCreateContext( alDevice, nullptr );
- if( !alContext ){
- ALCenum err = alcGetError( alDevice );
- ofLogError("ofOpenALSoundPlayer") << "initialize(): couldn't not create OpenAL context : "<< getALCErrorString( err );
- close();
- return;
- }
-
- if( alcMakeContextCurrent( alContext )==ALC_FALSE ){
- ALCenum err = alcGetError( alDevice );
- ofLogError("ofOpenALSoundPlayer") << "initialize(): couldn't not make current the create OpenAL context : "<< getALCErrorString( err );
- close();
- return;
- };
- alListener3f( AL_POSITION, 0,0,0 );
-#ifdef OF_USING_MPG123
- mpg123_init();
-#endif
-
- }
- ofLogVerbose("ofOpenALSoundPlayer") << "initialize(): Done";
-}
-
-//---------------------------------------
-void ofOpenALSoundPlayer::createWindow(int size){
- if(int(window.size())!=size){
- windowSum = 0;
- window.resize(size);
- // hanning window
- for(int i = 0; i < size; i++){
- window[i] = .54 - .46 * cos((glm::two_pi() * i) / (size - 1));
- windowSum += window[i];
- }
- }
-}
-
-//---------------------------------------
-void ofOpenALSoundPlayer::close(){
- // Destroy the OpenAL context (if any) before closing the device
- if( alDevice ){
- if( alContext ){
-#ifdef OF_USING_MPG123
- mpg123_exit();
-#endif
- alcMakeContextCurrent(nullptr);
- alcDestroyContext(alContext);
- alContext = nullptr;
- }
- if( alcCloseDevice( alDevice )==ALC_FALSE ){
- ofLogNotice("ofOpenALSoundPlayer") << "initialize(): error closing OpenAL device.";
- }
- alDevice = nullptr;
- }
-}
-
-// ----------------------------------------------------------------------------
-bool ofOpenALSoundPlayer::sfReadFile(const std::filesystem::path& path, vector & buffer, vector & fftAuxBuffer){
- SF_INFO sfInfo;
- SNDFILE* f = sf_open(path.string().c_str(),SFM_READ,&sfInfo);
- if(!f){
- ofLogError("ofOpenALSoundPlayer") << "sfReadFile(): couldn't read \"" << path << "\"";
- return false;
- }
-
- buffer.resize(sfInfo.frames*sfInfo.channels);
- fftAuxBuffer.resize(sfInfo.frames*sfInfo.channels);
-
- int subformat = sfInfo.format & SF_FORMAT_SUBMASK ;
- if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE){
- double scale ;
- sf_command (f, SFC_CALC_SIGNAL_MAX, &scale, sizeof (scale)) ;
- if (scale < 1e-10)
- scale = 1.0 ;
- else
- scale = 32700.0 / scale ;
-
- sf_count_t samples_read = sf_read_float (f, &fftAuxBuffer[0], fftAuxBuffer.size());
- if(samples_read<(int)fftAuxBuffer.size()){
- ofLogWarning("ofOpenALSoundPlayer") << "sfReadFile(): read " << samples_read << " float samples, expected "
- << fftAuxBuffer.size() << " for \"" << path << "\"";
- }
- for (int i = 0 ; i < int(fftAuxBuffer.size()) ; i++){
- fftAuxBuffer[i] *= scale ;
- buffer[i] = 32565.0 * fftAuxBuffer[i];
- }
- }else{
- sf_count_t frames_read = sf_readf_short(f,&buffer[0],sfInfo.frames);
- if(frames_read & buffer,vector & fftAuxBuffer){
- int err = MPG123_OK;
- mpg123_handle * f = mpg123_new(nullptr,&err);
- if(mpg123_open(f,path.string().c_str())!=MPG123_OK){
- ofLogError("ofOpenALSoundPlayer") << "mpg123ReadFile(): couldn't read \"" << path << "\"";
- return false;
- }
-
- mpg123_enc_enum encoding;
- long int rate;
- mpg123_getformat(f,&rate,&channels,(int*)&encoding);
- if(encoding!=MPG123_ENC_SIGNED_16){
- ofLogError("ofOpenALSoundPlayer") << "mpg123ReadFile(): " << getMpg123EncodingString(encoding)
- << " encoding for \"" << path << "\"" << " unsupported, expecting MPG123_ENC_SIGNED_16";
- return false;
- }
- samplerate = rate;
-
- size_t done=0;
- size_t buffer_size = mpg123_outblock( f );
- buffer.resize(buffer_size/2);
- while(mpg123_read(f,(unsigned char*)&buffer[buffer.size()-buffer_size/2],buffer_size,&done)!=MPG123_DONE){
- buffer.resize(buffer.size()+buffer_size/2);
- };
- buffer.resize(buffer.size()-(buffer_size/2-done/2));
- mpg123_close(f);
- mpg123_delete(f);
-
- fftAuxBuffer.resize(buffer.size());
- for(int i=0;i<(int)buffer.size();i++){
- fftAuxBuffer[i] = float(buffer[i])/32565.f;
- }
- duration = float(buffer.size()/channels) / float(samplerate);
- return true;
-}
-#endif
-
-//------------------------------------------------------------
-bool ofOpenALSoundPlayer::sfStream(const std::filesystem::path& path,vector & buffer,vector & fftAuxBuffer){
- if(!streamf){
- SF_INFO sfInfo;
- streamf = sf_open(path.string().c_str(),SFM_READ,&sfInfo);
- if(!streamf){
- ofLogError("ofOpenALSoundPlayer") << "sfStream(): couldn't read \"" << path << "\"";
- return false;
- }
-
- stream_subformat = sfInfo.format & SF_FORMAT_SUBMASK ;
- if (stream_subformat == SF_FORMAT_FLOAT || stream_subformat == SF_FORMAT_DOUBLE){
- sf_command (streamf, SFC_CALC_SIGNAL_MAX, &stream_scale, sizeof (stream_scale)) ;
- if (stream_scale < 1e-10)
- stream_scale = 1.0 ;
- else
- stream_scale = 32700.0 / stream_scale ;
- }
- channels = sfInfo.channels;
- duration = float(sfInfo.frames) / float(sfInfo.samplerate);
- samplerate = sfInfo.samplerate;
- stream_samples_read = 0;
- }
-
- int curr_buffer_size = BUFFER_STREAM_SIZE*channels;
- if(speed>1) curr_buffer_size *= (int)round(speed);
- buffer.resize(curr_buffer_size);
- fftAuxBuffer.resize(buffer.size());
- if (stream_subformat == SF_FORMAT_FLOAT || stream_subformat == SF_FORMAT_DOUBLE){
- sf_count_t samples_read = sf_read_float (streamf, &fftAuxBuffer[0], fftAuxBuffer.size());
- stream_samples_read += samples_read;
- if(samples_read<(int)fftAuxBuffer.size()){
- fftAuxBuffer.resize(samples_read);
- buffer.resize(samples_read);
- setPosition(0);
- if(!bLoop) stopThread();
- stream_samples_read = 0;
- stream_end = true;
- }
- for (int i = 0 ; i < int(fftAuxBuffer.size()) ; i++){
- fftAuxBuffer[i] *= stream_scale ;
- buffer[i] = 32565.0 * fftAuxBuffer[i];
- }
- }else{
- sf_count_t frames_read = sf_readf_short(streamf,&buffer[0],curr_buffer_size/channels);
- stream_samples_read += frames_read*channels;
- if(frames_read & buffer,vector & fftAuxBuffer){
- if(!mp3streamf){
- int err = MPG123_OK;
- mp3streamf = mpg123_new(nullptr,&err);
- if(mpg123_open(mp3streamf,path.string().c_str())!=MPG123_OK){
- mpg123_close(mp3streamf);
- mpg123_delete(mp3streamf);
- ofLogError("ofOpenALSoundPlayer") << "mpg123Stream(): couldn't read \"" << path << "\"";
- return false;
- }
-
- long int rate;
- mpg123_getformat(mp3streamf,&rate,&channels,(int*)&stream_encoding);
- if(stream_encoding!=MPG123_ENC_SIGNED_16){
- ofLogError("ofOpenALSoundPlayer") << "mpg123Stream(): " << getMpg123EncodingString(stream_encoding)
- << " encoding for \"" << path << "\"" << " unsupported, expecting MPG123_ENC_SIGNED_16";
- return false;
- }
- samplerate = rate;
- mp3_buffer_size = mpg123_outblock( mp3streamf );
-
-
- mpg123_seek(mp3streamf,0,SEEK_END);
- off_t samples = mpg123_tell(mp3streamf);
- duration = float(samples/channels) / float(samplerate);
- mpg123_seek(mp3streamf,0,SEEK_SET);
- }
-
- int curr_buffer_size = mp3_buffer_size;
- if(speed>1) curr_buffer_size *= (int)round(speed);
- buffer.resize(curr_buffer_size);
- fftAuxBuffer.resize(buffer.size());
- size_t done=0;
- if(mpg123_read(mp3streamf,(unsigned char*)&buffer[0],curr_buffer_size*2,&done)==MPG123_DONE){
- setPosition(0);
- buffer.resize(done/2);
- fftAuxBuffer.resize(done/2);
- if(!bLoop) stopThread();
- stream_end = true;
- }
-
-
- for(int i=0;i<(int)buffer.size();i++){
- fftAuxBuffer[i] = float(buffer[i])/32565.f;
- }
-
- return true;
-}
-#endif
-
-//------------------------------------------------------------
-bool ofOpenALSoundPlayer::stream(const std::filesystem::path& fileName, vector & buffer){
-#ifdef OF_USING_MPG123
- if(ofFilePath::getFileExt(fileName)=="mp3" || ofFilePath::getFileExt(fileName)=="MP3" || mp3streamf){
- if(!mpg123Stream(fileName,buffer,fftAuxBuffer)) return false;
- }else
-#endif
- if(!sfStream(fileName,buffer,fftAuxBuffer)) return false;
-
- fftBuffers.resize(channels);
- int numFrames = buffer.size()/channels;
-
- for(int i=0;i & buffer){
-#ifdef OF_USING_MPG123
- if(ofFilePath::getFileExt(fileName)!="mp3" && ofFilePath::getFileExt(fileName)!="MP3"){
- if(!sfReadFile(fileName,buffer,fftAuxBuffer)) return false;
- }else{
- if(!mpg123ReadFile(fileName,buffer,fftAuxBuffer)) return false;
- }
-#else
- if(!sfReadFile(fileName,buffer,fftAuxBuffer)) return false;
-#endif
- fftBuffers.resize(channels);
- int numFrames = buffer.size()/channels;
-
- for(int i=0;i > multibuffer;
- multibuffer.resize(channels);
- sources.resize(channels);
- alGenSources(channels, &sources[0]);
- if(isStreaming){
- for(int s=0; s<2;s++){
- for(int i=0;i > multibuffer;
- multibuffer.resize(channels);
- while(isThreadRunning()){
- std::unique_lock lock(mutex);
- for(int i=0; i1){
- for(int j=0;j lock(mutex);
-
- // Delete sources before buffers.
- alDeleteSources(sources.size(),&sources[0]);
- alDeleteBuffers(buffers.size(),&buffers[0]);
-
- sources.clear();
- buffers.clear();
- }
-
- // Free resources and close file descriptors.
-#ifdef OF_USING_MPG123
- if(mp3streamf){
- mpg123_close(mp3streamf);
- mpg123_delete(mp3streamf);
- }
- mp3streamf = 0;
-#endif
-
- if(streamf){
- sf_close(streamf);
- }
- streamf = 0;
-
- bLoadedOk = false;
-}
-
-//------------------------------------------------------------
-bool ofOpenALSoundPlayer::isPlaying() const{
- if(sources.empty()) return false;
- if(isStreaming) return isThreadRunning();
- ALint state;
- bool playing=false;
- for(int i=0;i<(int)sources.size();i++){
- alGetSourcei(sources[i],AL_SOURCE_STATE,&state);
- playing |= (state == AL_PLAYING);
- }
- return playing;
-}
-
-//------------------------------------------------------------
-bool ofOpenALSoundPlayer::isPaused() const{
- if(sources.empty()) return false;
- ALint state;
- bool paused=true;
- for(int i=0;i<(int)sources.size();i++){
- alGetSourcei(sources[i],AL_SOURCE_STATE,&state);
- paused &= (state == AL_PAUSED);
- }
- return paused;
-}
-
-//------------------------------------------------------------
-float ofOpenALSoundPlayer::getSpeed() const{
- return speed;
-}
-
-//------------------------------------------------------------
-float ofOpenALSoundPlayer::getPan() const{
- return pan;
-}
-
-//------------------------------------------------------------
-float ofOpenALSoundPlayer::getVolume() const{
- return volume;
-}
-
-//------------------------------------------------------------
-void ofOpenALSoundPlayer::setVolume(float vol){
- volume = vol;
- if(sources.empty()) return;
- if(channels==1){
- alSourcef (sources[sources.size()-1], AL_GAIN, vol);
- }else{
- setPan(pan);
- }
-}
-
-//------------------------------------------------------------
-void ofOpenALSoundPlayer::setPosition(float pct){
- setPositionMS(duration*pct*1000.f);
-}
-
-//------------------------------------------------------------
-void ofOpenALSoundPlayer::setPositionMS(int ms){
- if(sources.empty()) return;
-#ifdef OF_USING_MPG123
- if(mp3streamf){
- mpg123_seek(mp3streamf,float(ms)/1000.f*samplerate,SEEK_SET);
- }else
-#endif
- if(streamf){
- stream_samples_read = sf_seek(streamf,float(ms)/1000.f*samplerate,SEEK_SET) * channels;
- }else{
- for(int i=0;i<(int)channels;i++){
- alSourcef(sources[sources.size()-channels+i],AL_SEC_OFFSET,float(ms)/1000.f);
- }
- }
-}
-
-//------------------------------------------------------------
-float ofOpenALSoundPlayer::getPosition() const{
- if(duration==0 || sources.empty())
- return 0;
- else
- return getPositionMS()/(1000.f*duration);
-}
-
-//------------------------------------------------------------
-int ofOpenALSoundPlayer::getPositionMS() const{
- if(sources.empty()) return 0;
- float pos;
-#ifdef OF_USING_MPG123
- if(mp3streamf){
- pos = float(mpg123_tell(mp3streamf)) / float(samplerate);
- }else
-#endif
- if(streamf){
- pos = float(stream_samples_read) / float(channels) / float(samplerate);
- }else{
- alGetSourcef(sources[sources.size()-1],AL_SEC_OFFSET,&pos);
- }
- return pos * 1000.f;
-}
-
-//------------------------------------------------------------
-void ofOpenALSoundPlayer::setPan(float p){
- if(sources.empty()) return;
- p = glm::clamp(p, -1.f, 1.f);
- pan = p;
- if(channels==1){
- float pos[3] = {p,0,0};
- alSourcefv(sources[sources.size()-1],AL_POSITION,pos);
- }else{
- // calculates left/right volumes from pan-value (constant panning law)
- // see: Curtis Roads: Computer Music Tutorial p 460
- // thanks to jasch
- float angle = p * 0.7853981633974483f; // in radians from -45. to +45.
- float cosAngle = cos(angle);
- float sinAngle = sin(angle);
- float leftVol = (cosAngle - sinAngle) * 0.7071067811865475; // multiplied by sqrt(2)/2
- float rightVol = (cosAngle + sinAngle) * 0.7071067811865475; // multiplied by sqrt(2)/2
- for(int i=0;i<(int)channels;i++){
- if(i==0){
- alSourcef(sources[sources.size()-channels+i],AL_GAIN,leftVol*volume);
- }else{
- alSourcef(sources[sources.size()-channels+i],AL_GAIN,rightVol*volume);
- }
- }
- }
-}
-
-
-//------------------------------------------------------------
-void ofOpenALSoundPlayer::setPaused(bool bP){
- if(sources.empty()) return;
- std::unique_lock lock(mutex);
- if(bP){
- alSourcePausev(sources.size(),&sources[0]);
- if(isStreaming){
- stopThread();
- }
- }else{
- alSourcePlayv(sources.size(),&sources[0]);
- if(isStreaming){
- startThread();
- }
- }
-
- bPaused = bP;
-}
-
-
-//------------------------------------------------------------
-void ofOpenALSoundPlayer::setSpeed(float spd){
- for(int i=0;i lock(mutex);
- int err = alGetError();
-
- // if the sound is set to multiplay, then create new sources,
- // do not multiplay on loop or we won't be able to stop it
- if (bMultiPlay && !bLoop){
- sources.resize(sources.size()+channels);
- alGetError(); // Clear error.
- alGenSources(channels, &sources[sources.size()-channels]);
- err = alGetError();
- if (err != AL_NO_ERROR){
- ofLogError("ofOpenALSoundPlayer") << "play(): couldn't create multiplay stereo sources: "
- << (int) err << " " << getALErrorString(err);
- return;
- }
- for(int i=0;i lock(mutex);
- alSourceStopv(channels,&sources[sources.size()-channels]);
- if(isStreaming){
- setPosition(0);
- stopThread();
- }
-}
-
-// ----------------------------------------------------------------------------
-void ofOpenALSoundPlayer::initFFT(int bands){
- if(int(bins.size())==bands) return;
- int signalSize = (bands-1)*2;
- if(fftCfg!=0) kiss_fftr_free(fftCfg);
- fftCfg = kiss_fftr_alloc(signalSize, 0, nullptr, nullptr);
- cx_out.resize(bands);
- bins.resize(bands);
- createWindow(signalSize);
-}
-
-// ----------------------------------------------------------------------------
-void ofOpenALSoundPlayer::initSystemFFT(int bands){
- if(int(systemBins.size())==bands) return;
- int signalSize = (bands-1)*2;
- if(systemFftCfg!=0) kiss_fftr_free(systemFftCfg);
- systemFftCfg = kiss_fftr_alloc(signalSize, 0, nullptr, nullptr);
- systemCx_out.resize(bands);
- systemBins.resize(bands);
- createWindow(signalSize);
-}
-
-float * ofOpenALSoundPlayer::getCurrentBufferSum(int size){
- if(int(windowedSignal.size())!=size){
- windowedSignal.resize(size);
- }
- windowedSignal.assign(windowedSignal.size(),0);
- for(int k=0;k=(int)fftBuffers[0].size()) continue;
- for(int i=0;i::iterator it;
- for(it=players().begin();it!=players().end();it++){
- if(!(*it)->isPlaying()) continue;
- float * buffer = (*it)->getCurrentBufferSum(signalSize);
- for(int i=0;i & signal){
- for(int i = 0; i < (int)signal.size(); i++)
- signal[i] *= window[i];
-}
-
-
-#endif
+#include "ofOpenALSoundPlayer.h"
+
+#ifdef OF_SOUND_PLAYER_OPENAL
+
+#include "ofConstants.h"
+#include "glm/gtc/constants.hpp"
+#include "glm/common.hpp"
+#include "ofLog.h"
+#include "ofEvents.h"
+#include
+
+#if defined (TARGET_OF_IOS) || defined (TARGET_OSX)
+#include
+#include
+#else
+#include
+#include
+#endif
+
+#ifdef OF_USING_MPG123
+#include
+#endif
+
+using namespace std;
+
+static ALCdevice * alDevice = nullptr;
+static ALCcontext * alContext = nullptr;
+vector ofOpenALSoundPlayer::window;
+float ofOpenALSoundPlayer::windowSum = 0.f;
+
+
+kiss_fftr_cfg ofOpenALSoundPlayer::systemFftCfg=0;
+vector ofOpenALSoundPlayer::systemWindowedSignal;
+vector ofOpenALSoundPlayer::systemBins;
+vector ofOpenALSoundPlayer::systemCx_out;
+
+static set & players(){
+ static set * players = new set;
+ return *players;
+}
+
+void ofOpenALSoundUpdate(){
+ alcProcessContext(alContext);
+}
+
+// ----------------------------------------------------------------------------
+// from http://devmaster.net/posts/2893/openal-lesson-6-advanced-loading-and-error-handles
+static string getALErrorString(ALenum error) {
+ switch(error) {
+ case AL_NO_ERROR:
+ return "AL_NO_ERROR";
+ case AL_INVALID_NAME:
+ return "AL_INVALID_NAME";
+ case AL_INVALID_ENUM:
+ return "AL_INVALID_ENUM";
+ case AL_INVALID_VALUE:
+ return "AL_INVALID_VALUE";
+ case AL_INVALID_OPERATION:
+ return "AL_INVALID_OPERATION";
+ case AL_OUT_OF_MEMORY:
+ return "AL_OUT_OF_MEMORY";
+ };
+ return "UNKWOWN_ERROR";
+}
+
+static string getALCErrorString(ALCenum error) {
+ switch(error) {
+ case ALC_NO_ERROR:
+ return "ALC_NO_ERROR";
+ case ALC_INVALID_DEVICE:
+ return "ALC_INVALID_DEVICE";
+ case ALC_INVALID_CONTEXT:
+ return "ALC_INVALID_CONTEXT";
+ case ALC_INVALID_ENUM:
+ return "ALC_INVALID_ENUM";
+ case ALC_INVALID_VALUE:
+ return "ALC_INVALID_VALUE";
+ case ALC_OUT_OF_MEMORY:
+ return "ALC_OUT_OF_MEMORY";
+ };
+ return "UNKWOWN_ERROR";
+}
+
+#ifdef OF_USING_MPG123
+static string getMpg123EncodingString(int encoding) {
+ switch(encoding) {
+ case MPG123_ENC_16:
+ return "MPG123_ENC_16";
+#if MPG123_API_VERSION>=36
+ case MPG123_ENC_24:
+ return "MPG123_ENC_24";
+#endif
+ case MPG123_ENC_32:
+ return "MPG123_ENC_32";
+ case MPG123_ENC_8:
+ return "MPG123_ENC_8";
+ case MPG123_ENC_ALAW_8:
+ return "MPG123_ENC_ALAW_8";
+ case MPG123_ENC_FLOAT:
+ return "MPG123_ENC_FLOAT";
+ case MPG123_ENC_FLOAT_32:
+ return "MPG123_ENC_FLOAT_32";
+ case MPG123_ENC_FLOAT_64:
+ return "MPG123_ENC_FLOAT_64";
+ case MPG123_ENC_SIGNED:
+ return "MPG123_ENC_SIGNED";
+ case MPG123_ENC_SIGNED_16:
+ return "MPG123_ENC_SIGNED_16";
+#if MPG123_API_VERSION>=36
+ case MPG123_ENC_SIGNED_24:
+ return "MPG123_ENC_SIGNED_24";
+#endif
+ case MPG123_ENC_SIGNED_32:
+ return "MPG123_ENC_SIGNED_32";
+ case MPG123_ENC_SIGNED_8:
+ return "MPG123_ENC_SIGNED_8";
+ case MPG123_ENC_ULAW_8:
+ return "MPG123_ENC_ULAW_8";
+ case MPG123_ENC_UNSIGNED_16:
+ return "MPG123_ENC_UNSIGNED_16";
+#if MPG123_API_VERSION>=36
+ case MPG123_ENC_UNSIGNED_24:
+ return "MPG123_ENC_UNSIGNED_24";
+#endif
+ case MPG123_ENC_UNSIGNED_32:
+ return "MPG123_ENC_UNSIGNED_32";
+ case MPG123_ENC_UNSIGNED_8:
+ return "MPG123_ENC_UNSIGNED_8";
+ default:
+ return "MPG123_ENC_ANY";
+ }
+}
+#endif
+
+#define BUFFER_STREAM_SIZE 4096
+
+// now, the individual sound player:
+//------------------------------------------------------------
+ofOpenALSoundPlayer::ofOpenALSoundPlayer(){
+ bLoop = false;
+ bLoadedOk = false;
+ pan = 0.0f; // range for oF is -1 to 1,
+ volume = 1.0f;
+ internalFreq = 44100;
+ speed = 1;
+ bPaused = false;
+ isStreaming = false;
+ channels = 0;
+ duration = 0;
+ fftCfg = 0;
+ streamf = 0;
+#ifdef OF_USING_MPG123
+ mp3streamf = 0;
+#endif
+ players().insert(this);
+}
+
+// ----------------------------------------------------------------------------
+ofOpenALSoundPlayer::~ofOpenALSoundPlayer(){
+ unload();
+ kiss_fftr_free(fftCfg);
+ players().erase(this);
+ if( players().empty() ){
+ close();
+ }
+}
+
+//---------------------------------------
+// this should only be called once
+void ofOpenALSoundPlayer::initialize(){
+ if( !alDevice ){
+ alDevice = alcOpenDevice( nullptr );
+ if( !alDevice ){
+ ofLogError("ofOpenALSoundPlayer") << "initialize(): couldn't open OpenAL default device";
+ return;
+ }else{
+ ofLogVerbose("ofOpenALSoundPlayer") << "initialize(): opening "<< alcGetString( alDevice, ALC_DEVICE_SPECIFIER );
+ }
+ // Create OpenAL context and make it current. If fails, close the OpenAL device that was just opened.
+ alContext = alcCreateContext( alDevice, nullptr );
+ if( !alContext ){
+ ALCenum err = alcGetError( alDevice );
+ ofLogError("ofOpenALSoundPlayer") << "initialize(): couldn't not create OpenAL context : "<< getALCErrorString( err );
+ close();
+ return;
+ }
+
+ if( alcMakeContextCurrent( alContext )==ALC_FALSE ){
+ ALCenum err = alcGetError( alDevice );
+ ofLogError("ofOpenALSoundPlayer") << "initialize(): couldn't not make current the create OpenAL context : "<< getALCErrorString( err );
+ close();
+ return;
+ };
+ alListener3f( AL_POSITION, 0,0,0 );
+#ifdef OF_USING_MPG123
+ mpg123_init();
+#endif
+
+ }
+ ofLogVerbose("ofOpenALSoundPlayer") << "initialize(): Done";
+}
+
+//---------------------------------------
+void ofOpenALSoundPlayer::createWindow(int size){
+ if(int(window.size())!=size){
+ windowSum = 0;
+ window.resize(size);
+ // hanning window
+ for(int i = 0; i < size; i++){
+ window[i] = .54 - .46 * cos((glm::two_pi() * i) / (size - 1));
+ windowSum += window[i];
+ }
+ }
+}
+
+//---------------------------------------
+void ofOpenALSoundPlayer::close(){
+ // Destroy the OpenAL context (if any) before closing the device
+ if( alDevice ){
+ if( alContext ){
+#ifdef OF_USING_MPG123
+ mpg123_exit();
+#endif
+ alcMakeContextCurrent(nullptr);
+ alcDestroyContext(alContext);
+ alContext = nullptr;
+ }
+ if( alcCloseDevice( alDevice )==ALC_FALSE ){
+ ofLogNotice("ofOpenALSoundPlayer") << "initialize(): error closing OpenAL device.";
+ }
+ alDevice = nullptr;
+ }
+}
+
+// ----------------------------------------------------------------------------
+bool ofOpenALSoundPlayer::sfReadFile(const std::filesystem::path& path, vector & buffer, vector & fftAuxBuffer){
+ SF_INFO sfInfo;
+ SNDFILE* f = sf_open(path.string().c_str(),SFM_READ,&sfInfo);
+ if(!f){
+ ofLogError("ofOpenALSoundPlayer") << "sfReadFile(): couldn't read \"" << path << "\"";
+ return false;
+ }
+
+ buffer.resize(sfInfo.frames*sfInfo.channels);
+ fftAuxBuffer.resize(sfInfo.frames*sfInfo.channels);
+
+ int subformat = sfInfo.format & SF_FORMAT_SUBMASK ;
+ if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE){
+ double scale ;
+ sf_command (f, SFC_CALC_SIGNAL_MAX, &scale, sizeof (scale)) ;
+ if (scale < 1e-10)
+ scale = 1.0 ;
+ else
+ scale = 32700.0 / scale ;
+
+ sf_count_t samples_read = sf_read_float (f, &fftAuxBuffer[0], fftAuxBuffer.size());
+ if(samples_read<(int)fftAuxBuffer.size()){
+ ofLogWarning("ofOpenALSoundPlayer") << "sfReadFile(): read " << samples_read << " float samples, expected "
+ << fftAuxBuffer.size() << " for \"" << path << "\"";
+ }
+ for (int i = 0 ; i < int(fftAuxBuffer.size()) ; i++){
+ fftAuxBuffer[i] *= scale ;
+ buffer[i] = 32565.0 * fftAuxBuffer[i];
+ }
+ }else{
+ sf_count_t frames_read = sf_readf_short(f,&buffer[0],sfInfo.frames);
+ if(frames_read & buffer,vector & fftAuxBuffer){
+ int err = MPG123_OK;
+ mpg123_handle * f = mpg123_new(nullptr,&err);
+ if(mpg123_open(f,path.string().c_str())!=MPG123_OK){
+ ofLogError("ofOpenALSoundPlayer") << "mpg123ReadFile(): couldn't read \"" << path << "\"";
+ return false;
+ }
+
+ mpg123_enc_enum encoding;
+ long int rate;
+ mpg123_getformat(f,&rate,&channels,(int*)&encoding);
+ if(encoding!=MPG123_ENC_SIGNED_16){
+ ofLogError("ofOpenALSoundPlayer") << "mpg123ReadFile(): " << getMpg123EncodingString(encoding)
+ << " encoding for \"" << path << "\"" << " unsupported, expecting MPG123_ENC_SIGNED_16";
+ return false;
+ }
+ samplerate = rate;
+
+ size_t done=0;
+ size_t buffer_size = mpg123_outblock( f );
+ buffer.resize(buffer_size/2);
+ while(mpg123_read(f,(unsigned char*)&buffer[buffer.size()-buffer_size/2],buffer_size,&done)!=MPG123_DONE){
+ buffer.resize(buffer.size()+buffer_size/2);
+ };
+ buffer.resize(buffer.size()-(buffer_size/2-done/2));
+ mpg123_close(f);
+ mpg123_delete(f);
+
+ fftAuxBuffer.resize(buffer.size());
+ for(int i=0;i<(int)buffer.size();i++){
+ fftAuxBuffer[i] = float(buffer[i])/32565.f;
+ }
+ duration = float(buffer.size()/channels) / float(samplerate);
+ return true;
+}
+#endif
+
+//------------------------------------------------------------
+bool ofOpenALSoundPlayer::sfStream(const std::filesystem::path& path,vector & buffer,vector & fftAuxBuffer){
+ if(!streamf){
+ SF_INFO sfInfo;
+ streamf = sf_open(path.string().c_str(),SFM_READ,&sfInfo);
+ if(!streamf){
+ ofLogError("ofOpenALSoundPlayer") << "sfStream(): couldn't read \"" << path << "\"";
+ return false;
+ }
+
+ stream_subformat = sfInfo.format & SF_FORMAT_SUBMASK ;
+ if (stream_subformat == SF_FORMAT_FLOAT || stream_subformat == SF_FORMAT_DOUBLE){
+ sf_command (streamf, SFC_CALC_SIGNAL_MAX, &stream_scale, sizeof (stream_scale)) ;
+ if (stream_scale < 1e-10)
+ stream_scale = 1.0 ;
+ else
+ stream_scale = 32700.0 / stream_scale ;
+ }
+ channels = sfInfo.channels;
+ duration = float(sfInfo.frames) / float(sfInfo.samplerate);
+ samplerate = sfInfo.samplerate;
+ stream_samples_read = 0;
+ }
+
+ int curr_buffer_size = BUFFER_STREAM_SIZE*channels;
+ if(speed>1) curr_buffer_size *= (int)round(speed);
+ buffer.resize(curr_buffer_size);
+ fftAuxBuffer.resize(buffer.size());
+ if (stream_subformat == SF_FORMAT_FLOAT || stream_subformat == SF_FORMAT_DOUBLE){
+ sf_count_t samples_read = sf_read_float (streamf, &fftAuxBuffer[0], fftAuxBuffer.size());
+ stream_samples_read += samples_read;
+ if(samples_read<(int)fftAuxBuffer.size()){
+ fftAuxBuffer.resize(samples_read);
+ buffer.resize(samples_read);
+ setPosition(0);
+ if(!bLoop) stopThread();
+ stream_samples_read = 0;
+ stream_end = true;
+ }
+ for (int i = 0 ; i < int(fftAuxBuffer.size()) ; i++){
+ fftAuxBuffer[i] *= stream_scale ;
+ buffer[i] = 32565.0 * fftAuxBuffer[i];
+ }
+ }else{
+ sf_count_t frames_read = sf_readf_short(streamf,&buffer[0],curr_buffer_size/channels);
+ stream_samples_read += frames_read*channels;
+ if(frames_read & buffer,vector & fftAuxBuffer){
+ if(!mp3streamf){
+ int err = MPG123_OK;
+ mp3streamf = mpg123_new(nullptr,&err);
+ if(mpg123_open(mp3streamf,path.string().c_str())!=MPG123_OK){
+ mpg123_close(mp3streamf);
+ mpg123_delete(mp3streamf);
+ ofLogError("ofOpenALSoundPlayer") << "mpg123Stream(): couldn't read \"" << path << "\"";
+ return false;
+ }
+
+ long int rate;
+ mpg123_getformat(mp3streamf,&rate,&channels,(int*)&stream_encoding);
+ if(stream_encoding!=MPG123_ENC_SIGNED_16){
+ ofLogError("ofOpenALSoundPlayer") << "mpg123Stream(): " << getMpg123EncodingString(stream_encoding)
+ << " encoding for \"" << path << "\"" << " unsupported, expecting MPG123_ENC_SIGNED_16";
+ return false;
+ }
+ samplerate = rate;
+ mp3_buffer_size = mpg123_outblock( mp3streamf );
+
+
+ mpg123_seek(mp3streamf,0,SEEK_END);
+ off_t samples = mpg123_tell(mp3streamf);
+ duration = float(samples/channels) / float(samplerate);
+ mpg123_seek(mp3streamf,0,SEEK_SET);
+ }
+
+ int curr_buffer_size = mp3_buffer_size;
+ if(speed>1) curr_buffer_size *= (int)round(speed);
+ buffer.resize(curr_buffer_size);
+ fftAuxBuffer.resize(buffer.size());
+ size_t done=0;
+ if(mpg123_read(mp3streamf,(unsigned char*)&buffer[0],curr_buffer_size*2,&done)==MPG123_DONE){
+ setPosition(0);
+ buffer.resize(done/2);
+ fftAuxBuffer.resize(done/2);
+ if(!bLoop) stopThread();
+ stream_end = true;
+ }
+
+
+ for(int i=0;i<(int)buffer.size();i++){
+ fftAuxBuffer[i] = float(buffer[i])/32565.f;
+ }
+
+ return true;
+}
+#endif
+
+//------------------------------------------------------------
+bool ofOpenALSoundPlayer::stream(const std::filesystem::path& fileName, vector & buffer){
+#ifdef OF_USING_MPG123
+ if(ofFilePath::getFileExt(fileName)=="mp3" || ofFilePath::getFileExt(fileName)=="MP3" || mp3streamf){
+ if(!mpg123Stream(fileName,buffer,fftAuxBuffer)) return false;
+ }else
+#endif
+ if(!sfStream(fileName,buffer,fftAuxBuffer)) return false;
+
+ fftBuffers.resize(channels);
+ int numFrames = buffer.size()/channels;
+
+ for(int i=0;i & buffer){
+#ifdef OF_USING_MPG123
+ if(ofFilePath::getFileExt(fileName)!="mp3" && ofFilePath::getFileExt(fileName)!="MP3"){
+ if(!sfReadFile(fileName,buffer,fftAuxBuffer)) return false;
+ }else{
+ if(!mpg123ReadFile(fileName,buffer,fftAuxBuffer)) return false;
+ }
+#else
+ if(!sfReadFile(fileName,buffer,fftAuxBuffer)) return false;
+#endif
+ fftBuffers.resize(channels);
+ int numFrames = buffer.size()/channels;
+
+ for(int i=0;i > multibuffer;
+ multibuffer.resize(channels);
+ sources.resize(channels);
+ alGenSources(channels, &sources[0]);
+ if(isStreaming){
+ for(int s=0; s<2;s++){
+ for(int i=0;i > multibuffer;
+ multibuffer.resize(channels);
+ while(isThreadRunning()){
+ std::unique_lock lock(mutex);
+ for(int i=0; i1){
+ for(int j=0;j lock(mutex);
+
+ // Delete sources before buffers.
+ alDeleteSources(sources.size(),&sources[0]);
+ alDeleteBuffers(buffers.size(),&buffers[0]);
+
+ sources.clear();
+ buffers.clear();
+ }
+
+ // Free resources and close file descriptors.
+#ifdef OF_USING_MPG123
+ if(mp3streamf){
+ mpg123_close(mp3streamf);
+ mpg123_delete(mp3streamf);
+ }
+ mp3streamf = 0;
+#endif
+
+ if(streamf){
+ sf_close(streamf);
+ }
+ streamf = 0;
+
+ bLoadedOk = false;
+}
+
+//------------------------------------------------------------
+bool ofOpenALSoundPlayer::isPlaying() const{
+ if(sources.empty()) return false;
+ if(isStreaming) return isThreadRunning();
+ ALint state;
+ bool playing=false;
+ for(int i=0;i<(int)sources.size();i++){
+ alGetSourcei(sources[i],AL_SOURCE_STATE,&state);
+ playing |= (state == AL_PLAYING);
+ }
+ return playing;
+}
+
+//------------------------------------------------------------
+bool ofOpenALSoundPlayer::isPaused() const{
+ if(sources.empty()) return false;
+ ALint state;
+ bool paused=true;
+ for(int i=0;i<(int)sources.size();i++){
+ alGetSourcei(sources[i],AL_SOURCE_STATE,&state);
+ paused &= (state == AL_PAUSED);
+ }
+ return paused;
+}
+
+//------------------------------------------------------------
+float ofOpenALSoundPlayer::getSpeed() const{
+ return speed;
+}
+
+//------------------------------------------------------------
+float ofOpenALSoundPlayer::getPan() const{
+ return pan;
+}
+
+//------------------------------------------------------------
+float ofOpenALSoundPlayer::getVolume() const{
+ return volume;
+}
+
+//------------------------------------------------------------
+void ofOpenALSoundPlayer::setVolume(float vol){
+ volume = vol;
+ if(sources.empty()) return;
+ if(channels==1){
+ alSourcef (sources[sources.size()-1], AL_GAIN, vol);
+ }else{
+ setPan(pan);
+ }
+}
+
+//------------------------------------------------------------
+void ofOpenALSoundPlayer::setPosition(float pct){
+ setPositionMS(duration*pct*1000.f);
+}
+
+//------------------------------------------------------------
+void ofOpenALSoundPlayer::setPositionMS(int ms){
+ if(sources.empty()) return;
+#ifdef OF_USING_MPG123
+ if(mp3streamf){
+ mpg123_seek(mp3streamf,float(ms)/1000.f*samplerate,SEEK_SET);
+ }else
+#endif
+ if(streamf){
+ stream_samples_read = sf_seek(streamf,float(ms)/1000.f*samplerate,SEEK_SET) * channels;
+ }else{
+ for(int i=0;i<(int)channels;i++){
+ alSourcef(sources[sources.size()-channels+i],AL_SEC_OFFSET,float(ms)/1000.f);
+ }
+ }
+}
+
+//------------------------------------------------------------
+float ofOpenALSoundPlayer::getPosition() const{
+ if(duration==0 || sources.empty())
+ return 0;
+ else
+ return getPositionMS()/(1000.f*duration);
+}
+
+//------------------------------------------------------------
+int ofOpenALSoundPlayer::getPositionMS() const{
+ if(sources.empty()) return 0;
+ float pos;
+#ifdef OF_USING_MPG123
+ if(mp3streamf){
+ pos = float(mpg123_tell(mp3streamf)) / float(samplerate);
+ }else
+#endif
+ if(streamf){
+ pos = float(stream_samples_read) / float(channels) / float(samplerate);
+ }else{
+ alGetSourcef(sources[sources.size()-1],AL_SEC_OFFSET,&pos);
+ }
+ return pos * 1000.f;
+}
+
+//------------------------------------------------------------
+void ofOpenALSoundPlayer::setPan(float p){
+ if(sources.empty()) return;
+ p = glm::clamp(p, -1.f, 1.f);
+ pan = p;
+ if(channels==1){
+ float pos[3] = {p,0,0};
+ alSourcefv(sources[sources.size()-1],AL_POSITION,pos);
+ }else{
+ // calculates left/right volumes from pan-value (constant panning law)
+ // see: Curtis Roads: Computer Music Tutorial p 460
+ // thanks to jasch
+ float angle = p * 0.7853981633974483f; // in radians from -45. to +45.
+ float cosAngle = cos(angle);
+ float sinAngle = sin(angle);
+ float leftVol = (cosAngle - sinAngle) * 0.7071067811865475; // multiplied by sqrt(2)/2
+ float rightVol = (cosAngle + sinAngle) * 0.7071067811865475; // multiplied by sqrt(2)/2
+ for(int i=0;i<(int)channels;i++){
+ if(i==0){
+ alSourcef(sources[sources.size()-channels+i],AL_GAIN,leftVol*volume);
+ }else{
+ alSourcef(sources[sources.size()-channels+i],AL_GAIN,rightVol*volume);
+ }
+ }
+ }
+}
+
+
+//------------------------------------------------------------
+void ofOpenALSoundPlayer::setPaused(bool bP){
+ if(sources.empty()) return;
+ std::unique_lock lock(mutex);
+ if(bP){
+ alSourcePausev(sources.size(),&sources[0]);
+ if(isStreaming){
+ stopThread();
+ }
+ }else{
+ alSourcePlayv(sources.size(),&sources[0]);
+ if(isStreaming){
+ startThread();
+ }
+ }
+
+ bPaused = bP;
+}
+
+
+//------------------------------------------------------------
+void ofOpenALSoundPlayer::setSpeed(float spd){
+ for(int i=0;i lock(mutex);
+ int err = alGetError();
+
+ // if the sound is set to multiplay, then create new sources,
+ // do not multiplay on loop or we won't be able to stop it
+ if (bMultiPlay && !bLoop){
+ sources.resize(sources.size()+channels);
+ alGetError(); // Clear error.
+ alGenSources(channels, &sources[sources.size()-channels]);
+ err = alGetError();
+ if (err != AL_NO_ERROR){
+ ofLogError("ofOpenALSoundPlayer") << "play(): couldn't create multiplay stereo sources: "
+ << (int) err << " " << getALErrorString(err);
+ return;
+ }
+ for(int i=0;i lock(mutex);
+ alSourceStopv(channels,&sources[sources.size()-channels]);
+ if(isStreaming){
+ setPosition(0);
+ stopThread();
+ }
+}
+
+// ----------------------------------------------------------------------------
+void ofOpenALSoundPlayer::initFFT(int bands){
+ if(int(bins.size())==bands) return;
+ int signalSize = (bands-1)*2;
+ if(fftCfg!=0) kiss_fftr_free(fftCfg);
+ fftCfg = kiss_fftr_alloc(signalSize, 0, nullptr, nullptr);
+ cx_out.resize(bands);
+ bins.resize(bands);
+ createWindow(signalSize);
+}
+
+// ----------------------------------------------------------------------------
+void ofOpenALSoundPlayer::initSystemFFT(int bands){
+ if(int(systemBins.size())==bands) return;
+ int signalSize = (bands-1)*2;
+ if(systemFftCfg!=0) kiss_fftr_free(systemFftCfg);
+ systemFftCfg = kiss_fftr_alloc(signalSize, 0, nullptr, nullptr);
+ systemCx_out.resize(bands);
+ systemBins.resize(bands);
+ createWindow(signalSize);
+}
+
+float * ofOpenALSoundPlayer::getCurrentBufferSum(int size){
+ if(int(windowedSignal.size())!=size){
+ windowedSignal.resize(size);
+ }
+ windowedSignal.assign(windowedSignal.size(),0);
+ for(int k=0;k=(int)fftBuffers[0].size()) continue;
+ for(int i=0;i::iterator it;
+ for(it=players().begin();it!=players().end();it++){
+ if(!(*it)->isPlaying()) continue;
+ float * buffer = (*it)->getCurrentBufferSum(signalSize);
+ for(int i=0;i & signal){
+ for(int i = 0; i < (int)signal.size(); i++)
+ signal[i] *= window[i];
+}
+
+
+#endif
diff --git a/patches/msys2/sound/ofOpenALSoundPlayer.h b/patches/msys2/sound/ofOpenALSoundPlayer.h
index 042f7b3..9c0adde 100644
--- a/patches/msys2/sound/ofOpenALSoundPlayer.h
+++ b/patches/msys2/sound/ofOpenALSoundPlayer.h
@@ -1,157 +1,157 @@
-#pragma once
-
-#include "ofConstants.h"
-
-#ifdef OF_SOUND_PLAYER_OPENAL
-#include "ofSoundBaseTypes.h"
-#include "ofThread.h"
-
-
-
-typedef unsigned int ALuint;
-
-#include "kiss_fft.h"
-#include "kiss_fftr.h"
-
-
-
-typedef struct SNDFILE_tag SNDFILE ;
-
-
-#ifdef OF_USING_MPG123
- typedef struct mpg123_handle_struct mpg123_handle;
-#endif
-
-class ofEventArgs;
-
-// TO DO :
-// ---------------------------
-// -fft via fmod, as in the last time...
-// -close fmod if it's up
-// -loadSoundForStreaming(char * fileName);
-// ---------------------------
-
-// interesting:
-// http://www.compuphase.com/mp3/mp3loops.htm
-
-
-// ---------------------------------------------------------------------------- SOUND SYSTEM FMOD
-
-// --------------------- global functions:
-void ofFmodSoundStopAll();
-void ofFmodSoundSetVolume(float vol);
-void ofOpenALSoundUpdate(); // calls FMOD update.
-float * ofFmodSoundGetSpectrum(int nBands); // max 512...
-
-
-// --------------------- player functions:
-class ofOpenALSoundPlayer : public ofBaseSoundPlayer, public ofThread {
-
- public:
-
- ofOpenALSoundPlayer();
- virtual ~ofOpenALSoundPlayer();
-
- bool load(const std::filesystem::path& fileName, bool stream = false);
- void unload();
- void play();
- void stop();
-
- void setVolume(float vol);
- void setPan(float vol); // -1 to 1
- void setSpeed(float spd);
- void setPaused(bool bP);
- void setLoop(bool bLp);
- void setMultiPlay(bool bMp);
- void setPosition(float pct); // 0 = start, 1 = end;
- void setPositionMS(int ms);
-
-
- float getPosition() const;
- int getPositionMS() const;
- bool isPlaying() const;
- float getSpeed() const;
- float getPan() const;
- float getVolume() const;
- bool isPaused() const;
- bool isLoaded() const;
-
- static void initialize();
- static void close();
-
- float * getSpectrum(int bands);
-
- static float * getSystemSpectrum(int bands);
-
- protected:
- void threadedFunction();
-
- private:
- friend void ofOpenALSoundUpdate();
- void update(ofEventArgs & args);
- void initFFT(int bands);
- float * getCurrentBufferSum(int size);
-
- static void createWindow(int size);
- static void runWindow(std::vector & signal);
- static void initSystemFFT(int bands);
-
- bool sfReadFile(const std::filesystem::path& path,std::vector & buffer,std::vector & fftAuxBuffer);
- bool sfStream(const std::filesystem::path& path,std::vector & buffer,std::vector & fftAuxBuffer);
-#ifdef OF_USING_MPG123
- bool mpg123ReadFile(const std::filesystem::path& path,std::vector & buffer,std::vector & fftAuxBuffer);
- bool mpg123Stream(const std::filesystem::path& path,std::vector & buffer,std::vector & fftAuxBuffer);
-#endif
-
- bool readFile(const std::filesystem::path& fileName,std::vector & buffer);
- bool stream(const std::filesystem::path& fileName, std::vector & buffer);
-
- bool isStreaming;
- bool bMultiPlay;
- bool bLoop;
- bool bLoadedOk;
- bool bPaused;
- float pan; // 0 - 1
- float volume; // 0 - 1
- float internalFreq; // 44100 ?
- float speed; // -n to n, 1 = normal, -1 backwards
- unsigned int length; // in samples;
-
- static std::vector window;
- static float windowSum;
-
- int channels;
- float duration; //in secs
- int samplerate;
- std::vector buffers;
- std::vector sources;
-
- // fft structures
- std::vector > fftBuffers;
- kiss_fftr_cfg fftCfg;
- std::vector windowedSignal;
- std::vector bins;
- std::vector cx_out;
-
-
- static kiss_fftr_cfg systemFftCfg;
- static std::vector systemWindowedSignal;
- static std::vector systemBins;
- static std::vector systemCx_out;
-
- SNDFILE* streamf;
- size_t stream_samples_read;
-#ifdef OF_USING_MPG123
- mpg123_handle * mp3streamf;
- int stream_encoding;
-#endif
- int mp3_buffer_size;
- int stream_subformat;
- double stream_scale;
- std::vector buffer;
- std::vector fftAuxBuffer;
-
- bool stream_end;
-};
-
-#endif
+#pragma once
+
+#include "ofConstants.h"
+
+#ifdef OF_SOUND_PLAYER_OPENAL
+#include "ofSoundBaseTypes.h"
+#include "ofThread.h"
+
+
+
+typedef unsigned int ALuint;
+
+#include "kiss_fft.h"
+#include "kiss_fftr.h"
+
+
+
+typedef struct SNDFILE_tag SNDFILE ;
+
+
+#ifdef OF_USING_MPG123
+ typedef struct mpg123_handle_struct mpg123_handle;
+#endif
+
+class ofEventArgs;
+
+// TO DO :
+// ---------------------------
+// -fft via fmod, as in the last time...
+// -close fmod if it's up
+// -loadSoundForStreaming(char * fileName);
+// ---------------------------
+
+// interesting:
+// http://www.compuphase.com/mp3/mp3loops.htm
+
+
+// ---------------------------------------------------------------------------- SOUND SYSTEM FMOD
+
+// --------------------- global functions:
+void ofFmodSoundStopAll();
+void ofFmodSoundSetVolume(float vol);
+void ofOpenALSoundUpdate(); // calls FMOD update.
+float * ofFmodSoundGetSpectrum(int nBands); // max 512...
+
+
+// --------------------- player functions:
+class ofOpenALSoundPlayer : public ofBaseSoundPlayer, public ofThread {
+
+ public:
+
+ ofOpenALSoundPlayer();
+ virtual ~ofOpenALSoundPlayer();
+
+ bool load(const std::filesystem::path& fileName, bool stream = false);
+ void unload();
+ void play();
+ void stop();
+
+ void setVolume(float vol);
+ void setPan(float vol); // -1 to 1
+ void setSpeed(float spd);
+ void setPaused(bool bP);
+ void setLoop(bool bLp);
+ void setMultiPlay(bool bMp);
+ void setPosition(float pct); // 0 = start, 1 = end;
+ void setPositionMS(int ms);
+
+
+ float getPosition() const;
+ int getPositionMS() const;
+ bool isPlaying() const;
+ float getSpeed() const;
+ float getPan() const;
+ float getVolume() const;
+ bool isPaused() const;
+ bool isLoaded() const;
+
+ static void initialize();
+ static void close();
+
+ float * getSpectrum(int bands);
+
+ static float * getSystemSpectrum(int bands);
+
+ protected:
+ void threadedFunction();
+
+ private:
+ friend void ofOpenALSoundUpdate();
+ void update(ofEventArgs & args);
+ void initFFT(int bands);
+ float * getCurrentBufferSum(int size);
+
+ static void createWindow(int size);
+ static void runWindow(std::vector & signal);
+ static void initSystemFFT(int bands);
+
+ bool sfReadFile(const std::filesystem::path& path,std::vector & buffer,std::vector & fftAuxBuffer);
+ bool sfStream(const std::filesystem::path& path,std::vector & buffer,std::vector & fftAuxBuffer);
+#ifdef OF_USING_MPG123
+ bool mpg123ReadFile(const std::filesystem::path& path,std::vector & buffer,std::vector & fftAuxBuffer);
+ bool mpg123Stream(const std::filesystem::path& path,std::vector & buffer,std::vector & fftAuxBuffer);
+#endif
+
+ bool readFile(const std::filesystem::path& fileName,std::vector & buffer);
+ bool stream(const std::filesystem::path& fileName, std::vector & buffer);
+
+ bool isStreaming;
+ bool bMultiPlay;
+ bool bLoop;
+ bool bLoadedOk;
+ bool bPaused;
+ float pan; // 0 - 1
+ float volume; // 0 - 1
+ float internalFreq; // 44100 ?
+ float speed; // -n to n, 1 = normal, -1 backwards
+ unsigned int length; // in samples;
+
+ static std::vector window;
+ static float windowSum;
+
+ int channels;
+ float duration; //in secs
+ int samplerate;
+ std::vector buffers;
+ std::vector sources;
+
+ // fft structures
+ std::vector > fftBuffers;
+ kiss_fftr_cfg fftCfg;
+ std::vector windowedSignal;
+ std::vector bins;
+ std::vector