diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json new file mode 100644 index 0000000..64d50c9 --- /dev/null +++ b/.config/dotnet-tools.json @@ -0,0 +1,18 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "ezpipeline": { + "version": "0.0.46", + "commands": [ + "ezpipeline" + ] + }, + "unofficial.Urho3DNet.Editor": { + "version": "0.3.7.842", + "commands": [ + "rbfx" + ] + } + } +} diff --git a/.github/workflows/build-master.yml b/.github/workflows/build-master.yml new file mode 100644 index 0000000..27beae8 --- /dev/null +++ b/.github/workflows/build-master.yml @@ -0,0 +1,371 @@ +name: BuildGame + +on: + push: + branches: [ "master", "main" ] + +permissions: + contents: write + +jobs: + # --------------------------------------------------------------------------------------- + set_version: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Setup .NET + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 8.0.x + + - name: Restore tools + run: dotnet tool restore + + - name: Get version + run: dotnet tool run ezpipeline git-height-version -- -b 0.0.1 -v BUILD_VERSION + + - name: Get android version + run: dotnet tool run ezpipeline git-height-version -- -v ANDROID_VERSION + + - name: Create Release + uses: softprops/action-gh-release@v1 + with: + name: v${{ env.BUILD_VERSION }} + tag_name: v${{ env.BUILD_VERSION }} + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Check for Secret PLAY_KEYSTORE + id: play-keystore-check + run: | + if [ "${{ secrets.PLAY_KEYSTORE }}" != '' ]; then + echo "HAS_PLAY_KEYSTORE=true" >> "$GITHUB_OUTPUT" + else + echo "HAS_PLAY_KEYSTORE=false" >> "$GITHUB_OUTPUT" + fi + + - name: Check for STEAM_USERNAME + id: steam-check + run: | + if [ "${{ secrets.STEAM_USERNAME }}" != '' ]; then + echo "HAS_STEAM_USERNAME=true" >> "$GITHUB_OUTPUT" + else + echo "HAS_STEAM_USERNAME=false" >> "$GITHUB_OUTPUT" + fi + + outputs: + BUILD_VERSION: ${{ env.BUILD_VERSION }} + ANDROID_VERSION: ${{ env.ANDROID_VERSION }} + HAS_PLAY_KEYSTORE: ${{ steps.play-keystore-check.outputs.HAS_PLAY_KEYSTORE }} + HAS_STEAM_USERNAME: ${{ steps.steam-check.outputs.HAS_STEAM_USERNAME }} + + # --------------------------------------------------------------------------------------- + tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Setup .NET + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 8.0.x + + - name: Restore tools + run: dotnet tool restore + + - name: Test in Debug configuration + working-directory: ./RbfxTemplate.Tests + run: dotnet test --configuration Debug --verbosity normal + + - name: Test in Release configuration + working-directory: ./RbfxTemplate.Tests + run: dotnet test --configuration Release --verbosity normal + + # --------------------------------------------------------------------------------------- + build_desktop: + needs: [set_version, tests] + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [macos-13, windows-latest, ubuntu-latest] + + steps: + - uses: actions/checkout@v3 + with: + submodules: recursive + fetch-depth: 1 + + - name: Evaluate target runtime + shell: bash + run: | + echo "OS: $OSTYPE" + if [[ "$OSTYPE" == "darwin"* ]]; then + echo "RUNTIME_ID: osx-x64" + echo "RUNTIME_ID=osx-x64" >> $GITHUB_ENV + elif [[ "$OSTYPE" == "linux"* ]]; then + echo "RUNTIME_ID: linux-x64" + echo "RUNTIME_ID=linux-x64" >> $GITHUB_ENV + elif [[ "$OSTYPE" == "msys"* ]]; then + echo "RUNTIME_ID: win-x64" + echo "RUNTIME_ID=win-x64" >> $GITHUB_ENV + else + echo "Unrecognized OS type $OSTYPE" + exit 1 + fi + + - name: Setup .NET + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 8.0.x + + - name: Restore tools + run: dotnet tool restore + + - name: Restore dependencies + working-directory: ./RbfxTemplate.Desktop + run: dotnet restore + + - name: Dotnet Publish + working-directory: ./RbfxTemplate.Desktop + run: dotnet publish -f net8.0 -c Release --runtime ${{ env.RUNTIME_ID }} --self-contained true -p:Version=${{ needs.set_version.outputs.BUILD_VERSION }} + + - name: Copy runtime dlls + if: ${{ env.RUNTIME_ID == 'win-x64' }} + run: | + copy "C:/Windows/System32/MSVCP140.dll" "RbfxTemplate.Desktop/bin/Release/net8.0/${{ env.RUNTIME_ID }}/publish/" + copy "C:/Windows/System32/VCRUNTIME140.dll" "RbfxTemplate.Desktop/bin/Release/net8.0/${{ env.RUNTIME_ID }}/publish/" + copy "C:/Windows/System32/VCRUNTIME140_1.dll" "RbfxTemplate.Desktop/bin/Release/net8.0/${{ env.RUNTIME_ID }}/publish/" + copy "C:/Windows/System32/D3DCOMPILER_47.dll" "RbfxTemplate.Desktop/bin/Release/net8.0/${{ env.RUNTIME_ID }}/publish/" + + - name: Zip Package + run: dotnet tool run ezpipeline -- zip -i RbfxTemplate.Desktop/bin/Release/net8.0/${{ env.RUNTIME_ID }}/publish/ -o RbfxTemplate.${{ env.RUNTIME_ID }}.zip + + - name: Release + uses: softprops/action-gh-release@v1 + with: + files: | + ./RbfxTemplate.${{ env.RUNTIME_ID }}.zip + name: v${{ needs.set_version.outputs.BUILD_VERSION }} + tag_name: v${{ needs.set_version.outputs.BUILD_VERSION }} + token: ${{ secrets.GITHUB_TOKEN }} + + # ------------ itch.io ------------ + - name: Release to itch.io ${{ vars.ITCH_PROJECT }} + env: + BUTLER_API_KEY: ${{ secrets.BUTLER_API_KEY }} + if: ${{ env.BUTLER_API_KEY != '' && vars.ITCH_PROJECT != '' }} + run: | + dotnet tool run ezpipeline -- fetch-tool --name Butler -o tools/itch + tools/itch/butler push RbfxTemplate.Desktop/bin/Release/net8.0/${{ env.RUNTIME_ID }}/publish/ ${{ vars.ITCH_PROJECT }}:${{ env.RUNTIME_ID }} + shell: bash + + # --------------------------------------------------------------------------------------- + build_android: + needs: [set_version, tests] + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + with: + submodules: recursive + fetch-depth: 1 + + - name: Setup .NET + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 8.0.x + + - name: Restore tools + run: dotnet tool restore + + - name: Install Workloads + run: dotnet workload install android + + - name: Restore dependencies + working-directory: ./RbfxTemplate.Android + run: dotnet restore + + - name: Install android-sdk + shell: bash + run: | + sudo apt-get install -y wget tar android-sdk unzip tree + echo $ANDROID_HOME + sudo chmod -R a+rw $ANDROID_HOME + + - name: Fetch AndroidSDKManager + run: | + dotnet tool run ezpipeline fetch-tool -n AndroidSDKManager --output $ANDROID_HOME --path --version 9123335 + yes | $ANDROID_HOME/cmdline-tools/bin/sdkmanager --licenses --sdk_root=$ANDROID_HOME + + - name: 'Print Java version' + run: javac -version + + - name: Install Android SDK and Platforms + run: $ANDROID_HOME/cmdline-tools/bin/sdkmanager "platform-tools" "platforms;android-33" --sdk_root=$ANDROID_HOME + + - name: Decode Keystore + id: decode_keystore + if: ${{ needs.set_version.outputs.HAS_PLAY_KEYSTORE == 'true' }} + uses: timheuer/base64-to-file@v1 + with: + fileDir: '${{ github.workspace }}/RbfxTemplate.Android' + fileName: 'googleplay.jks' + encodedString: ${{ secrets.PLAY_KEYSTORE }} + + - name: Extract ApplicationId from RbfxTemplate.Android.csproj + working-directory: ./RbfxTemplate.Android + run: | + dotnet tool run ezpipeline get-msbuild-property -i RbfxTemplate.Android.csproj -p ApplicationId -v ANDROID_PACKAGENAME + + - name: Dotnet Publish + working-directory: ./RbfxTemplate.Android + run: | + if [ -n "${{ secrets.PLAY_KEYSTORE }}" ]; then + echo "Secret PLAY_KEYSTORE is defined. Building and signing the aab file." + dotnet publish -f net8.0-android -c Release --no-restore -p:ApplicationId=${{ env.ANDROID_PACKAGENAME }} -p:ApplicationDisplayVersion=${{ needs.set_version.outputs.BUILD_VERSION }} -p:ApplicationVersion=${{ needs.set_version.outputs.ANDROID_VERSION }} -p:AndroidSdkDirectory=$ANDROID_HOME -p:Version=${{ needs.set_version.outputs.BUILD_VERSION }} /p:AndroidKeyStore=true /p:AndroidSigningKeyStore=googleplay.jks /p:AndroidSigningKeyAlias=${{secrets.PLAY_KEYSTORE_ALIAS}} /p:AndroidSigningKeyPass="${{ secrets.PLAY_KEYSTORE_PASS }}" /p:AndroidSigningStorePass="${{ secrets.PLAY_KEYSTORE_PASS }}" + else + echo "Secret PLAY_KEYSTORE is not defined. Building with no signature." + dotnet publish -f net8.0-android -c Release --no-restore -p:ApplicationId=${{ env.ANDROID_PACKAGENAME }} -p:ApplicationDisplayVersion=${{ needs.set_version.outputs.BUILD_VERSION }} -p:ApplicationVersion=${{ needs.set_version.outputs.ANDROID_VERSION }} -p:AndroidSdkDirectory=$ANDROID_HOME -p:Version=${{ needs.set_version.outputs.BUILD_VERSION }} + fi + + - name: Find APK + run: | + dotnet tool run ezpipeline resolve-path -i ./RbfxTemplate.Android/bin/Release/**/*-Signed.apk -v APK_PATH + dotnet tool run ezpipeline resolve-path -i ./RbfxTemplate.Android/bin/Release/**/*-Signed.aab -v AAB_PATH + + - name: Release + uses: softprops/action-gh-release@v1 + with: + files: | + ${{ env.APK_PATH }} + ${{ env.AAB_PATH }} + name: v${{ needs.set_version.outputs.BUILD_VERSION }} + tag_name: v${{ needs.set_version.outputs.BUILD_VERSION }} + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Release to itch.io ${{ vars.ITCH_PROJECT }} + env: + BUTLER_API_KEY: ${{ secrets.BUTLER_API_KEY }} + if: ${{ env.BUTLER_API_KEY != '' && vars.ITCH_PROJECT != '' }} + run: | + dotnet tool run ezpipeline -- fetch-tool --name Butler -o tools/itch + tools/itch/butler push ${{ env.APK_PATH }} ${{ vars.ITCH_PROJECT }}:android + shell: bash + + - uses: r0adkll/upload-google-play@v1.1.3 + name: Upload Android Artifact to Play Console + env: + PLAYSTORE_SERVICE_ACC: ${{ secrets.PLAYSTORE_SERVICE_ACC }} + if: ${{ env.PLAYSTORE_SERVICE_ACC != '' }} + with: + serviceAccountJsonPlainText: ${{ secrets.PLAYSTORE_SERVICE_ACC }} + packageName: ${{ env.ANDROID_PACKAGENAME }} + releaseFiles: ${{ env.AAB_PATH }} + track: internal + # --------------------------------------------------------------------------------------- + build_uwp: + needs: [set_version, tests] + runs-on: windows-latest + + steps: + - uses: actions/checkout@v3 + with: + submodules: recursive + fetch-depth: 1 + + - name: Setup .NET + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 8.0.x + + - name: Add msbuild to PATH + uses: microsoft/setup-msbuild@v1.1 + + - name: Restore tools + run: dotnet tool restore + + - name: Restore application + working-directory: ./RbfxTemplate.UWP + run: msbuild RbfxTemplate.UWP.csproj /t:Restore /p:Configuration=Release + + - name: Patch manifest version + working-directory: ./RbfxTemplate.UWP + run: dotnet tool run ezpipeline -- set-xml -i Package.appxmanifest -p default:Package/default:Identity -a Version -v ${{ needs.set_version.outputs.BUILD_VERSION }}.0 + + - name: Dotnet Publish + working-directory: ./RbfxTemplate.UWP + run: msbuild RbfxTemplate.UWP.csproj /p:AppxPackageDir=appxupload /p:AppxBundle=Always /p:AppxBundlePlatforms="x64" /p:Platform=x64 /p:AppxPackageSigningEnabled=false /p:UapAppxPackageBuildMode=StoreUpload /p:Configuration=Release /p:Version=${{ needs.set_version.outputs.BUILD_VERSION }} + + - name: Zip Package + run: dotnet tool run ezpipeline -- zip -i RbfxTemplate.UWP/appxupload/RbfxTemplate.UWP_${{ needs.set_version.outputs.BUILD_VERSION }}.0_Test -o RbfxTemplate.UWP/appxupload/RbfxTemplate.UWP.x64.zip + + - name: Release + uses: softprops/action-gh-release@v1 + with: + files: | + RbfxTemplate.UWP/appxupload/RbfxTemplate.UWP_${{ needs.set_version.outputs.BUILD_VERSION }}.0_x64_bundle.appxupload + RbfxTemplate.UWP/appxupload/RbfxTemplate.UWP.x64.zip + name: v${{ needs.set_version.outputs.BUILD_VERSION }} + tag_name: v${{ needs.set_version.outputs.BUILD_VERSION }} + token: ${{ secrets.GITHUB_TOKEN }} + + # ------------ Steam ------------ + publish_to_steam: + needs: [set_version, build_desktop] + runs-on: ubuntu-latest + if: needs.set_version.outputs.HAS_STEAM_USERNAME == 'true' + steps: + - name: Download Windows Build + uses: robinraju/release-downloader@v1 + with: + repository: ${{ github.repository }} + tag: v${{ needs.set_version.outputs.BUILD_VERSION }} + fileName: 'RbfxTemplate.win-x64.zip' + token: ${{ secrets.GITHUB_TOKEN }} + out-file-path: ./StandaloneWindows64 + extract: true + + - name: Download Linux Build + uses: robinraju/release-downloader@v1 + with: + repository: ${{ github.repository }} + tag: v${{ needs.set_version.outputs.BUILD_VERSION }} + fileName: 'RbfxTemplate.linux-x64.zip' + token: ${{ secrets.GITHUB_TOKEN }} + out-file-path: ./StandaloneLinux64 + extract: true + + - name: Download Mac Build + uses: robinraju/release-downloader@v1 + with: + repository: ${{ github.repository }} + tag: v${{ needs.set_version.outputs.BUILD_VERSION }} + fileName: 'RbfxTemplate.osx-x64.zip' + token: ${{ secrets.GITHUB_TOKEN }} + out-file-path: ./StandaloneMac64 + extract: true + + - name: Delete RbfxTemplate.*-x64.zip + run: | + ROOT_FOLDER="./" + PATTERN="*RbfxTemplate.*-x64.zip" + find "$ROOT_FOLDER" -type f -name "$PATTERN" -exec rm -f {} + + + - uses: game-ci/steam-deploy@v3 + env: + STEAM_USERNAME: ${{ secrets.STEAM_USERNAME }} + name: Steam - Publish + with: + username: ${{ secrets.STEAM_USERNAME }} + configVdf: ${{ secrets.STEAM_CONFIG_VDF }} + appId: ${{ secrets.STEAM_APPID }} + buildDescription: v${{ needs.set_version.outputs.BUILD_VERSION }} + rootPath: ./ + depot1Path: StandaloneWindows64 + depot2Path: StandaloneLinux64 + depot3Path: StandaloneMac64 + releaseBranch: prerelease diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..188e1c3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,270 @@ +syntax: glob + +#NuGet things +project.lock.json + +### VisualStudio ### + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +msbuild.log + +# Visual Studio 2015 +.vs/ + +# Visual Studio 2015 Pre-CTP6 +*.sln.ide +*.ide/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +#NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding addin-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml + +# 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 +*.pubxml +*.publishproj + +# NuGet Packages +*.nupkg +**/packages/* + +# Windows Azure Build Output +csx/ +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +sql/ +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*.dbmdl +*.dbproj.schemaview +*.pfx +*.publishsettings +node_modules/ +*.metaproj +*.metaproj.tmp + +# 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 + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +### MonoDevelop ### + +*.pidb +*.userprefs + +### Windows ### + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp + +# Windows shortcuts +*.lnk + +### Linux ### + +*~ + +# KDE directory preferences +.directory + +### OSX ### + +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear on external disk +.Spotlight-V100 +.Trashes + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# vim temporary files +[._]*.s[a-w][a-z] +[._]s[a-w][a-z] +*.un~ +Session.vim +.netrwhist +*~ + +*.ini +*.VC.db +*.nvact +*.opendb + +#VS Code stuff + +.vscode +launchSettings.json + +# Generated shaders +Shaders.Generated + +# RBFX Editor sattelite files +*.user.json + +RbfxTemplate/Content/Common +*.jks +googleplay.txt diff --git a/.template.config/template.json b/.template.config/template.json new file mode 100644 index 0000000..5700d1e --- /dev/null +++ b/.template.config/template.json @@ -0,0 +1,87 @@ +{ + "$schema": "http://json.schemastore.org/template", + + // The author of the template + "author": "rbfx", + + // Zero or more characteristics of the template which may be used in search. In this field you define the values shown as Tags in dotnet new + "classifications": [ "Common", "Solution" ], + + // The name for the template. This is displayed as the template name when using dotnet new and Visual Studio. + "name": "Rebel Framework Casual Project Template", + + // A unique name for this template + "identity": "rbfx.template.casual", + + // A name for selecting the template in CLI environment. + // This is the name shown as Short Name in dotnet new list of templates, and is the name to use to run this template. + "shortName": "rbfx.casual", + + // The name in the source tree to replace with the name the user specifies. + // The value to be replaced with can be given using the -n --name options while running a template. + // The template engine will look for any occurrence of the name present in the config file and replace it in file names and file contents. + // If no name is specified by the host, the current directory is used. + // The value of the sourceName is available in built-in name symbol and can be used as the source for creating other symbols and condition expressions. + "sourceName": "RbfxTemplate", + + // An optional list of guids which appear in the template source and should be replaced in the template output. + "guids": [ + "{DAAE87E1-EBB6-472A-98D6-1411941CFD8E}", + "{AC46195D-9A59-4725-8A77-E2309185C707}", + "{E5A649CE-987F-46FE-8FA8-1290951AE21D}", + "{E15D7151-C812-4432-AB2A-F9EF06E4DF73}", + "{70D12BD7-3CFE-48B6-8E28-B9554FB21AD0}", + "{6EC5CAE7-DD30-4181-ADF2-B1BA19BA84F0}", + "{7DE6BF8D-C5F4-4C2A-8F02-525A97B81F1D}", + "{39ad144a-075c-4e1b-9d81-1a1e4672a258}" + ], + + // You can use tags to improve the metadata of your project. + // Well-known tags are: language and type. To specify the template language, use the tag language. + // To specify the template type, use the tag type. Supported types are: project, item, solution. + "tags": { + "language": "C#", + "type": "project" + }, + + // The symbols section defines variables and their values, the values may be the defined in terms of other symbols. + "symbols": { + "skipRestore": { + "type": "parameter", + "datatype": "bool", + "description": "If specified, skips the automatic restore of the project on create.", + "defaultValue": "false" + } + }, + + // The set of mappings in the template content to user directories. It's defined as any array of Source + // "sources": [ + // ] + + // A list of template files for further processing by the host (including post-actions). + // The path should contain the relative path to the file prior to the symbol based renaming that may happen during template generation. + // It is defined as an array of Primary Outputs + "primaryOutputs": [ + { + "path": "RbfxTemplate\\RbfxTemplate.csproj" + }, + { + "path": "RbfxTemplate.Android\\RbfxTemplate.Android.csproj" + }, + { + "path": "RbfxTemplate.Desktop\\RbfxTemplate.Desktop.csproj" + }, + { + "path": "RbfxTemplate.IOS\\RbfxTemplate.IOS.csproj" + }, + { + "path": "RbfxTemplate.Tests\\RbfxTemplate.Tests.csproj" + }, + { + "path": "RbfxTemplate.UWP\\RbfxTemplate.UWP.csproj" + } + ], + + // The set of globing patterns indicating the content that was included by sources.include that should not be processed + "exclude": ["**/[Bb]in/**", "**/[Oo]bj/**", ".template.config/**/*", "**/*.lock.json"] +} \ No newline at end of file diff --git a/Content/Android/Data/android.txt b/Content/Android/Data/android.txt new file mode 100644 index 0000000..e69de29 diff --git a/Content/Common/.gitignore b/Content/Common/.gitignore new file mode 100644 index 0000000..e2fcb36 --- /dev/null +++ b/Content/Common/.gitignore @@ -0,0 +1,19 @@ +# Ignore asset cache +/Cache.json + +# Ignore temporary files +/Temp/ + +# Ignore UI settings +/ui.ini + +# Ignore preview screenshot +/Preview.png + +# Ignore artifacts +/Artifacts/ + +# Ignore internal files +*.blend1 +*.user.json + diff --git a/Content/Common/Cache/common_cache.txt b/Content/Common/Cache/common_cache.txt new file mode 100644 index 0000000..bb1f62c --- /dev/null +++ b/Content/Common/Cache/common_cache.txt @@ -0,0 +1 @@ +When editor import files it will place assets in the Cache folder. \ No newline at end of file diff --git a/Content/Common/Data/Fonts/Anonymous Pro.ttf b/Content/Common/Data/Fonts/Anonymous Pro.ttf new file mode 100644 index 0000000..06aafc0 Binary files /dev/null and b/Content/Common/Data/Fonts/Anonymous Pro.ttf differ diff --git a/Content/Common/Data/Fonts/ArchivoBlack-Regular.ttf b/Content/Common/Data/Fonts/ArchivoBlack-Regular.ttf new file mode 100644 index 0000000..ebadf62 Binary files /dev/null and b/Content/Common/Data/Fonts/ArchivoBlack-Regular.ttf differ diff --git a/Content/Common/Data/Fonts/OFL.txt b/Content/Common/Data/Fonts/OFL.txt new file mode 100644 index 0000000..ef84be7 --- /dev/null +++ b/Content/Common/Data/Fonts/OFL.txt @@ -0,0 +1,93 @@ +Copyright 2019 The Cherry Bomb Project Authors (https://github.com/satsuyako/CherryBomb) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/Content/Common/Data/Fonts/read_me.html b/Content/Common/Data/Fonts/read_me.html new file mode 100644 index 0000000..9f53dc8 --- /dev/null +++ b/Content/Common/Data/Fonts/read_me.html @@ -0,0 +1,2 @@ +Larabie Fonts "read me" file, license and FAQ

LARABIE FONTS “README.TXT”

All Larabie Fonts in this file are free to use for personal and/or commercial purposes. No payment is necessary to use these fonts for personal or commercial use. For Software Products who want to include Larabie Fonts see the License Agreement below. You can add this font to a website but do not combine fonts into a single archive or alter them in any way.

All Larabie Fonts are free for commercial use but a sample of your product would be gratefully appreciated so I can see how the font looks in use. Contact www.larabiefonts.com/donation.html for mailing information.

Some Larabie Fonts have enhanced and expanded families available for sale at www.typodermic.com.

If you'd like to make a voluntary donation to Larabie Fonts for the use of the free fonts in any amount please go to www.larabiefonts.com/donation.html

I accept CDs, magazines, t-shirts, a sample of your merchandise or anything featuring Larabie Fonts. Please remember to list your item as a ‘gift’ on the customs form or I will have to pay import duties and taxes on the item. Mailing information is provided at the link above.

Font installation help is available at www.larabiefonts.com/help.html

LARABIE FONTS FREQUENTLY ASKED QUESTIONS

LARABIE FONTS END-USER LICENSE AGREEMENT FOR SOFTWARE PRODUCTS

SOFTWARE PRODUCT LICENSE

The SOFTWARE PRODUCT is protected by copyright laws and International copyright treaties, as well as other intellectual property laws and treaties. The SOFTWARE PRODUCT is licensed, not sold.

1. GRANT OF LICENSE. This document grants you the following rights:

- Installation and Use. You may install and use an unlimited number of copies of the SOFTWARE PRODUCT. You may copy and distribute unlimited copies of the SOFTWARE PRODUCT as you receive them, in any medium, provided that you publish on each copy an appropriate copyright notice. Keep intact all the notices that refer to this License and give any other recipients of the fonts a copy of this License along with the fonts.

2. DESCRIPTION OF OTHER RIGHTS AND LIMITATIONS.

- You may modify your copy or copies of the SOFTWARE PRODUCT or any portion of it, provided that you also meet all of these rules:

a) Do not alter in any way alphanumeric characters (A-Z, a-z, 1-9) contained in the font. An exception is converting between formats, here is allowed the nominal distortion that occurs during conversion from second order to third order quadratic curves (TrueType to Postscript) and vice versa.

b) Extra characters may be added; here it is allowed to use curves (shapes) from alphanumeric characters in fonts under same license.

c) It is allowed to modify and remove analpahbetics (punctuation, special characters, ligatures and symbols).

d) The original font name must be retained but can be augmented. (ie. a Font named Blue Highway can be renamed Blue Highway Cyrillic or Blue Highway ANSI, etc.)

e) Character mapping may be altered.

f) If the kerning information is altered or discarded it must be stated in the user notes or documentation.

g) All modifications must be released under this license.

LIMITED WARRANTY NO WARRANTIES. Larabie Fonts expressly disclaims any warranty for the SOFTWARE PRODUCT. The SOFTWARE PRODUCT and any related documentation is provided "as is" without warranty of any kind, either express or implied, including, without limitation, the implied warranties or merchantability, fitness for a particular purpose, or non-infringement. The entire risk arising out of use or performance of the SOFTWARE PRODUCT remains with you.

NO LIABILITY FOR CONSEQUENTIAL DAMAGES. In no event shall Larabie Fonts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or any other pecuniary loss) arising out of the use of or inability to use this product, even if Larabie Fonts has been advised of the possibility of such damages.

3. MISCELLANEOUS

Should you have any questions concerning this document, or if you desire to contact Larabie Fonts for any reason, please email www.larabiefonts.com/email.html.

+ diff --git a/Content/Common/Data/Images/Background.png b/Content/Common/Data/Images/Background.png new file mode 100644 index 0000000..b09e58b Binary files /dev/null and b/Content/Common/Data/Images/Background.png differ diff --git a/Content/Common/Data/Images/Splash.png b/Content/Common/Data/Images/Splash.png new file mode 100644 index 0000000..84529a3 Binary files /dev/null and b/Content/Common/Data/Images/Splash.png differ diff --git a/Content/Common/Data/Materials/Skyplane.xml b/Content/Common/Data/Materials/Skyplane.xml new file mode 100644 index 0000000..74331d3 --- /dev/null +++ b/Content/Common/Data/Materials/Skyplane.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Content/Common/Data/Scenes/Scene.scene b/Content/Common/Data/Scenes/Scene.scene new file mode 100644 index 0000000..2802763 --- /dev/null +++ b/Content/Common/Data/Scenes/Scene.scene @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Content/Common/Data/UI/GameScreen.rml b/Content/Common/Data/UI/GameScreen.rml new file mode 100644 index 0000000..2c8dd42 --- /dev/null +++ b/Content/Common/Data/UI/GameScreen.rml @@ -0,0 +1,81 @@ + + + + + + + + + + + +
+
Level complete!
+ + + Next + +
+ + + + +
\ No newline at end of file diff --git a/Content/Common/Data/UI/MainMenu.rml b/Content/Common/Data/UI/MainMenu.rml new file mode 100644 index 0000000..ff912ed --- /dev/null +++ b/Content/Common/Data/UI/MainMenu.rml @@ -0,0 +1,61 @@ + + + + + + + + + + +
+ + + +
+ + +
diff --git a/Content/Common/Data/UI/Options.rml b/Content/Common/Data/UI/Options.rml new file mode 100644 index 0000000..ecf3cb8 --- /dev/null +++ b/Content/Common/Data/UI/Options.rml @@ -0,0 +1,82 @@ + + + + + + + + + + + + diff --git a/Content/Common/Data/UI/PrivacyPolicy.rml b/Content/Common/Data/UI/PrivacyPolicy.rml new file mode 100644 index 0000000..4ade386 --- /dev/null +++ b/Content/Common/Data/UI/PrivacyPolicy.rml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + diff --git a/Content/Common/Data/UI/casual.png b/Content/Common/Data/UI/casual.png new file mode 100644 index 0000000..5c71aec Binary files /dev/null and b/Content/Common/Data/UI/casual.png differ diff --git a/Content/Common/Data/UI/casual.rcss b/Content/Common/Data/UI/casual.rcss new file mode 100644 index 0000000..76012af --- /dev/null +++ b/Content/Common/Data/UI/casual.rcss @@ -0,0 +1,422 @@ +@spritesheet theme +{ + src: casual.png; + blue-button: 478.27417px 4px 28px 48px; + blue-button-inner: 491.27417px 25px 2px 2px; + blue-button-hover: 4px 118px 28px 48px; + blue-button-hover-inner: 17px 135px 2px 2px; + blue-button-active: 40px 118px 28px 48px; + blue-button-active-inner: 53px 141px 2px 2px; + blue-button-disabled: 76px 118px 28px 48px; + blue-button-disabled-inner: 89px 143px 2px 2px; + orange-button: 112px 118px 28px 48px; + orange-button-inner: 125px 139px 2px 2px; + orange-button-hover: 148px 118px 28px 48px; + orange-button-hover-inner: 161px 135px 2px 2px; + orange-button-active: 184px 118px 28px 48px; + orange-button-active-inner: 197px 141px 2px 2px; + orange-button-disabled: 220px 118px 28px 48px; + orange-button-disabled-inner: 233px 143px 2px 2px; + gray-inner-panel: 112px 4px 52px 58px; + gray-inner-panel-inner: 137px 31px 2px 2px; + gray-outer-panel: 4px 4px 100px 106px; + gray-outer-panel-inner: 53px 55px 2px 2px; + gray-header-panel: 396px 70px 4px 10px; + gray-header-panel-inner: 397px 73px 2px 2px; + gray-footer-panel: 408px 70px 4px 8px; + gray-footer-panel-inner: 409px 73px 2px 2px; + slidertrack: 182px 70px 14px 22px; + slidertrack-inner: 188px 80px 2px 2px; + sliderbar: 204px 70px 16px 28px; + sliderbar-inner: 211px 81px 2px 2px; + blue-checkbox: 172px 4px 30.284271px 50.28427px; + blue-checkbox-hover: 210.28427px 4px 30.284271px 50.28427px; + blue-checkbox-active: 248.56854px 4px 30.284271px 50.28427px; + blue-checkbox-disabled: 286.8528px 4px 30.284271px 50.28427px; + blue-checkbox-checked: 325.1371px 4px 30.284271px 50.28427px; + blue-checkbox-checked-hover: 363.42136px 4px 30.284271px 50.28427px; + blue-checkbox-checked-active: 401.70563px 4px 30.284271px 50.28427px; + blue-checkbox-checked-disabled: 439.9899px 4px 30.284271px 50.28427px; + blue-slider-slidertrack: 112px 70px 26px 34px; + blue-slider-slidertrack-inner: 124px 86px 2px 2px; + blue-slider-sliderbar: 146px 70px 28px 40px; + blue-slider-sliderbar-inner: 159px 87px 2px 2px; + selectarrow: 228px 70px 20px 20px; + icon-diamond: 256px 70px 20px 20px; + icon-money: 284px 70px 20px 20px; + icon-settings: 312px 70px 20px 20px; + icon-xbox: 340px 70px 20px 20px; + icon-discord: 368px 70px 20px 20px; + +} +input.blue-button, +select.blue-button, +select.blue-button selectbox +{ + decorator: ninepatch( blue-button, blue-button-inner, 1.0 ); + box-sizing: border-box; + vertical-align: center; + overflow: auto; + display: inline-block; + min-width: 28px; + min-height: 48px; + text-align: center; + font-effect: outline(1px #333), shadow(0px 3px #333); + padding-top: 16.5px; + padding-right: 12.5px; + padding-bottom: 20.5px; + padding-left: 12.5px; +} +select.blue-button, +select.blue-button selectbox +{ + text-align: left; + padding-top: 16.5px; + padding-right: 12.5px; + padding-bottom: 40.5px; + padding-left: 12.5px; +} +select.blue-button selectvalue +{ + padding-right: 60px; +} +select.blue-button selectbox option:hover +{ + font-effect: outline(1px #333), shadow(0px 3px #333); + background: #1E90FF; +} +input.blue-button:hover, +input.blue-button:focus-visible, +select.blue-button:hover, +select.blue-button:focus-visible +{ + decorator: ninepatch( blue-button-hover, blue-button-hover-inner, 1.0 ); + padding-top: 12.5px; + padding-right: 12.5px; + padding-bottom: 24.5px; + padding-left: 12.5px; +} +select.blue-button:hover, +select.blue-button:focus-visible +{ + text-align: left; + padding-top: 12.5px; + padding-right: 12.5px; + padding-bottom: 44.5px; + padding-left: 12.5px; +} +input.blue-button:active, +select.blue-button:active +{ + decorator: ninepatch( blue-button-active, blue-button-active-inner, 1.0 ); + padding-top: 18.5px; + padding-right: 12.5px; + padding-bottom: 18.5px; + padding-left: 12.5px; +} +select.blue-button:active +{ + text-align: left; + padding-top: 18.5px; + padding-right: 12.5px; + padding-bottom: 38.5px; + padding-left: 12.5px; +} +input.blue-button:disabled, +select.blue-button selectbox +{ + decorator: ninepatch( blue-button-disabled, blue-button-disabled-inner, 1.0 ); + font-effect: none; + padding-top: 20.5px; + padding-right: 12.5px; + padding-bottom: 16.5px; + padding-left: 12.5px; +} +select.blue-button selectbox +{ + text-align: left; + padding-top: 20.5px; + padding-right: 12.5px; + padding-bottom: 36.5px; + padding-left: 12.5px; +} +input.orange-button, +select.orange-button, +select.orange-button selectbox +{ + decorator: ninepatch( orange-button, orange-button-inner, 1.0 ); + box-sizing: border-box; + vertical-align: center; + overflow: auto; + display: inline-block; + min-width: 28px; + min-height: 48px; + text-align: center; + font-effect: outline(1px #333), shadow(0px 3px #333); + padding-top: 16.5px; + padding-right: 12.5px; + padding-bottom: 20.5px; + padding-left: 12.5px; +} +select.orange-button, +select.orange-button selectbox +{ + text-align: left; + padding-top: 16.5px; + padding-right: 12.5px; + padding-bottom: 40.5px; + padding-left: 12.5px; +} +select.orange-button selectvalue +{ + padding-right: 60px; +} +select.orange-button selectbox option:hover +{ + font-effect: outline(1px #333), shadow(0px 3px #333); + background: #FFA500; +} +input.orange-button:hover, +input.orange-button:focus-visible, +select.orange-button:hover, +select.orange-button:focus-visible +{ + decorator: ninepatch( orange-button-hover, orange-button-hover-inner, 1.0 ); + padding-top: 12.5px; + padding-right: 12.5px; + padding-bottom: 24.5px; + padding-left: 12.5px; +} +select.orange-button:hover, +select.orange-button:focus-visible +{ + text-align: left; + padding-top: 12.5px; + padding-right: 12.5px; + padding-bottom: 44.5px; + padding-left: 12.5px; +} +input.orange-button:active, +select.orange-button:active +{ + decorator: ninepatch( orange-button-active, orange-button-active-inner, 1.0 ); + padding-top: 18.5px; + padding-right: 12.5px; + padding-bottom: 18.5px; + padding-left: 12.5px; +} +select.orange-button:active +{ + text-align: left; + padding-top: 18.5px; + padding-right: 12.5px; + padding-bottom: 38.5px; + padding-left: 12.5px; +} +input.orange-button:disabled, +select.orange-button selectbox +{ + decorator: ninepatch( orange-button-disabled, orange-button-disabled-inner, 1.0 ); + font-effect: none; + padding-top: 20.5px; + padding-right: 12.5px; + padding-bottom: 16.5px; + padding-left: 12.5px; +} +select.orange-button selectbox +{ + text-align: left; + padding-top: 20.5px; + padding-right: 12.5px; + padding-bottom: 36.5px; + padding-left: 12.5px; +} +.gray-inner-panel +{ + decorator: ninepatch( gray-inner-panel, gray-inner-panel-inner, 1.0 ); + box-sizing: border-box; + vertical-align: center; + overflow: auto; + display: inline-block; + min-width: 52px; + min-height: 58px; + padding-top: 24.5px; + padding-right: 24.5px; + padding-bottom: 26.5px; + padding-left: 24.5px; +} +.gray-outer-panel +{ + decorator: ninepatch( gray-outer-panel, gray-outer-panel-inner, 1.0 ); + box-sizing: border-box; + vertical-align: center; + overflow: auto; + display: inline-block; + min-width: 100px; + min-height: 106px; + padding-top: 48.5px; + padding-right: 48.5px; + padding-bottom: 50.5px; + padding-left: 48.5px; +} +.gray-header-panel +{ + decorator: ninepatch( gray-header-panel, gray-header-panel-inner, 1.0 ); + box-sizing: border-box; + vertical-align: center; + overflow: auto; + display: inline-block; + min-width: 4px; + min-height: 10px; + padding-top: 0.5px; + padding-right: 0.5px; + padding-bottom: 2.5px; + padding-left: 0.5px; +} +.gray-footer-panel +{ + decorator: ninepatch( gray-footer-panel, gray-footer-panel-inner, 1.0 ); + box-sizing: border-box; + vertical-align: center; + overflow: auto; + display: inline-block; + min-width: 4px; + min-height: 8px; + padding-top: 0.5px; + padding-right: 0.5px; + padding-bottom: 0.5px; + padding-left: 0.5px; +} +scrollbarvertical +{ + width: 14px; +} +scrollbarhorizontal +{ + height: 22px; +} +slidertrack +{ + decorator: ninepatch( slidertrack, slidertrack-inner, 1.0 ); +} +sliderbar +{ + decorator: ninepatch( sliderbar, sliderbar-inner, 1.0 ); +} +input.blue-checkbox +{ + decorator: image( blue-checkbox ); + box-sizing: border-box; + vertical-align: center; + overflow: auto; + display: inline-block; + min-width: 30.284271px; + min-height: 50.28427px; + padding-top: 16.5px; + padding-right: 14.784271px; + padding-bottom: 22.784271px; + padding-left: 12.5px; +} +input.blue-checkbox:hover, +input.blue-checkbox:focus-visible +{ + decorator: image( blue-checkbox-hover ); + padding-top: 12.5px; + padding-right: 14.784271px; + padding-bottom: 26.784271px; + padding-left: 12.5px; +} +input.blue-checkbox:active +{ + decorator: image( blue-checkbox-active ); + padding-top: 18.5px; + padding-right: 14.784271px; + padding-bottom: 20.784271px; + padding-left: 12.5px; +} +input.blue-checkbox:disabled +{ + decorator: image( blue-checkbox-disabled ); + padding-top: 20.5px; + padding-right: 14.784271px; + padding-bottom: 18.784271px; + padding-left: 12.5px; +} +input.blue-checkbox:checked +{ + decorator: image( blue-checkbox-checked ); + box-sizing: border-box; + vertical-align: center; + overflow: auto; + display: inline-block; + min-width: 30.284271px; + min-height: 50.28427px; + padding-top: 16.5px; + padding-right: 14.784271px; + padding-bottom: 22.784271px; + padding-left: 12.5px; +} +input.blue-checkbox:checked:hover, +input.blue-checkbox:checked:focus-visible +{ + decorator: image( blue-checkbox-checked-hover ); + padding-top: 12.5px; + padding-right: 14.784271px; + padding-bottom: 26.784271px; + padding-left: 12.5px; +} +input.blue-checkbox:checked:active +{ + decorator: image( blue-checkbox-checked-active ); + padding-top: 18.5px; + padding-right: 14.784271px; + padding-bottom: 20.784271px; + padding-left: 12.5px; +} +input.blue-checkbox:checked:disabled +{ + decorator: image( blue-checkbox-checked-disabled ); + padding-top: 20.5px; + padding-right: 14.784271px; + padding-bottom: 18.784271px; + padding-left: 12.5px; +} +input.blue-slider slidertrack +{ + height: 20px; + decorator: ninepatch( blue-slider-slidertrack, blue-slider-slidertrack-inner, 1.0 ); +} +input.blue-slider sliderbar +{ + margin-top: -10px; + width: 28px; + height: 40px; + decorator: ninepatch( blue-slider-sliderbar, blue-slider-sliderbar-inner, 1.0 ); +} +select selectarrow +{ + decorator: image( selectarrow ); + width: 20px; + height: 20px; +} +icon.icon-diamond +{ + decorator: image( icon-diamond ); +} +icon.icon-money +{ + decorator: image( icon-money ); +} +icon.icon-settings +{ + decorator: image( icon-settings ); +} +icon.icon-xbox +{ + decorator: image( icon-xbox ); +} +icon.icon-discord +{ + decorator: image( icon-discord ); +} + diff --git a/Content/Common/Data/UI/rml.rcss b/Content/Common/Data/UI/rml.rcss new file mode 100644 index 0000000..390bc12 --- /dev/null +++ b/Content/Common/Data/UI/rml.rcss @@ -0,0 +1,108 @@ +body, div, +h1, h2, h3, h4, +h5, h6, p, +hr, pre, datagrid, +tabset tabs, pre, +navigable +{ + display: block; + line-height: 1.25em; +} + +h1 +{ + font-size: 2em; + margin: .75em 0; +} + +h2 +{ + font-size: 1.5em; + margin: .50em 0; +} + +h3 +{ + font-size: 1.25em; + margin: .25em 0; +} + +h4 +{ + margin: .25em 0; +} + +h5 +{ + font-size: .75em; +} + +h6 +{ + font-size: .50em; +} + +h1, h2, h3, h4, +h5, h6, strong, b +{ + font-weight: bold; +} + +em, i +{ + font-style: italic; +} + +pre +{ + white-space: pre; +} + +hr +{ + border-bottom: 1dp; + margin-bottom: 0.5em; +} + +s, strike +{ + text-decoration: line-through; +} + +p, input, textarea, select, progressbar +{ + margin-bottom: 4dp; +} + +table +{ + box-sizing: border-box; + display: table; +} +tr +{ + box-sizing: border-box; + display: table-row; +} +td +{ + box-sizing: border-box; + display: table-cell; +} +col +{ + box-sizing: border-box; + display: table-column; +} +colgroup +{ + display: table-column-group; +} +thead, tbody, tfoot +{ + display: table-row-group; +} +input +{ + nav: auto; +} \ No newline at end of file diff --git a/Content/Common/Data/common.txt b/Content/Common/Data/common.txt new file mode 100644 index 0000000..e69de29 diff --git a/Content/Common/Project.json b/Content/Common/Project.json new file mode 100644 index 0000000..ba107c8 --- /dev/null +++ b/Content/Common/Project.json @@ -0,0 +1,15 @@ +{ + "LaunchManager": { + "Configurations": [ + { + "MainPlugin": "Builtin.SceneViewer", + "Name": "View Current Scene" + } + ] + }, + "PluginManager": { + "LoadedPlugins": [ + "Builtin.SceneViewer" + ] + } +} \ No newline at end of file diff --git a/Content/Desktop/Data/desktop.txt b/Content/Desktop/Data/desktop.txt new file mode 100644 index 0000000..e69de29 diff --git a/Content/IOS/Data/ios.txt b/Content/IOS/Data/ios.txt new file mode 100644 index 0000000..e69de29 diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 0000000..e5046ec --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,6 @@ + + + + 0.3.7.842 + + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..4e41bac --- /dev/null +++ b/README.md @@ -0,0 +1,186 @@ +# Rebel Framework Empty Project Template + +## Install the Casual Project Template: + +Open your terminal or command prompt. + +Use the following command to install the rbfx.template.casual template package from NuGet: + +``` +dotnet new install rbfx.template.empty +``` + +This command will download and install the template package. If you want to install a specific version, you can specify it using the format rbfx.template.casual::. + +## Create a New Solution Using the Installed Template: + +Navigate to the directory where you want to create your solution. + +Run the following command to generate a new solution based on the installed template: + +``` +dotnet new rbfx-empty -n MyAwesomeGame +``` + +Replace MyAwesomeGame with your desired solution name. + +This command will create a new solution with the necessary project structure and files based on the Casual template. + +## Explore and Customize: + +Inside the newly created solution folder (MyAwesomeGame in this example), you’ll find project files for the game, character, and other related components. + +Customize the project files according to your requirements. You can add more game features, modify existing code, and create additional projects within the solution. + +## Build and Run: + +Build the solution using the following command: + +``` +dotnet build +``` + +Run your game using: + +``` +dotnet run --project MyAwesomeGame.Desktop/MyAwesomeGame.Desktop.csproj +``` + +This will compile your solution and execute the game. +Remember to adjust the commands and folder names based on your specific setup. Happy coding! 🚀🎮 + +For more information, you can refer to the [official documentation on installing and managing SDK templates](https://learn.microsoft.com/en-us/dotnet/core/install/templates). + +# GitHub Actions Workflow Execution: + +Whenever you push changes to the master branch, GitHub Actions will automatically trigger the workflow. + +It will build your game, create a GitHub release, and upload the precompiled game artifact. + +## Verify the Release: + +Visit the [Releases](https://github.com/rbfx/rbfx-csharp-empty/releases) section of your repository to verify that the release was created successfully. + +## Optional: itch.io Publishing: + +If you want to publish to itch.io setup itch.io token. Go to your GitHub repository. +Navigate to ```Settings > Secrets and variables```. +Add a new secret named **BUTLER_API_KEY** and set its value to your **itch.io** personal access token. +Add new variable **ITCH_PROJECT** to the itch.io project id like [rebelfork/rbfx-csharp-empty](https://rebelfork.itch.io/rbfx-csharp-empty) + +That's it! Your GitHub Actions workflow will now build your game and make it available for download via GitHub Releases. Optionally, it can also publish to itch.io if configured. + +## Optional: Steam Publishing + +This action assumes you are registered as a [partner](https://partner.steamgames.com/) with Steam. + +One way of publishing the app would be to download zip files for *.Desktop.* builds and manually upload them to relevant depots. The rest of this readme is dedicated to publish automation via Github Action. + +### Set STEAM_APPID and STEAM_USERNAME action secret + +Set STEAM_USERNAME to the builder's user name. + +Set STEAM_APPID to the application or demo id. + +### Create "prerelease" branch + +You need to create a "prerelease" branch in the **App Data Admin**. Go to SteamPipe/Builds menu and click **Create new branch**. + +The reason for this is that Steam doesn't allow to make default branch live automatically and the Github Action for Steam publication will fail to do so. + +### Depots + +The Github Action deploys into 3 depots: + +- Depot 1: Operating System : Windows, Architecture : 64-bit OS Only +- Depot 2: Operating System : Linux + SteamOS, Architecture : 64-bit OS Only +- Depot 3: Operating System : macOS, Architecture : 64-bit OS Only + +If either of these depots missing the publish_to_steam job will fail. + +Once you are done defining your depots, **publish the changes** that you have made from the [Publish](https://partner.steamgames.com/apps/publishing) page. If you try to run Github Action before publishing the depots the action will fail to publish binaries. + +### Create a Steam Build Account + +Create a specialised builder account that only has access to `Edit App Metadata` and `Publish App Changes To Steam`, +and permissions to edit your specific app. + +https://partner.steamgames.com/doc/sdk/uploading#Build_Account + +### Set STEAM_CONFIG_VDF action secret + +Deploying to Steam requires using Multi-Factor Authentication (MFA) through Steam Guard unless `totp` is passed. +This means that simply using username and password isn't enough to authenticate with Steam. +However, it is possible to go through the MFA process only once by setting up GitHub Secrets for `configVdf` with these steps: +1. Install [Valve's offical steamcmd](https://partner.steamgames.com/doc/sdk/uploading#1) on your local machine. All following steps will also be done on your local machine. [Downloading_SteamCMD](https://developer.valvesoftware.com/wiki/SteamCMD#Downloading_SteamCMD) +1. Try to login with `steamcmd +login +quit`, which may prompt for the MFA code. If so, type in the MFA code that was emailed to your builder account's email address. +1. Validate that the MFA process is complete by running `steamcmd +login +quit` again. It should not ask for the MFA code again. +1. The folder from which you run `steamcmd` will now contain an updated `config/config.vdf` file. + 1. Windows: Use certutil to convert config.vdf content to base64 encoded string ```certutil -encodehex -f config/config.vdf config_base64.txt 0x40000001 1>nul``` + 1. Linux/MacOS: Use ```cat config/config.vdf | base64 > config_base64.txt``` to encode the file. +1. Copy the contents of `config_base64.txt` to a GitHub Secret `STEAM_CONFIG_VDF`. +1. `If:` when running the action you recieve another MFA code via email, run `steamcmd +set_steam_guard_code ` on your local machine and repeat the `config.vdf` encoding and replace secret `STEAM_CONFIG_VDF` with its contents. + +More documentation on steam publishing could be found at https://github.com/game-ci/steam-deploy + +## Optional: Google Play Publishing + +To publish app to Google Play directly from the GitHub Action you need to define several secrets in the pipeline. + +### PLAY_KEYSTORE, PLAY_KEYSTORE_ALIAS and PLAY_KEYSTORE_PASS + +First you need to generate Java Key Store file by running the following command: + +```shell +keytool -v -genkey -v -keystore googleplay.jks -alias someKindOfName -keyalg RSA -validity 10000 +``` + +**Don't user quotes " as part of the password, it may mess up the GitHub action scripts!** + +Replace alias with a name related to you. Store the alias into PLAY_KEYSTORE_ALIAS secret of the GitHub pipeline. The password you set to the keystore should go into PLAY_KEYSTORE_PASS secret. + +Also you need to store the whole content of the googleplay.jks file into the PLAY_KEYSTORE secret. The easy way of doing that is to encode the file content into base64 string and store the string value into the secret by running the following command on windows: + +```shell +certutil -encodehex -f googleplay.jks googleplay.txt 0x40000001 1>nul +``` + +or using openssl elsewhere: + +```shell +openssl base64 < googleplay.jks | tr -d '\n' | tee googleplay.txt +``` + +Upload the content of googleplay.txt to PLAY_KEYSTORE variable. + +**Dont' forget to delete googleplay.txt and keep the googleplay.jks in a safe place locally!** + +More on this: https://thewissen.io/making-maui-cd-pipeline/ + +### PLAYSTORE_SERVICE_ACC + +## Configure access via service account + +This step use https://github.com/r0adkll/upload-google-play for the publishing. Here is what you need to do: + +1. Enable the Google Play Android Developer API. + 1. Go to https://console.cloud.google.com/apis/library/androidpublisher.googleapis.com. + 1. Click on Enable. +1. Create a new service account in Google Cloud Platform ([docs](https://developers.google.com/android-publisher/getting_started#service-account)). + 1. Navigate to https://cloud.google.com/gcp. + 1. Open `Console` > `IAM & Admin` > `Credentials` > `Manage service accounts` > `Create service account`. + 1. Pick a name for the new account. Do not grant the account any permissions. + 1. To use it from the GitHub Action use either: + - Account key in GitHub secrets (simpler): + 1. Open the newly created service account, click on `keys` tab and add a new key, JSON type. + 1. When successful, a JSON file will be automatically downloaded on your machine. + 1. Store the content of this file to your GitHub secrets, e.g. `PLAYSTORE_SERVICE_ACC`. +1. Add the service account to Google Play Console. + 1. Open https://play.google.com/console and pick your developer account. + 1. Open Users and permissions. + 1. Click invite new user and add the email of the service account created in the previous step. + 1. Grant permissions to the app that you want the service account to deploy in `app permissions`. +1. Create new application via Google Play Console + 1. Open https://play.google.com/console and pick your developer account. + 1. Press `Create App` and create new application using the same ApplicationId as in your c# project + 1. Make sure you upload an apk or aab manually first by creating a release through the play console. diff --git a/RbfxTemplate.Android/AndroidManifest.xml b/RbfxTemplate.Android/AndroidManifest.xml new file mode 100644 index 0000000..ae7679f --- /dev/null +++ b/RbfxTemplate.Android/AndroidManifest.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/RbfxTemplate.Android/BundleConfig.json b/RbfxTemplate.Android/BundleConfig.json new file mode 100644 index 0000000..b4599e5 --- /dev/null +++ b/RbfxTemplate.Android/BundleConfig.json @@ -0,0 +1,5 @@ +{ +"optimizations" : { +"uncompress_native_libraries" : {} +} +} \ No newline at end of file diff --git a/RbfxTemplate.Android/MainActivity.cs b/RbfxTemplate.Android/MainActivity.cs new file mode 100644 index 0000000..17094a4 --- /dev/null +++ b/RbfxTemplate.Android/MainActivity.cs @@ -0,0 +1,35 @@ +using Android.Content.PM; +using Android.Runtime; +using Org.Libsdl.App; +using Urho3DNet; + +namespace RbfxTemplate +{ + [Activity(Label = "@string/app_name", + ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize | ConfigChanges.KeyboardHidden, + Theme = "@android:style/Theme.NoTitleBar.Fullscreen", HardwareAccelerated = true, MainLauncher = true)] + public class MainActivity : UrhoActivity + { + protected override void OnResume() + { + base.OnResume(); + } + + protected override void OnCreate(Bundle? savedInstanceState) + { + //Launcher.SdlTrapBackButton = true; + Launcher.Run(_ => new UrhoApplication(_)); + + base.OnCreate(savedInstanceState); + //Xamarin.Essentials.Platform.Init(this, savedInstanceState); + } + + public override void OnRequestPermissionsResult(int requestCode, string[] permissions, + [GeneratedEnum] global::Android.Content.PM.Permission[] grantResults) + { + //Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults); + + base.OnRequestPermissionsResult(requestCode, permissions, grantResults); + } + } +} \ No newline at end of file diff --git a/RbfxTemplate.Android/RbfxTemplate.Android.csproj b/RbfxTemplate.Android/RbfxTemplate.Android.csproj new file mode 100644 index 0000000..88534f1 --- /dev/null +++ b/RbfxTemplate.Android/RbfxTemplate.Android.csproj @@ -0,0 +1,37 @@ + + + net8.0-android + 21 + 34 + Exe + enable + enable + com.companyname.RbfxTemplate + 1 + 1.0 + BundleConfig.json + + True + + + + + + + + + Cache/%(RecursiveDir)%(FileName)%(Extension) + + + Data/%(RecursiveDir)%(FileName)%(Extension) + + + Data/%(RecursiveDir)%(FileName)%(Extension) + + + + + + + + diff --git a/RbfxTemplate.Android/Resources/AboutResources.txt b/RbfxTemplate.Android/Resources/AboutResources.txt new file mode 100644 index 0000000..219f425 --- /dev/null +++ b/RbfxTemplate.Android/Resources/AboutResources.txt @@ -0,0 +1,44 @@ +Images, layout descriptions, binary blobs and string dictionaries can be included +in your application as resource files. Various Android APIs are designed to +operate on the resource IDs instead of dealing with images, strings or binary blobs +directly. + +For example, a sample Android app that contains a user interface layout (main.xml), +an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png) +would keep its resources in the "Resources" directory of the application: + +Resources/ + drawable/ + icon.png + + layout/ + main.xml + + values/ + strings.xml + +In order to get the build system to recognize Android resources, set the build action to +"AndroidResource". The native Android APIs do not operate directly with filenames, but +instead operate on resource IDs. When you compile an Android application that uses resources, +the build system will package the resources for distribution and generate a class called "Resource" +(this is an Android convention) that contains the tokens for each one of the resources +included. For example, for the above Resources layout, this is what the Resource class would expose: + +public class Resource { + public class Drawable { + public const int icon = 0x123; + } + + public class Layout { + public const int main = 0x456; + } + + public class Strings { + public const int first_string = 0xabc; + public const int second_string = 0xbcd; + } +} + +You would then use Resource.Drawable.icon to reference the drawable/icon.png file, or +Resource.Layout.main to reference the layout/main.xml file, or Resource.Strings.first_string +to reference the first string in the dictionary file values/strings.xml. \ No newline at end of file diff --git a/RbfxTemplate.Android/Resources/layout/activity_main.xml b/RbfxTemplate.Android/Resources/layout/activity_main.xml new file mode 100644 index 0000000..091f342 --- /dev/null +++ b/RbfxTemplate.Android/Resources/layout/activity_main.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/RbfxTemplate.Android/Resources/mipmap-anydpi-v26/ic_launcher.xml b/RbfxTemplate.Android/Resources/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..036d09b --- /dev/null +++ b/RbfxTemplate.Android/Resources/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/RbfxTemplate.Android/Resources/mipmap-anydpi-v26/ic_launcher_round.xml b/RbfxTemplate.Android/Resources/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..036d09b --- /dev/null +++ b/RbfxTemplate.Android/Resources/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/RbfxTemplate.Android/Resources/mipmap-hdpi/ic_launcher.png b/RbfxTemplate.Android/Resources/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..9781ccd Binary files /dev/null and b/RbfxTemplate.Android/Resources/mipmap-hdpi/ic_launcher.png differ diff --git a/RbfxTemplate.Android/Resources/mipmap-hdpi/ic_launcher_foreground.png b/RbfxTemplate.Android/Resources/mipmap-hdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..4674e9e Binary files /dev/null and b/RbfxTemplate.Android/Resources/mipmap-hdpi/ic_launcher_foreground.png differ diff --git a/RbfxTemplate.Android/Resources/mipmap-hdpi/ic_launcher_round.png b/RbfxTemplate.Android/Resources/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 0000000..9f3217b Binary files /dev/null and b/RbfxTemplate.Android/Resources/mipmap-hdpi/ic_launcher_round.png differ diff --git a/RbfxTemplate.Android/Resources/mipmap-mdpi/ic_launcher.png b/RbfxTemplate.Android/Resources/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..98de30c Binary files /dev/null and b/RbfxTemplate.Android/Resources/mipmap-mdpi/ic_launcher.png differ diff --git a/RbfxTemplate.Android/Resources/mipmap-mdpi/ic_launcher_foreground.png b/RbfxTemplate.Android/Resources/mipmap-mdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..79187b4 Binary files /dev/null and b/RbfxTemplate.Android/Resources/mipmap-mdpi/ic_launcher_foreground.png differ diff --git a/RbfxTemplate.Android/Resources/mipmap-mdpi/ic_launcher_round.png b/RbfxTemplate.Android/Resources/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 0000000..36c272b Binary files /dev/null and b/RbfxTemplate.Android/Resources/mipmap-mdpi/ic_launcher_round.png differ diff --git a/RbfxTemplate.Android/Resources/mipmap-xhdpi/ic_launcher.png b/RbfxTemplate.Android/Resources/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..7ab63ad Binary files /dev/null and b/RbfxTemplate.Android/Resources/mipmap-xhdpi/ic_launcher.png differ diff --git a/RbfxTemplate.Android/Resources/mipmap-xhdpi/ic_launcher_foreground.png b/RbfxTemplate.Android/Resources/mipmap-xhdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..0d98530 Binary files /dev/null and b/RbfxTemplate.Android/Resources/mipmap-xhdpi/ic_launcher_foreground.png differ diff --git a/RbfxTemplate.Android/Resources/mipmap-xhdpi/ic_launcher_round.png b/RbfxTemplate.Android/Resources/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 0000000..6ed1efa Binary files /dev/null and b/RbfxTemplate.Android/Resources/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/RbfxTemplate.Android/Resources/mipmap-xxhdpi/ic_launcher.png b/RbfxTemplate.Android/Resources/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..8c1b2e7 Binary files /dev/null and b/RbfxTemplate.Android/Resources/mipmap-xxhdpi/ic_launcher.png differ diff --git a/RbfxTemplate.Android/Resources/mipmap-xxhdpi/ic_launcher_foreground.png b/RbfxTemplate.Android/Resources/mipmap-xxhdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..66b51c5 Binary files /dev/null and b/RbfxTemplate.Android/Resources/mipmap-xxhdpi/ic_launcher_foreground.png differ diff --git a/RbfxTemplate.Android/Resources/mipmap-xxhdpi/ic_launcher_round.png b/RbfxTemplate.Android/Resources/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..9d53091 Binary files /dev/null and b/RbfxTemplate.Android/Resources/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/RbfxTemplate.Android/Resources/mipmap-xxxhdpi/ic_launcher.png b/RbfxTemplate.Android/Resources/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..84bd477 Binary files /dev/null and b/RbfxTemplate.Android/Resources/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/RbfxTemplate.Android/Resources/mipmap-xxxhdpi/ic_launcher_foreground.png b/RbfxTemplate.Android/Resources/mipmap-xxxhdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..e3a4abc Binary files /dev/null and b/RbfxTemplate.Android/Resources/mipmap-xxxhdpi/ic_launcher_foreground.png differ diff --git a/RbfxTemplate.Android/Resources/mipmap-xxxhdpi/ic_launcher_round.png b/RbfxTemplate.Android/Resources/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..b3b4214 Binary files /dev/null and b/RbfxTemplate.Android/Resources/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/RbfxTemplate.Android/Resources/values/colors.xml b/RbfxTemplate.Android/Resources/values/colors.xml new file mode 100644 index 0000000..17bb9a9 --- /dev/null +++ b/RbfxTemplate.Android/Resources/values/colors.xml @@ -0,0 +1,6 @@ + + + #2c3e50 + #1B3147 + #3498db + diff --git a/RbfxTemplate.Android/Resources/values/dimens.xml b/RbfxTemplate.Android/Resources/values/dimens.xml new file mode 100644 index 0000000..59a0b0c --- /dev/null +++ b/RbfxTemplate.Android/Resources/values/dimens.xml @@ -0,0 +1,3 @@ + + 16dp + diff --git a/RbfxTemplate.Android/Resources/values/ic_launcher_background.xml b/RbfxTemplate.Android/Resources/values/ic_launcher_background.xml new file mode 100644 index 0000000..6ec24e6 --- /dev/null +++ b/RbfxTemplate.Android/Resources/values/ic_launcher_background.xml @@ -0,0 +1,4 @@ + + + #2C3E50 + \ No newline at end of file diff --git a/RbfxTemplate.Android/Resources/values/strings.xml b/RbfxTemplate.Android/Resources/values/strings.xml new file mode 100644 index 0000000..e369c79 --- /dev/null +++ b/RbfxTemplate.Android/Resources/values/strings.xml @@ -0,0 +1,3 @@ + + RbfxTemplate + diff --git a/RbfxTemplate.Desktop/Program.cs b/RbfxTemplate.Desktop/Program.cs new file mode 100644 index 0000000..9aa63aa --- /dev/null +++ b/RbfxTemplate.Desktop/Program.cs @@ -0,0 +1,17 @@ +using System; +using Urho3DNet; + +namespace RbfxTemplate +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main(string[] args) + { + Launcher.Run(_ => new UrhoApplication(_)); + } + } +} diff --git a/RbfxTemplate.Desktop/RbfxTemplate.Desktop.csproj b/RbfxTemplate.Desktop/RbfxTemplate.Desktop.csproj new file mode 100644 index 0000000..145f9a9 --- /dev/null +++ b/RbfxTemplate.Desktop/RbfxTemplate.Desktop.csproj @@ -0,0 +1,49 @@ + + + + Exe + net8.0 + RbfxTemplate + icon.ico + + True + + + + x64 + + + + + + + + + Cache/%(RecursiveDir)%(FileName)%(Extension) + PreserveNewest + + + Data/%(RecursiveDir)%(FileName)%(Extension) + PreserveNewest + + + Data/%(RecursiveDir)%(FileName)%(Extension) + PreserveNewest + + + + + + + + + + + + + + + + + + diff --git a/RbfxTemplate.Desktop/icon.ico b/RbfxTemplate.Desktop/icon.ico new file mode 100644 index 0000000..e59303f Binary files /dev/null and b/RbfxTemplate.Desktop/icon.ico differ diff --git a/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Contents.json b/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..98f4d03 --- /dev/null +++ b/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,117 @@ +{ + "images": [ + { + "scale": "2x", + "size": "20x20", + "idiom": "iphone", + "filename": "Icon40.png" + }, + { + "scale": "3x", + "size": "20x20", + "idiom": "iphone", + "filename": "Icon60.png" + }, + { + "scale": "2x", + "size": "29x29", + "idiom": "iphone", + "filename": "Icon58.png" + }, + { + "scale": "3x", + "size": "29x29", + "idiom": "iphone", + "filename": "Icon87.png" + }, + { + "scale": "2x", + "size": "40x40", + "idiom": "iphone", + "filename": "Icon80.png" + }, + { + "scale": "3x", + "size": "40x40", + "idiom": "iphone", + "filename": "Icon120.png" + }, + { + "scale": "2x", + "size": "60x60", + "idiom": "iphone", + "filename": "Icon120.png" + }, + { + "scale": "3x", + "size": "60x60", + "idiom": "iphone", + "filename": "Icon180.png" + }, + { + "scale": "1x", + "size": "20x20", + "idiom": "ipad", + "filename": "Icon20.png" + }, + { + "scale": "2x", + "size": "20x20", + "idiom": "ipad", + "filename": "Icon40.png" + }, + { + "scale": "1x", + "size": "29x29", + "idiom": "ipad", + "filename": "Icon29.png" + }, + { + "scale": "2x", + "size": "29x29", + "idiom": "ipad", + "filename": "Icon58.png" + }, + { + "scale": "1x", + "size": "40x40", + "idiom": "ipad", + "filename": "Icon40.png" + }, + { + "scale": "2x", + "size": "40x40", + "idiom": "ipad", + "filename": "Icon80.png" + }, + { + "scale": "1x", + "size": "76x76", + "idiom": "ipad", + "filename": "Icon76.png" + }, + { + "scale": "2x", + "size": "76x76", + "idiom": "ipad", + "filename": "Icon152.png" + }, + { + "scale": "2x", + "size": "83.5x83.5", + "idiom": "ipad", + "filename": "Icon167.png" + }, + { + "scale": "1x", + "size": "1024x1024", + "idiom": "ios-marketing", + "filename": "Icon1024.png" + } + ], + "properties": {}, + "info": { + "version": 1, + "author": "xcode" + } +} \ No newline at end of file diff --git a/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon1024.png b/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon1024.png new file mode 100644 index 0000000..1040613 Binary files /dev/null and b/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon1024.png differ diff --git a/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon120.png b/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon120.png new file mode 100644 index 0000000..73a2782 Binary files /dev/null and b/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon120.png differ diff --git a/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon152.png b/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon152.png new file mode 100644 index 0000000..bd87fd7 Binary files /dev/null and b/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon152.png differ diff --git a/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon167.png b/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon167.png new file mode 100644 index 0000000..d73409a Binary files /dev/null and b/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon167.png differ diff --git a/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon180.png b/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon180.png new file mode 100644 index 0000000..ffb520c Binary files /dev/null and b/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon180.png differ diff --git a/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon20.png b/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon20.png new file mode 100644 index 0000000..c3fbe4d Binary files /dev/null and b/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon20.png differ diff --git a/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon29.png b/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon29.png new file mode 100644 index 0000000..dc5e46f Binary files /dev/null and b/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon29.png differ diff --git a/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon40.png b/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon40.png new file mode 100644 index 0000000..f3cf982 Binary files /dev/null and b/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon40.png differ diff --git a/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon58.png b/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon58.png new file mode 100644 index 0000000..32c009d Binary files /dev/null and b/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon58.png differ diff --git a/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon60.png b/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon60.png new file mode 100644 index 0000000..429ea92 Binary files /dev/null and b/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon60.png differ diff --git a/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon76.png b/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon76.png new file mode 100644 index 0000000..7bf8cf3 Binary files /dev/null and b/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon76.png differ diff --git a/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon80.png b/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon80.png new file mode 100644 index 0000000..07eb84e Binary files /dev/null and b/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon80.png differ diff --git a/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon87.png b/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon87.png new file mode 100644 index 0000000..64ddf75 Binary files /dev/null and b/RbfxTemplate.IOS/Assets.xcassets/AppIcon.appiconset/Icon87.png differ diff --git a/RbfxTemplate.IOS/Entitlements.plist b/RbfxTemplate.IOS/Entitlements.plist new file mode 100644 index 0000000..36a8706 --- /dev/null +++ b/RbfxTemplate.IOS/Entitlements.plist @@ -0,0 +1,6 @@ + + + + + + diff --git a/RbfxTemplate.IOS/Info.plist b/RbfxTemplate.IOS/Info.plist new file mode 100644 index 0000000..e049547 --- /dev/null +++ b/RbfxTemplate.IOS/Info.plist @@ -0,0 +1,44 @@ + + + + + CFBundleDisplayName + RbfxTemplate + CFBundleIdentifier + com.companyname.RbfxTemplate + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + MinimumOSVersion + 13.0 + UIDeviceFamily + + 1 + 2 + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + XSAppIconAssets + Assets.xcassets/AppIcon.appiconset + + diff --git a/RbfxTemplate.IOS/Main.cs b/RbfxTemplate.IOS/Main.cs new file mode 100644 index 0000000..e82ae5b --- /dev/null +++ b/RbfxTemplate.IOS/Main.cs @@ -0,0 +1,13 @@ +using Urho3DNet; + +namespace RbfxTemplate.IOS +{ + public class Application + { + // This is the main entry point of the application. + static void Main(string[] args) + { + Launcher.Run(_ =>new UrhoApplication(_)); + } + } +} \ No newline at end of file diff --git a/RbfxTemplate.IOS/RbfxTemplate.IOS.csproj b/RbfxTemplate.IOS/RbfxTemplate.IOS.csproj new file mode 100644 index 0000000..f3c1f45 --- /dev/null +++ b/RbfxTemplate.IOS/RbfxTemplate.IOS.csproj @@ -0,0 +1,32 @@ + + + net8.0-ios + Exe + enable + true + 13.0 + + True + + + + + + + + + Cache/%(RecursiveDir)%(FileName)%(Extension) + + + Data/%(RecursiveDir)%(FileName)%(Extension) + + + Data/%(RecursiveDir)%(FileName)%(Extension) + + + + + + + + \ No newline at end of file diff --git a/RbfxTemplate.IOS/Resources/LaunchScreen.xib b/RbfxTemplate.IOS/Resources/LaunchScreen.xib new file mode 100644 index 0000000..8190201 --- /dev/null +++ b/RbfxTemplate.IOS/Resources/LaunchScreen.xib @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RbfxTemplate.Tests/JsonResourceTests.cs b/RbfxTemplate.Tests/JsonResourceTests.cs new file mode 100644 index 0000000..be14b47 --- /dev/null +++ b/RbfxTemplate.Tests/JsonResourceTests.cs @@ -0,0 +1,113 @@ +// Copyright (c) 2024-2024 the rbfx project. +// This work is licensed under the terms of the MIT license. +// For a copy, see or the accompanying LICENSE file. + +using RbfxTemplate.Tests; +using RbfxTemplate.Utils; +using Xunit; + +namespace Urho3DNet.Tests +{ + public enum TestEnum + { + A,B,C + } + public class TestContainer + { + public Vector2 Vector2 { get; set; } + public Vector3 Vector3 { get; set; } + public Vector4 Vector4 { get; set; } + public Quaternion Quaternion { get; set; } + public IntVector2 IntVector2 { get; set; } + public IntVector3 IntVector3 { get; set; } + public BoundingBox BoundingBox { get; set; } + public TestEnum Enum { get; set; } + public Material? Material { get; set; } + + public TestContainer() + { + } + + public TestContainer(Material mat) + { + Vector2 = new Vector2(1, 2); + Vector3 = new Vector3(1, 2, 3); + Vector4 = new Vector4(1, 2, 3, 4); + Quaternion = new Quaternion(10, Vector3.Down); + IntVector2 = new IntVector2(1, 2); + IntVector3 = new IntVector3(1, 2, 3); + BoundingBox = new BoundingBox(new Vector3(-1, -2, -3), new Vector3(1, 2, 3)); + Enum = TestEnum.B; + Material = mat; + } + } + + [ObjectFactory] + public partial class TestResource : JsonResource + { + public TestResource(Context context) : base(context) + { + } + } + public class JsonResourceTests + { + [Fact] + public async Task SaveSimpleResource() + { + await RbfxTestFramework.Context.ToMainThreadAsync(); + + var mat = new Material(RbfxTestFramework.Context); + mat.Name = "TestResource.material"; + RbfxTestFramework.Context.ResourceCache.AddManualResource(mat); + + var res = new TestResource(RbfxTestFramework.Context); + var testContainer = new TestContainer(mat); + + res.Value = testContainer; + var fileIdentifier = new FileIdentifier("conf", "SaveJson.json"); + res.SaveFile(fileIdentifier); + res.Value = new TestContainer(); + res.LoadFile(fileIdentifier); + Assert.NotNull(res.Value); + Assert.Equal(testContainer.IntVector2, res.Value.IntVector2); + Assert.Equal(testContainer.IntVector3, res.Value.IntVector3); + Assert.Equal(testContainer.Vector2, res.Value.Vector2); + Assert.Equal(testContainer.Vector3, res.Value.Vector3); + Assert.Equal(testContainer.Vector4, res.Value.Vector4); + Assert.Equal(testContainer.Quaternion, res.Value.Quaternion); + Assert.Equal(testContainer.BoundingBox, res.Value.BoundingBox); + Assert.Equal(testContainer.Enum, res.Value.Enum); + Assert.Equal(testContainer.Material, res.Value.Material); + var path = RbfxTestFramework.Context.VirtualFileSystem.GetAbsoluteNameFromIdentifier(fileIdentifier); + System.IO.File.Delete(path); + } + + [Fact] + public async Task SaveConfigResource() + { + await RbfxTestFramework.Context.ToMainThreadAsync(); + + var mat = new Material(RbfxTestFramework.Context); + mat.Name = "TestResource2.material"; + RbfxTestFramework.Context.ResourceCache.AddManualResource(mat); + + using var conf1 = new ConfigFileContainer(RbfxTestFramework.Context); + conf1.Value = new TestContainer(mat); + conf1.SaveConfig(); + + using var conf2 = ConfigFileContainer.LoadConfig(RbfxTestFramework.Context); + + Assert.Equal(conf1.Value.IntVector2, conf2.Ptr.Value.IntVector2); + Assert.Equal(conf1.Value.IntVector3, conf2.Ptr.Value.IntVector3); + Assert.Equal(conf1.Value.Vector2, conf2.Ptr.Value.Vector2); + Assert.Equal(conf1.Value.Vector3, conf2.Ptr.Value.Vector3); + Assert.Equal(conf1.Value.Vector4, conf2.Ptr.Value.Vector4); + Assert.Equal(conf1.Value.Quaternion, conf2.Ptr.Value.Quaternion); + Assert.Equal(conf1.Value.BoundingBox, conf2.Ptr.Value.BoundingBox); + Assert.Equal(conf1.Value.Enum, conf2.Ptr.Value.Enum); + Assert.Equal(conf1.Value.Material, conf2.Ptr.Value.Material); + var path = RbfxTestFramework.Context.VirtualFileSystem.GetAbsoluteNameFromIdentifier(new FileIdentifier("conf", conf2.Ptr.Name)); + System.IO.File.Delete(path); + } + } +} diff --git a/RbfxTemplate.Tests/RbfxTemplate.Tests.csproj b/RbfxTemplate.Tests/RbfxTemplate.Tests.csproj new file mode 100644 index 0000000..e4029e5 --- /dev/null +++ b/RbfxTemplate.Tests/RbfxTemplate.Tests.csproj @@ -0,0 +1,38 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + %(RecursiveDir)%(FileName)%(Extension) + PreserveNewest + + + %(RecursiveDir)%(FileName)%(Extension) + PreserveNewest + + + + + + + + \ No newline at end of file diff --git a/RbfxTemplate.Tests/RbfxTestFramework.cs b/RbfxTemplate.Tests/RbfxTestFramework.cs new file mode 100644 index 0000000..ab17aa4 --- /dev/null +++ b/RbfxTemplate.Tests/RbfxTestFramework.cs @@ -0,0 +1,150 @@ +// +// Copyright (c) 2022-2023 the rbfx project. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System.Diagnostics; +using System.Runtime.CompilerServices; +using Urho3DNet; +using Xunit.Abstractions; +using Xunit.Sdk; + +[assembly: Xunit.TestFramework("RbfxTemplate.Tests.RbfxTestFramework", "RbfxTemplate.Tests")] + +namespace RbfxTemplate.Tests +{ + /// + /// Helper class to run the Urho3D Application in a background. + /// + public class RbfxTestFramework : XunitTestFramework, IDisposable + { + /// + /// Static reference to the RbfxTestFramework instance. + /// The test framework going to create one. + /// + private static RbfxTestFramework _instance = null!; + + /// + /// Context of the application. + /// + private SharedPtr _context = (Context)null!; + + /// + /// Ticking application. + /// + private SharedPtr _app = (SimpleHeadlessApplication)null!; + + /// + /// Application main thread. + /// + private System.Threading.Thread _thread; + + /// + /// ManualResetEvent to synchronise with application creation. + /// + private readonly ManualResetEvent _initLock = new ManualResetEvent(false); + + /// + /// Create and run application instance. + /// + /// + public RbfxTestFramework(IMessageSink messageSink) + : base(messageSink) + { + _instance = this; + + // Run the application main thread. + _thread = new System.Threading.Thread(RunApp); + _thread.Start(); + + // Wait for application to run. + _initLock.WaitOne(); + } + + /// + /// Current Urho3D context. + /// + public static Context Context => _instance._context; + + /// + /// Current Urho3D application. + /// + public static SimpleHeadlessApplication Application => _instance._app; + + /// + /// Await this to continue execution in the application main thread. + /// + /// Main thread awaitable. + public static ConfiguredTaskAwaitable ToMainThreadAsync(ITestOutputHelper? testOutputHelper = null) + { + var tcs = new TaskCompletionSource(); + var workQueue = Context.GetSubsystem(); + workQueue.PostTaskForMainThread((threadId, queue) => + { + _instance._app.Ptr.TestOutput = testOutputHelper; + tcs.TrySetResult(true); + }); + return tcs.Task.ConfigureAwait(false); + } + + /// + /// Run application main loop in a task. + /// + private void RunApp() + { + bool isSet = false; + try + { + _context = new Context(); + _app = new SimpleHeadlessApplication(_context); + // Signal about application creation. + _initLock.Set(); + isSet = true; + _app.Ptr.Run(); + } + finally + { + // Make sure that the constructor can continue to run. + if (!isSet) + _initLock.Set(); + _app?.Dispose(); + _context?.Dispose(); + } + } + + /// + /// Dispose application. + /// + + public new void Dispose() + { + _context.Ptr.Engine.Exit(); + try + { + _thread.Join(); + } + catch (Exception ex) + { + Debug.WriteLine(ex); + } + base.Dispose(); + } + } +} diff --git a/RbfxTemplate.Tests/SampleUnitTestFixture.cs b/RbfxTemplate.Tests/SampleUnitTestFixture.cs new file mode 100644 index 0000000..201e21a --- /dev/null +++ b/RbfxTemplate.Tests/SampleUnitTestFixture.cs @@ -0,0 +1,52 @@ +using Urho3DNet; +using Xunit; + +namespace RbfxTemplate.Tests +{ + /// + /// Sample set of unit tests. + /// Replace this with your own unit tests. + /// + public class SampleUnitTestFixture + { + [Fact] + public async Task SampleSceneTest() + { + await RbfxTestFramework.ToMainThreadAsync(); + + SharedPtr scene = new Scene(RbfxTestFramework.Context); + + Assert.Equal(0u, scene.Ptr.GetNumChildren()); + } + + [Fact] + public async Task SampleEventTest() + { + await RbfxTestFramework.ToMainThreadAsync(); + + SharedPtr scene = new Scene(RbfxTestFramework.Context); + scene.Ptr.SubscribeToEvent("TestEvent", scene.Ptr, map => { }); + scene.Ptr.SendEvent("TestEvent"); + } + + [Fact] + public async Task SampleExceptionTest() + { + async Task TestMethod() + { + await RbfxTestFramework.ToMainThreadAsync(); + throw new ArgumentException("Expected exception"); + } + + await Assert.ThrowsAsync(TestMethod); + } + + [Fact(Skip = "This test demonstrates that async failing test handled properly")] + public async Task SampleFailingTest() + { + await RbfxTestFramework.ToMainThreadAsync(); + + Assert.True(false); + } + } +} diff --git a/RbfxTemplate.Tests/SimpleHeadlessApplication.cs b/RbfxTemplate.Tests/SimpleHeadlessApplication.cs new file mode 100644 index 0000000..7c01e74 --- /dev/null +++ b/RbfxTemplate.Tests/SimpleHeadlessApplication.cs @@ -0,0 +1,55 @@ +using Urho3DNet; +using Xunit.Abstractions; + +namespace RbfxTemplate.Tests +{ + /// + /// Test application. + /// + public partial class SimpleHeadlessApplication : Application + { + public SimpleHeadlessApplication(Context context) : base(context) + { + } + + /// + /// Setup headless application. + /// + public override void Setup() + { + base.Setup(); + EngineParameters[Urho3D.EpHeadless] = true; + EngineParameters[Urho3D.EpSound] = false; + } + + /// + /// Start headless application. + /// + public override void Start() + { + base.Start(); + SubscribeToEvent(E.LogMessage, OnLogMessage); + } + + /// + /// Current test output. + /// + public ITestOutputHelper? TestOutput { get; set; } + + /// + /// Handle log messages. + /// + /// Log message arguments. + /// + private void OnLogMessage(VariantMap args) + { + var helper = TestOutput; + if (helper != null) + { + var logLevel = (LogLevel)args[E.LogMessage.Level].Int; + var message = args[E.LogMessage.Message].String; + helper.WriteLine($"{logLevel}: {message}"); + } + } + } +} \ No newline at end of file diff --git a/RbfxTemplate.UWP/AssemblyInfo.cs b/RbfxTemplate.UWP/AssemblyInfo.cs new file mode 100644 index 0000000..ea10112 --- /dev/null +++ b/RbfxTemplate.UWP/AssemblyInfo.cs @@ -0,0 +1,29 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("RbfxTemplate.UWP")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("RbfxTemplate.UWP")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: ComVisible(false)] \ No newline at end of file diff --git a/RbfxTemplate.UWP/Assets/LockScreenLogo.scale-200.png b/RbfxTemplate.UWP/Assets/LockScreenLogo.scale-200.png new file mode 100644 index 0000000..98de30c Binary files /dev/null and b/RbfxTemplate.UWP/Assets/LockScreenLogo.scale-200.png differ diff --git a/RbfxTemplate.UWP/Assets/SplashScreen.scale-200.png b/RbfxTemplate.UWP/Assets/SplashScreen.scale-200.png new file mode 100644 index 0000000..59ca156 Binary files /dev/null and b/RbfxTemplate.UWP/Assets/SplashScreen.scale-200.png differ diff --git a/RbfxTemplate.UWP/Assets/Square150x150Logo.scale-200.png b/RbfxTemplate.UWP/Assets/Square150x150Logo.scale-200.png new file mode 100644 index 0000000..f85dfd2 Binary files /dev/null and b/RbfxTemplate.UWP/Assets/Square150x150Logo.scale-200.png differ diff --git a/RbfxTemplate.UWP/Assets/Square44x44Logo.scale-200.png b/RbfxTemplate.UWP/Assets/Square44x44Logo.scale-200.png new file mode 100644 index 0000000..f79bd56 Binary files /dev/null and b/RbfxTemplate.UWP/Assets/Square44x44Logo.scale-200.png differ diff --git a/RbfxTemplate.UWP/Assets/Square44x44Logo.targetsize-24_altform-unplated.png b/RbfxTemplate.UWP/Assets/Square44x44Logo.targetsize-24_altform-unplated.png new file mode 100644 index 0000000..9e79e6d Binary files /dev/null and b/RbfxTemplate.UWP/Assets/Square44x44Logo.targetsize-24_altform-unplated.png differ diff --git a/RbfxTemplate.UWP/Assets/StoreLogo.png b/RbfxTemplate.UWP/Assets/StoreLogo.png new file mode 100644 index 0000000..636b95d Binary files /dev/null and b/RbfxTemplate.UWP/Assets/StoreLogo.png differ diff --git a/RbfxTemplate.UWP/Assets/Wide310x150Logo.scale-200.png b/RbfxTemplate.UWP/Assets/Wide310x150Logo.scale-200.png new file mode 100644 index 0000000..c8312ec Binary files /dev/null and b/RbfxTemplate.UWP/Assets/Wide310x150Logo.scale-200.png differ diff --git a/RbfxTemplate.UWP/Default.rd.xml b/RbfxTemplate.UWP/Default.rd.xml new file mode 100644 index 0000000..af00722 --- /dev/null +++ b/RbfxTemplate.UWP/Default.rd.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/RbfxTemplate.UWP/Package.appxmanifest b/RbfxTemplate.UWP/Package.appxmanifest new file mode 100644 index 0000000..df79672 --- /dev/null +++ b/RbfxTemplate.UWP/Package.appxmanifest @@ -0,0 +1,49 @@ + + + + + + + + + + RbfxTemplate.UWP + gleb + Assets\StoreLogo.png + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/RbfxTemplate.UWP/Program.cs b/RbfxTemplate.UWP/Program.cs new file mode 100644 index 0000000..48ec74f --- /dev/null +++ b/RbfxTemplate.UWP/Program.cs @@ -0,0 +1,18 @@ +using System; +using Urho3DNet; + +namespace RbfxTemplate +{ + internal class Program + { + /// + /// Defines the entry point of the application. + /// + [MTAThread] + private static void Main() + { + Urho3DNet.Launcher.SdlHandleBackButton = true; + Urho3DNet.Launcher.Run(_=> new UrhoApplication(_)); + } + } +} \ No newline at end of file diff --git a/RbfxTemplate.UWP/Properties/AssemblyInfo.cs b/RbfxTemplate.UWP/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..b9dc277 --- /dev/null +++ b/RbfxTemplate.UWP/Properties/AssemblyInfo.cs @@ -0,0 +1,29 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("RbfxTemplate")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("RbfxTemplate")] +[assembly: AssemblyCopyright("Copyright © RbfxTemplate 2023")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: ComVisible(false)] \ No newline at end of file diff --git a/RbfxTemplate.UWP/Properties/Default.rd.xml b/RbfxTemplate.UWP/Properties/Default.rd.xml new file mode 100644 index 0000000..af00722 --- /dev/null +++ b/RbfxTemplate.UWP/Properties/Default.rd.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/RbfxTemplate.UWP/RbfxTemplate.UWP.csproj b/RbfxTemplate.UWP/RbfxTemplate.UWP.csproj new file mode 100644 index 0000000..7ce43ad --- /dev/null +++ b/RbfxTemplate.UWP/RbfxTemplate.UWP.csproj @@ -0,0 +1,143 @@ + + + + + Debug + x86 + {6EC5CAE7-DD30-4181-ADF2-B1BA19BA84F0} + AppContainerExe + Properties + RbfxTemplate + RbfxTemplate.UWP + en-US + UAP + 10.0.17763.0 + 10.0.16299.0 + 14 + 512 + {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + true + false + $(DefaultItemExcludes);*.user.json + + True + + + x64 + + + true + bin\ARM64\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + ARM64 + false + prompt + true + true + + + bin\ARM64\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + ARM64 + false + prompt + true + true + + + true + bin\x64\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + x64 + false + prompt + true + + + bin\x64\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + x64 + false + prompt + true + true + + + PackageReference + + + + + + + + Designer + + + + + + + + + + + + + + + Cache/%(RecursiveDir)%(FileName)%(Extension) + PreserveNewest + true + Cache/%(RecursiveDir)%(FileName)%(Extension) + + + Data/%(RecursiveDir)%(FileName)%(Extension) + PreserveNewest + true + Data/%(RecursiveDir)%(FileName)%(Extension) + + + Data/%(RecursiveDir)%(FileName)%(Extension) + PreserveNewest + true + Data/%(RecursiveDir)%(FileName)%(Extension) + + + + + + 6.2.10 + + + $(Urho3DNetVersion) + + + + + {12061FFC-551B-48ED-96CA-BB13DF2B8C67} + RbfxTemplate + + + + 14.0 + + + + \ No newline at end of file diff --git a/RbfxTemplate.csproj b/RbfxTemplate.csproj new file mode 100644 index 0000000..45b6034 --- /dev/null +++ b/RbfxTemplate.csproj @@ -0,0 +1,29 @@ + + + + Template + 1.0 + ./README.md + MIT + ./content/Content/Common/Data/Images/Splash.png + rbfx.template.casual + true + Rebel Framework Casual Project Template + rbfx + Templates to use when creating a casual game using Rebel Framework. + dotnet-new;templates;rbfx + net8.0 + + true + false + content + + + + + + + + + + \ No newline at end of file diff --git a/RbfxTemplate.sln b/RbfxTemplate.sln new file mode 100644 index 0000000..0fcf534 --- /dev/null +++ b/RbfxTemplate.sln @@ -0,0 +1,150 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.7.34024.191 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RbfxTemplate", "RbfxTemplate\RbfxTemplate.csproj", "{DAAE87E1-EBB6-472A-98D6-1411941CFD8E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RbfxTemplate.Android", "RbfxTemplate.Android\RbfxTemplate.Android.csproj", "{AC46195D-9A59-4725-8A77-E2309185C707}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RbfxTemplate.Desktop", "RbfxTemplate.Desktop\RbfxTemplate.Desktop.csproj", "{E5A649CE-987F-46FE-8FA8-1290951AE21D}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RbfxTemplate.IOS", "RbfxTemplate.IOS\RbfxTemplate.IOS.csproj", "{E15D7151-C812-4432-AB2A-F9EF06E4DF73}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RbfxTemplate.Tests", "RbfxTemplate.Tests\RbfxTemplate.Tests.csproj", "{70D12BD7-3CFE-48B6-8E28-B9554FB21AD0}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RbfxTemplate.UWP", "RbfxTemplate.UWP\RbfxTemplate.UWP.csproj", "{6EC5CAE7-DD30-4181-ADF2-B1BA19BA84F0}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{7DE6BF8D-C5F4-4C2A-8F02-525A97B81F1D}" + ProjectSection(SolutionItems) = preProject + Directory.Build.props = Directory.Build.props + .config\dotnet-tools.json = .config\dotnet-tools.json + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{D82AE45E-DEA4-4B99-897B-80FF32460DFF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IconUpdater", "Tools\IconUpdater\IconUpdater.csproj", "{2940DEDC-756B-43AE-BAD2-49BFA7D83009}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Release|Any CPU = Release|Any CPU + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DAAE87E1-EBB6-472A-98D6-1411941CFD8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DAAE87E1-EBB6-472A-98D6-1411941CFD8E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DAAE87E1-EBB6-472A-98D6-1411941CFD8E}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {DAAE87E1-EBB6-472A-98D6-1411941CFD8E}.Debug|ARM64.Build.0 = Debug|Any CPU + {DAAE87E1-EBB6-472A-98D6-1411941CFD8E}.Debug|x64.ActiveCfg = Debug|Any CPU + {DAAE87E1-EBB6-472A-98D6-1411941CFD8E}.Debug|x64.Build.0 = Debug|Any CPU + {DAAE87E1-EBB6-472A-98D6-1411941CFD8E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DAAE87E1-EBB6-472A-98D6-1411941CFD8E}.Release|Any CPU.Build.0 = Release|Any CPU + {DAAE87E1-EBB6-472A-98D6-1411941CFD8E}.Release|ARM64.ActiveCfg = Release|Any CPU + {DAAE87E1-EBB6-472A-98D6-1411941CFD8E}.Release|ARM64.Build.0 = Release|Any CPU + {DAAE87E1-EBB6-472A-98D6-1411941CFD8E}.Release|x64.ActiveCfg = Release|Any CPU + {DAAE87E1-EBB6-472A-98D6-1411941CFD8E}.Release|x64.Build.0 = Release|Any CPU + {AC46195D-9A59-4725-8A77-E2309185C707}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AC46195D-9A59-4725-8A77-E2309185C707}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AC46195D-9A59-4725-8A77-E2309185C707}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {AC46195D-9A59-4725-8A77-E2309185C707}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {AC46195D-9A59-4725-8A77-E2309185C707}.Debug|ARM64.Build.0 = Debug|Any CPU + {AC46195D-9A59-4725-8A77-E2309185C707}.Debug|ARM64.Deploy.0 = Debug|Any CPU + {AC46195D-9A59-4725-8A77-E2309185C707}.Debug|x64.ActiveCfg = Debug|Any CPU + {AC46195D-9A59-4725-8A77-E2309185C707}.Debug|x64.Build.0 = Debug|Any CPU + {AC46195D-9A59-4725-8A77-E2309185C707}.Debug|x64.Deploy.0 = Debug|Any CPU + {AC46195D-9A59-4725-8A77-E2309185C707}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AC46195D-9A59-4725-8A77-E2309185C707}.Release|Any CPU.Build.0 = Release|Any CPU + {AC46195D-9A59-4725-8A77-E2309185C707}.Release|Any CPU.Deploy.0 = Release|Any CPU + {AC46195D-9A59-4725-8A77-E2309185C707}.Release|ARM64.ActiveCfg = Release|Any CPU + {AC46195D-9A59-4725-8A77-E2309185C707}.Release|ARM64.Build.0 = Release|Any CPU + {AC46195D-9A59-4725-8A77-E2309185C707}.Release|ARM64.Deploy.0 = Release|Any CPU + {AC46195D-9A59-4725-8A77-E2309185C707}.Release|x64.ActiveCfg = Release|Any CPU + {AC46195D-9A59-4725-8A77-E2309185C707}.Release|x64.Build.0 = Release|Any CPU + {AC46195D-9A59-4725-8A77-E2309185C707}.Release|x64.Deploy.0 = Release|Any CPU + {E5A649CE-987F-46FE-8FA8-1290951AE21D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E5A649CE-987F-46FE-8FA8-1290951AE21D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E5A649CE-987F-46FE-8FA8-1290951AE21D}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {E5A649CE-987F-46FE-8FA8-1290951AE21D}.Debug|ARM64.Build.0 = Debug|Any CPU + {E5A649CE-987F-46FE-8FA8-1290951AE21D}.Debug|x64.ActiveCfg = Debug|Any CPU + {E5A649CE-987F-46FE-8FA8-1290951AE21D}.Debug|x64.Build.0 = Debug|Any CPU + {E5A649CE-987F-46FE-8FA8-1290951AE21D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E5A649CE-987F-46FE-8FA8-1290951AE21D}.Release|Any CPU.Build.0 = Release|Any CPU + {E5A649CE-987F-46FE-8FA8-1290951AE21D}.Release|ARM64.ActiveCfg = Release|Any CPU + {E5A649CE-987F-46FE-8FA8-1290951AE21D}.Release|ARM64.Build.0 = Release|Any CPU + {E5A649CE-987F-46FE-8FA8-1290951AE21D}.Release|x64.ActiveCfg = Release|Any CPU + {E5A649CE-987F-46FE-8FA8-1290951AE21D}.Release|x64.Build.0 = Release|Any CPU + {E15D7151-C812-4432-AB2A-F9EF06E4DF73}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E15D7151-C812-4432-AB2A-F9EF06E4DF73}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E15D7151-C812-4432-AB2A-F9EF06E4DF73}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {E15D7151-C812-4432-AB2A-F9EF06E4DF73}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {E15D7151-C812-4432-AB2A-F9EF06E4DF73}.Debug|ARM64.Build.0 = Debug|Any CPU + {E15D7151-C812-4432-AB2A-F9EF06E4DF73}.Debug|ARM64.Deploy.0 = Debug|Any CPU + {E15D7151-C812-4432-AB2A-F9EF06E4DF73}.Debug|x64.ActiveCfg = Debug|Any CPU + {E15D7151-C812-4432-AB2A-F9EF06E4DF73}.Debug|x64.Build.0 = Debug|Any CPU + {E15D7151-C812-4432-AB2A-F9EF06E4DF73}.Debug|x64.Deploy.0 = Debug|Any CPU + {E15D7151-C812-4432-AB2A-F9EF06E4DF73}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E15D7151-C812-4432-AB2A-F9EF06E4DF73}.Release|Any CPU.Build.0 = Release|Any CPU + {E15D7151-C812-4432-AB2A-F9EF06E4DF73}.Release|Any CPU.Deploy.0 = Release|Any CPU + {E15D7151-C812-4432-AB2A-F9EF06E4DF73}.Release|ARM64.ActiveCfg = Release|Any CPU + {E15D7151-C812-4432-AB2A-F9EF06E4DF73}.Release|ARM64.Build.0 = Release|Any CPU + {E15D7151-C812-4432-AB2A-F9EF06E4DF73}.Release|ARM64.Deploy.0 = Release|Any CPU + {E15D7151-C812-4432-AB2A-F9EF06E4DF73}.Release|x64.ActiveCfg = Release|Any CPU + {E15D7151-C812-4432-AB2A-F9EF06E4DF73}.Release|x64.Build.0 = Release|Any CPU + {E15D7151-C812-4432-AB2A-F9EF06E4DF73}.Release|x64.Deploy.0 = Release|Any CPU + {70D12BD7-3CFE-48B6-8E28-B9554FB21AD0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {70D12BD7-3CFE-48B6-8E28-B9554FB21AD0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {70D12BD7-3CFE-48B6-8E28-B9554FB21AD0}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {70D12BD7-3CFE-48B6-8E28-B9554FB21AD0}.Debug|ARM64.Build.0 = Debug|Any CPU + {70D12BD7-3CFE-48B6-8E28-B9554FB21AD0}.Debug|x64.ActiveCfg = Debug|Any CPU + {70D12BD7-3CFE-48B6-8E28-B9554FB21AD0}.Debug|x64.Build.0 = Debug|Any CPU + {70D12BD7-3CFE-48B6-8E28-B9554FB21AD0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {70D12BD7-3CFE-48B6-8E28-B9554FB21AD0}.Release|Any CPU.Build.0 = Release|Any CPU + {70D12BD7-3CFE-48B6-8E28-B9554FB21AD0}.Release|ARM64.ActiveCfg = Release|Any CPU + {70D12BD7-3CFE-48B6-8E28-B9554FB21AD0}.Release|ARM64.Build.0 = Release|Any CPU + {70D12BD7-3CFE-48B6-8E28-B9554FB21AD0}.Release|x64.ActiveCfg = Release|Any CPU + {70D12BD7-3CFE-48B6-8E28-B9554FB21AD0}.Release|x64.Build.0 = Release|Any CPU + {6EC5CAE7-DD30-4181-ADF2-B1BA19BA84F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6EC5CAE7-DD30-4181-ADF2-B1BA19BA84F0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6EC5CAE7-DD30-4181-ADF2-B1BA19BA84F0}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {6EC5CAE7-DD30-4181-ADF2-B1BA19BA84F0}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {6EC5CAE7-DD30-4181-ADF2-B1BA19BA84F0}.Debug|ARM64.Build.0 = Debug|ARM64 + {6EC5CAE7-DD30-4181-ADF2-B1BA19BA84F0}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {6EC5CAE7-DD30-4181-ADF2-B1BA19BA84F0}.Debug|x64.ActiveCfg = Debug|x64 + {6EC5CAE7-DD30-4181-ADF2-B1BA19BA84F0}.Debug|x64.Build.0 = Debug|x64 + {6EC5CAE7-DD30-4181-ADF2-B1BA19BA84F0}.Debug|x64.Deploy.0 = Debug|x64 + {6EC5CAE7-DD30-4181-ADF2-B1BA19BA84F0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6EC5CAE7-DD30-4181-ADF2-B1BA19BA84F0}.Release|Any CPU.Build.0 = Release|Any CPU + {6EC5CAE7-DD30-4181-ADF2-B1BA19BA84F0}.Release|Any CPU.Deploy.0 = Release|Any CPU + {6EC5CAE7-DD30-4181-ADF2-B1BA19BA84F0}.Release|ARM64.ActiveCfg = Release|ARM64 + {6EC5CAE7-DD30-4181-ADF2-B1BA19BA84F0}.Release|ARM64.Build.0 = Release|ARM64 + {6EC5CAE7-DD30-4181-ADF2-B1BA19BA84F0}.Release|ARM64.Deploy.0 = Release|ARM64 + {6EC5CAE7-DD30-4181-ADF2-B1BA19BA84F0}.Release|x64.ActiveCfg = Release|x64 + {6EC5CAE7-DD30-4181-ADF2-B1BA19BA84F0}.Release|x64.Build.0 = Release|x64 + {6EC5CAE7-DD30-4181-ADF2-B1BA19BA84F0}.Release|x64.Deploy.0 = Release|x64 + {2940DEDC-756B-43AE-BAD2-49BFA7D83009}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2940DEDC-756B-43AE-BAD2-49BFA7D83009}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2940DEDC-756B-43AE-BAD2-49BFA7D83009}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {2940DEDC-756B-43AE-BAD2-49BFA7D83009}.Debug|ARM64.Build.0 = Debug|Any CPU + {2940DEDC-756B-43AE-BAD2-49BFA7D83009}.Debug|x64.ActiveCfg = Debug|Any CPU + {2940DEDC-756B-43AE-BAD2-49BFA7D83009}.Debug|x64.Build.0 = Debug|Any CPU + {2940DEDC-756B-43AE-BAD2-49BFA7D83009}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2940DEDC-756B-43AE-BAD2-49BFA7D83009}.Release|Any CPU.Build.0 = Release|Any CPU + {2940DEDC-756B-43AE-BAD2-49BFA7D83009}.Release|ARM64.ActiveCfg = Release|Any CPU + {2940DEDC-756B-43AE-BAD2-49BFA7D83009}.Release|ARM64.Build.0 = Release|Any CPU + {2940DEDC-756B-43AE-BAD2-49BFA7D83009}.Release|x64.ActiveCfg = Release|Any CPU + {2940DEDC-756B-43AE-BAD2-49BFA7D83009}.Release|x64.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {2940DEDC-756B-43AE-BAD2-49BFA7D83009} = {D82AE45E-DEA4-4B99-897B-80FF32460DFF} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {DFC4B6F7-CE69-4022-B783-EB634FF510C9} + EndGlobalSection +EndGlobal diff --git a/RbfxTemplate/GameRmlUIComponent.cs b/RbfxTemplate/GameRmlUIComponent.cs new file mode 100644 index 0000000..c0b69e2 --- /dev/null +++ b/RbfxTemplate/GameRmlUIComponent.cs @@ -0,0 +1,51 @@ +using System.ComponentModel; +using Urho3DNet; + +namespace RbfxTemplate +{ + [ObjectFactory(Category = "Component/Game")] + [Preserve(AllMembers = true)] + public partial class GameRmlUIComponent : RmlUIComponent + { + private RmlUIStateBase _state; + + public GameRmlUIComponent(Context context) : base(context) + { + } + + public RmlUIStateBase State + { + get => _state; + set + { + if (_state != value) + { + if (_state != null) + _state.PropertyChanged -= OnPropertyChanged; + + _state = value; + + if (_state != null) + _state.PropertyChanged += OnPropertyChanged; + } + } + } + + private void OnPropertyChanged(object sender, PropertyChangedEventArgs e) + { + DirtyVariable(e.PropertyName); + } + + public void UpdateProperties() + { + DirtyAllVariables(); + } + + protected override void OnDataModelInitialized() + { + State?.OnDataModelInitialized(this); + + base.OnDataModelInitialized(); + } + } +} \ No newline at end of file diff --git a/RbfxTemplate/GameSettings.cs b/RbfxTemplate/GameSettings.cs new file mode 100644 index 0000000..96417c8 --- /dev/null +++ b/RbfxTemplate/GameSettings.cs @@ -0,0 +1,45 @@ +using System; +using Urho3DNet; + +namespace RbfxTemplate +{ + /// + /// Settings file content. + /// + public class GameSettings + { + private static readonly string SOUND_MASTER = "Master"; + + private static readonly string SOUND_EFFECT = "Effect"; + + private static readonly string SOUND_MUSIC = "Music"; + + /// + /// Get or set master volume. + /// + public float MasterVolume { get; set; } = 1.0f; + + /// + /// Get or set music volume. + /// + public float MusicVolume { get; set; } = 1.0f; + + /// + /// Get or set effects volume. + /// + public float EffectVolume { get; set; } = 1.0f; + + /// + /// Apply settings to the application global settings. + /// + /// Application context. + public void Apply(Context context) + { + var audio = context.GetSubsystem