diff --git a/.github/workflows/libzedmd.yml b/.github/workflows/libzedmd.yml index 5a5bb57..5a5324f 100644 --- a/.github/workflows/libzedmd.yml +++ b/.github/workflows/libzedmd.yml @@ -1,7 +1,6 @@ name: libzedmd on: push: - pull_request: defaults: @@ -15,7 +14,7 @@ jobs: outputs: tag: ${{ steps.version.outputs.tag }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - id: version @@ -28,7 +27,7 @@ jobs: echo "tag=${TAG}" >> $GITHUB_OUTPUT build: - name: Build libzedmd-${{ matrix.platform }} + name: Build libzedmd-${{ matrix.platform }}-${{ matrix.arch }} runs-on: ${{ matrix.os }} needs: [ version ] strategy: @@ -36,96 +35,168 @@ jobs: matrix: include: - os: windows-latest - platform: win-x64 - platform-name: x64 + platform: win + arch: x64 - os: windows-latest - platform: win-x86 - platform-name: Win32 - - os: macos-latest - platform: macOS-x64 - - os: macos-latest - platform: macOS-arm64 + platform: win + arch: x86 - os: macos-latest - platform: ios-arm64 + platform: macos + arch: arm64 - os: macos-latest - platform: tvos-arm64 + platform: macos + arch: x64 - os: ubuntu-latest - platform: linux-x64 + platform: linux + arch: x64 - os: ubuntu-latest - platform: android-arm64-v8a + platform: linux + arch: aarch64 + - os: ubuntu-latest + platform: android + arch: arm64-v8a + - os: macos-latest + platform: ios + arch: arm64 + - os: macos-latest + platform: tvos + arch: arm64 steps: - - uses: actions/checkout@v3 - - name: Checkout libserialport - uses: actions/checkout@v3 - with: - repository: PPUC/libserialport - path: libserialport - - run: mv libserialport ../libserialport - - name: Build libzedmd-${{ matrix.platform }} + - uses: actions/checkout@v4 + - if: (matrix.platform == 'win') + name: Add msbuild to path (win runner) + uses: microsoft/setup-msbuild@v1.1 + - if: (matrix.platform == 'macos') + name: Add autoconf and automake (mac runner) run: | - if [[ "${{ matrix.os }}" == "windows-latest" ]]; then - if [[ "${{ matrix.platform-name }}" == "Win32" ]]; then - cmake -G "Visual Studio 17 2022" -A ${{ matrix.platform-name }} -B build -DUSE_WIN32=ON - else - cmake -G "Visual Studio 17 2022" -A ${{ matrix.platform-name }} -B build - fi - cmake --build build --config Release - elif [[ "${{ matrix.os }}" == "macos-latest" ]]; then - if [[ "${{ matrix.platform }}" == "macOS-arm64" ]]; then - cmake -DCMAKE_BUILD_TYPE=Release -B build/Release -DUSE_OSXARM=ON - elif [[ "${{ matrix.platform }}" == "macOS-x64" ]]; then - cmake -DCMAKE_BUILD_TYPE=Release -B build/Release -DUSE_OSXINTEL=ON - elif [[ "${{ matrix.platform }}" == "ios-arm64" ]]; then - cmake -DCMAKE_BUILD_TYPE=Release -B build/Release -DUSE_IOS=ON - elif [[ "${{ matrix.platform }}" == "tvos-arm64" ]]; then - cmake -DCMAKE_BUILD_TYPE=Release -B build/Release -DUSE_TVOS=ON - fi - cmake --build build/Release - elif [[ "${{ matrix.os }}" == "ubuntu-latest" ]]; then - if [[ "${{ matrix.platform }}" == "android-arm64-v8a" ]]; then - cmake -DCMAKE_BUILD_TYPE=Release -B build/Release -DUSE_ANDROID=ON - else - cmake -DCMAKE_BUILD_TYPE=Release -B build/Release - fi - cmake --build build/Release + brew install autoconf automake + - if: (!(matrix.platform == 'linux' && matrix.arch == 'aarch64')) + name: Build libzedmd-${{ matrix.platform }}-${{ matrix.arch }} + run: | + ./platforms/${{ matrix.platform }}/${{ matrix.arch }}/external.sh + if [[ "${{ matrix.platform }}" == "win" ]]; then + if [[ "${{ matrix.arch }}" == "x86" ]]; then + cmake -G "Visual Studio 17 2022" -A Win32 -DPLATFORM=${{ matrix.platform }} -DARCH=${{ matrix.arch }} -B build + else + cmake -G "Visual Studio 17 2022" -DPLATFORM=${{ matrix.platform }} -DARCH=${{ matrix.arch }} -B build + fi + cmake --build build --config Release + else + if [[ "$(uname)" == "Darwin" ]]; then + NUM_PROCS=$(sysctl -n hw.ncpu) + else + NUM_PROCS=$(nproc) + fi + cmake -DCMAKE_BUILD_TYPE=Release -DPLATFORM=${{ matrix.platform }} -DARCH=${{ matrix.arch }} -B build + cmake --build build -- -j${NUM_PROCS} fi - - run: | + - if: (matrix.platform == 'linux' && matrix.arch == 'aarch64') + name: Build libzedmd-${{ matrix.platform }}-${{ matrix.arch }} (arm runner) + uses: pguyot/arm-runner-action@v2 + with: + base_image: raspios_lite_arm64:latest + image_additional_mb: 4096 + cpu: cortex-a53 + cpu_info: cpuinfo/raspberrypi_zero2_w_arm64 + bind_mount_repository: true + commands: | + apt-get update -y --allow-releaseinfo-change + apt-get install --no-install-recommends -y pkg-config cmake autoconf automake libtool + ./platforms/${{ matrix.platform }}/${{ matrix.arch }}/external.sh + NUM_PROCS=$(nproc) + cmake -DCMAKE_BUILD_TYPE=Release -DPLATFORM=${{ matrix.platform }} -DARCH=${{ matrix.arch }} -B build + cmake --build build -- -j${NUM_PROCS} + - name: Prepare artifacts + id: artifacts + run: | mkdir tmp - if [[ "${{ matrix.os }}" == "windows-latest" ]]; then - cp build/Release/zedmd* tmp + if [[ "${{ matrix.platform }}" == "win" ]]; then + ARTIFACT_PATH="tmp" + if [[ "${{ matrix.arch }}" == "x86" ]]; then + cp build/Release/zedmd.lib tmp + cp build/Release/zedmd.dll tmp + else + cp build/Release/zedmd64.lib tmp + cp build/Release/zedmd64.dll tmp + fi + cp build/Release/zedmd_static.lib tmp + cp build/Release/libserialport.lib tmp + cp build/Release/libserialport.dll tmp + cp build/Release/zedmd_test_s.exe tmp + cp build/Release/zedmd_test.exe tmp else - cp build/Release/libzedmd* tmp + ARTIFACT_PATH="libzedmd-${{ needs.version.outputs.tag }}-${{ matrix.platform }}-${{ matrix.arch }}.tar.gz" + if [[ "${{ matrix.platform }}" == "macos" ]]; then + cp build/libzedmd.a tmp + cp build/libzedmd.*.dylib tmp + cp build/libserialport.dylib tmp + cp build/zedmd_test_s tmp + cp build/zedmd_test tmp + elif [[ "${{ matrix.platform }}" == "linux" ]]; then + cp build/libzedmd.a tmp + cp build/libzedmd.so.* tmp + cp build/libserialport.so.* tmp + cp build/zedmd_test_s tmp + cp build/zedmd_test tmp + elif [[ "${{ matrix.platform }}" == "ios" || "${{ matrix.platform }}" == "tvos" ]]; then + cp build/libzedmd.a tmp + cp build/libzedmd.*.dylib tmp + elif [[ "${{ matrix.platform }}" == "android" ]]; then + cp build/libzedmd.a tmp + cp build/libzedmd.so tmp + fi + cd tmp + tar -czvf ../${ARTIFACT_PATH} * fi - - uses: actions/upload-artifact@v3 + echo "artifact_path=${ARTIFACT_PATH}" >> $GITHUB_OUTPUT + - name: Upload artifacts + uses: actions/upload-artifact@v3 with: - name: libzedmd-${{ needs.version.outputs.tag }}-${{ matrix.platform }} - path: tmp + name: libzedmd-${{ needs.version.outputs.tag }}-${{ matrix.platform }}-${{ matrix.arch }} + path: ${{ steps.artifacts.outputs.artifact_path }} post-build: runs-on: macos-latest needs: [ version, build ] - name: Build libzedmd-macOS + name: Build libzedmd-macos steps: - uses: actions/download-artifact@v3 - - run: | - mkdir libzedmd-${{ needs.version.outputs.tag }}-macOS - lipo -create -output libzedmd-${{ needs.version.outputs.tag }}-macOS/libzedmd.dylib \ - libzedmd-${{ needs.version.outputs.tag }}-macOS-x64/libzedmd.dylib \ - libzedmd-${{ needs.version.outputs.tag }}-macOS-arm64/libzedmd.dylib - - uses: actions/upload-artifact@v3 + - name: Unpack artifacts + run: | + cd libzedmd-${{ needs.version.outputs.tag }}-macos-x64 + tar -xzvf libzedmd-${{ needs.version.outputs.tag }}-macos-x64.tar.gz + cd .. + cd libzedmd-${{ needs.version.outputs.tag }}-macos-arm64 + tar -xzvf libzedmd-${{ needs.version.outputs.tag }}-macos-arm64.tar.gz + - name: Combine macos architectures + run: | + mkdir tmp + lipo -create -output tmp/libzedmd-${{ needs.version.outputs.tag }}.dylib \ + libzedmd-${{ needs.version.outputs.tag }}-macos-arm64/libzedmd.${{ needs.version.outputs.tag }}.dylib \ + libzedmd-${{ needs.version.outputs.tag }}-macos-x64/libzedmd.${{ needs.version.outputs.tag }}.dylib + lipo -create -output tmp/libserialport.dylib \ + libzedmd-${{ needs.version.outputs.tag }}-macos-arm64/libserialport.dylib \ + libzedmd-${{ needs.version.outputs.tag }}-macos-x64/libserialport.dylib + lipo -create -output tmp/zedmd_test \ + libzedmd-${{ needs.version.outputs.tag }}-macos-arm64/zedmd_test \ + libzedmd-${{ needs.version.outputs.tag }}-macos-x64/zedmd_test + lipo -create -output tmp/zedmd_test_s \ + libzedmd-${{ needs.version.outputs.tag }}-macos-arm64/zedmd_test_s \ + libzedmd-${{ needs.version.outputs.tag }}-macos-x64/zedmd_test_s + - name: Prepare artifacts + run: | + cd tmp + tar -czvf ../libzedmd-${{ needs.version.outputs.tag }}-macos.tar.gz * + - name: Upload artifacts + uses: actions/upload-artifact@v3 with: - name: libzedmd-${{ needs.version.outputs.tag }}-macOS - path: libzedmd-${{ needs.version.outputs.tag }}-macOS + name: libzedmd-${{ needs.version.outputs.tag }}-macos + path: libzedmd-${{ needs.version.outputs.tag }}-macos.tar.gz - name: Package if: startsWith(github.ref, 'refs/tags/') run: | zip -r libzedmd-${{ needs.version.outputs.tag }}-win-x64.zip libzedmd-${{ needs.version.outputs.tag }}-win-x64 - zip -r libzedmd-${{ needs.version.outputs.tag }}-win-x86.zip libzedmd-${{ needs.version.outputs.tag }}-win-x86 - zip -r libzedmd-${{ needs.version.outputs.tag }}-ios-arm64.zip libzedmd-${{ needs.version.outputs.tag }}-ios-arm64 - zip -r libzedmd-${{ needs.version.outputs.tag }}-tvos-arm64.zip libzedmd-${{ needs.version.outputs.tag }}-tvos-arm64 - zip -r libzedmd-${{ needs.version.outputs.tag }}-linux-x64.zip libzedmd-${{ needs.version.outputs.tag }}-linux-x64 - zip -r libzedmd-${{ needs.version.outputs.tag }}-android-arm64-v8a.zip libzedmd-${{ needs.version.outputs.tag }}-android-arm64-v8a - zip -r libzedmd-${{ needs.version.outputs.tag }}-macOS.zip libzedmd-${{ needs.version.outputs.tag }}-macOS + zip -r libzedmd-${{ needs.version.outputs.tag }}-win-x86.zip libzedmd-${{ needs.version.outputs.tag }}-win-x86 - name: Release uses: softprops/action-gh-release@v1 if: startsWith(github.ref, 'refs/tags/') @@ -134,8 +205,11 @@ jobs: files: | libzedmd-${{ needs.version.outputs.tag }}-win-x64.zip libzedmd-${{ needs.version.outputs.tag }}-win-x86.zip - libzedmd-${{ needs.version.outputs.tag }}-ios-arm64.zip - libzedmd-${{ needs.version.outputs.tag }}-tvos-arm64.zip - libzedmd-${{ needs.version.outputs.tag }}-linux-x64.zip - libzedmd-${{ needs.version.outputs.tag }}-android-arm64-v8a.zip - libzedmd-${{ needs.version.outputs.tag }}-macOS.zip + libzedmd-${{ needs.version.outputs.tag }}-macos-arm64/libzedmd-${{ needs.version.outputs.tag }}-macos-arm64.tar.gz + libzedmd-${{ needs.version.outputs.tag }}-macos-x64/libzedmd-${{ needs.version.outputs.tag }}-macos-x64.tar.gz + libzedmd-${{ needs.version.outputs.tag }}-macos.tar.gz + libzedmd-${{ needs.version.outputs.tag }}-linux-x64/libzedmd-${{ needs.version.outputs.tag }}-linux-x64.tar.gz + libzedmd-${{ needs.version.outputs.tag }}-linux-aarch64/libzedmd-${{ needs.version.outputs.tag }}-linux-aarch64.tar.gz + libzedmd-${{ needs.version.outputs.tag }}-ios-arm64/libzedmd-${{ needs.version.outputs.tag }}-ios-arm64.tar.gz + libzedmd-${{ needs.version.outputs.tag }}-tvos-arm64/libzedmd-${{ needs.version.outputs.tag }}-tvos-arm64.tar.gz + libzedmd-${{ needs.version.outputs.tag }}-android-arm64-v8a/libzedmd-${{ needs.version.outputs.tag }}-android-arm64-v8a.tar.gz \ No newline at end of file diff --git a/.gitignore b/.gitignore index e2d79ae..4e64173 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,8 @@ /.vs/ /.vscode/ CMakeSettings.json +external.sh +external +third-party/runtime-libs +third-party/build-libs +third-party/include/libserialport.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 4556c65..9f82c30 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,17 +1,22 @@ -cmake_minimum_required(VERSION 3.18) +cmake_minimum_required(VERSION 3.25) -option(USE_OSXARM "macOS arm64" OFF) -option(USE_OSXINTEL "macOS x86_64" OFF) -option(USE_IOS "ios" OFF) -option(USE_TVOS "tvos" OFF) -option(USE_ANDROID "android" OFF) -option(USE_WIN32 "Win32" OFF) +set(PLATFORM "win" CACHE STRING "Platform") +set(ARCH "x64" CACHE STRING "Arch") -if(USE_IOS) +option(BUILD_SHARED "Option to build shared library" ON) +option(BUILD_STATIC "Option to build static library" ON) + +message(STATUS "PLATFORM: ${PLATFORM}") +message(STATUS "ARCH: ${ARCH}") + +message(STATUS "BUILD_SHARED: ${BUILD_SHARED}") +message(STATUS "BUILD_STATIC: ${BUILD_STATIC}") + +if(PLATFORM STREQUAL "ios") set(CMAKE_SYSTEM_NAME iOS) -elseif(USE_TVOS) +elseif(PLATFORM STREQUAL "tvos") set(CMAKE_SYSTEM_NAME tvOS) -elseif(USE_ANDROID) +elseif(PLATFORM STREQUAL "android") set(CMAKE_SYSTEM_NAME Android) set(CMAKE_SYSTEM_VERSION 30) set(CMAKE_ANDROID_ARCH_ABI arm64-v8a) @@ -26,102 +31,169 @@ string(REGEX MATCH "ZEDMD_VERSION_PATCH[ ]+([0-9]+)" _tmp ${version}) set(VERSION_PATCH "${CMAKE_MATCH_1}") project(zedmd VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}" - DESCRIPTION "Cross-platform library for communicating with ZeDMD.") + DESCRIPTION "Cross-platform library for communicating with ZeDMD.") -set(LIB_NAME "zedmd") -if(USE_OSXARM) +if(PLATFORM STREQUAL "win") + if(ARCH STREQUAL "x86") + add_compile_definitions(WIN32) + endif() +elseif(PLATFORM STREQUAL "macos") + set(CMAKE_OSX_DEPLOYMENT_TARGET 13.0) + if (ARCH STREQUAL "arm64") + set(CMAKE_OSX_ARCHITECTURES arm64) + elseif(ARCH STREQUAL "x64") + set(CMAKE_OSX_ARCHITECTURES x86_64) + endif() + set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) + set(CMAKE_INSTALL_RPATH "@executable_path") +elseif(PLATFORM STREQUAL "ios" OR PLATFORM STREQUAL "tvos") + set(CMAKE_OSX_DEPLOYMENT_TARGET 16.0) set(CMAKE_OSX_ARCHITECTURES arm64) -elseif(USE_OSXINTEL) - set(CMAKE_OSX_ARCHITECTURES x86_64) -elseif(USE_IOS OR USE_TVOS) - set(CMAKE_OSX_DEPLOYMENT_TARGET 16.0) - set(CMAKE_OSX_ARCHITECTURES arm64) - set(CMAKE_POSITION_INDEPENDENT_CODE ON) - set(CMAKE_C_FLAGS -fembed-bitcode) - set(CMAKE_CXX_FLAGS -fembed-bitcode) -elseif(USE_WIN32) - add_compile_definitions(WIN32) -elseif(USE_ANDROID) -else() - set(LIB_NAME "zedmd64") +elseif(PLATFORM STREQUAL "linux" OR PLATFORM STREQUAL "android") + set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) + set(CMAKE_INSTALL_RPATH "$ORIGIN") endif() set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_VISIBILITY_PRESET hidden) set(CMAKE_C_STANDARD 99) -set(CMAKE_C_VISIBILITY_PRESET hidden) - -set(MINIZ_SOURCES - src/miniz/miniz.h - src/miniz/miniz.c -) - -set(KOMIHASH_SOURCES - src/komihash/komihash.h -) -if(NOT EXISTS ${SERIALPORT_LIBRARIES}) - get_filename_component(SERIALPORT_CMAKE ../libserialport/CMakeLists.txt ABSOLUTE) - if(EXISTS ${SERIALPORT_CMAKE}) - message(STATUS "enabling SerialPort") - add_subdirectory(../libserialport libserialport) - set (SERIALPORT_LIBRARIES SerialPort) - else() - message(STATUS "libserialport source not found in ../libserialport") - endif() -endif() +set(CMAKE_CXX_VISIBILITY_PRESET hidden) +set(CMAKE_C_VISIBILITY_PRESET hidden) -set(LIBRARY_SOURCES - ${MINIZ_SOURCES} - ${KOMIHASH_SOURCES} +set(ZEDMD_SOURCES src/ZeDMDComm.h src/ZeDMDComm.cpp src/ZeDMDWiFi.h src/ZeDMDWiFi.cpp src/ZeDMD.h src/ZeDMD.cpp + third-party/include/komihash/komihash.h + third-party/include/miniz/miniz.h + third-party/include/miniz/miniz.c ) -set(INCLUDE_DIRS +set(ZEDMD_INCLUDE_DIRS src + third-party/include ) -include_directories(AFTER src) - -if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) - if(NOT USE_IOS AND NOT USE_TVOS) - add_library(zedmd_shared SHARED ${LIBRARY_SOURCES}) - set_target_properties(zedmd_shared PROPERTIES - OUTPUT_NAME ${LIB_NAME} - VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH} - LINK_FLAGS_RELEASE -s - ) - target_include_directories(zedmd_shared PUBLIC ${INCLUDE_DIRS}) - target_link_libraries(zedmd_shared LINK_PUBLIC - ${SERIALPORT_LIBRARIES} - ) - if(WIN32) - target_link_libraries(zedmd_shared PRIVATE ws2_32) - endif() - install(TARGETS zedmd_shared - LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/lib - ) - endif() - - add_library(zedmd_static STATIC ${LIBRARY_SOURCES}) - set_target_properties(zedmd_static PROPERTIES OUTPUT_NAME "zedmd") - target_include_directories(zedmd_static PUBLIC ${INCLUDE_DIRS}) - target_link_libraries(zedmd_static LINK_PUBLIC - ${SERIALPORT_LIBRARIES} +if(BUILD_SHARED) + add_library(zedmd_shared SHARED ${ZEDMD_SOURCES}) + + target_include_directories(zedmd_shared PUBLIC ${ZEDMD_INCLUDE_DIRS}) + + if(PLATFORM STREQUAL "win") + target_link_directories(zedmd_shared PUBLIC + third-party/build-libs/${PLATFORM}/${ARCH} + third-party/runtime-libs/${PLATFORM}/${ARCH} + ) + target_link_libraries(zedmd_shared PUBLIC libserialport ws2_32) + elseif(PLATFORM STREQUAL "macos") + target_link_directories(zedmd_shared PUBLIC + third-party/runtime-libs/${PLATFORM}/${ARCH} + ) + target_link_libraries(zedmd_shared PUBLIC serialport) + elseif(PLATFORM STREQUAL "linux") + target_link_directories(zedmd_shared PUBLIC + third-party/runtime-libs/${PLATFORM}/${ARCH} + ) + target_link_libraries(zedmd_shared PUBLIC -l:libserialport.so.0) + endif() + + if(PLATFORM STREQUAL "win" AND ARCH STREQUAL "x64") + set(ZEDMD_OUTPUT_NAME "zedmd64") + else() + set(ZEDMD_OUTPUT_NAME "zedmd") + endif() + + set_target_properties(zedmd_shared PROPERTIES + OUTPUT_NAME ${ZEDMD_OUTPUT_NAME} + VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH} ) - if(WIN32) - target_link_libraries(zedmd_static PRIVATE ws2_32) + + install(TARGETS zedmd_shared + LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/lib + ) + install(FILES src/ZeDMD.h DESTINATION ${CMAKE_INSTALL_PREFIX}/include) + + if(PLATFORM STREQUAL "win" OR PLATFORM STREQUAL "macos" OR PLATFORM STREQUAL "linux") + add_executable(zedmd_test + src/test.cpp + ) + + target_link_libraries(zedmd_test PUBLIC zedmd_shared) + + if(PLATFORM STREQUAL "win") + add_custom_command(TARGET zedmd_test POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_SOURCE_DIR}/third-party/build-libs/${PLATFORM}/${ARCH}/libserialport.lib" "$" + COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_SOURCE_DIR}/third-party/runtime-libs/${PLATFORM}/${ARCH}/libserialport.dll" "$" + ) + elseif(PLATFORM STREQUAL "macos") + add_custom_command(TARGET zedmd_test POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_SOURCE_DIR}/third-party/runtime-libs/${PLATFORM}/${ARCH}/libserialport.dylib" "$" + ) + elseif(PLATFORM STREQUAL "linux") + add_custom_command(TARGET zedmd_test POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_SOURCE_DIR}/third-party/runtime-libs/${PLATFORM}/${ARCH}/libserialport.so.0" "$" + ) + endif() + endif() +endif() + +if(BUILD_STATIC) + add_library(zedmd_static STATIC ${ZEDMD_SOURCES}) + + target_include_directories(zedmd_static PUBLIC ${ZEDMD_INCLUDE_DIRS}) + + if(PLATFORM STREQUAL "win") + set_target_properties(zedmd_static PROPERTIES + OUTPUT_NAME "zedmd_static" + ) + else() + set_target_properties(zedmd_static PROPERTIES + OUTPUT_NAME "zedmd" + ) endif() + install(TARGETS zedmd_static LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/lib ) install(FILES src/ZeDMD.h DESTINATION ${CMAKE_INSTALL_PREFIX}/include) -else() - add_library(ZeDMD ${LIBRARY_SOURCES}) -endif() \ No newline at end of file + if(PLATFORM STREQUAL "win" OR PLATFORM STREQUAL "macos" OR PLATFORM STREQUAL "linux") + add_executable(zedmd_test_s + src/test.cpp + ) + + if(PLATFORM STREQUAL "win") + target_link_directories(zedmd_test_s PUBLIC + third-party/build-libs/${PLATFORM}/${ARCH} + third-party/runtime-libs/${PLATFORM}/${ARCH} + ) + target_link_libraries(zedmd_test_s PUBLIC zedmd_static libserialport ws2_32) + + add_custom_command(TARGET zedmd_test_s POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_SOURCE_DIR}/third-party/build-libs/${PLATFORM}/${ARCH}/libserialport.lib" "$" + COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_SOURCE_DIR}/third-party/runtime-libs/${PLATFORM}/${ARCH}/libserialport.dll" "$" + ) + elseif(PLATFORM STREQUAL "macos") + target_link_directories(zedmd_test_s PUBLIC + third-party/runtime-libs/${PLATFORM}/${ARCH} + ) + target_link_libraries(zedmd_test_s PUBLIC zedmd_static serialport) + + add_custom_command(TARGET zedmd_test_s POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_SOURCE_DIR}/third-party/runtime-libs/${PLATFORM}/${ARCH}/libserialport.dylib" "$" + ) + elseif(PLATFORM STREQUAL "linux") + target_link_directories(zedmd_test_s PUBLIC + third-party/runtime-libs/${PLATFORM}/${ARCH} + ) + target_link_libraries(zedmd_test_s PUBLIC zedmd_static -l:libserialport.so.0) + + add_custom_command(TARGET zedmd_test_s POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_SOURCE_DIR}/third-party/runtime-libs/${PLATFORM}/${ARCH}/libserialport.so.0" "$" + ) + endif() + endif() +endif() diff --git a/platforms/android/arm64-v8a/external.sh b/platforms/android/arm64-v8a/external.sh new file mode 100755 index 0000000..9e618fa --- /dev/null +++ b/platforms/android/arm64-v8a/external.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -e + +rm -rf mkdir +mkdir mkdir +cd mkdir + +# +# andoroid arm64-v8a has no external dependencies +# diff --git a/platforms/ios/arm64/external.sh b/platforms/ios/arm64/external.sh new file mode 100755 index 0000000..343031f --- /dev/null +++ b/platforms/ios/arm64/external.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -e + +rm -rf mkdir +mkdir mkdir +cd mkdir + +# +# ios has no external dependencies +# diff --git a/platforms/linux/aarch64/external.sh b/platforms/linux/aarch64/external.sh new file mode 100755 index 0000000..b8b4ff1 --- /dev/null +++ b/platforms/linux/aarch64/external.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +set -e + +LIBSERIALPORT_SHA=fd20b0fc5a34cd7f776e4af6c763f59041de223b + +NUM_PROCS=$(nproc) + +echo "Building libraries..." +echo " LIBSERIALPORT_SHA: ${LIBSERIALPORT_SHA}" +echo " NUM_PROCS: ${NUM_PROCS}" +echo "" + +rm -rf external +mkdir external +cd external + +# +# build libserialport and copy to platform/arch +# + +curl -sL https://github.com/sigrokproject/libserialport/archive/${LIBSERIALPORT_SHA}.zip -o libserialport.zip +unzip libserialport.zip +cd libserialport-$LIBSERIALPORT_SHA +cp libserialport.h ../../third-party/include +./autogen.sh +./configure +make -j${NUM_PROCS} +cp .libs/libserialport.a ../../third-party/build-libs/linux/aarch64 +cp .libs/libserialport.so.0 ../../third-party/runtime-libs/linux/aarch64 +cd .. diff --git a/platforms/linux/x64/external.sh b/platforms/linux/x64/external.sh new file mode 100755 index 0000000..17027fa --- /dev/null +++ b/platforms/linux/x64/external.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +set -e + +LIBSERIALPORT_SHA=fd20b0fc5a34cd7f776e4af6c763f59041de223b + +NUM_PROCS=$(nproc) + +echo "Building libraries..." +echo " LIBSERIALPORT_SHA: ${LIBSERIALPORT_SHA}" +echo " NUM_PROCS: ${NUM_PROCS}" +echo "" + +rm -rf external +mkdir external +cd external + +# +# build libserialport and copy to platform/arch +# + +curl -sL https://github.com/sigrokproject/libserialport/archive/${LIBSERIALPORT_SHA}.zip -o libserialport.zip +unzip libserialport.zip +cd libserialport-$LIBSERIALPORT_SHA +cp libserialport.h ../../third-party/include +./autogen.sh +./configure +make -j${NUM_PROCS} +cp .libs/libserialport.a ../../third-party/build-libs/linux/x64 +cp .libs/libserialport.so.0 ../../third-party/runtime-libs/linux/x64 +cd .. \ No newline at end of file diff --git a/platforms/macos/arm64/external.sh b/platforms/macos/arm64/external.sh new file mode 100755 index 0000000..b77c791 --- /dev/null +++ b/platforms/macos/arm64/external.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +set -e + +LIBSERIALPORT_SHA=fd20b0fc5a34cd7f776e4af6c763f59041de223b + +NUM_PROCS=$(sysctl -n hw.ncpu) + +echo "Building libraries..." +echo " LIBSERIALPORT_SHA: ${LIBSERIALPORT_SHA}" +echo " NUM_PROCS: ${NUM_PROCS}" +echo "" + +rm -rf external +mkdir external +cd external + +# +# build libserialport and copy to platform/arch +# + +curl -sL https://github.com/sigrokproject/libserialport/archive/${LIBSERIALPORT_SHA}.zip -o libserialport.zip +unzip libserialport.zip +cd libserialport-$LIBSERIALPORT_SHA +cp libserialport.h ../../third-party/include +./autogen.sh +./configure --host=aarch64-apple-darwin CFLAGS="-arch arm64" LDFLAGS="-Wl,-install_name,@rpath/libserialport.dylib" +make -j${NUM_PROCS} +cp .libs/libserialport.a ../../third-party/build-libs/macos/arm64 +cp .libs/libserialport.dylib ../../third-party/runtime-libs/macos/arm64 +cd .. diff --git a/platforms/macos/x64/external.sh b/platforms/macos/x64/external.sh new file mode 100755 index 0000000..2128d61 --- /dev/null +++ b/platforms/macos/x64/external.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +set -e + +LIBSERIALPORT_SHA=fd20b0fc5a34cd7f776e4af6c763f59041de223b + +NUM_PROCS=$(sysctl -n hw.ncpu) + +echo "Building libraries..." +echo " LIBSERIALPORT_SHA: ${LIBSERIALPORT_SHA}" +echo " NUM_PROCS: ${NUM_PROCS}" +echo "" + +rm -rf external +mkdir external +cd external + +# +# build libserialport and copy to platform/arch +# + +curl -sL https://github.com/sigrokproject/libserialport/archive/${LIBSERIALPORT_SHA}.zip -o libserialport.zip +unzip libserialport.zip +cd libserialport-$LIBSERIALPORT_SHA +cp libserialport.h ../../third-party/include +./autogen.sh +./configure --host=x86_64-apple-darwin CFLAGS="-arch x86_64" LDFLAGS="-Wl,-install_name,@rpath/libserialport.dylib" +make -j${NUM_PROCS} +cp .libs/libserialport.a ../../third-party/build-libs/macos/x64 +cp .libs/libserialport.dylib ../../third-party/runtime-libs/macos/x64 +cd .. diff --git a/platforms/tvos/arm64/external.sh b/platforms/tvos/arm64/external.sh new file mode 100755 index 0000000..0d98a39 --- /dev/null +++ b/platforms/tvos/arm64/external.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -e + +rm -rf mkdir +mkdir mkdir +cd mkdir + +# +# tvos has no external dependencies +# diff --git a/platforms/win/x64/external.sh b/platforms/win/x64/external.sh new file mode 100755 index 0000000..15edd52 --- /dev/null +++ b/platforms/win/x64/external.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +set -e + +LIBSERIALPORT_SHA=fd20b0fc5a34cd7f776e4af6c763f59041de223b + +echo "Building libraries..." +echo " LIBSERIALPORT_SHA: ${LIBSERIALPORT_SHA}" +echo "" + +rm -rf external +mkdir external +cd external + +# +# build libserialport and copy to platform/arch +# + +curl -sL https://github.com/sigrokproject/libserialport/archive/${LIBSERIALPORT_SHA}.zip -o libserialport.zip +unzip libserialport.zip +cd libserialport-$LIBSERIALPORT_SHA +cp libserialport.h ../../third-party/include +msbuild.exe libserialport.sln -p:Configuration=Release -p:Platform=x64 +cp x64/Release/libserialport.lib ../../third-party/build-libs/win/x64 +cp x64/Release/libserialport.dll ../../third-party/runtime-libs/win/x64 +cd .. \ No newline at end of file diff --git a/platforms/win/x86/external.sh b/platforms/win/x86/external.sh new file mode 100755 index 0000000..27779cd --- /dev/null +++ b/platforms/win/x86/external.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +set -e + +LIBSERIALPORT_SHA=fd20b0fc5a34cd7f776e4af6c763f59041de223b + +echo "Building libraries..." +echo " LIBSERIALPORT_SHA: ${LIBSERIALPORT_SHA}" +echo "" + +rm -rf external +mkdir external +cd external + +# +# build libserialport and copy to platform/arch +# + +curl -sL https://github.com/sigrokproject/libserialport/archive/${LIBSERIALPORT_SHA}.zip -o libserialport.zip +unzip libserialport.zip +cd libserialport-$LIBSERIALPORT_SHA +cp libserialport.h ../../third-party/include +msbuild.exe libserialport.sln -p:Configuration=Release -p:Platform=x86 +cp Release/libserialport.lib ../../third-party/build-libs/win/x86 +cp Release/libserialport.dll ../../third-party/runtime-libs/win/x86 +cd .. \ No newline at end of file diff --git a/src/ZeDMD.cpp b/src/ZeDMD.cpp index eaa3e11..62446a0 100644 --- a/src/ZeDMD.cpp +++ b/src/ZeDMD.cpp @@ -2,6 +2,8 @@ #include "ZeDMDComm.h" #include "ZeDMDWiFi.h" +#include + ZeDMD::ZeDMD() { m_romWidth = 0; @@ -45,13 +47,6 @@ void ZeDMD::SetLogMessageCallback(ZeDMD_LogMessageCallback callback, const void m_pZeDMDWiFi->SetLogMessageCallback(callback, userData); } -#ifdef __ANDROID__ -void ZeDMD::SetAndroidGetJNIEnvFunc(ZeDMD_AndroidGetJNIEnvFunc func) -{ - m_pZeDMDComm->SetAndroidGetJNIEnvFunc(func); -} -#endif - void ZeDMD::Close() { m_pZeDMDComm->Disconnect(); @@ -831,3 +826,37 @@ int ZeDMD::Scale(uint8_t *pScaledFrame, uint8_t *pFrame, uint8_t colors, uint16_ return bufferSize; } + +ZEDMDAPI ZeDMD *ZeDMD_GetInstance() { return new ZeDMD(); }; +ZEDMDAPI void ZeDMD_IgnoreDevice(ZeDMD *pZeDMD, const char *const ignore_device) { return pZeDMD->IgnoreDevice(ignore_device); }; +ZEDMDAPI void ZeDMD_SetDevice(ZeDMD *pZeDMD, const char *const device) { return pZeDMD->SetDevice(device); }; +ZEDMDAPI bool ZeDMD_Open(ZeDMD *pZeDMD) { return pZeDMD->Open(); }; +ZEDMDAPI bool ZeDMD_OpenWiFi(ZeDMD *pZeDMD, const char *ip, int port) { return pZeDMD->OpenWiFi(ip, port); }; +ZEDMDAPI void ZeDMD_Close(ZeDMD *pZeDMD) { return pZeDMD->Close(); }; + +ZEDMDAPI void ZeDMD_SetFrameSize(ZeDMD *pZeDMD, uint16_t width, uint16_t height) { return pZeDMD->SetFrameSize(width, height); }; +ZEDMDAPI void ZeDMD_SetPalette(ZeDMD *pZeDMD, uint8_t *pPalette, uint8_t numColors) { return pZeDMD->SetPalette(pPalette, numColors); }; +ZEDMDAPI void ZeDMD_SetDefaultPalette(ZeDMD *pZeDMD, uint8_t bitDepth) { return pZeDMD->SetDefaultPalette(bitDepth); }; +ZEDMDAPI uint8_t *ZeDMD_GetDefaultPalette(ZeDMD *pZeDMD, uint8_t bitDepth) { return pZeDMD->GetDefaultPalette(bitDepth); }; +ZEDMDAPI void ZeDMD_LedTest(ZeDMD *pZeDMD) { return pZeDMD->LedTest(); }; +ZEDMDAPI void ZeDMD_EnableDebug(ZeDMD *pZeDMD) { return pZeDMD->EnableDebug(); }; +ZEDMDAPI void ZeDMD_DisableDebug(ZeDMD *pZeDMD) { return pZeDMD->DisableDebug(); }; +ZEDMDAPI void ZeDMD_SetRGBOrder(ZeDMD *pZeDMD, uint8_t rgbOrder) { return pZeDMD->SetRGBOrder(rgbOrder); }; +ZEDMDAPI void ZeDMD_SetBrightness(ZeDMD *pZeDMD, uint8_t brightness) { return pZeDMD->SetBrightness(brightness); }; +ZEDMDAPI void ZeDMD_SaveSettings(ZeDMD *pZeDMD) { return pZeDMD->SaveSettings(); }; +ZEDMDAPI void ZeDMD_EnablePreDownscaling(ZeDMD *pZeDMD) { return pZeDMD->EnablePreDownscaling(); }; +ZEDMDAPI void ZeDMD_DisablePreDownscaling(ZeDMD *pZeDMD) { return pZeDMD->DisablePreDownscaling(); }; +ZEDMDAPI void ZeDMD_EnablePreUpscaling(ZeDMD *pZeDMD) { return pZeDMD->EnablePreUpscaling(); }; +ZEDMDAPI void ZeDMD_DisablePreUpscaling(ZeDMD *pZeDMD) { return pZeDMD->DisablePreUpscaling(); }; +ZEDMDAPI void ZeDMD_EnableUpscaling(ZeDMD *pZeDMD) { return pZeDMD->EnableUpscaling(); }; +ZEDMDAPI void ZeDMD_DisableUpscaling(ZeDMD *pZeDMD) { return pZeDMD->DisableUpscaling(); }; +ZEDMDAPI void ZeDMD_SetWiFiSSID(ZeDMD *pZeDMD, const char *const ssid) { return pZeDMD->SetWiFiSSID(ssid); }; +ZEDMDAPI void ZeDMD_SetWiFiPassword(ZeDMD *pZeDMD, const char *const password) { return pZeDMD->SetWiFiPassword(password); }; +ZEDMDAPI void ZeDMD_SetWiFiPort(ZeDMD *pZeDMD, int port) { return pZeDMD->SetWiFiPort(port); }; +ZEDMDAPI void ZeDMD_EnforceStreaming(ZeDMD *pZeDMD) { return pZeDMD->EnforceStreaming(); }; + +ZEDMDAPI void ZeDMD_ClearScreen(ZeDMD *pZeDMD) { return pZeDMD->ClearScreen(); }; +ZEDMDAPI void ZeDMD_RenderGray2(ZeDMD *pZeDMD, uint8_t *frame) { return pZeDMD->RenderGray2(frame); }; +ZEDMDAPI void ZeDMD_RenderGray4(ZeDMD *pZeDMD, uint8_t *frame) { return pZeDMD->RenderGray4(frame); }; +ZEDMDAPI void ZeDMD_RenderColoredGray6(ZeDMD *pZeDMD, uint8_t *frame, uint8_t *rotations) { return pZeDMD->RenderColoredGray6(frame, rotations); }; +ZEDMDAPI void ZeDMD_RenderRgb24(ZeDMD *pZeDMD, uint8_t *frame) { return pZeDMD->RenderRgb24(frame); }; \ No newline at end of file diff --git a/src/ZeDMD.h b/src/ZeDMD.h index 069f10f..0e69479 100644 --- a/src/ZeDMD.h +++ b/src/ZeDMD.h @@ -1,7 +1,7 @@ #pragma once #define ZEDMD_VERSION_MAJOR 0 // X Digits -#define ZEDMD_VERSION_MINOR 2 // Max 2 Digits +#define ZEDMD_VERSION_MINOR 3 // Max 2 Digits #define ZEDMD_VERSION_PATCH 0 // Max 2 Digits #define _ZEDMD_STR(x) #x @@ -14,7 +14,7 @@ #define ZEDMD_MAX_HEIGHT 64 #define ZEDMD_MAX_PALETTE 192 -#if defined(_WIN32) || defined(_WIN64) +#ifdef _MSC_VER #define ZEDMDAPI __declspec(dllexport) #define CALLBACK __stdcall #else @@ -26,10 +26,6 @@ #include #include -#ifdef __ANDROID__ -typedef void *(*ZeDMD_AndroidGetJNIEnvFunc)(); -#endif - typedef void(CALLBACK *ZeDMD_LogMessageCallback)(const char *format, va_list args, const void *userData); class ZeDMDComm; @@ -41,10 +37,6 @@ class ZEDMDAPI ZeDMD ZeDMD(); ~ZeDMD(); -#ifdef __ANDROID__ - void SetAndroidGetJNIEnvFunc(ZeDMD_AndroidGetJNIEnvFunc func); -#endif - void SetLogMessageCallback(ZeDMD_LogMessageCallback callback, const void *userData); void IgnoreDevice(const char *const ignore_device); @@ -121,45 +113,48 @@ class ZEDMDAPI ZeDMD 191, 95, 0, 204, 102, 0, 230, 114, 0, 255, 127, 0}; }; + #ifdef __cplusplus extern "C" { #endif - extern ZEDMDAPI ZeDMD *ZeDMD_GetInstance() { return new ZeDMD(); }; - extern ZEDMDAPI void ZeDMD_IgnoreDevice(ZeDMD *pZeDMD, const char *const ignore_device) { return pZeDMD->IgnoreDevice(ignore_device); }; - extern ZEDMDAPI void ZeDMD_SetDevice(ZeDMD *pZeDMD, const char *const device) { return pZeDMD->SetDevice(device); }; - extern ZEDMDAPI bool ZeDMD_Open(ZeDMD *pZeDMD) { return pZeDMD->Open(); }; - extern ZEDMDAPI bool ZeDMD_OpenWiFi(ZeDMD *pZeDMD, const char *ip, int port) { return pZeDMD->OpenWiFi(ip, port); }; - extern ZEDMDAPI void ZeDMD_Close(ZeDMD *pZeDMD) { return pZeDMD->Close(); }; - - extern ZEDMDAPI void ZeDMD_SetFrameSize(ZeDMD *pZeDMD, uint16_t width, uint16_t height) { return pZeDMD->SetFrameSize(width, height); }; - extern ZEDMDAPI void ZeDMD_SetPalette(ZeDMD *pZeDMD, uint8_t *pPalette, uint8_t numColors) { return pZeDMD->SetPalette(pPalette, numColors); }; - extern ZEDMDAPI void ZeDMD_SetDefaultPalette(ZeDMD *pZeDMD, uint8_t bitDepth) { return pZeDMD->SetDefaultPalette(bitDepth); }; - extern ZEDMDAPI uint8_t *ZeDMD_GetDefaultPalette(ZeDMD *pZeDMD, uint8_t bitDepth) { return pZeDMD->GetDefaultPalette(bitDepth); }; - extern ZEDMDAPI void ZeDMD_LedTest(ZeDMD *pZeDMD) { return pZeDMD->LedTest(); }; - extern ZEDMDAPI void ZeDMD_EnableDebug(ZeDMD *pZeDMD) { return pZeDMD->EnableDebug(); }; - extern ZEDMDAPI void ZeDMD_DisableDebug(ZeDMD *pZeDMD) { return pZeDMD->DisableDebug(); }; - extern ZEDMDAPI void ZeDMD_SetRGBOrder(ZeDMD *pZeDMD, uint8_t rgbOrder) { return pZeDMD->SetRGBOrder(rgbOrder); }; - extern ZEDMDAPI void ZeDMD_SetBrightness(ZeDMD *pZeDMD, uint8_t brightness) { return pZeDMD->SetBrightness(brightness); }; - extern ZEDMDAPI void ZeDMD_SaveSettings(ZeDMD *pZeDMD) { return pZeDMD->SaveSettings(); }; - extern ZEDMDAPI void ZeDMD_EnablePreDownscaling(ZeDMD *pZeDMD) { return pZeDMD->EnablePreDownscaling(); }; - extern ZEDMDAPI void ZeDMD_DisablePreDownscaling(ZeDMD *pZeDMD) { return pZeDMD->DisablePreDownscaling(); }; - extern ZEDMDAPI void ZeDMD_EnablePreUpscaling(ZeDMD *pZeDMD) { return pZeDMD->EnablePreUpscaling(); }; - extern ZEDMDAPI void ZeDMD_DisablePreUpscaling(ZeDMD *pZeDMD) { return pZeDMD->DisablePreUpscaling(); }; - extern ZEDMDAPI void ZeDMD_EnableUpscaling(ZeDMD *pZeDMD) { return pZeDMD->EnableUpscaling(); }; - extern ZEDMDAPI void ZeDMD_DisableUpscaling(ZeDMD *pZeDMD) { return pZeDMD->DisableUpscaling(); }; - extern ZEDMDAPI void ZeDMD_SetWiFiSSID(ZeDMD *pZeDMD, const char *const ssid) { return pZeDMD->SetWiFiSSID(ssid); }; - extern ZEDMDAPI void ZeDMD_SetWiFiPassword(ZeDMD *pZeDMD, const char *const password) { return pZeDMD->SetWiFiPassword(password); }; - extern ZEDMDAPI void ZeDMD_SetWiFiPort(ZeDMD *pZeDMD, int port) { return pZeDMD->SetWiFiPort(port); }; - extern ZEDMDAPI void ZeDMD_EnforceStreaming(ZeDMD *pZeDMD) { return pZeDMD->EnforceStreaming(); }; - - extern ZEDMDAPI void ZeDMD_ClearScreen(ZeDMD *pZeDMD) { return pZeDMD->ClearScreen(); }; - extern ZEDMDAPI void ZeDMD_RenderGray2(ZeDMD *pZeDMD, uint8_t *frame) { return pZeDMD->RenderGray2(frame); }; - extern ZEDMDAPI void ZeDMD_RenderGray4(ZeDMD *pZeDMD, uint8_t *frame) { return pZeDMD->RenderGray4(frame); }; - extern ZEDMDAPI void ZeDMD_RenderColoredGray6(ZeDMD *pZeDMD, uint8_t *frame, uint8_t *rotations) { return pZeDMD->RenderColoredGray6(frame, rotations); }; - extern ZEDMDAPI void ZeDMD_RenderRgb24(ZeDMD *pZeDMD, uint8_t *frame) { return pZeDMD->RenderRgb24(frame); }; + extern ZEDMDAPI ZeDMD *ZeDMD_GetInstance(); + extern ZEDMDAPI void ZeDMD_IgnoreDevice(ZeDMD *pZeDMD, const char *const ignore_device); + extern ZEDMDAPI void ZeDMD_SetDevice(ZeDMD *pZeDMD, const char *const device); + extern ZEDMDAPI bool ZeDMD_Open(ZeDMD *pZeDMD); + extern ZEDMDAPI bool ZeDMD_OpenWiFi(ZeDMD *pZeDMD, const char *ip, int port); + extern ZEDMDAPI void ZeDMD_Close(ZeDMD *pZeDMD); + + extern ZEDMDAPI void ZeDMD_SetFrameSize(ZeDMD *pZeDMD, uint16_t width, uint16_t height); + extern ZEDMDAPI void ZeDMD_SetPalette(ZeDMD *pZeDMD, uint8_t *pPalette, uint8_t numColors); + extern ZEDMDAPI void ZeDMD_SetDefaultPalette(ZeDMD *pZeDMD, uint8_t bitDepth); + extern ZEDMDAPI uint8_t *ZeDMD_GetDefaultPalette(ZeDMD *pZeDMD, uint8_t bitDepth); + extern ZEDMDAPI void ZeDMD_LedTest(ZeDMD *pZeDMD); + extern ZEDMDAPI void ZeDMD_EnableDebug(ZeDMD *pZeDMD); + extern ZEDMDAPI void ZeDMD_DisableDebug(ZeDMD *pZeDMD); + extern ZEDMDAPI void ZeDMD_SetRGBOrder(ZeDMD *pZeDMD, uint8_t rgbOrder); + extern ZEDMDAPI void ZeDMD_SetBrightness(ZeDMD *pZeDMD, uint8_t brightness); + extern ZEDMDAPI void ZeDMD_SaveSettings(ZeDMD *pZeDMD); + extern ZEDMDAPI void ZeDMD_EnablePreDownscaling(ZeDMD *pZeDMD); + extern ZEDMDAPI void ZeDMD_DisablePreDownscaling(ZeDMD *pZeDMD); + extern ZEDMDAPI void ZeDMD_EnablePreUpscaling(ZeDMD *pZeDMD); + extern ZEDMDAPI void ZeDMD_DisablePreUpscaling(ZeDMD *pZeDMD); + extern ZEDMDAPI void ZeDMD_EnableUpscaling(ZeDMD *pZeDMD); + extern ZEDMDAPI void ZeDMD_DisableUpscaling(ZeDMD *pZeDMD); + extern ZEDMDAPI void ZeDMD_SetWiFiSSID(ZeDMD *pZeDMD, const char *const ssid); + extern ZEDMDAPI void ZeDMD_SetWiFiPassword(ZeDMD *pZeDMD, const char *const password); + extern ZEDMDAPI void ZeDMD_SetWiFiPort(ZeDMD *pZeDMD, int port); + extern ZEDMDAPI void ZeDMD_EnforceStreaming(ZeDMD *pZeDMD); + + extern ZEDMDAPI void ZeDMD_ClearScreen(ZeDMD *pZeDMD); + extern ZEDMDAPI void ZeDMD_RenderGray2(ZeDMD *pZeDMD, uint8_t *frame); + extern ZEDMDAPI void ZeDMD_RenderGray4(ZeDMD *pZeDMD, uint8_t *frame); + extern ZEDMDAPI void ZeDMD_RenderColoredGray6(ZeDMD *pZeDMD, uint8_t *frame, uint8_t *rotations); + extern ZEDMDAPI void ZeDMD_RenderRgb24(ZeDMD *pZeDMD, uint8_t *frame); #ifdef __cplusplus } #endif + + diff --git a/src/ZeDMDComm.cpp b/src/ZeDMDComm.cpp index 91b4d34..cea1dae 100644 --- a/src/ZeDMDComm.cpp +++ b/src/ZeDMDComm.cpp @@ -1,29 +1,25 @@ #include "ZeDMDComm.h" + #include "miniz/miniz.h" #include "komihash/komihash.h" ZeDMDComm::ZeDMDComm() { m_pThread = NULL; +#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || defined(__ANDROID__)) + m_pSerialPort = NULL; +#endif } ZeDMDComm::~ZeDMDComm() { - if (m_pThread) - { + if (m_pThread) { m_pThread->join(); delete m_pThread; } } -#ifdef __ANDROID__ -void ZeDMDComm::SetAndroidGetJNIEnvFunc(ZeDMD_AndroidGetJNIEnvFunc func) -{ - m_serialPort.SetAndroidGetJNIEnvFunc(func); -} -#endif - void ZeDMDComm::SetLogMessageCallback(ZeDMD_LogMessageCallback callback, const void *userData) { m_logMessageCallback = callback; @@ -43,146 +39,127 @@ void ZeDMDComm::LogMessage(const char *format, ...) void ZeDMDComm::Run() { - m_pThread = new std::thread([this]() - { - LogMessage("ZeDMDComm run thread starting"); - int8_t lastStreamId = -1; - - while (m_serialPort.IsOpen()) - { - m_frameQueueMutex.lock(); - - if (m_frames.empty()) - { - m_delayedFrameMutex.lock(); - if (m_delayedFrameReady) { - while (m_delayedFrames.size() > 0) - { - ZeDMDFrame frame = m_delayedFrames.front(); - lastStreamId = frame.streamId; - m_frames.push(frame); - m_delayedFrames.pop(); - } - m_delayedFrameReady = false; - m_frameCounter = 1; - m_delayedFrameMutex.unlock(); - m_frameQueueMutex.unlock(); - continue; - } - m_delayedFrameMutex.unlock(); - m_frameQueueMutex.unlock(); - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - continue; - } - else - { - bool delay = false; - m_delayedFrameMutex.lock(); - delay = m_delayedFrameReady; - m_delayedFrameMutex.unlock(); - - if (delay && m_frameCounter > 2) { - while (m_frames.size() > 0) - { - m_frames.pop(); - } - m_frameCounter = 0; - m_frameQueueMutex.unlock(); - continue; - } - } - - ZeDMDFrame frame = m_frames.front(); - m_frames.pop(); - if (frame.streamId != -1) - { - if (frame.streamId != lastStreamId) - { - if (lastStreamId != -1) - { - m_frameCounter--; - } - - lastStreamId = frame.streamId; - } - } - else { - m_frameCounter--; - } - m_frameQueueMutex.unlock(); - - bool success = StreamBytes(&frame); - if (!success && frame.size < ZEDMD_COMM_FRAME_SIZE_COMMAND_LIMIT) - { - std::this_thread::sleep_for(std::chrono::milliseconds(8)); - // Try to send the command again, in case the wait for the (R)eady signal ran into a timeout. - success = StreamBytes(&frame); - } - - if (frame.data) - { - free(frame.data); - } - - if (!success) - { - std::this_thread::sleep_for(std::chrono::milliseconds(2)); - } - } - - LogMessage("ZeDMDComm run thread finished"); }); +#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || defined(__ANDROID__)) + m_pThread = new std::thread([this]() { + LogMessage("ZeDMDComm run thread starting"); + int8_t lastStreamId = -1; + + while (m_pSerialPort) { + m_frameQueueMutex.lock(); + + if (m_frames.empty()) { + m_delayedFrameMutex.lock(); + if (m_delayedFrameReady) { + while (m_delayedFrames.size() > 0) { + ZeDMDFrame frame = m_delayedFrames.front(); + lastStreamId = frame.streamId; + m_frames.push(frame); + m_delayedFrames.pop(); + } + m_delayedFrameReady = false; + m_frameCounter = 1; + m_delayedFrameMutex.unlock(); + m_frameQueueMutex.unlock(); + continue; + } + m_delayedFrameMutex.unlock(); + m_frameQueueMutex.unlock(); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + continue; + } + else { + bool delay = false; + m_delayedFrameMutex.lock(); + delay = m_delayedFrameReady; + m_delayedFrameMutex.unlock(); + + if (delay && m_frameCounter > 2) { + while (m_frames.size() > 0) + m_frames.pop(); + m_frameCounter = 0; + m_frameQueueMutex.unlock(); + continue; + } + } + + ZeDMDFrame frame = m_frames.front(); + m_frames.pop(); + if (frame.streamId != -1) { + if (frame.streamId != lastStreamId) { + if (lastStreamId != -1) + m_frameCounter--; + + lastStreamId = frame.streamId; + } + } + else + m_frameCounter--; + + m_frameQueueMutex.unlock(); + + bool success = StreamBytes(&frame); + if (!success && frame.size < ZEDMD_COMM_FRAME_SIZE_COMMAND_LIMIT) { + std::this_thread::sleep_for(std::chrono::milliseconds(8)); + // Try to send the command again, in case the wait for the (R)eady signal ran into a timeout. + success = StreamBytes(&frame); + } + + if (frame.data) + free(frame.data); + + if (!success) + std::this_thread::sleep_for(std::chrono::milliseconds(2)); + } + + LogMessage("ZeDMDComm run thread finished"); + }); +#endif } void ZeDMDComm::QueueCommand(char command, uint8_t *data, int size, int8_t streamId, bool delayed) { - if (!m_serialPort.IsOpen()) - { +#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || defined(__ANDROID__)) + if (!m_pSerialPort) return; - } ZeDMDFrame frame = {0}; frame.command = command; frame.size = size; frame.streamId = streamId; - if (data && size > 0) - { + if (data && size > 0) { frame.data = (uint8_t *)malloc(size); memcpy(frame.data, data, size); } // delayed standard frame - if (streamId == -1 && FillDelayed()) - { + if (streamId == -1 && FillDelayed()) { m_delayedFrameMutex.lock(); while (m_delayedFrames.size() > 0) - { m_delayedFrames.pop(); - } + m_delayedFrames.push(frame); m_delayedFrameReady = true; m_delayedFrameMutex.unlock(); m_lastStreamId = -1; } // delayed streamed zones - else if (streamId != -1 && delayed) - { + else if (streamId != -1 && delayed) { m_delayedFrameMutex.lock(); m_delayedFrames.push(frame); m_delayedFrameMutex.unlock(); m_lastStreamId = streamId; } - else - { + else { m_frameQueueMutex.lock(); - if (streamId == -1 || m_lastStreamId != streamId) - { + if (streamId == -1 || m_lastStreamId != streamId) { m_frameCounter++; m_lastStreamId = streamId; } m_frames.push(frame); m_frameQueueMutex.unlock(); } +#endif } void ZeDMDComm::QueueCommand(char command, uint8_t value) @@ -203,45 +180,35 @@ void ZeDMDComm::QueueCommand(char command, uint8_t *data, int size, uint16_t wid uint8_t zone[16 * 8 * 3] = { 0 }; if (++m_streamId > 64) - { m_streamId = 0; - } bool delayed = false; - if (FillDelayed()) - { + if (FillDelayed()) { delayed = true; m_delayedFrameMutex.lock(); m_delayedFrameReady = false; while (m_delayedFrames.size() > 0) - { m_delayedFrames.pop(); - } + m_delayedFrameMutex.unlock(); // A delayed frame needs to be complete. memset(m_zoneHashes, 0, 128); } - for (uint16_t y = 0; y < height; y += m_zoneHeight) - { - for (uint16_t x = 0; x < width; x += m_zoneWidth) - { + for (uint16_t y = 0; y < height; y += m_zoneHeight) { + for (uint16_t x = 0; x < width; x += m_zoneWidth) { for (uint8_t z = 0; z < m_zoneHeight; z++) - { memcpy(&zone[z * m_zoneWidth * 3], &data[((y + z) * width + x) * 3], m_zoneWidth * 3); - } uint64_t hash = komihash(zone, m_zoneWidth * m_zoneHeight * 3, 0); - if (hash != m_zoneHashes[idx]) - { + if (hash != m_zoneHashes[idx]) { m_zoneHashes[idx] = hash; buffer[bufferSize++] = idx; memcpy(&buffer[bufferSize], zone, m_zoneWidth * m_zoneHeight * 3); bufferSize += m_zoneWidth * m_zoneHeight * 3; - if (bufferSize >= (width * m_zoneHeight * 3 + 16)) - { + if (bufferSize >= (width * m_zoneHeight * 3 + 16)) { QueueCommand(command, buffer, bufferSize, m_streamId, delayed); bufferSize = 0; } @@ -251,12 +218,9 @@ void ZeDMDComm::QueueCommand(char command, uint8_t *data, int size, uint16_t wid } if (bufferSize > 0) - { QueueCommand(command, buffer, bufferSize, m_streamId, delayed); - } - if (delayed) - { + if (delayed) { m_delayedFrameMutex.lock(); m_delayedFrameReady = true; m_delayedFrameMutex.unlock(); @@ -274,34 +238,27 @@ bool ZeDMDComm::FillDelayed() return (count > ZEDMD_COMM_FRAME_QUEUE_SIZE_MAX) || delayed; } -void ZeDMDComm::IgnoreDevice(const char *ignore_device) +void ZeDMDComm::IgnoreDevice(const char* ignore_device) { if (sizeof(ignore_device) < 32 && m_ignoredDevicesCounter < 10) - { strcpy(&m_ignoredDevices[m_ignoredDevicesCounter++][0], ignore_device); - } } -void ZeDMDComm::SetDevice(const char *device) +void ZeDMDComm::SetDevice(const char* device) { - if (sizeof(device) < 32) - { + if (sizeof(device) < 32) strcpy(&m_device[0], device); - } } bool ZeDMDComm::Connect() { -#ifndef __ANDROID__ +#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || defined(__ANDROID__)) if (m_device[0] != 0) - { return Connect(m_device); - } char szDevice[32]; - for (int i = 0; i < 7; i++) - { + for (int i = 0; i < 7; i++) { #ifdef __APPLE__ sprintf(szDevice, "/dev/cu.usbserial-%04d", i); #elif defined(_WIN32) || defined(_WIN64) @@ -310,105 +267,95 @@ bool ZeDMDComm::Connect() sprintf(szDevice, "/dev/ttyUSB%d", i); #endif - for (int j = 0; j < m_ignoredDevicesCounter; j++) - { + for (int j = 0; j < m_ignoredDevicesCounter; j++) { if (strcmp(szDevice, m_ignoredDevices[j]) == 0) - { continue; - } } if (Connect(szDevice)) return true; } - - return false; -#else - return Connect(NULL); #endif + return false; } void ZeDMDComm::Disconnect() { - if (!m_serialPort.IsOpen()) +#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || defined(__ANDROID__)) + if (!m_pSerialPort) return; Reset(); - m_serialPort.Close(); + sp_close(m_pSerialPort); + m_pSerialPort = NULL; +#endif } bool ZeDMDComm::Connect(char *pDevice) { - m_serialPort.SetReadTimeout(ZEDMD_COMM_SERIAL_READ_TIMEOUT); - m_serialPort.SetWriteTimeout(ZEDMD_COMM_SERIAL_WRITE_TIMEOUT); - - if (m_serialPort.Open(pDevice, ZEDMD_COMM_BAUD_RATE, 8, 1, 0) != 1) +#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || defined(__ANDROID__)) + if (sp_get_port_by_name(pDevice, &m_pSerialPort) != SP_OK) return false; + sp_open(m_pSerialPort, SP_MODE_READ_WRITE); + + sp_set_baudrate(m_pSerialPort, ZEDMD_COMM_BAUD_RATE); + sp_set_bits(m_pSerialPort, 8); + sp_set_parity(m_pSerialPort, SP_PARITY_NONE); + sp_set_stopbits(m_pSerialPort, 1); + Reset(); uint8_t data[8] = {0}; - // Android in general but also ZeDMD HD require some time after opening the device. - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - - // ESP32 sends some information about itself before we could use the line. - while (m_serialPort.Available() > 0) - m_serialPort.ReadBytes(data, 8); + while (sp_input_waiting(m_pSerialPort) > 0) + sp_blocking_read(m_pSerialPort, data, 8, ZEDMD_COMM_SERIAL_READ_TIMEOUT); -#ifdef __ANDROID__ - // Android returns a large buffer of 80 and 00, so wait and read again to clear - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - - while (m_serialPort.Available() > 0) - m_serialPort.ReadBytes(data, 8); -#endif + std::this_thread::sleep_for(std::chrono::milliseconds(200)); - m_serialPort.WriteBytes((uint8_t *)CTRL_CHARS_HEADER, CTRL_CHARS_HEADER_SIZE); - m_serialPort.WriteChar(ZEDMD_COMM_COMMAND::Handshake); + data[0] = ZEDMD_COMM_COMMAND::Handshake; + sp_blocking_write(m_pSerialPort, (void*)CTRL_CHARS_HEADER, CTRL_CHARS_HEADER_SIZE, ZEDMD_COMM_SERIAL_WRITE_TIMEOUT); + sp_blocking_write(m_pSerialPort, (void*)data, 1, ZEDMD_COMM_SERIAL_WRITE_TIMEOUT); + std::this_thread::sleep_for(std::chrono::milliseconds(200)); - if (m_serialPort.ReadBytes(data, 8)) - { - if (!memcmp(data, CTRL_CHARS_HEADER, 4)) - { + if (sp_blocking_read(m_pSerialPort, data, 8, 0)) { + if (!memcmp(data, CTRL_CHARS_HEADER, 4)) { m_width = data[4] + data[5] * 256; m_height = data[6] + data[7] * 256; m_zoneWidth = m_width / 16; m_zoneHeight = m_height / 8; - uint8_t response; - - if (m_serialPort.ReadByte() == 'R') - { - m_serialPort.WriteBytes((uint8_t *)CTRL_CHARS_HEADER, 6); - m_serialPort.WriteChar(ZEDMD_COMM_COMMAND::Compression); + if (sp_blocking_read(m_pSerialPort, data, 1, ZEDMD_COMM_SERIAL_READ_TIMEOUT) && data[0] == 'R') { + data[0] = ZEDMD_COMM_COMMAND::Compression; + sp_blocking_write(m_pSerialPort, (void*)CTRL_CHARS_HEADER, 6, ZEDMD_COMM_SERIAL_WRITE_TIMEOUT); + sp_blocking_write(m_pSerialPort, (void*)data, 1, ZEDMD_COMM_SERIAL_WRITE_TIMEOUT); std::this_thread::sleep_for(std::chrono::milliseconds(4)); - if (m_serialPort.ReadByte() == 'A' && m_serialPort.ReadByte() == 'R') - { - m_serialPort.WriteBytes((uint8_t *)CTRL_CHARS_HEADER, 6); - m_serialPort.WriteChar(ZEDMD_COMM_COMMAND::Chunk); - m_serialPort.WriteChar(ZEDMD_COMM_MAX_SERIAL_WRITE_AT_ONCE / 256); + if (sp_blocking_read(m_pSerialPort, data, 1, ZEDMD_COMM_SERIAL_READ_TIMEOUT) && data[0] == 'A' && + sp_blocking_read(m_pSerialPort, data, 1, ZEDMD_COMM_SERIAL_READ_TIMEOUT) && data[0] == 'R') { + + data[0] = ZEDMD_COMM_COMMAND::Chunk; + data[1] = ZEDMD_COMM_MAX_SERIAL_WRITE_AT_ONCE / 256; + sp_blocking_write(m_pSerialPort, (void*)CTRL_CHARS_HEADER, 6, ZEDMD_COMM_SERIAL_WRITE_TIMEOUT); + sp_blocking_write(m_pSerialPort, (void*)data, 2, ZEDMD_COMM_SERIAL_WRITE_TIMEOUT); std::this_thread::sleep_for(std::chrono::milliseconds(4)); - if (m_serialPort.ReadByte() == 'A' && m_serialPort.ReadByte() == 'R') - { - m_serialPort.WriteBytes((uint8_t *)CTRL_CHARS_HEADER, 6); - m_serialPort.WriteChar(ZEDMD_COMM_COMMAND::EnableFlowControlV2); + if (sp_blocking_read(m_pSerialPort, data, 1, ZEDMD_COMM_SERIAL_READ_TIMEOUT) && data[0] == 'A' && + sp_blocking_read(m_pSerialPort, data, 1, ZEDMD_COMM_SERIAL_READ_TIMEOUT) && data[0] == 'R') { + data[0] = ZEDMD_COMM_COMMAND::EnableFlowControlV2; + sp_blocking_write(m_pSerialPort, (void*)CTRL_CHARS_HEADER, 6, ZEDMD_COMM_SERIAL_WRITE_TIMEOUT); + sp_blocking_write(m_pSerialPort, (void*)data, 1, ZEDMD_COMM_SERIAL_WRITE_TIMEOUT); std::this_thread::sleep_for(std::chrono::milliseconds(4)); - if (m_serialPort.ReadByte() == 'A') - { + if (sp_blocking_read(m_pSerialPort, data, 1, ZEDMD_COMM_SERIAL_READ_TIMEOUT) && data[0] == 'A') { m_flowControlCounter = 1; - if (pDevice) - { + if (pDevice) { LogMessage("ZeDMD found: device=%s, width=%d, height=%d", pDevice, m_width, m_height); } - else - { + else { LogMessage("ZeDMD found: width=%d, height=%d", m_width, m_height); } @@ -421,35 +368,43 @@ bool ZeDMDComm::Connect(char *pDevice) } Disconnect(); +#endif return false; } void ZeDMDComm::Reset() { - m_serialPort.ClearDTR(); - m_serialPort.SetRTS(); +#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || defined(__ANDROID__)) + if (!m_pSerialPort) + return; + + sp_set_dtr(m_pSerialPort, SP_DTR_OFF); + sp_set_rts(m_pSerialPort, SP_RTS_ON); + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + + sp_set_rts(m_pSerialPort, SP_RTS_OFF); + sp_set_dtr(m_pSerialPort, SP_DTR_OFF); std::this_thread::sleep_for(std::chrono::milliseconds(200)); - m_serialPort.ClearRTS(); - m_serialPort.ClearDTR(); + sp_flush(m_pSerialPort, SP_BUF_BOTH); std::this_thread::sleep_for(std::chrono::milliseconds(200)); +#endif } bool ZeDMDComm::StreamBytes(ZeDMDFrame *pFrame) { +#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || defined(__ANDROID__)) uint8_t *data; int size; - if (pFrame->size == 0) - { + if (pFrame->size == 0) { size = CTRL_CHARS_HEADER_SIZE + 1; data = (uint8_t *)malloc(size); memcpy(data, CTRL_CHARS_HEADER, CTRL_CHARS_HEADER_SIZE); data[CTRL_CHARS_HEADER_SIZE] = pFrame->command; } - else - { + else { mz_ulong compressedSize = mz_compressBound(pFrame->size); data = (uint8_t *)malloc(CTRL_CHARS_HEADER_SIZE + 3 + compressedSize); memcpy(data, CTRL_CHARS_HEADER, CTRL_CHARS_HEADER_SIZE); @@ -463,53 +418,46 @@ bool ZeDMDComm::StreamBytes(ZeDMDFrame *pFrame) bool success = false; uint8_t flowControlCounter; - do - { + do { // In case of a timeout, ReadByte() returns 0. - flowControlCounter = m_serialPort.ReadByte(); + sp_blocking_read(m_pSerialPort, &flowControlCounter, 1, ZEDMD_COMM_SERIAL_READ_TIMEOUT); } while (flowControlCounter != 0 && flowControlCounter != m_flowControlCounter); - if (flowControlCounter == m_flowControlCounter) - { + if (flowControlCounter == m_flowControlCounter) { int position = 0; success = true; - while (position < size && success) - { - m_serialPort.WriteBytes(data + position, ((size - position) < ZEDMD_COMM_MAX_SERIAL_WRITE_AT_ONCE) ? (size - position) : ZEDMD_COMM_MAX_SERIAL_WRITE_AT_ONCE); - + while (position < size && success) { + sp_blocking_write(m_pSerialPort, data + position, ((size - position) < ZEDMD_COMM_MAX_SERIAL_WRITE_AT_ONCE) ? (size - position) : ZEDMD_COMM_MAX_SERIAL_WRITE_AT_ONCE, ZEDMD_COMM_SERIAL_WRITE_TIMEOUT); + uint8_t response; - do - { - response = m_serialPort.ReadByte(); + do { + sp_blocking_read(m_pSerialPort, &response, 1, ZEDMD_COMM_SERIAL_READ_TIMEOUT); } while (response == flowControlCounter); if (response == 'A') position += ZEDMD_COMM_MAX_SERIAL_WRITE_AT_ONCE; - else - { + else { success = false; LogMessage("Write bytes failure: response=%c", response); } } if (m_flowControlCounter < 32) - { m_flowControlCounter++; - } else - { m_flowControlCounter = 1; - } } - else - { + else { LogMessage("No Ready Signal"); } free(data); return success; +#else + return false; +#endif } uint16_t ZeDMDComm::GetWidth() @@ -520,4 +468,4 @@ uint16_t ZeDMDComm::GetWidth() uint16_t ZeDMDComm::GetHeight() { return m_height; -} \ No newline at end of file +} diff --git a/src/ZeDMDComm.h b/src/ZeDMDComm.h index 685f63f..f5168bc 100644 --- a/src/ZeDMDComm.h +++ b/src/ZeDMDComm.h @@ -7,8 +7,14 @@ #include #include #include -// @todo better handling of external lib -#include "../../libserialport/src/SerialPort.h" + +#if defined(__APPLE__) +#include +#endif + +#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || defined(__ANDROID__)) +#include "libserialport.h" +#endif #if defined(_WIN32) || defined(_WIN64) #define CALLBACK __stdcall @@ -63,24 +69,17 @@ struct ZeDMDFrame #define ZEDMD_COMM_SERIAL_READ_TIMEOUT 16 #define ZEDMD_COMM_SERIAL_WRITE_TIMEOUT 16 -#if defined(_WIN32) || defined(_WIN64) +#if defined(__APPLE__) +#define ZEDMD_COMM_MAX_SERIAL_WRITE_AT_ONCE 512 +#elif defined(_WIN32) || defined(_WIN64) #define ZEDMD_COMM_MAX_SERIAL_WRITE_AT_ONCE 8192 -#elif defined(__APPLE__) -#define ZEDMD_COMM_MAX_SERIAL_WRITE_AT_ONCE 256 -#elif defined(__ANDROID__) -#define ZEDMD_COMM_MAX_SERIAL_WRITE_AT_ONCE 2048 #else -// defined (__linux__) #define ZEDMD_COMM_MAX_SERIAL_WRITE_AT_ONCE 256 #endif #define ZEDMD_COMM_FRAME_SIZE_COMMAND_LIMIT 10 #define ZEDMD_COMM_FRAME_QUEUE_SIZE_MAX 8 -#ifdef __ANDROID__ -typedef void *(*ZeDMD_AndroidGetJNIEnvFunc)(); -#endif - typedef void(CALLBACK *ZeDMD_LogMessageCallback)(const char *format, va_list args, const void *userData); class ZeDMDComm @@ -93,10 +92,6 @@ class ZeDMDComm ZeDMDComm(); ~ZeDMDComm(); -#ifdef __ANDROID__ - void SetAndroidGetJNIEnvFunc(ZeDMD_AndroidGetJNIEnvFunc func); -#endif - void SetLogMessageCallback(ZeDMD_LogMessageCallback callback, const void *userData); void IgnoreDevice(const char *ignore_device); @@ -135,7 +130,9 @@ class ZeDMDComm char m_ignoredDevices[10][32] = {0}; uint8_t m_ignoredDevicesCounter = 0; char m_device[32] = {0}; - SerialPort m_serialPort; +#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || defined(__ANDROID__)) + struct sp_port* m_pSerialPort; +#endif std::queue m_frames; std::thread *m_pThread; std::mutex m_frameQueueMutex; diff --git a/src/ZeDMDWiFi.cpp b/src/ZeDMDWiFi.cpp index 2fb3c87..cb3d5cb 100644 --- a/src/ZeDMDWiFi.cpp +++ b/src/ZeDMDWiFi.cpp @@ -1,4 +1,5 @@ #include "ZeDMDWiFi.h" + #include "miniz/miniz.h" #include "komihash/komihash.h" diff --git a/src/test.cpp b/src/test.cpp new file mode 100644 index 0000000..9df4ba7 --- /dev/null +++ b/src/test.cpp @@ -0,0 +1,16 @@ +#include "ZeDMD.h" + +#include +#include + +int main(int argc, const char* argv[]) { + ZeDMD* pZEDMD = new ZeDMD(); + + if (pZEDMD->Open()) { + pZEDMD->LedTest(); + + std::this_thread::sleep_for(std::chrono::milliseconds(5000)); + + pZEDMD->Close(); + } +} \ No newline at end of file diff --git a/third-party/build-libs/linux/aarch64/README.md b/third-party/build-libs/linux/aarch64/README.md new file mode 100644 index 0000000..32ff9b1 --- /dev/null +++ b/third-party/build-libs/linux/aarch64/README.md @@ -0,0 +1 @@ +linux aarch64 build-libs go here diff --git a/third-party/build-libs/linux/x64/README.md b/third-party/build-libs/linux/x64/README.md new file mode 100644 index 0000000..d73c406 --- /dev/null +++ b/third-party/build-libs/linux/x64/README.md @@ -0,0 +1 @@ +linux x64 build-libs go here \ No newline at end of file diff --git a/third-party/build-libs/macos/arm64/README.md b/third-party/build-libs/macos/arm64/README.md new file mode 100644 index 0000000..97b02f8 --- /dev/null +++ b/third-party/build-libs/macos/arm64/README.md @@ -0,0 +1 @@ +macos arm64 build-libs go here diff --git a/third-party/build-libs/macos/x64/README.md b/third-party/build-libs/macos/x64/README.md new file mode 100644 index 0000000..71cfccf --- /dev/null +++ b/third-party/build-libs/macos/x64/README.md @@ -0,0 +1 @@ +macos x64 build-libs go here \ No newline at end of file diff --git a/third-party/build-libs/win/x64/README.md b/third-party/build-libs/win/x64/README.md new file mode 100644 index 0000000..342b42b --- /dev/null +++ b/third-party/build-libs/win/x64/README.md @@ -0,0 +1 @@ +win x64 build-libs go here \ No newline at end of file diff --git a/third-party/build-libs/win/x86/README.md b/third-party/build-libs/win/x86/README.md new file mode 100644 index 0000000..1c19be1 --- /dev/null +++ b/third-party/build-libs/win/x86/README.md @@ -0,0 +1 @@ +win x86 build-libs go here diff --git a/src/komihash/komihash.h b/third-party/include/komihash/komihash.h similarity index 100% rename from src/komihash/komihash.h rename to third-party/include/komihash/komihash.h diff --git a/src/miniz/miniz.c b/third-party/include/miniz/miniz.c similarity index 100% rename from src/miniz/miniz.c rename to third-party/include/miniz/miniz.c diff --git a/src/miniz/miniz.h b/third-party/include/miniz/miniz.h similarity index 100% rename from src/miniz/miniz.h rename to third-party/include/miniz/miniz.h diff --git a/third-party/runtime-libs/android/arm64-v8a/README.md b/third-party/runtime-libs/android/arm64-v8a/README.md new file mode 100644 index 0000000..81d33d2 --- /dev/null +++ b/third-party/runtime-libs/android/arm64-v8a/README.md @@ -0,0 +1 @@ +android arm64-v8a runtime-libs go here \ No newline at end of file diff --git a/third-party/runtime-libs/ios/arm64/README.md b/third-party/runtime-libs/ios/arm64/README.md new file mode 100644 index 0000000..e85338b --- /dev/null +++ b/third-party/runtime-libs/ios/arm64/README.md @@ -0,0 +1 @@ +ios arm64 runtime-libs go here \ No newline at end of file diff --git a/third-party/runtime-libs/linux/aarch64/README.md b/third-party/runtime-libs/linux/aarch64/README.md new file mode 100644 index 0000000..9087f0b --- /dev/null +++ b/third-party/runtime-libs/linux/aarch64/README.md @@ -0,0 +1 @@ +linux aarch64 runtime-libs go here \ No newline at end of file diff --git a/third-party/runtime-libs/linux/x64/README.md b/third-party/runtime-libs/linux/x64/README.md new file mode 100644 index 0000000..d25e945 --- /dev/null +++ b/third-party/runtime-libs/linux/x64/README.md @@ -0,0 +1 @@ +linux x64 runtime-libs go here \ No newline at end of file diff --git a/third-party/runtime-libs/macos/arm64/README.md b/third-party/runtime-libs/macos/arm64/README.md new file mode 100644 index 0000000..7ddb096 --- /dev/null +++ b/third-party/runtime-libs/macos/arm64/README.md @@ -0,0 +1 @@ +macos arm64 runtime-libs go here \ No newline at end of file diff --git a/third-party/runtime-libs/macos/x64/README.md b/third-party/runtime-libs/macos/x64/README.md new file mode 100644 index 0000000..72711de --- /dev/null +++ b/third-party/runtime-libs/macos/x64/README.md @@ -0,0 +1 @@ +macos x64 runtime-libs go here \ No newline at end of file diff --git a/third-party/runtime-libs/tvos/arm64/README.md b/third-party/runtime-libs/tvos/arm64/README.md new file mode 100644 index 0000000..90c9892 --- /dev/null +++ b/third-party/runtime-libs/tvos/arm64/README.md @@ -0,0 +1 @@ +tvos arm64 runtime-libs go here \ No newline at end of file diff --git a/third-party/runtime-libs/win/x64/README.md b/third-party/runtime-libs/win/x64/README.md new file mode 100644 index 0000000..203fd72 --- /dev/null +++ b/third-party/runtime-libs/win/x64/README.md @@ -0,0 +1 @@ +win x64 runtime-libs go here \ No newline at end of file diff --git a/third-party/runtime-libs/win/x86/README.md b/third-party/runtime-libs/win/x86/README.md new file mode 100644 index 0000000..b716171 --- /dev/null +++ b/third-party/runtime-libs/win/x86/README.md @@ -0,0 +1 @@ +win x86 runtime-libs go here \ No newline at end of file