mirror of
https://github.com/litruv/PNGTuber-Plus.git
synced 2026-07-24 02:26:02 +10:00
Compare commits
7 Commits
build-51b8
...
v2025.07.2
| Author | SHA1 | Date | |
|---|---|---|---|
| fc4cacdc9f | |||
| 848361d19b | |||
| 711865c6a4 | |||
| d231b730f7 | |||
| 8ba361f3c2 | |||
| c74dccf1cf | |||
| 5c51691ba7 |
121
.github/workflows/build-windows.yml
vendored
121
.github/workflows/build-windows.yml
vendored
@@ -1,5 +1,6 @@
|
||||
name: Build Windows
|
||||
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master, main ]
|
||||
@@ -14,24 +15,76 @@ env:
|
||||
jobs:
|
||||
export-windows:
|
||||
name: Windows Export
|
||||
runs-on: ubuntu-20.04
|
||||
container:
|
||||
image: barichello/godot-ci:4.4.1
|
||||
runs-on: self-hosted
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
lfs: true
|
||||
|
||||
- name: Setup
|
||||
- name: Debug Environment
|
||||
run: |
|
||||
mkdir -v -p ~/.local/share/godot/export_templates/
|
||||
mv /root/.local/share/godot/export_templates/${GODOT_VERSION}.stable ~/.local/share/godot/export_templates/${GODOT_VERSION}.stable
|
||||
|
||||
Write-Host "Current directory: $(Get-Location)"
|
||||
Write-Host "Godot executable exists: $(Test-Path 'D:\Godot\Godot_v4.4.1-stable_win64.exe')"
|
||||
Write-Host "Export name: $env:EXPORT_NAME"
|
||||
Write-Host "Project file exists: $(Test-Path 'project.godot')"
|
||||
Get-ChildItem -Path . -Filter "*.cfg" | Select-Object Name
|
||||
|
||||
- name: Verify Export Templates
|
||||
run: |
|
||||
$templateDir = "C:\WINDOWS\ServiceProfiles\NetworkService\AppData\Roaming\Godot\export_templates\4.4.1.stable"
|
||||
Write-Host "Checking for export templates at: $templateDir"
|
||||
|
||||
if (Test-Path $templateDir) {
|
||||
Write-Host "Export templates found. Contents:"
|
||||
Get-ChildItem -Path $templateDir | Where-Object {$_.Name -like "*windows*"} | Select-Object Name, Length | Format-Table
|
||||
|
||||
# Verify the specific Windows templates we need
|
||||
$debugTemplate = Join-Path $templateDir "windows_debug_x86_64.exe"
|
||||
$releaseTemplate = Join-Path $templateDir "windows_release_x86_64.exe"
|
||||
|
||||
if ((Test-Path $debugTemplate) -and (Test-Path $releaseTemplate)) {
|
||||
Write-Host "✅ Required Windows templates found"
|
||||
} else {
|
||||
Write-Host "❌ Required Windows templates missing"
|
||||
exit 1
|
||||
}
|
||||
} else {
|
||||
Write-Host "❌ Export template directory not found!"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Check if rcedit is available (it's already in the project)
|
||||
Write-Host "Checking for rcedit..."
|
||||
if (Test-Path "rcedit-x64.exe") {
|
||||
Write-Host "✅ rcedit found in project directory"
|
||||
} else {
|
||||
Write-Host "rcedit not found - downloading..."
|
||||
Invoke-WebRequest -Uri "https://github.com/electron/rcedit/releases/latest/download/rcedit-x64.exe" -OutFile "rcedit-x64.exe"
|
||||
Write-Host "✅ rcedit downloaded"
|
||||
}
|
||||
|
||||
- name: Windows Build
|
||||
run: .\build-windows-ci.bat
|
||||
shell: cmd
|
||||
|
||||
- name: Check Build Output
|
||||
run: |
|
||||
mkdir -v -p build/windows
|
||||
godot --headless --verbose --export-release "Windows Desktop" build/windows/$EXPORT_NAME.exe
|
||||
Write-Host "Build directory contents:"
|
||||
if (Test-Path "build\windows") {
|
||||
Get-ChildItem -Path "build\windows" -Recurse | Select-Object Name, Length
|
||||
} else {
|
||||
Write-Host "Build directory does not exist!"
|
||||
}
|
||||
|
||||
if (Test-Path "build\windows\PNGTuber-Plus.exe") {
|
||||
Write-Host "Build SUCCESS: PNGTuber-Plus.exe created"
|
||||
$fileSize = (Get-Item "build\windows\PNGTuber-Plus.exe").Length
|
||||
Write-Host "File size: $fileSize bytes"
|
||||
} else {
|
||||
Write-Host "Build FAILED: PNGTuber-Plus.exe not found"
|
||||
exit 1
|
||||
}
|
||||
|
||||
- name: Upload Windows Build
|
||||
uses: actions/upload-artifact@v4
|
||||
@@ -43,9 +96,39 @@ jobs:
|
||||
release:
|
||||
name: Create Release
|
||||
needs: export-windows
|
||||
runs-on: ubuntu-latest
|
||||
if: github.ref == 'refs/heads/master' && github.event_name == 'push'
|
||||
runs-on: self-hosted
|
||||
if: github.ref == 'refs/heads/master' && github.event_name == 'push' && success()
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Generate Release Info
|
||||
id: release_info
|
||||
run: |
|
||||
# Get current date and time
|
||||
$date = Get-Date -Format "yyyy.MM.dd"
|
||||
$time = Get-Date -Format "HHmm"
|
||||
|
||||
# Get short commit hash (first 7 characters)
|
||||
$shortSha = "${{ github.sha }}".Substring(0, 7)
|
||||
|
||||
# Get commit count since last tag (for build number)
|
||||
$buildNumber = & git rev-list --count HEAD
|
||||
|
||||
# Create version-like tag and release name
|
||||
$tag = "v$date-build$buildNumber"
|
||||
$releaseName = "PNGTuber+ v$date Build $buildNumber"
|
||||
|
||||
Write-Host "Generated tag: $tag"
|
||||
Write-Host "Generated release name: $releaseName"
|
||||
|
||||
# Set outputs for use in next steps
|
||||
echo "tag=$tag" >> $env:GITHUB_OUTPUT
|
||||
echo "release_name=$releaseName" >> $env:GITHUB_OUTPUT
|
||||
echo "short_sha=$shortSha" >> $env:GITHUB_OUTPUT
|
||||
echo "build_number=$buildNumber" >> $env:GITHUB_OUTPUT
|
||||
- name: Download Windows Build
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
@@ -58,21 +141,19 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: build-${{ github.sha }}
|
||||
release_name: PNGTuber Plus Build ${{ github.sha }}
|
||||
tag_name: ${{ steps.release_info.outputs.tag }}
|
||||
release_name: ${{ steps.release_info.outputs.release_name }}
|
||||
body: |
|
||||
Automated build of PNGTuber Plus
|
||||
|
||||
## Recent Updates by Litruv
|
||||
- **StreamDeck Integration**: Add buttons to enable the streamdeck plugin that was built in
|
||||
- **Rotation Wobble**: New sprite rotation effects with frequency and amplitude controls
|
||||
- **Enhanced Modifier Keys**: Support for complex key combinations (Ctrl+Shift+Alt+Cmd)
|
||||
- **Godot 4.4.1 Support**: Updated for latest Godot stable release
|
||||
|
||||
|
||||
## Installation
|
||||
1. Download PNGTuber-Plus.exe from the assets below
|
||||
2. Run the executable - no installation required!
|
||||
3. For StreamDeck integration, download the plugin from [here](https://github.com/BoyneGames/streamdeck-godot-plugin/releases/tag/1.0.0)
|
||||
|
||||
## Credits
|
||||
- Original project by [kaiakairos](https://github.com/kaiakairos/PNGTuber-Plus)
|
||||
- Microphone improvements by [k0ffinz](https://github.com/k0ffinz/PNGTuber-Plus)
|
||||
draft: false
|
||||
prerelease: false
|
||||
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,3 +3,4 @@
|
||||
.export/
|
||||
.itchio/
|
||||
.steam/
|
||||
build/
|
||||
33
.vscode/launch.json
vendored
Normal file
33
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Launch PNGTuber Plus (Godot)",
|
||||
"type": "godot",
|
||||
"request": "launch",
|
||||
"port": 6007,
|
||||
"address": "127.0.0.1"
|
||||
},
|
||||
{
|
||||
"name": "Attach to Running Godot",
|
||||
"type": "godot",
|
||||
"request": "attach",
|
||||
"port": 6007,
|
||||
"address": "127.0.0.1"
|
||||
},
|
||||
{
|
||||
"name": "Launch Built Executable",
|
||||
"type": "PowerShell",
|
||||
"request": "launch",
|
||||
"script": "if (Test-Path '${workspaceFolder}\\build\\windows\\PNGTuber-Plus.exe') { Start-Process '${workspaceFolder}\\build\\windows\\PNGTuber-Plus.exe' } else { Write-Host 'Executable not found. Build the project first.' }",
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"name": "Build and Launch",
|
||||
"type": "PowerShell",
|
||||
"request": "launch",
|
||||
"script": ".\\build-windows.bat; if (Test-Path '.\\build\\windows\\PNGTuber-Plus.exe') { Start-Process '.\\build\\windows\\PNGTuber-Plus.exe' }",
|
||||
"cwd": "${workspaceFolder}"
|
||||
}
|
||||
]
|
||||
}
|
||||
121
.vscode/tasks.json
vendored
Normal file
121
.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "Build Windows (Local)",
|
||||
"type": "shell",
|
||||
"command": ".\\build-windows.bat",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"args": [],
|
||||
"isBackground": false,
|
||||
"problemMatcher": [],
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared",
|
||||
"showReuseMessage": true,
|
||||
"clear": false
|
||||
},
|
||||
"detail": "Build Windows executable using local build script with template management"
|
||||
},
|
||||
{
|
||||
"label": "Build Windows (CI)",
|
||||
"type": "shell",
|
||||
"command": ".\\build-windows-ci.bat",
|
||||
"group": "build",
|
||||
"args": [],
|
||||
"isBackground": false,
|
||||
"problemMatcher": [],
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared",
|
||||
"showReuseMessage": true,
|
||||
"clear": false
|
||||
},
|
||||
"detail": "Build Windows executable using CI build script (no template download)"
|
||||
},
|
||||
{
|
||||
"label": "Export Windows (Godot Direct)",
|
||||
"type": "shell",
|
||||
"command": "D:\\Godot\\Godot_v4.4.1-stable_win64.exe",
|
||||
"group": "build",
|
||||
"args": [
|
||||
"--headless",
|
||||
"--export-release",
|
||||
"\"Windows Desktop\"",
|
||||
"\"build/windows/PNGTuber-Plus.exe\""
|
||||
],
|
||||
"isBackground": false,
|
||||
"problemMatcher": [],
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared",
|
||||
"showReuseMessage": true,
|
||||
"clear": false
|
||||
},
|
||||
"detail": "Export Windows build directly using Godot (requires templates already installed)"
|
||||
},
|
||||
{
|
||||
"label": "Clean Build Directory",
|
||||
"type": "shell",
|
||||
"command": "if (Test-Path 'build') { Remove-Item -Recurse -Force 'build' }; Write-Host 'Build directory cleaned'",
|
||||
"group": "build",
|
||||
"args": [],
|
||||
"isBackground": false,
|
||||
"problemMatcher": [],
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared",
|
||||
"showReuseMessage": true,
|
||||
"clear": false
|
||||
},
|
||||
"detail": "Clean the build output directory"
|
||||
},
|
||||
{
|
||||
"label": "Open Build Directory",
|
||||
"type": "shell",
|
||||
"command": "if (Test-Path 'build\\windows') { explorer 'build\\windows' } else { Write-Host 'Build directory does not exist. Run a build first.' }",
|
||||
"group": "build",
|
||||
"args": [],
|
||||
"isBackground": false,
|
||||
"problemMatcher": [],
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared",
|
||||
"showReuseMessage": true,
|
||||
"clear": false
|
||||
},
|
||||
"detail": "Open the Windows build output directory in Explorer"
|
||||
},
|
||||
{
|
||||
"label": "Run Built Executable",
|
||||
"type": "shell",
|
||||
"command": "if (Test-Path 'build\\windows\\PNGTuber-Plus.exe') { Start-Process 'build\\windows\\PNGTuber-Plus.exe' } else { Write-Host 'Executable not found. Build the project first.' }",
|
||||
"group": "test",
|
||||
"args": [],
|
||||
"isBackground": true,
|
||||
"problemMatcher": [],
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared",
|
||||
"showReuseMessage": true,
|
||||
"clear": false
|
||||
},
|
||||
"detail": "Run the built Windows executable for testing"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -8,9 +8,10 @@
|
||||
- **Rotation Wobble**: New sprite rotation effects with frequency and amplitude controls
|
||||
- **Enhanced Modifier Keys**: Support for complex key combinations (Ctrl+Shift+Alt+Cmd)
|
||||
- **Godot 4.4.1 Support**: Updated for latest Godot stable release
|
||||
- **Microphone Improvements**: Audio delay fix & more *from [k0ffinz/PNGTuber-Plus](https://github.com/k0ffinz/PNGTuber-Plus)*
|
||||
|
||||
## 🙏 Credits
|
||||
|
||||
- **Original Project**: PNGTuber Plus base application
|
||||
- **Original Project**: [PNGTuber Plus by kaiakairos](https://github.com/kaiakairos/PNGTuber-Plus)
|
||||
- **StreamDeck Plugin**: Based on [BoyneGames StreamDeck Godot Plugin](https://github.com/BoyneGames/streamdeck-godot-plugin)
|
||||
- **Enhanced Features**: Max Litruv Boonzaayer
|
||||
- **Microphone Improvements**: k0ffinz - Experimental mic loudness detection, improved audio initialization, and audio delay fixes from [k0ffinz/PNGTuber-Plus](https://github.com/k0ffinz/PNGTuber-Plus)
|
||||
Binary file not shown.
@@ -29,13 +29,13 @@ var blink = false
|
||||
var blinkTick = 0
|
||||
|
||||
#Audio Listener
|
||||
|
||||
var currentMicrophone = null
|
||||
var playa:AudioStreamPlayer
|
||||
|
||||
var speaking = false
|
||||
var spectrum
|
||||
var volume = 0
|
||||
var volumeSensitivity = 0.0
|
||||
var experimentalMicLoudness = false
|
||||
|
||||
var volumeLimit = 0.0
|
||||
var senseLimit = 0.0
|
||||
@@ -44,8 +44,6 @@ var senseLimit = 0.0
|
||||
signal startSpeaking
|
||||
signal stopSpeaking
|
||||
|
||||
var micResetTime = 180
|
||||
|
||||
var updatePusherNode = null
|
||||
|
||||
var rand = RandomNumberGenerator.new()
|
||||
@@ -56,28 +54,23 @@ func _ready():
|
||||
if !Saving.settings.has("useStreamDeck"):
|
||||
Saving.settings["useStreamDeck"] = false
|
||||
|
||||
if Saving.settings.has("secondsToMicReset"):
|
||||
Global.micResetTime = Saving.settings["secondsToMicReset"]
|
||||
if Saving.settings.has("experimentalMicLoudness"):
|
||||
Global.experimentalMicLoudness = Saving.settings["experimentalMicLoudness"]
|
||||
else:
|
||||
Saving.settings["secondsToMicReset"] = 180
|
||||
|
||||
Saving.settings["experimentalMicLoudness"] = false
|
||||
|
||||
createMicrophone()
|
||||
|
||||
func createMicrophone():
|
||||
var playa = AudioStreamPlayer.new()
|
||||
var mic = AudioStreamMicrophone.new()
|
||||
playa.stream = mic
|
||||
playa.autoplay = true
|
||||
if playa != null:
|
||||
remove_child(playa)
|
||||
playa.free()
|
||||
playa = AudioStreamPlayer.new()
|
||||
playa.bus = "MIC"
|
||||
playa.stream = AudioStreamMicrophone.new()
|
||||
add_child(playa)
|
||||
currentMicrophone = playa
|
||||
await get_tree().create_timer(micResetTime).timeout
|
||||
if currentMicrophone != playa:
|
||||
return
|
||||
deleteAllMics()
|
||||
currentMicrophone = null
|
||||
await get_tree().create_timer(0.25).timeout
|
||||
createMicrophone()
|
||||
await get_tree().create_timer(0.25).timeout # apparently it works to fix WASAPI "Initialize failed with error 0xffffffff88890002" and "init_input_device" errors
|
||||
playa.play()
|
||||
|
||||
func deleteAllMics():
|
||||
for child in get_children():
|
||||
@@ -87,8 +80,9 @@ func deleteAllMics():
|
||||
func _process(delta):
|
||||
animationTick += 1
|
||||
|
||||
volume = spectrum.get_magnitude_for_frequency_range(20, 20000).length()
|
||||
if currentMicrophone != null:
|
||||
volume = (AudioServer.get_bus_peak_volume_left_db(1, 0) + AudioServer.get_bus_peak_volume_right_db(1, 0)) / 1600.0 + 0.25 if experimentalMicLoudness else spectrum.get_magnitude_for_frequency_range(20, 20000).length()
|
||||
|
||||
if playa != null:
|
||||
volumeSensitivity = lerp(volumeSensitivity,0.0,delta*2)
|
||||
|
||||
if volume>volumeLimit:
|
||||
|
||||
@@ -54,13 +54,13 @@ var settings = {
|
||||
"bounce":250,
|
||||
"gravity":1000,
|
||||
"maxFPS":60,
|
||||
"secondsToMicReset":180,
|
||||
"backgroundColor":var_to_str(Color(0.0,0.0,0.0,0.0)),
|
||||
"filtering":false,
|
||||
"costumeKeys":["1","2","3","4","5","6","7","8","9","0"],
|
||||
"blinkSpeed":1.0,
|
||||
"blinkChance":200,
|
||||
"bounceOnCostumeChange":false,
|
||||
"experimentalMicLoudness":false,
|
||||
}
|
||||
|
||||
var settingsPath = "user://settings.pngtp"
|
||||
|
||||
Binary file not shown.
40
build-windows-ci.bat
Normal file
40
build-windows-ci.bat
Normal file
@@ -0,0 +1,40 @@
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
echo Building PNGTuber Plus for Windows (CI Environment)...
|
||||
|
||||
rem Create build directory
|
||||
if not exist "build\windows" mkdir "build\windows"
|
||||
|
||||
rem Templates should already be installed by the GitHub Actions workflow
|
||||
set TEMPLATE_DIR=C:\WINDOWS\ServiceProfiles\NetworkService\AppData\Roaming\Godot\export_templates\4.4.1.stable
|
||||
echo Checking for export templates at: %TEMPLATE_DIR%
|
||||
|
||||
if exist "%TEMPLATE_DIR%" (
|
||||
echo Export templates found.
|
||||
dir "%TEMPLATE_DIR%"
|
||||
) else (
|
||||
echo ERROR: Export templates not found at %TEMPLATE_DIR%
|
||||
echo This should have been handled by the GitHub Actions setup step.
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
rem Build the project
|
||||
echo Running Godot export...
|
||||
"D:\Godot\Godot_v4.4.1-stable_win64.exe" --headless --export-release "Windows Desktop" "build\windows\PNGTuber-Plus.exe"
|
||||
|
||||
if %ERRORLEVEL% EQU 0 (
|
||||
echo.
|
||||
echo Build completed successfully!
|
||||
echo Output: build\windows\PNGTuber-Plus.exe
|
||||
if exist "build\windows\PNGTuber-Plus.exe" (
|
||||
echo File size:
|
||||
dir "build\windows\PNGTuber-Plus.exe"
|
||||
)
|
||||
echo.
|
||||
) else (
|
||||
echo.
|
||||
echo Build failed with error code %ERRORLEVEL%
|
||||
echo.
|
||||
exit /b %ERRORLEVEL%
|
||||
)
|
||||
@@ -1,22 +1,49 @@
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
echo Building PNGTuber Plus for Windows...
|
||||
|
||||
:: Create build directory
|
||||
rem Create build directory
|
||||
if not exist "build\windows" mkdir "build\windows"
|
||||
|
||||
:: Build the project
|
||||
rem Install export templates if they don't exist
|
||||
echo Checking for export templates...
|
||||
set TEMPLATE_DIR=%APPDATA%\Godot\export_templates\4.4.1.stable
|
||||
if not exist "%TEMPLATE_DIR%" (
|
||||
echo Export templates not found. Installing...
|
||||
"D:\Godot\Godot_v4.4.1-stable_win64.exe" --headless --export-pack
|
||||
timeout /t 5 /nobreak >nul
|
||||
|
||||
rem Download templates if the export-pack didn't work
|
||||
if not exist "%TEMPLATE_DIR%" (
|
||||
echo Downloading export templates...
|
||||
powershell -Command "& {Invoke-WebRequest -Uri 'https://github.com/godotengine/godot/releases/download/4.4.1-stable/Godot_v4.4.1-stable_export_templates.tpz' -OutFile 'templates.tpz'}"
|
||||
|
||||
rem Rename and extract templates
|
||||
powershell -Command "& {Rename-Item 'templates.tpz' 'templates.zip'}"
|
||||
powershell -Command "& {Expand-Archive -Path 'templates.zip' -DestinationPath 'temp_templates' -Force}"
|
||||
if not exist "%APPDATA%\Godot\export_templates" mkdir "%APPDATA%\Godot\export_templates"
|
||||
move "temp_templates\templates" "%TEMPLATE_DIR%"
|
||||
rmdir /s /q "temp_templates"
|
||||
del "templates.zip"
|
||||
echo Export templates installed.
|
||||
)
|
||||
) else (
|
||||
echo Export templates found.
|
||||
)
|
||||
|
||||
rem Build the project
|
||||
echo Running Godot export...
|
||||
godot --headless --verbose --export-release "Windows Desktop" "build\windows\PNGTuber-Plus.exe"
|
||||
"D:\Godot\Godot_v4.4.1-stable_win64.exe" --headless --export-release "Windows Desktop" "build\windows\PNGTuber-Plus.exe"
|
||||
|
||||
if %ERRORLEVEL% EQU 0 (
|
||||
echo.
|
||||
echo ✅ Build completed successfully!
|
||||
echo Build completed successfully!
|
||||
echo Output: build\windows\PNGTuber-Plus.exe
|
||||
echo.
|
||||
pause
|
||||
) else (
|
||||
echo.
|
||||
echo ❌ Build failed with error code %ERRORLEVEL%
|
||||
echo Build failed with error code %ERRORLEVEL%
|
||||
echo.
|
||||
pause
|
||||
)
|
||||
|
||||
|
||||
@@ -3,27 +3,29 @@
|
||||
name="Windows Desktop"
|
||||
platform="Windows Desktop"
|
||||
runnable=true
|
||||
advanced_options=true
|
||||
dedicated_server=false
|
||||
custom_features=""
|
||||
export_filter="all_resources"
|
||||
include_filter=""
|
||||
exclude_filter=""
|
||||
export_path=".export/release 1.4.5/steam/PNGTUBER PLUS 1.4.5 STEAM.exe"
|
||||
exclude_filter="addons/godot-git-plugin/*"
|
||||
export_path="build/windows/PNGTuber-Plus.exe"
|
||||
patches=PackedStringArray()
|
||||
encryption_include_filters=""
|
||||
encryption_exclude_filters=""
|
||||
seed=0
|
||||
encrypt_pck=false
|
||||
encrypt_directory=false
|
||||
script_export_mode=2
|
||||
|
||||
[preset.0.options]
|
||||
|
||||
custom_template/debug=""
|
||||
custom_template/release=""
|
||||
debug/export_console_wrapper=1
|
||||
binary_format/embed_pck=false
|
||||
texture_format/bptc=true
|
||||
texture_format/s3tc=true
|
||||
texture_format/etc=false
|
||||
texture_format/etc2=false
|
||||
debug/export_console_wrapper=2
|
||||
binary_format/embed_pck=true
|
||||
texture_format/s3tc_bptc=true
|
||||
texture_format/etc2_astc=false
|
||||
binary_format/architecture="x86_64"
|
||||
codesign/enable=false
|
||||
codesign/timestamp=true
|
||||
@@ -42,6 +44,9 @@ application/product_name="PNGTuber Plus"
|
||||
application/file_description=""
|
||||
application/copyright=""
|
||||
application/trademarks=""
|
||||
application/export_angle=0
|
||||
application/export_d3d12=0
|
||||
application/d3d12_agility_sdk_multiarch=true
|
||||
ssh_remote_deploy/enabled=false
|
||||
ssh_remote_deploy/host="user@host_ip"
|
||||
ssh_remote_deploy/port="22"
|
||||
@@ -59,22 +64,30 @@ Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorActi
|
||||
ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue
|
||||
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue
|
||||
Remove-Item -Recurse -Force '{temp_dir}'"
|
||||
texture_format/bptc=true
|
||||
texture_format/s3tc=true
|
||||
texture_format/etc=false
|
||||
texture_format/etc2=false
|
||||
|
||||
[preset.1]
|
||||
|
||||
name="Linux/X11"
|
||||
platform="Linux/X11"
|
||||
platform="Linux"
|
||||
runnable=true
|
||||
advanced_options=false
|
||||
dedicated_server=false
|
||||
custom_features=""
|
||||
export_filter="all_resources"
|
||||
include_filter=""
|
||||
exclude_filter=""
|
||||
export_path=".export/release 1.4.5/linux/PNGTUBER PLUS 1.4.5 LINUX.x86_64"
|
||||
patches=PackedStringArray()
|
||||
encryption_include_filters=""
|
||||
encryption_exclude_filters=""
|
||||
seed=0
|
||||
encrypt_pck=false
|
||||
encrypt_directory=false
|
||||
script_export_mode=2
|
||||
|
||||
[preset.1.options]
|
||||
|
||||
@@ -82,10 +95,8 @@ custom_template/debug=""
|
||||
custom_template/release=""
|
||||
debug/export_console_wrapper=1
|
||||
binary_format/embed_pck=false
|
||||
texture_format/bptc=true
|
||||
texture_format/s3tc=true
|
||||
texture_format/etc=false
|
||||
texture_format/etc2=false
|
||||
texture_format/s3tc_bptc=true
|
||||
texture_format/etc2_astc=false
|
||||
binary_format/architecture="x86_64"
|
||||
ssh_remote_deploy/enabled=false
|
||||
ssh_remote_deploy/host="user@host_ip"
|
||||
@@ -99,22 +110,30 @@ unzip -o -q \"{temp_dir}/{archive_name}\" -d \"{temp_dir}\"
|
||||
ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash
|
||||
kill $(pgrep -x -f \"{temp_dir}/{exe_name} {cmd_args}\")
|
||||
rm -rf \"{temp_dir}\""
|
||||
texture_format/bptc=true
|
||||
texture_format/s3tc=true
|
||||
texture_format/etc=false
|
||||
texture_format/etc2=false
|
||||
|
||||
[preset.2]
|
||||
|
||||
name="macOS"
|
||||
platform="macOS"
|
||||
runnable=true
|
||||
advanced_options=false
|
||||
dedicated_server=false
|
||||
custom_features=""
|
||||
export_filter="all_resources"
|
||||
include_filter=""
|
||||
exclude_filter=""
|
||||
export_path=".export/release 1.4.5/mac/PNGTUBER PLUS 1.4.5 MAC.zip"
|
||||
patches=PackedStringArray()
|
||||
encryption_include_filters=""
|
||||
encryption_exclude_filters=""
|
||||
seed=0
|
||||
encrypt_pck=false
|
||||
encrypt_directory=false
|
||||
script_export_mode=2
|
||||
|
||||
[preset.2.options]
|
||||
|
||||
@@ -132,8 +151,11 @@ application/short_version="1.4.5"
|
||||
application/version="1.4.5"
|
||||
application/copyright=""
|
||||
application/copyright_localized={}
|
||||
application/min_macos_version="10.12"
|
||||
application/min_macos_version_x86_64="10.12"
|
||||
application/min_macos_version_arm64="11.00"
|
||||
application/export_angle=0
|
||||
display/high_res=true
|
||||
application/additional_plist_content=""
|
||||
xcode/platform_build="14C18"
|
||||
xcode/sdk_version="13.1"
|
||||
xcode/sdk_build="22C55"
|
||||
@@ -166,7 +188,9 @@ codesign/entitlements/app_sandbox/files_downloads=0
|
||||
codesign/entitlements/app_sandbox/files_pictures=0
|
||||
codesign/entitlements/app_sandbox/files_music=0
|
||||
codesign/entitlements/app_sandbox/files_movies=0
|
||||
codesign/entitlements/app_sandbox/files_user_selected=0
|
||||
codesign/entitlements/app_sandbox/helper_executables=[]
|
||||
codesign/entitlements/additional=""
|
||||
codesign/custom_options=PackedStringArray()
|
||||
notarization/notarization=0
|
||||
privacy/microphone_usage_description="So the guy can go up and down!"
|
||||
@@ -191,6 +215,148 @@ privacy/network_volumes_usage_description=""
|
||||
privacy/network_volumes_usage_description_localized={}
|
||||
privacy/removable_volumes_usage_description=""
|
||||
privacy/removable_volumes_usage_description_localized={}
|
||||
privacy/tracking_enabled=false
|
||||
privacy/tracking_domains=PackedStringArray()
|
||||
privacy/collected_data/name/collected=false
|
||||
privacy/collected_data/name/linked_to_user=false
|
||||
privacy/collected_data/name/used_for_tracking=false
|
||||
privacy/collected_data/name/collection_purposes=0
|
||||
privacy/collected_data/email_address/collected=false
|
||||
privacy/collected_data/email_address/linked_to_user=false
|
||||
privacy/collected_data/email_address/used_for_tracking=false
|
||||
privacy/collected_data/email_address/collection_purposes=0
|
||||
privacy/collected_data/phone_number/collected=false
|
||||
privacy/collected_data/phone_number/linked_to_user=false
|
||||
privacy/collected_data/phone_number/used_for_tracking=false
|
||||
privacy/collected_data/phone_number/collection_purposes=0
|
||||
privacy/collected_data/physical_address/collected=false
|
||||
privacy/collected_data/physical_address/linked_to_user=false
|
||||
privacy/collected_data/physical_address/used_for_tracking=false
|
||||
privacy/collected_data/physical_address/collection_purposes=0
|
||||
privacy/collected_data/other_contact_info/collected=false
|
||||
privacy/collected_data/other_contact_info/linked_to_user=false
|
||||
privacy/collected_data/other_contact_info/used_for_tracking=false
|
||||
privacy/collected_data/other_contact_info/collection_purposes=0
|
||||
privacy/collected_data/health/collected=false
|
||||
privacy/collected_data/health/linked_to_user=false
|
||||
privacy/collected_data/health/used_for_tracking=false
|
||||
privacy/collected_data/health/collection_purposes=0
|
||||
privacy/collected_data/fitness/collected=false
|
||||
privacy/collected_data/fitness/linked_to_user=false
|
||||
privacy/collected_data/fitness/used_for_tracking=false
|
||||
privacy/collected_data/fitness/collection_purposes=0
|
||||
privacy/collected_data/payment_info/collected=false
|
||||
privacy/collected_data/payment_info/linked_to_user=false
|
||||
privacy/collected_data/payment_info/used_for_tracking=false
|
||||
privacy/collected_data/payment_info/collection_purposes=0
|
||||
privacy/collected_data/credit_info/collected=false
|
||||
privacy/collected_data/credit_info/linked_to_user=false
|
||||
privacy/collected_data/credit_info/used_for_tracking=false
|
||||
privacy/collected_data/credit_info/collection_purposes=0
|
||||
privacy/collected_data/other_financial_info/collected=false
|
||||
privacy/collected_data/other_financial_info/linked_to_user=false
|
||||
privacy/collected_data/other_financial_info/used_for_tracking=false
|
||||
privacy/collected_data/other_financial_info/collection_purposes=0
|
||||
privacy/collected_data/precise_location/collected=false
|
||||
privacy/collected_data/precise_location/linked_to_user=false
|
||||
privacy/collected_data/precise_location/used_for_tracking=false
|
||||
privacy/collected_data/precise_location/collection_purposes=0
|
||||
privacy/collected_data/coarse_location/collected=false
|
||||
privacy/collected_data/coarse_location/linked_to_user=false
|
||||
privacy/collected_data/coarse_location/used_for_tracking=false
|
||||
privacy/collected_data/coarse_location/collection_purposes=0
|
||||
privacy/collected_data/sensitive_info/collected=false
|
||||
privacy/collected_data/sensitive_info/linked_to_user=false
|
||||
privacy/collected_data/sensitive_info/used_for_tracking=false
|
||||
privacy/collected_data/sensitive_info/collection_purposes=0
|
||||
privacy/collected_data/contacts/collected=false
|
||||
privacy/collected_data/contacts/linked_to_user=false
|
||||
privacy/collected_data/contacts/used_for_tracking=false
|
||||
privacy/collected_data/contacts/collection_purposes=0
|
||||
privacy/collected_data/emails_or_text_messages/collected=false
|
||||
privacy/collected_data/emails_or_text_messages/linked_to_user=false
|
||||
privacy/collected_data/emails_or_text_messages/used_for_tracking=false
|
||||
privacy/collected_data/emails_or_text_messages/collection_purposes=0
|
||||
privacy/collected_data/photos_or_videos/collected=false
|
||||
privacy/collected_data/photos_or_videos/linked_to_user=false
|
||||
privacy/collected_data/photos_or_videos/used_for_tracking=false
|
||||
privacy/collected_data/photos_or_videos/collection_purposes=0
|
||||
privacy/collected_data/audio_data/collected=false
|
||||
privacy/collected_data/audio_data/linked_to_user=false
|
||||
privacy/collected_data/audio_data/used_for_tracking=false
|
||||
privacy/collected_data/audio_data/collection_purposes=0
|
||||
privacy/collected_data/gameplay_content/collected=false
|
||||
privacy/collected_data/gameplay_content/linked_to_user=false
|
||||
privacy/collected_data/gameplay_content/used_for_tracking=false
|
||||
privacy/collected_data/gameplay_content/collection_purposes=0
|
||||
privacy/collected_data/customer_support/collected=false
|
||||
privacy/collected_data/customer_support/linked_to_user=false
|
||||
privacy/collected_data/customer_support/used_for_tracking=false
|
||||
privacy/collected_data/customer_support/collection_purposes=0
|
||||
privacy/collected_data/other_user_content/collected=false
|
||||
privacy/collected_data/other_user_content/linked_to_user=false
|
||||
privacy/collected_data/other_user_content/used_for_tracking=false
|
||||
privacy/collected_data/other_user_content/collection_purposes=0
|
||||
privacy/collected_data/browsing_history/collected=false
|
||||
privacy/collected_data/browsing_history/linked_to_user=false
|
||||
privacy/collected_data/browsing_history/used_for_tracking=false
|
||||
privacy/collected_data/browsing_history/collection_purposes=0
|
||||
privacy/collected_data/search_hhistory/collected=false
|
||||
privacy/collected_data/search_hhistory/linked_to_user=false
|
||||
privacy/collected_data/search_hhistory/used_for_tracking=false
|
||||
privacy/collected_data/search_hhistory/collection_purposes=0
|
||||
privacy/collected_data/user_id/collected=false
|
||||
privacy/collected_data/user_id/linked_to_user=false
|
||||
privacy/collected_data/user_id/used_for_tracking=false
|
||||
privacy/collected_data/user_id/collection_purposes=0
|
||||
privacy/collected_data/device_id/collected=false
|
||||
privacy/collected_data/device_id/linked_to_user=false
|
||||
privacy/collected_data/device_id/used_for_tracking=false
|
||||
privacy/collected_data/device_id/collection_purposes=0
|
||||
privacy/collected_data/purchase_history/collected=false
|
||||
privacy/collected_data/purchase_history/linked_to_user=false
|
||||
privacy/collected_data/purchase_history/used_for_tracking=false
|
||||
privacy/collected_data/purchase_history/collection_purposes=0
|
||||
privacy/collected_data/product_interaction/collected=false
|
||||
privacy/collected_data/product_interaction/linked_to_user=false
|
||||
privacy/collected_data/product_interaction/used_for_tracking=false
|
||||
privacy/collected_data/product_interaction/collection_purposes=0
|
||||
privacy/collected_data/advertising_data/collected=false
|
||||
privacy/collected_data/advertising_data/linked_to_user=false
|
||||
privacy/collected_data/advertising_data/used_for_tracking=false
|
||||
privacy/collected_data/advertising_data/collection_purposes=0
|
||||
privacy/collected_data/other_usage_data/collected=false
|
||||
privacy/collected_data/other_usage_data/linked_to_user=false
|
||||
privacy/collected_data/other_usage_data/used_for_tracking=false
|
||||
privacy/collected_data/other_usage_data/collection_purposes=0
|
||||
privacy/collected_data/crash_data/collected=false
|
||||
privacy/collected_data/crash_data/linked_to_user=false
|
||||
privacy/collected_data/crash_data/used_for_tracking=false
|
||||
privacy/collected_data/crash_data/collection_purposes=0
|
||||
privacy/collected_data/performance_data/collected=false
|
||||
privacy/collected_data/performance_data/linked_to_user=false
|
||||
privacy/collected_data/performance_data/used_for_tracking=false
|
||||
privacy/collected_data/performance_data/collection_purposes=0
|
||||
privacy/collected_data/other_diagnostic_data/collected=false
|
||||
privacy/collected_data/other_diagnostic_data/linked_to_user=false
|
||||
privacy/collected_data/other_diagnostic_data/used_for_tracking=false
|
||||
privacy/collected_data/other_diagnostic_data/collection_purposes=0
|
||||
privacy/collected_data/environment_scanning/collected=false
|
||||
privacy/collected_data/environment_scanning/linked_to_user=false
|
||||
privacy/collected_data/environment_scanning/used_for_tracking=false
|
||||
privacy/collected_data/environment_scanning/collection_purposes=0
|
||||
privacy/collected_data/hands/collected=false
|
||||
privacy/collected_data/hands/linked_to_user=false
|
||||
privacy/collected_data/hands/used_for_tracking=false
|
||||
privacy/collected_data/hands/collection_purposes=0
|
||||
privacy/collected_data/head/collected=false
|
||||
privacy/collected_data/head/linked_to_user=false
|
||||
privacy/collected_data/head/used_for_tracking=false
|
||||
privacy/collected_data/head/collection_purposes=0
|
||||
privacy/collected_data/other_data_types/collected=false
|
||||
privacy/collected_data/other_data_types/linked_to_user=false
|
||||
privacy/collected_data/other_data_types/used_for_tracking=false
|
||||
privacy/collected_data/other_data_types/collection_purposes=0
|
||||
ssh_remote_deploy/enabled=false
|
||||
ssh_remote_deploy/host="user@host_ip"
|
||||
ssh_remote_deploy/port="22"
|
||||
@@ -202,3 +368,71 @@ open \"{temp_dir}/{exe_name}.app\" --args {cmd_args}"
|
||||
ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash
|
||||
kill $(pgrep -x -f \"{temp_dir}/{exe_name}.app/Contents/MacOS/{exe_name} {cmd_args}\")
|
||||
rm -rf \"{temp_dir}\""
|
||||
application/min_macos_version="10.12"
|
||||
|
||||
[preset.3]
|
||||
|
||||
name="Windows Desktop 2"
|
||||
platform="Windows Desktop"
|
||||
runnable=false
|
||||
advanced_options=false
|
||||
dedicated_server=false
|
||||
custom_features=""
|
||||
export_filter="all_resources"
|
||||
include_filter=""
|
||||
exclude_filter=""
|
||||
export_path=""
|
||||
patches=PackedStringArray()
|
||||
encryption_include_filters=""
|
||||
encryption_exclude_filters=""
|
||||
seed=0
|
||||
encrypt_pck=false
|
||||
encrypt_directory=false
|
||||
script_export_mode=2
|
||||
|
||||
[preset.3.options]
|
||||
|
||||
custom_template/debug=""
|
||||
custom_template/release=""
|
||||
debug/export_console_wrapper=1
|
||||
binary_format/embed_pck=false
|
||||
texture_format/s3tc_bptc=true
|
||||
texture_format/etc2_astc=false
|
||||
binary_format/architecture="x86_64"
|
||||
codesign/enable=false
|
||||
codesign/timestamp=true
|
||||
codesign/timestamp_server_url=""
|
||||
codesign/digest_algorithm=1
|
||||
codesign/description=""
|
||||
codesign/custom_options=PackedStringArray()
|
||||
application/modify_resources=true
|
||||
application/icon=""
|
||||
application/console_wrapper_icon=""
|
||||
application/icon_interpolation=4
|
||||
application/file_version=""
|
||||
application/product_version=""
|
||||
application/company_name=""
|
||||
application/product_name=""
|
||||
application/file_description=""
|
||||
application/copyright=""
|
||||
application/trademarks=""
|
||||
application/export_angle=0
|
||||
application/export_d3d12=0
|
||||
application/d3d12_agility_sdk_multiarch=true
|
||||
ssh_remote_deploy/enabled=false
|
||||
ssh_remote_deploy/host="user@host_ip"
|
||||
ssh_remote_deploy/port="22"
|
||||
ssh_remote_deploy/extra_args_ssh=""
|
||||
ssh_remote_deploy/extra_args_scp=""
|
||||
ssh_remote_deploy/run_script="Expand-Archive -LiteralPath '{temp_dir}\\{archive_name}' -DestinationPath '{temp_dir}'
|
||||
$action = New-ScheduledTaskAction -Execute '{temp_dir}\\{exe_name}' -Argument '{cmd_args}'
|
||||
$trigger = New-ScheduledTaskTrigger -Once -At 00:00
|
||||
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries
|
||||
$task = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings
|
||||
Register-ScheduledTask godot_remote_debug -InputObject $task -Force:$true
|
||||
Start-ScheduledTask -TaskName godot_remote_debug
|
||||
while (Get-ScheduledTask -TaskName godot_remote_debug | ? State -eq running) { Start-Sleep -Milliseconds 100 }
|
||||
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue"
|
||||
ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue
|
||||
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue
|
||||
Remove-Item -Recurse -Force '{temp_dir}'"
|
||||
|
||||
@@ -30,6 +30,7 @@ var editMode = true
|
||||
@onready var spriteObject = preload("res://ui_scenes/selectedSprite/spriteObject.tscn")
|
||||
|
||||
var saveLoaded = false
|
||||
var isSelectingMask = false
|
||||
|
||||
#Motion
|
||||
var yVel = 0
|
||||
@@ -62,7 +63,9 @@ func _ready():
|
||||
|
||||
Global.connect("startSpeaking",onSpeak)
|
||||
|
||||
ElgatoStreamDeck.on_key_down.connect(changeCostumeStreamDeck)
|
||||
var streamdeck_node = get_node_or_null("/root/ElgatoStreamDeck")
|
||||
if streamdeck_node:
|
||||
streamdeck_node.on_key_down.connect(changeCostumeStreamDeck)
|
||||
|
||||
if Saving.settings["newUser"]:
|
||||
_on_load_dialog_file_selected("default")
|
||||
@@ -153,6 +156,9 @@ func _process(delta):
|
||||
followShadow()
|
||||
|
||||
func followShadow():
|
||||
shadow.visible = false # Disabled drop shadow
|
||||
return
|
||||
|
||||
shadow.visible = is_instance_valid(Global.heldSprite)
|
||||
if !shadow.visible:
|
||||
return
|
||||
@@ -171,6 +177,9 @@ func isFileSystemOpen():
|
||||
if obj.visible:
|
||||
if obj == replaceDialog:
|
||||
return true
|
||||
# Don't clear held sprite when selecting mask
|
||||
if obj == fileDialog and isSelectingMask:
|
||||
return true
|
||||
Global.heldSprite = null
|
||||
return true
|
||||
return false
|
||||
@@ -288,7 +297,20 @@ func _on_add_button_pressed():
|
||||
|
||||
#Runs when selecting image in File Dialog
|
||||
func _on_file_dialog_file_selected(path):
|
||||
add_image(path)
|
||||
if isSelectingMask:
|
||||
# Handle mask selection
|
||||
if Global.heldSprite != null:
|
||||
Global.heldSprite.setMaskTexture(path)
|
||||
Global.spriteEdit.updateMaskDisplay(path)
|
||||
isSelectingMask = false
|
||||
else:
|
||||
# Handle normal sprite addition
|
||||
add_image(path)
|
||||
|
||||
#Opens File Dialog for mask selection
|
||||
func openMaskSelection():
|
||||
isSelectingMask = true
|
||||
fileDialog.visible = true
|
||||
|
||||
func _on_save_button_pressed():
|
||||
$SaveDialog.visible = true
|
||||
@@ -363,6 +385,14 @@ func _on_load_dialog_file_selected(path):
|
||||
if data[item].has("toggle"):
|
||||
sprite.toggle = data[item]["toggle"]
|
||||
|
||||
# Load mask properties
|
||||
if data[item].has("mask_texture_path"):
|
||||
sprite.mask_texture_path = data[item]["mask_texture_path"]
|
||||
if data[item].has("use_mask"):
|
||||
sprite.use_mask = data[item]["use_mask"]
|
||||
if data[item].has("mask_opacity"):
|
||||
sprite.mask_opacity = data[item]["mask_opacity"]
|
||||
|
||||
origin.add_child(sprite)
|
||||
sprite.position = str_to_var(data[item]["pos"])
|
||||
|
||||
@@ -424,6 +454,11 @@ func _on_save_dialog_file_selected(path):
|
||||
|
||||
data[id]["toggle"] = child.toggle
|
||||
|
||||
# Save mask properties
|
||||
data[id]["mask_texture_path"] = child.mask_texture_path
|
||||
data[id]["use_mask"] = child.use_mask
|
||||
data[id]["mask_opacity"] = child.mask_opacity
|
||||
|
||||
id += 1
|
||||
|
||||
Saving.settings["lastAvatar"] = path
|
||||
@@ -445,9 +480,9 @@ func _on_kofi_pressed():
|
||||
Global.pushUpdate("Support me on ko-fi!")
|
||||
|
||||
|
||||
func _on_twitter_pressed():
|
||||
OS.shell_open("https://twitter.com/kaiakairos")
|
||||
Global.pushUpdate("Follow me on twitter!")
|
||||
func _on_bluesky_pressed():
|
||||
OS.shell_open("https://bsky.app/profile/kaiakairos.net")
|
||||
Global.pushUpdate("Follow me on bluesky!")
|
||||
|
||||
|
||||
func _on_replace_button_pressed():
|
||||
@@ -547,7 +582,7 @@ func moveSpriteMenu(delta):
|
||||
|
||||
var size = get_viewport().get_visible_rect().size
|
||||
|
||||
var windowLength = 1400
|
||||
var windowLength = 1800
|
||||
|
||||
$ViewerArrows/Arrows.position.y = size.y - 25
|
||||
|
||||
@@ -604,7 +639,7 @@ func _on_background_input_capture_bg_key_pressed(node, keys_pressed):
|
||||
var has_ctrl = keys_pressed.has(KEY_CTRL) and keys_pressed[KEY_CTRL]
|
||||
var has_shift = keys_pressed.has(KEY_SHIFT) and keys_pressed[KEY_SHIFT]
|
||||
var has_alt = keys_pressed.has(KEY_ALT) and keys_pressed[KEY_ALT]
|
||||
var has_meta = keys_pressed.has(KEY_META) and keys_pressed[KEY_META] # Command key on macOS
|
||||
var meta_pressed = keys_pressed.has(KEY_META) and keys_pressed[KEY_META] # Command key on macOS
|
||||
|
||||
# Build modifier prefix once
|
||||
if has_ctrl:
|
||||
@@ -613,7 +648,7 @@ func _on_background_input_capture_bg_key_pressed(node, keys_pressed):
|
||||
modifiers.append("Shift")
|
||||
if has_alt:
|
||||
modifiers.append("Alt")
|
||||
if has_meta:
|
||||
if meta_pressed:
|
||||
modifiers.append("Cmd") # Command key on macOS
|
||||
|
||||
var modifier_prefix = ""
|
||||
|
||||
@@ -14341,7 +14341,7 @@ offset_bottom = 27.0
|
||||
theme = SubResource("Theme_rv56a")
|
||||
flat = true
|
||||
|
||||
[node name="twitter" type="Button" parent="ControlPanel/Links"]
|
||||
[node name="bluesky" type="Button" parent="ControlPanel/Links"]
|
||||
offset_left = -5.0
|
||||
offset_top = -29.0
|
||||
offset_right = 61.0
|
||||
@@ -14730,7 +14730,7 @@ z_index = -4096
|
||||
[connection signal="pressed" from="ControlPanel/SettingsButton/settingsButtons" to="." method="_on_settings_buttons_pressed"]
|
||||
[connection signal="pressed" from="ControlPanel/Edit/Button" to="." method="swapMode"]
|
||||
[connection signal="pressed" from="ControlPanel/Links/kofi" to="." method="_on_kofi_pressed"]
|
||||
[connection signal="pressed" from="ControlPanel/Links/twitter" to="." method="_on_twitter_pressed"]
|
||||
[connection signal="pressed" from="ControlPanel/Links/bluesky" to="." method="_on_bluesky_pressed"]
|
||||
[connection signal="pressed" from="EditControls/Add/addButton" to="." method="_on_add_button_pressed"]
|
||||
[connection signal="pressed" from="EditControls/Link/linkButton" to="." method="_on_link_button_pressed"]
|
||||
[connection signal="pressed" from="EditControls/Exit/Button2" to="." method="swapMode"]
|
||||
|
||||
@@ -23,6 +23,7 @@ config/icon="res://icon.png"
|
||||
[audio]
|
||||
|
||||
driver/enable_input=true
|
||||
buses/channel_disable_time=0.0
|
||||
|
||||
[autoload]
|
||||
|
||||
@@ -147,4 +148,6 @@ textures/canvas_textures/default_texture_filter=0
|
||||
textures/canvas_textures/default_texture_repeat=1
|
||||
renderer/rendering_method="gl_compatibility"
|
||||
renderer/rendering_method.mobile="gl_compatibility"
|
||||
shading/overrides/force_vertex_shading=true
|
||||
shading/overrides/force_lambert_over_burley=true
|
||||
environment/defaults/default_clear_color=Color(0.376471, 0.376471, 0.376471, 1)
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
shader_type canvas_item;
|
||||
|
||||
uniform sampler2D noise_texture:repeat_enable;
|
||||
uniform float distortion_strengh: hint_range(0, 0.1) = 1.0;
|
||||
uniform sampler2D noise_texture: source_color, repeat_enable;
|
||||
uniform float distortion_strengh: hint_range(0, 0.1) = 0.01;
|
||||
uniform float speed: hint_range(0.1, 10) = 1.0;
|
||||
uniform bool use_noise_texture: hint_default_true = false;
|
||||
|
||||
void fragment() {
|
||||
vec4 noise_pixel = texture(noise_texture, UV + floor(TIME*speed)/3.0);
|
||||
vec2 uv_offset = (noise_pixel.rg * 2.0 - 1.0) * distortion_strengh;
|
||||
vec2 uv_offset = vec2(0.0);
|
||||
|
||||
if (use_noise_texture) {
|
||||
vec4 noise_pixel = texture(noise_texture, UV + floor(TIME * speed) / 3.0);
|
||||
uv_offset = (noise_pixel.rg * 2.0 - 1.0) * distortion_strengh;
|
||||
} else {
|
||||
// Fallback procedural noise when no texture is provided
|
||||
float noise = sin(UV.x * 20.0 + TIME * speed) * cos(UV.y * 20.0 + TIME * speed * 0.7);
|
||||
uv_offset = vec2(noise) * distortion_strengh;
|
||||
}
|
||||
|
||||
COLOR = texture(TEXTURE, UV + uv_offset);
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
uid://b342og0l0k1p
|
||||
uid://4a1uhohwy43l
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 14 KiB |
@@ -7,17 +7,11 @@ func _ready():
|
||||
|
||||
|
||||
func _on_button_pressed():
|
||||
|
||||
if !get_parent().get_parent().get_parent().visible:
|
||||
return
|
||||
|
||||
AudioServer.input_device = micName
|
||||
Global.deleteAllMics()
|
||||
Global.currentMicrophone = null
|
||||
|
||||
Global.createMicrophone()
|
||||
get_parent().get_parent().get_parent().visible = false
|
||||
|
||||
await get_tree().create_timer(1.0).timeout
|
||||
Global.createMicrophone()
|
||||
|
||||
|
||||
|
||||
23
ui_scenes/selectedSprite/mask.gdshader
Normal file
23
ui_scenes/selectedSprite/mask.gdshader
Normal file
@@ -0,0 +1,23 @@
|
||||
shader_type canvas_item;
|
||||
|
||||
uniform sampler2D mask_texture : source_color;
|
||||
uniform bool use_mask = false;
|
||||
uniform float mask_opacity : hint_range(0.0, 1.0) = 1.0;
|
||||
|
||||
void fragment() {
|
||||
// Get the original sprite color
|
||||
vec4 sprite_color = texture(TEXTURE, UV);
|
||||
|
||||
if (use_mask) {
|
||||
// Sample the mask texture
|
||||
vec4 mask_sample = texture(mask_texture, UV);
|
||||
|
||||
// Use the mask's alpha channel to determine visibility
|
||||
float mask_alpha = mask_sample.a * mask_opacity;
|
||||
|
||||
// Apply the mask by multiplying the sprite's alpha with the mask alpha
|
||||
sprite_color.a *= mask_alpha;
|
||||
}
|
||||
|
||||
COLOR = sprite_color;
|
||||
}
|
||||
1
ui_scenes/selectedSprite/mask.gdshader.uid
Normal file
1
ui_scenes/selectedSprite/mask.gdshader.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://btd72itp0cy6b
|
||||
@@ -1,17 +1,8 @@
|
||||
shader_type canvas_item;
|
||||
|
||||
uniform float speed;
|
||||
|
||||
uniform sampler2D backImg: repeat_enable;
|
||||
|
||||
uniform sampler2D palette;
|
||||
uniform float palette_speed = 0.1;
|
||||
uniform vec4 outline_color : source_color = vec4(1.0, 0.0, 0.0, 0.3);
|
||||
|
||||
void fragment(){
|
||||
|
||||
vec2 scroll = vec2(1.0,0.0) * TIME * speed;
|
||||
vec4 tex = texture(TEXTURE, (UV));
|
||||
float palette_swap = mod(tex.r - TIME * palette_speed, 1.0);
|
||||
COLOR = vec4(texture(palette, vec2(palette_swap, 0)).rgb, tex.a);
|
||||
|
||||
vec4 tex = texture(TEXTURE, UV);
|
||||
COLOR = vec4(outline_color.rgb, tex.a * outline_color.a);
|
||||
}
|
||||
@@ -77,6 +77,12 @@ var ignoreBounce = false
|
||||
var frames = 1
|
||||
var animSpeed = 0
|
||||
|
||||
#Masking
|
||||
var mask_texture_path = ""
|
||||
var mask_texture = null
|
||||
var use_mask = false
|
||||
var mask_opacity = 1.0
|
||||
|
||||
var remadePolygon = false
|
||||
|
||||
var clipped = false
|
||||
@@ -119,6 +125,9 @@ func _ready():
|
||||
|
||||
sprite.texture = tex
|
||||
|
||||
# Initialize masking
|
||||
setupMasking()
|
||||
|
||||
var bitmap = BitMap.new()
|
||||
bitmap.create_from_image_alpha(imageData)
|
||||
|
||||
@@ -409,3 +418,53 @@ func visToggle(keys):
|
||||
|
||||
func makeVis():
|
||||
$WobbleOrigin/DragOrigin.visible = true
|
||||
|
||||
## Setup masking system
|
||||
func setupMasking():
|
||||
if use_mask and mask_texture_path != "":
|
||||
loadMaskTexture()
|
||||
updateMaskShader()
|
||||
|
||||
## Load mask texture from file path
|
||||
func loadMaskTexture():
|
||||
if mask_texture_path == "":
|
||||
return
|
||||
|
||||
var img = Image.new()
|
||||
var err = img.load(mask_texture_path)
|
||||
if err != OK:
|
||||
print_debug("Failed to load mask texture: " + mask_texture_path)
|
||||
return
|
||||
|
||||
mask_texture = ImageTexture.create_from_image(img)
|
||||
|
||||
## Apply or remove mask shader
|
||||
func updateMaskShader():
|
||||
if use_mask and mask_texture != null:
|
||||
# Create mask material with shader
|
||||
var mask_shader = load("res://ui_scenes/selectedSprite/mask.gdshader")
|
||||
var mask_material = ShaderMaterial.new()
|
||||
mask_material.shader = mask_shader
|
||||
mask_material.set_shader_parameter("mask_texture", mask_texture)
|
||||
mask_material.set_shader_parameter("use_mask", true)
|
||||
mask_material.set_shader_parameter("mask_opacity", mask_opacity)
|
||||
|
||||
sprite.material = mask_material
|
||||
else:
|
||||
# Remove mask material
|
||||
sprite.material = null
|
||||
|
||||
## Set mask texture from external source
|
||||
func setMaskTexture(texture_path: String, opacity: float = 1.0):
|
||||
mask_texture_path = texture_path
|
||||
mask_opacity = opacity
|
||||
use_mask = true
|
||||
loadMaskTexture()
|
||||
updateMaskShader()
|
||||
|
||||
## Remove masking
|
||||
func removeMask():
|
||||
use_mask = false
|
||||
mask_texture = null
|
||||
mask_texture_path = ""
|
||||
updateMaskShader()
|
||||
|
||||
@@ -46,6 +46,8 @@ func setvalues():
|
||||
label.text = "costume " + str(tag) + " key: \"" + Global.main.costumeKeys[tag-1] + "\""
|
||||
tag += 1
|
||||
|
||||
$experimentalMicLoudness/checkmark.button_pressed = Global.experimentalMicLoudness
|
||||
|
||||
func _on_color_picker_button_color_changed(color):
|
||||
get_viewport().transparent_bg = false
|
||||
RenderingServer.set_default_clear_color(color)
|
||||
@@ -202,10 +204,17 @@ func _on_costume_check_toggled(button_pressed):
|
||||
## @param button_pressed: bool - Whether StreamDeck should be enabled
|
||||
func _on_stream_deck_check_toggled(button_pressed):
|
||||
Saving.settings["useStreamDeck"] = button_pressed
|
||||
if ElgatoStreamDeck:
|
||||
ElgatoStreamDeck.refresh_connection()
|
||||
if get_node_or_null("/root/ElgatoStreamDeck"):
|
||||
get_node("/root/ElgatoStreamDeck").refresh_connection()
|
||||
Global.pushUpdate("StreamDeck integration " + ("enabled" if button_pressed else "disabled") + ".")
|
||||
|
||||
## Handle experimental microphone loudness toggle
|
||||
## @param checked: bool - Whether experimental mic loudness should be enabled
|
||||
func _on_experimental_mic_loudness_toggle(checked):
|
||||
Global.experimentalMicLoudness = checked
|
||||
Saving.settings["experimentalMicLoudness"] = checked
|
||||
print("Experimental mic loudness: ", checked)
|
||||
|
||||
|
||||
func _process(delta):
|
||||
var g = to_local(get_global_mouse_position())
|
||||
|
||||
@@ -14289,46 +14289,67 @@ offset_bottom = 28.0
|
||||
text = "confirm"
|
||||
|
||||
[node name="StreamDeck" type="Node2D" parent="."]
|
||||
position = Vector2(16, 373)
|
||||
position = Vector2(16, 337)
|
||||
|
||||
[node name="Label" type="Label" parent="StreamDeck"]
|
||||
offset_right = 138.0
|
||||
offset_bottom = 34.0
|
||||
text = "use streamdeck"
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="streamDeckCheck" type="CheckBox" parent="StreamDeck"]
|
||||
offset_left = 130.0
|
||||
offset_top = 1.0
|
||||
offset_right = 154.0
|
||||
offset_bottom = 25.0
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="experimentalMicLoudness" type="Node2D" parent="."]
|
||||
position = Vector2(16, 369)
|
||||
|
||||
[node name="Label" type="Label" parent="experimentalMicLoudness"]
|
||||
offset_right = 200.0
|
||||
offset_bottom = 34.0
|
||||
text = "mic loudness"
|
||||
|
||||
[node name="checkmark" type="CheckBox" parent="experimentalMicLoudness"]
|
||||
offset_left = 130.0
|
||||
offset_top = 1.0
|
||||
offset_right = 154.0
|
||||
offset_bottom = 25.0
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="AntiAliasing" type="Node2D" parent="."]
|
||||
position = Vector2(16, 405)
|
||||
position = Vector2(16, 401)
|
||||
|
||||
[node name="Label" type="Label" parent="AntiAliasing"]
|
||||
offset_right = 138.0
|
||||
offset_bottom = 34.0
|
||||
text = "texture filtering"
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="CheckBox" type="CheckBox" parent="AntiAliasing"]
|
||||
offset_left = 130.0
|
||||
offset_top = 1.0
|
||||
offset_right = 154.0
|
||||
offset_bottom = 25.0
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="bounceOnCostume" type="Node2D" parent="."]
|
||||
position = Vector2(17, 341)
|
||||
position = Vector2(17, 305)
|
||||
|
||||
[node name="Label" type="Label" parent="bounceOnCostume"]
|
||||
offset_right = 138.0
|
||||
offset_bottom = 34.0
|
||||
text = "costume bounce"
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="costumeCheck" type="CheckBox" parent="bounceOnCostume"]
|
||||
offset_left = 130.0
|
||||
offset_top = 1.0
|
||||
offset_right = 154.0
|
||||
offset_bottom = 25.0
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="BounceForce" type="Node2D" parent="."]
|
||||
position = Vector2(22, 115)
|
||||
@@ -14832,7 +14853,7 @@ offset_bottom = -75.0
|
||||
text = "costume hotkeys"
|
||||
|
||||
[node name="BlinkSpeed" type="Node2D" parent="."]
|
||||
position = Vector2(17, 283)
|
||||
position = Vector2(17, 253)
|
||||
|
||||
[node name="Label" type="Label" parent="BlinkSpeed"]
|
||||
offset_left = -10.0
|
||||
@@ -14841,6 +14862,7 @@ offset_right = 158.0
|
||||
offset_bottom = 27.0
|
||||
text = "blink speed: 1"
|
||||
horizontal_alignment = 1
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="blinkSpeed" type="HSlider" parent="BlinkSpeed"]
|
||||
offset_left = -9.0
|
||||
@@ -14851,9 +14873,10 @@ theme = SubResource("Theme_e6tc4")
|
||||
max_value = 20.0
|
||||
value = 1.0
|
||||
scrollable = false
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="BlinkChance" type="Node2D" parent="."]
|
||||
position = Vector2(17, 235)
|
||||
position = Vector2(17, 205)
|
||||
|
||||
[node name="Label" type="Label" parent="BlinkChance"]
|
||||
offset_left = -10.0
|
||||
@@ -14862,6 +14885,7 @@ offset_right = 160.0
|
||||
offset_bottom = 27.0
|
||||
text = "blink chance: 1 in 200"
|
||||
horizontal_alignment = 1
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="blinkChance" type="HSlider" parent="BlinkChance"]
|
||||
offset_left = -8.0
|
||||
@@ -14873,6 +14897,7 @@ min_value = 1.0
|
||||
max_value = 300.0
|
||||
value = 200.0
|
||||
scrollable = false
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[connection signal="pressed" from="Background/Transparent/Button" to="." method="_on_button_pressed"]
|
||||
[connection signal="pressed" from="Background/Green/greenButton" to="." method="_on_green_button_pressed"]
|
||||
@@ -14883,6 +14908,7 @@ scrollable = false
|
||||
[connection signal="value_changed" from="MaxFPS/fpsDrag" to="." method="_on_fps_drag_value_changed"]
|
||||
[connection signal="pressed" from="MaxFPS/confirm" to="." method="_on_confirm_pressed"]
|
||||
[connection signal="toggled" from="StreamDeck/streamDeckCheck" to="." method="_on_stream_deck_check_toggled"]
|
||||
[connection signal="toggled" from="experimentalMicLoudness/checkmark" to="." method="_on_experimental_mic_loudness_toggle"]
|
||||
[connection signal="toggled" from="AntiAliasing/CheckBox" to="." method="_on_check_box_toggled"]
|
||||
[connection signal="toggled" from="bounceOnCostume/costumeCheck" to="." method="_on_costume_check_toggled"]
|
||||
[connection signal="value_changed" from="BounceForce/bounceForce" to="." method="_on_bounce_force_value_changed"]
|
||||
|
||||
@@ -75,6 +75,15 @@ func setImage():
|
||||
|
||||
$VisToggle/setToggle/Label.text = "toggle: \"" + Global.heldSprite.toggle + "\""
|
||||
|
||||
# Update masking controls
|
||||
$Masking/useMaskCheckbox.button_pressed = Global.heldSprite.use_mask
|
||||
$Masking/maskOpacityLabel.text = "mask opacity: " + str(Global.heldSprite.mask_opacity)
|
||||
$Masking/maskOpacity.value = Global.heldSprite.mask_opacity
|
||||
if Global.heldSprite.mask_texture_path.is_empty():
|
||||
$Masking/maskPathLabel.text = "mask: (none)"
|
||||
else:
|
||||
$Masking/maskPathLabel.text = "mask: " + Global.heldSprite.mask_texture_path.get_file()
|
||||
|
||||
changeRotLimit()
|
||||
|
||||
setLayerButtons()
|
||||
@@ -364,8 +373,25 @@ func _on_delete_pressed():
|
||||
func _on_set_toggle_pressed():
|
||||
$VisToggle/setToggle/Label.text = "toggle: AWAITING INPUT"
|
||||
await Global.main.fatfuckingballs
|
||||
|
||||
var keys = await Global.main.spriteVisToggles
|
||||
var key = keys[0]
|
||||
Global.heldSprite.toggle = key
|
||||
$VisToggle/setToggle/Label.text = "toggle: \"" + Global.heldSprite.toggle + "\""
|
||||
|
||||
## Masking signal handlers
|
||||
func _on_use_mask_checkbox_toggled(button_pressed):
|
||||
Global.heldSprite.use_mask = button_pressed
|
||||
Global.heldSprite.updateMaskShader()
|
||||
|
||||
func _on_mask_opacity_value_changed(value):
|
||||
Global.heldSprite.mask_opacity = value
|
||||
$Masking/maskOpacityLabel.text = "mask opacity: " + str(value)
|
||||
Global.heldSprite.updateMaskShader()
|
||||
|
||||
func _on_select_mask_pressed():
|
||||
Global.main.openMaskSelection()
|
||||
|
||||
func updateMaskDisplay(path: String):
|
||||
$Masking/maskPathLabel.text = "mask: " + path.get_file()
|
||||
$Masking/useMaskCheckbox.button_pressed = true
|
||||
|
||||
func _on_clear_mask_pressed():
|
||||
Global.heldSprite.removeMask()
|
||||
$Masking/maskPathLabel.text = "mask: (none)"
|
||||
$Masking/useMaskCheckbox.button_pressed = false
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
[ext_resource type="Texture2D" uid="uid://gflmeocxfnrq" path="res://ui_scenes/settings/deleteHotkey.png" id="27_fgu6g"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_21kva"]
|
||||
size = Vector2(245, 1341)
|
||||
size = Vector2(245, 1596.5)
|
||||
|
||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_hxmah"]
|
||||
shader = ExtResource("3_ky0lu")
|
||||
@@ -14285,7 +14285,7 @@ script = ExtResource("1_hp0e3")
|
||||
z_index = -2
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"]
|
||||
position = Vector2(122.5, 670.5)
|
||||
position = Vector2(122.5, 725)
|
||||
shape = SubResource("RectangleShape2D_21kva")
|
||||
|
||||
[node name="Border" type="Sprite2D" parent="."]
|
||||
@@ -14910,6 +14910,66 @@ position = Vector2(-2, -2)
|
||||
texture = ExtResource("27_fgu6g")
|
||||
centered = false
|
||||
|
||||
[node name="Masking" type="Node2D" parent="."]
|
||||
position = Vector2(0, 1360.83)
|
||||
|
||||
[node name="animationBox" type="Sprite2D" parent="Masking"]
|
||||
position = Vector2(125, 92.4052)
|
||||
scale = Vector2(1, 0.905768)
|
||||
texture = ExtResource("15_wqi8b")
|
||||
|
||||
[node name="maskingLabel" type="Label" parent="Masking"]
|
||||
offset_left = 20.0
|
||||
offset_right = 120.0
|
||||
offset_bottom = 26.0
|
||||
text = "MASKING"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="useMaskCheckbox" type="CheckBox" parent="Masking"]
|
||||
offset_left = 20.0
|
||||
offset_top = 30.0
|
||||
offset_right = 200.0
|
||||
offset_bottom = 54.0
|
||||
text = "Use Mask"
|
||||
|
||||
[node name="maskOpacityLabel" type="Label" parent="Masking"]
|
||||
offset_left = 20.0
|
||||
offset_top = 60.0
|
||||
offset_right = 200.0
|
||||
offset_bottom = 86.0
|
||||
text = "mask opacity: 1.0"
|
||||
|
||||
[node name="maskOpacity" type="HSlider" parent="Masking"]
|
||||
offset_left = 20.0
|
||||
offset_top = 90.0
|
||||
offset_right = 200.0
|
||||
offset_bottom = 106.0
|
||||
max_value = 1.0
|
||||
step = 0.01
|
||||
value = 1.0
|
||||
|
||||
[node name="maskPathLabel" type="Label" parent="Masking"]
|
||||
offset_left = 20.0
|
||||
offset_top = 120.0
|
||||
offset_right = 400.0
|
||||
offset_bottom = 146.0
|
||||
text = "mask: (none)"
|
||||
autowrap_mode = 2
|
||||
|
||||
[node name="selectMask" type="Button" parent="Masking"]
|
||||
offset_left = 20.0
|
||||
offset_top = 150.0
|
||||
offset_right = 120.0
|
||||
offset_bottom = 181.0
|
||||
text = "Select Mask"
|
||||
|
||||
[node name="clearMask" type="Button" parent="Masking"]
|
||||
offset_left = 130.0
|
||||
offset_top = 150.0
|
||||
offset_right = 220.0
|
||||
offset_bottom = 181.0
|
||||
text = "Clear Mask"
|
||||
|
||||
[connection signal="pressed" from="Buttons/Speaking/speaking" to="." method="_on_speaking_pressed"]
|
||||
[connection signal="pressed" from="Buttons/Blinking/blinking" to="." method="_on_blinking_pressed"]
|
||||
[connection signal="pressed" from="Buttons/Trash/trash" to="." method="_on_trash_pressed"]
|
||||
@@ -14941,3 +15001,7 @@ centered = false
|
||||
[connection signal="pressed" from="Layers/Layer10/layerButton10" to="." method="_on_layer_button_10_pressed"]
|
||||
[connection signal="pressed" from="VisToggle/setToggle" to="." method="_on_set_toggle_pressed"]
|
||||
[connection signal="pressed" from="VisToggle/setToggle/delete" to="." method="_on_delete_pressed"]
|
||||
[connection signal="toggled" from="Masking/useMaskCheckbox" to="." method="_on_use_mask_checkbox_toggled"]
|
||||
[connection signal="value_changed" from="Masking/maskOpacity" to="." method="_on_mask_opacity_value_changed"]
|
||||
[connection signal="pressed" from="Masking/selectMask" to="." method="_on_select_mask_pressed"]
|
||||
[connection signal="pressed" from="Masking/clearMask" to="." method="_on_clear_mask_pressed"]
|
||||
|
||||
Reference in New Issue
Block a user