diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..b865c0c --- /dev/null +++ b/.clang-format @@ -0,0 +1,14 @@ +# Ref: https://clang.llvm.org/docs/ClangFormatStyleOptions.html +BasedOnStyle: LLVM +UseTab: ForIndentation +IndentWidth: 4 +TabWidth: 4 +LineEnding: LF +BreakBeforeBraces: Allman +BreakBeforeConceptDeclarations: Always +AllowShortIfStatementsOnASingleLine: false +IndentCaseLabels: true +ColumnLimit: 0 +AccessModifierOffset: -4 +NamespaceIndentation: All +FixNamespaceComments: false diff --git a/.github/workflows/ManualReleaseMain.yml b/.github/workflows/ManualReleaseMain.yml new file mode 100644 index 0000000..c6c612f --- /dev/null +++ b/.github/workflows/ManualReleaseMain.yml @@ -0,0 +1,106 @@ +name: "Manual Release - Main" + +on: + workflow_dispatch: + inputs: + workflowPreset: + description: "Configure/Build/Test/Package configuration" + required: false + default: "Release" + type: choice + options: + - "Release" + - "RelWithDebInfo" + - "MinSizeRel" + - "Debug" + versionMajor: + description: "Major Version" + required: false + default: 0 + type: number + versionMinor: + description: "Minor Version" + required: false + default: 1 + type: number + versionPatch: + description: "Patch Version" + required: false + default: 0 + type: number + +env: + VCPKG_ROOT: C:/vcpkg + MSYSTEM: clang64 + ARCH: clang-x86_64 + +jobs: + Build: + name: Build w/ MSYS2 + runs-on: windows-latest + + defaults: + run: + shell: pwsh + + steps: + - name: Setup MSYS2 ${{ env.MSYSTEM }} (${{ env.ARCH }}) + uses: msys2/setup-msys2@v2 + with: + msystem: ${{ env.MSYSTEM }} + release: false + update: true + cache: true + install: git base-devel mingw-w64-${{ env.ARCH }}-toolchain mingw-w64-${{ env.ARCH }}-cmake + + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: ${{ github.ref }} + + - name: Get new build number + id: build-number + run: | + $build_number = $((${{ vars.BUILD_NUMBER }} + 1)) + echo "current_build_number=$build_number" | Set-Content $env:GITHUB_OUTPUT + + - name: Run CMake + shell: msys2 {0} + env: + RC_VERSION_MAJOR: ${{inputs.versionMajor}} + RC_VERSION_MINOR: ${{inputs.versionMinor}} + RC_VERSION_PATCH: ${{inputs.versionPatch}} + RC_VERSION_BUILD: ${{steps.build-number.outputs.current_build_number}} + run: cmake --workflow --preset ${{inputs.workflowPreset}} --fresh + + - name: Run CTest + shell: msys2 {0} + run: ctest --preset ${{inputs.workflowPreset}} --output-on-failure + + - name: Update build number variable + env: + GH_TOKEN: ${{ secrets.GH_VARIABLE_RW_TOKEN }} + run: gh variable set BUILD_NUMBER -b${{ steps.build-number.outputs.current_build_number }} + + - name: Zip the publish artifacts + working-directory: ${{github.workspace}} + run: | + Add-Type -assembly 'System.IO.Compression' + Add-Type -assembly 'System.IO.Compression.FileSystem' + [System.IO.Compression.ZipArchive]$zipFile = [System.IO.Compression.ZipFile]::Open('SRTManager-v${{inputs.versionMajor}}.${{inputs.versionMinor}}.${{inputs.versionPatch}}-${{steps.build-number.outputs.current_build_number}}-${{inputs.workflowPreset}}.zip', ([System.IO.Compression.ZipArchiveMode]::Create)) + [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($zipFile, 'build/SRTManager.exe', 'SRTManager.exe') + [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($zipFile, 'build/SRTManager.dll', 'SRTManager.dll') + [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($zipFile, 'LICENSE', 'LICENSE') + [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($zipFile, 'README.md', 'README.md') + $zipFile.Dispose() + + - name: Publish release + uses: marvinpinto/action-automatic-releases@latest + with: + repo_token: "${{ secrets.GITHUB_TOKEN }}" + automatic_release_tag: "${{inputs.workflowPreset}}-build" + prerelease: true + title: "Manual Build [main] - v${{inputs.versionMajor}}.${{inputs.versionMinor}}.${{inputs.versionPatch}}-${{steps.build-number.outputs.current_build_number}} Release" + files: | + SRTManager-v${{inputs.versionMajor}}.${{inputs.versionMinor}}.${{inputs.versionPatch}}-${{steps.build-number.outputs.current_build_number}}-${{inputs.workflowPreset}}.zip diff --git a/.gitignore b/.gitignore index 259148f..eca57f5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,66 @@ +### Self-defined + +build/ +vcpkg_installed/ +extern/ + +### https://github.com/github/gitignore/blob/main/C.gitignore + +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf + +### https://github.com/github/gitignore/blob/main/C++.gitignore + # Prerequisites *.d @@ -30,3 +93,419 @@ *.exe *.out *.app + +### https://github.com/github/gitignore/blob/main/CMake.gitignore + +CMakeLists.txt.user +CMakeCache.txt +CMakeFiles +CMakeScripts +Testing +Makefile +cmake_install.cmake +install_manifest.txt +compile_commands.json +CTestTestfile.cmake +_deps + +### https://github.com/github/gitignore/blob/main/VisualStudio.gitignore + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.tlog +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio 6 auto-generated project file (contains which files were open etc.) +*.vbp + +# Visual Studio 6 workspace and project file (working project files containing files to include in project) +*.dsw +*.dsp + +# Visual Studio 6 technical files +*.ncb +*.aps + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# Visual Studio History (VSHistory) files +.vshistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +# VS Code files for those working on multiple tools +.vscode/* +!.vscode/c_cpp_properties.json +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +# Windows Installer files from build outputs +*.cab +*.msi +*.msix +*.msm +*.msp + +# JetBrains Rider +*.sln.iml diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..0bb3577 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,22 @@ +{ + "configurations": [ + { + "name": "Win32", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [ + "_DEBUG", + "UNICODE", + "_UNICODE" + ], + "windowsSdkVersion": "10.0.22621.0", + "compilerPath": "C:/msys64/clang64/bin/clang++.exe", + "cStandard": "c17", + "cppStandard": "c++23", + "intelliSenseMode": "windows-clang-x64", + "configurationProvider": "ms-vscode.cmake-tools" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..ee130f3 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,53 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "(lldb) Launch", + "type": "lldb", + "request": "launch", + "program": "${workspaceFolder}/build/SRTManager.exe", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}/build", + "environment": [], + "externalConsole": false, + "MIMode": "lldb", + "miDebuggerPath": "C:/msys64/clang64/bin/lldb.exe", + "setupCommands": [ + { + "description": "Enable pretty-printing for lldb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "description": "Set Disassembly Flavor to Intel", + "text": "-lldb-set disassembly-flavor intel", + "ignoreFailures": true + } + ] + }, + { + "name": "(lldb) Attach", + "type": "lldb", + "request": "attach", + "program": "${workspaceFolder}/build/SRTManager.exe", + "MIMode": "lldb", + "miDebuggerPath": "C:/msys64/clang64/bin/lldb.exe", + "setupCommands": [ + { + "description": "Enable pretty-printing for lldb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "description": "Set Disassembly Flavor to Intel", + "text": "-lldb-set disassembly-flavor intel", + "ignoreFailures": true + } + ] + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..f2d593e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,125 @@ +{ + "files.associations": { + "*.c": "c", + "*.h": "cpp", + "*.cpp": "cpp", + "*.hpp": "cpp", + "*.cs": "csharp", + "*.yml": "yaml", + "CMakeLists.txt": "cmake", + "*.cmake": "cmake", + "Makefile": "makefile", + "Makefile2": "makefile", + "*.yaml": "yaml", + "atomic": "cpp", + "bit": "cpp", + "cctype": "cpp", + "charconv": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "compare": "cpp", + "concepts": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "exception": "cpp", + "format": "cpp", + "initializer_list": "cpp", + "iosfwd": "cpp", + "iterator": "cpp", + "limits": "cpp", + "locale": "cpp", + "memory": "cpp", + "new": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "string": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "typeinfo": "cpp", + "utility": "cpp", + "xfacet": "cpp", + "xiosbase": "cpp", + "xlocale": "cpp", + "xlocbuf": "cpp", + "xlocinfo": "cpp", + "xlocmes": "cpp", + "xlocmon": "cpp", + "xlocnum": "cpp", + "xloctime": "cpp", + "xmemory": "cpp", + "xstring": "cpp", + "xtr1common": "cpp", + "xutility": "cpp", + "array": "cpp", + "*.tcc": "cpp", + "cstdarg": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "string_view": "cpp", + "istream": "cpp", + "numbers": "cpp", + "ostream": "cpp", + "span": "cpp", + "sstream": "cpp", + "cinttypes": "cpp", + "variant": "cpp", + "iostream": "cpp", + "ios": "cpp", + "list": "cpp", + "ranges": "cpp", + "codecvt": "cpp", + "ratio": "cpp", + "iomanip": "cpp", + "filesystem": "cpp", + "condition_variable": "cpp", + "mutex": "cpp", + "semaphore": "cpp", + "stop_token": "cpp", + "thread": "cpp", + "map": "cpp", + "unordered_set": "cpp", + "fstream": "cpp", + "chrono": "cpp", + "future": "cpp", + "stdfloat": "cpp", + "text_encoding": "cpp", + "any": "cpp", + "set": "cpp", + "__bit_reference": "cpp", + "__hash_table": "cpp", + "__locale": "cpp", + "__node_handle": "cpp", + "__split_buffer": "cpp", + "__threading_support": "cpp", + "__tree": "cpp", + "__verbose_abort": "cpp", + "bitset": "cpp", + "csignal": "cpp", + "execution": "cpp", + "forward_list": "cpp", + "print": "cpp", + "queue": "cpp", + "shared_mutex": "cpp", + "stack": "cpp", + "__config": "cpp" + }, + "C_Cpp.default.cppStandard": "c++23", + "cmake.environment": { + "PATH": "C:\\msys64\\clang64\\bin;C:\\msys64\\usr\\bin;${env:PATH}" + }, + "cmake.generator": "MSYS Makefiles" +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..be97cba --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,154 @@ +cmake_minimum_required(VERSION 3.25) +set(CMAKE_C_COMPILER "C:/msys64/clang64/bin/clang.exe" CACHE FILEPATH "" FORCE) +set(CMAKE_CXX_COMPILER "C:/msys64/clang64/bin/clang++.exe" CACHE FILEPATH "" FORCE) +project (SRTManager) + +function(set_from_env var_name default_value var_type var_desc) + if(DEFINED ENV{${var_name}}) + set(${var_name} $ENV{${var_name}} CACHE ${var_type} ${var_desc} FORCE) + else() + set(${var_name} ${default_value} CACHE ${var_type} ${var_desc} FORCE) + endif() +endfunction() + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") +set(CMAKE_SHARED_LIBRARY_PREFIX "") +set(CMAKE_SHARED_LIBRARY_SUFFIX ".dll") +set(CMAKE_STATIC_LIBRARY_PREFIX "") +set(CMAKE_STATIC_LIBRARY_SUFFIX ".lib") +set(CMAKE_EXECUTABLE_ENABLE_EXPORTS TRUE) +option(BUILD_SHARED_LIBS "Build using shared libraries" ON) +if(BUILD_SHARED_LIBS) + add_definitions(-DBUILD_SHARED_LIBS) +else() + add_definitions(-DBUILD_STATIC_LIBS) +endif() + +include(CTest) +enable_testing() +include(GoogleTest) +find_package(GTest CONFIG REQUIRED) + +#set(CMAKE_C_STANDARD 17) # 90, 99, 11, 17, 23 +#set(CMAKE_C_STANDARD_REQUIRED TRUE) +set(CMAKE_CXX_STANDARD 23) # 98, 11, 14, 17, 20, 23, 26 +set(CMAKE_CXX_STANDARD_REQUIRED TRUE) +string(ASCII 169 COPYRIGHT) + +# VERSIONINFO properties (Ref: https://learn.microsoft.com/en-us/windows/win32/menurc/versioninfo-resource) +set(RC_PRODUCTNAME "SRT Manager") +set(RC_FILEDESCRIPTION "A program for installing, uninstalling, and updating SRT Host and its plugins.") +set(RC_COMPANYNAME "Travis J. Gutjahr") +set(RC_LEGALCOPYRIGHT "Copyright ${COPYRIGHT} 2024 Travis J. Gutjahr") +set(RC_INTERNALNAME "${PROJECT_NAME}") +set(RC_ORIGINALFILENAME "${RC_INTERNALNAME}.exe") + +# Major.Minor.Patch.Rev +set_from_env(RC_VERSION_MAJOR 0 STRING "Version (major) of the product.") +set_from_env(RC_VERSION_MINOR 1 STRING "Version (minor) of the product.") +set_from_env(RC_VERSION_PATCH 0 STRING "Version (patch) of the product.") +set_from_env(RC_VERSION_BUILD 1 STRING "Version (build) of the product.") # Auto-increment in build CI/CD. + +# Compile the version information. +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/VersionInfo.rc.in ${CMAKE_CURRENT_BINARY_DIR}/VersionInfo.rc @ONLY) + +add_definitions("-DSRTMGR_VERSION_MAJOR=${RC_VERSION_MAJOR}") +add_definitions("-DSRTMGR_VERSION_MINOR=${RC_VERSION_MINOR}") +add_definitions("-DSRTMGR_VERSION_PATCH=${RC_VERSION_PATCH}") +add_definitions("-DSRTMGR_VERSION_BUILD=${RC_VERSION_BUILD}") + +include(FetchContent) +set(FETCHCONTENT_QUIET off) + +FetchContent_Declare( + SHA-2 + GIT_REPOSITORY https://github.com/amosnier/sha-2.git + GIT_TAG b29613850d6e54e7159197ef42c7d22d012b6367 # origin/master + SOURCE_DIR ${PROJECT_SOURCE_DIR}/extern/amosnier/sha-2 +) +FetchContent_MakeAvailable(SHA-2) + +# vcpkg dependencies. +find_package(SDL2 CONFIG REQUIRED) +find_package(imgui CONFIG REQUIRED) + +# Required libraries we'll link for ImGUI. +find_library(D3D11_LIBRARY d3d11 REQUIRED PATHS C:/msys64/clang64/lib) +find_library(D3DCOMPILER_LIBRARY d3dcompiler REQUIRED PATHS C:/msys64/clang64/lib) + +include(CMakePrintHelpers) +cmake_print_variables( + D3D11_LIBRARY + D3DCOMPILER_LIBRARY +) + +add_compile_options( + -Wall -Wextra -Wpedantic + -m64 -masm=intel + $<$,$,$>:-O3> # Optimize. + #$<$,$>:-s> # Debug symbol stripping. [Requires GCC] + $<$,$>:-g> # Set symbol type. + #$<$,$>:-gcodeview> # Set symbol type. (MSVC++ format) [Requires GCC 14+ or clang] + $<$:-O0> # No optimizations. + ) +add_compile_definitions( + $<$,$,$>:RELEASE> + $<$:DEBUG> + ) +add_link_options( + -static -stdlib=libc++ -lc++ -lc++abi +) + +cmake_print_variables( + CMAKE_C_COMPILER + CMAKE_CXX_COMPILER +) + +target_link_libraries(imgui::imgui INTERFACE ${D3D11_LIBRARY} ${D3DCOMPILER_LIBRARY}) +include_directories(include extern/amosnier/sha-2) + +### Library +add_library(${PROJECT_NAME} +${CMAKE_CURRENT_BINARY_DIR}/VersionInfo.rc +extern/amosnier/sha-2/sha-256.c +src/Helpers.cpp +src/UI.cpp +) +target_link_libraries(${PROJECT_NAME} +PRIVATE imgui::imgui +) +add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD DEPENDS ${PROJECT_NAME} COMMAND $<$,$>:${CMAKE_STRIP}> ARGS --strip-all ${PROJECT_NAME}.dll) + +### Executable +add_executable(${PROJECT_NAME}App +${CMAKE_CURRENT_BINARY_DIR}/VersionInfo.rc +src/Main.cpp +) +target_link_libraries(${PROJECT_NAME}App +PRIVATE ${PROJECT_NAME} +PRIVATE SDL2::SDL2main +PRIVATE SDL2::SDL2 +) +set_target_properties(${PROJECT_NAME}App +PROPERTIES OUTPUT_NAME ${PROJECT_NAME}) +add_custom_command(TARGET ${PROJECT_NAME}App POST_BUILD DEPENDS ${PROJECT_NAME}App COMMAND $<$,$>:${CMAKE_STRIP}> ARGS --strip-all ${PROJECT_NAME}.exe) + +### Unit Tests +include_directories(${GTest_INCLUDE_DIRS}) + +add_executable(${PROJECT_NAME}Tests +tests/test_Strings.cpp +) +target_link_libraries(${PROJECT_NAME}Tests +PRIVATE GTest::gtest +PRIVATE GTest::gtest_main +PRIVATE ${PROJECT_NAME} +) + +gtest_discover_tests(${PROJECT_NAME}Tests +PROPERTIES +DISCOVERY_TIMEOUT 30 +TEST_LIST discovered_tests +) diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 0000000..96c1fd7 --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,170 @@ +{ + "version": 6, + "cmakeMinimumRequired": { + "major": 3, + "minor": 25, + "patch": 0 + }, + "configurePresets": [ + { + "name": "default", + "generator": "MSYS Makefiles", + "hidden": true, + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake", + "VCPKG_TARGET_TRIPLET": "x64-mingw-static-custom", + "VCPKG_HOST_TRIPLET": "x64-mingw-static-custom" + } + }, + { + "name": "Debug", + "inherits": [ + "default" + ], + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug" + } + }, + { + "name": "Release", + "inherits": [ + "default" + ], + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release" + } + }, + { + "name": "RelWithDebInfo", + "inherits": [ + "default" + ], + "cacheVariables": { + "CMAKE_BUILD_TYPE": "RelWithDebInfo" + } + }, + { + "name": "MinSizeRel", + "inherits": [ + "default" + ], + "cacheVariables": { + "CMAKE_BUILD_TYPE": "MinSizeRel" + } + } + ], + "buildPresets": [ + { + "name": "Debug", + "configurePreset": "Debug" + }, + { + "name": "Release", + "configurePreset": "Release" + }, + { + "name": "RelWithDebInfo", + "configurePreset": "RelWithDebInfo" + }, + { + "name": "MinSizeRel", + "configurePreset": "MinSizeRel" + } + ], + "testPresets": [ + { + "name": "default", + "hidden": true, + "output": { + "outputOnFailure": true + }, + "execution": { + "noTestsAction": "error", + "stopOnFailure": true + } + }, + { + "name": "Debug", + "inherits": [ + "default" + ], + "configurePreset": "Debug" + }, + { + "name": "Release", + "inherits": [ + "default" + ], + "configurePreset": "Release" + }, + { + "name": "RelWithDebInfo", + "inherits": [ + "default" + ], + "configurePreset": "RelWithDebInfo" + }, + { + "name": "MinSizeRel", + "inherits": [ + "default" + ], + "configurePreset": "MinSizeRel" + } + ], + "workflowPresets": [ + { + "name": "Debug", + "steps": [ + { + "type": "configure", + "name": "Debug" + }, + { + "type": "build", + "name": "Debug" + } + ] + }, + { + "name": "Release", + "steps": [ + { + "type": "configure", + "name": "Release" + }, + { + "type": "build", + "name": "Release" + } + ] + }, + { + "name": "RelWithDebInfo", + "steps": [ + { + "type": "configure", + "name": "RelWithDebInfo" + }, + { + "type": "build", + "name": "RelWithDebInfo" + } + ] + }, + { + "name": "MinSizeRel", + "steps": [ + { + "type": "configure", + "name": "MinSizeRel" + }, + { + "type": "build", + "name": "MinSizeRel" + } + ] + } + ] +} \ No newline at end of file diff --git a/LICENSE b/LICENSE index b40fa40..b8498da 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2024 Speed Run Tool +Copyright (c) 2024 Travis J. Gutjahr Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 0a812e7..40d504a 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ -# SRTManager +# SRT Manager + A program for installing, uninstalling, and updating SRT Host and its plugins. diff --git a/include/Common.h b/include/Common.h new file mode 100644 index 0000000..e23549f --- /dev/null +++ b/include/Common.h @@ -0,0 +1,88 @@ +#ifndef SRTMGR_COMMON_H +#define SRTMGR_COMMON_H + +#ifdef DEBUG +static const bool IsDebug = true; +#else +static const bool IsDebug = false; +#endif + +#ifndef LIBRARY_EXPORT_API +// Windows Static or non-Windows +#if defined(BUILD_STATIC_LIBS) || !defined(WIN32) || !defined(WIN64) +#define LIBRARY_EXPORT_API +// Windows Shared (Build/Export) +#elif defined(BUILD_SHARED_LIBS) +#define LIBRARY_EXPORT_API __declspec(dllexport) +// Windows Shared (Usage/Import) +#else +#define LIBRARY_EXPORT_API __declspec(dllimport) +#endif +#endif + +#ifndef PACKED_DATA +#define PACKED_DATA __attribute__((packed)) +#endif + +#ifndef CONCATENATION +#define CONCATENATION(left, right) left##right +#endif + +#ifndef DEFINE_CONCATENATION +#define DEFINE_CONCATENATION(left, right) CONCATENATION(left, right) +#endif + +#ifndef NAMEOF +#define NAMEOF(name) #name +#endif + +// #ifdef __GNUC__ +// #define UNUSED(x) UNUSED_##x __attribute__((__unused__)) +// #else +// #define UNUSED(x) UNUSED_##x +// #endif + +#ifdef __GNUC__ +#define UNUSED(x) x __attribute__((__unused__)) +#else +#define UNUSED(x) x +#endif + +// #ifdef __GNUC__ +// #define UNUSED_FUNCTION(x) __attribute__((__unused__)) UNUSED_##x +// #else +// #define UNUSED_FUNCTION(x) UNUSED_##x +// #endif + +#ifdef __GNUC__ +#define UNUSED_FUNCTION(x) __attribute__((__unused__)) x +#else +#define UNUSED_FUNCTION(x) x +#endif + +// Program friendly name +#ifndef SRTMGR_APP_NAME +#define SRTMGR_APP_NAME "SRT Manager" +#endif + +// Major version number. This is defined at compile time so this is just a placeholder. +#ifndef SRTMGR_VERSION_MAJOR +#define SRTMGR_VERSION_MAJOR 0 +#endif + +// Minor version number. This is defined at compile time so this is just a placeholder. +#ifndef SRTMGR_VERSION_MINOR +#define SRTMGR_VERSION_MINOR 1 +#endif + +// Patch version number. This is defined at compile time so this is just a placeholder. +#ifndef SRTMGR_VERSION_PATCH +#define SRTMGR_VERSION_PATCH 0 +#endif + +// Build number. This is defined at compile time so this is just a placeholder. +#ifndef SRTMGR_VERSION_BUILD +#define SRTMGR_VERSION_BUILD 0 +#endif + +#endif diff --git a/include/Helpers.h b/include/Helpers.h new file mode 100644 index 0000000..a6bf06a --- /dev/null +++ b/include/Helpers.h @@ -0,0 +1,15 @@ +#ifndef SRTMGR_HELPERS_H +#define SRTMGR_HELPERS_H + +#include "Common.h" +#include +#include +#include + +namespace SRTMGR +{ + std::unique_ptr GetPrintfFormattedString(const char *fmt, ...); + void DrawFPSText(void); +} + +#endif diff --git a/include/Main.h b/include/Main.h new file mode 100644 index 0000000..bacadb4 --- /dev/null +++ b/include/Main.h @@ -0,0 +1,8 @@ +#ifndef SRTMGR_MAIN_H +#define SRTMGR_MAIN_H + +#include "Common.h" +#include "UI.h" +#include + +#endif diff --git a/include/UI.h b/include/UI.h new file mode 100644 index 0000000..59e9681 --- /dev/null +++ b/include/UI.h @@ -0,0 +1,47 @@ +#ifndef SRTMGR_UI_H +#define SRTMGR_UI_H + +#include "Common.h" +#include "Helpers.h" +#include +#include +#include +#include +#include +#include +#include +#include + +namespace SRTMGR +{ + class UI + { + private: + bool show_Main = true; + bool show_Debug_ImGuiDemo = false; + bool show_Help_About = false; + + ID3D11Device *g_pd3dDevice = nullptr; + ID3D11DeviceContext *g_pd3dDeviceContext = nullptr; + IDXGISwapChain *g_pSwapChain = nullptr; + ID3D11RenderTargetView *g_mainRenderTargetView = nullptr; + SDL_Window *window; + ImVec4 clear_color; + + bool CreateDeviceD3D(HWND hWnd); + void CleanupDeviceD3D(); + void CreateRenderTarget(); + void CleanupRenderTarget(); + + void __stdcall DrawMainUI(bool &); + void __stdcall DrawHelpAboutUI(const bool &); + + protected: + public: + UI(); + ~UI(); + void RenderLoop(void); + }; +} + +#endif diff --git a/src/Helpers.cpp b/src/Helpers.cpp new file mode 100644 index 0000000..347ca72 --- /dev/null +++ b/src/Helpers.cpp @@ -0,0 +1,30 @@ +#include "Helpers.h" + +void SRTMGR::DrawFPSText(void) +{ + static const float halfCharSize = ImGui::CalcTextSize(" ").x / 2.f; + ImGuiIO &io = ImGui::GetIO(); + const char fpsFormat[] = "Application average %.3f ms/frame (%.1f FPS)"; + + std::unique_ptr fpsFormattedText = GetPrintfFormattedString(fpsFormat, 1000.0f / io.Framerate, io.Framerate); + ImVec2 fpsTextSize = ImGui::CalcTextSize(fpsFormattedText.get()->c_str()); + + ImGui::SameLine(ImGui::GetWindowWidth() - (fpsTextSize.x + halfCharSize)); + ImGui::Text("%s", fpsFormattedText.get()->c_str()); +} + +std::unique_ptr SRTMGR::GetPrintfFormattedString(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + int size = vsnprintf(nullptr, 0, fmt, args) + 1; + + std::unique_ptr returnValue = std::make_unique(); + returnValue.get()->reserve(size); + vsnprintf(returnValue.get()->data(), size, fmt, args); + + va_end(args); + + return returnValue; +} diff --git a/src/Main.cpp b/src/Main.cpp new file mode 100644 index 0000000..4df59cd --- /dev/null +++ b/src/Main.cpp @@ -0,0 +1,9 @@ +#include "Main.h" + +int main(int UNUSED(argc), char *UNUSED(argv[])) +{ + std::unique_ptr ui = std::make_unique(); + ui.get()->RenderLoop(); + + return 0; +} diff --git a/src/UI.cpp b/src/UI.cpp new file mode 100644 index 0000000..fb737a7 --- /dev/null +++ b/src/UI.cpp @@ -0,0 +1,350 @@ +#include "UI.h" + +SRTMGR::UI::UI() +{ + // Setup SDL + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0) + { + printf("Error: %s\n", SDL_GetError()); + return; + } + + // From 2.0.18: Enable native IME. +#ifdef SDL_HINT_IME_SHOW_UI + SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1"); +#endif + + // Setup window + SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_BORDERLESS | SDL_WINDOW_MAXIMIZED | SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_HIDDEN); + window = SDL_CreateWindow(SRTMGR_APP_NAME, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1, 1, window_flags); + if (window == nullptr) + { + printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError()); + return; + } + + SDL_SysWMinfo wmInfo; + SDL_VERSION(&wmInfo.version); + SDL_GetWindowWMInfo(window, &wmInfo); + HWND hwnd = (HWND)wmInfo.info.win.window; + + // Initialize Direct3D + if (!CreateDeviceD3D(hwnd)) + { + CleanupDeviceD3D(); + return; + } + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO &io = ImGui::GetIO(); + io.IniFilename = "SRTManager.ini"; + io.LogFilename = "SRTManager.log"; + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking + io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows + // io.ConfigViewportsNoAutoMerge = true; + // io.ConfigViewportsNoTaskBarIcon = true; + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + // ImGui::StyleColorsLight(); + + // When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones. + ImGuiStyle &style = ImGui::GetStyle(); + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + style.WindowRounding = 0.0f; + style.Colors[ImGuiCol_WindowBg].w = 1.0f; + } + + // Setup Platform/Renderer backends + ImGui_ImplSDL2_InitForD3D(window); + ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext); + + // Load Fonts + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering. + // - Read 'docs/FONTS.md' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! + // io.Fonts->AddFontDefault(); + // io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f); + // io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); + // io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); + // io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); + // ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese()); + // IM_ASSERT(font != nullptr); + + // Our state + clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); +} + +SRTMGR::UI::~UI() +{ + // Cleanup + ImGui_ImplDX11_Shutdown(); + ImGui_ImplSDL2_Shutdown(); + ImGui::DestroyContext(); + + CleanupDeviceD3D(); + SDL_DestroyWindow(window); + SDL_Quit(); +} + +void SRTMGR::UI::RenderLoop(void) +{ + while (show_Main) + { + // Poll and handle events (inputs, window resize, etc.) + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. + SDL_Event event; + while (SDL_PollEvent(&event)) + { + ImGui_ImplSDL2_ProcessEvent(&event); + if (event.type == SDL_QUIT) + show_Main = false; + if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window)) + show_Main = false; + if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_RESIZED && event.window.windowID == SDL_GetWindowID(window)) + { + // Release all outstanding references to the swap chain's buffers before resizing. + CleanupRenderTarget(); + g_pSwapChain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, 0); + CreateRenderTarget(); + } + } + + // Start the Dear ImGui frame + ImGui_ImplDX11_NewFrame(); + ImGui_ImplSDL2_NewFrame(); + ImGui::NewFrame(); + + DrawMainUI(show_Main); + + // Rendering + ImGui::Render(); + const float clear_color_with_alpha[4] = {clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w}; + g_pd3dDeviceContext->OMSetRenderTargets(1, &g_mainRenderTargetView, nullptr); + g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, clear_color_with_alpha); + ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); + + // Update and Render additional Platform Windows + ImGuiIO &io = ImGui::GetIO(); + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + ImGui::UpdatePlatformWindows(); + ImGui::RenderPlatformWindowsDefault(); + } + + // g_pSwapChain->Present(1, 0); // Present with vsync + g_pSwapChain->Present(0, 0); // Present without vsync + } +} + +void __stdcall SRTMGR::UI::DrawMainUI(bool &open) +{ + // If the Main UI is hidden, exit here. + if (!open) + return; + + // Conditionally shown items (shown only if the Main UI is showing) + if (show_Debug_ImGuiDemo) + ImGui::ShowDemoWindow(&show_Debug_ImGuiDemo); + + if (show_Help_About) + DrawHelpAboutUI(show_Help_About); + + // Specify a default position/size in case there's no data in the .ini file. + ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(800, 600), ImGuiCond_FirstUseEver); + + if (!ImGui::Begin(SRTMGR_APP_NAME, (bool *)&open, ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoCollapse)) + { + ImGui::End(); + return; + } + + // Menu Bar + if (ImGui::BeginMenuBar()) + { + if (ImGui::BeginMenu("File")) + { + if (ImGui::MenuItem("Exit", NULL, false, true)) + open = !open; + ImGui::EndMenu(); + } + + if (IsDebug) + { + if (ImGui::BeginMenu("Debug")) + { + ImGui::MenuItem("ImGui Demo", NULL, &show_Debug_ImGuiDemo); + ImGui::EndMenu(); + } + } + + if (ImGui::BeginMenu("Help")) + { + ImGui::MenuItem("About", NULL, &show_Help_About); + ImGui::EndMenu(); + } + ImGui::EndMenuBar(); + } + + SRTMGR::DrawFPSText(); + ImGui::End(); +} + +void __stdcall SRTMGR::UI::DrawHelpAboutUI(const bool &open) +{ + // Specify a default position/size in case there's no data in the .ini file. + ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_FirstUseEver); + + if (!ImGui::Begin("About", (bool *)&open, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize)) + { + ImGui::End(); + return; + } + + ImGui::Text(SRTMGR_APP_NAME); + ImGui::Text("v%d.%d.%d (Build #%d)", SRTMGR_VERSION_MAJOR, SRTMGR_VERSION_MINOR, SRTMGR_VERSION_PATCH, SRTMGR_VERSION_BUILD); + ImGui::Separator(); + ImGui::BulletText("Contributors\n\tSquirrelies"); + ImGui::Spacing(); + ImGui::Spacing(); + bool copyToClipboard = ImGui::Button("Copy to clipboard"); + ImGui::Spacing(); + if (ImGui::BeginChild("buildInfo", ImVec2(0, 0), ImGuiChildFlags_FrameStyle | ImGuiChildFlags_AutoResizeX | ImGuiChildFlags_AutoResizeY, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize)) + { + if (copyToClipboard) + { + ImGui::LogToClipboard(); + ImGui::LogText("```\n"); // Back quotes will make text appears without formatting when pasting on GitHub + } + + ImGui::Text(SRTMGR_APP_NAME); + ImGui::Text("v%d.%d.%d (Build #%d)", SRTMGR_VERSION_MAJOR, SRTMGR_VERSION_MINOR, SRTMGR_VERSION_PATCH, SRTMGR_VERSION_BUILD); + ImGui::Separator(); + ImGui::Text("Build datetime: %s %s", __DATE__, __TIME__); + ImGui::Text("Debug build: %s", IsDebug ? "true" : "false"); + ImGui::Text("sizeof(void *): %d", (int)sizeof(void *)); +#ifdef _WIN32 + ImGui::Text("define: _WIN32"); +#endif +#ifdef _WIN64 + ImGui::Text("define: _WIN64"); +#endif + ImGui::Text("define: __cplusplus=%d", (int)__cplusplus); +#ifdef __STDC__ + ImGui::Text("define: __STDC__=%d", (int)__STDC__); +#endif +#ifdef __STDC_VERSION__ + ImGui::Text("define: __STDC_VERSION__=%d", (int)__STDC_VERSION__); +#endif +#ifdef __GNUC__ + ImGui::Text("define: __GNUC__=%d", (int)__GNUC__); +#endif +#ifdef __clang_version__ + ImGui::Text("define: __clang_version__=%s", __clang_version__); +#endif + +#ifdef _MSC_VER + ImGui::Text("define: _MSC_VER=%d", _MSC_VER); +#endif +#ifdef _MSVC_LANG + ImGui::Text("define: _MSVC_LANG=%d", (int)_MSVC_LANG); +#endif +#ifdef __MINGW32__ + ImGui::Text("define: __MINGW32__"); +#endif +#ifdef __MINGW64__ + ImGui::Text("define: __MINGW64__"); +#endif + + if (copyToClipboard) + { + ImGui::LogText("\n```"); + ImGui::LogFinish(); + } + ImGui::EndChild(); + } + + ImGui::End(); +} + +bool SRTMGR::UI::CreateDeviceD3D(HWND hWnd) +{ + // Setup swap chain + DXGI_SWAP_CHAIN_DESC sd; + ZeroMemory(&sd, sizeof(sd)); + sd.BufferCount = 2; + sd.BufferDesc.Width = 0; + sd.BufferDesc.Height = 0; + sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + sd.BufferDesc.RefreshRate.Numerator = 60; + sd.BufferDesc.RefreshRate.Denominator = 1; + sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; + sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + sd.OutputWindow = hWnd; + sd.SampleDesc.Count = 1; + sd.SampleDesc.Quality = 0; + sd.Windowed = TRUE; + sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + + UINT createDeviceFlags = 0; + // createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; + D3D_FEATURE_LEVEL featureLevel; + const D3D_FEATURE_LEVEL featureLevelArray[2] = { + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_0, + }; + if (D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext) != S_OK) + return false; + + CreateRenderTarget(); + return true; +} + +void SRTMGR::UI::CleanupDeviceD3D() +{ + CleanupRenderTarget(); + if (g_pSwapChain) + { + g_pSwapChain->Release(); + g_pSwapChain = nullptr; + } + if (g_pd3dDeviceContext) + { + g_pd3dDeviceContext->Release(); + g_pd3dDeviceContext = nullptr; + } + if (g_pd3dDevice) + { + g_pd3dDevice->Release(); + g_pd3dDevice = nullptr; + } +} + +void SRTMGR::UI::CreateRenderTarget() +{ + ID3D11Texture2D *pBackBuffer; + g_pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer)); + g_pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &g_mainRenderTargetView); + pBackBuffer->Release(); +} + +void SRTMGR::UI::CleanupRenderTarget() +{ + if (g_mainRenderTargetView) + { + g_mainRenderTargetView->Release(); + g_mainRenderTargetView = nullptr; + } +} diff --git a/src/VersionInfo.rc.in b/src/VersionInfo.rc.in new file mode 100644 index 0000000..85875d6 --- /dev/null +++ b/src/VersionInfo.rc.in @@ -0,0 +1,65 @@ +#include + +#define VER_PRODUCTNAME_STR "@RC_PRODUCTNAME@\0" +#define VER_FILEDESCRIPTION_STR "@RC_FILEDESCRIPTION@\0" +#define VER_COMPANYNAME_STR "@RC_COMPANYNAME@\0" +#define VER_LEGALCOPYRIGHT_STR "@RC_LEGALCOPYRIGHT@\0" +#define VER_INTERNALNAME_STR "@RC_INTERNALNAME@\0" +#define VER_ORIGINALFILENAME_STR "@RC_ORIGINALFILENAME@\0" +#define VER_LEGALTRADEMARKS1_STR "\0" +#define VER_LEGALTRADEMARKS2_STR "\0" + +#define VER_FILEVERSION @RC_VERSION_MAJOR@,@RC_VERSION_MINOR@,@RC_VERSION_PATCH@,@RC_VERSION_BUILD@ +#define VER_FILEVERSION_STR "@RC_VERSION_MAJOR@.@RC_VERSION_MINOR@.@RC_VERSION_PATCH@.@RC_VERSION_BUILD@\0" + +#define VER_PRODUCTVERSION @RC_VERSION_MAJOR@,@RC_VERSION_MINOR@,@RC_VERSION_PATCH@,@RC_VERSION_BUILD@ +#define VER_PRODUCTVERSION_STR "@RC_VERSION_MAJOR@.@RC_VERSION_MINOR@.@RC_VERSION_PATCH@ (Build #@RC_VERSION_BUILD@)\0" + +#define VER_PRIVATEBUILD 0 +#define VER_PRERELEASE 0 + +#ifndef DEBUG +#define VER_DEBUG 0 +#else +#define VER_DEBUG VS_FF_DEBUG +#endif + +VS_VERSION_INFO VERSIONINFO +FILEVERSION VER_FILEVERSION +PRODUCTVERSION VER_PRODUCTVERSION +FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +FILEFLAGS (VER_PRIVATEBUILD|VER_PRERELEASE|VER_DEBUG) +FILEOS VOS__WINDOWS32 +FILETYPE VFT_DLL +FILESUBTYPE VFT2_UNKNOWN +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + BEGIN + VALUE "CompanyName", VER_COMPANYNAME_STR + VALUE "FileDescription", VER_FILEDESCRIPTION_STR + VALUE "FileVersion", VER_FILEVERSION_STR + VALUE "InternalName", VER_INTERNALNAME_STR + VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR + VALUE "LegalTrademarks1", VER_LEGALTRADEMARKS1_STR + VALUE "LegalTrademarks2", VER_LEGALTRADEMARKS2_STR + VALUE "OriginalFilename", VER_ORIGINALFILENAME_STR + VALUE "ProductName", VER_PRODUCTNAME_STR + VALUE "ProductVersion", VER_PRODUCTVERSION_STR + END + END + + BLOCK "VarFileInfo" + BEGIN + /* The following line should only be modified for localized versions. */ + /* It consists of any number of WORD,WORD pairs, with each pair */ + /* describing a language,codepage combination supported by the file. */ + /* */ + /* For example, a file might have values "0x409,1252" indicating that it */ + /* supports English language (0x409) in the Windows ANSI codepage (1252). */ + + VALUE "Translation", 0x409, 1252 + + END +END \ No newline at end of file diff --git a/tests/test_Strings.cpp b/tests/test_Strings.cpp new file mode 100644 index 0000000..7421e38 --- /dev/null +++ b/tests/test_Strings.cpp @@ -0,0 +1,17 @@ +#include + +TEST(GetStringSizeTests, CorrectValueA) +{ + EXPECT_EQ(sizeof("123"), (size_t)4); +} + +TEST(GetStringSizeTests, CorrectValueW) +{ + EXPECT_EQ(sizeof(L"123"), (size_t)8); +} + +int wmain(int argc, wchar_t *argv[]) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/vcpkg-configuration.json b/vcpkg-configuration.json new file mode 100644 index 0000000..1ec898f --- /dev/null +++ b/vcpkg-configuration.json @@ -0,0 +1,17 @@ +{ + "default-registry": { + "kind": "git", + "baseline": "f1c6efee2245009540dde947e0e3d008f3aa7dbb", + "repository": "https://github.com/microsoft/vcpkg" + }, + "registries": [ + { + "kind": "artifact", + "location": "https://github.com/microsoft/vcpkg-ce-catalog/archive/refs/heads/main.zip", + "name": "microsoft" + } + ], + "overlay-triplets": [ + "./vcpkg/triplets" + ] +} \ No newline at end of file diff --git a/vcpkg.json b/vcpkg.json new file mode 100644 index 0000000..9cf62f3 --- /dev/null +++ b/vcpkg.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json", + "dependencies": [ + "gtest", + "sdl2", + { + "name": "imgui", + "features": [ + "dx11-binding", + "sdl2-binding", + "docking-experimental" + ] + } + ] +} \ No newline at end of file diff --git a/vcpkg/triplets/x64-mingw-dynamic-custom.cmake b/vcpkg/triplets/x64-mingw-dynamic-custom.cmake new file mode 100644 index 0000000..02e5182 --- /dev/null +++ b/vcpkg/triplets/x64-mingw-dynamic-custom.cmake @@ -0,0 +1,16 @@ +# Determine VCPKG_ROOT +if (NOT DEFINED VCPKG_ROOT) + message(STATUS "VCPKG_ROOT is not defined. Checking for environment variable...") + if (DEFINED ENV{VCPKG_ROOT}) + set(VCPKG_ROOT $ENV{VCPKG_ROOT}) + message(STATUS "VCPKG_ROOT found in environment variables. VCPKG_ROOT is now set to ${VCPKG_ROOT}") + else() + set(VCPKG_ROOT "C:/vcpkg") + message(STATUS "VCPKG_ROOT not found in environment variables. VCPKG_ROOT is now set to ${VCPKG_ROOT}") + endif() +endif() + +include(${VCPKG_ROOT}/triplets/community/x64-mingw-dynamic.cmake) + +set(VCPKG_C_FLAGS ${VCPKG_C_FLAGS} -DIM_ASSERT\(_EXPR\)=\(\(void\)\(_EXPR\)\)) +set(VCPKG_CXX_FLAGS ${VCPKG_CXX_FLAGS} -DIM_ASSERT\(_EXPR\)=\(\(void\)\(_EXPR\)\)) diff --git a/vcpkg/triplets/x64-mingw-static-custom.cmake b/vcpkg/triplets/x64-mingw-static-custom.cmake new file mode 100644 index 0000000..eb427e9 --- /dev/null +++ b/vcpkg/triplets/x64-mingw-static-custom.cmake @@ -0,0 +1,16 @@ +# Determine VCPKG_ROOT +if (NOT DEFINED VCPKG_ROOT) + message(STATUS "VCPKG_ROOT is not defined. Checking for environment variable...") + if (DEFINED ENV{VCPKG_ROOT}) + set(VCPKG_ROOT $ENV{VCPKG_ROOT}) + message(STATUS "VCPKG_ROOT found in environment variables. VCPKG_ROOT is now set to ${VCPKG_ROOT}") + else() + set(VCPKG_ROOT "C:/vcpkg") + message(STATUS "VCPKG_ROOT not found in environment variables. VCPKG_ROOT is now set to ${VCPKG_ROOT}") + endif() +endif() + +include(${VCPKG_ROOT}/triplets/community/x64-mingw-static.cmake) + +set(VCPKG_C_FLAGS ${VCPKG_C_FLAGS} -DIM_ASSERT\(_EXPR\)=\(\(void\)\(_EXPR\)\)) +set(VCPKG_CXX_FLAGS ${VCPKG_CXX_FLAGS} -DIM_ASSERT\(_EXPR\)=\(\(void\)\(_EXPR\)\))